{
  "version": 3,
  "sources": ["/cdn/shop/t/4/assets/ims-orders.js?bust=20260702"],
  "sourcesContent": ["(function () {\n  'use strict';\n\n  const S = () => window.SM;\n  const db = () => window.SM.DB;\n  const ui = () => window.SM.UI;\n  const util = () => window.SM.UTIL;\n\n  const PAGE_SIZE = 25;\n  let _orders = [];\n  let _platforms = [];\n  let _currentPage = 1;\n  let _orderItems = [];\n  let _activeDeal = null;\n  let _matchedCustomer = null; // { id, customer_type, discount_type, discount_value } \u2014 set by checkForDeals()\n  // Set when a registered customer is explicitly chosen from the wholesale\n  // postcode lookup. saveOrder() previously re-derived customer_id purely by\n  // exact phone match, which silently failed when the customer had no phone\n  // on file or the number was formatted differently \u2014 leaving wholesale\n  // orders with customer_id = null, which in turn means no receivable is\n  // ever created on delivery and the order can never be marked paid.\n  let _pickedCustomerId = null;\n  let _customerDefaultAddress = '';   // registered address of the picked customer, for the alt-delivery toggle\n  let _customerDefaultPostcode = '';\n  let _selectedOrders = new Set();\n\n  // \u2500\u2500\u2500 ORDER HISTORY \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  let _historyOrders = [];\n  let _historyPage = 1;\n\n  async function showHistory(savedFilters = null) {\n    const now = new Date();\n    const monthStart = new Date(now.getFullYear(), now.getMonth(), 1).toISOString().split('T')[0];\n    const today = now.toISOString().split('T')[0];\n    const f = savedFilters || {};\n\n    // Load platforms and couriers for filter dropdowns\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const [{ data: platforms }, { data: couriers }] = await Promise.all([\n      client.from('platforms').select('id,name').eq('is_active', true).order('name'),\n      client.from('couriers').select('id,name').order('name')\n    ]);\n\n    const platOpts = (platforms||[]).map(p=>`<option value=\"${p.id}\" ${f.platform===p.id?'selected':''}>${util().sanitize(p.name)}</option>`).join('');\n    const courierOpts = (couriers||[]).map(c=>`<option value=\"${c.id}\" ${f.courier===c.id?'selected':''}>${util().sanitize(c.name)}</option>`).join('');\n\n    ui().openModal('Order history', `\n      <div style=\"display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px;margin-bottom:10px\">\n        <div>\n          <label class=\"ims__label\">Date from</label>\n          <input class=\"ims__input\" type=\"date\" id=\"ims-hist-from\" value=\"${f.from || monthStart}\" onchange=\"window.IMS_ORDERS.loadHistory()\">\n        </div>\n        <div>\n          <label class=\"ims__label\">Date to</label>\n          <input class=\"ims__input\" type=\"date\" id=\"ims-hist-to\" value=\"${f.to || today}\" onchange=\"window.IMS_ORDERS.loadHistory()\">\n        </div>\n        <div>\n          <label class=\"ims__label\">Order status</label>\n          <select class=\"ims__select\" id=\"ims-hist-status\" onchange=\"window.IMS_ORDERS.loadHistory()\">\n            <option value=\"\">All statuses</option>\n            <option value=\"confirmed\" ${f.status==='confirmed'?'selected':''}>Confirmed</option>\n            <option value=\"picking\" ${f.status==='picking'?'selected':''}>Picking</option>\n            <option value=\"packed\" ${f.status==='packed'?'selected':''}>Packed</option>\n            <option value=\"dispatched\" ${f.status==='dispatched'?'selected':''}>Dispatched</option>\n            <option value=\"delivered\" ${f.status==='delivered'?'selected':''}>Delivered</option>\n            <option value=\"cancelled\" ${f.status==='cancelled'?'selected':''}>Cancelled</option>\n            <option value=\"refunded\" ${f.status==='refunded'?'selected':''}>Refunded</option>\n            <option value=\"return_requested\" ${f.status==='return_requested'?'selected':''}>Return Requested</option>\n            <option value=\"return_received\" ${f.status==='return_received'?'selected':''}>Return Received</option>\n            <option value=\"lost\" ${f.status==='lost'?'selected':''}>Lost</option>\n            <option value=\"failed\" ${f.status==='failed'?'selected':''}>Failed</option>\n          </select>\n        </div>\n        <div>\n          <label class=\"ims__label\">Payment status</label>\n          <select class=\"ims__select\" id=\"ims-hist-payment\" onchange=\"window.IMS_ORDERS.loadHistory()\">\n            <option value=\"\">All payments</option>\n            <option value=\"unpaid\" ${f.payment==='unpaid'?'selected':''}>Unpaid</option>\n            <option value=\"paid\" ${f.payment==='paid'?'selected':''}>Paid</option>\n            <option value=\"partial\" ${f.payment==='partial'?'selected':''}>Partial</option>\n            <option value=\"refunded\" ${f.payment==='refunded'?'selected':''}>Refunded</option>\n          </select>\n        </div>\n        <div>\n          <label class=\"ims__label\">Platform</label>\n          <select class=\"ims__select\" id=\"ims-hist-platform\" onchange=\"window.IMS_ORDERS.loadHistory()\">\n            <option value=\"\">All platforms</option>${platOpts}\n          </select>\n        </div>\n        <div>\n          <label class=\"ims__label\">Courier</label>\n          <select class=\"ims__select\" id=\"ims-hist-courier\" onchange=\"window.IMS_ORDERS.loadHistory()\">\n            <option value=\"\">All couriers</option>${courierOpts}\n          </select>\n        </div>\n        <div>\n          <label class=\"ims__label\">Order type</label>\n          <select class=\"ims__select\" id=\"ims-hist-type\" onchange=\"window.IMS_ORDERS.loadHistory()\">\n            <option value=\"\">All types</option>\n            <option value=\"retail\" ${f.type==='retail'?'selected':''}>Retail</option>\n            <option value=\"wholesale\" ${f.type==='wholesale'?'selected':''}>Wholesale</option>\n          </select>\n        </div>\n        <div>\n          <label class=\"ims__label\">Search (order #, customer, postcode, SKU, ref)</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-hist-search\" placeholder=\"Any keyword...\" value=\"${util().sanitize(f.search||'')}\">\n        </div>\n        <div style=\"display:flex;align-items:flex-end;gap:6px\">\n          <button class=\"ims__btn ims__btn--primary\" style=\"flex:1\" onclick=\"window.IMS_ORDERS.loadHistory()\"><i class=\"ti ti-search\"></i> Search</button>\n          <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.IMS_ORDERS.clearHistoryFilters()\"><i class=\"ti ti-x\"></i></button>\n        </div>\n      </div>\n\n      <div id=\"ims-hist-stats\" style=\"display:flex;gap:8px;margin-bottom:10px;flex-wrap:wrap\"></div>\n\n      <div class=\"ims__table-wrap\" style=\"max-height:380px;overflow-y:auto;overflow-x:auto;-webkit-overflow-scrolling:touch\">\n        <table class=\"ims__table\" style=\"min-width:900px\">\n          <thead><tr>\n            <th>Order #</th><th>Ref</th><th>Customer</th><th>Platform</th>\n            <th>Products</th><th>Qty</th><th>Value</th><th>Date</th>\n            <th>Status</th><th>Payment</th><th>Courier</th><th></th>\n          </tr></thead>\n          <tbody id=\"ims-hist-tbody\">\n            <tr><td colspan=\"12\" class=\"ims__table-empty\"><i class=\"ti ti-loader-2 ims__spin\"></i></td></tr>\n          </tbody>\n        </table>\n      </div>\n      <div id=\"ims-hist-pagination\" style=\"display:flex;gap:4px;margin-top:10px;align-items:center;flex-wrap:wrap\"></div>\n    `, `\n      <button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_ORDERS.exportHistory()\" title=\"One row per order\"><i class=\"ti ti-download\"></i> Export orders</button>\n      <button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_ORDERS.exportHistoryItems()\" title=\"One row per item: SKU, product, quantity and price\"><i class=\"ti ti-download\"></i> Export items</button>\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Close</button>\n    `, 'xl');\n\n    loadHistory();\n\n    setTimeout(() => {\n      document.getElementById('ims-hist-search')?.addEventListener('keydown', e => {\n        if (e.key === 'Enter') loadHistory();\n      });\n    }, 200);\n  }\n\n  // Opening an order from History replaces History's own modal content\n  // entirely (the app only ever has one modal open at a time), so simply\n  // closing the order back out previously closed everything, losing\n  // whatever date range and filters were set. This captures them first,\n  // then swaps the order detail's Close button (only for orders opened\n  // this specific way) to return to History with those same filters\n  // restored, rather than closing out completely.\n  async function viewOrderFromHistory(orderId){\n    const savedFilters = {\n      from: document.getElementById('ims-hist-from')?.value || '',\n      to: document.getElementById('ims-hist-to')?.value || '',\n      status: document.getElementById('ims-hist-status')?.value || '',\n      payment: document.getElementById('ims-hist-payment')?.value || '',\n      platform: document.getElementById('ims-hist-platform')?.value || '',\n      courier: document.getElementById('ims-hist-courier')?.value || '',\n      type: document.getElementById('ims-hist-type')?.value || '',\n      search: document.getElementById('ims-hist-search')?.value || ''\n    };\n    await openOrder(orderId);\n    setTimeout(() => {\n      const closeBtn = document.querySelector('#ims-modal-footer button[onclick*=\"closeModal\"]');\n      if(closeBtn) closeBtn.onclick = () => showHistory(savedFilters);\n    }, 150);\n  }\n\n  function clearHistoryFilters() {\n    ['ims-hist-status','ims-hist-payment','ims-hist-platform','ims-hist-courier','ims-hist-type','ims-hist-search'].forEach(id => {\n      const el = document.getElementById(id);\n      if (el) el.value = '';\n    });\n    loadHistory();\n  }\n\n      async function loadHistory() {\n    const tbody = document.getElementById('ims-hist-tbody');\n    if (!tbody) return;\n    tbody.innerHTML = `<tr><td colspan=\"12\" class=\"ims__table-empty\"><i class=\"ti ti-loader-2 ims__spin\"></i></td></tr>`;\n\n    const from       = document.getElementById('ims-hist-from')?.value || '';\n    const to         = document.getElementById('ims-hist-to')?.value || '';\n    const search     = document.getElementById('ims-hist-search')?.value?.trim().toLowerCase() || '';\n    const status     = document.getElementById('ims-hist-status')?.value || '';\n    const payment    = document.getElementById('ims-hist-payment')?.value || '';\n    const platformId = document.getElementById('ims-hist-platform')?.value || '';\n    const courierId  = document.getElementById('ims-hist-courier')?.value || '';\n    const orderType  = document.getElementById('ims-hist-type')?.value || '';\n\n    const companyId = window.SM.AUTH.company?.id;\n    const histOpts = {\n      select: 'id,order_number,external_ref,customer_name,order_type,fulfillment_type,status,payment_status,payment_method,total_value,created_at,delivered_at,dispatched_at,postcode,return_reason,refund_amount,platform_id,platforms(name),shipments(tracking_number,courier_id,is_return_collection,couriers(name))',\n      order: { col: 'created_at', asc: false },\n      noCompanyFilter: true,\n      neq: { fulfillment_type: 'dropship' },\n      eq: { company_id: companyId }\n    };\n    if (from)       histOpts.gte = { created_at: from+'T00:00:00' };\n    if (to)         histOpts.lte = { created_at: to+'T23:59:59' };\n    if (status)     histOpts.eq = { ...histOpts.eq, status: status };\n    if (payment)    histOpts.eq = { ...histOpts.eq, payment_status: payment };\n    if (platformId) histOpts.eq = { ...histOpts.eq, platform_id: platformId };\n    if (orderType)  histOpts.eq = { ...histOpts.eq, order_type: orderType };\n\n    const { data, error } = await _histReadAll('orders', histOpts);\n    if (error) {\n      tbody.innerHTML = `<tr><td colspan=\"12\" class=\"ims__table-empty\">Error: ${error.message}</td></tr>`;\n      return;\n    }\n\n    // order_items has no company_id column \u2014 fetch separately with raw client\n    const histOrderIds = (data||[]).map(o => o.id);\n    let histItemsMap = {};\n    if (histOrderIds.length) {\n      const histItems = await _histItemsFor(histOrderIds);\n      (histItems||[]).forEach(i => {\n        if (!histItemsMap[i.order_id]) histItemsMap[i.order_id] = [];\n        histItemsMap[i.order_id].push(i);\n      });\n    }\n    let orders = (data||[]).map(o => ({\n      ...o,\n      items: histItemsMap[o.id] || [],\n      courier: (o.shipments||[]).find(x=>!x.is_return_collection)?.couriers?.name || '',\n      tracking: (o.shipments||[]).find(x=>!x.is_return_collection)?.tracking_number || '',\n      _courierId: (o.shipments||[]).find(x=>!x.is_return_collection)?.courier_id || ''\n    }));\n\n    // Client-side filters\n    if (courierId) orders = orders.filter(o => o._courierId === courierId);\n    if (search) {\n      orders = orders.filter(o => {\n        const skus = o.items.map(i=>i.sku).join(' ').toLowerCase();\n        const prods = o.items.map(i=>i.product_name).join(' ').toLowerCase();\n        return (\n          o.order_number?.toLowerCase().includes(search) ||\n          o.customer_name?.toLowerCase().includes(search) ||\n          o.postcode?.toLowerCase().includes(search) ||\n          o.external_ref?.toLowerCase().includes(search) ||\n          o.tracking?.toLowerCase().includes(search) ||\n          skus.includes(search) ||\n          prods.includes(search)\n        );\n      });\n    }\n\n    _historyOrders = orders;\n    _historyPage = 1;\n\n    // Stats\n    const statsEl = document.getElementById('ims-hist-stats');\n    if (statsEl) {\n      const totalVal  = orders.reduce((s,o)=>s+(o.total_value||0),0);\n      const delivered = orders.filter(o=>o.status==='delivered').length;\n      const cancelled = orders.filter(o=>o.status==='cancelled').length;\n      const refunded  = orders.filter(o=>o.status==='refunded').length;\n      const unpaid    = orders.filter(o=>o.payment_status==='unpaid').length;\n      statsEl.innerHTML = [\n        {l:'Total orders',  v:orders.length,                   t:''},\n        {l:'Revenue',       v:util().formatCurrency(totalVal), t:'success'},\n        {l:'Delivered',     v:delivered,                       t:'success'},\n        {l:'Cancelled',     v:cancelled,                       t:'neutral'},\n        {l:'Refunded',      v:refunded,                        t:'danger'},\n        {l:'Unpaid',        v:unpaid,                          t:'danger'},\n      ].map(s=>`<div class=\"ims__stat\" style=\"padding:6px 12px;min-width:90px;border:0.5px solid var(--ims-border);border-radius:var(--ims-radius)\">\n        <div class=\"ims__stat-label\" style=\"font-size:10px\">${s.l}</div>\n        <div class=\"ims__stat-value${s.t?' ims__stat-value--'+s.t:''}\" style=\"font-size:14px\">${s.v}</div>\n      </div>`).join('');\n    }\n\n    renderHistoryTable();\n  }\n\n  function renderHistoryTable() {\n    const tbody = document.getElementById('ims-hist-tbody');\n    const pagEl = document.getElementById('ims-hist-pagination');\n    if (!tbody) return;\n    const total = _historyOrders.length;\n    if (!total) {\n      tbody.innerHTML = '<tr><td colspan=\"12\" class=\"ims__table-empty\">No orders found \u2014 try adjusting filters</td></tr>';\n      if (pagEl) pagEl.innerHTML = '';\n      return;\n    }\n    const start = (_historyPage-1)*PAGE_SIZE;\n    const page  = _historyOrders.slice(start, start+PAGE_SIZE);\n    tbody.innerHTML = page.map(o=>{\n      const products = o.items.map(i=>{\n        const name = util().sanitize(i.product_name||'');\n        const sku  = util().sanitize(i.sku||'');\n        return name ? (sku ? `${name} (${sku})` : name) : sku;\n      }).filter(Boolean).join(', ') || '\u2014';\n      const qty  = o.items.reduce((s,i)=>s+(i.quantity||0),0) || '\u2014';\n      return `<tr>\n        <td><span class=\"ims__link\" onclick=\"window.IMS_ORDERS.viewOrderFromHistory('${util().jsArg(o.id)}')\">${util().sanitize(o.order_number)}</span></td>\n        <td style=\"font-size:11px\">${util().sanitize(o.external_ref||'\u2014')}</td>\n        <td>${util().sanitize(o.customer_name||'\u2014')}</td>\n        <td style=\"font-size:11px\">${util().sanitize(o.platforms?.name||'\u2014')}</td>\n        <td style=\"font-size:11px\">${products}</td>\n        <td style=\"text-align:right\">${qty}</td>\n        <td>${util().formatCurrency(o.total_value)}</td>\n        <td style=\"font-size:11px\">${util().formatDate(o.created_at)}</td>\n        <td>${util().pill(o.status)}</td>\n        <td>${o.payment_status?util().pill(o.payment_status):'\u2014'}</td>\n        <td style=\"font-size:11px\">${util().sanitize(o.courier||'\u2014')}</td>\n        <td>\n          <div class=\"ims__btn-group\">\n            <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_ORDERS.viewOrderFromHistory('${util().jsArg(o.id)}')\"><i class=\"ti ti-eye\"></i></button>\n            <button class=\"ims__btn ims__btn--ghost ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_ORDERS.showActivityLog('${util().jsArg(o.id)}','${util().jsArg(o.order_number)}')\" title=\"Activity log\"><i class=\"ti ti-history\"></i></button>\n          </div>\n        </td>\n      </tr>`;\n    }).join('');\n\n    if (pagEl) {\n      const pages = Math.ceil(total/PAGE_SIZE);\n      pagEl.innerHTML = pages<=1 ? '' :\n        `<span class=\"ims__page-info\">Showing ${Math.min(start+1,total)}\u2013${Math.min(_historyPage*PAGE_SIZE,total)} of ${total}</span>`+\n        Array.from({length:pages},(_,i)=>`<button class=\"ims__btn ims__btn--sm ${i+1===_historyPage?'ims__btn--primary':'ims__btn--secondary'}\" onclick=\"window.IMS_ORDERS.goHistoryPage(${i+1})\">${i+1}</button>`).join('');\n    }\n  }\n\n  function goHistoryPage(p) { _historyPage=p; renderHistoryTable(); }\n  function showActive() { load(); }\n\n  async function showActivityLog(orderId, orderNumber) {\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const { data: logs } = await client.from('order_activity_log')\n      .select('*')\n      .eq('order_id', orderId)\n      .order('created_at', {ascending: true});\n\n    const rows = (logs||[]).length ? (logs||[]).map(l=>`\n      <tr>\n        <td style=\"font-size:11px;white-space:nowrap\">${util().formatDate(l.created_at)}</td>\n        <td style=\"font-size:11px\">${util().sanitize(l.user_name||'System')}</td>\n        <td style=\"font-weight:500\">${util().sanitize(l.action||'\u2014')}</td>\n        <td style=\"font-size:11px;color:var(--ims-text-muted)\">${l.old_value?util().sanitize(l.old_value):'\u2014'}</td>\n        <td style=\"font-size:11px\">${l.new_value?util().sanitize(l.new_value):'\u2014'}</td>\n        <td style=\"font-size:11px;color:var(--ims-text-muted)\">${l.notes?util().sanitize(l.notes):'\u2014'}</td>\n      </tr>`).join('')\n    : '<tr><td colspan=\"6\" class=\"ims__table-empty\">No activity recorded for this order</td></tr>';\n\n    ui().openModal(`Activity log: ${orderNumber}`, `\n      <div class=\"ims__table-wrap\" style=\"max-height:420px;overflow-y:auto\">\n        <table class=\"ims__table\">\n          <thead><tr><th>Time</th><th>User</th><th>Action</th><th>From</th><th>To</th><th>Notes</th></tr></thead>\n          <tbody>${rows}</tbody>\n        </table>\n      </div>\n    `, `<button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Close</button>`, 'lg');\n  }\n\n  // \u2500\u2500\u2500 ORDER HISTORY: reading every row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // The database returns at most 1,000 rows per request, so the history\n  // reads orders in pages, and their lines in batches of 150 orders, until\n  // everything is in (lines were near that limit already).\n  async function _histReadAll(table, opts) {\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY), out = [];\n    for (let start = 0; start < 500000; start += 1000) {\n      let q = client.from(table).select(opts.select || '*');\n      if (!opts.noCompanyFilter && window.SM.AUTH.company?.id) q = q.eq('company_id', window.SM.AUTH.company.id);\n      Object.entries(opts.eq || {}).forEach(([k, v]) => { q = q.eq(k, v); });\n      Object.entries(opts.neq || {}).forEach(([k, v]) => { q = q.neq(k, v); });\n      Object.entries(opts.gte || {}).forEach(([k, v]) => { q = q.gte(k, v); });\n      Object.entries(opts.lte || {}).forEach(([k, v]) => { q = q.lte(k, v); });\n      if (opts.order) q = q.order(opts.order.col, { ascending: opts.order.asc !== false });\n      q = q.order('id', { ascending: true });   // a fixed order, so pages never overlap or skip\n      const { data, error } = await q.range(start, start + 999);\n      if (error) return { data: out.length ? out : null, error };\n      out.push(...(data || []));\n      if (!data || data.length < 1000) break;\n    }\n    return { data: out, error: null };\n  }\n  async function _histItemsFor(orderIds) {\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY), out = [];\n    for (let i = 0; i < orderIds.length; i += 150) {\n      const part = orderIds.slice(i, i + 150);\n      for (let start = 0; ; start += 1000) {\n        const { data, error } = await client.from('order_items').select('id,order_id,product_name,sku,quantity,unit_price,total_price')\n          .in('order_id', part).order('id', { ascending: true }).range(start, start + 999);\n        if (error) return out;\n        out.push(...(data || []));\n        if (!data || data.length < 1000) break;\n      }\n    }\n    return out;\n  }\n\n  // One row per item: what was ordered, how many, at what price.\n  function exportHistoryItems() {\n    if (!_historyOrders.length) { ui().toast('No orders to export','warning'); return; }\n    const from = document.getElementById('ims-hist-from')?.value||'';\n    const to   = document.getElementById('ims-hist-to')?.value||'';\n    const rows = [];\n    _historyOrders.forEach(o => {\n      const base = [o.order_number, o.external_ref||'', util().formatDate(o.created_at), o.customer_name||'', o.postcode||'', o.platforms?.name||'', o.order_type||'', o.status||'', o.payment_status||''];\n      if (!o.items.length) { rows.push([...base, '', '', 0, '', '']); return; }\n      o.items.forEach(i => rows.push([...base, i.sku||'', i.product_name||'', i.quantity||0,\n        i.unit_price != null ? Number(i.unit_price).toFixed(2) : '', i.total_price != null ? Number(i.total_price).toFixed(2) : ((Number(i.unit_price)||0)*(Number(i.quantity)||0)).toFixed(2)]));\n    });\n    util().exportCSV(['Order #','External ref','Date','Customer','Postcode','Platform','Order type','Status','Payment','SKU','Product','Qty','Unit price','Line total'],\n      rows, `order_items_${from}_to_${to}`);\n  }\n\n  async function exportHistory() {\n    if (!_historyOrders.length) { ui().toast('No orders to export','warning'); return; }\n    const from = document.getElementById('ims-hist-from')?.value||'';\n    const to   = document.getElementById('ims-hist-to')?.value||'';\n    util().exportCSV(\n      ['Order #','External ref','Customer','Postcode','Platform','Order type','SKU(s)','Product(s)','Qty','Value','Date','Status','Payment','Payment method','Courier','Tracking','Return reason'],\n      _historyOrders.map(o=>[\n        o.order_number,\n        o.external_ref||'',\n        o.customer_name||'',\n        o.postcode||'',\n        o.platforms?.name||'',\n        o.order_type||'',\n        o.items.map(i=>i.sku||'').join(';'),\n        o.items.map(i=>i.product_name||'').join(';'),\n        o.items.reduce((s,i)=>s+(i.quantity||0),0),\n        (o.total_value||0).toFixed(2),\n        util().formatDate(o.created_at),\n        o.status||'',\n        o.payment_status||'',\n        o.payment_method||'',\n        o.courier||'',\n        o.tracking||'',\n        o.return_reason||''\n      ]),\n      `order_history_${from}_to_${to}`\n    );\n  }\n\n\n  // \u2500\u2500\u2500 ACTIVITY LOG \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  async function logActivity(orderId, action, oldValue='', newValue='', notes='') {\n    try {\n      const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n      const user = window.SM.AUTH.user;\n      await client.from('order_activity_log').insert({\n        order_id:   orderId,\n        user_id:    user?.id || null,\n        user_name:  user?.name || user?.email || 'System',\n        action,\n        old_value:  oldValue ? String(oldValue) : null,\n        new_value:  newValue ? String(newValue) : null,\n        notes:      notes || null,\n        created_at: new Date().toISOString()\n      });\n    } catch(e) { console.warn('[Activity log]', e.message); }\n  }\n\n  // \u2500\u2500\u2500 LOAD ORDERS LIST \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  async function load() {\n    const tbody = document.getElementById('ims-orders-tbody');\n    if (!tbody) return;\n    tbody.innerHTML = `<tr><td colspan=\"11\" class=\"ims__table-empty\"><i class=\"ti ti-loader-2 ims__spin\"></i></td></tr>`;\n    _selectedOrders.clear();\n\n    const search   = document.getElementById('ims-orders-search')?.value?.trim() || '';\n    const status   = document.getElementById('ims-orders-status')?.value || '';\n    const platform = document.getElementById('ims-orders-platform')?.value || '';\n    const type     = document.getElementById('ims-orders-type')?.value || '';\n\n    const opts = {\n      select: 'id,order_number,customer_name,order_type,fulfillment_type,status,total_value,created_at,dispatched_at,postcode,dropship_customer_id,platforms(id,name)',\n      order: { col: 'created_at', asc: false }\n    };\n    opts.neq = { fulfillment_type: 'dropship' };\n    if (status && status !== 'delayed') {\n      opts.eq = { status };\n    } else if (!status) {\n      // Default view: only orders still fully owned by Order Management.\n      // \"Packed\" now hands off to Logistics immediately, so it's excluded\n      // here too \u2014 findable via the \"Packed\" filter, Logistics, or History.\n      opts.in = { status: ['confirmed', 'picking'] };\n    }\n    if (platform) opts.eq = { ...opts.eq, platform_id: platform };\n    if (type) opts.eq = { ...opts.eq, order_type: type };\n\n    let { data, error } = await db().select('orders', opts);\n    if (error) { ui().toast('Failed to load orders', 'error'); return; }\n\n    const orderIds = (data||[]).map(o => o.id);\n    let itemsMap = {};\n    if (orderIds.length) {\n      const rawClient = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n      const { data: items } = await rawClient.from('order_items')\n        .select('order_id,product_name,sku,quantity')\n        .in('order_id', orderIds);\n      (items||[]).forEach(i => {\n        if (!itemsMap[i.order_id]) itemsMap[i.order_id] = [];\n        itemsMap[i.order_id].push(i);\n      });\n    }\n\n    let orders = (data||[]).map(o => ({ ...o, items: itemsMap[o.id] || [] }));\n\n    if (search) {\n      const s = search.toLowerCase();\n      orders = orders.filter(o => {\n        const prods = o.items.map(i => i.product_name||'').join(' ').toLowerCase();\n        const skus  = o.items.map(i => i.sku||'').join(' ').toLowerCase();\n        return (\n          o.order_number?.toLowerCase().includes(s) ||\n          o.customer_name?.toLowerCase().includes(s) ||\n          o.postcode?.toLowerCase().includes(s) ||\n          prods.includes(s) ||\n          skus.includes(s)\n        );\n      });\n    }\n\n    orders = orders.map(o => ({ ...o, _delayed: util().isDelayed(o) }));\n    if (status === 'delayed') orders = orders.filter(o => o._delayed);\n\n    _orders = orders;\n    _currentPage = 1;\n    renderTable();\n    loadPlatformFilter();\n    ui().updateBadge('ims-badge-orders',\n      orders.filter(o => ['confirmed','picking','packed'].includes(o.status) || o._delayed).length\n    );\n  }\n\n  // \u2500\u2500\u2500 UNPAID EXPIRY CHECK \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  async function checkUnpaidExpiry() {\n    const now = new Date();\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const { data: expiring } = await client.from('orders')\n      .select('id,order_number,customer_name,total_value,unpaid_expires_at,created_at')\n      .eq('payment_status','unpaid')\n      .eq('fulfillment_type','retail')\n      .not('status','in','(\"cancelled\",\"refunded\",\"delivered\")')\n      .lte('unpaid_expires_at', now.toISOString())\n      .order('unpaid_expires_at');\n\n    if (!expiring?.length) return;\n\n    // Show action modal for expired unpaid orders\n    const rows = expiring.map(o => `\n      <tr>\n        <td><strong>${util().sanitize(o.order_number)}</strong></td>\n        <td>${util().sanitize(o.customer_name||'\u2014')}</td>\n        <td>${util().formatCurrency(o.total_value)}</td>\n        <td style=\"color:var(--ims-danger)\">${util().formatDate(o.unpaid_expires_at)}</td>\n        <td>\n          <div class=\"ims__btn-group\">\n            <button class=\"ims__btn ims__btn--success ims__btn--sm\" onclick=\"window.IMS_ORDERS.convertUnpaid('${util().jsArg(o.id)}','paid')\">Paid</button>\n            <button class=\"ims__btn ims__btn--accent ims__btn--sm\" onclick=\"window.IMS_ORDERS.convertUnpaid('${util().jsArg(o.id)}','cod')\">COD</button>\n            <button class=\"ims__btn ims__btn--danger ims__btn--sm\" onclick=\"window.IMS_ORDERS.cancelUnpaid('${util().jsArg(o.id)}','${util().jsArg(o.order_number)}')\">Cancel</button>\n          </div>\n        </td>\n      </tr>`).join('');\n\n    ui().openModal(`\u26A0 ${expiring.length} unpaid order(s) have expired`, `\n      <div class=\"ims__alert ims__alert--danger\" style=\"margin-bottom:14px\">\n        <i class=\"ti ti-clock\"></i>\n        <span>The following orders have exceeded the 7-day payment window. Please take action on each order \u2014 convert to Paid, COD, or cancel.</span>\n      </div>\n      <div class=\"ims__table-wrap\">\n        <table class=\"ims__table\">\n          <thead><tr><th>Order #</th><th>Customer</th><th>Value</th><th>Expired</th><th>Action</th></tr></thead>\n          <tbody>${rows}</tbody>\n        </table>\n      </div>\n    `, `<button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Dismiss</button>`, 'lg');\n  }\n\n  async function convertUnpaid(orderId, newStatus) {\n    const expiresAt = newStatus === 'unpaid' ? new Date(Date.now() + 7*24*60*60*1000).toISOString() : null;\n    await db().update('orders', orderId, {\n      payment_status:    newStatus,\n      unpaid_expires_at: expiresAt\n    });\n    await logActivity(orderId, 'Payment status converted', 'unpaid', newStatus, 'Converted from expired unpaid');\n    ui().toast(`Order converted to ${newStatus}`, 'success');\n    // Remove row from modal\n    const modal = document.getElementById('ims-modal-body');\n    if (modal) {\n      const rows = modal.querySelectorAll('tbody tr');\n      rows.forEach(row => {\n        if (row.innerHTML.includes(orderId)) row.remove();\n      });\n      const remaining = modal.querySelectorAll('tbody tr').length;\n      if (!remaining) ui().closeModal();\n    }\n    load();\n  }\n\n  async function cancelUnpaid(orderId, orderNumber) {\n    ui().confirm(`Cancel unpaid order <strong>${orderNumber}</strong>?<br><br>Stock reservations will be released.`, async () => {\n      // Release stock reservations\n      const { data: _cancelOrd } = await db().select('orders', { select: 'warehouse_id,order_items(product_id,quantity)', eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true });\n      const items = _cancelOrd?.order_items || [];\n      const whId = _cancelOrd?.warehouse_id;\n      // Release one line at a time. Releasing every line at once meant two\n      // lines of the same product both read the same starting figure, so\n      // only one release was applied and stock stayed wrongly reserved.\n      for (const item of (items||[])) {\n        if (!item.product_id) continue;\n        const { data: sl } = whId\n          ? await db().select('stock_levels', { eq: { product_id: item.product_id, warehouse_id: whId }, maybeSingle: true, noCompanyFilter: true })\n          : await db().select('stock_levels', { eq: { product_id: item.product_id }, limit: 1, noCompanyFilter: true }).then(r => ({ data: r.data?.[0] }));\n        if (sl) await db().update('stock_levels', sl.id, { reserved_qty: Math.max(0,(sl.reserved_qty||0)-(item.quantity||0)) });\n      }\n      const _cancelClient2 = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n      await _cancelClient2.from('logistics_jobs').delete().eq('order_id', orderId);\n\n      await db().update('orders', orderId, { status: 'cancelled', payment_status: 'unpaid', unpaid_expires_at: null });\n      await logActivity(orderId, 'Order cancelled', 'confirmed', 'cancelled', 'Cancelled \u2014 unpaid order expired');\n      ui().toast('Order cancelled \u2014 stock released', 'success');\n      const modal = document.getElementById('ims-modal-body');\n      if (modal) {\n        const rows = modal.querySelectorAll('tbody tr');\n        rows.forEach(row => { if (row.innerHTML.includes(orderId)) row.remove(); });\n        if (!modal.querySelectorAll('tbody tr').length) ui().closeModal();\n      }\n      load();\n    }, 'Cancel order', false);\n  }\n\n  function renderTable() {\n    const tbody = document.getElementById('ims-orders-tbody');\n    if (!tbody) return;\n    const total = _orders.length;\n    if (!total) {\n      tbody.innerHTML = '<tr><td colspan=\"11\" class=\"ims__table-empty\">No orders found</td></tr>';\n      renderPagination(0);\n      updateBulkBar();\n      return;\n    }\n    const start = (_currentPage - 1) * PAGE_SIZE;\n    const page  = _orders.slice(start, start + PAGE_SIZE);\n\n    tbody.innerHTML = page.map(o => {\n      const status = o._delayed ? 'delayed' : o.status;\n      const daysToExpiry = o.payment_status==='unpaid'&&o.unpaid_expires_at\n        ? Math.ceil((new Date(o.unpaid_expires_at)-new Date())/(1000*60*60*24)) : null;\n      const expiryBadge = daysToExpiry!==null\n        ? daysToExpiry<=0\n          ? `<span class=\"ims__pill ims__pill--danger\" style=\"font-size:10px\">Expired</span>`\n          : daysToExpiry<=1\n            ? `<span class=\"ims__pill ims__pill--danger\" style=\"font-size:10px\">Expires today</span>`\n            : daysToExpiry<=3\n              ? `<span class=\"ims__pill ims__pill--warning\" style=\"font-size:10px\">Exp. ${daysToExpiry}d</span>`\n              : ''\n        : '';\n      const typePill = o.order_type === 'wholesale'\n        ? `<span class=\"ims__pill ims__pill--info\">Wholesale</span>`\n        : `<span class=\"ims__pill ims__pill--neutral\">Retail</span>`;\n      const products = (o.items||[]).map(i => {\n        const name = util().sanitize(i.product_name||'');\n        const sku  = util().sanitize(i.sku||'');\n        return name ? (sku ? `${name} (${sku})` : name) : sku;\n      }).filter(Boolean).join(', ') || '\u2014';\n      const qty = (o.items||[]).reduce((s, i) => s + (i.quantity||0), 0) || '\u2014';\n      return `\n        <tr class=\"${o._delayed ? 'ims__row--delayed' : ''}\">\n          <td><input type=\"checkbox\" class=\"ims-order-cb\" data-id=\"${o.id}\" ${_selectedOrders.has(o.id)?'checked':''} onchange=\"window.IMS_ORDERS.toggleSelectOrder('${util().jsArg(o.id)}',this.checked)\"></td>\n          <td><span class=\"ims__link\" onclick=\"window.IMS_ORDERS.openOrder('${util().jsArg(o.id)}')\">${util().sanitize(o.order_number)}</span></td>\n          <td>${util().sanitize(o.customer_name||'\u2014')}</td>\n          <td>${util().sanitize(o.platforms?.name||'\u2014')}</td>\n          <td>${typePill}</td>\n          <td style=\"font-size:11px;max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap\" title=\"${products}\">${products}</td>\n          <td style=\"text-align:right\">${qty}</td>\n          <td>${util().formatCurrency(o.total_value)}${o.has_price_override?` <span title=\"Contains price override\" style=\"color:var(--ims-warning);font-size:11px\"><i class=\"ti ti-alert-triangle\"></i></span>`:''}</td>\n          <td>${util().formatDate(o.created_at)}</td>\n          <td>${util().pill(status)}${o.payment_status&&o.order_type==='retail'?` ${util().pill(o.payment_status)}`:''} ${expiryBadge}</td>\n          <td>\n            <div class=\"ims__btn-group\">\n              <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_ORDERS.openOrder('${util().jsArg(o.id)}')\" title=\"View\"><i class=\"ti ti-eye\"></i></button>\n              ${o._delayed ? `<button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\" onclick=\"window.SM.UI.showPanel('logistics')\" title=\"Chase courier in Logistics \u2192 Tracking\"><i class=\"ti ti-truck-delivery\"></i></button>` : ''}\n              </div>\n          </td>\n        </tr>`;\n    }).join('');\n    renderPagination(total);\n    updateBulkBar();\n    const allCb = document.getElementById('ims-orders-select-all');\n    if (allCb) {\n      const pageIds = page.map(o => o.id);\n      allCb.checked = pageIds.length > 0 && pageIds.every(id => _selectedOrders.has(id));\n    }\n  }\n\n  function renderPagination(total) {\n    const el = document.getElementById('ims-orders-pagination');\n    if (!el) return;\n    const pages = Math.ceil(total / PAGE_SIZE);\n    if (pages <= 1) { el.innerHTML = ''; return; }\n    el.innerHTML = `<span class=\"ims__page-info\">Showing ${Math.min((_currentPage-1)*PAGE_SIZE+1,total)}\u2013${Math.min(_currentPage*PAGE_SIZE,total)} of ${total}</span>` +\n      Array.from({ length: pages }, (_, i) => `\n        <button class=\"ims__btn ims__btn--sm ${i+1===_currentPage?'ims__btn--primary':'ims__btn--secondary'}\"\n          onclick=\"window.IMS_ORDERS.goPage(${i+1})\">${i+1}</button>`).join('');\n  }\n\n  // \u2500\u2500\u2500 BULK SELECT & STATUS UPDATE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // Selection tracks order IDs, so it survives page changes within the\n  // same filtered list. \"Select all\" only selects the current page \u2014\n  // consistent with the 25-row page size, avoids surprise mass-updates\n  // across hundreds of unseen rows. Status choices are deliberately\n  // limited to the same forward transitions the single-order dropdown\n  // allows (confirmed/picking \u2192 picking/packed); anything else has its\n  // own dedicated flow with side effects this must not bypass.\n  function toggleSelectOrder(id, checked) {\n    if (checked) _selectedOrders.add(id); else _selectedOrders.delete(id);\n    updateBulkBar();\n    const allCb = document.getElementById('ims-orders-select-all');\n    if (allCb) {\n      const pageIds = _orders.slice((_currentPage-1)*PAGE_SIZE, _currentPage*PAGE_SIZE).map(o=>o.id);\n      allCb.checked = pageIds.length>0 && pageIds.every(pid=>_selectedOrders.has(pid));\n    }\n  }\n\n  function toggleSelectAll(checked) {\n    const pageIds = _orders.slice((_currentPage-1)*PAGE_SIZE, _currentPage*PAGE_SIZE).map(o=>o.id);\n    pageIds.forEach(id => { if (checked) _selectedOrders.add(id); else _selectedOrders.delete(id); });\n    renderTable();\n  }\n\n  function clearSelection() {\n    _selectedOrders.clear();\n    renderTable();\n  }\n\n  function updateBulkBar() {\n    const bar = document.getElementById('ims-orders-bulk-bar');\n    if (!bar) return;\n    const count = _selectedOrders.size;\n    if (!count) { bar.style.display = 'none'; bar.innerHTML = ''; return; }\n    bar.style.display = '';\n    bar.innerHTML = `\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:14px;justify-content:space-between;flex-wrap:wrap\">\n        <span><i class=\"ti ti-checkbox\"></i> <strong>${count}</strong> order${count===1?'':'s'} selected</span>\n        <div style=\"display:flex;gap:8px;align-items:center;flex-wrap:wrap\">\n          <select class=\"ims__select\" id=\"ims-bulk-status-sel\" style=\"width:auto;font-size:12px\">\n            <option value=\"\">Set status to...</option>\n            <option value=\"picking\">Picking</option>\n            <option value=\"packed\">Packed</option>\n          </select>\n          <button class=\"ims__btn ims__btn--primary ims__btn--sm\" onclick=\"window.IMS_ORDERS.applyBulkStatus()\">Apply</button>\n          <button class=\"ims__btn ims__btn--ghost ims__btn--sm\" onclick=\"window.IMS_ORDERS.clearSelection()\">Clear selection</button>\n        </div>\n      </div>`;\n  }\n\n  async function applyBulkStatus() {\n    const sel = document.getElementById('ims-bulk-status-sel');\n    const newStatus = sel?.value;\n    if (!newStatus) { ui().toast('Please choose a status to apply', 'error'); return; }\n    const ids = [..._selectedOrders];\n    if (!ids.length) return;\n\n    const bar = document.getElementById('ims-orders-bulk-bar');\n    const applyBtn = bar?.querySelector('button.ims__btn--primary');\n    const clearBtn = bar?.querySelector('button.ims__btn--ghost');\n    if (sel) sel.disabled = true;\n    if (applyBtn) { applyBtn.disabled = true; applyBtn.innerHTML = '<i class=\"ti ti-loader-2 ims__spin\"></i> Applying...'; }\n    if (clearBtn) clearBtn.disabled = true;\n\n    // Inject a progress bar so a large selection doesn't look frozen \u2014\n    // each order requires a status lookup, an update, and an activity\n    // log entry (plus a logistics job insert when moving to Packed).\n    const total = ids.length;\n    if (bar) {\n      bar.insertAdjacentHTML('beforeend', `\n        <div id=\"ims-bulk-progress\" style=\"margin-top:8px\">\n          <div style=\"display:flex;justify-content:space-between;font-size:11px;color:var(--ims-text-muted);margin-bottom:4px\">\n            <span id=\"ims-bulk-progress-label\">Starting...</span>\n            <span id=\"ims-bulk-progress-pct\">0%</span>\n          </div>\n          <div style=\"background:var(--ims-border);border-radius:999px;height:6px;overflow:hidden\">\n            <div id=\"ims-bulk-progress-bar\" style=\"height:6px;width:0%;background:var(--ims-accent);border-radius:999px;transition:width .2s\"></div>\n          </div>\n        </div>`);\n    }\n    const setBulkProgress = (done, label) => {\n      const pct = total > 0 ? Math.round((done/total)*100) : 0;\n      const barEl = document.getElementById('ims-bulk-progress-bar');\n      const pctEl = document.getElementById('ims-bulk-progress-pct');\n      const labelEl = document.getElementById('ims-bulk-progress-label');\n      if (barEl) barEl.style.width = pct+'%';\n      if (pctEl) pctEl.textContent = pct+'%';\n      if (labelEl) labelEl.textContent = label;\n    };\n\n    let updated = 0, skipped = 0, processed = 0;\n    for (const id of ids) {\n      processed++;\n      setBulkProgress(processed - 1, `Updating order ${processed} of ${total}`);\n      const { data: current } = await db().select('orders', { select: 'status', eq: { id }, maybeSingle: true, noCompanyFilter: true });\n      if (!['confirmed','picking'].includes(current?.status)) { skipped++; setBulkProgress(processed, `Updated ${processed} of ${total}`); continue; }\n      const { error } = await db().update('orders', id, { status: newStatus });\n      if (error) { skipped++; setBulkProgress(processed, `Updated ${processed} of ${total}`); continue; }\n      await logActivity(id, 'Status updated', current?.status||'', newStatus, 'Bulk status update');\n      if (newStatus === 'packed') {\n        await db().insert('logistics_jobs', { order_id: id, job_type: 'delivery', status: 'unassigned' });\n      }\n      updated++;\n      setBulkProgress(processed, `Updated ${processed} of ${total}`);\n    }\n\n    setBulkProgress(total, 'All done!');\n    await new Promise(r => setTimeout(r, 300));\n\n    _selectedOrders.clear();\n    ui().toast(`${updated} order(s) updated${skipped?`, ${skipped} skipped (not eligible for this transition)`:''}`, skipped ? 'warning' : 'success', 5000);\n    load();\n  }\n\n  async function loadPlatformFilter() {\n    if (_platforms.length) return;\n    const companyId = window.SM.AUTH.company?.id;\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const { data } = await client.from('platforms')\n      .select('id,name,order_type')\n      .eq('company_id', companyId)\n      .eq('is_active', true)\n      .order('sort_order');\n    _platforms = data || [];\n    const sel = document.getElementById('ims-orders-platform');\n    if (!sel) return;\n    _platforms.forEach(p => {\n      if (!sel.querySelector(`option[value=\"${p.id}\"]`)) {\n        const opt = document.createElement('option');\n        opt.value = p.id; opt.textContent = p.name;\n        sel.appendChild(opt);\n      }\n    });\n  }\n\n  // \u2500\u2500\u2500 NEW ORDER FORM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  let _batchOrders = [];   // orders saved in current batch session\n  let _batchId = null;     // current batch ID\n\n  async function showNewOrder(batchMode=false) {\n    _amend = null;   // a New order is never an amendment (amendOrder sets it after opening)\n    _orderItems = [];\n    _activeDeal = null;\n    _matchedCustomer = null;\n    _pickedCustomerId = null;\n    _customerDefaultAddress = '';\n    _customerDefaultPostcode = '';\n    const companyId = window.SM.AUTH.company?.id;\n    const company   = window.SM.AUTH.company;\n\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const { data: platforms } = await client.from('platforms')\n      .select('id,name,order_type')\n      .eq('company_id', companyId)\n      .eq('is_active', true)\n      .order('sort_order');\n\n    const cats = company?.business_category || [];\n    const filtered = (platforms || []).filter(p => {\n      if (!p.categories || p.categories.includes('all')) return true;\n      if (!cats.length) return true;\n      return p.categories.some(c => cats.includes(c));\n    });\n\n    const platformOpts = filtered.map(p =>\n      `<option value=\"${p.id}\" data-type=\"${p.order_type}\">${util().sanitize(p.name)}</option>`\n    ).join('');\n\n    const { data: warehouses } = await db().select('warehouses', { eq: { is_active: true }, order: { col: 'is_default', asc: false } });\n    const defaultWarehouse = (warehouses||[]).find(w => w.is_default) || (warehouses||[])[0] || null;\n    const warehouseOpts = (warehouses||[]).map(w =>\n      `<option value=\"${w.id}\" ${defaultWarehouse&&w.id===defaultWarehouse.id?'selected':''}>${util().sanitize(w.name)}${w.is_default?' (default)':''}</option>`\n    ).join('');\n    ui().openModal('New order', `\n      <div class=\"ims__form-grid\">\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label ims__label--req\">Delivery postcode</label>\n          <div style=\"position:relative\">\n            <input class=\"ims__input\" type=\"text\" id=\"ims-no-postcode\" placeholder=\"e.g. SW1A 1AA\" autocomplete=\"off\">\n            <div id=\"ims-no-postcode-drop\" class=\"ims__ac-dropdown\"></div>\n          </div>\n          <span class=\"ims__input-hint\" id=\"ims-no-postcode-hint\"></span>\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label ims__label--req\">Platform</label>\n          <select class=\"ims__select\" id=\"ims-no-platform\" onchange=\"window.IMS_ORDERS.onPlatformChange()\">\n            <option value=\"\">Select platform</option>${platformOpts}\n          </select>\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label ims__label--req\">Customer name</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-no-custname\" placeholder=\"Customer or business name\">\n          <span class=\"ims__input-hint\" id=\"ims-no-custname-hint\"></span>\n        </div>\n        <div class=\"ims__form-group ims__form-group--full\" id=\"ims-no-quickadd\" style=\"display:none;padding:14px;background:var(--ims-surface2);border:1px solid var(--ims-border);border-radius:var(--ims-radius)\">\n          <div style=\"display:flex;justify-content:space-between;align-items:center;margin-bottom:10px\">\n            <strong style=\"font-size:13px\">New customer</strong>\n            <span class=\"ims__link\" style=\"font-size:12px\" onclick=\"window.IMS_ORDERS.cancelQuickAddCustomer()\">Cancel \u2014 enter as one-off instead</span>\n          </div>\n          <div class=\"ims__form-grid\">\n            <div class=\"ims__form-group\">\n              <label class=\"ims__label ims__label--req\">Business / customer name</label>\n              <input class=\"ims__input\" type=\"text\" id=\"ims-qa-name\">\n            </div>\n            <div class=\"ims__form-group\">\n              <label class=\"ims__label\">Contact name</label>\n              <input class=\"ims__input\" type=\"text\" id=\"ims-qa-contact\">\n            </div>\n            <div class=\"ims__form-group\">\n              <label class=\"ims__label\">Phone</label>\n              <input class=\"ims__input\" type=\"tel\" id=\"ims-qa-phone\">\n            </div>\n            <div class=\"ims__form-group\">\n              <label class=\"ims__label\">Email</label>\n              <input class=\"ims__input\" type=\"email\" id=\"ims-qa-email\">\n            </div>\n            <div class=\"ims__form-group\">\n              <label class=\"ims__label\">Postcode</label>\n              <input class=\"ims__input\" type=\"text\" id=\"ims-qa-postcode\">\n            </div>\n            <div class=\"ims__form-group ims__form-group--full\">\n              <label class=\"ims__label\">Address</label>\n              <input class=\"ims__input\" type=\"text\" id=\"ims-qa-address\">\n            </div>\n          </div>\n          <button class=\"ims__btn ims__btn--primary ims__btn--sm\" style=\"margin-top:6px\" onclick=\"window.IMS_ORDERS.saveQuickAddCustomer()\"><i class=\"ti ti-user-plus\"></i> Save customer &amp; continue</button>\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label\">Order type</label>\n          <select class=\"ims__select\" id=\"ims-no-type-display\" disabled>\n            <option value=\"retail\">Retail</option>\n            <option value=\"wholesale\">Wholesale</option>\n          </select>\n          <span class=\"ims__input-hint\" id=\"ims-no-type-hint\">Auto-set from platform</span>\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label ims__label--req\">Order date</label>\n          <input class=\"ims__input\" type=\"date\" id=\"ims-no-orderdate\" value=\"${new Date().toISOString().split('T')[0]}\" max=\"${new Date().toISOString().split('T')[0]}\">\n          <span class=\"ims__input-hint\">Defaults to today \u2014 change if logging an order taken earlier</span>\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label ims__label--req\">Fulfilling warehouse</label>\n          <select class=\"ims__select\" id=\"ims-no-warehouse\" onchange=\"window.IMS_ORDERS.onWarehouseChange()\">\n            <option value=\"\">Select warehouse</option>${warehouseOpts}\n          </select>\n          <span class=\"ims__input-hint\">Stock availability below is checked against this warehouse</span>\n        </div>\n        <div class=\"ims__form-group ims__form-group--full\">\n          <div style=\"display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:6px\">\n            <label class=\"ims__label ims__label--req\" style=\"margin:0\">Delivery address</label>\n            <label id=\"ims-no-altdelivery-wrap\" style=\"display:none;align-items:center;gap:7px;font-size:12px;font-weight:500;color:var(--ims-text-sec);cursor:pointer\">\n              <input type=\"checkbox\" id=\"ims-no-altdelivery\" onchange=\"window.IMS_ORDERS.toggleAltDelivery()\">\n              Deliver to a different address\n            </label>\n          </div>\n          <textarea class=\"ims__textarea\" id=\"ims-no-address\" rows=\"2\" placeholder=\"Full delivery address\"></textarea>\n          <span class=\"ims__input-hint\" id=\"ims-no-altdelivery-hint\"></span>\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label\">Phone</label>\n          <input class=\"ims__input\" type=\"tel\" id=\"ims-no-phone\">\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label\">Email</label>\n          <input class=\"ims__input\" type=\"email\" id=\"ims-no-email\">\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label\">External ref (platform order #)</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-no-extref\" placeholder=\"e.g. Amazon order number\">\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label\">Notes</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-no-notes\" placeholder=\"Special instructions\">\n        </div>\n        <div class=\"ims__form-group ims__form-group--full\" id=\"ims-override-reason-group\" style=\"display:none\">\n          <label class=\"ims__label\" style=\"color:var(--ims-warning)\"><i class=\"ti ti-alert-triangle\"></i> Price override reason (required)</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-no-override-reason\" placeholder=\"e.g. Customer negotiated, promotional price, clearance...\">\n          <span class=\"ims__input-hint\">One or more item prices differ from the standard catalogue price</span>\n        </div>\n        <div class=\"ims__form-group ims__form-group--full\">\n          <label class=\"ims__label ims__label--req\">Payment status</label>\n          <div style=\"display:flex;gap:8px;flex-wrap:wrap\" id=\"ims-no-payment-btns\">\n            <label style=\"display:flex;align-items:center;gap:6px;cursor:pointer;padding:8px 14px;border:1.5px solid var(--ims-border);border-radius:var(--ims-radius);flex:1;min-width:120px\" id=\"ims-pay-btn-paid\">\n              <input type=\"radio\" name=\"ims-no-payment\" value=\"paid\" style=\"accent-color:var(--ims-success)\" checked>\n              <span><strong style=\"color:var(--ims-success)\">Paid</strong><br><span style=\"font-size:11px;color:var(--ims-text-muted)\">Payment received</span></span>\n            </label>\n            <label style=\"display:flex;align-items:center;gap:6px;cursor:pointer;padding:8px 14px;border:1.5px solid var(--ims-border);border-radius:var(--ims-radius);flex:1;min-width:120px\" id=\"ims-pay-btn-cod\">\n              <input type=\"radio\" name=\"ims-no-payment\" value=\"cod\">\n              <span><strong style=\"color:var(--ims-accent)\">COD</strong><br><span style=\"font-size:11px;color:var(--ims-text-muted)\">Cash on delivery</span></span>\n            </label>\n            <label style=\"display:flex;align-items:center;gap:6px;cursor:pointer;padding:8px 14px;border:1.5px solid var(--ims-border);border-radius:var(--ims-radius);flex:1;min-width:120px\" id=\"ims-pay-btn-unpaid\">\n              <input type=\"radio\" name=\"ims-no-payment\" value=\"unpaid\">\n              <span><strong style=\"color:var(--ims-danger)\">Unpaid</strong><br><span style=\"font-size:11px;color:var(--ims-text-muted)\">7-day hold</span></span>\n            </label>\n          </div>\n          <div id=\"ims-unpaid-warning\" style=\"margin-top:6px;font-size:11px;color:var(--ims-danger);display:none\">\n            <i class=\"ti ti-clock\"></i> Unpaid orders are held for 7 days then automatically flagged for action\n          </div>\n        </div>\n      </div>\n      <hr class=\"ims__divider\">\n      <div id=\"ims-deal-banner\" class=\"ims__alert ims__alert--info\" style=\"display:none;margin-bottom:10px\"></div>\n      <div style=\"display:flex;align-items:center;justify-content:space-between;margin-bottom:10px\">\n        <strong style=\"font-size:13px\">Order items</strong>\n        <button class=\"ims__btn ims__btn--secondary ims__btn--sm\" onclick=\"window.IMS_ORDERS.addItem()\"><i class=\"ti ti-plus\"></i> Add item</button>\n        <select class=\"ims__select\" id=\"ims-no-add-service\" style=\"width:auto;font-size:12px\" onchange=\"window.IMS_ORDERS.addService(this.value)\"><option value=\"\">+ Add service</option></select>\n      </div>\n      <div id=\"ims-no-items\">\n        <div style=\"font-size:12px;color:var(--ims-text-muted);padding:10px 0\">No items added yet</div>\n      </div>\n      <hr class=\"ims__divider\">\n      <div style=\"display:flex;justify-content:flex-end;align-items:center;gap:10px;margin-bottom:8px\">\n        <span style=\"font-size:13px;color:var(--ims-text-sec)\">Prices entered are</span>\n        <select class=\"ims__select\" id=\"ims-no-vat-treatment\" style=\"width:auto;font-size:12px\">\n          <option value=\"inclusive\">Inclusive of VAT</option>\n          <option value=\"exclusive\">Exclusive of VAT (VAT added on invoice)</option>\n        </select>\n      </div>\n      <div style=\"display:flex;justify-content:flex-end;align-items:center;gap:10px;margin-bottom:8px\">\n        <span style=\"font-size:13px;color:var(--ims-text-sec)\">Discount</span>\n        <select class=\"ims__select\" id=\"ims-no-disc-type\" style=\"width:auto;font-size:12px\" onchange=\"window.IMS_ORDERS.updateTotal()\">\n          <option value=\"none\">No discount</option>\n          <option value=\"pct\">Percentage %</option>\n          <option value=\"fixed\">Fixed \u00A3</option>\n        </select>\n        <input class=\"ims__input\" type=\"number\" min=\"0\" step=\"0.01\" id=\"ims-no-disc-value\"\n          placeholder=\"0\" style=\"width:80px;font-size:12px\"\n          oninput=\"window.IMS_ORDERS.updateTotal()\">\n        <span style=\"font-size:12px;color:var(--ims-danger);font-weight:600\" id=\"ims-no-disc-display\"></span>\n      </div>\n      <div style=\"display:flex;justify-content:flex-end;align-items:center;gap:12px\">\n        <span style=\"font-size:13px;color:var(--ims-text-sec)\">Total:</span>\n        <span style=\"font-size:20px;font-weight:700\" id=\"ims-no-total\">${util().formatCurrency(0)}</span>\n      </div>\n    `, `\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.IMS_ORDERS.cancelBatch()\">Cancel</button>\n      ${_batchOrders.length>0?`<span style=\"font-size:12px;color:var(--ims-text-muted);margin-right:4px\">${_batchOrders.length} saved in batch</span>`:''}\n      <button class=\"ims__btn ims__btn--secondary\" id=\"ims-save-add-btn\" onclick=\"window.IMS_ORDERS.saveOrder(this,true)\">\n        <i class=\"ti ti-plus\"></i> Save &amp; add new\n      </button>\n      <button class=\"ims__btn ims__btn--primary\" id=\"ims-save-order-btn\" onclick=\"window.IMS_ORDERS.saveOrder(this,false)\">\n        <i class=\"ti ti-check\"></i> ${_batchOrders.length>0?'Save &amp; exit':'Create order'}\n      </button>\n    `, 'lg');\n\n    await _loadServices();   // after the form is drawn, so the \"+ Add service\" list is filled\n    bindPostcodeLookup();\n    _bindAreaCheck();\n    setTimeout(()=>{\n      document.querySelectorAll('input[name=\"ims-no-payment\"]').forEach(r=>{\n        r.addEventListener('change', ()=>{\n          const warn = document.getElementById('ims-unpaid-warning');\n          if(warn) warn.style.display = r.value === 'unpaid' && r.checked ? '' : 'none';\n        });\n      });\n      document.getElementById('ims-no-phone')?.addEventListener('blur', checkForDeals);\n    }, 200);\n  }\n\n  // \u2500\u2500\u2500 DEALS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // Looks up the phone-matched customer and any active deal for the\n  // selected platform/customer, applies it to already-added items,\n  // and shows a banner. Called on platform change and phone blur.\n  async function checkForDeals() {\n    const platformId = document.getElementById('ims-no-platform')?.value || null;\n    const phone = document.getElementById('ims-no-phone')?.value?.trim();\n\n    _matchedCustomer = null;\n    if (phone) {\n      const { data: cust } = await db().select('customers', {\n        select: 'id,customer_type,discount_type,discount_value',\n        eq: { phone, is_active: true }, maybeSingle: true   // deactivated customers are not matched\n      });\n      if (cust) _matchedCustomer = cust;\n    }\n\n    const customerId = _matchedCustomer?.id || null;\n    // customers table uses wholesale/retailer/trade; deals module now\n    // uses the same vocabulary directly \u2014 no translation needed.\n    const customerType = _matchedCustomer?.customer_type || null;\n\n    const deals = (await window.IMS_DEALS?.getActiveDealsForOrder(customerId, customerType, platformId)) || [];\n    if (!deals.length) {\n      _activeDeal = null;\n    } else {\n      deals.sort((a, b) => {\n        const aSpecific = (a.deal_customers||[]).some(dc => dc.customer_id === customerId) ? 1 : 0;\n        const bSpecific = (b.deal_customers||[]).some(dc => dc.customer_id === customerId) ? 1 : 0;\n        if (aSpecific !== bSpecific) return bSpecific - aSpecific;\n        return (b.discount_value||0) - (a.discount_value||0);\n      });\n      _activeDeal = deals[0];\n    }\n\n    updateDealBanner();\n    _orderItems.forEach((item, i) => { if (item.productId) applyDealToItem(i); });\n    renderItems();\n  }\n\n  function applyDealToItem(index) {\n    const item = _orderItems[index];\n    if (!item) return;\n    // A line loaded from an order being amended keeps the price already\n    // agreed, unless its product is changed.\n    if (item.keepPrice) return;\n    const base = item.basePrice ?? item.standardPrice ?? 0;\n    if (_activeDeal) {\n      const { finalPrice } = window.IMS_DEALS.calculateDealPrice(\n        base, _matchedCustomer?.discount_type, _matchedCustomer?.discount_value || 0, _activeDeal\n      );\n      item.unitPrice = finalPrice;\n      item.dealPrice = finalPrice;\n      item.dealApplied = true;\n    } else {\n      item.unitPrice = base;\n      item.dealPrice = null;\n      item.dealApplied = false;\n    }\n    // The system has just set this line's price itself, so any earlier\n    // manual override on the line no longer applies. Without this, a\n    // stale \"overridden\" flag would be saved against a system price.\n    item.isOverride = false;\n    item.overridePct = 0;\n  }\n\n  function updateDealBanner() {\n    const banner = document.getElementById('ims-deal-banner');\n    if (!banner) return;\n    if (_activeDeal) {\n      const discLabel = _activeDeal.discount_type === 'percentage'\n        ? `${_activeDeal.discount_value}% off`\n        : `\u00A3${_activeDeal.discount_value} off`;\n      banner.style.display = '';\n      banner.innerHTML = `<i class=\"ti ti-tag\"></i> Deal applied: <strong>${util().sanitize(_activeDeal.name)}</strong> \u2014 ${discLabel} (${_activeDeal.stacking_behaviour==='stack'?'stacks with':'replaces'} standing discount)`;\n    } else {\n      banner.style.display = 'none';\n      banner.innerHTML = '';\n    }\n  }\n\n  function onPlatformChange() {\n    const sel = document.getElementById('ims-no-platform');\n    if (!sel) return;\n    const opt = sel.options[sel.selectedIndex];\n    const type = opt?.dataset?.type || '';\n    const platformName = (opt?.textContent || '').toLowerCase();\n    const display = document.getElementById('ims-no-type-display');\n    const hint = document.getElementById('ims-no-type-hint');\n    if (display) {\n      display.value = type === 'wholesale' ? 'wholesale' : 'retail';\n      // Walk-in customers sometimes place a bulk order and ask for\n      // wholesale rates on the spot \u2014 unlock the choice for that platform\n      // specifically rather than forcing every walk-in sale to Retail.\n      // Every other platform stays locked to its own fixed type, since an\n      // Amazon or eBay order should never be manually switched.\n      const isWalkIn = platformName.includes('walk');\n      display.disabled = !isWalkIn;\n      if (hint) hint.textContent = isWalkIn\n        ? 'Walk-in customer \u2014 choose Retail or Wholesale for this order'\n        : 'Auto-set from platform';\n    }\n    checkForDeals();\n    updateCustomerLock();\n    // If a postcode was already typed before switching to a wholesale\n    // platform, trigger the registered-customer postcode lookup now\n    // rather than waiting for another keystroke in the postcode field.\n    const postcodeInput = document.getElementById('ims-no-postcode');\n    if (type === 'wholesale' && postcodeInput?.value?.trim().length >= 3) {\n      postcodeInput.dispatchEvent(new Event('input'));\n    }\n  }\n\n  // Wholesale orders must be tied to a registered customer, otherwise no\n  // receivable is created on delivery and the order can never be marked\n  // paid (this is how \"DA17 6BS\" ended up as a customer name and \u00A33.3k of\n  // debt became unrecoverable). Marketplace orders are the opposite \u2014\n  // buyer names from Temu/Amazon/eBay will never exist as customer\n  // records, so those stay free text.\n  function updateCustomerLock() {\n    const sel   = document.getElementById('ims-no-platform');\n    const input = document.getElementById('ims-no-custname');\n    const hint  = document.getElementById('ims-no-custname-hint');\n    if (!sel || !input || !hint) return;\n    const type = sel.options[sel.selectedIndex]?.dataset?.type || '';\n\n    if (type !== 'wholesale') {\n      input.readOnly = false;\n      input.style.background = '';\n      input.placeholder = 'Customer or business name';\n      hint.innerHTML = '';\n      return;\n    }\n\n    input.readOnly = true;\n    input.style.background = 'var(--ims-surface2)';\n    input.placeholder = 'Select a registered customer';\n\n    if (_pickedCustomerId) {\n      hint.innerHTML = `<span style=\"color:var(--ims-success)\"><i class=\"ti ti-link\"></i> Linked to a registered customer</span>\n        &nbsp;\u00B7&nbsp;<span class=\"ims__link\" style=\"cursor:pointer\" onclick=\"window.IMS_ORDERS.clearPickedCustomer()\">Change</span>`;\n    } else {\n      hint.innerHTML = `<span style=\"color:var(--ims-warning)\"><i class=\"ti ti-alert-triangle\"></i> Search by postcode above to link a registered customer</span>\n        &nbsp;\u00B7&nbsp;${_canAddCustomers()\n          ? `<span class=\"ims__link\" style=\"cursor:pointer\" onclick=\"window.IMS_ORDERS.addNewCustomerFromOrder()\">+ Add new customer</span>`\n          : `<span style=\"color:var(--ims-text-muted)\">Ask an Admin to add new customers</span>`}`;\n    }\n  }\n\n  function clearPickedCustomer() {\n    _pickedCustomerId = null;\n    ['ims-no-custname','ims-no-address','ims-no-phone','ims-no-email'].forEach(id => {\n      const el = document.getElementById(id);\n      if (el) el.value = '';\n    });\n    updateCustomerLock();\n    checkForDeals();\n  }\n\n  // Honest limitation: the Customers form is itself a modal, so opening it\n  // from inside the new-order modal would replace it and lose the order in\n  // progress. Rather than silently discarding work, this asks first.\n  // \"+ Add new customer\" (under the customer name) opens the order form's\n  // own quick-add, which adds the customer and links them to this order.\n  // It used to leave the order for the Customers screen, losing everything\n  // typed so far. The full Customers screen is still in the sidebar for\n  // detailed records.\n  async function addNewCustomerFromOrder() {\n    if (!_canAddCustomers()) { ui().toast('Only an Admin can add new customers', 'error'); return; }\n    showQuickAddCustomer();\n  }\n\n  // \u2500\u2500\u2500 POSTCODE LOOKUP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  function bindPostcodeLookup() {\n    const input   = document.getElementById('ims-no-postcode');\n    const drop    = document.getElementById('ims-no-postcode-drop');\n    const hint    = document.getElementById('ims-no-postcode-hint');\n    if (!input || !drop) return;\n\n    const search = util().debounce(async (val) => {\n      const seq = ++_searchSeq.postcode;\n      const clean = val.replace(/\\s/g,'').toUpperCase();\n      if (clean.length < 3) { drop.style.display = 'none'; return; }\n\n      // Registered wholesale/retailer/trade customer accounts matching\n      // this postcode \u2014 only looked up when the selected platform is a\n      // wholesale-type platform (e.g. \"Retailer / Wholesaler\"), since\n      // that's the audience with real customer accounts on file.\n      const platSel  = document.getElementById('ims-no-platform');\n      const platType = platSel?.options[platSel.selectedIndex]?.dataset?.type || '';\n      let accountMatches = [];\n      if (platType === 'wholesale') {\n        // `clean` has spaces stripped (\"BS57ES\"), but customers store their\n        // postcode WITH the space (\"BS5 7ES\") \u2014 so an ilike against `clean`\n        // could never match, and this lookup silently returned nothing for\n        // every wholesale order ever created. order_postcode_history stores\n        // them normalised, which is why only that half appeared to work.\n        //\n        // Query on the area code (first two chars \u2014 always space-free and\n        // present regardless of stored format), then compare properly\n        // normalised values client-side, so \"BS5 7ES\" or \"BS57ES\" typed by\n        // the user matches either way it happens to be stored.\n        const area = clean.slice(0, 2);\n        const { data } = await db().select('customers', {\n          select: 'id,business_name,contact_name,phone,email,address,postcode,customer_type',\n          ilike: { postcode: area },\n          eq: { is_active: true },\n          limit: 50\n        });\n        if (seq !== _searchSeq.postcode) return;   // a newer search has started\n        accountMatches = (data || [])\n          .filter(c => (c.postcode || '').replace(/\\s/g, '').toUpperCase().startsWith(clean))\n          .slice(0, 8);\n      }\n\n      const { data: matches } = await db().select('order_postcode_history', {\n        ilike: { postcode: clean },\n        order: { col: 'order_count', asc: false },\n        limit: 8\n      });\n      if (seq !== _searchSeq.postcode) return;   // a newer search has started\n      const historyCount = matches?.length || 0;\n      const accountCount = accountMatches.length;\n\n      if (!accountCount && !historyCount) {\n        drop.style.display = 'none';\n        if (hint) hint.textContent = 'New postcode \u2014 no previous deliveries';\n        return;\n      }\n\n      if (hint) {\n        hint.textContent = accountCount\n          ? `${accountCount} registered customer(s) at this postcode`\n          : `${historyCount} previous customer(s) at this postcode`;\n      }\n\n      drop.innerHTML = `\n        ${_canAddCustomers() ? `<div class=\"ims__ac-item\" style=\"font-weight:600;color:var(--ims-accent)\"\n          onmousedown=\"window.IMS_ORDERS.showQuickAddCustomer()\">\n          <i class=\"ti ti-user-plus\"></i> + New customer\n        </div>` : ''}\n        ${accountCount ? `\n          <div style=\"font-size:10px;font-weight:600;color:var(--ims-text-muted);padding:4px 8px;text-transform:uppercase\">Registered customers</div>\n          ${accountMatches.map(c => `\n            <div class=\"ims__ac-item\"\n              onmousedown=\"window.IMS_ORDERS.fillCustomerFromAccount(${JSON.stringify(c).replace(/\"/g,'&quot;')})\">\n              <strong>${util().sanitize(c.business_name)}</strong>\n              <span style=\"font-size:11px;color:var(--ims-text-muted);margin-left:6px\">${util().sanitize(c.customer_type||'')}</span>\n            </div>`).join('')}\n        ` : ''}\n        ${historyCount ? `\n          ${accountCount ? '<div style=\"font-size:10px;font-weight:600;color:var(--ims-text-muted);padding:4px 8px;text-transform:uppercase;border-top:1px solid var(--ims-border);margin-top:4px\">Previous orders</div>' : ''}\n          ${matches.map(m => `\n            <div class=\"ims__ac-item\"\n              onmousedown=\"window.IMS_ORDERS.fillCustomer(${JSON.stringify(m).replace(/\"/g,'&quot;')})\">\n              <strong>${util().sanitize(m.customer_name)}</strong>\n              <span style=\"font-size:11px;color:var(--ims-text-muted);margin-left:6px\">${m.order_count} order(s)</span>\n            </div>`).join('')}\n        ` : ''}`;\n      drop.style.display = 'block';\n    }, 300);\n\n    input.addEventListener('input', e => search(e.target.value));\n    input.addEventListener('blur', () => setTimeout(() => { drop.style.display = 'none'; }, 200));\n  }\n\n  function fillCustomerFromAccount(record) {\n    _pickedCustomerId = record.id;\n    const f = (id, v) => { const el = document.getElementById(id); if (el) el.value = v || ''; };\n    f('ims-no-custname', record.business_name);\n    f('ims-no-address',  record.address);\n    f('ims-no-postcode', record.postcode);\n    f('ims-no-phone',    record.phone);\n    f('ims-no-email',    record.email);\n    const drop = document.getElementById('ims-no-postcode-drop');\n    if (drop) drop.style.display = 'none';\n    // Re-run deal matching now that the phone field reflects this\n    // customer \u2014 checkForDeals() derives _matchedCustomer by phone, so\n    // this naturally picks up their standing discount/deal without\n    // duplicating that lookup logic here.\n    checkForDeals();\n    updateCustomerLock();\n    // Remember this customer's registered address/postcode so the\n    // \"deliver elsewhere\" toggle can restore it if the user unticks, and\n    // reveal that toggle now that we have a registered customer to compare\n    // against. The customer RECORD is never modified \u2014 only what's on this\n    // one order changes.\n    _customerDefaultAddress  = record.address || '';\n    _customerDefaultPostcode = record.postcode || '';\n    const altWrap = document.getElementById('ims-no-altdelivery-wrap');\n    if (altWrap) altWrap.style.display = 'flex';\n    const altChk = document.getElementById('ims-no-altdelivery');\n    if (altChk) altChk.checked = false;\n    lockDeliveryFields(true);\n    ui().toast(`Customer details filled from ${record.business_name}`, 'success');   // toast() escapes its message itself\n  }\n\n  // When a registered customer is selected, their delivery address/postcode\n  // are locked to their record by default. Ticking \"Deliver to a different\n  // address\" unlocks and clears them for a one-off destination; unticking\n  // restores the customer's registered address.\n  function toggleAltDelivery() {\n    const chk  = document.getElementById('ims-no-altdelivery');\n    const hint = document.getElementById('ims-no-altdelivery-hint');\n    const addr = document.getElementById('ims-no-address');\n    const pc   = document.getElementById('ims-no-postcode');\n    if (!chk) return;\n\n    if (chk.checked) {\n      lockDeliveryFields(false);\n      if (addr) addr.value = '';\n      if (pc)   pc.value   = '';\n      if (hint) hint.innerHTML = '<span style=\"color:var(--ims-warning)\"><i class=\"ti ti-map-pin\"></i> One-off delivery address \u2014 the customer record is not changed.</span>';\n      if (pc) pc.focus();\n    } else {\n      if (addr) addr.value = _customerDefaultAddress;\n      if (pc)   pc.value   = _customerDefaultPostcode;\n      lockDeliveryFields(true);\n      if (hint) hint.innerHTML = '';\n    }\n  }\n\n  function lockDeliveryFields(locked) {\n    const addr = document.getElementById('ims-no-address');\n    const pc   = document.getElementById('ims-no-postcode');\n    [addr, pc].forEach(el => {\n      if (!el) return;\n      el.readOnly = locked;\n      el.style.background = locked ? 'var(--ims-surface2)' : '';\n    });\n  }\n\n  function fillCustomer(record) {\n    const f = (id, v) => { const el = document.getElementById(id); if (el) el.value = v || ''; };\n    f('ims-no-custname', record.customer_name);\n    f('ims-no-address',  record.address);\n    f('ims-no-postcode', record.postcode);\n    f('ims-no-phone',    record.phone);\n    f('ims-no-email',    record.email);\n    const drop = document.getElementById('ims-no-postcode-drop');\n    if (drop) drop.style.display = 'none';\n    ui().toast('Customer details filled from history', 'success');\n  }\n\n  function clearCustomer() {\n    ['ims-no-custname','ims-no-address','ims-no-phone','ims-no-email'].forEach(id => {\n      const el = document.getElementById(id); if (el) el.value = '';\n    });\n    const drop = document.getElementById('ims-no-postcode-drop');\n    if (drop) drop.style.display = 'none';\n  }\n\n  // \u2500\u2500\u2500 QUICK-ADD CUSTOMER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // The postcode dropdown's \"+ New customer\" previously just called\n  // clearCustomer() \u2014 clearing the fields for free typing, with no real\n  // customer record ever created and no customer_id set on the order.\n  // Every order entered this way was silently unlinked: it wouldn't show\n  // up under any customer's history, and there was nothing in Customers\n  // to find, because nothing was ever inserted there. This replaces that\n  // with an actual inline creation form, so \"+ New customer\" does what\n  // it says \u2014 creates a real, linked customer record \u2014 without leaving\n  // the order form or losing anything already entered.\n  function showQuickAddCustomer() {\n    if (!_canAddCustomers()) { ui().toast('Only an Admin can add new customers', 'error'); return; }\n    const drop = document.getElementById('ims-no-postcode-drop');\n    if (drop) drop.style.display = 'none';\n    const nameField = document.getElementById('ims-no-custname')?.closest('.ims__form-group');\n    if (nameField) nameField.style.display = 'none';\n    const quickAdd = document.getElementById('ims-no-quickadd');\n    if (quickAdd) quickAdd.style.display = '';\n    // Pre-fill from whatever's already typed, so staff don't retype it.\n    const postcode = document.getElementById('ims-no-postcode')?.value || '';\n    const typedName = document.getElementById('ims-no-custname')?.value || '';\n    const qaPostcode = document.getElementById('ims-qa-postcode');\n    const qaName = document.getElementById('ims-qa-name');\n    if (qaPostcode) qaPostcode.value = postcode;\n    if (qaName) qaName.value = typedName;\n    qaName?.focus();\n  }\n\n  async function saveQuickAddCustomer() {\n    const name = document.getElementById('ims-qa-name')?.value?.trim();\n    if (!name) { ui().toast('Please enter a business/customer name', 'error'); return; }\n    const contact  = document.getElementById('ims-qa-contact')?.value?.trim()  || null;\n    const phone    = document.getElementById('ims-qa-phone')?.value?.trim()    || null;\n    const email    = document.getElementById('ims-qa-email')?.value?.trim()    || null;\n    const postcode = document.getElementById('ims-qa-postcode')?.value?.trim() || null;\n    const address  = document.getElementById('ims-qa-address')?.value?.trim() || null;\n\n    // Checked again here, not just by hiding the option.\n    if (!_canAddCustomers()) { ui().toast('Only an Admin can add new customers', 'error'); return; }\n    // Someone other than an Admin adding a customer: no credit until an\n    // Admin sets terms (the same rule as the Customers screen).\n    const noCredit = window.SM.AUTH.isAdmin() ? {} : { credit_terms: 'Advance payment', credit_limit: 0 };\n    const { data, error } = await db().insert('customers', {\n      business_name: name, contact_name: contact,\n      phone, email, postcode, address, is_active: true, ...noCredit\n    });\n    if (error) { ui().toast('Failed to create customer: ' + error.message, 'error'); return; }\n\n    _pickedCustomerId = data.id;\n    const set = (id, val) => { const el = document.getElementById(id); if (el) el.value = val || ''; };\n    set('ims-no-custname', name);\n    set('ims-no-phone', phone);\n    set('ims-no-email', email);\n    set('ims-no-address', address);\n    const pcEl = document.getElementById('ims-no-postcode');\n    if (pcEl && !pcEl.value) pcEl.value = postcode || '';\n\n    const quickAdd = document.getElementById('ims-no-quickadd');\n    if (quickAdd) quickAdd.style.display = 'none';\n    const nameField = document.getElementById('ims-no-custname')?.closest('.ims__form-group');\n    if (nameField) nameField.style.display = '';\n\n    updateCustomerLock();\n    ui().toast(`${name} added \u2014 linked to this order`, 'success');\n  }\n\n  // Explicit escape hatch for a genuine one-off sale where a permanent\n  // customer record isn't wanted \u2014 falls back to the old free-text\n  // behaviour, but now only by deliberate choice rather than by default.\n  function cancelQuickAddCustomer() {\n    const quickAdd = document.getElementById('ims-no-quickadd');\n    if (quickAdd) quickAdd.style.display = 'none';\n    const nameField = document.getElementById('ims-no-custname')?.closest('.ims__form-group');\n    if (nameField) nameField.style.display = '';\n    clearCustomer();\n  }\n\n  // \u2500\u2500\u2500 ORDER ITEMS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // \u2500\u2500\u2500 SERVICES ON AN ORDER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // Services from the price list (Logistics > Services), sold as order\n  // lines: no stock effect, the order's VAT setting, no deals or price\n  // override rules. Whoever carries them out confirms done / not done.\n  let _services = [];\n  async function _loadServices() {\n    const { data } = await window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY)\n      .from('services').select('id,name,customer_price,per').eq('company_id', window.SM.AUTH.company?.id).eq('is_active', true).order('sort_order', { ascending: true });\n    _services = data || [];\n    const sel = document.getElementById('ims-no-add-service');\n    if (sel) sel.innerHTML = `<option value=\"\">+ Add service</option>` + (_services.length ? _services.map(v => `<option value=\"${v.id}\">${util().sanitize(v.name)} (${util().formatCurrency(v.customer_price)})</option>`).join('') : '<option value=\"\" disabled>No services set up yet</option>');\n  }\n  function addService(serviceId) {\n    const v = _services.find(x => x.id === serviceId);\n    const sel = document.getElementById('ims-no-add-service'); if (sel) sel.value = '';\n    if (!v) return;\n    _orderItems.push({ productId: '', productName: v.name, sku: '', qty: 1, unitPrice: Number(v.customer_price) || 0, costPrice: 0,\n      basePrice: Number(v.customer_price) || 0, dealApplied: false, keepPrice: true, serviceId: v.id, per: v.per });\n    renderItems();\n  }\n\n  // \u2500\u2500\u2500 OUTSIDE OUR DELIVERY AREA? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // A warning (not a block) under the postcode when no courier with zones\n  // delivers there (every one has it in its \"Not delivered\" zone), so\n  // nobody promises a delivery we cannot make. The latest check wins, so\n  // fast typing never shows an old answer.\n  let _areaSeq = 0;\n  function _bindAreaCheck() {\n    const input = document.getElementById('ims-no-postcode');\n    if (!input || input.dataset.areaBound === '1') return;\n    input.dataset.areaBound = '1';\n    let t = null;\n    input.addEventListener('input', () => { clearTimeout(t); t = setTimeout(_checkDeliveryArea, 400); });\n    input.addEventListener('change', _checkDeliveryArea);\n  }\n  async function _checkDeliveryArea() {\n    const input = document.getElementById('ims-no-postcode'); if (!input) return;\n    let hint = document.getElementById('ims-no-area-hint');\n    if (!hint) {\n      hint = document.createElement('div'); hint.id = 'ims-no-area-hint'; hint.style.cssText = 'font-size:12px;margin-top:4px';\n      (document.getElementById('ims-no-postcode-hint') || input).insertAdjacentElement('afterend', hint);\n    }\n    const seq = ++_areaSeq;\n    const pc = String(input.value || '').toUpperCase().replace(/\\s+/g, '');\n    if (pc.length < 5) { hint.innerHTML = ''; return; }\n    const out = pc.slice(0, -3), area = (out.match(/^[A-Z]{1,2}/) || [''])[0];\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const { data: zones } = await client.from('courier_zones').select('id,courier_id,kind').eq('company_id', window.SM.AUTH.company?.id);\n    const couriers = [...new Set((zones || []).map(z => z.courier_id))];\n    if (!couriers.length) { if (seq === _areaSeq) hint.innerHTML = ''; return; }\n    const { data: pcs } = await client.from('courier_zone_postcodes').select('courier_id,zone_id,prefix').in('prefix', [out, area]);\n    if (seq !== _areaSeq) return;   // a newer check has started\n    const notServed = couriers.filter(cid => {\n      const mine = (pcs || []).filter(p => p.courier_id === cid);\n      const hit = mine.find(p => p.prefix === out) || mine.find(p => p.prefix === area);\n      return (zones || []).find(z => z.id === hit?.zone_id)?.kind === 'not_served';\n    });\n    hint.innerHTML = notServed.length === couriers.length\n      ? `<span style=\"color:var(--ims-warning)\"><i class=\"ti ti-alert-triangle\"></i> ${util().sanitize(out)} is outside our delivery area. Check before promising a delivery.</span>`\n      : '';\n  }\n\n  function addItem() {\n    _orderItems.push({ productId: '', productName: '', sku: '', qty: 1, unitPrice: 0, costPrice: 0, basePrice: 0, dealApplied: false });\n    renderItems();\n  }\n\n  function renderItems() {\n    const container = document.getElementById('ims-no-items');\n    if (!container) return;\n    if (!_orderItems.length) {\n      container.innerHTML = '<div style=\"font-size:12px;color:var(--ims-text-muted);padding:10px 0\">No items added yet</div>';\n      syncOverrideReason();\n      updateTotal();\n      return;\n    }\n    container.innerHTML = _orderItems.map((item, i) => item.serviceId ? `\n      <div style=\"display:grid;grid-template-columns:2fr 70px 110px auto;gap:8px;align-items:center;margin-bottom:8px\">\n        <div style=\"display:flex;gap:6px;align-items:center\"><span class=\"ims__pill ims__pill--info\" style=\"font-size:10px\">Service</span><span>${util().sanitize(item.productName)}</span></div>\n        <input class=\"ims__input\" type=\"number\" min=\"1\" value=\"${item.qty}\" ${item.per === 'order' ? 'disabled title=\"Charged once per order\"' : ''}\n          oninput=\"window.IMS_ORDERS.updateItem(${i},'qty',+this.value||1)\">\n        <input class=\"ims__input\" type=\"number\" min=\"0\" step=\"0.01\" value=\"${item.unitPrice}\" placeholder=\"Price (&pound;)\" id=\"ims-price-${i}\"\n          oninput=\"window.IMS_ORDERS.updateItem(${i},'unitPrice',+this.value||0)\">\n        <button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\"\n          onclick=\"window.IMS_ORDERS.removeItem(${i})\"><i class=\"ti ti-trash\"></i></button>\n      </div>` : `\n      <div style=\"display:grid;grid-template-columns:2fr 70px 110px auto;gap:8px;align-items:center;margin-bottom:8px\">\n        <div style=\"position:relative\">\n          <input class=\"ims__input\" type=\"text\" placeholder=\"Product name or SKU\"\n            value=\"${util().sanitize(item.productName)}\" autocomplete=\"off\"\n            oninput=\"window.IMS_ORDERS.updateItem(${i},'productName',this.value);window.IMS_ORDERS.searchProduct(${i},this.value,this)\">\n          <div id=\"ims-prod-drop-${i}\" class=\"ims__ac-dropdown\"></div>\n        </div>\n        <input class=\"ims__input\" type=\"number\" min=\"1\" value=\"${item.qty}\" placeholder=\"Qty\"\n          oninput=\"window.IMS_ORDERS.updateItem(${i},'qty',+this.value||1)\">\n        <div style=\"position:relative\">\n          <input class=\"ims__input\" type=\"number\" min=\"0\" step=\"0.01\"\n            value=\"${item.unitPrice}\" placeholder=\"Unit price (&pound;)\"\n            id=\"ims-price-${i}\"\n            oninput=\"window.IMS_ORDERS.updateItem(${i},'unitPrice',+this.value||0);window.IMS_ORDERS.checkOverride(${i})\"\n            style=\"${item.isOverride?'border-color:var(--ims-warning);background:var(--ims-warning-bg)':item.dealApplied?'border-color:var(--ims-accent)':''}\">\n          ${item.productId ? `<span style=\"font-size:10px;color:var(--ims-text-muted);position:absolute;top:-16px;left:0\">Available: <span id=\"ims-avail-${i}\">...</span></span>` : ''}\n          <div id=\"ims-price-note-${i}\">${_priceNoteHtml(item)}</div>\n        </div>\n        <button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\"\n          onclick=\"window.IMS_ORDERS.removeItem(${i})\"><i class=\"ti ti-trash\"></i></button>\n      </div>\n      <div id=\"ims-alloc-panel-${i}\" style=\"margin:-4px 0 8px 0\"></div>`).join('');\n    // Load available stock for each product against the selected warehouse\n    const warehouseId = document.getElementById('ims-no-warehouse')?.value || '';\n    _orderItems.forEach((item, i) => {\n      if (item.productId) loadAvailStock(i, item.productId, warehouseId);\n    });\n    syncOverrideReason();\n    updateTotal();\n  }\n\n  function onWarehouseChange() {\n    const warehouseId = document.getElementById('ims-no-warehouse')?.value || '';\n    // A marked allocation release belongs to the warehouse it was made in,\n    // so changing warehouse cancels it (nothing was released yet).\n    const hadReleases = _orderItems.some(i => i.pendingReleases?.length);\n    _orderItems.forEach(i => { i.pendingReleases = []; });\n    if (hadReleases) ui().toast('Warehouse changed, so the marked allocation releases were cancelled', 'info', 6000);\n    _orderItems.forEach((item, i) => {\n      const panel = document.getElementById(`ims-alloc-panel-${i}`);\n      if (panel) { panel.innerHTML = ''; panel.dataset.expanded = '0'; }\n      if (item.productId) loadAvailStock(i, item.productId, warehouseId);\n    });\n  }\n\n  // \u2500\u2500\u2500 RELEASE FROM DROPSHIP ALLOCATION \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // When normal stock runs out but a dropship partner has units allocated\n  // in this warehouse, staff can release some to this order. The release\n  // is only MARKED on the order line (item.pendingReleases) and carried\n  // out by saveOrder() after the order has saved. Before, it happened the\n  // moment Release was clicked, so closing the form without saving took\n  // the units away from the partner for nothing.\n\n  // Units marked for release on this order, for a product in a warehouse.\n  function _pendingReleaseQty(productId, warehouseId) {\n    return _orderItems.reduce((sum, item) => sum + (item.pendingReleases || [])\n      .filter(r => r.productId === productId && r.warehouseId === warehouseId)\n      .reduce((s, r) => s + (r.qty || 0), 0), 0);\n  }\n\n  // Units already marked for release from one allocation on this order.\n  function _pendingForAllocation(allocId) {\n    return _orderItems.reduce((sum, item) => sum + (item.pendingReleases || [])\n      .filter(r => r.allocId === allocId)\n      .reduce((s, r) => s + (r.qty || 0), 0), 0);\n  }\n\n  // Refreshes the stock figure and panel on every line of this product,\n  // since a release marked on one line changes what the others can see.\n  function _refreshAvailForProduct(productId) {\n    const warehouseId = document.getElementById('ims-no-warehouse')?.value || '';\n    _orderItems.forEach((item, i) => {\n      if (item.productId === productId) loadAvailStock(i, productId, warehouseId);\n    });\n  }\n\n  async function loadAvailStock(index, productId, warehouseId) {\n    const el = document.getElementById(`ims-avail-${index}`);\n    if (!warehouseId) {\n      if (el) { el.textContent = 'Select a warehouse'; el.style.color = 'var(--ims-warning)'; }\n      return;\n    }\n    const { data: sl } = await db().select('stock_levels', {\n      eq: { product_id: productId, warehouse_id: warehouseId }, maybeSingle: true, noCompanyFilter: true\n    });\n    const qty      = sl?.quantity || 0;\n    const reserved = sl?.reserved_qty || 0;\n    // Units marked for release on this order count as free already, so\n    // staff see the effect straight away.\n    const alloc    = Math.max(0, (sl?.reserved_by_allocations || 0) - _pendingReleaseQty(productId, warehouseId));\n    const trueAvail  = qty - reserved - alloc;\n    const looseAvail = qty - reserved; // ignoring dropship allocations\n    if (el) {\n      el.textContent = trueAvail;\n      el.style.color = trueAvail <= 0 ? 'var(--ims-danger)' : trueAvail <= 5 ? 'var(--ims-warning)' : '';\n    }\n\n    const item = _orderItems[index];\n    const needed = item?.qty || 1;\n    const panel = document.getElementById(`ims-alloc-panel-${index}`);\n    if (!panel) return;\n    if (panel.dataset.expanded === '1') return; // the release list is open; leave it\n\n    if (item?.pendingReleases?.length) {\n      const total = item.pendingReleases.reduce((s, r) => s + (r.qty || 0), 0);\n      const partners = [...new Set(item.pendingReleases.map(r => r.partner))].join(', ');\n      panel.innerHTML = `\n        <div class=\"ims__alert ims__alert--info\" style=\"margin:0;padding:6px 10px;font-size:11px;display:flex;align-items:center;justify-content:space-between;gap:8px\">\n          <span><i class=\"ti ti-arrow-back-up\"></i> ${total} unit(s) will be released from ${util().sanitize(partners)} when this order is saved.</span>\n          <button class=\"ims__btn ims__btn--ghost ims__btn--sm\" onclick=\"window.IMS_ORDERS.undoRelease(${index})\">Undo</button>\n        </div>`;\n      return;\n    }\n\n    if (trueAvail < needed && alloc > 0 && looseAvail >= needed) {\n      const shortfall = needed - trueAvail;\n      panel.innerHTML = `\n        <div class=\"ims__alert ims__alert--warning\" style=\"margin:0;padding:6px 10px;font-size:11px;display:flex;align-items:center;justify-content:space-between;gap:8px\">\n          <span><i class=\"ti ti-alert-triangle\"></i> ${alloc} unit(s) here are held for dropship allocation. Releasing some could cover this order.</span>\n          <button class=\"ims__btn ims__btn--warning ims__btn--sm\" onclick=\"window.IMS_ORDERS.toggleAllocationPanel(${index},'${util().jsArg(productId)}','${util().jsArg(warehouseId)}',${shortfall})\">Release from allocation</button>\n        </div>`;\n    } else {\n      panel.innerHTML = '';\n    }\n  }\n\n  async function toggleAllocationPanel(index, productId, warehouseId, shortfall) {\n    const panel = document.getElementById(`ims-alloc-panel-${index}`);\n    if (!panel) return;\n    if (panel.dataset.expanded === '1') {\n      panel.dataset.expanded = '0';\n      loadAvailStock(index, productId, warehouseId);\n      return;\n    }\n    const { data: allocs } = await db().select('dropship_allocations', {\n      select: 'id,remaining_qty,dropship_customers(business_name)',\n      eq: { product_id: productId, warehouse_id: warehouseId },\n      gt: { remaining_qty: 0 },\n      noCompanyFilter: true\n    });\n    // Leave out units already marked for release on another line.\n    const rows = (allocs||[])\n      .map(a => ({ ...a, free: (a.remaining_qty||0) - _pendingForAllocation(a.id) }))\n      .filter(a => a.free > 0);\n    panel.dataset.expanded = '1';\n    if (!rows.length) {\n      panel.innerHTML = `<div class=\"ims__alert ims__alert--info\" style=\"margin:0;padding:6px 10px;font-size:11px\">No dropship allocations found for this product in this warehouse.</div>`;\n      return;\n    }\n    panel.innerHTML = `\n      <div class=\"ims__card\" style=\"padding:8px;margin:0\">\n        <div style=\"font-size:11px;color:var(--ims-text-muted);margin-bottom:6px\">Need ${shortfall} more unit(s). Choose how many to release from each partner. Nothing is released until you save the order.</div>\n        ${rows.map(a => `\n          <div style=\"display:flex;align-items:center;gap:6px;margin-bottom:4px\">\n            <span style=\"font-size:12px;flex:1\">${util().sanitize(a.dropship_customers?.business_name||'Unknown customer')}: ${a.free} allocated</span>\n            <input class=\"ims__input\" type=\"number\" min=\"1\" max=\"${a.free}\" value=\"${Math.min(shortfall, a.free)}\" id=\"ims-alloc-qty-${index}-${a.id}\" style=\"width:70px;font-size:12px\">\n            <button class=\"ims__btn ims__btn--warning ims__btn--sm\" onclick=\"window.IMS_ORDERS.releaseFromAllocation(${index},'${util().jsArg(a.id)}','${util().jsArg(productId)}','${util().jsArg(warehouseId)}')\">Release</button>\n          </div>`).join('')}\n        <button class=\"ims__btn ims__btn--ghost ims__btn--sm\" style=\"margin-top:4px\" onclick=\"window.IMS_ORDERS.toggleAllocationPanel(${index},'${util().jsArg(productId)}','${util().jsArg(warehouseId)}',${shortfall})\">Close</button>\n      </div>`;\n  }\n\n  // Marks a release on this order line. Nothing changes in the database\n  // until the order is saved (see saveOrder).\n  async function releaseFromAllocation(index, allocId, productId, warehouseId) {\n    const item = _orderItems[index];\n    if (!item) return;\n    const input = document.getElementById(`ims-alloc-qty-${index}-${allocId}`);\n    const releaseQty = parseInt(input?.value) || 0;\n    if (!releaseQty || releaseQty <= 0) { ui().toast('Enter a quantity to release', 'error'); return; }\n\n    const { data: alloc } = await db().select('dropship_allocations', {\n      select: 'remaining_qty,dropship_customers(business_name)', eq: { id: allocId }, maybeSingle: true, noCompanyFilter: true\n    });\n    if (!alloc) { ui().toast('Allocation not found', 'error'); return; }\n    const free = (alloc.remaining_qty||0) - _pendingForAllocation(allocId);\n    const qty = Math.min(releaseQty, free);\n    if (qty <= 0) { ui().toast('Nothing left to release on this allocation', 'error'); return; }\n    const partner = alloc.dropship_customers?.business_name || 'dropship partner';\n\n    item.pendingReleases = [...(item.pendingReleases || []), { allocId, productId, warehouseId, qty, partner }];\n    ui().toast(`${qty} unit(s) will be released from ${partner} when you save this order`, 'info', 5000);\n    const panel = document.getElementById(`ims-alloc-panel-${index}`);\n    if (panel) panel.dataset.expanded = '0';\n    _refreshAvailForProduct(productId);\n  }\n\n  // Cancels the releases marked on one order line.\n  function undoRelease(index) {\n    const item = _orderItems[index];\n    if (!item) return;\n    item.pendingReleases = [];\n    ui().toast('Release cancelled', 'info', 3000);\n    if (item.productId) _refreshAvailForProduct(item.productId);\n  }\n\n  function updateItem(index, field, value) {\n    if (_orderItems[index]) {\n      _orderItems[index][field] = value;\n      if (field === 'qty' || field === 'unitPrice') updateTotal();\n    }\n  }\n\n  function removeItem(index) {\n    _orderItems.splice(index, 1);\n    renderItems();\n  }\n\n  function updateTotal() {\n    const subtotal = _orderItems.reduce((s, i) => s + ((i.qty||1) * (i.unitPrice||0)), 0);\n    const discType  = document.getElementById('ims-no-disc-type')?.value || 'none';\n    const discVal   = parseFloat(document.getElementById('ims-no-disc-value')?.value) || 0;\n    let discAmt = 0;\n    if(discType === 'pct' && discVal > 0)   discAmt = subtotal * (discVal / 100);\n    if(discType === 'fixed' && discVal > 0) discAmt = Math.min(discVal, subtotal);\n    const total = Math.max(0, subtotal - discAmt);\n    const discDisplay = document.getElementById('ims-no-disc-display');\n    if(discDisplay) discDisplay.textContent = discAmt > 0 ? `\u2212 ${util().formatCurrency(discAmt)}` : '';\n    const el = document.getElementById('ims-no-total');\n    if(el) el.textContent = util().formatCurrency(total);\n  }\n\n  // Note under a line's price box: the override warning, or the deal\n  // label, or nothing. Shared by renderItems() and checkOverride() so the\n  // first draw and every later in-place update always look the same.\n  function _priceNoteHtml(item) {\n    if (item.isOverride) {\n      return `<div style=\"font-size:10px;margin-top:2px;color:var(--ims-warning)\">\n          <i class=\"ti ti-alert-triangle\"></i>\n          Standard: ${util().formatCurrency(item.standardPrice)}\n          (${item.overridePct > 0 ? '+' : ''}${(item.overridePct || 0).toFixed(1)}%)\n        </div>`;\n    }\n    if (item.dealApplied) {\n      return `<div style=\"font-size:10px;margin-top:2px;color:var(--ims-accent)\">\n          <i class=\"ti ti-tag\"></i>\n          Deal price (was ${util().formatCurrency(item.basePrice || item.standardPrice)})\n        </div>`;\n    }\n    return '';\n  }\n\n  // Shows the \"Price override reason (required)\" field only while at\n  // least one line is overridden.\n  function syncOverrideReason() {\n    const hasAnyOverride = _orderItems.some(i => i.isOverride);\n    const group = document.getElementById('ims-override-reason-group');\n    if (group) group.style.display = hasAnyOverride ? '' : 'none';\n  }\n\n  // Runs on every keystroke in a price box.\n  //\n  // A line counts as overridden when staff type a price that differs from\n  // the price the system put there: the deal price if a deal applied,\n  // otherwise the standard catalogue price. Re-typing the deal price is\n  // therefore not an override. The saved percentage is always measured\n  // against the standard catalogue price, because that is what the Price\n  // Overrides report compares against (its Standard / Charged columns).\n  //\n  // This must NOT call renderItems(): that rebuilds every row, which throws\n  // the cursor out of the box after each character and wipes any open\n  // allocation panels. It updates only this row, then the reason field.\n  function checkOverride(index) {\n    const item = _orderItems[index];\n    if (!item) return;\n    const standard = Number(item.standardPrice) || 0;\n    if (standard > 0) {\n      const expected = (item.dealApplied && item.dealPrice != null)\n        ? Number(item.dealPrice)\n        : standard;\n      const charged = Number(item.unitPrice) || 0;\n      item.isOverride = Math.abs(charged - expected) > 0.005;\n      item.overridePct = item.isOverride ? ((charged - standard) / standard) * 100 : 0;\n    } else {\n      // No catalogue price on this product, so there is nothing to\n      // override against.\n      item.isOverride = false;\n      item.overridePct = 0;\n    }\n    const input = document.getElementById(`ims-price-${index}`);\n    if (input) {\n      input.style.borderColor = item.isOverride ? 'var(--ims-warning)' : (item.dealApplied ? 'var(--ims-accent)' : '');\n      input.style.background  = item.isOverride ? 'var(--ims-warning-bg)' : '';\n    }\n    const note = document.getElementById(`ims-price-note-${index}`);\n    if (note) note.innerHTML = _priceNoteHtml(item);\n    syncOverrideReason();\n  }\n\n  // Search guards. Every keystroke starts a new search, and the answers can\n  // come back in any order. Each search takes a number, and only the latest\n  // one may update the list, so an older, slower search can never replace\n  // the newer results (or hide the list). Seen as a match that sometimes\n  // failed to appear while typing.\n  const _searchSeq = { product: {}, postcode: 0 };\n\n  async function searchProduct(index, query, inputEl) {\n    const seq = (_searchSeq.product[index] = (_searchSeq.product[index] || 0) + 1);\n    if (!query || query.length < 2) {\n      const d = document.getElementById(`ims-prod-drop-${index}`);\n      if (d) d.style.display = 'none';\n      return;\n    }\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const [{ data: byName }, { data: bySku }] = await Promise.all([\n      db().select('products', { ilike: { name: query }, select: 'id,name,sku', limit: 5 }),\n      db().select('products', { ilike: { sku: query }, select: 'id,name,sku', limit: 5 })\n    ]);\n    if (seq !== _searchSeq.product[index]) return;   // a newer search has started\n    const combined = [...(byName||[]), ...(bySku||[])];\n    const products = combined.filter((p,i,arr) => arr.findIndex(x=>x.id===p.id)===i).slice(0,8);\n    const drop = document.getElementById(`ims-prod-drop-${index}`);\n    if (!drop || !products?.length) { if (drop) drop.style.display = 'none'; return; }\n    drop.innerHTML = products.map(p =>\n      `<div class=\"ims__ac-item\"\n        onmousedown=\"window.IMS_ORDERS.selectProduct(${index},${JSON.stringify({id:p.id,name:p.name,sku:p.sku}).replace(/\"/g,'&quot;')})\">\n        <strong>${util().sanitize(p.name)}</strong>\n        <span style=\"font-size:11px;color:var(--ims-text-muted);margin-left:6px\">${p.sku}</span>\n      </div>`\n    ).join('');\n    drop.style.display = 'block';\n  }\n\n  async function selectProduct(index, product) {\n    if (_orderItems[index]) {\n      _orderItems[index].keepPrice   = false;   // a different product: priced afresh\n      _orderItems[index].productId   = product.id;\n      _orderItems[index].productName = product.name;\n      _orderItems[index].sku         = product.sku;\n\n      const platSel = document.getElementById('ims-no-platform');\n      const platformId = platSel?.value;\n      const orderType = document.getElementById('ims-no-type-display')?.value || 'retail';\n\n      const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n      let price = 0;\n\n      if (platformId) {\n        const { data: platPrices } = await client.from('product_prices')\n          .select('price').eq('product_id', product.id)\n          .eq('price_type', 'platform').eq('platform_id', platformId).limit(1);\n        if (platPrices?.[0]) price = platPrices[0].price;\n      }\n      if (!price) {\n        const priceType = orderType === 'retail' ? 'rrp' : 'wholesale';\n        const { data: basePrices } = await client.from('product_prices')\n          .select('price').eq('product_id', product.id)\n          .eq('price_type', priceType).is('platform_id', null).limit(1);\n        if (basePrices?.[0]) price = basePrices[0].price;\n      }\n      if (!price) {\n        const fallbackType = orderType === 'retail' ? 'wholesale' : 'rrp';\n        const { data: fallback } = await client.from('product_prices')\n          .select('price').eq('product_id', product.id)\n          .eq('price_type', fallbackType).is('platform_id', null).limit(1);\n        if (fallback?.[0]) price = fallback[0].price;\n      }\n\n      _orderItems[index].basePrice     = price || 0;\n      _orderItems[index].unitPrice     = price || 0;\n      _orderItems[index].standardPrice = price || 0;\n      _orderItems[index].dealApplied   = false;\n      // A different product was picked, so any release marked for the\n      // previous product on this line no longer applies.\n      _orderItems[index].pendingReleases = [];\n\n      const { data: costRows } = await client.from('product_prices')\n        .select('price').eq('product_id', product.id)\n        .eq('price_type', 'cost').is('platform_id', null).limit(1);\n      if (costRows?.[0]) _orderItems[index].costPrice = costRows[0].price;\n\n      applyDealToItem(index);\n    }\n    renderItems();\n    const drop = document.getElementById(`ims-prod-drop-${index}`);\n    if (drop) drop.style.display = 'none';\n  }\n\n  // \u2500\u2500\u2500 WARNING BOX ON TOP OF THE ORDER FORM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // A small \"go back / go ahead\" box shown ABOVE the open order form,\n  // used by every warning in saveOrder(). It replaces two things:\n  //  - the shared UI.confirm(), which swaps the order form out for the\n  //    question. The duplicate-order warning used it, so the form was\n  //    wiped and saveOrder() then read empty fields (payment fell back to\n  //    \"unpaid\"; phone, email and notes were saved blank).\n  //  - the browser's own confirm(), where OK is always the default, so\n  //    pressing Enter out of habit went ahead.\n  // Here \"Go back\" is the default: it has focus, and Enter or Escape both\n  // mean go back. Tab only moves between the two buttons. Resolves true\n  // only if the go-ahead button is chosen. Pass okLabel: null for a hard\n  // block (only \"Go back\" is shown). Callers must sanitise any\n  // user-entered text they put in `message`.\n  // Adding customers (quick-add and \"+ Add new customer\"): Super Admin and\n  // Admin, or anyone granted \"Can add new customers\" in Users. The Customers\n  // screen and the database apply the same rule.\n  const _canAddCustomers = () => !!window.SM.AUTH.canAddCustomers?.();\n\n  // With reasonLabel, the box also asks for a written reason: the go-ahead\n  // button stays disabled until one is typed, and the promise resolves to\n  // that reason (or false for \"Go back\"). Enter inside the reason box adds\n  // a new line; it never submits or cancels.\n  function _askOverForm({ title, message, okLabel = 'Save anyway', danger = false, reasonLabel = null }) {\n    return new Promise(resolve => {\n      const wrap = document.createElement('div');\n      wrap.style.cssText = 'position:fixed;inset:0;z-index:100000;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px';\n      wrap.innerHTML = `\n        <div role=\"alertdialog\" aria-modal=\"true\" style=\"background:var(--ims-surface);color:var(--ims-text);border:1px solid var(--ims-border);border-radius:var(--ims-radius);max-width:460px;width:100%;box-shadow:0 20px 50px rgba(0,0,0,.3);font-family:var(--ims-font);font-size:14px\">\n          <div style=\"padding:16px 18px 6px;font-weight:700;display:flex;align-items:center;gap:8px\"><i class=\"ti ti-alert-triangle\" style=\"color:var(--ims-warning)\"></i>${util().sanitize(title)}</div>\n          <div style=\"padding:6px 18px 14px;color:var(--ims-text-sec);line-height:1.5\">${message}</div>\n          ${reasonLabel ? `<div style=\"padding:0 18px 14px\"><label style=\"display:block;font-size:12px;font-weight:600;margin-bottom:6px\">${util().sanitize(reasonLabel)}</label><textarea data-act-reason rows=\"3\" class=\"ims__textarea\" style=\"width:100%\"></textarea></div>` : ''}\n          <div style=\"padding:12px 18px;border-top:1px solid var(--ims-border);display:flex;justify-content:flex-end;gap:8px\">\n            <button type=\"button\" class=\"ims__btn ims__btn--ghost\" data-act=\"cancel\">Go back</button>\n            ${okLabel ? `<button type=\"button\" class=\"ims__btn ims__btn--${danger ? 'danger' : 'warning'}\" data-act=\"ok\">${util().sanitize(okLabel)}</button>` : ''}\n          </div>\n        </div>`;\n      const cancelBtn = () => wrap.querySelector('[data-act=\"cancel\"]');\n      const okBtn = () => wrap.querySelector('[data-act=\"ok\"]');\n      const reasonBox = () => wrap.querySelector('[data-act-reason]');\n      const reasonText = () => (reasonBox()?.value || '').trim();\n      const finish = (answer) => {\n        document.removeEventListener('keydown', onKey, true);\n        wrap.remove();\n        resolve(answer && reasonLabel ? reasonText() : answer);\n      };\n      const onKey = (e) => {\n        if (e.key === 'Escape') { e.preventDefault(); e.stopPropagation(); finish(false); }\n        else if (e.key === 'Enter') {\n          if (document.activeElement === reasonBox()) return;   // new line in the reason\n          e.preventDefault(); e.stopPropagation(); finish(!!okBtn() && !okBtn().disabled && document.activeElement === okBtn());\n        }\n        else if (e.key === 'Tab') {\n          e.preventDefault(); e.stopPropagation();\n          const order = [reasonBox(), cancelBtn(), okBtn()].filter(el => el && !el.disabled);\n          const at = order.indexOf(document.activeElement);\n          (order[(at + 1) % order.length] || cancelBtn()).focus();\n        }\n      };\n      wrap.addEventListener('click', e => {\n        const act = e.target.closest('[data-act]')?.dataset.act;\n        if (act === 'ok' && okBtn()?.disabled) return;\n        if (act) finish(act === 'ok');\n      });\n      if (reasonLabel) {\n        wrap.addEventListener('input', () => { if (okBtn()) okBtn().disabled = !reasonText(); });\n      }\n      document.addEventListener('keydown', onKey, true);\n      // Placed inside the app container: the app's colours (--ims-surface\n      // and the rest, light and dark) are defined on it, not on the page,\n      // so a box attached to the page itself had no background at all.\n      (document.getElementById('ims-app') || document.body).appendChild(wrap);\n      if (reasonLabel && okBtn()) okBtn().disabled = true;\n      (reasonBox() || cancelBtn()).focus();\n    });\n  }\n\n  // \u2500\u2500\u2500 SAVE ORDER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // \u2500\u2500\u2500 AMEND ORDER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // A normal order can be amended (customer and delivery details, items,\n  // warehouse, notes) while it is Confirmed, Picking or Packed, or on a\n  // manifest whose van has not departed (\"Van departed\" in Logistics). It\n  // uses the New order form, prefilled, so every rule still applies: stock\n  // check, deals, price overrides, wholesale block, credit limit and who may\n  // add customers. Stock reservations move by the difference only.\n  let _amend = null;   // { order, items, manifest } while amending\n\n  async function _amendState(order) {\n    if (!order) return { ok: false, why: 'Order not found.' };\n    if (order.fulfillment_type === 'dropship') return { ok: false, why: 'Dropship orders are changed from the Dropship screen.' };\n    if (['confirmed', 'picking', 'packed'].includes(order.status)) return { ok: true };\n    if (order.status === 'dispatched') {\n      const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n      const { data: jobs } = await client.from('logistics_jobs')\n        .select('manifest_id,manifests(manifest_number,departed_at)').eq('order_id', order.id);\n      const onManifest = (jobs || []).find(j => j.manifest_id && j.manifests);\n      if (onManifest && !onManifest.manifests.departed_at) return { ok: true, manifest: onManifest.manifests.manifest_number };\n      return { ok: false, why: onManifest ? `The van for ${onManifest.manifests.manifest_number} has departed.` : 'It has already been sent.' };\n    }\n    return { ok: false, why: `It is ${order.status}.` };\n  }\n\n  // Did the lines change (product, quantity or price)?\n  function _itemsChanged(oldItems, newItems) {\n    const key = (pid, name, qty, price) => `${pid || ''}|${pid ? '' : String(name || '').toLowerCase()}|${Number(qty) || 0}|${(Number(price) || 0).toFixed(2)}`;\n    const a = (oldItems || []).map(i => key(i.product_id, i.product_name, i.quantity, i.unit_price)).sort().join(';');\n    const b = (newItems || []).map(i => key(i.productId, i.productName, i.qty || 1, i.unitPrice)).sort().join(';');\n    return a !== b;\n  }\n\n  // Plain-English list of what changed, for the activity log.\n  function _amendSummary(old, oldItems, newItems, fields) {\n    const lines = [];\n    const byKey = {};\n    (oldItems || []).forEach(i => { const k = i.product_id || `n:${i.product_name}`; byKey[k] = byKey[k] || { name: i.product_name, oldQty: 0, newQty: 0, oldPrice: i.unit_price, newPrice: null }; byKey[k].oldQty += (i.quantity || 0); });\n    (newItems || []).forEach(i => { const k = i.productId || `n:${i.productName}`; byKey[k] = byKey[k] || { name: i.productName, oldQty: 0, newQty: 0, oldPrice: null, newPrice: i.unitPrice }; byKey[k].newQty += (i.qty || 1); byKey[k].newPrice = i.unitPrice; });\n    Object.values(byKey).forEach(v => {\n      if (!v.oldQty) lines.push(`Added ${v.newQty} x ${v.name}`);\n      else if (!v.newQty) lines.push(`Removed ${v.oldQty} x ${v.name}`);\n      else {\n        if (v.oldQty !== v.newQty) lines.push(`${v.name}: ${v.oldQty} to ${v.newQty}`);\n        if (v.newPrice != null && v.oldPrice != null && Math.abs(v.newPrice - v.oldPrice) > 0.004) lines.push(`${v.name} price \u00A3${Number(v.oldPrice).toFixed(2)} to \u00A3${Number(v.newPrice).toFixed(2)}`);\n      }\n    });\n    const labels = { customer_name: 'Customer', address: 'Address', postcode: 'Postcode', phone: 'Phone', email: 'Email', external_ref: 'Reference', warehouse_id: 'Warehouse' };\n    Object.entries(labels).forEach(([k, label]) => { if ((old[k] || '') !== (fields[k] || '')) lines.push(`${label} changed`); });\n    if (Math.abs((old.total_value || 0) - (fields.total_value || 0)) > 0.004) lines.push(`Total \u00A3${Number(old.total_value || 0).toFixed(2)} to \u00A3${Number(fields.total_value || 0).toFixed(2)}`);\n    return lines.join('; ') || 'No changes';\n  }\n\n  async function amendOrder(orderId) {\n    const { data: order } = await db().select('orders', { eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true });\n    const st = await _amendState(order);\n    if (!st.ok) { ui().toast(`${order?.order_number || 'This order'} can no longer be amended. ${st.why}`, 'warning', 8000); return; }\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const { data: items } = await client.from('order_items').select('*').eq('order_id', orderId);\n\n    await showNewOrder(false);\n    const set = (id, v) => { const el = document.getElementById(id); if (el) el.value = v ?? ''; };\n    set('ims-no-platform', order.platform_id);\n    onPlatformChange();\n    await checkForDeals();                       // before the lines load, so it cannot re-price them\n    const typeSel = document.getElementById('ims-no-type-display');\n    if (typeSel && order.order_type) typeSel.value = order.order_type;\n    set('ims-no-warehouse', order.warehouse_id);\n    set('ims-no-postcode', order.postcode);\n    _checkDeliveryArea();\n    set('ims-no-custname', order.customer_name);\n    set('ims-no-address', order.address);\n    set('ims-no-phone', order.phone);\n    set('ims-no-email', order.email);\n    set('ims-no-extref', order.external_ref);\n    set('ims-no-notes', order.notes);\n    set('ims-no-orderdate', String(order.created_at || '').split('T')[0]);\n    set('ims-no-vat-treatment', order.vat_treatment || 'inclusive');\n    _pickedCustomerId = order.customer_id || null;\n    updateCustomerLock();\n\n    // Payment is handled from the order itself (Mark as paid, Refund), so\n    // the payment choice is set to the order's own and hidden.\n    const pay = document.querySelector(`input[name=\"ims-no-payment\"][value=\"${order.payment_status}\"]`);\n    if (pay) pay.checked = true;\n    const payGroup = document.getElementById('ims-no-payment-btns')?.closest('.ims__form-group');\n    if (payGroup) payGroup.innerHTML = `<label class=\"ims__label\">Payment</label><div style=\"font-size:13px\">${util().sanitize(order.payment_status || 'unpaid')}. Payments and refunds are recorded from the order itself.</div>`\n      + `<input type=\"radio\" name=\"ims-no-payment\" value=\"${util().sanitize(order.payment_status || 'unpaid')}\" checked style=\"display:none\">`;\n\n    _orderItems = (items || []).map(i => ({\n      productId: i.product_id || '', productName: i.product_name || '', sku: i.sku || '',\n      qty: i.quantity || 1, unitPrice: i.unit_price || 0, costPrice: i.cost_price || 0,\n      basePrice: i.standard_price ?? i.unit_price ?? 0, standardPrice: i.standard_price ?? null,\n      isOverride: !!i.price_overridden, overridePct: i.override_pct || 0,\n      dealApplied: false, keepPrice: true,\n      serviceId: i.service_id || null, per: i.service_id ? (_services.find(v => v.id === i.service_id)?.per || 'order') : undefined\n    }));\n    const reasonLine = (items || []).find(i => i.price_overridden && i.override_reason);\n    if (reasonLine) set('ims-no-override-reason', reasonLine.override_reason);\n    // Keep any order-level discount: the saved total is below the lines.\n    const linesTotal = _orderItems.reduce((t, i) => t + (i.qty || 1) * (i.unitPrice || 0), 0);\n    if (linesTotal - (order.total_value || 0) > 0.005) { set('ims-no-disc-type', 'fixed'); set('ims-no-disc-value', (linesTotal - order.total_value).toFixed(2)); }\n    renderItems();\n    updateTotal();\n\n    const titleEl = document.getElementById('ims-modal-title');\n    if (titleEl) titleEl.textContent = `Amend ${order.order_number}${st.manifest ? ` (on ${st.manifest})` : ''}`;\n    document.getElementById('ims-save-add-btn')?.remove();\n    const saveBtn = document.getElementById('ims-save-order-btn');\n    if (saveBtn) saveBtn.innerHTML = '<i class=\"ti ti-check\"></i> Save changes';\n    _amend = { order, items: items || [], manifest: st.manifest || null };\n  }\n\n  async function _saveAmendment(c) {\n    const old = _amend.order;\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    // Checked again: the van may have departed while the form was open.\n    const { data: fresh } = await db().select('orders', { eq: { id: old.id }, maybeSingle: true, noCompanyFilter: true });\n    const st = await _amendState(fresh);\n    if (!st.ok) { ui().toast(`${c.orderNumber} can no longer be amended. ${st.why} Nothing was changed.`, 'warning', 9000); c.restoreBtn(); return; }\n\n    // 1. New lines first. If they cannot be saved, nothing has changed yet.\n    const itemRows = _orderItems.map(item => ({\n      order_id: old.id, product_id: item.productId || null, service_id: item.serviceId || null, product_name: item.productName, sku: item.sku || '',\n      quantity: item.qty || 1, unit_price: item.unitPrice || 0, total_price: (item.qty || 1) * (item.unitPrice || 0),\n      cost_price: item.costPrice || 0, standard_price: item.standardPrice || null,\n      price_overridden: item.isOverride || false, override_reason: item.isOverride ? c.overrideReason : null,\n      override_pct: item.isOverride ? Math.round((item.overridePct || 0) * 100) / 100 : null\n    }));\n    const { data: newLines, error: insErr } = await client.from('order_items').insert(itemRows).select('id');\n    if (insErr) { ui().toast(`Changes not saved. The item lines could not be saved, so nothing was changed. Reason: ${insErr.message}`, 'error', 10000); c.restoreBtn(); return; }\n    // 2. Then the old lines go. If that fails, the new lines are taken out\n    //    again, so the order is exactly as it was.\n    const oldIds = _amend.items.map(i => i.id);\n    if (oldIds.length) {\n      const { error: delErr } = await client.from('order_items').delete().in('id', oldIds);\n      if (delErr) {\n        await client.from('order_items').delete().in('id', (newLines || []).map(r => r.id));\n        ui().toast(`Changes not saved. The old item lines could not be replaced, so nothing was changed. Reason: ${delErr.message}`, 'error', 10000);\n        c.restoreBtn(); return;\n      }\n    }\n    // 3. The order itself.\n    const fields = {\n      platform_id: c.platformId, order_type: c.orderType, customer_name: c.custName, customer_id: c.matchedCustomerId,\n      warehouse_id: c.warehouseId, postcode: c.postcode, address: c.address, phone: c.g('ims-no-phone'), email: c.g('ims-no-email'),\n      external_ref: c.g('ims-no-extref') || old.external_ref || null,   // an empty box keeps the order's existing reference\n      notes: [c.g('ims-no-notes'), ..._orderItems.flatMap(i => (i.pendingReleases || []).map(r =>\n        `Released ${r.qty} x ${i.productName} from ${r.partner} allocation to fulfil this order.`))].filter(Boolean).join(' | '),\n      total_value: c.total, has_price_override: c.hasAnyOverride, vat_treatment: c.vatTreatment,\n      deal_id: _activeDeal?.id || old.deal_id || null, deal_name_snapshot: _activeDeal?.name || old.deal_name_snapshot || null,\n      amended_at: new Date().toISOString()\n    };\n    // Money: a paid order that now costs more has more to collect; one that\n    // costs less needs a refund (done with Refund on the order, never here).\n    let payNote = '';\n    if (old.payment_status === 'paid' && c.total > (old.total_value || 0) + 0.005) {\n      fields.payment_status = 'partial';\n      payNote = ` \u00A3${(c.total - old.total_value).toFixed(2)} more to collect (payment now partial).`;\n    } else if (old.payment_status === 'paid' && c.total < (old.total_value || 0) - 0.005) {\n      payNote = ` \u00A3${(old.total_value - c.total).toFixed(2)} to refund: use Refund on the order.`;\n    }\n    const summary = _amendSummary(old, _amend.items, _orderItems, fields);\n    const { error: upErr } = await db().update('orders', old.id, fields);\n    if (upErr) ui().toast(`${c.orderNumber}: the items were changed, but the order details could not be saved (${upErr.message}). Please check the order.`, 'warning', 12000);\n\n    // 4. Allocation releases marked on new lines (same as a new order).\n    for (const item of _orderItems) {\n      for (const rel of (item.pendingReleases || [])) {\n        if (rel.warehouseId !== c.warehouseId) continue;\n        const { data: alloc } = await db().select('dropship_allocations', { select: 'allocated_qty,remaining_qty', eq: { id: rel.allocId }, maybeSingle: true, noCompanyFilter: true });\n        const actual = Math.min(rel.qty, alloc?.remaining_qty || 0);\n        if (actual <= 0) continue;\n        const { error: allocErr } = await db().update('dropship_allocations', rel.allocId, {\n          allocated_qty: Math.max(0, (alloc.allocated_qty || 0) - actual), remaining_qty: Math.max(0, (alloc.remaining_qty || 0) - actual)\n        });\n        if (allocErr) continue;\n        const { data: relSl } = await db().select('stock_levels', { eq: { product_id: rel.productId, warehouse_id: rel.warehouseId }, maybeSingle: true, noCompanyFilter: true });\n        if (relSl) await db().update('stock_levels', relSl.id, { reserved_by_allocations: Math.max(0, (relSl.reserved_by_allocations || 0) - actual) });\n        await logActivity(old.id, 'Released from allocation', '', '', `${actual} x ${item.productName} released from ${rel.partner} allocation`);\n      }\n    }\n\n    // 5. Reservations move by the difference only (or move warehouse),\n    //    one product at a time.\n    const oldQ = {}, newQ = {};\n    _amend.items.forEach(i => { if (i.product_id) oldQ[i.product_id] = (oldQ[i.product_id] || 0) + (i.quantity || 0); });\n    _orderItems.forEach(i => { if (i.productId) newQ[i.productId] = (newQ[i.productId] || 0) + (i.qty || 1); });\n    const moves = [];\n    if (old.warehouse_id !== c.warehouseId) {\n      Object.entries(oldQ).forEach(([p, q]) => moves.push([p, old.warehouse_id, -q]));\n      Object.entries(newQ).forEach(([p, q]) => moves.push([p, c.warehouseId, q]));\n    } else {\n      new Set([...Object.keys(oldQ), ...Object.keys(newQ)]).forEach(p => { const d = (newQ[p] || 0) - (oldQ[p] || 0); if (d) moves.push([p, c.warehouseId, d]); });\n    }\n    const reserveFailed = [];\n    for (const [p, wh, d] of moves) {\n      if (!wh) continue;\n      const { data: sl } = await db().select('stock_levels', { eq: { product_id: p, warehouse_id: wh }, maybeSingle: true, noCompanyFilter: true });\n      if (!sl) { if (d > 0) reserveFailed.push(p); continue; }\n      const { error } = await db().update('stock_levels', sl.id, { reserved_qty: Math.max(0, (sl.reserved_qty || 0) + d) });\n      if (error) reserveFailed.push(p);\n    }\n\n    await logActivity(old.id, 'Order amended', old.status, old.status, summary);\n\n    // 6. Reminders.\n    const notes = [];\n    if (payNote) notes.push(payNote.trim());\n    if (st.manifest) notes.push(`It is on ${st.manifest}: reprint the manifest for the driver.`);\n    else if (['picking', 'packed'].includes(old.status)) notes.push('It was already being picked or packed: tell the warehouse.');\n    const { data: ship } = await client.from('shipments').select('id').eq('order_id', old.id).eq('is_return_collection', false).limit(1);\n    if (ship?.length) notes.push('A courier label exists: update it with the courier.');\n    if (reserveFailed.length) notes.push('Some stock reservations could not be updated: please check stock levels.');\n\n    _amend = null;\n    _orderItems = [];\n    ui().closeModal();\n    ui().toast(`${c.orderNumber} amended. ${summary}.${notes.length ? ' ' + notes.join(' ') : ''}`, notes.length ? 'warning' : 'success', notes.length ? 12000 : 6000);\n    load();\n  }\n\n  async function saveOrder(btn, addAnother=false) {\n    const saveBtn = btn || document.getElementById(addAnother?'ims-save-add-btn':'ims-save-order-btn');\n    if(saveBtn){ saveBtn.disabled=true; saveBtn.innerHTML=`<i class=\"ti ti-loader-2 ims__spin\"></i> Saving...`; }\n    const restoreBtn=()=>{ if(saveBtn && _amend){ saveBtn.disabled=false; saveBtn.innerHTML='<i class=\"ti ti-check\"></i> Save changes'; return; } if(saveBtn){ saveBtn.disabled=false; saveBtn.innerHTML=addAnother?'<i class=\"ti ti-plus\"></i> Save &amp; add new':'<i class=\"ti ti-check\"></i> '+((_batchOrders.length>0)?'Save &amp; exit':'Create order'); } };\n    const g = id => document.getElementById(id)?.value?.trim() || '';\n    const postcode   = g('ims-no-postcode').toUpperCase().replace(/\\s+/g,' ');\n    const platformId = g('ims-no-platform');\n    const custName   = g('ims-no-custname');\n    const address    = g('ims-no-address');\n    const orderDate  = g('ims-no-orderdate');\n    const warehouseId = g('ims-no-warehouse');\n\n    if (!postcode)   { ui().toast('Postcode is required', 'error'); restoreBtn(); return; }\n    // A marketplace order (Amazon, eBay, Temu, B&Q...) must carry the\n    // marketplace's own order number, so it can be matched with the\n    // marketplace later. (Left empty, StockMaestro used to put its own\n    // order number there instead.)\n    {\n      const platName = (document.getElementById('ims-no-platform')?.selectedOptions?.[0]?.textContent || '').trim().toLowerCase();\n      const isMarketplace = (window.SM.EMAIL?.EXCLUDED_PLATFORMS || []).includes(platName);\n      const extRefVal = g('ims-no-extref');\n      if (isMarketplace && (!extRefVal || (_amend && extRefVal === _amend.order.order_number))) {\n        ui().toast(`Please enter the ${document.getElementById('ims-no-platform')?.selectedOptions?.[0]?.textContent?.trim() || 'marketplace'} order number in External reference.`, 'error', 7000);\n        document.getElementById('ims-no-extref')?.focus();\n        restoreBtn(); return;\n      }\n    }\n    if (!orderDate)  { ui().toast('Order date is required', 'error'); restoreBtn(); return; }\n    if (!warehouseId) { ui().toast('Please select a fulfilling warehouse', 'error'); restoreBtn(); return; }\n    if (!platformId) { ui().toast('Please select a platform', 'error'); restoreBtn(); return; }\n    if (!custName)   { ui().toast('Customer name is required', 'error'); restoreBtn(); return; }\n    if (!address)    { ui().toast('Delivery address is required', 'error'); restoreBtn(); return; }\n    if (!_orderItems.length) { ui().toast('Please add at least one item', 'error'); restoreBtn(); return; }\n\n    const emptyItems = _orderItems.filter(i => !i.productName);\n    if (emptyItems.length) { ui().toast('All items must have a product name', 'error'); restoreBtn(); return; }\n\n    const orderType = document.getElementById('ims-no-type-display')?.value || 'retail';\n    const vatTreatment = document.getElementById('ims-no-vat-treatment')?.value || 'inclusive';\n    const subtotal  = _orderItems.reduce((s, i) => s + ((i.qty||1) * (i.unitPrice||0)), 0);\n    const discType  = document.getElementById('ims-no-disc-type')?.value || 'none';\n    const discVal   = parseFloat(document.getElementById('ims-no-disc-value')?.value) || 0;\n    let discAmt = 0;\n    if(discType === 'pct' && discVal > 0)   discAmt = subtotal * (discVal / 100);\n    if(discType === 'fixed' && discVal > 0) discAmt = Math.min(discVal, subtotal);\n    const total = Math.max(0, subtotal - discAmt);\n\n    // Filter to ORD- prefixed orders only \u2014 'orders' also holds DSO- (dropship)\n    // and other-prefixed rows, so an unfiltered \"most recent\" lookup can pick\n    // up the wrong prefix and generate a number that collides with an\n    // existing ORD- order.\n    let orderNumber;\n    if (_amend) {\n      orderNumber = _amend.order.order_number;   // amending: the order keeps its number\n      // An order with a sales invoice keeps its items as invoiced (customer\n      // and delivery details can still change). Otherwise the invoice\n      // already sent would silently differ from the order.\n      if (_amend.order.invoice_id && _itemsChanged(_amend.items, _orderItems)) {\n        await _askOverForm({\n          title: 'Items are invoiced',\n          message: `${util().sanitize(orderNumber)} already has a sales invoice, so its items cannot be changed here. Credit or cancel the invoice in Accounts first. Customer and delivery details can still be changed.`,\n          okLabel: null\n        });\n        restoreBtn(); return;\n      }\n    } else {\n      const { data: lastOrder } = await db().select('orders', {\n        select: 'order_number', ilike: { order_number: 'ORD-' }, order: { col: 'order_number', asc: false }, limit: 1\n      });\n      orderNumber = util().generateRef('ORD', lastOrder?.[0]?.order_number);\n    }\n\n    // Link this order to an existing customer record if one matches by phone \u2014\n    // needed for customer order history/counts and (for wholesale) AR automation.\n    let matchedCustomerId = null;\n    // An explicitly picked customer always wins over phone-matching, which\n    // is only a best-effort fallback for orders typed in without using the\n    // postcode lookup.\n    let cust = null;\n    if (_pickedCustomerId) {\n      const { data: picked } = await db().select('customers', {\n        eq: { id: _pickedCustomerId }, maybeSingle: true\n      });\n      cust = picked || null;\n    }\n    const phoneForLookup = g('ims-no-phone');\n    if (!cust && phoneForLookup) {\n      const { data: byPhone } = await db().select('customers', {\n        eq: { phone: phoneForLookup.trim(), is_active: true }, maybeSingle: true   // deactivated customers are not matched\n      });\n      cust = byPhone || null;\n    }\n    if (true) {\n      if (cust) {\n        matchedCustomerId = cust.id;\n        if (orderType === 'wholesale' && cust.credit_limit > 0) {\n          const { data: recs } = await db().select('accounts_receivable', {\n            eq: { customer_id: cust.id, status: 'unpaid' }\n          });\n          const outstanding = (recs||[]).reduce((s,r) => s + ((r.amount||0)-(r.paid_amount||0)), 0);\n          const remaining = cust.credit_limit - outstanding;\n          if (total > remaining) {\n            const proceed = await _askOverForm({\n              title: 'Credit limit warning',\n              message: `Customer: <strong>${util().sanitize(cust.business_name)}</strong><br>Credit limit: \u00A3${cust.credit_limit.toFixed(2)}<br>Outstanding: \u00A3${outstanding.toFixed(2)}<br>This order: \u00A3${total.toFixed(2)}<br>Over limit by: <strong>\u00A3${(total - remaining).toFixed(2)}</strong>`,\n              okLabel: 'Save anyway'\n            });\n            if (!proceed) { restoreBtn(); return; }\n          }\n        }\n      }\n    }\n\n    // A wholesale order with no linked customer can never produce a\n    // receivable on delivery, so it would be permanently stuck as unpaid\n    // with no way to clear it. Only relevant if anything is actually\n    // going to be owed \u2014 a walk-in customer paying cash/card in full on\n    // the spot has nothing outstanding, so no receivable is needed and\n    // this warning would just be noise for that case.\n    const paymentStatusCheck = document.querySelector('input[name=\"ims-no-payment\"]:checked')?.value || 'unpaid';\n    // This is a hard block, not a warning. Saved anyway, the order would\n    // get no receivable on delivery (every delivery path needs a linked\n    // customer), so the money owed would never appear in Accounts, and it\n    // could not be marked paid either (\"Mark as paid\" is retail only).\n    // The only way out was a Super Admin linking a customer afterwards.\n    if (orderType === 'wholesale' && !matchedCustomerId && paymentStatusCheck !== 'paid') {\n      await _askOverForm({\n        title: 'Link a registered customer first',\n        message: 'A wholesale order that is not paid in full must be linked to a registered customer. Otherwise nothing owed is recorded in Accounts when it is delivered, and the payment cannot be recorded.<br><br>To continue, either:<br>&bull; search the customer by <strong>postcode</strong> and select them, or<br>' +\n          (_canAddCustomers()\n            ? '&bull; if they are new, add them with <strong>+ New customer</strong> in the postcode search, or<br>'\n            : '&bull; if they are new, <strong>ask an Admin</strong> to add them, or<br>') +\n          '&bull; if they have paid in full now, set payment to <strong>Paid</strong>.',\n        okLabel: null\n      });\n      restoreBtn();\n      return;\n    }\n\n    const hasAnyOverride = _orderItems.some(i => i.isOverride);\n    const overrideReason = document.getElementById('ims-no-override-reason')?.value?.trim() || null;\n    if (hasAnyOverride && !overrideReason) { ui().toast('Please enter a reason for the price override', 'error'); restoreBtn(); return; }\n\n    // Stock check. Before saving, warn if any product on this order needs\n    // more than is free in the chosen warehouse: on hand, minus reserved,\n    // minus what is held for dropship partners (after any releases marked\n    // on this order). Not a hard block, because staff sometimes sell ahead\n    // of an incoming delivery on purpose, but it can no longer happen by\n    // accident. Before this, an order could quietly over-promise stock,\n    // including units held for a partner.\n    const needByProduct = {};\n    _orderItems.forEach(i => {\n      if (!i.productId) return;\n      if (!needByProduct[i.productId]) needByProduct[i.productId] = { name: i.productName, qty: 0 };\n      needByProduct[i.productId].qty += (i.qty || 1);\n    });\n    const shortLines = [];\n    let anyHeld = false;\n    for (const [productId, need] of Object.entries(needByProduct)) {\n      const { data: sl } = await db().select('stock_levels', {\n        eq: { product_id: productId, warehouse_id: warehouseId }, maybeSingle: true, noCompanyFilter: true\n      });\n      const held = Math.max(0, (sl?.reserved_by_allocations || 0) - _pendingReleaseQty(productId, warehouseId));\n      // When amending, this order's own existing reservation (same\n      // warehouse) is already inside \"reserved\", so it counts as free for\n      // this order: only the extra units need to be available.\n      const ownHeld = (_amend && _amend.order.warehouse_id === warehouseId)\n        ? _amend.items.filter(i => i.product_id === productId).reduce((t, i) => t + (i.quantity || 0), 0) : 0;\n      const free = (sl?.quantity || 0) - (sl?.reserved_qty || 0) - held + ownHeld;\n      if (need.qty <= free) continue;\n      let heldText = '';\n      if (held > 0) {\n        anyHeld = true;\n        // DB.select has no \"greater than\" filter, so empty allocations are\n        // dropped here instead.\n        const { data: holders } = await db().select('dropship_allocations', {\n          select: 'remaining_qty,dropship_customers(business_name)',\n          eq: { product_id: productId, warehouse_id: warehouseId }, noCompanyFilter: true\n        });\n        const names = [...new Set((holders || []).filter(h => (h.remaining_qty || 0) > 0)\n          .map(h => h.dropship_customers?.business_name).filter(Boolean))];\n        heldText = ` (${held} held for ${names.length ? names.join(', ') : 'dropship partners'})`;\n      }\n      shortLines.push(`${need.name}: needs ${need.qty}, ${Math.max(0, free)} available${heldText}`);\n    }\n    if (shortLines.length) {\n      const proceed = await _askOverForm({\n        title: 'Not enough stock',\n        message: shortLines.map(l => util().sanitize(l)).join('<br>') +\n          (anyHeld ? '<br><br>To use stock held for a partner, choose <strong>Go back</strong> and use <strong>Release from allocation</strong> on that line.' : ''),\n        okLabel: 'Save anyway'\n      });\n      if (!proceed) { restoreBtn(); return; }\n    }\n\n    // Duplicate detection. A duplicate is the same customer (the linked\n    // account, or the same name AND postcode) with the same products and\n    // quantities, created in the last 30 minutes (cancelled orders ignored).\n    // It used to be the same name and the same total within 60 seconds, so\n    // a real duplicate a minute later, or with a typo, slipped through,\n    // while a different order of the same value was flagged.\n    // \"Create anyway\" needs a written reason, kept in the activity log.\n    const thirtyMinsAgo = new Date(Date.now() - 30 * 60000).toISOString();\n    const { data: recentOrders } = _amend ? { data: [] } : await db().select('orders', {   // not when amending: it is the same order\n      select: 'id,order_number,customer_id,customer_name,postcode,status,order_items(product_id,product_name,quantity)',\n      gte: { created_at: thirtyMinsAgo },\n      order: { col: 'created_at', asc: false },\n      limit: 50\n    });\n    const normText = v => String(v || '').toLowerCase().replace(/\\s+/g, ' ').trim();\n    const normPc   = v => String(v || '').toUpperCase().replace(/\\s+/g, '');\n    const basket = lines => {\n      const m = {};\n      lines.forEach(l => {\n        const k = l.pid ? `p:${l.pid}` : `n:${normText(l.name)}`;\n        m[k] = (m[k] || 0) + (Number(l.qty) || 0);\n      });\n      return JSON.stringify(Object.keys(m).sort().map(k => [k, m[k]]));\n    };\n    const thisBasket = basket(_orderItems.map(i => ({ pid: i.productId, name: i.productName, qty: i.qty || 1 })));\n    const duplicateOf = (recentOrders || []).find(o => {\n      if (o.status === 'cancelled') return false;\n      const sameCustomer = (matchedCustomerId && o.customer_id === matchedCustomerId)\n        || (normText(o.customer_name) === normText(custName) && normPc(o.postcode) === normPc(postcode));\n      if (!sameCustomer) return false;\n      return basket((o.order_items || []).map(i => ({ pid: i.product_id, name: i.product_name, qty: i.quantity }))) === thisBasket;\n    });\n    let duplicateReason = null;\n    if (duplicateOf) {\n      const reason = await _askOverForm({\n        title: 'Possible duplicate order',\n        message: `<strong>${util().sanitize(duplicateOf.order_number)}</strong> was created in the last 30 minutes for <strong>${util().sanitize(custName)}</strong> with the same products and quantities. If this is a genuine separate order, say why.`,\n        okLabel: 'Create anyway',\n        danger: true,\n        reasonLabel: 'Reason this is not a duplicate (required)'\n      });\n      if (!reason) { restoreBtn(); return; }\n      duplicateReason = `${reason} (similar to ${duplicateOf.order_number})`;\n    }\n\n    if (_amend) { await _saveAmendment({ saveBtn, restoreBtn, g, orderNumber, custName, matchedCustomerId, warehouseId, platformId,\n      orderType, vatTreatment, postcode, address, total, hasAnyOverride, overrideReason }); return; }\n\n    const paymentStatus = document.querySelector('input[name=\"ims-no-payment\"]:checked')?.value || 'unpaid';\n    const unpaidExpiresAt = paymentStatus === 'unpaid'\n      ? new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()\n      : null;\n\n    const now = new Date();\n    const orderDateTime = new Date(`${orderDate}T${now.toTimeString().split(' ')[0]}`);\n\n    let order, error;\n    for (let attempt = 0; attempt < 3; attempt++) {\n      const result = await db().insert('orders', {\n        order_number:       orderNumber,\n        platform_id:        platformId,\n        order_type:         orderType,\n        fulfillment_type:   'retail',\n        customer_name:      custName,\n        customer_id:        matchedCustomerId,\n        warehouse_id:       warehouseId,\n        postcode,\n        address,\n        phone:              g('ims-no-phone'),\n        email:              g('ims-no-email'),\n        external_ref:       g('ims-no-extref') || orderNumber,\n        // Staff notes, plus a line for each allocation release marked on this order.\n        notes:              [g('ims-no-notes'), ..._orderItems.flatMap(i => (i.pendingReleases || []).map(r =>\n                              `Released ${r.qty} x ${i.productName} from ${r.partner} allocation to fulfil this order.`))]\n                              .filter(Boolean).join(' | '),\n        status:             'confirmed',\n        created_at:         orderDateTime.toISOString(),\n        payment_status:     paymentStatus,\n        unpaid_expires_at:  unpaidExpiresAt,\n        total_value:        total,\n        has_price_override: hasAnyOverride,\n        vat_treatment:      vatTreatment,\n        deal_id:            _activeDeal?.id || null,\n        deal_name_snapshot: _activeDeal?.name || null,\n        deal_discount_applied: _orderItems.some(i => i.dealApplied) ? 1 : 0,\n        created_by:         window.SM.AUTH.user?.id\n      });\n      order = result.data;\n      error = result.error;\n      if (!error) break;\n      const isDupe = error.code === '23505' || /duplicate key/i.test(error.message||'');\n      if (!isDupe) break;\n      // Order number collided \u2014 bump past it and retry\n      orderNumber = util().generateRef('ORD', orderNumber);\n    }\n\n    if (error) { ui().toast('Failed to create order: ' + error.message, 'error'); restoreBtn(); return; }\n    // Save every item line in ONE insert. Postgres runs a multi-row insert\n    // as a single statement, so either every line saves or none do. Before\n    // this, each line was saved on its own and the result was never\n    // checked, so a failed line vanished while the order still showed as\n    // saved. order_items has no company_id column, so the raw client is used.\n    const _itemsClient = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const itemRows = _orderItems.map(item => ({\n      order_id:         order.id,\n      product_id:       item.productId || null,\n      service_id:       item.serviceId || null,\n      product_name:     item.productName,\n      sku:              item.sku || '',\n      quantity:         item.qty || 1,\n      unit_price:       item.unitPrice || 0,\n      total_price:      (item.qty||1) * (item.unitPrice||0),\n      cost_price:       item.costPrice || 0,\n      standard_price:   item.standardPrice || null,\n      price_overridden: item.isOverride || false,\n      override_reason:  item.isOverride ? overrideReason : null,\n      override_pct:     item.isOverride ? Math.round((item.overridePct || 0) * 100) / 100 : null\n    }));\n    const { error: itemsError } = await _itemsClient.from('order_items').insert(itemRows);\n    if (itemsError) {\n      // Undo the half-saved order. At this point no stock has been reserved,\n      // no activity has been logged and nothing else points at the order,\n      // so removing the order row is the whole undo.\n      const { error: undoError } = await db().remove('orders', order.id);\n      if (undoError) {\n        ui().toast(`Order ${orderNumber} was created but its items could not be saved, and it could not be removed automatically. Please cancel ${orderNumber} and enter it again. Reason: ${itemsError.message}`, 'error', 15000);\n        load();\n      } else {\n        ui().toast(`Order not saved. The item lines could not be saved, so nothing was recorded. Please try again. Reason: ${itemsError.message}`, 'error', 10000);\n      }\n      restoreBtn();\n      return;\n    }\n    await logActivity(order.id, 'Order created', '', 'confirmed', `Customer: ${custName}, Value: \u00A3${total.toFixed(2)}`);\n    if (duplicateReason) await logActivity(order.id, 'Duplicate warning overridden', '', 'confirmed', duplicateReason);\n\n    // Carry out any \"release from allocation\" marked on this order. This\n    // runs only now, once the order and its items have saved, so an order\n    // that is abandoned or fails to save never takes stock from a partner.\n    // The allocation shrinks (Allocated AND Remaining), so the partner's\n    // \"Sold\" figure (Allocated minus Remaining) stays true: released units\n    // were not sold to them.\n    const releaseProblems = [];\n    for (const item of _orderItems) {\n      for (const rel of (item.pendingReleases || [])) {\n        if (rel.warehouseId !== warehouseId) continue;\n        const { data: alloc } = await db().select('dropship_allocations', {\n          select: 'allocated_qty,remaining_qty', eq: { id: rel.allocId }, maybeSingle: true, noCompanyFilter: true\n        });\n        const actual = Math.min(rel.qty, alloc?.remaining_qty || 0);\n        if (actual <= 0) { releaseProblems.push(`${item.productName}: nothing left to release from ${rel.partner}`); continue; }\n        const { error: allocErr } = await db().update('dropship_allocations', rel.allocId, {\n          allocated_qty: Math.max(0, (alloc.allocated_qty || 0) - actual),\n          remaining_qty: Math.max(0, (alloc.remaining_qty || 0) - actual)\n        });\n        if (allocErr) { releaseProblems.push(`${item.productName}: release from ${rel.partner} failed`); continue; }\n        const { data: relSl } = await db().select('stock_levels', {\n          eq: { product_id: rel.productId, warehouse_id: rel.warehouseId }, maybeSingle: true, noCompanyFilter: true\n        });\n        if (relSl) {\n          await db().update('stock_levels', relSl.id, {\n            reserved_by_allocations: Math.max(0, (relSl.reserved_by_allocations || 0) - actual)\n          });\n        }\n        await logActivity(order.id, 'Released from allocation', '', '', `${actual} x ${item.productName} released from ${rel.partner} allocation`);\n        if (actual < rel.qty) releaseProblems.push(`${item.productName}: only ${actual} of ${rel.qty} released from ${rel.partner}`);\n      }\n    }\n    if (releaseProblems.length) {\n      ui().toast(`Order ${orderNumber} saved, but some allocation releases did not go through in full: ${releaseProblems.join('; ')}. Please check stock for these products.`, 'warning', 15000);\n    }\n\n    // Reserve stock one line at a time. Doing every line at once meant two\n    // lines of the same product both read the same starting figure, so one\n    // reservation was lost. Failures are now reported instead of ignored.\n    const reserveFailed = [];\n    for (const item of _orderItems) {\n      if (!item.productId) continue;\n      const { data: sl, error: slError } = await db().select('stock_levels', {\n        eq: { product_id: item.productId, warehouse_id: warehouseId }, maybeSingle: true, noCompanyFilter: true\n      });\n      if (slError) { reserveFailed.push(item.productName); continue; }\n      if (sl) {\n        const { error: reserveError } = await db().update('stock_levels', sl.id, {\n          reserved_qty: (sl.reserved_qty || 0) + (item.qty || 1)\n        });\n        if (reserveError) reserveFailed.push(item.productName);\n      }\n    }\n    if (reserveFailed.length) {\n      await logActivity(order.id, 'Stock reservation failed', '', '', `Not reserved: ${reserveFailed.join(', ')}`);\n      ui().toast(`Order ${orderNumber} saved, but stock could not be reserved for: ${reserveFailed.join(', ')}. Please check stock levels.`, 'warning', 12000);\n    }\n\n    \n\n    await db().upsert('order_postcode_history', {\n      company_id:    window.SM.AUTH.company?.id,\n      postcode,\n      customer_name: custName,\n      address,\n      phone:         g('ims-no-phone'),\n      email:         g('ims-no-email'),\n      order_count:   1,\n      last_used:     new Date().toISOString()\n    }, 'company_id,postcode,customer_name');\n\n    _orderItems = [];\n\n    // Batch mode handling\n    _batchOrders.push({ id: order.id, orderNumber, customerName: custName, total, paymentStatus });\n\n    if (addAnother) {\n      // Save and open fresh form for next order\n      ui().toast(`${orderNumber} saved \u2014 add next order`, 'success', 3000);\n      showNewOrder(true);\n    } else {\n      // Save and exit \u2014 if batch has multiple orders, show payment review\n      if (_batchOrders.length > 1) {\n        ui().closeModal();\n        showBatchPaymentReview();\n      } else {\n        // Single order \u2014 done\n        ui().closeModal();\n        ui().toast(`Order ${orderNumber} created successfully`, 'success');\n        window.SM.EMAIL.send(order.id, 'confirmed');\n        _batchOrders = [];\n        _batchId = null;\n        _activeDeal = null;\n        _matchedCustomer = null;\n        load();\n      }\n    }\n  }\n\n  function cancelBatch() {\n    _batchOrders = [];\n    _batchId = null;\n    _orderItems = [];\n    _activeDeal = null;\n    _matchedCustomer = null;\n    ui().closeModal();\n  }\n\n  async function showBatchPaymentReview() {\n    // Generate batch number\n    const { data: lastBatch } = await db().select('order_batches', {\n      select: 'batch_number', order: { col: 'created_at', asc: false }, limit: 1\n    });\n    const batchNumber = util().generateRef('BTH', lastBatch?.[0]?.batch_number);\n\n    // Create batch record\n    const { data: batch } = await db().insert('order_batches', {\n      batch_number: batchNumber,\n      company_id:   window.SM.AUTH.company?.id,\n      created_by:   window.SM.AUTH.user?.id,\n      status:       'open'\n    });\n\n    // Link all orders in batch\n    if (batch) {\n      _batchId = batch.id;\n      await Promise.all(_batchOrders.map(o =>\n        db().update('orders', o.id, { batch_id: batch.id })\n      ));\n    }\n\n    const rows = _batchOrders.map((o,i) => `\n      <tr>\n        <td style=\"font-weight:600\">${util().sanitize(o.orderNumber)}</td>\n        <td>${util().sanitize(o.customerName)}</td>\n        <td>${util().formatCurrency(o.total)}</td>\n        <td>\n          <div style=\"display:flex;gap:6px\">\n            <label style=\"display:flex;align-items:center;gap:4px;cursor:pointer;padding:4px 10px;border:1.5px solid var(--ims-border);border-radius:var(--ims-radius);font-size:12px\">\n              <input type=\"radio\" name=\"pay-${i}\" value=\"paid\" style=\"accent-color:var(--ims-success)\" ${o.paymentStatus==='paid'?'checked':''}>\n              <span style=\"color:var(--ims-success)\">Paid</span>\n            </label>\n            <label style=\"display:flex;align-items:center;gap:4px;cursor:pointer;padding:4px 10px;border:1.5px solid var(--ims-border);border-radius:var(--ims-radius);font-size:12px\">\n              <input type=\"radio\" name=\"pay-${i}\" value=\"cod\" style=\"accent-color:var(--ims-accent)\" ${o.paymentStatus==='cod'?'checked':''}>\n              <span style=\"color:var(--ims-accent)\">COD</span>\n            </label>\n            <label style=\"display:flex;align-items:center;gap:4px;cursor:pointer;padding:4px 10px;border:1.5px solid var(--ims-border);border-radius:var(--ims-radius);font-size:12px\">\n              <input type=\"radio\" name=\"pay-${i}\" value=\"unpaid\" style=\"accent-color:var(--ims-danger)\" ${o.paymentStatus==='unpaid'?'checked':''}>\n              <span style=\"color:var(--ims-danger)\">Unpaid</span>\n            </label>\n          </div>\n        </td>\n      </tr>`).join('');\n\n    ui().openModal(`Batch ${batchNumber} \u2014 confirm payment status`, `\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:14px\">\n        <i class=\"ti ti-info-circle\"></i>\n        <span><strong>${_batchOrders.length} orders</strong> saved in batch <strong>${batchNumber}</strong>. Confirm payment status for each order. Paid and COD orders will be available for processing. Unpaid orders will be held for 7 days.</span>\n      </div>\n      <table class=\"ims__table\">\n        <thead><tr><th>Order #</th><th>Customer</th><th>Value</th><th>Payment status</th></tr></thead>\n        <tbody>${rows}</tbody>\n      </table>\n    `, `\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_ORDERS.confirmBatchPayment()\">\n        <i class=\"ti ti-check\"></i> Confirm &amp; process batch\n      </button>\n    `, 'lg');\n  }\n\n  async function confirmBatchPayment() {\n    const updates = _batchOrders.map((o, i) => {\n      const paymentStatus = document.querySelector(`input[name=\"pay-${i}\"]:checked`)?.value || o.paymentStatus;\n      const unpaidExpiresAt = paymentStatus === 'unpaid'\n        ? new Date(Date.now() + 7*24*60*60*1000).toISOString() : null;\n      return { id: o.id, paymentStatus, unpaidExpiresAt };\n    });\n\n    await Promise.all(updates.map(u =>\n      db().update('orders', u.id, {\n        payment_status:    u.paymentStatus,\n        unpaid_expires_at: u.unpaidExpiresAt\n      })\n    ));\n\n    const paid   = updates.filter(u=>u.paymentStatus==='paid').length;\n    const cod    = updates.filter(u=>u.paymentStatus==='cod').length;\n    const unpaid = updates.filter(u=>u.paymentStatus==='unpaid').length;\n\n    // Update batch status\n    if (_batchId) await db().update('order_batches', _batchId, { status: 'processed' });\n\n    ui().closeModal();\n    ui().toast(\n      `Batch processed \u2014 ${paid} paid, ${cod} COD, ${unpaid} unpaid (7-day hold)`,\n      'success', 5000\n    );\n\n    _batchOrders = [];\n    _batchId = null;\n    load();\n  }\n\n\n  // \u2500\u2500\u2500 ORDER DETAIL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // \u2500\u2500\u2500 ORDER DETAIL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  async function openOrder(id) {\n    const { data: order, error } = await db().select('orders', {\n      select: '*, platforms(name), order_items(*), dropship_customers(business_name), shipments(tracking_number, courier_order_ref, is_return_collection, couriers(name,tracking_url_base,requires_postcode,postcode_param,tracking_form_only)), logistics_jobs(id,job_type,status)',\n      eq: { id }, maybeSingle: true, noCompanyFilter: true\n    });\n    if (error || !order) { ui().toast('Order not found', 'error'); return; }\n    // Website (Shopify) orders: the last update sent to Shopify, from\n    // shopify_sync_log. Same rule as the shopify-sync Edge Function.\n    const _isShopifyOrder = order.fulfillment_type !== 'dropship' && !!(order.source_order_id ||\n      (/website|own store/i.test(order.platforms?.name || '') && /^#\\d+$/.test(String(order.external_ref || '').trim())));\n    let _shopLast = null;\n    if (_isShopifyOrder) {\n      const { data: _sl } = await window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY)\n        .from('shopify_sync_log').select('action,status,detail,created_at,created_by_name')\n        .eq('order_id', order.id).order('created_at', { ascending: false }).limit(1);\n      _shopLast = _sl?.[0] || null;\n    }\n    // Commission only shown to cost-authorised roles \u2014 it reveals margin.\n    let _comm = { hasCommission: false };\n    if (window.SM.AUTH.canSeeCost?.() && order.platform_id) {\n      const rates = await util().getCommissionRates();\n      _comm = util().calcCommission(order.total_value, rates[order.platform_id]);\n    }\n    const isDropship = order.fulfillment_type === 'dropship';\n    const isDelayed  = !isDropship && util().isDelayed(order);\n    const shipment   = (order.shipments||[]).find(x=>!x.is_return_collection);   // the delivery (not a return collection)\n    const trackUrl   = shipment ? util().buildTrackingUrl(shipment.couriers, shipment.tracking_number, order.postcode) : null;\n    const TERMINAL   = ['delivered','cancelled','refunded'];\n    const isTerminal = TERMINAL.includes(order.status);\n    const isReturnable = order.status === 'delivered';\n    const isReturnInProgress = ['return_requested','return_received'].includes(order.status);\n    const STATUS_SEQUENCE = ['confirmed', 'picking', 'packed'];\n    const STATUS_LABELS    = { picking: 'Picking', packed: 'Packed' };\n    const canCancelHere    = ['confirmed', 'picking', 'packed'].includes(order.status);\n    const seqIdx           = STATUS_SEQUENCE.indexOf(order.status);\n    const nextSteps        = seqIdx >= 0 ? STATUS_SEQUENCE.slice(seqIdx + 1) : [];\n\n    // Who created the order: the name recorded at that moment (activity\n    // log), plus the account's current name if it has changed since (an\n    // account handed over to someone else keeps its history correct).\n    const _who = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const _svcTag = i => !i.service_id ? '' : ` <span class=\"ims__pill ims__pill--info\" style=\"font-size:10px\">Service</span>${i.service_status === 'done' ? ` <span class=\"ims__pill ims__pill--success\" style=\"font-size:10px\">Done</span>${i.service_cost != null ? ` <span style=\"font-size:11px;color:var(--ims-text-muted)\">own-van cost ${util().formatCurrency(i.service_cost)} &middot; margin ${util().formatCurrency((Number(i.unit_price) || 0) * (Number(i.quantity) || 1) - Number(i.service_cost))}</span>` : ''}` : i.service_status === 'not_done' ? ' <span class=\"ims__pill ims__pill--danger\" style=\"font-size:10px\">Not done: refund if paid</span>' : ''}`;\n    const { data: createdLog } = await _who.from('order_activity_log').select('user_name,created_at')\n      .eq('order_id', order.id).eq('action', 'Order created').order('created_at', { ascending: true }).limit(1);\n    let creatorNow = null;\n    if (order.created_by) {\n      const { data: cu } = await _who.from('users').select('name').eq('id', order.created_by).maybeSingle();\n      creatorNow = cu?.name || null;\n    }\n    const createdName = createdLog?.[0]?.user_name || creatorNow;\n    const createdLine = createdName\n      ? `${util().sanitize(createdName)}${creatorNow && creatorNow !== createdName ? ` <span style=\"color:var(--ims-text-muted)\">(account now: ${util().sanitize(creatorNow)})</span>` : ''}<div style=\"font-size:11px;color:var(--ims-text-muted)\">${util().formatDateTime(createdLog?.[0]?.created_at || order.created_at)}</div>`\n      : '-';\n\n    const html = `\n      <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:16px\">\n        <div><span class=\"ims__label\">Order number</span><div style=\"font-weight:700;font-size:16px\">${util().sanitize(order.order_number)}</div></div>\n        <div><span class=\"ims__label\">Status</span><div style=\"display:flex;gap:8px;align-items:center\">\n          ${util().pill(isDelayed?'delayed':order.status)}\n          ${order.payment_status&&order.order_type!=='wholesale'?util().pill(order.payment_status):''}\n        </div></div>\n        <div><span class=\"ims__label\">Customer</span><div>${util().sanitize(order.customer_name||'\u2014')}</div></div>\n        <div><span class=\"ims__label\">Platform</span><div>${util().sanitize(order.platforms?.name||'-')}</div></div>\n        <div><span class=\"ims__label\">Created by</span><div>${createdLine}</div></div>\n        <div><span class=\"ims__label\">Order type</span><div>${\n          isDropship ? `<span class=\"ims__pill ims__pill--accent\">Dropship</span>`\n          : order.order_type==='wholesale' ? '<span class=\"ims__pill ims__pill--info\">Wholesale</span>'\n          : '<span class=\"ims__pill ims__pill--neutral\">Retail</span>'\n        }</div></div>\n        <div><span class=\"ims__label\">Postcode</span><div>${util().sanitize(order.postcode||order.end_postcode||'\u2014')}</div></div>\n        <div style=\"grid-column:1/-1\"><span class=\"ims__label\">Delivery address</span><div>${util().sanitize(order.address||order.end_address||'\u2014')}</div></div>\n        <div><span class=\"ims__label\">Order date</span><div>${util().formatDate(order.created_at)}</div></div>\n        <div><span class=\"ims__label\">Phone</span><div>${util().sanitize(order.phone||order.end_customer_phone||'\u2014')}</div></div>\n        ${order.order_type==='retail'?`\n          <div><span class=\"ims__label\">Payment</span><div style=\"display:flex;gap:8px;align-items:center\">\n            ${util().pill(order.payment_status||'unpaid')}\n            ${order.payment_received_at?`<span style=\"font-size:11px;color:var(--ims-text-muted)\">${util().formatDate(order.payment_received_at)}</span>`:''}\n            ${order.payment_method?`<span style=\"font-size:11px;color:var(--ims-text-muted)\">${util().sanitize(order.payment_method)}</span>`:''}\n          </div></div>\n          <div><span class=\"ims__label\">External ref</span><div>${util().sanitize(order.external_ref||'\u2014')}</div></div>`:''}\n        ${isDropship && order.dropship_customers ? `\n          <div><span class=\"ims__label\">Dropship customer</span><div style=\"font-weight:600\">${util().sanitize(order.dropship_customers.business_name)}</div></div>\n          <div><span class=\"ims__label\">End customer</span><div>${util().sanitize(order.end_customer_name||'\u2014')}</div></div>` : ''}\n        ${shipment ? `\n          <div><span class=\"ims__label\">Courier</span><div>${util().sanitize(shipment.couriers?.name||'\u2014')}</div></div>\n          <div><span class=\"ims__label\">Tracking #</span><div>${trackUrl?`<a href=\"${trackUrl}\" target=\"_blank\" class=\"ims__link\">${util().sanitize(shipment.tracking_number||'\u2014')}</a>`:util().sanitize(shipment.tracking_number||'\u2014')}</div></div>\n          ${shipment.courier_order_ref ? `<div><span class=\"ims__label\">Courier order no.</span><div>${util().sanitize(shipment.courier_order_ref)}</div></div>` : ''}` : ''}\n        ${_isShopifyOrder ? `\n          <div style=\"grid-column:1/-1\"><span class=\"ims__label\">Shopify</span><div style=\"display:flex;gap:8px;align-items:center;flex-wrap:wrap\">${_shopifyLine(_shopLast)}${_shopLast?.status === 'failed' ? `<button class=\"ims__btn ims__btn--secondary ims__btn--sm\" onclick=\"window.IMS_ORDERS.resendShopify('${util().jsArg(order.id)}','${util().jsArg(_shopLast.action)}')\"><i class=\"ti ti-refresh\"></i> Send to Shopify again</button>` : ''}</div></div>` : ''}\n        ${order.collected_by ? `\n          <div><span class=\"ims__label\">Collected by</span><div>${util().sanitize(order.collected_by)}</div></div>\n          <div><span class=\"ims__label\">Vehicle reg</span><div>${util().sanitize(order.collection_vehicle||'\u2014')}</div></div>\n          <div><span class=\"ims__label\">Collected at</span><div>${util().formatDate(order.collected_at)}</div></div>` : ''}\n        ${order.return_reason ? `\n          <div><span class=\"ims__label\">Return reason</span><div>${util().sanitize(order.return_reason)}</div></div>\n          <div><span class=\"ims__label\">Return requested</span><div>${util().formatDate(order.return_requested_at)}</div></div>` : ''}\n        ${order.refund_amount ? `\n          <div><span class=\"ims__label\">Refund amount</span><div style=\"font-weight:600;color:var(--ims-danger)\">\u00A3${(order.refund_amount||0).toFixed(2)}</div></div>\n          <div><span class=\"ims__label\">Refunded at</span><div>${util().formatDate(order.refunded_at)}</div></div>` : ''}\n        ${order.notes ? `<div style=\"grid-column:1/-1\"><span class=\"ims__label\">Notes</span><div>${util().sanitize(order.notes)}</div></div>` : ''}\n      </div>\n      <hr class=\"ims__divider\">\n      <strong style=\"font-size:13px\">Items</strong>\n      <div class=\"ims__table-wrap\" style=\"margin-top:8px\">\n        <table class=\"ims__table\">\n          <thead><tr><th>Product</th><th>SKU</th><th>Qty</th><th>Unit price</th><th>Total</th></tr></thead>\n          <tbody>\n            ${(order.order_items||[]).map(i => `\n              <tr><td>${util().sanitize(i.product_name||'-')}${_svcTag(i)}</td><td>${util().sanitize(i.sku||'-')}</td>\n              <td>${i.quantity}</td><td>${util().formatCurrency(i.unit_price)}</td><td>${util().formatCurrency(i.total_price)}</td></tr>`).join('')}\n            <tr><td colspan=\"4\" style=\"text-align:right;font-weight:600\">${_comm.hasCommission ? 'Gross' : 'Total'}</td><td style=\"font-weight:700\">${util().formatCurrency(order.total_value)}</td></tr>\n            ${_comm.hasCommission ? `\n            <tr><td colspan=\"4\" style=\"text-align:right;color:var(--ims-danger)\">Marketplace commission</td><td style=\"color:var(--ims-danger)\">\u2212${util().formatCurrency(_comm.commission)}</td></tr>\n            <tr><td colspan=\"4\" style=\"text-align:right;font-weight:700\">Net after commission</td><td style=\"font-weight:800;color:var(--ims-success)\">${util().formatCurrency(_comm.net)}</td></tr>` : ''}\n          </tbody>\n        </table>\n      </div>\n      <div id=\"ims-ord-pod-${util().sanitize(order.id)}\"></div>\n      <div id=\"ims-ord-col-${util().sanitize(order.id)}\"></div>\n      ${isDelayed ? `<div class=\"ims__alert ims__alert--warning\" style=\"margin-top:12px\"><i class=\"ti ti-alert-triangle\"></i><span>Delayed \u2014 dispatched ${util().daysSince(order.dispatched_at)} days ago with no delivery confirmation.</span></div>` : ''}\n      ${isTerminal ? `<div class=\"ims__alert ims__alert--info\" style=\"margin-top:12px\"><i class=\"ti ti-lock\"></i><span>Order is <strong>${order.status}</strong>: status is final.</span></div>` : ''}\n      ${order.amended_at ? `<div class=\"ims__alert ims__alert--info\" style=\"margin-top:12px\"><i class=\"ti ti-pencil\"></i><span>Amended on ${util().formatDateTime ? util().formatDateTime(order.amended_at) : util().formatDate(order.amended_at)}. See the activity log for what changed.</span></div>` : ''}`;\n\n    // Amend: while Confirmed, Picking or Packed, or on a manifest whose van\n    // has not departed. Anyone with Orders access.\n    const amendSt = await _amendState(order);\n    const footer = `\n      <div class=\"ims__btn-group\" style=\"flex-wrap:wrap\">\n        <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.IMS_ORDERS.printOrder('${util().jsArg(order.id)}')\"><i class=\"ti ti-printer\"></i> Print</button>\n        <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.IMS_ORDERS.showActivityLog('${util().jsArg(order.id)}','${util().jsArg(order.order_number)}')\" title=\"Everything done to this order, by whom and when\"><i class=\"ti ti-history\"></i> Activity</button>\n        ${amendSt.ok ? `<button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_ORDERS.amendOrder('${util().jsArg(order.id)}')\"><i class=\"ti ti-pencil\"></i> Amend order</button>` : ''}\n        ${window.SM.AUTH.isSuperAdmin() ? `<button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_ORDERS.editOrderCustomer('${util().jsArg(order.id)}')\"><i class=\"ti ti-edit\"></i> Edit customer &amp; refs</button>` : ''}\n        ${isDelayed ? `<button class=\"ims__btn ims__btn--danger\" onclick=\"window.SM.UI.closeModal();window.SM.UI.showPanel('logistics')\"><i class=\"ti ti-truck-delivery\"></i> Chase in Logistics</button>` : ''}\n        ${order.status==='lost' ? `<div class=\"ims__alert ims__alert--info\" style=\"margin:0;padding:8px 12px;font-size:12px\"><i class=\"ti ti-file-alert\"></i> Claim management for lost orders is handled from <strong>Logistics \u2192 Tracking \u2192 Lost Orders</strong>.</div>` : ''}\n        ${!isDropship && !isTerminal && !isReturnInProgress ? canCancelHere ? `\n          ${nextSteps.length ? `\n          <select class=\"ims__select\" id=\"ims-order-status-sel\" style=\"font-size:12px;width:auto\">\n            <option value=\"\">Update status...</option>\n            ${nextSteps.map(s => `<option value=\"${s}\">${STATUS_LABELS[s]}</option>`).join('')}\n          </select>\n          <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_ORDERS.updateStatus('${util().jsArg(order.id)}')\">Update</button>` : `\n          <div class=\"ims__alert ims__alert--info\" style=\"margin:0;padding:8px 12px;font-size:12px;flex:1 1 100%\"><i class=\"ti ti-list-check\"></i> Sent to Logistics as an unassigned job. It will move to Despatched automatically once a courier, own truck, or self-collection is assigned.</div>`}\n          <button class=\"ims__btn ims__btn--danger\" onclick=\"window.IMS_ORDERS.cancelOrder('${util().jsArg(order.id)}','${util().jsArg(order.order_number)}')\"><i class=\"ti ti-x\"></i> Cancel order</button>` : `\n          <div class=\"ims__alert ims__alert--info\" style=\"margin:0;padding:8px 12px;font-size:12px;flex:1 1 100%\"><i class=\"ti ti-truck\"></i> This order has been despatched \u2014 delivery, failed delivery, lost and return updates are now managed from <strong>Logistics</strong>.</div>` : ''}\n        ${order.status === 'return_requested' ? `<button class=\"ims__btn ims__btn--secondary\" onclick=\"window.SM.UI.closeModal();window.IMS_LOGISTICS?.bookCourierCollection('${util().jsArg(order.id)}','${util().jsArg(order.order_number)}')\" title=\"Book a courier to collect this return\"><i class=\"ti ti-truck-delivery\"></i> Book courier collection</button>` : ''}\n        ${order.status === 'return_requested' ? `<button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_ORDERS.arrangeVanPickup('${util().jsArg(order.id)}','${util().jsArg(order.order_number)}')\" title=\"Collect this return with our own van\"><i class=\"ti ti-truck-return\"></i> Arrange van pick-up</button>` : ''}\n        ${isReturnable ? `<button class=\"ims__btn ims__btn--warning\" onclick=\"window.IMS_ORDERS.showReturnModal('${util().jsArg(order.id)}','${util().jsArg(order.order_number)}',${order.total_value||0})\"><i class=\"ti ti-arrow-back-up\"></i> Request return</button>` : ''}\n        ${isReturnable ? `<button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_ORDERS.showRefundNoReturn('${util().jsArg(order.id)}','${util().jsArg(order.order_number)}',${order.total_value||0})\"><i class=\"ti ti-currency-pound\"></i> Refund (no return)</button>` : ''}\n        ${order.status==='return_requested' ? `<button class=\"ims__btn ims__btn--info\" onclick=\"window.IMS_ORDERS.markReturnReceived('${util().jsArg(order.id)}')\"><i class=\"ti ti-package-import\"></i> Mark return received</button>` : ''}\n        ${order.status==='return_received' ? `<button class=\"ims__btn ims__btn--success\" onclick=\"window.IMS_ORDERS.processRefund('${util().jsArg(order.id)}',${order.total_value||0})\"><i class=\"ti ti-currency-pound\"></i> Process refund</button>` : ''}\n        ${order.order_type==='retail'&&(order.payment_status==='unpaid'||!order.payment_status)&&order.status!=='cancelled' ? `<button class=\"ims__btn ims__btn--success\" onclick=\"window.IMS_ORDERS.markPaid('${util().jsArg(order.id)}',${order.total_value||0})\"><i class=\"ti ti-check\"></i> Mark paid</button>` : ''}\n        ${order.order_type==='wholesale'&&(order.payment_status==='unpaid'||order.payment_status==='partial')&&order.status!=='cancelled' ? `\n          <div class=\"ims__alert ims__alert--info\" style=\"margin:0;padding:8px 12px;font-size:12px;flex:1 1 100%\">\n            <i class=\"ti ti-receipt\"></i>\n            <span>Wholesale orders are paid on credit terms \u2014 record the payment in <strong>Accounts \u2192 Receivables</strong>, which will mark this order paid automatically.</span>\n            <button class=\"ims__btn ims__btn--secondary ims__btn--sm\" style=\"margin-left:auto\" onclick=\"window.SM.UI.closeModal();window.SM.UI.showPanel('accounts');setTimeout(()=>window.IMS_ACCOUNTS?.switchTab('receivables'),400)\"><i class=\"ti ti-arrow-right\"></i> Go to Receivables</button>\n          </div>` : ''}\n        ${isDropship && !['collected','cancelled'].includes(order.status) ? `\n          <button class=\"ims__btn ims__btn--success\" onclick=\"window.SM.UI.closeModal();window.IMS_DROPSHIP?.showCollectionModal('${util().jsArg(order.id)}','${util().jsArg(order.order_number)}','${util().jsArg(order.dropship_customers?.business_name||'')}')\">\n            <i class=\"ti ti-truck-loading\"></i> Confirm collection</button>` : ''}\n        <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Close</button>\n      </div>`;\n    ui().openModal(`Order ${order.order_number}`, html, footer, 'lg');\n    // Proof of delivery recorded at the stop (photo, signature, name...).\n    window.IMS_LOGISTICS?.renderOrderPod?.(order.id, `ims-ord-pod-${order.id}`);\n    // A courier collection booked for this return (Mark collected, Edit, Cancel).\n    window.IMS_LOGISTICS?.renderReturnCollection?.(order.id, `ims-ord-col-${order.id}`, order.status);\n  }\n\n  async function updateStatus(orderId, claimId=null) {\n    const sel = document.getElementById('ims-order-status-sel');\n    if (!sel?.value) return;\n    const newStatus = sel.value;\n\n    // \u2500\u2500 Normal status update (Picking / Packed only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    const { data: current } = await db().select('orders', { select: 'status', eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true });\n    if (!['confirmed','picking'].includes(current?.status)) {\n      ui().toast('This order can no longer be updated from here', 'error');\n      return;\n    }\n    const { error } = await db().update('orders', orderId, { status: newStatus });\n    if (error) { ui().toast('Update failed', 'error'); return; }\n    await logActivity(orderId, 'Status updated', current?.status||'', newStatus);\n\n    if (newStatus === 'packed') {\n      await db().insert('logistics_jobs', {\n        order_id: orderId,\n        job_type: 'delivery',\n        status:   'unassigned'\n      });\n    }\n\n    ui().closeModal();\n    ui().toast('Order status updated', 'success');\n    load();\n  }\n\n  // The order view's \"Shopify\" line: the last update sent to Shopify.\n  function _shopifyLine(last) {\n    if (!last) return '<span style=\"font-size:12px;color:var(--ims-text-muted)\">No update sent from StockMaestro yet</span>';\n    const what = { fulfil: 'Fulfil', tracking: 'Tracking update', unfulfil: 'Unfulfil', cancel: 'Cancel' }[last.action] || last.action;\n    const pill = last.status === 'done' ? '<span class=\"ims__pill ims__pill--success\">Updated</span>'\n      : last.status === 'failed' ? '<span class=\"ims__pill ims__pill--danger\">Not updated</span>'\n      : '<span class=\"ims__pill ims__pill--neutral\">No change needed</span>';\n    return `${pill}<span style=\"font-size:12px\">${util().sanitize(what)}: ${util().sanitize(last.detail || '')}</span>`\n      + `<span style=\"font-size:11px;color:var(--ims-text-muted)\">${util().formatDate(last.created_at)}${last.created_by_name ? ' &middot; ' + util().sanitize(last.created_by_name) : ''}</span>`;\n  }\n\n  // \"Send to Shopify again\": repeats the last update that failed, then\n  // reopens the order to show the new result.\n  async function resendShopify(orderId, action) {\n    if (!window.SM.SHOPIFY) return;\n    ui().toast('Sending to Shopify...', 'info', 3000);\n    const out = await window.SM.SHOPIFY.sync(action, [orderId]);\n    const r = out?.results?.[0];\n    if (r?.status === 'done') ui().toast('Shopify updated', 'success');\n    else if (r?.status === 'skipped') ui().toast(r.detail || 'Nothing to change in Shopify', 'info', 6000);\n    else if (!out) ui().toast('Shopify could not be reached. Try again later.', 'warning', 6000);\n    openOrder(orderId);\n  }\n\n  async function cancelOrder(orderId, orderNumber) {\n    ui().confirm(`Cancel order <strong>${orderNumber}</strong>?<br><br>Stock reservations will be released and the order will move to the Cancelled list.`, async () => {\n      const { data: cancelOrd } = await db().select('orders', {\n        select: 'status,warehouse_id,order_items(product_id,quantity)', eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true\n      });\n      if (!['confirmed','picking','packed'].includes(cancelOrd?.status)) {\n        ui().toast('This order can no longer be cancelled from here', 'error');\n        return;\n      }\n      const items = cancelOrd?.order_items || [];\n      const whId = cancelOrd?.warehouse_id;\n      // Release one line at a time. Releasing every line at once meant two\n      // lines of the same product both read the same starting figure, so\n      // only one release was applied and stock stayed wrongly reserved.\n      for (const item of (items||[])) {\n        if (!item.product_id) continue;\n        const { data: sl } = whId\n          ? await db().select('stock_levels', { eq: { product_id: item.product_id, warehouse_id: whId }, maybeSingle: true, noCompanyFilter: true })\n          : await db().select('stock_levels', { eq: { product_id: item.product_id }, limit: 1, noCompanyFilter: true }).then(r => ({ data: r.data?.[0] }));\n        if (sl) await db().update('stock_levels', sl.id, { reserved_qty: Math.max(0,(sl.reserved_qty||0)-(item.quantity||0)) });\n      }\n      // Remove any Logistics job tied to this order \u2014 orders that reached\n      // 'packed' have one, and Logistics' own cancel path always deletes it.\n      // Without this, a stale unassigned job keeps pointing at an order that\n      // no longer exists in any actionable state.\n      const _cancelClient = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n      await _cancelClient.from('logistics_jobs').delete().eq('order_id', orderId);\n\n      await db().update('orders', orderId, { status: 'cancelled' });\n      await logActivity(orderId, 'Order cancelled', cancelOrd?.status||'', 'cancelled', 'Cancelled from Order Management');\n      window.SM.SHOPIFY?.sync('cancel', [orderId]);   // website orders: cancelled and restocked in Shopify (no refund)\n      ui().closeModal();\n      ui().toast('Order cancelled \u2014 stock released', 'success');\n      load();\n    }, 'Cancel order', true);\n  }\n\n  async function markPaid(orderId, totalValue) {\n    ui().openModal('Mark order as paid', `\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:14px\"><i class=\"ti ti-currency-pound\"></i>\n        <span>Record payment of <strong>${util().formatCurrency(totalValue)}</strong> for this order.</span></div>\n      <div class=\"ims__form-grid\">\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Payment method</label>\n          <select class=\"ims__select\" id=\"ims-pay-method\">\n            <option value=\"bank_transfer\">Bank transfer</option><option value=\"card\">Card payment</option>\n            <option value=\"cash\">Cash</option><option value=\"cheque\">Cheque</option>\n            <option value=\"paypal\">PayPal</option><option value=\"other\">Other</option>\n          </select></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Payment date</label>\n          <input class=\"ims__input\" type=\"date\" id=\"ims-pay-date\" value=\"${new Date().toISOString().split('T')[0]}\"></div>\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label\">Amount received (\u00A3)</label>\n          <input class=\"ims__input\" type=\"number\" step=\"0.01\" id=\"ims-pay-amount\" value=\"${totalValue.toFixed(2)}\">\n          <span class=\"ims__input-hint\">Change to a lower amount if partial payment received</span></div>\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label\">Payment reference</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-pay-ref\" placeholder=\"e.g. bank transfer ref, receipt number\"></div>\n      </div>`,`\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--success\" onclick=\"window.IMS_ORDERS.confirmPayment('${util().jsArg(orderId)}',${totalValue})\">\n        <i class=\"ti ti-check\"></i> Confirm payment</button>`,'sm');\n  }\n\n  async function confirmPayment(orderId, totalValue) {\n    const method  = document.getElementById('ims-pay-method')?.value;\n    const dateVal = document.getElementById('ims-pay-date')?.value;\n    const amount  = parseFloat(document.getElementById('ims-pay-amount')?.value)||0;\n    const ref     = document.getElementById('ims-pay-ref')?.value?.trim();\n    if (!amount) { ui().toast('Please enter the amount received', 'error'); return; }\n    const isPartial = amount < totalValue;\n    await db().update('orders', orderId, { payment_status: isPartial?'partial':'paid', payment_received_at: new Date(`${dateVal}T00:00:00`).toISOString(), payment_method: method });\n    const { data: ord } = await db().select('orders', { select: 'order_number,payment_status', eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true });\n    await db().insert('transactions', { date: dateVal, type: 'income', category: 'Sales revenue', description: `Payment received \u2014 ${ord?.order_number||'order'} (${method})`, amount, reference: ref||ord?.order_number });\n    await logActivity(orderId, 'Payment recorded', ord?.payment_status||'unpaid', isPartial?'partial':'paid', `\u00A3${amount.toFixed(2)} via ${method}`);\n    ui().closeModal(); ui().toast(`Payment of ${util().formatCurrency(amount)} recorded${isPartial?' \u2014 partial payment':''}`,'success',4000); load();\n  }\n\n  async function showReturnModal(orderId, orderNumber, totalValue) {\n    ui().openModal(`Request return: ${orderNumber}`,`\n      <div class=\"ims__alert ims__alert--warning\" style=\"margin-bottom:14px\"><i class=\"ti ti-alert-triangle\"></i>\n        <span>Initiating a return changes status to <strong>Return Requested</strong>. Stock restocked once return received and inspected.</span></div>\n      <div class=\"ims__form-grid\">\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label ims__label--req\">Return reason</label>\n          <select class=\"ims__select\" id=\"ims-ret-reason\"><option value=\"\">Select reason...</option>\n            <option value=\"damaged_in_transit\">Damaged in transit</option><option value=\"wrong_item_sent\">Wrong item sent</option>\n            <option value=\"not_as_described\">Not as described</option><option value=\"customer_changed_mind\">Customer changed mind</option>\n            <option value=\"faulty_product\">Faulty product</option><option value=\"other\">Other</option>\n          </select></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Return method</label>\n          <select class=\"ims__select\" id=\"ims-ret-method\">\n            <option value=\"courier_collection\">Courier collection (we arrange)</option>\n            <option value=\"customer_dropoff\">Customer drops off</option>\n            <option value=\"customer_courier\">Customer arranges courier</option>\n            <option value=\"own_van_pickup\">Collect with our van</option>\n          </select></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Refund amount (\u00A3)</label>\n          <input class=\"ims__input\" type=\"number\" step=\"0.01\" id=\"ims-ret-refund\" value=\"${totalValue.toFixed(2)}\">\n          <span class=\"ims__input-hint\">Adjust for restocking fee if applicable</span></div>\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label\">Notes</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-ret-notes\" placeholder=\"Additional details about the return\"></div>\n      </div>`,`\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--warning\" onclick=\"window.IMS_ORDERS.submitReturn('${util().jsArg(orderId)}',${totalValue})\">\n        <i class=\"ti ti-arrow-back-up\"></i> Initiate return</button>`,'sm');\n  }\n\n  // Collect a requested return with our own van (it joins the Own Truck Queue).\n  async function arrangeVanPickup(orderId, orderNumber) {\n    if (!window.IMS_LOGISTICS?.arrangeVanPickup) { ui().toast('Logistics is not available', 'error'); return; }\n    const done = await window.IMS_LOGISTICS.arrangeVanPickup(orderId, orderNumber);\n    if (done) openOrder(orderId);\n  }\n\n  async function submitReturn(orderId, totalValue) {\n    const reason = document.getElementById('ims-ret-reason')?.value;\n    const refund = parseFloat(document.getElementById('ims-ret-refund')?.value)||totalValue;\n    const notes  = document.getElementById('ims-ret-notes')?.value?.trim();\n    if (!reason) { ui().toast('Please select a return reason', 'error'); return; }\n    // The return method is now saved (it used to be asked for, then lost).\n    const method = document.getElementById('ims-ret-method')?.value || null;\n    const { error } = await db().update('orders', orderId, { status: 'return_requested', return_reason: reason, return_requested_at: new Date().toISOString(), refund_amount: refund, notes: notes||null, return_method: method });\n    if (error) { ui().toast('Failed: ' + error.message, 'error'); return; }\n    await logActivity(orderId, 'Return initiated', 'delivered', 'return_requested', reason);\n    ui().closeModal();\n    if (method === 'own_van_pickup' && window.IMS_LOGISTICS?.arrangeVanPickup) {\n      // Collected by our van: the pick-up goes straight into the Own Truck Queue.\n      await window.IMS_LOGISTICS.arrangeVanPickup(orderId, null);\n    } else if (method === 'courier_collection' && window.IMS_LOGISTICS?.bookCourierCollection) {\n      // Collected by a courier: book it now (courier, date, charge, email).\n      load();\n      return window.IMS_LOGISTICS.bookCourierCollection(orderId, null);\n    } else {\n      ui().toast('Return initiated: awaiting the item back at the warehouse', 'info', 4000);\n    }\n    load();\n  }\n\n  async function markReturnReceived(orderId) {\n    ui().confirm('Confirm that the returned item has been received and inspected at the warehouse?', async () => {\n      await db().update('orders', orderId, { status: 'return_received', return_received_at: new Date().toISOString() });\n      await logActivity(orderId, 'Return received', 'return_requested', 'return_received');\n      ui().toast('Return received \u2014 ready to process refund', 'success'); load();\n    }, 'Confirm received', false);\n  }\n\n  // \u2500\u2500\u2500 REFUNDS: shared safety checks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // Both refund paths below used to run every step without checking any\n  // of them, then always say \"Refund processed\". Now:\n  //  - an order that is already refunded is refused (no second refund);\n  //  - the order is marked refunded FIRST, and only while it is not\n  //    already refunded, so a double click or two screens at once cannot\n  //    both go through; if that step fails, nothing else happens;\n  //  - every later step is checked, and anything that did not work is\n  //    named in the message so it can be put right by hand;\n  //  - whichever list is open (Orders, or Logistics > Tracking and Lost\n  //    Orders) is refreshed, so the order does not linger on screen.\n\n  function _authClient() {\n    return window.supabase.createClient(\n      window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY,\n      { global: { headers: { Authorization: `Bearer ${window.SM.AUTH.session?.access_token}` } } }\n    );\n  }\n\n  // Marks the order refunded, but only if it is not refunded already.\n  // Returns { ok: true } if this call did it, { already: true } if it was\n  // already refunded, or { error } if the update failed.\n  async function _markRefunded(orderId, extraFields) {\n    const { data, error } = await _authClient().from('orders')\n      .update({ status: 'refunded', payment_status: 'refunded', ...extraFields })\n      .eq('id', orderId)\n      .or('payment_status.is.null,payment_status.neq.refunded')\n      .select('id');\n    if (error) return { error };\n    if (!data?.length) return { already: true };\n    return { ok: true };\n  }\n\n  function _refreshAfterRefund() {\n    load();\n    if (window.SM.UI.activePanel === 'logistics') window.IMS_LOGISTICS?.loadTracking?.();\n  }\n\n  // The money steps, run after the order is marked refunded. Each one is\n  // checked. Returns a list of plain-English problems (empty if all ok).\n  async function _refundMoneySteps(orderId, orderNumber, amount, dateVal, creditNoteReason, refundDescription) {\n    const problems = [];\n    // If a sales invoice was already generated for this order, issue a\n    // credit note against it rather than leaving it sitting there as if\n    // still owed.\n    let noteNum = null;\n    try {\n      noteNum = await window.IMS_ACCOUNTS.reverseOrderInvoice(orderId, amount, dateVal, creditNoteReason);\n    } catch (e) {\n      problems.push(`the credit note could not be issued (${e.message})`);\n    }\n    // If a wholesale receivable was raised on delivery, clear it, so\n    // Accounts does not keep chasing payment on a refunded order.\n    const { error: arErr } = await _authClient().from('accounts_receivable').delete().eq('order_id', orderId);\n    if (arErr) problems.push(`the amount owed in Accounts could not be cleared (${arErr.message})`);\n    // The refund is recorded ONCE, as a reduction of sales (standard\n    // practice, as in Xero and Sage). When a credit note was issued above,\n    // it already recorded that entry; otherwise record it here. (It used to\n    // add a \"Refunds\" expense as well, counting invoiced refunds twice.)\n    if (!noteNum) {\n      const { error: txErr } = await db().insert('transactions', {\n        date: dateVal, type: 'income', category: 'Sales returns and refunds',\n        description: refundDescription, amount: -amount, vat_amount: 0, reference: orderNumber\n      });\n      if (txErr) problems.push(`the refund could not be recorded in Accounts (${txErr.message})`);\n    }\n    return problems;\n  }\n\n  async function processRefund(orderId, totalValue) {\n    const { data: ord } = await db().select('orders', {\n      select: 'order_number,refund_amount,return_reason,status,payment_status',\n      eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true\n    });\n    if (!ord) { ui().toast('Order not found', 'error'); return; }\n    const orderNumber = ord.order_number || '';\n    if (ord.payment_status === 'refunded' || ord.status === 'refunded') {\n      ui().toast(`${orderNumber} has already been refunded. Nothing was changed.`, 'warning', 6000);\n      _refreshAfterRefund();\n      return;\n    }\n    const refundAmt = ord.refund_amount || totalValue || 0;\n    const reason = ord.return_reason || 'return';\n    ui().confirm(`Process refund of <strong>${util().formatCurrency(refundAmt)}</strong>?<br><br>This will mark the order as Refunded, restock items, and record a refund transaction.`, async () => {\n      const dateVal = new Date().toISOString().split('T')[0];\n      const mark = await _markRefunded(orderId, { refunded_at: new Date().toISOString() });\n      if (mark.error) {\n        ui().closeModal();\n        ui().toast(`Refund not processed: ${orderNumber} could not be marked as refunded (${mark.error.message}). Nothing was changed.`, 'error', 10000);\n        return;\n      }\n      if (mark.already) {\n        ui().closeModal();\n        ui().toast(`${orderNumber} has already been refunded. Nothing was changed.`, 'warning', 6000);\n        _refreshAfterRefund();\n        return;\n      }\n      await logActivity(orderId, 'Refund processed', ord.status || '', 'refunded', `\u00A3${refundAmt.toFixed(2)}`);\n\n      const problems = [];\n      // Restock. smartRestock (ims-logistics.js) runs at most once per\n      // order, so this is safe even if the goods were already put back\n      // when the return was received.\n      try {\n        await window.IMS_LOGISTICS.smartRestock(orderId, orderNumber, `Refund processed (${reason})`);\n      } catch (e) {\n        problems.push(`stock could not be updated (${e.message})`);\n      }\n      problems.push(...await _refundMoneySteps(orderId, orderNumber, refundAmt, dateVal,\n        `Refund: order returned (${reason})`, `Refund: ${orderNumber} (${reason})`));\n\n      ui().closeModal();\n      if (problems.length) {\n        ui().toast(`Refund of ${util().formatCurrency(refundAmt)} recorded on ${orderNumber}, but ${problems.join('; ')}. Please put this right by hand.`, 'warning', 15000);\n      } else {\n        ui().toast(`Refund of ${util().formatCurrency(refundAmt)} processed`, 'success', 5000);\n      }\n      _refreshAfterRefund();\n    }, 'Process refund', false);\n  }\n\n  // \u2500\u2500\u2500 REFUND WITHOUT RETURN \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // Covers the case where the customer keeps the item and still gets\n  // refunded. No restock, since nothing physical is coming back.\n  function showRefundNoReturn(orderId, orderNumber, totalValue) {\n    const todayStr = new Date().toISOString().split('T')[0];\n    ui().openModal(`Refund without return: ${orderNumber}`, `\n      <div class=\"ims__alert ims__alert--warning\" style=\"margin-bottom:14px\">\n        <i class=\"ti ti-alert-triangle\"></i>\n        <span>Customer keeps the item, so <strong>no stock will be restocked</strong>. Use this for goodwill refunds, partial-fault compensation, or any case where the goods are not coming back.</span>\n      </div>\n      <div class=\"ims__form-grid\">\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Refund amount (\u00A3)</label><input class=\"ims__input\" type=\"number\" step=\"0.01\" min=\"0\" id=\"ims-rnr-amount\" value=\"${(totalValue||0).toFixed(2)}\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Date</label><input class=\"ims__input\" type=\"date\" id=\"ims-rnr-date\" value=\"${todayStr}\" max=\"${todayStr}\"></div>\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label ims__label--req\">Reason</label><input class=\"ims__input\" type=\"text\" id=\"ims-rnr-reason\" placeholder=\"e.g. Goodwill gesture, minor cosmetic fault, short delivery...\"></div>\n      </div>\n    `,`\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--success\" onclick=\"window.IMS_ORDERS.confirmRefundNoReturn('${util().jsArg(orderId)}','${util().jsArg(orderNumber)}')\"><i class=\"ti ti-currency-pound\"></i> Confirm refund</button>\n    `,'sm');\n  }\n\n  async function confirmRefundNoReturn(orderId, orderNumber) {\n    const amount = parseFloat(document.getElementById('ims-rnr-amount')?.value)||0;\n    const dateVal = document.getElementById('ims-rnr-date')?.value;\n    const reason = document.getElementById('ims-rnr-reason')?.value?.trim();\n    if(!amount||amount<=0){ ui().toast('Please enter a valid amount','error'); return; }\n    if(!dateVal){ ui().toast('Please select a date','error'); return; }\n    if(!reason){ ui().toast('Please enter a reason','error'); return; }\n\n    const { data: ord } = await db().select('orders', {\n      select: 'status,payment_status', eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true\n    });\n    if (ord?.payment_status === 'refunded' || ord?.status === 'refunded') {\n      ui().closeModal();\n      ui().toast(`${orderNumber} has already been refunded. Nothing was changed.`, 'warning', 6000);\n      _refreshAfterRefund();\n      return;\n    }\n\n    // No restock here: the customer is keeping the item.\n    const mark = await _markRefunded(orderId, {\n      refunded_at: new Date(dateVal).toISOString(),\n      return_reason: `Refund without return: ${reason}`\n    });\n    if (mark.error) {\n      ui().toast(`Refund not processed: ${orderNumber} could not be marked as refunded (${mark.error.message}). Nothing was changed.`, 'error', 10000);\n      return;\n    }\n    if (mark.already) {\n      ui().closeModal();\n      ui().toast(`${orderNumber} has already been refunded. Nothing was changed.`, 'warning', 6000);\n      _refreshAfterRefund();\n      return;\n    }\n    await logActivity(orderId, 'Refund without return', ord?.status || 'delivered', 'refunded', `\u00A3${amount.toFixed(2)}: ${reason}`);\n\n    const problems = await _refundMoneySteps(orderId, orderNumber, amount, dateVal,\n      `Refund without return: ${reason}`, `Refund without return: ${orderNumber} (${reason})`);\n\n    ui().closeModal();\n    if (problems.length) {\n      ui().toast(`Refund of ${util().formatCurrency(amount)} recorded on ${orderNumber}, but ${problems.join('; ')}. Please put this right by hand.`, 'warning', 15000);\n    } else {\n      ui().toast(`Refund of ${util().formatCurrency(amount)} processed. Customer kept the item.`, 'success', 5000);\n    }\n    _refreshAfterRefund();\n  }\n\n\n  // \u2500\u2500\u2500 FOLLOW UP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // Courier follow-ups are now handled solely in Logistics \u2192 Tracking.\n  // Order Management previously had its own independent followUp()/\n  // sendFollowUp() pair writing to a separate `courier_followups` table,\n  // which neither Logistics nor the dashboard could see \u2014 so the same\n  // parcel could be chased twice with no shared history. Both functions\n  // and their exports have been removed; delayed orders now link across\n  // to Logistics instead. The `courier_followups` table is retained for\n  // historical records and is still read by the dashboard's chased check.\n\n  // \u2500\u2500\u2500 EDIT ORDER CUSTOMER (Super Admin only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // Deliberately limited to customer details and customer linkage \u2014 it does\n  // NOT touch line items, quantities or prices, because changing those after\n  // stock has been reserved/picked/dispatched would silently corrupt\n  // inventory unless the reservations are correctly unwound. That's a\n  // separate, larger job.\n  let _editCustPicked = null;\n\n  async function editOrderCustomer(orderId) {\n    if (!window.SM.AUTH.isSuperAdmin()) { ui().toast('Only Super Admin can edit orders', 'error'); return; }\n    const { data: order } = await db().select('orders', {\n      eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true\n    });\n    if (!order) { ui().toast('Order not found', 'error'); return; }\n    _editCustPicked = order.customer_id || null;\n\n    const isWholesale = order.order_type === 'wholesale';\n\n    ui().openModal(`Edit customer & references \u2014 ${util().sanitize(order.order_number)}`, `\n      <div class=\"ims__alert ims__alert--warning\" style=\"margin-bottom:12px\">\n        <i class=\"ti ti-alert-triangle\"></i>\n        <span>Editing customer details only. Line items, quantities and pricing cannot be changed here.</span>\n      </div>\n      ${isWholesale ? `\n      <div class=\"ims__form-group\" style=\"margin-bottom:12px\">\n        <label class=\"ims__label ims__label--req\">Link to registered customer</label>\n        <div style=\"position:relative\">\n          <input class=\"ims__input\" type=\"text\" id=\"ims-eoc-search\" placeholder=\"Start typing a business name or postcode, then pick from the list\" autocomplete=\"off\"\n            value=\"${util().sanitize(order.customer_name || '')}\"\n            oninput=\"window.IMS_ORDERS.searchEditCustomer(this.value)\">\n          <div id=\"ims-eoc-drop\" class=\"ims__ac-dropdown\"></div>\n        </div>\n        <span class=\"ims__input-hint\" id=\"ims-eoc-linked\">${order.customer_id\n          ? '<span style=\"color:var(--ims-success)\"><i class=\"ti ti-link\"></i> Currently linked to a customer record</span>'\n          : '<span style=\"color:var(--ims-danger)\"><i class=\"ti ti-unlink\"></i> Not linked \u2014 you must <strong>pick a customer from this list</strong>. Typing a name below does not link it.</span>'}</span>\n      </div>` : ''}\n      <div class=\"ims__form-grid\">\n        <div class=\"ims__form-group ims__form-group--full\">\n          <label class=\"ims__label ims__label--req\">Customer name</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-eoc-name\" value=\"${util().sanitize(order.customer_name || '')}\"\n            ${isWholesale ? 'readonly style=\"background:var(--ims-surface2)\"' : ''}>\n          ${isWholesale ? '<span class=\"ims__input-hint\">Set automatically from the registered customer you pick above.</span>' : ''}\n        </div>\n        <div class=\"ims__form-group ims__form-group--full\">\n          <label class=\"ims__label\">Address</label>\n          <textarea class=\"ims__textarea\" id=\"ims-eoc-address\" rows=\"2\">${util().sanitize(order.address || '')}</textarea>\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label\">Postcode</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-eoc-postcode\" value=\"${util().sanitize(order.postcode || '')}\">\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label\">Phone</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-eoc-phone\" value=\"${util().sanitize(order.phone || '')}\">\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label\">Email</label>\n          <input class=\"ims__input\" type=\"email\" id=\"ims-eoc-email\" value=\"${util().sanitize(order.email || '')}\">\n        </div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label\">Marketplace / external ref</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-eoc-extref\" value=\"${util().sanitize(order.external_ref || '')}\">\n        </div>\n      </div>\n    `, `\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_ORDERS.saveOrderCustomer('${util().jsArg(orderId)}')\"><i class=\"ti ti-check\"></i> Save changes</button>\n    `, 'lg');\n\n    // Pre-filling an input's `value` does not fire `oninput` \u2014 that only\n    // happens when a human types \u2014 so the pre-filled search sat there doing\n    // nothing. Run the lookup once after the modal is in the DOM so matching\n    // customers are offered immediately.\n    if (isWholesale && order.customer_name) {\n      setTimeout(() => searchEditCustomer(order.customer_name), 150);\n    }\n  }\n\n  async function searchEditCustomer(query) {\n    const drop = document.getElementById('ims-eoc-drop');\n    if (!drop) return;\n    if (!query || query.trim().length < 2) { drop.style.display = 'none'; return; }\n    const q = query.trim();\n    const [byName, byPostcode] = await Promise.all([\n      // Deactivated customers are not offered.\n      db().select('customers', { ilike: { business_name: q }, eq: { is_active: true }, select: 'id,business_name,address,postcode,phone,email', limit: 5 }),\n      db().select('customers', { ilike: { postcode: q }, eq: { is_active: true }, select: 'id,business_name,address,postcode,phone,email', limit: 5 })\n    ]);\n    const combined = [...(byName.data || []), ...(byPostcode.data || [])]\n      .filter((c, i, arr) => arr.findIndex(x => x.id === c.id) === i).slice(0, 8);\n    if (!combined.length) { drop.style.display = 'none'; return; }\n    drop.innerHTML = combined.map(c => `\n      <div class=\"ims__ac-item\" onmousedown='window.IMS_ORDERS.selectEditCustomer(${JSON.stringify(c).replace(/'/g, \"&#39;\")})'>\n        <strong>${util().sanitize(c.business_name)}</strong>\n        <div style=\"font-size:11px;color:var(--ims-text-muted)\">${util().sanitize(c.postcode || '')}</div>\n      </div>`).join('');\n    drop.style.display = 'block';\n  }\n\n  function selectEditCustomer(c) {\n    _editCustPicked = c.id;\n    const f = (id, v) => { const el = document.getElementById(id); if (el) el.value = v || ''; };\n    f('ims-eoc-name', c.business_name);\n    f('ims-eoc-address', c.address);\n    f('ims-eoc-postcode', c.postcode);\n    f('ims-eoc-phone', c.phone);\n    f('ims-eoc-email', c.email);\n    const drop = document.getElementById('ims-eoc-drop');\n    if (drop) drop.style.display = 'none';\n    const search = document.getElementById('ims-eoc-search');\n    if (search) search.value = c.business_name;\n    const linked = document.getElementById('ims-eoc-linked');\n    if (linked) linked.innerHTML = `<span style=\"color:var(--ims-success)\"><i class=\"ti ti-link\"></i> Will be linked to <strong>${util().sanitize(c.business_name)}</strong></span>`;\n  }\n\n  async function saveOrderCustomer(orderId) {\n    if (!window.SM.AUTH.isSuperAdmin()) { ui().toast('Only Super Admin can edit orders', 'error'); return; }\n    const g = id => document.getElementById(id)?.value?.trim() || '';\n    const name = g('ims-eoc-name');\n    if (!name) { ui().toast('Customer name is required', 'error'); return; }\n\n    const { data: order } = await db().select('orders', {\n      eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true\n    });\n    if (!order) { ui().toast('Order not found', 'error'); return; }\n\n    const { error } = await db().update('orders', orderId, {\n      customer_name: name,\n      address:       g('ims-eoc-address') || null,\n      postcode:      g('ims-eoc-postcode') || null,\n      phone:         g('ims-eoc-phone') || null,\n      email:         g('ims-eoc-email') || null,\n      external_ref:  g('ims-eoc-extref') || null,\n      customer_id:   _editCustPicked || null\n    });\n    if (error) { ui().toast('Failed to save: ' + error.message, 'error'); return; }\n\n    // If this is a delivered wholesale order that now finally has a customer\n    // linked, create the receivable that was skipped at delivery time \u2014\n    // otherwise it stays permanently unpaid with no way to clear it. Only\n    // if the order is genuinely still unpaid, though \u2014 if it was already\n    // settled (e.g. genuine COD collected on delivery), no receivable is\n    // needed regardless of the newly-linked customer's default terms.\n    let arCreated = false;\n    if (_editCustPicked && order.order_type === 'wholesale' && order.status === 'delivered') {\n      const { data: existingAR } = await db().select('accounts_receivable', {\n        eq: { order_id: orderId }, maybeSingle: true, noCompanyFilter: true\n      });\n      if (!existingAR) {\n        const { data: cust } = await db().select('customers', { select: 'credit_terms', eq: { id: _editCustPicked }, maybeSingle: true, noCompanyFilter: true });\n        const dueDate = util().resolveReceivableDueDate(order.payment_status, cust?.credit_terms);\n        if (dueDate) {\n          const { error: arErr } = await db().insert('accounts_receivable', {\n            order_id:    orderId,\n            customer_id: _editCustPicked,\n            amount:      order.total_value || 0,\n            paid_amount: 0,\n            status:      'unpaid',\n            invoice_ref: order.order_number,\n            due_date:    dueDate\n          });\n          if (!arErr) arCreated = true;\n        }\n      }\n    }\n\n    await logActivity(orderId, null, null, 'customer_edited', `Customer details edited by ${window.SM.AUTH.user?.name || 'Super Admin'}`);\n\n    ui().closeModal();\n    ui().toast(\n      arCreated\n        ? `Customer updated \u2014 receivable created in Accounts for ${util().formatCurrency(order.total_value || 0)}`\n        : 'Customer details updated',\n      'success', arCreated ? 6000 : 3000\n    );\n\n    // The same order appears in four separate views, each with its own\n    // independent render, across two different modules:\n    //   #ims-orders-tbody        \u2192 Order Management list      (load)\n    //   #ims-hist-tbody          \u2192 Order History              (loadHistory)\n    //   #ims-tracking-table-wrap \u2192 Logistics \u2192 Tracking       (IMS_LOGISTICS.loadTracking)\n    //   #ims-lost-table-wrap     \u2192 Logistics \u2192 Lost Orders    (IMS_LOGISTICS.loadLostOrders)\n    // Each render function bails out early if its own container isn't\n    // mounted, so calling them all is safe \u2014 whichever view is actually on\n    // screen refreshes, the rest no-op. Refreshing only the Orders views\n    // meant an edit made from Logistics didn't show until a full reload.\n    if (document.getElementById('ims-orders-tbody'))        load();\n    if (document.getElementById('ims-hist-tbody'))          loadHistory();\n    if (document.getElementById('ims-tracking-table-wrap')) window.IMS_LOGISTICS?.loadTracking?.();\n    if (document.getElementById('ims-lost-table-wrap'))     window.IMS_LOGISTICS?.loadLostOrders?.();\n  }\n\n  // \u2500\u2500\u2500 PRINT ORDER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  async function printOrder(orderId) {\n    const { data: order } = await db().select('orders', {\n      select: '*, platforms(name)',\n      eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true\n    });\n    if (!order) return;\n\n    // order_items RLS requires service role \u2014 embed in db() with noCompanyFilter\n    const { data: _printOrd } = await db().select('orders', { select: 'order_items(*)', eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true });\n    const orderItems = _printOrd?.order_items || [];\n\n    const isDropship = order.fulfillment_type === 'dropship';\n    const docTitle = isDropship ? 'Dropship Order' : order.order_type === 'wholesale' ? 'Sales Order' : 'Order Confirmation';\n    const statusLabels = {\n      confirmed:'Confirmed', picking:'Picking', packed:'Packed', dispatched:'Dispatched',\n      delivered:'Delivered', failed:'Failed delivery', lost:'Lost', cancelled:'Cancelled',\n      return_requested:'Return Requested', return_received:'Return Received', refunded:'Refunded'\n    };\n    const statusLabel = statusLabels[order.status] || order.status || '\u2014';\n\n    const itemRows = (orderItems||[]).map(i=>[\n      util().sanitize(i.product_name||'\u2014'),\n      util().sanitize(i.sku||'\u2014'),\n      String(i.quantity),\n      `\u00A3${(i.unit_price||0).toFixed(2)}`,\n      `\u00A3${(i.total_price||0).toFixed(2)}`\n    ]);\n    const itemTableHtml=window.PRINT.table({\n      colWidths:['38%','18%','10%','16%','18%'],\n      columns:[\n        {label:'Product'},{label:'SKU'},{label:'Qty',align:'r'},\n        {label:'Unit price',align:'r'},{label:'Total',align:'r'}\n      ],\n      rows:itemRows\n    });\n\n    const headerHtml=window.PRINT.header({\n      title:docTitle,\n      docRef:order.order_number,\n      rightLabel:'Deliver to',\n      rightName:util().sanitize(order.customer_name||order.end_customer_name||'\u2014'),\n      rightLines:[\n        util().sanitize(order.address||order.end_address||''),\n        util().sanitize(order.postcode||order.end_postcode||''),\n        util().sanitize(order.phone||order.end_customer_phone||''),\n        '',\n        `<strong>Order date:</strong> ${util().formatDate(order.created_at)}`,\n        `<strong>Platform:</strong> ${util().sanitize(order.platforms?.name||'\u2014')}`,\n        `<strong>Ref:</strong> ${util().sanitize(order.external_ref||'\u2014')}`,\n        `<strong>Status:</strong> ${statusLabel}`\n      ]\n    });\n\n    const summaryHtml=`\n      <table style=\"width:260px;margin-left:auto;border-collapse:collapse;font-size:10pt\">\n        <tr class=\"tr\"><td style=\"padding:3px 6px\"><strong>Order total</strong></td><td class=\"r\" style=\"padding:3px 6px\"><strong>\u00A3${(order.total_value||0).toFixed(2)}</strong></td></tr>\n      </table>`;\n\n    const notesHtml = order.notes\n      ? `<div style=\"margin-top:12px;font-size:9pt\"><strong>Notes:</strong> ${util().sanitize(order.notes)}</div>`\n      : '';\n\n    const page=`\n      ${headerHtml}\n      <div class=\"st\">Order items</div>\n      <hr class=\"rule\">\n      ${itemTableHtml}\n      <hr class=\"rule\">\n      ${summaryHtml}\n      <hr class=\"rule-dbl\" style=\"width:260px;margin-left:auto;margin-top:2px\">\n      ${notesHtml}\n      ${window.PRINT.pageFooter(['StockMaestro \u00A9 2026 ABSA Digital','Order '+(order.order_number||'')],1,1)}\n    `;\n\n    window.PRINT.renderDocument([page],`Order ${order.order_number}`);\n  }\n\n  // \u2500\u2500\u2500 IMPORT ORDERS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  function showImport() {\n    ui().openModal('Import orders', `\n      <div class=\"ims__alert ims__alert--info\"><i class=\"ti ti-info-circle\"></i>\n        <span>Upload a Shopify CSV export or a StockMaestro orders template. Download the template first to see the required format. Orders import with your specified date, reserve stock against the chosen warehouse, and land as Confirmed \u2014 ready to move through Picking \u2192 Packed \u2192 Logistics like any other order.</span>\n      </div>\n      <div class=\"ims__btn-group\" style=\"margin-bottom:16px\">\n        <button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_ORDERS.downloadTemplate()\"><i class=\"ti ti-download\"></i> Download template</button>\n      </div>\n      <div class=\"ims__form-group\">\n        <label class=\"ims__label\">Select CSV file</label>\n        <input type=\"file\" accept=\".csv\" id=\"ims-import-file\" class=\"ims__input\" onchange=\"window.IMS_ORDERS.previewImport(this)\">\n      </div>\n      <div id=\"ims-import-preview\"></div>\n    `, `\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--primary\" id=\"ims-import-commit-btn\" style=\"display:none\" onclick=\"window.IMS_ORDERS.commitImport()\"><i class=\"ti ti-check\"></i> Import orders</button>\n    `, 'lg');\n  }\n\n  function downloadTemplate() {\n    util().exportCSV(\n      ['Order date (YYYY-MM-DD)','Customer name','Postcode','Address','Phone','Email','External ref','Platform','Warehouse','Payment status (Paid/COD/Unpaid)','Product name','SKU','Quantity','Unit price','Notes'],\n      [\n        ['2026-05-12','John Smith','SW1A 1AA','1 Example Street London','07700900000','john@email.com','BATCH-0001','Amazon UK','Wern Industrial Estate','Paid','Example Chair','CHR-001','2','35.00',''],\n        ['2026-05-12','John Smith','SW1A 1AA','1 Example Street London','07700900000','john@email.com','BATCH-0001','Amazon UK','Wern Industrial Estate','Paid','Example Table','TBL-002','1','89.00','Second item, same order \u2014 same External ref']\n      ],\n      'orders_template'\n    );\n  }\n\n  let _importRows = [];\n\n  // Normalizes a CSV date value to YYYY-MM-DD. Accepts ISO (YYYY-MM-DD)\n  // as-is, and UK-format DD/MM/YYYY (1 or 2 digit day/month) \u2014 Excel\n  // commonly reformats date-like cells to the system locale (DD/MM/YYYY\n  // for UK Excel) even if the cell was originally typed as YYYY-MM-DD,\n  // so both must be accepted to avoid rejecting genuinely valid dates.\n  function _importParseDate(raw) {\n    const val = (raw || '').trim();\n    if (/^\\d{4}-\\d{2}-\\d{2}$/.test(val)) return val;\n    const m = val.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/);\n    if (m) {\n      const day = parseInt(m[1], 10), month = parseInt(m[2], 10), year = parseInt(m[3], 10);\n      if (day >= 1 && day <= 31 && month >= 1 && month <= 12) {\n        return `${year}-${String(month).padStart(2,'0')}-${String(day).padStart(2,'0')}`;\n      }\n    }\n    return '';\n  }\n\n  async function previewImport(input) {\n    const file = input.files?.[0];\n    if (!file) return;\n    const text = await file.text();\n    const { headers, rows } = util().parseCSV(text);\n    const preview = document.getElementById('ims-import-preview');\n    const commitBtn = document.getElementById('ims-import-commit-btn');\n\n    if (!rows.length) {\n      if (preview) preview.innerHTML = '<div class=\"ims__alert ims__alert--danger\"><i class=\"ti ti-alert-circle\"></i><span>No data rows found in file</span></div>';\n      return;\n    }\n\n    const isShopify = headers.includes('Name') && headers.includes('Lineitem name');\n    const todayStr = new Date().toISOString().split('T')[0];\n    _importRows = rows.map((row, i) => {\n      const get = col => {\n        const idx = headers.indexOf(col);\n        return idx >= 0 ? row[idx] || '' : '';\n      };\n      if (isShopify) {\n        return {\n          order_date:    _importParseDate(get('Created at')?.split(' ')[0]) || todayStr,\n          customer_name: get('Shipping Name') || get('Billing Name'),\n          postcode:      get('Shipping Zip'),\n          address:       [get('Shipping Address1'),get('Shipping Address2'),get('Shipping City')].filter(Boolean).join(', '),\n          phone:         get('Shipping Phone') || get('Billing Phone'),\n          email:         get('Email'),\n          platform_name: 'Website / Own Store',\n          warehouse_name: '',\n          payment_status: 'paid',\n          product_name:  get('Lineitem name'),\n          sku:           get('Lineitem sku'),\n          quantity:      parseInt(get('Lineitem quantity'))||1,\n          unit_price:    parseFloat(get('Lineitem price'))||0,\n          external_ref:  get('Name'),\n          valid:         !!(get('Shipping Name') && get('Lineitem name'))\n        };\n      } else {\n        const rawDate = get('Order date (YYYY-MM-DD)') || get('Order date');\n        const parsedDate = _importParseDate(rawDate);\n        return {\n          order_date:    parsedDate,\n          customer_name: get('Customer name'),\n          postcode:      get('Postcode'),\n          address:       get('Address'),\n          phone:         get('Phone'),\n          email:         get('Email'),\n          external_ref:  get('External ref'),\n          platform_name: get('Platform'),\n          warehouse_name: get('Warehouse'),\n          payment_status: (get('Payment status (Paid/COD/Unpaid)') || get('Payment status') || 'paid').toLowerCase(),\n          product_name:  get('Product name'),\n          sku:           get('SKU'),\n          quantity:      parseInt(get('Quantity'))||1,\n          unit_price:    parseFloat(get('Unit price'))||0,\n          notes:         get('Notes'),\n          valid:         !!(get('Customer name') && get('Product name') && parsedDate)\n        };\n      }\n    });\n\n    const valid   = _importRows.filter(r => r.valid).length;\n    const invalid = _importRows.length - valid;\n\n    if (preview) preview.innerHTML = `\n      <div class=\"ims__alert ims__alert--success\" style=\"margin-top:12px\"><i class=\"ti ti-check\"></i>\n        <span>Found <strong>${_importRows.length} rows</strong> \u2014 ${valid} valid, ${invalid} will be skipped</span>\n      </div>\n      <div class=\"ims__table-wrap\" style=\"max-height:200px;overflow-y:auto;margin-top:8px\">\n        <table class=\"ims__table\">\n          <thead><tr><th>Customer</th><th>Product</th><th>Qty</th><th>Price</th><th>Valid</th></tr></thead>\n          <tbody>${_importRows.slice(0,10).map(r => `\n            <tr>\n              <td>${util().sanitize(r.customer_name||'\u2014')}</td>\n              <td>${util().sanitize(r.product_name||'\u2014')}</td>\n              <td>${r.quantity}</td>\n              <td>${util().formatCurrency(r.unit_price)}</td>\n              <td>${r.valid?'<span class=\"ims__pill ims__pill--success\">\u2713</span>':'<span class=\"ims__pill ims__pill--danger\">\u2717</span>'}</td>\n            </tr>`).join('')}\n            ${_importRows.length > 10 ? `<tr><td colspan=\"5\" class=\"ims__table-empty\">...and ${_importRows.length-10} more rows</td></tr>` : ''}\n          </tbody>\n        </table>\n      </div>`;\n\n    if (commitBtn) commitBtn.style.display = valid > 0 ? 'inline-flex' : 'none';\n  }\n\n  // Looks up a product by SKU first (exact match), then by name (fuzzy),\n  // for linking bulk-imported order lines to real stock.\n  async function _importLookupProduct(sku, name) {\n    if (sku) {\n      const { data } = await db().select('products', { eq: { sku: sku.trim() }, select: 'id,name,sku' });\n      if (data?.[0]) return data[0];\n    }\n    if (name) {\n      const { data } = await db().select('products', { ilike: { name: name.trim() }, select: 'id,name,sku', limit: 1 });\n      if (data?.[0]) return data[0];\n    }\n    return null;\n  }\n\n  // Resolves unit price + cost price for a product, mirroring the\n  // platform \u2192 order-type \u2192 fallback logic used in manual order entry.\n  async function _importResolvePrice(client, productId, orderType, platformId) {\n    let price = 0;\n    if (platformId) {\n      const { data } = await client.from('product_prices').select('price').eq('product_id', productId).eq('price_type', 'platform').eq('platform_id', platformId).limit(1);\n      if (data?.[0]) price = data[0].price;\n    }\n    if (!price) {\n      const priceType = orderType === 'retail' ? 'rrp' : 'wholesale';\n      const { data } = await client.from('product_prices').select('price').eq('product_id', productId).eq('price_type', priceType).is('platform_id', null).limit(1);\n      if (data?.[0]) price = data[0].price;\n    }\n    if (!price) {\n      const fallbackType = orderType === 'retail' ? 'wholesale' : 'rrp';\n      const { data } = await client.from('product_prices').select('price').eq('product_id', productId).eq('price_type', fallbackType).is('platform_id', null).limit(1);\n      if (data?.[0]) price = data[0].price;\n    }\n    const { data: costRows } = await client.from('product_prices').select('price').eq('product_id', productId).eq('price_type', 'cost').is('platform_id', null).limit(1);\n    const costPrice = costRows?.[0]?.price || 0;\n    return { price: price || 0, costPrice };\n  }\n\n  async function commitImport() {\n    const valid = _importRows.filter(r => r.valid);\n    if (!valid.length) return;\n\n    const commitBtn = document.getElementById('ims-import-commit-btn');\n    if (commitBtn) { commitBtn.disabled = true; commitBtn.innerHTML = '<i class=\"ti ti-loader-2 ims__spin\"></i> Importing...'; }\n\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const { data: platforms } = await client.from('platforms').select('id,name,order_type').eq('is_active', true);\n    const platformMap = {};\n    (platforms||[]).forEach(p => { platformMap[p.name.toLowerCase()] = p; });\n\n    const { data: warehouses } = await db().select('warehouses', { eq: { is_active: true } });\n    const warehouseMap = {};\n    (warehouses||[]).forEach(w => { warehouseMap[w.name.toLowerCase()] = w.id; });\n    const defaultWarehouseId = (warehouses||[]).find(w => w.is_default)?.id || (warehouses||[])[0]?.id || null;\n    let defaultedWarehouseCount = 0;\n\n    let created = 0, itemsLinked = 0, itemsUnmatched = 0, stockShortfalls = 0;\n    const groups = {};\n    valid.forEach(row => {\n      const key = row.external_ref || `${row.customer_name}||${row.postcode}||${row.order_date}`;\n      if (!groups[key]) groups[key] = { ...row, items: [] };\n      groups[key].items.push({ product_name: row.product_name, sku: row.sku, quantity: row.quantity, unit_price: row.unit_price });\n    });\n\n    const groupEntries = Object.entries(groups);\n    const totalGroups = groupEntries.length;\n\n    // Inject a progress bar into the modal so a large import doesn't look\n    // like it's frozen \u2014 this can take real time (many sequential product\n    // lookups, price resolutions, and stock updates per order).\n    const preview = document.getElementById('ims-import-preview');\n    if (preview) {\n      preview.insertAdjacentHTML('afterbegin', `\n        <div id=\"ims-import-progress\" style=\"margin-bottom:14px\">\n          <div style=\"display:flex;justify-content:space-between;font-size:12px;color:var(--ims-text-muted);margin-bottom:5px\">\n            <span id=\"ims-import-progress-label\">Starting import...</span>\n            <span id=\"ims-import-progress-pct\">0%</span>\n          </div>\n          <div style=\"background:var(--ims-border);border-radius:999px;height:8px;overflow:hidden\">\n            <div id=\"ims-import-progress-bar\" style=\"height:8px;width:0%;background:var(--ims-accent);border-radius:999px;transition:width .25s\"></div>\n          </div>\n        </div>`);\n    }\n    const setImportProgress = (done, label) => {\n      const pct = totalGroups > 0 ? Math.round((done/totalGroups)*100) : 0;\n      const bar = document.getElementById('ims-import-progress-bar');\n      const pctEl = document.getElementById('ims-import-progress-pct');\n      const labelEl = document.getElementById('ims-import-progress-label');\n      if (bar) bar.style.width = pct+'%';\n      if (pctEl) pctEl.textContent = pct+'%';\n      if (labelEl) labelEl.textContent = label;\n    };\n\n    // Filter to ORD- prefixed orders only \u2014 'orders' also holds DSO- (dropship)\n    // and other-prefixed rows, so an unfiltered lookup can pick up the wrong\n    // prefix and generate numbers that collide with existing ORD- orders.\n    const { data: lastOrder } = await db().select('orders', { select: 'order_number', ilike: { order_number: 'ORD-' }, order: { col: 'order_number', asc: false }, limit: 1 });\n    let orderNum = lastOrder?.[0]?.order_number ? parseInt(lastOrder[0].order_number.split('-').pop()) || 0 : 0;\n\n    let processed = 0;\n    // Orders that could not be saved. Listed in the final message instead\n    // of being skipped silently.\n    const failedOrders = [];\n    for (const [key, group] of groupEntries) {\n      processed++;\n      setImportProgress(processed - 1, `Importing order ${processed} of ${totalGroups}: ${group.customer_name}`);\n\n      const platform = platformMap[(group.platform_name||'').toLowerCase()] || null;\n      const platformId = platform?.id || null;\n      const orderType = platform?.order_type || 'retail';\n\n      let warehouseId = warehouseMap[(group.warehouse_name||'').toLowerCase()] || null;\n      if (!warehouseId) { warehouseId = defaultWarehouseId; defaultedWarehouseCount++; }\n\n      const paymentStatus = ['paid','cod','unpaid'].includes(group.payment_status) ? group.payment_status : 'paid';\n      const unpaidExpiresAt = paymentStatus === 'unpaid' ? new Date(Date.now() + 7*24*60*60*1000).toISOString() : null;\n\n      let matchedCustomerId = null;\n      if (group.phone) {\n        const { data: cust } = await db().select('customers', { eq: { phone: group.phone.trim(), is_active: true }, maybeSingle: true });   // deactivated customers are not matched\n        if (cust) matchedCustomerId = cust.id;\n      }\n\n      // Same rule as manual order entry: a wholesale order that is not paid\n      // in full must be linked to a registered customer (matched here by\n      // phone), or nothing owed would ever reach Accounts. Skip it and list\n      // it in the end message so it can be fixed and imported again.\n      if (orderType === 'wholesale' && !matchedCustomerId && paymentStatus !== 'paid') {\n        failedOrders.push(`${group.customer_name} (wholesale and not paid, but no registered customer matches its phone number)`);\n        continue;\n      }\n\n      // Resolve each line item: link to a real product where possible,\n      // fill in a standard price if the CSV left it blank.\n      const resolvedItems = await Promise.all(group.items.map(async item => {\n        const product = await _importLookupProduct(item.sku, item.product_name);\n        let unitPrice = item.unit_price;\n        let costPrice = 0;\n        if (product) {\n          itemsLinked++;\n          if (!unitPrice) {\n            const resolved = await _importResolvePrice(client, product.id, orderType, platformId);\n            unitPrice = resolved.price;\n            costPrice = resolved.costPrice;\n          }\n        } else {\n          itemsUnmatched++;\n        }\n        return { ...item, product_id: product?.id || null, unit_price: unitPrice || 0, cost_price: costPrice };\n      }));\n\n      const total = resolvedItems.reduce((s, i) => s + (i.quantity * i.unit_price), 0);\n      const orderDateTime = new Date(`${group.order_date}T${new Date().toTimeString().split(' ')[0]}`);\n\n      // Retry-on-collision, same protection as manual order entry\n      let order, error;\n      for (let attempt = 0; attempt < 3; attempt++) {\n        orderNum++;\n        const orderNumber = `ORD-${String(orderNum).padStart(5,'0')}`;\n        const result = await db().insert('orders', {\n          order_number:      orderNumber,\n          platform_id:       platformId,\n          order_type:        orderType,\n          fulfillment_type:  'retail',\n          customer_name:     group.customer_name,\n          customer_id:       matchedCustomerId,\n          warehouse_id:      warehouseId,\n          postcode:          group.postcode,\n          address:           group.address,\n          phone:             group.phone,\n          email:             group.email,\n          external_ref:      group.external_ref,\n          notes:             group.notes,\n          status:            'confirmed',\n          created_at:        orderDateTime.toISOString(),\n          payment_status:    paymentStatus,\n          unpaid_expires_at: unpaidExpiresAt,\n          total_value:       total,\n          has_price_override: false,\n          created_by:        window.SM.AUTH.user?.id\n        });\n        order = result.data; error = result.error;\n        if (!error) break;\n        const isDupe = error.code === '23505' || /duplicate key/i.test(error.message||'');\n        if (!isDupe) break;\n      }\n\n      if (!error && order) {\n        // Save every item line in ONE insert: either all lines save or none\n        // do. order_items has no company_id column, so the raw client is used.\n        const _impClient = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n        const { error: impItemsError } = await _impClient.from('order_items').insert(resolvedItems.map(item => ({\n          order_id:     order.id,\n          product_id:   item.product_id,\n          product_name: item.product_name,\n          sku:          item.sku,\n          quantity:     item.quantity,\n          unit_price:   item.unit_price,\n          total_price:  item.quantity * item.unit_price,\n          cost_price:   item.cost_price\n        })));\n        if (impItemsError) {\n          // Undo the half-saved order so it never appears with no items.\n          const { error: undoError } = await db().remove('orders', order.id);\n          failedOrders.push(undoError\n            ? `${group.customer_name} (${order.order_number} was left with no items, please cancel it)`\n            : group.customer_name);\n          continue;\n        }\n\n        // Reserve stock one line at a time, same as manual order entry, so\n        // two lines of the same product cannot overwrite each other.\n        for (const item of resolvedItems) {\n          if (!item.product_id || !warehouseId) continue;\n          const { data: sl } = await db().select('stock_levels', {\n            eq: { product_id: item.product_id, warehouse_id: warehouseId }, maybeSingle: true, noCompanyFilter: true\n          });\n          if (sl) {\n            const available = (sl.quantity||0) - (sl.reserved_qty||0);\n            if (item.quantity > available) stockShortfalls++;\n            await db().update('stock_levels', sl.id, { reserved_qty: (sl.reserved_qty||0) + item.quantity });\n          } else {\n            stockShortfalls++;\n            await db().insert('stock_levels', { product_id: item.product_id, warehouse_id: warehouseId, quantity: 0, reserved_qty: item.quantity });\n          }\n        }\n\n        await logActivity(order.id, 'Order created', '', 'confirmed', `Bulk imported. Customer: ${group.customer_name}, Value: \u00A3${total.toFixed(2)}`);\n        created++;\n      } else {\n        failedOrders.push(group.customer_name);\n      }\n    }\n\n    ui().closeModal();\n    let msg = `${created} order(s) imported`;\n    if (itemsUnmatched > 0) msg += ` \u2014 ${itemsUnmatched} item(s) had no matching product (stock not reserved for these)`;\n    if (stockShortfalls > 0) msg += ` \u2014 ${stockShortfalls} item(s) exceeded available stock, please review`;\n    if (defaultedWarehouseCount > 0) msg += ` \u2014 ${defaultedWarehouseCount} order(s) used the default warehouse`;\n    if (failedOrders.length) msg += `. ${failedOrders.length} order(s) could not be saved and were skipped: ${failedOrders.join(', ')}. Please check these and import them again`;\n    ui().toast(msg, failedOrders.length ? 'error' : (itemsUnmatched||stockShortfalls ? 'warning' : 'success'), failedOrders.length ? 15000 : 8000);\n    _importRows = [];\n    load();\n  }\n\n  // \u2500\u2500\u2500 BINDINGS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  window.addEventListener('ims:panel', e => {\n    if (e.detail.panel === 'orders') {\n      _orderItems = [];\n      load();\n      // Check for expired unpaid orders on every panel open\n      setTimeout(checkUnpaidExpiry, 800);\n    }\n  });\n\n  window.addEventListener('ims:ready', () => {\n    document.getElementById('ims-orders-new-btn')?.addEventListener('click', showNewOrder);\n    document.getElementById('ims-orders-import-btn')?.addEventListener('click', showImport);\n    document.getElementById('ims-orders-history-btn')?.addEventListener('click', showHistory);\n    ['ims-orders-search','ims-orders-status','ims-orders-platform','ims-orders-type'].forEach(id => {\n      const el = document.getElementById(id);\n      if (!el) return;\n      el.addEventListener('input', util().debounce(load, 350));\n      el.addEventListener('change', load);\n    });\n  });\n\n  window.IMS_ORDERS = { arrangeVanPickup, exportHistoryItems, resendShopify,\n    load, openOrder, updateStatus, cancelOrder, showNewOrder, onPlatformChange,\n    fillCustomer, fillCustomerFromAccount, clearCustomer, addItem, updateItem, removeItem, updateTotal, checkOverride,\n    onWarehouseChange, toggleAllocationPanel, releaseFromAllocation, undoRelease,\n    searchProduct, selectProduct, saveOrder,\n    updateCustomerLock, clearPickedCustomer, addNewCustomerFromOrder,\n    showQuickAddCustomer, saveQuickAddCustomer, cancelQuickAddCustomer,\n    toggleAltDelivery,\n    editOrderCustomer, searchEditCustomer, selectEditCustomer, saveOrderCustomer, amendOrder, addService,\n    printOrder,\n    showImport, downloadTemplate, previewImport, commitImport,\n    markPaid, confirmPayment, showReturnModal, submitReturn,\n    markReturnReceived, processRefund, showRefundNoReturn, confirmRefundNoReturn,\n    showHistory, loadHistory, renderHistoryTable, goHistoryPage, viewOrderFromHistory,\n    showActive, exportHistory, clearHistoryFilters, showActivityLog,\n    checkUnpaidExpiry, convertUnpaid, cancelUnpaid,\n    cancelBatch, showBatchPaymentReview, confirmBatchPayment,\n    toggleSelectOrder, toggleSelectAll, clearSelection, applyBulkStatus,\n    goPage: (p) => { _currentPage = p; renderTable(); }\n  };\n\n})();\n"],
  "mappings": "CAAC,UAAY,CACX,aAEA,MAAM,EAAI,IAAM,OAAO,GACjB,GAAK,IAAM,OAAO,GAAG,GACrB,GAAK,IAAM,OAAO,GAAG,GACrB,KAAO,IAAM,OAAO,GAAG,KAG7B,IAAI,QAAU,CAAC,EACX,WAAa,CAAC,EACd,aAAe,EACf,YAAc,CAAC,EACf,YAAc,KACd,iBAAmB,KAOnB,kBAAoB,KACpB,wBAA0B,GAC1B,yBAA2B,GAC3B,gBAAkB,IAAI,IAGtB,eAAiB,CAAC,EAClB,aAAe,EAEnB,eAAe,YAAY,aAAe,KAAM,CAC9C,MAAM,IAAM,IAAI,KACV,WAAa,IAAI,KAAK,IAAI,YAAY,EAAG,IAAI,SAAS,EAAG,CAAC,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,EACtF,MAAQ,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,EACtC,EAAI,cAAgB,CAAC,EAGrB,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3F,CAAC,CAAE,KAAM,SAAU,EAAG,CAAE,KAAM,QAAS,CAAC,EAAI,MAAM,QAAQ,IAAI,CAClE,OAAO,KAAK,WAAW,EAAE,OAAO,SAAS,EAAE,GAAG,YAAa,EAAI,EAAE,MAAM,MAAM,EAC7E,OAAO,KAAK,UAAU,EAAE,OAAO,SAAS,EAAE,MAAM,MAAM,CACxD,CAAC,EAEK,UAAY,WAAW,CAAC,GAAG,IAAI,GAAG,kBAAkB,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,IAAI,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,EAC3I,aAAe,UAAU,CAAC,GAAG,IAAI,GAAG,kBAAkB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,WAAW,EAAE,IAAI,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,EAElJ,GAAG,EAAE,UAAU,gBAAiB;AAAA;AAAA;AAAA;AAAA,4EAIwC,EAAE,MAAQ,UAAU;AAAA;AAAA;AAAA;AAAA,0EAItB,EAAE,IAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wCAM/C,EAAE,SAAS,YAAY,WAAW,EAAE;AAAA,sCACtC,EAAE,SAAS,UAAU,WAAW,EAAE;AAAA,qCACnC,EAAE,SAAS,SAAS,WAAW,EAAE;AAAA,yCAC7B,EAAE,SAAS,aAAa,WAAW,EAAE;AAAA,wCACtC,EAAE,SAAS,YAAY,WAAW,EAAE;AAAA,wCACpC,EAAE,SAAS,YAAY,WAAW,EAAE;AAAA,uCACrC,EAAE,SAAS,WAAW,WAAW,EAAE;AAAA,+CAC3B,EAAE,SAAS,mBAAmB,WAAW,EAAE;AAAA,8CAC5C,EAAE,SAAS,kBAAkB,WAAW,EAAE;AAAA,mCACrD,EAAE,SAAS,OAAO,WAAW,EAAE;AAAA,qCAC7B,EAAE,SAAS,SAAS,WAAW,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAOjC,EAAE,UAAU,SAAS,WAAW,EAAE;AAAA,mCACpC,EAAE,UAAU,OAAO,WAAW,EAAE;AAAA,sCAC7B,EAAE,UAAU,UAAU,WAAW,EAAE;AAAA,uCAClC,EAAE,UAAU,WAAW,WAAW,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qDAMtB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oDAMT,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAO1B,EAAE,OAAO,SAAS,WAAW,EAAE;AAAA,wCAC5B,EAAE,OAAO,YAAY,WAAW,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA,2GAKiC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAuBjI;AAAA;AAAA;AAAA;AAAA,MAIA,IAAI,EAEP,YAAY,EAEZ,WAAW,IAAM,CACf,SAAS,eAAe,iBAAiB,GAAG,iBAAiB,UAAW,GAAK,CACvE,EAAE,MAAQ,SAAS,YAAY,CACrC,CAAC,CACH,EAAG,GAAG,CACR,CASA,eAAe,qBAAqB,QAAQ,CAC1C,MAAM,aAAe,CACnB,KAAM,SAAS,eAAe,eAAe,GAAG,OAAS,GACzD,GAAI,SAAS,eAAe,aAAa,GAAG,OAAS,GACrD,OAAQ,SAAS,eAAe,iBAAiB,GAAG,OAAS,GAC7D,QAAS,SAAS,eAAe,kBAAkB,GAAG,OAAS,GAC/D,SAAU,SAAS,eAAe,mBAAmB,GAAG,OAAS,GACjE,QAAS,SAAS,eAAe,kBAAkB,GAAG,OAAS,GAC/D,KAAM,SAAS,eAAe,eAAe,GAAG,OAAS,GACzD,OAAQ,SAAS,eAAe,iBAAiB,GAAG,OAAS,EAC/D,EACA,MAAM,UAAU,OAAO,EACvB,WAAW,IAAM,CACf,MAAM,SAAW,SAAS,cAAc,iDAAiD,EACtF,WAAU,SAAS,QAAU,IAAM,YAAY,YAAY,EAChE,EAAG,GAAG,CACR,CAEA,SAAS,qBAAsB,CAC7B,CAAC,kBAAkB,mBAAmB,oBAAoB,mBAAmB,gBAAgB,iBAAiB,EAAE,QAAQ,IAAM,CAC5H,MAAM,GAAK,SAAS,eAAe,EAAE,EACjC,KAAI,GAAG,MAAQ,GACrB,CAAC,EACD,YAAY,CACd,CAEI,eAAe,aAAc,CAC/B,MAAM,MAAQ,SAAS,eAAe,gBAAgB,EACtD,GAAI,CAAC,MAAO,OACZ,MAAM,UAAY,mGAElB,MAAM,KAAa,SAAS,eAAe,eAAe,GAAG,OAAS,GAChE,GAAa,SAAS,eAAe,aAAa,GAAG,OAAS,GAC9D,OAAa,SAAS,eAAe,iBAAiB,GAAG,OAAO,KAAK,EAAE,YAAY,GAAK,GACxF,OAAa,SAAS,eAAe,iBAAiB,GAAG,OAAS,GAClE,QAAa,SAAS,eAAe,kBAAkB,GAAG,OAAS,GACnE,WAAa,SAAS,eAAe,mBAAmB,GAAG,OAAS,GACpE,UAAa,SAAS,eAAe,kBAAkB,GAAG,OAAS,GACnE,UAAa,SAAS,eAAe,eAAe,GAAG,OAAS,GAEhE,UAAY,OAAO,GAAG,KAAK,SAAS,GACpC,SAAW,CACf,OAAQ,2SACR,MAAO,CAAE,IAAK,aAAc,IAAK,EAAM,EACvC,gBAAiB,GACjB,IAAK,CAAE,iBAAkB,UAAW,EACpC,GAAI,CAAE,WAAY,SAAU,CAC9B,EACI,OAAY,SAAS,IAAM,CAAE,WAAY,KAAK,WAAY,GAC1D,KAAY,SAAS,IAAM,CAAE,WAAY,GAAG,WAAY,GACxD,SAAY,SAAS,GAAK,CAAE,GAAG,SAAS,GAAI,MAAe,GAC3D,UAAY,SAAS,GAAK,CAAE,GAAG,SAAS,GAAI,eAAgB,OAAQ,GACpE,aAAY,SAAS,GAAK,CAAE,GAAG,SAAS,GAAI,YAAa,UAAW,GACpE,YAAY,SAAS,GAAK,CAAE,GAAG,SAAS,GAAI,WAAY,SAAU,GAEtE,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,aAAa,SAAU,QAAQ,EAC7D,GAAI,MAAO,CACT,MAAM,UAAY,wDAAwD,MAAM,OAAO,aACvF,MACF,CAGA,MAAM,cAAgB,MAAM,CAAC,GAAG,IAAI,GAAK,EAAE,EAAE,EAC7C,IAAI,aAAe,CAAC,EAChB,aAAa,SACG,MAAM,cAAc,YAAY,GACtC,CAAC,GAAG,QAAQ,GAAK,CACtB,aAAa,EAAE,QAAQ,IAAG,aAAa,EAAE,QAAQ,EAAI,CAAC,GAC3D,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,CACjC,CAAC,EAEH,IAAI,QAAU,MAAM,CAAC,GAAG,IAAI,IAAM,CAChC,GAAG,EACH,MAAO,aAAa,EAAE,EAAE,GAAK,CAAC,EAC9B,SAAU,EAAE,WAAW,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,oBAAoB,GAAG,UAAU,MAAQ,GAC/E,UAAW,EAAE,WAAW,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,oBAAoB,GAAG,iBAAmB,GACjF,YAAa,EAAE,WAAW,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,oBAAoB,GAAG,YAAc,EAChF,EAAE,EAGE,YAAW,OAAS,OAAO,OAAO,GAAK,EAAE,aAAe,SAAS,GACjE,SACF,OAAS,OAAO,OAAO,GAAK,CAC1B,MAAM,KAAO,EAAE,MAAM,IAAI,GAAG,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,YAAY,EACnD,MAAQ,EAAE,MAAM,IAAI,GAAG,EAAE,YAAY,EAAE,KAAK,GAAG,EAAE,YAAY,EACnE,OACE,EAAE,cAAc,YAAY,EAAE,SAAS,MAAM,GAC7C,EAAE,eAAe,YAAY,EAAE,SAAS,MAAM,GAC9C,EAAE,UAAU,YAAY,EAAE,SAAS,MAAM,GACzC,EAAE,cAAc,YAAY,EAAE,SAAS,MAAM,GAC7C,EAAE,UAAU,YAAY,EAAE,SAAS,MAAM,GACzC,KAAK,SAAS,MAAM,GACpB,MAAM,SAAS,MAAM,CAEzB,CAAC,GAGH,eAAiB,OACjB,aAAe,EAGf,MAAM,QAAU,SAAS,eAAe,gBAAgB,EACxD,GAAI,QAAS,CACX,MAAM,SAAY,OAAO,OAAO,CAAC,EAAE,IAAI,GAAG,EAAE,aAAa,GAAG,CAAC,EACvD,UAAY,OAAO,OAAO,GAAG,EAAE,SAAS,WAAW,EAAE,OACrD,UAAY,OAAO,OAAO,GAAG,EAAE,SAAS,WAAW,EAAE,OACrD,SAAY,OAAO,OAAO,GAAG,EAAE,SAAS,UAAU,EAAE,OACpD,OAAY,OAAO,OAAO,GAAG,EAAE,iBAAiB,QAAQ,EAAE,OAChE,QAAQ,UAAY,CAClB,CAAC,EAAE,eAAiB,EAAE,OAAO,OAA0B,EAAE,EAAE,EAC3D,CAAC,EAAE,UAAiB,EAAE,KAAK,EAAE,eAAe,QAAQ,EAAG,EAAE,SAAS,EAClE,CAAC,EAAE,YAAiB,EAAE,UAAiC,EAAE,SAAS,EAClE,CAAC,EAAE,YAAiB,EAAE,UAAiC,EAAE,SAAS,EAClE,CAAC,EAAE,WAAiB,EAAE,SAAiC,EAAE,QAAQ,EACjE,CAAC,EAAE,SAAiB,EAAE,OAAiC,EAAE,QAAQ,CACnE,EAAE,IAAI,GAAG;AAAA,8DAC+C,EAAE,CAAC;AAAA,qCAC5B,EAAE,EAAE,qBAAqB,EAAE,EAAE,EAAE,4BAA4B,EAAE,CAAC;AAAA,aACtF,EAAE,KAAK,EAAE,CAClB,CAEA,mBAAmB,CACrB,CAEA,SAAS,oBAAqB,CAC5B,MAAM,MAAQ,SAAS,eAAe,gBAAgB,EAChD,MAAQ,SAAS,eAAe,qBAAqB,EAC3D,GAAI,CAAC,MAAO,OACZ,MAAM,MAAQ,eAAe,OAC7B,GAAI,CAAC,MAAO,CACV,MAAM,UAAY,uGACd,QAAO,MAAM,UAAY,IAC7B,MACF,CACA,MAAM,OAAS,aAAa,GAAG,GACzB,KAAQ,eAAe,MAAM,MAAO,MAAM,EAAS,EA6BzD,GA5BA,MAAM,UAAY,KAAK,IAAI,GAAG,CAC5B,MAAM,SAAW,EAAE,MAAM,IAAI,GAAG,CAC9B,MAAM,KAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,EACzC,IAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EACtC,OAAO,KAAQ,IAAM,GAAG,IAAI,KAAK,GAAG,IAAM,KAAQ,GACpD,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,GAAK,SAC3B,IAAO,EAAE,MAAM,OAAO,CAAC,EAAE,IAAI,GAAG,EAAE,UAAU,GAAG,CAAC,GAAK,SAC3D,MAAO;AAAA,uFAC0E,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC;AAAA,qCAC1G,KAAK,EAAE,SAAS,EAAE,cAAc,QAAG,CAAC;AAAA,cAC3D,KAAK,EAAE,SAAS,EAAE,eAAe,QAAG,CAAC;AAAA,qCACd,KAAK,EAAE,SAAS,EAAE,WAAW,MAAM,QAAG,CAAC;AAAA,qCACvC,QAAQ;AAAA,uCACN,GAAG;AAAA,cAC5B,KAAK,EAAE,eAAe,EAAE,WAAW,CAAC;AAAA,qCACb,KAAK,EAAE,WAAW,EAAE,UAAU,CAAC;AAAA,cACtD,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC;AAAA,cACrB,EAAE,eAAe,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,QAAG;AAAA,qCAC3B,KAAK,EAAE,SAAS,EAAE,SAAS,QAAG,CAAC;AAAA;AAAA;AAAA,wIAGoE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;AAAA,+HAC3B,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC;AAAA;AAAA;AAAA,YAI/K,CAAC,EAAE,KAAK,EAAE,EAEN,MAAO,CACT,MAAM,MAAQ,KAAK,KAAK,MAAM,EAAS,EACvC,MAAM,UAAY,OAAO,EAAI,GAC3B,wCAAwC,KAAK,IAAI,MAAM,EAAE,KAAK,CAAC,SAAI,KAAK,IAAI,aAAa,GAAU,KAAK,CAAC,OAAO,KAAK,UACrH,MAAM,KAAK,CAAC,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,wCAAwC,EAAE,IAAI,aAAa,oBAAoB,qBAAqB,8CAA8C,EAAE,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,CACvN,CACF,CAEA,SAAS,cAAc,EAAG,CAAE,aAAa,EAAG,mBAAmB,CAAG,CAClE,SAAS,YAAa,CAAE,KAAK,CAAG,CAEhC,eAAe,gBAAgB,QAAS,YAAa,CACnD,MAAM,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3F,CAAE,KAAM,IAAK,EAAI,MAAM,OAAO,KAAK,oBAAoB,EAC1D,OAAO,GAAG,EACV,GAAG,WAAY,OAAO,EACtB,MAAM,aAAc,CAAC,UAAW,EAAI,CAAC,EAElC,MAAQ,MAAM,CAAC,GAAG,QAAU,MAAM,CAAC,GAAG,IAAI,GAAG;AAAA;AAAA,wDAEC,KAAK,EAAE,WAAW,EAAE,UAAU,CAAC;AAAA,qCAClD,KAAK,EAAE,SAAS,EAAE,WAAW,QAAQ,CAAC;AAAA,sCACrC,KAAK,EAAE,SAAS,EAAE,QAAQ,QAAG,CAAC;AAAA,iEACH,EAAE,UAAU,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,QAAG;AAAA,qCACxE,EAAE,UAAU,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,QAAG;AAAA,iEAChB,EAAE,MAAM,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAG;AAAA,YACzF,EAAE,KAAK,EAAE,EACf,6FAEF,GAAG,EAAE,UAAU,iBAAiB,WAAW,GAAI;AAAA;AAAA;AAAA;AAAA,mBAIhC,IAAI;AAAA;AAAA;AAAA,MAGhB,8FAA+F,IAAI,CACxG,CAMA,eAAe,aAAa,MAAO,KAAM,CACvC,MAAM,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAAG,IAAM,CAAC,EAC3G,QAAS,MAAQ,EAAG,MAAQ,IAAQ,OAAS,IAAM,CACjD,IAAI,EAAI,OAAO,KAAK,KAAK,EAAE,OAAO,KAAK,QAAU,GAAG,EAChD,CAAC,KAAK,iBAAmB,OAAO,GAAG,KAAK,SAAS,KAAI,EAAI,EAAE,GAAG,aAAc,OAAO,GAAG,KAAK,QAAQ,EAAE,GACzG,OAAO,QAAQ,KAAK,IAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAG,CAAC,IAAM,CAAE,EAAI,EAAE,GAAG,EAAG,CAAC,CAAG,CAAC,EACrE,OAAO,QAAQ,KAAK,KAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAG,CAAC,IAAM,CAAE,EAAI,EAAE,IAAI,EAAG,CAAC,CAAG,CAAC,EACvE,OAAO,QAAQ,KAAK,KAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAG,CAAC,IAAM,CAAE,EAAI,EAAE,IAAI,EAAG,CAAC,CAAG,CAAC,EACvE,OAAO,QAAQ,KAAK,KAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAG,CAAC,IAAM,CAAE,EAAI,EAAE,IAAI,EAAG,CAAC,CAAG,CAAC,EACnE,KAAK,QAAO,EAAI,EAAE,MAAM,KAAK,MAAM,IAAK,CAAE,UAAW,KAAK,MAAM,MAAQ,EAAM,CAAC,GACnF,EAAI,EAAE,MAAM,KAAM,CAAE,UAAW,EAAK,CAAC,EACrC,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,EAAE,MAAM,MAAO,MAAQ,GAAG,EACxD,GAAI,MAAO,MAAO,CAAE,KAAM,IAAI,OAAS,IAAM,KAAM,KAAM,EAEzD,GADA,IAAI,KAAK,GAAI,MAAQ,CAAC,CAAE,EACpB,CAAC,MAAQ,KAAK,OAAS,IAAM,KACnC,CACA,MAAO,CAAE,KAAM,IAAK,MAAO,IAAK,CAClC,CACA,eAAe,cAAc,SAAU,CACrC,MAAM,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAAG,IAAM,CAAC,EAC3G,QAAS,EAAI,EAAG,EAAI,SAAS,OAAQ,GAAK,IAAK,CAC7C,MAAM,KAAO,SAAS,MAAM,EAAG,EAAI,GAAG,EACtC,QAAS,MAAQ,GAAK,OAAS,IAAM,CACnC,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,OAAO,KAAK,aAAa,EAAE,OAAO,8DAA8D,EAC3H,GAAG,WAAY,IAAI,EAAE,MAAM,KAAM,CAAE,UAAW,EAAK,CAAC,EAAE,MAAM,MAAO,MAAQ,GAAG,EACjF,GAAI,MAAO,OAAO,IAElB,GADA,IAAI,KAAK,GAAI,MAAQ,CAAC,CAAE,EACpB,CAAC,MAAQ,KAAK,OAAS,IAAM,KACnC,CACF,CACA,OAAO,GACT,CAGA,SAAS,oBAAqB,CAC5B,GAAI,CAAC,eAAe,OAAQ,CAAE,GAAG,EAAE,MAAM,sBAAsB,SAAS,EAAG,MAAQ,CACnF,MAAM,KAAO,SAAS,eAAe,eAAe,GAAG,OAAO,GACxD,GAAO,SAAS,eAAe,aAAa,GAAG,OAAO,GACtD,KAAO,CAAC,EACd,eAAe,QAAQ,GAAK,CAC1B,MAAM,KAAO,CAAC,EAAE,aAAc,EAAE,cAAc,GAAI,KAAK,EAAE,WAAW,EAAE,UAAU,EAAG,EAAE,eAAe,GAAI,EAAE,UAAU,GAAI,EAAE,WAAW,MAAM,GAAI,EAAE,YAAY,GAAI,EAAE,QAAQ,GAAI,EAAE,gBAAgB,EAAE,EACnM,GAAI,CAAC,EAAE,MAAM,OAAQ,CAAE,KAAK,KAAK,CAAC,GAAG,KAAM,GAAI,GAAI,EAAG,GAAI,EAAE,CAAC,EAAG,MAAQ,CACxE,EAAE,MAAM,QAAQ,GAAK,KAAK,KAAK,CAAC,GAAG,KAAM,EAAE,KAAK,GAAI,EAAE,cAAc,GAAI,EAAE,UAAU,EAClF,EAAE,YAAc,KAAO,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAI,GAAI,EAAE,aAAe,KAAO,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC,IAAM,OAAO,EAAE,UAAU,GAAG,IAAI,OAAO,EAAE,QAAQ,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAC5L,CAAC,EACD,KAAK,EAAE,UAAU,CAAC,UAAU,eAAe,OAAO,WAAW,WAAW,WAAW,aAAa,SAAS,UAAU,MAAM,UAAU,MAAM,aAAa,YAAY,EAChK,KAAM,eAAe,IAAI,OAAO,EAAE,EAAE,CACxC,CAEA,eAAe,eAAgB,CAC7B,GAAI,CAAC,eAAe,OAAQ,CAAE,GAAG,EAAE,MAAM,sBAAsB,SAAS,EAAG,MAAQ,CACnF,MAAM,KAAO,SAAS,eAAe,eAAe,GAAG,OAAO,GACxD,GAAO,SAAS,eAAe,aAAa,GAAG,OAAO,GAC5D,KAAK,EAAE,UACL,CAAC,UAAU,eAAe,WAAW,WAAW,WAAW,aAAa,SAAS,aAAa,MAAM,QAAQ,OAAO,SAAS,UAAU,iBAAiB,UAAU,WAAW,eAAe,EAC3L,eAAe,IAAI,GAAG,CACpB,EAAE,aACF,EAAE,cAAc,GAChB,EAAE,eAAe,GACjB,EAAE,UAAU,GACZ,EAAE,WAAW,MAAM,GACnB,EAAE,YAAY,GACd,EAAE,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,EAAE,KAAK,GAAG,EAClC,EAAE,MAAM,IAAI,GAAG,EAAE,cAAc,EAAE,EAAE,KAAK,GAAG,EAC3C,EAAE,MAAM,OAAO,CAAC,EAAE,IAAI,GAAG,EAAE,UAAU,GAAG,CAAC,GACxC,EAAE,aAAa,GAAG,QAAQ,CAAC,EAC5B,KAAK,EAAE,WAAW,EAAE,UAAU,EAC9B,EAAE,QAAQ,GACV,EAAE,gBAAgB,GAClB,EAAE,gBAAgB,GAClB,EAAE,SAAS,GACX,EAAE,UAAU,GACZ,EAAE,eAAe,EACnB,CAAC,EACD,iBAAiB,IAAI,OAAO,EAAE,EAChC,CACF,CAIA,eAAe,YAAY,QAAS,OAAQ,SAAS,GAAI,SAAS,GAAI,MAAM,GAAI,CAC9E,GAAI,CACF,MAAM,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3F,KAAO,OAAO,GAAG,KAAK,KAC5B,MAAM,OAAO,KAAK,oBAAoB,EAAE,OAAO,CAC7C,SAAY,QACZ,QAAY,MAAM,IAAM,KACxB,UAAY,MAAM,MAAQ,MAAM,OAAS,SACzC,OACA,UAAY,SAAW,OAAO,QAAQ,EAAI,KAC1C,UAAY,SAAW,OAAO,QAAQ,EAAI,KAC1C,MAAY,OAAS,KACrB,WAAY,IAAI,KAAK,EAAE,YAAY,CACrC,CAAC,CACH,OAAQ,EAAG,CAAE,QAAQ,KAAK,iBAAkB,EAAE,OAAO,CAAG,CAC1D,CAGA,eAAe,MAAO,CACpB,MAAM,MAAQ,SAAS,eAAe,kBAAkB,EACxD,GAAI,CAAC,MAAO,OACZ,MAAM,UAAY,mGAClB,gBAAgB,MAAM,EAEtB,MAAM,OAAW,SAAS,eAAe,mBAAmB,GAAG,OAAO,KAAK,GAAK,GAC1E,OAAW,SAAS,eAAe,mBAAmB,GAAG,OAAS,GAClE,SAAW,SAAS,eAAe,qBAAqB,GAAG,OAAS,GACpE,KAAW,SAAS,eAAe,iBAAiB,GAAG,OAAS,GAEhE,KAAO,CACX,OAAQ,yJACR,MAAO,CAAE,IAAK,aAAc,IAAK,EAAM,CACzC,EACA,KAAK,IAAM,CAAE,iBAAkB,UAAW,EACtC,QAAU,SAAW,UACvB,KAAK,GAAK,CAAE,MAAO,EACT,SAIV,KAAK,GAAK,CAAE,OAAQ,CAAC,YAAa,SAAS,CAAE,GAE3C,WAAU,KAAK,GAAK,CAAE,GAAG,KAAK,GAAI,YAAa,QAAS,GACxD,OAAM,KAAK,GAAK,CAAE,GAAG,KAAK,GAAI,WAAY,IAAK,GAEnD,GAAI,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,IAAI,EACtD,GAAI,MAAO,CAAE,GAAG,EAAE,MAAM,wBAAyB,OAAO,EAAG,MAAQ,CAEnE,MAAM,UAAY,MAAM,CAAC,GAAG,IAAI,GAAK,EAAE,EAAE,EACzC,IAAI,SAAW,CAAC,EAChB,GAAI,SAAS,OAAQ,CACnB,MAAM,UAAY,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC9F,CAAE,KAAM,KAAM,EAAI,MAAM,UAAU,KAAK,aAAa,EACvD,OAAO,oCAAoC,EAC3C,GAAG,WAAY,QAAQ,GACzB,OAAO,CAAC,GAAG,QAAQ,GAAK,CAClB,SAAS,EAAE,QAAQ,IAAG,SAAS,EAAE,QAAQ,EAAI,CAAC,GACnD,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,CAC7B,CAAC,CACH,CAEA,IAAI,QAAU,MAAM,CAAC,GAAG,IAAI,IAAM,CAAE,GAAG,EAAG,MAAO,SAAS,EAAE,EAAE,GAAK,CAAC,CAAE,EAAE,EAExE,GAAI,OAAQ,CACV,MAAM,EAAI,OAAO,YAAY,EAC7B,OAAS,OAAO,OAAO,GAAK,CAC1B,MAAM,MAAQ,EAAE,MAAM,IAAI,GAAK,EAAE,cAAc,EAAE,EAAE,KAAK,GAAG,EAAE,YAAY,EACnE,KAAQ,EAAE,MAAM,IAAI,GAAK,EAAE,KAAK,EAAE,EAAE,KAAK,GAAG,EAAE,YAAY,EAChE,OACE,EAAE,cAAc,YAAY,EAAE,SAAS,CAAC,GACxC,EAAE,eAAe,YAAY,EAAE,SAAS,CAAC,GACzC,EAAE,UAAU,YAAY,EAAE,SAAS,CAAC,GACpC,MAAM,SAAS,CAAC,GAChB,KAAK,SAAS,CAAC,CAEnB,CAAC,CACH,CAEA,OAAS,OAAO,IAAI,IAAM,CAAE,GAAG,EAAG,SAAU,KAAK,EAAE,UAAU,CAAC,CAAE,EAAE,EAC9D,SAAW,YAAW,OAAS,OAAO,OAAO,GAAK,EAAE,QAAQ,GAEhE,QAAU,OACV,aAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,GAAG,EAAE,YAAY,mBACf,OAAO,OAAO,GAAK,CAAC,YAAY,UAAU,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAK,EAAE,QAAQ,EAAE,MACxF,CACF,CAGA,eAAe,mBAAoB,CACjC,MAAM,IAAM,IAAI,KACV,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3F,CAAE,KAAM,QAAS,EAAI,MAAM,OAAO,KAAK,QAAQ,EAClD,OAAO,wEAAwE,EAC/E,GAAG,iBAAiB,QAAQ,EAC5B,GAAG,mBAAmB,QAAQ,EAC9B,IAAI,SAAS,KAAK,sCAAsC,EACxD,IAAI,oBAAqB,IAAI,YAAY,CAAC,EAC1C,MAAM,mBAAmB,EAE5B,GAAI,CAAC,UAAU,OAAQ,OAGvB,MAAM,KAAO,SAAS,IAAI,GAAK;AAAA;AAAA,sBAEb,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC;AAAA,cACvC,KAAK,EAAE,SAAS,EAAE,eAAe,QAAG,CAAC;AAAA,cACrC,KAAK,EAAE,eAAe,EAAE,WAAW,CAAC;AAAA,8CACJ,KAAK,EAAE,WAAW,EAAE,iBAAiB,CAAC;AAAA;AAAA;AAAA,gHAG4B,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;AAAA,+GACnB,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;AAAA,8GACnB,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC;AAAA;AAAA;AAAA,YAGtJ,EAAE,KAAK,EAAE,EAEjB,GAAG,EAAE,UAAU,UAAK,SAAS,MAAM,gCAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAQrD,IAAI;AAAA;AAAA;AAAA,MAGhB,gGAAiG,IAAI,CAC1G,CAEA,eAAe,cAAc,QAAS,UAAW,CAC/C,MAAM,UAAY,YAAc,SAAW,IAAI,KAAK,KAAK,IAAI,EAAI,MAAe,EAAE,YAAY,EAAI,KAClG,MAAM,GAAG,EAAE,OAAO,SAAU,QAAS,CACnC,eAAmB,UACnB,kBAAmB,SACrB,CAAC,EACD,MAAM,YAAY,QAAS,2BAA4B,SAAU,UAAW,+BAA+B,EAC3G,GAAG,EAAE,MAAM,sBAAsB,SAAS,GAAI,SAAS,EAEvD,MAAM,MAAQ,SAAS,eAAe,gBAAgB,EAClD,QACW,MAAM,iBAAiB,UAAU,EACzC,QAAQ,KAAO,CACd,IAAI,UAAU,SAAS,OAAO,GAAG,IAAI,OAAO,CAClD,CAAC,EACiB,MAAM,iBAAiB,UAAU,EAAE,QACrC,GAAG,EAAE,WAAW,GAElC,KAAK,CACP,CAEA,eAAe,aAAa,QAAS,YAAa,CAChD,GAAG,EAAE,QAAQ,+BAA+B,WAAW,yDAA0D,SAAY,CAE3H,KAAM,CAAE,KAAM,UAAW,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAAE,OAAQ,gDAAiD,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EAC7K,MAAQ,YAAY,aAAe,CAAC,EACpC,KAAO,YAAY,aAIzB,UAAW,QAAS,OAAO,CAAC,EAAI,CAC9B,GAAI,CAAC,KAAK,WAAY,SACtB,KAAM,CAAE,KAAM,EAAG,EAAI,KACjB,MAAM,GAAG,EAAE,OAAO,eAAgB,CAAE,GAAI,CAAE,WAAY,KAAK,WAAY,aAAc,IAAK,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EACvI,MAAM,GAAG,EAAE,OAAO,eAAgB,CAAE,GAAI,CAAE,WAAY,KAAK,UAAW,EAAG,MAAO,EAAG,gBAAiB,EAAK,CAAC,EAAE,KAAK,IAAM,CAAE,KAAM,EAAE,OAAO,CAAC,CAAE,EAAE,EAC7I,IAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,GAAG,GAAI,CAAE,aAAc,KAAK,IAAI,GAAG,GAAG,cAAc,IAAI,KAAK,UAAU,EAAE,CAAE,CAAC,CACxH,CAEA,MADuB,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EACpF,KAAK,gBAAgB,EAAE,OAAO,EAAE,GAAG,WAAY,OAAO,EAE3E,MAAM,GAAG,EAAE,OAAO,SAAU,QAAS,CAAE,OAAQ,YAAa,eAAgB,SAAU,kBAAmB,IAAK,CAAC,EAC/G,MAAM,YAAY,QAAS,kBAAmB,YAAa,YAAa,uCAAkC,EAC1G,GAAG,EAAE,MAAM,wCAAoC,SAAS,EACxD,MAAM,MAAQ,SAAS,eAAe,gBAAgB,EAClD,QACW,MAAM,iBAAiB,UAAU,EACzC,QAAQ,KAAO,CAAM,IAAI,UAAU,SAAS,OAAO,GAAG,IAAI,OAAO,CAAG,CAAC,EACrE,MAAM,iBAAiB,UAAU,EAAE,QAAQ,GAAG,EAAE,WAAW,GAElE,KAAK,CACP,EAAG,eAAgB,EAAK,CAC1B,CAEA,SAAS,aAAc,CACrB,MAAM,MAAQ,SAAS,eAAe,kBAAkB,EACxD,GAAI,CAAC,MAAO,OACZ,MAAM,MAAQ,QAAQ,OACtB,GAAI,CAAC,MAAO,CACV,MAAM,UAAY,0EAClB,iBAAiB,CAAC,EAClB,cAAc,EACd,MACF,CACA,MAAM,OAAS,aAAe,GAAK,GAC7B,KAAQ,QAAQ,MAAM,MAAO,MAAQ,EAAS,EAEpD,MAAM,UAAY,KAAK,IAAI,GAAK,CAC9B,MAAM,OAAS,EAAE,SAAW,UAAY,EAAE,OACpC,aAAe,EAAE,iBAAiB,UAAU,EAAE,kBAChD,KAAK,MAAM,IAAI,KAAK,EAAE,iBAAiB,EAAE,IAAI,OAAS,IAAK,GAAG,GAAG,GAAG,EAAI,KACtE,YAAc,eAAe,KAC/B,cAAc,EACZ,kFACA,cAAc,EACZ,wFACA,cAAc,EACZ,0EAA0E,YAAY,WACtF,GACN,GACE,SAAW,EAAE,aAAe,YAC9B,2DACA,2DACE,UAAY,EAAE,OAAO,CAAC,GAAG,IAAI,GAAK,CACtC,MAAM,KAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,EACzC,IAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EACtC,OAAO,KAAQ,IAAM,GAAG,IAAI,KAAK,GAAG,IAAM,KAAQ,GACpD,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,GAAK,SAC3B,KAAO,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,EAAG,IAAM,GAAK,EAAE,UAAU,GAAI,CAAC,GAAK,SACtE,MAAO;AAAA,qBACQ,EAAE,SAAW,oBAAsB,EAAE;AAAA,qEACW,EAAE,EAAE,KAAK,gBAAgB,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,mDAAmD,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;AAAA,8EAC3G,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC;AAAA,gBACtH,KAAK,EAAE,SAAS,EAAE,eAAe,QAAG,CAAC;AAAA,gBACrC,KAAK,EAAE,SAAS,EAAE,WAAW,MAAM,QAAG,CAAC;AAAA,gBACvC,QAAQ;AAAA,wHACgG,QAAQ,KAAK,QAAQ;AAAA,yCACpG,GAAG;AAAA,gBAC5B,KAAK,EAAE,eAAe,EAAE,WAAW,CAAC,GAAG,EAAE,mBAAmB,qIAAqI,EAAE;AAAA,gBACnM,KAAK,EAAE,WAAW,EAAE,UAAU,CAAC;AAAA,gBAC/B,KAAK,EAAE,KAAK,MAAM,CAAC,GAAG,EAAE,gBAAgB,EAAE,aAAa,SAAS,IAAI,KAAK,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,EAAE,IAAI,WAAW;AAAA;AAAA;AAAA,+HAGN,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;AAAA,gBACjI,EAAE,SAAW,uNAAoN,EAAE;AAAA;AAAA;AAAA,cAI/O,CAAC,EAAE,KAAK,EAAE,EACV,iBAAiB,KAAK,EACtB,cAAc,EACd,MAAM,MAAQ,SAAS,eAAe,uBAAuB,EAC7D,GAAI,MAAO,CACT,MAAM,QAAU,KAAK,IAAI,GAAK,EAAE,EAAE,EAClC,MAAM,QAAU,QAAQ,OAAS,GAAK,QAAQ,MAAM,IAAM,gBAAgB,IAAI,EAAE,CAAC,CACnF,CACF,CAEA,SAAS,iBAAiB,MAAO,CAC/B,MAAM,GAAK,SAAS,eAAe,uBAAuB,EAC1D,GAAI,CAAC,GAAI,OACT,MAAM,MAAQ,KAAK,KAAK,MAAQ,EAAS,EACzC,GAAI,OAAS,EAAG,CAAE,GAAG,UAAY,GAAI,MAAQ,CAC7C,GAAG,UAAY,wCAAwC,KAAK,KAAK,aAAa,GAAG,GAAU,EAAE,KAAK,CAAC,SAAI,KAAK,IAAI,aAAa,GAAU,KAAK,CAAC,OAAO,KAAK,UACvJ,MAAM,KAAK,CAAE,OAAQ,KAAM,EAAG,CAAC,EAAG,IAAM;AAAA,+CACC,EAAE,IAAI,aAAa,oBAAoB,qBAAqB;AAAA,8CAC7D,EAAE,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,CAC5E,CAUA,SAAS,kBAAkB,GAAI,QAAS,CAClC,QAAS,gBAAgB,IAAI,EAAE,EAAQ,gBAAgB,OAAO,EAAE,EACpE,cAAc,EACd,MAAM,MAAQ,SAAS,eAAe,uBAAuB,EAC7D,GAAI,MAAO,CACT,MAAM,QAAU,QAAQ,OAAO,aAAa,GAAG,GAAW,aAAa,EAAS,EAAE,IAAI,GAAG,EAAE,EAAE,EAC7F,MAAM,QAAU,QAAQ,OAAO,GAAK,QAAQ,MAAM,KAAK,gBAAgB,IAAI,GAAG,CAAC,CACjF,CACF,CAEA,SAAS,gBAAgB,QAAS,CAChB,QAAQ,OAAO,aAAa,GAAG,GAAW,aAAa,EAAS,EAAE,IAAI,GAAG,EAAE,EAAE,EACrF,QAAQ,IAAM,CAAM,QAAS,gBAAgB,IAAI,EAAE,EAAQ,gBAAgB,OAAO,EAAE,CAAG,CAAC,EAChG,YAAY,CACd,CAEA,SAAS,gBAAiB,CACxB,gBAAgB,MAAM,EACtB,YAAY,CACd,CAEA,SAAS,eAAgB,CACvB,MAAM,IAAM,SAAS,eAAe,qBAAqB,EACzD,GAAI,CAAC,IAAK,OACV,MAAM,MAAQ,gBAAgB,KAC9B,GAAI,CAAC,MAAO,CAAE,IAAI,MAAM,QAAU,OAAQ,IAAI,UAAY,GAAI,MAAQ,CACtE,IAAI,MAAM,QAAU,GACpB,IAAI,UAAY;AAAA;AAAA,uDAEmC,KAAK,kBAAkB,QAAQ,EAAE,GAAG,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAW5F,CAEA,eAAe,iBAAkB,CAC/B,MAAM,IAAM,SAAS,eAAe,qBAAqB,EACnD,UAAY,KAAK,MACvB,GAAI,CAAC,UAAW,CAAE,GAAG,EAAE,MAAM,kCAAmC,OAAO,EAAG,MAAQ,CAClF,MAAM,IAAM,CAAC,GAAG,eAAe,EAC/B,GAAI,CAAC,IAAI,OAAQ,OAEjB,MAAM,IAAM,SAAS,eAAe,qBAAqB,EACnD,SAAW,KAAK,cAAc,0BAA0B,EACxD,SAAW,KAAK,cAAc,wBAAwB,EACxD,MAAK,IAAI,SAAW,IACpB,WAAY,SAAS,SAAW,GAAM,SAAS,UAAY,wDAC3D,WAAU,SAAS,SAAW,IAKlC,MAAM,MAAQ,IAAI,OACd,KACF,IAAI,mBAAmB,YAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAS3B,EAEX,MAAM,gBAAkB,CAAC,KAAM,QAAU,CACvC,MAAM,IAAM,MAAQ,EAAI,KAAK,MAAO,KAAK,MAAO,GAAG,EAAI,EACjD,MAAQ,SAAS,eAAe,uBAAuB,EACvD,MAAQ,SAAS,eAAe,uBAAuB,EACvD,QAAU,SAAS,eAAe,yBAAyB,EAC7D,QAAO,MAAM,MAAM,MAAQ,IAAI,KAC/B,QAAO,MAAM,YAAc,IAAI,KAC/B,UAAS,QAAQ,YAAc,MACrC,EAEA,IAAI,QAAU,EAAG,QAAU,EAAG,UAAY,EAC1C,UAAW,MAAM,IAAK,CACpB,YACA,gBAAgB,UAAY,EAAG,kBAAkB,SAAS,OAAO,KAAK,EAAE,EACxE,KAAM,CAAE,KAAM,OAAQ,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAAE,OAAQ,SAAU,GAAI,CAAE,EAAG,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EAChI,GAAI,CAAC,CAAC,YAAY,SAAS,EAAE,SAAS,SAAS,MAAM,EAAG,CAAE,UAAW,gBAAgB,UAAW,WAAW,SAAS,OAAO,KAAK,EAAE,EAAG,QAAU,CAC/I,KAAM,CAAE,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,GAAI,CAAE,OAAQ,SAAU,CAAC,EACvE,GAAI,MAAO,CAAE,UAAW,gBAAgB,UAAW,WAAW,SAAS,OAAO,KAAK,EAAE,EAAG,QAAU,CAClG,MAAM,YAAY,GAAI,iBAAkB,SAAS,QAAQ,GAAI,UAAW,oBAAoB,EACxF,YAAc,UAChB,MAAM,GAAG,EAAE,OAAO,iBAAkB,CAAE,SAAU,GAAI,SAAU,WAAY,OAAQ,YAAa,CAAC,EAElG,UACA,gBAAgB,UAAW,WAAW,SAAS,OAAO,KAAK,EAAE,CAC/D,CAEA,gBAAgB,MAAO,WAAW,EAClC,MAAM,IAAI,QAAQ,GAAK,WAAW,EAAG,GAAG,CAAC,EAEzC,gBAAgB,MAAM,EACtB,GAAG,EAAE,MAAM,GAAG,OAAO,oBAAoB,QAAQ,KAAK,OAAO,8CAA8C,EAAE,GAAI,QAAU,UAAY,UAAW,GAAI,EACtJ,KAAK,CACP,CAEA,eAAe,oBAAqB,CAClC,GAAI,WAAW,OAAQ,OACvB,MAAM,UAAY,OAAO,GAAG,KAAK,SAAS,GACpC,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3F,CAAE,IAAK,EAAI,MAAM,OAAO,KAAK,WAAW,EAC3C,OAAO,oBAAoB,EAC3B,GAAG,aAAc,SAAS,EAC1B,GAAG,YAAa,EAAI,EACpB,MAAM,YAAY,EACrB,WAAa,MAAQ,CAAC,EACtB,MAAM,IAAM,SAAS,eAAe,qBAAqB,EACpD,KACL,WAAW,QAAQ,GAAK,CACtB,GAAI,CAAC,IAAI,cAAc,iBAAiB,EAAE,EAAE,IAAI,EAAG,CACjD,MAAM,IAAM,SAAS,cAAc,QAAQ,EAC3C,IAAI,MAAQ,EAAE,GAAI,IAAI,YAAc,EAAE,KACtC,IAAI,YAAY,GAAG,CACrB,CACF,CAAC,CACH,CAGA,IAAI,aAAe,CAAC,EAChB,SAAW,KAEf,eAAe,aAAa,UAAU,GAAO,CAC3C,OAAS,KACT,YAAc,CAAC,EACf,YAAc,KACd,iBAAmB,KACnB,kBAAoB,KACpB,wBAA0B,GAC1B,yBAA2B,GAC3B,MAAM,UAAY,OAAO,GAAG,KAAK,SAAS,GACpC,QAAY,OAAO,GAAG,KAAK,QAE3B,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3F,CAAE,KAAM,SAAU,EAAI,MAAM,OAAO,KAAK,WAAW,EACtD,OAAO,oBAAoB,EAC3B,GAAG,aAAc,SAAS,EAC1B,GAAG,YAAa,EAAI,EACpB,MAAM,YAAY,EAEf,KAAO,SAAS,mBAAqB,CAAC,EAOtC,cANY,WAAa,CAAC,GAAG,OAAO,GACpC,CAAC,EAAE,YAAc,EAAE,WAAW,SAAS,KAAK,GAC5C,CAAC,KAAK,OAAe,GAClB,EAAE,WAAW,KAAK,GAAK,KAAK,SAAS,CAAC,CAAC,CAC/C,EAE6B,IAAI,GAChC,kBAAkB,EAAE,EAAE,gBAAgB,EAAE,UAAU,KAAK,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,WAChF,EAAE,KAAK,EAAE,EAEH,CAAE,KAAM,UAAW,EAAI,MAAM,GAAG,EAAE,OAAO,aAAc,CAAE,GAAI,CAAE,UAAW,EAAK,EAAG,MAAO,CAAE,IAAK,aAAc,IAAK,EAAM,CAAE,CAAC,EAC5H,kBAAoB,YAAY,CAAC,GAAG,KAAK,GAAK,EAAE,UAAU,IAAM,YAAY,CAAC,GAAG,CAAC,GAAK,KACtF,eAAiB,YAAY,CAAC,GAAG,IAAI,GACzC,kBAAkB,EAAE,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,GAAG,WAAW,EAAE,IAAI,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,WAAW,aAAa,EAAE,WACjJ,EAAE,KAAK,EAAE,EACT,GAAG,EAAE,UAAU,YAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uDAauB,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+EAmDY,IAAI,KAAK,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,UAAU,IAAI,KAAK,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wDAM7G,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yEAyFI,KAAK,EAAE,eAAe,CAAC,CAAC;AAAA;AAAA,MAE1F;AAAA;AAAA,QAEC,aAAa,OAAO,EAAE,6EAA6E,aAAa,MAAM,yBAAyB,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA,sCAKnH,aAAa,OAAO,EAAE,kBAAkB,cAAc;AAAA;AAAA,MAErF,IAAI,EAEP,MAAM,cAAc,EACpB,mBAAmB,EACnB,eAAe,EACf,WAAW,IAAI,CACb,SAAS,iBAAiB,8BAA8B,EAAE,QAAQ,GAAG,CACnE,EAAE,iBAAiB,SAAU,IAAI,CAC/B,MAAM,KAAO,SAAS,eAAe,oBAAoB,EACtD,OAAM,KAAK,MAAM,QAAU,EAAE,QAAU,UAAY,EAAE,QAAU,GAAK,OACzE,CAAC,CACH,CAAC,EACD,SAAS,eAAe,cAAc,GAAG,iBAAiB,OAAQ,aAAa,CACjF,EAAG,GAAG,CACR,CAMA,eAAe,eAAgB,CAC7B,MAAM,WAAa,SAAS,eAAe,iBAAiB,GAAG,OAAS,KAClE,MAAQ,SAAS,eAAe,cAAc,GAAG,OAAO,KAAK,EAGnE,GADA,iBAAmB,KACf,MAAO,CACT,KAAM,CAAE,KAAM,IAAK,EAAI,MAAM,GAAG,EAAE,OAAO,YAAa,CACpD,OAAQ,gDACR,GAAI,CAAE,MAAO,UAAW,EAAK,EAAG,YAAa,EAC/C,CAAC,EACG,OAAM,iBAAmB,KAC/B,CAEA,MAAM,WAAa,kBAAkB,IAAM,KAGrC,aAAe,kBAAkB,eAAiB,KAElD,MAAS,MAAM,OAAO,WAAW,uBAAuB,WAAY,aAAc,UAAU,GAAM,CAAC,EACpG,MAAM,QAGT,MAAM,KAAK,CAAC,EAAG,IAAM,CACnB,MAAM,WAAa,EAAE,gBAAgB,CAAC,GAAG,KAAK,IAAM,GAAG,cAAgB,UAAU,EAAI,EAAI,EACnF,WAAa,EAAE,gBAAgB,CAAC,GAAG,KAAK,IAAM,GAAG,cAAgB,UAAU,EAAI,EAAI,EACzF,OAAI,YAAc,UAAkB,UAAY,WACxC,EAAE,gBAAgB,IAAM,EAAE,gBAAgB,EACpD,CAAC,EACD,YAAc,MAAM,CAAC,GARrB,YAAc,KAWhB,iBAAiB,EACjB,YAAY,QAAQ,CAAC,KAAM,IAAM,CAAM,KAAK,WAAW,gBAAgB,CAAC,CAAG,CAAC,EAC5E,YAAY,CACd,CAEA,SAAS,gBAAgB,MAAO,CAC9B,MAAM,KAAO,YAAY,KAAK,EAI9B,GAHI,CAAC,MAGD,KAAK,UAAW,OACpB,MAAM,KAAO,KAAK,WAAa,KAAK,eAAiB,EACrD,GAAI,YAAa,CACf,KAAM,CAAE,UAAW,EAAI,OAAO,UAAU,mBACtC,KAAM,kBAAkB,cAAe,kBAAkB,gBAAkB,EAAG,WAChF,EACA,KAAK,UAAY,WACjB,KAAK,UAAY,WACjB,KAAK,YAAc,EACrB,MACE,KAAK,UAAY,KACjB,KAAK,UAAY,KACjB,KAAK,YAAc,GAKrB,KAAK,WAAa,GAClB,KAAK,YAAc,CACrB,CAEA,SAAS,kBAAmB,CAC1B,MAAM,OAAS,SAAS,eAAe,iBAAiB,EACxD,GAAK,OACL,GAAI,YAAa,CACf,MAAM,UAAY,YAAY,gBAAkB,aAC5C,GAAG,YAAY,cAAc,QAC7B,OAAI,YAAY,cAAc,OAClC,OAAO,MAAM,QAAU,GACvB,OAAO,UAAY,mDAAmD,KAAK,EAAE,SAAS,YAAY,IAAI,CAAC,oBAAe,SAAS,KAAK,YAAY,qBAAqB,QAAQ,cAAc,UAAU,qBACvM,MACE,OAAO,MAAM,QAAU,OACvB,OAAO,UAAY,EAEvB,CAEA,SAAS,kBAAmB,CAC1B,MAAM,IAAM,SAAS,eAAe,iBAAiB,EACrD,GAAI,CAAC,IAAK,OACV,MAAM,IAAM,IAAI,QAAQ,IAAI,aAAa,EACnC,KAAO,KAAK,SAAS,MAAQ,GAC7B,cAAgB,KAAK,aAAe,IAAI,YAAY,EACpD,QAAU,SAAS,eAAe,qBAAqB,EACvD,KAAO,SAAS,eAAe,kBAAkB,EACvD,GAAI,QAAS,CACX,QAAQ,MAAQ,OAAS,YAAc,YAAc,SAMrD,MAAM,SAAW,aAAa,SAAS,MAAM,EAC7C,QAAQ,SAAW,CAAC,SAChB,OAAM,KAAK,YAAc,SACzB,oEACA,yBACN,CACA,cAAc,EACd,mBAAmB,EAInB,MAAM,cAAgB,SAAS,eAAe,iBAAiB,EAC3D,OAAS,aAAe,eAAe,OAAO,KAAK,EAAE,QAAU,GACjE,cAAc,cAAc,IAAI,MAAM,OAAO,CAAC,CAElD,CAQA,SAAS,oBAAqB,CAC5B,MAAM,IAAQ,SAAS,eAAe,iBAAiB,EACjD,MAAQ,SAAS,eAAe,iBAAiB,EACjD,KAAQ,SAAS,eAAe,sBAAsB,EAC5D,GAAI,CAAC,KAAO,CAAC,OAAS,CAAC,KAAM,OAG7B,IAFa,IAAI,QAAQ,IAAI,aAAa,GAAG,SAAS,MAAQ,MAEjD,YAAa,CACxB,MAAM,SAAW,GACjB,MAAM,MAAM,WAAa,GACzB,MAAM,YAAc,4BACpB,KAAK,UAAY,GACjB,MACF,CAEA,MAAM,SAAW,GACjB,MAAM,MAAM,WAAa,sBACzB,MAAM,YAAc,+BAEhB,kBACF,KAAK,UAAY;AAAA,wIAGjB,KAAK,UAAY;AAAA,0BACA,iBAAiB,EAC5B,iIACA,oFAAoF,EAE9F,CAEA,SAAS,qBAAsB,CAC7B,kBAAoB,KACpB,CAAC,kBAAkB,iBAAiB,eAAe,cAAc,EAAE,QAAQ,IAAM,CAC/E,MAAM,GAAK,SAAS,eAAe,EAAE,EACjC,KAAI,GAAG,MAAQ,GACrB,CAAC,EACD,mBAAmB,EACnB,cAAc,CAChB,CAUA,eAAe,yBAA0B,CACvC,GAAI,CAAC,iBAAiB,EAAG,CAAE,GAAG,EAAE,MAAM,sCAAuC,OAAO,EAAG,MAAQ,CAC/F,qBAAqB,CACvB,CAGA,SAAS,oBAAqB,CAC5B,MAAM,MAAU,SAAS,eAAe,iBAAiB,EACnD,KAAU,SAAS,eAAe,sBAAsB,EACxD,KAAU,SAAS,eAAe,sBAAsB,EAC9D,GAAI,CAAC,OAAS,CAAC,KAAM,OAErB,MAAM,OAAS,KAAK,EAAE,SAAS,MAAO,KAAQ,CAC5C,MAAM,IAAM,EAAE,WAAW,SACnB,MAAQ,IAAI,QAAQ,MAAM,EAAE,EAAE,YAAY,EAChD,GAAI,MAAM,OAAS,EAAG,CAAE,KAAK,MAAM,QAAU,OAAQ,MAAQ,CAM7D,MAAM,QAAW,SAAS,eAAe,iBAAiB,EACpD,SAAW,SAAS,QAAQ,QAAQ,aAAa,GAAG,SAAS,MAAQ,GAC3E,IAAI,eAAiB,CAAC,EACtB,GAAI,WAAa,YAAa,CAW5B,MAAM,KAAO,MAAM,MAAM,EAAG,CAAC,EACvB,CAAE,IAAK,EAAI,MAAM,GAAG,EAAE,OAAO,YAAa,CAC9C,OAAQ,2EACR,MAAO,CAAE,SAAU,IAAK,EACxB,GAAI,CAAE,UAAW,EAAK,EACtB,MAAO,EACT,CAAC,EACD,GAAI,MAAQ,WAAW,SAAU,OACjC,gBAAkB,MAAQ,CAAC,GACxB,OAAO,IAAM,EAAE,UAAY,IAAI,QAAQ,MAAO,EAAE,EAAE,YAAY,EAAE,WAAW,KAAK,CAAC,EACjF,MAAM,EAAG,CAAC,CACf,CAEA,KAAM,CAAE,KAAM,OAAQ,EAAI,MAAM,GAAG,EAAE,OAAO,yBAA0B,CACpE,MAAO,CAAE,SAAU,KAAM,EACzB,MAAO,CAAE,IAAK,cAAe,IAAK,EAAM,EACxC,MAAO,CACT,CAAC,EACD,GAAI,MAAQ,WAAW,SAAU,OACjC,MAAM,aAAe,SAAS,QAAU,EAClC,aAAe,eAAe,OAEpC,GAAI,CAAC,cAAgB,CAAC,aAAc,CAClC,KAAK,MAAM,QAAU,OACjB,OAAM,KAAK,YAAc,8CAC7B,MACF,CAEI,OACF,KAAK,YAAc,aACf,GAAG,YAAY,2CACf,GAAG,YAAY,0CAGrB,KAAK,UAAY;AAAA,UACb,iBAAiB,EAAI;AAAA;AAAA;AAAA,gBAGb,EAAE;AAAA,UACV,aAAe;AAAA;AAAA,YAEb,eAAe,IAAI,GAAK;AAAA;AAAA,uEAEmC,KAAK,UAAU,CAAC,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAAA,wBACvF,KAAK,EAAE,SAAS,EAAE,aAAa,CAAC;AAAA,yFACiC,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;AAAA,mBAC1G,EAAE,KAAK,EAAE,CAAC;AAAA,UACjB,EAAE;AAAA,UACJ,aAAe;AAAA,YACb,aAAe,+LAAiM,EAAE;AAAA,YAClN,QAAQ,IAAI,GAAK;AAAA;AAAA,4DAE+B,KAAK,UAAU,CAAC,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAAA,wBAC5E,KAAK,EAAE,SAAS,EAAE,aAAa,CAAC;AAAA,yFACiC,EAAE,WAAW;AAAA,mBACnF,EAAE,KAAK,EAAE,CAAC;AAAA,UACjB,EAAE,GACR,KAAK,MAAM,QAAU,OACvB,EAAG,GAAG,EAEN,MAAM,iBAAiB,QAAS,GAAK,OAAO,EAAE,OAAO,KAAK,CAAC,EAC3D,MAAM,iBAAiB,OAAQ,IAAM,WAAW,IAAM,CAAE,KAAK,MAAM,QAAU,MAAQ,EAAG,GAAG,CAAC,CAC9F,CAEA,SAAS,wBAAwB,OAAQ,CACvC,kBAAoB,OAAO,GAC3B,MAAM,EAAI,CAAC,GAAI,IAAM,CAAE,MAAM,GAAK,SAAS,eAAe,EAAE,EAAO,KAAI,GAAG,MAAQ,GAAK,GAAI,EAC3F,EAAE,kBAAmB,OAAO,aAAa,EACzC,EAAE,iBAAmB,OAAO,OAAO,EACnC,EAAE,kBAAmB,OAAO,QAAQ,EACpC,EAAE,eAAmB,OAAO,KAAK,EACjC,EAAE,eAAmB,OAAO,KAAK,EACjC,MAAM,KAAO,SAAS,eAAe,sBAAsB,EACvD,OAAM,KAAK,MAAM,QAAU,QAK/B,cAAc,EACd,mBAAmB,EAMnB,wBAA2B,OAAO,SAAW,GAC7C,yBAA2B,OAAO,UAAY,GAC9C,MAAM,QAAU,SAAS,eAAe,yBAAyB,EAC7D,UAAS,QAAQ,MAAM,QAAU,QACrC,MAAM,OAAS,SAAS,eAAe,oBAAoB,EACvD,SAAQ,OAAO,QAAU,IAC7B,mBAAmB,EAAI,EACvB,GAAG,EAAE,MAAM,gCAAgC,OAAO,aAAa,GAAI,SAAS,CAC9E,CAMA,SAAS,mBAAoB,CAC3B,MAAM,IAAO,SAAS,eAAe,oBAAoB,EACnD,KAAO,SAAS,eAAe,yBAAyB,EACxD,KAAO,SAAS,eAAe,gBAAgB,EAC/C,GAAO,SAAS,eAAe,iBAAiB,EACjD,MAED,IAAI,SACN,mBAAmB,EAAK,EACpB,OAAM,KAAK,MAAQ,IACnB,KAAM,GAAG,MAAU,IACnB,OAAM,KAAK,UAAY,mJACvB,IAAI,GAAG,MAAM,IAEb,OAAM,KAAK,MAAQ,yBACnB,KAAM,GAAG,MAAU,0BACvB,mBAAmB,EAAI,EACnB,OAAM,KAAK,UAAY,KAE/B,CAEA,SAAS,mBAAmB,OAAQ,CAClC,MAAM,KAAO,SAAS,eAAe,gBAAgB,EAC/C,GAAO,SAAS,eAAe,iBAAiB,EACtD,CAAC,KAAM,EAAE,EAAE,QAAQ,IAAM,CAClB,KACL,GAAG,SAAW,OACd,GAAG,MAAM,WAAa,OAAS,sBAAwB,GACzD,CAAC,CACH,CAEA,SAAS,aAAa,OAAQ,CAC5B,MAAM,EAAI,CAAC,GAAI,IAAM,CAAE,MAAM,GAAK,SAAS,eAAe,EAAE,EAAO,KAAI,GAAG,MAAQ,GAAK,GAAI,EAC3F,EAAE,kBAAmB,OAAO,aAAa,EACzC,EAAE,iBAAmB,OAAO,OAAO,EACnC,EAAE,kBAAmB,OAAO,QAAQ,EACpC,EAAE,eAAmB,OAAO,KAAK,EACjC,EAAE,eAAmB,OAAO,KAAK,EACjC,MAAM,KAAO,SAAS,eAAe,sBAAsB,EACvD,OAAM,KAAK,MAAM,QAAU,QAC/B,GAAG,EAAE,MAAM,uCAAwC,SAAS,CAC9D,CAEA,SAAS,eAAgB,CACvB,CAAC,kBAAkB,iBAAiB,eAAe,cAAc,EAAE,QAAQ,IAAM,CAC/E,MAAM,GAAK,SAAS,eAAe,EAAE,EAAO,KAAI,GAAG,MAAQ,GAC7D,CAAC,EACD,MAAM,KAAO,SAAS,eAAe,sBAAsB,EACvD,OAAM,KAAK,MAAM,QAAU,OACjC,CAYA,SAAS,sBAAuB,CAC9B,GAAI,CAAC,iBAAiB,EAAG,CAAE,GAAG,EAAE,MAAM,sCAAuC,OAAO,EAAG,MAAQ,CAC/F,MAAM,KAAO,SAAS,eAAe,sBAAsB,EACvD,OAAM,KAAK,MAAM,QAAU,QAC/B,MAAM,UAAY,SAAS,eAAe,iBAAiB,GAAG,QAAQ,kBAAkB,EACpF,YAAW,UAAU,MAAM,QAAU,QACzC,MAAM,SAAW,SAAS,eAAe,iBAAiB,EACtD,WAAU,SAAS,MAAM,QAAU,IAEvC,MAAM,SAAW,SAAS,eAAe,iBAAiB,GAAG,OAAS,GAChE,UAAY,SAAS,eAAe,iBAAiB,GAAG,OAAS,GACjE,WAAa,SAAS,eAAe,iBAAiB,EACtD,OAAS,SAAS,eAAe,aAAa,EAChD,aAAY,WAAW,MAAQ,UAC/B,SAAQ,OAAO,MAAQ,WAC3B,QAAQ,MAAM,CAChB,CAEA,eAAe,sBAAuB,CACpC,MAAM,KAAO,SAAS,eAAe,aAAa,GAAG,OAAO,KAAK,EACjE,GAAI,CAAC,KAAM,CAAE,GAAG,EAAE,MAAM,wCAAyC,OAAO,EAAG,MAAQ,CACnF,MAAM,QAAW,SAAS,eAAe,gBAAgB,GAAG,OAAO,KAAK,GAAM,KACxE,MAAW,SAAS,eAAe,cAAc,GAAG,OAAO,KAAK,GAAQ,KACxE,MAAW,SAAS,eAAe,cAAc,GAAG,OAAO,KAAK,GAAQ,KACxE,SAAW,SAAS,eAAe,iBAAiB,GAAG,OAAO,KAAK,GAAK,KACxE,QAAW,SAAS,eAAe,gBAAgB,GAAG,OAAO,KAAK,GAAK,KAG7E,GAAI,CAAC,iBAAiB,EAAG,CAAE,GAAG,EAAE,MAAM,sCAAuC,OAAO,EAAG,MAAQ,CAG/F,MAAM,SAAW,OAAO,GAAG,KAAK,QAAQ,EAAI,CAAC,EAAI,CAAE,aAAc,kBAAmB,aAAc,CAAE,EAC9F,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,YAAa,CACrD,cAAe,KAAM,aAAc,QACnC,MAAO,MAAO,SAAU,QAAS,UAAW,GAAM,GAAG,QACvD,CAAC,EACD,GAAI,MAAO,CAAE,GAAG,EAAE,MAAM,8BAAgC,MAAM,QAAS,OAAO,EAAG,MAAQ,CAEzF,kBAAoB,KAAK,GACzB,MAAM,IAAM,CAAC,GAAI,MAAQ,CAAE,MAAM,GAAK,SAAS,eAAe,EAAE,EAAO,KAAI,GAAG,MAAQ,KAAO,GAAI,EACjG,IAAI,kBAAmB,IAAI,EAC3B,IAAI,eAAgB,KAAK,EACzB,IAAI,eAAgB,KAAK,EACzB,IAAI,iBAAkB,OAAO,EAC7B,MAAM,KAAO,SAAS,eAAe,iBAAiB,EAClD,MAAQ,CAAC,KAAK,QAAO,KAAK,MAAQ,UAAY,IAElD,MAAM,SAAW,SAAS,eAAe,iBAAiB,EACtD,WAAU,SAAS,MAAM,QAAU,QACvC,MAAM,UAAY,SAAS,eAAe,iBAAiB,GAAG,QAAQ,kBAAkB,EACpF,YAAW,UAAU,MAAM,QAAU,IAEzC,mBAAmB,EACnB,GAAG,EAAE,MAAM,GAAG,IAAI,qCAAiC,SAAS,CAC9D,CAKA,SAAS,wBAAyB,CAChC,MAAM,SAAW,SAAS,eAAe,iBAAiB,EACtD,WAAU,SAAS,MAAM,QAAU,QACvC,MAAM,UAAY,SAAS,eAAe,iBAAiB,GAAG,QAAQ,kBAAkB,EACpF,YAAW,UAAU,MAAM,QAAU,IACzC,cAAc,CAChB,CAOA,IAAI,UAAY,CAAC,EACjB,eAAe,eAAgB,CAC7B,KAAM,CAAE,IAAK,EAAI,MAAM,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EACtG,KAAK,UAAU,EAAE,OAAO,4BAA4B,EAAE,GAAG,aAAc,OAAO,GAAG,KAAK,SAAS,EAAE,EAAE,GAAG,YAAa,EAAI,EAAE,MAAM,aAAc,CAAE,UAAW,EAAK,CAAC,EACnK,UAAY,MAAQ,CAAC,EACrB,MAAM,IAAM,SAAS,eAAe,oBAAoB,EACpD,MAAK,IAAI,UAAY,2CAA6C,UAAU,OAAS,UAAU,IAAI,GAAK,kBAAkB,EAAE,EAAE,KAAK,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,KAAK,EAAE,eAAe,EAAE,cAAc,CAAC,YAAY,EAAE,KAAK,EAAE,EAAI,6DACrO,CACA,SAAS,WAAW,UAAW,CAC7B,MAAM,EAAI,UAAU,KAAK,GAAK,EAAE,KAAO,SAAS,EAC1C,IAAM,SAAS,eAAe,oBAAoB,EAAO,MAAK,IAAI,MAAQ,IAC3E,IACL,YAAY,KAAK,CAAE,UAAW,GAAI,YAAa,EAAE,KAAM,IAAK,GAAI,IAAK,EAAG,UAAW,OAAO,EAAE,cAAc,GAAK,EAAG,UAAW,EAC3H,UAAW,OAAO,EAAE,cAAc,GAAK,EAAG,YAAa,GAAO,UAAW,GAAM,UAAW,EAAE,GAAI,IAAK,EAAE,GAAI,CAAC,EAC9G,YAAY,EACd,CAOA,IAAI,SAAW,EACf,SAAS,gBAAiB,CACxB,MAAM,MAAQ,SAAS,eAAe,iBAAiB,EACvD,GAAI,CAAC,OAAS,MAAM,QAAQ,YAAc,IAAK,OAC/C,MAAM,QAAQ,UAAY,IAC1B,IAAI,EAAI,KACR,MAAM,iBAAiB,QAAS,IAAM,CAAE,aAAa,CAAC,EAAG,EAAI,WAAW,mBAAoB,GAAG,CAAG,CAAC,EACnG,MAAM,iBAAiB,SAAU,kBAAkB,CACrD,CACA,eAAe,oBAAqB,CAClC,MAAM,MAAQ,SAAS,eAAe,iBAAiB,EAAG,GAAI,CAAC,MAAO,OACtE,IAAI,KAAO,SAAS,eAAe,kBAAkB,EAChD,OACH,KAAO,SAAS,cAAc,KAAK,EAAG,KAAK,GAAK,mBAAoB,KAAK,MAAM,QAAU,iCACxF,SAAS,eAAe,sBAAsB,GAAK,OAAO,sBAAsB,WAAY,IAAI,GAEnG,MAAM,IAAM,EAAE,SACR,GAAK,OAAO,MAAM,OAAS,EAAE,EAAE,YAAY,EAAE,QAAQ,OAAQ,EAAE,EACrE,GAAI,GAAG,OAAS,EAAG,CAAE,KAAK,UAAY,GAAI,MAAQ,CAClD,MAAM,IAAM,GAAG,MAAM,EAAG,EAAE,EAAG,MAAQ,IAAI,MAAM,aAAa,GAAK,CAAC,EAAE,GAAG,CAAC,EAClE,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3F,CAAE,KAAM,KAAM,EAAI,MAAM,OAAO,KAAK,eAAe,EAAE,OAAO,oBAAoB,EAAE,GAAG,aAAc,OAAO,GAAG,KAAK,SAAS,EAAE,EAC7H,SAAW,CAAC,GAAG,IAAI,KAAK,OAAS,CAAC,GAAG,IAAI,GAAK,EAAE,UAAU,CAAC,CAAC,EAClE,GAAI,CAAC,SAAS,OAAQ,CAAM,MAAQ,WAAU,KAAK,UAAY,IAAI,MAAQ,CAC3E,KAAM,CAAE,KAAM,GAAI,EAAI,MAAM,OAAO,KAAK,wBAAwB,EAAE,OAAO,2BAA2B,EAAE,GAAG,SAAU,CAAC,IAAK,IAAI,CAAC,EAC9H,GAAI,MAAQ,SAAU,OACtB,MAAM,UAAY,SAAS,OAAO,KAAO,CACvC,MAAM,MAAQ,KAAO,CAAC,GAAG,OAAO,GAAK,EAAE,aAAe,GAAG,EACnD,IAAM,KAAK,KAAK,GAAK,EAAE,SAAW,GAAG,GAAK,KAAK,KAAK,GAAK,EAAE,SAAW,IAAI,EAChF,OAAQ,OAAS,CAAC,GAAG,KAAK,GAAK,EAAE,KAAO,KAAK,OAAO,GAAG,OAAS,YAClE,CAAC,EACD,KAAK,UAAY,UAAU,SAAW,SAAS,OAC3C,+EAA+E,KAAK,EAAE,SAAS,GAAG,CAAC,2EACnG,EACN,CAEA,SAAS,SAAU,CACjB,YAAY,KAAK,CAAE,UAAW,GAAI,YAAa,GAAI,IAAK,GAAI,IAAK,EAAG,UAAW,EAAG,UAAW,EAAG,UAAW,EAAG,YAAa,EAAM,CAAC,EAClI,YAAY,CACd,CAEA,SAAS,aAAc,CACrB,MAAM,UAAY,SAAS,eAAe,cAAc,EACxD,GAAI,CAAC,UAAW,OAChB,GAAI,CAAC,YAAY,OAAQ,CACvB,UAAU,UAAY,kGACtB,mBAAmB,EACnB,YAAY,EACZ,MACF,CACA,UAAU,UAAY,YAAY,IAAI,CAAC,KAAM,IAAM,KAAK,UAAY;AAAA;AAAA,kJAE0E,KAAK,EAAE,SAAS,KAAK,WAAW,CAAC;AAAA,iEAClH,KAAK,GAAG,KAAK,KAAK,MAAQ,QAAU,0CAA4C,EAAE;AAAA,kDACjG,CAAC;AAAA,6EAC0B,KAAK,SAAS,iDAAiD,CAAC;AAAA,kDAC3F,CAAC;AAAA;AAAA,kDAED,CAAC;AAAA,cACnC;AAAA;AAAA;AAAA;AAAA,qBAIK,KAAK,EAAE,SAAS,KAAK,WAAW,CAAC;AAAA,oDACF,CAAC,8DAA8D,CAAC;AAAA,mCACjF,CAAC;AAAA;AAAA,iEAE6B,KAAK,GAAG;AAAA,kDACvB,CAAC;AAAA;AAAA;AAAA,qBAG9B,KAAK,SAAS;AAAA,4BACP,CAAC;AAAA,oDACuB,CAAC,gEAAgE,CAAC;AAAA,qBACjG,KAAK,WAAW,mEAAmE,KAAK,YAAY,iCAAiC,EAAE;AAAA,YAChJ,KAAK,UAAY,8HAA8H,CAAC,sBAAwB,EAAE;AAAA,oCAClJ,CAAC,KAAK,eAAe,IAAI,CAAC;AAAA;AAAA;AAAA,kDAGZ,CAAC;AAAA;AAAA,iCAElB,CAAC,sCAAsC,EAAE,KAAK,EAAE,EAE7E,MAAM,YAAc,SAAS,eAAe,kBAAkB,GAAG,OAAS,GAC1E,YAAY,QAAQ,CAAC,KAAM,IAAM,CAC3B,KAAK,WAAW,eAAe,EAAG,KAAK,UAAW,WAAW,CACnE,CAAC,EACD,mBAAmB,EACnB,YAAY,CACd,CAEA,SAAS,mBAAoB,CAC3B,MAAM,YAAc,SAAS,eAAe,kBAAkB,GAAG,OAAS,GAGpE,YAAc,YAAY,KAAK,GAAK,EAAE,iBAAiB,MAAM,EACnE,YAAY,QAAQ,GAAK,CAAE,EAAE,gBAAkB,CAAC,CAAG,CAAC,EAChD,aAAa,GAAG,EAAE,MAAM,sEAAuE,OAAQ,GAAI,EAC/G,YAAY,QAAQ,CAAC,KAAM,IAAM,CAC/B,MAAM,MAAQ,SAAS,eAAe,mBAAmB,CAAC,EAAE,EACxD,QAAS,MAAM,UAAY,GAAI,MAAM,QAAQ,SAAW,KACxD,KAAK,WAAW,eAAe,EAAG,KAAK,UAAW,WAAW,CACnE,CAAC,CACH,CAWA,SAAS,mBAAmB,UAAW,YAAa,CAClD,OAAO,YAAY,OAAO,CAAC,IAAK,OAAS,KAAO,KAAK,iBAAmB,CAAC,GACtE,OAAO,GAAK,EAAE,YAAc,WAAa,EAAE,cAAgB,WAAW,EACtE,OAAO,CAAC,EAAG,IAAM,GAAK,EAAE,KAAO,GAAI,CAAC,EAAG,CAAC,CAC7C,CAGA,SAAS,sBAAsB,QAAS,CACtC,OAAO,YAAY,OAAO,CAAC,IAAK,OAAS,KAAO,KAAK,iBAAmB,CAAC,GACtE,OAAO,GAAK,EAAE,UAAY,OAAO,EACjC,OAAO,CAAC,EAAG,IAAM,GAAK,EAAE,KAAO,GAAI,CAAC,EAAG,CAAC,CAC7C,CAIA,SAAS,wBAAwB,UAAW,CAC1C,MAAM,YAAc,SAAS,eAAe,kBAAkB,GAAG,OAAS,GAC1E,YAAY,QAAQ,CAAC,KAAM,IAAM,CAC3B,KAAK,YAAc,WAAW,eAAe,EAAG,UAAW,WAAW,CAC5E,CAAC,CACH,CAEA,eAAe,eAAe,MAAO,UAAW,YAAa,CAC3D,MAAM,GAAK,SAAS,eAAe,aAAa,KAAK,EAAE,EACvD,GAAI,CAAC,YAAa,CACZ,KAAM,GAAG,YAAc,qBAAsB,GAAG,MAAM,MAAQ,sBAClE,MACF,CACA,KAAM,CAAE,KAAM,EAAG,EAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,CACrD,GAAI,CAAE,WAAY,UAAW,aAAc,WAAY,EAAG,YAAa,GAAM,gBAAiB,EAChG,CAAC,EACK,IAAW,IAAI,UAAY,EAC3B,SAAW,IAAI,cAAgB,EAG/B,MAAW,KAAK,IAAI,GAAI,IAAI,yBAA2B,GAAK,mBAAmB,UAAW,WAAW,CAAC,EACtG,UAAa,IAAM,SAAW,MAC9B,WAAa,IAAM,SACrB,KACF,GAAG,YAAc,UACjB,GAAG,MAAM,MAAQ,WAAa,EAAI,oBAAsB,WAAa,EAAI,qBAAuB,IAGlG,MAAM,KAAO,YAAY,KAAK,EACxB,OAAS,MAAM,KAAO,EACtB,MAAQ,SAAS,eAAe,mBAAmB,KAAK,EAAE,EAChE,GAAK,OACD,MAAM,QAAQ,WAAa,IAE/B,IAAI,MAAM,iBAAiB,OAAQ,CACjC,MAAM,MAAQ,KAAK,gBAAgB,OAAO,CAAC,EAAG,IAAM,GAAK,EAAE,KAAO,GAAI,CAAC,EACjE,SAAW,CAAC,GAAG,IAAI,IAAI,KAAK,gBAAgB,IAAI,GAAK,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,IAAI,EACjF,MAAM,UAAY;AAAA;AAAA,sDAE8B,KAAK,kCAAkC,KAAK,EAAE,SAAS,QAAQ,CAAC;AAAA,yGACb,KAAK;AAAA,gBAExG,MACF,CAEA,GAAI,UAAY,QAAU,MAAQ,GAAK,YAAc,OAAQ,CAC3D,MAAM,UAAY,OAAS,UAC3B,MAAM,UAAY;AAAA;AAAA,uDAE+B,KAAK;AAAA,qHACyD,KAAK,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC,MAAM,KAAK,EAAE,MAAM,WAAW,CAAC,KAAK,SAAS;AAAA,eAE/L,MACE,MAAM,UAAY,GAEtB,CAEA,eAAe,sBAAsB,MAAO,UAAW,YAAa,UAAW,CAC7E,MAAM,MAAQ,SAAS,eAAe,mBAAmB,KAAK,EAAE,EAChE,GAAI,CAAC,MAAO,OACZ,GAAI,MAAM,QAAQ,WAAa,IAAK,CAClC,MAAM,QAAQ,SAAW,IACzB,eAAe,MAAO,UAAW,WAAW,EAC5C,MACF,CACA,KAAM,CAAE,KAAM,MAAO,EAAI,MAAM,GAAG,EAAE,OAAO,uBAAwB,CACjE,OAAQ,qDACR,GAAI,CAAE,WAAY,UAAW,aAAc,WAAY,EACvD,GAAI,CAAE,cAAe,CAAE,EACvB,gBAAiB,EACnB,CAAC,EAEK,MAAQ,QAAQ,CAAC,GACpB,IAAI,IAAM,CAAE,GAAG,EAAG,MAAO,EAAE,eAAe,GAAK,sBAAsB,EAAE,EAAE,CAAE,EAAE,EAC7E,OAAO,GAAK,EAAE,KAAO,CAAC,EAEzB,GADA,MAAM,QAAQ,SAAW,IACrB,CAAC,KAAK,OAAQ,CAChB,MAAM,UAAY,oKAClB,MACF,CACA,MAAM,UAAY;AAAA;AAAA,yFAEmE,SAAS;AAAA,UACxF,KAAK,IAAI,GAAK;AAAA;AAAA,kDAE0B,KAAK,EAAE,SAAS,EAAE,oBAAoB,eAAe,kBAAkB,CAAC,KAAK,EAAE,IAAI;AAAA,mEAClE,EAAE,IAAI,YAAY,KAAK,IAAI,UAAW,EAAE,IAAI,CAAC,uBAAuB,KAAK,IAAI,EAAE,EAAE;AAAA,uHAC7B,KAAK,KAAK,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,EAAE,MAAM,SAAS,CAAC,MAAM,KAAK,EAAE,MAAM,WAAW,CAAC;AAAA,iBAC9L,EAAE,KAAK,EAAE,CAAC;AAAA,wIAC6G,KAAK,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC,MAAM,KAAK,EAAE,MAAM,WAAW,CAAC,KAAK,SAAS;AAAA,aAEpN,CAIA,eAAe,sBAAsB,MAAO,QAAS,UAAW,YAAa,CAC3E,MAAM,KAAO,YAAY,KAAK,EAC9B,GAAI,CAAC,KAAM,OACX,MAAM,MAAQ,SAAS,eAAe,iBAAiB,KAAK,IAAI,OAAO,EAAE,EACnE,WAAa,SAAS,OAAO,KAAK,GAAK,EAC7C,GAAI,CAAC,YAAc,YAAc,EAAG,CAAE,GAAG,EAAE,MAAM,8BAA+B,OAAO,EAAG,MAAQ,CAElG,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,uBAAwB,CAChE,OAAQ,kDAAmD,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EACtH,CAAC,EACD,GAAI,CAAC,MAAO,CAAE,GAAG,EAAE,MAAM,uBAAwB,OAAO,EAAG,MAAQ,CACnE,MAAM,MAAQ,MAAM,eAAe,GAAK,sBAAsB,OAAO,EAC/D,IAAM,KAAK,IAAI,WAAY,IAAI,EACrC,GAAI,KAAO,EAAG,CAAE,GAAG,EAAE,MAAM,6CAA8C,OAAO,EAAG,MAAQ,CAC3F,MAAM,QAAU,MAAM,oBAAoB,eAAiB,mBAE3D,KAAK,gBAAkB,CAAC,GAAI,KAAK,iBAAmB,CAAC,EAAI,CAAE,QAAS,UAAW,YAAa,IAAK,OAAQ,CAAC,EAC1G,GAAG,EAAE,MAAM,GAAG,GAAG,kCAAkC,OAAO,4BAA6B,OAAQ,GAAI,EACnG,MAAM,MAAQ,SAAS,eAAe,mBAAmB,KAAK,EAAE,EAC5D,QAAO,MAAM,QAAQ,SAAW,KACpC,wBAAwB,SAAS,CACnC,CAGA,SAAS,YAAY,MAAO,CAC1B,MAAM,KAAO,YAAY,KAAK,EACzB,OACL,KAAK,gBAAkB,CAAC,EACxB,GAAG,EAAE,MAAM,oBAAqB,OAAQ,GAAI,EACxC,KAAK,WAAW,wBAAwB,KAAK,SAAS,EAC5D,CAEA,SAAS,WAAW,MAAO,MAAO,MAAO,CACnC,YAAY,KAAK,IACnB,YAAY,KAAK,EAAE,KAAK,EAAI,OACxB,QAAU,OAAS,QAAU,cAAa,YAAY,EAE9D,CAEA,SAAS,WAAW,MAAO,CACzB,YAAY,OAAO,MAAO,CAAC,EAC3B,YAAY,CACd,CAEA,SAAS,aAAc,CACrB,MAAM,SAAW,YAAY,OAAO,CAAC,EAAG,IAAM,GAAM,EAAE,KAAK,IAAM,EAAE,WAAW,GAAK,CAAC,EAC9E,SAAY,SAAS,eAAe,kBAAkB,GAAG,OAAS,OAClE,QAAY,WAAW,SAAS,eAAe,mBAAmB,GAAG,KAAK,GAAK,EACrF,IAAI,QAAU,EACX,WAAa,OAAS,QAAU,IAAK,QAAU,UAAY,QAAU,MACrE,WAAa,SAAW,QAAU,IAAG,QAAU,KAAK,IAAI,QAAS,QAAQ,GAC5E,MAAM,MAAQ,KAAK,IAAI,EAAG,SAAW,OAAO,EACtC,YAAc,SAAS,eAAe,qBAAqB,EAC9D,cAAa,YAAY,YAAc,QAAU,EAAI,UAAK,KAAK,EAAE,eAAe,OAAO,CAAC,GAAK,IAChG,MAAM,GAAK,SAAS,eAAe,cAAc,EAC9C,KAAI,GAAG,YAAc,KAAK,EAAE,eAAe,KAAK,EACrD,CAKA,SAAS,eAAe,KAAM,CAC5B,OAAI,KAAK,WACA;AAAA;AAAA,sBAES,KAAK,EAAE,eAAe,KAAK,aAAa,CAAC;AAAA,aAClD,KAAK,YAAc,EAAI,IAAM,EAAE,IAAI,KAAK,aAAe,GAAG,QAAQ,CAAC,CAAC;AAAA,gBAGzE,KAAK,YACA;AAAA;AAAA,4BAEe,KAAK,EAAE,eAAe,KAAK,WAAa,KAAK,aAAa,CAAC;AAAA,gBAG5E,EACT,CAIA,SAAS,oBAAqB,CAC5B,MAAM,eAAiB,YAAY,KAAK,GAAK,EAAE,UAAU,EACnD,MAAQ,SAAS,eAAe,2BAA2B,EAC7D,QAAO,MAAM,MAAM,QAAU,eAAiB,GAAK,OACzD,CAcA,SAAS,cAAc,MAAO,CAC5B,MAAM,KAAO,YAAY,KAAK,EAC9B,GAAI,CAAC,KAAM,OACX,MAAM,SAAW,OAAO,KAAK,aAAa,GAAK,EAC/C,GAAI,SAAW,EAAG,CAChB,MAAM,SAAY,KAAK,aAAe,KAAK,WAAa,KACpD,OAAO,KAAK,SAAS,EACrB,SACE,QAAU,OAAO,KAAK,SAAS,GAAK,EAC1C,KAAK,WAAa,KAAK,IAAI,QAAU,QAAQ,EAAI,KACjD,KAAK,YAAc,KAAK,YAAe,QAAU,UAAY,SAAY,IAAM,CACjF,MAGE,KAAK,WAAa,GAClB,KAAK,YAAc,EAErB,MAAM,MAAQ,SAAS,eAAe,aAAa,KAAK,EAAE,EACtD,QACF,MAAM,MAAM,YAAc,KAAK,WAAa,qBAAwB,KAAK,YAAc,oBAAsB,GAC7G,MAAM,MAAM,WAAc,KAAK,WAAa,wBAA0B,IAExE,MAAM,KAAO,SAAS,eAAe,kBAAkB,KAAK,EAAE,EAC1D,OAAM,KAAK,UAAY,eAAe,IAAI,GAC9C,mBAAmB,CACrB,CAOA,MAAM,WAAa,CAAE,QAAS,CAAC,EAAG,SAAU,CAAE,EAE9C,eAAe,cAAc,MAAO,MAAO,QAAS,CAClD,MAAM,IAAO,WAAW,QAAQ,KAAK,GAAK,WAAW,QAAQ,KAAK,GAAK,GAAK,EAC5E,GAAI,CAAC,OAAS,MAAM,OAAS,EAAG,CAC9B,MAAM,EAAI,SAAS,eAAe,iBAAiB,KAAK,EAAE,EACtD,IAAG,EAAE,MAAM,QAAU,QACzB,MACF,CACA,MAAM,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3F,CAAC,CAAE,KAAM,MAAO,EAAG,CAAE,KAAM,KAAM,CAAC,EAAI,MAAM,QAAQ,IAAI,CAC5D,GAAG,EAAE,OAAO,WAAY,CAAE,MAAO,CAAE,KAAM,KAAM,EAAG,OAAQ,cAAe,MAAO,CAAE,CAAC,EACnF,GAAG,EAAE,OAAO,WAAY,CAAE,MAAO,CAAE,IAAK,KAAM,EAAG,OAAQ,cAAe,MAAO,CAAE,CAAC,CACpF,CAAC,EACD,GAAI,MAAQ,WAAW,QAAQ,KAAK,EAAG,OAEvC,MAAM,SADW,CAAC,GAAI,QAAQ,CAAC,EAAI,GAAI,OAAO,CAAC,CAAE,EACvB,OAAO,CAAC,EAAE,EAAE,MAAQ,IAAI,UAAU,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EACpF,KAAO,SAAS,eAAe,iBAAiB,KAAK,EAAE,EAC7D,GAAI,CAAC,MAAQ,CAAC,UAAU,OAAQ,CAAM,OAAM,KAAK,MAAM,QAAU,QAAQ,MAAQ,CACjF,KAAK,UAAY,SAAS,IAAI,GAC5B;AAAA,uDACiD,KAAK,IAAI,KAAK,UAAU,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAAA,kBACpH,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC;AAAA,mFAC0C,EAAE,GAAG;AAAA,aAEpF,EAAE,KAAK,EAAE,EACT,KAAK,MAAM,QAAU,OACvB,CAEA,eAAe,cAAc,MAAO,QAAS,CAC3C,GAAI,YAAY,KAAK,EAAG,CACtB,YAAY,KAAK,EAAE,UAAc,GACjC,YAAY,KAAK,EAAE,UAAc,QAAQ,GACzC,YAAY,KAAK,EAAE,YAAc,QAAQ,KACzC,YAAY,KAAK,EAAE,IAAc,QAAQ,IAGzC,MAAM,WADU,SAAS,eAAe,iBAAiB,GAC7B,MACtB,UAAY,SAAS,eAAe,qBAAqB,GAAG,OAAS,SAErE,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EACjG,IAAI,MAAQ,EAEZ,GAAI,WAAY,CACd,KAAM,CAAE,KAAM,UAAW,EAAI,MAAM,OAAO,KAAK,gBAAgB,EAC5D,OAAO,OAAO,EAAE,GAAG,aAAc,QAAQ,EAAE,EAC3C,GAAG,aAAc,UAAU,EAAE,GAAG,cAAe,UAAU,EAAE,MAAM,CAAC,EACjE,aAAa,CAAC,IAAG,MAAQ,WAAW,CAAC,EAAE,MAC7C,CACA,GAAI,CAAC,MAAO,CACV,MAAM,UAAY,YAAc,SAAW,MAAQ,YAC7C,CAAE,KAAM,UAAW,EAAI,MAAM,OAAO,KAAK,gBAAgB,EAC5D,OAAO,OAAO,EAAE,GAAG,aAAc,QAAQ,EAAE,EAC3C,GAAG,aAAc,SAAS,EAAE,GAAG,cAAe,IAAI,EAAE,MAAM,CAAC,EAC1D,aAAa,CAAC,IAAG,MAAQ,WAAW,CAAC,EAAE,MAC7C,CACA,GAAI,CAAC,MAAO,CACV,MAAM,aAAe,YAAc,SAAW,YAAc,MACtD,CAAE,KAAM,QAAS,EAAI,MAAM,OAAO,KAAK,gBAAgB,EAC1D,OAAO,OAAO,EAAE,GAAG,aAAc,QAAQ,EAAE,EAC3C,GAAG,aAAc,YAAY,EAAE,GAAG,cAAe,IAAI,EAAE,MAAM,CAAC,EAC7D,WAAW,CAAC,IAAG,MAAQ,SAAS,CAAC,EAAE,MACzC,CAEA,YAAY,KAAK,EAAE,UAAgB,OAAS,EAC5C,YAAY,KAAK,EAAE,UAAgB,OAAS,EAC5C,YAAY,KAAK,EAAE,cAAgB,OAAS,EAC5C,YAAY,KAAK,EAAE,YAAgB,GAGnC,YAAY,KAAK,EAAE,gBAAkB,CAAC,EAEtC,KAAM,CAAE,KAAM,QAAS,EAAI,MAAM,OAAO,KAAK,gBAAgB,EAC1D,OAAO,OAAO,EAAE,GAAG,aAAc,QAAQ,EAAE,EAC3C,GAAG,aAAc,MAAM,EAAE,GAAG,cAAe,IAAI,EAAE,MAAM,CAAC,EACvD,WAAW,CAAC,IAAG,YAAY,KAAK,EAAE,UAAY,SAAS,CAAC,EAAE,OAE9D,gBAAgB,KAAK,CACvB,CACA,YAAY,EACZ,MAAM,KAAO,SAAS,eAAe,iBAAiB,KAAK,EAAE,EACzD,OAAM,KAAK,MAAM,QAAU,OACjC,CAmBA,MAAM,iBAAmB,IAAM,CAAC,CAAC,OAAO,GAAG,KAAK,kBAAkB,EAMlE,SAAS,aAAa,CAAE,MAAO,QAAS,QAAU,cAAe,OAAS,GAAO,YAAc,IAAK,EAAG,CACrG,OAAO,IAAI,QAAQ,SAAW,CAC5B,MAAM,KAAO,SAAS,cAAc,KAAK,EACzC,KAAK,MAAM,QAAU,uIACrB,KAAK,UAAY;AAAA;AAAA,4KAEqJ,KAAK,EAAE,SAAS,KAAK,CAAC;AAAA,yFACzG,OAAO;AAAA,YACpF,YAAc,kHAAkH,KAAK,EAAE,SAAS,WAAW,CAAC,wGAA0G,EAAE;AAAA;AAAA;AAAA,cAGtQ,QAAU,mDAAmD,OAAS,SAAW,SAAS,mBAAmB,KAAK,EAAE,SAAS,OAAO,CAAC,YAAc,EAAE;AAAA;AAAA,gBAG7J,MAAM,UAAY,IAAM,KAAK,cAAc,qBAAqB,EAC1D,MAAQ,IAAM,KAAK,cAAc,iBAAiB,EAClD,UAAY,IAAM,KAAK,cAAc,mBAAmB,EACxD,WAAa,KAAO,UAAU,GAAG,OAAS,IAAI,KAAK,EACnD,OAAU,QAAW,CACzB,SAAS,oBAAoB,UAAW,MAAO,EAAI,EACnD,KAAK,OAAO,EACZ,QAAQ,QAAU,YAAc,WAAW,EAAI,MAAM,CACvD,EACM,MAAS,GAAM,CACnB,GAAI,EAAE,MAAQ,SAAY,EAAE,eAAe,EAAG,EAAE,gBAAgB,EAAG,OAAO,EAAK,UACtE,EAAE,MAAQ,QAAS,CAC1B,GAAI,SAAS,gBAAkB,UAAU,EAAG,OAC5C,EAAE,eAAe,EAAG,EAAE,gBAAgB,EAAG,OAAO,CAAC,CAAC,MAAM,GAAK,CAAC,MAAM,EAAE,UAAY,SAAS,gBAAkB,MAAM,CAAC,CACtH,SACS,EAAE,MAAQ,MAAO,CACxB,EAAE,eAAe,EAAG,EAAE,gBAAgB,EACtC,MAAM,MAAQ,CAAC,UAAU,EAAG,UAAU,EAAG,MAAM,CAAC,EAAE,OAAO,IAAM,IAAM,CAAC,GAAG,QAAQ,EAC3E,GAAK,MAAM,QAAQ,SAAS,aAAa,GAC9C,OAAO,GAAK,GAAK,MAAM,MAAM,GAAK,UAAU,GAAG,MAAM,CACxD,CACF,EACA,KAAK,iBAAiB,QAAS,GAAK,CAClC,MAAM,IAAM,EAAE,OAAO,QAAQ,YAAY,GAAG,QAAQ,IAChD,MAAQ,MAAQ,MAAM,GAAG,UACzB,KAAK,OAAO,MAAQ,IAAI,CAC9B,CAAC,EACG,aACF,KAAK,iBAAiB,QAAS,IAAM,CAAM,MAAM,IAAG,MAAM,EAAE,SAAW,CAAC,WAAW,EAAG,CAAC,EAEzF,SAAS,iBAAiB,UAAW,MAAO,EAAI,GAI/C,SAAS,eAAe,SAAS,GAAK,SAAS,MAAM,YAAY,IAAI,EAClE,aAAe,MAAM,IAAG,MAAM,EAAE,SAAW,KAC9C,UAAU,GAAK,UAAU,GAAG,MAAM,CACrC,CAAC,CACH,CAUA,IAAI,OAAS,KAEb,eAAe,YAAY,MAAO,CAChC,GAAI,CAAC,MAAO,MAAO,CAAE,GAAI,GAAO,IAAK,kBAAmB,EACxD,GAAI,MAAM,mBAAqB,WAAY,MAAO,CAAE,GAAI,GAAO,IAAK,uDAAwD,EAC5H,GAAI,CAAC,YAAa,UAAW,QAAQ,EAAE,SAAS,MAAM,MAAM,EAAG,MAAO,CAAE,GAAI,EAAK,EACjF,GAAI,MAAM,SAAW,aAAc,CACjC,MAAM,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3F,CAAE,KAAM,IAAK,EAAI,MAAM,OAAO,KAAK,gBAAgB,EACtD,OAAO,oDAAoD,EAAE,GAAG,WAAY,MAAM,EAAE,EACjF,YAAc,MAAQ,CAAC,GAAG,KAAK,GAAK,EAAE,aAAe,EAAE,SAAS,EACtE,OAAI,YAAc,CAAC,WAAW,UAAU,YAAoB,CAAE,GAAI,GAAM,SAAU,WAAW,UAAU,eAAgB,EAChH,CAAE,GAAI,GAAO,IAAK,WAAa,eAAe,WAAW,UAAU,eAAe,iBAAmB,2BAA4B,CAC1I,CACA,MAAO,CAAE,GAAI,GAAO,IAAK,SAAS,MAAM,MAAM,GAAI,CACpD,CAGA,SAAS,cAAc,SAAU,SAAU,CACzC,MAAM,IAAM,CAAC,IAAK,KAAM,IAAK,QAAU,GAAG,KAAO,EAAE,IAAI,IAAM,GAAK,OAAO,MAAQ,EAAE,EAAE,YAAY,CAAC,IAAI,OAAO,GAAG,GAAK,CAAC,KAAK,OAAO,KAAK,GAAK,GAAG,QAAQ,CAAC,CAAC,GACnJ,GAAK,UAAY,CAAC,GAAG,IAAI,GAAK,IAAI,EAAE,WAAY,EAAE,aAAc,EAAE,SAAU,EAAE,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,EAC1G,GAAK,UAAY,CAAC,GAAG,IAAI,GAAK,IAAI,EAAE,UAAW,EAAE,YAAa,EAAE,KAAO,EAAG,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,EAC7G,OAAO,IAAM,CACf,CAGA,SAAS,cAAc,IAAK,SAAU,SAAU,OAAQ,CACtD,MAAM,MAAQ,CAAC,EACT,MAAQ,CAAC,EACf,OAAC,UAAY,CAAC,GAAG,QAAQ,GAAK,CAAE,MAAM,EAAI,EAAE,YAAc,KAAK,EAAE,YAAY,GAAI,MAAM,CAAC,EAAI,MAAM,CAAC,GAAK,CAAE,KAAM,EAAE,aAAc,OAAQ,EAAG,OAAQ,EAAG,SAAU,EAAE,WAAY,SAAU,IAAK,EAAG,MAAM,CAAC,EAAE,QAAW,EAAE,UAAY,CAAI,CAAC,GACtO,UAAY,CAAC,GAAG,QAAQ,GAAK,CAAE,MAAM,EAAI,EAAE,WAAa,KAAK,EAAE,WAAW,GAAI,MAAM,CAAC,EAAI,MAAM,CAAC,GAAK,CAAE,KAAM,EAAE,YAAa,OAAQ,EAAG,OAAQ,EAAG,SAAU,KAAM,SAAU,EAAE,SAAU,EAAG,MAAM,CAAC,EAAE,QAAW,EAAE,KAAO,EAAI,MAAM,CAAC,EAAE,SAAW,EAAE,SAAW,CAAC,EAC/P,OAAO,OAAO,KAAK,EAAE,QAAQ,GAAK,CAC3B,EAAE,OACG,EAAE,QAEN,EAAE,SAAW,EAAE,QAAQ,MAAM,KAAK,GAAG,EAAE,IAAI,KAAK,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,EACzE,EAAE,UAAY,MAAQ,EAAE,UAAY,MAAQ,KAAK,IAAI,EAAE,SAAW,EAAE,QAAQ,EAAI,MAAO,MAAM,KAAK,GAAG,EAAE,IAAI,cAAW,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,WAAQ,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,GAH5K,MAAM,KAAK,WAAW,EAAE,MAAM,MAAM,EAAE,IAAI,EAAE,EADjD,MAAM,KAAK,SAAS,EAAE,MAAM,MAAM,EAAE,IAAI,EAAE,CAM3D,CAAC,EAED,OAAO,QADQ,CAAE,cAAe,WAAY,QAAS,UAAW,SAAU,WAAY,MAAO,QAAS,MAAO,QAAS,aAAc,YAAa,aAAc,WAAY,CACtJ,EAAE,QAAQ,CAAC,CAAC,EAAG,KAAK,IAAM,EAAO,IAAI,CAAC,GAAK,OAAS,OAAO,CAAC,GAAK,KAAK,MAAM,KAAK,GAAG,KAAK,UAAU,CAAG,CAAC,EACxH,KAAK,KAAK,IAAI,aAAe,IAAM,OAAO,aAAe,EAAE,EAAI,MAAO,MAAM,KAAK,aAAU,OAAO,IAAI,aAAe,CAAC,EAAE,QAAQ,CAAC,CAAC,WAAQ,OAAO,OAAO,aAAe,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,EACnL,MAAM,KAAK,IAAI,GAAK,YAC7B,CAEA,eAAe,WAAW,QAAS,CACjC,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAAE,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EAC/G,GAAK,MAAM,YAAY,KAAK,EAClC,GAAI,CAAC,GAAG,GAAI,CAAE,GAAG,EAAE,MAAM,GAAG,OAAO,cAAgB,YAAY,8BAA8B,GAAG,GAAG,GAAI,UAAW,GAAI,EAAG,MAAQ,CACjI,MAAM,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3F,CAAE,KAAM,KAAM,EAAI,MAAM,OAAO,KAAK,aAAa,EAAE,OAAO,GAAG,EAAE,GAAG,WAAY,OAAO,EAE3F,MAAM,aAAa,EAAK,EACxB,MAAM,IAAM,CAAC,GAAI,IAAM,CAAE,MAAM,GAAK,SAAS,eAAe,EAAE,EAAO,KAAI,GAAG,MAAQ,GAAK,GAAI,EAC7F,IAAI,kBAAmB,MAAM,WAAW,EACxC,iBAAiB,EACjB,MAAM,cAAc,EACpB,MAAM,QAAU,SAAS,eAAe,qBAAqB,EACzD,SAAW,MAAM,aAAY,QAAQ,MAAQ,MAAM,YACvD,IAAI,mBAAoB,MAAM,YAAY,EAC1C,IAAI,kBAAmB,MAAM,QAAQ,EACrC,mBAAmB,EACnB,IAAI,kBAAmB,MAAM,aAAa,EAC1C,IAAI,iBAAkB,MAAM,OAAO,EACnC,IAAI,eAAgB,MAAM,KAAK,EAC/B,IAAI,eAAgB,MAAM,KAAK,EAC/B,IAAI,gBAAiB,MAAM,YAAY,EACvC,IAAI,eAAgB,MAAM,KAAK,EAC/B,IAAI,mBAAoB,OAAO,MAAM,YAAc,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,EACpE,IAAI,uBAAwB,MAAM,eAAiB,WAAW,EAC9D,kBAAoB,MAAM,aAAe,KACzC,mBAAmB,EAInB,MAAM,IAAM,SAAS,cAAc,uCAAuC,MAAM,cAAc,IAAI,EAC9F,MAAK,IAAI,QAAU,IACvB,MAAM,SAAW,SAAS,eAAe,qBAAqB,GAAG,QAAQ,kBAAkB,EACvF,WAAU,SAAS,UAAY,wEAAwE,KAAK,EAAE,SAAS,MAAM,gBAAkB,QAAQ,CAAC,oHACpG,KAAK,EAAE,SAAS,MAAM,gBAAkB,QAAQ,CAAC,mCAEzG,aAAe,OAAS,CAAC,GAAG,IAAI,IAAM,CACpC,UAAW,EAAE,YAAc,GAAI,YAAa,EAAE,cAAgB,GAAI,IAAK,EAAE,KAAO,GAChF,IAAK,EAAE,UAAY,EAAG,UAAW,EAAE,YAAc,EAAG,UAAW,EAAE,YAAc,EAC/E,UAAW,EAAE,gBAAkB,EAAE,YAAc,EAAG,cAAe,EAAE,gBAAkB,KACrF,WAAY,CAAC,CAAC,EAAE,iBAAkB,YAAa,EAAE,cAAgB,EACjE,YAAa,GAAO,UAAW,GAC/B,UAAW,EAAE,YAAc,KAAM,IAAK,EAAE,WAAc,UAAU,KAAK,GAAK,EAAE,KAAO,EAAE,UAAU,GAAG,KAAO,QAAW,MACtH,EAAE,EACF,MAAM,YAAc,OAAS,CAAC,GAAG,KAAK,GAAK,EAAE,kBAAoB,EAAE,eAAe,EAC9E,YAAY,IAAI,yBAA0B,WAAW,eAAe,EAExE,MAAM,WAAa,YAAY,OAAO,CAAC,EAAG,IAAM,GAAK,EAAE,KAAO,IAAM,EAAE,WAAa,GAAI,CAAC,EACpF,YAAc,MAAM,aAAe,GAAK,OAAS,IAAI,mBAAoB,OAAO,EAAG,IAAI,qBAAsB,WAAa,MAAM,aAAa,QAAQ,CAAC,CAAC,GAC3J,YAAY,EACZ,YAAY,EAEZ,MAAM,QAAU,SAAS,eAAe,iBAAiB,EACrD,UAAS,QAAQ,YAAc,SAAS,MAAM,YAAY,GAAG,GAAG,SAAW,QAAQ,GAAG,QAAQ,IAAM,EAAE,IAC1G,SAAS,eAAe,kBAAkB,GAAG,OAAO,EACpD,MAAM,QAAU,SAAS,eAAe,oBAAoB,EACxD,UAAS,QAAQ,UAAY,4CACjC,OAAS,CAAE,MAAO,MAAO,OAAS,CAAC,EAAG,SAAU,GAAG,UAAY,IAAK,CACtE,CAEA,eAAe,eAAe,EAAG,CAC/B,MAAM,IAAM,OAAO,MACb,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAE3F,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAAE,GAAI,CAAE,GAAI,IAAI,EAAG,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EAC9G,GAAK,MAAM,YAAY,KAAK,EAClC,GAAI,CAAC,GAAG,GAAI,CAAE,GAAG,EAAE,MAAM,GAAG,EAAE,WAAW,8BAA8B,GAAG,GAAG,wBAAyB,UAAW,GAAI,EAAG,EAAE,WAAW,EAAG,MAAQ,CAGhJ,MAAM,SAAW,YAAY,IAAI,OAAS,CACxC,SAAU,IAAI,GAAI,WAAY,KAAK,WAAa,KAAM,WAAY,KAAK,WAAa,KAAM,aAAc,KAAK,YAAa,IAAK,KAAK,KAAO,GAC3I,SAAU,KAAK,KAAO,EAAG,WAAY,KAAK,WAAa,EAAG,aAAc,KAAK,KAAO,IAAM,KAAK,WAAa,GAC5G,WAAY,KAAK,WAAa,EAAG,eAAgB,KAAK,eAAiB,KACvE,iBAAkB,KAAK,YAAc,GAAO,gBAAiB,KAAK,WAAa,EAAE,eAAiB,KAClG,aAAc,KAAK,WAAa,KAAK,OAAO,KAAK,aAAe,GAAK,GAAG,EAAI,IAAM,IACpF,EAAE,EACI,CAAE,KAAM,SAAU,MAAO,MAAO,EAAI,MAAM,OAAO,KAAK,aAAa,EAAE,OAAO,QAAQ,EAAE,OAAO,IAAI,EACvG,GAAI,OAAQ,CAAE,GAAG,EAAE,MAAM,yFAAyF,OAAO,OAAO,GAAI,QAAS,GAAK,EAAG,EAAE,WAAW,EAAG,MAAQ,CAG7K,MAAM,OAAS,OAAO,MAAM,IAAI,GAAK,EAAE,EAAE,EACzC,GAAI,OAAO,OAAQ,CACjB,KAAM,CAAE,MAAO,MAAO,EAAI,MAAM,OAAO,KAAK,aAAa,EAAE,OAAO,EAAE,GAAG,KAAM,MAAM,EACnF,GAAI,OAAQ,CACV,MAAM,OAAO,KAAK,aAAa,EAAE,OAAO,EAAE,GAAG,MAAO,UAAY,CAAC,GAAG,IAAI,GAAK,EAAE,EAAE,CAAC,EAClF,GAAG,EAAE,MAAM,gGAAgG,OAAO,OAAO,GAAI,QAAS,GAAK,EAC3I,EAAE,WAAW,EAAG,MAClB,CACF,CAEA,MAAM,OAAS,CACb,YAAa,EAAE,WAAY,WAAY,EAAE,UAAW,cAAe,EAAE,SAAU,YAAa,EAAE,kBAC9F,aAAc,EAAE,YAAa,SAAU,EAAE,SAAU,QAAS,EAAE,QAAS,MAAO,EAAE,EAAE,cAAc,EAAG,MAAO,EAAE,EAAE,cAAc,EAC5H,aAAc,EAAE,EAAE,eAAe,GAAK,IAAI,cAAgB,KAC1D,MAAO,CAAC,EAAE,EAAE,cAAc,EAAG,GAAG,YAAY,QAAQ,IAAM,EAAE,iBAAmB,CAAC,GAAG,IAAI,GACrF,YAAY,EAAE,GAAG,MAAM,EAAE,WAAW,SAAS,EAAE,OAAO,mCAAmC,CAAC,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,KAAK,EACzH,YAAa,EAAE,MAAO,mBAAoB,EAAE,eAAgB,cAAe,EAAE,aAC7E,QAAS,aAAa,IAAM,IAAI,SAAW,KAAM,mBAAoB,aAAa,MAAQ,IAAI,oBAAsB,KACpH,WAAY,IAAI,KAAK,EAAE,YAAY,CACrC,EAGA,IAAI,QAAU,GACV,IAAI,iBAAmB,QAAU,EAAE,OAAS,IAAI,aAAe,GAAK,MACtE,OAAO,eAAiB,UACxB,QAAU,SAAM,EAAE,MAAQ,IAAI,aAAa,QAAQ,CAAC,CAAC,2CAC5C,IAAI,iBAAmB,QAAU,EAAE,OAAS,IAAI,aAAe,GAAK,OAC7E,QAAU,SAAM,IAAI,YAAc,EAAE,OAAO,QAAQ,CAAC,CAAC,wCAEvD,MAAM,QAAU,cAAc,IAAK,OAAO,MAAO,YAAa,MAAM,EAC9D,CAAE,MAAO,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,IAAI,GAAI,MAAM,EAC/D,OAAO,GAAG,EAAE,MAAM,GAAG,EAAE,WAAW,uEAAuE,MAAM,OAAO,6BAA8B,UAAW,IAAK,EAGxK,UAAW,QAAQ,YACjB,UAAW,OAAQ,KAAK,iBAAmB,CAAC,EAAI,CAC9C,GAAI,IAAI,cAAgB,EAAE,YAAa,SACvC,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,uBAAwB,CAAE,OAAQ,8BAA+B,GAAI,CAAE,GAAI,IAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EACxK,OAAS,KAAK,IAAI,IAAI,IAAK,OAAO,eAAiB,CAAC,EAC1D,GAAI,QAAU,EAAG,SACjB,KAAM,CAAE,MAAO,QAAS,EAAI,MAAM,GAAG,EAAE,OAAO,uBAAwB,IAAI,QAAS,CACjF,cAAe,KAAK,IAAI,GAAI,MAAM,eAAiB,GAAK,MAAM,EAAG,cAAe,KAAK,IAAI,GAAI,MAAM,eAAiB,GAAK,MAAM,CACjI,CAAC,EACD,GAAI,SAAU,SACd,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,CAAE,GAAI,CAAE,WAAY,IAAI,UAAW,aAAc,IAAI,WAAY,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EACpK,OAAO,MAAM,GAAG,EAAE,OAAO,eAAgB,MAAM,GAAI,CAAE,wBAAyB,KAAK,IAAI,GAAI,MAAM,yBAA2B,GAAK,MAAM,CAAE,CAAC,EAC9I,MAAM,YAAY,IAAI,GAAI,2BAA4B,GAAI,GAAI,GAAG,MAAM,MAAM,KAAK,WAAW,kBAAkB,IAAI,OAAO,aAAa,CACzI,CAKF,MAAM,KAAO,CAAC,EAAG,KAAO,CAAC,EACzB,OAAO,MAAM,QAAQ,GAAK,CAAM,EAAE,aAAY,KAAK,EAAE,UAAU,GAAK,KAAK,EAAE,UAAU,GAAK,IAAM,EAAE,UAAY,GAAI,CAAC,EACnH,YAAY,QAAQ,GAAK,CAAM,EAAE,YAAW,KAAK,EAAE,SAAS,GAAK,KAAK,EAAE,SAAS,GAAK,IAAM,EAAE,KAAO,GAAI,CAAC,EAC1G,MAAM,MAAQ,CAAC,EACX,IAAI,eAAiB,EAAE,aACzB,OAAO,QAAQ,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAG,CAAC,IAAM,MAAM,KAAK,CAAC,EAAG,IAAI,aAAc,CAAC,CAAC,CAAC,CAAC,EAC9E,OAAO,QAAQ,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAG,CAAC,IAAM,MAAM,KAAK,CAAC,EAAG,EAAE,YAAa,CAAC,CAAC,CAAC,GAE1E,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,IAAI,EAAG,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,EAAE,QAAQ,GAAK,CAAE,MAAM,GAAK,KAAK,CAAC,GAAK,IAAM,KAAK,CAAC,GAAK,GAAQ,GAAG,MAAM,KAAK,CAAC,EAAG,EAAE,YAAa,CAAC,CAAC,CAAG,CAAC,EAE7J,MAAM,cAAgB,CAAC,EACvB,SAAW,CAAC,EAAG,GAAI,CAAC,IAAK,MAAO,CAC9B,GAAI,CAAC,GAAI,SACT,KAAM,CAAE,KAAM,EAAG,EAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,CAAE,GAAI,CAAE,WAAY,EAAG,aAAc,EAAG,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EAC5I,GAAI,CAAC,GAAI,CAAM,EAAI,GAAG,cAAc,KAAK,CAAC,EAAG,QAAU,CACvD,KAAM,CAAE,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,GAAG,GAAI,CAAE,aAAc,KAAK,IAAI,GAAI,GAAG,cAAgB,GAAK,CAAC,CAAE,CAAC,EAChH,OAAO,cAAc,KAAK,CAAC,CACjC,CAEA,MAAM,YAAY,IAAI,GAAI,gBAAiB,IAAI,OAAQ,IAAI,OAAQ,OAAO,EAG1E,MAAM,MAAQ,CAAC,EACX,SAAS,MAAM,KAAK,QAAQ,KAAK,CAAC,EAClC,GAAG,SAAU,MAAM,KAAK,YAAY,GAAG,QAAQ,wCAAwC,EAClF,CAAC,UAAW,QAAQ,EAAE,SAAS,IAAI,MAAM,GAAG,MAAM,KAAK,4DAA4D,EAC5H,KAAM,CAAE,KAAM,IAAK,EAAI,MAAM,OAAO,KAAK,WAAW,EAAE,OAAO,IAAI,EAAE,GAAG,WAAY,IAAI,EAAE,EAAE,GAAG,uBAAwB,EAAK,EAAE,MAAM,CAAC,EAC/H,MAAM,QAAQ,MAAM,KAAK,qDAAqD,EAC9E,cAAc,QAAQ,MAAM,KAAK,0EAA0E,EAE/G,OAAS,KACT,YAAc,CAAC,EACf,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,GAAG,EAAE,WAAW,aAAa,OAAO,IAAI,MAAM,OAAS,IAAM,MAAM,KAAK,GAAG,EAAI,EAAE,GAAI,MAAM,OAAS,UAAY,UAAW,MAAM,OAAS,KAAQ,GAAI,EACjK,KAAK,CACP,CAEA,eAAe,UAAU,IAAK,WAAW,GAAO,CAC9C,MAAM,QAAU,KAAO,SAAS,eAAe,WAAW,mBAAmB,oBAAoB,EAC9F,UAAU,QAAQ,SAAS,GAAM,QAAQ,UAAU,sDACtD,MAAM,WAAW,IAAI,CAAE,GAAG,SAAW,OAAO,CAAE,QAAQ,SAAS,GAAO,QAAQ,UAAU,2CAA4C,MAAQ,CAAK,UAAU,QAAQ,SAAS,GAAO,QAAQ,UAAU,WAAW,gDAAgD,gCAAiC,aAAa,OAAO,EAAG,kBAAkB,gBAAmB,EACvV,EAAI,IAAM,SAAS,eAAe,EAAE,GAAG,OAAO,KAAK,GAAK,GACxD,SAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,QAAQ,OAAO,GAAG,EAClE,WAAa,EAAE,iBAAiB,EAChC,SAAa,EAAE,iBAAiB,EAChC,QAAa,EAAE,gBAAgB,EAC/B,UAAa,EAAE,kBAAkB,EACjC,YAAc,EAAE,kBAAkB,EAExC,GAAI,CAAC,SAAY,CAAE,GAAG,EAAE,MAAM,uBAAwB,OAAO,EAAG,WAAW,EAAG,MAAQ,CAKtF,CACE,MAAM,UAAY,SAAS,eAAe,iBAAiB,GAAG,kBAAkB,CAAC,GAAG,aAAe,IAAI,KAAK,EAAE,YAAY,EACpH,eAAiB,OAAO,GAAG,OAAO,oBAAsB,CAAC,GAAG,SAAS,QAAQ,EAC7E,UAAY,EAAE,eAAe,EACnC,GAAI,gBAAkB,CAAC,WAAc,QAAU,YAAc,OAAO,MAAM,cAAgB,CACxF,GAAG,EAAE,MAAM,oBAAoB,SAAS,eAAe,iBAAiB,GAAG,kBAAkB,CAAC,GAAG,aAAa,KAAK,GAAK,aAAa,uCAAwC,QAAS,GAAI,EAC1L,SAAS,eAAe,eAAe,GAAG,MAAM,EAChD,WAAW,EAAG,MAChB,CACF,CACA,GAAI,CAAC,UAAY,CAAE,GAAG,EAAE,MAAM,yBAA0B,OAAO,EAAG,WAAW,EAAG,MAAQ,CACxF,GAAI,CAAC,YAAa,CAAE,GAAG,EAAE,MAAM,uCAAwC,OAAO,EAAG,WAAW,EAAG,MAAQ,CACvG,GAAI,CAAC,WAAY,CAAE,GAAG,EAAE,MAAM,2BAA4B,OAAO,EAAG,WAAW,EAAG,MAAQ,CAC1F,GAAI,CAAC,SAAY,CAAE,GAAG,EAAE,MAAM,4BAA6B,OAAO,EAAG,WAAW,EAAG,MAAQ,CAC3F,GAAI,CAAC,QAAY,CAAE,GAAG,EAAE,MAAM,+BAAgC,OAAO,EAAG,WAAW,EAAG,MAAQ,CAC9F,GAAI,CAAC,YAAY,OAAQ,CAAE,GAAG,EAAE,MAAM,+BAAgC,OAAO,EAAG,WAAW,EAAG,MAAQ,CAGtG,GADmB,YAAY,OAAO,GAAK,CAAC,EAAE,WAAW,EAC1C,OAAQ,CAAE,GAAG,EAAE,MAAM,qCAAsC,OAAO,EAAG,WAAW,EAAG,MAAQ,CAE1G,MAAM,UAAY,SAAS,eAAe,qBAAqB,GAAG,OAAS,SACrE,aAAe,SAAS,eAAe,sBAAsB,GAAG,OAAS,YACzE,SAAY,YAAY,OAAO,CAAC,EAAG,IAAM,GAAM,EAAE,KAAK,IAAM,EAAE,WAAW,GAAK,CAAC,EAC/E,SAAY,SAAS,eAAe,kBAAkB,GAAG,OAAS,OAClE,QAAY,WAAW,SAAS,eAAe,mBAAmB,GAAG,KAAK,GAAK,EACrF,IAAI,QAAU,EACX,WAAa,OAAS,QAAU,IAAK,QAAU,UAAY,QAAU,MACrE,WAAa,SAAW,QAAU,IAAG,QAAU,KAAK,IAAI,QAAS,QAAQ,GAC5E,MAAM,MAAQ,KAAK,IAAI,EAAG,SAAW,OAAO,EAM5C,IAAI,YACJ,GAAI,QAKF,GAJA,YAAc,OAAO,MAAM,aAIvB,OAAO,MAAM,YAAc,cAAc,OAAO,MAAO,WAAW,EAAG,CACvE,MAAM,aAAa,CACjB,MAAO,qBACP,QAAS,GAAG,KAAK,EAAE,SAAS,WAAW,CAAC,yKACxC,QAAS,IACX,CAAC,EACD,WAAW,EAAG,MAChB,MACK,CACL,KAAM,CAAE,KAAM,SAAU,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CACtD,OAAQ,eAAgB,MAAO,CAAE,aAAc,MAAO,EAAG,MAAO,CAAE,IAAK,eAAgB,IAAK,EAAM,EAAG,MAAO,CAC9G,CAAC,EACD,YAAc,KAAK,EAAE,YAAY,MAAO,YAAY,CAAC,GAAG,YAAY,CACtE,CAIA,IAAI,kBAAoB,KAIpB,KAAO,KACX,GAAI,kBAAmB,CACrB,KAAM,CAAE,KAAM,MAAO,EAAI,MAAM,GAAG,EAAE,OAAO,YAAa,CACtD,GAAI,CAAE,GAAI,iBAAkB,EAAG,YAAa,EAC9C,CAAC,EACD,KAAO,QAAU,IACnB,CACA,MAAM,eAAiB,EAAE,cAAc,EACvC,GAAI,CAAC,MAAQ,eAAgB,CAC3B,KAAM,CAAE,KAAM,OAAQ,EAAI,MAAM,GAAG,EAAE,OAAO,YAAa,CACvD,GAAI,CAAE,MAAO,eAAe,KAAK,EAAG,UAAW,EAAK,EAAG,YAAa,EACtE,CAAC,EACD,KAAO,SAAW,IACpB,CAEE,GAAI,OACF,kBAAoB,KAAK,GACrB,YAAc,aAAe,KAAK,aAAe,GAAG,CACtD,KAAM,CAAE,KAAM,IAAK,EAAI,MAAM,GAAG,EAAE,OAAO,sBAAuB,CAC9D,GAAI,CAAE,YAAa,KAAK,GAAI,OAAQ,QAAS,CAC/C,CAAC,EACK,aAAe,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,IAAM,IAAM,EAAE,QAAQ,IAAI,EAAE,aAAa,IAAK,CAAC,EAClF,UAAY,KAAK,aAAe,YACtC,GAAI,MAAQ,WAMN,CALY,MAAM,aAAa,CACjC,MAAO,uBACP,QAAS,qBAAqB,KAAK,EAAE,SAAS,KAAK,aAAa,CAAC,kCAA+B,KAAK,aAAa,QAAQ,CAAC,CAAC,wBAAqB,YAAY,QAAQ,CAAC,CAAC,uBAAoB,MAAM,QAAQ,CAAC,CAAC,mCAAgC,MAAQ,WAAW,QAAQ,CAAC,CAAC,YACxQ,QAAS,aACX,CAAC,EACa,CAAE,WAAW,EAAG,MAAQ,CAE1C,CAUJ,MAAM,mBAAqB,SAAS,cAAc,sCAAsC,GAAG,OAAS,SAMpG,GAAI,YAAc,aAAe,CAAC,mBAAqB,qBAAuB,OAAQ,CACpF,MAAM,aAAa,CACjB,MAAO,mCACP,QAAS,+SACN,iBAAiB,EACd,uGACA,6EACJ,8EACF,QAAS,IACX,CAAC,EACD,WAAW,EACX,MACF,CAEA,MAAM,eAAiB,YAAY,KAAK,GAAK,EAAE,UAAU,EACnD,eAAiB,SAAS,eAAe,wBAAwB,GAAG,OAAO,KAAK,GAAK,KAC3F,GAAI,gBAAkB,CAAC,eAAgB,CAAE,GAAG,EAAE,MAAM,+CAAgD,OAAO,EAAG,WAAW,EAAG,MAAQ,CASpI,MAAM,cAAgB,CAAC,EACvB,YAAY,QAAQ,GAAK,CAClB,EAAE,YACF,cAAc,EAAE,SAAS,IAAG,cAAc,EAAE,SAAS,EAAI,CAAE,KAAM,EAAE,YAAa,IAAK,CAAE,GAC5F,cAAc,EAAE,SAAS,EAAE,KAAQ,EAAE,KAAO,EAC9C,CAAC,EACD,MAAM,WAAa,CAAC,EACpB,IAAI,QAAU,GACd,SAAW,CAAC,UAAW,IAAI,IAAK,OAAO,QAAQ,aAAa,EAAG,CAC7D,KAAM,CAAE,KAAM,EAAG,EAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,CACrD,GAAI,CAAE,WAAY,UAAW,aAAc,WAAY,EAAG,YAAa,GAAM,gBAAiB,EAChG,CAAC,EACK,KAAO,KAAK,IAAI,GAAI,IAAI,yBAA2B,GAAK,mBAAmB,UAAW,WAAW,CAAC,EAIlG,QAAW,QAAU,OAAO,MAAM,eAAiB,YACrD,OAAO,MAAM,OAAO,GAAK,EAAE,aAAe,SAAS,EAAE,OAAO,CAAC,EAAG,IAAM,GAAK,EAAE,UAAY,GAAI,CAAC,EAAI,EAChG,MAAQ,IAAI,UAAY,IAAM,IAAI,cAAgB,GAAK,KAAO,QACpE,GAAI,KAAK,KAAO,KAAM,SACtB,IAAI,SAAW,GACf,GAAI,KAAO,EAAG,CACZ,QAAU,GAGV,KAAM,CAAE,KAAM,OAAQ,EAAI,MAAM,GAAG,EAAE,OAAO,uBAAwB,CAClE,OAAQ,kDACR,GAAI,CAAE,WAAY,UAAW,aAAc,WAAY,EAAG,gBAAiB,EAC7E,CAAC,EACK,MAAQ,CAAC,GAAG,IAAI,KAAK,SAAW,CAAC,GAAG,OAAO,IAAM,EAAE,eAAiB,GAAK,CAAC,EAC7E,IAAI,GAAK,EAAE,oBAAoB,aAAa,EAAE,OAAO,OAAO,CAAC,CAAC,EACjE,SAAW,KAAK,IAAI,aAAa,MAAM,OAAS,MAAM,KAAK,IAAI,EAAI,mBAAmB,GACxF,CACA,WAAW,KAAK,GAAG,KAAK,IAAI,WAAW,KAAK,GAAG,KAAK,KAAK,IAAI,EAAG,IAAI,CAAC,aAAa,QAAQ,EAAE,CAC9F,CACA,GAAI,WAAW,QAOT,CANY,MAAM,aAAa,CACjC,MAAO,mBACP,QAAS,WAAW,IAAI,GAAK,KAAK,EAAE,SAAS,CAAC,CAAC,EAAE,KAAK,MAAM,GACzD,QAAU,0IAA4I,IACzJ,QAAS,aACX,CAAC,EACa,CAAE,WAAW,EAAG,MAAQ,CAUxC,MAAM,cAAgB,IAAI,KAAK,KAAK,IAAI,EAAI,GAAK,GAAK,EAAE,YAAY,EAC9D,CAAE,KAAM,YAAa,EAAI,OAAS,CAAE,KAAM,CAAC,CAAE,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CACjF,OAAQ,0GACR,IAAK,CAAE,WAAY,aAAc,EACjC,MAAO,CAAE,IAAK,aAAc,IAAK,EAAM,EACvC,MAAO,EACT,CAAC,EACK,SAAW,GAAK,OAAO,GAAK,EAAE,EAAE,YAAY,EAAE,QAAQ,OAAQ,GAAG,EAAE,KAAK,EACxE,OAAW,GAAK,OAAO,GAAK,EAAE,EAAE,YAAY,EAAE,QAAQ,OAAQ,EAAE,EAChE,OAAS,OAAS,CACtB,MAAM,EAAI,CAAC,EACX,aAAM,QAAQ,GAAK,CACjB,MAAM,EAAI,EAAE,IAAM,KAAK,EAAE,GAAG,GAAK,KAAK,SAAS,EAAE,IAAI,CAAC,GACtD,EAAE,CAAC,GAAK,EAAE,CAAC,GAAK,IAAM,OAAO,EAAE,GAAG,GAAK,EACzC,CAAC,EACM,KAAK,UAAU,OAAO,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,GAAK,CAAC,EAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CACjE,EACM,WAAa,OAAO,YAAY,IAAI,IAAM,CAAE,IAAK,EAAE,UAAW,KAAM,EAAE,YAAa,IAAK,EAAE,KAAO,CAAE,EAAE,CAAC,EACtG,aAAe,cAAgB,CAAC,GAAG,KAAK,GACxC,EAAE,SAAW,aAGb,EAFkB,mBAAqB,EAAE,cAAgB,mBACvD,SAAS,EAAE,aAAa,IAAM,SAAS,QAAQ,GAAK,OAAO,EAAE,QAAQ,IAAM,OAAO,QAAQ,GACtE,GACnB,QAAQ,EAAE,aAAe,CAAC,GAAG,IAAI,IAAM,CAAE,IAAK,EAAE,WAAY,KAAM,EAAE,aAAc,IAAK,EAAE,QAAS,EAAE,CAAC,IAAM,UACnH,EACD,IAAI,gBAAkB,KACtB,GAAI,YAAa,CACf,MAAM,OAAS,MAAM,aAAa,CAChC,MAAO,2BACP,QAAS,WAAW,KAAK,EAAE,SAAS,YAAY,YAAY,CAAC,4DAA4D,KAAK,EAAE,SAAS,QAAQ,CAAC,iGAClJ,QAAS,gBACT,OAAQ,GACR,YAAa,2CACf,CAAC,EACD,GAAI,CAAC,OAAQ,CAAE,WAAW,EAAG,MAAQ,CACrC,gBAAkB,GAAG,MAAM,gBAAgB,YAAY,YAAY,GACrE,CAEA,GAAI,OAAQ,CAAE,MAAM,eAAe,CAAE,QAAS,WAAY,EAAG,YAAa,SAAU,kBAAmB,YAAa,WAClH,UAAW,aAAc,SAAU,QAAS,MAAO,eAAgB,cAAe,CAAC,EAAG,MAAQ,CAEhG,MAAM,cAAgB,SAAS,cAAc,sCAAsC,GAAG,OAAS,SACzF,gBAAkB,gBAAkB,SACtC,IAAI,KAAK,KAAK,IAAI,EAAI,MAAc,GAAK,GAAI,EAAE,YAAY,EAC3D,KAEE,IAAM,IAAI,KACV,cAAgB,IAAI,KAAK,GAAG,SAAS,IAAI,IAAI,aAAa,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,EAAE,EAEjF,IAAI,MAAO,MACX,QAAS,QAAU,EAAG,QAAU,EAAG,UAAW,CAC5C,MAAM,OAAS,MAAM,GAAG,EAAE,OAAO,SAAU,CACzC,aAAoB,YACpB,YAAoB,WACpB,WAAoB,UACpB,iBAAoB,SACpB,cAAoB,SACpB,YAAoB,kBACpB,aAAoB,YACpB,SACA,QACA,MAAoB,EAAE,cAAc,EACpC,MAAoB,EAAE,cAAc,EACpC,aAAoB,EAAE,eAAe,GAAK,YAE1C,MAAoB,CAAC,EAAE,cAAc,EAAG,GAAG,YAAY,QAAQ,IAAM,EAAE,iBAAmB,CAAC,GAAG,IAAI,GAC5E,YAAY,EAAE,GAAG,MAAM,EAAE,WAAW,SAAS,EAAE,OAAO,mCAAmC,CAAC,CAAC,EAC1F,OAAO,OAAO,EAAE,KAAK,KAAK,EACjD,OAAoB,YACpB,WAAoB,cAAc,YAAY,EAC9C,eAAoB,cACpB,kBAAoB,gBACpB,YAAoB,MACpB,mBAAoB,eACpB,cAAoB,aACpB,QAAoB,aAAa,IAAM,KACvC,mBAAoB,aAAa,MAAQ,KACzC,sBAAuB,YAAY,KAAK,GAAK,EAAE,WAAW,EAAI,EAAI,EAClE,WAAoB,OAAO,GAAG,KAAK,MAAM,EAC3C,CAAC,EAKD,GAJA,MAAQ,OAAO,KACf,MAAQ,OAAO,MACX,CAAC,OAED,EADW,MAAM,OAAS,SAAW,iBAAiB,KAAK,MAAM,SAAS,EAAE,GACnE,MAEb,YAAc,KAAK,EAAE,YAAY,MAAO,WAAW,CACrD,CAEA,GAAI,MAAO,CAAE,GAAG,EAAE,MAAM,2BAA6B,MAAM,QAAS,OAAO,EAAG,WAAW,EAAG,MAAQ,CAMpG,MAAM,aAAe,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EACjG,SAAW,YAAY,IAAI,OAAS,CACxC,SAAkB,MAAM,GACxB,WAAkB,KAAK,WAAa,KACpC,WAAkB,KAAK,WAAa,KACpC,aAAkB,KAAK,YACvB,IAAkB,KAAK,KAAO,GAC9B,SAAkB,KAAK,KAAO,EAC9B,WAAkB,KAAK,WAAa,EACpC,aAAmB,KAAK,KAAK,IAAM,KAAK,WAAW,GACnD,WAAkB,KAAK,WAAa,EACpC,eAAkB,KAAK,eAAiB,KACxC,iBAAkB,KAAK,YAAc,GACrC,gBAAkB,KAAK,WAAa,eAAiB,KACrD,aAAkB,KAAK,WAAa,KAAK,OAAO,KAAK,aAAe,GAAK,GAAG,EAAI,IAAM,IACxF,EAAE,EACI,CAAE,MAAO,UAAW,EAAI,MAAM,aAAa,KAAK,aAAa,EAAE,OAAO,QAAQ,EACpF,GAAI,WAAY,CAId,KAAM,CAAE,MAAO,SAAU,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,MAAM,EAAE,EAC7D,WACF,GAAG,EAAE,MAAM,SAAS,WAAW,2GAA2G,WAAW,gCAAgC,WAAW,OAAO,GAAI,QAAS,IAAK,EACzN,KAAK,GAEL,GAAG,EAAE,MAAM,0GAA0G,WAAW,OAAO,GAAI,QAAS,GAAK,EAE3J,WAAW,EACX,MACF,CACA,MAAM,YAAY,MAAM,GAAI,gBAAiB,GAAI,YAAa,aAAa,QAAQ,gBAAa,MAAM,QAAQ,CAAC,CAAC,EAAE,EAC9G,iBAAiB,MAAM,YAAY,MAAM,GAAI,+BAAgC,GAAI,YAAa,eAAe,EAQjH,MAAM,gBAAkB,CAAC,EACzB,UAAW,QAAQ,YACjB,UAAW,OAAQ,KAAK,iBAAmB,CAAC,EAAI,CAC9C,GAAI,IAAI,cAAgB,YAAa,SACrC,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,uBAAwB,CAChE,OAAQ,8BAA+B,GAAI,CAAE,GAAI,IAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EACtG,CAAC,EACK,OAAS,KAAK,IAAI,IAAI,IAAK,OAAO,eAAiB,CAAC,EAC1D,GAAI,QAAU,EAAG,CAAE,gBAAgB,KAAK,GAAG,KAAK,WAAW,kCAAkC,IAAI,OAAO,EAAE,EAAG,QAAU,CACvH,KAAM,CAAE,MAAO,QAAS,EAAI,MAAM,GAAG,EAAE,OAAO,uBAAwB,IAAI,QAAS,CACjF,cAAe,KAAK,IAAI,GAAI,MAAM,eAAiB,GAAK,MAAM,EAC9D,cAAe,KAAK,IAAI,GAAI,MAAM,eAAiB,GAAK,MAAM,CAChE,CAAC,EACD,GAAI,SAAU,CAAE,gBAAgB,KAAK,GAAG,KAAK,WAAW,kBAAkB,IAAI,OAAO,SAAS,EAAG,QAAU,CAC3G,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,CACxD,GAAI,CAAE,WAAY,IAAI,UAAW,aAAc,IAAI,WAAY,EAAG,YAAa,GAAM,gBAAiB,EACxG,CAAC,EACG,OACF,MAAM,GAAG,EAAE,OAAO,eAAgB,MAAM,GAAI,CAC1C,wBAAyB,KAAK,IAAI,GAAI,MAAM,yBAA2B,GAAK,MAAM,CACpF,CAAC,EAEH,MAAM,YAAY,MAAM,GAAI,2BAA4B,GAAI,GAAI,GAAG,MAAM,MAAM,KAAK,WAAW,kBAAkB,IAAI,OAAO,aAAa,EACrI,OAAS,IAAI,KAAK,gBAAgB,KAAK,GAAG,KAAK,WAAW,UAAU,MAAM,OAAO,IAAI,GAAG,kBAAkB,IAAI,OAAO,EAAE,CAC7H,CAEE,gBAAgB,QAClB,GAAG,EAAE,MAAM,SAAS,WAAW,oEAAoE,gBAAgB,KAAK,IAAI,CAAC,2CAA4C,UAAW,IAAK,EAM3L,MAAM,cAAgB,CAAC,EACvB,UAAW,QAAQ,YAAa,CAC9B,GAAI,CAAC,KAAK,UAAW,SACrB,KAAM,CAAE,KAAM,GAAI,MAAO,OAAQ,EAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,CACrE,GAAI,CAAE,WAAY,KAAK,UAAW,aAAc,WAAY,EAAG,YAAa,GAAM,gBAAiB,EACrG,CAAC,EACD,GAAI,QAAS,CAAE,cAAc,KAAK,KAAK,WAAW,EAAG,QAAU,CAC/D,GAAI,GAAI,CACN,KAAM,CAAE,MAAO,YAAa,EAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,GAAG,GAAI,CACvE,cAAe,GAAG,cAAgB,IAAM,KAAK,KAAO,EACtD,CAAC,EACG,cAAc,cAAc,KAAK,KAAK,WAAW,CACvD,CACF,CACI,cAAc,SAChB,MAAM,YAAY,MAAM,GAAI,2BAA4B,GAAI,GAAI,iBAAiB,cAAc,KAAK,IAAI,CAAC,EAAE,EAC3G,GAAG,EAAE,MAAM,SAAS,WAAW,gDAAgD,cAAc,KAAK,IAAI,CAAC,+BAAgC,UAAW,IAAK,GAKzJ,MAAM,GAAG,EAAE,OAAO,yBAA0B,CAC1C,WAAe,OAAO,GAAG,KAAK,SAAS,GACvC,SACA,cAAe,SACf,QACA,MAAe,EAAE,cAAc,EAC/B,MAAe,EAAE,cAAc,EAC/B,YAAe,EACf,UAAe,IAAI,KAAK,EAAE,YAAY,CACxC,EAAG,mCAAmC,EAEtC,YAAc,CAAC,EAGf,aAAa,KAAK,CAAE,GAAI,MAAM,GAAI,YAAa,aAAc,SAAU,MAAO,aAAc,CAAC,EAEzF,YAEF,GAAG,EAAE,MAAM,GAAG,WAAW,+BAA2B,UAAW,GAAI,EACnE,aAAa,EAAI,GAGb,aAAa,OAAS,GACxB,GAAG,EAAE,WAAW,EAChB,uBAAuB,IAGvB,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,SAAS,WAAW,wBAAyB,SAAS,EACjE,OAAO,GAAG,MAAM,KAAK,MAAM,GAAI,WAAW,EAC1C,aAAe,CAAC,EAChB,SAAW,KACX,YAAc,KACd,iBAAmB,KACnB,KAAK,EAGX,CAEA,SAAS,aAAc,CACrB,aAAe,CAAC,EAChB,SAAW,KACX,YAAc,CAAC,EACf,YAAc,KACd,iBAAmB,KACnB,GAAG,EAAE,WAAW,CAClB,CAEA,eAAe,wBAAyB,CAEtC,KAAM,CAAE,KAAM,SAAU,EAAI,MAAM,GAAG,EAAE,OAAO,gBAAiB,CAC7D,OAAQ,eAAgB,MAAO,CAAE,IAAK,aAAc,IAAK,EAAM,EAAG,MAAO,CAC3E,CAAC,EACK,YAAc,KAAK,EAAE,YAAY,MAAO,YAAY,CAAC,GAAG,YAAY,EAGpE,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,gBAAiB,CACzD,aAAc,YACd,WAAc,OAAO,GAAG,KAAK,SAAS,GACtC,WAAc,OAAO,GAAG,KAAK,MAAM,GACnC,OAAc,MAChB,CAAC,EAGG,QACF,SAAW,MAAM,GACjB,MAAM,QAAQ,IAAI,aAAa,IAAI,GACjC,GAAG,EAAE,OAAO,SAAU,EAAE,GAAI,CAAE,SAAU,MAAM,EAAG,CAAC,CACpD,CAAC,GAGH,MAAM,KAAO,aAAa,IAAI,CAAC,EAAE,IAAM;AAAA;AAAA,sCAEL,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC;AAAA,cACtD,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC;AAAA,cAC/B,KAAK,EAAE,eAAe,EAAE,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA,8CAIE,CAAC,0DAA0D,EAAE,gBAAgB,OAAO,UAAU,EAAE;AAAA;AAAA;AAAA;AAAA,8CAIhG,CAAC,wDAAwD,EAAE,gBAAgB,MAAM,UAAU,EAAE;AAAA;AAAA;AAAA;AAAA,8CAI7F,CAAC,2DAA2D,EAAE,gBAAgB,SAAS,UAAU,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA,YAKrI,EAAE,KAAK,EAAE,EAEjB,GAAG,EAAE,UAAU,SAAS,WAAW,iCAA6B;AAAA;AAAA;AAAA,wBAG5C,aAAa,MAAM,2CAA2C,WAAW;AAAA;AAAA;AAAA;AAAA,iBAIhF,IAAI;AAAA;AAAA,MAEd;AAAA;AAAA;AAAA;AAAA;AAAA,MAKA,IAAI,CACT,CAEA,eAAe,qBAAsB,CACnC,MAAM,QAAU,aAAa,IAAI,CAAC,EAAG,IAAM,CACzC,MAAM,cAAgB,SAAS,cAAc,mBAAmB,CAAC,YAAY,GAAG,OAAS,EAAE,cACrF,gBAAkB,gBAAkB,SACtC,IAAI,KAAK,KAAK,IAAI,EAAI,MAAQ,GAAG,GAAI,EAAE,YAAY,EAAI,KAC3D,MAAO,CAAE,GAAI,EAAE,GAAI,cAAe,eAAgB,CACpD,CAAC,EAED,MAAM,QAAQ,IAAI,QAAQ,IAAI,GAC5B,GAAG,EAAE,OAAO,SAAU,EAAE,GAAI,CAC1B,eAAmB,EAAE,cACrB,kBAAmB,EAAE,eACvB,CAAC,CACH,CAAC,EAED,MAAM,KAAS,QAAQ,OAAO,GAAG,EAAE,gBAAgB,MAAM,EAAE,OACrD,IAAS,QAAQ,OAAO,GAAG,EAAE,gBAAgB,KAAK,EAAE,OACpD,OAAS,QAAQ,OAAO,GAAG,EAAE,gBAAgB,QAAQ,EAAE,OAGzD,UAAU,MAAM,GAAG,EAAE,OAAO,gBAAiB,SAAU,CAAE,OAAQ,WAAY,CAAC,EAElF,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MACH,0BAAqB,IAAI,UAAU,GAAG,SAAS,MAAM,uBACrD,UAAW,GACb,EAEA,aAAe,CAAC,EAChB,SAAW,KACX,KAAK,CACP,CAKA,eAAe,UAAU,GAAI,CAC3B,KAAM,CAAE,KAAM,MAAO,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CACzD,OAAQ,uQACR,GAAI,CAAE,EAAG,EAAG,YAAa,GAAM,gBAAiB,EAClD,CAAC,EACD,GAAI,OAAS,CAAC,MAAO,CAAE,GAAG,EAAE,MAAM,kBAAmB,OAAO,EAAG,MAAQ,CAGvE,MAAM,gBAAkB,MAAM,mBAAqB,YAAc,CAAC,EAAE,MAAM,iBACvE,qBAAqB,KAAK,MAAM,WAAW,MAAQ,EAAE,GAAK,SAAS,KAAK,OAAO,MAAM,cAAgB,EAAE,EAAE,KAAK,CAAC,GAClH,IAAI,UAAY,KAChB,GAAI,gBAAiB,CACnB,KAAM,CAAE,KAAM,GAAI,EAAI,MAAM,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3G,KAAK,kBAAkB,EAAE,OAAO,iDAAiD,EACjF,GAAG,WAAY,MAAM,EAAE,EAAE,MAAM,aAAc,CAAE,UAAW,EAAM,CAAC,EAAE,MAAM,CAAC,EAC7E,UAAY,MAAM,CAAC,GAAK,IAC1B,CAEA,IAAI,MAAQ,CAAE,cAAe,EAAM,EACnC,GAAI,OAAO,GAAG,KAAK,aAAa,GAAK,MAAM,YAAa,CACtD,MAAM,MAAQ,MAAM,KAAK,EAAE,mBAAmB,EAC9C,MAAQ,KAAK,EAAE,eAAe,MAAM,YAAa,MAAM,MAAM,WAAW,CAAC,CAC3E,CACA,MAAM,WAAa,MAAM,mBAAqB,WACxC,UAAa,CAAC,YAAc,KAAK,EAAE,UAAU,KAAK,EAClD,UAAc,MAAM,WAAW,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,oBAAoB,EAClE,SAAa,SAAW,KAAK,EAAE,iBAAiB,SAAS,SAAU,SAAS,gBAAiB,MAAM,QAAQ,EAAI,KAE/G,WADa,CAAC,YAAY,YAAY,UAAU,EAC1B,SAAS,MAAM,MAAM,EAC3C,aAAe,MAAM,SAAW,YAChC,mBAAqB,CAAC,mBAAmB,iBAAiB,EAAE,SAAS,MAAM,MAAM,EACjF,gBAAkB,CAAC,YAAa,UAAW,QAAQ,EACnD,cAAmB,CAAE,QAAS,UAAW,OAAQ,QAAS,EAC1D,cAAmB,CAAC,YAAa,UAAW,QAAQ,EAAE,SAAS,MAAM,MAAM,EAC3E,OAAmB,gBAAgB,QAAQ,MAAM,MAAM,EACvD,UAAmB,QAAU,EAAI,gBAAgB,MAAM,OAAS,CAAC,EAAI,CAAC,EAKtE,KAAO,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EACzF,QAAU,GAAM,EAAE,WAAkB,iFAAiF,EAAE,iBAAmB,OAAS,iFAAiF,EAAE,cAAgB,KAAO,0EAA0E,KAAK,EAAE,eAAe,EAAE,YAAY,CAAC,oBAAoB,KAAK,EAAE,gBAAgB,OAAO,EAAE,UAAU,GAAK,IAAM,OAAO,EAAE,QAAQ,GAAK,GAAK,OAAO,EAAE,YAAY,CAAC,CAAC,UAAY,EAAE,GAAK,EAAE,iBAAmB,WAAa,oGAAsG,EAAE,GAArmB,GAC/B,CAAE,KAAM,UAAW,EAAI,MAAM,KAAK,KAAK,oBAAoB,EAAE,OAAO,sBAAsB,EAC7F,GAAG,WAAY,MAAM,EAAE,EAAE,GAAG,SAAU,eAAe,EAAE,MAAM,aAAc,CAAE,UAAW,EAAK,CAAC,EAAE,MAAM,CAAC,EAC1G,IAAI,WAAa,KACjB,GAAI,MAAM,WAAY,CACpB,KAAM,CAAE,KAAM,EAAG,EAAI,MAAM,KAAK,KAAK,OAAO,EAAE,OAAO,MAAM,EAAE,GAAG,KAAM,MAAM,UAAU,EAAE,YAAY,EACpG,WAAa,IAAI,MAAQ,IAC3B,CACA,MAAM,YAAc,aAAa,CAAC,GAAG,WAAa,WAC5C,YAAc,YAChB,GAAG,KAAK,EAAE,SAAS,WAAW,CAAC,GAAG,YAAc,aAAe,YAAc,4DAA4D,KAAK,EAAE,SAAS,UAAU,CAAC,WAAa,EAAE,2DAA2D,KAAK,EAAE,eAAe,aAAa,CAAC,GAAG,YAAc,MAAM,UAAU,CAAC,SACpT,IAEE,KAAO;AAAA;AAAA,uGAEsF,KAAK,EAAE,SAAS,MAAM,YAAY,CAAC;AAAA;AAAA,YAE9H,KAAK,EAAE,KAAK,UAAU,UAAU,MAAM,MAAM,CAAC;AAAA,YAC7C,MAAM,gBAAgB,MAAM,aAAa,YAAY,KAAK,EAAE,KAAK,MAAM,cAAc,EAAE,EAAE;AAAA;AAAA,4DAEzC,KAAK,EAAE,SAAS,MAAM,eAAe,QAAG,CAAC;AAAA,4DACzC,KAAK,EAAE,SAAS,MAAM,WAAW,MAAM,GAAG,CAAC;AAAA,8DACzC,WAAW;AAAA,8DAE/D,WAAa,4DACX,MAAM,aAAa,YAAc,2DACjC,0DACJ;AAAA,4DACoD,KAAK,EAAE,SAAS,MAAM,UAAU,MAAM,cAAc,QAAG,CAAC;AAAA,6FACvB,KAAK,EAAE,SAAS,MAAM,SAAS,MAAM,aAAa,QAAG,CAAC;AAAA,8DACrF,KAAK,EAAE,WAAW,MAAM,UAAU,CAAC;AAAA,yDACxC,KAAK,EAAE,SAAS,MAAM,OAAO,MAAM,oBAAoB,QAAG,CAAC;AAAA,UAC1G,MAAM,aAAa,SAAS;AAAA;AAAA,cAExB,KAAK,EAAE,KAAK,MAAM,gBAAgB,QAAQ,CAAC;AAAA,cAC3C,MAAM,oBAAoB,4DAA4D,KAAK,EAAE,WAAW,MAAM,mBAAmB,CAAC,UAAU,EAAE;AAAA,cAC9I,MAAM,eAAe,4DAA4D,KAAK,EAAE,SAAS,MAAM,cAAc,CAAC,UAAU,EAAE;AAAA;AAAA,kEAE9E,KAAK,EAAE,SAAS,MAAM,cAAc,QAAG,CAAC,eAAe,EAAE;AAAA,UACjH,YAAc,MAAM,mBAAqB;AAAA,+FAC4C,KAAK,EAAE,SAAS,MAAM,mBAAmB,aAAa,CAAC;AAAA,kEACpF,KAAK,EAAE,SAAS,MAAM,mBAAmB,QAAG,CAAC,eAAiB,EAAE;AAAA,UACxH,SAAW;AAAA,6DACwC,KAAK,EAAE,SAAS,SAAS,UAAU,MAAM,QAAG,CAAC;AAAA,gEAC1C,SAAS,YAAY,QAAQ,uCAAuC,KAAK,EAAE,SAAS,SAAS,iBAAiB,QAAG,CAAC,OAAO,KAAK,EAAE,SAAS,SAAS,iBAAiB,QAAG,CAAC;AAAA,YAC3N,SAAS,kBAAoB,8DAA8D,KAAK,EAAE,SAAS,SAAS,iBAAiB,CAAC,eAAiB,EAAE,GAAK,EAAE;AAAA,UAClK,gBAAkB;AAAA,qJACyH,aAAa,SAAS,CAAC,GAAG,WAAW,SAAW,SAAW,uGAAuG,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,MAAM,KAAK,EAAE,MAAM,UAAU,MAAM,CAAC,mEAAqE,EAAE,eAAiB,EAAE;AAAA,UACjc,MAAM,aAAe;AAAA,kEACmC,KAAK,EAAE,SAAS,MAAM,YAAY,CAAC;AAAA,iEACpC,KAAK,EAAE,SAAS,MAAM,oBAAoB,QAAG,CAAC;AAAA,kEAC7C,KAAK,EAAE,WAAW,MAAM,YAAY,CAAC,eAAiB,EAAE;AAAA,UAChH,MAAM,cAAgB;AAAA,mEACmC,KAAK,EAAE,SAAS,MAAM,aAAa,CAAC;AAAA,sEACjC,KAAK,EAAE,WAAW,MAAM,mBAAmB,CAAC,eAAiB,EAAE;AAAA,UAC3H,MAAM,cAAgB;AAAA,wHACqF,MAAM,eAAe,GAAG,QAAQ,CAAC,CAAC;AAAA,iEACtF,KAAK,EAAE,WAAW,MAAM,WAAW,CAAC,eAAiB,EAAE;AAAA,UAC9G,MAAM,MAAQ,2EAA2E,KAAK,EAAE,SAAS,MAAM,KAAK,CAAC,eAAiB,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAQnI,MAAM,aAAa,CAAC,GAAG,IAAI,GAAK;AAAA,wBACvB,KAAK,EAAE,SAAS,EAAE,cAAc,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,YAAY,KAAK,EAAE,SAAS,EAAE,KAAK,GAAG,CAAC;AAAA,oBAC5F,EAAE,QAAQ,YAAY,KAAK,EAAE,eAAe,EAAE,UAAU,CAAC,YAAY,KAAK,EAAE,eAAe,EAAE,WAAW,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC;AAAA,2EACxE,MAAM,cAAgB,QAAU,OAAO,oCAAoC,KAAK,EAAE,eAAe,MAAM,WAAW,CAAC;AAAA,cAChL,MAAM,cAAgB;AAAA,wJAC+G,KAAK,EAAE,eAAe,MAAM,UAAU,CAAC;AAAA,yJACjC,KAAK,EAAE,eAAe,MAAM,GAAG,CAAC,aAAe,EAAE;AAAA;AAAA;AAAA;AAAA,6BAI7K,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;AAAA,6BACzB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;AAAA,QAC9C,UAAY,2IAAsI,KAAK,EAAE,UAAU,MAAM,aAAa,CAAC,wDAA0D,EAAE;AAAA,QACnP,WAAa,qHAAqH,MAAM,MAAM,2CAA6C,EAAE;AAAA,QAC7L,MAAM,WAAa,iHAAiH,KAAK,EAAE,eAAiB,KAAK,EAAE,eAAe,MAAM,UAAU,EAAI,KAAK,EAAE,WAAW,MAAM,UAAU,CAAC,wDAA0D,EAAE,GAInS,QAAU,MAAM,YAAY,KAAK,EACjC,OAAS;AAAA;AAAA,0FAEuE,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC;AAAA,+FACjB,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,MAAM,KAAK,EAAE,MAAM,MAAM,YAAY,CAAC;AAAA,UACjJ,QAAQ,GAAK,qFAAqF,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,wDAA0D,EAAE;AAAA,UACpL,OAAO,GAAG,KAAK,aAAa,EAAI,8FAA8F,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,mEAAqE,EAAE;AAAA,UAC3N,UAAY,qLAAuL,EAAE;AAAA,UACrM,MAAM,SAAS,OAAS,mPAA2O,EAAE;AAAA,UACrQ,CAAC,YAAc,CAAC,YAAc,CAAC,mBAAqB,cAAgB;AAAA,YAClE,UAAU,OAAS;AAAA;AAAA;AAAA,cAGjB,UAAU,IAAI,GAAK,kBAAkB,CAAC,KAAK,cAAc,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC;AAAA;AAAA,gGAEE,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,sBAAwB;AAAA,qSACuJ;AAAA,8FACvM,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,MAAM,KAAK,EAAE,MAAM,MAAM,YAAY,CAAC,oDAAsD;AAAA,+RAC4E,EAAE;AAAA,UACpR,MAAM,SAAW,mBAAqB,gIAAgI,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,MAAM,KAAK,EAAE,MAAM,MAAM,YAAY,CAAC,0HAA4H,EAAE;AAAA,UAChW,MAAM,SAAW,mBAAqB,6FAA6F,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,MAAM,KAAK,EAAE,MAAM,MAAM,YAAY,CAAC,mHAAqH,EAAE;AAAA,UACtT,aAAe,0FAA0F,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,MAAM,KAAK,EAAE,MAAM,MAAM,YAAY,CAAC,KAAK,MAAM,aAAa,CAAC,iEAAmE,EAAE;AAAA,UACnQ,aAAe,+FAA+F,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,MAAM,KAAK,EAAE,MAAM,MAAM,YAAY,CAAC,KAAK,MAAM,aAAa,CAAC,sEAAwE,EAAE;AAAA,UAC7Q,MAAM,SAAS,mBAAqB,0FAA0F,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,yEAA2E,EAAE;AAAA,UACjO,MAAM,SAAS,kBAAoB,wFAAwF,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,KAAK,MAAM,aAAa,CAAC,kEAAoE,EAAE;AAAA,UAChP,MAAM,aAAa,WAAW,MAAM,iBAAiB,UAAU,CAAC,MAAM,iBAAiB,MAAM,SAAS,YAAc,mFAAmF,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,KAAK,MAAM,aAAa,CAAC,oDAAsD,EAAE;AAAA,UAC9S,MAAM,aAAa,cAAc,MAAM,iBAAiB,UAAU,MAAM,iBAAiB,YAAY,MAAM,SAAS,YAAc;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKxH,EAAE;AAAA,UACZ,YAAc,CAAC,CAAC,YAAY,WAAW,EAAE,SAAS,MAAM,MAAM,EAAI;AAAA,oIACwD,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,MAAM,KAAK,EAAE,MAAM,MAAM,YAAY,CAAC,MAAM,KAAK,EAAE,MAAM,MAAM,oBAAoB,eAAe,EAAE,CAAC;AAAA,6EAChL,EAAE;AAAA;AAAA,cAG7E,GAAG,EAAE,UAAU,SAAS,MAAM,YAAY,GAAI,KAAM,OAAQ,IAAI,EAEhE,OAAO,eAAe,iBAAiB,MAAM,GAAI,eAAe,MAAM,EAAE,EAAE,EAE1E,OAAO,eAAe,yBAAyB,MAAM,GAAI,eAAe,MAAM,EAAE,GAAI,MAAM,MAAM,CAClG,CAEA,eAAe,aAAa,QAAS,QAAQ,KAAM,CACjD,MAAM,IAAM,SAAS,eAAe,sBAAsB,EAC1D,GAAI,CAAC,KAAK,MAAO,OACjB,MAAM,UAAY,IAAI,MAGhB,CAAE,KAAM,OAAQ,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAAE,OAAQ,SAAU,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EACzI,GAAI,CAAC,CAAC,YAAY,SAAS,EAAE,SAAS,SAAS,MAAM,EAAG,CACtD,GAAG,EAAE,MAAM,gDAAiD,OAAO,EACnE,MACF,CACA,KAAM,CAAE,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,QAAS,CAAE,OAAQ,SAAU,CAAC,EAC5E,GAAI,MAAO,CAAE,GAAG,EAAE,MAAM,gBAAiB,OAAO,EAAG,MAAQ,CAC3D,MAAM,YAAY,QAAS,iBAAkB,SAAS,QAAQ,GAAI,SAAS,EAEvE,YAAc,UAChB,MAAM,GAAG,EAAE,OAAO,iBAAkB,CAClC,SAAU,QACV,SAAU,WACV,OAAU,YACZ,CAAC,EAGH,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,uBAAwB,SAAS,EAC5C,KAAK,CACP,CAGA,SAAS,aAAa,KAAM,CAC1B,GAAI,CAAC,KAAM,MAAO,uGAClB,MAAM,KAAO,CAAE,OAAQ,SAAU,SAAU,kBAAmB,SAAU,WAAY,OAAQ,QAAS,EAAE,KAAK,MAAM,GAAK,KAAK,OAI5H,MAAO,GAHM,KAAK,SAAW,OAAS,4DAClC,KAAK,SAAW,SAAW,+DAC3B,oEACU,gCAAgC,KAAK,EAAE,SAAS,IAAI,CAAC,KAAK,KAAK,EAAE,SAAS,KAAK,QAAU,EAAE,CAAC,mEAC1C,KAAK,EAAE,WAAW,KAAK,UAAU,CAAC,GAAG,KAAK,gBAAkB,aAAe,KAAK,EAAE,SAAS,KAAK,eAAe,EAAI,EAAE,SACvL,CAIA,eAAe,cAAc,QAAS,OAAQ,CAC5C,GAAI,CAAC,OAAO,GAAG,QAAS,OACxB,GAAG,EAAE,MAAM,wBAAyB,OAAQ,GAAI,EAChD,MAAM,IAAM,MAAM,OAAO,GAAG,QAAQ,KAAK,OAAQ,CAAC,OAAO,CAAC,EACpD,EAAI,KAAK,UAAU,CAAC,EACtB,GAAG,SAAW,OAAQ,GAAG,EAAE,MAAM,kBAAmB,SAAS,EACxD,GAAG,SAAW,UAAW,GAAG,EAAE,MAAM,EAAE,QAAU,+BAAgC,OAAQ,GAAI,EAC3F,KAAK,GAAG,EAAE,MAAM,iDAAkD,UAAW,GAAI,EAC3F,UAAU,OAAO,CACnB,CAEA,eAAe,YAAY,QAAS,YAAa,CAC/C,GAAG,EAAE,QAAQ,wBAAwB,WAAW,uGAAwG,SAAY,CAClK,KAAM,CAAE,KAAM,SAAU,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CACtD,OAAQ,uDAAwD,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAC3H,CAAC,EACD,GAAI,CAAC,CAAC,YAAY,UAAU,QAAQ,EAAE,SAAS,WAAW,MAAM,EAAG,CACjE,GAAG,EAAE,MAAM,kDAAmD,OAAO,EACrE,MACF,CACA,MAAM,MAAQ,WAAW,aAAe,CAAC,EACnC,KAAO,WAAW,aAIxB,UAAW,QAAS,OAAO,CAAC,EAAI,CAC9B,GAAI,CAAC,KAAK,WAAY,SACtB,KAAM,CAAE,KAAM,EAAG,EAAI,KACjB,MAAM,GAAG,EAAE,OAAO,eAAgB,CAAE,GAAI,CAAE,WAAY,KAAK,WAAY,aAAc,IAAK,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EACvI,MAAM,GAAG,EAAE,OAAO,eAAgB,CAAE,GAAI,CAAE,WAAY,KAAK,UAAW,EAAG,MAAO,EAAG,gBAAiB,EAAK,CAAC,EAAE,KAAK,IAAM,CAAE,KAAM,EAAE,OAAO,CAAC,CAAE,EAAE,EAC7I,IAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,GAAG,GAAI,CAAE,aAAc,KAAK,IAAI,GAAG,GAAG,cAAc,IAAI,KAAK,UAAU,EAAE,CAAE,CAAC,CACxH,CAMA,MADsB,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EACpF,KAAK,gBAAgB,EAAE,OAAO,EAAE,GAAG,WAAY,OAAO,EAE1E,MAAM,GAAG,EAAE,OAAO,SAAU,QAAS,CAAE,OAAQ,WAAY,CAAC,EAC5D,MAAM,YAAY,QAAS,kBAAmB,WAAW,QAAQ,GAAI,YAAa,iCAAiC,EACnH,OAAO,GAAG,SAAS,KAAK,SAAU,CAAC,OAAO,CAAC,EAC3C,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,wCAAoC,SAAS,EACxD,KAAK,CACP,EAAG,eAAgB,EAAI,CACzB,CAEA,eAAe,SAAS,QAAS,WAAY,CAC3C,GAAG,EAAE,UAAU,qBAAsB;AAAA;AAAA,0CAEC,KAAK,EAAE,eAAe,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2EASA,IAAI,KAAK,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA;AAAA,2FAEtB,WAAW,QAAQ,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA,cAIlG;AAAA;AAAA,8FAEgF,KAAK,EAAE,MAAM,OAAO,CAAC,KAAK,UAAU;AAAA,8DACpE,IAAI,CAChE,CAEA,eAAe,eAAe,QAAS,WAAY,CACjD,MAAM,OAAU,SAAS,eAAe,gBAAgB,GAAG,MACrD,QAAU,SAAS,eAAe,cAAc,GAAG,MACnD,OAAU,WAAW,SAAS,eAAe,gBAAgB,GAAG,KAAK,GAAG,EACxE,IAAU,SAAS,eAAe,aAAa,GAAG,OAAO,KAAK,EACpE,GAAI,CAAC,OAAQ,CAAE,GAAG,EAAE,MAAM,mCAAoC,OAAO,EAAG,MAAQ,CAChF,MAAM,UAAY,OAAS,WAC3B,MAAM,GAAG,EAAE,OAAO,SAAU,QAAS,CAAE,eAAgB,UAAU,UAAU,OAAQ,oBAAqB,IAAI,KAAK,GAAG,OAAO,WAAW,EAAE,YAAY,EAAG,eAAgB,MAAO,CAAC,EAC/K,KAAM,CAAE,KAAM,GAAI,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAAE,OAAQ,8BAA+B,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EAC1J,MAAM,GAAG,EAAE,OAAO,eAAgB,CAAE,KAAM,QAAS,KAAM,SAAU,SAAU,gBAAiB,YAAa,2BAAsB,KAAK,cAAc,OAAO,KAAK,MAAM,IAAK,OAAQ,UAAW,KAAK,KAAK,YAAa,CAAC,EACtN,MAAM,YAAY,QAAS,mBAAoB,KAAK,gBAAgB,SAAU,UAAU,UAAU,OAAQ,OAAI,OAAO,QAAQ,CAAC,CAAC,QAAQ,MAAM,EAAE,EAC/I,GAAG,EAAE,WAAW,EAAG,GAAG,EAAE,MAAM,cAAc,KAAK,EAAE,eAAe,MAAM,CAAC,YAAY,UAAU,0BAAqB,EAAE,GAAG,UAAU,GAAI,EAAG,KAAK,CACjJ,CAEA,eAAe,gBAAgB,QAAS,YAAa,WAAY,CAC/D,GAAG,EAAE,UAAU,mBAAmB,WAAW,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2FAkBuC,WAAW,QAAQ,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA,cAIlG;AAAA;AAAA,4FAE8E,KAAK,EAAE,MAAM,OAAO,CAAC,KAAK,UAAU;AAAA,sEAC1D,IAAI,CACxE,CAGA,eAAe,iBAAiB,QAAS,YAAa,CACpD,GAAI,CAAC,OAAO,eAAe,iBAAkB,CAAE,GAAG,EAAE,MAAM,6BAA8B,OAAO,EAAG,MAAQ,CAC7F,MAAM,OAAO,cAAc,iBAAiB,QAAS,WAAW,GACnE,UAAU,OAAO,CAC7B,CAEA,eAAe,aAAa,QAAS,WAAY,CAC/C,MAAM,OAAS,SAAS,eAAe,gBAAgB,GAAG,MACpD,OAAS,WAAW,SAAS,eAAe,gBAAgB,GAAG,KAAK,GAAG,WACvE,MAAS,SAAS,eAAe,eAAe,GAAG,OAAO,KAAK,EACrE,GAAI,CAAC,OAAQ,CAAE,GAAG,EAAE,MAAM,gCAAiC,OAAO,EAAG,MAAQ,CAE7E,MAAM,OAAS,SAAS,eAAe,gBAAgB,GAAG,OAAS,KAC7D,CAAE,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,QAAS,CAAE,OAAQ,mBAAoB,cAAe,OAAQ,oBAAqB,IAAI,KAAK,EAAE,YAAY,EAAG,cAAe,OAAQ,MAAO,OAAO,KAAM,cAAe,MAAO,CAAC,EAC7N,GAAI,MAAO,CAAE,GAAG,EAAE,MAAM,WAAa,MAAM,QAAS,OAAO,EAAG,MAAQ,CAGtE,GAFA,MAAM,YAAY,QAAS,mBAAoB,YAAa,mBAAoB,MAAM,EACtF,GAAG,EAAE,WAAW,EACZ,SAAW,kBAAoB,OAAO,eAAe,iBAEvD,MAAM,OAAO,cAAc,iBAAiB,QAAS,IAAI,MACpD,IAAI,SAAW,sBAAwB,OAAO,eAAe,sBAElE,YAAK,EACE,OAAO,cAAc,sBAAsB,QAAS,IAAI,EAE/D,GAAG,EAAE,MAAM,4DAA6D,OAAQ,GAAI,EAEtF,KAAK,CACP,CAEA,eAAe,mBAAmB,QAAS,CACzC,GAAG,EAAE,QAAQ,mFAAoF,SAAY,CAC3G,MAAM,GAAG,EAAE,OAAO,SAAU,QAAS,CAAE,OAAQ,kBAAmB,mBAAoB,IAAI,KAAK,EAAE,YAAY,CAAE,CAAC,EAChH,MAAM,YAAY,QAAS,kBAAmB,mBAAoB,iBAAiB,EACnF,GAAG,EAAE,MAAM,iDAA6C,SAAS,EAAG,KAAK,CAC3E,EAAG,mBAAoB,EAAK,CAC9B,CAcA,SAAS,aAAc,CACrB,OAAO,OAAO,SAAS,aACrB,OAAO,iBAAkB,OAAO,sBAChC,CAAE,OAAQ,CAAE,QAAS,CAAE,cAAe,UAAU,OAAO,GAAG,KAAK,SAAS,YAAY,EAAG,CAAE,CAAE,CAC7F,CACF,CAKA,eAAe,cAAc,QAAS,YAAa,CACjD,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,YAAY,EAAE,KAAK,QAAQ,EACtD,OAAO,CAAE,OAAQ,WAAY,eAAgB,WAAY,GAAG,WAAY,CAAC,EACzE,GAAG,KAAM,OAAO,EAChB,GAAG,oDAAoD,EACvD,OAAO,IAAI,EACd,OAAI,MAAc,CAAE,KAAM,EACrB,MAAM,OACJ,CAAE,GAAI,EAAK,EADQ,CAAE,QAAS,EAAK,CAE5C,CAEA,SAAS,qBAAsB,CAC7B,KAAK,EACD,OAAO,GAAG,GAAG,cAAgB,aAAa,OAAO,eAAe,eAAe,CACrF,CAIA,eAAe,kBAAkB,QAAS,YAAa,OAAQ,QAAS,iBAAkB,kBAAmB,CAC3G,MAAM,SAAW,CAAC,EAIlB,IAAI,QAAU,KACd,GAAI,CACF,QAAU,MAAM,OAAO,aAAa,oBAAoB,QAAS,OAAQ,QAAS,gBAAgB,CACpG,OAAS,EAAG,CACV,SAAS,KAAK,wCAAwC,EAAE,OAAO,GAAG,CACpE,CAGA,KAAM,CAAE,MAAO,KAAM,EAAI,MAAM,YAAY,EAAE,KAAK,qBAAqB,EAAE,OAAO,EAAE,GAAG,WAAY,OAAO,EAMxG,GALI,OAAO,SAAS,KAAK,qDAAqD,MAAM,OAAO,GAAG,EAK1F,CAAC,QAAS,CACZ,KAAM,CAAE,MAAO,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,CACzD,KAAM,QAAS,KAAM,SAAU,SAAU,4BACzC,YAAa,kBAAmB,OAAQ,CAAC,OAAQ,WAAY,EAAG,UAAW,WAC7E,CAAC,EACG,OAAO,SAAS,KAAK,iDAAiD,MAAM,OAAO,GAAG,CAC5F,CACA,OAAO,QACT,CAEA,eAAe,cAAc,QAAS,WAAY,CAChD,KAAM,CAAE,KAAM,GAAI,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAChD,OAAQ,iEACR,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAC3D,CAAC,EACD,GAAI,CAAC,IAAK,CAAE,GAAG,EAAE,MAAM,kBAAmB,OAAO,EAAG,MAAQ,CAC5D,MAAM,YAAc,IAAI,cAAgB,GACxC,GAAI,IAAI,iBAAmB,YAAc,IAAI,SAAW,WAAY,CAClE,GAAG,EAAE,MAAM,GAAG,WAAW,mDAAoD,UAAW,GAAI,EAC5F,oBAAoB,EACpB,MACF,CACA,MAAM,UAAY,IAAI,eAAiB,YAAc,EAC/C,OAAS,IAAI,eAAiB,SACpC,GAAG,EAAE,QAAQ,6BAA6B,KAAK,EAAE,eAAe,SAAS,CAAC,0GAA2G,SAAY,CAC/L,MAAM,QAAU,IAAI,KAAK,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,EAC/C,KAAO,MAAM,cAAc,QAAS,CAAE,YAAa,IAAI,KAAK,EAAE,YAAY,CAAE,CAAC,EACnF,GAAI,KAAK,MAAO,CACd,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,yBAAyB,WAAW,qCAAqC,KAAK,MAAM,OAAO,0BAA2B,QAAS,GAAK,EAC/I,MACF,CACA,GAAI,KAAK,QAAS,CAChB,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,GAAG,WAAW,mDAAoD,UAAW,GAAI,EAC5F,oBAAoB,EACpB,MACF,CACA,MAAM,YAAY,QAAS,mBAAoB,IAAI,QAAU,GAAI,WAAY,OAAI,UAAU,QAAQ,CAAC,CAAC,EAAE,EAEvG,MAAM,SAAW,CAAC,EAIlB,GAAI,CACF,MAAM,OAAO,cAAc,aAAa,QAAS,YAAa,qBAAqB,MAAM,GAAG,CAC9F,OAAS,EAAG,CACV,SAAS,KAAK,+BAA+B,EAAE,OAAO,GAAG,CAC3D,CACA,SAAS,KAAK,GAAG,MAAM,kBAAkB,QAAS,YAAa,UAAW,QACxE,2BAA2B,MAAM,IAAK,WAAW,WAAW,KAAK,MAAM,GAAG,CAAC,EAE7E,GAAG,EAAE,WAAW,EACZ,SAAS,OACX,GAAG,EAAE,MAAM,aAAa,KAAK,EAAE,eAAe,SAAS,CAAC,gBAAgB,WAAW,SAAS,SAAS,KAAK,IAAI,CAAC,mCAAoC,UAAW,IAAK,EAEnK,GAAG,EAAE,MAAM,aAAa,KAAK,EAAE,eAAe,SAAS,CAAC,aAAc,UAAW,GAAI,EAEvF,oBAAoB,CACtB,EAAG,iBAAkB,EAAK,CAC5B,CAKA,SAAS,mBAAmB,QAAS,YAAa,WAAY,CAC5D,MAAM,SAAW,IAAI,KAAK,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,EACtD,GAAG,EAAE,UAAU,0BAA0B,WAAW,GAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qMAMsI,YAAY,GAAG,QAAQ,CAAC,CAAC;AAAA,4JAC/D,QAAQ,UAAU,QAAQ;AAAA;AAAA;AAAA,MAGhL;AAAA;AAAA,qGAE+F,KAAK,EAAE,MAAM,OAAO,CAAC,MAAM,KAAK,EAAE,MAAM,WAAW,CAAC;AAAA,MACnJ,IAAI,CACR,CAEA,eAAe,sBAAsB,QAAS,YAAa,CACzD,MAAM,OAAS,WAAW,SAAS,eAAe,gBAAgB,GAAG,KAAK,GAAG,EACvE,QAAU,SAAS,eAAe,cAAc,GAAG,MACnD,OAAS,SAAS,eAAe,gBAAgB,GAAG,OAAO,KAAK,EACtE,GAAG,CAAC,QAAQ,QAAQ,EAAE,CAAE,GAAG,EAAE,MAAM,8BAA8B,OAAO,EAAG,MAAQ,CACnF,GAAG,CAAC,QAAQ,CAAE,GAAG,EAAE,MAAM,uBAAuB,OAAO,EAAG,MAAQ,CAClE,GAAG,CAAC,OAAO,CAAE,GAAG,EAAE,MAAM,wBAAwB,OAAO,EAAG,MAAQ,CAElE,KAAM,CAAE,KAAM,GAAI,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAChD,OAAQ,wBAAyB,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAC5F,CAAC,EACD,GAAI,KAAK,iBAAmB,YAAc,KAAK,SAAW,WAAY,CACpE,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,GAAG,WAAW,mDAAoD,UAAW,GAAI,EAC5F,oBAAoB,EACpB,MACF,CAGA,MAAM,KAAO,MAAM,cAAc,QAAS,CACxC,YAAa,IAAI,KAAK,OAAO,EAAE,YAAY,EAC3C,cAAe,0BAA0B,MAAM,EACjD,CAAC,EACD,GAAI,KAAK,MAAO,CACd,GAAG,EAAE,MAAM,yBAAyB,WAAW,qCAAqC,KAAK,MAAM,OAAO,0BAA2B,QAAS,GAAK,EAC/I,MACF,CACA,GAAI,KAAK,QAAS,CAChB,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,GAAG,WAAW,mDAAoD,UAAW,GAAI,EAC5F,oBAAoB,EACpB,MACF,CACA,MAAM,YAAY,QAAS,wBAAyB,KAAK,QAAU,YAAa,WAAY,OAAI,OAAO,QAAQ,CAAC,CAAC,KAAK,MAAM,EAAE,EAE9H,MAAM,SAAW,MAAM,kBAAkB,QAAS,YAAa,OAAQ,QACrE,0BAA0B,MAAM,GAAI,0BAA0B,WAAW,KAAK,MAAM,GAAG,EAEzF,GAAG,EAAE,WAAW,EACZ,SAAS,OACX,GAAG,EAAE,MAAM,aAAa,KAAK,EAAE,eAAe,MAAM,CAAC,gBAAgB,WAAW,SAAS,SAAS,KAAK,IAAI,CAAC,mCAAoC,UAAW,IAAK,EAEhK,GAAG,EAAE,MAAM,aAAa,KAAK,EAAE,eAAe,MAAM,CAAC,sCAAuC,UAAW,GAAI,EAE7G,oBAAoB,CACtB,CAmBA,IAAI,gBAAkB,KAEtB,eAAe,kBAAkB,QAAS,CACxC,GAAI,CAAC,OAAO,GAAG,KAAK,aAAa,EAAG,CAAE,GAAG,EAAE,MAAM,mCAAoC,OAAO,EAAG,MAAQ,CACvG,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAClD,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAC3D,CAAC,EACD,GAAI,CAAC,MAAO,CAAE,GAAG,EAAE,MAAM,kBAAmB,OAAO,EAAG,MAAQ,CAC9D,gBAAkB,MAAM,aAAe,KAEvC,MAAM,YAAc,MAAM,aAAe,YAEzC,GAAG,EAAE,UAAU,qCAAgC,KAAK,EAAE,SAAS,MAAM,YAAY,CAAC,GAAI;AAAA;AAAA;AAAA;AAAA;AAAA,QAKlF,YAAc;AAAA;AAAA;AAAA;AAAA;AAAA,qBAKD,KAAK,EAAE,SAAS,MAAM,eAAiB,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA,4DAIH,MAAM,YACtD,iHACA,6LAAwL;AAAA,cACpL,EAAE;AAAA;AAAA;AAAA;AAAA,2EAIyD,KAAK,EAAE,SAAS,MAAM,eAAiB,EAAE,CAAC;AAAA,cACvG,YAAc,kDAAoD,EAAE;AAAA,YACtE,YAAc,sGAAwG,EAAE;AAAA;AAAA;AAAA;AAAA,0EAI1D,KAAK,EAAE,SAAS,MAAM,SAAW,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA,+EAI/B,KAAK,EAAE,SAAS,MAAM,UAAY,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA,4EAIxC,KAAK,EAAE,SAAS,MAAM,OAAS,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA,6EAIjC,KAAK,EAAE,SAAS,MAAM,OAAS,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA,6EAIlC,KAAK,EAAE,SAAS,MAAM,cAAgB,EAAE,CAAC;AAAA;AAAA;AAAA,MAG/G;AAAA;AAAA,iGAE0F,KAAK,EAAE,MAAM,OAAO,CAAC;AAAA,MAC/G,IAAI,EAMH,aAAe,MAAM,eACvB,WAAW,IAAM,mBAAmB,MAAM,aAAa,EAAG,GAAG,CAEjE,CAEA,eAAe,mBAAmB,MAAO,CACvC,MAAM,KAAO,SAAS,eAAe,cAAc,EACnD,GAAI,CAAC,KAAM,OACX,GAAI,CAAC,OAAS,MAAM,KAAK,EAAE,OAAS,EAAG,CAAE,KAAK,MAAM,QAAU,OAAQ,MAAQ,CAC9E,MAAM,EAAI,MAAM,KAAK,EACf,CAAC,OAAQ,UAAU,EAAI,MAAM,QAAQ,IAAI,CAE7C,GAAG,EAAE,OAAO,YAAa,CAAE,MAAO,CAAE,cAAe,CAAE,EAAG,GAAI,CAAE,UAAW,EAAK,EAAG,OAAQ,gDAAiD,MAAO,CAAE,CAAC,EACpJ,GAAG,EAAE,OAAO,YAAa,CAAE,MAAO,CAAE,SAAU,CAAE,EAAG,GAAI,CAAE,UAAW,EAAK,EAAG,OAAQ,gDAAiD,MAAO,CAAE,CAAC,CACjJ,CAAC,EACK,SAAW,CAAC,GAAI,OAAO,MAAQ,CAAC,EAAI,GAAI,WAAW,MAAQ,CAAC,CAAE,EACjE,OAAO,CAAC,EAAG,EAAG,MAAQ,IAAI,UAAU,GAAK,EAAE,KAAO,EAAE,EAAE,IAAM,CAAC,EAAE,MAAM,EAAG,CAAC,EAC5E,GAAI,CAAC,SAAS,OAAQ,CAAE,KAAK,MAAM,QAAU,OAAQ,MAAQ,CAC7D,KAAK,UAAY,SAAS,IAAI,GAAK;AAAA,oFAC6C,KAAK,UAAU,CAAC,EAAE,QAAQ,KAAM,OAAO,CAAC;AAAA,kBAC1G,KAAK,EAAE,SAAS,EAAE,aAAa,CAAC;AAAA,kEACgB,KAAK,EAAE,SAAS,EAAE,UAAY,EAAE,CAAC;AAAA,aACtF,EAAE,KAAK,EAAE,EAClB,KAAK,MAAM,QAAU,OACvB,CAEA,SAAS,mBAAmB,EAAG,CAC7B,gBAAkB,EAAE,GACpB,MAAM,EAAI,CAAC,GAAI,IAAM,CAAE,MAAM,GAAK,SAAS,eAAe,EAAE,EAAO,KAAI,GAAG,MAAQ,GAAK,GAAI,EAC3F,EAAE,eAAgB,EAAE,aAAa,EACjC,EAAE,kBAAmB,EAAE,OAAO,EAC9B,EAAE,mBAAoB,EAAE,QAAQ,EAChC,EAAE,gBAAiB,EAAE,KAAK,EAC1B,EAAE,gBAAiB,EAAE,KAAK,EAC1B,MAAM,KAAO,SAAS,eAAe,cAAc,EAC/C,OAAM,KAAK,MAAM,QAAU,QAC/B,MAAM,OAAS,SAAS,eAAe,gBAAgB,EACnD,SAAQ,OAAO,MAAQ,EAAE,eAC7B,MAAM,OAAS,SAAS,eAAe,gBAAgB,EACnD,SAAQ,OAAO,UAAY,+FAA+F,KAAK,EAAE,SAAS,EAAE,aAAa,CAAC,mBAChK,CAEA,eAAe,kBAAkB,QAAS,CACxC,GAAI,CAAC,OAAO,GAAG,KAAK,aAAa,EAAG,CAAE,GAAG,EAAE,MAAM,mCAAoC,OAAO,EAAG,MAAQ,CACvG,MAAM,EAAI,IAAM,SAAS,eAAe,EAAE,GAAG,OAAO,KAAK,GAAK,GACxD,KAAO,EAAE,cAAc,EAC7B,GAAI,CAAC,KAAM,CAAE,GAAG,EAAE,MAAM,4BAA6B,OAAO,EAAG,MAAQ,CAEvE,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAClD,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAC3D,CAAC,EACD,GAAI,CAAC,MAAO,CAAE,GAAG,EAAE,MAAM,kBAAmB,OAAO,EAAG,MAAQ,CAE9D,KAAM,CAAE,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,QAAS,CACrD,cAAe,KACf,QAAe,EAAE,iBAAiB,GAAK,KACvC,SAAe,EAAE,kBAAkB,GAAK,KACxC,MAAe,EAAE,eAAe,GAAK,KACrC,MAAe,EAAE,eAAe,GAAK,KACrC,aAAe,EAAE,gBAAgB,GAAK,KACtC,YAAe,iBAAmB,IACpC,CAAC,EACD,GAAI,MAAO,CAAE,GAAG,EAAE,MAAM,mBAAqB,MAAM,QAAS,OAAO,EAAG,MAAQ,CAQ9E,IAAI,UAAY,GAChB,GAAI,iBAAmB,MAAM,aAAe,aAAe,MAAM,SAAW,YAAa,CACvF,KAAM,CAAE,KAAM,UAAW,EAAI,MAAM,GAAG,EAAE,OAAO,sBAAuB,CACpE,GAAI,CAAE,SAAU,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EACjE,CAAC,EACD,GAAI,CAAC,WAAY,CACf,KAAM,CAAE,KAAM,IAAK,EAAI,MAAM,GAAG,EAAE,OAAO,YAAa,CAAE,OAAQ,eAAgB,GAAI,CAAE,GAAI,eAAgB,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EACjJ,QAAU,KAAK,EAAE,yBAAyB,MAAM,eAAgB,MAAM,YAAY,EACxF,GAAI,QAAS,CACX,KAAM,CAAE,MAAO,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,sBAAuB,CAChE,SAAa,QACb,YAAa,gBACb,OAAa,MAAM,aAAe,EAClC,YAAa,EACb,OAAa,SACb,YAAa,MAAM,aACnB,SAAa,OACf,CAAC,EACI,QAAO,UAAY,GAC1B,CACF,CACF,CAEA,MAAM,YAAY,QAAS,KAAM,KAAM,kBAAmB,8BAA8B,OAAO,GAAG,KAAK,MAAM,MAAQ,aAAa,EAAE,EAEpI,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MACH,UACI,8DAAyD,KAAK,EAAE,eAAe,MAAM,aAAe,CAAC,CAAC,GACtG,2BACJ,UAAW,UAAY,IAAO,GAChC,EAYI,SAAS,eAAe,kBAAkB,GAAU,KAAK,EACzD,SAAS,eAAe,gBAAgB,GAAY,YAAY,EAChE,SAAS,eAAe,yBAAyB,GAAG,OAAO,eAAe,eAAe,EACzF,SAAS,eAAe,qBAAqB,GAAO,OAAO,eAAe,iBAAiB,CACjG,CAGA,eAAe,WAAW,QAAS,CACjC,KAAM,CAAE,KAAM,KAAM,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAClD,OAAQ,qBACR,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAC3D,CAAC,EACD,GAAI,CAAC,MAAO,OAGZ,KAAM,CAAE,KAAM,SAAU,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAAE,OAAQ,iBAAkB,GAAI,CAAE,GAAI,OAAQ,EAAG,YAAa,GAAM,gBAAiB,EAAK,CAAC,EAC7I,WAAa,WAAW,aAAe,CAAC,EAGxC,SADa,MAAM,mBAAqB,WAChB,iBAAmB,MAAM,aAAe,YAAc,cAAgB,qBAM9F,YALe,CACnB,UAAU,YAAa,QAAQ,UAAW,OAAO,SAAU,WAAW,aACtE,UAAU,YAAa,OAAO,kBAAmB,KAAK,OAAQ,UAAU,YACxE,iBAAiB,mBAAoB,gBAAgB,kBAAmB,SAAS,UACnF,EACiC,MAAM,MAAM,GAAK,MAAM,QAAU,SAE5D,UAAY,YAAY,CAAC,GAAG,IAAI,GAAG,CACvC,KAAK,EAAE,SAAS,EAAE,cAAc,QAAG,EACnC,KAAK,EAAE,SAAS,EAAE,KAAK,QAAG,EAC1B,OAAO,EAAE,QAAQ,EACjB,QAAK,EAAE,YAAY,GAAG,QAAQ,CAAC,CAAC,GAChC,QAAK,EAAE,aAAa,GAAG,QAAQ,CAAC,CAAC,EACnC,CAAC,EACK,cAAc,OAAO,MAAM,MAAM,CACrC,UAAU,CAAC,MAAM,MAAM,MAAM,MAAM,KAAK,EACxC,QAAQ,CACN,CAAC,MAAM,SAAS,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,MAAM,MAAM,MAAM,GAAG,EACtD,CAAC,MAAM,aAAa,MAAM,GAAG,EAAE,CAAC,MAAM,QAAQ,MAAM,GAAG,CACzD,EACA,KAAK,QACP,CAAC,EAEK,WAAW,OAAO,MAAM,OAAO,CACnC,MAAM,SACN,OAAO,MAAM,aACb,WAAW,aACX,UAAU,KAAK,EAAE,SAAS,MAAM,eAAe,MAAM,mBAAmB,QAAG,EAC3E,WAAW,CACT,KAAK,EAAE,SAAS,MAAM,SAAS,MAAM,aAAa,EAAE,EACpD,KAAK,EAAE,SAAS,MAAM,UAAU,MAAM,cAAc,EAAE,EACtD,KAAK,EAAE,SAAS,MAAM,OAAO,MAAM,oBAAoB,EAAE,EACzD,GACA,gCAAgC,KAAK,EAAE,WAAW,MAAM,UAAU,CAAC,GACnE,8BAA8B,KAAK,EAAE,SAAS,MAAM,WAAW,MAAM,QAAG,CAAC,GACzE,yBAAyB,KAAK,EAAE,SAAS,MAAM,cAAc,QAAG,CAAC,GACjE,4BAA4B,WAAW,EACzC,CACF,CAAC,EAEK,YAAY;AAAA;AAAA,yIAEgH,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC;AAAA,gBAG5J,UAAY,MAAM,MACpB,sEAAsE,KAAK,EAAE,SAAS,MAAM,KAAK,CAAC,SAClG,GAEE,KAAK;AAAA,QACP,UAAU;AAAA;AAAA;AAAA,QAGV,aAAa;AAAA;AAAA,QAEb,WAAW;AAAA;AAAA,QAEX,SAAS;AAAA,QACT,OAAO,MAAM,WAAW,CAAC,sCAAmC,UAAU,MAAM,cAAc,GAAG,EAAE,EAAE,CAAC,CAAC;AAAA,MAGvG,OAAO,MAAM,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,YAAY,EAAE,CAClE,CAGA,SAAS,YAAa,CACpB,GAAG,EAAE,UAAU,gBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAY7B;AAAA;AAAA;AAAA,MAGA,IAAI,CACT,CAEA,SAAS,kBAAmB,CAC1B,KAAK,EAAE,UACL,CAAC,0BAA0B,gBAAgB,WAAW,UAAU,QAAQ,QAAQ,eAAe,WAAW,YAAY,mCAAmC,eAAe,MAAM,WAAW,aAAa,OAAO,EAC7M,CACE,CAAC,aAAa,aAAa,WAAW,0BAA0B,cAAc,iBAAiB,aAAa,YAAY,yBAAyB,OAAO,gBAAgB,UAAU,IAAI,QAAQ,EAAE,EAChM,CAAC,aAAa,aAAa,WAAW,0BAA0B,cAAc,iBAAiB,aAAa,YAAY,yBAAyB,OAAO,gBAAgB,UAAU,IAAI,QAAQ,kDAA6C,CAC7O,EACA,iBACF,CACF,CAEA,IAAI,YAAc,CAAC,EAOnB,SAAS,iBAAiB,IAAK,CAC7B,MAAM,KAAO,KAAO,IAAI,KAAK,EAC7B,GAAI,sBAAsB,KAAK,GAAG,EAAG,OAAO,IAC5C,MAAM,EAAI,IAAI,MAAM,iCAAiC,EACrD,GAAI,EAAG,CACL,MAAM,IAAM,SAAS,EAAE,CAAC,EAAG,EAAE,EAAG,MAAQ,SAAS,EAAE,CAAC,EAAG,EAAE,EAAG,KAAO,SAAS,EAAE,CAAC,EAAG,EAAE,EACpF,GAAI,KAAO,GAAK,KAAO,IAAM,OAAS,GAAK,OAAS,GAClD,MAAO,GAAG,IAAI,IAAI,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,IAAI,OAAO,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,EAElF,CACA,MAAO,EACT,CAEA,eAAe,cAAc,MAAO,CAClC,MAAM,KAAO,MAAM,QAAQ,CAAC,EAC5B,GAAI,CAAC,KAAM,OACX,MAAM,KAAO,MAAM,KAAK,KAAK,EACvB,CAAE,QAAS,IAAK,EAAI,KAAK,EAAE,SAAS,IAAI,EACxC,QAAU,SAAS,eAAe,oBAAoB,EACtD,UAAY,SAAS,eAAe,uBAAuB,EAEjE,GAAI,CAAC,KAAK,OAAQ,CACZ,UAAS,QAAQ,UAAY,8HACjC,MACF,CAEA,MAAM,UAAY,QAAQ,SAAS,MAAM,GAAK,QAAQ,SAAS,eAAe,EACxE,SAAW,IAAI,KAAK,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,EACtD,YAAc,KAAK,IAAI,CAAC,IAAK,IAAM,CACjC,MAAM,IAAM,KAAO,CACjB,MAAM,IAAM,QAAQ,QAAQ,GAAG,EAC/B,OAAO,KAAO,GAAI,IAAI,GAAG,GAAK,EAChC,EACA,GAAI,UACF,MAAO,CACL,WAAe,iBAAiB,IAAI,YAAY,GAAG,MAAM,GAAG,EAAE,CAAC,CAAC,GAAK,SACrE,cAAe,IAAI,eAAe,GAAK,IAAI,cAAc,EACzD,SAAe,IAAI,cAAc,EACjC,QAAe,CAAC,IAAI,mBAAmB,EAAE,IAAI,mBAAmB,EAAE,IAAI,eAAe,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,EACjH,MAAe,IAAI,gBAAgB,GAAK,IAAI,eAAe,EAC3D,MAAe,IAAI,OAAO,EAC1B,cAAe,sBACf,eAAgB,GAChB,eAAgB,OAChB,aAAe,IAAI,eAAe,EAClC,IAAe,IAAI,cAAc,EACjC,SAAe,SAAS,IAAI,mBAAmB,CAAC,GAAG,EACnD,WAAe,WAAW,IAAI,gBAAgB,CAAC,GAAG,EAClD,aAAe,IAAI,MAAM,EACzB,MAAe,CAAC,EAAE,IAAI,eAAe,GAAK,IAAI,eAAe,EAC/D,EACK,CACL,MAAM,QAAU,IAAI,yBAAyB,GAAK,IAAI,YAAY,EAC5D,WAAa,iBAAiB,OAAO,EAC3C,MAAO,CACL,WAAe,WACf,cAAe,IAAI,eAAe,EAClC,SAAe,IAAI,UAAU,EAC7B,QAAe,IAAI,SAAS,EAC5B,MAAe,IAAI,OAAO,EAC1B,MAAe,IAAI,OAAO,EAC1B,aAAe,IAAI,cAAc,EACjC,cAAe,IAAI,UAAU,EAC7B,eAAgB,IAAI,WAAW,EAC/B,gBAAiB,IAAI,kCAAkC,GAAK,IAAI,gBAAgB,GAAK,QAAQ,YAAY,EACzG,aAAe,IAAI,cAAc,EACjC,IAAe,IAAI,KAAK,EACxB,SAAe,SAAS,IAAI,UAAU,CAAC,GAAG,EAC1C,WAAe,WAAW,IAAI,YAAY,CAAC,GAAG,EAC9C,MAAe,IAAI,OAAO,EAC1B,MAAe,CAAC,EAAE,IAAI,eAAe,GAAK,IAAI,cAAc,GAAK,WACnE,CACF,CACF,CAAC,EAED,MAAM,MAAU,YAAY,OAAO,GAAK,EAAE,KAAK,EAAE,OAC3C,QAAU,YAAY,OAAS,MAEjC,UAAS,QAAQ,UAAY;AAAA;AAAA,8BAEP,YAAY,MAAM,yBAAoB,KAAK,WAAW,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,mBAKxE,YAAY,MAAM,EAAE,EAAE,EAAE,IAAI,GAAK;AAAA;AAAA,oBAEhC,KAAK,EAAE,SAAS,EAAE,eAAe,QAAG,CAAC;AAAA,oBACrC,KAAK,EAAE,SAAS,EAAE,cAAc,QAAG,CAAC;AAAA,oBACpC,EAAE,QAAQ;AAAA,oBACV,KAAK,EAAE,eAAe,EAAE,UAAU,CAAC;AAAA,oBACnC,EAAE,MAAM,2DAAsD,yDAAoD;AAAA,kBACpH,EAAE,KAAK,EAAE,CAAC;AAAA,cACd,YAAY,OAAS,GAAK,uDAAuD,YAAY,OAAO,EAAE,uBAAyB,EAAE;AAAA;AAAA;AAAA,eAKvI,YAAW,UAAU,MAAM,QAAU,MAAQ,EAAI,cAAgB,OACvE,CAIA,eAAe,qBAAqB,IAAK,KAAM,CAC7C,GAAI,IAAK,CACP,KAAM,CAAE,IAAK,EAAI,MAAM,GAAG,EAAE,OAAO,WAAY,CAAE,GAAI,CAAE,IAAK,IAAI,KAAK,CAAE,EAAG,OAAQ,aAAc,CAAC,EACjG,GAAI,OAAO,CAAC,EAAG,OAAO,KAAK,CAAC,CAC9B,CACA,GAAI,KAAM,CACR,KAAM,CAAE,IAAK,EAAI,MAAM,GAAG,EAAE,OAAO,WAAY,CAAE,MAAO,CAAE,KAAM,KAAK,KAAK,CAAE,EAAG,OAAQ,cAAe,MAAO,CAAE,CAAC,EAChH,GAAI,OAAO,CAAC,EAAG,OAAO,KAAK,CAAC,CAC9B,CACA,OAAO,IACT,CAIA,eAAe,oBAAoB,OAAQ,UAAW,UAAW,WAAY,CAC3E,IAAI,MAAQ,EACZ,GAAI,WAAY,CACd,KAAM,CAAE,IAAK,EAAI,MAAM,OAAO,KAAK,gBAAgB,EAAE,OAAO,OAAO,EAAE,GAAG,aAAc,SAAS,EAAE,GAAG,aAAc,UAAU,EAAE,GAAG,cAAe,UAAU,EAAE,MAAM,CAAC,EAC/J,OAAO,CAAC,IAAG,MAAQ,KAAK,CAAC,EAAE,MACjC,CACA,GAAI,CAAC,MAAO,CACV,MAAM,UAAY,YAAc,SAAW,MAAQ,YAC7C,CAAE,IAAK,EAAI,MAAM,OAAO,KAAK,gBAAgB,EAAE,OAAO,OAAO,EAAE,GAAG,aAAc,SAAS,EAAE,GAAG,aAAc,SAAS,EAAE,GAAG,cAAe,IAAI,EAAE,MAAM,CAAC,EACxJ,OAAO,CAAC,IAAG,MAAQ,KAAK,CAAC,EAAE,MACjC,CACA,GAAI,CAAC,MAAO,CACV,MAAM,aAAe,YAAc,SAAW,YAAc,MACtD,CAAE,IAAK,EAAI,MAAM,OAAO,KAAK,gBAAgB,EAAE,OAAO,OAAO,EAAE,GAAG,aAAc,SAAS,EAAE,GAAG,aAAc,YAAY,EAAE,GAAG,cAAe,IAAI,EAAE,MAAM,CAAC,EAC3J,OAAO,CAAC,IAAG,MAAQ,KAAK,CAAC,EAAE,MACjC,CACA,KAAM,CAAE,KAAM,QAAS,EAAI,MAAM,OAAO,KAAK,gBAAgB,EAAE,OAAO,OAAO,EAAE,GAAG,aAAc,SAAS,EAAE,GAAG,aAAc,MAAM,EAAE,GAAG,cAAe,IAAI,EAAE,MAAM,CAAC,EAC7J,UAAY,WAAW,CAAC,GAAG,OAAS,EAC1C,MAAO,CAAE,MAAO,OAAS,EAAG,SAAU,CACxC,CAEA,eAAe,cAAe,CAC5B,MAAM,MAAQ,YAAY,OAAO,GAAK,EAAE,KAAK,EAC7C,GAAI,CAAC,MAAM,OAAQ,OAEnB,MAAM,UAAY,SAAS,eAAe,uBAAuB,EAC7D,YAAa,UAAU,SAAW,GAAM,UAAU,UAAY,yDAElE,MAAM,OAAS,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC3F,CAAE,KAAM,SAAU,EAAI,MAAM,OAAO,KAAK,WAAW,EAAE,OAAO,oBAAoB,EAAE,GAAG,YAAa,EAAI,EACtG,YAAc,CAAC,GACpB,WAAW,CAAC,GAAG,QAAQ,GAAK,CAAE,YAAY,EAAE,KAAK,YAAY,CAAC,EAAI,CAAG,CAAC,EAEvE,KAAM,CAAE,KAAM,UAAW,EAAI,MAAM,GAAG,EAAE,OAAO,aAAc,CAAE,GAAI,CAAE,UAAW,EAAK,CAAE,CAAC,EAClF,aAAe,CAAC,GACrB,YAAY,CAAC,GAAG,QAAQ,GAAK,CAAE,aAAa,EAAE,KAAK,YAAY,CAAC,EAAI,EAAE,EAAI,CAAC,EAC5E,MAAM,oBAAsB,YAAY,CAAC,GAAG,KAAK,GAAK,EAAE,UAAU,GAAG,KAAO,YAAY,CAAC,GAAG,CAAC,GAAG,IAAM,KACtG,IAAI,wBAA0B,EAE1B,QAAU,EAAG,YAAc,EAAG,eAAiB,EAAG,gBAAkB,EACxE,MAAM,OAAS,CAAC,EAChB,MAAM,QAAQ,KAAO,CACnB,MAAM,IAAM,IAAI,cAAgB,GAAG,IAAI,aAAa,KAAK,IAAI,QAAQ,KAAK,IAAI,UAAU,GACnF,OAAO,GAAG,IAAG,OAAO,GAAG,EAAI,CAAE,GAAG,IAAK,MAAO,CAAC,CAAE,GACpD,OAAO,GAAG,EAAE,MAAM,KAAK,CAAE,aAAc,IAAI,aAAc,IAAK,IAAI,IAAK,SAAU,IAAI,SAAU,WAAY,IAAI,UAAW,CAAC,CAC7H,CAAC,EAED,MAAM,aAAe,OAAO,QAAQ,MAAM,EACpC,YAAc,aAAa,OAK3B,QAAU,SAAS,eAAe,oBAAoB,EACxD,SACF,QAAQ,mBAAmB,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAShC,EAEX,MAAM,kBAAoB,CAAC,KAAM,QAAU,CACzC,MAAM,IAAM,YAAc,EAAI,KAAK,MAAO,KAAK,YAAa,GAAG,EAAI,EAC7D,IAAM,SAAS,eAAe,yBAAyB,EACvD,MAAQ,SAAS,eAAe,yBAAyB,EACzD,QAAU,SAAS,eAAe,2BAA2B,EAC/D,MAAK,IAAI,MAAM,MAAQ,IAAI,KAC3B,QAAO,MAAM,YAAc,IAAI,KAC/B,UAAS,QAAQ,YAAc,MACrC,EAKM,CAAE,KAAM,SAAU,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,CAAE,OAAQ,eAAgB,MAAO,CAAE,aAAc,MAAO,EAAG,MAAO,CAAE,IAAK,eAAgB,IAAK,EAAM,EAAG,MAAO,CAAE,CAAC,EACzK,IAAI,SAAW,YAAY,CAAC,GAAG,cAAe,SAAS,UAAU,CAAC,EAAE,aAAa,MAAM,GAAG,EAAE,IAAI,CAAC,GAAK,EAElG,UAAY,EAGhB,MAAM,aAAe,CAAC,EACtB,SAAW,CAAC,IAAK,KAAK,IAAK,aAAc,CACvC,YACA,kBAAkB,UAAY,EAAG,mBAAmB,SAAS,OAAO,WAAW,KAAK,MAAM,aAAa,EAAE,EAEzG,MAAM,SAAW,aAAa,MAAM,eAAe,IAAI,YAAY,CAAC,GAAK,KACnE,WAAa,UAAU,IAAM,KAC7B,UAAY,UAAU,YAAc,SAE1C,IAAI,YAAc,cAAc,MAAM,gBAAgB,IAAI,YAAY,CAAC,GAAK,KACvE,cAAe,YAAc,mBAAoB,2BAEtD,MAAM,cAAgB,CAAC,OAAO,MAAM,QAAQ,EAAE,SAAS,MAAM,cAAc,EAAI,MAAM,eAAiB,OAChG,gBAAkB,gBAAkB,SAAW,IAAI,KAAK,KAAK,IAAI,EAAI,MAAQ,GAAG,GAAI,EAAE,YAAY,EAAI,KAE5G,IAAI,kBAAoB,KACxB,GAAI,MAAM,MAAO,CACf,KAAM,CAAE,KAAM,IAAK,EAAI,MAAM,GAAG,EAAE,OAAO,YAAa,CAAE,GAAI,CAAE,MAAO,MAAM,MAAM,KAAK,EAAG,UAAW,EAAK,EAAG,YAAa,EAAK,CAAC,EAC3H,OAAM,kBAAoB,KAAK,GACrC,CAMA,GAAI,YAAc,aAAe,CAAC,mBAAqB,gBAAkB,OAAQ,CAC/E,aAAa,KAAK,GAAG,MAAM,aAAa,gFAAgF,EACxH,QACF,CAIA,MAAM,cAAgB,MAAM,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,MAAQ,CACpE,MAAM,QAAU,MAAM,qBAAqB,KAAK,IAAK,KAAK,YAAY,EACtE,IAAI,UAAY,KAAK,WACjB,UAAY,EAChB,GAAI,SAEF,GADA,cACI,CAAC,UAAW,CACd,MAAM,SAAW,MAAM,oBAAoB,OAAQ,QAAQ,GAAI,UAAW,UAAU,EACpF,UAAY,SAAS,MACrB,UAAY,SAAS,SACvB,OAEA,iBAEF,MAAO,CAAE,GAAG,KAAM,WAAY,SAAS,IAAM,KAAM,WAAY,WAAa,EAAG,WAAY,SAAU,CACvG,CAAC,CAAC,EAEI,MAAQ,cAAc,OAAO,CAAC,EAAG,IAAM,EAAK,EAAE,SAAW,EAAE,WAAa,CAAC,EACzE,cAAgB,IAAI,KAAK,GAAG,MAAM,UAAU,IAAI,IAAI,KAAK,EAAE,aAAa,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,EAAE,EAG/F,IAAI,MAAO,MACX,QAAS,QAAU,EAAG,QAAU,EAAG,UAAW,CAC5C,WACA,MAAM,YAAc,OAAO,OAAO,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,GACrD,OAAS,MAAM,GAAG,EAAE,OAAO,SAAU,CACzC,aAAmB,YACnB,YAAmB,WACnB,WAAmB,UACnB,iBAAmB,SACnB,cAAmB,MAAM,cACzB,YAAmB,kBACnB,aAAmB,YACnB,SAAmB,MAAM,SACzB,QAAmB,MAAM,QACzB,MAAmB,MAAM,MACzB,MAAmB,MAAM,MACzB,aAAmB,MAAM,aACzB,MAAmB,MAAM,MACzB,OAAmB,YACnB,WAAmB,cAAc,YAAY,EAC7C,eAAmB,cACnB,kBAAmB,gBACnB,YAAmB,MACnB,mBAAoB,GACpB,WAAmB,OAAO,GAAG,KAAK,MAAM,EAC1C,CAAC,EAID,GAHA,MAAQ,OAAO,KAAM,MAAQ,OAAO,MAChC,CAAC,OAED,EADW,MAAM,OAAS,SAAW,iBAAiB,KAAK,MAAM,SAAS,EAAE,GACnE,KACf,CAEA,GAAI,CAAC,OAAS,MAAO,CAGnB,MAAM,WAAa,OAAO,SAAS,aAAa,OAAO,iBAAkB,OAAO,qBAAqB,EAC/F,CAAE,MAAO,aAAc,EAAI,MAAM,WAAW,KAAK,aAAa,EAAE,OAAO,cAAc,IAAI,OAAS,CACtG,SAAc,MAAM,GACpB,WAAc,KAAK,WACnB,aAAc,KAAK,aACnB,IAAc,KAAK,IACnB,SAAc,KAAK,SACnB,WAAc,KAAK,WACnB,YAAc,KAAK,SAAW,KAAK,WACnC,WAAc,KAAK,UACrB,EAAE,CAAC,EACH,GAAI,cAAe,CAEjB,KAAM,CAAE,MAAO,SAAU,EAAI,MAAM,GAAG,EAAE,OAAO,SAAU,MAAM,EAAE,EACjE,aAAa,KAAK,UACd,GAAG,MAAM,aAAa,KAAK,MAAM,YAAY,6CAC7C,MAAM,aAAa,EACvB,QACF,CAIA,UAAW,QAAQ,cAAe,CAChC,GAAI,CAAC,KAAK,YAAc,CAAC,YAAa,SACtC,KAAM,CAAE,KAAM,EAAG,EAAI,MAAM,GAAG,EAAE,OAAO,eAAgB,CACrD,GAAI,CAAE,WAAY,KAAK,WAAY,aAAc,WAAY,EAAG,YAAa,GAAM,gBAAiB,EACtG,CAAC,EACD,GAAI,GAAI,CACN,MAAM,WAAa,GAAG,UAAU,IAAM,GAAG,cAAc,GACnD,KAAK,SAAW,WAAW,kBAC/B,MAAM,GAAG,EAAE,OAAO,eAAgB,GAAG,GAAI,CAAE,cAAe,GAAG,cAAc,GAAK,KAAK,QAAS,CAAC,CACjG,MACE,kBACA,MAAM,GAAG,EAAE,OAAO,eAAgB,CAAE,WAAY,KAAK,WAAY,aAAc,YAAa,SAAU,EAAG,aAAc,KAAK,QAAS,CAAC,CAE1I,CAEA,MAAM,YAAY,MAAM,GAAI,gBAAiB,GAAI,YAAa,4BAA4B,MAAM,aAAa,gBAAa,MAAM,QAAQ,CAAC,CAAC,EAAE,EAC5I,SACF,MACE,aAAa,KAAK,MAAM,aAAa,CAEzC,CAEA,GAAG,EAAE,WAAW,EAChB,IAAI,IAAM,GAAG,OAAO,qBAChB,eAAiB,IAAG,KAAO,WAAM,cAAc,mEAC/C,gBAAkB,IAAG,KAAO,WAAM,eAAe,oDACjD,wBAA0B,IAAG,KAAO,WAAM,uBAAuB,wCACjE,aAAa,SAAQ,KAAO,KAAK,aAAa,MAAM,kDAAkD,aAAa,KAAK,IAAI,CAAC,8CACjI,GAAG,EAAE,MAAM,IAAK,aAAa,OAAS,QAAW,gBAAgB,gBAAkB,UAAY,UAAY,aAAa,OAAS,KAAQ,GAAI,EAC7I,YAAc,CAAC,EACf,KAAK,CACP,CAGA,OAAO,iBAAiB,YAAa,GAAK,CACpC,EAAE,OAAO,QAAU,WACrB,YAAc,CAAC,EACf,KAAK,EAEL,WAAW,kBAAmB,GAAG,EAErC,CAAC,EAED,OAAO,iBAAiB,YAAa,IAAM,CACzC,SAAS,eAAe,oBAAoB,GAAG,iBAAiB,QAAS,YAAY,EACrF,SAAS,eAAe,uBAAuB,GAAG,iBAAiB,QAAS,UAAU,EACtF,SAAS,eAAe,wBAAwB,GAAG,iBAAiB,QAAS,WAAW,EACxF,CAAC,oBAAoB,oBAAoB,sBAAsB,iBAAiB,EAAE,QAAQ,IAAM,CAC9F,MAAM,GAAK,SAAS,eAAe,EAAE,EAChC,KACL,GAAG,iBAAiB,QAAS,KAAK,EAAE,SAAS,KAAM,GAAG,CAAC,EACvD,GAAG,iBAAiB,SAAU,IAAI,EACpC,CAAC,CACH,CAAC,EAED,OAAO,WAAa,CAAE,iBAAkB,mBAAoB,cAC1D,KAAM,UAAW,aAAc,YAAa,aAAc,iBAC1D,aAAc,wBAAyB,cAAe,QAAS,WAAY,WAAY,YAAa,cACpG,kBAAmB,sBAAuB,sBAAuB,YACjE,cAAe,cAAe,UAC9B,mBAAoB,oBAAqB,wBACzC,qBAAsB,qBAAsB,uBAC5C,kBACA,kBAAmB,mBAAoB,mBAAoB,kBAAmB,WAAY,WAC1F,WACA,WAAY,iBAAkB,cAAe,aAC7C,SAAU,eAAgB,gBAAiB,aAC3C,mBAAoB,cAAe,mBAAoB,sBACvD,YAAa,YAAa,mBAAoB,cAAe,qBAC7D,WAAY,cAAe,oBAAqB,gBAChD,kBAAmB,cAAe,aAClC,YAAa,uBAAwB,oBACrC,kBAAmB,gBAAiB,eAAgB,gBACpD,OAAS,GAAM,CAAE,aAAe,EAAG,YAAY,CAAG,CACpD,CAEF,GAAG",
  "names": []
}
