1/** 2 * jQuery Ripples plugin v0.6.0 / https://github.com/sirxemic/jquery.ripples 3 * MIT License 4 * @author sirxemic / https://sirxemic.com/ 5 */ 6 7!(function (e, t) { 8 "object" == typeof exports && "undefined" != typeof module 9 ? t(require("jquery")) 10 : "function" == typeof define && define.amd 11 ? define(["jquery"], t) 12 : t(e.$); 13})(this, function (e) { 14 "use strict"; 15 function t(e) { 16 return "%" == e[e.length - 1]; 17 } 18 function r(e) { 19 var t = e.split(" "); 20 if (1 !== t.length) 21 return t.map(function (t) { 22 switch (e) { 23 case "center": 24 return "50%"; 25 case "top": 26 case "left": 27 return "0"; 28 case "right": 29 case "bottom": 30 return "100%"; 31 default: 32 return t; 33 } 34 }); 35 switch (e) { 36 case "center": 37 return ["50%", "50%"]; 38 case "top": 39 return ["50%", "0"]; 40 case "bottom": 41 return ["50%", "100%"]; 42 case "left": 43 return ["0", "50%"]; 44 case "right": 45 return ["100%", "50%"]; 46 default: 47 return [e, "50%"]; 48 } 49 } 50 function i(e, t, r) { 51 function i(e, t) { 52 var r = s.createShader(e); 53 if ( 54 (s.shaderSource(r, t), 55 s.compileShader(r), 56 !s.getShaderParameter(r, s.COMPILE_STATUS)) 57 ) 58 throw new Error("compile error: " + s.getShaderInfoLog(r)); 59 return r; 60 } 61 var n = {}; 62 if ( 63 ((n.id = s.createProgram()), 64 s.attachShader(n.id, i(s.VERTEX_SHADER, e)), 65 s.attachShader(n.id, i(s.FRAGMENT_SHADER, t)), 66 s.linkProgram(n.id), 67 !s.getProgramParameter(n.id, s.LINK_STATUS)) 68 ) 69 throw new Error("link error: " + s.getProgramInfoLog(n.id)); 70 (n.uniforms = {}), 71 (n.locations = {}), 72 s.useProgram(n.id), 73 s.enableVertexAttribArray(0); 74 for ( 75 var o, a, u = /uniform (\w+) (\w+)/g, h = e + t; 76 null != (o = u.exec(h)); 77 78 ) 79 (a = o[2]), (n.locations[a] = s.getUniformLocation(n.id, a)); 80 return n; 81 } 82 function n(e, t) { 83 s.activeTexture(s.TEXTURE0 + (t || 0)), s.bindTexture(s.TEXTURE_2D, e); 84 } 85 function o(e) { 86 var t = /url\(["']?([^"']*)["']?\)/.exec(e); 87 return null == t ? null : t[1]; 88 } 89 function a(e) { 90 return e.match(/^data:/); 91 } 92 var s, 93 u = (e = e && "default" in e ? e.default : e)(window), 94 h = (function () { 95 function e(e, t) { 96 var i = "OES_texture_" + e, 97 n = i + "_linear", 98 o = n in r, 99 a = [i]; 100 return o && a.push(n), { type: t, linearSupport: o, extensions: a }; 101 } 102 var t = document.createElement("canvas"); 103 if (!(s = t.getContext("webgl") || t.getContext("experimental-webgl"))) 104 return null; 105 var r = {}; 106 if ( 107 ([ 108 "OES_texture_float", 109 "OES_texture_half_float", 110 "OES_texture_float_linear", 111 "OES_texture_half_float_linear", 112 ].forEach(function (e) { 113 var t = s.getExtension(e); 114 t && (r[e] = t); 115 }), 116 !r.OES_texture_float) 117 ) 118 return null; 119 var i = []; 120 i.push(e("float", s.FLOAT)), 121 r.OES_texture_half_float && 122 i.push(e("half_float", r.OES_texture_half_float.HALF_FLOAT_OES)); 123 var n = s.createTexture(), 124 o = s.createFramebuffer(); 125 s.bindFramebuffer(s.FRAMEBUFFER, o), 126 s.bindTexture(s.TEXTURE_2D, n), 127 s.texParameteri(s.TEXTURE_2D, s.TEXTURE_MIN_FILTER, s.NEAREST), 128 s.texParameteri(s.TEXTURE_2D, s.TEXTURE_MAG_FILTER, s.NEAREST), 129 s.texParameteri(s.TEXTURE_2D, s.TEXTURE_WRAP_S, s.CLAMP_TO_EDGE), 130 s.texParameteri(s.TEXTURE_2D, s.TEXTURE_WRAP_T, s.CLAMP_TO_EDGE); 131 for (var a = null, u = 0; u < i.length; u++) 132 if ( 133 (s.texImage2D( 134 s.TEXTURE_2D, 135 0, 136 s.RGBA, 137 32, 138 32, 139 0, 140 s.RGBA, 141 i[u].type, 142 null 143 ), 144 s.framebufferTexture2D( 145 s.FRAMEBUFFER, 146 s.COLOR_ATTACHMENT0, 147 s.TEXTURE_2D, 148 n, 149 0 150 ), 151 s.checkFramebufferStatus(s.FRAMEBUFFER) === s.FRAMEBUFFER_COMPLETE) 152 ) { 153 a = i[u]; 154 break; 155 } 156 return a; 157 })(), 158 c = (function (e, t) {
159 try { 160 return new ImageData(e, t); 161 } catch (r) { 162 return document 163 .createElement("canvas") 164 .getContext("2d") 165 .createImageData(e, t); 166 } 167 })(32, 32); 168 e("head").prepend( 169 "<style>.jquery-ripples { position: relative; z-index: 0; }</style>" 170 ); 171 var d = function (t, r) { 172 function i() { 173 n.destroyed || (n.step(), requestAnimationFrame(i)); 174 } 175 var n = this; 176 (this.$el = e(t)), 177 (this.interactive = r.interactive), 178 (this.resolution = r.resolution), 179 (this.textureDelta = new Float32Array([ 180 1 / this.resolution, 181 1 / this.resolution, 182 ])), 183 (this.perturbance = r.perturbance), 184 (this.dropRadius = r.dropRadius), 185 (this.crossOrigin = r.crossOrigin), 186 (this.imageUrl = r.imageUrl); 187 var o = document.createElement("canvas"); 188 (o.width = this.$el.innerWidth()), 189 (o.height = this.$el.innerHeight()), 190 (this.canvas = o), 191 (this.$canvas = e(o)), 192 this.$canvas.css({ 193 position: "absolute", 194 left: 0, 195 top: 0, 196 right: 0, 197 bottom: 0, 198 zIndex: -1, 199 }), 200 this.$el.addClass("jquery-ripples").append(o), 201 (this.context = s = 202 o.getContext("webgl") || o.getContext("experimental-webgl")), 203 h.extensions.forEach(function (e) { 204 s.getExtension(e); 205 }), 206 e(window).on("resize", function () { 207 n.updateSize(); 208 }), 209 (this.textures = []), 210 (this.framebuffers = []), 211 (this.bufferWriteIndex = 0), 212 (this.bufferReadIndex = 1); 213 for (var a = 0; a < 2; a++) { 214 var u = s.createTexture(), 215 c = s.createFramebuffer(); 216 s.bindFramebuffer(s.FRAMEBUFFER, c), 217 s.bindTexture(s.TEXTURE_2D, u), 218 s.texParameteri( 219 s.TEXTURE_2D, 220 s.TEXTURE_MIN_FILTER,
221 h.linearSupport ? s.LINEAR : s.NEAREST 222 ), 223 s.texParameteri( 224 s.TEXTURE_2D, 225 s.TEXTURE_MAG_FILTER, 226 h.linearSupport ? s.LINEAR : s.NEAREST 227 ), 228 s.texParameteri(s.TEXTURE_2D, s.TEXTURE_WRAP_S, s.CLAMP_TO_EDGE), 229 s.texParameteri(s.TEXTURE_2D, s.TEXTURE_WRAP_T, s.CLAMP_TO_EDGE), 230 s.texImage2D( 231 s.TEXTURE_2D, 232 0, 233 s.RGBA, 234 this.resolution, 235 this.resolution, 236 0, 237 s.RGBA, 238 h.type, 239 null 240 ), 241 s.framebufferTexture2D( 242 s.FRAMEBUFFER, 243 s.COLOR_ATTACHMENT0, 244 s.TEXTURE_2D, 245 u, 246 0 247 ), 248 this.textures.push(u), 249 this.framebuffers.push(c); 250 } 251 (this.quad = s.createBuffer()), 252 s.bindBuffer(s.ARRAY_BUFFER, this.quad), 253 s.bufferData( 254 s.ARRAY_BUFFER, 255 new Float32Array([-1, -1, 1, -1, 1, 1, -1, 1]), 256 s.STATIC_DRAW 257 ), 258 this.initShaders(), 259 this.initTexture(), 260 this.setTransparentTexture(), 261 this.loadImage(), 262 s.clearColor(0, 0, 0, 0), 263 s.blendFunc(s.SRC_ALPHA, s.ONE_MINUS_SRC_ALPHA), 264 (this.visible = !0), 265 (this.running = !0), 266 (this.inited = !0), 267 (this.destroyed = !1), 268 this.setupPointerEvents(), 269 requestAnimationFrame(i); 270 }; 271 (d.DEFAULTS = { 272 imageUrl: null, 273 resolution: 256, 274 dropRadius: 20, 275 perturbance: 0.03, 276 interactive: !0, 277 crossOrigin: "", 278 }), 279 (d.prototype = { 280 setupPointerEvents: function () { 281 function e() { 282 return r.visible && r.running && r.interactive; 283 } 284 function t(t, i) { 285 e() && 286 r.dropAtPointer(t, r.dropRadius * (i ? 1.5 : 1), i ? 0.14 : 0.01); 287 } 288 var r = this; 289 this.$el 290 .on("mousemove.ripples", function (e) { 291 t(e); 292 }) 293 .on("touchmove.ripples, touchstart.ripples", function (e) { 294 for ( 295 var r = e.originalEvent.changedTouches, i = 0; 296 i < r.length; 297 i++ 298 ) 299 t(r[i]); 300 }) 301 .on("mousedown.ripples", function (e) { 302 t(e, !0); 303 }); 304 }, 305 loadImage: function () { 306 var e = this; 307 s = this.context; 308 var t = 309 this.imageUrl || 310 o(this.originalCssBackgroundImage) || 311 o(this.$el.css("backgroundImage")); 312 if (t != this.imageSource) 313 if (((this.imageSource = t), this.imageSource)) { 314 var r = new Image(); 315 (r.onload = function () { 316 function t(e) { 317 return 0 == (e & (e - 1)); 318 } 319 s = e.context; 320 var i = t(r.width) && t(r.height) ? s.REPEAT : s.CLAMP_TO_EDGE; 321 s.bindTexture(s.TEXTURE_2D, e.backgroundTexture), 322 s.texParameteri(s.TEXTURE_2D, s.TEXTURE_WRAP_S, i), 323 s.texParameteri(s.TEXTURE_2D, s.TEXTURE_WRAP_T, i), 324 s.texImage2D( 325 s.TEXTURE_2D, 326 0, 327 s.RGBA, 328 s.RGBA, 329 s.UNSIGNED_BYTE, 330 r 331 ), 332 (e.backgroundWidth = r.width), 333 (e.backgroundHeight = r.height), 334 e.hideCssBackground(); 335 }), 336 (r.onerror = function () { 337 (s = e.context), e.setTransparentTexture(); 338 }), 339 (r.crossOrigin = a(this.imageSource) ? null : this.crossOrigin), 340 (r.src = this.imageSource); 341 } else this.setTransparentTexture(); 342 }, 343 step: function () { 344 (s = this.context), 345 this.visible && 346 (this.computeTextureBoundaries(), 347 this.running && this.update(), 348 this.render()); 349 }, 350 drawQuad: function () { 351 s.bindBuffer(s.ARRAY_BUFFER, this.quad), 352 s.vertexAttribPointer(0, 2, s.FLOAT, !1, 0, 0), 353 s.drawArrays(s.TRIANGLE_FAN, 0, 4); 354 }, 355 render: function () { 356 s.bindFramebuffer(s.FRAMEBUFFER, null), 357 s.viewport(0, 0, this.canvas.width, this.canvas.height), 358 s.enable(s.BLEND), 359 s.clear(s.COLOR_BUFFER_BIT | s.DEPTH_BUFFER_BIT), 360 s.useProgram(this.renderProgram.id), 361 n(this.backgroundTexture, 0), 362 n(this.textures[0], 1), 363 s.uniform1f( 364 this.renderProgram.locations.perturbance, 365 this.perturbance 366 ), 367 s.uniform2fv( 368 this.renderProgram.locations.topLeft, 369 this.renderProgram.uniforms.topLeft 370 ), 371 s.uniform2fv( 372 this.renderProgram.locations.bottomRight, 373 this.renderProgram.uniforms.bottomRight 374 ), 375 s.uniform2fv( 376 this.renderProgram.locations.containerRatio, 377 this.renderProgram.uniforms.containerRatio 378 ), 379 s.uniform1i(this.renderProgram.locations.samplerBackgroun
379d, 0), 380 s.uniform1i(this.renderProgram.locations.samplerRipples, 1), 381 this.drawQuad(), 382 s.disable(s.BLEND); 383 }, 384 update: function () { 385 s.viewport(0, 0, this.resolution, this.resolution), 386 s.bindFramebuffer( 387 s.FRAMEBUFFER, 388 this.framebuffers[this.bufferWriteIndex] 389 ), 390 n(this.textures[this.bufferReadIndex]), 391 s.useProgram(this.updateProgram.id), 392 this.drawQuad(), 393 this.swapBufferIndices(); 394 }, 395 swapBufferIndices: function () { 396 (this.bufferWriteIndex = 1 - this.bufferWriteIndex), 397 (this.bufferReadIndex = 1 - this.bufferReadIndex); 398 }, 399 computeTextureBoundaries: function () { 400 var e, 401 i = this.$el.css("background-size"), 402 n = this.$el.css("background-attachment"), 403 o = r(this.$el.css("background-position")); 404 if ( 405 ("fixed" == n 406 ? (((e = { 407 left: window.pageXOffset, 408 top: window.pageYOffset, 409 }).width = u.width()), 410 (e.height = u.height())) 411 : (((e = this.$el.offset()).width = this.$el.innerWidth()),
412 (e.height = this.$el.innerHeight())), 413 "cover" == i) 414 ) 415 var a = Math.max( 416 e.width / this.backgroundWidth, 417 e.height / this.backgroundHeight 418 ), 419 s = this.backgroundWidth * a, 420 h = this.backgroundHeight * a; 421 else if ("contain" == i) 422 var a = Math.min( 423 e.width / this.backgroundWidth, 424 e.height / this.backgroundHeight 425 ), 426 s = this.backgroundWidth * a, 427 h = this.backgroundHeight * a; 428 else { 429 var s = (i = i.split(" "))[0] || "", 430 h = i[1] || s; 431 t(s) 432 ? (s = (e.width * parseFloat(s)) / 100) 433 : "auto" != s && (s = parseFloat(s)), 434 t(h) 435 ? (h = (e.height * parseFloat(h)) / 100) 436 : "auto" != h && (h = parseFloat(h)), 437 "auto" == s && "auto" == h 438 ? ((s = this.backgroundWidth), (h = this.backgroundHeight)) 439 : ("auto" == s && 440 (s = this.backgroundWidth * (h / this.backgroundHeight)), 441 "auto" == h && 442 (h = this.backgroundHeight * (s / this.backgroundWidth))); 443 } 444 var c = o[0], 445 d = o[1]; 446 (c = t(c) 447 ? e.left + ((e.width - s) * parseFloat(c)) / 100 448 : e.left + parseFloat(c)), 449 (d = t(d) 450 ? e.top + ((e.height - h) * parseFloat(d)) / 100 451 : e.top + parseFloat(d)); 452 var f = this.$el.offset(); 453 (this.renderProgram.uniforms.topLeft = new Float32Array([ 454 (f.left - c) / s, 455 (f.top - d) / h, 456 ])), 457 (this.renderProgram.uniforms.bottomRight = new Float32Array([ 458 this.renderProgram.uniforms.topLeft[0] + this.$el.innerWidth() / s, 459 this.renderProgram.uniforms.topLeft[1] + this.$el.innerHe
459ight() / h, 460 ])); 461 var l = Math.max(this.canvas.width, this.canvas.height); 462 this.renderProgram.uniforms.containerRatio = new Float32Array([ 463 this.canvas.width / l, 464 this.canvas.height / l, 465 ]); 466 }, 467 initShaders: function () { 468 var e = [ 469 "attribute vec2 vertex;", 470 "varying vec2 coord;", 471 "void main() {", 472 "coord = vertex * 0.5 + 0.5;", 473 "gl_Position = vec4(vertex, 0.0, 1.0);", 474 "}", 475 ].join("\n"); 476 (this.dropProgram = i( 477 e, 478 [ 479 "precision highp float;", 480 "const float PI = 3.141592653589793;", 481 "uniform sampler2D texture;", 482 "uniform vec2 center;", 483 "uniform float radius;", 484 "uniform float strength;", 485 "varying vec2 coord;", 486 "void main() {", 487 "vec4 info = texture2D(texture, coord);", 488 "float drop = max(0.0, 1.0 - length(center * 0.5 + 0.5 - coord) / radius);", 489 "drop = 0.5 - cos(drop * PI) * 0.5;", 490 "info.r += drop * strength;", 491 "gl_FragColor = info;", 492 "}", 493 ].join("\n") 494 )), 495 (this.updateProgram = i( 496 e, 497 [ 498 "precision highp float;", 499 "uniform sampler2D texture;", 500 "uniform vec2 delta;", 501 "varying vec2 coord;", 502 "void main() {", 503 "vec4 info = texture2D(texture, coord);", 504 "vec2 dx = vec2(delta.x, 0.0);", 505 "vec2 dy = vec2(0.0, delta.y);", 506 "float average = (", 507 "texture2D(texture, coord - dx).r +", 508 "texture2D(texture, coord - dy).r +", 509 "texture2D(texture, coord + dx).r +", 510 "texture2D(texture, coord + dy).r", 511 ") * 0.25;", 512 "info.g += (average - info.r) * 2.0;", 513 "info.g *= 0.995;", 514 "info.r += info.g;", 515 "gl_FragColor = info;", 516 "}", 517 ].join("\n") 518 )), 519 s.uniform2fv(this.updateProgram.locations.delta, this.textureDelta), 520 (this.renderProgram = i( 521 [ 522 "precision highp float;", 523 "attribute vec2 vertex;", 524 "uniform vec2 topLeft;", 525 "uniform vec2 bottomRight;", 526 "uniform vec2 containerRatio;", 527 "varying vec2 ripplesCoord;", 528 "varying vec2 backgroundCoord;", 529 "void main() {", 530 "backgroundCoord = mix(topLeft, bottomRight, vertex * 0.5 + 0.5);", 531 "backgroundCoord.y = 1.0 - backgroundCoord.y;", 532 "ripplesCoord = vec2(vertex.x, -vertex.y) * containerRatio * 0.5 + 0.5;", 533 "gl_Position = vec4(vertex.x, -vertex.y, 0.0, 1.0);", 534 "}", 535 ].join("\n"), 536 [ 537 "precision highp float;", 538 "uniform sampler2D samplerBackground;", 539 "uniform sampler2D samplerRipples;", 540 "uniform vec2 delta;", 541 "uniform float perturbance;", 542 "varying vec2 ripplesCoord;", 543 "varying vec2 backgroundCoord;", 544 "void main() {", 545 "float height = texture2D(samplerRipples, ripplesCoord).r;", 546 "float heightX = texture2D(samplerRipples, vec2(ripplesCoord.x + delta.x, ripplesCoord.y)).r;", 547 "float heightY = texture2D(samplerRipples, vec2(ripplesCoord.x, ripplesCoord.y + delta.y)).r;", 548 "vec3 dx = vec3(delta.x, heightX - height, 0.0);", 549 "vec3 dy = vec3(0.0, heightY - height, delta.y);", 550 "vec2 offset = -normalize(cross(dy, dx)).xz;", 551 "float specular = pow(max(0.0, dot(offset, normalize(vec2(-0.6, 1.0)))), 4.0);", 552 "gl_FragColor = texture2D(samplerBackground, backgroundCoord + offset * perturbance) + specular;", 553 "}", 554 ].join("\n") 555 )), 556 s.uniform2fv(this.renderProgram.locations.delta, this.textureDelta); 557 }, 558 initTexture: function () { 559 (this.backgroundTexture = s.createTexture()), 560 s.bindTexture(s.TEXTURE_2D, this.backgroundTexture), 561 s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, 1), 562 s.texParameteri(s.TEXTURE_2D, s.TEXTURE_MAG_FILTER, s.LINEAR), 563 s.texParameteri(s.TEXTURE_2D, s.TEXTURE_MIN_FILTER, s.LINEAR); 564 }, 565 setTransparentTexture: function () { 566 s.bindTexture(s.TEXTURE_2D, this.backgroundTexture), 567 s.texImage2D(s.TEXTURE_2D, 0, s.RGBA, s.RGBA, s.UNSIGNED_BYTE, c); 568 },
569 hideCssBackground: function () { 570 var e = this.$el[0].style.backgroundImage; 571 "none" != e && 572 ((this.originalInlineCss = e), 573 (this.originalCssBackgroundImage = this.$el.css("backgroundImage")), 574 this.$el.css("backgroundImage", "none")); 575 }, 576 restoreCssBackground: function () { 577 this.$el.css("backgroundImage", this.originalInlineCss || ""); 578 }, 579 dropAtPointer: function (e, t, r) { 580 var i = parseInt(this.$el.css("border-left-width")) || 0, 581 n = parseInt(this.$el.css("border-top-width")) || 0; 582 this.drop( 583 e.pageX - this.$el.offset().left - i, 584 e.pageY - this.$el.offset().top - n, 585 t, 586 r 587 ); 588 }, 589 drop: function (e, t, r, i) { 590 s = this.context; 591 var o = this.$el.innerWidth(), 592 a = this.$el.innerHeight(), 593 u = Math.max(o, a); 594 r /= u; 595 var h = new Float32Array([(2 * e - o) / u, (a - 2 * t) / u]); 596 s.viewport(0, 0, this.resolution, this.resolution), 597 s.bindFramebuffer( 598 s.FRAMEBUFFER, 599 this.framebuffers[this.bufferWriteIndex] 600 ), 601 n(this.textures[this.bufferReadIndex]), 602 s.useProgram(this.dropProgram.id), 603 s.uniform2fv(this.dropProgram.locations.center, h), 604 s.uniform1f(this.dropProgram.locations.radius, r), 605 s.uniform1f(this.dropProgram.locations.strength, i), 606 this.drawQuad(), 607 this.swapBufferIndices(); 608 }, 609 updateSize: function () { 610 var e = this.$el.innerWidth(),
611 t = this.$el.innerHeight(); 612 (e == this.canvas.width && t == this.canvas.height) || 613 ((this.canvas.width = e), (this.canvas.height = t)); 614 }, 615 destroy: function () { 616 this.$el 617 .off(".ripples") 618 .removeClass("jquery-ripples") 619 .removeData("ripples"), 620 this.$canvas.remove(), 621 this.restoreCssBackground(), 622 (this.destroyed = !0); 623 }, 624 show: function () { 625 (this.visible = !0), this.$canvas.show(), this.hideCssBackground(); 626 }, 627 hide: function () { 628 (this.visible = !1), this.$canvas.hide(), this.restoreCssBackground(); 629 }, 630 pause: function () { 631 this.running = !1; 632 }, 633 play: function () { 634 this.running = !0; 635 }, 636 set: function (e, t) { 637 switch (e) { 638 case "dropRadius": 639 case "perturbance": 640 case "interactive": 641 case "crossOrigin": 642 this[e] = t; 643 break; 644 case "imageUrl": 645 (this.imageUrl = t), this.loadImage(); 646 } 647 }, 648 }); 649 var f = e.fn.ripples; 650 (e.fn.ripples = function (t) { 651 if (!h) 652 throw new Error( 653 "Your browser does not support WebGL, the OES_texture_float extension or rendering to floating point textures." 654 ); 655 var r = 656 arguments.length > 1 ? Array.prototype.slice.call(arguments, 1) : void 0; 657 return this.each(function () { 658 var i = e(this), 659 n = i.data("ripples"), 660 o = e.extend({}, d.DEFAULTS, i.data(), "object" == typeof t && t); 661 (n || "string" != typeof t) && 662 (n 663 ? "string" == typeof t && d.prototype[t].apply(n, r) 664 : i.data("ripples", (n = new d(this, o)))); 665 }); 666 }), 667 (e.fn.ripples.Constructor = d), 668 (e.fn.ripples.noConflict = function () { 669 return (e.fn.ripples = f), this; 670 }); 671});
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.