{"id":512,"date":"2026-09-25T21:56:35","date_gmt":"2026-09-25T19:56:35","guid":{"rendered":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/"},"modified":"2026-09-25T22:02:00","modified_gmt":"2026-09-25T20:02:00","slug":"min-foderplan","status":"publish","type":"page","link":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/","title":{"rendered":"Min foderplan"},"content":{"rendered":"\n<div class=\"wp-block-group alignfull kiss kiss-myplan is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-group kiss-plan-hero kiss-myplan-hero kiss-band-forest is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-group kiss-inner is-layout-flow wp-block-group-is-layout-flow\">\n<p class=\"kiss-label wp-block-paragraph\">Automatisk levering<\/p>\n\n\n\n<h1 class=\"wp-block-heading kiss-hero-title\">Min foderplan<\/h1>\n\n\n\n<p class=\"kiss-lead wp-block-paragraph\">Her styrer du leveringerne. N\u00e6ste pose lander, lige f\u00f8r den gamle er tom, og du kan springe over, flytte eller s\u00e6tte p\u00e5 pause, n\u00e5r du vil.<\/p>\n<\/div>\n\n\n\n<div class=\"kiss-float-stickers\" aria-hidden=\"true\"><img decoding=\"async\" src=\"https:\/\/myfirstdomain.byrasmusfrost.com\/wp-content\/uploads\/2026\/09\/kiss-sticker-husky.webp\" alt=\"\"><img decoding=\"async\" src=\"https:\/\/myfirstdomain.byrasmusfrost.com\/wp-content\/uploads\/2026\/09\/kiss-sticker-cocker.webp\" alt=\"\"><img decoding=\"async\" src=\"https:\/\/myfirstdomain.byrasmusfrost.com\/wp-content\/uploads\/2026\/09\/kiss-sticker-bulldog.webp\" alt=\"\"><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-group kiss-sec kiss-planner-sec kiss-myplan-sec is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-group kiss-wrap is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"kiss-dash is-loading\" id=\"kissMyPlan\" aria-live=\"polite\"><p class=\"kiss-dash-loading\">Henter din foderplan \u2026<\/p><\/div>\n<script>(function(){var KP=(function(){var K=(function kissPlanBase() {\nvar KEY = 'kissPlan', DAY = 864e5;\nfunction has(a, k) { return (a || []).indexOf(k) > -1; }\nfunction poss(name) { name = String(name || '').trim(); if (!name) return ''; return name + (\/[sxz]$\/i.test(name) ? '\u2019' : 's'); }\nfunction num(n, dec) { if (dec) return n.toFixed(dec).replace('.', ','); var r = Math.round(n); return r >= 1000 ? r.toLocaleString('da-DK') : String(r); }\nfunction kr(n) { var r = Math.round(n * 100) \/ 100; return (r % 1 ? r.toFixed(2).replace('.', ',') : String(Math.round(r))) + ' kr.'; }\nfunction kgTxt(g) { return num(g \/ 1000, g % 1000 ? 1 : 0) + ' kg'; }\nfunction ship(total) { return total >= 399 ? 0 : 39; }\nfunction now(p) { var d = new Date(); d.setHours(12, 0, 0, 0); return new Date(d.getTime() + ((p ? p.demo : 0) || 0) * DAY); }\nfunction addDays(d, n) { var x = new Date(d.getTime() + n * DAY); x.setHours(12, 0, 0, 0); return x; }\nfunction workdays(d, n) { var x = d; while (n > 0) { x = addDays(x, 1); var w = x.getDay(); if (w !== 0) { if (w !== 6) n--; } } return x; }\nfunction iso(d) { var m = d.getMonth() + 1, dd = d.getDate(); return d.getFullYear() + '-' + (m > 9 ? m : '0' + m) + '-' + (dd > 9 ? dd : '0' + dd); }\nfunction fromIso(s) { var a = String(s).split('-'); return new Date(+a[0], +a[1] - 1, +a[2], 12); }\nfunction between(a, b) { return Math.round((b - a) \/ DAY); }\nfunction fmt(d, long) {\ntry { return d.toLocaleDateString('da-DK', long ? { weekday: 'long', day: 'numeric', month: 'long' } : { weekday: 'short', day: 'numeric', month: 'short' }); }\ncatch (e) { return iso(d); }\n}\nfunction load() { try { var s = localStorage.getItem(KEY); return s ? JSON.parse(s) : null; } catch (e) { return null; } }\nfunction save(p) { try { p.updated = Date.now(); localStorage.setItem(KEY, JSON.stringify(p)); return true; } catch (e) { return false; } }\nfunction clear() { try { localStorage.removeItem(KEY); } catch (e) {} }\nfunction stockAt(p, d) {\nif (!p.stock) return 0;\nvar days = between(fromIso(p.stock.date), d);\nif (0 > days) return p.stock.grams;\nreturn Math.max(0, p.stock.grams - p.g * days);\n}\nfunction arrived(p) { return p.stock ? now(p) >= fromIso(p.stock.date) : false; }\nfunction retime(p) {\nvar t = now(p), min = addDays(t, 1);\nif (!arrived(p)) { p.next = iso(addDays(fromIso(p.stock.date), p.d - 2)); return p; }\nvar run = addDays(t, Math.floor(stockAt(p, t) \/ p.g)), nx = addDays(run, -2);\np.next = iso(nx > min ? nx : min);\nreturn p;\n}\nfunction activate(p, order) {\nvar t = now(p), first = workdays(t, 2);\np.status = 'active';\np.order = order || '';\np.started = iso(t);\np.first = iso(first);\np.stock = { date: iso(first), grams: p.n * p.product.bag };\np.next = iso(addDays(first, p.d - 2));\np.skips = [];\np.history = [{ date: iso(first), n: p.n, s: 'first' }];\nreturn p;\n}\nfunction roll(p) {\nif (!p) return p;\nif (p.status !== 'active') return p;\nvar t = now(p);\nfor (var i = 0; 80 > i; i++) {\nvar nd = fromIso(p.next);\nif (nd > t) break;\nif (has(p.skips, p.next)) {\np.history.push({ date: p.next, n: 0, s: 'skip' });\np.skips = p.skips.filter(function (x) { return x !== p.next; });\n} else {\np.stock = { date: p.next, grams: stockAt(p, nd) + p.n * p.product.bag };\np.history.push({ date: p.next, n: p.n, s: 'ok' });\n}\np.next = iso(addDays(nd, p.d));\n}\nif (p.history.length > 12) p.history = p.history.slice(-12);\nreturn p;\n}\nfunction upcoming(p, count) {\nvar out = [], t = now(p), cur = fromIso(p.next);\nfor (var i = 0; count > i; i++) { out.push({ date: iso(cur), skip: has(p.skips, iso(cur)) }); cur = addDays(cur, p.d); }\nvar food = arrived(p) ? stockAt(p, t) : p.stock.grams, from = arrived(p) ? t : fromIso(p.stock.date), empty = null;\nfor (var j = 0; out.length > j; j++) {\nvar dd = fromIso(out[j].date), need = p.g * between(from, dd);\nif (need > food) { empty = addDays(from, Math.floor(food \/ p.g)); break; }\nfood = food - need;\nfrom = dd;\nif (!out[j].skip) food = food + p.n * p.product.bag;\n}\nreturn { list: out, empty: empty };\n}\nfunction summary(p) { return p.n + ' \u00d7 ' + p.product.n + ' (' + kgTxt(p.product.bag) + ') hver ' + p.d + '. dag'; }\nreturn {\nDAY: DAY, has: has, poss: poss, num: num, kr: kr, kgTxt: kgTxt, ship: ship,\nnow: now, addDays: addDays, workdays: workdays, iso: iso, fromIso: fromIso, between: between, fmt: fmt,\nload: load, save: save, clear: clear, stockAt: stockAt, arrived: arrived, retime: retime,\nactivate: activate, roll: roll, upcoming: upcoming, summary: summary\n};\n})();return (function kissPlanData(K) {\nvar BREEDS = {\nhusky: { n: 'Husky', kg: 22, act: 'high', tip: 'Huskyer er bygget til at l\u00f8be og har ofte et h\u00f8jt energibehov p\u00e5 aktive dage.' },\nsetter: { n: 'Setter', kg: 27, act: 'high', tip: 'Settere er energiske jagthunde, der har brug for nok protein til de lange ture.' },\nfrenchie: { n: 'Fransk bulldog', kg: 12, lean: ['mave', 'vaegt'], tip: 'Franske bulldogs kan have en f\u00f8lsom mave og tager nemt p\u00e5. Sm\u00e5, faste m\u00e5ltider hj\u00e6lper.' },\npoodle: { n: 'Puddel', kg: 15, lean: ['pels'], tip: 'Pudler har pels, der vokser hele tiden. Omega-3 fra fisk st\u00f8tter hud og pels.' },\ncocker: { n: 'Cocker spaniel', kg: 13, lean: ['vaegt', 'pels'], tip: 'Cocker spaniels elsker mad og tager let p\u00e5, s\u00e5 vej portionen af.' },\nhound: { n: 'Beagle', kg: 12, lean: ['vaegt'], tip: 'Beagler er madglade og tager let p\u00e5. Hold igen med godbidderne.' },\nretriever: { n: 'Golden retriever', kg: 30, lean: ['led', 'vaegt'], tip: 'Retrievere er glade for mad. En stabil v\u00e6gt sk\u00e5ner leddene.' },\nbulldog: { n: 'Engelsk bulldog', kg: 23, lean: ['mave', 'pels'], tip: 'Engelske bulldogs har ofte sart hud og mave og har godt af en stabil v\u00e6gt.' },\nrottweiler: { n: 'Rottweiler', kg: 45, lean: ['led'], tip: 'Rottweilere er store hunde med tunge led. En stabil v\u00e6gt sk\u00e5ner leddene.' },\ndoberman: { n: 'Dobermann', kg: 38, act: 'high', lean: ['led'], tip: 'Dobermanns er atletiske og har brug for foder, der holder dem slanke og st\u00e6rke.' },\nmixed: { n: 'Blanding', kg: 15, tip: 'Blandinger er lige s\u00e5 forskellige som deres for\u00e6ldre. V\u00e6gt og aktivitet siger mest om portionen.' }\n};\nvar PRODUCTS = [\n{ id: 225, slug: 'kylling-havre', n: 'Kylling \\u0026 havre', price: 179, bag: 2000, kcal: 3.7, life: 'adult', w: { aktiv: 1, ingen: 3 } },\n{ id: 226, slug: 'laks-sode-kartofler', n: 'Laks \\u0026 s\u00f8de kartofler', price: 199, bag: 2000, kcal: 3.8, life: 'adult', w: { pels: 4, aktiv: 2, mave: 1 } },\n{ id: 227, slug: 'lam-ris', n: 'Lam \\u0026 ris', price: 149, bag: 2000, kcal: 3.6, life: 'adult', w: { mave: 4, allergi: 2, kraesen: 2 } },\n{ id: 228, slug: 'hvalpe-kylling', n: 'Hvalpe-kylling', price: 169, bag: 1500, kcal: 3.9, life: 'puppy', w: {} },\n{ id: 229, slug: 'sensitiv-laks-kornfri', n: 'Sensitiv laks, kornfri', price: 219, bag: 2000, kcal: 3.7, life: 'adult', w: { allergi: 5, mave: 3, pels: 2 } },\n{ id: 230, slug: 'senior-let', n: 'Senior let', price: 209, bag: 2000, kcal: 3.4, life: 'senior', w: { vaegt: 5, led: 4 } }\n];\nvar WHY = {\n225: { base: 'Langsomt bagt kylling og fuldkornshavre giver j\u00e6vn energi.', ingen: 'Vores bestseller og et sikkert valg til de fleste voksne hunde.', aktiv: 'Kylling og havre giver stabil energi til g\u00e5ture og leg.' },\n226: { base: 'Norsk laks og s\u00f8de kartofler med omega-3.', pels: 'Laksolie med omega-3 giver blank pels og rolig hud.', aktiv: 'Ekstra energi fra laks til lange ture og l\u00f8b.', mave: 'S\u00f8de kartofler er sk\u00e5nsomme for maven.' },\n227: { base: 'Mildt lam og ris til voksne hunde.', mave: 'Lam og ris er milde r\u00e5varer, der sk\u00e5ner en f\u00f8lsom mave.', allergi: 'Lam er et godt skift, hvis kylling giver kl\u00f8e.', kraesen: 'Mild smag, som mange kr\u00e6sne hunde tager godt imod.' },\n228: { base: 'Sm\u00e5 kugler med ekstra protein og calcium til en hvalp i v\u00e6kst.' },\n229: { base: 'Kornfrit foder med laks til en sart mave.', allergi: 'Kornfrit og med laks, s\u00e5 der er f\u00e6rre ting at reagere p\u00e5.', mave: 'Let at ford\u00f8je for en sart mave.', pels: 'Laks giver omega-3 til hud og pels.' },\n230: { base: 'F\u00e6rre kalorier og ekstra glukosamin.', vaegt: 'F\u00e6rre kalorier g\u00f8r det lettere at holde v\u00e6gten.', led: 'Glukosamin og gr\u00f8nl\u00e6bet musling st\u00f8tter leddene.', senior: 'Lavet til hunde p\u00e5 7 \u00e5r og derover.' }\n};\nvar EXTRA = {\nkraesen: { id: 231, n: 'Kyllingegryde, 6 \u00d7 400 g', t: 'En skefuld v\u00e5dfoder ovenp\u00e5 g\u00f8r sk\u00e5len mere sp\u00e6ndende.' },\npuppy: { id: 233, n: 'Tr\u00e6ningsgodbidder, kylling', t: 'Sm\u00e5 godbidder til hvalpetr\u00e6ningen.' },\nled: { id: 238, n: 'Ortop\u00e6disk hundeseng, str. M', t: 'En fast madras aflaster leddene, n\u00e5r hunden sover.' },\npels: { id: 239, n: 'Grooming-s\u00e6t, pels \\u0026 pote', t: 'B\u00f8rst pelsen et par gange om ugen.' }\n};\nvar NEEDS = { mave: 'F\u00f8lsom mave', allergi: 'Allergi eller kl\u00f8e', pels: 'Hud og pels', led: 'Led og bev\u00e6gelse', vaegt: 'V\u00e6gtkontrol', kraesen: 'Kr\u00e6sen', ingen: 'Intet s\u00e6rligt' };\nvar LIFE = { puppy: 'Hvalp', adult: 'Voksen', senior: 'Senior' };\nvar ACT = { low: 'Rolig', normal: 'Normal', high: 'Meget aktiv' };\nvar F = { puppy: { low: 2, normal: 2, high: 2.2 }, adult: { low: 1.2, normal: 1.4, high: 1.8 }, senior: { low: 1.1, normal: 1.2, high: 1.4 } };\nvar has = K.has;\nfunction realNeeds(d) { return (d.needs || []).filter(function (n) { return n !== 'ingen'; }); }\nfunction product(id) { for (var i = 0; PRODUCTS.length > i; i++) { if (PRODUCTS[i].id === +id) return PRODUCTS[i]; } return null; }\nfunction size(kg) { return 10 > kg ? 'Lille' : (25 > kg ? 'Mellem' : (40 > kg ? 'Stor' : 'K\u00e6mpe')); }\nfunction energy(d) {\nvar f = F[d.life][d.act];\nif (d.neut) { if (d.life !== 'puppy') f = f * 0.9; }\nif (has(d.needs, 'vaegt')) f = f * 0.9;\nreturn Math.round(70 * Math.pow(d.kg, 0.75) * f);\n}\nfunction grams(kcal, dens) { return Math.max(5, Math.round(kcal \/ dens \/ 5) * 5); }\nfunction score(p, d) {\nif (d.life === 'puppy') return p.life === 'puppy' ? 20 : -1;\nif (p.life === 'puppy') return -1;\nvar s = d.life === 'senior' ? (p.life === 'senior' ? 8 : 4) : (p.life === 'senior' ? 1 : 6);\nvar needs = realNeeds(d);\nneeds.forEach(function (n) { s += p.w[n] || 0; });\nif (d.act === 'high') s += p.w.aktiv || 0;\nif (!needs.length) s += p.w.ingen || 0;\nvar b = BREEDS[d.breed];\nif (b) { (b.lean || []).forEach(function (n) { s += (p.w[n] || 0) \/ 4; }); }\nreturn s;\n}\nfunction recommend(d) {\nvar list = PRODUCTS.map(function (p) { return { p: p, s: score(p, d) }; }).filter(function (x) { return x.s > 0; });\nlist.sort(function (a, b) { return b.s - a.s; });\nvar top = list.length ? list[0].s : 1;\nvar best = Math.min(98, 90 + 2 * realNeeds(d).length + (d.life === 'adult' ? 0 : 4));\nlist.forEach(function (x, i) { x.pct = i ? Math.max(35, Math.min(best - 4, Math.round(best * x.s \/ top))) : best; });\nreturn list;\n}\nfunction why(p, d) {\nvar W = WHY[p.id] || {}, out = [], needs = realNeeds(d);\nif (d.life === 'senior') { if (W.senior) out.push(W.senior); }\nneeds.forEach(function (n) { if (W[n]) out.push(W[n]); });\nif (d.act === 'high') { if (W.aktiv) out.push(W.aktiv); }\nif (!needs.length) { if (W.ingen) out.push(W.ingen); }\nif (!out.length) out.push(W.base);\nreturn out.slice(0, 3);\n}\nfunction extra(d) {\nif (d.life === 'puppy') return EXTRA.puppy;\nvar needs = realNeeds(d);\nfor (var i = 0; needs.length > i; i++) { if (EXTRA[needs[i]]) return EXTRA[needs[i]]; }\nreturn null;\n}\nfunction options(g, bag) {\nvar out = [];\nfor (var n = 1; 7 > n; n++) {\nvar days = Math.floor(n * bag \/ g);\nif (days >= 7) { if (70 >= days) out.push({ n: n, d: days }); }\n}\nif (!out.length) out.push({ n: 1, d: Math.max(7, Math.min(70, Math.floor(bag \/ g))) });\nreturn out;\n}\nfunction pickRec(list) { for (var i = 0; list.length > i; i++) { if (list[i].d >= 14) return i; } return list.length - 1; }\nfunction recalc(p) {\nvar t = K.now(p);\nif (K.arrived(p)) p.stock = { date: K.iso(t), grams: K.stockAt(p, t) };\np.kcal = energy(p.dog);\np.g = grams(p.kcal, p.product.kcal);\nvar o = options(p.g, p.product.bag), ok = false;\no.forEach(function (x) { if (x.n === p.n) ok = true; });\nif (!ok) p.n = o[pickRec(o)].n;\np.d = Math.floor(p.n * p.product.bag \/ p.g);\nreturn K.retime(p);\n}\nvar out = {\nBREEDS: BREEDS, PRODUCTS: PRODUCTS, NEEDS: NEEDS, LIFE: LIFE, ACT: ACT,\nrealNeeds: realNeeds, product: product, size: size,\nenergy: energy, grams: grams, recommend: recommend, why: why, extra: extra,\noptions: options, pickRec: pickRec, recalc: recalc\n};\nObject.keys(K).forEach(function (k) { out[k] = K[k]; });\nreturn out;\n})(K)})(),D=(function kissDom() {\nfunction h(tag, a, kids) {\nvar el = document.createElement(tag);\nif (a) {\nObject.keys(a).forEach(function (k) {\nvar v = a[k];\nif (v === null || v === undefined || v === false) return;\nif (k === 'class') el.className = v;\nelse if (k === 'text') el.textContent = v;\nelse if (k.indexOf('on') === 0) el.addEventListener(k.slice(2), v);\nelse el.setAttribute(k, v === true ? '' : v);\n});\n}\nadd(el, kids);\nreturn el;\n}\nfunction add(el, kids) {\n(Array.isArray(kids) ? kids : [kids]).forEach(function (c) {\nif (c === null || c === undefined || c === false) return;\nel.appendChild(typeof c === 'string' || typeof c === 'number' ? document.createTextNode(String(c)) : c);\n});\nreturn el;\n}\nfunction empty(el) { while (el.firstChild) el.removeChild(el.firstChild); return el; }\nfunction decode(s) { var t = document.createElement('textarea'); t.innerHTML = String(s || ''); return t.value; }\nreturn { h: h, add: add, empty: empty, decode: decode };\n})();(function kissMyPlan(KP, D) {\nvar box = document.getElementById('kissMyPlan');\nif (!box) return;\nvar h = D.h, title = document.querySelector('.kiss-myplan-hero h1'), lead = document.querySelector('.kiss-myplan-hero .kiss-lead');\nvar confirmStop = false, msg = '';\nfunction saveRender(p, m) { KP.save(p); msg = m || ''; render(); }\nfunction btn(text, cls, fn, aria) { return h('button', { type: 'button', class: 'kiss-dash-btn' + (cls ? ' ' + cls : ''), text: text, 'aria-label': aria || null, onclick: fn }); }\nfunction card(cls, kids) { return h('section', { class: 'kiss-dash-card' + (cls ? ' ' + cls : '') }, kids); }\nfunction who(p) { return p.dog.name || (KP.BREEDS[p.dog.breed] || {}).n || 'din hund'; }\nfunction whose(p) { return p.dog.name ? KP.poss(p.dog.name) : 'Din hunds'; }\nfunction emptyState(p) {\nif (title) title.textContent = 'Min foderplan';\nvar kids = [];\nif (p) {\nif (p.status === 'pending') {\nkids = [h('p', { class: 'kiss-label', text: 'N\u00e6sten klar' }), h('h2', { text: whose(p) + ' plan venter p\u00e5 f\u00f8rste ordre' }),\nh('p', { text: 'Du har valgt ' + KP.summary(p) + '. Gennemf\u00f8r ordren i kassen, s\u00e5 starter den automatiske levering.' }),\nh('div', { class: 'kiss-dash-actions' }, [h('a', { class: 'kiss-pill', href: '\/index.php\/kasse\/', text: 'G\u00e5 til kassen \u2192' }), h('a', { class: 'kiss-dash-btn', href: '\/index.php\/foderplan\/#plan', text: 'Lav en ny plan' })])];\n} else if (p.status === 'stopped') {\nkids = [h('p', { class: 'kiss-label', text: 'Planen er stoppet' }), h('h2', { text: whose(p) + ' plan er stoppet' }),\nh('p', { text: 'Der kommer ikke flere leveringer. Du kan starte planen igen med de samme indstillinger eller lave en ny.' }),\nh('div', { class: 'kiss-dash-actions' }, [\nh('button', { type: 'button', class: 'kiss-pill', text: 'Start planen igen', onclick: function () { p.status = 'active'; KP.retime(p); saveRender(p, 'Planen k\u00f8rer igen. N\u00e6ste levering er ' + KP.fmt(KP.fromIso(p.next), true) + '.'); } }),\nh('a', { class: 'kiss-dash-btn', href: '\/index.php\/foderplan\/#plan', text: 'Lav en ny plan' })\n])];\n}\n}\nif (!kids.length) {\nkids = [h('p', { class: 'kiss-label', text: 'Ingen plan endnu' }), h('h2', { text: 'Du har ingen foderplan endnu' }),\nh('p', { text: 'Svar p\u00e5 fem korte sp\u00f8rgsm\u00e5l om din hund. S\u00e5 finder vi foderet, regner portionen ud og sender en ny pose, lige f\u00f8r den gamle er tom.' }),\nh('div', { class: 'kiss-dash-actions' }, [h('a', { class: 'kiss-pill', href: '\/index.php\/foderplan\/#plan', text: 'Lav en foderplan \u2192' })])];\n}\nD.empty(box);\nbox.className = 'kiss-dash is-empty';\nbox.appendChild(card('is-empty', kids));\n}\nfunction render() {\nvar p = KP.load();\nif (!p) { emptyState(null); return; }\nif (p.status !== 'active') { if (p.status !== 'paused') { emptyState(p); return; } }\nKP.roll(p);\nKP.save(p);\nvar t = KP.now(p), paused = p.status === 'paused', up = KP.upcoming(p, 4), nx = KP.fromIso(p.next), days = KP.between(t, nx);\nif (title) title.textContent = whose(p) + ' foderplan';\nif (lead) lead.textContent = paused ? 'Planen er sat p\u00e5 pause. Der sendes ikke noget, f\u00f8r du genoptager den.' : 'Her styrer du leveringerne. N\u00e6ste pose lander, lige f\u00f8r den gamle er tom.';\nD.empty(box);\nbox.className = 'kiss-dash' + (paused ? ' is-paused' : '');\nif (msg) box.appendChild(h('p', { class: 'kiss-dash-msg', role: 'status', text: msg }));\nvar skipNext = KP.has(p.skips, p.next);\nvar nextCard = card('is-next', [\nh('p', { class: 'kiss-label', text: paused ? 'P\u00e5 pause' : 'N\u00e6ste levering' }),\nh('h2', { text: paused ? 'Ingen leveringer lige nu' : KP.fmt(nx, true) }),\nh('p', { class: 'kiss-dash-sub', text: paused ? 'Genoptag planen, s\u00e5 regner vi en ny dato ud.' : (skipNext ? 'Denne levering er sprunget over.' : (days > 1 ? 'Om ' + days + ' dage' : (days === 1 ? 'I morgen' : 'I dag'))) }),\nh('div', { class: 'kiss-dash-prod' }, [\np.product.img ? h('img', { src: p.product.img, alt: '' }) : null,\nh('div', null, [h('b', { text: p.n + ' \u00d7 ' + p.product.n }), h('span', { text: KP.kgTxt(p.product.bag) + ' pr. pose \u00b7 ' + KP.kr(p.n * p.product.price) + (KP.ship(p.n * p.product.price) ? ' + fragt' : ' \u00b7 fri fragt') })])\n]),\npaused ? h('div', { class: 'kiss-dash-actions' }, [btn('Genoptag planen', 'is-primary', function () { p.status = 'active'; KP.retime(p); saveRender(p, 'Planen k\u00f8rer igen. N\u00e6ste levering er ' + KP.fmt(KP.fromIso(p.next), true) + '.'); })]) :\nh('div', { class: 'kiss-dash-actions' }, [\nbtn(skipNext ? 'Fortryd spring over' : 'Spring over', 'is-primary', function () { toggleSkip(p, p.next); }),\nbtn('3 dage tidligere', '', function () { move(p, -3); }),\nbtn('3 dage senere', '', function () { move(p, 3); }),\nh('a', { class: 'kiss-dash-btn', href: '\/index.php\/produkt-kategori\/godbidder\/', text: 'Tilf\u00f8j en godbid' })\n])\n]);\nvar food = KP.arrived(p) ? KP.stockAt(p, t) : 0, left = Math.floor(food \/ p.g), full = p.n * p.product.bag, pct = KP.arrived(p) ? Math.max(0, Math.min(100, Math.round(food \/ full * 100))) : 0;\nvar foodCard = card('is-food', [\nh('p', { class: 'kiss-label', text: 'Foder derhjemme' }),\nKP.arrived(p) ? h('div', { class: 'kiss-dash-big' }, [h('b', { text: String(left) }), h('span', { text: left === 1 ? 'dag tilbage' : 'dage tilbage' })]) : h('div', { class: 'kiss-dash-big' }, [h('b', { text: String(Math.max(1, KP.between(t, KP.fromIso(p.first)))) }), h('span', { text: KP.between(t, KP.fromIso(p.first)) > 1 ? 'dage til f\u00f8rste levering' : 'dag til f\u00f8rste levering' })]),\nh('div', { class: 'kiss-gauge', role: 'img', 'aria-label': 'Cirka ' + pct + ' % af leveringen er tilbage' }, [h('i', { style: 'width:' + pct + '%' })]),\nh('p', { class: 'kiss-dash-sub', text: KP.arrived(p) ? 'Ca. ' + KP.kgTxt(Math.round(food \/ 100) * 100) + ' tilbage. ' + who(p).charAt(0).toUpperCase() + who(p).slice(1) + ' spiser ' + p.g + ' g om dagen.' : 'F\u00f8rste levering ankommer ca. ' + KP.fmt(KP.fromIso(p.first), true) + '. S\u00e5 begynder vi at t\u00e6lle ned.' }),\nup.empty ? h('p', { class: 'kiss-dash-warn', text: 'Pas p\u00e5: Med de valgte spring over slipper foderet op ca. ' + KP.fmt(up.empty, true) + '.' }) : null\n]);\nvar list = h('ol', { class: 'kiss-dash-list' }, up.list.map(function (u) {\nvar d = KP.fromIso(u.date);\nreturn h('li', { class: u.skip ? 'is-skip' : null }, [\nh('span', { class: 'kiss-dash-date' }, [h('b', { text: String(d.getDate()) }), h('small', { text: d.toLocaleDateString('da-DK', { month: 'short' }) })]),\nh('span', { class: 'kiss-dash-what' }, [h('b', { text: paused ? 'P\u00e5 pause' : (u.skip ? 'Sprunget over' : p.n + ' \u00d7 ' + p.product.n) }), h('small', { text: KP.fmt(d) + (u.skip ? '' : ' \u00b7 ' + KP.kr(p.n * p.product.price)) })]),\npaused ? null : btn(u.skip ? 'Fortryd' : 'Spring over', 'is-small', function () { toggleSkip(p, u.date); }, (u.skip ? 'Fortryd spring over ' : 'Spring over ') + KP.fmt(d, true))\n]);\n}));\nvar hist = (p.history || []).slice(-3).reverse().map(function (x) {\nreturn h('li', null, [h('b', { text: KP.fmt(KP.fromIso(x.date)) }), h('span', { text: x.s === 'skip' ? 'Sprunget over' : (x.s === 'first' ? 'F\u00f8rste levering' + (p.order ? ' (ordre #' + p.order + ')' : '') : 'Leveret: ' + x.n + ' \u00d7 ' + p.product.n) })]);\n});\nvar listCard = card('is-list', [h('p', { class: 'kiss-label', text: 'Kommende leveringer' }), list, hist.length ? h('p', { class: 'kiss-label kiss-dash-hist-h', text: 'Seneste' }) : null, hist.length ? h('ul', { class: 'kiss-dash-hist' }, hist) : null]);\nvar kgIn = h('input', { type: 'number', min: '1', max: '90', step: '0.5', value: String(p.dog.kg), inputmode: 'decimal', 'aria-label': 'V\u00e6gt i kg' });\nvar bagOpts = KP.options(p.g, p.product.bag);\nvar bags = h('div', { class: 'kiss-seg kiss-dash-bags', role: 'radiogroup', 'aria-label': 'Poser pr. levering' }, bagOpts.slice(0, 4).map(function (o) {\nreturn h('label', null, [h('input', { type: 'radio', name: 'kissBags', value: o.n, checked: o.n === p.n, onchange: function () { p.n = o.n; p.d = o.d; KP.retime(p); saveRender(p, 'Nu sender vi ' + KP.summary(p) + '.'); } }), h('span', { text: o.n + (o.n === 1 ? ' pose' : ' poser') + ' \u00b7 hver ' + o.d + '. dag' })]);\n}));\nvar dogCard = card('is-dog', [\nh('p', { class: 'kiss-label', text: 'Hund og indstillinger' }),\nh('dl', { class: 'kiss-prof' }, [\nh('div', { class: 'kiss-prof-row' }, [h('dt', { text: 'Hund' }), h('dd', { text: who(p) + ' \u00b7 ' + (KP.BREEDS[p.dog.breed] || {}).n + ' \u00b7 ' + KP.LIFE[p.dog.life] })]),\nh('div', { class: 'kiss-prof-row' }, [h('dt', { text: 'Portion' }), h('dd', { text: p.g + ' g om dagen (' + KP.num(p.kcal) + ' kcal)' })]),\nh('div', { class: 'kiss-prof-row' }, [h('dt', { text: 'Levering' }), h('dd', { text: KP.summary(p) })])\n]),\nh('div', { class: 'kiss-field' }, [h('span', { text: 'V\u00e6gt i kg' }), h('div', { class: 'kiss-dash-inline' }, [kgIn, btn('Opdater portion', '', function () {\nvar v = parseFloat(String(kgIn.value || '').replace(',', '.'));\nif (!(v >= 1) || v > 90) { kgIn.setCustomValidity('Skriv en v\u00e6gt mellem 1 og 90 kg'); kgIn.reportValidity(); return; }\nkgIn.setCustomValidity('');\nvar og = p.g;\np.dog.kg = Math.round(v * 2) \/ 2;\nKP.recalc(p);\nsaveRender(p, og === p.g ? 'V\u00e6gten er gemt. Portionen er den samme.' : 'Ny portion: ' + p.g + ' g om dagen. Nu sender vi ' + KP.summary(p) + '.');\n})])]),\nh('fieldset', { class: 'kiss-field' }, [h('legend', { text: 'Poser pr. levering' }), bags]),\nh('div', { class: 'kiss-dash-actions' }, paused ? [] : [btn('S\u00e6t p\u00e5 pause', '', function () { p.status = 'paused'; saveRender(p, 'Planen er sat p\u00e5 pause.'); })].concat(\nconfirmStop ? [h('span', { class: 'kiss-dash-confirm' }, [h('span', { text: 'Stop planen helt?' }), btn('Ja, stop', 'is-danger', function () { confirmStop = false; p.status = 'stopped'; saveRender(p, ''); }), btn('Fortryd', '', function () { confirmStop = false; render(); })])] :\n[btn('Stop planen', 'is-ghost', function () { confirmStop = true; render(); })]\n)),\nh('a', { class: 'kiss-dash-link', href: '\/index.php\/foderplan\/?race=' + p.dog.breed + '#plan', text: 'Skift foder eller lav planen om \u2192' })\n]);\nbox.appendChild(h('div', { class: 'kiss-dash-col' }, [nextCard, listCard]));\nbox.appendChild(h('div', { class: 'kiss-dash-col' }, [foodCard, dogCard]));\nbox.appendChild(h('div', { class: 'kiss-dash-proto' }, [\nh('p', null, [h('b', { text: 'Prototype til skoleprojektet. ' }), h('span', { text: 'Planen gemmes kun i denne browser, og der sendes ingen rigtige pakker. I en rigtig butik ville planen ligge p\u00e5 kundens konto, og ordrerne blive oprettet automatisk.' })]),\nh('div', { class: 'kiss-dash-actions' }, [\nbtn('Spol en uge frem (demo)', 'is-small', function () { p.demo = (p.demo || 0) + 7; saveRender(p, 'Demo: Vi har spolet en uge frem til ' + KP.fmt(KP.now(p), true) + '.'); }),\np.demo ? btn('Tilbage til i dag', 'is-small', function () { p.demo = 0; saveRender(p, 'Demo: tilbage til i dag.'); }) : null\n])\n]));\n}\nfunction toggleSkip(p, date) {\nif (KP.has(p.skips, date)) { p.skips = p.skips.filter(function (x) { return x !== date; }); saveRender(p, 'Leveringen ' + KP.fmt(KP.fromIso(date), true) + ' kommer alligevel.'); }\nelse { p.skips = (p.skips || []).concat([date]); saveRender(p, 'Leveringen ' + KP.fmt(KP.fromIso(date), true) + ' er sprunget over.'); }\n}\nfunction move(p, n) {\nvar t = KP.now(p), cur = KP.fromIso(p.next), nd = KP.addDays(cur, n), min = KP.addDays(t, 1);\nif (min > nd) nd = min;\np.skips = (p.skips || []).filter(function (x) { return x !== p.next; });\np.next = KP.iso(nd);\nsaveRender(p, 'N\u00e6ste levering er flyttet til ' + KP.fmt(nd, true) + '.');\n}\nrender();\n})(KP,D);})();<\/script>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Automatisk levering Min foderplan Her styrer du leveringerne. N\u00e6ste pose lander, lige f\u00f8r den gamle er tom, og du kan springe over, flytte eller s\u00e6tte p\u00e5 pause, n\u00e5r du vil. Henter din foderplan \u2026<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"kiss-blank","meta":{"footnotes":""},"class_list":["post-512","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Min foderplan - Kiss<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/\" \/>\n<meta property=\"og:locale\" content=\"da_DK\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Min foderplan - Kiss\" \/>\n<meta property=\"og:description\" content=\"Automatisk levering Min foderplan Her styrer du leveringerne. N\u00e6ste pose lander, lige f\u00f8r den gamle er tom, og du kan springe over, flytte eller s\u00e6tte p\u00e5 pause, n\u00e5r du vil. Henter din foderplan \u2026\" \/>\n<meta property=\"og:url\" content=\"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/\" \/>\n<meta property=\"og:site_name\" content=\"Kiss\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-25T20:02:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/myfirstdomain.byrasmusfrost.com\/wp-content\/uploads\/2026\/09\/kiss-sticker-husky.webp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/index.php\\\/min-foderplan\\\/\",\"url\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/index.php\\\/min-foderplan\\\/\",\"name\":\"Min foderplan - Kiss\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/index.php\\\/min-foderplan\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/index.php\\\/min-foderplan\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/kiss-sticker-husky.webp\",\"datePublished\":\"2026-09-25T19:56:35+00:00\",\"dateModified\":\"2026-09-25T20:02:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/index.php\\\/min-foderplan\\\/#breadcrumb\"},\"inLanguage\":\"da-DK\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/index.php\\\/min-foderplan\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"da-DK\",\"@id\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/index.php\\\/min-foderplan\\\/#primaryimage\",\"url\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/kiss-sticker-husky.webp\",\"contentUrl\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/kiss-sticker-husky.webp\",\"width\":433,\"height\":600,\"caption\":\"Husky dog sticker\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/index.php\\\/min-foderplan\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Min foderplan\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/#website\",\"url\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/\",\"name\":\"Kiss\",\"description\":\"Frisk-bagt hundefoder og udstyr til fork\u00e6lede hunde\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/myfirstdomain.byrasmusfrost.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"da-DK\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Min foderplan - Kiss","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/","og_locale":"da_DK","og_type":"article","og_title":"Min foderplan - Kiss","og_description":"Automatisk levering Min foderplan Her styrer du leveringerne. N\u00e6ste pose lander, lige f\u00f8r den gamle er tom, og du kan springe over, flytte eller s\u00e6tte p\u00e5 pause, n\u00e5r du vil. Henter din foderplan \u2026","og_url":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/","og_site_name":"Kiss","article_modified_time":"2026-09-25T20:02:00+00:00","og_image":[{"url":"https:\/\/myfirstdomain.byrasmusfrost.com\/wp-content\/uploads\/2026\/09\/kiss-sticker-husky.webp","type":"","width":"","height":""}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/","url":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/","name":"Min foderplan - Kiss","isPartOf":{"@id":"https:\/\/myfirstdomain.byrasmusfrost.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/#primaryimage"},"image":{"@id":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/#primaryimage"},"thumbnailUrl":"https:\/\/myfirstdomain.byrasmusfrost.com\/wp-content\/uploads\/2026\/09\/kiss-sticker-husky.webp","datePublished":"2026-09-25T19:56:35+00:00","dateModified":"2026-09-25T20:02:00+00:00","breadcrumb":{"@id":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/#breadcrumb"},"inLanguage":"da-DK","potentialAction":[{"@type":"ReadAction","target":["https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/"]}]},{"@type":"ImageObject","inLanguage":"da-DK","@id":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/#primaryimage","url":"https:\/\/myfirstdomain.byrasmusfrost.com\/wp-content\/uploads\/2026\/09\/kiss-sticker-husky.webp","contentUrl":"https:\/\/myfirstdomain.byrasmusfrost.com\/wp-content\/uploads\/2026\/09\/kiss-sticker-husky.webp","width":433,"height":600,"caption":"Husky dog sticker"},{"@type":"BreadcrumbList","@id":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/min-foderplan\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/myfirstdomain.byrasmusfrost.com\/"},{"@type":"ListItem","position":2,"name":"Min foderplan"}]},{"@type":"WebSite","@id":"https:\/\/myfirstdomain.byrasmusfrost.com\/#website","url":"https:\/\/myfirstdomain.byrasmusfrost.com\/","name":"Kiss","description":"Frisk-bagt hundefoder og udstyr til fork\u00e6lede hunde","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/myfirstdomain.byrasmusfrost.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"da-DK"}]}},"_links":{"self":[{"href":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/wp-json\/wp\/v2\/pages\/512","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/wp-json\/wp\/v2\/comments?post=512"}],"version-history":[{"count":1,"href":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/wp-json\/wp\/v2\/pages\/512\/revisions"}],"predecessor-version":[{"id":519,"href":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/wp-json\/wp\/v2\/pages\/512\/revisions\/519"}],"wp:attachment":[{"href":"https:\/\/myfirstdomain.byrasmusfrost.com\/index.php\/wp-json\/wp\/v2\/media?parent=512"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}