1var NetDania = NetDania || {}; 2NetDania.QL = NetDania.QL || {}; 3NetDania.QL.Util = NetDania.QL.Util || {}; 4 5 6NetDania.QL.getRecordById = function (records, id) { 7 for (var k = 0; k < records.length; k++) { 8 if (records[k].id === id) { 9 return records[k]; 10 } 11 } 12 return undefined; 13} 14 15 16NetDania.QL.refreshCell = function (grid, rec, cellid, val, oldval, fxy) { 17 18 var cell = document.getElementById(cellid); 19 if (cell !== null && val != oldval) { 20 21 var torender = '<div>' + val + '</div>'; 22 if (grid.renderers[fxy] !== undefined) { 23 torender = grid.renderers[fxy].fn(grid, rec, cellid, val, oldval, fxy); 24 } 25 26 cell.innerHTML = torender; 27 28 if (grid.renderers[fxy] !== undefined && grid.renderers[fxy].hightlightInterval !== undefined) { 29 // only reset column f11 30 if(cellid.substr(-2)=='11'){ 31 setTimeout(function () { 32 NetDania.QL.Util.resetHighlight(cellid); 33 }, grid.renderers[fxy].hightlightInterval); 34 } 35 } 36 } 37} 38 39NetDania.QL.receiveQuotesJsonData = function (updateObject, grid) { 40 var id = updateObject.id; 41 var record = NetDania.QL.getRecordById(grid.records, "recid-" + grid.id + "-" + id); 42 record.compute.updatePrice(updateObject); 43}; 44 45NetDania.QL.Util.dateFormat = function () { 46 var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g, 47 timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[\-+]\d{4})?)\b/g, 48 timezoneClip = /[^\-+\dA-Z]/g, 49 pad = function (val, len) { 50 val = String(val); 51 len = len || 2; 52 while (val.length < len) { 53 val = "0" + val; 54 } 55 return val; 56 }; 57 58 // Regexes and supporting functions are cached through closure 59 return function (date, mask, utc) { 60 var dF = NetDania.QL.Util.dateFormat; 61 62 // You can't provide utc if you skip other args (use the "UTC:" mask prefix) 63 if (arguments.length == 1 && (typeof date == "string" || date instanceof String) && !/\d/.test(date)) { 64 mask = date; 65 date = undefined; 66 } 67 68 // Passing date through Date applies Date.parse, if necessary 69 date = date ? new Date(date) : new Date(); 70 if (isNaN(date)) { 71 throw new SyntaxError("invalid date"); 72 } 73 74 mask = String(dF.masks[mask] || mask || dF.masks["default"]); 75 76 // Allow setting the utc argument via the mask 77 if (mask.slice(0, 4) == "UTC:") { 78 mask = mask.slice(4); 79 utc = true; 80 } 81 82 var _ = utc ? "getUTC" : "get", 83 d = date[_ + "Date"](), 84 D = date[_ + "Day"](), 85 m = date[_ + "Month"](), 86 y = date[_ + "FullYear"](), 87 H = date[_ + "Hours"](), 88 M = date[_ + "Minutes"](), 89 s = date[_ + "Seconds"](), 90 L = date[_ + "Milliseconds"](), 91 o = utc ? 0 : date.getTimezoneOffset(), 92 flags = { 93 d: d, 94 dd: pad(d), 95 ddd: dF.i18n.dayNames[D], 96 dddd: dF.i18n.dayNames[D + 7], 97 m: m + 1, 98 mm: pad(m + 1), 99 mmm: dF.i18n.monthNames[m], 100 mmmm: dF.i18n.monthNames[m + 12], 101 yy: String(y).slice(2), 102 yyyy: y, 103 h: H % 12 || 12, 104 hh: pad(H % 12 || 12), 105 H: H, 106 HH: pad(H), 107 M: M, 108 MM: pad(M), 109 s: s, 110 ss: pad(s), 111 l: pad(L, 3), 112 L: pad(L > 99 ? Math.round(L / 10) : L), 113 t: H < 12 ? "a" : "p", 114 tt: H < 12 ? "am" : "pm", 115 T: H < 12 ? "A" : "P", 116 TT: H < 12 ? "AM" : "PM", 117 Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""), 118 o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4), 119 S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10] 120 }; 121 122 return mask.replace(token, function ($0) { 123 return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1); 124 }); 125 }; 126}(); 127
128// Some common format strings 129NetDania.QL.Util.dateFormat.masks = { 130 "default": "ddd mmm dd yyyy HH:MM:ss", 131 shortDate: "m/d/yy", 132 mediumDate: "mmm d, yyyy", 133 longDate: "mmmm d, yyyy", 134 fullDate: "dddd, mmmm d, yyyy", 135 shortTime: "h:MM TT", 136 mediumTime: "h:MM:ss TT", 137 longTime: "h:MM:ss TT Z", 138 isoDate: "yyyy-mm-dd", 139 isoTime: "HH:MM:ss", 140 isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", 141 isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" 142}; 143 144// Internationalization strings 145NetDania.QL.Util.dateFormat.i18n = { 146 dayNames: [ 147 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 148 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" 149 ], 150 monthNames: [ 151 "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 152 //"Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November", "December" 153 "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
153November", "December" 154 155 ] 156}; 157 158NetDania.QL.Util.isInArray = function (val, arr) { 159 var isInArr = false; 160 for (i = 0; i < arr.length; i++) { 161 if (arr[i] == val) { 162 isInArr = true; 163 break; 164 } 165 } 166 return isInArr; 167}; 168 169 170NetDania.QL.Util.resetColor = function (spanid) { 171 return false; 172 var span = document.getElementById(spanid); 173 if (span) { 174 for (var i = 0; i < span.children.length; i++) { 175 span.children[i].style.color = ''; 176 } 177 } 178}; 179 180NetDania.QL.Util.resetHighlight = function (spanid) { 181 182 var span = document.getElementById(spanid); 183 if (span !== null) { 184 185 for (var i = 0; i < span.children.length; i++) { 186 span.children[i].style.backgroundColor = 'transparent'; 187 } 188 189 setTimeout(function () { 190 NetDania.QL.Util.resetColor(spanid); 191 }, 500); 192 } else { 193 194 } 195}; 196 197NetDania.QL.Util.generateChars = function (length) { 198 var chars = ''; 199 200 for (var i = 0; i < length; i++) { 201 var randomChar = Math.floor(Math.random() * 36); 202 chars += randomChar.toString(36); 203 } 204 205 return chars; 206}; 207 208NetDania.QL.Util.isNumber = function (n) { 209 return !isNaN(parseFloat(n)) && isFinite(n); 210}; 211 212NetDania.QL.Util.removeLastDecimalPoint = function (val) { 213 if (val.substr(val.length - 1, val.length - 1) === '.') { 214 return val.substr(0, val.length - 1); 215 } 216 return val; 217}; 218 219 220// Sets cookie values. Expiration date is optional // 221NetDania.QL.Util.setCookie = function (name, value, expire) { 222 document.cookie = name + "=" + escape(value) + ((expire == null) ? "" : ("; expires=" + expire.toGMTString())); 223}; 224 225// Returns the value of the cookie with the given name // 226// this fixes an issue with the old method, ambiguous values 227// with this test document.cookie.indexOf( name + "=" ); 228NetDania.QL.Util.getCookie = function (check_name) { 229 // first we'll split this cookie up into name/value pairs 230 // note: document.cookie only returns name=value, not the other components 231 var a_all_cookies = document.cookie.split(';'); 232 var a_temp_cookie = ''; 233 var cookie_name = ''; 234 var cookie_value = ''; 235 var b_cookie_found = false; // set boolean t/f default f 236 237 for (i = 0; i < a_all_cookies.length; i++) { 238 // now we'll split apart each name=value pair 239 a_temp_cookie = a_all_cookies[i].split('='); 240 241 242 // and trim left/right whitespace while we're at it 243 cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, ''); 244 245 // if the extracted name matches passed check_name 246 if (cookie_name == check_name) { 247 b_cookie_found = true; 248 // we need to handle case where cookie has no value but exists (no = sign, that is): 249 if (a_temp_cookie.length > 1) { 250 cookie_value = unescape(a_temp_cookie[1].replace(/^\s+|\s+$/g, '')); 251 } 252 // note that in cases where cookie is initialized but no value, null is returned 253 return cookie_value; 254 break; 255 } 256 a_temp_cookie = null; 257 cookie_name = ''; 258 } 259 if (!b_cookie_found) { 260 return null; 261 } 262}; 263 264NetDania.QL.Util.HashCode = function(s){ 265 var hash = 0; 266 var i; 267 var charH; 268 if (s.length == 0) return hash; 269 for (i = 0, l = s.length; i < l; i++) { 270 charH = s.charCodeAt(i); 271 hash = ((hash<<5)-hash)+charH; 272 hash |= 0; // Convert to 32bit integer 273 } 274 return Math.abs(hash); 275}; 276 277 278/** 279 * . 280 */ 281 282(function (global) { 283 'use strict'; 284 285 /** 286 * 287 * @type {*|{}} 288 */ 289 global.NetDania = global.NetDania || {}; 290 291 /** 292 * 293 * @type {*|{}} 294 */ 295 global.NetDania.Java = global.NetDania.Java || {}; 296 297 /** 298 * 299 * @type {*|{}} 300 */ 301 global.NetDania.Java.Util = global.NetDania.Java.Util || {}; 302 303 304 /** 305 * 306 */ 307 var Util = global.NetDania.Java.Util; 308 309 /** 310 * 311 * @param opts 312 * @class Map 313 * @constructor 314 */ 315 var Map = function () { 316 this.keys = []; 317 this.data = []; 318 this.dataOld = []; 319 }; 320 321 Map.prototype.put = function (key, value) { 322 if (this.data[key] == null) { 323 this.keys.push(key); 324 } 325 this.dataOld[key] = this.data[key]; 326 this.data[key] = value; 327 }; 328 329 Map.prototype.get = function (key) { 330 var v = this.data[key]; 331 if (v == null || v === undefined) { 332 return null 333 } else { 334 return v; 335 } 336 }; 337 338 Map.prototype.getOld = function (key) { 339 var v = this.dataOld[key]; 340 if (v == null || v === undefined) { 341 return null 342 } else { 343 return v; 344 } 345 }; 346 347 Map.prototype.remove = function (key) { 348 this.keys.splice(key, 1); 349 this.data.splice(key, 1); 350 this.dataOld.splice(key, 1); 351 }; 352 353 Map.prototype.each = function (fn) { 354 if (typeof fn !== 'function') { 355 return; 356 } 357 var len = this.keys.length; 358 for (var i = 0; i < len; i++) { 359 var k = this.keys[i]; 360 fn(k, this.data[k], i); 361 } 362 }; 363 364 Map.prototype.entrySet = function () { 365 var len = this.keys.length; 366 var entrys = new Array(len); 367 for (var i = 0; i < len; i++) { 368 entrys[i] = { 369 key: this.keys[i], 370 value: this.data[i] 371 }; 372 } 373 return entrys; 374 }; 375 376 Map.prototype.isEmpty = function () { 377 return this.size() == 0; 378 }; 379 380 Map.prototype.size = function () { 381 return this.keys.length; 382 }; 383 384 Map.Entry = function(key, value) { 385 this.key = key; 386 this.value = value; 387 }; 388 389 Map.Entry.prototype.getKey = function() { 390 return this.key; 391 }; 392 393 Map.Entry.prototype.getValue = function() { 394 return this.value; 395 }; 396 397 Util.Map = Map; 398 399})(window); 400 401(function (global) { 402 ("use strict"); 403 404 /** 405 * 406 * @type {*|{}} 407 */ 408 global.NetDania = global.NetDania || {}; 409 410 /** 411 * 412 * @type {*|{}} 413 */ 414 global.NetDania.QL = global.NetDania.QL || {}; 415 416 /** 417 * 418 * @type {*|{}} 419 */ 420 global.NetDania.QL.Util = global.NetDania.QL.Util || {}; 421 422 /** 423 * 424 */ 425 var util = global.NetDania.QL.Util; 426 427 /** 428 * 429 * @param opts 430 * @class Integer 431 * @constructor 432 */ 433 var ComputedQuoteRow = function (id, grid) { 434 this.price = new NetDania.Java.Util.Map(); 435 436 this.grid = grid; 437 this.columns = grid.columns; 438 this.id = id; 439 }; 440 441 /** 442 * Updates defined columns 443 */ 444 ComputedQuoteRow.prototype.updateDefinedCols = function() { 445 446 for (const column in this.columns) { 447 var text = this.price.get(column.replace('f','')); 448 if (text == null) { 449 text = "N/A"; 450 } 451 452 var oldtext = this.price.getOld(column.replace('f','')); 453 if (oldtext == null) { 454 oldtext = undefined; 455 } 456 457 var r = NetDania.QL.getRecordById(this.grid.records, this.id); 458 NetDania.QL.refreshCell(this.grid, r, this.id + '-' + column, text, oldtext, column); 459 } 460 } 461 462 ComputedQuoteRow.prototype.updatePrice = function ( 463 priceResponse 464 ) {
465 if (priceResponse == null) { 466 this.setAllFieldsNA(); 467 this.updateDefinedCols(); 468 return; 469 } 470 471 472 var SwsFields = NetDania.JsApi.Fields; 473 474 var availableIDs = priceResponse.getFIDs(); 475 var n = availableIDs.length; 476 477 var t; 478 for (var i = 0; i < n; i++) { 479 if (availableIDs[i] == SwsFields.QUOTE_NAME) { 480 continue; 481 } 482 if (availableIDs[i] == SwsFields._QUOTE_SYMBOL) { 483 continue; 484 } 485 486 t = priceResponse.get(availableIDs[i]); 487 if (t !== "N/A") { 488 this.price.put(availableIDs[i], t); 489 continue; 490 } 491 if (availableIDs[i] == SwsFields.QUOTE_TIME_STAMP) { 492 this.price.put(availableIDs[i], t); 493 continue; 494 } 495 496 this.price.put(availableIDs[i], t); 497 } 498 this.calcSpecialFields(); 499 this.updateDefinedCols(); 500 }; 501 502 /** 503 * Returns the numeric value of this string, or 504 * the special NaN value if the string cannot be converted, 505 * or if it is null. 506 */ 507 ComputedQuoteRow.prototype.getValue = function (s, field) { 508 if (s == null) { 509 return Number.NaN; 510 } 511 try { 512 return parseFloat(s); 513 } catch (ex) { 514 return Number.NaN; 515 } 516 }; 517 518 /** 519 * Formats a double to a String. 520 * The returned string will not contain any grouping digits, 521 * so it can be used in example in the Double.valueOf(String) 522 * method afterwards. An algorithm is used to determine the best 523 * number of decimal digits on the returned price value. 524 */ 525 ComputedQuoteRow.prototype.format = function (price) { 526 if (isNaN(price)) { 527 return "N/A"; 528 } 529 var d = Math.abs(price); 530 531 return price.toString(); 532 }; 533 534 /** 535 * Sets all fields value for the instrument with "N/A" 536 */ 537 /* 538 ComputedQuoteRow.prototype.setAllFieldsNA = function() { 539 for (Short s : price.keySet()) { 540 this.price.put(s, "N/A"); 541 } 542 }*/ 543 544 /** 545 * Calculates other fields such as "Change" and "% Change". 546 * This method should be called whenever a price update has occurred for an instrument. 547 */ 548 ComputedQuoteRow.prototype.calcSpecialFields = function () { 549 var SwsFields = NetDania.JsApi.Fields; 550 551 // Get last 552 var last = this.getValue(this.price.get(SwsFields.QUOTE_LAST)); 553 if (isNaN(last)) { 554 last = this.getValue(this.price.get(SwsFields.QUOTE_BID)); // get bid 555 } 556 // Get close 557 var close = this.getValue(this.price.get(SwsFields.QUOTE_CLOSE)); 558 if (!isNaN(last) && !isNaN(close)) { 559 // Calculate Change and % Change 560 var change = last - close; 561 var percentChange = (change * 100) / close; 562 this.price.put(SwsFields._QUOTE_CHANGE, this.format(change)); 563 this.price.put(SwsFields._QUOTE_PERCENT_CHANGE, this.format(percentChange)); 564 } 565 // Get previous year close 566 var prvYrClose = this.getValue(this.price.get(SwsFields.QUOTE_PRV_YEAR_CLOSE)); 567 if (!isNaN(last) && !isNaN(prvYrClose)) { 568 // Calculate Year Change and % Change 569 var yrChange = last - prvYrClose; 570 var yrPercentChange = (yrChange * 100) / prvYrClose; 571 this.price.put(SwsFields._QUOTE_YEAR_CHANGE, this.format(yrChange)); 572 this.price.put(SwsFields._QUOTE_YEAR_PERCENT_CHANGE,this.format(yrPercentChange)); 573 } 574 // Get closing price 1 Week ago 575 var oneWeekClose = this.getValue( 576 this.price.get(SwsFields.QUOTE_1WEEK_CLOSE) 577 ); 578 if (!isNaN(last) && !isNaN(oneWeekClose)) { 579 // Calculate 1 Week Change and % Change 580 var weekChange = last - oneWeekClose; 581 var weekPercentChange = (weekChange * 100) / oneWeekClose; 582 this.price.put(SwsFields._QUOTE_1WEEK_CHANGE, this.format(weekChange)); 583 this.price.put( 584 SwsFields._QUOTE_1WEEK_PERCENT_CHANGE, 585 this.format(weekPercentChange) 586 ); 587 } 588 // Get closing price 1 Month ago 589 var oneMonthClose = this.getValue( 590 this.price.get(SwsFields.QUOTE_1MONTH_CLOSE) 591 ); 592 if (!isNaN(last) && !isNaN(oneMonthClose)) { 593 // Calculate 1 Month Change and % Change 594 var monthChange = last - oneMonthClose;
595 var monthPercentChange = (monthChange * 100) / oneMonthClose; 596 this.price.put( 597 SwsFields._QUOTE_1MONTH_CHANGE, 598 this.format(monthChange) 599 ); 600 this.price.put( 601 SwsFields._QUOTE_1MONTH_PERCENT_CHANGE, 602 this.format(monthPercentChange) 603 ); 604 } 605 // Get closing price 3 Months ago 606 var threeMonthClose = this.getValue( 607 this.price.get(SwsFields.QUOTE_3MONTH_CLOSE) 608 ); 609 if (!isNaN(last) && !isNaN(threeMonthClose)) { 610 // Calculate 3 Months Change and % Change 611 var month3Change = last - threeMonthClose; 612 var month3PercentChange = (month3Change * 100) / threeMonthClose; 613 this.price.put( 614 SwsFields._QUOTE_3MONTH_CHANGE, 615 this.format(month3Change) 616 ); 617 this.price.put( 618 SwsFields._QUOTE_3MONTH_PERCENT_CHANGE, 619 this.format(month3PercentChange) 620 ); 621 } 622 // Get closing price 12 Months ago 623 var oneYrClose = this.getValue( 624 this.price.get(SwsFields.QUOTE_1YEAR_CLOSE) 625 ); 626 if (!isNaN(last) && !isNaN(oneYrClose)) { 627 // Calculate 12 Months Change and % Change 628 var oneYrChange = last - oneYrClose; 629 var oneYrPercentChange = (oneYrChange * 100) / oneYrClose; 630 this.price.put(SwsFields._QUOTE_1YEAR_CHANGE, this.format(oneYrChange)); 631 this.price.put( 632 SwsFields._QUOTE_1YEAR_PERCENT_CHANGE, 633 this.format(oneYrPercentChange) 634 ); 635 } 636 // Get EPS and calc P/E 637 var eps = this.getValue( 638 this.price.get(SwsFields.QUOTE_EARN_PER_SHARE) 639 ); 640 if (!isNaN(last) && !isNaN(eps) && eps > 0) { 641 this.price.put( 642 SwsFields._QUOTE_PRICE_PER_EARN, 643 this.format(last / eps) 644 ); 645 } 646 // Get EPS estimated 647 var epsEst = this.getValue( 648 this.price.get(SwsFields.QUOTE_EARN_PER_SHARE_EST) 649 ); 650 if (!isNaN(last) && !isNaN(epsEst) && epsEst > 0) { 651 // Calc P/E, estimated and Earnings per price, estimated 652 this.price.put( 653 SwsFields._QUOTE_PRICE_PER_EARN_EST, 654 this.format(last / epsEst) 655 ); 656 this.price.put( 657 SwsFields._QUOTE_EARN_PER_PRICE_EST, 658 this.format((100 * epsEst) / last) 659 ); 660 } 661 // Get volume increment and calc Amount turnover (for last stock trade) 662 var volInc = this.getValue( 663 this.price.get(SwsFields.QUOTE_VOLUME_INC) 664 ); 665 if (!isNaN(last) && !isNaN(volInc)) { 666 this.price.put( 667 SwsFields._QUOTE_AMOUNT_TURNOVR, 668 this.format(last * volInc) 669 ); 670 } 671 672 // Ensure that year high and low is correct 673 var todayHigh = this.getValue( 674 this.price.get(SwsFields.QUOTE_HIGH) 675 ); 676 var todayLow = this.getValue( 677 this.price.get(SwsFields.QUOTE_LOW) 678 ); 679 var yearHigh = this.getValue( 680 this.price.get(SwsFields.QUOTE_YEAR_HIGH) 681 ); 682 var yearLow = this.getValue( 683 this.price.get(SwsFields.QUOTE_YEAR_LOW) 684 ); 685 if (!isNaN(todayHigh) && !isNaN(yearHigh) && todayHigh > yearHigh) { 686 this.price.put(SwsFields.QUOTE_YEAR_HIGH, this.format(todayHigh)); 687 } 688 if (!isNaN(todayLow) && !isNaN(yearLow) && todayLow < yearLow) { 689 this.price.put(SwsFields.QUOTE_YEAR_LOW, this.format(todayLow)); 690 } 691 // Ensure that 52 week high and low is correct 692 var week52High = this.getValue( 693 this.price.get(SwsFields.QUOTE_52W_HIGH) 694 ); 695 var week52Low = this.getValue( 696 this.price.get(SwsFields.QUOTE_52W_LOW) 697 ); 698 if (!isNaN(todayHigh) && !isNaN(week52High) && todayHigh > week52High) { 699 this.price.put(SwsFields.QUOTE_52W_HIGH, this.format(todayHigh)); 700 } 701 if (!isNaN(todayLow) && !isNaN(week52Low) && todayLow < week52Low) { 702 this.price.put(SwsFields.QUOTE_52W_LOW, this.format(todayLow)); 703 } 704 // Get the bid/ask combination field (or last instead if available) 705 var bidAsk = this.format(this.getValue(this.price.get(SwsFields.QUOTE_LAST))); 706 if (bidAsk === "N/A") { 707 var bid = this.format(this.getValue(this.price.get(SwsFields.QUOTE_BID))); 708 var ask = this.format(this.getValue(this.price.get(SwsFields.QUOTE_ASK))); 709 bidAsk = this.getBidAsk(bid, ask); 710 } 711 if (bidAsk !== "N/A") { 712 this.price.put(SwsFields._QUOTE_LAST_BID_ASK, bidAsk); 713 } 714 }; 715 716 /** 717 * Returns a combination of bid/ask as a single String. 718 */ 719 ComputedQuoteRow.prototype.getBidAsk = function(bid, ask) { 720 if (bid ==="N/A" || ask === "N/A") { 721 return bid; 722 } 723 var charsChanged = false;
724 var subBid = bid.substring(0, 1); 725 var subAsk = ask.substring(0, 1); 726 var finishAsk = "/"; 727 var i = 0; 728 var bidLength = bid.length; 729 var askLength = ask.length; 730 while (i < bidLength && i < askLength) { 731 subBid = bid.substring(i, i + 1); 732 subAsk = ask.substring(i, i + 1); 733 if (charsChanged || subBid !==subAsk) { 734 charsChanged = true; 735 finishAsk +=subAsk; 736 } 737 i++; 738 } 739 if (finishAsk !== "/") { 740 return bid + finishAsk; 741 } else { 742 return bid; 743 } 744 } 745 746 ComputedQuoteRow.class = "ComputedQuoteRow"; 747 748 util.ComputedQuoteRow = ComputedQuoteRow; 749})(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.