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.