PageSourceSearch

https://patriothydro.com/wp-content/plugins/mapsvg/dist/Mapsvg-DZ70V7wV.js

js patriothydro.com collected 2026-10-04 07:45:21 UTC 24,726 bytes, 750 lines download raw bytes

1/******************************************************************************
2Copyright (c) Microsoft Corporation.
3
4Permission to use, copy, modify, and/or distribute this software for any
5purpose with or without fee is hereby granted.
6
7THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13PERFORMANCE OF THIS SOFTWARE.
14***************************************************************************** */
15/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
16
17
18function __rest(s, e) {
19    var t = {};
20    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
21        t[p] = s[p];
22    if (s != null && typeof Object.getOwnPropertySymbols === "function")
23        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
24            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
25                t[p[i]] = s[p[i]];
26        }
27    return t;
28}
29
30function __awaiter(thisArg, _arguments, P, generator) {
31    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
32    return new (P || (P = Promise))(function (resolve, reject) {
33        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
34        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
35        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
36        step((generator = generator.apply(thisArg, _arguments || [])).next());
37    });
38}
39
40typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
41    var e = new Error(message);
42    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
43};
44
45jQuery;
46class ResizeSensor {
47    constructor(element, callback) {
48        const _this = this;
49        _this.element = element;
50        _this.callback = callback;
51        const style = getComputedStyle(element);
52        let zIndex = parseInt(style.zIndex);
53        if (isNaN(zIndex)) {
54            zIndex = 0;
55        }
56        zIndex--;
57        _this.expand = document.createElement("div");
58        _this.expand.style.position = "absolute";
59        _this.expand.style.left = "0px";
60        _this.expand.style.top = "0px";
61        _this.expand.style.right = "0px";
62        _this.expand.style.bottom = "0px";
63        _this.expand.style.overflow = "hidden";
64        _this.expand.style.zIndex = zIndex.toString();
65        _this.expand.style.visibility = "hidden";
66        const expandChild = document.createElement("div");
67        expandChild.style.position = "absolute";
68        expandChild.style.left = "0px";
69        expandChild.style.top = "0px";
70        expandChild.style.width = "10000000px";
71        expandChild.style.height = "10000000px";
72        _this.expand.appendChild(expandChild);
73        _this.shrink = document.createElement("div");
74        _this.shrink.style.position = "absolute";
75        _this.shrink.style.left = "0px";
76        _this.shrink.style.top = "0px";
77        _this.shrink.style.right = "0px";
78        _this.shrink.style.bottom = "0px";
79        _this.shrink.style.overflow = "hidden";
80        _this.shrink.style.zIndex = zIndex.toString();
81        _this.shrink.style.visibility = "hidden";
82        const shrinkChild = document.createElement("div");
83        shrinkChild.style.position = "absolute";
84        shrinkChild.style.left = "0px";
85        shrinkChild.style.top = "0px";
86        shrinkChild.style.width = "200%";
87        shrinkChild.style.height = "200%";
88        _this.shrink.appendChild(shrinkChild);
89        _this.element.appendChild(_this.expand);
90        _this.element.appendChild(_this.shrink);
91        const size = element.getBoundingClientRect();
92        _this.currentWidth = size.width;
93        _this.currentHeight = size.height;
94        _this.setScroll();
95        _this.expand.addEventListener("scroll", function () {
96            _this.onScroll();
97        });
98        _this.shrink.addEventListener("scroll", function () {
99            _this.onScroll();
100        });
101    }
102    onScroll() {
103        const _this = this;
104        const size = _this.element.getBoundingClientRect();
105        const newWidth = size.width;
106        const newHeight = size.height;
107        if (newWidth != _this.currentWidth || newHeight != _this.currentHeight) {
108            _this.currentWidth = newWidth;
109            _this.currentHeight = newHeight;
110            _this.callback();
111        }
112        this.setScroll();
113    }
114    setScroll() {
115        this.expand.scrollLeft = 10000000;
116        this.expand.scrollTop = 10000000;
117        this.shrink.scrollLeft = 10000000;
118        this.shrink.scrollTop = 10000000;
119    }
120    destroy() {
121        this.expand.remove();
122        this.shrink.remove();
123    }
124}
125
126const getUserAgent = () => navigator.userAgent.toLowerCase();
127const getDevice = () => {
128    const userAgent = getUserAgent();
129    const res = {
130        ios: userAgent.indexOf("ipad") > -1 ||
131            userAgent.indexOf("iphone") > -1 ||
132            userAgent.indexOf("ipod") > -1,
133        android: userAgent.indexOf("android") !== -1,
134    };
135    return res;
136};
137const isPhone = () => window.matchMedia("only screen and (max-width: 812px)").matches;
138const getBrowser = () => {
139    const userAgent = getUserAgent();
140    const browser = {
141        ie: userAgent.indexOf("msie") > -1 ||
142            userAgent.indexOf("trident") > -1 ||
143            userAgent.indexOf("edge") > -1,
144        firefox: userAgent.indexOf("firefox") > -1,
145        safari: userAgent.indexOf("safari") > -1 && userAgent.indexOf("chrome") === -1,
146    };
147    return browser;
148};
149const getMouseCoords = (e) => {
150    if ("originalEvent" in e) {
151        e = e.originalEvent;
152    }
153    if ("clientX" in e) {
154        e = e;
155        return {
156            x: e.clientX + $(document).scrollLeft(),
157            y: e.clientY + $(document).scrollTop(),
158        };
159    }
160    if ("pageX" in e) {
161        e = e;
162        return { x: e.pageX, y: e.pageY };
163    }
164    else if (window.mapsvg.touchDevice) {
165        e = e.originalEvent || e;
166        return e.touches && e.touches[0]
167            ? { x: e.touches[0].pageX, y: e.touches[0].pageY }
168            : { x: e.changedTouches[0].pageX, y: e.changedTouches[0].pageY };
169    }
170};
171const ucfirst = (string) => {
172    return string.charAt(0).toUpperCase() + string.slice(1);
173};
174const parseBoolean = (string) => {
175    switch (String(string).toLowerCase()) {
176        case "on":
177        case "true":
178        case "1":
179        case "yes":
180        case "y":
181            return true;
182        case "off":
183        case "false":
184        case "0":
185        case "no":
186        case "n":
187            return false;
188        default:
189            return undefined;
190    }
191};
192const isNumber = (n) => {
193    return !isNaN(parseFloat(n)) && isFinite(n);
194};
195const safeURL = (url) => {
196    if (url.indexOf("http://") == 0 || url.indexOf("https://") == 0)
197        url = "//" + url.split("://").pop();
198    return url.replace(/^.*\/\/[^/]+/, "");
199};
200const addTrailingSlash = (url) => {
201    return url.endsWith("/") ? url : url + "/";
202};
203const removeLeadingSlash = (str) => {
204    return str.startsWith("/") ? str.slice(1) : str;
205};
206const convertToText = (obj) => {
207    const string = [];
208    if (obj === null) {
209        return null;
210    }
211    if (obj === undefined) {
212        return '""';
213    }
214    else if (typeof obj == "object" && obj.join == undefined) {
215        let prop;
216        for (prop in obj) {
217            if (Object.prototype.hasOwnProperty.call(obj, prop)) {
218                const key = '"' + prop.replace(/"/g, '\\"') + '"';
219                string.push(key + ": " + convertToText(obj[prop]));
220            }
221        }
222        return "{" + string.join(",") + "}";
223    }
224    else if (typeof obj == "object" && !(obj.join == undefined)) {
225        let prop;
226        for (prop in obj) {
227            string.push(convertToText(obj[prop]));
228        }
229        return "[" + string.join(",") + "]";
230    }
231    else if (typeof obj == "function") {
232        return obj.toString().replace("function anonymous", "function");
233    }
234    else {
235        return JSON.stringify(obj);
236    }
237};
238const fixColorHash = (color) => {
239    const hexColorNoHash = new RegExp(/^([0-9a-f]{3}|[0-9a-f]{6})$/i);
240    if (typeof color === "string" && color.match(hexColorNoHash) !== null) {
241        color = "#" + color;
242    }
243    return color;
244};
245const throttle = (method, delay, scope, params) => {
246    clearTimeout(method._tId);
247    method._tId = setTimeout(function () {
248        method.apply(scope, params);
249    }, delay);
250};
251const debounce = (func, wait) => {
252    let timeout = null;
253    return function (...args) {
254        const context = this;
255        clearTimeout(timeout);
256        timeout = setTimeout(() => {
257            func.apply(context, args);
258        }, wait);
259    };
260};
261let geocoder;
262const geocode = (query, callback) => {
263    if (!window.google) {
264        console.error("MapSVG: Google Maps API is not loaded.");
265        jQuery.growl.error({
266            title: "Error",
267            message: "Google Maps API is not loaded",
268        });
269        return false;
270    }
271    if (!geocoder) {
272        geocoder = new google.maps.Geocoder();
273    }
274    throttle(geocoder.geocode, 500, geocoder, [
275        query,
276        function (results, status) {
277            if (status === "OK") {
278                callback(results);
279            }
280            else if (status === "ZERO_RESULTS") {
281                return;
282            }
283            else {
284                jQuery.growl &&
285                    jQuery.growl.error({
286                        title: "Error: " + status,
287                        message: "There is some problem with Google API keys. See browser's console for more details",
288                    });
289            }
290        },
291    ]);
292};
293function functionFromString(string) {
294    let func;
295    let error;
296    const fn = string.trim();
297    if (fn.indexOf("{") == -1 || fn.indexOf("function") !== 0 || fn.indexOf("(") == -1) {
298        return new SyntaxError("MapSVG user function error: no function body.");
299    }
300    const fnBody = fn.substring(fn.indexOf("{") + 1, fn.lastIndexOf("}"));
301    const params = fn.substring(fn.indexOf("(") + 1, fn.indexOf(")"));
302    try {
303        func = new Function(params, fnBody);
304    }
305    catch (err) {
306        error = err;
307    }
308    if (!error)
309        return func;
310    else
311        return error;
312}
313function toSnakeCase(str) {
314    return typeof str === "string" ? str.replace(/\s+/g, "_") : str;
315}
316const handleFailedRequest = (response) => {
317    let message = "";
318    if (response.status === 403) {
319        if (response.responseText.indexOf("Wordfence") !== -1) {
320            message +=
321                "The request has been blocked by Wordfence. " +
322                    'Switch Wordfence to "Learning mode", and save the map settings again. ' +
323                    "If the settings are saved successfully, you can switch Wordfence back to normal mode.";
324        }
325        else {
326            message +=
327                "The request has been blocked by your server. " +
328                    "Do you have mod_sec Apache's module enabled? If that's the case you need to change its settings.";
329        }
330    }
331    else {
332        if (response && response.responseText) {
333            try {
334                const _response = JSON.parse(response.responseText);
335                if (_response && _response.data && _response.data.error) {
336                    message = _response.data.error;
337                }
338            }
339            catch (e) {
340            }
341        }
342    }
343    $.growl.error({
344        title: "Error: " + response.status + " " + response.statusText,
345        message: message,
346        duration: 30000,
347    });
348};
349const isMac = () => {
350    return navigator.platform.toUpperCase().indexOf("MAC") >= 0;
351};
352const loadFiles = (files) => {
353    const scriptPromises = [];
354    files.forEach((file) => {
355        scriptPromises.push(loadFile(file));
356    });
357    return Promise.all(scriptPromises);
358};
359const getFileType = (url) => {
360    const jsPattern = /\.js($|\?)/;
361    const cssPattern = /\.css($|\?)/;
362    if (jsPattern.test(url)) {
363        return "JS";
364    }
365    else if (cssPattern.test(url)) {
366        return "CSS";
367    }
368    else {
369        return "Unknown";
370    }
371};
372const loadFile = (file) => {
373    return new Promise((resolve, reject) => {
374        const { path: url, children } = file;
375        const isScript = getFileType(url) === "JS";
376        const isStyle = getFileType(url) === "CSS";
377        if (isScript) {
378            const script = document.createElement("script");
379            script.src = window.mapsvg.routes.root + url;
380            if (script.src.indexOf("?v") === -1 && script.src.indexOf("&v") === -1) {
381                if (script.src.indexOf("?") === -1) {
382                    script.src += "?v=" + window.mapsvg.version;
383                }
384                else {
385                    script.src += "&v=" + window.mapsvg.version;
386                }
387            }
388            script.type = "text/javascript";
389            script.defer = false;
390            script.async = true;
391            script.onload = function () {
392                if (children && children.length > 0) {
393                    resolve(loadFiles(children));
394                }
395                else {
396                    resolve(url);
397                }
398            };
399            script.onerror = function () {
400                reject(new Error("Failed to load script " + url));
401            };
402            document.head.appendChild(script);
403        }
404        else if (isStyle) {
405            const link = document.createElement("link");
406            link.href = window.mapsvg.routes.root + url;
407            link.rel = "stylesheet";
408            document.head.appendChild(link);
409            resolve(url);
410        }
411    });
412};
413function compareVersions(v1, v2) {
414    if (v1 && !v2) {
415        return 1;
416    }
417    if (!v1 && v2) {
418        return -1;
419    }
420    if (!v1 && !v2) {
421        return 0;
422    }
423    const v1Parts = v1.split(".").map(Number);
424    const v2Parts = v2.split(".").map(Number);
425    const length = Math.max(v1Parts.length, v2Parts.length);
426    for (let i = 0; i < length; i++) {
427        const part1 = v1Parts[i] || 0;
428        const part2 = v2Parts[i] || 0;
429        if (part1 > part2)
430            return 1;
431        if (part1 < part2)
432            return -1;
433    }
434    return 0;
435}
436function* idGenerator() {
437    let id = 1;
438    while (true) {
439        yield id++;
440    }
441}
442const idGen = idGenerator();
443function useId() {
444    return idGen.next().value;
445}
446function deepMerge(target, middle, source) {
447    if (source === undefined) {
448        return deepMergeTwo(target, middle);
449    }
450    deepMergeTwo(target, middle);
451    return deepMergeTwo(target, source);
452}
453function deepMergeTwo(target, source) {
454    if (source === undefined) {
455        return target;
456    }
457    if (typeof source !== "object" || source === null) {
458        return source;
459    }
460    if (Array.isArray(source)) {
461        return source.map((item) => deepMergeTwo({}, item));
462    }
463    for (const key in source) {
464        if (Object.prototype.hasOwnProperty.call(source, key)) {
465            if (source[key] === undefined) {
466                continue;
467            }
468            if (typeof source[key] === "object" && source[key] !== null) {
469                if (typeof target[key] !== "object" || target[key] === null) {
470                    target[key] = {};
471                }
472                target[key] = deepMergeTwo(target[key], source[key]);
473            }
474            else {
475                target[key] = source[key];
476            }
477        }
478    }
479    return target;
480}
481const getNestedValue = (obj, path) => {
482    return path.split(".").reduce((acc, part) => acc && acc[part], obj);
483};
484const splitObjectAndField = (fields) => {
485    const linkParts = fields.split(".");
486    const object = linkParts[0];
487    const field = linkParts.slice(1).join(".");
488    return { object, field };
489};
490const env = {
491    isPhone,
492    isMac,
493    getBrowser,
494    getDevice,
495    getMouseCoords,
496    getUserAgent,
497};
498const numbers = {
499    isNumber,
500    parseBoolean,
501    compareVersions,
502};
503const strings = {
504    safeURL,
505    ucfirst,
506    convertToText,
507    fixColorHash,
508    removeLeadingSlash,
509    functionFromString,
510    toSnakeCase,
511};
512const funcs = {
513    geocode,
514    throttle,
515    deepMerge,
516    getNestedValue,
517    splitObjectAndField,
518};
519const files = {
520    getFileType,
521    loadFiles,
522    loadFile,
523};
524const http = {
525    handleFailedRequest,
526};
527const utils = {
528    env,
529    numbers,
530    strings,
531    funcs,
532    files,
533    http,
534};
535
536if (typeof $ === "undefined") {
537    $ = jQuery;
538}
539class Map {
540    constructor() { }
541}
542class Mapsvg {
543    constructor() {
544        this.loaded = false;
545        this.version = "8.4.22";
546        this.templatesLoaded = {};
547        this.mouse = { x: 0, y: 0 };
548        this.meta = {};
549        this.ResizeSensor = ResizeSensor;
550        this.googleMapsApiLoaded = false;
551        this.instances = [];
552        const { wp, mapsvg_paths, ajaxurl, mapsvg_runtime_vars, google } = window;
553        if (typeof wp !== "undefined" && typeof wp.media !== "undefined") {
554            this.mediaUploader = wp.media({
555                title: "Choose images",
556                button: {
557                    text: "Choose images",
558                },
559                multiple: true,
560            });
561        }
562        this.mouse = { x: 0, y: 0 };
563    }
564    static createClient(frontEndOptions) {
565        const options = frontEndOptions !== null && frontEndOptions !== void 0 ? frontEndOptions : window.mapsvgFrontendParams;
566        if (!options) {
567            throw new Error("MapSVG: can't initialize the core due to the missing front-end options.");
568        }
569        let mapsvgCore;
570        if (!mapsvgCore) {
571            mapsvgCore = new Mapsvg();
572            mapsvgCore.init(options);
573            window.MapSVG = mapsvgCore;
574        }
575        return mapsvgCore;
576    }
577    init(options) {
578        return __awaiter(this, void 0, void 0, function* () {
579            this.nonce = options.nonce;
580            this.routes = options.routes;
581            this.googleMaps = {
582                apiKey: options.google_maps_api_key,
583                onLoadCallbacks: [],
584                apiIsLoading: false,
585                loaded: false,
586            };
587            if (typeof window.ajaxurl !== "undefined") {
588                this.routes.ajaxurl = window.ajaxurl;
589            }
590            this.setEventHandlers();
591            this.extendBuiltins();
592            if (!window.mapsvg || window.mapsvg instanceof HTMLElement) {
593                const load = () => __awaiter(this, void 0, void 0, function* () {
594                    const initGlobalsFile = yield import('./InitGlobals-Cu3n4WND.js');
595                    initGlobalsFile.initGlobals();
596                });
597                yield load();
598            }
599            this.loadMaps();
600            this.initialized = true;
601        });
602    }
603    receiveMessageFromIframe(event) {
604        const frames = document.getElementsByTagName("iframe");
605        for (let i = 0; i < frames.length; i++) {
606            if (frames[i].contentWindow === event.source) {
607                jQuery(frames[i]).css({ height: event.data.height });
608                break;
609            }
610        }
611    }
612    loadMap(container) {
613        const _a = container.dataset, { id: _id, svgFileLastChanged: _svgFileLastChanged, viewBox: _viewBox, loadDb } = _a, rest = __rest(_a, ["id", "svgFileLastChanged", "viewBox", "loadDb"]);
614        const id = Number(_id);
615        const svgFileLastChanged = Number(_svgFileLastChanged);
616        if (typeof loadDb !== "undefined") {
617            deepMerge(rest, { database: { loadOnStart: loadDb === "true" } });
618        }
619        setTimeout(() => {
620            new window.mapsvg.map(container.id, { id, options: Object.assign({ id }, rest), svgFileLastChanged });
621        }, 5);
622    }
623    lazyLoadMap(container) {
624        const observer = new IntersectionObserver((entries) => {
625            entries.forEach((entry) => {
626                if (entry.isIntersecting) {
627                    this.loadMap(entry.target);
628                    observer.unobserve(entry.target);
629                }
630            });
631        }, {
632            root: null,
633            threshold: 0,
634        });
635        observer.observe(container);
636    }
637    loadMaps() {
638        this.unloadMaps();
639        const containers = document.querySelectorAll('.mapsvg[data-autoload="true"]');
640        containers.forEach((container) => {
641            if (container.dataset.lazy === "true") {
642                this.lazyLoadMap(container);
643            }
644            else {
645                this.loadMap(container);
646            }
647        });
648        this.loaded = true;
649    }
650    unloadMaps() {
651        const autoloadContainers = document.querySelectorAll('.mapsvg[data-autoload="true"]');
652        autoloadContainers.forEach((container) => {
653            const mapId = container.getAttribute("id");
654            const mapInstance = this.getById(mapId);
655            if (mapInstance) {
656                mapInstance.destroy();
657            }
658        });
659        this.loaded = false;
660    }
661    setEventHandlers() {
662        window.addEventListener("message", this.receiveMessageFromIframe, false);
663    }
664    addInstance(mapsvg) {
665        this.instances.push(mapsvg);
666    }
667    get(index) {
668        return this.instances[index];
669    }
670    getById(id) {
671        const instance = this.instances.filter(function (i) {
672            return i.id == id;
673        });
674        if (instance.length > 0) {
675            return instance[0];
676        }
677    }
678    getByContainerId(id) {
679        const instance = this.instances.filter(function (i) {
680            return i.$map.attr("id") == id;
681        });
682        if (instance.length > 0) {
683            return instance[0];
684        }
685    }
686    extend(sub, base) {
687        sub.prototype = Object.create(base.prototype);
688        sub.prototype.constructor = sub;
689    }
690    set nonce(_nonce) {
691        this._nonce = _nonce;
692    }
693    get nonce() {
694        return this._nonce;
695    }
696    get googleMapsApiKey() {
697        return this.googleMaps.apiKey;
698    }
699    extendBuiltins() {
700        if (!String.prototype.trim) {
701            String.prototype.trim = function () {
702                return this.replace(/^\s+|\s+$/g, "");
703            };
704        }
705        if (!("remove" in Element.prototype)) {
706            Element.prototype.remove = function () {
707                if (this.parentNode) {
708                    this.parentNode.removeChild(this);
709                }
710            };
711        }
712        Math.hypot =
713            Math.hypot ||
714                function (...args) {
715                    let y = 0;
716                    const length = args.length;
717                    for (let i = 0; i < length; i++) {
718                        if (args[i] === Infinity || args[i] === -Infinity) {
719                            return Infinity;
720                        }
721                        y += args[i] * args[i];
722                    }
723                    return Math.sqrt(y);
724                };
725        SVGElement.prototype.getTransformToElement =
726            SVGElement.prototype.getTransformToElement ||
727                function (toElement) {
728                    let value;
729                    try {
730                        value = toElement.getScreenCTM().inverse().multiply(this.getScreenCTM());
731                    }
732                    catch (e) {
733                        return;
734                    }
735                    return value;
736                };
737        if (!Object.values) {
738            Object.values = function (object) {
739                return Object.keys(object).map(function (k) {
740                    return object[k];
741                });
742            };
743        }
744    }
745}
746Mapsvg.initialized = false;
747const mapsvgCore = Mapsvg.createClient();
748
749export { Mapsvg as M, ResizeSensor as R, __rest as _, addTrailingSlash as a, __awaiter as b, useId as c, deepMerge as d, getMouseCoords as e, debounce as f, geocode as g, functionFromString as h, isPhone as i, utils as j, isNumber as k, fixColorHash as l, mapsvgCore as m, env as n, splitObjectAndField as o, parseBoolean as p, getNestedValue as q, removeLeadingSlash as r, safeURL as s, throttle as t, ucfirst as u, compareVersions as v, Map as w };
750//# sourceMappingURL=Mapsvg-DZ70V7wV.js.map

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.