astar-visualizer 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/astar-visualizer.js +734 -626
- package/dist/astar-visualizer.umd.cjs +5 -5
- package/dist/style.css +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(C,
|
|
1
|
+
(function(C,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],n):(C=typeof globalThis<"u"?globalThis:C||self,n(C.AStarVisualizer={},C["react/jsx-runtime"],C.React))})(this,function(C,n,M){"use strict";const Fe="",je="",G=e=>{let t;const a=new Set,o=(p,d)=>{const h=typeof p=="function"?p(t):p;if(!Object.is(h,t)){const f=t;t=d??(typeof h!="object"||h===null)?h:Object.assign({},t,h),a.forEach(g=>g(t,f))}},s=()=>t,v={setState:o,getState:s,getInitialState:()=>c,subscribe:p=>(a.add(p),()=>a.delete(p)),destroy:()=>{a.clear()}},c=t=e(o,s,v);return v},ae=e=>e?G(e):G;function re(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var k={exports:{}},z={},V={exports:{}},W={};/**
|
|
2
2
|
* @license React
|
|
3
3
|
* use-sync-external-store-shim.production.js
|
|
4
4
|
*
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* This source code is licensed under the MIT license found in the
|
|
8
8
|
* LICENSE file in the root directory of this source tree.
|
|
9
|
-
*/var
|
|
9
|
+
*/var H;function ne(){if(H)return W;H=1;var e=M;function t(d,h){return d===h&&(d!==0||1/d===1/h)||d!==d&&h!==h}var a=typeof Object.is=="function"?Object.is:t,o=e.useState,s=e.useEffect,r=e.useLayoutEffect,i=e.useDebugValue;function m(d,h){var f=h(),g=o({inst:{value:f,getSnapshot:h}}),u=g[0].inst,N=g[1];return r(function(){u.value=f,u.getSnapshot=h,v(u)&&N({inst:u})},[d,f,h]),s(function(){return v(u)&&N({inst:u}),d(function(){v(u)&&N({inst:u})})},[d]),i(f),f}function v(d){var h=d.getSnapshot;d=d.value;try{var f=h();return!a(d,f)}catch{return!0}}function c(d,h){return h()}var p=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?c:m;return W.useSyncExternalStore=e.useSyncExternalStore!==void 0?e.useSyncExternalStore:p,W}var I={};/**
|
|
10
10
|
* @license React
|
|
11
11
|
* use-sync-external-store-shim.development.js
|
|
12
12
|
*
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*
|
|
15
15
|
* This source code is licensed under the MIT license found in the
|
|
16
16
|
* LICENSE file in the root directory of this source tree.
|
|
17
|
-
*/var
|
|
17
|
+
*/var K;function oe(){return K||(K=1,process.env.NODE_ENV!=="production"&&function(){function e(f,g){return f===g&&(f!==0||1/f===1/g)||f!==f&&g!==g}function t(f,g){p||s.startTransition===void 0||(p=!0,console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var u=g();if(!d){var N=g();r(u,N)||(console.error("The result of getSnapshot should be cached to avoid an infinite loop"),d=!0)}N=i({inst:{value:u,getSnapshot:g}});var S=N[0].inst,y=N[1];return v(function(){S.value=u,S.getSnapshot=g,a(S)&&y({inst:S})},[f,u,g]),m(function(){return a(S)&&y({inst:S}),f(function(){a(S)&&y({inst:S})})},[f]),c(u),u}function a(f){var g=f.getSnapshot;f=f.value;try{var u=g();return!r(f,u)}catch{return!0}}function o(f,g){return g()}typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var s=M,r=typeof Object.is=="function"?Object.is:e,i=s.useState,m=s.useEffect,v=s.useLayoutEffect,c=s.useDebugValue,p=!1,d=!1,h=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?o:t;I.useSyncExternalStore=s.useSyncExternalStore!==void 0?s.useSyncExternalStore:h,typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),I}var U;function J(){return U||(U=1,process.env.NODE_ENV==="production"?V.exports=ne():V.exports=oe()),V.exports}/**
|
|
18
18
|
* @license React
|
|
19
19
|
* use-sync-external-store-shim/with-selector.production.js
|
|
20
20
|
*
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*
|
|
23
23
|
* This source code is licensed under the MIT license found in the
|
|
24
24
|
* LICENSE file in the root directory of this source tree.
|
|
25
|
-
*/var
|
|
25
|
+
*/var Y;function le(){if(Y)return z;Y=1;var e=M,t=J();function a(c,p){return c===p&&(c!==0||1/c===1/p)||c!==c&&p!==p}var o=typeof Object.is=="function"?Object.is:a,s=t.useSyncExternalStore,r=e.useRef,i=e.useEffect,m=e.useMemo,v=e.useDebugValue;return z.useSyncExternalStoreWithSelector=function(c,p,d,h,f){var g=r(null);if(g.current===null){var u={hasValue:!1,value:null};g.current=u}else u=g.current;g=m(function(){function S(w){if(!y){if(y=!0,b=w,w=h(w),f!==void 0&&u.hasValue){var _=u.value;if(f(_,w))return O=_}return O=w}if(_=O,o(b,w))return _;var L=h(w);return f!==void 0&&f(_,L)?(b=w,_):(b=w,O=L)}var y=!1,b,O,E=d===void 0?null:d;return[function(){return S(p())},E===null?void 0:function(){return S(E())}]},[p,d,h,f]);var N=s(c,g[0],g[1]);return i(function(){u.hasValue=!0,u.value=N},[N]),v(N),N},z}var B={};/**
|
|
26
26
|
* @license React
|
|
27
27
|
* use-sync-external-store-shim/with-selector.development.js
|
|
28
28
|
*
|
|
@@ -30,4 +30,4 @@
|
|
|
30
30
|
*
|
|
31
31
|
* This source code is licensed under the MIT license found in the
|
|
32
32
|
* LICENSE file in the root directory of this source tree.
|
|
33
|
-
*/var Y;function ce(){return Y||(Y=1,process.env.NODE_ENV!=="production"&&function(){function e(c,f){return c===f&&(c!==0||1/c===1/f)||c!==c&&f!==f}typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var t=L,o=J(),n=typeof Object.is=="function"?Object.is:e,s=o.useSyncExternalStore,r=t.useRef,l=t.useEffect,v=t.useMemo,w=t.useDebugValue;j.useSyncExternalStoreWithSelector=function(c,f,u,d,h){var m=r(null);if(m.current===null){var p={hasValue:!1,value:null};m.current=p}else p=m.current;m=v(function(){function E(_){if(!y){if(y=!0,b=_,_=d(_),h!==void 0&&p.hasValue){var M=p.value;if(h(M,_))return N=M}return N=_}if(M=N,n(b,_))return M;var D=d(_);return h!==void 0&&h(M,D)?(b=_,M):(b=_,N=D)}var y=!1,b,N,A=u===void 0?null:u;return[function(){return E(f())},A===null?void 0:function(){return E(A())}]},[f,u,d,h]);var S=s(c,m[0],m[1]);return l(function(){p.hasValue=!0,p.value=S},[S]),w(S),S},typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),j}process.env.NODE_ENV==="production"?P.exports=le():P.exports=ce();var ie=P.exports;const ue=se(ie),{useDebugValue:de}=L,{useSyncExternalStoreWithSelector:fe}=ue;let je=!1;const he=e=>e;function me(e,t=he,o){const n=fe(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,o);return de(n),n}const Q=e=>{const t=typeof e=="function"?re(e):e,o=(n,s)=>me(t,n,s);return Object.assign(o,t),o},pe=e=>e?Q(e):Q;var a=(e=>(e[e.Empty=0]="Empty",e[e.Start=1]="Start",e[e.End=2]="End",e[e.Obstacle=3]="Obstacle",e[e.Visited=4]="Visited",e[e.Path=5]="Path",e[e.Water=6]="Water",e[e.Forest=7]="Forest",e[e.Mountain=8]="Mountain",e))(a||{}),z=(e=>(e.Classic="classic",e.Medieval="medieval",e))(z||{});const x=(e,t)=>{const o=Math.abs(e.row-t.row),n=Math.abs(e.col-t.col);return Math.floor(10*Math.sqrt(o*o+n*n))},ve=(e,t)=>({row:e.row,col:e.col,g:0,h:x(e,t),f:x(e,t),parent:null}),we=(e,t,o)=>{const n=[{row:e.row-1,col:e.col},{row:e.row+1,col:e.col},{row:e.row,col:e.col-1},{row:e.row,col:e.col+1}];o&&n.push({row:e.row-1,col:e.col-1},{row:e.row-1,col:e.col+1},{row:e.row+1,col:e.col-1},{row:e.row+1,col:e.col+1});const s=[a.Obstacle,a.Water,a.Mountain];return n.filter(r=>r.row>=0&&r.row<t.length&&r.col>=0&&r.col<t[0].length&&!s.includes(t[r.row][r.col].state)).map(r=>({row:r.row,col:r.col,state:t[r.row][r.col].state}))},be=(e,t,o)=>{const n=Math.abs(e.row-t.row),s=Math.abs(e.col-t.col),r=e.g+(n===0||s===0?10:14),l=x(t,o),v=r+l;return{g:r,h:l,f:v}},ge=e=>{const t=[];let o=e;for(;o;)t.push(o),o=o.parent;return t.reverse()},Ee=(e,t,o,n)=>{const s=[],r=[],l=ve(t,o);for(s.push(l);s.length>0;){s.sort((c,f)=>c.f-f.f);const v=s.shift();if(v.row===o.row&&v.col===o.col)return r.push(v),{path:ge(v),visitedNodes:r};r.push(v);const w=we(v,e,n);for(const c of w){if(r.some(m=>m.row===c.row&&m.col===c.col))continue;const{g:f,h:u,f:d}=be(v,c,o),h=s.find(m=>m.row===c.row&&m.col===c.col);if(!h||f<h.g){const m={row:c.row,col:c.col,g:f,h:u,f:d,parent:v};h?(h.g=f,h.f=d,h.parent=v):s.push(m)}}}return{path:[],visitedNodes:r}},Se=e=>({cells:Array.from({length:8},(t,o)=>Array.from({length:12},(n,s)=>({row:o,col:s,state:a.Empty}))),rows:8,columns:12,startTile:null,endTile:null,obstacleTiles:[],path:[],visitedNodes:[],setNumberOfColumns:t=>{e(o=>{const n=o.cells.map(s=>t>o.columns?[...s,...Array.from({length:t-o.columns},(r,l)=>({row:s[0].row,col:o.columns+l,state:a.Empty}))]:s.slice(0,t));return{...o,columns:t,cells:n}})},setNumberOfRows:t=>{e(o=>{let n=[...o.cells];return t>o.rows?n=[...n,...Array.from({length:t-o.rows},(s,r)=>Array.from({length:o.columns},(l,v)=>({row:o.rows+r,col:v,state:a.Empty})))]:n=n.slice(0,t),{...o,rows:t,cells:n}})},setCellState:(t,o,n)=>{e(s=>{const r=s.cells.map(c=>c.map(f=>({...f})));let l=s.startTile,v=s.endTile,w=[...s.obstacleTiles];switch(n===a.Start&&s.startTile&&(r[s.startTile.row][s.startTile.col].state=a.Empty,l=null),n===a.End&&s.endTile&&(r[s.endTile.row][s.endTile.col].state=a.Empty,v=null),r[t][o].state=n,n){case a.Start:l={row:t,col:o};break;case a.End:v={row:t,col:o};break;case a.Obstacle:w.some(c=>c.row===t&&c.col===o)||w.push({row:t,col:o});break;case a.Empty:w=w.filter(c=>!(c.row===t&&c.col===o));break}return{...s,cells:r,startTile:l,endTile:v,obstacleTiles:w}})},resetCells:()=>{e(t=>({...t,cells:t.cells.map(o=>o.map(n=>({...n,state:a.Empty}))),startTile:null,endTile:null,obstacleTiles:[],path:[],visitedNodes:[]}))},handleFindPath:t=>{e(o=>{const n=o.cells.flat().find(r=>r.state===a.Start),s=o.cells.flat().find(r=>r.state===a.End);if(n&&s){const r=o.cells.map(c=>c.map(f=>({row:f.row,col:f.col,state:f.state}))),{path:l,visitedNodes:v}=Ee(r,n,s,t);return(async(c,f)=>{for(let u of f)await new Promise(d=>setTimeout(d,100)),e(d=>{const h=d.cells.map(m=>m.map(p=>({...p,state:u.row===p.row&&u.col===p.col&&p.state===a.Empty?a.Visited:p.state})));return{...d,cells:h,visitedNodes:[...d.visitedNodes,u]}});for(let u of c)await new Promise(d=>setTimeout(d,250)),e(d=>{const h=d.cells.map(m=>m.map(p=>({...p,state:u.row===p.row&&u.col===p.col?a.Path:p.state})));return{...d,cells:h,path:[...d.path,u]}})})(l,v),{...o,path:[],visitedNodes:[]}}return o})},setPath:t=>{e(o=>{const n=o.cells.map(s=>s.map(r=>({...r,state:t.some(l=>l.row===r.row&&l.col===r.col)?a.Path:r.state})));return{...o,cells:n}})},setVisitedNodes:t=>{e(o=>{const n=o.cells.map(s=>s.map(r=>({...r,state:t.some(l=>l.row===r.row&&l.col===r.col)&&r.state===a.Empty?a.Visited:r.state})));return{...o,cells:n}})}}),_e=e=>({activeButton:a.Start,setSelectedButtonState:t=>e({activeButton:t}),canTravelDiagonally:!0,setCanTravelDiagonally:t=>e({canTravelDiagonally:t})}),ye=e=>({visualTheme:z.Medieval,showCosts:!1,setVisualTheme:t=>e({visualTheme:t}),setShowCosts:t=>e({showCosts:t})}),F=pe((e,t,o)=>({...Se(e),..._e(e),...ye(e)})),Oe={id:z.Classic,name:"Classic",startIcon:"●",endIcon:"●",terrains:{[a.Obstacle]:{name:"Wall",icon:"■",passable:!1}},presets:[{id:"random",name:"Random",icon:"🎲"},{id:"maze",name:"Maze",icon:"🔲"}]},Ne={id:z.Medieval,name:"Medieval",startIcon:"⚔️",endIcon:"🏰",terrains:{[a.Obstacle]:{name:"Wall",icon:"🧱",passable:!1},[a.Water]:{name:"Water",icon:"🌊",passable:!1},[a.Forest]:{name:"Forest",icon:"🌲",passable:!0},[a.Mountain]:{name:"Mountain",icon:"⛰️",passable:!1}},presets:[{id:"river",name:"River Crossing",icon:"🌊"},{id:"mountains",name:"Mountain Range",icon:"⛰️"},{id:"maze",name:"Castle Maze",icon:"🏰"},{id:"random",name:"Random Forest",icon:"🎲"}]},X={[z.Classic]:Oe,[z.Medieval]:Ne},G=e=>X[e],Me=e=>{const t=G(e);return Object.entries(t.terrains).map(([o,n])=>({state:Number(o),config:n}))},xe="",Te=()=>{var S;const{cells:e,activeButton:t,setCellState:o,setSelectedButtonState:n,visitedNodes:s,path:r,visualTheme:l,showCosts:v}=F(),w=G(l),[c,f]=L.useState({width:0,height:0}),u=L.useRef(null);L.useEffect(()=>{const E=()=>{if(u.current){const y=u.current.getBoundingClientRect();f({width:y.width,height:y.height})}};return E(),window.addEventListener("resize",E),()=>window.removeEventListener("resize",E)},[]);const d=(E,y)=>{switch(o(E,y,t),t){case a.Start:n(a.End);break;case a.End:n(a.Obstacle);break}},h=(E,y)=>{const b=s.find(N=>N.row===E&&N.col===y);return b?{g:b.g,h:b.h,f:b.f}:{g:null,h:null,f:null}},p=(()=>{var O;if(!c.width||!c.height)return 20;const E=((O=e[0])==null?void 0:O.length)||1,y=e.length||1,b=20,N=E+y,A=c.width-b-N,_=c.height-b-N,M=A/E,D=_/y,g=Math.min(M,D);return Math.max(15,Math.min(g,60))})();return i.jsx("div",{className:"grid-wrapper",ref:u,children:i.jsx("div",{className:"grid-container",style:{display:"grid",gridTemplateColumns:`repeat(${((S=e[0])==null?void 0:S.length)||1}, ${p}px)`,gridTemplateRows:`repeat(${e.length||1}, ${p}px)`,gap:"1px",padding:"8px",background:"var(--bg-secondary)",borderRadius:"8px",boxShadow:"0 2px 8px rgba(0, 0, 0, 0.1)",border:"1px solid var(--border-color)"},children:e.map((E,y)=>E.map((b,N)=>{var V,$,ee,te;const A=r.some(T=>T.row===b.row&&T.col===b.col),_=s.some(T=>T.row===b.row&&T.col===b.col),{g:M,h:D,f:g}=h(b.row,b.col);let O=Ce(b,_);if(A){const T=r.findIndex(oe=>oe.row===b.row&&oe.col===b.col);T===0?O="var(--cell-start)":T===r.length-1?O="var(--cell-end)":O="var(--cell-path)"}return i.jsxs("div",{className:"grid-cell",onClick:()=>d(y,N),style:{width:p,height:p,backgroundColor:O,border:"1px solid var(--cell-border)",cursor:"pointer",transition:"all 0.15s ease",position:"relative",display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"2px"},onMouseEnter:T=>{b.state===a.Empty&&(T.currentTarget.style.backgroundColor="var(--bg-tertiary)",T.currentTarget.style.transform="scale(1.02)")},onMouseLeave:T=>{b.state===a.Empty&&(T.currentTarget.style.backgroundColor=O,T.currentTarget.style.transform="scale(1)")},children:[_&&v&&i.jsxs("div",{className:"cell-values",children:[i.jsxs("div",{className:"value-h",children:["h",D]}),i.jsxs("div",{className:"value-f",children:["f",g]}),i.jsxs("div",{className:"value-g",children:["g",M]})]}),b.state===a.Start&&i.jsx("div",{className:"cell-indicator start",children:w.startIcon}),b.state===a.End&&i.jsx("div",{className:"cell-indicator end",children:w.endIcon}),b.state===a.Obstacle&&i.jsx("div",{className:"cell-indicator obstacle",children:((V=w.terrains[a.Obstacle])==null?void 0:V.icon)||"■"}),b.state===a.Water&&i.jsx("div",{className:"cell-indicator water",children:(($=w.terrains[a.Water])==null?void 0:$.icon)||"🌊"}),b.state===a.Forest&&i.jsx("div",{className:"cell-indicator forest",children:((ee=w.terrains[a.Forest])==null?void 0:ee.icon)||"🌲"}),b.state===a.Mountain&&i.jsx("div",{className:"cell-indicator mountain",children:((te=w.terrains[a.Mountain])==null?void 0:te.icon)||"⛰️"})]},`${y}-${N}`)}))})})},Ce=(e,t)=>{if(t)return e.state===a.Start?"var(--cell-start)":e.state===a.End?"var(--cell-end)":"var(--cell-visited)";switch(e.state){case a.Start:return"var(--cell-start)";case a.End:return"var(--cell-end)";case a.Obstacle:return"var(--cell-obstacle)";case a.Water:return"var(--cell-water)";case a.Forest:return"var(--cell-forest)";case a.Mountain:return"var(--cell-mountain)";case a.Empty:return"var(--cell-empty)";default:return"var(--cell-empty)"}},Le=(e,t)=>{const o=[],n=Math.floor(e/2),s=Math.max(2,Math.floor(t/6)),r=[];for(let l=0;l<s;l++){const v=Math.floor(t/(s+1)*(l+1));r.push(v)}for(let l=0;l<t;l++)r.includes(l)||(o.push({row:n,col:l,state:a.Water}),n+1<e&&o.push({row:n+1,col:l,state:a.Water}));for(let l=0;l<t;l+=3)n-1>=0&&Math.random()>.5&&o.push({row:n-1,col:l,state:a.Forest}),n+2<e&&Math.random()>.5&&o.push({row:n+2,col:l,state:a.Forest});return o},Ae=(e,t)=>{const o=[],n=Math.floor(e*.2),s=Math.floor(t*.1),r=Math.floor(e*.8),l=Math.floor(t*.9),v=Math.max(2,Math.floor(Math.min(e,t)/5)),w=[];for(let c=0;c<v;c++)w.push(Math.floor((l-s)/(v+1)*(c+1))+s);for(let c=s;c<=l;c++){const f=(c-s)/(l-s),u=Math.floor(n+(r-n)*f);w.some(d=>Math.abs(c-d)<=1)||(u>=0&&u<e&&o.push({row:u,col:c,state:a.Mountain}),u+1<e&&Math.random()>.3&&o.push({row:u+1,col:c,state:a.Mountain}),u-1>=0&&Math.random()>.3&&o.push({row:u-1,col:c,state:a.Mountain}))}for(const c of[...o])if(c.state===a.Mountain){const f=[{row:c.row-2,col:c.col},{row:c.row+2,col:c.col},{row:c.row,col:c.col-2},{row:c.row,col:c.col+2}];for(const u of f)u.row>=0&&u.row<e&&u.col>=0&&u.col<t&&Math.random()>.7&&(o.some(d=>d.row===u.row&&d.col===u.col)||o.push({row:u.row,col:u.col,state:a.Forest}))}return o},De=(e,t)=>{const o=[];for(let s=0;s<e;s++)for(let r=0;r<t;r++){const l=s%3===1,v=r%3===1;(l||v)&&Math.random()>.35&&o.push({row:s,col:r,state:a.Obstacle})}const n=2;return o.filter(s=>{const r=s.row<n&&s.col<n,l=s.row>=e-n&&s.col>=t-n;return!r&&!l})},ze=(e,t,o=.25)=>{const n=[];for(let s=0;s<e;s++)for(let r=0;r<t;r++)if(!(s<2&&r<2||s>=e-2&&r>=t-2)&&Math.random()<o){const v=Math.random();let w;v<.4?w=a.Forest:v<.6?w=a.Obstacle:v<.8?w=a.Water:w=a.Mountain,n.push({row:s,col:r,state:w})}return n},Ve=(e,t,o=.2)=>{const n=[];for(let s=0;s<e;s++)for(let r=0;r<t;r++)!(s<2&&r<2||s>=e-2&&r>=t-2)&&Math.random()<o&&n.push({row:s,col:r,state:a.Obstacle});return n},ke=(e,t)=>{const o=[];for(let s=0;s<e;s++)for(let r=0;r<t;r++){const l=s%3===1,v=r%3===1;(l||v)&&Math.random()>.35&&o.push({row:s,col:r,state:a.Obstacle})}const n=2;return o.filter(s=>{const r=s.row<n&&s.col<n,l=s.row>=e-n&&s.col>=t-n;return!r&&!l})},Fe="",Pe=({isDarkMode:e,setIsDarkMode:t})=>{const{activeButton:o,setSelectedButtonState:n,resetCells:s,rows:r,columns:l,setNumberOfRows:v,setNumberOfColumns:w,handleFindPath:c,canTravelDiagonally:f,setCanTravelDiagonally:u,visualTheme:d,setVisualTheme:h,showCosts:m,setShowCosts:p,setCellState:S}=F(),E=G(d),y=Me(d),b=()=>{t(!e)},N=[{label:"Start",state:a.Start},{label:"End",state:a.End},{label:"Obstacle",state:a.Obstacle},{label:"Clear",state:a.Empty},{label:"Reset",state:null}],A=g=>{g===null?_():n(g)},_=()=>{s(),n(a.Start)},M=()=>{c(f)},D=g=>{s();let O;if(d===z.Medieval)switch(g){case"river":O=Le(r,l);break;case"mountains":O=Ae(r,l);break;case"maze":O=De(r,l);break;case"random":O=ze(r,l);break;default:return}else switch(g){case"random":O=Ve(r,l);break;case"maze":O=ke(r,l);break;default:return}for(const V of O)S(V.row,V.col,V.state);S(0,0,a.Start),S(r-1,l-1,a.End),n(a.Obstacle)};return i.jsx("div",{className:"control-panel",children:i.jsxs("div",{className:"control-grid",children:[i.jsxs("div",{className:"control-group theme-section",children:[i.jsx("h3",{className:"group-title",children:"Theme"}),i.jsxs("div",{className:"button-group",children:[i.jsx("select",{className:"theme-select",value:d,onChange:g=>h(g.target.value),children:Object.values(X).map(g=>i.jsx("option",{value:g.id,children:g.name},g.id))}),i.jsx("button",{className:`control-button theme-toggle ${e?"active":""}`,onClick:b,title:e?"Switch to light mode":"Switch to dark mode",children:e?"☀️ Light":"🌙 Dark"}),i.jsx("button",{className:`control-button show-costs ${m?"active":""}`,onClick:()=>p(!m),title:m?"Hide costs":"Show costs",children:m?"📊 Costs On":"📊 Costs Off"})]})]}),i.jsxs("div",{className:"control-group tools",children:[i.jsx("h3",{className:"group-title",children:"Tools"}),i.jsx("div",{className:"button-group",children:N.map((g,O)=>i.jsx("button",{className:`control-button ${g.label.toLowerCase()} ${o===g.state?"active":""}`,onClick:()=>A(g.state),children:g.label},O))})]}),d===z.Medieval&&i.jsxs("div",{className:"control-group terrain",children:[i.jsx("h3",{className:"group-title",children:"Terrain"}),i.jsx("div",{className:"button-group",children:y.filter(({state:g})=>g!==a.Obstacle).map(({state:g,config:O})=>i.jsxs("button",{className:`control-button terrain-btn ${O.name.toLowerCase()} ${o===g?"active":""}`,onClick:()=>n(g),title:O.passable?"Passable terrain":"Impassable terrain",children:[O.icon," ",O.name]},g))})]}),i.jsxs("div",{className:"control-group presets",children:[i.jsx("h3",{className:"group-title",children:"Generate Map"}),i.jsx("div",{className:"button-group",children:E.presets.map(g=>i.jsxs("button",{className:"control-button preset-btn",onClick:()=>D(g.id),children:[g.icon," ",g.name]},g.id))})]}),i.jsxs("div",{className:"control-group actions",children:[i.jsx("h3",{className:"group-title",children:"Actions"}),i.jsxs("div",{className:"button-group",children:[i.jsx("button",{className:"control-button find-path",onClick:M,children:"Find Path"}),i.jsx("button",{className:`control-button diagonal ${f?"active":""}`,onClick:()=>u(!f),children:f?"Diagonal On":"Diagonal Off"})]})]}),i.jsxs("div",{className:"control-group size",children:[i.jsx("h3",{className:"group-title",children:"Grid Size"}),i.jsxs("div",{className:"size-controls",children:[i.jsxs("div",{className:"size-control",children:[i.jsx("label",{className:"size-label",children:"Rows"}),i.jsxs("div",{className:"size-buttons",children:[i.jsx("button",{className:"size-button",onClick:()=>v(Math.max(5,r-1)),disabled:r<=5,children:"−"}),i.jsx("span",{className:"size-value",children:r}),i.jsx("button",{className:"size-button",onClick:()=>v(Math.min(50,r+1)),disabled:r>=50,children:"+"})]})]}),i.jsxs("div",{className:"size-control",children:[i.jsx("label",{className:"size-label",children:"Columns"}),i.jsxs("div",{className:"size-buttons",children:[i.jsx("button",{className:"size-button",onClick:()=>w(Math.max(5,l-1)),disabled:l<=5,children:"−"}),i.jsx("span",{className:"size-value",children:l}),i.jsx("button",{className:"size-button",onClick:()=>w(Math.min(50,l+1)),disabled:l>=50,children:"+"})]})]})]})]})]})})},Z=({defaultDarkMode:e})=>{const t=L.useRef(null),{visualTheme:o}=F(),[n,s]=L.useState(()=>{if(e!==void 0)return e;const r=localStorage.getItem("astar-darkMode");return r?JSON.parse(r):!1});return L.useEffect(()=>{e===void 0&&localStorage.setItem("astar-darkMode",JSON.stringify(n)),t.current&&(t.current.setAttribute("data-theme",n?"dark":"light"),t.current.setAttribute("data-visual-theme",o))},[n,e,o]),i.jsx("div",{ref:t,className:"astar-visualizer-root","data-theme":n?"dark":"light","data-visual-theme":o,children:i.jsxs("div",{className:"app-container",children:[i.jsx("header",{className:"app-header",children:i.jsx("h1",{className:"app-title",children:"A* Pathfinding"})}),i.jsx("main",{className:"app-main",children:i.jsx(Te,{})}),i.jsx("footer",{className:"app-footer",children:i.jsx(Pe,{isDarkMode:n,setIsDarkMode:s})})]})})};function We({defaultDarkMode:e}){return i.jsx(Z,{defaultDarkMode:e})}C.AStarVisualizer=We,C.CellState=a,C.Layout=Z,C.VisualTheme=z,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})});
|
|
33
|
+
*/var q;function ce(){return q||(q=1,process.env.NODE_ENV!=="production"&&function(){function e(c,p){return c===p&&(c!==0||1/c===1/p)||c!==c&&p!==p}typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var t=M,a=J(),o=typeof Object.is=="function"?Object.is:e,s=a.useSyncExternalStore,r=t.useRef,i=t.useEffect,m=t.useMemo,v=t.useDebugValue;B.useSyncExternalStoreWithSelector=function(c,p,d,h,f){var g=r(null);if(g.current===null){var u={hasValue:!1,value:null};g.current=u}else u=g.current;g=m(function(){function S(w){if(!y){if(y=!0,b=w,w=h(w),f!==void 0&&u.hasValue){var _=u.value;if(f(_,w))return O=_}return O=w}if(_=O,o(b,w))return _;var L=h(w);return f!==void 0&&f(_,L)?(b=w,_):(b=w,O=L)}var y=!1,b,O,E=d===void 0?null:d;return[function(){return S(p())},E===null?void 0:function(){return S(E())}]},[p,d,h,f]);var N=s(c,g[0],g[1]);return i(function(){u.hasValue=!0,u.value=N},[N]),v(N),N},typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),B}process.env.NODE_ENV==="production"?k.exports=le():k.exports=ce();var ie=k.exports;const de=re(ie),{useDebugValue:ue}=M,{useSyncExternalStoreWithSelector:he}=de;let Ge=!1;const fe=e=>e;function pe(e,t=fe,a){const o=he(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,a);return ue(o),o}const Q=e=>{const t=typeof e=="function"?ae(e):e,a=(o,s)=>pe(t,o,s);return Object.assign(a,t),a},me=e=>e?Q(e):Q;var l=(e=>(e[e.Empty=0]="Empty",e[e.Start=1]="Start",e[e.End=2]="End",e[e.Obstacle=3]="Obstacle",e[e.Visited=4]="Visited",e[e.Path=5]="Path",e[e.Water=6]="Water",e[e.Forest=7]="Forest",e[e.Mountain=8]="Mountain",e))(l||{}),A=(e=>(e.Classic="classic",e.Medieval="medieval",e))(A||{});const x=(e,t)=>{const a=Math.abs(e.row-t.row),o=Math.abs(e.col-t.col);return Math.floor(10*Math.sqrt(a*a+o*o))},ve=(e,t)=>({row:e.row,col:e.col,g:0,h:x(e,t),f:x(e,t),parent:null}),ge=(e,t,a)=>{const o=[{row:e.row-1,col:e.col},{row:e.row+1,col:e.col},{row:e.row,col:e.col-1},{row:e.row,col:e.col+1}];a&&o.push({row:e.row-1,col:e.col-1},{row:e.row-1,col:e.col+1},{row:e.row+1,col:e.col-1},{row:e.row+1,col:e.col+1});const s=[l.Obstacle,l.Water,l.Mountain];return o.filter(r=>r.row>=0&&r.row<t.length&&r.col>=0&&r.col<t[0].length&&!s.includes(t[r.row][r.col].state)).map(r=>({row:r.row,col:r.col,state:t[r.row][r.col].state}))},be=(e,t,a)=>{const o=Math.abs(e.row-t.row),s=Math.abs(e.col-t.col),r=e.g+(o===0||s===0?10:14),i=x(t,a),m=r+i;return{g:r,h:i,f:m}},we=e=>{const t=[];let a=e;for(;a;)t.push(a),a=a.parent;return t.reverse()},Se=(e,t,a,o)=>{const s=[],r=[],i=ve(t,a);for(s.push(i);s.length>0;){s.sort((c,p)=>c.f-p.f);const m=s.shift();if(m.row===a.row&&m.col===a.col)return r.push(m),{path:we(m),visitedNodes:r};r.push(m);const v=ge(m,e,o);for(const c of v){if(r.some(g=>g.row===c.row&&g.col===c.col))continue;const{g:p,h:d,f:h}=be(m,c,a),f=s.find(g=>g.row===c.row&&g.col===c.col);if(!f||p<f.g){const g={row:c.row,col:c.col,g:p,h:d,f:h,parent:m};f?(f.g=p,f.f=h,f.parent=m):s.push(g)}}}return{path:[],visitedNodes:r}},Ee=e=>({cells:Array.from({length:8},(t,a)=>Array.from({length:12},(o,s)=>({row:a,col:s,state:l.Empty}))),rows:8,columns:12,startTile:null,endTile:null,obstacleTiles:[],path:[],visitedNodes:[],setNumberOfColumns:t=>{e(a=>{const o=a.cells.map(s=>t>a.columns?[...s,...Array.from({length:t-a.columns},(r,i)=>({row:s[0].row,col:a.columns+i,state:l.Empty}))]:s.slice(0,t));return{...a,columns:t,cells:o}})},setNumberOfRows:t=>{e(a=>{let o=[...a.cells];return t>a.rows?o=[...o,...Array.from({length:t-a.rows},(s,r)=>Array.from({length:a.columns},(i,m)=>({row:a.rows+r,col:m,state:l.Empty})))]:o=o.slice(0,t),{...a,rows:t,cells:o}})},setCellState:(t,a,o)=>{e(s=>{const r=s.cells.map(c=>c.map(p=>({...p})));let i=s.startTile,m=s.endTile,v=[...s.obstacleTiles];switch(o===l.Start&&s.startTile&&(r[s.startTile.row][s.startTile.col].state=l.Empty,i=null),o===l.End&&s.endTile&&(r[s.endTile.row][s.endTile.col].state=l.Empty,m=null),r[t][a].state=o,o){case l.Start:i={row:t,col:a};break;case l.End:m={row:t,col:a};break;case l.Obstacle:v.some(c=>c.row===t&&c.col===a)||v.push({row:t,col:a});break;case l.Empty:v=v.filter(c=>!(c.row===t&&c.col===a));break}return{...s,cells:r,startTile:i,endTile:m,obstacleTiles:v}})},resetCells:()=>{e(t=>({...t,cells:t.cells.map(a=>a.map(o=>({...o,state:l.Empty}))),startTile:null,endTile:null,obstacleTiles:[],path:[],visitedNodes:[]}))},handleFindPath:t=>{e(a=>{const o=a.cells.flat().find(r=>r.state===l.Start),s=a.cells.flat().find(r=>r.state===l.End);if(o&&s){const r=a.cells.map(c=>c.map(p=>({row:p.row,col:p.col,state:p.state}))),{path:i,visitedNodes:m}=Se(r,o,s,t);return(async(c,p)=>{for(let d of p)await new Promise(h=>setTimeout(h,100)),e(h=>{const f=h.cells.map(g=>g.map(u=>({...u,state:d.row===u.row&&d.col===u.col&&u.state===l.Empty?l.Visited:u.state})));return{...h,cells:f,visitedNodes:[...h.visitedNodes,d]}});for(let d of c)await new Promise(h=>setTimeout(h,250)),e(h=>{const f=h.cells.map(g=>g.map(u=>({...u,state:d.row===u.row&&d.col===u.col?l.Path:u.state})));return{...h,cells:f,path:[...h.path,d]}})})(i,m),{...a,path:[],visitedNodes:[]}}return a})},setPath:t=>{e(a=>{const o=a.cells.map(s=>s.map(r=>({...r,state:t.some(i=>i.row===r.row&&i.col===r.col)?l.Path:r.state})));return{...a,cells:o}})},setVisitedNodes:t=>{e(a=>{const o=a.cells.map(s=>s.map(r=>({...r,state:t.some(i=>i.row===r.row&&i.col===r.col)&&r.state===l.Empty?l.Visited:r.state})));return{...a,cells:o}})}}),Ne=e=>({activeButton:l.Start,setSelectedButtonState:t=>e({activeButton:t}),canTravelDiagonally:!0,setCanTravelDiagonally:t=>e({canTravelDiagonally:t})}),ye=e=>({visualTheme:A.Medieval,showCosts:!1,setVisualTheme:t=>e({visualTheme:t}),setShowCosts:t=>e({showCosts:t})}),_e=e=>({currentRun:null,isAnimating:!1,isPaused:!1,animationSpeed:1,startAnimation:()=>e({isAnimating:!0,isPaused:!1}),stopAnimation:()=>e({isAnimating:!1,isPaused:!1}),pauseAnimation:()=>e({isPaused:!0}),resumeAnimation:()=>e({isPaused:!1}),setAnimationSpeed:t=>e({animationSpeed:t}),setCurrentRun:t=>e({currentRun:t}),clearCurrentRun:()=>e({currentRun:null})}),P=me((e,t,a)=>({...Ee(e),...Ne(e),...ye(e),..._e(e)})),Oe={id:A.Classic,name:"Classic",startIcon:"●",endIcon:"●",terrains:{[l.Obstacle]:{name:"Wall",icon:"■",passable:!1}},presets:[{id:"random",name:"Random",icon:""},{id:"maze",name:"Maze",icon:""}]},Te={id:A.Medieval,name:"Medieval",startIcon:"⚔️",endIcon:"🏰",terrains:{[l.Obstacle]:{name:"Wall",icon:"🧱",passable:!1},[l.Water]:{name:"Water",icon:"🌊",passable:!1},[l.Forest]:{name:"Forest",icon:"🌲",passable:!0},[l.Mountain]:{name:"Mountain",icon:"⛰️",passable:!1}},presets:[{id:"river",name:"River Crossing",icon:""},{id:"mountains",name:"Mountain Range",icon:""},{id:"maze",name:"Castle Maze",icon:""},{id:"random",name:"Random Forest",icon:""}]},X={[A.Classic]:Oe,[A.Medieval]:Te},F=e=>X[e],Me=e=>{const t=F(e);return Object.entries(t.terrains).map(([a,o])=>({state:Number(a),config:o}))},He="",Ce=()=>{var N;const{cells:e,activeButton:t,setCellState:a,setSelectedButtonState:o,visitedNodes:s,path:r,visualTheme:i,showCosts:m}=P(),v=F(i),[c,p]=M.useState({width:0,height:0}),d=M.useRef(null);M.useEffect(()=>{const S=()=>{if(d.current){const y=d.current.getBoundingClientRect();p({width:y.width,height:y.height})}};return S(),window.addEventListener("resize",S),()=>window.removeEventListener("resize",S)},[]);const h=(S,y)=>{switch(a(S,y,t),t){case l.Start:o(l.End);break;case l.End:o(l.Obstacle);break}},f=(S,y)=>{const b=s.find(O=>O.row===S&&O.col===y);return b?{g:b.g,h:b.h,f:b.f}:{g:null,h:null,f:null}},u=(()=>{var D;if(!c.width||!c.height)return 20;const S=((D=e[0])==null?void 0:D.length)||1,y=e.length||1,b=20,O=S+y,E=c.width-b-O,w=c.height-b-O,_=E/S,L=w/y,j=Math.min(_,L);return Math.max(15,Math.min(j,60))})();return n.jsx("div",{className:"grid-wrapper",ref:d,children:n.jsx("div",{className:"grid-container",style:{display:"grid",gridTemplateColumns:`repeat(${((N=e[0])==null?void 0:N.length)||1}, ${u}px)`,gridTemplateRows:`repeat(${e.length||1}, ${u}px)`,gap:"1px",padding:"8px",background:"var(--bg-secondary)",borderRadius:"8px",boxShadow:"0 2px 8px rgba(0, 0, 0, 0.1)",border:"1px solid var(--border-color)"},children:e.map((S,y)=>S.map((b,O)=>{var $,R,ee,te;const E=r.some(T=>T.row===b.row&&T.col===b.col),w=s.some(T=>T.row===b.row&&T.col===b.col),{g:_,h:L,f:j}=f(b.row,b.col);let D=Ae(b,w);if(E){const T=r.findIndex(se=>se.row===b.row&&se.col===b.col);T===0?D="var(--cell-start)":T===r.length-1?D="var(--cell-end)":D="var(--cell-path)"}return n.jsxs("div",{className:"grid-cell",onClick:()=>h(y,O),style:{width:u,height:u,backgroundColor:D,border:"1px solid var(--cell-border)",cursor:"pointer",transition:"all 0.15s ease",position:"relative",display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"2px"},onMouseEnter:T=>{b.state===l.Empty&&(T.currentTarget.style.backgroundColor="var(--bg-tertiary)",T.currentTarget.style.transform="scale(1.02)")},onMouseLeave:T=>{b.state===l.Empty&&(T.currentTarget.style.backgroundColor=D,T.currentTarget.style.transform="scale(1)")},children:[w&&m&&n.jsxs("div",{className:"cell-values",children:[n.jsxs("div",{className:"value-h",children:["h",L]}),n.jsxs("div",{className:"value-f",children:["f",j]}),n.jsxs("div",{className:"value-g",children:["g",_]})]}),b.state===l.Start&&n.jsx("div",{className:"cell-indicator start",style:{fontSize:u*.7},children:v.startIcon}),b.state===l.End&&n.jsx("div",{className:"cell-indicator end",style:{fontSize:u*.7},children:v.endIcon}),b.state===l.Obstacle&&n.jsx("div",{className:"cell-indicator obstacle",style:{fontSize:u*.7},children:(($=v.terrains[l.Obstacle])==null?void 0:$.icon)||"■"}),b.state===l.Water&&n.jsx("div",{className:"cell-indicator water",style:{fontSize:u*.7},children:((R=v.terrains[l.Water])==null?void 0:R.icon)||"🌊"}),b.state===l.Forest&&n.jsx("div",{className:"cell-indicator forest",style:{fontSize:u*.7},children:((ee=v.terrains[l.Forest])==null?void 0:ee.icon)||"🌲"}),b.state===l.Mountain&&n.jsx("div",{className:"cell-indicator mountain",style:{fontSize:u*.7},children:((te=v.terrains[l.Mountain])==null?void 0:te.icon)||"⛰️"})]},`${y}-${O}`)}))})})},Ae=(e,t)=>{if(t)return e.state===l.Start?"var(--cell-start)":e.state===l.End?"var(--cell-end)":"var(--cell-visited)";switch(e.state){case l.Start:return"var(--cell-start)";case l.End:return"var(--cell-end)";case l.Obstacle:return"var(--cell-obstacle)";case l.Water:return"var(--cell-water)";case l.Forest:return"var(--cell-forest)";case l.Mountain:return"var(--cell-mountain)";case l.Empty:return"var(--cell-empty)";default:return"var(--cell-empty)"}},Ke="",Le=()=>{const{activeButton:e,setSelectedButtonState:t,handleFindPath:a,canTravelDiagonally:o,resetCells:s}=P(),r=[{label:"Start",state:l.Start,className:"start"},{label:"End",state:l.End,className:"end"},{label:"Wall",state:l.Obstacle,className:"wall"},{label:"Erase",state:l.Empty,className:"erase"}],i=()=>{a(o)},m=()=>{s(),t(l.Start)};return n.jsxs("div",{className:"toolbar",children:[n.jsx("div",{className:"toolbar-section tools",children:r.map(({label:v,state:c,className:p})=>n.jsx("button",{className:`toolbar-button ${p} ${e===c?"active":""}`,onClick:()=>t(c),children:v},v))}),n.jsx("div",{className:"toolbar-divider"}),n.jsx("button",{className:"toolbar-button reset",onClick:m,children:"Clear All"}),n.jsx("div",{className:"toolbar-spacer"}),n.jsx("button",{className:"toolbar-button primary find-path",onClick:i,children:"Find Path"})]})},Ue="",De=()=>{var v;const{currentRun:e,isAnimating:t,visitedNodes:a,path:o}=P(),s=(e==null?void 0:e.nodesExplored)??a.length,r=(e==null?void 0:e.pathLength)??o.length,i=r>0&&s>0?(r/s*100).toFixed(1):null,m=((v=e==null?void 0:e.executionTimeMs)==null?void 0:v.toFixed(0))??null;return s===0&&r===0&&!t?null:n.jsx("div",{className:"stats-panel",children:n.jsxs("div",{className:"stats-container",children:[n.jsxs("div",{className:"stat-item",children:[n.jsx("span",{className:"stat-label",children:"Nodes Explored"}),n.jsx("span",{className:"stat-value",children:s})]}),n.jsx("div",{className:"stat-divider"}),n.jsxs("div",{className:"stat-item",children:[n.jsx("span",{className:"stat-label",children:"Path Length"}),n.jsx("span",{className:"stat-value",children:r>0?r:"—"})]}),i&&n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"stat-divider"}),n.jsxs("div",{className:"stat-item",children:[n.jsx("span",{className:"stat-label",children:"Efficiency"}),n.jsxs("span",{className:"stat-value",children:[i,"%"]})]})]}),m&&n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"stat-divider"}),n.jsxs("div",{className:"stat-item",children:[n.jsx("span",{className:"stat-label",children:"Time"}),n.jsxs("span",{className:"stat-value",children:[m,"ms"]})]})]}),t&&n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"stat-divider"}),n.jsx("div",{className:"stat-item status",children:n.jsx("span",{className:"stat-status animating",children:"Running..."})})]})]})})},Pe=(e,t)=>{const a=[],o=Math.floor(e/2),s=Math.max(2,Math.floor(t/6)),r=[];for(let i=0;i<s;i++){const m=Math.floor(t/(s+1)*(i+1));r.push(m)}for(let i=0;i<t;i++)r.includes(i)||(a.push({row:o,col:i,state:l.Water}),o+1<e&&a.push({row:o+1,col:i,state:l.Water}));for(let i=0;i<t;i+=3)o-1>=0&&Math.random()>.5&&a.push({row:o-1,col:i,state:l.Forest}),o+2<e&&Math.random()>.5&&a.push({row:o+2,col:i,state:l.Forest});return a},Ve=(e,t)=>{const a=[],o=Math.floor(e*.2),s=Math.floor(t*.1),r=Math.floor(e*.8),i=Math.floor(t*.9),m=Math.max(2,Math.floor(Math.min(e,t)/5)),v=[];for(let c=0;c<m;c++)v.push(Math.floor((i-s)/(m+1)*(c+1))+s);for(let c=s;c<=i;c++){const p=(c-s)/(i-s),d=Math.floor(o+(r-o)*p);v.some(h=>Math.abs(c-h)<=1)||(d>=0&&d<e&&a.push({row:d,col:c,state:l.Mountain}),d+1<e&&Math.random()>.3&&a.push({row:d+1,col:c,state:l.Mountain}),d-1>=0&&Math.random()>.3&&a.push({row:d-1,col:c,state:l.Mountain}))}for(const c of[...a])if(c.state===l.Mountain){const p=[{row:c.row-2,col:c.col},{row:c.row+2,col:c.col},{row:c.row,col:c.col-2},{row:c.row,col:c.col+2}];for(const d of p)d.row>=0&&d.row<e&&d.col>=0&&d.col<t&&Math.random()>.7&&(a.some(h=>h.row===d.row&&h.col===d.col)||a.push({row:d.row,col:d.col,state:l.Forest}))}return a},ke=(e,t)=>{const a=[];for(let s=0;s<e;s++)for(let r=0;r<t;r++){const i=s%3===1,m=r%3===1;(i||m)&&Math.random()>.35&&a.push({row:s,col:r,state:l.Obstacle})}const o=2;return a.filter(s=>{const r=s.row<o&&s.col<o,i=s.row>=e-o&&s.col>=t-o;return!r&&!i})},ze=(e,t,a=.25)=>{const o=[];for(let s=0;s<e;s++)for(let r=0;r<t;r++)if(!(s<2&&r<2||s>=e-2&&r>=t-2)&&Math.random()<a){const m=Math.random();let v;m<.4?v=l.Forest:m<.6?v=l.Obstacle:m<.8?v=l.Water:v=l.Mountain,o.push({row:s,col:r,state:v})}return o},We=(e,t,a=.2)=>{const o=[];for(let s=0;s<e;s++)for(let r=0;r<t;r++)!(s<2&&r<2||s>=e-2&&r>=t-2)&&Math.random()<a&&o.push({row:s,col:r,state:l.Obstacle});return o},Ie=(e,t)=>{const a=[];for(let s=0;s<e;s++)for(let r=0;r<t;r++){const i=s%3===1,m=r%3===1;(i||m)&&Math.random()>.35&&a.push({row:s,col:r,state:l.Obstacle})}const o=2;return a.filter(s=>{const r=s.row<o&&s.col<o,i=s.row>=e-o&&s.col>=t-o;return!r&&!i})},Je="",Be=({isDarkMode:e,setIsDarkMode:t})=>{const[a,o]=M.useState(!1),{rows:s,columns:r,setNumberOfRows:i,setNumberOfColumns:m,visualTheme:v,setVisualTheme:c,canTravelDiagonally:p,setCanTravelDiagonally:d,showCosts:h,setShowCosts:f,activeButton:g,setSelectedButtonState:u,setCellState:N,resetCells:S}=P(),y=F(v),b=Me(v),O=E=>{S();let w;if(v===A.Medieval)switch(E){case"river":w=Pe(s,r);break;case"mountains":w=Ve(s,r);break;case"maze":w=ke(s,r);break;case"random":w=ze(s,r);break;default:return}else switch(E){case"random":w=We(s,r);break;case"maze":w=Ie(s,r);break;default:return}for(const _ of w)N(_.row,_.col,_.state);N(0,0,l.Start),N(s-1,r-1,l.End),u(l.Obstacle)};return n.jsxs("div",{className:`settings-container ${a?"open":""}`,children:[n.jsxs("button",{className:"settings-toggle",onClick:()=>o(!a),"aria-label":"Toggle settings","aria-expanded":a,children:[n.jsx("span",{className:"settings-icon",children:"⚙"}),n.jsx("span",{className:"settings-label",children:"Settings"}),n.jsx("span",{className:`settings-chevron ${a?"open":""}`,children:"▼"})]}),a&&n.jsx("div",{className:"settings-panel",children:n.jsxs("div",{className:"settings-content",children:[n.jsxs("div",{className:"settings-section",children:[n.jsx("h3",{className:"settings-section-title",children:"Appearance"}),n.jsxs("div",{className:"settings-row",children:[n.jsx("label",{children:"Theme"}),n.jsx("select",{className:"settings-select",value:v,onChange:E=>c(E.target.value),children:Object.values(X).map(E=>n.jsx("option",{value:E.id,children:E.name},E.id))})]}),n.jsxs("div",{className:"settings-row",children:[n.jsx("label",{children:"Color Mode"}),n.jsxs("div",{className:"settings-toggle-group",children:[n.jsx("button",{className:`settings-toggle-btn ${e?"":"active"}`,onClick:()=>t(!1),children:"Light"}),n.jsx("button",{className:`settings-toggle-btn ${e?"active":""}`,onClick:()=>t(!0),children:"Dark"})]})]})]}),n.jsxs("div",{className:"settings-section",children:[n.jsx("h3",{className:"settings-section-title",children:"Grid"}),n.jsxs("div",{className:"settings-row",children:[n.jsx("label",{children:"Rows"}),n.jsxs("div",{className:"settings-stepper",children:[n.jsx("button",{onClick:()=>i(Math.max(5,s-1)),disabled:s<=5,children:"−"}),n.jsx("span",{className:"stepper-value",children:s}),n.jsx("button",{onClick:()=>i(Math.min(50,s+1)),disabled:s>=50,children:"+"})]})]}),n.jsxs("div",{className:"settings-row",children:[n.jsx("label",{children:"Columns"}),n.jsxs("div",{className:"settings-stepper",children:[n.jsx("button",{onClick:()=>m(Math.max(5,r-1)),disabled:r<=5,children:"−"}),n.jsx("span",{className:"stepper-value",children:r}),n.jsx("button",{onClick:()=>m(Math.min(50,r+1)),disabled:r>=50,children:"+"})]})]})]}),n.jsxs("div",{className:"settings-section",children:[n.jsx("h3",{className:"settings-section-title",children:"Algorithm"}),n.jsxs("div",{className:"settings-row",children:[n.jsx("label",{children:"Diagonal Movement"}),n.jsxs("div",{className:"settings-toggle-group",children:[n.jsx("button",{className:`settings-toggle-btn ${p?"":"active"}`,onClick:()=>d(!1),children:"Off"}),n.jsx("button",{className:`settings-toggle-btn ${p?"active":""}`,onClick:()=>d(!0),children:"On"})]})]}),n.jsxs("div",{className:"settings-row",children:[n.jsx("label",{children:"Show Costs"}),n.jsxs("div",{className:"settings-toggle-group",children:[n.jsx("button",{className:`settings-toggle-btn ${h?"":"active"}`,onClick:()=>f(!1),children:"Off"}),n.jsx("button",{className:`settings-toggle-btn ${h?"active":""}`,onClick:()=>f(!0),children:"On"})]})]})]}),v===A.Medieval&&n.jsxs("div",{className:"settings-section",children:[n.jsx("h3",{className:"settings-section-title",children:"Terrain Tools"}),n.jsx("div",{className:"settings-terrain-grid",children:b.filter(({state:E})=>E!==l.Obstacle).map(({state:E,config:w})=>n.jsxs("button",{className:`settings-terrain-btn ${g===E?"active":""}`,onClick:()=>u(E),title:w.passable?"Passable terrain":"Impassable terrain",children:[w.icon," ",w.name]},E))})]}),n.jsxs("div",{className:"settings-section",children:[n.jsx("h3",{className:"settings-section-title",children:"Generate Map"}),n.jsx("div",{className:"settings-preset-grid",children:y.presets.map(E=>n.jsx("button",{className:"settings-preset-btn",onClick:()=>O(E.id),children:E.name},E.id))})]})]})})]})},Z=({defaultDarkMode:e})=>{const t=M.useRef(null),{visualTheme:a}=P(),[o,s]=M.useState(()=>{if(e!==void 0)return e;const r=localStorage.getItem("astar-darkMode");return r?JSON.parse(r):!1});return M.useEffect(()=>{e===void 0&&localStorage.setItem("astar-darkMode",JSON.stringify(o)),t.current&&(t.current.setAttribute("data-theme",o?"dark":"light"),t.current.setAttribute("data-visual-theme",a))},[o,e,a]),n.jsx("div",{ref:t,className:"astar-visualizer-root","data-theme":o?"dark":"light","data-visual-theme":a,children:n.jsxs("div",{className:"app-container",children:[n.jsx("header",{className:"app-header",children:n.jsx("h1",{className:"app-title",children:"A* Pathfinding Visualizer"})}),n.jsx(Le,{}),n.jsx("main",{className:"app-main",children:n.jsx(Ce,{})}),n.jsx(De,{}),n.jsx(Be,{isDarkMode:o,setIsDarkMode:s})]})})};function xe({defaultDarkMode:e}){return n.jsx(Z,{defaultDarkMode:e})}C.AStarVisualizer=xe,C.CellState=l,C.Layout=Z,C.VisualTheme=A,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})});
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;line-height:1.5;font-weight:400;--bg-primary: #fafafa;--bg-secondary: #ffffff;--bg-tertiary: #f5f5f5;--text-primary: #1a1a1a;--text-secondary: #666666;--text-muted: #999999;--border-color: #e0e0e0;--border-hover: #d0d0d0;--cell-empty: #ffffff;--cell-start: #4caf50;--cell-end: #f44336;--cell-obstacle: #424242;--cell-visited: #2196f3;--cell-path: #ff9800;--cell-border: #e0e0e0;--cell-water: #4A90D9;--cell-forest: #228B22;--cell-mountain: #8B7355;--primary: #2196f3;--primary-hover: #1976d2;--success: #4caf50;--success-hover: #388e3c;--danger: #f44336;--danger-hover: #d32f2f;--warning: #ff9800;--warning-hover: #f57c00;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%}.astar-visualizer-root[data-theme=dark]{--bg-primary: #0f0f0f;--bg-secondary: #1a1a1a;--bg-tertiary: #2a2a2a;--text-primary: #ffffff;--text-secondary: #b3b3b3;--text-muted: #808080;--border-color: #404040;--border-hover: #505050;--cell-empty: #2a2a2a;--cell-start: #4caf50;--cell-end: #f44336;--cell-obstacle: #1a1a1a;--cell-visited: #2196f3;--cell-path: #ff9800;--cell-border: #404040;--cell-water: #1E5A8F;--cell-forest: #1B5E20;--cell-mountain: #5D4E37;--primary: #2196f3;--primary-hover: #1976d2;--success: #4caf50;--success-hover: #388e3c;--danger: #f44336;--danger-hover: #d32f2f;--warning: #ff9800;--warning-hover: #f57c00}.astar-visualizer-root[data-visual-theme=medieval]{--cell-empty: #90EE90;--cell-start: #4caf50;--cell-end: #8B0000;--cell-obstacle: #696969;--cell-visited: #87CEEB;--cell-path: #FFD700;--cell-border: #556B2F;--cell-water: #4A90D9;--cell-forest: #228B22;--cell-mountain: #8B7355}.astar-visualizer-root[data-visual-theme=medieval][data-theme=dark]{--cell-empty: #2D5A2D;--cell-start: #2E7D32;--cell-end: #5C0000;--cell-obstacle: #3D3D3D;--cell-visited: #4682B4;--cell-path: #B8860B;--cell-border: #3B4A29;--cell-water: #1E3A5F;--cell-forest: #1B4D1B;--cell-mountain: #4A3728}.astar-visualizer-root,.astar-visualizer-root *,.astar-visualizer-root *:before,.astar-visualizer-root *:after{transition:background-color .3s ease,color .3s ease,border-color .3s ease,box-shadow .3s ease}.astar-visualizer-root{width:100%;height:100%;display:flex;flex-direction:column;margin:0;padding:0;overflow:hidden;background:var(--bg-primary);color:var(--text-primary);position:relative}.astar-visualizer-root *{box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.astar-visualizer-root .app-container{display:flex;flex-direction:column;height:100%;width:100%}.astar-visualizer-root .app-header{padding:.5rem 1rem;background:var(--bg-secondary);border-bottom:1px solid var(--border-color);text-align:center;flex-shrink:0}.astar-visualizer-root .app-title{font-size:1.25rem;font-weight:600;margin:0;color:var(--text-primary);letter-spacing:-.025em}.astar-visualizer-root .app-main{flex:1;display:flex;justify-content:center;align-items:center;padding:.5rem;overflow:hidden;min-height:0}.astar-visualizer-root .app-footer{padding:.5rem 1rem;background:var(--bg-secondary);border-top:1px solid var(--border-color);flex-shrink:0;overflow-y:auto;max-height:30%}.astar-visualizer-root button{border:1px solid var(--border-color);border-radius:6px;padding:.5rem 1rem;font-size:.875rem;font-weight:500;font-family:inherit;background:var(--bg-secondary);color:var(--text-primary);cursor:pointer;transition:all .2s ease;outline:none}.astar-visualizer-root button:hover{border-color:var(--border-hover);background:var(--bg-tertiary)}.astar-visualizer-root button:active{transform:translateY(1px)}.astar-visualizer-root button:focus-visible{outline:2px solid var(--primary);outline-offset:2px}@media (max-width: 768px){.astar-visualizer-root .app-header{padding:.75rem 1.5rem}.astar-visualizer-root .app-title{font-size:1.5rem}.astar-visualizer-root .app-main{padding:.25rem}.astar-visualizer-root .app-footer{padding:.75rem 1.5rem}}@media (max-width: 480px){.astar-visualizer-root .app-header{padding:.5rem 1rem}.astar-visualizer-root .app-title{font-size:1.25rem}.astar-visualizer-root .app-main{padding:.125rem}.astar-visualizer-root .app-footer{padding:.5rem 1rem}}@media (max-height: 600px){.astar-visualizer-root .app-header{padding:.5rem 1rem}.astar-visualizer-root .app-title{font-size:1.25rem}.astar-visualizer-root .app-footer{padding:.5rem 1rem}}@media (max-height: 400px){.astar-visualizer-root .app-header{padding:.25rem .5rem}.astar-visualizer-root .app-title{font-size:1rem}.astar-visualizer-root .app-footer{padding:.25rem .5rem}}.astar-visualizer-root #root{width:100%;height:100%;margin:0;padding:0;overflow:hidden;display:flex;flex-direction:column}.astar-visualizer-root .loading{display:flex;justify-content:center;align-items:center;height:100%;font-size:1.5rem;color:var(--text-secondary)}.astar-visualizer-root .error{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;padding:2rem;text-align:center}.astar-visualizer-root .error h2{color:var(--danger);margin-bottom:1rem}.astar-visualizer-root .error p{color:var(--text-secondary);max-width:500px}@media (prefers-reduced-motion: reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}*{transition:none!important}}@media (prefers-contrast: high){:root{--cell-border: #000000;--text-primary: #000000;--text-secondary: #000000;--bg-primary: #ffffff;--bg-secondary: #ffffff}[data-theme=dark]{--cell-border: #ffffff;--text-primary: #ffffff;--text-secondary: #ffffff;--bg-primary: #000000;--bg-secondary: #000000}}@media print{.astar-visualizer-root .app-footer{display:none}.astar-visualizer-root .app-header{background:white!important;color:#000!important}.astar-visualizer-root .grid-container{box-shadow:none!important;border:2px solid black!important}}.astar-visualizer-root .grid-wrapper{display:flex;justify-content:center;align-items:center;width:100%;height:100%;padding:.5rem;box-sizing:border-box;overflow:hidden}.astar-visualizer-root .grid-container{display:grid;gap:1px;padding:4px;background:var(--bg-secondary);border-radius:4px;box-shadow:0 2px 8px #0000001a;border:1px solid var(--border-color);width:fit-content;height:fit-content}.astar-visualizer-root .grid-cell{position:relative;display:flex;justify-content:center;align-items:center;border:1px solid var(--cell-border);cursor:pointer;transition:all .15s ease;border-radius:2px;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.astar-visualizer-root .grid-cell:hover{transform:scale(1.02)}.astar-visualizer-root .grid-cell:active{transform:scale(.98)}.astar-visualizer-root .cell-values{position:absolute;top:0;left:0;right:0;bottom:0;display:grid;grid-template-columns:1fr 1fr 1fr;grid-template-rows:1fr 1fr;font-size:.75rem;font-weight:700;color:#fff;text-shadow:0 2px 4px rgba(0,0,0,.9);pointer-events:none}.astar-visualizer-root .value-h{grid-column:1;grid-row:1;display:flex;align-items:center;justify-content:center;font-size:.65rem}.astar-visualizer-root .value-f{grid-column:3;grid-row:1;display:flex;align-items:center;justify-content:center;font-size:.65rem}.astar-visualizer-root .value-g{grid-column:2;grid-row:2;display:flex;align-items:center;justify-content:center;font-size:.65rem}.astar-visualizer-root .cell-indicator{font-size:1.2rem;font-weight:700;color:#fff;text-shadow:0 2px 4px rgba(0,0,0,.9)}.astar-visualizer-root .cell-indicator.start,.astar-visualizer-root .cell-indicator.end,.astar-visualizer-root .cell-indicator.obstacle{color:#fff}@media (max-width: 768px){.astar-visualizer-root .cell-values{font-size:.6rem}.astar-visualizer-root .value-h,.astar-visualizer-root .value-f,.astar-visualizer-root .value-g{font-size:.5rem}.astar-visualizer-root .cell-indicator{font-size:1rem}}@media (max-width: 480px){.astar-visualizer-root .cell-values{font-size:.5rem}.astar-visualizer-root .value-h,.astar-visualizer-root .value-f,.astar-visualizer-root .value-g{font-size:.4rem}.astar-visualizer-root .cell-indicator{font-size:.9rem}}.astar-visualizer-root .control-panel{padding:1rem;background:var(--bg-secondary);border-radius:8px;border:1px solid var(--border-color);box-shadow:0 2px 8px #0000001a}.astar-visualizer-root .control-grid{display:grid;grid-template-columns:1fr;gap:1.5rem;align-items:start}.astar-visualizer-root .control-group{display:flex;flex-direction:column;gap:.75rem}.astar-visualizer-root .group-title{font-size:.875rem;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.05em;margin:0;padding-bottom:.5rem;border-bottom:1px solid var(--border-color)}.astar-visualizer-root .button-group{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center;justify-content:center}.astar-visualizer-root .control-button{padding:.5rem 1rem;font-size:.875rem;font-weight:500;color:var(--text-primary);background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:6px;cursor:pointer;transition:all .2s ease;outline:none;min-width:fit-content}.astar-visualizer-root .control-button:hover{border-color:var(--border-hover);background:var(--bg-tertiary)}.astar-visualizer-root .control-button:active{transform:translateY(1px)}.astar-visualizer-root .control-button:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.astar-visualizer-root .control-button.start.active{background:var(--success);border-color:var(--success);color:#fff}.astar-visualizer-root .control-button.end.active{background:var(--danger);border-color:var(--danger);color:#fff}.astar-visualizer-root .control-button.obstacle.active{background:var(--text-primary);border-color:var(--text-primary);color:#fff}.astar-visualizer-root .control-button.clear.active{background:var(--text-muted);border-color:var(--text-muted);color:#fff}.astar-visualizer-root .control-button.reset{background:var(--danger);border-color:var(--danger);color:#fff}.astar-visualizer-root .control-button.reset:hover{background:var(--danger-hover);border-color:var(--danger-hover)}.astar-visualizer-root .control-button.find-path{background:var(--primary);border-color:var(--primary);color:#fff}.astar-visualizer-root .control-button.find-path:hover{background:var(--primary-hover);border-color:var(--primary-hover)}.astar-visualizer-root .control-button.diagonal.active{background:var(--warning);border-color:var(--warning);color:#fff}.astar-visualizer-root .control-button.diagonal:hover{background:var(--warning-hover);border-color:var(--warning-hover)}.astar-visualizer-root .control-button.theme-toggle{background:var(--text-muted);border-color:var(--text-muted);color:#fff}.astar-visualizer-root .control-button.theme-toggle:hover{background:var(--text-secondary);border-color:var(--text-secondary)}.astar-visualizer-root .control-button.theme-toggle.active{background:var(--warning);border-color:var(--warning);color:#fff}.astar-visualizer-root .control-button.theme-toggle.active:hover{background:var(--warning-hover);border-color:var(--warning-hover)}.astar-visualizer-root .theme-select{padding:.5rem 1rem;font-size:.875rem;font-weight:500;font-family:inherit;color:var(--text-primary);background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:6px;cursor:pointer;transition:all .2s ease;outline:none;min-width:120px}.astar-visualizer-root .theme-select:hover{border-color:var(--border-hover);background:var(--bg-tertiary)}.astar-visualizer-root .theme-select:focus{outline:2px solid var(--primary);outline-offset:2px}.astar-visualizer-root .control-button.show-costs{background:var(--text-muted);border-color:var(--text-muted);color:#fff}.astar-visualizer-root .control-button.show-costs:hover{background:var(--text-secondary);border-color:var(--text-secondary)}.astar-visualizer-root .control-button.show-costs.active{background:var(--primary);border-color:var(--primary);color:#fff}.astar-visualizer-root .control-button.terrain-btn{background:var(--bg-secondary);border-color:var(--border-color)}.astar-visualizer-root .control-button.terrain-btn:hover{background:var(--bg-tertiary);border-color:var(--border-hover)}.astar-visualizer-root .control-button.terrain-btn.water.active{background:#4A90D9;border-color:#4a90d9;color:#fff}.astar-visualizer-root .control-button.terrain-btn.forest.active{background:#228B22;border-color:#228b22;color:#fff}.astar-visualizer-root .control-button.terrain-btn.mountain.active{background:#8B7355;border-color:#8b7355;color:#fff}.astar-visualizer-root .control-button.preset-btn{background:var(--bg-tertiary);border-color:var(--border-color)}.astar-visualizer-root .control-button.preset-btn:hover{background:var(--primary);border-color:var(--primary);color:#fff}.astar-visualizer-root .size-controls{display:flex;flex-direction:column;gap:.75rem;align-items:center}.astar-visualizer-root .size-control{display:flex;flex-direction:column;gap:.25rem;align-items:center}.astar-visualizer-root .size-label{font-size:.75rem;font-weight:500;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.05em}.astar-visualizer-root .size-buttons{display:flex;align-items:center;gap:.5rem}.astar-visualizer-root .size-button{display:flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;font-size:1rem;font-weight:600;color:var(--text-primary);background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:4px;cursor:pointer;transition:all .2s ease;outline:none}.astar-visualizer-root .size-button:hover:not(:disabled){background:var(--primary);border-color:var(--primary);color:#fff}.astar-visualizer-root .size-button:active:not(:disabled){transform:scale(.95)}.astar-visualizer-root .size-button:disabled{opacity:.4;cursor:not-allowed}.astar-visualizer-root .size-button:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.astar-visualizer-root .size-value{display:flex;align-items:center;justify-content:center;min-width:2.5rem;height:1.75rem;font-size:.875rem;font-weight:600;color:var(--text-primary);background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:4px}@media (min-width: 1024px){.astar-visualizer-root .control-grid{grid-template-columns:2fr 1fr 1fr;gap:2rem}.astar-visualizer-root .control-group.tools{grid-column:1}.astar-visualizer-root .control-group.actions{grid-column:2}.astar-visualizer-root .control-group.size{grid-column:3}}@media (min-width: 768px) and (max-width: 1023px){.astar-visualizer-root .control-grid{grid-template-columns:1fr 1fr;gap:1.5rem}.astar-visualizer-root .control-group.tools{grid-column:1 / -1}.astar-visualizer-root .control-group.actions{grid-column:1}.astar-visualizer-root .control-group.size{grid-column:2}}@media (max-width: 768px){.astar-visualizer-root .control-panel{padding:.75rem}.astar-visualizer-root .control-grid{gap:1rem}.astar-visualizer-root .button-group{gap:.375rem}.astar-visualizer-root .control-button{padding:.375rem .75rem;font-size:.8125rem}.astar-visualizer-root .size-controls{gap:.5rem}.astar-visualizer-root .size-buttons{gap:.375rem}.astar-visualizer-root .size-button{width:1.5rem;height:1.5rem;font-size:.875rem}.astar-visualizer-root .size-value{min-width:2rem;height:1.5rem;font-size:.8125rem}}@media (max-width: 480px){.astar-visualizer-root .control-panel{padding:.5rem}.astar-visualizer-root .control-grid{gap:.75rem}.astar-visualizer-root .button-group{flex-direction:column;gap:.25rem}.astar-visualizer-root .control-button{width:100%;padding:.5rem;font-size:.75rem}.astar-visualizer-root .size-controls{gap:.375rem}.astar-visualizer-root .size-buttons{gap:.25rem}.astar-visualizer-root .size-button{width:1.25rem;height:1.25rem;font-size:.75rem}.astar-visualizer-root .size-value{min-width:1.75rem;height:1.25rem;font-size:.75rem}}
|
|
1
|
+
:root{font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;line-height:1.5;font-weight:400;--apple-blue: #0071e3;--apple-blue-hover: #0077ed;--apple-green: #34c759;--apple-green-hover: #30d158;--apple-red: #ff3b30;--apple-red-hover: #ff453a;--apple-orange: #ff9500;--apple-orange-hover: #ff9f0a;--bg-primary: #f5f5f7;--bg-secondary: #ffffff;--bg-tertiary: #e8e8ed;--text-primary: #1d1d1f;--text-secondary: #6e6e73;--text-muted: #86868b;--border-color: #d2d2d7;--border-hover: #c7c7cc;--cell-empty: #ffffff;--cell-start: var(--apple-green);--cell-end: var(--apple-red);--cell-obstacle: #3a3a3c;--cell-visited: var(--apple-blue);--cell-path: var(--apple-orange);--cell-border: #d2d2d7;--cell-water: #5ac8fa;--cell-forest: #34c759;--cell-mountain: #8e8e93;--primary: var(--apple-blue);--primary-hover: var(--apple-blue-hover);--success: var(--apple-green);--success-hover: var(--apple-green-hover);--danger: var(--apple-red);--danger-hover: var(--apple-red-hover);--warning: var(--apple-orange);--warning-hover: var(--apple-orange-hover);font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%}.astar-visualizer-root[data-theme=dark]{--bg-primary: #000000;--bg-secondary: #1c1c1e;--bg-tertiary: #2c2c2e;--text-primary: #ffffff;--text-secondary: #98989d;--text-muted: #636366;--border-color: #38383a;--border-hover: #48484a;--cell-empty: #2c2c2e;--cell-start: #30d158;--cell-end: #ff453a;--cell-obstacle: #1c1c1e;--cell-visited: #0a84ff;--cell-path: #ff9f0a;--cell-border: #38383a;--cell-water: #64d2ff;--cell-forest: #30d158;--cell-mountain: #636366;--primary: #0a84ff;--primary-hover: #409cff;--success: #30d158;--success-hover: #34c759;--danger: #ff453a;--danger-hover: #ff6961;--warning: #ff9f0a;--warning-hover: #ffb340}.astar-visualizer-root[data-visual-theme=medieval]{--cell-empty: #90EE90;--cell-start: #4caf50;--cell-end: #8B0000;--cell-obstacle: #696969;--cell-visited: #87CEEB;--cell-path: #FFD700;--cell-border: #556B2F;--cell-water: #4A90D9;--cell-forest: #228B22;--cell-mountain: #8B7355}.astar-visualizer-root[data-visual-theme=medieval][data-theme=dark]{--cell-empty: #2D5A2D;--cell-start: #2E7D32;--cell-end: #5C0000;--cell-obstacle: #3D3D3D;--cell-visited: #4682B4;--cell-path: #B8860B;--cell-border: #3B4A29;--cell-water: #1E3A5F;--cell-forest: #1B4D1B;--cell-mountain: #4A3728}.astar-visualizer-root,.astar-visualizer-root *,.astar-visualizer-root *:before,.astar-visualizer-root *:after{transition:background-color .3s ease,color .3s ease,border-color .3s ease,box-shadow .3s ease}.astar-visualizer-root{width:100%;height:100%;display:flex;flex-direction:column;margin:0;padding:0;overflow:hidden;background:var(--bg-primary);color:var(--text-primary);position:relative}.astar-visualizer-root *{box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.astar-visualizer-root .app-container{display:flex;flex-direction:column;height:100%;width:100%}.astar-visualizer-root .app-header{padding:1rem 1.5rem;background:var(--bg-secondary);border-bottom:1px solid var(--border-color);text-align:center;flex-shrink:0}.astar-visualizer-root .app-title{font-size:1.25rem;font-weight:600;margin:0;color:var(--text-primary);letter-spacing:-.025em}.astar-visualizer-root .app-main{flex:1;display:flex;justify-content:center;align-items:center;padding:.5rem;overflow:hidden;min-height:0}.astar-visualizer-root button{border:1.5px solid var(--border-color);border-radius:8px;padding:.625rem 1.25rem;font-size:.875rem;font-weight:500;font-family:inherit;background:var(--bg-secondary);color:var(--text-primary);cursor:pointer;transition:all .2s ease;outline:none}.astar-visualizer-root button:hover{border-color:var(--border-hover);background:var(--bg-tertiary)}.astar-visualizer-root button:active{transform:translateY(1px)}.astar-visualizer-root button:focus-visible{outline:2px solid var(--primary);outline-offset:2px}@media (max-width: 768px){.astar-visualizer-root .app-header{padding:.75rem 1.5rem}.astar-visualizer-root .app-title{font-size:1.5rem}.astar-visualizer-root .app-main{padding:.25rem}.astar-visualizer-root .app-footer{padding:.75rem 1.5rem}}@media (max-width: 480px){.astar-visualizer-root .app-header{padding:.5rem 1rem}.astar-visualizer-root .app-title{font-size:1.25rem}.astar-visualizer-root .app-main{padding:.125rem}.astar-visualizer-root .app-footer{padding:.5rem 1rem}}@media (max-height: 600px){.astar-visualizer-root .app-header{padding:.5rem 1rem}.astar-visualizer-root .app-title{font-size:1.25rem}.astar-visualizer-root .app-footer{padding:.5rem 1rem}}@media (max-height: 400px){.astar-visualizer-root .app-header{padding:.25rem .5rem}.astar-visualizer-root .app-title{font-size:1rem}.astar-visualizer-root .app-footer{padding:.25rem .5rem}}.astar-visualizer-root #root{width:100%;height:100%;margin:0;padding:0;overflow:hidden;display:flex;flex-direction:column}.astar-visualizer-root .loading{display:flex;justify-content:center;align-items:center;height:100%;font-size:1.5rem;color:var(--text-secondary)}.astar-visualizer-root .error{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;padding:2rem;text-align:center}.astar-visualizer-root .error h2{color:var(--danger);margin-bottom:1rem}.astar-visualizer-root .error p{color:var(--text-secondary);max-width:500px}@media (prefers-reduced-motion: reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}*{transition:none!important}}@media (prefers-contrast: high){:root{--cell-border: #000000;--text-primary: #000000;--text-secondary: #000000;--bg-primary: #ffffff;--bg-secondary: #ffffff}[data-theme=dark]{--cell-border: #ffffff;--text-primary: #ffffff;--text-secondary: #ffffff;--bg-primary: #000000;--bg-secondary: #000000}}@media print{.astar-visualizer-root .app-footer{display:none}.astar-visualizer-root .app-header{background:white!important;color:#000!important}.astar-visualizer-root .grid-container{box-shadow:none!important;border:2px solid black!important}}.astar-visualizer-root .grid-wrapper{display:flex;justify-content:center;align-items:center;width:100%;height:100%;padding:.5rem;box-sizing:border-box;overflow:hidden}.astar-visualizer-root .grid-container{display:grid;gap:1px;padding:8px;background:var(--bg-secondary);border-radius:12px;box-shadow:0 1px 3px #00000014,0 4px 12px #0000001f;border:1px solid var(--border-color);width:fit-content;height:fit-content}.astar-visualizer-root .grid-cell{position:relative;display:flex;justify-content:center;align-items:center;border:1px solid var(--cell-border);cursor:pointer;transition:transform .15s cubic-bezier(.34,1.56,.64,1),background-color .2s ease,box-shadow .15s ease;border-radius:4px;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.astar-visualizer-root .grid-cell:hover{transform:scale(1.05);z-index:1}.astar-visualizer-root .grid-cell:active{transform:scale(.95)}.astar-visualizer-root .cell-values{position:absolute;top:0;left:0;right:0;bottom:0;display:grid;grid-template-columns:1fr 1fr 1fr;grid-template-rows:1fr 1fr;font-size:.75rem;font-weight:700;color:#fff;text-shadow:0 2px 4px rgba(0,0,0,.9);pointer-events:none}.astar-visualizer-root .value-h{grid-column:1;grid-row:1;display:flex;align-items:center;justify-content:center;font-size:.65rem}.astar-visualizer-root .value-f{grid-column:3;grid-row:1;display:flex;align-items:center;justify-content:center;font-size:.65rem}.astar-visualizer-root .value-g{grid-column:2;grid-row:2;display:flex;align-items:center;justify-content:center;font-size:.65rem}.astar-visualizer-root .cell-indicator{font-weight:700;color:#fff;text-shadow:0 2px 4px rgba(0,0,0,.9)}.astar-visualizer-root .cell-indicator.start,.astar-visualizer-root .cell-indicator.end,.astar-visualizer-root .cell-indicator.obstacle{color:#fff}@media (max-width: 768px){.astar-visualizer-root .cell-values{font-size:.6rem}.astar-visualizer-root .value-h,.astar-visualizer-root .value-f,.astar-visualizer-root .value-g{font-size:.5rem}}@media (max-width: 480px){.astar-visualizer-root .cell-values{font-size:.5rem}.astar-visualizer-root .value-h,.astar-visualizer-root .value-f,.astar-visualizer-root .value-g{font-size:.4rem}}.astar-visualizer-root .toolbar{display:flex;align-items:center;gap:.75rem;padding:.875rem 1.5rem;background:var(--bg-secondary);border-bottom:1px solid var(--border-color)}.astar-visualizer-root .toolbar-section{display:flex;align-items:center;gap:.5rem}.astar-visualizer-root .toolbar-divider{width:1px;height:24px;background:var(--border-color);margin:0 .5rem}.astar-visualizer-root .toolbar-spacer{flex:1}.astar-visualizer-root .toolbar-button{padding:.5rem 1rem;background:transparent;border:1.5px solid var(--border-color);border-radius:8px;font-size:.875rem;font-weight:500;color:var(--text-primary);cursor:pointer;transition:all .2s ease;outline:none}.astar-visualizer-root .toolbar-button:hover:not(:disabled){border-color:var(--primary);color:var(--primary)}.astar-visualizer-root .toolbar-button:active:not(:disabled){transform:translateY(1px)}.astar-visualizer-root .toolbar-button:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.astar-visualizer-root .toolbar-button.start.active{background:var(--success);border-color:var(--success);color:#fff}.astar-visualizer-root .toolbar-button.end.active{background:var(--danger);border-color:var(--danger);color:#fff}.astar-visualizer-root .toolbar-button.wall.active{background:var(--text-primary);border-color:var(--text-primary);color:var(--bg-primary)}.astar-visualizer-root .toolbar-button.erase.active{background:var(--text-muted);border-color:var(--text-muted);color:#fff}.astar-visualizer-root .toolbar-button.reset{color:var(--danger);border-color:var(--danger)}.astar-visualizer-root .toolbar-button.reset:hover{background:var(--danger);color:#fff}.astar-visualizer-root .toolbar-button.primary{background:var(--primary);border-color:var(--primary);color:#fff;padding:.625rem 1.5rem;font-weight:600;box-shadow:0 2px 8px #0071e340}.astar-visualizer-root .toolbar-button.primary:hover{background:var(--primary-hover);border-color:var(--primary-hover);transform:translateY(-1px);box-shadow:0 4px 12px #0071e359}.astar-visualizer-root .toolbar-button.primary:active{transform:translateY(0)}@media (max-width: 768px){.astar-visualizer-root .toolbar{flex-wrap:wrap;padding:.75rem 1rem;gap:.5rem}.astar-visualizer-root .toolbar-section.tools{order:1;width:100%;justify-content:center}.astar-visualizer-root .toolbar-divider,.astar-visualizer-root .toolbar-spacer{display:none}.astar-visualizer-root .toolbar-button.reset{order:2}.astar-visualizer-root .toolbar-button.primary{order:3;flex:1;min-width:120px}}@media (max-width: 480px){.astar-visualizer-root .toolbar{padding:.5rem}.astar-visualizer-root .toolbar-button{padding:.375rem .75rem;font-size:.8125rem}.astar-visualizer-root .toolbar-button.primary{width:100%}}.astar-visualizer-root .stats-panel{background:var(--bg-secondary);border-top:1px solid var(--border-color);padding:.75rem 1.5rem}.astar-visualizer-root .stats-container{display:flex;align-items:center;justify-content:center;gap:1.5rem;flex-wrap:wrap}.astar-visualizer-root .stat-item{display:flex;flex-direction:column;align-items:center;gap:.25rem}.astar-visualizer-root .stat-label{font-size:.6875rem;font-weight:500;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em}.astar-visualizer-root .stat-value{font-size:1.125rem;font-weight:600;color:var(--text-primary);font-variant-numeric:tabular-nums}.astar-visualizer-root .stat-divider{width:1px;height:32px;background:var(--border-color)}.astar-visualizer-root .stat-status{font-size:.8125rem;font-weight:500;padding:.25rem .75rem;border-radius:9999px}.astar-visualizer-root .stat-status.animating{color:var(--primary);background:rgba(0,113,227,.1);animation:pulse 1.5s ease-in-out infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.6}}@media (max-width: 768px){.astar-visualizer-root .stats-panel{padding:.5rem 1rem}.astar-visualizer-root .stats-container{gap:1rem}.astar-visualizer-root .stat-value{font-size:1rem}.astar-visualizer-root .stat-divider{height:24px}}@media (max-width: 480px){.astar-visualizer-root .stats-container{gap:.75rem}.astar-visualizer-root .stat-label{font-size:.625rem}.astar-visualizer-root .stat-value{font-size:.875rem}.astar-visualizer-root .stat-divider{display:none}}.astar-visualizer-root .settings-container{background:var(--bg-secondary);border-top:1px solid var(--border-color)}.astar-visualizer-root .settings-toggle{display:flex;align-items:center;justify-content:center;gap:.5rem;width:100%;padding:.75rem 1rem;background:transparent;border:none;color:var(--text-secondary);font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}.astar-visualizer-root .settings-toggle:hover{color:var(--text-primary);background:var(--bg-tertiary)}.astar-visualizer-root .settings-icon{font-size:1rem}.astar-visualizer-root .settings-chevron{font-size:.625rem;transition:transform .2s ease}.astar-visualizer-root .settings-chevron.open{transform:rotate(180deg)}.astar-visualizer-root .settings-panel{border-top:1px solid var(--border-color);padding:1rem 1.5rem 1.5rem;animation:slideDown .2s ease}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.astar-visualizer-root .settings-content{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:1.5rem}.astar-visualizer-root .settings-section{display:flex;flex-direction:column;gap:.75rem}.astar-visualizer-root .settings-section-title{font-size:.75rem;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em;margin:0;padding-bottom:.5rem;border-bottom:1px solid var(--border-color)}.astar-visualizer-root .settings-row{display:flex;align-items:center;justify-content:space-between;gap:1rem}.astar-visualizer-root .settings-row label{font-size:.875rem;font-weight:500;color:var(--text-primary)}.astar-visualizer-root .settings-select{padding:.5rem .75rem;font-size:.875rem;font-weight:500;font-family:inherit;color:var(--text-primary);background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:6px;cursor:pointer;min-width:100px}.astar-visualizer-root .settings-select:hover{border-color:var(--border-hover)}.astar-visualizer-root .settings-select:focus{outline:2px solid var(--primary);outline-offset:2px}.astar-visualizer-root .settings-toggle-group{display:flex;border:1px solid var(--border-color);border-radius:6px;overflow:hidden}.astar-visualizer-root .settings-toggle-btn{padding:.375rem .75rem;font-size:.8125rem;font-weight:500;color:var(--text-secondary);background:transparent;border:none;cursor:pointer;transition:all .2s ease}.astar-visualizer-root .settings-toggle-btn:not(:last-child){border-right:1px solid var(--border-color)}.astar-visualizer-root .settings-toggle-btn:hover:not(.active){color:var(--text-primary);background:var(--bg-tertiary)}.astar-visualizer-root .settings-toggle-btn.active{color:#fff;background:var(--primary)}.astar-visualizer-root .settings-stepper{display:flex;align-items:center;border:1px solid var(--border-color);border-radius:6px;overflow:hidden}.astar-visualizer-root .settings-stepper button{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;font-size:1rem;font-weight:600;color:var(--text-primary);background:transparent;border:none;cursor:pointer;transition:all .2s ease}.astar-visualizer-root .settings-stepper button:hover:not(:disabled){background:var(--primary);color:#fff}.astar-visualizer-root .settings-stepper button:disabled{opacity:.4;cursor:not-allowed}.astar-visualizer-root .stepper-value{display:flex;align-items:center;justify-content:center;min-width:2.5rem;height:2rem;font-size:.875rem;font-weight:600;color:var(--text-primary);background:var(--bg-tertiary);border-left:1px solid var(--border-color);border-right:1px solid var(--border-color)}.astar-visualizer-root .settings-terrain-grid{display:flex;flex-wrap:wrap;gap:.5rem}.astar-visualizer-root .settings-terrain-btn{padding:.5rem .75rem;font-size:.8125rem;font-weight:500;color:var(--text-primary);background:transparent;border:1.5px solid var(--border-color);border-radius:6px;cursor:pointer;transition:all .2s ease}.astar-visualizer-root .settings-terrain-btn:hover{border-color:var(--primary);color:var(--primary)}.astar-visualizer-root .settings-terrain-btn.active{background:var(--primary);border-color:var(--primary);color:#fff}.astar-visualizer-root .settings-preset-grid{display:flex;flex-wrap:wrap;gap:.5rem}.astar-visualizer-root .settings-preset-btn{padding:.5rem .75rem;font-size:.8125rem;font-weight:500;color:var(--text-primary);background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:6px;cursor:pointer;transition:all .2s ease}.astar-visualizer-root .settings-preset-btn:hover{background:var(--primary);border-color:var(--primary);color:#fff}@media (max-width: 768px){.astar-visualizer-root .settings-panel{padding:.75rem 1rem 1rem}.astar-visualizer-root .settings-content{grid-template-columns:1fr;gap:1rem}}@media (max-width: 480px){.astar-visualizer-root .settings-panel{padding:.5rem .75rem .75rem}.astar-visualizer-root .settings-row{flex-direction:column;align-items:flex-start;gap:.5rem}.astar-visualizer-root .settings-toggle-group,.astar-visualizer-root .settings-stepper,.astar-visualizer-root .settings-select{width:100%}.astar-visualizer-root .settings-toggle-btn{flex:1}}
|
package/package.json
CHANGED