-
Notifications
You must be signed in to change notification settings - Fork 0
/
js.js.map
1 lines (1 loc) · 63.8 KB
/
js.js.map
1
{"version":3,"sources":["src/js.js"],"names":[],"mappings":"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","file":"js.js","sourcesContent":[";(async function () {\n /* eslint-disable no-undef */\n const GAME_VERSION = 4\n const DEBUG = false\n const log = DEBUG ? (a) => { console.log(a); return a } : (a) => a\n const PROFILE = false\n\n const documentParsed = performance.now()\n\n const scriptHTML = document.currentScript.outerHTML\n const initialHTMLWithoutThisScript = document.body.innerHTML.replace(scriptHTML, '')\n\n let boardGenerationRetryCount = 0\n\n // Mapping integers to non-negative integers and vice versa\n function fold (x) {\n return x >= 0 ? 2 * x : -2 * x - 1\n }\n\n function unfold (y) {\n return y % 2 === 0 ? y / 2 : -(y + 1) / 2\n }\n\n function pairUnsigned (x, y) {\n return 0.5 * (x + y) * (x + y + 1) + y\n }\n\n function unpairUnsigned (z) {\n const w = Math.floor((Math.sqrt(8 * z + 1) - 1) / 2)\n const t = (w * w + w) / 2\n const y = z - t\n const x = w - y\n return [x, y]\n }\n\n function pairSigned (x, y) {\n const mappedX = fold(x)\n const mappedY = fold(y)\n const cantorResult = pairUnsigned(mappedX, mappedY)\n return unfold(cantorResult)\n }\n\n function unpairSigned (z) {\n const cantorInverse = unpairUnsigned(fold(z))\n return [unfold(cantorInverse[0]), unfold(cantorInverse[1])]\n }\n log(unpairSigned(42))\n\n async function fetchBody (url) {\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`)\n }\n return await response.text()\n }\n\n async function fetchLines (url) {\n return (await fetchBody(url)).split('\\n').filter(s => !s.startsWith('#')).map(s => s.trim())\n }\n\n const wordsetNames = await fetchLines('/data/wordsets.txt')\n const wordsets = []\n\n async function loadWordset (wordsetName) {\n const wordset = await fetchLines(`/data/wordsets/${wordsetName}.txt`)\n wordsets.push(wordset)\n return wordset\n }\n\n async function loadWordsetForStage (stage) {\n const index = stage % wordsetNames.length\n const wordset = wordsets[index] ?? await loadWordset(wordsetNames[index])\n return wordset\n }\n\n const wordListFull = []\n\n const random = {\n s1: 0,\n s2: 0,\n setSeed (seed) {\n this.s1 = seed\n this.s2 = seed\n },\n random () {\n this.s1 = (this.s1 * 1103515245 + 12345) & 2147483647\n this.s2 ^= this.s2 << 13\n this.s2 ^= this.s2 >> 17\n this.s2 ^= this.s2 << 5\n log('random.random')\n return log(((this.s1 ^ this.s2) + 2147483648) / 4294967295)\n }\n }\n\n function saveGameStateWhenIdle () {\n requestIdleCallback(() => {\n saveGameState()\n })\n }\n\n function saveGameState () {\n const currentStateSaved = load('gameState')\n if (currentStateSaved) {\n save('gameState', serializeGameState())\n }\n }\n\n const eventsToSave = ['keyup', 'pointerup', 'pointercancel', 'scrollend']\n\n async function init () {\n 'use strict'\n if (window.hwgInitialized) {\n throw new Error('Game was already initialized.')\n }\n\n window.hwgInitialized = true\n\n const stageElement = document.getElementById('stage')\n\n const dirMap = [\n [3, 2, 1],\n [4, -1, 0],\n [5, 6, 7]\n ]\n\n const [nfdChoBase, nfdJungBase, nfdJongBase] = [...'각'.normalize('NFD')]\n const simpleJungBase = 'ㅏ'\n const jungDiff = simpleJungBase.charCodeAt(0) - nfdJungBase.charCodeAt(0)\n\n const simpleToCompositeJamoMap = {\n ㄱㄱ: 'ㄲ',\n ㄱㅅ: 'ㄳ',\n ㄴㅈ: 'ㄵ',\n ㄴㅎ: 'ㄶ',\n ㄷㄷ: 'ㄸ',\n ㄹㄱ: 'ㄺ',\n ㄹㅁ: 'ㄻ',\n ㄹㅂ: 'ㄼ',\n ㄹㅅ: 'ㄽ',\n ㄹㅌ: 'ㄾ',\n ㄹㅍ: 'ㄿ',\n ㄹㅎ: 'ㅀ',\n ㅂㅂ: 'ㅃ',\n ㅂㅅ: 'ㅄ',\n ㅅㅅ: 'ㅆ',\n ㅈㅈ: 'ㅉ',\n ㅏㅣ: 'ㅐ',\n ㅑㅣ: 'ㅒ',\n ㅓㅣ: 'ㅔ',\n ㅕㅣ: 'ㅖ',\n ㅗㅏ: 'ㅘ',\n ㅗㅏㅣ: 'ㅙ',\n ㅗㅣ: 'ㅚ',\n ㅜㅓ: 'ㅝ',\n ㅜㅓㅣ: 'ㅞ',\n ㅜㅣ: 'ㅟ',\n ㅡㅣ: 'ㅢ'\n }\n\n const compositeToSimpleJamoMap = Object.fromEntries(Object.entries(simpleToCompositeJamoMap).map(([simple, composite]) => [composite, simple]))\n\n let randomHueBase = -1\n let stageNumber = 1\n let previousGameState\n try {\n previousGameState = deserializeGameState(load('gameState'))\n if (previousGameState) {\n stageNumber = previousGameState.stageNumber\n stageElement.textContent = stageNumber\n }\n } catch (e) {\n console.error(e)\n clear('gameState')\n }\n\n stageElement.textContent = stageNumber\n\n wordListFull.length = 0\n wordListFull.push(...await loadWordsetForStage(stageNumber))\n\n const seed = pairSigned(stageNumber, boardGenerationRetryCount)\n\n random.setSeed(seed)\n\n const cloned = [...wordListFull]\n\n const wordCount = 16\n\n function simpleJamoBreakdown (word) {\n return [...word.normalize('NFC')].flatMap(decomposeIntoSimple)\n }\n\n const wordList = []\n for (let i = 0; i < wordCount; i++) {\n wordList.push(...cloned.splice(randomInt(0, cloned.length - 1), 1))\n }\n cloned.length = 0\n\n const wordListElement = document.getElementById('word-list')\n const wordListTemplate = document.getElementById('word-template')\n wordList.forEach(word => {\n const li = wordListTemplate.content.cloneNode(true).querySelector('li')\n li.textContent = word\n li.dataset.word = word\n wordListElement.appendChild(li)\n })\n\n const jamoBoardElement = document.getElementById('jamo-board')\n const jamoBoardTemplate = document.getElementById('jamo-template')\n\n jamoBoardElement.addEventListener('selectstart', (e) => {\n e.preventDefault()\n })\n let isRightClick = false\n jamoBoardElement.addEventListener('contextmenu', (e) => {\n if (!isRightClick) {\n e.preventDefault()\n }\n isRightClick = false\n })\n\n const width = 12\n const height = 12\n\n const simpleJamoList = 'ㄱㄴㄷㄹㅁㅂㅅㅇㅈㅊㅋㅌㅍㅎㅏㅑㅓㅕㅗㅛㅜㅠㅡㅣ'\n\n function calculateChecksum (gs) {\n return [...gs].map(c => c.charCodeAt()).reduce((acc, val) => ((acc >>> 1) | ((acc & 1) << 15)) ^ val, 0)\n }\n\n function currentState () {\n const completions = Array.from(jamoBoardElement.querySelectorAll('.completion-bar')).filter((elem) => elem !== currentJamoCompletion).map(elem => {\n return `${elem.dataset.start},${elem.dataset.end}`\n }).join()\n\n return {\n GAME_VERSION,\n width,\n height,\n completions,\n stageNumber\n }\n }\n\n function serializeGameState (gsObject = currentState()) {\n const gsJSONString = JSON.stringify(gsObject)\n return `${gsJSONString}|${calculateChecksum(gsJSONString)}`\n }\n\n function groupElements (arr, numElements) {\n return arr.reduce((acc, val) => {\n if (!acc.length || acc.at(-1).length === numElements) {\n acc.push([])\n }\n acc.at(-1).push(val)\n return acc\n }, [])\n }\n\n function deserializeGameState (gsStringFull) {\n if (gsStringFull === null) {\n return null\n }\n const [gsObjectStr, checksum] = gsStringFull.split('|')\n const expectedChecksum = calculateChecksum(gsObjectStr)\n if (expectedChecksum !== checksum * 1) {\n throw new Error('saved game state is corrupted')\n }\n const gsObject = JSON.parse(gsObjectStr)\n if (gsObject.GAME_VERSION !== GAME_VERSION) {\n throw new Error('The saved game state is from a different version of the game.')\n }\n if (gsObject.completions) {\n gsObject.completions = groupElements(gsObject.completions.split(',').map(Number), 4)\n } else {\n gsObject.completions = []\n }\n return gsObject\n }\n\n function decomposeIntoSimple (char) {\n const [nfdCho, nfdJung, nfdJong] = [...char.normalize('NFD')].concat(['', '', '']).slice(0, 3)\n const simpleCho = 'ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ'[nfdCho.charCodeAt(0) - nfdChoBase.charCodeAt(0)]\n const simpleJung = String.fromCharCode(nfdJung.charCodeAt(0) + jungDiff)\n const simpleJong = nfdJong.length ? 'ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ'[nfdJong.charCodeAt(0) - nfdJongBase.charCodeAt(0)] : ''\n return [simpleCho, simpleJung, simpleJong].flatMap(jamo => [...(compositeToSimpleJamoMap[jamo] ?? jamo)])\n }\n\n function composeIntoComposite (simpleJamo) { // @TODO: complete this function\n simpleJamo = [...simpleJamo]\n const hangulImeStateMachine = {\n cho: {\n ㄱ: ['ㄱ', 'jung'],\n ㄴㄹㅁㅇㅊㅋㅌㅍㅎ: ['jung'],\n ㄷ: ['ㄷ', 'jung'],\n ㅂ: ['ㅂ', 'jung'],\n ㅅ: ['ㅅ', 'jung'],\n ㅈ: ['ㅈ', 'jung']\n },\n jung: {\n ㅏㅑㅓㅕㅡ: ['ㅣ', 'jong'],\n ㅗ: ['ㅏ', 'ㅣ', 'jong'],\n ㅛㅠㅣ: ['jong'],\n ㅜ: ['ㅓ', 'ㅣ', 'jong']\n },\n jong: {\n ㄱ: ['ㄱ', 'ㅅ', 'cho'],\n ㄴ: ['ㅈ', 'ㅎ', 'cho'],\n ㄷㅁㅇㅈㅊㅋㅌㅍㅎ: ['cho'],\n ㄹ: ['ㄱ', 'ㅁ', 'ㅂ', 'ㅅ', 'ㅌ', 'ㅍ', 'ㅎ', 'cho'],\n ㅂ: ['ㅅ', 'cho'],\n ㅅ: ['ㅅ', 'cho']\n }\n }\n const maxLengths = Object.freeze({\n cho: 2,\n jung: 3,\n jong: 2\n })\n const currentLengths = {\n cho: 0,\n jung: 0,\n jong: 0\n }\n // 'ㅂㅂㅜㅓㅣㄹㄱ' -> [['ㅂㅂ'], ['ㅜ','ㅓ','ㅣ'], ['ㄹ', 'ㄱ']]\n let currentState = 'cho'\n const grouped = []\n const group = []\n let nextCandidate = null\n while (simpleJamo[0]) {\n const jamo = simpleJamo.shift() // 'ㅂ'\n group.push(jamo)\n currentLengths[currentState]++\n const transitionOptions = hangulImeStateMachine[currentState] // cho: { ... }\n const transition = Object.entries(transitionOptions).find(([jamoOptions, _]) => jamoOptions.includes(jamo))\n if (!transition) {\n throw new Error('cannot find suitable continuation for jamo sequence')\n }\n const [, targetStates] = transition // ['ㅂ', 'jung']\n if (targetStates.length === 1 || currentLengths[currentState] === maxLengths[currentState]) {\n currentLengths[currentState] = 0\n currentState = targetStates[0]\n grouped.push([...group])\n group.length = 0\n if (nextCandidate && !nextCandidate.includes(jamo)) {\n throw new Error('next candidate mismatch')\n }\n nextCandidate = null\n } else {\n nextCandidate = targetStates.slice(0, -1)\n }\n }\n\n return grouped\n }\n if (DEBUG) {\n window.composeIntoComposite = composeIntoComposite\n }\n\n const randomJamo = () => {\n log(randomJamo.name)\n return log(simpleJamoList[randomInt(0, simpleJamoList.length - 1)])\n }\n\n const simpleJamoFromWordList = wordList.flatMap(word => [...word.normalize('NFC')].flatMap(decomposeIntoSimple))\n const jamoFromWordList = () => {\n log(jamoFromWordList.name)\n return log(simpleJamoFromWordList[randomInt(0, simpleJamoFromWordList.length - 1)])\n }\n\n const gap = 0.75\n\n function noTransitionZone (fn, elem) {\n elem.classList.add('no-transition')\n fn()\n requestAnimationFrame(() => {\n requestAnimationFrame(() => { // 1 frame skip does not work in some cases\n elem.classList.remove('no-transition')\n })\n })\n }\n\n const fillJamoBoard = () => {\n jamoBoardElement.style.setProperty('--gap', `${gap}rem`)\n jamoBoardElement.style.setProperty('--width', width)\n jamoBoardElement.style.setProperty('--height', height)\n\n noTransitionZone(() => {\n for (let i = 0; i < width * height; i++) {\n const jamoElement = jamoBoardTemplate.content.cloneNode(true).querySelector('i')\n const jamo = randomInt(0, 1) ? randomJamo() : jamoFromWordList()\n jamoElement.dataset.jamo = jamo\n jamoBoardElement.appendChild(jamoElement)\n }\n }, jamoBoardElement)\n }\n\n fillJamoBoard()\n\n const jamoWrittenPositions = Array.from({ length: width * height }, () => null)\n\n const getPosition = (x, y, direction, progress) => {\n if (direction < 0 || direction > 7) {\n throw new RangeError('direction must be 0 to 7')\n }\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n if (dirMap[dy + 1][dx + 1] === direction) {\n return [x + dx * progress, y + dy * progress]\n }\n }\n }\n }\n\n const jamoElements = jamoBoardElement.querySelectorAll('#jamo-board>i')\n\n jamoElements.forEach((jamoElement, jamoIndex) => {\n jamoElement.dataset.index = jamoIndex\n })\n\n /**\n *\n * @param {string} word\n * @param {number} x\n * @param {number} y\n * @param {number} direction 0 to 7, starting from towards east(right) 1/8 turn CCW each step\n */\n const writeWord = (word, x, y, direction) => {\n const breakdown = simpleJamoBreakdown(word)\n // first check without writing\n if (breakdown.length > width && breakdown.length > height) {\n throw new RangeError('word too long for board')\n }\n for (let i = 0; i < breakdown.length; i++) {\n const [targetX, targetY] = getPosition(x, y, direction, i)\n if (targetX < 0 || targetX >= width || targetY < 0 || targetY >= height) {\n return false\n }\n const jamoIndex = targetY * width + targetX\n const existingJamo = jamoWrittenPositions[jamoIndex]\n if (existingJamo && existingJamo !== breakdown[i]) {\n return false\n }\n }\n\n for (let i = 0; i < breakdown.length; i++) {\n const [targetX, targetY] = getPosition(x, y, direction, i)\n const jamo = breakdown[i]\n const jamoIndex = targetY * width + targetX\n jamoWrittenPositions[jamoIndex] = jamo\n const jamoElement = jamoElements[jamoIndex]\n jamoElement.dataset.jamo = jamo\n }\n\n return true\n }\n\n const cellSize = 2\n jamoBoardElement.style.setProperty('--size', `${cellSize}rem`)\n\n function memo (key, compute) {\n const cache = memo.cache ?? (memo.cache = new Map())\n if (cache.has(key)) {\n return cache.get(key)\n }\n const result = compute()\n cache.set(key, result)\n return result\n }\n\n function createCompletionBarElement (startX, startY, endX, endY, updateElement = null) {\n const completionBarTemplate = memo(createCompletionBarElement, () => document.getElementById('completion-bar-template'))\n const completionBarElement = updateElement ?? completionBarTemplate.content.cloneNode(true).querySelector('.completion-bar')\n const padding = 0.25\n\n completionBarElement.dataset.start = `${startX},${startY}`\n completionBarElement.dataset.end = `${endX},${endY}`\n\n const sdx = Math.sign(endX - startX)\n const sdy = Math.sign(endY - startY)\n const xMin = Math.min(startX, endX)\n const xMax = Math.max(startX, endX)\n const yMin = Math.min(startY, endY)\n const yMax = Math.max(startY, endY)\n const top = yMin * cellSize + (gap * yMin)\n const left = xMin * cellSize + (gap * xMin)\n const width = (xMax - xMin + 1) * cellSize + (gap * (xMax - xMin))\n const height = (yMax - yMin + 1) * cellSize + (gap * (yMax - yMin))\n\n const hypot = Math.hypot(width, height) + padding\n const angle = Math.atan2(sdy * height, sdx * width) * 180 / Math.PI\n\n const prevAngle = completionBarElement.style.getPropertyValue('--angle').match(/(\\d+)deg/)?.[1] * 1\n\n if (isNaN(prevAngle) || prevAngle === angle) {\n completionBarElement.classList.remove('no-transition')\n } else {\n completionBarElement.classList.add('no-transition')\n }\n completionBarElement.style.setProperty('--top', `${top}rem`)\n completionBarElement.style.setProperty('--left', `${left}rem`)\n completionBarElement.style.setProperty('--width', `${width}rem`)\n completionBarElement.style.setProperty('--height', `${height}rem`)\n\n completionBarElement.style.setProperty('--thick', `${cellSize + padding}rem`)\n completionBarElement.style.setProperty('--hypot', `${hypot}rem`)\n completionBarElement.style.setProperty('--angle', `${angle}deg`)\n\n const randomHue = Math.floor(randomFromCoords(startX, startY) * colorSteps) * Math.floor(360 / colorSteps)\n completionBarElement.style.setProperty('--hue', randomHueBase + randomHue)\n\n return completionBarElement\n }\n\n let foundWords = 0\n\n const stageClearDialog = document.getElementById('stage-clear-dialog')\n const yesButton = stageClearDialog.querySelector('#next-stage')\n const noButton = stageClearDialog.querySelector('#cancel-next-stage')\n yesButton.addEventListener('click', () => {\n boardGenerationRetryCount = 0\n const currentGameState = currentState()\n save('gameState', serializeGameState({ ...currentGameState, completions: '', stageNumber: currentGameState.stageNumber + 1 }))\n reset()\n }, { passive: true })\n noButton.addEventListener('click', () => {\n stageClearDialog.close()\n }, { passive: true })\n\n function prefetchNextStageWordset () {\n loadWordsetForStage(stageNumber + 1)\n }\n\n function markWordAsFound (wordElement, completionBarElement) {\n foundWords++\n wordElement.style.setProperty('--hue', completionBarElement.style.getPropertyValue('--hue'))\n wordElement.classList.add('found')\n if (foundWords === wordCount) {\n stageClearDialog.showModal()\n prefetchNextStageWordset()\n }\n }\n\n function markCompletionAsCompleted (startX, startY, endX, endY) {\n const completionBarElement = createCompletionBarElement(startX, startY, endX, endY)\n const jamoSequence = completionToJamoSequence(startX, startY, endX, endY)\n const foundWord = findWordByJamoSequence(jamoSequence)\n const wordElement = wordListElement.querySelector(`li[data-word=\"${foundWord}\"]`)\n markWordAsFound(wordElement, completionBarElement)\n jamoBoardElement.appendChild(completionBarElement)\n }\n\n function randomInt (min, max) {\n log(randomInt.name)\n log([min, max])\n return log(Math.floor(random.random() * (max - min + 1)) + min)\n }\n\n const colorSteps = 16\n randomHueBase = randomInt(0, 359)\n\n function randomFromCoords (x, y) {\n const dot = x * 12.9898 + y * 78.233\n return (Math.sin(dot) * 43758.5453) % 1\n }\n\n const easyDirection = true\n\n const numDirections = easyDirection ? 4 : 8\n const directionsProbabilityDist = Array.from({ length: numDirections }, () => wordCount)\n let sum = wordCount * numDirections\n\n const getDirection = () => {\n const randomUniform = randomInt(0, sum - 1)\n let temp = 0\n for (let i = 0; i < numDirections; i++) {\n temp += directionsProbabilityDist[i]\n if (randomUniform < temp) {\n return i\n }\n }\n }\n\n try {\n wordList.toSorted((a, b) => {\n return simpleJamoBreakdown(b).length - simpleJamoBreakdown(a).length\n }).forEach((word) => {\n let x\n let y\n let direction\n let repeated = 0\n while (true) {\n x = randomInt(0, width - 1)\n y = randomInt(0, height - 1)\n direction = getDirection()\n const directionCorrected = easyDirection ? ((direction + 6) % 8) : direction\n const success = writeWord(word, x, y, directionCorrected)\n if (success) {\n directionsProbabilityDist[direction]--\n sum--\n if (wordCount - directionsProbabilityDist[direction] > wordCount / 3) {\n sum -= directionsProbabilityDist[direction]\n directionsProbabilityDist[direction] = 0\n }\n break\n }\n if (repeated > wordCount ** 2) {\n boardGenerationRetryCount++\n throw new Error('Failed to populate a word to the board. Try increasing the size of the board or reducing the number of words. Retrying...')\n }\n repeated++\n }\n })\n } catch (e) {\n console.error(e)\n reset()\n return\n }\n\n if (previousGameState) {\n previousGameState.completions.forEach(([startX, startY, endX, endY]) => {\n markCompletionAsCompleted(startX, startY, endX, endY)\n })\n }\n\n // add event listener for dark mode toggle\n const darkModeToggleButton = document.getElementById('dark-mode-toggle')\n\n const toggleModes = () => {\n const mode = darkModeToggleButton.dataset.mode\n const options = darkModeToggleButton.dataset.modeOptions.split('|')\n const nextMode = options[(options.indexOf(mode) + 1) % options.length]\n const startViewTransition = (change) => document.startViewTransition ? document.startViewTransition(change) : change()\n startViewTransition(() => {\n darkModeToggleButton.dataset.mode = nextMode\n document.documentElement.dataset.mode = nextMode\n })\n localStorage.darkMode = nextMode\n }\n darkModeToggleButton.addEventListener('click', toggleModes, { passive: true })\n const darkMode = localStorage.darkMode\n if (darkMode) {\n noTransitionZone(() => {\n darkModeToggleButton.dataset.mode = darkMode\n document.documentElement.dataset.mode = darkMode\n }, darkModeToggleButton)\n }\n\n const pointerdown = new Proxy({ value: false }, {\n set: (target, prop, value) => {\n if (prop === 'value' && typeof value === 'boolean') {\n if (DEBUG) {\n Array.from(jamoBoardElement.querySelectorAll('.start, .mid, .end')).forEach(elem => elem.classList.remove('start', 'mid', 'end'))\n }\n return Reflect.set(target, prop, value)\n }\n }\n })\n\n let dragStartPos = [-1, -1]\n let dragDir = -1\n let dragEndPos = [-1, -1]\n\n function isOctilinear (origin, target) {\n const [ox, oy] = origin\n const [tx, ty] = target\n const isOrthogonal = ox === tx || oy === ty\n const isDiagonal = Math.abs(ox - tx) === Math.abs(oy - ty)\n if (!(isOrthogonal || isDiagonal)) {\n return -1\n }\n const [dx, dy] = [tx - ox, ty - oy]\n return dirMap[Math.sign(dy) + 1][Math.sign(dx) + 1]\n }\n\n function getClosestOctilinearPoint (origin, target, dir) {\n const [ox, oy] = origin\n const [tx, ty] = target\n const [dx, dy] = [tx - ox, ty - oy]\n let [dxO, dyO] = [tx - ox, ty - oy]\n let [dxD, dyD] = [tx - ox, ty - oy]\n\n // orthogonal\n if (Math.abs(dxO) < Math.abs(dyO)) {\n dxO = 0\n } else {\n dyO = 0\n }\n\n // diagonal\n if ((dxD + dyD) % 2) {\n // parity mismatch adjustment\n if (Math.abs(dxD) < Math.abs(dyD)) {\n dyD -= Math.sign(dyD)\n } else {\n dxD -= Math.sign(dxD)\n }\n }\n {\n const dist = Math.abs(Math.abs(dxD) - Math.abs(dyD)) / 2\n if (Math.abs(dxD) < Math.abs(dyD)) {\n dxD += Math.sign(dxD) * dist\n dyD -= Math.sign(dyD) * dist\n } else {\n dxD -= Math.sign(dxD) * dist\n dyD += Math.sign(dyD) * dist\n }\n }\n\n const distO = Math.abs(dx - dxO) + Math.abs(dy - dyO)\n const distD = Math.abs(dx - dxD) + Math.abs(dy - dyD)\n\n if (distO === distD) {\n return dir % 2 === 0 ? [ox + dxO, oy + dyO] : [ox + dxD, oy + dyD]\n } else if (distO < distD) {\n return [ox + dxO, oy + dyO]\n } else {\n return [ox + dxD, oy + dyD]\n }\n }\n\n let currentJamoCompletion = null\n\n function updateJamoCompletion () {\n if (!(dragStartPos[0] !== -1 && dragStartPos[1] !== -1)) {\n return\n }\n const exists = currentJamoCompletion !== null\n const [sx, sy] = dragStartPos\n const [ex, ey] = dragEndPos[0] === -1 && dragEndPos[1] === -1 ? [sx, sy] : dragEndPos\n currentJamoCompletion = createCompletionBarElement(sx, sy, ex, ey, currentJamoCompletion)\n if (!exists) {\n jamoBoardElement.appendChild(currentJamoCompletion)\n }\n }\n\n function createRange (start, end) {\n const inc = start < end ? 1 : -1\n const result = []\n for (let i = 0; i <= Math.abs(end - start); i++) {\n result.push(i * inc + start)\n }\n return result\n }\n\n function completionToJamoSequence (startX, startY, endX, endY) {\n const rangeX = createRange(startX, endX)\n const rangeY = createRange(startY, endY)\n const longer = Math.max(rangeX.length, rangeY.length)\n const coords = Array.from({ length: longer }, (_, i) => [rangeX[i] ?? startX, rangeY[i] ?? startY])\n return coords.map(([x, y]) => jamoElements[y * width + x].dataset.jamo).join('')\n }\n\n function findWordByJamoSequence (jamoSequence) {\n return wordList.find(word => {\n const [simple, reversed] = memo(word, () => {\n const simple = simpleJamoBreakdown(word)\n return [simple.join(''), simple.toReversed().join('')]\n })\n return simple === jamoSequence || reversed === jamoSequence\n })\n }\n\n /**\n *\n * @param {HTMLElement} jamoCompletionElement\n */\n function removeJamoCompletion (jamoCompletionElement) {\n jamoCompletionElement.animate({\n opacity: 0\n }, {\n duration: 150,\n easing: 'ease-out'\n }).finished.then(() => {\n jamoCompletionElement.remove()\n })\n }\n\n function checkJamoCompletion (jamoCompletionElement) {\n try {\n if (jamoCompletionElement === null) {\n return\n }\n const [startX, startY] = jamoCompletionElement.dataset.start.split(',').map(Number)\n const [endX, endY] = jamoCompletionElement.dataset.end.split(',').map(Number)\n if (startX === endX && startY === endY) {\n removeJamoCompletion(jamoCompletionElement)\n return\n }\n const dir = isOctilinear([startX, startY], [endX, endY])\n if (dir === -1) {\n removeJamoCompletion(jamoCompletionElement)\n return\n }\n const jamoSequence = completionToJamoSequence(startX, startY, endX, endY)\n const foundWord = findWordByJamoSequence(jamoSequence)\n if (foundWord) {\n const wordElement = wordListElement.querySelector(`li[data-word=\"${foundWord}\"]`)\n if (wordElement) {\n if (wordElement.classList.contains('found')) {\n removeJamoCompletion(jamoCompletionElement)\n } else {\n markWordAsFound(wordElement, jamoCompletionElement)\n }\n }\n } else {\n removeJamoCompletion(jamoCompletionElement)\n }\n } finally {\n currentJamoCompletion = null\n }\n }\n\n jamoBoardElement.addEventListener('pointerdown', (e) => {\n if (!e.target.matches('#jamo-board>i')) {\n return\n }\n pointerdown.value = true\n dragStartPos = calculateCellPosFromCoords(e.clientX, e.clientY)\n if (dragStartPos[0] < 0 || dragStartPos[0] >= width || dragStartPos[1] < 0 || dragStartPos[1] >= height) {\n dragStartPos = [-1, -1]\n return\n }\n dragEndPos = [-1, -1]\n dragDir = -1\n updateJamoCompletion()\n }, { passive: true })\n\n document.addEventListener('pointerup', (e) => {\n isRightClick = e.button === 2\n pointerdown.value = false\n if (dragStartPos[0] === dragEndPos[0] && dragStartPos[1] === dragEndPos[1]) {\n currentJamoCompletion?.remove()\n currentJamoCompletion = null\n } else if (dragEndPos[0] !== -1 && dragEndPos[1] !== -1) {\n checkJamoCompletion(currentJamoCompletion)\n }\n }, { passive: true })\n\n function calculateOvershoot (value, min, max) {\n if (value < min) {\n return min - value\n }\n if (value > max) {\n return value - max\n }\n return 0\n }\n\n function calculateCellSize () {\n const firstElement = jamoElements[0]\n const rightElement = jamoElements[1]\n const bottomElement = jamoElements[width]\n const firstRect = firstElement.getBoundingClientRect()\n const rightRect = rightElement.getBoundingClientRect()\n const bottomRect = bottomElement.getBoundingClientRect()\n const cellInteractiveWidth = rightRect.left - firstRect.left\n const cellInteractiveHeight = bottomRect.top - firstRect.top\n const left = firstRect.left\n const top = firstRect.top\n const gapX = rightRect.left - firstRect.right\n const gapY = bottomRect.top - firstRect.bottom\n return [left, top, cellInteractiveWidth, cellInteractiveHeight, gapX, gapY]\n }\n\n function calculateCellPosFromCoords (clientX, clientY) {\n const [left, top, cellWidth, cellHeight, gapX, gapY] = calculateCellSize()\n const boardLeft = left - gapX / 2\n const boardTop = top - gapY / 2\n const [relativeX, relativeY] = [clientX - boardLeft, clientY - boardTop]\n const [cellX, cellY] = [Math.floor(relativeX / cellWidth), Math.floor(relativeY / cellHeight)]\n return [cellX, cellY]\n }\n\n function clamp (value, min, max) {\n return Math.min(max, Math.max(min, value))\n }\n\n document.addEventListener('pointermove', (e) => {\n if (!pointerdown.value) {\n return\n }\n e.preventDefault()\n const pos = calculateCellPosFromCoords(e.clientX, e.clientY)\n pos[0] = clamp(pos[0], 0, width - 1)\n pos[1] = clamp(pos[1], 0, height - 1)\n if (dragStartPos[0] === pos[0] && dragStartPos[1] === pos[1]) {\n return\n }\n const dir = isOctilinear(dragStartPos, pos)\n if (dir !== -1) {\n dragEndPos = pos\n dragDir = dir\n } else if (dragEndPos[0] !== -1 && dragEndPos[1] !== -1) {\n dragEndPos = getClosestOctilinearPoint(dragStartPos, pos, dragDir)\n }\n if (!(dragEndPos[0] !== -1 && dragEndPos[1] !== -1)) {\n return\n }\n let [cx, cy] = dragEndPos\n if (cx < 0 || cx >= width || cy < 0 || cy >= height) {\n const correctedDragDir = isOctilinear(dragStartPos, [cx, cy])\n const overshootX = calculateOvershoot(cx, 0, width - 1)\n const overshootY = calculateOvershoot(cy, 0, height - 1)\n const maxOvershoot = Math.max(overshootX, overshootY);\n [cx, cy] = getPosition(cx, cy, correctedDragDir, -maxOvershoot)\n }\n dragEndPos = [cx, cy]\n\n const closestIndex = dragEndPos[1] * width + dragEndPos[0]\n const closestElement = jamoElements[closestIndex]\n if (DEBUG) {\n jamoBoardElement.querySelector('.end')?.classList.remove('end')\n closestElement.classList.add('end')\n }\n updateJamoCompletion()\n })\n\n if (!previousGameState) {\n save('gameState', serializeGameState())\n }\n\n window.serializeGameState = serializeGameState\n\n const mainElement = document.querySelector('main')\n\n const resizeToFit = () => {\n const screenWidth = screen.availWidth\n const screenHeight = screen.availHeight\n\n mainElement.style.transform = 'scale(1)'\n mainElement.style.margin = '0'\n\n const { width, height } = mainElement.getBoundingClientRect()\n\n const zoomFactor = Math.min(1, screenWidth / width, screenHeight / height)\n\n mainElement.style.transform = `scale(${zoomFactor})`\n mainElement.style.margin = `${(height * (zoomFactor - 1)) / 2}px ${(width * (zoomFactor - 1)) / 2}px`\n }\n resizeToFit()\n window.addEventListener('resize', resizeToFit, { passive: true })\n\n eventsToSave.forEach(event => {\n document.addEventListener(event, saveGameStateWhenIdle, { passive: true })\n })\n\n function saveHistoryState () {\n if (history.state) {\n save('historyState', history.state)\n }\n }\n\n window.addEventListener('beforeunload', () => {\n saveGameState()\n saveHistoryState()\n }, { passive: true })\n\n function u2b (str) {\n const encoder = new TextEncoder()\n const encodedData = encoder.encode(str)\n const binaryString = String.fromCharCode(...encodedData)\n return btoa(binaryString)\n }\n\n function b2u (base64) {\n const binaryString = atob(base64)\n const encodedData = new Uint8Array(binaryString.split('').map(char => char.charCodeAt(0)))\n const decoder = new TextDecoder()\n return decoder.decode(encodedData)\n }\n\n const settingsPanel = document.getElementById('settings-panel')\n const exportText = document.getElementById('export-game-state-plaintext')\n\n document.getElementById('show-settings-panel').addEventListener('click', () => {\n settingsPanel.showModal()\n })\n\n document.getElementById('settings-panel').addEventListener('open', () => {\n saveGameState()\n exportText.value = u2b(load('gameState'))\n })\n\n const successReportButtons = document.querySelectorAll('button[data-success-report]')\n successReportButtons.forEach(button => {\n button.addEventListener('click', () => {\n if (!button.successReport) {\n const successReport = document.getElementById('success-report-template').content.cloneNode(true).querySelector('input')\n successReport.setCustomValidity(button.dataset.successReport)\n button.appendChild(successReport)\n button.successReport = successReport\n }\n button.successReport.reportValidity()\n })\n })\n\n document.getElementById('copy-game-state-plaintext').addEventListener('click', () => {\n navigator.clipboard.writeText(exportText.value)\n })\n\n document.getElementById('download-game-state-plaintext').addEventListener('click', () => {\n const a = document.createElement('a')\n const blob = new Blob([exportText.value], { type: 'text/plain' })\n a.href = URL.createObjectURL(blob)\n a.download = `save-${new Date().toISOString().replace(/\\D/g, '')}.hwgsave`\n a.hidden = true\n document.body.appendChild(a)\n a.click()\n a.remove()\n URL.revokeObjectURL(a.href)\n })\n\n const importText = document.getElementById('import-game-state-plaintext')\n\n const fileWrapperLabel = document.getElementById('file-wrapper')\n\n function reportError (message) {\n importText.setCustomValidity(message)\n importText.reportValidity()\n }\n\n document.getElementById('select-game-state-file').addEventListener('input', (e) => {\n const file = e.target.files[0]\n fileWrapperLabel.dataset.filename = file.name\n const reader = new FileReader()\n reader.onload = (e) => {\n const result = e.target.result\n try {\n const gameStateText = b2u(result)\n deserializeGameState(gameStateText)\n } catch (err) {\n console.error('Failed to parse game state from file', err)\n reportError('선택한 파일의 구문 분석에 실패했습니다.')\n }\n importText.value = result\n }\n reader.readAsText(file)\n })\n\n document.getElementById('apply-imported-game-state').addEventListener('click', () => {\n try {\n const gameStateText = b2u(importText.value)\n deserializeGameState(gameStateText)\n save('gameState', gameStateText)\n reset()\n } catch (err) {\n console.error('Failed to parse game state from text', err)\n reportError('올바른 형식의 게임 상태 텍스트가 아닙니다.')\n }\n })\n\n const dialogOpenEvent = new CustomEvent('open')\n\n const dialogOpenObserver = new MutationObserver((mutations) => {\n mutations.forEach(({ target, type, attributeName }) => {\n if (type === 'attributes' && attributeName === 'open' && target.open) {\n target.dispatchEvent(dialogOpenEvent)\n }\n })\n })\n\n document.querySelectorAll('dialog').forEach(dialog => {\n const { id } = dialog\n dialogOpenObserver.observe(dialog, {\n attributes: true,\n attributeFilter: ['open'],\n subtree: false\n })\n dialog.addEventListener(\n 'click',\n (event) => {\n const rect = dialog.getBoundingClientRect()\n if (!dialog.open) {\n return\n }\n if (rect.left > event.clientX ||\n rect.right < event.clientX ||\n rect.top > event.clientY ||\n rect.bottom < event.clientY\n ) {\n // show bump animation\n dialog.classList.remove('bump')\n requestAnimationFrame(() => {\n dialog.classList.add('bump')\n })\n }\n }\n )\n dialog.addEventListener('open', () => {\n if (location.hash !== `#${id}`) {\n const url = `#${id}`\n history.pushState({ open: id, url }, '', url)\n }\n })\n\n dialog.addEventListener('close', () => {\n dialog.classList.remove('bump')\n\n const url = new URL(location)\n url.hash = ''\n history.pushState({ open: null, url: url.toString() }, '', url)\n })\n })\n\n const minimumPressDuration = 2000\n\n let timeout = null\n\n const clearButton = document.getElementById('clear-game-state')\n clearButton.addEventListener('contextmenu', (e) => {\n e.preventDefault()\n })\n clearButton.addEventListener('pointerdown', () => {\n timeout = setTimeout(() => {\n clear('gameState')\n location.reload()\n }, minimumPressDuration)\n })\n clearButton.addEventListener('pointerup', () => {\n clearTimeout(timeout)\n })\n clearButton.addEventListener('pointerleave', () => {\n clearTimeout(timeout)\n })\n\n // fix dialog forms with sandboxed document\n const dialogCloseButtons = document.querySelectorAll('form[method=dialog]>button[type=submit]')\n dialogCloseButtons.forEach(button => {\n button.addEventListener('click', (e) => {\n e.preventDefault()\n button.closest('dialog')?.close?.()\n })\n })\n\n // @TODO: show relevant image for each word after finding it\n // requestIdleCallback(() => {\n // // preload images\n // const imageElements = wordList.map(word => {\n // const img = document.createElement('img')\n // img.src = `/images/wordsets/0/${word}.webp`\n // return img\n // })\n // imageElements.forEach(img => img.decode().then(() => {\n // console.log('decoded', img.src)\n // }).catch(() => {\n // console.log('failed to decode', img.src)\n // }))\n // })\n\n const gameInitialized = performance.now()\n\n if (PROFILE) {\n requestIdleCallback(() => {\n const settled = performance.now()\n\n const t1 = documentParsed - begin\n const t2 = jsParsed - documentParsed\n const t3 = gameInitialized - jsParsed\n const t4 = settled - gameInitialized\n const t5 = settled - begin\n\n const perfHistory = load('perfHistory', [])\n perfHistory.push([t1, t2, t3, t4, t5])\n save('perfHistory', perfHistory)\n })\n }\n\n // load saved history state\n const historyState = load('historyState')\n if (historyState?.url) {\n history.replaceState(historyState, '', historyState.url)\n }\n\n handleHashChange(location.hash.slice(1))\n }\n\n function reset () {\n const children = [...document.body.children].filter(elem => elem !== document.currentScript)\n children.forEach(child => child.remove())\n document.body.innerHTML = initialHTMLWithoutThisScript\n window.hwgInitialized = false\n\n eventsToSave.forEach(event => {\n document.removeEventListener(event, saveGameStateWhenIdle)\n })\n\n init()\n }\n\n function load (key, fallback) {\n const data = localStorage[key]\n if (typeof data === 'string') {\n return JSON.parse(data)\n }\n return fallback ?? null\n }\n\n function clear (key) {\n delete localStorage[key]\n }\n\n function save (key, value) {\n localStorage[key] = JSON.stringify(value)\n }\n\n function average (arr) {\n return arr.reduce((acc, val) => acc + val, 0) / arr.length\n }\n if (DEBUG) {\n window.average = average\n }\n\n function median (arr) {\n const sorted = arr.slice().sort((a, b) => a - b)\n const mid = Math.floor(sorted.length / 2)\n if (sorted.length % 2 === 0) {\n return (sorted[mid - 1] + sorted[mid]) / 2\n }\n return sorted[mid]\n }\n if (DEBUG) {\n window.median = median\n }\n\n function getCurrentFunctionName () {\n const currentStackRaw = new Error().stack\n const callerLine = currentStackRaw.split('\\n').slice(1)[1]\n return callerLine.match(/at (\\w+)/)[1]\n }\n if (DEBUG) {\n window.getCurrentFunctionName = getCurrentFunctionName\n }\n\n const jsParsed = performance.now()\n\n init()\n\n function handleHashChange (hash) {\n if (hash) {\n document.getElementById(hash)?.show?.()\n } else {\n document.querySelector('dialog[open]')?.close?.()\n }\n }\n\n // add event listener to window.location\n window.addEventListener('popstate', (e) => {\n handleHashChange(e.state.open)\n })\n\n function registerKonamiCodeHandler () {\n const [u, d, l, r] = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight']\n const konamiCode = [u, u, d, d, l, r, l, r, 'b', 'a', 'Enter']\n let konamiCodeIndex = 0\n const handler = async (e) => {\n if (e.key === konamiCode[konamiCodeIndex]) {\n konamiCodeIndex++\n if (konamiCodeIndex === konamiCode.length) {\n showCrazyShit()\n window.removeEventListener('keydown', handler)\n }\n } else {\n konamiCodeIndex = 0\n }\n }\n window.addEventListener('keydown', handler, { passive: true })\n }\n if (DEBUG) {\n registerKonamiCodeHandler()\n }\n\n function showCrazyShit () {\n console.log('showing lunatic text')\n }\n})()\n"]}