1/* 2 * jQuery FlexSlider v1.8 3 * http://www.woothemes.com/flexslider/ 4 * 5 * Copyright 2012 WooThemes 6 * Free to use under the MIT license. 7 * http://www.opensource.org/licenses/mit-license.php 8 * 9 * Contributing Author: Tyler Smith 10 */ 11 12;(function ($) { 13 14 //FlexSlider: Object Instance 15 $.flexslider = function(el, options) { 16 var slider = $(el); 17 18 // slider DOM reference for use outside of the plugin 19 $.data(el, "flexslider", slider); 20 21 slider.init = function() { 22 slider.vars = $.extend({}, $.flexslider.defaults, options); 23 $.data(el, 'flexsliderInit', true); 24 slider.container = $('.slides', slider).first(); 25 slider.slides = $('.slides:first > li', slider); 26 slider.count = slider.slides.length; 27 slider.animating = false; 28 slider.currentSlide = slider.vars.slideToStart; 29 slider.animatingTo = slider.currentSlide; 30 slider.atEnd = (slider.currentSlide == 0) ? true : false; 31 slider.eventType = ('ontouchstart' in document.documentElement) ? 'touchstart' : 'click'; 32 slider.cloneCount = 0; 33 slider.cloneOffset = 0; 34 slider.manualPause = false; 35 slider.vertical = (slider.vars.slideDirection == "vertical"); 36 slider.prop = (slider.vertical) ? "top" : "marginLeft"; 37 slider.args = {}; 38 39 //Test for webbkit CSS3 Animations 40 slider.transitions = "webkitTransition" in document.body.style; 41 if (slider.transitions) slider.prop = "-webkit-transform"; 42 43 //Test for controlsContainer 44 if (slider.vars.controlsContainer != "") { 45 slider.controlsContainer = $(slider.vars.controlsContainer).eq($('.slides').index(slider.container)); 46 slider.containerExists = slider.controlsContainer.length > 0; 47 } 48 //Test for manualControls 49 if (slider.vars.manualControls != "") { 50 slider.manualControls = $(slider.vars.manualControls, ((slider.containerExists) ? slider.controlsContainer : slider)); 51 slider.manualExists = slider.manualControls.length > 0; 52 } 53 54 /////////////////////////////////////////////////////////////////// 55 // FlexSlider: Randomize Slides 56 if (slider.vars.randomize) { 57 slider.slides.sort(function() { return (Math.round(Math.random())-0.5); }); 58 slider.container.empty().append(slider.slides); 59 } 60 /////////////////////////////////////////////////////////////////// 61 62 /////////////////////////////////////////////////////////////////// 63 // FlexSlider: Slider Animation Initialize 64 if (slider.vars.animation.toLowerCase() == "slide") { 65 if (slider.transitions) { 66 slider.setTransition(0); 67 } 68 slider.css({"overflow": "hidden"}); 69 if (slider.vars.animationLoop) { 70 slider.cloneCount = 2; 71 slider.cloneOffset = 1; 72 slider.container.append(slider.slides.filter(':first').clone().addClass('clone')).prepend(slider.slides.filter(':last').clone().addClass('clone')); 73 } 74 //create newSlides to capture possible clones 75 slider.newSlides = $('.slides:first > li', slider); 76 var sliderOffset = (-1 * (slider.currentSlide + slider.cloneOffset)); 77 if (slider.vertical) { 78 slider.newSlides.css({"display": "block", "width": "100%", "float": "left"}); 79 slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%"); 80 //Timeout function to give browser enough time to get proper height initially 81 setTimeout(function() { 82 slider.css({"position": "relative"}).height(slider.slides.filter(':first').height()); 83 slider.args[slider.prop] = (slider.transitions) ? "translate3d(0," + sliderOffset * slider.height() + "px,0)" : sliderOffset * slider.height() + "px"; 84 slider.container.css(slider.args); 85 }, 100); 86 87 } else { 88 slider.args[slider.prop] = (slider.transitions) ? "translate3d(" + sliderOffset * slider.width() + "px,0,0)" : sliderOffset * slider.width() + "px"; 89 slider.container.width((slider.count + slider.cloneCount) * 200 + "%").css(slider.args); 90 //Timeout function to give browser enough time to get proper width initially 91 setTimeout(function() { 92 slider.newSlides.width(slider.width()).css({"float": "left", "display": "block"}); 93 }, 100); 94 } 95 96 } else { //Default to fade 97 //Not supporting fade CSS3 transitions right now 98 slider.transitions = false; 99 slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%"}).eq(slider.currentSlide).fadeIn(slider.vars.animationDuration); 100 }
101 /////////////////////////////////////////////////////////////////// 102 103 /////////////////////////////////////////////////////////////////// 104 // FlexSlider: Control Nav 105 if (slider.vars.controlNav) { 106 if (slider.manualExists) { 107 slider.controlNav = slider.manualControls; 108 } else { 109 var controlNavScaffold = $('<ol class="flex-control-nav"></ol>'); 110 var j = 1; 111 for (var i = 0; i < slider.count; i++) { 112 controlNavScaffold.append('<li><a>' + j + '</a></li>'); 113 j++; 114 } 115 116 if (slider.containerExists) { 117 $(slider.controlsContainer).append(controlNavScaffold); 118 slider.controlNav = $('.flex-control-nav li a', slider.controlsContainer); 119 } else { 120 slider.append(controlNavScaffold); 121 slider.controlNav = $('.flex-control-nav li a', slider); 122 } 123 } 124 125 slider.controlNav.eq(slider.currentSlide).addClass('active'); 126 127 slider.controlNav.bind(slider.eventType, function(event) { 128 event.preventDefault(); 129 if (!$(this).hasClass('active')) { 130 (slider.controlNav.index($(this)) > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev"; 131 slider.flexAnimate(slider.controlNav.index($(this)), slider.vars.pauseOnAction); 132 } 133 }); 134 } 135 /////////////////////////////////////////////////////////////////// 136 137 ////////////////////////////////////////////////////////////////// 138 //FlexSlider: Direction Nav 139 if (slider.vars.directionNav) { 140 var directionNavScaffold = $('<ul class="flex-direction-nav"><li><a class="prev" href="#">' + slider.vars.prevText + '</a></li><li><a class="next" href="#">' + slider.vars.nextText + '</a></li></ul>'); 141 142 if (slider.containerExists) { 143 $(slider.controlsContainer).append(directionNavScaffold); 144 slider.directionNav = $('.flex-direction-nav li a', slider.controlsContainer); 145 } else { 146 slider.append(directionNavScaffold); 147 slider.directionNav = $('.flex-direction-nav li a', slider); 148 } 149 150 //Set initial disable styles if necessary 151 if (!slider.vars.animationLoop) { 152 if (slider.currentSlide == 0) { 153 slider.directionNav.filter('.prev').addClass('disabled'); 154 } else if (slider.currentSlide == slider.count - 1) { 155 slider.directionNav.filter('.next').addClass('disabled'); 156 } 157 } 158 159 slider.directionNav.bind(slider.eventType, function(event) { 160 event.preventDefault(); 161 var target = ($(this).hasClass('next')) ? slider.getTarget('next') : slider.getTarget('prev'); 162 163 if (slider.canAdvance(target)) { 164 slider.flexAnimate(target, slider.vars.pauseOnAction); 165 } 166 }); 167 } 168 ////////////////////////////////////////////////////////////////// 169 170 ////////////////////////////////////////////////////////////////// 171 //FlexSlider: Keyboard Nav 172 if (slider.vars.keyboardNav && $('ul.slides').length == 1) { 173 function keyboardMove(event) { 174 if (slider.animating) { 175 return; 176 } else if (event.keyCode != 39 && event.keyCode != 37){ 177 return; 178 } else { 179 if (event.keyCode == 39) { 180 var target = slider.getTarget('next'); 181 } else if (event.keyCode == 37){ 182 var target = slider.getTarget('prev'); 183 } 184 185 if (slider.canAdvance(target)) { 186 slider.flexAnimate(target, slider.vars.pauseOnAction); 187 } 188 } 189 } 190 $(document).bind('keyup', keyboardMove); 191 } 192 ////////////////////////////////////////////////////////////////// 193 194 /////////////////////////////////////////////////////////////////// 195 // FlexSlider: Mousewheel interaction 196 if (slider.vars.mousewheel) { 197 slider.mousewheelEvent = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel"; 198 slider.bind(slider.mousewheelEvent, function(e) { 199 e.preventDefault(); 200 e = e ? e : window.event; 201 var wheelData = e.detail ? e.detail * -1 : e.originalEvent.wheelDelta / 40, 202 target = (wheelData < 0) ? slider.getTarget('next') : slider.getTarget('prev'); 203 204 if (slider.canAdvance(target)) { 205 slider.flexAnimate(target, slider.vars.pauseOnAction); 206 } 207 }); 208 }
209 /////////////////////////////////////////////////////////////////// 210 211 ////////////////////////////////////////////////////////////////// 212 //FlexSlider: Slideshow Setup 213 if (slider.vars.slideshow) { 214 //pauseOnHover 215 if (slider.vars.pauseOnHover && slider.vars.slideshow) { 216 slider.hover(function() { 217 slider.pause(); 218 }, function() { 219 if (!slider.manualPause) { 220 slider.resume(); 221 } 222 }); 223 } 224 225 //Initialize animation 226 slider.animatedSlides = setInterval(slider.animateSlides, slider.vars.slideshowSpeed); 227 } 228 ////////////////////////////////////////////////////////////////// 229 230 ////////////////////////////////////////////////////////////////// 231 //FlexSlider: Pause/Play 232 if (slider.vars.pausePlay) { 233 var pausePlayScaffold = $('<div class="flex-pauseplay"><span></span></div>'); 234 235 if (slider.containerExists) { 236 slider.controlsContainer.append(pausePlayScaffold); 237 slider.pausePlay = $('.flex-pauseplay span', slider.controlsContainer); 238 } else { 239 slider.append(pausePlayScaffold); 240 slider.pausePlay = $('.flex-pauseplay span', slider); 241 } 242 243 var pausePlayState = (slider.vars.slideshow) ? 'pause' : 'play'; 244 slider.pausePlay.addClass(pausePlayState).text((pausePlayState == 'pause') ? slider.vars.pauseText : slider.vars.playText); 245 246 slider.pausePlay.bind(slider.eventType, function(event) { 247 event.preventDefault(); 248 if ($(this).hasClass('pause')) { 249 slider.pause(); 250 slider.manualPause = true; 251 } else { 252 slider.resume(); 253 slider.manualPause = false; 254 } 255 }); 256 } 257 ////////////////////////////////////////////////////////////////// 258 259 ////////////////////////////////////////////////////////////////// 260 //FlexSlider:Touch Swip Gestures 261 //Some brilliant concepts adapted from the following sources 262 //Source: TouchSwipe - http://www.netcu.de/jquery-touchwipe-iphone-ipad-library 263 //Source: SwipeJS - http://swipejs.com 264 if ('ontouchstart' in document.documentElement) { 265 //For brevity, variables are named for x-axis scrolling 266 //The variables are then swapped if vertical sliding is applied 267 //This reduces redundant code...I think :) 268 //If debugging, recognize variables are named for horizontal scrolling 269 var startX, 270 startY, 271 offset, 272 cwidth, 273 dx, 274 startT, 275 scrolling = false; 276 277 slider.each(function() { 278 if ('ontouchstart' in document.documentElement) { 279 this.addEventListener('touchstart', onTouchStart, false); 280 } 281 }); 282 283 function onTouchStart(e) { 284 if (slider.animating) { 285 e.preventDefault(); 286 } else if (e.touches.length == 1) { 287 slider.pause(); 288 cwidth = (slider.vertical) ? slider.height() : slider.width(); 289 startT = Number(new Date()); 290 offset = (slider.vertical) ? (slider.currentSlide + slider.cloneOffset) * slider.height() : (slider.currentSlide + slider.cloneOffset) * slider.width(); 291 startX = (slider.vertical) ? e.touches[0].pageY : e.touches[0].pageX; 292 startY = (slider.vertical) ? e.touches[0].pageX : e.touches[0].pageY; 293 slider.setTransition(0); 294 295 this.addEventListener('touchmove', onTouchMove, false); 296 this.addEventListener('touchend', onTouchEnd, false); 297 } 298 } 299 300 function onTouchMove(e) { 301 dx = (slider.vertical) ? startX - e.touches[0].pageY : startX - e.touches[0].pageX; 302 scrolling = (slider.vertical) ? (Math.abs(dx) < Math.abs(e.touches[0].pageX - startY)) : (Math.abs(dx) < Math.abs(e.touches[0].pageY - startY)); 303 304 if (!scrolling) { 305 e.preventDefault(); 306 if (slider.vars.animation == "slide" && slider.transitions) { 307 if (!slider.vars.animationLoop) { 308 dx = dx/((slider.currentSlide == 0 && dx < 0 || slider.currentSlide == slider.count - 1 && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1); 309 } 310 slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + (-offset - dx) + "px,0)": "translate3d(" + (-offset - dx) + "px,0,0)"; 311 slider.container.css(slider.args); 312 } 313 } 314 } 315 316 function onTouchEnd(e) { 317 slider.animating = false; 318 if (slider.animatingTo == slider.currentSlide && !scrolling && !(dx == null)) { 319 var target = (dx > 0) ? slider.getTarget('next') : slider.getTarget('prev'); 320 if (slider.canAdvance(target) && Number(new Date()) - startT < 550 && Math.abs(dx) > 20 || Math.abs(dx) > cwidth/2) { 321 slider.flexAnimate(target, slider.vars.pauseOnAction); 322 } else { 323 slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction); 324 } 325 } 326 327 //Finish the touch by undoing the touch session 328 this.removeEventListener('touchmove', onTouchMove, false); 329 this.removeEventListener('touchend', onTouchEnd, false); 330 startX = null; 331 startY = null; 332 dx = null; 333 offset = null; 334 } 335 }
336 ////////////////////////////////////////////////////////////////// 337 338 ////////////////////////////////////////////////////////////////// 339 //FlexSlider: Resize Functions (If necessary) 340 if (slider.vars.animation.toLowerCase() == "slide") { 341 $(window).resize(function(){ 342 if (!slider.animating && slider.is(":visible")) { 343 if (slider.vertical) { 344 slider.height(slider.slides.filter(':first').height()); 345 slider.args[slider.prop] = (-1 * (slider.currentSlide + slider.cloneOffset))* slider.slides.filter(':first').height() + "px"; 346 if (slider.transitions) { 347 slider.setTransition(0); 348 slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)"; 349 } 350 slider.container.css(slider.args); 351 } else { 352 slider.newSlides.width(slider.width()); 353 slider.args[slider.prop] = (-1 * (slider.currentSlide + slider.cloneOffset))* slider.width() + "px"; 354 if (slider.transitions) { 355 slider.setTransition(0); 356 slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)"; 357 } 358 slider.container.css(slider.args); 359 } 360 } 361 }); 362 } 363 ////////////////////////////////////////////////////////////////// 364 365 //FlexSlider: start() Callback 366 slider.vars.start(slider); 367 } 368 369 //FlexSlider: Animation Actions 370 slider.flexAnimate = function(target, pause) { 371 if (!slider.animating && slider.is(":visible")) { 372 //Animating flag 373 slider.animating = true; 374 375 //FlexSlider: before() animation Callback 376 slider.animatingTo = target; 377 slider.vars.before(slider); 378 379 //Optional paramter to pause slider when making an anmiation call 380 if (pause) { 381 slider.pause(); 382 } 383 384 //Update controlNav 385 if (slider.vars.controlNav) { 386 slider.controlNav.removeClass('active').eq(target).addClass('active'); 387 } 388 389 //Is the slider at either end 390 slider.atEnd = (target == 0 || target == slider.count - 1) ? true : false; 391 if (!slider.vars.animationLoop && slider.vars.directionNav) { 392 if (target == 0) { 393 slider.directionNav.removeClass('disabled').filter('.prev').addClass('disabled'); 394 } else if (target == slider.count - 1) { 395 slider.directionNav.removeClass('disabled').filter('.next').addClass('disabled'); 396 } else { 397 slider.directionNav.removeClass('disabled'); 398 } 399 } 400 401 if (!slider.vars.animationLoop && target == slider.count - 1) { 402 slider.pause(); 403 //FlexSlider: end() of cycle Callback 404 slider.vars.end(slider); 405 } 406 407 if (slider.vars.animation.toLowerCase() == "slide") { 408 var dimension = (slider.vertical) ? slider.slides.filter(':first').height() : slider.slides.filter(':first').width(); 409 410 if (slider.currentSlide == 0 && target == slider.count - 1 && slider.vars.animationLoop && slider.direction != "next") { 411 slider.slideString = "0px"; 412 } else if (slider.currentSlide == slider.count - 1 && target == 0 && slider.vars.animationLoop && slider.direction != "prev") { 413 slider.slideString = (-1 * (slider.count + 1)) * dimension + "px"; 414 } else { 415 slider.slideString = (-1 * (target + slider.cloneOffset)) * dimension + "px"; 416 } 417 slider.args[slider.prop] = slider.slideString; 418 419 if (slider.transitions) { 420 slider.setTransition(slider.vars.animationDuration); 421 slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.slideString + ",0)" : "translate3d(" + slider.slideString + ",0,0)"; 422 slider.container.css(slider.args).one("webkitTransitionEnd transitionend", function(){ 423 slider.wrapup(dimension); 424 }); 425 } else { 426 slider.container.animate(slider.args, slider.vars.animationDuration, function(){ 427 slider.wrapup(dimension); 428 }); 429 } 430 } else { //Default to Fade 431 slider.slides.eq(slider.currentSlide).fadeOut(slider.vars.animationDuration); 432 slider.slides.eq(target).fadeIn(slider.vars.animationDuration, function() { 433 slider.wrapup(); 434 }); 435 } 436 } 437 } 438 439 //FlexSlider: Function to minify redundant animation actions 440 slider.wrapup = function(dimension) { 441 if (slider.vars.animation == "slide") { 442 //Jump the slider if necessary 443 if (slider.currentSlide == 0 && slider.animatingTo == slider.count - 1 && slider.vars.animationLoop) { 444 slider.args[slider.prop] = (-1 * slider.count) * dimension + "px"; 445 if (slider.transitions) { 446 slider.setTransition(0); 447 slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)"; 448 } 449 slider.container.css(slider.args); 450 } else if (slider.currentSlide == slider.count - 1 && slider.animatingTo == 0 && slider.vars.animationLoop) { 451 slider.args[slider.prop] = -1 * dimension + "px"; 452 if (slider.transitions) { 453 slider.setTransition(0); 454 slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)"; 455 } 456 slider.container.css(slider.args); 457 } 458 } 459 slider.animating = false; 460 slider.currentSlide = slider.animatingTo; 461 //FlexSlider: after() animation Callback 462 slider.vars.after(slider); 463 } 464 465 //FlexSlider: Automatic Slideshow 466 slider.animateSlides = function() { 467 if (!slider.animating) { 468 slider.flexAnimate(slider.getTarget("next")); 469 } 470 } 471 472 //FlexSlider: Automatic Slideshow Pause 473 slider.pause = function() { 474 clearInterval(slider.animatedSlides); 475 if (slider.vars.pausePlay) { 476 slider.pausePlay.removeClass('pause').addClass('play').text(slider.vars.playText); 477 } 478 } 479 480 //FlexSlider: Automatic Slideshow Start/Resume 481 slider.resume = function() { 482 slider.animatedSlides = setInterval(slider.animateSlides, slider.vars.slideshowSpeed); 483 if (slider.vars.pausePlay) { 484 slider.pausePlay.removeClass('play').addClass('pause').text(slider.vars.pauseText); 485 } 486 } 487 488 //FlexSlider: Helper function for non-looping sliders 489 slider.canAdvance = function(target) { 490 if (!slider.vars.animationLoop && slider.atEnd) { 491 if (slider.currentSlide == 0 && target == slider.count - 1 && slider.direction != "next") { 492 return false; 493 } else if (slider.currentSlide == slider.count - 1 && target == 0 && slider.direction == "next") { 494 return false; 495 } else { 496 return true; 497 } 498 } else { 499 return true; 500 } 501 } 502 503 //FlexSlider: Helper function to determine animation target 504 slider.getTarget = function(dir) { 505 slider.direction = dir; 506 if (dir == "next") { 507 return (slider.currentSlide == slider.count - 1) ? 0 : slider.currentSlide + 1; 508 } else { 509 return (slider.currentSlide == 0) ? slider.count - 1 : slider.currentSlide - 1; 510 } 511 } 512 513 //FlexSlider: Helper function to set CSS3 transitions 514 slider.setTransition = function(dur) { 515 slider.container.css({'-webkit-transition-duration': (dur/1000) + "s"}); 516 } 517 518 //FlexSlider: Initialize 519 slider.init(); 520 } 521 522 //FlexSlider: Default Settings 523 $.flexslider.defaults = { 524 animation: "fade", //String: Select your animation type, "fade" or "slide" 525 slideDirection: "horizontal", //String: Select the sliding direction, "horizontal" or "vertical" 526 slideshow: true, //Boolean: Animate slider automatically 527 slideshowSpeed: 7000, //Integer: Set the speed of the slideshow cycling, in milliseconds 528 animationDuration: 600, //Integer: Set the speed of animations, in milliseconds 529 directionNav: true, //Boolean: Create navigation for previous/next navigation? (true/false) 530 controlNav: true, //Boolean: Create navigation for paging control of each clide? Note: Leave true for manualControls usage 531 keyboardNav: true, //Boolean: Allow slider navigating via keyboard left/right keys 532 mousewheel: false, //Boolean: Allow slider navigating via mousewheel 533 prevText: "Previous", //String: Set the text for the "previous" directionNav item 534 nextText: "Next", //String: Set the text for the "next" directionNav item
535 pausePlay: false, //Boolean: Create pause/play dynamic element 536 pauseText: 'Pause', //String: Set the text for the "pause" pausePlay item 537 playText: 'Play', //String: Set the text for the "play" pausePlay item 538 randomize: false, //Boolean: Randomize slide order 539 slideToStart: 0, //Integer: The slide that the slider should start on. Array notation (0 = first slide) 540 animationLoop: true, //Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end 541 pauseOnAction: true, //Boolean: Pause the slideshow when interacting with control elements, highly recommended. 542 pauseOnHover: false, //Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering 543 controlsContainer: "", //Selector: Declare which container the navigation elements should be appended too. Default container is the flexSlider element. Example use would be ".flexslider-container", "#container", etc. If the given element is not found, the default action will be taken. 544 manualControls: "", //Selector: Declare custom control navigation. Example would be ".flex-control-nav li" or "#tabs-nav li img", etc. The number of elements in your controlNav should match the number of slides/tabs. 545 start: function(){}, //Callback: function(slider) - Fires when the slider loads the first slide 546 before: function(){}, //Callback: function(slider) - Fires asynchronously with each slider animation 547 after: function(){}, //Callback: function(slider) - Fires after each slider animation completes 548 end: function(){} //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous) 549 } 550 551 //FlexSlider: Plugin Function 552 $.fn.flexslider = function(options) { 553 return this.each(function() { 554 if ($(this).find('.slides li').length == 1) { 555 $(this).find('.slides li').fadeIn(400); 556 } 557 else if ($(this).data('flexsliderInit') != true) { 558 new $.flexslider(this, options); 559 } 560 }); 561 } 562 563})(jQuery);
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.