PageSourceSearch

https://neurosell.tech/assets/js/vendor/debug.addIndicators.min.js

js neurosell.tech collected 2026-10-07 17:49:27 UTC 30,030 bytes, 677 lines download raw bytes

1/*!
2 * @file Debug Extension for ScrollMagic.
3 */
4/**
5 * This plugin was formerly known as the ScrollMagic debug extension.
6 *
7 * It enables you to add visual indicators to your page, to be able to see exactly when a scene is triggered.
8 *
9 * To have access to this extension, please include `plugins/debug.addIndicators.js`.
10 * @mixin debug.addIndicators
11 */
12(function (root, factory) {
13    if (typeof define === 'function' && define.amd) {
14        // AMD. Register as an anonymous module.
15        define(['ScrollMagic'], factory);
16    } else if (typeof exports === 'object') {
17            // CommonJS
18            factory(require('scrollmagic'));
19    } else {
20            // no browser global export needed, just execute
21        factory(root.ScrollMagic || (root.jQuery && root.jQuery.ScrollMagic));
22    }
23}(this, function(ScrollMagic) {
24    "use strict";
25    var NAMESPACE = "debug.addIndicators";
26
27    // (BUILD) - REMOVE IN MINIFY - START
28    var
29        console = window.console || {},
30        err = Function.prototype.bind.call(console.error || console.log || function() {}, console);
31    if (!ScrollMagic) {
32        err("(" + NAMESPACE + ") -> ERROR: The ScrollMagic main module could not be found. Please make sure it's loaded before this plugin or use an asynchronous loader like requirejs.");
33    }
34    // (BUILD) - REMOVE IN MINIFY - END
35
36    // plugin settings
37    var
38        FONT_SIZE = "0.85em",
39        ZINDEX = "9999",
40        EDGE_OFFSET = 15; // minimum edge distance, added to indentation
41
42    // overall vars
43    var
44        _util = ScrollMagic._util,
45        _autoindex = 0;
46
47
48
49    ScrollMagic.Scene.extend(function () {
50        var
51            Scene = this,
52            _indicator;
53
54        // (BUILD) - REMOVE IN MINIFY - START
55        var log = function () {
56            if (Scene._log) { // not available, when main source minified
57                Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->");
58                Scene._log.apply(this, arguments);
59            }
60        };
61        // (BUILD) - REMOVE IN MINIFY - END
62
63        /**
64         * Add visual indicators for a ScrollMagic.Scene.
65         * @memberof! debug.addIndicators#
66         *
67         * @example
68         * // add basic indicators
69         * scene.addIndicators()
70         *
71         * // passing options
72         * scene.addIndicators({name: "pin scene", colorEnd: "#FFFFFF"});
73         *
74         * @param {object} [options] - An object containing one or more options for the indicators.
75         * @param {(string|object)} [options.parent] - A selector, DOM Object or a jQuery object that the indicators should be added to.
76                                                                                                                         If undefined, the controller's container will be used.
77         * @param {number} [options.name=""] - This string will be displayed at the start and end indicators of the scene for identification purposes. If no name is supplied an automatic index will be used.
78         * @param {number} [options.indent=0] - Additional position offset for the indicators (useful, when having multiple scenes starting at the same position).
79         * @param {string} [options.colorStart=green] - CSS color definition for the start indicator.
80         * @param {string} [options.colorEnd=red] - CSS color definition for the end indicator.
81         * @param {string} [options.colorTrigger=blue] - CSS color definition for the trigger indicator.
82         */
83        Scene.addIndicators = function(options) {
84            if (!_indicator) {
85                var
86                    DEFAULT_OPTIONS = {
87                        name: "",
88                        indent: 0,
89                        parent: undefined,
90                        colorStart: "green",
91                        colorEnd: "red",
92                        colorTrigger: "blue",
93                    };
94
95                options = _util.extend({}, DEFAULT_OPTIONS, options);
96
97                _autoindex++;
98                _indicator = new Indicator(Scene, options);
99
100                Scene.on("add.plugin_addIndicators", _indicator.add);
101                Scene.on("remove.plugin_addIndicators", _indicator.remove);
102                Scene.on("destroy.plugin_addIndicators", Scene.removeIndicators);
103
104                // it the scene already has a controller we can start right away.
105                if (Scene.controller()) {
106                    _indicator.add();
107                }
108            }
109            return Scene;
110        };
111
112        /**
113         * Removes visual indicators from a ScrollMagic.Scene.
114         * @memberof! debug.addIndicators#
115         *
116         * @example
117         * // remove previously added indicators
118         * scene.removeIndicators()
119         *
120         */
121        Scene.removeIndicators = function() {
122            if (_indicator) {
123                _indicator.remove();
124                this.off("*.plugin_addIndicators");
125                _indicator = undefined;
126            }
127            return Scene;
128        };
129
130    });
131
132
133    /*
134     * ----------------------------------------------------------------
135     * Extension for controller to store and update related indicators
136     * ----------------------------------------------------------------
137     */
138    // add option to globally auto-add indicators to scenes
139    /**
140     * Every ScrollMagic.Controller instance now accepts an additional option.
141     * See {@link ScrollMagic.Controller} for a complete list of the standard options.
142     * @memberof! debug.addIndicators#
143     * @method new ScrollMagic.Controller(options)
144     * @example
145     * // make a controller and add indicators to all scenes attached
146     * var controller = new ScrollMagic.Controller({addIndicators: true});
147     * // this scene will automatically have indicators added to it
148     * new ScrollMagic.Scene()
149     *                .addTo(controller);
150     *
151     * @param {object} [options] - Options for the Controller.
152     * @param {boolean} [options.addIndicators=false] - If set to `true` every scene that is added to the controller will automatically get indicators added to it.
153     */
154    ScrollMagic.Controller.addOption("addIndicators", false);
155    // extend Controller
156    ScrollMagic.Controller.extend(function () {
157        var
158            Controller = this,
159            _info = Controller.info(),
160            _container = _info.container,
161            _isDocument = _info.isDocument,
162            _vertical = _info.vertical,
163            _indicators = { // container for all indicators and methods
164                groups: []
165            };
166
167        // (BUILD) - REMOVE IN MINIFY - START
168        var log = function () {
169            if (Controller._log) { // not available, when main source minified
170                Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->");
171                Controller._log.apply(this, arguments);
172            }
173        };
174        if (Controller._indicators) {
175            log(2, "WARNING: Scene already has a property '_indicators', which will be overwritten by plugin.");
176        }
177        // (BUILD) - REMOVE IN MINIFY - END
178
179        // add indicators container
180        this._indicators = _indicators;
181        /*
182            needed updates:
183            +++++++++++++++
184            start/end position on scene shift (handled in Indicator class)
185            trigger parameters on triggerHook value change (handled in Indicator class)
186            bounds position on container scroll or resize (to keep alignment to bottom/right)
187            trigger position on container resize, window resize (if container isn't document) and window scroll (if container isn't document)
188        */
189
190        // event handler for when associated bounds markers need to be repositioned
191        var handleBoundsPositionChange = function () {
192            _indicators.updateBoundsPositions();
193        };
194
195        // event handler for when associated trigger groups need to be repositioned
196        var handleTriggerPositionChange = function () {
197            _indicators.updateTriggerGroupPositions();
198        };
199
200        _container.addEventListener("resize", handleTriggerPositionChange);
201        if (!_isDocument) {
202            window.addEventListener("resize", handleTriggerPositionChange);
203            window.addEventListener("scroll", handleTriggerPositionChange);
204        }
205        // update all related bounds containers
206        _container.addEventListener("resize", handleBoundsPositionChange);
207        _container.addEventListener("scroll", handleBoundsPositionChange);
208
209
210        // updates the position of the bounds container to aligned to the right for vertical containers and to the bottom for horizontal
211        this._indicators.updateBoundsPositions = function (specificIndicator) {
212            var // constant for all bounds
213                groups = specificIndicator ?
214                                [_util.extend({}, specificIndicator.triggerGroup, {members: [specificIndicator]})]: // create a group with only one element
215                                _indicators.groups, // use all
216                g = groups.length,
217                css = {},
218                paramPos = _vertical ? "left"  : "top",
219                paramDimension = _vertical ? "width" : "height",
220                edge = _vertical ?
221                            _util.get.scrollLeft(_container) + _util.get.width(_container) - EDGE_OFFSET:
222                            _util.get.scrollTop(_container) + _util.get.height(_container) - EDGE_OFFSET,
223                b, triggerSize, group;
224            while (g--) { // group loop
225                group = groups[g];
226                b = group.members.length;
227                triggerSize = _util.get[paramDimension](group.element.firstChild);
228                while (b--) { // indicators loop
229                    css[paramPos] = edge - triggerSize;
230                    _util.css(group.members[b].bounds, css);
231                }
232            }
233        };
234
235        // updates the positions of all trigger groups attached to a controller or a specific one, if provided
236        this._indicators.updateTriggerGroupPositions = function (specificGroup) {
237            var // constant vars
238                groups = specificGroup ? [specificGroup] : _indicators.groups,
239                i = groups.length,
240                container = _isDocument ? document.body : _container,
241                containerOffset = _isDocument ?  {top: 0, left: 0} : _util.get.offset(container, true),
242                edge = _vertical ?
243                            _util.get.width(_container) - EDGE_OFFSET :
244                            _util.get.height(_container) - EDGE_OFFSET,
245                paramDimension = _vertical ? "width"  : "height",
246                paramTransform = _vertical ? "Y" : "X";
247            var // changing vars
248                    group,
249                    elem,
250                    pos,
251                    elemSize,
252                    transform;
253            while (i--) {
254                group = groups[i];
255                elem = group.element;
256                pos = group.triggerHook * Controller.info("size");
257                elemSize = _util.get[paramDimension](elem.firstChild.firstChild);
258                transform = pos > elemSize ? "translate" + paramTransform + "(-100%)" : "";
259
260                _util.css(elem, {
261                    top: containerOffset.top + (_vertical ? pos : edge - group.members[0].options.indent),
262                    left: containerOffset.left + (_vertical ? edge - group.members[0].options.indent : pos)
263                });
264                _util.css(elem.firstChild.firstChild, {
265                    "-ms-transform" : transform,
266                    "-webkit-transform" : transform,
267                    "transform" : transform
268                });
269            }
270        };
271
272        // updates the label for the group to contain the name, if it only has one member
273        this._indicators.updateTriggerGroupLabel = function (group) {
274            var
275                text = "trigger" + (group.members.length > 1 ? "" : " " + group.members[0].options.name),
276                elem = group.element.firstChild.firstChild,
277                doUpdate = elem.textContent !== text;
278            if (doUpdate) {
279                elem.textContent = text;
280                if (_vertical) { // bounds position is dependent on text length, so update
281                    _indicators.updateBoundsPositions();
282                }
283            }
284        };
285
286        // add indicators if global option is set
287        this.addScene = function (newScene) {
288
289            if (this._options.addIndicators && newScene instanceof ScrollMagic.Scene && newScene.controller() === Controller) {
290                newScene.addIndicators();
291            }
292            // call original destroy method
293            this.$super.addScene.apply(this, arguments);
294        };
295
296        // remove all previously set listeners on destroy
297        this.destroy = function () {
298            _container.removeEventListener("resize", handleTriggerPositionChange);
299            if (!_isDocument) {
300                window.removeEventListener("resize", handleTriggerPositionChange);
301                window.removeEventListener("scroll", handleTriggerPositionChange);
302            }
303            _container.removeEventListener("resize", handleBoundsPositionChange);
304            _container.removeEventListener("scroll", handleBoundsPositionChange);
305            // call original destroy method
306            this.$super.destroy.apply(this, arguments);
307        };
308        return Controller;
309
310    });
311
312    /*
313     * ----------------------------------------------------------------
314     * Internal class for the construction of Indicators
315     * ----------------------------------------------------------------
316     */
317    var Indicator = function (Scene, options) {
318        var
319            Indicator = this,
320            _elemBounds = TPL.bounds(),
321            _elemStart = TPL.start(options.colorStart),
322            _elemEnd = TPL.end(options.colorEnd),
323            _boundsContainer = options.parent && _util.get.elements(options.parent)[0],
324            _vertical,
325            _ctrl;
326
327        // (BUILD) - REMOVE IN MINIFY - START
328        var log = function () {
329            if (Scene._log) { // not available, when main source minified
330                Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->");
331                Scene._log.apply(this, arguments);
332            }
333        };
334        // (BUILD) - REMOVE IN MINIFY - END
335
336        options.name = options.name || _autoindex;
337
338        // prepare bounds elements
339        _elemStart.firstChild.textContent += " " + options.name;
340        _elemEnd.textContent += " " + options.name;
341        _elemBounds.appendChild(_elemStart);
342        _elemBounds.appendChild(_elemEnd);
343
344        // set public variables
345        Indicator.options = options;
346        Indicator.bounds = _elemBounds;
347        // will be set later
348        Indicator.triggerGroup = undefined;
349
350        // add indicators to DOM
351        this.add = function () {
352            _ctrl = Scene.controller();
353            _vertical = _ctrl.info("vertical");
354
355            var isDocument = _ctrl.info("isDocument");
356
357            if (!_boundsContainer) {
358                // no parent supplied or doesnt exist
359                _boundsContainer = isDocument ? document.body : _ctrl.info("container"); // check if window/document (then use body)
360            }
361            if (!isDocument && _util.css(_boundsContainer, "position") === 'static') {
362                // position mode needed for correct positioning of indicators
363                _util.css(_boundsContainer, {position: "relative"});
364            }
365
366            // add listeners for updates
367            Scene.on("change.plugin_addIndicators", handleTriggerParamsChange);
368            Scene.on("shift.plugin_addIndicators", handleBoundsParamsChange);
369
370            // updates trigger & bounds (will add elements if needed)
371            updateTriggerGroup();
372            updateBounds();
373
374            setTimeout(function () { // do after all execution is finished otherwise sometimes size calculations are off
375                _ctrl._indicators.updateBoundsPositions(Indicator);
376            }, 0);
377
378            log(3, "added indicators");
379        };
380
381        // remove indicators from DOM
382        this.remove = function () {
383            if (Indicator.triggerGroup) { // if not set there's nothing to remove
384                Scene.off("change.plugin_addIndicators", handleTriggerParamsChange);
385                Scene.off("shift.plugin_addIndicators", handleBoundsParamsChange);
386
387                if (Indicator.triggerGroup.members.length > 1) {
388                    // just remove from memberlist of old group
389                    var group = Indicator.triggerGroup;
390                    group.members.splice(group.members.indexOf(Indicator), 1);
391                    _ctrl._indicators.updateTriggerGroupLabel(group);
392                    _ctrl._indicators.updateTriggerGroupPositions(group);
393                    Indicator.triggerGroup = undefined;
394                } else {
395                    // remove complete group
396                    removeTriggerGroup();
397                }
398                removeBounds();
399
400                log(3, "removed indicators");
401            }
402        };
403
404        /*
405         * ----------------------------------------------------------------
406         * internal Event Handlers
407         * ----------------------------------------------------------------
408         */
409
410        // event handler for when bounds params change
411        var handleBoundsParamsChange = function () {
412            updateBounds();
413        };
414
415        // event handler for when trigger params change
416        var handleTriggerParamsChange = function (e) {
417            if (e.what === "triggerHook") {
418                updateTriggerGroup();
419            }
420        };
421
422        /*
423         * ----------------------------------------------------------------
424         * Bounds (start / stop) management
425         * ----------------------------------------------------------------
426         */
427
428        // adds an new bounds elements to the array and to the DOM
429        var addBounds = function () {
430            var v = _ctrl.info("vertical");
431            // apply stuff we didn't know before...
432            _util.css(_elemStart.firstChild, {
433                "border-bottom-width" : v ? 1 : 0,
434                "border-right-width" :    v ? 0 : 1,
435                "bottom":                                v ? -1 : options.indent,
436                "right":                                v ? options.indent : -1,
437                "padding":                            v ? "0 8px" : "2px 4px",
438            });
439            _util.css(_elemEnd, {
440                "border-top-width" :        v ? 1 : 0,
441                "border-left-width" :    v ? 0 : 1,
442                "top":                                    v ? "100%" : "",
443                "right":                                v ? options.indent : "",
444                "bottom":                                v ? "" : options.indent,
445                "left":                                    v ? "" : "100%",
446                "padding":                            v ? "0 8px" : "2px 4px"
447            });
448            // append
449            _boundsContainer.appendChild(_elemBounds);
450        };
451
452        // remove bounds from list and DOM
453        var removeBounds = function () {
454            _elemBounds.parentNode.removeChild(_elemBounds);
455        };
456
457        // update the start and end positions of the scene
458        var updateBounds = function () {
459            if (_elemBounds.parentNode !== _boundsContainer) {
460                addBounds(); // Add Bounds elements (start/end)
461            }
462            var css = {};
463            css[_vertical ? "top" : "left"] = Scene.triggerPosition();
464            css[_vertical ? "height" : "width"] = Scene.duration();
465            _util.css(_elemBounds, css);
466            _util.css(_elemEnd, {
467                display: Scene.duration() > 0 ? "" : "none"
468            });
469        };
470
471        /*
472         * ----------------------------------------------------------------
473         * trigger and trigger group management
474         * ----------------------------------------------------------------
475         */
476
477        // adds an new trigger group to the array and to the DOM
478        var addTriggerGroup = function () {
479            var triggerElem = TPL.trigger(options.colorTrigger); // new trigger element
480            var css = {};
481            css[_vertical ? "right" : "bottom"] = 0;
482            css[_vertical ? "border-top-width" : "border-left-width"] = 1;
483            _util.css(triggerElem.firstChild, css);
484            _util.css(triggerElem.firstChild.firstChild, {
485                padding: _vertical ? "0 8px 3px 8px" : "3px 4px"
486            });
487            document.body.appendChild(triggerElem); // directly add to body
488            var newGroup = {
489                triggerHook: Scene.triggerHook(),
490                element: triggerElem,
491                members: [Indicator]
492            };
493            _ctrl._indicators.groups.push(newGroup);
494            Indicator.triggerGroup = newGroup;
495            // update right away
496            _ctrl._indicators.updateTriggerGroupLabel(newGroup);
497            _ctrl._indicators.updateTriggerGroupPositions(newGroup);
498        };
499
500        var removeTriggerGroup = function () {
501            _ctrl._indicators.groups.splice(_ctrl._indicators.groups.indexOf(Indicator.triggerGroup), 1);
502            Indicator.triggerGroup.element.parentNode.removeChild(Indicator.triggerGroup.element);
503            Indicator.triggerGroup = undefined;
504        };
505
506        // updates the trigger group -> either join existing or add new one
507        /*
508         * Logic:
509         * 1 if a trigger group exist, check if it's in sync with Scene settings – if so, nothing else needs to happen
510         * 2 try to find an existing one that matches Scene parameters
511         *   2.1 If a match is found check if already assigned to an existing group
512         *           If so:
513         *       A: it was the last member of existing group -> kill whole group
514         *       B: the existing group has other members -> just remove from member list
515         *   2.2 Assign to matching group
516         * 3 if no new match could be found, check if assigned to existing group
517         *   A: yes, and it's the only member -> just update parameters and positions and keep using this group
518         *   B: yes but there are other members -> remove from member list and create a new one
519         *   C: no, so create a new one
520         */
521        var updateTriggerGroup = function () {
522            var
523                triggerHook = Scene.triggerHook(),
524                closeEnough = 0.0001;
525
526            // Have a group, check if it still matches
527            if (Indicator.triggerGroup) {
528                if (Math.abs(Indicator.triggerGroup.triggerHook - triggerHook) < closeEnough) {
529                    // _util.log(0, "trigger", options.name, "->", "no need to change, still in sync");
530                    return; // all good
531                }
532            }
533            // Don't have a group, check if a matching one exists
534            // _util.log(0, "trigger", options.name, "->", "out of sync!");
535            var
536                groups = _ctrl._indicators.groups,
537                group,
538                i = groups.length;
539            while (i--) {
540                group = groups[i];
541                if (Math.abs(group.triggerHook - triggerHook) < closeEnough) {
542                    // found a match!
543                    // _util.log(0, "trigger", options.name, "->", "found match");
544                    if (Indicator.triggerGroup) { // do I have an old group that is out of sync?
545                        if (Indicator.triggerGroup.members.length === 1) { // is it the only remaining group?
546                            // _util.log(0, "trigger", options.name, "->", "kill");
547                            // was the last member, remove the whole group
548                            removeTriggerGroup();
549                        } else {
550                            Indicator.triggerGroup.members.splice(Indicator.triggerGroup.members.indexOf(Indicator), 1); // just remove from memberlist of old group
551                            _ctrl._indicators.updateTriggerGroupLabel(Indicator.triggerGroup);
552                            _ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup);
553                            // _util.log(0, "trigger", options.name, "->", "removing from previous member list");
554                        }
555                    }
556                    // join new group
557                    group.members.push(Indicator);
558                    Indicator.triggerGroup = group;
559                    _ctrl._indicators.updateTriggerGroupLabel(group);
560                    return;
561                }
562            }
563
564            // at this point I am obviously out of sync and don't match any other group
565            if (Indicator.triggerGroup) {
566                if (Indicator.triggerGroup.members.length === 1) {
567                    // _util.log(0, "trigger", options.name, "->", "updating existing");
568                    // out of sync but i'm the only member => just change and update
569                    Indicator.triggerGroup.triggerHook = triggerHook;
570                    _ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup);
571                    return;
572                } else {
573                    // _util.log(0, "trigger", options.name, "->", "removing from previous member list");
574                    Indicator.triggerGroup.members.splice(Indicator.triggerGroup.members.indexOf(Indicator), 1); // just remove from memberlist of old group
575                    _ctrl._indicators.updateTriggerGroupLabel(Indicator.triggerGroup);
576                    _ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup);
577                    Indicator.triggerGroup = undefined; // need a brand new group...
578                }
579            }
580            // _util.log(0, "trigger", options.name, "->", "add a new one");
581            // did not find any match, make new trigger group
582            addTriggerGroup();
583        };
584    };
585
586    /*
587     * ----------------------------------------------------------------
588     * Templates for the indicators
589     * ----------------------------------------------------------------
590     */
591    var TPL = {
592        start: function (color) {
593            // inner element (for bottom offset -1, while keeping top position 0)
594            var inner = document.createElement("div");
595            inner.textContent = "start";
596            _util.css(inner, {
597                position: "absolute",
598                overflow: "visible",
599                display: "none",
600                "border-width" : 0,
601                "border-style" : "solid",
602                color: color,
603                "border-color" : color
604            });
605            var e = document.createElement('div');
606            // wrapper
607            _util.css(e, {
608                position: "absolute",
609                overflow: "visible",
610                width: 0,
611                height: 0
612            });
613            e.appendChild(inner);
614            return e;
615        },
616        end: function (color) {
617            var e = document.createElement('div');
618            e.textContent = "end";
619            _util.css(e, {
620                position: "absolute",
621                overflow: "visible",
622                display: "none",
623                "border-width" : 0,
624                "border-style" : "solid",
625                color: color,
626                "border-color" : color
627            });
628            return e;
629        },
630        bounds: function () {
631            var e = document.createElement('div');
632            _util.css(e, {
633                position: "absolute",
634                overflow: "visible",
635                display: "none",
636                "white-space": "nowrap",
637                "pointer-events" : "none",
638                "font-size": FONT_SIZE
639            });
640            e.style.zIndex = ZINDEX;
641            return e;
642        },
643        trigger: function (color) {
644            // inner to be above or below line but keep position
645            var inner = document.createElement('div');
646            inner.textContent = "trigger";
647            _util.css(inner, {
648                position: "relative",
649            });
650            // inner wrapper for right: 0 and main element has no size
651            var w = document.createElement('div');
652            _util.css(w, {
653                position: "absolute",
654                overflow: "visible",
655                display: "none",
656                "border-width" : 0,
657                "border-style" : "solid",
658                color: color,
659                "border-color" : color
660            });
661            w.appendChild(inner);
662            // wrapper
663            var e = document.createElement('div');
664            _util.css(e, {
665                position: "fixed",
666                overflow: "visible",
667                "white-space": "nowrap",
668                "pointer-events" : "none",
669                "font-size": FONT_SIZE
670            });
671            e.style.zIndex = ZINDEX;
672            e.appendChild(w);
673            return e;
674        },
675    };
676
677}));

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.