<!DOCTYPE html>
<html lang="{{HTML_LANG}}">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  {{BOOTSTRAP_CSS}}
  <style>{{DIALOG_CSS}}</style>
  <style>
    .marking-profile-preview-box {
      height: 168px;
      background: #f8fafc;
    }
    .marking-profile-preview-box svg {
      display: block;
      width: 100%;
      height: 160px;
    }
    .marking-profile-preview-box polygon {
      fill: rgba(37, 99, 235, 0.12);
      stroke: #2563eb;
      stroke-width: 1.5;
      vector-effect: non-scaling-stroke;
    }
    .marking-preset-thumb {
      width: 44px;
      height: 44px;
      flex-shrink: 0;
      background: #f8fafc;
      border-radius: 4px;
    }
    .marking-preset-thumb svg {
      display: block;
      width: 44px;
      height: 44px;
    }
    .marking-preset-thumb polygon {
      fill: rgba(37, 99, 235, 0.15);
      stroke: #2563eb;
      stroke-width: 1.2;
      vector-effect: non-scaling-stroke;
    }
  </style>
</head>
<body class="p-3">
  <div class="container-fluid">
    <div class="mb-2 d-flex justify-content-between align-items-start">
      <div>
        <h2 class="h6 mb-0">{{MARKING_SETTINGS_TITLE}}</h2>
        <p class="text-muted small mb-0">{{MARKING_SETTINGS_SUBTITLE}}</p>
      </div>
      <span id="marking-save-status" class="small text-success" style="min-width:60px;text-align:right;"></span>
    </div>

    <div class="card border mb-2">
      <div class="card-body py-2 px-3">
        <div class="unfold-section-title">{{MARKING_SETTINGS_MODE_SECTION}}</div>
        <div class="d-flex gap-3">
          <label class="form-check form-check-inline mb-0">
            <input class="form-check-input" type="radio" name="marking_mode" value="line" {{MARKING_MODE_LINE_CHECKED}}>
            <span class="form-check-label">{{MARKING_HUD_LINE}}</span>
          </label>
          <label class="form-check form-check-inline mb-0">
            <input class="form-check-input" type="radio" name="marking_mode" value="area" {{MARKING_MODE_AREA_CHECKED}}>
            <span class="form-check-label">{{MARKING_HUD_AREA}}</span>
          </label>
        </div>
      </div>
    </div>

    <div id="marking-profile-preview-wrap" class="card border mb-2 d-none">
      <div class="card-body py-2 px-3">
        <div class="unfold-section-title">{{MARKING_SETTINGS_PROFILE_PREVIEW}}</div>
        <div id="marking-profile-preview-box" class="marking-profile-preview-box border rounded d-flex align-items-center justify-content-center">
          <svg id="marking-profile-preview-svg" preserveAspectRatio="xMidYMid meet" aria-hidden="true"></svg>
        </div>
        <div id="marking-profile-size-row" class="row g-1 mt-2 align-items-end">
          <div class="col-5">
            <label class="form-label small mb-1">{{MARKING_SETTINGS_PROFILE_WIDTH}}</label>
            <input type="text" id="marking-profile-width-mm" class="form-control form-control-sm bg-light" readonly tabindex="-1">
          </div>
          <div class="col-2 d-flex justify-content-center">
            <button type="button" id="marking-swap-axes-btn" class="btn btn-sm btn-outline-secondary"
                    title="{{MARKING_SWAP_AXES}}" aria-label="{{MARKING_SWAP_AXES}}">&#8644;</button>
          </div>
          <div class="col-5">
            <label class="form-label small mb-1">{{MARKING_SETTINGS_PROFILE_HEIGHT}}</label>
            <input type="text" id="marking-profile-height-mm" class="form-control form-control-sm bg-light" readonly tabindex="-1">
          </div>
        </div>
        <p id="marking-profile-preview-hint" class="text-muted small mb-0 mt-2 d-none">{{MARKING_SETTINGS_PROFILE_PREVIEW_HINT}}</p>
      </div>
    </div>

    <div class="card border mb-2">
      <div class="card-body py-2 px-3">
        <div class="unfold-section-title">{{MARKING_SETTINGS_PARAMS_SECTION}}</div>
        <div class="row g-2">
          <div class="col-6 col-md-4 js-marking-hide-custom">
            <label class="form-label small mb-1">{{MARKING_HUD_OFFSET}}</label>
            <input type="number" step="0.1" min="0" class="form-control form-control-sm js-marking-num" data-marking-key="edge_end_offset_mm" value="{{EDGE_END_OFFSET_MM}}">
          </div>
          <div class="col-6 col-md-4 js-marking-area-field">
            <label class="form-label small mb-1">{{MARKING_HUD_WIDTH}}</label>
            <input type="number" step="0.1" min="0.1" class="form-control form-control-sm js-marking-num" data-marking-key="area_width_mm" value="{{AREA_WIDTH_MM}}">
          </div>
          <div class="col-12 js-marking-offset-line" id="marking-offsets-section">
            <label class="form-label small mb-1">{{MARKING_OFFSET_FROM_LINE}}</label>
            <div id="marking-offsets-list"></div>
            <button type="button" class="btn btn-sm btn-outline-secondary mt-1" id="marking-offset-add">+ {{MARKING_ADD_OFFSET}}</button>
          </div>
          <div class="col-6 col-md-4 js-marking-profile-locked-offset">
            <label class="form-label small mb-1">{{MARKING_PROFILE_OFFSET_LOCKED_LINE}}</label>
            <input type="number" step="0.1" class="form-control form-control-sm js-marking-num" data-marking-key="profile_offset_from_locked_line_mm" value="{{PROFILE_OFFSET_LOCKED_LINE_MM}}">
          </div>
          <div class="col-12 js-marking-hide-custom">
            <label class="form-check mb-0">
              <input type="checkbox" class="form-check-input" id="marking-preset-ring" {{MARKING_PRESET_RING_CHECKED}}>
              <span class="form-check-label small">{{MARKING_PRESET_RING}}</span>
            </label>
          </div>
          <div class="col-12">
            <label class="form-check mb-0">
              <input type="checkbox" class="form-check-input" id="marking-mark-back-face" {{MARKING_MARK_BACK_FACE_CHECKED}}>
              <span class="form-check-label small">{{MARKING_MARK_BACK_FACE}}</span>
            </label>
          </div>
          <div class="col-12 js-marking-line-layer">
            <label class="form-label small mb-1">{{MARKING_HUD_LAYER}}</label>
            <input type="text" class="form-control form-control-sm js-marking-str" data-marking-key="line_layer_name" value="{{LINE_LAYER_NAME}}">
          </div>
          <div class="col-12 js-marking-area-layer">
            <label class="form-label small mb-1">{{MARKING_HUD_LAYER}}</label>
            <input type="text" class="form-control form-control-sm js-marking-str" data-marking-key="area_layer_name" value="{{AREA_LAYER_NAME}}">
          </div>
        </div>
      </div>
    </div>

    <div class="card border mb-2">
      <div class="card-body py-2 px-3">
        <div class="unfold-section-title">{{MARKING_SETTINGS_PRESETS_SECTION}}</div>
        <p class="text-muted small mb-2">{{MARKING_SETTINGS_PRESETS_HINT}}</p>
        <div class="row g-2 mb-2">
          <div class="col-12">
            <label class="form-label small mb-1">{{MARKING_PRESET_NAME}}</label>
            <input type="text" id="marking-preset-name" class="form-control form-control-sm" value="{{ACTIVE_PRESET_NAME}}" placeholder="Groove_LED">
          </div>
        </div>
        <div class="d-flex flex-wrap gap-2 align-items-center">
          <button type="button" class="btn btn-sm btn-outline-secondary" id="marking-new-preset-btn">{{MARKING_NEW_PRESET}}</button>
          <button type="button" class="btn btn-sm btn-primary" id="marking-save-preset-btn">{{MARKING_SAVE_PRESET}}</button>
          <button type="button" class="btn btn-sm btn-outline-danger ms-auto" id="marking-reset-presets-btn">{{MARKING_RESET_PRESETS}}</button>
        </div>
        <div id="marking-preset-list" class="mt-3"></div>
      </div>
    </div>
  </div>
  <script>
  (function () {
    var GG_MARKING_STRINGS = {
      saved: {{MARKING_SAVED_JSON}},
      save_failed: {{MARKING_SAVE_FAILED_JSON}},
      preset_saved: {{MARKING_PRESET_SAVED_JSON}},
      delete: {{MARKING_DELETE_JSON}},
      reset_confirm: {{MARKING_RESET_CONFIRM_JSON}}
    };
    var PRESETS = {{MARKING_PRESETS_JSON}};
    var EDITING_PRESET_ID = {{ACTIVE_PRESET_ID_JSON}};
    var DEFAULT_PRESET_ID = {{MARKING_DEFAULT_PRESET_ID_JSON}};
    var BUILTIN_PRESET_IDS = {{MARKING_BUILTIN_PRESET_IDS_JSON}};
    function isBuiltinPreset(id) { return BUILTIN_PRESET_IDS.indexOf(id) !== -1; }
    var PROFILE_PREVIEW_PAD = 0.12;
    var OFFSETS_FROM_LINE_MM = {{OFFSETS_FROM_LINE_MM_JSON}};

    function renderOffsetRows(offsets) {
      var list = document.getElementById('marking-offsets-list');
      if (!list) return;
      list.innerHTML = '';
      offsets.forEach(function (val, i) {
        var row = document.createElement('div');
        row.className = 'd-flex align-items-center gap-1 mb-1';
        var inp = document.createElement('input');
        inp.type = 'number';
        inp.step = '0.1';
        inp.className = 'form-control form-control-sm';
        inp.dataset.offsetIndex = i;
        inp.value = val;
        inp.addEventListener('change', function () {
          OFFSETS_FROM_LINE_MM[i] = parseFloat(inp.value) || 0;
          sketchup.on_marking_setting_changed('offsets_from_line_mm[' + i + ']', inp.value);
          showStatus(true, 'saved');
        });
        row.appendChild(inp);
        if (offsets.length > 1) {
          var removeBtn = document.createElement('button');
          removeBtn.type = 'button';
          removeBtn.className = 'btn btn-sm btn-outline-danger flex-shrink-0';
          removeBtn.textContent = '−';
          removeBtn.addEventListener('click', function () {
            sketchup.on_marking_setting_changed('offsets_from_line_mm[-' + i + ']', '');
            OFFSETS_FROM_LINE_MM.splice(i, 1);
            renderOffsetRows(OFFSETS_FROM_LINE_MM);
            showStatus(true, 'saved');
          });
          row.appendChild(removeBtn);
        }
        list.appendChild(row);
      });
    }

    function showStatus(ok, key) {
      var st = document.getElementById('marking-save-status');
      if (!st) return;
      st.className = ok ? 'small text-success' : 'small text-danger';
      st.textContent = ok ? (GG_MARKING_STRINGS[key] || GG_MARKING_STRINGS.saved) : GG_MARKING_STRINGS.save_failed;
    }

    function currentMode() {
      var el = document.querySelector('input[name="marking_mode"]:checked');
      return el ? el.value : 'area';
    }

    function readNum(key) {
      var el = document.querySelector('.js-marking-num[data-marking-key="' + key + '"]');
      return el ? parseFloat(el.value) || 0 : 0;
    }

    function readStr(key) {
      var el = document.querySelector('.js-marking-str[data-marking-key="' + key + '"]');
      return el ? el.value.trim() : '';
    }

    function readRing() {
      var el = document.getElementById('marking-preset-ring');
      return el ? !!el.checked : false;
    }

    function setRing(val) {
      var el = document.getElementById('marking-preset-ring');
      if (el) el.checked = !!val;
    }

    function readBackFace() {
      var el = document.getElementById('marking-mark-back-face');
      return el ? !!el.checked : false;
    }

    function setBackFace(val) {
      var el = document.getElementById('marking-mark-back-face');
      if (el) el.checked = !!val;
    }

    function isCustomProfile(p) {
      return !!(p && p.profile_kind === 'custom_profile' && p.profile_ring && p.profile_ring.length >= 3);
    }

    function isGroupProfile(p) {
      return !!(p && p.profile_kind === 'group' && p.group_definition_name);
    }

    function isProfilePreset(p) {
      return isCustomProfile(p) || isGroupProfile(p);
    }

    function profilePreviewSvgData(ring) {
      if (!ring || ring.length < 3) return null;
      var xs = [];
      var ys = [];
      ring.forEach(function (row) {
        xs.push(Number(row[0]));
        ys.push(Number(row[1]));
      });
      var minX = Math.min.apply(null, xs);
      var maxX = Math.max.apply(null, xs);
      var minY = Math.min.apply(null, ys);
      var maxY = Math.max.apply(null, ys);
      var spanX = Math.max(maxX - minX, 1e-6);
      var spanY = Math.max(maxY - minY, 1e-6);
      var pad = Math.max(spanX, spanY) * PROFILE_PREVIEW_PAD;
      var width = spanX + (2 * pad);
      var height = spanY + (2 * pad);
      var points = ring.map(function (row) {
        var x = (Number(row[0]) - minX + pad).toFixed(4);
        var y = (maxY - Number(row[1]) + pad).toFixed(4);
        return x + ',' + y;
      }).join(' ');
      return { viewBox: '0 0 ' + width.toFixed(4) + ' ' + height.toFixed(4), points: points };
    }

    function fillProfileSvg(svg, ring) {
      if (!svg) return false;
      while (svg.firstChild) svg.removeChild(svg.firstChild);
      var data = profilePreviewSvgData(ring);
      if (!data) return false;
      svg.setAttribute('viewBox', data.viewBox);
      var poly = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
      poly.setAttribute('points', data.points);
      svg.appendChild(poly);
      return true;
    }

    function editingPreset() {
      if (!EDITING_PRESET_ID) return null;
      return PRESETS.find(function (p) { return p.id === EDITING_PRESET_ID; }) || null;
    }

    function profileSizeFromPreset(p) {
      if (!p) return null;
      if (p.profile_width_mm != null && p.profile_height_mm != null) {
        return { width: p.profile_width_mm, height: p.profile_height_mm };
      }
      var ring = p.profile_ring;
      if (!ring || ring.length < 3) return null;
      var xs = [];
      var ys = [];
      ring.forEach(function (row) {
        xs.push(Number(row[0]));
        ys.push(Number(row[1]));
      });
      var inchToMm = 25.4;
      return {
        width: ((Math.max.apply(null, xs) - Math.min.apply(null, xs)) * inchToMm).toFixed(1),
        height: ((Math.max.apply(null, ys) - Math.min.apply(null, ys)) * inchToMm).toFixed(1)
      };
    }

    function updateProfileSizeFields(p) {
      var size = profileSizeFromPreset(p);
      var wEl = document.getElementById('marking-profile-width-mm');
      var hEl = document.getElementById('marking-profile-height-mm');
      if (!wEl || !hEl) return;
      if (!size) {
        wEl.value = '';
        hEl.value = '';
        return;
      }
      wEl.value = size.width;
      hEl.value = size.height;
    }

    function renderProfilePreview(p) {
      var wrap = document.getElementById('marking-profile-preview-wrap');
      var svg = document.getElementById('marking-profile-preview-svg');
      var hint = document.getElementById('marking-profile-preview-hint');
      if (!wrap || !svg) return;
      var custom = isCustomProfile(p);
      wrap.classList.toggle('d-none', !custom);
      if (!custom) return;
      var ok = fillProfileSvg(svg, p.profile_ring);
      if (hint) hint.classList.toggle('d-none', ok);
      updateProfileSizeFields(p);
    }

    function syncCustomProfileUi() {
      var p = editingPreset();
      var custom = isCustomProfile(p);
      var prof = isProfilePreset(p);
      var area = currentMode() === 'area';
      renderProfilePreview(p);
      document.querySelectorAll('.js-marking-hide-custom').forEach(function (el) {
        el.style.display = prof ? 'none' : '';
      });
      document.querySelectorAll('.js-marking-offset-line').forEach(function (el) {
        el.style.display = '';
      });
      document.querySelectorAll('.js-marking-profile-locked-offset').forEach(function (el) {
        el.style.display = prof ? '' : 'none';
      });
      document.querySelectorAll('.js-marking-area-field').forEach(function (el) {
        el.style.display = area && !prof ? '' : 'none';
      });
      if (!prof) {
        syncModeFields();
      } else {
        document.querySelectorAll('.js-marking-area-layer').forEach(function (el) {
          el.style.display = area ? '' : 'none';
        });
        document.querySelectorAll('.js-marking-line-layer').forEach(function (el) {
          el.style.display = area ? 'none' : '';
        });
      }
    }

    function syncModeFields() {
      var area = currentMode() === 'area';
      var custom = isCustomProfile(editingPreset());
      document.querySelectorAll('.js-marking-area-field, .js-marking-area-layer').forEach(function (el) {
        el.style.display = area && !custom ? '' : 'none';
      });
      document.querySelectorAll('.js-marking-line-layer').forEach(function (el) {
        el.style.display = area ? 'none' : '';
      });
    }

    function isDefaultPresetEditing() {
      return EDITING_PRESET_ID === DEFAULT_PRESET_ID;
    }

    function syncDefaultPresetUi() {
      var locked = isDefaultPresetEditing();
      var nameEl = document.getElementById('marking-preset-name');
      if (nameEl) {
        nameEl.readOnly = locked;
        nameEl.classList.toggle('bg-light', locked);
      }
      renderOffsetRows(OFFSETS_FROM_LINE_MM);
    }

    function setNum(key, val) {
      var el = document.querySelector('.js-marking-num[data-marking-key="' + key + '"]');
      if (el) el.value = val;
    }

    function setStr(key, val) {
      var el = document.querySelector('.js-marking-str[data-marking-key="' + key + '"]');
      if (el) el.value = val;
    }

    function startNewPreset() {
      EDITING_PRESET_ID = '';
      var nameEl = document.getElementById('marking-preset-name');
      if (nameEl) {
        nameEl.value = '';
        nameEl.focus();
      }
      setRing(false);
      renderPresetList();
      syncDefaultPresetUi();
      syncCustomProfileUi();
      if (window.sketchup && sketchup.on_marking_new_preset) {
        sketchup.on_marking_new_preset();
      }
    }

    function loadPresetIntoForm(p) {
      if (!p) return;
      EDITING_PRESET_ID = p.id || '';
      document.getElementById('marking-preset-name').value = p.name || '';
      var mode = p.mode === 'line' ? 'line' : 'area';
      document.querySelectorAll('input[name="marking_mode"]').forEach(function (el) {
        el.checked = el.value === mode;
      });
      setNum('edge_end_offset_mm', p.edge_end_offset_mm);
      setNum('area_width_mm', p.area_width_mm);
      OFFSETS_FROM_LINE_MM = (p.offsets_from_line_mm && p.offsets_from_line_mm.length) ? p.offsets_from_line_mm.slice() : [p.offset_from_line_mm || 0];
      renderOffsetRows(OFFSETS_FROM_LINE_MM);
      setNum('profile_offset_from_locked_line_mm', p.profile_offset_from_locked_line_mm != null ? p.profile_offset_from_locked_line_mm : p.offset_from_line_mm);
      setStr('line_layer_name', p.line_layer_name || '');
      setStr('area_layer_name', p.area_layer_name || '');
      setRing(p.ring);
      setBackFace(p.mark_back_face);
      syncModeFields();
      syncDefaultPresetUi();
      syncCustomProfileUi();
      if (window.sketchup && sketchup.on_marking_apply_preset && p.id) {
        sketchup.on_marking_apply_preset(p.id);
      }
    }

    function renderPresetList() {
      var root = document.getElementById('marking-preset-list');
      if (!root) return;
      root.innerHTML = '';
      if (!PRESETS.length) {
        root.innerHTML = '<p class="text-muted small mb-0">â€”</p>';
        return;
      }
      PRESETS.forEach(function (p) {
        var row = document.createElement('div');
        row.className = 'd-flex align-items-center justify-content-between border rounded px-2 py-1 mb-1 marking-preset-row gap-2';
        row.style.cursor = 'pointer';
        if (p.id === EDITING_PRESET_ID) {
          row.classList.add('border-primary', 'bg-light');
        }
        var left = document.createElement('div');
        left.className = 'd-flex align-items-center gap-2 flex-grow-1 min-w-0';
        if (isCustomProfile(p)) {
          var thumb = document.createElement('div');
          thumb.className = 'marking-preset-thumb border';
          var thumbSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
          thumbSvg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
          fillProfileSvg(thumbSvg, p.profile_ring);
          thumb.appendChild(thumbSvg);
          left.appendChild(thumb);
        }
        var label = document.createElement('span');
        label.className = 'small text-truncate';
        var ringTag = p.ring ? ', ring' : '';
        var shapeTag = isCustomProfile(p) ? ', shape' : (isGroupProfile(p) ? ', group' : '');
        label.textContent = (isProfilePreset(p) ? '\u25C6 ' : '') + p.name + ' (' + p.mode + ringTag + shapeTag + ')';
        left.appendChild(label);
        row.appendChild(left);
        row.addEventListener('click', function (ev) {
          if (ev.target.tagName === 'BUTTON') return;
          loadPresetIntoForm(p);
          renderPresetList();
        });
        if (!isBuiltinPreset(p.id)) {
          var btn = document.createElement('button');
          btn.type = 'button';
          btn.className = 'btn btn-sm btn-outline-danger flex-shrink-0';
          btn.textContent = GG_MARKING_STRINGS.delete;
          btn.addEventListener('click', function (ev) {
            ev.stopPropagation();
            sketchup.on_marking_delete_preset(p.id);
          });
          row.appendChild(btn);
        }
        root.appendChild(row);
      });
    }

    document.querySelectorAll('input[name="marking_mode"]').forEach(function (el) {
      el.addEventListener('change', function () {
        if (!el.checked) return;
        syncModeFields();
        syncCustomProfileUi();
        sketchup.on_marking_mode_changed(el.value);
        showStatus(true, 'saved');
      });
    });

    document.querySelectorAll('.js-marking-num').forEach(function (el) {
      el.addEventListener('change', function () {
        sketchup.on_marking_setting_changed(el.dataset.markingKey, el.value);
        showStatus(true, 'saved');
      });
    });

    document.querySelectorAll('.js-marking-str').forEach(function (el) {
      el.addEventListener('change', function () {
        sketchup.on_marking_setting_changed(el.dataset.markingKey, el.value);
        showStatus(true, 'saved');
      });
    });

    var ringEl = document.getElementById('marking-preset-ring');
    if (ringEl) {
      ringEl.addEventListener('change', function () {
        sketchup.on_marking_setting_changed('ring', ringEl.checked ? '1' : '0');
        showStatus(true, 'saved');
      });
    }

    var backFaceEl = document.getElementById('marking-mark-back-face');
    if (backFaceEl) {
      backFaceEl.addEventListener('change', function () {
        sketchup.on_marking_setting_changed('mark_back_face', backFaceEl.checked ? '1' : '0');
        showStatus(true, 'saved');
      });
    }

    var swapAxesEl = document.getElementById('marking-swap-axes-btn');
    if (swapAxesEl) {
      swapAxesEl.addEventListener('click', function () {
        if (window.sketchup && sketchup.on_marking_swap_profile_axes) {
          sketchup.on_marking_swap_profile_axes();
          showStatus(true, 'saved');
        }
      });
    }

    document.getElementById('marking-new-preset-btn').addEventListener('click', startNewPreset);

    var resetBtn = document.getElementById('marking-reset-presets-btn');
    if (resetBtn) {
      resetBtn.addEventListener('click', function () {
        if (!window.confirm(GG_MARKING_STRINGS.reset_confirm)) return;
        if (window.sketchup && sketchup.on_marking_reset_presets) {
          sketchup.on_marking_reset_presets();
          showStatus(true, 'saved');
        }
      });
    }

    var addOffsetBtn = document.getElementById('marking-offset-add');
    if (addOffsetBtn) {
      addOffsetBtn.addEventListener('click', function () {
        var lastVal = OFFSETS_FROM_LINE_MM.length > 0 ? OFFSETS_FROM_LINE_MM[OFFSETS_FROM_LINE_MM.length - 1] : 0;
        sketchup.on_marking_setting_changed('offsets_from_line_mm[+]', String(lastVal));
        OFFSETS_FROM_LINE_MM.push(lastVal);
        renderOffsetRows(OFFSETS_FROM_LINE_MM);
        showStatus(true, 'saved');
      });
    }

    document.getElementById('marking-save-preset-btn').addEventListener('click', function () {
      var nameEl = document.getElementById('marking-preset-name');
      var name = isDefaultPresetEditing()
        ? (PRESETS.find(function (p) { return p.id === DEFAULT_PRESET_ID; }) || {}).name || 'Default'
        : nameEl.value.trim();
      if (!name) return;
      var mode = currentMode();
      var payload = {
        id: EDITING_PRESET_ID || '',
        name: name,
        mode: mode,
        edge_end_offset_mm: readNum('edge_end_offset_mm'),
        area_width_mm: readNum('area_width_mm'),
        offsets_from_line_mm: OFFSETS_FROM_LINE_MM.slice(),
        offset_from_line_mm: OFFSETS_FROM_LINE_MM[0] || 0,
        profile_offset_from_locked_line_mm: readNum('profile_offset_from_locked_line_mm'),
        line_layer_name: readStr('line_layer_name'),
        area_layer_name: readStr('area_layer_name'),
        ring: readRing(),
        mark_back_face: readBackFace(),
        layer: mode === 'area' ? readStr('area_layer_name') : readStr('line_layer_name')
      };
      var existing = editingPreset();
      if (existing && isCustomProfile(existing)) {
        payload.profile_kind = existing.profile_kind;
        payload.profile_centroid = existing.profile_centroid;
        payload.profile_ring = existing.profile_ring;
        payload.profile_label_text = existing.profile_label_text;
        payload.profile_label_height_mm = existing.profile_label_height_mm;
        payload.profile_label_layer_name = existing.profile_label_layer_name;
      } else if (existing && isGroupProfile(existing)) {
        payload.profile_kind = existing.profile_kind;
        payload.group_definition_name = existing.group_definition_name;
        payload.profile_centroid = existing.profile_centroid;
      }
      sketchup.on_marking_save_preset(JSON.stringify(payload));
      EDITING_PRESET_ID = payload.id || EDITING_PRESET_ID;
      showStatus(true, 'preset_saved');
    });

    renderOffsetRows(OFFSETS_FROM_LINE_MM);
    syncModeFields();
    syncDefaultPresetUi();
    syncCustomProfileUi();
    renderPresetList();
  })();
  </script>
</body>
</html>
