1function slog(str) { 2 try { 3 console.log(str); 4 } catch (e) {} 5} 6 7(function (window) { 8 'use strict'; 9 if (window.AcritBonusIntegration) { 10 return; 11 } 12 13 /*/ 14 BX.onCustomEvent = function (eventObject, eventName) { 15 console.log('onCustomEvent'); 16 console.log(eventName); 17 console.log(eventObject); 18 //console.log(arEventParams); 19 console.log('===================='); 20 }; 21 /**/ 22 23 /** 24 * @param arParams 25 * @constructor 26 */ 27 window.AcritBonusIntegration = function (arParams) { 28 if (typeof arParams === 'object') { 29 this.Params = arParams; 30 this.elementcount = 0; 31 this.elementID = 0; 32 } 33 slog('window.AcritBonusIntegration'); 34 35 // custom product autointegration with definition of productId outside 36 if (typeof productId != 'undefined') { 37 this.elementID = productId; 38 this.elementcount = 1; 39 this.ElementBonus(); 40 } 41 42 // basket and product 43 BX.addCustomEvent('onCatalogElementChangeOffer', BX.proxy(this.DetailElement, this)); 44 this.BasketAllBonus(); 45 if (BX.Sale) { 46 BX.addCustomEvent('OnBasketChange', BX.proxy(this.BasketAllBonus, this)); 47 } 48 49 // old 50 ////BX.addCustomEvent('quantityChange', BX.proxy(this.ChangeQuantity, this)); 51 ////BX.addCustomEvent('quantityUp', BX.proxy(this.ChangeQuantity, this)); 52 ////BX.addCustomEvent('ChangeQuantity', BX.proxy(this.ChangeQuantity, this)); 53 54 // order 55 if (BX.Sale) { 56 this.SOAAjax(); 57 } 58 BX.addCustomEvent('onAjaxSuccess', BX.proxy(this.SOAAjax, this)); 59 60 this.PersonalPage(); 61 }; 62 window.AcritBonusIntegration.prototype.UpdateBonus = function () 63 { 64 }; 65 window.AcritBonusIntegration.prototype = { 66 ErrorNotFoundClass: function (className, id, functionBlock = false) { 67 if (functionBlock != false) { 68 console.log('acrit.bonus warning: Block [' + functionBlock + '] not found class[' + className + '] in id[' + id + ']'); 69 } else { 70 console.log('acrit.bonus warning: not found class[' + className + '] in id[' + id + ']'); 71 } 72 }, 73 ErrorNotFoundId: function (id, functionBlock = false) { 74 if (functionBlock != false) { 75 console.error('acrit.bonus warning: Block [' + functionBlock + '] not found id[' + id + ']'); 76 } else { 77 console.error('acrit.bonus warning: not found id[' + id + ']'); 78 } 79 }, 80 PersonalPage: function () { 81 var params = this.Params.PERSONAL; 82 if (params.ON != undefined && params.ON) { 83 let blockId = this.getBlockId(params.BLOCK_ID); 84 85 if (params.BALANCE != undefined) { 86 if (! document.querySelector(blockId)) { 87 this.ErrorNotFoundId(blockId); 88 return; 89 } 90 var block = BX.findChild(document.querySelector(blockId), { 91 'tag': 'div', 92 'class': params.BLOCK_CLASS 93 }, true); 94 if (!block) { 95 this.ErrorNotFoundClass(params.BLOCK_CLASS, blockId, 'Personal page'); 96 return; 97 } 98 99 var html = BX.create('DIV', {props: {className: 'acrit-bonus-personal-balance'}, html: params.BALANCE_TEXT + ' ' + params.BALANCE}); 100 if (block) { 101 BX.prepend(html, block) 102 } 103 } 104 if (params.ORDERS != undefined) { 105 // insert bonus on page /personal/orders/?filter_history=Y 106 var fields = BX.findChild(BX(params.BLOCK_ID), {class: 'sale-order-list-about-link'}, true, true); 107 var href = ''; 108 var orderId = ''; 109 fields.forEach(function (element) { 110 href = element.getAttribute('href'); 111 orderId = href.replace('/personal/orders/', ''); 112 if (params.ORDERS[orderId] != undefined) { 113 var html = BX.create('DIV', {props: {className: 'acrit-bonus-personal-order-bonus'}, html: params.ORDERS_TEXT + ' ' + params.ORDERS[orderId]}); 114 BX.insertAfter(html, element); 115 } 116 }); 117 } 118 } 119 120 }, 121 BasketAllBonus: function () { 122 if (this.Params.CART.ON != true) { 123 return; 124 } 125 126 if (!BX.Sale || !BX.Sale.BasketComponent || !BX.Sale.BasketComponent.result) { 127 return; 128 } 129 if (!BX.Sale.BasketComponent.result.GRID.ROWS && BX.Sale.BasketComponent.result.BASKET_ITEM_RENDER_DATA) { 130 BX.Sale.BasketComponent.result.GRID.ROWS = BX.Sale.BasketComponent.result.BASKET_ITEM_RENDER_DATA; 131 } 132 if (!BX.Sale.BasketComponent.result.GRID.ROWS) { 133 return; 134 } 135 136 const _this = this; 137 const params = { 138 ACTION: 'BASKET', 139 AJAX: 'Y', 140 SITE_ID: this.Params.SITE_ID, 141 TYPE: 'CART', 142 ENDTOEND: 'Y', 143 /*GRID: BX.Sale.BasketComponent.result.GRID.ROWS,*/ 144 COUNTS: 1, 145 }; 146
147 const createBonusBlock = function () { 148 const blockId = _this.getBlockId(_this.Params.CART.MAIN_BLOCK); 149 if (! document.querySelector(blockId)) { 150 _this.ErrorNotFoundId(blockId, 'BASKET'); 151 return; 152 } 153 154 const itog_block = BX.findChild(document.querySelector(blockId), { 155 'tag': 'div', 156 'class': _this.Params.CART.OUT_BLOCK 157 }, true); 158 const bonus_all = BX.create('DIV', {props: {id: 'bonus_all'}}); 159 if (! itog_block) { 160 _this.ErrorNotFoundClass(_this.Params.CART.OUT_BLOCK, blockId, 'BASKET'); 161 } else { 162 itog_block.appendChild(bonus_all); 163 } 164 return bonus_all; 165 }; 166 167 BX.ajax({ 168 url: this.Params.CART.PATH, 169 data: params, 170 method: 'POST', 171 dataType: 'json', 172 timeout: 60, 173 async: true, 174 processData: true, 175 scriptsRunFirst: true, 176 emulateOnload: true, 177 start: true, 178 cache: false, 179 onsuccess: function (data) { 180 window.setTimeout(function() { 181 let bonus_all = document.getElementById('bonus_all'); 182 if (typeof data.ALLBONUS != 'undefined' && data.ALLBONUS != '') { 183 if (! bonus_all) { 184 bonus_all = createBonusBlock(); 185 } 186 BX.adjust(bonus_all, {html: _this.Params.CART.LANG_BONUS + ' ' + data.ALLBONUS}); 187 } else if (bonus_all) { 188 BX.remove(bonus_all); 189 } 190 }, _this.getWaitBxAjaxTimeout()); 191 /* 192 if (_this.Params.CART.BONUS_OFFER == true) { 193 for (var id in data.ITEMS) { 194 var item = data.ITEMS[id]; 195 var product_block = BX('basket-item-' + item.ID); 196 var price_blocks = BX.findChild(product_block, { 197 'tag': 'div', 198 'class': 'basket-item-block-price' 199 }, true, true); 200 var price_for_item = price_blocks[1]; 201 var bonus_item = BX.create('DIV', { 202 props: { 203 id: 'bonus_item_' + item.ID, 204 className: 'bonus bonus_item_cart' 205 }, html: _this.Params.CART.OFFER_LANG_BONUS + ' ' + item.BONUS 206 }); 207 BX.remove(BX('bonus_item_' + item.ID)); 208 if (parseFloat(item.BONUS) > 0) 209 price_for_item.appendChild(bonus_item); 210 } 211 } 212 if (_this.Params.CARTBONUSPAY.ON == true) { 213 var bonuspay_block = BX.findChild(BX(_this.Params.CARTBONUSPAY.MAIN_BLOCK), { 214 'tag': 'div', 215 'class': _this.Params.CARTBONUSPAY.OUT_BLOCK 216 }, true); 217 var bonuspay = BX.create('DIV', { 218 props: {id: 'bonuspay'}, 219 html: 'bonuspay for cart (test) !!!not use!!!' 220 }); 221 bonuspay_block.appendChild(bonuspay); 222 } 223 */ 224 }, 225 onfailure: function () { 226 } 227 }); 228 }, 229 SOAAjax: function (ajaxResult) { 230 // here may pass other ajax-calls 231 if (!BX.Sale || (BX.Sale.OrderAjaxComponent == undefined) || (typeof ajaxResult !== 'undefined' && typeof ajaxResult.order === 'undefined')) { 232 return; 233 } 234 const _this = this; 235 window.setTimeout(function (){ 236 _this.payBonusElement(BX.Sale.OrderAjaxComponent.result); 237 }, _this.getWaitBxAjaxTimeout()); 238 }, 239 payBonusElement: function (result) { 240 if (typeof result === 'undefined' || !this.Params.SOA.ON) { 241 return; 242 } 243 BX.remove(BX('bonus_order')); 244 BX.remove(BX('bonus_pay')); 245 246 // region BONUS.TOTAL BLOCK 247 if (this.Params.SOA.MAIN_BLOCK) { 248 const total_block = BX.findChild(BX(this.Params.SOA.MAIN_BLOCK), { 249 'tag': 'div', 250 'class': this.Params.SOA.OUT_BLOCK 251 }, true, true); 252 253 // when total_block is multiple: 254 255 /** 256 * Inserts a specified block element after each block in a list of provided blocks. 257 * 258 * @param {HTMLElement} block - The block element to insert. 259 * @param {HTMLElement[]} afterBlocks - An array of block elements after which the specified block will be inserted. 260 */ 261 const insertAfterBlock = function (block, afterBlocks) { 262 afterBlocks.forEach(function (afterBlock) { 263 BX.insertAfter(block, afterBlock); 264 }); 265 }; 266 267 if (parseFloat(result.TOTAL.BONUS_PAY_USER_INPUT) > 0) { 268 BX.remove(BX('acrit-bonus-total-pay-by-bonus')); 269 var totalPayByBonus = BX.create('DIV', { 270 attrs: {className: 'bx-soa-cart-total-line', id: 'acrit-bonus-total-pay-by-bonus'}, 271 html: '<div id="acrit-bonus-total-pay-by-bonus-block"><span class="bx-soa-cart-t">' + result.TOTAL.TOTAL_BONUS_PAY_TITLE + '</span><span class="bx-soa-cart-d">' + result.TOTAL.BONUS_PAY_USER_INPUT_FORMAT + '</span></div>' 272 }); 273 if (total_block.length && totalPayByBonus) { 274 insertAfterBlock(totalPayByBonus, total_block); 275 } else { 276 console.log('Warning: cant add item acrit-bonus-total-pay-by-bonus'); 277 } 278 } 279 if (parseFloat(result.TOTAL.BONUS_ORDER) > 0) { 280 BX.remove(BX('bonus_order')); 281 var block_order_bonus = BX.create('DIV', { 282 attrs: {className: 'bx-soa-cart-total-line', id: 'bonus_order'}, 283 html: '<div id="order_bonus"><span class="bx-soa-cart-t">' + this.Params.SOA.LANG_BONUS + '</span><span class="bx-soa-cart-d">' + result.TOTAL.BONUS_ORDER_FORMAT + '</span></div>' 284 }); 285 if (total_block.length && block_order_bonus) { 286 insertAfterBlock(block_order_bonus, total_block); 287 } else { 288 console.log('Warning: cant add item #order_bonus'); 289 } 290 } 291 if (parseFloat(result.TOTAL.BONUS_PAY) > 0) { 292 BX.remove(BX('bonus_pay')); 293 var block_bonus_pay = BX.create('DIV', { 294 attrs: {className: 'bx-soa-cart-total-line', id: 'bonus_pay'}, 295 html: '<div id="order_bonuspay"><span class="bx-soa-cart-t">' + this.Params.SOA.LANG_BONUSPAY + '</span><span class="bx-soa-cart-d">' + result.TOTAL.BONUS_PAY + '</span></div>' 296 }); 297 if (total_block.length && block_bonus_pay) { 298 insertAfterBlock(block_bonus_pay, total_block); 299 } else { 300 console.log('Warning: cant add item #order_bonuspay'); 301 } 302 } 303 } 304 // endregion 305 306 // region BONUSPAY form DISPLAY 307 if (result.BONUSPAY && result.BONUSPAY.DISPLAY == true) { 308 var payment_block = BX.create('DIV', { 309 attrs: { 310 id: 'acrit-bonus-paysystem', 311 className: 'bx-soa-section' 312 } 313 }); 314 var title = BX.create('DIV', { 315 attrs: {className: 'bx-soa-section-title-container'}, 316 html: '<h2 class="bx-soa-section-title col-sm-9">
316' + 317 '<span class="bx-soa-section-title-count"></span>' + result.BONUSPAY.NAME + '</h2>' 318 }); 319 var con = BX.create('DIV', {attrs: {className: 'bx-soa-section-content container-fluid'}}); 320 var container = BX.create('DIV', {attrs: {className: 'bx-soa-pp row'}}); 321 var container_in = BX.create('DIV', {attrs: {className: 'col-sm-9 bx-soa-pp-item-container'}}); 322 var container_inpic = BX.create('DIV', {attrs: {className: 'col-sm-2 bx-soa-pp-item-container'}}); 323 payment_block.appendChild(title); 324 var comment_block = BX.create('DIV', { 325 props: {className: 'bonus_comment'}, 326 children: [ 327 BX.create('strong', {html: this.Params.SOA.INTEGRATION_ORDER_TEXT_IN_YOU_ACCOUNT.replace("#SUMMA#", result.BONUSPAY.CURRENT_BONUS_BUDGET_FORMATED.replace("", " "))}) 328 ] 329 }); 330 var max_pay = BX.create('span', {html: '<br />' + this.Params.SOA.INTEGRATION_ORDER_TXT_YOU_MUST_PAY.replace("#PERCENT#", result.BONUSPAY.ORDER_PAY_PERCENT).replace("#MAXPAY#", result.BONUSPAY.MAXPAY_FORMATTED)}); 331 var pay_field_block = BX.create('DIV', { 332 props: {id: 'bonus_payfield_block'}, 333 children: [BX.create('strong', {text: result.BONUSPAY.USER_INPUT == true ? this.Params.SOA.INTEGRATION_ORDER_TXT_HOW_MUCH_BONUS : ''})] 334 }); 335 var non_bonuspay = BX.create('DIV', { 336 props: {className: 'bonus_comment'}, 337 children: [ 338 BX.create('strong', {text: this.Params.SOA.ITR_BONUS_NONE_PAYBONUS}) 339 ] 340 }); 341 var input_field = BX.create('input', { 342 attrs: { 343 type: 'text', 344 id: 'BONUS_CNT', 345 value: result.BONUSPAY.USER_VALUE, 346 name: 'BONUS_CNT', 347 disabled: result.PAY_BONUS_ACCOUNT ? 'disable' : '', 348 pattern: "\\d+(\\.\\d+)?" 349 }, 350 style: { 351 'width': '150px' 352 }, 353 }); 354 if (this.Params.CHECK_SMS.ON == 'Y') { 355 var sms_field_block = BX.create('DIV', { 356 props: {id: 'sms_payfield_block'}, 357 children: [BX.create('strong', {text: this.Params.CHECK_SMS.SMSTEXT})] 358 }); 359 var sms_code = BX.create('input', { 360 attrs: { 361 type: 'text', 362 id: 'SMSCODE', 363 value: result.SMSCODE ? result.SMSCODE : '', 364 name: 'SMSCODE', 365 disabled: result.CHECKSMS ? 'disable' : '', 366 }, 367 style: { 368 'width': '150px' 369 } 370 }); 371 var checksms = BX.create('LABEL', { 372 props: {className: 'bxr-subscribe-tab-link bxr-font-color bxr-border-color'}, 373 children: [ 374 BX.create('INPUT', { 375 attrs: { 376 type: 'checkbox', 377 id: 'CHECK_SMS', 378 name: 'CHECK_SMS', 379 value: 'Y', 380 checked: result.CHECKSMS 381 }, 382 style: { 383 'display': 'none', 384 }, 385 events: { 386 click: BX.proxy(this.checksms, this) 387 } 388 }), 389 BX.create('SPAN', { 390 text: (result.CHECKSMS ? this.Params.SOA.ITR_BONUS_TXT_BONUSPAY_CANCEL : this.Params.SOA.ITR_BONUS_TXT_BONUSPAY_OK) 391 }) 392 ], 393 style: { 394 'border': '1px solid #e3e6e8', 395 'padding': '2px', 396 'margin-left': '10px', 397 'cursor': 'pointer', 398 }, 399 }); 400 } 401 402 var input_field_hidden = BX.create('input', { 403 attrs: { 404 type: 'hidden', 405 id: 'BONUS_CNT', 406 value: result.BONUSPAY.MAXPAY, 407 name: 'BONUS_CNT', 408 }, 409 }); 410 var hiddenpay = BX.create('INPUT', { 411 attrs: { 412 type: 'hidden', 413 name: 'PAY_BONUS_ACCOUNT', 414 value: 'N', 415 }, 416 }); 417 var label = BX.create('LABEL', { 418 props: {className: 'bxr-subscribe-tab-link bxr-font-color bxr-border-color'}, 419 children: [ 420 BX.create('INPUT', { 421 attrs: { 422 type: 'checkbox', 423 id: 'PAY_BONUS_ACCOUNT', 424 name: 'PAY_BONUS_ACCOUNT', 425 value: 'Y', 426 checked: result.PAY_BONUS_ACCOUNT 427 }, 428 style: { 429 'display': 'none', 430 }, 431 events: { 432 click: BX.proxy(this.selectBonusPaySystem, this) 433 } 434 }), 435 BX.create('SPAN', { 436 text: (result.PAY_BONUS_ACCOUNT ? this.Params.SOA.PAY_BONUS_APPLY_BUTTON_CANCEL : this.Params.SOA.PAY_BONUS_APPLY_BUTTON_OK) 437 }) 438 ], 439 style: { 440 'border': '1px solid #e3e6e8', 441 'padding': '2px', 442 'margin-left': '10px', 443 'cursor': 'pointer', 444 }, 445 } 446 ); 447 var help = BX.create('DIV', { 448 props: {}, 449 children: [ 450 BX.create('A', { 451 props: {href: BX.util.htmlspecialchars(this.Params.SOA.INTEGRATION_ORDER_PATH_TO_HELP)}, 452 html: BX.util.htmlspecialchars(this.Params.SOA.ITR_BONUS_TEXT_TO_HELP) 453 }), 454 ], 455 } 456 ); 457 var logoNode = BX.create('DIV', {props: {className: 'bx-soa-pp-company-image'}}); 458 var logotype = result.BONUSPAY.LOGOTIP_SRC; 459 if (logotype) { 460 logoNode.setAttribute('style', 461 'background-image: url(' + logotype + ');' + 462 'background-image: -webkit-image-set(url(' + logotype + ') 1x, url(' + logotype + ') 2x)' 463 ); 464 } 465 var pic_con = BX.create('DIV', {attrs: {className: 'bx-soa-pp-company-graf-container'}}); 466 pic_con.appendChild(logoNode); 467 container_inpic.appendChild(pic_con); 468 container_in.appendChild(comment_block); 469 if (result.BONUSPAY.MAXPAY > 0) { 470 container_in.appendChild(max_pay); 471 container_in.appendChild(pay_field_block); 472 473 if (result.BONUSPAY.USER_INPUT == true) { 474 container_in.appendChild(input_field); 475 } else { 476 container_in.appendChild(input_field_hidden); 477 container_in.appendChild(hiddenpay); 478 } 479 container_in.appendChild(label); 480 if (this.Params.CHECK_SMS.ON == 'Y' && result.PAY_BONUS_ACCOUNT) { 481 container_in.appendChild(sms_field_block); 482 container_in.appendChild(sms_code); 483 container_in.appendChild(checksms); 484 } 485 } else { 486 container_in.appendChild(non_bonuspay); 487 } 488 container_in.appendChild(help); 489 490 BX.remove(BX('acrit-bonus-paysystem')); 491 container.appendChild(container_inpic); 492 container.appendChild(container_in); 493 con.appendChild(container); 494 payment_block.appendChild(con); 495 496 BX.addClass(payment_block, this.Params.SOA.BONUSPAY_OUT_BLOCK); 497 498 let blockId = this.getBlockId(this.Params.SOA.BONUSPAY_MAIN_BLOCK); 499 BX.insertAfter(payment_block, document.querySelector(blockId)); 500 } else { 501 BX.remove(BX('acrit-bonus-paysystem')); 502 } 503 504 if (document.getElementById('BONUS_CNT')) { 505 document.getElementById('BONUS_CNT').addEventListener('keydown', (e) => { 506 if (e.key === 'Enter') { 507 e.stopPropagation(); 508 return false;
509 } 510 }); 511 document.getElementById('BONUS_CNT').addEventListener('input', function (e) { 512 this.value = this.value.replace(/[^0-9+.]/g, ''); 513 }); 514 } 515 // endregion 516 }, 517 checksms: function () { 518 BX.Sale.OrderAjaxComponent.sendRequest(); 519 }, 520 selectBonusPaySystem: function () { 521 BX.Sale.OrderAjaxComponent.sendRequest(); 522 }, 523 DetailElement: function (eventData, eventname) { 524 slog('DetailElement'); 525 if (eventData) { 526 const _this = this; 527 window.setTimeout(function (){ 528 _this.elementID = eventData.newId; 529 _this.ElementBonus(); 530 }, _this.getWaitBxAjaxTimeout()) 531 } 532 }, 533 ChangeQuantity: function (eventData) { 534 slog(eventData); 535 this.elementID = eventData.newId; 536 this.elementcount = eventData.Qua; 537 this.ElementBonus(); 538 }, 539 ElementBonus: function () { 540 slog('ElementBonus') 541 if (this.Params.DETAIL.ON != true) { 542 return; 543 } 544 let params = { 545 AJAX: 'Y', 546 SITE_ID: this.Params.SITE_ID, 547 PRODUCT_ID: this.elementID, 548 COUNTS: this.elementcount 549 }; 550 const _this = this; 551 const isDoubleElementId = (this.productPageElementId != undefined && this.productPageElementId == this.elementID); 552 const isDoubleElementCount = (this.productPageElementCount != undefined && this.productPageElementCount == this.elementcount); 553 if (isDoubleElementId && isDoubleElementCount) { 554 slog('double'); 555 return; 556 } 557 558 this.timestamp = Date.now(); 559 this.productPageElementId = this.elementID; 560 this.productPageElementCount = this.elementcount; 561 562 BX.ajax({ 563 url: this.Params.DETAIL.PATH, 564 data: params, 565 method: 'POST', 566 dataType: 'html', 567 timeout: 60, 568 async: true, 569 processData: true, 570 scriptsRunFirst: true, 571 emulateOnload: true, 572 start: true, 573 cache: false, 574 onsuccess: function (data) { 575 let bonus_all; 576 if (data.toString().trim() == '') { 577 return; 578 } 579 580 window.setTimeout(function () { 581 let blockId = _this.getBlockId(_this.Params.DETAIL.MAIN_BLOCK); 582 583 const itog_block = BX.findChild( 584 document.querySelector(blockId), 585 {'tag': 'div', 'class': _this.Params.DETAIL.OUT_BLOCK}, true 586 ); 587 if (!itog_block) { 588 if (! document.querySelector(blockId)) { 589 _this.ErrorNotFoundId(blockId); 590 } else { 591 _this.ErrorNotFoundClass(blockId, _this.Params.DETAIL.OUT_BLOCK, 'PRODUCT PAGE'); 592 } 593 } 594 if (_this.Params.DETAIL.COMP_TEMPLATE == '') { 595 bonus_all = BX.create('DIV', {props: {id: 'bonus_all'}, html: _this.Params.DETAIL.LANG_BONUS + ' ' + data}); 596 } else { 597 bonus_all = BX.create('DIV', {props: {id: 'bonus_all'}, html: data}); 598 } 599 BX.remove(BX('bonus_all')); 600 itog_block.appendChild(bonus_all); 601 }, _this.getWaitBxAjaxTimeout()); 602 }, 603 onfailure: function () { 604 } 605 }); 606 }, 607 608 getBlockId: function (blockId) { 609 if (typeof blockId === 'undefined') { 610 return false; 611 } 612 blockId = blockId.toString().trim(); 613 if (blockId[0] !== '#' && blockId[0] !== '.') { 614 blockId = '#' + blockId; 615 } 616 return blockId; 617 }, 618 619 getWaitBxAjaxTimeout: function() { 620 return 800; // bx basket uses ajax, wait it 621 } 622 }; 623})(window);
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.