{"id":850,"date":"2026-05-18T09:30:28","date_gmt":"2026-05-18T09:30:28","guid":{"rendered":"https:\/\/ecolymp.eu\/?page_id=850"},"modified":"2026-07-22T03:55:26","modified_gmt":"2026-07-22T03:55:26","slug":"product-manuals","status":"publish","type":"page","link":"https:\/\/ecolymp.eu\/sl\/product-manuals\/","title":{"rendered":"Product Manuals"},"content":{"rendered":"    <div id=\"m8-ecolymp-manuals-584268\" class=\"m8-eml\" data-json=\"https:\/\/ecolymp.eu\/wp-content\/plugins\/m8-ecolymp-manual-library\/manuals.json\">\n        <div class=\"m8-eml-head\">\n            <div>\n                <h2>Product Manuals<\/h2>\n                <p>Official manuals and technical documents from our manufacturing partners.<\/p>\n            <\/div>\n            <div class=\"m8-eml-count\" aria-live=\"polite\">Loading\u2026<\/div>\n        <\/div>\n\n        <div class=\"m8-eml-toolbar\">\n            <label class=\"m8-eml-search-wrap\">\n                <span class=\"screen-reader-text\">Search manuals<\/span>\n                <input type=\"search\" class=\"m8-eml-search\" placeholder=\"Search by brand, model or manual\">\n            <\/label>\n            <button type=\"button\" class=\"m8-eml-clear\" hidden>Clear<\/button>\n        <\/div>\n\n        <div class=\"m8-eml-brands\" role=\"group\" aria-label=\"Filter manuals by brand\"><\/div>\n        <div class=\"m8-eml-results\"><\/div>\n        <div class=\"m8-eml-empty\" hidden>No matching manuals found.<\/div>\n    <\/div>\n\n    <style>\n        #m8-ecolymp-manuals-584268 {\n            --m8-border:#dce5e7;\n            --m8-text:#102f38;\n            --m8-muted:#64777d;\n            --m8-soft:#f5f8f8;\n            --m8-accent:#078b7c;\n            --m8-accent-dark:#057267;\n            color:var(--m8-text);\n            font-family:inherit;\n        }\n        #m8-ecolymp-manuals-584268 * { box-sizing:border-box; }\n        #m8-ecolymp-manuals-584268 .m8-eml-head {\n            display:flex;\n            justify-content:space-between;\n            align-items:flex-end;\n            gap:18px;\n            margin:0 0 20px;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-head h2 {\n            margin:0 0 6px;\n            font-size:clamp(28px,4vw,42px);\n            line-height:1.08;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-head p {\n            margin:0;\n            color:var(--m8-muted);\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-count {\n            color:var(--m8-muted);\n            font-size:14px;\n            white-space:nowrap;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-toolbar {\n            display:flex;\n            gap:10px;\n            margin-bottom:12px;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-search-wrap {\n            flex:1;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-search {\n            width:100%;\n            min-height:48px;\n            padding:11px 15px;\n            border:1px solid #cbd7da;\n            border-radius:10px;\n            background:#fff;\n            color:var(--m8-text);\n            font:inherit;\n            outline:none;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-search:focus {\n            border-color:var(--m8-accent);\n            box-shadow:0 0 0 3px rgba(7,139,124,.12);\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-clear {\n            min-width:76px;\n            border:1px solid var(--m8-border);\n            border-radius:10px;\n            background:#fff;\n            color:var(--m8-text);\n            padding:0 16px;\n            font:inherit;\n            font-weight:700;\n            cursor:pointer;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-brands {\n            display:flex;\n            flex-wrap:wrap;\n            gap:8px;\n            padding:12px;\n            margin-bottom:20px;\n            border:1px solid var(--m8-border);\n            border-radius:12px;\n            background:var(--m8-soft);\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-brand-btn {\n            min-height:38px;\n            padding:7px 14px;\n            border:1px solid transparent;\n            border-radius:999px;\n            background:#fff;\n            color:var(--m8-text);\n            font:inherit;\n            font-size:14px;\n            font-weight:700;\n            cursor:pointer;\n            transition:.15s ease;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-brand-btn:hover {\n            border-color:#aabdc1;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-brand-btn.is-active {\n            background:var(--m8-accent);\n            color:#fff;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-results {\n            display:grid;\n            gap:24px;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-brand-section {\n            min-width:0;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-brand-head {\n            display:flex;\n            align-items:center;\n            justify-content:space-between;\n            gap:12px;\n            padding-bottom:10px;\n            margin-bottom:12px;\n            border-bottom:2px solid var(--m8-text);\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-brand-title {\n            margin:0;\n            font-size:22px;\n            line-height:1.2;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-brand-meta {\n            color:var(--m8-muted);\n            font-size:13px;\n            white-space:nowrap;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-model-grid {\n            display:grid;\n            grid-template-columns:repeat(2,minmax(0,1fr));\n            gap:12px;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-model-card {\n            min-width:0;\n            padding:16px;\n            border:1px solid var(--m8-border);\n            border-radius:12px;\n            background:#fff;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-model-top {\n            display:flex;\n            align-items:center;\n            justify-content:space-between;\n            gap:10px;\n            margin-bottom:12px;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-model-title {\n            margin:0;\n            font-size:18px;\n            line-height:1.25;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-category {\n            display:inline-flex;\n            padding:4px 8px;\n            border-radius:999px;\n            background:var(--m8-soft);\n            color:var(--m8-muted);\n            font-size:11px;\n            white-space:nowrap;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-doc-group + .m8-eml-doc-group {\n            margin-top:11px;\n            padding-top:11px;\n            border-top:1px solid #edf1f2;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-doc-name {\n            margin-bottom:7px;\n            color:var(--m8-muted);\n            font-size:13px;\n            font-weight:700;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-language-list {\n            display:flex;\n            flex-wrap:wrap;\n            gap:7px;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-language {\n            display:inline-flex;\n            align-items:center;\n            justify-content:center;\n            min-width:43px;\n            min-height:34px;\n            padding:6px 9px;\n            border-radius:8px;\n            background:#eaf5f3;\n            color:var(--m8-accent-dark) !important;\n            text-decoration:none !important;\n            font-size:12px;\n            font-weight:800;\n            line-height:1;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-language:hover {\n            background:var(--m8-accent);\n            color:#fff !important;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-language::after {\n            content:'\u2193';\n            margin-left:4px;\n            font-size:11px;\n        }\n        #m8-ecolymp-manuals-584268 .m8-eml-empty {\n            padding:36px;\n            border:1px dashed var(--m8-border);\n            border-radius:12px;\n            color:var(--m8-muted);\n            text-align:center;\n        }\n        @media (max-width:760px) {\n            #m8-ecolymp-manuals-584268 .m8-eml-head {\n                align-items:flex-start;\n                flex-direction:column;\n            }\n            #m8-ecolymp-manuals-584268 .m8-eml-model-grid {\n                grid-template-columns:1fr;\n            }\n        }\n        @media (max-width:480px) {\n            #m8-ecolymp-manuals-584268 .m8-eml-toolbar {\n                align-items:stretch;\n            }\n            #m8-ecolymp-manuals-584268 .m8-eml-clear {\n                min-width:64px;\n                padding:0 10px;\n            }\n            #m8-ecolymp-manuals-584268 .m8-eml-brands {\n                flex-wrap:nowrap;\n                overflow-x:auto;\n                -webkit-overflow-scrolling:touch;\n            }\n            #m8-ecolymp-manuals-584268 .m8-eml-brand-btn {\n                flex:0 0 auto;\n            }\n            #m8-ecolymp-manuals-584268 .m8-eml-model-card {\n                padding:14px;\n            }\n        }\n    <\/style>\n\n    <script>\n    (() => {\n        const root = document.getElementById(\"m8-ecolymp-manuals-584268\");\n        if (!root) return;\n\n        const search = root.querySelector('.m8-eml-search');\n        const clearButton = root.querySelector('.m8-eml-clear');\n        const brandBar = root.querySelector('.m8-eml-brands');\n        const results = root.querySelector('.m8-eml-results');\n        const empty = root.querySelector('.m8-eml-empty');\n        const count = root.querySelector('.m8-eml-count');\n\n        let all = [];\n        let selectedBrand = '';\n\n        const esc = value => String(value ?? '').replace(\/[&<>\"']\/g, ch => ({\n            '&':'&amp;', '<':'&lt;', '>':'&gt;', '\"':'&quot;', \"'\":'&#039;'\n        }[ch]));\n\n        const natural = (a, b) => String(a).localeCompare(String(b), undefined, {\n            numeric:true,\n            sensitivity:'base'\n        });\n\n        const languageCode = language => {\n            const codes = {\n                'English':'EN', 'English (New)':'EN', 'German':'DE', 'French':'FR',\n                'Italian':'IT', 'Spanish':'ES', 'Polish':'PL', 'Dutch':'NL',\n                'Portuguese':'PT', 'Multiple':'MULTI'\n            };\n            return codes[language] || String(language).slice(0, 3).toUpperCase();\n        };\n\n        const itemUrl = item => item.manual_url || item.pdf_url || '';\n\n        function prepareRows(data) {\n            const seen = new Set();\n            return data.filter(item => {\n                const url = itemUrl(item);\n                if (item.status !== 'verified_direct' || !url) return false;\n                const key = [item.brand, item.model, item.document_type, item.language, url].join('|');\n                if (seen.has(key)) return false;\n                seen.add(key);\n                return true;\n            });\n        }\n\n        function renderBrandButtons() {\n            const brands = [...new Set(all.map(item => item.brand))].sort(natural);\n            const buttons = [''].concat(brands).map(brand => {\n                const label = brand || 'All brands';\n                const active = selectedBrand === brand ? ' is-active' : '';\n                return '<button type=\"button\" class=\"m8-eml-brand-btn' + active + '\" data-brand=\"' + esc(brand) + '\">' + esc(label) + '<\/button>';\n            });\n            brandBar.innerHTML = buttons.join('');\n        }\n\n        function currentRows() {\n            const query = search.value.trim().toLowerCase();\n            return all.filter(item => {\n                if (selectedBrand && item.brand !== selectedBrand) return false;\n                if (!query) return true;\n                const aliases = Array.isArray(item.aliases) ? item.aliases.join(' ') : '';\n                const haystack = [item.brand, item.model, aliases, item.category, item.document_type, item.language]\n                    .join(' ')\n                    .toLowerCase();\n                return haystack.includes(query);\n            });\n        }\n\n        function groupRows(rows) {\n            const grouped = {};\n            rows.forEach(item => {\n                grouped[item.brand] ??= {};\n                grouped[item.brand][item.model] ??= {\n                    category:item.category || '',\n                    documents:{}\n                };\n                grouped[item.brand][item.model].documents[item.document_type] ??= [];\n                grouped[item.brand][item.model].documents[item.document_type].push(item);\n            });\n            return grouped;\n        }\n\n        function render() {\n            renderBrandButtons();\n            const rows = currentRows();\n            const grouped = groupRows(rows);\n            const modelCount = new Set(rows.map(item => item.brand + '|' + item.model)).size;\n            count.textContent = modelCount + ' model' + (modelCount === 1 ? '' : 's') + ' \u00b7 ' + rows.length + ' document' + (rows.length === 1 ? '' : 's');\n            clearButton.hidden = !selectedBrand && !search.value.trim();\n            empty.hidden = rows.length > 0;\n\n            if (!rows.length) {\n                results.innerHTML = '';\n                return;\n            }\n\n            results.innerHTML = Object.keys(grouped).sort(natural).map(brand => {\n                const models = grouped[brand];\n                const brandRows = rows.filter(item => item.brand === brand);\n                const modelCards = Object.keys(models).sort((a, b) => {\n                    if (a === 'All models') return -1;\n                    if (b === 'All models') return 1;\n                    return natural(a, b);\n                }).map(model => {\n                    const modelData = models[model];\n                    const docGroups = Object.keys(modelData.documents).sort(natural).map(documentType => {\n                        const links = modelData.documents[documentType]\n                            .sort((a, b) => natural(a.language, b.language))\n                            .map(item => {\n                                const label = documentType === 'CE Certificate'\n                                    ? 'PDF'\n                                    : languageCode(item.language);\n                                const url = itemUrl(item);\n                                const verb = item.access_type === 'direct_download' ? 'Download' : 'Open';\n                                return '<a class=\"m8-eml-language\" href=\"' + esc(url) + '\" target=\"_blank\" rel=\"noopener\" title=\"' + verb + ' ' + esc(item.language) + ' ' + esc(documentType) + '\">' + esc(label) + '<\/a>';\n                            })\n                            .join('');\n                        return '<div class=\"m8-eml-doc-group\"><div class=\"m8-eml-doc-name\">' + esc(documentType) + '<\/div><div class=\"m8-eml-language-list\">' + links + '<\/div><\/div>';\n                    }).join('');\n\n                    const displayModel = model === 'All models' ? 'General documents' : model;\n                    return '<article class=\"m8-eml-model-card\">' +\n                        '<div class=\"m8-eml-model-top\"><h4 class=\"m8-eml-model-title\">' + esc(displayModel) + '<\/h4>' +\n                        (modelData.category ? '<span class=\"m8-eml-category\">' + esc(modelData.category) + '<\/span>' : '') +\n                        '<\/div>' + docGroups + '<\/article>';\n                }).join('');\n\n                const brandModelCount = new Set(brandRows.map(item => item.model)).size;\n                return '<section class=\"m8-eml-brand-section\">' +\n                    '<div class=\"m8-eml-brand-head\"><h3 class=\"m8-eml-brand-title\">' + esc(brand) + '<\/h3>' +\n                    '<span class=\"m8-eml-brand-meta\">' + brandModelCount + ' models \u00b7 ' + brandRows.length + ' files<\/span><\/div>' +\n                    '<div class=\"m8-eml-model-grid\">' + modelCards + '<\/div><\/section>';\n            }).join('');\n        }\n\n        brandBar.addEventListener('click', event => {\n            const button = event.target.closest('.m8-eml-brand-btn');\n            if (!button) return;\n            selectedBrand = button.dataset.brand || '';\n            render();\n        });\n\n        search.addEventListener('input', render);\n        clearButton.addEventListener('click', () => {\n            search.value = '';\n            selectedBrand = '';\n            render();\n            search.focus();\n        });\n\n        fetch(root.dataset.json, {credentials:'same-origin'})\n            .then(response => {\n                if (!response.ok) throw new Error('HTTP ' + response.status);\n                return response.json();\n            })\n            .then(data => {\n                all = prepareRows(Array.isArray(data) ? data : []);\n                render();\n            })\n            .catch(error => {\n                count.textContent = 'Load failed';\n                empty.hidden = false;\n                empty.textContent = 'Manual data could not be loaded: ' + error.message;\n            });\n    })();\n    <\/script>\n    \n","protected":false},"excerpt":{"rendered":"","protected":false},"author":12,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"inline_featured_image":false,"footnotes":""},"class_list":["post-850","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ecolymp.eu\/sl\/wp-json\/wp\/v2\/pages\/850","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ecolymp.eu\/sl\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ecolymp.eu\/sl\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ecolymp.eu\/sl\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/ecolymp.eu\/sl\/wp-json\/wp\/v2\/comments?post=850"}],"version-history":[{"count":4,"href":"https:\/\/ecolymp.eu\/sl\/wp-json\/wp\/v2\/pages\/850\/revisions"}],"predecessor-version":[{"id":2870,"href":"https:\/\/ecolymp.eu\/sl\/wp-json\/wp\/v2\/pages\/850\/revisions\/2870"}],"wp:attachment":[{"href":"https:\/\/ecolymp.eu\/sl\/wp-json\/wp\/v2\/media?parent=850"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}