{
  "version": 3,
  "sources": ["/cdn/shop/t/9/assets/maquette.js?x=1790327448"],
  "sourcesContent": ["/*\n  maquette.js \u2014 plapuedacaes.com \u00D7 addaxa-mockup (plan \u00A72.6 A, \u00A710bis, Addendum A).\n  Vanilla ES2017, no dependency, loaded with `defer` from layout/theme.liquid\n  (model: popup-antileave.js). A single global object: window.pdcMaquette.\n\n  Roles (Otypo-style mockup system: no cart sharing on the customer side):\n  - Restore (templates/page.maquette.liquid, link sent by the graphic designer): #t=<token> or ?t=<token> \u2192\n    GET /apps/maquette/carts/:token \u2192 preview \u2192 \"Charger ce panier\" (replace / add)\n    \u2192 /cart/clear.js \u2192 /cart/add.js line by line \u2192 /cart/update.js \u2192 \u2026/restored \u2192 /cart.\n  - Studio status: [data-maquette-cta] rendered OFFLINE in Liquid; deferred fetch\n    (DOMContentLoaded + requestIdleCallback), 2 s timeout, sessionStorage cache 60 s,\n    `is-online` class when the graphic designer is online.\n  - Studio mode (\u00A710bis): #studio=<token> stored in sessionStorage, fixed banner, shop CTAs hidden\n    (checkout, save/share, popups, account \u2014 maquette.css on body.maquette-studio-mode);\n    on /cart, the \"Enregistrer la maquette (N)\" button (snippets/maquette-studio-cart.liquid,\n    hidden outside studio mode): GET /cart.js \u2192 CartPayload + studio token \u2192 POST /apps/maquette/carts,\n    then back to the inbox tab that opened this one (postMessage + ack \u2192 tab closes; else redirect).\n  - Mockup request (\u00A72.6 B, WP-D2): popup snippets/maquette-request.liquid opened by\n    [data-maquette-request-open] (product page, help badge, homepage, cart, toast, designer) \u2192\n    context capture (product form + files, the ONE design the customer made \u2014 toast or form\n    Printlane reference, never the cart \u2014, Printlane draft stored by assets/maquette-printlane-hooks.js;\n    \"En repartant de z\u00E9ro\" tab: product only) \u2192 POST /apps/maquette/requests\n    (JSON, or multipart payload + files \u2264 5 \u00D7 10 MB) \u2192 reference PDC-M-xxx + promise; WhatsApp:\n    window pre-opened within the click, then location = whatsappUrl; on a computer (no touch screen)\n    a QR code instead, GET /apps/maquette/requests/:reference polled until the message arrives;\n    anti-duplicate (signature, 10 min).\n\n  Configuration (object set BEFORE this script, completed without being overwritten):\n    window.pdcMaquette = {\n      endpoint: '/apps/maquette',        // Shopify App Proxy\n      statusPath: '/status',             // GET endpoint + statusPath\n      requestPath: '/requests',          // POST endpoint + requestPath\n      fallbackStatusUrl: 'https://mockup.addaxa.fr/public/shops/plaquedeces/studio-status',\n      cartUrl: '/cart',\n      moneyFormat: '{{amount_with_comma_separator}} \u20AC',  // shop.money_format (Shopify.formatMoney)\n      currency: 'EUR',\n      whatsapp: '+33 6 12 34 56 78',     // settings.maquette_whatsapp_number; empty \u2192 WhatsApp channel hidden\n      page: 'product' | 'cart' | 'home', // current template (Liquid); otherwise inferred from the DOM\n      locale: 'fr',                      // request.locale.iso_code\n      enabled: true,                     // snippets/maquette-gate.liquid (setting or ?maquette=on); false \u2192 request switched off\n      flags: { printlaneHelpHook: true, printlaneDraftHook: true, savedToast: true }\n    }\n\n  Pure functions exposed for the tests: window.pdcMaquette.__pure (and module.exports).\n*/\n(function (root) {\n  'use strict';\n\n  // ---------------------------------------------------------------------------\n  // Constants (mirror of shared/types/cart-share.ts and studio-token.ts)\n  // ---------------------------------------------------------------------------\n  var CART_TOKEN_PATTERN = /^[\\w-]{22}$/;\n  var BASE64URL_PATTERN = /^[\\w-]+$/;\n  var ATTRIBUTE_PREFIX = '_maquette';\n  var ATTRIBUTE_TOKEN = '_maquette';\n  var ATTRIBUTE_REQUEST = '_maquette_demande';\n  var LINE_PROPERTY_TOKEN = '_maquette';\n  var ATTRIBUTE_REFERENCE = '_maquette_ref';\n  // Customer cart saved / shared (popup-antileave.js, /pages/panier): its own attribute, NOT `_maquette`\n  // (a `_maquette` cart counts as a graphic designer sale and hides the mockup popup).\n  var ATTRIBUTE_PANIER = '_panier';\n  var STORAGE_RESTORE_TOKEN = 'pdcMaquetteToken';\n  var STORAGE_EDIT_REF = 'pdcMaquetteEdit';\n  // Printlane designer (same script and store as the app embed on the product and cart pages)\n  var PRINTLANE_SCRIPT = 'https://designer.printlane.com/js/shopify/37103173765.js';\n  var PRINTLANE_SHOP = '5e8b3d316803b900189cd791';\n  var STUDIO_TOKEN_VERSION = 1;\n  var STORAGE_STUDIO = 'pdcMaquetteStudio';\n  var STUDIO_RETURN_ACK_MS = 1500;\n  var STORAGE_STATUS = 'pdcMaquetteStatus';\n  var STATUS_CACHE_MS = 60 * 1000;\n  var STATUS_TIMEOUT_MS = 2000;\n  var HIDDEN_PROPERTY = /customization reference/i;\n\n  // Mockup request (mirror of server/services/inbox/requests.ts + schemas.ts)\n  var REQUEST_MAX_FILES = 5;\n  var REQUEST_MAX_FILE_SIZE = 10 * 1024 * 1024;\n  var REQUEST_MAX_TEXT = 5000;\n  var REQUEST_DUPLICATE_MS = 10 * 60 * 1000;\n  var REQUEST_FILE_EXTENSIONS = /\\.(jpe?g|png|gif|webp|heic|heif|bmp|tiff?|pdf)$/i;\n  var PROPERTY_PATTERN = /^properties\\[(.+)\\]$/;\n  var STORAGE_REQUEST = 'pdcMaquetteRequest';\n  var STORAGE_SAVED = 'pdcMaquetteSaved';\n  var SAVED_TOAST_MS = 2 * 60 * 1000;\n  var FLAG_KEYS = ['printlaneHelpHook', 'printlaneDraftHook', 'savedToast'];\n  var HELP_MESSAGE = 'Cliquez d\u2019abord sur \u00AB Ajouter au panier \u00BB dans l\u2019\u00E9diteur pour que le graphiste voie votre design, puis revenez ici pour d\u00E9crire ce que vous souhaitez.';\n\n  var DEFAULTS = {\n    endpoint: '/apps/maquette',\n    statusPath: '/status',\n    requestPath: '/requests',\n    fallbackStatusUrl: 'https://mockup.addaxa.fr/public/shops/plaquedeces/studio-status',\n    cartUrl: '/cart',\n    moneyFormat: null,\n    currency: 'EUR',\n    whatsapp: null,\n    page: null,\n    locale: null,\n    flags: null,\n    printlaneDraft: null,\n    fetch: null\n  };\n\n  var pdc = root.pdcMaquette && typeof root.pdcMaquette === 'object' ? root.pdcMaquette : {};\n  Object.keys(DEFAULTS).forEach(function (key) {\n    if (!(key in pdc)) pdc[key] = DEFAULTS[key];\n  });\n  root.pdcMaquette = pdc;\n\n  // ---------------------------------------------------------------------------\n  // Pure functions (tested in test/unit/theme-maquette.test.ts)\n  // ---------------------------------------------------------------------------\n\n  function isPlainObject(value) {\n    return !!value && typeof value === 'object' && !Array.isArray(value);\n  }\n\n  // /cart.js sometimes returns numbers or booleans: everything becomes a string (like the server zod).\n  function normalizeStringMap(map) {\n    var out = {};\n    if (!isPlainObject(map)) return out;\n    Object.keys(map).forEach(function (key) {\n      var value = map[key];\n      if (value === null || value === undefined) return;\n      out[key] = typeof value === 'string' ? value : String(value);\n    });\n    return out;\n  }\n\n  // The `_maquette*` attributes are set by the restore page, `_panier` by the shared cart page\n  // (/pages/panier): never sent back to the proxy, nor copied from one cart to another.\n  function filterAttributes(attributes) {\n    var source = normalizeStringMap(attributes);\n    var out = {};\n    Object.keys(source).forEach(function (key) {\n      if (key.indexOf(ATTRIBUTE_PREFIX) === 0 || key === ATTRIBUTE_PANIER) return;\n      out[key] = source[key];\n    });\n    return out;\n  }\n\n  // EXACT mirror of the server-side `cartJsToPayload` (WP-A1): /cart.js \u2192 CartPayload.\n  function cartJsToPayload(cart) {\n    var source = isPlainObject(cart) ? cart : {};\n    var items = Array.isArray(source.items) ? source.items : [];\n    return {\n      items: items.map(function (item) {\n        var linePrice = typeof item.final_line_price === 'number' ? item.final_line_price : item.line_price;\n        var meta = {\n          title: item.title,\n          productTitle: item.product_title,\n          variantTitle: item.variant_title || null,\n          handle: item.handle,\n          image: item.image || null,\n          price: typeof item.final_price === 'number' ? item.final_price : item.price,\n          linePrice: linePrice,\n          productType: item.product_type\n        };\n        Object.keys(meta).forEach(function (key) {\n          if (meta[key] === undefined) delete meta[key];\n        });\n        return {\n          id: item.variant_id,\n          quantity: item.quantity,\n          properties: normalizeStringMap(item.properties),\n          meta: meta\n        };\n      }),\n      attributes: filterAttributes(source.attributes),\n      note: source.note ? String(source.note) : null,\n      currency: typeof source.currency === 'string' ? source.currency : undefined\n    };\n  }\n\n  function parseParams(fragment) {\n    var params = {};\n    String(fragment || '').replace(/^[#?]/, '').split('&').forEach(function (pair) {\n      if (!pair) return;\n      var index = pair.indexOf('=');\n      var key = index === -1 ? pair : pair.slice(0, index);\n      var value = index === -1 ? '' : pair.slice(index + 1);\n      try {\n        params[decodeURIComponent(key)] = decodeURIComponent(value);\n      } catch (e) {\n        params[key] = value;\n      }\n    });\n    return params;\n  }\n\n  // `#t=<token>` (mockup link, never sent to the server) or `?t=<token>` (Meta template) \u2192 token or null\n  function parseRestoreToken(hash, search) {\n    var candidates = [parseParams(hash).t, parseParams(search).t];\n    for (var i = 0; i < candidates.length; i += 1) {\n      var candidate = (candidates[i] || '').trim();\n      if (CART_TOKEN_PATTERN.test(candidate)) return candidate;\n    }\n    return null;\n  }\n\n  // `#studio=<token>` \u2192 raw token or null\n  function parseStudioFragment(hash) {\n    var value = (parseParams(hash).studio || '').trim();\n    return value ? value : null;\n  }\n\n  function decodeBase64Url(input) {\n    var base64 = String(input).replace(/-/g, '+').replace(/_/g, '/');\n    while (base64.length % 4) base64 += '=';\n    var binary = root.atob(base64);\n    var encoded = '';\n    for (var i = 0; i < binary.length; i += 1) {\n      encoded += '%' + ('00' + binary.charCodeAt(i).toString(16)).slice(-2);\n    }\n    return decodeURIComponent(encoded);\n  }\n\n  // Studio token `base64url(json).base64url(hmac)`: the body is read without checking the\n  // signature (the proxy checks it) to show the reference and handle expiry.\n  function decodeStudioToken(token, now) {\n    var at = typeof now === 'number' ? now : Date.now();\n    var parts = String(token || '').trim().split('.');\n    if (parts.length !== 2 || !BASE64URL_PATTERN.test(parts[0]) || !BASE64URL_PATTERN.test(parts[1])) return null;\n    var wire;\n    try {\n      wire = JSON.parse(decodeBase64Url(parts[0]));\n    } catch (e) {\n      return null;\n    }\n    if (!isPlainObject(wire) || wire.v !== STUDIO_TOKEN_VERSION) return null;\n    if (typeof wire.r !== 'number' || wire.r <= 0 || typeof wire.f !== 'string' || !wire.f) return null;\n    if (typeof wire.e !== 'number' || wire.e * 1000 <= at) return null;\n    var state = {\n      token: parts.join('.'),\n      reference: wire.f,\n      requestId: wire.r,\n      expiresAt: new Date(wire.e * 1000).toISOString()\n    };\n    // Optional: last studio cart to resume (\"Reprendre la derni\u00E8re maquette\")\n    if (typeof wire.c === 'string' && CART_TOKEN_PATTERN.test(wire.c)) state.cart = wire.c;\n    return state;\n  }\n\n  // Properties shown on the restore page: `_*` and the Printlane reference are hidden.\n  function visibleProperties(properties) {\n    var source = normalizeStringMap(properties);\n    return Object.keys(source).filter(function (key) {\n      return key.charAt(0) !== '_' && !HIDDEN_PROPERTY.test(key) && source[key] !== '';\n    }).map(function (key) {\n      return [key, source[key]];\n    });\n  }\n\n  function printlaneRef(properties) {\n    var source = normalizeStringMap(properties);\n    var keys = Object.keys(source);\n    for (var i = 0; i < keys.length; i += 1) {\n      if (HIDDEN_PROPERTY.test(keys[i]) && source[keys[i]]) return source[keys[i]];\n    }\n    return null;\n  }\n\n  // `images`: { ref: URL } of the mockup's plaques (`thumbs` response) \u2192 hidden property\n  // `_maquette_image`, which the cart (sections/cart-template.liquid) shows straight from its HTML.\n  var LINE_PROPERTY_IMAGE = '_maquette_image';\n  // Line whose design the customer edited on the mockup page: the graphic designer's image is outdated\n  var LINE_PROPERTY_EDITED = '_maquette_modifiee';\n  var MAQUETTE_IMAGE_PREFIX = 'https://mockup.addaxa.fr/public/previews/';\n  function withLineToken(properties, token, images) {\n    var out = normalizeStringMap(properties);\n    // No token: studio resume, the lines are not a customer mockup\n    if (token) out[LINE_PROPERTY_TOKEN] = token;\n    var ref = printlaneRef(out);\n    var image = ref && images ? images[ref] : null;\n    if (typeof image === 'string' && image.indexOf(MAQUETTE_IMAGE_PREFIX) === 0) out[LINE_PROPERTY_IMAGE] = image;\n    return out;\n  }\n\n  // Added line by line, STRICTLY sequential (items[] of /cart/add.js is atomic:\n  // one invalid line would cancel everything). 422/404 \u2192 line skipped and listed.\n  function restoreSequentially(items, token, options) {\n    var opts = options || {};\n    var fetchImpl = opts.fetch;\n    var added = [];\n    var failed = [];\n    var list = Array.isArray(items) ? items.slice() : [];\n\n    function step(index) {\n      if (index >= list.length) return Promise.resolve({ added: added, failed: failed });\n      var item = list[index];\n      var body = { items: [{ id: item.id, quantity: item.quantity, properties: withLineToken(item.properties, token, opts.images) }] };\n      if (typeof opts.onProgress === 'function') opts.onProgress(index, list.length, item);\n      return fetchImpl('/cart/add.js', {\n        method: 'POST',\n        credentials: 'same-origin',\n        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n        body: JSON.stringify(body)\n      }).then(function (response) {\n        if (response.ok) {\n          added.push(item);\n          return null;\n        }\n        return readJson(response).then(function (data) {\n          failed.push({\n            item: item,\n            status: response.status,\n            message: (data && (data.description || data.message)) || ''\n          });\n        });\n      }, function (error) {\n        failed.push({ item: item, status: 0, message: error && error.message ? error.message : 'network' });\n      }).then(function () {\n        return step(index + 1);\n      });\n    }\n\n    return step(0);\n  }\n\n  function readJson(response) {\n    if (!response || typeof response.json !== 'function') return Promise.resolve(null);\n    return Promise.resolve(response.json()).catch(function () { return null; });\n  }\n\n  // Mockup page: lines with a Printlane design (shown large) and other lines\n  // (fixings, services: simple \"\u00C9galement inclus\" list).\n  function mockupLines(items) {\n    var designs = [];\n    var extras = [];\n    (Array.isArray(items) ? items : []).forEach(function (item) {\n      if (printlaneRef(item && item.properties)) designs.push(item);\n      else extras.push(item);\n    });\n    return { designs: designs, extras: extras };\n  }\n\n  function linePrice(item) {\n    var meta = (item && item.meta) || {};\n    if (typeof meta.linePrice === 'number') return meta.linePrice;\n    if (typeof meta.price === 'number') return meta.price * (Number(item.quantity) || 1);\n    return null;\n  }\n\n  // Total price of the mockup (cents); null if a price is missing (no fake total shown).\n  function sharedTotal(items) {\n    var list = Array.isArray(items) ? items : [];\n    var total = 0;\n    for (var i = 0; i < list.length; i += 1) {\n      var price = linePrice(list[i]);\n      if (price === null) return null;\n      total += price;\n    }\n    return total;\n  }\n\n  // Mockup already loaded in this cart (link reopened): nothing is rewritten, go to the cart.\n  function isAlreadyLoaded(cart, token, sharedItems) {\n    if (!cart || !token) return false;\n    var attributes = normalizeStringMap(cart.attributes);\n    if (attributes[ATTRIBUTE_TOKEN] !== token) return false;\n    var lines = (Array.isArray(cart.items) ? cart.items : []).filter(function (item) {\n      return normalizeStringMap(item && item.properties)[LINE_PROPERTY_TOKEN] === token;\n    });\n    var expected = Array.isArray(sharedItems) ? sharedItems.length : 0;\n    return expected > 0 && lines.length === expected;\n  }\n\n  // Outcome of the adds: `failed` if nothing went through or if the plaque itself (Printlane line) is missing.\n  function restoreOutcome(report) {\n    var added = (report && report.added) || [];\n    var failed = (report && report.failed) || [];\n    if (!failed.length && added.length) return 'done';\n    if (!added.length) return 'failed';\n    var designFailed = failed.some(function (entry) { return !!printlaneRef(entry.item && entry.item.properties); });\n    return designFailed ? 'failed' : 'partial';\n  }\n\n  // Fallback FR formatting when Shopify.formatMoney is not loaded: 1 234,50 \u20AC\n  function formatMoneyFr(cents, currency) {\n    var amount = (Number(cents) || 0) / 100;\n    var parts = amount.toFixed(2).split('.');\n    var integer = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, '\u202F');\n    var symbol = !currency || currency === 'EUR' ? '\u20AC' : currency;\n    return integer + ',' + parts[1] + '\u00A0' + symbol;\n  }\n\n  function formatMoney(cents, currency) {\n    if (root.Shopify && typeof root.Shopify.formatMoney === 'function' && pdc.moneyFormat) {\n      try {\n        return root.Shopify.formatMoney(cents, pdc.moneyFormat);\n      } catch (e) { /* unexpected format: FR formatting */ }\n    }\n    return formatMoneyFr(cents, currency || pdc.currency);\n  }\n\n  // Readable error messages (studio send and restore)\n  function errorMessage(status, data, context) {\n    var detail = data && data.data && data.data.message ? data.data.message : (data && data.message) || '';\n    if (status === 413) return 'Ce panier est trop volumineux pour \u00EAtre envoy\u00E9 comme maquette (50 articles maximum).';\n    if (status === 422) return 'Ce panier ne peut pas \u00EAtre envoy\u00E9 comme maquette' + (detail ? ' : ' + detail : '.');\n    if (status === 404 && context === 'restore') return 'Ce lien ne fonctionne plus. Une version plus r\u00E9cente de votre maquette vous a peut-\u00EAtre \u00E9t\u00E9 envoy\u00E9e : utilisez le lien du dernier email re\u00E7u. Sinon, appelez-nous au 09 78 45 01 34, nous vous renvoyons un nouveau lien.';\n    if (status === 0 && context === 'restore') return 'La connexion semble interrompue. V\u00E9rifiez que vous \u00EAtes connect\u00E9 \u00E0 Internet, puis appuyez sur \u00AB R\u00E9essayer \u00BB.';\n    if ((status === 401 || status === 403) && context === 'studio') return 'Jeton studio absent, invalide ou expir\u00E9 : relancez \u00AB Cr\u00E9er la maquette sur le site \u00BB depuis l\u2019inbox.';\n    if (status === 401 || status === 403) return 'Le service de maquette n\u2019est pas disponible pour le moment.';\n    if (status === 0) return 'Impossible de joindre le service. V\u00E9rifiez votre connexion puis r\u00E9essayez.';\n    return 'Une erreur est survenue (' + status + '). R\u00E9essayez dans quelques instants.';\n  }\n\n  function formatDateFr(iso) {\n    var date = new Date(iso);\n    if (isNaN(date.getTime())) return '';\n    var day = ('0' + date.getDate()).slice(-2);\n    var month = ('0' + (date.getMonth() + 1)).slice(-2);\n    return day + '/' + month + '/' + date.getFullYear();\n  }\n\n  // ---------------------------------------------------------------------------\n  // Mockup request (plan \u00A72.6 B) \u2014 pure functions\n  // ---------------------------------------------------------------------------\n\n  function toArray(list) {\n    if (!list) return [];\n    if (Array.isArray(list)) return list.slice();\n    if (typeof list.length === 'number') return Array.prototype.slice.call(list);\n    return [];\n  }\n\n  function pushUnique(list, value) {\n    if (value && list.indexOf(value) === -1) list.push(value);\n  }\n\n  function attr(node, name) {\n    return node && typeof node.getAttribute === 'function' ? node.getAttribute(name) : null;\n  }\n\n  function queryAll(node, selector) {\n    return node && typeof node.querySelectorAll === 'function' ? toArray(node.querySelectorAll(selector)) : [];\n  }\n\n  function queryOne(node, selector) {\n    return node && typeof node.querySelector === 'function' ? node.querySelector(selector) : null;\n  }\n\n  function truncate(value, max) {\n    var text = String(value === null || value === undefined ? '' : value);\n    return text.length > max ? text.slice(0, max) : text;\n  }\n\n  function normalizeFlags(flags) {\n    var source = isPlainObject(flags) ? flags : {};\n    var out = {};\n    FLAG_KEYS.forEach(function (key) { out[key] = source[key] !== false; });\n    return out;\n  }\n\n  function normalizePage(page) {\n    return page === 'product' || page === 'cart' ? page : 'home';\n  }\n\n  // `data-product` = product | json | escape: getAttribute returns the decoded JSON.\n  function parseProductJson(text) {\n    if (!text) return null;\n    try {\n      var product = typeof text === 'string' ? JSON.parse(text) : text;\n      return isPlainObject(product) ? product : null;\n    } catch (e) {\n      return null;\n    }\n  }\n\n  function findVariant(product, variantId) {\n    var variants = product && Array.isArray(product.variants) ? product.variants : [];\n    var id = Number(variantId);\n    for (var i = 0; i < variants.length; i += 1) {\n      if (variants[i] && Number(variants[i].id) === id) return variants[i];\n    }\n    return null;\n  }\n\n  // Readable options \"Taille : 30 x 20 cm\" from product.options + variant.option1..3\n  function variantOptions(product, variant) {\n    var out = {};\n    if (!variant) return out;\n    var names = product && Array.isArray(product.options) ? product.options : [];\n    names.forEach(function (name, index) {\n      var label = typeof name === 'string' ? name : (name && name.name) || ('Option ' + (index + 1));\n      var value = variant['option' + (index + 1)];\n      if (value === undefined || value === null || value === '') return;\n      if (label === 'Title' && value === 'Default Title') return;\n      out[truncate(label, 255)] = truncate(value, 255);\n    });\n    return out;\n  }\n\n  function variantImage(product, variant) {\n    var image = variant && variant.featured_image && (variant.featured_image.src || variant.featured_image.url);\n    if (!image && product) image = product.featured_image || (Array.isArray(product.images) ? product.images[0] : null);\n    if (!image) return null;\n    var url = typeof image === 'string' ? image : (image.src || image.url || '');\n    if (url.indexOf('//') === 0) url = 'https:' + url;\n    return url ? truncate(url, 2000) : null;\n  }\n\n  // Popup preview (never sent): the selected variant's own image (the one the product gallery\n  // shows, e.g. the star plaque), else the front view = the listing hover image\n  // (snippets/product-thumbnail.liquid): the \"couv_hover\" image, else the 2nd image.\n  function frontImage(container) {\n    var product = container ? parseProductJson(attr(container, 'data-product')) : null;\n    var idField = queryOne(container, 'select[name=\"id\"], input[name=\"id\"]');\n    var variant = idField ? findVariant(product, idField.value) : null;\n    if (variant && variant.featured_image) return variantImage(product, variant);\n    var urls = (product && Array.isArray(product.images) ? product.images : []).map(function (image) {\n      var url = typeof image === 'string' ? image : (image && (image.src || image.url)) || '';\n      return url.indexOf('//') === 0 ? 'https:' + url : url;\n    });\n    for (var i = 0; i < urls.length; i++) {\n      if (urls[i].indexOf('couv_hover') !== -1) return urls[i];\n    }\n    return urls[1] || null;\n  }\n\n  function propertyName(name) {\n    var match = PROPERTY_PATTERN.exec(name || '');\n    return match ? match[1] : null;\n  }\n\n  // (1) Snapshot of the product form: `container` = [data-product-form] (or any ancestor of the\n  // button), `scope` = document (the #printlane-customization-reference input is injected by\n  // Printlane, sometimes outside the form). Returns { product, properties, files, printlaneRefs }.\n  function productSnapshot(product, variant, variantId, quantity) {\n    var out = {\n      handle: truncate(product.handle, 255),\n      title: truncate(product.title || '', 255),\n      variantId: variant ? Number(variant.id) : variantId,\n      variantTitle: variant && variant.title && variant.title !== 'Default Title' ? truncate(variant.title, 255) : null,\n      options: variantOptions(product, variant),\n      price: variant && typeof variant.price === 'number' ? variant.price : null,\n      image: variantImage(product, variant),\n      quantity: quantity\n    };\n    if (typeof product.id === 'number') out.productId = product.id;\n    return out;\n  }\n\n  function captureProductForm(container, scope) {\n    var out = { product: null, properties: {}, files: [], printlaneRefs: [] };\n    if (!container || typeof container.querySelectorAll !== 'function') return out;\n\n    var product = parseProductJson(attr(container, 'data-product'));\n    var idField = queryOne(container, 'select[name=\"id\"], input[name=\"id\"]');\n    var variantId = idField && idField.value !== undefined && idField.value !== '' ? Number(idField.value) : NaN;\n    var variant = findVariant(product, variantId) || (product && !isFinite(variantId) && Array.isArray(product.variants) ? product.variants[0] : null);\n    var quantityField = queryOne(container, '[name=\"quantity\"]');\n    var quantity = quantityField ? parseInt(quantityField.value, 10) : 1;\n\n    if (product && product.handle && (variant || isFinite(variantId))) {\n      out.product = productSnapshot(product, variant, variantId, quantity > 0 ? quantity : 1);\n    }\n\n    queryAll(container, '[name^=\"properties[\"]').forEach(function (field) {\n      var name = propertyName(attr(field, 'name'));\n      if (!name) return;\n      var type = (attr(field, 'type') || '').toLowerCase();\n      if (type === 'file') {\n        toArray(field.files).forEach(function (file) { if (file) out.files.push(file); });\n        return;\n      }\n      if ((type === 'radio' || type === 'checkbox') && !field.checked) return;\n      var value = field.value === undefined || field.value === null ? '' : String(field.value).trim();\n      if (!value) return;\n      if (HIDDEN_PROPERTY.test(name)) {\n        pushUnique(out.printlaneRefs, truncate(value, 255));\n        return;\n      }\n      out.properties[truncate(name, 255)] = truncate(value, 5000);\n    });\n\n    var refInput = queryOne(scope, '#printlane-customization-reference') || queryOne(container, '#printlane-customization-reference');\n    if (refInput && refInput.value) pushUnique(out.printlaneRefs, truncate(String(refInput.value).trim(), 255));\n    return out;\n  }\n\n  // (2) Printlane draft: { raw: product (events.updated), capturedAt } \u2192 PrintlaneDraft.\n  // The shape of `product` is undocumented: best effort, we collect the pairs\n  // { name|label|id|key, text|value } up to 5 levels, 50 fields, no cycles.\n  function draftFromPrintlane(draft, now) {\n    if (!draft || !draft.raw || typeof draft.raw !== 'object') return null;\n    var raw = draft.raw;\n    var fields = {};\n    var count = 0;\n    var seen = [];\n\n    function label(node) {\n      var candidates = [node.name, node.label, node.title, node.key, node.id];\n      for (var i = 0; i < candidates.length; i += 1) {\n        if (typeof candidates[i] === 'string' && candidates[i]) return candidates[i];\n        if (typeof candidates[i] === 'number') return String(candidates[i]);\n      }\n      return null;\n    }\n\n    function walk(node, depth) {\n      if (count >= 50 || !node || typeof node !== 'object' || depth > 5 || seen.indexOf(node) !== -1) return;\n      seen.push(node);\n      if (Array.isArray(node)) {\n        node.forEach(function (child) { walk(child, depth + 1); });\n        return;\n      }\n      var text = typeof node.text === 'string' ? node.text : (typeof node.value === 'string' ? node.value : null);\n      var name = label(node);\n      if (text !== null && name && text.trim()) {\n        var key = truncate(name, 255);\n        if (!(key in fields)) {\n          fields[key] = truncate(text, 1000);\n          count += 1;\n        }\n      }\n      Object.keys(node).forEach(function (key) {\n        var child = node[key];\n        if (child && typeof child === 'object') walk(child, depth + 1);\n      });\n    }\n    walk(raw, 0);\n\n    var templateId = raw.templateId || raw.template_id || (raw.template && (raw.template.id || raw.template.uuid)) || null;\n    var out = { fields: fields, capturedAt: draft.capturedAt || new Date(typeof now === 'number' ? now : Date.now()).toISOString() };\n    if (templateId !== null && templateId !== undefined && templateId !== '') out.templateId = truncate(templateId, 255);\n    return out;\n  }\n\n  // Full context (ShopifyRequestContext) + files of the product form.\n  // input: { page, snapshot? | form + scope, design, fromScratch, choices, draft, pageUrl, locale, now }\n  // The design is the ONE the customer just made (`design`, else the product form's\n  // Printlane reference) \u2014 never a cart line. \"En repartant de z\u00E9ro\" sends none of it.\n  // `choices` (popup shape / fixing pickers, { Forme, Fixation }) go into the properties in both modes.\n  function captureContext(input) {\n    var opts = input || {};\n    var snapshot = opts.snapshot || captureProductForm(opts.form, opts.scope);\n    var context = { page: normalizePage(opts.page) };\n    if (opts.pageUrl) context.pageUrl = truncate(opts.pageUrl, 2000);\n    if (opts.locale) context.locale = truncate(String(opts.locale).trim(), 8);\n    if (snapshot.product) context.product = snapshot.product;\n    var properties = opts.fromScratch ? {} : normalizeStringMap(snapshot.properties);\n    var choices = normalizeStringMap(opts.choices);\n    Object.keys(choices).forEach(function (key) { properties[key] = choices[key]; });\n    if (Object.keys(properties).length) context.properties = properties;\n    if (opts.fromScratch) return { context: context, files: snapshot.files };\n\n    var design = opts.design ? truncate(String(opts.design).trim(), 255) : snapshot.printlaneRefs[0];\n    if (design) context.printlaneRefs = [design];\n    var draft = draftFromPrintlane(opts.draft, opts.now);\n    if (draft) context.printlaneDraft = draft;\n    return { context: context, files: snapshot.files };\n  }\n\n  function isAllowedFile(file) {\n    var type = String(file.type || '');\n    if (/^image\\//.test(type) || type === 'application/pdf') return true;\n    if (!type) return REQUEST_FILE_EXTENSIONS.test(String(file.name || ''));\n    return false;\n  }\n\n  // \u2264 5 files, \u2264 10 MB each, images or PDF \u2014 same limits as the proxy.\n  function validateFiles(files, options) {\n    var opts = options || {};\n    var maxFiles = opts.maxFiles || REQUEST_MAX_FILES;\n    var maxSize = opts.maxSize || REQUEST_MAX_FILE_SIZE;\n    var accepted = [];\n    var rejected = [];\n    toArray(files).forEach(function (file) {\n      if (!file) return;\n      var name = file.name || 'fichier';\n      if (accepted.length >= maxFiles) rejected.push({ name: name, reason: 'count' });\n      else if (typeof file.size === 'number' && file.size > maxSize) rejected.push({ name: name, reason: 'size' });\n      else if (!isAllowedFile(file)) rejected.push({ name: name, reason: 'type' });\n      else accepted.push(file);\n    });\n    return { accepted: accepted, rejected: rejected };\n  }\n\n  function fileRejectionMessage(rejected) {\n    if (!rejected || !rejected.length) return '';\n    var reasons = { count: '5 fichiers maximum', size: 'fichier trop lourd, 10 Mo maximum', type: 'seules les photos et les PDF sont accept\u00E9s' };\n    return rejected.map(function (entry) {\n      return entry.name + ' n\u2019a pas \u00E9t\u00E9 ajout\u00E9 (' + (reasons[entry.reason] || entry.reason) + ').';\n    }).join(' ');\n  }\n\n  // Fingerprint of the attached files (name:size): two different \"files only\" requests are not duplicates\n  function filesKey(files) {\n    return toArray(files).map(function (file) {\n      return (file && file.name ? file.name : '') + ':' + (file && typeof file.size === 'number' ? file.size : '');\n    }).join(',');\n  }\n\n  function formatBytes(size) {\n    var bytes = Number(size) || 0;\n    if (bytes >= 1024 * 1024) return (bytes / 1024 / 1024).toFixed(1).replace('.', ',') + ' Mo';\n    if (bytes >= 1024) return Math.round(bytes / 1024) + ' Ko';\n    return bytes + ' o';\n  }\n\n  function hashString(input) {\n    var hash = 5381;\n    for (var i = 0; i < input.length; i += 1) hash = ((hash << 5) + hash + input.charCodeAt(i)) | 0;\n    return (hash >>> 0).toString(36);\n  }\n\n  // Anti-duplicate: fingerprint of text + variant + minute (stable within the same minute), \u2264 128 characters.\n  function requestSignature(text, variantId, at, files) {\n    var minute = Math.floor((typeof at === 'number' ? at : Date.now()) / 60000);\n    var base = String(text || '').trim() + '|' + (variantId || '') + '|' + minute + (files ? '|' + files : '');\n    return 'pdc-' + hashString(base) + '-' + hashString(base.split('').reverse().join('')) + '-' + minute.toString(36);\n  }\n\n  function requestMemoKey(text, variantId, channel, files) {\n    return String(text || '').trim() + '|' + (variantId || '') + '|' + (channel || '') + (files ? '|' + files : '');\n  }\n\n  function isValidEmail(email) {\n    return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/.test(String(email || '').trim());\n  }\n\n  // CreateShopifyRequestBody (shared/types/request.ts)\n  function buildRequestBody(input) {\n    var opts = input || {};\n    var body = {\n      channel: opts.channel === 'email' ? 'email' : 'whatsapp',\n      text: truncate(String(opts.text || '').trim(), REQUEST_MAX_TEXT),\n      context: opts.context\n    };\n    var email = String(opts.email || '').trim();\n    if (email) body.email = truncate(email, 255);\n    if (opts.signature) body.signature = truncate(opts.signature, 128);\n    return body;\n  }\n\n  // JSON without files; otherwise multipart `payload` (JSON) + `files` (n \u00D7 File) \u2014 like readOutboundFiles on the server side.\n  function buildRequestTransport(body, files, FormDataImpl) {\n    var list = toArray(files);\n    if (!list.length || typeof FormDataImpl !== 'function') {\n      return { multipart: false, body: JSON.stringify(body), headers: { 'Content-Type': 'application/json' } };\n    }\n    var form = new FormDataImpl();\n    form.append('payload', JSON.stringify(body));\n    list.forEach(function (file) { form.append('files', file, file.name || 'fichier'); });\n    return { multipart: true, body: form, headers: {} };\n  }\n\n  // (the server detail \u2014 zod, English \u2014 is never shown to the customer)\n  function requestErrorMessage(status) {\n    if (status === 413) return 'Vos fichiers sont trop lourds : 5 fichiers de 10 Mo maximum.';\n    if (status === 400 || status === 422) return 'Votre demande n\u2019a pas pu \u00EAtre envoy\u00E9e. V\u00E9rifiez votre adresse email, puis r\u00E9essayez.';\n    if (status === 429) return 'Trop de demandes en peu de temps. R\u00E9essayez dans quelques minutes, ou appelez-nous au 09 78 45 01 34.';\n    if (status === 401 || status === 403) return 'Le service de demande de maquette n\u2019est pas disponible pour le moment. Appelez-nous au 09 78 45 01 34.';\n    if (status === 0) return 'Impossible d\u2019envoyer votre demande : v\u00E9rifiez votre connexion Internet, puis r\u00E9essayez.';\n    return 'Un probl\u00E8me technique nous emp\u00EAche d\u2019envoyer votre demande. R\u00E9essayez dans un instant ou appelez-nous au 09 78 45 01 34.';\n  }\n\n  function closeWindow(win) {\n    try { if (win && !win.closed && typeof win.close === 'function') win.close(); } catch (e) { /* window already closed */ }\n  }\n\n  // WhatsApp window: pre-opened in the click handler (popup blockers), navigated after the response.\n  function navigateWhatsapp(win, url) {\n    if (!url) {\n      closeWindow(win);\n      return 'none';\n    }\n    if (win && !win.closed) {\n      try {\n        win.location.href = url;\n        return 'preopened';\n      } catch (e) { /* window unreachable: link shown */ }\n    }\n    closeWindow(win);\n    return 'blocked';\n  }\n\n  // QR code: greeting + reference only (the request text is already stored); a long\n  // text would make the code too dense to scan, or too big for a QR code at all\n  function shortWhatsappUrl(url) {\n    var match = /^([^?]+)\\?text=(.*)$/.exec(String(url || ''));\n    if (!match) return url;\n    try {\n      return match[1] + '?text=' + encodeURIComponent(decodeURIComponent(match[2]).split('\\n')[0]);\n    } catch (e) {\n      return url;\n    }\n  }\n\n  // Send orchestration, without DOM: everything goes through `io` (testable).\n  //   input: { channel, email, text, page, snapshot, files, design, fromScratch, choices, draft, pageUrl, locale, now }\n  //   io:    { openWindow(), fetchJson(url, opts), readMemo(), writeMemo(memo), FormData, url }\n  // Returns { status: 'done'|'error', response?, duplicate, whatsapp: 'preopened'|'blocked'|'none'|null, rejectedFiles, message? }\n  function sendRequest(input, io) {\n    var opts = input || {};\n    var ports = io || {};\n    var now = typeof opts.now === 'number' ? opts.now : Date.now();\n    var channel = opts.channel === 'email' ? 'email' : 'whatsapp';\n    var snapshot = opts.snapshot || { product: null, properties: {}, files: [], printlaneRefs: [] };\n    var variantId = snapshot.product ? snapshot.product.variantId : '';\n    // The design sent (or its absence) is part of what makes two requests the same\n    var choices = normalizeStringMap(opts.choices);\n    var attached = filesKey(opts.files) + (opts.fromScratch ? '|scratch' : (opts.design ? '|' + opts.design : '')) +\n      Object.keys(choices).map(function (key) { return '|' + choices[key]; }).join('');\n    var key = requestMemoKey(opts.text, variantId, channel, attached);\n\n    // 1. WhatsApp window pre-opened, synchronously, before any await\n    var popup = channel === 'whatsapp' && typeof ports.openWindow === 'function' ? ports.openWindow() : null;\n\n    // 2. Local anti-duplicate (10 min): the response is reused without network\n    var memo = typeof ports.readMemo === 'function' ? ports.readMemo() : null;\n    if (memo && memo.key === key && memo.response && typeof memo.at === 'number' && now - memo.at < REQUEST_DUPLICATE_MS) {\n      return Promise.resolve({\n        status: 'done',\n        response: memo.response,\n        duplicate: true,\n        rejectedFiles: [],\n        whatsapp: channel === 'whatsapp' ? navigateWhatsapp(popup, memo.response.whatsappUrl) : null\n      });\n    }\n\n    var signature = requestSignature(opts.text, variantId, now, attached);\n    var url = ports.url || (pdc.endpoint + pdc.requestPath);\n\n    return Promise.resolve().then(function () {\n      var captured = captureContext({\n        page: opts.page,\n        snapshot: snapshot,\n        design: opts.design,\n        fromScratch: opts.fromScratch,\n        choices: choices,\n        draft: opts.draft,\n        pageUrl: opts.pageUrl,\n        locale: opts.locale,\n        now: now\n      });\n      var validated = validateFiles(captured.files.concat(toArray(opts.files)));\n      var body = buildRequestBody({ channel: channel, email: opts.email, text: opts.text, context: captured.context, signature: signature });\n      var transport = buildRequestTransport(body, validated.accepted, ports.FormData);\n      return ports.fetchJson(url, { method: 'POST', headers: transport.headers, body: transport.body }).then(function (result) {\n        if (!result || !result.ok || !result.data || !result.data.reference) {\n          closeWindow(popup);\n          var status = result ? result.status : 0;\n          return { status: 'error', httpStatus: status, data: result ? result.data : null, message: requestErrorMessage(status, result ? result.data : null), rejectedFiles: validated.rejected };\n        }\n        if (typeof ports.writeMemo === 'function') ports.writeMemo({ key: key, signature: signature, response: result.data, at: now });\n        return {\n          status: 'done',\n          response: result.data,\n          duplicate: false,\n          rejectedFiles: validated.rejected,\n          whatsapp: channel === 'whatsapp' ? navigateWhatsapp(popup, result.data.whatsappUrl) : null\n        };\n      });\n    }).then(null, function () {\n      closeWindow(popup);\n      return { status: 'error', httpStatus: 0, data: null, message: requestErrorMessage(0, null), rejectedFiles: [] };\n    });\n  }\n\n  var pure = {\n    CART_TOKEN_PATTERN: CART_TOKEN_PATTERN,\n    REQUEST_MAX_FILES: REQUEST_MAX_FILES,\n    REQUEST_MAX_FILE_SIZE: REQUEST_MAX_FILE_SIZE,\n    REQUEST_DUPLICATE_MS: REQUEST_DUPLICATE_MS,\n    HELP_MESSAGE: HELP_MESSAGE,\n    normalizeFlags: normalizeFlags,\n    normalizePage: normalizePage,\n    parseProductJson: parseProductJson,\n    findVariant: findVariant,\n    variantOptions: variantOptions,\n    captureProductForm: captureProductForm,\n    draftFromPrintlane: draftFromPrintlane,\n    captureContext: captureContext,\n    validateFiles: validateFiles,\n    fileRejectionMessage: fileRejectionMessage,\n    formatBytes: formatBytes,\n    requestSignature: requestSignature,\n    requestMemoKey: requestMemoKey,\n    filesKey: filesKey,\n    isValidEmail: isValidEmail,\n    buildRequestBody: buildRequestBody,\n    buildRequestTransport: buildRequestTransport,\n    requestErrorMessage: requestErrorMessage,\n    navigateWhatsapp: navigateWhatsapp,\n    shortWhatsappUrl: shortWhatsappUrl,\n    sendRequest: sendRequest,\n    ATTRIBUTE_TOKEN: ATTRIBUTE_TOKEN,\n    ATTRIBUTE_PANIER: ATTRIBUTE_PANIER,\n    ATTRIBUTE_REQUEST: ATTRIBUTE_REQUEST,\n    LINE_PROPERTY_TOKEN: LINE_PROPERTY_TOKEN,\n    normalizeStringMap: normalizeStringMap,\n    filterAttributes: filterAttributes,\n    cartJsToPayload: cartJsToPayload,\n    parseParams: parseParams,\n    parseRestoreToken: parseRestoreToken,\n    parseStudioFragment: parseStudioFragment,\n    decodeStudioToken: decodeStudioToken,\n    visibleProperties: visibleProperties,\n    printlaneRef: printlaneRef,\n    withLineToken: withLineToken,\n    restoreSequentially: restoreSequentially,\n    mockupLines: mockupLines,\n    sharedTotal: sharedTotal,\n    isAlreadyLoaded: isAlreadyLoaded,\n    restoreOutcome: restoreOutcome,\n    formatMoneyFr: formatMoneyFr,\n    errorMessage: errorMessage,\n    formatDateFr: formatDateFr\n  };\n  pdc.__pure = pure;\n  if (typeof module !== 'undefined' && module.exports) module.exports = pure;\n\n  // No DOM (tests, Node): stop here.\n  if (!root.document || typeof root.document.querySelector !== 'function') return;\n\n  var doc = root.document;\n\n  // ---------------------------------------------------------------------------\n  // Network\n  // ---------------------------------------------------------------------------\n\n  function doFetch(url, opts) {\n    var impl = typeof pdc.fetch === 'function' ? pdc.fetch : root.fetch.bind(root);\n    return impl(url, opts);\n  }\n\n  function fetchJson(url, opts) {\n    var options = opts || {};\n    options.credentials = options.credentials || 'same-origin';\n    options.headers = options.headers || {};\n    options.headers.Accept = 'application/json';\n    var isFormData = typeof root.FormData === 'function' && options.body instanceof root.FormData;\n    if (options.body && typeof options.body !== 'string' && !isFormData) {\n      options.headers['Content-Type'] = 'application/json';\n      options.body = JSON.stringify(options.body);\n    }\n    return doFetch(url, options).then(function (response) {\n      return readJson(response).then(function (data) {\n        return { ok: response.ok, status: response.status, data: data };\n      });\n    }, function (error) {\n      return { ok: false, status: 0, data: null, error: error };\n    });\n  }\n\n  function fetchWithTimeout(url, opts, ms) {\n    var options = opts || {};\n    var controller = typeof root.AbortController === 'function' ? new root.AbortController() : null;\n    if (controller) options.signal = controller.signal;\n    var timer;\n    var timeout = new Promise(function (resolve) {\n      timer = setTimeout(function () {\n        if (controller) controller.abort();\n        resolve({ ok: false, status: 0, data: null, error: new Error('timeout') });\n      }, ms);\n    });\n    return Promise.race([fetchJson(url, options), timeout]).then(function (result) {\n      clearTimeout(timer);\n      return result;\n    });\n  }\n\n  // Promise rejected after `ms` (Shopify cart unreachable: no stuck button)\n  function withTimeout(promise, ms) {\n    return new Promise(function (resolve, reject) {\n      var timer = setTimeout(function () { reject(new Error('timeout')); }, ms);\n      promise.then(function (value) { clearTimeout(timer); resolve(value); }, function (error) { clearTimeout(timer); reject(error); });\n    });\n  }\n\n  function getCart() {\n    return fetchJson('/cart.js', { method: 'GET' }).then(function (result) {\n      if (!result.ok || !result.data) throw new Error('cart.js indisponible (' + result.status + ')');\n      return result.data;\n    });\n  }\n\n  // ---------------------------------------------------------------------------\n  // DOM helpers\n  // ---------------------------------------------------------------------------\n\n  function qs(selector, scope) { return (scope || doc).querySelector(selector); }\n  function qsa(selector, scope) { return Array.prototype.slice.call((scope || doc).querySelectorAll(selector)); }\n\n  function el(tag, attrs, children) {\n    var node = doc.createElement(tag);\n    Object.keys(attrs || {}).forEach(function (key) {\n      if (key === 'text') node.textContent = attrs[key];\n      else if (key === 'className') node.className = attrs[key];\n      else if (attrs[key] !== null && attrs[key] !== undefined) node.setAttribute(key, attrs[key]);\n    });\n    (children || []).forEach(function (child) {\n      if (child) node.appendChild(typeof child === 'string' ? doc.createTextNode(child) : child);\n    });\n    return node;\n  }\n\n  function setText(selector, scope, value) {\n    qsa(selector, scope).forEach(function (node) { node.textContent = value; });\n  }\n\n  function show(node, visible) {\n    if (!node) return;\n    if (visible) node.removeAttribute('hidden');\n    else node.setAttribute('hidden', '');\n  }\n\n  function showState(scope, attribute, name) {\n    qsa('[' + attribute + ']', scope).forEach(function (node) {\n      show(node, node.getAttribute(attribute) === name);\n    });\n  }\n\n  function storageGet(key) {\n    try { return root.sessionStorage.getItem(key); } catch (e) { return null; }\n  }\n  function storageSet(key, value) {\n    try { root.sessionStorage.setItem(key, value); } catch (e) { /* private browsing: no cache */ }\n  }\n  function storageRemove(key) {\n    try { root.sessionStorage.removeItem(key); } catch (e) { /* same */ }\n  }\n\n  function stripLocationParams(keys) {\n    if (!root.history || !root.history.replaceState) return;\n    try {\n      var url = new root.URL(root.location.href);\n      var hashParams = parseParams(url.hash);\n      var keep = [];\n      Object.keys(hashParams).forEach(function (key) {\n        if (keys.indexOf(key) === -1) keep.push(encodeURIComponent(key) + '=' + encodeURIComponent(hashParams[key]));\n      });\n      keys.forEach(function (key) { url.searchParams.delete(key); });\n      url.hash = keep.length ? '#' + keep.join('&') : '';\n      root.history.replaceState(null, doc.title, url.pathname + url.search + url.hash);\n    } catch (e) { /* URL API unavailable: keep the URL as is */ }\n  }\n\n  // ---------------------------------------------------------------------------\n  // Studio mode (\u00A710bis)\n  // ---------------------------------------------------------------------------\n\n  function readStudioState() {\n    var raw = storageGet(STORAGE_STUDIO);\n    if (!raw) return null;\n    try {\n      var state = JSON.parse(raw);\n      if (!state || !state.token || !state.reference || new Date(state.expiresAt).getTime() <= Date.now()) {\n        storageRemove(STORAGE_STUDIO);\n        return null;\n      }\n      return state;\n    } catch (e) {\n      storageRemove(STORAGE_STUDIO);\n      return null;\n    }\n  }\n\n  function enterStudioMode(state) {\n    storageSet(STORAGE_STUDIO, JSON.stringify(state));\n  }\n\n  function exitStudioMode() {\n    storageRemove(STORAGE_STUDIO);\n    var banner = qs('[data-maquette-studio-banner]');\n    if (banner && banner.parentNode) banner.parentNode.removeChild(banner);\n    doc.body.classList.remove('maquette-studio-mode');\n    qsa('[data-maquette-studio-send]').forEach(function (button) { applyStudioButton(button, null); });\n  }\n\n  // Studio mode prepares ONE request's plaque in the staff cart. The cart itself remembers\n  // which request it belongs to (`_maquette_studio`): studio state lives in sessionStorage,\n  // i.e. per tab, while the inbox opens every \"Create on site\" in a new tab \u2014 so the tab\n  // cannot tell a new request from a reopened one. Clear the cart only when it holds\n  // another request's work (or a restored customer mockup); same request: keep it.\n  // `_maquette*` attributes are never sent with the studio cart (filterAttributes).\n  var ATTRIBUTE_STUDIO = '_maquette_studio';\n\n  function prepareCartForStudio(state, cartToken) {\n    if (cartToken) {\n      return resumeStudioCart(state, cartToken).then(function (resumed) {\n        return resumed ? null : prepareCartForStudio(state);\n      });\n    }\n    var requestId = String(state.requestId);\n    return getCart().then(function (cart) {\n      var attributes = normalizeStringMap(cart.attributes);\n      if (attributes[ATTRIBUTE_STUDIO] === requestId) return null;\n      var reset = {};\n      reset[ATTRIBUTE_STUDIO] = requestId;\n      var dirty = (cart.items && cart.items.length) || attributes[ATTRIBUTE_TOKEN] || attributes[ATTRIBUTE_REQUEST];\n      if (!dirty) return fetchJson('/cart/update.js', { method: 'POST', body: { attributes: reset } });\n      reset[ATTRIBUTE_TOKEN] = '';\n      reset[ATTRIBUTE_REFERENCE] = '';\n      reset[ATTRIBUTE_REQUEST] = '';\n      return fetchJson('/cart/clear.js', { method: 'POST', body: {} }).then(function () {\n        return fetchJson('/cart/update.js', { method: 'POST', body: { attributes: reset } });\n      }).then(function () {\n        storageRemove(STORAGE_RESTORE_TOKEN);\n        storageRemove(STORAGE_EDIT_REF);\n        // The rendered cart (or its counter) predates the reset\n        if (/\\/cart\\/?$/.test(root.location.pathname)) root.location.reload();\n      });\n    }).catch(function () { /* cart left as is: staff can empty it by hand */ });\n  }\n\n  // \"Reprendre la derni\u00E8re maquette\": the staff cart becomes the lines of the last studio cart\n  // sent for this request (always, even if the cart already belongs to the request), then /cart\n  // reloads and initPendingEditor opens the Printlane editor on the plaque. The lines are fetched\n  // before anything is cleared; resolves false when nothing was restored (expired cart, error)\n  // so the caller falls back to the regular preparation (empty studio cart).\n  function resumeStudioCart(state, cartToken) {\n    var url = pdc.endpoint + '/carts/' + encodeURIComponent(cartToken);\n    return fetchWithTimeout(url, { method: 'GET', headers: { 'x-studio-token': state.token } }, 20000).then(function (result) {\n      var shared = result.ok && result.data && Array.isArray(result.data.items) ? result.data : null;\n      if (!shared || !shared.items.length) return false;\n      // Customer-restore bookkeeping (`_maquette`, `_maquette_image`, `_maquette_modifiee`) is dropped:\n      // the next send must not carry the previous mockup's token or image\n      var lines = shared.items.map(function (item) {\n        var properties = normalizeStringMap(item.properties);\n        Object.keys(properties).forEach(function (key) {\n          if (key.indexOf(ATTRIBUTE_PREFIX) === 0) delete properties[key];\n        });\n        return { id: item.id, quantity: item.quantity, properties: properties };\n      });\n      return fetchJson('/cart/clear.js', { method: 'POST', body: {} }).then(function (cleared) {\n        if (!cleared.ok) return false;\n        // From here the cart is the studio cart, even if no line could be added back (then empty)\n        return restoreSequentially(lines, null, { fetch: doFetch }).then(function (report) {\n          var attributes = filterAttributes(shared.attributes);\n          attributes[ATTRIBUTE_STUDIO] = String(state.requestId);\n          attributes[ATTRIBUTE_TOKEN] = '';\n          attributes[ATTRIBUTE_REFERENCE] = '';\n          attributes[ATTRIBUTE_REQUEST] = '';\n          return fetchJson('/cart/update.js', { method: 'POST', body: { attributes: attributes, note: shared.note || '' } }).then(function () {\n            var ref = null;\n            report.added.forEach(function (item) { ref = ref || printlaneRef(item.properties); });\n            storageRemove(STORAGE_RESTORE_TOKEN);\n            if (ref) storageSet(STORAGE_EDIT_REF, ref);\n            else storageRemove(STORAGE_EDIT_REF);\n            // The rendered cart predates the change (the #studio= fragment is already stripped)\n            root.location.replace(pdc.cartUrl);\n            return true;\n          });\n        });\n      });\n    }).catch(function () { return false; });\n  }\n\n  // Returns the cart reset promise (or null), so the send button waits for the new request's cart\n  function detectStudioFragment() {\n    var token = parseStudioFragment(root.location.hash);\n    if (!token) return null;\n    var state = decodeStudioToken(token);\n    var reset = null;\n    if (state) {\n      // The cart to resume is used once, never kept in the stored studio state\n      var cartToken = state.cart;\n      delete state.cart;\n      enterStudioMode(state);\n      reset = prepareCartForStudio(state, cartToken);\n    }\n    stripLocationParams(['studio']);\n    return reset;\n  }\n\n  function renderStudioBanner(state) {\n    if (qs('[data-maquette-studio-banner]')) return;\n    var exit = el('button', { type: 'button', className: 'maquette-studio-banner__exit', 'data-maquette-studio-exit': '', text: 'Quitter le mode studio' });\n    var banner = el('div', { className: 'maquette-studio-banner', 'data-maquette-studio-banner': '', role: 'status' }, [\n      el('span', { className: 'maquette-studio-banner__label' }, [\n        'Mode studio \u2014 demande ',\n        el('strong', { text: state.reference })\n      ]),\n      exit\n    ]);\n    doc.body.appendChild(banner);\n    doc.body.classList.add('maquette-studio-mode');\n  }\n\n  // Studio mode is the graphic designer's workbench, not a shop: what maquette.css cannot hide\n  // on body.maquette-studio-mode is handled here. Customers never reach this code.\n  function applyStudioPage() {\n    // Newsletter popup: fancybox opens `.js-newsletter-popup` a few seconds after load; without\n    // the node, fancybox has nothing to open (hiding its container would leave the scroll locked)\n    qsa('.js-newsletter-popup').forEach(function (node) {\n      if (node.parentNode) node.parentNode.removeChild(node);\n    });\n    // Product form set to go to the checkout after the add: the cart instead\n    qsa('form[action*=\"/cart/add\"] input[name=\"return_to\"]').forEach(function (input) {\n      if (/checkout/.test(input.value)) input.value = pdc.cartUrl;\n    });\n    // Pandectes consent: its <pandectes-cmp> sets an inline `display: block !important` that CSS\n    // can't override, and it is injected late\n    if (!root.MutationObserver || !doc.body) return hideConsent();\n    var observer = new root.MutationObserver(hideConsent);\n    hideConsent();\n    // Its own style rewrites included (subtree for the style attribute), for the first 30 s\n    observer.observe(doc.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style'] });\n    setTimeout(function () { observer.disconnect(); }, 30000);\n  }\n\n  function hideConsent() {\n    qsa('pandectes-cmp').forEach(function (node) {\n      if (node.style.getPropertyValue('display') !== 'none') node.style.setProperty('display', 'none', 'important');\n    });\n  }\n\n  function studioModeActive() {\n    return !!doc.body && doc.body.classList.contains('maquette-studio-mode');\n  }\n\n  // \"Enregistrer la maquette (N)\" button: visible only in studio mode\n  function applyStudioButton(button, studio) {\n    var label = qs('[data-maquette-studio-send-text]', button) || button;\n    var template = button.getAttribute('data-maquette-studio-label');\n    show(button, !!studio);\n    // Rendered with style=\"display: none\" (safeguard if the CSS is missing): only studio mode lifts it\n    button.style.display = studio ? '' : 'none';\n    if (studio && template) label.textContent = template.replace('{reference}', studio.reference);\n  }\n\n  // ---------------------------------------------------------------------------\n  // Sending the cart as a mockup (cart page, studio mode only)\n  // ---------------------------------------------------------------------------\n\n  function openModal(modal) {\n    show(modal, true);\n    doc.body.classList.add('maquette-modal-open');\n    var dialog = qs('.maquette-modal__dialog', modal);\n    if (dialog) dialog.focus();\n  }\n\n  function closeModal(modal) {\n    show(modal, false);\n    doc.body.classList.remove('maquette-modal-open');\n  }\n\n  function bindModal(modal) {\n    if (modal.getAttribute('data-maquette-bound')) return;\n    modal.setAttribute('data-maquette-bound', '1');\n    qsa('[data-maquette-modal-close]', modal).forEach(function (node) {\n      node.addEventListener('click', function () { closeModal(modal); });\n    });\n  }\n\n  // Mounted plaque as the cart shows it (Printlane design laid over the product\n  // photo). Printlane generates it when the design is saved and keeps it in the\n  // browser (IndexedDB): no server URL serves it. Source: the JS API\n  // `window.printlane.loadThumbnail(ref, 'blob')` (undocumented \u2192 tested and\n  // guarded), otherwise the <img data:> it put in the cart. Re-encoded as JPEG\n  // \u2264 1200 px. Returns a promise { ref: dataUrl }; best effort, never rejected.\n  var MOUNTED_WIDTH = 1200;\n  var MOUNTED_MIN_WIDTH = 200;\n\n  function imageToJpeg(img) {\n    if (!img || !img.naturalWidth || img.naturalWidth < MOUNTED_MIN_WIDTH) return null;\n    try {\n      var scale = Math.min(1, MOUNTED_WIDTH / img.naturalWidth);\n      var canvas = doc.createElement('canvas');\n      canvas.width = Math.round(img.naturalWidth * scale);\n      canvas.height = Math.round(img.naturalHeight * scale);\n      var context = canvas.getContext('2d');\n      context.fillStyle = '#ffffff';\n      context.fillRect(0, 0, canvas.width, canvas.height);\n      context.drawImage(img, 0, 0, canvas.width, canvas.height);\n      return canvas.toDataURL('image/jpeg', 0.82);\n    } catch (e) {\n      return null;\n    }\n  }\n\n  function thumbnailFromPrintlane(ref) {\n    var api = root.printlane || root.colorlab;\n    if (!api || typeof api.loadThumbnail !== 'function' || !root.URL || !root.Image) return Promise.resolve(null);\n    return Promise.resolve().then(function () {\n      return api.loadThumbnail(ref, 'blob');\n    }).then(function (blob) {\n      if (!blob || typeof blob !== 'object' || !blob.size) return null;\n      return new Promise(function (resolve) {\n        var url = root.URL.createObjectURL(blob);\n        var img = new root.Image();\n        img.onload = function () { resolve(imageToJpeg(img)); root.URL.revokeObjectURL(url); };\n        img.onerror = function () { resolve(null); root.URL.revokeObjectURL(url); };\n        img.src = url;\n      });\n    }).catch(function () { return null; });\n  }\n\n  // Cart links Printlane binds to a design (image link and \"Modifier ma plaque\" text link)\n  function printlaneLineAnchors(ref) {\n    return qsa('a.colorlab-open-personalisation[data-colorlab], a.printlane-open[data-colorlab]').filter(function (a) {\n      return a.getAttribute('data-colorlab') === ref;\n    });\n  }\n\n  // Fallback: the image Printlane put in the cart, only if it really is its own\n  // (data:) \u2014 otherwise it is the catalogue photo, or an image from another domain.\n  function thumbnailFromCart(ref) {\n    var img = printlaneLineAnchors(ref).map(function (a) { return qs('img', a); }).filter(function (candidate) {\n      var src = candidate ? (candidate.currentSrc || candidate.src || '') : '';\n      return src.indexOf('data:image/') === 0 && candidate.complete;\n    })[0];\n    return imageToJpeg(img);\n  }\n\n  function captureMountedImages(cart) {\n    var refs = [];\n    (cart && cart.items || []).forEach(function (item) { pushUnique(refs, printlaneRef(item.properties)); });\n    return Promise.all(refs.map(function (ref) {\n      return thumbnailFromPrintlane(ref).then(function (image) { return image || thumbnailFromCart(ref); });\n    })).then(function (images) {\n      var out = {};\n      refs.forEach(function (ref, i) { if (images[i]) out[ref] = images[i]; });\n      return out;\n    }).catch(function () { return {}; });\n  }\n\n  // Cart: the lines coming from a mockup (`_maquette` property = cart token)\n  // show the mockup's plaque, not the catalogue photo. Printlane only sets its\n  // thumbnail in the browser that created the design (the graphic designer's): on the\n  // customer's side, it is replaced by the mockup image served by the proxy.\n  function applyCartMockupImage(ref, src) {\n    printlaneLineAnchors(ref).forEach(function (a) {\n      var img = qs('img', a);\n      if (!img || img.getAttribute('src') === src) return;\n      ['srcset', 'data-src', 'data-srcset', 'sizes'].forEach(function (name) { img.removeAttribute(name); });\n      // The theme's `transition--fade-in` keeps the image at opacity 0 without `lazyloaded`\n      img.classList.remove('lazyload');\n      img.classList.add('lazyloaded');\n      img.setAttribute('src', src);\n      img.setAttribute('alt', 'Votre plaque personnalis\u00E9e');\n    });\n  }\n\n  function initCartMockupImages() {\n    if (!/\\/cart\\/?$/.test(root.location.pathname)) return;\n    // Only if a mockup plaque is in the cart (class set by the Liquid):\n    // an ordinary customer's cart makes no extra request\n    if (!qs('.cart-has-maquette')) return;\n    getCart().then(function (cart) {\n      // Token of the line (`_maquette`), otherwise the cart's (attribute set on restore)\n      var byToken = {};\n      var cartToken = normalizeStringMap(cart && cart.attributes)[ATTRIBUTE_TOKEN];\n      (cart && cart.items || []).forEach(function (item) {\n        var properties = normalizeStringMap(item.properties);\n        var token = properties[LINE_PROPERTY_TOKEN] || cartToken;\n        var ref = printlaneRef(properties);\n        // Image already rendered by the Liquid (`_maquette_image`), or design edited by the\n        // customer (Printlane thumbnail is the right one): nothing to do\n        if (properties[LINE_PROPERTY_IMAGE] || properties[LINE_PROPERTY_EDITED]) return;\n        if (!token || !ref || !CART_TOKEN_PATTERN.test(token)) return;\n        (byToken[token] = byToken[token] || []).push(ref);\n      });\n      return Promise.all(Object.keys(byToken).map(function (token) {\n        return fetchJson(pdc.endpoint + '/carts/' + encodeURIComponent(token) + '?peek=1', { method: 'GET' }).then(function (result) {\n          var previews = result.ok && result.data && result.data.previews ? result.data.previews : {};\n          byToken[token].forEach(function (ref) {\n            if (!previews[ref]) return;\n            applyCartMockupImage(ref, previews[ref]);\n            // The theme's lazyload may run again after us: reapply once\n            root.setTimeout(function () { applyCartMockupImage(ref, previews[ref]); }, 1500);\n          });\n        });\n      }));\n    }).catch(function () { /* catalogue photo: the order stays correct (design reference) */ });\n  }\n\n  // Back to the inbox once the mockup is saved. The inbox opened this tab (window.open): it is told\n  // where to go ({ source: 'pdc-mockup-editor', type: 'saved', inboxUrl }, posted to the inbox origin\n  // only) and answers { source: 'addaxa-mockup', type: 'ack' } from that same origin and window;\n  // then studio mode ends and the tab closes. No opener, no ack within 1.5 s, or a browser that\n  // refuses to close the tab: today's redirect to inboxUrl in this tab.\n  function returnToInbox(inboxUrl) {\n    var origin = null;\n    try { origin = new root.URL(inboxUrl).origin; } catch (e) { /* no URL API: redirect */ }\n    var opener = root.opener;\n    var fallback = function () { exitStudioMode(); root.location.href = inboxUrl; };\n    if (!origin || !opener || opener.closed) { fallback(); return; }\n    var done = false;\n    var timer = null;\n    var onMessage = function (event) {\n      var data = event.data;\n      if (event.origin !== origin || event.source !== opener) return;\n      if (!data || typeof data !== 'object' || data.source !== 'addaxa-mockup' || data.type !== 'ack') return;\n      finish(true);\n    };\n    function finish(acked) {\n      if (done) return;\n      done = true;\n      root.clearTimeout(timer);\n      root.removeEventListener('message', onMessage);\n      if (!acked) { fallback(); return; }\n      exitStudioMode();\n      try { root.close(); } catch (e) { /* refused: redirect below */ }\n      // Still open after a tick (close() silently refused): same tab goes to the inbox\n      root.setTimeout(function () { if (!root.closed) root.location.href = inboxUrl; }, 100);\n    }\n    root.addEventListener('message', onMessage);\n    timer = root.setTimeout(function () { finish(false); }, STUDIO_RETURN_ACK_MS);\n    try {\n      opener.postMessage({ source: 'pdc-mockup-editor', type: 'saved', inboxUrl: inboxUrl }, origin);\n    } catch (e) {\n      finish(false);\n    }\n  }\n\n  function sendStudioCart(modal) {\n    var studio = readStudioState();\n    openModal(modal);\n    if (!studio) {\n      // Token expired in the meantime: the proxy would refuse (403), say so right away\n      showState(modal, 'data-maquette-studio-state', 'error');\n      setText('[data-maquette-studio-error]', modal, errorMessage(403, null, 'studio'));\n      qsa('[data-maquette-studio-send]').forEach(function (button) { applyStudioButton(button, null); });\n      return;\n    }\n    showState(modal, 'data-maquette-studio-state', 'loading');\n\n    getCart().then(function (cart) {\n      if (!cart.items || !cart.items.length) {\n        showState(modal, 'data-maquette-studio-state', 'error');\n        setText('[data-maquette-studio-error]', modal, 'Le panier est vide : ajoutez la plaque personnalis\u00E9e avant de l\u2019envoyer comme maquette.');\n        return null;\n      }\n      var payload = cartJsToPayload(cart);\n      payload.studioToken = studio.token;\n      var headers = { 'x-studio-token': studio.token };\n      return captureMountedImages(cart).then(function (mounted) {\n        if (Object.keys(mounted).length) payload.mockupImages = mounted;\n        return fetchJson(pdc.endpoint + '/carts', { method: 'POST', headers: headers, body: payload });\n      }).then(function (result) {\n        if (!result.ok || !result.data || !result.data.token) {\n          showState(modal, 'data-maquette-studio-state', 'error');\n          setText('[data-maquette-studio-error]', modal, errorMessage(result.status, result.data, 'studio'));\n          return null;\n        }\n        setText('[data-maquette-studio-reference]', modal, studio.reference);\n        showState(modal, 'data-maquette-studio-state', 'done');\n        // Straight back to the request's thread in the inbox: the mockup is sent to the customer from there\n        if (typeof result.data.inboxUrl === 'string' && /^https:\\/\\//.test(result.data.inboxUrl)) {\n          returnToInbox(result.data.inboxUrl);\n        }\n        return null;\n      });\n    }).catch(function () {\n      showState(modal, 'data-maquette-studio-state', 'error');\n      setText('[data-maquette-studio-error]', modal, errorMessage(0, null, 'studio'));\n    });\n  }\n\n  function initStudioCart() {\n    var modal = qs('[data-maquette-modal=\"studio\"]');\n    var studio = readStudioState();\n    qsa('[data-maquette-studio-send]').forEach(function (button) {\n      applyStudioButton(button, studio);\n      if (button.getAttribute('data-maquette-bound')) return;\n      button.setAttribute('data-maquette-bound', '1');\n      button.addEventListener('click', function (event) {\n        event.preventDefault();\n        if (modal) sendStudioCart(modal);\n      });\n    });\n    if (modal) {\n      bindModal(modal);\n      var retry = qs('[data-maquette-studio-retry]', modal);\n      if (retry && !retry.getAttribute('data-maquette-bound')) {\n        retry.setAttribute('data-maquette-bound', '1');\n        retry.addEventListener('click', function () { sendStudioCart(modal); });\n      }\n    }\n  }\n\n  // ---------------------------------------------------------------------------\n  // Restore (page /pages/maquette)\n  // ---------------------------------------------------------------------------\n\n  // Large plaque image: Printlane thumbnail (the real mockup), never the catalogue\n  // photo presented as \"votre maquette\". Without a thumbnail: neutral frame + phone number.\n  function renderMockupImage(item, previews, showTitle) {\n    var meta = item.meta || {};\n    var ref = printlaneRef(item.properties);\n    var src = ref && previews ? previews[ref] : null;\n    var title = meta.productTitle || meta.title || '';\n    var missing = el('div', { className: 'maquette-mockup__missing' }, [\n      el('p', { text: 'L\u2019aper\u00E7u de votre maquette n\u2019a pas pu s\u2019afficher ici. Vous le verrez dans votre panier apr\u00E8s validation.' }),\n      el('p', { text: 'Une question ? Appelez-nous au 09 78 45 01 34.' })\n    ]);\n    var figure = el('figure', { className: 'maquette-mockup' }, [\n      showTitle && title ? el('figcaption', { className: 'maquette-mockup__title', text: title }) : null\n    ]);\n    if (!src) {\n      figure.appendChild(missing);\n      return figure;\n    }\n    var image = el('img', { className: 'maquette-mockup__image', src: src, alt: 'Aper\u00E7u de votre plaque personnalis\u00E9e' });\n    // Click on the plaque = \"Je modifie moi-m\u00EAme\": Printlane editor opened on the page (initRestore)\n    var frame = el('div', { className: 'maquette-mockup__frame', role: 'button', tabindex: '0', title: 'Modifier ma plaque', 'aria-label': 'Modifier ma plaque', 'data-maquette-restore-edit': ref || '' }, [image]);\n    image.addEventListener('error', function () {\n      if (frame.parentNode) frame.parentNode.replaceChild(missing, frame);\n    });\n    figure.appendChild(frame);\n    return figure;\n  }\n\n  function variantText(item) {\n    var meta = (item && item.meta) || {};\n    return meta.variantTitle && meta.variantTitle !== 'Default Title' ? meta.variantTitle : '';\n  }\n\n  var CANDLE_HANDLE = 'bougie-souvenir-eternel';\n  var MATERIALS = { 'Plaque fun\u00E9raire': 'Plexiglass', 'Plaque premium': 'Granit' };\n  // Same display names as the cart (sections/cart-template.liquid)\n  var OPTION_LABELS = {\n    'Sans fixation': 'Aucun',\n    'Socle Noir': 'Pieds noirs',\n    'Socle Bronze': 'Pieds bronzes',\n    'Vis et cache vis': 'Vis et cache-vis',\n    'Socle Marbre Blanc': 'Socle Marbre',\n    'Socle Granit Gris': 'Socle gris perla',\n    'Socle Granit Noir': 'Socle granit'\n  };\n\n  // \"D\u00E9tails\" of the mockup page: material, then each option of the variant with its Shopify\n  // name (/products/<handle>.js, not stored with the mockup), then the other included items.\n  function renderRestoreDetails(page, item, extras) {\n    var box = qs('[data-maquette-restore-details]', page);\n    var list = qs('[data-maquette-restore-details-list]', page);\n    if (!box || !list) return Promise.resolve();\n    var rows = [];\n    var meta = (item && item.meta) || {};\n    if (MATERIALS[meta.productType]) rows.push(['Mati\u00E8re', MATERIALS[meta.productType]]);\n    var values = variantText(item) ? variantText(item).split(' / ').map(function (value) { return OPTION_LABELS[value] || value; }) : [];\n    var more = extras.map(function (extra) {\n      var extraMeta = extra.meta || {};\n      var label = extraMeta.productTitle || extraMeta.title || ('Article ' + extra.id);\n      return extra.quantity > 1 ? label + ' (\u00D7' + extra.quantity + ')' : label;\n    });\n    function draw(names) {\n      var all = rows.concat(values.map(function (value, index) { return [names[index] || ('Option ' + (index + 1)), value]; }));\n      if (more.length) all.push(['\u00C9galement inclus', more.join(', ')]);\n      list.innerHTML = '';\n      all.forEach(function (row) {\n        list.appendChild(el('li', {}, [el('span', { text: row[0] + ' :' }), el('strong', { text: row[1] })]));\n      });\n      show(box, all.length > 0);\n    }\n    // Drawn once the option names are known (no \"Option 1\" flash); generic names after 2.5 s\n    if (!values.length || !meta.handle) {\n      draw([]);\n      return Promise.resolve();\n    }\n    var names = fetchJson('/products/' + encodeURIComponent(meta.handle) + '.js').then(function (result) {\n      var product = result.ok ? result.data : null;\n      return product && Array.isArray(product.options) ? product.options.map(function (option) {\n        return typeof option === 'string' ? option : (option && option.name) || '';\n      }) : [];\n    }, function () { return []; });\n    var late = new Promise(function (resolve) { setTimeout(function () { resolve([]); }, 2500); });\n    return Promise.race([names, late]).then(draw);\n  }\n\n  // Same estimate as the product pages (assets/sections.js.liquid deliveryEstimation, moment fr)\n  function restoreDeliveryDate() {\n    var estimate = root.deliveryEstimation;\n    if (!estimate || typeof estimate.getEstimatedDelivery !== 'function' || !root.moment) return '';\n    try {\n      estimate.products = [];\n      return estimate.getEstimatedDelivery().chronopost.format('dddd DD MMM');\n    } catch (e) {\n      return '';\n    }\n  }\n\n  // The app embed does not load Printlane on /pages/maquette: script loaded on demand. Its own init\n  // reads printlane_shopify_data: \"cart\" page type = no product form to hook.\n  function loadPrintlane() {\n    if (root.printlane && typeof root.printlane.open === 'function') return Promise.resolve(root.printlane);\n    if (!root.printlane_shopify_data) {\n      root.printlane_shopify_data = { pageType: 'cart', customizableVariants: [], currentVariantId: '', generateThumbnail: true, cartRowSelector: '.cart__row', rootLocale: 'fr' };\n    }\n    return withTimeout(new Promise(function (resolve, reject) {\n      var script = doc.createElement('script');\n      script.src = PRINTLANE_SCRIPT;\n      script.async = true;\n      script.onload = function () {\n        if (root.printlane && typeof root.printlane.open === 'function') resolve(root.printlane);\n        else reject(new Error('printlane'));\n      };\n      script.onerror = function () { reject(new Error('printlane')); };\n      doc.head.appendChild(script);\n    }), 10000);\n  }\n\n  function initRestore() {\n    var page = qs('[data-maquette-restore]');\n    if (!page || page.getAttribute('data-maquette-bound')) return;\n    page.setAttribute('data-maquette-bound', '1');\n    var cartUrl = page.getAttribute('data-maquette-cart-url') || pdc.cartUrl;\n    var shared = null;\n    var busy = false;\n    var lastAction = null;\n    var slowTimer = null;\n    var progressTimer = null;\n    var edited = false;\n\n    function state(name) {\n      showState(page, 'data-maquette-restore-state', name);\n      var heading = qs('[data-maquette-restore-focus]');\n      // Not when the mockup is displayed: only when the step changes after an action (error, send)\n      if (heading && name !== 'loading' && name !== 'ready' && typeof heading.focus === 'function') {\n        try { heading.focus({ preventScroll: false }); } catch (e) { heading.focus(); }\n      }\n    }\n    function fail(message, retry) {\n      setText('[data-maquette-restore-error]', page, message);\n      show(qs('[data-maquette-restore-retry]', page), !!retry);\n      lastAction = retry || null;\n      state('error');\n    }\n    // Progress screen: \"Chargement\u2026\", then \"Termin\u00E9\" just before opening the cart\n    function progressDone(done) {\n      var box = qs('[data-maquette-restore-progress]', page);\n      if (box) box.classList.toggle('is-done', done);\n    }\n    function startProgress() {\n      progressDone(false);\n      var slow = qs('[data-maquette-restore-progress-slow]', page);\n      show(slow, false);\n      clearTimeout(progressTimer);\n      progressTimer = setTimeout(function () { show(slow, true); }, 10000);\n      state('progress');\n    }\n    function goCart(editRef) {\n      clearTimeout(progressTimer);\n      show(qs('[data-maquette-restore-progress-slow]', page), false);\n      progressDone(true);\n      storageRemove(STORAGE_RESTORE_TOKEN);\n      if (editRef) storageSet(STORAGE_EDIT_REF, editRef);\n      // Short pause so \"Termin\u00E9\" is seen before the cart loads\n      setTimeout(function () { root.location.replace(cartUrl); }, 500);\n    }\n\n    // Token: URL (#t= / ?t=), otherwise stored (page reloaded, Back button); removed from the URL.\n    var token = parseRestoreToken(root.location.hash, root.location.search) || storageGet(STORAGE_RESTORE_TOKEN);\n    stripLocationParams(['t']);\n    if (!token) {\n      fail(errorMessage(404, null, 'restore'));\n      return;\n    }\n    storageSet(STORAGE_RESTORE_TOKEN, token);\n\n    function render() {\n      var lines = mockupLines(shared.items);\n      var designs = lines.designs.length ? lines.designs : shared.items.slice(0, 1);\n      var extras = lines.designs.length ? lines.extras : shared.items.slice(1);\n      var box = qs('[data-maquette-restore-mockups]', page);\n      box.innerHTML = '';\n      designs.forEach(function (item) {\n        box.appendChild(renderMockupImage(item, shared.previews || {}, designs.length > 1));\n      });\n      var main = designs[0] || {};\n      var mainMeta = main.meta || {};\n      var productTitle = designs.length > 1 ? 'Votre commande' : (mainMeta.productTitle || mainMeta.title || 'Votre plaque');\n      setText('[data-maquette-restore-product]', page, productTitle);\n      setText('[data-maquette-restore-reference]', page, shared.requestReference || '');\n      show(qs('[data-maquette-restore-eyebrow]', page), !!shared.requestReference);\n      // \"Je modifie moi-m\u00EAme\" = click on the plaque: Printlane editor opened on this page\n      var editButton = qs('.maquette-restore__edit', page);\n      if (editButton) editButton.setAttribute('data-maquette-restore-edit', printlaneRef(main.properties) || '');\n      var candle = extras.some(function (item) { return ((item.meta || {}).handle || '') === CANDLE_HANDLE; });\n      show(qs('[data-maquette-restore-candle]', page), candle);\n      var details = renderRestoreDetails(page, designs.length > 1 ? null : main, extras.filter(function (item) {\n        return ((item.meta || {}).handle || '') !== CANDLE_HANDLE;\n      }));\n      var delivery = restoreDeliveryDate();\n      setText('.delivery-estimate', page, delivery);\n      show(qs('[data-maquette-restore-delivery-row]', page), !!delivery);\n      var total = sharedTotal(shared.items);\n      setText('[data-maquette-restore-total]', page, total === null ? '' : formatMoney(total, shared.currency || pdc.currency));\n      setText('[data-maquette-restore-installment]', page, total === null ? '' : formatMoney(Math.round(total / 3), shared.currency || pdc.currency));\n      show(qs('[data-maquette-restore-total-row]', page), total !== null);\n      var note = qs('[data-maquette-restore-note]', page);\n      if (note) {\n        show(note, !!shared.note);\n        setText('[data-maquette-restore-note-text]', page, shared.note || '');\n      }\n      details.then(function () { state('ready'); });\n    }\n\n    function load() {\n      state('loading');\n      var slow = qs('[data-maquette-restore-slow]', page);\n      show(slow, false);\n      clearTimeout(slowTimer);\n      slowTimer = setTimeout(function () { show(slow, true); }, 6000);\n      fetchWithTimeout(pdc.endpoint + '/carts/' + encodeURIComponent(token), { method: 'GET' }, 20000).then(function (result) {\n        clearTimeout(slowTimer);\n        // Network down, timeout or service outage: retryable\n        if (result.status === 0 || result.status >= 500) {\n          fail(errorMessage(0, null, 'restore'), load);\n          return;\n        }\n        // Invalid, revoked or expired link (the server does not tell them apart): new link by phone\n        if (!result.ok || !result.data || !Array.isArray(result.data.items) || !result.data.items.length) {\n          storageRemove(STORAGE_RESTORE_TOKEN);\n          fail(errorMessage(404, null, 'restore'));\n          return;\n        }\n        // Cart saved / shared by a customer: its own page (/pages/panier), never shown as a mockup\n        if (result.data.source === 'customer') {\n          storageRemove(STORAGE_RESTORE_TOKEN);\n          root.location.replace('/pages/panier#t=' + encodeURIComponent(token));\n          return;\n        }\n        shared = result.data;\n        if (shared.status === 'converted') state('ordered');\n        else render();\n      });\n    }\n\n    function validate(editRef) {\n      if (busy || !shared) return;\n      busy = true;\n      var button = qs('[data-maquette-restore-validate]', page);\n      if (button) { button.disabled = true; button.setAttribute('aria-busy', 'true'); }\n      startProgress();\n\n      function done() {\n        busy = false;\n        clearTimeout(progressTimer);\n        if (button) { button.disabled = false; button.removeAttribute('aria-busy'); }\n      }\n      function networkError() {\n        done();\n        fail(errorMessage(0, null, 'restore'), function () { validate(editRef); });\n      }\n\n      withTimeout(getCart(), 15000).then(function (current) {\n        // Edited design: the cart is rebuilt (the line's mockup image is no longer the right one)\n        if (!edited && isAlreadyLoaded(current, token, shared.items)) {\n          goCart(editRef);\n          return null;\n        }\n        // Decision: the cart becomes exactly the mockup (no question asked to the customer).\n        var clear = current.items && current.items.length ? fetchJson('/cart/clear.js', { method: 'POST', body: {} }) : Promise.resolve({ ok: true });\n        return clear.then(function (cleared) {\n          if (!cleared.ok) throw new Error('cart/clear.js (' + cleared.status + ')');\n          return restoreSequentially(Array.isArray(shared.items) ? shared.items : [], token, { fetch: doFetch, images: shared.thumbs || null });\n        }).then(function (report) {\n          if (!report.added.length) return report;\n          var attributes = filterAttributes(shared.attributes);\n          attributes[ATTRIBUTE_TOKEN] = token;\n          attributes[ATTRIBUTE_REQUEST] = shared.requestId ? String(shared.requestId) : '';\n          // A restored customer mockup is not a studio cart (see prepareCartForStudio)\n          attributes[ATTRIBUTE_STUDIO] = '';\n          attributes[ATTRIBUTE_REFERENCE] = shared.requestReference || '';\n          var update = function () {\n            return fetchJson('/cart/update.js', { method: 'POST', body: { attributes: attributes, note: shared.note || '' } });\n          };\n          // The `_maquette` attribute is what credits the order: one retry, then\n          // an error (the retry button rebuilds the cart) rather than a cart that converts unseen\n          return update().then(function (updated) {\n            return updated.ok ? updated : update();\n          }).then(function (updated) {\n            if (!updated.ok) throw new Error('cart/update.js (' + updated.status + ')');\n            // Restore count only: a failure here must not block the customer\n            return fetchJson(pdc.endpoint + '/carts/' + encodeURIComponent(token) + '/restored', { method: 'POST', body: {} });\n          }).then(function () { return report; });\n        }).then(function (report) {\n          var outcome = restoreOutcome(report);\n          if (outcome === 'done') {\n            goCart(editRef);\n            return;\n          }\n          done();\n          var failedList = qs('[data-maquette-restore-failed]', page);\n          if (failedList) {\n            failedList.innerHTML = '';\n            report.failed.forEach(function (entry) {\n              var meta = entry.item.meta || {};\n              failedList.appendChild(el('li', { text: meta.productTitle || meta.title || ('Article ' + entry.item.id) }));\n            });\n          }\n          var cartLink = qs('[data-maquette-restore-cart-link]', page);\n          if (cartLink) cartLink.href = cartUrl;\n          if (outcome === 'failed') storageRemove(STORAGE_RESTORE_TOKEN);\n          state(outcome);\n        });\n      }).catch(networkError);\n    }\n\n    // The saved design replaces the mockup's in the lines; its mockup image is dropped and the line\n    // flagged (the cart shows the Printlane thumbnail instead)\n    function useEditedDesign(oldRef, newRef) {\n      edited = true;\n      shared.items.forEach(function (item) {\n        var properties = item.properties || {};\n        Object.keys(properties).forEach(function (key) {\n          if (properties[key] !== oldRef) return;\n          properties[key] = newRef;\n          properties[LINE_PROPERTY_EDITED] = '1';\n        });\n      });\n      if (shared.thumbs) delete shared.thumbs[oldRef];\n    }\n\n    // \"Je modifie moi-m\u00EAme\" / click on the plaque: Printlane editor on this page; saved \u2192 cart.\n    // Printlane unavailable: previous behaviour (loaded into the cart, editor opened there).\n    function edit(ref) {\n      if (busy || !shared) return;\n      var parts = (ref || '').split('.');\n      if (parts.length !== 2) {\n        validate(ref || null);\n        return;\n      }\n      busy = true;\n      loadPrintlane().then(function (printlane) {\n        busy = false;\n        printlane.open({\n          shop: PRINTLANE_SHOP,\n          id: parts[0],\n          token: parts[1],\n          language: 'fr',\n          options: { generateThumbnail: true },\n          callback: function (id, designToken) {\n            printlane.close();\n            useEditedDesign(ref, id + '.' + designToken);\n            validate();\n          }\n        });\n      }, function () {\n        busy = false;\n        validate(ref);\n      });\n    }\n\n    qsa('[data-maquette-restore-validate]', page).forEach(function (button) {\n      button.addEventListener('click', function (event) { event.preventDefault(); validate(); });\n    });\n    // Clickable plaque (rendered after loading): delegated listeners\n    page.addEventListener('click', function (event) {\n      var frame = closest(event.target, '[data-maquette-restore-edit]');\n      if (!frame) return;\n      event.preventDefault();\n      edit(frame.getAttribute('data-maquette-restore-edit') || null);\n    });\n    page.addEventListener('keydown', function (event) {\n      if (event.key !== 'Enter' && event.key !== ' ') return;\n      var frame = closest(event.target, '[data-maquette-restore-edit]');\n      if (!frame) return;\n      event.preventDefault();\n      edit(frame.getAttribute('data-maquette-restore-edit') || null);\n    });\n    qsa('[data-maquette-restore-retry]', page).forEach(function (button) {\n      button.addEventListener('click', function (event) {\n        event.preventDefault();\n        if (typeof lastAction === 'function') lastAction();\n      });\n    });\n    qsa('[data-maquette-restore-again]', page).forEach(function (button) {\n      button.addEventListener('click', function (event) { event.preventDefault(); if (shared) render(); });\n    });\n\n    load();\n  }\n\n  // Arriving at the cart after a click on the plaque (mockup page): open the line's Printlane\n  // editor, exactly like \"Modifier ma plaque\". The Printlane script (app\n  // embed, pageType cart) attaches its listeners once loaded: wait for `printlane`.\n  function initPendingEditor() {\n    var ref = storageGet(STORAGE_EDIT_REF);\n    if (!ref) return;\n    var selector = '.colorlab-open-personalisation[data-colorlab=\"' + ref.replace(/[\"\\\\]/g, '') + '\"]';\n    if (!qs('.cart__row') && !qs(selector)) return;\n    storageRemove(STORAGE_EDIT_REF);\n    var started = Date.now();\n    (function attempt() {\n      var trigger = qs(selector);\n      if (trigger && (root.printlane || root.colorlab)) {\n        setTimeout(function () { trigger.click(); }, 400);\n        return;\n      }\n      if (Date.now() - started < 15000) setTimeout(attempt, 250);\n    })();\n  }\n\n  // ---------------------------------------------------------------------------\n  // Customer cart: save / share (assets/popup-antileave.js) and shared cart page\n  // (/pages/panier, assets/panier.js). Same proxy and same CartPayload as studio mode, no studio token:\n  //   POST {endpoint}/carts { cart, intent: 'save' | 'share', email?, token? } (JSON, else 415)\n  //   \u2192 201 { token, url, expiresAt, createdAt, reused } (403 { code: 'customer_carts_disabled' }, 413, 422, 429)\n  //   `token`: link already obtained for this cart (\"Obtenir le lien\"), reused by the e-mail save.\n  //   GET {endpoint}/carts/:token, then POST {endpoint}/carts/:token/restored (like /pages/maquette).\n  // Attribution: cart attribute `_panier` = token (never `_maquette`).\n  // ---------------------------------------------------------------------------\n\n  var CUSTOMER_MAX_LINES = 20;\n  var TOO_MANY_LINES = /too[ _]?(big|many)|<=\\s*20|20 (items|lines)/i;\n\n  function isCustomerCartLink(data) {\n    if (!data || typeof data.token !== 'string' || !CART_TOKEN_PATTERN.test(data.token)) return false;\n    return typeof data.url === 'string' && data.url.indexOf('https://') === 0 && data.url.indexOf('#t=' + data.token) !== -1;\n  }\n\n  // Code of a refused save: the backend's own `code`, else \"too many lines\" read from the 422 detail\n  function customerCartErrorCode(result) {\n    var data = result && result.data;\n    if (data && typeof data.code === 'string') return data.code;\n    var detail = data && data.data && typeof data.data.message === 'string' ? data.data.message : (data && typeof data.message === 'string' ? data.message : '');\n    if (result && result.status === 422 && /items/i.test(detail) && TOO_MANY_LINES.test(detail)) return 'too_many_lines';\n    return null;\n  }\n\n  // Never rejected: { ok, status, data, code }. `ms` = budget for /cart.js + POST (timeout \u2192 status 0).\n  // options.token: link already obtained for this cart, sent back so that the same link is reused.\n  function createCustomerCart(intent, email, ms, options) {\n    var opts = options || {};\n    var budget = typeof ms === 'number' && ms > 0 ? ms : 4000;\n    var started = Date.now();\n    return withTimeout(getCart(), budget).then(function (cart) {\n      if (!cart || !Array.isArray(cart.items) || !cart.items.length) return { ok: false, status: 0, data: null, code: 'empty_cart' };\n      // Same limit as the backend (422): no request sent\n      if (cart.items.length > CUSTOMER_MAX_LINES) return { ok: false, status: 422, data: null, code: 'too_many_lines' };\n      var body = { cart: cartJsToPayload(cart), intent: intent === 'share' ? 'share' : 'save' };\n      if (email) body.email = String(email).trim();\n      if (typeof opts.token === 'string' && CART_TOKEN_PATTERN.test(opts.token)) body.token = opts.token;\n      var left = Math.max(budget - (Date.now() - started), 500);\n      // fetchJson sends the object body as JSON with `Content-Type: application/json` (required, 415 otherwise)\n      return fetchWithTimeout(pdc.endpoint + '/carts', { method: 'POST', body: body }, left).then(function (result) {\n        if (result.ok && isCustomerCartLink(result.data)) return { ok: true, status: result.status, data: result.data, code: null };\n        return { ok: false, status: result.status, data: result.data, code: customerCartErrorCode(result) };\n      });\n    }).catch(function () {\n      return { ok: false, status: 0, data: null, code: 'timeout' };\n    });\n  }\n\n  // { ok, status, data } \u2014 data = shared cart (items, previews, thumbs, attributes, note, currency, status)\n  function fetchCustomerCart(token) {\n    return fetchWithTimeout(pdc.endpoint + '/carts/' + encodeURIComponent(token), { method: 'GET' }, 20000);\n  }\n\n  // Shared cart already taken in this cart (link reopened): every line is there, attribute set.\n  function isCustomerCartLoaded(cart, token, sharedItems) {\n    if (!cart || !token) return false;\n    if (normalizeStringMap(cart.attributes)[ATTRIBUTE_PANIER] !== token) return false;\n    var lines = Array.isArray(cart.items) ? cart.items : [];\n    var expected = Array.isArray(sharedItems) ? sharedItems : [];\n    return expected.length > 0 && expected.every(function (item) {\n      var ref = printlaneRef(item.properties);\n      return lines.some(function (line) {\n        return line.variant_id === item.id && (!ref || printlaneRef(line.properties) === ref);\n      });\n    });\n  }\n\n  // mode 'replace' (cart emptied first) or 'merge'. Lines added one by one (restoreSequentially, no\n  // `_maquette` line token), then `_panier` attribute, then restore count. Rejected only if /cart.js or\n  // /cart/clear.js fail; resolves the add report { added, failed, attributed }.\n  function applyCustomerCart(shared, token, mode) {\n    var replace = mode === 'replace';\n    var items = shared && Array.isArray(shared.items) ? shared.items : [];\n    var current = null;\n    return withTimeout(getCart(), 15000).then(function (cart) {\n      current = cart;\n      var clear = replace && current.items && current.items.length ? fetchJson('/cart/clear.js', { method: 'POST', body: {} }) : Promise.resolve({ ok: true });\n      return clear.then(function (cleared) {\n        if (!cleared.ok) throw new Error('cart/clear.js (' + cleared.status + ')');\n        return restoreSequentially(items, null, { fetch: doFetch });\n      });\n    }).then(function (report) {\n      report.attributed = false;\n      if (!report.added.length) return report;\n      // Replace: the shared cart's own attributes and note come with it, and the mockup attributes\n      // left in the visitor's cart are emptied (clear.js keeps attributes: a leftover `_maquette` would\n      // credit a graphic designer); merge: only `_panier`\n      var attributes = replace ? filterAttributes(shared.attributes) : {};\n      if (replace) {\n        Object.keys(normalizeStringMap(current && current.attributes)).forEach(function (key) {\n          if (key.indexOf(ATTRIBUTE_PREFIX) === 0 || key.indexOf('_studio') === 0) attributes[key] = '';\n        });\n        [ATTRIBUTE_TOKEN, ATTRIBUTE_REQUEST, ATTRIBUTE_REFERENCE, ATTRIBUTE_STUDIO].forEach(function (key) { attributes[key] = ''; });\n      }\n      attributes[ATTRIBUTE_PANIER] = token;\n      var body = { attributes: attributes };\n      if (replace && shared.note) body.note = String(shared.note);\n      var update = function () { return fetchJson('/cart/update.js', { method: 'POST', body: body }); };\n      // Attribution only: one retry, a failure never blocks the customer (the cart is right)\n      return update().then(function (updated) {\n        return updated.ok ? updated : update();\n      }).then(function (updated) {\n        report.attributed = !!updated.ok;\n        return fetchJson(pdc.endpoint + '/carts/' + encodeURIComponent(token) + '/restored', { method: 'POST', body: {} });\n      }).then(function () { return report; });\n    });\n  }\n\n  pdc.customerCart = {\n    attribute: ATTRIBUTE_PANIER,\n    maxLines: CUSTOMER_MAX_LINES,\n    create: createCustomerCart,\n    fetch: fetchCustomerCart,\n    apply: applyCustomerCart,\n    isLoaded: isCustomerCartLoaded,\n    getCart: getCart,\n    parseToken: parseRestoreToken,\n    printlaneRef: printlaneRef,\n    visibleProperties: visibleProperties,\n    sharedTotal: sharedTotal,\n    linePrice: linePrice,\n    restoreOutcome: restoreOutcome,\n    formatMoney: formatMoney,\n    formatDate: formatDateFr\n  };\n\n  // ---------------------------------------------------------------------------\n  // Studio status (Addendum A)\n  // ---------------------------------------------------------------------------\n\n  function readStatusCache() {\n    var raw = storageGet(STORAGE_STATUS);\n    if (!raw) return null;\n    try {\n      var cached = JSON.parse(raw);\n      if (!cached || typeof cached.at !== 'number' || Date.now() - cached.at > STATUS_CACHE_MS) return null;\n      return cached.status;\n    } catch (e) {\n      return null;\n    }\n  }\n\n  function applyStatus(status) {\n    var online = !!(status && status.online);\n    qsa('[data-maquette-cta]').forEach(function (node) {\n      node.classList.toggle('is-online', online);\n      node.classList.add('is-resolved');\n    });\n  }\n\n  // Fetched only where a visible entry point shows it (badge, listing card), or when the popup opens (force)\n  function loadStatus(force) {\n    if (force !== true && !qs('.maquette-gs')) return;\n    var cached = readStatusCache();\n    if (cached) {\n      applyStatus(cached);\n      return;\n    }\n    function ok(result) {\n      return result.ok && result.data && typeof result.data.online === 'boolean';\n    }\n    fetchWithTimeout(pdc.endpoint + pdc.statusPath, { method: 'GET' }, STATUS_TIMEOUT_MS).then(function (result) {\n      if (ok(result)) return result;\n      // Fallback: public endpoint (CORS) if the proxy fails\n      return fetchWithTimeout(pdc.fallbackStatusUrl, { method: 'GET', credentials: 'omit', mode: 'cors' }, STATUS_TIMEOUT_MS);\n    }).then(function (result) {\n      if (!ok(result)) return; // failure: stay offline (Liquid render)\n      storageSet(STORAGE_STATUS, JSON.stringify({ at: Date.now(), status: result.data }));\n      applyStatus(result.data);\n    });\n  }\n\n  function scheduleStatus() {\n    if (typeof root.requestIdleCallback === 'function') root.requestIdleCallback(loadStatus, { timeout: 1500 });\n    else setTimeout(loadStatus, 50);\n  }\n\n  // ---------------------------------------------------------------------------\n  // Mockup request (plan \u00A72.6 B) \u2014 popup, capture, send, toast, Printlane hooks\n  // ---------------------------------------------------------------------------\n\n  var flags = normalizeFlags(pdc.flags);\n  pdc.flags = pdc.flags && typeof pdc.flags === 'object' ? pdc.flags : {};\n  FLAG_KEYS.forEach(function (key) { pdc.flags[key] = flags[key]; });\n\n  // design: Printlane reference of the customer's own design (null: none); hasModel: tabs shown;\n  // mode: 'design' (\"Depuis ce produit\") | 'scratch'\n  var request = { files: [], previews: [], opts: null, snapshot: null, design: null, frontImage: null, openImage: null, hasModel: false, mode: 'scratch', background: null, backgroundLoading: null };\n  // \"Votre fond\" model: the customer brings their own background (file import)\n  var CUSTOM_BACKGROUND = 'plaque-funeraire-personnalisee';\n  // Products of the \"Mod\u00E8le\" picker (/products/<handle>.js), by handle: promises (loadModel)\n  var backgroundProducts = {};\n\n  function requestModal() { return qs('[data-maquette-modal=\"request\"]'); }\n\n  function closest(node, selector) {\n    return node && typeof node.closest === 'function' ? node.closest(selector) : null;\n  }\n\n  function detectPage(trigger) {\n    var explicit = attr(trigger, 'data-maquette-page');\n    if (explicit) return normalizePage(explicit);\n    if (pdc.page) return normalizePage(pdc.page);\n    var className = doc.body ? String(doc.body.className) : '';\n    if (/\\bproduct\\b/.test(className) || qs('[data-product-form]')) return 'product';\n    if (/\\bcart\\b/.test(className)) return 'cart';\n    return 'home';\n  }\n\n  function productContainer(trigger) {\n    return closest(trigger, '[data-product-form]') || qs('[data-product-form]');\n  }\n\n  function showRequestState(modal, name) { showState(modal, 'data-maquette-request-state', name); }\n\n  function requestError(modal, message) {\n    var node = qs('[data-maquette-request-error]', modal);\n    if (!node) return;\n    node.textContent = message || '';\n    show(node, !!message);\n  }\n\n  // Channel: email only if no WhatsApp number is configured; otherwise the clicked button decides\n  // (\"\u00C9changer sur WhatsApp\" or \"Recevoir par email\" \u2192 email field + \"Envoyer ma demande\").\n  function showEmailField(modal, visible) {\n    var field = qs('[data-maquette-request-email-field]', modal);\n    show(field, visible);\n    var reveal = qs('[data-maquette-request-email-reveal]', modal);\n    show(reveal, !visible);\n    var dialog = qs('.maquette-request', modal);\n    if (dialog) dialog.classList.toggle('is-email-open', visible);\n  }\n\n  function resetChannel(modal) {\n    showEmailField(modal, !pdc.whatsapp);\n  }\n\n  // Tabs \"Depuis ce produit\" / \"En repartant de z\u00E9ro\" (like Otypo), only when the popup\n  // has a model to start from: the product page, or a design the customer just saved\n  // (toast). Anywhere else (listing, home, cart link) it is always from scratch.\n  function renderDesignMode(modal) {\n    show(qs('[data-maquette-request-tabs]', modal), request.hasModel);\n    qsa('[data-maquette-request-mode]', modal).forEach(function (tab) {\n      var active = tab.getAttribute('data-maquette-request-mode') === request.mode;\n      tab.classList.toggle('is-active', active);\n      tab.setAttribute('aria-selected', active ? 'true' : 'false');\n    });\n    var preview = qs('[data-maquette-request-design]', modal);\n    var image = qs('[data-maquette-request-design-image]', modal);\n    show(preview, request.hasModel && request.mode === 'design' && !!(image && image.getAttribute('src')));\n    // Background picker: the product's own background goes with \"Depuis ce produit\"\n    qsa('[data-maquette-request-scratch-only]', modal).forEach(function (picker) {\n      show(picker, request.mode === 'scratch');\n    });\n  }\n\n  // Product photos carry a wide white margin around the plaque: crop the image to what\n  // is not white (or transparent) so the plaque fills the fixed-height frame. Needs readable\n  // pixels (Shopify CDN sends CORS *, Printlane thumbnails are data/blob URLs); otherwise\n  // the image stays as it is.\n  function trimWhitespace(image) {\n    if (image.getAttribute('data-maquette-trimmed') === image.getAttribute('src')) return;\n    var width = image.naturalWidth;\n    var height = image.naturalHeight;\n    if (!width || !height) return;\n    try {\n      var scale = Math.min(1, 300 / Math.max(width, height));\n      var probe = document.createElement('canvas');\n      probe.width = Math.max(1, Math.round(width * scale));\n      probe.height = Math.max(1, Math.round(height * scale));\n      var context = probe.getContext('2d');\n      context.drawImage(image, 0, 0, probe.width, probe.height);\n      var pixels = context.getImageData(0, 0, probe.width, probe.height).data;\n      var left = probe.width, top = probe.height, right = -1, bottom = -1;\n      for (var y = 0; y < probe.height; y++) {\n        for (var x = 0; x < probe.width; x++) {\n          var i = (y * probe.width + x) * 4;\n          if (pixels[i + 3] < 16 || (pixels[i] > 238 && pixels[i + 1] > 238 && pixels[i + 2] > 238)) continue;\n          if (x < left) left = x;\n          if (x > right) right = x;\n          if (y < top) top = y;\n          if (y > bottom) bottom = y;\n        }\n      }\n      if (right < 0) return;\n      // Back to full resolution, with a small margin so the shadow is not cut\n      var margin = 0.04 * Math.max(right - left, bottom - top);\n      var sx = Math.max(0, (left - margin) / scale);\n      var sy = Math.max(0, (top - margin) / scale);\n      var sw = Math.min(width, (right + 1 + margin) / scale) - sx;\n      var sh = Math.min(height, (bottom + 1 + margin) / scale) - sy;\n      // Less than 10% to gain: not worth replacing the image\n      if (sw * sh > 0.9 * width * height) return;\n      var output = document.createElement('canvas');\n      var outScale = Math.min(1, 900 / Math.max(sw, sh));\n      output.width = Math.round(sw * outScale);\n      output.height = Math.round(sh * outScale);\n      output.getContext('2d').drawImage(image, sx, sy, sw, sh, 0, 0, output.width, output.height);\n      var cropped = output.toDataURL('image/png');\n      image.setAttribute('data-maquette-trimmed', cropped);\n      image.setAttribute('src', cropped);\n    } catch (e) { /* tainted canvas (no CORS): keep the full image */ }\n  }\n\n  // The customer's design (Printlane thumbnail, read in the browser that made it),\n  // else the product photo of the selected variant\n  function loadModelPreview(modal) {\n    var image = qs('[data-maquette-request-design-image]', modal);\n    if (!image) return;\n    // Spinner instead of a blank frame until the (cropped) image is shown\n    var frame = qs('[data-maquette-request-design]', modal);\n    function loading(on) { if (frame) frame.classList.toggle('is-loading', on); }\n    if (!image.getAttribute('data-maquette-trim-bound')) {\n      image.setAttribute('data-maquette-trim-bound', '1');\n      image.addEventListener('load', function () {\n        var src = image.getAttribute('src');\n        trimWhitespace(image);\n        // Cropped: the cropped copy loads next\n        if (image.getAttribute('src') === src) loading(false);\n      });\n      image.addEventListener('error', function () { loading(false); });\n    }\n    loading(true);\n    image.removeAttribute('src');\n    image.removeAttribute('data-maquette-trimmed');\n    var ref = request.design;\n    var fallback = request.frontImage || (request.snapshot && request.snapshot.product ? request.snapshot.product.image : null);\n    (ref ? thumbnailFromPrintlane(ref) : Promise.resolve(null)).then(function (src) {\n      if (request.design !== ref) return;\n      if (src || fallback) image.setAttribute('src', src || fallback);\n      else loading(false);\n      renderDesignMode(modal);\n    });\n  }\n\n  function revokePreviews() {\n    request.previews.forEach(function (url) {\n      try { root.URL.revokeObjectURL(url); } catch (e) { /* already revoked */ }\n    });\n    request.previews = [];\n  }\n\n  function renderPreviews(modal) {\n    var list = qs('[data-maquette-request-previews]', modal);\n    if (!list) return;\n    list.innerHTML = '';\n    revokePreviews();\n    request.files.forEach(function (file, index) {\n      var isImage = /^image\\//.test(file.type || '');\n      var visual;\n      if (isImage && root.URL && typeof root.URL.createObjectURL === 'function') {\n        var url = root.URL.createObjectURL(file);\n        request.previews.push(url);\n        visual = el('img', { className: 'maquette-request__preview-image', src: url, alt: '' });\n      } else {\n        visual = el('span', { className: 'maquette-request__preview-image maquette-request__preview-image--file', text: 'PDF' });\n      }\n      list.appendChild(el('li', { className: 'maquette-request__preview' }, [\n        visual,\n        el('span', { className: 'maquette-request__preview-name', text: file.name + ' \u00B7 ' + formatBytes(file.size) }),\n        el('button', { type: 'button', className: 'maquette-request__preview-remove', 'data-maquette-request-remove': String(index), 'aria-label': 'Retirer ' + file.name, text: 'Retirer' })\n      ]));\n    });\n    show(list, request.files.length > 0);\n  }\n\n  function addFiles(modal, files) {\n    var validated = validateFiles(request.files.concat(toArray(files)));\n    request.files = validated.accepted;\n    var error = qs('[data-maquette-request-files-error]', modal);\n    if (error) {\n      error.textContent = fileRejectionMessage(validated.rejected);\n      show(error, validated.rejected.length > 0);\n    }\n    renderPreviews(modal);\n  }\n\n  function readRequestMemo() {\n    var raw = storageGet(STORAGE_REQUEST);\n    if (!raw) return null;\n    try { return JSON.parse(raw); } catch (e) { return null; }\n  }\n\n  function renderRequestDone(modal, result, channel, email, qr) {\n    var response = result.response || {};\n    var whatsappBlock = qs('[data-maquette-request-done-whatsapp]', modal);\n    var emailBlock = qs('[data-maquette-request-done-email]', modal);\n    var fallbackBlock = qs('[data-maquette-request-done-fallback]', modal);\n    var qrBlock = qs('[data-maquette-request-done-qr]', modal);\n    var hasLink = channel === 'whatsapp' && !!response.whatsappUrl;\n    var withQr = hasLink && qr && !!qrBlock;\n    show(qs('[data-maquette-request-done-received]', modal), false);\n    show(qrBlock, withQr);\n    // QR code: no \u00AB Continuer sur le site \u00BB while waiting, leaving there loses the request\n    show(qs('.maquette-request__continue', modal), !withQr);\n    show(whatsappBlock, hasLink && !withQr);\n    show(emailBlock, channel === 'email');\n    show(fallbackBlock, channel === 'whatsapp' && !response.whatsappUrl);\n    // \"Ouvrir WhatsApp\" only when the browser blocked the pre-opened WhatsApp tab\n    var link = qs('[data-maquette-request-whatsapp-link]', modal);\n    if (link && hasLink) link.href = response.whatsappUrl;\n    show(link, hasLink && !withQr && result.whatsapp === 'blocked');\n    if (channel === 'email') setText('[data-maquette-request-done-email-address]', modal, email || '');\n    show(qs('[data-maquette-request-duplicate]', modal), !!result.duplicate);\n    var rejected = qs('[data-maquette-request-done-rejected]', modal);\n    if (rejected) {\n      var list = (result.rejectedFiles || []).map(function (entry) { return entry.name; });\n      rejected.textContent = list.length ? 'Ces fichiers n\u2019ont pas pu \u00EAtre joints : ' + list.join(', ') + '. Vous pourrez les envoyer en r\u00E9pondant \u00E0 notre email (ou dans WhatsApp).' : '';\n      show(rejected, list.length > 0);\n    }\n    showRequestState(modal, 'done');\n    if (withQr) startQr(modal, qrBlock, response);\n    var block = withQr ? qrBlock : (hasLink ? whatsappBlock : (channel === 'email' ? emailBlock : fallbackBlock));\n    var title = block ? qs('[data-maquette-request-done-title]', block) : null;\n    if (title) {\n      try { title.focus(); } catch (e) { /* focus refused */ }\n    }\n  }\n\n  // ----- Desktop WhatsApp: QR code until the customer's message arrives -----\n  // On a computer wa.me lands on a page asking for an app most customers do not have there.\n  var QR_POLL_MS = 4000;\n  var QR_HINT_MS = 90000;\n  var QR_POLL_MAX_MS = 15 * 60000;\n  var qrPoll = null;\n  var qrLibrary = null;\n\n  function prefersQrCode() {\n    return typeof root.matchMedia === 'function' && !root.matchMedia('(pointer: coarse)').matches;\n  }\n\n  function loadQrLibrary(src) {\n    if (typeof root.qrcode === 'function') return Promise.resolve(root.qrcode);\n    if (!qrLibrary) {\n      qrLibrary = new Promise(function (resolve, reject) {\n        var script = el('script', { src: src });\n        script.onload = function () { if (typeof root.qrcode === 'function') resolve(root.qrcode); else reject(new Error('qrcode')); };\n        script.onerror = reject;\n        doc.head.appendChild(script);\n      }).then(null, function (error) {\n        qrLibrary = null;\n        throw error;\n      });\n    }\n    return qrLibrary;\n  }\n\n  function drawQr(canvas, url, src) {\n    if (!canvas) return;\n    show(canvas, true);\n    loadQrLibrary(src).then(function (qrcode) {\n      var code = qrcode(0, 'M');\n      code.addData(url);\n      code.make();\n      var count = code.getModuleCount();\n      // 2 white modules around (quiet zone), whole pixels per module: sharp\n      var cell = Math.max(1, Math.floor(canvas.width / (count + 4)));\n      var offset = Math.floor((canvas.width - cell * count) / 2);\n      var context = canvas.getContext('2d');\n      context.fillStyle = '#ffffff';\n      context.fillRect(0, 0, canvas.width, canvas.height);\n      context.fillStyle = '#000000';\n      for (var row = 0; row < count; row += 1) {\n        for (var col = 0; col < count; col += 1) {\n          if (code.isDark(row, col)) context.fillRect(offset + col * cell, offset + row * cell, cell, cell);\n        }\n      }\n    }).then(null, function () {\n      // No QR code: the \u00AB installed on this computer \u00BB link and email stay\n      show(canvas, false);\n    });\n  }\n\n  function stopQr() {\n    if (!qrPoll) return;\n    clearTimeout(qrPoll.timer);\n    clearTimeout(qrPoll.hint);\n    qrPoll = null;\n  }\n\n  function startQr(modal, block, response) {\n    stopQr();\n    var app = qs('[data-maquette-request-qr-app]', block);\n    if (app) app.href = response.whatsappUrl;\n    var hint = qs('[data-maquette-request-qr-hint]', block);\n    show(hint, false);\n    show(qs('[data-maquette-request-qr-wait]', block), true);\n    drawQr(qs('[data-maquette-request-qr]', block), shortWhatsappUrl(response.whatsappUrl), block.getAttribute('data-maquette-request-qr-script'));\n\n    var poll = qrPoll = { startedAt: Date.now(), timer: null, hint: null };\n    poll.hint = setTimeout(function () { show(hint, true); }, QR_HINT_MS);\n    var url = pdc.endpoint + pdc.requestPath + '/' + encodeURIComponent(response.reference || '');\n    function tick() {\n      if (qrPoll !== poll) return;\n      // Popup closed or replaced (InstantClick page change): their message still attaches on our side\n      if (modal.hasAttribute('hidden') || !doc.documentElement.contains(modal)) {\n        stopQr();\n        return;\n      }\n      // Gave up: no more \u00AB En attente \u00BB that would never turn into \u00AB Re\u00E7u \u00BB\n      if (Date.now() - poll.startedAt > QR_POLL_MAX_MS) {\n        stopQr();\n        show(qs('[data-maquette-request-qr-wait]', block), false);\n        show(hint, true);\n        return;\n      }\n      fetchJson(url, { method: 'GET' }).then(function (result) {\n        if (qrPoll !== poll) return;\n        if (result.ok && result.data && result.data.received) {\n          stopQr();\n          showReceived(modal);\n          return;\n        }\n        poll.timer = setTimeout(tick, QR_POLL_MS);\n      });\n    }\n    poll.timer = setTimeout(tick, QR_POLL_MS);\n  }\n\n  function showReceived(modal) {\n    request.files = [];\n    renderPreviews(modal);\n    show(qs('[data-maquette-request-done-qr]', modal), false);\n    var block = qs('[data-maquette-request-done-received]', modal);\n    show(block, true);\n    show(qs('.maquette-request__continue', modal), true);\n    var title = block ? qs('[data-maquette-request-done-title]', block) : null;\n    if (title) {\n      try { title.focus(); } catch (e) { /* focus refused */ }\n    }\n  }\n\n  // \u00AB Plut\u00F4t par email ? \u00BB: back to the form, text and files kept, only the address is missing\n  function qrToEmail(modal) {\n    stopQr();\n    showRequestState(modal, 'form');\n    showEmailField(modal, true);\n    var input = qs('[data-maquette-request-email]', modal);\n    if (input) {\n      try {\n        input.focus();\n        // Long form above (pickers): keep the field in view on a small laptop\n        if (typeof input.scrollIntoView === 'function') input.scrollIntoView({ block: 'center' });\n      } catch (e) { /* focus refused */ }\n    }\n  }\n\n  function fieldError(field, invalid) {\n    if (!field) return;\n    if (invalid) {\n      field.setAttribute('aria-invalid', 'true');\n      field.setAttribute('aria-describedby', 'maquette-request-error');\n    } else {\n      field.removeAttribute('aria-invalid');\n      field.removeAttribute('aria-describedby');\n    }\n  }\n\n  // `channel`: 'whatsapp' (WhatsApp button, SYNCHRONOUS call from the click: the window is pre-opened\n  // before any await) or 'email' (form). Text OR files are enough (the server accepts an empty text).\n  function submitRequest(modal, channelChoice) {\n    var opts = request.opts || { page: detectPage(null), trigger: null };\n    var textarea = qs('[data-maquette-request-text]', modal);\n    var emailInput = qs('[data-maquette-request-email]', modal);\n    var text = textarea ? String(textarea.value || '').trim() : '';\n    var email = emailInput ? String(emailInput.value || '').trim() : '';\n    var channel = channelChoice === 'whatsapp' && pdc.whatsapp ? 'whatsapp' : 'email';\n    var qr = channel === 'whatsapp' && prefersQrCode();\n    requestError(modal, '');\n    fieldError(textarea, false);\n    fieldError(emailInput, false);\n    if (!text && !request.files.length) {\n      requestError(modal, 'D\u00E9crivez votre besoin ou importez un fichier pour que notre graphiste puisse vous aider.');\n      fieldError(textarea, true);\n      if (textarea) textarea.focus();\n      return;\n    }\n    if (channel === 'email' && !isValidEmail(email)) {\n      showEmailField(modal, true);\n      requestError(modal, 'Indiquez votre adresse email pour recevoir la maquette (par exemple : marie.dupont@orange.fr).');\n      fieldError(emailInput, true);\n      if (emailInput) emailInput.focus();\n      return;\n    }\n\n    // Model still loading: send once it is there (it becomes the request's product)\n    if (request.backgroundLoading) {\n      // Buttons hidden meanwhile: no second click, no double request\n      showRequestState(modal, 'sending');\n      request.backgroundLoading.then(function () { submitRequest(modal, channelChoice); });\n      return;\n    }\n\n    // New snapshot at send time (variant / texts / files may have changed)\n    var container = opts.page === 'product' ? productContainer(opts.trigger) : null;\n    var snapshot = captureProductForm(container, doc);\n    var fromScratch = request.mode === 'scratch';\n    if (fromScratch && request.background) {\n      var model = request.background;\n      var base = modelBaseVariant(model);\n      // Shape + fixing, else the shape alone (some shapes only exist with a few fixings)\n      snapshot.product = productSnapshot(model, pickedVariant(modal, model, base.id) || pickedVariant(modal, model, base.id, 'Forme') || base, null, 1);\n    }\n    // Shape / fixing changed in the popup: send that variant (the studio opens on it), unless a\n    // Printlane design goes with the request (it belongs to the product form's variant)\n    if (snapshot.product && !(fromScratch && request.background) && (fromScratch || (!snapshot.printlaneRefs.length && !request.design))) {\n      var product = parseProductJson(attr(container, 'data-product'));\n      var picked = pickedVariant(modal, product, snapshot.product.variantId);\n      if (picked && Number(picked.id) !== snapshot.product.variantId) {\n        snapshot.product.variantId = Number(picked.id);\n        snapshot.product.variantTitle = picked.title && picked.title !== 'Default Title' ? truncate(picked.title, 255) : null;\n        snapshot.product.options = variantOptions(product, picked);\n        snapshot.product.price = typeof picked.price === 'number' ? picked.price : null;\n        snapshot.product.image = variantImage(product, picked);\n      }\n    }\n    var choices = {};\n    qsa('[data-maquette-request-picker]', modal).forEach(function (picker) {\n      var checked = !picker.hidden && qs('input:checked', picker);\n      // The model goes by its name (\"Marbre noir\"), so the designer knows the customer picked it\n      if (checked) choices[picker.getAttribute('data-maquette-request-picker')] = picker.hasAttribute('data-maquette-request-scratch-only') ? checked.getAttribute('aria-label') : checked.value;\n    });\n    show(qs('[data-maquette-request-sending-files]', modal), request.files.length > 0);\n    showRequestState(modal, 'sending');\n\n    sendRequest({\n      channel: channel,\n      email: email,\n      text: text,\n      page: opts.page,\n      snapshot: snapshot,\n      files: request.files,\n      design: fromScratch ? null : request.design,\n      // Also drops a Printlane draft left by an earlier product page (InstantClick keeps `window`)\n      fromScratch: fromScratch,\n      choices: choices,\n      draft: pdc.flags.printlaneDraftHook ? pdc.printlaneDraft : null,\n      pageUrl: root.location ? root.location.href : '',\n      locale: pdc.locale || (doc.documentElement && doc.documentElement.lang) || ''\n    }, {\n      // QR code: no WhatsApp tab (sendRequest opens none without this port)\n      openWindow: qr ? null : function () {\n        try { return root.open('about:blank', '_blank'); } catch (e) { return null; }\n      },\n      fetchJson: fetchJson,\n      readMemo: readRequestMemo,\n      writeMemo: function (memo) { storageSet(STORAGE_REQUEST, JSON.stringify(memo)); },\n      FormData: root.FormData\n    }).then(function (result) {\n      if (result.status !== 'done') {\n        showRequestState(modal, 'form');\n        requestError(modal, result.message);\n        return;\n      }\n      // QR code: files kept until the message arrives (\u00AB Plut\u00F4t par email ? \u00BB resends them)\n      if (result.duplicate === false && !qr) {\n        request.files = [];\n        renderPreviews(modal);\n      }\n      renderRequestDone(modal, result, channel, email, qr);\n    });\n  }\n\n  // A third-party theme script removes the <input type=\"file\"> present at page\n  // load (seen on plapuedacaes.com, 25/09): the popup's one is (re)created\n  // on first open; an input added after load is not removed.\n  function createFileInputIfMissing(modal) {\n    var input = qs('[data-maquette-request-files]', modal);\n    if (input) return input;\n    var label = qs('.maquette-request__files-button', modal);\n    if (!label) return null;\n    input = doc.createElement('input');\n    input.type = 'file';\n    input.multiple = true;\n    input.accept = 'image/*,.pdf';\n    input.setAttribute('data-maquette-request-files', '');\n    label.appendChild(input);\n    return input;\n  }\n\n  // Listener set on the input itself (idempotent): called on every open,\n  // since the input may have been removed and recreated in the meantime.\n  function ensureFileInput(modal) {\n    var input = createFileInputIfMissing(modal);\n    if (input && !input.getAttribute('data-maquette-bound')) {\n      input.setAttribute('data-maquette-bound', '1');\n      input.addEventListener('change', function () {\n        addFiles(modal, input.files);\n        input.value = '';\n      });\n    }\n    return input;\n  }\n\n  function bindRequestModal(modal) {\n    // Own marker: `data-maquette-bound` is bindModal's (otherwise the cross and \"Fermer\" are never wired)\n    if (modal.getAttribute('data-maquette-request-bound')) return;\n    modal.setAttribute('data-maquette-request-bound', '1');\n    bindModal(modal);\n    var form = qs('[data-maquette-request-form]', modal);\n    if (form) {\n      form.addEventListener('submit', function (event) {\n        event.preventDefault();\n        submitRequest(modal, 'email');\n      });\n    }\n    qsa('[data-maquette-request-send=\"whatsapp\"]', modal).forEach(function (button) {\n      button.addEventListener('click', function (event) {\n        event.preventDefault();\n        submitRequest(modal, 'whatsapp');\n      });\n    });\n    qsa('[data-maquette-request-qr-email]', modal).forEach(function (button) {\n      button.addEventListener('click', function (event) {\n        event.preventDefault();\n        qrToEmail(modal);\n      });\n    });\n    qsa('[data-maquette-request-email-reveal]', modal).forEach(function (button) {\n      button.addEventListener('click', function (event) {\n        event.preventDefault();\n        showEmailField(modal, true);\n        var input = qs('[data-maquette-request-email]', modal);\n        if (input) {\n          try { input.focus(); } catch (e) { /* focus refused */ }\n        }\n      });\n    });\n    ensureFileInput(modal);\n    qsa('[data-maquette-request-picker]', modal).forEach(function (picker) {\n      picker.addEventListener('change', function (event) {\n        if (picker.hasAttribute('data-maquette-request-scratch-only')) {\n          showModels(picker, event.target);\n          // Picked low in the grid: bring back the folded tile\n          scrollToTop(picker);\n          pickBackground(modal, event.target.value);\n        }\n        else {\n          // Shape first: it may switch the fixing, the preview shows the result\n          filterByShape(modal);\n          showPickedVariant(modal);\n        }\n      });\n    });\n    // Click on the picked model again: unpicked, the grid comes back (the model is optional)\n    qsa('[data-maquette-request-scratch-only]', modal).forEach(function (picker) {\n      picker.addEventListener('click', function (event) {\n        var label = closest(event.target, 'label');\n        var radio = label && qs('#' + label.getAttribute('for'), picker);\n        if (!radio || !radio.checked) return;\n        event.preventDefault();\n        radio.checked = false;\n        showModels(picker, null, true);\n        pickBackground(modal, null);\n      });\n    });\n    qsa('[data-maquette-model-more]', modal).forEach(function (button) {\n      button.addEventListener('click', function () { showModels(closest(button, 'fieldset'), null, true); });\n    });\n    qsa('[data-maquette-model-upload]', modal).forEach(function (button) {\n      button.addEventListener('click', function () {\n        var input = ensureFileInput(modal);\n        if (input) input.click();\n      });\n    });\n    qsa('[data-maquette-model-change]', modal).forEach(function (button) {\n      button.addEventListener('click', function () {\n        showModels(closest(button, 'fieldset'), null, true);\n        scrollToTop(closest(button, 'fieldset'));\n      });\n    });\n    qsa('[data-maquette-request-mode]', modal).forEach(function (tab) {\n      tab.addEventListener('click', function (event) {\n        event.preventDefault();\n        request.mode = tab.getAttribute('data-maquette-request-mode') === 'design' ? 'design' : 'scratch';\n        renderDesignMode(modal);\n      });\n    });\n    modal.addEventListener('click', function (event) {\n      var remove = closest(event.target, '[data-maquette-request-remove]');\n      if (!remove) return;\n      event.preventDefault();\n      request.files.splice(Number(remove.getAttribute('data-maquette-request-remove')), 1);\n      renderPreviews(modal);\n    });\n  }\n\n  // Index (1-3) of the product option a picker drives: the one whose name contains the picker's\n  // name (\"Forme de la plaque\", \"Syst\u00E8me de fixation\"), 0 if none. Never guessed from the values:\n  // \"Dimensions 21 x 14 cm\" of a Livre plaque is not a rectangle.\n  function pickerOption(product, picker) {\n    var key = String(picker.getAttribute('data-maquette-request-picker') || '').toLowerCase();\n    var names = product && Array.isArray(product.options) ? product.options : [];\n    for (var i = 0; i < names.length && i < 3; i += 1) {\n      var name = typeof names[i] === 'string' ? names[i] : (names[i] && names[i].name) || '';\n      if (key && name.toLowerCase().indexOf(key) !== -1) return i + 1;\n    }\n    // The popup's models without a \"Forme\" option sell their shape(s) as \"Dimensions\" (\"30 x 20 cm\", \"Coeur\"\u2026)\n    if (key === 'forme' && product && product === request.background) {\n      for (var j = 0; j < names.length && j < 3; j += 1) {\n        var other = typeof names[j] === 'string' ? names[j] : (names[j] && names[j].name) || '';\n        if (other.toLowerCase() === 'dimensions') return j + 1;\n      }\n    }\n    return 0;\n  }\n\n  // The product variant with the shape / fixing picked in the popup, its other options unchanged\n  // (null without a product, or if the product has no such variant). `only`: that picker alone.\n  function pickedVariant(modal, product, variantId, only) {\n    var current = findVariant(product, variantId);\n    if (!current) return null;\n    var wanted = [1, 2, 3].map(function (n) { return current['option' + n] || null; });\n    qsa('[data-maquette-request-picker]', modal).forEach(function (picker) {\n      if (only && picker.getAttribute('data-maquette-request-picker') !== only) return;\n      var checked = qs('input:checked', picker);\n      var n = pickerOption(product, picker);\n      if (checked && n && !picker.hidden) wanted[n - 1] = checked.getAttribute('data-maquette-product-value');\n    });\n    return product.variants.filter(function (variant) {\n      return [1, 2, 3].every(function (n, i) { return (variant['option' + n] || null) === wanted[i]; });\n    })[0] || null;\n  }\n\n  // Picker changed on a product page: the preview shows the picked variant's photo\n  // (a saved Printlane design keeps its own thumbnail).\n  function showPickedVariant(modal) {\n    if (!request.opts || request.opts.page !== 'product' || request.design || !request.snapshot || !request.snapshot.product) return;\n    var product = parseProductJson(attr(productContainer(request.opts.trigger), 'data-product'));\n    var variant = pickedVariant(modal, product, request.snapshot.product.variantId);\n    // No such variant: back to the image shown at opening\n    request.frontImage = variant ? variantImage(product, variant) : request.openImage;\n    loadModelPreview(modal);\n  }\n\n  // Shape / fixing pickers, called on every open. On a product page they only offer what the\n  // product sells: the values of its \"Forme\u2026\" / \"\u2026fixation\" option, checked on the selected\n  // variant; a picker is hidden when the product has no such option or a single value.\n  // Without a product: every tile except the product-only ones, defaults checked.\n  // The model picker has no product option: every tile (filterByShape then keeps the ones\n  // selling the picked shape), checked by the customer (reset on open), shown by renderDesignMode.\n  function renderPickers(modal, product, variant) {\n    qsa('[data-maquette-request-picker]', modal).forEach(function (picker) {\n      var free = picker.hasAttribute('data-maquette-request-scratch-only');\n      var n = free ? 0 : pickerOption(product, picker);\n      var sold = n ? product.variants.map(function (v) { return v['option' + n]; }) : [];\n      var shown = 0;\n      qsa('input[type=\"radio\"]', picker).forEach(function (radio) {\n        var value = radio.getAttribute('data-maquette-product-value');\n        var visible = free || (product ? sold.indexOf(value) !== -1 : !radio.hasAttribute('data-maquette-product-only'));\n        var tile = radio.parentNode;\n        tile.hidden = !visible;\n        // Grid edges for the label alignment (nth-child would count the hidden tiles)\n        tile.classList.toggle('is-row-start', visible && shown % 6 === 0);\n        tile.classList.toggle('is-row-end', visible && shown % 6 === 5);\n        if (!free) radio.checked = product ? visible && !!variant && variant['option' + n] === value : radio.defaultChecked;\n        if (visible) shown += 1;\n      });\n      if (!free) picker.hidden = shown < 2;\n    });\n  }\n\n  // Picked shape: only the fixings and the models that exist in it (all of them when the shape\n  // picker is hidden). A fixing that no longer fits falls back to \"Pieds noirs\" (sold in every\n  // shape), a model is unpicked. Folding classes follow the shown models (nth-child would count\n  // the hidden ones).\n  function filterByShape(modal) {\n    var shapePicker = qs('[data-maquette-request-picker=\"Forme\"]', modal);\n    var shapeRadio = shapePicker && !shapePicker.hidden ? qs('input:checked', shapePicker) : null;\n    var shape = shapeRadio ? shapeRadio.getAttribute('data-maquette-product-value') : null;\n    var fits = function (radio) {\n      var shapes = radio.getAttribute('data-maquette-shapes');\n      return !shape || !shapes || shapes.split(',').indexOf(shape) !== -1;\n    };\n    var fixings = qs('[data-maquette-request-picker=\"Fixation\"]', modal);\n    if (fixings) {\n      var row = 0;\n      qsa('input[type=\"radio\"]', fixings).forEach(function (radio) {\n        var tile = radio.parentNode;\n        var visible = !tile.hidden && fits(radio);\n        tile.classList.toggle('is-off-shape', !fits(radio));\n        tile.classList.toggle('is-row-start', visible && row % 6 === 0);\n        tile.classList.toggle('is-row-end', visible && row % 6 === 5);\n        if (visible) row += 1;\n        if (radio.checked && !fits(radio)) {\n          var fallback = qs('input[data-maquette-product-value=\"Socle Noir\"]', fixings);\n          if (fallback && !fallback.parentNode.hidden) fallback.checked = true;\n          else radio.checked = false;\n        }\n      });\n    }\n    var models = qs('[data-maquette-request-scratch-only]', modal);\n    if (!models) return;\n    var shown = 0;\n    qsa('input[type=\"radio\"]', models).forEach(function (radio) {\n      var shapes = radio.getAttribute('data-maquette-shapes');\n      var visible = fits(radio);\n      var tile = radio.parentNode;\n      tile.hidden = !visible;\n      tile.classList.toggle('is-folded-mobile', visible && shown >= 6);\n      tile.classList.toggle('is-folded', visible && shown >= 8);\n      if (visible) shown += 1;\n      if (visible) showModelShape(radio, shapes ? null : shape);\n      if (!visible && radio.checked) {\n        radio.checked = false;\n        showModels(models, null, false);\n        pickBackground(modal, null);\n      }\n    });\n    var more = qs('[data-maquette-model-more]', models);\n    if (more) more.textContent = 'Voir les ' + shown + ' mod\u00E8les';\n  }\n\n  // Tile photo of a model sold in every shape: its cover (a rectangle), or for another shape its\n  // photo in that shape (variant image, product loaded once).\n  function showModelShape(radio, shape) {\n    var image = qs('img', radio.parentNode);\n    if (!image) return;\n    var cover = image.getAttribute('data-cover') || image.getAttribute('src');\n    image.setAttribute('data-cover', cover);\n    if (!shape || shape === '21 x 14 cm' || shape === '30 x 20 cm') {\n      image.setAttribute('src', cover);\n      return;\n    }\n    loadModel(radio.value).then(function (product) {\n      var checked = product && qs('[data-maquette-request-picker=\"Forme\"] input:checked');\n      if (!checked || checked.getAttribute('data-maquette-product-value') !== shape) return;\n      var variant = product.variants.filter(function (v) { return v.option1 === shape && v.featured_image; })[0];\n      image.setAttribute('src', variant ? variant.featured_image.src + (variant.featured_image.src.indexOf('?') === -1 ? '?' : '&') + 'width=260' : cover);\n    });\n  }\n\n  // Product of a \"Mod\u00E8le\" tile (/products/<handle>.js), loaded once; null if it fails\n  function loadModel(handle) {\n    if (!backgroundProducts[handle]) {\n      var base = (root.Shopify && root.Shopify.routes && root.Shopify.routes.root) || '/';\n      backgroundProducts[handle] = fetchJson(base + 'products/' + encodeURIComponent(handle) + '.js').then(function (result) {\n        var product = result.ok ? parseProductJson(result.data) : null;\n        if (product && Array.isArray(product.variants) && product.variants.length) return product;\n        delete backgroundProducts[handle];\n        return null;\n      });\n    }\n    return backgroundProducts[handle];\n  }\n\n  // Model grid: 2 rows, all of them (\"Voir les N mod\u00E8les\" / \"Changer de mod\u00E8le\"), or only the\n  // picked one (`picked` = its radio).\n  function showModels(picker, picked, open) {\n    if (!picker) return;\n    picker.classList.toggle('is-open', !!(open || picked));\n    picker.classList.toggle('is-picked', !!picked);\n    qsa('.selector-container', picker).forEach(function (tile) {\n      tile.classList.toggle('is-checked', !!picked && tile === picked.parentNode);\n    });\n    show(qs('[data-maquette-model-change]', picker), !!picked);\n    show(qs('[data-maquette-model-upload]', picker), !!picked && picked.value === CUSTOM_BACKGROUND);\n  }\n\n  function scrollToTop(node) {\n    try { node.scrollIntoView({ block: 'start', behavior: 'smooth' }); } catch (e) { /* old browser */ }\n  }\n\n  // The model's variant to start from. The customer never picks its \"Importer une photo\"\n  // option: it follows what they did (a file attached = \"Avec photo\").\n  function modelBaseVariant(model) {\n    var names = Array.isArray(model.options) ? model.options : [];\n    for (var i = 0; i < names.length && i < 3; i += 1) {\n      var name = typeof names[i] === 'string' ? names[i] : (names[i] && names[i].name) || '';\n      if (name.toLowerCase().indexOf('photo') === -1) continue;\n      var wanted = request.files.length ? 'Avec photo' : 'Sans photo';\n      for (var j = 0; j < model.variants.length; j += 1) {\n        if (model.variants[j]['option' + (i + 1)] === wanted) return model.variants[j];\n      }\n    }\n    return model.variants[0];\n  }\n\n  // \"Mod\u00E8le\" tile picked: that product becomes the request's product.\n  // Loaded once from Shopify; until then (or if it fails) the pickers stay as they are.\n  function pickBackground(modal, handle) {\n    request.background = null;\n    request.backgroundLoading = null;\n    if (!handle) return;\n    var apply = function (product) {\n      var checked = qs('[data-maquette-request-scratch-only] input:checked', modal);\n      // Another model picked meanwhile, or the page changed (InstantClick replaces the popup)\n      if (!product || !checked || checked.value !== handle || modal !== requestModal()) return;\n      request.background = product;\n    };\n    var loading = loadModel(handle).then(function (product) {\n      if (request.backgroundLoading === loading) request.backgroundLoading = null;\n      apply(product);\n    });\n    request.backgroundLoading = loading;\n  }\n\n  // Opens the popup. options: { trigger, page, printlaneRef, prefill, message, source }\n  function openRequest(options) {\n    var opts = options || {};\n    var modal = requestModal();\n    if (!modal) return false;\n    bindRequestModal(modal);\n    ensureFileInput(modal);\n    var page = opts.page ? normalizePage(opts.page) : detectPage(opts.trigger);\n    stopQr();\n    request.opts = { page: page, trigger: opts.trigger || null, printlaneRef: opts.printlaneRef || null, source: opts.source || 'button' };\n    request.snapshot = page === 'product' ? captureProductForm(productContainer(opts.trigger), doc) : null;\n    request.frontImage = page === 'product' ? frontImage(productContainer(opts.trigger)) : null;\n    request.openImage = request.frontImage;\n    // Files attached then left behind must not go out with a request about another product\n    request.files = [];\n    renderPreviews(modal);\n    request.design = request.opts.printlaneRef || (request.snapshot && request.snapshot.printlaneRefs[0]) || null;\n    request.hasModel = !!(request.design || (request.snapshot && request.snapshot.product));\n    request.mode = request.hasModel ? 'design' : 'scratch';\n    renderDesignMode(modal);\n    if (request.hasModel) loadModelPreview(modal);\n    request.background = null;\n    request.backgroundLoading = null;\n    qsa('[data-maquette-request-scratch-only] input', modal).forEach(function (radio) { radio.checked = radio.defaultChecked; });\n    showModels(qs('[data-maquette-request-scratch-only]', modal), null, false);\n    var pickerProduct = page === 'product' ? parseProductJson(attr(productContainer(opts.trigger), 'data-product')) : null;\n    renderPickers(modal, pickerProduct, request.snapshot && request.snapshot.product ? findVariant(pickerProduct, request.snapshot.product.variantId) : null);\n    filterByShape(modal);\n\n    var notice = qs('[data-maquette-request-notice]', modal);\n    if (notice) {\n      notice.textContent = opts.message || '';\n      show(notice, !!opts.message);\n    }\n    var textarea = qs('[data-maquette-request-text]', modal);\n    if (textarea && opts.prefill && !textarea.value) textarea.value = opts.prefill;\n    requestError(modal, '');\n    resetChannel(modal);\n    showRequestState(modal, 'form');\n    openModal(modal);\n    loadStatus(true);\n    // Focus on the title, not the field: the phone keyboard would hide the explanation\n    var title = qs('[data-maquette-request-focus]', modal);\n    if (title) {\n      try { title.focus(); } catch (e) { /* focus refused */ }\n    }\n    return true;\n  }\n\n  // (c) colorlab-saved: the customer clicked \"Ajouter au panier\" in the designer.\n  // Immediate toast (Ajax add) + stored 2 min for the /cart page (classic form submit).\n  function removeToast() {\n    var toast = qs('[data-maquette-toast]');\n    if (toast && toast.parentNode) toast.parentNode.removeChild(toast);\n  }\n\n  function showSavedToast(state) {\n    if (!pdc.flags.savedToast || !doc.body) return;\n    removeToast();\n    var toast = el('div', { className: 'maquette-toast', 'data-maquette-toast': '', role: 'status' }, [\n      el('p', { className: 'maquette-toast__text', text: 'Votre design est enregistr\u00E9 \u2014 demander une maquette gratuite avec ce design ?' }),\n      el('div', { className: 'maquette-toast__actions' }, [\n        el('button', {\n          type: 'button',\n          className: 'maquette-button maquette-toast__cta',\n          'data-maquette-request-open': '',\n          'data-maquette-page': state.page || '',\n          'data-maquette-printlane-ref': state.ref || '',\n          'data-maquette-prefill': 'Je souhaite une maquette avec le design que je viens d\u2019enregistrer dans l\u2019\u00E9diteur.',\n          text: 'Demander une maquette'\n        }),\n        el('button', { type: 'button', className: 'maquette-toast__close', 'data-maquette-toast-close': '', 'aria-label': 'Fermer', text: '\u00D7' })\n      ])\n    ]);\n    doc.body.appendChild(toast);\n    setTimeout(function () {\n      if (toast.parentNode) toast.parentNode.removeChild(toast);\n    }, 30000);\n  }\n\n  function printlaneRefFromEvent(event) {\n    var detail = event && event.detail;\n    if (detail && typeof detail === 'object') {\n      if (typeof detail.reference === 'string' && detail.reference) return detail.reference;\n      if (typeof detail.customizationReference === 'string' && detail.customizationReference) return detail.customizationReference;\n      if (detail.id && detail.token) return detail.id + '.' + detail.token;\n    } else if (typeof detail === 'string' && detail) {\n      return detail;\n    }\n    var input = qs('#printlane-customization-reference');\n    return input && input.value ? String(input.value) : null;\n  }\n\n  function onColorlabSaved(event) {\n    if (!pdc.flags.savedToast) return;\n    var state = { ref: printlaneRefFromEvent(event), at: Date.now(), page: detectPage(null) };\n    storageSet(STORAGE_SAVED, JSON.stringify(state));\n    // Printlane injects the input right before submitting: re-read after a tick\n    setTimeout(function () {\n      if (!state.ref) {\n        state.ref = printlaneRefFromEvent(null);\n        if (state.ref) storageSet(STORAGE_SAVED, JSON.stringify(state));\n      }\n      showSavedToast(state);\n    }, 50);\n  }\n\n  function resumeSavedToast() {\n    var raw = storageGet(STORAGE_SAVED);\n    if (!raw) return;\n    var state;\n    try { state = JSON.parse(raw); } catch (e) { state = null; }\n    if (!state || typeof state.at !== 'number' || Date.now() - state.at > SAVED_TOAST_MS) {\n      storageRemove(STORAGE_SAVED);\n      return;\n    }\n    if (detectPage(null) !== 'cart') return;\n    storageRemove(STORAGE_SAVED);\n    showSavedToast({ ref: state.ref, page: 'cart' });\n  }\n\n  // (a) helpClicked relayed by maquette-printlane-hooks.js (DOM event, or pendingHelp if this script was not loaded yet)\n  function onPrintlaneHelp() {\n    pdc.pendingHelp = null;\n    if (!pdc.flags.printlaneHelpHook) return;\n    openRequest({ source: 'printlane-help', message: HELP_MESSAGE, page: detectPage(null) });\n  }\n\n  function initRequest() {\n    var modal = requestModal();\n    if (modal) bindRequestModal(modal);\n    resumeSavedToast();\n    if (pdc.pendingHelp) onPrintlaneHelp();\n  }\n\n  // ---------------------------------------------------------------------------\n  // Initialisation (idempotent: InstantClick re-runs the body scripts)\n  // ---------------------------------------------------------------------------\n\n  // Switch (snippets/maquette-gate.liquid): false \u2192 no popup, no toast, no studio status.\n  // Restore and studio mode stay active: they are only reached through a link from the graphic designer.\n  function requestEnabled() {\n    return pdc.enabled !== false;\n  }\n\n  function init() {\n    var studioReset = detectStudioFragment();\n    var studio = readStudioState();\n    if (studio) {\n      renderStudioBanner(studio);\n      applyStudioPage();\n    }\n    if (studioReset) studioReset.then(initStudioCart);\n    else initStudioCart();\n    initCartMockupImages();\n    initRestore();\n    initPendingEditor();\n    if (!requestEnabled()) return;\n    initRequest();\n    scheduleStatus();\n  }\n\n  // Delegated listeners set only once per document, even if InstantClick\n  // re-runs this script on every page change.\n  if (!pdc.__delegated) {\n    pdc.__delegated = true;\n    doc.addEventListener('click', function (event) {\n      var target = event.target && event.target.closest ? event.target.closest('[data-maquette-studio-exit]') : null;\n      if (!target) return;\n      event.preventDefault();\n      exitStudioMode();\n      var modal = qs('[data-maquette-modal=\"studio\"]');\n      if (modal) closeModal(modal);\n    });\n    // Studio mode: the staff cart is never checked out from this tab. Capture phase, so the\n    // theme's own handlers (mini-cart, terms checkbox) never see the click or the submit.\n    doc.addEventListener('click', function (event) {\n      if (!studioModeActive()) return;\n      if (!closest(event.target, 'a[href*=\"/checkout\"], [name=\"checkout\"]')) return;\n      event.preventDefault();\n      event.stopPropagation();\n    }, true);\n    doc.addEventListener('submit', function (event) {\n      if (!studioModeActive()) return;\n      var form = event.target;\n      var action = form && form.getAttribute ? (form.getAttribute('action') || '') : '';\n      var submitter = event.submitter || null;\n      if (!/\\/checkout/.test(action) && !(submitter && submitter.name === 'checkout')) return;\n      event.preventDefault();\n      event.stopPropagation();\n    }, true);\n    doc.addEventListener('click', function (event) {\n      var target = closest(event.target, '[data-maquette-request-open]');\n      if (target && requestEnabled()) {\n        event.preventDefault();\n        if (typeof event.stopPropagation === 'function') event.stopPropagation();\n        var opened = openRequest({\n          trigger: target,\n          printlaneRef: target.getAttribute('data-maquette-printlane-ref') || null,\n          prefill: target.getAttribute('data-maquette-prefill') || null,\n          message: target.getAttribute('data-maquette-message') || null\n        });\n        if (opened && closest(target, '[data-maquette-toast]')) removeToast();\n        return;\n      }\n      if (closest(event.target, '[data-maquette-toast-close]')) {\n        event.preventDefault();\n        removeToast();\n      }\n    });\n    doc.addEventListener('keydown', function (event) {\n      if (event.key !== 'Escape') return;\n      qsa('[data-maquette-modal]:not([hidden])').forEach(closeModal);\n    });\n    doc.addEventListener('colorlab-saved', function (event) { if (requestEnabled()) onColorlabSaved(event); });\n    doc.addEventListener('pdc:maquette:help', function (event) { if (requestEnabled()) onPrintlaneHelp(event); });\n  }\n\n  pdc.init = init;\n  pdc.exitStudioMode = exitStudioMode;\n  pdc.openRequest = openRequest;\n  pdc.refreshStatus = function () { storageRemove(STORAGE_STATUS); loadStatus(); };\n\n  if (doc.readyState === 'loading') doc.addEventListener('DOMContentLoaded', init);\n  else init();\n})(typeof window !== 'undefined' ? window : this);\n"],
  "mappings": "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",
  "names": ["linePrice", "flags", "key", "names"]
}
