{
  "version": 3,
  "sources": ["/cdn/shop/t/12/assets/marathon-configurator.js?cb=56243839"],
  "sourcesContent": ["/* ============================================================\n   AP10 Marathon-Konfigurator\n   - GPX-Upload oder Preset-Auswahl\n   - Live-Karte (MapLibre GL + MapTiler) mit exakt skalierter Strecke\n   - Poster-PDF (Canvas \u2192 Mini-PDF) + STL (H\u00F6henprofil-Band) im Browser\n   - Upload zu Supabase, Line-Item-Properties wie beim Perso-Flow\n   ============================================================ */\n(function () {\n  if (customElements.get('marathon-configurator')) return;\n\n  const PDF_DPI = 300;\n  const PX_PER_MM = PDF_DPI / 25.4; // 11.811\n\n  /* Postergr\u00F6\u00DFen (mm, DIN) + maximale Strecken-Seitenl\u00E4nge (mm) */\n  const SIZES = {\n    A4: { wMm: 210, hMm: 297, trackMm: 170 },\n    A3: { wMm: 297, hMm: 420, trackMm: 210 }\n  };\n\n  /* STL-Parameter */\n  const STL = {\n    widthMm: 5,     // Bandbreite der Strecke\n    maxHMm: 10,     // maximale Gesamth\u00F6he (h\u00F6chster Punkt)\n    minHMm: 1,      // Mindestdicke am niedrigsten Punkt (Druckbarkeit)\n    flatHMm: 5,     // H\u00F6he, falls GPX keine H\u00F6hendaten enth\u00E4lt\n    maxPoints: 1500 // Punkte nach Vereinfachung\n  };\n\n  /* Poster-Layout (Anteile der Posterbreite/-h\u00F6he) \u2014 nach Beispiel-Layout */\n  const L = {\n    mapX0: 0.06, mapX1: 0.94, mapY0: 0.045, mapY1: 0.78,\n    trackColor: '#000000',\n    trackPrintMm: 2.5,           // gedruckte Linienbreite (mm), per Block-Setting \u00FCberschreibbar\n    markerColor: '#ffffff',\n    textDark: '#12121C',\n    textMuted: '#6b7c93',\n    dateY: 0.818, dateSize: 0.020,\n    event1Y: 0.872, event1Size: 0.075,\n    event2Y: 0.916, event2Size: 0.052,\n    numY: 0.808, numSize: 0.018,\n    nameY: 0.845, nameSize: 0.030,\n    paceY: 0.895, paceSize: 0.018,\n    timeY: 0.935, timeSize: 0.048\n  };\n\n  const TEXT_FONT = '\"Poppins\", sans-serif';\n  const MONO_FONT = '\"Roboto Mono\", monospace';\n\n  /* ---------------- Poster-Designs ----------------\n     Auswahl \u00FCber Produkt-Metafeld custom.poster_design.\n     'klassisch' = Karten-Layout (Code unten), SVG-Designs rendern einen\n     statischen SVG-Hintergrund + dynamische Texte + Strecke.\n     Positionen/Gr\u00F6\u00DFen als Anteile der Posterbreite (x, size) bzw. -h\u00F6he (y),\n     vermessen aus der Design-Vorlage. */\n  const DESIGNS = {\n    klassisch: {\n      hasMap: true,\n      upperName: true,\n      dateShort: false,\n      fields: {\n        event: { label: 'Event-Name', ph: 'Berlin Marathon' },\n        datum: { label: 'Datum', ph: '29. September 2024' },\n        nummer: { label: 'Startnummer', ph: '27623' },\n        name: { label: 'Name', ph: 'VORNAME NACHNAME' },\n        pace: { label: '\u00D8 Pace / km', ph: '05:19' },\n        zeit: { label: 'Gesamtzeit', ph: '3:43:48' }\n      }\n    },\n    editorial: {\n      hasMap: false,\n      asset: 'editorial',\n      bg: '#fff3ec',\n      font: MONO_FONT,\n      upperName: false,\n      dateShort: true,\n      track: { cx: 0.5, cy: 0.4375, markers: false },\n      texts: [\n        { src: 'bezeichnung', x: 0.3010, y: 0.04381, size: 0.01679, ls: 0.19, weight: 500, upper: true, maxW: 0.62 },\n        { src: 'event1', x: 0.3034, y: 0.09415, size: 0.0628, ls: 0, weight: 700, upper: true, maxW: 0.62 },\n        { src: 'event2', x: 0.3010, y: 0.11671, size: 0.02008, ls: 0.2, weight: 500, upper: true, maxW: 0.62 },\n        { src: 'nummer', x: 0.1166, y: 0.11576, size: 0.1219, ls: 0.04, weight: 500, align: 'center', color: '#fff3ec', maxW: 0.176 },\n        { src: 'coord1', x: 0.067, y: 0.24862, size: 0.01689, ls: 0.14, weight: 400 },\n        { src: 'coord2', x: 0.067, y: 0.26228, size: 0.01689, ls: 0.14, weight: 400 },\n        { src: 'datum', x: 0.11285, y: 0.7816, size: 0.01594, ls: 0.15, weight: 400 },\n        { src: 'distance', x: 0.3364, y: 0.7816, size: 0.01594, ls: 0.15, weight: 400 },\n        { src: 'zeit', x: 0.5513, y: 0.7816, size: 0.01594, ls: 0.15, weight: 400 },\n        { src: 'name', x: 0.7504, y: 0.7816, size: 0.01594, ls: 0.15, weight: 400 }\n      ],\n      fields: {\n        bezeichnung: { label: 'Eventbezeichnung', ph: 'BMW Berlin - 2026', sample: 'BMW Berlin - 2026' },\n        event: { label: 'Event-Name', ph: 'Berlin Marathon', sample: 'Berlin Marathon' },\n        datum: { label: 'Datum', ph: '23.07.2026', sample: '23.07.2026' },\n        nummer: { label: 'Nummer', ph: '10', sample: '10' },\n        name: { label: 'Name', ph: 'Vorname Nachname', sample: 'Dein Name' },\n        zeit: { label: 'Gesamtzeit', ph: '03:15:03', sample: '03:15:03' }\n      }\n    },\n    mono: {\n      hasMap: true,\n      mapFull: true,\n      asset: 'mono',\n      font: MONO_FONT,\n      upperName: false,\n      dateShort: true,\n      // Mono: Kundenstile aus dem Block-Setting, Light als Standard\n      defaultStyle: '019f931b-9046-7381-8c06-e9d772a300b3',\n      // Wei\u00DF-Verl\u00E4ufe: [Ausfaden-Ende, ~volldeckend] als H\u00F6henanteil\n      fadeTop: [0.115, 0.2],\n      fadeBottom: [0.775, 0.835],\n      track: { cx: 0.5, cy: 0.5, markers: false },\n      texts: [\n        { src: 'datum', x: 0.11285, y: 0.08394, size: 0.01594, ls: 0.15, weight: 400 },\n        { src: 'distance', x: 0.33637, y: 0.08394, size: 0.01594, ls: 0.15, weight: 400 },\n        { src: 'zeit', x: 0.55131, y: 0.08394, size: 0.01594, ls: 0.15, weight: 400 },\n        { src: 'name', x: 0.75046, y: 0.08394, size: 0.01594, ls: 0.15, weight: 400 },\n        { src: 'coord1', x: 0.93199, y: 0.68365, size: 0.01679, ls: 0.14, weight: 400, align: 'right' },\n        { src: 'coord2', x: 0.93199, y: 0.69707, size: 0.01679, ls: 0.14, weight: 400, align: 'right' },\n        { src: 'bezeichnung', x: 0.06834, y: 0.84903, size: 0.02127, ls: 0.16, weight: 500, upper: true, maxW: 0.55 },\n        { src: 'event1', x: 0.06683, y: 0.91125, size: 0.07772, ls: 0, weight: 700, upper: true, maxW: 0.62 },\n        { src: 'event2', x: 0.06834, y: 0.93939, size: 0.02551, ls: 0.14, weight: 500, upper: true, maxW: 0.62 }\n      ],\n      fields: {\n        bezeichnung: { label: 'Eventbezeichnung', ph: 'BMW Berlin - 2026', sample: 'BMW Berlin - 2026' },\n        event: { label: 'Event-Name', ph: 'Berlin Marathon', sample: 'Berlin Marathon' },\n        datum: { label: 'Datum', ph: '23.07.2026', sample: '23.07.2026' },\n        name: { label: 'Name', ph: 'Vorname Nachname', sample: 'Dein Name' },\n        zeit: { label: 'Gesamtzeit', ph: '03:15:03', sample: '03:15:03' }\n      }\n    }\n  };\n\n  /* Text mit Buchstabenabstand zeichnen, optional zentriert + auto-verkleinert */\n  function drawTextLS(ctx, text, xPx, yPx, sizePx, lsEm, weight, font, color, align, maxWPx) {\n    if (!text) return;\n    let size = sizePx;\n    const widthAt = (s) => {\n      ctx.font = weight + ' ' + s + 'px ' + font;\n      let w = 0;\n      for (const ch of text) w += ctx.measureText(ch).width + lsEm * s;\n      return w - (text.length ? lsEm * size : 0);\n    };\n    let w = widthAt(size);\n    if (maxWPx && w > maxWPx) {\n      size = size * (maxWPx / w);\n      w = widthAt(size);\n    }\n    let x = xPx;\n    if (align === 'center') {\n      x = xPx - w / 2;\n    } else if (align === 'right') {\n      x = xPx - w;\n    } else {\n      // Tinten-Ausrichtung: linke Druckkante exakt auf xPx (Vorabstand kompensieren)\n      const m0 = ctx.measureText(text[0]);\n      if (typeof m0.actualBoundingBoxLeft === 'number') x = xPx + m0.actualBoundingBoxLeft;\n    }\n    ctx.fillStyle = color || '#000000';\n    ctx.textAlign = 'left';\n    ctx.textBaseline = 'alphabetic';\n    for (const ch of text) {\n      ctx.fillText(ch, x, yPx);\n      x += ctx.measureText(ch).width + lsEm * size;\n    }\n  }\n\n  /* Dezimalgrad \u2192 52\u00B031'N */\n  function fmtCoord(deg, isLat) {\n    const hemi = isLat ? (deg >= 0 ? 'N' : 'S') : (deg >= 0 ? 'E' : 'W');\n    const a = Math.abs(deg);\n    const d = Math.floor(a);\n    let m = Math.round((a - d) * 60);\n    if (m === 60) m = 0;\n    return d + '\u00B0' + String(m).padStart(2, '0') + \"'\" + hemi;\n  }\n  const MAPLIBRE_JS = 'https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js';\n  const MAPLIBRE_CSS = 'https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css';\n\n  /* Eigene Stile: MapTiler-Basisstil wird clientseitig monochrom umgef\u00E4rbt.\n     Schl\u00FCssel = Stil-ID im Block-Setting, z. B. \"ap10-blau|Klassisch\" */\n  const PSEUDO_STYLES = {\n    'ap10-blau': {\n      base: 'streets-v2',\n      bg: '#b7cdec',    // Fl\u00E4che\n      land: '#96b7e4',  // Parks, Gr\u00FCnfl\u00E4chen, Flugh\u00E4fen\n      water: '#8fb2e2', // Wasser\n      line: '#6890cc'   // Stra\u00DFen\n    }\n  };\n\n  function recolorStyle(style, P) {\n    (style.layers || []).forEach((ly) => {\n      const id = (ly.id || '') + ' ' + (ly['source-layer'] || '');\n      if (ly.type === 'symbol' || ly.type === 'fill-extrusion' || ly.type === 'raster' || ly.type === 'hillshade') {\n        ly.layout = ly.layout || {};\n        ly.layout.visibility = 'none';\n        return;\n      }\n      if (ly.type === 'background') {\n        ly.paint = { 'background-color': P.bg };\n        return;\n      }\n      const isWater = /water|river|ocean|waterway/i.test(id);\n      const isLand = /park|landcover|landuse|grass|wood|forest|cemetery|golf|pitch|garden|sand|aeroway/i.test(id);\n      const isBuilding = /building/i.test(id);\n      if (ly.type === 'fill') {\n        let c = P.bg;\n        if (isWater) c = P.water;\n        else if (isLand) c = P.land;\n        else if (isBuilding) c = P.bg;\n        ly.paint = ly.paint || {};\n        ly.paint['fill-color'] = c;\n        ly.paint['fill-outline-color'] = c;\n        delete ly.paint['fill-pattern'];\n      } else if (ly.type === 'line') {\n        if (/casing|boundary|admin|disputed/i.test(id)) {\n          ly.layout = ly.layout || {};\n          ly.layout.visibility = 'none';\n          return;\n        }\n        ly.paint = ly.paint || {};\n        ly.paint['line-color'] = isWater ? P.water : P.line;\n        delete ly.paint['line-pattern'];\n      }\n    });\n    return style;\n  }\n\n  /* Kachel-Vorschau f\u00FCr Eigen-Stile (kleines stilisiertes Kartenmotiv) */\n  function pseudoThumb(P) {\n    const c = document.createElement('canvas');\n    c.width = 96;\n    c.height = 96;\n    const x = c.getContext('2d');\n    x.fillStyle = P.bg;\n    x.fillRect(0, 0, 96, 96);\n    x.fillStyle = P.land;\n    x.beginPath();\n    x.arc(72, 24, 22, 0, Math.PI * 2);\n    x.fill();\n    x.fillStyle = P.water;\n    x.beginPath();\n    x.ellipse(22, 76, 20, 13, 0.5, 0, Math.PI * 2);\n    x.fill();\n    x.strokeStyle = P.line;\n    x.lineCap = 'round';\n    x.lineWidth = 3.5;\n    x.beginPath();\n    x.moveTo(-5, 32);\n    x.bezierCurveTo(30, 22, 60, 48, 101, 40);\n    x.stroke();\n    x.lineWidth = 2;\n    x.beginPath();\n    x.moveTo(22, -5);\n    x.bezierCurveTo(38, 40, 22, 68, 42, 101);\n    x.stroke();\n    x.beginPath();\n    x.moveTo(-5, 62);\n    x.lineTo(101, 80);\n    x.stroke();\n    return c.toDataURL();\n  }\n\n  /* ---------------- Utilities ---------------- */\n  function loadMapLibre() {\n    if (window.maplibregl) return Promise.resolve();\n    if (window.__mcMapLibreP) return window.__mcMapLibreP;\n    window.__mcMapLibreP = new Promise((resolve, reject) => {\n      const link = document.createElement('link');\n      link.rel = 'stylesheet';\n      link.href = MAPLIBRE_CSS;\n      document.head.appendChild(link);\n      const s = document.createElement('script');\n      s.src = MAPLIBRE_JS;\n      s.onload = () => resolve();\n      s.onerror = () => reject(new Error('Karten-Bibliothek konnte nicht geladen werden.'));\n      document.head.appendChild(s);\n    });\n    return window.__mcMapLibreP;\n  }\n\n  /* GPX \u2192 Punkte {lat, lon, ele, time} */\n  function parseGpx(xmlText) {\n    const doc = new DOMParser().parseFromString(xmlText, 'application/xml');\n    if (doc.querySelector('parsererror')) throw new Error('GPX-Datei konnte nicht gelesen werden.');\n    let nodes = doc.querySelectorAll('trkpt');\n    if (!nodes.length) nodes = doc.querySelectorAll('rtept');\n    if (nodes.length < 2) throw new Error('Die GPX-Datei enth\u00E4lt keine Strecke.');\n    const pts = [];\n    nodes.forEach((n) => {\n      const lat = parseFloat(n.getAttribute('lat'));\n      const lon = parseFloat(n.getAttribute('lon'));\n      if (isNaN(lat) || isNaN(lon)) return;\n      const eleN = n.querySelector('ele');\n      const timeN = n.querySelector('time');\n      pts.push({\n        lat: lat,\n        lon: lon,\n        ele: eleN ? parseFloat(eleN.textContent) : null,\n        time: timeN ? new Date(timeN.textContent) : null\n      });\n    });\n    if (pts.length < 2) throw new Error('Die GPX-Datei enth\u00E4lt zu wenige Punkte.');\n    return pts;\n  }\n\n  function haversine(a, b) {\n    const R = 6371000;\n    const dLat = (b.lat - a.lat) * Math.PI / 180;\n    const dLon = (b.lon - a.lon) * Math.PI / 180;\n    const s = Math.sin(dLat / 2) ** 2 +\n      Math.cos(a.lat * Math.PI / 180) * Math.cos(b.lat * Math.PI / 180) * Math.sin(dLon / 2) ** 2;\n    return 2 * R * Math.asin(Math.sqrt(s));\n  }\n\n  /* Web-Mercator-Weltkoordinaten (0..1) \u2014 identisch zur Kartenprojektion */\n  function toWorld(p) {\n    const x = (p.lon + 180) / 360;\n    const s = Math.sin(p.lat * Math.PI / 180);\n    const y = 0.5 - Math.log((1 + s) / (1 - s)) / (4 * Math.PI);\n    return { x: x, y: y };\n  }\n\n  /* Douglas-Peucker auf Weltkoordinaten */\n  function simplify(points, tolerance) {\n    if (points.length <= 2) return points;\n    const keep = new Uint8Array(points.length);\n    keep[0] = keep[points.length - 1] = 1;\n    const stack = [[0, points.length - 1]];\n    while (stack.length) {\n      const seg = stack.pop();\n      const a = points[seg[0]], b = points[seg[1]];\n      let maxD = 0, idx = -1;\n      const dx = b.wx - a.wx, dy = b.wy - a.wy;\n      const len2 = dx * dx + dy * dy;\n      for (let i = seg[0] + 1; i < seg[1]; i++) {\n        const p = points[i];\n        let d;\n        if (len2 === 0) {\n          d = Math.hypot(p.wx - a.wx, p.wy - a.wy);\n        } else {\n          const t = Math.max(0, Math.min(1, ((p.wx - a.wx) * dx + (p.wy - a.wy) * dy) / len2));\n          d = Math.hypot(p.wx - (a.wx + t * dx), p.wy - (a.wy + t * dy));\n        }\n        if (d > maxD) { maxD = d; idx = i; }\n      }\n      if (maxD > tolerance && idx > 0) {\n        keep[idx] = 1;\n        stack.push([seg[0], idx], [idx, seg[1]]);\n      }\n    }\n    return points.filter((_, i) => keep[i]);\n  }\n\n  function movingAverage(values, win) {\n    const out = new Array(values.length);\n    for (let i = 0; i < values.length; i++) {\n      let sum = 0, n = 0;\n      for (let j = Math.max(0, i - win); j <= Math.min(values.length - 1, i + win); j++) {\n        sum += values[j]; n++;\n      }\n      out[i] = sum / n;\n    }\n    return out;\n  }\n\n  function fmtDuration(ms) {\n    const s = Math.round(ms / 1000);\n    const h = Math.floor(s / 3600);\n    const m = Math.floor((s % 3600) / 60);\n    const sec = s % 60;\n    return h + ':' + String(m).padStart(2, '0') + ':' + String(sec).padStart(2, '0');\n  }\n\n  const MONTHS_DE = ['Januar', 'Februar', 'M\u00E4rz', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'];\n\n  /* ---------------- Mini-PDF (JPEG-Embed) ---------------- */\n  function buildPdf(jpegBytes, wPx, hPx, dpi) {\n    const wPt = (wPx * 72 / dpi).toFixed(2);\n    const hPt = (hPx * 72 / dpi).toFixed(2);\n    const te = (s) => {\n      const b = new Uint8Array(s.length);\n      for (let i = 0; i < s.length; i++) b[i] = s.charCodeAt(i) & 0xff;\n      return b;\n    };\n    const content = 'q ' + wPt + ' 0 0 ' + hPt + ' 0 0 cm /Im1 Do Q';\n    const objs = [\n      '1 0 obj\\n<< /Type /Catalog /Pages 2 0 R >>\\nendobj\\n',\n      '2 0 obj\\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\\nendobj\\n',\n      '3 0 obj\\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ' + wPt + ' ' + hPt + '] /Resources << /XObject << /Im1 4 0 R >> >> /Contents 5 0 R >>\\nendobj\\n',\n      null,\n      '5 0 obj\\n<< /Length ' + content.length + ' >>\\nstream\\n' + content + '\\nendstream\\nendobj\\n'\n    ];\n    const imgHead = '4 0 obj\\n<< /Type /XObject /Subtype /Image /Width ' + wPx + ' /Height ' + hPx + ' /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length ' + jpegBytes.length + ' >>\\nstream\\n';\n    const imgTail = '\\nendstream\\nendobj\\n';\n    const parts = [];\n    const offsets = [0];\n    let pos = 0;\n    const push = (b) => { parts.push(b); pos += b.length; };\n    push(te('%PDF-1.4\\n%\\xE2\\xE3\\xCF\\xD3\\n'));\n    for (let i = 0; i < objs.length; i++) {\n      offsets.push(pos);\n      if (i === 3) { push(te(imgHead)); push(jpegBytes); push(te(imgTail)); }\n      else push(te(objs[i]));\n    }\n    const xrefPos = pos;\n    let xref = 'xref\\n0 6\\n0000000000 65535 f \\n';\n    for (let i = 1; i <= 5; i++) xref += String(offsets[i]).padStart(10, '0') + ' 00000 n \\n';\n    xref += 'trailer\\n<< /Size 6 /Root 1 0 R >>\\nstartxref\\n' + xrefPos + '\\n%%EOF\\n';\n    push(te(xref));\n    const total = parts.reduce((n, p) => n + p.length, 0);\n    const out = new Uint8Array(total);\n    let o = 0;\n    for (const p of parts) { out.set(p, o); o += p.length; }\n    return new Blob([out], { type: 'application/pdf' });\n  }\n\n  /* ---------------- STL-Builder ----------------\n     Band entlang der Strecke: pro Segment ein Quader (Unterseite plan z=0,\n     Oberseite folgt dem H\u00F6henprofil), an Enden und Knicken runde Scheiben\n     (runde Joins/Caps wie beim Poster-Strich). \u00DCberlappende Volumen werden\n     vom Slicer vereinigt. Au\u00DFenkontur \u00FCberschreitet die Mittellinie nie um\n     mehr als die halbe Bandbreite \u2192 exakte Maximalma\u00DFe. */\n  function buildStl(pts2d, tops, widthMm) {\n    const halfW = (widthMm || STL.widthMm) / 2;\n    const n = pts2d.length;\n    const tris = [];\n    const quad = (a, b, c, d) => { tris.push([a, b, c], [a, c, d]); };\n\n    // Segment-Quader mit geneigter Oberseite\n    for (let i = 0; i < n - 1; i++) {\n      const p = pts2d[i], q = pts2d[i + 1];\n      const dx = q.x - p.x, dy = q.y - p.y;\n      const len = Math.hypot(dx, dy);\n      if (len < 1e-6) continue;\n      const nx = -dy / len * halfW, ny = dx / len * halfW;\n      const zP = tops[i], zQ = tops[i + 1];\n      const PL = [p.x + nx, p.y + ny], PR = [p.x - nx, p.y - ny];\n      const QL = [q.x + nx, q.y + ny], QR = [q.x - nx, q.y - ny];\n      const v = (c, z) => [c[0], c[1], z];\n      quad(v(PL, zP), v(PR, zP), v(QR, zQ), v(QL, zQ)); // Oberseite\n      quad(v(PR, 0), v(PL, 0), v(QL, 0), v(QR, 0));     // Unterseite\n      quad(v(PL, 0), v(PL, zP), v(QL, zQ), v(QL, 0));   // Wand links\n      quad(v(PR, zP), v(PR, 0), v(QR, 0), v(QR, zQ));   // Wand rechts\n      quad(v(PR, 0), v(PR, zP), v(PL, zP), v(PL, 0));   // Kappe Anfang\n      quad(v(QL, 0), v(QL, zQ), v(QR, zQ), v(QR, 0));   // Kappe Ende\n    }\n\n    // Runde Scheibe (Zylinder) an Punkt c mit Deckelh\u00F6he h\n    const SEG = 16;\n    const disc = (c, h) => {\n      for (let k = 0; k < SEG; k++) {\n        const a0 = (k / SEG) * 2 * Math.PI, a1 = ((k + 1) / SEG) * 2 * Math.PI;\n        const x0 = c.x + Math.cos(a0) * halfW, y0 = c.y + Math.sin(a0) * halfW;\n        const x1 = c.x + Math.cos(a1) * halfW, y1 = c.y + Math.sin(a1) * halfW;\n        tris.push([[c.x, c.y, h], [x0, y0, h], [x1, y1, h]]); // Deckel\n        tris.push([[c.x, c.y, 0], [x1, y1, 0], [x0, y0, 0]]); // Boden\n        tris.push([[x0, y0, 0], [x1, y1, 0], [x1, y1, h]]);   // Wand\n        tris.push([[x0, y0, 0], [x1, y1, h], [x0, y0, h]]);\n      }\n    };\n\n    // Runde Endkappen + runde Gelenke an Knicken\n    disc(pts2d[0], tops[0]);\n    disc(pts2d[n - 1], tops[n - 1]);\n    for (let i = 1; i < n - 1; i++) {\n      const a = pts2d[i - 1], b = pts2d[i], c = pts2d[i + 1];\n      const v1x = b.x - a.x, v1y = b.y - a.y;\n      const v2x = c.x - b.x, v2y = c.y - b.y;\n      if (Math.hypot(v1x, v1y) < 1e-6 || Math.hypot(v2x, v2y) < 1e-6) continue;\n      const ang = Math.abs(Math.atan2(v1x * v2y - v1y * v2x, v1x * v2x + v1y * v2y));\n      if (ang > 0.05) disc(b, tops[i]); // Knick > ~3\u00B0\n    }\n\n    // Bin\u00E4r-STL schreiben\n    const count = tris.length;\n    const buf = new ArrayBuffer(84 + count * 50);\n    const dv = new DataView(buf);\n    const header = 'AP10 Marathon Track';\n    for (let i = 0; i < header.length; i++) dv.setUint8(i, header.charCodeAt(i));\n    dv.setUint32(80, count, true);\n    let off = 84;\n    for (const t of tris) {\n      const ax = t[1][0] - t[0][0], ay = t[1][1] - t[0][1], az = t[1][2] - t[0][2];\n      const bx = t[2][0] - t[0][0], by = t[2][1] - t[0][1], bz = t[2][2] - t[0][2];\n      let nx = ay * bz - az * by, ny = az * bx - ax * bz, nz = ax * by - ay * bx;\n      const nl = Math.hypot(nx, ny, nz) || 1;\n      dv.setFloat32(off, nx / nl, true);\n      dv.setFloat32(off + 4, ny / nl, true);\n      dv.setFloat32(off + 8, nz / nl, true);\n      off += 12;\n      for (const p of t) {\n        dv.setFloat32(off, p[0], true);\n        dv.setFloat32(off + 4, p[1], true);\n        dv.setFloat32(off + 8, p[2], true);\n        off += 12;\n      }\n      dv.setUint16(off, 0, true);\n      off += 2;\n    }\n    return new Blob([buf], { type: 'application/octet-stream' });\n  }\n\n  /* ================= Custom Element ================= */\n  class MarathonConfigurator extends HTMLElement {\n    connectedCallback() {\n      try {\n        this.cfg = JSON.parse(this.querySelector('[data-mc-config]').textContent);\n      } catch (e) {\n        console.error('[MC] Config fehlerhaft', e);\n        return;\n      }\n      this.inline = this.hasAttribute('data-inline') || !!this.cfg.inline;\n      if (this.inline) {\n        // Inline-Modus: Editor liegt direkt auf der Seite, Vorschau in der Medienspalte\n        this.trigger = null;\n        this.modal = this;\n        this.previewRoot = document.querySelector('.mc-preview--inline') || this;\n      } else {\n        this.trigger = this.querySelector('.mc-trigger');\n        this.modal = this.querySelector('.mc-modal');\n        if (this.modal.parentNode !== document.body) document.body.appendChild(this.modal);\n        this.previewRoot = this.modal.querySelector('.mc-preview');\n      }\n\n      this.previewCanvas = this.previewRoot.querySelector('.mc-preview__canvas');\n      this.form = this.modal.querySelector('.mc-form');\n      this.errorEl = this.modal.querySelector('.mc-error');\n      this.submitBtn = this.modal.querySelector('.mc-submit');\n      this.statusEl = this.previewRoot.querySelector('.mc-map-status');\n\n      this.track = null;       // {points, world, distanceM, durationMs, hasEle}\n      this._mapCache = null;   // {key, canvas, meta}\n      this.renderQueued = false;\n\n      this.designKey = (this.cfg.design && DESIGNS[this.cfg.design]) ? this.cfg.design : 'klassisch';\n      this.D = DESIGNS[this.designKey];\n      if (this.D.defaultStyle) this.cfg.styleId = this.D.defaultStyle;\n\n      this.buildPresets();\n      this.buildStyles();\n      this.applyDesign();\n      this.bindEvents();\n      this.setupSteps();\n\n      // Fenstergr\u00F6\u00DFe \u00E4ndert sich (auch Rotation) \u2192 Vorschau + Karten-Ebenen neu vermessen\n      window.addEventListener('resize', () => {\n        clearTimeout(this._rsT);\n        this._rsT = setTimeout(() => {\n          if (!this.inline && !this.modal.classList.contains('is-open')) return;\n          this._previewBox = null;\n          this.layoutLiveMap();\n          if (this.track) this.queuePreview(false);\n        }, 200);\n      });\n      if (this.inline) {\n        setTimeout(() => this.initLiveMap(), 600);\n        this.setupMiniPreview();\n      }\n    }\n\n    /* ---------- Schritt-Assistent: Strecke \u2192 Karten-Stil \u2192 Details ---------- */\n    setupSteps() {\n      this.stepPanels = {};\n      this.modal.querySelectorAll('[data-mc-step]').forEach((p) => { this.stepPanels[p.dataset.mcStep] = p; });\n      this.backBtn = this.modal.querySelector('[data-mc-back]');\n      this.nextBtn = this.modal.querySelector('[data-mc-next]');\n      this.hasStyleStep = !!(this.styleButtons && this.styleButtons.length);\n      // Ohne Stil-Auswahl wandert die Strecken-Karte in den Detail-Schritt\n      if (!this.hasStyleStep && this.stepPanels.details) {\n        const card = this.modal.querySelector('.mc-track-card');\n        if (card) this.stepPanels.details.insertBefore(card, this.stepPanels.details.firstChild);\n      }\n      this.steps = this.hasStyleStep ? ['track', 'style', 'details'] : ['track', 'details'];\n      if (this.inline) {\n        // Inline-Modus: alle Schritte gleichzeitig, keine Navigation\n        Object.keys(this.stepPanels).forEach((k) => {\n          this.stepPanels[k].hidden = (k === 'style' && !this.hasStyleStep);\n        });\n        if (this.backBtn) this.backBtn.hidden = true;\n        if (this.nextBtn) this.nextBtn.hidden = true;\n        if (this.submitBtn) this.submitBtn.hidden = false;\n        return;\n      }\n      if (this.backBtn) this.backBtn.addEventListener('click', () => this.goStep(this.stepIndex - 1));\n      if (this.nextBtn) this.nextBtn.addEventListener('click', () => {\n        if (this.steps[this.stepIndex] === 'track' && !this.track) return;\n        this.goStep(this.stepIndex + 1);\n      });\n      this.goStep(0);\n    }\n\n    goStep(i) {\n      if (this.inline || !this.steps) return;\n      this.stepIndex = Math.max(0, Math.min(this.steps.length - 1, i));\n      const key = this.steps[this.stepIndex];\n      Object.keys(this.stepPanels).forEach((k) => { this.stepPanels[k].hidden = k !== key; });\n      const last = this.stepIndex === this.steps.length - 1;\n      if (this.backBtn) this.backBtn.hidden = this.stepIndex === 0;\n      if (this.nextBtn) this.nextBtn.hidden = last;\n      if (this.submitBtn) this.submitBtn.hidden = !last;\n      this.updateNextState();\n      if (this.form) this.form.scrollTop = 0;\n      // Sheet-H\u00F6he \u00E4ndert sich pro Schritt \u2192 Vorschau + Karten-Ebenen neu vermessen\n      this._previewBox = null;\n      this.layoutLiveMap();\n      if (this.track) this.queuePreview(false);\n    }\n\n    updateNextState() {\n      if (!this.nextBtn || this.inline || !this.steps) return;\n      this.nextBtn.disabled = this.steps[this.stepIndex] === 'track' && !this.track;\n    }\n\n    /* Felder + Labels je Design umschalten */\n    applyDesign() {\n      const fields = this.D.fields || {};\n      this.modal.querySelectorAll('[data-mc-field]').forEach((wrap) => {\n        const key = wrap.getAttribute('data-mc-field');\n        const def = fields[key];\n        wrap.hidden = !def;\n        if (def) {\n          const lab = wrap.querySelector('label');\n          const inp = wrap.querySelector('input');\n          if (lab && def.label) lab.textContent = def.label;\n          if (inp && def.ph) inp.placeholder = def.ph;\n        }\n      });\n      const nameWrap = this.modal.querySelector('[data-mc-field=\"name\"]');\n      if (nameWrap) nameWrap.classList.toggle('mc-field--uppercase', !!this.D.upperName);\n      // Datum + Gesamtzeit in eine Zeile r\u00FCcken, wenn Startnummer/Pace im Design fehlen\n      const fDat = this.modal.querySelector('[data-mc-field=\"datum\"]');\n      const fNum = this.modal.querySelector('[data-mc-field=\"nummer\"]');\n      const fPace = this.modal.querySelector('[data-mc-field=\"pace\"]');\n      const fZeit = this.modal.querySelector('[data-mc-field=\"zeit\"]');\n      if (fDat && fZeit && !fDat.hidden && !fZeit.hidden && fNum && fNum.hidden && fPace && fPace.hidden) {\n        fDat.parentElement.appendChild(fZeit);\n      }\n      // Zeilen ohne sichtbare Felder komplett ausblenden (sonst bleibt die Grid-L\u00FCcke)\n      this.modal.querySelectorAll('.mc-fields__row').forEach((row) => {\n        const anyVisible = Array.prototype.some.call(row.children, (c) => !c.hidden);\n        row.style.display = anyVisible ? '' : 'none';\n      });\n      // Design-eigenes Platzhalterbild in der Vorschau\n      const phImg = this.previewRoot.querySelector('.mc-preview__placeholder');\n      const phUrl = this.cfg.placeholders && this.cfg.placeholders[this.designKey];\n      if (phImg && phUrl) phImg.src = phUrl;\n    }\n\n    /* Kunden-Stilauswahl: Kacheln mit Mini-Karten (MapTiler Static API) */\n    buildStyles() {\n      const wrap = this.modal.querySelector('.mc-styles');\n      const row = this.modal.querySelector('[data-mc-styles-row]');\n      const styles = (this.D && this.D.styles) || this.cfg.styles || [];\n      if (!wrap || styles.length < 2 || (this.D && this.D.hasMap === false)) {\n        if (row) row.hidden = true;\n        return;\n      }\n      this.styleButtons = [];\n      styles.forEach((s) => {\n        const btn = document.createElement('button');\n        btn.type = 'button';\n        btn.className = 'mc-style' + (s.id === this.cfg.styleId ? ' is-active' : '');\n        btn.innerHTML = '<span class=\"mc-style__thumb\"><img alt=\"\"></span><span class=\"mc-style__label\"></span>';\n        btn.querySelector('.mc-style__label').textContent = s.label;\n        btn._styleId = s.id;\n        btn.addEventListener('click', () => {\n          if (this.cfg.styleId === s.id) return;\n          this.cfg.styleId = s.id;\n          wrap.querySelectorAll('.mc-style').forEach((b) => b.classList.remove('is-active'));\n          btn.classList.add('is-active');\n          if (this._liveMap && this._liveMapStyle !== s.id) {\n            this._liveMapStyle = s.id;\n            this.getStyleArg().then((st) => { try { this._liveMap.setStyle(st); } catch (e) {} });\n          }\n          this.queuePreview(true);\n        });\n        wrap.appendChild(btn);\n        this.styleButtons.push(btn);\n      });\n      // Platzhalter-Ausschnitt, bis eine Strecke geladen ist\n      this.updateStyleThumbs(10.2, 50.9, 4.2);\n    }\n\n    updateStyleThumbs(lon, lat, zoom) {\n      if (!this.styleButtons) return;\n      this.styleButtons.forEach((btn) => {\n        const img = btn.querySelector('img');\n        const ps = PSEUDO_STYLES[btn._styleId];\n        if (ps) {\n          if (!img.src) img.src = pseudoThumb(ps);\n          return;\n        }\n        img.src = 'https://api.maptiler.com/maps/' + btn._styleId + '/static/'\n          + lon.toFixed(5) + ',' + lat.toFixed(5) + ',' + Math.max(0, zoom).toFixed(2)\n          + '/96x96@2x.png?key=' + this.cfg.maptilerKey + '&attribution=false';\n      });\n    }\n\n    /* ---------- Strecken-Datenbank (Supabase + Block-Presets) ---------- */\n    buildPresets() {\n      // ?marathon=slug \u2192 Strecke direkt vorausw\u00E4hlen (teilbarer Link)\n      try {\n        const slug = new URLSearchParams(window.location.search).get('marathon');\n        if (!slug) return;\n        this.loadTrackDb().then((db) => {\n          const t = db.find((x) => x.slug === slug);\n          if (!t) return;\n          this.modal.querySelectorAll('[data-mc-source]').forEach((b) => {\n            b.classList.toggle('is-active', b.dataset.mcSource === 'preset');\n          });\n          const up = this.modal.querySelector('[data-mc-panel=\"upload\"]');\n          const pp = this.modal.querySelector('[data-mc-panel=\"preset\"]');\n          if (up) up.hidden = true;\n          if (pp) pp.hidden = false;\n          if (!this.inline) this.openModal();\n          // Nach dem Deep-Link direkt zu Schritt 2 (Stil bzw. Details)\n          this.selectDbTrack(t).then(() => this.goStep(1));\n        });\n      } catch (e) { /* URL nicht lesbar \u2014 ignorieren */ }\n    }\n\n    loadTrackDb() {\n      if (this._trackDbP) return this._trackDbP;\n      this._trackDbP = (async () => {\n        let db = [];\n        try {\n          const res = await fetch(this.cfg.supabaseUrl + '/rest/v1/marathon_tracks?select=slug,name,country,country_code,type,distance_km,elevation_m,gpx_path&active=eq.true&order=rank.asc&limit=1000', {\n            headers: {\n              apikey: this.cfg.supabaseKey,\n              Authorization: 'Bearer ' + this.cfg.supabaseKey\n            }\n          });\n          if (res.ok) db = await res.json();\n        } catch (e) { /* Datenbank nicht erreichbar \u2192 nur Block-Presets */ }\n        (this.cfg.presets || []).forEach((p, i) => {\n          db.unshift({ slug: 'custom-' + i, name: p.label, url: p.url });\n        });\n        return db;\n      })();\n      return this._trackDbP;\n    }\n\n    trackUrl(t) {\n      return t.url || (this.cfg.supabaseUrl + '/storage/v1/object/public/' + this.cfg.bucket + '/' + t.gpx_path);\n    }\n\n    flagEmoji(cc) {\n      if (!cc || cc.length !== 2) return '\uD83C\uDFC1';\n      const A = 0x1f1e6;\n      return String.fromCodePoint(A + cc.toUpperCase().charCodeAt(0) - 65, A + cc.toUpperCase().charCodeAt(1) - 65);\n    }\n\n    /* Renn-Typ \u2192 Kategorie (f\u00FCr Badge-Farbe + Filter) */\n    typeCat(type) {\n      const t = (type || '').toLowerCase();\n      if (t === 'marathon') return 'marathon';\n      if (t === 'halbmarathon') return 'halb';\n      if (t === 'ultra' || t === 'marathon+') return 'ultra';\n      if (t.indexOf('trail') !== -1) return 'trail';\n      return 'sonstige';\n    }\n\n    typeLabel(type) {\n      const map = { marathon: 'Marathon', halb: 'Halbmarathon', ultra: 'Ultra', trail: 'Trail' };\n      return map[this.typeCat(type)] || (type || 'Lauf');\n    }\n\n    async openTrackList(query) {\n      const list = this.form.querySelector('.mc-combo__list');\n      if (!list) return;\n      const db = await this.loadTrackDb();\n      const q = (query || '').trim().toLowerCase();\n      const norm = (s) => (s || '').toLowerCase();\n      const typeSel = this.form.querySelector('[name=\"preset_type\"]');\n      const cat = typeSel ? typeSel.value : '';\n      const hits = db.filter((t) =>\n        (!cat || this.typeCat(t.type) === cat)\n        && (!q || norm(t.name).indexOf(q) !== -1 || norm(t.country).indexOf(q) !== -1 || norm(t.type).indexOf(q) !== -1)\n      ).slice(0, 30);\n      list.innerHTML = '';\n      if (!hits.length) {\n        const d = document.createElement('div');\n        d.className = 'mc-combo__empty';\n        d.textContent = 'Keine Strecke gefunden';\n        list.appendChild(d);\n      }\n      hits.forEach((t) => {\n        const btn = document.createElement('button');\n        btn.type = 'button';\n        btn.className = 'mc-combo__item';\n        btn.innerHTML = '<span class=\"mc-combo__flag\"></span><span class=\"mc-combo__text\"><span class=\"mc-combo__name\"></span><span class=\"mc-combo__meta\"></span></span><span class=\"mc-badge\"></span>';\n        btn.querySelector('.mc-combo__flag').textContent = this.flagEmoji(t.country_code);\n        btn.querySelector('.mc-combo__name').textContent = t.name;\n        const meta = [t.distance_km ? t.distance_km + ' km' : '', t.country].filter(Boolean).join(' \u00B7 ');\n        btn.querySelector('.mc-combo__meta').textContent = meta;\n        const badge = btn.querySelector('.mc-badge');\n        badge.textContent = this.typeLabel(t.type);\n        badge.className = 'mc-badge mc-badge--' + this.typeCat(t.type);\n        btn.addEventListener('click', () => this.selectDbTrack(t));\n        list.appendChild(btn);\n      });\n      list.hidden = false;\n      const combo = this.form.querySelector('.mc-combo');\n      if (combo) combo.classList.add('is-open');\n      const inp = this.form.querySelector('[name=\"preset_search\"]');\n      if (inp) inp.setAttribute('aria-expanded', 'true');\n    }\n\n    closeTrackList() {\n      const list = this.form && this.form.querySelector('.mc-combo__list');\n      if (list) list.hidden = true;\n      const combo = this.form && this.form.querySelector('.mc-combo');\n      if (combo) combo.classList.remove('is-open');\n      const inp = this.form && this.form.querySelector('[name=\"preset_search\"]');\n      if (inp) inp.setAttribute('aria-expanded', 'false');\n    }\n\n    /* Kachel mit Strecken-Daten unter dem Suchfeld */\n    showTrackCard(t) {\n      const card = this.form.querySelector('.mc-track-card');\n      if (!card) return;\n      const dist = t.distance_km\n        ? String(t.distance_km).replace('.', ',') + ' km'\n        : (this.track ? (this.track.distanceM / 1000).toFixed(1).replace('.', ',') + ' km' : '\u2013');\n      let elev = (t.elevation_m || t.elevation_m === 0) ? t.elevation_m : null;\n      if (elev === null && this.track && this.track.hasEle && this.track.eles) {\n        let up = 0;\n        for (let i = 1; i < this.track.eles.length; i++) {\n          const d = this.track.eles[i] - this.track.eles[i - 1];\n          if (d > 0) up += d;\n        }\n        elev = Math.round(up);\n      }\n      card.querySelector('.mc-track-card__flag').textContent = this.flagEmoji(t.country_code);\n      card.querySelector('.mc-track-card__name').textContent = t.name || '';\n      const typeEl = card.querySelector('.mc-track-card__type');\n      typeEl.textContent = this.typeLabel(t.type);\n      typeEl.className = 'mc-track-card__type mc-badge mc-badge--' + this.typeCat(t.type);\n      typeEl.hidden = !t.type;\n      card.querySelector('[data-mc-stat=\"dist\"]').textContent = dist;\n      card.querySelector('[data-mc-stat=\"elev\"]').textContent = elev !== null ? elev.toLocaleString('de-DE') + ' m' : '\u2013';\n      card.querySelector('[data-mc-stat=\"land\"]').textContent = t.country || '\u2013';\n      card.hidden = false;\n    }\n\n    hideTrackCard() {\n      const card = this.form && this.form.querySelector('.mc-track-card');\n      if (card) card.hidden = true;\n    }\n\n    async selectDbTrack(t) {\n      this.closeTrackList();\n      const input = this.form.querySelector('[name=\"preset_search\"]');\n      if (input) input.value = t.name;\n      try {\n        this.setStatus('Strecke wird geladen \u2026');\n        const res = await fetch(this.trackUrl(t));\n        if (!res.ok) throw new Error('Strecke konnte nicht geladen werden.');\n        this.loadTrack(await res.text());\n        this.showTrackCard(t);\n        const ev = this.form.querySelector('[name=\"event\"]');\n        if (ev && t.name) ev.value = t.name;\n        // Nach der Auswahl automatisch zum n\u00E4chsten Schritt\n        if (!this.inline && this.steps && this.steps[this.stepIndex] === 'track') {\n          this.goStep(this.stepIndex + 1);\n        }\n        // URL-Parameter f\u00FCr teilbaren Link setzen\n        if (t.slug && t.slug.indexOf('custom-') !== 0) {\n          try {\n            const u = new URL(window.location.href);\n            u.searchParams.set('marathon', t.slug);\n            history.replaceState(null, '', u.toString());\n          } catch (e) { /* ignorieren */ }\n        }\n      } catch (err) {\n        this.showError(err.message);\n        this.setStatus('');\n      }\n    }\n\n    bindEvents() {\n      if (this.trigger) this.trigger.addEventListener('click', (e) => { e.preventDefault(); this.openModal(); });\n      this.modal.querySelectorAll('[data-mc-close]').forEach((el) =>\n        el.addEventListener('click', (e) => { e.preventDefault(); this.closeModal(); })\n      );\n      document.addEventListener('keydown', (e) => {\n        if (e.key === 'Escape' && this.modal.classList.contains('is-open')) this.closeModal();\n      });\n\n      // Quelle umschalten (Preset / Upload)\n      this.modal.querySelectorAll('[data-mc-source]').forEach((btn) => {\n        btn.addEventListener('click', () => {\n          this.modal.querySelectorAll('[data-mc-source]').forEach((b) => b.classList.remove('is-active'));\n          btn.classList.add('is-active');\n          const mode = btn.dataset.mcSource;\n          this.modal.querySelector('[data-mc-panel=\"upload\"]').hidden = mode !== 'upload';\n          this.modal.querySelector('[data-mc-panel=\"preset\"]').hidden = mode !== 'preset';\n        });\n      });\n\n      // Sprung-Links (\"Deine Strecke nicht gefunden? GPX hochladen\")\n      this.modal.querySelectorAll('[data-mc-goto]').forEach((btn) => {\n        btn.addEventListener('click', () => {\n          const target = this.modal.querySelector('[data-mc-source=\"' + btn.dataset.mcGoto + '\"]');\n          if (target) target.click();\n        });\n      });\n\n      // GPX-Upload (mehrere Dateien m\u00F6glich \u2014 Triathlon: Schwimmen/Rad/Laufen)\n      this.form.querySelector('[name=\"gpxfile\"]').addEventListener('change', async (e) => {\n        const files = Array.from(e.target.files || []).slice(0, 3);\n        if (!files.length) return;\n        try {\n          this.setStatus(files.length > 1 ? files.length + ' GPX-Dateien werden gelesen \u2026' : 'GPX wird gelesen \u2026');\n          const texts = await Promise.all(files.map((f) => f.text()));\n          this.loadTracks(texts);\n          // Strecken-Karte mit Dateiname + berechneten Werten f\u00FCllen\n          const nice = files.length > 1\n            ? 'Deine Strecke (' + files.length + ' Teilstrecken)'\n            : files[0].name.replace(/\\.gpx$/i, '').replace(/[_-]+/g, ' ').trim();\n          this.showTrackCard({ name: nice || 'Deine Strecke', country: '', country_code: '', type: files.length > 1 ? 'Triathlon' : '' });\n          // Nach dem Upload automatisch zum n\u00E4chsten Schritt\n          if (!this.inline && this.steps && this.steps[this.stepIndex] === 'track') {\n            this.goStep(this.stepIndex + 1);\n          }\n        } catch (err) {\n          this.showError(err.message);\n          this.setStatus('');\n        }\n      });\n\n      // Marathon-Suche (Strecken-Datenbank + Block-Presets)\n      const searchInput = this.form.querySelector('[name=\"preset_search\"]');\n      if (searchInput) {\n        searchInput.addEventListener('focus', () => this.openTrackList(searchInput.value));\n        searchInput.addEventListener('input', () => this.openTrackList(searchInput.value));\n        document.addEventListener('click', (e) => {\n          if (!e.target.closest('.mc-combo')) this.closeTrackList();\n        });\n        const typeSel = this.form.querySelector('[name=\"preset_type\"]');\n        if (typeSel) typeSel.addEventListener('change', () => this.openTrackList(searchInput.value));\n      }\n\n      // Textfelder \u2192 nur Text-Layer neu zeichnen\n      this.form.addEventListener('input', (e) => {\n        if (e.target.name === 'gpxfile') return;\n        this.queuePreview(false);\n      });\n\n      // Variantenwechsel (Gr\u00F6\u00DFe) \u2192 Karte neu\n      document.addEventListener('change', (e) => {\n        if (e.target && e.target.name && e.target.name.indexOf('options[') === 0) {\n          setTimeout(() => {\n            this.layoutLiveMap();\n            this.queuePreview(true);\n          }, 60);\n        }\n      });\n\n      this.submitBtn.addEventListener('click', (e) => { e.preventDefault(); this.addToCart(); });\n\n      // 3D-Produktvorschau\n      const btn3d = this.previewRoot.querySelector('.mc-3d-btn');\n      if (btn3d) btn3d.addEventListener('click', (e) => { e.preventDefault(); this.open3d(); });\n    }\n\n    /* ---------- 3D-Produktvorschau (Rahmen-GLB + Streckenband) ---------- */\n    async open3d() {\n      if (!this.track || this._3dBusy) return;\n      const btn = this.previewRoot.querySelector('.mc-3d-btn');\n      try {\n        this._3dBusy = true;\n        if (btn) btn.classList.add('is-loading');\n        const S = SIZES[this.currentSize()];\n        // Poster flach rendern (ohne Fake-3D-Schatten \u2014 das echte Band kommt obendrauf)\n        const poster = await this.compose(1600 / (S.wMm * PX_PER_MM), false);\n        // Alle Segmente (Triathlon) zu einer Viewer-Geometrie zusammenf\u00FChren\n        const stlParts = await Promise.all(this.makeStls().map((b) => b.arrayBuffer()));\n        let stlBuf = stlParts[0];\n        if (stlParts.length > 1) {\n          let n = 0;\n          stlParts.forEach((b) => { n += new DataView(b).getUint32(80, true); });\n          const merged = new ArrayBuffer(84 + n * 50);\n          new DataView(merged).setUint32(80, n, true);\n          const dst = new Uint8Array(merged);\n          let off = 84;\n          stlParts.forEach((b) => { const src = new Uint8Array(b, 84); dst.set(src, off); off += src.length; });\n          stlBuf = merged;\n        }\n        const mod = await import(this.cfg.viewer3d);\n        const center = (this.D && this.D.track)\n          ? { cx: this.D.track.cx, cy: this.D.track.cy }\n          : { cx: (L.mapX0 + L.mapX1) / 2, cy: (L.mapY0 + L.mapY1) / 2 };\n        // Rahmen-Modell passend zur Gr\u00F6\u00DFe (A4/A3); Fallback: einzelne URL\n        const glbUrl = (this.cfg.frameGlb && typeof this.cfg.frameGlb === 'object')\n          ? (this.cfg.frameGlb[this.currentSize()] || this.cfg.frameGlb.A4)\n          : this.cfg.frameGlb;\n        await mod.openViewer({\n          glbUrl: glbUrl,\n          posterCanvas: poster,\n          stlBuffer: stlBuf,\n          sizeMm: { w: S.wMm, h: S.hMm },\n          trackCenter: center\n        });\n      } catch (err) {\n        console.error('[MC] 3D-Ansicht:', err);\n        this.showError('3D-Ansicht konnte nicht geladen werden. Bitte versuche es erneut.');\n      } finally {\n        this._3dBusy = false;\n        if (btn) btn.classList.remove('is-loading');\n      }\n    }\n\n    /* ---------- Track laden ---------- */\n    loadTrack(gpxText) {\n      this.loadTracks([gpxText]);\n    }\n\n    /* Eine oder mehrere GPX-Dateien laden (Triathlon: Schwimmen/Rad/Laufen).\n       Teilstrecken, deren Ende und Start nah beieinander liegen, werden\n       verbunden; sonst bleiben sie eigenst\u00E4ndige Segmente (eigene STLs). */\n    loadTracks(texts) {\n      let files = texts\n        .map((txt) => ({ raw: parseGpx(txt), text: txt }))\n        .filter((f) => f.raw.length > 1);\n      if (!files.length) throw new Error('Keine g\u00FCltigen Streckenpunkte gefunden.');\n\n      // Nach Startzeit sortieren, wenn alle Dateien Zeitstempel haben\n      const firstTime = (f) => { const p = f.raw.find((q) => q.time); return p ? p.time.getTime() : null; };\n      if (files.every((f) => firstTime(f) !== null)) {\n        files.sort((a, b) => firstTime(a) - firstTime(b));\n      }\n      this.gpxTexts = files.map((f) => f.text);\n      this.gpxText = this.gpxTexts[0]; // Kompatibilit\u00E4t\n\n      // Distanz & Dauer \u00FCber alle Dateien\n      let dist = 0;\n      files.forEach((f) => { for (let i = 1; i < f.raw.length; i++) dist += haversine(f.raw[i - 1], f.raw[i]); });\n      const times = [];\n      files.forEach((f) => f.raw.forEach((p) => { if (p.time) times.push(p.time.getTime()); }));\n      const durMs = times.length >= 2 ? Math.max.apply(null, times) - Math.min.apply(null, times) : null;\n      const startTime = times.length ? new Date(Math.min.apply(null, times)) : null;\n\n      // Weltkoordinaten\n      files.forEach((f) => f.raw.forEach((p) => { const w = toWorld(p); p.wx = w.x; p.wy = w.y; }));\n\n      // Teilstrecken verketten: Ende \u2192 n\u00E4chster Start unter 500 m \u21D2 verbinden\n      const CONNECT_M = 500;\n      const segsRaw = [];\n      files.forEach((f) => {\n        const prev = segsRaw[segsRaw.length - 1];\n        if (prev && haversine(prev[prev.length - 1], f.raw[0]) < CONNECT_M) {\n          prev.push.apply(prev, f.raw);\n        } else {\n          segsRaw.push(f.raw.slice());\n        }\n      });\n\n      // Gemeinsame Bounding-Box (bestimmt den Ma\u00DFstab f\u00FCr Poster UND STLs)\n      let wxMin = Infinity, wxMax = -Infinity, wyMin = Infinity, wyMax = -Infinity;\n      files.forEach((f) => f.raw.forEach((p) => {\n        wxMin = Math.min(wxMin, p.wx); wxMax = Math.max(wxMax, p.wx);\n        wyMin = Math.min(wyMin, p.wy); wyMax = Math.max(wyMax, p.wy);\n      }));\n      const span = Math.max(wxMax - wxMin, wyMax - wyMin) || 1e-9;\n\n      // Je Segment vereinfachen (Punktbudget aufteilen) + H\u00F6hen gl\u00E4tten\n      const budget = Math.max(200, Math.ceil(STL.maxPoints / segsRaw.length));\n      const segs = segsRaw.map((rawSeg) => {\n        let sp = simplify(rawSeg, span / 4000);\n        if (sp.length > budget) {\n          const step = Math.ceil(sp.length / budget);\n          sp = sp.filter((_, i) => i % step === 0 || i === sp.length - 1);\n        }\n        const hasEle = sp.every((p) => p.ele !== null && !isNaN(p.ele));\n        return { pts: sp, hasEle: hasEle, eles: hasEle ? movingAverage(sp.map((p) => p.ele), 5) : null };\n      });\n\n      // Kombinierte Punktliste mit Segmentmarken (f\u00FCrs Zeichnen: moveTo statt Verbindungslinie)\n      const pts = [];\n      segs.forEach((s, si) => s.pts.forEach((p, i) => {\n        p.segStart = (si > 0 && i === 0);\n        pts.push(p);\n      }));\n      const hasEleAll = segs.every((s) => s.hasEle);\n      const elesAll = hasEleAll ? [].concat.apply([], segs.map((s) => s.eles)) : null;\n\n      this.track = {\n        segs: segs,\n        pts: pts,\n        eles: elesAll,\n        hasEle: hasEleAll,\n        bounds: { wxMin: wxMin, wxMax: wxMax, wyMin: wyMin, wyMax: wyMax },\n        distanceM: dist,\n        durationMs: durMs,\n        startTime: startTime\n      };\n\n      // Felder vorbef\u00FCllen (nur wenn leer)\n      const set = (name, val) => {\n        const el = this.form.querySelector('[name=\"' + name + '\"]');\n        if (el && !el.value && val) el.value = val;\n      };\n      if (durMs) {\n        set('zeit', fmtDuration(durMs));\n        const paceSec = (durMs / 1000) / (dist / 1000);\n        const pm = Math.floor(paceSec / 60), ps = Math.round(paceSec % 60);\n        set('pace', String(pm).padStart(2, '0') + ':' + String(ps).padStart(2, '0'));\n      }\n      if (this.track.startTime) {\n        const d = this.track.startTime;\n        if (this.D && this.D.dateShort) {\n          set('datum', String(d.getDate()).padStart(2, '0') + '.' + String(d.getMonth() + 1).padStart(2, '0') + '.' + d.getFullYear());\n        } else {\n          set('datum', d.getDate() + '. ' + MONTHS_DE[d.getMonth()] + ' ' + d.getFullYear());\n        }\n      }\n      if (!this.track.hasEle) {\n        this.setStatus(this.track.segs.some((s) => s.hasEle)\n          ? 'Hinweis: Teilstrecken ohne H\u00F6hendaten werden mit einheitlicher H\u00F6he erstellt.'\n          : 'Hinweis: GPX ohne H\u00F6hendaten \u2014 3D-Strecke wird mit einheitlicher H\u00F6he erstellt.');\n      } else {\n        this.setStatus('');\n      }\n      // Stil-Kacheln zeigen jetzt den Strecken-Ausschnitt\n      const tcx = (wxMin + wxMax) / 2, tcy = (wyMin + wyMax) / 2;\n      const tLon = tcx * 360 - 180;\n      const tLat = Math.atan(Math.sinh(Math.PI * (1 - 2 * tcy))) * 180 / Math.PI;\n      this.updateStyleThumbs(tLon, tLat, Math.log2((96 / span) / 512) - 0.3);\n\n      this._mapCache = null;\n      this.showError('');\n      this.updateNextState();\n      // 3D-Ansicht verf\u00FCgbar, sobald eine Strecke geladen ist\n      const btn3d = this.previewRoot.querySelector('.mc-3d-btn');\n      if (btn3d) btn3d.hidden = false;\n      // Hinweis sofort ausblenden \u2014 Strecke ist gew\u00E4hlt, der Flug beginnt\n      const emptyHint = this.previewRoot.querySelector('.mc-preview__empty');\n      if (emptyHint) emptyHint.hidden = true;\n      if (this._liveMap && (!this.D || this.D.hasMap !== false)) {\n        this.animateToTrack();\n      } else {\n        this.queuePreview(true);\n      }\n    }\n\n    /* ---------- Gr\u00F6\u00DFe / Variante ---------- */\n    currentVariantId() {\n      const input = document.querySelector('form[id^=\"product-form\"] input[name=\"id\"], form[action*=\"/cart/add\"] input[name=\"id\"]');\n      if (input) return String(input.value);\n      // Fallback ohne Kaufbutton-Formular: gew\u00E4hlte Gr\u00F6\u00DFe im Varianten-Picker\n      const checked = document.querySelector('input[name^=\"options[\"]:checked');\n      if (checked && this.cfg.variantSizes) {\n        for (const id in this.cfg.variantSizes) {\n          if (this.cfg.variantSizes[id] === checked.value) return id;\n        }\n      }\n      const ids = this.cfg.variantSizes ? Object.keys(this.cfg.variantSizes) : [];\n      return ids.length ? ids[0] : null;\n    }\n\n    currentSize() {\n      const vid = this.currentVariantId();\n      const key = (vid && this.cfg.variantSizes && this.cfg.variantSizes[vid]) || 'A4';\n      return SIZES[key] ? key : 'A4';\n    }\n\n    /* Aufgel\u00F6sten Stil (URL oder umgef\u00E4rbtes Stil-Objekt) liefern */\n    async getStyleArg() {\n      const ps = PSEUDO_STYLES[this.cfg.styleId];\n      if (ps) {\n        const base = 'https://api.maptiler.com/maps/' + ps.base + '/style.json?key=' + this.cfg.maptilerKey;\n        try {\n          const res = await fetch(base);\n          if (res.ok) return recolorStyle(await res.json(), ps);\n        } catch (e) { /* Basis-Stil-URL als Fallback */ }\n        return base;\n      }\n      return 'https://api.maptiler.com/maps/' + this.cfg.styleId + '/style.json?key=' + this.cfg.maptilerKey;\n    }\n\n    /* ---------- Live-Karte in der Vorschau (Deutschland \u2192 Flug zur Strecke) ---------- */\n\n    /* Positioniert die Live-Karte ins Kartenfenster des Posters und zeichnet\n       Rahmen + Posterfl\u00E4che (mit Kartenloch, Verl\u00E4ufen und Design-Overlay). */\n    async layoutLiveMap() {\n      const holder = this.previewRoot.querySelector('.mc-preview__livemap');\n      const chrome = this.previewRoot.querySelector('.mc-preview__chrome');\n      if (!holder || !chrome) return;\n      const cs = getComputedStyle(this.previewRoot);\n      const padL = parseFloat(cs.paddingLeft) || 0;\n      const padT = parseFloat(cs.paddingTop) || 0;\n      const bw = this.previewRoot.clientWidth - padL - (parseFloat(cs.paddingRight) || 0);\n      const bh = this.previewRoot.clientHeight - padT - (parseFloat(cs.paddingBottom) || 0);\n      if (bw < 50 || bh < 50) {\n        if ((this._lmTries || 0) < 20) {\n          this._lmTries = (this._lmTries || 0) + 1;\n          setTimeout(() => this.layoutLiveMap(), 300);\n        }\n        return;\n      }\n      this._lmTries = 0;\n      const S = SIZES[this.currentSize()];\n      const frame = await this.loadFrame(this.currentSize());\n      let dispW, dispH, winRect;\n      if (frame) {\n        const fit = Math.min(bw / frame.w, bh / frame.h);\n        dispW = frame.w * fit;\n        dispH = frame.h * fit;\n        winRect = {\n          x: frame.win.x / frame.w * dispW,\n          y: frame.win.y / frame.h * dispH,\n          w: frame.win.w / frame.w * dispW,\n          h: frame.win.h / frame.h * dispH\n        };\n      } else {\n        const fit = Math.min(bw / S.wMm, bh / S.hMm);\n        dispW = S.wMm * fit;\n        dispH = S.hMm * fit;\n        winRect = { x: 0, y: 0, w: dispW, h: dispH };\n      }\n      const left = padL + (bw - dispW) / 2;\n      const top = padT + (bh - dispH) / 2;\n      const mf = (this.D && this.D.mapFull)\n        ? { x0: 0, y0: 0, x1: 1, y1: 1 }\n        : { x0: L.mapX0, y0: L.mapY0, x1: L.mapX1, y1: L.mapY1 };\n      holder.style.inset = 'auto';\n      holder.style.left = (left + winRect.x + mf.x0 * winRect.w) + 'px';\n      holder.style.top = (top + winRect.y + mf.y0 * winRect.h) + 'px';\n      holder.style.width = ((mf.x1 - mf.x0) * winRect.w) + 'px';\n      holder.style.height = ((mf.y1 - mf.y0) * winRect.h) + 'px';\n\n      const dpr = Math.min(window.devicePixelRatio || 1, 3);\n      chrome.width = Math.round(dispW * dpr);\n      chrome.height = Math.round(dispH * dpr);\n      chrome.style.left = left + 'px';\n      chrome.style.top = top + 'px';\n      chrome.style.width = dispW + 'px';\n      chrome.style.height = dispH + 'px';\n      const cctx = chrome.getContext('2d');\n      cctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n      cctx.clearRect(0, 0, dispW, dispH);\n      cctx.fillStyle = (this.D && this.D.bg) || '#ffffff';\n      cctx.fillRect(winRect.x, winRect.y, winRect.w, winRect.h);\n      cctx.clearRect(\n        winRect.x + mf.x0 * winRect.w,\n        winRect.y + mf.y0 * winRect.h,\n        (mf.x1 - mf.x0) * winRect.w,\n        (mf.y1 - mf.y0) * winRect.h\n      );\n      if (this.D && this.D.fadeTop) {\n        const gt = cctx.createLinearGradient(0, winRect.y, 0, winRect.y + this.D.fadeTop[1] * winRect.h);\n        gt.addColorStop(0, 'rgba(255,255,255,1)');\n        gt.addColorStop(Math.min(0.999, this.D.fadeTop[0] / this.D.fadeTop[1]), 'rgba(255,255,255,0.92)');\n        gt.addColorStop(1, 'rgba(255,255,255,0)');\n        cctx.fillStyle = gt;\n        cctx.fillRect(winRect.x, winRect.y, winRect.w, this.D.fadeTop[1] * winRect.h);\n      }\n      if (this.D && this.D.fadeBottom) {\n        const y0 = winRect.y + this.D.fadeBottom[0] * winRect.h;\n        const gb = cctx.createLinearGradient(0, y0, 0, winRect.y + winRect.h);\n        gb.addColorStop(0, 'rgba(255,255,255,0)');\n        gb.addColorStop(Math.min(0.999, (this.D.fadeBottom[1] - this.D.fadeBottom[0]) / (1 - this.D.fadeBottom[0])), 'rgba(255,255,255,0.92)');\n        gb.addColorStop(1, 'rgba(255,255,255,1)');\n        cctx.fillStyle = gb;\n        cctx.fillRect(winRect.x, y0, winRect.w, winRect.h - this.D.fadeBottom[0] * winRect.h);\n      }\n      if (this.D && this.D.asset) {\n        const bg = await this.loadDesignBg();\n        if (bg) cctx.drawImage(bg, winRect.x, winRect.y, winRect.w, winRect.h);\n      }\n      if (frame) cctx.drawImage(frame.img, 0, 0, dispW, dispH);\n      chrome.hidden = false;\n      this._lmLayout = {\n        dispW: dispW,\n        dispH: dispH,\n        mapX: winRect.x + mf.x0 * winRect.w,\n        mapY: winRect.y + mf.y0 * winRect.h,\n        mapW: (mf.x1 - mf.x0) * winRect.w,\n        mapH: (mf.y1 - mf.y0) * winRect.h\n      };\n      if (this._liveMap) {\n        try { this._liveMap.resize(); } catch (e) { /* ignorieren */ }\n      }\n    }\n\n    /* ---------- Mobile Mini-Vorschau (fixiert beim Scrollen) ---------- */\n    setupMiniPreview() {\n      if (!this.inline || this._mini) return;\n      const mini = document.createElement('div');\n      mini.className = 'mc-mini';\n      mini.hidden = true;\n      const c = document.createElement('canvas');\n      mini.appendChild(c);\n      document.body.appendChild(mini);\n      this._mini = mini;\n      this._miniCanvas = c;\n      this._miniVisible = false;\n      const onScroll = () => {\n        if (window.innerWidth >= 750) {\n          if (this._miniVisible) { this._miniVisible = false; mini.hidden = true; }\n          return;\n        }\n        const pr = this.previewRoot.getBoundingClientRect();\n        const formR = this.getBoundingClientRect();\n        const show = pr.bottom < 90 && formR.bottom > 180;\n        if (show !== this._miniVisible) {\n          this._miniVisible = show;\n          mini.hidden = !show;\n          if (show) {\n            let top = 0;\n            const header = document.querySelector('.shopify-section-header, sticky-header, .section-header');\n            if (header) {\n              const hr = header.getBoundingClientRect();\n              if (hr.top <= 1 && hr.bottom > 0 && hr.bottom < 180) top = hr.bottom;\n            }\n            mini.style.top = top + 'px';\n            this.copyToMini();\n          }\n        }\n      };\n      window.addEventListener('scroll', onScroll, { passive: true });\n      window.addEventListener('resize', onScroll, { passive: true });\n      onScroll();\n      // W\u00E4hrend des Flugs live in die Mini-Vorschau spiegeln\n      const hookRender = () => {\n        if (this._liveMap) {\n          this._liveMap.on('render', () => this.copyToMini());\n        } else if (!this._liveMapFailed) {\n          setTimeout(hookRender, 1200);\n        }\n      };\n      hookRender();\n    }\n\n    copyToMini() {\n      if (!this._miniVisible || !this._miniCanvas) return;\n      const cvs = this._miniCanvas;\n      const pc = this.previewCanvas;\n      const lay = this._lmLayout;\n      const dpr = Math.min(window.devicePixelRatio || 1, 2);\n      const hasPoster = this.previewRoot.classList.contains('has-preview')\n        && !this.previewRoot.classList.contains('is-flying') && pc.width > 20;\n      const ph = this.previewRoot.querySelector('.mc-preview__placeholder');\n      let srcW, srcH;\n      if (hasPoster) { srcW = pc.width; srcH = pc.height; }\n      else if (lay && this._liveMap) { srcW = lay.dispW; srcH = lay.dispH; }\n      else if (ph && !ph.hidden && ph.complete && ph.naturalWidth) { srcW = ph.naturalWidth; srcH = ph.naturalHeight; }\n      else return;\n      const cssW = Math.min((window.innerWidth || 375) * 0.62, 280);\n      const cssH = cssW * (srcH / srcW);\n      cvs.width = Math.round(cssW * dpr);\n      cvs.height = Math.round(cssH * dpr);\n      cvs.style.width = cssW + 'px';\n      cvs.style.height = cssH + 'px';\n      const x = cvs.getContext('2d');\n      x.imageSmoothingEnabled = true;\n      x.imageSmoothingQuality = 'high';\n      if (hasPoster) {\n        x.drawImage(pc, 0, 0, cvs.width, cvs.height);\n        return;\n      }\n      if (lay && this._liveMap) {\n        const s = cvs.width / lay.dispW;\n        try {\n          const mapCvs = this._liveMap.getCanvas();\n          if (mapCvs && mapCvs.width) x.drawImage(mapCvs, lay.mapX * s, lay.mapY * s, lay.mapW * s, lay.mapH * s);\n        } catch (e) { /* ignorieren */ }\n        const chrome = this.previewRoot.querySelector('.mc-preview__chrome');\n        if (chrome && chrome.width) x.drawImage(chrome, 0, 0, cvs.width, cvs.height);\n        return;\n      }\n      x.drawImage(ph, 0, 0, cvs.width, cvs.height);\n    }\n\n    async initLiveMap() {\n      if (this.D && this.D.hasMap === false) return;\n      if (this._liveMap || this._liveMapFailed) return;\n      const holder = this.previewRoot.querySelector('.mc-preview__livemap');\n      if (!holder) return;\n      try {\n        await loadMapLibre();\n        const styleArg = await this.getStyleArg();\n        const ph = this.previewRoot.querySelector('.mc-preview__placeholder');\n        if (ph) ph.hidden = true;\n        await this.layoutLiveMap();\n        holder.hidden = false;\n        this._liveMap = new maplibregl.Map({\n          container: holder,\n          style: styleArg,\n          center: [10.4, 51.1],\n          zoom: 4.6,\n          interactive: false,\n          attributionControl: false,\n          fadeDuration: 300,\n          preserveDrawingBuffer: true\n        });\n        this._liveMapStyle = this.cfg.styleId;\n      } catch (e) {\n        this._liveMapFailed = true;\n        if (holder) holder.hidden = true;\n        const chrome = this.previewRoot.querySelector('.mc-preview__chrome');\n        if (chrome) chrome.hidden = true;\n        const ph = this.previewRoot.querySelector('.mc-preview__placeholder');\n        if (ph) ph.hidden = false;\n      }\n    }\n\n    /* Zum Streckenort fliegen, danach Poster rendern und einblenden */\n    animateToTrack() {\n      const t = this.track;\n      if (!t || !this._liveMap) {\n        this.queuePreview(true);\n        return;\n      }\n      if (this._liveMapStyle !== this.cfg.styleId) {\n        this._liveMapStyle = this.cfg.styleId;\n        this.getStyleArg().then((s) => { try { this._liveMap.setStyle(s); } catch (e) { /* ignorieren */ } });\n      }\n      const b = t.bounds;\n      const holder = this.previewRoot.querySelector('.mc-preview__livemap');\n      const wpx = Math.max(80, holder.clientWidth);\n      const hpx = Math.max(80, holder.clientHeight);\n      const spanX = Math.max(b.wxMax - b.wxMin, 1e-9);\n      const spanY = Math.max(b.wyMax - b.wyMin, 1e-9);\n      const zoom = Math.min(15, Math.log2(Math.min(wpx / spanX, hpx / spanY) / 512) - 0.45);\n      const cx = (b.wxMin + b.wxMax) / 2, cy = (b.wyMin + b.wyMax) / 2;\n      const lon = cx * 360 - 180;\n      const lat = Math.atan(Math.sinh(Math.PI * (1 - 2 * cy))) * 180 / Math.PI;\n\n      this.previewRoot.classList.add('is-flying');\n      let done = false;\n      const finish = () => {\n        if (done) return;\n        done = true;\n        if (this._flyT) clearTimeout(this._flyT);\n        Promise.resolve(this.renderPreview()).then(() => {\n          this.previewRoot.classList.remove('is-flying');\n          this.copyToMini(); // Mini-Vorschau nach Flugende auf das fertige Poster aktualisieren\n        });\n      };\n      try {\n        const reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n        if (reduce) {\n          this._liveMap.jumpTo({ center: [lon, lat], zoom: zoom });\n          setTimeout(finish, 250);\n        } else {\n          this._liveMap.once('moveend', finish);\n          this._liveMap.flyTo({ center: [lon, lat], zoom: zoom, speed: 1.9, curve: 1.4, essential: true });\n          this._flyT = setTimeout(finish, 6000); // Fallback, falls moveend ausbleibt\n        }\n      } catch (e) {\n        finish();\n      }\n    }\n\n    /* ---------- Karte rendern ---------- */\n    mapWindow(posterW, posterH) {\n      return {\n        x: L.mapX0 * posterW,\n        y: L.mapY0 * posterH,\n        w: (L.mapX1 - L.mapX0) * posterW,\n        h: (L.mapY1 - L.mapY0) * posterH\n      };\n    }\n\n    /* Rendert die Karte f\u00FCr gegebene Fenstergr\u00F6\u00DFe (px) und Ziel-Streckengr\u00F6\u00DFe (px).\n       Liefert {canvas, project(fn world\u2192px im Fenster)} */\n    async renderMap(winW, winH, trackPx) {\n      await loadMapLibre();\n      const t = this.track;\n      const b = t.bounds;\n      const cx = (b.wxMin + b.wxMax) / 2;\n      const cy = (b.wyMin + b.wyMax) / 2;\n      const spanW = Math.max(b.wxMax - b.wxMin, 1e-12);\n      const spanH = Math.max(b.wyMax - b.wyMin, 1e-12);\n      const span = Math.max(spanW, spanH);\n      // Weltgr\u00F6\u00DFe (px) so, dass die l\u00E4ngste Bbox-Seite exakt trackPx entspricht\n      const worldPx = trackPx / span;\n      const zoom = Math.log2(worldPx / 512);\n\n      const holder = document.createElement('div');\n      holder.style.cssText = 'position:fixed;left:-100000px;top:0;width:' + winW + 'px;height:' + winH + 'px;';\n      document.body.appendChild(holder);\n\n      const styleArg = await this.getStyleArg();\n\n      return new Promise((resolve, reject) => {\n        let done = false;\n        const map = new maplibregl.Map({\n          container: holder,\n          style: styleArg,\n          interactive: false,\n          attributionControl: false,\n          pixelRatio: 1,\n          fadeDuration: 0,\n          preserveDrawingBuffer: true\n        });\n        // Zentrum aus Weltkoordinaten\n        const lon = cx * 360 - 180;\n        const lat = Math.atan(Math.sinh(Math.PI * (1 - 2 * cy))) * 180 / Math.PI;\n        map.jumpTo({ center: [lon, lat], zoom: zoom });\n\n        const finish = () => {\n          if (done) return;\n          done = true;\n          try {\n            const src = map.getCanvas();\n            const out = document.createElement('canvas');\n            out.width = winW;\n            out.height = winH;\n            const octx = out.getContext('2d');\n            octx.drawImage(src, 0, 0, winW, winH);\n            // Leere Karte (nichts gerendert) nicht als Erfolg werten\n            const probe = octx.getImageData(0, 0, Math.min(winW, 50), Math.min(winH, 50)).data;\n            let opaque = false;\n            for (let i = 3; i < probe.length; i += 16) {\n              if (probe[i] > 0) { opaque = true; break; }\n            }\n            if (!opaque) throw new Error('Karte konnte nicht geladen werden. Bitte versuche es erneut.');\n            map.remove();\n            holder.remove();\n            const project = (wx, wy) => ({\n              x: winW / 2 + (wx - cx) * worldPx,\n              y: winH / 2 + (wy - cy) * worldPx\n            });\n            resolve({ canvas: out, project: project });\n          } catch (err) {\n            map.remove(); holder.remove();\n            reject(err);\n          }\n        };\n        map.on('idle', finish);\n        map.on('error', (e) => {\n          // Stil-/Tile-Fehler nicht fatal behandeln, solange gerendert wird\n          if (e && e.error && /style/i.test(String(e.error.message || ''))) {\n            if (!done) { done = true; map.remove(); holder.remove(); reject(new Error('Kartenstil konnte nicht geladen werden.')); }\n          }\n        });\n        setTimeout(finish, 15000); // Fallback\n      });\n    }\n\n    /* ---------- SVG-Design: statischer Hintergrund ---------- */\n    loadDesignBg() {\n      this._designBgs = this._designBgs || {};\n      const key = this.D.asset;\n      if (this._designBgs[key] !== undefined) return Promise.resolve(this._designBgs[key]);\n      const url = this.cfg.designAssets && this.cfg.designAssets[key];\n      if (!url) { this._designBgs[key] = null; return Promise.resolve(null); }\n      return new Promise((resolve) => {\n        const img = new Image();\n        img.crossOrigin = 'anonymous';\n        img.onload = () => { this._designBgs[key] = img; resolve(img); };\n        img.onerror = () => { this._designBgs[key] = null; resolve(null); };\n        img.src = url;\n      });\n    }\n\n    /* ---------- SVG-Design komponieren (kartenlos) ---------- */\n    async composeSvgDesign(scale, fx3d) {\n      const S = SIZES[this.currentSize()];\n      const D = this.D;\n      const W = Math.round(S.wMm * PX_PER_MM * scale);\n      const H = Math.round(S.hMm * PX_PER_MM * scale);\n      const canvas = document.createElement('canvas');\n      canvas.width = W;\n      canvas.height = H;\n      const ctx = canvas.getContext('2d');\n      ctx.imageSmoothingEnabled = true;\n      ctx.imageSmoothingQuality = 'high';\n\n      const t = this.track;\n      const b = t.bounds;\n      const span = Math.max(b.wxMax - b.wxMin, b.wyMax - b.wyMin) || 1e-9;\n      const lineMm = parseFloat(this.cfg.trackMm) || L.trackPrintMm;\n      const trackPx = (S.trackMm - lineMm) * PX_PER_MM * scale;\n\n      // Hintergrund: vollfl\u00E4chige Karte (mapFull) oder Farbfl\u00E4che\n      let mapR = null;\n      if (D.mapFull) {\n        const cacheKey = this.designKey + ':' + this.currentSize() + ':' + W + ':' + this.cfg.styleId + ':' + lineMm;\n        if (!this._mapCache || this._mapCache.key !== cacheKey) {\n          this.setStatus('Karte wird geladen \u2026');\n          const rendered = await this.renderMap(W, H, trackPx);\n          this._mapCache = { key: cacheKey, map: rendered };\n          this.setStatus('');\n        }\n        mapR = this._mapCache.map;\n        ctx.drawImage(mapR.canvas, 0, 0);\n        // Wei\u00DF-Verl\u00E4ufe oben/unten f\u00FCr lesbare Textzonen\n        if (D.fadeTop) {\n          const gt = ctx.createLinearGradient(0, 0, 0, D.fadeTop[1] * H);\n          gt.addColorStop(0, 'rgba(255,255,255,1)');\n          gt.addColorStop(Math.min(0.999, D.fadeTop[0] / D.fadeTop[1]), 'rgba(255,255,255,0.92)');\n          gt.addColorStop(1, 'rgba(255,255,255,0)');\n          ctx.fillStyle = gt;\n          ctx.fillRect(0, 0, W, D.fadeTop[1] * H);\n        }\n        if (D.fadeBottom) {\n          const gb = ctx.createLinearGradient(0, D.fadeBottom[0] * H, 0, H);\n          gb.addColorStop(0, 'rgba(255,255,255,0)');\n          gb.addColorStop(Math.min(0.999, (D.fadeBottom[1] - D.fadeBottom[0]) / (1 - D.fadeBottom[0])), 'rgba(255,255,255,0.92)');\n          gb.addColorStop(1, 'rgba(255,255,255,1)');\n          ctx.fillStyle = gb;\n          ctx.fillRect(0, D.fadeBottom[0] * H, W, H - D.fadeBottom[0] * H);\n        }\n      } else {\n        ctx.fillStyle = D.bg || '#ffffff';\n        ctx.fillRect(0, 0, W, H);\n      }\n      const bgImg = await this.loadDesignBg();\n      if (bgImg) ctx.drawImage(bgImg, 0, 0, W, H);\n\n      // Strecke (gleiche Skala wie STL: Mittellinie + Band = trackMm)\n      const pxPerWorld = trackPx / span;\n      const cxw = (b.wxMin + b.wxMax) / 2, cyw = (b.wyMin + b.wyMax) / 2;\n      const tcx = D.track.cx * W, tcy = D.track.cy * H;\n      const toXY = mapR\n        ? (p) => mapR.project(p.wx, p.wy)\n        : (p) => ({ x: tcx + (p.wx - cxw) * pxPerWorld, y: tcy + (p.wy - cyw) * pxPerWorld });\n      const lw = lineMm * PX_PER_MM * scale;\n      const tracePath = () => {\n        ctx.beginPath();\n        t.pts.forEach((p, i) => {\n          const c = toXY(p);\n          if (i === 0 || p.segStart) ctx.moveTo(c.x, c.y);\n          else ctx.lineTo(c.x, c.y);\n        });\n      };\n      ctx.lineJoin = 'round';\n      ctx.lineCap = 'round';\n      ctx.strokeStyle = L.trackColor;\n      ctx.lineWidth = lw;\n      if (fx3d) {\n        ctx.save();\n        ctx.shadowColor = 'rgba(10, 14, 20, 0.45)';\n        ctx.shadowBlur = lw * 0.9;\n        ctx.shadowOffsetX = lw * 0.3;\n        ctx.shadowOffsetY = lw * 0.55;\n        tracePath();\n        ctx.stroke();\n        ctx.restore();\n        tracePath();\n        ctx.stroke();\n        ctx.save();\n        ctx.translate(-lw * 0.1, -lw * 0.16);\n        ctx.strokeStyle = 'rgba(255, 255, 255, 0.12)';\n        ctx.lineWidth = lw * 0.28;\n        tracePath();\n        ctx.stroke();\n        ctx.restore();\n        ctx.strokeStyle = L.trackColor;\n        ctx.lineWidth = lw;\n      } else {\n        tracePath();\n        ctx.stroke();\n      }\n\n      // Dynamische Texte \u2014 leere Felder zeigen die Beispieltexte des Designs\n      const g = (n) => (this.form.querySelector('[name=\"' + n + '\"]') || { value: '' }).value.trim();\n      const gv = (n) => g(n) || ((D.fields && D.fields[n] && D.fields[n].sample) || '');\n      const event = gv('event') || 'Marathon';\n      const words = event.split(/\\s+/);\n      const centerLon = cxw * 360 - 180;\n      const centerLat = Math.atan(Math.sinh(Math.PI * (1 - 2 * cyw))) * 180 / Math.PI;\n      const values = {\n        bezeichnung: gv('bezeichnung'),\n        event1: words.length > 1 ? words[0] : event,\n        event2: words.length > 1 ? words.slice(1).join(' ') : '',\n        nummer: gv('nummer'),\n        coord1: fmtCoord(centerLat, true),\n        coord2: fmtCoord(centerLon, false),\n        datum: gv('datum'),\n        distance: (t.distanceM / 1000).toFixed(3) + ' km',\n        zeit: gv('zeit'),\n        name: gv('name')\n      };\n      const font = D.font || MONO_FONT;\n      (D.texts || []).forEach((el) => {\n        let txt = values[el.src] || '';\n        if (el.upper) txt = txt.toUpperCase();\n        if (!txt) return;\n        drawTextLS(ctx, txt, el.x * W, el.y * H, el.size * W, el.ls || 0, el.weight || 400, font, el.color || '#000000', el.align, el.maxW ? el.maxW * W : 0);\n      });\n      return canvas;\n    }\n\n    /* ---------- Poster komponieren ---------- */\n    async compose(scale, fx3d) {\n      if (this.D && this.D.asset) return this.composeSvgDesign(scale, fx3d);\n      const sizeKey = this.currentSize();\n      const S = SIZES[sizeKey];\n      const posterW = Math.round(S.wMm * PX_PER_MM * scale);\n      const posterH = Math.round(S.hMm * PX_PER_MM * scale);\n      const win = this.mapWindow(posterW, posterH);\n      // Mittellinie so skalieren, dass Strecke inkl. Bandbreite max. trackMm misst\n      const lineMm = parseFloat(this.cfg.trackMm) || L.trackPrintMm;\n      const trackPx = (S.trackMm - lineMm) * PX_PER_MM * scale;\n\n      const cacheKey = sizeKey + ':' + Math.round(posterW) + ':' + this.cfg.styleId + ':' + lineMm;\n      if (!this._mapCache || this._mapCache.key !== cacheKey) {\n        this.setStatus('Karte wird geladen \u2026');\n        const rendered = await this.renderMap(Math.round(win.w), Math.round(win.h), trackPx);\n        this._mapCache = { key: cacheKey, map: rendered };\n        this.setStatus(this.track.hasEle ? '' : 'Hinweis: GPX ohne H\u00F6hendaten \u2014 3D-Strecke wird mit einheitlicher H\u00F6he erstellt.');\n      }\n      const mapR = this._mapCache.map;\n\n      const canvas = document.createElement('canvas');\n      canvas.width = posterW;\n      canvas.height = posterH;\n      const ctx = canvas.getContext('2d');\n\n      // Hintergrund + Karte\n      ctx.fillStyle = '#ffffff';\n      ctx.fillRect(0, 0, posterW, posterH);\n      ctx.drawImage(mapR.canvas, win.x, win.y);\n\n      // Strecke zeichnen (exakt registriert \u00FCber dieselbe Projektion)\n      const pts = this.track.pts;\n      ctx.save();\n      ctx.beginPath();\n      ctx.rect(win.x, win.y, win.w, win.h);\n      ctx.clip();\n      const lw = lineMm * PX_PER_MM * scale;\n      const tracePath = () => {\n        ctx.beginPath();\n        pts.forEach((p, i) => {\n          const c = mapR.project(p.wx, p.wy);\n          const x = win.x + c.x, y = win.y + c.y;\n          if (i === 0 || p.segStart) ctx.moveTo(x, y);\n          else ctx.lineTo(x, y);\n        });\n      };\n      ctx.lineJoin = 'round';\n      ctx.lineCap = 'round';\n      ctx.strokeStyle = L.trackColor;\n      ctx.lineWidth = lw;\n      if (fx3d) {\n        // 3D-Druck-Optik (nur Vorschau): weicher Schlagschatten + dezente Oberkante\n        ctx.save();\n        ctx.shadowColor = 'rgba(10, 14, 20, 0.45)';\n        ctx.shadowBlur = lw * 0.9;\n        ctx.shadowOffsetX = lw * 0.30;\n        ctx.shadowOffsetY = lw * 0.55;\n        tracePath();\n        ctx.stroke();\n        ctx.restore();\n        tracePath();\n        ctx.stroke();\n        ctx.save();\n        ctx.translate(-lw * 0.10, -lw * 0.16);\n        ctx.strokeStyle = 'rgba(255, 255, 255, 0.12)';\n        ctx.lineWidth = lw * 0.28;\n        tracePath();\n        ctx.stroke();\n        ctx.restore();\n      } else {\n        tracePath();\n        ctx.stroke();\n      }\n      // Start/Ziel-Marker\n      const mk = (p) => {\n        const c = mapR.project(p.wx, p.wy);\n        ctx.beginPath();\n        ctx.arc(win.x + c.x, win.y + c.y, lineMm * PX_PER_MM * scale * 0.75, 0, Math.PI * 2);\n        ctx.fillStyle = L.markerColor;\n        ctx.fill();\n        ctx.lineWidth = lineMm * PX_PER_MM * scale * 0.4;\n        ctx.strokeStyle = L.trackColor;\n        ctx.stroke();\n      };\n      mk(pts[0]);\n      mk(pts[pts.length - 1]);\n      ctx.restore();\n\n      // Texte\n      const g = (n) => (this.form.querySelector('[name=\"' + n + '\"]') || { value: '' }).value.trim();\n      const event = (g('event') || 'Marathon').toUpperCase();\n      const words = event.split(/\\s+/);\n      const line1 = words.length > 1 ? words[0] : event;\n      const line2 = words.length > 1 ? words.slice(1).join(' ') : '';\n      const W = posterW, H = posterH;\n\n      ctx.textBaseline = 'middle';\n      // Links: Datum + Event\n      ctx.textAlign = 'left';\n      if (g('datum')) {\n        ctx.font = '500 ' + L.dateSize * W + 'px ' + TEXT_FONT;\n        ctx.fillStyle = L.textMuted;\n        ctx.fillText(g('datum').toUpperCase(), L.mapX0 * W, L.dateY * H);\n      }\n      ctx.font = '700 ' + L.event1Size * W + 'px ' + TEXT_FONT;\n      ctx.fillStyle = L.textDark;\n      ctx.fillText(line1, L.mapX0 * W, L.event1Y * H);\n      if (line2) {\n        ctx.font = '500 ' + L.event2Size * W + 'px ' + TEXT_FONT;\n        ctx.fillText(line2, L.mapX0 * W, L.event2Y * H);\n      }\n      // Rechts: Nummer, Name, Pace, Zeit\n      ctx.textAlign = 'right';\n      const rx = L.mapX1 * W;\n      if (g('nummer')) {\n        ctx.font = '500 ' + L.numSize * W + 'px ' + TEXT_FONT;\n        ctx.fillStyle = L.textMuted;\n        ctx.fillText('#' + g('nummer'), rx, L.numY * H);\n      }\n      if (g('name')) {\n        ctx.font = '700 ' + L.nameSize * W + 'px ' + TEXT_FONT;\n        ctx.fillStyle = L.textDark;\n        ctx.fillText(g('name').toUpperCase(), rx, L.nameY * H);\n      }\n      if (g('pace')) {\n        ctx.font = '500 ' + L.paceSize * W + 'px ' + TEXT_FONT;\n        ctx.fillStyle = L.textMuted;\n        ctx.fillText('\u00D8 ' + g('pace') + ' MIN', rx, L.paceY * H);\n      }\n      if (g('zeit')) {\n        ctx.font = '700 ' + L.timeSize * W + 'px ' + TEXT_FONT;\n        ctx.fillStyle = L.textDark;\n        ctx.fillText(g('zeit').toUpperCase() + 'H', rx, L.timeY * H);\n      }\n      return canvas;\n    }\n\n    /* ---------- Rahmen-Overlay (nur Vorschau, nicht im Druck-PDF) ---------- */\n    loadFrame(sizeKey) {\n      this._frames = this._frames || {};\n      if (this._frames[sizeKey] !== undefined) return Promise.resolve(this._frames[sizeKey]);\n      const url = this.cfg.frames && this.cfg.frames[sizeKey];\n      if (!url) { this._frames[sizeKey] = null; return Promise.resolve(null); }\n      return new Promise((resolve) => {\n        const img = new Image();\n        img.crossOrigin = 'anonymous';\n        img.onload = () => {\n          try {\n            // Transparentes Fenster (Poster-Bereich) \u00FCber den Alphakanal finden\n            const c = document.createElement('canvas');\n            c.width = img.naturalWidth;\n            c.height = img.naturalHeight;\n            const x = c.getContext('2d');\n            x.drawImage(img, 0, 0);\n            const d = x.getImageData(0, 0, c.width, c.height).data;\n            let x0 = Infinity, y0 = Infinity, x1 = -1, y1 = -1;\n            for (let yy = 0; yy < c.height; yy++) {\n              for (let xx = 0; xx < c.width; xx++) {\n                if (d[(yy * c.width + xx) * 4 + 3] < 16) {\n                  if (xx < x0) x0 = xx;\n                  if (xx > x1) x1 = xx;\n                  if (yy < y0) y0 = yy;\n                  if (yy > y1) y1 = yy;\n                }\n              }\n            }\n            const f = (x1 > x0 && y1 > y0)\n              ? { img: img, w: img.naturalWidth, h: img.naturalHeight, win: { x: x0, y: y0, w: x1 - x0 + 1, h: y1 - y0 + 1 } }\n              : null;\n            this._frames[sizeKey] = f;\n            resolve(f);\n          } catch (e) {\n            this._frames[sizeKey] = null;\n            resolve(null);\n          }\n        };\n        img.onerror = () => { this._frames[sizeKey] = null; resolve(null); };\n        img.src = url;\n      });\n    }\n\n    /* ---------- Vorschau ---------- */\n    queuePreview(mapChanged) {\n      if (mapChanged) this._mapCache = null;\n      if (this.renderQueued) return;\n      this.renderQueued = true;\n      setTimeout(() => { this.renderQueued = false; this.renderPreview(); }, 120);\n    }\n\n    async renderPreview() {\n      if (!this.track) return;\n      try {\n        await Promise.all([\n          document.fonts.load('700 100px Poppins'),\n          document.fonts.load('500 100px Poppins'),\n          document.fonts.load('400 100px \"Roboto Mono\"'),\n          document.fonts.load('500 100px \"Roboto Mono\"'),\n          document.fonts.load('700 100px \"Roboto Mono\"')\n        ]).catch(() => {});\n        const S = SIZES[this.currentSize()];\n        const holder = this.previewCanvas.parentElement;\n        if (!this._previewBox || this._previewBox.fallback) {\n          const cs = getComputedStyle(holder);\n          const bw = holder.clientWidth - parseFloat(cs.paddingLeft) - parseFloat(cs.paddingRight);\n          const bh = holder.clientHeight - parseFloat(cs.paddingTop) - parseFloat(cs.paddingBottom);\n          if (bw >= 50 && bh >= 50) {\n            this._previewBox = { w: bw, h: bh, fallback: false };\n            this._measureTries = 0;\n          } else if (!this._previewBox) {\n            if ((this._measureTries || 0) < 10) {\n              // Modal noch nicht gelayoutet \u2192 kurz warten und erneut messen\n              this._measureTries = (this._measureTries || 0) + 1;\n              setTimeout(() => this.renderPreview(), 150);\n              return;\n            }\n            // Notl\u00F6sung; wird beim n\u00E4chsten Render durch echte Messung ersetzt\n            this._previewBox = { w: Math.max(100, bw), h: Math.max(100, bh), fallback: true };\n            this._measureTries = 0;\n          }\n        }\n        // 1,5-faches Supersampling f\u00FCr eine knackige Vorschau (max. 3x)\n        const dpr = Math.min((window.devicePixelRatio || 1) * 1.5, 3);\n        const frame = await this.loadFrame(this.currentSize());\n        if (frame) {\n          // Poster im Rahmen: Rahmen einpassen, Poster ins transparente Fenster legen\n          const fitF = Math.min(this._previewBox.w / frame.w, this._previewBox.h / frame.h);\n          const dispW = Math.round(frame.w * fitF * dpr);\n          const dispH = Math.round(frame.h * fitF * dpr);\n          const wx = frame.win.x / frame.w * dispW;\n          const wy = frame.win.y / frame.h * dispH;\n          const ww = frame.win.w / frame.w * dispW;\n          const wh = frame.win.h / frame.h * dispH;\n          const poster = await this.compose(ww / (S.wMm * PX_PER_MM), true);\n          this.previewCanvas.width = dispW;\n          this.previewCanvas.height = dispH;\n          const pctx = this.previewCanvas.getContext('2d');\n          pctx.imageSmoothingEnabled = true;\n          pctx.imageSmoothingQuality = 'high';\n          pctx.clearRect(0, 0, dispW, dispH);\n          pctx.drawImage(poster, wx, wy, ww, wh);\n          pctx.drawImage(frame.img, 0, 0, dispW, dispH);\n          this.previewCanvas.style.width = Math.round(dispW / dpr) + 'px';\n          this.previewCanvas.style.height = Math.round(dispH / dpr) + 'px';\n        } else {\n          const fit = Math.min(this._previewBox.w / S.wMm, this._previewBox.h / S.hMm); // CSS-px pro mm\n          const targetW = S.wMm * fit * dpr;             // Ziel-Canvas-Breite in px\n          const cScale = targetW / (S.wMm * PX_PER_MM);  // Skalierung gg\u00FC. Druckaufl\u00F6sung\n          const canvas = await this.compose(cScale, true);\n          this.previewCanvas.width = canvas.width;\n          this.previewCanvas.height = canvas.height;\n          this.previewCanvas.style.width = Math.round(canvas.width / dpr) + 'px';\n          this.previewCanvas.style.height = Math.round(canvas.height / dpr) + 'px';\n          const fctx = this.previewCanvas.getContext('2d');\n          fctx.imageSmoothingEnabled = true;\n          fctx.imageSmoothingQuality = 'high';\n          fctx.drawImage(canvas, 0, 0);\n        }\n        this.previewCanvas.parentElement.classList.add('has-preview');\n        const empty = this.previewRoot.querySelector('.mc-preview__empty');\n        if (empty) empty.hidden = true;\n        this.copyToMini();\n      } catch (err) {\n        console.error('[MC] Vorschau:', err);\n        this.showError(err.message || 'Vorschau fehlgeschlagen.');\n      }\n    }\n\n    /* ---------- Modal ---------- */\n    openModal() {\n      if (this.inline) return;\n      this.modal.classList.add('is-open');\n      document.body.classList.add('mc-modal-open');\n      this._previewBox = null;\n      this.showError('');\n      this.initLiveMap();\n      if (this._liveMap) setTimeout(() => { try { this._liveMap.resize(); } catch (e) {} }, 80);\n      if (this.track) this.queuePreview(false);\n    }\n\n    closeModal() {\n      if (this.inline) return;\n      this.modal.classList.remove('is-open');\n      document.body.classList.remove('mc-modal-open');\n    }\n\n    setStatus(msg) {\n      if (this.statusEl) {\n        this.statusEl.textContent = msg || '';\n        this.statusEl.hidden = !msg;\n      }\n    }\n\n    showError(msg) {\n      this.errorEl.textContent = msg || '';\n      this.errorEl.hidden = !msg;\n    }\n\n    setLoading(on, label) {\n      this.submitBtn.disabled = on;\n      this.submitBtn.classList.toggle('is-loading', on);\n      const span = this.submitBtn.querySelector('span');\n      if (span) {\n        if (on) {\n          if (!this.submitBtn.dataset.label) this.submitBtn.dataset.label = span.textContent;\n          span.textContent = label || 'Wird erstellt \u2026';\n        } else if (this.submitBtn.dataset.label) {\n          span.textContent = this.submitBtn.dataset.label;\n        }\n      }\n    }\n\n    /* ---------- STL erzeugen (ein Teil je Segment) ---------- */\n    makeStls() {\n      const t = this.track;\n      const S = SIZES[this.currentSize()];\n      const b = t.bounds;\n      const spanW = Math.max(b.wxMax - b.wxMin, 1e-12);\n      const spanH = Math.max(b.wyMax - b.wyMin, 1e-12);\n      const span = Math.max(spanW, spanH);\n      // Bandbreite = eingestellte Druck-Linienbreite (Poster und 3D-Druck identisch);\n      // Mittellinie + halbe Bandbreite je Seite = exakt S.trackMm Au\u00DFenma\u00DF\n      const lineMm = parseFloat(this.cfg.trackMm) || L.trackPrintMm;\n      const mmPerWorld = (S.trackMm - lineMm) / span;\n\n      // Globale H\u00F6henskala \u00FCber alle Segmente mit H\u00F6hendaten\n      const segs = t.segs || [{ pts: t.pts, eles: t.eles, hasEle: t.hasEle }];\n      let mn = Infinity, mx = -Infinity;\n      segs.forEach((s) => { if (s.eles) s.eles.forEach((e) => { mn = Math.min(mn, e); mx = Math.max(mx, e); }); });\n      const range = Math.max(mx - mn, 0.001);\n\n      // Ein STL je Segment \u2014 gleiche mm-Skala wie das gedruckte Poster,\n      // einzelne Teile d\u00FCrfen daher kleiner als das 170/210-mm-Ma\u00DF sein\n      return segs.map((s) => {\n        const pts2d = s.pts.map((p) => ({\n          x: (p.wx - b.wxMin) * mmPerWorld,\n          y: (b.wyMax - p.wy) * mmPerWorld\n        }));\n        const tops = s.eles\n          ? s.eles.map((e) => STL.minHMm + ((e - mn) / range) * (STL.maxHMm - STL.minHMm))\n          : s.pts.map(() => STL.flatHMm);\n        return buildStl(pts2d, tops, lineMm);\n      });\n    }\n\n    makeStl() {\n      // Kompatibilit\u00E4t: erstes (bei Einzelstrecke: einziges) Teil\n      return this.makeStls()[0];\n    }\n\n    /* ---------- Add to Cart ---------- */\n    async addToCart() {\n      this.showError('');\n      const g = (n) => (this.form.querySelector('[name=\"' + n + '\"]') || { value: '' }).value.trim();\n      if (!this.track) { this.showError('Bitte lade zuerst eine GPX-Datei hoch oder w\u00E4hle einen Marathon.'); return; }\n      if (!g('name')) { this.showError('Bitte gib deinen Namen ein.'); return; }\n      if (!g('event')) { this.showError('Bitte gib den Event-Namen ein.'); return; }\n      const variantId = this.currentVariantId();\n      if (!variantId) { this.showError('Keine Variante gew\u00E4hlt.'); return; }\n\n      this.setLoading(true, 'Poster wird erstellt \u2026');\n      try {\n        // 1) Finales Poster in Druckaufl\u00F6sung\n        this._mapCache = null; // Druckaufl\u00F6sung frisch rendern\n        const canvas = await this.compose(1);\n        const jpegBlob = await new Promise((res) => canvas.toBlob(res, 'image/jpeg', 0.92));\n        if (!jpegBlob) throw new Error('Poster konnte nicht erzeugt werden.');\n        const pdfBlob = buildPdf(new Uint8Array(await jpegBlob.arrayBuffer()), canvas.width, canvas.height, PDF_DPI);\n\n        // 2) STL (bei Triathlon: ein Teil je Segment)\n        this.setLoading(true, '3D-Strecke wird erstellt \u2026');\n        const stlBlobs = this.makeStls();\n\n        // 3) Uploads\n        this.setLoading(true, 'Wird hochgeladen \u2026');\n        const rand = Math.random().toString(36).slice(2, 8);\n        const ts = Date.now();\n        const base = 'marathon-' + ts + '-' + rand;\n        const pdfName = 'marathon/pdf/' + base + '.pdf';\n        const up = async (path, blob, type) => {\n          const res = await fetch(this.cfg.supabaseUrl + '/storage/v1/object/' + this.cfg.bucket + '/' + path, {\n            method: 'POST',\n            headers: {\n              'Authorization': 'Bearer ' + this.cfg.supabaseKey,\n              'apikey': this.cfg.supabaseKey,\n              'Content-Type': type\n            },\n            body: blob\n          });\n          if (!res.ok) {\n            const t = await res.text().catch(() => '');\n            throw new Error('Upload fehlgeschlagen (' + res.status + '). ' + t);\n          }\n          return this.cfg.supabaseUrl + '/storage/v1/object/public/' + this.cfg.bucket + '/' + path;\n        };\n        const pdfUrl = await up(pdfName, pdfBlob, 'application/pdf');\n        const stlUrls = [];\n        for (let i = 0; i < stlBlobs.length; i++) {\n          const suffix = stlBlobs.length > 1 ? '-teil' + (i + 1) : '';\n          stlUrls.push(await up('marathon/stl/' + base + suffix + '.stl', stlBlobs[i], 'application/octet-stream'));\n        }\n        const gpxUrls = [];\n        const gpxTexts = this.gpxTexts || (this.gpxText ? [this.gpxText] : []);\n        for (let i = 0; i < gpxTexts.length; i++) {\n          const suffix = gpxTexts.length > 1 ? '-teil' + (i + 1) : '';\n          gpxUrls.push(await up('marathon/gpx/' + base + suffix + '.gpx', new Blob([gpxTexts[i]], { type: 'application/gpx+xml' }), 'application/gpx+xml'));\n        }\n\n        // 4) Warenkorb\n        this.setLoading(true, 'Wird hinzugef\u00FCgt \u2026');\n        const qtyInput = document.querySelector('form[id^=\"product-form\"] input[name=\"quantity\"], input[id^=\"Quantity-\"]');\n        const qty = Math.max(1, parseInt(qtyInput && qtyInput.value, 10) || 1);\n        const cart = document.querySelector('cart-drawer');\n        const sections = cart && cart.getSectionsToRender\n          ? cart.getSectionsToRender().map((s) => s.id)\n          : ['cart-drawer', 'cart-icon-bubble'];\n\n        const res = await fetch((window.routes && window.routes.cart_add_url ? window.routes.cart_add_url : '/cart/add') + '.js', {\n          method: 'POST',\n          headers: {\n            'Content-Type': 'application/json',\n            'Accept': 'application/javascript',\n            'X-Requested-With': 'XMLHttpRequest'\n          },\n          body: JSON.stringify({\n            items: [{\n              id: parseInt(variantId, 10),\n              quantity: qty,\n              properties: (function () {\n                const props = {\n                  'Name': g('name').toUpperCase(),\n                  'Event': g('event'),\n                  '_Perso-PDF': pdfUrl\n                };\n                stlUrls.forEach((u, i) => { props['_Perso-STL' + (i ? '-' + (i + 1) : '')] = u; });\n                gpxUrls.forEach((u, i) => { props['_Perso-GPX' + (i ? '-' + (i + 1) : '')] = u; });\n                return props;\n              })()\n            }],\n            sections: sections,\n            sections_url: window.location.pathname\n          })\n        });\n        const data = await res.json();\n        if (!res.ok || data.status) {\n          throw new Error(data.description || data.message || 'Konnte nicht in den Warenkorb gelegt werden.');\n        }\n\n        this.closeModal();\n        if (cart && cart.renderContents && data.sections) {\n          cart.renderContents(data);\n        } else if (typeof publish === 'function' && typeof PUB_SUB_EVENTS !== 'undefined') {\n          publish(PUB_SUB_EVENTS.cartUpdate, { source: 'marathon-configurator' });\n        }\n      } catch (err) {\n        console.error('[MC] Fehler:', err);\n        this.showError(err.message || 'Etwas ist schiefgelaufen. Bitte erneut versuchen.');\n      } finally {\n        this.setLoading(false);\n      }\n    }\n  }\n\n  customElements.define('marathon-configurator', MarathonConfigurator);\n})();\n"],
  "mappings": "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",
  "names": ["w", "res"]
}
