WME Multi Map Overlay

Erweiterte Version mit TopPlus, Dark Map, Basemap.de und allen DACH Geoportal Overlays

安裝腳本?
作者推薦腳本

您可能也會喜歡 WME GeoPortal Overlay DACH Beta

安裝腳本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name WME Multi Map Overlay
// @namespace https://greasyfork.org/de/users/863740-horst-wittlich
// @version 2025.11.09
// @description Erweiterte Version mit TopPlus, Dark Map, Basemap.de und allen DACH Geoportal Overlays
// @author Hiwi234
// @match https://www.waze.com/editor*
// @match https://www.waze.com/*/editor*
// @match https://beta.waze.com/editor*
// @match https://beta.waze.com/*/editor*
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @grant GM_info
// @connect sgx.geodatenzentrum.de
// @connect owsproxy.lgl-bw.de
// @connect www.wmts.nrw.de
// @connect geoservices.bayern.de
// @connect mapsneu.wien.gv.at
// @connect basemap.at
// @connect wmts.geo.admin.ch
// @connect www.geoportal.hessen.de
// @connect www.gds-srv.hessen.de
// @connect cdnjs.cloudflare.com
// @connect a.tile.openstreetmap.org
// @connect b.tile.openstreetmap.org
// @connect c.tile.openstreetmap.org
// @connect a.basemaps.cartocdn.com
// @connect b.basemaps.cartocdn.com
// @connect c.basemaps.cartocdn.com
// @connect a.tile.opentopomap.org
// @connect b.tile.opentopomap.org
// @connect c.tile.opentopomap.org
// @connect opendata.lgln.niedersachsen.de
// @connect www.gds-srv.hessen.de
// @connect gdi.berlin.de
// @connect isk.geobasis-bb.de
// @connect geodienste.hamburg.de
// @connect www.geodaten-mv.de
// @connect geo5.service24.rlp.de
// @connect geoportal.saarland.de
// @connect geodienste.sachsen.de
// @connect www.geodatenportal.sachsen-anhalt.de
// @connect dienste.gdi-sh.de
// @connect www.geoproxy.geoportal-th.de
// @license MIT
// ==/UserScript==

(function() {
'use strict';

const SCRIPT_NAME = 'WME Multi Overlay';
const SCRIPT_ID = 'wme-multi-overlay';
const DEFAULT_OPACITY = 0.64;
const DEFAULT_ZINDEX = 2010; // KORRIGIERT: Korrekte Standardwert 2010
const STORAGE_KEY = 'wme-overlay-settings';
const COLLAPSED_STATE_KEY = 'wme-overlay-collapsed-groups';

// Layer storage
const layers = {};

// KORRIGIERT: Zusätzliche Metadaten-Speicherung für Z-Index
const layerMetadata = {};

// Collapsed state storage
let collapsedGroups = {};

// Globaler Ein/Aus-Schalter (persistenter Zustand)
let scriptEnabled = true;
const ENABLED_KEY = 'wme-overlay-enabled';

function updateAllLayersVisibilityFromEnabled() {
    const settings = loadSettings();
    Object.keys(layers).forEach(layerId => {
        const layer = layers[layerId];
        if (!layer) return;
        const layerSettings = (settings.layers || {})[layerId] || {};
        const visible = !!layerSettings.visible;
        layer.setVisibility(scriptEnabled && visible);
    });
}

function setScriptEnabled(enabled, silent = false) {
    scriptEnabled = !!enabled;
    try { localStorage.setItem(ENABLED_KEY, JSON.stringify(scriptEnabled)); } catch (e) {}
    updateAllLayersVisibilityFromEnabled();
    const btn = document.getElementById('wme-overlay-toggle-btn');
    if (btn) {
        btn.textContent = scriptEnabled ? '🟢 Overlays AN' : '🔴 Overlays AUS';
        btn.setAttribute('aria-pressed', String(scriptEnabled));
    }
    document.dispatchEvent(new CustomEvent('wme-overlay-enabled-changed', { detail: { enabled: scriptEnabled } }));
}

function loadEnabledState() {
    let saved = null;
    try { saved = localStorage.getItem(ENABLED_KEY); } catch (e) {}
    if (saved !== null) {
        try { setScriptEnabled(JSON.parse(saved), true); return; } catch (e) {}
    }
    setScriptEnabled(true, true);
}

function toggleScriptEnabled() {
    setScriptEnabled(!scriptEnabled);
}

function createGlobalToggleUI() {

    let layerSidebarCheckbox = null;

    function buildSideItem() {
        const item = document.createElement('wz-checkbox');
        item.id = 'wme-overlay-side-toggle';
        item.checked = scriptEnabled;
        item.textContent = 'Multi Map';

        item.addEventListener('change', () => {
            toggleScriptEnabled();
            updateLayerSidebarCheckboxState();
        });

        layerSidebarCheckbox = item;

        // Event Listener für globale Änderungen
        document.addEventListener('wme-overlay-enabled-changed', (ev) => {
            const enabled = !!(ev && ev.detail && ev.detail.enabled);
            updateLayerSidebarCheckboxState();
        });

        return item;
    }

    function updateLayerSidebarCheckboxState() {
        if (layerSidebarCheckbox) {
            layerSidebarCheckbox.checked = scriptEnabled;
        }
    }

    function findRightPanelInsertionPoint() {
        // Bevorzugt direkt nach "Satellitenbild" im rechten Karten-Ebenen-Panel einfügen
        const sat = Array.from(document.querySelectorAll('label,div,span,button'))
            .find(el => /^\s*Satellitenbild\s*$/i.test((el.textContent||'')));
        if (sat) return { parent: sat.parentElement, mode: 'after' };

        // Alternativ: Liste unter "Andere Daten" finden
        const otherHeader = Array.from(document.querySelectorAll('h3,h4,button,div'))
            .find(el => /\bAndere Daten\b|\bOther Data\b|\bOther layers\b/i.test((el.textContent||'')));
        if (otherHeader) {
            const section = otherHeader.closest('section') || otherHeader.parentElement;
            const list = section && (section.querySelector('ul') || section.querySelector('div[role="group"],div'));
            if (list) return { parent: list, mode: 'prepend' };
        }

        // Fallback: generischer Container des rechten Panels
        const rightPanel = document.querySelector('[aria-label="Karten-Ebenen"],[data-testid="layers-panel"],.layers-panel,.panel-right');
        if (rightPanel) return { parent: rightPanel, mode: 'append' };
        return null;
    }

    function mountInPanel() {
        const target = findRightPanelInsertionPoint();
        if (!target) return false;
        if (document.getElementById('wme-overlay-side-toggle')) return true;
        const item = buildSideItem();
        if (target.mode === 'after' && target.parent) {
            target.parent.insertAdjacentElement('afterend', item);
        } else if (target.mode === 'prepend' && target.parent) {
            target.parent.insertBefore(item, target.parent.firstChild);
        } else if (target.parent) {
            target.parent.appendChild(item);
        } else {
            return false;
        }
        return true;
    }

    // Direkt versuchen im Panel zu montieren
    const mounted = mountInPanel();

    // Beobachte DOM, bis das rechte Panel gerendert ist
    if (!mounted) {
        const observer = new MutationObserver(() => {
            if (mountInPanel()) observer.disconnect();
        });
        observer.observe(document.body, { childList: true, subtree: true });
    }

    // Tastenkürzel Alt+O
    document.addEventListener('keydown', (ev) => {
        if (ev.altKey && (ev.key === 'o' || ev.key === 'O')) {
            ev.preventDefault();
            toggleScriptEnabled();
            updateLayerSidebarCheckboxState();
        }
    });

    // Globale Funktion für Synchronisation zwischen beiden Checkboxen
    window.updateLayerSidebarCheckbox = updateLayerSidebarCheckboxState;
}

// Settings Management - KORRIGIERT
function saveSettings() {
    const settings = {
        version: GM_info.script.version,
        layers: {}
    };

    Object.keys(layers).forEach(layerId => {
        const layer = layers[layerId];
        if (layer) {
            // KORRIGIERT: Verwende Metadaten für Z-Index als Fallback
            const metadata = layerMetadata[layerId] || {};
            settings.layers[layerId] = {
                visible: layer.getVisibility(),
                opacity: layer.opacity || DEFAULT_OPACITY,
                zIndex: metadata.zIndex || layer.getZIndex() || DEFAULT_ZINDEX // KORRIGIERT
            };
        }
    });

    try {
        localStorage.setItem(STORAGE_KEY, JSON.stringify(settings));
    } catch (error) {
        console.error('Fehler beim Speichern der Settings:', error);
    }
}

function saveCollapsedState() {
    try {
        localStorage.setItem(COLLAPSED_STATE_KEY, JSON.stringify(collapsedGroups));
    } catch (error) {
        console.error('Fehler beim Speichern des Collapsed State:', error);
    }
}

function loadCollapsedState() {
    try {
        const saved = localStorage.getItem(COLLAPSED_STATE_KEY);
        if (saved) {
            collapsedGroups = JSON.parse(saved);
        }
    } catch (error) {
        console.error('Fehler beim Laden der Collapsed State:', error);
        collapsedGroups = {};
    }
}

function saveGlobalFilters() {
    try {
        localStorage.setItem('wme-overlay-global-filters', JSON.stringify(globalFilters));
    } catch (error) {
        console.error('Fehler beim Speichern der globalen Filter:', error);
    }
}

function loadGlobalFilters() {
    try {
        const saved = localStorage.getItem('wme-overlay-global-filters');
        if (saved) {
            const filters = JSON.parse(saved);
            globalFilters = { ...globalFilters, ...filters };
        }
    } catch (error) {
        console.error('Fehler beim Laden der globalen Filter:', error);
    }
}

function loadSettings() {
    try {
        const saved = localStorage.getItem(STORAGE_KEY);
        if (saved) {
            const settings = JSON.parse(saved);
            return settings;
        }
    } catch (error) {
        console.error('Fehler beim Laden der Settings:', error);
    }
    return { layers: {} };
}

function applySettingsToLayer(layerId, layer) {
    const settings = loadSettings();
    const layerSettings = settings.layers[layerId];

    if (layerSettings) {
        // KORRIGIERT: Initialisiere Metadaten für Layer
        if (!layerMetadata[layerId]) {
            layerMetadata[layerId] = {};
        }

        // Sichtbarkeit anwenden (nur wenn Script aktiviert ist)
        const shouldBeVisible = scriptEnabled && (layerSettings.visible || false);
        layer.setVisibility(shouldBeVisible);

        // Transparenz anwenden
        layer.setOpacity(layerSettings.opacity || DEFAULT_OPACITY);

        // KORRIGIERT: Z-Index anwenden und in Metadaten speichern
        const zIndex = layerSettings.zIndex || DEFAULT_ZINDEX;
        layer.setZIndex(zIndex);
        layerMetadata[layerId].zIndex = zIndex;
    } else {
        // KORRIGIERT: Standardwerte setzen wenn keine Settings vorhanden
        if (!layerMetadata[layerId]) {
            layerMetadata[layerId] = {};
        }
        layer.setZIndex(DEFAULT_ZINDEX);
        layerMetadata[layerId].zIndex = DEFAULT_ZINDEX;
    }
}

// Filter-Updates: nur auf den ausgewählten Hintergrund-Layer anwenden
function updateAllLayerFilters() {
    const brightness = globalFilters.brightness;
    const contrast = globalFilters.contrast;
    const saturation = globalFilters.saturation;
    const sharpness = globalFilters.sharpness;

    // CSS Filter mit funktionierender Schärfe erstellen
    let filterString = `brightness(${brightness}%) contrast(${contrast}%) saturate(${saturation}%)`;

    // Schärfe-Implementierung
    if (sharpness < 100) {
        const blurAmount = (100 - sharpness) / 100 * 2; // Max 2px blur bei 0%
        filterString += ` blur(${blurAmount}px)`;
    } else if (sharpness > 100) {
        const extraContrast = 100 + (sharpness - 100) * 0.5; // Moderate Verstärkung
        filterString += ` contrast(${extraContrast}%)`;
    }

    setTimeout(() => {
        // Zunächst Filter in relevanten Map-Containern zurücksetzen
        const resetElems = document.querySelectorAll('#map canvas, #WazeMap canvas, .olLayerDiv');
        resetElems.forEach(el => {
            el.style.filter = '';
            el.style.webkitFilter = '';
        });

        // Auf alle Overlay-Layer (von uns erstellt) anwenden
        Object.keys(layers).forEach(layerId => {
            const layer = layers[layerId];
            if (layer && layer.div) {
                layer.div.style.filter = filterString;
                layer.div.style.webkitFilter = filterString;
            }
        });

        // Auf alle OL Layer-Divs anwenden (inkl. Standard-Hintergrundkarte)
        const layerElements = document.querySelectorAll('.olLayerDiv');
        layerElements.forEach(element => {
            element.style.filter = filterString;
            element.style.webkitFilter = filterString;
        });

        // Auf Canvas-Rendering anwenden (falls Basemap als Canvas gezeichnet wird)
        const canvasElements = document.querySelectorAll('#map canvas, #WazeMap canvas');
        canvasElements.forEach(canvas => {
            canvas.style.filter = filterString;
            canvas.style.webkitFilter = filterString;
        });
    }, 100);
}

// Neu organisierte Layer-Konfiguration
const layerGroups = {
    basic: {
        name: "🔧 Basis Layer",
        layers: [
            {
                id: 'basemap-de',
                name: 'Basemap.de',
                type: 'wms',
                url: 'https://sgx.geodatenzentrum.de/wms_basemapde',
                params: {
                    layers: 'de_basemapde_web_raster_farbe',
                    format: 'image/png',
                    transparent: true
                },
                attribution: '© <a href="https://www.basemap.de">basemap.de</a>'
            },
            {
                id: 'basemap-de-grau',
                name: 'Basemap.de Grau',
                type: 'wms',
                url: 'https://sgx.geodatenzentrum.de/wms_basemapde',
                params: {
                    layers: 'de_basemapde_web_raster_grau',
                    format: 'image/png',
                    transparent: true
                },
                attribution: '© <a href="https://www.basemap.de">basemap.de</a>'
            },
            {
                id: 'topplus',
                name: 'TopPlus WMS',
                type: 'wms',
                url: 'https://sgx.geodatenzentrum.de/wms_topplus_web_open',
                params: {
                    layers: 'web',
                    format: 'image/png',
                    transparent: true
                },
                attribution: '© BKG'
            },
            {
                id: 'topplus-grau',
                name: 'TopPlus Grau',
                type: 'wms',
                url: 'https://sgx.geodatenzentrum.de/wms_topplus_web_open',
                params: {
                    layers: 'web_grau',
                    format: 'image/png',
                    transparent: true
                },
                attribution: '© BKG'
            },
            {
                // (Liegenschaftskarten verschoben in eigene Kategorie)
            }
        ]
    },
    cadastre: {
        name: "📐 Liegenschaftskarten",
        layers: [
            {
                id: "alkis-by",
                name: "Liegenschaftskarte Bayern",
                type: "wmts",
                source: "https://geoservices.bayern.de/od/wmts/geobasis/v1/1.0.0/WMTSCapabilities.xml",
                layerName: "by_webkarte",
                matrixSet: "smerc",
				attribution: 'Bayerische Vermessungsverwaltung, GeoBasis-DE / BKG'
            },
			{
                id: 'alkis-be',
                name: 'Liegenschaftskarte Berlin',
                type: 'wms',
                url: 'https://gdi.berlin.de/services/wms/alkis?SERVICE=wms',
                params: {
                    layers: 'a_alkis_raster',
                    format: 'image/png',
                    version: '1.3.0'
                },
            },
			{
                id: 'alkis-bw',
                name: 'Liegenschaftskarte BW',
                type: 'wms',
                url: 'https://owsproxy.lgl-bw.de/owsproxy/ows/WMS_LGL-BW_ALKIS_Basis_Vertrieb?service=WMS',
                params: {
                    layers: 'nora:ALKIS_Basis_Vertrieb,nora:ALKIS_Beschriftung',
                    format: 'image/png',
                    version: '1.3.0'
                },
                attribution: 'LGL-BW'
            },
			{
                id: 'alkis-bb',
                name: 'Liegenschaftskarte BB',
                type: 'wms',
                url: 'https://isk.geobasis-bb.de/ows/alkis_wms?service=WMS',
                params: {
                    layers: 'adv_alkis_gewaesser,adv_alkis_vegetation,adv_alkis_verkehr,adv_alkis_siedlung,adv_alkis_gebaeude,adv_alkis_flurstuecke',
                    format: 'image/png',
                    version: '1.3.0'
                },
                attribution: 'GeoBasis-DE/LGB'
            },
            {
                id: 'alkis-hb',
                name: 'Liegenschaftskarte Bremen',
                type: 'wms',
                url: 'https://opendata.lgln.niedersachsen.de/doorman/noauth/alkishb_wms',
                params: {
                    layers: 'ALKIS',
                    styles: 'Farbe',
                    format: 'image/png',
                    version: '1.3.0'
                },
                attribution: 'Landesamt GeoInformation Bremen'
            },
			{
                id: 'alkis-hh',
                name: 'Liegenschaftskarte Hamburg',
                type: 'wms',
                url: 'https://geodienste.hamburg.de/HH_WMS_ALKIS_Basiskarte?SERVICE=WMS',
                params: {
                    layers: '0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,27,25,23,29,30',
                    format: 'image/png',
                    version: '1.3.0'
                },
                attribution: 'Freie und Hansestadt Hamburg, Landesbetrieb Geoinformation und Vermessung, 2014'
            },
            {
                id: 'alkis-he',
                name: 'Liegenschaftskarte Hessen',
                type: 'wms',
                url: 'https://www.gds-srv.hessen.de/cgi-bin/lika-services/ogc-free-maps.ows',
                params: {
                    layers: 'he_alk',
                    format: 'image/png',
                    transparent: true,
                    version: '1.3.0'
                },
                attribution: 'Hessische Verwaltung für Bodenmanagement und Geoinformation'
            },
			{
                id: 'alkis-mv',
                name: 'Liegenschaftskarte MV',
                type: 'wms',
                url: 'https://www.geodaten-mv.de/dienste/alkis_wms',
                params: {
                    layers: 'adv_alkis_tatsaechliche_nutzung,adv_alkis_gebaeude,adv_alkis_flurstuecke',
                    format: 'image/png',
                    version: '1.3.0'
                },
                attribution: 'GeoBasis-DE/M-V'
            },
            {
                id: 'alkis-nds',
                name: 'Liegenschaftskarte NDS',
                type: 'wms',
                url: 'https://opendata.lgln.niedersachsen.de/doorman/noauth/alkis_wms',
                params: {
                    layers: 'ALKIS',
                    styles: 'Farbe',
                    format: 'image/png',
                    transparent: true,
                    version: '1.3.0'
                },
                attribution: 'GeoBasis-DE/LGLN'
            },
			{
                id: "alkis-nw",
                name: "Liegenschaftskarte NRW (Farbe)",
                type: "wmts",
                source: "https://www.wmts.nrw.de/geobasis/wmts_nw_alkis/1.0.0/WMTSCapabilities.xml",
                layerName: "nw_alkis",
                matrixSet: "EPSG_3857_16",
            },
            {
                id: "alkis-nw-grau",
                name: "Liegenschaftskarte NRW (Grau)",
                type: "wmts",
                source: "https://www.wmts.nrw.de/geobasis/wmts_nw_alkis/1.0.0/WMTSCapabilities.xml",
                layerName: "nw_alkis_grau",
                matrixSet: "EPSG_3857_16",
            },
			{
                id: 'alkis-rp',
                name: 'Liegenschaftskarte RLP',
                type: 'wms',
                url: 'https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi',
                params: {
                    layers: 'Nutzung,GebaeudeBauwerke,Flurstueck,Lagebezeichnungen',
                    format: 'image/png',
                    version: '1.3.0'
                },
                attribution: 'GeoBasis-DE / LVermGeoRP'
            },
			{
                id: 'alkis-sl',
                name: 'Liegenschaftskarte Saarland',
                type: 'wms',
                url: 'https://geoportal.saarland.de/geobasisdaten/mapserv?map=/mapfiles/geobasisdaten/Internet/alkis.map&SERVICE=WMS',
                params: {
                    layers: 'adv_alkis',
                    format: 'image/png',
                    version: '1.1.1'
                },
                attribution: 'GeoBasis DE/LVGL-SL'
            },
			{
                id: 'alkis-sn',
                name: 'Liegenschaftskarte Sachsen',
                type: 'wms',
                url: 'https://geodienste.sachsen.de/wms_geosn_alkis-adv/guest',
                params: {
                    layers: 'adv_alkis_tatsaechliche_nutzung,adv_alkis_gebaeude,adv_alkis_flurstuecke,adv_alkis_fgp',
                    format: 'image/png'
                },
                attribution: 'Geodaten Sachsen'
            },
			{
                id: 'alkis-st',
                name: 'Liegenschaftskarte ST',
                type: 'wms',
                url: 'https://www.geodatenportal.sachsen-anhalt.de/wss/service/ST_LVermGeo_ALKIS_WMS_AdV_konform_App/guest',
                params: {
                    layers: 'adv_alkis_tatsaechliche_nutzung,adv_alkis_gebaeude,st_alkis_flurstuecke',
                    format: 'image/png'
                },
                attribution: 'GeoBasis DE/LVermGeo ST'
            },
			{
                id: 'alkis-sh',
                name: 'Liegenschaftskarte SH',
                type: 'wms',
                url: 'https://dienste.gdi-sh.de/WMS_SH_ALKIS_OpenGBD',
                params: {
                    layers: 'SH_ALKIS',
                    format: 'image/png'
                },
                attribution: 'GeoBasis-DE/LVermGeo SH'
            },
			{
                id: 'alkis-th',
                name: 'Liegenschaftskarte Thüringen',
                type: 'wms',
                url: 'https://www.geoproxy.geoportal-th.de/geoproxy/services/adv_alkis_wms_th',
                params: {
                    layers: 'adv_alkis_gewaesser,adv_alkis_siedlung,adv_alkis_vegetation,adv_alkis_verkehr,adv_alkis_flurstuecke,adv_alkis_gebaeude',
                    format: 'image/png',
					version: '1.3.0'
                },
                attribution: 'GDI-Th'
            },
        ]
    },
    germany: {
        name: "🇩🇪 GeoOverlays DE",
        layers: [
            {
                id: "geoportal-nrw",
                name: "GeoPortal NRW",
                type: "wmts",
                source: "https://www.wmts.nrw.de/geobasis/wmts_nw_dtk/1.0.0/WMTSCapabilities.xml",
                layerName: "nw_dtk_col",
                matrixSet: "EPSG_3857_16",
            },
            {
                id: "geoportal-nrw-overlay",
                name: "GeoPortal NRW Overlay",
                type: "wmts",
                source: "https://www.wmts.nrw.de/geobasis/wmts_nw_dop_overlay/1.0.0/WMTSCapabilities.xml",
                layerName: "nw_dop_overlay",
                matrixSet: "EPSG_3857_16",
            },
            {
                id: "geoportal-by",
                name: "GeoPortal BY",
                type: "wmts",
                source: "https://geoservices.bayern.de/od/wmts/geobasis/v1/1.0.0/WMTSCapabilities.xml",
                layerName: "by_webkarte",
                matrixSet: "smerc",
            },
            {
                id: "dop-nrw",
                name: "Luftbild NRW",
                type: "wmts",
                source: "https://www.wmts.nrw.de/geobasis/wmts_nw_dop/1.0.0/WMTSCapabilities.xml",
                layerName: "nw_dop",
                matrixSet: "EPSG_3857_16",
            },
            {
                id: "dop-by",
                name: "Luftbild BY",
                type: "wmts",
                source: "https://geoservices.bayern.de/od/wmts/geobasis/v1/1.0.0/WMTSCapabilities.xml",
                layerName: "by_dop",
                matrixSet: "smerc",
            },
            {
                id: 'dop-nds',
                name: 'Luftbild NDS',
                type: 'wms',
                url: 'https://opendata.lgln.niedersachsen.de/doorman/noauth/dop_wms',
                params: {
                    layers: 'ni_dop20',
                    format: 'image/png',
                    transparent: false,
                    version: '1.3.0',
                    crs: 'EPSG:3857'
                },
                attribution: '© LGLN 2024'
            },
            {
                id: 'vg25-de',
                name: 'Verwaltungsgebiete DE 1:25.000',
                type: 'wms',
                url: 'https://sg.geodatenzentrum.de/wms_vg25',
                params: {
                    layers: 'vg25',
                    format: 'image/png',
                    transparent: true
                },
                attribution: '© BKG'
            },
            {
                id: 'vg25-li-de',
                name: 'Grenzlinien DE 1:25.000',
                type: 'wms',
                url: 'https://sg.geodatenzentrum.de/wms_vg25',
                params: {
                    layers: 'vg25_li',
                    format: 'image/png',
                    transparent: true
                },
                attribution: '© BKG'
            },
            // (Liegenschaftskarte Hessen verschoben in eigene Kategorie)
            {
                id: 'truedop-hessen',
                name: 'TrueDOP Hessen (Luftbild)',
                type: 'wms',
                url: 'https://www.gds-srv.hessen.de/cgi-bin/lika-services/de-viewer/access/ogc-free-images.ows',
                params: {
                    layers: 'he_dop20_rgb',
                    format: 'image/jpeg',
                    transparent: false,
                    version: '1.3.0',
                    crs: 'EPSG:3857'
                },
                attribution: '© Hessische Verwaltung für Bodenmanagement und Geoinformation'
            }
        ]
    },
    austria: {
        name: "🇦🇹 GeoOverlays AT",
        layers: [
            {
                id: "basemap-at",
                name: "Basemap AT",
                type: "wmts",
                source: "https://mapsneu.wien.gv.at/basemapneu/1.0.0/WMTSCapabilities.xml",
                layerName: "geolandbasemap",
                matrixSet: "google3857",
            },
            {
                id: "overlay-at",
                name: "Overlay AT",
                type: "wmts",
                source: "https://www.basemap.at/wmts/1.0.0/WMTSCapabilities.xml",
                layerName: "bmapoverlay",
                matrixSet: "google3857",
            }
        ]
    },
    switzerland: {
        name: "🇨🇭 GeoOverlays CH",
        layers: [
            {
                id: "swiss-strassen",
                name: "Strassenkarte",
                type: "wmts",
                source: "https://wmts.geo.admin.ch/EPSG/3857/1.0.0/WMTSCapabilities.xml",
                layerName: "ch.swisstopo.swisstne-base",
                matrixSet: "3857_18",
            },
            {
                id: "swiss-basis",
                name: "Basisnetz",
                type: "wmts",
                source: "https://wmts.geo.admin.ch/EPSG/3857/1.0.0/WMTSCapabilities.xml",
                layerName: "ch.swisstopo.swisstlm3d-strassen",
                matrixSet: "3857_18",
            },
            {
                id: "swiss-luft",
                name: "Luftbild",
                type: "wmts",
                source: "https://wmts.geo.admin.ch/EPSG/3857/1.0.0/WMTSCapabilities.xml",
                layerName: "ch.swisstopo.swissimage-product",
                matrixSet: "3857_20",
            }
        ]
    },
    unofficial: {
        name: "🌍 Nicht Amtliche Karten",
        layers: [
            {
                id: 'osm-standard',
                name: 'OpenStreetMap Standard',
                type: 'xyz',
                urls: [
                    'https://a.tile.openstreetmap.org/${z}/${x}/${y}.png',
                    'https://b.tile.openstreetmap.org/${z}/${x}/${y}.png',
                    'https://c.tile.openstreetmap.org/${z}/${x}/${y}.png'
                ],
                attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
            },
            {
                id: 'darkmap',
                name: 'OSM Dark Matter',
                type: 'xyz',
                urls: [
                    'https://a.basemaps.cartocdn.com/dark_all/${z}/${x}/${y}@2x.png',
                    'https://b.basemaps.cartocdn.com/dark_all/${z}/${x}/${y}@2x.png',
                    'https://c.basemaps.cartocdn.com/dark_all/${z}/${x}/${y}@2x.png'
                ],
                attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>'
            },
            {
                id: 'opentopomap',
                name: 'OpenTopoMap',
                type: 'xyz',
                urls: [
                    'https://a.tile.opentopomap.org/${z}/${x}/${y}.png',
                    'https://b.tile.opentopomap.org/${z}/${x}/${y}.png',
                    'https://c.tile.opentopomap.org/${z}/${x}/${y}.png'
                ],
                attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, SRTM | Map style: © <a href="https://opentopomap.org">OpenTopoMap</a> (CC-BY-SA)'
            }
        ]
    }
};

// Hilfsfunktionen für OpenLayers Patches
function loadOLScript(filename) {
    const version = OpenLayers.VERSION_NUMBER.replace(/Release /, "");
    const url = `https://cdnjs.cloudflare.com/ajax/libs/openlayers/${version}/${filename}.js`;
    console.info("Loading openlayers/" + version + "/" + filename + ".js");
    const nonceEl = document.querySelector('script[nonce]');
    const nonce = nonceEl ? (nonceEl.nonce || nonceEl.getAttribute('nonce')) : null;

    // Lade Modulcode per GM_xmlhttpRequest und injiziere ihn inline mit Nonce (CSP-konform)
    try {
        GM_xmlhttpRequest({
            method: "GET",
            url,
            onload: (response) => {
                if (!response || typeof response.responseText !== 'string' || response.status !== 200) {
                    console.error(SCRIPT_NAME + ': Fehler beim Laden von', url, response && response.status);
                    return;
                }
                const script = document.createElement('script');
                script.type = 'text/javascript';
                // Inline-Code, kein eval – CSP erlaubt, wenn Nonce gesetzt
                if (nonce) script.setAttribute('nonce', nonce);
                script.textContent = response.responseText;
                document.head.appendChild(script);
            },
            onerror: (err) => {
                console.error(SCRIPT_NAME + ': Netzwerkfehler beim Laden von', url, err);
            }
        });
    } catch (e) {
        console.error(SCRIPT_NAME + ': Ausnahme beim Laden von', url, e);
    }
}

function patchOpenLayers() {
    if (!OpenLayers.VERSION_NUMBER.match(/^Release [0-9.]*$/)) {
        console.error("OpenLayers version mismatch - cannot apply patch");
        return;
    }

    // Lade notwendige OpenLayers Komponenten mit Delay für bessere Kompatibilität
    const scripts = [
        "lib/OpenLayers/Format/XML",
        "lib/OpenLayers/Format/XML/VersionedOGC",
        "lib/OpenLayers/Layer/WMTS",
        "lib/OpenLayers/Format/OWSCommon",
        "lib/OpenLayers/Format/OWSCommon/v1",
        "lib/OpenLayers/Format/OWSCommon/v1_1_0",
        "lib/OpenLayers/Format/WMSCapabilities",
        "lib/OpenLayers/Format/WMSCapabilities/v1",
        "lib/OpenLayers/Format/WMSCapabilities/v1_3",
        "lib/OpenLayers/Format/WMSCapabilities/v1_3_0",
        "lib/OpenLayers/Format/WMTSCapabilities",
        "lib/OpenLayers/Format/WMTSCapabilities/v1_0_0"
    ];

    // Lade Scripts sequenziell mit kleinem Delay
    scripts.forEach((script, index) => {
        setTimeout(() => {
            loadOLScript(script);
        }, index * 50); // 50ms Delay zwischen Scripts
    });

    // Warte bis alle Scripts geladen sind, bevor WMTS Layer erstellt werden
    setTimeout(() => {
        const hasWMTS = typeof OpenLayers.Layer.WMTS === 'function';
        const hasCaps = typeof OpenLayers.Format.WMTSCapabilities === 'function';
        if (!hasWMTS || !hasCaps) {
            console.warn(SCRIPT_NAME + ': WMTS Komponenten nicht vollständig geladen, versuche erneut...');
            // Zweiter Ladeversuch für die kritischen Module
            [
                "lib/OpenLayers/Layer/WMTS",
                "lib/OpenLayers/Format/WMTSCapabilities",
                "lib/OpenLayers/Format/WMTSCapabilities/v1_0_0"
            ].forEach((m, i) => setTimeout(() => loadOLScript(m), i * 50));
        } else {
            console.info(SCRIPT_NAME + ': WMTS Komponenten bereit.');
        }
    }, scripts.length * 50 + 600);
}

// Basis Layer erstellen - KORRIGIERT
function createBasicLayer(config) {
    const olMap = W.map.getOLMap();
    let layer;

    switch (config.type) {
        case 'wms':
            layer = new OpenLayers.Layer.WMS(
                config.name,
                config.url,
                config.params,
                {
                    transitionEffect: 'resize',
                    attribution: config.attribution,
                    isBaseLayer: false,
                    visibility: false,
                    opacity: DEFAULT_OPACITY,
                    projection: new OpenLayers.Projection("EPSG:3857"),
                    displayInLayerSwitcher: false,
                    alwaysInRange: true,
                    zIndex: DEFAULT_ZINDEX
                }
            );
            break;

        case 'xyz':
            // Für OpenTopoMap und andere XYZ-Services: Spezielle URL-Behandlung
            if (config.id === 'opentopomap') {
                layer = new OpenLayers.Layer.XYZ(
                    config.name,
                    config.urls,
                    {
                        attribution: config.attribution,
                        transitionEffect: 'resize',
                        isBaseLayer: false,
                        visibility: false,
                        opacity: DEFAULT_OPACITY,
                        displayInLayerSwitcher: false,
                        alwaysInRange: true,
                        sphericalMercator: true,
                        projection: new OpenLayers.Projection("EPSG:3857"),
                        zIndex: DEFAULT_ZINDEX,
                        // Explizite getURL-Funktion für OpenTopoMap
                        getURL: function(bounds) {
                            var res = this.getServerResolution();
                            var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
                            var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
                            var z = this.getServerZoom();
                            var path = z + "/" + x + "/" + y + ".png";
                            var url = this.url;
                            if (OpenLayers.Util.isArray(url)) {
                                var s = '' + x + y + z;
                                url = this.selectUrl(path, url);
                            }
                            return url.replace(/\$\{z\}/g, z).replace(/\$\{x\}/g, x).replace(/\$\{y\}/g, y);
                        }
                    }
                );
            } else {
                layer = new OpenLayers.Layer.XYZ(
                    config.name,
                    config.urls,
                    {
                        attribution: config.attribution,
                        transitionEffect: 'resize',
                        isBaseLayer: false,
                        visibility: false,
                        opacity: DEFAULT_OPACITY,
                        displayInLayerSwitcher: false,
                        alwaysInRange: true,
                        sphericalMercator: true,
                        projection: new OpenLayers.Projection("EPSG:3857"),
                        zIndex: DEFAULT_ZINDEX
                    }
                );
            }
            break;
    }

    if (layer) {
        layer.setOpacity(DEFAULT_OPACITY);
        olMap.addLayer(layer);
        layers[config.id] = layer;

        // KORRIGIERT: Metadaten initialisieren
        layerMetadata[config.id] = { zIndex: DEFAULT_ZINDEX };

        // Gespeicherte Einstellungen anwenden
        applySettingsToLayer(config.id, layer);
    }
}

// WMTS Layer erstellen - KORRIGIERT
function createWMTSLayer(layerConfig) {
    return new Promise((resolve, reject) => {
        // Prüfe ob WMTSCapabilities verfügbar ist
        if (typeof OpenLayers.Format.WMTSCapabilities !== 'function') {
            console.warn(`⚠ WMTSCapabilities not available for ${layerConfig.name}, skipping...`);
            reject(new Error("WMTSCapabilities constructor not available"));
            return;
        }

        GM_xmlhttpRequest({
            method: "GET",
            url: layerConfig.source,
            onload: (response) => {
                try {
                    let responseXML = response.responseXML;
                    if (!responseXML) {
                        responseXML = new DOMParser().parseFromString(response.responseText, "text/xml");
                    }

                    if (!responseXML || !(responseXML instanceof XMLDocument)) {
                        throw new Error("Invalid XML response");
                    }

                    const format = new OpenLayers.Format.WMTSCapabilities();
                    const capabilities = format.read(responseXML);

                    const layer = format.createLayer(capabilities, {
                        layer: layerConfig.layerName,
                        matrixSet: layerConfig.matrixSet,
                        opacity: DEFAULT_OPACITY,
                        isBaseLayer: false,
                        requestEncoding: layerConfig.requestEncoding || "REST",
                        visibility: false,
                        zIndex: DEFAULT_ZINDEX
                    });

                    if (layer && layer.url && layer.url.length) {
                        const olMap = W.map.getOLMap();
                        olMap.addLayer(layer);
                        olMap.setLayerIndex(layer, 9);

                        layers[layerConfig.id] = layer;

                        // KORRIGIERT: Metadaten initialisieren
                        layerMetadata[layerConfig.id] = { zIndex: DEFAULT_ZINDEX };

                        // Gespeicherte Einstellungen anwenden
                        applySettingsToLayer(layerConfig.id, layer);

                        resolve(layer);
                    } else {
                        throw new Error("No valid URLs found");
                    }

                } catch (error) {
                    console.error(`✗ Failed to load ${layerConfig.name}:`, error);
                    reject(error);
                }
            },
            onerror: () => reject(new Error("Network error")),
            ontimeout: () => reject(new Error("Request timeout"))
        });
    });
}

// Update Notification System
function showUpdateNotification() {
    // Prüfe ob bereits angezeigt wurde
    const lastShown = localStorage.getItem('wme-overlay-update-shown');
    const currentVersion = GM_info.script.version;

    if (lastShown === currentVersion) {
        return; // Bereits für diese Version angezeigt
    }

    // Erstelle Overlay
    const overlay = document.createElement('div');
    overlay.className = 'update-notification-overlay';
    overlay.innerHTML = `
        <div class="update-notification">
            <div class="update-header">
                <h2>WME Multi Map 🗺️ Overlay</h2>
                <div class="header-right">
                    <span class="version-badge">v${currentVersion}</span>
                    <button class="close-btn" id="header-close-btn">×</button>
                </div>
            </div>
            <div class="update-content">
                <h3>🎨 Vollständige Overlay-Features!</h3>
                <div class="new-features">
                    <div class="feature-group">
                        <h4>🆕 Neue Karten hinzugefügt:</h4>
                        <ul>
                            <li>🌍 <strong>Luftbild NRW (dop-nrw)</strong> - Hochauflösende Luftbilder von Nordrhein-Westfalen</li>
                            <li>🏔️ <strong>Luftbild Bayern (dop-by)</strong> - Detaillierte Luftaufnahmen aus Bayern</li>
                            <li>📍 <strong>Verwaltungsgebiete DE 1:25.000 (vg25-de)</strong> - Präzise deutsche Verwaltungsgrenzen im Maßstab 1:25.000</li>
                            <li>🔲 <strong>Grenzlinien DE 1:25.000 (vg25-li-de)</strong> - Deutsche Verwaltungsgrenzen ohne Beschriftung</li>
                        </ul>
                    </div>
                    <div class="feature-group">
                        <h4>📐 Neue Liegenschaftskarten:</h4>
                        <ul>
                            <li>🧭 <strong>Liegenschaftskarte NRW (Farbe)</strong> – WMTS, Web Mercator (EPSG:3857)</li>
                            <li>⬛ <strong>Liegenschaftskarte NRW (Grau)</strong> – WMTS, Web Mercator (EPSG:3857)</li>
                            <li>🗂️ <strong>Liegenschaftskarte Niedersachsen (ALKIS)</strong> – WMS</li>
                            <li>🗺️ <strong>Liegenschaftskarte Hessen</strong> – WMS</li>
                        </ul>
                    </div>
                </div>
                <div class="feature-info">
                    <p><strong>🎯 NEU:</strong> Liegenschaftskarten für NRW (Farbe/Grau), Niedersachsen (ALKIS) und Hessen verfügbar – ideal für Grundstücks- und Flurstücksrecherche. Danke an endradon</p>
                </div>
            </div>
            <div class="update-actions">
                <button class="btn-primary" id="explore-maps-btn">🚀 Neue Karten erkunden und Schließen!
                </button>
            </div>
        </div>
    `;

    // Styles für das Update-Popup
    const updateStyle = document.createElement('style');
    updateStyle.textContent = `
        .update-notification-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.8);
            z-index: 999999;
            display: flex;
            align-items: center;
            justify-content: center;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        }

        .update-notification {
            background: white;
            border-radius: 12px;
            max-width: 600px;
            width: 90%;
            max-height: 80vh;
            overflow-y: auto;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
            animation: slideIn 0.3s ease-out;
        }

        @keyframes slideIn {
            from {
                opacity: 0;
                transform: scale(0.9) translateY(-20px);
            }
            to {
                opacity: 1;
                transform: scale(1) translateY(0);
            }
        }

        .update-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 12px 12px 0 0;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .header-right {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .close-btn {
            background: rgba(255, 255, 255, 0.2);
            border: none;
            color: white;
            width: 32px;
            height: 32px;
            border-radius: 50%;
            font-size: 18px;
            font-weight: bold;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: background 0.2s;
        }

        .close-btn:hover {
            background: rgba(255, 255, 255, 0.3);
        }

        .update-header h2 {
            margin: 0;
            font-size: 24px;
            font-weight: 600;
        }

        .version-badge {
            background: rgba(255, 255, 255, 0.2);
            padding: 4px 12px;
            border-radius: 20px;
            font-size: 14px;
            font-weight: 500;
        }

        .update-content {
            padding: 24px;
        }

        .update-content h3 {
            margin: 0 0 20px 0;
            color: #333;
            font-size: 20px;
        }

        .new-features {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin-bottom: 24px;
        }

        .feature-group {
            background: #f8f9fa;
            padding: 16px;
            border-radius: 8px;
            border-left: 4px solid #667eea;
        }

        .feature-group h4 {
            margin: 0 0 12px 0;
            color: #333;
            font-size: 16px;
            font-weight: 600;
        }

        .feature-group ul {
            margin: 0;
            padding-left: 0;
            list-style: none;
        }

        .feature-group li {
            margin: 6px 0;
            color: #555;
            font-size: 14px;
        }

        .feature-info {
            background: #e3f2fd;
            padding: 16px;
            border-radius: 8px;
            border-left: 4px solid #2196f3;
        }

        .feature-info p {
            margin: 0;
            color: #1565c0;
            font-size: 14px;
        }

        .feature-info strong {
            font-weight: 600;
        }

        .update-actions {
            padding: 20px 24px;
            border-top: 1px solid #eee;
            display: flex;
            gap: 12px;
            justify-content: flex-end;
        }

        .btn-primary, .btn-secondary {
            padding: 12px 24px;
            border: none;
            border-radius: 6px;
            font-size: 14px;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.2s;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            line-height: 1;
            text-align: center;
        }

        .btn-primary {
            background: #667eea;
            color: white;
        }

        .btn-primary:hover {
            background: #5a6fd8;
            transform: translateY(-1px);
        }

        .btn-secondary {
            background: #e0e0e0;
            color: #333;
        }

        .btn-secondary:hover {
            background: #d0d0d0;
        }
    `;
    document.head.appendChild(updateStyle);
    document.body.appendChild(overlay);

    // Event Listener für Buttons hinzufügen
    overlay.querySelector('#explore-maps-btn').addEventListener('click', function() {
        overlay.remove();
        localStorage.setItem('wme-overlay-update-shown', currentVersion);
    });



    overlay.querySelector('#header-close-btn').addEventListener('click', function() {
        overlay.remove();
        localStorage.setItem('wme-overlay-update-shown', currentVersion);
    });

    // Overlay bei Klick außerhalb schließen
    overlay.addEventListener('click', function(e) {
        if (e.target === overlay) {
            overlay.remove();
            localStorage.setItem('wme-overlay-update-shown', currentVersion);
        }
    });

    // ESC-Taste zum Schließen
    document.addEventListener('keydown', function(e) {
        if (e.key === 'Escape' && document.contains(overlay)) {
            overlay.remove();
            localStorage.setItem('wme-overlay-update-shown', currentVersion);
        }
    });
}

// Drag & Drop Funktionalität für Hauptmenüs/Kategorien
function makeGroupDraggable(container, groupKey) {
    container.dataset.groupKey = groupKey;

    const header = container.querySelector('.group-header');
    if (!header) return;

    // Drag-Handle zur Gruppe hinzufügen (rechts positioniert)
    const dragHandle = document.createElement('span');
    dragHandle.className = 'group-drag-handle';
    dragHandle.innerHTML = '⋮⋮';
    dragHandle.title = 'Kategorie verschieben';
    dragHandle.draggable = true; // Nur das Handle ist draggable

    // Handle am Ende des Headers einfügen
    header.appendChild(dragHandle);

    // Drag Events nur für das Handle
    dragHandle.addEventListener('dragstart', (e) => {
        container.classList.add('group-dragging');
        e.dataTransfer.setData('text/plain', groupKey);
        e.dataTransfer.effectAllowed = 'move';
        e.stopPropagation();
    });

    dragHandle.addEventListener('dragend', () => {
        container.classList.remove('group-dragging');
        // Entferne alle Drop-Indikatoren
        document.querySelectorAll('.layer-group').forEach(el => {
            el.classList.remove('group-drop-target-above', 'group-drop-target-below');
        });
    });

    // Drop Events auf dem Container
    container.addEventListener('dragover', (e) => {
        e.preventDefault();
        e.dataTransfer.dropEffect = 'move';

        const draggingElement = document.querySelector('.group-dragging');
        if (draggingElement && draggingElement !== container) {
            const rect = container.getBoundingClientRect();
            const midY = rect.top + rect.height / 2;

            // Entferne vorherige Indikatoren
            container.classList.remove('group-drop-target-above', 'group-drop-target-below');

            // Füge entsprechenden Indikator hinzu
            if (e.clientY < midY) {
                container.classList.add('group-drop-target-above');
            } else {
                container.classList.add('group-drop-target-below');
            }
        }
    });

    container.addEventListener('dragleave', (e) => {
        // Nur entfernen wenn wir den Container wirklich verlassen
        if (!container.contains(e.relatedTarget)) {
            container.classList.remove('group-drop-target-above', 'group-drop-target-below');
        }
    });

    container.addEventListener('drop', (e) => {
        e.preventDefault();
        const draggedGroupKey = e.dataTransfer.getData('text/plain');
        const draggedElement = document.querySelector(`[data-group-key="${draggedGroupKey}"]`);

        if (draggedElement && draggedElement !== container) {
            const rect = container.getBoundingClientRect();
            const midY = rect.top + rect.height / 2;
            const parent = container.parentNode;

            if (e.clientY < midY) {
                // Einfügen vor dem aktuellen Element
                parent.insertBefore(draggedElement, container);
            } else {
                // Einfügen nach dem aktuellen Element
                parent.insertBefore(draggedElement, container.nextSibling);
            }

            // Speichere neue Gruppenreihenfolge
            saveGroupOrder();
        }

        // Cleanup
        container.classList.remove('group-drop-target-above', 'group-drop-target-below');
    });

    // Verhindere Toggle beim Drag-Handle
    dragHandle.addEventListener('click', (e) => {
        e.stopPropagation();
        e.preventDefault();
    });
}

// Speichere und lade Gruppenreihenfolge
function saveGroupOrder() {
    const overlayTab = document.querySelector('.overlay-tab');
    if (!overlayTab) return;

    const groupElements = overlayTab.querySelectorAll('.layer-group[data-group-key]');
    const order = Array.from(groupElements).map(el => el.dataset.groupKey);

    try {
        localStorage.setItem('wme-overlay-group-order', JSON.stringify(order));
    } catch (error) {
        console.error('Fehler beim Speichern der Gruppenreihenfolge:', error);
    }
}

function loadGroupOrder() {
    try {
        const saved = localStorage.getItem('wme-overlay-group-order');
        if (saved) {
            return JSON.parse(saved);
        }
    } catch (error) {
        console.error('Fehler beim Laden der Gruppenreihenfolge:', error);
    }
    // Standard-Reihenfolge
    return ['basic', 'cadastre', 'germany', 'austria', 'switzerland', 'unofficial'];
}
function createLayerControl(layerId, name, isGroup = false, groupKey = null) {
    const container = document.createElement('div');
    container.className = isGroup ? 'layer-group' : 'layer-control';

    if (isGroup) {
        const header = document.createElement('div');
        header.className = 'group-header';
        header.style.cursor = 'pointer';

        // Erstelle Toggle-Button mit Pfeil
        const toggleButton = document.createElement('span');
        toggleButton.className = 'toggle-button';
        // Standardmäßig eingeklappt, außer explizit als geöffnet gespeichert
        // Basis Layer und Karten Einstellungen sind standardmäßig geöffnet
        const shouldBeOpenByDefault = (
            groupKey === 'basic' ||
            groupKey === 'global-filters' ||
            (typeof name === 'string' && name.indexOf('Karten Einstellungen') !== -1)
        );
        const isCollapsed = shouldBeOpenByDefault ? (collapsedGroups[groupKey] === false) : (collapsedGroups[groupKey] !== true);
        toggleButton.innerHTML = isCollapsed ? '▶' : '▼';

        const titleSpan = document.createElement('span');
        titleSpan.className = 'group-title';
        titleSpan.textContent = name;

        header.appendChild(toggleButton);
        header.appendChild(titleSpan);

        // Erstelle Content-Container
        const content = document.createElement('div');
        content.className = 'group-content';
        content.style.display = isCollapsed ? 'none' : 'block';

        // Click-Handler für Toggle
        header.addEventListener('click', () => {
            const isCurrentlyCollapsed = content.style.display === 'none';
            content.style.display = isCurrentlyCollapsed ? 'block' : 'none';
            toggleButton.innerHTML = isCurrentlyCollapsed ? '▼' : '▶';

            // Speichere Zustand (true = geöffnet, false/undefined = geschlossen)
            collapsedGroups[groupKey] = isCurrentlyCollapsed;
            saveCollapsedState();
        });

        container.appendChild(header);
        container.appendChild(content);
        container.content = content; // Referenz für späteren Zugriff

        // Drag & Drop für Gruppen aktivieren
        makeGroupDraggable(container, groupKey);

        return container;
    }

    const layer = layers[layerId];
    if (!layer) return container;

    // Sichtbarkeits-Checkbox
    const checkbox = document.createElement('input');
    checkbox.type = 'checkbox';
    checkbox.checked = layer.getVisibility();
    checkbox.addEventListener('change', () => {
        layer.setVisibility(checkbox.checked);
        saveSettings(); // Speichern nach Änderung
    });

    const label = document.createElement('label');
    label.appendChild(checkbox);
    label.appendChild(document.createTextNode(name));

    // Transparenz-Slider - KORRIGIERT
    const opacityContainer = document.createElement('div');
    opacityContainer.className = 'slider-container';

    const opacityLabel = document.createElement('span');
    opacityLabel.textContent = 'Transparenz: ';

    const opacityValue = document.createElement('span');
    opacityValue.className = 'slider-value';
    opacityValue.textContent = Math.round((layer.opacity || DEFAULT_OPACITY) * 100) + '%';

    const opacitySlider = document.createElement('input');
    opacitySlider.type = 'range';
    opacitySlider.min = '0';
    opacitySlider.max = '100';
    opacitySlider.step = '1';
    opacitySlider.value = Math.round((layer.opacity || DEFAULT_OPACITY) * 100);

    opacitySlider.addEventListener('input', () => {
        const value = parseInt(opacitySlider.value) / 100;
        layer.setOpacity(value);
        layer.opacity = value; // KORRIGIERT: Speichere auch im Layer-Objekt
        opacityValue.textContent = opacitySlider.value + '%';
        saveSettings(); // Speichern nach Änderung
    });

    opacityContainer.appendChild(opacityLabel);
    opacityContainer.appendChild(opacitySlider);
    opacityContainer.appendChild(opacityValue);

    // Z-Index-Slider - KORRIGIERT
    const zIndexContainer = document.createElement('div');
    zIndexContainer.className = 'slider-container';

    const zIndexLabel = document.createElement('span');
    zIndexLabel.textContent = 'Ebene: ';

    const zIndexValue = document.createElement('span');
    zIndexValue.className = 'slider-value';

    // KORRIGIERT: Verwende Metadaten für aktuellen Z-Index-Wert
    const currentZIndex = layerMetadata[layerId]?.zIndex || layer.getZIndex() || DEFAULT_ZINDEX;
    zIndexValue.textContent = currentZIndex;

    const zIndexSlider = document.createElement('input');
    zIndexSlider.type = 'range';
    zIndexSlider.min = '1900';
    zIndexSlider.max = '2500';
    zIndexSlider.step = '5';
    zIndexSlider.value = currentZIndex; // KORRIGIERT: Verwende currentZIndex

    zIndexSlider.addEventListener('input', () => {
        const zIndex = parseInt(zIndexSlider.value);
        layer.setZIndex(zIndex);

        // KORRIGIERT: Speichere Z-Index in Metadaten
        if (!layerMetadata[layerId]) {
            layerMetadata[layerId] = {};
        }
        layerMetadata[layerId].zIndex = zIndex;

        zIndexValue.textContent = zIndex;
        saveSettings(); // Speichern nach Änderung
    });

    zIndexContainer.appendChild(zIndexLabel);
    zIndexContainer.appendChild(zIndexSlider);
    zIndexContainer.appendChild(zIndexValue);

    container.appendChild(label);
    container.appendChild(opacityContainer);
    container.appendChild(zIndexContainer);

    // Füge Legende- und Kartenstand-Buttons für Basemap.de hinzu
    if (layerId === 'basemap-de') {
        const legendContainer = document.createElement('div');
        legendContainer.className = 'legend-container';
        legendContainer.style.cssText = `
            margin-top: 6px;
            display: flex;
            gap: 3px;
        `;

        const legendButton = document.createElement('button');
        legendButton.textContent = '📋 Legende';
        legendButton.style.cssText = `
            background: linear-gradient(135deg, #4CAF50, #45a049);
            color: white;
            border: none;
            padding: 0px 6px;
            border-radius: 4px;
            font-size: 10px;
            line-height: 1;
            height: 20px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.2s ease;
            box-shadow: 0 1px 2px rgba(0,0,0,0.1);
            flex: 1;
        `;

        legendButton.addEventListener('mouseenter', () => {
            legendButton.style.background = 'linear-gradient(135deg, #45a049, #3d8b40)';
            legendButton.style.transform = 'translateY(-1px)';
            legendButton.style.boxShadow = '0 2px 3px rgba(0,0,0,0.15)';
        });

        legendButton.addEventListener('mouseleave', () => {
            legendButton.style.background = 'linear-gradient(135deg, #4CAF50, #45a049)';
            legendButton.style.transform = 'translateY(0)';
            legendButton.style.boxShadow = '0 1px 2px rgba(0,0,0,0.1)';
        });

        legendButton.addEventListener('click', () => {
            window.open('https://basemap.de/produkte-und-dienste/web-raster/legende-web-raster-farbe/', '_blank');
        });

        const kartenstadButton = document.createElement('button');
        kartenstadButton.textContent = '📅 Kartenstand';
        kartenstadButton.style.cssText = `
            background: linear-gradient(135deg, #2196F3, #1976D2);
            color: white;
            border: none;
            padding: 0px 6px;
            border-radius: 4px;
            font-size: 10px;
            line-height: 1;
            height: 20px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.2s ease;
            box-shadow: 0 1px 2px rgba(0,0,0,0.1);
            flex: 1;
        `;

        kartenstadButton.addEventListener('mouseenter', () => {
            kartenstadButton.style.background = 'linear-gradient(135deg, #1976D2, #1565C0)';
            kartenstadButton.style.transform = 'translateY(-1px)';
            kartenstadButton.style.boxShadow = '0 2px 3px rgba(0,0,0,0.15)';
        });

        kartenstadButton.addEventListener('mouseleave', () => {
            kartenstadButton.style.background = 'linear-gradient(135deg, #2196F3, #1976D2)';
            kartenstadButton.style.transform = 'translateY(0)';
            kartenstadButton.style.boxShadow = '0 1px 2px rgba(0,0,0,0.1)';
        });

        kartenstadButton.addEventListener('click', () => {
            window.open('https://basemap.de/data/produkte/web_raster/meta/bm_web_raster_datenaktualitaet.html', '_blank');
        });

        legendContainer.appendChild(legendButton);
        legendContainer.appendChild(kartenstadButton);
        container.appendChild(legendContainer);
    }

    // Füge Legende- und Kartenstand-Buttons für TopPlus WMS hinzu
    if (layerId === 'topplus') {
        const legendContainer = document.createElement('div');
        legendContainer.className = 'legend-container';
        legendContainer.style.cssText = `
            margin-top: 6px;
            display: flex;
            gap: 3px;
        `;

        const legendButton = document.createElement('button');
        legendButton.textContent = '📋 Legende';
        legendButton.style.cssText = `
            background: linear-gradient(135deg, #4CAF50, #45a049);
            color: white;
            border: none;
            padding: 0px 6px;
            border-radius: 4px;
            font-size: 10px;
            line-height: 1;
            height: 20px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.2s ease;
            box-shadow: 0 1px 2px rgba(0,0,0,0.1);
            flex: 1;
        `;

        legendButton.addEventListener('mouseenter', () => {
            legendButton.style.background = 'linear-gradient(135deg, #45a049, #3d8b40)';
            legendButton.style.transform = 'translateY(-1px)';
            legendButton.style.boxShadow = '0 2px 3px rgba(0,0,0,0.15)';
        });

        legendButton.addEventListener('mouseleave', () => {
            legendButton.style.background = 'linear-gradient(135deg, #4CAF50, #45a049)';
            legendButton.style.transform = 'translateY(0)';
            legendButton.style.boxShadow = '0 1px 2px rgba(0,0,0,0.1)';
        });

        legendButton.addEventListener('click', () => {
            window.open('https://sgx.geodatenzentrum.de/web_public/gdz/dokumentation/deu/topplusopen.pdf', '_blank');
        });

        const kartenstadButton = document.createElement('button');
        kartenstadButton.textContent = '📅 Kartenstand';
        kartenstadButton.style.cssText = `
            background: linear-gradient(135deg, #2196F3, #1976D2);
            color: white;
            border: none;
            padding: 0px 6px;
            border-radius: 4px;
            font-size: 10px;
            line-height: 1;
            height: 20px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.2s ease;
            box-shadow: 0 1px 2px rgba(0,0,0,0.1);
            flex: 1;
        `;

        kartenstadButton.addEventListener('mouseenter', () => {
            kartenstadButton.style.background = 'linear-gradient(135deg, #1976D2, #1565C0)';
            kartenstadButton.style.transform = 'translateY(-1px)';
            kartenstadButton.style.boxShadow = '0 2px 3px rgba(0,0,0,0.15)';
        });

        kartenstadButton.addEventListener('mouseleave', () => {
            kartenstadButton.style.background = 'linear-gradient(135deg, #2196F3, #1976D2)';
            kartenstadButton.style.transform = 'translateY(0)';
            kartenstadButton.style.boxShadow = '0 1px 2px rgba(0,0,0,0.1)';
        });

        kartenstadButton.addEventListener('click', () => {
            window.open('https://sgx.geodatenzentrum.de/web_public/gdz/datenquellen/datenquellen_topplusopen.pdf', '_blank');
        });

        legendContainer.appendChild(legendButton);
        legendContainer.appendChild(kartenstadButton);
        container.appendChild(legendContainer);
    }

    return container;
}

// Globale Filter-Einstellungen
let globalFilters = {
    brightness: 100,
    contrast: 100,
    saturation: 100,
    sharpness: 100
};

function createGlobalFilterControls() {
    const container = createLayerControl(null, '🎨 Karten Einstellungen', true, 'global-filters');
    const content = container.content;

    // Helligkeit-Slider
    const brightnessContainer = document.createElement('div');
    brightnessContainer.className = 'slider-container global-filter';

    const brightnessLabel = document.createElement('span');
    brightnessLabel.textContent = 'Helligkeit: ';

    const brightnessValue = document.createElement('span');
    brightnessValue.className = 'slider-value';
    brightnessValue.textContent = globalFilters.brightness + '%';

    const brightnessSlider = document.createElement('input');
    brightnessSlider.type = 'range';
    brightnessSlider.min = '0';
    brightnessSlider.max = '300';
    brightnessSlider.step = '1';
    brightnessSlider.value = globalFilters.brightness;

    brightnessSlider.addEventListener('input', () => {
        const value = parseInt(brightnessSlider.value);
        globalFilters.brightness = value;
        brightnessValue.textContent = value + '%';
        updateAllLayerFilters();
        saveGlobalFilters();
    });

    brightnessContainer.appendChild(brightnessLabel);
    brightnessContainer.appendChild(brightnessSlider);
    brightnessContainer.appendChild(brightnessValue);

    // Kontrast-Slider
    const contrastContainer = document.createElement('div');
    contrastContainer.className = 'slider-container global-filter';

    const contrastLabel = document.createElement('span');
    contrastLabel.textContent = 'Kontrast: ';

    const contrastValue = document.createElement('span');
    contrastValue.className = 'slider-value';
    contrastValue.textContent = globalFilters.contrast + '%';

    const contrastSlider = document.createElement('input');
    contrastSlider.type = 'range';
    contrastSlider.min = '0';
    contrastSlider.max = '300';
    contrastSlider.step = '1';
    contrastSlider.value = globalFilters.contrast;

    contrastSlider.addEventListener('input', () => {
        const value = parseInt(contrastSlider.value);
        globalFilters.contrast = value;
        contrastValue.textContent = value + '%';
        updateAllLayerFilters();
        saveGlobalFilters();
    });

    contrastContainer.appendChild(contrastLabel);
    contrastContainer.appendChild(contrastSlider);
    contrastContainer.appendChild(contrastValue);

    // Sättigung-Slider
    const saturationContainer = document.createElement('div');
    saturationContainer.className = 'slider-container global-filter';

    const saturationLabel = document.createElement('span');
    saturationLabel.textContent = 'Sättigung: ';

    const saturationValue = document.createElement('span');
    saturationValue.className = 'slider-value';
    saturationValue.textContent = globalFilters.saturation + '%';

    const saturationSlider = document.createElement('input');
    saturationSlider.type = 'range';
    saturationSlider.min = '0';
    saturationSlider.max = '300';
    saturationSlider.step = '1';
    saturationSlider.value = globalFilters.saturation;

    saturationSlider.addEventListener('input', () => {
        const value = parseInt(saturationSlider.value);
        globalFilters.saturation = value;
        saturationValue.textContent = value + '%';
        updateAllLayerFilters();
        saveGlobalFilters();
    });

    saturationContainer.appendChild(saturationLabel);
    saturationContainer.appendChild(saturationSlider);
    saturationContainer.appendChild(saturationValue);

    // Schärfe-Slider (mit funktionierender Implementierung)
    const sharpnessContainer = document.createElement('div');
    sharpnessContainer.className = 'slider-container global-filter';

    const sharpnessLabel = document.createElement('span');
    sharpnessLabel.textContent = 'Schärfe: ';

    const sharpnessValue = document.createElement('span');
    sharpnessValue.className = 'slider-value';
    sharpnessValue.textContent = globalFilters.sharpness + '%';

    const sharpnessSlider = document.createElement('input');
    sharpnessSlider.type = 'range';
    sharpnessSlider.min = '0';
    sharpnessSlider.max = '300';
    sharpnessSlider.step = '1';
    sharpnessSlider.value = globalFilters.sharpness;

    sharpnessSlider.addEventListener('input', () => {
        const value = parseInt(sharpnessSlider.value);
        globalFilters.sharpness = value;
        sharpnessValue.textContent = value + '%';
        updateAllLayerFilters();
        saveGlobalFilters();
    });

    sharpnessContainer.appendChild(sharpnessLabel);
    sharpnessContainer.appendChild(sharpnessSlider);
    sharpnessContainer.appendChild(sharpnessValue);

    content.appendChild(brightnessContainer);
    content.appendChild(contrastContainer);
    content.appendChild(saturationContainer);
    content.appendChild(sharpnessContainer);

    return container;
}

async function initializeScript() {
    try {
        // Registriere Script-Info
        W.userscripts[SCRIPT_ID] = {
            name: SCRIPT_NAME,
            author: 'Hiwi234',
            version: GM_info.script.version
        };

        // Lade gespeicherte Zustände
        loadCollapsedState();

        // Globaler Overlayschalter: Zustand laden und UI erstellen
        loadEnabledState();
        createGlobalToggleUI();

        // Patche OpenLayers für WMTS Support
        patchOpenLayers();

        // Warte länger für OpenLayers Patches und WMTS Komponenten
        await new Promise(resolve => setTimeout(resolve, 2000));

        // Erstelle alle Layer
        const wmtsPromises = [];

        Object.keys(layerGroups).forEach(groupKey => {
            const group = layerGroups[groupKey];
            group.layers.forEach(layerConfig => {
                if (layerConfig.type === 'wmts') {
                    wmtsPromises.push(createWMTSLayer(layerConfig));
                } else {
                    createBasicLayer(layerConfig);
                }
            });
        });

        // Warte auf alle WMTS Layer
        await Promise.allSettled(wmtsPromises);

        // Wende globalen Ein/Aus-Zustand auf alle Layer an
        setScriptEnabled(scriptEnabled, true);

        // Erstelle Sidebar Tab
        const { tabLabel, tabPane } = W.userscripts.registerSidebarTab(SCRIPT_ID);
        tabLabel.textContent = 'Multi Map 🗺️';
        tabLabel.title = 'Erweiterte Karten-Overlays';

        await W.userscripts.waitForElementConnected(tabPane);

        // Erstelle Content Container
        const content = document.createElement('div');
        content.className = 'overlay-tab';



        // Lade globale Filter-Einstellungen
        loadGlobalFilters();

        // Füge alle Gruppen in der gespeicherten Reihenfolge hinzu
        const savedGroupOrder = loadGroupOrder();
        savedGroupOrder.forEach(groupKey => {
            if (layerGroups[groupKey]) {
                const group = layerGroups[groupKey];
                const groupContainer = createLayerControl(null, group.name, true, groupKey);

                group.layers.forEach(layerConfig => {
                    if (layers[layerConfig.id]) {
                        groupContainer.content.appendChild(createLayerControl(layerConfig.id, layerConfig.name));
                    }
                });
                content.appendChild(groupContainer);
            }
        });

        // Füge globale Filter-Kontrollen am Ende hinzu
        content.appendChild(createGlobalFilterControls());

        tabPane.appendChild(content);

        // Füge Reset-Button hinzu
        const resetContainer = document.createElement('div');
        resetContainer.className = 'reset-container';

        const resetButton = document.createElement('button');
        resetButton.textContent = '🔄 Alles zurücksetzen';
        resetButton.className = 'reset-button';
        resetButton.addEventListener('click', () => {
            if (confirm('Alle Einstellungen zurücksetzen?')) {
                localStorage.removeItem(STORAGE_KEY);
                localStorage.removeItem('wme-overlay-global-filters');
                localStorage.removeItem(COLLAPSED_STATE_KEY);
                localStorage.removeItem('wme-overlay-group-order');
                location.reload();
            }
        });

        resetContainer.appendChild(resetButton);
        tabPane.appendChild(resetContainer);

        // Füge erweiterte Styles hinzu
        const style = document.createElement('style');
        style.textContent = `
            .overlay-tab {
                padding: 6px;
                max-height: 70vh;
                overflow-y: auto;
            }

            .master-toggle-container {
                background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
                border: 1px solid #dee2e6;
                border-radius: 6px;
                padding: 8px;
                margin-bottom: 10px;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }

            .master-toggle-label {
                display: flex;
                align-items: center;
                cursor: pointer;
                font-weight: 600;
                font-size: 14px;
                gap: 8px;
                user-select: none;
            }

            .master-toggle-checkbox {
                width: 18px;
                height: 18px;
                cursor: pointer;
                accent-color: #4CAF50;
            }

            .master-toggle-text {
                transition: color 0.3s ease;
                font-weight: 600;
            }

            .layer-group {
                margin-bottom: 8px;
                border: 1px solid #ddd;
                border-radius: 5px;
                overflow: hidden;
            }

            .group-header {
                background: #f5f5f5;
                padding: 6px 10px;
                font-weight: bold;
                border-bottom: 1px solid #ddd;
                display: flex;
                align-items: center;
                gap: 6px;
                transition: background-color 0.2s ease;
                position: relative;
            }

            .group-header:hover {
                background: #e8e8e8;
            }

            .group-drag-handle {
                position: absolute;
                right: 8px;
                top: 50%;
                transform: translateY(-50%);
                cursor: grab;
                color: #999;
                font-size: 13px;
                user-select: none;
                padding: 3px 5px;
                border-radius: 3px;
                transition: all 0.2s ease;
                background: rgba(255,255,255,0.8);
                border: 1px solid #ddd;
            }

            .group-drag-handle:hover {
                background: rgba(0,0,0,0.1);
                color: #666;
                border-color: #999;
            }

            .toggle-button {
                font-size: 11px;
                color: #666;
                transition: transform 0.2s ease;
                display: inline-block;
                width: 14px;
                text-align: center;
            }

            .group-title {
                font-size: 13px;
                flex: 1;
            }

            .group-content {
                transition: all 0.3s ease;
                overflow: hidden;
            }

            .layer-control {
                margin: 0;
                padding: 8px;
                border-bottom: 1px solid #eee;
            }

            .layer-control:last-child {
                border-bottom: none;
            }

            .layer-control label {
                display: block;
                margin-bottom: 4px;
                font-weight: 500;
                cursor: pointer;
            }

            .layer-control input[type="checkbox"] {
                margin-right: 6px;
            }

            .slider-container {
                margin: 4px 0;
                display: flex;
                align-items: center;
            }

            .global-filter {
                padding: 6px 10px;
                border-bottom: 1px solid #eee;
            }

            .global-filter:last-child {
                border-bottom: none;
            }

            /* Fette Schrift für Karten Einstellungen */
            .layer-group[data-group-key="global-filters"] .group-title {
                font-weight: 700;
            }
            .global-filter span {
                font-weight: 700;
            }

            .slider-container span {
                display: inline-block;
                width: 78px;
                font-size: 11px;
                color: #666;
            }

            .slider-container input[type="range"] {
                flex: 1;
                margin: 0 6px;
            }

            .slider-value {
                width: 40px !important;
                text-align: right;
                font-weight: 500;
                color: #333 !important;
            }

            .reset-container {
                margin-top: 10px;
                padding: 10px;
                border-top: 1px solid #ddd;
                text-align: center;
            }

            .reset-button {
                background: #f44336;
                color: white;
                border: none;
                padding: 6px 12px;
                border-radius: 4px;
                cursor: pointer;
                font-size: 11px;
                transition: background 0.2s;
            }

            .reset-button:hover {
                background: #d32f2f;
            }

            /* Drag & Drop Styles für Gruppen */

            .layer-group[draggable="true"] {
                transition: all 0.2s ease;
            }

            .layer-group.group-dragging {
                opacity: 0.6;
                transform: rotate(1deg);
                box-shadow: 0 8px 25px rgba(0,0,0,0.3);
                z-index: 1000;
                border: 2px dashed #666;
            }

            .layer-group.group-drop-target-above {
                border-top: 4px solid #4CAF50;
                margin-top: 4px;
            }

            .layer-group.group-drop-target-below {
                border-bottom: 4px solid #4CAF50;
                margin-bottom: 4px;
            }

            .group-drag-handle[draggable="true"]:active {
                cursor: grabbing;
            }
        `;
        document.head.appendChild(style);

        // Zeige Update-Benachrichtigung
        showUpdateNotification();

        // Initiale Anwendung der globalen Filter
        setTimeout(() => {
            updateAllLayerFilters();
        }, 2000);

    } catch (error) {
        console.error(SCRIPT_NAME + ': Fehler bei der Initialisierung:', error);
    }
}

// Starte Initialisierung wenn WME bereit ist
if (W?.userscripts?.state.isReady) {
    initializeScript();
} else {
    document.addEventListener('wme-ready', initializeScript, { once: true });
}

})();