PageSourceSearch

https://www.romana-auto.it/assets/accessibility/accessibility.js?v=2026092302

js romana-auto.it collected 2026-09-25 20:36:21 UTC 44,575 bytes, 754 lines download raw bytes

1class AHAccessibility {
2
3    constructor({ holder, baseUrl, primaryColor = "#161616", textColor = "#FFFFFF", left = "20px", bottom = "20px" }) {
4        this.name = "AHAccessibility";
5        this.version = "1.0.0";
6        this.description = "Accessibility features for the application.";
7        this.author = "AD HOC";
8        this.authorHtml = "AD <span class=\"adhoc-color\">HOC</span>";
9        this.license = "MIT";
10        this.homepage = "https://www.adhocweb.it";
11        this.websiteAccessibility = baseUrl;
12        this.primaryColor = primaryColor;
13        this.textColor = textColor;
14        this.left = left;
15        this.bottom = bottom;
16
17        if (typeof holder === 'undefined') {
18            console.error(`${this.name}: Holder is undefined.`);
19            return;
20        }
21
22        if (typeof holder === 'string') {
23            holder = document.querySelector(holder);
24            if (!holder) {
25                console.error(`${this.name}: No element found for the provided selector.`);
26                return;
27            }
28        }
29
30        this.holder = holder;
31        this.init();
32    }
33
34    init() {
35        const hideInterface = this.getCookie('hideAccessibilityInterface') || 'false';
36        if (hideInterface !== 'true') {
37            this.injectStyles();
38        }
39
40        console.log(`${this.name} v${this.version} initialized.`);
41    }
42
43    createAccessibilityFloatingButton() {
44        const div = document.createElement('div');
45        div.classList.add('accessibility-floating-button-container');
46        div.innerHTML = this.getHtmlFloatingButton();
47
48        const button = div.querySelector('.floating-button');
49        button.addEventListener('click', () => {
50            const menu = this.holder.querySelector('.accessibility-menu-container');
51            if (menu) {
52                menu.classList.toggle('show');
53
54                const isHidden = menu.getAttribute('aria-hidden') === 'true';
55                menu.setAttribute('aria-hidden', isHidden ? 'false' : 'true');
56
57                if (!isHidden) document.querySelector('.accessibility-floating-button').focus();
58                else menu.focus();
59            }
60        });
61
62        this.holder.appendChild(div);
63    }
64
65    createAccessibilityMenu() {
66        const div = document.createElement('div');
67        div.classList.add('accessibility-menu-container');
68        div.setAttribute('aria-hidden', 'true');
69        div.setAttribute('tabindex', '-1');
70        div.innerHTML = this.getHtmlMenu();
71
72        const closeButton = div.querySelector('.accessibility-menu-close');
73        closeButton.addEventListener('click', () => {
74            const menu = this.holder.querySelector('.accessibility-menu-container');
75            if (menu) {
76                document.querySelector('.floating-button').focus();
77
78                menu.classList.remove('show');
79                menu.setAttribute('aria-hidden', 'true');
80            }
81        });
82
83        const menuBackdrop = div.querySelector('.accessibility-menu-backdrop');
84        menuBackdrop.addEventListener('click', () => {
85            const menu = this.holder.querySelector('.accessibility-menu-container');
86            if (menu) {
87                document.querySelector('.floating-button').focus();
88                menu.classList.remove('show');
89                menu.setAttribute('aria-hidden', 'true');
90            }
91        });
92
93        const settingsButtons = div.querySelectorAll('.accessibility-setting[data-action]');
94        settingsButtons.forEach(button => {
95            button.addEventListener('click', (event) => {
96                const action = event.currentTarget.getAttribute('data-action');
97                this.handleSettingAction(action);
98            });
99        });
100
101        const modalBackdrop = div.querySelector('.accessibility-modal-backdrop');
102        modalBackdrop.addEventListener('click', () => {
103            const modal = this.holder.querySelector(this.selectorModal);
104            if (modal) {
105                modal.setAttribute('aria-hidden', 'true');
106                modal.classList.remove('show');
107                this.selectorModal = null;
108            }
109        });
110
111        const cancelButtonModal = div.querySelectorAll('.accessibility-button-cancel');
112        cancelButtonModal.forEach(button => {
113            button.addEventListener('click', () => {
114                const modal = this.holder.querySelector(this.selectorModal);
115                if (modal) {
116                    modal.setAttribute('aria-hidden', 'true');
117                    modal.classList.remove('show');
118                    this.selectorModal = null;
119                }
120            });
121        });
122
123        const confirmButtonModal = div.querySelectorAll('.accessibility-button-confirm');
124        confirmButtonModal.forEach(button => {
125            button.addEventListener('click', (event) => {
126                const action = event.currentTarget.getAttribute('data-modal-action');
127                this.handleModalAction(action);
128            });
129        });
130
131        this.holder.appendChild(div);
132    }
133
134    initDefaultParameters() {
135        this.defaultZoomMultiplier = 0.16;
136        this.minZoomLevel = 0.5;
137        this.maxZoomLevel = 2.0;
138
139        this.defaultFontSizeMultiplier = 0.5;
140        // this.minFontSize = 10;
141        // this.maxFontSize = 52;
142
143        // Setto le variabili css per i colori dell'interfaccia
144        document.documentElement.style.setProperty('--accessibility-primary-color', this.primaryColor);
145        document.documentElement.style.setProperty('--accessibility-text-color', this.textColor);
146
147        const elements = this.holder.querySelectorAll('h1, h2, h3, h4, h5, h6, p, a, li, span, div, input, textarea, button, select, label, legend');
148        const filtered = Array.from(elements).filter(el => !el.closest('.accessibility-menu-container') && !el.closest('.accessibility-floating-button-container'));
149
150        filtered.forEach(el => {
151            const style = window.getComputedStyle(el);
152            const fontSizeStr = style.fontSize;
153            const fontSize = parseFloat(fontSizeStr);
154            el.dataset.originalFontSize = fontSize; // Store original font size in a data attribute
155        });
156
157        const landmarks = [
158            { role: "banner", label: "Intestazione", target: this.holder.querySelector('header') },
159            { role: "main", label: "Contenuto principale", target: this.holder.querySelector('main') },
160            { role: "contentinfo", label: "Piè di pagina", target: this.holder.querySelector('footer') }
161        ];
162
163        // Crea il container dei link di salto
164        const skipNav = document.createElement("nav");
165        skipNav.setAttribute("aria-label", "Link rapidi");
166        skipNav.classList.add("accessibility-skip-nav");
167
168        // Genera i link verso i landmark
169        landmarks.forEach(lm => {
170            if (lm.target) {
171                const link = document.createElement("a");
172                link.classList.add("accessibility-skip-link");
173                link.setAttribute("role", "link");
174                link.setAttribute("aria-label", `Vai a ${lm.label}`);
175                link.href = "#";
176                link.textContent = `Vai a ${lm.label}`;
177
178                link.addEventListener("click", e => {
179                    e.preventDefault();
180                    lm.target.setAttribute("tabindex", "-1"); // focusabile temporaneamente
181                    lm.target.focus();
182                });
183
184                // Mostra i link quando ricevono focus
185                link.addEventListener("focusin", () => {
186                    link.style.top = "0";
187                });
188                link.addEventListener("focusout", () => {
189                    link.style.top = "-9999px";
190                });
191
192                skipNav.appendChild(link);
193            }
194        });
195
196        document.body.prepend(skipNav);
197
198        // Mostra i link quando ricevono focus
199        skipNav.addEventListener("focusin", () => {
200            skipNav.style.left = "0";
201        });
202        skipNav.addEventListener("focusout", () => {
203            skipNav.style.left = "-9999px";
204        });
205
206        window.addEventListener('scroll', () => {
207            const floatingButton = this.holder.querySelector('.accessibility-floating-button');
208            if (!floatingButton) return;
209
210            const isMenuOpen = this.holder.querySelector('.accessibility-menu-container.show');
211            if (isMenuOpen) return; // Non fare nulla se il menu &egrave; aperto
212
213            const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop;
214            if (currentScrollTop > 100) {
215                // Scrolling down
216                floatingButton.style.display = 'none'; // Nascondi il bottone
217                floatingButton.querySelector('.floating-button').setAttribute('tabindex', '-1'); // Rendi il bottone non focusabile
218            } else {
219                // Scrolling up
220                floatingButton.style.display = 'block'; // Mostra il bottone
221                floatingButton.querySelector('.floating-button').setAttribute('tabindex', '0'); // Rendi il bottone focusabile
222            }
223        });
224    }
225
226    applySavedPreferences() {
227        const savedZoom = this.getCookie('zoomLevel');
228        if (savedZoom) {
229            document.body.style.zoom = savedZoom;
230            const zoomPercentage = Math.round((parseFloat(savedZoom) - 1) * 100 / this.defaultZoomMultiplier);
231            this.holder.querySelector('#zoom-level').textContent = zoomPercentage === 0 ? 'Predefinito' : `${zoomPercentage}%`;
232        }
233
234        const savedFontSize = this.getCookie('fontSize');
235        if (savedFontSize) {
236            const fontSizePercentage = parseInt(savedFontSize);
237            const elements = this.holder.querySelectorAll('h1, h2, h3, h4, h5, h6, p, a, li, span, div, input, textarea, button, select, label, legend');
238            const filtered = Array.from(elements).filter(el => !el.closest('.accessibility-menu-container') && !el.closest('.accessibility-floating-button-container'));
239
240            filtered.forEach(el => {
241                const baseFontSize = parseFloat(el.dataset.originalFontSize) || 16; // Fallback to 16px if not set
242                const newFontSize = Math.round(baseFontSize + (this.defaultFontSizeMultiplier * (fontSizePercentage / 100) * baseFontSize));
243                el.style.fontSize = `${newFontSize}px`;
244            });
245            this.holder.querySelector('#font-size-level').textContent = fontSizePercentage === 0 ? 'Predefinito' : `${fontSizePercentage}%`;
246        }
247
248        const readableFont = this.getCookie('readableFont');
249        if (readableFont === 'true') {
250            const elements = this.holder.querySelectorAll('h1, h2, h3, h4, h5, h6, p, a, li, span, div, input, textarea, button, select, label, legend');
251
252            elements.forEach(el => {
253                el.style.fontFamily = 'Arial, sans-serif';
254            });
255            this.holder.querySelector('.accessibility-setting[data-action="readable-font"]').classList.add('active');
256        }
257
258        const textAlignment = this.getCookie('textAlignment');
259        if (textAlignment) {
260            const elements = this.holder.querySelectorAll('h1, h2, h3, h4, h5, h6, p, a, li, span, div, input, textarea, button, select, label, legend');
261
262            elements.forEach(el => {
263                el.style.textAlign = textAlignment;
264                el.style.justifyContent = textAlignment === 'left' ? 'start' : textAlignment === 'right' ? 'end' : 'center';
265            });
266            this.holder.querySelectorAll('.accessibility-setting[data-action^="alterate-alignment-"]').forEach(btn => {
267                btn.classList.remove('active');
268                if (btn.getAttribute('data-action') === `alterate-alignment-${textAlignment}`) {
269                    btn.classList.add('active');
270                }
271            });
272        }
273
274        const filterColor = this.getCookie('filterColor');
275        if (filterColor) {
276            const html = document.documentElement;
277            switch (filterColor) {
278                case 'high-contrast':
279                    html.style.filter = 'contrast(1.5)';
280                    break;
281                case 'high-saturation':
282                    html.style.filter = 'saturate(2)';
283                    break;
284                case 'monocromatic':
285                    html.style.filter = 'grayscale(1)';
286                    break;
287                case 'low-saturation':
288                    html.style.filter = 'saturate(0.5)';
289                    break;
290                default:
291                    html.style.filter = '';
292            }
293            this.holder.querySelectorAll('.accessibility-setting[data-action^="filter-"]').forEach(btn => {
294                btn.classList.remove('active');
295                if (btn.getAttribute('data-action') === `filter-${filterColor}`) {
296                    btn.classList.add('active');
297                }
298            });
299        }
300    }
301
302    handleSettingAction(action) {
303        switch (action) {
304            case 'reset-settings':
305                this.resetSettings();
306                break;
307            case 'read-accessibility-statement':
308                // this.selectorModal = '#accessibility-modal-read-accessibility-statement';
309                // this.showAccessibilityModal();
310                window.open('/dichiarazione-di-accessibilita', '_blank');
311                break;
312            case 'hide-accessibility':
313                this.selectorModal = '#accessibility-modal-hide-accessibility';
314                this.showAccessibilityModal();
315                break;
316            case 'increase-zoom':
317                this.increaseZoom();
318                break;
319            case 'decrease-zoom':
320                this.decreaseZoom();
321                break;
322            case 'increase-font-size':
323                this.increaseFontSize();
324                break;
325            case 'decrease-font-size':
326                this.decreaseFontSize();
327                break;
328            case 'readable-font':
329                this.toggleReadableFont();
330                break;
331            case 'alterate-alignment-center':
332                this.toggleAlignment('center');
333                break;
334            case 'alterate-alignment-left':
335                this.toggleAlignment('left');
336                break;
337            case 'alterate-alignment-right':
338                this.toggleAlignment('right');
339                break;
340            case 'filter-high-contrast':
341                this.filterColor('high-contrast');
342                break;
343            case 'filter-high-saturation':
344                this.filterColor('high-saturation');
345                break;
346            case 'filter-monocromatic':
347                this.filterColor('monocromatic');
348                break;
349            case 'filter-low-saturation':
350                this.filterColor('low-saturation');
351                break;
352            default:
353                console.warn(`${this.name}: Unknown action "${action}".`);
354        }
355    }
356
357    handleModalAction(action) {
358        switch (action) {
359            case 'hide-accessibility':
360                this.hideAccessibilityInterface();
361                const modal = this.holder.querySelector(this.selectorModal);
362                if (modal) {
363                    modal.setAttribute('aria-hidden', 'true');
364                    modal.classList.remove('show');
365                    this.selectorModal = null;
366                }
367                break;
368            default:
369                console.warn(`${this.name}: Unknown modal action "${action}".`);
370        }
371    }
372
373    resetSettings() {
374        this.setCookie('zoomLevel', '', -1);
375        this.setCookie('fontSize', '', -1);
376        this.setCookie('readableFont', '', -1);
377        this.setCookie('textAlignment', '', -1);
378        this.setCookie('filterColor', '', -1);
379
380        window.location.reload();
381    }
382
383    hideAccessibilityInterface() {
384        this.setCookie('hideAccessibilityInterface', 'true', 365);
385
386        const floatingButton = this.holder.querySelector('.accessibility-floating-button');
387        if (floatingButton) floatingButton.remove();
388        const menu = this.holder.querySelector('.accessibility-menu');
389        if (menu) menu.remove();
390
391        this.resetSettings();
392    }
393
394    showAccessibilityModal() {
395        const modal = this.holder.querySelector(this.selectorModal);
396        if (!modal) return;
397
398        modal.setAttribute('aria-hidden', 'false');
399        modal.classList.add('show');
400        modal.focus();
401    }
402
403    increaseZoom() {
404        const currentZoom = document.body.style.zoom ? parseFloat(document.body.style.zoom) : 1;
405        const newZoom = Math.min(currentZoom + (0.1 * this.defaultZoomMultiplier), 1 + (this.defaultZoomMultiplier * this.maxZoomLevel)); // Limit max zoom to 200%
406        const newZoomPercentage = Math.round((newZoom - 1) * 100 / this.defaultZoomMultiplier);
407        document.body.style.zoom = newZoom;
408        this.holder.querySelector('#zoom-level').textContent = `${newZoomPercentage}%`;
409        if (newZoom === 1) this.holder.querySelector('#zoom-level').textContent = 'Predefinito';
410
411        this.setCookie('zoomLevel', newZoom, 365);
412    }
413
414    decreaseZoom() {
415        const currentZoom = document.body.style.zoom ? parseFloat(document.body.style.zoom) : 1;
416        const newZoom = Math.max(currentZoom - (0.1 * this.defaultZoomMultiplier), 1 - (this.defaultZoomMultiplier * this.minZoomLevel)); // Limit min zoom -50%
417        const newZoomPercentage = Math.round((newZoom - 1) * 100 / this.defaultZoomMultiplier);
418        document.body.style.zoom = newZoom;
419        this.holder.querySelector('#zoom-level').textContent = `${newZoomPercentage}%`;
420        if (newZoom === 1) this.holder.querySelector('#zoom-level').textContent = 'Predefinito';
421
422        this.setCookie('zoomLevel', newZoom, 365);
423    }
424
425    increaseFontSize() {
426        let fontSizePercentage = parseInt(this.getCookie('fontSize'));
427        if (isNaN(fontSizePercentage)) fontSizePercentage = 0; // Default font size
428
429        const elements = this.holder.querySelectorAll('h1, h2, h3, h4, h5, h6, p, a, li, span, div, input, textarea, button, select, label, legend');
430        const filtered = Array.from(elements).filter(el => !el.closest('.accessibility-menu-container') && !el.closest('.accessibility-floating-button-container'));
431
432        filtered.forEach(el => {
433            const style = window.getComputedStyle(el);
434            const currentFontSize = style.fontSize ? parseFloat(style.fontSize) : 16;
435            const baseFontSize = parseFloat(el.dataset.originalFontSize) || 16; // Fallback to 16px if not set
436            const newFontSize = Math.round(currentFontSize + (this.defaultFontSizeMultiplier * 0.1 * baseFontSize));
437            el.style.fontSize = `${newFontSize}px`;
438        });
439
440        fontSizePercentage += 10;
441        this.setCookie('fontSize', fontSizePercentage, 365);
442        this.holder.querySelector('#font-size-level').textContent = `${fontSizePercentage}%`;
443        if (fontSizePercentage === 0) this.holder.querySelector('#font-size-level').textContent = 'Predefinito';
444    }
445
446    decreaseFontSize() {
447        let fontSizePercentage = parseInt(this.getCookie('fontSize'));
448        if (isNaN(fontSizePercentage)) fontSizePercentage = 0; // Default font size
449
450        const elements = this.holder.querySelectorAll('h1, h2, h3, h4, h5, h6, p, a, li, span, div, input, textarea, button, select, label, legend');
451        const filtered = Array.from(elements).filter(el => !el.closest('.accessibility-menu-container') && !el.closest('.accessibility-floating-button-container'));
452
453        filtered.forEach(el => {
454            const style = window.getComputedStyle(el);
455            const currentFontSize = style.fontSize ? parseFloat(style.fontSize) : 16;
456            const baseFontSize = parseFloat(el.dataset.originalFontSize) || 16; // Fallback to 16px if not set
457            const newFontSize = Math.round(currentFontSize - (this.defaultFontSizeMultiplier * 0.1 * baseFontSize));
458            el.style.fontSize = `${newFontSize}px`;
459        });
460
461        fontSizePercentage -= 10;
462        this.setCookie('fontSize', fontSizePercentage, 365);
463        this.holder.querySelector('#font-size-level').textContent = `${fontSizePercentage}%`;
464        if (fontSizePercentage === 0) this.holder.querySelector('#font-size-level').textContent = 'Predefinito';
465    }
466
467    toggleReadableFont() {
468        const readableFont = this.getCookie('readableFont') || 'false';
469        const elements = this.holder.querySelectorAll('h1, h2, h3, h4, h5, h6, p, a, li, span, div, input, textarea, button, select, label, legend');
470
471        elements.forEach(el => {
472            if (readableFont !== 'true') {
473                el.style.fontFamily = 'Arial, sans-serif';
474            } else {
475                el.style.fontFamily = '';
476            }
477        });
478
479        this.holder.querySelector('.accessibility-setting[data-action="readable-font"]').classList.toggle('active', readableFont !== 'true');
480
481        setCookie('readableFont', readableFont === 'true' ? 'false' : 'true', 365);
482    }
483
484    toggleAlignment(alignment) {
485        const currentAlignment = this.getCookie('textAlignment');
486        const elements = this.holder.querySelectorAll('h1, h2, h3, h4, h5, h6, p, a, li, span, div, input, textarea, button, select, label, legend');
487
488        elements.forEach(el => {
489            if (currentAlignment === alignment) {
490                el.style.textAlign = '';
491                el.style.justifyContent = '';
492            } else {
493                el.style.textAlign = alignment;
494                el.style.justifyContent = alignment === 'left' ? 'start' : alignment === 'right' ? 'end' : 'center';
495            }
496        });
497        this.holder.querySelectorAll('.accessibility-setting[data-action^="alterate-alignment-"]').forEach(btn => {
498            btn.classList.remove('active');
499            if (btn.getAttribute('data-action') === `alterate-alignment-${alignment}` && currentAlignment !== alignment) {
500                btn.classList.add('active');
501            }
502        });
503
504        this.setCookie('textAlignment', currentAlignment !== alignment ? alignment : '', 365);
505    }
506
507    filterColor(filter) {
508        const currentFilter = this.getCookie('filterColor');
509        const html = document.documentElement;
510        html.style.filter = '';
511
512        if (currentFilter === filter) {
513            this.setCookie('filterColor', '', -1);
514            this.holder.querySelectorAll('.accessibility-setting[data-action^="filter-"]').forEach(btn => btn.classList.remove('active'));
515        } else {
516            switch (filter) {
517                case 'high-contrast':
518                    html.style.filter = 'contrast(1.5)';
519                    break;
520                case 'high-saturation':
521                    html.style.filter = 'saturate(2)';
522                    break;
523                case 'monocromatic':
524                    html.style.filter = 'grayscale(1)';
525                    break;
526                case 'low-saturation':
527                    html.style.filter = 'saturate(0.5)';
528                    break;
529                default:
530                    html.style.filter = '';
531            }
532            this.setCookie('filterColor', filter, 365);
533            this.holder.querySelectorAll('.accessibility-setting[data-action^="filter-"]').forEach(btn => {
534                btn.classList.remove('active');
535                if (btn.getAttribute('data-action') === `filter-${filter}`) {
536                    btn.classList.add('active');
537                }
538            });
539        }
540    }
541
542    injectStyles() {
543        const linkElement = document.createElement('link');
544        linkElement.rel = 'stylesheet';
545        linkElement.href = `${this.websiteAccessibility}/assets/accessibility/accessibility.css?v=${new Date().getTime()}&ver=${this.version}`;
546        linkElement.onload = () => {
547            this.createAccessibilityFloatingButton();
548            this.createAccessibilityMenu();
549            this.initDefaultParameters();
550            this.applySavedPreferences();
551        };
552        this.holder.appendChild(linkElement);
553    }
554
555    getHtmlFloatingButton() {
556        return `
557            <div class="accessibility-floating-button" style="--accessibility-bottom: ${this.bottom}; --accessibility-left: ${this.left};">
558                <button class="floating-button" aria-label="Apri/Chiudi Menu">
559                    <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="${this.primaryColor}">
560                        <path d="M480-723.85q-30.69 0-52.27-21.57-21.58-21.58-21.58-52.27 0-30.69 21.58-52.27 21.58-21.58 52.27-21.58 30.69 0 52.27 21.58 21.58 21.58 21.58 52.27 0 30.69-21.58 52.27-21.58 21.57-52.27 21.57ZM376.16-90v-521.54q-61.16-5-121.62-14.42-60.46-9.43-114.54-23.27l14.62-60q76.84 19.85 159.27 28.77 82.42 8.92 166.11 8.92 83.69 0 166.11-8.92 82.43-8.92 159.27-28.77l14.62 60q-54.08 13.84-114.54 23.27-60.46 9.42-121.62 14.42V-90h-59.99v-244.62h-87.7V-90h-59.99Z"/>
561                    </svg>
562                </button>
563            </div>
564        `;
565        // <svg viewBox="0 0 20 24" width="20" height="24" fill="none">
566        //     <g fill="${this.primaryColor}" stroke="${this.primaryColor}" stroke-width=".318">
567        //         <path d="M17.887 5.683c-2.627.664-4.907 1.144-7.886 1.144-2.985 0-5.269-.483-7.904-1.149C1.3 5.476.477 5.91.23 6.67a1.436 1.436 0 0 0 .877 1.792c1.21.45
5675 2.43.855 3.668 1.26l1.094.36c.594.197.946.785.833 1.382L4.699 22.008c-.15.788.357 1.556 1.153 1.774.867.237 1.78-.256 2.007-1.1l1.698-6.32a.456.456 0 0 1 .444-.332c.21 0 .392.136.445.332l1.698 6.32c.227.844 1.14 1.337 2.007 1.1.796-.218 1.302-.986 1.153-1.774l-1.995-10.507c-.116-.61.256-1.21.87-1.405 1.59-.503 3.148-1.02 4.687-1.59a1.461 1.461 0 0 0 .907-1.816c-.246-.77-1.08-1.211-1.886-1.007Z"/>
568        //         <path d="M10 5.657c.756 0 1.481-.29 2.016-.806a2.703 2.703 0 0 0 .836-1.943 2.68 2.68 0 0 0-.481-1.527 2.832 2.832 0 0 0-1.28-1.013A2.95 2.95 0 0 0 9.444.212a2.886 2.886 0 0 0-1.46.752 2.72 2.72 0 0 0-.78 1.408 2.658 2.658 0 0 0 .161 1.588c.216.502.582.932 1.05 1.234.47.302 1.021.463 1.585.463z"/>
569        //     </g>
570        // </svg>
571    }
572
573    getHtmlMenu() {
574        return `
575            <div class="accessibility-menu">
576                <button class="accessibility-menu-close" aria-label="Chiudi Menu">
577                    <img src="${this.websiteAccessibility}/assets/accessibility/media/close-icon.png" alt="Icona chiudi" width="28" height="28">
578                </button>
579                <div class="accessibility-menu-header">
580                    <p class="accessibility-title">Regolazione Accessibilit&agrave;</p>
581                </div>
582                <div class="accessibility-menu-content">
583                    <button class="accessibility-button accessibility-setting" data-action="reset-settings" aria-label="Reset Impostazioni">
584                        <img src="${this.websiteAccessibility}/assets/accessibility/media/reset-icon.png" alt="Icona reset" width="21" height="21"> Reset impostazioni
585                    </button>
586                    <button class="accessibility-button accessibility-setting" data-action="read-accessibility-statement" aria-label="Leggi Dichiarazione di Accessibilit&agrave;">
587                        <img src="${this.websiteAccessibility}/assets/accessibility/media/document-icon.png" alt="Icona documento" width="21" height="21"> Dichiarazione
588                    </button>
589                    <button class="accessibility-button accessibility-setting" data-action="hide-accessibility" aria-label="Nascondi Interfaccia Accessibilit&agrave;">
590                        <img src="${this.websiteAccessibility}/assets/accessibility/media/hide-icon.png" alt="Icona nascondi" width="21" height="21"> Nascondi interfaccia
591                    </button>
592                    <div class="accessibility-menu-separator" role="separator" aria-orientation="horizontal"></div>
593                    <p class="accessibility-title">Regolazione dei contenuti</p>
594                    <div class="accessibility-settings-group">
595                        <div class="accessibility-col-12">
596                            <div class="accessibility-setting-item">
597                                <p id="alterate-zoom-label" class="accessibility-setting-label">
598                                    <img src="${this.websiteAccessibility}/assets/accessibility/media/scale-icon.png" alt="Icona scala contenuto" width="21" height="21"> Scala i contenuti
599                                </p>
600                                <div class="accessibility-setting-controls">
601                                    <button class="accessibility-button accessibility-setting" aria-label="Riduci Scala Contenuti" data-action="decrease-zoom">
602                                        <img src="${this.websiteAccessibility}/assets/accessibility/media/remove-icon.png" alt="Icona diminuisci" width="21" height="21">
603                                    </button>
604                                    <span id="zoom-level" class="accessibility-setting-value" aria-live="polite" aria-atomic="true">Predefinito</span>
605                                    <button class="accessibility-button accessibility-setting" aria-label="Aumenta Scala Contenuti" data-action="increase-zoom">
606                                        <img src="${this.websiteAccessibility}/assets/accessibility/media/add-icon.png" alt="Icona incrementa" width="21" height="21">
607                                    </button>
608                                </div>
609                            </div>
610                        </div>
611                        <div class="accessibility-col-12">
612                            <div class="accessibility-setting-item">
613                                <p id="alterate-font-size-label" class="accessibility-setting-label">
614                                    <img src="${this.websiteAccessibility}/assets/accessibility/media/font-icon.png" alt="Icona dimensione caratteri" width="21" height="21"> Regola la dimensione dei caratteri
615                                </p>
616                                <div class="accessibility-setting-control
616s">
617                                    <button class="accessibility-button accessibility-setting" aria-label="Riduci Dimensione Caratteri" data-action="decrease-font-size">
618                                        <img src="${this.websiteAccessibility}/assets/accessibility/media/remove-icon.png" alt="Icona diminuisci" width="21" height="21">
619                                    </button>
620                                    <span id="font-size-level" class="accessibility-setting-value" aria-live="polite" aria-atomic="true">Predefinito</span>
621                                    <button class="accessibility-button accessibility-setting" aria-label="Aumenta Dimensione Caratteri" data-action="increase-font-size">
622                                        <img src="${this.websiteAccessibility}/assets/accessibility/media/add-icon.png" alt="Icona incrementa" width="21" height="21">
623                                    </button>
624                                </div>
625                            </div>
626                        </div>
627                    </div>
628                    <div class="accessibility-settings-group">
629                        <div class="accessibility-col-6">
630                            <button type="button" class="accessibility-setting-item accessibility-setting" aria-labelledby="#readable-font-label" data-action="readable-font">
631                                <img src="${this.websiteAccessibility}/assets/accessibility/media/text-icon.png" alt="Icona carattere" width="28" height="28">
632                                <p id="readable-font-label" class="accessibility-setting-label">
632Carattere leggibile</p>
633                            </button>
634                        </div>
635                        <div class="accessibility-col-6">
636                            <button type="button" class="accessibility-setting-item accessibility-setting" aria-labelledby="#alterate-alignment-center-label" data-action="alterate-alignment-center">
637                                <img src="${this.websiteAccessibility}/assets/accessibility/media/align-center-icon.png" alt="Icona allinea centro" width="28" height="28">
638                                <p id="alterate-alignment-center-label" class="accessibility-setting-label">Allinea al centro</p>
639                            </button>
640                        </div>
641                        <div class="accessibility-col-6">
642                            <button type="button" class="accessibility-setting-item accessibility-setting" aria-labelledby="#alterate-alignment-left-label" data-action="alterate-alignment-left">
643                                <img src="${this.websiteAccessibility}/assets/accessibility/media/align-left-icon.png" alt="Icona allinea sinistra" width="28" height="28">
644                                <p id="alterate-alignment-left-label" class="accessibility-setting-label">Allinea a sinistra</p>
645                            </button>
646                        </div>
647                        <div class="accessibility-col-6">
648                            <button type="button" class="accessibility-setting-item accessibility-setting" aria-labelledby="#alterate-alignment-right-label" data-action="alterate-alignment-right">
649                                <img src="${this.websiteAccessibility}/assets/accessibility/media/align-right-icon.png" alt="Icona allinea destra" width="28" height="28">
650                                <p id="alterate-alignment-right-label" class="accessibility-setting-label">Allinea a destra</p>
651                            </button>
652                        </div>
653                    </div>
654                    <div class="accessibility-menu-separator" role="separator" aria-orientation="horizontal"></div>
655                    <p class="accessibility-title">Regolazione del colore</p>
656                    <div class="accessibility-settings-group">
657                        <div class="accessibility-col-6 accessibility-col-lg-4">
658                            <button type="button" class="accessibility-setting-item accessibility-setting" aria-labelledby="#high-contrast-label" data-action="filter-high-contrast">
659                                <img src="${this.websiteAccessibility}/assets/accessibility/media/contrast-icon.png" alt="Icona contrasto" width="28" height="28">
660                                <p id="high-contrast-label" class="accessibility-setting-label">Contrasto elevato</p>
661                            </button>
662                        </div>
663                        <div class="accessibility-col-6 accessibility-col-lg-4">
664                            <button type="button" class="accessibility-setting-item accessibility-setting" aria-labelledby="#high-saturation-label" data-action="filter-high-saturation">
665                                <img src="${this.websiteAccessibility}/assets/accessibility/media/saturation-high-icon.png" alt="Icona saturazione alta" width="28" height="28">
666                                <p id="high-saturation-label" class="accessibility-setting-label">Saturazione elevata</p>
667                            </button>
668                        </div>
669                        <div class="accessibility-col-6 accessibility-col-lg-4">
670                            <button type="button" class="accessibility-setting-item accessibility-setting" aria-labelledby="#monocromatic-label" data-action="filter-monocromatic">
671                                <img src="${this.websiteAccessibility}/assets/accessibility/media/mono-icon.png" alt="Icona monocromatico" width="28" height="28">
672                                <p id="monocromatic-label" class="accessibility-setting-label">Monocromatico</p>
673                            </button>
674                        </div>
675                        <div class="accessibility-col-6">
676                            <button type="button" class="accessibility-setting-item accessibility-setting" aria-labelledby="#low-saturation-label" data-action="filter-low-saturation">
677                                <img src="${this.websiteAccessibility}/assets/accessibility/media/saturation-low-icon.png" alt="Icona saturaziona bassa" width="28" height="28">
678                                <p id="low-saturation-label" class="accessibility-setting-label">Saturazione bassa</p>
679                            </button>
680                        </div>
681                    </div>
682                </div>
683                <div id="accessibility-modal-hide-accessibility" role="dialog" class="accessibility-modal" aria-hidden="true" tabindex="-1">
684                    <p class="accessibility-title">Vuoi nascondere l'interfaccia di accessibilit&agrave;?</p>
685                    <p>Attenzione: se scegli di nascondere l'interfaccia di accessibilit&agrave;, non potrai pi&ugrave; vederla, a meno che non cancelli la cronologia e i dati di navigazione. Sei sicuro di voler nascondere l'interfaccia?</p>
686                    <div class="accessibility-modal-actions">
687                        <button class="accessibility-button accessibility-button-confirm" aria-label="Conferma Nascondi Interfaccia" data-modal-action="hide-accessibility">Conferma</button>
688                        <button class="accessibility-button accessibility-button-cancel" aria-label="Annulla Nascondi Interfaccia">Annulla</button>
689                    </div>
690                </div>
691                <div id="accessibility-modal-read-accessibility-statement" role="dialog" class="accessibility-modal" aria-hidden="true" tabindex="-1">
692                    <p class="accessibility-title">Dichiarazione di Accessibilit&agrave;</p>
693                    <div class="accessibility-section">
694                        <p class="accessibility-title-section">Stato di conformit&agrave;</p>
695                        <p class="accessibility-text">Crediamo fermamente che Internet debba essere disponibile e accessibile a chiunque e ci impegniamo a fornire un sito web accessibile al pubblico pi&ugrave; ampio possibile, indipendentemente dalle abilit&agrave;.</p>
696                        <p class="accessibility-text">Per realizzare questo obiettivo, puntiamo ad aderire nel modo pi&ugrave; rigoroso possibile alle Linee guida per l'accessibilit&agrave; dei contenuti web 2.1 (WCAG 2.1) del World Wide Web Consortium (W3C), a livello AA. Queste linee guida spiegano come rendere i contenuti web accessibili a persone con una vasta gamma di disabilit&agrave;. Rispettarle ci aiuta a garantire che il sito web sia accessibile a persone non vedenti, con disabilit&agrave; motorie, problemi di vista, disabilit&agrave;
696 cognitive e molto altro.</p>
697                        <p class="accessibility-text">Questo sito web utilizza diverse tecnologie pensate per renderlo il pi&ugrave; accessibile possibile in ogni momento. Utilizziamo un'interfaccia di accessibilit&agrave; che consente alle persone con disabilit&agrave; specifiche di modificare l'interfaccia utente (UI) del sito web e di adattarla alle proprie esigenze personali.</p>
698                        <p class="accessibility-text">Inoltre, il sito web utilizza un'applicazione basata sull'intelligenza artificiale che opera in background e ottimizza costantemente il livello di accessibilit&agrave;. Questa applicazione corregge il codice HTML del sito, adatta le sue funzionalit&agrave; e il suo comportamento per i lettori di schermo utilizzati dagli utenti non vedenti e per le funzioni da tastiera impiegate da persone con disabilit&agrave; motorie.</p>
699                        <p class="accessibility-text">Nonostante i nostri sforzi, alcune parti del sito web potrebbero non essere ancora completamente conformi alle linee guida WCAG 2.1. Stiamo lavorando costantemente per migliorare l'accessibilit&agrave; del sito e accogliamo con favore qualsiasi feedback o suggerimento che possa aiutarci in questo processo.</p>
700                        <p class="accessibility-text">Se desideri contattare il proprietario del sito web, utilizza il modulo presente sul sito.</p>
701                    </div>
702                    <div class="accessibility-section">
703                        <p class="accessibility-title-section">Navigazione tramite lettore di schermo e tastiera</p>
704                        <p class="accessibility-text">Il nostro sito web implementa la tecnica degli attributi ARIA (Accessible Rich Internet Applications), insieme a diverse modifiche comportamentali, per garantire che gli utenti non vedenti che utilizzano lettori di schermo possano leggere, comprendere e utilizzare pienamente le funzioni del sito. Non appena un utente con un lettore di schermo accede al sito, riceve immediatamente un prompt per inserire il Profilo del Lettore di Schermo, cos&igrave; da poter navigare e operare sul sito in modo efficace.<br/>Ecco come il nostro sito soddisfa alcuni dei requisiti più importanti per i lettori di schermo:</p>
705                        <p class="accessibility-text">
706                            <ul>
707                                <li>
708                                    <span class="accessibility-fw-500">Ottimizzazione per lettori di schermo:</span>
709                                    <br/>
710                                    Eseguiamo un processo che analizza i componenti del sito dall'alto verso il basso, per garantire la conformit&agrave; continua anche durante gli aggiornamenti del sito. In questo processo forniamo ai lettori di schermo dati significativi tramite l'insieme di attributi ARIA. Ad esempio, forniamo etichette accurate per i moduli; descrizioni per le icone interattive (icone dei social media, icone di ricerca, icone del carrello, ecc.); indicazioni di convalida per i campi dei moduli; ruoli degli elementi come pulsanti, menu, finestre modali (popup) e altri.
711                                    <br/>
712                                    <br/>
713                                    Inoltre, il processo in background analizza tutte le immagini del sito web. Fornisce una descrizione accurata e significativa basata sul riconoscimento degli oggetti presenti nelle immagini, utilizzata come tag ALT (testo alternativo) per le immagini non descritte. Estrarre anche i testi incorporati nelle immagini tramite la tecnologia OCR (riconoscimento ottico dei caratteri). Per attivare le regolazioni per il lettore di schermo in qualsiasi momento, agli utenti basta premere la combinazione di tasti Alt+1. Gli utenti che utilizzano lettori di schermo ricevono anche annunci automatici che li invitano ad attivare la modalit&agrave; Lettore di Schermo non appena accedono al sito.
714                                    <br/>
715                                    <br/>
716                                    Queste regolazioni sono compatibili con i principali lettori di schermo, come JAWS, NVDA, VoiceOver e TalkBack.
717                                </li>
718                                <li>
719                                    <span class="accessibility-fw-500">Ottimizzazione della navigazione tramite tastiera:</span>
720                                </li>
721                            </ul>
722                        </p>
723                    </div>
724                    <div class="accessibility-modal-actions">
725                        <button class="accessibility-button accessibility-button-cancel" aria-label="Chiudi Dichiarazione">Chiudi</button>
726                    </div>
727                </div>
728                <div class="accessibility-modal-backdrop"></div>
729            </div>
730            <div class="accessibility-menu-backdrop"></div>
731        `;
732        // <div class="accessibility-menu-footer">
733        //     <p class="accessibility-text-footer">Realizzato da <a href="${this.homepage}" target="_blank" rel="noopener">${this.authorHtml}</a></p>
734        // </div>
735    }
736
737    setCookie(name, value, days) {
738        const date = new Date();
739        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
740        const expires = "expires=" + date.toUTCString();
741        document.cookie = name + "=" + value + ";" + expires + ";path=/";
742    }
743
744    getCookie(name) {
745        const nameEQ = name + "=";
746        const ca = document.cookie.split(';');
747        for (let i = 0; i < ca.length; i++) {
748            let c = ca[i];
749            while (c.charAt(0) === ' ') c = c.substring(1, c.length);
750            if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
751        }
752        return null;
753    }
754}

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.