PageSourceSearch

https://tt25.ru/bitrix/templates/aspro_optimus/components/bitrix/c…alog.bigdata.products/optimus_new/script.js

js tt25.ru collected 2026-09-26 10:30:32 UTC 35,971 bytes, 1,523 lines download raw bytes

1(function (window) {
2
3if (!!window.JCCatalogBigdataProducts)
4{
5	return;
6}
7
8var BasketButton = function(params)
9{
10	BasketButton.superclass.constructor.apply(this, arguments);
11	this.nameNode = BX.create('span', {
12		props : { className : 'bx_medium bx_bt_button', id : this.id },
13		text: params.text
14	});
15	this.buttonNode = BX.create('span', {
16		attrs: { className: params.ownerClass },
17		style: { marginBottom: '0', borderBottom: '0 none transparent' },
18		children: [this.nameNode],
19		events : this.contextEvents
20	});
21	if (BX.browser.IsIE())
22	{
23		this.buttonNode.setAttribute("hideFocus", "hidefocus");
24	}
25};
26BX.extend(BasketButton, BX.PopupWindowButton);
27
28window.JCCatalogBigdataProducts = function (arParams)
29{
30	this.productType = 0;
31	this.showQuantity = true;
32	this.showAbsent = true;
33	this.secondPict = false;
34	this.showOldPrice = false;
35	this.showPercent = false;
36	this.showSkuProps = false;
37	this.visual = {
38		ID: '',
39		PICT_ID: '',
40		SECOND_PICT_ID: '',
41		QUANTITY_ID: '',
42		QUANTITY_UP_ID: '',
43		QUANTITY_DOWN_ID: '',
44		PRICE_ID: '',
45		DSC_PERC: '',
46		SECOND_DSC_PERC: '',
47		DISPLAY_PROP_DIV: '',
48		BASKET_PROP_DIV: ''
49	};
50	this.product = {
51		checkQuantity: false,
52		maxQuantity: 0,
53		stepQuantity: 1,
54		isDblQuantity: false,
55		canBuy: true,
56		canSubscription: true,
57		name: '',
58		pict: {},
59		id: 0,
60		addUrl: '',
61		buyUrl: ''
62	};
63	this.basketData = {
64		useProps: false,
65		emptyProps: false,
66		quantity: 'quantity',
67		props: 'prop',
68		basketUrl: ''
69	};
70
71	this.defaultPict = {
72		pict: null,
73		secondPict: null
74	};
75
76	this.checkQuantity = false;
77	this.maxQuantity = 0;
78	this.stepQuantity = 1;
79	this.isDblQuantity = false;
80	this.canBuy = true;
81	this.canSubscription = true;
82	this.precision = 6;
83	this.precisionFactor = Math.pow(10,this.precision);
84
85	this.offers = [];
86	this.offerNum = 0;
87	this.treeProps = [];
88	this.obTreeRows = [];
89	this.showCount = [];
90	this.showStart = [];
91	this.selectedValues = {};
92
93	this.obProduct = null;
94	this.obQuantity = null;
95	this.obQuantityUp = null;
96	this.obQuantityDown = null;
97	this.obPict = null;
98	this.obSecondPict = null;
99	this.obPrice = null;
100	this.obTree = null;
101	this.obBuyBtn = null;
102	this.obDscPerc = null;
103	this.obSecondDscPerc = null;
104	this.obSkuProps = null;
105	this.obMeasure = null;
106
107	this.obPopupWin = null;
108	this.basketUrl = '';
109	this.basketParams = {};
110
111	this.treeRowShowSize = 5;
112	this.treeEnableArrow = { display: '', cursor: 'pointer', opacity: 1 };
113	this.treeDisableArrow = { display: '', cursor: 'default', opacity:0.2 };
114
115	this.lastElement = false;
116	this.containerHeight = 0;
117
118	this.errorCode = 0;
119
120	if ('object' === typeof arParams)
121	{
122		this.productType = parseInt(arParams.PRODUCT_TYPE, 10);
123		this.showQuantity = arParams.SHOW_QUANTITY;
124		this.showAbsent = arParams.SHOW_ABSENT;
125		this.secondPict = !!arParams.SECOND_PICT;
126		this.showOldPrice = !!arParams.SHOW_OLD_PRICE;
127		this.showPercent = !!arParams.SHOW_DISCOUNT_PERCENT;
128		this.showSkuProps = !!arParams.SHOW_SKU_PROPS;
129
130		this.visual = arParams.VISUAL;
131		switch (this.productType)
132		{
133			case 1://product
134			case 2://set
135				if (!!arParams.PRODUCT && 'object' === typeof(arParams.PRODUCT))
136				{
137					if (this.showQuantity)
138					{
139						this.product.checkQuantity = arParams.PRODUCT.CHECK_QUANTITY;
140						this.product.isDblQuantity = arParams.PRODUCT.QUANTITY_FLOAT;
141						if (this.product.checkQuantity)
142						{
143							this.product.maxQuantity = (this.product.isDblQuantity ? parseFloat(arParams.PRODUCT.MAX_QUANTITY) : parseInt(arParams.PRODUCT.MAX_QUANTITY, 10));
144						}
145						this.product.stepQuantity = (this.product.isDblQuantity ? parseFloat(arParams.PRODUCT.STEP_QUANTITY) : parseInt(arParams.PRODUCT.STEP_QUANTITY, 10));
146
147						this.checkQuantity = this.product.checkQuantity;
148						this.isDblQuantity = this.product.isDblQuantity;
149						this.maxQuantity = this.product.maxQuantity;
150						this.stepQuantity = this.product.stepQuantity;
151						if (this.isDblQuantity)
152						{
153							this.stepQuantity = Math.round(this.stepQuantity*this.precisionFactor)/this.precisionFactor;
154						}
155					}
156					this.product.canBuy = arParams.PRODUCT.CAN_BUY;
157					this.product.canSubscription = arParams.PRODUCT.SUBSCRIPTION;
158
159					this.canBuy = this.product.canBuy;
160					this.canSubscription = this.product.canSubscription;
161
162					this.product.name = arParams.PRODUCT.NAME;
163					this.product.pict = arParams.PRODUCT.PICT;
164					this.product.id = arParams.PRODUCT.ID;
165					if (!!arParams.PRODUCT.ADD_URL)
166					{
167						this.product.addUrl = arParams.PRODUCT.ADD_URL;
168					}
169					if (!!arParams.PRODUCT.BUY_URL)
170					{
171						this.product.buyUrl = arParams.PRODUCT.BUY_URL;
172					}
173					if (!!arParams.BASKET && 'object' === typeof(arParams.BASKET))
174					{
175						this.basketData.useProps = !!arParams.BASKET.ADD_PROPS;
176						this.basketData.emptyProps = !!arParams.BASKET.EMPTY_PROPS;
177					}
178				}
179				else
180				{
181					this.errorCode = -1;
182				}
183				break;
184			case 3://sku
185				if (!!arParams.OFFERS && BX.type.isArray(arParams.OFFERS))
186				{
187					if (!!arParams.PRODUCT && 'object' === typeof(arParams.PRODUCT))
188					{
189						this.product.name = arParams.PRODUCT.NAME;
190						this.product.id = arParams.PRODUCT.ID;
191					}
192					this.offers = arParams.OFFERS;
193					this.offerNum = 0;
194					if (!!arParams.OFFER_SELECTED)
195					{
196						this.offerNum = parseInt(arParams.OFFER_SELECTED, 10);
197					}
198					if (isNaN(this.offerNum))
199					{
200						this.offerNum = 0;
201					}
202					if (!!arParams.TREE_PROPS)
203					{
204						this.treeProps = arParams.TREE_PROPS;
205					}
206					if (!!arParams.DEFAULT_PICTURE)
207					{
208						this.defaultPict.pict = arParams.DEFAULT_PICTURE.PICTURE;
209						this.defaultPict.secondPict = arParams.DEFAULT_PICTURE.PICTURE_SECOND;
210					}
211				}
212				else
213				{
214					this.errorCode = -1;
215				}
216				break;
217			default:
218				this.errorCode = -1;
219		}
220		if (!!arParams.BASKET && 'object' === typeof(arParams.BASKET))
221		{
222			if (!!arParams.BASKET.QUANTITY)
223			{
224				this.basketData.quantity = arParams.BASKET.QUANTITY;
225			}
226			if (!!arParams.BASKET.PROPS)
227			{
228				this.basketData.props = arParams.BASKET.PROPS;
229			}
230			if (!!arParams.BASKET.BASKET_URL)
231			{
232				this.basketData.basketUrl = arParams.BASKET.BASKET_URL;
233			}
234		}
235		this.lastElement = (!!arParams.LAST_ELEMENT && 'Y' === arParams.LAST_ELEMENT);
236	}
237	if (0 === this.errorCode)
238	{
239		BX.ready(BX.delegate(this.Init,this));
240	}
241};
242
243window.JCCatalogBigdataProducts.prototype.Init = function()
244{
245	var i = 0,
246		strPrefix = '',
247		TreeItems = null;
248
249	this.obProduct = BX(this.visual.ID);
250	if (!this.obProduct)
251	{
252		this.errorCode = -1;
253	}
254	this.obPict = BX(this.visual.PICT_ID);
255	if (!this.obPict)
256	{
257		this.errorCode = -2;
258	}
259	if (this.secondPict && !!this.visual.SECOND_PICT_ID)
260	{
261		this.obSecondPict = BX(this.visual.SECOND_PICT_ID);
262	}
263	this.obPrice = BX(this.visual.PRICE_ID);
264	if (!this.obPrice)
265	{
266		this.errorCode = -16;
267	}
268	if (this.showQuantity && !!this.visual.QUANTITY_ID)
269	{
270		this.obQuantity = BX(this.visual.QUANTITY_ID);
271		if (!!this.visual.QUANTITY_UP_ID)
272		{
273			this.obQuantityUp = BX(this.visual.QUANTITY_UP_ID);
274		}
275		if (!!this.visual.QUANTITY_DOWN_ID)
276		{
277			this.obQuantityDown = BX(this.visual.QUANTITY_DOWN_ID);
278		}
279	}
280	if (3 === this.productType)
281	{
282		if (!!this.visual.TREE_ID)
283		{
284			this.obTree = BX(this.visual.TREE_ID);
285			if (!this.obTree)
286			{
287				this.errorCode = -256;
288			}
289			strPrefix = this.visual.TREE_ITEM_ID;
290			for (i = 0; i < this.treeProps.length; i++)
291			{
292				this.obTreeRows[i] = {
293					LEFT: BX(strPrefix+this.treeProps[i].ID+'_left'),
294					RIGHT: BX(strPrefix+this.treeProps[i].ID+'_right'),
295					LIST: BX(strPrefix+this.treeProps[i].ID+'_list'),
296					CONT: BX(strPrefix+this.treeProps[i].ID+'_cont')
297				};
298				if (!this.obTreeRows[i].LEFT || !this.obTreeRows[i].RIGHT || !this.obTreeRows[i].LIST || !this.obTreeRows[i].CONT)
299				{
300					this.errorCode = -512;
301					break;
302				}
303			}
304		}
305		if (!!this.visual.QUANTITY_MEASURE)
306		{
307			this.obMeasure = BX(this.visual.QUANTITY_MEASURE);
308		}
309	}
310	if (!!this.visual.BUY_ID)
311	{
312		this.obBuyBtn = BX(this.visual.BUY_ID);
313	}
314
315	if (this.showPercent)
316	{
317		if (!!this.visual.DSC_PERC)
318		{
319			this.obDscPerc = BX(this.visual.DSC_PERC);
320		}
321		if (this.secondPict && !!this.visual.SECOND_DSC_PERC)
322		{
323			this.obSecondDscPerc = BX(this.visual.SECOND_DSC_PERC);
324		}
325	}
326
327	if (this.showSkuProps)
328	{
329		if (!!this.visual.DISPLAY_PROP_DIV)
330		{
331			this.obSkuProps = BX(this.visual.DISPLAY_PROP_DIV);
332		}
333	}
334
335	if (0 === this.errorCode)
336	{
337		if (this.showQuantity)
338		{
339			if (!!this.obQuantityUp)
340			{
341				BX.bind(this.obQuantityUp, 'click', BX.delegate(this.QuantityUp, this));
342			}
343			if (!!this.obQuantityDown)
344			{
345				BX.bind(this.obQuantityDown, 'click', BX.delegate(this.QuantityDown, this));
346			}
347			if (!!this.obQuantity)
348			{
349				BX.bind(this.obQuantity, 'change', BX.delegate(this.QuantityChange, this));
350			}
351		}
352		switch (this.productType)
353		{
354			case 1://product
355				break;
356			case 3://sku
357				TreeItems = BX.findChildren(this.obTree, {tagName: 'li'}, true);
358				if (!!TreeItems && 0 < TreeItems.length)
359				{
360					for (i = 0; i < TreeItems.length; i++)
361					{
362						BX.bind(TreeItems[i], 'click', BX.delegate(this.SelectOfferProp, this));
363					}
364				}
365				for (i = 0; i < this.obTreeRows.length; i++)
366				{
367					BX.bind(this.obTreeRows[i].LEFT, 'click', BX.delegate(this.RowLeft, this));
368					BX.bind(this.obTreeRows[i].RIGHT, 'click', BX.delegate(this.RowRight, this));
369				}
370				this.SetCurrent();
371				break;
372		}
373		if (!!this.obBuyBtn)
374		{
375			BX.bind(this.obBuyBtn, 'click', BX.delegate(this.Basket, this));
376		}
377		if (this.lastElement)
378		{
379			this.containerHeight = parseInt(this.obProduct.parentNode.offsetHeight, 10);
380			if (isNaN(this.containerHeight))
381			{
382				this.containerHeight = 0;
383			}
384			this.setHeight();
385			BX.bind(window, 'resize', BX.delegate(this.checkHeight, this));
386			BX.bind(this.obProduct.parentNode, 'mouseover', BX.delegate(this.setHeight, this));
387			BX.bind(this.obProduct.parentNode, 'mouseout', BX.delegate(this.clearHeight, this));
388		}
389	}
390};
391
392window.JCCatalogBigdataProducts.prototype.checkHeight = function()
393{
394	this.containerHeight = parseInt(this.obProduct.parentNode.offsetHeight, 10);
395	if (isNaN(this.containerHeight))
396	{
397		this.containerHeight = 0;
398	}
399};
400
401window.JCCatalogBigdataProducts.prototype.setHeight = function()
402{
403	if (0 < this.containerHeight)
404	{
405		BX.adjust(this.obProduct.parentNode, {style: { height: this.containerHeight+'px'}});
406	}
407};
408
409window.JCCatalogBigdataProducts.prototype.clearHeight = function()
410{
411	BX.adjust(this.obProduct.parentNode, {style: { height: 'auto'}});
412};
413
414window.JCCatalogBigdataProducts.prototype.QuantityUp = function()
415{
416	var curValue = 0,
417		boolSet = true;
418
419	if (0 === this.errorCode && this.showQuantity && this.canBuy)
420	{
421		curValue = (this.isDblQuantity ? parseFloat(this.obQuantity.value) : parseInt(this.obQuantity.value, 10));
422		if (!isNaN(curValue))
423		{
424			curValue += this.stepQuantity;
425			if (this.checkQuantity)
426			{
427				if (curValue > this.maxQuantity)
428				{
429					boolSet = false;
430				}
431			}
432			if (boolSet)
433			{
434				if (this.isDblQuantity)
435				{
436					curValue = Math.round(curValue*this.precisionFactor)/this.precisionFactor;
437				}
438				this.obQuantity.value = curValue;
439			}
440		}
441	}
442};
443
444window.JCCatalogBigdataProducts.prototype.QuantityDown = function()
445{
446	var curValue = 0,
447		boolSet = true;
448
449	if (0 === this.errorCode && this.showQuantity && this.canBuy)
450	{
451		curValue = (this.isDblQuantity ? parseFloat(this.obQuantity.value): parseInt(this.obQuantity.value, 10));
452		if (!isNaN(curValue))
453		{
454			curValue -= this.stepQuantity;
455			if (curValue < this.stepQuantity)
456			{
457				boolSet = false;
458			}
459			if (boolSet)
460			{
461				if (this.isDblQuantity)
462				{
463					curValue = Math.round(curValue*this.precisionFactor)/this.precisionFactor;
464				}
465				this.obQuantity.value = curValue;
466			}
467		}
468	}
469};
470
471window.JCCatalogBigdataProducts.prototype.QuantityChange = function()
472{
473	var curValue = 0,
474		boolSet = true;
475
476	if (0 === this.errorCode && this.showQuantity)
477	{
478		if (this.canBuy)
479		{
480			curValue = (this.isDblQuantity ? parseFloat(this.obQuantity.value) : parseInt(this.obQuantity.value, 10));
481			if (!isNaN(curValue))
482			{
483				if (this.checkQuantity)
484				{
485					if (curValue > this.maxQuantity)
486					{
487						boolSet = false;
488						curValue = this.maxQuantity;
489					}
490					else if (curValue < this.stepQuantity)
491					{
492						boolSet = false;
493						curValue = this.stepQuantity;
494					}
495				}
496				if (!boolSet)
497				{
498					this.obQuantity.value = curValue;
499				}
500			}
501			else
502			{
503				this.obQuantity.value = this.stepQuantity;
504			}
505		}
506		else
507		{
508			this.obQuantity.value = this.stepQuantity;
509		}
510	}
511};
512
513window.JCCatalogBigdataProducts.prototype.QuantitySet = function(index)
514{
515	if (0 === this.errorCode)
516	{
517		this.canBuy = this.offers[index].CAN_BUY;
518		if (this.canBuy)
519		{
520			BX.addClass(this.obBuyBtn, 'bx_bt_button');
521			BX.removeClass(this.obBuyBtn, 'bx_bt_button_type_2');
522			this.obBuyBtn.innerHTML = BX.message('CBD_MESS_BTN_BUY');
523		}
524		else
525		{
526			BX.addClass(this.obBuyBtn, 'bx_bt_button_type_2');
527			BX.removeClass(this.obBuyBtn, 'bx_bt_button');
528			this.obBuyBtn.innerHTML = BX.message('CBD_MESS_NOT_AVAILABLE');
529		}
530		if (this.showQuantity)
531		{
532			this.isDblQuantity = this.offers[index].QUANTITY_FLOAT;
533			this.checkQuantity = this.offers[index].CHECK_QUANTITY;
534			if (this.isDblQuantity)
535			{
536				this.maxQuantity = parseFloat(this.offers[index].MAX_QUANTITY);
537				this.stepQuantity = Math.round(parseFloat(this.offers[index].STEP_QUANTITY)*this.precisionFactor)/this.precisionFactor;
538			}
539			else
540			{
541				this.maxQuantity = parseInt(this.offers[index].MAX_QUANTITY, 10);
542				this.stepQuantity = parseInt(this.offers[index].STEP_QUANTITY, 10);
543			}
544
545			this.obQuantity.value = this.stepQuantity;
546			this.obQuantity.disabled = !this.canBuy;
547			if (!!this.obMeasure)
548			{
549				if (!!this.offers[index].MEASURE)
550				{
551					BX.adjust(this.obMeasure, { html : this.offers[index].MEASURE});
552				}
553				else
554				{
555					BX.adjust(this.obMeasure, { html : ''});
556				}
557			}
558		}
559	}
560};
561
562window.JCCatalogBigdataProducts.prototype.SelectOfferProp = function()
563{
564	var i = 0,
565		value = '',
566		strTreeValue = '',
567		arTreeItem = [],
568		RowItems = null,
569		target = BX.proxy_context;
570
571	if (!!target && target.hasAttribute('data-treevalue'))
572	{
573		strTreeValue = target.getAttribute('data-treevalue');
574		arTreeItem = strTreeValue.split('_');
575		if (this.SearchOfferPropIndex(arTreeItem[0], arTreeItem[1]))
576		{
577			RowItems = BX.findChildren(target.parentNode, {tagName: 'li'}, false);
578			if (!!RowItems && 0 < RowItems.length)
579			{
580				for (i = 0; i < RowItems.length; i++)
581				{
582					value = RowItems[i].getAttribute('data-onevalue');
583					if (value === arTreeItem[1])
584					{
585						BX.addClass(RowItems[i], 'bx_active');
586					}
587					else
588					{
589						BX.removeClass(RowItems[i], 'bx_active');
590					}
591				}
592			}
593		}
594	}
595};
596
597window.JCCatalogBigdataProducts.prototype.SearchOfferPropIndex = function(strPropID, strPropValue)
598{
599	var strName = '',
600		arShowValues = false,
601		i, j,
602		arCanBuyValues = [],
603		index = -1,
604		arFilter = {},
605		tmpFilter = [];
606
607	for (i = 0; i < this.treeProps.length; i++)
608	{
609		if (this.treeProps[i].ID === strPropID)
610		{
611			index = i;
612			break;
613		}
614	}
615
616	if (-1 < index)
617	{
618		for (i = 0; i < index; i++)
619		{
620			strName = 'PROP_'+this.treeProps[i].ID;
621			arFilter[strName] = this.selectedValues[strName];
622		}
623		strName = 'PROP_'+this.treeProps[index].ID;
624		arShowValues = this.GetRowValues(arFilter, strName);
625		if (!arShowValues)
626		{
627			return false;
628		}
629		if (!BX.util.in_array(strPropValue, arShowValues))
630		{
631			return false;
632		}
633		arFilter[strName] = strPropValue;
634		for (i = index+1; i < this.treeProps.length; i++)
635		{
636			strName = 'PROP_'+this.treeProps[i].ID;
637			arShowValues = this.GetRowValues(arFilter, strName);
638			if (!arShowValues)
639			{
640				return false;
641			}
642			if (this.showAbsent)
643			{
644				arCanBuyValues = [];
645				tmpFilter = [];
646				tmpFilter = BX.clone(arFilter, true);
647				for (j = 0; j < arShowValues.length; j++)
648				{
649					tmpFilter[strName] = arShowValues[j];
650					if (this.GetCanBuy(tmpFilter))
651					{
652						arCanBuyValues[arCanBuyValues.length] = arShowValues[j];
653					}
654				}
655			}
656			else
657			{
658				arCanBuyValues = arShowValues;
659			}
660			if (!!this.selectedValues[strName] && BX.util.in_array(this.selectedValues[strName], arCanBuyValues))
661			{
662				arFilter[strName] = this.selectedValues[strName];
663			}
664			else
665			{
666				arFilter[strName] = arCanBuyValues[0];
667			}
668			this.UpdateRow(i, arFilter[strName], arShowValues, arCanBuyValues);
669		}
670		this.selectedValues = arFilter;
671		this.ChangeInfo();
672	}
673	return true;
674};
675
676window.JCCatalogBigdataProducts.prototype.RowLeft = function()
677{
678	var i = 0,
679		strTreeValue = '',
680		index = -1,
681		target = BX.proxy_context;
682
683	if (!!target && target.hasAttribute('data-treevalue'))
684	{
685		strTreeValue = target.getAttribute('data-treevalue');
686		for (i = 0; i < this.treeProps.length; i++)
687		{
688			if (this.treeProps[i].ID === strTreeValue)
689			{
690				index = i;
691				break;
692			}
693		}
694		if (-1 < index && this.treeRowShowSize < this.showCount[index])
695		{
696			if (0 > this.showStart[index])
697			{
698				this.showStart[index]++;
699				BX.adjust(this.obTreeRows[index].LIST, { style: { marginLeft: this.showStart[index]*20+'%' }});
700				BX.adjust(this.obTreeRows[index].RIGHT, { style: this.treeEnableArrow });
701			}
702
703			if (0 <= this.showStart[index])
704			{
705				BX.adjust(this.obTreeRows[index].LEFT, { style: this.treeDisableArrow });
706			}
707		}
708	}
709};
710
711window.JCCatalogBigdataProducts.prototype.RowRight = function()
712{
713	var i = 0,
714		strTreeValue = '',
715		index = -1,
716		target = BX.proxy_context;
717
718	if (!!target && target.hasAttribute('data-treevalue'))
719	{
720		strTreeValue = target.getAttribute('data-treevalue');
721		for (i = 0; i < this.treeProps.length; i++)
722		{
723			if (this.treeProps[i].ID === strTreeValue)
724			{
725				index = i;
726				break;
727			}
728		}
729		if (-1 < index && this.treeRowShowSize < this.showCount[index])
730		{
731			if ((this.treeRowShowSize - this.showStart[index]) < this.showCount[index])
732			{
733				this.showStart[index]--;
734				BX.adjust(this.obTreeRows[index].LIST, { style: { marginLeft: this.showStart[index]*20+'%' }});
735				BX.adjust(this.obTreeRows[index].LEFT, { style: this.treeEnableArrow });
736			}
737
738			if ((this.treeRowShowSize - this.showStart[index]) >= this.showCount[index])
739			{
740				BX.adjust(this.obTreeRows[index].RIGHT, { style: this.treeDisableArrow });
741			}
742		}
743	}
744};
745
746window.JCCatalogBigdataProducts.prototype.UpdateRow = function(intNumber, activeID, showID, canBuyID)
747{
748	var i = 0,
749		showI = 0,
750		value = '',
751		countShow = 0,
752		strNewLen = '',
753		obData = {},
754		pictMode = false,
755		extShowMode = false,
756		isCurrent = false,
757		selectIndex = 0,
758		obLeft = this.treeEnableArrow,
759		obRight = this.treeEnableArrow,
760		currentShowStart = 0,
761		RowItems = null;
762
763	if (-1 < intNumber && intNumber < this.obTreeRows.length)
764	{
765		RowItems = BX.findChildren(this.obTreeRows[intNumber].LIST, {tagName: 'li'}, false);
766		if (!!RowItems && 0 < RowItems.length)
767		{
768			pictMode = ('PICT' === this.treeProps[intNumber].SHOW_MODE);
769			countShow = showID.length;
770			extShowMode = this.treeRowShowSize < countShow;
771			strNewLen = (extShowMode ? (100/countShow)+'%' : '20%');
772			obData = {
773				props: { className: '' },
774				style: {
775					width: strNewLen
776				}
777			};
778			if (pictMode)
779			{
780				obData.style.paddingTop = strNewLen;
781			}
782			for (i = 0; i < RowItems.length; i++)
783			{
784				value = RowItems[i].getAttribute('data-onevalue');
785				isCurrent = (value === activeID);
786				if (BX.util.in_array(value, canBuyID))
787				{
788					obData.props.className = (isCurrent ? 'bx_active' : '');
789				}
790				else
791				{
792					obData.props.className = (isCurrent ? 'bx_active bx_missing' : 'bx_missing');
793				}
794				obData.style.display = 'none';
795				if (BX.util.in_array(value, showID))
796				{
797					obData.style.display = '';
798					if (isCurrent)
799					{
800						selectIndex = showI;
801					}
802					showI++;
803				}
804				BX.adjust(RowItems[i], obData);
805			}
806
807			obData = {
808				style: {
809					width: (extShowMode ? 20*countShow : 100)+'%',
810					marginLeft: '0%'
811				}
812			};
813			if (pictMode)
814			{
815				BX.adjust(this.obTreeRows[intNumber].CONT, {props: {className: (extShowMode ? 'bx_item_detail_scu full' : 'bx_item_detail_scu')}});
816			}
817			else
818			{
819				BX.adjust(this.obTreeRows[intNumber].CONT, {props: {className: (extShowMode ? 'bx_item_detail_size full' : 'bx_item_detail_size')}});
820			}
821			if (extShowMode)
822			{
823				if (selectIndex +1 === countShow)
824				{
825					obRight = this.treeDisableArrow;
826				}
827				if (this.treeRowShowSize <= selectIndex)
828				{
829					currentShowStart = this.treeRowShowSize - selectIndex - 1;
830					obData.style.marginLeft = currentShowStart*20+'%';
831				}
832				if (0 === currentShowStart)
833				{
834					obLeft = this.treeDisableArrow;
835				}
836				BX.adjust(this.obTreeRows[intNumber].LEFT, {style: obLeft });
837				BX.adjust(this.obTreeRows[intNumber].RIGHT, {style: obRight });
838			}
839			else
840			{
841				BX.adjust(this.obTreeRows[intNumber].LEFT, {style: {display: 'none'}});
842				BX.adjust(this.obTreeRows[intNumber].RIGHT, {style: {display: 'none'}});
843			}
844			BX.adjust(this.obTreeRows[intNumber].LIST, obData);
845			this.showCount[intNumber] = countShow;
846			this.showStart[intNumber] = currentShowStart;
847		}
848	}
849};
850
851window.JCCatalogBigdataProducts.prototype.GetRowValues = function(arFilter, index)
852{
853	var i = 0,
854		j,
855		arValues = [],
856		boolSearch = false,
857		boolOneSearch = true;
858
859	if (0 === arFilter.length)
860	{
861		for (i = 0; i < this.offers.length; i++)
862		{
863			if (!BX.util.in_array(this.offers[i].TREE[index], arValues))
864			{
865				arValues[arValues.length] = this.offers[i].TREE[index];
866			}
867		}
868		boolSearch = true;
869	}
870	else
871	{
872		for (i = 0; i < this.offers.length; i++)
873		{
874			boolOneSearch = true;
875			for (j in arFilter)
876			{
877				if (arFilter[j] !== this.offers[i].TREE[j])
878				{
879					boolOneSearch = false;
880					break;
881				}
882			}
883			if (boolOneSearch)
884			{
885				if (!BX.util.in_array(this.offers[i].TREE[index], arValues))
886				{
887					arValues[arValues.length] = this.offers[i].TREE[index];
888				}
889				boolSearch = true;
890			}
891		}
892	}
893	return (boolSearch ? arValues : false);
894};
895
896window.JCCatalogBigdataProducts.prototype.GetCanBuy = function(arFilter)
897{
898	var i = 0,
899		j,
900		boolSearch = false,
901		boolOneSearch = true;
902
903	for (i = 0; i < this.offers.length; i++)
904	{
905		boolOneSearch = true;
906		for (j in arFilter)
907		{
908			if (arFilter[j] !== this.offers[i].TREE[j])
909			{
910				boolOneSearch = false;
911				break;
912			}
913		}
914		if (boolOneSearch)
915		{
916			if (this.offers[i].CAN_BUY)
917			{
918				boolSearch = true;
919				break;
920			}
921		}
922	}
923	return boolSearch;
924};
925
926window.JCCatalogBigdataProducts.prototype.SetCurrent = function()
927{
928	var i = 0,
929		j = 0,
930		arCanBuyValues = [],
931		strName = '',
932		arShowValues = false,
933		arFilter = {},
934		tmpFilter = [],
935		current = this.offers[this.offerNum].TREE;
936
937	for (i = 0; i < this.treeProps.length; i++)
938	{
939		strName = 'PROP_'+this.treeProps[i].ID;
940		arShowValues = this.GetRowValues(arFilter, strName);
941		if (!arShowValues)
942		{
943			break;
944		}
945		if (BX.util.in_array(current[strName], arShowValues))
946		{
947			arFilter[strName] = current[strName];
948		}
949		else
950		{
951			arFilter[strName] = arShowValues[0];
952			this.offerNum = 0;
953		}
954		if (this.showAbsent)
955		{
956			arCanBuyValues = [];
957			tmpFilter = [];
958			tmpFilter = BX.clone(arFilter, true);
959			for (j = 0; j < arShowValues.length; j++)
960			{
961				tmpFilter[strName] = arShowValues[j];
962				if (this.GetCanBuy(tmpFilter))
963				{
964					arCanBuyValues[arCanBuyValues.length] = arShowValues[j];
965				}
966			}
967		}
968		else
969		{
970			arCanBuyValues = arShowValues;
971		}
972		this.UpdateRow(i, arFilter[strName], arShowValues, arCanBuyValues);
973	}
974	this.selectedValues = arFilter;
975	this.ChangeInfo();
976};
977
978window.JCCatalogBigdataProducts.prototype.ChangeInfo = function()
979{
980	var i = 0,
981		j,
982		index = -1,
983		obData = {},
984		boolOneSearch = true,
985		strPrice = '';
986
987	for (i = 0; i < this.offers.length; i++)
988	{
989		boolOneSearch = true;
990		for (j in this.selectedValues)
991		{
992			if (this.selectedValues[j] !== this.offers[i].TREE[j])
993			{
994				boolOneSearch = false;
995				break;
996			}
997		}
998		if (boolOneSearch)
999		{
1000			index = i;
1001			break;
1002		}
1003	}
1004	if (-1 < index)
1005	{
1006		if (!!this.obPict)
1007		{
1008			if (!!this.offers[index].PREVIEW_PICTURE)
1009			{
1010				BX.adjust(this.obPict, {style: {backgroundImage: 'url('+this.offers[index].PREVIEW_PICTURE.SRC+')'}});
1011			}
1012			else
1013			{
1014				BX.adjust(this.obPict, {style: {backgroundImage: 'url('+this.defaultPict.pict.SRC+')'}});
1015			}
1016		}
1017		if (this.secondPict && !!this.obSecondPict)
1018		{
1019			if (!!this.offers[index].PREVIEW_PICTURE_SECOND)
1020			{
1021				BX.adjust(this.obSecondPict, {style: {backgroundImage: 'url('+this.offers[index].PREVIEW_PICTURE_SECOND.SRC+')'}});
1022			}
1023			else if (!!this.offers[index].PREVIEW_PICTURE.SRC)
1024			{
1025				BX.adjust(this.obSecondPict, {style: {backgroundImage: 'url('+this.offers[index].PREVIEW_PICTURE.SRC+')'}});
1026			}
1027			else if (!!this.defaultPict.secondPict)
1028			{
1029				BX.adjust(this.obSecondPict, {style: {backgroundImage: 'url('+this.defaultPict.secondPict.SRC+')'}});
1030			}
1031			else
1032			{
1033				BX.adjust(this.obSecondPict, {style: {backgroundImage: 'url('+this.defaultPict.pict.SRC+')'}});
1034			}
1035		}
1036		if (this.showSkuProps && !!this.obSkuProps)
1037		{
1038			if (0 === this.offers[index].DISPLAY_PROPERTIES.length)
1039			{
1040				BX.adjust(this.obSkuProps, {style: {display: 'none'}, html: ''});
1041			}
1042			else
1043			{
1044				BX.adjust(this.obSkuProps, {style: {display: ''}, html: this.offers[index].DISPLAY_PROPERTIES});
1045			}
1046		}
1047		if (!!this.obPrice)
1048		{
1049			strPrice = this.offers[index].PRICE.PRINT_DISCOUNT_VALUE;
1050			if (this.showOldPrice && (this.offers[index].PRICE.DISCOUNT_VALUE !== this.offers[index].PRICE.VALUE))
1051			{
1052				strPrice += ' <span>'+this.offers[index].PRICE.PRINT_VALUE+'</span>';
1053			}
1054			BX.adjust(this.obPrice, {html: strPrice});
1055			if (this.showPercent)
1056			{
1057				if (this.offers[index].PRICE.DISCOUNT_VALUE !== this.offers[index].PRICE.VALUE)
1058				{
1059					obData = {
1060						style: {
1061							display: ''
1062						},
1063						html: this.offers[index].PRICE.DISCOUNT_DIFF_PERCENT
1064					};
1065				}
1066				else
1067				{
1068					obData = {
1069						style: {
1070							display: 'none'
1071						},
1072						html: ''
1073					};
1074				}
1075				if (!!this.obDscPerc)
1076				{
1077					BX.adjust(this.obDscPerc, obData);
1078				}
1079				if (!!this.obSecondDscPerc)
1080				{
1081					BX.adjust(this.obSecondDscPerc, obData);
1082				}
1083			}
1084		}
1085		this.offerNum = index;
1086		this.QuantitySet(this.offerNum);
1087	}
1088};
1089
1090window.JCCatalogBigdataProducts.prototype.InitBasketUrl = function()
1091{
1092	switch (this.productType)
1093	{
1094		case 1://product
1095		case 2://set
1096			this.basketUrl = this.product.addUrl;
1097			break;
1098		case 3://sku
1099			this.basketUrl = this.offers[this.offerNum].ADD_URL;
1100			break;
1101	}
1102	this.basketParams = {
1103		'ajax_basket': 'Y',
1104		'rcm': 'yes'
1105	};
1106	if (this.showQuantity)
1107	{
1108		this.basketParams[this.basketData.quantity] = this.obQuantity.value;
1109	}
1110};
1111
1112window.JCCatalogBigdataProducts.prototype.FillBasketProps = function()
1113{
1114	if (!this.visual.BASKET_PROP_DIV)
1115	{
1116		return;
1117	}
1118	var
1119		i = 0,
1120		propCollection = null,
1121		foundValues = false,
1122		obBasketProps = null;
1123
1124	if (this.basketData.useProps && !this.basketData.emptyProps)
1125	{
1126		if (!!this.obPopupWin && !!this.obPopupWin.contentContainer)
1127		{
1128			obBasketProps = this.obPopupWin.contentContainer;
1129		}
1130	}
1131	else
1132	{
1133		obBasketProps = BX(this.visual.BASKET_PROP_DIV);
1134	}
1135	if (!obBasketProps)
1136	{
1137		return;
1138	}
1139	propCollection = obBasketProps.getElementsByTagName('select');
1140	if (!!propCollection && !!propCollection.length)
1141	{
1142		for (i = 0; i < propCollection.length; i++)
1143		{
1144			if (!propCollection[i].disabled)
1145			{
1146				switch(propCollection[i].type.toLowerCase())
1147				{
1148					case 'select-one':
1149						this.basketParams[propCollection[i].name] = propCollection[i].value;
1150						foundValues = true;
1151						break;
1152					default:
1153						break;
1154				}
1155			}
1156		}
1157	}
1158	propCollection = obBasketProps.getElementsByTagName('input');
1159	if (!!propCollection && !!propCollection.length)
1160	{
1161		for (i = 0; i < propCollection.length; i++)
1162		{
1163			if (!propCollection[i].disabled)
1164			{
1165				switch(propCollection[i].type.toLowerCase())
1166				{
1167					case 'hidden':
1168						this.basketParams[propCollection[i].name] = propCollection[i].value;
1169						foundValues = true;
1170						break;
1171					case 'radio':
1172						if (propCollection[i].checked)
1173						{
1174							this.basketParams[propCollection[i].name] = propCollection[i].value;
1175							foundValues = true;
1176						}
1177						break;
1178					default:
1179						break;
1180				}
1181			}
1182		}
1183	}
1184	if (!foundValues)
1185	{
1186		this.basketParams[this.basketData.props] = [];
1187		this.basketParams[this.basketData.props][0] = 0;
1188	}
1189};
1190
1191window.JCCatalogBigdataProducts.prototype.SendToBasket = function()
1192{
1193	if (!this.canBuy)
1194	{
1195		return;
1196	}
1197	this.InitBasketUrl();
1198	this.FillBasketProps();
1199
1200	// check recommendation
1201	if (this.product && this.product.id)
1202	{
1203		if (JCCatalogBigdataProducts.productsByRecommendation && JCCatalogBigdataProducts.productsByRecommendation[this.product.id])
1204		{
1205			this.RememberProductRecommendation(JCCatalogBigdataProducts.productsByRecommendation[this.product.id], this.product.id);
1206		}
1207	}
1208
1209	BX.ajax({
1210		method: 'POST',
1211		dataType: 'json',
1212		url: this.basketUrl,
1213		data: this.basketParams,
1214		onsuccess: BX.delegate(this.BasketResult, this)
1215	});
1216};
1217
1218/**
1219 * @deprecated
1220 * @param obj
1221 * @param productId
1222 * @constructor
1223 */
1224window.JCCatalogBigdataProducts.prototype.RememberRecommendation = function(obj, productId)
1225{
1226	var rcmContainer = BX.findParent(obj, {'className':'bigdata_recommended_products_items'});
1227	var rcmId = BX.findChild(rcmContainer, {'attr':{'name':'bigdata_recommendation_id'}}, true).value;
1228
1229	this.RememberProductRecommendation(rcmId, productId);
1230};
1231
1232window.JCCatalogBigdataProducts.prototype.RememberProductRecommendation = function(recommendationId, productId)
1233{
1234	// save to RCM_PRODUCT_LOG
1235	var plCookieName = BX.cookie_prefix+'_RCM_PRODUCT_LOG';
1236	var plCookie = getCookie(plCookieName);
1237	var itemFound = false;
1238
1239	var cItems = [],
1240		cItem;
1241
1242	if (plCookie)
1243	{
1244		cItems = plCookie.split('.');
1245	}
1246
1247	var i = cItems.length;
1248
1249	while (i--)
1250	{
1251		cItem = cItems[i].split('-');
1252
1253		if (cItem[0] == productId)
1254		{
1255			// it's already in recommendations, update the date
1256			cItem = cItems[i].split('-');
1257
1258			// update rcmId and date
1259			cItem[1] = recommendationId;
1260			cItem[2] = BX.current_server_time;
1261
1262			cItems[i] = cItem.join('-');
1263			itemFound = true;
1264		}
1265		else
1266		{
1267			if ((BX.current_server_time - cItem[2]) > 3600*24*30)
1268			{
1269				cItems.splice(i, 1);
1270			}
1271		}
1272	}
1273
1274	if (!itemFound)
1275	{
1276		// add recommendation
1277		cItems.push([productId, recommendationId, BX.current_server_time].join('-'));
1278	}
1279
1280	// serialize
1281	var plNewCookie = cItems.join('.');
1282
1283	var cookieDate = new Date(new Date().getTime() + 1000*3600*24*365*10);
1284	document.cookie=plCookieName+"="+plNewCookie+"; path=/; expires="+cookieDate.toUTCString()+"; domain="+BX.cookie_domain;
1285};
1286
1287window.JCCatalogBigdataProducts.prototype.Basket = function()
1288{
1289	var contentBasketProps = '';
1290	if (!this.canBuy)
1291	{
1292		return;
1293	}
1294	switch (this.productType)
1295	{
1296	case 1://product
1297	case 2://set
1298		if (this.basketData.useProps && !this.basketData.emptyProps)
1299		{
1300			this.InitPopupWindow();
1301			this.obPopupWin.setTitleBar({
1302				content: BX.create('div', {
1303					style: { marginRight: '30px', whiteSpace: 'nowrap' },
1304					text: BX.message('CBD_TITLE_BASKET_PROPS')
1305				})
1306			});
1307			if (BX(this.visual.BASKET_PROP_DIV))
1308			{
1309				contentBasketProps = BX(this.visual.BASKET_PROP_DIV).innerHTML;
1310			}
1311			this.obPopupWin.setContent(contentBasketProps);
1312			this.obPopupWin.setButtons([
1313				new BasketButton({
1314					ownerClass: this.obProduct.parentNode.parentNode.parentNode.className,
1315					text: BX.message('CBD_BTN_MESSAGE_SEND_PROPS'),
1316					events: {
1317						click: BX.delegate(this.SendToBasket, this)
1318					}
1319				})
1320			]);
1321			this.obPopupWin.show();
1322		}
1323		else
1324		{
1325			this.SendToBasket();
1326		}
1327		break;
1328	case 3://sku
1329		this.SendToBasket();
1330		break;
1331	}
1332};
1333
1334window.JCCatalogBigdataProducts.prototype.BasketResult = function(arResult)
1335{
1336	var strContent = '',
1337		strName = '',
1338		strPict = '',
1339		successful = true,
1340		buttons = [];
1341
1342	if (!!this.obPopupWin)
1343	{
1344		this.obPopupWin.close();
1345	}
1346	if ('object' !== typeof arResult)
1347	{
1348		return false;
1349	}
1350	successful = ('OK' === arResult.STATUS);
1351	if (successful)
1352	{
1353		BX.onCustomEvent('OnBasketChange');
1354		strName = this.product.name;
1355		switch(this.productType)
1356		{
1357		case 1://
1358		case 2://
1359			strPict = this.product.pict.SRC;
1360			break;
1361		case 3:
1362			strPict = (!!this.offers[this.offerNum].PREVIEW_PICTURE ?
1363				this.offers[this.offerNum].PREVIEW_PICTURE.SRC :
1364				this.defaultPict.pict.SRC
1365			);
1366			break;
1367		}
1368		strContent = '<div style="width: 96%; margin: 10px 2%; text-align: center;"><img src="'+strPict+'" height="130" style="max-height:130px"><p>'+strName+'</p></div>';
1369		buttons = [
1370			new BasketButton({
1371				ownerClass: this.obProduct.parentNode.parentNode.parentNode.className,
1372				text: BX.message("CBD_BTN_MESSAGE_BASKET_REDIRECT"),
1373				events: {
1374					click: BX.delegate(function(){
1375						location.href = (!!this.basketData.basketUrl ? this.basketData.basketUrl : BX.message('CBD_BASKET_URL'));
1376					}, this)
1377				}
1378			})
1379		];
1380	}
1381	else
1382	{
1383		strContent = (!!arResult.MESSAGE ? arResult.MESSAGE : BX.message('CBD_BASKET_UNKNOWN_ERROR'));
1384		buttons = [
1385			new BasketButton({
1386				ownerClass: this.obProduct.parentNode.parentNode.parentNode.className,
1387				text: BX.message('CBD_BTN_MESSAGE_CLOSE'),
1388				events: {
1389					click: BX.delegate(this.obPopupWin.close, this.obPopupWin)
1390				}
1391			})
1392		];
1393	}
1394	this.InitPopupWindow();
1395	this.obPopupWin.setTitleBar({
1396		content: BX.create('div', {
1397			style: { marginRight: '30px', whiteSpace: 'nowrap' },
1398			text: (successful ? BX.message('CBD_TITLE_SUCCESSFUL') : BX.message('CBD_TITLE_ERROR'))
1399		})
1400	});
1401	this.obPopupWin.setContent(strContent);
1402	this.obPopupWin.setButtons(buttons);
1403	this.obPopupWin.show();
1404};
1405
1406window.JCCatalogBigdataProducts.prototype.InitPopupWindow = function()
1407{
1408	if (!!this.obPopupWin)
1409	{
1410		return;
1411	}
1412	this.obPopupWin = BX.PopupWindowManager.create('CatalogSectionBasket_'+this.visual.ID, null, {
1413		autoHide: false,
1414		offsetLeft: 0,
1415		offsetTop: 0,
1416		overlay : true,
1417		closeByEsc: true,
1418		titleBar: true,
1419		closeIcon: {top: '10px', right: '10px'}
1420	});
1421};
1422})(window);
1423
1424function getCookie(name) {
1425	var matches = document.cookie.match(new RegExp(
1426		"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
1427	));
1428	return matches ? decodeURIComponent(matches[1]) : undefined;
1429}
1430
1431/**
1432 * @deprecated see ajax.php
1433 * @param rcm_items_cont
1434 */
1435function bx_rcm_recommendation_event_attaching(rcm_items_cont)
1436{
1437	return null;
1438}
1439
1440function bx_rcm_adaptive_recommendation_event_attaching(items, uniqId)
1441{
1442	// onclick handler
1443	var callback = function (e)  {
1444
1445		var link = BX(this), j;
1446
1447		for (j in items)
1448		{
1449			if (items[j].productUrl == link.getAttribute('href'))
1450			{
1451				window.JCCatalogBigdataProducts.prototype.RememberProductRecommendation(
1452					items[j].recommendationId, items[j].productId
1453				);
1454
1455				break;
1456			}
1457		}
1458	};
1459
1460	// check if a container was defined is the template
1461	var itemsContainer = BX(uniqId);
1462
1463	if (!itemsContainer)
1464	{
1465		// then get all the links
1466		itemsContainer = document.body;
1467	}
1468
1469	var links = BX.findChildren(itemsContainer, {tag:'a'}, true);
1470
1471	// bind
1472	if (links)
1473	{
1474		var i;
1475		for (i in links)
1476		{
1477			BX.bind(links[i], 'click', callback);
1478		}
1479	}
1480}
1481
1482function bx_rcm_get_from_cloud(injectId, rcmParameters, localAjaxData)
1483{
1484	var url = 'https://analytics.bitrix.info/crecoms/v1_0/recoms.php';
1485	var data = BX.ajax.prepareData(rcmParameters);
1486
1487	if (data)
1488	{
1489		url += (url.indexOf('?') !== -1 ? "&" : "?") + data;
1490	}
1491
1492	var onready = function(response) {
1493
1494		if (!response.items)
1495		{
1496			response.items = [];
1497		}
1498		BX.ajax({
1499			url: '/bitrix/components/bitrix/catalog.bigdata.products/ajax.php?'+BX.ajax.prepareData({'AJAX_ITEMS': response.items, 'RID': response.id}),
1500			method: 'POST',
1501			data: localAjaxData,
1502			dataType: 'html',
1503			processData: false,
1504			start: true,
1505			onsuccess: function (html) {
1506				var ob = BX.processHTML(html);
1507
1508				// inject
1509				BX(injectId).innerHTML = ob.HTML;
1510				BX.ajax.processScripts(ob.SCRIPT);
1511			}
1512		});
1513	};
1514
1515	BX.ajax({
1516		'method': 'GET',
1517		'dataType': 'json',
1518		'url': url,
1519		'timeout': 3,
1520		'onsuccess': onready,
1521		'onfailure': onready
1522	});
1523}

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.