PageSourceSearch

https://lukoilamericas.com/bundles/scripts?v=Pd4_Pb0aGTpahVWzS0c4iqHyrplww6szEgte4xF7riE1

js lukoilamericas.com collected 2026-09-24 10:02:25 UTC 735,851 bytes, 17,711 lines download raw bytes

1/* Minification failed. Returning unminified contents.
2(3148,78-79): run-time error JS1195: Expected expression: >
3(3148,86-87): run-time error JS1004: Expected ';': )
4(3150,72-73): run-time error JS1195: Expected expression: >
5(3152,4-5): run-time error JS1195: Expected expression: )
6(3156,76-77): run-time error JS1195: Expected expression: >
7(3156,84-85): run-time error JS1004: Expected ';': )
8(3158,4-5): run-time error JS1195: Expected expression: )
9(3160,27-28): run-time error JS1014: Invalid character: `
10(3160,42-43): run-time error JS1014: Invalid character: `
11(3160,43-44): run-time error JS1195: Expected expression: )
12(3160,44-45): run-time error JS1197: Too many errors. The file might not be a JavaScript file: .
13(3141,1-31): run-time error JS1301: End of file encountered before function is properly closed: function ViewUploadFile(e, id)
14(3161,2-3): run-time error JS1002: Syntax error: }
15(3162,2-3): run-time error JS1197: Too many errors. The file might not be a JavaScript file: $
16 */
17$(function () {
18	$.fn.fancyboxInit = function (params) {
19		this.fancybox(fancyBoxTplInit(params));
20		return this;
21	};
22
23	$.fancyboxInit = function (params){
24		return $.fancybox(fancyBoxTplInit(params));
25	}
26
27	function fancyBoxTplInit (params) {
28		if (typeof params == 'undefined')
29			params = {};
30		params.tpl = {
31			error: '<p class="fancybox-error">' + GlobalSettings.FancyboxError + '</p>'
32		};
33		return params;
34	}
35
36	$.fancyConfirm = function (content, callback, buttons) {
37		var result;
38		var buttonsHtml = "";
39		switch (buttons) {
40			case "YesNo":
41				buttonsHtml = '<button id="fancyConfirm_ok" class="button">' + GlobalSettings.Yes + '</button><button id="fancyConfirm_cancel" class="button button-transparent">' + GlobalSettings.No + '</button>';
42				break;
43			case "Ok":
44				buttonsHtml = '<button id="fancyConfirm_ok" class="button">' + GlobalSettings.Ok + '</button>';
45				break;
46		}
47
48		$.fancyboxInit({
49			padding: 10,
50			autoSize: false,
51			autoHeight: true,
52			minHeight: 50,
53			width: 400,
54			content: '<div class="modal-confirm"><div class="modal-confirm__body">' + content + '</div><div class="group-buttons">' + buttonsHtml + '</div></div>',
55			afterShow: function () {
56				$(".modal-confirm #fancyConfirm_cancel").on("click", function () {
57					result = false;
58					$.fancybox.close();
59				});
60				$(".modal-confirm #fancyConfirm_ok").on("click", function () {
61					result = true;
62					$.fancybox.close();
63				});
64			},
65			afterClose: function () {
66				if (callback) {
67					callback.call(this, result);
68				}
69			}
70		});
71	};
72
73	var isPageBeingRefreshed = false;
74	$(window).on('beforeunload', function () {
75		isPageBeingRefreshed = true;
76	});
77
78	$.fancyboxMessage = function (message, onCloseCallback) {
79		if (!isPageBeingRefreshed) {
80			$.fancyboxInit({
81				padding: 10,
82				autoSize: false,
83				autoHeight: true,
84				width: 200,
85				content: '<div class="modal-confirm"><div class="modal-confirm__body">' + message + '</div><div class="group-buttons"><button id="fancyConfirm_ok" class="button">' + GlobalSettings.Ok + '</button></div></div>',
86				afterShow: function() {
87					$(".modal-confirm #fancyConfirm_ok").on("click", function() {
88						$.fancybox.close();
89					});
90				},
91				afterClose: function () {
92					if (typeof onCloseCallback == "function" && onCloseCallback) {
93						onCloseCallback.call(this);
94					}
95				}
96			});
97		}
98	};
99});;
100$(document).ready(function ($) {
101	$(".global-nav #lang .dropdown-menu li a").on("click", function () {
102		var lang = $(this).parent().attr("langCode");
103		if (lang != null && lang != '') {
104			$.lukoilSaveCookie('LukLanguage', lang, { path: '/' });
105		}
106	});
107
108	/* TopBar - Position and Open/Close
109	==============================================================================*/
110	var $topBarToggle = $('#topbar-toggle');
111	var $topBar = $('.topbar');
112	var $topBarContent = $('.topbar-content');
113	var isDesktopBar;
114	var timerOpenTopBar;
115	function hideTopBar() {
116		clearTimeout(timerOpenTopBar);
117		$topBarContent.removeClass('open');
118		$topBarContent.animate({ height: 0 }, isDesktopBar ? 200 : 300);
119		$topBarToggle.removeClass('dropup');
120	};
121
122	function showTopBar(flag) {
123		if ($topBarToggle.hasClass('dropup')) {
124			if (flag != null && flag) {
125				hideTopBar();
126			}
127			return;
128		}
129		timerOpenTopBar = setTimeout(function () {
130			var height = $topBarContent.find('.container').outerHeight();
131			$topBarContent.animate({ height: height + 'px' }, 200, function() {
132				$topBarContent.addClass('open');
133			});
134			$topBarToggle.addClass('dropup');
135		}, 100);
136		$('#widgets').removeClass('open');
137	}
138
139	function showTopBarMouse() {
140		showTopBar(false);
141	}
142	function showTopBarClick() {
143		showTopBar(true);
144	}
145
146	setTimeout(function () {
147		var fullMode = $('html').attr('fullMode') != null;
148		var isUaDesktop = $('html').hasClass('ua-desktop');
149		isDesktopBar = isUaDesktop || fullMode;
150		$topBar.on('mouseleave', hideTopBar);
151		if (!isUaDesktop) {
152			if (fullMode) {
153				$(".changeSiteMode .fullMode").hide();
154				$(".cchangeSiteModeopy .mobileMode").show();
155			} else {
156				$(".changeSiteMode .fullMode").show();
157				$(".changeSiteMode .mobileMode").hide();
158			}
159		}
160
161		if (isDesktopBar) {
162			$topBarToggle.on('mouseenter', showTopBarMouse);
163		} else {
164			$(".ua-mobile #topSearchForm, .ua-mobile #footerSearchForm").removeAttr("target");
165		}
166		$topBarToggle.on('click', showTopBarClick);
167	}, 100);
168
169	$(".htmlContent table").wrap("<div class='tableOverflow'></div>");
170
171	$(".changeSiteMode .fullMode").on("click", function () {
172		$.lukoilSaveCookie('FULL_SITE_MODE', 'true', { path: '/', expires: 10000 });
173		window.location.reload();
174		return false;
175	});
176	$(".changeSiteMode .mobileMode").on("click", function () {
177		$.removeCookie('FULL_SITE_MODE', { path: '/' });
178		window.location.reload();
179		return false;
180	});
181
182	/* TopBar - Show company activities on click
183	==============================================================================*/
184	$('.activities .dropdown').on("click", function(event) {
185		event.preventDefault();
186		var id = $(this).find('a').attr('href');
187		$(this).addClass('open').siblings('.dropdown').removeClass('open');
188		$(id).addClass('open').siblings('.dropdown-menu').removeClass('open');
189	});
190
191	/* Sticky Navigation
192	==============================================================================*/
193	/*$(window).scroll(function() {
194	  if( $(this).scrollTop() > 40 ) {
195		$('.navbar').addClass('navbar-fixed');
196	  } else {
197		$('.navbar').removeClass('navbar-fixed');
198	  }
199	});*/
200
201	/* Resize font
202	==============================================================================*/
203	if ($.lukoilGetCookie('TEXT_SIZE')) {
204		var cookieTextSize = $.lukoilGetCookie('TEXT_SIZE');
205		$('body').addClass(cookieTextSize);
206		var resizeFondEl = $('.resize-font');
207		resizeFondEl.find('button').removeClass('active');
208		resizeFondEl.find('li.' + cookieTextSize + ' button').addClass('active');
209	}
210	$('.resize-font button').on("click", function() {
211		var $this = $(this);
212		var textSize = $this.parent().attr('class');
213		$('body').removeClass('normal medium large').addClass(textSize);
214		$.lukoilSaveCookie('TEXT_SIZE', textSize, { path: '/', expires: 10000 });
215		$this.closest('.resize-font').find('button').removeClass('active');
216		$this.addClass('active');
217		$('.timeline').trigger("resize");
218		textEllipsis();
219		return false;
220	});
221
222	/* Widgets - Open/Close
223	==============================================================================*/
224	$('#widgets-toggle').on("click", function() {
225		$('#widgets').toggleClass('open');
226		return false;
227	});
228
229	/* Widgets - collapse margin for HtmlContentQualification
230	==============================================================================*/
231	$(document).on("show.bs.collapse", ".panel-specification .panel-collapse", function () {
232		$(this).each(function () {
233			$(this).animate({ "margin-top": $(this).attr("margin-top") }, 150);
234		});
235	});
236
237	$(document).on("hide.bs.collapse", ".panel-specification .panel-collapse", function () {
238		$(this).each(function () {
239			$(this).attr("margin-top", $(this).css("margin-top"));
240			$(this).animate({ "margin-top": "0px" }, 150);
241		});
242	});
243
244	/* Widgets - Save
245	==============================================================================*/
246	var widgetsIsSaved = $.lukoilGetCookie('WIDGETS_SAVED');
247	if (!widgetsIsSaved) {
248		$('#widgets').removeClass('hide');
249	}
250
251	$('#widgets-save').on("click", function() {
252		$.lukoilSaveCookie('WIDGETS_SAVED', 'true', { path: '/', expires: 10000 });
253		window.location.reload();
254		return false;
255	});
256
257	/* Scroll To top
258	==============================================================================*/
259	$(window).on("scroll", function() {
260		if ($(this).scrollTop() > 100) {
261			$('#scroll-top').css({ bottom: '15px' });
262		} else {
263			$('#scroll-top').css({ bottom: '-100px' });
264		}
265		if ($(this).scrollTop() > 1) {
266			$('.subsidiary.index-page .title-fixed').addClass('fly');
267		} else {
268			$('.subsidiary.index-page .title-fixed').removeClass('fly');
269		}
270	});
271
272	$('#scroll-top').on("click", function() {
273		$('html, body').animate({ scrollTop: '0px' }, 500);
274		return false;
275	});
276
277	if ($('.subsidiary.index-page').length) {
278		$(window).on("scroll", function() {
279			if ($(this).scrollTop()) {
280				$('.subsidiary.index-page .title-fixed').addClass('fly');
281			} else {
282				$('.subsidiary.index-page .title-fixed').removeClass('fly');
283			}
284		});
285	}
286
287	/* Full screen
288	==============================================================================*/
289	var isFullScreenEnable = typeof document.fullscreenEnabled !== 'undefined';
290	if (isFullScreenEnable) {
291		$('.btn-toggle-full-screen').on('click', function() {
292			var $fullScreenElem = $(this).closest('.panel-full-screen');
293			if (!$fullScreenElem.length) return;
294			if (document.fullscreenElement) {
295				document.exitFullscreen();
296			} else {
297				$fullScreenElem[0].requestFullscreen();
298			}
299		});
300		document.addEventListener("fullscreenchange", function() {
301			if (document.fullscreenElement) {
302				$('.panel-full-screen').addClass('in-full-screen');
303			} else {
304				$('.panel-full-screen').removeClass('in-full-screen');
305			}
306		});
307	} else {
308		$('body').addClass('custom-full-screen');
309		$(document).on('click', '.btn-toggle-full-screen', function() {
310			$(this).closest('.panel-full-screen').toggleClass('in-full-screen');
311			if ($('.panel-full-screen--map').length) updateSizeMap();
312		});
313		$(document).on("keyup", function(e) {
314			if (e.keyCode !== 27) return;
315			$('.panel-full-screen').removeClass('in-full-screen');
316			if ($('.panel-full-screen--map').length) updateSizeMap();
317		});
318	}
319
320	/* Photo Slider
321	==============================================================================*/
322	var slidesCookiesConfig = {
323		path: '/',
324		domain: GlobalSettings.CookiesConfigDomain
325	};
326	var slidesCookiesKey = "LukSlider";
327	var getSlidesCookies = function() {
328		var slidesCookies = $.lukoilGetCookie(slidesCookiesKey);
329		return slidesCookies == null ? {} : JSON.parse(slidesCookies);
330	};
331	var saveSlidesCookies = function (cookies, sliderId, slideId) {
332		if (cookies == null) {
333			cookies = getSlidesCookies();
334		}
335		cookies[sliderId] = slideId;
336		$.lukoilSaveCookie(slidesCookiesKey, JSON.stringify(cookies), slidesCookiesConfig);
337	};
338
339	setTimeout(function () {
340		var slidesCookies = getSlidesCookies();
341		$('.rslides').each(function () {
342			var startidx = 0;
343			var thisSliderId = $(this).attr("sliderId");
344			if (thisSliderId != null && thisSliderId != '') {
345				var id = slidesCookies[thisSliderId];
346				if (id != null) {
347					startidx = $(this).find("li").index($(this).find("[slideId=" + id + "]"));
348					var count = $(this).find("li").length;
349					startidx = startidx + 1 >= count ? 0 : startidx + 1;
350					var slideId = $(this).find("li").eq(startidx).attr("slideId");
351					saveSlidesCookies(slidesCookies, thisSliderId, slideId);
352				}
353			}
354			$(this).responsiveSlides({
355				startidx: startidx,
356				pager: true,
357				pause: true,
358				after: function (i, s) {
359					var $slide = $(s).eq(i);
360					var slideId = $slide.attr("slideId");
361					var sliderId = $slide.closest(".rslides").attr("sliderId");
362					saveSlidesCookies(null, sliderId, slideId);
363				}
364			});
365		});
366	}, 0);
367
368	/* Popover
369	==============================================================================*/
370	$('body').append($('<div class="popover-custom--hidden popover"><div class="popover-content"></div></div>'));
371	initToolTip($('body'));
372
373	$.createDownloadPopover($(document));
374
375	$('.trainer-form').on('show.bs.popover', '.tooltip_item', function() {
376		$('input').trigger("blur");
377	});
378
379	$(document).on('click', '.label-control__hint', function(e) { e.preventDefault(); }); // fix so that when the opening tip, do not choose checkbox
380
381	/* Photo Gallery
382	 ==============================================================================*/
383	var $photoGallers = $('.photo-gallery-slider');
384	$photoGallers.each(function () {
385		var countPhoto = $(this).find('img').length;
386		$(this).lukOwlCarousel({
387			nav: true,
388			navRewind: false,
389			dots: false,
390			margin: 10,
391			responsive: {
392				0: {
393					autoWidth: false,
394					slideBy: 1,
395					items: 1
396				},
397				450: {
398					autoWidth: false,
399					slideBy: 2,
400					items: 2
401				},
402				768: {
403					slideBy: 3,
404					items: countPhoto >= 3 ? 3 : countPhoto
405				}
406			}
407		});
408	});
409
410	var $photoManagers = $('.photo-managers-slider');
411	$photoManagers.each(function () {
412		$(this).lukOwlCarousel({
413			mouseDrag: false,
414			touchDrag: false,
415			pullDrag: false,
416			freeDrag: false,
417			nav: false,
418			dots: false,
419			autoplay: true,
420			autoplayTimeout: 5000,
421			autoplaySpeed: 1000,
422			loop: true,
423			responsive: {
424				0: {
425					autoWidth: false,
426					slideBy: 1,
427					items: 1
428				},
429			}
430		});
431	});
432	$photoManagers.on("mouseover", function (e) {
433		$(e.target).trigger('stop.owl.autoplay');
434	}).on("mouseleave", function (e) {
435		$(e.target).trigger('play.owl.autoplay');
436	});
437
438	var $gasInfo = $('.gas-general-info__image');
439	$gasInfo.lukOwlCarousel({
440		nav: true,
441		navRewind: false,
442		dots: false,
443		margin: 20,
444		responsive: {
445			0: {
446				slideBy: 1,
447				items: 1
448			},
449			768: {
450				slideBy: 3,
451				items: 3
452			}
453		}
454	});
455
456	var $manufacturer = $('.manufacturers-slider');
457	$manufacturer.lukOwlCarousel({
458		nav: true,
459		navRewind: false,
460		dots: false,
461		margin: 20,
462		responsive: {
463			0: {
464				items: 1
465			},
466			360: {
467				slideBy: 2,
468				items: 2
469			},
470			768: {
471				slideBy: 5,
472				items: 5
473			}
474		}
475	});
476
477	var $relatedSliders = $('.related-slider');
478	$relatedSliders.lukOwlCarousel({
479		lazyContent: true,
480		nav: true,
481		navRewind: false,
482		dots: false,
483		margin: 20,
484		responsive: {
485			0: {
486				slideBy: 1,
487				items: 1
488			},
489			450: {
490				slideBy: 2,
491				items: 2
492			},
493			768: {
494				slideBy: 3,
495				items: 3
496			}
497		}
498	});
499
500	try {
501		$('.ribbon-slider').each(function() {
502			var countVisibleItems = $(this).data('number-visible-items');
503			$(this).lukOwlCarousel({
504				lazyContent: true,
505				nav: true,
506				navRewind: false,
507				dots: false,
508				margin: 20,
509				responsive: {
510					0: {
511						slideBy: 2,
512						items: 2
513					},
514					450: {
515						slideBy: 3,
516						items: 3
517					},
518					768: {
519						slideBy: 3,
520						items: 3
521					},
522					992: {
523						slideBy: countVisibleItems,
524						items: countVisibleItems
525					}
526				}
527			});
528		});
529	} catch (ex) {
530	}
531
532	$('.panel-adjustable-social').each(function() {
533		var countVisibleItems = $(this).data('number-visible-items');
534		$(this).lukOwlCarousel({
535			lazyContent: true,
536			nav: true,
537			navRewind: false,
538			dots: false,
539			margin: 20,
540			responsive: {
541				0: {
542					slideBy: 1,
543					items: 1
544				},
545				768: {
546					slideBy: countVisibleItems,
547					items: countVisibleItems
548				}
549			}
550		});
551	});
552
553	$('.photo-album').lukMediaAlbum({
554		video: '<i class="icon-play"></i>',
555		audio: '<i class="icon-audio"></i>',
556		file: '<i class="icon-download"></i>'
557	});
558
559	var $timeLineSliders = $('.timline-date__slider');
560	$timeLineSliders.lukOwlCarousel({
561		nav: true,
562		navRewind: false,
563		dots: false,
564		margin: 10,
565		slideBy: 7,
566		items: 7,
567		responsive: {
568			0: {
569				slideBy: 3,
570				items: 3
571			},
572			580: {},
573			990: {
574				margin: 44
575			}
576		},
577		onInitialize: function (event) {
578			$(event.target).closest('.timline-date').show();
579		}
580	});
581
582	var $adjustableOils = $('.adjustable-oil');
583	$adjustableOils.lukOwlCarousel({
584		nav: true,
585		navRewind: false,
586		dots: false,
587		margin: 20,
588		responsive: {
589			0: {
590				items: 1,
591				slideBy: 1
592			},
593			768: {
594				items: 2,
595				slideBy: 2
596			},
597			992: {
598				items: 4,
599				slideBy: 4
600			}
601		}
602	});
603
604	setTimeout(function () {
605		var $fuelPrices = $('.widget-fuel-price .nav-tabs');
606		$fuelPrices.lukOwlCarousel({
607			nav: true,
608			navRewind: false,
609			dots: false,
610			items: 1,
611			margin: 1,
612			autoWidth: true
613		});
614	});
615
616	//setTimeout(function () {
617	//	var $fuelPrices = $('.gas-station-prices .nav-tabs');
618	//	$fuelPrices.addClass("owl-carousel");
619	//	$fuelPrices.owlCarousel({
620	//		nav: true,
621	//		navRewind: false,
622	//		dots: false,
623	//		autoWidth: false,
624	//		responsive: {
625	//			0: {
626	//				items: 1,
627	//				slideBy: 1
628	//			},
629	//			768: {
630	//				items: 2,
631	//				slideBy: 2
632	//			},
633	//			992: {
634	//				items: 3,
635	//				slideBy: 3
636	//			}
637	//	}
638	//	});
639	//});
640
641	/* Auto resize textarea
642	 ==============================================================================*/
643	$('.form textarea').each(function() {
644		$(this).autoResize({
645			maxHeight: '500px'
646		});
647	});
648
649	/* Datepicker
650	 ==============================================================================*/
651	$('#calendar-from').datepicker({
652		changeMonth: true,
653		changeYear: true,
654		yearRange: "1990:+3",
655		onClose: function(date) {
656			$('#calendar-to').datepicker("option", "minDate", date);
657		}
658	});
659
660	$('#calendar-to').datepicker({
661		changeMonth: true,
662		changeYear: true,
663		yearRange: "1990:+3",
664		onClose: function(date) {
665			$('#calendar-from').datepicker("option", "maxDate", date);
666		}
667	});
668
669	$('.calendar').datepicker({
670		changeMonth: true,
671		changeYear: true,
672		yearRange: '1900:' + new Date().getFullYear() + ''
673	});
674
675	/* Autocomplete
676	 ==============================================================================*/
677	var availableTags = [
678		"ActionScript AppleScript Asp Scheme Ruby JavaScript ColdFusion",
679		"AppleScript",
680		"Asp",
681		"BASIC",
682		"C",
683		"C++",
684		"Clojure",
685		"COBOL",
686		"ColdFusion",
687		"Erlang",
688		"Fortran",
689		"Groovy",
690		"Haskell",
691		"Java",
692		"JavaScript",
693		"Lisp",
694		"Perl",
695		"PHP",
696		"Python",
697		"Ruby",
698		"Scala",
699		"Scheme"
700	];
701	$('.field-autocomplete').autocomplete({
702		source: availableTags,
703		open: function(event, ui) {
704			$(ui).width($(event.target).innerWidth());
705		},
706		create: function() {
707			var theme = $(this).data('theme');
708			$(this).data('ui-autocomplete')._renderMenu = function(ul, items) {
709				var that = this;
710				$.each(items, function(index, item) {
711					that._renderItemData(ul, item);
712				});
713				if (theme) $(ul).addClass('ui-autocomplete_' + theme);
714			};
715		}
716	});
717
718	/* Filter dropdown
719	 ==============================================================================*/
720	$('.dropdown-multi-selection .dropdown-toggle').on('click', function(e) {
721		e.preventDefault();
722		if ($(this).closest('.dropdown').hasClass('disabled')) return;
723		var $dropDown = $(this).closest('.dropdown-multi-selection');
724		if ($dropDown.hasClass('open')) {
725			$('.dropdown-multi-selection').removeClass('open');
726		} else {
727			$('.dropdown-multi-selection').removeClass('open');
728			$dropDown.addClass('open');
729			
730			var $ul = $dropDown.find('ul');
731			var $parents = $(this).parents();
732			if ($parents.length > 0) {
733				var $first = undefined;
734				for (var i = 0; i < $parents.length; i++){
735					if ($($parents[i]).css('overflow') === 'hidden') {
736						$first = $($parents[i]);
737						break;
738					}
739				}
740
741				if ($first) {
742					var spaceDown = $first.offset().top + $first.height() - ($dropDown.offset().top + $dropDown.height());
743					var spaceUp = $dropDown.offset().top - $first.offset().top;
744					var oldHeight = parseFloat($ul.css('max-height'));
745					var isDown = true;
746					var newHeight = oldHeight;
747
748					if (oldHeight > spaceDown) {
749						if (oldHeight > spaceUp) {
750							isDown = spaceDown > spaceUp;
751							newHeight = isDown ? spaceDown : spaceUp;
752							$ul.css('max-height', newHeight);
753						} else {
754							isDown = false;
755						}
756					}
757
758					if (!isDown) {
759						$ul.addClass('open-on-top');
760						$ul.css('top', '-' + newHeight + 'px');
761					} else {
762						$ul.removeClass('open-on-top');
763						$ul.css('top', 'auto');
764					}
765					//oldHeight = oldHeight != null ? oldHeight : parseFloat($ul.css('height'));
766
767				}
768			}
769		}
770	});
771
772	$(document).on('click', '.dropdown-currency li', function() {
773		var dropdown = $(this).closest('.dropdown');
774		var currency = $(this).find('a').html();
775		dropdown.find('li').removeClass('selected').data('selected', undefined);
776		$(this).addClass('selected');
777		dropdown.find('.dropdown-toggle__text').html(currency);
778	});
779
780	$('.dropdown-currency .dropdown-menu').on({
781		mouseenter: function () {
782			$(this).find('li.selected').toggleClass('sel selected');
783		}, mouseleave: function () {
784			if (!$(this).find('li').hasClass('selected')) $(this).find('li.sel').addClass('selected');
785			$(this).find('li.sel').removeClass('sel');
786		}
787	});
788
789	$(document).on("click", function(event) {
790		if ($(event.target).closest('.dropdown-multi-selection.open').length) return;
791		$('.dropdown-multi-selection').removeClass('open');
792	});
793
794	var hideDropdownMenuFly = function(event) {
795		if (!$(event.target).closest('.dropdown-menu_fly').length && !$(event.target).closest('.dropdown-fly-menu').length) {
796			$('#shared-fly').hide();
797			$('.owl-carousel .dropdown-toggle').removeClass('opened');
798			$(window).off('scroll', hideDropdownMenuFlyByScroll);
799			$(document).off('mousedown touchstart', hideDropdownMenuFly);
800		}
801	};
802
803	var hideDropdownMenuFlyByScroll = function() {
804		if ($('#shared-fly').css('display') === 'block') {
805			$('#shared-fly').hide();
806			$('.owl-carousel .dropdown-toggle').removeClass('opened');
807		}
808		$(window).off('scroll', hideDropdownMenuFlyByScroll);
809	};
810
811	$(document).on('click', '.owl-carousel .dropdown-toggle', function() {
812		var offsetTopFromWindow = Math.round($(this).offset().top - $(window).scrollTop() + $(this).height()),
813			offsetLeftFromWindow = Math.round($(this).offset().left - $(window).scrollLeft());
814		if ($(this).hasClass('opened')) {
815			$(this).removeClass('opened');
816			$('#shared-fly').hide();
817		} else {
818			$('.owl-carousel .dropdown-toggle').removeClass('opened');
819			$(this).addClass('opened');
820			$('#shared-fly')
821				.css({
822					'top': offsetTopFromWindow,
823					'left': offsetLeftFromWindow,
824					'position': 'fixed'
825				})
826				.show();
827			$(document).on('mousedown touchstart', hideDropdownMenuFly);
828			$(window).on('scroll', hideDropdownMenuFlyByScroll);
829		}
830	});
831
832	$('.dropdown-multi-selection').each(function() {
833		var $dropdown = $(this);
834		var $titleDrop = $dropdown.find('.dropdown-toggle span');
835		var $nameTitleDrop = $titleDrop.html();
836		insertTitleCheckFiled($dropdown, $titleDrop, $nameTitleDrop);
837		$dropdown.find('input[type="checkbox"]').on('change', function () {
838			insertTitleCheckFiled($dropdown, $titleDrop, $nameTitleDrop);
839		});
840	});
841
842	function insertTitleCheckFiled($dropdown, $titleDrop, $nameTitleDrop) {
843		var titleCheckCheckbox = [];
844		$dropdown.find('li').filter(function () { return $(this).css("display") != "none" }).find('input[type="checkbox"]:checked').each(function () {
845			titleCheckCheckbox.push($(this).closest('.checkbox').find('label span').html());
846		});
847		if (titleCheckCheckbox.length) {
848			$titleDrop.html(titleCheckCheckbox.join(', '));
849		} else {
850			$titleDrop.html($nameTitleDrop);
851		}
852	}
853
854	$('.button-reset').on('click', function(event) {
855		event.preventDefault();
856		var checkboxes = $(".filter input:checked");
857		checkboxes.prop("checked", false).trigger("refresh").trigger('change');
858	});
859
860	/* Fancybox modal
861	==============================================================================*/
862	$('.modal-slide-show').fancyboxInit({
863		padding: 10,
864		maxWidth: 960
865	});
866
867	$('.text-popup').fancyboxInit({
868		padding: 10,
869		type: 'ajax',
870		minWidth: 240,
871		maxWidth: 940
872	});
873
874	$('.show-video').fancyboxInit({
875		type: 'iframe',
876		padding: 10,
877		beforeLoad: function() {
878			var url = $(this.element).attr("href");
879			var youtubeRegex = /(?:https?:\/\/)?(?:www\.)?(?:(?:(?:youtube.com\/watch\?[^?]*v=|youtu.be\/)([\w\-]+))(?:[^\s?]+)?)/;
880			var matched = youtubeRegex.exec(url);
881			if (matched && matched.length > 1) {
882				var yuotubeId = matched[1];
883				var embeddedUrl = "https://www.youtube.com/embed/" + yuotubeId;
884				embeddedUrl += '?fs=1&autoplay=1';
885				this.href = embeddedUrl;
886			}
887		}
888	});
889
890	$(".gas-station-info-action-modal-link").fancyboxInit({
891		maxWidth: 800
892	});
893
894	function fancyboxModal(content) {
895		$.fancybox.open({
896			padding: 10,
897			content: content,
898			beforeShow: function() {
899				var $fancyBoxContent = $(this.inner);
900				var $videos = $fancyBoxContent.find('video');
901				if ($videos.length) {
902					var $video = $($videos[0]);
903					var startTime = $video.data('start-time');
904					if (startTime) {
905						var timeParts = startTime.split(":");
906						var sedonds = 3600 * parseInt(timeParts[0]) + 60 * parseInt(timeParts[1]) + parseInt(timeParts[2]);
907						$video.on('loadedmetadata', function() {
908							this.currentTime = sedonds;
909							$.fancybox.update();
910						});
911					} else {
912						$video.on('loadedmetadata', function () {
913							$.fancybox.update();
914						});
915					}
916				}
917			}
918		});
919	}
920
921	function fancyConfirm(content, callback) {
922		var ret;
923		jQuery.fancyboxInit({
924			modal: true,
925			content: '<div class="modal-confirm"><div class="modal-confirm__body">' + content + '</div><div class="group-buttons"><button id="fancyConfirm_ok" class="button">' + GlobalSettings.Ok + '</button><button id="fancyConfirm_cancel" class="button button-transparent">' + GlobalSettings.Cancel + '</button></div></div>',
926			afterShow: function() {
927				jQuery("#fancyConfirm_cancel").on("click", function() {
928					ret = false;
929					jQuery.fancybox.close();
930				});
931				jQuery("#fancyConfirm_ok").on("click", function() {
932					ret = true;
933					jQuery.fancybox.close();
934				});
935			},
936			beforeClose: function() {
937				callback.call(this, ret);
938			}
939		});
940	}
941
942	var canPlayVideo = !!document.createElement('video').canPlayType;
943	var canPlayAudio = !!document.createElement('audio').canPlayType;
944
945	if (canPlayVideo) {
946		$(document).on('click', '.show-video-local', function (event) {
947			var $element = $(this);
948			if (isDesktopBar) {
949				var startTime = $element.data('start-time');
950				event.preventDefault();
951				fancyboxModal('<div class="fancy-video-player"><video ' + (startTime ? 'data-start-time="' + startTime + '"' : '') + ' controls autoplay oncanplay="videoCanPlay(this)"><source src="' + this.href + '" type="video/mp4"></video></div>');
952			} else {
953				var target = $element.attr("target");
954				if (target != null) {
955					$element.removeAttr("target");
956					event.preventDefault();
957					setTimeout(function () {
958						$(this).trigger(event);
959					}, 10);
960				}
961			}
962		});
963	}
964
965	if (canPlayAudio) {
966		$(document).on('click', '.show-audio-player', function(event) {
967			event.preventDefault();
968			fancyboxModal('<div class="audio-player"><audio controls autoplay><source src="' + this.href + '" type="audio/mp3"></audio></div>');
969		});
970	}
971
972	$(document).on('click', '.show-rules-filling', function(event) {
973			event.preventDefault();
974			var content = $(this).attr('href');
975			fancyboxModal($(content).removeClass('hidden'));
976		})
977		.on('click', '.button_show-action', function(event) {
978			event.preventDefault();
979			var content = $(this).attr('href');
980			fancyboxModal($(content).removeClass('hidden'));
981		})
982		.on('click', '.show-fancy-confirm', function(event) {
983			event.preventDefault();
984			var content = $(this).attr('href');
985			fancyConfirm($(content).html(), function() {});
986		});
987
988	if ($('.form-trainer').length) fancyboxModal($('#trainer-modal').removeClass('hidden'));
989
990	function calcMaxHeightModalBody() {
991		var modalIndent = parseInt($('.modal-dialog').css('marginTop')) + parseInt($('.modal-dialog').css('marginBottom'));
992		var modalBodyIndent = parseInt($('.modal-body').css('marginTop')) + parseInt($('.modal-body').css('marginBottom'));
993		$('.modal-body').css('max-height', $(window).height() - modalIndent - modalBodyIndent - 2);
994	}
995
996	calcMaxHeightModalBody();
997
998
999	/* Handler collapse panel-time-line
1000	==============================================================================*/
1001	$(document)
1002		.on('show.bs.collapse', $('.panel-time-line').children('.panel-collapse'), function(e) {
1003			$(e.target).closest('.panel-time-line').addClass('opened');
1004		})
1005		.on('hide.bs.collapse', $('.panel-time-line').children('.panel-collapse'), function(e) {
1006			$(e.target).closest('.panel-time-line').removeClass('opened');
1007		});
1008
1009	/* Handler panel-asset
1010	 ==============================================================================*/
1011	$(document)
1012		.on('show.bs.collapse', '.panel-asset .panel-collapse', function() {
1013			var $text = $(this).closest('.text');
1014			$text.find('.read-more').hide();
1015			$text.find('.hide-details').removeClass('hidden');
1016			$text.find('.description-full').removeClass('hidden');
1017			$text.find('.description-cut').addClass('hidden');
1018		})
1019		.on('hide.bs.collapse', '.panel-asset .panel-collapse', function() {
1020			var $text = $(this).closest('.text');
1021			$text.find('.read-more').show();
1022			$text.find('.hide-details').addClass('hidden');
1023			$text.find('.description-full').addClass('hidden');
1024			$text.find('.description-cut').removeClass('hidden');
1025		})
1026		.on('click', '.panel-asset .view-map', function() {
1027			var panelAsset = $(this).closest('.panel-asset');
1028			if (panelAsset.find('.trigger-collapsed').hasClass('collapsed')) return;
1029			var needTodScrol = panelAsset.find('.map-container').offset().top - $(window).height() / 4;
1030			$('html, body').animate({ scrollTop: needTodScrol + 'px' }, 500);
1031		})
1032		.on('click', '.panel-asset .view-photo', function() {
1033			var panelAsset = $(this).closest('.panel-asset');
1034			if (panelAsset.find('.trigger-collapsed').hasClass('collapsed')) return;
1035			var needTodScrol = panelAsset.find('.panel-asset__slider').offset().top - $(window).height() / 4;
1036			$('html, body').animate({ scrollTop: needTodScrol + 'px' }, 500);
1037		}).on("shown.bs.collapse", ".panel-we-present .panel-collapse", function () {
1038			presentTextEllipsis();
1039		});;
1040
1041
1042	/* Ellipsis for multiple line content
1043	==============================================================================*/
1044	function presentTextEllipsis() {
1045		$('.countries .country a, .countries .country span').dotdotdot({
1046			ellipsis: ' ...',
1047			height: 40,
1048			callback: function(isTruncated, orgContent) {
1049				if (isTruncated) {
1050					$(this).attr("title", orgContent[0].data);
1051				}
1052			}
1053		});
1054	}
1055
1056	/*Ellipsis chart categories*/
1057	function chartTextEllipsis() {
1058		if ($('.chart-controls__item').length > 0) {
1059			var width = $('.chart-controls__item').width();
1060			$.each($('.chart-control_legendYears a'), function (index, categories) {
1061				var title = $(categories).attr('title');
1062				$(categories).text(title).dotdotdot({ width: width, ellipsis: '...', callback: function (isTruncated, orgContent) { if (isTruncated) { $(this).attr("title", orgContent[0].data); } } });
1063			});
1064		}
1065	}
1066
1067	function textEllipsis() {
1068		dotdotdotRun();
1069		/* setTimeout for fix IE7 bug */
1070		setTimeout(function() {
1071			dotdotdotRun();
1072		}, 500);
1073		//$(window).on("load", function() {
1074		//	// For cases when image absence can affect text truncating
1075		//	dotdotdotRun();
1076		//});
1077		presentTextEllipsis();
1078		chartTextEllipsis();
1079	}
1080
1081	function dotdotdotRun() {
1082		$('.infoblock-red .descr').dotdotdot();
1083		$('.infoblock-grey:not(.adjustable-client)').find('.infoblock-body h3,.text').dotdotdot();
1084		$('.adjustable-client').each(function () {
1085			var h = $(this).hasClass('adjustable-client_full') ? 50 : $(this).find('.text').css('max-height');
1086			$(this).find('.text').dotdotdot({ height: h });
1087		});
1088
1089		$('.page-title h1').dotdotdot();
1090		$('.infoblock-red_popular-topics .title').dotdotdot();
1091		$('.infoblock-grey_promo h2').dotdotdot();
1092	}
1093
1094	textEllipsis();
1095
1096	/* Networking block - Open/Close
1097	==============================================================================*/
1098	$('.inner-page .collapsable-widget h2').on("click", function () {
1099		$(this).parents('.collapsable-widget').find('.collapsable-widget-content').toggleClass('close');
1100		return false;
1101	});
1102
1103	/* Putting footer on the bottom of the page
1104	==============================================================================*/
1105	function calculateMinHeightMain() {
1106		$('#main').css('min-height', $(window).height() - $('#footer').outerHeight() - parseInt($('#main').css('padding-top')));
1107	}
1108
1109	calculateMinHeightMain();
1110
1111	/* Fix position of dropdown menu in footer
1112	==============================================================================*/
1113	$('#footer').find('.dropdown').on('click', function() {
1114		var dmHeight = $(this).find('.dropdown-menu').height();
1115		if (dmHeight > 100) {
1116			$(this).addClass('dropup');
1117		}
1118	});
1119
1120	/* Center error page content
1121	 ==============================================================================*/
1122	function centerErrorPage() {
1123		var offsetTop = 0;
1124		if ($('body').height() <= $(window).height()) {
1125			offsetTop = ($('#main').height() - $('.error-page').height()) / 2;
1126		} else {
1127			offsetTop = 0;
1128		}
1129		$('.error-page').css('marginTop', offsetTop);
1130	}
1131
1132	centerErrorPage();
1133
1134	/* Events for resize screen
1135	==============================================================================*/
1136	$(window).on("resize", function() {
1137		textEllipsis();
1138		calculateMinHeightMain();
1139		calcMaxHeightModalBody();
1140		centerErrorPage();
1141	});
1142
1143	/* Animate signatures
1144	 ==============================================================================*/
1145	function animateSign() {
1146		var timer = 0;
1147		var selectors = '';
1148		var countTagSpan = 0;
1149		var $textBlock;
1150		$('.animate-sign-text').each(function() {
1151			if ($(this).find('span').length > countTagSpan) {
1152				countTagSpan = $(this).find('span').length;
1153				$textBlock = $(this);
1154			}
1155		});
1156
1157		function createStylesForAnimation() {
1158			$textBlock.find('span').each(function(indexElem, element) {
1159				var index = indexElem + 1;
1160				var selector = '.start-animate .animate-sign-text span:nth-child(' + index + ') {opacity: 1; transition:opacity ' + timer + 's ease-in-out}';
1161				timer += 0.025;
1162				selectors += selector;
1163			});
1164		}
1165
1166		if ($textBlock && $textBlock.length) createStylesForAnimation();
1167		$('body').append('<style>' + selectors + '</style>');
1168		$('.animate-sign').on("click", function() {
1169			var $contentBlock = $(this).find('.animate-sign-content');
1170			if ($contentBlock.hasClass('start-animate')) return;
1171			$contentBlock.addClass('start-animate');
1172			setTimeout(function() {
1173				$contentBlock.removeClass('start-animate');
1174			}, timer + 7000);
1175		});
1176	}
1177
1178	if ($('.trainer-content').length) animateSign();
1179
1180	/* On toggle visibility field search
1181	 ==============================================================================*/
1182	$('.dropdown-toggle_search-btn').on('click', function() {
1183		$(this).parent().addClass('opened');
1184	});
1185
1186	$(document).on('click', function(e) {
1187		if ($(e.target).closest('.dropdown-toggle_search-btn').length || $(e.target).closest('.search.dropdown-menu').length) return;
1188		$('.dropdown_header-search').removeClass('opened');
1189	});
1190
1191	$('.survey__question').find('input').on('change', function() {
1192		var $surveyQuestion = $(this).closest('.survey__question');
1193		var isShowInputText = !$(this).closest('.survey__question').find('.another-answer-box input').is(':checked');
1194		var $inputAnswer = $surveyQuestion.find('.another-answer-text');
1195		$inputAnswer.toggleClass('hidden', isShowInputText); //.focus();
1196		if (!isShowInputText) $inputAnswer.trigger("focus");
1197	});
1198
1199	/* Cartography
1200	 ==============================================================================*/
1201	var $tabContent = $('.map-finder__tab-content');
1202	var changeSizeMapContainer;
1203	if (isFullScreenEnable) {
1204		changeSizeMapContainer = function() {
1205			if (document.fullscreenElement) {
1206				calcHeightContainerMap(screen.height);
1207			} else {
1208				calcHeightContainerMap($('#map').height());
1209			}
1210		};
1211	} else {
1212		changeSizeMapContainer = function() {
1213			if ($('.panel-full-screen').hasClass('in-full-screen')) {
1214				calcHeightContainerMap($(window).height());
1215			} else {
1216				calcHeightContainerMap($('#map').height());
1217			}
1218		};
1219	}
1220
1221	function calcHeightContainerMap(height) {
1222		var $tabsContent = $('.map-finder__tabs-content');
1223		var minHeightTabsContent = height - parseInt($tabsContent.css('margin-top')) - parseInt($tabsContent.css('margin-bottom'));
1224		$('.map-finder__tab-content').css('max-height', minHeightTabsContent);
1225	}
1226
1227	$(document)
1228		.on('click', '.map-finder__tab', function() {
1229			if ($('.map-finder').hasClass('opened') && $(this).hasClass('selected')) {
1230				$('.map-finder').removeClass('opened');
1231			} else {
1232				var idTabContent = $(this).attr('href');
1233				$('.map-finder__tab-content').removeClass('opened');
1234				$('' + idTabContent + '').addClass('opened');
1235				$('.map-finder__tab').removeClass('selected');
1236				$(this).addClass('selected');
1237				$('.map-finder').addClass('opened');
1238			}
1239			return false;
1240		});
1241
1242	$tabContent.mCustomScrollbar({
1243		axis: 'y',
1244		scrollInertia: 10,
1245		advanced: {
1246			updateOnContentResize: true,
1247			autoUpdateTimeout: 30
1248		},
1249		mouseWheel: {
1250			preventDefault: true
1251		},
1252		callbacks: {
1253			onScrollStart: function() {
1254				$('.map-finder .select-custom').select2("close");
1255			}
1256		}
1257	});
1258
1259	function updateSizeMap() {
1260		changeSizeMapContainer();
1261		$tabContent.mCustomScrollbar('update');
1262		typeof window.resizeMap === "function" && window.resizeMap();
1263	}
1264
1265	$(window).on('resize', function() {
1266		if ($('.panel-full-screen--map').length) updateSizeMap();
1267	});
1268
1269	if (document.addEventListener) {
1270		document.addEventListener("fullscreenchange", function() {
1271			if ($('.panel-full-screen--map').length) updateSizeMap();
1272		});
1273	}
1274
1275	$('.map-finder .select-custom')
1276		.each(function() {
1277			var theme = $(this).data('theme') || 'bd-red';
1278			var search = $(this).data('search') ? 0 : -1;
1279			$(this)
1280				.select2({
1281					width: 'auto',
1282					dropdownParent: $('.panel-full-screen--map'),
1283					minimumResultsForSearch: search,
1284					theme: theme
1285				});
1286		});
1287
1288	$('.is-check-element').find('input:checkbox').on('change', function() {
1289		if ($(this).is(':checked')) {
1290			$(this).closest('.is-check-element').addClass('selected');
1291		} else {
1292			$(this).closest('.is-check-element').removeClass('selected');
1293		}
1294	});
1295
1296	var timeValue = [0, 24];
1297	$('.slider-timing').slider({
1298		range: true,
1299		min: timeValue[0],
1300		max: timeValue[1],
1301		values: timeValue,
1302		create: function(event, ui) {
1303			$(event.target).find('.ui-slider-handle').eq(0).append($('<div></div>', { 'class': 'time-range time-range_from', html: timeValue[0] }));
1304			$(event.target).find('.ui-slider-handle').eq(1).append($('<div></div>', { 'class': 'time-range time-range_to', html: timeValue[1] }));
1305		},
1306		slide: function(event, ui) {
1307			$(event.target).find('.time-range_from').text(ui.values[0]);
1308			$(event.target).find('.time-range_to').text(ui.values[1]);
1309		},
1310		change: function(event, ui) {
1311			$(event.target).find('.time-range_from').text(ui.values[0]);
1312			$(event.target).find('.time-range_to').text(ui.values[1]);
1313		}
1314	});
1315
1316	function onClickMultiButton() {
1317		var $item = $(this).closest('.filter-time-item');
1318		var $buttons = $item.find('.multi-button__item');
1319		var $weekDay = $item.find('.week').find('input');
1320		var $timeSlider = $item.find('.slider-timing');
1321		var isLink = !!$(this).attr('href');
1322		var disableWeedDay = function() {
1323			$buttons.removeClass('selected').find('input').prop('checked', false);
1324			$timeSlider.slider('disable');
1325			$item.addClass('slider-timing-disable');
1326			$weekDay.prop("disabled", true);
1327			$(this).find('input').prop('checked', true);
1328		};
1329		var enableWeekDay = function() {
1330			$buttons.removeClass('selected').find('input').prop('checked', false);
1331			$timeSlider.slider('enable');
1332			$item.removeClass('slider-timing-disable');
1333			$weekDay.prop("disabled", false);
1334		};
1335
1336		if (isLink) {
1337			if (!$(this).hasClass('selected')) {
1338				enableWeekDay.call(this);
1339				$(this).addClass('selected');
1340			} else {
1341				$(this).removeClass('selected');
1342			}
1343		} else {
1344			var idPanelCollapse = $(this).siblings('[data-toggle="collapse"]').attr('href');
1345			if ($(idPanelCollapse).hasClass('in')) $(idPanelCollapse).collapse('hide');
1346			if ($(this).hasClass('selected')) {
1347				enableWeekDay.call(this);
1348			} else {
1349				disableWeedDay.call(this);
1350				$(this).addClass('selected');
1351			}
1352		}
1353	}
1354
1355	$('.multi-button__item').on('click', onClickMultiButton);
1356
1357	/* Modification input file
1358	 ==============================================================================*/
1359	initInputFile();
1360
1361	/* Toggle country
1362	 ==============================================================================*/
1363	$('.dropdown-toggle_country').on('click', function(event) {
1364		event.preventDefault();
1365		var $dropdown = $(this).closest('.dropdown_country');
1366		$dropdown.toggleClass('opened');
1367		$dropdown.find('.search__field').trigger("focus");
1368	});
1369
1370	$(document).on('click', function(event) {
1371		if ($(event.target).closest('.dropdown_country').length && !$(event.target).closest('.dropdown-menu__item').length) return;
1372		$('.dropdown_country').removeClass('opened');
1373	});
1374});
1375
1376/* For IE - Hide focus on input elements
1377==============================================================================*/
1378(function($) {
1379	$(function() {
1380		window.setInterval(function() {
1381			$(document.activeElement).filter('input:hidden').trigger("blur");
1382		}, 500);
1383	});
1384})(jQuery);
1385
1386window.scrollToElement = function($element, timeScroll) {
1387	var needTodScroll = $element.offset().top - $('#header').height();
1388	$('html, body').animate({ scrollTop: needTodScroll + 'px' }, timeScroll);
1389};
1390
1391/* Tool Tip */
1392function initToolTip($container) {
1393	var $hiddenPopover = $('.popover-custom--hidden');
1394	var $hiddenPopoverContent = $hiddenPopover.find('.popover-content');
1395	$container.find('.tooltip_item').on("mouseenter mouseleave", function (event) {
1396		if (event.type === "mouseenter") {
1397			var content = $(this).find('.tooltip_content').html();
1398			$hiddenPopoverContent.html(content);
1399			var offsetTop = $(this).offset().top - $(window).scrollTop() - $('#header').innerHeight() - $hiddenPopover.innerHe
1399ight() - 20;
1400			var placementPopover = offsetTop > 0 ? 'top' : 'bottom';
1401			$(this).popover({
1402				title: '',
1403				trigger: 'manual',
1404				content: function () {
1405					return content;
1406				},
1407				placement: placementPopover,
1408				container: 'body',
1409				html: true
1410			});
1411			$('.tooltip_item').not(this).popover('hide').popover('destroy');
1412			$(this).popover('show');
1413		} else if (event.type === "mouseleave") {
1414			var _this = this;
1415			var popoverTimerId = setInterval(function () {
1416				if (!$(".popover:hover").length) {
1417					if (!$(_this).is(':hover')) {
1418						$(_this).popover('hide').popover('destroy');
1419						$hiddenPopoverContent.html('');
1420						clearInterval(popoverTimerId);
1421					}
1422				}
1423			}, 1000);
1424		}
1425	}
1426	);
1427}
1428
1429/* Input files */
1430function initInputFile(container) {
1431	var $wrapInputFile = $('<div class="jq-file form-control"></div>');
1432	var fileInputs = typeof container === 'undefined' ? $('[type="file"]') : $(container).find('[type="file"]');
1433	fileInputs.each(function() {
1434		var $input = $(this);
1435		var fileNumber = $input.data('file-number') || '';
1436		var placeholder = $input.data('placeholder') || '';
1437		var browse = $input.data('browse') || '';
1438		var $name = $('<div>', { 'class': 'jq-file__name', html: placeholder });
1439		var $file = $('<div>', { 'class': 'jq-file__browse', html: browse });
1440		$input
1441			.wrap($wrapInputFile)
1442			.before($name, $file)
1443			.on('change', function() {
1444				var value = $input.val();
1445				if ($input.is('[multiple]') && $input[0].files) {
1446					value = '';
1447					var files = $input[0].files.length;
1448					if (files > 0) {
1449						value = 'Загружено файлов: ' + fileNumber + ' ' + files;
1450					}
1451				}
1452				value = value.replace(/.+[\\\/]/, '') || placeholder;
1453				$name.text(value);
1454			});
1455	});
1456}
1457
1458function videoCanPlay(el) {
1459	if ($('html').hasClass('ua-desktop')) {
1460		if (el != null && $(el).length > 0 && $(el).context != null) {
1461			var w = $(el).context.videoWidth;
1462			var h = $(el).context.videoHeight;
1463			if (w > 0) {
1464				var ww = $("html").width();
1465				var w1 = w;
1466				var h1 = h;
1467				if (ww <= w1) {
1468					w1 = ww - 300;
1469					h1 = h / (w / w1);
1470
1471					w = w1;
1472					h = h1 - 50;
1473				}
1474				$(el).css("width", w + "px").css("height", h + "px");
1475				$.fancybox.update();
1476			}
1477		}
1478	}
1479};
1480// Content of this file was generated on application start
1481var Constants = {PageSize:10,MediaLibraryPageSize:12,PaginationSize:3,OilCatalogPageSize:9,WinnersPageSize:20};
1482Constants.queryParamNames = {
1483  "LanguageCode": "lng",
1484  "LanguageGuid": "l",
1485  "WidgetId": "wid",
1486  "PressReleaseId": "rid",
1487  "InformationMaterialId": "mid",
1488  "MediaFileId": "mfid",
1489  "Region": "reg",
1490  "SearchQuery": "query",
1491  "Industry": "ind",
1492  "Country": "ctry",
1493  "StartDate": "sdate",
1494  "EndDate": "edate",
1495  "FileType": "ftype",
1496  "Theme": "theme",
1497  "Person": "pers",
1498  "Project": "proj",
1499  "Organization": "org",
1500  "Audience": "aud",
1501  "Importance": "imp",
1502  "Tags": "tags",
1503  "Id": "id",
1504  "IsFullScreenMode": "isFullScreenMode",
1505  "Expand": "expand",
1506  "AdvertisementId": "aid",
1507  "TypeId": "typeid",
1508  "TreeId": "treeid",
1509  "OwnerId": "ownerid",
1510  "Query": "query",
1511  "OrganizationId": "organizationId",
1512  "ProjectId": "projectId",
1513  "FieldOfActivityId": "fieldOfActivityId",
1514  "DownloadFile": "dl",
1515  "ConfirmationToken": "token",
1516  "SubscriptionAction": "action",
1517  "SubscriptionGuid": "subscription",
1518  "RegistrationGuid": "registration",
1519  "EventId": "eventId",
1520  "PreviewMassMediaId": "preview_corpmediaid",
1521  "PreviewEventId": "preview_eventid",
1522  "OfficeWebAppsFileSource": "src",
1523  "OilProductId": "product",
1524  "ApplicationId": "application",
1525  "ViscosityId": "viscosity",
1526  "BrandId": "brand",
1527  "GasStationId": "gasStationId",
1528  "Take": "take",
1529  "Skip": "skip"
1530};
1531Constants.AjaxResultCodes = {
1532  "Success": "Success",
1533  "Error": "Error"
1534};
1535Constants.InformationMaterialTypes = {
1536  "Default": 0,
1537  "MediaAlbum": 1,
1538  "PressRelease": 2,
1539  "News": 3,
1540  "MassMediaIssue": 4,
1541  "Event": 5,
1542  "Publication": 6
1543};
1544Constants.fileTypes = {
1545  "Default": 0,
1546  "Document": 1,
1547  "Image": 2,
1548  "Video": 3,
1549  "Audio": 4,
1550  "Template": 5,
1551  "Zip": 6
1552};
1553Constants.previewTypes = {
1554  "Default": 0,
1555  "NewsFeeds": 1,
1556  "Album": 2,
1557  "AlbumFeed": 3,
1558  "Interestingly": 4,
1559  "MediaLibrary": 5,
1560  "ItMayInterestHigher": 6,
1561  "ItMayInterestLower": 7,
1562  "Photowire": 8,
1563  "Videos": 9,
1564  "PhotoRibbon": 10
1565};
1566Constants.Languages = ['kz','ru','nl','cn','sk','ka','sr','de','fi','el','pl','dk','en','se','bg','no','az','hr','pt','it','tr','fr','hu','cz','lt','lv','uk','me','ar','mk','ro','es','uz','be'];
1567;
1568/*!
1569 * jQuery Cookie Plugin v1.4.1
1570 * https://github.com/carhartl/jquery-cookie
1571 *
1572 * Copyright 2013 Klaus Hartl
1573 * Released under the MIT license
1574 */
1575(function (factory) {
1576	if (typeof define === 'function' && define.amd) {
1577		// AMD
1578		define(['jquery'], factory);
1579	} else if (typeof exports === 'object') {
1580		// CommonJS
1581		factory(require('jquery'));
1582	} else {
1583		// Browser globals
1584		factory(jQuery);
1585	}
1586}(function ($) {
1587
1588	var pluses = /\+/g;
1589
1590	function encode(s) {
1591		return config.raw ? s : encodeURIComponent(s);
1592	}
1593
1594	function decode(s) {
1595		return config.raw ? s : decodeURIComponent(s);
1596	}
1597
1598	function stringifyCookieValue(value) {
1599		return encode(config.json ? JSON.stringify(value) : String(value));
1600	}
1601
1602	function parseCookieValue(s) {
1603		if (s.indexOf('"') === 0) {
1604			// This is a quoted cookie as according to RFC2068, unescape...
1605			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
1606		}
1607
1608		try {
1609			// Replace server-side written pluses with spaces.
1610			// If we can't decode the cookie, ignore it, it's unusable.
1611			// If we can't parse the cookie, ignore it, it's unusable.
1612			s = decodeURIComponent(s.replace(pluses, ' '));
1613			return config.json ? JSON.parse(s) : s;
1614		} catch(e) {}
1615	}
1616
1617	function read(s, converter) {
1618		var value = config.raw ? s : parseCookieValue(s);
1619		return $.isFunction(converter) ? converter(value) : value;
1620	}
1621
1622	var config = $.cookie = function (key, value, options) {
1623
1624		// Write
1625
1626		if (value !== undefined && !$.isFunction(value)) {
1627			options = $.extend({}, config.defaults, options);
1628
1629			if (typeof options.expires === 'number') {
1630				var days = options.expires, t = options.expires = new Date();
1631				t.setTime(+t + days * 864e+5);
1632			}
1633
1634			return (document.cookie = [
1635				encode(key), '=', stringifyCookieValue(value),
1636				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
1637				options.path    ? '; path=' + options.path : '',
1638				options.domain  ? '; domain=' + options.domain : '',
1639				options.secure  ? '; secure' : ''
1640			].join(''));
1641		}
1642
1643		// Read
1644
1645		var result = key ? undefined : {};
1646
1647		// To prevent the for loop in the first place assign an empty array
1648		// in case there are no cookies at all. Also prevents odd result when
1649		// calling $.cookie().
1650		var cookies = document.cookie ? document.cookie.split('; ') : [];
1651
1652		for (var i = 0, l = cookies.length; i < l; i++) {
1653			var parts = cookies[i].split('=');
1654			var name = decode(parts.shift());
1655			var cookie = parts.join('=');
1656
1657			if (key && key === name) {
1658				// If second argument (value) is a function it's a converter...
1659				result = read(cookie, value);
1660				break;
1661			}
1662
1663			// Prevent storing a cookie that we couldn't decode.
1664			if (!key && (cookie = read(cookie)) !== undefined) {
1665				result[name] = cookie;
1666			}
1667		}
1668
1669		return result;
1670	};
1671
1672	config.defaults = {};
1673
1674	$.removeCookie = function (key, options) {
1675		if ($.cookie(key) === undefined) {
1676			return false;
1677		}
1678
1679		// Must not alter options, thus extending a fresh object...
1680		$.cookie(key, '', $.extend({}, options, { expires: -1 }));
1681		return !$.cookie(key);
1682	};
1683
1684}));
1685;
1686(function ($) {
1687	$.lukoilGetCookie = function (key) {
1688		return Cookies.get(key);
1689	}
1690
1691	$.lukoilSaveCookie = function (key, value, config) {
1692		var redList = [
1693			"LukCookiePolicy",
1694			"LukCookiePolicy_functional",
1695			"LukCookiePolicy_analystic",
1696
1697			"LukCartMapPositionYandex",
1698			"LukCartMapPositionGoogle",
1699
1700			"LukCountryCode",
1701			"LukGeoObjectId",
1702			"LukGeolocation",
1703			"LukLocationSelect",
1704			"LukLanguage",
1705
1706			"LukDisplayedBanners",
1707			"LukDisplayedBannersAllowAdditional",
1708			"LukOnlineSuveyUserId",
1709			"LukOnlineSurveySkipIds",
1710
1711			"LukRedirected",
1712			"OldSiteRedirection",
1713			"OldSiteRedirectionSession",
1714
1715			"azs_prices_station_id",
1716
1717			"FULL_SITE_MODE",
1718			"TEXT_SIZE",
1719			"WIDGETS_SAVED",
1720
1721			"LukSlider"
1722		];
1723
1724		var functionalCookieEnabled = true;
1725		
1726		if (config != null) {
1727			Cookies.set(key, value, config);
1728		} else {
1729			Cookies.set(key, value);
1730		}
1731	}
1732})(jQuery);;
1733// @hash v3-7B773953ACF2FA892AD2AE4AFA19BF74FBDAFC5B
1734// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden.
1735// Version: 2.1.1-dev-20151124-1300 (build 563ed55)
1736// Generated at:
1737///////////////////////////////////////////////////////////////////////////////
1738/*! globaldata v0.0.1 | MIT */
1739;
1740(function (global, factory) {
1741    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (function () {
1742        var current = global.GlobalData;
1743        var exports = global.GlobalData = factory();
1744        exports.noConflict = function () {
1745            global.GlobalData = current;return exports;
1746        };
1747    })());
1748})(this, function () {
1749    'use strict';
1750
1751    ///* eslint-disable no-var */
1752    //function assign(target) {
1753    //    for (var i = 1; i < arguments.length; i++) {
1754    //        var source = arguments[i];
1755    //        for (var key in source) {
1756    //            target[key] = source[key];
1757    //        }
1758    //    }
1759    //    return target
1760    //}
1761    ///* eslint-enable no-var */
1762
1763    /* eslint-disable no-var */
1764
1765    function main(url, name) {
1766        var _handshake = undefined;
1767        var _key = undefined;
1768        var _url = undefined;
1769        var _name = "globaldata-api";
1770
1771        //window.addEventListener ?
1772        //    window.addEventListener("load", constr, false) :
1773        //    window.attachEvent && window.attachEvent("onload", constr);
1774
1775        function handshake() {
1776            Postmate.debug = true;
1777            _handshake = new Postmate({
1778                container: document.body,
1779                url: _url,
1780                name: _name
1781            });
1782        }
1783
1784        function initsync(url, key) {
1785            _url = url + "?" + key;
1786            handshake();
1787        }
1788        function init(url, key) {
1789            _url = url + "?" + key;
1790            if (document.readyState === "loading") {
1791                window.addEventListener ? window.addEventListener("DOMContentLoaded", handshake, false) : window.attachEvent && window.attachEvent("onDOMContentLoaded ", handshake);
1792            } else {
1793                handshake();
1794            }
1795        }
1796
1797        function set(name, value) {
1798            return regeneratorRuntime.async(function set$(context$3$0) {
1799                var _this = this;
1800
1801                while (1) switch (context$3$0.prev = context$3$0.next) {
1802                    case 0:
1803                        if (!(typeof _handshake === 'undefined')) {
1804                            context$3$0.next = 3;
1805                            break;
1806                        }
1807
1808                        console.log("run init before use");
1809                        return context$3$0.abrupt('return');
1810
1811                    case 3:
1812                        context$3$0.next = 5;
1813                        return regeneratorRuntime.awrap(_handshake.then(function callee$3$0(child) {
1814                            return regeneratorRuntime.async(function callee$3$0$(context$4$0) {
1815                                while (1) switch (context$4$0.prev = context$4$0.next) {
1816                                    case 0:
1817                                        context$4$0.next = 2;
1818                                        return regeneratorRuntime.awrap(child.call('set_' + name, value));
1819
1820                                    case 2:
1821                                    case 'end':
1822                                        return context$4$0.stop();
1823                                }
1824                            }, null, _this);
1825                        }));
1826
1827                    case 5:
1828                    case 'end':
1829                        return context$3$0.stop();
1830                }
1831            }, null, this);
1832        }
1833
1834        function get(name) {
1835            var args$3$0 = arguments;
1836            return regeneratorRuntime.async(function get$(context$3$0) {
1837                var _this2 = this;
1838
1839                while (1) switch (context$3$0.prev = context$3$0.next) {
1840                    case 0:
1841                        if (!(typeof _handshake === 'undefined' || args$3$0.length && !name)) {
1842                            context$3$0.next = 3;
1843                            break;
1844                        }
1845
1846                        console.log("run init before use");
1847                        return context$3$0.abrupt('return');
1848
1849                    case 3:
1850                        context$3$0.next = 5;
1851                        return regeneratorRuntime.awrap(_handshake.then(function callee$3$0(child) {
1852                            return regeneratorRuntime.async(function callee$3$0$(context$4$0) {
1853                                while (1) switch (context$4$0.prev = context$4$0.next) {
1854                                    case 0:
1855                                        context$4$0.next = 2;
1856                                        return regeneratorRuntime.awrap(child.get(name).then(function (data) {
1857                                            /*console.log(name + " - " + data);*/return data;
1858                                        }));
1859
1860                                    case 2:
1861                                        return context$4$0.abrupt('return', context$4$0.sent);
1862
1863                                    case 3:
1864                                    case 'end':
1865                                        return context$4$0.stop();
1866                                }
1867                            }, null, _this2);
1868                        }));
1869
1870                    case 5:
1871                        return context$3$0.abrupt('return', context$3$0.sent);
1872
1873                    case 6:
1874                    case 'end':
1875                        return context$3$0.stop();
1876                }
1877            }, null, this);
1878        }
1879
1880        function remove(name) {
1881            var args$3$0 = arguments;
1882            return regeneratorRuntime.async(function remove$(context$3$0) {
1883                var _this3 = this;
1884
1885                while (1) switch (context$3$0.prev = context$3$0.next) {
1886                    case 0:
1887                        if (!(typeof _handshake === 'undefined' || args$3$0.length && !name)) {
1888                            context$3$0.next = 3;
1889                            break;
1890                        }
1891
1892                        console.log("run init before use");
1893                        return context$3$0.abrupt('return');
1894
1895                    case 3:
1896                        context$3$0.next = 5;
1897                        return regeneratorRuntime.awrap(_handshake.then(function callee$3$0(child) {
1898                            return regeneratorRuntime.async(function callee$3$0$(context$4$0) {
1899                                while (1) switch (context$4$0.prev = context$4$0.next) {
1900                                    case 0:
1901                                        context$4$0.next = 2;
1902                                        return regeneratorRuntime.awrap(child.call('remove_' + name, value));
1903
1904                                    case 2:
1905                                    case 'end':
1906                                        return context$4$0.stop();
1907                                }
1908                            }, null, _this3);
1909                        }));
1910
1911                    case 5:
1912                    case 'end':
1913                        return context$3$0.stop();
1914                }
1915            }, null, this);
1916        }
1917
1918        return Object.create({
1919            init: init,
1920            initsync: initsync,
1921            set: set,
1922            get: get,
1923            remove: remove
1924        });
1925    }
1926
1927    var api = main();
1928    /* eslint-enable no-var */
1929
1930    return api;
1931});;
1932var LukoilApp = new Marionette.Application();
1933
1934$(document).ready(function () {
1935	if (!Date.prototype.toISOString) {
1936		(function () {
1937
1938			function pad(number) {
1939				if (number < 10) {
1940					return '0' + number;
1941				}
1942				return number;
1943			}
1944
1945			Date.prototype.toISOString = function () {
1946				return this.getUTCFullYear() +
1947					'-' + pad(this.getUTCMonth() + 1) +
1948					'-' + pad(this.getUTCDate()) +
1949					'T' + pad(this.getUTCHours()) +
1950					':' + pad(this.getUTCMinutes()) +
1951					':' + pad(this.getUTCSeconds()) +
1952					'.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) +
1953					'Z';
1954			};
1955		}());
1956	}
1957
1958	(function() {
1959		var D = new Date('2011-06-02T09:34:29+02:00');
1960		if (isNaN(D) || D.getUTCMonth() !== 5 || D.getUTCDate() !== 2 ||
1961			D.getUTCHours() !== 7 || D.getUTCMinutes() !== 34) {
1962			Date.fromISO = function(s) {
1963				var day,
1964					tz,
1965					rx = /^(\d{4}\-\d\d\-\d\d([tT][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
1966					p = rx.exec(s) || [];
1967				if (p[1]) {
1968					day = p[1].split(/\D/);
1969					for (var i = 0, L = day.length; i < L; i++) {
1970						day[i] = parseInt(day[i], 10) || 0;
1971					}
1972					day[1] -= 1;
1973					day = new Date(Date.UTC.apply(Date, day));
1974					if (!day.getDate()) return NaN;
1975					if (p[5]) {
1976						tz = (parseInt(p[5], 10) * 60);
1977						if (p[6]) tz += parseInt(p[6], 10);
1978						if (p[4] == '+') tz *= -1;
1979						if (tz) day.setUTCMinutes(day.getUTCMinutes() + tz);
1980					}
1981					return day;
1982				}
1983				return NaN;
1984			};
1985		} else {
1986			Date.fromISO = function(s) {
1987				return new Date(s);
1988			};
1989		}
1990	})();
1991
1992	var options = {};
1993
1994	if (lukAppSettings) {
1995		$.extend(options, lukAppSettings);
1996	}
1997
1998	setTimeout(function() {
1999		$(document).on("shown.bs.collapse", ".ua-safari .content .panel-collapse", function () {
2000			$(this).find("img").each(function() {
2001				var $clone = $(this).clone(true);
2002				$(this).replaceWith($clone);
2003			});
2004		});
2005	},100);
2006
2007	if ($('.col-sm-3.col-md-3.content-block-right').length > 0) {
2008		if ($('.col-sm-3.col-md-3.content-block-right').first().children().length == 0) {
2009			$('.col-sm-3.col-md-3.content-block-right').first().hide();
2010			$('.col-sm-9.col-md-9.content-block-left').css('width', '100%');
2011			$('.col-sm-9.col-md-9.content-block-left').first().css('width', '100%');
2012			$('.col-sm-9.col-md-9.content-block-left').first().find('.content').first().css('padding', '0');
2013			if ($(window).width() > 800) {
2014				$(':not(.adjustable-client-container .infoblock-grey).infoblock-grey .image').css('max-height', '152px');
2015				$(':not(.adjustable-client-container .infoblock-grey).infoblock-grey .image img').css('height', '152px');
2016			}
2017		}
2018	}
2019
2020	LukoilApp.start(options);
2021});
2022
2023/*
2024Number.prototype.formatNumber(n, x, s, c)
2025	@param integer	n: length of decimal
2026	@param integer	x: length of whole part
2027	@param mixed	s: sections delimiter
2028	@param mixed	c: decimal delimiter
2029*/
2030Number.prototype.formatNumber = function (n, x, s, c) {
2031	var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
2032		num = this.toFixed(Math.max(0, ~~n));
2033
2034	return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ','));
2035};
2036
2037String.prototype.encodeURIComponent = function () {
2038	return isNullOrWhiteSpace(this) ? null : encodeURIComponent(this);
2039};
2040String.prototype.decodeURIComponent = function () {
2041	return isNullOrWhiteSpace(this) ? null : decodeURIComponent(this);
2042};
2043
2044if (typeof String.prototype.startsWith != 'function') {
2045	String.prototype.startsWith = function (str) {
2046		return this.substring(0, str.length) === str;
2047	}
2048};
2049
2050Date.prototype.localAsUtcDate = function() {
2051	return new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
2052};
2053
2054Date.prototype.utcAslocalDate = function () {
2055	return new Date(this.getUTCFullYear(), this.getUTCMonth(), this.getUTCDate());
2056};
2057
2058function isNullOrWhiteSpace(value) {
2059	return value == null || value.trim() == "";
2060}
2061
2062function submitSearchForm(form) {
2063	var input = $(form).find(":input.inputSearchQuery");
2064	var val = input.val().trim();
2065	if (val != "") {
2066		$(form).find(":input.searchQuery").val(val.encodeURIComponent());
2067	} else {
2068		return false;
2069	}
2070	return true;
2071}
2072
2073/*
2074	Jquery Plugins
2075*/
2076(function ($) {
2077	$.validator.messages.required = GlobalSettings.Validator.Required;
2078	$.validator.messages.email = GlobalSettings.Validator.Email;
2079	$.validator.messages.maxlength = $.validator.format(GlobalSettings.Validator.MaxLength);
2080	$.validator.addMethod("regex", function (value, element, regstring) {
2081		if (this.optional(element)) {
2082			return true;
2083		}
2084		var regParts = regstring.match(/^\/(.*?)\/([gim]*)$/);
2085		var regexp = regParts ? new RegExp(regParts[1], regParts[2]) : new RegExp(regstring);
2086		var regexMessage = $(element).attr("regexMessage");
2087		if (regexMessage == null || regexMessage == "") {
2088			regexMessage = GlobalSettings.Validator.Regex;
2089		}
2090		$.validator.messages["regex"] = regexMessage;
2091		return regexp.test(value);
2092	}, GlobalSettings.Validator.Regex);
2093
2094	// Date now max validator
2095	$.validator.addMethod("lukoildatenowmax", function (value, element, params) {
2096		try {
2097			return (!value.trim()) || ($.datepicker.parseDate(GlobalSettings.ViewForm.DateFormat, value) <= $.datepicker.parseDate(GlobalSettings.ViewForm.DateFormat, params.nowdate));
2098		} catch (e) {
2099			return false;
2100		}
2101	});
2102	$.validator.unobtrusive.adapters.add("lukoildatenowmax", ['nowdate'], function (options) {
2103		var params = { nowdate: options.params.nowdate };
2104		options.rules["lukoildatenowmax"] = params;
2105		options.messages["lukoildatenowmax"] = options.message;
2106	});
2107
2108	jQuery.validator.setDefaults({
2109		ignore: ".ignoreValidate",
2110		highlight: function (element) {
2111			if ($(element).is("select")) {
2112				$(element).closest("div.form-control").addClass("error");
2113			}
2114			$(element).addClass("input-validation-error");
2115		},
2116		unhighlight: function (element) {
2117			if ($(element).is("select")) {
2118				$(element).closest("div.form-control").removeClass("error");
2119			}
2120			$(element).removeClass("input-validation-error");
2121		}
2122	});
2123
2124	//File size validator
2125	jQuery.validator.unobtrusive.adapters.add("filesize", ["maxfilesizemb"], function (options) {
2126		var params = { maxfilesizemb: options.params.maxfilesizemb };
2127
2128		options.rules["filesize"] = params;
2129		if (options.message) {
2130			options.messages["filesize"] = options.message;
2131		}
2132	});
2133
2134	jQuery.validator.addMethod("filesize", function (value, element, param) {
2135		if (value === "") {
2136			return true;
2137		}
2138
2139		var maxFileSizeMb = parseInt(param.maxfilesizemb);
2140
2141		// use HTML5 File API to check selected file size
2142		// https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
2143		// http://caniuse.com/#feat=fileapi
2144		if (element.files != undefined && element.files[0] != undefined && element.files[0].size != undefined) {
2145			var filesize = parseInt(element.files[0].size);
2146
2147			return filesize <= maxFileSizeMb * 1024 * 1024;
2148		}
2149
2150		// if the browser doesn't support the HTML5 file API, just return true
2151		// since returning false would prevent submitting the form 
2152		return true;
2153	});
2154
2155	$.fn.getNullValue = function () {
2156		var val = $(this).val();
2157		return val == "null" ? null : val;
2158	};
2159
2160	$.fn.formStyler = function (isDestroy) {
2161		$(this).find("select.select-custom").initSelect2(isDestroy);
2162		return this;
2163	};
2164
2165	$.fn.destroySelect2 = function () {
2166		$(this).select2("destroy");
2167	};
2168
2169	$.fn.initSelect2 = function (isDestroy) {
2170		$(this).each(function () {
2171			var minimumResultsForSearch = Infinity;
2172			var dataSearch = $(this).attr("data-search");
2173			if (dataSearch != null && dataSearch.toLowerCase() == 'true') {
2174				minimumResultsForSearch = 1;
2175			}
2176			if (isDestroy != null && isDestroy) {
2177				$(this).destroySelect2();
2178			}
2179			var theme = $(this).attr("data-theme");
2180			var select2Options = {
2181				minimumResultsForSearch: minimumResultsForSearch,
2182				width: 'auto',
2183				language: window.GlobalSettings.CurrentLanguage,
2184				theme: theme || ''
2185			};
2186			var dataChangeSelectAll = $(this).attr("data-change-select-all");
2187			if (dataChangeSelectAll != null && dataChangeSelectAll.toLowerCase() == 'true') {
2188				select2Options.templateResult = function(data) {
2189					if (data.id === '' || data.id === 'null' || data.id === '0') {
2190						return GlobalSettings.SelectAllOptionText;
2191					}
2192					return data.text;
2193				};
2194			}
2195			$(this).select2(select2Options).on('select2:close', function() {
2196				var frm = $(this).closest("form");
2197				if (frm != null) {
2198					var validator = $(frm).validate();
2199					if (validator != null) {
2200						$(this).valid();
2201						$(frm).fixValidationStyle();
2202					}
2203				}
2204			});
2205		});
2206		
2207		return this;
2208	};
2209
2210	$.fn.setCurrentValuesAsDefault = function () {
2211		$(this).find(":input").each(function () {
2212			var type = $(this).prop("type");
2213			if (type === "checkbox" || type === "radio") {
2214				$(this).prop("defaultChecked", $(this).prop("checked"));
2215			} else if (type === "hidden" || type === "password" || type === "text" || type === "textarea") {
2216				$(this).prop("defaultValue", $(this).prop("value"));
2217			} else if (type === "select-one" || type === "select-multiple") {
2218				$(this).find("option").each(function () {
2219					$(this).prop("defaultSelected", $(this).prop("selected"));
2220				});
2221			}
2222		});
2223		return this;
2224	};
2225
2226	$.fn.formReset = function (clearForm, resetValidation) {
2227		var $form = $(this);
2228		if ($form != null) {
2229			$.each($form, function () {
2230				if (clearForm != null && clearForm) {
2231					$(this).find("input[type='text']").val("");
2232					$(this).find("input[type='checkbox']").removeAttr("checked");
2233					$(this).find("input[type='radio']").removeAttr("checked");
2234					$(this).find("select option").removeAttr("selected");
2235				}
2236				this.reset();
2237				$(this).formStyler(true).formStyler();
2238				if (resetValidation == undefined || resetValidation) {
2239					$(this).resetValidation();
2240				}
2241			});
2242		}
2243		return this;
2244	};
2245
2246	$.fn.resetValidation = function () {
2247		var $form = $(this);
2248		//reset jQuery Validate's internals
2249		var validator = $form.validate();
2250		validator.resetForm();
2251		$form.hideValidationMessages();
2252		return this;
2253	};
2254
2255	$.fn.hideValidationMessages = function () {
2256		var $form = $(this);
2257		$form.find(".field-validation-error[data-valmsg-for]").hide();
2258		$form.find(".field-validation-error, .input-validation-error").removeClass("field-validation-error").removeClass("input-validation-error");
2259		return this;
2260	};
2261
2262	$.fn.hideValidationMessage = function () {
2263		var $field = $(this);
2264		var $form = $field.closest("form");
2265		var $message = $form.find(".field-validation-error[data-valmsg-for='" + $field.prop("name") + "']");
2266		$message.removeClass("field-validation-error").empty();
2267		return this;
2268	};
2269
2270	/* Get all form parameters */
2271	$.fn.serializeJSON = function (includeDisabled) {
2272		var json = {};
2273		var disabled = null;
2274		if (includeDisabled != null && includeDisabled) {
2275			disabled = $(this).find(":input:disabled").removeAttr("disabled");
2276		}
2277		jQuery.map($(this).serializeArray(), function (n, i) {
2278			if (!json.hasOwnProperty(n["name"]) || json[n["name"]] == "false") {//for checkbox which was built MVC
2279				json[n["name"]] = n["value"];
2280			}
2281		});
2282		if (includeDisabled != null && includeDisabled && disabled != null) {
2283			disabled.attr("disabled", "disabled");
2284		}
2285		return json;
2286	};
2287
2288	$.fn.getFormValidationSummary = function () {
2289		var $el = $(this).find(".validation-summary-errors ul");
2290		if ($el.length == 0) {
2291			$(this).prepend('<div class="validation-summary-errors"><ul></ul></div>');
2292			return $(this).getFormValidationSummary();
2293		}
2294		return $el;
2295	};
2296
2297	$.fn.fixValidationStyle = function () {
2298		$(this).each(function () {
2299			$(this).find("div.form-group").removeClass("error");
2300			$(this).find(".input-validation-error").each(function () {
2301				$(this).fixValidationElementStyle();
2302			});
2303		});
2304		return this;
2305	};
2306
2307	$.fn.fixValidationElementStyle = function () {
2308		if ($(this).attr("type") == "file") {
2309			$(this).closest("div.form-group").addClass("error");
2310		}
2311		return this;
2312	};
2313
2314	$.fn.showValidationMessage = function (form) {
2315		$(this).each(function (i, e) {
2316			var name = $(e).attr("name");
2317			$(e).addClass("input-validation-error").removeClass("valid");
2318			$(e).fixValidationElementStyle();
2319			if (form == null)
2320				form = $(e).closest("form");
2321			var $dataValmsgFor = $(form).find("[data-valmsg-for='" + name + "']");
2322			if ($dataValmsgFor == null || $dataValmsgFor.length == 0) {
2323				$dataValmsgFor = $("<span data-valmsg-for='" + name + "'></span>");
2324				$dataValmsgFor.insertAfter($(e));
2325			}
2326			$dataValmsgFor.addClass("field-validation-error").show();
2327		});
2328		return this;
2329	};
2330
2331	$.fn.isValiationSummaryErrors = function (data) {
2332		var form = this;
2333		if (data == null || data.Tag == null || data.Tag != "ValidationErrors")
2334			return false;
2335		var $list = $(form).getFormValidationSummary();
2336		//clear last validation messages
2337		$list.html("");
2338		$(form).find(".field-validation-error[data-valmsg-for]").hide();
2339		$(form).find(".field-validation-error, .input-validation-error").removeClass("field-validation-error").removeClass("input-validation-error");
2340		$(form).find("div.form-group").removeClass("error");
2341
2342		$.each(data.State, function (i, item) {
2343			var valmsg, lblTxt, errorList = "";
2344			if (item.Name) {
2345				var el = $(form).find("[name='" + item.Name + "']");
2346				$(el).showValidationMessage(form);
2347				valmsg = $(form).find("[data-valmsg-for='" + item.Name + "']");
2348				lblTxt = $(form).find("label[for='" + item.Name + "']").text();
2349				if (lblTxt) {
2350					lblTxt += ": ";
2351				}
2352			}
2353			if (valmsg != null && valmsg.length) {
2354				$(valmsg).text(item.Errors.shift());
2355				if (!item.Errors.length) {
2356					return;
2357				}
2358			}
2359			$.each(item.Errors, function (c, val) {
2360				errorList += "<li>";
2361				if (lblTxt != null && lblTxt != "")
2362					errorList += lblTxt;
2363				errorList += val + "</li>";
2364			});
2365			$list.append(errorList);
2366		});
2367		if ($list.find("li:first").length) {
2368			$list.closest("div").show();
2369		}
2370		return true;
2371	};
2372
2373	$.fn.initDatepickers = function () {
2374		$(this).find(".form-datePicker").each(function () {
2375			$(this).datepicker({
2376				dateFormat: GlobalSettings.ViewForm.DateFormat,
2377				changeYear: true,
2378				changeMonth: true,
2379				yearRange: "1990:+3",
2380				firstDay: GlobalSettings.ViewForm.FirstDay,
2381				maxDate: $(this).data('val-lukoildatenowmax-nowdate'),
2382				onSelect: function (dateText, inst) {
2383					$(inst.input).val(dateText).datepicker("hide");
2384					var frm = $(inst.input).closest("form");
2385					if (frm != null && frm.length > 0) {
2386						$(frm).validate().element("#" + inst.id);
2387					}
2388					$(inst.input).trigger("change");
2389				},
2390				onClose: function (selectedDate) {
2391					var dateTo = $(this).attr("date-to");
2392					if (dateTo != null && dateTo != '') {
2393						$("#" + dateTo).datepicker("option", "minDate", selectedDate);
2394					}
2395					var dateFrom = $(this).attr("date-from");
2396					if (dateFrom != null && dateFrom != '') {
2397						$("#" + dateFrom).datepicker("option", "maxDate", selectedDate);
2398					}
2399				}
2400			});
2401		});
2402		return this;
2403	};
2404
2405	$.fn.reloadLukoilCaptcha = function () {
2406		$(this).find(".captcha").find("[id$='_ReloadLink']").trigger("click");
2407	};
2408
2409	$.reloadLukoilCaptcha = function (captchaId) {
2410		$("form .captcha #" + captchaId + "_ReloadLink").trigger("click");
2411	};
2412
2413	$.fn.getCaptcha = function () {
2414		var $frm = $(this);
2415		var captchaID = $frm.find("input[name='Captcha_Client_CaptchaID']").val();
2416		var userInputID = $frm.find("input[name='Captcha_Client_UserInputID']").val();
2417		var instanceID = $frm.find("input[name='Captcha_Client_InstanceID']").val();
2418		var value = $frm.find("#" + userInputID).val();
2419
2420		return {
2421			value: value,
2422			captchaID: captchaID,
2423			userInputID: userInputID,
2424			instanceID: instanceID
2425		}
2426	};
2427
2428	$.fn.lukoilAjaxSubmitForm = function (beforeSubmitCallback, completeCallback, successCallback, hideFormAfterSubmit, onCloseCallBack ) {
2429		var $frm = $(this);
2430		if ($frm.attr("hideForm") == null) {
2431			$frm.attr("hideForm", hideFormAfterSubmit == null ? true : hideFormAfterSubmit);
2432		}
2433		$frm.on("submit",function () {
2434			if ($frm.valid()) {
2435				$frm.hideValidationMessages();
2436				$frm.find(".overlay").show();
2437				$frm.ajaxSubmit({
2438					beforeSubmit: function(arr, $form, options) {
2439						if (beforeSubmitCallback) {
2440							beforeSubmitCallback();
2441						}
2442					},
2443					success: function(responseText, statusText, xhr, form) {
2444						var responseJson = $.isPlainObject(responseText) ? responseText : $.parseJSON(responseText);
2445						if (!$frm.isValiationSummaryErrors(responseJson)) {
2446							if (responseJson != null) {
2447								var actionResult = responseJson.Result;
2448								if (window.location.pathname.indexOf('/consumers/support') != -1) {
2449									ym(42633489, 'reachGoal', 'mn_expert_forms_sent')
2450								} 
2451								switch (actionResult) {
2452									case Constants.AjaxResultCodes.Success:
2453										$.fancyboxMessage(responseJson.Value, function() { if (responseJson.OnCloseEvent != null) onCloseCallBack(responseJson.OnCloseEvent) });
2454										var hideForm = $frm.attr("hideForm");
2455										if (hideForm == null || hideForm == "true") {
2456											$frm.hide();
2457										} else {
2458											$frm.reloadLukoilCaptcha();
2459										}
2460										if (successCallback) {
2461											successCallback();
2462										}
2463										break;
2464									default:
2465										$.fancyboxMessage(responseJson.Value);
2466										$frm.reloadLukoilCaptcha();
2467										break;
2468								}
2469							}
2470						} else {
2471							$frm.reloadLukoilCaptcha();
2472							$.fancybox.reposition();
2473						}
2474					},
2475					error: function(jqXHR, textStatus, errorThrown) {
2476						$frm.reloadLukoilCaptcha();
2477						if (jqXHR != null && jqXHR.responseJSON != null && jqXHR.responseJSON.Result != null && jqXHR.responseJSON.Value != null) {
2478							if (jqXHR.responseJSON.WebEventCode != null && jqXHR.responseJSON.WebEventCode == GlobalSettings.WebEventCodes.RuntimeErrorPostTooLarge) {
2479								$.fancyboxMessage(GlobalSettings.ErrorMessages.RuntimeErrorPostTooLargeMessage);
2480							}
2481							else {
2482								$.fancyboxMessage(jqXHR.responseJSON.Value);
2483							}
2484						}
2485						else {
2486							$.fancyboxMessage(GlobalSettings.ErrorMessages.FormSubmitErrorMessage);
2487						}
2488					},
2489					complete: function() {
2490						if (completeCallback) {
2491							completeCallback();
2492						}
2493						$frm.find(".overlay").hide();
2494					}
2495				});
2496			} else {
2497				$frm.fixValidationStyle();
2498			}
2499			return false;
2500		});
2501	};
2502
2503	$.fn.lukMediaAlbum = function (options) {
2504		var gallery = function () {
2505			var $container = $(this);
2506			var $thumbs = $container.find('.photo-album-thumbs');
2507			var $thumb = $container.find('.photo-album-thumb');
2508			var $box = $container.find('.photo-album-box');
2509			var $boxElem = $('<div class="photo-album-box-elem">');
2510			var content = [];
2511			var data;
2512			var isDisable = false;
2513			var mediaContent = {
2514				image: {
2515					img: function (src, icon) {
2516						icon = icon || '';
2517						return '<img class="photo-album-elem-img" src="' + src + '"> ' + icon;
2518					}
2519				},
2520				video: {
2521					local: function (src) {
2522						return '<video class="photo-album-elem-video" controls autoplay><source src="' + src + '" type="video/mp4"></video>';
2523					},
2524					youtube: function (src) {
2525						return '<iframe class="photo-album-elem-video" src="' + src + '">';
2526					}
2527				},
2528				audio: {
2529					player: function (imgSrc, audioSrc) {
2530						return mediaContent.image.img(imgSrc) + '<div class="audio-player"><audio class="photo-album-elem-audio" controls autoplay><source src="' + audioSrc + '" type="audio/mpeg"></audio></div>';
2531					}
2532				},
2533				description: function (title, text) {
2534					title = title || '';
2535					text = text ? '<p>' + text + '</p>' : '';
2536					return title || text ? '<div class="infoblock-body"><div class="content-title">' + title + '</div><div class="content-collapse">
2536' + text + '</div></div>' : '';
2537				},
2538				file: {}
2539			};
2540
2541			$thumb
2542				.each(function (indexThumb) {
2543				var href = $(this).attr('href'),
2544					dataHref = $(this).data('href'),
2545					elem = {};
2546				$(this).attr('data-index-item', indexThumb);
2547				elem.isCursorPointer = true;
2548				if ($(this).hasClass('video-local')) {
2549					elem.image = mediaContent.image.img(href, options.video);
2550					elem.media = mediaContent.video.local(dataHref);
2551				} else if ($(this).hasClass('video-youtube')) {
2552					elem.image = mediaContent.image.img(href, options.video);
2553					elem.media = mediaContent.video.youtube(dataHref);
2554				} else if ($(this).hasClass('audio')) {
2555					elem.image = mediaContent.image.img(href, options.audio);
2556					elem.media = mediaContent.audio.player(href, dataHref);
2557				} else if ($(this).hasClass('file')) {
2558					elem.image = mediaContent.image.img(href, options.file);
2559					elem.media = dataHref;
2560					elem.isOpenNewWindow = true;
2561				} else {
2562					elem.isCursorPointer = false;
2563					elem.image = mediaContent.image.img(href);
2564				}
2565				elem.description = mediaContent.description($(this).data('title'), $(this).data('description'));
2566				content.push(elem);
2567			});
2568
2569			var index = $thumbs.data("preselected") || 0;
2570			data = content[index];
2571			$($thumb[index]).addClass('selected');
2572
2573			$box
2574				.prepend(
2575				$boxElem
2576					.clone()
2577					.addClass(function () { return data.isCursorPointer ? 'cursor-pointer' : ''; })
2578					.append(content[index].image, content[index].description)
2579				)
2580				.on('click', function () {
2581				if (isDisable) return;
2582				isDisable = true;
2583				if (data.isOpenNewWindow) {
2584					window.open(data.media);
2585				} else {
2586					$container.find('.photo-album-box-elem').html(data.media);
2587				}
2588			});
2589
2590			var fullStateItemCount = 5;
2591			$thumbs.lukOwlCarousel({
2592				lazyContent: true,
2593				nav: true,
2594				navRewind: false,
2595				dots: false,
2596				margin: 20,
2597				startPosition: index >= fullStateItemCount ? index : 0,
2598				responsive: {
2599					0: {
2600						items: 3
2601					},
2602					768: {
2603						items: fullStateItemCount
2604					}
2605				}
2606			});
2607
2608			var isAnimate = false;
2609			var $newBoxElem;
2610
2611			$thumbs.on('click', '.photo-album-thumb', function (event) {
2612				event.preventDefault();
2613				if (isAnimate && $(this).hasClass('selected')) return;
2614				isDisable = false;
2615				data = content[$(this).data('indexItem')];
2616				$thumb.removeClass('selected');
2617				$(this).addClass('selected');
2618				$newBoxElem = $boxElem
2619					.clone()
2620					.css({ 'position': 'absolute', 'z-index': 2 })
2621					.addClass(function() {
2622						return data.isCursorPointer ? 'cursor-pointer' : '';
2623					});
2624				$newBoxElem.append(data.image, data.description);
2625				$box.prepend($newBoxElem);
2626				$newBoxElem.hide(0, function () {
2627					isAnimate = true;
2628				});
2629				$newBoxElem.fadeIn(200, function () {
2630					$container.find('.photo-album-box-elem').eq(1).remove();
2631					$newBoxElem.attr('style', '');
2632					isAnimate = false;
2633				});
2634
2635			});
2636
2637		};
2638
2639		this.each(gallery);
2640
2641		return this;
2642	};
2643
2644	$.fn.getValFromMultiSelect = function () {
2645		var $selector = $(this);
2646
2647		if ($selector == null || $selector.length == 0) {
2648			return null;
2649		}
2650
2651		if ($selector.is(".dropdown-menu") && $selector.closest(".dropdown").is(".dropdown-multi-selection")) {
2652			return $selector.find("input:checked").map(function () { return { value: $(this).data("val"), type: $(this).data("tag-type") } }).get();
2653		}
2654
2655		throw "getValFromMultiSelect only for multiselects";
2656	}
2657
2658	$.fn.getFilterFromMultiSelect = function () {
2659		var $selector = $(this);
2660
2661		if ($selector == null || $selector.length == 0) {
2662			return null;
2663		}
2664
2665		if ($selector.is(".dropdown-menu") && $selector.closest(".dropdown").is(".dropdown-multi-selection")) {
2666			return $selector.find("input:checked").map(function () { return { value: $(this).data("filter"), type: $(this).data("tag-type") } }).get();
2667		}
2668
2669		throw "getFilterFromMultiSelect only for multiselects";
2670	}
2671
2672	$.fn.updateSelectStateByValueInAnother = function ($select, triggerValue) {
2673		var values = $select.getValFromMultiSelect();
2674
2675		if (triggerValue && (!values.length || _.indexOf(values, function(item) {
2676			return item.value == triggerValue;
2677		}) !== -1)) {
2678			$(this).closest(".dropdown").removeClass("disabled");
2679		} else {
2680			$(this).closest(".dropdown").addClass("disabled");
2681		}
2682	}
2683
2684	$.fn.lukOwlCarousel = function (opt) {
2685		if (opt == null) {
2686			opt = {};
2687		}
2688
2689		var arabic = $("body").hasClass("ar");
2690		opt.rtl = arabic != null && arabic;
2691
2692		$(this).addClass("owl-carousel");
2693		$(this).owlCarousel(opt);
2694		return this;
2695	}
2696
2697	$.fn.setMaxZindex = function (opt) {
2698		var def = { inc: 1, group: "*" };
2699		$.extend(def, opt);
2700		var zmax = 0;
2701		$(def.group).each(function () {
2702			var cur = parseInt($(this).css("z-index"));
2703			zmax = cur > zmax ? cur : zmax;
2704		});
2705		if (!this.jquery)
2706			return zmax;
2707
2708		return this.each(function () {
2709			zmax += def.inc;
2710			$(this).css("z-index", zmax);
2711		});
2712	};
2713
2714
2715	$.getTagsValFromMultiselects = function ($parent, ulSelectors) {
2716		var tagsValue = "";
2717		_.each(ulSelectors, function (selector) {
2718			_.each($parent.find(selector).getValFromMultiSelect(), function (selected) {
2719				tagsValue += "" + selected.value + "," + selected.type + ";";
2720			});
2721		});
2722
2723		return tagsValue == "" ? undefined : tagsValue;
2724	};
2725
2726	$.createDownloadPopover = function ($scope) {
2727		$.each($($scope).find('.show-popover-download'), function (_, popover) {
2728			var $popover = $(popover);
2729			if (!$popover.data("popover-set")) {
2730				$popover.popover({
2731					title: '',
2732					trigger: 'manual',
2733					content: function() {
2734						return $(this).html();
2735					},
2736					placement: 'bottom',
2737					container: 'body',
2738					html: true
2739				})
2740				.on('click', function() {
2741					if ($(this).hasClass('opened')) {
2742						$(this).removeClass('opened').popover('hide');
2743					} else {
2744						$('.show-popover-download.opened').popover('hide').removeClass('opened');
2745						$(this).addClass('opened').popover('show');
2746					}
2747					});
2748				$popover.data("popover-set", true);
2749			}
2750		});
2751		$($scope).on('click', function (even) {
2752			if ($(even.target).closest('.show-popover-download').length || $(even.target).closest('.popover').length) return;
2753			$('.show-popover-download.opened').popover('hide').removeClass('opened');
2754		});
2755	};
2756
2757	$.resetDatePickerValue = function($datepicker) {
2758		if ($datepicker) {
2759			$.datepicker._clearDate($datepicker);
2760
2761			$datepicker.datepicker("option", {
2762				minDate: null,
2763				maxDate: null
2764			});
2765		}
2766	}
2767})(jQuery);
2768
2769$(function () {
2770	/* Form styler
2771	==============================================================================*/
2772	//$("form.form").each(function () { $(this).formStyler(); });
2773	//$(".checkbox-custom, .radio-custom, .file-custom").styler();
2774	//$(".select-custom").styler({ onSelectClosed: function() {
2775	//	var frm = $(this).closest("form");
2776	//	if (frm != null) {
2777	//		var validator = $(frm).validate();
2778	//		if (validator != null) {
2779	//			$(this).find("select").valid();
2780	//		}
2781	//	}
2782	//}, selectPlaceholder: GlobalSettings.Resource.SelectPlaceholder });
2783
2784	$('.select-custom').initSelect2();
2785});
2786
2787/*
2788	Knockout custom bindings
2789*/
2790//Trim text
2791//Example using: <span data-bind="trimHtml: <TextField>, trimTextLength: 150"></span>
2792ko.bindingHandlers.trimHtml = {
2793	init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
2794		var resultHtml = ko.computed(function () {
2795			var untrimmedText = ko.utils.unwrapObservable(valueAccessor());
2796			var defaultMaxLength = 100;
2797			var minLength = 5;
2798			var maxLength = ko.utils.unwrapObservable(allBindingsAccessor().trimTextLength) || defaultMaxLength;
2799			if (maxLength < minLength)
2800				maxLength = minLength;
2801			var result = untrimmedText.length > maxLength ? untrimmedText.substring(0, maxLength) : untrimmedText;
2802			return result;
2803		});
2804		ko.applyBindingsToNode(element, {
2805			html: resultHtml
2806		}, viewModel);
2807
2808		return {
2809			controlsDescendantBindings: true
2810		};
2811	}
2812};
2813
2814// File icons
2815//Example using: <a data-bind="fileIcon: FileType"></a>
2816ko.bindingHandlers.fileIcon = {
2817	update: function (element, valueAccessor) {
2818		var classesByTypes = {
2819			2: "icon icon-s-picture_round",
2820			3: "icon icon-s-play_round",
2821			4: "icon icon-s-audio_round",
2822			Default: "icon icon-s-flipbook-pdf_round"
2823		};
2824
2825		for (var type in classesByTypes) {
2826			if (classesByTypes.hasOwnProperty(type)) {
2827				ko.utils.toggleDomNodeCssClass(element, classesByTypes[type], false);
2828			}
2829		}
2830
2831		var fileType = ko.utils.unwrapObservable(valueAccessor());
2832
2833		ko.utils.toggleDomNodeCssClass(element, fileType in classesByTypes ? classesByTypes[fileType] : classesByTypes.Default, true);
2834	}
2835};
2836
2837var fileBigIcon = function (element, valueAccessor, withPicture) {
2838	var classesByTypes = {
2839	    2: withPicture ? "icon-picture" : "",
2840		3: "icon-play",
2841		4: "icon-audio",
2842		Default: "icon-download"
2843	};
2844
2845	for (var type in classesByTypes) {
2846		if (classesByTypes.hasOwnProperty(type)) {
2847			ko.utils.toggleDomNodeCssClass(element, classesByTypes[type], false);
2848		}
2849	}
2850
2851	var fileType = ko.utils.unwrapObservable(valueAccessor());
2852
2853	ko.utils.toggleDomNodeCssClass(element, fileType in classesByTypes ? classesByTypes[fileType] : classesByTypes.Default, true);
2854}
2855
2856// File big icons
2857//Example using: <a data-bind="fileBigIcon: FileType"></a>
2858ko.bindingHandlers.fileBigIcon = {
2859	update: function (element, valueAccessor) {
2860	    fileBigIcon(element, valueAccessor, false);
2861	}
2862};
2863
2864// File big icons
2865//Example using: <a data-bind="fileBigIconWithPicture: FileType"></a>
2866ko.bindingHandlers.fileBigIconWithPicture = {
2867	update: function (element, valueAccessor) {
2868	    fileBigIcon(element, valueAccessor, true);
2869	}
2870};
2871
2872// Show file in modal window
2873// Example using: <a data-bind="showModal: FileType"></a>
2874ko.bindingHandlers.showModal = {
2875	update: function (element, valueAccessor) {
2876		var classesByTypes = {
2877			2: "modal-slide-show",
2878			3: "show-video-local",
2879			4: "show-audio-player",
2880			Default: ""
2881		};
2882
2883		for (var type in classesByTypes) {
2884			if (classesByTypes.hasOwnProperty(type)) {
2885				ko.utils.toggleDomNodeCssClass(element, classesByTypes[type], false);
2886			}
2887		}
2888
2889		var fileType = ko.utils.unwrapObservable(valueAccessor());
2890
2891		ko.utils.toggleDomNodeCssClass(element, fileType in classesByTypes ? classesByTypes[fileType] : classesByTypes.Default, true);
2892	}
2893};
2894
2895// Set 'target' attribute by file type
2896// Example using: <a data-bind="linkTarget: FileType"></a>
2897ko.bindingHandlers.linkTarget = {
2898	update: function (element, valueAccessor) {
2899		var fileType = ko.utils.unwrapObservable(valueAccessor());
2900		if (fileType == Constants.fileTypes.Document) {
2901			$(element).attr("target",  "_blank");
2902		}
2903	}
2904};
2905
2906function removeInternalHost(link) {
2907	if (!link) {
2908		return null;
2909	}
2910
2911	var result = link;
2912
2913	var linkStartsWithBaseUrl = result.indexOf(GlobalSettings.BaseUrl) == 0;
2914	if (linkStartsWithBaseUrl) {
2915		result = result.substring(GlobalSettings.BaseUrl.length);
2916	}
2917	var linkStartsWithSiteUrl = result.indexOf(GlobalSettings.SiteUrl) == 0;
2918	if (linkStartsWithSiteUrl) {
2919		result = result.substring(GlobalSettings.SiteUrl.length);
2920	}
2921
2922	var linkStartsWithHttpORSlash = result.indexOf("http") == 0 || result.indexOf("//") == 0;
2923
2924	return {
2925		result: result,
2926		linkStartsWithBaseUrl: linkStartsWithBaseUrl,
2927		linkStartsWithSiteUrl: linkStartsWithSiteUrl,
2928		linkStartsWithHttpORSlash: linkStartsWithHttpORSlash
2929	};
2930}
2931
2932function isExternalLink(link) {
2933	if (!link) {
2934		return false;
2935	}
2936
2937	var isExternal = true;
2938	var updated = removeInternalHost(link);
2939	if (!updated) {
2940		return false;
2941	}
2942	if (GlobalSettings.CurrentSitePath == "") {
2943		$.each(Constants.Languages, function () {
2944			if (updated.result.indexOf("/" + this) == 0) {
2945				isExternal = false;
2946				return;
2947			}
2948		});
2949	} else {
2950		isExternal = updated.result.indexOf("/" + GlobalSettings.CurrentSitePath) == -1;
2951	}
2952
2953	return isExternal;
2954};
2955
2956// Change class "icon-s-chevron-link" to "icon-s-share" and add target for other site links
2957// Example using: <a data-bind="InternalUrl: true/false"></a>
2958ko.bindingHandlers.InternalUrl = {
2959	update: function (element, valueAccessor) {
2960		if (ko.utils.unwrapObservable(valueAccessor())) {
2961			var href = $(element).attr("href");
2962
2963			if (!href) {
2964				return;
2965			}
2966
2967			if (isExternalLink(href)) {
2968				$(element).attr("target", "_blank");
2969				if ($(element).hasClass("icon-s-chevron-link")) {
2970					$(element).removeClass("icon-s-chevron-link").addClass("icon-s-share");
2971				}
2972
2973				var link = removeInternalHost(href);
2974				if (!link) {
2975					return;
2976				}
2977				if (link.linkStartsWithHttpORSlash) {
2978					$(element).attr("href", link.result);
2979				}
2980				else if (!link.linkStartsWithBaseUrl && !link.linkStartsWithSiteUrl) {
2981					$(element).attr("href", GlobalSettings.SiteUrl + link.result);
2982				}
2983			}
2984		}
2985	}
2986};
2987
2988// Show or hide with slide animation
2989// Example using: <a data-bind="slideVisible: linkIsVisible"></a>
2990ko.bindingHandlers.slideVisible = {
2991	init: function (element, valueAccessor) {
2992		var value = valueAccessor();
2993		$(element).toggle(ko.unwrap(value));
2994	},
2995	update: function (element, valueAccessor) {
2996		var value = valueAccessor();
2997		ko.unwrap(value) ? $(element).slideDown() : $(element).slideUp();
2998	}
2999};
3000
3001// Alternative to built-in "checked" binding for radiobuttons. Works with radiobuttons styled by JQuery Form Styler plugin 
3002// Example using: <a data-bind="checkedRadioStyler: isChecked"></a>
3003ko.bindingHandlers.checkedRadioStyler = {
3004	init: function (element, valueAccessor) {
3005		ko.bindingHandlers.checkedRadioStyler.update(element, valueAccessor);
3006		$(element).on("change", function () {
3007			var value = valueAccessor();
3008			var $this = $(this);
3009			if (ko.isObservable(value) && $this.is(":checked")) {
3010				value($this.val());
3011			}
3012		});
3013	},
3014	update: function (element, valueAccessor) {
3015		var $element = $(element);
3016		var value = valueAccessor();
3017		$element.prop("checked", ko.utils.unwrapObservable(value) == $element.val()).trigger("refresh");
3018	}
3019};
3020
3021// Alternative to built-in "checked" binding for checkboxes. Works with checkboxes styled by JQuery Form Styler plugin 
3022// Example using: <a data-bind="checkedCheckboxStyler: isChecked"></a>
3023ko.bindingHandlers.checkedCheckboxStyler = {
3024	init: function (element, valueAccessor, allBindings) {
3025		ko.bindingHandlers.checkedCheckboxStyler.update(element, valueAccessor, allBindings);
3026		$(element).on("change",function () {
3027			var checked = $(this).is(":checked");
3028			var value = valueAccessor();
3029			if (ko.isObservable(value)) {
3030				// if array
3031				if (!(value.destroyAll === undefined)) {
3032					if (checked) {
3033						value.push(allBindings().checkedValue);
3034					} else {
3035						value.remove(allBindings().checkedValue);
3036					}
3037				} else {
3038					value(checked);
3039				}
3040			}
3041		});
3042	},
3043	update: function (element, valueAccessor, allBindings) {
3044		var value = ko.utils.unwrapObservable(valueAccessor());
3045
3046		$(element).prop("checked", value.constructor === Array ? _.indexOf(value, allBindings().checkedValue) !== -1 : value).trigger("refresh");;
3047	}
3048};
3049
3050//DisplayContact
3051//Example using: 
3052//			<span data-bind="DisplayContact: <TextField>, iconClassPostfix: 'email', hrefPrefix: 'mailto'"></span>
3053//			<span data-bind="DisplayContact: <TextField>, iconClassPostfix: 'phone', hrefPrefix: 'tel'"></span>
3054//			<span data-bind="DisplayContact: <TextField>, iconClassPostfix: 'fax'"></span>
3055ko.bindingHandlers.displayContact = {
3056	init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
3057		var resultHtml = ko.computed(function () {
3058			var contactString = ko.utils.unwrapObservable(valueAccessor());
3059			var iconClassPostfix = ko.utils.unwrapObservable(allBindingsAccessor().iconClassPostfix);
3060			var hrefPrefix = ko.utils.unwrapObservable(allBindingsAccessor().hrefPrefix) || '';
3061
3062			var stringResult = "";
3063			if (!isNullOrWhiteSpace(contactString)) {
3064				contactString = contactString.replace(new RegExp('\r', 'g'), '').replace(new RegExp('\n', 'g'), ';');
3065
3066				stringResult += "<div class=\"list-contacts\"><i class=\"icon icon-s-" + iconClassPostfix + "\"></i><p>";
3067				var contactLines = contactString.split(';');
3068				for (var i = 0; i < contactLines.length; i++)
3069				{
3070					var contacts = contactLines[i].split(',');
3071					for (var j = 0; j < contacts.length; j++)
3072					{
3073						var contact = contacts[j] != null ? contacts[j].trim() : null;
3074						var comma = j + 1 != contacts.length ? ", " : "";
3075						var title = "";
3076						var href = "";
3077						if (hrefPrefix == "mailto" || hrefPrefix == "link") {
3078							var index = contact.indexOf(" ");
3079							index = index > 0 ? index : contact.length;
3080							title = contact.substring(index);
3081							href = contact.substring(0, index);
3082						}
3083						else {
3084							title = contact.match(new RegExp('([а-яА-ЯёЁa-zA-Z]).*', 'g'));
3085							title = title != null && title.length > 0 ? title[0] : "";
3086							href = isNullOrWhiteSpace(title) ? contact : contact.replace(title, '');
3087						}
3088						title = title != null ? title.trim() : "";
3089						href = href != null ? href.trim() : "";
3090						if (isNullOrWhiteSpace(hrefPrefix)) {
3091							stringResult += href + " " + title + comma;
3092						}
3093						else {
3094							if (hrefPrefix == "link") {
3095								var linkHref = href.startsWith("http://") || href.startsWith("https://") ? href : "http://" + href;
3096								stringResult += "<a href=\"" + linkHref + "\" target=\"_blank\">" + href + "</a>" + (isNullOrWhiteSpace(title) ? "" : "&nbsp;" + title) + comma;
3097							} else {
3098								stringResult += "<a href=\"" + hrefPrefix + ":" + href + "\">" + href + "</a>" + (isNullOrWhiteSpace(title) ? "" : "&nbsp;" + title) + comma;
3099							}
3100						}
3101					}
3102					if (i != contactLines.Length) {
3103						stringResult += "</p><p>";
3104					}
3105				}
3106				stringResult += "</p></div>";
3107			}
3108			return stringResult;
3109		});
3110		ko.applyBindingsToNode(element, {
3111			html: resultHtml
3112		}, viewModel);
3113		return {
3114			controlsDescendantBindings: true
3115		};
3116	}
3117};
3118
3119//Format Number
3120//Example using: <span data-bind="formatNumber: <NumberField>, thousandsSep: ' ', decimals: 2, decPoint: ','"></span>
3121ko.bindingHandlers.formatNumber = {
3122	init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
3123		var resultText = ko.computed(function () {
3124			var value = ko.utils.unwrapObservable(valueAccessor());
3125			var alolowNull = ko.utils.unwrapObservable(allBindingsAccessor().alolowNull) || false;
3126			if (alolowNull && value == null)
3127				return "";
3128			value = Number(value);
3129			var thousandsSep = ko.utils.unwrapObservable(allBindingsAccessor().thousandsSep) || " ";
3130			var decimals = ko.utils.unwrapObservable(allBindingsAccessor().decimals) || -1;
3131			var decPoint = ko.utils.unwrapObservable(allBindingsAccessor().decPoint) || ",";
3132			var result = Highcharts.numberFormat(value, decimals, decPoint, thousandsSep);
3133			return result;
3134		});
3135		ko.applyBindingsToNode(element, {
3136			text: resultText
3137		}, viewModel);
3138
3139		return {
3140			controlsDescendantBindings: true
3141		};
3142	}
3143};
3144
3145ko.bindingHandlers.ko_autocomplete = {
3146	init: function (element, params) {
3147		$(element).autocomplete(params());
3148	},
3149	update: function (element, params) {
3150		$(element).autocomplete("option", "source", params().source);
3151	}
3152};
3153
3154var fileFieldsIds = [];
3155var fileLists = [];
3156
3157function ViewUploadFile(e, id) {
3158	var index = 0;
3159	if (fileFieldsIds.indexOf(id) === -1) {
3160		fileFieldsIds.push(id);
3161		fileLists.push(e.target.files);
3162	}
3163	else {
3164		var currentFiles = Array.from(fileLists[fileFieldsIds.indexOf(id)]).map(e => e.name);
3165		var dt = new DataTransfer();
3166		Array.from(fileLists[fileFieldsIds.indexOf(id)]).forEach((fileInfo) => {
3167				dt.items.add(fileInfo);
3168		});
3169		Array.from(e.target.files).forEach((fileInfo) => {
3170			if (currentFiles.indexOf(fileInfo.name) === -1) {
3171				dt.items.add(fileInfo);
3172				currentFiles = Array.from(fileLists[fileFieldsIds.indexOf(id)]).map(e => e.name);
3173			}
3174		});
3175		fileLists[fileFieldsIds.indexOf(id)] = dt.files;
3176		document.getElementById(`${e.target.id}`).files = dt.files;
3177	}
3178	$(`#${id}`).empty();
3179	Array.from(fileLists[fileFieldsIds.indexOf(id)]).forEach((fileInfo) => {
3180		$(`#${id}`).append(`<p class='jq-file__fileListItem'>
3181								${fileInfo.name}
3182								<span  parentId='${e.target.id}' index='${index}' onclick='RemoveFile(event)' class="jq-file__fileListRemoveItem"></span>
3183							</p>`);
3184		index++;
3185	});
3186}
3187
3188function RemoveFile(e) {
3189	var index = 0;
3190	var dt = new DataTransfer();
3191	Array.from(document.getElementById(`${e.target.attributes['parentid'].value}`).files).forEach((fileInfo) => {
3192		if (index != e.target.attributes['index'].value)
3193			dt.items.add(fileInfo);
3194		index++;
3195	});
3196	fileLists[fileFieldsIds.indexOf(`fileList_${e.target.attributes['parentid'].value}`)] = dt.files;
3197	document.getElementById(`${e.target.attributes['parentid'].value}`).files = dt.files;
3198	var element = document.getElementById(`${e.target.attributes['parentid'].value}`);
3199	var evt = document.createEvent("HTMLEvents");
3200	evt.initEvent("change", true, true);
3201	element.dispatchEvent(evt);
3202};
3203LukoilApp.module("Menu", function (Menu, LukoilApp, Backbone, Marionette, $, _) {
3204
3205	Menu.on("start", function (options) {
3206		Menu.run();
3207	});
3208
3209	Menu.run = function () {
3210		/* NavBar - Show submenu
3211		 ==============================================================================*/
3212		var isTouchDevice = (function() {
3213			var result = 'ontouchstart' in window		// works on most browsers 
3214						|| navigator.maxTouchPoints;	// works on IE10/11 and Surface
3215			return result;
3216		})();
3217
3218		if (window.innerWidth < 992 /*|| isTouchDevice*/) $('body').addClass('mobile-menu');
3219
3220		var isDesctopVersion = !$('body').hasClass('mobile-menu');
3221		var $submenuTitle = $('.submenu-title');
3222		var $navbarToggle = $('.navbar-toggle');
3223		var $navbarCollapse = $('#navbar-collapse');
3224		var $navbarSubmenu = $('#navbar-submenu');
3225		var $submenuList = $('.submenu-list');
3226		var $navberNavLi = $('.navbar-nav').find('li');
3227		var $navbarSubmenuContainer = $('.navbar-submenu-container');
3228		var isBlockSubmenu = true;
3229		var timerForClosedMenu;
3230		var timerBlockSubmenu;
3231		var timerOpenSubmenu;
3232
3233		function updateSizeMobileMenu() {
3234			var heightSubmenu = $(window).height() - $('#header').height();
3235			$navbarCollapse.height(heightSubmenu);
3236			$submenuTitle.width(heightSubmenu);
3237			$('.submenu-col').height('auto');
3238			$('.subsidiary .navbar-submenu-container').css('left', 'auto');
3239		}
3240
3241		function updateMenu() {
3242			var isWindowMobile = window.innerWidth < 992 /*|| isTouchDevice*/;
3243			var isMobileMenuVersion = $('body').hasClass('mobile-menu');
3244			if (!window.matchMedia('(max-width: 767px)').matches) {
3245			    $('html').removeClass('opened-submenu');
3246			}
3247			else {
3248			    if ($navbarCollapse.hasClass('opened')) {
3249			        $('html').addClass('opened-submenu');
3250			    }
3251			}
3252			if (isWindowMobile) {
3253				if (!isMobileMenuVersion) {
3254					$('body').addClass('mobile-menu');
3255					$('.subsidiary .dropdown-submenu').off('mouseenter mouseleave');
3256					$navberNavLi.off('mouseenter mouseleave');
3257					$navbarSubmenuContainer.off('mouseenter mouseleave');
3258					$('.navbar-nav.navbar-right').off('mouseenter mouseleave');
3259					handlersMobileMenu();
3260				}
3261				updateSizeMobileMenu();
3262			} else {			    
3263				if (isMobileMenuVersion) {
3264					$submenuTitle.off('click');
3265					$navbarToggle.off('click');
3266					$('.submenu-item__title .more-info').off('click');
3267					$('.navbar-nav .more-info').off('click');
3268					$('body').removeClass('mobile-menu');
3269					$('body').swipe("destroy");
3270					$navbarCollapse.height(0);
3271					handlersDesctopMenu();
3272				}
3273			}
3274		}
3275
3276		/*---Desctop version---*/
3277		function openDropdownSubmenu() {
3278			clearTimeout(timerForClosedMenu);
3279			$navberNavLi.removeClass('active');
3280			$submenuList.removeClass('opened');
3281			$navbarSubmenu.removeClass('open');
3282			var idSubmenu = $(this).attr('id');
3283			var $submenu = $('[data-submenu-id="' + idSubmenu + '"]');
3284			if ($submenu != null && $submenu.length > 0) {
3285				$(this).addClass('active');
3286				var $submenuCols = $submenu.find('.submenu-col');
3287				if (idSubmenu === undefined) return;
3288				$navbarSubmenu.addClass('open');
3289				$submenu.addClass('opened');
3290				var maxHeight = 0;
3291				$submenuCols.each(function() {
3292					if ($(this).height() > maxHeight) maxHeight = $(this).height();
3293				});
3294				$submenuCols.height(maxHeight);
3295			}
3296		}
3297
3298		function mouseenterDropdownSubmenu() {
3299			if (isBlockSubmenu) {
3300				timerOpenSubmenu = setTimeout(openDropdownSubmenu.bind(this), 100);
3301			} else {
3302				openDropdownSubmenu.call(this);
3303			}
3304		}
3305
3306		function mouseleaveDropdownSubmenu() {
3307			timerForClosedMenu = setTimeout(mouseleaveNavbarCollapse, 100);
3308			clearTimeout(timerOpenSubmenu);
3309		}
3310
3311		function mouseenterNavbarCollapse() {
3312			clearTimeout(timerForClosedMenu);
3313			isBlockSubmenu = false;
3314		}
3315
3316		function mouseleaveNavbarCollapse() {
3317			clearTimeout(timerForClosedMenu);
3318			$navberNavLi.removeClass('active').filter('.select').addClass('active');
3319			$submenuList.removeClass('opened');
3320			$navbarSubmenu.removeClass('open');
3321		}
3322
3323		function handlersDesctopMenu() {
3324			$navberNavLi.on({ mouseenter: mouseenterDropdownSubmenu, mouseleave: mouseleaveDropdownSubmenu });
3325			$navbarSubmenuContainer.on({mouseenter: mouseenterNavbarCollapse, mouseleave: mouseleaveNavbarCollapse}); //$navbarSubmenu
3326			$('.subsidiary .dropdown-submenu').on({
3327				mouseenter: function () {
3328					$navbarSubmenuContainer.css('left', $(this).offset().left);
3329				}
3330			});
3331			$('.navbar-nav.navbar-right').on(
3332				{
3333					mouseenter: function () {
3334						timerBlockSubmenu = setTimeout(function () {
3335							isBlockSubmenu = false;
3336						}, 80);
3337					},
3338					mouseleave: function () {
3339						clearTimeout(timerBlockSubmenu);
3340						isBlockSubmenu = true;
3341					}
3342				}
3343			);
3344		}
3345		/*---END Desctop version---*/
3346
3347		/*---Modile version---*/
3348		function onHideSubmenu() {
3349			$(this).closest('.opened').removeClass('opened').find('.opened').removeClass('opened');
3350		}
3351
3352		function onToggleNavbarCollapse() {
3353		    if ($navbarCollapse.hasClass('opened')) {
3354		        $('html').removeClass('opened-submenu');
3355		    }
3356		    else {
3357		        if (window.matchMedia('(max-width: 767px)').matches) {
3358		            $('html').addClass('opened-submenu');
3359		        }
3360		    }
3361		    $navbarCollapse.toggleClass('opened');
3362		}
3363
3364		function onShowSubmenu() {
3365			$(this).closest('.submenu-item').find('.submenu-item__list').addClass('opened');
3366		}
3367
3368		function onShowSubmenuList() {
3369			var idSubmenu = $(this).parent().attr('id');
3370			$('[data-submenu-id="'+idSubmenu+'"]').addClass('opened');
3371		}
3372
3373		function handlersMobileMenu() {
3374			var isSwipeDisable = false;
3375			var swipeDistance = 180;
3376			var isMenuDisabled = false;
3377			var scrollTop = $(window).scrollTop();
3378			$('body').swipe({
3379				swipeStatus: function(event, phase, direction, distance) {
3380					isMenuDisabled = scrollTop !== $(window).scrollTop();
3381					scrollTop = $(window).scrollTop();
3382					if (distance < swipeDistance || isMenuDisabled) return;
3383					if ($(event.target).closest('.owl-carousel').length) return;
3384					if ($(event.target).closest('.tableOverflow').length) return;
3385					if ($(event.target).closest('#navbar-collapse').length) {
3386						if (phase === 'move' && direction === 'right' && !isSwipeDisable) {
3387							if ($(event.target).hasClass('navbar-nav') || $(event.target).closest('ul').hasClass('navbar-nav')) {
3388							    $navbarCollapse.removeClass('opened');
3389								$('html').removeClass('opened-submenu');
3390							} else {
3391								$(event.target).closest('.opened').removeClass('opened');
3392							}
3393							isSwipeDisable = true;
3394						}
3395					} else {
3396						if (phase === 'move' && direction === 'left') {
3397						    $navbarCollapse.addClass('opened');
3398						    if (window.matchMedia("(max-width: 767px)").matches) {
3399						        $('html').addClass('opened-submenu');
3400						    }
3401						}
3402
3403						if (phase === 'move' && direction === 'right') {
3404							$navbarCollapse.removeClass('opened');
3405							$('html').removeClass('opened-submenu');
3406						}
3407					}
3408				},
3409				swipeRight: function() {
3410					isSwipeDisable = false; //TODO: для скрытия меню второго уровня
3411				},
3412				excludedElements: '.no-swipe, .fancybox-overlay',
3413				preventDefaultEvents: false,
3414				triggerOnTouchEnd: false,
3415				threshold: swipeDistance,
3416				maxTimeThreshold: 800,
3417			});
3418			$submenuTitle.on('click', onHideSubmenu);
3419			$navbarToggle.on('click', onToggleNavbarCollapse);
3420			$('.submenu-item__title .more-info').on('click', onShowSubmenu);
3421			$('.navbar-nav .more-info').on('click', onShowSubmenuList);
3422		}
3423		/*---END Modile version---*/
3424
3425		if (isDesctopVersion) {
3426			handlersDesctopMenu();
3427		} else {
3428			handlersMobileMenu();
3429			updateSizeMobileMenu();
3430		}
3431
3432		$(window).on('resize', updateMenu);
3433
3434		/*--- сохранение utm меток ---*/
3435		(function() {
3436			var domainsToDecorate = [
3437  
3438					'auto.lukoil.ru/ru/zapravsiavigodoy',
3439					'auto.lukoil.ru/ru/zapravsiavigodoy/Cards',
3440					'auto.lukoil.ru/ru/zapravsiavigodoy/PersonalAccount',
3441					'auto.lukoil.ru/ru/Promotions',
3442					'auto.lukoil.ru/ru/Support',
3443					'auto.lukoil.ru/ru/LUKOILClub/MobileApp',
3444					'auto.lukoil.ru/ru/ProductsAndServices/Fuel',
3445					'auto.lukoil.ru/ru/ProductsAndServices/LukCafe',
3446					'auto.lukoil.ru/ru/ProductsAndServices/Giftcard',
3447					'auto.lukoil.ru/ru/ProductsAndServices/Lubricants',
3448					'auto.lukoil.ru/ru/ProductsAndServices/PetrolStations',
3449					'auto.lukoil.ru/ru/ForBusiness/FuelCard',
3450					'auto.lukoil.ru/ru/ForBusiness/PromotionsB2B',
3451					'auto.lukoil.ru/ru/ForBusiness/MobileAppB2B',
3452					'auto.lukoil.ru/ru/ForBusiness/services',
3453					'auto.lukoil.ru/ru/ForBusiness/UsefulInformation',
3454					'auto.lukoil.ru/ru/ForBusiness/Contacts',
3455					'auto.lukoil.ru/ru/Forpartners/Dealers',
3456					'auto.lukoil.ru/ru/Forpartners/MobileAppB2B_partners',
3457					'auto.lukoil.ru/ru/Forpartners/services',
3458					'auto.lukoil.ru/ru',
3459					'auto.lukoil.ru/ru/ForBusiness/DiscountsB2B',
3460					'auto.lukoil.ru/ru/ForBusiness/PersonalAccount',
3461					'auto.lukoil.ru/ru/ForBusiness/EDO',
3462					
3463					'franchise.lukoil.ru/ru',
3464					'customer.licard.ru/proposals/list',
3465					'customer.licard.ru'
3466				],
3467				queryParams = [
3468					'utm_medium',
3469					'utm_source',
3470					'utm_campaign',
3471					'utm_term',
3472					'utm_content'
3473				]
3474				   var links = document.querySelectorAll('a');
3475  
3476			  links.forEach(function(link) {
3477				  var href = link.getAttribute('href');
3478				  if (!href) return; 
3479				  if (domainsToDecorate.some(function(domain) { return href.includes(domain); })) {
3480					  link.setAttribute('href', decorateUrl(href));
3481				  }
3482			  });
3483  
3484			  function decorateUrl(urlToDecorate) {
3485				  urlToDecorate = (urlToDecorate.indexOf('?') === -1) ? urlToDecorate + '?' : urlToDecorate + '&';
3486				  var collectedQueryParams = [];
3487  
3488				  queryParams.forEach(function(queryParam) {
3489					  if (getQueryParam(queryParam)) {
3490						  collectedQueryParams.push(queryParam + '=' + getQueryParam(queryParam));
3491					  }
3492				  });
3493  
3494				  return urlToDecorate + collectedQueryParams.join('&');
3495			  }
3496  
3497			  function getQueryParam(name) {
3498				  if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(window.location.search))
3499					  return decodeURIComponent(name[1]);
3500			  }
3501		  })(); 
3502		  
3503		  
3504		  
3505		  window.addEventListener('load', function() {
3506		  (function() {
3507			var domainsToDecorate = [
3508					'lukoil.ru/auto/Russia/ru/Promotions/points/',
3509					'lukoil.ru/licard/ru/News/News'
3510					
3511				],
3512				queryParams = [
3513					'utm_medium',
3514					'utm_source',
3515					'utm_campaign',
3516					'utm_term',
3517					'utm_content'
3518				]
3519				   var links = document.querySelectorAll('a');
3520  
3521			  links.forEach(function(link) {
3522				  var href = link.getAttribute('href');
3523				  if (!href) return; 
3524				  if (domainsToDecorate.some(function(domain) { return href.includes(domain); })) {
3525					  link.setAttribute('href', decorateUrl(href));
3526				  }
3527			  });
3528  
3529			  function decorateUrl(urlToDecorate) {
3530				  urlToDecorate = (urlToDecorate.indexOf('?') === -1) ? urlToDecorate + '?' : urlToDecorate + '&';
3531				  var collectedQueryParams = [];
3532  
3533				  queryParams.forEach(function(queryParam) {
3534					  if (getQueryParam(queryParam)) {
3535						  collectedQueryParams.push(queryParam + '=' + getQueryParam(queryParam));
3536					  }
3537				  });
3538  
3539				  return urlToDecorate + collectedQueryParams.join('&');
3540			  }
3541  
3542			  function getQueryParam(name) {
3543				  if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(window.location.search))
3544					  return decodeURIComponent(name[1]);
3545			  }
3546		  })(); 
3547		});
3548		/*--- конец сохранения utm меток ---*/
3549	};
3550});;
3551LukoilApp.module("UserLocation", function (UserLocation, LukoilApp, Backbone, Marionette, $, _) {
3552
3553    var requiredModules = {
3554        util: LukoilApp.module("Util"),
3555        YandexMapServices: LukoilApp.module("YandexMapServices")
3556    };
3557
3558    var options = { debug: true }, logger;
3559
3560    var settings = {
3561        selectors: {
3562        },
3563        geolocationInfoCookiesConfig: {
3564            expires: 100,
3565            path: '/'
3566        },
3567        cookiesConfig: {
3568            path: '/'
3569        },
3570        cookiesConfigForever: {
3571            path: '/',
3572            expires: 365 * 100
3573        },
3574        countryCodeCookieKey: "LukCountryCode",
3575        geoObjectIdCookieKey: "LukGeoObjectId",
3576        locationCookieKey: "LukLocation",
3577        geolocationInfoCookieKey: "LukGeolocation",
3578        locationSelectCookieKey: "LukLocationSelect",
3579        verifyCountryCodeUrl: "/api/userLocation/VerifyCountryCodeOrGetDefault",
3580        currentSiteLocationUrl: "/api/userLocation/GetCurrentSiteLocation",
3581        countrySelector: ".global-nav .dropdown_country"
3582    };
3583
3584    var cookieStorage = {};
3585
3586    // ----------- CookieStorage -----------
3587    var CookieStorage = function (config) {
3588        this.config = config || {};
3589    }
3590    CookieStorage.prototype.save = function (keyInStorage, model) {
3591        $.lukoilSaveCookie(keyInStorage, JSON.stringify(model), this.config);
3592    }
3593    CookieStorage.prototype.getValue = function (keyInStorage) {
3594        return $.lukoilGetCookie(keyInStorage);
3595    }
3596
3597    UserLocation.getCountryCode = function (languageCode /* optional */) {
3598        var df = $.Deferred();
3599
3600        var cookieCountryCode = $.lukoilGetCookie(settings.countryCodeCookieKey);
3601        if (cookieCountryCode) {
3602            df.resolve(cookieCountryCode);
3603        } else {
3604            var geolocationInfo = $.lukoilGetCookie(settings.locationCookieKey);
3605            if (geolocationInfo == null || geolocationInfo == '') {
3606                UserLocation.SelectCurrentLocation(languageCode, df);
3607            }
3608            else {
3609                cookieStorage = new CookieStorage(settings.geolocationInfoCookiesConfig);
3610                geolocationInfoReady(cookieStorage, df, JSON.parse(geolocationInfo));
3611            }
3612        }
3613
3614        return df;
3615    };
3616
3617    UserLocation.saveCountryCode = function (countryCode, saveChoicee) {
3618        $.lukoilSaveCookie(settings.countryCodeCookieKey, countryCode, saveChoicee ? settings.cookiesConfigForever : settings.cookiesConfig);
3619    };
3620
3621    UserLocation.saveGeoObjectId = function (id, saveChoicee) {
3622        $.lukoilSaveCookie(settings.geoObjectIdCookieKey, id, saveChoicee ? settings.cookiesConfigForever : settings.cookiesConfig);
3623    };
3624    UserLocation.getGeoObjectId = function () {
3625        return $.lukoilGetCookie(settings.geoObjectIdCookieKey);
3626    };
3627
3628    UserLocation.areCookiesEnabled = function () {
3629        var cookieEnabled = (navigator.cookieEnabled) ? true : false;
3630        if (typeof navigator.cookieEnabled == "undefined" && !cookieEnabled) {
3631            document.cookie = "testcookie";
3632            cookieEnabled = (document.cookie.indexOf("testcookie") != -1) ? true : false;
3633        }
3634        return (cookieEnabled);
3635    };
3636
3637    var getRegionById = function (countries, id) {
3638        var found;
3639        _.each(countries, function (c) {
3640            _.each(c.Regions, function (r) {
3641                if (r.Id === id) {
3642                    found = r;
3643                }
3644            });
3645        });
3646        return found;
3647    };
3648
3649    function inIframe() {
3650        try {
3651            return window.self !== window.top;
3652        } catch (e) {
3653            return true;
3654        }
3655    }
3656
3657    var geolocationInfoReady = function (cookieStorage, df, geolocationInfo) {
3658        var select = cookieStorage.getValue(settings.locationSelectCookieKey);
3659        var printMode = cookieStorage.getValue("printMode");
3660        if (!select && printMode !== "True" && !inIframe()) {
3661            cookieStorage.save(settings.locationSelectCookieKey, true);
3662            var choosenId = UserLocation.getGeoObjectId();
3663            if (!choosenId) {
3664                if (UserLocation.areCookiesEnabled()) {
3665                    if (!localStorage.getItem('isReloaded')) {
3666                        localStorage.setItem('isReloaded', true);
3667                        window.location.reload(true);
3668                    }
3669                    else {
3670
3671                    }
3672                }
3673                else if (df) {
3674                    df.resolve(geolocationInfo.countryCode);
3675                }
3676            }
3677        }
3678        else if (df) {
3679            df.resolve(geolocationInfo.countryCode);
3680        }
3681    }
3682
3683    var verifyCountryCodeReady = function (df, geolocationInfo) {
3684        $.ajax(settings.verifyCountryCodeUrl,
3685            {
3686                async: true,
3687                cache: false,
3688                data: {
3689                    countryCode: geolocationInfo.countryCode
3690                },
3691                dataType: "json",
3692                method: "POST",
3693                traditional: true
3694            }).done(function (answer) {
3695                if (answer && answer.countryCode) {
3696                    UserLocation.saveCountryCode(answer.countryCode);
3697                    UserLocation.saveGeoObjectId(answer.geoObjectId);
3698                    if (UserLocation.areCookiesEnabled()) {
3699                        window.location.reload(true);
3700                    } else if (df) {
3701                        df.resolve(answer.countryCode);
3702                    }
3703                }
3704            }).fail(function (jqXHR, textStatus, errorThrown) {
3705                if (df != null) {
3706                    df.reject(errorThrown);
3707                }
3708            });
3709    }
3710
3711    var saveCurrentSiteLocation = function (answer) {
3712        var geolocationInfo = answer.geolocationInfo;
3713        cookieStorage.save(settings.locationCookieKey, geolocationInfo);
3714        cookieStorage.save(settings.geolocationInfoCookieKey, geolocationInfo);
3715        if (answer.countryCode) {
3716            UserLocation.saveCountryCode(answer.countryCode);
3717        }
3718        if (answer.geoObjectId) {
3719            UserLocation.saveGeoObjectId(answer.geoObjectId);
3720        }
3721        return geolocationInfo;
3722    }
3723
3724    var tryGetCurrentSiteLocation = function (success, fallback) {
3725        $.ajax(settings.currentSiteLocationUrl,
3726            {
3727                async: true,
3728                cache: false,
3729                data: {
3730                    currentUrl: window.location.href
3731                },
3732                dataType: "json",
3733                method: "GET"
3734            }).done(function (answer) {
3735                if (answer && answer.useYandex === false && answer.geolocationInfo) {
3736                    success(answer);
3737                } else {
3738                    fallback();
3739                }
3740            }).fail(function () {
3741                fallback();
3742            });
3743    }
3744
3745    const GetYandexCacheOptions = {
3746        enableHighAccuracy: true,
3747        timeout: 5000,
3748        maximumAge: 0,
3749    };
3750
3751    function GetYandexCacheError(err) {
3752        console.warn(`ERROR(${err.code}): ${err.message}`);
3753    }    
3754
3755    UserLocation.SelectCurrentLocation = function (languageCode, df) {
3756        var $countryContainer = $(settings.countrySelector);
3757        cookieStorage = new CookieStorage(settings.geolocationInfoCookiesConfig);
3758        var geolocationInfo = cookieStorage.getValue(settings.locationCookieKey);
3759        if ($countryContainer.length) {
3760            if (geolocationInfo == null || geolocationInfo == '') {
3761                tryGetCurrentSiteLocation(function(answer) {
3762                    var hadGeoObjectId = UserLocation.getGeoObjectId();
3763                    var geolocationInfo = saveCurrentSiteLocation(answer);
3764                    if (!hadGeoObjectId && UserLocation.areCookiesEnabled()) {
3765                        window.location.reload(true);
3766                    } else {
3767                        geolocationInfoReady(cookieStorage, df, geolocationInfo);
3768                    }
3769                }, function() {
3770                    navigator.geolocation.getCurrentPosition(function (pos) {
3771                    const crd = pos.coords;
3772                    $.ajax("/api/cartography/GetYandexCache", {
3773                        async: true,
3774                        cache: true,
3775                        ifModified: true,
3776                        data: { latitudes: crd.latitude, longitude: crd.longitude },
3777                        dataType: "json",
3778                        method: "GET"
3779                    }).then(function (result) {
3780                        if (result == '') {
3781                            requiredModules.YandexMapServices.ensureMapApiIsReady(languageCode).then(function () {
3782                                requiredModules.YandexMapServices.getCurrentLocation('auto').then(function (location) {
3783                                    var geolocationInfo = location.geolocationInfo;
3784                                    $.ajax("/api/cartography/AddYandexCache", {
3785                                        async: true,
3786                                        cache: true,
3787                                        ifModified: true,
3788                                        data: { latitudes: crd.latitude, longitude: crd.longitude, value: JSON.stringify(geolocationInfo), brows: window.navigator.userAgent },
3789                                        dataType: "json",
3790                                        method: "Post"
3791                                    }).then(function (result) {
3792                                        console.log("Данные взяты из яндекса, записаны в БД и в куки")
3793                                        cookieStorage.save(settings.locationCookieKey, geolocationInfo);
3794                                        geolocationInfoReady(cookieStorage, df, geolocationInfo);
3795                                    });
3796                                });
3797                            });
3798                        }
3799                        else {
3800                            console.log("Данные взяты из БД и записаны в куки")
3801                            cookieStorage.save(settings.locationCookieKey, JSON.parse(result));
3802                            geolocationInfoReady(cookieStorage, df, JSON.parse(result));
3803                        }
3804                    });
3805                }, function (err) {
3806                    requiredModules.YandexMapServices.ensureMapApiIsReady(languageCode).then(function () {
3807                        requiredModules.YandexMapServices.getCurrentLocation('auto').then(function (location) {
3808                            var geolocationInfo = location.geolocationInfo;
3809                            cookieStorage.save(settings.locationCookieKey, geolocationInfo);
3810                            geolocationInfoReady(cookieStorage, df, geolocationInfo);
3811                        });
3812                    });
3813                }, GetYandexCacheOptions);               
3814                });
3815            } else {
3816                console.log("Данные взяты из куки")
3817                geolocationInfoReady(cookieStorage, df, geolocationInfo);
3818            }
3819        } else {
3820            if (languageCode != null && languageCode != '') {
3821                if (geolocationInfo == null || geolocationInfo == '') {
3822                    tryGetCurrentSiteLocation(function(answer) {
3823                        var geolocationInfo = saveCurrentSiteLocation(answer);
3824                        verifyCountryCodeReady(df, geolocationInfo);
3825                    }, function() {
3826                        navigator.geolocation.getCurrentPosition(function (pos) {
3827                        const crd = pos.coords;
3828                        $.ajax("/api/cartography/GetYandexCache", {
3829                            async: true,
3830                            cache: true,
3831                            ifModified: true,
3832                            data: { latitudes: crd.latitude, longitude: crd.longitude },
3833                            dataType: "json",
3834                            method: "GET"
3835                        }).then(function (result) {
3836                            if (result == '') {
3837                                requiredModules.YandexMapServices.ensureMapApiIsReady(languageCode).then(requiredModules.YandexMapServices.getCurrentLocation).then(function (result) {
3838                                    if (result && result.geolocationInfo && result.geolocationInfo.countryCode) {
3839                                        $.ajax("/api/cartography/AddYandexCache", {
3840                                            async: true,
3841                                            cache: true,
3842                                            ifModified: true,
3843                                            data: { latitudes: crd.latitude, longitude: crd.longitude, value: JSON.stringify(result.geolocationInfo), brows: window.navigator.userAgent },
3844                                            dataType: "json",
3845                                            method: "Post"
3846                                        }).then(function (result) {
3847                                            verifyCountryCodeReady(df, result.geolocationInfo);
3848                                        });
3849                                    }
3850                                });
3851                            }
3852                            else {
3853                                verifyCountryCodeReady(df, JSON.parse(result));
3854                            }
3855                        });
3856                    }, function (err) {
3857                        requiredModules.YandexMapServices.ensureMapApiIsReady(languageCode).then(requiredModules.YandexMapServices.getCurrentLocation).then(function (result) {
3858                            if (result && result.geolocationInfo && result.geolocationInfo.countryCode) {
3859                                verifyCountryCodeReady(df, result.geolocationInfo);
3860                            }
3861                        });
3862                    }, GetYandexCacheOptions);  
3863                    });
3864                } else {
3865                    verifyCountryCodeReady(df, geolocationInfo);
3866                }
3867            }
3868        }
3869    };
3870
3871    var UserCountriesViewModel = function (parameters) {
3872        this.hideRegions = false;
3873        this.countries = parameters.countries;
3874
3875        this.choosenObject = ko.observable(parameters.selectedCountry);
3876        this.currentFilter = ko.observable();
3877        this.saveChoise = ko.observable(false);
3878
3879        var $countryContainer = $(settings.countrySelector);
3880
3881        var choosenId = UserLocation.getGeoObjectId();
3882        if (choosenId) {
3883            var obj = _.filter(this.getCountries(), function (c) {
3884                return c.Id === choosenId;
3885            });
3886            if (obj && obj.length) {
3887                this.choosenObject(obj[0]);
3888            } else {
3889                obj = getRegionById(this.getCountries(), choosenId);
3890                if (obj) {
3891                    this.choosenObject(obj);
3892                }
3893            }
3894        }
3895
3896        var self = this;
3897        this.changeSelection = function (newGeoObject) {
3898            self.choosenObject(newGeoObject);
3899            var code;
3900            if (newGeoObject.CountryCode) {
3901                code = newGeoObject.CountryCode;
3902            } else {
3903                var country = _.filter(self.getCountries(), function (c) {
3904                    return _.any(c.Regions, function (r) {
3905                        return r.Id === newGeoObject.Id;
3906                    });
3907                })[0];
3908                code = country.CountryCode;
3909            }
3910
3911            $.ajax(settings.verifyCountryCodeUrl, {
3912                async: true,
3913                cache: false,
3914                data: {
3915                    countryCode: code
3916                },
3917                dataType: "json",
3918                method: "POST",
3919                traditional: true
3920            }).done(function (answer) {
3921                if (answer && answer.countryCode && answer.geoObjectId) {
3922                    UserLocation.saveCountryCode(answer.countryCode, self.saveChoise());
3923                    if (answer.countryCode === code) {
3924                        UserLocation.saveGeoObjectId(newGeoObject.Id, self.saveChoise());
3925                    } else {
3926                        UserLocation.saveGeoObjectId(answer.geoObjectId, self.saveChoise());
3927                    }
3928                    if (UserLocation.areCookiesEnabled()) {
3929                        window.location.reload(true);
3930                    }
3931                }
3932            });
3933        }
3934
3935        this.filteredObjects = ko.pureComputed(function () {
3936            if (!self.currentFilter()) {
3937                return self.getCountries();
3938            } else {
3939                var filter = self.currentFilter().toLowerCase();
3940                var fc = ko.utils.arrayFilter(self.getCountries(), function (c) {
3941                    return c.Title.toLowerCase().indexOf(filter) >= 0 || _.any(c.Regions, function (r) {
3942                        return r.Title.toLowerCase().indexOf(filter) >= 0;
3943                    });
3944                });
3945
3946                var newCountries = _.map(fc, function (c) {
3947                    return { Title: c.Title, Regions: [], Id: c.Id, CountryCode: c.CountryCode };
3948                });
3949
3950                _.each(fc, function (c) {
3951                    var regs = ko.utils.arrayFilter(c.Regions, function (r) {
3952                        return r.Title.toLowerCase().indexOf(filter) >= 0;
3953                    });
3954                    var nc = _.filter(newCountries, function (c1) {
3955                        return c1.Title === c.Title;
3956                    })[0];
3957                    nc.Regions = _.map(regs, function (r) {
3958                        return { Title: r.Title, Id: r.Id };
3959                    });
3960                });
3961
3962                return newCountries;
3963            }
3964        });
3965
3966        if ($countryContainer.length) {
3967            ko.applyBindings(this, $countryContainer[0]);
3968        }
3969    }
3970
3971    UserCountriesViewModel.prototype.getCountries = function () {
3972        if (this.hideRegions) {
3973            return _.map(this.countries, function (c) {
3974                return { Title: c.Title, Regions: [], Id: c.Id, CountryCode: c.CountryCode };
3975            });
3976        } else {
3977            return this.countries;
3978        }
3979    }
3980
3981    UserLocation.run = function (parameters) {
3982        var vm = new UserCountriesViewModel(parameters);
3983    };
3984
3985    UserLocation.on("start", function (options) {
3986        UserLocation.SelectCurrentLocation();
3987    });
3988
3989});
3990;
3991// @hash v3-0D67B262E4671821C418A11340E829C282040C52
3992// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden.
3993// Version: 2.1.1-dev-20151124-1300 (build 563ed55)
3994// Generated at:
3995///////////////////////////////////////////////////////////////////////////////
3996
3997
3998LukoilApp.module("Util", function (Util, LukoilApp, Backbone, Marionette, $, _, global) {
3999	"use strict";
4000
4001	Util.createObject = typeof Object.create === 'function' ? function (object) {
4002		return Object.create(object);
4003	} : (function () {
4004		function Temp() {};
4005		return function (O) {
4006			if (typeof O !== 'object') {
4007				throw new TypeError('Object prototype may only be an Object or null');
4008			}
4009			Temp.prototype = O;
4010			return new Temp();
4011		};
4012	})();
4013
4014	Util.getResolvedPromise = (function () {
4015		var resolvedPromise = $.when();
4016		return function () {
4017			return resolvedPromise;
4018		};
4019	})();
4020
4021	Util.createResolvedPromise = function () {
4022		var deferred = $.Deferred();
4023		deferred.resolve.apply(deferred, arguments);
4024		return deferred.promise();
4025	};
4026
4027	Util.createRejectedPromise = function () {
4028		var deferred = $.Deferred();
4029		deferred.reject.apply(deferred, arguments);
4030		return deferred.promise();
4031	};
4032
4033	Util.createSinglePropertyObject = function (propertyName, propertyValue) {
4034		var obj = {};
4035		obj[propertyName] = propertyValue;
4036		return obj;
4037	};
4038
4039	Util.trimString = typeof String.prototype.trim === "function" ? function (s) {
4040		return s.trim();
4041	} : (function () {
4042		var special = String.fromCharCode(0xFEFF, 0xA0);
4043		var regexp = new RegExp("^[\\s" + special + "]+|[\\s" + special + "]+$", "g");
4044		return function (s) {
4045			return s.replace(regexp, "");
4046		};
4047	})();
4048
4049	Util.noop = function () {};
4050
4051	Util.oneRequestAtATimeServicePrototype = {
4052		startRequest: function startRequest(requestPromise) {
4053			var self = this;
4054			var lastRequest = self.lastRequest;
4055			var request = $.Deferred();
4056			if (lastRequest) {
4057				self.lastRequest = null;
4058				lastRequest.reject();
4059			}
4060			self.lastRequest = request;
4061			requestPromise.then(function () /* any arguments */{
4062				self.lastRequest = null;
4063				request.resolve.apply(request, arguments);
4064			}, function () {
4065				self.lastRequest = null;
4066				request.reject();
4067			});
4068			return request;
4069		}
4070	};
4071
4072	Util.logError = function (message) {
4073		if (global.console) {
4074			global.console.error(message);
4075		}
4076	};
4077
4078	function Throttler(minPauseBetweenExecutionsInMilliseconds) {
4079		this.minPauseBetweenExecutionsInMilliseconds = minPauseBetweenExecutionsInMilliseconds;
4080		this.executeNextPromise = Util.getResolvedPromise();
4081	};
4082	Throttler.prototype.throttle = function (callback) {
4083		var context = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1];
4084
4085		var self = this;
4086		var last = self.executeNextPromise;
4087		var callbackDeferred = $.Deferred();
4088		var executeNextDeferred = $.Deferred();
4089		self.executeNextPromise = executeNextDeferred.promise();
4090		last.always(function () {
4091			callback.call(context).always(function () {
4092				Util.createWaitPromise(self.minPauseBetweenExecutionsInMilliseconds).then(function () {
4093					executeNextDeferred.resolve();
4094				});
4095			}).then(function () /* any arguments */{
4096				callbackDeferred.resolve.apply(callbackDeferred, arguments);
4097			}, function () /* any arguments */{
4098				callbackDeferred.reject.apply(callbackDeferred, arguments);
4099			});
4100		});
4101		return callbackDeferred.promise();
4102	};
4103	(function (t) {
4104		Util.Throttler = t;
4105	})(Throttler);
4106
4107	function GeographySpan(minLat, maxLat, leftBoundLng, lngSpan) {
4108		this.minLatitude = minLat;
4109		this.maxLatitude = maxLat;
4110		this.leftBoundLongitude = leftBoundLng;
4111		this.longitudinalSpan = lngSpan;
4112	}
4113	GeographySpan.prototype.contains = function (point) {
4114		if (this.minLatitude < point.latitude && point.latitude < this.maxLatitude) {
4115			var d = point.longitude - this.leftBoundLongitude;
4116			if (d < 0) {
4117				d += 360;
4118			}
4119			return d < this.longitudinalSpan;
4120		} else {
4121			return false;
4122		}
4123	};
4124	(function (t) {
4125		Util.GeographySpan = t;
4126	})(GeographySpan);
4127
4128	Util.normalizeLongitude = function (longitude) {
4129		return Util.mod(longitude + 180, 360) - 180;
4130	};
4131
4132	Util.formatCurrency = function (amount) {
4133		var groupSeparator = " "; // that is, &thinsp;
4134
4135		function format(num, max) {
4136			return (max + num).toString().substring(1);
4137		};
4138
4139		var s = "";
4140		var a = amount;
4141		for (; a >= 1000;) {
4142			s = groupSeparator + format(a % 1000, 1000) + s;
4143			a = Math.floor(a / 1000);
4144		}
4145		return a + s;
4146	};
4147
4148	Util.formatCurrencyWithCents = function (amount) {
4149		var decimalPlaces = 2;
4150		var absAmount = Math.abs(amount);
4151		var intPart = Math.floor(absAmount);
4152		var fracPart = absAmount - intPart;
4153		var fracPartString = fracPart.toFixed(decimalPlaces);
4154		return (amount < 0 ? "-" : "") + Util.formatCurrency(intPart) + fracPartString.substring(fracPartString.length - decimalPlaces - 1);
4155	};
4156
4157	Util.rejectNull = function (value) {
4158		if (value == null) {
4159			throw new TypeError("Value unexpectedly is null or undefined.");
4160		}
4161		return value;
4162	};
4163
4164	Util.isPromisePending = function (p) {
4165		return p.state() === "pending";
4166	};
4167	Util.isPromiseResolved = function (p) {
4168		return p.state() === "resolved";
4169	};
4170	Util.isPromiseRejected = function (p) {
4171		return p.state() === "rejected";
4172	};
4173
4174	Util.createArray = function (value, size) {
4175		var a = new Array(size);
4176		var i;
4177		for (i = 0; i < size; ++i) {
4178			a[i] = value;
4179		}
4180		return a;
4181	};
4182
4183	Util.mod = function (a, b) {
4184		return a - Math.floor(a / b) * b;
4185	};
4186
4187	Util.createWaitPromise = function (waitInMilliseconds) {
4188		var deferred = $.Deferred();
4189		global.setTimeout(function () {
4190			deferred.resolve();
4191		}, waitInMilliseconds);
4192		return deferred.promise();
4193	};
4194
4195	Util.stripType = function (a) {
4196		return a;
4197	};
4198
4199	function CancellationToken() {
4200		this.canceled = false;
4201	}
4202	CancellationToken.prototype.isCanceled = function () {
4203		return this.canceled;
4204	};
4205	CancellationToken.prototype.cancel = function () {
4206		this.canceled = true;
4207	};
4208
4209	Util.CancellationToken = Util.stripType(CancellationToken);
4210
4211	function getNonThrowingWrapper(f) {
4212		return function () /* any arguments*/{
4213			try {
4214				return f.apply(undefined, arguments);
4215			} catch (e) {
4216				if (global.console && typeof global.console.error === "function") {
4217					global.console.error(e.message);
4218					global.console.error(e.stack);
4219				}
4220			}
4221		};
4222	}
4223
4224	function JQueryPromiseWrapper(jQueryPromise) {
4225		this.jQueryPromise = jQueryPromise;
4226	}
4227	JQueryPromiseWrapper.prototype.then = function (doneFilter, failFilter, progressFilter) {
4228		return this.jQueryPromise.then(doneFilter && getNonThrowingWrapper(doneFilter) || null, failFilter && getNonThrowingWrapper(failFilter) || null, progressFilter && getNonThrowingWrapper(progressFilter) || null);
4229	};
4230	JQueryPromiseWrapper.prototype.done = function () {
4231		this.jQueryPromise.done(_.map(_.flatten(arguments), getNonThrowingWrapper));
4232		return this;
4233	};
4234	JQueryPromiseWrapper.prototype.fail = function () {
4235		this.jQueryPromise.fail(_.map(_.flatten(arguments), getNonThrowingWrapper));
4236		return this;
4237	};
4238	JQueryPromiseWrapper.prototype.always = function () {
4239		this.jQueryPromise.always(_.map(_.flatten(arguments), getNonThrowingWrapper));
4240		return this;
4241	};
4242	JQueryPromiseWrapper.prototype.state = function () {
4243		return this.jQueryPromise.state();
4244	};
4245	JQueryPromiseWrapper.prototype.promise = function () {
4246		return this.jQueryPromise;
4247	};
4248	Util.JQueryPromiseWrapper = Util.stripType(JQueryPromiseWrapper);
4249
4250	Util.getUniqueNumber = (function () {
4251		var id = 0;
4252		return function () {
4253			return ++id;
4254		};
4255	})();
4256
4257	Util.tryParseStringToArray = function (stringifiedArray) {
4258		try {
4259			if (stringifiedArray) {
4260				return JSON.parse(stringifiedArray) || [];
4261			}
4262			return [];
4263		} catch (e) {
4264			global.console && global.console.log(e);
4265			return [];
4266		}
4267	};
4268
4269	var Logger = function Logger(options) {
4270		this.useConsole = _.isUndefined(options.useConsole) ? true : options.useConsole;this.moduleName = options.moduleName || '';
4271	};
4272	Logger.prototype.log = function (data) {
4273		if (this.useConsole && console && console.log) {
4274			console.log('[' + this.moduleName + '] ' + data);
4275		}
4276	};
4277	Util.createLogger = function (options) {
4278		return new Logger(options);
4279	};
4280}, this);
4281/* any arguments */ /* any arguments */ /* multiple arguments */ /* multiple arguments */ /* multiple arguments */;
4282// @hash v3-B38E21DF2B7D9E8B322D081F977B351A5D7EE87D
4283// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden.
4284// Version: 2.1.1-dev-20151124-1300 (build 563ed55)
4285// Generated at:
4286///////////////////////////////////////////////////////////////////////////////
4287
4288
4289LukoilApp.module("MapUtil", function (MapUtil, LukoilApp, Backbone, Marionette, $, _, global) {
4290	"use strict";
4291
4292	var requiredModules = {
4293		util: LukoilApp.module("Util"),
4294		yandexMapServices: LukoilApp.module("YandexMapServices")
4295	};
4296
4297	var consts = {
4298		geolocationServiceTimeoutInMilliseconds: 10000,
4299		geolocationServiceMaxCacheAgeInMilliseconds: 10 * 60 * 1000
4300	};
4301
4302	var stabilizedMapProviderModule = (function (utilModule, $) {
4303		function StabilizedMapProvider(map, mapStabilizationWaitInMilliseconds, mapDestabilizationCallback, mapStabilizationCallback) {
4304			var self = this;
4305			self.map = map;
4306			self.enabled = true;
4307			self.mapStabilizationCallback = mapStabilizationCallback;
4308			self.lastDeferred = $.Deferred();
4309			self.lastDeferred.resolve();
4310			self.lastCancelable = $.Deferred();
4311			self.listener = map.listenToBoundsChange(function () {
4312				if (self.enabled) {
4313					(function () {
4314						if (utilModule.isPromiseResolved(self.lastDeferred)) {
4315							self.lastDeferred = $.Deferred();
4316						}
4317						mapDestabilizationCallback();
4318						var deferred = self.lastDeferred;
4319						var lastCancelable = self.startRequest(map.getIdlePromise().then(function () {
4320							return utilModule.createWaitPromise(mapStabilizationWaitInMilliseconds);
4321						}));
4322						self.lastCancelable = lastCancelable;
4323						lastCancelable.then(function () {
4324							deferred.resolve();
4325							self.mapStabilizationCallback();
4326						}, function (canceled) {
4327							if (canceled) {
4328								deferred.reject();
4329							}
4330						});
4331					})();
4332				}
4333			});
4334		}
4335		StabilizedMapProvider.prototype = utilModule.createObject(utilModule.oneRequestAtATimeServicePrototype);
4336		StabilizedMapProvider.prototype.constructor = StabilizedMapProvider;
4337		StabilizedMapProvider.prototype.scheduleStabilizationHandling = function () {
4338			if (this.enabled && utilModule.isPromiseResolved(this.lastDeferred.promise())) {
4339				this.mapStabilizationCallback();
4340			}
4341		};
4342		StabilizedMapProvider.prototype.destroy = function () {
4343			this.enabled = false;
4344			this.map.stopListeningToBoundsChange(this.listener);
4345			this.lastCancelable.reject(true);
4346		};
4347
4348		return {
4349			StabilizedMapProvider: StabilizedMapProvider
4350		};
4351	})(requiredModules.util, $);
4352
4353	var userLocationModule = (function (PromiseWrapperClass, createResolvedPromise, yandexMapServices, consts) {
4354		function UserLocationProvider() {
4355			this.userLocationOverride = null;
4356			this.gasStationLocationOverrride = null;
4357			this.promise = null;
4358		}
4359		UserLocationProvider.prototype.geolocate = function (languageCode) {
4360			var _this = this;
4361
4362			if (!this.promise) {
4363				var timeoutExpired;
4364
4365				(function () {
4366					var deferred = $.Deferred();
4367					if (global.navigator.geolocation) {
4368						(function () {
4369							timeoutExpired = false;
4370
4371							var timeoutHandlerId = global.setTimeout(function () {
4372								timeoutExpired = true;
4373								deferred.reject();
4374							}, consts.geolocationServiceTimeoutInMilliseconds);
4375
4376							global.navigator.geolocation.getCurrentPosition(function (position) {
4377								global.clearTimeout(timeoutHandlerId);
4378								if (!timeoutExpired) {
4379									if (position && position.coords && global.isFinite(position.coords.latitude) && global.isFinite(position.coords.longitude)) {
4380										deferred.resolve({ location: { lat: position.coords.latitude, lng: position.coords.longitude } });
4381									} else {
4382										deferred.reject();
4383									}
4384								}
4385							}, function (positionError) {
4386								global.clearTimeout(timeoutHandlerId);
4387								if (!timeoutExpired) {
4388									deferred.reject();
4389								}
4390							}, {
4391								maximumAge: consts.geolocationServiceMaxCacheAgeInMilliseconds,
4392								timeout: Math.floor(consts.geolocationServiceTimeoutInMilliseconds / 2)
4393							});
4394						})();
4395					} else {
4396						deferred.reject();
4397					}
4398					_this.promise = deferred.then(null, function () {
4399						return yandexMapServices.ensureMapApiIsReady(languageCode).then(yandexMapServices.getCurrentLocation);
4400					});
4401				})();
4402			}
4403			return this.promise;
4404		};
4405		UserLocationProvider.prototype.setUserLocation = function (location) {
4406			this.userLocationOverride = location;
4407		};
4408		UserLocationProvider.prototype.setGasStationLocation = function (location) {
4409			this.gasStationLocationOverrride = location;
4410		};
4411		UserLocationProvider.prototype.getCurrentLocation = function (languageCode) {
4412			return new PromiseWrapperClass(this.gasStationLocationOverrride ? createResolvedPromise({ location: { lat: this.gasStationLocationOverrride.latitude, lng: this.gasStationLocationOverrride.longitude } }) : this.userLocationOverride ? createResolvedPromise({ location: { lat: this.userLocationOverride.latitude, lng: this.userLocationOverride.longitude } }) : this.geolocate(languageCode));
4413		};
4414		return {
4415			UserLocationProvider: UserLocationProvider
4416		};
4417	})(requiredModules.util.JQueryPromiseWrapper, requiredModules.util.createResolvedPromise, requiredModules.yandexMapServices, consts);
4418
4419	var mapSearchControlModule = (function (noop, createRejectedPromise) {
4420
4421		function MapSearchControl(addressSearchInputInitializer, addressResolver, mapPositioningCancellationTokenGenerator) {
4422			this.addressSearchInputInitializer = addressSearchInputInitializer;
4423			this.addressResolver = addressResolver;
4424			this.mapPositioningCancellationTokenGenerator = mapPositioningCancellationTokenGenerator;
4425			this.mapPositioningCallback = noop;
4426			this.mapReady = $.Deferred();
4427			this.uiReady = $.Deferred();
4428			this.$input = null;
4429			this.$button = null;
4430		}
4431		MapSearchControl.prototype.setMap = function (map) {
4432			this.mapReady.resolve(map);
4433		};
4434		MapSearchControl.prototype.setMapPositioningCallback = function (callback) {
4435			this.mapPositioningCallback = callback;
4436		};
4437		MapSearchControl.prototype.setEnabledState = function (enabled) {
4438			var self = this;
4439			self.uiReady.then(function () {
4440				self.$input.prop("readonly", !enabled);
4441				self.$input.prop("disabled", !enabled);
4442				self.$button.prop("disabled", !enabled);
4443			});
4444		};
4445		MapSearchControl.prototype.initializeUI = function (input, button) {
4446			var self = this;
4447			self.$input = $(input);
4448			self.$button = button && $(button);
4449			self.addressSearchInputInitializer(self.$input[0], function (bounds) {
4450				self.handleResolvedResult(bounds, self.mapPositioningCancellationTokenGenerator());
4451			}, function (address) {
4452				self.setAddress(address, self.mapPositioningCancellationTokenGenerator());
4453			});
4454
4455			if (self.$button) {
4456				self.$button.on("click", function () {
4457					self.setAddress(self.$input.val(), self.mapPositioningCancellationTokenGenerator());
4458				});
4459			}
4460
4461			self.uiReady.resolve();
4462		};
4463		MapSearchControl.prototype.setAddress = function (address, mapPositioningCancellationToken) {
4464			var self = this;
4465			address = address || "";
4466			return self.uiReady.then(function () {
4467				self.$input.val(address);
4468				if (address) {
4469					return self.addressResolver(address).then(function (bounds) {
4470						self.handleResolvedResult(bounds, mapPositioningCancellationToken);
4471					});
4472				} else {
4473					return createRejectedPromise();
4474				}
4475			});
4476		};
4477		MapSearchControl.prototype.handleResolvedResult = function (bounds, mapPositioningCancellationToken) {
4478			var self = this;
4479			self.mapReady.then(function (map) {
4480				if (!mapPositioningCancellationToken.isCanceled()) {
4481					map.fitBounds(bounds.minLatitude, bounds.maxLatitude, bounds.leftLongitude, bounds.rightLongitude).then(function () {
4482						if (!mapPositioningCancellationToken.isCanceled()) {
4483							self.mapPositioningCallback();
4484						}
4485					});
4486				}
4487			});
4488		};
4489
4490		return {
4491			MapSearchControl: MapSearchControl
4492		};
4493	})(requiredModules.util.noop, requiredModules.util.createRejectedPromise);
4494
4495	MapUtil.StabilizedMapProvider = requiredModules.util.stripType(stabilizedMapProviderModule.StabilizedMapProvider);
4496	MapUtil.userLocationProvider = new userLocationModule.UserLocationProvider();
4497	MapUtil.MapSearchControl = requiredModules.util.stripType(mapSearchControlModule.MapSearchControl);
4498}, this);;
4499// @hash v3-600BBE1351D51132A414A5DF53CA763D9B31BA52
4500// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden.
4501// Version: 2.1.1-dev-20151124-1300 (build 563ed55)
4502// Generated at:
4503///////////////////////////////////////////////////////////////////////////////
4504
4505
4506LukoilApp.module("CartographyObjects", function (CartographyObjects, LukoilApp, Backbone, Marionette, $, _, global) {
4507	"use strict";
4508
4509	var requiredModules = {
4510		util: LukoilApp.module("Util")
4511	};
4512
4513	var consts = {
4514		formIds: {
4515			gasStation: "gasStation",
4516			oilSeller: "oilSeller",
4517			salePoint: "salePoint",
4518			seaport: "seaport",
4519			airport: "airport",
4520			tankFarm: "tankFarm",
4521			legalEntities: "legalEntities",
4522			route: "route",
4523			seaportOil: "seaportOil"
4524		}
4525	};
4526	var legalEntitiesTemporaryIconUrl = "/Content/img/92-euro.png";
4527	var legalEntitiesVirtualCardIconUrl = "/Content/icons/{0}/card-virtual.png";
4528	var legalEntitiesPlasticCardIconUrl = "/Content/icons/{0}/card-plastic.png";
4529	var legalEntitiesGoldIconUrl = "/Content/icons/{0}/gold.png";
4530	var legalEntitiesPlatinumIconUrl = "/Content/icons/{0}/platinum.png";
4531	var legalEntitiesCategoryAIconUrl = "/Content/icons/{0}/categoryA.png";
4532	var legalEntitiesCategoryBIconUrl = "/Content/icons/{0}/categoryB.png";
4533	var legalEntitiesDefaultPinIconUrl = "/content/img/icon-point-gas.png";
4534	var legalEntitiesSpecialPinIconUrl = "/content/img/icon-point-legal.png";
4535
4536	function GasStationEnumerableAttributeItem(serverSearchResultEnumerableAttributeItem) {
4537		this.Name = serverSearchResultEnumerableAttributeItem.Name; // Non-null string.
4538		this.Text = serverSearchResultEnumerableAttributeItem.Text;
4539		this.FuelName = serverSearchResultEnumerableAttributeItem.FuelName;
4540		this.Title = serverSearchResultEnumerableAttributeItem.Title;
4541		this.IconFileBaseUrl = serverSearchResultEnumerableAttributeItem.IconFileBaseUrl; // Nullable string.
4542		this.Description = serverSearchResultEnumerableAttributeItem.Description;
4542 // Nullable string.
4543	};
4544
4545	function GasStationFuel(serverSearchResultGasStationFuel) {
4546		this.Id = serverSearchResultGasStationFuel.FuelId; // Non-null finite number.
4547		this.Name = serverSearchResultGasStationFuel.Name; // Non-null string.
4548		this.DisplayPrice = serverSearchResultGasStationFuel.DisplayPrice; // add
4549		this.Price = serverSearchResultGasStationFuel.Price; // add
4550		this.CurrencyDisplayName = serverSearchResultGasStationFuel.CurrencyDisplayName; // Nullable string, null only iff Price is null.
4551		this.IconFileBaseUrl = serverSearchResultGasStationFuel.IconFileBaseUrl; /// Nullable string.
4552	};
4553
4554	function BunkeringDeliveryMethod(serverSearchResultBunkeringDeliveryMethod) {
4555		this.IconCssClass = serverSearchResultBunkeringDeliveryMethod.IconCssClass;
4556		this.Amount = serverSearchResultBunkeringDeliveryMethod.Amount;
4557		this.AmountUnit = serverSearchResultBunkeringDeliveryMethod.AmountUnit;
4558		this.MinNotice = serverSearchResultBunkeringDeliveryMethod.MinNotice;
4559	};
4560
4561	function _SeaportOilInfo_(serverSeaportOilInfo) {
4562		this.ListName = serverSeaportOilInfo.ListName;
4563		this.ProductListCode = serverSeaportOilInfo.ProductListCode;
4564
4565		var deliveryMethods = _.map(serverSeaportOilInfo.DeliveryMethods, function (item) {
4566			return new BunkeringDeliveryMethod(item);
4567		});
4568
4569		this.DeliveryMethods = deliveryMethods;
4570		this.DeliveryMethodsWithAmounts = _.filter(deliveryMethods, function (dm) {
4571			return dm.Amount != null;
4572		});
4573		this.DeliveryMethodsWithNotices = _.filter(deliveryMethods, function (dm) {
4574			return dm.MinNotice != null;
4575		});
4576	};
4577
4578	function CartographyObject(serverSearchResultItem) {
4579		// Non-null finite number.
4580		this.Latitude = serverSearchResultItem.Latitude;
4581
4582		// Non-null finite number.
4583		this.Longitude = serverSearchResultItem.Longitude;
4584
4585		// Non-null string.
4586		this.Name = serverSearchResultItem.Name;
4587
4588		// Nullable string.
4589		this.Address = serverSearchResultItem.Address;
4590
4591		// Nullable string.
4592		this.Contacts = serverSearchResultItem.Contacts;
4593
4594		// Non-null string;
4595		this.IconUrl = serverSearchResultItem.IconUrl;
4596	};
4597
4598	function Company(serverSearchResultCompany) {
4599		this.Name = serverSearchResultCompany.Name;
4600		this.HomePageUrl = serverSearchResultCompany.HomePageUrl;
4601	}
4602
4603	var gasStationBase = CartographyObject;
4604	function _GasStation_(serverSearchResultItem) {
4605		var gasStation = serverSearchResultItem.GasStation;
4606		gasStationBase.call(this, gasStation);
4607
4608		// Non-null integer.
4609		this.Id = gasStation.GasStationId;
4610
4611		this.Company = gasStation.Company && new Company(gasStation.Company);
4612
4613		// Non-null string.
4614		this.DisplayName = gasStation.DisplayName;
4615
4616		this.DisplayNameOnly = gasStation.DisplayNameOnly;
4617		this.Phone = gasStation.Phone;
4618		this.Fax = gasStation.Fax;
4619		this.Email = gasStation.Email;
4620		this.PostCode = gasStation.PostCode;
4621		this.Street = gasStation.Street;
4622		this.City = gasStation.City;
4623		this.GasStationStatus = gasStation.GasStationStatus;
4624
4625		this.StationPhotoUrl = gasStation.StationPhotoUrl;
4626
4627		// Non-null array.
4628		this.Fuels = _.map(serverSearchResultItem.Fuels, function (item) {
4629			return new GasStationFuel(item);
4630		});
4631
4632		// Non-null array.
4633		this.Services = _.map(gasStation.Services, function (item) {
4634			return new GasStationEnumerableAttributeItem(item);
4635		});
4636
4637		// Non-null array.
4638		this.PaymentTypes = _.map(gasStation.PaymentTypes, function (item) {
4639			return new GasStationEnumerableAttributeItem(item);
4640		});
4641
4642		// Non-null array.
4643		this.Promotions = _.map(gasStation.Advertisements, function (item) {
4644			return new GasStationEnumerableAttributeItem(item);
4645		});
4646
4647		// Non-null array.
4648		this.Properties = _.map(gasStation.Properties, function (item) {
4649			return new GasStationEnumerableAttributeItem(item);
4650		});
4651
4652		this.BusinessHours = [gasStation.BusinessHoursForClient];
4653	};
4654	_GasStation_.prototype = requiredModules.util.createObject(gasStationBase.prototype);
4655	_GasStation_.prototype.constructor = _GasStation_;
4656	_GasStation_.prototype.type = consts.formIds.gasStation;
4657
4658	var oilSellerBase = CartographyObject;
4659	function OilSeller(serverSearchResultItem) {
4660		oilSellerBase.call(this, serverSearchResultItem);
4661		this.Id = serverSearchResultItem.OilSellerId;
4662		this.Name = serverSearchResultItem.Name;
4663		this.Email = serverSearchResultItem.Email;
4664		this.Phone = serverSearchResultItem.Phone;
4665		this.Fax = serverSearchResultItem.Fax;
4666		this.OilSellerType = serverSearchResultItem.OilSellerType && serverSearchResultItem.OilSellerType.Name || "";
4667		this.BusinessHours = [serverSearchResultItem.BusinessHoursForClient];
4668	}
4669	OilSeller.prototype = requiredModules.util.createObject(oilSellerBase.prototype);
4670	OilSeller.prototype.constructor = OilSeller;
4671	OilSeller.prototype.type = consts.formIds.oilSeller;
4672
4673	var salePointBase = CartographyObject;
4674	function SalePoint(serverSearchResultItem) {
4675		salePointBase.call(this, serverSearchResultItem);
4676		this.Id = serverSearchResultItem.SalePointId;
4677		this.Name = serverSearchResultItem.Name;
4678		this.Phone = serverSearchResultItem.Phone;
4679		this.PostCode = serverSearchResultItem.PostCode;
4680		this.SalePointType = serverSearchResultItem.SalePointType && serverSearchResultItem.SalePointType.Name || "";
4681		this.RoadServices = _.map(serverSearchResultItem.RoadServices, function (item) {
4682			return new GasStationEnumerableAttributeItem(item);
4683		});
4684		this.CardTypes = _.map(serverSearchResultItem.CardTypes, function (item) {
4685			return new GasStationEnumerableAttributeItem(item);
4686		});
4687		this.BusinessHours = serverSearchResultItem.BusinessHours;
4688		this.HomePageUrl = serverSearchResultItem.HomePageUrl;
4689	}
4690	SalePoint.prototype = requiredModules.util.createObject(salePointBase.prototype);
4691	SalePoint.prototype.constructor = SalePoint;
4692	SalePoint.prototype.type = consts.formIds.salePoint;
4693
4694	var seaportBase = CartographyObject;
4695	function Seaport(serverSearchResultItem) {
4696		seaportBase.call(this, serverSearchResultItem);
4697
4698		// Non-null integer.
4699		this.Id = serverSearchResultItem.SeaportId;
4700
4701		// Non-null boolean.
4702		this.IsBunkeringOil = serverSearchResultItem.IsBunkeringOil;
4703
4704		this.Description = serverSearchResultItem.Description;
4705
4706		// Non-null boolean.
4707		this.IsBunkeringFuel = serverSearchResultItem.IsBunkeringFuel;
4708
4709		this.FuelingCompany = serverSearchResultItem.FuelingCompany && new Company(serverSearchResultItem.FuelingCompany);
4710		this.OilingCompany = serverSearchResultItem.OilingCompany && new Company(serverSearchResultItem.OilingCompany);
4711
4712		this.OilInfo = new _SeaportOilInfo_(serverSearchResultItem.OilInfo);
4713	};
4714	Seaport.prototype = requiredModules.util.createObject(seaportBase.prototype);
4715	Seaport.prototype.constructor = Seaport;
4716	Seaport.prototype.type = consts.formIds.seaport;
4717
4718	var airportBase = CartographyObject;
4719	function Airport(serverSearchResultItem) {
4720		airportBase.call(this, serverSearchResultItem);
4721
4722		// Non-null integer.
4723		this.Id = serverSearchResultItem.AirportId;
4724
4725		this.Company = serverSearchResultItem.Company && new Company(serverSearchResultItem.Company);
4726	};
4727	Airport.prototype = requiredModules.util.createObject(airportBase.prototype);
4728	Airport.prototype.constructor = Airport;
4729	Airport.prototype.type = consts.formIds.airport;
4730
4731	var tankFarmBase = CartographyObject;
4732	function TankFarm(serverSearchResultItem) {
4733		tankFarmBase.call(this, serverSearchResultItem);
4734
4735		// Non-null integer.
4736		this.Id = serverSearchResultItem.TankFarmId;
4737
4738		this.Company = serverSearchResultItem.Company && new Company(serverSearchResultItem.Company);
4739
4740		this.BusinessHoursForClient = serverSearchResultItem.BusinessHoursForClient;
4741
4742		this.Phone = this.Company ? this.Company.Phone : null;
4743		this.Fax = this.Company ? this.Company.Fax : null;
4744		this.Email = this.Company ? this.Company.Email : null;
4745
4746		this.TypeFilling = serverSearchResultItem.TypeFilling || [];
4747		this.ShippingMethod = serverSearchResultItem.ShippingMethod || [];
4748		this.Fuel = serverSearchResultItem.Fuel || [];
4749	};
4750	TankFarm.prototype = requiredModules.util.createObject(tankFarmBase.prototype);
4751	TankFarm.prototype.constructor = TankFarm;
4752	TankFarm.prototype.type = consts.formIds.tankFarm;
4753
4754	var legalEntitiesBase = CartographyObject;
4755	function getLegalEntityPinIconUrl(serverSearchResultItem) {
4756		var brandName = String(serverSearchResultItem.BrandName || "").trim().toLowerCase();
4757		var category = String(serverSearchResultItem.Category || "").trim();
4758		return brandName === "teboil" && (category.toUpperCase() === "A" || category === "А") ? legalEntitiesSpecialPinIconUrl : legalEntitiesDefaultPinIconUrl;
4759	}
4760	function normalizeLegalEntityCategory(category) {
4761		var normalizedCategory = String(category || "").trim();
4762		if (normalizedCategory === "А") {
4763			return "A";
4764		}
4765		if (normalizedCategory === "В") {
4766			return "B";
4767		}
4768		return normalizedCategory.toUpperCase();
4769	}
4770	function getLegalEntityCategoryIconUrl(category) {
4771		var normalizedCategory = normalizeLegalEntityCategory(category);
4772		if (normalizedCategory === "A") {
4773			return legalEntitiesCategoryAIconUrl;
4774		}
4775		if (normalizedCategory === "B") {
4776			return legalEntitiesCategoryBIconUrl;
4777		}
4778		return legalEntitiesTemporaryIconUrl;
4779	}
4780	function getLegalEntityCategoryDisplayName(category) {
4781		var normalizedCategory = normalizeLegalEntityCategory(category);
4782		if (normalizedCategory === "A") {
4783			return "Категория А";
4784		}
4785		if (normalizedCategory === "B") {
4786			return "Категория Б";
4787		}
4788		return normalizedCategory ? "Категория " + normalizedCategory : "";
4789	}
4790	function getLegalEntityPopupTitle(serverSearchResultItem) {
4791		var brandName = String(serverSearchResultItem.BrandName || "").trim().toLowerCase();
4792		var category = String(serverSearchResultItem.Category || "").trim();
4793		return brandName === "teboil" && (category.toUpperCase() === "A" || category === "А") ? "Партнерская АЗС" : String(serverSearchResultItem.Number || "");
4794	}
4795	function LegalEntities(serverSearchResultItem) {
4796		legalEntitiesBase.call(this, serverSearchResultItem);
4797
4798		// Non-null integer.
4799		this.Number = serverSearchResultItem.Number;
4800		this.WorkMode = serverSearchResultItem.WorkMode;
4801		this.IconUrl = serverSearchResultItem.IconUrl || getLegalEntityPinIconUrl(serverSearchResultItem);
4802		this.Name = getLegalEntityPopupTitle(serverSearchResultItem);
4803		this.Services = _.map(serverSearchResultItem.Service || serverSearchResultItem.Services || [], function (item) {
4804			return new GasStationEnumerableAttributeItem(item);
4805		});
4806		this.Fuel = _.map(serverSearchResultItem.Fuel || [], function (item) {
4807			return new GasStationEnumerableAttributeItem(item);
4808		});
4809		this.Statuses = [];
4810		this.CardTypes = [];
4811
4812		if (serverSearchResultItem.IsGold) {
4813			this.Statuses.push(new GasStationEnumerableAttributeItem({
4814				Name: "Золотая АЗС",
4815				IconFileBaseUrl: legalEntitiesGoldIconUrl
4816			}));
4817		}
4818		if (serverSearchResultItem.IsPlatinum) {
4819			this.Statuses.push(new GasStationEnumerableAttributeItem({
4820				Name: "Платиновая АЗС",
4821				IconFileBaseUrl: legalEntitiesPlatinumIconUrl
4822			}));
4823		}
4824		if (serverSearchResultItem.Category) {
4825			this.Statuses.push(new GasStationEnumerableAttributeItem({
4826				Name: getLegalEntityCategoryDisplayName(serverSearchResultItem.Category),
4827				IconFileBaseUrl: getLegalEntityCategoryIconUrl(serverSearchResultItem.Category)
4828			}));
4829		}
4830		if (serverSearchResultItem.IsVirtual) {
4831			this.CardTypes.push(new GasStationEnumerableAttributeItem({
4832				Name: "Виртуальная топливная карта",
4833				IconFileBaseUrl: legalEntitiesVirtualCardIconUrl
4834			}));
4835		}
4836		if (serverSearchResultItem.IsPlastic) {
4837			this.CardTypes.push(new GasStationEnumerableAttributeItem({
4838				Name: "Пластиковая топливная карта",
4839				IconFileBaseUrl: legalEntitiesPlasticCardIconUrl
4840			}));
4841		}
4842	};
4843	LegalEntities.prototype = requiredModules.util.createObject(legalEntitiesBase.prototype);
4844	LegalEntities.prototype.constructor = LegalEntities;
4845	LegalEntities.prototype.type = consts.formIds.legalEntities;
4846
4847	var cartographyObjectTypeSelectors = [{ property: "GasStationId", ctor: _GasStation_ }, { property: "AirportId", ctor: Airport }, { property: "TankFarmId", ctor: TankFarm }, { property: "SeaportId", ctor: Seaport }, { property: "OilSellerId", ctor: OilSeller }, { property: "SalePointId", ctor: SalePoint }, { property: "Number", ctor: LegalEntities }];
4848	function getCartographyObjectConstructorFromServerSearchResultItem(serverSearchResultItem) {
4849		var selector = _.find(cartographyObjectTypeSelectors, function (selector) {
4850			return selector.property in serverSearchResultItem;
4851		});
4852		return selector && selector.ctor || _GasStation_;
4853	};
4854
4855	CartographyObjects.consts = consts;
4856	CartographyObjects.GasStation = requiredModules.util.stripType(_GasStation_);
4857	CartographyObjects.OilSeller = requiredModules.util.stripType(OilSeller);
4858	CartographyObjects.SalePoint = requiredModules.util.stripType(SalePoint);
4859	CartographyObjects.LegalEntities = requiredModules.util.stripType(LegalEntities);
4860	CartographyObjects.CartographyObject = requiredModules.util.stripType(CartographyObject);
4861	CartographyObjects.GasStationFuel = requiredModules.util.stripType(GasStationFuel);
4862	CartographyObjects.getCartographyObjectConstructorFromServerSearchResultItem = getCartographyObjectConstructorFromServerSearchResultItem;
4863}, this);;
4864// @hash v3-B2FDE9156B9BE797D6809CD202811B637DDEF23F
4865// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden.
4866// Version: 2.1.1-dev-20151124-1300 (build 563ed55)
4867// Generated at:
4868///////////////////////////////////////////////////////////////////////////////
4869
4870
4871LukoilApp.module("CartographyCommon", function (CartographyCommon, LukoilApp, Backbone, Marionette, $, _, global) {
4872	"use strict";
4873
4874	var requiredModules = {
4875		util: LukoilApp.module("Util"),
4876		objects: LukoilApp.module("CartographyObjects"),
4877		userLocation: LukoilApp.module("UserLocation")
4878	};
4879
4880	var consts = {
4881		formIds: requiredModules.objects.consts.formIds,
4882		filterIds: {
4883			federalLine: "federalLine",
4884			service: "service",
4885			roadService: "roadService",
4886			promotion: "promotion",
4887			fuelType: "fuelType",
4888			paymentType: "paymentType",
4889			cardType: "cardType",
4890			property: "property",
4891			highway: "highway",
4892			gasStationBusinessHours: "gasStationBusinessHours",
4893			tankFarmBusinessHours: "tankFarmBusinessHours",
4894			storeBusinessHours: "storeBusinessHours",
4895			geography: "geography",
4896			postCode: "postCode",
4897			date: "date",
4898			currentRegion: "currentdRegion",
4899			closestObjects: "closest",
4900			twentyFourHour: "twentyFourHour",
4901			CTO: "CTO",
4902			//oilBunkering: "oilBunkering",
4903			fuelBunkering: "fuelBunkering",
4904			company: "company",
4905			genesisOil: "genesisOil",
4906			luxeOil: "luxeOil",
4907			sellsOil: "sellsOil",
4908			salePointTypeId: "salePointTypeId",
4909			typeFilling: "typeFilling",
4910			shippingMethod: "shippingMethod",
4911			tankFarmFuel: "tankFarmFuel"
4912		},
4913		geolocationServiceTimeoutInMilliseconds: 10000,
4914		geolocationServiceMaxCacheAgeInMilliseconds: 10 * 60 * 1000
4915	};
4916
4917	;
4918
4919	function SearchProvider() {
4920		this.languageCode = "RU";
4921	};
4922
4923	// NOTE: maybe cache everything except fuel prices.
4924	SearchProvider.prototype.getObjectsInfoFromServer = (function () {
4925		var cache = requiredModules.util.createObject(null);
4926
4927		function getCacheKey(parameterCollection) {
4928			return JSON.stringify(parameterCollection);
4929		}
4930
4931		return function (objectInfoRequests) {
4932			var parameterCollection = {
4933				ids: _.map(objectInfoRequests, function (item) {
4934					return item.type + String(item.id);
4935				})
4936			};
4937			parameterCollection[global.Constants.queryParamNames.LanguageCode] = this.languageCode;
4938			return $.ajax("/api/cartography/GetObjects", {
4939				async: true,
4940				cache: true,
4941				ifModified: true,
4942				data: parameterCollection,
4943				dataType: "json",
4944				method: "GET",
4945				traditional: true
4946			}).then(function (serverSearchResults, statusString) {
4947				if (statusString === "notmodified" && serverSearchResults == null) {
4948					serverSearchResults = JSON.parse(cache[getCacheKey(parameterCollection)]);
4949				} else {
4950					cache[getCacheKey(parameterCollection)] = JSON.stringify(serverSearchResults);
4951				}
4952				return _.map(serverSearchResults, function (item) {
4953					return new (requiredModules.objects.getCartographyObjectConstructorFromServerSearchResultItem(item))(item);
4954				});
4955			});
4956		};
4957	})();
4958
4959	SearchProvider.prototype.getObjectInfoFromServer = function (type, id) {
4960		return this.getObjectsInfoFromServer([{ type: type, id: id }]).then(function (objects) {
4961			return objects[0];
4962		});
4963	};
4964
4965	SearchProvider.prototype.getFuelClasses = function (countryCode) {
4966		var parameters = {
4967			country: countryCode
4968		};
4969		parameters[global.Constants.queryParamNames.LanguageCode] = this.languageCode;
4970		return $.ajax("/api/cartography/GetFuelClasses", {
4971			async: true,
4972			cache: true,
4973			ifModified: true,
4974			data: parameters,
4975			dataType: "json",
4976			method: "GET",
4977			traditional: true
4978		}).then(function (serverFuelResult) {
4979			// Not handling undefined 304 response data because the web method is called only once and the browser provides a cached response.
4980
4981			return _.map(serverFuelResult, function (item) {
4982				return new requiredModules.objects.GasStationFuel(item);
4983			});
4984		});
4985	};
4986
4987	SearchProvider.prototype.setLanguage = function (languageCode) {
4988		this.languageCode = languageCode;
4989	};
4990
4991	var currentSelectedCountryModule = (function () {
4992		var countryCode;
4993		return {
4994			getCurrentSelectedCountry: function getCurrentSelectedCountry(languageCode) {
4995				return new requiredModules.util.JQueryPromiseWrapper(countryCode ? requiredModules.util.createResolvedPromise(countryCode) : requiredModules.userLocation.getCountryCode(languageCode));
4996			},
4997			setCurrentSelectedCountry: function setCurrentSelectedCountry(countryCode_) {
4998				countryCode = countryCode_;
4999			}
5000		};
5001	})();
5002
5003	CartographyCommon.consts = consts;
5004
5005	CartographyCommon.searchProvider = new SearchProvider();
5006
5007	CartographyCommon.getCurrentSelectedCountry = currentSelectedCountryModule.getCurrentSelectedCountry;
5008	CartographyCommon.setCurrentSelectedCountry = currentSelectedCountryModule.setCurrentSelectedCountry;
5009
5010	var uiModule = (function () {
5011		var deferred = $.Deferred();
5012		return {
5013			uiReady: new requiredModules.util.JQueryPromiseWrapper(deferred.promise()),
5014			activateUi: function activateUi() {
5015				deferred.resolve();
5016			}
5017		};
5018	})();
5019
5020	CartographyCommon.uiReady = uiModule.uiReady;
5021	CartographyCommon.activateUi = uiModule.activateUi;
5022
5023	var mapModule = (function (mapHolder, PromiseWrapperClass, $) {
5024		var mapDeferred = $.Deferred();
5025		return {
5026			initMap: function initMap(mapProvider, mapContainerElement, position, options) {
5027				mapHolder.map = new mapProvider.createPositionedMap(mapContainerElement, position, options);
5028				mapDeferred.resolve();
5029			},
5030
5031			mapReady: new PromiseWrapperClass(mapDeferred.promise())
5032		};
5033	})(CartographyCommon, requiredModules.util.JQueryPromiseWrapper, $);
5034
5035	CartographyCommon.initMap = mapModule.initMap;
5036	CartographyCommon.mapReady = mapModule.mapReady;
5037	CartographyCommon.map = requiredModules.util.stripType(null);
5038
5039	var iconModule = (function () {
5040		function getIconUrl(iconFileBaseUrl, fileNameSuffix) {
5041			if (iconFileBaseUrl) {
5042				var suffixIndex = iconFileBaseUrl.lastIndexOf(".");
5043				var result = suffixIndex >= 0 ? iconFileBaseUrl.substr(0, suffixIndex) + fileNameSuffix + iconFileBaseUrl.substr(suffixIndex) : iconFileBaseUrl + fileNameSuffix;
5044				var langFolder = window.GlobalSettings.Cartography.DefaultIconFolder;
5045				if ($.inArray(window.GlobalSettings.CurrentLanguage, window.GlobalSettings.Cartography.IconFolders) >= 0) {
5046					langFolder = window.GlobalSettings.CurrentLanguage;
5047				}
5048				result = result.replace(/\{0\}/g, langFolder);
5049				return result;
5050			} else {
5051				return null;
5052			}
5053		}
5054		return {
5055			getEnabledIconUrl: function getEnabledIconUrl(iconFileBaseUrl) {
5056				return getIconUrl(iconFileBaseUrl, "-red");
5057			},
5058			getDisabledIconUrl: function getDisabledIconUrl(iconFileBaseUrl) {
5059				return getIconUrl(iconFileBaseUrl, "-white");
5060			}
5061		};
5062	})();
5063	CartographyCommon.getEnabledIconUrl = iconModule.getEnabledIconUrl;
5064	CartographyCommon.getDisabledIconUrl = iconModule.getDisabledIconUrl;
5065
5066	CartographyCommon.getUserPositionIconUrl = function (formId) {
5067		return "/Content/img/icon-user-location-" + formId + ".png";
5068	};
5069}, this);;
5070// @hash v3-57BAD47D3193C3862CD5E5A1C49A8552EC5F013E
5071// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden.
5072// Version: 2.1.1-dev-20151124-1300 (build 563ed55)
5073// Generated at:
5074///////////////////////////////////////////////////////////////////////////////
5075
5076
5077LukoilApp.module("CartographySearch", function (CartographySearch, LukoilApp, Backbone, Marionette, $, _, global) {
5078	"use strict";
5079
5080	var requiredModules = {
5081		util: LukoilApp.module("Util"),
5082		common: LukoilApp.module("CartographyCommon")
5083	};
5084
5085	CartographySearch.objectTypes = {
5086		gasStation: "gasStation",
5087		oilSeller: "oilSeller",
5088		salePoint: "salePoint",
5089		airport: "airport",
5090		tankFarm: "tankFarm",
5091		legalEntities: "legalEntities",
5092		seaport: "seaport"
5093	};
5094
5095	var wordSizeShift = 5;
5096	var wordSize = 1 << wordSizeShift;
5097	var wordMask = wordSize - 1;
5098
5099	function pad(a, length, value) {
5100		var i = a.length;
5101		for (; i < length; ++i) {
5102			a.push(value);
5103		}
5104	}
5105
5106	function padBitSet(objects, dictionary, propertyName) {
5107		var size = Math.ceil(dictionary.length / wordSize);
5108		_.each(objects, function (o) {
5109			pad(o[propertyName], size, 0);
5110		});
5111	}
5112
5113	var serviceBitsPropertyName = "serviceBits";
5114	var roadServiceBitsPropertyName = "roadServiceBits";
5115	var promotionBitsPropertyName = "promotionBits";
5116	var fuelClassBitsPropertyName = "fuelClassBits";
5117	var paymentTypeBitsPropertyName = "paymentTypeBits";
5118	var cardTypeBitsPropertyName = "cardTypeBits";
5119	var propertyBitsPropertyName = "propertyBits";
5120	var luxeOilPropertyName = "luxeFlag";
5121	var genesisOilPropertyName = "genesisFlag";
5122	var gasStationBusinessHoursPropertyName = "businessHours";
5123	var tankFarmBusinessHoursPropertyName = "tankFarmBusinessHours";
5124	var typeFillingPropertyName = "typeFilling";
5125	var shippingMethodPropertyName = "shippingMethod";
5126	var tankFarmFuelPropertyName = "tankFarmFuel";
5127	var storeBusinessHoursPropertyName = "storeBusinessHours";
5128	var open24HoursPropertyName = "open24Hours";
5129	var CTOPropertyName = "cto";
5130	var sellsOilPropertyName = "sellsOil";
5131	var highwayPropertyName = "highwayId";
5132	var postCodePropertyName = "postCode";
5133
5134	var disjunction = 0;
5135	var conjunction = 1;
5136
5137	function initializeGasStations(searchData) {
5138		padBitSet(searchData.gasStations, searchData.services, serviceBitsPropertyName);
5139		padBitSet(searchData.gasStations, searchData.promotions, promotionBitsPropertyName);
5140		padBitSet(searchData.gasStations, searchData.fuelClasses, fuelClassBitsPropertyName);
5141		padBitSet(searchData.gasStations, searchData.paymentTypes, paymentTypeBitsPropertyName);
5142		padBitSet(searchData.gasStations, searchData.properties, propertyBitsPropertyName);
5143	}
5144
5145	function initializeOilSellers(searchData) {
5146		padBitSet(searchData.oilSellers, searchData.promotions, promotionBitsPropertyName);
5147	}
5148
5149	function initializeSalePoints(searchData) {
5150		padBitSet(searchData.salePoints, searchData.roadServices, roadServiceBitsPropertyName);
5151		padBitSet(searchData.salePoints, searchData.cardTypes, cardTypeBitsPropertyName);
5152	}
5153
5154	function getCondition(bitWords, objectVariableName, propertyName, joinType) {
5155		var a = [];
5156		_.each(bitWords, function (w, index) {
5157			if (w !== 0) {
5158				a.push("((" + objectVariableName + "." + propertyName + "[" + index + "]" + " & " + w + ")" + (joinType === disjunction ? " !== 0 " : " === " + w) + ")");
5159			}
5160		});
5161		return a.length > 0 ? "(" + a.join(joinType === disjunction ? " || " : " && ") + ")" : "";
5162	}
5163	function getArrayCondition(propertyName, objectVariableName, filterValues) {
5164		if (!filterValues || filterValues.length === 0) {
5165			return "";
5166		}
5167
5168		return objectVariableName + "." + propertyName + " != null && " + objectVariableName + "." + propertyName + ".some(function(v){ return " + JSON.stringify(filterValues) + ".indexOf(v) !== -1 })";
5169	}
5170	function encodeAsBits(set, baseSet) {
5171		var size = baseSet.length;
5172		var encoded = new Array(size + wordSize - 1 >> wordSizeShift);
5173		var i;
5174		for (i = 0; i < encoded.length; ++i) {
5175			encoded[i] = 0;
5176		}
5177		_.each(set, function (a) {
5178			var n = _.indexOf(baseSet, a);
5179			if (n >= 0) {
5180				encoded[n >> wordSizeShift] |= 1 << (n & wordMask);
5181			}
5182		});
5183		return encoded;
5184	}
5185
5186	function getClosestObjects(searchObjects) {
5187		if (searchObjects.length === 0 || searchObjects[0].distanceFromUser == null) {
5188			return searchObjects;
5189		} else {
5190			var _ret = (function () {
5191				var minDistance = requiredModules.util.rejectNull(_.min(searchObjects, function (searchObject) {
5192					return requiredModules.util.rejectNull(searchObject.distanceFromUser);
5193				}).distanceFromUser);
5194				var radius = minDistance * (1.0 + closestObjectMarginPercent / 100.0);
5195				return {
5196					v: _.filter(searchObjects, function (o) {
5197						return requiredModules.util.rejectNull(o.distanceFromUser) <= radius;
5198					})
5199				};
5200			})();
5201
5202			if (typeof _ret === "object") return _ret.v;
5203		}
5204	};
5205
5206	function filterObjectsByGeographyBounds(objects, bounds) {
5207		var leftLongitude = requiredModules.util.normalizeLongitude(bounds.leftBoundLongitude);
5208		var rightLongitude = leftLongitude + bounds.longitudinalSpan;
5209		var longitudeRanges = rightLongitude > 180 ? [{ a: leftLongitude, b: 180 }, { a: -180, b: rightLongitude - 360 }] : [{ a: leftLongitude, b: rightLongitude }];
5210		var result = [];
5211		var i;
5212		var len = objects.length;
5213		var x;
5214		if (longitudeRanges.length === 1) {
5215			for (i = 0; i < len; ++i) {
5216				x = objects[i];
5217				if (bounds.minLatitude <= x.Latitude && x.Latitude <= bounds.maxLatitude && longitudeRanges[0].a <= x.Longitude && x.Longitude <= longitudeRanges[0].b) {
5218					result.push(x);
5219				}
5220			}
5221		} else {
5222			for (i = 0; i < len; ++i) {
5223				x = objects[i];
5224				if (bounds.minLatitude <= x.Latitude && x.Latitude <= bounds.maxLatitude && (longitudeRanges[0].a <= x.Longitude && x.Longitude <= longitudeRanges[0].b || longitudeRanges[1].a <= x.Longitude && x.Longitude <= longitudeRanges[1].b)) {
5225					result.push(x);
5226				}
5227			}
5228		}
5229		return result;
5230	}
5231
5232	function getBusinessHoursCondition(businessHours, businessHoursPropertyName, objectVariableName) {
5233		if (businessHours && businessHours.length > 0) {
5234			var _a = [];
5235			var i;
5236			for (i = 0; i < businessHours.length; ++i) {
5237				if (businessHours[i]) {
5238					_a.push(objectVariableName + "." + businessHoursPropertyName + "[" + i + "] != null && " + objectVariableName + "." + businessHoursPropertyName + "[" + i + "][0] <= " + businessHours[i][0] + " && " + businessHours[i][1] + " <= " + objectVariableName + "." + businessHoursPropertyName + "[" + i + "][1]");
5239				}
5240			}
5241			var s = _a.join(" && ");
5242			return s.length > 0 ? "( " + objectVariableName + "." + businessHoursPropertyName + " != null && " + s + ")" : "";
5243		} else {
5244			return "";
5245		}
5246	}
5247
5248	function getTankFarmBusinessHoursCondition(businessHours, businessHoursPropertyName, objectVariableName) {
5249		if (businessHours && businessHours.length > 0) {
5250			var _a2 = [];
5251			var i;
5252
5253			for (i = 0; i < businessHours.length; ++i) {
5254				if (businessHours[i]) {
5255					_a2.push(objectVariableName + "." + businessHoursPropertyName + "[" + i + "] != null" + " && " + objectVariableName + "." + businessHoursPropertyName + "[" + i + "][0] <= " + businessHours[i][0] + " && " + businessHours[i][1] + " <= " + objectVariableName + "." + businessHoursPropertyName + "[" + i + "][1]");
5256				}
5257			}
5258
5259			var s = _a2.join(" && ");
5260
5261			return s.length > 0 ? "(" + objectVariableName + "." + businessHoursPropertyName + " == null" + " || " + "(" + objectVariableName + "." + businessHoursPropertyName + " != null && " + s + ")" + ")" : "";
5262		}
5263
5264		return "";
5265	}
5266
5267	function getBooleanCondition(propertyName, objectVariableName) {
5268		return "(" + objectVariableName + "." + propertyName + ")";
5269	}
5270
5271	function getValueCondition(propertyName, objectVariableName, value) {
5272		return "(" + objectVariableName + "." + propertyName + " === " + global.JSON.stringify(value) + ")";
5273	}
5274
5275	var searchFunctionCode = "var r = [];\n" + "var len = a.length;\n" + "var i;\n" + "var x;\n" + "for (i = 0; i < len; ++i) {\n" + "	x = a[i];\n" + "	if (<%= condition %>) {\n" + "		r.push(x);\n" + "	}\n" + "}\n" + "return r;\n";
5276
5277	function searchGasStations(data, parameters) {
5278		var services = parameters[requiredModules.common.consts.filterIds.service] || [];
5279		var promotions = parameters[requiredModules.common.consts.filterIds.promotion] || [];
5280		var paymentTypes = parameters[requiredModules.common.consts.filterIds.paymentType] || [];
5281		var fuelClasses = parameters[requiredModules.common.consts.filterIds.fuelType] || [];
5282		var properties = parameters[requiredModules.common.consts.filterIds.property] || [];
5283		var gasStationBusinessHours = parameters[requiredModules.common.consts.filterIds.gasStationBusinessHours] || null;
5284		var storeBusinessHours = parameters[requiredModules.common.consts.filterIds.storeBusinessHours] || null;
5285		var shouldSellOil = parameters[requiredModules.common.consts.filterIds.sellsOil] || false;
5286		var highwayId = parameters[requiredModules.common.consts.filterIds.highway] != null ? global.parseInt(parameters[requiredModules.common.consts.filterIds.highway], 10) : null;
5287		var postCode = parameters[requiredModules.common.consts.filterIds.postCode] || null;
5288
5289		if (storeBusinessHours) {
5290			services.push(data.storeServiceId);
5291		}
5292
5293		var serviceBits = encodeAsBits(services, data.services);
5294		var promotionBits = encodeAsBits(promotions, data.promotions);
5295		var paymentTypeBits = encodeAsBits(paymentTypes, data.paymentTypes);
5296		var fuelClassBits = encodeAsBits(fuelClasses, data.fuelClasses);
5297		var propertyBits = encodeAsBits(properties, data.properties);
5298
5299		var objectVariableName = "x";
5300
5301		var code = searchFunctionCode;
5302
5303		var servicesCondition = getCondition(serviceBits, objectVariableName, serviceBitsPropertyName, conjunction);
5304		var promotionsCondition = getCondition(promotionBits, objectVariableName, promotionBitsPropertyName, disjunction);
5305		var fuelClassesCondition = getCondition(fuelClassBits, objectVariableName, fuelClassBitsPropertyName, disjunction);
5306		var paymentTypesCondition = getCondition(paymentTypeBits, objectVariableName, paymentTypeBitsPropertyName, disjunction);
5307		var propertyCondition = getCondition(propertyBits, objectVariableName, propertyBitsPropertyName, disjunction);
5308		var gasStationBusinessHoursCondition = getBusinessHoursCondition(gasStationBusinessHours, gasStationBusinessHoursPropertyName, objectVariableName);
5309		var storeBusinessHoursCondition = getBusinessHoursCondition(storeBusinessHours, storeBusinessHoursPropertyName, objectVariableName);
5310		var shouldSellOilCondition = shouldSellOil && getBooleanCondition(sellsOilPropertyName, objectVariableName) || "";
5311		var highwayCondition = highwayId != null ? getValueCondition(highwayPropertyName, objectVariableName, highwayId) : "";
5312		var postCodeCondition = postCode != null ? getValueCondition(postCodePropertyName, objectVariableName, postCode) : "";
5313
5314		var filterConditions = _.filter([promotionsCondition, servicesCondition, fuelClassesCondition, paymentTypesCondition, propertyCondition, gasStationBusinessHoursCondition, storeBusinessHoursCondition, shouldSellOilCondition, highwayCondition, postCodeCondition], function (c) {
5315			return c.length > 0;
5316		});
5317		var condition = filterConditions.length > 0 ? filterConditions.join(" && ") : "true";
5318
5319		var result = new Function("a", _.template(code)({ condition: condition }))(data.gasStations);
5320
5321		return result;
5322	}
5323
5324	function searchOilSellers(data, parameters) {
5325		var promotions = parameters[requiredModules.common.consts.filterIds.promotion] || [];
5326		var mustBeOpen24Hours = parameters[requiredModules.common.consts.filterIds.twentyFourHour] || false;
5327		var mustBeCTO = parameters[requiredModules.common.consts.filterIds.CTO] || false;
5328
5329		var promotionBits = encodeAsBits(promotions, data.promotions);
5330
5331		var objectVariableName = "x";
5332
5333		var code = searchFunctionCode;
5334
5335		var genesisCondition = parameters[requiredModules.common.consts.filterIds.genesisOil] && getBooleanCondition(genesisOilPropertyName, objectVariableName) || "";
5336		var luxeCondition = parameters[requiredModules.common.consts.filterIds.luxeOil] && getBooleanCondition(luxeOilPropertyName, objectVariableName) || "";
5337		var promotionsCondition = getCondition(promotionBits, objectVariableName, promotionBitsPropertyName, disjunction);
5338		var open24HoursCondition = mustBeOpen24Hours && getBooleanCondition(open24HoursPropertyName, objectVariableName) || "";
5339		var CTOCondition = mustBeCTO && getBooleanCondition(CTOPropertyName, objectVariableName) || "";
5340
5341		if (mustBeCTO) {
5342			$("#OilTitleCTO").show();
5343			$("#OilTitleSeller").hide();
5344		} else {
5345			$("#OilTitleCTO").hide();
5346			$("#OilTitleSeller").show();
5347		}
5348
5349		var filterConditions = _.filter([promotionsCondition, genesisCondition, luxeCondition, open24HoursCondition, CTOCondition], function (c) {
5350			return c.length > 0;
5351		});
5352		var condition = filterConditions.length > 0 ? filterConditions.join(" && ") : "true";
5353		var result = new Function("a", _.template(code)({ condition: condition }))(data.oilSellers);
5354
5355		return result;
5356	}
5357
5358	function searchSalePoints(data, parameters) {
5359		//return data;
5360		var roadServices = parameters[requiredModules.common.consts.filterIds.roadService] || [];
5361		var cardTypes = parameters[requiredModules.common.consts.filterIds.cardType] || [];
5362		var postCode = parameters[requiredModules.common.consts.filterIds.postCode] || null;
5363
5364		var roadServiceBits = encodeAsBits(roadServices, data.roadServices);
5365		var cardTypeBits = encodeAsBits(cardTypes, data.cardTypes);
5366
5367		var objectVariableName = "x";
5368
5369		var code = searchFunctionCode;
5370
5371		var roadServicesCondition = getCondition(roadServiceBits, objectVariableName, roadServiceBitsPropertyName, disjunction);
5372		var cardTypesCondition = getCondition(cardTypeBits, objectVariableName, cardTypeBitsPropertyName, disjunction);
5373		var postCodeCondition = postCode != null ? getValueCondition(postCodePropertyName, objectVariableName, postCode) : "";
5374
5375		var filterConditions = _.filter([roadServicesCondition, cardTypesCondition, postCodeCondition], function (c) {
5376			return c.length > 0;
5377		});
5378		var condition = filterConditions.length > 0 ? filterConditions.join(" && ") : "true";
5379		var result = new Function("a", _.template(code)({ condition: condition }))(data.salePoints);
5380
5381		return result;
5382	}
5383
5384	function searchAirports(data, parameters) {
5385		return data;
5386	}
5387
5388	function searchSeaports(data, parameters) {
5389		//const mustBunkerFuel: boolean = parameters[requiredModules.common.consts.filterIds.fuelBunkering] || false;
5390
5391		var companyIdString = parameters[requiredModules.common.consts.filterIds.company];
5392		var companyId = companyIdString == null ? null : global.parseInt(companyIdString, 10);
5393
5394		return _.filter(data, function (s) {
5395			return (/*(!mustBunkerFuel || s.isBunkeringFuel )  && (!mustBunkerOil || s.isBunkeringOil) && */companyId == null || s.fuelingCompanyId === companyId /*|| s.oilingCompanyId === companyId */
5396			);
5397		});
5398	}
5399
5400	function searchSeaportsOil(data, parameters) {
5401		return _.filter(data, function (s) {
5402			return true;
5403		});
5404	}
5405
5406	function sear
5406chTankFarms(data, parameters) {
5407
5408		var companyId = parameters[requiredModules.common.consts.filterIds.company] != null ? global.parseInt(parameters[requiredModules.common.consts.filterIds.company], 10) : null;
5409		var typeFilling = parameters[requiredModules.common.consts.filterIds.typeFilling] || [];
5410		var shippingMethod = parameters[requiredModules.common.consts.filterIds.shippingMethod] || [];
5411		var tankFarmFuel = parameters[requiredModules.common.consts.filterIds.tankFarmFuel] || [];
5412		var tankFarmBusinessHours = parameters[requiredModules.common.consts.filterIds.tankFarmBusinessHours] || null;
5413
5414		var objectVariableName = "x";
5415		var code = searchFunctionCode;
5416
5417		var companyCondition = companyId != null ? getValueCondition(companyIdPropertyName, objectVariableName, companyId) : "";
5418		var tankFarmBusinessHoursCondition = getTankFarmBusinessHoursCondition(tankFarmBusinessHours, tankFarmBusinessHoursPropertyName, objectVariableName);
5419		var typeFillingCondition = getArrayCondition(typeFillingPropertyName, objectVariableName, typeFilling);
5420		var shippingMethodCondition = getArrayCondition(shippingMethodPropertyName, objectVariableName, shippingMethod);
5421		var tankFarmFuelCondition = getArrayCondition(tankFarmFuelPropertyName, objectVariableName, tankFarmFuel);
5422
5423		var filterConditions = _.filter([companyCondition, typeFillingCondition, shippingMethodCondition, tankFarmFuelCondition, tankFarmBusinessHoursCondition], function (c) {
5424			return c && c.length > 0;
5425		});
5426
5427		var condition = filterConditions.length > 0 ? filterConditions.join(" && ") : "true";
5428
5429		return new Function("a", _.template(code)({ condition: condition }))(data);
5430	}
5431
5432	function searchLegalEntities(data, parameters) {
5433		var serviceIds = parameters[requiredModules.common.consts.filterIds.service] || [];
5434		var fuelTypeIds = parameters[requiredModules.common.consts.filterIds.fuelType] || [];
5435		var propertyIds = parameters[requiredModules.common.consts.filterIds.property] || [];
5436		var cardTypeIds = parameters[requiredModules.common.consts.filterIds.cardType] || [];
5437
5438		return _.filter(data, function (s) {
5439			var matchesService = serviceIds.length === 0 || _.some(serviceIds, function (serviceId) {
5440				return _.contains(s.ServiceIds || [], serviceId);
5441			});
5442			var matchesFuelType = fuelTypeIds.length === 0 || _.some(fuelTypeIds, function (fuelTypeId) {
5443				return _.contains(s.FuelIds || [], fuelTypeId);
5444			});
5445			var matchesProperty = propertyIds.length === 0 || _.some(propertyIds, function (propertyId) {
5446				return _.contains(s.PropertyIds || [], propertyId);
5447			});
5448			var matchesCardType = cardTypeIds.length === 0 || _.some(cardTypeIds, function (cardTypeId) {
5449				return _.contains(s.CardTypeIds || [], cardTypeId);
5450			});
5451
5452			return matchesService && matchesFuelType && matchesProperty && matchesCardType;
5453		});
5454	}
5455
5456	function searchLegalEntities(data, parameters) {
5457		var serviceIds = parameters[requiredModules.common.consts.filterIds.service] || [];
5458		var fuelTypeIds = parameters[requiredModules.common.consts.filterIds.fuelType] || [];
5459		var propertyIds = parameters[requiredModules.common.consts.filterIds.property] || [];
5460		var cardTypeIds = parameters[requiredModules.common.consts.filterIds.cardType] || [];
5461
5462		return _.filter(data, function (s) {
5463			var matchesService = serviceIds.length === 0 || _.some(serviceIds, function (serviceId) {
5464				return _.contains(s.ServiceIds || [], serviceId);
5465			});
5466			var matchesFuelType = fuelTypeIds.length === 0 || _.some(fuelTypeIds, function (fuelTypeId) {
5467				return _.contains(s.FuelIds || [], fuelTypeId);
5468			});
5469			var matchesProperty = propertyIds.length === 0 || _.some(propertyIds, function (propertyId) {
5470				return _.contains(s.PropertyIds || [], propertyId);
5471			});
5472			var matchesCardType = cardTypeIds.length === 0 || _.some(cardTypeIds, function (cardTypeId) {
5473				return _.contains(s.CardTypeIds || [], cardTypeId);
5474			});
5475
5476			return matchesService && matchesFuelType && matchesProperty && matchesCardType;
5477		});
5478	}
5479
5480	function searchLegalEntities(data, parameters) {
5481		var serviceIds = parameters[requiredModules.common.consts.filterIds.service] || [];
5482		var fuelTypeIds = parameters[requiredModules.common.consts.filterIds.fuelType] || [];
5483		var propertyIds = parameters[requiredModules.common.consts.filterIds.property] || [];
5484		var cardTypeIds = parameters[requiredModules.common.consts.filterIds.cardType] || [];
5485
5486		return _.filter(data, function (s) {
5487			var matchesService = serviceIds.length === 0 || _.some(serviceIds, function (serviceId) {
5488				return _.contains(s.ServiceIds || [], serviceId);
5489			});
5490			var matchesFuelType = fuelTypeIds.length === 0 || _.some(fuelTypeIds, function (fuelTypeId) {
5491				return _.contains(s.FuelIds || [], fuelTypeId);
5492			});
5493			var matchesProperty = propertyIds.length === 0 || _.some(propertyIds, function (propertyId) {
5494				return _.contains(s.PropertyIds || [], propertyId);
5495			});
5496			var matchesCardType = cardTypeIds.length === 0 || _.some(cardTypeIds, function (cardTypeId) {
5497				return _.contains(s.CardTypeIds || [], cardTypeId);
5498			});
5499
5500			return matchesService && matchesFuelType && matchesProperty && matchesCardType;
5501		});
5502	}
5503
5504	var searchDeferreds = requiredModules.util.createObject(null);
5505	_.each(requiredModules.common.consts.formIds, function (formId) {
5506		searchDeferreds[formId] = $.Deferred();
5507	});
5508	var closestObjectMarginPercent;
5509
5510	CartographySearch.initializeForObjectType = function (formId, searchData, closestObjectMarginPercent_) {
5511		closestObjectMarginPercent = closestObjectMarginPercent_;
5512		var deferred = searchDeferreds[formId];
5513		switch (formId) {
5514			case requiredModules.common.consts.formIds.gasStation:
5515				initializeGasStations(searchData);
5516				deferred.resolve(searchGasStations, searchData);
5517				break;
5518			case requiredModules.common.consts.formIds.airport:
5519				deferred.resolve(searchAirports, searchData);
5520				break;
5521			case requiredModules.common.consts.formIds.seaport:
5522				deferred.resolve(searchSeaports, searchData);
5523				break;
5524			case requiredModules.common.consts.formIds.seaportOil:
5525				deferred.resolve(searchSeaportsOil, searchData);
5526				break;
5527			case requiredModules.common.consts.formIds.tankFarm:
5528				deferred.resolve(searchTankFarms, searchData);
5529				break;
5530			case requiredModules.common.consts.formIds.legalEntities:
5531				deferred.resolve(searchLegalEntities, searchData);
5532				break;
5533			case requiredModules.common.consts.formIds.oilSeller:
5534				initializeOilSellers(searchData);
5535				deferred.resolve(searchOilSellers, searchData);
5536				break;
5537			case requiredModules.common.consts.formIds.salePoint:
5538				initializeSalePoints(searchData);
5539				deferred.resolve(searchSalePoints, searchData);
5540				break;
5541		}
5542	};
5543	CartographySearch.search = function (formId, parameters) {
5544		return searchDeferreds[formId].then(function (searchFunction, searchData) {
5545			return searchFunction(searchData, parameters);
5546		});
5547	};
5548
5549	CartographySearch.filterObjectsByGeographyBounds = filterObjectsByGeographyBounds;
5550	CartographySearch.getClosestObjects = getClosestObjects;
5551
5552	CartographySearch.searchGasStationsForRouting = function (fuelClassIds, minLatitude, maxLatitude, leftBoundLongitude, longitudinalSpan, mustBeTwentyFourHour) {
5553		var selections = requiredModules.util.createObject(null);
5554		if (mustBeTwentyFourHour) {
5555			selections[requiredModules.common.consts.filterIds.gasStationBusinessHours] = requiredModules.util.createArray([0, 24], 7);
5556		}
5557		if (fuelClassIds) {
5558			selections[requiredModules.common.consts.filterIds.fuelType] = fuelClassIds;
5559		}
5560		var bounds = new requiredModules.util.GeographySpan(minLatitude, maxLatitude, leftBoundLongitude, longitudinalSpan);
5561		return this.search(requiredModules.common.consts.formIds.gasStation, selections).then(function (results) {
5562			return filterObjectsByGeographyBounds(results, bounds);
5563		}).then(function (results) {
5564			return _.map(results, function (item) {
5565				return requiredModules.util.createObject(item);
5566			});
5567		});
5568	};
5569}, this);
5570//const mustBunkerOil: boolean = parameters[requiredModules.common.consts.filterIds.oilBunkering] || false;;
5571// @hash v3-F1EAB957902B5EB1B59241BD15C5341B3B0863A9
5572// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden.
5573// Version: 2.1.1-dev-20151124-1300 (build 563ed55)
5574// Generated at:
5575///////////////////////////////////////////////////////////////////////////////
5576
5577
5578LukoilApp.module("GoogleMapServices", function (GoogleMapServices, LukoilApp, Backbone, Marionette, $, _, global) {
5579	"use strict";
5580
5581	var requiredModules = {
5582		util: LukoilApp.module("Util")
5583	};
5584
5585	var minPauseBetweenRequestsInMilliseconds = 1000;
5586
5587	var throttler = new requiredModules.util.Throttler(minPauseBetweenRequestsInMilliseconds);
5588
5589	function getResultPlaceIdFromGeocodingResults(geocodingResults, predicate) {
5590		var result = _.find(geocodingResults, predicate);
5591		return result != null ? result.place_id : null;
5592	};
5593
5594	function getCountryFromGeocodingResults(geocodingResults) {
5595		var countryType = "country";
5596		function hasCountryType(item) {
5597			return _.contains(item.types, countryType);
5598		};
5599
5600		return _.find(geocodingResults, hasCountryType);
5601	};
5602
5603	function getCountryPlaceIdFromGeocodingResults(geocodingResults) {
5604		var country = getCountryFromGeocodingResults(geocodingResults);
5605		return country != null ? country.place_id : null;
5606	};
5607
5608	function getRegionPlaceIdFromGeocodingResults(geocodingResults) {
5609		var regionType = "administrative_area_level_1";
5610		function hasRegionType(item) {
5611			return _.contains(item.types, regionType);
5612		};
5613
5614		return getResultPlaceIdFromGeocodingResults(geocodingResults, hasRegionType);
5615	};
5616
5617	// geocodingResults must be non-empty.
5618	function getMostSpecificGeocodingResult(geocodingResults) {
5619		return _.max(geocodingResults, function (item) {
5620			return item.address_components.length;
5621		});
5622	};
5623
5624	function getGeocodingResultWithoutUnnamedRoads(geocodingResults) {
5625		// filter results with Unnamed Road in address,
5626
5627		var withoutUnnamedRoads = _.filter(geocodingResults, function (r) {
5628			return r.formatted_address.indexOf("Unnamed Road") === -1;
5629		});
5630		return _.max(withoutUnnamedRoads.length > 0 ? withoutUnnamedRoads : geocodingResults, function (item) {
5631			return item.address_components.length;
5632		});
5633	};
5634
5635	;
5636
5637	function GeocodingService() {
5638		this.geocoder = new global.google.maps.Geocoder();
5639		this.cachedResults = requiredModules.util.createObject(null);
5640	};
5641
5642	function putInCache(cache, key, value) {
5643		cache[JSON.stringify(key)] = value;
5644	}
5645
5646	function getFromCache(cache, key) {
5647		return cache[JSON.stringify(key)];
5648	}
5649
5650	GeocodingService.prototype.wrapGeocoderCallInPromise = function () {
5651		var self = this;
5652		var deferred = $.Deferred();
5653		var geocoderArguments = _.map(arguments, function (x) {
5654			return x;
5655		}).concat([function (results, status) {
5656			deferred.resolve(results, status);
5657		}]);
5658		self.geocoder.geocode.apply(self.geocoder, geocoderArguments);
5659		return deferred.promise();
5660	};
5661
5662	GeocodingService.prototype.getPossiblyCachedGoogleResultForLocation = function (latitude, longitude, startCallback) {
5663		var self = this;
5664		var key = { latitude: latitude, longitude: longitude };
5665		var result = getFromCache(self.cachedResults, key);
5666		if (result) {
5667			return requiredModules.util.createResolvedPromise.apply(requiredModules.util, result);
5668		} else {
5669			var promise = startCallback();
5670			promise.done(function () {
5671				putInCache(self.cachedResults, key, arguments);
5672			});
5673			return promise;
5674		}
5675	};
5676
5677	GeocodingService.prototype.getFormattedAddress = function (latitude, longitude) {
5678		var self = this;
5679
5680		return self.getPossiblyCachedGoogleResultForLocation(latitude, longitude, function () {
5681			return throttler.throttle(function () {
5682				return self.wrapGeocoderCallInPromise({
5683					location: new global.google.maps.LatLng(latitude, longitude)
5684				});
5685			});
5686		}).then(function (results, status) {
5687			if (status === "OK" && results != null) {
5688				return { address: getGeocodingResultWithoutUnnamedRoads(results).formatted_address };
5689			} else {
5690				return requiredModules.util.createRejectedPromise("Failed to get address for the specified location.");
5691			}
5692		});
5693	};
5694
5695	GeocodingService.prototype.getCountryAndRegionPlaceIds = function (latitude, longitude) {
5696		var self = this;
5697
5698		return self.getPossiblyCachedGoogleResultForLocation(latitude, longitude, function () {
5699			return throttler.throttle(function () {
5700				return self.wrapGeocoderCallInPromise({
5701					location: new global.google.maps.LatLng(latitude, longitude)
5702				});
5703			});
5704		}).then(function (results, status) {
5705			if (status === "OK" && results != null) {
5706				return {
5707					countryPlaceId: getCountryPlaceIdFromGeocodingResults(results),
5708					regionPlaceId: getRegionPlaceIdFromGeocodingResults(results)
5709				};
5710			} else {
5711				return requiredModules.util.createRejectedPromise("Failed to get country and place IDs for the specified location.");
5712			}
5713		});
5714	};
5715
5716	GeocodingService.prototype.getCountryBounds = function (latitude, longitude) {
5717		var self = this;
5718
5719		return self.getPossiblyCachedGoogleResultForLocation(latitude, longitude, function () {
5720			return throttler.throttle(function () {
5721				return self.wrapGeocoderCallInPromise({
5722					location: new global.google.maps.LatLng(latitude, longitude)
5723				});
5724			});
5725		}).then(function (results, status) {
5726			if (status === "OK" && results != null) {
5727				var country = getCountryFromGeocodingResults(results);
5728				if (country) {
5729					var ne = country.geometry.viewport.getNorthEast();
5730					var sw = country.geometry.viewport.getSouthWest();
5731					return {
5732						minLatitude: sw.lat(),
5733						maxLatitude: ne.lat(),
5734						leftLongitude: sw.lng(),
5735						rightLongitude: ne.lng()
5736					};
5737				} else {
5738					return requiredModules.util.createRejectedPromise("Failed to get country bounds for the specified location.");
5739				}
5740			} else {
5741				return requiredModules.util.createRejectedPromise("Failed to get country bounds for the specified location.");
5742			}
5743		});
5744	};
5745
5746	GeocodingService.prototype.getAddressBounds = function (address) {
5747		var self = this;
5748		if (!address || !requiredModules.util.trimString(address)) {
5749			return requiredModules.util.createRejectedPromise();
5750		}
5751		return throttler.throttle(function () {
5752			return self.wrapGeocoderCallInPromise({
5753				address: address
5754			});
5755		}).then(function (results, status) {
5756			if (status === "OK" && results != null) {
5757				var result = getMostSpecificGeocodingResult(results);
5758				var ne = result.geometry.viewport.getNorthEast();
5759				var sw = result.geometry.viewport.getSouthWest
5759();
5760				return {
5761					minLatitude: sw.lat(),
5762					maxLatitude: ne.lat(),
5763					leftLongitude: sw.lng(),
5764					rightLongitude: ne.lng()
5765				};
5766			} else {
5767				return requiredModules.util.createRejectedPromise();
5768			}
5769		});
5770	};
5771	GeocodingService.prototype.getLocation = function (address) {
5772		var self = this;
5773		if (!address || !requiredModules.util.trimString(address)) {
5774			return requiredModules.util.createRejectedPromise();
5775		}
5776		return throttler.throttle(function () {
5777			return self.wrapGeocoderCallInPromise({
5778				address: address
5779			});
5780		}).then(function (results, status) {
5781			if (status === "OK" && results != null) {
5782				var result = getMostSpecificGeocodingResult(results);
5783				var routingResult = getGeocodingResultWithoutUnnamedRoads(results);
5784				return {
5785					location: result.geometry.location,
5786					routingLocation: { latitude: routingResult.geometry.location.lat(), longitude: routingResult.geometry.location.lng() }
5787				};
5788			} else {
5789				return requiredModules.util.createRejectedPromise("Failed to get location for address: " + requiredModules.util.rejectNull(address));
5790			}
5791		});
5792	};
5793
5794	function init() {
5795		GoogleMapServices.geocodingService = new GeocodingService();
5796		return $.ajax({
5797			url: "/Scripts/lib/googlemap-marker-with-label.js",
5798			dataType: "script",
5799			cache: true
5800		});
5801	};
5802
5803	GoogleMapServices.apiLoadFailureHandler = function () {};
5804
5805	var googleMapsScriptLoadedDeferred;
5806
5807	GoogleMapServices.onGoogleMapsScriptLoaded = function () {
5808		init().then(function () {
5809			googleMapsScriptLoadedDeferred.resolve();
5810		}, function () {
5811			googleMapsScriptLoadedDeferred.reject();
5812		});
5813	};
5814
5815	GoogleMapServices.apiKey = window.GlobalSettings.GoogleApiKey;
5816
5817	GoogleMapServices.disableApiKey = function () {
5818		GoogleMapServices.apiKey = "";
5819	};
5820
5821	GoogleMapServices.ensureMapApiIsReady = function (languageCode) {
5822		// Libraries: "places" for address field autocomplete on cartography page.
5823
5824		if (!googleMapsScriptLoadedDeferred) {
5825			googleMapsScriptLoadedDeferred = $.Deferred();
5826			var effectiveLanguageCode = languageCode || "RU";
5827			$.ajax({
5828				url: "https://maps.googleapis.com/maps/api/js?key=" + GoogleMapServices.apiKey + "&v=3&libraries=geometry,places&language=" + effectiveLanguageCode + "&callback=LukoilApp.GoogleMapServices.onGoogleMapsScriptLoaded",
5829				dataType: "script",
5830				cache: true
5831			}).fail(function () {
5832				googleMapsScriptLoadedDeferred.reject("Google Maps script failed to load.");
5833			});
5834			googleMapsScriptLoadedDeferred.fail(function (message) {
5835				requiredModules.util.logError(message);
5836				GoogleMapServices.apiLoadFailureHandler();
5837			});
5838		}
5839		return new requiredModules.util.JQueryPromiseWrapper(googleMapsScriptLoadedDeferred.promise());
5840	};
5841
5842	GoogleMapServices.computeGeographicalDistanceInMeters = function (latitude1, longitude1, latitude2, longitude2) {
5843		return google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(latitude1, longitude1), new google.maps.LatLng(latitude2, longitude2));
5844	};
5845
5846	GoogleMapServices.createAddressSearchInput = function (inputElement, changeEventCallback, changeEventCallbackIfNotResolving) {
5847		var effectiveChangeEventCallback = changeEventCallback || requiredModules.util.noop;
5848		var ac = new global.google.maps.places.Autocomplete(inputElement, {
5849			types: ["geocode"]
5850		});
5851		global.google.maps.event.addListener(ac, "place_changed", function () {
5852			var place = ac.getPlace();
5853			if (place) {
5854				if (place.formatted_address) {
5855					var viewport = place.geometry.viewport;
5856					if (viewport) {
5857						var ne = viewport.getNorthEast();
5858						var sw = viewport.getSouthWest();
5859						effectiveChangeEventCallback({
5860							minLatitude: sw.lat(),
5861							maxLatitude: ne.lat(),
5862							leftLongitude: sw.lng(),
5863							rightLongitude: ne.lng()
5864						});
5865					} else {
5866						GoogleMapServices.geocodingService.getAddressBounds(place.formatted_address).then(effectiveChangeEventCallback);
5867					}
5868				} else {
5869					GoogleMapServices.geocodingService.getAddressBounds(place.name).then(effectiveChangeEventCallback);
5870				}
5871			}
5872		});
5873		$(inputElement).on("keypress", function (event) {
5874			if (event.which === 13) {
5875				event.preventDefault();
5876			}
5877		});
5878	};
5879
5880	var maxMapZoomLevel = 10;
5881	var singleMarkerMapZoomLevel = 10;
5882
5883	var ensureMarkerClustererApiReady = (function () {
5884		var markerClustererApiPromise;
5885		return function () {
5886			if (!markerClustererApiPromise) {
5887				markerClustererApiPromise = $.ajax({
5888					url: "/Scripts/lib/markerclusterer.min.js",
5889					dataType: "script",
5890					cache: true
5891				});
5892			}
5893			return markerClustererApiPromise;
5894		};
5895	})();
5896
5897	function Map(containerElement, options, providerOptions) {
5898		this.backingMap = new global.google.maps.Map(containerElement, _.extend(options ? {
5899			center: new global.google.maps.LatLng(options.latitude, options.longitude),
5900			zoom: options.zoom
5901		} : {}, providerOptions));
5902		this.markers = [];
5903		this.infoWindow = undefined;
5904		this.markerCluster = undefined;
5905		this.simpleMarkers = [];
5906		this.autoCompleteInputs = [];
5907	};
5908
5909	Map.prototype.getSpanBounds = function () {
5910		var bounds = this.backingMap.getBounds();
5911		if (bounds) {
5912			var sw = bounds.getSouthWest();
5913			var ne = bounds.getNorthEast();
5914			var span = bounds.toSpan();
5915			return sw && ne && span ? new requiredModules.util.GeographySpan(sw.lat(), ne.lat(), sw.lng(), span.lng()) : null;
5916		} else {
5917			return null;
5918		}
5919	};
5920
5921	Map.prototype.setCenterAndZoomForAllPoints = function (center, points, cancellationToken) {
5922		var self = this;
5923		var bounds;
5924		function predicate(p) {
5925			//return !self.backingMap.getBounds().contains(new global.google.maps.LatLng(p.latitude, p.longitude));
5926			var b = self.backingMap.getBounds();
5927			return b != null && !b.contains(new global.google.maps.LatLng(p.latitude, p.longitude));
5928		};
5929		if (center) {
5930			self.backingMap.panTo(new global.google.maps.LatLng(center.latitude, center.longitude));
5931		} else {
5932			self.backingMap.panTo(new global.google.maps.LatLng(points[0].latitude, points[0].longitude));
5933		}
5934		var zoom = maxMapZoomLevel;
5935		do {
5936			self.backingMap.setZoom(zoom);
5937			bounds = self.backingMap.getBounds();
5938			--zoom;
5939		} while (_.some(points, predicate));
5940		return requiredModules.util.getResolvedPromise();
5941	};
5942
5943	Map.prototype.getIdlePromise = function () {
5944		var deferred = $.Deferred();
5945		global.google.maps.event.addListenerOnce(this.backingMap, "idle", function () {
5946			deferred.resolve();
5947		});
5948		return deferred.promise();
5949	};
5950
5951	Map.prototype.listenToBoundsChange = function (callback) {
5952		return global.google.maps.event.addListener(this.backingMap, "bounds_changed", callback);
5953	};
5954
5955	Map.prototype.stopListeningToBoundsChange = function (listener) {
5956		global.google.maps.event.removeListener(listener);
5957	};
5958
5959	Map.prototype.getCenter = function () {
5960		var r = this.backingMap.getCenter();
5961		return r != null ? {
5962			latitude: r.lat(),
5963			longitude: r.lng()
5964		} : {
5965			latitude: 0,
5966			longitude: 0
5967		};
5968	};
5969
5970	Map.prototype.getZoomLevel = function () {
5971		return this.backingMap.getZoom();
5972	};
5973
5974	Map.prototype.setCenterAndZoomLevel = function (latitude, longitude, zoomLevel) {
5975		this.backingMap.setCenter(new global.google.maps.LatLng(latitude, longitude));
5976		if (zoomLevel != null) {
5977			this.backingMap.setZoom(zoomLevel);
5978		}
5979	};
5980
5981	Map.prototype.fitBounds = function (minLatitude, maxLatitude, leftLongitude, rightLongitude) {
5982		this.backingMap.fitBounds(new global.google.maps.LatLngBounds(new global.google.maps.LatLng(minLatitude, leftLongitude), new global.google.maps.LatLng(maxLatitude, rightLongitude)));
5983		return this.getIdlePromise();
5984	};
5985
5986	Map.prototype.putSimpleMarkerInCenter = function (iconUrl) {
5987		new global.google.maps.Marker({
5988			map: this.backingMap,
5989			position: this.backingMap.getCenter(),
5990			icon: iconUrl
5991		});
5992	};
5993
5994	function asUpdatingMapInfoWindow(object) {
5995		return _.isObject(object) && _.isFunction(object.startUpdate) ? object : null;
5996	}
5997
5998	function putClusteredMarkersOnMap(map, markers) {
5999		ensureMarkerClustererApiReady().then(function () {
6000			map.markerCluster = new MarkerClusterer(map.backingMap, map.markers, {
6001				maxZoom: 10,
6002				gridSize: 65,
6003				styles: [{
6004					url: "/Content/img/icon-cluster-25.png",
6005					height: 25,
6006					width: 25,
6007					textColor: "#ffffff",
6008					textSize: 12
6009				}, {
6010					url: "/Content/img/icon-cluster.png",
6011					height: 31,
6012					width: 31,
6013					textColor: "#ffffff",
6014					textSize: 12
6015				}, {
6016					url: "/Content/img/icon-cluster-37.png",
6017					height: 37,
6018					width: 37,
6019					textColor: "#ffffff",
6020					textSize: 12
6021				}]
6022			});
6023		}, function () {
6024			_.each(map.markers, function (marker) {
6025				marker.setMap(map.backingMap);
6026			});
6027		});
6028	}
6029
6030	function setMarkers(map, items, infoWindowContentCallback, isClustering, onMarkerClickCallback) {
6031		if (map.infoWindow) {
6032			map.infoWindow.close();
6033			map.infoWindow = undefined;
6034		}
6035		_.each(map.markers, function (marker) {
6036			marker.setMap(null);
6037		});
6038		if (map.markerCluster != null) {
6039			map.markerCluster.clearMarkers();
6040		}
6041
6042		map.markers = _.map(items, function (item) {
6043			var marker = new global.google.maps.Marker({
6044				position: new global.google.maps.LatLng(item.Latitude, item.Longitude),
6045				icon: item.IconUrl,
6046				map: isClustering ? null : map.backingMap
6047			});
6048			if (infoWindowContentCallback != null) {
6049				marker.addListener("click", function callee$3$0() {
6050					var callResult, uiw, infoWindow;
6051					return regeneratorRuntime.async(function callee$3$0$(context$4$0) {
6052						while (1) switch (context$4$0.prev = context$4$0.next) {
6053							case 0:
6054								onMarkerClickCallback && onMarkerClickCallback(item, marker);
6055								if (map.infoWindow) {
6056									map.infoWindow.close();
6057									map.infoWindow = undefined;
6058								}
6059								context$4$0.next = 4;
6060								return regeneratorRuntime.awrap(requiredModules.util.rejectNull(infoWindowContentCallback)(item));
6061
6062							case 4:
6063								callResult = context$4$0.sent;
6064								uiw = asUpdatingMapInfoWindow(callResult);
6065								infoWindow = new global.google.maps.InfoWindow({
6066									content: uiw ? uiw.initialContent : callResult
6067								});
6068
6069								infoWindow.addListener("closeclick", function () {
6070									map.infoWindow = undefined;
6071								});
6072								map.infoWindow = infoWindow;
6073								if (!uiw) {
6074									global.google.maps.event.trigger(map.backingMap, "resize");
6075								}
6076								infoWindow.open(map.backingMap, marker);
6077								if (uiw) {
6078									$.when(uiw.startUpdate(), requiredModules.util.createWaitPromise(100)).then(function (content) {
6079										infoWindow.close();
6080										var w = new global.google.maps.InfoWindow({
6081											content: content
6082										});
6083										w.addListener("closeclick", function () {
6084											map.infoWindow = undefined;
6085										});
6086										map.infoWindow = w;
6087										global.google.maps.event.trigger(map.backingMap, "resize");
6088										w.open(map.backingMap, marker);
6089									});
6090								}
6091
6092							case 12:
6093							case "end":
6094								return context$4$0.stop();
6095						}
6096					}, null, this);
6097				});
6098			}
6099			return marker;
6100		});
6101		if (isClustering) {
6102			putClusteredMarkersOnMap(map, map.markers);
6103		}
6104		return map.markers;
6105	};
6106
6107	function putSelectableItemsOnMap(map, items, selectedItem, unselectedIconUrl, selectedIconUrl, selectionChangeCallback, infoWindowContentCallback) {
6108		var itemsWithIcons = requiredModules.util.stripType(items);
6109		_.each(itemsWithIcons, function (item) {
6110			item.IconUrl = item === selectedItem ? selectedIconUrl : unselectedIconUrl;
6111		});
6112
6113		var selectedMarker;
6114		var markers = setMarkers(map, itemsWithIcons, infoWindowContentCallback, true, function (item, marker) {
6115			if (marker !== selectedMarker) {
6116				if (selectedMarker) {
6117					selectedMarker.setIcon(unselectedIconUrl);
6118				}
6119				selectedMarker = marker;
6120				selectedMarker.setIcon(selectedIconUrl);
6121				selectionChangeCallback(item);
6122			}
6123		});
6124		selectedMarker = _.find(markers, function (marker) {
6125			return marker.getIcon() === selectedIconUrl;
6126		});
6127	};
6128
6129	// TODO: implement own bounds computation.
6130	function getGoogleBounds(items, getCoordinates) {
6131		var firstCoordinates = getCoordinates(items[0]);
6132		var firstPosition = new global.google.maps.LatLng(firstCoordinates.latitude, firstCoordinates.longitude);
6133		var bounds = new global.google.maps.LatLngBounds(firstPosition);
6134		_.each(items, function (item) {
6135			var coords = getCoordinates(item);
6136			bounds = bounds.extend(new global.google.maps.LatLng(coords.latitude, coords.longitude));
6137		});
6138		return bounds;
6139	}
6140
6141	function getBounds(items, getCoordinates) {
6142		var googleBounds = getGoogleBounds(items, getCoordinates);
6143		var southWest = googleBounds.getSouthWest();
6144		var northEast = googleBounds.getNorthEast();
6145		return {
6146			southWest: { latitude: southWest.lat(), longitude: southWest.lng() },
6147			northEast: { latitude: northEast.lat(), longitude: northEast.lng() }
6148		};
6149	}
6150
6151	function makeMarkersFit(googleMap, markers) {
6152		if (markers.length > 0) {
6153			if (markers.length === 1) {
6154				googleMap.setCenter(markers[0].getPosition());
6155				googleMap.setZoom(singleMarkerMapZoomLevel);
6156			} else {
6157				googleMap.fitBounds(getGoogleBounds(markers, function (marker) {
6158					var pos = marker.getPosition();
6159					return { latitude: pos.lat(), longitude: pos.lng() };
6160				}));
6161			}
6162		}
6163	}
6164
6165	Map.prototype.addSimpleMarkers = function (items) {
6166		var map = this;
6167		items = _.filter(items, function (g) {
6168			return g.Latitude != null && g.Longitude != null;
6169		});
6170		_.each(map.simpleMarkers, function (marker) {
6171			marker.setMap(null);
6172		});
6173		map.simpleMarkers = [];
6174		_.each(items, function (item) {
6175			var m = item.Label ? new global.MarkerWithLabel({
6176				map: map.backingMap,
6177				position: new global.google.maps.LatLng(item.Latitude, item.Longitude),
6178				icon: item.IconUrl,
6179				labelContent: item.Label,
6180				labelAnchor: new global.google.maps.Point(3, 30),
6181				labelClass: "map-marker-label", // the CSS class for the label
6182				labelInBackground: false
6183			}) : new global.google.maps.Marker({
6184				map: map.backingMap,
6185				position: new global.google.maps.LatLng(item.Latitude, item.Longitude),
6186				icon: item.IconUrl
6187			});
6188			map.simpleMarkers.push(m);
6189		});
6190	};
6191
6192	Map.prototype.hideAutoCompleteInputsMarkers = function (options) {
6193		var selector = requiredModules.util.rejectNull(options).selector;
6194		var $selector = $(selector);
6195		_.each(this.autoCompleteInputs, function (inp) {
6196			if (inp && inp.marker) {
6197				if ($selector && inp.selector && inp.selector[0] === $selector[0]) {
6198					inp.marker.setMap(null);
6199				} else if (!$selector) inp.marker.setMap(null);
6200			};
6201		});
6202	};
6203
6204	Map.prototype.createAutocompleteInput = function (options) {
6205		var map = this;
6206		var $selector = options.selector;
6207		var icon = options.icon;
6208		if (!$selector.length) return;
6209
6210		var existedAc = _.filter(map.autoCompleteInputs, function (a) {
6211			return a.selector[0] === $selector[0];
6212		});
6213
6214		if (!existedAc.length) {
6215			var ac = new google.maps.places.Autocomplete($selector[0]);
6216			var autoCompleteInput = { selector: $selector, ac: ac };
6217			map.autoCompleteInputs.push(autoCompleteInput);
6218		}
6219
6220		$selector.on('focus', function (e) {
6221			if (map.handler) google.maps.event.removeListener(map.handler);
6222			map.handler = map.backingMap.addListener("click", function (e) {
6223				existedAc = _.filter(map.autoCompleteInputs, function (a) {
6224					return a.selector[0] === $selector[0];
6225				});
6226				if (existedAc.length) {
6227					var newPosition = e.latLng;
6228					var autoCompleteInput = existedAc[0];
6229					if (autoCompleteInput.marker) autoCompleteInput.marker.setMap(null);
6230					autoCompleteInput.marker = new global.google.maps.Marker({
6231						map: map.backingMap,
6232						position: newPosition,
6233						icon: icon
6234					});
6235					google.maps.event.removeListener(map.handler);
6236					GoogleMapServices.geocodingService.getFormattedAddress(newPosition.lat(), newPosition.lng()).then(function (result) {
6237						autoCompleteInput.selector.val(result.address);
6238					});
6239				}
6240			});
6241		});
6242	};
6243
6244	Map.prototype.setClusterMarkers = function (items, infoWindowContentCallback, onMarkerClickCallback) {
6245		setMarkers(this, items, infoWindowContentCallback, true, onMarkerClickCallback);
6246	};
6247
6248	Map.prototype.setMarkers = function (items, infoWindowContentCallback, onMarkerClickCallback) {
6249		setMarkers(this, items, infoWindowContentCallback, false, onMarkerClickCallback);
6250	};
6251
6252	Map.prototype.removeAutocompleteHandler = function () {
6253		if (this.handler) google.maps.event.removeListener(this.handler);
6254	};
6255
6256	Map.prototype.setMarkersAndMakeThemFit = function (items, infoWindowContentCallback, onMarkerClickCallback) {
6257		this.setMarkers(items, infoWindowContentCallback, onMarkerClickCallback);
6258		makeMarkersFit(this.backingMap, this.markers);
6259	};
6260
6261	Map.prototype.setClusterMarkersAndMakeThemFit = function (items, infoWindowContentCallback, onMarkerClickCallback) {
6262		this.setClusterMarkers(items, infoWindowContentCallback, onMarkerClickCallback);
6263		makeMarkersFit(this.backingMap, this.markers);
6264	};
6265
6266	Map.prototype.putSelectableItemsOnMap = function (items, selectedItem, unselectedIconUrl, selectedIconUrl, selectionChangeCallback, infoWindowContentCallback) {
6267		putSelectableItemsOnMap(this, items, selectedItem, unselectedIconUrl, selectedIconUrl, selectionChangeCallback, infoWindowContentCallback);
6268	};
6269
6270	Map.prototype.getMapServiceProvider = function () {
6271		return GoogleMapServices;
6272	};
6273
6274	Map.prototype.putUserPositionMarkerOnMap = function (latitude, longitude, iconUrl) {
6275		new global.google.maps.Marker({
6276			//anchorPoint
6277			clickable: false,
6278			//cursor
6279			icon: iconUrl,
6280			map: this.backingMap,
6281			position: new global.google.maps.LatLng(latitude, longitude)
6282		});
6283	};
6284
6285	Map.prototype.refresh = function () {
6286		global.google.maps.event.trigger(this.backingMap, "resize");
6287	};
6288
6289	GoogleMapServices.createMap = function (containerElement, options) {
6290		return new Map(containerElement, options);
6291	};
6292
6293	GoogleMapServices.createPositionedMap = function (containerElement, position, providerOptions) {
6294		return new Map(containerElement, position ? { latitude: position.coordinates.latitude, longitude: position.coordinates.longitude, zoom: position.zoomLevel } : null, providerOptions);
6295	};
6296
6297	GoogleMapServices.getBounds = getBounds;
6298}, this);
6299// because geocoding sometimes can't find location for such addresses
6300/* any arguments */ /* any arguments */;
6301// @hash v3-4B82EE7AF459BD08720C7032CC254356B2D1B6BB
6302// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden.
6303// Version: 2.1.1-dev-20151124-1300 (build 563ed55)
6304// Generated at:
6305///////////////////////////////////////////////////////////////////////////////
6306
6307
6308LukoilApp.module("YandexMapServices", function (YandexMapServices, LukoilApp, Backbone, Marionette, $, _, global) {
6309	"use strict";
6310
6311	var _this = this;
6312
6313	var requiredModules = {
6314		googleMapServices: LukoilApp.module("GoogleMapServices"),
6315		util: LukoilApp.module("Util")
6316	};
6317
6318	// ----------- CookieStorage -----------
6319	var CookieStorage = function CookieStorage(config) {
6320		this.config = config || {};
6321	};
6322	CookieStorage.prototype.save = function (keyInStorage, model) {
6323		$.lukoilSaveCookie(keyInStorage, JSON.stringify(model), this.config);
6324	};
6325	CookieStorage.prototype.getValue = function (keyInStorage) {
6326		return $.lukoilGetCookie(keyInStorage);
6327	};
6328
6329	var settings = {
6330		selectors: {},
6331		geolocationInfoCookiesConfig: {
6332			expires: 100,
6333			path: '/'
6334		},
6335		cookiesConfig: {
6336			path: '/'
6337		},
6338		cookiesConfigForever: {
6339			path: '/',
6340			expires: 365 * 100
6341		},
6342		countryCodeCookieKey: "LukCountryCode",
6343		geoObjectIdCookieKey: "LukGeoObjectId",
6344		locationCookieKey: "LukLocation",
6345		locationSelectCookieKey: "LukLocationSelect",
6346		verifyCountryCodeUrl: "/api/userLocation/VerifyCountryCodeOrGetDefault",
6347		countrySelector: ".global-nav .dropdown_country"
6348	};
6349
6350	var singleMarkerMapZoomLevel = 10;
6351
6352	var minPauseBetweenRequestsInMilliseconds = 1000;
6353
6354	var throttler = new requiredModules.util.Throttler(minPauseBetweenRequestsInMilliseconds);
6355
6356	function LatLng(lat, lng) {
6357		this.lat = lat;
6358		this.lng = lng;
6359	}
6360
6361	function LatLngBounds(southwest, northeast) {
6362		this.southwest = southwest;
6363		this.northeast = northeast;
6364
6365		this.extend = function (newPoint) {
6366			var minLat = this.southwest.lat;
6367			var maxLat = this.southwest.lat;
6368			var minLng = this.southwest.lng;
6369			var maxLng = this.southwest.lng;
6370
6371			if (this.northeast) {
6372				if (this.northeast.lat < minLat) {
6373					minLat = this.northeast.lat;
6374				}
6375
6376				if (this.northeast.lat > maxLat) {
6377					maxLat = this.northeast.lat;
6378				}
6379
6380				if (this.northeast.lng < minLng) {
6381					minLng = this.northeast.lng;
6382				}
6383
6384				if (this.northeast.lng > maxLng) {
6385					maxLng = this.northeast.lng;
6386				}
6387			}
6388
6389			if (newPoint) {
6390				if (newPoint.lat < minLat) {
6391					minLat = newPoint.lat;
6392				}
6393
6394				if (newPoint.lat > maxLat) {
6395					maxLat = newPoint.lat;
6396				}
6397
6398				if (newPoint.lng < minLng) {
6399					minLng = newPoint.lng;
6400				}
6401
6402				if (newPoint.lng > maxLng) {
6403					maxLng = newPoint.lng;
6404				}
6405			}
6406
6407			return new LatLngBounds(new LatLng(minLat, minLng), new LatLng(maxLat, maxLng));
6408		};
6409
6410		this.getSouthWest = function () {
6411			return this.southwest;
6412		};
6413
6414		this.getNorthEast = function () {
6415			if (this.northeast) return this.northeast;
6416
6417			return this.southwest;
6418		};
6419	}
6420
6421	var yandexMapsScriptApiReadyDeferred;
6422	var markerLabelLayout;
6423	var apiLanguageCode;
6424
6425	function GeocodingService() {
6426		this.geocoder = global.ymaps;
6427		return this;
6428	};
6429
6430	GeocodingService.prototype.wrapGeocoderCallInPromise = function (args) {
6431		var self = this;
6432		var deferred = $.Deferred();
6433		self.geocoder.geocode(args).then(function (results) {
6434			deferred.resolve(results);
6435		}).fail(function (err) {
6436			return requiredModules.util.createRejectedPromise("Geocoding failed: " + err);
6437		});
6438		return deferred.promise();
6439	};
6440
6441	GeocodingService.prototype.getLocationOrAddress = function (latitudeOrAddress, longitude) {
6442		var args = longitude ? [latitudeOrAddress, longitude] : latitudeOrAddress;
6443		return this.wrapGeocoderCallInPromise(args).then(function (results) {
6444			var nearest = results.geoObjects.get(0);
6445			if (nearest) {
6446				var address = nearest.properties.get('text');
6447				var location = { latitude: nearest.geometry.getCoordinates()[0], longitude: nearest.geometry.getCoordinates()[1] };
6448				var bounds;
6449				try {
6450					bounds = nearest.properties.get('boundedBy');
6451				} catch (e) {}
6452				return { address: address, location: location, routingLocation: location, bounds: boun
6452ds };
6453			} else {
6454				return requiredModules.util.createRejectedPromise("Failed to get address for the specified location.");
6455			}
6456		});
6457	};
6458
6459	GeocodingService.prototype.getFormattedAddress = function (latitude, longitude) {
6460		return this.getLocationOrAddress(latitude, longitude);
6461	};
6462
6463	GeocodingService.prototype.getLocation = function (address) {
6464		return this.getLocationOrAddress(address);
6465	};
6466
6467	YandexMapServices.onApiLoad = function () {
6468		YandexMapServices.geocodingService = new GeocodingService();
6469		markerLabelLayout = global.ymaps.templateLayoutFactory.createClass("<div class='map-marker-label'>{{properties.iconContent}}</div>");
6470		yandexMapsScriptApiReadyDeferred.resolve();
6471	};
6472
6473	YandexMapServices.apiLoadFailureHandler = function () {};
6474
6475	YandexMapServices.ensureMapApiIsReady = function (languageCode) {
6476		if (!yandexMapsScriptApiReadyDeferred) {
6477			yandexMapsScriptApiReadyDeferred = $.Deferred();
6478			apiLanguageCode = languageCode;
6479			var locale = !languageCode || languageCode.toUpperCase() === "RU" ? "ru_RU" : "en_US";
6480			var url = "https://api-maps.yandex.ru/2.1/?lang=" + locale + (window.GlobalSettings.YandexApiKey != '' ? "&apikey=" + window.GlobalSettings.YandexApiKey : '') + (window.GlobalSettings.YandexSuggestApiKey != '' ? "&suggest_apikey=" + window.GlobalSettings.YandexSuggestApiKey : '') + "&load=" // available packages with modules: https://tech.yandex.ru/maps/doc/jsapi/2.0/ref/reference/packages-docpage/
6481			//+ "package.full"
6482			 + "Map" + ",Clusterer" + ",templateLayoutFactory" + ",GeoObjectCollection" + ",geolocation" + ",geoQuery" + ",coordSystem.geo" // used in routing
6483			 + ",route" // package.route
6484			 + ",geocode" // package.route
6485			 + ",SuggestView" // package.route
6486			 + ",Placemark" // package.route
6487			 + ",geoObject.addon.balloon" + ",layout.ImageWithContent" + ",collection.Item" + ",util.augment" + ",control.ZoomControl" // package.controls
6488			 + ",regions" + ",GeoQueryResult" + ",Polygon" + "&onload=LukoilApp.YandexMapServices.onApiLoad";
6489			$.ajax({
6490				url: url,
6491				dataType: "script",
6492				cache: true
6493			}).fail(function () {
6494				yandexMapsScriptApiReadyDeferred.reject("Yandex Maps script failed to load.");
6495			});
6496			yandexMapsScriptApiReadyDeferred.fail(function (message) {
6497				requiredModules.util.logError(message);
6498				YandexMapServices.apiLoadFailureHandler();
6499			});
6500		}
6501		return new requiredModules.util.JQueryPromiseWrapper(yandexMapsScriptApiReadyDeferred.promise());
6502	};
6503
6504	var GetYandexCacheOptions = {
6505		enableHighAccuracy: true,
6506		timeout: 5000,
6507		maximumAge: 0
6508	};
6509
6510	YandexMapServices.getCurrentLocation = (function () {
6511		var deferred;
6512		var crd;
6513		return function (provider) {
6514			if (!deferred) {
6515				deferred = $.Deferred();
6516				var $countryContainer = $(settings.countrySelector);
6517				var cookieStorage = new CookieStorage(settings.geolocationInfoCookiesConfig);
6518				var geolocationInfo = cookieStorage.getValue(settings.locationCookieKey);
6519				if ($countryContainer.length) {
6520					if (geolocationInfo == null || geolocationInfo == '') {
6521						navigator.geolocation.getCurrentPosition(function (pos) {
6522							crd = pos.coords;
6523							$.ajax("/api/cartography/GetYandexCache", {
6524								async: true,
6525								cache: true,
6526								ifModified: true,
6527								data: { latitudes: crd.latitude, longitude: crd.longitude },
6528								dataType: "json",
6529								method: "GET"
6530							}).then(function (result) {
6531								if (result == '') {
6532									requiredModules.YandexMapServices.ensureMapApiIsReady(languageCode).then(function () {
6533										requiredModules.YandexMapServices.getCurrentLocation('auto').then(function (location) {
6534											var geolocationInfo = location.geolocationInfo;
6535											$.ajax("/api/cartography/AddYandexCache", {
6536												async: true,
6537												cache: true,
6538												ifModified: true,
6539												data: { latitudes: crd.latitude, longitude: crd.longitude, value: JSON.stringify(geolocationInfo), brows: window.navigator.userAgent },
6540												dataType: "json",
6541												method: "Post"
6542											}).then(function (result) {
6543												console.log("Данные взяты из яндекса, записаны в БД и в куки");
6544												cookieStorage.save(settings.locationCookieKey, geolocationInfo);
6545											});
6546										});
6547									});
6548								} else {
6549									console.log("Данные взяты из БД и записаны в куки");
6550									cookieStorage.save(settings.locationCookieKey, JSON.parse(result));
6551								}
6552							});
6553						}, function (err) {
6554							requiredModules.YandexMapServices.ensureMapApiIsReady(languageCode).then(function () {
6555								requiredModules.YandexMapServices.getCurrentLocation('auto').then(function (location) {
6556									var geolocationInfo = location.geolocationInfo;
6557									cookieStorage.save(settings.locationCookieKey, geolocationInfo);
6558								});
6559							});
6560						}, GetYandexCacheOptions);
6561					}
6562				} else {
6563					if (languageCode != null && languageCode != '') {
6564						if (geolocationInfo == null || geolocationInfo == '') {
6565							navigator.geolocation.getCurrentPosition(function (pos) {
6566								crd = pos.coords;
6567								$.ajax("/api/cartography/GetYandexCache", {
6568									async: true,
6569									cache: true,
6570									ifModified: true,
6571									data: { latitudes: crd.latitude, longitude: crd.longitude },
6572									dataType: "json",
6573									method: "GET"
6574								}).then(function (result) {
6575									if (result == '') {
6576										requiredModules.YandexMapServices.ensureMapApiIsReady(languageCode).then(requiredModules.YandexMapServices.getCurrentLocation).then(function (result) {
6577											if (result && result.geolocationInfo && result.geolocationInfo.countryCode) {
6578												$.ajax("/api/cartography/AddYandexCache", {
6579													async: true,
6580													cache: true,
6581													ifModified: true,
6582													data: { latitudes: crd.latitude, longitude: crd.longitude, value: JSON.stringify(result.geolocationInfo), brows: window.navigator.userAgent },
6583													dataType: "json",
6584													method: "Post"
6585												}).then(function (result) {
6586													geolocationInfo = result.geolocationInfo;
6587												});
6588											}
6589										});
6590									}
6591								});
6592							}, function (err) {
6593								requiredModules.YandexMapServices.ensureMapApiIsReady(languageCode).then(requiredModules.YandexMapServices.getCurrentLocation).then(function (result) {
6594									if (result && result.geolocationInfo && result.geolocationInfo.countryCode) {
6595										geolocationInfo = result.geolocationInfo;
6596									}
6597								});
6598							}, GetYandexCacheOptions);
6599						}
6600					}
6601				}
6602				if (geolocationInfo == null || geolocationInfo == '') {
6603					var yandexPromise = global.ymaps.geolocation.get({
6604						//provider: 'yandex', // provider: 'auto' returns an error with message "Not found"
6605						provider: provider != null && provider !== '' ? provider : 'yandex',
6606						//mapStateAutoApply: true
6607						autoReverseGeocode: true,
6608						timeout: 10000
6609					});
6610					yandexPromise.then(function (result) {
6611						var bounds, countryName, countryCode, location, geolocationInfo, region, city;
6612						try {
6613							location = {
6614								lat: result.geoObjects.position[0],
6615								lng: result.geoObjects.position[1]
6616							};
6617							bounds = result.geoObjects.get(0).properties.get('boundedBy');
6618							var addressDetails = result.geoObjects.get(0).properties.get("metaDataProperty").GeocoderMetaData.AddressDetails;
6619							if (addressDetails && addressDetails.Country) {
6620								countryName = addressDetails.Country.CountryName;
6621								countryCode = addressDetails.Country.CountryNameCode;
6622								if (addressDetails.Country.AdministrativeArea) {
6623									region = addressDetails.Country.AdministrativeArea.AdministrativeAreaName;
6624									if (addressDetails.Country.AdministrativeArea.SubAdministrativeArea && addressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality) {
6625										city = addressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
6626									}
6627								}
6628							}
6629							geolocationInfo = {
6630								countryName: countryName,
6631								countryCode: countryCode,
6632								region: region,
6633								city: city
6634							};
6635						} catch (e) {}
6636
6637						if (location) {
6638							deferred.resolve({
6639								isLocationInRussia: countryName === "Россия" || countryName === "Russia" || countryCode != null && countryCode.toUpperCase() === "RU",
6640								location: location,
6641								bounds: bounds,
6642								geolocationInfo: geolocationInfo
6643							});
6644						} else {
6645							deferred.reject("Failed to determine the user's location.");
6646						}
6647					});
6648					yandexPromise.fail(function (errorMessage) {
6649						deferred.reject(errorMessage);
6650					});
6651					return deferred.promise();
6652				} else {
6653					console.log("данные взяты из кукки");
6654					fetchLocation();
6655				}
6656			}
6657		};
6658	})();
6659
6660	var fetchLocation = function fetchLocation() {
6661		var position, location, geoObj, bounds;
6662		return regeneratorRuntime.async(function fetchLocation$(context$2$0) {
6663			while (1) switch (context$2$0.prev = context$2$0.next) {
6664				case 0:
6665					context$2$0.prev = 0;
6666					context$2$0.next = 3;
6667					return regeneratorRuntime.awrap(getCoordinates());
6668
6669				case 3:
6670					position = context$2$0.sent;
6671					location = {
6672						lat: position.latitude,
6673						lng: position.longitude
6674					};
6675					geoObj = JSON.parse(geolocationInfo);
6676
6677					console.log(geoObj);
6678					deferred.resolve({
6679						isLocationInRussia: geoObj.countryName === "Россия" || geoObj.countryName === "Russia" || geoObj.countryCode != null && geoObj.countryCode.toUpperCase() === "RU",
6680						location: location,
6681						bounds: bounds,
6682						geolocationInfo: geoObj
6683					});
6684					return context$2$0.abrupt("return", deferred.promise());
6685
6686				case 11:
6687					context$2$0.prev = 11;
6688					context$2$0.t0 = context$2$0["catch"](0);
6689
6690					console.error("Error getting location:", context$2$0.t0.message);
6691
6692				case 14:
6693				case "end":
6694					return context$2$0.stop();
6695			}
6696		}, null, _this, [[0, 11]]);
6697	};
6698
6699	var getCoordinates = function getCoordinates() {
6700		return new Promise(function (resolve, reject) {
6701			if (!navigator.geolocation) {
6702				reject(new Error("Geolocation is not supported by your browser."));
6703			} else {
6704				navigator.geolocation.getCurrentPosition(resolve, reject, GetYandexCacheOptions);
6705			}
6706		});
6707	};
6708
6709	YandexMapServices.createAddressSearchInput = function (inputElement, changeEventCallback, changeEventCallbackIfNotResolving) {
6710		var effectiveChangeEventCallbackIfNotResolving = changeEventCallbackIfNotResolving || requiredModules.util.noop;
6711		var suggestView = new global.ymaps.SuggestView(inputElement);
6712		suggestView.events.add("select", function (event) {
6713			effectiveChangeEventCallbackIfNotResolving(event.get("item").value);
6714		});
6715		var $input = $(inputElement);
6716		$input.on("keypress", function (event) {
6717			if (event.which === 13) {
6718				event.preventDefault();
6719				effectiveChangeEventCallbackIfNotResolving(requiredModules.util.stripType($input.val()) || "");
6720			}
6721		});
6722	};
6723
6724	var createSimpleMarker = function createSimpleMarker(position, icon, label, shouldOpenEmptyBalloon) {
6725		var mo = {};
6726		if (icon) {
6727			mo = requiredModules.util.stripType({
6728				iconImageHref: icon,
6729				iconLayout: label ? "default#imageWithContent" : 'default#image',
6730				iconImageSize: icon.indexOf('-attention') >= 0 ? [40, 47] : [31, 42],
6731				iconImageOffset: [-16, -40]
6732			});
6733			if (label) {
6734				mo.iconContentLayout = markerLabelLayout;
6735				mo.iconContentOffset = [6, 8];
6736				mo.iconContentSize = [20, 10];
6737			}
6738		} else {
6739			mo.preset = 'islands#redIcon';
6740		}
6741		mo.openEmptyBalloon = !!shouldOpenEmptyBalloon;
6742		var properties = label ? { iconContent: label } : {};
6743		return new global.ymaps.Placemark(position, properties, mo);
6744	};
6745
6746	function Map(containerElement, options, yandexMapOptions) {
6747		this.backingMap = new global.ymaps.Map(containerElement, _.extend(options ? {
6748			center: [options.latitude, options.longitude],
6749			zoom: options.zoom
6750		} : {}, yandexMapOptions));
6751		this.simpleMarkers = new global.ymaps.GeoObjectCollection();
6752		this.someMarkers = new global.ymaps.GeoObjectCollection();
6753		this.backingMap.geoObjects.add(this.simpleMarkers);
6754		this.backingMap.geoObjects.add(this.someMarkers);
6755		this.autoCompleteInputs = [];
6756		this.markers = new global.ymaps.GeoObjectCollection();
6757		this.backingMap.geoObjects.add(this.markers);
6758
6759		this.infoWindow = undefined;
6760
6761		var clusterIcons = [{
6762			href: "/Content/img/icon-cluster.png",
6763			size: [25, 25],
6764			offset: [0, 0]
6765		}, {
6766			href: "/Content/img/icon-cluster.png",
6767			size: [31, 31],
6768			offset: [0, 0]
6769		}, {
6770			href: "/Content/img/icon-cluster.png",
6771			size: [37, 37],
6772			offset: [0, 0]
6773		}];
6774		var whiteFontColorIconLayout = global.ymaps.templateLayoutFactory.createClass('<div style="color: #FFFFFF;">$[properties.geoObjects.length]</div>');
6775		this.markerCluster = new global.ymaps.Clusterer({
6776			clusterIcons: clusterIcons,
6777			clusterIconContentLayout: whiteFontColorIconLayout,
6778			gridSize: 90,
6779			//viewportMargin: 16,
6780			//zoomMargin: 30,
6781			maxZoom: 17,
6782			clusterNumbers: [9, 99],
6783			groupByCoordinates: false,
6784			clusterDisableClickZoom: false,
6785			clusterHideIconOnBalloonOpen: false,
6786			geoObjectHideIconOnBalloonOpen: false
6787		});
6788		this.backingMap.geoObjects.add(this.markerCluster);
6789	};
6790
6791	Map.prototype.getZoomLevel = function () {
6792		return this.backingMap.getZoom();
6793	};
6794
6795	Map.prototype.getCenter = function () {
6796		var ac = this.backingMap.getCenter();
6797		return {
6798			latitude: ac[0],
6799			longitude: ac[1]
6800		};
6801	};
6802
6803	function getSpanFromYandexBounds(bounds) {
6804		var delta = 1.0 / (1 << 10);
6805		if (Math.abs(bounds[0][1] - bounds[1][1]) < delta) {
6806			return new requiredModules.util.GeographySpan(bounds[0][0], bounds[1][0], -180, 360);
6807		} else {
6808			var l = requiredModules.util.normalizeLongitude(bounds[0][1]);
6809			var d = bounds[1][1] - bounds[0][1];
6810			var s = d >= 360 ? 360 : requiredModules.util.mod(d, 360);
6811			return new requiredModules.util.GeographySpan(bounds[0][0], bounds[1][0], l, s);
6812		}
6813	}
6814
6815	function getPromiseFromYandexPromise(yandexPromise) {
6816		var deferred = $.Deferred();
6817		yandexPromise.then(function () {
6818			deferred.resolve.apply(deferred, arguments);
6819		}, function () {
6820			deferred.reject.apply(deferred, arguments);
6821		});
6822		return deferred.promise();
6823	};
6824
6825	Map.prototype.getSpanBounds = function () {
6826		var ac = this.backingMap.getBounds();
6827		return ac == null ? null : getSpanFromYandexBounds(ac);
6828	};
6829
6830	Map.prototype.setCenterAndZoomLevel = function (latitude, longitude, zoomLevel) {
6831		this.backingMap.setCenter([latitude, longitude], zoomLevel);
6832	};
6833
6834	Map.prototype.fitBounds = function (minLatitude, maxLatitude, leftLongitude, rightLongitude) {
6835		return getPromiseFromYandexPromise(this.backingMap.setBounds([[minLatitude, leftLongitude], [maxLatitude, rightLongitude]]));
6836	};
6837
6838	Map.prototype.getIdlePromise = function () {
6839		var deferred = $.Deferred();
6840		this.backingMap.events.once("actionend", function () {
6841			deferred.resolve();
6842		});
6843		return deferred.promise();
6844	};
6845
6846	Map.prototype.listenToBoundsChange = function (callback) {
6847		return this.backingMap.events.add("boundschange", callback);
6848	};
6849
6850	Map.prototype.stopListeningToBoundsChange = function (listener) {
6851		this.backingMap.events.remove("boundschange", listener);
6852	};
6853
6854	var maxMapZoomLevel = 11;
6855
6856	Map.prototype.setCenterAndZoomForAllPoints = function (center, points, cancellationToken) {
6857		var self = this;
6858		var map = self.backingMap;
6859		var deferred = $.Deferred();
6860		var bounds;
6861		var mapCenter;
6862		var zoom = maxMapZoomLevel + 1;
6863
6864		var ct = cancellationToken || new requiredModules.util.CancellationToken();
6865
6866		function predicate(p) {
6867			return !bounds.contains(p);
6868		};
6869		function areSomePointsOutOfViewport() {
6870			bounds = requiredModules.util.rejectNull(self.getSpanBounds());
6871			return _.some(points, predicate);
6872		}
6873		function resolve() {
6874			deferred.resolve();
6875		}
6876		function f() {
6877			if (ct.isCanceled()) {
6878				deferred.reject();
6879				return;
6880			}
6881			--zoom;
6882			if (zoom <= 0) {
6883				resolve();
6884			} else {
6885				var c = map.getCenter();
6886				if (c[0] === mapCenter.latitude && c[1] === mapCenter.longitude && (zoom === max
6886MapZoomLevel || areSomePointsOutOfViewport())) {
6887					map.setZoom(zoom).then(f, resolve);
6888				} else {
6889					resolve();
6890				}
6891			}
6892		}
6893		map.setCenter([center.latitude, center.longitude]).then(function () {
6894			mapCenter = self.getCenter();
6895			f();
6896		}, resolve);
6897		return deferred.promise();
6898	};
6899
6900	Map.prototype.createAutocompleteInput = function (options) {
6901		var map = this;
6902		var $selector = options.selector;
6903		var icon = options.icon;
6904		if (!$selector.length) return;
6905
6906		var existedAc = _.filter(map.autoCompleteInputs, function (a) {
6907			return a.selector[0] === $selector[0];
6908		});
6909
6910		if (!existedAc.length) {
6911			var ac = new global.ymaps.SuggestView($selector[0]);
6912			map.autoCompleteInputs.push({ selector: $selector, ac: ac });
6913		}
6914
6915		$selector.on('focus', function () {
6916			if (map.handler) map.handler.removeAll();
6917
6918			map.handler = map.backingMap.events.group().add('click', function (e) {
6919
6920				existedAc = _.filter(map.autoCompleteInputs, function (a) {
6921					return a.selector[0] === $selector[0];
6922				});
6923				if (existedAc.length) {
6924					var newPosition = e.get('coords');
6925					var autoCompleteInput = existedAc[0];
6926					if (autoCompleteInput.marker) map.someMarkers.remove(autoCompleteInput.marker);
6927
6928					autoCompleteInput.marker = createSimpleMarker(newPosition, icon);
6929					map.someMarkers.add(autoCompleteInput.marker);
6930					map.handler.removeAll();
6931
6932					global.ymaps.geocode(newPosition).then(function (res) {
6933						var nearest = res.geoObjects.get(0);
6934						var name = nearest.properties.get('text');
6935						$selector.val(name);
6936						autoCompleteInput.ac.destroy();
6937						autoCompleteInput.ac = new global.ymaps.SuggestView($selector[0]);
6938					});
6939				}
6940			});
6941		});
6942	};
6943
6944	Map.prototype.removeAutocompleteHandler = function () {
6945		if (this.handler) this.handler.removeAll();
6946	};
6947
6948	Map.prototype.hideAutoCompleteInputsMarkers = function (options) {
6949		var selector = requiredModules.util.rejectNull(options).selector;
6950		var $selector = $(selector);
6951		var autoCompleteInput = _.filter(this.autoCompleteInputs, function (ac) {
6952			return ac.selector[0] === $selector[0];
6953		});
6954		if (autoCompleteInput.length && autoCompleteInput[0].marker && autoCompleteInput[0].marker.getMap()) {
6955			this.someMarkers.remove(autoCompleteInput[0].marker);
6956			autoCompleteInput[0].marker = null;
6957		}
6958	};
6959
6960	Map.prototype.addSimpleMarkers = function (items) {
6961		var map = this;
6962		items = _.filter(items, function (g) {
6963			return g.Latitude != null && g.Longitude != null;
6964		});
6965		this.simpleMarkers.removeAll();
6966		_.each(items, function (item) {
6967			var m = createSimpleMarker([item.Latitude, item.Longitude], item.IconUrl, item.Label);
6968			map.simpleMarkers.add(m);
6969		});
6970	};
6971
6972	//Map.prototype.renderRoute = function (directionResponse) {
6973	//	if (this.route)
6974	//		this.backingMap.geoObjects.remove(this.route);
6975	//	directionResponse.getWayPoints().removeAll();
6976	//	this.route = directionResponse;
6977	//	this.backingMap.geoObjects.add(this.route);
6978	//	_.each(this.autoCompleteInputs, function(ac) {
6979	//		if (ac.marker) ac.marker = undefined;
6980	//	});
6981	//};
6982
6983	Map.prototype.getSuggestViewLocation = function ($elem) {
6984		var sv = _.filter(this.autoCompleteInputs, function (a) {
6985			return a.selector[0] === $elem[0];
6986		});
6987		return sv.length ? sv[0].ac.state.get('request') : undefined;
6988	};
6989
6990	// TODO: factor out
6991	function asUpdatingMapInfoWindow(object) {
6992		return _.isObject(object) && _.isFunction(object.startUpdate) ? object : null;
6993	}
6994
6995	function setMarkers(map, items, isClustering, infoWindowContentElementCallback, onMarkerClickCallback) {
6996		map.backingMap.geoObjects.remove(map.markers);
6997		map.markerCluster.removeAll();
6998		map.markers.removeAll();
6999		var thismarkers = map.markers;
7000		_.each(items, function (item) {
7001			var m = createSimpleMarker([item.Latitude, item.Longitude], item.IconUrl, null, true);
7002			if (infoWindowContentElementCallback) {
7003				m.events.add("balloonopen", function callee$3$0(event) {
7004					var callResult, uiw;
7005					return regeneratorRuntime.async(function callee$3$0$(context$4$0) {
7006						while (1) switch (context$4$0.prev = context$4$0.next) {
7007							case 0:
7008								onMarkerClickCallback && onMarkerClickCallback();
7009								context$4$0.next = 3;
7010								return regeneratorRuntime.awrap(requiredModules.util.rejectNull(infoWindowContentElementCallback)(item));
7011
7012							case 3:
7013								callResult = context$4$0.sent;
7014								uiw = asUpdatingMapInfoWindow(callResult);
7015
7016								if (uiw) {
7017									m.properties.set("balloonContent", uiw.initialContent);
7018									uiw.startUpdate().then(function (content) {
7019										m.properties.set("balloonContent", content);
7020									});
7021								} else {
7022									m.properties.set("balloonContent", callResult);
7023								}
7024
7025							case 6:
7026							case "end":
7027								return context$4$0.stop();
7028						}
7029					}, null, this);
7030				});
7031			}
7032			thismarkers.add(m);
7033		});
7034		if (isClustering) {
7035			var data = [];
7036			thismarkers.each(function (m) {
7037				data.push(m);
7038			});
7039			map.markerCluster.add(data);
7040		} else {
7041			map.backingMap.geoObjects.add(map.markers);
7042		}
7043	}
7044
7045	Map.prototype.getYandexBounds = function (items, getCoordinates) {
7046		var firstCoordinates = getCoordinates(items[0]);
7047		var firstPosition = new LatLng(firstCoordinates.latitude, firstCoordinates.longitude);
7048		var bounds = new LatLngBounds(firstPosition);
7049		_.each(items, function (item) {
7050			var coords = getCoordinates(item);
7051			bounds = bounds.extend(new LatLng(coords.latitude, coords.longitude));
7052		});
7053		return bounds;
7054	};
7055
7056	Map.prototype.getBounds = function (items, getCoordinates) {
7057		var yandexBounds = this.getYandexBounds(items, getCoordinates);
7058		var southWest = yandexBounds.getSouthWest();
7059		var northEast = yandexBounds.getNorthEast();
7060		return {
7061			southWest: { latitude: southWest.lat, longitude: southWest.lng },
7062			northEast: { latitude: northEast.lat, longitude: northEast.lng }
7063		};
7064	};
7065
7066	function getMostSpecificGeocodingResult(geocodingResults) {
7067		return _.max(geocodingResults, function (item) {
7068			return item.address_components.length;
7069		});
7070	};
7071
7072	GeocodingService.prototype.getAddressBounds = function (address) {
7073		var self = this;
7074		if (!address || !requiredModules.util.trimString(address)) {
7075			return requiredModules.util.createRejectedPromise();
7076		}
7077		return this.getLocation(address).then(function (results, status) {
7078			if (results != null) {
7079				return {
7080					minLatitude: results.bounds[0][0],
7081					maxLatitude: results.bounds[1][0],
7082					leftLongitude: results.bounds[0][1],
7083					rightLongitude: results.bounds[1][1]
7084				};
7085			} else {
7086				return requiredModules.util.createRejectedPromise();
7087			}
7088		});
7089	};
7090
7091	Map.prototype.makeObjectsFit = function (yandexMap, items) {
7092		var self = this;
7093		if (items.length > 0) {
7094			if (items.length === 1) {
7095				yandexMap.setCenter([items[0].Latitude, items[0].Longitude], singleMarkerMapZoomLevel);
7096			} else {
7097				// TODO: implement own bounds computation and don't require Google Maps here.
7098				/*requiredModules.googleMapServices.*/YandexMapServices.ensureMapApiIsReady(apiLanguageCode).then(function () {
7099					var bounds = /*requiredModules.googleMapServices.*/self.getBounds(items, function (item) {
7100						return { latitude: item.Latitude, longitude: item.Longitude };
7101					});
7102					yandexMap.setBounds([[bounds.southWest.latitude, bounds.southWest.longitude], [bounds.northEast.latitude, bounds.northEast.longitude]]);
7103				});
7104			}
7105		}
7106	};
7107
7108	Map.prototype.setClusterMarkers = function (items, infoWindowContentElementCallback, onMarkerClickCallback) {
7109		setMarkers(this, items, true, infoWindowContentElementCallback, onMarkerClickCallback);
7110	};
7111
7112	Map.prototype.setMarkers = function (items, infoWindowContentElementCallback, onMarkerClickCallback) {
7113		setMarkers(this, items, false, infoWindowContentElementCallback, onMarkerClickCallback);
7114	};
7115
7116	Map.prototype.setMarkersAndMakeThemFit = function (items, infoWindowContentCallback, onMarkerClickCallback) {
7117		this.setMarkers(items, infoWindowContentCallback, onMarkerClickCallback);
7118		this.makeObjectsFit(this.backingMap, items);
7119	};
7120
7121	Map.prototype.setClusterMarkersAndMakeThemFit = function (items, infoWindowContentCallback, onMarkerClickCallback) {
7122		this.setClusterMarkers(items, infoWindowContentCallback, onMarkerClickCallback);
7123		this.makeObjectsFit(this.backingMap, items);
7124	};
7125
7126	Map.prototype.getMapServiceProvider = function () {
7127		return YandexMapServices;
7128	};
7129
7130	Map.prototype.putUserPositionMarkerOnMap = function (latitude, longitude, iconUrl) {
7131		this.backingMap.geoObjects.add(new global.ymaps.Placemark([latitude, longitude], {}, {
7132			iconLayout: "default#image",
7133			iconImageHref: iconUrl,
7134			iconImageOffset: [-19, -40]
7135		}));
7136	};
7137
7138	Map.prototype.putSimpleMarkerInCenter = function (iconUrl) {
7139		this.simpleMarkers.add(createSimpleMarker(this.backingMap.getCenter(), iconUrl));
7140	};
7141
7142	Map.prototype.refresh = function () {
7143		this.backingMap.container.fitToViewport();
7144	};
7145
7146	YandexMapServices.createMap = function (containerElement, options, yandexMapOptions) {
7147		return new Map(containerElement, options, yandexMapOptions);
7148	};
7149	YandexMapServices.createPositionedMap = function (containerElement, position) {
7150		return new Map(containerElement, position ? { latitude: position.coordinates.latitude, longitude: position.coordinates.longitude, zoom: position.zoomLevel } : { latitude: 0, longitude: 0, zoom: 1 });
7151	};
7152}, this);
7153/* any arguments */ /* any arguments */;
7154// @hash v3-530119527AEE47D95E8D54C47A422B7C86FF3241
7155// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden.
7156// Version: 2.1.1-dev-20151124-1300 (build 563ed55)
7157// Generated at:
7158///////////////////////////////////////////////////////////////////////////////
7159
7160
7161LukoilApp.module("CartographySearchResults", function (CartographySearchResults, LukoilApp, Backbone, Marionette, $, _, global) {
7162    "use strict";
7163
7164    var requiredModules = {
7165        util: LukoilApp.module("Util"),
7166        common: LukoilApp.module("CartographyCommon"),
7167        objects: LukoilApp.module("CartographyObjects")
7168    };
7169
7170    var globals = {};
7171
7172    // -------------------------- Utilities --------------------------
7173    // -------------------------- /Utilities --------------------------
7174
7175    // -------------------------- Constants --------------------------
7176    globals.consts = {};
7177    // -------------------------- /Constants -------------------------
7178
7179    (function (object) {
7180        object.prototype.getObjectInfoPageUrl = function () {
7181            return this.model.objectInfoPageUrl + "?type=" + global.encodeURIComponent(this.t
7181ype) + "&id=" + global.encodeURIComponent(this.Id);
7182        };
7183
7184        object.prototype.getRoutePageUrl = function () {
7185            return this.model.routePageUrl + "?form=gasStation&tab=route&targetLat=" + global.encodeURIComponent(this.Latitude.toFixed()) + "&targetLng=" + global.encodeURIComponent(this.Longitude.toFixed());
7186        };
7187
7188        object.prototype.getFeedbackPageUrl = function () {
7189            return this.model.feedbackPageUrl ? this.model.feedbackPageUrl + "?gs=" + global.encodeURIComponent(this.Id) : "#";
7190        };
7191    })(requiredModules.objects.CartographyObject);
7192
7193    (function () {
7194        function updatePromotionModalForm() {
7195            this.model.modalFormPromotions(this.Promotions);
7196        }
7197        requiredModules.util.stripType(requiredModules.objects.GasStation.prototype).updatePromotionModalForm = updatePromotionModalForm;
7198    })();
7199
7200    var searchSettingsModule = (function () {
7201        return {
7202            resultsPageSize: 3
7203        };
7204    })();
7205
7206    // -------------------------- UI module -------------------------
7207    var uiModule = (function () {
7208        var showMoreContainerSelector;
7209        var errorContainerSelector;
7210
7211        var exposedApi = {
7212            initialize: function initialize(showMoreContainerSelectorParameter, errorContainerSelectorParameter) {
7213                showMoreContainerSelector = showMoreContainerSelectorParameter;
7214                errorContainerSelector = errorContainerSelectorParameter;
7215            },
7216
7217            getFormSearchResultsContainer: function getFormSearchResultsContainer(formContainerSelector) {
7218                return $(formContainerSelector).find(".formSearchResults");
7219            },
7220
7221            getSearchResultsHeadingContainer: function getSearchResultsHeadingContainer(formContainerSelector, headingContainerSelector) {
7222                return $(formContainerSelector).find(headingContainerSelector);
7223            },
7224
7225            getShowMoreContainer: function getShowMoreContainer(formContainerSelector) {
7226                return $(formContainerSelector).find(showMoreContainerSelector);
7227            },
7228
7229            getPromotionModalFormContainer: function getPromotionModalFormContainer() {
7230                return $("#gasListAction");
7231            },
7232
7233            getFormInfoWindowContainerSelector: function getFormInfoWindowContainerSelector(objectType) {
7234                return "#" + objectType + "InfoWindowTemplate";
7235            },
7236
7237            logErrorToDom: function logErrorToDom(err) {
7238                $(function () {
7239                    $(errorContainerSelector).append($("<span></span>").text(err));
7240                });
7241            }
7242        };
7243        return exposedApi;
7244    })();
7245    // -------------------------- /UI module ------------------------
7246
7247    function logError(text) {
7248        if (global.console) {
7249            console.error(text);
7250        } else {
7251            uiModule.logErrorToDom(text);
7252        }
7253    };
7254
7255    function getObjectsInfoFromServer(objectInfoRequests) {
7256        return requiredModules.common.searchProvider.getObjectsInfoFromServer(objectInfoRequests);
7257    }
7258
7259    var getPossiblyCachedObjectsInfo = (function () {
7260        function getObjectId(searchObject) {
7261            return requiredModules.util.stripType(searchObject)[searchObject.idPropertyName];
7262        }
7263        function getCacheKey(searchObject) {
7264            return searchObject.idPropertyName + ":" + getObjectId(searchObject);
7265        }
7266        var cache = requiredModules.util.createObject(null);
7267
7268        return function (searchObjects) {
7269            var uniqueSearchObjects = _.uniq(searchObjects, false, getCacheKey);
7270            var objectsWithCachePromises = _.map(uniqueSearchObjects, function (searchObject) {
7271                return {
7272                    searchObject: searchObject,
7273                    promise: cache[getCacheKey(searchObject)]
7274                };
7275            });
7276            var missing = _.filter(objectsWithCachePromises, function (item) {
7277                return item.promise == null;
7278            });
7279            if (missing.length > 0) {
7280                (function () {
7281                    var missingParams = _.map(missing, function (item) {
7282                        return { type: item.searchObject.type, id: getObjectId(item.searchObject) };
7283                    });
7284                    var promise = getObjectsInfoFromServer(missingParams);
7285                    _.each(missing, function (item, index) {
7286                        cache[getCacheKey(item.searchObject)] = promise.then(function (items) {
7287                            return items[index];
7288                        });
7289                    });
7290                })();
7291            }
7292            return _.map(searchObjects, function (searchObject) {
7293                return requiredModules.util.createObject(cache[getCacheKey(searchObject)]);
7294            });
7295        };
7296    })();
7297
7298    function getPossiblyCachedObjectInfo(searchObject) {
7299        return getPossiblyCachedObjectsInfo([searchObject])[0];
7300    }
7301
7302    function startLoadingData(items) {
7303        _.each(_.zip(items, getPossiblyCachedObjectsInfo(_.map(items, function (item) {
7304            return item.searchObject;
7305        }))), function (a) {
7306            a[1].then(function (objectInfo) {
7307                objectInfo.model = a[0].searchObject.model;
7308                a[0].targetObject.data(objectInfo);
7309            });
7310        });
7311    }
7312
7313    function createLoadingObjectInfoItems(searchObjects) {
7314        var displayedItems = _.map(searchObjects, function (searchObject) {
7315            return _.extend({}, searchObject, { data: global.ko.observable(), uniqueId: requiredModules.util.getUniqueNumber() });
7316        });
7317        return {
7318            displayedItems: displayedItems,
7319            loadingItems: _.map(searchObjects, function (item, index) {
7320                return {
7321                    searchObject: searchObjects[index],
7322                    targetObject: displayedItems[index]
7323                };
7324            })
7325        };
7326    }
7327
7328    var infoWindowModule = (function () {
7329        var mes = requiredModules.util.createObject(null);
7330
7331        function getElementForObject(objectInfo) {
7332            var me = mes[objectInfo.type];
7333            var med;
7334            if (!me) {
7335                var selector = uiModule.getFormInfoWindowContainerSelector(objectInfo.type);
7336                var $elements = $(selector);
7337                if ($elements.length === 1) {
7338                    med = {
7339                        model: {
7340                            getDisabledIconUrl: requiredModules.common.getDisabledIconUrl,
7341                            getAttributeTitle: function getAttributeTitle(item) {
7342                                return item && (item.Name || item.Text || item.FuelName || item.Title) || "";
7343                            },
7344                            ObjectInfo: global.ko.observable(objectInfo)
7345                        },
7346                        element: $elements[0]
7347                    };
7348                    global.ko.applyBindings(med.model, med.element);
7349                    mes[objectInfo.type] = med;
7350                } else {
7351                    throw new Error("Not exactly one element found for element '" + selector + "'.");
7352                }
7353            } else {
7354                med = me;
7355                med.model.ObjectInfo(objectInfo);
7356            }
7357            return med.element;
7358        }
7359
7360        return {
7361            getInfoWindowContent: function getInfoWindowContent(object) {
7362                var errorMessage, updateContent, p, r, result, content;
7363                return regeneratorRuntime.async(function getInfoWindowContent$(context$3$0) {
7364                    while (1) switch (context$3$0.prev = context$3$0.next) {
7365                        case 0:
7366                            updateContent = function updateContent(objectInfo) {
7367                                // TODO
7368                                objectInfo.model = requiredModules.util.stripType(object).model;
7369                                return getElementForObject(objectInfo).outerHTML;
7370                            };
7371
7372                            errorMessage = "Failed to retrieve object info.";
7373                            p = getPossiblyCachedObjectInfo(object);
7374
7375                            if (!requiredModules.util.isPromisePending(p)) {
7376                                context$3$0.next = 9;
7377                                break;
7378                            }
7379
7380                            r = {
7381                                initialContent: "",
7382                                startUpdate: function startUpdate(setContentCallback) {
7383                                    return p.then(function (objectInfo) {
7384                                        return updateContent(objectInfo);
7385                                    }, function () {
7386                                        return errorMessage;
7387                                    });
7388                                }
7389                            };
7390                            result = r;
7391                            return context$3$0.abrupt("return", result);
7392
7393                        case 9:
7394                            if (!requiredModules.util.isPromiseResolved(p)) {
7395                                context$3$0.next = 15;
7396                                break;
7397                            }
7398
7399                            context$3$0.next = 12;
7400                            return regeneratorRuntime.awrap(Promise.all([p.then(function (objectInfo) {
7401                                content = updateContent(objectInfo);
7402                            })]));
7403
7404                        case 12:
7405                            return context$3$0.abrupt("return", content);
7406
7407                        case 15:
7408                            return context$3$0.abrupt("return", errorMessage);
7409
7410                        case 16:
7411                        case "end":
7412                            return context$3$0.stop();
7413                    }
7414                }, null, this);
7415            }
7416        };
7417    })();
7418
7419    var objectInfoPageUrl;
7420    var basicOilListPageUrl;
7421    var extendedOilListPageUrl;
7422    var fullOilListPageUrl;
7423    var feedbackPageUrl;
7424    var routePageUrl;
7425    var navigateToCallback;
7426    var onMarkerClickCallback;
7427
7428    var modalFormPromotions = global.ko.observableArray();
7429
7430    function SearchResultsView(formContainerSelector, departurePointCode, headingContainerSelector) {
7431        var self = this;
7432
7433        var resultsModel = {
7434            displayedItems: global.ko.observableArray(),
7435            searchItems: global.ko.observableArray(),
7436            showMoreItems: function showMoreItems() {
7437                var length = global.Math.min(this.displayedItems().length + searchSettingsModule.resultsPageSize, this.searchItems().length);
7438                var newItems = createLoadingObjectInfoItems(this.searchItems().slice(this.displayedItems().length, length));
7439                this.displayedItems.push.apply(this.displayedItems, newItems.displayedItems);
7440                startLoadingData(newItems.loadingItems);
7441            },
7442            objectInfoPageUrl: objectInfoPageUrl,
7443            basicOilListPageUrl: basicOilListPageUrl,
7444            extendedOilListPageUrl: extendedOilListPageUrl,
7445            fullOilListPageUrl: fullOilListPageUrl,
7446            getOilListPageUrl: function getOilListPageUrl(productListCode) {
7447                switch (productListCode) {
7448                    case 1:
7449                        return this.basicOilListPageUrl;
7450                    case 2:
7451                        return this.extendedOilListPageUrl;
7452                    case 3:
7453                        return this.fullOilListPageUrl;
7454                    default:
7455                        return null;
7456                }
7457            },
7458            feedbackPageUrl: feedbackPageUrl,
7459            routePageUrl: routePageUrl,
7460            modalFormPromotions: modalFormPromotions,
7461            departurePointCode: departurePointCode,
7462            navigateTo: function navigateTo(data) {
7463                navigateToCallback(data.Latitude, data.Longitude, resultsModel.departurePointCode);
7464            },
7465            getDisabledIconUrl: requiredModules.common.getDisabledIconUrl,
7466            getSamePoints: function getSamePoints(item) {
7467                var items = this.searchItems();
7468                var samePoints = item != null ? jQuery.grep(items, function (o, i) {
7469                    return o != null && (o.oilSellerId != null && o.oilSellerId != item.Id || o.salePointId != null && o.salePointId != item.Id || o.gasStationId != null && o.gasStationId != item.Id) && o.Latitude == item.Latitude && o.Longitude == item.Longitude;
7470                }) : null;
7471                return samePoints != null && samePoints.length > 0 ? samePoints : [];
7472            },
7473            getObjectInfoPageUrl: function getObjectInfoPageUrl(item) {
7474                return item.model.objectInfoPageUrl + "?type=" + global.encodeURIComponent(item.type) + "&id=" + global.encodeURIComponent(item.oilSellerId);
7475            }
7476        };
7477        self.resultsModel = resultsModel;
7478
7479        var $e = uiModule.getFormSearchResultsContainer(formContainerSelector);
7480        if ($e.length === 1) {
7481            global.ko.applyBindings(self.resultsModel, $e[0]);
7482        } else {
7483            if ($e.length != 0) {
7484                logError("Not exactly one search results container found for form selector '" + formContainerSelector + "'.");
7485            }
7486        }
7487
7488        if (headingContainerSelector) {
7489            var $he = uiModule.getSearchResultsHeadingContainer(formContainerSelector, headingContainerSelector);
7490            if ($he.length === 1) {
7491                global.ko.applyBindings(self.resultsModel, $he[0]);
7492            } else {
7493                if ($he.length != 0) {
7494                    logError("Not exactly one search results heading container found for form selector '" + formContainerSelector + "'.");
7495                }
7496            }
7497        }
7498
7499        var $sme = uiModule.getShowMoreContainer(formContainerSelector);
7500        if ($sme.length === 1) {
7501            global.ko.applyBindings(self.resultsModel, $sme[0]);
7502        } else {
7503            if ($sme.length != 0) {
7504                logError("Not exactly one show-more container found for form selector '" + formContainerSelector + "'.");
7505            }
7506        }
7507
7508        return this;
7509    };
7510
7511    SearchResultsView.prototype.setMapSearchResults = function (searchResults, mapMarkersCallback) {
7512        var self = this;
7513
7514        // TODO
7515        _.each(searchResults, function (item) {
7516            item.model = self.resultsModel;
7517        });
7518
7519        mapMarkersCallback(searchResults, infoWindowModule.getInfoWindowContent, onMarkerClickCallback);
7520    };
7521
7522    SearchResultsView.prototype.setListSearchResults = function (searchResults) {
7523        var self = this;
7524
7525        // TODO
7526        _.each(searchResults, function (item) {
7527            item.model = self.resultsModel;
7528        });
7529        self.resultsModel.searchItems(searchResults);
7530
7531        var newItems = createLoadingObjectInfoItems(self.resultsModel.searchItems().slice(0, global.Math.min(searchSettingsModule.resultsPageSize, self.resultsModel.searchItems().length)));
7532        self.resultsModel.displayedItems(newItems.displayedItems);
7533        startLoadingData(newItems.loadingItems);
7534    };
7535
7536    SearchResultsView.prototype.setListSearchResultsToPending = function () {
7537        var self = this;
7538        self.resultsModel.searchItems([]);
7539        self.resultsModel.displayedItems([]);
7540    };
7541
7542    CartographySearchResults.SearchResultsView = SearchResultsView;
7543
7544    CartographySearchResults.getInfoWindowContent = infoWindowModule.getInfoWindowContent;
7545
7546    CartographySearchResults.initialize = function (navigateToCallback_, showMoreContainerSelector, errorContainerSelector, objectInfoPageUrl_, basicOilListPageUrl_, extendedOilListPageUrl_, fullOilListPageUrl_, routePageUrl_, feedbackPageUrl_, onMarkerClickCallback_) {
7547        navigateToCallback = navigateToCallback_;
7548        objectInfoPageUrl = objectInfoPageUrl_;
7549        basicOilListPageUrl = basicOilListPageUrl_;
7550        extendedOilListPageUrl = extendedOilListPageUrl_;
7551        fullOilListPageUrl = fullOilListPageUrl_;
7552        feedbackPageUrl = feedbackPageUrl_;
7553        routePageUrl = routePageUrl_;
7554        onMarkerClickCallback = onMarkerClickCallback_;
7555        uiModule.initialize(showMoreContainerSelector, errorContainerSelector);
7556
7557        $(function () {
7558            var $pe = uiModule.getPromotionModalFormContainer();
7559            if ($pe.length === 1) {
7560                global.ko.applyBindings(modalFormPromotions, $pe[0]);
7561            } else {
7562                if ($pe.length != 0) {
7563                    logError("Not exactly one promotion modal form container found.");
7564                }
7565            }
7566        });
7567    };
7568}, this);;
7569// @hash v3-3DA60CE307CFB5247DFC02A5F4AAF46D221641F2
7570// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden.
7571// Version: 2.1.1-dev-20151124-1300 (build 563ed55)
7572// Generated at:
7573///////////////////////////////////////////////////////////////////////////////
7574var _extends=Object.assign || function(target){for(var i=1;i < arguments.length;i++) {var source=arguments[i];for(var key in source) {if(Object.prototype.hasOwnProperty.call(source,key)){target[key] = source[key];}}}return target;}; // Last tracked design map.js commit: a1f49d06622d16a9fb9b07c1434a1089236254bf
7575LukoilApp.module("Cartography",function(Cartography,LukoilApp,Backbone,Marionette,$,_,momentJs,global){"use strict";var requiredModules={util:LukoilApp.module("Util"),common:LukoilApp.module("CartographyCommon"),mapUtil:LukoilApp.module("MapUtil"),search:LukoilApp.module("CartographySearch"),routing:LukoilApp.module("Routing"),googleMapServices:LukoilApp.module("GoogleMapServices"),yandexMapServices:LukoilApp.module("YandexMapServices"),searchResults:LukoilApp.module("CartographySearchResults"),mapProvider:LukoilApp.module("Util").stripType(null) // determined later
7576};var globals={}; // -------------------------- Utilities --------------------------
7577var utilityModule=(function(){return {repeatDOMElements:function repeatDOMElements($container,list){var $e=$container.children();var $elements=$e.detach();var newElementArray=[];_.each(list,function(item,index){var $newElements=$elements.clone().appendTo($container);newElementArray.push({item:item,$e:$newElements});});$elements.remove();return newElementArray;}};})(); // -------------------------- /Utilities --------------------------
7578// -------------------------- Constants --------------------------
7579globals.consts = {};globals.consts.formIds = requiredModules.common.consts.formIds;globals.consts.defaultFormId = requiredModules.common.consts.formIds.gasStation;globals.consts.filterIds = requiredModules.common.consts.filterIds;globals.consts.defaultSearchModeId = globals.consts.formIds.gasStation; // -------------------------- /Constants -------------------------
7580var defaultMapBounds;var criticalErrorMessage;function criticalErrorHandler(){$(function(){$.fancybox.open({content:criticalErrorMessage});});};requiredModules.yandexMapServices.apiLoadFailureHandler = criticalErrorHandler;requiredModules.googleMapServices.apiLoadFailureHandler = criticalErrorHandler;var searchSettingsModule=(function(){return {objectInfoPageUrl:undefined,feedbackPageUrl:undefined,routePageUrl:undefined,closestObjectMarginPercent:undefined};})();var selectAndLoadMapApi=(function(){var promise;return function(languageCode){if(!promise){promise = requiredModules.common.getCurrentSelectedCountry(languageCode).then(function(countryCode){requiredModules.mapProvider = requiredModules.googleMapServices; //requiredModules.googleMapServices.disableApiKey();
7581//if (countryCode === "RU") {
7582//	requiredModules.mapProvider = requiredModules.yandexMapServices;
7583//	requiredModules.googleMapServices.disableApiKey();
7584//} else {
7585//	requiredModules.mapProvider = requiredModules.googleMapServices;
7586//               }
7587return requiredModules.mapProvider.ensureMapApiIsReady(languageCode).promise();});}return promise;};})();var savedMapPositionModule=(function(){var re=new RegExp("([^:]+):([^:]+):([^:]+)");
7587function getMapProviderCode(mapProvider){return mapProvider === requiredModules.googleMapServices?"Google":"Yandex";}function getCookieName(mapProvider){return "LukCartMapPosition" + getMapProviderCode(mapProvider);}function getPositionString(coordinates,zoomLevel){return coordinates.latitude + ":" + coordinates.longitude + ":" + zoomLevel;}function parsePositionString(positionString){if(positionString){var c=re.exec(positionString);var lat=parseFloat(c[1]);var lng=parseFloat(c[2]);var _zoomLevel=parseFloat(c[3]);return isFinite(lat) && isFinite(lng) && isFinite(_zoomLevel)?{coordinates:{latitude:lat,longitude:lng},zoomLevel:_zoomLevel}:null;}else {return null;}}return {saveMapPosition:function saveMapPosition(mapProvider,coordinates,zoomLevel){$.lukoilSaveCookie(getCookieName(mapProvider),getPositionString(coordinates,zoomLevel),{expires:365,path:"/"});},getMapPosition:function getMapPosition(mapProvider){return parsePositionString($.lukoilGetCookie(getCookieName(mapProvider)));}};})(); // -------------------------- Geolocation service -------------------------
7588var geolocationService=(function(){var placeIdsPromise;var countryBoundsPromise;var exposedApi={getCurrentLocationPlaceIds:function getCurrentLocationPlaceIds(){if(!placeIdsPromise){placeIdsPromise = $.when(requiredModules.googleMapServices.ensureMapApiIsReady(GlobalSettings.CurrentLanguage).promise(),requiredModules.mapUtil.userLocationProvider.getCurrentLocation()).then(function(_1,geolocationResult){return requiredModules.googleMapServices.geocodingService.getCountryAndRegionPlaceIds(geolocationResult.location.lat,geolocationResult.location.lng);});}return placeIdsPromise;},getCurrentSelectedCountryBounds:function getCurrentSelectedCountryBounds(languageCode){if(!countryBoundsPromise){countryBoundsPromise = requiredModules.common.getCurrentSelectedCountry(languageCode).then(function(countryCode){return $.ajax("/api/cartography/GetCountryOrDefaultBounds",{async:true,cache:true,data:{country:countryCode},dataType:"json",method:"GET"}).then(function(serverResult){return serverResult && serverResult.ViewportSWLatitude != null?{minLatitude:serverResult.ViewportSWLatitude,maxLatitude:serverResult.ViewportNELatitude,leftLongitude:serverResult.ViewportSWLongitude,rightLongitude:serverResult.ViewportNELongitude}:defaultMapBounds;});});}return countryBoundsPromise;}};return exposedApi;})(); // -------------------------- /Geolocation service ------------------------
7589// -------------------------- UI module -------------------------
7590var uiModule=(function(){var mapContainerSelector="#map";var mapControlContainerCssClass="map-finder-container";var mapControlContainerSelector="." + mapControlContainerCssClass;var fullScreenControlSelector=".full-screen-control";var shouldShowSearchUI;function initializeYandexMap(mapProvider,mapContainer,position){requiredModules.common.initMap(mapProvider,mapContainer,position);var yandexMap=requiredModules.common.map.backingMap;var deferred=$.Deferred();var CustomControlClass=function CustomControlClass($parentElem,options){CustomControlClass.superclass.constructor.call(this,options);this._$content = null;this.$parentElem = $parentElem;};$("#map").addClass("ya-map");global.ymaps.util.augment(CustomControlClass,ymaps.collection.Item,{onAddToMap:function onAddToMap(map){CustomControlClass.superclass.onAddToMap.call(this,map);this._lastCenter = null;this.getParent().getChildElement(this).then(this._onGetChildElement,this);},onRemoveFromMap:function onRemoveFromMap(oldMap){this._lastCenter = null;if(this._$content){this._$content.remove();this._mapEventGroup.removeAll();}CustomControlClass.superclass.onRemoveFromMap.call(this,oldMap);},_onGetChildElement:function _onGetChildElement(parentDomContainer){this._$content = this.$parentElem.appendTo(parentDomContainer);this._mapEventGroup = this.getMap().events.group();deferred.resolve();}});if(shouldShowSearchUI){yandexMap.controls.add(new CustomControlClass($(mapControlContainerSelector)),{float:'none',position:{top:0,right:0}});}yandexMap.controls.add(new CustomControlClass($(fullScreenControlSelector)),{float:'none',position:{top:0,left:0}});yandexMap.controls.remove('searchControl');yandexMap.controls.remove('typeSelector'); //yandexMap.controls.remove('scaleLine');
7591yandexMap.controls.add('zoomControl');yandexMap.controls.remove('trafficControl');yandexMap.controls.remove("fullscreenControl");yandexMap.controls.remove('geolocationControl');window.resizeMap = function(){yandexMap.container.fitToViewport();};$(mapControlContainerSelector).removeClass("hide");if(shouldShowSearchUI){deferred.then(function(){$(mapControlContainerSelector).removeClass("hidden");$(fullScreenControlSelector).removeClass("hidden");});}return deferred.promise();}function initializeGoogleMap(mapProvider,mapContainer,position){$("#map").addClass("google-map");requiredModules.common.initMap(mapProvider,mapContainer,position,{zoomControlOptions:{position:google.maps.ControlPosition.LEFT_CENTER},mapTypeControl:false,streetViewControl:false});var googleMap=requiredModules.common.map.backingMap;var control=$(mapControlContainerSelector)[0];var fullScreenControl=$(fullScreenControlSelector)[0];requiredModules.util.stripType(control).index = 1;requiredModules.util.stripType(fullScreenControl).index = 2;if(shouldShowSearchUI){googleMap.controls[global.google.maps.ControlPosition.TOP_RIGHT].push(control);}googleMap.controls[global.google.maps.ControlPosition.TOP_LEFT].push(fullScreenControl);$(mapControlContainerSelector).removeClass("hide");if(shouldShowSearchUI){global.google.maps.event.addListener(googleMap,"tilesloaded",function(){$(mapControlContainerSelector).removeClass("hidden");$(fullScreenControlSelector).removeClass("hidden");});}window.resizeMap = function(){google.maps.event.trigger(googleMap,'resize');};return requiredModules.util.getResolvedPromise();}var mapControlSelector=".map-finder";var activeTabLinkCssClass="selected";var activeTabCssClass="opened";var errorContainerSelector="#errorLogContainer";var expandedUiCssClass="opened";function getFormTabLinkCssClass(formId){return formId + "TabLink";}function getFormContainerSelector(formId){return ".map-finder__tabs-content ." + formId + "Form";};function getFormFiltersContainerSelector(formId){return getFormContainerSelector(formId) + ".formFilters";};function getFormSearchResultsContainerSelector(formId){return getFormContainerSelector(formId) + " .formSearchResults";};function getFormFilterSelector(formId,filterId){return getFormFiltersContainerSelector(formId) + " ." + filterId + "Filter";};function getFormTabLinkSelector(formId){return ".map-finder__tabs ." + getFormTabLinkCssClass(formId);}function ensureUiIsExpanded(){$(mapControlSelector).addClass(expandedUiCssClass);}function ensureUiIsCollapsed(){$(mapControlSelector).removeClass(expandedUiCssClass);}var initializeMapCallback;var uiDeferred=$.Deferred();var forms;var currentForm;var exposedApi={initialize:function initialize(shouldShowSearchUI_,mapProvider,forms_,uiSett
7591ingsParameter){shouldShowSearchUI = shouldShowSearchUI_;exposedApi.uiSettings = uiSettingsParameter;forms = forms_;initializeMapCallback = mapProvider === requiredModules.googleMapServices?initializeGoogleMap:initializeYandexMap;},activate:function activate(position){initializeMapCallback(requiredModules.mapProvider,exposedApi.getMapContainer(),position).then(function(){$(".map-finder__tab").on("click",function(event){var $e=$(this);var form=_.find(forms,function(f,formId){return $e.hasClass(getFormTabLinkCssClass(formId));});if(form){exposedApi.activateForm(form,false);}event.preventDefault();});requiredModules.common.activateUi();});},getMapContainer:function getMapContainer(){return $(mapContainerSelector)[0];},activateForm:function activateForm(form,shouldChangeUI){if(form !== currentForm){if(currentForm){currentForm.hide();if(shouldChangeUI){requiredModules.common.uiReady.then(function(){exposedApi.deactivateFormUI(currentForm.formId);});}}if(!currentForm || shouldChangeUI){requiredModules.common.uiReady.then(function(){exposedApi.activateFormUI(form.formId);});}form.show(!currentForm);currentForm = form;}},activateRoutingForm:function activateRoutingForm(){var routingForm=forms[globals.consts.formIds.route];if(routingForm){exposedApi.activateForm(routingForm,true);ensureUiIsExpanded();}},hideFormUI:function hideFormUI(formId){$(getFormTabLinkSelector(formId)).hide();$(getFormContainerSelector(formId)).hide();},activateFormUI:function activateFormUI(formId){$(getFormTabLinkSelector(formId)).addClass(activeTabLinkCssClass);$(getFormContainerSelector(formId)).addClass(activeTabCssClass);},deactivateFormUI:function deactivateFormUI(formId){$(getFormTabLinkSelector(formId)).removeClass(activeTabLinkCssClass);$(getFormContainerSelector(formId)).removeClass(activeTabCssClass);},ensureUiIsCollapsed:ensureUiIsCollapsed,getFormFilterSelector:getFormFilterSelector,getFormContainerSelector:getFormContainerSelector,getFormSearchResultsContainer:function getFormSearchResultsContainer(formId){return $(getFormSearchResultsContainerSelector(formId));},getFormInfoWindowContainerSelector:function getFormInfoWindowContainerSelector(formId){return "#" + formId + "InfoWindowTemplate";},getFormResetFiltersButton:function getFormResetFiltersButton(formId){return $(getFormContainerSelector(formId) + " .resetFiltersClass");},hideLoadingOverlay:function hideLoadingOverlay(){$("#loadingOverlay").hide();},logErrorToDom:function logErrorToDom(err){$(function(){$(errorContainerSelector).append($("<span></span>").text(err.toString()));});},uiSettings:{},errorContainerSelector:errorContainerSelector,searchResultsHeadingContainerSelector:".searchResultsHeading",showMoreContainerSelector:".showMore"};return exposedApi;})(); // -------------------------- /UI module ------------------------
7592function logError(error){if(global.console){global.console.error(error);}else {uiModule.logErrorToDom(error);}}; // -------------------------- Search providers -------------------------
7593var serverServiceModule=(function(){var languageCode;var filtersAffectingOther=[];function FiltersProvider(){};FiltersProvider.prototype = requiredModules.util.createObject(requiredModules.util.oneRequestAtATimeServicePrototype);FiltersProvider.prototype.constructor = FiltersProvider;FiltersProvider.prototype.isFilterAffectingOther = function(filterId){return _.contains(filtersAffectingOther,filterId);};FiltersProvider.prototype.getFilters = (function(){var cache=requiredModules.util.createObject(null);function getCacheKey(parameterCollection){return JSON.stringify(parameterCollection);}return function(formId,countryCode,changedFilterId,filterSelections,filters){var parameterCollection={form:formId,country:countryCode,changedFilter:changedFilterId || "root"};parameterCollection[global.Constants.queryParamNames.LanguageCode] = languageCode;var date=new Date();parameterCollection[globals.consts.filterIds.date] = Date.UTC(date.getFullYear(),date.getMonth(),date.getDate());_.each(filterSelections,function(selection,filterId){parameterCollection = _.extend(parameterCollection,filters[filterId].getUrlParametersFromSelection(selection));});
7593return this.startRequest($.ajax("/api/cartography/GetFilters",{async:true,cache:true,ifModified:true,data:parameterCollection,dataType:"json",method:"GET",traditional:true})).then(function(newFilters,statusString){if(statusString === "notmodified" && newFilters == null){newFilters = JSON.parse(cache[getCacheKey(parameterCollection)]);}else {cache[getCacheKey(parameterCollection)] = JSON.stringify(newFilters);}if(newFilters[globals.consts.filterIds.service]){newFilters[globals.consts.filterIds.service].Items = Array.prototype.concat.apply([],_.pluck(newFilters[globals.consts.filterIds.service].Items,"Items"));}if(newFilters[globals.consts.filterIds.roadService]){newFilters[globals.consts.filterIds.roadService].Items = Array.prototype.concat.apply([],_.pluck(newFilters[globals.consts.filterIds.roadService].Items,"Items"));}var typeFillingFilter=newFilters["typeFilling"];if(typeFillingFilter){typeFillingFilter.options = ko.observableArray(typeFillingFilter.Items.map(function(item){return _extends({},item,{Selected:ko.observable(false)});}));}var shippingMethodFilter=newFilters["shippingMethod"];if(shippingMethodFilter){shippingMethodFilter.options = ko.observableArray(shippingMethodFilter.Items.map(function(item){return _extends({},item,{Selected:ko.observable(false)});}));}var tankFarmFuelFilter=newFilters["tankFarmFuel"];if(tankFarmFuelFilter){tankFarmFuelFilter.options = ko.observableArray(tankFarmFuelFilter.Items.map(function(item){return _extends({},item,{Selected:ko.observable(false)});}));} //if (newFilters[globals.consts.filterIds.cardType]) {
7594//	newFilters[globals.consts.filterIds.cardType].Items = Array.prototype.concat.apply([], _.pluck(newFilters[globals.consts.filterIds.cardType].Items, "Items"));
7595//}
7596return newFilters;});};})();var exposedApi={initialize:function initialize(_languageCode){languageCode = _languageCode;requiredModules.common.searchProvider.setLanguage(languageCode);},filtersProvider:new FiltersProvider(),searchProvider:requiredModules.common.searchProvider,objectsProvider:{getObjects:function getObjects(formId){ //var parameterCollection: Object = {
7597//	form: formId,
7598//};
7599//_.each(filterSelections, function (selection: any, filterId: string): void {
7600//	parameterCollection = _.extend(parameterCollection, filters[filterId].getUrlParametersFromSelection(selection));
7601//});
7602return $.ajax("/api/cartography/GetSearchObjects",{async:true,cache:true,ifModified:true,data:{form:formId,SalePointTypeId:SalePointStorade.Id},dataType:"json",method:"GET"}).then(function(result){ // Not handling undefined 304 response data because the web method is called only once and the browser provides a cached response.
7603return result;});},getCountryDependentObjectData:function getCountryDependentObjectData(formId,countryCode){return $.ajax("/api/cartography/GetCountryDependentSearchObjectData",{async:true,cache:true,ifModified:true,data:{form:formId,country:countryCode},dataType:"json",method:"GET"}).then(function(result){ // Not handling undefined 304 response data because the web method is called only once and the browser provides a cached response.
7604return result;});}}};return exposedApi;})(); // -------------------------- /Search providers ------------------------
7605var ensureGasStationSearchInitialized=(function(){var formId=globals.consts.formIds.gasStation;var initialized=false;function GasStation(serverGasStation,countryDependent,iconUrl,attentionIconUrl,userLocation){this.gasStationId = serverGasStation.GasStationId;this.Latitude = serverGasStation.Latitude;this.Longitude = serverGasStation.Longitude;this.IconUrl = serverGasStation.GasStationStatus == 6 || serverGasStation.GasStationStatus == 7?attentionIconUrl:iconUrl;this.IsDisabled = serverGasStation.GasStationStatus == 6 || serverGasStation.GasStationStatus == 7;this.displayName = serverGasStation.DisplayName;this.sellsOil = serverGasStation.SellsOil;this.highwayId = serverGasStation.HighwayId;this.postCode = serverGasStation.PostCode;this.serviceBits = serverGasStation.Services;this.promotionBits = serverGasStation.Promotions;this.paymentTypeBits = serverGasStation.PaymentTypes;this.propertyBits = serverGasStation.Properties;if(countryDependent){this.fuelClassBits = countryDependent.FuelClasses;}else {this.fuelClassBits = [];}this.businessHours = serverGasStation.BusinessHours;this.storeBusinessHours = serverGasStation.StoreBusinessHours;this.distanceFromUser = userLocation?requiredModules.googleMapServices.computeGeographicalDistanceInMeters(this.Latitude,this.Longitude,userLocation.latitude,userLocation.longitude):null;}GasStation.prototype.idPropertyName = "gasStationId";GasStation.prototype.type = requiredModules.search.objectTypes.gasStation;function GasStationSearchData(serverGasStationData,countryDependent,userLocation){this.services = serverGasStationData.Services;this.promotions = serverGasStationData.Promotions;this.paymentTypes = serverGasStationData.PaymentTypes;this.fuelClasses = countryDependent.FuelClasses;this.properties = serverGasStationData.Properties;this.storeServiceId = serverGasStationData.StoreServiceId;var cd=_.object(_.map(countryDependent.GasStations,function(gs){return [gs.GasStationId,gs];}));this.gasStations = _.map(serverGasStationData.GasStations,function(gs){return new GasStation(gs,cd[gs.GasStationId],serverGasStationData.IconUrl,serverGasStationData.AttentionIconUrl,userLocation);});}function initialize(){var p1=serverServiceModule.objectsProvider.getObjects(formId);var p2=requiredModules.common.getCurrentSelectedCountry(GlobalSettings.CurrentLanguage).then(function(countryCode){return serverServiceModule.objectsProvider.getCountryDependentObjectData(formId,countryCode);});var p3=requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function(geolocationResult){return geolocationResult.location && geolocationResult.location.lat != null && geolocationResult.location.lng != null?{latitude:geolocationResult.location.lat,longitude:geolocationResult.location.lng}:null;},function(){return requiredModules.util.createResolvedPromise(null);});var p4=requiredModules.googleMapServices.ensureMapApiIsReady(GlobalSettings.CurrentLanguage).promise();$.when(p1,p2,p3,p4).then(function(serverGasStationData,countryDependentResult,userLocation,_4){var data=new GasStationSearchData(serverGasStationData,countryDependentResult,userLocation);data.gasStations.sort(function(a,b){var ea=!!a.displayName,eb=!!b.displayName;return ea === eb?ea && a.displayName.localeCompare(b.displayName) || 0:ea?-1:1;});requiredModules.search.initializeForObjectType(formId,data,searchSettingsModule.closestObjectMarginPercent);});}return function(){if(!initialized){initialized = true;initialize();}};})(); // -------------------------- Filter module --------------------------
7606var filterModule=(function(){function setFilters(filters,newFiltersWithSelections){var expandPanel=false;_.each(newFiltersWithSelections,function(filterOptionsWithSelections,filterId){if(filters[filterId]){if(filterOptionsWithSelections != null && filterOptionsWithSelections.Selection != null && filterOptionsWithSelections.Selection.length > 0){var $filterBlock=$(filters[filterId].uiComponentSelector);if($filterBlock.length > 0){$filterBlock.parents(".map-finder__panel").find(".tab-content__title").trigger("click");
7606if(filterOptionsWithSelections.ClearFilter != null && filterOptionsWithSelections.ClearFilter != ''){filters[filterOptionsWithSelections.ClearFilter].clearSelection();}expandPanel = true;}}filters[filterId].setOptions(filterOptionsWithSelections.Items,filterOptionsWithSelections.Selection);}});if(expandPanel){var f=$(".map-finder").width();var m=$("#map").width();if(m / 2 >= f){$(".map-finder").addClass("opened");}}};function scheduleFilterUiInitialization(model,selector){requiredModules.common.uiReady.then(function(){var $e=$(selector);if($e.length === 1){global.ko.applyBindings(model,$e[0]);} //else {
7607//	 logError("Not exactly one element found for selector '" + selector + "'.");
7608//}
7609});};var searchFilterPrototype={setChangeEventHandler:function setChangeEventHandler(handler,context){this.changeEventHandler = function(filter){handler.call(context,filter);};}};function updateFilterUiState(filters,mapCancellationToken){_.each(filters,function(filter){if(filter.updateUiState){filter.updateUiState(mapCancellationToken);}});};function getFilterSelections(filters){var filterIds=_.keys(filters);return $.when.apply($,_.map(filterIds,function(filterId){return filters[filterId].getSelectionPromise();})).then(function(){var selections=arguments;return _.object(filterIds,selections);});};function SingleValuedListSearchFilter(filterId,noSelectionItemText,uiComponentSelector){var self=this;self.filterId = filterId;self.noSelectionItemText = noSelectionItemText;self.uiComponentSelector = uiComponentSelector;self.$select = undefined; // Initially set from settings or undefined, then null when selection is obtained from the view model.
7610self.initialSelectedId = undefined;return this;};SingleValuedListSearchFilter.prototype = requiredModules.util.createObject(searchFilterPrototype);SingleValuedListSearchFilter.prototype.constructor = SingleValuedListSearchFilter;SingleValuedListSearchFilter.prototype.initialize = function(filterSettings){var self=this;if(filterSettings != null){self.initialSelectedId = filterSettings;}self.model = {options:[],selectedId:null};requiredModules.common.uiReady.then(function(){self.$select = $(self.uiComponentSelector).filter("select");self.$select.on("change",function(){self.model.selectedId = self.$select.val() || null;self.changeEventHandler(self);});});};SingleValuedListSearchFilter.prototype.getUrlParametersFromSelection = function(selection){return selection != null?requiredModules.util.createSinglePropertyObject(this.filterId,selection):{};};SingleValuedListSearchFilter.prototype.setOptions = function(options,selection){var self=this;this.initialSelectedId = null;this.model.options = [{Id:"",Text:this.noSelectionItemText}].concat(options);this.model.selectedId = selection;requiredModules.common.uiReady.then(function(){self.$select.destroySelect2();self.$select.empty();self.$select.append("<option></option>");_.each(utilityModule.repeatDOMElements(self.$select,self.model.options),function(item){item.$e.attr("value",item.item.Id);item.$e.text(item.item.Text);});self.$select.val(self.model.selectedId || "");self.$select.initSelect2();});};SingleValuedListSearchFilter.prototype.clearSelection = function(){var self=this;self.model.selectedId = null;requiredModules.common.uiReady.then(function(){ // Just to indicate a reset immediately, not waiting for the new filter selections to get retrieved.
7611self.$select.val("");});};SingleValuedListSearchFilter.prototype.getSelectionPromise = function(){ //console.log('SingleValuedListSearchFilter');
7612return requiredModules.util.createResolvedPromise(this.initialSelectedId !== null?this.initialSelectedId:this.model.selectedId);};function MultiValuedListSearchFilter(filterId,uiComponentSelector){var self=this;self.filterId = filterId;self.uiComponentSelector = uiComponentSelector;self.shouldFireChangeEvent = false; // Initially set from settings or [], then null when selection is obtained from the view model.
7613self.initialSelectedIds = [];};MultiValuedListSearchFilter.prototype = requiredModules.util.createObject(searchFilterPrototype);MultiValuedListSearchFilter.prototype.constructor = MultiValuedListSearchFilter;MultiValuedListSearchFilter.prototype.initializeModelOnly = function(filterSettings){var self=this;if(filterSettings != null){self.initialSelectedIds = filterSettings;}self.model = {options:global.ko.observableArray()};};MultiValuedListSearchFilter.prototype.initialize = function(filterSettings){this.initializeModelOnly(filterSettings);scheduleFilterUiInitialization(this.model,this.uiComponentSelector);};MultiValuedListSearchFilter.prototype.getUrlParametersFromSelection = function(selection){return requiredModules.util.createSinglePropertyObject(this.filterId,selection);};MultiValuedListSearchFilter.prototype.setOptions = function(options,selection){var self=this;var displayedOptions=_.map(options,function(x){var o=requiredModules.util.createObject(x);o.Selected = global.ko.observable(_.some(selection,function(id){return id === o.Id;}));if(self.model.changeSelection){o.Selected.subscribe(self.model.changeSelection);}o.uniqueId = requiredModules.util.getUniqueNumber();return o;});this.initialSelectedIds = null;this.shouldFireChangeEvent = false;this.model.options(displayedOptions);this.shouldFireChangeEvent = true;};MultiValuedListSearchFilter.prototype.getSelection = function(){return this.initialSelectedIds !== null?this.initialSelectedIds:_.map(_.filter(this.model.options(),function(item){return item.Selected();}),function(item){return item.Id;});};MultiValuedListSearchFilter.prototype.clearSelection = function(){var self=this;self.shouldFireChangeEvent = false;_.each(self.model.options(),function(item){item.Selected(false);});self.shouldFireChangeEvent = true;};MultiValuedListSearchFilter.prototype.getSelectionPromise = function(){ //console.log('MultiValuedListSearchFilter');
7614return requiredModules.util.createResolvedPromise(this.getSelection());};var iconListSearchFilterBase=MultiValuedListSearchFilter;function IconListSearchFilter(filterId,uiComponentSelector,noItemsText){iconListSearchFilterBase.call(this,filterId,uiComponentSelector);this.noItemsText = noItemsText;};IconListSearchFilter.prototype = requiredModules.util.createObject(iconListSearchFilterBase.prototype);IconListSearchFilter.prototype.constructor = IconListSearchFilter;IconListSearchFilter.prototype.initialize = function(filterSettings){var self=this;self.initializeModelOnly(filterSettings);self.model.getCurrentSelectedCssClass = function(item){return item.Selected()?"selected":"";};self.model.getEnabledIconUrl = requiredModules.common.getEnabledIconUrl;self.model.getDisabledIconUrl = requiredModules.common.getDisabledIconUrl;self.model.changeSelection = function(){if(self.shouldFireChangeEvent){self.changeEventHandler(self);}};self.model.noItemsText = self.noItemsText;scheduleFilterUiInitialization(self.model,self.uiComponentSelector);};var checkboxListSearchFilterBase=MultiValuedListSearchFilter;function CheckboxListSearchFilter(filterId,uiComponentSelector,fireChangeEvent,noItemsText){checkboxListSearchFilterBase.call(this,filterId,uiComponentSelector);this.fireChangeEvent = Boolean(fireChangeEvent);this.noItemsText = noItemsText;};CheckboxListSearchFilter.prototype = requiredModules.util.createObject(checkboxListSearchFilterBase.prototype);CheckboxListSearchFilter.prototype.constructor = CheckboxListSearchFilter;CheckboxListSearchFilter.prototype.initialize = function(filterSettings){var self=this;this.initializeModelOnly(filterSettings);if(this.fireChangeEvent){this.model.changeSelection = function(){if(self.shouldFireChangeEvent){self.changeEventHandler(self);}};}};CheckboxListSearchFilter.prototype.setOptions = function(options,selection){checkboxListSearchFilterBase.prototype.setOptions.call(this,options,selection);var self=this;_.each(self.model.options(),function(item){item.uniqueId = requiredModules.util.getUniqueNumber();});requiredModules.common.uiReady.then(function(){var $container=$(self.uiComponentSelector);$container.remove(".noItemsClass");$container.children(":not(:first-child)").remove(); //$container.find("input:checkbox").styler("destroy");
7615_.each(utilityModule.repeatDOMElements($container,self.model.options()),function(item){item.$e.each(function(ind,element){global.ko.applyBindings(item.item,element);});item.$e.find("input:checkbox").on("change",function(){item.item.Selected(!!$(this).prop("checked"));});}); //$container.find("input:checkbox").styler();
7616if(options.length === 0){$("<p class='noItemsClass'></p>").prependTo($container).text(self.noItemsText);}});};function PromotionSearchFilter(filterId,uiComponentSelector,modalFormSelector){var self=this;self.filterId = filterId;self.uiComponentSelector = uiComponentSelector;self.regionFilter = new CheckboxListSearchFilter(filterId + "-region",modalFormSelector + " .regionPromotions");self.countryFilter = new CheckboxListSearchFilter(filterId + "-country",modalFormSelector + " .countryPromotions");self.otherFilter = new CheckboxListSearchFilter(filterId + "-other",modalFormSelector + " .otherPromotions");self.modalFormSelector = modalFormSelector;return this;};PromotionSearchFilter.prototype = requiredModules.util.createObject(searchFilterPrototype);PromotionSearchFilter.prototype.constructor = PromotionSearchFilter;PromotionSearchFilter.prototype.getSelectedCount = function(){return this.regionFilter.getSelection().length + this.countryFilter.getSelection().length + this.otherFilter.getSelection().length;};PromotionSearchFilter.prototype.initialize = function(filterSettings){var self=this;self.regionFilter.initialize(null);self.countryFilter.initialize(null);self.otherFilter.initialize(filterSettings);self.model = {count:global.ko.observable(0),selectedCount:global.ko.observable(self.getSelectedCount())};scheduleFilterUiInitialization(self.model,self.uiComponentSelector);requiredModules.common.uiReady.then(function(){$(self.modalFormSelector).find(".button").on("click",function(event){event.preventDefault();self.changeEventHandler(self);$(self.modalFormSelector).modal('hide');self.model.selectedCount(self.getSelectedCount());});});};PromotionSearchFilter.prototype.getUrlParametersFromSelection = function(selection){return requiredModules.util.createSinglePropertyObject(this.filterId,selection);};PromotionSearchFilter.prototype.setOptions = function(options,selection){var self=this;self.model.count(options.RegionPromotions.length + options.CountryPromotions.length + options.OtherPromotions.length);requiredModules.common.uiReady.then(function(){var $form=$(self.modalFormSelector);
7616var $regionContainer=$form.find(".regionPromotionsWrapper");var $countryContainer=$form.find(".countryPromotionsWrapper");var $otherContainer=$form.find(".otherPromotionsWrapper");if(options.RegionPromotions.length > 0){$regionContainer.show();}else {$regionContainer.hide();}if(options.CountryPromotions.length > 0){$countryContainer.show();}else {$countryContainer.hide();}if(options.OtherPromotions.length > 0){$otherContainer.show();}else {$otherContainer.hide();}if(options.RegionPromotions.length === 0 && options.CountryPromotions.length === 0 && options.OtherPromotions.length === 0){$form.find(".noPromotions").show();}else {$form.find(".noPromotions").hide();}self.regionFilter.setOptions(options.RegionPromotions,selection);self.countryFilter.setOptions(options.CountryPromotions,selection);self.otherFilter.setOptions(options.OtherPromotions,selection);});};PromotionSearchFilter.prototype.clearSelection = function(){var self=this;self.regionFilter.clearSelection();self.countryFilter.clearSelection();self.otherFilter.clearSelection();self.model.selectedCount(self.getSelectedCount());};PromotionSearchFilter.prototype.getSelectionPromise = function(){ //console.log('PromotionSearchFilter');
7617return requiredModules.util.createResolvedPromise(this.regionFilter.getSelection().concat(this.countryFilter.getSelection()).concat(this.otherFilter.getSelection()));}; // NOTE: disabled flag filter is effectively off.
7618function FlagSearchFilter(filterId,uiComponentSelector,enabled){var self=this;self.filterId = filterId;self.enabled = enabled == null?true:enabled;self.uiComponentSelector = uiComponentSelector;self.shouldFireUserChangeEvent = false;self.value = false;self.$input = undefined;self.$element = undefined;};FlagSearchFilter.prototype = requiredModules.util.createObject(searchFilterPrototype);FlagSearchFilter.prototype.constructor = FlagSearchFilter;FlagSearchFilter.prototype.updateUi = function(){var self=this;self.shouldFireUserChangeEvent = false;if(self.enabled && self.value){$(self.uiComponentSelector).filter("label").addClass("selected");$(self.uiComponentSelector).filter("span").addClass("selected");}else {$(self.uiComponentSelector).filter("label").removeClass("selected");$(self.uiComponentSelector).filter("span").removeClass("selected");}self.$input.prop("checked",self.enabled && self.value);self.$input.prop("readonly",!self.enabled);self.$input.prop("disabled",!self.enabled);if(self.enabled){self.$element.removeClass("disabled");}else {self.$element.addClass("disabled");}self.shouldFireUserChangeEvent = true;};FlagSearchFilter.prototype.initialize = function(filterSettings){var self=this;if(filterSettings != null){self.value = filterSettings;}requiredModules.common.uiReady.then(function(){self.$element = $(self.uiComponentSelector);self.$input = self.$element.find("input");self.updateUi();self.$element.filter("span").on("click",function(){if(self.shouldFireUserChangeEvent && self.enabled){self.changeEventHandler(self);}});if(self.$element.filter("label").add(self.$element.find("label")).length > 0){self.$input.on("change",function(){if(self.shouldFireUserChangeEvent && self.enabled){self.changeEventHandler(self);}});}});};FlagSearchFilter.prototype.getUrlParametersFromSelection = function(selection){return selection?requiredModules.util.createSinglePropertyObject(this.filterId,1):{};};FlagSearchFilter.prototype.getValue = function(){return this.enabled && (this.$input?!!this.$input.prop("checked"):this.value);};FlagSearchFilter.prototype.clearSelection = function(){this.setValue(false);};FlagSearchFilter.prototype.getSelectionPromise = function(){ //console.log('FlagSearchFilter');
7619return requiredModules.util.createResolvedPromise(this.getValue());};FlagSearchFilter.prototype.setValue = function(value){var self=this;self.value = value;requiredModules.common.uiReady.then(function(){self.updateUi();});};FlagSearchFilter.prototype.enable = function(){var self=this;self.enabled = true;requiredModules.common.uiReady.then(function(){self.updateUi();});};function BusinessHoursSearchFilter(filterId,uiComponentSelector){this.filterId = filterId;this.uiComponentSelector = uiComponentSelector;this.hour24Filter = new FlagSearchFilter("hour24",uiComponentSelector + " .hour24Class");this.anyFilter = new FlagSearchFilter("any",uiComponentSelector + " .anyBusinessHoursClass");this.weekDaysFilter = new IconListSearchFilter("weekDays",uiComponentSelector + " .week");this.$pickBusinessHours = null;this.startHour = 0;this.endHour = 24;this.shouldFireUserChangeEvent = false;return this;}BusinessHoursSearchFilter.prototype = requiredModules.util.createObject(searchFilterPrototype);BusinessHoursSearchFilter.prototype.constructor = BusinessHoursSearchFilter;BusinessHoursSearchFilter.prototype.initialize = function(){var self=this;function changeEventHandler(filter){if(self.shouldFireUserChangeEvent){self.changeEventHandler(self);}}self.hour24Filter.initialize();self.anyFilter.initialize();self.weekDaysFilter.initialize();var options=_.map(_.zip(_.range(0,7),momentJs.weekdays(),momentJs.weekdaysMin()),function(x){return _.object(["Id","Text","ShortText"],x);});options.push(options.shift());self.weekDaysFilter.setOptions(options,[]);self.hour24Filter.setChangeEventHandler(changeEventHandler);self.anyFilter.setChangeEventHandler(changeEventHandler);self.weekDaysFilter.setChangeEventHandler(changeEventHandler);requiredModules.common.uiReady.then(function(){self.$pickBusinessHours = $(self.uiComponentSelector).find(".pickBusinessHoursClass");self.$pickBusinessHours.on("click",function(event){changeEventHandler(self);});
7619$(self.uiComponentSelector + " .slider-timing").on("slidechange",requiredModules.util.stripType(function(event,ui){self.startHour = parseInt(ui.values[0],10);self.endHour = parseInt(ui.values[1],10);changeEventHandler(self);}));});self.shouldFireUserChangeEvent = true;};BusinessHoursSearchFilter.prototype.clearSelection = function(){var self=this;self.hour24Filter.clearSelection();self.anyFilter.clearSelection();self.weekDaysFilter.clearSelection();self.startHour = 0;self.endHour = 24;requiredModules.common.uiReady.then(function(){self.shouldFireUserChangeEvent = false;requiredModules.util.stripType($(self.uiComponentSelector + " .slider-timing")).slider("values",[self.startHour,self.endHour]);if(self.$pickBusinessHours.hasClass("selected")){self.$pickBusinessHours.trigger("click");}self.shouldFireUserChangeEvent = true;});};BusinessHoursSearchFilter.prototype.getUrlParametersFromSelection = function(){return {};};BusinessHoursSearchFilter.prototype.getSelectionPromise = function(){ //console.log('BusinessHoursSearchFilter');
7620var self=this;var weekDays=this.weekDaysFilter.getSelection();return requiredModules.util.createResolvedPromise(this.hour24Filter.getValue()?requiredModules.util.createArray([0,24],7):this.anyFilter.getValue()?[]:this.$pickBusinessHours && this.$pickBusinessHours.hasClass("selected")?_.map(_.range(7),function(item){return _.contains(weekDays,item)?[self.startHour,self.endHour]:null;}):null);};function ClosestObjectsSearchFilter(filterId,uiComponentSelector,clickHandler){var self=this;self.filterId = filterId;self.enabled = false;self.uiComponentSelector = uiComponentSelector;self.shouldFireUserChangeEvent = false;self.$element = undefined;self.value = false;self.clickHandler = clickHandler;return this;};ClosestObjectsSearchFilter.prototype = requiredModules.util.createObject(searchFilterPrototype);ClosestObjectsSearchFilter.prototype.constructor = ClosestObjectsSearchFilter;ClosestObjectsSearchFilter.prototype.updateUi = function(){var self=this;self.shouldFireUserChangeEvent = false;self.$element.prop("disabled",!self.enabled);if(self.enabled){self.$element.removeClass("disabled");}else {self.$element.addClass("disabled");}self.shouldFireUserChangeEvent = true;};ClosestObjectsSearchFilter.prototype.initialize = function(filterSettings){var self=this;if(filterSettings != null){self.value = filterSettings;}requiredModules.common.uiReady.then(function(){self.$element = $(self.uiComponentSelector);self.updateUi();self.$element.on("click",function(){if(self.shouldFireUserChangeEvent && self.enabled){self.clickHandler();}});});self.enabledStatePromise = requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function(geolocationResult){self.enable();return true;},function(){return requiredModules.util.createResolvedPromise(false);});};ClosestObjectsSearchFilter.prototype.enable = function(){var self=this;self.enabled = true;requiredModules.common.uiReady.then(function(){self.updateUi();});};ClosestObjectsSearchFilter.prototype.setValue = function(value){this.value = value;};ClosestObjectsSearchFilter.prototype.getSelectionPromise = function(){ //console.log('ClosestObjectsSearchFilter');
7621var self=this;return self.enabledStatePromise.then(function(){return self.value;});};ClosestObjectsSearchFilter.prototype.getUrlParametersFromSelection = function(selection){return selection?requiredModules.util.createSinglePropertyObject(this.filterId,1):{};};ClosestObjectsSearchFilter.prototype.clearSelection = function(){this.setValue(false);};ClosestObjectsSearchFilter.prototype.isSelectionSearchingClosest = function(selection){return selection;};function GeographySearchFilter(filterId,uiComponentSelector,enabledStateSourceCallback){var self=this;self.uiComponentSelector = uiComponentSelector;self.text = "";self.lastMapPosition = null;self.enabled = false;self.enabledStateSourceCallback = enabledStateSourceCallback;self.mapSearchControl = undefined;return this;};GeographySearchFilter.prototype = requiredModules.util.createObject(searchFilterPrototype);GeographySearchFilter.prototype.constructor = GeographySearchFilter;GeographySearchFilter.prototype.updateUi = function(){var self=this;self.mapSearchControl.setEnabledState(self.enabled);};GeographySearchFilter.prototype.initialize = function(filterSettings,mapCancellationTokenSource){var self=this;if(filterSettings != null){self.text = filterSettings;}scheduleFilterUiInitialization({},self.uiComponentSelector);self.mapSearchControl = new requiredModules.mapUtil.MapSearchControl(function(inputElement,changeEventCallback,changeEventCallbackIfNotResolving){requiredModules.mapProvider.createAddressSearchInput.apply(requiredModules.mapProvider,arguments);},function(address){if(address){return requiredModules.mapProvider /*googleMapServices*/.ensureMapApiIsReady(GlobalSettings.CurrentLanguage).then(function(){return requiredModules.mapProvider /*googleMapServices*/.geocodingService.getAddressBounds(address);});}else {return requiredModules.util.createRejectedPromise();}},function(){return mapCancellationTokenSource.getCancellationToken();});self.mapSearchControl.setMapPositioningCallback(function(){var center=requiredModules.common.map.getCenter();self.lastMapPosition = {latitude:center.latitude,longitude:center.longitude,zoomLevel:requiredModules.common.map.getZoomLevel()};});requiredModules.common.mapReady.then(function(){self.mapSearchControl.setMap(requiredModules.common.map);});requiredModules.common.uiReady.then(function(){var $container=$(self.uiComponentSelector);var $input=$container.find("input");var $button=$container.find("button");if($input.length !== 1){return;}$input.val(self.text);self.enabled = self.enabledStateSourceCallback();selectAndLoadMapApi().then(function(){self.mapSearchControl.initializeUI($input[0],$button[0]);self.mapSearchControl.setEnabledState(self.enabled);});});};GeographySearchFilter.prototype.getUrlParametersFromSelection = function(selection){return {};};GeographySearchFilter.prototype.getSelectionPromise = function(){ //console.log('GeographySearchFilter');
7622return requiredModules.util.createResolvedPromise(null);};GeographySearchFilter.prototype.updateUiState = function(mapCancellationToken){var self=this;var newEnabledState=self.enabledStateSourceCallback();if(newEnabledState && !self.enabled && self.lastMapPosition != null){requiredModules.common.mapReady.then(function(){if(self.lastMapPosition != null && !mapCancellationToken.isCanceled()){requiredModules.common.map.setCenterAndZoomLevel(self.lastMapPosition.latitude,self.lastMapPosition.longitude,self.lastMapPosition.zoomLevel);}});}self.enabled = newEnabledState;requiredModules.common.uiReady.then(function(){self.updateUi();});};GeographySearchFilter.prototype.clearSelection = function(){var self=this;self.text = "";var cancellationToken=new requiredModules.util.CancellationToken();cancellationToken.cancel();self.mapSearchControl.setAddress("",cancellationToken);self.lastMapPosition = null;};GeographySearchFilter.prototype.setOptions = requiredModules.util.noop;GeographySearchFilter.prototype.resolveAddress = function(mapCancellationToken){var self=this;return self.mapSearchControl.setAddress(self.text,mapCancellationToken);};function CurrentRegionSearchFilter(){return this;};CurrentRegionSearchFilter.prototype = requiredModules.util.createObject(searchFilterPrototype);CurrentRegionSearchFilter.prototype.constructor = CurrentRegionSearchFilter;CurrentRegionSearchFilter.prototype.initialize = requiredModules.util.noop;CurrentRegionSearchFilter.prototype.getUrlParametersFromSelection = function(selection){return selection?requiredModules.util.createSinglePropertyObject("regionPlaceId",selection):{};};CurrentRegionSearchFilter.prototype.setOptions = requiredModules.util.noop;CurrentRegionSearchFilter.prototype.clearSelection = requiredModules.util.noop;CurrentRegionSearchFilter.prototype.getSelectionPromise = function(){ //console.log('CurrentRegionSearchFilter');
7623return geolocationService.getCurrentLocationPlaceIds().then(function(placeIds){return placeIds.regionPlaceId || null;},function(){return requiredModules.util.createResolvedPromise(null);});};function SalePointTypeIdSearchFilter(_salePointTypeId){SalePointTypeIdSearchFilter.prototype.SalePointSt = _salePointTypeId;return this;};SalePointTypeIdSearchFilter.prototype = requiredModules.util.createObject(searchFilterPrototype);
7623SalePointTypeIdSearchFilter.prototype.constructor = SalePointTypeIdSearchFilter;SalePointTypeIdSearchFilter.prototype.initialize = requiredModules.util.noop;SalePointTypeIdSearchFilter.prototype.getUrlParametersFromSelection = function(selection){return selection?requiredModules.util.createSinglePropertyObject("salePointTypeId",selection):{};};SalePointTypeIdSearchFilter.prototype.setOptions = requiredModules.util.noop;SalePointTypeIdSearchFilter.prototype.clearSelection = requiredModules.util.noop;SalePointTypeIdSearchFilter.prototype.getSelectionPromise = function(){ //console.log(this.SalePointSt);
7624return this.SalePointSt; //SalePointStorade.Id;
7625//geolocationService.getCurrentLocationPlaceIds().then(function (placeIds): ?string {
7626//	return placeIds.regionPlaceId || null;
7627//}, function (): _Promise_ {
7628//	return requiredModules.util.createResolvedPromise(null);
7629//});
7630};return {getFilterSelections:getFilterSelections,updateFilterUiState:updateFilterUiState,setFilters:setFilters,SingleValuedListSearchFilter:SingleValuedListSearchFilter,IconListSearchFilter:requiredModules.util.stripType(IconListSearchFilter),FlagSearchFilter:requiredModules.util.stripType(FlagSearchFilter),ClosestObjectsSearchFilter:ClosestObjectsSearchFilter,GeographySearchFilter:GeographySearchFilter,PromotionSearchFilter:PromotionSearchFilter,CurrentRegionSearchFilter:CurrentRegionSearchFilter,SalePointTypeIdSearchFilter:SalePointTypeIdSearchFilter,BusinessHoursSearchFilter:BusinessHoursSearchFilter,CheckboxListSearchFilter:requiredModules.util.stripType(CheckboxListSearchFilter)};})(); // -------------------------- /Filter module -------------------------
7631// -------------------------- Filter block module -------------------------
7632var filterBlockModule=(function(){function FilterBlock(form,filters,languageCode){var self=this;self.languageCode = languageCode;self.form = form;self.filters = filters;self.lastSerialAction = requiredModules.util.getResolvedPromise();_.each(self.filters,function(filter){filter.setChangeEventHandler(self.onFilterChange,self);});return this;};FilterBlock.prototype.scheduleSerialAction = function(callback){var self=this;var last=self.lastSerialAction;var deferred=$.Deferred();self.lastSerialAction = deferred.promise();last.always(function(){callback().always(function(){deferred.resolve();});});};FilterBlock.prototype.onFilterChange = function(changedFilter){var self=this;var mapCancellationToken=self.form.getCancellationToken();self.scheduleSerialAction(function(){var promise=self.updateFilters(changedFilter,mapCancellationToken);promise.then(function(){self.form.scheduleSearch(mapCancellationToken);});return promise;});};FilterBlock.prototype.updateFilters = function(changedFilter,mapCancellationToken){var self=this;filterModule.updateFilterUiState(self.filters,mapCancellationToken);if(changedFilter == null || serverServiceModule.filtersProvider.isFilterAffectingOther(changedFilter.filterId)){return filterModule.getFilterSelections(self.filters).then(function(selections){return requiredModules.common.getCurrentSelectedCountry(self.languageCode).then(function(countryCode){return serverServiceModule.filtersProvider.getFilters(self.form.formId,countryCode,changedFilter && changedFilter.filterId || undefined,selections,self.filters);});}).then(function(newFilters){filterModule.setFilters(self.filters,newFilters);});}else {return requiredModules.util.getResolvedPromise();}};return {FilterBlock:FilterBlock};})(); // -------------------------- /Filter block module ------------------------
7633// -------------------------- Form module -------------------------
7634function initFormModule(noCompanyItemSelectedItemText,noHighwaySelectedItemText,noPostCodeSelectedItemText,noFuelTypesText,noServicesText,noPaymentTypesText,languageCode){function Form(formId,filters){var self=this;this.formId = formId;this.filters = filters;this.searchResultsView = null;this.searchResults = [];this.stabilizedMapProvider = null;this.initializedOnMap = false;this.notShowedResultsYet = true;this.mapCancellationToken = new requiredModules.util.CancellationToken();this.mapCancellationToken.cancel();return this;};Form.prototype.getCancellationToken = function(){return this.mapCancellationToken;};Form.prototype.initialize = function(filterSettings){var self=this;_.each(self.filters,function(filter,filterId){filter.initialize(filterSettings[filterId],self);});requiredModules.common.uiReady.then(function(){uiModule.getFormResetFiltersButton(self.formId).on("click",function(event){event.preventDefault();self.resetFilters();});self.searchResultsView = new requiredModules.searchResults.SearchResultsView(uiModule.getFormContainerSelector(self.formId),"user",uiModule.searchResultsHeadingContainerSelector);});self.filterBlock = new filterBlockModule.FilterBlock(self,self.filters,languageCode);self.doInitialize();};
7634Form.prototype.initializeOnMap = function(mapCancellationToken){var self=this;requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function(geolocationResult){if(geolocationResult.location && geolocationResult.location.lat != null && geolocationResult.location.lng != null){requiredModules.common.map.putUserPositionMarkerOnMap(geolocationResult.location.lat,geolocationResult.location.lng,requiredModules.common.getUserPositionIconUrl(self.formId));}});self.filterBlock.scheduleSerialAction(function(){function handleNoGeosearch(){var closestFilter=self.filters[globals.consts.filterIds.closestObjects];if(closestFilter){return closestFilter.getSelectionPromise().then(function(isSearchingClosest){return isSearchingClosest?null:self.initializeDefaultMap(mapCancellationToken);});}else {return self.initializeDefaultMap(mapCancellationToken);}};function updateFilters(){return self.filterBlock.updateFilters(null,mapCancellationToken);}return (function(){var geosearchFilter=self.filters[globals.consts.filterIds.geography];if(geosearchFilter){return geosearchFilter.resolveAddress(mapCancellationToken).then(function(){var closestFilter=self.filters[globals.consts.filterIds.closestObjects];if(closestFilter){closestFilter.setValue(false);}return null;},handleNoGeosearch);}else {return handleNoGeosearch();}})().then(updateFilters,updateFilters).always(function(){self.scheduleSearch(mapCancellationToken);});});};Form.prototype.setListSearchResults = function(searchResults,mapCancellationToken){var self=this;if(!mapCancellationToken.isCanceled()){var bounds=requiredModules.common.map.getSpanBounds();if(bounds){self.searchResultsView.setListSearchResults(requiredModules.search.filterObjectsByGeographyBounds(searchResults,bounds));}}};Form.prototype.showFirstResultsOnMap = function(items,mapCancellationToken,infoWindowContentCallback,onMarkerClickCallback){var self=this;if(self.isClusteringMarkers){requiredModules.common.map.setClusterMarkers(items,infoWindowContentCallback,onMarkerClickCallback);}else {requiredModules.common.map.setMarkers(items,infoWindowContentCallback,onMarkerClickCallback);}};Form.prototype.setSearchResults = function(searchResults,mapCancellationToken,notShowedResultsYet){var self=this;self.searchResults = searchResults;requiredModules.common.mapReady.then(function(){self.searchResultsView.setMapSearchResults(searchResults,function(items,infoWindowContentElementCallback,onMarkerClickCallback){if(!mapCancellationToken.isCanceled()){if(notShowedResultsYet){self.showFirstResultsOnMap(items,mapCancellationToken,infoWindowContentElementCallback,onMarkerClickCallback);if(!self.notShowedResultsYet){uiModule.hideLoadingOverlay();}}else {Form.prototype.showFirstResultsOnMap.call(self,items,mapCancellationToken,infoWindowContentElementCallback,onMarkerClickCallback);}}});if(!mapCancellationToken.isCanceled()){self.stabilizedMapProvider.scheduleStabilizationHandling();}});};Form.prototype.positionMapToClosestObjects = function(mapCancellationToken){var self=this;$.when(requiredModules.common.mapReady.promise(),requiredModules.mapUtil.userLocationProvider.getCurrentLocation()).then(function(_1,geolocationResult){if(!mapCancellationToken.isCanceled()){var points=_.map(requiredModules.search.getClosestObjects(self.searchResults),function(x){return {latitude:x.Latitude,longitude:x.Longitude};});requiredModules.common.map.setCenterAndZoomForAllPoints({latitude:geolocationResult.location.lat,longitude:geolocationResult.location.lng},points,mapCancellationToken);}});};Form.prototype.positionMapToClosestObjectsWithoutLocation = function(mapCancellationToken){var self=this;var points=_.map(requiredModules.search.getClosestObjects(self.searchResults),function(x){return {latitude:x.Latitude,longitude:x.Longitude};});requiredModules.common.map.setCenterAndZoomForAllPoints(null,points,mapCancellationToken);};Form.prototype.search = function(mapCancellationToken){var self=this;requiredModules.common.uiReady.then(function(){self.searchResultsView.setListSearchResultsToPending();filterModule.updateFilterUiState(self.filters,mapCancellationToken);filterModule.getFilterSelections(self.filters).then(function(selections){var s=selections;requiredModules.search.search(self.formId,s).then(function(searchResults){var notShowedResultsYet=self.notShowedResultsYet;self.notShowedResultsYet = false;self.setSearchResults(searchResults,mapCancellationToken,notShowedResultsYet);var closestObjectFilter=self.filters[globals.consts.filterIds.closestObjects];if(notShowedResultsYet && closestObjectFilter && closestObjectFilter.isSelectionSearchingClosest(selections[globals.consts.filterIds.closestObjects])){self.positionMapToClosestObjects(mapCancellationToken);} // cratch
7635else if(!notShowedResultsYet && self.filters.postCode !== undefined && self.filters.postCode.model.selectedId){self.positionMapToClosestObjectsWithoutLocation(mapCancellationToken);}});});});};Form.prototype.scheduleSearch = function(mapCancellationToken){var self=this;self.filterBlock.lastSerialAction.then(function(){self.search(mapCancellationToken);});};Form.prototype.initializeMap = function(){var self=this;var mapCancellationToken=self.getCancellationToken();self.stabilizedMapProvider = new requiredModules.mapUtil.StabilizedMapProvider(requiredModules.common.map,uiModule.mapStabilizationWaitInMilliseconds,function(){self.searchResultsView.setListSearchResultsToPending();},function(){self.setListSearchResults(self.searchResults,mapCancellationToken);savedMapPositionModule.saveMapPosition(requiredModules.mapProvider,requiredModules.common.map.getCenter(),requiredModules.common.map.getZoomLevel());});self.setSearchResults(self.searchResults,mapCancellationToken,self.notShowedResultsYet);};Form.prototype.clearMap = function(){var self=this;self.stabilizedMapProvider.destroy();self.mapCancellationToken.cancel();requiredModules.common.map.setClusterMarkers([]);};Form.prototype.show = function(isFirstShownForm){var self=this;var newMapCancellationToken=new requiredModules.util.CancellationToken();if(isFirstShownForm){self.mapCancellationToken = newMapCancellationToken;}if(!self.initializedOnMap){self.initializedOnMap = true;
7635self.initializeOnMap(self.getCancellationToken());}self.mapCancellationToken = newMapCancellationToken;$.when(requiredModules.common.mapReady.promise(),requiredModules.common.uiReady.promise()).then(function(){self.initializeMap();});};Form.prototype.hide = function(){var self=this;$.when(requiredModules.common.mapReady.promise(),requiredModules.common.uiReady.promise()).then(function(){self.clearMap();});};Form.prototype.resetFilters = function(){var self=this;_.each(self.filters,function(filter,filterId){filter.clearSelection();});self.filterBlock.onFilterChange(null);};function handleNoCountry(mapCancellationToken){return requiredModules.common.mapReady.then(function(){if(!mapCancellationToken.isCanceled()){requiredModules.common.map.fitBounds(defaultMapBounds.minLatitude,defaultMapBounds.maxLatitude,defaultMapBounds.leftLongitude,defaultMapBounds.rightLongitude);}});};function initializeMapWithCountry(mapCancellationToken){return geolocationService.getCurrentSelectedCountryBounds().then(function(bounds){return requiredModules.common.mapReady.then(function(){if(!mapCancellationToken.isCanceled()){requiredModules.common.map.fitBounds(bounds.minLatitude,bounds.maxLatitude,bounds.leftLongitude,bounds.rightLongitude);}});},function(){handleNoCountry(mapCancellationToken);});};function initializeMapWithWorld(mapCancellationToken){var worldBounds={minLatitude:-70,maxLatitude:70,leftLongitude:-179,rightLongitude:179};return requiredModules.common.mapReady.then(function(){if(!mapCancellationToken.isCanceled()){requiredModules.common.map.fitBounds(worldBounds.minLatitude,worldBounds.maxLatitude,worldBounds.leftLongitude,worldBounds.rightLongitude);}});}function GasStationForm(filters){Form.call(this,requiredModules.common.consts.formIds.gasStation,filters);}GasStationForm.prototype = requiredModules.util.createObject(Form.prototype);GasStationForm.prototype.constructor = GasStationForm;GasStationForm.prototype.initializeDefaultMap = initializeMapWithCountry;GasStationForm.prototype.isClusteringMarkers = true;GasStationForm.prototype.doInitialize = function(){ensureGasStationSearchInitialized();};function OilSellerForm(filters){Form.call(this,requiredModules.common.consts.formIds.oilSeller,filters);}OilSellerForm.prototype = requiredModules.util.createObject(Form.prototype);OilSellerForm.prototype.constructor = OilSellerForm;OilSellerForm.prototype.initializeDefaultMap = initializeMapWithCountry;OilSellerForm.prototype.isClusteringMarkers = true;OilSellerForm.prototype.doInitialize = function(){var self=this;function OilSeller(serverOilSeller,iconUrl,userLocation){this.linkedGasStationId = serverOilSeller.LinkedGasStationId; //this.GasStationStatus = serverOilSeller.GasStationStatus;
7636this.Latitude = serverOilSeller.Latitude;this.Longitude = serverOilSeller.Longitude;this.IconUrl = iconUrl;this.name = serverOilSeller.Name;this.promotionBits = serverOilSeller.Promotions;this.genesisFlag = serverOilSeller.GenesisFlag;this.luxeFlag = serverOilSeller.LuxeFlag;this.open24Hours = serverOilSeller.IsOpen24Hours;this.cto = serverOilSeller.IsCTO;this.distanceFromUser = userLocation?requiredModules.googleMapServices.computeGeographicalDistanceInMeters(this.Latitude,this.Longitude,userLocation.latitude,userLocation.longitude):null;if(this.linkedGasStationId != null){this.idPropertyName = "linkedGasStationId";this.type = requiredModules.search.objectTypes.gasStation;}else {this.oilSellerId = serverOilSeller.OilSellerId;this.idPropertyName = "oilSellerId";this.type = requiredModules.search.objectTypes.oilSeller;}}function OilSellerSearchData(serverOilSellerData,userLocation){this.promotions = serverOilSellerData.Promotions;this.oilSellers = _.map(serverOilSellerData.OilSellers,function(gs){return new OilSeller(gs,gs.IconUrl,userLocation);});}var p1=serverServiceModule.objectsProvider.getObjects(self.formId);var p2=requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function(geolocationResult){return geolocationResult.location && geolocationResult.location.lat != null && geolocationResult.location.lng != null?{latitude:geolocationResult.location.lat,longitude:geolocationResult.location.lng}:null;},function(){return requiredModules.util.createResolvedPromise(null);});var p3=requiredModules.googleMapServices.ensureMapApiIsReady(languageCode).promise();$.when(p1,p2,p3).then(function(serverOilSellerData,userLocation,_3){var data=new OilSellerSearchData(serverOilSellerData,userLocation);data.oilSellers.sort(function(a,b){var ea=!!a.name,eb=!!b.name;return ea === eb?ea && a.name.localeCompare(b.name) || 0:ea?-1:1;});requiredModules.search.initializeForObjectType(self.formId,data,searchSettingsModule.closestObjectMarginPercent);});};function SalePointForm(filters){Form.call(this,requiredModules.common.consts.formIds.salePoint,filters);}SalePointForm.prototype = requiredModules.util.createObject(Form.prototype);
7636SalePointForm.prototype.constructor = SalePointForm;SalePointForm.prototype.initializeDefaultMap = initializeMapWithCountry;SalePointForm.prototype.isClusteringMarkers = true;SalePointForm.prototype.doInitialize = function(){var self=this;function SalePoint(serverSalePoint,iconUrl,userLocation){ //this.linkedGasStationId = serverOilSeller.LinkedGasStationId;
7637//this.GasStationStatus = serverOilSeller.GasStationStatus;
7638this.Latitude = serverSalePoint.Latitude;this.Longitude = serverSalePoint.Longitude;this.IconUrl = iconUrl;this.name = serverSalePoint.Name;this.roadServiceBits = serverSalePoint.RoadServices;this.cardTypeBits = serverSalePoint.CardTypes;this.postCode = serverSalePoint.PostCode; //this.genesisFlag = serverOilSeller.GenesisFlag;
7639//this.luxeFlag = serverOilSeller.LuxeFlag;
7640//this.open24Hours = serverOilSeller.IsOpen24Hours;
7641//this.cto = serverOilSeller.IsCTO;
7642this.distanceFromUser = userLocation?requiredModules.googleMapServices.computeGeographicalDistanceInMeters(this.Latitude,this.Longitude,userLocation.latitude,userLocation.longitude):null; //if (this.linkedGasStationId != null) {
7643//	this.idPropertyName = "linkedGasStationId";
7644//	this.type = requiredModules.search.objectTypes.gasStation;
7645//} else {
7646this.salePointId = serverSalePoint.SalePointId;this.idPropertyName = "salePointId";this.type = requiredModules.search.objectTypes.salePoint; //}
7647}function SalePointSearchData(serverSalePointData,userLocation){this.roadServices = serverSalePointData.RoadServices;this.cardTypes = serverSalePointData.CardTypes;this.salePoints = _.map(serverSalePointData.SalePoints,function(gs){return new SalePoint(gs,gs.IconUrl,userLocation);});}var p1=serverServiceModule.objectsProvider.getObjects(self.formId);var p2=requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function(geolocationResult){return geolocationResult.location && geolocationResult.location.lat != null && geolocationResult.location.lng != null?{latitude:geolocationResult.location.lat,longitude:geolocationResult.location.lng}:null;},function(){return requiredModules.util.createResolvedPromise(null);});var p3=requiredModules.googleMapServices.ensureMapApiIsReady(languageCode).promise();$.when(p1,p2,p3).then(function(serverSalePointData,userLocation,_3){var data=new SalePointSearchData(serverSalePointData,userLocation);data.salePoints.sort(function(a,b){var ea=!!a.name,eb=!!b.name;return ea === eb?ea && a.name.localeCompare(b.name) || 0:ea?-1:1;});requiredModules.search.initializeForObjectType(self.formId,data,searchSettingsModule.closestObjectMarginPercent);});};function SeaportForm(filters){Form.call(this,requiredModules.common.consts.formIds.seaport,filters);}SeaportForm.prototype = requiredModules.util.createObject(Form.prototype);SeaportForm.prototype.constructor = SeaportForm;SeaportForm.prototype.isClusteringMarkers = false;SeaportForm.prototype.initializeDefaultMap = initializeMapWithWorld;SeaportForm.prototype.showFirstResultsOnMap = function(items,mapCancellationToken,infoWindowContentCallback,onMarkerClickCallback){requiredModules.common.map.setMarkersAndMakeThemFit(items,infoWindowContentCallback,onMarkerClickCallback);};SeaportForm.prototype.doInitialize = function(){var self=this;function Seaport(serverSeaport,iconUrl){this.seaportId = serverSeaport.SeaportId;this.Latitude = serverSeaport.Latitude;this.Longitude = serverSeaport.Longitude;this.name = serverSeaport.Name;this.isBunkeringFuel = serverSeaport.IsBunkeringFuel;this.isBunkeringOil = serverSeaport.IsBunkeringOil;this.fuelingCompanyId = serverSeaport.FuelingCompanyId;this.oilingCompanyId = serverSeaport.OilingCompanyId;this.IconUrl = iconUrl;}Seaport.prototype.idPropertyName = "seaportId";Seaport.prototype.type = requiredModules.search.objectTypes.seaport;function getSeaportSearchData(serverSeaportData){return _.map(serverSeaportData.Seaports,function(a){return new Seaport(a,serverSeaportData.IconUrl);});}serverServiceModule.objectsProvider.getObjects(self.formId).then(function(serverSeaportData){var data=getSeaportSearchData(serverSeaportData);data.sort(function(a,b){var ea=!!a.name,eb=!!b.name;return ea === eb?ea && a.name.localeCompare(b.name) || 0:ea?-1:1;});requiredModules.search.initializeForObjectType(self.formId,data,searchSettingsModule.closestObjectMarginPercent);});};function SeaportOilForm(filters){Form.call(this,requiredModules.common.consts.formIds.seaportOil,filters);}SeaportOilForm.prototype = requiredModules.util.createObject(Form.prototype);SeaportOilForm.prototype.constructor = SeaportOilForm;SeaportOilForm.prototype.isClusteringMarkers = false;SeaportOilForm.prototype.initializeDefaultMap = initializeMapWithWorld;SeaportOilForm.prototype.showFirstResultsOnMap = function(items,mapCancellationToken,infoWindowContentCallback,onMarkerClickCallback){requiredModules.common.map.setMarkersAndMakeThemFit(items,infoWindowContentCallback,onMarkerClickCallback);};SeaportOilForm.prototype.doInitialize = function(){var self=this;function Seaport(serverSeaport,iconUrl){this.seaportId = serverSeaport.SeaportId;this.Latitude = serverSeaport.Latitude;this.Longitude = serverSeaport.Longitude;this.name = serverSeaport.Name;this.isBunkeringFuel = serverSeaport.IsBunkeringFuel;this.isBunkeringOil = serverSeaport.IsBunkeringOil;this.fuelingCompanyId = serverSeaport.FuelingCompanyId;this.oilingCompanyId = serverSeaport.OilingCompanyId;this.IconUrl = iconUrl;}Seaport.prototype.idPropertyName = "seaportId";Seaport.prototype.type = requiredModules.search.objectTypes.seaport;function getSeaportSearchData(serverSeaportData){return _.map(serverSeaportData.Seaports,function(a){return new Seaport(a,serverSeaportData.IconUrl);});}serverServiceModule.objectsProvider.getObjects(self.formId).then(function(serverSeaportData){var data=getSeaportSearchData(serverSeaportData);data.sort(function(a,b){var ea=!!a.name,eb=!!b.name;return ea === eb?ea && a.name.localeCompare(b.name) || 0:ea?-1:1;});requiredModules.search.initializeForObjectType(self.formId,data,searchSettingsModule.closestObjectMarginPercent);});};function AirportForm(filters){Form.call(this,requiredModules.common.consts.formIds.airport,filters);}AirportForm.prototype = requiredModules.util.createObject(Form.prototype);AirportForm.prototype.constructor = AirportForm;AirportForm.prototype.isClusteringMarkers = false;AirportForm.prototype.initializeDefaultMap = initializeMapWithWorld;AirportForm.prototype.showFirstResultsOnMap = function(items,mapCancellationToken,infoWindowContentCallback,onMarkerClickCallback){requiredModules.common.map.setMarkersAndMakeThemFit(items,infoWindowContentCallback,onMarkerClickCallback);};AirportForm.prototype.doInitialize = function(){var self=this;function Airport(serverAirport,iconUrl){this.airportId = serverAirport.AirportId;this.Latitude = serverAirport.Latitude;this.Longitude = serverAirport.Longitude;this.name = serverAirport.Name;this.IconUrl = iconUrl;}Airport.prototype.idPropertyName = "airportId";Airport.prototype.type = requiredModules.search.objectTypes.airport;function getAirportSearchData(serverAirportData){return _.map(serverAirportData.Airports,function(a){return new Airport(a,serverAirportData.IconUrl);});}serverServiceModule.objectsProvider.getObjects(self.formId).then(function(serverAirportData){var data=getAirportSearchData(serverAirportData);data.sort(function(a,b){var ea=!!a.name,eb=!!b.name;return ea === eb?ea && a.name.localeCompare(b.name) || 0:ea?-1:1;});requiredModules.search.initializeForObjectType(self.formId,data,searchSettingsModule.closestObjectMarginPercent);});};function TankFarmForm(filters){Form.call(this,requiredModules.common.consts.formIds.tankFarm,filters);}TankFarmForm.prototype = requiredModules.util.createObject(Form.prototype);TankFarmForm.prototype.constructor = TankFarmForm;TankFarmForm.prototype.isClusteringMarkers = false;TankFarmForm.prototype.initializeDefaultMap = initializeMapWithWorld;TankFarmForm.prototype.showFirstResultsOnMap = function(items,mapCancellationToken,infoWindowContentCallback,onMarkerClickCallback){requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function(geolocationResult){if(!mapCancellationToken.isCanceled()){var points=_.map(requiredModules.search.getClosestObjects(items),function(x){return {latitude:x.Latitude,longitude:x.Longitude};});requiredModules.common.map.setCenterAndZoomForAllPoints({latitude:geolocationResult.location.lat,longitude:geolocationResult.location.lng},points,mapCancellationToken).always(function(){if(!mapCancellationToken.isCanceled()){requiredModules.common.map.setMarkers(items,infoWindowContentCallback,onMarkerClickCallback);}});}},function(){if(!mapCancellationToken.isCanceled()){requiredModules.common.map.setMarkers(items,infoWindowContentCallback,onMarkerClickCallback);}});};TankFarmForm.prototype.doInitialize = function(){var self=this;function TankFarm(serverTankFarm,iconUrl,userLocation){this.tankFarmId = serverTankFarm.TankFarmId;this.Latitude = serverTankFarm.Latitude;this.Longitude = serverTankFarm.Longitude;
7647this.name = serverTankFarm.Name;this.companyId = serverTankFarm.CompanyId;this.IconUrl = iconUrl;this.distanceFromUser = userLocation?requiredModules.googleMapServices.computeGeographicalDistanceInMeters(this.Latitude,this.Longitude,userLocation.latitude,userLocation.longitude):null;this.typeFilling = serverTankFarm.TypeFilling;this.shippingMethod = serverTankFarm.ShippingMethod;this.tankFarmFuel = serverTankFarm.TankFarmFuel;this.tankFarmBusinessHours = serverTankFarm.BusinessHours;}TankFarm.prototype.idPropertyName = "tankFarmId";TankFarm.prototype.type = requiredModules.search.objectTypes.tankFarm;function getTankFarmSearchData(serverTankFarmData,userLocation){return _.map(serverTankFarmData.TankFarms,function(a){return new TankFarm(a,serverTankFarmData.IconUrl,userLocation);});}var p1=requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function(geolocationResult){return geolocationResult.location && geolocationResult.location.lat != null && geolocationResult.location.lng != null?{latitude:geolocationResult.location.lat,longitude:geolocationResult.location.lng}:null;},function(){return requiredModules.util.createResolvedPromise(null);});var p2=requiredModules.googleMapServices.ensureMapApiIsReady(languageCode).promise();$.when(serverServiceModule.objectsProvider.getObjects(self.formId),p1,p2).then(function(serverTankFarmData,userLocation,_){var data=getTankFarmSearchData(serverTankFarmData,userLocation);data.sort(function(a,b){var ea=!!a.name,eb=!!b.name;return ea === eb?ea && a.name.localeCompare(b.name) || 0:ea?-1:1;});requiredModules.search.initializeForObjectType(self.formId,data,searchSettingsModule.closestObjectMarginPercent);});};function LegalEntitiesForm(filters){Form.call(this,requiredModules.common.consts.formIds.legalEntities,filters);}LegalEntitiesForm.prototype = requiredModules.util.createObject(Form.prototype);LegalEntitiesForm.prototype.constructor = LegalEntitiesForm;LegalEntitiesForm.prototype.isClusteringMarkers = false;LegalEntitiesForm.prototype.initializeDefaultMap = initializeMapWithWorld;LegalEntitiesForm.prototype.showFirstResultsOnMap = TankFarmForm.prototype.showFirstResultsOnMap;LegalEntitiesForm.prototype.doInitialize = function(){var self=this;function LegalEntities(serverLegalEntity,iconUrl,userLocation){this.legalEntityId = serverLegalEntity.ID;this.Latitude = serverLegalEntity.Latitude;this.Longitude = serverLegalEntity.Longitude;this.Number = serverLegalEntity.Number;this.Address = serverLegalEntity.Address;this.ServiceIds = serverLegalEntity.ServiceIds || [];this.FuelIds = serverLegalEntity.FuelIds || [];this.PropertyIds = serverLegalEntity.PropertyIds || [];this.CardTypeIds = serverLegalEntity.CardTypeIds || [];this.name = serverLegalEntity.BrandName || String(serverLegalEntity.Number);this.IconUrl = serverLegalEntity.IconUrl || iconUrl;this.distanceFromUser = userLocation?requiredModules.googleMapServices.computeGeographicalDistanceInMeters(this.Latitude,this.Longitude,userLocation.latitude,userLocation.longitude):null;}LegalEntities.prototype.idPropertyName = "legalEntityId";LegalEntities.prototype.type = requiredModules.search.objectTypes.legalEntities;function getLegalEntitiesSearchData(serverLegalEntitiesData,userLocation){return _.map(serverLegalEntitiesData.LegalEntities,function(a){return new LegalEntities(a,serverLegalEntitiesData.IconUrl,userLocation);});}var p1=requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function(geolocationResult){return geolocationResult.location && geolocationResult.location.lat != null && geolocationResult.location.lng != null?{latitude:geolocationResult.location.lat,longitude:geolocationResult.location.lng}:null;},function(){return requiredModules.util.createResolvedPromise(null);});var p2=requiredModules.googleMapServices.ensureMapApiIsReady(languageCode).promise();$.when(serverServiceModule.objectsProvider.getObjects(self.formId),p1,p2).then(function(serverLegalEntitiesData,userLocation,_){var data=getLegalEntitiesSearchData(serverLegalEntitiesData,userLocation);data.sort(function(a,b){var ea=!!a.name,eb=!!b.name;return ea === eb?ea && a.name.localeCompare(b.name) || 0:ea?-1:1;});requiredModules.search.initializeForObjectType(self.formId,data,searchSettingsModule.closestObjectMarginPercent);});};var formsById=(function(){var gasStationFilters=requiredModules.util.createObject(null);var oilSellerFilters=requiredModules.util.createObject(null);var salePointFilters=requiredModules.util.createObject(null);var airportFilters=requiredModules.util.createObject(null);var seaportFilters=requiredModules.util.createObject(null);var seaportOilFilters=requiredModules.util.createObject(null);var tankFarmFilters=requiredModules.util.createObject(null);var legalEntitiesFilters=requiredModules.util.createObject(null);var formsById=requiredModules.util.createObject(null);formsById[requiredModules.common.consts.formIds.gasStation] = new GasStationForm(gasStationFilters);formsById[requiredModules.common.consts.formIds.oilSeller] = new OilSellerForm(oilSellerFilters);formsById[requiredModules.common.consts.formIds.salePoint] = new SalePointForm(salePointFilters);formsById[requiredModules.common.consts.formIds.airport] = new AirportForm(
7647airportFilters);formsById[requiredModules.common.consts.formIds.seaport] = new SeaportForm(seaportFilters);formsById[requiredModules.common.consts.formIds.tankFarm] = new TankFarmForm(tankFarmFilters);formsById[requiredModules.common.consts.formIds.legalEntities] = new LegalEntitiesForm(legalEntitiesFilters);formsById[requiredModules.common.consts.formIds.seaportOil] = new SeaportOilForm(seaportOilFilters);formsById[requiredModules.common.consts.formIds.route] = {formId:requiredModules.common.consts.formIds.route,mapCancellationToken:null,getCancellationToken:function getCancellationToken(){return this.mapCancellationToken;},initialize:function initialize(){ensureGasStationSearchInitialized();},initializeOnMap:function initializeOnMap(mapCancellationToken){try{requiredModules.routing.initializeOnMap(mapCancellationToken && !mapCancellationToken.isCanceled());}catch(e) {if(global.console){global.console.error(e.message);global.console.error(e.stack);}else {uiModule.logErrorToDom(e);}}},initializeMap:function initializeMap(){try{requiredModules.routing.putObjectsOnMap();}catch(e) {if(global.console){global.console.error(e.message);global.console.error(e.stack);}else {uiModule.logErrorToDom(e);}}},clearMap:function clearMap(){try{requiredModules.routing.clearObjectsFromMap();}catch(e) {if(global.console){global.console.error(e.message);global.console.error(e.stack);}else {uiModule.logErrorToDom(e);}}},show:Form.prototype.show,hide:Form.prototype.hide};gasStationFilters[globals.consts.filterIds.postCode] = new filterModule.SingleValuedListSearchFilter(globals.consts.filterIds.postCode,noPostCodeSelectedItemText,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.postCode));gasStationFilters[globals.consts.filterIds.highway] = new filterModule.SingleValuedListSearchFilter(globals.consts.filterIds.highway,noHighwaySelectedItemText,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.highway));gasStationFilters[globals.consts.filterIds.sellsOil] = new filterModule.FlagSearchFilter(globals.consts.filterIds.sellsOil,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.sellsOil));gasStationFilters[globals.consts.filterIds.fuelType] = new filterModule.IconListSearchFilter(globals.consts.filterIds.fuelType,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.fuelType),noFuelTypesText);gasStationFilters[globals.consts.filterIds.paymentType] = new filterModule.CheckboxListSearchFilter(globals.consts.filterIds.paymentType,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.paymentType),true,noPaymentTypesText);gasStationFilters[globals.consts.filterIds.promotion] = new filterModule.PromotionSearchFilter(globals.consts.filterIds.promotion,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.promotion),"#gasLocatorActionModal");gasStationFilters[globals.consts.filterIds.service] = new filterModule.IconListSearchFilter(globals.consts.filterIds.service,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.service),noServicesText);gasStationFilters[globals.consts.filterIds.property] = new filterModule.IconListSearchFilter(globals.consts.filterIds.property,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.property));gasStationFilters[globals.consts.filterIds.closestObjects] = new filterModule.ClosestObjectsSearchFilter(globals.consts.filterIds.closestObjects,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,"closestObjects"),function(){var form=formsById[requiredModules.common.consts.formIds.gasStation];form.positionMapToClosestObjects(form.getCancellationToken());});gasStationFilters[globals.consts.filterIds.gasStationBusinessHours] = new filterModule.BusinessHoursSearchFilter(globals.consts.filterIds.gasStationBusinessHours,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.gasStationBusinessHours));gasStationFilters[globals.consts.filterIds.storeBusinessHours] = new filterModule.BusinessHoursSearchFilter(globals.consts.filterIds.storeBusinessHours,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.storeBusinessHours));gasStationFilters[globals.consts.filterIds.currentRegion] = new filterModule.CurrentRegionSearchFilter();gasStationFilters[globals.consts.filterIds.geography] = new filterModule.GeographySearchFilter(globals.consts.filterIds.geography,ui
7647Module.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.geography),function(){return true;});oilSellerFilters[globals.consts.filterIds.promotion] = new filterModule.PromotionSearchFilter(globals.consts.filterIds.promotion,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.oilSeller,globals.consts.filterIds.promotion),"#gasLocatorActionModal");oilSellerFilters[globals.consts.filterIds.closestObjects] = new filterModule.ClosestObjectsSearchFilter(globals.consts.filterIds.closestObjects,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.oilSeller,"closestObjects"),function(){var form=formsById[requiredModules.common.consts.formIds.oilSeller];form.positionMapToClosestObjects(form.getCancellationToken());});oilSellerFilters[globals.consts.filterIds.twentyFourHour] = new filterModule.FlagSearchFilter(globals.consts.filterIds.twentyFourHour,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.oilSeller,globals.consts.filterIds.twentyFourHour));oilSellerFilters[globals.consts.filterIds.CTO] = new filterModule.FlagSearchFilter(globals.consts.filterIds.CTO,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.oilSeller,globals.consts.filterIds.CTO));oilSellerFilters[globals.consts.filterIds.luxeOil] = new filterModule.FlagSearchFilter(globals.consts.filterIds.luxeOil,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.oilSeller,globals.consts.filterIds.luxeOil));oilSellerFilters[globals.consts.filterIds.genesisOil] = new filterModule.FlagSearchFilter(globals.consts.filterIds.genesisOil,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.oilSeller,globals.consts.filterIds.genesisOil));oilSellerFilters[globals.consts.filterIds.currentRegion] = new filterModule.CurrentRegionSearchFilter();oilSellerFilters[globals.consts.filterIds.geography] = new filterModule.GeographySearchFilter(globals.consts.filterIds.geography,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.oilSeller,globals.consts.filterIds.geography),function(){return true;});salePointFilters[globals.consts.filterIds.postCode] = new filterModule.SingleValuedListSearchFilter(globals.consts.filterIds.postCode,noPostCodeSelectedItemText,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.gasStation,globals.consts.filterIds.postCode));salePointFilters[globals.consts.filterIds.roadService] = new filterModule.IconListSearchFilter(globals.consts.filterIds.roadService,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.salePoint,globals.consts.filterIds.roadService),noServicesText);salePointFilters[globals.consts.filterIds.cardType] = new filterModule.IconListSearchFilter(globals.consts.filterIds.cardType,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.salePoint,globals.consts.filterIds.cardType),noServicesText);salePointFilters[globals.consts.filterIds.closestObjects] = new filterModule.ClosestObjectsSearchFilter(globals.consts.filterIds.closestObjects,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.salePoint,"closestObjects"),function(){var form=formsById[requiredModules.common.consts.formIds.salePoint];form.positionMapToClosestObjects(form.getCancellationToken());});salePointFilters[globals.consts.filterIds.salePointTypeId] = new filterModule.SalePointTypeIdSearchFilter(SalePointStorade.Id); //salePointFilters[globals.consts.filterIds.twentyFourHour] = new filterModule.FlagSearchFilter(
7648//	globals.consts.filterIds.twentyFourHour,
7649//	uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.salePoint, globals.consts.filterIds.twentyFourHour));
7650//salePointFilters[globals.consts.filterIds.CTO] = new filterModule.FlagSearchFilter(
7651//	globals.consts.filterIds.CTO,
7652//	uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.salePoint, globals.consts.filterIds.CTO));
7653//salePointFilters[globals.consts.filterIds.luxeOil] = new filterModule.FlagSearchFilter(
7654//	globals.consts.filterIds.luxeOil,
7655//	uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.salePoint, globals.consts.filterIds.luxeOil));
7656//salePointFilters[globals.consts.filterIds.genesisOil] = new filterModule.FlagSearchFilter(
7657//	globals.consts.filterIds.genesisOil,
7658//	uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.salePoint, globals.consts.filterIds.genesisOil));
7659salePointFilters[globals.consts.filterIds.currentRegion] = new filterModule.CurrentRegionSearchFilter();salePointFilters[globals.consts.filterIds.geography] = new filterModule.GeographySearchFilter(globals.consts.filterIds.geography,ui
7659Module.getFormFilterSelector(requiredModules.common.consts.formIds.salePoint,globals.consts.filterIds.geography),function(){return true;});airportFilters[globals.consts.filterIds.geography] = new filterModule.GeographySearchFilter(globals.consts.filterIds.geography,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.airport,globals.consts.filterIds.geography),function(){return true;});seaportFilters[globals.consts.filterIds.geography] = new filterModule.GeographySearchFilter(globals.consts.filterIds.geography,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.seaport,globals.consts.filterIds.geography),function(){return true;});seaportOilFilters[globals.consts.filterIds.geography] = new filterModule.GeographySearchFilter(globals.consts.filterIds.geography,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.seaportOil,globals.consts.filterIds.geography),function(){return true;}); /*
7660			seaportFilters[globals.consts.filterIds.oilBunkering] = new filterModule.FlagSearchFilter(
7661							globals.consts.filterIds.oilBunkering,
7662							uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.seaport, globals.consts.filterIds.oilBunkering));
7663			seaportFilters[globals.consts.filterIds.fuelBunkering] = new filterModule.FlagSearchFilter(
7664							globals.consts.filterIds.fuelBunkering,
7665							uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.seaport, globals.consts.filterIds.fuelBunkering));
7666*/seaportFilters[globals.consts.filterIds.company] = new filterModule.SingleValuedListSearchFilter(globals.consts.filterIds.company,noCompanyItemSelectedItemText,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.seaport,globals.consts.filterIds.company));tankFarmFilters[globals.consts.filterIds.geography] = new filterModule.GeographySearchFilter(globals.consts.filterIds.geography,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.tankFarm,globals.consts.filterIds.geography),function(){return true;});tankFarmFilters[globals.consts.filterIds.company] = new filterModule.SingleValuedListSearchFilter(globals.consts.filterIds.company,noCompanyItemSelectedItemText,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.tankFarm,globals.consts.filterIds.company));legalEntitiesFilters[globals.consts.filterIds.geography] = new filterModule.GeographySearchFilter(globals.consts.filterIds.geography,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.legalEntities,globals.consts.filterIds.geography),function(){return true;});legalEntitiesFilters[globals.consts.filterIds.service] = new filterModule.IconListSearchFilter(globals.consts.filterIds.service,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.legalEntities,globals.consts.filterIds.service),noServicesText);legalEntitiesFilters[globals.consts.filterIds.fuelType] = new filterModule.IconListSearchFilter(globals.consts.filterIds.fuelType,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.legalEntities,globals.consts.filterIds.fuelType),noFuelTypesText);legalEntitiesFilters[globals.consts.filterIds.property] = new filterModule.IconListSearchFilter(globals.consts.filterIds.property,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.legalEntities,globals.consts.filterIds.property),noServicesText);legalEntitiesFilters[globals.consts.filterIds.cardType] = new filterModule.IconListSearchFilter(globals.consts.filterIds.cardType,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.legalEntities,globals.consts.filterIds.cardType),noServicesText);tankFarmFilters[globals.consts.filterIds.typeFilling] = new filterModule.IconListSearchFilter(globals.consts.filterIds.typeFilling,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.tankFarm,globals.consts.filterIds.typeFilling));tankFarmFilters[globals.consts.filterIds.shippingMethod] = new filterModule.IconListSearchFilter(globals.consts.filterIds.shippingMethod,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.tankFarm,globals.consts.filterIds.shippingMethod));tankFarmFilters[globals.consts.filterIds.tankFarmFuel] = new filterModule.IconListSearchFilter(globals.consts.filterIds.tankFarmFuel,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.tankFarm,globals.consts.filterIds.tankFarmFuel));tankFarmFilters[globals.consts.filterIds.tankFarmBusinessHours] = new filterModule.BusinessHoursSearchFilter(globals.consts.filterIds.tankFarmBusinessHours,uiModule.getFormFilterSelector(requiredModules.common.consts.formIds.tankFarm,globals.consts.filterIds.tankFarmBusinessHours));return formsById;})();var searchModes=(function(){var gasStationMode=requiredModules.util.createObject(null);gasStationMode[requiredModules.common.consts.formIds.gasStation] = formsById[requiredModules.common.consts.formIds.gasStation];gasStationMode[requiredModules.common.consts.formIds.route] = formsById[requiredModules.common.consts.formIds.route];var oilSellerMode=requiredModules.util.createObject(null);oilSellerMode[requiredModules.common.consts.formIds.oilSeller] = formsById[requiredModules.common.consts.formIds.oilSeller];oilSellerMode[requiredModules.common.consts.formIds.route] = formsById[requiredModules.common.consts.formIds.route];var salePointMode=requiredModules.util.createObject(null);salePointMode[requiredModules.common.consts.formIds.salePoint] = formsById[requiredModules.common.consts.formIds.salePoint]; //salePointMode[requiredModules.common.consts.formIds.route] = formsById[requiredModules.common.consts.formIds.route];
7667var seaportMode=requiredModules.util.createObject(null);seaportMode[requiredModules.common.consts.formIds.seaport] = formsById[requiredModules.common.consts.formIds.seaport];var seaportOilMode=requiredModules.util.createObject(null);seaportOilMode[requiredModules.common.consts.formIds.seaportOil] = formsById[requiredModules.common.consts.formIds.seaportOil];var airportMode=requiredModules.util.createObject(null);airportMode[requiredModules.common.consts.formIds.airport] = formsById[requiredModules.common.consts.formIds.airport];var tankFarmMode=requiredModules.util.createObject(null);tankFarmMode[requiredModules.common.consts.formIds.tankFarm] = formsById[requiredModules.common.consts.formIds.tankFarm];var legalEntitiesMode=requiredModules.util.createObject(null);legalEntitiesMode[requiredModules.common.consts.formIds.legalEntities] = formsById[requiredModules.common.consts.formIds.legalEntities];var modes=requiredModules.util.createObject(null);modes[requiredModules.common.consts.formIds.gasStation] = gasStationMode;modes[requiredModules.common.consts.formIds.oilSeller] = oilSellerMode;modes[requiredModules.common.consts.formIds.salePoint] = salePointMode;modes[requiredModules.common.consts.formIds.seaport] = seaportMode;modes[requiredModules.common.consts.formIds.airport] = airportMode;modes[requiredModules.common.consts.formIds.tankFarm] = tankFarmMode;modes[requiredModules.common.consts.formIds.legalEntities] = legalEntitiesMode;modes[requiredModules.common.consts.formIds.seaportOil] = seaportOilMode;return modes;})();return {searchModes:searchModes,forms:formsById};} // -------------------------- /Form module ------------------------
7668function navigate(){try{requiredModules.routing.navigate.apply(requiredModules.routing,arguments);}catch(e) {if(global.console){global.console.error(e.message);global.console.error(e.stack);}else {uiModule.logErrorToDom(e);}}};function navigateTo(latitude,longitude,departurePointCode){uiModule.activateRoutingForm();navigate({target:{lat:latitude,lng:longitude},departurePointCode:departurePointCode}); // Return false to prevent default action since this function can be a click event handler.
7669return false;};Cartography.navigateTo = navigateTo;Cartography.run = function(settings){var uiSettings=settings.ui;var searchSettings=settings.search || {};var providerSettings=searchSettings.providers || {};var filterSettings=searchSettings.filters || {};var routingSettings=settings.routing || {};var languageCode=settings.language || "RU";var searchModeSetting=searchSettings.mode;var tabId=settings.tab;defaultMapBounds = searchSettings.defaultMapBounds;criticalErrorMessage = searchSettings.criticalErrorMessage;searchSettingsModule.objectInfoPageUrl = searchSettings.objectInfoPageUrl;searchSettingsModule.feedbackPageUrl = searchSettings.feedbackPageUrl;searchSettingsModule.routePageUrl = searchSettings.routePageUrl;searchSettingsModule.closestObjectMarginPercent = searchSettings.closestObjectMarginPercent;serverServiceModule.initialize(languageCode);requiredModules.searchResults.initialize(navigateTo,uiModule.showMoreContainerSelector,uiModule.errorContainerSelector,searchSettingsModule.objectInfoPageUrl,searchSettings.basicOilListPageUrl,searchSettings.extendedOilListPageUrl,searchSettings.fullOilListPageUrl,searchSettingsModule.routePageUrl,searchSettingsModule.feedbackPageUrl,uiModule.ensureUiIsCollapsed);if(settings.countryCodeOverride){requiredModules.common.setCurrentSelectedCountry(settings.countryCodeOverride);}
7669if(settings.userLocationOverride){requiredModules.mapUtil.userLocationProvider.setUserLocation(settings.userLocationOverride);}if(settings.gasStationLocationOverrride){requiredModules.mapUtil.userLocationProvider.setGasStationLocation(settings.gasStationLocationOverrride);}var mapApiPromise=selectAndLoadMapApi(languageCode);var formModule=initFormModule(uiSettings.noCompanySelectedItem,uiSettings.noHighwaySelectedItemText,uiSettings.noPostCodeSelectedItemText,uiSettings.noFuelTypesText,uiSettings.noServicesText,uiSettings.noPaymentTypesText,languageCode);var forms=formModule.searchModes[searchModeSetting] || formModule.searchModes[globals.consts.defaultSearchModeId];var form=_.find(forms,function(f,key){return key !== globals.consts.formIds.route;});var routeForm=forms[globals.consts.formIds.route];$(function(){_.each(formModule.forms,function(form){if(!forms[form.formId]){uiModule.hideFormUI(form.formId);}});});_.each(forms,function(form){form.initialize(filterSettings);});mapApiPromise.then(function(){uiModule.initialize(uiSettings.showSearchUI,requiredModules.mapProvider,forms,uiSettings);$(function(){uiModule.activate(savedMapPositionModule.getMapPosition(requiredModules.mapProvider));});if(settings.zoomToLocation){setTimeout(function(){requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function(geolocationResult){requiredModules.common.map.setCenterAndZoomForAllPoints({latitude:geolocationResult.location.lat,longitude:geolocationResult.location.lng},null,null);});},2000);}});requiredModules.common.mapReady.then(function(){if(routeForm && tabId === globals.consts.formIds.route){navigate(routingSettings);uiModule.activateRoutingForm();uiModule.hideLoadingOverlay();}else if(form){uiModule.activateForm(form,true);}});};},moment,this); /* multiple */ /* any arguments */;
7670LukoilApp.module("Routing", function (Routing, LukoilApp, Backbone, Marionette, $, _, global) {
7671	"use strict";
7672
7673	var requiredModules = {
7674		search: LukoilApp.module("CartographySearch"),
7675		searchResults: LukoilApp.module("CartographySearchResults"),
7676		common: LukoilApp.module("CartographyCommon"),
7677		mapUtil: LukoilApp.module("MapUtil"),
7678		util: LukoilApp.module("Util")
7679	};
7680
7681	var options = {
7682		mapDefaultZoomLevel: 12,
7683		distanceToStationToShow: 400,
7684		searchRadius: 10000,
7685		maxRefPointsCount: 4,
7686		minPauseBetweenExecutionsInMilliseconds: 0,
7687		debug: true,
7688		internalDebuggingEnabled: false
7689	};
7690
7691	var searchRes;
7692	var cancellationToken;
7693	var startInputDf = $.Deferred();
7694	var selectors, icons;
7695	var geocodingService;
7696	var directionService;
7697	var map;
7698	var mapService;
7699	var closestStations;
7700	var referencePoints;
7701	var referencePointInputs = [];
7702	var navigationTarget;
7703	var logger;
7704	var throttler;
7705
7706	var routeInfo = { applied: false };
7707	routeInfo.totalDistance = ko.observable(0);
7708	routeInfo.totalConsumption = ko.observable(0);
7709	var routingProgress = { executing: ko.observable(false) }
7710
7711	/*-------------- Text Utils --------------*/
7712	function appendTextToValue(value, appendText) {
7713		return (value && value !== "0") ? value + " " + appendText : null;
7714		//return value + " " + appendText;
7715	};
7716	function getLengthText(lengthInMeter) {
7717		if (lengthInMeter < 1000)
7718			return appendTextToValue(lengthInMeter.toFixed(0), GlobalSettings.Routing.TextMeter);
7719		return appendTextToValue((lengthInMeter / 1000).toFixed(0), GlobalSettings.Routing.TextKm);
7720	};
7721	var Timer = function (logger, autoStart, msg) {
7722		if (autoStart) this.start();
7723		this.msg= msg || "";
7724		this.logger = logger;
7725	}
7726	Timer.prototype.start = function () { this.startTime = new Date().getTime(); };
7727	Timer.prototype.stop = function () { this.endTime = new Date().getTime(); this.logger.log('Execution time: ' + ((this.endTime - this.startTime) / 1000) + " s." + this.msg); }
7728	/*-------------- /Text Utils --------------*/
7729
7730	/*-------------- Form Utils --------------*/
7731	function setStartInput(address) {
7732		$(selectors.startPoint).val(address);
7733	};
7734	function setEndInput(address, target) {
7735		$(selectors.endPoint).val(address);
7736		if (target != null) {
7737			$(selectors.endPoint).attr("latitude", target.latitude);
7738			$(selectors.endPoint).attr("longitude", target.longitude);
7739		} else {
7740			$(selectors.endPoint).removeAttr("latitude");
7741			$(selectors.endPoint).removeAttr("longitude");
7742		}
7743	};
7744	function getStartAddress() {
7745		return $(selectors.startPoint).val();
7746	};
7747	function getEndAddress() {
7748		var result = {
7749			value: $(selectors.endPoint).val()
7750		};
7751		var latitude = $(selectors.endPoint).attr("latitude");
7752		var longitude = $(selectors.endPoint).attr("longitude");
7753		if (latitude != null && longitude != null)
7754		{
7755			result.location = {
7756				latitude: latitude,
7757				longitude: longitude
7758			};
7759		}
7760		return result;
7761	};
7762	function isChecked(selector) {
7763		return $(selector + ".selected").length > 0;
7764	};
7765	function getFilterValues(selector) {
7766		var $selected = $(selector).find('.selected').toArray();
7767		var ids = _.map($selected, function (el) {
7768			return $(el).data('fuel-id');
7769		});
7770		return ids;
7771	}
7772	function bindChangeRoutePointsBtn() {
7773		$(selectors.changeRoutePointsBtn).on('click', function () {
7774			var sp = $(selectors.startPoint);
7775			var spText = sp.val();
7776			var ep = $(selectors.endPoint);
7777			sp.val(ep.val());
7778			ep.val(spText);
7779		});
7780	};
7781	function bindStartRoutingBtn(func) {
7782		var $mapStartRoutingBtn = $(selectors.mapStartRoutingBtn);
7783		if ($mapStartRoutingBtn.length) {
7784			$mapStartRoutingBtn.on('click', function () {
7785				func();
7786			});
7787		} else logger.log("Start routing button is no found");
7788	};
7789	function getAdditionalPointsCount() {
7790		return $(selectors.additionalRefPointsContainer).length;
7791	};
7792	function removeBtnCallback(selector) {
7793		map.hideAutoCompleteInputsMarkers({ selector: selector });
7794	};
7795	function insertRoutePointInput(params) {
7796		var callback = params && params.callback ? params.callback : function () { };
7797		var refPointsControls = $(selectors.refPointsControls);
7798		if (refPointsControls.length) {
7799			var tmpl = $(selectors.refPointTemplate).html();
7800			var $refPointContainer = $(tmpl);
7801			var $refPointInput = $refPointContainer.find('input');
7802			var $refRemoveBtn = $refPointContainer.find(selectors.refRemoveBtn);
7803			$refRemoveBtn.on('click', function () {
7804				$(this).closest(selectors.additionalRefPointsContainer).remove();
7805				callback($refPointInput);
7806				referencePointInputs = _.filter(referencePointInputs, function (inp) {
7807					return inp[0] === $refPointInput[0];
7808				});
7809			});
7810			$refPointContainer.insertBefore(refPointsControls);
7811			return $refPointInput;
7812		} else logger.log("Inserting tag for additional reference point is not found");
7813		return {};
7814	};
7815	function bindAddRefPointBtn() {
7816		$(selectors.addRefPointBtn).on('click', function () {
7817			var refPointsCount = getAdditionalPointsCount();
7818
7819			if (refPointsCount < options.maxRefPointsCount) {
7820				var refPointInput = insertRoutePointInput({ callback: removeBtnCallback });
7821				if (refPointInput.length) {
7822					map.createAutocompleteInput({ selector: refPointInput, icon: icons.refPoints });
7823					referencePointInputs.push(refPointInput);
7824				}
7825			}
7826		});
7827	};
7828	/*-------------- Form /Utils --------------*/
7829
7830	/*---------- Searching on route functions ----------*/
7831	function getConsumptionPerOneKilometer() {
7832		var consumptionPerHumdredKm = $(selectors.averageFuelConsumption).val();
7833		if (consumptionPerHumdredKm > 0) {
7834			var consumptionPerOneKilometer = consumptionPerHumdredKm / 100;
7835			return consumptionPerOneKilometer;
7836		}
7837		return 0;
7838	};
7839	function getTankVolume() {
7840		return $(selectors.tankVolume).val();
7841	};
7842	function getConsumption(legLengthInMeters, consumptionPerOneKilometer) {
7843		return legLengthInMeters * consumptionPerOneKilometer / 1000;
7844	};
7845	Routing.getPointPositionToPath = function (startLat, startLng, endLat, endLng, targetPointLat, targetPointLng) {
7846		var ax = startLat;
7847		var ay = startLng;
7848		var bx = endLat;
7849		var by = endLng;
7850		var px = targetPointLat;
7851		var py = targetPointLng;
7852		return (bx - ax) * (py - ay) - (by - ay) * (px - ax) > 0;
7853	};
7854	/*---------- /Searching on route functions ----------*/
7855
7856	var isYandexService = function() {
7857		if (mapService && mapService.moduleName === "YandexMapServices") return true;
7858		return false;
7859	};
7860
7861	var getDirectionService = function () {
7862		if (isYandexService()) {
7863			return LukoilApp.module("RoutingYandex").directionService;
7864		} else if (mapService && mapService.moduleName === "GoogleMapServices") {
7865			return LukoilApp.module("RoutingGoogle").directionService;
7866		}
7867
7868		return {};
7869	};
7870
7871	var centerMap = function (map) {
7872		requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function (result) {
7873			map.setCenterAndZoomLevel(result.location.lat, result.location.lng, options.mapDefaultZoomLevel);
7874		});
7875	};
7876
7877	var loadFilters = function () {
7878		requiredModules.common.getCurrentSelectedCountry(GlobalSettings.CurrentLanguage).then(function (countryCode) {
7879			requiredModules.common.searchProvider.getFuelClasses(countryCode).then(function (fuels) {
7880				var fuelFilterDiv = $(selectors.mapFuelTypeFilterContainerSel);
7881				if (fuelFilterDiv.length) {
7882					var model = { fuels: fuels };
7883					_.each(fuels, function(f) {
7884						f.EnabledIconUrl = requiredModules.common.getEnabledIconUrl(f.IconFileBaseUrl);
7885						f.DisabledIconUrl = requiredModules.common.getDisabledIconUrl(f.IconFileBaseUrl);
7886					});
7887					ko.applyBindings(model, fuelFilterDiv[0]);
7888					$(selectors.mapFuelTypeFilterContainerSel + ' input:checkbox').on('change', function () {
7889						if ($(this).is(':checked')) {
7890							$(this).closest('label').addClass('selected');
7891						} else {
7892							$(this).closest('label').removeClass('selected');
7893						}
7894					});
7895				}
7896			});
7897		});
7898	};
7899
7900	function getGeocodingResultByAddresses(addresses) {
7901		var defArr = [];
7902		_.each(addresses, function (addr) {
7903			var def = $.Deferred();
7904			geocodingService.getLocation(addr).then(function (result) {
7905				def.resolve(result.routingLocation);
7906			});
7907			defArr.push(def);
7908		});
7909
7910		return $.when.apply(undefined, defArr);
7911	};
7912
7913	function getAdditionalPointsAddresses() {
7914		var $addressesInputs = $(selectors.additionalRefPointsContainer).toArray();
7915		var addresses = _.map($addressesInputs, function (inp) {
7916			var $inp = $(inp).find("input");
7917			return $inp.val();
7918		});
7919		var notEmptyAddresses = _.filter(addresses, function (a) {
7920			return a && a.trim();
7921		});
7922		return notEmptyAddresses;
7923	};
7924	function getRefPoints() {
7925		var startAddress = getStartAddress(),
7926			endAddress = getEndAddress(),
7927			df = $.Deferred();
7928
7929		if (!startAddress || !endAddress || !endAddress.value) {
7930			logger.log("ref points not defined");
7931			df.reject("ref points not defined");
7932			routingProgress.executing(false);
7933		} else {
7934			geocodingService.getLocation(startAddress).always(function (startCoords) {
7935				if (endAddress.location != null && endAddress.location.latitude != null && endAddress.location.longitude != null) {
7936					if (startCoords.routingLocation) {
7937						var additionalPointsAddresses = getAdditionalPointsAddresses();
7938						var deferred = getGeocodingResultByAddresses(additionalPointsAddresses);
7939						deferred.always(function (/* multiple geocoding results */) {
7940							var geocodingResults = _.map(arguments, function (x) { return x; });
7941							df.resolve({
7942								origin: startCoords.routingLocation,
7943								destination: endAddress.location,
7944								waypoints: geocodingResults
7945							});
7946						});
7947						setEndInput('');
7948					}
7949				} else {
7950					geocodingService.getLocation(endAddress.value).always(function (endCoords) {
7951						if (startCoords.routingLocation && endCoords.routingLocation) {
7952							var additionalPointsAddresses = getAdditionalPointsAddresses();
7953							var deferred = getGeocodingResultByAddresses(additionalPointsAddresses);
7954							deferred.always(function(/* multiple geocoding results */) {
7955								var geocodingResults = _.map(arguments, function(x) { return x; });
7956								df.resolve({
7957									origin: startCoords.routingLocation,
7958									destination: endCoords.routingLocation,
7959									waypoints: geocodingResults
7960								});
7961							});
7962						} else {
7963							logger.log("getRefPoints: " + startCoords + " " + endCoords);
7964							routingProgress.executing(false);
7965							$.fancyboxMessage(GlobalSettings.Routing.PerformingRouteError);
7966						}
7967					});
7968				}
7969			});
7970		}
7971
7972		return df.promise();
7973	};
7974
7975	function showBriefStationsInfo(stations, map) {
7976		var sortedStations = _.sortBy(stations, "orderOnRoute");
7977		_.each(sortedStations, function (s, ind) {
7978			function getDistanceFormatted(num) {
7979				return Math.floor(num * 10) / 10;
7980			};
7981
7982			var distanceToStation = s.distanceToPrev ? getDistanceFormatted(s.distanceToPrev) : 0;
7983			s.DistanceToStation = getLengthText(distanceToStation);
7984			s.ConsumptionText = appendTextToValue(_.isUndefined(s.consumption) ? 0 : s.consumption.toFixed(0), GlobalSettings.Routing.TextLiter);
7985			s.StationRouteSequenseText = GlobalSettings.Routing.RoutePointText + (ind + 1);
7986			//if (ind === 0) {
7987			//	s.StationRouteSequenseText = GlobalSettings.Routing.RouteStartPointText;
7988			//} else if (ind < sortedStations.length - 1) {
7989			//	s.StationRouteSequenseText = GlobalSettings.Routing.RoutePointText + ind;
7990			//} else {
7991			//	s.StationRouteSequenseText = GlobalSettings.Routing.RouteEndPointText;
7992			//}
7993		});
7994
7995		searchRes.setMapSearchResults(sortedStations, function (items, infoWindowContentElementCallback, onMarkerClickCallback) {
7996			if (map && map.setClusterMarkers) {
7997				var mapItems = _.filter(items, function (g) {
7998					return g.Latitude != null && g.Longitude != null;
7999				});
8000				map.setClusterMarkers(mapItems, infoWindowContentElementCallback, onMarkerClickCallback);
8001			}
8002		});
8003		searchRes.setListSearchResults(sortedStations);
8004	};
8005
8006	function showRouteInfo(info) {
8007		var $panel = $(info.panelInfoSelector);
8008		if ($panel.length) {
8009			routeInfo.totalDistance(getLengthText(info.totalDistance));
8010			routeInfo.totalConsumption(appendTextToValue(info.totalConsumption.toFixed(0), GlobalSettings.Routing.TextLiter));
8011			if (!routeInfo.applied) {
8012				ko.applyBindings(routeInfo, $panel[0]);
8013				routeInfo.applied = true;
8014			}
8015		} else logger.log("ShowRouteInfo. Info Panel not found.");
8016	};
8017
8018	function getStationsInBounds(searchBounds) {
8019		var df = $.Deferred();
8020		var fuelFilter = getFilterValues(selectors.mapFuelTypeFilterContainerSel);
8021		var map24HoursFilter = isChecked(selectors.map24HoursFilterSel);
8022		requiredModules.search.searchGasStationsForRouting(fuelFilter, searchBounds.swLat, searchBounds.neLat, searchBounds.swLng, searchBounds.lngDiff, map24HoursFilter).done(function (stationsModel) {
8023			df.resolve(stationsModel);
8024		});
8025		return df;
8026	};
8027
8028	function getClosestStationsSearchResult(stations, response) {
8029		var results = [];
8030		var defArr = [];
8031		_.each(_.filter(stations, function(s) {
8032			return s.IsDisabled == null || !s.IsDisabled;
8033		}), function (s) {
8034			var def = $.Deferred();
8035			throttler.throttle(function () { //setTimeout(function() {
8036				var t;
8037				if (options.internalDebuggingEnabled) t = new Timer(console, true, " (search result)");
8038				// major time-consumer operation
8039				var minDistanceToRoute = directionService.getMinDistanceToRoute(response, s.Latitude, s.Longitude, options.distanceToStationToShow);
8040				if (t) t.stop();
8041				results.push({ minDistanceToRoute: minDistanceToRoute, station: s });
8042				def.resolve(results);
8043				return def;
8044			});
8045			defArr.push(def);
8046		});
8047
8048		return $.when.apply(undefined, defArr);
8049	};
8050
8051	function getClosestStationsPromise(params) {
8052
8053		var df = $.Deferred();
8054
8055		var response = params.directionResponse;
8056		var checkPlacement = params.checkPlacement;
8057		var stations = params.stations;
8058
8059		var msg = " (from " + getStartAddress() + " to " + getEndAddress().address + ")";
8060		var t = new Timer(logger,true, msg);
8061		getClosestStationsSearchResult(stations, response).then(function (results) {
8062			t.stop();
8063			var closestStations = _.filter(stations, function (s) {
8064				var res = _.filter(results, function(r) {
8065					return r.station.gasStationId === s.gasStationId;
8066				})[0];
8067				return res != null && res.minDistanceToRoute <= options.distanceToStationToShow;
8068			});
8069
8070			if (checkPlacement) {
8071				closestStations = _.filter(closestStations, function(s) {
8072					return directionService.isPositionOnTheRightHand(response, s.Latitude, s.Longitude, options.distanceToStationToShow);
8073				});
8074			}
8075			df.resolve(closestStations);
8076		});
8077
8078		return df.promise();
8079	}
8080
8081	function getTotalConsumptionAndAddConsumptionBetweenStations(consumptionInfo, directionResponse, stations) {
8082		if (consumptionInfo == null) {
8083			consumptionInfo = { totalConsumption: 0, lastConsumption: 0 };
8084		}
8085		if (!stations || !stations.length)
8086			return consumptionInfo;
8087
8088		var consumptionPerOneKilometer = getConsumptionPerOneKilometer();
8089		var tankVolume = getTankVolume();
8090
8091		var allStations = _.map(stations, function (s) { return s; });
8092
8093		var nextStation = null;
8094		var orderOnRoute = 0;
8095		while (allStations.length) {
8096			var prevPos = nextStation
8097				? directionService.getNearestPointTo(directionResponse, nextStation.Latitude, nextStation.Longitude)
8098				: directionService.getRouteStartPoint(directionResponse);
8099			nextStation = directionService.lookforClosestStationToPosition(prevPos.Latitude, prevPos.Longitude, allStations);
8100			var distanceOnRouteBetween = directionService.getDistanceOnRoute(directionResponse, prevPos.Latitude, prevPos.Longitude, nextStation.Latitude, nextStation.Longitude);
8101			var consumption = getConsumption(distanceOnRouteBetween, consumptionPerOneKilometer);
8102
8103			nextStation.LowFuel = consumption > tankVolume;
8104			nextStation.consumption = consumption;
8105			nextStation.distanceToPrev = distanceOnRouteBetween;
8106			nextStation.orderOnRoute = orderOnRoute;
8107
8108			orderOnRoute++;
8109			allStations = _.filter(allStations, function (a) {
8110				return !nextStation || a.gasStationId !== nextStation.gasStationId;
8111			});
8112		}
8113
8114		var endPosition = directionService.getRouteEndPoint(directionResponse);
8115		var distanceOnRoute = directionService.getDistanceOnRoute(directionResponse, endPosition.Latitude, endPosition.Longitude, nextStation.Latitude, nextStation.Longitude);
8116		var lastConsumption = getConsumption(distanceOnRoute, consumptionPerOneKilometer);
8117		if (lastConsumption > tankVolume) nextStation.LowFuel = true;
8118
8119		consumptionInfo.lastConsumption += lastConsumption;
8120
8121		return consumptionInfo;
8122	}
8123
8124	function hideAutoCompleteInputsMarkers() {
8125		map.hideAutoCompleteInputsMarkers({ selector: selectors.startPoint });
8126		map.hideAutoCompleteInputsMarkers({ selector: selectors.endPoint });
8127		_.each(referencePointInputs, function (inp) {
8128			map.hideAutoCompleteInputsMarkers({ selector: inp });
8129		});
8130	}
8131
8132	function showRoute(refPoints) {
8133		var avoidTolls = !isChecked(selectors.useTollsInput);
8134		var avoidTrafficJams = isChecked(selectors.avoidJamsInput);
8135
8136		var startPoint = refPoints.origin;
8137		var endPoint = refPoints.destination;
8138		var waypoints = refPoints.waypoints;
8139
8140		var points = [startPoint]
8141			.concat(waypoints)
8142			.concat([endPoint]);
8143
8144		closestStations = [];
8145		var totalDistance = 0;
8146		var consumptionInfo = null;
8147		var consumptionPerOneKilometer = getConsumptionPerOneKilometer();
8148
8149		var len = points.length;
8150		var isError = false;
8151		for (var i = 0; i < len - 1; i++) {
8152			if (isError)
8153				break;
8154
8155			var _refPoints = { origin: points[i], destination: points[i + 1], waypoints: [] };
8156			directionService.getRoutePromise({ refPoints: _refPoints, avoidTolls: avoidTolls, avoidTrafficJams: avoidTrafficJams }).always(function (directionResponse) {
8157				if (directionResponse.msg) {
8158					isError = true;
8159					$.fancyboxMessage(directionResponse.msg);
8160					logger.log(directionResponse.msg + " (Status: " + directionResponse.status + (directionResponse.providerMessage ? ", provider message: " + directionResponse.providerMessage : "") + ")");
8161					routingProgress.executing(false);
8162					return;
8163				}
8164
8165				if (cancellationToken.isCanceled()) {
8166					logger.log("cancellationToken isCanceled");
8167					routingProgress.executing(false);
8168					return;
8169				}
8170
8171				var searchBounds = directionService.getBoundsForSearch(directionResponse);
8172				getStationsInBounds(searchBounds).done(function (stations) {
8173					if (cancellationToken.isCanceled()) {
8174						logger.log("cancellationToken isCanceled");
8175						routingProgress.executing(false);
8176						return;
8177					}
8178
8179					var checkPlacement = isChecked(selectors.checkPlacementInput);
8180					var closestStationsPromise = getClosestStationsPromise({ directionResponse: directionResponse, checkPlacement: checkPlacement, stations: stations });
8181					closestStationsPromise.then(function(foundStations) {
8182						if (options.internalDebuggingEnabled && console) {
8183							if (window.console && window.console.log) {
8184								console.log("stations count: " + stations.length);
8185								console.log("closest stations count: " + foundStations.length);
8186							}
8187						}
8188
8189						closestStations = closestStations.concat(foundStations);
8190						totalDistance += directionService.getRouteLengthInMeters(directionResponse);
8191						consumptionInfo = getTotalConsumptionAndAddConsumptionBetweenStations(consumptionInfo, directionResponse, closestStations);
8192						consumptionInfo.totalConsumption = getConsumption(totalDistance, consumptionPerOneKilometer);
8193						showBriefStationsInfo(closestStations, map);
8194						showRouteInfo({ totalDistance: totalDistance, totalConsumption: consumptionInfo.totalConsumption, panelInfoSelector: selectors.panelInfoSelector });
8195
8196						routingProgress.executing(false);
8197					});
8198				});
8199			});
8200		}
8201		if(!isError){
8202			directionService.getRoutePromise({ refPoints: refPoints, avoidTolls: avoidTolls, avoidTrafficJams: avoidTrafficJams }).always(function(directionResponse) {
8203				directionService.renderAllDirections({ directionResponse: directionResponse, stations: [], refPoints: refPoints, map: map, cancellationToken: cancellationToken });
8204			});
8205
8206			hideAutoCompleteInputsMarkers();
8207
8208			var refPointsItems = [];
8209			refPointsItems.push({ Latitude: startPoint.latitude, Longitude: startPoint.longitude, IconUrl: icons.start });
8210			_.each(waypoints, function (wp, index) {
8211				refPointsItems.push({ Latitude: wp.latitude, Longitude: wp.longitude, IconUrl: icons.refPoints, Label: String(index + 1) });
8212			});
8213			refPointsItems.push({ Latitude: endPoint.latitude, Longitude: endPoint.longitude, IconUrl: icons.end });
8214			referencePoints = refPointsItems;
8215			map.addSimpleMarkers(refPointsItems);
8216		}
8217	};
8218
8219	function startRouting() {
8220		routingProgress.executing(true);
8221		map.setClusterMarkers([]);
8222		getRefPoints().then(showRoute);
8223	};
8224
8225	function bindInsertCurrentLocation() {
8226		$(selectors.insertCurrentLocation).on("click", function () {
8227			var $this = $(this);
8228			requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function (result) {
8229				var df = geocodingService.getFormattedAddress(result.location.lat, result.location.lng);
8230				df.then(function (res) {
8231					var $input = $this.closest("div").find("input");
8232					$input.val(res.address);
8233				});
8234			});
8235		});
8236	};
8237
8238	var initRefPointsInputs = function (map) {
8239		requiredModules.mapUtil.userLocationProvider.getCurrentLocation().then(function (result) {
8240			if (!geocodingService) geocodingService = mapService.geocodingService;
8241
8242			startInputDf = geocodingService.getFormattedAddress(result.location.lat, result.location.lng);
8243			startInputDf.then(function (res) {
8244
8245				setStartInput(res.address);
8246
8247				map.createAutocompleteInput({ selector: $(selectors.startPoint), icon: icons.refPoints });
8248				map.createAutocompleteInput({ selector: $(selectors.endPoint), icon: icons.refPoints });
8249
8250				bindChangeRoutePointsBtn();
8251				bindStartRoutingBtn(startRouting);
8252				bindAddRefPointBtn();
8253				bindInsertCurrentLocation();
8254				if (navigationTarget) {
8255					startRouting();
8256				}
8257			});
8258		});
8259	};
8260
8261	// Called the first time the tab becomes active.
8262	Routing.initializeOnMap = function (shouldSetMapPosition) {
8263		searchRes = new requiredModules.searchResults.SearchResultsView('#tab-content-routeplaner', 'selection', '.searchResultsHeading');
8264
8265		cancellationToken = new requiredModules.util.CancellationToken();
8266
8267		map = requiredModules.common.map;
8268		mapService = map.getMapServiceProvider();
8269		geocodingService = mapService.geocodingService;
8270		if (!directionService) directionService = getDirectionService();
8271
8272		if (isYandexService()) {
8273			$(selectors.useTollsInput).hide();
8274		} else {
8275			$(selectors.avoidJamsInput).hide();
8276		}
8277
8278		if (shouldSetMapPosition) centerMap(map);
8279		loadFilters();
8280		initRefPointsInputs(map);
8281		routingProgress.executing(false);
8282
8283		var routingProgressOverlay = $(selectors.routeProgressOverlay);
8284		if (routingProgressOverlay.length) ko.applyBindings(routingProgress, routingProgressOverlay[0]);
8285
8286		if (navigationTarget && geocodingService) {
8287			geocodingService.getFormattedAddress(navigationTarget.latitude, navigationTarget.longitude).then(function (res) {
8288				setEndInput(res.address);
8289			});
8290		}
8291	};
8292
8293	// Called whenever the tab becomes active.
8294	Routing.putObjectsOnMap = function () {
8295		cancellationToken = new requiredModules.util.CancellationToken();
8296		directionService.showRoute({ centerMap: false });
8297		showBriefStationsInfo(closestStations, map);
8298		map.addSimpleMarkers(referencePoints);
8299	};
8300
8301	// Called whenever the tab becomes inactive.
8302	Routing.clearObjectsFromMap = function () {
8303		cancellationToken.cancel();
8304		directionService.clearRoute();
8305		map.addSimpleMarkers([]);
8306		map.removeAutocompleteHandler();
8307	};
8308
8309	// May be called early (before DOM and map scripts are  ready) if the page is loaded with the routing tab open.
8310	// Also called on the user's "navigate" command.
8311	Routing.navigate = function (parameters) {
8312		if (parameters && parameters.target && parameters.target.lat && parameters.target.lng) {
8313			var t = parameters.target;
8314			var latitude = t.lat;
8315			var longitude = t.lng;
8316			$(selectors.additionalRefPointsContainer + ' ' + selectors.refRemoveBtn).trigger('click');
8317			navigationTarget = { latitude: latitude, longitude: longitude };
8318			if (geocodingService) {
8319				geocodingService.getFormattedAddress(latitude, longitude).then(function (res) {
8320					setEndInput(res.address, navigationTarget);
8321					startInputDf.then(startRouting);
8322				});
8323			}
8324		}
8325	};
8326
8327	Routing.init = function(parameters) {
8328		options = $.extend(options, parameters);
8329		logger = requiredModules.util.createLogger({ useConsole: options.debug, moduleName: "Routing" });
8330		throttler = new requiredModules.util.Throttler(options.minPauseBetweenExecutionsInMilliseconds);
8331	};
8332
8333	Routing.on("start", function (options) {
8334		selectors = {
8335			//mapContainer: '.cd-map-locator_route .map-container',
8336			checkPlacementInput: '#map-check-placement',
8337			avoidJamsInput: '#map-avoid-jams',
8338			map24HoursFilterSel: '#mapThrough24Hours',
8339			useTollsInput: '#map-use-tolls',
8340			setRouteThroughLukoilGsInput: '.map-through-gs.selected',
8341			tankVolume: '#map-tank-volume',
8342			averageFuelConsumption: '#map-fuel-consumption',
8343			mapFuelTypeFilterContainerSel: '#map-fuel-types',
8344			panelInfoSelector: '#routParams',
8345			mapStartRoutingBtn: '#map-start-direction',
8346			changeRoutePointsBtn: '#reverse-route',
8347			additionalRefPointsContainer: '.luk-point-container',
8348			addRefPointBtn: '#map-route-points-add',
8349			//startPoint: '.cd-map-locator_route .map-route-points-start',
8350			//endPoint: '.cd-map-locator_route .map-route-points-end',
8351			startPoint: '#rout-point-from',
8352			endPoint: '#rout-point-to',
8353			refPointsControls: '#ref-points-controls',
8354			refPointTemplate: '#luk-refpoint-template',
8355			refRemoveBtn: 'i',
8356			insertCurrentLocation: '.luk-insert-current-location',
8357			routeProgressOverlay: '#routeProgressOverlay'
8358		};
8359		icons = {
8360			start: '/content/img/icon-point-start.png',
8361			end: '/content/img/icon-point-end.png',
8362			refPoints: '/content/img/icon-point.png',
8363			station: '/content/img/icon-point-gas.png'
8364		};
8365
8366	});
8367
8368	Routing.options = options;
8369
8370});;
8371LukoilApp.module("RoutingGoogle", function (RoutingGoogle, LukoilApp, Backbone, Marionette, $, _, global) {
8372	"use strict";
8373
8374	var requiredModules = {
8375		util: LukoilApp.module("Util"),
8376		routing: LukoilApp.module("Routing")
8377	};
8378
8379	var logger = requiredModules.util.createLogger({ useConsole: true, moduleName: "RoutingGoogle" });
8380
8381	function createCoordinate(lat, lng) {
8382		return new google.maps.LatLng(lat, lng);
8383	}
8384
8385	var directionService = (function () {
8386		var directionsRenderers = [];
8387		var mapDirectionsService;
8388		var gmap;
8389		var directionResponse;
8390
8391		function clearRenderers() {
8392			_.each(directionsRenderers, function (renderer) {
8393				renderer.setMap(null);
8394				renderer.setPanel(null);
8395			});
8396			directionsRenderers = [];
8397		}
8398
8399		function renderDirections(directionResponse, routeIndexToDisplay, params) {
8400			var routeRenderOptions = {
8401				color: '#00458E',
8402				strokeWeight: 4,
8403				strokeOpacity: 1.0,
8404				suppressMarkers: true
8405			};
8406			var renderer = new google.maps.DirectionsRenderer({
8407				draggable: false,
8408				suppressMarkers: true,
8409				preserveViewport: params && !_.isUndefined(params.centerMap) ? !params.centerMap : false, // if preserveViewport=true - map not centered
8410				polylineOptions: { strokeColor: routeRenderOptions.color, strokeWeight: routeRenderOptions.strokeWeight, strokeOpacity: routeRenderOptions.strokeOpacity }
8411			});
8412			renderer.setMap(gmap.backingMap);
8413			renderer.setDirections(directionResponse);
8414			renderer.setRouteIndex(routeIndexToDisplay);
8415			directionsRenderers.push(renderer);
8416		}
8417
8418		function showRoutes(params) {
8419			if (directionResponse) {
8420				for (var i = 0; i < directionResponse.routes.length; i++) renderDirections(directionResponse, i, params);
8421			}
8422		}
8423		function getDistance(first, second) {
8424			return google.maps.geometry.spherical.computeDistanceBetween(first, second);
8425		};
8426
8427		function calcDistanceAndPathToStep(step, position, distanceToStationToShow, skipIfTooFar) {
8428			var minDistance = distanceToStationToShow + 1;
8429			var pathwithMinDistance, skip = 0, pointsToSkipIfTooFar = 10;
8430			_.each(step.path, function(point) {
8431				if (skip > 0) {
8432					skip--;
8433				} else {
8434					var distance = getDistance(new google.maps.LatLng(point.lat(), point.lng()), position);
8435					if (skipIfTooFar && distance > distanceToStationToShow) {
8436						skip = pointsToSkipIfTooFar;
8437					}
8438					if (distance < minDistance) {
8439						minDistance = distance;
8440						pathwithMinDistance = point;
8441					}
8442				}
8443			});
8444			return { minDistance: minDistance, pathwithMinDistance: pathwithMinDistance };
8445		};
8446		function calcDistanceToStep(stepToFind, position, distanceToStationToShow, skipIfTooFar) {
8447			return calcDistanceAndPathToStep(stepToFind, position, distanceToStationToShow, skipIfTooFar).minDistance;
8448		};
8449
8450		// possible performance hit
8451		function findCLosestStepAndDistance(route, position, distanceToStationToShow) {
8452			var stepToFind = route.legs[0].steps[0];
8453			var minDistance = distanceToStationToShow + 1;
8454			_.each(route.legs, function (leg) {
8455				_.each(leg.steps, function(step) {
8456					var distance = calcDistanceToStep(step, position, distanceToStationToShow, false);
8457					if (distance < minDistance) {
8458						minDistance = distance;
8459						stepToFind = step;
8460					}
8461				});
8462			});
8463			return { step: stepToFind, distance: minDistance };
8464		};
8465
8466		function getClosestStepsByEndPointsOnly(steps, position) {
8467			var lowerRadius = 20000;
8468			var minSteps = _.filter(steps, function(step) {
8469				var start = step.path[0];
8470				var end = step.path[step.path.length - 1];
8471				var distanceStart = getDistance(new google.maps.LatLng(start.lat(), start.lng()), position);
8472				var	distanceEnd = getDistance(new google.maps.LatLng(end.lat(), end.lng()), position);
8473				return distanceEnd < lowerRadius || distanceStart < lowerRadius;
8474			});
8475			return minSteps;
8476		};
8477
8478		function getMinDistanceToRoute(route, position, distanceToStationToShow) {
8479			var minDistance = distanceToStationToShow + 1;
8480			_.each(route.legs, function (leg) {
8481
8482				var closestSteps = getClosestStepsByEndPointsOnly(leg.steps, position);
8483				_.each(closestSteps, function(step) {
8484					var distance = calcDistanceToStep(step, position, distanceToStationToShow, true);
8485					if (distance < minDistance) {
8486						minDistance = distance;
8487					}
8488				});
8489
8490			});
8491
8492			return minDistance;
8493		};
8494
8495		function findClosestPath(step, position) {
8496			var minDistance = getDistance(step.start_location, position);
8497			var closestPoint = step.start_location;
8498			var closestPointIndex = 0;
8499			_.each(step.path, function (p, index) {
8500				var distance = getDistance(new google.maps.LatLng(p.lat(), p.lng()), position);
8501				if (distance < minDistance) {
8502					minDistance = distance;
8503					closestPoint = p;
8504					closestPointIndex = index;
8505				}
8506			});
8507			if (closestPointIndex === step.path.length - 1) {
8508				return { start_location: step.path[closestPointIndex - 1], end_location: closestPoint };
8509			} else {
8510				return { start_location: closestPoint, end_location: step.path[closestPointIndex + 1] };
8511			}
8512		};
8513		function findClosestStep(route, position, distanceToStationToShow) {
8514			return findCLosestStepAndDistance(route, position, distanceToStationToShow).step;
8515		};
8516		
8517		function isPositionOnTheRightHand(route, position, distanceToStationToShow) {
8518			var closestPath = findClosestPath(findClosestStep(route, position, distanceToStationToShow), position);
8519			
8520			if (!closestPath) return true;
8521			// todo: negate for left-hand roads, take info from dictionary
8522			return requiredModules.routing.getPointPositionToPath(
8523				closestPath.start_location.lat(), closestPath.start_location.lng(),
8524				closestPath.end_location.lat(), closestPath.end_location.lng(),
8525				position.lat(), position.lng());
8526		};
8527		function getNearestPointTo(route, position) {
8528			var coords = route.overview_path;
8529			var pointWithMinDistance = coords[0];
8530			var minDistance = getDistance(pointWithMinDistance, position);
8531			_.each(coords, function (p) {
8532				var dist = getDistance(position, p);
8533				if (minDistance > dist) {
8534					minDistance = dist;
8535					pointWithMinDistance = p;
8536				}
8537			});
8538			return pointWithMinDistance;
8539		};
8540
8541		function getRouteStartPoint(route) {
8542			return route.overview_path[0];
8543		};
8544		function getRouteEndPoint(route) {
8545			return route.overview_path[route.overview_path.length - 1];
8546		};
8547
8548		function lookforClosestStationToPosition(position, stations) {
8549			if (stations && stations.length) {
8550				var closestAzs = _.reduce(stations, function (prev, next) {
8551					var prevDist = getDistance(position, new google.maps.LatLng(prev.Latitude, prev.Longitude));
8552					var nextDist = getDistance(position, new google.maps.LatLng(next.Latitude, next.Longitude));
8553					return nextDist < prevDist ? next : prev;
8554				});
8555				return closestAzs;
8556			}
8557			return null;
8558		};
8559
8560		function getPathLenth(pathCoords) {
8561			var prev;
8562			var len = 0;
8563			_.each(pathCoords, function (next) {
8564				if (prev) {
8565					len += getDistance(prev, next);
8566				}
8567				prev = next;
8568			});
8569			return len;
8570		};
8571		function getDistanceOnRoute(route, firstPoint, stationPosition) {
8572			var secondPoint = getNearestPointTo(route, stationPosition);
8573			var coords = route.overview_path;
8574			var firstPointIndex = _.findIndex(coords, function (p) {
8575				return p.equals(firstPoint);
8576			});
8577			var stationPositionIndex = _.findIndex(coords, function (p) {
8578				return p.equals(secondPoint);
8579			});
8580
8581			var index = 0;
8582			var pathBetweenPoints = _.filter(coords, function (p) {
8583				var result;
8584				if (firstPointIndex < stationPositionIndex) {
8585					result = firstPointIndex <= index && index <= stationPositionIndex;
8586				} else {
8587					result = stationPositionIndex <= index && index <= firstPointIndex;
8588				}
8589				index++;
8590				return result;
8591			});
8592
8593			return getPathLenth(pathBetweenPoints);
8594		};
8595
8596		return {
8597			getRoutePromise: function (options) {
8598				var df = $.Deferred();
8599				var refPoints = options.refPoints;
8600				var avoidTolls = options.avoidTolls;
8601				var waypoints = _.map(refPoints.waypoints, function (w) {
8602					return { location: createCoordinate(w.latitude, w.longitude), stopover: true };
8603				});
8604				var request = {
8605					origin: createCoordinate(refPoints.origin.latitude, refPoints.origin.longitude),
8606					destination: createCoordinate(refPoints.destination.latitude, refPoints.destination.longitude),
8607					waypoints: waypoints,
8608					optimizeWaypoints: true, // provide the shortest possible route + return the reordered waypoints
8609					avoidTolls: avoidTolls, // paid road
8610					travelMode: google.maps.TravelMode.DRIVING
8611				};
8612				if (!mapDirectionsService) {
8613					mapDirectionsService = new google.maps.DirectionsService();
8614				}
8615				mapDirectionsService.route(request, function (response, status) {
8616					if (status === google.maps.DirectionsStatus.OK && response.routes.length) {
8617						df.resolve(response);
8618					} else {
8619						df.reject({ msg: GlobalSettings.Routing.PerformingRouteError, status: status });
8620					}
8621				});
8622				return df;
8623			},
8624			clearRoute: function () {
8625				clearRenderers();
8626			},
8627			showRoute: function (params) {
8628				showRoutes(params);
8629			},
8630			renderAllDirections: function (parameters) {
8631				gmap = parameters.map;
8632				clearRenderers();
8633				directionResponse = parameters.directionResponse;
8634				if (parameters.cancellationToken && parameters.cancellationToken.isCanceled()) {
8635					logger.log("cancellationToken isCanceled");
8636					return;
8637				}
8638
8639				showRoutes();
8640			},
8641			getBoundsForSearch: function (routeResponse) {
8642				var mainRoute = routeResponse.routes[0];
8643				var bounds = mainRoute.bounds;
8644				var leftPoint = [bounds.getSouthWest().lat(), bounds.getSouthWest().lng()];
8645				var rightPoint = [bounds.getNorthEast().lat(), bounds.getNorthEast().lng()];
8646				var lngDiff = rightPoint[1] - leftPoint[1];
8647				if (lngDiff < 0) {
8648					lngDiff += 360;
8649				} else if (Math.abs(lngDiff) < 0.001) {
8650					lngDiff = 360;
8651				}
8652				return { swLat: leftPoint[0], neLat: rightPoint[0], swLng: leftPoint[1], lngDiff: lngDiff };
8653			},
8654			getRouteLengthInMeters: function (response) {
8655				if (response && response.routes && response.routes.length) {
8656					var route = response.routes[0];
8657					if (route && route.legs) {
8658						var entireDistanceInMeters = _.reduce(route.legs, function (distance, leg) {
8659							return distance + leg.distance.value;
8660						}, 0);
8661						return entireDistanceInMeters;
8662					} else logger.log("Google getRouteLengthInMeters. route does not contain legs.");
8663				} else logger.log("Google getRouteLengthInMeters. no routes found.");
8664
8665				return 0;
8666			},
8667			getMinDistanceToRoute: function (response, positionLat, positionLng, distanceToStationToShow) {
8668				var route = response.routes[0];
8669				return getMinDistanceToRoute(route, new google.maps.LatLng(positionLat, positionLng), distanceToStationToShow);
8670			},
8671			isPositionOnTheRightHand: function (response, positionLat, positionLng, distanceToStationToShow) {
8672				var route = response.routes[0];
8673				return isPositionOnTheRightHand(route, new google.maps.LatLng(positionLat, positionLng), distanceToStationToShow);
8674			},
8675			getNearestPointTo: function (response, positionLat, positionLng) {
8676				var route = response.routes[0];
8677				var position = getNearestPointTo(route, new google.maps.LatLng(positionLat, positionLng));
8678				return { Latitude: position.lat(), Longitude: position.lng() };
8679			},
8680			getRouteStartPoint: function (response) {
8681				var route = response.routes[0];
8682				var position = getRouteStartPoint(route);
8683				return { Latitude: position.lat(), Longitude: position.lng() };
8684			},
8685			getRouteEndPoint: function (response) {
8686				var route = response.routes[0];
8687				var position = getRouteEndPoint(route);
8688				return { Latitude: position.lat(), Longitude: position.lng() };
8689			},
8690			lookforClosestStationToPosition: function (positionLat, positionLng, stations) {
8691				return lookforClosestStationToPosition(new google.maps.LatLng(positionLat, positionLng), stations);
8692			},
8693			getDistanceOnRoute: function (response, prevPositionLat, prevPositionLng, nextPositionLat, nextPositionLng) {
8694				var route = response.routes[0];
8695				return getDistanceOnRoute(route,
8696					new google.maps.LatLng(prevPositionLat, prevPositionLng),
8697					new google.maps.LatLng(nextPositionLat, nextPositionLng));
8698			}
8699		};
8700	})();
8701
8702	RoutingGoogle.directionService = directionService;
8703
8704	RoutingGoogle.on("start", function (options) {
8705
8706	});
8707
8708});;
8709LukoilApp.module("RoutingYandex", function (RoutingYandex, LukoilApp, Backbone, Marionette, $, _, global) {
8710	"use strict";
8711
8712	var requiredModules = {
8713		util: LukoilApp.module("Util"),
8714		routing: LukoilApp.module("Routing")
8715	};
8716
8717	var logger = requiredModules.util.createLogger({ useConsole: true, moduleName: "RoutingYandex" });
8718
8719	var directionService = (function () {
8720
8721		var directionResponse;
8722		var gmap;
8723
8724		function clearRoutes() {
8725			if (directionResponse) {
8726				gmap.backingMap.geoObjects.remove(directionResponse);
8727				directionResponse.getWayPoints().removeAll();
8728			}
8729		}
8730
8731		function renderRoute(params) {
8732			clearRoutes();
8733			if (gmap) {
8734				if (params && !_.isUndefined(params.centerMap) && directionResponse.options.get("mapStateAutoApply")) {
8735					directionResponse.options.set("mapStateAutoApply", params.centerMap);
8736				}
8737				gmap.backingMap.geoObjects.add(directionResponse);
8738			}
8739		};
8740
8741		function getAllCoords(route) {
8742			var coords = [];
8743			route.getPaths().each(function (p) {
8744				_.each(p.geometry.getCoordinates(), function (cc) {
8745					coords.push(cc);
8746				});
8747			});
8748			return coords;
8749		};
8750		function getDistanceYandex(first, second) {
8751			var distance = ymaps.coordSystem.geo.getDistance(first, second);
8752			return distance;
8753		};
8754		function getPathLenthYandex(pathCoords) {
8755			var prev;
8756			var len = 0;
8757			_.each(pathCoords, function (next) {
8758				if (prev) {
8759					len += getDistanceYandex(prev, next);
8760				}
8761				prev = next;
8762			});
8763			return len;
8764		};
8765
8766		var getPathWithMinDistanceToEndPoints = function (paths, position, distanceToStationToShow) {
8767			var pa = paths.toArray();
8768			if (pa.length === 1)
8769				return pa[0];
8770
8771			var minDistance = distanceToStationToShow +1;
8772			var minPath;
8773
8774			paths.each(function (path) {
8775				if(!minPath) minPath = path;
8776				var points1 = path.geometry.getCoordinates();
8777				var points = [points1[0],points1[points1.length-1]];
8778
8779				_.each(points, function (point) {
8780					if (minDistance > distanceToStationToShow) {
8781						var distance = getDistanceYandex(point, position);
8782						if (distance < minDistance) {
8783							minDistance = distance;
8784							minPath = path;
8785						}
8786					}
8787				});
8788			});
8789			return minPath;
8790		};
8791
8792		// possible performance hit
8793		function getMinDistanceToRouteYandex(mainRoute, position, distanceToStationToShow) {
8794			var paths = mainRoute.getPaths();
8795			var minDistance = distanceToStationToShow + 1;
8796			var pm = getPathWithMinDistanceToEndPoints(paths, position, distanceToStationToShow);
8797
8798			var points = pm.geometry.getCoordinates();
8799			var skip = 0;
8800			var pointsToSkipIfTooFarLowRadius = 10;
8801			var pointsToSkipIfTooFarMiddleRadius = 100;
8802			var pointsToSkipIfTooFarHighestRadius = 1000;
8803			_.each(points, function(point, ind) {
8804				if (skip > 0) {
8805					skip--;
8806				} else {
8807					if (minDistance > distanceToStationToShow) {
8808						var distance = getDistanceYandex(point, position);
8809						if (distance > distanceToStationToShow * pointsToSkipIfTooFarHighestRadius) {
8810							skip = pointsToSkipIfTooFarHighestRadius;
8811						} else if (distance > distanceToStationToShow * pointsToSkipIfTooFarMiddleRadius) {
8812							skip = pointsToSkipIfTooFarMiddleRadius;
8813						} else if (distance > distanceToStationToShow * pointsToSkipIfTooFarLowRadius) {
8814							skip = pointsToSkipIfTooFarLowRadius;
8815						}
8816						if (distance < minDistance) minDistance = distance;
8817					}
8818				}
8819
8820			});
8821			return minDistance;
8822		}
8823
8824		function isStartPointOnRoute(route, point) {
8825			var startPoint = route.getPaths().toArray()[0].geometry.getCoordinates()[0];
8826			return startPoint[0] === point[0] && startPoint[1] === point[1];
8827		};
8828		function getNextPointOnRoute(route, point, reverse) {
8829			var coords = getAllCoords(route);
8830			var pointIndex = _.findIndex(coords, function (p) {
8831				return p[0] === point[0] && p[1] === point[1];
8832			});
8833			if (reverse) {
8834				return coords[pointIndex - 1];
8835			}
8836			return coords[pointIndex + 1];
8837		};
8838		function getNearestPointToYandex(route, position) {
8839			var coords = getAllCoords(route);
8840			var pointWithMinDistance = coords[0];
8841			var minDistance = getDistanceYandex(pointWithMinDistance, position);
8842			_.each(coords, function (p) {
8843				var dist = getDistanceYandex(position, p);
8844				if (minDistance > dist) {
8845					minDistance = dist;
8846					pointWithMinDistance = p;
8847				}
8848			});
8849			return pointWithMinDistance;
8850		};
8851		function findClosestPathYandex(route, position) {
8852			var closestPrevPoint;
8853			var closestPoint = getNearestPointToYandex(route, position);
8854			if (isStartPointOnRoute(route, closestPoint)) {
8855				closestPrevPoint = closestPoint;
8856				closestPoint = getNextPointOnRoute(route, closestPoint);
8857			} else {
8858				closestPrevPoint = getNextPointOnRoute(route, closestPoint, true);
8859			}
8860
8861			return {
8862				start_location: closestPrevPoint,
8863				end_location: closestPoint
8864			};
8865		};
8866		function isPositionOnTheRightHand(route, position) {
8867			var closestPath = findClosestPathYandex(route, position);
8868			if (!closestPath) return true;
8869			// todo: negate for left-hand roads, take info from dictionary
8870			return requiredModules.routing.getPointPositionToPath(
8871				closestPath.start_location[0], closestPath.start_location[1],
8872				closestPath.end_location[0], closestPath.end_location[1],
8873				position[0], position[1]);
8874		};
8875		function lookforClosestStationToPosition(position, stations) {
8876			if (stations && stations.length) {
8877				var closestStation = _.reduce(stations, function (prev, next) {
8878					var prevDist = getDistanceYandex(position, [prev.Latitude,prev.Longitude]);
8879					var nextDist = getDistanceYandex(position, [next.Latitude, next.Longitude]);
8880					return nextDist < prevDist ? next : prev;
8881				});
8882				return closestStation;
8883			}
8884			return null;
8885		};
8886
8887		function getDistanceOnRouteYandex(route, firstPoint, stationPosition) {
8888			var secondPoint = getNearestPointToYandex(route, stationPosition);
8889			var coords = getAllCoords(route);
8890			var firstPointIndex = _.findIndex(coords, function (p) {
8891				return p[0] === firstPoint[0] && p[1] === firstPoint[1];
8892			});
8893			var stationPositionIndex = _.findIndex(coords, function (p) {
8894				return p[0] === secondPoint[0] && p[1] === secondPoint[1];
8895			});
8896
8897			var index = 0;
8898			var pathBetweenPoints = _.filter(coords, function (p) {
8899				var result;
8900				if (firstPointIndex < stationPositionIndex) {
8901					result = firstPointIndex <= index && index <= stationPositionIndex;
8902				} else {
8903					result = stationPositionIndex <= index && index <= firstPointIndex;
8904				}
8905				index++;
8906				return result;
8907			});
8908
8909			return getPathLenthYandex(pathBetweenPoints);
8910		};
8911
8912		return {
8913			getRoutePromise: function (options) {
8914				var refPoints = options.refPoints;
8915				var origin = [refPoints.origin.latitude, refPoints.origin.longitude];
8916				var destination = [refPoints.destination.latitude, refPoints.destination.longitude];
8917				var waypoints = _.map(refPoints.waypoints, function (wp) {
8918					return [wp.latitude, wp.longitude];
8919				});
8920				var points = [origin].concat(waypoints).concat([destination]);
8921
8922				var df = $.Deferred();
8923				//return ymaps.multiRouter.MultiRoute({ referencePoints: points }, { wayPointStartVisible: false, wayPointFinishVisible: false });
8924				var ymapsDf = ymaps.route(points, { wayPointStartVisible: false, wayPointFinishVisible: false, mapStateAutoApply: true, avoidTrafficJams: options.avoidTrafficJams });
8925				ymapsDf.then(function(response) {
8926					// Sometimes Yandex returns an incomplete route.
8927					if (response.getPaths().getLength() + 1 === points.length) {
8928						df.resolve(response);
8929					} else {
8930						df.reject({ msg: GlobalSettings.Routing.PerformingRouteError, status: err.code, providerMessage: err.message });
8931					}
8932				}).fail(function(err) {
8933					df.reject({ msg: GlobalSettings.Routing.PerformingRouteError, status: err.code, providerMessage: err.message });
8934				});
8935
8936				return df;
8937			},
8938			clearRoute: function () {
8939				clearRoutes();
8940			},
8941			showRoute: function (params) {
8942				renderRoute(params);
8943			},
8944			renderAllDirections: function (parameters) {
8945				gmap = parameters.map;
8946				clearRoutes();
8947				directionResponse = parameters.directionResponse;
8948
8949				if (parameters.cancellationToken && parameters.cancellationToken.isCanceled()) {
8950					logger.log("cancellationToken isCanceled");
8951					return;
8952				}
8953
8954				renderRoute();
8955			},
8956			getBoundsForSearch: function (routeResponse) {
8957				var bounds = routeResponse.properties.get("boundedBy");
8958				var leftPoint = bounds[0];
8959				var rightPoint = bounds[1];
8960				var lngDiff = rightPoint[1] - leftPoint[1];
8961				if (lngDiff < 0) {
8962					lngDiff += 360;
8963				} else if (Math.abs(lngDiff) < 0.001) {
8964					lngDiff = 360;
8965				}
8966
8967				return { swLat: leftPoint[0], neLat: rightPoint[0], swLng: leftPoint[1], lngDiff: lngDiff };
8968			},
8969			getRouteLengthInMeters: function (route) {
8970				return getPathLenthYandex(getAllCoords(route));
8971			},
8972			getMinDistanceToRoute: function (route, positionLat, positionLng, distanceToStationToShow) {
8973				return getMinDistanceToRouteYandex(route, [positionLat, positionLng], distanceToStationToShow);
8974			},
8975			isPositionOnTheRightHand: function (route, positionLat, positionLng) {
8976				return isPositionOnTheRightHand(route, [positionLat, positionLng]);
8977			},
8978			getNearestPointTo: function (route, positionLat, positionLng) {
8979				var position = getNearestPointToYandex(route, [positionLat, positionLng]);
8980				return { Latitude: position[0], Longitude: position[1] };
8981			},
8982			getRouteStartPoint: function (route) {
8983				var position = route.getPaths().get(0).geometry.getCoordinates()[0];
8984				return { Latitude: position[0], Longitude: position[1] };
8985			},
8986			getRouteEndPoint: function (route) {
8987				var lastPath = route.getPaths().get(route.getPaths().toArray().length - 1);
8988				var lastPoints = lastPath.geometry.getCoordinates();
8989				var endPosition = lastPoints[lastPoints.length - 1];
8990				return { Latitude: endPosition[0], Longitude: endPosition[1] };
8991			},
8992			lookforClosestStationToPosition: function (positionLat, positionLng, stations) {
8993				return lookforClosestStationToPosition([positionLat, positionLng], stations);
8994			},
8995			getDistanceOnRoute: function (route, prevPositionLat, prevPositionLng, nextPositionLat, nextPositionLng) {
8996				return getDistanceOnRouteYandex(route, [prevPositionLat, prevPositionLng], [nextPositionLat, nextPositionLng]);
8997			}
8998		};
8999	})();
9000
9001	RoutingYandex.directionService = directionService;
9002
9003	RoutingYandex.on("start", function (options) {
9004
9005	});
9006
9007});;
9008// @hash v3-96FDF1636895CE7CB00B4350F8145CC862E763A3
9009// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden.
9010// Version: 2.1.1-dev-20151124-1300 (build 563ed55)
9011// Generated at:
9012///////////////////////////////////////////////////////////////////////////////
9013LukoilApp.module("Favorites", function (Favorites, LukoilApp, Backbone, Marionette, $, _) {
9014    var modules = {
9015        util: LukoilApp.module("Util")
9016    };
9017
9018    var logger = modules.util.createLogger({});
9019
9020    var settings = {
9021        favoritePagesCookieName: 'luk_favorites_pages',
9022        favoriteFilesCookieName: 'luk_favorites_files',
9023        favoriteMaterialsCookieName: 'luk_favorites_materials',
9024        favoritesBatchMaxSizeInMb: 150,
9025        favoritesMaxCount: 20,
9026        cookiesConfig: {
9027            expires: 365 * 100,
9028            path: '/' //,
9029            //domain: GlobalSettings.CookiesConfigDomain
9030        },
9031        addLinkSelector: '.favorites .favorites-add',
9032        favoritesPageItemSelector: '#favoritePageItem',
9033        favoriteListContainerSelector: ".favorites-list",
9034        countsSpan: $('.favorites li.favorites-count span'),
9035        removeItemBtnSelector: '.favorites-list .favorites-remove',
9036        removeCheckedBtnSelector: '.favorites-list .favorites-remove-checked',
9037        printCheckedBtnSel: '.favorites-list .favorites-print-checked',
9038        favoriteItemContainerSel: '.favorites-page-container',
9039        pageUrlLinkSel: 'a.bookmark-page-url',
9040        addFileLinksSelector: 'a.tooltip_favorite'
9041    };
9042
9043    var messagesTypes = {
9044        favoritesNumberExeedError: 1,
9045        pageAlreadyInFavoritesError: 2,
9046        fileAlreadyInFavoritesError: 3,
9047        materialAlreadyInFavoritesError: 4,
9048        pageAddedSuccessfully: 10,
9049        fileAddedSuccessfully: 11,
9050        filesAddedSuccessfully: 12,
9051        filesAlreadyInFavoritesError: 13
9052    };
9053
9054    var localizedMessages = {
9055        cofirmRemoving: GlobalSettings.Favorites.Confirmation,
9056        favoritesNumberExeed: GlobalSettings.Favorites.NumberExeed,
9057        pageAlreadyInFavorites: GlobalSettings.Favorites.PageAlreadyIn,
9058        fileAlreadyInFavorites: GlobalSettings.Favorites.FileAlreadyIn,
9059        materialAlreadyInFavorites: GlobalSettings.Favorites.MaterialAlreadyIn,
9060        pageAdded: GlobalSettings.Favorites.PageAdded,
9061        fileAdded: GlobalSettings.Favorites.FileAdded,
9062        filesAdded: GlobalSettings.Favorites.FilesAdded,
9063        filesAlreadyInFavorites: GlobalSettings.Favorites.FilesAlreadyIn,
9064        maxDownloadFileSizeExeed: GlobalSettings.Favorites.MaxDownloadFileSizeExeed
9065    };
9066
9067    var getMessageFor = function getMessageFor(value) {
9068        switch (value) {
9069            case messagesTypes.favoritesNumberExeedError:
9070                return localizedMessages.favoritesNumberExeed;
9071            case messagesTypes.pageAlreadyInFavoritesError:
9072                return localizedMessages.pageAlreadyInFavorites;
9073            case messagesTypes.fileAlreadyInFavoritesError:
9074                return localizedMessages.fileAlreadyInFavorites;
9075            case messagesTypes.materialAlreadyInFavoritesError:
9076                return localizedMessages.materialAlreadyInFavorites;
9077            case messagesTypes.pageAddedSuccessfully:
9078                return localizedMessages.pageAdded;
9079            case messagesTypes.fileAddedSuccessfully:
9080                return localizedMessages.fileAdded;
9081            case messagesTypes.filesAddedSuccessfully:
9082                return localizedMessages.filesAdded;
9083            case messagesTypes.filesAlreadyInFavoritesError:
9084                return localizedMessages.filesAlreadyInFavorites;
9085            default:
9086                return "";
9087        }
9088    };
9089
9090    var showMessageFor = function showMessageFor(messageValue) {
9091        var msg = getMessageFor(messageValue);
9092        if (msg) $.fancyboxMessage(msg);
9093    };
9094
9095    // ----------- Cookie Storage Facade -----------
9096    var CookieStorageFacade = function CookieStorageFacade(config) {
9097        this.config = config || {};
9098    };
9099    CookieStorageFacade.prototype.save = function callee$1$0(model) {
9100        var keyInStorage, stringyfied, str;
9101        return regeneratorRuntime.async(function callee$1$0$(context$2$0) {
9102            while (1) switch (context$2$0.prev = context$2$0.next) {
9103                case 0:
9104                    if (model) {
9105                        context$2$0.next = 2;
9106                        break;
9107                    }
9108
9109                    return context$2$0.abrupt("return");
9110
9111                case 2:
9112                    keyInStorage = model.keyInStorage;
9113                    context$2$0.next = 5;
9114                    return regeneratorRuntime.awrap(this.getStringifiedAsync(keyInStorage));
9115
9116                case 5:
9117                    stringyfied = context$2$0.sent;
9118                    context$2$0.next = 8;
9119                    return regeneratorRuntime.awrap(model.canAdd(stringyfied, this));
9120
9121                case 8:
9122                    if (context$2$0.sent) {
9123                        context$2$0.next = 10;
9124                        break;
9125                    }
9126
9127                    return context$2$0.abrupt("return", false);
9128
9129                case 10:
9130                    str = model.getStringyfied(stringyfied);
9131                    context$2$0.next = 13;
9132                    return regeneratorRuntime.awrap(GlobalData.set(keyInStorage, str));
9133
9134                case 13:
9135                    return context$2$0.abrupt("return", true);
9136
9137                case 14:
9138                case "end":
9139                    return context$2$0.stop();
9140            }
9141        }, null, this);
9142    };
9143    CookieStorageFacade.prototype.getStringifiedAsync = function callee$1$0(keyInStorage) {
9144        var result;
9145        return regeneratorRuntime.async(function callee$1$0$(context$2$0) {
9146            while (1) switch (context$2$0.prev = context$2$0.next) {
9147                case 0:
9148                    result = undefined;
9149                    context$2$0.next = 3;
9150                    return regeneratorRuntime.awrap(GlobalData.get(keyInStorage));
9151
9152                case 3:
9153                    result = context$2$0.sent;
9154                    return context$2$0.abrupt("return", result);
9155
9156                case 5:
9157                case "end":
9158                    return context$2$0.stop();
9159            }
9160        }, null, this);
9161    };
9162    //$.lukoilGetCookie(keyInStorage);
9163    CookieStorageFacade.prototype.getStringified = function (keyInStorage) {
9164        //console.log(Cookies.get(keyInStorage));
9165        return $.lukoilGetCookie(keyInStorage);
9166        //return atob($.lukoilGetCookie(keyInStorage) === undefined ? "" : $.lukoilGetCookie(keyInStorage));
9167    };
9168
9169    CookieStorageFacade.prototype.remove = function (model) {
9170        ///????
9171        if (!model) return;
9172        var keyInStorage = model.keyInStorage;
9173        var stringyfied = this.getStringified(keyInStorage); // TTTT
9174        var str = model.removeFrom(stringyfied);
9175        //GlobalData.remove(keyInStorage); ///
9176        Cookies.set(keyInStorage, str, this.config);
9177        //$.lukoilSaveCookie(keyInStorage, str, this.config);
9178        //$.lukoilSaveCookie(keyInStorage, btoa(str), this.config);
9179    };
9180    CookieStorageFacade.prototype.removeAll = function callee$1$0() {
9181        return regeneratorRuntime.async(function callee$1$0$(context$2$0) {
9182            while (1) switch (context$2$0.prev = context$2$0.next) {
9183                case 0:
9184                    /// add something here
9185                    $.removeCookie(settings.favoriteFilesCookieName, { path: settings.cookiesConfig.path /*, domain: settings.cookiesConfig.domain*/ });
9186                    $.removeCookie(settings.favoritePagesCookieName, { path: settings.cookiesConfig.path /*, domain: settings.cookiesConfig.domain*/ });
9187
9188                case 2:
9189                case "end":
9190                    return context$2$0.stop();
9191            }
9192        }, null, this);
9193    };
9194
9195    var cookieStorageFacade = new CookieStorageFacade(settings.cookiesConfig);
9196
9197    // ----------- Util functions -----------
9198    function getTotalFavoriteItemsCountAsync() {
9199        var files, pages, materials, fileList, pageList, materialsList, filesInMaterialsCount;
9200        return regeneratorRuntime.async(function getTotalFavoriteItemsCountAsync$(context$2$0) {
9201            while (1) switch (context$2$0.prev = context$2$0.next) {
9202                case 0:
9203                    context$2$0.next = 2;
9204                    return regeneratorRuntime.awrap(cookieStorageFacade.getStringifiedAsync(settings.favoriteFilesCookieName));
9205
9206                case 2:
9207                    files = context$2$0.sent;
9208                    context$2$0.next = 5;
9209                    return regeneratorRuntime.awrap(cookieStorageFacade.getStringifiedAsync(settings.favoritePagesCookieName));
9210
9211                case 5:
9212                    pages = context$2$0.sent;
9213                    context$2$0.next = 8;
9214                    return regeneratorRuntime.awrap(cookieStorageFacade.getStringifiedAsync(settings.favoriteMaterialsCookieName));
9215
9216                case 8:
9217                    materials = context$2$0.sent;
9218                    fileList = files ? JSON.parse(files) : [];
9219                    pageList = pages ? JSON.parse(pages) : [];
9220                    materialsList = materials ? JSON.parse(materials) : [];
9221                    filesInMaterialsCount = _.reduce(materialsList, function (prev, next) {
9222                        return prev + next.c;
9223                    }, 0);
9224                    return context$2$0.abrupt("return", fileList.length + pageList.length + filesInMaterialsCount);
9225
9226                case 14:
9227                case "end":
9228                    return context$2$0.stop();
9229            }
9230        }, null, this);
9231    }
9232
9233    function getTotalFavoriteItemsCount() {
9234        var files = cookieStorageFacade.getStringified(settings.favoriteFilesCookieName);
9235        var pages = cookieStorageFacade.getStringified(settings.favoritePagesCookieName);
9236        //console.log("TFIC");
9237        var materials = cookieStorageFacade.getStringified(settings.favoriteMaterialsCookieName);
9238        var fileList = files ? JSON.parse(files) : [];
9239        var pageList = pages ? JSON.parse(pages) : [];
9240        var materialsList = materials ? JSON.parse(materials) : [];
9241        var filesInMaterialsCount = _.reduce(materialsList, function (prev, next) {
9242            return prev + next.c;
9243        }, 0);
9244        return fileList.length + pageList.length + filesInMaterialsCount;
9245    }
9246
9247    function isMaxCountExeed() {
9248        return regeneratorRuntime.async(function isMaxCountExeed$(context$2$0) {
9249            while (1) switch (context$2$0.prev = context$2$0.next) {
9250                case 0:
9251                    context$2$0.next = 2;
9252                    return regeneratorRuntime.awrap(getTotalFavoriteItemsCountAsync());
9253
9254                case 2:
9255                    context$2$0.t0 = context$2$0.sent;
9256                    context$2$0.t1 = settings.favoritesMaxCount;
9257                    return context$2$0.abrupt("return", context$2$0.t0 >= context$2$0.t1);
9258
9259                case 5:
9260                case "end":
9261                    return context$2$0.stop();
9262            }
9263        }, null, this);
9264    };
9265    var calculateSizeInMb = function calculateSizeInMb(filesize) {
9266        return Math.floor(filesize / (1024 * 1024));
9267    };
9268    function trimAny(str, chars) {
9269        var start = 0,
9270            end = str.length;
9271
9272        while (start < end && chars.indexOf(str[start]) >= 0) ++start;
9273
9274        while (end > start && chars.indexOf(str[end - 1]) >= 0) --end;
9275
9276        return start > 0 || end < str.length ? str.substring(start, end) : str;
9277    }
9278    function getHost(href) {
9279        return Object.assign(document.createElement('a'), { href: href }).host;
9280    }
9281    var showFavoritesCountAsync = function showFavoritesCountAsync() {
9282        var countsSpan, format, itemsCount, resultText;
9283        return regeneratorRuntime.async(function showFavoritesCountAsync$(context$2$0) {
9284            while (1) switch (context$2$0.prev = context$2$0.next) {
9285                case 0:
9286                    countsSpan = $('.favorites .favorites-count span[data-count-template]');
9287
9288                    if (countsSpan) {
9289                        context$2$0.next = 3;
9290                        break;
9291                    }
9292
9293                    return context$2$0.abrupt("return");
9294
9295                case 3:
9296                    format = countsSpan.data("count-template");
9297
9298                    if (format) {
9299                        context$2$0.next = 6;
9300                        break;
9301                    }
9302
9303                    return context$2$0.abrupt("return");
9304
9305                case 6:
9306                    context$2$0.next = 8;
9307                    return regeneratorRuntime.awrap(getTotalFavoriteItemsCountAsync());
9308
9309                case 8:
9310                    itemsCount = context$2$0.sent;
9311                    resultText = format.replace("{0}", itemsCount);
9312
9313                    countsSpan.html(resultText);
9314
9315                    //    var favLink = $("#favorites-link");
9316                    //    var url = favLink.attr("href");
9317
9318                    //    if (window.location.host != getHost(url)) {
9319                    //        var files = await cookieStorageFacade.getStringifiedAsync(settings.favoriteFilesCookieName);
9320                    //        var pages = await cookieStorageFacade.getStringifiedAsync(settings.favoritePagesCookieName);
9321                    //        var queryString = "";
9322
9323                    //        if (url && url.indexOf("?") > -1)
9324                    //            url = url.substring(0, url.indexOf("?"));
9325                    //        if (files)
9326                    //            queryString += "files=" + btoa(files) + "&";
9327                    //        if (pages)
9328                    //            queryString += "pages=" + btoa(pages) + "&";
9329                    //        queryString = queryString.replace(/^&*|&*$/g, '');
9330                    //        if (queryString.length > 0)
9331                    //            favLink.attr("href", url + "?" + queryString);
9332                    //    }
9333
9334                case 11:
9335                case "end":
9336                    return context$2$0.stop();
9337            }
9338        }, null, this);
9339    };
9340
9341    var showFavoritesCount = function showFavoritesCount() {
9342        var countsSpan = $('.favorites .favorites-count span[data-count-template]');
9343        if (!countsSpan) return;
9344        var format = countsSpan.data("count-template");
9345        if (!format) return;
9346        var itemsCount = getTotalFavoriteItemsCount();
9347        var resultText = format.replace("{0}", itemsCount);
9348        countsSpan.html(resultText);
9349
9350        //    var favLink = $("#favorites-link");
9351        //    var url = favLink.attr("href");
9352
9353        //    if (window.location.host != getHost(url)) {
9354        //        var files = cookieStorageFacade.getStringified(settings.favoriteFilesCookieName);
9355        //        var pages = cookieStorageFacade.getStringified(settings.favoritePagesCookieName);
9356        //        var queryString = "";
9357
9358        //        if (url && url.indexOf("?") > -1)
9359        //            url = url.substring(0, url.indexOf("?"));
9360        //        if (files)
9361        //            queryString += "files=" + btoa(files) + "&";
9362        //        if (pages)
9363        //            queryString += "pages=" + btoa(pages) + "&";
9364        //        queryString = queryString.replace(/^&*|&*$/g, '');
9365        //        if (queryString.length > 0)
9366        //            favLink.attr("href", url + "?" + queryString);
9367        //    }
9368    };
9369
9370    function createFavoriteFileFromInputData(input) {
9371        var $input = $(input);
9372        var idToRemove = $input.data("fileid");
9373        var typeToRemove = $input.data("librarytype");
9374        var filesize = parseFloat($input.data("filesize"));
9375        return new FavoriteFile(idToRemove, typeToRemove, filesize);
9376    };
9377
9378    // ----------- Page Model -----------
9379    var FavoritePage = function FavoritePage(id, itemParam, itemType) {
9380        this.id = id;
9381        this.itemParam = isNaN(itemParam) ? null : itemParam;
9382        this.itemType = isNaN(itemType) ? null : itemType;
9383        this.lastErrorType = "";
9384    };
9385    FavoritePage.prototype.shorten = function () {
9386        return { i: this.id, p: this.itemParam, t: this.itemType };
9387    };
9388    FavoritePage.prototype.parse = function (shortPage) {
9389        return new FavoritePage(shortPage.i, shortPage.p, shortPage.t);
9390    };
9391    var PageModel = function PageModel(keyInStorage, item) {
9392        this.keyInStorage = keyInStorage;
9393        this.item = item;
9394    };
9395    PageModel.prototype.getLastErrorType = function () {
9396        return this.lastErrorType;
9397    };
9398    PageModel.prototype.canAdd = function callee$1$0(stringyfied) {
9399        var list, item, isItemAlreadyAdded;
9400        return regeneratorRuntime.async(function callee$1$0$(context$2$0) {
9401            while (1) switch (context$2$0.prev = context$2$0.next) {
9402                case 0:
9403                    this.lastErrorType = "";
9404                    context$2$0.next = 3;
9405                    return regeneratorRuntime.awrap(isMaxCountExeed());
9406
9407                case 3:
9408                    if (!context$2$0.sent) {
9409                        context$2$0.next = 6;
9410                        break;
9411                    }
9412
9413                    this.lastErrorType = messagesTypes.favoritesNumberExeedError;
9414                    return context$2$0.abrupt("return", false);
9415
9416                case 6:
9417                    list = stringyfied ? JSON.parse(stringyfied) : [];
9418                    item = this.item;
9419                    isItemAlreadyAdded = _.any(list, function (f) {
9420                        return f.i === item.id && f.p === item.itemParam && f.t === item.itemType;
9421                    });
9422
9423                    if (!isItemAlreadyAdded) {
9424                        context$2$0.next = 12;
9425                        break;
9426                    }
9427
9428                    this.lastErrorType = messagesTypes.pageAlreadyInFavoritesError;
9429                    return context$2$0.abrupt("return", false);
9430
9431                case 12:
9432                    return context$2$0.abrupt("return", true);
9433
9434                case 13:
9435                case "end":
9436                    return context$2$0.stop();
9437            }
9438        }, null, this);
9439    };
9440    PageModel.prototype.getStringyfied = function (stringyfied) {
9441        var modelList = stringyfied ? JSON.parse(stringyfied) : [];
9442        modelList.push(this.item.shorten());
9443        return JSON.stringify(modelList);
9444    };
9445    PageModel.prototype.removeFrom = function (stringyfied) {
9446        var list = stringyfied ? JSON.parse(stringyfied) : [];
9447        var item = this.item;
9448        list = list.filter(function (current) {
9449            return current.i !== item.id || current.p !== item.itemParam || current.t !== item.itemType;
9450        });
9451        return JSON.stringify(list);
9452    };
9453
9454    // ----------- Material Model -----------
9455    var FavoriteMaterial = function FavoriteMaterial(id, filesCount) {
9456        this.id = id;
9457        this.filesCount = filesCount;
9458        this.lastErrorType = "";
9459    };
9460    FavoriteMaterial.prototype.shorten = function () {
9461        return { i: this.id, c: this.filesCount };
9462    };
9463    FavoriteMaterial.prototype.parse = function (shortFile) {
9464        return new FavoriteMaterial(shortFile.i, shortFile.c);
9465    };
9466    var MaterialModel = function MaterialModel(item) {
9467        this.keyInStorage = settings.favoriteMaterialsCookieName;
9468        this.item = item;
9469    };
9470    MaterialModel.prototype.getLastErrorType = function () {
9471        return this.lastErrorType;
9472    };
9473    MaterialModel.prototype.canAdd = function callee$1$0(stringyfied) {
9474        var total, list, item, isItemAlreadyAdded;
9475        return regeneratorRuntime.async(function callee$1$0$(context$2$0) {
9476            while (1) switch (context$2$0.prev = context$2$0.next) {
9477                case 0:
9478                    this.lastErrorType = "";
9479                    context$2$0.next = 3;
9480                    return regeneratorRuntime.awrap(getTotalFavoriteItemsCountAsync());
9481
9482                case 3:
9483                    total = context$2$0.sent;
9484
9485                    if (!(total + this.item.filesCount > settings.favoritesMaxCount)) {
9486                        context$2$0.next = 7;
9487                        break;
9488                    }
9489
9490                    this.lastErrorType = messagesTypes.favoritesNumberExeedError;
9491                    return context$2$0.abrupt("return", false);
9492
9493                case 7:
9494                    list = stringyfied ? JSON.parse(stringyfied) : [];
9495                    item = this.item;
9496                    isItemAlreadyAdded = _.any(list, function (current) {
9497                        return current.i === item.id;
9498                    });
9499
9500                    if (!isItemAlreadyAdded) {
9501                        context$2$0.next = 13;
9502                        break;
9503                    }
9504
9505                    this.lastErrorType = messagesTypes.materialAlreadyInFavoritesError;
9506                    return context$2$0.abrupt("return", false);
9507
9508                case 13:
9509                    return context$2$0.abrupt("return", true);
9510
9511                case 14:
9512                case "end":
9513                    return context$2$0.stop();
9514            }
9515        }, null, this);
9516    };
9517    MaterialModel.prototype.getStringyfied = function (stringyfied) {
9518        var list = stringyfied ? JSON.parse(stringyfied) : [];
9519        list.push(this.item.shorten());
9520        return JSON.stringify(list);
9521    };
9522    // ----------- File Model -----------
9523    var FavoriteFile = function FavoriteFile(fileid, librarytype, filesize) {
9524        this.fileid = fileid;
9525        this.librarytype = librarytype;
9526        this.filesize = filesize || 0;
9527        this.lastErrorType = "";
9528    };
9529    FavoriteFile.prototype.shorten = function () {
9530        return { i: this.fileid, t: this.librarytype };
9531    };
9532    FavoriteFile.prototype.parse = function (shortFile) {
9533        return new FavoriteFile(shortFile.i, shortFile.t);
9534    };
9535    var FileModel = function FileModel(keyInStorage, item) {
9536        this.keyInStorage = keyInStorage;
9537        this.item = item;
9538    };
9539    FileModel.prototype.getLastErrorType = function () {
9540        return this.lastErrorType;
9541    };
9542    FileModel.prototype.canAdd = function callee$1$0(stringyfied) {
9543        var list, item, isItemAlreadyAdded;
9544        return regeneratorRuntime.async(function callee$1$0$(context$2$0) {
9545            while (1) switch (context$2$0.prev = context$2$0.next) {
9546                case 0:
9547                    this.lastErrorType = "";
9548                    context$2$0.next = 3;
9549                    return regeneratorRuntime.awrap(isMaxCountExeed());
9550
9551                case 3:
9552                    if (!context$2$0.sent) {
9553                        context$2$0.next = 6;
9554                        break;
9555                    }
9556
9557                    this.lastErrorType = messagesTypes.favoritesNumberExeedError;
9558                    return context$2$0.abrupt("return", false);
9559
9560                case 6:
9561                    list = stringyfied ? JSON.parse(stringyfied) : [];
9562                    item = this.item;
9563                    isItemAlreadyAdded = _.any(list, function (current) {
9564                        return current.i === item.fileid && current.t === item.librarytype;
9565                    });
9566
9567                    if (!isItemAlreadyAdded) {
9568                        context$2$0.next = 12;
9569                        break;
9570                    }
9571
9572                    this.lastErrorType = messagesTypes.fileAlreadyInFavoritesError;
9573                    return context$2$0.abrupt("return", false);
9574
9575                case 12:
9576                    return context$2$0.abrupt("return", true);
9577
9578                case 13:
9579                case "end":
9580                    return context$2$0.stop();
9581            }
9582        }, null, this);
9583    };
9584    FileModel.prototype.getStringyfied = function (stringyfied) {
9585        var list = stringyfied ? JSON.parse(stringyfied) : [];
9586        list.push(this.item.shorten());
9587        return JSON.stringify(list);
9588    };
9589    FileModel.prototype.removeFrom = function (stringyfied) {
9590        var list = stringyfied ? JSON.parse(stringyfied) : [];
9591        var item = this.item;
9592        list = _.filter(list, function (current) {
9593            return current.i !== item.fileid || current.t !== item.librarytype;
9594        });
9595        return JSON.stringify(list);
9596    };
9597    // ----------- Model END -----------
9598
9599    // ----------- Add to cookis -----------
9600    function saveModelAndRefreshCount(model, successMessageType, skipDialog) {
9601        var fileNotExistInCache, errMessageType;
9602        return regeneratorRuntime.async(function saveModelAndRefreshCount$(context$2$0) {
9603            while (1) switch (context$2$0.prev = context$2$0.next) {
9604                case 0:
9605                    context$2$0.next = 2;
9606                    return regeneratorRuntime.awrap(cookieStorageFacade.save(model));
9607
9608                case 2:
9609                    fileNotExistInCache = context$2$0.sent;
9610                    errMessageType = model.getLastErrorType();
9611
9612                    if (!skipDialog) {
9613                        if (errMessageType) showMessageFor(errMessageType);else showMessageFor(successMessageType);
9614                    }
9615
9616                    context$2$0.next = 7;
9617                    return regeneratorRuntime.awrap(showFavoritesCountAsync());
9618
9619                case 7:
9620                    return context$2$0.abrupt("return", fileNotExistInCache);
9621
9622                case 8:
9623                case "end":
9624                    return context$2$0.stop();
9625            }
9626        }, null, this);
9627    }
9628
9629    Favorites.AddFile = function callee$1$0(fileid, librarytype) {
9630        var file, fileModel;
9631        return regeneratorRuntime.async(function callee$1$0$(context$2$0) {
9632            while (1) switch (context$2$0.prev = context$2$0.next) {
9633                case 0:
9634                    if (!(fileid && librarytype)) {
9635                        context$2$0.next = 6;
9636                        break;
9637                    }
9638
9639                    file = new FavoriteFile(fileid, librarytype);
9640                    fileModel = new FileModel(settings.favoriteFilesCookieName, file);
9641                    context$2$0.next = 5;
9642                    return regeneratorRuntime.awrap(saveModelAndRefreshCount(fileModel, messagesTypes.fileAddedSuccessfully));
9643
9644                case 5:
9645                    return context$2$0.abrupt("return", context$2$0.sent);
9646
9647                case 6:
9648                case "end":
9649                    return context$2$0.stop();
9650            }
9651        }, null, this);
9652    };
9653
9654    Favorites.AddFiles = function callee$1$0(files) {
9655        var filesAdded, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, f, curfileIsAdded;
9656
9657        return regeneratorRuntime.async(function callee$1$0$(context$2$0) {
9658            while (1) switch (context$2$0.prev = context$2$0.next) {
9659                case 0:
9660                    if (!files) {
9661                        context$2$0.next = 31;
9662                        break;
9663                    }
9664
9665                    filesAdded = false;
9666                    _iteratorNormalCompletion = true;
9667                    _didIteratorError = false;
9668                    _iteratorError = undefined;
9669                    context$2$0.prev = 5;
9670                    _iterator = files[Symbol.iterator]();
9671
9672                case 7:
9673                    if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
9674                        context$2$0.next = 16;
9675                        break;
9676                    }
9677
9678                    f = _step.value;
9679                    context$2$0.next = 11;
9680                    return regeneratorRuntime.awrap(Favorites.AddFile(f.id || f.Id, f.librarytype || f.LibraryType, true));
9681
9682                case 11:
9683                    curfileIsAdded = context$2$0.sent;
9684
9685                    filesAdded = filesAdded || curfileIsAdded;
9686
9687                case 13:
9688                    _iteratorNormalCompletion = true;
9689                    context$2$0.next = 7;
9690                    break;
9691
9692                case 16:
9693                    context$2$0.next = 22;
9694                    break;
9695
9696                case 18:
9697                    context$2$0.prev = 18;
9698                    context$2$0.t0 = context$2$0["catch"](5);
9699                    _didIteratorError = true;
9700                    _iteratorError = context$2$0.t0;
9701
9702                case 22:
9703                    context$2$0.prev = 22;
9704                    context$2$0.prev = 23;
9705
9706                    if (!_iteratorNormalCompletion && _iterator["return"]) {
9707                        _iterator["return"]();
9708                    }
9709
9710                case 25:
9711                    context$2$0.prev = 25;
9712
9713                    if (!_didIteratorError) {
9714                        context$2$0.next = 28;
9715                        break;
9716                    }
9717
9718                    throw _iteratorError;
9719
9720                case 28:
9721                    return context$2$0.finish(25);
9722
9723                case 29:
9724                    return context$2$0.finish(22);
9725
9726                case 30:
9727                    //_.each(files, async function (f) {
9728                    //    var curfileIsAdded = await Favorites.AddFile(f.id || f.Id, f.librarytype || f.LibraryType, true);
9729                    //    filesAdded = filesAdded || curfileIsAdded;
9730                    //});
9731                    if (filesAdded) {
9732                        showMessageFor(messagesTypes.filesAddedSuccessfully);
9733                    } else {
9734                        showMessageFor(messagesTypes.filesAlreadyInFavoritesError);
9735                    }
9736
9737                case 31:
9738                case "end":
9739                    return context$2$0.stop();
9740            }
9741        }, null, this, [[5, 18, 22, 30], [23,, 25, 29]]);
9742    };
9743
9744    Favorites.AddMaterial = function callee$1$0(materialid, filesCount) {
9745        var entity, model;
9746        return regeneratorRuntime.async(function callee$1$0$(context$2$0) {
9747            while (1) switch (context$2$0.prev = context$2$0.next) {
9748                case 0:
9749                    entity = new FavoriteMaterial(materialid, filesCount);
9750                    model = new MaterialModel(entity);
9751                    context$2$0.next = 4;
9752                    return regeneratorRuntime.awrap(saveModelAndRefreshCount(model, filesCount > 1 ? messagesTypes.filesAddedSuccessfully : messagesTypes.fileAddedSuccessfully));
9753
9754                case 4:
9755                case "end":
9756                    return context$2$0.stop();
9757            }
9758        }, null, this);
9759    };
9760
9761    var addPage = function addPage(currPageId, currPageItemParam, currPageItemType) {
9762        var page, pageModel, errMessageType;
9763        return regeneratorRuntime.async(function addPage$(context$2$0) {
9764            while (1) switch (context$2$0.prev = context$2$0.next) {
9765                case 0:
9766                    if (!currPageId) {
9767                        context$2$0.next = 11;
9768                        break;
9769                    }
9770
9771                    page = new FavoritePage(currPageId, currPageItemParam, currPageItemType);
9772                    pageModel = new PageModel(settings.favoritePagesCookieName, page);
9773                    context$2$0.next = 5;
9774                    return regeneratorRuntime.awrap(cookieStorageFacade.save(pageModel));
9775
9776                case 5:
9777                    errMessageType = pageModel.getLastErrorType();
9778
9779                    if (errMessageType) showMessageFor(errMessageType);else showMessageFor(messagesTypes.pageAddedSuccessfully);
9780                    context$2$0.next = 9;
9781                    return regeneratorRuntime.awrap(showFavoritesCountAsync());
9782
9783                case 9:
9784                    context$2$0.next = 12;
9785                    break;
9786
9787                case 11:
9788                    logger.log("page id is not defined for favorites");
9789
9790                case 12:
9791                case "end":
9792                    return context$2$0.stop();
9793            }
9794        }, null, this);
9795    };
9796    // ----------- Add to cookis END -----------
9797
9798    // ----------- Remove actions -----------
9799    function showMessageForEmptyFavorites(input) {
9800        var $container = $(input).closest('.favorites-list');
9801        $container.hide().prev().removeClass("hidden");
9802    };
9803
9804    function removeModelAndHideInput(model, input) {
9805        var $input = $(input);
9806        var $link = $input.closest(settings.favoriteItemContainerSel);
9807        cookieStorageFacade.remove(model);
9808        var tF = getTotalFavoriteItemsCount();
9809        $link.fadeOut(function () {
9810            if (!tF) showMessageForEmptyFavorites(input);
9811            var bm = $input.closest(".bookmark");
9812            $link.remove();
9813
9814            if (!bm.find("input").length) {
9815                bm.parent().hide().next().hide();
9816            }
9817        });
9818    }
9819    var executeRemovePageAction = function executeRemovePageAction(input) {
9820        var idToRemove = $(input).data("page-id");
9821        var itemParamToRemove = $(input).data("item-param");
9822        var itemTypeToRemove = $(input).data("item-type");
9823        var itemIsFromCookie = $(input).data("item-isfromcookie");
9824        var model = new PageModel(settings.favoritePagesCookieName, new FavoritePage(idToRemove, itemParamToRemove, itemTypeToRemove));
9825        removeModelAndHideInput(model, input);
9826    };
9827
9828    var executeRemoveFileAction = function executeRemoveFileAction(input) {
9829        var model = new FileModel(settings.favoriteFilesCookieName, createFavoriteFileFromInputData(input));
9830        removeModelAndHideInput(model, input);
9831    };
9832    // ----------- Remove actions END -----------
9833
9834    function inIframe() {
9835        try {
9836            return window.self !== window.top;
9837        } catch (e) {
9838            return true;
9839        }
9840    }
9841
9842    if (inIframe() && $.lukoilGetCookie("printMode") === "True") {
9843        //console.log('binding');
9844        if (document.readyState === "loading") {
9845            window.addEventListener ? window.addEventListener("DOMContentLoaded", printIt, false) : window.attachEvent && window.attachEvent("onDOMContentLoaded ", printIt);
9846        } else {
9847            printIt();
9848        }
9849        //Cookies.remove("printMode");
9850    }
9851
9852    function printIt() {
9853        //console.log('print');
9854        var $title = $(document).find(".page-title h1");
9855        var fullTitle = $title.data("full-title");
9856        if (fullTitle) $title.text(fullTitle);
9857
9858        window.print();
9859    }
9860
9861    Favorites.run = function callee$1$0() {
9862        var $addLinks, removePages, removeFiles, downloadFiles, removeAll, koObject, restoreTitleEllipsedWithDotJqueryPlugin, callPrint, printCheckedPages, favorsContainer;
9863        return regeneratorRuntime.async(function callee$1$0$(context$2$0) {
9864            while (1) switch (context$2$0.prev = context$2$0.next) {
9865                case 0:
9866                    printCheckedPages = function printCheckedPages(data, event) {
9867                        if (koObject.LoadingInProccess()) return false;
9868                        var checkedInputs = $(event.target).closest(".panel-content").prev().find("input:checked");
9869                        if (checkedInputs.length) koObject.LoadingInProccess(true);
9870
9871                        var loadingIframesIndexes = [];
9872                        _.each(checkedInputs, function (checkedInput, index, list) {
9873                            var $link = $(checkedInput).closest(settings.favoriteItemContainerSel).find(settings.pageUrlLinkSel);
9874                            var url = $link.attr("href");
9875
9876                            if (url == null || url === "") {
9877                                return true;
9878                            }
9879
9880                            var iframeId = 'iframePrint';
9881                            var $iframe = $("iframe#" + iframeId);
9882
9883                            // remove previous iframes
9884                            if (index === 0 && $iframe.length !== 0) {
9885                                $iframe.remove();
9886                                $iframe = $("iframe#" + iframeId);
9887                            }
9888
9889                            if ($iframe.length === 0) {
9890                                // create new host iframe
9891                                $("body").append("<iframe class='printIframe' id='" + iframeId + "'></iframe>");
9892                                $iframe = $("iframe#" + iframeId);
9893                                url = url.replace("http://", "https://");
9894                                if (url.includes("?")) url += "&printmode=1";else url += "?printmode=1";
9895                                $iframe.attr("src", url);
9896
9897                                if (list.length === 1) {
9898                                    $iframe.load(function () {
9899                                        restoreTitleEllipsedWithDotJqueryPlugin($iframe);
9900                                        callPrint(iframeId);
9901                                    });
9902                                }
9903                            } else {
9904                                // add child iframe
9905                                var _index = index;
9906                                var _url = url;
9907                                loadingIframesIndexes.push(_index);
9908                                $iframe.load(function () {
9909                                    restoreTitleEllipsedWithDotJqueryPlugin($iframe);
9910                                    var newFrameId = iframeId + "_" + _index;
9911                                    $("body").find("#" + newFrameId).remove();
9912                                    $("body").first().append("<iframe class='printIframe' id='" + newFrameId + "'></iframe>");
9913                                    var $newIframe = $("body").first().find("iframe#" + newFrameId);
9914                                    _url = _url.replace("http://", "https://");
9915                                    if (_url.includes("?")) _url += "&printmode=1";else _url += "?printmode=1";
9916                                    $newIframe.attr("src", _url);
9917                                    $newIframe.load(function () {
9918                                        restoreTitleEllipsedWithDotJqueryPlugin($newIframe);
9919                                        /*var newIframeContents = $newIframe.contents().find("body");
9920                                        $iframe.contents()
9921                                            .find("body").first()
9922                                            .append("<div style='page-break-before: always;'></div>")
9923                                            .append(newIframeContents);*/
9924                                        loadingIframesIndexes = _.filter(loadingIframesIndexes, function (ind) {
9925                                            return ind !== _index;
9926                                        });
9927
9928                                        if (loadingIframesIndexes.length === 0) {
9929                                            callPrint(iframeId);
9930                                        }
9931                                    });
9932                                });
9933                            }
9934                        });
9935
9936                        return false;
9937                    };
9938
9939                    callPrint = function callPrint(iframeId) {
9940                        koObject.LoadingInProccess(false);
9941                        return;
9942                        var iframe = document.getElementById(iframeId).contentWindow;
9943                        iframe.focus();
9944                        iframe.print();
9945                    };
9946
9947                    restoreTitleEllipsedWithDotJqueryPlugin = function restoreTitleEllipsedWithDotJqueryPlugin($iframe) {
9948                        return;
9949                        var page = $iframe[0];
9950                        var iframeDocument = page.contentDocument || page.contentWindow.document;
9951                        var $title = $(iframeDocument).find(".page-title h1");
9952                        var fullTitle = $title.data("full-title");
9953                        if (fullTitle) $title.text(fullTitle);
9954                    };
9955
9956                    removeAll = function removeAll(data, event) {
9957                        var needToDelete;
9958                        return regeneratorRuntime.async(function removeAll$(context$3$0) {
9959                            while (1) switch (context$3$0.prev = context$3$0.next) {
9960                                case 0:
9961                                    needToDelete = false;
9962
9963                                    $.fancyConfirm(localizedMessages.cofirmRemoving, function callee$3$0(confirmResult) {
9964                                        return regeneratorRuntime.async(function callee$3$0$(context$4$0) {
9965                                            while (1) switch (context$4$0.prev = context$4$0.next) {
9966                                                case 0:
9967                                                    if (confirmResult) {
9968                                                        cookieStorageFacade.removeAll();
9969                                                        showMessageForEmptyFavorites(event.target);
9970                                                        showFavoritesCount();
9971                                                    }
9972
9973                                                case 1:
9974                                                case "end":
9975                                                    return context$4$0.stop();
9976                                            }
9977                                        }, null, this);
9978                                    }, "YesNo");
9979
9980                                case 2:
9981                                case "end":
9982                                    return context$3$0.stop();
9983                            }
9984                        }, null, this);
9985                    };
9986
9987                    downloadFiles = function downloadFiles(data, event) {
9988                        var $checkedInputs = $(event.target).closest("div.panel-content").prev().find("input:checked");
9989                        if ($checkedInputs.length) {
9990                            var queryParams = "";
9991                            var totalFileSize = 0.0;
9992                            _.each($checkedInputs, function (input) {
9993                                var file = createFavoriteFileFromInputData(input);
9994                                queryParams += file.fileid + "," + file.librarytype + ";";
9995                                totalFileSize += file.filesize;
9996                            });
9997
9998                            var sizeInMb = calculateSizeInMb(totalFileSize);
9999                            if (sizeInMb > settings.favoritesBatchMaxSizeInMb) {
10000                                var msg = localizedMessages.maxDownloadFileSizeExeed.replace("{0}", settings.favoritesBatchMaxSizeInMb);
10001                                $.fancyboxMessage(msg);
10002                            } else window.location.href = "/Handlers/DownloadMaterialsArchiveHandler.ashx?f=" + queryParams;
10003                        }
10004                    };
10005
10006                    removeFiles = function removeFiles(data, event) {
10007                        var $checkedInputs, needToDelete;
10008                        return regeneratorRuntime.async(function removeFiles$(context$3$0) {
10009                            while (1) switch (context$3$0.prev = context$3$0.next) {
10010                                case 0:
10011                                    $checkedInputs = $(event.target).closest("div.panel-content").prev().find("input:checked");
10012
10013                                    if ($checkedInputs.length) {
10014                                        needToDelete = false;
10015
10016                                        $.fancyConfirm(localizedMessages.cofirmRemoving, function callee$3$0(confirmResult) {
10017                                            return regeneratorRuntime.async(function callee$3$0$(context$4$0) {
10018                                                while (1) switch (context$4$0.prev = context$4$0.next) {
10019                                                    case 0:
10020                                                        if (confirmResult) {
10021                                                            /*for (var checkedInput of $checkedInputs) {
10022                                                                executeRemovePageAction(checkedInput);
10023                                                            }*/
10024                                                            _.each($checkedInputs, function callee$4$0(checkedInput) {
10025                                                                return regeneratorRuntime.async(function callee$4$0$(context$5$0) {
10026                                                                    while (1) switch (context$5$0.prev = context$5$0.next) {
10027                                                                        case 0:
10028                                                                            context$5$0.next = 2;
10029                                                                            return regeneratorRuntime.awrap(executeRemoveFileAction(checkedInput));
10030
10031                                                                        case 2:
10032                                                                        case "end":
10033                                                                            return context$5$0.stop();
10034                                                                    }
10035                                                                }, null, this);
10036                                                            });
10037                                                            showFavoritesCount();
10038                                                        }
10039
10040                                                    case 1:
10041                                                    case "end":
10042                                                        return context$4$0.stop();
10043                                                }
10044                                            }, null, this);
10045                                        }, "YesNo");
10046                                    }
10047
10048                                case 2:
10049                                case "end":
10050                                    return context$3$0.stop();
10051                            }
10052                        }, null, this);
10053                    };
10054
10055                    removePages = function removePages(data, event) {
10056                        var $checkedInputs = $(event.target).closest("div.panel-content").prev().find("input:checked");
10057                        if ($checkedInputs.length) {
10058                            var needToDelete = false;
10059                            $.fancyConfirm(localizedMessages.cofirmRemoving, function (confirmResult) {
10060                                if (confirmResult) {
10061                                    //for (var checkedInput of $checkedInputs) {
10062                                    //    executeRemovePageAction(checkedInput);
10063                                    //}
10064                                    _.each($checkedInputs, function (checkedInput) {
10065                                        executeRemovePageAction(checkedInput);
10066                                    });
10067                                    showFavoritesCount();
10068                                }
10069                            }, "YesNo");
10070                        }
10071                    };
10072
10073                    //var printMode = $.lukoilGetCookie("printMode") === "True";
10074                    if (typeof globalDataApi !== 'undefined' && isPageForFavorites === true /*&& !printMode*/) GlobalData.initsync(globalDataApi, globalDataLicense);else {//if (typeof isPageForFavorites !== 'undefined' && isPageForFavorites === true && printMode) {
10075                        //return;
10076                    }
10077
10078                    $addLinks = $(settings.addLinkSelector);
10079                    context$2$0.next = 11;
10080                    return regeneratorRuntime.awrap(showFavoritesCountAsync());
10081
10082                case 11:
10083                    $addLinks.on("click", function callee$2$0() {
10084                        var currPageId, currPageItemParam, currPageItemType;
10085                        return regeneratorRuntime.async(function callee$2$0$(context$3$0) {
10086                            while (1) switch (context$3$0.prev = context$3$0.next) {
10087                                case 0:
10088                                    currPageId = parseInt($(this).data("current-page-id"));
10089                                    currPageItemParam = parseInt($(settings.favoritesPageItemSelector).data("item-param"));
10090                                    currPageItemType = parseInt($(settings.favoritesPageItemSelector).data("item-type"));
10091                                    context$3$0.next = 5;
10092                                    return regeneratorRuntime.awrap(addPage(currPageId, currPageItemParam, currPageItemType));
10093
10094                                case 5:
10095                                case "end":
10096                                    return context$3$0.stop();
10097                            }
10098                        }, null, this);
10099                    });
10100
10101                    ;
10102                    ;
10103
10104                    ;
10105
10106                    koObject = {
10107                        LoadingInProccess: ko.observable(false),
10108                        RemovePages: removePages,
10109                        RemoveFiles: removeFiles,
10110                        DownloadFiles: downloadFiles,
10111                        RemoveAll: removeAll
10112                    };
10113                    ;
10114
10115                    koObject.PrintCheckedPages = printCheckedPages;
10116                    favorsContainer = $(settings.favoriteListContainerSelector);
10117
10118                    if (favorsContainer.length) {
10119                        ko.applyBindings(koObject, $(settings.favoriteListContainerSelector)[0]);
10120                    }
10121
10122                case 20:
10123                case "end":
10124                    return context$2$0.stop();
10125            }
10126        }, null, this);
10127    };
10128
10129    Favorites.on("start", function (options) {
10130        if (options && options.favorites) {
10131            settings = $.extend(settings, options.favorites);
10132        }
10133        Favorites.run();
10134    });
10135});
10136///
10137//$.lukoilSaveCookie(keyInStorage, str, this.config);
10138
10139//console.log("result - " + result);
10140
10141//console.log("TFIC");;
10142LukoilApp.module("Targeting", function (Targeting, LukoilApp, Backbone, Marionette, $, _, global) {
10143	"use strict";
10144
10145	var requiredModules = {
10146		util: LukoilApp.module("Util"),
10147		YandexMapServices: LukoilApp.module("YandexMapServices")
10148	};
10149
10150	var settings = {
10151		cookiesConfig: {
10152			expires: 365 * 100,
10153			path: '/'
10154		},
10155		checkboxContainerSel: "#widgets .checkbox",
10156		btnSaveSel: "#luk-targeting-save",
10157		journalName: "LukPressList",
10158		uppName: "LukUpp",
10159		coefficientName: "LukFavourites",
10160		geolocationInfoName: "LukGeolocation",
10161		locationName: "LukLocation",
10162		currentSiteLocationUrl: "/api/userLocation/GetCurrentSiteLocation",
10163		tagMaxValue: 300, 
10164		journalLength: 50,
10165		debug: false,
10166		fileLinksSelector: "body .luk-targeting-file-link",
10167		tagsDataAttrName: "personalization",
10168		tagsSplitter: ";"
10169	};
10170
10171	var data = {};
10172
10173	var journals = {};
10174
10175	var cookieStorage = {};
10176
10177	// ----------- Logger -----------
10178	var Logger = function (useConsole) { this.useConsole = useConsole || true; };
10179	Logger.prototype.log = function (data) { if (this.useConsole && console && console.log) { console.log(data); } }
10180	var logger = new Logger(settings.debug);
10181
10182	// ----------- Journal for counting actions -----------
10183	var JournalRecord = function(tags, count) {
10184		this.tags = tags;
10185		this.count = count || 0;
10186		this.created = new Date();
10187		this.url = window.location.pathname;
10188	}
10189
10190	JournalRecord.prototype.increaseTimeCount = function (amount, maxTagPoint) {
10191		this.count += amount;
10192		if (this.count > maxTagPoint) {
10193			this.count = maxTagPoint;
10194		}
10195	}
10196
10197	var ActionsJournal = function (maxTagPoint, creationTime, coefficient) {
10198		this.records = [];
10199		this.tagMaxValue = maxTagPoint || 300;
10200		this.creationTime = creationTime || new Date();
10201		this.coefficient = coefficient || 1.0;
10202	}
10203	ActionsJournal.prototype.addRecordsFromTags = function (tags) {
10204		var grouppedByCount = _.groupBy(tags, function(t) {
10205			return t.count;
10206		});
10207
10208		var self = this;
10209		_.each(grouppedByCount, function (group) {
10210			var ids = _.map(group, function (t) {
10211				return t.id;
10212			});
10213			var count = group[0].count;
10214			var rec = new JournalRecord(ids, count);
10215			self.records.push(rec);
10216		});
10217	};
10218	ActionsJournal.prototype.clearAll = function () {
10219		this.records = [];
10220	};
10221	ActionsJournal.prototype.addRecord = function (tags, count) {
10222		if (tags && Array.isArray(tags)) {
10223			var rec = new JournalRecord(tags, count);
10224			this.records.push(rec);
10225			return rec;
10226		}
10227		return null;
10228	};
10229	ActionsJournal.prototype.increaseTimeCount = function (endTime) {
10230		var mtp = this.tagMaxValue;
10231		var amount = this.getSecondsInActiveStatus(endTime) * this.coefficient;
10232		_.each(this.records, function (rec) {
10233			rec.increaseTimeCount(amount, mtp);
10234		});
10235	};
10236	ActionsJournal.prototype.getSecondsInActiveStatus = function (endDateTime) {
10237		var currentTime = endDateTime || new Date();
10238		var diff = currentTime.getTime() - this.creationTime.getTime();
10239		this.creationTime = currentTime;
10240		return Math.ceil(diff / 1000);
10241	}
10242
10243	// ----------- Journal for store counted tags locally -----------
10244	var LocalJournal = function (locStorage, maxRecordsNumber) {
10245		this.locStorage = locStorage;
10246		this.maxRecordsNumber = maxRecordsNumber || settings.journalLength;
10247		this.records = locStorage.getAsArray() || [];
10248	};
10249	LocalJournal.prototype.getRecords = function () {
10250		return this.locStorage.getAsArray();
10251	}
10252	LocalJournal.prototype.reloadFromStorage = function () {
10253		this.records = this.locStorage.getAsArray() || [];
10254	}
10255	LocalJournal.prototype.clearAll = function () {
10256		this.records = [];
10257		this.saveInStorage();
10258	}
10259	LocalJournal.prototype.saveInStorage = function () {
10260		var recordsToSave = _.map(this.records, function (rec) {
10261			var newLocalRecord = { tags: rec.tags, count: rec.count };
10262			if (rec.created) {
10263				newLocalRecord.created = rec.created;
10264			}
10265			if (rec.url) {
10266				newLocalRecord.url = rec.url;
10267			}
10268			return newLocalRecord;
10269		});
10270		return this.locStorage.save(recordsToSave);
10271	}
10272	LocalJournal.prototype.addRecords = function (newRecords) {
10273		var thisRec = this.records;
10274		_.each(newRecords, function (rec) {
10275			thisRec.push(rec);
10276		});
10277		if (this.records.length > this.maxRecordsNumber) {
10278			this.records.splice(0, this.records.length - this.maxRecordsNumber);
10279		}
10280	}
10281	LocalJournal.prototype.extractTags = function () {
10282		var tagsWithCountNotMerged = [];
10283		_.each(this.records, function (rec) {
10284			_.each(rec.tags, function (tag) {
10285				tagsWithCountNotMerged.push({ id: tag, count: rec.count });
10286			});
10287		});
10288		var mergedTags = [];
10289		_.each(tagsWithCountNotMerged, function (ct) {
10290			var existed = _.filter(mergedTags, function (rt) {
10291				return ct.id === rt.id;
10292			});
10293			if (existed.length) {
10294				existed[0].count += ct.count;
10295			} else {
10296				mergedTags.push({ id: ct.id, count: ct.count });
10297			}
10298		});
10299		return mergedTags;
10300	}
10301
10302	// ----------- Journal tag -----------
10303	var JournalTag = function (tagId, tagCount) {
10304		this.id = tagId;
10305		this.count = tagCount || 0;
10306	}
10307
10308	JournalTag.prototype.getSecondsInActiveStatus = function (fromDateTime) {
10309		var currentTime = fromDateTime || new Date();
10310		var diff = currentTime.getTime() - this.dateTime.getTime();
10311		return Math.ceil(diff / 1000);
10312	}
10313
10314	JournalTag.prototype.resetStartDateTime = function () {
10315		this.startDateTime = new Date();
10316	}
10317
10318	JournalTag.prototype.increaseCount = function (maxTagPoint) {
10319		if (this.needToCalculateOnPage) {
10320			this.count += this.getSecondsInActiveStatus();
10321			if (this.count > maxTagPoint) {
10322				this.count = maxTagPoint;
10323			}
10324		}
10325	}
10326
10327	// ----------- CookieStorage -----------
10328	var CookieStorage = function (config) {
10329		this.config = config || {};
10330	}
10331	CookieStorage.prototype.save = function (keyInStorage, model) {
10332		$.lukoilSaveCookie(keyInStorage, JSON.stringify(model), this.config);
10333	}
10334	CookieStorage.prototype.getValue = function (keyInStorage) {
10335		return $.lukoilGetCookie(keyInStorage);
10336	}
10337	CookieStorage.prototype.getArray = function (keyInStorage, mapFunc) {
10338		var modelString = $.lukoilGetCookie(keyInStorage);
10339		var models = requiredModules.util.tryParseStringToArray(modelString);
10340		var journalTags = _.map(models, function (model) {
10341			//return new JournalTag(model.t, model.c);
10342			if (mapFunc) {
10343				return mapFunc(model);
10344			} else {
10345				return model;
10346			}
10347		});
10348		return journalTags;
10349	}
10350
10351	// ----------- LocalStorage -----------
10352	var LocalStorage = function (keyInStorage) {
10353		this.key = keyInStorage;
10354	}
10355	LocalStorage.prototype.supported = function (model) {
10356		return typeof (Storage) !== "undefined";
10357	}
10358	LocalStorage.prototype.save = function (model) {
10359		if (this.supported()) {
10360			try {
10361				localStorage.setItem(this.key, JSON.stringify(model));
10362			} catch (e) {
10363				logger.log("targeting.LocalStorage.save: " + e);
10364			} 
10365		}
10366	}
10367	LocalStorage.prototype.getAsArray = function () {
10368		if (this.supported()) {
10369			try {
10370				// possible error when accessing local storage in IE with low level access in Windows 8
10371				// solution: http://stackoverflow.com/questions/13102116/access-denied-for-localstorage-in-ie10
10372				var modelString = localStorage.getItem(this.key);
10373				var model = requiredModules.util.tryParseStringToArray(modelString);
10374				return model;
10375			} catch (e) {
10376				logger.log("targeting.LocalStorage.getAsArray: " + e);
10377			} 
10378		}
10379		return [];
10380	}
10381
10382	// ----------- Util START -----------
10383	var getDiffInSeconds = function (toDateTime) {
10384		var currentTime = new Date();
10385		var diff = currentTime.getTime() - toDateTime.getTime();
10386		return Math.ceil(diff / 1000);
10387	}
10388
10389	var copyJournalToCookie = function (tags, cookieStorage, journalKey) {
10390		var journalModel = _.map(tags, function (vm) {
10391			return { t: vm.id, c: vm.count };
10392		});
10393		cookieStorage.save(journalKey, journalModel);
10394	};
10395
10396	var fillUpp = function(upp) {
10397		if (settings.debug) {
10398			_.each(upp, function (tagValue) {
10399				var container = $('<div></div>');
10400				$(settings.checkboxContainerSel).after(container);
10401				container.html(tagValue.name + ": " + "<label>" + tagValue.count + "</label>");
10402			});
10403		}
10404	}
10405	
10406	var mapServerTagValuesToJournalTags = function (tags) {
10407		return _.map(tags, function(t) {
10408			return new JournalTag(t.t, t.c);
10409		});
10410	};
10411
10412	var tryParseObject = function(value) {
10413		if (!value) {
10414			return null;
10415		}
10416		try {
10417			return JSON.parse(value);
10418		} catch (e) {
10419			return null;
10420		}
10421	};
10422
10423	// ----------- Util END -----------
10424
10425	Targeting.run = function () {
10426		data.startingTime = new Date();
10427		cookieStorage = new CookieStorage(settings.cookiesConfig);
10428		var coefficientValue = cookieStorage.getValue(settings.coefficientName);
10429		var coefficient10 = parseFloat(coefficientValue) || 10.0;
10430		var coefficient = coefficient10 / 10;
10431		var locStorage = new LocalStorage(settings.journalName);
10432		journals.local = new LocalJournal(locStorage);
10433		journals.actions = new ActionsJournal(settings.tagMaxValue, data.startingTime, coefficient);
10434		var tagsToCount = cookieStorage.getArray(settings.journalName);
10435		var mappedTags = mapServerTagValuesToJournalTags(tagsToCount);
10436		journals.actions.addRecordsFromTags(mappedTags);
10437
10438		// refresh journal in cookie for ajax calls
10439		var currentTags = journals.local.extractTags();
10440		copyJournalToCookie(currentTags, cookieStorage, settings.journalName);
10441		document.cookie = "LukPersonalizedJournal=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
10442		document.cookie = "LukPersonalizedCoefficient=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
10443		localStorage.removeItem('LukPersonalizedJournal');
10444		localStorage.removeItem('LukPersonalizedCoefficient');
10445
10446		var upp = cookieStorage.getArray(settings.uppName);
10447		fillUpp(upp);
10448
10449		var geolocationInfo = cookieStorage.getValue(settings.geolocationInfoName);
10450		if (geolocationInfo == null || geolocationInfo == '') {
10451			var locationInfo = tryParseObject(cookieStorage.getValue(settings.locationName));
10452			var saveGeolocationInfo = function(info) {
10453				geolocationInfo = info;
10454				cookieStorage.save(settings.geolocationInfoName, geolocationInfo);
10455			};
10456			var getLocationFromYandex = function() {
10457				requiredModules.YandexMapServices.ensureMapApiIsReady(GlobalSettings.CurrentLanguage).then(function() {
10458					requiredModules.YandexMapServices.getCurrentLocation().then(function(location) {
10459						saveGeolocationInfo(location.geolocationInfo);
10460					});
10461				});
10462			};
10463
10464			if (locationInfo) {
10465				saveGeolocationInfo(locationInfo);
10466			} else {
10467				$.ajax(settings.currentSiteLocationUrl, {
10468					async: true,
10469					cache: false,
10470					data: {
10471						currentUrl: window.location.href
10472					},
10473					dataType: "json",
10474					method: "GET"
10475				}).done(function(answer) {
10476					if (answer && answer.useYandex === false && answer.geolocationInfo) {
10477						saveGeolocationInfo(answer.geolocationInfo);
10478					} else {
10479						getLocationFromYandex();
10480					}
10481				}).fail(getLocationFromYandex);
10482			}
10483		}
10484
10485		// ----------- Aside widget logic -----------
10486		var widgetsIsSaved = $.lukoilGetCookie('WIDGETS_SAVED');
10487		if (!widgetsIsSaved) {
10488			$('#widgets').removeClass('hide');
10489		} else {
10490			$('#widgets').addClass('hide');
10491		}
10492		$(settings.btnSaveSel).on("click", function () {
10493			var tagInputs = $("div.checkbox input:checked");
10494			var tagIds = [];
10495			_.each(tagInputs, function (inp) {
10496				var tagId = $(inp).val();
10497				tagIds.push(tagId);
10498			});
10499			var rec = Targeting.addRecord(tagIds, settings.tagMaxValue);
10500			$.lukoilSaveCookie('WIDGETS_SAVED', 'true', settings.cookiesConfig);
10501			window.location.reload();
10502			return false;
10503		});
10504
10505		window.onbeforeunload = function () {
10506			var endDate = new Date();
10507			journals.actions.increaseTimeCount(endDate);
10508			journals.local.reloadFromStorage();
10509			journals.local.addRecords(journals.actions.records);
10510			journals.local.saveInStorage();
10511
10512			var tags = journals.local.extractTags();
10513			copyJournalToCookie(tags, cookieStorage, settings.journalName);
10514		};
10515
10516		Targeting.ReattachEvents();
10517	}
10518
10519	Targeting.addRecord = function (tagIds, tagCount) {
10520		var rec = journals.actions.addRecord(tagIds, tagCount);
10521		return rec;
10522	};
10523
10524	// todo remove from release
10525	// ----------- DEBUG function BEGIN -----------
10526	Targeting.getActionsJournal = function() {
10527		return journals.actions.records;
10528	}
10529	Targeting.getLocalRecords = function () {
10530		return journals.local.records;
10531	}
10532	Targeting.updateLocalRecord = function (ind, count, tagIds) {
10533		if (ind >= 0 && ind < journals.local.records.length) {
10534			var rec = journals.local.records[ind];
10535			rec.count = count;
10536			if (tagIds && Array.isArray(tagIds)) {
10537				rec.tags = tagIds;
10538			}
10539			return rec;
10540		}
10541		return "wrong index " + ind;
10542	}
10543	// ----------- DEBUG function END -----------
10544
10545	Targeting.clearAll = function () {
10546		journals.local.clearAll();
10547		journals.actions.clearAll();
10548		cookieStorage.save(settings.journalName, []);
10549	}
10550
10551	Targeting.ReattachEvents = function () {
10552		$(settings.fileLinksSelector).off("click");
10553		$(settings.fileLinksSelector).on("click", function () {
10554			var $this = $(this);
10555			var fileTagsData = $this.data(settings.tagsDataAttrName);
10556			if (fileTagsData) {
10557				var tagIds = fileTagsData.split(settings.tagsSplitter);
10558				Targeting.addRecord(tagIds, settings.tagMaxValue);
10559			}
10560		});
10561	}
10562
10563	Targeting.on("start", function (options) {
10564		if (options && options.targeting) {
10565			settings = $.extend(settings, options.targeting);
10566		}
10567		Targeting.run();
10568	});
10569});
10570;
10571LukoilApp.module("Widgets", function (Widgets, LukoilApp, Backbone, Marionette, $, _) {
10572	var settings = {
10573		getMaterialsUrl: "/api/materials/GetMaterials",
10574		getTeasersUrl: "/api/materials/GetTeasers"
10575	};
10576
10577	var requiredModules = {
10578		targeting: LukoilApp.module("Targeting"),
10579		sharing: LukoilApp.module("Sharing")
10580	};
10581
10582	Widgets.on("start", function (options) {
10583		Widgets.run();
10584	});
10585
10586	function showFancyboxError() {
10587		$.fancyboxInit({
10588			padding: 10,
10589			content: "<div>" + GlobalSettings.ErrorMessages.AjaxErrorMessage + "</div>"
10590		});
10591	}
10592
10593	function InfoHighlightedVm(widgetId, maxCount, language, site) {
10594		var self = this;
10595		self.Materials = ko.observableArray([]);
10596		self.MaxCount = maxCount;
10597
10598		self.LoadingInProcess = ko.observable(false);
10599		self.ShowPaginationButtons = ko.observable(true);
10600		self.CanLoadMore = ko.computed(function () {
10601			return !self.LoadingInProcess() && self.MaxCount > self.Materials().length + 2;
10602		});
10603		self.LoadMore = function () {
10604			if (!self.LoadingInProcess()) {
10605				self.LoadingInProcess(true);
10606				$.ajax(settings.getMaterialsUrl, {
10607					async: true,
10608					cache: false,
10609					data: {
10610						widgetId: widgetId,
10611						itemsNumberToSkip: self.Materials().length + 2,
10612						itemsNumberToLoad: 2,
10613						fillRowByEmpty: true,
10614						language: language,
10615						site: site
10616					},
10617					dataType: "json",
10618					method: "GET",
10619					traditional: true
10620				}).then(function(result) {
10621					if (result.materials.length) {
10622						_.each(result.materials, function(material) {
10623							if (material == null) {
10624								material = { IsNull: true };
10625							} else {
10626								material.IsNull = false;
10627							}
10628							self.Materials.push(material);
10629						});
10630
10631						setTimeout(function () {
10632							$('.infoblock-grey .text[dotdotdot="true"]').each(function() {
10633								$(this).dotdotdot();
10634								$(this).removeAttr("dotdotdot");
10635							});
10636						}, 100);
10637					}
10638				}).fail(function () {
10639					showFancyboxError();
10640				}).always(function () {
10641					self.LoadingInProcess(false);
10642				});
10643			}
10644		};
10645	}
10646
10647	function AdjustableForClientVm(widgetId, totalItemsCount, itemsCount) {
10648		var self = this;
10649		self.Materials = ko.observableArray([]);
10650		self.TotalItemsCount = totalItemsCount;
10651		self.ItemsCount = itemsCount;
10652		self.LoadingInProcess = ko.observable(false);
10653		self.ShowPaginationButtons = ko.observable(true);
10654		self.CanLoadMore = ko.computed(function () {
10655			return !self.LoadingInProcess() && self.TotalItemsCount > self.ItemsCount;
10656		});
10657		self.LoadMore = function () {
10658			if (!self.LoadingInProcess()) {
10659				self.LoadingInProcess(true);
10660				$.ajax(settings.getTeasersUrl, {
10661					async: true,
10662					cache: false,
10663					data: {
10664						widgetId: widgetId,
10665						itemsNumberToSkip: self.ItemsCount
10666					},
10667					dataType: "json",
10668					method: "GET",
10669					traditional: true,
10670					success: function(result) {
10671						if (result.materials.length) {
10672							_.each(result.materials, function(item) {
10673								item.materialBlockCss = item.Teaser && item.Teaser.Size === 1 ? "col-sm-4 col-md-4" :
10674									item.Teaser && item.Teaser.Size === 2 ? "col-sm-8 col-md-8"
10675									: "col-sm-12 col-md-12";
10676								item.infoBlockCss = "infoblock-grey adjustable-client";
10677								item.infoBlockCss += item.Teaser.Size === 3 ? " adjustable-client_full text" : (item.PreviewImageUrl ? "" : " text text_links");
10678								item.infoBlockCss += item.Teaser && item.Teaser.ExternalLinksParsed && item.Teaser.ExternalLinksParsed.length ? " text_more-links" : "";
10679
10680								item.file = item.MediaFiles && item.MediaFiles.length ? item.MediaFiles[0].Entity : null;
10681								self.Materials.push(item);
10682							});
10683							self.ItemsCount += result.materials.length;
10684							$('.adjustable-client').each(function () {
10685								var h = $(this).hasClass('adjustable-client_full') ? 50 : $(this).find('.text').css('max-height');
10686								$(this).find('.text').dotdotdot({ height: h });
10687							});
10688							requiredModules.sharing.run();
10689						}
10690					}
10691				}).fail(function () {
10692					showFancyboxError();
10693				}).always(function () {
10694					self.LoadingInProcess(false);
10695				});
10696			}
10697		};
10698	}
10699
10700	Widgets.run = function () {
10701		// footer redirection from group and worldwide selects
10702		$("#footer select.luk-redirect").on("change", function (e) {
10703			var $this = $(this);
10704			var url = $this.val();
10705			var internal = $this.find("option:selected").data("internal") === "True";
10706
10707			if (url && url !== "//" && url !== "0") {
10708				if (internal) {
10709					window.location.href = url;
10710				} else {
10711					window.open(url, '_blank');
10712				}
10713				
10714			};
10715		});
10716
10717		// scroll when we have hash with block id to show widget under menu and other top fixed positioned elements
10718		var getFixedPositionedElementsHeight = function () {
10719
10720			// for main site pages
10721			if ($("#home").length)
10722				return $("#header").height();
10723
10724			// for subsidiary site pages
10725			var subsidiaryTitle = $(".subsidiary__heading");
10726			if (subsidiaryTitle.length)
10727				return $("#header").height() + subsidiaryTitle.height();
10728			return $("#header").height();
10729		};
10730
10731		var scrollToWidget = function(target) {
10732			var elementTopPosition = target.offset().top;
10733			var fixedPositionedElementsHeight = getFixedPositionedElementsHeight();
10734			var marginTop = parseInt(target.next().css('margin-top'));
10735			var elementTopPositionWithFixedHeight = elementTopPosition - fixedPositionedElementsHeight - marginTop;
10736
10737			if (elementTopPositionWithFixedHeight != $(window).scrollTop()) {
10738				window.scrollTo(0, elementTopPositionWithFixedHeight - 20);
10739			}
10740		};
10741
10742		var windowScrollTop = $(window).scrollTop();
10743		var widgetIdQueryStringParameterName = "wid=";
10744		var startWidIndex = location.search.indexOf(widgetIdQueryStringParameterName);
10745		if (!windowScrollTop && startWidIndex > -1) {
10746			var endWidIndex = location.search.indexOf("&", startWidIndex + 1);
10747			if (endWidIndex < 0) {
10748				endWidIndex = location.search.length;
10749			}
10750			var widStr = location.search.substr(startWidIndex + widgetIdQueryStringParameterName.length, endWidIndex - startWidIndex);
10751			var target = $("#" + widStr);
10752			if (target.length && target.offset()) {
10753				target.next().find("a.collapsed[data-toggle]").trigger("click");
10754				scrollToWidget(target);
10755
10756				var attempt = 0;
10757				var scrollInterval = setTimeout(function () {
10758					if (attempt > 4) {
10759						clearInterval(scrollInterval);
10760					}
10761					scrollToWidget(target);
10762					attempt++;
10763				}, 200);
10764			}
10765		}
10766
10767		// TopManagerPerson functionality START
10768		var getHostUrl = function (url) {
10769			var urlParts = url.split('/');
10770			if (urlParts.length > 1) {
10771				return urlParts[2];
10772			}
10773		};
10774		var gobackBtn = $(".luk-go-back");
10775		if (gobackBtn.length) {
10776			var currentHostUrl = window.location.host;
10777			var referrerHostUrl = getHostUrl(document.referrer);
10778			var isPreviousLukoilPageUrl = currentHostUrl && referrerHostUrl && currentHostUrl === referrerHostUrl;
10779			if (history.length && isPreviousLukoilPageUrl) {
10780				gobackBtn.on("click", function () {
10781					history.back();
10782					return false;
10783				});
10784			} else {
10785				gobackBtn.hide();
10786			}
10787		}
10788		// TopManagerPerson functionality END
10789
10790		// DownloadQuickly functionality START
10791		var downloadQuicklyLoadMoreMaterialsBtn = $(".luk-downloadquickly-more");
10792		if (downloadQuicklyLoadMoreMaterialsBtn.length) {
10793			// todo for several widgets on a page
10794			var ItemsPerLoad = 3;
10795			downloadQuicklyLoadMoreMaterialsBtn.on("click", function () {
10796				var $this = $(this);
10797				var totalLoadedStr = $this.data("total-loaded");
10798				var totalLoaded = parseInt(totalLoadedStr) || ItemsPerLoad;
10799				var parameters = {
10800					widgetId: $this.data("widget-id"),
10801					itemsNumberToSkip: totalLoaded,
10802					itemsNumberToLoad: ItemsPerLoad,
10803					fillRowByEmpty: true
10804				};
10805				var preloader = $this.closest("div.panel-content").find(".preloader");
10806				$(preloader).show();
10807				$this.hide();
10808				$.ajax(settings.getMaterialsUrl, {
10809					async: true,
10810					cache: false,
10811					data: parameters,
10812					dataType: "json",
10813					method: "GET",
10814					traditional: true
10815				}).then(function (result) {
10816					if (result.materials && result.materials.length) {
10817						var reattachEventsIsNeeded = false;
10818						_.each(result.materials, function (m) {
10819							if (m != null) {
10820								_.each(m.MediaFiles, function (orederedEntity) {
10821									var file = orederedEntity.Entity;
10822									if (file.PersonalizedTags && file.PersonalizedTags.length) {
10823										file.tags = _.map(file.PersonalizedTags, function (pt) {
10824											return pt.TagGuid;
10825										});
10826										file.tagsData = file.tags.join(";");
10827										reattachEventsIsNeeded = true;
10828									} else file.tagsData = "";
10829								});
10830							}
10831						});
10832						totalLoaded += result.materials.length;
10833						$this.data("total-loaded", totalLoaded);
10834						var templateHtml = $("#downloadQuicklyFileTmpl").html();
10835						var compile = _.template(templateHtml);
10836						var emptyTemplateHtml = $("#downloadQuicklyEmptyTmpl").html();
10837						var compileEmpty = _.template(emptyTemplateHtml);
10838						var htmlEmpty = compileEmpty();
10839						_.each(result.materials, function (m) {
10840							if (m != null) {
10841								if (m.MediaFiles && m.MediaFiles.length) {
10842									var file = m.MediaFiles[0].Entity;
10843									file.MaterialTitle = m.MaterialTitle;
10844									var html = compile(file);
10845									$(html).insertBefore($this.closest("div.panel-content"));
10846								}
10847							} else {
10848								$(htmlEmpty).insertBefore($this.closest("div.panel-content"));
10849							}
10850						});
10851						if (reattachEventsIsNeeded) requiredModules.targeting.ReattachEvents();
10852					}
10853
10854					$this.show();
10855					if (!result.canLoadMore || !result.materials || !result.materials.length || result.materials.length < ItemsPerLoad) {
10856						$this.closest("div.panel-content").hide();
10857					}
10858					$(preloader).hide();
10859				}).fail(function () {
10860					showFancyboxError();
10861					$this.show();
10862					$(preloader).hide();
10863				});
10864
10865				return false;
10866			});
10867		}
10868		// DownloadQuickly functionality END
10869
10870		// InfoHighlighted functionality START
10871		_.each($(".interesting"), function(widget) {
10872			var $widget = $(widget);
10873			var vm = new InfoHighlightedVm($widget.data("widget-id"), $widget.data("total-count"), $widget.data("language"), $widget.data("site"));
10874			ko.applyBindings(vm, widget);
10875		});
10876		// InfoHighlighted functionality END
10877
10878		// AdjustableForClient functionality START
10879		_.each($(".adjustable-client-container"), function (widget) {
10880			var $widget = $(widget);
10881			var total = $widget.data("total-count");
10882			var loaded = $widget.data("loaded-count");
10883			var vm = new AdjustableForClientVm($widget.data("widget-id"), total, loaded);
10884			ko.applyBindings(vm, widget);
10885		});
10886		// AdjustableForClient functionality END
10887
10888		// Referrals functionality START
10889		var showLinkForNonEmptyValue = function (linkData, target, isExternalLink) {
10890			if (linkData) {
10891				target.removeAttr("target");
10892				if (isExternalLink) {
10893					target.attr("target", "_blank");
10894					target.removeClass("icon-s-chevron-link").addClass("icon-s-share");
10895				} else {
10896					target.removeClass("icon-s-share").addClass("icon-s-chevron-link");
10897				}
10898				target.attr("href", linkData);
10899				target.show();
10900			} else {
10901				target.hide();
10902			}
10903		};
10904		var showLinkForImage = function (linkInt, linkExt, block) {
10905			var $img = $(block).closest("div.panel-body").find(".image .referralLink");
10906			$img.removeAttr("target");
10907			if (linkInt != null && linkInt != '') {
10908				$img.attr("href", linkInt);
10909			} else if (linkExt != null && linkExt != '') {
10910				$img.attr("href", linkExt);
10911				$img.attr("target", "_blank");
10912			} else {
10913				$img.attr("href", "javascript:void(0);");
10914			}
10915		}
10916		$(".luk-referrals-container .dropdown li a").on("click", function (e) {
10917			var $this = $(this);
10918			var intLinkNewHrefValue = $this.data("link-int");
10919			var intLinkNewHrefAsExtValue = $this.data("link-int-ext");
10920			var extLinkNewHrefValue = $this.data("link-ext");
10921			$this.closest("div").children("a").first().children("span").text($this.text());
10922			showLinkForNonEmptyValue(intLinkNewHrefValue, $this.closest("div.buttons").children("a.luk-referrals-link-int"), intLinkNewHrefAsExtValue);
10923			showLinkForNonEmptyValue(extLinkNewHrefValue, $this.closest("div.buttons").children("a.luk-referrals-link-ext"), true);
10924			showLinkForImage(intLinkNewHrefValue, extLinkNewHrefValue, $this);
10925		});
10926		$(".luk-referrals-container").each(function () {
10927			var firstElementInContainer = $(this).find(".dropdown li a:first");
10928			if (firstElementInContainer.text() == firstElementInContainer.closest("div").children("a").first().children("span").text()) {
10929				$(this).find(".dropdown li a:first").trigger("click");
10930			}
10931		});
10932		$(".luk-referrals-container .buttons").children("a.luk-referrals-link").filter("[href]").show();
10933		// Referrals functionality END
10934
10935	};
10936
10937	var getFilterCategories = function (selectedAnswers) {
10938		var cat = _.map(selectedAnswers, function (a) {
10939			return a.Category;
10940		});
10941
10942		var gr = _.groupBy(cat, 'Id');
10943		var filters = _.map(gr, function(g,key) {
10944			return {
10945				count: g.length,
10946				id: key,
10947				title: g.length > 0 && g[0] != null ? g[0].Title : '',
10948				active: ko.observable(false)
10949			};
10950		});
10951
10952		filters = _.sortBy(filters, function(f) {
10953			return f.title;
10954		});
10955
10956		return filters.length > 1 ? filters : [];
10957	};
10958
10959	function FaqVm(selectedAnswers, categories, selector) {
10960		var self = this;
10961		self.selector = selector;
10962		self.allCategories = categories;
10963		self.allAnswers = selectedAnswers;
10964		self.categories = ko.observableArray([]);
10965		self.choosenCategory = ko.observable();
10966		self.selectedAnswers = ko.observableArray(selectedAnswers);
10967		var highLevelCategories = _.filter(categories, function (c) {
10968			return !c.IsSubCategory;
10969		});
10970		self.categories(highLevelCategories);
10971
10972		var filterCategories = getFilterCategories(selectedAnswers);
10973		self.filterCategories = ko.observableArray(filterCategories);
10974
10975		var loadCategory = function (categoryId) {
10976			return $.ajax("/api/faq/GetCategory", {
10977				async: true,
10978				cache: false,
10979				data: {
10980					categoryId: categoryId
10981				},
10982				dataType: "json",
10983				method: "GET",
10984				traditional: true
10985			});
10986		};
10987		var setAnswers = function (vm, answers) {
10988			vm.selectedAnswers(answers);
10989			//self.allAnswers = self.allAnswers.concat(answers);
10990			//vm.allAnswers = answers;
10991			vm.filterCategories(getFilterCategories(answers));
10992		};
10993
10994		var changeCategory = function (categoryId) {
10995			if (!categoryId) {
10996				self.selectedAnswers(self.allAnswers);
10997				self.filterCategories(getFilterCategories(self.allAnswers));
10998				return;
10999			}
11000
11001			var category = _.filter(self.allCategories, function (c) {
11002				return c.Id === categoryId;
11003			})[0];
11004
11005			if (!category.items || !category.items.length) {
11006				loadCategory(category.Id).done(function (result) {
11007					if (result.answers) {
11008						var answers = JSON.parse(result.answers);
11009						if (answers) {
11010							_.each(answers, function (a) {
11011								a.Category = _.filter(self.allCategories, function (c) {
11012									return c.Id === a.CategoryId;
11013								})[0];
11014							});
11015							setAnswers(self, answers);
11016							category.items = answers;
11017						}
11018					}
11019				}).fail(function (jqXHR, textStatus, errorThrown) {
11020					if (window.console && window.console.log) { console.log(errorThrown); }
11021				});
11022			} else {
11023				setAnswers(self, category.items);
11024			}
11025		};
11026
11027		var mappingLinks = function (isExternal, items) {
11028			return _.map(_.filter(items, function (l) { return l.url !== undefined && l.url !== null; }),
11029				function (l) { return { isExternal: isExternal, url: l.url, title: l.title } });
11030		};
11031
11032		self.choosenCategory.subscribe(function (categoryId) {
11033			changeCategory(categoryId);
11034		});
11035
11036		self.filterAnswers = function (category) {
11037			if (_.every(self.filterCategories(), function (fc) {
11038				return !fc.active();
11039			})) {
11040				var t = _.filter(self.allAnswers, function (a) {
11041					return a.CategoryId === category.id;
11042				});
11043				self.selectedAnswers(t);
11044				category.active(!category.active());
11045				return;
11046			}
11047
11048			category.active(!category.active());
11049			var f;
11050			if (category.active()) {
11051				f = _.filter(self.allAnswers, function (a) {
11052					return a.CategoryId === category.id || _.any(self.selectedAnswers(), function (sa) {
11053						return sa.CategoryId === a.CategoryId;
11054					});
11055				});
11056			} else {
11057				f = _.filter(self.selectedAnswers(), function (a) {
11058					return a.CategoryId !== category.id;
11059				});
11060			}
11061
11062			if (f.length) {
11063				self.selectedAnswers(f);
11064			} else {
11065				var $container = $(self.selector);
11066				var $select = $container.find(".select-category-faq select");
11067				if ($select.val() != null && $select.val() != '') {
11068					var curentObj = _.filter(self.allCategories, function(c) {
11069						return c.Id === category.id;
11070					})[0];
11071					if (curentObj != null && curentObj.ParentCategory != null) {
11072						changeCategory(curentObj.ParentCategory.Id);
11073						return;
11074					}
11075				}
11076				self.selectedAnswers(self.allAnswers);
11077			}
11078		}
11079
11080		self.getAllLinks = function (answer) {
11081			var internal = mappingLinks(false, answer.InternalLinks);
11082			var external = mappingLinks(true, answer.ExternalLinks);
11083			return internal.concat(external);
11084		};
11085
11086		self.getEvenOrOddClass = function (index) {
11087			return index % 2 === 0 ? "odd" : "even";
11088		};
11089
11090		self.getAllLinks = function (answer) {
11091			var internal = mappingLinks(false, answer.InternalLinks);
11092			var external = mappingLinks(true, answer.ExternalLinks);
11093			return internal.concat(external);
11094		};
11095
11096		ko.applyBindings(self, $(selector)[0]);
11097	}
11098
11099	Widgets.initFaq = function (options) {
11100		var selectedAnswers = options.selectedAnswers, categories = options.categories, selector = options.selector;
11101		var container = $(selector);
11102		if (container.length === 1) {
11103			var vm = new FaqVm(selectedAnswers, categories, selector);
11104		} else if (container.length > 1) {
11105			if (console && console.log) {
11106				console.log("too mush FAQ containers");
11107			}
11108		}else {
11109			if (console && console.log) {
11110				console.log("no FAQ container");
11111			}
11112		}
11113	}
11114});
11115
11116ko.PaginationViewModel = function (pageSize, allItemCount, widgetSelector, loadFunction) {
11117	var self = this;
11118		self.allCountItem = ko.observable(0);
11119		self.LoadedPages = ko.observableArray([]);
11120		self.CurrentPage = ko.observable(1);
11121		self.PageSize = ko.observable(pageSize);
11122		self.PageCount = ko.computed(function () {
11123			if (self.allCountItem() != 0)
11124				return Math.ceil(self.allCountItem() / self.PageSize());
11125			else
11126				return Math.ceil(allItemCount() / self.PageSize());
11127		});
11128		self.FirstPage = 1;
11129		self.LastPage = ko.pureComputed(function () {
11130			return self.PageCount();
11131		});
11132
11133		self.SecondPage = 2;
11134
11135		self.PenultimatePage = ko.pureComputed(function () {
11136			var penultimate = self.LastPage() - 1;
11137			return penultimate < self.FirstPage ? self.FirstPage : penultimate;
11138		});
11139
11140		self.PaginationSize = ko.observable(Constants.PaginationSize);
11141		self.ListSize = ko.pureComputed(function () {
11142			return self.PaginationSize() + 2;
11143		});
11144
11145		self.FirstShowPage = function () {
11146			var firstShowPage = self.CurrentPage() - Math.floor((self.PaginationSize() - 1) / 2);
11147
11148			if (self.CurrentPage() > self.FirstPage + self.PaginationSize()) {
11149				if (self.CurrentPage() >= self.LastPage() - self.PaginationSize()) {
11150					firstShowPage = self.LastPage() - self.PaginationSize() - 1;
11151					firstShowPage = firstShowPage > self.SecondPage ? firstShowPage : self.SecondPage;
11152				} else {
11153					firstShowPage = firstShowPage < self.SecondPage ? self.SecondPage : firstShowPage;
11154					firstShowPage = firstShowPage - 1 == self.SecondPage ? self.SecondPage : firstShowPage;
11155				}
11156			}
11157			else {
11158				firstShowPage = self.SecondPage;
11159			}
11160
11161			return firstShowPage;
11162		};
11163
11164		self.LastShowPage = function () {
11165			var firstShowPage = Math.max(self.CurrentPage() - Math.floor((self.PaginationSize() - 1) / 2), self.FirstShowPage());
11166			var lastShowPage = firstShowPage + self.PaginationSize() - 1;
11167			lastShowPage = lastShowPage + 1 >= self.PenultimatePage() ? self.PenultimatePage() : lastShowPage;
11168			return lastShowPage;
11169		}
11170		self.ShowPrevPage = ko.computed(function () {
11171			return self.CurrentPage() !== 0 && self.CurrentPage() !== 1;
11172		});
11173		self.ShowNextPage = ko.computed(function () {
11174			return self.CurrentPage() !== 0 && self.CurrentPage() !== self.PageCount();
11175		});
11176
11177		self.ShowPrevPages = ko.computed(function () {
11178			return self.FirstShowPage() > self.SecondPage;
11179		});
11180		self.ShowNextPages = ko.computed(function () {
11181			return self.LastShowPage() < self.PenultimatePage();
11182		});
11183
11184		self.GetPages = ko.pureComputed(function () {
11185			var pages = [];
11186			var firstShowPage = self.FirstShowPage();
11187			var lastShowPage = self.LastShowPage();
11188			var listSizeNow = lastShowPage - firstShowPage + 1;
11189
11190			if (self.ShowPrevPages()) {
11191				listSizeNow++;
11192			}
11193
11194			if (self.ShowNextPages()) {
11195				listSizeNow++;
11196			}
11197
11198			if (listSizeNow < self.ListSize()) {
11199				var difference = self.ListSize() - listSizeNow;
11200				for (; difference > 0; difference--) {
11201					if (firstShowPage > self.SecondPage) {
11202						firstShowPage--;
11203					}
11204					else {
11205						if (lastShowPage < self.PenultimatePage()) {
11206							lastShowPage++;
11207						}
11208					}
11209				}
11210		}
11211
11212			for (var i = firstShowPage; i <= lastShowPage ; i++)
11213				pages.push(i);
11214
11215			return pages;
11216		});
11217		self.PrevPage = function (n) {
11218			var previous = self.CurrentPage() - (n != null ? n : 1);
11219			if (previous < self.FirstPage)
11220				return self.FirstPage;
11221			return previous;
11222		};
11223		self.NextPage = function (n) {
11224			var next = self.CurrentPage() + (n != null ? n : 1);
11225			if (next > self.LastPage())
11226				return self.LastPage();
11227			return next;
11228		};
11229		self.SetCurrentPage = function (page, target) {
11230			if (page < self.FirstPage)
11231				page = self.FirstPage;
11232
11233			if (page > self.LastPage())
11234				page = self.LastPage();
11235
11236			self.CurrentPage(page);
11237
11238			if (target != null) {
11239				var $list = $(target).parents(widgetSelector);
11240				self.LoadedPages.removeAll();
11241				loadFunction(self, $list, (page - 1) * self.PageSize(), true);
11242			}
11243		};
11244		self.GoToPage = function (page, event) {
11245			if (self.CurrentPage() !== page && page >= self.FirstPage && page <= self.LastPage())
11246				self.SetCurrentPage(page, event.target);
11247		}
11248		self.GoToPrevPage = function (m, event) {
11249			if (self.ShowPrevPage()) {
11250				var prev = self.PrevPage();
11251				if (prev != null)
11252					self.SetCurrentPage(prev, event.target);
11253			}
11254		};
11255		self.GoToNextPage = function (m, event) {
11256			if (self.ShowNextPage()) {
11257				var next = self.NextPage();
11258				if (next != null)
11259					self.SetCurrentPage(next, event.target);
11260			}
11261		};
11262		self.GoToPrevPages = function (m, event) {
11263			if (self.ShowPrevPages()) {
11264				var prev = self.PrevPage(self.PaginationSize());
11265					self.SetCurrentPage(prev, event.target);
11266			}
11267		};
11268		self.GoToNextPages = function (m, event) {
11269			if (self.ShowNextPage()) {
11270				var next = self.NextPage(self.PaginationSize());
11271				if (next != null)
11272					self.SetCurrentPage(next, event.target);
11273			}
11274		};
11275
11276		self.CanLoadMore = ko.computed(function () {
11277			return !self.LoadingInProcess() && self.CurrentPage() !== self.PageCount();
11278		});
11279 };
11280LukoilApp.module("Calendar", function (Calendar, LukoilApp, Backbone, Marionette, $, _) {
11281	"use strict";
11282
11283	var settings = {
11284		eventRegistrationWidgetSelector: ".event-registration-widget",
11285		eventListWidgetSelector: ".event-list-widget",
11286		calendarWidgetSelector: ".calendar-widget",
11287		filterForm: ".filter form",
11288		eventListFilterBtnSelector: ".filter-btn",
11289		eventListResultsSelector: ".event-list-results",
11290		getEventsUrl: "/api/presscenter/events",
11291		exportUrl: "/api/presscenter/exportevent",
11292		getTagsUrl: "/api/presscenter/Tags",
11293		importanceSelector: ".importance-select",
11294		audienceSelector: ".audience-select",
11295		countrySelector: ".country-select",
11296		themeSelector: ".theme-select",
11297		regionSelector: ".region-select",
11298		organizationSelector: ".organization-select",
11299		datepickerSelector: ".form-control.calendar",
11300		startDateSelector: "#calendar-from",
11301		endDateSelector: "#calendar-to",
11302		loadMoreButtonSelector: ".load-more-button",
11303		eventFromCalendarWidgetSelector: ".event-from-calendar-widget",
11304		resetButtonSelector: ".button-reset",
11305		queryInputSelector: ".search-control",
11306	};
11307
11308	var buildQueryStringForEventListFilter = function (tags, query, theme, startDate, endDate, defaultGuid) {
11309		var url = new URI(window.location.href);
11310
11311		url.search(function(data) {
11312			data[Constants.queryParamNames.SearchQuery] = query ? query : undefined;
11313			data[Constants.queryParamNames.StartDate] = startDate ? startDate : undefined;
11314			data[Constants.queryParamNames.EndDate] = endDate ? endDate : undefined;
11315			data[Constants.queryParamNames.Tags] = tags ? tags : undefined;
11316			data[Constants.queryParamNames.EventId] = undefined;
11317			return data;
11318		});
11319
11320		return url.search();
11321	};
11322
11323	var requiredModules = {
11324		mediaLibrary: LukoilApp.module("MediaLibrary")
11325	};
11326
11327	var pad = function(num, size) {
11328		var s = num + "";
11329		while (s.length < size) s = "0" + s;
11330		return s;
11331	};
11332
11333	var clearUrlQuery = function () {
11334		if (window.history && window.history.pushState) {
11335			window.history.replaceState(null, "", location.protocol + "//" + location.host + location.pathname);
11336		} else {
11337			window.location.href = location.protocol + "//" + location.host + location.pathname + "#";
11338		}
11339	}
11340
11341	var updateSearchParams = function (vm, $eventList, defaultGuid) {
11342		var themeVal = $eventList.find(settings.themeSelector + " input:checked").map(function () {
11343			return $(this).data("val");
11344		}).get();
11345		var $startDatePicker = $eventList.find(settings.startDateSelector);
11346		var $endDatePicker = $eventList.find(settings.endDateSelector);
11347		var startDateValue = $.datepicker.parseDate($startDatePicker.datepicker("option", "dateFormat"), $startDatePicker.val());
11348		var endDateValue = $.datepicker.parseDate($endDatePicker.datepicker("option", "dateFormat"), $endDatePicker.val());
11349		var queryVal = $eventList.find(settings.queryInputSelector).val().encodeURIComponent();
11350		var tagsVal = $.getTagsValFromMultiselects($eventList, [settings.themeSelector, settings.countrySelector, settings.regionSelector]);
11351
11352		vm.SearchParams = {
11353			tags: tagsVal,
11354			query: queryVal,
11355			theme: themeVal || defaultGuid,
11356			currentUrl: window.location.href,
11357			startDate: startDateValue ? startDateValue.localAsUtcDate().toISOString() : null,
11358			endDate: endDateValue ? endDateValue.localAsUtcDate().toISOString() : null,
11359			take: Constants.PageSize,
11360			widgetGuid: $eventList.data("widgetguid"),
11361			siteGuid: $eventList.data("siteguid"),
11362			languageGuid: $eventList.data("lang")
11363		};
11364	};
11365
11366	var fillMultiselector = function ($data, values) {
11367		$data.parent().removeClass("disabled");
11368		$data.find("li").hide();
11369		values.map(function (item) {
11370			$data.find("input[data-val = " + item + "]").parents('li').show();
11371		});
11372	}
11373
11374	var updateFilterData = function ($mediaLibraries, tagsData) {
11375		var $tagsContainers = $mediaLibraries.find(".tags-data");
11376		var $themeMultiselect = $mediaLibraries.find(settings.themeSelector);
11377		var $countryMultiselect = $mediaLibraries.find(settings.countrySelector);
11378		var $regionMultiselect = $mediaLibraries.find(settings.regionSelector);
11379
11380		if ($tagsContainers && $tagsContainers.length > 0) {
11381			var $container = $($tagsContainers[0]);
11382			var data = JSON.parse($container.text() || $container.html());
11383
11384			var compatibleThemeValues = [];
11385			var compatibleCountryValues = [];
11386			var compatibleRegionValues = [];
11387			if (data != null && data.Items != null) {
11388				data.Items.map(function (item) {
11389					if ((tagsData.theme.length == 0 || tagsData.theme.indexOf(item.theme) != -1) &&
11390						(tagsData.country.length == 0 || tagsData.country.indexOf(item.country) != -1) &&
11391						(tagsData.region.length == 0 || tagsData.region.indexOf(item.region) != -1)) {
11392						if (compatibleThemeValues.indexOf(item.theme) == -1 && item.theme != null)
11393							compatibleThemeValues.push(item.theme);
11394						if (compatibleCountryValues.indexOf(item.country) == -1 && item.country != null)
11395							compatibleCountryValues.push(item.country);
11396						if (compatibleRegionValues.indexOf(item.region) == -1 && item.region != null)
11397							compatibleRegionValues.push(item.region);
11398					}
11399				});
11400			}
11401			if (compatibleThemeValues.length > 0 && tagsData.theme.length == 0) {
11402				fillMultiselector($themeMultiselect, compatibleThemeValues);
11403			} else if (tagsData.theme.length == 0) {
11404				$themeMultiselect.parent().addClass("disabled");
11405			}
11406			if (compatibleCountryValues.length > 0 && tagsData.country.length == 0) {
11407				fillMultiselector($countryMultiselect, compatibleCountryValues);
11408			} else if (tagsData.country.length == 0) {
11409				$countryMultiselect.parent().addClass("disabled");
11410			}
11411			if (compatibleRegionValues.length > 0 && tagsData.region.length == 0) {
11412				fillMultiselector($regionMultiselect, compatibleRegionValues);
11413			} else if (tagsData.region.length == 0) {
11414				$regionMultiselect.parent().addClass("disabled");
11415			}
11416		}
11417	}
11418
11419	var getValues = function ($data, array) {
11420		var $ms = $data.getValFromMultiSelect();
11421		if ($ms != null) {
11422			$ms.map(function (item) {
11423				array.push(item.value);
11424			});
11425		}
11426	}
11427
11428	var onChangeFilter = function ($mediaLibraries) {
11429		var $themeMultiselect = $mediaLibraries.find(settings.themeSelector);
11430		var $countryMultiselect = $mediaLibraries.find(settings.countrySelector);
11431		var $regionMultiselect = $mediaLibraries.find(settings.regionSelector);
11432
11433		var tagsData = {
11434			theme: [],
11435			country: [],
11436			region: []
11437		};
11438
11439		if ($themeMultiselect.getValFromMultiSelect().length > 0)
11440			getValues($themeMultiselect, tagsData.theme);
11441		if ($countryMultiselect.getValFromMultiSelect().length > 0)
11442			getValues($countryMultiselect, tagsData.country);
11443		if ($regionMultiselect.getValFromMultiSelect().length > 0)
11444			getValues($regionMultiselect, tagsData.region);
11445
11446		updateFilterData($mediaLibraries, tagsData);
11447
11448		if (tagsData.country.length > 0) {
11449			$regionMultiselect.parent().addClass("disabled");
11450		}
11451	}
11452
11453	var loadEvents = function (vm, $eventList, skip, isPaging, defaultGuid) {
11454		if (!vm.LoadingInProcess()) {
11455			if (!skip) {
11456				updateSearchParams(vm, $eventList, defaultGuid);
11457			}
11458
11459			vm.LoadingInProcess(true);
11460
11461			var data = vm.SearchParams;
11462			data.skip = skip;
11463
11464			$.ajax({
11465				url: settings.getEventsUrl,
11466				data: data,
11467				success: function (data) {
11468					var queryString = buildQueryStringForEventListFilter(vm.SearchParams.tags, vm.SearchParams.query, vm.SearchParams.theme, vm.SearchParams.startDate, vm.SearchParams.endDate, defaultGuid);
11469					if (window.history && window.history.pushState) {
11470						window.history.replaceState(null, "", location.protocol + "//" + location.host + location.pathname + queryString);
11471					} else {
11472						window.location.href = location.protocol + "//" + location.host + location.pathname + "#" + queryString;
11473					}
11474					if (!skip || isPaging) {
11475						vm.ClearEvents();
11476					}
11477					_.each(data.Items, function (item) {
11478						vm.AddEvent(item);
11479					});
11480					vm.AllEventsCount(data.Count);
11481					$.createDownloadPopover($eventList);
11482
11483					$eventList.find(".panel-time-line-month.last > .collapse").collapse("show");
11484				},
11485				traditional: true,
11486				cache: false
11487			}).fail(function () {
11488				$.fancyboxMessage(GlobalSettings.ErrorMessages.AjaxErrorMessage);
11489			}).always(function () {
11490				vm.LoadingInProcess(false);
11491			});
11492		}
11493	};
11494
11495	Calendar.on("start", function (options) {
11496		Calendar.run();
11497	});
11498
11499	function MonthViewModel(month, id) {
11500		var self = this;
11501		self.Id = id;
11502		self.Month = month;
11503		self.TwoDigitMonth = pad(self.Month, 2);
11504		self.Events = ko.observableArray([]);
11505		self.AddEvent = function (event) {
11506			event.vmId = self.Id + "-" + event.InformationMaterialId;
11507
11508			event.isFutureEvent = moment().isBefore(event.momentStartDate);
11509
11510			event.PreviewFile = null;
11511			if (event.PreviewFiles && event.PreviewFiles.length) {
11512				event.PreviewFile = _.find(event.PreviewFiles, function (file) {
11513					return file.PreviewType === Constants.previewTypes.NewsFeeds;
11514				});
11515			}
11516
11517			event.VideoLink = {
11518				href: null,
11519				type: null
11520			}
11521
11522			for (var i = 0; i < event.MediaFiles.length; i++) {
11523				if (event.MediaFiles[i].LinkedMediaFile) {
11524					event.MediaFiles[i] = event.MediaFiles[i].LinkedMediaFile;
11525				}
11526				if (event.MediaFiles[i].File && event.MediaFiles[i].File.Type === 3 && event.VideoLink.href === null) {
11527					event.VideoLink =
11528					{
11529						href: event.MediaFiles[i].File.FileUrl,
11530						type: event.MediaFiles[i].File.Type
11531					}
11532				}
11533			}
11534
11535			event.fileListData = requiredModules.mediaLibrary.getVmForFileList(event.MediaFiles);
11536
11537			self.Events.push(event);
11538			self.Events.sort(function (left, right) {
11539				if (right.StartDate == left.StartDate) {
11540					return 0;
11541			}
11542				return right.StartDate > left.StartDate ? 1 : -1;
11543			});
11544		};
11545	}
11546
11547	function YearViewModel(year, id) {
11548		var self = this;
11549		self.Id = id;
11550		self.Year = year;
11551		self.Months = ko.observableArray([]);
11552		self.AddEvent = function(event) {
11553			var month = event.momentStartDate.month() + 1;
11554			var monthVm = _.find(self.Months(), function (item) {
11555				return month === item.Month;
11556			});
11557			if (!monthVm) {
11558				monthVm = new MonthViewModel(month, self.Id + "-" + month);
11559				self.Months.push(monthVm);
11560				self.Months.sort(function (left, right) {
11561					return right.Month - left.Month;
11562				});
11563			}
11564			monthVm.AddEvent(event);
11565		};
11566	}
11567
11568	function EventListResultViewModel(id) {
11569		var self = this;
11570		self.Skipped = ko.observable(0);
11571
11572		self.Id = id;
11573		self.SearchParams = undefined;
11574		self.Years = ko.observableArray([]);
11575		self.AllEventsCount = ko.observable(0);
11576		self.EventCount = ko.observable(0);
11577		self.LoadingInProcess = ko.observable(false);
11578		self.ShowPaginationButtons = ko.observable(true);
11579
11580		self.AddEvent = function (event) {
11581			event.momentStartDate = moment(event.StartDate);
11582			var year = event.momentStartDate.year();
11583			var yearVm = _.find(self.Years(), function(item) {
11584				return year === item.Year;
11585			});
11586			if (!yearVm) {
11587				yearVm = new YearViewModel(year, self.Id + "-" + year);
11588				self.Years.push(yearVm);
11589				self.Years.sort(function (left, right) {
11590					return right.Year - left.Year;
11591				});
11592			}
11593			yearVm.AddEvent(event);
11594			self.EventCount(self.EventCount() + 1);
11595		};
11596
11597		self.IsActivePage = function (value) {
11598			//console.log(value, self.LoadedPages(), $.inArray(value, self.LoadedPages()));
11599			return $.inArray(value, self.LoadedPages()) >= 0;
11600		}
11601
11602		ko.PaginationViewModel.call(self, Constants.PageSize, self.AllEventsCount, settings.eventListWidgetSelector, loadEvents);
11603
11604		self.ClearEvents = function() {
11605			self.Years.removeAll();
11606			self.EventCount(0);
11607		};
11608	}
11609
11610	var resetFilter = function ($eventList) {
11611		$eventList.find(settings.queryInputSelector).val("");
11612		$.resetDatePickerValue($eventList.find(settings.startDateSelector));
11613		$.resetDatePickerValue($eventList.find(settings.endDateSelector));
11614		_.each($eventList.find("select"), function (select) {
11615			var $select = $(select);
11616			$select.val($select.find("option:first").val()).trigger("refresh");
11617		});
11618	};
11619
11620	var prepareEventLists = function (eventList, index) {
11621		var $eventList = $(eventList);
11622		var $datePickers = $eventList.find(settings.datepickerSelector);
11623		_.each($datePickers, function(picker) {
11624			var $picker = $(picker);
11625			var initialDate = $picker.data("initialvalue");
11626			if (initialDate) {
11627				$picker.val($.datepicker.formatDate($picker.datepicker("option", "dateFormat"), moment(initialDate).toDate()));
11628			}
11629		});
11630
11631		$eventList.find(".field-autocomplete").autocomplete({
11632			delay: 500,
11633			source: [],
11634			open: function (event, ui) {
11635				$('.ui-autocomplete').width($(event.target).innerWidth());
11636			}
11637		}).on("keyup", function () {
11638			var $input = $(this);
11639			$.ajax({
11640				url: settings.getTagsUrl,
11641				data: {
11642					query: $input.val().encodeURIComponent(),
11643					lang: $eventList.data("lang")
11644				},
11645				method: "get",
11646				success: function (data) {
11647					if (data && data.length) {
11648						$input.autocomplete("option", "source", data);
11649					}
11650				},
11651				traditional: true,
11652				cache: false
11653			});
11654		});
11655
11656		onChangeFilter($eventList);
11657		$eventList.find(settings.themeSelector).find("input").on('change', function () {
11658			onChangeFilter($eventList);
11659		});
11660		$eventList.find(settings.countrySelector).find("input").on("change", function () {
11661			onChangeFilter($eventList);
11662		});
11663		$eventList.find(settings.regionSelector).find("input").on("change", function () {
11664			onChangeFilter($eventList);
11665		});
11666
11667		var resultsVm = new EventListResultViewModel(index);
11668
11669		var defaultGuid = $eventList.data("defaultguid");
11670
11671		if ($eventList.find(".panel-filter").length) {
11672			updateSearchParams(resultsVm, $eventList, false, defaultGuid);
11673		}
11674
11675		$eventList.find(settings.filterForm).on("submit", function () { return false; });
11676		$eventList.find(settings.eventListFilterBtnSelector).on("click", function () {
11677			resultsVm.LoadedPages.removeAll();
11678			resultsVm.CurrentPage(1);
11679			loadEvents(resultsVm, $eventList, 0, false, $eventList.data("defaultguid"));
11680		});
11681		$eventList.on("click", settings.loadMoreButtonSelector, function () {
11682			var page = resultsVm.CurrentPage();
11683			resultsVm.CurrentPage(page + 1);
11684			resultsVm.LoadedPages.push(page);
11685			loadEvents(resultsVm, $eventList, resultsVm.EventCount(), false, defaultGuid);
11686		});
11687		$eventList.find(settings.resetButtonSelector).on("click", function () {
11688			resetFilter($eventList);
11689		});
11690
11691		var eventsData = null;
11692		var $jsonContainers = $eventList.find(".events-data");
11693		if ($jsonContainers && $jsonContainers.length > 0) {
11694			var $jsonContainer = $($jsonContainers[0]);
11695			eventsData = JSON.parse($jsonContainer.text() || $jsonContainer.html());
11696
11697			resultsVm.Skipped(eventsData.Skipped);
11698			resultsVm.CurrentPage(Math.floor(resultsVm.Skipped() / resultsVm.PageSize()) + 1);
11699
11700			_.each(eventsData.Items, function(item) {
11701				resultsVm.AddEvent(item);
11702			});
11703			resultsVm.AllEventsCount(eventsData.Count);}
11704
11705		if (!eventsData || (!eventsData.Items.length)) {
11706			$eventList.remove();
11707		} else {
11708			var resultContainer = $eventList.find(settings.eventListResultsSelector)[0];
11709			ko.cleanNode(resultContainer);
11710			updateSearchParams(resultsVm, $eventList);
11711			var widgetGuid = $eventList.attr("data-widgetguid");
11712			$(".server-rendered-" + widgetGuid).remove();
11713			ko.applyBindings(resultsVm, resultContainer);
11714			$.createDownloadPopover($eventList);
11715		}
11716	};
11717
11718	var prepareEventListsSafely = function () {
11719		var $eventLists = $(settings.eventListWidgetSelector);
11720		_.each($eventLists, function(eventList, index) {
11721			try {
11722				prepareEventLists(eventList, index);
11723			} catch (e) {
11724				if (window.console && window.console.log) { console.log("Failed to render event list widget #" + (index + 1)); }
11725			}
11726		});
11727	};
11728
11729	var isOpenedPopover = false;
11730
11731	var createTemplateEvents = function (events, widgetData) {
11732		var templateEvent = "";
11733
11734		$.each(events, function (_, event) {
11735			var eventListUrl = null;
11736			if (widgetData.InternalLinkUrl) {
11737				eventListUrl = widgetData.InternalLinkUrl;
11738			} else if (widgetData.EventListUrl) {
11739				eventListUrl = widgetData.EventListUrl;
11740			}
11741
11742			templateEvent += "<div class='calendar-event'>" +
11743				(eventListUrl 
11744					? "<a href='" + eventListUrl + "?" + widgetData.EventListQueryString + "&sdate=" + event.StartDate + "&edate=" + event.StartDate +  "' class='calendar-event__title'>" + event.Name + "</a>"
11745					: "<span>" + event.Name + "</span>") +
11746				"<div class='calendar-event__controls'><div class='control-links'>";
11747
11748			var todayUtcUnixTime = moment().unix();
11749
11750			if (widgetData.RegistrationUrl && event.EnableRegistration && event.unixTime > todayUtcUnixTime) {
11751				templateEvent += "<div class='control-link'><a href='" + widgetData.RegistrationUrl + "?" + Constants.queryParamNames.EventId + "=" + event.InformationMaterialId + "#" + widgetData.EventRegistrationWidgetFragment + "'>" + GlobalSettings.Calendar.RegistrationLinkLabel + "</a></div>";
11752			}
11753
11754			if (event.unixTime > todayUtcUnixTime) {
11755				var exportLink = settings.exportUrl + "?" + Constants.queryParamNames.EventId + "=" + event.InformationMaterialId + "&" + Constants.queryParamNames.DownloadFile;
11756
11757				templateEvent += "<div class='control-link'><a href='" + exportLink + "''>" + GlobalSettings.Calendar.AddToCalendar + "</a></div>";
11758			}
11759
11760			templateEvent += "</div></div></div>";
11761		});
11762
11763		return '<div class="calendar-list-events">' + templateEvent + "</div>";
11764	}
11765
11766	var initPopover = function (element, events, widgetData) {
11767		element.popover({
11768			title: "",
11769			trigger: "manual",
11770			content: createTemplateEvents(events, widgetData),
11771			placement: "bottom",
11772			container: "body",
11773			html: true
11774		});
11775		return element;
11776	}
11777
11778	$(document).on("click", function () {
11779		if (!isOpenedPopover) $(".day-with-single-event, .day-with-multiple-events").popover("hide");
11780	});
11781
11782	var groupEventsByDate = function(groupsObject, events) {
11783		_.each(events, function (event) {
11784			event.unixTime = moment(event.StartDate).startOf("day").unix();
11785			groupsObject[event.unixTime] = groupsObject[event.unixTime] || [];
11786			groupsObject[event.unixTime].push(event);
11787		});
11788	}
11789
11790	var prepareCalendars = function(widget) {
11791		var $widget = $(widget);
11792		var $jsonContainers = $widget.find(".calendar-data");
11793		var widgetData;
11794		if ($jsonContainers && $jsonContainers.length > 0) {
11795			var $jsonContainer = $($jsonContainers[0]);
11796			widgetData = JSON.parse($jsonContainer.text() || $jsonContainer.html());
11797		}
11798		var $calendarContainer = $widget.find(".calendar-container");
11799
11800		if (widgetData && widgetData.InformationMaterials) {
11801			var eventsByDate = {};
11802			var loadedYears = [];
11803			var tagsParam = "";
11804			var $loader = $widget.find(".overlay");
11805
11806			if (widgetData.ThemeGuids && widgetData.ThemeGuids.length) { // TODO: use not only themes
11807				_.each(widgetData.ThemeGuids, function(guid) {
11808					tagsParam += guid + "," + 1 + ";"; // TODO: use constants
11809				});
11810			}
11811
11812			widgetData.LoadedFrom = moment(widgetData.LoadedFrom);
11813			widgetData.LoadedTo = moment(widgetData.LoadedTo);
11814
11815			var firstYear = widgetData.LoadedFrom.year();
11816			var lastYear = widgetData.LoadedTo.year();
11817			for (var i = firstYear; i <= lastYear; i++) {
11818				loadedYears.push(i);
11819			}
11820
11821			var defaultDate = null;
11822
11823			if (widgetData.InPreviewMode && widgetData.InformationMaterials.length) {
11824				defaultDate = moment(widgetData.InformationMaterials[0].StartDate).toDate();
11825			}
11826
11827			groupEventsByDate(eventsByDate, widgetData.InformationMaterials);
11828
11829			var today = moment();
11830
11831			$calendarContainer.datepicker({
11832				changeYear: true,
11833				changeMonth: true,
11834				firstDay: 1,
11835				defaultDate: defaultDate,
11836				yearRange: "1990:+3",
11837				showOtherMonths: true,
11838				selectOtherMonths: true,
11839				showAdditionalWeeksOtherMonths: 1,
11840				beforeShowDay: function (date) {
11841					var calendarDayDate = moment(date);
11842					var result = [false, ""];
11843					var events = eventsByDate[calendarDayDate.unix()];
11844
11845					if (events && events.length) {
11846						result[1] = events.length === 1 ? "day-with-single-event " : "day-with-multiple-events";
11847						result[0] = true;
11848					}
11848 else if (calendarDayDate.year() === today.year() && calendarDayDate.month() === today.month() && calendarDayDate.date() === today.date()) {
11849						result[0] = true;
11850					}
11851
11852					return result;
11853				},
11854				onChangeMonthYear: function (year) {
11855					var selectedYearIndex = _.indexOf(loadedYears, year);
11856					var precedingYearIndex = _.indexOf(loadedYears, year - 1);
11857					var nextYearIndex = _.indexOf(loadedYears, year + 1);
11858
11859					if (widgetData.InPreviewMode) {
11860						return;
11861					}
11862
11863					var targetFrom = null;
11864					var targetTo = null;
11865
11866					if (precedingYearIndex === -1) {
11867						targetFrom = moment.utc([year - 1, 0, 1]);
11868					} else if (selectedYearIndex === -1) {
11869						targetFrom = moment.utc([year, 0, 1]);
11870					} else if (nextYearIndex === -1) {
11871						targetFrom = moment.utc([year + 1, 0, 1]);
11872					}
11873
11874					if (nextYearIndex === -1) {
11875						targetTo = moment.utc([year + 2, 0, 1]);
11876					} else if (selectedYearIndex === -1) {
11877						targetTo = moment.utc([year + 1, 0, 1]);
11878					} else if (precedingYearIndex === -1) {
11879						targetTo = moment.utc([year, 0, 1]);
11880					}
11881
11882					if (targetFrom && targetTo) {
11883						targetTo = targetTo.subtract(1, "milliseconds");
11884						$loader.show();
11885						var data = {
11886							startDate: targetFrom.toISOString(),
11887							endDate: targetTo.toISOString(),
11888							languageGuid: $widget.data("lang"),
11889							widgetGuid: $widget.data("widgetGuid"),
11890							tags: tagsParam,
11891							withoutEstimatedEvents: true
11892						};
11893						$.ajax({
11894							url: settings.getEventsUrl,
11895							data: data,
11896							success: function (data) {
11897								groupEventsByDate(eventsByDate, data.Items);
11898
11899								for (var i = targetFrom.year() ; i <= targetTo.year() ; i++) {
11900									loadedYears.push(i);
11901								}
11902
11903								$calendarContainer.datepicker("refresh");
11904							},
11905							traditional: true,
11906							cache: false
11907						}).always(function () {
11908							$loader.hide();
11909						});
11910					}
11911				},
11912				onSelect: function (dateText) {
11913					var $calendar = $(this);
11914					var dateFormat = $calendar.datepicker("option", "dateFormat");
11915					var date = moment($.datepicker.parseDate(dateFormat, dateText));
11916					var unixTime = date.unix();
11917					var events = eventsByDate[unixTime];
11918					var day = date.date();
11919
11920					$calendar.find(".day-with-single-event, .day-with-multiple-events").popover("hide");
11921
11922					setTimeout(function () {
11923						var $curDay = $calendar.find('.ui-datepicker-current-day');
11924						if ($curDay.attr('data-month') === $calendar.data('select-month') &&
11925							parseInt($curDay.text()) === $calendar.data('select-day')) isOpenedPopover = true;
11926
11927						if (!isOpenedPopover) {
11928							initPopover($curDay, events, widgetData).popover('show');
11929							$calendar.data({ 'select-day': day, 'select-month': $curDay.attr('data-month') });
11930						} else {
11931							$calendar.removeData(['select-day', 'data-month']);
11932						}
11933						isOpenedPopover = false;
11934					}.bind(this));
11935				}
11936			});
11937		}
11938	};
11939
11940	var prepareCalendarsSafely = function () {
11941		var $calendarWidgets = $(settings.calendarWidgetSelector);
11942		_.each($calendarWidgets, function(widget, index) {
11943			try {
11944				prepareCalendars(widget);
11945			} catch (e) {
11946				if (window.console && window.console.log) { console.log("Failed to render calendar widget #" + (index + 1)); }
11947			}
11948		});
11949	};
11950
11951	var EventRegistrationViewModel = function () {
11952		self.confiramtionChecked = ko.observable(false);
11953	};
11954
11955	var prepareEventRegistration = function () {
11956		_.each($(settings.eventRegistrationWidgetSelector), function (widget) {
11957			try {
11958				var $widget = $(widget);
11959				ko.applyBindings(new EventRegistrationViewModel(), widget);
11960
11961				var uiMessage = $widget.data("message");
11962				if (uiMessage) {
11963					$.fancyboxMessage(uiMessage, 400);
11964					clearUrlQuery();
11965				}
11966
11967				if (window.location.hash === "#event-registration-widget-anchor") {
11968					$widget.find(".panel-collapse").collapse("show");
11969				}
11970
11971				var $sendForm = $widget.find("form");
11972				$sendForm.lukoilAjaxSubmitForm(null, null, function () {
11973					$sendForm.reloadLukoilCaptcha();
11974				}, false);
11975			} catch (e) {
11976				if (window.console && window.console.log) { console.log("Failed to render event registration widget #" + (index + 1)); }
11977			}
11978		});
11979	}
11980
11981	Calendar.run = function () {
11982		prepareEventRegistration();
11983		prepareEventListsSafely();
11984		prepareCalendarsSafely();
11985	};
11986});;
11987LukoilApp.module("Advertisements", function (Advertisements, LukoilApp, Backbone, Marionette, $, _) {
11988    var settings = {
11989        filterListWidgetSelector: ".content",
11990        queryInputSelector: ".filter_lukoil input[type=text]",
11991        search: ".search-control",
11992        dataSelector: ".advert-data",
11993        listWidgetSelector: ".advert-list",
11994        apiUrl: "/api/advertisements/advertisements",
11995        apiUrlSearch: "/api/advertisements/advertisementssearch",
11996        loadMoreButtonSelector: ".load-more-button",
11997        listFilterBtnSelector: ".filter-btn",
11998        resetButtonSelector: ".button-reset",
11999
12000        applicationSelector: ".application-select",
12001        typeSelect: ".type-select"
12002    };
12003
12004    var TagsAll = {
12005        application: [],
12006        type: []
12007    };
12008    var filter = false;
12009    var count = 0;
12010    var dataArr = [];
12011
12012    var loadAdvertisements = function (vm, data, skip) {
12013        if (!vm.LoadingInProcess()) {
12014            vm.LoadingInProcess(true);
12015            data.skip = skip === undefined ? vm.CurrentCount() : skip;
12016            $.ajax({
12017                url: settings.apiUrl,
12018                data: data,
12019                method: "post",
12020                success: function (dataSource) {
12021                    dataSource = JSON.parse(dataSource);
12022                    _.each(dataSource.Items, function (item) {
12023                        vm.AddItem(item);
12024                    });
12025                    vm.TotalItemsCount(dataSource.Count);
12026                },
12027                traditional: true,
12028                cache: false
12029            }).fail(function () {
12030                $.fancyboxInit({
12031                    padding: 10,
12032                    content: "<div>" + GlobalSettings.ErrorMessages.AjaxErrorMessage + "</div>"
12033                });
12034            }).always(function () {
12035                vm.LoadingInProcess(false);
12036            });
12037        }
12038    };
12039
12040    var loadAdvertisementsWithSearch = function (vm, data, skip) {
12041        if (!vm.LoadingInProcess()) {
12042            vm.LoadingInProcess(true);
12043            vm.CurrentCount(0);
12044            data.skip = skip;
12045            data.filter = filter;
12046            $.ajax({
12047                url: settings.apiUrlSearch,
12048                data: data,
12049                method: "post",
12050                success: function (dataSource) {
12051                    dataSource = JSON.parse(dataSource);
12052                    if (dataSource.Items.length === 0) {
12053                        $.fancyboxInit({
12054                            padding: 10,
12055                            content: "<div>" + "Ничего не найдено" + "</div>"
12056                        });
12057                    }
12058                    dataArr = dataSource.Items;
12059                    count = $(".advert-list").data("count");
12060                    var arr = dataArr.slice(0, count);
12061                    _.each(arr, function (item) {
12062                        vm.AddItem(item);
12063                    });
12064                    vm.TotalItemsCount(dataSource.Count);
12065                },
12066                traditional: true,
12067                cache: false
12068            }).fail(function () {
12069                $.fancyboxInit({
12070                    padding: 10,
12071                    content: "<div>" + GlobalSettings.ErrorMessages.AjaxErrorMessage + "</div>"
12072                });
12073            }).always(function () {
12074                vm.LoadingInProcess(false);
12075            });
12076        }
12077    };
12078
12079    var getValues = function ($data, array, checked) {
12080        var $ms = $data.getValFromMultiSelect();
12081        if ($ms != null) {
12082            $ms.map(function (item) {
12083                array.push(item.value);
12084            });
12085        }
12086        fillMultiselector(array, checked)
12087    }
12088
12089    //ToDo
12090    var getValuesType = function ($data, array, checked) {
12091        var $ms = $data.getValFromMultiSelect();
12092        if ($ms != null) {
12093            $ms.map(function (item) {
12094                array.push(item.value);
12095            });
12096        }
12097    }
12098
12099    var onChangeFilter = function ($widget) {
12100        var $applicationMultiselect = $widget.find(settings.applicationSelector);
12101        var $typeMultiselect = $widget.find(settings.typeSelect);
12102
12103        var tagsData = {
12104            application: [],
12105            type: []
12106        };
12107
12108        if ($applicationMultiselect.length > 0 && $applicationMultiselect.getValFromMultiSelect().length > 0) { // change > 0
12109            getValues($applicationMultiselect, tagsData.application);
12110        }
12111
12112        if ($typeMultiselect.length > 0 && $typeMultiselect.getValFromMultiSelect().length > 0) {
12113            getValuesType($typeMultiselect, tagsData.type);
12114            $typeMultiselect.parent().removeClass("disabled");
12115        }
12116
12117        if (tagsData.application.length === 0) {
12118            $typeMultiselect.parent().removeClass("disabled");
12119            var content = $(settings.filterListWidgetSelector)
12120            var type = content.find(settings.typeSelect)
12121            var li = type.find("li")
12122            li.each(function (item) {
12123                $(this).show()
12124            })
12125        }
12126        TagsAll = tagsData; // ToDo
12127    }
12128
12129    var fillMultiselector = function (array) {
12130        var content = $(settings.filterListWidgetSelector);
12131        var type = content.find(settings.typeSelect);
12132        var selectors = findAllSelector(type);
12133        var countSelector = 0;
12134        selectors.each(function (item) {
12135            if (array.length > 0) {
12136                if ($.inArray($(this).data("parent"), array) === -1) {
12137                    if (type.getValFromMultiSelect().length === 0) {
12138                        $(this).closest("li").hide();
12139                    }
12140                } else {
12141                    countSelector = ++countSelector;
12142                    $(this)
12143                        .closest("li")
12144                        .show();
12145                }
12146            } else {
12147                $(this).closest("li").show();
12148                this.checked = false;
12149            }
12150        });
12151
12152        if (countSelector === 0 && type.getValFromMultiSelect().length === 0) {
12153            type.parent().addClass("disabled");
12154        } else {
12155            type.parent().removeClass("disabled");
12156        }
12157    };
12158
12159    var findAllSelector = function (selector) {
12160        var li = selector.find("li");
12161        var checkboxes = li.find("input[type=checkbox]");
12162        return checkboxes
12163    }
12164
12165    var findChildTags = function (array) {
12166        var localArr = [];
12167        var content = $(settings.filterListWidgetSelector);
12168        var type = content.find(settings.typeSelect);
12169        var checkboxes = findAllSelector(type)
12170        checkboxes.each(function (item) {
12171            if (array.length > 0) {
12172                if ($.inArray($(this).data("parent"), array) >= 0) {
12173                    localArr.push($(this).data("val"));
12174                }
12175            }
12176        });
12177        return localArr;
12178    }
12179
12180
12181    var ListResultViewModel = function () {
12182        var self = this;
12183
12184        self.Advertisements = ko.observableArray();
12185        self.CurrentCount = ko.observable(0);
12186        self.TotalItemsCount = ko.observable(0);
12187        self.LoadingInProcess = ko.observable(false);
12188        self.ShowPaginationButtons = ko.observable(true);
12189        self.CanLoadMore = ko.computed(function () {
12190            return !self.LoadingInProcess() && self.TotalItemsCount() > self.CurrentCount();
12191        });
12192
12193        self.AddItem = function (item) {
12194            self.Advertisements.push(item);
12195            self.CurrentCount(self.CurrentCount() + 1);
12196        }
12197        self.Tags = ko.observable();
12198        self.searchText = ko.observable("");
12199    };
12200
12201    var resetFilter = function ($widget) {
12202        $widget.find(".search-control").val("");
12203        filter = false;
12204    }
12205
12206    var prepareList = function () {
12207        var $widgets = $(settings.listWidgetSelector);
12208        var $filterWidgets = $(settings.filterListWidgetSelector);
12209
12210        $filterWidgets.find(settings.resetButtonSelector).on("click", function () {
12211            resetFilter($filterWidgets);
12212        });
12213
12214        var $filterListWidgetSelector = $(settings.filterListWidgetSelector);
12215        $filterListWidgetSelector.find(settings.applicationSelector).find("input").on('change',
12216            function (e) {
12217                onChangeFilter($filterListWidgetSelector);
12218            });
12219
12220        $filterListWidgetSelector.find(settings.typeSelect).find("input").on('change',
12221            function (e) {
12222                onChangeFilter($filterListWidgetSelector);
12223            });
12224
12225        _.each($widgets, function (widgetItem, index) {
12226            try {
12227                var $widgetItem = $(widgetItem);
12228                var vm = new ListResultViewModel(widgetItem);
12229                var $jsonContainers = $widgetItem.find(settings.dataSelector);
12230                if ($jsonContainers && $jsonContainers.length) {
12231                    var $jsonContainer = $($jsonContainers[0]);
12232                    var dataSource = JSON.parse($jsonContainer.text() || $jsonContainer.html());
12233                    _.each(dataSource.Items, function (item) {
12234                        vm.AddItem(item);
12235                    });
12236                    vm.TotalItemsCount(dataSource.Count);
12237                }
12238
12239                ko.applyBindings(vm, widgetItem);
12240
12241                var ajaxParams = {
12242                    widgetGuid: $widgetItem.data("widget-guid"),
12243                    published: $widgetItem.data("published"),
12244                    siteGuid: $widgetItem.data("site"),
12245                    countryGuid: $widgetItem.data("country"),
12246                    regionGuid: $widgetItem.data("region"),
12247                    stationId: $widgetItem.data("station"),
12248                    organizationGuid: $widgetItem.data("organization"),
12249                    take: $widgetItem.data("count"),
12250                    tags: [],
12251                    query: ""
12252                };
12253
12254                $widgetItem.on("click", settings.loadMoreButtonSelector, function () {
12255                    vm
12256                    if (!filter) {
12257                        loadAdvertisements(vm, ajaxParams);
12258                    } else {
12259                        if (!vm.LoadingInProcess()) {
12260                            vm.LoadingInProcess(true);
12261                        }
12262                        var arr = [];
12263                        arr = dataArr.slice(count, (count + count));
12264                        count += count;
12265                        _.each(arr, function (item) {
12266                            vm.AddItem(item);
12267                        });
12268                        vm.LoadingInProcess(false);
12269                    }
12270
12271                });
12272
12273                $filterListWidgetSelector.find(settings.queryInputSelector).on("keypress", function (e) {
12274                    if ((event.keyCode || event.which) == 13) {
12275                        var searchQuery = $(".search-control").val();
12276                        if (TagsAll.application.length != 0 || TagsAll.type != 0 || searchQuery != "") {
12277                            filter = true;
12278                            var childTags = [];
12279                            if (TagsAll.application.length > 0 && TagsAll.type.length === 0) {
12280                                childTags = findChildTags(TagsAll.application);
12281                                TagsAll.type = childTags;
12282                            }
12283                            ajaxParams.tags = TagsAll.application.concat(TagsAll.type);
12284                            ajaxParams.query = searchQuery != "" ? searchQuery : null;
12285                            vm.Advertisements([]);
12286                            ajaxParams.take = 999;
12287                            vm;
12288                            loadAdvertisementsWithSearch(vm, ajaxParams, 0);
12289                        }
12290                    }
12291                });
12292
12293                $filterListWidgetSelector.find(settings.listFilterBtnSelector).on("click", function () {
12294                    var searchQuery = $('.search-control').val();
12295                    if (TagsAll.application.length != 0 || TagsAll.type != 0 || searchQuery != "") {
12296                        filter = true;
12297                        var childTags = [];
12298                        if (TagsAll.application.length > 0 && TagsAll.type.length === 0) {
12299                            childTags = findChildTags(TagsAll.application)
12300                            TagsAll.type = childTags;
12301                        }
12302                        ajaxParams.tags = TagsAll.application.concat(TagsAll.type);
12303                        ajaxParams.query = searchQuery != "" ? searchQuery : null;
12304                        vm.Advertisements([]);
12305                        ajaxParams.take = 999;
12306                        vm
12307                        loadAdvertisementsWithSearch(vm, ajaxParams, 0);
12308                    } else {
12309                        document.location.reload(true);
12310                    }
12311                });
12312
12313            } catch (e) {
12314                if (window.console && window.console.log) { console.log("Failed to render advertlist list #" + (index + 1)); }
12315            }
12316        });
12317    };
12318
12319    Advertisements.run = function () {
12320        prepareList();
12321    };
12322
12323    Advertisements.on("start", function (options) {
12324        if (typeof useFilterInAdvList !== 'undefined')
12325            Advertisements.run();
12326    });
12327});
12328;
12329LukoilApp.module("PressReleases", function (PressReleases, LukoilApp, Backbone, Marionette, $, _) {
12330	"use strict";
12331
12332	var settings = {
12333		pressreleaseListWidgetSelector: ".pressrelease-list-widget",
12334		pressreleasePageWidgetSelector: ".press-release-page-title",
12335		filterForm: ".filter form",
12336		pressReleasesListFilterBtnSelector: ".filter-btn",
12337		pressReleasesListResultsSelector: ".pressrelease-list-results",
12338		getReleasesUrl: "/api/presscenter/releases",
12339		getTagsUrl: "/api/presscenter/Tags",
12340		datepickerSelector: ".form-control.calendar",
12341		startDateSelector: "#calendar-from",
12342		endDateSelector: "#calendar-to",
12343		loadMoreButtonSelector: ".load-more-button",
12344		countrySelector: ".country-select",
12345		themeSelector: ".theme-select",
12346		regionSelector: ".region-select",
12347		queryInputSelector: ".search-control",
12348		resetButtonSelector: ".button-reset",
12349	};
12350
12351	var requiredModules = {
12352		mediaLibrary: LukoilApp.module("MediaLibrary")
12353	};
12354
12355	var buildQueryStringForEventListFilter = function (query, tags, startDate, endDate) {
12356		var url = new URI(window.location.href);
12357
12358		url.search(function (data) {
12359			data[Constants.queryParamNames.SearchQuery] = query ? query : undefined;
12360			data[Constants.queryParamNames.Tags] = tags ? tags : undefined;
12361			data[Constants.queryParamNames.StartDate] = startDate ? startDate : undefined;
12362			data[Constants.queryParamNames.EndDate] = endDate ? endDate : undefined;
12363			return data;
12364		});
12365
12366		return url.search();
12367	};
12368
12369	var pad = function (num, size) {
12370		var s = num + "";
12371		while (s.length < size) s = "0" + s;
12372		return s;
12373	};
12374
12375	var updateSearchParams = function (vm, $releasesList) {
12376		vm.SearchParams = {
12377			currentUrl: window.location.href,
12378			take: Constants.PageSize,
12379			siteGuid: $releasesList.data("site-guid"),
12380			widgetGuid: $releasesList.data("widget-guid"),
12381			pageNavGuid: $releasesList.data("current-nav-guid"),
12382			langGuid: $releasesList.data("lang")
12383		};
12384
12385		if ($releasesList.find(".panel-filter").length) {
12386			var multiselects = [settings.themeSelector, settings.countrySelector];
12387			if (!$releasesList.find(settings.regionSelector).parent().hasClass("disabled")) {
12388				multiselects.push(settings.regionSelector);
12389			}
12390			var tagsVal = $.getTagsValFromMultiselects($releasesList, multiselects);
12391
12392			var $startDatePicker = $releasesList.find(settings.startDateSelector);
12393			var $endDatePicker = $releasesList.find(settings.endDateSelector);
12394			var queryVal = $releasesList.find(settings.queryInputSelector).val();
12395
12396			var startDateValue = $.datepicker.parseDate($startDatePicker.datepicker("option", "dateFormat"), $startDatePicker.val());
12397			var endDateValue = $.datepicker.parseDate($endDatePicker.datepicker("option", "dateFormat"), $endDatePicker.val());
12398
12399			vm.SearchParams.query = queryVal ? queryVal.encodeURIComponent() : queryVal;
12400			vm.SearchParams.tags = tagsVal;
12401			vm.SearchParams.startDate = startDateValue ? startDateValue.localAsUtcDate().toISOString() : null;
12402			vm.SearchParams.endDate = endDateValue ? endDateValue.localAsUtcDate().toISOString() : null;
12403		}
12404	};
12405
12406	var loadReleases = function (vm, $releasesList, skip, isPaging) {
12407		if (!vm.LoadingInProcess()) {
12408			if (!skip) {
12409				updateSearchParams(vm, $releasesList);
12410			}
12411
12412			vm.LoadingInProcess(true);
12413
12414			var data = vm.SearchParams;
12415			data.skip = skip;
12416
12417			$.ajax({
12418				url: settings.getReleasesUrl,
12419				data: data,
12420				method: "post",
12421				success: function (data) {
12422					var queryString = buildQueryStringForEventListFilter(vm.SearchParams.query, vm.SearchParams.tags, vm.SearchParams.startDate, vm.SearchParams.endDate);
12423					if (window.history && window.history.pushState) {
12424						window.history.replaceState(null, "", location.protocol + "//" + location.host + location.pathname + queryString);
12425					} else {
12426						window.location.href = location.protocol + "//" + location.host + location.pathname + "#" + queryString;
12427					}
12428					if (!skip || isPaging) {
12429						vm.ClearReleases();
12430					}
12431					_.each(data.Items, function (item) {
12432						vm.AddRelease(item);
12433					});
12434					vm.AllReleasesCount(data.Count);
12435					$.createDownloadPopover($releasesList);
12436
12437					$releasesList.find(".panel-time-line-month.last > .collapse").collapse("show");
12438				},
12439				traditional: true,
12440				cache: false
12441			}).fail(function () {
12442				$.fancyboxMessage(GlobalSettings.ErrorMessages.AjaxErrorMessage);
12443			}).always(function () {
12444				vm.LoadingInProcess(false);
12445			});
12446		}
12447	};
12448
12449	PressReleases.on("start", function (options) {
12450		PressReleases.run();
12451	});
12452
12453	function MonthViewModel(month, id, noSorting) {
12454		var self = this;
12455		self.Id = id;
12456		self.Month = month;
12457		self.TwoDigitMonth = pad(self.Month, 2);
12458		self.Releases = ko.observableArray([]);
12459		self.AddRelease = function (release) {
12460			release.vmId = self.Id + "-";
12461			if (release.MediaFileId) {
12462				release.Id = release.MediaFileId;
12463				release.vmId += release.MediaFileId + "mf";
12464			}
12465			else {
12466				release.Id = release.InformationMaterialId;
12467				release.vmId += release.InformationMaterialId + "im";
12468			}
12469
12470			if (!release.TableOfContents) {
12471				release.TableOfContents = null;
12472			}
12473
12474			release.PreviewFile = null;
12475			if (release.PreviewFiles && release.PreviewFiles.length) {
12476				release.PreviewFile = _.find(release.PreviewFiles, function (file) {
12477					return file.PreviewType === Constants.previewTypes.NewsFeeds || file.PreviewType === Constants.previewTypes.MediaLibrary;
12478				});
12479			}
12480
12481			if (release.MediaFileId) {
12482				release.Announcement = release.Description;
12483				release.ShowDescriptionInList = null;
12484				release.PreviewFile = release.MediaLibraryPreviewFile;
12485				release.MediaFiles = [release];
12486			}
12487
12488			if (!release.MediaFileId && release.MainFile) {
12489				release.MediaFiles.push({
12490					File: release.MainFile,
12491					Name: release.Name
12492				});
12493			}
12494
12495			if (release.MediaFiles) {
12496				for (var i = 0; i < release.MediaFiles.length; i++) {
12497					if (release.MediaFiles[i].LinkedMediaFile) {
12498						var linked = release.MediaFiles[i].LinkedMediaFile;
12499						release.MediaFiles[i] = linked;
12500					}
12501				}
12502			}
12503
12504			if (release.Type === Constants.InformationMaterialTypes.Publication &&
12505				!release.Agreed) {
12506				release.Url = null;
12507			}
12508
12509			release.redTitle = release.Type !== Constants.InformationMaterialTypes.PressRelease &&
12510				release.Type !== Constants.InformationMaterialTypes.News;
12511
12512			if (release.Type === Constants.InformationMaterialTypes.MediaAlbum ||
12513				release.Type === Constants.InformationMaterialTypes.Publication ||
12514				release.Type === Constants.InformationMaterialTypes.Event ||
12515				release.MediaFileId) {
12516				release.SubTitle = release.Name;
12517			} else {
12518				release.SubTitle = null;
12519			}
12520
12521			release.HasLinks = function (html) {
12522				if (!html) {
12523					return false;
12524				}
12525				var regex = '<a.*>.*</a>';
12526				return html.match(regex);
12527			}
12528
12529			if (release.Type === Constants.InformationMaterialTypes.MediaAlbum ||
12530				release.MediaFileId) {
12531				release.Name = GlobalSettings.PressReleaseList.MediaTitle;
12532			} else if (release.Type === Constants.InformationMaterialTypes.Event) {
12533				release.Name = GlobalSettings.PressReleaseList.EventTitle;
12534			} else if (release.Type === Constants.InformationMaterialTypes.Publication) {
12535				release.Name = GlobalSettings.PressReleaseList.PublicationTitle;
12536			}
12537
12538			var pdfExportTitle = null;
12539
12540			if (release.Type === Constants.InformationMaterialTypes.PressRelease)
12541			{
12542				pdfExportTitle = "ReleaseIn";
12543			} else if (release.Type === Constants.InformationMaterialTypes.News) {
12544				pdfExportTitle = "NewsIn";
12545			} else if (release.Type === Constants.InformationMaterialTypes.Publication && release.Agreed) {
12546				pdfExportTitle = "PublicationIn";
12547			}
12548
12549			if (pdfExportTitle !== null) {
12550				var exportUrl = "/api/presscenter/exportpressrelease?id=" + release.InformationMaterialId;
12551				release.MediaFiles.unshift({
12552					Name: GlobalSettings.PressRelease[pdfExportTitle],
12553					File: {
12554						AllowPreview: true,
12555						FileExtension: "PDF",
12556						FileDownloadUrl: exportUrl + "&dl=1",
12557						FileUrl: exportUrl,
12558						FileSizeText: null,
12559						Type: Constants.fileTypes.Document
12560					}
12561				});
12562			}
12563
12564			release.fileListData = requiredModules.mediaLibrary.getVmForFileList(release.MediaFiles);
12565			release.findFirstFileByTypes = function () {
12566				var types = arguments;
12567				return _.find(release.fileListData.allFiles, function (file) {
12568					for (var i = 0; i < types.length; i++) {
12569						if (file.Type == types[i]) {
12570							return true;
12571						}
12572					}
12573					return false;
12574				});
12575			};
12576			self.Releases.push(release);
12577			if (!noSorting) {
12578				self.Releases.sort(function (left, right) {
12579					if (right.PublicationDate === left.PublicationDate) {
12580						if (right.ContentSetId === left.ContentSetId) {
12581							if (right.Id === left.Id){
12582								return 0;
12583							}
12584
12585							return right.Id > left.Id;
12586						}
12587
12588						return right.ContentSetId > left.ContentSetId;
12589					}
12590
12591					return right.PublicationDate > left.PublicationDate ? 1 : -1;
12592				});
12593			}
12594		};
12595	}
12596
12597	function YearViewModel(year, id) {
12598		var self = this;
12599		self.Id = id;
12600		self.Year = year;
12601		self.Months = ko.observableArray([]);
12602		self.AddRelease = function (release) {
12603			var month = release.momentPublicationDate.month() + 1;
12604			var monthVm = _.find(self.Months(), function (item) {
12605				return month === item.Month;
12606			});
12607			if (!monthVm) {
12608				monthVm = new MonthViewModel(month, self.Id + "-" + month);
12609				self.Months.push(monthVm);
12610				self.Months.sort(function (left, right) {
12611					return right.Month - left.Month;
12612				});
12613			}
12614			monthVm.AddRelease(release);
12615		};
12616	}
12617
12618	function PressReleaseResultViewModel(id) {
12619		var self = this;
12620		self.Skipped = ko.observable(0);
12621		self.Id = id;
12622		self.SearchParams = {};
12623		self.Years = ko.observableArray([]);
12624		self.AllReleasesCount = ko.observable(0);
12625		self.LoadingInProcess = ko.observable(false);
12626		self.ShowPaginationButtons = ko.observable(true);
12627
12628		self.AddRelease = function (release) {
12629			release.momentPublicationDate = moment(release.PublicationDate);
12630			var year = release.momentPublicationDate.year();
12631			var yearVm = _.find(self.Years(), function (item) {
12632				return year === item.Year;
12633			});
12634			if (!yearVm) {
12635				yearVm = new YearViewModel(year, self.Id + "-" + year);
12636				self.Years.push(yearVm);
12637				self.Years.sort(function (left, right) {
12638					return right.Year - left.Year;
12639				});
12640			}
12641
12642			yearVm.AddRelease(release);
12643			self.AllReleasesCount(self.AllReleasesCount() + 1);
12644		};
12645
12646		self.IsActivePage = function (value) {
12647			//console.log(value, self.LoadedPages(), $.inArray(value, self.LoadedPages()));
12648			return $.inArray(value, self.LoadedPages()) >= 0;
12649		}
12650
12651		ko.PaginationViewModel.call(self, Constants.PageSize, self.AllReleasesCount, settings.pressreleaseListWidgetSelector, loadReleases);
12652		
12653		self.ClearReleases = function () {
12654			self.Years.removeAll();
12655			self.AllReleasesCount(0);
12656		};
12657	}
12658
12659	function PressReleaseResultCompactViewModel(id) {
12660		var self = this;
12661		self.Id = id;
12662		self.ReleasesVm = ko.observable(new MonthViewModel(null, self.Id, true));
12663		self.AddRelease = function (release) {
12664			self.ReleasesVm().AddRelease(release);
12665		};
12666	}
12667
12668	var resetFilter = function ($pressReleases) {
12669		$pressReleases.find(settings.queryInputSelector).val("");
12670		$.resetDatePickerValue($pressReleases.find(settings.startDateSelector));
12671		$.resetDatePickerValue($pressReleases.find(settings.endDateSelector));
12672	};
12673
12674	var updateFilterData = function ($dataSelector, $containers, tagsData) {
12675		if (tagsData.length > 0 && $containers && $containers.length > 0) {
12676			var $container = $($containers[0]);
12677			var data = JSON.parse($container.text() || $container.html());
12678
12679			var compatibleValues = [];
12680			if (data != null && data.Items != null) {
12681				data.Items.map(function(item) {
12682					if (tagsData.indexOf(item.theme) != -1 && compatibleValues.indexOf(item.area) == -1) {
12683						compatibleValues.push(item.area);
12684					}
12685				});
12686			}
12687			if (compatibleValues.length > 0) {
12688				$dataSelector.parent().removeClass("disabled");
12689				$dataSelector.find("li").hide();
12690				compatibleValues.map(function(item) {
12691					$dataSelector.find("input[data-val = " + item + "]").parents('li').show();
12692				});
12693			} else {
12694				$dataSelector.parent().addClass("disabled");
12695			}
12696		} else {
12697			$dataSelector.find("li").show();
12698			$dataSelector.parent().removeClass("disabled");
12699		}
12700	}
12701
12702	var onChangeThemeFilter = function ($pressReleaseList) {
12703		var $themeCountryContainers = $pressReleaseList.find(".theme-country-tag-guids");
12704		var $themeRegionContainers = $pressReleaseList.find(".theme-region-tag-guids");
12705
12706		var $themeMultiselect = $pressReleaseList.find(settings.themeSelector);
12707		var $countryMultiselect = $pressReleaseList.find(settings.countrySelector);
12708		var $regionMultiselect = $pressReleaseList.find(settings.regionSelector);
12709
12710		var tagsArray = [];
12711		var $ms = $themeMultiselect.getValFromMultiSelect();
12712		if ($ms != null) {
12713			$ms.map(function(item) {
12714				tagsArray.push(item.value);
12715			});
12716
12717			updateFilterData($countryMultiselect, $themeCountryContainers, tagsArray);
12718			updateFilterData($regionMultiselect, $themeRegionContainers, tagsArray);
12719
12720			if ($countryMultiselect.getValFromMultiSelect().length > 0) {
12721				$regionMultiselect.parent().addClass("disabled");
12722			}
12723		}
12724	}
12725
12726	var getCompatibleThemes = function ($containers, tagsData) {
12727		var compatibleValues = [];
12728		if (tagsData.length > 0 && $containers && $containers.length > 0) {
12729			var $container = $($containers[0]);
12730			var data = JSON.parse($container.text() || $container.html());
12731			if (data != null && data.Items != null) {
12732				data.Items.map(function(item) {
12733					if (tagsData.indexOf(item.area) != -1 && compatibleValues.indexOf(item.theme) == -1) {
12734						compatibleValues.push(item.theme);
12735					}
12736				});
12737			}
12738		}
12739
12740		return compatibleValues;
12741	}
12742
12743	var updateThemeFilter = function ($pressReleaseList) {
12744		var $themeCountryContainers = $pressReleaseList.find(".theme-country-tag-guids");
12745		var $themeRegionContainers = $pressReleaseList.find(".theme-region-tag-guids");
12746
12747		var countryThemeValues = $pressReleaseList.find(settings.countrySelector).getValFromMultiSelect();
12748		var regionThemeValues = $pressReleaseList.find(settings.regionSelector).getValFromMultiSelect();
12749
12750		var countryValues = [];
12751		if (countryThemeValues != null) {
12752			countryThemeValues.map(function(item) {
12753				countryValues.push(item.value);
12754			});
12755		}
12756
12757		var regionValues = [];
12758		if (regionThemeValues != null) {
12759			regionThemeValues.map(function(item) {
12760				regionValues.push(item.value);
12761			});
12762		}
12763
12764		var $themeSelector = $pressReleaseList.find(settings.themeSelector);
12765		if (regionValues.length > 0 || countryValues.length > 0) {
12766			var compatibleThemes = [];
12767			getCompatibleThemes($themeCountryContainers, countryValues).map(function(item) {
12768				if (compatibleThemes.indexOf(item) == -1) {
12769					compatibleThemes.push(item);
12770				}
12771			});
12772			getCompatibleThemes($themeRegionContainers, regionValues).map(function(item) {
12773				if (compatibleThemes.indexOf(item) == -1) {
12774					compatibleThemes.push(item);
12775				}
12776			});
12777
12778			if (compatibleThemes.length > 0) {
12779				$themeSelector.parent().removeClass("disabled");
12780				$themeSelector.find("li").hide();
12781				compatibleThemes.map(function (item) {
12782					$themeSelector.find("input[data-val = " + item + "]").parents('li').show();
12783				});
12784			}
12785			else {
12786				$themeSelector.parent().addClass("disabled");
12787			}
12788		} else {
12789			$themeSelector.find("li").show();
12790			$themeSelector.parent().removeClass("disabled");
12791		}
12792	}
12793
12794	var preparePressReleaseLists = function () {
12795		var $pressReleaseLists = $(settings.pressreleaseListWidgetSelector);
12796		_.each($pressReleaseLists, function (pressReleaseList, index) {
12797			try {
12798				var $pressReleaseList = $(pressReleaseList);
12799				var isCompactMode = $($pressReleaseList[0]).data("compact") === "True";
12800				var resultsVm;
12801
12802				if ($pressReleaseList.find(".panel-filter").length) {
12803					var $regionsSelect = $pressReleaseList.find(settings.regionSelector);
12804					var $countrySelect = $pressReleaseList.find(settings.countrySelector);
12805					var russiaGuid = $pressReleaseList.data("russia-guid");
12806
12807					$regionsSelect.updateSelectStateByValueInAnother($countrySelect, russiaGuid);
12808					$pressReleaseList.find(settings.countrySelector).on("change", "input", function () {
12809						$regionsSelect.updateSelectStateByValueInAnother($countrySelect, russiaGuid);
12810					});
12811				}
12812
12813				$pressReleaseList.find(".field-autocomplete").autocomplete({
12814					delay: 500,
12815					source: [],
12816					open: function (event, ui) {
12817						$('.ui-autocomplete').width($(event.target).innerWidth());
12818					}
12819				}).on("keyup", function () {
12820					var $input = $(this);
12821					$.ajax({
12822						url: settings.getTagsUrl,
12823						data: {
12824							query: $input.val().encodeURIComponent(),
12825							lang: $pressReleaseList.data("lang")
12826						},
12827						method: "get",
12828						success: function (data) {
12829							if (data && data.length) {
12830								$input.autocomplete("option", "source", data);
12831							}
12832						},
12833						traditional: true,
12834						cache: false
12835					});
12836				});
12837
12838				if (isCompactMode) {
12839					resultsVm = new PressReleaseResultCompactViewModel(index);
12840				} else {
12841					var $datePickers = $pressReleaseList.find(settings.datepickerSelector);
12842					_.each($datePickers, function (picker) {
12843						var $picker = $(picker);
12844						var initialDate = $picker.data("initialvalue");
12845						if (initialDate) {
12846							$picker.val($.datepicker.formatDate($picker.datepicker("option", "dateFormat"), moment(initialDate).toDate()));
12847						}
12848					});
12849
12850					resultsVm = new PressReleaseResultViewModel(index);
12851
12852					$pressReleaseList.find(settings.filterForm).on("submit", function () { return false; });
12853					$pressReleaseList.find(settings.pressReleasesListFilterBtnSelector).on("click", function () {
12854						resultsVm.LoadedPages.removeAll();
12855						resultsVm.CurrentPage(1);
12856						loadReleases(resultsVm, $pressReleaseList, 0, false);
12857					});
12858					$pressReleaseList.on("click", settings.loadMoreButtonSelector, function () {
12859						var page = resultsVm.CurrentPage();
12860						resultsVm.CurrentPage(page + 1);
12861						resultsVm.LoadedPages.push(page);
12862						loadReleases(resultsVm, $pressReleaseList, page * resultsVm.PageSize(), false);
12863					});
12864					$pressReleaseList.find(settings.resetButtonSelector).on("click", function () {
12865						resetFilter($pressReleaseList);
12866					});
12867				}
12868
12869				onChangeThemeFilter($pressReleaseList);
12870				$pressReleaseList.find(settings.themeSelector).find("input").on('change', function () {
12871					onChangeThemeFilter($pressReleaseList);
12872				});
12873
12874				updateThemeFilter($pressReleaseList);
12875				$pressReleaseList.find(settings.countrySelector).find("input").on("change", function () {
12876					updateThemeFilter($pressReleaseList);
12877				});
12878
12879				$pressReleaseList.find(settings.regionSelector).find("input").on("change", function () {
12880					updateThemeFilter($pressReleaseList);
12881				});
12882
12883				var releasesData = null;
12884				var $jsonContainers = $pressReleaseList.find(".pressreleases-data");
12885				if ($jsonContainers && $jsonContainers.length > 0) {
12886					var $jsonContainer = $($jsonContainers[0]);
12887					releasesData = JSON.parse($jsonContainer.text() || $jsonContainer.html());
12888					if (!isCompactMode) {
12889						resultsVm.Skipped(releasesData.Skipped);
12890						resultsVm.CurrentPage(Math.floor(resultsVm.Skipped() / resultsVm.PageSize()) + 1);
12891					}
12892					_.each(releasesData.Items, function (item) {
12893						resultsVm.AddRelease(item);
12894					});
12895					if (resultsVm.AllReleasesCount) {
12896						resultsVm.AllReleasesCount(releasesData.Count);
12897					}
12898				}
12899
12900				if (!releasesData || (!releasesData.Items.length && isCompactMode)) {
12901					$pressReleaseList.remove();
12902				} else {
12903					var resultContainer = $pressReleaseList.find(settings.pressReleasesListResultsSelector)[0];
12904					ko.cleanNode(resultContainer);
12905					updateSearchParams(resultsVm, $pressReleaseList);
12906					var widgetGuid = $pressReleaseList.attr("data-widget-guid");
12907					$(".server-rendered-" + widgetGuid).remove();
12908					ko.applyBindings(resultsVm, resultContainer);
12909					$.createDownloadPopover($pressReleaseList);
12910				}
12911
12912			} catch (e) {
12913				if (window.console && window.console.log) { console.log("Failed to render press releases list #" + (index + 1)); }
12914			}
12915		});
12916	};
12917
12918	var preparePressReleasePages = function () {
12919		var $pressReleasePages = $(settings.pressreleasePageWidgetSelector);
12920		_.each($pressReleasePages, function (pressReleasePage, index) {
12921			try {
12922				if (window.pressReleaseAvailableLocales != null) {
12923					$("#lang .dropdown-menu li[langcode]").addClass("hide");
12924					$.each(window.pressReleaseAvailableLocales,
12925						function(i, e) {
12926							$("#lang .dropdown-menu li[langcode='" + e.toLowerCase() + "']").removeClass("hide");
12927						});
12928					if ($("#lang .dropdown-menu li[langcode]:not(.hide)").length == 0) {
12929						$("#lang .caret, #lang .dropdown-menu").hide();
12930					}
12931				} else {
12932					$("#lang .dropdown-menu a").addClass("disabled").attr("href", null);
12933				}
12934			} catch (e) {
12935				if (window.console && window.console.log) { console.log("Failed to render press releases page #" + (index + 1)); }
12936			}
12937		});
12938	};
12939
12940	PressReleases.run = function () {
12941		preparePressReleasePages();
12942		preparePressReleaseLists();
12943	};
12944});;
12945LukoilApp.module("MassMedia", function (MassMedia, LukoilApp, Backbone, Marionette, $, _) {
12946	"use strict";
12947
12948	var settings = {
12949		massMediaWidgetSelector: ".massmedia-widget",
12950		massMediaApiUrl: "/api/presscenter/issue"
12951	};
12952
12953	MassMedia.on("start", function (options) {
12954		MassMedia.run();
12955	});
12956
12957	var requiredModules = {
12958		mediaLibrary: LukoilApp.module("MediaLibrary")
12959	};
12960
12961	function MassMediaViewModel(currentIssue, issueList) {
12962		var self = this;
12963		var prepareFiles = function (issue) {
12964			issue.PreviewFile = null;
12965			if (issue.PreviewFiles && issue.PreviewFiles.length) {
12966				issue.PreviewFile = _.find(issue.PreviewFiles, function (file) {
12967					return file.PreviewType === Constants.previewTypes.NewsFeeds;
12968				});
12969			}
12970
12971			for (var i = 0; i < issue.MediaFiles.length; i++) {
12972				if (issue.MediaFiles[i].LinkedMediaFile) {
12973					issue.MediaFiles[i] = issue.MediaFiles[i].LinkedMediaFile;
12974				}
12975			}
12976
12977			if (!issue.IsAnonCollapsed) {
12978				issue.IsAnonCollapsed = ko.observable(false);
12979			} else {
12980				issue.IsAnonCollapsed(false);
12981			}
12982			
12983			issue.fileListData = requiredModules.mediaLibrary.getVmForFileList(issue.MediaFiles);
12984
12985			return issue;
12986		}
12987
12988		self.CurrentIssue = ko.observable();
12989		self.IssueList = ko.observableArray(issueList);
12990		self.Years = _.unique(_.pluck(issueList, "Year"));
12991		self.CurrentYear = ko.observable(self.Years[0]);
12992		self.IssueByYear = ko.observableArray([]);
12993
12994		var issueCache = {};
12995		if (currentIssue) {
12996			issueCache[currentIssue.InformationMaterialId] = prepareFiles(currentIssue);
12997
12998			self.CurrentIssue(currentIssue);
12999
13000			var date = moment(currentIssue.PublicationDate);
13001
13002			self.CurrentYear = ko.observable(date.year());
13003		}
13004
13005		self.SelectIssue = function (issueInfo, event) {
13006			var fromCache = issueCache[issueInfo.IssueId];
13007			if (fromCache) {
13008				if (self.CurrentIssue()) {
13009					issueCache[self.CurrentIssue().InformationMaterialId] = self.CurrentIssue();
13010				}
13011
13012				self.CurrentIssue(fromCache);
13013				$.createDownloadPopover($(settings.massMediaWidgetSelector));
13014			} else {
13015				$.ajax({
13016					url: settings.massMediaApiUrl,
13017					data: { issueId: issueInfo.IssueId },
13018					success: function (data) {
13019						issueCache[self.CurrentIssue().InformationMaterialId] = self.CurrentIssue();
13020						self.CurrentIssue(prepareFiles($.parseJSON(data)));
13021						$.createDownloadPopover($(settings.massMediaWidgetSelector));
13022					},
13023					cache: false
13024				});
13025			}
13026		};
13027
13028		var updateIssues = function (year) {
13029			self.IssueByYear(_.filter(issueList,
13030			function (issue) {
13031				return issue.Year === year;
13032			}));
13033		}
13034
13035		self.UpdateIssueByYear = function (year, event) {
13036			self.CurrentYear(year);
13037			updateIssues(year);
13038			self.SelectIssue(self.IssueByYear()[0]);
13039		}
13040
13041		updateIssues(self.CurrentYear());
13042	}
13043
13044	var prepareMassMediaWidget = function() {
13045		var $massMediaWidgets = $(settings.massMediaWidgetSelector);
13046		_.each($massMediaWidgets, function (widget, index) {
13047			try {
13048				var $widget = $(widget);
13049
13050				var $jsonContainer = $($widget.find("script")[0]);
13051				if ($jsonContainer.length) {
13052					var widgetData = $.parseJSON($jsonContainer.text() || $jsonContainer.html());
13053					$jsonContainer.remove();
13054					if (!widgetData) {
13055						$widget.hide();
13056						return;
13057					}
13058
13059					var widgetVm = new MassMediaViewModel(widgetData.LastIssue, widgetData.IssueInfoList);
13060					ko.applyBindings(widgetVm, widget);
13061
13062					$.createDownloadPopover($widget);
13063				} else {
13064					$widget.hide();
13065				}
13066			} catch (e) {
13067				if (window.console && window.console.log) { console.log("Failed to render Mass media widget #" + (index + 1)); }
13068			} 
13069		});
13070	};
13071
13072	MassMedia.run = function () {
13073		prepareMassMediaWidget();
13074	};
13075});;
13076LukoilApp.module("GasStationPrices", function (GasStationPrices, LukoilApp, Backbone, Marionette, $, _) {
13077	"use strict";
13078
13079	var settings = {
13080		widgetSelector: ".gas-station-prices",
13081		cookieName: "azs_prices_station_id"
13082	};
13083
13084	GasStationPrices.on("start", function (options) {
13085		GasStationPrices.run();
13086	});
13087
13088	var initWidget = function ($widget, tabsCount) {
13089		$widget.find(".owl-stage-outer").remove();
13090		$widget.find('.nav-tabs').trigger('destroy.owl.carousel');
13091		$widget.find('.nav-tabs').lukOwlCarousel({
13092			nav: true,
13093			navRewind: false,
13094			dots: false,
13095			autoWidth: false,
13096			responsive: {
13097				0: {
13098					items: 1,
13099					slideBy: 1
13100				},
13101				768: {
13102					items: tabsCount,
13103					slideBy: tabsCount
13104				},
13105				992: {
13106					items: tabsCount,
13107					slideBy: tabsCount
13108				}
13109			}
13110		});
13111
13112		$widget.find('.managers-info ul').responsiveSlides({
13113			pager: false,
13114			pause: false,
13115			timeout: 3000,
13116			namespace: "manager-slide"
13117		});
13118	};
13119
13120	function GasStationPricesWidgetVM(data, $widget) {
13121		var self = this;
13122    updateData(data);
13123		var getStationFromCookie = function() {
13124			var id = $.lukoilGetCookie(settings.cookieName);
13125			if (id) {
13126				return _.find(self.Stations(),
13127					function(station) {
13128						return station.Id == id;
13129					});
13130			}
13131		};
13132
13133		self.Stations = ko.observableArray(_.sortBy(data.Stations, function(s) {
13134			return s.City;
13135    }));
13136   // add for Belgian Site
13137    self.uniqueStations = ko.dependentObservable(function() {
13138      var types = ko.utils.arrayMap(self.Stations(), function(item){ return item.PostCode})
13139      return ko.utils.arrayGetDistinctValues(types).sort();
13140  });
13141  self.SelectedUniqueStations = ""
13142    self.SelectedStation = ko.observable(getStationFromCookie() || self.Stations()[0]);
13143		self.SelectedFuel = ko.observable(self.SelectedStation().Fuels[0]);
13144		self.CurrentTime = ko.observable(getTime());
13145
13146		setInterval(function () {
13147			self.CurrentTime(getTime());
13148		}, 1000);
13149
13150		function getTime() {
13151			return moment().utc().add(data.TimeOffset, "m").format('LLL');
13152		}
13153
13154		self.ChangeFuel = function(data) {
13155			self.SelectedFuel(data);
13156    };
13157
13158    self.GoToStationPost = function(data) {
13159        var url = window.location.href + '/ForMotorists/PetrolStations?form=gasStation&tab=search&closest=0&geographyString=Belgium postal_code' + self.SelectedUniqueStations;
13160        window.location.href = url;
13161    };
13162		self.ChangeSation = function(data) {
13163			self.SelectedFuel(self.SelectedStation().Fuels[0]);
13164
13165			self.UpdateCarouselAndSlid3er();
13166			saveCokie();
13167		};
13168
13169		self.UpdateCarouselAndSlid3er = function () {
13170			var tabsCount = self.SelectedStation().Fuels.length > 4 ? 4 : self.SelectedStation().Fuels.length;
13171			initWidget($widget, tabsCount);
13172		};
13173
13174		var saveCokie = function() {
13175			$.removeCookie(settings.cookieName);
13176			$.lukoilSaveCookie(settings.cookieName, self.SelectedStation().Id, { expires: 90, path: '/' });
13177		}
13178
13179		function updateData(data) {
13180			$.each(data.Stations, function(index, station) {
13181				$.each(station.Fuels, function (index, fuel) {
13182					fuel.DiscountCurrency = fuel.Currency;
13183					if ((GlobalSettings.CurrentLanguage === 'fr' || GlobalSettings.CurrentLanguage === 'nl') && fuel.Discount) {
13184						fuel.Discount = (parseFloat(fuel.Discount.replace(',', '.')) * 100).toFixed(1);
13185						fuel.Discount = fuel.Discount.replace('.', ',');
13186						fuel.DiscountCurrency = 'CENT';
13187					}
13188				});
13189			});
13190		}
13191	}
13192
13193	var prepareWidgets = function() {
13194		var $widgets = $(settings.widgetSelector);
13195		_.each($widgets, function (widget, index) {
13196			try {
13197				var $widget = $(widget);
13198
13199				var $jsonContainer = $($widget.find("script")[0]);
13200				if ($jsonContainer.length) {
13201					var widgetData = $.parseJSON($jsonContainer.text() || $jsonContainer.html());
13202					$jsonContainer.remove();
13203					if (!widgetData || !widgetData.Stations.length) {
13204						$widget.hide();
13205						return;
13206					}
13207
13208					var widgetVm = new GasStationPricesWidgetVM(widgetData, $widget);
13209					ko.applyBindings(widgetVm, widget);
13210					widgetVm.UpdateCarouselAndSlid3er();
13211				} else {
13212					if ($widget.hasClass("gasStationPage")) {
13213						var tabsCount = $widget.find('.nav-tabs .nav-tab').length > 4 ? 4 : $widget.find('.nav-tabs .nav-tab').length;
13214						initWidget($widget, tabsCount);
13215
13216					} else {
13217						$widget.hide();
13218					}
13219				}
13220			} catch (e) {
13221				if (window.console && window.console.log) { console.log("Failed to render GasStationPrices widget #" + (index + 1)); }
13222			}
13223		});
13224	};
13225
13226	GasStationPrices.run = function () {
13227		prepareWidgets();
13228	};
13229});
13230
13231function ChangeFuelPrice(el, fuelId) {
13232	var $gs = $(el).closest(".gas-station-prices");
13233	$gs.find(".nav-tabs .nav-tab").removeClass("selected");
13234	$gs.find(".nav-tabs .nav-tab#fuelId_" + fuelId).addClass("selected");
13235
13236	$gs.find(".tab-content .tab-pane").removeClass("active");
13237	$gs.find(".tab-content .tab-pane#tab-pane_" + fuelId).addClass("active");
13238}
13239;
13240LukoilApp.module("Trainers", function(Trainers, LukoilApp, Backbone, Marionette, $, _) {
13241	var settings = {
13242		invalidClassName: "invalid",
13243		sendEmailUrl: "/api/trainers/sendpdftoemail"
13244	};
13245
13246	Trainers.on("start", function(options) {
13247		Trainers.run();
13248	});
13249
13250	var FormViewModel = function (type, formSelector, successMessage, errorsMessage, successWarningMessage) {
13251		var self = this;
13252		self.Type = type,
13253		self.Checks = null;
13254		self.PersonName = ko.observable("");
13255		self.IsDirty = ko.observable(true);
13256		self.FormSelector = formSelector;
13257		self.SuccessMessage = successMessage;
13258		self.ErrorsMessage = errorsMessage;
13259		self.SuccessWarningMessage = successWarningMessage;
13260		self.Errors = ko.observableArray([]);
13261		self.AddError = function (errorString, checkName) {
13262			self.Errors.remove(function (error) {
13263				return error.checkName === checkName;
13264			});
13265			if (errorString) {
13266				self.Errors.push({ checkName: checkName, errorString: errorString });
13267			}
13268		};
13269	};
13270
13271	var TrainersViewModel = function () {
13272		var self = this;
13273
13274		self.Form = new FormViewModel(1, "#individual-shareholder-form", "Анкета заполнена без ошибок!", "При заполнении анкеты допущены ошибки. Заполните анкету еще раз.", "Рекомендуется проставить отметку «Согласен на внесение исправительных записей». При наличии отметки о согласии в этом поле Вам не потребуется давать отдельное письменное согласие на внесение исправительных записей по Вашему лицевому счету, если в этом возникнет потребность, что существенно сократит время на устранение возможных неточностей. <br/> Хотите это сделать?");
13275		self.Countinuation = new FormViewModel(2, "#continuation-of-individual-shareholder
13275-form", "Продолжение анкеты заполнено без ошибок!", "При заполнении продолжения анкеты допущены ошибки. Заполните анкету еще раз.");
13276		self.StandardVoting = new FormViewModel(3, "#standard-voting-paper", "Бюллетень заполнен без ошибок!", "При заполнении бюллетеня допущены ошибки.");
13277		self.CumulativeVoting = new FormViewModel(4, "#cumulative-voting-paper", "Бюллетень заполнен без ошибок!", "При заполнении бюллетеня допущены ошибки.");
13278		self.SelectedForm = ko.observable();
13279		self.SendIsOpen = ko.observable(false);
13280		self.Email = ko.observable("");
13281		self.EmailIsValid = ko.observable(true);
13282
13283		var validateInner = function (dontShowSuccessMessage) {
13284			_.each(self.SelectedForm().Checks, function (item) {
13285				if (item && item.validate) {
13286					item.validate();
13287				}
13288			});
13289
13290			var isValid = !self.SelectedForm().Errors().length;
13291
13292			if (isValid) {
13293				var checked = $("#correctional-record-sign input[type=checkbox]:checked");
13294				if (!dontShowSuccessMessage && self.SelectedForm().SuccessMessage) {
13295					if (checked != null && checked.length == 0 && self.SelectedForm().SuccessWarningMessage) {
13296						$.fancyConfirm(self.SelectedForm().SuccessWarningMessage, function (confirmResult) {
13297							if (!confirmResult) {
13298								setTimeout(function() {
13299									$.fancyConfirm(self.SelectedForm().SuccessMessage, null, "Ok");
13300								}, 100);
13301							}
13302						}, "YesNo");
13303					} else {
13304						$.fancyConfirm(self.SelectedForm().SuccessMessage, null, "Ok");
13305					}
13306				}
13307			} else if (self.SelectedForm().ErrorsMessage) {
13308				$.fancyConfirm(self.SelectedForm().ErrorsMessage, null, "Ok");
13309			}
13310
13311			self.SelectedForm().IsDirty(!isValid);
13312
13313			return isValid;
13314		};
13315
13316		var getTrainerValues = function() {
13317			var $form = $(self.SelectedForm().FormSelector);
13318
13319			var values = {};
13320
13321			_.each($form.find("input, select"), function (input) {
13322				var $input = $(input);
13323				var key = $input.data("key");
13324				if (key) {
13325					if ($input.is(":checkbox")) {
13326						values[key] = $input.is(":checked") ? 1 : 0;
13327					} else {
13328						values[key] = $input.val().encodeURIComponent();
13329					}
13330				}
13331			});
13332
13333			return values;
13334		};
13335
13336		self.Validate = function () {
13337			return validateInner();
13338		};
13339
13340		self.Print = function () {
13341			if (self.SelectedForm().FormSelector && validateInner(true)) {
13342				var $frame = $("#trainer-print-frame");
13343
13344				$frame.contents()
13345					.find('body')
13346					.html("")
13347					.append("<link href='/Content/css/bootstrap.min.css' rel='stylesheet'/><link href='/Content/css/style.css' rel='stylesheet'/><link href='/Content/css/trainers.css' rel='stylesheet'/>")
13348					.append($(self.SelectedForm().FormSelector).parent().clone());
13349
13350				setTimeout(function() {
13351					$frame[0].contentWindow.print();
13352				}, 500);
13353			}
13354		};
13355
13356		self.OpenSendDialog = function() {
13357			self.SendIsOpen(true);
13358		}
13359
13360		self.SubmitEmailForm = function (formElement) {
13361			$(formElement).find("input[name=Values]").val(JSON.stringify(getTrainerValues()));
13362			$(formElement).find("input[name=Type]").val(self.SelectedForm().Type);
13363			return true;
13364		};
13365
13366		self.Save = function () {
13367			if (self.SelectedForm().FormSelector && validateInner(true)) {
13368				var $saveForm = $("#trainer-save-form");
13369				$saveForm.find("textarea[name=type]").val(self.SelectedForm().Type);
13370				$saveForm.find("textarea[name=values]").val(JSON.stringify(getTrainerValues()));
13371				$saveForm.trigger("submit");
13372			}
13373		};
13374	};
13375
13376	var trainersVm;
13377
13378	var Check = function (options) {
13379		var setValidationClasses = function (errorString) {
13380			var $target = options.$invalidClassTarget || options.$elements;
13381			if (errorString) {
13382				$target.addClass(settings.invalidClassName);
13383			} else {
13384				$target.removeClass(settings.invalidClassName);
13385			}
13386		};
13387
13388		var checkRegexp = function (val) {
13389			var result = true;
13390			if ((!options.regexpValidationPredicate || options.regexpValidationPredicate(options.triggerElSelector)) && options.regexp && options.regexp instanceof RegExp) {
13391				var regexp = options.regexp;
13392				regexp.lastIndex = 0;
13393				var matches = regexp.exec(val);
13394				result = matches && matches[0] === val;
13395			}
13396			return result;
13397		};
13398
13399		getValue = function ($elements) {
13400			var value = "";
13401			_.each($elements, function (element) {
13402				value += $(element).val();
13403			});
13404			return value;
13405		};
13406
13407		var onEditCheck = function () {
13408			var val = getValue(options.$elements);
13409			var result = !val || checkRegexp(val) ? undefined : options.regexpValidationError;
13410			if (!result && options.additionalOnEditValidation) {
13411				result = options.additionalOnEditValidation(val, options.$elements);
13412			}
13413			setValidationClasses(result);
13414			options.vm.AddError(result, options.name);
13415			return result;
13416		};
13417
13418		if (options.checkOnEdit) {
13419			options.$elements.on("change", function (event) {
13420				onEditCheck();
13421			});
13422		}
13423
13424		this.name = options.name;
13425		this.triggerElSelector = options.triggerElSelector;
13426		this.checkOnEdit = options.checkOnEdit;
13427
13428		this.getCurrentValue = function () {
13429			return getValue(options.$elements);
13430		}
13431
13432		this.validate = function (checkOnlyOnEdit) {
13433			var result;
13434			var val = getValue(options.$elements);
13435			if (checkOnlyOnEdit && val) {
13436				result = onEditCheck();
13437			} else {
13438				if (val) {
13439					result = onEditCheck();
13440				} else {
13441					result = options.mandatoryField && (!options.mandatoryValidationPredicate || options.mandatoryValidationPredicate(options.triggerElSelector)) ? options.mandatoryFieldError : undefined;
13442				}
13443				if (!result && options.additionalValidation) {
13444					result = options.additionalValidation(val, options.$elements);
13445				}
13446			}
13447
13448			setValidationClasses(result);
13449			options.vm.AddError(result, options.name);
13450		};
13451	};
13452
13453	var registerTrigger = function(selector, checks) {
13454		$(selector).on("change", function () {
13455			_.each(checks, function (check) {
13456				if (check.triggerElSelector === selector && check.getCurrentValue() && check.checkOnEdit) {
13457					check.validate(true);
13458				}
13459			});
13460		});
13461	}
13462
13463	var prepareTrainers = function () {
13464		var $shareholderFormWidget;
13465		var $votingPaperFormWidget;
13466		// delete all trainers widgets except first
13467		_.each($(".individual-shareholder-form-widget, .voting-paper-form-widget"), function (item, index) {
13468			var $item = $(item);
13469			if (index === 0 && $item.is(".individual-shareholder-form-widget")) {
13470				$shareholderFormWidget = $item;
13471			} else if (index === 0 && $item.is(".voting-paper-form-widget")) {
13472				$votingPaperFormWidget = $item;
13473			} else if (index > 0) {
13474				$item.remove();
13475			}
13476		});
13477
13478
13479		if ($shareholderFormWidget) {
13480			trainersVm = new TrainersViewModel();
13481			trainersVm.SelectedForm(trainersVm.Form);
13482			ko.applyBindings(trainersVm, $shareholderFormWidget[0]);
13483
13484			$shareholderFormWidget.find('.calendar').datepicker("option", "yearRange", "-150:+150");
13485
13486			$shareholderFormWidget.find(".trainer-form input, .trainer-form select").on("change", function () {
13487				trainersVm.SelectedForm().IsDirty(true);
13488			});
13489
13490			$(".trainer-popup .button, .change-form-button").on("click", function () {
13491				var form = this.getAttribute("data-form");
13492				if (form === "continuation") {
13493					if (trainersVm.SelectedForm() === trainersVm.Form && $(this).is(".change-form-button") && trainersVm.Form.IsDirty()) {
13494						$.fancyConfirm("Сначала требуется заполнить анкету акционера с применением тренажера «Анкеты акционера».", null, "Ok");
13495					} else {
13496						trainersVm.SelectedForm(trainersVm.Countinuation);
13497						parent.$.fancybox.close();
13498					}
13499				} else {
13500					trainersVm.SelectedForm(trainersVm.Form);
13501					parent.$.fancybox.close();
13502				}
13503			});
13504
13505			var $sendForm = $("#send-email-form form");
13506			$sendForm.lukoilAjaxSubmitForm(null, null, function() {
13507				trainersVm.SendIsOpen(false);
13508				$sendForm.reloadLukoilCaptcha();
13509			}, false);
13510
13511			if ($("#individual-shareholder-form").length) {
13512
13513				$("#individual-shareholder-form").find(".auto-tab-inputs").on("keyup", "input", function () {
13514					var key = event.keyCode || event.charCode;
13515					var $el = $(this);
13516					var curLength = $el.val().length;
13517					var maxLength = $el.attr("maxlength");
13518					if (key == 8 && curLength === 0) {
13519						$el.prev("input").trigger("focus");
13520					}
13521					if (curLength == maxLength) {
13522						$el.next("input").trigger("focus");
13523					}
13524				});
13525
13526				var bankInputCheckboxSelector = "#payment-info .pay-method .bank-account input";
13527				var moneyOrderInputCheckboxSelector = "#payment-info .pay-method .money-order input";
13528				var identitySelector = "#identity-info .identity-type select";
13529				var responceOpenSchetInputCheckboxSelector = "#responce-open-schet .responce-open-schet-check input";
13530
13531				var $bankInputCheckbox = $(bankInputCheckboxSelector);
13532				var $moneyOrderInputCheckbox = $(moneyOrderInputCheckboxSelector);
13533
13534				$bankInputCheckbox.on("change", function () {
13535					if ($moneyOrderInputCheckbox.prop("checked")) {
13536						$moneyOrderInputCheckbox.prop("checked", !$bankInputCheckbox.prop("checked"));
13537					}
13538				});
13539
13540				$moneyOrderInputCheckbox.on("change",function () {
13541					if ($bankInputCheckbox.prop("checked")) {
13542						$bankInputCheckbox.prop("checked", !$moneyOrderInputCheckbox.prop("checked"));
13543					}
13544				});
13545
13546				var postInputCheckboxSelector = "#responce-open-schet .responce-open-schet-inputs .schet-post input";
13547				var registerInputCheckboxSelector = "#responce-open-schet .responce-open-schet-inputs .schet-register input";
13548				var pointInputCheckboxSelector = "#responce-open-schet .responce-open-schet-inputs .schet-point input";
13549				var $postInputCheckbox = $(postInputCheckboxSelector);
13550				var $registerInputCheckbox = $(registerInputCheckboxSelector);
13551				var $pointInputCheckbox = $(pointInputCheckboxSelector);
13552				$postInputCheckbox.on("change", function () {
13553					if ($registerInputCheckbox.prop("checked")) {
13554						$registerInputCheckbox.prop("checked", !$postInputCheckbox.prop("checked"));
13555					}
13556					if ($pointInputCheckbox.prop("checked")) {
13557						$pointInputCheckbox.prop("checked", !$postInputCheckbox.prop("checked"));
13558					}
13559				});
13560				$registerInputCheckbox.on("change", function () {
13561					if ($postInputCheckbox.prop("checked")) {
13562						$postInputCheckbox.prop("checked", !$registerInputCheckbox.prop("checked"));
13563					}
13564					if ($pointInputCheckbox.prop("checked")) {
13565						$pointInputCheckbox.prop("checked", !$registerInputCheckbox.prop("checked"));
13566					}
13567				});
13568				$pointInputCheckbox.on("change", function () {
13569					if ($postInputCheckbox.prop("checked")) {
13570						$postInputCheckbox.prop("checked", !$pointInputCheckbox.prop("checked"));
13571					}
13572					if ($registerInputCheckbox.prop("checked")) {
13573						$registerInputCheckbox.prop("checked", !$pointInputCheckbox.prop("checked"));
13574					}
13575				});
13576
13577				trainersVm.Form.Checks = [
13578					new Check({
13579						vm: trainersVm.Form,
13580						name: "09713320714649019532e0b2ab7d4ddc",
13581						regexp: /([A-z,А-я,\s,\'\-]+)/g,
13582						checkOnEdit: true,
13583						$elements: $("#name-block input"),
13584						regexpValidationError: "Неверно заполнено поле «Фамилия Имя Отчество». Допускаются только буквы, апостроф и тире.",
13585						mandatoryField: true,
13586						mandatoryFieldError: "Не заполнено обязательное поле «Фамилия Имя Отчество»."
13587					}),
13588					new Check({
13589						vm: trainersVm.Form,
13590						name: "2c575bd60e3a4aa8a5f976b28f42033e",
13591						regexp: /([A-z,А-я,\s,\'\-]+)/g,
13592						checkOnEdit: false,
13593						$elements: $("#personal-info .citizenship input"),
13594						regexpValidationError: "Неверно заполнено поле «Гражданство». Допускаются только буквы, апостроф и тире.",
13595						mandatoryField: true,
13596						mandatoryFieldError: "Не заполнено обязательное поле «Гражданство»."
13597					}),
13598					new Check({
13599						vm: trainersVm.Form,
13600						name: "3eb1a9dfead64daeabbdf18f169c731d",
13601						$elements: $("#personal-info .calendar"),
13602						mandatoryField: true,
13603						mandatoryFieldError: "Не заполнено обязательное поле «Дата рождения».",
13604						additionalValidation: function (val) {
13605							var date;
13606							var dateFormat = $("#personal-info .calendar").datepicker("option", "dateFormat");
13607							try {
13608								date = $.datepicker.parseDate(dateFormat, val);
13609							} catch (e) {
13610								return "Неверно заполнено поле «Дата рождения». Допускается только ввод даты.";
13611							}
13612							var today = new Date();
13613							today.setHours(0, 0, 0, 0);
13614							return date > today ? "Неверно заполнено поле «Дата рождения». Нельзя ввести дату, которая ещё не наступила." : undefined;
13615						}
13616					}),
13617					new Check({
13618						vm: trainersVm.Form,
13619						name: "905a4a4c81ab4512be187f6e4bb81b93",
13620						regexp: /(\d*)/g,
13621						checkOnEdit: true,
13622						$elements: $("#personal-info .inn input"),
13623						regexpValidationError: "Неверно заполнено поле «ИНН». Допускается ввод только цифр.",
13624						mandatoryField: false
13625					}),
13626					new Check({
13627						vm: trainersVm.Form,
13628						name: "1410757273df4d82b8b806bf16a9558e",
13629						regexp: /(\d{12})/g,
13630						checkOnEdit: true,
13631						$elements: $("#personal-info .inn input"),
13632						regexpValidationError: "Неверно заполнено поле «ИНН». Должны быть введены 12 цифр.",
13633						mandatoryField: false
13634					}),
13635					new Check({
13636						vm: trainersVm.Form,
13637						name: "b63cdd10a986431ba027d2358fc67785",
13638						regexp: /([A-z,А-я,\s,\'\-]+)/g,
13639						checkOnEdit: false,
13640						$elements: $("#personal-info .place-of-birth input"),
13641						regexpValidationError: "Неверно заполнено поле «Место рождения». Допускаются только буквы, апостроф и тире.",
13642						mandatoryField: true,
13643						mandatoryFieldError: "Не заполнено обязательное поле «Место рождения»."
13644					}),
13645					new Check({
13646						vm: trainersVm.Form,
13647						name: "7db1367931e8479aa83eef89324f6c93",
13648						$elements: $("#identity-info .identity-type select"),
13649						mandatoryField: true,
13650						mandatoryFieldError: "Не заполнено обязательное поле «Вид документа, удостоверяющего личность»."
13651					}),
13652					new Check({
13653						vm: trainersVm.Form,
13654						name: "6b4d841f175c43c1babc6ae13c861fbd",
13655						regexp: /(\d{4})/g,
13656						triggerElSelector: identitySelector,
13657						checkOnEdit: true,
13658						$elements: $("#identity-info .series input"),
13659						regexpValidationError: "Неверно заполнено поле «Серия». Допускается ввод только четырех цифр.",
13660						mandatoryField: true,
13661						mandatoryFieldError: "Не заполнено обязательное поле «серия».",
13662						regexpValidationPredicate: function (elSelector) {
13663							return $(elSelector).val() === "Паспорт гражданина РФ";
13664						},
13665						mandatoryValidationPredicate: function (elSelector) {
13666							return $(elSelector).val() === "Паспорт гражданина РФ";
13667						}
13668					}),
13669					new Check({
13670						vm: trainersVm.Form,
13671						name: "612f23de56624fb3b5a565d5f620175a",
13672						regexp: /(\d{6})/g,
13673						checkOnEdit: true,
13674						triggerElSelector: identitySelector,
13675						$elements: $("#identity-info .number input"),
13676						regexpValidationError: "Неверно заполнено поле «Номер». Допускается ввод только шести цифр.",
13677						mandatoryField: true,
13678						mandatoryFieldError: "Не заполнено обязательное поле «номер».",
13679						regexpValidationPredicate: function (elSelector) {
13680							return $(elSelector).val() === "Паспорт гражданина РФ";
13681						}
13682					}),
13683					new Check({
13684						vm: trainersVm.Form,
13685						name: "6029efa6bedc40a7a9ebcb9228f869c7",
13686						$elements: $("#identity-info .date-of-issue .calendar"),
13687						mandatoryField: true,
13688						mandatoryFieldError: "Не заполнено обязательное поле «Дата выдачи».",
13689						additionalValidation: function (val) {
13690							var date;
13691							var dateFormat = $("#identity-info .date-of-issue .calendar").datepicker("option", "dateFormat");
13692							try {
13693								date = $.datepicker.parseDate(dateFormat, val);
13694							} catch (e) {
13695								return "Неверно заполнено поле «Дата выдачи». Допускается только ввод даты.";
13696							}
13697							var today = new Date();
13698							today.setHours(0, 0, 0, 0);
13699							return date > today ? "Неверно заполнено поле «Дата выдачи». Нельзя ввести дату, которая ещё не наступила." : undefined;
13700						}
13701					}),
13702					new Check({
13703						vm: trainersVm.Form,
13704						name: "694078ca6fb34ee9aae58685a8aba4f4",
13705						$elements: $("#identity-info .authority input"),
13706						mandatoryField: true,
13707						mandatoryFieldError: "Не заполнено обязательное поле «Наименование выдавшего органа»."
13708					}),
13709					new Check({
13710						vm: trainersVm.Form,
13711						name: "8e3b2ef793a041848f1a6b3d3ad23552",
13712						$elements: $("#registration-address .index-input"),
13713						regexp: /(\d*)/g,
13714						checkOnEdit: true,
13715						regexpValidationError: "Неверно заполнено поле «Почтовый индекс адреса места регистрации». В поле должны быть только цифровые значения.",
13716						mandatoryField: true,
13717						mandatoryFieldError: "Не заполнено обязательное поле «Почтовый индекс адреса места регистрации»."
13718					}),
13719					new Check({
13720						vm: trainersVm.Form,
13721						name: "a6db993a9f624bfc8e4e42f8d6dd1fe2",
13722						$elements: $("#registration-address .country"),
13723						mandatoryField: true,
13724						mandatoryFieldError: "Не заполнено обязательное поле «Страна места регистрации»."
13725					}),
13726					new Check({
13727						vm: trainersVm.Form,
13728						name: "919aa32a8a4a445690c661d81526bada",
13729						$elements: $("#registration-address .region"),
13730						mandatoryField: true,
13731						mandatoryFieldError: "Не заполнено обязательное поле «Республика, край, область, район, населённый пункт места регистрации»."
13732					}),
13733					new Check({
13734						vm: trainersVm.Form,
13735						name: "556ffc5a952645ecad718a19204529a6",
13736						$elements: $("#registration-address .street"),
13737						mandatoryField: true,
13738						mandatoryFieldError: "Не заполнено обязательное поле «Микрорайон, улица места регистрации»."
13739					}),
13740					new Check({
13741						vm: trainersVm.Form,
13742						name: "72356f819e674ad1a4a4d4e05dc3e458",
13743						$elements: $("#registration-address .house"),
13744						mandatoryField: true,
13745						mandatoryFieldError: "Не заполнено обязательное поле «Дом, корпус, квартира места регистрации»."
13746					}),
13747					new Check({
13748						vm: trainersVm.Form,
13749						name: "fb546296a07e4aba9618d587748a9c94",
13750						$elements: $("#living-address .index-input"),
13751						regexp: /(\d*)/g,
13752						checkOnEdit: true,
13753						regexpValidationError: "Неверно заполнено поле «Почтовый индекс адреса места жительства». В поле должны быть только цифровые значения.",
13754						mandatoryField: true,
13755						mandatoryFieldError: "Не заполнено обязательное поле «Почтовый индекс адреса места жительства»."
13756					}),
13757					new Check({
13758						vm: trainersVm.Form,
13759						name: "f104f7a473754d7382481ac5df597417",
13760						$elements: $("#living-address .country"),
13761						mandatoryField: true,
13762						mandatoryFieldError: "Не заполнено обязательное поле «Страна места жительства»."
13763					}),
13764					new Check({
13765						vm: trainersVm.Form,
13766						name: "d6d32447882a4224b7fdb81e47df1689",
13767						$elements: $("#living-address .region"),
13768						mandatoryField: true,
13769						mandatoryFieldError: "Не заполнено обязательное поле «Республика, край, область, район, населённый пункт места жительства»."
13770					}),
13771					new Check({
13772						vm: trainersVm.Form,
13773						name: "19b36eb3f94a4f96b9bc9e139b1d9de3",
13774						$elements: $("#living-address .street"),
13775						mandatoryField: true,
13776						mandatoryFieldError: "Не заполнено обязательное поле «Микрорайон, улица места жительства»."
13777					}),
13778					new Check({
13779						vm: trainersVm.Form,
13780						name: "efa0ece2ba744841ac26027f1886399a",
13781						$elements: $("#living-address .house"),
13782						mandatoryField: true,
13783						mandatoryFieldError: "Не заполнено обязательное поле «Дом, корпус, квартира места жительства»."
13784					}),
13785					new Check({
13786						vm: trainersVm.Form,
13787						name: "21facd94f95544a5867d976da8fc59b8",
13788						regexp: /([^A-zА-я]+)/g,
13789						checkOnEdit: true,
13790						$elements: $("#phones-mail-info .phone"),
13791						regexpValidationError: "Неверно заполнено поле «Телефон». В поле не должно быть букв.",
13792						mandatoryField: false
13793					}),
13794					new Check({
13795						vm: trainersVm.Form,
13796						name: "162c001eddb44234939779f8aa229851",
13797						regexp: /([^A-zА-я]+)/g,
13798						checkOnEdit: true,
13799						$elements: $("#phones-mail-info .mobile-phone"),
13800						regexpValidationError: "Неверно заполнено поле «Мобильный телефон». В поле не должно быть букв.",
13801						mandatoryField: false
13802					}),
13803					new Check({
13804						vm: trainersVm.Form,
13805						name: "eb684745fbd8432485ce8897046b1145",
13806						regexp: /([^@]*@[^@]*)/g,
13807						checkOnEdit: true,
13808						$elements: $("#phones-mail-info .email"),
13809						regexpValidationError: "Неверно заполнено поле «e-mail». Не указан символ @.",
13810						mandatoryField: false
13811					}),
13812					new Check({
13813						vm: trainersVm.Form,
13814						name: "052815b278774019acd96e6a3240b4d3",
13815						$elements: $("#payment-info .pay-method input[type=checkbox]"),
13816						$invalidClassTarget: $("#payment-info .pay-method input[type=checkbox] + strong"),
13817						additionalOnEditValidation: function (val, $elements) {
13818							var checkedCount = 0;
13819							_.each($elements, function (item) {
13820								if ($(item).prop("checked")) {
13821									checkedCount++;
13822								}
13823							});
13824							return checkedCount > 1 ? "Неверно заполнено поле «Способ выплаты доходов по ценным бумагам». Не могут быть указаны одновременно значения «На банковский счет» и «Почтовым переводом»." : "";
13825						},
13826						additionalValidation: function (val, $elements) {
13827							var checkedCount = 0;
13828							_.each($elements, function (item) {
13829								if ($(item).prop("checked")) {
13830									checkedCount++;
13831								}
13832							});
13833							return !checkedCount ? "Обязательно должен быть выбран один из способов выплаты дохода." : "";
13834						}
13835					}),
13836					new Check({
13837						vm: trainersVm.Form,
13838						name: "704b665fd1f0456fab3a5b88d9fe3d91",
13839						$elements: $("#payment-info .bank-name input"),
13840						triggerElSelector: bankInputCheckboxSelector,
13841						mandatoryField: true,
13842						mandatoryFieldError: "Не заполнено обязательное поле «Банк получателя».",
13843						mandatoryValidationPredicate: function (elSelector) {
13844							return $(elSelector).prop("checked");
13845						}
13846					}),
13847					new Check({
13848						vm: trainersVm.Form,
13849						name: "a773ea6621384bec9fd68d4cf3a792a9",
13850						$elements: $("#payment-info .bank-bik .bik-inputs input"),
13851						triggerElSelector: bankInputCheckboxSelector,
13852						regexp: /(\d*)/g,
13853						checkOnEdit: true,
13854						mandatoryField: false,
13855						regexpValidationError: "Неверно заполнено поле «БИК банка». Допускается ввод только цифр.",
13856						regexpValidationPredicate: function (elSelector) {
13857							return $(elSelector).prop("checked");
13858						}
13859					}),
13860					new Check({
13861						vm: trainersVm.Form,
13862						name: "18e03800ca3348ffbbaba4f3cf09fa49",
13863						$elements: $("#payment-info .bank-bik .bik-inputs input"),
13864						triggerElSelector: bankInputCheckboxSelector,
13865						regexp: /(\d{9})/g,
13866						checkOnEdit: true,
13867						mandatoryField: true,
13868						mandatoryFieldError: "Не заполнено обязательное поле «БИК банка».",
13869						regexpValidationError: "Неверно заполнено поле «БИК банка». Должны быть введены 9 цифр.",
13870						regexpValidationPredicate: function (elSelector) {
13871							return $(elSelector).prop("checked");
13872						},
13873						mandatoryValidationPredicate: function (elSelector) {
13874							return $(elSelector).prop("checked");
13875						}
13876					}),
13877					new Check({
13878						vm: trainersVm.Form,
13879						name: "eea1c29fb4fe4d878c82b452ade9d239",
13880						$elements: $("#payment-info .bank-ca input"),
13881						mandatoryField: false,
13882						triggerElSelector: bankInputCheckboxSelector,
13883						checkOnEdit: true,
13884						regexp: /(\d*)/g,
13885						regexpValidationError: "Неверно заполнено поле «Р/счет банка». Допускается ввод только цифр.",
13886						regexpValidationPredicate: function (elSelector) {
13887							return $(elSelector).prop("checked");
13888						},
13889					}),
13890					new Check({
13891						vm: trainersVm.Form,
13892						name: "eb60a112934d47b983eedf0ded7c9644",
13893						$elements: $("#payment-info .bank-ca input"),
13894						mandatoryField: false,
13895						triggerElSelector: bankInputCheckboxSelector,
13896						checkOnEdit: true,
13897						regexp: /(\d{20})/g,
13898						regexpValidationError: "Неверно заполнено поле «Р/счет банка». Должны быть введены 20 цифр.",
13899						regexpValidationPredicate: function (elSelector) {
13900							return $(elSelector).prop("checked");
13901						},
13902						additionalOnEditValidation: function (val) {
13903							if ($(bankInputCheckboxSelector).prop("checked")) {
13904								var bik = "";
13905								_.each($("#payment-info .bank-bik .bik-inputs input").toArray(), function (item) {
13906									bik += $(item).val();
13907								});
13908
13909								var ka = "";
13910								_.each($("#payment-info .bank-ka input").toArray(), function (item) {
13911									ka += $(item).val();
13912								});
13913
13914								if (bik && bik.length == 9) {
13915									var bikEnd = bik.slice(-3);
13916									var kaEnd = ka.slice(-3);
13917									var ca = val.slice(-3);
13918
13919									return bikEnd === ca && kaEnd === ca ? "" : "Неверно заполнено поле «Р/счет банка». Последние 3 цифры должны совпадать с последними 3 цифрами в полях «БИК банка» и «Корр. Счет банка».";
13920								}
13921							}
13922						}
13923					}),
13924					new Check({
13925						vm: trainersVm.Form,
13926						name: "6167772d56c649d5bfbbef25d04f8cee",
13927						$elements: $("#payment-info .bank-inn .bank-inn-inputs input"),
13928						mandatoryField: false,
13929						triggerElSelector: bankInputCheckboxSelector,
13930						regexp: /(\d*)/g,
13931						regexpValidationError: "Неверно заполнено поле «ИНН банка». Допускается ввод только цифр.",
13932						regexpValidationPredicate: function (elSelector) {
13933							return $(elSelector).prop("checked");
13934						},
13935					}),
13936					new Check({
13937						vm: trainersVm.Form,
13938						name: "ffa63aee191a4b26bbbb66c520ab71bd",
13939						$elements: $("#payment-info .bank-inn .bank-inn-inputs input"),
13940						mandatoryField: true,
13941						triggerElSelector: bankInputCheckboxSelector,
13942						regexp: /(\d{10})/g,
13943						regexpValidationError: "Неверно заполнено поле «ИНН банка». Должны быть введены 10 цифр.",
13944						mandatoryFieldError: "Не заполнено обязательное поле «ИНН банка».",
13945						regexpValidationPredicate: function (elSelector) {
13946							return $(elSelector).prop("checked");
13947						},
13948						mandatoryValidationPredicate: function (elSelector) {
13949							return $(elSelector).prop("checked");
13950						}
13951					}),
13952					new Check({
13953						vm: trainersVm.Form,
13954						name: "7ad661a0fb3c43668a21dd38608dcd36",
13955						$elements: $("#payment-info .bank-inn .bank-kpp-inputs input"),
13956						mandatoryField: false,
13957						triggerElSelector: bankInputCheckboxSelector,
13958						regexp: /(\d*)/g,
13959						regexpValidationError: "Неверно заполнено поле «КПП банка». Допускается ввод только цифр.",
13960						regexpValidationPredicate: function (elSelector) {
13961							return $(elSelector).prop("checked");
13962						}
13963					}),
13964					new Check({
13965						vm: trainersVm.Form,
13966						name: "c4d1907e840c4b63925fe2696d9c7c69",
13967						$elements: $("#payment-info .bank-inn .bank-kpp-inputs input"),
13968						mandatoryField: true,
13969						triggerElSelector: bankInputCheckboxSelector,
13970						regexp: /(\d{9})/g,
13971						regexpValidationError: "Неверно заполнено поле «КПП банка». Должны быть введены 9 цифр.",
13972						mandatoryFieldError: "Не заполнено обязательное поле «КПП банка».",
13973						regexpValidationPredicate: function (elSelector) {
13974							return $(elSelector).prop("checked");
13975						},
13976						mandatoryValidationPredicate: function (elSelector) {
13977							return $(elSelector).prop("checked");
13978						}
13979					}),
13980					new Check({
13981						vm: trainersVm.Form,
13982						name: "49ba0258413847f98ff1b329a8b1cfa3",
13983						$elements: $("#payment-info .bank-ka input"),
13984						mandatoryField: false,
13985						triggerElSelector: bankInputCheckboxSelector,
13986						checkOnEdit: true,
13987						regexp: /(\d*)/g,
13988						regexpValidationError: "Неверно заполнено поле «Корр. Счет банка». Допускается ввод только цифр.",
13989						mandatoryFieldError: "Не заполнено обязательное поле «Корр. Счет».",
13990						regexpValidationPredicate: function (elSelector) {
13991							return $(elSelector).prop("checked");
13992						}
13993					}),
13994					new Check({
13995						vm: trainersVm.Form,
13996						name: "bb4ebc46399c4f44824c7380e38d7650",
13997						$elements: $("#payment-info .bank-ka input"),
13998						mandatoryField: true,
13999						triggerElSelector: bankInputCheckboxSelector,
14000						checkOnEdit: true,
14001						regexp: /(\d{20})/g,
14002						regexpValidationError: "Неверно заполнено поле «Корр. Счет банка». Должны быть введены 20 цифр.",
14003						mandatoryFieldError: "Не заполнено обязательное поле «Корр. Счет банка».",
14004						regexpValidationPredicate: function (elSelector) {
14005							return $(elSelector).prop("checked");
14006						},
14007						mandatoryValidationPredicate: function (elSelector) {
14008							return $(elSelector).prop("checked");
14009						},
14010						additionalOnEditValidation: function(val) {
14011							if ($(bankInputCheckboxSelector).prop("checked")) {
14012								var bik = "";
14013								_.each($("#payment-info .bank-bik .bik-inputs input").toArray(), function (item) {
14014									bik += $(item).val();
14015								});
14016
14017								if (bik && bik.length == 9) {
14018									var bikEnd = bik.slice(-3);
14019									var ka = val.slice(-3);
14020
14021									return bikEnd === ka ? "" : "Неверно заполнено поле «Корр. Счет банка». Последние 3 цифры должны совпадать с последними 3 цифрами в поле «БИК банка».";
14022								}
14023							}
14024						}
14025					}),
14026					new Check({
14027						vm: trainersVm.Form,
14028						name: "aa729f028dfe46dcbb3e429d8648a3f3",
14029						$elements: $("#payment-info .recipient-ca input"),
14030						mandatoryField: false,
14031						triggerElSelector: bankInputCheckboxSelector,
14032						checkOnEdit: true,
14033						regexp: /(\d*)/g,
14034						regexpValidationError: "Неверно заполнено поле «Л/счет получателя». Допускается ввод только цифр.",
14035						regexpValidationPredicate: function (elSelector) {
14036							return $(elSelector).prop("checked");
14037						}
14038					}),
14039					new Check({
14040						vm: trainersVm.Form,
14041						name: "2f3206b2566d4b32817ffa21cf46ff25",
14042						$elements: $("#payment-info .recipient-ca input"),
14043						mandatoryField: true,
14044						triggerElSelector: bankInputCheckboxSelector,
14045						checkOnEdit: true,
14046						regexp: /(\d{20,})/g,
14047						regexpValidationError: "Неверно заполнено поле «Л/счет получателя». Должны быть введены 20 цифр.",
14048						mandatoryFieldError: "Не заполнено обязательное поле «Л/счет получателя».",
14049						regexpValidationPredicate: function (elSelector) {
14050							return $(elSelector).prop("checked");
14051						},
14052						mandatoryValidationPredicate: function (elSelector) {
14053							return $(elSelector).prop("checked");
14054						}
14055					}),
14056
14057					new Check({
14058						vm: trainersVm.Form,
14059						name: "f06f1490aa4a472780832345e681d497",
14060						$elements: $("#payment-info .bank-username input"),
14061						triggerElSelector: bankInputCheckboxSelector,
14062						mandatoryField: true,
14063						mandatoryFieldError: "Не заполнено обязательное поле «Наименование получателя».",
14064						mandatoryValidationPredicate: function (elSelector) {
14065							return $(elSelector).prop("checked");
14066						}
14067					}),
14068					new Check({
14069						vm: trainersVm.Form,
14070						name: "9167022fbc374715a170c126ed865728",
14071						$elements: $("#payment-info .bank-userinn .bank-userinn-inputs input"),
14072						triggerElSelector: bankInputCheckboxSelector,
14073						regexp: /(\d*)/g,
14074						checkOnEdit: true,
14075						mandatoryField: false,
14076						regexpValidationError: "Неверно заполнено поле «ИНН получателя». Допускается ввод только цифр.",
14077						regexpValidationPredicate: function (elSelector) {
14078							return $(elSelector).prop("checked");
14079						}
14080					}),
14081					new Check({
14082						vm: trainersVm.Form,
14083						name: "2194b1be98304004bb3745e336f87c08",
14084						$elements: $("#payment-info .bank-userinn .bank-userinn-inputs input"),
14085						triggerElSelector: bankInputCheckboxSelector,
14086						regexp: /(\d{12})/g,
14087						checkOnEdit: true,
14088						mandatoryField: true,
14089						mandatoryFieldError: "Не заполнено обязательное поле «ИНН получателя».",
14090						regexpValidationError: "Неверно заполнено поле «ИНН получателя». Должны быть введены 12 цифр.",
14091						regexpValidationPredicate: function (elSelector) {
14092							return $(elSelector).prop("checked");
14093						},
14094						mandatoryValidationPredicate: function (elSelector) {
14095							return $(elSelector).prop("checked");
14096						}
14097					}),
14098
14099					new Check({
14100						vm: trainersVm.Form,
14101						name: "21f6e6cc326a4cbba31a9ed24bab8626",
14102						$elements: $("#responce-open-schet .responce-open-schet-inputs input[type=checkbox]"),
14103						$invalidClassTarget: $("#responce-open-schet .responce-open-schet-inputs input[type=checkbox] + span"),
14104						//triggerElSelector: responceOpenSchetInputCheckboxSelector,
14105						//mandatoryFieldError: "Обязательно должен быть выбран один из способов получения уведомления.",
14106						additionalOnEditValidation: function (val, $elements) {
14107							if (!$(responceOpenSchetInputCheckboxSelector).prop("checked")) {
14108								return "";
14109							}
14110							var checkedCount = 0;
14111							_.each($elements, function (item) {
14112								if ($(item).prop("checked")) {
14113									checkedCount++;
14114								}
14115							});
14116							return checkedCount > 1 ? "Неверно заполнено поле «Способ получения уведомления». Допускается один способ получения уведомления." : "";
14117						},
14118						additionalValidation: function (val, $elements) {
14119							if (!$(responceOpenSchetInputCheckboxSelector).prop("checked")) {
14120								return "";
14121							}
14122							var checkedCount = 0;
14123							_.each($elements, function (item) {
14124								if ($(item).prop("checked")) {
14125									checkedCount++;
14126								}
14127							});
14128							return !checkedCount ? "Обязательно должен быть выбран один из способов получения уведомления." : "";
14129						}//,
14130						//mandatoryValidationPredicate: function (elSelector) {
14131						//	return $(elSelector).prop("checked");
14132						//}
14133					})
14134				];
14135
14136				registerTrigger(bankInputCheckboxSelector, trainersVm.Form.Checks);
14137				registerTrigger(identitySelector, trainersVm.Form.Checks);
14138			}
14139			if ($("#continuation-of-individual-shareholder-form").length) {
14140
14141				var identitySelectSelector = "#continuation-of-individual-shareholder-form .identity-block .identity-type select";
14142				var representativeTypeSelector = "#continuation-of-individual-shareholder-form .representative-block input[type=checkbox]";
14143
14144				trainersVm.Countinuation.Checks = [
14145					new Check({
14146						vm: trainersVm.Countinuation,
14147						name: "6371a6ab202549119e513612fe00e645",
14148						$elements: $("#continuation-of-individual-shareholder-form .name-block input"),
14149						mandatoryField: true,
14150						checkOnEdit: true,
14151						regexp: /([A-z,А-я,\s,\'\-]+)/g,
14152						mandatoryFieldError: "Не заполнено обязательное поле «Фамилия Имя Отчество».",
14153						regexpValidationError: "Неверно заполнено поле «Фамилия Имя Отчество». Допускаются только буквы, апостроф и тире."
14154					}),
14155					new Check({
14156						vm: trainersVm.Countinuation,
14157						name: "1704cccb447340aba0cc956162684df4",
14158						$elements: $("#continuation-of-individual-shareholder-form .representative-name"),
14159						mandatoryField: true,
14160						checkOnEdit: true,
14161						regexp: /([A-z,А-я,\s,\'\-]+)/g,
14162						mandatoryFieldError: "Не заполнено обязательное поле «Фамилия Имя Отчество».",
14163						regexpValidationError: "Неверно заполнено поле «Фамилия Имя Отчество». Допускаются только буквы, апостроф и тире."
14164					}),
14165					new Check({
14166						vm: trainersVm.Countinuation,
14167						name: "63e77f61075946d9a68b646100107afc",
14168						$elements: $("#continuation-of-individual-shareholder-form .identity-block .identity-type select"),
14169						mandatoryField: true,
14170						mandatoryFieldError: "Не заполнено обязательное поле «Вид документа, удостоверяющего личность»."
14171					}),
14172					new Check({
14173						vm: trainersVm.Countinuation,
14174						name: "10b6b92b8ff24ddcafb5c9e3408b8d56",
14175						regexp: /(\d{4})/g,
14176						checkOnEdit: true,
14177						triggerElSelector: identitySelectSelector,
14178						$elements: $("#continuation-of-individual-shareholder-form .identity-block .series input"),
14179						regexpValidationError: "Неверно заполнено поле «Серия». Допускается ввод только четырёх цифр.",
14180						mandatoryField: true,
14181						mandatoryFieldError: "Не заполнено обязательное поле «Серия».",
14182						regexpValidationPredicate: function (elSelector) {
14183							return $(elSelector).val() === "Паспорт гражданина РФ";
14184						},
14185						mandatoryValidationPredicate: function (elSelector) {
14186							return $(elSelector).val() === "Паспорт гражданина РФ";
14187						}
14188					}),
14189					new Check({
14190						vm: trainersVm.Countinuation,
14191						name: "2a6e03027bfe47efa07957a4e6aa01e8",
14192						regexp: /(\d{6})/g,
14193						checkOnEdit: true,
14194						triggerElSelector: identitySelectSelector,
14195						$elements: $("#continuation-of-individual-shareholder-form .identity-block .number input"),
14196						regexpValidationError: "Неверно заполнено поле «Номер». Допускается ввод только шести цифр.",
14197						mandatoryField: true,
14198						mandatoryFieldError: "Не заполнено обязательное поле «Номер».",
14199						regexpValidationPredicate: function (elSelector) {
14200							return $(elSelector).val() === "Паспорт гражданина РФ";
14201						}
14202					}),
14203					new Check({
14204						vm: trainersVm.Countinuation,
14205						name: "168a0aec24544d74aabcf7364daab409",
14206						$elements: $("#continuation-of-individual-shareholder-form .identity-block .date-of-issue .calendar"),
14207						mandatoryField: true,
14208						checkOnEdit: true,
14209						mandatoryFieldError: "Не заполнено обязательное поле «Дата выдачи».",
14210						additionalOnEditValidation: function (val) {
14211							var date;
14212							var dateFormat = $("#continuation-of-individual-shareholder
14212-form .identity-block .date-of-issue .calendar").datepicker("option", "dateFormat");
14213							try {
14214								date = $.datepicker.parseDate(dateFormat, val);
14215							} catch (e) {
14216								return "Неверно заполнено поле «Дата выдачи». Допускается только ввод даты.";
14217							}
14218							var today = new Date();
14219							today.setHours(0, 0, 0, 0);
14220							return date > today ? "Неверно заполнено поле «Дата выдачи». Нельзя ввести дату, которая ещё не наступила." : undefined;
14221						}
14222					}),
14223					new Check({
14224						vm: trainersVm.Countinuation,
14225						name: "b3728c4e19b646c286dc5fca963bd0dc",
14226						checkOnEdit: true,
14227						$elements: $("#continuation-of-individual-shareholder-form .representative-block .guardian, #continuation-of-individual-shareholder-form .representative-block .trustee"),
14228						$invalidClassTarget: $("#continuation-of-individual-shareholder-form .representative-block .guardian + strong, #continuation-of-individual-shareholder-form .representative-block .trustee + strong"),
14229						additionalOnEditValidation: function (val, $elements) {
14230							var checkedCount = 0;
14231							_.each($elements, function (item) {
14232								if ($(item).prop("checked")) {
14233									checkedCount++;
14234								}
14235							});
14236							return checkedCount > 1 ? "Неверно заполнено поле «Законный представитель физического лица». Отметки «опекун» и «попечитель» не могут быть установлены одновременно." : "";
14237						}
14238					}),
14239					new Check({
14240						vm: trainersVm.Countinuation,
14241						name: "beeef0f8eac54923869451d7a5d4bb16",
14242						$elements: $("#continuation-of-individual-shareholder-form .identity-block .authority input"),
14243						mandatoryField: true,
14244						mandatoryFieldError: "Не заполнено обязательное поле «Наименование выдавшего органа»."
14245					}),
14246					new Check({
14247						vm: trainersVm.Countinuation,
14248						name: "4e6231c116a948eebad8d31df247dac4",
14249						triggerElSelector: representativeTypeSelector,
14250						$elements: $("#continuation-of-individual-shareholder-form .act-on-the-appointment .identity-type input"),
14251						mandatoryField: true,
14252						mandatoryFieldError: "Не заполнено обязательное поле «Вид документа о назначении опекуна или попечителя».",
14253						mandatoryValidationPredicate: function (elSelector) {
14254							return _.some($(elSelector), function (checkbox) {
14255								return $(checkbox).is(":checked");
14256							});
14257						}
14258					}),
14259					new Check({
14260						vm: trainersVm.Countinuation,
14261						name: "4915790e797d492796fe965b0accf091",
14262						$elements: $("#continuation-of-individual-shareholder-form .act-on-the-appointment .date-of-issue .calendar"),
14263						mandatoryField: true,
14264						checkOnEdit: true,
14265						triggerElSelector: representativeTypeSelector,
14266						mandatoryFieldError: "Не заполнено обязательное поле «Дата выдачи документа о назначении опекуна или попечителя».",
14267						additionalOnEditValidation: function (val) {
14268							if (_.some($(representativeTypeSelector), function (checkbox) {
14269								return $(checkbox).is(":checked");
14270							})) {
14271								var date;
14272								var dateFormat = $("#continuation-of-individual-shareholder-form .act-on-the-appointment .date-of-issue .calendar").datepicker("option", "dateFormat");
14273								try {
14274									date = $.datepicker.parseDate(dateFormat, val);
14275								} catch (e) {
14276									return "Неверно заполнено поле «Дата выдачи документа о назначении опекуна или попечителя». Допускается только ввод даты.";
14277								}
14278								var today = new Date();
14279								today.setHours(0, 0, 0, 0);
14280								return date > today ? "Неверно заполнено поле «Дата выдачи документа о назначении опекуна или попечителя». Нельзя ввести дату, которая ещё не наступила." : undefined;
14281							}
14282						},
14283						regexpValidationPredicate: function (elSelector) {
14284							return _.some($(elSelector), function (checkbox) {
14285								return $(checkbox).is(":checked");
14286							});
14287						},
14288						mandatoryValidationPredicate: function (elSelector) {
14289							return _.some($(elSelector), function (checkbox) {
14290								return $(checkbox).is(":checked");
14291							});
14292						}
14293					}),
14294					new Check({
14295						vm: trainersVm.Countinuation,
14296						name: "6ef4a0c82de842e99df716c9f1e20a07",
14297						triggerElSelector: representativeTypeSelector,
14298						$elements: $("#continuation-of-individual-shareholder-form .act-on-the-appointment .authority input"),
14299						mandatoryField: true,
14300						mandatoryFieldError: "Не заполнено обязательное поле «Наименование органа, выдавшего документ о назначении опекуна или попечителя».",
14301						mandatoryValidationPredicate: function (elSelector) {
14302							return _.some($(elSelector), function(checkbox) {
14303								return $(checkbox).is(":checked");
14304							});
14305						}
14306					})
14307				];
14308
14309				registerTrigger(identitySelectSelector, trainersVm.Countinuation.Checks);
14310				registerTrigger(representativeTypeSelector, trainersVm.Countinuation.Checks);
14311			}
14312		} else if ($votingPaperFormWidget) {
14313			trainersVm = new TrainersViewModel();
14314			trainersVm.SelectedForm(trainersVm.StandardVoting);
14315			ko.applyBindings(trainersVm, $votingPaperFormWidget[0]);
14316
14317			$(".trainer-popup .button, .change-form-button").on("click", function () {
14318				var form = this.getAttribute("data-form");
14319				if (form === "cumulative") {
14320					trainersVm.SelectedForm(trainersVm.CumulativeVoting);
14321				} else {
14322					trainersVm.SelectedForm(trainersVm.StandardVoting);
14323				}
14324				parent.$.fancybox.close();
14325			});
14326
14327			var today = new Date();
14328			var dd = today.getDate();
14329			var mm = today.getMonth() + 1;
14330			var yyyy = today.getFullYear();
14331
14332			if (dd < 10) {
14333				dd = "0" + dd;
14334			}
14335
14336			if (mm < 10) {
14337				mm = "0" + mm;
14338			}
14339
14340			today = dd + "/" + mm + "/" + yyyy;
14341
14342			if ($("#standard-voting-paper").length) {
14343				$("#standard-voting-paper .main-info .date").text(today);
14344
14345				var questions = [
14346					"Утверждение годового отчета, годовой бухгалтерской отчетности, в том числе отчетов о при-былях и об убытках (счетов прибылей и убытков) Компании, а также распределение прибыли (в том числе выплата (объявление) дивидендов и убытков по результатам финансового года. Определение размера, срока, формы и порядка выплаты дивидендов",
14347					"Утверждение Устава ПАО «ЛУКОЙЛ» в новой редакции",
14348					"О вознаграждении и компенсации расходов членам Совета директоров ПАО «ЛУКОЙЛ",
14349					"Утверждение Аудитора ПАО «ЛУКОЙЛ"
14350				];
14351				$("#standard-voting-paper .question-text").text(_.sample(questions));
14352
14353				$("#standard-voting-paper .vote-table .vote-input").on("click", function () {
14354					var $el = $(this);
14355					if ($el.val() !== "100") {
14356						var $all = $("#standard-voting-paper .vote-table .vote-input");
14357						_.each($all, function (item) {
14358							$(item).val("");
14359						});
14360						$el.val("100");
14361					}
14362				});
14363
14364
14365				$("#standard-voting-paper .sign-block .sign-btn").on("click", function () {
14366					$(this).replaceWith("<img src='/content/img/sign-example.png'></img>");
14367				});
14368
14369				trainersVm.StandardVoting.Checks = [
14370					new Check({
14371						vm: trainersVm.StandardVoting,
14372						name: "55a090af58c543d59827b3ddaf517daf",
14373						$elements: $("#standard-voting-paper .main-info input"),
14374						regexp: /([A-z,А-я,\s,\'\-]+)/g,
14375						checkOnEdit: true,
14376						regexpValidationError: "Неверно заполнено поле «Фамилия Имя Отчество». Допускаются только буквы, апостроф и тире.",
14377						mandatoryField: true,
14378						mandatoryFieldError: "Не заполнено обязательное поле «Фамилия, имя, отчество (наименование) акционера»."
14379					}),
14380					new Check({
14381						vm: trainersVm.StandardVoting,
14382						name: "fb1d1a6b93f24583987306c531a47ea9",
14383						$elements: $("#standard-voting-paper .vote-table .vote-input"),
14384						additionalValidation: function (val) {
14385							var error = "Не заполнено обязательное поле «ЗА, ПРОТИВ, ВОЗДЕРЖАЛСЯ».";
14386							var result = "";
14387							var lastVal;
14388							_.each($("#standard-voting-paper .vote-table .vote-input"), function (item) {
14389								var val = $(item).val();
14390								if (lastVal && val) {
14391									result = error;
14392									return false;
14393								}
14394								lastVal = val ? val : lastVal;
14395							});
14396							if (!result && lastVal !== "100") {
14397								result = error;
14398							}
14399							return result;
14400						}
14401					}),
14402					new Check({
14403						vm: trainersVm.StandardVoting,
14404						name: "46b03e1622884d20b4d4008803c58e48",
14405						$elements: $("#standard-voting-paper .sign-block .sign-btn"),
14406						additionalValidation: function (val) {
14407							var error = "Не подписан бюллетень.";
14408							return $("#standard-voting-paper .sign-block .sign-btn").length ? error : "";
14409						}
14410					}),
14411					new Check({
14412						vm: trainersVm.StandardVoting,
14413						name: "d446444f11e24c5594160e17b79b7205",
14414						$elements: $("#standard-voting-paper .proxy-voting input"),
14415						mandatoryField: true,
14416						mandatoryFieldError: "Не заполнено обязательное поле «Отметка о голосовании по доверенности».",
14417						mandatoryValidationPredicate: function () {
14418							return $votingPaperFormWidget.find("#confidant-person").prop("checked");
14419						}
14420					})
14421				];
14422			}
14423			if ($("#cumulative-voting-paper").length) {
14424				$("#cumulative-voting-paper .main-info .date").text(today);
14425
14426				$("#cumulative-voting-paper .vote-table").on("keyup", "input", function () {
14427					var key = event.keyCode || event.charCode;
14428					var $el = $(this);
14429					var curLength = $el.val().length;
14430					var maxLength = $el.attr("maxlength");
14431					if (key == 8 && curLength === 0) {
14432						$el.parent().prev().find("input").trigger("focus");
14433					}
14434					if (curLength == maxLength) {
14435						$el.parent().next().find("input").trigger("focus");
14436					}
14437				});
14438
14439				$("#cumulative-voting-paper .sign-block .sign-btn").on("click", function () {
14440					$(this).replaceWith("<img src='/content/img/sign-example.png'></img>");
14441				});
14442
14443				$("#cumulative-voting-paper .against-table input, #cumulative-voting-paper .vote-table input").keydown(function (e) {
14444					// Allow: backspace, delete, tab, escape, enter and .
14445					if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 ||
14446						// Allow: Ctrl+A
14447						(e.keyCode == 65 && e.ctrlKey === true) ||
14448						// Allow: Ctrl+C
14449						(e.keyCode == 67 && e.ctrlKey === true) ||
14450						// Allow: Ctrl+X
14451						(e.keyCode == 88 && e.ctrlKey === true) ||
14452						// Allow: home, end, left, right
14453						(e.keyCode >= 35 && e.keyCode <= 39)) {
14454						// let it happen, don't do anything
14455						return;
14456					}
14457					// Ensure that it is a number and stop the keypress
14458					if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
14459						e.preventDefault();
14460					}
14461				});
14462
14463				trainersVm.CumulativeVoting.Checks = [
14464					new Check({
14465						vm: trainersVm.CumulativeVoting,
14466						name: "e0af1a00b4924246a40a7cd51d78ef0e",
14467						$elements: $("#cumulative-voting-paper .vote-table input, #cumulative-voting-paper .against-table input"),
14468						additionalValidation: function (val) {
14469							var result = "";
14470							var error = "Некорректно введена информация о голосовании.";
14471							var votes = 0;
14472							$("#cumulative-voting-paper .vote-table tr").each(function () {
14473								var $inputs = $(this).find("td.vote-input-cell input");
14474								if ($inputs.length) {
14475									var number = "";
14476									_.each($inputs, function (input) {
14477										var val = $(input).val() || "-";
14478										number += val;
14479									});
14480									number = number.replace(new RegExp(/(-+$)/g), "");
14481									var matches = new RegExp(/(\d+)/g).exec(number);
14482									if (number === "") {
14483										return true;
14484									} else if (matches && matches[0] === number) {
14485										votes += parseInt(number);
14486										return true;
14487									} else {
14488										result = error;
14489										return false;
14490									}
14491								}
14492								return true;
14493							});
14494
14495							var againstVal = $("#cumulative-voting-paper .against-table .against-input").val().trim();
14496							var abstentionVal = $("#cumulative-voting-paper .against-table .abstention-input").val().trim();
14497							var maxVotes = 1100;
14498							if (!result && votes === 0) {
14499								var againstVotes = null;
14500								var abstentionVotes = null;
14501								var matches = new RegExp(/(\d+)/g).exec(againstVal);
14502								if (matches && matches[0] === againstVal) {
14503									againstVotes = parseInt(againstVal);
14504								}
14505								matches = new RegExp(/(\d+)/g).exec(abstentionVal);
14506								if (matches && matches[0] === abstentionVal) {
14507									abstentionVotes = parseInt(abstentionVal);
14508								}
14509								if ((againstVotes === maxVotes && !abstentionVotes) || (abstentionVotes === maxVotes && !againstVotes)) {
14510									votes = maxVotes;
14511								} else {
14512									result = "Некорректно введена информация о голосовании.";
14513								}
14514							} else if (!result && votes !== 0) {
14515								result = !againstVal && !abstentionVal ? "" : error;
14516							}
14517
14518							result = !result && votes !== maxVotes ? error : result;
14519
14520							return result;
14521						}
14522					}),
14523					new Check({
14524						vm: trainersVm.CumulativeVoting,
14525						name: "3b1eaf558f674688821dde3b98796372",
14526						$elements: $("#cumulative-voting-paper .sign-block .sign-btn"),
14527						additionalValidation: function (val) {
14528							var error = "Не подписан бюллетень.";
14529							return $("#cumulative-voting-paper .sign-block .sign-btn").length ? error : "";
14530						}
14531					}),
14532					new Check({
14533						vm: trainersVm.CumulativeVoting,
14534						name: "17923f06509f4d85b91717b641c1947e",
14535						$elements: $("#cumulative-voting-paper .main-info input"),
14536						regexp: /([A-z,А-я,\s,\'\-]+)/g,
14537						checkOnEdit: true,
14538						regexpValidationError: "Неверно заполнено поле «Фамилия Имя Отчество». Допускаются только буквы, апостроф и тире.",
14539						mandatoryField: true,
14540						mandatoryFieldError: "Не заполнено обязательное поле «Фамилия, имя, отчество (наименование) акционера»."
14541					}),
14542					new Check({
14543						vm: trainersVm.CumulativeVoting,
14544						name: "5f310ec6da5c413dbcaa2f99e5c07b9b",
14545						$elements: $("#cumulative-voting-paper .proxy-voting input"),
14546						mandatoryField: true,
14547						mandatoryFieldError: "Не заполнено обязательное поле «Отметка о голосовании по доверенности».",
14548						mandatoryValidationPredicate: function () {
14549							return $votingPaperFormWidget.find("#confidant-person").prop("checked");
14550						}
14551					})
14552				];
14553			}
14554		}
14555	};
14556
14557	Trainers.run = function() {
14558		prepareTrainers();
14559	};
14560});;
14561LukoilApp.module("Subscription", function (Subscription, LukoilApp, Backbone, Marionette, $, _) {
14562	"use strict";
14563
14564	var settings = {
14565		newsSubscriptionWidgetSelector: ".panel-forms_news-feeds",
14566		eventReminderWidgetSelector: ".event-reminder-widget",
14567		eventReminderEventDropdownSelector: ".select-custom",
14568		eventReminderConfirmCheckboxSelector: ".checkbox-custom",
14569		apiRssUrl: "/api/subscription/rss",
14570		themeSelector: ".theme-select",
14571		languageSelector: ".language-select"
14572	};
14573
14574	Subscription.on("start", function (options) {
14575		Subscription.run();
14576	});
14577
14578	var clearUrlQuery = function() {
14579		if (window.history && window.history.pushState) {
14580			window.history.replaceState(null, "", location.protocol + "//" + location.host + location.pathname);
14581		} else {
14582			window.location.href = location.protocol + "//" + location.host + location.pathname + "#";
14583		}
14584	};
14585
14586	var NewsSubscriptionViewModel = function($element) {
14587		var self = this;
14588
14589		self.GetPressReleases = ko.observable($element.find("input[name=GetPressReleases]").prop("checked"));
14590		self.GetPressReleasesPDF = ko.observable($element.find("input[name=GetPressReleasesPDF]").prop("checked"));
14591		self.GetMediaMaterials = ko.observable($element.find("input[name=GetMediaMaterials]").prop("checked"));
14592		self.GetEvents = ko.observable($element.find("input[name=GetEvents]").prop("checked"));
14593		self.GetRegionNews = ko.observable($element.find("input[name=GetRegionNews]").prop("checked"));
14594		self.GetTenders = ko.observable($element.find("input[name=GetTenders]").prop("checked"));
14595		self.GetSubsidiaryTenderNews = ko.observable($element.find("input[name=GetSubsidiaryTender]").prop("checked"));
14596		self.GetVacancies = ko.observable($element.find("input[name=GetVacancies]").prop("checked"));
14597		self.Confirmed = ko.observable($element.find("input[name=Confirmed]").prop("checked"));
14598		self.ConfirmCancel = ko.observable($element.find("input[name=ConfirmCancel]").prop("checked"));
14599
14600		$element.find('.collapse').on('show.bs.collapse hide.bs.collapse', function (event) {
14601			var $target = $(event.target);
14602			var $toglles = $('[data-target="#' + $target.attr('id') + '"]');
14603			$toglles.prop("disabled", true);
14604		}).on('shown.bs.collapse hidden.bs.collapse', function (event) {
14605			var $target = $(event.target);
14606			var $toglles = $('[data-target="#' + $target.attr('id') + '"]');
14607			$toglles.prop("disabled", false);
14608		});
14609
14610		self.IsRss = ko.observable("False");
14611
14612		self.Mode = ko.observable($element.find("input[name=Mode]").val());
14613
14614		self.CanSubmit = ko.pureComputed(function() {
14615			return (self.GetPressReleases() ||
14616				self.GetMediaMaterials() ||
14617				self.GetEvents() ||
14618				self.GetRegionNews() ||
14619				self.GetTenders() ||
14620				self.GetSubsidiaryTenderNews() ||
14621				self.GetVacancies()) &&
14622			(self.IsRss() === "True" || self.Confirmed());
14623		});
14624
14625		self.CanCancelSubmit = ko.pureComputed(function () {
14626			return self.ConfirmCancel();
14627		});
14628
14629		self.EditCheckboxClick = function() {
14630			if (self.Confirmed) {
14631				self.ConfirmCancel(false);
14632			}
14633			return true;
14634		}
14635		self.CancelCheckboxClick = function() {
14636			if (self.ConfirmCancel) {
14637				self.Confirmed(false);
14638			}
14639			return true;
14640		}
14641
14642		self.SubmitEmailForm = function(formElement) {
14643			var $formElement = $(formElement);
14644
14645			$formElement.find("input[name=PressReleasesTagsString]").val($.getTagsValFromMultiselects($formElement, [".pressreleases-theme-select", ".pressreleases-country-region-select", ".pressreleases-organization-select"]));
14646
14647			$formElement.find("input[name=RegionNewsTagsString]").val($.getTagsValFromMultiselects($formElement, [".region-country-region-select", ".region-organization-select", ".region-theme-select"]));
14648			$formElement.find("input[name=RegionNewsLanguagesString]").val(_.pluck($formElement.find(".region-language-select").getValFromMultiSelect(), "value").join(","));
14649
14650			$formElement.find("input[name=TenderTagsString]").val($.getTagsValFromMultiselects($formElement, [".tender-organization-select"]));
14651
14652			$formElement.find("input[name=VacancyTagsString]").val($.getTagsValFromMultiselects($formElement, [".vacancies-organization-select", ".activities-select", ".vacancy-country-region-select"]));
14653			return true;
14654		};
14655	};
14656
14657	// CB NewsSubscription - Подписка на ленту нововстей
14658	var prepareNewsSubscription = function() {
14659		_.each($(settings.newsSubscriptionWidgetSelector), function (widget, index) {
14660			try {
14661				var $widget = $(widget);
14662				var viewModel = new NewsSubscriptionViewModel($widget);
14663
14664				ko.applyBindings(viewModel, widget);
14665
14666				var $sendForm = $widget.find("form");
14667				$sendForm.lukoilAjaxSubmitForm(null, null, function () {
14668					$sendForm.reloadLukoilCaptcha();
14669
14670					clearUrlQuery();
14671				}, false,
14672					function(onCloseEvent) {
14673						if (onCloseEvent == "refresh")
14674							location.reload();
14675					});
14676
14677				var uiMessage = $widget.data("message");
14678				if (uiMessage) {
14679					$.fancyboxMessage(uiMessage);
14680					clearUrlQuery();
14681				}
14682			} catch (e) {
14683				if (window.console && window.console.log) { console.log("Failed to render news subscription #" + (index + 1), e); }
14684			} 
14685		});
14686	};
14687
14688	var EventReminderViewModel = function ($element) {
14689		var self = this;
14690		var mode = $element.data("mode");
14691
14692		self.mode = ko.observable(mode);
14693		self.confiramtionChecked = ko.observable(mode);
14694		self.email = ko.observable($element.data("mail"));
14695
14696		self.SubmitEmailForm = function (formElement) {
14697			$(formElement).find("input[name=Action]").val(self.mode());
14698			$(formElement).find("input[name=SubscriptionGuid]").val($element.data("subscription"));
14699			$(formElement).find("input[name=Token]").val($element.data("token"));
14700			$(formElement).find("input[name=EventId]").val($element.find(settings.eventReminderEventDropdownSelector + " option:selected").val());
14701			$(formElement).find("input[name=Confirm]").val(self.confiramtionChecked() ? true : false);
14702			return true;
14703		};
14704	};
14705
14706	var prepareEventReminder = function() {
14707		_.each($(settings.eventReminderWidgetSelector),
14708			function(widget, index) {
14709				try {
14710					var $widget = $(widget);
14711					var viewModel = new EventReminderViewModel($widget);
14712					ko.applyBindings(viewModel, widget);
14713
14714					var uiMessage = $widget.data("message");
14715					if (uiMessage) {
14716						$.fancyboxMessage(uiMessage);
14717						clearUrlQuery();
14718					}
14719
14720					var $sendForm = $widget.find("form");
14721					$sendForm.lukoilAjaxSubmitForm(null,
14722						null,
14723						function() {
14724							viewModel.mode(null);
14725							viewModel.email("");
14726							$widget.find(settings.eventReminderEventDropdownSelector).trigger("refresh");
14727							$widget.find(settings.eventReminderConfirmCheckboxSelector).trigger("refresh");
14728							$sendForm.reloadLukoilCaptcha();
14729						},
14730						false);
14731
14732					$widget.find(settings.eventReminderEventDropdownSelector).trigger("refresh");
14733				} catch (e) {
14734					if (window.console && window.console.log) { console.log("Failed to render event reminder #" + (index + 1)); }
14735				}
14736			});
14737	};
14738
14739	Subscription.run = function () {
14740		prepareEventReminder();
14741		prepareNewsSubscription();
14742	};
14743});;
14744LukoilApp.module("TimeLine", function (TimeLine, LukoilApp, Backbone, Marionette, $, _, global) {
14745	"use strict";
14746
14747	var modules = {
14748		util: LukoilApp.module("Util")
14749	};
14750
14751	var settings = {
14752		screensLeftForLoadingMore: 2
14753	};
14754
14755	var selectors = {
14756		timelineContainer: ".timeline",
14757		timelineListContainer: ".timeline-list"
14758	};
14759
14760	var TimeLineViewModel = function (yearsLinks, years, materialItemsCount, fileItemsCount, totalCount, languageGuid, eventListPageUrl, containerSel, $listContainer) {
14761		var self = this;
14762
14763		var $container = $(containerSel);
14764		_.each(yearsLinks, function(el, ind) {
14765			//el.isSelected = !ind;
14766			el.isSelected = false;
14767		});
14768
14769		self.LoadingInProcess = ko.observable(false);
14770		self.ShowPaginationButtons = ko.observable(true);
14771		self.MaterialItemsCount = ko.observable(materialItemsCount);
14772		self.fileItemsCount = ko.observable(fileItemsCount);
14773		self.TotalCount = ko.observable(totalCount);
14774		self.CanLoadMore = ko.pureComputed(function() {
14775			return self.TotalCount() > (self.MaterialItemsCount() + self.fileItemsCount());
14776		});
14777		self.showTimeline = ko.observable(yearsLinks && years && years.length && yearsLinks.length);
14778		self.yearsLinks = ko.observableArray(yearsLinks);
14779
14780		_.each(years,
14781			function(year) {
14782				year.Items = ko.observableArray(year.Items);
14783			});
14784
14785		var yearToScroll = null;
14786		self.afterYearRender = function(elements, data) {
14787			if (yearToScroll && data.Year == yearToScroll) {
14788				scrollToYear('#year-' + yearToScroll);
14789				yearToScroll = null;
14790			}
14791		};
14792		self.years = ko.observableArray(years);
14793
14794		self.changeSelection = function (year) {
14795			var yearItems = _.find(self.years(),
14796			function (items) {
14797				return items.Year === year.Year;
14798			});
14799
14800			if (!yearItems) {
14801				self.LoadMore(year.Year);
14802			}
14803
14804			//_.each(self.yearsLinks(), function (el, ind) {
14805			//	el.isSelected = false;
14806			//});
14807			//year.isSelected = true;
14808		}
14809
14810		self.LoadMore = function (year) {
14811			if (!self.LoadingInProcess() && self.CanLoadMore()) {
14812				self.LoadingInProcess(true);
14813				LukoilTimeLine.loadInProcess = true;
14814				$.ajax({
14815					url: "/api/presscenter/timelineitems",
14816					data: {
14817						skipMaterials: self.MaterialItemsCount(),
14818						skipFiles: self.fileItemsCount(),
14819						languageGuid: languageGuid,
14820						eventListPageUrl: eventListPageUrl,
14821						take: year ? null : 20,
14822						year: year
14823					},
14824					method: "post",
14825					success: function (data) {
14826						if (data && data.length) {
14827							yearToScroll = year;
14828
14829							_.each(data,
14830								function (item) {
14831									var yearOfItem = _.find(self.years(),
14832										function(yearItem) {
14833											return yearItem.Year === item.Year;
14834										});
14835
14836									if (yearOfItem) {
14837										yearOfItem.Items.push(item.Item);
14838									} else {
14839										self.years.push({
14840											Year: item.Year,
14841											Text: item.Year,
14842											Items: ko.observableArray([item.Item])
14843										});
14844									}
14845
14846									if (item.Item.IsMediaFile) {
14847										self.fileItemsCount(self.fileItemsCount() + 1);
14848									} else {
14849										self.MaterialItemsCount(self.MaterialItemsCount() + 1);
14850									}
14851								});
14852
14853							$listContainer.lukTimeLine();
14854						}
14855					},
14856					traditional: true,
14857					cache: false
14858				}).fail(function () {
14859					$.fancyboxMessage(GlobalSettings.ErrorMessages.AjaxErrorMessage);
14860				}).always(function () {
14861					self.LoadingInProcess(false);
14862				});
14863			}
14864		}
14865
14866		$(window).scroll(function () {
14867			if ($(window).scrollTop() > $(document).height() - settings.screensLeftForLoadingMore * $(window).height()) {
14868				self.LoadMore();
14869			}
14870		});
14871
14872		ko.applyBindings(self, $container[0]);
14873	}
14874	
14875	TimeLine.run = function (options) {
14876
14877		var yearsLinks = options.yearsLinks,
14878			years = options.years,
14879			totalCount = options.totalCount,
14880			materialItemsCount = options.materialItemsCount,
14881			fileItemsCount = options.fileItemsCount,
14882			eventListPageUrl = options.eventListPageUrl,
14883			languageGuid = options.languageGuid;
14884
14885		var $listContainer = $(selectors.timelineListContainer);
14886		var vm = new TimeLineViewModel(yearsLinks, years, materialItemsCount, fileItemsCount, totalCount, languageGuid, eventListPageUrl, selectors.timelineContainer, $listContainer);
14887		var tl = $listContainer.lukTimeLine();
14888	}
14889
14890	TimeLine.on("start", function (options) { });
14891});
14892
14893
14894var LukoilTimeLine = {
14895	loadInProcess : false
14896}
14897
14898var scrollToYear = function (yearId) {
14899	var interval = setInterval(function() {
14900			var $year = $(yearId);
14901
14902			if ($year.length > 0 && !LukoilTimeLine.loadInProcess) {
14903				var offsetTop = $year.offset().top - $('#header').height() - 50;
14904				$('.timline-date__item').removeClass('selected');
14905				$(this).addClass('selected');
14906				$('html, body').animate({ scrollTop: offsetTop }, 500);
14907
14908				clearInterval(interval);
14909			}
14910		},
14911		50);
14912}
14913
14914$(document).on('click', '.timline-date__item', function (e) {
14915	e.preventDefault();
14916	var id = $(this).attr('href');
14917	scrollToYear(id);
14918});
14919
14920(function ($) {
14921	$.fn.lukTimeLine = function () {
14922		return this.each(function (_, elem) {
14923			$(elem).data('timelineFn', new TimelineGrid(elem));
14924		});
14925
14926	};
14927
14928	function TimelineGrid(element) {
14929		this.elem_ = $(element);
14930		this.items_ = $(element).find('.timeline-item');
14931		this.preloader_ = this.elem_.siblings('.timeline__preloader');
14932		this.indexPrevCol = 0;
14933		this.minIndent = 60;
14934		this.images = this.elem_.find('img');
14935		this.isDesktop = function () {
14936			return !window.matchMedia('(max-width: 767px)').matches;
14937		};
14938		this.init();
14939	}
14940
14941	TimelineGrid.prototype.init = function () {
14942		this.preloaderImage = this.preloader();
14943		$(window).on('resize', this.onResize.bind(this));
14944
14945		if (this.isDesktop()) {
14946			this.preloaderImage.then(this.buildInterface.bind(this));
14947		}
14948		else {
14949			this.items_.removeAttr('hidden');
14950			LukoilTimeLine.loadInProcess = false;
14951		}
14952	};
14953
14954	TimelineGrid.prototype.onResize = function () {
14955		this.updateGrid();
14956	};
14957
14958	TimelineGrid.prototype.updateGrid = function () {
14959		if (this.isDesktop()) {
14960			this.preloaderImage.then(this.buildInterface.bind(this));
14961		} else {
14962			this.elem_.height("auto");
14963			LukoilTimeLine.loadInProcess = false;
14964		}
14965	};
14966
14967	TimelineGrid.prototype.buildInterface = function () {
14968		this.columns = [0, 110];
14969		this.items_
14970		  .removeClass('timeline-item_inverted')
14971		  .each(this.makeGrid.bind(this));
14972		LukoilTimeLine.loadInProcess = false;
14973		this.elem_.height(this.getMaxHeightCol());
14974		this.preloader_.hide();
14975	};
14976
14977	TimelineGrid.prototype.makeGrid = function (index, elem) {
14978		var $item = $(elem);
14979		var indent;
14980		var indexCol = this.columns[0] < this.columns[1] ? 0 : 1;
14981		if (indexCol) {
14982			$item.addClass('timeline-item_inverted');
14983		}
14984		if (indexCol !== this.indexPrevCol) {
14985			indent = this.columns[indexCol] - parseInt($item.prev('.timeline-item').css('top'));
14986			if (indent < this.minIndent) {
14987				this.columns[indexCol] += this.minIndent - indent;
14988			}
14989		}
14990		$item.css('top', this.columns[indexCol]);
14991		$item.removeAttr('hidden');
14992		this.columns[indexCol] += $item.height();
14993		this.indexPrevCol = indexCol;
14994	};
14995
14996	TimelineGrid.prototype.getMaxHeightCol = function () {
14997		return Math.max.apply(null, this.columns);
14998	};
14999
15000	TimelineGrid.prototype.timerInitGridTimeline = function () {
15001		setTimeout(this.buildInterface.bind(this), 100); // шрифт может быть еще не загружен, до того как загрузятся картинки
15002	};
15003
15004	TimelineGrid.prototype.preloader = function () {
15005		var deferred = $.Deferred();
15006		var countLoadImages = 0;
15007		var storeImages = [];
15008		if (!this.images.length) deferred.resolve();
15009		$.each(this.images, function (_, img) {
15010			var image = new Image();
15011			image.src = img.src;
15012			image.onload = function () {
15013				countLoadImages++;
15014				if (countLoadImages === this.images.length) {
15015					deferred.resolve();
15016				}
15017			}.bind(this);
15018			image.onerror = function () {
15019				if (console && console.log) console.log("Failed to load image " + image.src);
15020				countLoadImages++;
15021				if (countLoadImages === this.images.length) {
15022					deferred.resolve();
15023				}
15024			}.bind(this);
15025			storeImages.push(image);
15026		}.bind(this));
15027		return deferred.promise();
15028	};
15029
15030	TimelineGrid.prototype.destroy = function () {
15031		$(window).off('resize.lukTimeline');
15032		this.elem_.removeData('timelineFn');
15033		this.items_.removeClass('timeline-item_inverted').removeAttr('style');
15034	}
15035
15036})(jQuery);
15037;
15038LukoilApp.module("RedirectionFromOldSite", function (RedirectionFromOldSite, LukoilApp, Backbone, Marionette, $, _) {
15039	"use strict";
15040
15041	var settings = {
15042		rememberCheckboxId: "redirect-to-old-remember",
15043		cookieName: "OldSiteRedirection",
15044		sessionCookieName: "OldSiteRedirectionSession"
15045	};
15046
15047	RedirectionFromOldSite.on("start", function (options) {
15048		RedirectionFromOldSite.run();
15049	});
15050
15051	var saveCookie = function (redirection, isOld) {
15052		var remember = $("#" + settings.rememberCheckboxId).prop("checked");
15053
15054		var cookieName = remember
15055			? settings.cookieName
15056			: settings.sessionCookieName;
15057
15058		Cookies.raw = true;
15059		var value = $.lukoilGetCookie(cookieName);
15060
15061		var redirections = [];
15062		if (value) {
15063			try {
15064				var allSaved = JSON.parse(value);
15065
15066				redirections = _.filter(allSaved,
15067					function(item) {
15068						return item.i !== redirection.Id;
15069					});
15070			} catch (e) {}
15071		}
15072
15073		redirections.push({
15074			i: redirection.Id,
15075			c: isOld ? 1 : 2
15076		});
15077
15078		$.removeCookie(cookieName);
15079
15080		$.lukoilSaveCookie(cookieName, JSON.stringify(redirections), { expires: remember ? 30 : undefined });
15081	};
15082
15083	RedirectionFromOldSite.run = function () {
15084		var redirection = GlobalSettings.RedirectionFromOldSite;
15085
15086		if (redirection) {
15087			$.fancybox({
15088				padding: 10,
15089				autoSize: false,
15090				autoHeight: true,
15091				width: 250,
15092				content: '<div class="modal-confirm">' +
15093							'<div class="modal-confirm__body">' + GlobalSettings.RedirectionToOldSite.ModalText + '</div>' +
15094							'<div class="group-buttons">' +
15095								'<button id="fancyConfirm_cancel" class="button">' + GlobalSettings.RedirectionToOldSite.New + '</button>' +
15096								'<button id="fancyConfirm_ok" class="button">' + GlobalSettings.RedirectionToOldSite.Old + '</button>' +
15097							'</div>' +
15098							'<div class="checkbox">' +
15099								'<input class="checkbox-custom" type="checkbox" id="' + settings.rememberCheckboxId + '" />' +
15100								'<label class="label-control" for="' + settings.rememberCheckboxId + '">' + GlobalSettings.RedirectionToOldSite.Remember + '</label>' +
15101							'</div>' +
15102						'</div>',
15103				afterShow: function () {
15104					$("#fancyConfirm_ok").on("click", function () {
15105						saveCookie(redirection, true);
15106						window.location.href = redirection.OldUrl;
15107					});
15108					$("#fancyConfirm_cancel").on("click", function () {
15109						saveCookie(redirection, false);
15110						window.location.href = redirection.NewUrl;
15111					});
15112				},
15113			});
15114		}
15115	};
15116});;
15117LukoilApp.module("OnlineSurveys", function(OnlineSurveys, LukoilApp, Backbone, Marionette, $, _) {
15118	var requiredModules = {
15119		util: LukoilApp.module("Util")
15120	};
15121
15122	var options = { debug: true }, logger;
15123
15124	var settings = {
15125		selectors: {
15126			survey: ".survey",
15127			question: ".survey__question",
15128			sendBtn: ".survey-btn-answer.send-answer .button",
15129			answerInputs: "input:not('.another-answer-support')",
15130			results: ".survey-total-result",
15131			surveyQuestions: ".survey-questions",
15132			answersContainer: ".survey-answer-container",
15133			questionTitle: ".survey__question-title",
15134			timer: ".survey__time",
15135			timeHolder: "span",
15136			startBtn: ".survey-btn-answer.start-survey .button",
15137			repeatBtn: ".survey-btn-repeat .button",
15138			overlay: ".survey_submit_overlay",
15139			urlReferer: ".urlReferer"
15140		},
15141		sendResultUrl: "/api/onlinesurvey/SendResult",
15142		idAttr: "survey-entity-id",
15143		free: "survey-free",
15144		uidKey: "LukOnlineSuveyUserId",
15145		newUIdAttr: "survey-user-new-id",
15146		cookiesConfig: {
15147			expires: 365 * 100,
15148			path: '/'
15149		},
15150		messages: {
15151			isEmpty: GlobalSettings.OnlineSurveys.AnswerIsEmpty,
15152			timeIsUp: GlobalSettings.OnlineSurveys.TimeIsUp
15153		},
15154		groupAttr: "survey-group",
15155		timerTicks: "test-ticks"
15156	};
15157
15158	var getUserId = function ($surveyContainer) {
15159		var uid = $.lukoilGetCookie(settings.uidKey);
15160		if (!uid) {
15161			uid = $surveyContainer.data(settings.newUIdAttr);
15162			$.lukoilSaveCookie(settings.uidKey, uid, settings.cookiesConfig);
15163		}
15164		return uid;
15165	};
15166	var getQuestionAnswer = function ($q) {
15167		var qid = $q.data(settings.idAttr);
15168		var answers = _.map($q.find(settings.selectors.answerInputs), function (inp) {
15169			var $inp = $(inp);
15170			return {
15171				title: $inp.closest(settings.selectors.answersContainer).find("label").text(),
15172				questionId: qid,
15173				id: $inp.data(settings.idAttr) || -1,
15174				isChecked: $inp.is(":checked"),
15175				text: $inp.val()
15176			};
15177		});
15178
15179		return {
15180			questionId: qid,
15181			title: $q.find(settings.selectors.questionTitle).text(),
15182			answers: answers,
15183			isFreeAnswer: $q.data(settings.free)
15184		};
15185	};
15186	var getAnswers = function (form) {
15187		var $qs = form.getQuestions();
15188
15189		var questionsWithAnswers = _.map($qs, function (q) {
15190			return getQuestionAnswer($(q));
15191		});
15192
15193		return {
15194			surveyId: form.surveyId || -1,
15195			answers: questionsWithAnswers,
15196			userId: getUserId(form.getContainer()),
15197			urlReferer: form.urlReferer,
15198			captcha: form.getCaptcha()
15199		};
15200	};
15201
15202	var sendAnswers = function (surveyAnswer, surveyForm, message, timer, timerCallback) {
15203		surveyForm.getOverlay().show();
15204		var $frm = surveyForm.getContainer();
15205		$.ajax(settings.sendResultUrl, {
15206			async: true,
15207			cache: false,
15208			data: {
15209				result: JSON.stringify(surveyAnswer)
15210			},
15211			dataType: "json",
15212			method: "POST",
15213			traditional: true
15214		}).done(function (result) {
15215			var responseJson = $.isPlainObject(result) ? result : $.parseJSON(result);
15216			if (!$frm.isValiationSummaryErrors(responseJson)) {
15217				surveyForm.getOverlay().hide();
15218				if (result && result.stats) {
15219					var stats = JSON.parse(result.stats);
15220					var existsStats = [];
15221					_.each(stats, function (s) {
15222						var found = _.find(surveyAnswer.answers,
15223							function (q) {
15224								return q.questionId === s.QuestionId;
15225							});
15226
15227						if (found != null) {
15228
15229							s.title = found.title;
15230							s.isFreeAnswer = found.isFreeAnswer;
15231
15232							var staleCount = 0;
15233
15234							_.each(s.AnswersStats, function (a) {
15235								a.percent = (a.TotalAnswersNumber ? a.YesAnswersNumber * 100.0 / a.TotalAnswersNumber : 0).toFixed(2);
15236								var question = _.find(surveyAnswer.answers, function (q) {
15237									return q.questionId === a.QuestionId;
15238								});
15239
15240								if (!question) {
15241									a.IsStale = true;
15242									staleCount++;
15243								} else {
15244									var answer = _.find(question.answers, function (qa) {
15245										return a.AnswerId === qa.id;
15246									});
15247
15248									if (!answer) {
15249										a.IsStale = true;
15250										staleCount++;
15251									} else {
15252										a.text = answer.title;
15253									}
15254								}
15255							});
15256
15257							if (staleCount === s.AnswersStats.length) {
15258								s.IsStale = true;
15259							} else {
15260								s.AnswersStats = _.filter(s.AnswersStats,
15261									function (a) {
15262										return !a.IsStale;
15263									});
15264							}
15265
15266							existsStats.push(s);
15267						}
15268					});
15269
15270					var $resultContainer = surveyForm.getResults();
15271					$resultContainer.show();
15272					surveyForm.SurveyResults(existsStats);
15273
15274					if (!ko.dataFor($resultContainer[0])) {
15275						ko.applyBindings({ questionsResult: surveyForm.SurveyResults }, $resultContainer[0]);
15276					}
15277				}
15278				else if (result && result.error) {
15279					logger.log(result.error);
15280				}
15281
15282				if (message || (result && result.message)) {
15283					$.fancyboxMessage(message || result.message);
15284				}
15285
15286				surveyForm.getQuestionsContainer().hide();
15287
15288				var $repeatBtn = surveyForm.getRepeatBtn();
15289
15290				if ($repeatBtn.length) {
15291					$repeatBtn.show();
15292				}
15293			} else {
15294				if (timer != null) {
15295					timer.run(timerCallback, true);
15296				}
15297				$frm.reloadLukoilCaptcha();
15298				surveyForm.getOverlay().hide();
15299			}
15300		}).fail(function (jqXHR, textStatus, errorThrown) {
15301			surveyForm.getOverlay().hide();
15302			logger.log(errorThrown);
15303			$.fancyboxInit({
15304				padding: 10,
15305				content: "<div>" + GlobalSettings.ErrorMessages.FormSubmitErrorMessage + "</div>"
15306			});
15307		});
15308	};
15309
15310	var SurveyValidationError = function (groupId, text) {
15311		this.groupId = groupId,
15312		this.text = text;
15313	};
15314
15315	var validateRadio = function($container) {
15316		var errors = [];
15317		var qs = $container.find(settings.selectors.question);
15318		_.each(qs, function (q) {
15319			var $q = $(q);
15320			var groupId = $q.data(settings.groupAttr);
15321			var $el = $q.find("input:radio[name='" + groupId + "']");
15322			if ($el.length) {
15323				var checked = $el.is(":checked");
15324				if (!checked) {
15325					errors.push(new SurveyValidationError(groupId, settings.messages.isEmpty));
15326					$q.find(".error").text(settings.messages.isEmpty).removeClass("hidden");
15327				}
15328			}
15329			
15330		});
15331		return errors;
15332	};
15333	var validateChecks = function($container) {
15334		var errors = [];
15335		var qs = $container.find(settings.selectors.question);
15336		_.each(qs, function (q) {
15337			var $q = $(q);
15338			var groupId = $q.data(settings.groupAttr);
15339			var $el = $q.find("input:checkbox");
15340			if ($el.length) {
15341				var checked = $el.is(":checked");
15342				if (!checked) {
15343					errors.push(new SurveyValidationError(groupId, settings.messages.isEmpty));
15344					$q.find(".error").text(settings.messages.isEmpty).removeClass("hidden");
15345				}
15346			}
15347		});
15348		return errors;
15349	};
15350
15351	var validateText = function($container) {
15352		var errors = [];
15353		var qs = $container.find(settings.selectors.question);
15354		_.each(qs, function (q) {
15355			var $q = $(q);
15356			var groupId = $q.data(settings.groupAttr);
15357			var $el = $q.find("input:text.free-answer");
15358			if ($el.length) {
15359				var checked = $el.val();
15360				if (!checked) {
15361					errors.push(new SurveyValidationError(groupId, settings.messages.isEmpty));
15362					$q.find(".error").text(settings.messages.isEmpty).removeClass("hidden");
15363				}
15364			}
15365		});
15366		return errors;
15367	};
15368
15369	var validateOtherText = function($container) {
15370		var errors = [];
15371		var qs = $container.find(settings.selectors.question);
15372		_.each(qs, function (q) {
15373			var $q = $(q);
15374			var groupId = $q.data(settings.groupAttr);
15375			var $el = $q.find("input.another-answer-support");
15376			if ($el.length) {
15377				var checked = $el.is(":checked");
15378				var text = $q.find("input.another-answer-text").val();
15379				if (checked && !text) {
15380					errors.push(new SurveyValidationError(groupId, settings.messages.isEmpty));
15381					$q.find(".error").text(settings.messages.isEmpty).removeClass("hidden");
15382				}
15383			}
15384		});
15385		return errors;
15386	};
15387
15388	var validateSurvey = function ($container) {
15389		$container.find(".error").addClass("hidden");
15390		var radioIsValid = validateRadio($container);
15391		var checkIsValid = validateChecks($container);
15392		var textIsValid = validateText($container);
15393		var othertextIsValid = validateOtherText($container);
15394		return { errors: radioIsValid.concat(checkIsValid).concat(textIsValid).concat(othertextIsValid) };
15395	};
15396
15397	var SurveyForm = function ($surveyContainer) {
15398		this.$surveyContainer = $surveyContainer; // $(settings.selectors.survey);
15399		this.$sendBtn = this.$surveyContainer.find(settings.selectors.sendBtn);
15400		this.$startBtn = this.$surveyContainer.find(settings.selectors.startBtn);
15401		this.$repeatBtn = this.$surveyContainer.find(settings.selectors.repeatBtn);
15402		this.$questionsContainer = this.$surveyContainer.find(settings.selectors.surveyQuestions);
15403		this.$questions = this.$questionsContainer.find(settings.selectors.question);
15404		this.$results = this.$surveyContainer.find(settings.selectors.results);
15405		this.surveyId = this.$surveyContainer.data(settings.idAttr);
15406		this.$timerContainer = this.$surveyContainer.find(settings.selectors.timer);
15407		this.$timeHolder = this.$timerContainer.find(settings.selectors.timeHolder);
15408		this.timerTicks = this.$timeHolder.data(settings.timerTicks);
15409		this.$overlay = this.$surveyContainer.find(settings.selectors.overlay);
15410		this.urlReferer = this.$surveyContainer.find(settings.selectors.urlReferer).val();
15411
15412		this.SurveyResults = ko.observableArray([]);
15413	};
15414	SurveyForm.prototype.getContainer = function() {
15415		return this.$surveyContainer;
15416	};
15417	SurveyForm.prototype.getSendBtn = function () {
15418		return this.$sendBtn;
15419	};
15420	SurveyForm.prototype.getStartBtn = function () {
15421		return this.$startBtn;
15422	};
15423	SurveyForm.prototype.getRepeatBtn = function () {
15424		return this.$repeatBtn;
15425	};
15426	SurveyForm.prototype.getQuestions = function () {
15427		return this.$questions;
15428	};
15429	SurveyForm.prototype.getQuestionsContainer = function () {
15430		return this.$questionsContainer;
15431	};
15432	SurveyForm.prototype.getResults = function () {
15433		return this.$results;
15434	};
15435	SurveyForm.prototype.getOverlay = function () {
15436		return this.$overlay;
15437	};
15438	SurveyForm.prototype.getCaptcha = function () {
15439		return this.$surveyContainer.getCaptcha();
15440	};
15441
15442	var SurveyTimer = function (surveyForm) {
15443		this.surveyForm = surveyForm;
15444		this.initialTicks = surveyForm.timerTicks;
15445		this.timeIsOver = false;
15446
15447		this.timerContainer = surveyForm.$timerContainer;
15448		this.timeHolder = surveyForm.$timeHolder;
15449		
15450		if (!this.initialTicks) return this;
15451		this.showTimer(this.initialTicks);
15452		if (this.initialTicks) {
15453			surveyForm.getQuestionsContainer().hide();
15454		}
15455		return this;
15456	};
15457	SurveyTimer.prototype.run = function(callback, isResume) {
15458		if (!this.initialTicks) return;
15459		this.timerContainer.show();
15460		if (!isResume)
15461			this.currentTicks = this.initialTicks;
15462		var self = this;
15463		this.timeIsOver = false;
15464
15465		var tickTimer = function () {
15466			if (self.currentTicks > 0) {
15467				self.currentTicks--;
15468				self.showTimer(self.currentTicks);
15469			}
15470
15471			if (self.currentTicks <= 0) {
15472				self.stop();
15473				if (callback) callback(self);
15474			}
15475		};
15476
15477		this.timerId = setInterval(tickTimer, 1000);
15478	};
15479	SurveyTimer.prototype.stop = function () {
15480		if (this.timerId) clearTimeout(this.timerId);
15481		this.timerContainer.hide();
15482	};
15483	SurveyTimer.prototype.showTimer = function (ticks) {
15484		var sec = ticks % 60;
15485		var min = Math.floor(ticks / 60);
15486		var formattedTime = min + ":" + (sec > 9 ? sec : "0" + sec);
15487		this.timeHolder.text(formattedTime);
15488	};
15489
15490	var timerCallback = function (timer) {
15491		timer.timeIsOver = true;
15492		$.fancyboxMessage(settings.messages.timeIsUp);
15493		timer.surveyForm.getQuestionsContainer().hide();
15494		timer.surveyForm.getResults().hide();
15495		timer.surveyForm.getRepeatBtn().show();
15496	}
15497
15498	OnlineSurveys.run = function () {
15499		var surveyContainers = $(settings.selectors.survey);
15500		if (!surveyContainers.length) return;
15501
15502		logger = requiredModules.util.createLogger({ useConsole: options.debug, moduleName: "OnlineSurveys" });
15503
15504		_.each(surveyContainers, function(surveyContainer) {
15505			var surveyForm = new SurveyForm($(surveyContainer));
15506			var timer = new SurveyTimer(surveyForm);
15507
15508			surveyForm.getStartBtn().on("click", function() {
15509				surveyForm.getStartBtn().hide();
15510				surveyForm.getQuestionsContainer().show();
15511				timer.run(timerCallback);
15512				return false;
15513			});
15514
15515			var $repeatBtn = surveyForm.getRepeatBtn();
15516
15517			if ($repeatBtn.length) {
15518				$repeatBtn.on("click",
15519					function() {
15520						$repeatBtn.hide();
15521						var $frm = surveyForm.getContainer();
15522						$frm.reloadLukoilCaptcha();
15523						surveyForm.getQuestionsContainer().show();
15524						surveyForm.getResults().hide();
15525						$(surveyContainer).formReset(true, true);
15526						$(surveyContainer).find(".another-answer-text").addClass("hidden");
15527						timer.run(timerCallback);
15528						return false;
15529					});
15530			}
15531
15532			surveyForm.getSendBtn().on("click", function () {
15533				if (timer.timeIsOver) return false;
15534
15535				var validationResult = validateSurvey(surveyForm.getContainer());
15536				if (validationResult.errors && validationResult.errors.length)
15537					return false;
15538
15539				var surveyAnswer = getAnswers(surveyForm);
15540				sendAnswers(surveyAnswer, surveyForm, null, timer, timerCallback);
15541				timer.stop();
15542				return false;
15543			});
15544		});
15545	};
15546
15547	OnlineSurveys.on("start", function (options) {
15548		OnlineSurveys.run();
15549	});
15550});;
15551LukoilApp.module("EssentialFacts", function (EssentialFacts, LukoilApp, Backbone, Marionette, $, _) {
15552
15553	var requiredModules = {
15554		util: LukoilApp.module("Util")
15555	};
15556
15557	var options = { debug: true }, logger;
15558
15559	var settings = {
15560		defaultSelectValue: "0",
15561		defaultPageSize: 5,
15562		pageSizeDataAttr: "page-size"
15563	};
15564
15565	var selectors = {
15566		container: ".essential-facts",
15567		filterForm: ".filter form",
15568		searchBtn: ".button-search",
15569		resetBtn: ".button-reset",
15570		loadMoreBtn: ".button-load-more",
15571		filter: ".select-custom",
15572		filterCategory: ".categories-select",
15573		filterMonth: ".months-select",
15574		item: ".essential-facts-item",
15575		visibleItems: ".essential-facts-item:visible",
15576		emptyResult: ".empty-search-result"
15577	};
15578
15579	var filterBy = function ($container, filter, attrName) {
15580		if (filter && filter !== settings.defaultSelectValue)
15581			$container.find(selectors.item + "[data-" + attrName + "!=" + filter + "]").removeClass("even").removeClass("odd").removeClass('visible').hide();
15582	};
15583	var filterByMultiple = function ($container, $selector, dataKey) {
15584		var filter = $selector.getValFromMultiSelect();
15585		if (filter && filter.length) {
15586			var items = $container.find(selectors.item);
15587			_.each(items, function(item) {
15588				var $item = $(item);
15589				var dataAttr = $item.data(dataKey).toString();
15590				if (_.all(filter, function(f) {
15591					return dataAttr != f.value.toString();
15592				})) {
15593					$item.removeClass("even").removeClass("odd").removeClass('visible').hide();
15594				}
15595			});
15596		}
15597	};
15598
15599	var Form = function(container, pageSize) {
15600		this.$container = $(container);
15601		this.$filters = this.$container.find(selectors.filter);
15602		this.$items = this.$container.find(selectors.item);
15603		this.pageSize = this.getPageSize() || pageSize;
15604		this.itemsNumberToShow = this.pageSize;
15605		if (this.$items.length <= this.itemsNumberToShow)
15606			this.getShowMoreBtn().hide();
15607		this.$container.removeClass("hidden");
15608		this.hideOverpagedItems();
15609		this.updateVisibility();
15610		var self = this;
15611		this.getFilterForm().on("submit", function () { return false; });
15612		this.getSearchBtn().on("click", function () {
15613			self.resetItemsNumberToShow();
15614			self.filterItems();
15615		});
15616		this.getResetBtn().on("click", function () {
15617			self.resetFilters();
15618		});
15619		this.getShowMoreBtn().on("click", function () {
15620			self.showMoreItems();
15621		});
15622	}
15623	Form.prototype.getPageSize = function () {
15624		return this.$container.data(settings.pageSizeDataAttr);
15625	}
15626	Form.prototype.getFilterForm = function () {
15627		return this.$container.find(selectors.filterForm);
15628	}
15629	Form.prototype.getSearchBtn = function() {
15630		return this.$container.find(selectors.searchBtn);
15631	}
15632	Form.prototype.getCategoryFilter = function () {
15633		return this.$container.find(selectors.filterCategory);
15634	}
15635	Form.prototype.getMonthFilter = function () {
15636		return this.$container.find(selectors.filterMonth);
15637	}
15638	Form.prototype.getResetBtn = function () {
15639		return this.$container.find(selectors.resetBtn);
15640	}
15641	Form.prototype.getEmptyResult = function () {
15642		return this.$container.find(selectors.emptyResult);
15643	}
15644	Form.prototype.getVisibleItems = function () {
15645		return this.$container.find(selectors.visibleItems);
15646	}
15647	Form.prototype.getShowMoreBtn = function () {
15648		return this.$container.find(selectors.loadMoreBtn);
15649	}
15650	Form.prototype.resetFilters = function () {
15651		_.each(this.$filters, function(filter) {
15652			$(filter).val(settings.defaultSelectValue).trigger("change");
15653		});
15654	}
15655	Form.prototype.hideOverpagedItems = function () {
15656		var $visibleItems = this.getVisibleItems();
15657		$visibleItems.addClass('visible');
15658		_.each($visibleItems, function (p, ind) {
15659			if (ind % 2) {
15660				$(p).removeClass("even");
15661				$(p).addClass("odd");
15662			}
15663			else {
15664				$(p).removeClass("odd");
15665				$(p).addClass("even");
15666			}
15667		});
15668		if ($visibleItems.length > this.itemsNumberToShow) {
15669			$visibleItems.slice(this.itemsNumberToShow)
15670				.removeClass('visible').removeClass("even").removeClass("odd").hide();
15671		}
15672	}
15673	Form.prototype.filterItems = function () {
15674		var filters = _.map(this.$filters, function(f) {
15675			return $(f).val();
15676		});
15677		this.$items.show();
15678		filterBy(this.$container, filters[0], "year");
15679
15680		filterByMultiple(this.$container, this.getCategoryFilter(), "category");
15681		filterByMultiple(this.$container, this.getMonthFilter(), "month");
15682
15683		if (this.getVisibleItems().length <= this.itemsNumberToShow)
15684			this.getShowMoreBtn().hide();
15685		else
15686			this.getShowMoreBtn().show();
15687
15688		this.hideOverpagedItems();
15689		this.updateVisibility();
15690	}
15691	Form.prototype.updateVisibility = function() {
15692		if (!this.$container.find(selectors.item).find(":visible").length) {
15693			this.getEmptyResult().show();
15694		} else {
15695			this.getEmptyResult().hide();
15696		}
15697	};
15698	Form.prototype.showMoreItems = function () {
15699		this.itemsNumberToShow += this.pageSize;
15700		this.filterItems();
15701	}
15702	Form.prototype.resetItemsNumberToShow = function () {
15703		this.itemsNumberToShow = this.pageSize;
15704	}
15705	
15706	EssentialFacts.run = function () {
15707		var $containers = $(selectors.container);
15708		if (!$containers.length) return;
15709		logger = requiredModules.util.createLogger({ useConsole: options.debug, moduleName: "EssentialFacts" });
15710		_.each($containers, function(container) {
15711			var form = new Form($(container), settings.defaultPageSize);
15712		});
15713	};
15714
15715	EssentialFacts.on("start", function (options) {
15716		EssentialFacts.run();
15717	});
15718});;
15719LukoilApp.module("MediaLibrary", function(MediaLibrary, LukoilApp, Backbone, Marionette, $, _) {
15720	"use strict";
15721
15722	var settings = {
15723		mediaLibraryWidgetSelector: ".media-library-widget",
15724		mediaLibraryJsonContainerSelector: ".materials-data",
15725		mediaLibraryResultsSelector: ".media-center-container",
15726		photoRibbonSelector: ".panel-list-photo_ribbon",
15727		themeSelector: ".theme-select",
15728		fileTypeSelector: ".file-type-select",
15729		languageSelector: ".language-select",
15730		projectSelector: ".project-select",
15731		countrySelector: ".country-select",
15732		industrySelector: ".industry-select",
15733		regionSelector: ".region-select",
15734		personSelector: ".person-select",
15735		startDateSelector: "#calendar-from",
15736		endDateSelector: "#calendar-to",
15737		queryInputSelector: ".search-control",
15738		getMaterialsUrl: "/api/presscenter/mediamaterials",
15739		getTagsUrl: "/api/presscenter/Tags",
15740		filterForm: ".filter form",
15741		mediaLibraryFilterBtnSelector: ".filter-btn",
15742		loadMoreButtonSelector: ".load-more-button",
15743		datepickerSelector: ".form-control.calendar",
15744		resetButtonSelector: ".button-reset",
15745		mediaAlbumWidgetSelector: ".media-album-widget",
15746		photoRibbonMaxHeight: 256,
15747		languageGuids: []
15748	};
15749
15750	function FileListViewModel(mediaFiles) {
15751		var self = this;
15752
15753		self.filesByTypeArray = [];
15754		self.allFiles = [];
15755		self.filesByType = {};
15756
15757		self.filesByType.DownloadOnly = [];
15758		self.filesByType[Constants.fileTypes.Document] = [];
15759		self.filesByType[Constants.fileTypes.Audio] = [];
15760		self.filesByType[Constants.fileTypes.Video] = [];
15761		self.filesByType[Constants.fileTypes.Image] = [];
15762
15763		if (mediaFiles) {
15764			_.each(mediaFiles,
15765				function(mediafile) {
15766					if (!mediafile.IsLink && mediafile.File) {
15767						mediafile.File.FileTitle = mediafile.Name;
15768						if (self.filesByType[mediafile.File.Type] && mediafile.File.AllowPreview) {
15769							self.filesByType[mediafile.File.Type].push(mediafile.File);
15770						} else {
15771							self.filesByType.DownloadOnly.push(mediafile.File);
15772						}
15773
15774						self.allFiles.push(mediafile.File);
15775					}
15776				});
15777		}
15778
15779		_.each(_.keys(self.filesByType),
15780			function(type) {
15781				self.filesByTypeArray.push({ type: type, files: self.filesByType[type] });
15782			});
15783
15784		var mediaFilesOrder = [0, 4, 1, 2, 3, 5, 6];
15785		self.filesByTypeArray.sort(function(a, b) {
15786			return mediaFilesOrder[b.type] - mediaFilesOrder[a.type];
15787		});
15788	};
15789
15790	MediaLibrary.getVmForFileList = function(mediaFiles) {
15791		return new FileListViewModel(mediaFiles);
15792	};
15793
15794	var requiredModules = {
15795		targeting: LukoilApp.module("Targeting")
15796	};
15797
15798	MediaLibrary.on("start",
15799		function(options) {
15800			MediaLibrary.run();
15801		});
15802
15803	var buildQueryStringForMediaLibraryFilter = function(query, fileType, tags, lang, startDate, endDate) {
15804		var url = new URI(window.location.href);
15805
15806		url.search(function(data) {
15807			data[Constants.queryParamNames.SearchQuery] = query ? query : undefined;
15808			data[Constants.queryParamNames.FileType] = fileType ? fileType : undefined;
15809			data[Constants.queryParamNames.LanguageGuid] = lang ? lang : undefined;
15810			data[Constants.queryParamNames.Tags] = tags ? tags : undefined;
15811			data[Constants.queryParamNames.StartDate] = startDate ? startDate : undefined;
15812			data[Constants.queryParamNames.EndDate] = endDate ? endDate : undefined;
15813			return data;
15814		});
15815
15816		return url.search();
15817	};
15818
15819	var updateSearchParams = function(vm, $mediaLibrary) {
15820		var tagsVal = $.getTagsValFromMultiselects($mediaLibrary,
15821			[
15822				settings.themeSelector, settings.projectSelector, settings.projectSelector, settings.countrySelector,
15823				settings.industrySelector, settings.regionSelector, settings.personSelector
15824			]);
15825
15826		var languageVal = settings.languageGuids;
15827		var fileTypesVal = _.pluck($mediaLibrary.find(settings.fileTypeSelector).getValFromMultiSelect(), "value");
15828
15829		var $startDatePicker = $mediaLibrary.find(settings.startDateSelector);
15830		var $endDatePicker = $mediaLibrary.find(settings.endDateSelector);
15831		var queryVal = $mediaLibrary.find(settings.queryInputSelector).val().encodeURIComponent();
15832
15833		var startDateValue =
15834			$.datepicker.parseDate($startDatePicker.datepicker("option", "dateFormat"), $startDatePicker.val());
15835		var endDateValue = $.datepicker.parseDate($endDatePicker.datepicker("option", "dateFormat"), $endDatePicker.val());
15836
15837		vm.SearchParams = {
15838			query: queryVal,
15839			fileTypes: fileTypesVal,
15840			tags: tagsVal,
15841			languages: languageVal,
15842			currentLangauge: $mediaLibrary.data("lang"),
15843			currentUrl: window.location.href,
15844			startDate: startDateValue ? startDateValue.localAsUtcDate().toISOString() : null,
15845			endDate: endDateValue ? endDateValue.localAsUtcDate().toISOString() : null,
15846			take: Constants.MediaLibraryPageSize,
15847			widgetGuid: $mediaLibrary.data("widgetguid"),
15848			siteGuid: $mediaLibrary.data("site-guid"),
15849			isPersonalizationDisabled: $mediaLibrary.data("personalizationdisabled")
15850		};
15851	};
15852
15853	var loadMaterials = function (vm, $mediaLibrary, skipAllMaterials, isPaging) {
15854		if (!vm.LoadingInProcess()) {
15855			if (!skipAllMaterials) {
15856				updateSearchParams(vm, $mediaLibrary);
15857			}
15858
15859			vm.LoadingInProcess(true);
15860
15861			var data = vm.SearchParams;
15862			data.skipAllMaterials = skipAllMaterials;
15863
15864			$.ajax({
15865				url: settings.getMaterialsUrl,
15866				data: data,
15867				method: "post",
15868				success: function(data) {
15869					var queryString = buildQueryStringForMediaLibraryFilter(vm.SearchParams.query,
15870						vm.SearchParams.fileTypes,
15871						vm.SearchParams.tags,
15872						vm.SearchParams.lang,
15873						vm.SearchParams.startDate,
15874						vm.SearchParams.endDate);
15875					if (window.history && window.history.pushState) {
15876						window.history.replaceState(null, "", location.protocol + "//" + location.host + location.pathname + queryString);
15877					} else {
15878						window.location.href = location.protocol + "//" + location.host + location.pathname + "#" + queryString;
15879					}
15880
15881					if (!skipAllMaterials || isPaging) {
15882						vm.ClearMaterials();
15883					}
15884					vm.AddMaterials(data.Items);
15885					vm.AllMaterialsCount(data.Count);
15886					$.createDownloadPopover($mediaLibrary);
15887
15888					requiredModules.targeting.ReattachEvents();
15889					$('.infoblock-grey_promo h2').dotdotdot();
15890				},
15891				traditional: true,
15892				cache: false
15893			}).fail(function() {
15894				$.fancyboxMessage(GlobalSettings.ErrorMessages.AjaxErrorMessage);
15895			}).always(function() {
15896				vm.LoadingInProcess(false);
15897			});
15898		}
15899	};
15900
15901	var resetFilter = function($mediaLibrary) {
15902		$mediaLibrary.find(settings.queryInputSelector).val("");
15903		$.resetDatePickerValue($mediaLibrary.find(settings.startDateSelector));
15904		$.resetDatePickerValue($mediaLibrary.find(settings.endDateSelector));
15905	};
15906
15907	var fillMultiselector = function($data, values) {
15908		$data.parent().removeClass("disabled");
15909		$data.find("li").hide();
15910		values.map(function(item) {
15911			$data.find("input[data-val = " + item + "]").parents('li').show();
15912		});
15913	}
15914
15915	var updateFilterData = function($mediaLibraries, tagsData) {
15916		var $tagsContainers = $mediaLibraries.find(".tags-data");
15917		var $themeMultiselect = $mediaLibraries.find(settings.themeSelector);
15918		var $countryMultiselect = $mediaLibraries.find(settings.countrySelector);
15919		var $regionMultiselect = $mediaLibraries.find(settings.regionSelector);
15920		var $projectMultiselect = $mediaLibraries.find(settings.projectSelector);
15921		var $industryMultiselect = $mediaLibraries.find(settings.industrySelector);
15922		var $personMultiselect = $mediaLibraries.find(settings.personSelector);
15923		var $languageMultiselect = $mediaLibraries.find(settings.languageSelector);
15924		var $fileTypeMultiselect = $mediaLibraries.find(settings.fileTypeSelector);
15925
15926		if ($tagsContainers && $tagsContainers.length > 0) {
15927			var $container = $($tagsContainers[0]);
15928			var data = JSON.parse($container.text() || $container.html());
15929
15930			var compatibleThemeValues = [];
15931			var compatibleCountryValues = [];
15932			var compatibleRegionValues = [];
15933			var compatibleProjectValues = [];
15934			var compatibleIndustryValues = [];
15935			var compatiblePersonValues = [];
15936			var compatibleLanguageValues = [];
15937			var compatibleTypeValues = [];
15938			if (data != null && data.Items != null) {
15939				data.Items.map(function(item) {
15940					if ((tagsData.theme.length == 0 || tagsData.theme.indexOf(item.theme) != -1) &&
15941						(tagsData.language.length == 0 || tagsData.language.indexOf(item.language) != -1) &&
15942						(tagsData.country.length == 0 || tagsData.country.indexOf(item.country) != -1) &&
15943						(tagsData.region.length == 0 || tagsData.region.indexOf(item.region) != -1) &&
15944						(tagsData.project.length == 0 || tagsData.project.indexOf(item.project) != -1) &&
15945						(tagsData.industry.length == 0 || tagsData.industry.indexOf(item.industry) != -1) &&
15946						(tagsData.person.length == 0 || tagsData.person.indexOf(item.person) != -1) &&
15947						(tagsData.type.length == 0 || tagsData.type.indexOf(item.type) != -1)) {
15948						if (compatibleThemeValues.indexOf(item.theme) == -1 && item.theme != null)
15949							compatibleThemeValues.push(item.theme);
15950						if (compatibleCountryValues.indexOf(item.country) == -1 && item.country != null)
15951							compatibleCountryValues.push(item.country);
15952						if (compatibleRegionValues.indexOf(item.region) == -1 && item.region != null)
15953							compatibleRegionValues.push(item.region);
15954						if (compatibleProjectValues.indexOf(item.project) == -1 && item.project != null)
15955							compatibleProjectValues.push(item.project);
15956						if (compatibleIndustryValues.indexOf(item.industry) == -1 && item.industry != null)
15957							compatibleIndustryValues.push(item.industry);
15958						if (compatiblePersonValues.indexOf(item.person) == -1 && item.person != null)
15959							compatiblePersonValues.push(item.person);
15960						if (compatibleLanguageValues.indexOf(item.language) == -1 && item.language != null)
15961							compatibleLanguageValues.push(item.language);
15962						if (compatibleTypeValues.indexOf(item.type) == -1 && item.type != null)
15963							compatibleTypeValues.push(item.type);
15964					}
15965				});
15966			}
15967			if (compatibleThemeValues.length > 0 && tagsData.theme.length == 0) {
15968				fillMultiselector($themeMultiselect, compatibleThemeValues);
15969			} else if (tagsData.theme.length == 0) {
15970				$themeMultiselect.parent().addClass("disabled");
15971			}
15972			if (compatibleCountryValues.length > 0 && tagsData.country.length == 0) {
15973				fillMultiselector($countryMultiselect, compatibleCountryValues);
15974			} else if (tagsData.country.length == 0) {
15975				$countryMultiselect.parent().addClass("disabled");
15976			}
15977			if (compatibleRegionValues.length > 0 && tagsData.region.length == 0) {
15978				fillMultiselector($regionMultiselect, compatibleRegionValues);
15979			} else if (tagsData.region.length == 0) {
15980				$regionMultiselect.parent().addClass("disabled");
15981			}
15982			if (compatiblePersonValues.length > 0 && tagsData.person.length == 0) {
15983				fillMultiselector($personMultiselect, compatiblePersonValues);
15984			} else if (tagsData.person.length == 0) {
15985				$personMultiselect.parent().addClass("disabled");
15986			}
15987			if (compatibleProjectValues.length > 0 && tagsData.project.length == 0) {
15988				fillMultiselector($projectMultiselect, compatibleProjectValues);
15989			} else if (tagsData.project.length == 0) {
15990				$projectMultiselect.parent().addClass("disabled");
15991			}
15992			if (compatibleIndustryValues.length > 0 && tagsData.industry.length == 0) {
15993				fillMultiselector($industryMultiselect, compatibleIndustryValues);
15994			} else if (tagsData.industry.length == 0) {
15995				$industryMultiselect.parent().addClass("disabled");
15996			}
15997			if (compatibleLanguageValues.length > 0 && tagsData.language.length == 0) {
15998				fillMultiselector($languageMultiselect, compatibleLanguageValues);
15999			} else if (tagsData.language.length == 0) {
16000				$languageMultiselect.parent().addClass("disabled");
16001			}
16002			if (compatibleTypeValues.length > 0 && tagsData.type.length == 0) {
16003				fillMultiselector($fileTypeMultiselect, compatibleTypeValues);
16004			} else if (tagsData.type.length == 0) {
16005				$fileTypeMultiselect.parent().addClass("disabled");
16006			}
16007			settings.languageGuids = compatibleLanguageValues;
16008		}
16009	}
16010
16011	var getValues = function ($data, array){
16012		var $ms = $data.getValFromMultiSelect();
16013		if ($ms != null) {
16014			$ms.map(function(item) {
16015				array.push(item.value);
16016			});
16017		}
16018	}
16019
16020	var onChangeFilter = function($mediaLibraries) {
16021		var $themeMultiselect = $mediaLibraries.find(settings.themeSelector);
16022		var $countryMultiselect = $mediaLibraries.find(settings.countrySelector);
16023		var $regionMultiselect = $mediaLibraries.find(settings.regionSelector);
16024		var $projectMultiselect = $mediaLibraries.find(settings.projectSelector);
16025		var $industryMultiselect = $mediaLibraries.find(settings.industrySelector);
16026		var $personMultiselect = $mediaLibraries.find(settings.personSelector);
16027		var $languageMultiselect = $mediaLibraries.find(settings.languageSelector);
16028		var $fileTypeMultiselect = $mediaLibraries.find(settings.fileTypeSelector);
16029
16030		var tagsData = {
16031			theme: [],
16032			language: [],
16033			country: [],
16034			region: [],
16035			project: [],
16036			industry: [],
16037			person: [],
16038			type: []
16039		};
16040
16041		if ($themeMultiselect.getValFromMultiSelect().length > 0)
16042			getValues($themeMultiselect, tagsData.theme);
16043		if ($countryMultiselect.getValFromMultiSelect().length > 0)
16044			getValues($countryMultiselect, tagsData.country);
16045		if ($regionMultiselect.getValFromMultiSelect().length > 0)
16046			getValues($regionMultiselect, tagsData.region);
16047		if ($projectMultiselect.getValFromMultiSelect().length > 0)
16048			getValues($projectMultiselect, tagsData.project);
16049		if ($industryMultiselect.getValFromMultiSelect().length > 0)
16050			getValues($industryMultiselect, tagsData.industry);
16051		if ($personMultiselect.getValFromMultiSelect().length > 0)
16052			getValues($personMultiselect, tagsData.person);
16053		if ($languageMultiselect.getValFromMultiSelect().length > 0)
16054			getValues($languageMultiselect, tagsData.language);
16055		if ($fileTypeMultiselect.getValFromMultiSelect().length > 0)
16056			getValues($fileTypeMultiselect, tagsData.type);
16057
16058		updateFilterData($mediaLibraries, tagsData);
16059
16060		if (tagsData.country.length > 0) {
16061			$regionMultiselect.parent().addClass("disabled");
16062		}
16063	}
16064
16065	function MediaLibraryResultViewModel(id) {
16066		var self = this;
16067
16068		self.Skipped = ko.observable(0);
16069		self.Id = id;
16070		self.SearchParams = undefined;
16071		self.AllMaterialsCount = ko.observable(0);
16072		self.Materials = ko.observableArray([]);
16073		self.LoadingInProcess = ko.observable(false);
16074		self.ShowPaginationButtons = ko.observable(true);
16075
16076		self.AddMaterials = function(materials) {
16077			if (materials && materials.length) {
16078				_.each(materials,
16079					function(material) {
16080						material.PreviewUrl = null;
16081						if (material.MediaFileId) {
16082							material.PreviewUrl = material.MediaLibraryPreviewFile ? material.MediaLibraryPreviewFile.FileUrl : null;
16083							material.FileSizeText = material.File.FileSizeText;
16084
16085							material.DownloadLabel = GlobalSettings.MediaLibrary.DownloadLabel +
16086								", " +
16087								material.File.FileExtension +
16088								" (" +
16089								material.FileSizeText +
16090								")";
16091						} else {
16092							material.MediaFileId = null;
16093							if (material.PreviewFiles && material.PreviewFiles.length) {
16094								var preview = _.find(material.PreviewFiles,
16095									function(file) {
16096										return file.PreviewType === Constants.previewTypes.MediaLibrary;
16097									});
16098
16099								if (preview) {
16100									material.PreviewUrl = preview.FileUrl;
16101								}
16102							}
16103						}
16104
16105						material.TagsData = null;
16106					});
16107
16108				ko.utils.arrayPushAll(self.Materials, materials);
16109
16110				self.AllMaterialsCount(self.Materials().length);
16111			}
16112		};
16113
16114		self.IsActivePage = function (value) {
16115			//console.log(value, self.LoadedPages(), $.inArray(value, self.LoadedPages()));
16116			return $.inArray(value, self.LoadedPages()) >= 0;
16117		}
16118
16119		ko.PaginationViewModel.call(self,
16120			Constants.MediaLibraryPageSize,
16121			self.AllMaterialsCount,
16122			settings.mediaLibraryWidgetSelector,
16123			loadMaterials);
16124
16125		self.ClearMaterials = function() {
16126			self.Materials.removeAll();
16127			self.AllMaterialsCount(0);
16128		};
16129	}
16130
16131	var prepareMediaLibraryWidgets = function() {
16132		var $mediaLibraries = $(settings.mediaLibraryWidgetSelector);
16133		_.each($mediaLibraries,
16134			function(mediaLibrary, index) {
16135				try {
16136					var $mediaLibrary = $(mediaLibrary);
16137					var $datePickers = $mediaLibrary.find(settings.datepickerSelector);
16138					_.each($datePickers,
16139						function(picker) {
16140							var $picker = $(picker);
16141							var initialDate = $picker.data("initialvalue");
16142							if (initialDate) {
16143								$picker.val($.datepicker.formatDate($picker.datepicker("option", "dateFormat"), moment(initialDate).toDate()));
16144							}
16145						});
16146
16147					$mediaLibrary.find(".field-autocomplete").autocomplete({
16148						delay: 500,
16149						source: [],
16150						open: function(event, ui) {
16151							$('.ui-autocomplete').width($(event.target).innerWidth());
16152						}
16153					}).on("keyup", function() {
16154						var $input = $(this);
16155						$.ajax({
16156							url: settings.getTagsUrl,
16157							data: {
16158								query: $input.val().encodeURIComponent(),
16159								lang: $mediaLibrary.data("lang")
16160							},
16161							method: "get",
16162							success: function(data) {
16163								if (data && data.length) {
16164									$input.autocomplete("option", "source", data);
16165								}
16166							},
16167							traditional: true,
16168							cache: false
16169						});
16170					});
16171
16172					var $regionsSelect = $mediaLibrary.find(settings.regionSelector);
16173					var $countrySelect = $mediaLibrary.find(settings.countrySelector);
16174					var russiaGuid = $mediaLibrary.data("russia-guid");
16175
16176					$mediaLibrary.updateSelectStateByValueInAnother($countrySelect, russiaGuid);
16177					$mediaLibrary.find(settings.countrySelector).on("change",
16178						"input",
16179						function() {
16180							$regionsSelect.updateSelectStateByValueInAnother($countrySelect, russiaGuid);
16181						});
16182
16183					onChangeFilter($mediaLibraries);
16184					$mediaLibraries.find(settings.themeSelector).find("input").on('change',
16185						function() {
16186							onChangeFilter($mediaLibraries);
16187						});
16188					$mediaLibraries.find(settings.countrySelector).find("input").on('change',
16189						function() {
16190							onChangeFilter($mediaLibraries);
16191						});
16192					$mediaLibraries.find(settings.regionSelector).find("input").on('change',
16193						function() {
16194							onChangeFilter($mediaLibraries);
16195						});
16196					$mediaLibraries.find(settings.projectSelector).find("input").on('change',
16197						function() {
16198							onChangeFilter($mediaLibraries);
16199						});
16200					$mediaLibraries.find(settings.industrySelector).find("input").on('change',
16201						function() {
16202							onChangeFilter($mediaLibraries);
16203						});
16204					$mediaLibraries.find(settings.personSelector).find("input").on('change',
16205						function() {
16206							onChangeFilter($mediaLibraries);
16207						});
16208					$mediaLibraries.find(settings.languageSelector).find("input").on('change',
16209						function() {
16210							onChangeFilter($mediaLibraries);
16211						});
16212					$mediaLibraries.find(settings.fileTypeSelector).find("input").on('change',
16213						function() {
16214							onChangeFilter($mediaLibraries);
16215						});
16216
16217					var resultsVm = new MediaLibraryResultViewModel(index);
16218
16219					updateSearchParams(resultsVm, $mediaLibrary);
16220					$('.infoblock-grey_promo h2').dotdotdot();
16221
16222					$mediaLibrary.find(settings.filterForm).on("submit", function() { return false; });
16223					$mediaLibrary.find(settings.mediaLibraryFilterBtnSelector).on("click", function() {
16224						resultsVm.LoadedPages.removeAll();
16225						resultsVm.CurrentPage(1);
16226						loadMaterials(resultsVm, $mediaLibrary, 0, false);
16227					});
16228					$mediaLibrary.find(settings.resetButtonSelector).on("click", function() {
16229						resetFilter($mediaLibrary);
16230					});
16231					$mediaLibrary.on("click",
16232						settings.loadMoreButtonSelector,
16233						function() {
16234							var page = resultsVm.CurrentPage();
16235							resultsVm.CurrentPage(page + 1);
16236							resultsVm.LoadedPages.push(page);
16237							loadMaterials(resultsVm, $mediaLibrary, page * resultsVm.PageSize(), false);
16238						});
16239
16240					var meterialsData = null;
16241					var $jsonContainers = $mediaLibrary.find(settings.mediaLibraryJsonContainerSelector);
16242					if ($jsonContainers && $jsonContainers.length > 0) {
16243						var $jsonContainer = $($jsonContainers[0]);
16244						meterialsData = JSON.parse($jsonContainer.text() || $jsonContainer.html());
16245						
16246						resultsVm.Skipped(meterialsData.Skipped);
16247						resultsVm.CurrentPage(Math.floor(resultsVm.Skipped() / resultsVm.PageSize()) + 1);
16248						
16249						resultsVm.AddMaterials(meterialsData.Items);
16250						resultsVm.AllMaterialsCount(meterialsData.Count);
16251					}
16252					if (!meterialsData || !meterialsData.Items.length) {
16253						$mediaLibrary.remove();
16254					} else {
16255						var resultContainer = $mediaLibrary.find(settings.mediaLibraryResultsSelector)[0];
16256						ko.cleanNode(resultContainer);
16257						updateSearchParams(resultsVm, $mediaLibrary);
16258						var widgetGuid = $mediaLibrary.attr("data-widgetguid");
16259						$(".server-rendered-" + widgetGuid).remove();
16260						ko.applyBindings(resultsVm, resultContainer);
16261						$.createDownloadPopover($mediaLibrary);
16262					}
16263
16264				} catch (e) {
16265					if (window.console && window.console.log) {
16266						console.log("Failed to render Media library widget #" + (index + 1));
16267					}
16268				}
16269			});
16270		requiredModules.targeting.ReattachEvents();
16271	};
16272
16273	var updateFileInfo = function($mediaAlbum, selectedIndex) {
16274		_.each($mediaAlbum.find(".media-file-buttons"),
16275			function(info) {
16276				var $info = $(info);
16277				if ($info.data("index-item") === selectedIndex) {
16278					$info.show();
16279				} else {
16280					$info.hide();
16281				}
16282			});
16283	};
16284
16285	var prepareMediaAlbumWidgets = function() {
16286		var $mediaAlbums = $(settings.mediaAlbumWidgetSelector);
16287
16288		// remove last item in breadcrumbs
16289		if ($mediaAlbums.length) {
16290			$(".breadcrumb .active").remove();
16291		}
16292
16293		_.each($mediaAlbums,
16294			function(mediaAlbum, index) {
16295				try {
16296					var $mediaAlbum = $(mediaAlbum);
16297					var $thumbs = $mediaAlbum.find(".photo-album-thumb");
16298					if ($thumbs.length < 2) {
16299						$mediaAlbum.find(".photo-album-thumbs").hide();
16300					}
16301					var selectedIndex = $mediaAlbum.find(".photo-album-thumb.selected").data("index-item");
16302					updateFileInfo($mediaAlbum, selectedIndex);
16303					$mediaAlbum.on("click",
16304						".owl-item",
16305						function() {
16306							var n = $(this).index();
16307							updateFileInfo($mediaAlbum, n);
16308						});
16309				} catch (e) {
16310					if (window.console && window.console.log) {
16311						console.log("Failed to render media album widget #" + (index + 1));
16312					}
16313				}
16314			});
16315	};
16316
16317	var preparePhotoRibbon = function() {
16318		var updateRibbonImages = function ($ribbon) {
16319			var $images = $ribbon.find("img");
16320
16321			if ($images.length) {
16322				var countPhoto = $images.length;
16323				var images, maxHeight, targetQuantifier, targetHeight;
16324				var ribbonWidth = $ribbon.width();
16325				var showAsCarousel = $ribbon.data("carousel");
16326				if (showAsCarousel) {
16327					var htmlWidth = $("html").width();
16328					var size = htmlWidth >= 768 ? 3 : htmlWidth >= 450 ? 2 : 1;
16329
16330					if (size > 1) {
16331						var $imagesTopN = $images.filter(":lt(" + size + ")");
16332
16333						images = _.map($images,
16334							function(image) {
16335								var $image = $(image);
16336								return {
16337									$el: $image,
16338									height: $image.data("height"),
16339									width: $image.data("width")
16340								}
16341							});
16342
16343						var imagesTopN = _.map($imagesTopN,
16344							function(image) {
16345								var $image = $(image);
16346								return {
16347									$el: $image,
16348									height: $image.data("height"),
16349									width: $image.data("width")
16350								}
16351							});
16352
16353						maxHeight = _.max(imagesTopN,
16354							function(image) {
16355								return image.height;
16356							}).height;
16357
16358						_.each(images,
16359							function(image) {
16360								var quantifier = maxHeight / image.height;
16361								image.height = maxHeight;
16362								image.width *= quantifier;
16363							});
16364
16365						var totalImagesWidthTopN = _.reduce(imagesTopN,
16366							function(memo, image) {
16367								return memo + image.width;
16368							}, 0);
16369
16370						var totalGapTopN = (size - 1) * 10;
16371
16372						targetQuantifier = totalImagesWidthTopN / (ribbonWidth - totalGapTopN);
16373						targetHeight = maxHeight / targetQuantifier;
16374
16375						if (targetHeight > settings.photoRibbonMaxHeight) {
16376							targetQuantifier *= targetHeight / settings.photoRibbonMaxHeight;
16377						}
16378
16379						_.each(images,
16380							function(image, index) {
16381								image.$el.css("width", Math.floor(image.width / targetQuantifier));
16382								image.$el.css("border", 0);
16383							});
16384					} else {
16385						$.each($images, function() {
16386							$(this).css("width", "100%");
16387						});
16388					}
16389
16390					var $car = $ribbon.find(".panel-body").lukOwlCarousel({
16391						nav: true,
16392						navRewind: false,
16393						dots: false,
16394						margin: 10,
16395						autoWidth: size > 1,
16396						//loop: true, 
16397						loop: countPhoto > size,
16398						responsive: {
16399							0: {
16400								slideBy: 1,
16401								items: 1
16402							},
16403							450: {
16404								slideBy: 2,
16405								items: 2
16406							},
16407							768: {
16408								slideBy: 1,
16409								items: countPhoto >= 3 ? 3 : countPhoto
16410							}
16411						},
16412						onResized: function(event) {
16413							$car.owlCarousel('destroy');
16414							updateRibbonImages($ribbon);
16415						}
16416					});
16417				} else {
16418					var gapInPercents = $ribbon.data("gap");
16419					images = _.map($images,
16420						function(image) {
16421							var $image = $(image);
16422							return {
16423								$el: $image,
16424								height: $image.data("height"),
16425								width: $image.data("width")
16426							}
16427						});
16428
16429					maxHeight = _.max(images,
16430						function(image) {
16431							return image.height;
16432						}).height;
16433
16434					_.each(images,
16435						function(image) {
16436							var quantifier = maxHeight / image.height;
16437							image.height = maxHeight;
16438							image.width *= quantifier;
16439						});
16440
16441					var totalImagesWidth = _.reduce(images,
16442						function(memo, image) {
16443							return memo + image.width;
16444						}, 0);
16445
16446					var gapBetweenImages = ribbonWidth * gapInPercents / 100;
16447					var totalGap = (images.length - 1) * gapBetweenImages;
16448
16449					targetQuantifier = totalImagesWidth / (ribbonWidth - totalGap);
16450					targetHeight = maxHeight / targetQuantifier;
16451
16452					var ribbonLeftPadding = null;
16453					if (targetHeight > settings.photoRibbonMaxHeight) {
16454						targetQuantifier *= targetHeight / settings.photoRibbonMaxHeight;
16455						var targetTotalImagesWidth = totalImagesWidth / targetQuantifier;
16456						ribbonLeftPadding = (ribbonWidth - totalGap - targetTotalImagesWidth) / 2;
16457					}
16458
16459					_.each(images,
16460						function(image, index) {
16461							image.$el.css("width", Math.floor(image.width / targetQuantifier));
16462							image.$el.css("border", 0);
16463							if (index) {
16464								image.$el.css("margin-left", Math.floor(gapBetweenImages));
16465							}
16466						});
16467
16468					if (ribbonLeftPadding) {
16469						$ribbon.css("padding-left", ribbonLeftPadding);
16470					}
16471				}
16472			}
16473		}
16474
16475		_.each($(settings.photoRibbonSelector),
16476			function(ribbon, index) {
16477				try {
16478					var $ribbon = $(ribbon);
16479
16480					updateRibbonImages($ribbon);
16481					$(window).on('resize',
16482						function() {
16483							updateRibbonImages($ribbon);
16484						});
16485				} catch (e) {
16486					if (window.console && window.console.log) {
16487						console.log("Failed to render photo ribbon widget #" + (index + 1));
16488					}
16489				}
16490			});
16491	};
16492
16493	MediaLibrary.run = function() {
16494		prepareMediaLibraryWidgets();
16495		prepareMediaAlbumWidgets();
16496		preparePhotoRibbon();
16497	};
16498});;
16499LukoilApp.module("OilCatalog", function (OilCatalog, LukoilApp, Backbone, Marionette, $, _) {
16500    "use strict";
16501
16502    var settings = {
16503        oilListWidgetSelector: ".oil-list-widget",
16504        oilInfoPageWidgetSelector: ".oil-information",
16505        loadMoreButtonSelector: ".load-more-button",
16506        loadAllButtonSelector: ".load-all-button",
16507        listFilterBtnSelector: ".filter-btn",
16508        resultsContainerSelector: ".oil-list-results",
16509        getProductsUrl: "/api/oilcatalog/products",
16510        resetButtonSelector: ".button-reset",
16511        queryInputSelector: ".filter_lukoil-oil input[type=text]",
16512
16513        applicationSelector: ".application-select",
16514        typeSelector: ".typeid-select",
16515        viscositySelector: ".viscosity-select"
16516    }
16517
16518    var totalSkip = 0;
16519    var totalTake = 0;
16520
16521    var updateSearchParams = function (vm, $widget, needReload = false) {
16522        vm.SearchParams = {
16523            langGuid: $widget.data("lang"),
16524            countryId: $widget.data("country"),
16525            categoryId: $widget.data("category"),
16526            take: Constants.OilCatalogPageSize,
16527            filterParams: {}
16528        };
16529
16530
16531        var $filter = $widget.find(".filter");
16532        if ($filter.length) {
16533            var query = "";
16534
16535            _.each($filter.find(".dropdown-menu"),
16536                function (select) {
16537                    var $select = $(select);
16538                    var paramName = $select.data("param");
16539                    var values = _.filter(_.map($select.getValFromMultiSelect(), "value"), function (val) {
16540                        return val !== "";
16541                    });
16542
16543                    var filters = _.filter(_.map($select.getFilterFromMultiSelect(), "value"), function (val) {
16544                        return val !== "";
16545                    });
16546
16547                    vm.SearchParams.filterParams[paramName] = values.join("_");
16548                    var jn = filters.join("-or-");
16549                    if (jn != "")
16550                        query += "/" + jn;
16551                });
16552
16553            _.each($filter.find(".search-control"),
16554                function (search) {
16555                    var $search = $(search);
16556                    var paramName = $search.data("param");
16557                    var value = $search.val();
16558                    vm.SearchParams.filterParams[paramName] = value ? value.encodeURIComponent() : value;
16559                });
16560
16561            _.each($filter.find(".filter-checkbox .checkbox-custom"),
16562                function (checkbox) {
16563                    var $checkbox = $(checkbox);
16564                    var paramName = $checkbox.data("param");
16565                    vm.SearchParams.filterParams[paramName] = $checkbox.is(":checked");
16566                });
16567
16568            var $tabContainer = $widget.find(".nav-tabs");
16569            if ($tabContainer.length) {
16570                var paramName = $tabContainer.data("param");
16571                var activeTab = $tabContainer.find(".active a");
16572
16573                if (activeTab.length) {
16574                    vm.SearchParams.filterParams[paramName] = activeTab.data("val");
16575                    var tn = activeTab.data("filter");
16576                    if (typeof tn !== "undefined" && tn != "")
16577                        query += "/" + tn;
16578                }
16579            }
16580            if (!needReload) {
16581                window.history.replaceState("string", "Oils", baseUrl.replace(/\/+$/, '') + "/" + query.replace(/\/+$/, '').replace(/^\/+/, '') + window.location.hash);
16582            }
16583            else {
16584                window.location.replace(baseUrl.replace(/\/+$/, '') + "/" + query.replace(/\/+$/, '').replace(/^\/+/, '') + window.location.hash);
16585            }
16586            
16587            //applyTitleAndDescriptionIfRussian();
16588        }
16589    }
16590
16591    var fillMultiselector = function ($data, values) {
16592        $data.parent().removeClass("disabled");
16593        $data.find("li").hide();
16594        values.map(function (item) {
16595            $data.find("input[data-val = " + item + "]").parents('li').show();
16596        });
16597    }
16598
16599    var updateFilterData = function ($widget, tagsData) {
16600        var $tagsContainers = $widget.find(".tags-data");
16601        var $applicationMultiselect = $widget.find(settings.applicationSelector);
16602        var $typeMultiselect = $widget.find(settings.typeSelector);
16603        var $viscosityMultiselect = $widget.find(settings.viscositySelector);
16604
16605        if ($tagsContainers && $tagsContainers.length > 0) {
16606            var $container = $($tagsContainers[0]);
16607            var data = JSON.parse($container.text() || $container.html());
16608
16609            var compatibleAppValues = [];
16610            var compatibleTypeValues = [];
16611            var compatibleViscosityValues = [];
16612            if (data != null && data.Items != null) {
16613                data.Items.map(function (item) {
16614                    if ((tagsData.application.length == 0 || tagsData.application.indexOf(item.application) != -1) &&
16615                        (tagsData.type.length == 0 || tagsData.type.indexOf(item.type) != -1) &&
16616                        (tagsData.viscosity.length == 0 || tagsData.viscosity.indexOf(item.viscosity) != -1)) {
16617                        if (compatibleAppValues.indexOf(item.application) == -1 && item.application != 0)
16618                            compatibleAppValues.push(item.application);
16619                        if (compatibleTypeValues.indexOf(item.type) == -1 && item.type != 0)
16620                            compatibleTypeValues.push(item.type);
16621                        if (compatibleViscosityValues.indexOf(item.viscosity) == -1 && item.viscosity != 0)
16622                            compatibleViscosityValues.push(item.viscosity);
16623                    }
16624                });
16625            }
16626            if ($applicationMultiselect.length > 0 && compatibleAppValues.length > 0 && tagsData.application.length == 0) {
16627                fillMultiselector($applicationMultiselect, compatibleAppValues);
16628            } else if (tagsData.application.length == 0) {
16629                $applicationMultiselect.parent().addClass("disabled");
16630            }
16631            if ($typeMultiselect.length > 0 && compatibleTypeValues.length > 0 && tagsData.type.length == 0) {
16632                fillMultiselector($typeMultiselect, compatibleTypeValues);
16633            } else if (tagsData.type.length == 0) {
16634                $typeMultiselect.parent().addClass("disabled");
16635            }
16636            if ($viscosityMultiselect.length > 0 && compatibleViscosityValues.length > 0 && tagsData.viscosity.length == 0) {
16637                fillMultiselector($viscosityMultiselect, compatibleViscosityValues);
16638            } else if (tagsData.viscosity.length == 0) {
16639                $viscosityMultiselect.parent().addClass("disabled");
16640            }
16641        }
16642    }
16643
16644    var getValues = function ($data, array) {
16645        var $ms = $data.getValFromMultiSelect();
16646        if ($ms != null) {
16647            $ms.map(function (item) {
16648                array.push(item.value);
16649            });
16650        }
16651    }
16652
16653    var onChangeFilter = function ($widget) {
16654        var $applicationMultiselect = $widget.find(settings.applicationSelector);
16655        var $typeMultiselect = $widget.find(settings.typeSelector);
16656        var $viscosityMultiselect = $widget.find(settings.viscositySelector);
16657
16658        var tagsData = {
16659            application: [],
16660            type: [],
16661            viscosity: []
16662        };
16663
16664        if ($applicationMultiselect.length > 0 && $applicationMultiselect.getValFromMultiSelect().length > 0)
16665            getValues($applicationMultiselect, tagsData.application);
16666        if ($typeMultiselect.length > 0 && $typeMultiselect.getValFromMultiSelect().length > 0)
16667            getValues($typeMultiselect, tagsData.type);
16668        if ($viscosityMultiselect.length > 0 && $viscosityMultiselect.getValFromMultiSelect().length > 0)
16669            getValues($viscosityMultiselect, tagsData.viscosity);
16670
16671        updateFilterData($widget, tagsData);
16672    }
16673
16674    var loadProducts = function (vm, $widget, skip, isPaging, take) {
16675        if (!vm.LoadingInProcess()) {
16676            if (!skip || take) {
16677                updateSearchParams(vm, $widget);
16678            }
16679
16680            vm.LoadingInProcess(true);
16681
16682            var data = vm.SearchParams;
16683            data.skip = skip;
16684
16685            _.extend(data, data.filterParams);
16686            var filterParams = data.filterParams;
16687            data.filterParams = undefined;
16688
16689            if (take) {
16690                data.take = take;
16691            }
16692
16693            $.ajax({
16694                url: settings.getProductsUrl,
16695                data: data,
16696                method: "post",
16697                success: function (data) {
16698                    if (!skip || isPaging) {
16699                        vm.ClearReleases();
16700                        totalSkip = skip;
16701                    }
16702
16703                    data = JSON.parse(data);
16704
16705                    vm.AddProducts(data.Items);
16706                    vm.AllProductCount(data.Count);
16707
16708                    totalTake = vm.Products().length;
16709
16710                    if (window.location.search.includes("take=")) {
16711                        if (totalTake == 9 && totalSkip == 0) {
16712                            history.pushState(null, '', window.location.pathname);
16713                        } else
16714                            if (window.location.search != ("?take=" + totalTake + "&skip=" + totalSkip) && 'URLSearchParams' in window) {
16715                                var searchParams = new URLSearchParams(window.location.search)
16716                                searchParams.set("take", totalTake);
16717                                searchParams.set("skip", totalSkip);
16718                                var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString();
16719                                history.pushState(null, '', newRelativePathQuery);
16720                            }
16721                    }
16722                    else {
16723                        if (totalTake <= 9 && totalSkip == 0) {
16724                            history.pushState(null, '', window.location.pathname);
16725                        }
16726                        else
16727                            window.location.hash = "take=" + totalTake + "&skip=" + totalSkip;
16728                    }
16729
16730
16731                    $.createDownloadPopover($widget);
16732                    applyTitleAndDescriptionIfRussian();
16733                    vm.ShowPaginationButtons(data.Count > totalTake);
16734                },
16735                traditional: true,
16736                cache: false
16737            }).fail(function () {
16738                $.fancyboxMessage(GlobalSettings.ErrorMessages.AjaxErrorMessage);
16739            }).always(function () {
16740                vm.LoadingInProcess(false);
16741            });
16742        }
16743    };
16744
16745    var loadAllProducts = function (vm, $widget) {
16746        if (!vm.LoadingInProcess()) {
16747            updateSearchParams(vm, $widget);
16748
16749            vm.LoadingInProcess(true);
16750
16751            var data = vm.SearchParams;
16752
16753            _.extend(data, data.filterParams);
16754            var filterParams = data.filterParams;
16755            data.filterParams = undefined;
16756            data.take = undefined;
16757
16758            $.ajax({
16759                url: settings.getProductsUrl,
16760                data: data,
16761                method: "post",
16762                success: function (data) {
16763                    vm.ClearReleases();
16764
16765                    data = JSON.parse(data);
16766
16767                    vm.AddProducts(data.Items);
16768                    vm.AllProductCount(data.Count);
16769
16770                    if (!window.location.hash.toLowerCase().includes('loadall'))
16771                        window.location.hash = 'loadAll=true';
16772
16773                    $.createDownloadPopover($widget);
16774
16775                    vm.ShowPaginationButtons(false);
16776                },
16777                traditional: true,
16778                cache: false
16779            }).fail(function () {
16780                $.fancyboxMessage(GlobalSettings.ErrorMessages.AjaxErrorMessage);
16781            }).always(function () {
16782                vm.LoadingInProcess(false);
16783            });
16784        }
16785    };
16786
16787    var OilListViewModel = function (index) {
16788        var self = this;
16789
16790        self.Skipped = ko.observable(0);
16791        self.ProductCount = ko.observable(0);
16792        self.AllProductCount = ko.observable(0);
16793        self.Products = ko.observableArray([]);
16794        self.LoadingInProcess = ko.observable(false);
16795
16796        self.CanLoadMore = ko.computed(function () {
16797            return !self.LoadingInProcess() && self.AllProductCount() > self.ProductCount();
16798        });
16799
16800        self.ShowPaginationButtons = ko.observable(true);
16801
16802        self.AddProducts = function (products) {
16803            _.each(products,
16804                function (product) {
16805                    if (!product.ListImage) {
16806                        product.ListImage = GlobalSettings.CurrentLanguage === "ru" ? "/Content/img/barrel-ru-210-220.png" : "/Content/img/barrel-eng-210-220.png";
16807                    }
16808
16809                    self.Products.push(product);
16810                });
16811
16812            self.ProductCount(self.Products().length);
16813        }
16814
16815        self.IsActivePage = function (value) {
16816            return $.inArray(value, self.LoadedPages()) >= 0;
16817        }
16818
16819        if (window.location.hash.includes("loadAll=true")) {
16820            ko.PaginationViewModel.call(self, Constants.OilCatalogPageSize, self.AllProductCount, settings.oilListWidgetSelector, loadAllProducts);
16821        } else {
16822            ko.PaginationViewModel.call(self, Constants.OilCatalogPageSize, self.AllProductCount, settings.oilListWidgetSelector, loadProducts);
16823        }
16824
16825        self.ClearReleases = function () {
16826            self.Products.removeAll();
16827            self.ProductCount(0);
16828        }
16829    };
16830
16831    var resetFilter = function ($widget) {
16832        $widget.find(".search-control").val("");
16833    }
16834
16835    var handleHashState = function (resultsVm, $oilListWidget) {
16836        if (window.location.hash.includes("loadAll=true")) {
16837            loadAllProducts(resultsVm, $oilListWidget);
16838        }
16839
16840        var hashSkip = 0;
16841        var hashTake = 9;
16842
16843        if (window.location.search.includes("take=")) {
16844            var uri = window.location.search.replace("?", '');
16845            var hashParams = uri.split("&");
16846            hashSkip = parseInt(hashParams.pop().replace("skip=", ""));
16847            hashTake = parseInt(hashParams.pop().replace("take=", ""));
16848        } else
16849            if (window.location.hash.includes("take=")) {
16850                var hashParams = window.location.hash.split("&");
16851                hashSkip = parseInt(hashParams.pop().replace("skip=", ""));
16852                hashTake = parseInt(hashParams.pop().replace("#take=", ""));
16853            }
16854
16855        if (hashSkip != totalSkip || hashTake != totalTake) {
16856            totalTake = hashTake;
16857            totalSkip = hashSkip;
16858            loadProducts(resultsVm, $oilListWidget, totalSkip, false, totalTake);
16859            resultsVm.ClearReleases();
16860            resultsVm.LoadedPages.removeAll();
16861            var currentPage = Math.floor((totalSkip + totalTake) / Constants.OilCatalogPageSize);
16862            if (currentPage * Constants.OilCatalogPageSize < (totalSkip + totalTake)) {
16863                currentPage += 1;
16864            }
16865
16866            var loadedPagesCount = totalTake / Constants.OilCatalogPageSize;
16867            for (var i = 1; i < loadedPagesCount; i++) {
16868                resultsVm.LoadedPages.push(currentPage - i);
16869            }
16870
16871            resultsVm.CurrentPage(currentPage);
16872        }
16873    }
16874
16875    function updateTitleAndDescription($oilListWidget) {
16876        // Сбор значений из выпадающих списков
16877        var applicationText = $oilListWidget.find(settings.applicationSelector).find("input:checked").map(function () {
16878            return $(this).next('label').text().trim().toLowerCase();
16879        }).get().join(' ');
16880
16881        var typeText = $oilListWidget.find(settings.typeSelector).find("input:checked").map(function () {
16882            return $(this).next('label').text().trim().toLowerCase();
16883        }).get().join(' ');
16884
16885        var viscosityText = $oilListWidget.find(settings.viscositySelector).find("input:checked").map(function () {
16886            return $(this).next('label').text().trim();
16887        }).get().join(' ');
16888
16889        if (window.location.pathname.toLowerCase().indexOf('/ru/products/forpassengercars') != -1) {
16890			var $tabs = $oilListWidget.find(".nav-tabs li");
16891            var isDefaultSelected = $tabs.first().hasClass("active");
16892
16893            // Установка метатега <meta name="robots">
16894            if ((applicationText && isDefaultSelected) || (isDefaultSelected && !applicationText && !typeText && !viscosityText)) {
16895                $("meta[name='robots']").remove();
16896            } else {
16897                if (!$("meta[name='robots']").length) {
16898                    $('head').append('<meta name="robots" content="noindex, nofollow">');
16899                }
16900            }
16901        } else {
16902            if ((applicationText) || (!applicationText && !typeText && !viscosityText)) {
16903                $("meta[name='robots']").remove();
16904            } else {
16905                if (!$("meta[name='robots']").length) {
16906                    $('head').append('<meta name="robots" content="noindex, nofollow">');
16907                }
16908            }
16909        }
16910    }
16911
16912    function applyTitleAndDescriptionIfRussian() {
16913        // Получаем текущий URL
16914        var currentUrl = window.location.href;
16915        // Проверяем, если текущий URL соответствует русской версии
16916        if (['/ru/products/forpassengercars', '/ru/products/forsmallengines', '/ru/products/forcommercialvehicles']
16917            .some(path => window.location.pathname.toLowerCase().indexOf(path) !== -1)) {
16918            var $oilListWidget = $(settings.oilListWidgetSelector); // Получаем виджет фильтров
16919            updateTitleAndDescription($oilListWidget); // Обновляем title и description
16920        }
16921    }
16922
16923    var prepareLists = function () {
16924        var $oilListWidgets = $(settings.oilListWidgetSelector);
16925        _.each($oilListWidgets, function (oilList, index) {
16926            try {
16927                var $oilListWidget = $(oilList);
16928
16929                var resultsVm = new OilListViewModel(index);
16930                var skipInitialLoad = false;
16931
16932                window.addEventListener('hashchange', function () {
16933                    handleHashState(resultsVm, $oilListWidget);
16934                })
16935
16936                handleHashState(resultsVm, $oilListWidget);
16937                if (window.location.hash.includes("take=") || window.location.search.includes("take=")) {
16938                    skipInitialLoad = true;
16939                }
16940
16941                $oilListWidget.find(settings.listFilterBtnSelector).on("click", function () {
16942                    //applyTitleAndDescriptionIfRussian();
16943                    resultsVm.LoadedPages.removeAll();
16944                    resultsVm.CurrentPage(1);                    
16945                    updateSearchParams(resultsVm, $oilListWidget, true);
16946                });
16947
16948                $oilListWidget.find(settings.queryInputSelector).on("keypress", function (e) {
16949                    if ((event.keyCode || event.which) == 13) {
16950                        resultsVm.LoadedPages.removeAll();
16951                        resultsVm.CurrentPage(1);
16952                        loadProducts(resultsVm, $oilListWidget, 0, false);
16953                    }
16954                });
16955
16956                $oilListWidget.on("click", settings.loadMoreButtonSelector, function () {
16957                    var page = resultsVm.CurrentPage();
16958                    resultsVm.CurrentPage(page + 1);
16959                    resultsVm.LoadedPages.push(page);
16960                    loadProducts(resultsVm, $oilListWidget, page * Constants.OilCatalogPageSize, false);
16961                });
16962
16963                $oilListWidget.on("click", settings.loadAllButtonSelector, function () {
16964                    loadAllProducts(resultsVm, $oilListWidget);
16965                });
16966
16967                onChangeFilter($oilListWidget);
16968                $oilListWidget.find(settings.applicationSelector).find("input").on('change',
16969                    function () {
16970                        onChangeFilter($oilListWidget);
16971                    });
16972                $oilListWidget.find(settings.typeSelector).find("input").on('change',
16973                    function () {
16974                        onChangeFilter($oilListWidget);
16975                    });
16976                $oilListWidget.find(settings.viscositySelector).find("input").on('change',
16977                    function () {
16978                        onChangeFilter($oilListWidget);
16979                    });
16980
16981                var tabs = $oilListWidget.find(".nav-tabs li");
16982                tabs.on("click", function () {
16983                    _.each(tabs,
16984                        function (tab) {
16985                            $(tab).removeClass("active");
16986                        });
16987
16988                    $(this).addClass("active");
16989                    resultsVm.LoadedPages.removeAll();
16990                    resultsVm.CurrentPage(1);
16991                    loadProducts(resultsVm, $oilListWidget, 0, false);
16992                });
16993
16994                $oilListWidget.find(settings.resetButtonSelector).on("click", function () {
16995                    resetFilter($oilListWidget);
16996                });
16997
16998                var productData = null;
16999                var $jsonContainers = $oilListWidget.find(".oil-data");
17000                if ($jsonContainers && $jsonContainers.length > 0) {
17001                    var $jsonContainer = $($jsonContainers[0]);
17002                    productData = JSON.parse($jsonContainer.text() || $jsonContainer.html());
17003
17004                    if (!skipInitialLoad) {
17005                        resultsVm.Skipped(productData.Skipped);
17006                        resultsVm.CurrentPage(Math.floor(resultsVm.Skipped() / resultsVm.PageSize()) + 1);
17007
17008                        resultsVm.AddProducts(productData.Items);
17009                        resultsVm.AllProductCount(productData.Count);
17010
17011                        //applyTitleAndDescriptionIfRussian();
17012                    }
17013                }
17014
17015
17016                if (!productData) {
17017                    $oilListWidget.remove();
17018                } else {
17019                    var resultContainer = $oilListWidget.find(settings.resultsContainerSelector)[0];
17020                    ko.cleanNode(resultContainer);
17021                    updateSearchParams(resultsVm, $oilListWidget);
17022                    var widgetGuid = $oilListWidget.attr("data-widget-guid");
17023                    $(".server-rendered-" + widgetGuid).remove();
17024                    ko.applyBindings(resultsVm, resultContainer);
17025                    $.createDownloadPopover($oilListWidget);
17026                }
17027            } catch (e) {
17028                if (window.console && window.console.log) { console.log("Failed to render oil list #" + (index + 1)); }
17029            }
17030        });
17031    };
17032
17033    var prepareInfoPages = function () {
17034        var $infoPages = $(settings.oilInfoPageWidgetSelector);
17035        _.each($infoPages, function (infoPage, index) {
17036            try {
17037                var $infoPage = $(infoPage);
17038                console.log($infoPage);
17039                var productName = $infoPage.data("name");
17040
17041                if (productName) {
17042                    $(".page-title h1").text(productName);
17043                    $(".breadcrumb .active span").text(productName);
17044                }
17045            } catch (e) {
17046                if (window.console && window.console.log) { console.log("Failed to render oil info page #" + (index + 1)); }
17047            }
17048        });
17049    };
17050
17051    var baseUrl;
17052
17053    var recalculateAdressString = function () {
17054        let url = document.URL
17055        if (typeof FilterUrlPart === 'undefined' || FilterUrlPart == null)
17056            baseUrl = url
17057        else
17058            baseUrl = url.substring(0, url.length - FilterUrlPart.length - window.location.hash.length)
17059        //console.log(baseUrl)
17060    }
17061
17062    OilCatalog.run = function () {
17063        recalculateAdressString();
17064        prepareLists();
17065        prepareInfoPages();
17066    };
17067
17068    OilCatalog.on("start", function (options) {
17069        OilCatalog.run();
17070    });
17071});;
17072LukoilApp.module("SeaportList", function (SeaportList, LukoilApp, Backbone, Marionette, $, _) {
17073	"use strict";
17074
17075	var settings = {
17076		widgetSelector: ".seaport-list-widget",
17077		resultsContainerSelector: ".seaport-list-results",
17078		pageSize: 10
17079	};
17080
17081	var SeaportListViewModel = function($list, index) {
17082		var self = this;
17083
17084		self.TotalCount = ko.observable(0);
17085		self.LoadedCount = ko.observable(0);
17086		self.Ports = ko.observableArray([]);
17087		self.LoadingInProcess = ko.observable(false);
17088		self.ShowPaginationButtons = ko.observable(true);
17089		self.CanLoadMore = ko.computed(function () {
17090			return !self.LoadingInProcess() && self.TotalCount() > self.LoadedCount();
17091		});
17092
17093		self.AddPorts = function(ports) {
17094			_.each(ports,
17095				function(port) {
17096					self.Ports.push(port);
17097
17098				});
17099
17100			self.LoadedCount(self.LoadedCount() + ports.length);
17101		};
17102
17103		self.ClearPorts = function() {
17104			self.Ports.removeAll();
17105			self.TotalCount(0);
17106			self.LoadedCount(0);
17107		};
17108
17109		var loadPorts = function(countryId, skip, take) {
17110			if (!self.LoadingInProcess()) {
17111				self.LoadingInProcess(true);
17112
17113				$.ajax({
17114					url: "/api/cartography/getseaports",
17115					data: {
17116						countryId: countryId === "0" ? null : countryId,
17117						skip: skip,
17118						take: take,
17119						languageCode: GlobalSettings.CurrentLanguage
17120					},
17121					method: "post",
17122					success: function (data) {
17123						if (!skip) {
17124							self.ClearPorts();
17125						}
17126
17127						self.AddPorts(data.Items);
17128
17129						self.TotalCount(data.Count);
17130					},
17131					traditional: true,
17132					cache: false
17133				}).fail(function () {
17134					$.fancyboxMessage(GlobalSettings.ErrorMessages.AjaxErrorMessage);
17135				}).always(function () {
17136					self.LoadingInProcess(false);
17137				});
17138			}
17139		};
17140
17141		var getCountryId = function() {
17142			return $list.find(".country-select select").val();
17143		};
17144
17145		self.ChangeCountry = function () {
17146			loadPorts(getCountryId());
17147		};
17148
17149		self.LoadMorePorts = function () {
17150			loadPorts(getCountryId(), self.LoadedCount(), settings.pageSize);
17151		};
17152	};
17153
17154	var prepareLists = function () {
17155		var $lists = $(settings.widgetSelector);
17156		_.each($lists, function (list, index) {
17157			try {
17158				var $list = $(list);
17159
17160				var resultsVm = new SeaportListViewModel($list, index);
17161
17162				$list.find(".country-select")
17163					.on("change",
17164						function() {
17165							resultsVm.ChangeCountry();
17166						});
17167
17168				var data = null;
17169				var $jsonContainers = $list.find(".seaport-data");
17170				if ($jsonContainers && $jsonContainers.length > 0) {
17171					var $jsonContainer = $($jsonContainers[0]);
17172					data = JSON.parse($jsonContainer.text() || $jsonContainer.html());
17173
17174					resultsVm.AddPorts(data.Items);
17175					resultsVm.TotalCount(data.Count);
17176				}
17177
17178				var resultContainer = $list.find(settings.resultsContainerSelector)[0];
17179				ko.cleanNode(resultContainer);
17180
17181				ko.applyBindings(resultsVm, resultContainer);
17182			} catch (e) {
17183				if (window.console && window.console.log) { console.log("Failed to render seaport list #" + (index + 1)); }
17184			}
17185		});
17186	};
17187
17188	SeaportList.run = function () {
17189		prepareLists();
17190	};
17191
17192	SeaportList.on("start", function (options) {
17193		SeaportList.run();
17194	});
17195});;
17196var cssua=function(n,l,p){var q=/\s*([\-\w ]+)[\s\/\:]([\d_]+\b(?:[\-\._\/]\w+)*)/,r=/([\w\-\.]+[\s\/][v]?[\d_]+\b(?:[\-\._\/]\w+)*)/g,s=/\b(?:(blackberry\w*|bb10)|(rim tablet os))(?:\/(\d+\.\d+(?:\.\w+)*))?/,t=/\bsilk-accelerated=true\b/,u=/\bfluidapp\b/,v=/(\bwindows\b|\bmacintosh\b|\blinux\b|\bunix\b)/,w=/(\bandroid\b|\bipad\b|\bipod\b|\bwindows phone\b|\bwpdesktop\b|\bxblwp7\b|\bzunewp7\b|\bwindows ce\b|\bblackberry\w*|\bbb10\b|\brim tablet os\b|\bmeego|\bwebos\b|\bpalm|\bsymbian|\bj2me\b|\bdocomo\b|\bpda\b|\bchtml\b|\bmidp\b|\bcldc\b|\w*?mobile\w*?|\w*?phone\w*?)/,
17197x=/(\bxbox\b|\bplaystation\b|\bnintendo\s+\w+)/,k={parse:function(b,d){var a={};d&&(a.standalone=d);b=(""+b).toLowerCase();if(!b)return a;
17197for(var c,e,g=b.split(/[()]/),f=0,k=g.length;f<k;f++)if(f%2){var m=g[f].split(";");c=0;for(e=m.length;c<e;c++)if(q.exec(m[c])){var h=RegExp.$1.split(" ").join("_"),l=RegExp.$2;if(!a[h]||parseFloat(a[h])<parseFloat(l))a[h]=l}}else if(m=g[f].match(r))for(c=0,e=m.length;c<e;c++)h=m[c].split(/[\/\s]+/),h.length&&"mozilla"!==h[0]&&(a[h[0].split(" ").join("_")]=h.slice(1).join("-"));
17198w.exec(b)?(a.mobile=RegExp.$1,s.exec(b)&&(delete a[a.mobile],a.blackberry=a.version||RegExp.$3||RegExp.$2||RegExp.$1,RegExp.$1?a.mobile="blackberry":"0.0.1"===a.version&&(a.blackberry="7.1.0.0"))):x.exec(b)?(a.game=RegExp.$1,c=a.game.split(" ").join("_"),a.version&&!a[c]&&(a[c]=a.version)):v.exec(b)&&(a.desktop=RegExp.$1);a.intel_mac_os_x?(a.mac_os_x=a.intel_mac_os_x.split("_").join("."),delete a.intel_mac_os_x):a.cpu_iphone_os?(a.ios=a.cpu_iphone_os.split("_").join("."),delete a.cpu_iphone_os):a.cpu_os?
17199(a.ios=a.cpu_os.split("_").join("."),delete a.cpu_os):"iphone"!==a.mobile||a.ios||(a.ios="1");a.opera&&a.version?(a.opera=a.version,delete a.blackberry):t.exec(b)?a.silk_accelerated=!0:u.exec(b)&&(a.fluidapp=a.version);a.edge&&(delete a.applewebkit,delete a.safari,delete a.chrome,delete a.android);if(a.applewebkit)a.webkit=a.applewebkit,delete a.applewebkit,a.opr&&(a.opera=a.opr,delete a.opr,delete a.chrome),a.safari&&(a.chrome||a.crios||a.fxios||a.opera||a.silk||a.fluidapp||a.phantomjs||a.mobile&&
17200!a.ios?(delete a.safari,a.vivaldi&&delete a.chrome):a.safari=a.version&&!a.rim_tablet_os?a.version:{419:"2.0.4",417:"2.0.3",416:"2.0.2",412:"2.0",312:"1.3",125:"1.2",85:"1.0"}[parseInt(a.safari,10)]||a.safari);else if(a.msie||a.trident)if(a.opera||(a.ie=a.msie||a.rv),delete a.msie,delete a.android,a.windows_phone_os)a.windows_phone=a.windows_phone_os,delete a.windows_phone_os;else{if("wpdesktop"===a.mobile||"xblwp7"===a.mobile||"zunewp7"===a.mobile)a.mobile="windows desktop",a.windows_phone=9>+a.ie?
17201"7.0":10>+a.ie?"7.5":"8.0",delete a.windows_nt}else if(a.gecko||a.firefox)a.gecko=a.rv;a.rv&&delete a.rv;a.version&&delete a.version;return a},format:function(b){var d="",a;for(a in b)if(a&&b.hasOwnProperty(a)){var c=a,e=b[a],c=c.split(".").join("-"),g=" ua-"+c;if("string"===typeof e){for(var e=e.split(" ").join("_").split(".").join("-"),f=e.indexOf("-");0<f;)g+=" ua-"+c+"-"+e.substring(0,f),f=e.indexOf("-",f+1);g+=" ua-"+c+"-"+e}d+=g}return d},encode:function(b){var d="",a;for(a in b)a&&b.hasOwnProperty(a)&&
17202(d&&(d+="\x26"),d+=encodeURIComponent(a)+"\x3d"+encodeURIComponent(b[a]));return d}};k.userAgent=k.ua=k.parse(l,p);l=k.format(k.ua)+" js";n.className=n.className?n.className.replace(/\bno-js\b/g,"")+l:l.substr(1);return k}(document.documentElement,navigator.userAgent,navigator.standalone);;
17203LukoilApp.module("Sharing", function(Sharing, LukoilApp, Backbone, Marionette, $, _) {
17204	var settings = {
17205		isSocialSharingEnabled: window.GlobalSettings.EnableSharing == "True"
17206	};
17207
17208	Sharing.on("start",
17209		function (options) {
17210			settings = options.sharing || settings;
17211			Sharing.run();
17212		});
17213
17214	var encodedPageUrl = encodeURIComponent(window.location.href);
17215
17216	var setShareLinkAction = function(selector, baseAddres) {
17217		var $shareLink = $(selector);
17218		if ($shareLink.length)
17219			$shareLink.attr("href", baseAddres + encodedPageUrl);
17220	};
17221	var sites =
17222	{
17223		//'Facebook': { Url: 'https://www.facebook.com/sharer/sharer.php?u=', Class: 'luk-share-action-facebookenabled' },
17224		'Vkontakte': { Url: 'http://vk.com/share.php?url=', Class: 'luk-share-action-vkenabled' },
17225		//'Twitter': { Url: 'https://twitter.com/intent/tweet?url=', Class: 'luk-share-action-twitterenabled' },
17226		//'Linkedin': { Url: 'http://www.linkedin.com/shareArticle?link=', Class: 'luk-share-action-linkedinenabled' },
17227		//'Google +': { Url: 'https://plus.google.com/share?url=', Class: 'luk-share-action-googleplusenabled' },
17228		//'Odnoklassniki': { Url: 'http://www.odnoklassniki.ru/dk?st.cmd=addShare&st.s=1&st._surl=', Class: 'luk-share-action-odnoklassnikienabled' }
17229	};
17230
17231	var shareHtml = "";
17232	_.each(sites,
17233		function(site, key) {
17234			shareHtml += '<li class="li-' + site.Class + '"><a href="javascript:void(0);" target="_blank" class="' + site.Class + '">' + key + '</a></li>';
17235		});
17236
17237	Sharing.run = function () {
17238		if (!$("#shared-fly").length) {
17239			var container = $('<ul class="dropdown-menu dropdown-menu_fly" id="shared-fly"></ul>');
17240			$("body").append(container);
17241			container.html(shareHtml);
17242		}
17243
17244		// "Share" Content block's functionality START
17245		if (settings.isSocialSharingEnabled) {
17246			_.each(sites, function (site) {
17247				setShareLinkAction('.luk-sharing-container .' + site.Class, site.Url);
17248			});
17249		}
17250
17251		setShareLinkAction(".luk-share-action-sendenabled", "mailto:?body=");
17252
17253		var numberOfNotHiddenLinks = 6;
17254		var shareMoreBtn = $(".luk-share-action-more");
17255
17256		var childLinks = $("li.luk-share-action");
17257
17258		if (childLinks.length > numberOfNotHiddenLinks) {
17259			shareMoreBtn.on("click", function () {
17260				var $this = $(this);
17261				childLinks.show();
17262				$this.closest("li").hide();
17263			});
17264			childLinks.slice(numberOfNotHiddenLinks - 1, childLinks.length).hide();
17265			shareMoreBtn.closest("li").show();
17266		}
17267
17268		$(".luk-share-action-printenabled").on("click", function () {
17269			window.print();
17270		});
17271		// "Share" Content block's functionality END
17272
17273		// Common sharing dropdown's functionality
17274		if (settings.isSocialSharingEnabled) {
17275			var dropdowns = $('.luk-sharing-dropdown');
17276			_.each(dropdowns, function (dd) {
17277				var $this = $(dd);
17278				if ($this.find(".dropdown-menu").length == 0) {
17279					var shareurl = $this.data('shareurl');
17280					var container = $('<ul class="dropdown-menu" role="menu"></ul>');
17281					$this.append(container);
17282					container.html(shareHtml);
17283					_.each(sites, function(site) {
17284						var url = site.Url + encodeURIComponent(shareurl);
17285						container.find('.' + site.Class).attr('href', url);
17286					});
17287				}
17288			});
17289
17290			var dropdownsFlyMenu = $('.dropdown-fly-menu');
17291			_.each(dropdownsFlyMenu, function (dd) {
17292				var $this = $(dd);
17293				$this.find('.share-info').on("click", function () {
17294					var shareurl = $this.data('shareurl');
17295					var container = $("#shared-fly");
17296					container.html(shareHtml);
17297					if (shareurl != null && shareurl != '') {
17298						_.each(sites, function (site) {
17299							var url = site.Url + encodeURIComponent(shareurl);
17300							container.find('.' + site.Class).attr('href', url);
17301						});
17302					}
17303				});
17304			});
17305		}
17306	};
17307});;
17308LukoilApp.module("Winners", function (Winners, LukoilApp, Backbone, Marionette, $, _) {
17309	"use strict";
17310
17311	var settings = {
17312		winnersListWidgetSelector: ".winners-list-widget",
17313		loadMoreButtonSelector: ".load-more-button",
17314		loadAllButtonSelector: ".load-all-button",
17315		listFilterBtnSelector: ".filter-btn",
17316		resultsContainerSelector: ".winners-list-results",
17317		getWinnersUrl: "/api/promo/winners",
17318		resetButtonSelector: ".button-reset",
17319		queryInputSelector: "#winner-prize",
17320		drawDateInputSelector: "#calendar-drawdate",
17321		cardNumberInputSelector: "#card-digits",
17322	
17323	//	applicationSelector: ".application-select",
17324	//	typeSelector: ".typeid-select",
17325	//	viscositySelector: ".viscosity-select"
17326	}
17327
17328	var buildQueryStringForEventListFilter = function (filterParams) {
17329		var url = new URI(window.location.href);
17330
17331		url.search(function (data) {
17332			_.each(_.keys(filterParams),
17333				function(param) {
17334					data[param] = filterParams[param] ? filterParams[param] : undefined;
17335				});
17336
17337			return data;
17338		});
17339
17340		return url.search();
17341	}
17342
17343	var updateSearchParams = function (vm, $widget) {
17344		vm.SearchParams = {
17345			take: Constants.WinnersPageSize,
17346			filterParams: {}
17347		};
17348
17349		var $filter = $widget.find(".filter");
17350		if ($filter.length) {
17351
17352			//var drawDatePicker = $filter.find(settings.drawDateInputSelector).val;
17353			//var queryVal = $filter.find(settings.queryInputSelector).val();
17354			var cardNumbers = $filter.find(settings.cardNumberInputSelector).val();
17355
17356			//vm.SearchParams.query = queryVal ? queryVal.encodeURIComponent() : queryVal;
17357			//vm.SearchParams.date = drawDatePicker ? drawDatePicker.encodeURIComponent() : drawDatePicker;
17358			vm.SearchParams.digits = cardNumbers ? cardNumbers.encodeURIComponent() : cardNumbers;
17359		}
17360	}
17361
17362	//var fillMultiselector = function ($data, values) {
17363	//	$data.parent().removeClass("disabled");
17364	//	$data.find("li").hide();
17365	//	values.map(function (item) {
17366	//		$data.find("input[data-val = " + item + "]").parents('li').show();
17367	//	});
17368	//}
17369
17370	//var updateFilterData = function ($widget, tagsData) {
17371	//	//var $tagsContainers = $widget.find(".tags-data");
17372	//	//var $applicationMultiselect = $widget.find(settings.applicationSelector);
17373	//	//var $typeMultiselect = $widget.find(settings.typeSelector);
17374	//	//var $viscosityMultiselect = $widget.find(settings.viscositySelector);
17375
17376	//	if ($tagsContainers && $tagsContainers.length > 0) {
17377	//		var $container = $($tagsContainers[0]);
17378	//		var data = JSON.parse($container.text() || $container.html());
17379
17380	//		var compatibleAppValues = [];
17381	//		var compatibleTypeValues = [];
17382	//		var compatibleViscosityValues = [];
17383	//		if (data != null && data.Items != null) {
17384	//			data.Items.map(function (item) {
17385	//				if ((tagsData.application.length == 0 || tagsData.application.indexOf(item.application) != -1) &&
17386	//					(tagsData.type.length == 0 || tagsData.type.indexOf(item.type) != -1) &&
17387	//					(tagsData.viscosity.length == 0 || tagsData.viscosity.indexOf(item.viscosity) != -1)) {
17388	//					if (compatibleAppValues.indexOf(item.application) == -1 && item.application != 0)
17389	//						compatibleAppValues.push(item.application);
17390	//					if (compatibleTypeValues.indexOf(item.type) == -1 && item.type != 0)
17391	//						compatibleTypeValues.push(item.type);
17392	//					if (compatibleViscosityValues.indexOf(item.viscosity) == -1 && item.viscosity != 0)
17393	//						compatibleViscosityValues.push(item.viscosity);
17394	//				}
17395	//			});
17396	//		}
17397	//		if ($applicationMultiselect.length > 0 && compatibleAppValues.length > 0 && tagsData.application.length == 0) {
17398	//			fillMultiselector($applicationMultiselect, compatibleAppValues);
17399	//		} else if (tagsData.application.length == 0) {
17400	//			$applicationMultiselect.parent().addClass("disabled");
17401	//		}
17402	//		if ($typeMultiselect.length > 0 && compatibleTypeValues.length > 0 && tagsData.type.length == 0) {
17403	//			fillMultiselector($typeMultiselect, compatibleTypeValues);
17404	//		} else if (tagsData.type.length == 0) {
17405	//			$typeMultiselect.parent().addClass("disabled");
17406	//		}
17407	//		if ($viscosityMultiselect.length > 0 && compatibleViscosityValues.length > 0 && tagsData.viscosity.length == 0) {
17408	//			fillMultiselector($viscosityMultiselect, compatibleViscosityValues);
17409	//		} else if (tagsData.viscosity.length == 0) {
17410	//			$viscosityMultiselect.parent().addClass("disabled");
17411	//		}
17412	//	}
17413	//}
17414
17415	var getValues = function ($data, array) {
17416		var $ms = $data.getValFromMultiSelect();
17417		if ($ms != null) {
17418			$ms.map(function (item) {
17419				array.push(item.value);
17420			});
17421		}
17422	}
17423
17424	var onChangeFilter = function ($widget) {
17425	//	var $applicationMultiselect = $widget.find(settings.applicationSelector);
17426	//	var $typeMultiselect = $widget.find(settings.typeSelector);
17427	//	var $viscosityMultiselect = $widget.find(settings.viscositySelector);
17428
17429	//	var tagsData = {
17430	//		application: [],
17431	//		type: [],
17432	//		viscosity: []
17433	//	};
17434
17435	//	if ($applicationMultiselect.length > 0 && $applicationMultiselect.getValFromMultiSelect().length > 0)
17436	//		getValues($applicationMultiselect, tagsData.application);
17437	//	if ($typeMultiselect.length > 0 && $typeMultiselect.getValFromMultiSelect().length > 0)
17438	//		getValues($typeMultiselect, tagsData.type);
17439	//	if ($viscosityMultiselect.length > 0 && $viscosityMultiselect.getValFromMultiSelect().length > 0)
17440	//		getValues($viscosityMultiselect, tagsData.viscosity);
17441
17442	//	updateFilterData($widget, tagsData);
17443	}
17444
17445	var loadWinners = function (vm, $widget, skip, isPaging) { //loadProducts
17446		if (!vm.LoadingInProcess()) {
17447			if (!skip) {
17448				updateSearchParams(vm, $widget);
17449			}
17450
17451			vm.LoadingInProcess(true);
17452
17453			var data = vm.SearchParams;
17454			data.skip = skip;
17455
17456			_.extend(data, data.filterParams);
17457			var filterParams = data.filterParams;
17458			//data.filterParams = undefined;
17459
17460			$.ajax({
17461				url: settings.getWinnersUrl,
17462				data: data,
17463				method: "post",
17464				success: function (data) {
17465					var queryString = buildQueryStringForEventListFilter(filterParams) || "";
17466					if (window.history && window.history.pushState) {
17467						window.history.replaceState(null, "", location.protocol + "//" + location.host + location.pathname + queryString);
17468					} else {
17469						window.location.href = location.protocol + "//" + location.host + location.pathname + "#" + queryString;
17470					}
17471
17472					if (!skip || isPaging) {
17473						vm.ClearWinners();
17474					}
17475
17476					//data = JSON.parse(data);
17477
17478					vm.AddWinners(data.Items);
17479					vm.AllWinnersCount(data.Count);
17480					$.createDownloadPopover($widget);
17481				},
17482				traditional: true,
17483				cache: false
17484			}).fail(function () {
17485				$.fancyboxMessage(GlobalSettings.ErrorMessages.AjaxErrorMessage);
17486			}).always(function () {
17487				vm.LoadingInProcess(false);
17488			});
17489		}
17490	};
17491
17492	var loadAllWinners = function (vm, $widget) {
17493		if (!vm.LoadingInProcess()) {
17494			updateSearchParams(vm, $widget);
17495	
17496			vm.LoadingInProcess(true);
17497
17498			var data = vm.SearchParams;
17499			
17500			_.extend(data, data.filterParams);
17501			var filterParams = data.filterParams;
17502			//data.filterParams = undefined;
17503			//data.take = undefined;
17504
17505			$.ajax({
17506				url: settings.getWinnersUrl,
17507				data: data,
17508				method: "post",
17509				success: function (data) {
17510					var queryString = buildQueryStringForEventListFilter(filterParams) || "";
17511					if (window.history && window.history.pushState) {
17512						window.history.replaceState(null, "", location.protocol + "//" + location.host + location.pathname + queryString);
17513						window.location.hash = 'loadAll=true';
17514					} else {
17515						window.location.href = location.protocol + "//" + location.host + location.pathname + "#loadAll=true&" + queryString;
17516					}
17517
17518					vm.ClearWinners();
17519					
17520					//data = JSON.parse(data);
17521
17522					vm.AddWinners(data.Items);
17523					vm.AllWinnersCount(data.Count);
17524					$.createDownloadPopover($widget);
17525
17526					vm.ShowPaginationButtons(false);
17527				},
17528				traditional: true,
17529				cache: false
17530			}).fail(function () {
17531				$.fancyboxMessage(GlobalSettings.ErrorMessages.AjaxErrorMessage);
17532			}).always(function () {
17533				vm.LoadingInProcess(false);
17534			});
17535		}
17536	};
17537
17538	var WinnerListViewModel = function (index) {
17539		var self = this;
17540
17541		self.Skipped = ko.observable(0);
17542		self.WinnersCount = ko.observable(0);
17543		self.AllWinnersCount = ko.observable(0);
17544		self.Winners = ko.observableArray([]);
17545		self.LoadingInProcess = ko.observable(false);
17546
17547		self.CanLoadMore = ko.computed(function () {
17548			return !self.LoadingInProcess() && self.AllWinnersCount() > self.WinnersCount();
17549		});
17550
17551		self.ShowPaginationButtons = ko.observable(true);
17552
17553		self.AddWinners = function(winners) {
17554			_.each(winners,
17555				function (winner) {
17556					if (!winner.ListImage) {
17557						winner.ListImage = GlobalSettings.CurrentLanguage === "ru" ? "/Content/img/barrel-ru-210-220.png" : "/Content/img/barrel-eng-210-220.png";
17558					}
17559
17560					self.Winners.push(winner);
17561				});
17562
17563			self.WinnersCount(self.Winners().length);
17564		}
17565
17566		self.IsActivePage = function (value) {
17567			return $.inArray(value, self.LoadedPages()) >= 0;
17568		}
17569
17570		if (window.location.hash.includes("loadAll=true")) {
17571			ko.PaginationViewModel.call(self, Constants.WinnersPageSize, self.AllWinnersCount, settings.winnersListWidgetSelector, loadAllWinners);
17572		} else {
17573			ko.PaginationViewModel.call(self, Constants.WinnersPageSize, self.AllWinnersCount, settings.winnersListWidgetSelector, loadWinners);
17574		}
17575
17576		self.ClearWinners = function() {
17577			self.Winners.removeAll();
17578			self.WinnersCount(0);
17579		}
17580	};
17581
17582	var resetFilter = function($widget) {
17583		$widget.find(".search-control").val("");
17584	}
17585
17586	var prepareLists = function() {
17587		var $winnerListWidgets = $(settings.winnersListWidgetSelector);
17588		_.each($winnerListWidgets, function (winnerList, index) {
17589			try {
17590				var $winnerListWidget = $(winnerList);
17591
17592				var resultsVm = new WinnerListViewModel(index);
17593
17594				if (window.location.hash.includes("loadAll=true")) {
17595					loadAllWinners(resultsVm, $winnerListWidget);
17596                }
17597
17598				$winnerListWidget.find(settings.listFilterBtnSelector).on("click", function () {
17599					resultsVm.LoadedPages.removeAll();
17600					resultsVm.CurrentPage(1);
17601					loadWinners(resultsVm, $winnerListWidget, 0, false);
17602				});
17603
17604				$winnerListWidget.find(settings.queryInputSelector).on("keypress", function(e) {
17605					if ((event.keyCode || event.which) == 13) {
17606						resultsVm.LoadedPages.removeAll();
17607						resultsVm.CurrentPage(1);
17608						loadWinners(resultsVm, $winnerListWidget, 0, false);
17609					}
17610				});
17611
17612				$winnerListWidget.on("click", settings.loadMoreButtonSelector, function () {
17613					var page = resultsVm.CurrentPage();
17614					resultsVm.CurrentPage(page + 1);
17615					resultsVm.LoadedPages.push(page);
17616					loadWinners(resultsVm, $winnerListWidget, resultsVm.WinnersCount(), false);
17617				});
17618
17619				$winnerListWidget.on("click", settings.loadAllButtonSelector, function () {
17620					loadAllWinners(resultsVm, $winnerListWidget);
17621				});
17622
17623				onChangeFilter($winnerListWidget);
17624				$winnerListWidget.find(settings.applicationSelector).find("input").on('change',
17625					function () {
17626						onChangeFilter($winnerListWidget);
17627					});
17628				$winnerListWidget.find(settings.typeSelector).find("input").on('change',
17629					function () {
17630						onChangeFilter($winnerListWidget);
17631					});
17632				$winnerListWidget.find(settings.viscositySelector).find("input").on('change',
17633					function () {
17634						onChangeFilter($winnerListWidget);
17635					});
17636					
17637				var tabs = $winnerListWidget.find(".nav-tabs li");
17638				tabs.on("click", function () {
17639					_.each(tabs,
17640						function(tab) {
17641							$(tab).removeClass("active");
17642						});
17643
17644					$(this).addClass("active");
17645					resultsVm.LoadedPages.removeAll();
17646					resultsVm.CurrentPage(1);
17647					loadWinners(resultsVm, $winnerListWidget, 0, false);
17648				});
17649
17650				$winnerListWidget.find(settings.resetButtonSelector).on("click", function () {
17651					resetFilter($winnerListWidget);
17652				});
17653
17654				var winnerData = null;
17655				var $jsonContainers = $winnerListWidget.find(".winners-data");
17656				if ($jsonContainers && $jsonContainers.length > 0) {
17657					var $jsonContainer = $($jsonContainers[0]);
17658					winnerData = JSON.parse($jsonContainer.text() || $jsonContainer.html());
17659
17660					resultsVm.Skipped(winnerData.Skipped);
17661					resultsVm.CurrentPage(Math.floor(resultsVm.Skipped() / resultsVm.PageSize()) + 1);
17662
17663					resultsVm.AddWinners(winnerData.Items);
17664					resultsVm.AllWinnersCount(winnerData.Count);
17665				}
17666
17667
17668				if (!winnerData) {
17669					$winnerListWidget.remove();
17670				} else {
17671					var resultContainer = $winnerListWidget.find(settings.resultsContainerSelector)[0];
17672					ko.cleanNode(resultContainer);
17673					updateSearchParams(resultsVm, $winnerListWidget);
17674					var widgetGuid = $winnerListWidget.attr("data-widget-guid");
17675					$(".server-rendered-" + widgetGuid).remove();
17676					ko.applyBindings(resultsVm, resultContainer);
17677					$.createDownloadPopover($winnerListWidget);
17678				}
17679			} catch (e) {
17680				if (window.console && window.console.log) { console.log("Failed to render winner list #" + (index + 1)); }
17681			}
17682		});
17683	};
17684
17685	var prepareInfoPages = function () {
17686		var $infoPages = $(settings.winnerInfoPageWidgetSelector);
17687		_.each($infoPages, function (infoPage, index) {
17688			try {
17689				var $infoPage = $(infoPage);
17690
17691				var winnerName = $infoPage.data("name");
17692
17693				if (winnerName) {
17694					$(".page-title h1").text(winnerName);
17695					$(".breadcrumb .active span").text(winnerName);
17696				}
17697			} catch (e) {
17698				if (window.console && window.console.log) { console.log("Failed to render winner info page #" + (index + 1)); }
17699			}
17700		});
17701	};
17702
17703	Winners.run = function () {
17704		prepareLists();
17705		prepareInfoPages();
17706	};
17707
17708	Winners.on("start", function (options) {
17709		Winners.run();
17710	});
17711});;

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.