PageSourceSearch

https://www.ptotoday.com/media/com_minitekslider/js/minitekslider.js?2eb5de

js ptotoday.com collected 2026-09-24 09:25:29 UTC 33,607 bytes, 831 lines download raw bytes

1((document, Joomla) => {
2    "use strict";
3
4    class Mslider {
5        /*
6         * Constructor
7         */
8        constructor(options, id, count, source, path, itemid) {
9            this.options = options;
10            this.widgetId = parseInt(id, 10);
11            this.totalCount = parseInt(count, 10);
12            this.sourceId = source;
13            this.path = path;
14            this.itemid = itemid;
15
16            this.navigatorEnabled = parseInt(this.options.slider_navigator, 10);
17            this.parallax = parseInt(this.options.slider_parallax, 10);
18            this.mediaSlider =
19                this.options.slider_theme == "media_slider" ? true : false;
20            this.hoverbox = parseInt(this.options.slider_hb, 10);
21            this.loadMore = parseInt(this.options.slider_load_more, 10);
22            this.container = document.querySelector(
23                "#mslider_" + this.widgetId
24            );
25            this.ignoreVideos = true;
26            this.videoSource =
27                typeof this.options.videoSource === "undefined"
28                    ? false
29                    : parseInt(this.options.videoSource, 10);
30
31            if (this.container == null) return;
32
33            // Initialize slider
34            this.initializeSlider();
35
36            // Load more items
37            if (this.loadMore) {
38                this.paginationDelay = 150;
39                this.appendItems();
40            }
41
42            // Navigator
43            if (this.navigatorEnabled) this.initializeNavigator();
44
45            // Progress bar
46            if (parseInt(this.options.slider_progressbar, 10))
47                this.initializeProgressBar();
48
49            // Parallax
50            if (this.parallax) this.triggerParallax();
51
52            // Media slider
53            if (this.mediaSlider) this.initializeMediaSlider();
54
55            // Modal images
56            if (this.hoverbox) {
57                if (parseInt(this.options.slider_hb_zoom, 10))
58                    this.initModalMessages();
59            }
60
61            // Check if we are inside an iframe
62            this.isIframe = window.frameElement ? true : false;
63
64            if (this.isIframe) {
65                if (document.querySelector(".mslider-description"))
66                    document.querySelector(
67                        ".mslider-description"
68                    ).style.padding = "20px";
69            }
70        }
71
72        initializeSlider() {
73            const self = this;
74            this.nav_container = document.querySelector(
75                "#mslider_nav_" + this.widgetId
76            );
77
78            this.draggable = parseInt(this.options.slider_drag, 10)
79                ? ">1"
80                : false;
81            this.freeScroll = parseInt(this.options.slider_free_scroll, 10)
82                ? true
83                : false;
84            var wrapAround =
85                parseInt(this.options.slider_rewind, 10) && !this.loadMore
86                    ? true
87                    : false;
88            this.groupCells = parseInt(this.options.slider_group_items, 10)
89                ? true
90                : false;
91            var autoplaySpeed = parseInt(
92                this.options.slider_autoplay_speed,
93                10
94            );
95            var autoPlay = parseInt(this.options.slider_autoplay, 10)
96                ? autoplaySpeed
97                : false;
98            var pauseAutoPlayOnHover = parseInt(
99                this.options.slider_pause_on_hover,
100                10
101            )
102                ? true
103                : false;
104            var fullscreen = parseInt(this.options.slider_fullscreen, 10)
105                ? true
106                : false;
107            var fade = parseInt(this.options.slider_fade, 10) ? true : false;
108            var adaptiveHeight = parseInt(
109                this.options.slider_adaptive_height,
110                10
111            )
112                ? true
113                : false;
114            var hash = parseInt(this.options.slider_hash, 10) ? true : false;
115            this.dragThreshold = parseInt(
116                this.options.slider_drag_threshold,
117                10
118            )
119                ? parseInt(this.options.slider_drag_threshold, 10)
120                : 3;
121            this.selectedAttraction = parseFloat(
122                this.options.slider_selected_attraction
123            )
124                ? parseFloat(this.options.slider_selected_attraction)
125                : 0.025;
126            this.friction = parseFloat(this.options.slider_friction)
127                ? parseFloat(this.options.slider_friction)
128                : 0.28;
129            this.freeScrollFriction = parseFloat(
130                this.options.slider_free_scroll_friction
131            )
132                ? parseFloat(this.options.slider_free_scroll_friction)
133                : 0.075;
134            var lazyLoad = parseInt(this.options.slider_lazyload, 10)
135                ? true
136                : false;
137            var initialIndex = parseInt(this.options.slider_initial_index, 10)
138                ? parseInt(this.options.slider_initial_index, 10) - 1
139                : 0;
140            var cellAlign = this.options.slider_cell_align;
141            var contain = parseInt(this.options.slider_contain, 10)
142                ? true
143                : false;
144            this.rightToLeft = parseInt(this.options.slider_rtl, 10)
145                ? true
146                : false;
147            var prevNextButtons = parseInt(this.options.slider_arrows, 10)
148                ? true
149                : false;
150            var pageDots = parseInt(this.options.slider_bullets, 10)
151                ? true
152                : false;
153
154            // Show slider
155            this.container.style.display = "block";
156
157            // Initialize Flickity
158            let update_slider = function () {
159                self.slider = new Flickity(self.container, {
160                    draggable: self.draggable,
161                    freeScroll: self.freeScroll,
162                    wrapAround: wrapAround,
163                    groupCells: self.groupCells,
164                    autoPlay: autoPlay,
165                    pauseAutoPlayOnHover: pauseAutoPlayOnHover,
166                    fullscreen: fullscreen,
167                    fade: fade,
168                    adaptiveHeight: adaptiveHeight,
169                    hash: hash,
170                    initialIndex: !hash ? initialIndex : undefined,
171                    dragThreshold: self.dragThreshold,
172                    selectedAttraction: self.selectedAttraction,
173                    friction: self.friction,
174                    freeScrollFriction: self.freeScrollFriction,
175                    imagesLoaded: true,
176                    lazyLoad: lazyLoad,
177                    cellSelector: ".mslider-item",
178                    accessibility: true,
179                    setGallerySize: true,
180                    resize: true,
181                    cellAlign: cellAlign,
182                    contain: contain,
183                    rightToLeft: self.rightToLeft,
184                    percentPosition: true,
185                    prevNextButtons: prevNextButtons,
186                    pageDots: pageDots,
187                    on: {
188                        ready: function () {
189                            document
190                                .querySelector(
191                                    "#mslider_wrapper_" + self.widgetId
192                                )
193                                .classList.add("flickity-ready");
194                            self.fixHeights(false);
195                        },
196                        fullscreenChange: function (isFullscreen) {
197                            if (self.navigatorEnabled) self.navigator.resize();
198
199                            if (isFullscreen) self.fixHeights(true);
200                            else self.fixHeights(false);
201
202                            self.slider.resize();
203                        },
204                    },
205                });
206            };
207
208            if (self.videoSource) self.videosReady(update_slider);
209
210            if (self.ignoreVideos) update_slider();
211        }
212
213        videosReady(callback) {
214            const self = this;
215            self.ignoreVideos = true;
216            const _videos = self.container.querySelectorAll("video");
217
218            if (_videos.length) {
219                let videos = [];
220
221                _videos.forEach((a) => {
222                    if (a.readyState == 0) videos.push(a);
223                });
224
225                if (videos.length) {
226                    self.ignoreVideos = false;
227                    let states = [];
228
229                    for (let i = 0; i < videos.length; i++) {
230                        states.push(0);
231                    }
232
233                    let promise = new Promise(function (resolve) {
234                        Object.keys(videos).forEach((key) => {
235                            videos[key].addEventListener("loadeddata", () => {
236                                states[key] = videos[key].readyState;
237
238                                // If all videos ready (readyState >=3), resolve promise
239                                if (states.every((v) => v >= 3))
240                                    resolve(states);
241                            });
242                        });
243                    });
244
245                    promise.then(function (value) {
246                        callback();
247                    });
248                }
249            }
250        }
251
252        appendItems() {
253            const self = this;
254            var ajax_request, nav_ajax_request;
255            var cells_loaded = self.slider.cells.length;
256            var new_cells_loaded, nav_cells_loaded;
257            var items_left = self.totalCount - cells_loaded;
258            var arrowsColor = self.options.slider_arrows_color;
259            var page = 2;
260            var new_page;
261            var next_button = self.container.querySelector(
262                ".flickity-button.next"
263            );
264
265            if (items_left > 0 && next_button) {
266                var next_clone = self.container
267                    .querySelector(".flickity-button.next")
268                    .cloneNode(true);
269                next_clone.classList.add("cloned");
270                self.insertAfter(next_clone, next_button);
271                next_clone.classList.add("disabled");
272                next_clone.style.display = "none";
273                next_clone.setAttribute("data-page", "2");
274                next_clone.appendChild(
275                    self.htmlToElement('<div class="mslider-loader"></div>')
276                );
277                self.createSpinner(".mslider-loader", arrowsColor);
278
279                // Corner case: 1st page has 0 or 1 slides
280                if (
281                    self.slider.slides.length == 0 ||
282                    self.slider.slides.length == 1
283                ) {
284                    self.container
285                        .querySelectorAll(".flickity-button.next")
286                        .forEach(function (a) {
287                            a.style.display = "none";
288                        });
289
290                    next_clone.classList.remove("disabled");
291                    next_clone.removeAttribute("disabled");
292                    next_clone.style.display = "block";
293                }
294
295                // Calculate visibility of cloned next button
296                self.slider.on("change", function (index) {
297                    if (self.groupCells)
298                        cells_loaded = self.slider.slides.length;
299                    else cells_loaded = self.slider.cells.length;
300
301                    items_left = self.totalCount - self.slider.cells.length;
302
303                    if (items_left > 0) {
304                        if (index == cells_loaded - 1) {
305                            self.container
306                                .querySelectorAll(".flickity-button.next")
307                                .forEach(function (a) {
308                                    a.style.display = "none";
309                                });
310
311                            next_clone.classList.remove("disabled");
312                            next_clone.style.display = "block";
313                        } else {
314                            self.container
315                                .querySelectorAll(".flickity-button.next")
316                                .forEach(function (a) {
317                                    a.style.display = "block";
318                                });
319
320                            next_clone.classList.add("disabled");
321                            next_clone.style.display = "none";
322                        }
323                    } else {
324                        self.container
325                            .querySelectorAll(".flickity-button.next")
326                            .forEach(function (a) {
327                                a.style.display = "block";
328                            });
329
330                        next_clone.remove();
331                    }
332                });
333
334                // Load more items
335                next_clone.addEventListener("click", function (e) {
336                    e.preventDefault();
337
338                    if (this.classList.contains("disabled")) return false;
339
340                    // Check if there is a pending ajax request
341                    if (typeof ajax_request !== "undefined")
342                        ajax_request.abort();
343
344                    if (self.groupCells) {
345                        new_cells_loaded = self.slider.slides.length;
346                        nav_cells_loaded = self.slider.cells.length;
347                    } else {
348                        new_cells_loaded = self.slider.cells.length;
349                        nav_cells_loaded = self.slider.cells.length;
350                    }
351
352                    page = next_clone.getAttribute("data-page");
353                    page = parseInt(page, 10);
354                    new_page = page + 1;
355
356                    // Increment data-page
357                    next_clone.setAttribute("data-page", new_page);
358
359                    // Show loader
360                    next_clone.classList.add("disabled");
361                    next_clone.querySelector("svg").style.display = "none";
362                    this.querySelector(".mslider-loader").style.display =
363                        "block";
364                    self.container.classList.add("is-loading");
365
366                    // Ajax
367                    ajax_request = Joomla.request({
368                        url:
369                            self.path +
370                            "index.php?option=com_minitekslider&task=slider.getContent&widget_id=" +
371                            self.widgetId +
372                            "&page=" +
373                            page +
374                            "&type=slider" +
375                            "&Itemid=" +
376                            self.itemid,
377                        method: "GET",
378                        onSuccess: (response, xhr) => {
379                            if (response.length > 3) {
380                                var items_array = response.split(
381                                    '<div class="mslider-media-db">'
382                                );
383                                var dbs = items_array[1];
384
385                                if (self.mediaSlider) {
386                                    // Update detail box in media slider
387                                    var dbItems = self.htmlToElements(
388                                        dbs,
389                                        ".mslider-detail-box"
390                                    );
391
392                                    dbItems.forEach(function (a) {
393                                        self.container
394                                            .querySelector(".mslider-media-db")
395                                            .appendChild(a);
396                                    });
397
398                                    self.container
399                                        .querySelectorAll(
400                                            ".mslider-media-db .mslider-detail-box"
401                                        )
402                                        .forEach(function (element, index) {
403                                            element.setAttribute(
404                                                "data-selectedindex",
405                                                index
406                                            );
407                                        });
408                                }
409
410                                // Load items
411                                var sliderItems = self.htmlToElements(
412                                    response,
413                                    ".mslider-item"
414                                );
415                                self.slider.append(sliderItems);
416
417                                // Fix heights
418                                if (
419                                    self.container.classList.contains(
420                                        "is-fullscreen"
421                                    )
422                                ) {
423                                    if (!self.mediaSlider)
424                                        self.fixHeights(true);
425                                } else self.fixHeights(false);
426
427                                // Initialize parallax
428                                if (self.parallax) self.triggerParallax();
429
430                                // Fade in items
431                                self.slider.once("select", function () {
432                                    self.container
433                                        .querySelectorAll(".mslider-item")
434                                        .forEach(function (a) {
435                                            a.classList.remove(
436                                                "mslider-item-hidden"
437                                            );
438                                        });
439
440                                    self.slider.resize();
441                                });
442
443                                // Update Navigator
444                                if (self.navigatorEnabled) {
445                                    nav_ajax_request = Joomla.request({
446                                        url:
447                                            self.path +
448                                            "index.php?option=com_minitekslider&task=slider.getContent&widget_id=" +
449                                            self.widgetId +
450                                            "&page=" +
451                                            page +
452                                            "&type=navigator" +
453                                            "&Itemid=" +
454                                            self.itemid,
455                                        method: "GET",
456                                        onSuccess: (response, xhr) => {
457                                            if (response.length > 3) {
458                                                // Load items
459                                                var navItems =
460                                                    self.htmlToElements(
461                                                        response,
462                                                        ".mslider-nav-item"
463                                                    );
464                                                self.navigator.append(navItems);
465                                                self.slider.select(
466                                                    new_cells_loaded
467                                                );
468
469                                                self.nav_container
470                                                    .querySelectorAll(
471                                                        ".mslider-nav-item"
472                                                    )
473                                                    .forEach(function (a) {
474                                                        a.classList.remove(
475                                                            "mslider-item-hidden"
476                                                        );
477                                                    });
478
479                                                self.container.classList.remove(
480                                                    "is-loading"
481                                                );
482                                            }
483                                        },
484                                        onError: (xhr) => {
485                                            console.log(xhr);
486                                        },
487                                    });
488                                } else {
489                                    if (page <= 2) {
490                                        // Make sure selection is delayed, otherwise the items heights are not calculated correctly on 2nd page
491                                        setTimeout(function () {
492                                            self.slider.select(
493                                                new_cells_loaded
494                                            );
495                                            self.container.classList.remove(
496                                                "is-loading"
497                                            );
498                                        }, self.paginationDelay);
499                                    } else {
500                                        self.slider.select(new_cells_loaded);
501                                        self.container.classList.remove(
502                                            "is-loading"
503                                        );
504                                    }
505                                }
506
507                                // Hide loader
508                                next_clone.querySelector("svg").style.display =
509                                    "block";
510                                next_clone.querySelector(
511                                    ".mslider-loader"
512                                ).style.display = "none";
513                            } else {
514                                self.container
515                                    .querySelectorAll(".flickity-button.next")
516                                    .forEach(function (a) {
517                                        a.style.display = "block";
518                                    });
519
520                                next_clone.remove();
521                                self.container.classList.remove("is-loading");
522                            }
523                        },
524                        onError: (xhr) => {
525                            console.log(xhr);
526                        },
527                    });
528                });
529            }
530        }
531
532        initializeNavigator() {
533            const self = this;
534            var prevNextButtons = parseInt(
535                this.options.slider_navigator_arrows,
536                10
537            );
538
539            // Show navigator
540            self.nav_container.style.display = "block";
541
542            // Initialize navigator
543            self.navigator = new Flickity(self.nav_container, {
544                draggable: self.draggable,
545                freeScroll: self.freeScroll,
546                groupCells: false,
547                asNavFor: "#mslider_" + self.widgetId,
548                dragThreshold: self.dragThreshold,
549                selectedAttraction: self.selectedAttraction,
550                friction: self.friction,
551                freeScrollFriction: self.freeScrollFriction,
552                imagesLoaded: true,
553                lazyLoad: false,
554                cellSelector: ".mslider-nav-item",
555                accessibility: true,
556                setGallerySize: true,
557                resize: true,
558                contain: true,
559                rightToLeft: self.rightToLeft,
560                percentPosition: true,
561                prevNextButtons: prevNextButtons,
562                pageDots: false,
563            });
564        }
565
566        fixHeights(fullscreen, index = false) {
567            var sliderPaddingTop = parseInt(
568                this.options.slider_cont_padding,
569                10
570            );
571            var sliderPaddingBottom = sliderPaddingTop;
572            var sliderMarginBottom = 30;
573            var mediaDbPaddingTop = 40;
574            var maxMediaDb = 350;
575            var navBottom = 10;
576            var bullets = this.container.querySelector(".flickity-page-dots");
577            var progressbar = document.querySelector(
578                "#mslider_progressbar_" + this.widgetId
579            );
580
581            if (fullscreen) {
582                // Fix slider height
583                var height =
584                    document.querySelector("#mslider_wrapper_" + this.widgetId)
585                        .offsetHeight - sliderPaddingTop;
586                var slider_height = 0;
587                var media_db_height = 0;
588                var navigator_height = 0;
589                var viewport_height;
590
591                if (this.mediaSlider) {
592                    if (index !== false) {
593                        var detail_boxes = this.container.querySelectorAll(
594                            ".mslider-media-db .mslider-detail-box"
595                        );
596
597                        if (detail_boxes)
598                            media_db_height =
599                                detail_boxes[index].offsetHeight +
600                                mediaDbPaddingTop;
601                    } else {
602                        if (this.container.querySelector(".mslider-media-db"))
603                            media_db_height =
604                                this.container.querySelector(
605                                    ".mslider-media-db"
606                                ).offsetHeight + mediaDbPaddingTop;
607                    }
608
609                    media_db_height =
610                        media_db_height > maxMediaDb
611                            ? maxMediaDb
612                            : media_db_height;
613                }
614
615                if (this.nav_container) {
616                    navigator_height =
617                        this.nav_container.offsetHeight + navBottom;
618
619                    if (bullets) sliderMarginBottom = 2 * sliderMarginBottom;
620                } else {
621                    if (!bullets && !progressbar)
622                        height = height - sliderPaddingBottom;
623                    else {
624                        if (bullets && !progressbar)
625                            sliderMarginBottom = 2 * sliderMarginBottom;
626                        else if (!bullets && progressbar)
627                            sliderMarginBottom = 10;
628                        else if (bullets && progressbar)
629                            sliderMarginBottom = 2 * sliderMarginBottom;
630                    }
631                }
632
633                // Update calculations
634                sliderMarginBottom =
635                    bullets || progressbar || this.nav_container
636                        ? sliderMarginBottom
637                        : 0;
638
639                // Container
640                slider_height = height - sliderMarginBottom - navigator_height;
641                this.container.style.height = slider_height + "px";
642
643                // Viewport
644                viewport_height = slider_height - media_db_height;
645                this.container.querySelector(
646                    ".flickity-viewport"
647                ).style.maxHeight = viewport_height + "px";
648
649                // Images
650                if (
651                    this.container.querySelectorAll(".mslider-photo-link img")
652                ) {
653                    var max_height =
654                        this.container.querySelector(
655                            ".flickity-viewport"
656                        ).offsetHeight;
657
658                    this.container
659                        .querySelectorAll(".mslider-photo-link img")
660                        .forEach(function (a) {
661                            a.style.maxHeight = max_height + "px";
662                        });
663                }
664            } else {
665                // Main
666                this.container.style.height = "auto";
667
668                // Viewport
669                this.container.querySelector(
670                    ".flickity-viewport"
671                ).style.maxHeight = "inherit";
672
673                // Images
674                if (
675                    this.container.querySelectorAll(".mslider-photo-link img")
676                ) {
677                    this.container
678                        .querySelectorAll(".mslider-photo-link img")
679                        .forEach(function (a) {
680                            a.style.maxHeight = "inherit";
681                        });
682                }
683            }
684        }
685
686        initializeProgressBar() {
687            var progressBar = document.querySelector(
688                "#mslider_progressbar_" + this.widgetId
689            );
690
691            this.slider.on("scroll", function (progress) {
692                progress = Math.max(0, Math.min(1, progress));
693                progressBar.style.width = progress * 100 + "%";
694            });
695        }
696
697        triggerParallax() {
698            const self = this;
699            var imgs = self.container.querySelectorAll(".mslider-item img");
700
701            if (imgs) {
702                self.slider.on("scroll", function (progress) {
703                    self.slider.slides.forEach(function (slide, i) {
704                        var img = imgs[i];
705                        var x = ((slide.target + self.slider.x) * -1) / 3;
706
707                        if (img)
708                            img.style.transform = "translateX(" + x + "px)";
709                    });
710                });
711            }
712        }
713
714        initializeMediaSlider() {
715            const self = this;
716            var media_db = self.container.querySelector(".mslider-media-db");
717            var viewport = self.container.querySelector(".flickity-viewport");
718            self.insertAfter(media_db, viewport);
719
720            media_db
721                .querySelectorAll(".mslider-detail-box")
722                .forEach(function (element, index) {
723                    element.setAttribute("data-selectedindex", index);
724                });
725
726            media_db.querySelector(
727                '.mslider-detail-box[data-selectedindex="0"]'
728            ).style.display = "block";
729
730            self.slider.on("select", function (index) {
731                media_db
732                    .querySelectorAll(".mslider-detail-box")
733                    .forEach(function (a) {
734                        a.style.display = "none";
735                    });
736
737                media_db.querySelector(
738                    '.mslider-detail-box[data-selectedindex="' + index + '"]'
739                ).style.display = "block";
740
741                // Update heights in fullscreen
742                if (self.slider.isFullscreen) self.fixHeights(true, index);
743            });
744        }
745
746        createSpinner(divIdentifier, color) {
747            var spinner_options = {
748                lines: 9,
749                length: 4,
750                width: 3,
751                radius: 3,
752                corners: 1,
753                rotate: 0,
754                direction: 1,
755                color: color,
756                speed: 1,
757                trail: 52,
758                shadow: false,
759                hwaccel: false,
760                className: "spinner",
761                zIndex: 2e9,
762                top: "50%",
763                left: "50%",
764            };
765
766            var target = document.querySelector(divIdentifier);
767
768            if (target) {
769                var spinner = new Spinner(spinner_options).spin();
770                target.innerHTML = "";
771                target.appendChild(spinner.el);
772            }
773
774            return;
775        }
776
777        insertAfter(newNode, referenceNode) {
778            referenceNode.parentNode.insertBefore(
779                newNode,
780                referenceNode.nextSibling
781            );
782        }
783
784        htmlToElement(htmlString) {
785            var div = document.createElement("div");
786            div.innerHTML = htmlString.trim();
787
788            return div.firstChild;
789        }
790
791        htmlToElements(htmlString, selector) {
792            var div = document.createElement("div");
793            div.innerHTML = htmlString.trim();
794
795            return div.querySelectorAll(selector);
796        }
797
798        initModalMessages() {
799            var zoomSlider = document.querySelector(
800                "#zoomSlider_" + this.widgetId
801            );
802
803            if (!zoomSlider) return;
804
805            zoomSlider.addEventListener("show.bs.modal", function (e) {
806                // Button that triggered the modal
807                var button = e.relatedTarget;
808
809                // Update the title
810                if (zoomSlider.querySelector(".modal-title")) {
811                    var title = button.getAttribute("data-ms-title");
812                    zoomSlider.querySelector(".modal-title").textContent =
813                        title;
814                }
815
816                // Update the image
817                var image = button.getAttribute("data-src");
818                zoomSlider.querySelector("img").setAttribute("src", image);
819            });
820
821            zoomSlider.addEventListener("hidden.bs.modal", function (e) {
822                zoomSlider.querySelector("img").setAttribute("src", "");
823            });
824        }
825    }
826
827    window.Mslider = {
828        initialise: (options, id, count, source, path, itemid) =>
829            new Mslider(options, id, count, source, path, itemid),
830    };
831})(document, Joomla);

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.