',POINTER_ICON='';class NumberSnakePuzzle{constructor(t=!1){this.gridWidth=6,this.gridHeight=6,this.grid=[],this.targetRowSums=[],this.targetColSums=[],this.solutionGrid=[],this.snakeHeads=[],this.moves=0,this.moveHistory=[],this.gameWon=!1,this.selectedCell=null,this.keyboardFocusCell=null,this.invalidCells=new Set,this.highlightedCells=new Set,this.isHistoryMode=!1,this.historyEntries=[],this.currentHistoryIndex=0,this.rowDiffs=Array(this.gridHeight).fill(0),this.colDiffs=Array(this.gridWidth).fill(0),this.clickedEmptyCells=new Set,this.cellToHead=new Map,this.temporaryState=null,this.startTime=null,this.elapsedTime=0,this.timerInterval=null,this.gameCompleted=!1,this.rng=mulberry32(parseInt(getTodaySeed())),this.isFirstLoad=!1;const e=getTodaySeed(),i=this.loadProgress();this.tutorialLevelPlayed=0,this.isTutorial=!1,this.tutorialPointer=null,this.tutorialPointerDoubleClick=!1,this.isOuroborosMode=t,this.tutorialSubtitles=["tutorial1Subtitle","tutorial2Subtitle","tutorial3Subtitle","tutorial4Subtitle","tutorial5Subtitle"];const s=localStorage.getItem("pibera_tutorial_played");if(s)if(i&&i.date===e){document.getElementById("tutorial-controls").style.display="none",this.isTutorial=!1,this.grid=i.grid,this.moves=i.moves,this.elapsedTime=i.elapsedTime||0,this.snakeHeads=i.snakeHeads,this.targetRowSums=i.targetRowSums,this.targetColSums=i.targetColSums,this.gameWon=i.gameWon,this.gameCompleted=i.gameCompleted,this.generateSolution(),this.cellToHead=new Map(i.cellToHead);for(let t=0;t{this.gameCompleted||this.updateTimer()},100))}else this.isTutorial=!1,document.getElementById("tutorial-controls").style.display="none",this.init();else{this.isTutorial=!0,this.tutorialPointer={row:0,col:0},this.tutorialPointerAppearanceDelay=1500;const t=languages[currentLanguageIndex];translations[t];document.querySelector(".controls").style.display="none",document.querySelector(".stats").style.display="none",document.querySelector(".grid").style.setProperty("--grid-size","5"),document.querySelector(".puzzle-container").classList.add("tutorial-0");const e=document.getElementById("tutorial-controls");setTimeout(()=>{e.classList.add("show")},500),this.gridWidth=5,this.gridHeight=1,this.grid=Array.from({length:this.gridHeight},()=>Array(this.gridWidth).fill(null)),this.solutionGrid=Array.from({length:this.gridHeight},()=>Array(this.gridWidth).fill(null)),this.solutionGrid[0][0]=5,this.solutionGrid[0][1]=4,this.solutionGrid[0][2]=3,this.solutionGrid[0][3]=2,this.solutionGrid[0][4]=1,this.cellToHead.set("0,0",{row:0,col:0,value:5}),this.clickedEmptyCells=new Set([]),this.grid[0][0]=5,this.snakeHeads=[{row:0,col:0,value:5}],this.targetRowSums=[15],this.targetColSums=[5,4,3,2,1];for(let t=0;tArray(this.gridWidth).fill(null))}generateSolution(){this.solutionGrid=Array.from({length:this.gridHeight},()=>Array(this.gridWidth).fill(null)),this.snakeHeads=[];const t=new Set,e=3+Math.floor(2*this.rng());let i=0;for(;(this.snakeHeads.lengtht+e.value,0)}createRandomSnake(t){let e=0;for(;e++<100;){const e=Math.floor(this.rng()*this.gridHeight),i=Math.floor(this.rng()*this.gridWidth),s=`${e},${i}`;if(t.has(s))continue;const l=this.growSnake(e,i,t);if(l.length>=3){const e=Math.min(l.length,8);if(!this.checkUniqueConstraint(l,e))continue;this.snakeHeads.push({row:l[0].row,col:l[0].col,value:e});for(let i=0;ithis.solutionGrid[e].reduce((t,e)=>t+(e||0),0)),this.targetColSums=Array.from({length:this.gridWidth},(t,e)=>this.solutionGrid.reduce((t,i)=>t+(i[e]||0),0))}placeSnakeHeads(){this.cellToHead=new Map;for(const t of this.snakeHeads){this.grid[t.row][t.col]=t.value;const e=`${t.row},${t.col}`;this.cellToHead.set(e,{row:t.row,col:t.col,value:t.value})}}render(t={}){this.validateGridState(),this.renderGrid(t),this.renderSumLabels(),this.updateStats();const e=this.loadHistory();if(document.getElementById("history-btn").style.display=e?"inline-block":"none",this.keyboardFocusCell){const t=this.getCellElement(this.keyboardFocusCell.row,this.keyboardFocusCell.col);t&&t.focus()}}renderGrid(t={}){const e=document.getElementById("grid");e.setAttribute("role","grid"),e.setAttribute("aria-label","Pibera game grid");document.querySelector(".grid-wrapper");if(e.innerHTML="",this.isHistoryMode?e.classList.add("history-mode"):e.classList.remove("history-mode"),this.isTutorial&&this.tutorialPointer)if(0===this.tutorialLevelPlayed)null===this.selectedCell&&null===this.grid[0][1]?this.tutorialPointer.col=0:null===this.grid[0][1]||null===this.grid[0][2]&&1!==this.selectedCell.col?this.tutorialPointer.col=1:null===this.grid[0][2]||null===this.grid[0][3]&&2!==this.selectedCell.col?this.tutorialPointer.col=2:null===this.grid[0][3]||null===this.grid[0][4]&&3!==this.selectedCell.col?this.tutorialPointer.col=3:null===this.grid[0][4]?this.tutorialPointer.col=4:this.tutorialPointer=null;else if(2===this.tutorialLevelPlayed)this.clickedEmptyCells.size>0||1===this.grid[1][0]?this.tutorialPointer=null:0===this.clickedEmptyCells.size&&null!==this.currentEyeCell&&(this.tutorialPointerAppearanceDelay=3e3,this.tutorialPointer={row:this.currentEyeCell.row,col:this.currentEyeCell.col});else if(3===this.tutorialLevelPlayed){const t=document.querySelector(".puzzle-container").classList.contains("do-not-click");null===this.selectedCell&&null===this.grid[1][0]?this.tutorialPointer={row:0,col:0}:null===this.grid[0][1]&&t?this.tutorialPointer={row:0,col:1}:null===this.grid[1][1]&&t?this.tutorialPointer={row:1,col:1}:null===this.grid[1][0]&&t?this.tutorialPointer={row:1,col:0}:3===this.grid[0][1]?(this.tutorialPointerDoubleClick=!1,this.tutorialPointer={row:0,col:1},this.selectedCell?0===this.selectedCell.row&&1===this.selectedCell.col||(this.tutorialPointerDoubleClick=!0):(this.tutorialPointerAppearanceDelay=3e3,this.tutorialPointerDoubleClick=!0)):this.tutorialPointer=null}for(let i=0;ithis.cellClick(i,s,"mouse"));const r=this.grid[i][s],a=`${i},${s}`;let n=`Cell ${String.fromCharCode(65+s)}${i+1}. `;if(null!==r){o.textContent=r,n+=`Value ${r}. `;const t={pattern:"linear-gradient(45deg, rgba(0,0,0,0.12) 25%, transparent 25%, transparent 75%, rgba(0,0,0,0.12) 75%), linear-gradient(-45deg, rgba(0,0,0,0.12) 25%, transparent 25%, transparent 75%, rgba(0,0,0,0.12) 75%)",size:"12px 12px"};o.style.setProperty("--snake-pattern",t.pattern),o.style.backgroundSize=`${t.size}, auto`;const e=this.snakeHeads.some(t=>t.row===i&&t.col===s);if(this.isHistoryMode)e?o.classList.add("history-starting"):o.classList.add("history-filled");else if(e?o.classList.add("starting"):this.invalidCells.has(a)?(o.classList.add("invalid"),n+="Invalid. "):o.classList.add("filled"),this.selectedCell&&this.selectedCell.row===i&&this.selectedCell.col===s&&(o.classList.add("selected"),n+="Selected. "),this.selectedCell&&null!==r){const t=`${this.selectedCell.row},${this.selectedCell.col}`,e=this.cellToHead.get(a),i=this.cellToHead.get(t);e&&i&&e.row===i.row&&e.col===i.col&&(r0?o.classList.add("will-delete"):(o.style.boxShadow="0 0 10px rgba(255,235,59,.8)",o.style.border="2px solid rgba(255,235,59,.6)"))}}else{if(n+="Empty. ",o.classList.add("empty"),this.clickedEmptyCells&&this.clickedEmptyCells.has(a)&&o.classList.add("empty-clicked"),!this.isHistoryMode&&this.currentEyeCell&&this.currentEyeCell.row===i&&this.currentEyeCell.col===s){const t=document.createElement("div");t.className="snake-eye open",t.innerHTML='',t.onclick=t=>{t.stopPropagation(),this.onSnakeEyeClick(i,s)},o.appendChild(t)}if(!this.isHistoryMode&&this.highlightedCells.has(a)){o.classList.remove("empty"),o.classList.add("highlighted");const t=document.createElement("span");t.className="preview-number",t.textContent=this.selectedCell.value-1,o.appendChild(t),n+=`Highlighted, can place ${this.selectedCell.value-1}. `}}if(o.setAttribute("aria-label",n),l.appendChild(o),e.appendChild(l),this.isTutorial&&this.tutorialPointer&&this.tutorialPointer.row===i&&this.tutorialPointer.col===s){const t=document.createElement("div");t.className="tutorial-pointer",this.tutorialPointerDoubleClick?(t.classList.add("double-click-pointer"),t.innerHTML="👆x2"):t.textContent="👆",this.tutorialPointerAppearanceDelay&&(t.style.opacity="0",t.style.transition="opacity 0.5s ease-in-out",setTimeout(()=>{t.style.opacity="1"},this.tutorialPointerAppearanceDelay),this.tutorialPointerAppearanceDelay=0),l.appendChild(t)}if(t.cellsToDestroy&&t.cellsToDestroy.some(t=>t.row===i&&t.col===s)&&(o.classList.remove("will-delete"),o.classList.add("cell-destroy")),t.newCell&&t.newCell.row===i&&t.newCell.col===s){const e=t.newCell.fromRow,r=t.newCell.fromCol,a=i-e,n=s-r;let h="0",d="0";1===a&&(d="-100%"),-1===a&&(d="100%"),1===n&&(h="-100%"),-1===n&&(h="100%"),l.classList.add("clipping"),o.style.transform=`translate(${h}, ${d})`,o.classList.add("cell-slide-in"),requestAnimationFrame(()=>{requestAnimationFrame(()=>{o.style.transform="translate(0, 0)",setTimeout(()=>{o.classList.remove("cell-slide-in"),l.classList.remove("clipping")},300)})})}}}cellClick(t,e,i="mouse"){if("mouse"===i&&(this.keyboardFocusCell=null),this.gameWon||this.isHistoryMode)return;const s=this.grid[t][e],l=`${t},${e}`;if(this.highlightedCells.has(l)){const i=this.cellToHead.get(`${this.selectedCell.row},${this.selectedCell.col}`);for(const[s,l]of this.cellToHead.entries()){const[o,r]=s.split(",").map(Number);if(l.value===this.selectedCell.value-1&&l.row===i.row&&l.col===i.col)return this.deleteSequenceTailFrom(o,r),void setTimeout(()=>{this.placeNumberInSequence(t,e)},350)}return void this.placeNumberInSequence(t,e)}if(this.selectedCell&&this.selectedCell.row===t&&this.selectedCell.col===e)if(this.snakeHeads.some(i=>i.row===t&&i.col===e)){const i=this.cellToHead.get(l);for(const[l,o]of this.cellToHead.entries()){const[r,a]=l.split(",").map(Number);if(o.value===i.value-1&&o.row===i.row&&o.col===i.col)return this.deleteSequenceTailFrom(r,a),void setTimeout(()=>{this.selectCell(t,e,s)},350)}}else{this.deleteSequenceTailFrom(t,e);const i=this.cellToHead.get(l);let s=null;for(const[t,e]of this.cellToHead.entries()){const[l,o]=t.split(",").map(Number);if(e.value===i.value+1&&e.row===i.row&&e.col===i.col){s={row:l,col:o,value:e.value};break}}s?setTimeout(()=>{this.selectCell(s.row,s.col,s.value)},350):this.clearSelection()}else null!==s&&this.selectCell(t,e,s)}selectCell(t,e,i){if(!this.isHistoryMode){if(this.selectedCell={row:t,col:e,value:i},this.highlightedCells.clear(),i>1){const i=[[-1,0],[1,0],[0,-1],[0,1]];for(const[s,l]of i){const i=t+s,o=e+l;this.clickedEmptyCells.has(`${i},${o}`)||this.currentEyeCell&&this.currentEyeCell.row===i&&this.currentEyeCell.col===o||this.isValidPosition(i,o)&&null===this.grid[i][o]&&this.highlightedCells.add(`${i},${o}`)}}this.render()}}clearSelection(){this.selectedCell=null,this.keyboardFocusCell=null,this.highlightedCells.clear(),this.render()}placeNumberInSequence(t,e){if(!this.selectedCell)return;0===this.moves&&this.startTimer();const i=this.selectedCell.value-1,s=`${this.selectedCell.row},${this.selectedCell.col}`,l=`${t},${e}`;this.moveHistory.push({row:t,col:e,previousValue:null}),this.grid[t][e]=i,this.moves++;const o=this.cellToHead.get(s);this.cellToHead.set(l,{...o,value:i});const r=this.selectedCell.row,a=this.selectedCell.col;1===i?this.clearSelection():this.selectCell(t,e,i),this.render({newCell:{row:t,col:e,fromRow:r,fromCol:a}}),this.checkWin(),this.hideError(),this.saveProgress()}deleteSequenceTailFrom(t,e){const i=`${t},${e}`,s=this.cellToHead.get(i);if(!s)return;const l=[];for(const[t,e]of this.cellToHead.entries())e.value<=s.value&&e.row===s.row&&e.col===s.col&&l.push(t);this.render({cellsToDestroy:l.map(t=>{const[e,i]=t.split(",");return{row:parseInt(e),col:parseInt(i)}})}),setTimeout(()=>{const t=[];for(const e of l){const[i,s]=e.split(",").map(Number);t.push({row:i,col:s,previousValue:this.grid[i][s]}),this.grid[i][s]=null,this.cellToHead.delete(e)}this.moveHistory.push({type:"bulk_delete",deletedCells:t}),this.render(),this.hideError(),this.saveProgress()},300)}renderSumLabels(){const t=document.querySelector(".grid-wrapper");for(let e=0;ei.classList.remove("checkmark-animated"),{once:!0}),createCheckmarkParticles(i)):(i.classList.remove("bounce"),i.offsetWidth,i.classList.add("bounce")))),0!==o&&""!==r&&a!==SUCCESS_ICON&&createParticles(i,Math.abs(o),o>0?"in":"out")}for(let e=0;ei.classList.remove("checkmark-animated"),{once:!0}),createCheckmarkParticles(i)):(i.classList.remove("bounce"),i.offsetWidth,i.classList.add("bounce")))),0!==o&&""!==r&&a!==SUCCESS_ICON&&createParticles(i,Math.abs(o),o>0?"in":"out")}}getRowSum(t){return this.grid[t].reduce((t,e)=>t+(e||0),0)}getColumnSum(t){return this.grid.reduce((e,i)=>e+(i[t]||0),0)}validateGridState(){this.invalidCells.clear();const t=[];this.validateUniqueConstraint()||t.push("Numbers cannot repeat in the same row or column");const e=document.getElementById("validation-status");if(0===t.length)e.className="validation-status valid";else{const t=languages[currentLanguageIndex],i=translations[t];e.textContent=`Invalid: ${i.invalidConstraint}`,e.className="validation-status invalid"}return 0===t.length}validateUniqueConstraint(){let t=!0;for(let e=0;e${i.tutorialCompleted}`;const s={pattern:"linear-gradient(45deg, rgba(0,0,0,0.12) 25%, transparent 25%, transparent 75%, rgba(0,0,0,0.12) 75%), linear-gradient(-45deg, rgba(0,0,0,0.12) 25%, transparent 25%, transparent 75%, rgba(0,0,0,0.12) 75%)",size:"12px 12px"};t.style.setProperty("--snake-pattern",s.pattern),t.style.backgroundSize=`${s.size}, auto`,t.style.display="block";const l=document.getElementById("flash-overlay");l.classList.add("active"),setTimeout(()=>{t.classList.add("shine"),setTimeout(()=>{t.classList.remove("shine"),l.classList.remove("active")},1500)},720)}return void setTimeout(()=>{const t=document.querySelector(".puzzle-container");t.classList.add("fade-out-scale-up");const e=document.getElementById("subtitle2");if(e.classList.add("fade-out-scale-up"),5===this.tutorialLevelPlayed){document.getElementById("tutorial-controls").classList.add("fade-out-scale-up")}setTimeout(()=>{if(this.isHistoryMode=!1,this.cellToHead.clear(),this.snakeHeads=[],this.clearGrid(),this.tutorialLevelPlayed<5)this.loadTutorial(this.tutorialLevelPlayed),this.tutorialLevelPlayed>=2&&startSnakeEyeAnimation();else{document.querySelector(".grid").style.setProperty("--grid-size","6"),this.gridHeight=6,this.gridWidth=6,this.isTutorial=!1;const t=document.getElementById("subtitle");t&&(t.style.display="none"),this.updateTutorialSubtitle(),document.getElementById("tutorial-controls").style.display="none";const e=document.querySelector(".controls"),i=document.querySelector(".stats");e.style.display="",i.style.display="",e.classList.add("fade-in-down"),i.classList.add("fade-in-down"),setTimeout(()=>{e.classList.remove("fade-in-down"),i.classList.remove("fade-in-down")},500),localStorage.setItem("pibera_tutorial_played","true"),this.init(),scheduleNextEye()}t.classList.remove("fade-out-scale-up"),t.classList.add("fade-in-scale-down"),this.updateTutorialSubtitle(),e.classList.remove("fade-out-scale-up"),e.classList.add("fade-in-scale-down"),setTimeout(()=>{t.classList.remove("fade-in-scale-down"),e.classList.remove("fade-in-scale-down")},500)},1e3),setTimeout(()=>{t.classList.remove("fade-out-scale-up")},2e3)},1500)}this.gameWon=!0,this.stopTimer(),this.clickedEmptyCells.clear(),this.currentEyeCell=null,eyeVisibilityDuration=5e3,eyeHasBeenClicked=!1,hideEye();const t=document.getElementById("victory"),e=languages[currentLanguageIndex],i=translations[e];t.innerHTML=`${i.victoryMessage}
`;const s={pattern:"linear-gradient(45deg, rgba(0,0,0,0.12) 25%, transparent 25%, transparent 75%, rgba(0,0,0,0.12) 75%), linear-gradient(-45deg, rgba(0,0,0,0.12) 25%, transparent 25%, transparent 75%, rgba(0,0,0,0.12) 75%)",size:"12px 12px"};t.style.setProperty("--snake-pattern",s.pattern),t.style.backgroundSize=`${s.size}, auto`,t.style.display="block";const l=document.getElementById("flash-overlay");l.classList.add("active"),setTimeout(()=>{t.classList.add("shine"),setTimeout(()=>{t.classList.remove("shine"),l.classList.remove("active")},1500)},720),this.isOuroborosMode?setTimeout(()=>{createConfetti(),this.isHistoryMode=!0,document.querySelector(".controls").style.display="none",document.getElementById("history-controls").style.display="none",document.getElementById("current-stats").style.display="none",document.getElementById("history-stats").style.display="block";const t=(new Date).toLocaleDateString(void 0,{year:"numeric",month:"long",day:"numeric"});document.getElementById("history-date").textContent=t,document.getElementById("history-moves").textContent=this.moves,document.getElementById("history-time").textContent=this.formatTime(this.elapsedTime);for(let t=0;t{createConfetti(),this.enterHistoryMode()},250),setTimeout(()=>{t.classList.add("compress"),setTimeout(()=>{t.style.display="none",t.classList.remove("compress")},600)},4e3)}}loadTutorial(t){this.updateTutorialSubtitle(),1===t?this.loadTutorial1():2===t?this.loadTutorial2():3===t?this.loadTutorial3():4===t&&this.loadTutorial4()}loadTutorial1(){this.gridHeight=3,this.gridWidth=3,this.grid=Array.from({length:this.gridHeight},()=>Array(this.gridWidth).fill(null)),this.solutionGrid=Array.from({length:this.gridHeight},()=>Array(this.gridWidth).fill(null)),this.solutionGrid[0][0]=8,this.solutionGrid[0][1]=7,this.solutionGrid[0][2]=6,this.solutionGrid[1][2]=5,this.solutionGrid[2][2]=4,this.solutionGrid[2][1]=3,this.solutionGrid[2][0]=2,this.solutionGrid[1][0]=1,this.cellToHead.set("0,0",{row:0,col:0,value:8}),this.clickedEmptyCells=new Set(["1,1"]),this.grid[0][0]=8,this.snakeHeads=[{row:0,col:0,value:8}],this.targetRowSums=[21,6,9],this.targetColSums=[11,10,15];for(let t=0;tArray(this.gridWidth).fill(null)),this.solutionGrid=Array.from({length:this.gridHeight},()=>Array(this.gridWidth).fill(null)),this.solutionGrid[0][0]=8,this.solutionGrid[0][1]=7,this.solutionGrid[0][2]=6,this.solutionGrid[1][2]=5,this.solutionGrid[1][1]=4,this.solutionGrid[2][1]=3,this.solutionGrid[2][0]=2,this.solutionGrid[1][0]=1,this.cellToHead.set("0,0",{row:0,col:0,value:8}),this.clickedEmptyCells=new Set([]),this.grid[0][0]=8,this.snakeHeads=[{row:0,col:0,value:8}],this.targetRowSums=[21,10,5],this.targetColSums=[11,14,11];for(let t=0;tArray(this.gridWidth).fill(null)),this.solutionGrid=Array.from({length:this.gridHeight},()=>Array(this.gridWidth).fill(null)),this.solutionGrid[0][0]=4,this.solutionGrid[1][0]=3,this.solutionGrid[1][1]=2,this.solutionGrid[0][1]=1,this.cellToHead.set("0,0",{row:0,col:0,value:4}),this.clickedEmptyCells=new Set([]),this.grid[0][0]=4,this.snakeHeads=[{row:0,col:0,value:4}],this.targetRowSums=[5,5],this.targetColSums=[7,3];for(let t=0;t{this.cellClick(0,0),setTimeout(()=>{this.cellClick(0,1),setTimeout(()=>{this.cellClick(1,1),setTimeout(()=>{this.cellClick(1,0),document.querySelector(".puzzle-container").classList.remove("do-not-click")},500)},500)},500)},500)}loadTutorial4(){this.gridHeight=4,this.gridWidth=4,this.grid=Array.from({length:this.gridHeight},()=>Array(this.gridWidth).fill(null)),this.solutionGrid=Array.from({length:this.gridHeight},()=>Array(this.gridWidth).fill(null)),this.solutionGrid[1][0]=4,this.solutionGrid[1][1]=3,this.solutionGrid[2][1]=2,this.solutionGrid[3][1]=1,this.solutionGrid[2][3]=3,this.solutionGrid[1][3]=2,this.solutionGrid[1][2]=1,this.cellToHead.set("1,0",{row:1,col:0,value:4}),this.cellToHead.set("2,3",{row:2,col:3,value:3}),this.clickedEmptyCells=new Set([]),this.grid[1][0]=4,this.grid[2][3]=3,this.snakeHeads=[{row:1,col:0,value:4},{row:2,col:3,value:3}],this.targetRowSums=[0,10,5,1],this.targetColSums=[4,6,1,5];for(let t=0;ti.row===t&&i.col===e)){const i=`${t},${e}`;this.grid[t][e]=null,this.cellToHead.delete(i)}}for(const t of this.snakeHeads){const e=`${t.row},${t.col}`;this.cellToHead.set(e,{row:t.row,col:t.col,value:t.value})}this.clickedEmptyCells.clear(),this.currentEyeCell=null,eyeVisibilityDuration=5e3,eyeHasBeenClicked=!1,hideEye(),this.isTutorial||scheduleNextEye();const t=document.getElementById("grid");t&&t.querySelectorAll(".cell").forEach(t=>{t.classList.remove("animate-color-change")}),this.moves=0,this.moveHistory=[],this.gameWon=!1,this.invalidCells.clear(),this.stopTimer(),this.startTime=null,this.elapsedTime=0,this.gameCompleted=!1,document.getElementById("victory").style.display="none",this.render(),this.hideError(),document.querySelectorAll(".sum-label").forEach(t=>t.remove())}saveProgress(){if(this.isOuroborosMode)return;if(!localStorage.getItem("pibera_tutorial_played"))return;const t=getTodaySeed(),e={date:t,grid:this.grid,moves:this.moves,elapsedTime:this.elapsedTime,snakeHeads:this.snakeHeads,targetRowSums:this.targetRowSums,targetColSums:this.targetColSums,cellToHead:Array.from(this.cellToHead.entries()),gameWon:this.gameWon,gameCompleted:this.gameCompleted};if(localStorage.setItem("pibera_state",JSON.stringify(e)),this.gameWon){const e=localStorage.getItem("pibera_history"),i=e?JSON.parse(e):{};i[t]={moves:this.moves,time:this.elapsedTime},localStorage.setItem("pibera_history",JSON.stringify(i))}}loadProgress(){if(this.isOuroborosMode)return null;const t=localStorage.getItem("pibera_state");if(!t)return null;try{return JSON.parse(t)}catch(t){return console.error("Failed to parse saved state",t),null}}loadHistory(){if(this.isOuroborosMode)return this.historyEntries=[],!1;const t=localStorage.getItem("pibera_history"),e=t?JSON.parse(t):{};return this.historyEntries=Object.entries(e).map(([t,e])=>({date:t,...e})).sort((t,e)=>e.date.localeCompare(t.date)),this.historyEntries.length>0}enterHistoryMode(){if(this.isHistoryMode||(this.temporaryState={grid:this.grid.map(t=>[...t]),moves:this.moves,elapsedTime:this.elapsedTime,snakeHeads:this.snakeHeads.map(t=>({...t})),targetRowSums:[...this.targetRowSums],targetColSums:[...this.targetColSums],cellToHead:new Map(this.cellToHead),gameWon:this.gameWon,gameCompleted:this.gameCompleted,selectedCell:this.selectedCell?{...this.selectedCell}:null,highlightedCells:new Set(this.highlightedCells),invalidCells:new Set(this.invalidCells),rowDiffs:[...this.rowDiffs],colDiffs:[...this.colDiffs],isTutorial:this.isTutorial,tutorialLevelPlayed:this.tutorialLevelPlayed,solutionGrid:this.solutionGrid.map(t=>[...t])},this.timerInterval&&(clearInterval(this.timerInterval),this.timerInterval=null)),this.loadHistory()){if(this.isHistoryMode=!0,this.currentHistoryIndex=0,this.showHistoryEntry(this.historyEntries[0]),document.querySelector(".controls").style.display="none",document.getElementById("history-controls").style.display="block",document.getElementById("current-stats").style.display="none",document.getElementById("history-stats").style.display="block",this.updateHistoryNavigation(),this.gameWon){const t=languages[currentLanguageIndex],e=translations[t];document.getElementById("validation-status").innerHTML=e.newPuzzleMessage,document.getElementById("validation-status").style.display="block",document.getElementById("validation-status").className="validation-status"}else document.getElementById("validation-status").style.display="none";document.getElementById("back-btn").style.display=this.gameWon?"none":"inline-block"}else this.showError("No completed games found in history!")}exitHistoryMode(){this.isHistoryMode=!1,this.temporaryState?(this.grid=this.temporaryState.grid,this.moves=this.temporaryState.moves,this.elapsedTime=this.temporaryState.elapsedTime,this.snakeHeads=this.temporaryState.snakeHeads,this.targetRowSums=this.temporaryState.targetRowSums,this.targetColSums=this.temporaryState.targetColSums,this.cellToHead=this.temporaryState.cellToHead,this.gameWon=this.temporaryState.gameWon,this.gameCompleted=this.temporaryState.gameCompleted,this.selectedCell=this.temporaryState.selectedCell,this.highlightedCells=this.temporaryState.highlightedCells,this.invalidCells=this.temporaryState.invalidCells,this.rowDiffs=this.temporaryState.rowDiffs,this.colDiffs=this.temporaryState.colDiffs,this.isTutorial=this.temporaryState.isTutorial,this.tutorialLevelPlayed=this.temporaryState.tutorialLevelPlayed,this.solutionGrid=this.temporaryState.solutionGrid,this.gameWon||this.gameCompleted||(this.startTime=Date.now()-this.elapsedTime,this.timerInterval=setInterval(()=>{this.gameCompleted||this.updateTimer()},100)),this.temporaryState=null):(console.error("Exiting history mode without a temporary state. This should not happen."),this.createEmptyGrid(),this.moves=0,this.elapsedTime=0,this.gameWon=!1,this.gameCompleted=!1,this.selectedCell=null,this.highlightedCells.clear(),this.invalidCells.clear(),this.timerInterval&&(clearInterval(this.timerInterval),this.timerInterval=null),this.startTime=null),this.render(),document.querySelector(".controls").style.display="block",document.getElementById("history-controls").style.display="none",document.getElementById("current-stats").style.display="block",document.getElementById("history-stats").style.display="none",document.getElementById("validation-status").style.display="",document.getElementById("victory").style.display="none",document.getElementById("back-btn").style.display="inline-block"}showHistoryEntry(t){const e=this.rng;this.rng=mulberry32(parseInt(t.date)),this.generateSolution();for(let t=0;t0&&(this.currentHistoryIndex--,this.showHistoryEntry(this.historyEntries[this.currentHistoryIndex]),this.updateHistoryNavigation())}updateHistoryNavigation(){const t=document.getElementById("prev-history-btn"),e=document.getElementById("next-history-btn");this.currentHistoryIndex>=this.historyEntries.length-1?t.style.visibility="hidden":t.style.visibility="visible",this.currentHistoryIndex<=0?e.style.visibility="hidden":e.style.visibility="visible"}onSnakeEyeClick(t,e){const i=`${t},${e}`;this.clickedEmptyCells.add(i),this.startTimer(),eyeHasBeenClicked=!0,eyeLifecycleTimeout&&(clearTimeout(eyeLifecycleTimeout),eyeLifecycleTimeout=null),this.highlightedCells.has(i)&&this.highlightedCells.delete(i);const s=document.querySelector(".snake-eye");s?(s.classList.remove("open"),s.classList.add("closing"),setTimeout(()=>{hideEye()},300)):hideEye();const l=this.getCellElement(t,e);eyeVisibilityDuration=Math.max(1e3,.9*eyeVisibilityDuration),setTimeout(()=>{if(this.render(),l){const i=this.getCellElement(t,e);i&&(i.classList.add("animate-color-change"),setTimeout(()=>{i.classList.remove("animate-color-change")},600))}},300),setTimeout(()=>{(!this.isTutorial||this.tutorialLevelPlayed>1)&&scheduleNextEye()},300)}showError(t){const e=document.getElementById("error-message");e.textContent=t,e.style.display="block",setTimeout(()=>this.hideError(),3e3)}hideError(){document.getElementById("error-message").style.display="none"}isValidPosition(t,e){return t>=0&&t=0&&e{this.gameCompleted||this.updateTimer()},100))}stopTimer(){this.timerInterval&&(clearInterval(this.timerInterval),this.timerInterval=null),this.gameCompleted=!0}updateTimer(){this.startTime&&!this.gameCompleted&&(this.elapsedTime=Date.now()-this.startTime,this.updateStats())}formatTime(t){const e=Math.floor(t/1e3);return`${Math.floor(e/60)}:${(e%60).toString().padStart(2,"0")}`}isGameCompletedToday(){if(this.isOuroborosMode)return!1;const t=getTodaySeed(),e=localStorage.getItem("pibera_history");if(!e)return!1;try{return JSON.parse(e).hasOwnProperty(t)}catch(t){return console.error("Failed to parse history",t),!1}}async startTutorialAnimation(){let t=0;for(let e=0;e{s.classList.add("highlight-bounce"),setTimeout(()=>{s.classList.remove("highlight-bounce")},700)},t),t+=50)}const e=document.querySelectorAll(".controls .btn");for(let i=0;i{s.classList.add("highlight-bounce"),setTimeout(()=>{s.classList.remove("highlight-bounce")},700)},t),t+=50)}}getCellElement(t,e){const i=document.getElementById("grid").children[t*this.gridWidth+e];return i?i.querySelector(".cell"):null}updateTutorialChecklist(){if(!localStorage.getItem("pibera_tutorial_played"))if(0===this.tutorialLevelPlayed){const t=document.querySelectorAll('#tutorial-1-tasks input[type="checkbox"]'),e=this.snakeHeads;let i=e.length>0;for(const t of e){const e=`${t.row},${t.col}`;let s=!1;for(const[t,i]of this.cellToHead.entries()){const[l,o]=t.split(",").map(Number);if(`${i.row},${i.col}`===e&&1===this.grid[l][o]){s=!0;break}}if(!s){i=!1;break}}t[0].checked=i;const s=this.rowDiffs.every(t=>0===t)&&this.colDiffs.every(t=>0===t);t[1].checked=s}else{const t=document.querySelectorAll('#tutorial-2-tasks input[type="checkbox"]'),e=this.snakeHeads;let i=e.length>0;for(const t of e){const e=`${t.row},${t.col}`;let s=!1;for(const[t,i]of this.cellToHead.entries()){const[l,o]=t.split(",").map(Number);if(`${i.row},${i.col}`===e&&1===this.grid[l][o]){s=!0;break}}if(!s){i=!1;break}}t[0].checked=i;const s=this.rowDiffs.every(t=>0===t)&&this.colDiffs.every(t=>0===t);t[1].checked=s,t[2].checked=this.validateUniqueConstraint()}}}