/* store.js — shared data layer (localStorage). Load this first on both pages. */ (function (global) { 'use strict'; var PKEY = 'qgen.pricelist.v3'; var QKEY = 'qgen.quote.v3'; var TERMS = [1, 3, 5, 10]; var DEFAULT_CODES = [ 'WAM B', 'WAM P', 'WAM C', 'MWPB', 'MWPD', 'MWPU', 'WHE', 'WHD', 'WHU', 'WHM', 'WHPL', 'WHPE', 'WHPG', 'WHPEx' ]; var money = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2, maximumFractionDigits: 2 }); function fmt(n) { return money.format(isFinite(n) ? n : 0); } function num(v) { var n = parseFloat(v); if (!isFinite(n) || n < 0) return 0; return Math.round(n * 100) / 100; } function blankDisc() { var d = {}; TERMS.forEach(function (y) { d[y] = 0; }); return d; } function blankProduct(code) { return { code: code, label: '', retail: 0, disc: blankDisc() }; } function defaults() { return { seeded: true, settings: { discMode: 'total' }, // 'total' | 'peryear' products: DEFAULT_CODES.map(blankProduct) }; } function normalizeProduct(p) { var out = blankProduct(String(p && p.code ? p.code : 'NEW').trim() || 'NEW'); out.label = p && p.label ? String(p.label) : ''; out.retail = num(p && p.retail); TERMS.forEach(function (y) { out.disc[y] = num(p && p.disc ? p.disc[y] : 0); }); return out; } function normalize(raw) { var data = defaults(); if (!raw || typeof raw !== 'object') return data; data.seeded = raw.seeded !== false; if (raw.settings && raw.settings.discMode === 'peryear') { data.settings.discMode = 'peryear'; } if (Array.isArray(raw.products)) { var seen = {}; data.products = raw.products.map(normalizeProduct).map(function (p) { var base = p.code, i = 2; while (seen[p.code.toLowerCase()]) { p.code = base + ' (' + i + ')'; i++; } seen[p.code.toLowerCase()] = true; return p; }); // Re-add any factory codes only if this list was never seeded. if (!data.seeded) { DEFAULT_CODES.forEach(function (c) { if (!seen[c.toLowerCase()]) data.products.push(blankProduct(c)); }); data.seeded = true; } } return data; } function loadPrices() { try { var raw = localStorage.getItem(PKEY); if (!raw) return defaults(); return normalize(JSON.parse(raw)); } catch (e) { console.warn('Price list unreadable, using defaults.', e); return defaults(); } } function savePrices(data) { try { localStorage.setItem(PKEY, JSON.stringify(normalize(data))); return true;