M Memories
PAST
Capture the knowledge and lessons that brought you here
A Actions
PRESENT
Identify immediate steps needed in the right direction
P Plans
FUTURE
Define the desired destination & the path that leads you there
window.__KHM=window.__KHM||[];__KHM.push("var KH_MAP_V = '3.3';\n\nfunction khMapRoot(){ return document.getElementById('kh-map-root'); }\n\nvar KH_E = {\n out3: function(p){ return 1 - Math.pow(1 - p, 3); },\n out5: function(p){ return 1 - Math.pow(1 - p, 5); },\n inOut4: function(p){ return p < 0.5 ? 8*p*p*p*p : 1 - Math.pow(-2*p + 2, 4)/2; },\n inOutS: function(p){ return -(Math.cos(Math.PI*p) - 1)/2; },\n back: function(p){ var c1 = 1.70158, c3 = c1 + 1;\n return 1 + c3*Math.pow(p-1,3) + c1*Math.pow(p-1,2); }\n};\n\nfunction khClamp(p){ return p < 0 ? 0 : (p > 1 ? 1 : p); }\n\nfunction khStill(){\n try{if(matchMedia('(prefers-reduced-motion: reduce)').matches)return 1}catch(e){}\n try{return matchMedia('(max-width:900px)').matches}catch(e){}\n}\n\nfunction khMapLen(el){\n try { if (el.getTotalLength){ var l = el.getTotalLength(); if (l > 0) return l; } } catch(e){}\n var w = parseFloat(el.getAttribute('width')), h = parseFloat(el.getAttribute('height'));\n if (w > 0 && h > 0) return 2*(w + h);\n return 0;\n}\n\nfunction khMapBuild(r){\n var items = [];\n function add(el, kind, a, b, ease){\n if (!el) return;\n var L = 0;\n if (kind === 'd' || kind === 'dp'){\n L = khMapLen(el);\n if (L > 0){ el.style.strokeDasharray = L; } else { kind = 'f'; }\n }\n items.push({ el: el, k: kind, a: a, b: b, L: L, e: ease || KH_E.out3 });\n }\n var cols = r.querySelectorAll('.kh-map-col'), S = 200;\n for (var i = 0; i < cols.length; i++){\n var c = cols[i], t = i*S;\n\n add(c.querySelector('.kh-page-rect'), 'd', t, t + 520, KH_E.inOut4);\n add(c.querySelector('.kh-map-letter'), 'f', t + 140, t + 420);\n add(c.querySelector('.kh-map-word'), 'f', t + 200, t + 480);\n add(c.querySelector('.kh-rule'), 'f', t + 320, t + 580);\n\n var marks = c.querySelectorAll('.kh-mark > *');\n for (var m = 0; m < marks.length; m++){\n add(marks[m], 'dp', t + 460 + m*60, t + 640 + m*60, KH_E.out5);\n }\n add(c.querySelector('.kh-nib'), 'f', t + 820, t + 960);\n\n var ink = c.querySelector('.kh-ink');\n if (ink) add(ink, 'd', 1300, 2200, KH_E.inOutS);\n\n add(c.querySelector('.kh-map-node'), 'f', 1350 + i*70, 1650 + i*70);\n add(c.querySelector('.kh-map-anchor'), 'f', 1450 + i*80, 1750 + i*80);\n add(c.querySelector('.kh-map-desc'), 'f', 1600 + i*80, 1900 + i*80);\n }\n\n var end = 0;\n for (var j = 0; j < items.length; j++) if (items[j].b > end) end = items[j].b;\n r.__khItems = items;\n r.__khEnd = end;\n}\n\nfunction khMapApply(r, ms){\n var items = r.__khItems;\n if (!items) return;\n for (var i = 0; i < items.length; i++){\n var it = items[i], p = it.e(khClamp((ms - it.a)/(it.b - it.a)));\n if (it.k === 'd'){\n it.el.style.strokeDashoffset = it.L*(1 - p);\n } else if (it.k === 'dp'){\n it.el.style.strokeDashoffset = it.L*(1 - p);\n it.el.style.strokeWidth = (1.6 + 0.3*p + 0.45*Math.sin(Math.PI*p)).toFixed(2);\n } else if (it.k === 's'){\n it.el.style.opacity = khClamp(p*1.6);\n it.el.style.transform = 'scale(' + (0.7 + 0.3*p).toFixed(3) + ')';\n } else {\n it.el.style.opacity = p;\n }\n }\n}\n\nfunction bootMap(){\n var r = khMapRoot();\n if (!r || !r.querySelector('.kh-page-rect')){\n setTimeout(bootMap, 50);\n return;\n }\n if (r.className.indexOf('kh-js') < 0) r.className += ' kh-js';\n r.setAttribute('data-kh-map-v', KH_MAP_V);\n khMapBuild(r);\n khMapApply(r, khStill() ? r.__khEnd : -1);\n r.setAttribute('data-kh-map-geom', KH_MAP_V);\n requestAnimationFrame(function(){ setTimeout(function(){\n khMapCanvas();\n try {\n if (window.frameElement && window.__khMap) window.__khMap.play();\n } catch(e){}\n }, 0); });\n}\n\nfunction khMapClearSketch(){\n var r = khMapRoot();\n if (!r) return;\n var list = r.querySelectorAll('.kh-map-canvas,.kh-map-fx-canvas');\n for (var i = 0; i < list.length; i++){\n var canvas = list[i], ctx = canvas.getContext('2d');\n if (!ctx) continue;\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.restore();\n }\n}\n\nfunction khMapClearLamp(){\n var fx = khMapRoot() && khMapRoot().querySelector('.kh-map-fx-canvas');\n if (!fx) return;\n var ctx = fx.getContext('2d');\n if (ctx) ctx.clearRect(0, 0, fx.width, fx.height);\n}\n\nfunction khMapCanvas(){\n if(!window.matchMedia('(hover:hover) and (min-width:761px)').matches) return;\n var r = khMapRoot(); if(!r || r.__khSketchReady) return;\n\n if (typeof r.__khFxStop === 'function') r.__khFxStop();\n\n var oldFx = r.querySelector('.kh-map-fx-canvas');\n var oldInk = r.querySelector('.kh-map-canvas');\n var oldHint = r.querySelector('.kh-map-draw-hint');\n var oldTools = r.querySelector('.kh-map-tools');\n if (oldFx) oldFx.remove();\n if (oldInk) oldInk.remove();\n if (oldHint) oldHint.remove();\n if (oldTools) oldTools.remove();\n\n var fx = document.createElement('canvas');\n fx.className = 'kh-map-fx-canvas';\n fx.setAttribute('aria-hidden', 'true');\n\n var c = document.createElement('canvas');\n c.className = 'kh-map-canvas';\n c.setAttribute('aria-hidden', 'true');\n\n var hint = document.createElement('span');\n hint.className = 'kh-map-draw-hint';\n hint.textContent = 'Draw here';\n hint.setAttribute('aria-hidden', 'true');\n\n var tools = document.createElement('div');\n tools.className = 'kh-map-tools';\n tools.setAttribute('role', 'toolbar');\n tools.setAttribute('aria-label', 'Drawing tools');\n\n var eraseBtn = document.createElement('button');\n eraseBtn.type = 'button';\n eraseBtn.className = 'kh-map-tool kh-map-tool-erase';\n eraseBtn.setAttribute('aria-pressed', 'false');\n eraseBtn.setAttribute('aria-label', 'Eraser');\n eraseBtn.title = 'Eraser';\n\n var clearBtn = document.createElement('button');\n clearBtn.type = 'button';\n clearBtn.className = 'kh-map-tool kh-map-tool-clear';\n clearBtn.setAttribute('aria-label', 'Clear drawing');\n clearBtn.title = 'Clear drawing';\n\n tools.appendChild(eraseBtn);\n tools.appendChild(clearBtn);\n\n r.appendChild(fx);\n r.appendChild(c);\n r.appendChild(hint);\n r.appendChild(tools);\n\n var fxCtx = fx.getContext('2d');\n var ctx = c.getContext('2d');\n var cw = 0, ch = 0, fxCw = 0, fxCh = 0, FX_BLEED = 100;\n var erasing = false;\n\n function applyTool(){\n if (erasing){\n ctx.globalCompositeOperation = 'destination-out';\n ctx.strokeStyle = 'rgba(0,0,0,1)';\n ctx.lineWidth = 18;\n } else {\n ctx.globalCompositeOperation = 'source-over';\n ctx.strokeStyle = '#387DDD';\n ctx.lineWidth = 2.5;\n }\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n }\n function syncToolUi(){\n eraseBtn.setAttribute('aria-pressed', erasing ? 'true' : 'false');\n eraseBtn.className = 'kh-map-tool ' + (erasing ? 'kh-map-tool-pencil' : 'kh-map-tool-erase');\n eraseBtn.setAttribute('aria-label', erasing ? 'Pencil' : 'Eraser');\n eraseBtn.title = erasing ? 'Pencil' : 'Eraser';\n hint.textContent = erasing ? 'Erase here' : 'Draw here';\n r.setAttribute('data-kh-map-tool', erasing ? 'erase' : 'draw');\n }\n function clearInk(){\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, c.width, c.height);\n ctx.restore();\n applyTool();\n }\n function sz(){\n var w = r.clientWidth, h = r.clientHeight;\n if (w < 1 || h < 1) return false;\n var dpr = window.devicePixelRatio || 1;\n fxCw = w + FX_BLEED * 2;\n fxCh = h + FX_BLEED * 2;\n cw = w;\n ch = h;\n c.width = Math.round(w * dpr);\n c.height = Math.round(h * dpr);\n c.style.width = w + 'px';\n c.style.height = h + 'px';\n fx.width = Math.round(fxCw * dpr);\n fx.height = Math.round(fxCh * dpr);\n fx.style.width = fxCw + 'px';\n fx.style.height = fxCh + 'px';\n fx.style.left = (-FX_BLEED) + 'px';\n fx.style.top = (-FX_BLEED) + 'px';\n fxCtx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n applyTool();\n return true;\n }\n if (window.ResizeObserver){\n new ResizeObserver(function(){ sz(); }).observe(r);\n } else {\n window.addEventListener('resize', sz);\n }\n (function waitSize(n){\n if (sz() || n > 40) return;\n setTimeout(function(){ waitSize(n + 1); }, 50);\n })(0);\n\n var mx = -999, my = -999, drawing = false, lx = 0, ly = 0, fxLive = true;\n var grainTile = null, lampMx = -999, lampMy = -999, lampRaf = 0;\n\n function placeHint(x, y){\n hint.style.transform = 'translate3d(' + (x + 12) + 'px,' + (y + 5) + 'px,0)';\n }\n function showHint(on){\n hint.style.opacity = on ? '1' : '0';\n }\n\n eraseBtn.addEventListener('click', function(e){\n e.preventDefault();\n e.stopPropagation();\n erasing = !erasing;\n applyTool();\n syncToolUi();\n });\n clearBtn.addEventListener('click', function(e){\n e.preventDefault();\n e.stopPropagation();\n clearInk();\n });\n syncToolUi();\n\n r.__khFxStop = function(){\n fxLive = false;\n if (lampRaf){ cancelAnimationFrame(lampRaf); lampRaf = 0; }\n };\n r.__khClearInk = clearInk;\n\n function bakeGrain(){\n var s = 128, cx = s * 0.5, cy = s * 0.5, R = s * 0.5 - 1;\n var t = document.createElement('canvas'), tc = t.getContext('2d');\n t.width = t.height = s;\n var gx, gy, h, v, alpha, dx, dy, dist, fade;\n for (gy = 0; gy < s; gy += 3){\n for (gx = 0; gx < s; gx += 3){\n dx = gx - cx; dy = gy - cy;\n dist = Math.sqrt(dx * dx + dy * dy);\n if (dist > R) continue;\n fade = 1 - dist / R;\n fade = fade * fade * (3 - 2 * fade);\n h = ((gx * 92837111) ^ (gy * 689287499)) >>> 0;\n v = h % 97;\n if (v > 84) continue;\n alpha = (0.04 + (v % 9) * 0.008) * fade;\n tc.fillStyle = v > 26\n ? 'rgba(1,29,90,' + alpha + ')'\n : 'rgba(240,243,249,' + (alpha * 0.18) + ')';\n tc.fillRect(gx, gy, 1, 1);\n }\n }\n tc.globalCompositeOperation = 'multiply';\n for (gy = 0; gy < s; gy += 4){\n for (gx = 0; gx < s; gx += 4){\n dx = gx - cx; dy = gy - cy;\n dist = Math.sqrt(dx * dx + dy * dy);\n if (dist > R) continue;\n fade = 1 - dist / R;\n fade = fade * fade * (3 - 2 * fade);\n h = ((gx * 48271) ^ (gy * 293479)) >>> 0;\n if ((h % 100) > 74) continue;\n tc.fillStyle = 'rgba(15,45,103,' + ((0.022 + (h % 6) * 0.007) * fade) + ')';\n tc.fillRect(gx, gy, 1, 1);\n }\n }\n grainTile = t;\n }\n bakeGrain();\n\n function drawLamp(){\n if (mx < -500){\n if (lampMx > -500){ fxCtx.clearRect(0, 0, fxCw, fxCh); lampMx = lampMy = -999; }\n return;\n }\n if (mx === lampMx && my === lampMy) return;\n lampMx = mx; lampMy = my;\n fxCtx.clearRect(0, 0, fxCw, fxCh);\n var x = mx + FX_BLEED, y = my + FX_BLEED, spread = 96, rad = 58, g, gs = rad * 2;\n if (grainTile){\n fxCtx.save();\n fxCtx.beginPath();\n fxCtx.arc(x, y, rad, 0, Math.PI * 2);\n fxCtx.clip();\n fxCtx.globalCompositeOperation = 'overlay';\n fxCtx.drawImage(grainTile, x - rad, y - rad, gs, gs);\n fxCtx.globalCompositeOperation = 'multiply';\n fxCtx.drawImage(grainTile, x - rad, y - rad, gs, gs);\n fxCtx.restore();\n }\n g = fxCtx.createRadialGradient(x - 14, y - 10, 0, x, y, rad);\n g.addColorStop(0, 'rgba(180,210,245,0.42)');\n g.addColorStop(0.35, 'rgba(120,170,230,0.22)');\n g.addColorStop(0.65, 'rgba(56,125,221,0.08)');\n g.addColorStop(1, 'rgba(56,125,221,0)');\n fxCtx.globalCompositeOperation = 'source-over';\n fxCtx.fillStyle = g;\n fxCtx.fillRect(x - spread, y - spread, spread * 2, spread * 2);\n g = fxCtx.createRadialGradient(x + 16, y + 12, 0, x - 6, y, rad);\n g.addColorStop(0, 'rgba(220,230,248,0.28)');\n g.addColorStop(0.5, 'rgba(240,243,249,0.10)');\n g.addColorStop(1, 'rgba(240,243,249,0)');\n fxCtx.globalCompositeOperation = 'soft-light';\n fxCtx.fillStyle = g;\n fxCtx.fillRect(x - spread, y - spread, spread * 2, spread * 2);\n g = fxCtx.createRadialGradient(x + 22, y - 16, 0, x + 8, y - 6, rad * 0.78);\n g.addColorStop(0, 'rgba(160,200,245,0.26)');\n g.addColorStop(0.7, 'rgba(56,125,221,0.05)');\n g.addColorStop(1, 'rgba(56,125,221,0)');\n fxCtx.globalCompositeOperation = 'screen';\n fxCtx.fillStyle = g;\n fxCtx.fillRect(x - spread, y - spread, spread * 2, spread * 2);\n }\n\n function scheduleLamp(){\n if (lampRaf) return;\n lampRaf = requestAnimationFrame(function(){\n lampRaf = 0;\n if (!fxLive || !r.parentNode) return;\n if (fxCw > 0 && fxCh > 0) drawLamp();\n });\n }\n\n function pos(e){\n var b = c.getBoundingClientRect();\n return [e.clientX - b.left, e.clientY - b.top];\n }\n function startStroke(x, y){\n drawing = true;\n lx = x; ly = y;\n applyTool();\n ctx.beginPath();\n ctx.moveTo(x, y);\n }\n function extendStroke(x, y){\n var mxx = (lx + x) * 0.5, myy = (ly + y) * 0.5;\n ctx.quadraticCurveTo(lx, ly, mxx, myy);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(mxx, myy);\n lx = x; ly = y;\n }\n function endStroke(){\n if (!drawing) return;\n ctx.lineTo(lx, ly);\n ctx.stroke();\n drawing = false;\n }\n\n c.addEventListener('mousedown', function(e){\n if (e.button !== 0) return;\n e.preventDefault();\n var p = pos(e);\n mx = p[0]; my = p[1];\n showHint(false);\n scheduleLamp();\n startStroke(p[0], p[1]);\n });\n c.addEventListener('mousemove', function(e){\n var p = pos(e);\n mx = p[0]; my = p[1];\n placeHint(p[0], p[1]);\n if (!drawing) showHint(true);\n scheduleLamp();\n if (!drawing) return;\n extendStroke(p[0], p[1]);\n });\n c.addEventListener('mouseenter', function(e){\n var p = pos(e);");
window.__KHM=window.__KHM||[];__KHM.push("\n mx = p[0]; my = p[1];\n placeHint(p[0], p[1]);\n if (!drawing) showHint(true);\n scheduleLamp();\n });\n function up(){\n endStroke();\n if (mx > -500) showHint(true);\n }\n function leave(){\n mx = -999; my = -999;\n showHint(false);\n if (lampRaf){ cancelAnimationFrame(lampRaf); lampRaf = 0; }\n drawLamp();\n endStroke();\n }\n c.addEventListener('mouseup', up);\n c.addEventListener('mouseleave', leave);\n window.addEventListener('mouseup', up);\n\n r.__khSketchReady = true;\n}\n\nfunction ensureLoop(){\n if (window.__khMapLoopV === KH_MAP_V) return;\n window.__khMapLoopV = KH_MAP_V;\n\n var lastRoot = null, t0 = 0, playing = false, done = false;\n var wasIn = false, outAt = 0, lastRq = null, bootAt = 0;\n\n var loaded = document.readyState !== 'loading';\n if (document.readyState === 'loading'){\n document.addEventListener('DOMContentLoaded', function(){ loaded = true; }, { once: true });\n }\n window.addEventListener('load', function(){ loaded = true; }, { once: true });\n\n function inViewOf(r){\n try { if (window.frameElement) return true; } catch(e){}\n var b = r.getBoundingClientRect();\n if (b.width < 1 && b.height < 1) return true;\n var vh = window.innerHeight || document.documentElement.clientHeight;\n return b.top < vh*0.85 && b.bottom > vh*0.15;\n }\n function reset(r){\n playing = false; done = false;\n khMapApply(r, khStill() ? r.__khEnd : -1);\n khMapClearSketch();\n }\n function start(r, now){\n playing = true; done = false; wasIn = true;\n t0 = now;\n }\n\n function frame(){\n if (window.__khMapLoopV !== KH_MAP_V) return;\n var r = khMapRoot();\n if (r){\n if (r !== lastRoot){\n var swapped = lastRoot !== null;\n lastRoot = r;\n if (swapped){\n r.removeAttribute('data-kh-map-geom');\n r.__khSketchReady = false;\n playing = false; done = false; wasIn = false;\n khMapCanvas();\n }\n }\n if (r.getAttribute('data-kh-map-geom') !== KH_MAP_V){\n if (r.className.indexOf('kh-js') < 0) r.className += ' kh-js';\n khMapBuild(r);\n khMapApply(r, khStill() ? r.__khEnd : -1);\n r.setAttribute('data-kh-map-geom', KH_MAP_V);\n }\n\n var now = performance.now();\n if (!loaded && document.readyState !== 'loading') loaded = true;\n if (!bootAt) bootAt = now;\n\n if (khStill()){\n khMapApply(r, r.__khEnd);\n done=1;playing=0;\n } else if (loaded){\n var inView = inViewOf(r);\n\n var rq = r.getAttribute('data-kh-map-replay-req');\n if (rq && rq !== lastRq){ lastRq = rq; start(r, now); }\n if (inView && !wasIn){ wasIn = true; start(r, now); }\n else if (!playing && !done && inView) start(r, now);\n\n if (!inView && (wasIn || done)){\n if (!outAt) outAt = now;\n if (now - outAt > 400){ wasIn = false; outAt = 0; reset(r); }\n } else {\n outAt = 0;\n }\n\n if (playing){\n var ms = now - t0;\n if (ms >= r.__khEnd){\n khMapApply(r, r.__khEnd);\n playing = false; done = true;\n } else {\n khMapApply(r, ms);\n }\n } else if (!done && loaded && (now - bootAt) > 600){\n start(r, now);\n } else if (!done && loaded && (now - bootAt) > 2000){\n khMapApply(r, r.__khEnd);\n done = true;\n }\n }\n }\n requestAnimationFrame(frame);\n }\n frame();\n\n window.__khMap = {\n play: function(){ var r = khMapRoot(); if (r) start(r, performance.now()); },\n replay: function(){ var r = khMapRoot(); if (r) r.setAttribute('data-kh-map-replay-req', Date.now()); },\n reset: function(){ var r = khMapRoot(); if (r) reset(r); },\n playing: function(){ return playing; },\n done: function(){ return done; },\n frame: function(){ var r = khMapRoot(); return playing ? performance.now() - t0 : (done && r ? r.__khEnd : 0); },\n inView: function(){ var r = khMapRoot(); return r ? inViewOf(r) : false; },\n clearLamp: khMapClearLamp,\n clearInk: function(){\n var r = khMapRoot();\n if (r && typeof r.__khClearInk === 'function') r.__khClearInk();\n else khMapClearSketch();\n }\n };\n}\n\nbootMap();ensureLoop();");(function(){try{new Function(__KHM.join(''))();}catch(e){console.error('[KH MAP]',e);}})();