{
  "version": 3,
  "sources": ["/cdn/shop/t/3/assets/branding-logo-placer.js?blp=9"],
  "sourcesContent": ["import { StandardEvents } from '@shopify/events';\n\n/**\n * Branded seat-cover popup: place a logo on a high/low-back photo.\n * Crop + background removal edit the file; drag on the seat is a preview only.\n * Logo files, placement text, count, and a composite screenshot go on the line item.\n *\n * @typedef {Object} LogoEntry\n * @property {number} id\n * @property {number} index\n * @property {File} file\n * @property {string} objectUrl\n * @property {string} workingSrc\n * @property {string | null} warpedSrc\n * @property {boolean} hasBackground\n * @property {number} x\n * @property {number} y\n * @property {number} scale\n * @property {number} rotation\n * @property {HTMLElement} layer\n * @property {HTMLImageElement} image\n * @property {HTMLInputElement} fileInput\n * @property {HTMLInputElement} placementInput\n */\n\nclass BrandingLogoPlacer extends HTMLElement {\n  /** @type {Record<string, HTMLElement>} */\n  refs = {};\n\n  /** @type {Element | null} */\n  #section = null;\n\n  /** @type {HTMLFormElement | null} */\n  #form = null;\n\n  /** @type {HTMLElement | null} */\n  #target = null;\n\n  /** @type {LogoEntry[]} */\n  #logos = [];\n\n  /** @type {number} */\n  #nextId = 1;\n\n  /** @type {number | null} */\n  #activeId = null;\n\n  #pointerId = -1;\n  /** @type {'move' | 'crop-move' | 'crop-resize' | null} */\n  #dragMode = null;\n  /** @type {string | null} */\n  #cropHandle = null;\n  #cropStart = { x: 0, y: 0, left: 8, top: 8, width: 84, height: 84 };\n  #addInFlight = false;\n  #allowNextClick = false;\n  #wasHidden = true;\n  /** @type {'headrest' | 'backrest'} */\n  #position = 'backrest';\n\n  connectedCallback() {\n    this.#collectRefs();\n    this.#wasHidden = this.hasAttribute('hidden');\n\n    this.#section = this.closest('.shopify-section, dialog');\n    this.#section?.addEventListener(StandardEvents.productSelect, this.#handleProductSelect);\n\n    this.#form = /** @type {HTMLFormElement | null} */ (document.getElementById(this.dataset.formId || ''));\n    document.addEventListener('click', this.#onAddButtonClick, true);\n\n    this.refs.fileInput?.addEventListener('change', this.#onFileChange);\n    this.refs.openButton?.addEventListener('click', () => this.#openModal());\n    this.refs.closeButton?.addEventListener('click', () => this.#closeModal());\n    this.refs.finishButton?.addEventListener('click', () => this.#closeModal());\n    this.refs.deleteButton?.addEventListener('click', () => {\n      if (this.#activeId != null) this.#removeLogo(this.#activeId);\n    });\n    this.refs.cropButton?.addEventListener('click', () => this.#applyCrop());\n    this.refs.bgButton?.addEventListener('click', () => this.#removeBackground());\n    this.refs.posHead?.addEventListener('change', () => this.#setPosition('headrest'));\n    this.refs.posBack?.addEventListener('change', () => this.#setPosition('backrest'));\n\n    this.refs.dialog?.addEventListener('click', (event) => {\n      if (event.target === this.refs.dialog) this.#closeModal();\n    });\n\n    this.addEventListener('dragenter', this.#onDragEnter);\n    this.addEventListener('dragover', this.#onDragOver);\n    this.addEventListener('dragleave', this.#onDragLeave);\n    this.addEventListener('drop', this.#onDrop);\n\n    this.refs.cropBox?.addEventListener('pointerdown', this.#onCropPointerDown);\n    window.addEventListener('resize', this.#onResize);\n\n    this.#target = this.refs.previewHost || null;\n    this.#syncSeatPreview();\n    this.#syncPositionOptions();\n    this.#syncFormState();\n  }\n\n  disconnectedCallback() {\n    this.#section?.removeEventListener(StandardEvents.productSelect, this.#handleProductSelect);\n    document.removeEventListener('click', this.#onAddButtonClick, true);\n    window.removeEventListener('resize', this.#onResize);\n    this.#clearAllLogos();\n    this.#section = null;\n    this.#form = null;\n  }\n\n  #onResize = () => {\n    this.#applySlotToLogos();\n  };\n\n  #collectRefs() {\n    /** @type {Record<string, HTMLElement>} */\n    const refs = {};\n    for (const element of this.querySelectorAll('[ref]')) {\n      if (!(element instanceof HTMLElement)) continue;\n      const key = element.getAttribute('ref');\n      if (key) refs[key] = element;\n    }\n    this.refs = refs;\n  }\n\n  get #requireUpload() {\n    return this.dataset.requireUpload === 'true';\n  }\n\n  get #maxBytes() {\n    return (Number(this.dataset.maxFileMb) || 5) * 1024 * 1024;\n  }\n\n  get #maxLogos() {\n    return Math.max(1, Math.min(4, Number(this.dataset.maxLogos) || 1));\n  }\n\n  get #formId() {\n    return this.dataset.formId || '';\n  }\n\n  get #active() {\n    return this.#logos.find((logo) => logo.id === this.#activeId) ?? null;\n  }\n\n  get #dialog() {\n    return /** @type {HTMLDialogElement | undefined} */ (this.refs.dialog);\n  }\n\n  #openModal() {\n    if (this.hasAttribute('hidden')) return;\n    this.#syncSeatPreview();\n    this.#syncPositionOptions();\n    if (!this.#dialog?.open) this.#dialog?.showModal();\n    this.#drawEditor();\n  }\n\n  #closeModal() {\n    if (this.#dialog?.open) this.#dialog.close();\n    this.#syncFormState();\n  }\n\n  #detectSeatKind() {\n    const forced = this.dataset.seatStyle;\n    if (forced === 'high' || forced === 'low') return forced;\n    const haystack = `${this.dataset.productHandle || ''} ${this.dataset.productTitle || ''}`.toLowerCase();\n    if (/\\blow[\\s-]?back\\b|\\blowback\\b|\\blow\\b/.test(haystack) && !/\\bhigh[\\s-]?back\\b/.test(haystack)) {\n      return 'low';\n    }\n    return 'high';\n  }\n\n  #syncSeatPreview() {\n    const kind = this.#detectSeatKind();\n    this.dataset.seatKind = kind;\n    const high = this.dataset.highImage || '';\n    const low = this.dataset.lowImage || '';\n    const src = kind === 'low' ? low || high : high || low;\n    const seat = /** @type {HTMLImageElement | undefined} */ (this.refs.seatImage);\n    const placeholder = this.refs.seatPlaceholder;\n    const label = this.refs.seatLabel;\n\n    if (label) label.textContent = kind === 'low' ? 'Low back' : 'High back';\n\n    if (seat && src) {\n      seat.hidden = false;\n      if (seat.src !== src) {\n        seat.src = src;\n        seat.alt = `${kind}-back seat cover preview`;\n      }\n      if (placeholder) placeholder.hidden = true;\n    } else if (placeholder) {\n      placeholder.hidden = false;\n    }\n\n    if (this.refs.modalTitle && this.dataset.productTitle) {\n      this.refs.modalTitle.textContent = this.dataset.productTitle;\n    }\n    if (this.dataset.productPrice) {\n      if (this.refs.modalPrice) this.refs.modalPrice.textContent = this.dataset.productPrice;\n      if (this.refs.footerPrice) this.refs.footerPrice.textContent = this.dataset.productPrice;\n    }\n  }\n\n  #syncPositionOptions() {\n    const lowBack = this.#detectSeatKind() === 'low';\n    this.refs.headrestOption?.toggleAttribute('hidden', lowBack);\n    if (lowBack && this.#position === 'headrest') this.#setPosition('backrest');\n  }\n\n  get #fixedScale() {\n    return Number(this.dataset.fixedScale || 22);\n  }\n\n  /** @param {LogoEntry} logo */\n  #logoMaxHeight(logo) {\n    const headrest = this.#position === 'headrest' && this.#detectSeatKind() !== 'low';\n    const baseHeight = headrest ? 16 : this.#detectSeatKind() === 'low' ? 19 : 17;\n    if (!logo.hasBackground) return baseHeight;\n    return baseHeight * (headrest ? 0.78 : 0.86);\n  }\n\n  /** @returns {{ x: number, y: number }} */\n  #slotCoords() {\n    const lowBack = this.#detectSeatKind() === 'low';\n    const useHead = this.#position === 'headrest' && !lowBack;\n    if (useHead) {\n      return {\n        x: Number(this.dataset.headrestX || 50),\n        y: Number(this.dataset.headrestY || 11),\n      };\n    }\n    return {\n      x: Number(this.dataset.backrestX || 50),\n      y: Number(this.dataset.backrestY || 31),\n    };\n  }\n\n  /**\n   * @param {'headrest' | 'backrest'} position\n   */\n  #setPosition(position) {\n    const lowBack = this.#detectSeatKind() === 'low';\n    this.#position = lowBack ? 'backrest' : position;\n    const head = /** @type {HTMLInputElement | undefined} */ (this.refs.posHead);\n    const back = /** @type {HTMLInputElement | undefined} */ (this.refs.posBack);\n    if (head) head.checked = this.#position === 'headrest';\n    if (back) back.checked = this.#position === 'backrest';\n    this.#applySlotToLogos();\n    this.#writePlacements();\n  }\n\n  #applySlotToLogos() {\n    const slot = this.#slotCoords();\n    const scale = this.#fixedScale;\n    for (const logo of this.#logos) {\n      logo.x = slot.x;\n      logo.y = slot.y;\n      logo.scale = scale;\n      this.#applyLogoTransform(logo);\n    }\n  }\n\n  /** @param {any} event */\n  #handleProductSelect = (event) => {\n    if (!(event.target instanceof Element) || event.target.closest('product-card')) return;\n\n    event.promise\n      ?.then((/** @type {any} */ { detail }) => {\n        if (!detail?.html) return;\n        const { html, newProduct } = detail;\n\n        if (newProduct) this.dataset.productId = newProduct.id;\n        else if (detail.productId && detail.productId !== this.dataset.productId) return;\n\n        const updated = html.querySelector(`branding-logo-placer[data-block-id=\"${this.dataset.blockId}\"]`);\n        if (!updated) return;\n\n        const nowHidden = updated.hasAttribute('hidden');\n        const becameBranded = this.#wasHidden && !nowHidden;\n        this.toggleAttribute('hidden', nowHidden);\n        this.#wasHidden = nowHidden;\n\n        if (updated instanceof HTMLElement) {\n          for (const key of ['productTitle', 'productHandle', 'productPrice', 'highImage', 'lowImage', 'seatKind']) {\n            const attr = key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n            const value = updated.getAttribute(`data-${attr}`);\n            if (value != null) this.dataset[key] = value;\n          }\n        }\n\n        this.#syncSeatPreview();\n        this.#syncPositionOptions();\n        this.#syncFormState();\n\n        if (nowHidden) {\n          this.#closeModal();\n          this.#clearError();\n          return;\n        }\n\n        if (becameBranded) this.#openModal();\n      })\n      .catch((/** @type {any} */ error) => {\n        if (error?.name !== 'AbortError') console.warn('[branding-logo-placer] Event promise rejected:', error);\n      });\n  };\n\n  #syncFormState() {\n    const active = !this.hasAttribute('hidden');\n    const count = this.#logos.length;\n    const { fileInput, countInput, previewInput, dropzoneTitle, editor, statusText, openButton, positionFieldset, positionInput, sizeInput } = this.refs;\n\n    if (fileInput instanceof HTMLInputElement) fileInput.disabled = !active || count >= this.#maxLogos;\n    if (countInput instanceof HTMLInputElement) {\n      countInput.disabled = !active;\n      countInput.value = active ? String(count) : '0';\n    }\n    if (previewInput instanceof HTMLInputElement) previewInput.disabled = !active;\n    if (positionInput instanceof HTMLInputElement) positionInput.disabled = !active;\n    if (sizeInput instanceof HTMLInputElement) sizeInput.disabled = !active;\n\n    for (const logo of this.#logos) {\n      logo.fileInput.disabled = !active;\n      logo.placementInput.disabled = !active;\n      logo.layer.toggleAttribute('hidden', !active);\n    }\n\n    editor?.toggleAttribute('hidden', count === 0);\n    positionFieldset?.toggleAttribute('hidden', count === 0);\n    if (dropzoneTitle) {\n      dropzoneTitle.textContent =\n        count >= this.#maxLogos\n          ? `Maximum ${this.#maxLogos} logo${this.#maxLogos === 1 ? '' : 's'}`\n          : count > 0\n            ? 'Replace logo'\n            : 'Add a logo file';\n    }\n    if (statusText) {\n      statusText.textContent = count\n        ? `${count} logo${count === 1 ? '' : 's'} ready \u2014 saved with your order when you add to cart.`\n        : 'No logo yet.';\n    }\n    if (openButton) openButton.textContent = count ? 'Edit logo placement' : 'Place your logo';\n\n    this.#writePlacements();\n  }\n\n  /** @returns {boolean} */\n  #blockIfMissingLogo() {\n    if (this.hasAttribute('hidden')) return false;\n    if (!this.#requireUpload) return false;\n    if (this.#logos.length > 0) return false;\n    this.#showError('Please upload a logo before adding to cart.');\n    this.#openModal();\n    return true;\n  }\n\n  #refreshForm() {\n    this.#form = /** @type {HTMLFormElement | null} */ (document.getElementById(this.#formId));\n    return this.#form;\n  }\n\n  /**\n   * @param {Event} event\n   * @returns {HTMLButtonElement | null}\n   */\n  #findOurAddButton(event) {\n    if (!(event.target instanceof Element)) return null;\n    const form = this.#refreshForm();\n    if (!form) return null;\n    const button = event.target.closest('button[type=\"submit\"], button[name=\"add\"]');\n    if (!(button instanceof HTMLButtonElement)) return null;\n    if (button.form === form || form.contains(button)) return button;\n    return null;\n  }\n\n  /** @param {MouseEvent} event */\n  #onAddButtonClick = (event) => {\n    if (this.hasAttribute('hidden')) return;\n    const button = this.#findOurAddButton(event);\n    if (!button) return;\n\n    if (this.#blockIfMissingLogo()) {\n      event.preventDefault();\n      event.stopPropagation();\n      event.stopImmediatePropagation();\n      return;\n    }\n\n    if (this.#allowNextClick) {\n      this.#allowNextClick = false;\n      return;\n    }\n\n    if (this.#addInFlight) {\n      event.preventDefault();\n      event.stopPropagation();\n      event.stopImmediatePropagation();\n      return;\n    }\n\n    event.preventDefault();\n    event.stopPropagation();\n    event.stopImmediatePropagation();\n    this.#addInFlight = true;\n\n    this.#attachScreenshot()\n      .catch((error) => console.warn('[branding-logo-placer] Screenshot skipped:', error))\n      .then(() => {\n        this.#allowNextClick = true;\n        button.click();\n      })\n      .finally(() => {\n        setTimeout(() => {\n          this.#addInFlight = false;\n          this.#allowNextClick = false;\n        }, 1500);\n      });\n  };\n\n  /** @param {Event} event */\n  #onFileChange = (event) => {\n    const file = /** @type {HTMLInputElement} */ (event.target).files?.[0];\n    if (this.refs.fileInput instanceof HTMLInputElement) this.refs.fileInput.value = '';\n    if (file) this.#loadFile(file);\n  };\n\n  /** @param {DragEvent} event */\n  #onDragEnter = (event) => {\n    event.preventDefault();\n    this.classList.add('is-dragging-file');\n  };\n\n  /** @param {DragEvent} event */\n  #onDragOver = (event) => {\n    event.preventDefault();\n  };\n\n  /** @param {DragEvent} event */\n  #onDragLeave = (event) => {\n    if (event.target === this || !this.contains(/** @type {Node} */ (event.relatedTarget))) {\n      this.classList.remove('is-dragging-file');\n    }\n  };\n\n  /** @param {DragEvent} event */\n  #onDrop = (event) => {\n    event.preventDefault();\n    this.classList.remove('is-dragging-file');\n    if (this.hasAttribute('hidden')) return;\n    const file = event.dataTransfer?.files?.[0];\n    if (file) this.#loadFile(file);\n  };\n\n  /** @param {File} file */\n  async #loadFile(file) {\n    if (this.#logos.length >= this.#maxLogos) {\n      if (this.#maxLogos === 1 && this.#logos[0]) {\n        this.#removeLogo(this.#logos[0].id);\n      } else {\n        this.#showError(`You can add up to ${this.#maxLogos} logos.`);\n        return;\n      }\n    }\n    if (!['image/png', 'image/jpeg', 'image/webp'].includes(file.type)) {\n      this.#showError('Please use a PNG, JPG or WEBP file.');\n      return;\n    }\n    if (file.size > this.#maxBytes) {\n      this.#showError(`Logo must be under ${this.dataset.maxFileMb || 5}MB.`);\n      return;\n    }\n\n    this.#clearError();\n    const objectUrl = URL.createObjectURL(file);\n    const workingSrc = await this.#fileToPngDataUrl(file).catch(() => objectUrl);\n    const hasBackground = await this.#detectBackgroundLayer(workingSrc).catch(() => false);\n    const warpedSrc = await this.#warpPreview(workingSrc).catch(() => null);\n\n    const slot = this.#slotCoords();\n    const entry = this.#createLogoEntry({\n      file,\n      objectUrl,\n      workingSrc,\n      warpedSrc,\n      hasBackground,\n      x: slot.x,\n      y: slot.y,\n      scale: this.#fixedScale,\n      rotation: 0,\n    });\n\n    this.#constrainLogo(entry);\n    this.#logos.push(entry);\n    this.#reindexLogos();\n    this.#setActive(entry.id);\n    this.#mountLogo(entry);\n    this.#syncFormState();\n    this.#resetCropBox();\n    this.#drawEditor();\n    this.#openModal();\n  }\n\n  /**\n   * @param {object} data\n   * @param {File} data.file\n   * @param {string} data.objectUrl\n   * @param {string} data.workingSrc\n   * @param {string | null} data.warpedSrc\n   * @param {boolean} data.hasBackground\n   * @param {number} data.x\n   * @param {number} data.y\n   * @param {number} data.scale\n   * @param {number} data.rotation\n   * @returns {LogoEntry}\n   */\n  #createLogoEntry(data) {\n    const id = this.#nextId++;\n    const template = /** @type {HTMLTemplateElement | undefined} */ (this.refs.layerTemplate);\n    const fragment = template?.content?.cloneNode(true);\n    const layer = /** @type {HTMLElement | null} */ (\n      fragment instanceof DocumentFragment ? fragment.querySelector('.branding-preview__logo') : null\n    );\n    if (!layer) throw new Error('Logo layer template missing');\n\n    const image = /** @type {HTMLImageElement} */ (layer.querySelector('img'));\n    image.alt = `Logo preview ${id}`;\n    image.src = data.warpedSrc || data.workingSrc;\n\n    const fileInput = document.createElement('input');\n    fileInput.type = 'file';\n    fileInput.accept = 'image/png,image/jpeg,image/webp,.png,.jpg,.jpeg,.webp';\n    fileInput.name = 'properties[Logo 1]';\n    fileInput.setAttribute('form', this.#formId);\n    fileInput.className = 'visually-hidden';\n    this.#assignFile(fileInput, data.file);\n\n    const placementInput = document.createElement('input');\n    placementInput.type = 'hidden';\n    placementInput.name = 'properties[Logo 1 placement]';\n    placementInput.setAttribute('form', this.#formId);\n    this.refs.inputsHost?.append(fileInput, placementInput);\n\n    /** @type {LogoEntry} */\n    const entry = {\n      id,\n      index: 1,\n      file: data.file,\n      objectUrl: data.objectUrl,\n      workingSrc: data.workingSrc,\n      warpedSrc: data.warpedSrc,\n      hasBackground: data.hasBackground,\n      x: data.x,\n      y: data.y,\n      scale: data.scale,\n      rotation: data.rotation,\n      layer,\n      image,\n      fileInput,\n      placementInput,\n    };\n\n    this.#applyLogoTransform(entry);\n    return entry;\n  }\n\n  /** @param {LogoEntry} logo */\n  #mountLogo(logo) {\n    this.#target = this.refs.previewHost || null;\n    if (!this.#target) return;\n    if (logo.layer.parentElement !== this.#target) this.#target.appendChild(logo.layer);\n    this.#applyLogoTransform(logo);\n  }\n\n  #reindexLogos() {\n    this.#logos.forEach((logo, i) => {\n      logo.index = i + 1;\n      logo.fileInput.name = `properties[Logo ${logo.index}]`;\n      logo.placementInput.name = `properties[Logo ${logo.index} placement]`;\n    });\n  }\n\n  /** @param {number} id */\n  #setActive(id) {\n    this.#activeId = id;\n    for (const logo of this.#logos) {\n      logo.layer.classList.toggle('is-selected', logo.id === id);\n    }\n    this.#drawEditor();\n  }\n\n  /** @param {number} id */\n  #removeLogo(id) {\n    const index = this.#logos.findIndex((logo) => logo.id === id);\n    if (index < 0) return;\n    const [logo] = this.#logos.splice(index, 1);\n    logo.layer.remove();\n    logo.fileInput.remove();\n    logo.placementInput.remove();\n    URL.revokeObjectURL(logo.objectUrl);\n    this.#activeId = this.#logos[this.#logos.length - 1]?.id ?? null;\n    if (this.#activeId != null) this.#setActive(this.#activeId);\n    this.#reindexLogos();\n    this.#syncFormState();\n    this.#drawEditor();\n  }\n\n  #clearAllLogos() {\n    for (const logo of [...this.#logos]) this.#removeLogo(logo.id);\n  }\n\n  /** @param {LogoEntry} logo */\n  #constrainLogo(logo) {\n    const slot = this.#slotCoords();\n    const headrest = this.#position === 'headrest' && this.#detectSeatKind() !== 'low';\n    const backgroundScale = headrest ? 0.76 : 0.85;\n    logo.scale = this.#fixedScale * (logo.hasBackground ? backgroundScale : 1);\n    logo.x = slot.x;\n    logo.y = logo.hasBackground && headrest ? slot.y - 0.5 : slot.y;\n  }\n\n  /** @param {LogoEntry} logo */\n  #applyLogoTransform(logo) {\n    this.#constrainLogo(logo);\n    logo.layer.style.setProperty('--logo-x', `${logo.x}%`);\n    logo.layer.style.setProperty('--logo-y', `${logo.y}%`);\n    logo.layer.style.setProperty('--logo-scale', String(logo.scale));\n    logo.layer.style.setProperty('--logo-max-height', String(this.#logoMaxHeight(logo)));\n    logo.layer.toggleAttribute('data-background-layer', logo.hasBackground);\n    logo.rotation = 0;\n    logo.layer.style.setProperty('--logo-rotation', '0deg');\n    const src = logo.warpedSrc || logo.workingSrc;\n    if (logo.image.src !== src) logo.image.src = src;\n  }\n\n  #writePlacements() {\n    const kind = this.#detectSeatKind() === 'low' ? 'Low back' : 'High back';\n    const slot = this.#position === 'headrest' && this.#detectSeatKind() !== 'low' ? 'Head rest' : 'Back rest';\n    const mm = this.dataset.logoMm || '145';\n    if (this.refs.positionInput instanceof HTMLInputElement) this.refs.positionInput.value = slot;\n    if (this.refs.sizeInput instanceof HTMLInputElement) this.refs.sizeInput.value = `${mm} mm`;\n    for (const logo of this.#logos) {\n      logo.placementInput.value = `${kind} \u00B7 ${slot} \u00B7 ${mm} mm`;\n    }\n    if (this.refs.countInput instanceof HTMLInputElement && !this.hasAttribute('hidden')) {\n      this.refs.countInput.value = String(this.#logos.length);\n    }\n  }\n\n  /** @param {PointerEvent} event */\n  #onCropPointerDown = (event) => {\n    if (!(event.target instanceof Element)) return;\n    event.preventDefault();\n    event.stopPropagation();\n    const handle = event.target.closest('[data-crop]');\n    this.#pointerId = event.pointerId;\n    this.#dragMode = handle ? 'crop-resize' : 'crop-move';\n    this.#cropHandle = handle?.getAttribute('data-crop') || null;\n    const box = this.refs.cropBox;\n    this.#cropStart = {\n      x: event.clientX,\n      y: event.clientY,\n      left: parseFloat(box?.style.left || '8'),\n      top: parseFloat(box?.style.top || '8'),\n      width: parseFloat(box?.style.width || '84'),\n      height: parseFloat(box?.style.height || '84'),\n    };\n    window.addEventListener('pointermove', this.#onPointerMove);\n    window.addEventListener('pointerup', this.#onPointerUp);\n    window.addEventListener('pointercancel', this.#onPointerUp);\n  };\n\n  /** @param {PointerEvent} event */\n  #onPointerMove = (event) => {\n    if (event.pointerId !== this.#pointerId || !this.#dragMode) return;\n    event.preventDefault();\n\n    const stage = this.refs.editorStage?.getBoundingClientRect();\n    const box = this.refs.cropBox;\n    if (!stage || !box || !stage.width) return;\n    const dx = ((event.clientX - this.#cropStart.x) / stage.width) * 100;\n    const dy = ((event.clientY - this.#cropStart.y) / stage.height) * 100;\n    let { left, top, width, height } = this.#cropStart;\n\n    if (this.#dragMode === 'crop-move') {\n      left += dx;\n      top += dy;\n    } else if (this.#cropHandle === 'se') {\n      width += dx;\n      height += dy;\n    } else if (this.#cropHandle === 'ne') {\n      width += dx;\n      top += dy;\n      height -= dy;\n    } else if (this.#cropHandle === 'sw') {\n      left += dx;\n      width -= dx;\n      height += dy;\n    } else if (this.#cropHandle === 'nw') {\n      left += dx;\n      top += dy;\n      width -= dx;\n      height -= dy;\n    }\n\n    width = this.#clamp(width, 12, 100);\n    height = this.#clamp(height, 12, 100);\n    left = this.#clamp(left, 0, 100 - width);\n    top = this.#clamp(top, 0, 100 - height);\n    this.#setCropBox(left, top, width, height);\n  };\n\n  /** @param {PointerEvent} event */\n  #onPointerUp = (event) => {\n    if (event.pointerId !== this.#pointerId) return;\n    this.#dragMode = null;\n    this.#cropHandle = null;\n    this.#pointerId = -1;\n    window.removeEventListener('pointermove', this.#onPointerMove);\n    window.removeEventListener('pointerup', this.#onPointerUp);\n    window.removeEventListener('pointercancel', this.#onPointerUp);\n    this.#writePlacements();\n  };\n\n  #resetCropBox() {\n    this.#setCropBox(8, 8, 84, 84);\n  }\n\n  /**\n   * @param {number} left\n   * @param {number} top\n   * @param {number} width\n   * @param {number} height\n   */\n  #setCropBox(left, top, width, height) {\n    const box = this.refs.cropBox;\n    if (!box) return;\n    box.style.left = `${left}%`;\n    box.style.top = `${top}%`;\n    box.style.width = `${width}%`;\n    box.style.height = `${height}%`;\n  }\n\n  async #drawEditor() {\n    const canvas = /** @type {HTMLCanvasElement | undefined} */ (this.refs.editorCanvas);\n    const logo = this.#active;\n    if (!canvas) return;\n    const ctx = canvas.getContext('2d');\n    if (!ctx) return;\n\n    const size = 520;\n    canvas.width = size;\n    canvas.height = size;\n    ctx.clearRect(0, 0, size, size);\n    if (!logo) return;\n\n    try {\n      const img = await this.#loadImageElement(logo.workingSrc);\n      const scale = Math.min(size / img.naturalWidth, size / img.naturalHeight);\n      const w = img.naturalWidth * scale;\n      const h = img.naturalHeight * scale;\n      ctx.drawImage(img, (size - w) / 2, (size - h) / 2, w, h);\n    } catch {\n      // ignore\n    }\n  }\n\n  async #applyCrop() {\n    const logo = this.#active;\n    const box = this.refs.cropBox;\n    if (!logo || !box) return;\n\n    const left = parseFloat(box.style.left || '8') / 100;\n    const top = parseFloat(box.style.top || '8') / 100;\n    const width = parseFloat(box.style.width || '84') / 100;\n    const height = parseFloat(box.style.height || '84') / 100;\n\n    const img = await this.#loadImageElement(logo.workingSrc);\n    const size = 520;\n    const scale = Math.min(size / img.naturalWidth, size / img.naturalHeight);\n    const drawW = img.naturalWidth * scale;\n    const drawH = img.naturalHeight * scale;\n    const offsetX = (size - drawW) / 2;\n    const offsetY = (size - drawH) / 2;\n\n    const sx = this.#clamp(((left * size - offsetX) / drawW) * img.naturalWidth, 0, img.naturalWidth - 1);\n    const sy = this.#clamp(((top * size - offsetY) / drawH) * img.naturalHeight, 0, img.naturalHeight - 1);\n    const sw = this.#clamp((width * size) / drawW * img.naturalWidth, 1, img.naturalWidth - sx);\n    const sh = this.#clamp((height * size) / drawH * img.naturalHeight, 1, img.naturalHeight - sy);\n\n    const out = document.createElement('canvas');\n    out.width = Math.max(1, Math.round(sw));\n    out.height = Math.max(1, Math.round(sh));\n    const ctx = out.getContext('2d');\n    if (!ctx) return;\n    ctx.drawImage(img, sx, sy, sw, sh, 0, 0, out.width, out.height);\n    await this.#commitCanvas(logo, out, `${this.#baseName(logo.file.name)}-cropped.png`);\n    this.#resetCropBox();\n  }\n\n  async #removeBackground() {\n    const logo = this.#active;\n    if (!logo) return;\n    const img = await this.#loadImageElement(logo.workingSrc);\n    const canvas = document.createElement('canvas');\n    canvas.width = img.naturalWidth;\n    canvas.height = img.naturalHeight;\n    const ctx = canvas.getContext('2d', { willReadFrequently: true });\n    if (!ctx) return;\n    ctx.drawImage(img, 0, 0);\n    const image = ctx.getImageData(0, 0, canvas.width, canvas.height);\n    this.#knockoutBackground(image);\n    ctx.putImageData(image, 0, 0);\n    await this.#commitCanvas(logo, canvas, `${this.#baseName(logo.file.name)}-nobg.png`);\n  }\n\n  /** @param {ImageData} image */\n  #knockoutBackground(image) {\n    const { data, width, height } = image;\n    const sample = (x, y) => {\n      const i = (y * width + x) * 4;\n      return [data[i], data[i + 1], data[i + 2], data[i + 3]];\n    };\n    const corners = [sample(0, 0), sample(width - 1, 0), sample(0, height - 1), sample(width - 1, height - 1)];\n    const key = corners.reduce(\n      (acc, c) => [acc[0] + c[0] / 4, acc[1] + c[1] / 4, acc[2] + c[2] / 4],\n      [0, 0, 0]\n    );\n    const dist = (i) => {\n      const dr = data[i] - key[0];\n      const dg = data[i + 1] - key[1];\n      const db = data[i + 2] - key[2];\n      return Math.sqrt(dr * dr + dg * dg + db * db);\n    };\n\n    const visited = new Uint8Array(width * height);\n    const queue = [];\n    const push = (x, y) => {\n      if (x < 0 || y < 0 || x >= width || y >= height) return;\n      const idx = y * width + x;\n      if (visited[idx]) return;\n      visited[idx] = 1;\n      if (dist(idx * 4) < 42 && data[idx * 4 + 3] > 8) queue.push(idx);\n    };\n\n    for (let x = 0; x < width; x++) {\n      push(x, 0);\n      push(x, height - 1);\n    }\n    for (let y = 0; y < height; y++) {\n      push(0, y);\n      push(width - 1, y);\n    }\n\n    while (queue.length) {\n      const idx = queue.pop();\n      if (idx == null) break;\n      data[idx * 4 + 3] = 0;\n      const x = idx % width;\n      const y = (idx / width) | 0;\n      push(x + 1, y);\n      push(x - 1, y);\n      push(x, y + 1);\n      push(x, y - 1);\n    }\n\n    // Soften the cut edge.\n    for (let i = 0; i < data.length; i += 4) {\n      if (data[i + 3] === 0) continue;\n      const d = dist(i);\n      if (d < 58) data[i + 3] = Math.round(data[i + 3] * ((d - 42) / 16));\n    }\n  }\n\n  /**\n   * @param {LogoEntry} logo\n   * @param {HTMLCanvasElement} canvas\n   * @param {string} filename\n   */\n  async #commitCanvas(logo, canvas, filename) {\n    const blob = await new Promise((resolve) => canvas.toBlob((b) => resolve(b), 'image/png'));\n    if (!blob) return;\n    const file = new File([blob], filename, { type: 'image/png' });\n    logo.file = file;\n    this.#assignFile(logo.fileInput, file);\n    logo.workingSrc = canvas.toDataURL('image/png');\n    logo.hasBackground = await this.#detectBackgroundLayer(logo.workingSrc).catch(() => false);\n    logo.warpedSrc = await this.#warpPreview(logo.workingSrc).catch(() => null);\n    this.#applyLogoTransform(logo);\n    this.#drawEditor();\n    this.#writePlacements();\n  }\n\n  /**\n   * @param {HTMLInputElement} input\n   * @param {File} file\n   */\n  #assignFile(input, file) {\n    const transfer = new DataTransfer();\n    transfer.items.add(file);\n    input.files = transfer.files;\n  }\n\n  /** @param {string} name */\n  #baseName(name) {\n    return name.replace(/\\.[^.]+$/, '') || 'logo';\n  }\n\n  async #attachScreenshot() {\n    const input = /** @type {HTMLInputElement | undefined} */ (this.refs.previewInput);\n    if (!input || this.#logos.length === 0) return;\n    const blob = await this.#capturePreviewBlob();\n    if (!blob) return;\n    this.#assignFile(input, new File([blob], 'placement-preview.png', { type: 'image/png' }));\n  }\n\n  /** @returns {Promise<Blob | null>} */\n  async #capturePreviewBlob() {\n    const host = this.#target || this.refs.previewHost;\n    const seat = /** @type {HTMLImageElement | undefined} */ (this.refs.seatImage);\n    if (!host) return null;\n\n    const width = 1200;\n    const height =\n      seat && seat.naturalWidth\n        ? Math.round(width * (seat.naturalHeight / seat.naturalWidth))\n        : Math.round(width * ((host.clientHeight || 900) / (host.clientWidth || 900)));\n    const canvas = document.createElement('canvas');\n    canvas.width = width;\n    canvas.height = height;\n    const ctx = canvas.getContext('2d');\n    if (!ctx) return null;\n    ctx.fillStyle = '#ececec';\n    ctx.fillRect(0, 0, width, height);\n\n    if (seat && !seat.hidden && seat.naturalWidth) {\n      this.#drawContain(ctx, seat, width, height);\n    }\n\n    for (const logo of this.#logos) {\n      try {\n        const img = await this.#loadImageElement(logo.warpedSrc || logo.workingSrc);\n        const maxLogoW = (logo.scale / 100) * width;\n        const maxLogoH = (this.#logoMaxHeight(logo) / 100) * height;\n        const logoScale = Math.min(\n          maxLogoW / (img.naturalWidth || 1),\n          maxLogoH / (img.naturalHeight || 1)\n        );\n        const logoW = img.naturalWidth * logoScale;\n        const logoH = img.naturalHeight * logoScale;\n        ctx.save();\n        ctx.translate((logo.x / 100) * width, (logo.y / 100) * height);\n        ctx.drawImage(img, -logoW / 2, -logoH / 2, logoW, logoH);\n        ctx.restore();\n      } catch (error) {\n        console.warn('[branding-logo-placer] Logo composite skipped:', error);\n      }\n    }\n\n    return new Promise((resolve) => canvas.toBlob((blob) => resolve(blob), 'image/png', 0.92));\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} ctx\n   * @param {CanvasImageSource & { naturalWidth?: number, naturalHeight?: number, width?: number, height?: number }} img\n   * @param {number} width\n   * @param {number} height\n   */\n  #drawContain(ctx, img, width, height) {\n    const iw = Number(img.naturalWidth || img.width) || width;\n    const ih = Number(img.naturalHeight || img.height) || height;\n    const scale = Math.min(width / iw, height / ih);\n    const dw = iw * scale;\n    const dh = ih * scale;\n    ctx.drawImage(img, (width - dw) / 2, (height - dh) / 2, dw, dh);\n  }\n\n  /**\n   * @param {string} src\n   * @returns {Promise<HTMLImageElement>}\n   */\n  #loadImageElement(src) {\n    return new Promise((resolve, reject) => {\n      const img = new Image();\n      img.onload = () => resolve(img);\n      img.onerror = () => reject(new Error('Image failed to load'));\n      img.src = src;\n    });\n  }\n\n  /**\n   * Detect a rectangular background by checking whether the corners and image\n   * border are opaque. Transparent logo artwork keeps the larger normal area.\n   * @param {string} src\n   * @returns {Promise<boolean>}\n   */\n  async #detectBackgroundLayer(src) {\n    const image = await this.#loadImageElement(src);\n    const size = 48;\n    const canvas = document.createElement('canvas');\n    canvas.width = size;\n    canvas.height = size;\n    const ctx = canvas.getContext('2d', { willReadFrequently: true });\n    if (!ctx) return false;\n    ctx.clearRect(0, 0, size, size);\n    ctx.drawImage(image, 0, 0, size, size);\n    const { data } = ctx.getImageData(0, 0, size, size);\n    const alphaAt = (x, y) => data[(y * size + x) * 4 + 3];\n\n    let borderPixels = 0;\n    let opaqueBorderPixels = 0;\n    for (let y = 0; y < size; y++) {\n      for (let x = 0; x < size; x++) {\n        if (x > 2 && x < size - 3 && y > 2 && y < size - 3) continue;\n        borderPixels++;\n        if (alphaAt(x, y) > 220) opaqueBorderPixels++;\n      }\n    }\n\n    const cornerAlpha = (startX, startY) => {\n      let total = 0;\n      for (let y = startY; y < startY + 4; y++) {\n        for (let x = startX; x < startX + 4; x++) total += alphaAt(x, y);\n      }\n      return total / 16;\n    };\n    const cornersOpaque = [\n      cornerAlpha(0, 0),\n      cornerAlpha(size - 4, 0),\n      cornerAlpha(0, size - 4),\n      cornerAlpha(size - 4, size - 4),\n    ].every((alpha) => alpha > 220);\n\n    return cornersOpaque && opaqueBorderPixels / borderPixels > 0.82;\n  }\n\n  /**\n   * @param {File} file\n   * @returns {Promise<string>}\n   */\n  async #fileToPngDataUrl(file) {\n    const decoded = await this.#decodeImage(file);\n    const canvas = document.createElement('canvas');\n    canvas.width = decoded.width;\n    canvas.height = decoded.height;\n    const ctx = canvas.getContext('2d');\n    if (!ctx) {\n      decoded.close?.();\n      return URL.createObjectURL(file);\n    }\n    ctx.drawImage(decoded.image, 0, 0);\n    decoded.close?.();\n    return canvas.toDataURL('image/png');\n  }\n\n  /**\n   * @param {File} file\n   * @returns {Promise<{ image: CanvasImageSource, width: number, height: number, close?: () => void }>}\n   */\n  async #decodeImage(file) {\n    if (typeof createImageBitmap === 'function') {\n      try {\n        const bitmap = await createImageBitmap(file);\n        return { image: bitmap, width: bitmap.width, height: bitmap.height, close: () => bitmap.close?.() };\n      } catch {\n        // fall through\n      }\n    }\n    const url = URL.createObjectURL(file);\n    const image = await this.#loadImageElement(url);\n    return { image, width: image.naturalWidth, height: image.naturalHeight };\n  }\n\n  /**\n   * Curve + shade so the overlay reads more like stitches on a seat back.\n   * @param {string} src\n   * @returns {Promise<string | null>}\n   */\n  async #warpPreview(src) {\n    const image = await this.#loadImageElement(src);\n    const width = Math.max(1, Math.min(900, image.naturalWidth || image.width));\n    const height = Math.max(1, Math.round((width / image.naturalWidth) * image.naturalHeight));\n    const source = document.createElement('canvas');\n    source.width = width;\n    source.height = height;\n    const sourceCtx = source.getContext('2d', { willReadFrequently: true });\n    if (!sourceCtx) return null;\n    sourceCtx.drawImage(image, 0, 0, width, height);\n    const sourceData = sourceCtx.getImageData(0, 0, width, height);\n    const out = document.createElement('canvas');\n    out.width = width;\n    out.height = height;\n    const outCtx = out.getContext('2d');\n    if (!outCtx) return null;\n    const outImage = outCtx.createImageData(width, height);\n    const strength = 0.12;\n    const vBulge = 0.03;\n\n    for (let y = 0; y < height; y++) {\n      const ny = y / (height - 1 || 1);\n      const vCurve = 1 + vBulge * Math.sin(ny * Math.PI);\n      for (let x = 0; x < width; x++) {\n        const nx = (x / (width - 1 || 1)) * 2 - 1;\n        const clamped = this.#clamp(nx / (1 + strength * 0.55), -0.999, 0.999);\n        const srcNx = Math.sin(clamped * (Math.PI / 2) * (1 + strength));\n        const srcX = ((srcNx + 1) / 2) * (width - 1);\n        const srcY = this.#clamp(((ny - 0.5) / vCurve + 0.5) * (height - 1), 0, height - 1);\n        const x0 = Math.floor(srcX);\n        const y0 = Math.floor(srcY);\n        const x1 = Math.min(width - 1, x0 + 1);\n        const y1 = Math.min(height - 1, y0 + 1);\n        const fx = srcX - x0;\n        const fy = srcY - y0;\n        const i = (y * width + x) * 4;\n        for (let c = 0; c < 4; c++) {\n          const s00 = sourceData.data[(y0 * width + x0) * 4 + c];\n          const s10 = sourceData.data[(y0 * width + x1) * 4 + c];\n          const s01 = sourceData.data[(y1 * width + x0) * 4 + c];\n          const s11 = sourceData.data[(y1 * width + x1) * 4 + c];\n          outImage.data[i + c] = Math.round(\n            s00 * (1 - fx) * (1 - fy) + s10 * fx * (1 - fy) + s01 * (1 - fx) * fy + s11 * fx * fy\n          );\n        }\n        const shade = 1 - Math.abs(nx) * 0.1;\n        outImage.data[i] = Math.round(outImage.data[i] * shade);\n        outImage.data[i + 1] = Math.round(outImage.data[i + 1] * shade);\n        outImage.data[i + 2] = Math.round(outImage.data[i + 2] * shade);\n      }\n    }\n\n    outCtx.putImageData(outImage, 0, 0);\n    return out.toDataURL('image/png');\n  }\n\n  /** @param {string} message */\n  #showError(message) {\n    for (const el of [this.refs.errorMessage, this.refs.modalError]) {\n      if (!el) continue;\n      el.textContent = message;\n      el.removeAttribute('hidden');\n    }\n  }\n\n  #clearError() {\n    for (const el of [this.refs.errorMessage, this.refs.modalError]) {\n      if (!el) continue;\n      el.textContent = '';\n      el.setAttribute('hidden', '');\n    }\n  }\n\n  /**\n   * @param {number} value\n   * @param {number} min\n   * @param {number} max\n   */\n  #clamp(value, min, max) {\n    return Math.min(max, Math.max(min, value));\n  }\n}\n\nif (!customElements.get('branding-logo-placer')) {\n  customElements.define('branding-logo-placer', BrandingLogoPlacer);\n}\n"],
  "mappings": "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",
  "names": ["logo"]
}
