PageSourceSearch

https://www.online-fashion.ru/bitrix/cache/js/s1/bitrix66/page_613…a9f6a243bac4b740bb25_v1.js?1791366221195951

js online-fashion.ru collected 2026-10-08 23:30:30 UTC 195,951 bytes, 6,505 lines download raw bytes

1
2; /* Start:"a:4:{s:4:"full";s:102:"/local/templates/bitrix66/components/bitrix/sale.basket.basket/basket/js/action-pool.js?17913091655918";s:6:"source";s:87:"/local/templates/bitrix66/components/bitrix/sale.basket.basket/basket/js/action-pool.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
3;(function(){
4	'use strict';
5
6	BX.namespace('BX.Sale.BasketActionPool');
7
8	BX.Sale.BasketActionPool = function(component)
9	{
10		this.component = component;
11
12		this.requestProcessing = false;
13		this.updateTimer = null;
14
15		this.isBasketRefreshed = this.component.params.DEFERRED_REFRESH !== 'Y';
16		this.needFullRecalculation = this.component.params.DEFERRED_REFRESH === 'Y';
17
18		this.pool = {};
19		this.lastActualPool = {};
20
21		this.approvedAction = ['QUANTITY', 'DELETE', 'RESTORE', 'DELAY', 'OFFER', 'MERGE_OFFER'];
22
23		this.switchTimer();
24	};
25
26	BX.Sale.BasketActionPool.prototype.setRefreshStatus = function(status)
27	{
28		this.isBasketRefreshed = !!status;
29	};
30
31	BX.Sale.BasketActionPool.prototype.getRefreshStatus = function()
32	{
33		return this.isBasketRefreshed;
34	};
35
36	BX.Sale.BasketActionPool.prototype.isItemInPool = function(itemId)
37	{
38		return !!this.pool[itemId];
39	};
40
41	BX.Sale.BasketActionPool.prototype.clearLastActualQuantityPool = function(itemId)
42	{
43		this.lastActualPool[itemId] && delete this.lastActualPool[itemId].QUANTITY;
44	};
45
46	BX.Sale.BasketActionPool.prototype.checkItemPoolBefore = function(itemId)
47	{
48		if (!itemId)
49			return;
50
51		this.pool[itemId] = this.pool[itemId] || {};
52	};
53
54	BX.Sale.BasketActionPool.prototype.checkItemPoolAfter = function(itemId)
55	{
56		if (!itemId || !this.pool[itemId])
57			return;
58
59		if (Object.keys(this.pool[itemId]).length === 0)
60		{
61			delete this.pool[itemId];
62		}
63	};
64
65	BX.Sale.BasketActionPool.prototype.addCoupon = function(coupon)
66	{
67		this.pool.COUPON = coupon;
68
69		this.switchTimer();
70	};
71
72	BX.Sale.BasketActionPool.prototype.removeCoupon = function(coupon)
73	{
74		this.checkItemPoolBefore('REMOVE_COUPON');
75
76		this.pool.REMOVE_COUPON[coupon] = coupon;
77
78		this.switchTimer();
79	};
80
81	BX.Sale.BasketActionPool.prototype.changeQuantity = function(itemId, quantity, oldQuantity)
82	{
83		this.checkItemPoolBefore(itemId);
84
85		if (
86			(this.lastActualPool[itemId] && this.lastActualPool[itemId].QUANTITY !== quantity)
87			|| (!this.lastActualPool[itemId] && quantity !== oldQuantity)
88		)
89		{
90			this.pool[itemId].QUANTITY = quantity;
91		}
92		else
93		{
94			this.pool[itemId] && delete this.pool[itemId].QUANTITY;
95		}
96
97		this.checkItemPoolAfter(itemId);
98		this.switchTimer();
99	};
100
101	BX.Sale.BasketActionPool.prototype.deleteItem = function(itemId)
102	{
103		this.checkItemPoolBefore(itemId);
104
105		if (this.pool[itemId].RESTORE)
106		{
107			delete this.pool[itemId].RESTORE;
108		}
109		else
110		{
111			this.pool[itemId].DELETE = 'Y';
112		}
113
114		this.checkItemPoolAfter(itemId);
115		this.switchTimer();
116	};
117
118	BX.Sale.BasketActionPool.prototype.restoreItem = function(itemId, itemData)
119	{
120		this.checkItemPoolBefore(itemId);
121
122		if (this.pool[itemId].DELETE === 'Y')
123		{
124			delete this.pool[itemId].DELETE;
125		}
126		else
127		{
128			this.pool[itemId].RESTORE = itemData;
129		}
130
131		this.checkItemPoolAfter(itemId);
132		this.switchTimer();
133	};
134
135	BX.Sale.BasketActionPool.prototype.addDelayed = function(itemId)
136	{
137		this.checkItemPoolBefore(itemId);
138
139		this.pool[itemId].DELAY = 'Y';
140
141		this.checkItemPoolAfter(itemId);
142		this.switchTimer();
143	};
144
145	BX.Sale.BasketActionPool.prototype.removeDelayed = function(itemId)
146	{
147		this.checkItemPoolBefore(itemId);
148
149		this.pool[itemId].DELAY = 'N';
150
151		this.checkItemPoolAfter(itemId);
152		this.switchTimer();
153	};
154
155	BX.Sale.BasketActionPool.prototype.changeSku = function(itemId, props, oldProps)
156	{
157		if (JSON.stringify(props) !== JSON.stringify(oldProps))
158		{
159			this.checkItemPoolBefore(itemId);
160			this.pool[itemId].OFFER = props;
161		}
162		else
163		{
164			this.pool[itemId] && delete this.pool[itemId].OFFER;
165			this.checkItemPoolAfter(itemId);
166		}
167
168		this.switchTimer();
169	};
170
171	BX.Sale.BasketActionPool.prototype.mergeSku = function(itemId)
172	{
173		this.checkItemPoolBefore(itemId);
174		this.pool[itemId].MERGE_OFFER = 'Y';
175
176		this.switchTimer();
177	};
178
179	BX.Sale.BasketActionPool.prototype.switchTimer = function()
180	{
181		clearTimeout(this.updateTimer);
182
183		if (this.isProcessing())
184		{
185			return;
186		}
187
188		if (this.isPoolEmpty())
189		{
190			this.component.editPostponedBasketItems();
191			this.component.fireCustomEvents();
192		}
193
194		if (!this.isPoolEmpty())
195		{
196			this.updateTimer = setTimeout(BX.proxy(this.trySendPool, this), 300);
197		}
198		else if (!this.getRefreshStatus())
199		{
200			this.trySendPool();
201		}
202	};
203
204	BX.Sale.BasketActionPool.prototype.trySendPool = function()
205	{
206		if (this.isPoolEmpty() && this.getRefreshStatus())
207		{
208			return;
209		}
210
211		this.doProcessing(true);
212
213		if (!this.isPoolEmpty())
214		{
215			this.component.sendRequest('recalculateAjax', {
216				basket: this.getPoolData()
217			});
218
219			this.lastActualPool = this.pool;
220			this.pool = {};
221		}
222		else if (!this.getRefreshStatus())
223		{
224			this.component.sendRequest('refreshAjax', {
225				fullRecalculation: this.needFullRecalculation ? 'Y' : 'N'
226			});
227			this.needFullRecalculation = false;
228		}
229	};
230
231	BX.Sale.BasketActionPool.prototype.getPoolData = function()
232	{
233		var poolData = {},
234			currentPool = this.pool;
235
236		if (currentPool.COUPON)
237		{
238			poolData.coupon = currentPool.COUPON;
239			delete currentPool.COUPON;
240		}
241
242		if (currentPool.REMOVE_COUPON)
243		{
244			poolData.delete_coupon = currentPool.REMOVE_COUPON;
245			delete currentPool.REMOVE_COUPON;
246		}
247
248		for (var id in currentPool)
249		{
250			if (currentPool.hasOwnProperty(id))
251			{
252				for (var action in currentPool[id])
253				{
254					if (currentPool[id].hasOwnProperty(action) && BX.util.in_array(action, this.approvedAction))
255					{
256						poolData[action + '_' + id] = currentPool[id][action];
257					}
258				}
259			}
260		}
261
262		return poolData;
263	};
264
265	BX.Sale.BasketActionPool.prototype.isPoolEmpty = function()
266	{
267		return Object.keys(this.pool).length === 0;
268	};
269
270	BX.Sale.BasketActionPool.prototype.doProcessing = function(state)
271	{
272		this.requestProcessing = state === true;
273
274		if (this.requestProcessing)
275		{
276			this.component.startLoader();
277		}
278		else
279		{
280			this.component.endLoader();
281		}
282	};
283
284	BX.Sale.BasketActionPool.prototype.isProcessing = function()
285	{
286		return this.requestProcessing === true;
287	};
288})();
289/* End */
290;
291; /* Start:"a:4:{s:4:"full";s:98:"/local/templates/bitrix66/components/bitrix/sale.basket.basket/basket/js/filter.js?179130916514092";s:6:"source";s:82:"/local/templates/bitrix66/components/bitrix/sale.basket.basket/basket/js/filter.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
292;(function(){
293	'use strict';
294
295	BX.namespace('BX.Sale.BasketFilter');
296
297	BX.Sale.BasketFilter = function(component)
298	{
299		this.component = component;
300
301		this.activeFilterMode = false;
302		this.filterTimer = null;
303		this.mouseOverClearFilter = false;
304
305		this.realShownItems = [];
306		this.realSortedItems = [];
307		this.realScrollTop = 0;
308
309		this.lastShownItemsHash = '';
310		this.currentFilter = {
311			query: '',
312			similarHash: '',
313			warning: false,
314			notAvailable: false,
315			delayed: false
316		};
317
318		if (this.component.useItemsFilter)
319		{
320			this.bindEvents();
321		}
322	};
323
324	BX.Sale.BasketFilter.prototype.bindEvents = function()
325	{
326		var entity;
327		var filterNode = this.component.getEntity(
328			this.component.getCacheNode(this.component.ids.itemListWrapper),
329			'basket-filter'
330		);
331
332		entity = this.component.getEntity(filterNode, 'basket-filter-input');
333		if (BX.type.isDomNode(entity))
334		{
335			BX.bind(entity, 'focus', function() {
336				filterNode.style.flex = 3;
337			});
338			BX.bind(entity, 'blur', BX.delegate(function() {
339				if (!this.mouseOverClearFilter)
340				{
341					filterNode.style.flex = '';
342				}
343			}, this));
344
345			BX.bind(entity, 'keyup', BX.proxy(this.onFilterInput, this));
346			BX.bind(entity, 'cut', BX.proxy(this.onFilterInput, this));
347			BX.bind(entity, 'paste', BX.proxy(this.onFilterInput, this));
348		}
349
350		entity = this.component.getEntity(filterNode, 'basket-filter-clear-btn');
351		if (BX.type.isDomNode(entity))
352		{
353			BX.bind(entity, 'mouseenter', BX.delegate(function() {
354				this.mouseOverClearFilter = true;
355			}, this));
356			BX.bind(entity, 'mouseout', BX.delegate(function() {
357				this.mouseOverClearFilter = false;
358			}, this));
359			BX.bind(entity, 'click', BX.delegate(function() {
360				if (!this.filterInputEmpty())
361				{
362					this.clearFilterInput();
363					this.onFilterChange();
364				}
365
366				filterNode.style.flex = '';
367			}, this));
368		}
369	};
370
371	BX.Sale.BasketFilter.prototype.isActive = function()
372	{
373		return this.activeFilterMode;
374	};
375
376	BX.Sale.BasketFilter.prototype.showFilterByName = function(name)
377	{
378		if (!name)
379			return;
380
381		switch (name)
382		{
383			case 'not-available':
384				this.showNotAvailableItemsFilter();
385				break;
386			case 'delayed':
387				this.showDelayItemsFilter();
388				break;
389			case 'warning':
390				this.showWarningItemsFilter();
391				break;
392			case 'similar':
393				this.showSimilarItemsFilter();
394				break;
395			case 'all':
396			default:
397				this.clearAllFiltersExcept([]);
398				this.onFilterChange();
399		}
400	};
401
402	BX.Sale.BasketFilter.prototype.onFilterInput = function()
403	{
404		var value = BX.type.isDomNode(BX.proxy_context) ? BX.util.trim(BX.proxy_context.value).toLowerCase() : '';
405
406		if (this.currentFilter.query !== value)
407		{
408			this.currentFilter.query = value;
409
410			this.onFilterChange();
411		}
412	};
413
414	BX.Sale.BasketFilter.prototype.clearAllFiltersExcept = function(names)
415	{
416		if (!names || !BX.type.isArray(names))
417			return;
418
419		!BX.util.in_array('input', names) && this.clearFilterInput();
420		!BX.util.in_array('warning', names) && this.clearWarningItemsFilter();
421		!BX.util.in_array('delayed', names) && this.clearDelayItemsFilter();
422		!BX.util.in_array('not-available', names) && this.clearNotAvailableItemsFilter();
423
424		if (!BX.util.in_array('similar', names))
425		{
426			this.clearSimilarItemsFilter();
427			this.component.showSimilarCount(false);
428		}
429	};
430
431	BX.Sale.BasketFilter.prototype.filterInputEmpty = function()
432	{
433		return this.currentFilter.query.length === 0;
434	};
435
436	BX.Sale.BasketFilter.prototype.clearFilterInput = function()
437	{
438		this.currentFilter.query = '';
439
440		var input = this.component.getEntity(
441			this.component.getCacheNode(this.component.ids.itemListWrapper),
442			'basket-filter-input'
443		);
444		if (BX.type.isDomNode(input))
445		{
446			input.value = '';
447		}
448	};
449
450	BX.Sale.BasketFilter.prototype.addWarningItemsFilter = function()
451	{
452		this.currentFilter.warning = true;
453	};
454
455	BX.Sale.BasketFilter.prototype.clearWarningItemsFilter = function()
456	{
457		this.currentFilter.warning = false;
458	};
459
460	BX.Sale.BasketFilter.prototype.showWarningItemsFilter = function()
461	{
462		if (!this.currentFilter.warning)
463		{
464			this.clearAllFiltersExcept(['warning']);
465			this.addWarningItemsFilter();
466			this.onFilterChange();
467		}
468	};
469
470	BX.Sale.BasketFilter.prototype.addDelayItemsFilter = function()
471	{
472		this.currentFilter.delayed = true;
473	};
474
475	BX.Sale.BasketFilter.prototype.clearDelayItemsFilter = function()
476	{
477		this.currentFilter.delayed = false;
478	};
479
480	BX.Sale.BasketFilter.prototype.showDelayItemsFilter = function()
481	{
482		if (!this.currentFilter.delayed)
483		{
484			this.clearAllFiltersExcept(['delayed']);
485			this.addDelayItemsFilter();
486			this.onFilterChange();
487		}
488	};
489
490	BX.Sale.BasketFilter.prototype.addNotAvailableItemsFilter = function()
491	{
492		this.currentFilter.notAvailable = true;
493	};
494
495	BX.Sale.BasketFilter.prototype.clearNotAvailableItemsFilter = function()
496	{
497		this.currentFilter.notAvailable = false;
498	};
499
500	BX.Sale.BasketFilter.prototype.showNotAvailableItemsFilter = function()
501	{
502		if (!this.currentFilter.notAvailable)
503		{
504			this.clearAllFiltersExcept(['not-available']);
505			this.addNotAvailableItemsFilter();
506			this.onFilterChange();
507		}
508	};
509
510	BX.Sale.BasketFilter.prototype.addSimilarItemsFilter = function(item)
511	{
512		this.currentFilter.similarHash = item.HASH;
513	};
514
515	BX.Sale.BasketFilter.prototype.clearSimilarItemsFilter = function()
516	{
517		this.currentFilter.similarHash = '';
518	};
519
520	BX.Sale.BasketFilter.prototype.showSimilarItemsFilter = function()
521	{
522		var item = this.component.getItemDataByTarget(BX.proxy_context);
523
524		if (this.currentFilter.similarHash !== item.HASH)
525		{
526			this.clearAllFiltersExcept(['similar']);
527			this.addSimilarItemsFilter(item);
528			this.onFilterChange();
529		}
530	};
531
532	BX.Sale.BasketFilter.prototype.getTimeoutDuration = function()
533	{
534		return this.component.duration.filterTimer;
535	};
536
537	BX.Sale.BasketFilter.prototype.onFilterChange = function()
538	{
539		this.component.showItemsOverlay();
540
541		if (
542			this.currentFilter.query.length
543			|| this.currentFilter.similarHash.length
544			|| this.currentFilter.warning
545			|| this.currentFilter.notAvailable
546			|| this.currentFilter.delayed
547		)
548		{
549			clearTimeout(this.filterTimer);
550			this.filterTimer = setTimeout(BX.proxy(this.enableFilterMode, this), this.getTimeoutDuration());
551		}
552		else
553		{
554			this.disableFilterMode();
555		}
556	};
557
558	BX.Sale.BasketFilter.prototype.enableFilterMode = function()
559	{
560		var foundItemsHash;
561
562		if (!this.activeFilterMode)
563		{
564			this.activeFilterMode = true;
565			this.realShownItems = BX.util.array_values(this.component.shownItems);
566			this.realSortedItems = BX.util.array_values(this.component.sortedItems);
567			this.realScrollTop = this.component.getDocumentScrollTop();
568		}
569
570		this.component.scrollToFirstItem();
571
572		this.component.sortedItems = this.searchItems();
573
574		foundItemsHash = JSON.stringify(this.component.sortedItems);
575
576		if (this.lastShownItemsHash !== foundItemsHash)
577		{
578			this.lastShownItemsHash = foundItemsHash;
579
580			this.component.deleteBasketItems(BX.util.array_values(this.component.shownItems), false);
581
582			if (this.component.sortedItems.length)
583			{
584				this.component.initializeBasketItems();
585				this.hideEmptyFilterResult();
586			}
587			else
588			{
589				this.showEmptyFilterResult();
590			}
591
592			if (this.currentFilter.similarHash.length)
593			{
594				this.component.showSimilarCount(true);
595			}
596		}
597		else
598		{
599			this.highlightFoundItems();
600		}
601
602		this.component.hideItemsOverlay();
603	};
604
605	BX.Sale.BasketFilter.prototype.disableFilterMode = function()
606	{
607		clearTimeout(this.filterTimer);
608		this.lastShownItemsHash = '';
609
610		if (this.activeFilterMode)
611		{
612			this.activeFilterMode = false;
613			this.component.sortedItems = BX.util.array_values(this.realSortedItems);
614
615			this.component.deleteBasketItems(BX.util.array_values(this.component.shownItems), false);
616			this.hideEmptyFilterResult();
617
618			this.component.editBasketItems(BX.util.array_values(this.realShownItems));
619			window.scrollTo(0, this.realScrollTop);
620		}
621
622		this.component.hideItemsOverlay();
623	};
624
625	BX.Sale.BasketFilter.prototype.searchItems = function()
626	{
627		var items = [];
628
629		for (var i = 0; i < this.realSortedItems.length; i++)
630		{
631			var item = this.component.items[this.realSortedItems[i]];
632
633			if (item && this.searchItemMatch(item))
634			{
635				items.push(item.ID);
636			}
637		}
638
639		return items;
640	};
641
642	BX.Sale.BasketFilter.prototype.highlightFoundItems = function()
643	{
644		if (!this.activeFilterMode)
645			return;
646
647		for (var i in this.component.shownItems)
648		{
649			if (this.component.shownItems.hasOwnProperty(i))
650			{
651				this.highlightSearchMatch(this.component.items[this.component.shownItems[i]]);
652			}
653		}
654	};
655
656	BX.Sale.BasketFilter.prototype.searchItemMatch = function(item)
657	{
658		var match = false,
659			found = false;
660
661		if (this.currentFilter.notAvailable)
662		{
663			found = !!item.NOT_AVAILABLE;
664			if (!found)
665			{
666				return match;
667			}
668		}
669		else if (this.currentFilter.delayed)
670		{
671			found = !!item.DELAYED;
672			if (!found)
673			{
674				return match;
675			}
676		}
677		else if (this.currentFilter.warning)
678		{
679			found = BX.util.in_array(item.ID, this.component.warningItems);
680			if (!found)
681			{
682				return match;
683			}
684		}
685		else if (BX.type.isNotEmptyString(this.currentFilter.similarHash))
686		{
687			found = this.currentFilter.similarHash === item.HASH;
688			if (!found)
689			{
690				return match;
691			}
692		}
693
694		if (BX.type.isNotEmptyString(this.currentFilter.query))
695		{
696			if (item.NAME.toLowerCase().indexOf(this.currentFilter.query) !== -1)
697			{
698				match = 'NAME';
699			}
700
701			if (!match)
702			{
703				var floatValue = parseFloat(this.currentFilter.query);
704				if (!isNaN(floatValue))
705				{
706					if (parseFloat(item.PRICE) === floatValue)
707					{
708						match = 'PRICE';
709					}
710					else if (parseFloat(item.SUM_PRICE) === floatValue)
711					{
712						match = 'SUM_PRICE';
713					}
714				}
715			}
716
717			if (!match && this.currentFilter.query.length >= 3)
718			{
719				if (item.PRICE_FORMATED.toLowerCase().indexOf(this.currentFilter.query) !== -1)
720				{
721					match = 'PRICE';
722				}
723				else if (item.SUM_PRICE_FORMATED.toLowerCase().indexOf(this.currentFilter.query) !== -1)
724				{
725					match = 'SUM_PRICE';
726				}
727			}
728
729			var k, lcValue;
730
731			if (!match && item.PROPS.length)
732			{
733				for (k in item.PROPS)
734				{
735					if (item.PROPS.hasOwnProperty(k) && BX.type.isNotEmptyString(item.PROPS[k].VALUE))
736					{
737						lcValue = item.PROPS[k].VALUE.toLowerCase();
738
739						if (
740							lcValue === this.currentFilter.query
741							|| (this.currentFilter.query.length >= 3 && lcValue.indexOf(this.currentFilter.query) !== -1)
742						)
743						{
744							match = 'PROPS';
745							break;
746						}
747					}
748				}
749			}
750
751			if (!match && item.COLUMN_LIST.length)
752			{
753				for (k in item.COLUMN_LIST)
754				{
755					if (item.COLUMN_LIST.hasOwnProperty(k) && BX.type.isNotEmptyString(item.COLUMN_LIST[k].VALUE))
756					{
757						lcValue = item.COLUMN_LIST[k].VALUE.toLowerCase();
758
759						if (
760							lcValue === this.currentFilter.query
761							|| (this.currentFilter.query.length >= 3 && lcValue.indexOf(this.currentFilter.query) !== -1)
762						)
763						{
764							match = 'COLUMNS';
765							break;
766						}
767					}
768				}
769			}
770		}
771		else if (found)
772		{
773			match = true;
774		}
775
776		return match;
777	};
778
779	BX.Sale.BasketFilter.prototype.highlightSearchMatch = function(itemData)
780	{
781		var searchMatch = this.searchItemMatch(itemData);
782
783		if (searchMatch)
784		{
785			var entity, i, k, code;
786
787			switch (searchMatch)
788			{
789				case 'NAME':
790					entity = this.component.getEntity(BX(this.component.ids.item + itemData.ID), 'basket-item-name');
791					if (BX.type.isDomNode(entity))
792					{
793						entity.innerHTML = itemData.NAME.replace(
794							new RegExp('(.*)(' + this.currentFilter.query.replace(/[.*+?^${}
794()|[\]\\]/g, "\\$&") + ')(.*)', 'gi'),
795							function (full, match1 , match2, match3)
796							{
797								return BX.util.htmlspecialchars(match1)
798									+ '<span class="basket-item-highlighted">'
799									+ BX.util.htmlspecialchars(match2)
800									+ '</span>' + BX.util.htmlspecialchars(match3);
801							}
802						);
803					}
804					break;
805				case 'PRICE':
806					entity = BX(this.component.ids.price + itemData.ID);
807					BX.addClass(entity, 'basket-item-highlighted');
808					break;
809				case 'SUM_PRICE':
810					entity = BX(this.component.ids.sumPrice + itemData.ID);
811					BX.addClass(entity, 'basket-item-highlighted');
812					break;
813				case 'PROPS':
814					entity = this.component.getEntities(BX(this.component.ids.item + itemData.ID), 'basket-item-property-value');
815
816					for (i = 0; i < entity.length; i++)
817					{
818						code = entity[i].getAttribute('data-property-code');
819
820						for (k in itemData.PROPS)
821						{
822							if (itemData.PROPS.hasOwnProperty(k) && itemData.PROPS[k].CODE === code)
823							{
824								entity[i].innerHTML = itemData.PROPS[k].VALUE.replace(
825									new RegExp('(' + this.currentFilter.query + ')', 'gi'),
826									'<span class="basket-item-highlighted">$1</span>'
827								);
828							}
829						}
830					}
831					break;
832				case 'COLUMNS':
833					entity = this.component.getEntities(BX(this.component.ids.item + itemData.ID), 'basket-item-property-column-value');
834
835					for (i = 0; i < entity.length; i++)
836					{
837						code = entity[i].getAttribute('data-column-property-code');
838
839						for (k in itemData.COLUMN_LIST)
840						{
841							if (itemData.COLUMN_LIST.hasOwnProperty(k) && itemData.COLUMN_LIST[k].CODE === code)
842							{
843								entity[i].innerHTML = itemData.COLUMN_LIST[k].VALUE.replace(
844									new RegExp('(' + this.currentFilter.query + ')', 'gi'),
845									'<span class="basket-item-highlighted">$1</span>'
846								);
847							}
848						}
849					}
850					break;
851			}
852		}
853	};
854
855	BX.Sale.BasketFilter.prototype.showEmptyFilterResult = function()
856	{
857		var itemListNode = this.component.getCacheNode(this.component.ids.itemList);
858
859		if (BX.type.isDomNode(itemListNode) && itemListNode.clientHeight >= 500)
860		{
861			var emptyResultNode = this.component.getCacheNode(this.component.ids.itemListEmptyResult);
862
863			if (BX.type.isDomNode(emptyResultNode))
864			{
865				emptyResultNode.style.display = '';
866			}
867		}
868	};
869
870	BX.Sale.BasketFilter.prototype.hideEmptyFilterResult = function()
871	{
872		var emptyResultNode = this.component.getCacheNode(this.component.ids.itemListEmptyResult);
873
874		if (BX.type.isDomNode(emptyResultNode))
875		{
876			emptyResultNode.style.display = 'none';
877		}
878	};
879})();
880/* End */
881;
882; /* Start:"a:4:{s:4:"full";s:101:"/local/templates/bitrix66/components/bitrix/sale.basket.basket/basket/js/component.js?179136621270831";s:6:"source";s:85:"/local/templates/bitrix66/components/bitrix/sale.basket.basket/basket/js/component.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
883;(function() {
884	'use strict';
885
886	BX.namespace('BX.Sale.BasketComponent');
887
888	BX.Sale.BasketComponent = {
889		maxItemsShowCount: 30,
890		precisionFactor: Math.pow(10, 6),
891		stickyHeaderOffset: 0,
892
893		duration: {
894			priceAnimation: 300,
895			filterTimer: 300
896		},
897
898		ids: {
899			item: 'basket-item-',
900			quantity: 'basket-item-quantity-',
901			price: 'basket-item-price-',
902			sumPrice: 'basket-item-sum-price-',
903			sumPriceOld: 'basket-item-sum-price-old-',
904			sumPriceDiff: 'basket-item-sum-price-difference-',
905			itemHeightAligner: 'basket-item-height-aligner-',
906			total: 'basket-total-price',
907			basketRoot: 'basket-root',
908			itemListWrapper: 'basket-items-list-wrapper',
909			itemListContainer: 'basket-items-list-container',
910			itemList: 'basket-item-list',
911			itemListTable: 'basket-item-table',
912			itemListEmptyResult: 'basket-item-list-empty-result',
913			itemListOverlay: 'basket-items-list-overlay',
914			warning: 'basket-warning'
915		},
916
917		initializePrimaryFields: function()
918		{
919			this.templates = {};
920			this.nodes = {};
921
922			/** Object of all basket items (itemId => itemArray) */
923			this.items = {};
924
925			/** Array of all basket items to show sorted by field SORT */
926			this.sortedItems = [];
927
928			/** Array of basket items showed on screen */
929			this.shownItems = [];
930
931			/** Array of basket items changed since last request */
932			this.changedItems = [];
933
934			/** Array of basket items postponed by pool to edit */
935			this.postponedItems = [];
936
937			/** Array of basket items with warnings */
938			this.warningItems = [];
939
940			this.isMobile = BX.browser.IsMobile();
941			this.isTouch = BX.hasClass(document.documentElement, 'bx-touch');
942
943			this.lastAction = 'initialLoad';
944			this.coupons = null;
945
946			this.imagePopup = null;
947			this.loadingScreen = null;
948
949			this.quantityDelay = null;
950			this.quantityTimer = null;
951		},
952
953		init: function(parameters)
954		{
955			this.initializePrimaryFields();
956
957			this.params = parameters.params || {};
958			this.template = parameters.template || '';
959			this.signedParamsString = parameters.signedParamsString || '';
960			this.siteId = parameters.siteId || '';
961			this.siteTemplateId = parameters.siteTemplateId || '';
962			this.ajaxUrl = this.params.AJAX_PATH || '';
963			this.templateFolder = parameters.templateFolder || '';
964
965			this.useDynamicScroll = this.params.USE_DYNAMIC_SCROLL === 'Y';
966			this.useItemsFilter = this.params.SHOW_FILTER === 'Y' && !this.isMobile;
967
968			this.initializeFilter();
969			this.applyBasketResult(parameters.result);
970			this.initializeActionPool();
971
972			if (this.useItemsFilter)
973			{
974				this.checkHeaderDisplay();
975				this.bindHeaderEvents();
976			}
977
978			this.initializeBasketItems();
979			this.editTotal();
980			this.editWarnings();
981
982			this.getCacheNode(this.ids.basketRoot).style.opacity = 1;
983
984			this.bindInitialEvents();
985		},
986
987		getTemplate: function(templateName)
988		{
989			if (!this.templates.hasOwnProperty(templateName))
990			{
991				var template = BX(templateName);
992				this.templates[templateName] = BX.type.isDomNode(template) ? template.innerHTML : '';
993			}
994
995			return this.templates[templateName];
996		},
997
998		getCacheNode: function(id)
999		{
1000			if (!this.nodes.hasOwnProperty(id))
1001			{
1002				this.nodes[id] = BX(id);
1003			}
1004
1005			return this.nodes[id];
1006		},
1007
1008		getEntity: function(parent, entity, additionalFilter)
1009		{
1010			if (!parent || !entity)
1011				return null;
1012
1013			additionalFilter = additionalFilter || '';
1014
1015			return parent.querySelector(additionalFilter + '[data-entity="' + entity + '"]');
1016		},
1017
1018		getEntities: function(parent, entity, additionalFilter)
1019		{
1020			if (!parent || !entity)
1021				return {length: 0};
1022
1023			additionalFilter = additionalFilter || '';
1024
1025			return parent.querySelectorAll(additionalFilter + '[data-entity="' + entity + '"]');
1026		},
1027
1028		bindInitialEvents: function()
1029		{
1030			this.bindWarningEvents();
1031
1032			BX.bind(window, 'scroll', BX.proxy(this.checkStickyHeaders, this));
1033			BX.bind(window, 'scroll', BX.proxy(this.lazyLoad, this));
1034
1035			BX.bind(window, 'resize', BX.throttle(this.checkStickyHeaders, 20, this));
1036		},
1037
1038		bindWarningEvents: function()
1039		{
1040			var showItemsNode = this.getEntity(BX(this.ids.warning), 'basket-items-warning-count');
1041
1042			if (BX.type.isDomNode(showItemsNode))
1043			{
1044				showItemsNode.style.display = '';
1045				BX.bind(showItemsNode, 'click', BX.delegate(function() {this.toggleFilter('warning');}, this));
1046			}
1047
1048			BX.bind(
1049				this.getEntity(BX(this.ids.warning), 'basket-items-warning-notification-close'),
1050				'click',
1051				BX.proxy(this.removeAllWarnings, this)
1052			);
1053		},
1054
1055		toggleFilter: function(event)
1056		{
1057			var target = BX.type.isNotEmptyString(event) ?
1058				this.getEntity(
1059					this.getCacheNode(this.ids.itemListWrapper),
1060					'basket-items-count',
1061					'[data-filter="' + event + '"]'
1062				)
1063				: BX.getEventTarget(event);
1064
1065			if (!BX.type.isDomNode(target) || BX.hasClass(target, 'active'))
1066				return;
1067
1068			var entityName = target.getAttribute('data-filter');
1069			var entities = target.parentNode.querySelectorAll('[data-filter]');
1070
1071			for (var i = 0; i < entities.length; i++)
1072			{
1073				if (entities[i].getAttribute('data-filter') === entityName)
1074				{
1075					BX.addClass(entities[i], 'active');
1076				}
1077				else if (BX.hasClass(entities[i], 'active'))
1078				{
1079					BX.removeClass(entities[i], 'active');
1080				}
1081			}
1082
1083			this.filter.showFilterByName(entityName);
1084		},
1085
1086		scrollToFirstItem: function()
1087		{
1088			var headerNode = this.getEntity(this.getCacheNode(this.ids.itemListWrapper), 'basket-items-list-header');
1089
1090			if (BX.type.isDomNode(headerNode))
1091			{
1092				var itemListTopPosition = BX.pos(this.getCacheNode(this.ids.itemListContainer)).top;
1093				var headerBottomPosition = BX.pos(headerNode).bottom;
1094
1095				if (itemListTopPosition < headerBottomPosition)
1096				{
1097					window.scrollTo(0, itemListTopPosition - this.stickyHeaderOffset);
1098				}
1099			}
1100		},
1101
1102		showItemsOverlay: function()
1103		{
1104			var overlay = this.getCacheNode(this.ids.itemListOverlay);
1105
1106			if (BX.type.isDomNode(overlay))
1107			{
1108				overlay.style.display = '';
1109			}
1110		},
1111
1112		hideItemsOverlay: function()
1113		{
1114			var overlay = this.getCacheNode(this.ids.itemListOverlay);
1115
1116			if (BX.type.isDomNode(overlay))
1117			{
1118				overlay.style.display = 'none';
1119			}
1120		},
1121
1122		checkHeaderDisplay: function()
1123		{
1124			var header = this.getCacheNode(this.ids.itemListWrapper);
1125
1126			if (BX.type.isDomNode(header))
1127			{
1128				BX.removeClass(header, 'basket-items-list-wrapper-light');
1129			}
1130		},
1131
1132		bindHeaderEvents: function()
1133		{
1134			var entities = this.getEntities(this.getCacheNode(this.ids.itemListWrapper), 'basket-items-count');
1135
1136			for (var i = 0; i < entities.length; i++)
1137			{
1138				BX.bind(entities[i], 'click', BX.proxy(this.toggleFilter, this));
1139			}
1140		},
1141
1142		checkStickyHeaders: function()
1143		{
1144			if (this.isMobile)
1145				return;
1146
1147			var node, position;
1148			var border = 2, offset = 0;
1149			var scrollTop = this.getDocumentScrollTop();
1150			var basketPosition = BX.pos(this.getCacheNode(this.ids.basketRoot));
1151			var basketScrolledToEnd = scrollTop + 200 >= basketPosition.bottom;
1152
1153			/*if (BX.util.in_array('top', this.params.TOTAL_BLOCK_DISPLAY))
1154			{
1155				var totalBlockNode = this.getEntity(this.getCacheNode(this.ids.basketRoot), 'basket-total-block');
1156				if (BX.type.isDomNode(totalBlockNode))
1157				{
1158					node = this.getEntity(totalBlockNode, 'basket-checkout-aligner');
1159					if (BX.type.isDomNode(node))
1160					{
1161						position = BX.pos(totalBlockNode);
1162
1163						if (scrollTop >= position.top)
1164						{
1165							offset += node.clientHeight;
1166
1167							if (!BX.hasClass(node, 'basket-checkout-container-fixed'))
1168							{
1169								totalBlockNode.style.height = position.height + 'px';
1170
1171								node.style.width = node.clientWidth + border + 'px';
1172								BX.addClass(node, 'basket-checkout-container-fixed');
1173							}
1174						}
1175						else if (BX.hasClass(node, 'basket-checkout-container-fixed'))
1176						{
1177							totalBlockNode.style.height = '';
1178
1179							node.style.width = '';
1180							BX.removeClass(node, 'basket-checkout-container-fixed');
1181						}
1182
1183						if (basketScrolledToEnd)
1184						{
1185							if (!BX.hasClass(node, 'basket-checkout-container-fixed-hide'))
1186							{
1187								BX.addClass(node, 'basket-checkout-container-fixed-hide');
1188							}
1189						}
1190						else if (BX.hasClass(node, 'basket-checkout-container-fixed-hide'))
1191						{
1192							BX.removeClass(node, 'basket-checkout-container-fixed-hide');
1193						}
1194					}
1195				}
1196			}*/
1197
1198			if (this.useItemsFilter)
1199			{
1200				var itemWrapperNode = this.getCacheNode(this.ids.itemListWrapper);
1201
1202				node = this.getEntity(itemWrapperNode, 'basket-items-list-header');
1203				if (BX.type.isDomNode(node))
1204				{
1205					position = BX.pos(itemWrapperNode);
1206
1207					if ((scrollTop + offset >= position.top) && !basketScrolledToEnd)
1208					{
1209						if (!BX.hasClass(node, 'basket-items-list-header-fixed'))
1210						{
1211							node.style.width = node.clientWidth + border + 'px';
1212
1213							itemWrapperNode.style.paddingTop = node.clientHeight + 'px';
1214
1215							BX.addClass(node, 'basket-items-list-header-fixed');
1216						}
1217
1218						if (offset)
1219						{
1220							node.style.top = offset + 'px';
1221						}
1222
1223						offset += node.clientHeight;
1224					}
1225					else if (BX.hasClass(node, 'basket-items-list-header-fixed'))
1226					{
1227						itemWrapperNode.style.paddingTop = '';
1228
1229						node.style.width = '';
1230						node.style.top = '';
1231
1232						BX.removeClass(node, 'basket-items-list-header-fixed');
1233					}
1234				}
1235			}
1236
1237			this.stickyHeaderOffset = offset;
1238		},
1239
1240		getDocumentScrollTop: function()
1241		{
1242			return window.scrollY
1243				|| window.pageYOffset
1244				|| document.body.scrollTop + (document.documentElement && document.documentElement.scrollTop || 0);
1245		},
1246
1247		lazyLoad: function()
1248		{
1249			var itemsNodePosition = BX.pos(this.getCacheNode(this.ids.itemListContainer));
1250
1251			if (this.getDocumentScrollTop() + window.innerHeight >= itemsNodePosition.bottom - 400)
1252			{
1253				var itemIds = this.getItemsAfter();
1254				if (itemIds.length)
1255				{
1256					this.editBasketItems(itemIds);
1257				}
1258			}
1259		},
1260
1261		fireCustomEvents: function()
1262		{
1263			if (this.result.EVENT_ONCHANGE_ON_START === 'Y')
1264			{
1265				BX.onCustomEvent('OnBasketChange');
1266			}
1267
1268			if (this.params.HIDE_COUPON !== 'Y')
1269			{
1270				if (this.coupons !== null && this.coupons !== this.result.COUPON_LIST)
1271				{
1272					BX.onCustomEvent('OnCouponApply');
1273				}
1274
1275				this.coupons = this.result.COUPON_LIST;
1276			}
1277		},
1278
1279		editTotal: function()
1280		{
1281			this.fillTotalBlocks();
1282			this.showItemsCount();
1283			this.showWarningItemsCount();
1284			this.showNotAvailableItemsCount();
1285			this.showDelayedItemsCount();
1286		},
1287
1288		fillTotalBlocks: function()
1289		{
1290			var totalNodes = this.getEntities(this.getCacheNode(this.ids.basketRoot), 'basket-total-block');
1291
1292			if (totalNodes && totalNodes.length)
1293			{
1294				var totalTemplate = this.getTemplate('basket-total-template');
1295				if (totalTemplate)
1296				{
1297					var totalRender = this.render(totalTemplate, this.result.TOTAL_RENDER_DATA);
1298
1299					for (var i in totalNodes)
1300					{
1301						if (totalNodes.hasOwnProperty(i) && BX.type.isDomNode(totalNodes[i])
1301)
1302						{
1303							totalNodes[i].innerHTML = totalRender;
1304
1305							this.bindTotalEvents(totalNodes[i]);
1306						}
1307					}
1308				}
1309			}
1310
1311			this.checkStickyHeaders();
1312		},
1313
1314		showItemsCount: function()
1315		{
1316			var itemCountNode = this.getEntity(
1317				this.getCacheNode(this.ids.itemListWrapper),
1318				'basket-items-count',
1319				'[data-filter="all"]'
1320			);
1321
1322			if (BX.type.isDomNode(itemCountNode))
1323			{
1324				itemCountNode.innerHTML = BX.message('SBB_IN_BASKET') + ' ' + this.result.BASKET_ITEMS_COUNT + ' ' + this.getGoodsMessage(this.result.BASKET_ITEMS_COUNT);
1325				itemCountNode.style.display = '';
1326			}
1327		},
1328
1329		showSimilarCount: function(state)
1330		{
1331			var itemCountNode = this.getEntity(
1332				this.getCacheNode(this.ids.itemListWrapper),
1333				'basket-items-count',
1334				'[data-filter="similar"]'
1335			);
1336
1337			if (BX.type.isDomNode(itemCountNode))
1338			{
1339				if (state)
1340				{
1341					itemCountNode.innerHTML = this.sortedItems.length + ' '
1342						+ this.getGoodsMessage(this.result.BASKET_ITEMS_COUNT, 'SBB_SIMILAR_ITEM');
1343					itemCountNode.style.display = '';
1344				}
1345				else
1346				{
1347					itemCountNode.style.display = 'none';
1348				}
1349			}
1350		},
1351
1352		showWarningItemsCount: function()
1353		{
1354			var itemCountNode = this.getEntity(
1355				this.getCacheNode(this.ids.itemListWrapper),
1356				'basket-items-count',
1357				'[data-filter="warning"]'
1358			);
1359
1360			if (BX.type.isDomNode(itemCountNode))
1361			{
1362				if (this.warningItems.length)
1363				{
1364					itemCountNode.innerHTML = this.warningItems.length + ' ' + BX.message('SBB_BASKET_ITEMS_WARNING');
1365					itemCountNode.style.display = '';
1366				}
1367				else
1368				{
1369					itemCountNode.style.display = 'none';
1370				}
1371			}
1372		},
1373
1374		showNotAvailableItemsCount: function()
1375		{
1376			var itemCountNode = this.getEntity(
1377				this.getCacheNode(this.ids.itemListWrapper),
1378				'basket-items-count',
1379				'[data-filter="not-available"]'
1380			);
1381
1382			if (BX.type.isDomNode(itemCountNode))
1383			{
1384				if (parseInt(this.result.NOT_AVAILABLE_BASKET_ITEMS_COUNT))
1385				{
1386					itemCountNode.innerHTML = this.result.NOT_AVAILABLE_BASKET_ITEMS_COUNT + ' '
1387						+ this.getGoodsMessage(this.result.NOT_AVAILABLE_BASKET_ITEMS_COUNT, 'SBB_NOT_AVAILABLE_ITEM');
1388					itemCountNode.style.display = '';
1389				}
1390				else
1391				{
1392					itemCountNode.style.display = 'none';
1393				}
1394			}
1395		},
1396
1397		showDelayedItemsCount: function()
1398		{
1399			var itemCountNode = this.getEntity(
1400				this.getCacheNode(this.ids.itemListWrapper),
1401				'basket-items-count',
1402				'[data-filter="delayed"]'
1403			);
1404
1405			if (BX.type.isDomNode(itemCountNode))
1406			{
1407				if (parseInt(this.result.DELAYED_BASKET_ITEMS_COUNT))
1408				{
1409					itemCountNode.innerHTML = this.result.DELAYED_BASKET_ITEMS_COUNT + ' '
1410						+ this.getGoodsMessage(this.result.DELAYED_BASKET_ITEMS_COUNT, 'SBB_DELAYED_ITEM');
1411					itemCountNode.style.display = '';
1412				}
1413				else
1414				{
1415					itemCountNode.style.display = 'none';
1416				}
1417			}
1418		},
1419
1420		getGoodsMessage: function(count, customMessage)
1421		{
1422			var mesCode;
1423			var countReminder = (count > 10 && count < 20) ? 0 : count % 10;
1424
1425			if (countReminder === 1)
1426			{
1427				mesCode = customMessage || 'SBB_GOOD';
1428			}
1429			else if (countReminder >= 2 && countReminder <= 4)
1430			{
1431				mesCode = customMessage ? customMessage + '_2' : 'SBB_GOOD_2';
1432			}
1433			else
1434			{
1435				mesCode = customMessage ? customMessage + 'S' : 'SBB_GOODS';
1436			}
1437
1438			return BX.message(mesCode);
1439		},
1440
1441		bindTotalEvents: function(node)
1442		{
1443			if (!this.result.TOTAL_RENDER_DATA.DISABLE_CHECKOUT)
1444			{
1445				BX.bind(this.getEntity(node, 'basket-checkout-button'), 'click', BX.proxy(this.checkOutAction, this));
1446			}
1447
1448			BX.bind(this.getEntity(node, 'basket-coupon-input'), 'change', BX.proxy(this.addCouponAction, this));
1449			BX.bind(this.getEntity(node, 'basket-coupon-input'), 'paste', BX.proxy(this.pasteCouponAction, this));
1450
1451			var couponNodes = this.getEntities(node, 'basket-coupon-delete');
1452			for (var i = 0, l = couponNodes.length; i < l; i++)
1453			{
1454				BX.bind(couponNodes[i], 'click', BX.proxy(this.removeCouponAction, this));
1455			}
1456
1457		},
1458
1459		checkOutAction: function()
1460		{
1461			document.location.href = this.params.PATH_TO_ORDER;
1462		},
1463
1464		addCouponAction: function(event)
1465		{
1466			var target = BX.getEventTarget(event);
1467			if (target && target.value)
1468			{
1469				this.actionPool.addCoupon(target.value);
1470				target.disabled = true;
1471			}
1472		},
1473
1474		pasteCouponAction: function(event)
1475		{
1476			setTimeout(BX.delegate(function() {
1477				this.addCouponAction(event);
1478			}, this), 10);
1479		},
1480
1481		removeCouponAction: function()
1482		{
1483			var value = BX.proxy_context && BX.util.trim(BX.proxy_context.getAttribute('data-coupon'));
1484			if (value)
1485			{
1486				this.actionPool.removeCoupon(value);
1487			}
1488		},
1489
1490		initializeActionPool: function()
1491		{
1492			this.actionPool = new BX.Sale.BasketActionPool(this);
1493		},
1494
1495		initializeFilter: function()
1496		{
1497			this.filter = new BX.Sale.BasketFilter(this);
1498		},
1499
1500		/**
1501		 * Send ajax request with basket data and executes callback by action
1502		 */
1503		sendRequest: function(action, data)
1504		{
1505			this.lastAction = action;
1506
1507			if (this.lastAction === 'recalculateAjax')
1508			{
1509				// we use it to reload all items if applied discounts changed
1510				data.lastAppliedDiscounts = BX.util.array_keys(this.result.FULL_DISCOUNT_LIST).join(',');
1511
1512				if (this.params.USE_ENHANCED_ECOMMERCE === 'Y')
1513				{
1514					this.checkAnalytics(data);
1515				}
1516			}
1517
1518			BX.ajax({
1519				method: 'POST',
1520				dataType: 'json',
1521				url: this.ajaxUrl,
1522				data: this.getData(data),
1523				timeout: 30,
1524				async: true,
1525				processData: true,
1526				scriptsRunFirst: true,
1527				emulateOnload: true,
1528				start: true,
1529				cache: false,
1530				onsuccess: BX.delegate(function(result) {
1531
1532					/*if(data.openCart == 'Y' && result.BASKET_DATA.BASKET_ITEM_RENDER_DATA.length > 0) {
1533						noscrollbar();
1534						$('body').removeClass('menu-mobile');
1535						$('.cart-container, .modal-mask').addClass('active');
1536						$('.menu-toggler, .conteiner-menu').removeClass('active');
1537					}*/
1538
1539					this.actionPool.doProcessing(false);
1540
1541					if (BX.type.isPlainObject(result)) {
1542
1543						this.actionPool.setRefreshStatus(result.BASKET_REFRESHED);
1544
1545						if (result.RESTORED_BASKET_ITEMS) {
1546							this.restoreBasketItems(result.RESTORED_BASKET_ITEMS);
1547						} else if (result.CHANGED_BASKET_ITEMS.length > 0) {
1548							this.editBasketItems(result.CHANGED_BASKET_ITEMS);
1549						}
1550
1551						// applyBasketResult() складывает в changedItems только позиции, которые пришли
1552						// изменёнными;
1552 выбывших из корзины среди них нет. Из-за этого удаление строки
1553						// прямо в шторке оформления не перерасчитывало заказ: товар пропадал из списка,
1554						// а «Товары», «К оплате» и порог бесплатной доставки оставались от прежней
1555						// корзины до перезагрузки страницы. Слияние одинаковых позиций тоже меняет
1556						// состав корзины, поэтому учитываем оба списка.
1557						var itemsRemoved = (result.DELETED_BASKET_ITEMS && result.DELETED_BASKET_ITEMS.length > 0)
1558							|| (result.MERGED_BASKET_ITEMS && result.MERGED_BASKET_ITEMS.length > 0);
1559
1560						if (result.DELETED_BASKET_ITEMS) {
1561							this.deleteBasketItems(result.DELETED_BASKET_ITEMS, this.params.SHOW_RESTORE === 'Y');
1562						}
1563
1564						if (result.MERGED_BASKET_ITEMS) {
1565							this.deleteBasketItems(result.MERGED_BASKET_ITEMS, false, true);
1566						}
1567
1568						this.applyBasketResult(result.BASKET_DATA);
1569
1570						if (result.RESTORED_BASKET_ITEMS.length == 0 && result.CHANGED_BASKET_ITEMS.length > 0) {
1571							this.editBasketItems(result.CHANGED_BASKET_ITEMS);
1572						} else {
1573							this.editBasketItems(this.getItemsToEdit());
1574						}
1575						this.editTotal();
1576
1577						this.applyPriceAnimation();
1578						this.editWarnings();
1579
1580						//this.actionPool.switchTimer();
1581
1582						if (this.isBasketIntegrated() && (this.isBasketChanged() || itemsRemoved))
1583						{
1584							BX.Sale.OrderAjaxComponent.sendRequest('', 'basket');
1585						}
1586						var cartCount = result.BASKET_DATA.BASKET_ITEM_RENDER_DATA.length;
1587						if(cartCount > 0) {
1588							window.parent.$('#bx_basket').html('<div class="cart-count">'+cartCount+'</div>');
1589						}else{
1590							window.parent.$('#bx_basket .cart-count').remove();
1591						}
1592					}else return;
1593				}, this),
1594				onfailure: BX.delegate(function() {
1595					this.actionPool.doProcessing(false);
1596				}, this)
1597			});
1598		},
1599
1600		isBasketIntegrated: function()
1601		{
1602			return this.params.BASKET_WITH_ORDER_INTEGRATION === 'Y';
1603		},
1604
1605		isBasketChanged: function()
1606		{
1607			return this.changedItems.length;
1608		},
1609
1610		addPriceAnimationData: function(nodeId, start, finish, currency)
1611		{
1612			if (!BX.type.isPlainObject(this.priceAnimationData))
1613			{
1614				this.clearPriceAnimationData();
1615			}
1616
1617			this.priceAnimationData.start[nodeId] = parseFloat(start);
1618			this.priceAnimationData.finish[nodeId] = parseFloat(finish);
1619			this.priceAnimationData.currency[nodeId] = currency;
1620			this.priceAnimationData.int[nodeId] = (parseFloat(start) === parseInt(start)) && (parseFloat(finish) === parseInt(finish));
1621		},
1622
1623		clearPriceAnimationData: function()
1624		{
1625			this.priceAnimationData = {
1626				start: {},
1627				finish: {},
1628				currency: {},
1629				int: {}
1630			};
1631		},
1632
1633		applyBasketResult: function(result)
1634		{
1635			this.changedItems = [];
1636			this.clearPriceAnimationData();
1637
1638			if (!BX.type.isPlainObject(result))
1639			{
1640				return;
1641			}
1642
1643			if (result.BASKET_ITEM_RENDER_DATA)
1644			{
1645				//result.BASKET_ITEM_RENDER_DATA = result.BASKET_ITEM_RENDER_DATA.sort((a, b) => a.TOP > b.TOP ? 1 : -1);
1646				var i, newData;
1647
1648				for (i in result.BASKET_ITEM_RENDER_DATA)
1649				{
1650					if (result.BASKET_ITEM_RENDER_DATA.hasOwnProperty(i))
1651					{
1652						newData = result.BASKET_ITEM_RENDER_DATA[i];
1653						newData.WARNINGS = this.checkBasketItemWarnings(newData, result.WARNING_MESSAGE_WITH_CODE);
1654
1655						if (this.items[newData.ID])
1656						{
1657							if (JSON.stringify(this.items[newData.ID]) === JSON.stringify(newData))
1658							{
1659								continue;
1660							}
1661						}
1662						else
1663						{
1664							this.addSortedItem(newData.ID, true);
1665						}
1666
1667						this.changedItems.push(newData.ID);
1668
1669						newData = this.checkBasketItemsAnimation(newData);
1670						this.items[newData.ID] = newData;
1671					}
1672				}
1673
1674				this.changedItems = BX.util.array_unique(this.changedItems.concat(this.getChangedSimilarOffers()));
1675
1676				/*if (this.isBasketChanged())
1677				{
1678					this.sortSortedItems(true);
1679				}*/
1680			}
1681
1682			if (result.TOTAL_RENDER_DATA)
1683			{
1684				result.TOTAL_RENDER_DATA = this.checkTotalAnimation(result.TOTAL_RENDER_DATA);
1685			}
1686
1687			this.result = result;
1688		},
1689
1690		itemSortFunction: function(a, b)
1691		{
1692			if (!this.items.hasOwnProperty(a) || !this.items.hasOwnProperty(b))
1693			{
1694				return 0;
1695			}
1696
1697			return parseFloat(this.items[a].SORT) - parseFloat(this.items[b].SORT);
1698		},
1699
1700		getChangedSimilarOffers: function()
1701		{
1702			var changedSimilarOffers = [];
1703
1704			var otherSimilarItemsQuantity, totalSimilarItemsQuantity;
1705			var hashMap = this.getHashMap();
1706
1707			for (var hash in hashMap)
1708			{
1709				if (hashMap.hasOwnProperty(hash))
1710				{
1711					if (hashMap[hash].length > 1)
1712					{
1713						for (var i = 0; i < hashMap[hash].length; i++)
1714						{
1715							otherSimilarItemsQuantity = 0;
1716							totalSimilarItemsQuantity = 0;
1717
1718							for (var k = 0; k < hashMap[hash].length; k ++)
1719							{
1720								if (hashMap[hash][k] != hashMap[hash][i])
1721								{
1722									otherSimilarItemsQuantity += parseFloat(this.items[hashMap[hash][k]].QUANTITY);
1723								}
1724
1725								totalSimilarItemsQuantity += parseFloat(this.items[hashMap[hash][k]].QUANTITY);
1726							}
1727
1728							if (
1729								!this.items[hashMap[hash][i]].HAS_SIMILAR_ITEMS
1730								|| this.items[hashMap[hash][i]].SIMILAR_ITEMS_QUANTITY != otherSimilarItemsQuantity
1731								|| this.items[hashMap[hash][i]].TOTAL_SIMILAR_ITEMS_QUANTITY != totalSimilarItemsQuantity
1732							)
1733							{
1734								changedSimilarOffers.push(hashMap[hash][i]);
1735
1736								this.items[hashMap[hash][i]].HAS_SIMILAR_ITEMS = true;
1737								this.items[hashMap[hash][i]].SIMILAR_ITEMS_QUANTITY = otherSimilarItemsQuantity;
1738								this.items[hashMap[hash][i]].TOTAL_SIMILAR_ITEMS_QUANTITY = totalSimilarItemsQuantity;
1739
1740								this.items[hashMap[hash][i]].ALL_AVAILABLE_QUANTITY = this.items[hashMap[hash][i]].AVAILABLE_QUANTITY;
1741								this.items[hashMap[hash][i]].AVAILABLE_QUANTITY = this.items[hashMap[hash][i]].ALL_AVAILABLE_QUANTITY - otherSimilarItemsQuantity;
1742							}
1743						}
1744					}
1745					else if (hashMap[hash][0] && this.items[hashMap[hash][0]].HAS_SIMILAR_ITEMS)
1746					{
1747						changedSimilarOffers.push(hashMap[hash][0]);
1748
1749						delete this.items[hashMap[hash][0]].HAS_SIMILAR_ITEMS;
1750						delete this.items[hashMap[hash][0]].SIMILAR_ITEMS_QUANTITY;
1751						delete this.items[hashMap[hash][0]].TOTAL_SIMILAR_ITEMS_QUANTITY;
1752
1753						this.items[hashMap[hash][0]].AVAILABLE_QUANTITY = this.items[hashMap[hash][0]].ALL_AVAILABLE_QUANTITY;
1754						delete this.items[hashMap[hash][0]].ALL_AVAILABLE_QUANTITY;
1755					}
1756				}
1757			}
1758
1759			return changedSimilarOffers;
1760		},
1761
1762		getHashMap: function()
1763		{
1764			var hashMap = {};
1765
1766			for (var id in this.items)
1767			{
1768				if (this.items.hasOwnProperty(id) && this.isItemAvailable(id))
1769				{
1770					if (!hashMap.hasOwnProperty(this.items[id].HASH))
1771					{
1772						hashMap[this.items[id].HASH] = [];
1773					}
1774
1775					hashMap[this.items[id].HASH].push(id);
1776				}
1777			}
1778
1779			return hashMap;
1780		},
1781
1782		isItemAvailable: function(itemId)
1783		{
1784			var sortedItems = this.filter.isActive() ? this.filter.realSortedItems : this.sortedItems;
1785
1786			return !this.items[itemId].NOT_AVAILABLE
1787				&& !this.items[itemId].SHOW_RESTORE
1788				&& BX.util.in_array(itemId, sortedItems);
1789		},
1790
1791		checkTotalAnimation: function(totalData)
1792		{
1793			if (this.result && this.result.TOTAL_RENDER_DATA && parseFloat(this.result.TOTAL_RENDER_DATA.PRICE) > parseFloat(totalData.PRICE))
1794			{
1795				totalData.PRICE_NEW = totalData.PRICE;
1796				totalData.PRICE = this.result.TOTAL_RENDER_DATA.PRICE;
1797
1798				totalData.PRICE_FORMATED_NEW = totalData.PRICE_FORMATED;
1799				totalData.PRICE_FORMATED = this.result.TOTAL_RENDER_DATA.PRICE_FORMATED;
1800
1801				this.addPriceAnimationData(this.ids.total, totalData.PRICE, totalData.PRICE_NEW, totalData.CURRENCY);
1802			}
1803
1804			return totalData;
1805		},
1806
1807		checkBasketItemsAnimation: function(itemData)
1808		{
1809			var itemId = itemData.ID;
1810
1811			if (this.items[itemId])
1812			{
1813				var quantityNode = BX(this.ids.quantity + itemId);
1814				if (
1815					BX.type.isDomNode(quantityNode)
1816					&& !this.actionPool.isItemInPool(itemId)
1817					&& parseFloat(quantityNode.value) !== parseFloat(itemData.QUANTITY)
1818				)
1819				{
1820					itemData.QUANTITY_ANIMATION = true;
1821					this.actionPool.clearLastActualQuantityPool(itemId);
1822				}
1823
1824				if (parseFloat(this.items[itemId].PRICE) > parseFloat(itemData.PRICE))
1825				{
1826					itemData.PRICE_NEW = itemData.PRICE;
1827					itemData.PRICE = this.items[itemId].PRICE;
1828
1829					itemData.PRICE_FORMATED_NEW = itemData.PRICE_FORMATED;
1830					itemData.PRICE_FORMATED = this.items[itemId].PRICE_FORMATED;
1831
1832					this.addPriceAnimationData(this.ids.price + itemId, itemData.PRICE, itemData.PRICE_NEW, itemData.CURRENCY);
1833				}
1834
1835				if (
1836					BX.util.in_array('SUM', this.params.COLUMNS_LIST)
1837					&& parseFloat(this.items[itemId].SUM_PRICE) > parseFloat(itemData.SUM_PRICE)
1838					&& parseFloat(this.items[itemId].QUANTITY) === parseFloat(itemData.QUANTITY)
1839				)
1840				{
1841					itemData.SUM_PRICE_NEW = itemData.SUM_PRICE;
1842					itemData.SUM_PRICE = this.items[itemId].SUM_PRICE;
1843
1844					itemData.SUM_PRICE_FORMATED_NEW = itemData.SUM_PRICE_FORMATED;
1845					itemData.SUM_PRICE_FORMATED = this.items[itemId].SUM_PRICE_FORMATED;
1846
1847					this.addPriceAnimationData(this.ids.sumPrice + itemId, itemData.SUM_PRICE, itemData.SUM_PRICE_NEW, itemData.CURRENCY);
1848				}
1849			}
1850
1851			return itemData;
1852		},
1853
1854		getData: function(data)
1855		{
1856			data = data || {};
1857
1858			data[this.params.ACTION_VARIABLE] = this.lastAction;
1859			data.via_ajax = 'Y';
1860			data.site_id = this.siteId;
1861			data.site_template_id = this.siteTemplateId;
1862			data.sessid = BX.bitrix_sessid();
1863			data.template = this.template;
1864			data.signedParamsString = this.signedParamsString;
1865
1866			return data;
1867		},
1868
1869		startLoader: function()
1870		{
1871			/*if (!this.loadingScreen)
1872            {
1873                this.loadingScreen = new BX.PopupWindow('loading_screen', null, {
1874                    events: {
1875                        onAfterPopupShow: BX.delegate(function() {
1876                            BX.cleanNode(this.loadingScreen.popupContainer);
1877                            BX.removeClass(this.loadingScreen.popupContainer, 'popup-window');
1878                            this.loadingScreen.popupContainer.appendChild(
1879                                BX.create('IMG', {props: {src: this.templateFolder + '/images/loader.gif'}})
1880                            );
1881                            this.loadingScreen.popupContainer.removeAttribute('style');
1882                            this.loadingScreen.popupContainer.style.display = 'block';
1883                        }, this)
1884                    }
1885                });
1886               BX.addClass(this.loadingScreen.popupContainer, 'bx-step-opacity');
1887           }
1888
1889           this.loadingScreen.show();*/
1890		},
1891
1892		/**
1893		 * Hiding loader image with overlay.
1894		 */
1895		endLoader: function()
1896		{
1897			/*if (this.loadingScreen && this.loadingScreen.isShown())
1898			{
1899			 	this.loadingScreen.close();
1900			}*/
1901		},
1902
1903		editWarnings: function()
1904		{
1905			this.editGeneralWarnings();
1906			this.editBasketItemWarnings();
1907			this.toggleWarningBlock();
1908			this.showWarningItemsCount();
1909		},
1910
1911		editGeneralWarnings: function()
1912		{
1913			var warningsNode = this.getEntity(this.getCacheNode(this.ids.warning), 'basket-general-warnings');
1914
1915			if (BX.type.isDomNode(warningsNode))
1916			{
1917				var generalWarningText = warningsNode.innerHTML;
1918
1919				if (this.result.WARNING_MESSAGE_WITH_CODE)
1920				{
1921					for (var code in this.result.WARNING_MESSAGE_WITH_CODE)
1922					{
1923						if (this.result.WARNING_MESSAGE_WITH_CODE.hasOwnProperty(code))
1924						{
1925							if (
1926								!this.items[code]
1927								&& generalWarningText.indexOf(this.result.WARNING_MESSAGE_WITH_CODE[code]) === -1
1928							)
1929							{
1930								generalWarningText += this.result.WARNING_MESSAGE_WITH_CODE[code] + '<br/>';
1931							}
1932						}
1933					}
1934				}
1935
1936				if (generalWarningText)
1937				{
1938					warningsNode.innerHTML = generalWarningText;
1939					warningsNode.style.display = '';
1940				}
1941				else
1942				{
1943					warningsNode.style.display = 'none';
1944					warningsNode.innerHTML = '';
1945				}
1946			}
1947		},
1948
1949		editBasketItemWarnings: function()
1950		{
1951			var itemsWarningsNode = this.getEntity(this.getCacheNode(this.ids.warning), 'basket-item-warnings');
1952
1953			if (BX.type.isDomNode(itemsWarningsNode))
1954			{
1955				if (this.warningItems.length)
1956				{
1957					var warningCount = this.getEntity(itemsWarningsNode, 'basket-items-warning-count');
1958					if (BX.type.isDomNode(warningCount))
1959					{
1960						warningCount.innerHTML = this.warningItems.length + ' ' + this.getGoodsMessage(this.warningItems.length);
1961					}
1962
1963					itemsWarningsNode.style.display = '';
1964				}
1965				else if (itemsWarningsNode.style.display !== 'none')
1966				{
1967					itemsWarningsNode.style.display = 'none';
1968
1969					if (this.filter.isActive())
1970					{
1971						this.toggleFilter('all');
1972					}
1973				}
1974			}
1975		},
1976
1977		toggleWarningBlock: function()
1978		{
1979			var warningNode = this.getCacheNode(this.ids.warning);
1980
1981			if (BX.type.isDomNode(warningNode))
1982			{
1983				var generalWarningNode = this.getEntity(warningNode, 'basket-general-warnings');
1984				var itemsWarningsNode = this.getEntity(warningNode, 'basket-item-warnings');
1985
1986				if (
1987					(!BX.type.isDomNode(generalWarningNode) || generalWarningNode.style.display === 'none')
1988					&& (!BX.type.isDomNode(itemsWarningsNode) || itemsWarningsNode.style.display === 'none')
1989				)
1990				{
1991					warningNode.style.display = 'none';
1992				}
1993				else
1994				{
1995					warningNode.style.display = '';
1996				}
1997			}
1998		},
1999
2000		checkBasketItemWarnings: function(itemData, warnings)
2001		{
2002			if (!itemData)
2003				return;
2004
2005			var itemWarnings;
2006
2007			if (this.items[itemData.ID] && this.lastAction === 'refreshAjax')
2008			{
2009				itemWarnings = this.items[itemData.ID].WARNINGS;
2010			}
2011			else
2012			{
2013				itemWarnings = [];
2014			}
2015
2016			if (BX.type.isArray(warnings[itemData.ID]) && warnings[itemData.ID].length)
2017			{
2018				for (var i in warnings[itemData.ID])
2019				{
2020					if (warnings[itemData.ID].hasOwnProperty(i) && !BX.util.in_array(warnings[itemData.ID][i], itemWarnings))
2021					{
2022						itemWarnings.push(warnings[itemData.ID][i]);
2023					}
2024				}
2025			}
2026
2027			if (itemWarnings.length)
2028			{
2029				if (!BX.util.in_array(itemData.ID, this.warningItems))
2030				{
2031					this.warningItems.push(itemData.ID);
2032				}
2033			}
2034			else if (BX.util.in_array(itemData.ID, this.warningItems))
2035			{
2036				this.warningItems.splice(BX.util.array_search(itemData.ID, this.warningItems), 1);
2037			}
2038
2039			return itemWarnings;
2040		},
2041
2042		removeAllWarnings: function(event)
2043		{
2044			this.clearGeneralWarnings();
2045			this.clearBasketItemsWarnings();
2046
2047			this.editWarnings();
2048
2049			event && event.preventDefault();
2050		},
2051
2052		clearGeneralWarnings: function()
2053		{
2054			this.result.WARNING_MESSAGE_WITH_CODE = {};
2055
2056			var generalWarningNode = this.getEntity(this.getCacheNode(this.ids.warning), 'basket-general-warnings');
2057
2058			if (BX.type.isDomNode(generalWarningNode))
2059			{
2060				generalWarningNode.innerHTML = '';
2061			}
2062		},
2063
2064		clearBasketItemsWarnings: function()
2065		{
2066			var itemsToEdit = [];
2067
2068			for (var i in this.warningItems)
2069			{
2070				if (this.warningItems.hasOwnProperty(i))
2071				{
2072					this.items[this.warningItems[i]].WARNINGS = [];
2073
2074					if (this.isItemShown(this.warningItems[i]))
2075					{
2076						itemsToEdit.push(this.warningItems[i]);
2077					}
2078				}
2079			}
2080
2081			this.warningItems = [];
2082			this.editBasketItems(itemsToEdit);
2083		},
2084
2085		isItemShown: function(itemId)
2086		{
2087			return BX.util.in_array(itemId, this.shownItems);
2088		},
2089
2090		initializeBasketItems: function()
2091		{
2092			if (Object.keys(this.items).length === 0)
2093				return;
2094
2095			for (var i = 0; i < this.sortedItems.length; i++)
2096			{
2097				if (this.useDynamicScroll && this.shownItems.length >= this.maxItemsShowCount)
2098				{
2099					break;
2100				}
2101
2102				this.createBasketItem(this.sortedItems[i]);
2103			}
2104		},
2105
2106		createBasketItem: function(itemId)
2107		{
2108			if (!this.items[itemId])
2109			{
2110				return;
2111			}
2112
2113			var basketItemTemplate = this.getTemplate('basket-item-template');
2114			if (basketItemTemplate)
2115			{
2116				var basketItemHtml = this.renderBasketItem(basketItemTemplate, this.items[itemId]);
2117				var sortIndex = BX.util.array_search(itemId, this.sortedItems);
2118
2119				if (this.shownItems.length && sortIndex >= 0)
2120				{
2121					if (sortIndex < BX.util.array_search(this.shownItems[0], this.sortedItems))
2122					{
2123						// insert before
2124						BX(this.ids.item + this.shownItems[0]).insertAdjacentHTML('beforebegin', basketItemHtml);
2125						this.shownItems.unshift(itemId);
2126					}
2127					else if (sortIndex > BX.util.array_search(this.shownItems[this.shownItems.length - 1], this.sortedItems))
2128					{
2129						// insert after
2130						BX(this.ids.item + this.shownItems[this.shownItems.length - 1]).insertAdjacentHTML('afterend', basketItemHtml);
2131						this.shownItems.push(itemId);
2132					}
2133					else
2134					{
2135						// insert between
2136						BX(this.ids.item + this.sortedItems[sortIndex + 1]).insertAdjacentHTML('beforebegin', basketItemHtml);
2137						this.shownItems.splice(sortIndex + 1, 0, itemId);
2138					}
2139				}
2140				else
2141				{
2142					this.getCacheNode(this.ids.itemListTable).insertAdjacentHTML('beforeend', basketItemHtml);
2143					this.shownItems.push(itemId);
2144				}
2145
2146				this.bindBasketItemEvents(this.items[itemId]);
2147
2148				if (this.filter.isActive())
2149				{
2150					this.filter.highlightSearchMatch(this.items[itemId]);
2151				}
2152			}
2153		},
2154
2155		getItemsToEdit: function()
2156		{
2157			var itemIds = [];
2158
2159			if (this.isBasketChanged())
2160			{
2161				for (var i in this.changedItems)
2162				{
2163					if (this.changedItems.hasOwnProperty(i) && this.isItemShown(this.changedItems[i]))
2164					{
2165						itemIds.push(this.changedItems[i]);
2166					}
2167				}
2168			}
2169
2170			return itemIds;
2171		},
2172
2173		getItemsAfter: function()
2174		{
2175			var itemIdsAfter = [];
2176
2177			if (this.useDynamicScroll)
2178			{
2179				var lastShownItemId = this.shownItems[this.shownItems.length - 1] || false;
2180
2181				if (lastShownItemId)
2182				{
2183					var i = 0;
2184					var index = BX.util.array_search(lastShownItemId, this.sortedItems);
2185
2186					while (this.sortedItems[++index] && i++ < this.maxItemsShowCount)
2187					{
2188						itemIdsAfter.push(this.sortedItems[index]);
2189					}
2190				}
2191			}
2192
2193			return itemIdsAfter;
2194		},
2195
2196		editBasketItems: function(itemIds)
2197		{
2198
2199			if (!itemIds || itemIds.length === 0)
2200			{
2201				return;
2202			}
2203
2204			var i, item;
2205
2206			for (i in itemIds)
2207			{
2208				if (!itemIds.hasOwnProperty(i) || !BX.type.isPlainObject(this.items[itemIds[i]]))
2209				{
2210					continue;
2211				}
2212
2213				item = this.items[itemIds[i]];
2214
2215				if (this.actionPool.isItemInPool(item.ID))
2216				{
2217					if (!BX.util.in_array(item.ID, this.postponedItems))
2218					{
2219						this.postponedItems.push(item.ID);
2220					}
2221
2222					continue;
2223				}
2224
2225				if (BX.type.isDomNode(BX(this.ids.item + item.ID)))
2226				{
2227					this.redrawBasketItemNode(item.ID);
2228					this.applyQuantityAnimation(item.ID);
2229				}
2230				else
2231				{
2232					this.createBasketItem(item.ID);
2233				}
2234			}
2235		},
2236
2237		editPostponedBasketItems: function()
2238		{
2239			if (!this.postponedItems.length)
2240				return;
2241
2242			var itemsToEdit = [];
2243
2244			for (var i in this.postponedItems)
2245			{
2246				if (this.postponedItems.hasOwnProperty(i) && this.isItemShown(this.postponedItems[i]))
2247				{
2248					itemsToEdit.push(this.postponedItems[i]);
2249				}
2250			}
2251
2252			this.postponedItems = [];
2253			this.editBasketItems(itemsToEdit);
2254		},
2255
2256		applyQuantityAnimation: function(itemId)
2257		{
2258			var basketItemNode = BX(this.ids.item + itemId);
2259
2260			if (BX.type.isDomNode(basketItemNode) && this.items[itemId])
2261			{
2262				if (this.items[itemId].QUANTITY_ANIMATION)
2263				{
2264					BX.addClass(BX(this.ids.quantity + itemId), 'basket-updated');
2265				}
2266			}
2267		},
2268
2269		applyPriceAnimation: function()
2270		{
2271
2272			if (!this.priceAnimationData || Object.keys(this.priceAnimationData.start).length === 0)
2273				return;
2274
2275			var animationData = this.priceAnimationData,
2276				nodeCache = {};
2277
2278			new BX.easing({
2279				duration: this.params.USE_PRICE_ANIMATION === 'Y' ? this.duration.priceAnimation : 1,
2280				start: animationData.start,
2281				finish: animationData.finish,
2282				transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
2283				step: BX.delegate(function(state){
2284					for (var nodeId in animationData.start)
2285					{
2286						if (animationData.start.hasOwnProperty(nodeId))
2287						{
2288							if (!nodeCache[nodeId])
2289							{
2290								if (nodeId === this.ids.total)
2291								{
2292									nodeCache[nodeId] = this.getEntities(this.getCacheNode(this.ids.basketRoot), this.ids.total);
2293								}
2294								else
2295								{
2296									var node = BX(nodeId);
2297									nodeCache[nodeId] = node ? [node] : [];
2298								}
2299							}
2300
2301							if (!animationData.int[nodeId])
2302							{
2303								// fix price blinking
2304								state[nodeId] = (state[nodeId] + (state[nodeId] % 1000) / 1000).toFixed(5);
2305							}
2306
2307							for (var i = 0; i < nodeCache[nodeId].length; i++)
2308							{
2309								if (nodeId === this.ids.total) {
2310									nodeCache[nodeId][i].innerHTML = this.getFormatPrice(state[nodeId], animationData.currency[nodeId])+' ₽';
2311								}else {
2312									nodeCache[nodeId][i].innerHTML = '₽ ' + this.getFormatPrice(state[nodeId], animationData.currency[nodeId]);
2313								}
2314							}
2315						}
2316					}
2317				}, this),
2318				complete: BX.delegate(function() {
2319					var nodeId, formattedPrice, itemId, type;
2320
2321					for (nodeId in animationData.start)
2322					{
2323						if (animationData.start.hasOwnProperty(nodeId)) {
2324							formattedPrice = this.getFormatPrice(animationData.finish[nodeId], animationData.currency[nodeId]);
2325
2326							for (var i = 0; i < nodeCache[nodeId].length; i++)
2327							{
2328								if (nodeId.indexOf(this.ids.total) !== -1) {
2329									nodeCache[nodeId][i].innerHTML = formattedPrice+' ₽';
2330								}else{
2331									nodeCache[nodeId][i].innerHTML = '₽ '+formattedPrice;
2332								}
2333							}
2334
2335							if (nodeId.indexOf(this.ids.sumPrice) !== -1)
2336							{
2337								type = 'SUM_PRICE';
2338								itemId = nodeId.substr(this.ids.sumPrice.length);
2339							}
2340							else if (nodeId.indexOf(this.ids.price) !== -1)
2341							{
2342								type = 'PRICE';
2343								itemId = nodeId.substr(this.ids.price.length);
2344							}
2345							else if (nodeId.indexOf(this.ids.total) !== -1)
2346							{
2347								type = 'TOTAL';
2348								itemId = '';
2349							}
2350							else
2351							{
2352								itemId = '';
2353								type = '';
2354							}
2355
2356							if (BX.type.isNotEmptyString(type))
2357							{
2358								if (itemId)
2359								{
2360									this.items[itemId][type] = animationData.finish[nodeId];
2361									delete this.items[itemId][type + '_NEW'];
2362									this.items[itemId][type + '_FORMATED'] = formattedPrice;
2363									delete this.items[itemId][type + '_FORMATED_NEW'];
2364								}
2365								else if (type === 'TOTAL')
2366								{
2367									this.result.TOTAL_RENDER_DATA.PRICE = animationData.finish[nodeId];
2368									delete this.result.TOTAL_RENDER_DATA.PRICE_NEW;
2369									this.result.TOTAL_RENDER_DATA.PRICE_FORMATED = formattedPrice;
2370									delete this.result.TOTAL_RENDER_DATA.PRICE_FORMATED_NEW;
2371								}
2372							}
2373						}
2374					}
2375
2376					this.filter.highlightFoundItems();
2377				}, this)
2378			}).animate();
2379		},
2380
2381		getFormatPrice: function(price, currency)
2382		{
2383			return BX.Currency.currencyFormat(price, currency, true);
2384		},
2385
2386		deleteBasketItems: function(items, restore, final)
2387		{
2388			if (!items || !items.length)
2389			{
2390				return;
2391			}
2392
2393			for (var i in items)
2394			{
2395				if (items.hasOwnProperty(i))
2396				{
2397					this.deleteBasketItem(items[i], restore, final);
2398				}
2399			}
2400		},
2401
2402		deleteBasketItem: function(itemId, restore, final)
2403		{
2404			// delete not available item with no chance to restore
2405			if (this.items[itemId].NOT_AVAILABLE && restore)
2406			{
2407				restore = false;
2408				final = true;
2409			}
2410
2411			if (restore)
2412			{
2413				this.items[itemId].SHOW_RESTORE = true;
2414				this.items[itemId].SHOW_LOADING = false;
2415				this.redrawBasketItemNode(itemId);
2416			}
2417			else
2418			{
2419				this.changeShownItem(itemId);
2420				BX.remove(BX(this.ids.item + itemId));
2421			}
2422
2423			if (final)
2424			{
2425				this.changeSortedItem(itemId, false, true);
2426				this.changeShownItem(itemId, false, true);
2427			}
2428		},
2429
2430		addSortedItem: function(itemId, all)
2431		{
2432			this.sortedItems.push(itemId.toString());
2433
2434			if (all && this.filter.isActive())
2435			{
2436				this.filter.realSortedItems.push(itemId.toString());
2437			}
2438		},
2439
2440		changeSortedItem: function(itemId, newItemId, all)
2441		{
2442			var index = BX.util.array_search(itemId, this.sortedItems);
2443
2444			if (index >= 0)
2445			{
2446				if (newItemId)
2447				{
2448					this.sortedItems.splice(index, 1, newItemId.toString());
2449				}
2450				else
2451				{
2452					this.sortedItems.splice(index, 1);
2453				}
2454			}
2455
2456			if (all && this.filter.isActive())
2457			{
2458				index = BX.util.array_search(itemId, this.filter.realSortedItems);
2459
2460				if (index >= 0)
2461				{
2462					if (newItemId)
2463					{
2464						this.filter.realSortedItems.splice(index, 1, newItemId.toString());
2465					}
2466					else
2467					{
2468						this.filter.realSortedItems.splice(index, 1);
2469					}
2470				}
2471			}
2472		},
2473
2474		sortSortedItems: function(all)
2475		{
2476			this.sortedItems.sort(BX.proxy(this.itemSortFunction, this));
2477
2478			if (all && this.filter.isActive())
2479			{
2480				this.filter.realSortedItems.sort(BX.proxy(this.itemSortFunction, this));
2481			}
2482		},
2483
2484		changeShownItem: function(itemId, newItemId, all)
2485		{
2486			var index = BX.util.array_search(itemId, this.shownItems);
2487
2488			if (index >= 0)
2489			{
2490				if (newItemId)
2491				{
2492					this.shownItems.splice(index, 1, newItemId.toString());
2493				}
2494				else
2495				{
2496					this.shownItems.splice(index, 1);
2497				}
2498			}
2499
2500			if (all && this.filter.isActive())
2501			{
2502				index = BX.util.array_search(itemId, this.filter.realShownItems);
2503
2504				if (index >= 0)
2505				{
2506					if (newItemId)
2507					{
2508						this.filter.realShownItems.splice(index, 1, newItemId.toString());
2509					}
2510					else
2511					{
2512						this.filter.realShownItems.splice(index, 1);
2513					}
2514				}
2515			}
2516		},
2517
2518		redrawBasketItemNode: function(itemId)
2519		{
2520			var basketItemNode = BX(this.ids.item + itemId);
2521
2522			if (!this.items[itemId] || !BX.type.isDomNode(basketItemNode))
2523				return;
2524
2525			var basketItemTemplate = this.getTemplate('basket-item-template');
2526			if (basketItemTemplate)
2527			{
2528				var nodeAligner = BX(this.ids.itemHeightAligner + itemId),
2529					oldHeight;
2530
2531				if (BX.type.isDomNode(nodeAligner))
2532				{
2533					oldHeight = nodeAligner.clientHeight;
2534				}
2535
2536				var basketItemHtml = this.renderBasketItem(basketItemTemplate, this.items[itemId]);
2537				basketItemNode.insertAdjacentHTML('beforebegin', basketItemHtml);
2538				BX.remove(basketItemNode);
2539
2540				if (oldHeight)
2541				{
2542					nodeAligner = BX(this.ids.itemHeightAligner + itemId);
2543
2544					if (BX.type.isDomNode(nodeAligner) && nodeAligner.clientHeight < oldHeight)
2545					{
2546						nodeAligner.style.minHeight = oldHeight + 'px';
2547						setTimeout(function(){nodeAligner.style.minHeight = '0px';}, 1);
2548					}
2549				}
2550
2551				this.bindBasketItemEvents(this.items[itemId]);
2552
2553				if (this.filter.isActive())
2554				{
2555					this.filter.highlightSearchMatch(this.items[itemId]);
2556				}
2557			}
2558		},
2559
2560		restoreBasketItems: function(items)
2561		{
2562			if (!items || Object.keys(items).length === 0)
2563			{
2564				return;
2565			}
2566
2567			var oldItemId, newItemId, basketItemNode;
2568
2569			for (oldItemId in items)
2570			{
2571				if (items.hasOwnProperty(oldItemId))
2572				{
2573					newItemId = items[oldItemId];
2574
2575					if (this.isItemShown(oldItemId))
2576					{
2577						this.changeShownItem(oldItemId, newItemId, true);
2578
2579						basketItemNode = BX(this.ids.item + oldItemId);
2580						if (BX.type.isDomNode(basketItemNode))
2581						{
2582							basketItemNode.id = this.ids.item + newItemId;
2583							basketItemNode.setAttribute('data-id', newItemId);
2584						}
2585					}
2586
2587					this.changeSortedItem(oldItemId, false, true);
2588				}
2589			}
2590		},
2591
2592		bindBasketItemEvents: function(itemData)
2593		{
2594			if (!itemData)
2595				return;
2596
2597			var itemNode = BX(this.ids.item + itemData.ID);
2598			if (BX.type.isDomNode(itemNode))
2599			{
2600				this.bindQuantityEvents(itemNode, itemData);
2601				this.bindSkuEvents(itemNode, itemData);
2602				this.bindImageEvents(itemNode, itemData);
2603				this.bindActionEvents(itemNode, itemData);
2604				this.bindRestoreAction(itemNode, itemData);
2605				this.bindItemWarningEvents(itemNode, itemData);
2606			}
2607		},
2608
2609		bindQuantityEvents: function(node, data)
2610		{
2611			if (!node || !data || !this.isItemAvailable(data.ID))
2612				return;
2613
2614			var entity;
2615
2616			var block = this.getEntity(node, 'basket-item-quantity-block');
2617			if (block)
2618			{
2619				var startEventName = this.isTouch ? 'touchstart' : 'mousedown';
2620				var endEventName = this.isTouch ? 'touchend' : 'mouseup';
2621
2622				entity = this.getEntity(block, 'basket-item-quantity-minus');
2623				BX.bind(entity, startEventName, BX.proxy(this.startQuantityInterval, this));
2624				BX.bind(entity, endEventName, BX.proxy(this.clearQuantityInterval, this));
2625				BX.bind(entity, 'mouseout', BX.proxy(this.clearQuantityInterval, this));
2626				BX.bind(entity, 'click', BX.proxy(this.quantityMinus, this));
2627
2628				entity = this.getEntity(block, 'basket-item-quantity-plus');
2629				BX.bind(entity, startEventName, BX.proxy(this.startQuantityInterval, this));
2630				BX.bind(entity, endEventName, BX.proxy(this.clearQuantityInterval, this));
2631				BX.bind(entity, 'mouseout', BX.proxy(this.clearQuantityInterval, this));
2632				BX.bind(entity, 'click', BX.proxy(this.quantityPlus, this));
2633
2634				entity = this.getEntity(block, 'basket-item-quantity-field');
2635				BX.bind(entity, 'change', BX.proxy(this.quantityChange, this));
2636			}
2637		},
2638
2639		startQuantityInterval: function()
2640		{
2641			var target = BX.proxy_context;
2642			var func = target.getAttribute('data-entity') === 'basket-item-quantity-minus'
2643				? BX.proxy(this.quantityMinus, this)
2644				: BX.proxy(this.quantityPlus, this);
2645
2646			this.quantityDelay = setTimeout(
2647				BX.delegate(function() {
2648					this.quantityTimer = setInterval(function(){func(target);}, 150);
2649				}, this),
2650				300
2651			);
2652		},
2653
2654		clearQuantityInterval: function()
2655		{
2656			clearTimeout(this.quantityDelay);
2657			clearInterval(this.quantityTimer);
2658		},
2659
2660		quantityPlus: function(target)
2661		{
2662			if (!BX.type.isDomNode(target))
2663			{
2664				target = BX.proxy_context;
2665				this.clearQuantityInterval();
2666			}
2667
2668			var itemData = this.getItemDataByTarget(target);
2669			if (itemData)
2670			{
2671				var quantityField = BX(this.ids.quantity + itemData.ID);
2672				var isQuantityFloat = this.isQuantityFloat(itemData);
2673
2674				var currentQuantity = isQuantityFloat ? parseFloat(quantityField.value) : Math.round(quantityField.value);
2675				var measureRatio = isQuantityFloat ? parseFloat(itemData.MEASURE_RATIO) : parseInt(itemData.MEASURE_RATIO);
2676
2677				var quantity = parseFloat((currentQuantity + measureRatio).toFixed(5));
2678				quantity = this.getCorrectQuantity(itemData, quantity);
2679
2680				this.setQuantity(itemData, quantity);
2681			}
2682		},
2683
2684		quantityMinus: function(target)
2685		{
2686			target = BX.type.isDomNode(target) ? target : BX.proxy_context;
2687
2688			var itemData = this.getItemDataByTarget(target);
2689			if (itemData)
2690			{
2691				var quantityField = BX(this.ids.quantity + itemData.ID);
2692				var isQuantityFloat = this.isQuantityFloat(itemData);
2693
2694				var currentQuantity = isQuantityFloat ? parseFloat(quantityField.value) : Math.round(quantityField.value);
2695				var measureRatio = isQuantityFloat ? parseFloat(itemData.MEASURE_RATIO) : parseInt(itemData.MEASURE_RATIO);
2696
2697				var quantity = parseFloat((currentQuantity - measureRatio).toFixed(5));
2698				quantity = this.getCorrectQuantity(itemData, quantity);
2699
2700				this.setQuantity(itemData, quantity);
2701			}
2702		},
2703
2704		quantityChange: function()
2705		{
2706			var itemData = this.getItemDataByTarget(BX.proxy_context);
2707			if (itemData)
2708			{
2709				var quantityField, quantity;
2710
2711				quantityField = BX(this.ids.quantity + itemData.ID);
2712				quantity = this.getCorrectQuantity(itemData, quantityField.value);
2713
2714				this.setQuantity(itemData, quantity);
2715			}
2716		},
2717
2718		isQuantityFloat: function(item)
2719		{
2720			return this.params.QUANTITY_FLOAT === 'Y' || (parseInt(item.MEASURE_RATIO) !== parseFloat(item.MEASURE_RATIO));
2721		},
2722
2723		getCorrectQuantity: function(itemData, quantity)
2724		{
2725			var isQuantityFloat = this.isQuantityFloat(itemData),
2726				measureRatio = isQuantityFloat ? parseFloat(itemData.MEASURE_RATIO) : parseInt(itemData.MEASURE_RATIO),
2727				availableQuantity = 0;
2728
2729			quantity = (isQuantityFloat ? parseFloat(quantity) : parseInt(quantity, 10)) || 0;
2730			if (quantity < 0)
2731			{
2732				quantity = 0;
2733			}
2734
2735			if (measureRatio > 0 && quantity < measureRatio)
2736			{
2737				quantity = measureRatio;
2738			}
2739
2740			if (itemData.CHECK_MAX_QUANTITY === 'Y')
2741			{
2742				availableQuantity = isQuantityFloat ? parseFloat(itemData.AVAILABLE_QUANTITY) : parseInt(itemData.AVAILABLE_QUANTITY);
2743				if (availableQuantity > 0 && quantity > availableQuantity)
2744				{
2745					quantity = availableQuantity;
2746				}
2747			}
2748
2749			var reminder = (quantity / measureRatio - ((quantity / measureRatio).toFixed(0))).toFixed(5),
2750				remain;
2751
2752			if (parseFloat(reminder) === 0)
2753			{
2754				return quantity;
2755			}
2756
2757			if (measureRatio !== 0 && measureRatio !== 1)
2758			{
2759				remain = (quantity * this.precisionFactor) % (measureRatio * this.precisionFactor) / this.precisionFactor;
2760
2761				if (measureRatio > 0 && remain > 0)
2762				{
2763					if (
2764						remain >= measureRatio / 2
2765						&& (
2766							availableQuantity === 0
2767							|| (quantity + measureRatio - remain) <= availableQuantity
2768						)
2769					)
2770					{
2771						quantity += (measureRatio - remain);
2772					}
2773					else
2774					{
2775						quantity -= remain;
2776					}
2777				}
2778			}
2779
2780			quantity = isQuantityFloat ? parseFloat(quantity) : parseInt(quantity, 10);
2781
2782			return quantity;
2783		},
2784
2785		setQuantity: function(itemData, quantity)
2786		{
2787			var quantityField = BX(this.ids.quantity + itemData.ID),
2788				currentQuantity;
2789
2790			if (quantityField)
2791			{
2792				quantity = parseFloat(quantity);
2793				currentQuantity = parseFloat(quantityField.getAttribute('data-value'));
2794
2795				quantityField.value = quantity;
2796
2797				if (parseFloat(itemData.QUANTITY) !== parseFloat(quantity))
2798				{
2799					this.animatePriceByQuantity(itemData, quantity);
2800					this.actionPool.changeQuantity(itemData.ID, quantity, currentQuantity);
2801				}
2802			}
2803		},
2804
2805		animatePriceByQuantity: function(itemData, quantity)
2806		{
2807			var priceNode = BX(this.ids.sumPrice + itemData.ID);
2808			if (!BX.type.isDomNode(priceNode))
2809				return;
2810
2811			var quantityMultiplier = quantity / parseFloat(itemData.MEASURE_RATIO);
2812
2813			var startPrice = parseFloat(itemData.SUM_PRICE),
2814				finalPrice = parseFloat(itemData.PRICE) * quantityMultiplier,
2815				isInt = parseInt(startPrice) === parseFloat(startPrice)
2816					&& parseInt(finalPrice) === parseFloat(finalPrice);
2817
2818			if (startPrice !== finalPrice) {
2819				this.items[itemData.ID].QUANTITY = quantity;
2820				this.items[itemData.ID].SUM_PRICE = finalPrice;
2821
2822				new BX.easing({
2823					duration: this.params.USE_PRICE_ANIMATION === 'Y' ? this.duration.priceAnimation : 1,
2824					start: {price: startPrice},
2825					finish: {price: finalPrice},
2826					transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
2827					step: BX.delegate(function(state){
2828						if (!isInt)
2829						{
2830							// fix price blinking
2831
2832						}
2833						state.price = (state.price + (state.price % 1000) / 1000).toFixed(0);
2834
2835						priceNode.innerHTML = '₽ '+this.getFormatPrice(state.price, itemData.CURRENCY);
2836					}, this),
2837					complete: BX.delegate(function() {
2838						var node, price;
2839
2840						priceNode.innerHTML = '₽ '+this.getFormatPrice(finalPrice, itemData.CURRENCY);
2841
2842						node = BX(this.ids.sumPriceOld + itemData.ID);
2843						if (BX.type.isDomNode(node))
2844						{
2845							price = parseFloat(itemData.FULL_PRICE) * quantityMultiplier;
2846							node.innerHTML = '₽ '+this.getFormatPrice(price, itemData.CURRENCY);
2847						}
2848
2849						node = BX(this.ids.sumPriceDiff + itemData.ID);
2850						if (BX.type.isDomNode(node))
2851						{
2852							price = parseFloat(itemData.DISCOUNT_PRICE) * quantityMultiplier;
2853							node.innerHTML = '₽ '+this.getFormatPrice(price, itemData.CURRENCY);
2854						}
2855					}, this)
2856				}).animate();
2857			}
2858		},
2859
2860		getItemDataByTarget: function(target)
2861		{
2862			var data = false;
2863			var id;
2864
2865			var itemNode = BX.findParent(target, {attrs: {'data-entity': 'basket-item'}});
2866			if (itemNode)
2867			{
2868				id = itemNode.getAttribute('data-id');
2869				data = this.items[id];
2870			}
2871
2872			return data;
2873		},
2874
2875		/*getItemDataByTargetKit: function(target)
2876		{
2877			var itemNode = BX.findParent(target, {attrs: {'data-entity': 'basket-item'}});
2878			if (itemNode)
2879			{
2880				return itemNode.getAttribute('data-kit');
2881			}
2882		},*/
2883
2884		bindSkuEvents: function(node, data)
2885		{
2886			if (!node || !data)
2887				return;
2888
2889			var blocks = this.getEntities(node, 'basket-item-sku-block');
2890			var blockEntities, i, l, ii, ll;
2891
2892			for (i = 0, l = blocks.length; i < l; i++)
2893			{
2894				blockEntities = this.getEntities(blocks[i], 'basket-item-sku-field');
2895
2896				for (ii = 0, ll = blockEntities.length; ii < ll; ii++)
2897				{
2898					BX.bind(blockEntities[ii], 'click', BX.proxy(this.changeSku, this));
2899				}
2900			}
2901		},
2902
2903		changeSku: function()
2904		{
2905			var i, l;
2906
2907			var target = BX.proxy_context;
2908
2909			if (BX.hasClass(target, 'selected'))
2910				return;
2911
2912			var itemData = this.getItemDataByTarget(target);
2913			if (itemData)
2914			{
2915				var basketItemNode = BX(this.ids.item + itemData.ID);
2916				if (basketItemNode)
2917				{
2918					var currentSkuListNodes = this.getEntities(target.parentNode, 'basket-item-sku-field');
2919					for (i = 0, l = currentSkuListNodes.length; i < l; i++)
2920					{
2921						if (currentSkuListNodes[i].isEqualNode(target))
2922						{
2923							BX.addClass(currentSkuListNodes[i], 'selected');
2924						}
2925						else
2926						{
2927							BX.removeClass(currentSkuListNodes[i], 'selected');
2928						}
2929					}
2930
2931					this.actionPool.changeSku(
2932						itemData.ID,
2933						this.getSkuPropertyValues(basketItemNode),
2934						this.getInitialSkuPropertyValues(basketItemNode)
2935					);
2936				}
2937			}
2938		},
2939
2940		getSkuPropertyValues: function(basketItemNode)
2941		{
2942			var propertyValues = {};
2943
2944			var propNodes = this.getEntities(basketItemNode, 'basket-item-sku-field', '.selected');
2945			for (var i = 0, l = propNodes.length; i < l; i++)
2946			{
2947				propertyValues[propNodes[i].getAttribute('data-property')] = BX.util.htmlspecialcharsback(propNodes[i].getAttribute('data-value-id'));
2948			}
2949
2950			return propertyValues;
2951		},
2952
2953		getInitialSkuPropertyValues: function(basketItemNode)
2954		{
2955			var propertyValues = {};
2956
2957			var propNodes = this.getEntities(basketItemNode, 'basket-item-sku-field', '[data-initial="true"]');
2958			for (var i = 0, l = propNodes.length; i < l; i++)
2959			{
2960				propertyValues[propNodes[i].getAttribute('data-property')] = BX.util.htmlspecialcharsback(propNodes[i].getAttribute('data-value-id'));
2961			}
2962
2963			return propertyValues;
2964		},
2965
2966		bindImageEvents: function(node, data)
2967		{
2968			if (!node || !data)
2969				return;
2970
2971			var images = node.querySelectorAll('.basket-item-custom-block-photo-item');
2972			for (var i = 0, l = images.length; i < l; i++)
2973			{
2974				BX.bind(images[i], 'click', BX.proxy(this.showPropertyImagePopup, this));
2975			}
2976		},
2977
2978		showPropertyImagePopup: function()
2979		{
2980			var target, propertyCode, imageIndex, item, imageSrc, i;
2981
2982			target = BX.proxy_context;
2983			item = this.getItemDataByTarget(target);
2984
2985			propertyCode = target.getAttribute('data-column-property-code');
2986			imageIndex = target.getAttribute('data-image-index');
2987
2988			if (item && item.COLUMN_LIST)
2989			{
2990				for (i in item.COLUMN_LIST)
2991				{
2992					if (
2993						item.COLUMN_LIST.hasOwnProperty(i)
2994						&& item.COLUMN_LIST[i].CODE === propertyCode
2995						&& item.COLUMN_LIST[i].VALUE[imageIndex]
2996					)
2997					{
2998						imageSrc = item.COLUMN_LIST[i].VALUE[imageIndex].IMAGE_SRC_ORIGINAL;
2999						break;
3000					}
3001				}
3002			}
3003
3004			if (!imageSrc)
3005			{
3006				return;
3007			}
3008
3009			if (this.imagePopup)
3010			{
3011				this.imagePopup.destroy();
3012			}
3013
3014			var imageId = 'bx-soa-image-popup-content';
3015			var that = this;
3016
3017			this.imagePopup = new BX.PopupWindow('bx-soa-image-popup', null, {
3018				lightShadow: true,
3019				offsetTop: 0,
3020				offsetLeft: 0,
3021				closeIcon: {top: '3px', right: '10px'},
3022				autoHide: true,
3023				bindOptions: {position: 'bottom'},
3024				closeByEsc: true,
3025				zIndex: 100,
3026				events: {
3027					onPopupShow: function() {
3028						BX.create('IMG', {
3029							props: {src: imageSrc},
3030							events: {
3031								load: function() {
3032									var content = BX(imageId);
3033									if (content)
3034									{
3035										var windowSize = BX.GetWindowInnerSize(),
3036											ratio = that.isMobile ? 0.5 : 0.9,
3037											contentHeight, contentWidth;
3038
3039										BX.cleanNode(content);
3040										content.appendChild(this);
3041
3042										contentHeight = content.offsetHeight;
3043										contentWidth = content.offsetWidth;
3044
3045										if (contentHeight >
3045 windowSize.innerHeight * ratio)
3046										{
3047											content.style.height = windowSize.innerHeight * ratio + 'px';
3048											content.style.width = contentWidth * (windowSize.innerHeight * ratio / contentHeight) + 'px';
3049											contentHeight = content.offsetHeight;
3050											contentWidth = content.offsetWidth;
3051										}
3052
3053										if (contentWidth > windowSize.innerWidth * ratio)
3054										{
3055											content.style.width = windowSize.innerWidth * ratio + 'px';
3056											content.style.height = contentHeight * (windowSize.innerWidth * ratio / contentWidth) + 'px';
3057										}
3058
3059										content.style.height = content.offsetHeight + 'px';
3060										content.style.width = content.offsetWidth + 'px';
3061
3062										that.imagePopup.adjustPosition();
3063									}
3064								}
3065							}
3066						});
3067					},
3068					onPopupClose: function() {
3069						this.destroy();
3070					}
3071				},
3072				content: BX.create('DIV', {props: {id: imageId}})
3073			});
3074			this.imagePopup.show();
3075		},
3076
3077		bindActionEvents: function(node, data)
3078		{
3079			if (!node || !data)
3080				return;
3081
3082			var entity;
3083
3084			if (BX.util.in_array('DELETE', this.params.COLUMNS_LIST))
3085			{
3086				entity = this.getEntities(node, 'basket-item-delete');
3087				for (var i = 0, l = entity.length; i < l; i++)
3088				{
3089					BX.bind(entity[i], 'click', BX.proxy(this.deleteAction, this));
3090				}
3091			}
3092
3093			if (BX.util.in_array('DELAY', this.params.COLUMNS_LIST))
3094			{
3095				entity = this.getEntity(node, 'basket-item-add-delayed');
3096				BX.bind(entity, 'click', BX.proxy(this.addDelayedAction, this));
3097
3098				entity = this.getEntity(node, 'basket-item-add-delay');
3099				BX.bind(entity, 'click', BX.proxy(this.addDelayed, this));
3100			}
3101
3102			entity = this.getEntity(node, 'basket-item-remove-delayed');
3103			BX.bind(entity, 'click', BX.proxy(this.removeDelayedAction, this));
3104
3105			entity = this.getEntity(node, 'basket-item-merge-sku-link');
3106			BX.bind(entity, 'click', BX.proxy(this.mergeAction, this));
3107
3108			entity = this.getEntity(node, 'basket-item-show-similar-link');
3109			BX.bind(entity, 'click', BX.delegate(function() {this.toggleFilter('similar');}, this));
3110
3111			entity = this.getEntity(node, 'to-cart');
3112			BX.bind(entity, 'click', BX.proxy(this.toCart, this));
3113		},
3114
3115		basketResult: function(arResult)
3116		{
3117			if (arResult.STATUS === 'OK')
3118			{
3119				this.setAnalyticsDataLayer('addToCart');
3120				$('.detail-add.to-cart .to-cart').addClass('hide');
3121				$('.detail-add.to-cart .open-cart').removeClass('hide');
3122				BX.ajax({
3123					method: 'POST',
3124					url: '/local/ajax/cartCount.php',
3125					async: true,
3126					onsuccess: function (result) {
3127						window.parent.BX('bx_basket').innerHTML = result;
3128						//BX.SidePanel.Instance.reload();
3129					}
3130				});
3131			}
3132		},
3133
3134		add2basket: function(itemData)
3135		{
3136			BX.ajax({
3137				method: 'POST',
3138				url: '/local/ajax/toCart.php',
3139				data: {
3140					PRODUCT_ID: itemData,
3141				},
3142				onsuccess: BX.proxy(this.basketResult, this)
3143			});
3144		},
3145
3146		toCart: function(event)
3147		{
3148			var itemDataKit_0 = false, itemDataKit_1 = false, btnCart = [];
3149			var itemData = this.getItemDataByTarget(BX.proxy_context);
3150			var kit_end = BX.proxy_context.closest('.product_kit_end');
3151			if (kit_end) {
3152				var kit_0 = BX.findPreviousSibling(kit_end, {'class': 'product_kit_0'});
3153				var kit_1 = BX.findPreviousSibling(kit_end, {'class': 'product_kit_1'});
3154				itemDataKit_0 = kit_1 ? kit_1.getAttribute('data-id') : false;
3155				itemDataKit_1 = kit_end ? kit_end.getAttribute('data-id') : false;
3156			}
3157			if (itemData.ID) {
3158				if (kit_end) btnCart.push(kit_end.getAttribute('data-product'));
3159				this.add2basket(itemData.ID);
3160			}
3161			if (itemDataKit_0) {
3162				if (kit_0) btnCart.push(kit_0.getAttribute('data-product'));
3163				this.add2basket(itemDataKit_0);
3164			}
3165			if (itemDataKit_1) {
3166				if (kit_1) btnCart.push(kit_1.getAttribute('data-product'));
3167				this.add2basket(itemDataKit_1);
3168			}
3169
3170			var test = window.parent.$('.detail-add.to-cart .to-cart');
3171			if (test.hasClass('hide')) {
3172				for (var i = 0; i < btnCart.length; i++) {
3173					if (test.hasClass('kit_'+btnCart[i])) {
3174						window.parent.$('.detail-add.to-cart .to-cart.kit_'+btnCart[i]).addClass('hide');
3175						window.parent.$('.detail-add.to-cart .open-cart.kit_'+btnCart[i]).removeClass('hide');
3176						break;
3177					}
3178				}
3179			}
3180
3181			/*var itemData = this.getItemDataByTarget(BX.proxy_context);
3182			if (itemData.PRODUCT_ID) {
3183				//BX.addClass(BX.getEventTarget(event),'hide');
3184				//BX.removeClass(BX('open-cart-'+itemData.ID),'hide');
3185				BX.ajax({
3186					method: 'POST',
3187					url: '/local/ajax/toCart.php',
3188					data: {
3189						PRODUCT_ID: itemData.PRODUCT_ID,
3190						KIT_ID: itemData.KIT_ID,
3191					},
3192					onsuccess: function (data) {
3193						BX.ajax({
3194							method: 'POST',
3195							url: '/local/ajax/cartCount.php',
3196							onsuccess: function (result) {
3197								window.parent.BX('bx_basket').innerHTML = result;
3198							}
3199						});
3200						//window.parent.BX('bx_basket').innerHTML = data;
3201						BX.SidePanel.Instance.reload()
3202					}
3203				});
3204			}*/
3205		},
3206
3207		deleteAction: function(event)
3208		{
3209			var itemDataKit_1 = false, itemDataKit_2 = false, btnCart = [];
3210			var itemData = this.getItemDataByTarget(BX.proxy_context);
3211			var kit_0 = BX.proxy_context.closest('.product_kit_0');
3212			if (kit_0) {
3213				var kit_1 = BX.findNextSibling(kit_0, {'class': 'product_kit_1'});
3214				var kit_end = BX.findNextSibling(kit_0, {'class': 'product_kit_end'});
3215				itemDataKit_1 = kit_1 ? kit_1.getAttribute('data-id') : false;
3216				itemDataKit_2 = kit_end ? kit_end.getAttribute('data-id') : false;
3217			}
3218			if (itemData.ID) {
3219				if (kit_0) btnCart.push(kit_0.getAttribute('data-product'));
3220				this.actionPool.deleteItem(itemData.ID);
3221			}
3222			if (itemDataKit_1) {
3223				if (kit_1) btnCart.push(kit_1.getAttribute('data-product'));
3224				this.actionPool.deleteItem(itemDataKit_1);
3225			}
3226			if (itemDataKit_2) {
3227				if (kit_end) btnCart.push(kit_end.getAttribute('data-product'));
3228				this.actionPool.deleteItem(itemDataKit_2);
3229			}
3230
3231			var test = window.parent.$('.detail-add.to-cart .to-cart');
3232			if (test.hasClass('hide')) {
3233				for (var i = 0; i < btnCart.length; i++) {
3234					if (test.hasClass('kit_'+btnCart[i])) {
3235						window.parent.$('.detail-add.to-cart .to-cart.kit_'+btnCart[i]).removeClass('hide');
3236						window.parent.$('.detail-add.to-cart .open-cart.kit_'+btnCart[i]).addClass('hide');
3237						break;
3238					}
3239				}
3240			}
3241
3242			/*if (itemData.ID)
3243			{
3244				//window.parent.$('.detail-add.to-cart .to-cart[data-product="'+itemData.PRODUCT_ID+'"]').removeClass('hide');
3245				//window.parent.$('.detail-add.to-cart .open-cart[data-product="'+itemData.PRODUCT_ID+'"]').addClass('hide');
3246
3247				var itemDataKit = this.getItemDataByTargetKit(BX.proxy_context);
3248				if(itemDataKit) {
3249					window.parent.$('.detail-add.to-cart .to-cart[data-product="'+itemDataKit+'"]').removeClass('hide');
3250					window.parent.$('.detail-add.to-cart .open-cart[data-product="'+itemDataKit+'"]').addClass('hide');
3251					var itemDataSet = $('[data-product="'+itemDataKit+'"]').attr('data-id');
3252					if(itemDataSet) {
3253						this.actionPool.deleteItem(itemDataSet);
3254						this.redrawBasketItemNode(itemDataSet);
3255						this.items[itemDataSet].SHOW_LOADING = true;
3256
3257						if (this.params.SHOW_RESTORE === 'Y' && this.isItemAvailable(itemDataSet))
3258						{
3259							this.items[itemDataSet].SHOW_RESTORE = true;
3260						}
3261					}
3262				}
3263
3264				//this.items[itemData.ID].SHOW_LOADING = true;
3265
3266				if (this.params.SHOW_RESTORE === 'Y' && this.isItemAvailable(itemData.ID))
3267				{
3268					this.items[itemData.ID].SHOW_RESTORE = true;
3269				}
3270
3271				//this.redrawBasketItemNode(itemData.ID);
3272			}*/
3273		},
3274
3275		addDelayed: function()
3276		{
3277			var target = BX.getEventTarget(event);
3278			var itemData = this.getItemDataByTarget(BX.proxy_context);
3279			var element = window.parent.document.querySelector('[data-delay-id="'+itemData.PRODUCT_ID+'"]');
3280			if(BX.hasClass(target,'added')) {
3281				if (element) BX.removeClass(element,'added');
3282				BX.removeClass(target,'added');
3283				this.basketDelay = 'del'
3284			}else{
3285				if (element) BX.addClass(element,'added');
3286				BX.addClass(target,'added');
3287				this.basketDelay = 'add'
3288			}
3289			if (itemData) {
3290				BX.ajax({
3291					method: 'POST',
3292					url: '/local/ajax/toDelay.php',
3293					data: {
3294						PRODUCT_ID: itemData.PRODUCT_ID,
3295						MODE: this.basketDelay
3296					},
3297					onsuccess: function () {
3298						BX.ajax({
3299							method: 'POST',
3300							url: '/local/ajax/delayCount.php',
3301							onsuccess: function (result) {
3302								window.parent.BX('bx_delay').innerHTML = result;
3303								window.parent.BX('bx_delay_mobile').innerHTML = result;
3304							}
3305						});
3306					}
3307				});
3308			}
3309		},
3310
3311		addDelayedAction: function()
3312		{
3313			var itemData = this.getItemDataByTarget(BX.proxy_context);
3314			if (itemData)
3315			{
3316				this.actionPool.addDelayed(itemData.ID);
3317
3318				this.items[itemData.ID].SHOW_LOADING = true;
3319				this.redrawBasketItemNode(itemData.ID);
3320			}
3321		},
3322
3323		removeDelayedAction: function()
3324		{
3325			var itemData = this.getItemDataByTarget(BX.proxy_context);
3326			if (itemData)
3327			{
3328				this.actionPool.removeDelayed(itemData.ID);
3329
3330				this.items[itemData.ID].SHOW_LOADING = true;
3331				this.redrawBasketItemNode(itemData.ID);
3332			}
3333		},
3334
3335		mergeAction: function()
3336		{
3337			var itemData = this.getItemDataByTarget(BX.proxy_context);
3338			if (itemData)
3339			{
3340				this.actionPool.mergeSku(itemData.ID);
3341			}
3342		},
3343
3344		bindRestoreAction: function(node, itemData)
3345		{
3346			if (!node || !itemData || this.params.SHOW_RESTORE !== 'Y')
3347				return;
3348
3349			BX.bind(
3350				this.getEntity(node, 'basket-item-restore-button'),
3351				'click',
3352				BX.delegate(function() {
3353					this.actionPool.restoreItem(itemData.ID, {
3354						PRODUCT_ID: itemData.PRODUCT_ID,
3355						QUANTITY: itemData.QUANTITY,
3356						PROPS: itemData.PROPS_ALL,
3357						SORT: itemData.SORT,
3358						MODULE: itemData.MODULE,
3359						PRODUCT_PROVIDER_CLASS: itemData.PRODUCT_PROVIDER_CLASS
3360					});
3361
3362					this.items[itemData.ID].SHOW_RESTORE = false;
3363					this.items[itemData.ID].SHOW_LOADING = true;
3364					this.redrawBasketItemNode(itemData.ID);
3365				}, this)
3366			);
3367			BX.bind(
3368				this.getEntity(node, 'basket-item-close-restore-button'),
3369				'click',
3370				BX.delegate(function() {
3371					this.deleteBasketItem(itemData.ID, false, true);
3372				}, this)
3373			);
3374		},
3375
3376		bindItemWarningEvents: function(node, data)
3377		{
3378			if (!node || !data)
3379				return;
3380
3381			BX.bind(
3382				this.getEntity(BX(this.ids.item + data.ID), 'basket-item-warning-close'),
3383				'click',
3384				BX.proxy(this.closeItemWarnings, this)
3385			);
3386		},
3387
3388		closeItemWarnings: function()
3389		{
3390			var target = BX.proxy_context;
3391
3392			if (BX.type.isDomNode(target))
3393			{
3394				var itemData = this.getItemDataByTarget(target);
3395
3396				this.items[itemData.ID].WARNINGS = [];
3397				this.warningItems.splice(BX.util.array_search(itemData.ID, this.warningItems), 1);
3398
3399				this.redrawBasketItemNode(itemData.ID);
3400				this.editWarnings();
3401			}
3402		},
3403
3404		renderBasketItem: function(template, data)
3405		{
3406			var clonedData = BX.clone(data);
3407
3408			if (BX.type.isPlainObject(clonedData))
3409			{
3410				clonedData.USE_FILTER = this.useItemsFilter
3411					&& !this.filter.currentFilter.similarHash.length;
3412			}
3413
3414			return Mustache.render(template, clonedData);
3415		},
3416
3417		render: function(template, data)
3418		{
3419			return Mustache.render(template, data);
3420		},
3421
3422		checkAnalytics: function(data)
3423		{
3424			if (!data || !data.basket)
3425				return;
3426
3427			var itemId, itemsDiff = {};
3428
3429			for (var i in data.basket)
3430			{
3431				if (data.basket.hasOwnProperty(i))
3432				{
3433					if (i.indexOf('QUANTITY_') >= 0)
3434					{
3435						itemId = i.substr(9);
3436
3437						if (this.items[itemId])
3438						{
3439							itemsDiff[itemId] = parseFloat(data.basket[i]) - parseFloat(BX(this.ids.quantity + itemId).getAttribute('data-value'));
3440						}
3441					}
3442					else if (i.indexOf('DELETE_') >= 0)
3443					{
3444						itemId = i.substr(7);
3445
3446						if (this.items[itemId])
3447						{
3448							itemsDiff[itemId] = -parseFloat(this.items[itemId].QUANTITY);
3449						}
3450					}
3451					else if (i.indexOf('RESTORE_') >= 0)
3452					{
3453						itemId = i.substr(8);
3454
3455						if (this.items[itemId])
3456						{
3457							itemsDiff[itemId] = parseFloat(this.items[itemId].QUANTITY);
3458						}
3459					}
3460				}
3461			}
3462
3463			this.setAnalyticsDataLayer(itemsDiff);
3464		},
3465
3466		setAnalyticsDataLayer: function(itemsDiff)
3467		{
3468			if (!itemsDiff || Object.keys(itemsDiff).length === 0)
3469				return;
3470
3471			window[this.params.DATA_LAYER_NAME] = window[this.params.DATA_LAYER_NAME] || [];
3472
3473			var plus = [], minus = [];
3474
3475			for (var itemId in itemsDiff)
3476			{
3477				if (itemsDiff.hasOwnProperty(itemId))
3478				{
3479					if (itemsDiff[itemId] > 0)
3480					{
3481						plus.push(this.getItemAnalyticsInfo(itemId, itemsDiff[itemId]));
3482					}
3483					else if (itemsDiff[itemId] < 0)
3484					{
3485						minus.push(this.getItemAnalyticsInfo(itemId, itemsDiff[itemId]));
3486					}
3487				}
3488			}
3489
3490			if (plus.length)
3491			{
3492				window[this.params.DATA_LAYER_NAME].push({
3493					event: 'addToCart',
3494					ecommerce: {
3495						currencyCode: this.items[itemId].CURRENCY || '',
3496						add: {
3497							products: plus
3498						}
3499					}
3500				});
3501			}
3502
3503			if (minus.length)
3504			{
3505				window[this.params.DATA_LAYER_NAME].push({
3506					event: 'removeFromCart',
3507					ecommerce: {
3508						currencyCode: this.items[itemId].CURRENCY || '',
3509						remove: {
3510							products: minus
3511						}
3512					}
3513				});
3514			}
3515		},
3516
3517		getItemAnalyticsInfo: function(itemId, diff)
3518		{
3519			if (!this.items[itemId])
3520				return {};
3521
3522			var brand = (this.items[itemId].BRAND || '').split(',  ').join('/');
3523			var variants = [];
3524
3525			var selectedSku = this.getEntities(BX(this.ids.item + itemId), 'basket-item-sku-field', '.selected');
3526			for (var i = 0, l = selectedSku.length; i < l; i++)
3527			{
3528				variants.push(selectedSku[i].getAttribute('data-sku-name'));
3529			}
3530
3531			return {
3532				'name': this.items[itemId].NAME || '',
3533				'id': this.items[itemId].PRODUCT_ID || '',
3534				'price': this.items[itemId].PRICE || 0,
3535				'brand': brand,
3536				'variant': variants.join('/'),
3537				'quantity': Math.abs(diff)
3538			};
3539		}
3540	};
3541})();
3542/* End */
3543;
3544; /* Start:"a:4:{s:4:"full";s:95:"/bitrix/components/bitrix/sale.products.gift.basket/templates/.default/script.js?17726179854796";s:6:"source";s:80:"/bitrix/components/bitrix/sale.products.gift.basket/templates/.default/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
3545(function() {
3546	'use strict';
3547
3548	if (!!window.JCSaleProductsGiftBasketComponent)
3549		return;
3550
3551	window.JCSaleProductsGiftBasketComponent = function(params) {
3552		this.formPosting = false;
3553		this.siteId = params.siteId || '';
3554		this.template = params.template || '';
3555		this.componentPath = params.componentPath || '';
3556		this.parameters = params.parameters || '';
3557
3558		this.container = document.querySelector('[data-entity="' + params.container + '"]');
3559		this.currentProductId = params.currentProductId;
3560
3561		if (params.initiallyShowHeader)
3562		{
3563			BX.ready(BX.proxy(this.showHeader, this));
3564		}
3565
3566		if (params.deferredLoad)
3567		{
3568			BX.ready(BX.proxy(this.deferredLoad, this));
3569		}
3570
3571		BX.addCustomEvent('OnBasketChange', BX.proxy(this.reloadGifts, this));
3572		BX.addCustomEvent('OnCouponApply', BX.proxy(this.reloadGifts, this));
3573	};
3574
3575	window.JCSaleProductsGiftBasketComponent.prototype =
3576	{
3577		reloadGifts: function()
3578		{
3579			this.sendRequest({action: 'deferredLoad', recalculateDiscounts: 'Y'});
3580		},
3581
3582		deferredLoad: function()
3583		{
3584			this.sendRequest({action: 'deferredLoad'});
3585		},
3586
3587		sendRequest: function(data)
3588		{
3589			var defaultData = {
3590				siteId: this.siteId,
3591				template: this.template,
3592				parameters: this.parameters
3593			};
3594
3595			BX.ajax({
3596				url: this.componentPath + '/ajax.php' + (document.location.href.indexOf('clear_cache=Y') !== -1 ? '?clear_cache=Y' : ''),
3597				method: 'POST',
3598				dataType: 'json',
3599				timeout: 60,
3600				data: BX.merge(defaultData, data),
3601				onsuccess: BX.delegate(function(result){
3602					if (!result || !result.JS)
3603					{
3604						this.hideHeader();
3605						BX.cleanNode(this.container);
3606						return;
3607					}
3608
3609					BX.ajax.processScripts(
3610						BX.processHTML(result.JS).SCRIPT,
3611						false,
3612						BX.delegate(function(){this.showAction(result, data);}, this)
3613					);
3614				}, this)
3615			});
3616		},
3617
3618		showAction: function(result, data)
3619		{
3620			if (!data)
3621				return;
3622
3623			switch (data.action)
3624			{
3625				case 'deferredLoad':
3626					this.processDeferredLoadAction(result);
3627					break;
3628			}
3629		},
3630
3631		processDeferredLoadAction: function(result)
3632		{
3633			if (!result)
3634				return;
3635
3636			this.processItems(result.items);
3637		},
3638
3639		processItems: function(itemsHtml)
3640		{
3641			if (!itemsHtml)
3642				return;
3643
3644			var processed = BX.processHTML(itemsHtml, false),
3645				temporaryNode = BX.create('DIV');
3646
3647			var items, k, origRows;
3648
3649			temporaryNode.innerHTML = processed.HTML;
3650
3651			origRows = this.container.querySelectorAll('[data-entity="items-row"]');
3652			if (origRows.length)
3653			{
3654				BX.cleanNode(this.container);
3655				this.showHeader(false);
3656			}
3657			else
3658			{
3659				this.showHeader(true);
3660			}
3661
3662			items = temporaryNode.querySelectorAll('[data-entity="items-row"]');
3663			for (k in items)
3664			{
3665				if (items.hasOwnProperty(k))
3666				{
3667					items[k].style.opacity = 0;
3668					this.container.appendChild(items[k]);
3669				}
3670			}
3671
3672			new BX.easing({
3673				duration: 2000,
3674				start: {opacity: 0},
3675				finish: {opacity: 100},
3676				transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
3677				step: function(state){
3678					for (var k in items)
3679					{
3680						if (items.hasOwnProperty(k))
3681						{
3682							items[k].style.opacity = state.opacity / 100;
3683						}
3684					}
3685				},
3686				complete: function(){
3687					for (var k in items)
3688					{
3689						if (items.hasOwnProperty(k))
3690						{
3691							items[k].removeAttribute('style');
3692						}
3693					}
3694				}
3695			}).animate();
3696
3697			BX.ajax.processScripts(processed.SCRIPT);
3698		},
3699
3700		showHeader: function(animate)
3701		{
3702			var parentNode = BX.findParent(this.container, {attr: {'data-entity': 'parent-container'}}),
3703				header;
3704
3705			if (parentNode && BX.type.isDomNode(parentNode))
3706			{
3707				header = parentNode.querySelector('[data-entity="header"]');
3708
3709				if (header && header.getAttribute('data-showed') === 'false')
3710				{
3711					header.style.display = '';
3712
3713					if (animate)
3714					{
3715						this.animation = new BX.easing({
3716							duration: 2000,
3717							start: {opacity: 0},
3718							finish: {opacity: 100},
3719							transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
3720							step: function(state){
3721								header.style.opacity = state.opacity / 100;
3722							},
3723							complete: function(){
3724								header.removeAttribute('style');
3725								header.setAttribute('data-showed', 'true');
3726							}
3727						});
3728						this.animation.animate()
3729					}
3730					else
3731					{
3732						header.style.opacity = 100;
3733					}
3734				}
3735			}
3736		},
3737
3738		hideHeader: function()
3739		{
3740			var parentNode = BX.findParent(this.container, {attr: {'data-entity': 'parent-container'}}),
3741				header;
3742
3743			if (parentNode && BX.type.isDomNode(parentNode))
3744			{
3745				header = parentNode.querySelector('[data-entity="header"]');
3746
3747				if (header)
3748				{
3749					if (this.animation)
3750					{
3751						this.animation.stop();
3752					}
3753
3754					header.style.display = 'none';
3755					header.style.opacity = 0;
3756					header.setAttribute('data-showed', 'false');
3757				}
3758			}
3759		}
3760	}
3761})();
3762/* End */
3763;
3764; /* Start:"a:4:{s:4:"full";s:91:"/local/templates/bitrix66/components/bitrix/catalog.item/.default/script.js?178953951698344";s:6:"source";s:75:"/local/templates/bitrix66/components/bitrix/catalog.item/.default/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
3765(function (window){
3766    'use strict';
3767
3768    if (window.JCCatalogItem)
3769        return;
3770
3771    var BasketButton = function(params)
3772    {
3773        BasketButton.superclass.constructor.apply(this, arguments);
3774        this.buttonNode = BX.create('button', {
3775            props: {className: 'btn btn-primary btn-buy btn-sm', id: this.id},
3776            style: typeof params.style === 'object' ? params.style : {},
3777            text: params.text,
3778            events: this.contextEvents
3779        });
3780
3781        if (BX.browser.IsIE())
3782        {
3783            this.buttonNode.setAttribute("hideFocus", "hidefocus");
3784        }
3785    };
3786    BX.extend(BasketButton, BX.PopupWindowButton);
3787
3788    window.JCCatalogItem = function (arParams)
3789    {
3790        this.productType = 0;
3791        this.showQuantity = true;
3792        this.showAbsent = true;
3793        this.secondPict = false;
3794        this.showOldPrice = false;
3795        this.showMaxQuantity = 'N';
3796        this.relativeQuantityFactor = 5;
3797        this.showPercent = false;
3798        this.showSkuProps = false;
3799        this.basketAction = 'ADD';
3800        this.showClosePopup = false;
3801        this.useCompare = false;
3802        this.showSubscription = false;
3803        this.visual = {
3804            ID: '',
3805            PICT_ID: '',
3806            SECOND_PICT_ID: '',
3807            PICT_SLIDER_ID: '',
3808            QUANTITY_ID: '',
3809            QUANTITY_UP_ID: '',
3810            QUANTITY_DOWN_ID: '',
3811            PRICE_ID: '',
3812            PRICE_OLD_ID: '',
3813            DSC_PERC: '',
3814            SECOND_DSC_PERC: '',
3815            DISPLAY_PROP_DIV: '',
3816            BASKET_PROP_DIV: '',
3817            SUBSCRIBE_ID: ''
3818        };
3819
3820        this.product = {
3821            checkQuantity: false,
3822            maxQuantity: 0,
3823            stepQuantity: 1,
3824            isDblQuantity: false,
3825            canBuy: true,
3826            name: '',
3827            pict: {},
3828            id: 0,
3829            addUrl: '',
3830            buyUrl: '',
3831            swiper: 'default',
3832            video: false
3833        };
3834
3835        this.basketMode = '';
3836        this.basketData = {
3837            useProps: false,
3838            emptyProps: false,
3839            quantity: 'quantity',
3840            props: 'prop',
3841            basketUrl: '',
3842            sku_props: '',
3843            sku_props_var: 'basket_props',
3844            add_url: '',
3845            buy_url: ''
3846        };
3847
3848        this.compareData = {
3849            compareUrl: '',
3850            compareDeleteUrl: '',
3851            comparePath: ''
3852        };
3853
3854        this.defaultPict = {
3855            pict: null,
3856            secondPict: null
3857        };
3858
3859        this.defaultSliderOptions = {
3860            interval: 3000,
3861            wrap: true
3862        };
3863        this.slider = {
3864            options: {},
3865            items: [],
3866            active: null,
3867            sliding: null,
3868            paused: null,
3869            interval: null,
3870            progress: null
3871        };
3872        this.touch = null;
3873
3874        this.quantityDelay = null;
3875        this.quantityTimer = null;
3876
3877        this.checkQuantity = false;
3878        this.maxQuantity = 0;
3879        this.minQuantity = 0;
3880        this.stepQuantity = 1;
3881        this.isDblQuantity = false;
3882        this.canBuy = true;
3883        this.precision = 6;
3884        this.precisionFactor = Math.pow(10, this.precision);
3885        this.bigData = false;
3886        this.fullDisplayMode = false;
3887        this.viewMode = '';
3888        this.templateTheme = '';
3889
3890        this.currentPriceMode = '';
3891        this.currentPrices = [];
3892        this.currentPriceSelected = 0;
3893        this.currentQuantityRanges = [];
3894        this.currentQuantityRangeSelected = 0;
3895
3896        this.offers = [];
3897        this.offerNum = 0;
3898        this.treeProps = [];
3899        this.selectedValues = {};
3900
3901        this.obProduct = null;
3902        this.blockNodes = {};
3903        this.obQuantity = null;
3904        this.obQuantityUp = null;
3905        this.obQuantityDown = null;
3906        this.obQuantityLimit = {};
3907        this.obPict = null;
3908        this.obSecondPict = null;
3909        this.obPictSlider = null;
3910        this.obPictSliderIndicator = null;
3911        this.obPrice = null;
3912        this.obTree = null;
3913        this.obBuyBtn = null;
3914        this.obBasketActions = null;
3915        this.obNotAvail = null;
3916        this.obSubscribe = null;
3917        this.obDscPerc = null;
3918        this.obSecondDscPerc = null;
3919        this.obSkuProps = null;
3920        this.obMeasure = null;
3921        this.obCompare = null;
3922
3923        this.obPopupWin = null;
3924        this.basketUrl = '';
3925        this.basketParams = {};
3926        this.isTouchDevice = BX.hasClass(document.documentElement, 'bx-touch');
3927        this.hoverTimer = null;
3928        this.hoverStateChangeForbidden = false;
3929        this.mouseX = null;
3930        this.mouseY = null;
3931
3932        this.useEnhancedEcommerce = false;
3933        this.dataLayerName = 'dataLayer';
3934        this.brandProperty = false;
3935
3936        this.errorCode = 0;
3937
3938        if (typeof arParams === 'object')
3939        {
3940            if (arParams.PRODUCT_TYPE)
3941            {
3942                this.productType = parseInt(arParams.PRODUCT_TYPE, 10);
3943            }
3944
3945            this.showQuantity = arParams.SHOW_QUANTITY;
3946            this.showAbsent = arParams.SHOW_ABSENT;
3947            this.secondPict = arParams.SECOND_PICT;
3948            this.showOldPrice = arParams.SHOW_OLD_PRICE;
3949            this.showMaxQuantity = arParams.SHOW_MAX_QUANTITY;
3950            this.relativeQuantityFactor = parseInt(arParams.RELATIVE_QUANTITY_FACTOR);
3951            this.showPercent = arParams.SHOW_DISCOUNT_PERCENT;
3952            this.showSkuProps = arParams.SHOW_SKU_PROPS;
3953            this.showSubscription = arParams.USE_SUBSCRIBE;
3954
3955            if (arParams.ADD_TO_BASKET_ACTION)
3956            {
3957                this.basketAction = arParams.ADD_TO_BASKET_ACTION;
3958            }
3959
3960            this.showClosePopup = arParams.SHOW_CLOSE_POPUP;
3961            this.useCompare = arParams.DISPLAY_COMPARE;
3962            this.fullDisplayMode = arParams.PRODUCT_DISPLAY_MODE === 'Y';
3963            this.bigData = arParams.BIG_DATA;
3964            this.viewMode = arParams.VIEW_MODE || '';
3965            this.templateTheme = arParams.TEMPLATE_THEME || '';
3966            this.useEnhancedEcommerce = arParams.USE_ENHANCED_ECOMMERCE === 'Y';
3967            this.dataLayerName = arParams.DATA_LAYER_NAME;
3968            this.brandProperty = arParams.BRAND_PROPERTY;
3969
3970            this.visual = arParams.VISUAL;
3971
3972            switch (this.productType)
3973            {
3974                case 0: // no catalog
3975                case 1: // product
3976                case 2: // set
3977                    if (arParams.PRODUCT && typeof arParams.PRODUCT === 'object')
3978                    {
3979                        this.currentPriceMode = arParams.PRODUCT.ITEM_PRICE_MODE;
3980                        this.currentPrices = arParams.PRODUCT.ITEM_PRICES;
3981                        this.currentPriceSelected = arParams.PRODUCT.ITEM_PRICE_SELECTED;
3982                        this.currentQuantityRanges = arParams.PRODUCT.ITEM_QUANTITY_RANGES;
3983                        this.currentQuantityRangeSelected = arParams.PRODUCT.ITEM_QUANTITY_RANGE_SELECTED;
3984
3985                        if (this.showQuantity)
3986                        {
3987                            this.product.checkQuantity = arParams.PRODUCT.CHECK_QUANTITY;
3988                            this.product.isDblQuantity = arParams.PRODUCT.QUANTITY_FLOAT;
3989
3990                            if (this.product.checkQuantity)
3991                            {
3992                                this.product.maxQuantity = (this.product.isDblQuantity ? parseFloat(arParams.PRODUCT.MAX_QUANTITY) : parseInt(arParams.PRODUCT.MAX_QUANTITY, 10));
3993                            }
3994
3995                            this.product.stepQuantity = (this.product.isDblQuantity ? parseFloat(arParams.PRODUCT.STEP_QUANTITY) : parseInt(arParams.PRODUCT.STEP_QUANTITY, 10));
3996
3997                            this.checkQuantity = this.product.checkQuantity;
3998                            this.isDblQuantity = this.product.isDblQuantity;
3999                            this.stepQuantity = this.product.stepQuantity;
4000                            this.maxQuantity = this.product.maxQuantity;
4001                            this.minQuantity = this.currentPriceMode === 'Q'
4002                                ? parseFloat(this.currentPrices[this.currentPriceSelected].MIN_QUANTITY)
4003                                : this.stepQuantity;
4004
4005                            if (this.isDblQuantity)
4006                            {
4007                                this.stepQuantity = Math.round(this.stepQuantity * this.precisionFactor) / this.precisionFactor;
4008                            }
4009                        }
4010
4011                        this.product.canBuy = arParams.PRODUCT.CAN_BUY;
4012
4013                        if (arParams.PRODUCT.MORE_PHOTO_COUNT)
4014                        {
4015                            this.product.morePhotoCount = arParams.PRODUCT.MORE_PHOTO_COUNT;
4016                            this.product.morePhoto = arParams.PRODUCT.MORE_PHOTO;
4017                        }
4018
4019                        if (arParams.PRODUCT.RCM_ID)
4020                        {
4021                            this.product.rcmId = arParams.PRODUCT.RCM_ID;
4022                        }
4023
4024                        this.canBuy = this.product.canBuy;
4025                        this.product.name = arParams.PRODUCT.NAME;
4026                        this.product.pict = arParams.PRODUCT.PICT;
4027                        this.product.id = arParams.PRODUCT.ID;
4028                        this.product.DETAIL_PAGE_URL = arParams.PRODUCT.DETAIL_PAGE_URL;
4029
4030                        if (arParams.PRODUCT.ADD_URL)
4031                        {
4032                            this.product.addUrl = arParams.PRODUCT.ADD_URL;
4033                        }
4034
4035                        if (arParams.PRODUCT.BUY_URL)
4036                        {
4037                            this.product.buyUrl = arParams.PRODUCT.BUY_URL;
4038                        }
4039
4040                        if (arParams.BASKET && typeof arParams.BASKET === 'object')
4041                        {
4042                            this.basketData.useProps = arParams.BASKET.ADD_PROPS;
4043                            this.basketData.emptyProps = arParams.BASKET.EMPTY_PROPS;
4044                        }
4045                    }
4046                    else
4047                    {
4048                        this.errorCode = -1;
4049                    }
4050
4051                    break;
4052                case 3: // sku
4053                    if (arParams.PRODUCT && typeof arParams.PRODUCT === 'object')
4054                    {
4055                        this.product.name = arParams.PRODUCT.NAME;
4056                        this.product.id = arParams.PRODUCT.ID;
4057                        this.product.DETAIL_PAGE_URL = arParams.PRODUCT.DETAIL_PAGE_URL;
4058                        this.product.morePhotoCount = arParams.PRODUCT.MORE_PHOTO_COUNT;
4059                        this.product.morePhoto = arParams.PRODUCT.MORE_PHOTO;
4060                        this.product.swiper = arParams.PRODUCT.SWIPER;
4061                        this.product.video = arParams.PRODUCT.VIDEO;
4062
4063                        if (arParams.PRODUCT.RCM_ID)
4064                        {
4065                            this.product.rcmId = arParams.PRODUCT.RCM_ID;
4066                        }
4067                    }
4068
4069                    if (arParams.OFFERS && BX.type.isArray(arParams.OFFERS))
4070                    {
4071                        this.offers = arParams.OFFERS;
4072                        this.offerNum = 0;
4073
4074                        if (arParams.OFFER_SELECTED)
4075                        {
4076                            this.offerNum = parseInt(arParams.OFFER_SELECTED, 10);
4077                        }
4078
4079                        if (isNaN(this.offerNum))
4080                        {
4081                            this.offerNum = 0;
4082                        }
4083
4084                        if (arParams.TREE_PROPS)
4085                        {
4086                            this.treeProps = arParams.TREE_PROPS;
4087                        }
4088
4089                        if (arParams.DEFAULT_PICTURE)
4090                        {
4091                            this.defaultPict.pict = arParams.DEFAULT_PICTURE.PICTURE;
4092                            this.defaultPict.secondPict = arParams.DEFAULT_PICTURE.PICTURE_SECOND;
4093                        }
4094                    }
4095
4096                    break;
4097                default:
4098                    this.errorCode = -1;
4099            }
4100            if (arParams.BASKET && typeof arParams.BASKET === 'object')
4101            {
4102                if (arParams.BASKET.QUANTITY)
4103                {
4104                    this.basketData.quantity = arParams.BASKET.QUANTITY;
4105                }
4106
4107                if (arParams.BASKET.PROPS)
4108                {
4109                    this.basketData.props = arParams.BASKET.PROPS;
4110                }
4111
4112                if (arParams.BASKET.BASKET_URL)
4113                {
4114                    this.basketData.basketUrl = arParams.BASKET.BASKET_URL;
4115                }
4116
4117                if (3 === this.productType)
4118                {
4119                    if (arParams.BASKET.SKU_PROPS)
4120                    {
4121                        this.basketData.sku_props = arParams.BASKET.SKU_PROPS;
4122                    }
4123                }
4124
4125                if (arParams.BASKET.ADD_URL_TEMPLATE)
4126                {
4127                    this.basketData.add_url = arParams.BASKET.ADD_URL_TEMPLATE;
4128                }
4129
4130                if (arParams.BASKET.BUY_URL_TEMPLATE)
4131                {
4132                    this.basketData.buy_url = arParams.BASKET.BUY_URL_TEMPLATE;
4133                }
4134
4135                if (this.basketData.add_url === '' && this.basketData.buy_url === '')
4136                {
4137                    this.errorCode = -1024;
4138                }
4139            }
4140
4141            if (this.useCompare)
4142            {
4143                if (arParams.COMPARE && typeof arParams.COMPARE === 'object')
4144                {
4145                    if (arParams.COMPARE.COMPARE_PATH)
4146                    {
4147                        this.compareData.comparePath = arParams.COMPARE.COMPARE_PATH;
4148                    }
4149
4150                    if (arParams.COMPARE.COMPARE_URL_TEMPLATE)
4151                    {
4152                        this.compareData.compareUrl = arParams.COMPARE.COMPARE_URL_TEMPLATE;
4153                    }
4154                    else
4155                    {
4156                        this.useCompare = false;
4157                    }
4158
4159                    if (arParams.COMPARE.COMPARE_DELETE_URL_TEMPLATE)
4160                    {
4161                        this.compareData.compareDeleteUrl = arParams.COMPARE.COMPARE_DELETE_URL_TEMPLATE;
4162                    }
4163                    else
4164                    {
4165                        this.useCompare = false;
4166                    }
4167                }
4168                else
4169                {
4170                    this.useCompare = false;
4171                }
4172            }
4173
4174            this.isFacebookConversionCustomizeProductEventEnabled
4175                = arParams.IS_FACEBOOK_CONVERSION_CUSTOMIZE_PRODUCT_EVENT_ENABLED
4176            ;
4177        }
4178
4179        if (this.errorCode === 0)
4180        {
4181            BX.ready(BX.delegate(this.init,this));
4182        }
4183    };
4184
4185    window.JCCatalogItem.prototype = {
4186        init: function()
4187        {
4188            var i = 0, treeItems = null;
4189
4190            var productId = this.product.id;
4191
4192            BX.bind(BX('delay_'+productId), 'click', BX.proxy(this.onDelay, this));
4193
4194            var speed = (document.body.offsetWidth > 767 ? 0 : 300);
4195
4196            if(this.product.video) {
4197                BX.ajax({
4198                    url: '/local/ajax/video.php?VIDEO='+this.product.video,
4199                    method: 'POST',
4200                    async: true,
4201                    cache: true,
4202                    onsuccess: function (result) {
4203                        BX('video_'+productId).innerHTML = result;
4204                        BX.removeClass(BX('video_'+productId), 'loading');
4205                    }
4206                });
4207                swiperСontainer[productId] = new Swiper('#catalog-listing .row .swiper_'+productId, {
4208                    slidesPerView: "auto",
4209                    spaceBetween: 10,
4210                    autoHeight: false,
4211                    freeMode: {
4212                        enabled: false,
4213                        sticky: true,
4214                    },
4215                    loop: true,
4216                    pagination: {
4217                        el: ".swiper-pagination",
4218                        clickable: true,
4219                    },
4220                    speed: speed,
4221                    initialSlide: BX.getCookie('BITRIX_SM_MODEL') == 'Y' ? 2 : 0,
4222                });
4223            }else {
4224                swiperСontainer[productId] = new Swiper('#catalog-listing .row .swiper_' + productId, {
4225                    slidesPerView: "auto",
4226                    spaceBetween: 10,
4227                    autoHeight: false,
4228                    freeMode: {
4229                        enabled: false,
4230                        sticky: true,
4231                    },
4232                    loop: true,
4233                    pagination: {
4234                        el: ".swiper-pagination",
4235                        clickable: true,
4236                    },
4237                    speed: speed,
4238                    initialSlide: BX.getCookie('BITRIX_SM_MODEL') == 'Y' ? 1 : 0,
4239                });
4240            }
4241
4242            BX.bind(BX('catalog-listing').querySelector('.swiper_'+productId), 'mouseleave', function () {
4243                if (BX.getCookie('BITRIX_SM_MODEL') == 'Y') {
4244                    if ($(this).hasClass('video')) {
4245                        swiperСontainer[productId].slideTo(2, speed, true);
4246                    } else {
4247                        swiperСontainer[productId].slideTo(1, speed, true);
4248                    }
4249                } else {
4250                    swiperСontainer[productId].slideTo(0, speed, true);
4251                }
4252            });
4253
4254            $('#catalog-listing .row').on('mouseover', '.swiper_'+productId+' .swiper-pagination-bullet', function (e) {
4255                if (document.body.offsetWidth > 767) {
4256                    swiperСontainer[productId].slideTo($(this).index(), speed, true);
4257                }
4258            });
4259
4260            this.obProduct = BX(this.visual.ID);
4261            if (!this.obProduct)
4262            {
4263                this.errorCode = -1;
4264            }
4265
4266            this.obPict = BX(this.visual.PICT_ID);
4267            if (!this.obPict)
4268            {
4269                this.errorCode = -2;
4270            }
4271
4272            if (this.secondPict && this.visual.SECOND_PICT_ID)
4273            {
4274                this.obSecondPict = BX(this.visual.SECOND_PICT_ID);
4275            }
4276
4277            this.obPictSlider = BX(this.visual.PICT_SLIDER_ID);
4278            this.obPictSliderIndicator = BX(this.visual.PICT_SLIDER_ID + '_indicator');
4279            this.obPictSliderProgressBar = BX(this.visual.PICT_SLIDER_ID + '_progress_bar');
4280            if (!this.obPictSlider)
4281            {
4282                this.errorCode = -4;
4283            }
4284
4285            this.obPrice = BX(this.visual.PRICE_ID);
4286            this.obPriceOld = BX(this.visual.PRICE_OLD_ID);
4287            this.obPriceTotal = BX(this.visual.PRICE_TOTAL_ID);
4288            if (!this.obPrice)
4289            {
4290                this.errorCode = -16;
4291            }
4292
4293            if (this.showQuantity && this.visual.QUANTITY_ID)
4294            {
4295                this.obQuantity = BX(this.visual.QUANTITY_ID);
4296                this.blockNodes.quantity = this.obProduct.querySelector('[data-entity="quantity-block"]');
4297
4298                if (!this.isTouchDevice)
4299                {
4300                    BX.bind(this.obQuantity, 'focus', BX.proxy(this.onFocus, this));
4301                    BX.bind(this.obQuantity, 'blur', BX.proxy(this.onBlur, this));
4302                }
4303
4304                if (this.visual.QUANTITY_UP_ID)
4305                {
4306                    this.obQuantityUp = BX(this.visual.QUANTITY_UP_ID);
4307                }
4308
4309                if (this.visual.QUANTITY_DOWN_ID)
4310                {
4311                    this.obQuantityDown = BX(this.visual.QUANTITY_DOWN_ID);
4312                }
4313            }
4314
4315            if (this.visual.QUANTITY_LIMIT && this.showMaxQuantity !== 'N')
4316            {
4317                this.obQuantityLimit.all = BX(this.visual.QUANTITY_LIMIT);
4318                if (this.obQuantityLimit.all)
4319                {
4320                    this.obQuantityLimit.value = this.obQuantityLimit.all.querySelector('[data-entity="quantity-limit-value"]');
4321                    if (!this.obQuantityLimit.value)
4322                    {
4323                        this.obQuantityLimit.all = null;
4324                    }
4325                }
4326            }
4327
4328            if (this.productType === 3 && this.fullDisplayMode)
4329            {
4330                if (this.visual.TREE_ID)
4331                {
4332                    this.obTree = BX(this.visual.TREE_ID);
4333                    if (!this.obTree)
4334                    {
4335                        this.errorCode = -256;
4336                    }
4337                }
4338
4339                if (this.visual.QUANTITY_MEASURE)
4340                {
4341                    this.obMeasure = BX(this.visual.QUANTITY_MEASURE);
4342                }
4343            }
4344
4345            this.obBasketActions = BX(this.visual.BASKET_ACTIONS_ID);
4346            if (this.obBasketActions)
4347            {
4348                if (this.visual.BUY_ID)
4349                {
4350                    this.obBuyBtn = BX(this.visual.BUY_ID);
4351                }
4352            }
4353
4354            this.obNotAvail = BX(this.visual.NOT_AVAILABLE_MESS);
4355
4356            if (this.showSubscription)
4357            {
4358                this.obSubscribe = BX(this.visual.SUBSCRIBE_ID);
4359            }
4360
4361            if (this.showPercent)
4362            {
4363                if (this.visual.DSC_PERC)
4364                {
4365                    this.obDscPerc = BX(this.visual.DSC_PERC);
4366                }
4367                if (this.secondPict && this.visual.SECOND_DSC_PERC)
4368                {
4369                    this.obSecondDscPerc = BX(this.visual.SECOND_DSC_PERC);
4370                }
4371            }
4372
4373            if (this.showSkuProps)
4374            {
4375                if (this.visual.DISPLAY_PROP_DIV)
4376                {
4377                    this.obSkuProps = BX(this.visual.DISPLAY_PROP_DIV);
4378                }
4379            }
4380
4381            if (this.errorCode === 0)
4382            {
4383                // product slider events
4384                if (this.isTouchDevice)
4385                {
4386                    BX.bind(this.obPictSlider, 'touchstart', BX.proxy(this.touchStartEvent, this));
4387                    BX.bind(this.obPictSlider, 'touchend', BX.proxy(this.touchEndEvent, this));
4388                    BX.bind(this.obPictSlider, 'touchcancel', BX.proxy(this.touchEndEvent, this));
4389                }
4390                else
4391                {
4392                    if (this.viewMode === 'CARD')
4393                    {
4394                        // product hover events
4395                        BX.bind(this.obProduct, 'mouseenter', BX.proxy(this.hoverOn, this));
4396                        BX.bind(this.obProduct, 'mouseleave', BX.proxy(this.hoverOff, this));
4397                    }
4398
4399                    // product slider events
4400                    BX.bind(this.obProduct, 'mouseenter', BX.proxy(this.cycleSlider, this));
4401                    BX.bind(this.obProduct, 'mouseleave', BX.proxy(this.stopSlider, this));
4402                }
4403
4404                if (this.bigData)
4405                {
4406                    var links = BX.findChildren(this.obProduct, {tag:'a'}, true);
4407                    if (links)
4408                    {
4409                        for (i in links)
4410                        {
4411                            if (links.hasOwnProperty(i))
4412                            {
4413                                if (links[i].getAttribute('href') == this.product.DETAIL_PAGE_URL)
4414                                {
4415                                    BX.bind(links[i], 'click', BX.proxy(this.rememberProductRecommendation, this));
4416                                }
4417                            }
4418                        }
4419                    }
4420                }
4421
4422                if (this.showQuantity)
4423                {
4424                    var startEventName = this.isTouchDevice ? 'touchstart' : 'mousedown';
4425                    var endEventName = this.isTouchDevice ? 'touchend' : 'mouseup';
4426
4427                    if (this.obQuantityUp)
4428                    {
4429                        BX.bind(this.obQuantityUp, startEventName, BX.proxy(this.startQuantityInterval, this));
4430                        BX.bind(this.obQuantityUp, endEventName, BX.proxy(this.clearQuantityInterval, this));
4431                        BX.bind(this.obQuantityUp, 'mouseout', BX.proxy(this.clearQuantityInterval, this));
4432                        BX.bind(this.obQuantityUp, 'click', BX.delegate(this.quantityUp, this));
4433                    }
4434
4435                    if (this.obQuantityDown)
4436                    {
4437                        BX.bind(this.obQuantityDown, startEventName, BX.proxy(this.startQuantityInterval, this));
4438                        BX.bind(this.obQuantityDown, endEventName, BX.proxy(this.clearQuantityInterval, this));
4439                        BX.bind(this.obQuantityDown, 'mouseout', BX.proxy(this.clearQuantityInterval, this));
4440                        BX.bind(this.obQuantityDown, 'click', BX.delegate(this.quantityDown, this));
4441                    }
4442
4443                    if (this.obQuantity)
4444                    {
4445                        BX.bind(this.obQuantity, 'change', BX.delegate(this.quantityChange, this));
4446                    }
4447                }
4448
4449                switch (this.productType)
4450                {
4451                    case 0: // no catalog
4452                    case 1: // product
4453                    case 2: // set
4454                        if (parseInt(this.product.morePhotoCount) > 1 && this.obPictSlider)
4455                        {
4456                            this.initializeSlider();
4457                        }
4458
4459                        this.checkQuantityControls();
4460
4461                        break;
4462                    case 3: // sku
4463                        if (this.offers.length > 0)
4464                        {
4465                            treeItems = BX.findChildren(this.obTree, {tagName: 'li'}, true);
4466
4467                            if (treeItems && treeItems.length)
4468                            {
4469                                for (i = 0; i < treeItems.length; i++)
4470                                {
4471                                    BX.bind(treeItems[i], 'click', BX.delegate(this.selectOfferProp, this));
4472                                }
4473                            }
4474
4475                            this.setCurrent();
4476                        }
4477                        else if (parseInt(this.product.morePhotoCount) > 1 && this.obPictSlider)
4478                        {
4479                            this.initializeSlider();
4480                        }
4481
4482                        break;
4483                }
4484
4485                if (this.obBuyBtn)
4486                {
4487                    if (this.basketAction === 'ADD')
4488                    {
4489                        BX.bind(this.obBuyBtn, 'click', BX.proxy(this.add2Basket, this));
4490                    }
4491                    else
4492                    {
4493                        BX.bind(this.obBuyBtn, 'click', BX.proxy(this.buyBasket, this));
4494                    }
4495                }
4496
4497                if (this.useCompare)
4498                {
4499                    this.obCompare = BX(this.visual.COMPARE_LINK_ID);
4500                    if (this.obCompare)
4501                    {
4502                        BX.bind(this.obCompare, 'click', BX.proxy(this.compare, this));
4503                    }
4504
4505                    BX.addCustomEvent('onCatalogDeleteCompare', BX.proxy(this.checkDeletedCompare, this));
4506                }
4507            }
4508        },
4509
4510        setAnalyticsDataLayer: function(action)
4511        {
4512            if (!this.useEnhancedEcommerce || !this.dataLayerName)
4513                return;
4514
4515            var item = {},
4516                info = {},
4517                variants = [],
4518                i, k, j, propId, skuId, propValues;
4519
4520            switch (this.productType)
4521            {
4522                case 0: //no catalog
4523                case 1: //product
4524                case 2: //set
4525                    item = {
4526                        'id': this.product.id,
4527                        'name': this.product.name,
4528                        'price': this.currentPrices[this.currentPriceSelected] && this.currentPrices[this.currentPriceSelected].PRICE,
4529                        'brand': BX.type.isArray(this.brandProperty) ? this.brandProperty.join('/') : this.brandProperty
4530                    };
4531                    break;
4532                case 3: //sku
4533                    for (i in this.offers[this.offerNum].TREE)
4534                    {
4535                        if (this.offers[this.offerNum].TREE.hasOwnProperty(i))
4536                        {
4537                            propId = i.substring(5);
4538                            skuId = this.offers[this.offerNum].TREE[i];
4539
4540                            for (k in this.treeProps)
4541                            {
4542                                if (this.treeProps.hasOwnProperty(k) && this.treeProps[k].ID == propId)
4543                                {
4544                                    for (j in this.treeProps[k].VALUES)
4545                                    {
4546                                        propValues = this.treeProps[k].VALUES[j];
4547                                        if (propValues.ID == skuId)
4548                                        {
4549                                            variants.push(propValues.NAME);
4550                                            break;
4551                                        }
4552                                    }
4553
4554                                }
4555                            }
4556                        }
4557                    }
4558
4559                    item = {
4560                        'id': this.offers[this.offerNum].ID,
4561                        'name': this.offers[this.offerNum].NAME,
4562                        'price': this.currentPrices[this.currentPriceSelected] && this.currentPrices[this.currentPriceSelected].PRICE,
4563                        'brand': BX.type.isArray(this.brandProperty) ? this.brandProperty.join('/') : this.brandProperty,
4564                        'variant': variants.join('/')
4565                    };
4566                    break;
4567            }
4568
4569            switch (action)
4570            {
4571                case 'addToCart':
4572                    info = {
4573                        'ecommerce': {
4574                            'currencyCode': this.currentPrices[this.currentPriceSelected] && this.currentPrices[this.currentPriceSelected].CURRENCY || '',
4575                            'add': {
4576                                'products': [{
4577                                    'name': item.name || '',
4578                                    'id': item.id || '',
4579                                    'price': item.price || 0,
4580                                    'brand': item.brand || '',
4581                                    'category': item.category || '',
4582                                    'variant': item.variant || '',
4583                                    'quantity': this.showQuantity && this.obQuantity ? this.obQuantity.value : 1
4584                                }]
4585                            }
4586                        }
4587                    };
4588                    break;
4589            }
4590
4591            window[this.dataLayerName] = window[this.dataLayerName] || [];
4592            window[this.dataLayerName].push(info);
4593        },
4594
4595        hoverOn: function(event)
4596        {
4597            clearTimeout(this.hoverTimer);
4598            this.obProduct.style.height = getComputedStyle(this.obProduct).height;
4599            BX.addClass(this.obProduct, 'hover');
4600
4601            BX.PreventDefault(event);
4602        },
4603
4604        hoverOff: function(event)
4605        {
4606            if (this.hoverStateChangeForbidden)
4607                return;
4608
4609            BX.removeClass(this.obProduct, 'hover');
4610            this.hoverTimer = setTimeout(
4611                BX.delegate(function(){
4612                    this.obProduct.style.height = 'auto';
4613                }, this),
4614                300
4615            );
4616
4617            BX.PreventDefault(event);
4618        },
4619
4620        onDelay: function(event)
4621        {
4622            var target = BX.getEventTarget(event);
4623            if(BX.hasClass(target,'added')) {
4624                BX.removeClass(target,'added');
4625                this.basketDelay = 'del'
4626            }else{
4627                BX.addClass(target,'added');
4628                this.basketDelay = 'add'
4629            }
4630            BX.ajax({
4631                method: 'POST',
4632                url: '/local/ajax/toDelay.php',
4633                data: {
4634                    PRODUCT_ID: this.product.id,
4635                    MODE: this.basketDelay,
4636                    CATALOG: 'Y',
4637                },
4638                onsuccess: function (result) {
4639                    window.basketCount();
4640                }
4641            });
4642        },
4643
4644        onFocus: function()
4645        {
4646            this.hoverStateChangeForbidden = true;
4647            BX.bind(document, 'mousemove', BX.proxy(this.captureMousePosition, this));
4648        },
4649
4650        onBlur: function()
4651        {
4652            this.hoverStateChangeForbidden = false;
4653            BX.unbind(document, 'mousemove', BX.proxy(this.captureMousePosition, this));
4654
4655            var cursorElement = document.elementFromPoint(this.mouseX, this.mouseY);
4656            if (!cursorElement || !this.obProduct.contains(cursorElement))
4657            {
4658                this.hoverOff();
4659            }
4660        },
4661
4662        captureMousePosition: function(event)
4663        {
4664            this.mouseX = event.clientX;
4665            this.mouseY = event.clientY;
4666        },
4667
4668        getCookie: function(name)
4669        {
4670            var matches = document.cookie.match(new RegExp(
4671                "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
4672            ));
4673
4674            return matches ? decodeURIComponent(matches[1]) : null;
4675        },
4676
4677        rememberProductRecommendation: function()
4678        {
4679            // save to RCM_PRODUCT_LOG
4680            var cookieName = BX.cookie_prefix + '_RCM_PRODUCT_LOG',
4681                cookie = this.getCookie(cookieName),
4682                itemFound = false;
4683
4684            var cItems = [],
4685                cItem;
4686
4687            if (cookie)
4688            {
4689                cItems = cookie.split('.');
4690            }
4691
4692            var i = cItems.length;
4693
4694            while (i--)
4695            {
4696                cItem = cItems[i].split('-');
4697
4698                if (cItem[0] == this.product.id)
4699                {
4700                    // it's already in recommendations, update the date
4701                    cItem = cItems[i].split('-');
4702
4703                    // update rcmId and date
4704                    cItem[1] = this.product.rcmId;
4705                    cItem[2] = BX.current_server_time;
4706
4707                    cItems[i] = cItem.join('-');
4708                    itemFound = true;
4709                }
4710                else
4711                {
4712                    if ((BX.current_server_time - cItem[2]) > 3600 * 24 * 30)
4713                    {
4714                        cItems.splice(i, 1);
4715                    }
4716                }
4717            }
4718
4719            if (!itemFound)
4720            {
4721                // add recommendation
4722                cItems.push([this.product.id, this.product.rcmId, BX.current_server_time].join('-'));
4723            }
4724
4725            // serialize
4726            var plNewCookie = cItems.join('.'),
4727                cookieDate = new Date(new Date().getTime() + 1000 * 3600 * 24 * 365 * 10).toUTCString();
4728
4729            document.cookie = cookieName + "=" + plNewCookie + "; path=/; expires=" + cookieDate + "; domain=" + BX.cookie_domain;
4730        },
4731
4732        startQuantityInterval: function()
4733        {
4734            var target = BX.proxy_context;
4735            var func = target.id === this.visual.QUANTITY_DOWN_ID
4736                ? BX.proxy(this.quantityDown, this)
4737                : BX.proxy(this.quantityUp, this);
4738
4739            this.quantityDelay = setTimeout(
4740                BX.delegate(function() {
4741                    this.quantityTimer = setInterval(func, 150);
4742                }, this),
4743                300
4744            );
4745        },
4746
4747        clearQuantityInterval: function()
4748        {
4749            clearTimeout(this.quantityDelay);
4750            clearInterval(this.quantityTimer);
4751        },
4752
4753        quantityUp: function()
4754        {
4755            var curValue = 0,
4756                boolSet = true;
4757
4758            if (this.errorCode === 0 && this.showQuantity && this.canBuy)
4759            {
4760                curValue = (this.isDblQuantity ? parseFloat(this.obQuantity.value) : parseInt(this.obQuantity.value, 10));
4761                if (!isNaN(curValue))
4762                {
4763                    curValue += this.stepQuantity;
4764                    if (this.checkQuantity)
4765                    {
4766                        if (curValue > this.maxQuantity)
4767                        {
4768                            boolSet = false;
4769                        }
4770                    }
4771
4772                    if (boolSet)
4773                    {
4774                        if (this.isDblQuantity)
4775                        {
4776                            curValue = Math.round(curValue * this.precisionFactor) / this.precisionFactor;
4777                        }
4778
4779                        this.obQuantity.value = curValue;
4780
4781                        this.setPrice();
4782                    }
4783                }
4784            }
4785        },
4786
4787        quantityDown: function()
4788        {
4789            var curValue = 0,
4790                boolSet = true;
4791
4792            if (this.errorCode === 0 && this.showQuantity && this.canBuy)
4793            {
4794                curValue = (this.isDblQuantity ? parseFloat(this.obQuantity.value) : parseInt(this.obQuantity.value, 10));
4795                if (!isNaN(curValue))
4796                {
4797                    curValue -= this.stepQuantity;
4798
4799                    this.checkPriceRange(curValue);
4800
4801                    if (curValue < this.minQuantity)
4802                    {
4803                        boolSet = false;
4804                    }
4805
4806                    if (boolSet)
4807                    {
4808                        if (this.isDblQuantity)
4809                        {
4810                            curValue = Math.round(curValue * this.precisionFactor) / this.precisionFactor;
4811                        }
4812
4813                        this.obQuantity.value = curValue;
4814
4815                        this.setPrice();
4816                    }
4817                }
4818            }
4819        },
4820
4821        quantityChange: function()
4822        {
4823            var curValue = 0,
4824                intCount;
4825
4826            if (this.errorCode === 0 && this.showQuantity)
4827            {
4828                if (this.canBuy)
4829                {
4830                    curValue = this.isDblQuantity ? parseFloat(this.obQuantity.value) : Math.round(this.obQuantity.value);
4831                    if (!isNaN(curValue))
4832                    {
4833                        if (this.checkQuantity)
4834                        {
4835                            if (curValue > this.maxQuantity)
4836                            {
4837                                curValue = this.maxQuantity;
4838                            }
4839                        }
4840
4841                        this.checkPriceRange(curValue);
4842
4843                        intCount = Math.floor(
4844                            Math.round(curValue * this.precisionFactor / this.stepQuantity) / this.precisionFactor
4845                        ) || 1;
4846                        curValue = (intCount <= 1 ? this.stepQuantity : intCount * this.stepQuantity);
4847                        curValue = Math.round(curValue * this.precisionFactor) / this.precisionFactor;
4848
4849                        if (curValue < this.minQuantity)
4850                        {
4851                            curValue = this.minQuantity;
4852                        }
4853
4854                        this.obQuantity.value = curValue;
4855                    }
4856                    else
4857                    {
4858                        this.obQuantity.value = this.minQuantity;
4859                    }
4860                }
4861                else
4862                {
4863                    this.obQuantity.value = this.minQuantity;
4864                }
4865
4866                this.setPrice();
4867            }
4868        },
4869
4870        quantitySet: function(index)
4871        {
4872            var resetQuantity, strLimit;
4873
4874            var newOffer = this.offers[index],
4875                oldOffer = this.offers[this.offerNum];
4876
4877            if (this.errorCode === 0)
4878            {
4879                this.canBuy = newOffer.CAN_BUY;
4880
4881                this.currentPriceMode = newOffer.ITEM_PRICE_MODE;
4882                this.currentPrices = newOffer.ITEM_PRICES;
4883                this.currentPriceSelected = newOffer.ITEM_PRICE_SELECTED;
4884                this.currentQuantityRanges = newOffer.ITEM_QUANTITY_RANGES;
4885                this.currentQuantityRangeSelected = newOffer.ITEM_QUANTITY_RANGE_SELECTED;
4886
4887                if (this.canBuy)
4888                {
4889                    if (this.blockNodes.quantity)
4890                    {
4891                        BX.style(this.blockNodes.quantity, 'display', '');
4892                    }
4893
4894                    if (this.obBasketActions)
4895                    {
4896                        BX.style(this.obBasketActions, 'display', '');
4897                    }
4898
4899                    if (this.obNotAvail)
4900                    {
4901                        BX.style(this.obNotAvail, 'display', 'none');
4902                    }
4903
4904                    if (this.obSubscribe)
4905                    {
4906                        BX.style(this.obSubscribe, 'display', 'none');
4907                    }
4908                }
4909                else
4910                {
4911                    if (this.blockNodes.quantity)
4912                    {
4913                        BX.style(this.blockNodes.quantity, 'display', 'none');
4914                    }
4915
4916                    if (this.obBasketActions)
4917                    {
4918                        BX.style(this.obBasketActions, 'display', 'none');
4919                    }
4920
4921                    if (this.obNotAvail)
4922                    {
4923                        BX.style(this.obNotAvail, 'display', '');
4924                    }
4925
4926                    if (this.obSubscribe)
4927                    {
4928                        if (newOffer.CATALOG_SUBSCRIBE === 'Y')
4929                        {
4930                            BX.style(this.obSubscribe, 'display', '');
4931                            this.obSubscribe.setAttribute('data-item', newOffer.ID);
4932                            BX(this.visual.SUBSCRIBE_ID + '_hidden').click();
4933                        }
4934                        else
4935                        {
4936                            BX.style(this.obSubscribe, 'display', 'none');
4937                        }
4938                    }
4939                }
4940
4941                this.isDblQuantity = newOffer.QUANTITY_FLOAT;
4942                this.checkQuantity = newOffer.CHECK_QUANTITY;
4943
4944                if (this.isDblQuantity)
4945                {
4946                    this.stepQuantity = Math.round(parseFloat(newOffer.STEP_QUANTITY) * this.precisionFactor) / this.precisionFactor;
4947                    this.maxQuantity = parseFloat(newOffer.MAX_QUANTITY);
4948                    this.minQuantity = this.currentPriceMode === 'Q' ? parseFloat(this.currentPrices[this.currentPriceSelected].MIN_QUANTITY) : this.stepQuantity;
4949                }
4950                else
4951                {
4952                    this.stepQuantity = parseInt(newOffer.STEP_QUANTITY, 10);
4953                    this.maxQuantity = parseInt(newOffer.MAX_QUANTITY, 10);
4954                    this.minQuantity = this.currentPriceMode === 'Q' ? parseInt(this.currentPrices[this.currentPriceSelected].MIN_QUANTITY) : this.stepQuantity;
4955                }
4956
4957                if (this.showQuantity)
4958                {
4959                    var isDifferentMinQuantity = oldOffer.ITEM_PRICES.length
4960                        && oldOffer.ITEM_PRICES[oldOffer.ITEM_PRICE_SELECTED]
4961                        && oldOffer.ITEM_PRICES[oldOffer.ITEM_PRICE_SELECTED].MIN_QUANTITY != this.minQuantity;
4962
4963                    if (this.isDblQuantity)
4964                    {
4965                        resetQuantity = Math.round(parseFloat(oldOffer.STEP_QUANTITY) * this.precisionFactor) / this.precisionFactor !== this.stepQuantity
4966                            || isDifferentMinQuantity
4967                            || oldOffer.MEASURE !== newOffer.MEASURE
4968                            || (
4969                                this.checkQuantity
4970                                && parseFloat(oldOffer.MAX_QUANTITY) > this.maxQuantity
4971                                && parseFloat(this.obQuantity.value) > this.maxQuantity
4972                            );
4973                    }
4974                    else
4975                    {
4976                        resetQuantity = parseInt(oldOffer.STEP_QUANTITY, 10) !== this.stepQuantity
4977                            || isDifferentMinQuantity
4978                            || oldOffer.MEASURE !== newOffer.MEASURE
4979                            || (
4980                                this.checkQuantity
4981                                && parseInt(oldOffer.MAX_QUANTITY, 10) > this.maxQuantity
4982                                && parseInt(this.obQuantity.value, 10) > this.maxQuantity
4983                            );
4984                    }
4985
4986                    this.obQuantity.disabled = !this.canBuy;
4987
4988                    if (resetQuantity)
4989                    {
4990                        this.obQuantity.value = this.minQuantity;
4991                    }
4992
4993                    if (this.obMeasure)
4994                    {
4995                        if (newOffer.MEASURE)
4996                        {
4997                            BX.adjust(this.obMeasure, {html: newOffer.MEASURE});
4998                        }
4999                        else
5000                        {
5001                            BX.adjust(this.obMeasure, {html: ''});
5002                        }
5003                    }
5004                }
5005
5006                if (this.obQuantityLimit.all)
5007                {
5008                    if (!this.checkQuantity || this.maxQuantity == 0)
5009                    {
5010                        BX.adjust(this.obQuantityLimit.value, {html: ''});
5011                        BX.adjust(this.obQuantityLimit.all, {style: {display: 'none'}});
5012                    }
5013                    else
5014                    {
5015                        if (this.showMaxQuantity === 'M')
5016                        {
5017                            strLimit = (this.maxQuantity / this.stepQuantity >= this.relativeQuantityFactor)
5018                                ? BX.message('RELATIVE_QUANTITY_MANY')
5019                                : BX.message('RELATIVE_QUANTITY_FEW');
5020                        }
5021                        else
5022                        {
5023                            strLimit = this.maxQuantity;
5024
5025                            if (newOffer.MEASURE)
5026                            {
5027                                strLimit += (' ' + newOffer.MEASURE);
5028                            }
5029                        }
5030
5031                        BX.adjust(this.obQuantityLimit.value, {html: strLimit});
5032                        BX.adjust(this.obQuantityLimit.all, {style: {display: ''}});
5033                    }
5034                }
5035            }
5036        },
5037
5038        initializeSlider: function()
5039        {
5040            var wrap = this.obPictSlider.getAttribute('data-slider-wrap');
5041            if (wrap)
5042            {
5043                this.slider.options.wrap = wrap === 'true';
5044            }
5045            else
5046            {
5047                this.slider.options.wrap = this.defaultSliderOptions.wrap;
5048            }
5049
5050            if (this.isTouchDevice)
5051            {
5052                this.slider.options.interval = false;
5053            }
5054            else
5055            {
5056                this.slider.options.interval = parseInt(this.obPictSlider.getAttribute('data-slider-interval')) || this.defaultSliderOptions.interval;
5057                // slider interval must be more than 700ms because of css transitions
5058                if (this.slider.options.interval < 700)
5059                {
5060                    this.slider.options.interval = 700;
5061                }
5062
5063                if (this.obPictSliderIndicator)
5064                {
5065                    var controls = this.obPictSliderIndicator.querySelectorAll('[data-go-to]');
5066                    for (var i in controls)
5067                    {
5068                        if (controls.hasOwnProperty(i))
5069                        {
5070                            BX.bind(controls[i], 'click', BX.proxy(this.sliderClickHandler, this));
5071                        }
5072                    }
5073                }
5074
5075                if (this.obPictSliderProgressBar)
5076                {
5077                    if (this.slider.progress)
5078                    {
5079                        this.resetProgress();
5080                        this.cycleSlider();
5081                    }
5082                    else
5083                    {
5084                        this.slider.progress = new BX.easing({
5085                            transition: BX.easing.transitions.linear,
5086                            step: BX.delegate(function(state){
5087                                this.obPictSliderProgressBar.style.width = state.width / 10 + '%';
5088                            }, this)
5089                        });
5090                    }
5091                }
5092            }
5093        },
5094
5095        checkTouch: function(event)
5096        {
5097            if (!event || !event.changedTouches)
5098                return false;
5099
5100            return event.changedTouches[0].identifier === this.touch.identifier;
5101        },
5102
5103        touchStartEvent: function(event)
5104        {
5105            if (event.touches.length != 1)
5106                return;
5107
5108            this.touch = event.changedTouches[0];
5109        },
5110
5111        touchEndEvent: function(event)
5112        {
5113            if (!this.checkTouch(event))
5114                return;
5115
5116            var deltaX = this.touch.pageX - event.changedTouches[0].pageX,
5117                deltaY = this.touch.pageY - event.changedTouches[0].pageY;
5118
5119            if (Math.abs(deltaX) >= Math.abs(deltaY) + 10)
5120            {
5121                if (deltaX > 0)
5122                {
5123                    this.slideNext();
5124                }
5125
5126                if (deltaX < 0)
5127                {
5128                    this.slidePrev();
5129                }
5130            }
5131        },
5132
5133        sliderClickHandler: function(event)
5134        {
5135            var target = BX.getEventTarget(event),
5136                slideIndex = target.getAttribute('data-go-to');
5137
5138            if (slideIndex)
5139            {
5140                this.slideTo(slideIndex)
5141            }
5142
5143            BX.PreventDefault(event);
5144        },
5145
5146        slideNext: function()
5147        {
5148            if (this.slider.sliding)
5149                return;
5150
5151            return this.slide('next');
5152        },
5153
5154        slidePrev: function()
5155        {
5156            if (this.slider.sliding)
5157                return;
5158
5159            return this.slide('prev');
5160        },
5161
5162        slideTo: function(pos)
5163        {
5164            this.slider.active = BX.findChild(this.obPictSlider, {className: 'item active'}, true, false);
5165            this.slider.progress && (this.slider.interval = true);
5166
5167            var activeIndex = this.getItemIndex(this.slider.active);
5168
5169            if (pos > (this.slider.items.length - 1) || pos < 0)
5170                return;
5171
5172            if (this.slider.sliding)
5173                return false;
5174
5175            if (activeIndex == pos)
5176            {
5177                this.stopSlider();
5178                this.cycleSlider();
5179                return;
5180            }
5181
5182            return this.slide(pos > activeIndex ? 'next' : 'prev', this.eq(this.slider.items, pos));
5183        },
5184
5185        slide: function(type, next)
5186        {
5187            var active = BX.findChild(this.obPictSlider, {className: 'item active'}, true, false),
5188                isCycling = this.slider.interval,
5189                direction = type === 'next' ? 'left' : 'right';
5190
5191            next = next || this.getItemForDirection(type, active);
5192
5193            if (BX.hasClass(next, 'active'))
5194            {
5195                return (this.slider.sliding = false);
5196            }
5197
5198            this.slider.sliding = true;
5199
5200            isCycling && this.stopSlider();
5201
5202            if (this.obPictSliderIndicator)
5203            {
5204                BX.removeClass(this.obPictSliderIndicator.querySelector('.active'), 'active');
5205                var nextIndicator = this.obPictSliderIndicator.querySelectorAll('[data-go-to]')[this.getItemIndex(next)];
5206                nextIndicator && BX.addClass(nextIndicator, 'active');
5207            }
5208
5209            if (BX.hasClass(this.obPictSlider, 'slide') && !BX.browser.IsIE())
5210            {
5211                var self = this;
5212                BX.addClass(next, type);
5213                next.offsetWidth; // force reflow
5214                BX.addClass(active, direction);
5215                BX.addClass(next, direction);
5216                setTimeout(function() {
5217                    BX.addClass(next, 'active');
5218                    BX.removeClass(active, 'active');
5219                    BX.removeClass(active, direction);
5220                    BX.removeClass(next, type);
5221                    BX.removeClass(next, direction);
5222                    self.slider.sliding = false;
5223                }, 700);
5224            }
5225            else
5226            {
5227                BX.addClass(next, 'active');
5228                this.slider.sliding = false;
5229            }
5230
5231            this.obPictSliderProgressBar && this.resetProgress();
5232            isCycling && this.cycleSlider();
5233        },
5234
5235        stopSlider: function(event)
5236        {
5237            event || (this.slider.paused = true);
5238
5239            this.slider.interval && clearInterval(this.slider.interval);
5240
5241            if (this.slider.progress)
5242            {
5243                this.slider.progress.stop();
5244
5245                var width = parseInt(this.obPictSliderProgressBar.style.width);
5246
5247                this.slider.progress.options.duration = this.slider.options.interval * width / 200;
5248                this.slider.progress.options.start = {width: width * 10};
5249                this.slider.progress.options.finish = {width: 0};
5250                this.slider.progress.options.complete = null;
5251                this.slider.progress.animate();
5252            }
5253        },
5254
5255        cycleSlider: function(event)
5256        {
5257            event || (this.slider.paused = false);
5258
5259            this.slider.interval && clearInterval(this.slider.interval);
5260
5261            if (this.slider.options.interval && !this.slider.paused)
5262            {
5263                if (this.slider.progress)
5264                {
5265                    this.slider.progress.stop();
5266
5267                    var width = parseInt(this.obPictSliderProgressBar.style.width);
5268
5269                    this.slider.progress.options.duration = this.slider.options.interval * (100 - width) / 100;
5270                    this.slider.progress.options.start = {width: width * 10};
5271                    this.slider.progress.options.finish = {width: 1000};
5272                    this.slider.progress.options.complete = BX.delegate(function(){
5273                        this.slider.interval = true;
5274                        this.slideNext();
5275                    }, this);
5276                    this.slider.progress.animate();
5277                }
5278                else
5279                {
5280                    this.slider.interval = setInterval(BX.proxy(this.slideNext, this), this.slider.options.interval);
5281                }
5282            }
5283        },
5284
5285        resetProgress: function()
5286        {
5287            this.slider.progress && this.slider.progress.stop();
5288            this.obPictSliderProgressBar.style.width = 0;
5289        },
5290
5291        getItemForDirection: function(direction, active)
5292        {
5293            var activeIndex = this.getItemIndex(active),
5294                willWrap = direction === 'prev' && activeIndex === 0
5295                    || direction === 'next' && activeIndex == (this.slider.items.length - 1);
5296
5297            if (willWrap && !this.slider.options.wrap)
5298                return active;
5299
5300            var delta = direction === 'prev' ? -1 : 1,
5301                itemIndex = (activeIndex + delta) % this.slider.items.length;
5302
5303            return this.eq(this.slider.items, itemIndex);
5304        },
5305
5306        getItemIndex: function(item)
5307        {
5308            this.slider.items = BX.findChildren(item.parentNode, {className: 'item'}, true);
5309
5310            return this.slider.items.indexOf(item || this.slider.active);
5311        },
5312
5313        eq: function(obj, i)
5314        {
5315            var len = obj.length,
5316                j = +i + (i < 0 ? len : 0);
5317
5318            return j >= 0 && j < len ? obj[j] : {};
5319        },
5320
5321        selectOfferProp: function()
5322        {
5323            var i = 0,
5324                value = '',
5325                strTreeValue = '',
5326                arTreeItem = [],
5327                rowItems = null,
5328                target = BX.proxy_context;
5329
5330            if (target && target.hasAttribute('data-treevalue'))
5331            {
5332                if (BX.hasClass(target, 'selected'))
5333                    return;
5334
5335                strTreeValue = target.getAttribute('data-treevalue');
5336                arTreeItem = strTreeValue.split('_');
5337                if (this.searchOfferPropIndex(arTreeItem[0], arTreeItem[1]))
5338                {
5339                    rowItems = BX.findChildren(target.parentNode, {tagName: 'li'}, false);
5340                    if (rowItems && 0 < rowItems.length)
5341                    {
5342                        for (i = 0; i < rowItems.length; i++)
5343                        {
5344                            value = rowItems[i].getAttribute('data-onevalue');
5345                            if (value === arTreeItem[1])
5346                            {
5347                                BX.addClass(rowItems[i], 'selected');
5348                            }
5349                            else
5350                            {
5351                                BX.removeClass(rowItems[i], 'selected');
5352                            }
5353                        }
5354                    }
5355
5356                    if (
5357                        this.isFacebookConversionCustomizeProductEventEnabled
5358                        && BX.Type.isArrayFilled(this.offers)
5359                        && BX.Type.isObject(this.offers[this.offerNum])
5360                    )
5361                    {
5362                        BX.ajax.runAction(
5363                            'sale.facebookconversion.customizeProduct',
5364                            {
5365                                data: {
5366                                    offerId: this.offers[this.offerNum]['ID']
5367                                }
5368                            }
5369                        );
5370                    }
5371                }
5372            }
5373        },
5374
5375        searchOfferPropIndex: function(strPropID, strPropValue)
5376        {
5377            var strName = '',
5378                arShowValues = false,
5379                i, j,
5380                arCanBuyValues = [],
5381                allValues = [],
5382                index = -1,
5383                arFilter = {},
5384                tmpFilter = [];
5385
5386            for (i = 0; i < this.treeProps.length; i++)
5387            {
5388                if (this.treeProps[i].ID === strPropID)
5389                {
5390                    index = i;
5391                    break;
5392                }
5393            }
5394
5395            if (-1 < index)
5396            {
5397                for (i = 0; i < index; i++)
5398                {
5399                    strName = 'PROP_'+this.treeProps[i].ID;
5400                    arFilter[strName] = this.selectedValues[strName];
5401                }
5402                strName = 'PROP_'+this.treeProps[index].ID;
5403                arShowValues = this.getRowValues(arFilter, strName);
5404                if (!arShowValues)
5405                {
5406                    return false;
5407                }
5408                if (!BX.util.in_array(strPropValue, arShowValues))
5409                {
5410                    return false;
5411                }
5412                arFilter[strName] = strPropValue;
5413                for (i = index+1; i < this.treeProps.length; i++)
5414                {
5415                    strName = 'PROP_'+this.treeProps[i].ID;
5416                    arShowValues = this.getRowValues(arFilter, strName);
5417                    if (!arShowValues)
5418                    {
5419                        return false;
5420                    }
5421                    allValues = [];
5422                    if (this.showAbsent)
5423                    {
5424                        arCanBuyValues = [];
5425                        tmpFilter = [];
5426                        tmpFilter = BX.clone(arFilter, true);
5427                        for (j = 0; j < arShowValues.length; j++)
5428                        {
5429                            tmpFilter[strName] = arShowValues[j];
5430                            allValues[allValues.length] = arShowValues[j];
5431                            if (this.getCanBuy(tmpFilter))
5432                                arCanBuyValues[arCanBuyValues.length] = arShowValues[j];
5433                        }
5434                    }
5435                    else
5436                    {
5437                        arCanBuyValues = arShowValues;
5438                    }
5439                    if (this.selectedValues[strName] && BX.util.in_array(this.selectedValues[strName], arCanBuyValues))
5440                    {
5441                        arFilter[strName] = this.selectedValues[strName];
5442                    }
5443                    else
5444                    {
5445                        if (this.showAbsent)
5446                            arFilter[strName] = (arCanBuyValues.length > 0 ? arCanBuyValues[0] : allValues[0]);
5447                        else
5448                            arFilter[strName] = arCanBuyValues[0];
5449                    }
5450                    this.updateRow(i, arFilter[strName], arShowValues, arCanBuyValues);
5451                }
5452                this.selectedValues = arFilter;
5453                this.changeInfo();
5454            }
5455            return true;
5456        },
5457
5458        updateRow: function(intNumber, activeID, showID, canBuyID)
5459        {
5460            var i = 0,
5461                value = '',
5462                isCurrent = false,
5463                rowItems = null;
5464
5465            var lineContainer = this.obTree.querySelectorAll('[data-entity="sku-line-block"]'),
5466                listContainer;
5467
5468            if (intNumber > -1 && intNumber < lineContainer.length)
5469            {
5470                listContainer = lineContainer[intNumber].querySelector('ul');
5471                rowItems = BX.findChildren(listContainer, {tagName: 'li'}, false);
5472                if (rowItems && 0 < rowItems.length)
5473                {
5474                    for (i = 0; i < rowItems.length; i++)
5475                    {
5476                        value = rowItems[i].getAttribute('data-onevalue');
5477                        isCurrent = value === activeID;
5478
5479                        if (isCurrent)
5480                        {
5481                            BX.addClass(rowItems[i], 'selected');
5482                        }
5483                        else
5484                        {
5485                            BX.removeClass(rowItems[i], 'selected');
5486                        }
5487
5488                        if (BX.util.in_array(value, canBuyID))
5489                        {
5490                            BX.removeClass(rowItems[i], 'notallowed');
5491                        }
5492                        else
5493                        {
5494                            BX.addClass(rowItems[i], 'notallowed');
5495                        }
5496
5497                        rowItems[i].style.display = BX.util.in_array(value, showID) ? '' : 'none';
5498
5499                        if (isCurrent)
5500                        {
5501                            lineContainer[intNumber].style.display = (value == 0 && canBuyID.length == 1) ? 'none' : '';
5502                        }
5503                    }
5504                }
5505            }
5506        },
5507
5508        getRowValues: function(arFilter, index)
5509        {
5510            var i = 0,
5511                j,
5512                arValues = [],
5513                boolSearch = false,
5514                boolOneSearch = true;
5515
5516            if (0 === arFilter.length)
5517            {
5518                for (i = 0; i < this.offers.length; i++)
5519                {
5520                    if (!BX.util.in_array(this.offers[i].TREE[index], arValues))
5521                    {
5522                        arValues[arValues.length] = this.offers[i].TREE[index];
5523                    }
5524                }
5525                boolSearch = true;
5526            }
5527            else
5528            {
5529                for (i = 0; i < this.offers.length; i++)
5530                {
5531                    boolOneSearch = true;
5532                    for (j in arFilter)
5533                    {
5534                        if (arFilter[j] !== this.offers[i].TREE[j])
5535                        {
5536                            boolOneSearch = false;
5537                            break;
5538                        }
5539                    }
5540                    if (boolOneSearch)
5541                    {
5542                        if (!BX.util.in_array(this.offers[i].TREE[index], arValues))
5543                        {
5544                            arValues[arValues.length] = this.offers[i].TREE[index];
5545                        }
5546                        boolSearch = true;
5547                    }
5548                }
5549            }
5550            return (boolSearch ? arValues : false);
5551        },
5552
5553        getCanBuy: function(arFilter)
5554        {
5555            var i, j,
5556                boolSearch = false,
5557                boolOneSearch = true;
5558
5559            for (i = 0; i < this.offers.length; i++)
5560            {
5561                boolOneSearch = true;
5562                for (j in arFilter)
5563                {
5564                    if (arFilter[j] !== this.offers[i].TREE[j])
5565                    {
5566                        boolOneSearch = false;
5567                        break;
5568                    }
5569                }
5570                if (boolOneSearch)
5571                {
5572                    if (this.offers[i].CAN_BUY)
5573                    {
5574                        boolSearch = true;
5575                        break;
5576                    }
5577                }
5578            }
5579
5580            return boolSearch;
5581        },
5582
5583        setCurrent: function()
5584        {
5585            var i,
5586                j = 0,
5587                arCanBuyValues = [],
5588                strName = '',
5589                arShowValues = false,
5590                arFilter = {},
5591                tmpFilter = [],
5592                current = this.offers[this.offerNum].TREE;
5593
5594            for (i = 0; i < this.treeProps.length; i++)
5595            {
5596                strName = 'PROP_'+this.treeProps[i].ID;
5597                arShowValues = this.getRowValues(arFilter, strName);
5598                if (!arShowValues)
5599                {
5600                    break;
5601                }
5602                if (BX.util.in_array(current[strName], arShowValues))
5603                {
5604                    arFilter[strName] = current[strName];
5605                }
5606                else
5607                {
5608                    arFilter[strName] = arShowValues[0];
5609                    this.offerNum = 0;
5610                }
5611                if (this.showAbsent)
5612                {
5613                    arCanBuyValues = [];
5614                    tmpFilter = [];
5615                    tmpFilter = BX.clone(arFilter, true);
5616                    for (j = 0; j < arShowValues.length; j++)
5617                    {
5618                        tmpFilter[strName] = arShowValues[j];
5619                        if (this.getCanBuy(tmpFilter))
5620                        {
5621                            arCanBuyValues[arCanBuyValues.length] = arShowValues[j];
5622                        }
5623                    }
5624                }
5625                else
5626                {
5627                    arCanBuyValues = arShowValues;
5628                }
5629                this.updateRow(i, arFilter[strName], arShowValues, arCanBuyValues);
5630            }
5631            this.selectedValues = arFilter;
5632            this.changeInfo();
5633        },
5634
5635        changeInfo: function()
5636        {
5637            var i, j,
5638                index = -1,
5639                boolOneSearch = true,
5640                quantityChanged;
5641
5642            for (i = 0; i < this.offers.length; i++)
5643            {
5644                boolOneSearch = true;
5645                for (j in this.selectedValues)
5646                {
5647                    if (this.selectedValues[j] !== this.offers[i].TREE[j])
5648                    {
5649                        boolOneSearch = false;
5650                        break;
5651                    }
5652                }
5653                if (boolOneSearch)
5654                {
5655                    index = i;
5656                    break;
5657                }
5658            }
5659            if (index > -1)
5660            {
5661                if (parseInt(this.offers[index].MORE_PHOTO_COUNT) > 1 && this.obPictSlider)
5662                {
5663                    // hide pict and second_pict containers
5664                    if (this.obPict)
5665                    {
5666                        this.obPict.style.display = 'none';
5667                    }
5668
5669                    if (this.obSecondPict)
5670                    {
5671                        this.obSecondPict.style.display = 'none';
5672                    }
5673
5674                    // clear slider container
5675                    BX.cleanNode(this.obPictSlider);
5676
5677                    // fill slider container with slides
5678                    for (i in this.offers[index].MORE_PHOTO)
5679                    {
5680                        if (this.offers[index].MORE_PHOTO.hasOwnProperty(i))
5681                        {
5682                            this.obPictSlider.appendChild(
5683                                BX.create('SPAN', {
5684                                    props: {className: 'product-item-image-slide item' + (i == 0 ? ' active' : '')},
5685                                    style: {backgroundImage: 'url(\'' + this.offers[index].MORE_PHOTO[i].SRC + '\')'}
5686                                })
5687                            );
5688                        }
5689                    }
5690
5691                    // fill slider indicator if exists
5692                    if (this.obPictSliderIndicator)
5693                    {
5694                        BX.cleanNode(this.obPictSliderIndicator);
5695
5696                        for (i in this.offers[index].MORE_PHOTO)
5697                        {
5698                            if (this.offers[index].MORE_PHOTO.hasOwnProperty(i))
5699                            {
5700                                this.obPictSliderIndicator.appendChild(
5701                                    BX.create('DIV', {
5702                                        attrs: {'data-go-to': i},
5703                                        props: {className: 'product-item-image-slider-control' + (i == 0 ? ' active' : '')}
5704                                    })
5705                                );
5706                                this.obPictSliderIndicator.appendChild(document.createTextNode(' '));
5707                            }
5708                        }
5709
5710                        this.obPictSliderIndicator.style.display = '';
5711                    }
5712
5713                    if (this.obPictSliderProgressBar)
5714                    {
5715                        this.obPictSliderProgressBar.style.display = '';
5716                    }
5717
5718                    // show slider container
5719                    this.obPictSlider.style.display = '';
5720                    this.initializeSlider();
5721                }
5722                else
5723                {
5724                    // hide slider container
5725                    if (this.obPictSlider)
5726                    {
5727                        this.obPictSlider.style.display = 'none';
5728                    }
5729
5730                    if (this.obPictSliderIndicator)
5731                    {
5732                        this.obPictSliderIndicator.style.display = 'none';
5733                    }
5734
5735                    if (this.obPictSliderProgressBar)
5736                    {
5737                        this.obPictSliderProgressBar.style.display = 'none';
5738                    }
5739
5740                    // show pict and pict_second containers
5741                    if (this.obPict)
5742                    {
5743                        if (this.offers[index].PREVIEW_PICTURE)
5744                        {
5745                            BX.adjust(this.obPict, {style: {backgroundImage: 'url(\'' + this.offers[index].PREVIEW_PICTURE.SRC + '\')'}});
5746                        }
5747                        else
5748                        {
5749                            BX.adjust(this.obPict, {style: {backgroundImage: 'url(\'' + this.defaultPict.pict.SRC + '\')'}});
5750                        }
5751
5752                        this.obPict.style.display = '';
5753                    }
5754
5755                    if (this.secondPict && this.obSecondPict)
5756                    {
5757                        if (this.offers[index].PREVIEW_PICTURE_SECOND)
5758                        {
5759                            BX.adjust(this.obSecondPict, {style: {backgroundImage: 'url(\'' + this.offers[index].PREVIEW_PICTURE_SECOND.SRC + '\')'}});
5760                        }
5761                        else if (this.offers[index].PREVIEW_PICTURE.SRC)
5762                        {
5763                            BX.adjust(this.obSecondPict, {style: {backgroundImage: 'url(\'' + this.offers[index].PREVIEW_PICTURE.SRC + '\')'}});
5764                        }
5765                        else if (this.defaultPict.secondPict)
5766                        {
5767                            BX.adjust(this.obSecondPict, {style: {backgroundImage: 'url(\'' + this.defaultPict.secondPict.SRC + '\')'}});
5768                        }
5769                        else
5770                        {
5771                            BX.adjust(this.obSecondPict, {style: {backgroundImage: 'url(\'' + this.defaultPict.pict.SRC + '\')'}});
5772                        }
5773
5774                        this.obSecondPict.style.display = '';
5775                    }
5776                }
5777
5778                if (this.showSkuProps && this.obSkuProps)
5779                {
5780                    if (this.offers[index].DISPLAY_PROPERTIES.length)
5781                    {
5782                        BX.adjust(this.obSkuProps, {style: {display: ''}, html: this.offers[index].DISPLAY_PROPERTIES});
5783                    }
5784                    else
5785                    {
5786                        BX.adjust(this.obSkuProps, {style: {display: 'none'}, html: ''});
5787                    }
5788                }
5789
5790                this.quantitySet(index);
5791                this.setPrice();
5792                this.setCompared(this.offers[index].COMPARED);
5793
5794                this.offerNum = index;
5795            }
5796        },
5797
5798        checkPriceRange: function(quantity)
5799        {
5800            if (typeof quantity === 'undefined'|| this.currentPriceMode != 'Q')
5801                return;
5802
5803            var range, found = false;
5804
5805            for (var i in this.currentQuantityRanges)
5806            {
5807                if (this.currentQuantityRanges.hasOwnProperty(i))
5808                {
5809                    range = this.currentQuantityRanges[i];
5810
5811                    if (
5812                        parseInt(quantity) >= parseInt(range.SORT_FROM)
5813                        && (
5814                            range.SORT_TO == 'INF'
5815                            || parseInt(quantity) <= parseInt(range.SORT_TO)
5816                        )
5817                    )
5818                    {
5819                        found = true;
5820                        this.currentQuantityRangeSelected = range.HASH;
5821                        break;
5822                    }
5823                }
5824            }
5825
5826            if (!found && (range = this.getMinPriceRange()))
5827            {
5828                this.currentQuantityRangeSelected = range.HASH;
5829            }
5830
5831            for (var k in this.currentPrices)
5832            {
5833                if (this.currentPrices.hasOwnProperty(k))
5834                {
5835                    if (this.currentPrices[k].QUANTITY_HASH == this.currentQuantityRangeSelected)
5836                    {
5837                        this.currentPriceSelected = k;
5838                        break;
5839                    }
5840                }
5841            }
5842        },
5843
5844        getMinPriceRange: function()
5845        {
5846            var range;
5847
5848            for (var i in this.currentQuantityRanges)
5849            {
5850                if (this.currentQuantityRanges.hasOwnProperty(i))
5851                {
5852                    if (
5853                        !range
5854                        || parseInt(this.currentQuantityRanges[i].SORT_FROM) < parseInt(range.SORT_FROM)
5855                    )
5856                    {
5857                        range = this.currentQuantityRanges[i];
5858                    }
5859                }
5860            }
5861
5862            return range;
5863        },
5864
5865        checkQuantityControls: function()
5866        {
5867            if (!this.obQuantity)
5868                return;
5869
5870            var reachedTopLimit = this.checkQuantity && parseFloat(this.obQuantity.value) + this.stepQuantity > this.maxQuantity,
5871                reachedBottomLimit = parseFloat(this.obQuantity.value) - this.stepQuantity < this.minQuantity;
5872
5873            if (reachedTopLimit)
5874            {
5875                BX.addClass(this.obQuantityUp, 'product-item-amount-field-btn-disabled');
5876            }
5877            else if (BX.hasClass(this.obQuantityUp, 'product-item-amount-field-btn-disabled'))
5878            {
5879                BX.removeClass(this.obQuantityUp, 'product-item-amount-field-btn-disabled');
5880            }
5881
5882            if (reachedBottomLimit)
5883            {
5884                BX.addClass(this.obQuantityDown, 'product-item-amount-field-btn-disabled');
5885            }
5886            else if (BX.hasClass(this.obQuantityDown, 'product-item-amount-field-btn-disabled'))
5887            {
5888                BX.removeClass(this.obQuantityDown, 'product-item-amount-field-btn-disabled');
5889            }
5890
5891            if (reachedTopLimit && reachedBottomLimit)
5892            {
5893                this.obQuantity.setAttribute('disabled', 'disabled');
5894            }
5895            else
5896            {
5897                this.obQuantity.removeAttribute('disabled');
5898            }
5899        },
5900
5901        setPrice: function()
5902        {
5903            var obData, price;
5904
5905            if (this.obQuantity)
5906            {
5907                this.checkPriceRange(this.obQuantity.value);
5908            }
5909
5910            this.checkQuantityControls();
5911
5912            price = this.currentPrices[this.currentPriceSelected];
5913
5914            if (this.obPrice)
5915            {
5916                if (price)
5917                {
5918                    BX.adjust(this.obPrice, {html: BX.Currency.currencyFormat(price.RATIO_PRICE, price.CURRENCY, true)});
5919                }
5920                else
5921                {
5922                    BX.adjust(this.obPrice, {html: ''});
5923                }
5924
5925                if (this.showOldPrice && this.obPriceOld)
5926                {
5927                    if (price && price.RATIO_PRICE !== price.RATIO_BASE_PRICE)
5928                    {
5929                        BX.adjust(this.obPriceOld, {
5930                            style: {display: ''},
5931                            html: BX.Currency.currencyFormat(price.RATIO_BASE_PRICE, price.CURRENCY, true)
5932                        });
5933                    }
5934                    else
5935                    {
5936                        BX.adjust(this.obPriceOld, {
5937                            style: {display: 'none'},
5938                            html: ''
5939                        });
5940                    }
5941                }
5942
5943                if (this.obPriceTotal)
5944                {
5945                    if (price && this.obQuantity && this.obQuantity.value != this.stepQuantity)
5946                    {
5947                        BX.adjust(this.obPriceTotal, {
5948                            html: BX.message('PRICE_TOTAL_PREFIX') + ' <strong>'
5949                                + BX.Currency.currencyFormat(price.PRICE * this.obQuantity.value, price.CURRENCY, true)
5950                                + '</strong>',
5951                            style: {display: ''}
5952                        });
5953                    }
5954                    else
5955                    {
5956                        BX.adjust(this.obPriceTotal, {
5957                            html: '',
5958                            style: {display: 'none'}
5959                        });
5960                    }
5961                }
5962
5963                if (this.showPercent)
5964                {
5965                    if (price && parseInt(price.PERCENT) > 0)
5966                    {
5967                        obData = {style: {display: ''}, html: -price.PERCENT + '%'};
5968                    }
5969                    else
5970                    {
5971                        obData = {style: {display: 'none'}, html: ''};
5972                    }
5973
5974                    if (this.obDscPerc)
5975                    {
5976                        BX.adjust(this.obDscPerc, obData);
5977                    }
5978
5979                    if (this.obSecondDscPerc)
5980                    {
5981                        BX.adjust(this.obSecondDscPerc, obData);
5982                    }
5983                }
5984            }
5985        },
5986
5987        compare: function(event)
5988        {
5989            var checkbox = this.obCompare.querySelector('[data-entity="compare-checkbox"]'),
5990                target = BX.getEventTarget(event),
5991                checked = true;
5992
5993            if (checkbox)
5994            {
5995                checked = target === checkbox ? checkbox.checked : !checkbox.checked;
5996            }
5997
5998            var url = checked ? this.compareData.compareUrl : this.compareData.compareDeleteUrl,
5999                compareLink;
6000
6001            if (url)
6002            {
6003                if (target !== checkbox)
6004                {
6005                    BX.PreventDefault(event);
6006                    this.setCompared(checked);
6007                }
6008
6009                switch (this.productType)
6010                {
6011                    case 0: // no catalog
6012                    case 1: // product
6013                    case 2: // set
6014                        compareLink = url.replace('#ID#', this.product.id.toString());
6015                        break;
6016                    case 3: // sku
6017                        compareLink = url.replace('#ID#', this.offers[this.offerNum].ID);
6018                        break;
6019                }
6020
6021                BX.ajax({
6022                    method: 'POST',
6023                    dataType: checked ? 'json' : 'html',
6024                    url: compareLink + (compareLink.indexOf('?') !== -1 ? '&' : '?') + 'ajax_action=Y',
6025                    onsuccess: checked
6026                        ? BX.proxy(this.compareResult, this)
6027                        : BX.proxy(this.compareDeleteResult, this)
6028                });
6029            }
6030        },
6031
6032        compareResult: function(result)
6033        {
6034            var popupContent, popupButtons;
6035
6036            if (this.obPopupWin)
6037            {
6038                this.obPopupWin.close();
6039            }
6040
6041            if (!BX.type.isPlainObject(result))
6042                return;
6043
6044            this.initPopupWindow();
6045
6046            if (this.offers.length > 0)
6047            {
6048                this.offers[this.offerNum].COMPARED = result.STATUS === 'OK';
6049            }
6050
6051            if (result.STATUS === 'OK')
6052            {
6053                BX.onCustomEvent('OnCompareChange');
6054
6055                popupContent = '<div style="width: 100%; margin: 0; text-align: center;"><p>'
6056                    + BX.message('COMPARE_MESSAGE_OK')
6057                    + '</p></div>';
6058
6059                if (this.showClosePopup)
6060                {
6061                    popupButtons = [
6062                        new BasketButton({
6063                            text: BX.message('BTN_MESSAGE_COMPARE_REDIRECT'),
6064                            events: {
6065                                click: BX.delegate(this.compareRedirect, this)
6066                            },
6067                            style: {marginRight: '10px'}
6068                        }),
6069                        new BasketButton({
6070                            text: BX.message('BTN_MESSAGE_CLOSE_POPUP'),
6071                            events: {
6072                                click: BX.delegate(this.obPopupWin.close, this.obPopupWin)
6073                            }
6074                        })
6075                    ];
6076                }
6077                else
6078                {
6079                    popupButtons = [
6080                        new BasketButton({
6081                            text: BX.message('BTN_MESSAGE_COMPARE_REDIRECT'),
6082                            events: {
6083                                click: BX.delegate(this.compareRedirect, this)
6084                            }
6085                        })
6086                    ];
6087                }
6088            }
6089            else
6090            {
6091                popupContent = '<div style="width: 100%; margin: 0; text-align: center;"><p>'
6092                    + (result.MESSAGE ? result.MESSAGE : BX.message('COMPARE_UNKNOWN_ERROR'))
6093                    + '</p></div>';
6094                popupButtons = [
6095                    new BasketButton({
6096                        text: BX.message('BTN_MESSAGE_CLOSE'),
6097                        events: {
6098                            click: BX.delegate(this.obPopupWin.close, this.obPopupWin)
6099                        }
6100                    })
6101                ];
6102            }
6103
6104            this.obPopupWin.setTitleBar(BX.message('COMPARE_TITLE'));
6105            this.obPopupWin.setContent(popupContent);
6106            this.obPopupWin.setButtons(popupButtons);
6107            this.obPopupWin.show();
6108        },
6109
6110        compareDeleteResult: function()
6111        {
6112            BX.onCustomEvent('OnCompareChange');
6113
6114            if (this.offers && this.offers.length)
6115            {
6116                this.offers[this.offerNum].COMPARED = false;
6117            }
6118        },
6119
6120        setCompared: function(state)
6121        {
6122            if (!this.obCompare)
6123                return;
6124
6125            var checkbox = this.obCompare.querySelector('[data-entity="compare-checkbox"]');
6126            if (checkbox)
6127            {
6128                checkbox.checked = state;
6129            }
6130        },
6131
6132        setCompareInfo: function(comparedIds)
6133        {
6134            if (!BX.type.isArray(comparedIds))
6135                return;
6136
6137            for (var i in this.offers)
6138            {
6139                if (this.offers.hasOwnProperty(i))
6140                {
6141                    this.offers[i].COMPARED = BX.util.in_array(this.offers[i].ID, comparedIds);
6142                }
6143            }
6144        },
6145
6146        compareRedirect: function()
6147        {
6148            if (this.compareData.comparePath)
6149            {
6150                location.href = this.compareData.comparePath;
6151            }
6152            else
6153            {
6154                this.obPopupWin.close();
6155            }
6156        },
6157
6158        checkDeletedCompare: function(id)
6159        {
6160            switch (this.productType)
6161            {
6162                case 0: // no catalog
6163                case 1: // product
6164                case 2: // set
6165                    if (this.product.id == id)
6166                    {
6167                        this.setCompared(false);
6168                    }
6169
6170                    break;
6171                case 3: // sku
6172                    var i = this.offers.length;
6173                    while (i--)
6174                    {
6175                        if (this.offers[i].ID == id)
6176                        {
6177                            this.offers[i].COMPARED = false;
6178
6179                            if (this.offerNum == i)
6180                            {
6181                                this.setCompared(false);
6182                            }
6183
6184                            break;
6185                        }
6186                    }
6187            }
6188        },
6189
6190        initBasketUrl: function()
6191        {
6192            this.basketUrl = (this.basketMode === 'ADD' ? this.basketData.add_url : this.basketData.buy_url);
6193            switch (this.productType)
6194            {
6195                case 1: // product
6196                case 2: // set
6197                    this.basketUrl = this.basketUrl.replace('#ID#', this.product.id.toString());
6198                    break;
6199                case 3: // sku
6200                    this.basketUrl = this.basketUrl.replace('#ID#', this.offers[this.offerNum].ID);
6201                    break;
6202            }
6203            this.basketParams = {
6204                'ajax_basket': 'Y'
6205            };
6206            if (this.showQuantity)
6207            {
6208                this.basketParams[this.basketData.quantity] = this.obQuantity.value;
6209            }
6210            if (this.basketData.sku_props)
6211            {
6212                this.basketParams[this.basketData.sku_props_var] = this.basketData.sku_props;
6213            }
6214        },
6215
6216        fillBasketProps: function()
6217        {
6218            if (!this.visual.BASKET_PROP_DIV)
6219            {
6220                return;
6221            }
6222            var
6223                i = 0,
6224                propCollection = null,
6225                foundValues = false,
6226                obBasketProps = null;
6227
6228            if (this.basketData.useProps && !this.basketData.emptyProps)
6229            {
6230                if (this.obPopupWin && this.obPopupWin.contentContainer)
6231                {
6232                    obBasketProps = this.obPopupWin.contentContainer;
6233                }
6234            }
6235            else
6236            {
6237                obBasketProps = BX(this.visual.BASKET_PROP_DIV);
6238            }
6239            if (obBasketProps)
6240            {
6241                propCollection = obBasketProps.getElementsByTagName('select');
6242                if (propCollection && propCollection.length)
6243                {
6244                    for (i = 0; i < propCollection.length; i++)
6245                    {
6246                        if (!propCollection[i].disabled)
6247                        {
6248                            switch (propCollection[i].type.toLowerCase())
6249                            {
6250                                case 'select-one':
6251                                    this.basketParams[propCollection[i].name] = propCollection[i].value;
6252                                    foundValues = true;
6253                                    break;
6254                                default:
6255                                    break;
6256                            }
6257                        }
6258                    }
6259                }
6260                propCollection = obBasketProps.getElementsByTagName('input');
6261                if (propCollection && propCollection.length)
6262                {
6263                    for (i = 0; i < propCollection.length; i++)
6264                    {
6265                        if (!propCollection[i].disabled)
6266                        {
6267                            switch (propCollection[i].type.toLowerCase())
6268                            {
6269                                case 'hidden':
6270                                    this.basketParams[propCollection[i].name] = propCollection[i].value;
6271                                    foundValues = true;
6272                                    break;
6273                                case 'radio':
6274                                    if (propCollection[i].checked)
6275                                    {
6276                                        this.basketParams[propCollection[i].name] = propCollection[i].value;
6277                                        foundValues = true;
6278                                    }
6279                                    break;
6280                                default:
6281                                    break;
6282                            }
6283                        }
6284                    }
6285                }
6286            }
6287            if (!foundValues)
6288            {
6289                this.basketParams[this.basketData.props] = [];
6290                this.basketParams[this.basketData.props][0] = 0;
6291            }
6292        },
6293
6294        add2Basket: function()
6295        {
6296            this.basketMode = 'ADD';
6297            this.basket();
6298        },
6299
6300        buyBasket: function()
6301        {
6302            this.basketMode = 'BUY';
6303            this.basket();
6304        },
6305
6306        sendToBasket: function()
6307        {
6308            if (!this.canBuy)
6309            {
6310                return;
6311            }
6312
6313            // check recommendation
6314            if (this.product && this.product.id && this.bigData)
6315            {
6316                this.rememberProductRecommendation();
6317            }
6318
6319            this.initBasketUrl();
6320            this.fillBasketProps();
6321            BX.ajax({
6322                method: 'POST',
6323                dataType: 'json',
6324                url: this.basketUrl,
6325                data: this.basketParams,
6326                onsuccess: BX.proxy(this.basketResult, this)
6327            });
6328        },
6329
6330        basket: function()
6331        {
6332            var contentBasketProps = '';
6333            if (!this.canBuy)
6334            {
6335                return;
6336            }
6337            switch (this.productType)
6338            {
6339                case 1: // product
6340                case 2: // set
6341                    if (this.basketData.useProps && !this.basketData.emptyProps)
6342                    {
6343                        this.initPopupWindow();
6344                        this.obPopupWin.setTitleBar(BX.message('TITLE_BASKET_PROPS'));
6345                        if (BX(this.visual.BASKET_PROP_DIV))
6346                        {
6347                            contentBasketProps = BX(this.visual.BASKET_PROP_DIV).innerHTML;
6348                        }
6349                        this.obPopupWin.setContent(contentBasketProps);
6350                        this.obPopupWin.setButtons([
6351                            new BasketButton({
6352                                text: BX.message('BTN_MESSAGE_SEND_PROPS'),
6353                                events: {
6354                                    click: BX.delegate(this.sendToBasket, this)
6355                                }
6356                            })
6357                        ]);
6358                        this.obPopupWin.show();
6359                    }
6360                    else
6361                    {
6362                        this.sendToBasket();
6363                    }
6364                    break;
6365                case 3: // sku
6366                    this.sendToBasket();
6367                    break;
6368            }
6369        },
6370
6371        basketResult: function(arResult)
6372        {
6373            var strContent = '',
6374                strPict = '',
6375                successful,
6376                buttons = [];
6377
6378            if (this.obPopupWin)
6379                this.obPopupWin.close();
6380
6381            if (!BX.type.isPlainObject(arResult))
6382                return;
6383
6384            successful = arResult.STATUS === 'OK';
6385
6386            if (successful)
6387            {
6388                this.setAnalyticsDataLayer('addToCart');
6389            }
6390
6391            if (successful && this.basketAction === 'BUY')
6392            {
6393                this.basketRedirect();
6394            }
6395            else
6396            {
6397                this.initPopupWindow();
6398
6399                if (successful)
6400                {
6401                    BX.onCustomEvent('OnBasketChange');
6402
6403                    if  (BX.findParent(this.obProduct, {className: 'bx_sale_gift_main_products'}, 10))
6404                    {
6405                        BX.onCustomEvent('onAddToBasketMainProduct', [this]);
6406                    }
6407
6408                    switch (this.productType)
6409                    {
6410                        case 1: // product
6411                        case 2: // set
6412                            strPict = this.product.pict.SRC;
6413                            break;
6414                        case 3: // sku
6415                            strPict = (this.offers[this.offerNum].PREVIEW_PICTURE ?
6416                                    this.offers[this.offerNum].PREVIEW_PICTURE.SRC :
6417                                    this.defaultPict.pict.SRC
6418                            );
6419                            break;
6420                    }
6421
6422                    strContent = '<div style="width: 100%; margin: 0; text-align: center;"><img src="'
6423                        + strPict + '" height="130" style="max-height:130px"><p>' + this.product.name + '</p></div>';
6424
6425                    if (this.showClosePopup)
6426                    {
6427                        buttons = [
6428                            new BasketButton({
6429                                text: BX.message("BTN_MESSAGE_BASKET_REDIRECT"),
6430                                events: {
6431                                    click: BX.delegate(this.basketRedirect, this)
6432                                },
6433                                style: {marginRight: '10px'}
6434                            }),
6435                            new BasketButton({
6436                                text: BX.message("BTN_MESSAGE_CLOSE_POPUP"),
6437                                events: {
6438                                    click: BX.delegate(this.obPopupWin.close, this.obPopupWin)
6439                                }
6440                            })
6441                        ];
6442                    }
6443                    else
6444                    {
6445                        buttons = [
6446                            new BasketButton({
6447                                text: BX.message("BTN_MESSAGE_BASKET_REDIRECT"),
6448                                events: {
6449                                    click: BX.delegate(this.basketRedirect, this)
6450                                }
6451                            })
6452                        ];
6453                    }
6454                }
6455                else
6456                {
6457                    strContent = '<div style="width: 100%; margin: 0; text-align: center;"><p>'
6458                        + (arResult.MESSAGE ? arResult.MESSAGE : BX.message('BASKET_UNKNOWN_ERROR'))
6459                        + '</p></div>';
6460                    buttons = [
6461                        new BasketButton({
6462                            text: BX.message('BTN_MESSAGE_CLOSE'),
6463                            events: {
6464                                click: BX.delegate(this.obPopupWin.close, this.obPopupWin)
6465                            }
6466                        })
6467                    ];
6468                }
6469                this.obPopupWin.setTitleBar(successful ? BX.message('TITLE_SUCCESSFUL') : BX.message('TITLE_ERROR'));
6470                this.obPopupWin.setContent(strContent);
6471                this.obPopupWin.setButtons(buttons);
6472                this.obPopupWin.show();
6473            }
6474        },
6475
6476        basketRedirect: function()
6477        {
6478            location.href = (this.basketData.basketUrl ? this.basketData.basketUrl : BX.message('BASKET_URL'));
6479        },
6480
6481        initPopupWindow: function()
6482        {
6483            if (this.obPopupWin)
6484                return;
6485
6486            this.obPopupWin = BX.PopupWindowManager.create('CatalogSectionBasket_' + this.visual.ID, null, {
6487                autoHide: true,
6488                offsetLeft: 0,
6489                offsetTop: 0,
6490                overlay : true,
6491                closeByEsc: true,
6492                titleBar: true,
6493                closeIcon: true,
6494                contentColor: 'white',
6495                className: this.templateTheme ? 'bx-' + this.templateTheme : ''
6496            });
6497        }
6498    };
6499})(window);
6500/* End */
6501;; /* /local/templates/bitrix66/components/bitrix/sale.basket.basket/basket/js/action-pool.js?17913091655918*/
6502; /* /local/templates/bitrix66/components/bitrix/sale.basket.basket/basket/js/filter.js?179130916514092*/
6503; /* /local/templates/bitrix66/components/bitrix/sale.basket.basket/basket/js/component.js?179136621270831*/
6504; /* /bitrix/components/bitrix/sale.products.gift.basket/templates/.default/script.js?17726179854796*/
6505; /* /local/templates/bitrix66/components/bitrix/catalog.item/.default/script.js?178953951698344*/

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.