{
  "version": 3,
  "sources": ["/cdn/shop/t/280/assets/wf-painted-portrait.js?cb=20261014c"],
  "sourcesContent": ["/* =====================================================================\r\n   wf-painted-portrait.js \u2014 Painted Pet Portrait background choice\r\n   (product tag `painted-portrait`: Personalized Painted Pet Portrait Charm\r\n   + Ring). The customer's pet is painted onto one of 6 preset painted\r\n   backgrounds; the choice ships as the line-item property `Background`\r\n   (Blue / Purple / White / Opal / Pink / Green \u2014 the order pipeline's\r\n   canonical values, see snippets/painted-background-options.liquid).\r\n\r\n   - PDP (snippets/painted-background-picker.liquid, inside the pet portrait\r\n     upload block of snippets/product-form.liquid): a server-rendered radio\r\n     group. This file keeps \"\u2014 Opal\" in the label, clears the error once one\r\n     is chosen, preselects ?background=opal, and blocks Add to Cart until a\r\n     background is chosen (capture phase, so it runs before the theme's\r\n     handlers). The pet portrait add handler in assets/1r-theme.js reads the\r\n     chosen value and sends it as Background (with the photo, never a Name).\r\n   - Build Your Charm Set (the #pet-portrait-modal in\r\n     snippets/photo-upload-multi.liquid, painted mode set by\r\n     assets/1r-theme.js addPetPortraitRequest): modalReset() clears the\r\n     modal's group on open, modalValidate() shows the error and returns\r\n     false until one is chosen, modalValue() returns the chosen value.\r\n   ===================================================================== */\r\n(function () {\r\n  'use strict';\r\n\r\n  var ERROR_TEXT = 'Please choose a background color.';\r\n\r\n  function checked(root) {\r\n    var r = root && root.querySelector('input.wf-pbg__input:checked');\r\n    return r ? r.value : '';\r\n  }\r\n\r\n  /* label value + error state for one field (PDP or modal) */\r\n  function bind(field) {\r\n    var info = field.querySelector('.wf-pbg__value');\r\n    var err = field.querySelector('.wf-pbg__error');\r\n    var set = field.querySelector('fieldset');\r\n\r\n    function showError(on) {\r\n      field.classList.toggle('is-invalid', !!on);\r\n      if (set) {\r\n        if (on) set.setAttribute('aria-invalid', 'true');\r\n        else set.removeAttribute('aria-invalid');\r\n      }\r\n      if (!err) return;\r\n      err.hidden = !on;\r\n      err.textContent = on ? ERROR_TEXT : '';\r\n    }\r\n    function sync() {\r\n      var v = checked(field);\r\n      if (info) info.textContent = v ? '\u2014 ' + v : '';\r\n      field.classList.toggle('is-chosen', !!v);\r\n      if (v) showError(false);\r\n    }\r\n    field.addEventListener('change', sync);\r\n    sync();   // a browser-restored choice (back/forward) shows in the label\r\n    return { showError: showError, sync: sync };\r\n  }\r\n\r\n  function focusFirst(field) {\r\n    var first = field.querySelector('input.wf-pbg__input');\r\n    if (first) { try { first.focus({ preventScroll: true }); } catch (e) { first.focus(); } }\r\n  }\r\n\r\n  /* ---------------------------------------------------------------------\r\n     PDP\r\n     --------------------------------------------------------------------- */\r\n  var pdpRequireFn = null;\r\n  function initPdp(field) {\r\n    if (field.getAttribute('data-wf-pbg-ready')) return;\r\n    field.setAttribute('data-wf-pbg-ready', '1');\r\n    var form = field.closest('form');\r\n    if (!form) return;\r\n    var ui = bind(field);\r\n\r\n    function requireBackground() {\r\n      ui.showError(true);\r\n      // a modal may still be closing (it restores focus to its trigger as it\r\n      // goes), so focus the group after it has settled\r\n      setTimeout(function () {\r\n        field.scrollIntoView({ behavior: 'smooth', block: 'center' });\r\n        focusFirst(field);\r\n      }, 60);\r\n    }\r\n    pdpRequireFn = requireBackground;\r\n\r\n    function blocked(e) {\r\n      if (checked(field)) return false;\r\n      e.preventDefault();\r\n      e.stopImmediatePropagation();\r\n      requireBackground();\r\n      return true;\r\n    }\r\n    document.addEventListener('click', function (e) {\r\n      var btn = e.target && e.target.closest && e.target.closest('.add-to-cart-btn, button[name=\"add\"]');\r\n      if (btn && form.contains(btn)) blocked(e);\r\n    }, true);\r\n    form.addEventListener('submit', function (e) { blocked(e); }, true);\r\n    /* jQuery-triggered adds ($('button.add-to-cart').click() after a photo\r\n       upload) run jQuery handlers without a native click when one of them\r\n       prevents the default, e.g. the ring's locket add in 1r-theme.js (a\r\n       delegated body handler). A handler delegated from the form runs before\r\n       those, so it gates them too (1r-theme.js also adds Background there). */\r\n    if (window.jQuery) {\r\n      window.jQuery(form).on('click', '.add-to-cart-btn, button[name=\"add\"]', function (e) { blocked(e); });\r\n    }\r\n\r\n    // ?background=opal preselects (e.g. an ad for one background)\r\n    var m = /[?&]background=([^&#]+)/i.exec(location.search);\r\n    if (m) {\r\n      var want = '';\r\n      try { want = decodeURIComponent(m[1].replace(/\\+/g, ' ')).trim().toLowerCase(); } catch (err) {}\r\n      [].forEach.call(field.querySelectorAll('input.wf-pbg__input'), function (r) {\r\n        if (want && r.value.toLowerCase() === want) r.checked = true;\r\n      });\r\n      ui.sync();\r\n    }\r\n  }\r\n\r\n  /* ---------------------------------------------------------------------\r\n     PDP photo card (snippets/product-form.liquid, [data-wf-pp-upload]): the\r\n     face of the pet portrait uploader. 1r-theme.js owns the upload: its\r\n     FilePond (#pet-portrait-image, visually hidden here) sends the file to\r\n     Cloudinary and stores the URL as .pet-portrait-image-container\r\n     data('cloudinary-url'); on failure it only resets the Add to Cart label.\r\n     The card opens FilePond and mirrors that state, with the photo in the\r\n     card's tile (pdp-personalizer.css .wf-has-photo / --wf-thumb).\r\n     --------------------------------------------------------------------- */\r\n  function initPetUpload(card) {\r\n    if (card.getAttribute('data-wf-pp-ready')) return;\r\n    card.setAttribute('data-wf-pp-ready', '1');\r\n    var host = card.closest('.pet-portrait-image-container');\r\n    var label = card.querySelector('#upload-btn-text');\r\n    var status = host && host.querySelector('[data-wf-pp-upload-status]');\r\n    if (!host || !label) return;\r\n    var $ = window.jQuery;\r\n    var poll = null;\r\n    var localUrl = null;\r\n\r\n    function pond() {\r\n      var root = host.querySelector('.filepond--root');\r\n      return root && window.FilePond && window.FilePond.find ? window.FilePond.find(root) : null;\r\n    }\r\n    function storedUrl() { return $ ? ($(host).data('cloudinary-url') || '') : ''; }\r\n    function thumb(src) {\r\n      if (src) card.style.setProperty('--wf-thumb', 'url(\"' + src + '\")');\r\n      else card.style.removeProperty('--wf-thumb');\r\n      card.classList.toggle('wf-has-photo', !!src);\r\n    }\r\n    function say(msg) { if (status) status.textContent = msg; }\r\n    function show(state) {\r\n      if (state === 'idle') { thumb(''); label.textContent = 'Upload Photo'; }\r\n      else if (state === 'uploading') { label.innerHTML = 'Uploading\u2026<small>One moment</small>'; say('Uploading your photo'); }\r\n      else if (state === 'done') { label.innerHTML = 'Photo added<small>Tap to change</small>'; say('Photo added'); }\r\n      else if (state === 'failed') { thumb(''); label.innerHTML = 'Upload didn\u2019t go through<small>Tap to try again</small>'; say('The photo did not upload. Tap to try again.'); }\r\n      card.classList.toggle('wf-pp-uploading', state === 'uploading');\r\n    }\r\n    // Cloudinary resizes (and turns an iPhone HEIC into JPEG) for the tile\r\n    function cloudThumb(url) {\r\n      return String(url).replace(/^http:\\/\\//, 'https://').replace('/image/upload/', '/image/upload/c_fill,w_120,h_160,f_jpg,q_auto/');\r\n    }\r\n\r\n    card.addEventListener('click', function () {\r\n      var p = pond();\r\n      if (p) p.browse();\r\n    });\r\n\r\n    host.addEventListener('FilePond:addfile', function (e) {\r\n      var item = e.detail && e.detail.file;\r\n      if ($) $(host).data('cloudinary-url', '');   // a new photo replaces the last one\r\n      if (localUrl) { try { URL.revokeObjectURL(localUrl); } catch (err) {} localUrl = null; }\r\n      if (item && item.file && /^image\\/(jpe?g|png|webp|gif)$/i.test(item.file.type || '')) {\r\n        localUrl = URL.createObjectURL(item.file);\r\n        thumb(localUrl);\r\n      } else {\r\n        thumb('');\r\n      }\r\n      show('uploading');\r\n      var started = Date.now();\r\n      clearInterval(poll);\r\n      poll = setInterval(function () {\r\n        var url = storedUrl();\r\n        var atc = document.querySelector('.product-single__form .add-to-cart-btn');\r\n        var busy = atc && /uploading/i.test(atc.textContent || '');\r\n        if (url) { clearInterval(poll); thumb(cloudThumb(url)); show('done'); }\r\n        else if (!busy && Date.now() - started > 1500) { clearInterval(poll); show('failed'); }\r\n      }, 300);\r\n    });\r\n    host.addEventListener('FilePond:removefile', function () {\r\n      clearInterval(poll);\r\n      if (!(pond() && pond().getFiles().length)) show('idle');\r\n    });\r\n  }\r\n\r\n  /* ---------------------------------------------------------------------\r\n     Build Your Charm Set modal\r\n     --------------------------------------------------------------------- */\r\n  var modalUi = null;\r\n  function modalField() {\r\n    return document.querySelector('#pet-portrait-modal [data-wf-pbg-modal]');\r\n  }\r\n  function modalReset() {\r\n    var field = modalField();\r\n    if (!field) return;\r\n    if (!modalUi) modalUi = bind(field);\r\n    [].forEach.call(field.querySelectorAll('input.wf-pbg__input'), function (r) { r.checked = false; });\r\n    modalUi.showError(false);\r\n    modalUi.sync();\r\n  }\r\n  function modalValue() {\r\n    return checked(modalField());\r\n  }\r\n  function modalValidate() {\r\n    var field = modalField();\r\n    if (!field) return false;\r\n    if (!modalUi) modalUi = bind(field);\r\n    if (checked(field)) return true;\r\n    modalUi.showError(true);\r\n    focusFirst(field);\r\n    return false;\r\n  }\r\n\r\n  window.WFPaintedPortrait = {\r\n    /* the pet portrait add handler in 1r-theme.js calls this when a\r\n       jQuery-triggered add (skip photo) arrives without a background */\r\n    pdpRequire: function () { if (pdpRequireFn) pdpRequireFn(); },\r\n    modalReset: modalReset,\r\n    modalValue: modalValue,\r\n    modalValidate: modalValidate\r\n  };\r\n\r\n  function boot() {\r\n    var fields = document.querySelectorAll('[data-wf-pbg-field]');\r\n    for (var i = 0; i < fields.length; i++) initPdp(fields[i]);\r\n    var cards = document.querySelectorAll('[data-wf-pp-upload]');\r\n    for (var j = 0; j < cards.length; j++) initPetUpload(cards[j]);\r\n  }\r\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot);\r\n  else boot();\r\n})();\r\n"],
  "mappings": "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",
  "names": []
}
