1/** 2 * Slider Kit v1.9.2 (packed) 3 * http://www.kyrielles.net/sliderkit 4 * 5 * Copyright (c) 2010-2012 Alan Frog 6 * Licensed under the GNU General Public License 7 */ (function ($) { 8 SliderKit = function () { 9 var n = this; 10 this._init = function (c, d) { 11 this.options = $.extend({}, this._settings, d); 12 this.cssNames = { 13 selected: this.options.cssprefix + "-selected", 14 panel: this.options.cssprefix + "-panel", 15 panels: this.options.cssprefix + "-panels", 16 panelActive: this.options.cssprefix + "-panel-active", 17 panelOld: this.options.cssprefix + "-panel-old", 18 panelsWrapper: this.options.cssprefix + "-panels-wrapper", 19 nav: this.options.cssprefix + "-nav", 20 navClip: this.options.cssprefix + "-nav-clip", 21 navBtn: this.options.cssprefix + "-nav-btn", 22 navPrev: this.options.cssprefix + "-nav-prev", 23 navNext: this.options.cssprefix + "-nav-next", 24 btnDisable: this.options.cssprefix + "-btn-disable", 25 btnPause: this.options.cssprefix + "-pause-btn", 26 goPrev: this.options.cssprefix + "-go-prev", 27 goNext: this.options.cssprefix + "-go-next", 28 playBtn: this.options.cssprefix + "-play-btn", 29 goBtns: this.options.cssprefix + "-go-btn" 30 }; 31 this.domObj = $(c); 32 this.panels = $("." + this.cssNames.panel, this.domObj); 33 this.allItems = this.panels.size(); 34 this.nav = $("." + this.cssNames.nav, this.domObj); 35 this.navClip = $("." + this.cssNames.navClip, this.nav); 36 this.arePanels = this.allItems > 0 ? 1 : 0; 37 this.isNavClip = this.navClip.size() > 0 ? 1 : 0; 38 if (!this.arePanels && !this.isNavClip) { 39 this._errorReport("Error #01", this.options.debug, 1) 40 } 41 this.domObjHeight = this.domObj.height(); 42 this.domObjWidth = this.domObj.width(); 43 if (!this.domObjHeight && !this.options.freeheight) { 44 this.domObjHeight = this.options.height; 45 this.domObj.css('height', this.domObjHeight); 46 this._errorReport("Error #02", this.options.debug, 0) 47 } 48 if (!this.domObjWidth) { 49 this.domObjWidth = this.options.width; 50 this.domObj.css('width', this.domObjWidth); 51 this._errorReport("Error #02", this.options.debug, 0) 52 } 53 this.domObj.css('display', 'block'); 54 this.currId = 0; 55 this.prevId = 0; 56 this.newId = 0; 57 this.currPanel = null; 58 this.prevPanel = 0; 59 this.prevPanelStill = 0; 60 this.firstTime = 1; 61 this.scrollActive = 0; 62 this.isPlaying = null; 63 this.changeOngoing = false; 64 this.currLine = 1; 65 this.animating = false; 66 this.panelAnteFns = new Array; 67 this.panelPostFns = new Array; 68 this.navAnteFns = new Array; 69 this.navPostFns = new Array; 70 this.runningScope = this.nav; 71 if (this.isNavClip) { 72 this._buildNav() 73 } 74 this._buildControls(); 75 if (this.arePanels) { 76 this.panelsBag = $("." + this.cssNames.panels, this.domObj); 77 if (this.options.panelfx == "sliding") { 78 this._wrapPanels() 79 } 80 } 81 this.lineScrollDo = !this.arePanels ? 1 : 0; 82 if (this.options.mousewheel) { 83 this.domObj.mousewheel(function (a, b) { 84 b > 0 ? n.stepBackward() : n.stepForward(); 85 return false 86 }) 87 } 88 if (this.options.keyboard) { 89 this.domObj.keyup(function (a) { 90 if (a.keyCode == 37) { 91 n.stepBackward() 92 } else if (a.keyCode == 39) { 93 n.stepForward() 94 } 95 }) 96 } 97 if (this.options.panelclick && this.arePanels) { 98 this.panelsBag.click(function () { 99 n.stepForward(); 100 return false 101 }) 102 } 103 this.startId = this.options.start >= this.allItems ? this.allItems - 1 : this.options.start < 0 ? 0 : this.options.start; 104 if (this.options.counter) { 105 try { 106 this.Counter() 107 } catch (err) {
108 this._errorReport(err, this.options.debug, 0) 109 } 110 } 111 if (this.imageFx) { 112 try { 113 this.imageFx() 114 } catch (err) { 115 this._errorReport(err, this.options.debug, 0) 116 } 117 } 118 if (this.options.delaycaptions) { 119 try { 120 this.DelayCaptions(this.options.delaycaptions) 121 } catch (err) { 122 this._errorReport(err, this.options.debug, 0) 123 } 124 } 125 this.changeWithId(this.startId, null); 126 if (this.options.auto) { 127 this.autoScrollStart(); 128 this._autoScrollHoverStop() 129 } 130 if (this.options.timer) { 131 try { 132 this.Timer(this.options.timer) 133 } catch (err) { 134 this._errorReport(err, this.options.debug, 0) 135 } 136 } 137 if (this.arePanels && !this.options.fastchange) { 138 this.runningScope = this.domObj.find('.' + this.cssNames.panels, '.' + this.cssNames.nav) 139 } 140 return this 141 }; 142 this._settings = { 143 cssprefix: "sliderkit", 144 width: 500, 145 height: 350, 146 start: 0, 147 auto: true, 148 autospeed: 4000, 149 autostill: false, 150 mousewheel: false, 151 keyboard: false, 152 circular: false, 153 shownavitems: 5, 154 navitemshover: false, 155 navclipcenter: false, 156 navcontinuous: false, 157 navscrollatend: false, 158 navpanelautoswitch: true, 159 navfx: "sliding", 160 navfxbefore: function () {}, 161 navfxafter: function () {}, 162 scroll: null, 163 scrollspeed: 600, 164 scrolleasing: null, 165 panelfx: "fading", 166 panelfxspeed: 700, 167 panelfxeasing: null, 168 panelfxfirst: "none", 169 panelfxbefore: function () {}, 170 panelfxafter: function () {}, 171 panelbtnshover: false, 172 panelclick: false, 173 verticalnav: false, 174 verticalslide: false, 175 tabs: false, 176 freeheight: false, 177 fastchange: true, 178 counter: false, 179 delaycaptions: false, 180 timer: false, 181 imagefx: false, 182 debug: false 183 }; 184 this._errorReport = function (a, b, c) { 185 if (b) { 186 alert("Slider Kit error!\nMessage = " + a + " (see doc for details)\nElement id = " + this.domObj.attr("id") + "\nElement class = " + this.domObj.attr("class")) 187 } 188 if (c) { 189 return false 190 } 191 }; 192 this._autoScrollHoverStop = function () { 193 if (!this.isPlayBtn && !this.options.autostill) { 194 this.domObj.hover(function () { 195 if (n.isPlaying != null) { 196 n.autoScrollStop() 197 } 198 }, function () { 199 n.autoScrollStart() 200 }) 201 } 202 if (this.options.autostill) { 203 this.domObj.mouseleave(function () { 204 if (n.isPlaying == null) { 205 n.autoScrollStart() 206 } 207 }) 208 } 209 }; 210 this._buildNav = function () { 211 this.navUL = $("ul", this.navClip); 212 this.navLI = $("li", this.navUL); 213 this.navLINum = this.navLI.size(); 214 if (this.arePanels && (this.navLINum != this.allItems) && this.nav.size() == 1) { 215 this._errorReport("Error #03", this.options.debug, 1) 216 } 217 if (this.options.tabs) { 218 this.options.shownavitems = this.allItems 219 } else { 220 function getLImargin(a) { 221 attrVal = n.navLI.css(a); 222 if (attrVal != "auto" && a != "" && a != "0px") { 223 return parseInt(attrVal) 224 } else return 0 225 } 226 var c = this.options.verticalnav ? this.nav.height() : this.nav.width(); 227 var d = this.navLI.outerWidth(true); 228 var e = this.navLI.outerHeight(true); 229 var f = getLImargin("margin-left") + getLImargin("margin-right"); 230 var g = getLImargin("margin-top") + getLImargin("margin-bottom"); 231 this.allItems = this.navLINum; 232 if (this.options.shownavitems > this.allItems) { 233 this.options.shownavitems = this.navLINum 234 } 235 this.navLIsize = this.options.verticalnav ? e : d; 236 this.navULSize = this.navLIsize * this.navLINum; 237 this.navClipSize = (this.options.shownavitems * this.navLIsize) - (this.options.verticalnav ? g : f); 238 this.cssPosAttr = this.options.verticalnav ? "top" : "left"; 239 var h = this.options.verticalnav ? "height" : "width"; 240 var i = this.options.verticalnav ? "width" : "height"; 241 this.navLI.css({ 242 width: this.navLI.width(), 243 height: this.navLI.height() 244 }); 245 this.navUL.css(h, this.navULSize + "px"); 246 this.navClip.css({ 247 width: this.options.verticalnav ? d : this.navClipSize, 248 height: this.options.verticalnav ? this.navClipSize : e 249 }); 250 if (this.options.navclipcenter) { 251 this.navClip.css(this.cssPosAttr, (c - this.navClipSize) / 2).css("margin", "0") 252 } 253 if (this.allItems > this.options.shownavitems) { 254 this.scrollActive = true; 255 if (this.options.scroll == null || this.options.scroll < 0 || this.options.scroll > this.allItems) { 256 this.options.scroll = this.options.shownavitems 257 } 258 } 259 this.navBtns = $('.' + this.cssNames.navBtn, this.nav); 260 if (this.navBtns.size() > 0) { 261 this._buildNavButtons() 262 } 263 } 264 if (this.options.navitemshover && this.arePanels) { 265 this.navLI.mouseover(function () { 266 n.changeWithId(getIndex(this, "li"), $(this)) 267 }) 268 } else if (this.arePanels || this.options.navscrollatend) { 269 this.navLI.click(function () { 270 n.changeWithId(getIndex(this, "li"), $(this)); 271 return false 272 }) 273 } 274 function getIndex(a, b) { 275 return $(b, $(a).parent()).index(a) 276 } 277 }; 278 this._buildNavButtons = function () { 279 if (this.scrollActive) { 280 this.scrollBtns = true; 281 this.navBtnPrev = $("." + this.cssNames.navPrev, this.nav); 282 this.navBtnNext = $("." + this.cssNames.navNext, this.nav); 283 this.navBtns.removeClass(this.cssNames.btnDisable); 284 this.navBtnPrev.click(function () { 285 n.navPrev(); 286 return false 287 }); 288 this.navBtnNext.click(function () { 289 n.navNext(); 290 return false 291 }); 292 if (this.options.navcontinuous) { 293 this.navBtnPrev.mouseover(function () { 294 n.navPrev(true) 295 }); 296 this.navBtnNext.mouseover(function () { 297 n.navNext(true) 298 }); 299 this.navBtns.mouseout(function () { 300 n.navStopContinuous() 301 }) 302 } 303 if (!this.options.circular) { 304 this.navBtnPrev.addClass(this.cssNames.btnDisable) 305 } 306 } else { 307 this.navBtns.addClass(this.cssNames.btnDisable) 308 } 309 }; 310 this._getNavPos = function () { 311 this.navPos = this.options.verticalnav ? this.navUL.position().top : this.navUL.position().left;
312 this.LIbefore = Math.ceil(Math.abs(this.navPos) / this.navLIsize); 313 this.LIafter = Math.floor((this.navULSize - Math.abs(this.navPos) - this.navClipSize) / this.navLIsize); 314 if (this.LIafter < 0) { 315 this.LIafter = 0 316 } 317 }; 318 this._buildControls = function () { 319 this.playBtn = $("." + this.cssNames.playBtn, this.domObj); 320 this.gBtns = $("." + this.cssNames.goBtns, this.domObj); 321 this.isPlayBtn = this.playBtn.size() > 0 ? 1 : 0; 322 this.goBtns = this.gBtns.size() > 0 ? 1 : 0; 323 if (this.isPlayBtn) { 324 if (this.options.auto) { 325 this.playBtn.addClass(this.cssNames.btnPause) 326 } 327 this.playBtn.click(function () { 328 if (n.playBtn.hasClass(n.cssNames.btnPause)) { 329 n.playBtnPause() 330 } else { 331 n.playBtnStart() 332 } 333 return false 334 }) 335 } 336 if (this.goBtns) { 337 this.goBtnPrev = $("." + this.cssNames.goPrev, this.domObj); 338 this.goBtnNext = $("." + this.cssNames.goNext, this.domObj); 339 if (this.options.panelbtnshover) { 340 this.gBtns.hide(); 341 $("." + this.cssNames.panels, this.domObj).hover(function () { 342 n.gBtns.fadeIn() 343 }, function () { 344 n.gBtns.fadeOut() 345 }) 346 } 347 this.goBtnPrev.click(function () { 348 n.stepBackward($(this)); 349 return false 350 }); 351 this.goBtnNext.click(function () { 352 n.stepForward($(this)); 353 return false 354 }) 355 } 356 }; 357 this._wrapPanels = function () { 358 if ($('.' + this.cssNames.panelsWrapper, this.domObj).size() == 0) { 359 this.panels.wrapAll('<div class="' + this.cssNames.panelsWrapper + '"></div>'); 360 this.panelsWrapper = $('.' + this.cssNames.panelsWrapper, this.panelsBag); 361 this.panelsWrapper.css('position', 'relative') 362 } 363 }; 364 this._change = function (a, b, c, d, e) { 365 if (e && this.isPlaying != null) { 366 if (this.isPlayBtn) { 367 this.playBtnPause() 368 } 369 if (this.options.autostill) { 370 n.autoScrollStop() 371 } 372 } 373 if (a) { 374 if (a.hasClass(this.cssNames.btnDisable)) { 375 return false 376 } 377 } 378 var f = 0; 379 var g = $(':animated', this.runningScope).size() > 0 ? 1 : 0; 380 if (!g && !this.animating) { 381 this.prevId = this.currId; 382 if (c == null && !d) { 383 this.currId = b == "-=" ? this.currId + 1 : this.currId - 1 384 } else if (c != null) { 385 c = parseInt(c); 386 this.currId = c < 0 ? 0 : c > this.allItems - 1 ? this.allItems - 1 : c; 387 var h = a ? a.parent().parent().hasClass(this.cssNames.navClip) ? false : true : true 388 } 389 if (this.goBtns) { 390 this.gBtns.removeClass(this.cssNames.btnDisable) 391 } 392 if (!this.options.circular) { 393 if (this.currId == -1) { 394 this.currId = 0; 395 f = 1 396 } 397 if (this.currId == 0 && this.goBtns) { 398 this.goBtnPrev.addClass(this.cssNames.btnDisable) 399 } 400 if (this.currId == this.allItems) { 401 this.currId = this.allItems - 1; 402 f = 1 403 } 404 if (this.currId == this.allItems - 1) { 405 if (this.options.auto) { 406 this.autoScrollStop() 407 } 408 if (this.goBtns) { 409 this.goBtnNext.addClass(this.cssNames.btnDisable) 410 } 411 } 412 } else if (!this.scrollActive) { 413 if (this.currId == this.allItems) { 414 this.currId = 0 415 } 416 if (this.currId == -1) { 417 this.currId = this.allItems - 1 418 } 419 } 420 if (this.scrollActive && !f) { 421 this._setNavScroll(d, b, h) 422 } 423 if (this.isNavClip) {
424 this.selectThumbnail(this.currId) 425 } 426 if (!(d && !this.options.navpanelautoswitch)) { 427 if (this.arePanels) { 428 this._animPanel(this.currId, b) 429 } 430 } 431 if (this.firstTime) { 432 this.firstTime = 0 433 } 434 } 435 }; 436 this._setNavScroll = function (a, b, c) { 437 this._getNavPos(); 438 var d = a ? true : false; 439 var e = 0; 440 if (!a) { 441 var f = Math.abs(this.currId + 1 - this.LIbefore); 442 var g = this.options.shownavitems - f + 1; 443 var h = this.currId == 0 || this.currId == this.allItems - 1 ? 1 : 0; 444 if ((this.options.navscrollatend && (g == 1 || f == 1)) && !this.firstTime && !h) { 445 e = this.options.scroll - 1; 446 d = true 447 } 448 if (g == 0 || f == 0) { 449 d = true 450 } 451 if (c) { 452 if (g < 0) { 453 g = 0 454 } 455 b = this.prevId < this.currId ? '-=' : '+='; 456 var i = Math.abs(this.prevId - this.currId); 457 if ((i - 1 > g && b == '-=') || (i > f && b == '+=')) { 458 e = i; 459 d = true 460 } 461 } 462 if (b == "") { 463 if (this.prevId == this.currId && !h) { 464 b = this.scrollWay == "-=" ? "+=" : "-=" 465 } else { 466 b = this.prevId < this.currId ? "-=" : "+=" 467 } 468 } 469 this.scrollWay = b 470 } 471 if (d) { 472 var j = e > 0 ? e : this.options.scroll; 473 var k = b == "-=" ? this.LIafter : this.LIbefore; 474 var l = k < j ? k : j; 475 var m = l * this.navLIsize; 476 this.newId = b == "-=" ? this.LIbefore + l : this.LIbefore - l + this.options.shownavitems - 1; 477 if ((b == "-=" && this.newId > this.currId) || (b == "+=" && this.newId < this.currId)) { 478 this.currId = this.newId 479 } 480 if (this.options.circular) { 481 if (this.LIbefore <= 0 && b == "+=") { 482 b = "-="; 483 this.currId = this.allItems - 1; 484 m = (this.LIafter / this.options.scroll) * (this.navLIsize * this.options.scroll) 485 } else if (this.LIafter == 0 && b == "-=") { 486 b = "+="; 487 this.currId = 0; 488 m = Math.abs(this.navPos) 489 } 490 } 491 this._animNav(b, m) 492 } 493 }; 494 this._animPanel = function (a, b) { 495 this.currPanel = this.panels.eq(a); 496 this.prevPanelStill = this.panels.eq(this.prevId); 497 var c = function () { 498 if ($.isFunction(n.options.panelfxafter)) { 499 n.options.panelfxafter() 500 } 501 n._runCallBacks(n.panelPostFns) 502 }; 503 if (!this.currPanel.hasClass(this.cssNames.panelActive)) { 504 if (this.firstTime) { 505 this.panelTransition = this.options.panelfxfirst; 506 var d = 1 507 } else { 508 var e = this.options.freeheight && this.options.panelfx == "fading" ? "tabsfading" : "none"; 509 this.panelTransition = this.options.freeheight ? e : this.options.panelfx 510 } 511 if ($.isFunction(n.options.panelfxbefore)) { 512 n.options.panelfxbefore() 513 } 514 this._runCallBacks(this.panelAnteFns); 515 this._panelTransitions[this.panelTransition](b, d, c) 516 } 517 }; 518 this._animNav = function (a, b) { 519 var c = function () { 520 if (!n.options.circular && n.scrollBtns) { 521 n.navBtns.removeClass(n.cssNames.btnDisable); 522 n._getNavPos(); 523 if (n.LIbefore <= 0) { 524 n.navBtnPrev.addClass(n.cssNames.btnDisable) 525 } else if (n.LIafter <= 0) { 526 n.navBtnNext.addClass(n.cssNames.btnDisable) 527 } 528 } 529 if (n.scrollcontinue) { 530 setTimeout(function () { 531 n.scrollcontinue == "-=" ? n.navPrev() : n.navNext() 532 }, 0) 533 } else if ($.isFunction(n.options.navfxafter)) { 534 n.options.navfxafter() 535 } 536 n._runCallBacks(n.navPostFns) 537 }; 538 if ($.isFunction(n.options.navfxbefore)) { 539 n.options.navfxbefore() 540 } 541 n._runCallBacks(n.navAnteFns); 542 this._navTransitions[this.options.navfx](a, b, c) 543 }; 544 this._runCallBacks = function (c) { 545 $.each(c, function (a, b) { 546 if ($.isFunction(b)) { 547 b() 548 } 549 }) 550 }; 551 this._clearCallBacks = function (a) { 552 a.length = 0 553 }; 554 this._panelTransitions = { 555 none: function (a, b, c) { 556 n.panels.removeClass(n.cssNames.panelActive).hide(); 557 n.currPanel.addClass(n.cssNames.panelActive).show(); 558 c() 559 }, 560 sliding: function (a, b, c) { 561 if (a == "") { 562 a = n.prevPanel < n.currId ? "-=" : "+=" 563 } 564 n.prevPanel = n.currId; 565 var d = a == "-=" ? "+" : "-"; 566 var e = n.options.verticalslide ? "top" : "left"; 567 var f = n.options.verticalnav ? n.domObjHeight : n.domObjWidth; 568 var g = e == "top" ? { 569 top: a + f 570 } : { 571 left: a + f 572 }; 573 n.oldPanel = $("." + n.cssNames.panelOld, n.domObj); 574 n.activePanel = $("." + n.cssNames.panelActive, n.domObj); 575 n.panels.css(e, "0"); 576 n.oldPanel.removeClass(n.cssNames.panelOld).hide(); 577 n.activePanel.removeClass(n.cssNames.panelActive).addClass(n.cssNames.panelOld); 578 n.currPanel.addClass(n.cssNames.panelActive).css(e, d + f + "px").show();
579 n.panelsWrapper.stop(true, true).css(e, "0").animate(g, n.options.panelfxspeed, n.options.panelfxeasing, function () { 580 c() 581 }) 582 }, 583 fading: function (a, b, c) { 584 if (b) { 585 n.panels.hide() 586 } else { 587 n.currPanel.css("display", "none") 588 } 589 $("." + n.cssNames.panelOld, n.domObj).removeClass(n.cssNames.panelOld); 590 $("." + n.cssNames.panelActive, n.domObj).stop(true, true).removeClass(n.cssNames.panelActive).addClass(n.cssNames.panelOld); 591 n.currPanel.addClass(n.cssNames.panelActive).animate({ 592 "opacity": "show" 593 }, n.options.panelfxspeed, n.options.panelfxeasing, function () { 594 c() 595 }) 596 }, 597 tabsfading: function (a, b, c) { 598 n.panels.removeClass(n.cssNames.panelActive).hide(); 599 n.currPanel.fadeIn(n.options.panelfxspeed, function () { 600 c() 601 }) 602 } 603 }; 604 this._navTransitions = { 605 none: function (a, b, c) { 606 var d = a == "-=" ? n.navPos - b : n.navPos + b; 607 n.navUL.css(n.cssPosAttr, d + "px"); 608 c() 609 }, 610 sliding: function (a, b, c) { 611 n.navUL.animate(n.cssPosAttr == "left" ? { 612 left: a + b 613 } : { 614 top: a + b 615 }, n.options.scrollspeed, n.options.scrolleasing, function () { 616 c() 617 }) 618 } 619 }; 620 this.playBtnPause = function () { 621 this.playBtn.removeClass(this.cssNames.btnPause); 622 this.autoScrollStop() 623 }; 624 this.playBtnStart = function () { 625 this.playBtn.addClass(n.cssNames.btnPause); 626 this.autoScrollStart() 627 }; 628 this.autoScrollStart = function () { 629 var a = this; 630 this.isPlaying = setInterval(function () { 631 a._change(null, "-=", null, a.lineScrollDo, null) 632 }, a.options.autospeed) 633 }; 634 this.autoScrollStop = function () { 635 clearTimeout(this.isPlaying); 636 this.isPlaying = null 637 }; 638 this.changeWithId = function (a, b) { 639 this._change(b, "", a, 0, 1) 640 }; 641 this.stepBackward = function (a) { 642 this._change(a, "+=", null, n.lineScrollDo, 1) 643 }; 644 this.stepForward = function (a) { 645 this._change(a, "-=", null, n.lineScrollDo, 1) 646 }; 647 this.navPrev = function (c) { 648 if (c) { 649 n.scrollcontinue = "-=" 650 } 651 this._change(this.navBtnPrev, "+=", null, 1, 1) 652 }; 653 this.navNext = function (c) { 654 if (c) { 655 n.scrollcontinue = "+=" 656 } 657 this._change(this.navBtnNext, "-=", null, 1, 1) 658 }; 659 this.navStopContinuous = function () { 660 n.scrollcontinue = "" 661 }; 662 this.selectThumbnail = function (a) { 663 $("." + this.cssNames.selected, this.navUL).removeClass(this.cssNames.selected); 664 this.navLI.eq(a).addClass(this.cssNames.selected) 665 } 666 }; 667 $.fn.sliderkit = function (a) { 668 return this.each(function () { 669 $(this).data("sliderkit", new SliderKit()._init(this, a)) 670 }) 671 } 672})(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.