1/** 2 * @property {object} wdp_script_data_pro 3 * @property {string} wdp_script_data_pro.ajaxurl 4 * @property {string} wdp_script_data_pro.update_price_with_qty 5 * @property {string} wdp_script_data_pro.highlight_range_qty_changed 6 * @property {string} wdp_script_data_pro.higlight_background_color 7 * @property {string} wdp_script_data_pro.higlight_text_color 8 * @property {string} wdp_script_data_pro.js_init_trigger 9 * @property {boolean} wdp_script_data_pro.replace_variable_price 10 * @property {string} wdp_script_data_pro.variable_price_selector 11 * @property {object} wdp_script_data_pro.page_data 12 * @property {boolean} wdp_script_data_pro.create_on_load 13 * @property {boolean} wdp_script_data_pro.show_spinner 14 * @property {string} wdp_script_data_pro.security 15 * @property {string} wdp_script_data_pro.security_param 16 */ 17 18/** 19 * @class 20 */ 21var DynamicPrice = (function () { 22 /** 23 * @constructs DynamicPrice 24 * @param {jQuery} $form 25 * @param {object} $opts 26 */ 27 function DynamicPrice($form, $opts) { 28 /** 29 * @type {Boolean} 30 * @private 31 */ 32 this.__isEnable = false; 33 34 /** 35 * @type {Object} 36 * @private 37 */ 38 this.__pageData = {}; 39 40 /** 41 * @type {String} 42 * @private 43 */ 44 this.__ajaxUrl = ""; 45 46 /** 47 * @name DynamicPrice#form 48 * @type {jQuery} 49 */ 50 this.form = null; 51 52 /** 53 * @type {number} 54 * @private 55 */ 56 this.__inputTimerId = null; 57 58 /** 59 * @type {Array} 60 * @private 61 */ 62 this.__price_destinations = []; 63 64 /** 65 * @type {Array} 66 * @private 67 */ 68 this.__subtotal_destinations = []; 69 70 /** 71 * @type {Array} 72 * @private 73 */ 74 this.__total_price_destinations = []; 75 76 this.__priceHtmlTemplate = "{{price_html}}"; 77 78 this.__priceSuffix = ""; 79 80 // for input observing 81 this.__lastChange = null;
82 this.__lastValue = null; 83 84 this.__cachePrice = null; 85 86 /** 87 * @type {Boolean} 88 * @private 89 */ 90 this.__show_spinner = true; 91 92 if (typeof $opts === 'undefined') { 93 $opts = wdp_script_data_pro; 94 } 95 96 if (typeof $opts.price_html_template !== 'undefined') { 97 this.__priceHtmlTemplate = $opts.price_html_template; 98 } 99 100 if (typeof $opts.dynamic_price_enable !== 'undefined') { 101 this.__isEnable = !!$opts.dynamic_price_enable; 102 } else if (typeof $opts.update_price_with_qty !== 'undefined') { 103 this.__isEnable = $opts.update_price_with_qty === "1"; 104 } 105 if (typeof $opts.page_data !== 'undefined') { 106 this.__pageData = $opts.page_data; 107 } 108 109 if (typeof $opts.price_suffix !== 'undefined') { 110 this.__priceSuffix = $opts.price_suffix; 111 } 112 113 if (typeof $opts.ajaxurl !== 'undefined') { 114 this.__ajaxUrl = $opts.ajaxurl; 115 } else { 116 logError("Empty ajaxurl"); 117 return; 118 } 119 120 if (typeof $form !== 'undefined' && $form.is('form')) { 121 this.form = $form 122 } else { 123 logError("Incorrect form provided"); 124 } 125 126 this.clickableBulkRows(); 127 128 if (typeof $opts.show_spinner !== 'undefined') { 129 this.__show_spinner = !!$opts.show_spinner; 130 } 131 132 /** 133 * 134 * @returns {function(): {price: number, value: string}[]} 135 * @private 136 */ 137 this.__addons_supplier = function () { 138 return [] 139 }; 140 } 141 142 function getTimestamp() { 143 return Math.floor(Date.now() / 1000); 144 } 145 146 DynamicPrice.prototype.stopObserve = function () { 147 if (this.__inputTimerId) { 148 clearInterval(this.__inputTimerId); 149 } 150 }; 151 152 DynamicPrice.prototype.__getQty = function () { 153 var $input = this.form.find('input[name="quantity"]'); 154 if ($input.length === 0) { 155 $input = this.form.find('select[name="quantity"]'); 156 if ($input.length === 0) { 157 return 0; 158 } 159 } 160 161 return $input.val(); 162 }; 163 164 DynamicPrice.prototype.observe = function () { 165 this.stopObserve(); 166 167 this.__lastChange = null;
168 this.__lastValue = this.__getQty(); 169 170 this.__inputTimerId = setInterval(this.__watch.bind(this), 300); 171 172 if (document.getElementById('asnp_easy_product_bundle')) { 173 setTimeout(() => { 174 this.__update(this.__lastValue); 175 }, 500); 176 } 177 }; 178 179 DynamicPrice.prototype.__watch = function () { 180 var $qty = this.__getQty(); 181 182 if ($qty && this.__lastValue !== $qty) { 183 this.__lastValue = $qty; 184 this.__lastChange = getTimestamp(); 185 } else if (this.__lastValue && this.__lastValue === $qty && this.__lastChange) { 186 this.__lastChange = null; 187 this.__update(this.__lastValue); 188 } 189 }; 190 191 DynamicPrice.prototype.__getProductId = function () { 192 var variationIdEl = this.form.find('[name="variation_id"]'); 193 var productIdEl = this.form.find('[name="add-to-cart"]'); 194 195 if (variationIdEl.length) { 196 return parseInt(variationIdEl.val()); 197 } else if (productIdEl.length) { 198 return parseInt(productIdEl.val()); 199 } 200 201 return false; 202 }; 203 204 DynamicPrice.prototype.__getVariationAttributes = function () { 205 let attributes = {}; 206 207 this.form.find('select').each(function (index, item) { 208 if (jQuery(item).attr("data-attribute_name")) { 209 attributes[jQuery(item).attr("data-attribute_name")] = jQuery(this).val(); 210 } 211 }); 212 213 return attributes; 214 }; 215 216 /** 217 * 218 * @param {string} $qty 219 * @param {string|undefined} $customPrice 220 * @returns {jQuery|null} 221 * @private 222 */ 223 DynamicPrice.prototype.__update = function ($qty, $customPrice = undefined) { 224 225 if (typeof $qty === 'undefined' || !$qty) { 226 logError("Empty qty"); 227 return null; 228 } else { 229 $qty = parseFloat($qty); 230 } 231 232 if (wdp_script_data_pro.highlight_range_qty_changed) { 233 this.__highlightRange($qty); 234 } 235 236 if (!this.__isEnable) { 237 return null; 238 } 239 240 if (typeof $customPrice === 'undefined') { 241 $customPrice = null; 242 } 243 244 var $existTotalPriceDestinations = []; 245 jQuery.each(this.__total_price_destinations, function (_, $selector) { 246 var $el = jQuery($selector).first(); 247 if ($el.length !== 0) { 248 $existTotalPriceDestinations.push($el); 249 } 250 }); 251 252 253 var $productId = this.__getProductId(); 254 if (!$productId) { 255 replaceDestinations($existTotalPriceDestinations, ''); 256 257 logError("Empty product ID"); 258 return null; 259 } 260 261 var $existPriceDestinations = []; 262 jQuery.each(this.__price_destinations, function (_, $selector) { 263 var $el = jQuery($selector).first(); 264 if ($el.length !== 0) { 265 $existPriceDestinations.push($el); 266 } 267 }); 268 269 var $existSubtotalDestinations = []; 270 jQuery.each(this.__subtotal_destinations, function (_, $selector) { 271 var $el = jQuery($selector).first(); 272 if ($el.length !== 0) { 273 $existSubtotalDestinations.push($el); 274 } 275 }); 276 277 278 if ($existPriceDestinations.length === 0 && $existSubtotalDestinations.length === 0 && $existTotalPriceDestinations.length === 0) { 279 return null; 280 } 281 282 var data = { 283 action: 'get_price_product_with_bulk_table', 284 product_id: $productId, 285 attributes: this.__getVariationAttributes(), 286 qty: $qty, 287 page_data: this.__pageData, 288 ...jQuery('form.cart').triggerHandler('wdp_get_custom_data') 289 }; 290 291 data[wdp_script_data_pro.security_param] = wdp_script_data_pro.security; 292 293 var $spinner_price = "<div id=\"spinner_price\"><img class=\"spinner_img\"></div>"; 294 var pricePreloaded = false; 295 296 if ($customPrice !== null) { 297 data.custom_price = $customPrice; 298 } else { 299 var $price_html = this.__tryToGetPreLoadedPrice($productId, $qty); 300 if ($price_html) { 301 replaceDestinations($existPriceDestinations, $price_html); 302 303 if ($existSubtotalDestinations.length === 0 && $existTotalPriceDestinations.length === 0) { 304 return; 305 } 306 307 pricePreloaded = true; 308 } 309 } 310 311 if (this.__show_spinner) { 312 if (!pricePreloaded) { 313 replaceDestinations($existPriceDestinations, $spinner_price); 314 } 315 replaceDestinations($existSubtotalDestinations, $spinner_price); 316 replaceDestinations($existTotalPriceDestinations, $spinner_price); 317 } 318 319 data.addons = this.__addons_supplier(); 320 this.__cachePrice = null; 321 return jQuery.ajax({ 322 url: this.__ajaxUrl, 323 data: data, 324 dataType: 'json', 325 type: 'POST', 326 success: (response) => { 327 if (response.success) { 328 if (!pricePreloaded) { 329 replaceDestinations($existPriceDestinations, response.data.price_html); 330 this.__cachePrice = response.data.price_html; 331 //do it directly if event show_variation already done 332 setTimeout(function () {
333 dynamicPrices.forEach(function (dynamicPrice) { 334 if (dynamicPrice.form[0] !== undefined) { 335 dynamicPrice.__show() 336 } 337 }); 338 }, 0); 339 340 } 341 replaceDestinations($existSubtotalDestinations, response.data.subtotal_html); 342 replaceDestinations($existTotalPriceDestinations, response.data.total_price_html); 343 344 if (response.data.external_plugins) { 345 response.data.external_plugins.forEach((external_plugin) => { 346 if (external_plugin.destination && external_plugin.html) 347 jQuery(external_plugin.destination).replaceWith(external_plugin.html); 348 }) 349 } 350 } else { 351 if (!pricePreloaded) { 352 clearDestinations($existPriceDestinations); 353 } 354 clearDestinations($existSubtotalDestinations); 355 clearDestinations($existTotalPriceDestinations); 356 } 357 }, 358 error: function (response) { 359 if (!pricePreloaded) { 360 clearDestinations($existPriceDestinations); 361 } 362 clearDestinations($existSubtotalDestinations); 363 clearDestinations($existTotalPriceDestinations); 364 } 365 }); 366 }; 367 DynamicPrice.prototype.__show = function () { 368 if (this.__cachePrice) { 369 var $existPriceDestinations = []; 370 jQuery.each(this.__price_destinations, function (_, $selector) { 371 var $el = jQuery($selector).first(); 372 if ($el.length !== 0) { 373 $existPriceDestinations.push($el); 374 } 375 }); 376 377 replaceDestinations($existPriceDestinations, this.__cachePrice); 378 this.__cachePrice = null; 379 } 380 }; 381 382 DynamicPrice.prototype.__highlightRange = function ($qty) { 383 var $productContainer = this.form.closest('.product'); 384 var $table = $productContainer.find('.bulk_table .wdp_pricing_table tbody'); 385 if (!$table.length) return; 386 $qty = parseFloat($qty); 387 388 $table.find('tr td').each(function () { 389 this.style.setProperty('background-color', ''); 390 this.style.setProperty('color', ''); 391 }); 392 393 $table.find('tr').each(function () { 394 var $row = jQuery(this); 395 var rangeText = $row.find('td').first().text().trim(); 396 var match = rangeText.match(/(\d+)(?:\s*-\s*(\d+))?/); 397 398 if (match) { 399 var from = parseFloat(match[1]); 400 var to = match[2] ? parseFloat(match[2]) : Infinity; 401 402 if ($qty >= from && $qty <= to) { 403 $row.find('td').each(function () { 404 this.style.setProperty('background-color', wdp_script_data_pro.higlight_background_color, 'important'); 405 this.style.setProperty('color', wdp_script_data_pro.higlight_text_color, 'important'); 406 }); 407 } 408 } 409 }); 410 }; 411 412 DynamicPrice.prototype.__clearTotalPrice = function () { 413 var $existTotalPriceDestinations = []; 414 jQuery.each(this.__total_price_destinations, function (_, $selector) { 415 var $el = jQuery($selector).first(); 416 if ($el.length !== 0) { 417 $existTotalPriceDestinations.push($el); 418 } 419 }); 420 421 var $productId = this.__getProductId(); 422 423 if (!$productId) { 424 replaceDestinations($existTotalPriceDestinations, ''); 425 } 426 }; 427 428 DynamicPrice.prototype.__tryToGetPreLoadedPrice = function ($productId, $qty) { 429 if (typeof wdp_script_data_pro.preLoaded === 'undefined') { 430 return null; 431 } 432 433 var $preLoaded = wdp_script_data_pro.preLoaded; 434 435 $qty = parseFloat($qty); 436 if (!$qty) { 437 return null; 438 } 439 440 $productId = $productId.toString(); 441 442 var _this = this; 443 444 var $html = null;
445 jQuery.each($preLoaded, function ($preLoadedProductId, $data) { 446 if (typeof $data.ranges === 'undefined' || typeof $data.price_html === 'undefined' || typeof $data.price_html_view === 'undefined' || typeof $data.index_number === 'undefined') { 447 return; // continue 448 } 449 var $ranges = $data.ranges; 450 var $price_html = $data.price_html; 451 var $current_qty = $data.index_number + $qty; 452 var $qty_already_in_cart = $data.qty_already_in_cart; 453 454 if ($preLoadedProductId === $productId) { 455 jQuery.each($ranges, function (_, $range) { 456 if (compareFloats($range['from'], '<=', $current_qty) && compareFloats($current_qty, '<=', $range['to']) 457 || (compareFloats($range['from'], '<=', $current_qty) && $range['to'] === "") 458 || ($range['from'] === "" && compareFloats($current_qty, '<=', $range['to'])) 459 ) { 460 $html = _this.__formatPriceHtml($range['striked_price_html'], $current_qty, $qty_already_in_cart, $range['regular_price_striked']); 461 return false; 462 } 463 }); 464 465 if (!$html) { 466 if ($current_qty === 1) { 467 $html = $data.price_html_view; 468 } else { 469 $html = _this.__formatPriceHtml($price_html, $current_qty, $qty_already_in_cart, ""); 470 } 471 } 472 } 473 if ($html) { 474 return false; 475 } 476 }); 477 478 return $html; 479 }; 480 481 function compareFloats($a, $op, $b) { 482 $a = Math.floor(parseFloat($a) * 100); 483 $b = Math.floor(parseFloat($b) * 100); 484 485 switch ($op) { 486 case "=": 487 return $a === $b; 488 case ">": 489 return $a > $b; 490 case ">=": 491 return $a >= $b; 492 case "<": 493 return $a < $b; 494 case "<=": 495 return $a <= $b; 496 } 497 498 return null; 499 } 500 501 function replaceDestinations($targets, $priceHtml) { 502 jQuery.each($targets, function (_, $target) { 503 $target.html($priceHtml); 504 jQuery(document).trigger('wdp_price_product_updated', $priceHtml); 505 506 var $wapfTotals = jQuery(".wapf-product-totals"); 507 if ($wapfTotals.length && $priceHtml) { 508 var temp = document.createElement("div"); 509 temp.innerHTML = $priceHtml; 510 var insEl = temp.querySelector("ins .woocommerce-Price-amount"); 511 var priceText = insEl ? insEl.textContent : temp.textContent; 512 var numericPrice = priceText.replace(/[^0-9,.\-]/g, "").replace(",", "."); 513 var priceValue = parseFloat(numericPrice); 514 515 if (!isNaN(priceValue)) { 516 $wapfTotals.data("product-price", priceValue); 517 518 var $form = jQuery(".wapf-wrapper").closest("form.cart"); 519 var $qtyInput = $form.find("input.qty"); 520 if ($qtyInput.length) { 521 $qtyInput.each(function() { 522 var val = jQuery(this).val(); 523 jQuery(this).val(val).trigger("change"); 524 }); 525 } 526 } 527 } 528 }) 529 } 530 531 DynamicPrice.prototype.clickableBulkRows = function () { 532 if (!wdp_script_data_pro.clickable_bulk_rows) { 533 return 534 } 535 536 let $table = jQuery('.bulk_table .wdp_pricing_table'); 537 let $input = jQuery('input[name="quantity"]'); 538 if (!$table || !$input || $table.data('measurement') !== 'qty' || $table.data('layout') !== 'verbose') return 539 540 // let $targets = $table.data('layout') === 'verbose' ? $table.find('tbody tr') : $table.find('thead td'); 541 let $targets = $table.find('tbody tr'); 542 543 $targets.addClass('clickable_bulk'); 544 $targets.css('--highlight-range-bg', wdp_script_data_pro.higlight_background_color); 545 $targets.css('--highlight-range-text', wdp_script_data_pro.higlight_text_color); 546 $targets.each((i) => { 547 jQuery($targets[i]).on('click', () => { 548 let $target = jQuery($targets[i]); 549 let min = $target.data('min'); 550 $input.val(min); 551 $target.find('[type="radio"]').prop("checked", true); 552 $targets.removeClass('wdp_selected_row'); 553 $target.addClass('wdp_selected_row'); 554 }) 555 }) 556 } 557 558 function clearDestinations($targets) { 559 jQuery.each($targets, function (_, $target) { 560 $target.html(""); 561 jQuery(document).trigger('wdp_price_product_updated', ""); 562 }) 563 } 564 565 DynamicPrice.prototype.addPriceDestination = function ($dest) { 566 if (typeof $dest === 'string') { 567 this.__price_destinations.push($dest); 568 } else if (Array.isArray($dest)) { 569 Array.prototype.push.apply(this.__price_destinations, $dest); 570 } 571 }; 572 573 DynamicPrice.prototype.addSubtotalDestination = function ($dest) { 574 if (typeof $dest === 'string') { 575 this.__subtotal_destinations.push($dest); 576 } else if (Array.isArray($dest)) { 577 Array.prototype.push.apply(this.__subtotal_destinations, $dest); 578 } 579 }; 580 581 DynamicPrice.prototype.addTotalPriceDestination = function ($dest) { 582 if (typeof $dest === 'string') { 583 this.__total_price_destinations.push($dest); 584 } else if (Array.isArray($dest)) { 585 Array.prototype.push.apply(this.__total_price_destinations, $dest); 586 } 587 }; 588 589 /** 590 * 591 * @param {function(): {price: number, value: string}[]} callback 592 */ 593 DynamicPrice.prototype.withAddonsSupplier = function (callback) { 594 this.__addons_supplier = callback; 595 }; 596
597 DynamicPrice.prototype.update = function ($args) { 598 var $qty = null; 599 var $customPrice = null; 600 601 if (typeof $args !== 'undefined') { 602 if (typeof $args.qty !== 'undefined') { 603 $qty = parseFloat($args.qty); 604 } else { 605 $qty = this.__getQty(); 606 } 607 608 if (typeof $args.custom_price !== 'undefined') { 609 $customPrice = $args.custom_price; 610 } 611 } 612 613 return this.__update($qty, $customPrice); 614 }; 615 616 617 DynamicPrice.prototype.disable = function () { 618 this.__isEnable = false; 619 }; 620 621 DynamicPrice.prototype.enable = function () { 622 this.__isEnable = true; 623 }; 624 625 DynamicPrice.prototype.__formatPriceHtml = function ($priceHtml, $indexNumber, $qtyAlreadyInCart, regularPriceStriked) { 626 return this.__priceHtmlTemplate 627 .replace("{{price_html}}", $priceHtml) 628 .replace("{{Nth_item}}", addSuffixOf($indexNumber)) 629 .replace("{{qty_already_in_cart}}", $qtyAlreadyInCart) 630 .replace("{{price_suffix}}", this.__priceSuffix) 631 .replace("{{regular_price_striked}}", regularPriceStriked); 632 }; 633 634 function addSuffixOf($value) { 635 var mod10 = $value % 10, 636 mod100 = $value % 100; 637 638 if (mod10 === 1 && mod100 !== 11) { 639 return $value + "st"; 640 } 641 if (mod10 === 2 && mod100 !== 12) { 642 return $value + "nd"; 643 } 644 if (mod10 === 3 && mod100 !== 13) { 645 return $value + "rd"; 646 } 647 return $value + "th"; 648 } 649 650 function logError($text) { 651 console.error("DynamicPrice error: %s", $text); 652 } 653 654 return DynamicPrice; 655})(); 656 657var dynamicPrices = []; 658 659function createDynamicPrice() { 660 var dynamicPrices = []; 661 662 jQuery('form.cart').each(function () { 663 var $form = jQuery(this); 664 var isVariation = $form.hasClass("variations_form"); 665 var $targets = []; 666 var $productId = $form.find('[name="add-to-cart"]').val(); 667 668 if (!$productId) { 669 return false; 670 } 671 672 if (isVariation) { 673 $targets.push('.product.post-' + $productId + ' .woocommerce-variation-price .price'); 674 675 if (wdp_script_data_pro.replace_variable_price) { 676 $targets.push('.product.post-' + $productId + ' ' + wdp_script_data_pro.variable_price_selector); 677 } 678 } else { 679 $targets.push('.product.post-' + $productId + ' .price'); 680 } 681 682 var optFirst = Object.assign({}, wdp_script_data_pro); 683 optFirst.dynamic_price_enable = true; 684 var dynamicPrice = new DynamicPrice($form, optFirst); 685 686 if (optFirst.update_price_with_qty === "1") { 687 dynamicPrice.addPriceDestination($targets); 688 } 689 690 dynamicPrice.addTotalPriceDestination(["div.adp-total-price"]); 691 692 dynamicPrice.observe(); 693 dynamicPrices.push(dynamicPrice); 694 }); 695 696 return dynamicPrices; 697} 698 699if (wdp_script_data_pro.js_init_trigger) { 700 jQuery(document).on(wdp_script_data_pro.js_init_trigger, function () { 701 dynamicPrices = createDynamicPrice(); 702 }); 703} 704 705if (wdp_script_data_pro.create_on_load) { 706 jQuery(document).ready(function () { 707 dynamicPrices = createDynamicPrice(); 708 709 jQuery('.variations_form').on('found_variation', { variationForm: this }, 710 function (event, variation) { 711 if (typeof variation !== 'undefined') { 712 setTimeout(function () { 713 dynamicPrices.forEach(function (dynamicPrice) { 714 if (dynamicPrice.form[0] !== undefined && dynamicPrice.form[0] === event.target) { 715 dynamicPrice.__update(dynamicPrice.__getQty()) 716 } 717 }); 718 }, 0); 719 } 720 721 return true; 722 }); 723 724 jQuery('.variations_form').on('show_variation', { variationForm: this }, 725 function (event, variation) { 726 if (typeof variation !== 'undefined') { 727 setTimeout(function () {
728 dynamicPrices.forEach(function (dynamicPrice) { 729 if (dynamicPrice.form[0] !== undefined) { 730 dynamicPrice.__show() 731 } 732 }); 733 }, 0); 734 } 735 736 return true; 737 }); 738 739 jQuery('.wdp_bulk_table_content').on('update', () => { 740 DynamicPrice.prototype.clickableBulkRows() 741 return true; 742 }); 743 744 jQuery('form.cart').on('adp_found_variation', function () { 745 setTimeout(function () { 746 dynamicPrices.forEach(function (dynamicPrice) { 747 if (dynamicPrice.form[0] !== undefined) { 748 dynamicPrice.__update(dynamicPrice.__getQty()) 749 } 750 }); 751 }, 0); 752 return true; 753 }); 754 755 jQuery('.variations_form').on('reset_data', { variationForm: this }, 756 function (event) { 757 setTimeout(function () { 758 dynamicPrices.forEach(function (dynamicPrice) { 759 if (dynamicPrice.form[0] !== undefined && dynamicPrice.form[0] === event.target) { 760 dynamicPrice.__clearTotalPrice(); 761 } 762 }); 763 764 }, 0); 765 766 return true; 767 }); 768 769 jQuery(document).ajaxComplete(function(event, xhr, settings) { 770 if (settings.url.indexOf('remove_from_cart') !== -1) { 771 setTimeout(function () { 772 if (typeof dynamicPrices !== 'undefined' && Array.isArray(dynamicPrices) && dynamicPrices.length) { 773 dynamicPrices.forEach(function (dynamicPrice) { 774 if (dynamicPrice.form[0] !== undefined) { 775 dynamicPrice.__update(dynamicPrice.__getQty()) 776 } 777 }); 778 } 779 }, 0); 780 } 781 }); 782 }); 783}
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.