UNPKG

carverjs

Version:

A React library for AI-generated interactive games with reinforcement learning support

13 lines 71.8 kB
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var me=require('react'),framerMotion=require('framer-motion'),jsxRuntime=require('react/jsx-runtime');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var me__namespace=/*#__PURE__*/_interopNamespace(me);var oe={x:0,y:0},se={x:0,y:0,z:0},Tt={x:1,y:0},Gt={x:0,y:1},At={x:1,y:0,z:0},Rt={x:0,y:1,z:0},wt={x:0,y:0,z:1},Le=oe,Be=se,xe={position:Le,rotation:{angle:0},scale:{x:1,y:1}},Et={position:Be,rotation:{x:0,y:0,z:0},scale:{x:1,y:1,z:1}},Dt={x:0,y:0,z:0,w:1},Pt={"top-left":{x:0,y:0},"top-center":{x:.5,y:0},"top-right":{x:1,y:0},"middle-left":{x:0,y:.5},"middle-center":{x:.5,y:.5},"middle-right":{x:1,y:.5},"bottom-left":{x:0,y:1},"bottom-center":{x:.5,y:1},"bottom-right":{x:1,y:1}},ve={up:{x:0,y:-1},down:{x:0,y:1},left:{x:-1,y:0},right:{x:1,y:0},forward:{x:0,y:-1},back:{x:0,y:1}},kt={up:{x:0,y:1,z:0},down:{x:0,y:-1,z:0},left:{x:-1,y:0,z:0},right:{x:1,y:0,z:0},forward:{x:0,y:0,z:-1},back:{x:0,y:0,z:1},in:{x:0,y:0,z:-1},out:{x:0,y:0,z:1}},It={DEGREES_TO_RADIANS:Math.PI/180,RADIANS_TO_DEGREES:180/Math.PI,PI:Math.PI,TWO_PI:Math.PI*2,HALF_PI:Math.PI/2,QUARTER_PI:Math.PI/4};function Y(e){return typeof e=="object"&&e!==null&&typeof e.x=="number"&&typeof e.y=="number"}function Se(e){return typeof e=="object"&&e!==null&&typeof e.x=="number"&&typeof e.y=="number"&&typeof e.z=="number"}function Ot(e){return typeof e=="object"&&e!==null&&typeof e.x=="number"&&typeof e.y=="number"&&typeof e.width=="number"&&typeof e.height=="number"}function Nt(e){return typeof e=="object"&&e!==null&&Y(e.position)&&typeof e.rotation=="object"&&typeof e.scale=="object"}function Vt(e){return typeof e=="object"&&e!==null&&Y(e.min)&&Y(e.max)}var Mt="1.0.0",_t="2025-01-25";var Fe={minScenes:3,maxScenes:20,estimatedTimePerScene:4,requiredElements:[],optionalElements:[],supportedAudiences:["beginner","intermediate","advanced"],version:"1.0.0"},ze={maxScenes:15,maxPlayTime:30,mustIncludeAssessments:false,allowBranching:true,difficultyProgression:"linear",contentComplexity:"moderate",maxTokensPerRequest:4e3,generationTimeLimit:3e5},Lt={estimatedDuration:3,difficulty:"medium",learningObjectives:[],prerequisites:[],tags:[]},Ue={learningStyle:"mixed",pace:"moderate",tone:"casual",language:"en"},Bt={contentCoverage:0,engagementScore:0,educationalEffectiveness:0,flowCoherence:0,technicalQuality:0,accessibilityScore:0,overallScore:0},Ft=["choice","input","click","drag","quiz","simulation","mini-game","gesture","voice","custom"],zt=["image","video","audio","animation","interactive","3d-model","particle-system"],Qe=["narrative","simulation","puzzle","rpg","quiz","adventure","strategy","arcade","educational","sandbox","platformer","action"],qe=["text","markdown","html","video","audio","image","interactive","simulation","assessment"],He=["easy","medium","hard","expert"],$e=["beginner","intermediate","advanced","expert"],Ye=["image","audio","video","font","texture","3d-model","animation","shader","data","script","style","manifest"],Ut=["web","mobile","desktop","console","vr","ar"],Qt=["keyboard","mouse","touch","gamepad","voice","gesture","eye-tracking","motion-controller"],ce={POOR:.3,FAIR:.5,GOOD:.7,EXCELLENT:.9},qt={LOADING_TIME_MS:3e3,MEMORY_USAGE_MB:100,FRAME_RATE_FPS:60,ASSET_SIZE_LIMIT_MB:50},Ht=["WCAG-2.1-A","WCAG-2.1-AA","WCAG-2.1-AAA","Section-508","EN-301-549"],$t=["linear","ease","ease-in","ease-out","ease-in-out","cubic-bezier","spring","bounce"],Yt=["fade","slide","zoom","flip","dissolve","wipe","custom"],jt=["ESRB","PEGI","CERO","USK","OFLC","custom"];function Xt(e){return typeof e=="object"&&e!==null&&typeof e.id=="string"&&typeof e.name=="string"&&typeof e.category=="string"&&typeof e.minScenes=="number"&&typeof e.maxScenes=="number"&&Array.isArray(e.requiredElements)&&Array.isArray(e.optionalElements)&&Array.isArray(e.supportedAudiences)}function Kt(e){return typeof e=="object"&&e!==null&&typeof e.contentId=="string"&&typeof e.gameType=="string"&&typeof e.targetAudience=="string"&&typeof e.learningContent=="object"&&typeof e.constraints=="object"}function Zt(e){return typeof e=="object"&&e!==null&&typeof e.id=="string"&&typeof e.gameType=="string"&&typeof e.title=="string"&&Array.isArray(e.scenes)&&typeof e.flow=="object"&&typeof e.metadata=="object"}function Wt(e){return typeof e=="object"&&e!==null&&typeof e.id=="string"&&typeof e.type=="string"&&typeof e.title=="string"&&typeof e.description=="string"&&typeof e.content=="object"&&Array.isArray(e.interactions)&&Array.isArray(e.transitions)&&typeof e.metadata=="object"}function Jt(e){return typeof e=="object"&&e!==null&&typeof e.contentId=="string"&&typeof e.title=="string"&&typeof e.description=="string"&&Array.isArray(e.modules)&&Array.isArray(e.chunks)}function en(e){return typeof e=="object"&&e!==null&&typeof e.isValid=="boolean"&&Array.isArray(e.errors)&&Array.isArray(e.warnings)}function tn(e){return typeof e=="object"&&e!==null&&typeof e.startSceneId=="string"&&Array.isArray(e.endSceneIds)&&Array.isArray(e.paths)&&Array.isArray(e.breakpoints)&&Array.isArray(e.continuityElements)}function nn(e){return typeof e=="object"&&e!==null&&typeof e.id=="string"&&typeof e.type=="string"&&typeof e.prompt=="string"}function rn(e){return typeof e=="object"&&e!==null&&typeof e.id=="string"&&typeof e.name=="string"&&typeof e.type=="string"&&typeof e.url=="string"}function an(e){return typeof e=="object"&&e!==null&&typeof e.contentCoverage=="number"&&typeof e.engagementScore=="number"&&typeof e.educationalEffectiveness=="number"&&typeof e.flowCoherence=="number"&&typeof e.technicalQuality=="number"&&typeof e.accessibilityScore=="number"&&typeof e.overallScore=="number"}function Te(e,t,n){return {id:e,name:t,category:n,description:`Default configuration for ${t} game type`,...Fe}}function on(e){return {...ze,...e}}function sn(e){return {...Ue,...e}}function le(e){return He.includes(e)}function cn(e){return $e.includes(e)}function ln(e){return Qe.includes(e)}function dn(e){return qe.includes(e)}function un(e){return Ye.includes(e)}function Ge(e){let t={contentCoverage:.2,engagementScore:.2,educationalEffectiveness:.2,flowCoherence:.15,technicalQuality:.15,accessibilityScore:.1};return e.contentCoverage*t.contentCoverage+e.engagementScore*t.engagementScore+e.educationalEffectiveness*t.educationalEffectiveness+e.flowCoherence*t.flowCoherence+e.technicalQuality*t.technicalQuality+e.accessibilityScore*t.accessibilityScore}function mn(e){return e<ce.POOR?"poor":e<ce.FAIR?"fair":e<ce.GOOD?"good":"excellent"}function pn(e){return e.reduce((t,n)=>t+n.metadata.estimatedDuration,0)}function gn(e){let t={easy:0,medium:0,hard:0,expert:0};return e.forEach(n=>{t[n.metadata.difficulty]++;}),t}function yn(e,t){if(e.modules.length===0)return 0;let n=new Set;return t.forEach(r=>{r.metadata.relatedChunks?.forEach(i=>{let o=e.chunks.find(a=>a.id===i);o&&n.add(o.moduleId);});}),n.size/e.modules.length}function de(e){let t=Date.now().toString(36),n=Math.random().toString(36).substring(2,8);return e?`${e}-${t}-${n}`:`${t}-${n}`}function Ce(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(e instanceof Array)return e.map(t=>Ce(t));if(typeof e=="object"){let t={};for(let n in e)e.hasOwnProperty(n)&&(t[n]=Ce(e[n]));return t}return e}function je(e,t){let n={...e};for(let r in t)if(t.hasOwnProperty(r)){let i=t[r],o=n[r];i&&o&&typeof i=="object"&&typeof o=="object"&&!Array.isArray(i)&&!Array.isArray(o)?n[r]=je(o,i):n[r]=i;}return n}function fn(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").substring(0,50)}function bn(e){if(e<1)return "< 1 min";if(e<60)return `${Math.round(e)} min`;let t=Math.floor(e/60),n=Math.round(e%60);return n===0?`${t}h`:`${t}h ${n}m`}function hn(e){if(e.length<2)return 1;let t={easy:1,medium:2,hard:3,expert:4},n=0;for(let r=1;r<e.length;r++){let i=t[e[r-1].metadata.difficulty],a=t[e[r].metadata.difficulty]-i;a>=0&&a<=1?n+=1:a<0?n+=.5:n+=.2;}return n/(e.length-1)}var xn="1.0.0",vn="2025-01-25",Sn=["Game Development Community"],Cn={"1.0.0":{backwardCompatible:[],forwardCompatible:[],breaking:[]}};var A={create:(e,t)=>({x:e,y:t}),add:(e,t)=>({x:e.x+t.x,y:e.y+t.y}),subtract:(e,t)=>({x:e.x-t.x,y:e.y-t.y}),multiply:(e,t)=>({x:e.x*t,y:e.y*t}),distance:(e,t)=>Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)),equals:(e,t)=>e.x===t.x&&e.y===t.y,clone:e=>({x:e.x,y:e.y})},ue={up:{x:0,y:-1},down:{x:0,y:1},left:{x:-1,y:0},right:{x:1,y:0}},Tn={gridSize:32,animationSpeed:300,debugMode:false,maxEpisodes:1e3,frameRate:60,enableCollisions:true,theme:{},customConfig:{}},N={startPosition:{x:0,y:0},sprite:"",color:"#4CAF50",speed:1,health:1,inventorySize:10,metadata:{}},Gn=(e,t)=>({label:t||e.type,type:e.type,...e.metadata?.description?{description:e.metadata.description}:{},...e.metadata?.effect?{effect:e.metadata.effect}:{},...e.target&&{target:e.target},...e.payload!==void 0&&{value:e.payload},...e.metadata&&{metadata:e.metadata}}),An=(e,t)=>({label:e,type:t?.type||"custom",...t?.description&&{description:t.description},...t?.effect&&{effect:t.effect},...t?.target&&{target:t.target},...t?.value!==void 0&&{value:t.value},metadata:t?.metadata||{}}),Rn={bounce:{initial:{y:20,opacity:0},animate:{y:0,opacity:1,transition:{type:"spring",stiffness:300,damping:20}},hover:{y:-2,transition:{type:"spring",stiffness:400}}},slide:{initial:{x:-20,opacity:0},animate:{x:0,opacity:1,transition:{type:"spring",stiffness:250,damping:25}},hover:{x:2,transition:{type:"spring",stiffness:400}}},fade:{initial:{opacity:0},animate:{opacity:1,transition:{duration:.3,ease:"easeOut"}},hover:{opacity:.8,transition:{duration:.2}}},zoom:{initial:{scale:.9,opacity:0},animate:{scale:1,opacity:1,transition:{type:"spring",stiffness:300,damping:25}},hover:{scale:1.05,transition:{type:"spring",stiffness:400}}},rotate:{initial:{rotate:-5,opacity:0},animate:{rotate:0,opacity:1,transition:{type:"spring",stiffness:300,damping:25}},hover:{rotate:1,transition:{type:"spring",stiffness:400}}},custom:{initial:{scale:1,opacity:0},animate:{scale:1,opacity:1},hover:{scale:1.02}}},Xe=e=>({startPosition:e?.startPosition||N.startPosition,sprite:e?.sprite??N.sprite,color:e?.color||N.color,speed:e?.speed||N.speed,health:e?.health||N.health,inventorySize:e?.inventorySize||N.inventorySize,metadata:e?.metadata||N.metadata}),wn=(e,t,n)=>({id:e,name:t,width:n?.width||10,height:n?.height||10,entities:n?.entities||[],player:Xe(n?.player),objectives:n?.objectives||[],...n?.background&&{background:n.background},...n?.transitions&&{transitions:n.transitions},...n?.config&&{config:n.config},...n?.metadata&&{metadata:n.metadata}}),En=(e,t,n,r)=>({id:e,type:t,position:n,...r?.sprite&&{sprite:r.sprite},...r?.color&&{color:r.color},...r?.behavior&&{behavior:r.behavior},isCollidable:r?.isCollidable??true,isVisible:r?.isVisible??true,isActive:r?.isActive??true,...r?.metadata&&{metadata:r.metadata},...r?.zIndex!==void 0&&{zIndex:r.zIndex}});var J={isValidPosition:(e,t,n)=>e.x>=0&&e.x<t&&e.y>=0&&e.y<n,isValidEntity:e=>!!(e.id&&e.type&&e.position),isValidScene:e=>!!(e.id&&e.width>0&&e.height>0),isValidGameModel:e=>!!(e.id&&e.scenes.length>0&&e.initialScene)},Ae={isVector2D:e=>typeof e=="object"&&e!==null&&typeof e.x=="number"&&typeof e.y=="number",isGameEntity:e=>typeof e=="object"&&e!==null&&typeof e.id=="string"&&typeof e.type=="string"&&Ae.isVector2D(e.position),isGameAction:e=>typeof e=="object"&&e!==null&&typeof e.type=="string"},B=class{constructor(t,n={},r=1e3){this.validateGameModel(t),this.gameModel=t,this.eventCallbacks=n,this.actionHistory=[],this.stateHistory=[],this.maxHistorySize=r,this.currentState=this.initializeGameState();}executeAction(t,n="human"){try{this.validateAction(t),this.addToHistory(this.currentState,t);let r=this.processAction(this.currentState,t);return this.currentState=r,this.eventCallbacks.onAction?.(t,n),this.eventCallbacks.onStateChange?.(r),r.isGameOver&&this.eventCallbacks.onGameOver?.(r),this.checkSceneTransitions(r),r}catch(r){throw this.eventCallbacks.onError?.(r),r}}getCurrentState(){return this.cloneState(this.currentState)}reset(){return this.actionHistory=[],this.stateHistory=[],this.currentState=this.initializeGameState(),this.eventCallbacks.onStateChange?.(this.currentState),this.cloneState(this.currentState)}getActionHistory(){return [...this.actionHistory]}getStateHistory(){return [...this.stateHistory]}undo(){if(this.stateHistory.length<2)return null;this.stateHistory.pop(),this.actionHistory.pop();let t=this.stateHistory[this.stateHistory.length-1];return this.currentState=this.cloneState(t),this.eventCallbacks.onStateChange?.(this.currentState),this.cloneState(this.currentState)}isValidPosition(t){let n=this.getCurrentScene();return J.isValidPosition(t,n.width,n.height)?!this.hasCollision(t):false}getAvailableActions(){let t=[],n=this.currentState.playerPosition;return ["up","down","left","right"].forEach(i=>{let o=A.add(n,ue[i]);this.isValidPosition(o)&&t.push({type:"move",direction:i,timestamp:Date.now()});}),this.getNearbyEntities(n).forEach(i=>{(i.type==="collectible"||i.type==="portal")&&t.push({type:"interact",target:i.id,timestamp:Date.now()});}),t}calculateStepResult(t,n,r){let i=this.calculateReward(t,n,r),o=r.isGameOver||this.allObjectivesCompleted(r);return {nextState:r,reward:i,done:o,info:{action:n,scoreChange:r.score-t.score,healthChange:r.playerHealth-t.playerHealth,objectivesCompleted:this.getCompletedObjectives(r).length}}}initializeGameState(){let t=this.gameModel.scenes.find(r=>r.id===this.gameModel.initialScene);if(!t)throw new Error(`Initial scene '${this.gameModel.initialScene}' not found`);let n={...N,...t.player};return {currentScene:t.id,playerPosition:A.clone(n.startPosition),entities:t.entities.map(r=>({...r})),score:0,episode:1,isGameOver:false,objectives:t.objectives.map(r=>({...r,isCompleted:false})),inventory:[],playerHealth:n.health,gameTime:0,metadata:{},stateHash:this.generateStateHash(t.id,n.startPosition,0)}}processAction(t,n){let r=this.cloneState(t);switch(n.type){case "move":r=this.processMovement(r,n);break;case "interact":r=this.processInteraction(r,n);break;case "reset":return this.initializeGameState();default:r=this.processCustomAction(r,n);}return r={...r,gameTime:r.gameTime+1,stateHash:this.generateStateHash(r.currentScene,r.playerPosition,r.gameTime)},r=this.processEntityBehaviors(r),r=this.checkObjectives(r),r=this.checkGameOverConditions(r),r}processMovement(t,n){if(!n.direction)throw new Error("Movement action requires direction");let r=t.playerPosition,i=ue[n.direction],o=A.add(r,i);if(!this.isValidPosition(o))return t;let a=t.entities.find(g=>g.type==="collectible"&&A.equals(g.position,o)),d={...t,playerPosition:o};return a&&(d=this.collectEntity(d,a)),d}processInteraction(t,n){if(!n.target)throw new Error("Interaction action requires target entity ID");let r=t.entities.find(a=>a.id===n.target);if(!r||A.distance(t.playerPosition,r.position)>1.5)return t;let o=t;switch(r.type){case "collectible":o=this.collectEntity(o,r);break;case "portal":o=this.processPortal(o,r);break;case "enemy":o=this.processEnemyInteraction(o,r);break;default:if(r.behavior?.onCollision){let a={id:"player",type:"player",position:t.playerPosition};try{let d=r.behavior.onCollision(a,r);Array.isArray(d)&&d.length>0&&(o=d.reduce((T,w)=>this.processAction(T,w),o));}catch(d){console.warn("Error in entity onCollision behavior:",d);}}}return o}collectEntity(t,n){return {...t,entities:t.entities.filter(r=>r.id!==n.id),inventory:[...t.inventory,n.id],score:t.score+(n.metadata?.points||10)}}processPortal(t,n){let r=n.metadata?.targetScene;if(!r)return t;let i=this.gameModel.scenes.find(a=>a.id===r);if(!i)return t;this.eventCallbacks.onSceneChange?.(t.currentScene,r);let o={...N,...i.player};return {...t,currentScene:r,playerPosition:A.clone(o.startPosition),entities:i.entities.map(a=>({...a})),objectives:[...t.objectives,...i.objectives.map(a=>({...a,isCompleted:false}))]}}processEnemyInteraction(t,n){let r=n.metadata?.damage||1,i=Math.max(0,t.playerHealth-r);return {...t,playerHealth:i,isGameOver:i<=0}}processCustomAction(t,n){return t}processEntityBehaviors(t){let n={...t};return n.entities=n.entities.map(r=>{if(r.behavior?.onUpdate&&r.isActive!==false)try{let i=r.behavior.onUpdate(r,1);if(i!==void 0&&typeof i=="object"&&i!==null&&!Array.isArray(i))return {...r,...i}}catch(i){console.warn("Error in entity onUpdate behavior:",i);}return r}),n}checkObjectives(t){let n=t.objectives.map(r=>{if(r.isCompleted)return r;let i=false;switch(r.type){case "collect":i=t.inventory.includes(r.target||"");break;case "reach":let o=t.entities.find(d=>d.id===r.target);o&&(i=A.equals(t.playerPosition,o.position));break;case "score":let a=r.target?parseInt(r.target):100;i=t.score>=a;break;case "custom":i=r.condition?r.condition(t):false;break}return i&&!r.isCompleted?(this.eventCallbacks.onObjectiveComplete?.(r),{...r,isCompleted:true}):r});return {...t,objectives:n}}checkGameOverConditions(t){if(t.isGameOver)return t;if(t.playerHealth<=0)return {...t,isGameOver:true};let n=t.objectives.filter(i=>i.isRequired!==false);return n.length>0&&n.every(i=>i.isCompleted)?{...t,isGameOver:true}:t}calculateReward(t,n,r){let i=0;i+=r.score-t.score,i+=(r.playerHealth-t.playerHealth)*10;let o=this.getCompletedObjectives(r).length,a=this.getCompletedObjectives(t).length;return i+=(o-a)*100,i-=1,r.isGameOver&&r.playerHealth<=0&&(i-=100),r.isGameOver&&this.allObjectivesCompleted(r)&&(i+=1e3),i}hasCollision(t){return this.currentState.entities.some(n=>n.isCollidable!==false&&n.type!=="collectible"&&A.equals(n.position,t))}getNearbyEntities(t,n=1.5){return this.currentState.entities.filter(r=>A.distance(t,r.position)<=n)}getCurrentScene(){let t=this.gameModel.scenes.find(n=>n.id===this.currentState.currentScene);if(!t)throw new Error(`Scene '${this.currentState.currentScene}' not found`);return t}getCompletedObjectives(t){return t.objectives.filter(n=>n.isCompleted)}allObjectivesCompleted(t){let n=t.objectives.filter(r=>r.isRequired!==false);return n.length>0&&n.every(r=>r.isCompleted)}checkSceneTransitions(t){let n=this.getCurrentScene();if(n.transitions)for(let r of n.transitions){let i=false;if(typeof r.trigger=="string"){let o=t.entities.find(a=>a.id===r.trigger);i=!o||A.equals(t.playerPosition,o.position);}else i=r.trigger(t);if(i){this.eventCallbacks.onSceneChange?.(t.currentScene,r.targetScene);break}}}cloneState(t){return {...t,entities:t.entities.map(n=>({...n})),objectives:t.objectives.map(n=>({...n})),inventory:[...t.inventory],metadata:{...t.metadata}}}generateStateHash(t,n,r){return `${t}_${n.x}_${n.y}_${r}`}addToHistory(t,n){this.stateHistory.push(this.cloneState(t)),this.actionHistory.push({...n}),this.stateHistory.length>this.maxHistorySize&&(this.stateHistory.shift(),this.actionHistory.shift());}validateGameModel(t){if(!J.isValidGameModel(t))throw new Error("Invalid game model provided to GameEngine")}validateAction(t){if(!Ae.isGameAction(t))throw new Error("Invalid game action provided to GameEngine")}};function Dn(e,t,n){return new B(e,t,n)}var Pn={maxStepsPerEpisode:1e3,rewardFunction:(e,t,n)=>kn(e,t,n),stateEncoding:"grid",actionSpace:"discrete",deterministic:false,seed:Math.floor(Math.random()*1e6),observationShape:[10,10,4],enableActionMasking:true},j=class{constructor(t,n={}){this.gameModel=t,this.config={...Pn,...n},this.gameEngine=new B(t),this.stepCount=0,this.episodeNumber=0,this.isInitialized=false,this.actionSpace=this.computeActionSpace(),this.observationSpace=this.computeObservationSpace(),this.currentState=this.gameEngine.getCurrentState(),this.isInitialized=true;}reset(){this.currentState=this.gameEngine.reset(),this.stepCount=0,this.episodeNumber++;let t=this.encodeState(this.currentState),n=this.getEnvInfo(false);return {observation:t,info:n}}step(t){if(!this.isInitialized)throw new Error("Environment not initialized. Call reset() first.");this.stepCount++;let n=typeof t=="number"?this.actionSpace[t]:t;if(!n)throw new Error(`Invalid action: ${t}`);let r=this.cloneState(this.currentState);try{this.currentState=this.gameEngine.executeAction(n,"agent");}catch(T){return console.warn("Invalid action attempted:",n,T),{observation:this.encodeState(this.currentState),reward:-10,terminated:false,truncated:false,info:this.getEnvInfo(false)}}let i=this.config.rewardFunction(r,n,this.currentState),o=this.isTerminated(),a=this.isTruncated(),d=this.encodeState(this.currentState),g=this.getEnvInfo(a);return {observation:d,reward:i,terminated:o,truncated:a,info:g}}getObservation(){return this.encodeState(this.currentState)}getActionSpace(){return {type:this.config.actionSpace,shape:[this.actionSpace.length],actions:[...this.actionSpace]}}getObservationSpace(){return {shape:this.observationSpace,type:"box",low:0,high:1}}getActionMask(){if(!this.config.enableActionMasking)return new Array(this.actionSpace.length).fill(true);let t=this.gameEngine.getAvailableActions();return this.actionSpace.map(n=>t.some(r=>this.actionsEqual(n,r)))}render(t="human"){return t==="human"?this.renderHuman():this.renderRgbArray()}getGameState(){return this.cloneState(this.currentState)}getCurrentScene(){return this.gameModel.scenes.find(t=>t.id===this.currentState.currentScene)||null}calculateDistanceReward(t,n,r=10){let i=A.distance(t,n);return Math.max(0,(r-i)/r)}isValidPosition(t){let n=this.getCurrentScene();return n?t.x>=0&&t.x<n.width&&t.y>=0&&t.y<n.height:false}getAvailableActions(){return this.gameEngine.getAvailableActions()}setConfig(t){this.config={...this.config,...t},t.rewardFunction&&(this.config.rewardFunction=t.rewardFunction);}exportState(){return {gameState:this.cloneState(this.currentState),stepCount:this.stepCount,episodeNumber:this.episodeNumber,config:this.config}}importState(t){this.currentState=this.cloneState(t.gameState),this.stepCount=t.stepCount,this.episodeNumber=t.episodeNumber,t.config&&this.setConfig(t.config);}encodeState(t){switch(this.config.stateEncoding){case "grid":return this.encodeGridState(t);case "vector":return this.encodeVectorState(t);case "custom":return this.encodeCustomState(t);default:return this.encodeGridState(t)}}encodeGridState(t){if(!this.getCurrentScene())return [];let[r,i,o]=this.config.observationShape,a=new Array(r*i*o).fill(0),d=t.playerPosition.y*r+t.playerPosition.x;return d>=0&&d<r*i&&(a[d]=1),t.entities.forEach(g=>{let T=g.position.y*r+g.position.x;if(T>=0&&T<r*i){let w=3;g.type==="obstacle"||g.type==="wall"?w=1:g.type==="collectible"&&(w=2);let p=w*r*i+T;p<a.length&&(a[p]=1);}}),a}encodeVectorState(t){let n=[],r=this.getCurrentScene();r?(n.push(t.playerPosition.x/r.width),n.push(t.playerPosition.y/r.height)):n.push(0,0),n.push(Math.min(t.score/1e3,1)),n.push(t.playerHealth/100),n.push(t.gameTime/1e3);let i=t.objectives.filter(a=>a.isCompleted).length;n.push(t.objectives.length>0?i/t.objectives.length:0);let o={obstacle:0,collectible:0,enemy:0,portal:0};return t.entities.forEach(a=>{a.type in o&&o[a.type]++;}),n.push(...Object.values(o).map(a=>Math.min(a/10,1))),n}encodeCustomState(t){return this.encodeVectorState(t)}computeActionSpace(){let t=[];return ["up","down","left","right"].forEach(n=>{t.push({type:"move",direction:n,timestamp:Date.now()});}),t.push({type:"interact",timestamp:Date.now()}),t.push({type:"reset",timestamp:Date.now()}),t}computeObservationSpace(){switch(this.config.stateEncoding){case "grid":return this.config.observationShape;case "vector":return [13];case "custom":return this.config.observationShape;default:return this.config.observationShape}}isTerminated(){return this.currentState.isGameOver}isTruncated(){return this.stepCount>=this.config.maxStepsPerEpisode}getEnvInfo(t){return {stepCount:this.stepCount,episodeNumber:this.episodeNumber,truncated:t,metadata:{scene:this.currentState.currentScene,score:this.currentState.score,health:this.currentState.playerHealth,objectivesCompleted:this.currentState.objectives.filter(n=>n.isCompleted).length,totalObjectives:this.currentState.objectives.length}}}renderHuman(){let t=this.getCurrentScene();if(!t)return "No current scene";let n=`=== Episode ${this.episodeNumber}, Step ${this.stepCount} === `;n+=`Scene: ${t.name} `,n+=`Score: ${this.currentState.score}, Health: ${this.currentState.playerHealth} `,n+=`Player: (${this.currentState.playerPosition.x}, ${this.currentState.playerPosition.y}) `;let r=[];for(let i=0;i<t.height;i++)r[i]=new Array(t.width).fill(".");return this.currentState.entities.forEach(i=>{if(i.isVisible!==false){let o=i.type==="obstacle"?"#":i.type==="collectible"?"$":i.type==="enemy"?"E":i.type==="portal"?"P":"?";r[i.position.y][i.position.x]=o;}}),r[this.currentState.playerPosition.y][this.currentState.playerPosition.x]="@",n+=` `,r.forEach(i=>{n+=i.join(" ")+` `;}),n}renderRgbArray(){let t=this.getCurrentScene();if(!t)return [];let n=[];for(let r=0;r<t.height;r++)for(let i=0;i<t.width;i++){let o=[240,240,240],a=this.currentState.entities.find(d=>d.position.x===i&&d.position.y===r&&d.isVisible!==false);if(a)switch(a.type){case "obstacle":case "wall":o=[255,0,0];break;case "collectible":o=[255,255,0];break;case "enemy":o=[255,100,0];break;case "portal":o=[128,0,255];break}this.currentState.playerPosition.x===i&&this.currentState.playerPosition.y===r&&(o=[0,255,0]),n.push(...o);}return n}actionsEqual(t,n){return t.type===n.type&&t.direction===n.direction&&t.target===n.target}cloneState(t){return {...t,entities:t.entities.map(n=>({...n})),objectives:t.objectives.map(n=>({...n})),inventory:[...t.inventory],metadata:{...t.metadata}}}};function kn(e,t,n){let r=0;r+=n.score-e.score,r+=(n.playerHealth-e.playerHealth)*10;let i=n.objectives.filter(a=>a.isCompleted).length,o=e.objectives.filter(a=>a.isCompleted).length;return r+=(i-o)*100,r-=1,n.isGameOver&&(n.playerHealth<=0?r-=100:r+=1e3),r}function In(e,t="training",n){let i={...{training:{maxStepsPerEpisode:1e3,stateEncoding:"grid",deterministic:false,enableActionMasking:true},evaluation:{maxStepsPerEpisode:2e3,stateEncoding:"grid",deterministic:true,enableActionMasking:false},debug:{maxStepsPerEpisode:100,stateEncoding:"vector",deterministic:true,enableActionMasking:true},custom:{}}[t],...n};return new j(e,i)}var Nn=({onAction:e,disabled:t,availableActions:n})=>{me.useEffect(()=>{if(t||n.length===0)return;let r=i=>{if(document.activeElement?.tagName==="INPUT"||document.activeElement?.tagName==="TEXTAREA")return;let o=i.key.toLowerCase(),a=null;switch(o){case "arrowup":case "w":a={type:"move",direction:"up",timestamp:Date.now()};break;case "arrowdown":case "s":a={type:"move",direction:"down",timestamp:Date.now()};break;case "arrowleft":case "a":a={type:"move",direction:"left",timestamp:Date.now()};break;case "arrowright":case "d":a={type:"move",direction:"right",timestamp:Date.now()};break;case " ":case "enter":a={type:"interact",timestamp:Date.now()};break;case "r":a={type:"reset",timestamp:Date.now()};break;case "1":case "2":case "3":case "4":case "5":let d=parseInt(o)-1;d<n.length&&(a=n[d]);break}a&&(i.preventDefault(),e(a));};return window.addEventListener("keydown",r),()=>window.removeEventListener("keydown",r)},[e,t,n]);},Ze=({gameState:e,gameMode:t,isPlaying:n,onPlay:r,onPause:i,onReset:o,onUndo:a,canUndo:d=false,playbackSpeed:g,onSpeedChange:T})=>jsxRuntime.jsx("div",{className:"game-controls bg-white dark:bg-gray-800 p-4 rounded-lg shadow-lg border",children:jsxRuntime.jsxs("div",{className:"flex items-center gap-4",children:[jsxRuntime.jsx("button",{onClick:n?i:r,className:"px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors",disabled:t==="manual",children:n?"\u23F8\uFE0F Pause":"\u25B6\uFE0F Play"}),jsxRuntime.jsx("button",{onClick:o,className:"px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700 transition-colors",children:"\u{1F504} Reset"}),a&&jsxRuntime.jsx("button",{onClick:a,disabled:!d,className:"px-4 py-2 bg-yellow-600 text-white rounded hover:bg-yellow-700 transition-colors disabled:opacity-50",children:"\u21B6 Undo"}),t!=="manual"&&jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsx("label",{className:"text-sm font-medium",children:"Speed:"}),jsxRuntime.jsxs("select",{value:g,onChange:w=>T(Number(w.target.value)),className:"px-2 py-1 border rounded dark:bg-gray-700 dark:border-gray-600",children:[jsxRuntime.jsx("option",{value:.5,children:"0.5x"}),jsxRuntime.jsx("option",{value:1,children:"1x"}),jsxRuntime.jsx("option",{value:2,children:"2x"}),jsxRuntime.jsx("option",{value:5,children:"5x"}),jsxRuntime.jsx("option",{value:10,children:"10x"})]})]}),jsxRuntime.jsxs("div",{className:"ml-auto text-sm text-gray-600 dark:text-gray-400",children:[jsxRuntime.jsxs("div",{children:["Score: ",e.score]}),jsxRuntime.jsxs("div",{children:["Health: ",e.playerHealth]}),jsxRuntime.jsxs("div",{children:["Time: ",e.gameTime]})]})]})}),Re=({gameModel:e,mode:t="manual",agent:n,renderingMode:r="grid",showOverlay:i=false,autoPlay:o=false,playbackSpeed:a=1,className:d="",onAction:g,onStateChange:T,onGameOver:w,onTrainingMetrics:p,enableAnimations:D=true,animationDuration:I=300,canvasSettings:E={enableDemoEntities:true,demoEntityCount:3,enablePhysics:true,showFPS:false}})=>{let[G]=me.useState(()=>new B(e)),[y,O]=me.useState(()=>G.getCurrentState()),[z,L]=me.useState("human"),[ne,re]=me.useState(o&&t==="agentOnly"),[Z,Ie]=me.useState(false),[k,Oe]=me.useState([]),[pe,Ne]=me.useState(a),q=me.useRef(null),$=me.useRef(),Ve=me.useRef(0),[ge,gt]=me.useState(0),[H,ye]=me.useState([]),W=me.useRef(),fe=me.useRef(),ie=me.useCallback(()=>{if(!q.current||r!=="canvas")return;let s=q.current;if(!s.getContext("2d"))return;let c=e.scenes.find(x=>x.id===y.currentScene);if(!c)return;let u=e.config.gridSize||32,h=c.width*u,v=c.height*u;if(s.width=h,s.height=v,E.enableDemoEntities&&y.entities.length===0){let x=[];for(let b=0;b<(E.demoEntityCount||3);b++)x.push({id:`demo-${b}`,type:"demo",position:{x:Math.random()*(h-40)+20,y:Math.random()*(v-40)+20},velocity:{x:(Math.random()-.5)*4,y:(Math.random()-.5)*4},size:{x:20+Math.random()*20,y:20+Math.random()*20},color:`hsl(${Math.random()*360}, 70%, 60%)`,rotation:0,scale:1,isVisible:true});ye(x);}},[r,e,y,E]),ae=me.useCallback((s,m)=>{if(m.isVisible===false)return;s.save(),s.fillStyle=m.color||Vn(m.type);let c=m,u=c.size||{x:e.config.gridSize||32,y:e.config.gridSize||32};if(s.translate(m.position.x+u.x/2,m.position.y+u.y/2),c.rotation&&s.rotate(c.rotation),c.scale&&s.scale(c.scale,c.scale),s.translate(-u.x/2,-u.y/2),m.sprite)s.fillRect(0,0,u.x,u.y);else switch(m.type){case "demo":s.beginPath(),s.arc(u.x/2,u.y/2,Math.min(u.x,u.y)/2,0,Math.PI*2),s.fill();break;case "collectible":s.beginPath(),s.moveTo(u.x/2,0),s.lineTo(u.x,u.y/2),s.lineTo(u.x/2,u.y),s.lineTo(0,u.y/2),s.closePath(),s.fill();break;case "enemy":s.beginPath(),s.moveTo(u.x/2,0),s.lineTo(u.x,u.y),s.lineTo(0,u.y),s.closePath(),s.fill();break;default:s.fillRect(0,0,u.x,u.y);break}s.restore();},[e.config.gridSize]),Me=me.useCallback((s,m,c,u)=>{if(!s.velocity||!E.enablePhysics)return s;let h=s.size||{x:32,y:32},v={x:s.position.x+s.velocity.x*m*60,y:s.position.y+s.velocity.y*m*60},x={...s.velocity};return (v.x<=0||v.x+h.x>=c)&&(x.x=-x.x,v.x=Math.max(0,Math.min(c-h.x,v.x))),(v.y<=0||v.y+h.y>=u)&&(x.y=-x.y,v.y=Math.max(0,Math.min(u-h.y,v.y))),{...s,position:v,velocity:x,rotation:(s.rotation||0)+.02,scale:1+Math.sin(Date.now()*.001)*.1}},[E.enablePhysics]),be=me.useCallback(s=>{if(!q.current||r!=="canvas")return;let m=q.current,c=m.getContext("2d");if(!c)return;let u=(s-Ve.current)/1e3;Ve.current=s,E.showFPS&&gt(Math.round(1/u)),c.clearRect(0,0,m.width,m.height);let h=e.scenes.find(b=>b.id===y.currentScene);if(h?.background)c.fillStyle=h.background,c.fillRect(0,0,m.width,m.height);else {let b=c.createLinearGradient(0,0,0,m.height);b.addColorStop(0,"#f8fafc"),b.addColorStop(1,"#e2e8f0"),c.fillStyle=b,c.fillRect(0,0,m.width,m.height);}if(e.config.debugMode){let b=e.config.gridSize||32;c.strokeStyle="rgba(0,0,0,0.1)",c.lineWidth=1;for(let C=0;C<m.width;C+=b)c.beginPath(),c.moveTo(C,0),c.lineTo(C,m.height),c.stroke();for(let C=0;C<m.height;C+=b)c.beginPath(),c.moveTo(0,C),c.lineTo(m.width,C),c.stroke();}E.enableDemoEntities&&(ye(b=>b.map(C=>Me(C,u,m.width,m.height))),H.forEach(b=>{ae(c,b);})),y.entities.forEach(b=>{let C={...b,size:{x:e.config.gridSize||32,y:e.config.gridSize||32}};ae(c,C);});let v=e.config.gridSize||32,x={id:"player",type:"player",position:{x:y.playerPosition.x*v,y:y.playerPosition.y*v},size:{x:v,y:v},color:h?.player.color||"#4CAF50",isVisible:true};ae(c,x),E.showFPS&&(c.fillStyle="rgba(0,0,0,0.7)",c.fillRect(10,10,80,25),c.fillStyle="white",c.font="14px monospace",c.fillText(`FPS: ${ge}`,15,28)),$.current=requestAnimationFrame(be);},[r,e,y,H,ge,E,ae,Me]),yt=me.useMemo(()=>{if(r!=="grid")return null;let s=e.scenes.find(c=>c.id===y.currentScene);if(!s)return null;let m=[];for(let c=0;c<s.height;c++){let u=[];for(let h=0;h<s.width;h++){let v={x:h,y:c},x=y.entities.find(C=>C.position.x===h&&C.position.y===c&&C.isVisible!==false),b=y.playerPosition.x===h&&y.playerPosition.y===c;u.push(jsxRuntime.jsxs(framerMotion.motion.div,{className:` w-8 h-8 border border-gray-200 dark:border-gray-700 flex items-center justify-center cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 ${b?"bg-green-500":""} ${x?`bg-${Mn(x.type)}`:"bg-gray-50 dark:bg-gray-900"} `,onClick:()=>he(v),whileHover:D?{scale:1.05}:{},whileTap:D?{scale:.95}:{},style:{backgroundColor:!b&&x?.color?x.color:void 0},children:[b&&"\u{1F464}",x&&!b&&(x.sprite?jsxRuntime.jsx("img",{src:x.sprite,alt:x.type,className:"w-6 h-6"}):jsxRuntime.jsx("span",{className:"text-xs",children:_n(x.type)}))]},`${h}-${c}`));}m.push(jsxRuntime.jsx("div",{className:"flex",children:u},c));}return m},[r,e,y,D]);me.useEffect(()=>{Ne(a);},[a]);let ft=me.useMemo(()=>G.getAvailableActions(),[G,y]),U=me.useCallback(async(s,m="human")=>{if(!Z){Ie(true);try{let c=G.getCurrentState(),u=G.executeAction(s,m);if(O(u),g?.(s,m),T?.(u),u.isGameOver&&(w?.(u),re(!1)),n&&m==="agent"){let h=G.calculateStepResult(c,s,u);n.learn(h);let v={episode:u.episode,totalReward:h.reward,episodeLength:u.gameTime,averageReward:k.length>0?k.slice(-10).reduce((x,b)=>x+b.totalReward,0)/Math.min(10,k.length):h.reward};Oe(x=>[...x,v]),p?.(v);}t==="vsAgent"&&L(m==="human"?"agent":"human");}finally{fe.current=setTimeout(()=>{Ie(false);},D?I:0);}}},[Z,G,n,t,g,T,w,p,k,D,I]);me.useEffect(()=>{if(!(!ne||!n||Z))return (t==="agentOnly"||t==="vsAgent"&&z==="agent")&&(W.current=setTimeout(()=>{if(!y.isGameOver){let s=n.selectAction(y);U(s,"agent");}},1e3/pe)),()=>{W.current&&clearTimeout(W.current);}},[ne,n,Z,t,z,y,pe,U]),Nn({onAction:s=>U(s,"human"),disabled:Z||t==="vsAgent"&&z==="agent"||t==="agentOnly",availableActions:ft});let bt=me.useCallback(()=>re(true),[]),ht=me.useCallback(()=>re(false),[]),xt=me.useCallback(()=>{let s=G.reset();O(s),L("human"),re(o&&t==="agentOnly"),Oe([]),ye([]),n?.reset(),r==="canvas"&&setTimeout(ie,100);},[G,o,t,n,r,ie]),vt=me.useCallback(()=>{let s=G.undo();s&&O(s);},[G]),he=me.useCallback(s=>{let m=y.playerPosition,c=A.subtract(s,m);if(Math.abs(c.x)+Math.abs(c.y)===1){let u=c.x>0?"right":c.x<0?"left":c.y>0?"down":"up";U({type:"move",direction:u,timestamp:Date.now()},"human");}else {let u=y.entities.find(h=>A.equals(h.position,s));u&&U({type:"interact",target:u.id,timestamp:Date.now()},"human");}},[y,U]),St=me.useCallback(s=>{if(r!=="canvas"||!q.current)return;let c=q.current.getBoundingClientRect(),u=s.clientX-c.left,h=s.clientY-c.top,v=e.config.gridSize||32,x={x:Math.floor(u/v),y:Math.floor(h/v)},b=[...y.entities,...H].find(C=>{let _e=C.size||{x:v,y:v};return u>=C.position.x&&u<=C.position.x+_e.x&&h>=C.position.y&&h<=C.position.y+_e.y});b&&b.id!=="player"?U({type:"interact",target:b.id,timestamp:Date.now()},"human"):he(x);},[r,e.config.gridSize,y.entities,H,U,he]);me.useEffect(()=>{if(r==="canvas")return ie(),$.current=requestAnimationFrame(be),()=>{$.current&&cancelAnimationFrame($.current);}},[r,ie,be]),me.useEffect(()=>()=>{W.current&&clearTimeout(W.current),fe.current&&clearTimeout(fe.current),$.current&&cancelAnimationFrame($.current);},[]);let Ct=e.scenes.find(s=>s.id===y.currentScene);return jsxRuntime.jsxs("div",{className:`carver-game-player ${d}`,children:[jsxRuntime.jsx(Ze,{gameState:y,gameMode:t,isPlaying:ne,onPlay:bt,onPause:ht,onReset:xt,onUndo:vt,canUndo:G.getStateHistory().length>1,playbackSpeed:pe,onSpeedChange:Ne}),jsxRuntime.jsxs("div",{className:"mt-2 mb-4 text-sm text-gray-600 dark:text-gray-400",children:["Rendering: ",jsxRuntime.jsx("span",{className:"font-semibold",children:r.toUpperCase()}),r==="canvas"&&E.showFPS&&jsxRuntime.jsxs("span",{className:"ml-4",children:["FPS: ",ge]})]}),jsxRuntime.jsx("div",{className:"game-display mt-4",children:r==="canvas"?jsxRuntime.jsxs("div",{className:"canvas-container",children:[jsxRuntime.jsx("canvas",{ref:q,onClick:St,className:"border-2 border-gray-300 dark:border-gray-600 rounded cursor-pointer",style:{backgroundColor:"#fff"}}),E.enableDemoEntities&&jsxRuntime.jsxs("div",{className:"mt-2 text-xs text-gray-500 text-center",children:["Canvas Mode - ",H.length," demo entities active"]})]}):jsxRuntime.jsx("div",{className:"game-grid",children:yt})}),jsxRuntime.jsxs("div",{className:"game-info mt-4 text-sm text-gray-600 dark:text-gray-400",children:[jsxRuntime.jsxs("div",{children:["Scene: ",Ct?.name||y.currentScene]}),jsxRuntime.jsxs("div",{children:["Mode: ",t]}),t==="vsAgent"&&jsxRuntime.jsxs("div",{children:["Current Player: ",z]}),jsxRuntime.jsxs("div",{children:["Objectives: ",y.objectives.filter(s=>s.isCompleted).length,"/",y.objectives.length]}),jsxRuntime.jsxs("div",{children:["Entities: ",y.entities.length,r==="canvas"&&H.length>0?` + ${H.length} demo`:""]})]}),i&&k.length>0&&jsxRuntime.jsxs("div",{className:"training-overlay mt-4 p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg",children:[jsxRuntime.jsx("h3",{className:"font-semibold mb-2",children:"Training Metrics"}),jsxRuntime.jsxs("div",{className:"grid grid-cols-2 gap-2 text-sm",children:[jsxRuntime.jsxs("div",{children:["Episode: ",k[k.length-1]?.episode]}),jsxRuntime.jsxs("div",{children:["Total Reward: ",k[k.length-1]?.totalReward]}),jsxRuntime.jsxs("div",{children:["Avg Reward: ",k[k.length-1]?.averageReward?.toFixed(2)]}),jsxRuntime.jsxs("div",{children:["Episode Length: ",k[k.length-1]?.episodeLength]})]})]})]})};function Vn(e){return {obstacle:"#f44336",collectible:"#ffeb3b",enemy:"#ff5722",portal:"#9c27b0",wall:"#424242",demo:"#4CAF50"}[e]||"#9e9e9e"}function Mn(e){return {obstacle:"red-500",collectible:"yellow-500",enemy:"orange-500",portal:"purple-500",wall:"gray-500",demo:"green-500"}[e]||"gray-400"}function _n(e){return {obstacle:"\u{1F6AB}",collectible:"\u{1F48E}",enemy:"\u{1F479}",portal:"\u{1F300}",wall:"\u{1F9F1}",trigger:"\u26A1",demo:"\u25CF"}[e]||"\u2753"}var tt={initial:{scale:1,opacity:0,y:20},animate:{scale:1,opacity:1,y:0,transition:{type:"spring",stiffness:300,damping:30,mass:.8}},hover:{scale:1.02,y:-2,transition:{type:"spring",stiffness:400,damping:20}},tap:{scale:.98,transition:{type:"spring",stiffness:600,damping:25}},disabled:{scale:1,opacity:.6,transition:{duration:.2}},exit:{scale:.95,opacity:0,y:-10,transition:{duration:.15}}},Ln={highlight:{boxShadow:["0 0 0 0 rgba(59, 130, 246, 0.7)","0 0 0 10px rgba(59, 130, 246, 0)","0 0 0 0 rgba(59, 130, 246, 0)"],transition:{duration:.6,ease:"easeOut"}},pulse:{scale:[1,1.05,1],transition:{duration:.4,ease:"easeInOut"}},bounce:{y:[0,-5,0],transition:{duration:.3,ease:"easeInOut"}}},Bn=e=>({small:"px-3 py-2 text-sm",medium:"px-4 py-3 text-base",large:"px-6 py-4 text-lg"})[e||"medium"],Fn=(e,t)=>t?"bg-gray-100 border-gray-200 text-gray-400 cursor-not-allowed dark:bg-gray-800 dark:border-gray-700 dark:text-gray-500":{default:"bg-white hover:bg-gray-50 border-gray-200 hover:border-gray-300 text-gray-900 hover:text-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700 dark:border-gray-600 dark:hover:border-gray-500 dark:text-gray-100 dark:hover:text-white",primary:"bg-blue-600 hover:bg-blue-700 border-blue-600 hover:border-blue-700 text-white dark:bg-blue-500 dark:hover:bg-blue-600",secondary:"bg-gray-600 hover:bg-gray-700 border-gray-600 hover:border-gray-700 text-white dark:bg-gray-500 dark:hover:bg-gray-600",danger:"bg-red-600 hover:bg-red-700 border-red-600 hover:border-red-700 text-white dark:bg-red-500 dark:hover:bg-red-600",success:"bg-green-600 hover:bg-green-700 border-green-600 hover:border-green-700 text-white dark:bg-green-500 dark:hover:bg-green-600"}[e||"default"],we=({action:e,onClick:t,disabled:n=false,size:r="medium",variant:i="default",className:o="",loading:a=false,icon:d,shortcut:g,ariaLabel:T})=>{let w=me.useMemo(()=>{let O="relative w-full text-left rounded-lg border-2 transition-all duration-200 font-medium focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900",z=Bn(r),L=Fn(i,n||a);return `${O} ${z} ${L} ${n||a?"":"shadow-sm hover:shadow-md"} ${o}`.trim()},[r,i,n,a,o]),p=me.useMemo(()=>n||a?{...tt,hover:{},tap:{}}:tt,[n,a]),D=me.useCallback(()=>{!n&&!a&&t();},[t,n,a]),I=me.useCallback(O=>{(O.key==="Enter"||O.key===" ")&&(O.preventDefault(),D());},[D]),E=()=>a?jsxRuntime.jsx(framerMotion.motion.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-4 h-4 border-2 border-current border-t-transparent rounded-full"}):d?jsxRuntime.jsx("span",{className:"w-4 h-4 flex items-center justify-center",children:d}):null,G=()=>g&&!a?jsxRuntime.jsx("span",{className:"text-xs opacity-60 font-mono bg-gray-100 dark:bg-gray-700 px-1.5 py-0.5 rounded",children:g}):null,y=()=>e.effect&&!n&&!a?jsxRuntime.jsxs(framerMotion.motion.div,{className:"text-sm opacity-60 mt-1",initial:{opacity:0,y:-5},animate:{opacity:1,y:0},transition:{delay:.1},children:["Effect: ",e.effect]}):null;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:jsxRuntime.jsxs(framerMotion.motion.button,{className:w,onClick:D,onKeyDown:I,disabled:n||a,variants:p,initial:"initial",animate:n||a?"disabled":"animate",whileHover:!n&&!a?"hover":void 0,whileTap:!n&&!a?"tap":void 0,exit:"exit","aria-label":T||e.label,"aria-disabled":n||a,role:"button",tabIndex:n?-1:0,children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[E(),jsxRuntime.jsx("span",{className:"font-medium",children:e.label})]}),jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[G(),jsxRuntime.jsx(framerMotion.motion.span,{className:"text-xl opacity-70",animate:{x:[0,2,0]},transition:{duration:2,repeat:1/0,ease:"easeInOut"},children:"\u2192"})]})]}),e.description&&jsxRuntime.jsx(framerMotion.motion.div,{className:"text-sm opacity-60 mt-1",initial:{opacity:0,y:-5},animate:{opacity:1,y:0},transition:{delay:.05},children:e.description}),y(),jsxRuntime.jsx(framerMotion.AnimatePresence,{children:a&&jsxRuntime.jsx(framerMotion.motion.div,{className:"absolute inset-0 bg-white/50 dark:bg-gray-800/50 rounded-lg flex items-center justify-center",initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},children:jsxRuntime.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsxRuntime.jsx(framerMotion.motion.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-4 h-4 border-2 border-current border-t-transparent rounded-full"}),"Processing..."]})})}),e.effect&&!n&&!a&&jsxRuntime.jsx(framerMotion.motion.div,{className:"absolute inset-0 pointer-events-none",variants:Ln,animate:e.effect})]})})};var nt=e=>({label:e.label,type:"navigate",target:e.nextId,...e.effect&&{effect:e.effect},metadata:{nextId:e.nextId,legacy:true}}),rt=(e,t,n)=>{let r=t||e.metadata?.label||Ee(e.type),i=n||e.metadata?.description;return {label:r,type:e.type,...i&&{description:i},...e.metadata?.effect?{effect:e.metadata.effect}:{},...e.target&&{target:e.target},...e.payload!==void 0&&{value:e.payload},metadata:{...e.metadata,direction:e.direction,timestamp:e.timestamp}}},zn=e=>({type:e.type||"custom",timestamp:Date.now(),...e.target&&{target:e.target},...e.value!==void 0&&{payload:e.value},metadata:{label:e.label,...e.description&&{description:e.description},...e.effect&&{effect:e.effect},...e.metadata}}),Ee=e=>({move:"Move",interact:"Interact",collect:"Collect",attack:"Attack",defend:"Defend",use:"Use Item",talk:"Talk",examine:"Examine",open:"Open",close:"Close",push:"Push",pull:"Pull",climb:"Climb",jump:"Jump",run:"Run",walk:"Walk",rest:"Rest",save:"Save Game",load:"Load Game",pause:"Pause",resume:"Resume",reset:"Reset",quit:"Quit",navigate:"Navigate",custom:"Action"})[e]||e.charAt(0).toUpperCase()+e.slice(1),it=e=>({attack:"pulse",collect:"bounce",interact:"highlight",magic:"highlight",spell:"highlight",move:"slide",transport:"zoom",navigate:"slide"})[e],Un=(e,t)=>{let n=it(e),r=t?.effect||n;return {label:t?.label||Ee(e),type:e,...t?.description&&{description:t.description},...r&&{effect:r},...t?.target&&{target:t.target},metadata:t?.metadata||{}}},Qn=(e,t)=>({label:`Move ${e.charAt(0).toUpperCase()+e.slice(1)}`,type:"move",effect:"slide",...t&&{description:t},metadata:{direction:e}}),qn=(e,t,n)=>({label:t||`Interact with ${e}`,type:"interact",target:e,effect:"highlight",...n&&{description:n}}),Hn=(e,t)=>({label:`Collect ${e}`,type:"collect",target:e,effect:"bounce",...t&&{description:t}}),at=e=>e&&typeof e=="object"&&typeof e.label=="string"&&typeof e.nextId=="string",ot=e=>e&&typeof e=="object"&&typeof e.type=="string",st=e=>e&&typeof e=="object"&&typeof e.label=="string",$n=(e,t)=>st(e)?e:at(e)?nt(e):ot(e)?rt(e,t):{label:t||"Unknown Action",type:"custom",metadata:{originalAction:e}};var De=({scene:e,className:t="",showMetadata:n=false,enableAnimations:r=true})=>{let i=p=>typeof p=="string"?p:typeof p=="number"?String(p):"",o=e?.name||e?.title||e?.id||"Untitled Scene",a=e?.description||(typeof e?.metadata?.description=="string"?e.metadata.description:""),d=()=>{if(!r)return "animate-fade-in";let p=e?.transitions;if(!p||!Array.isArray(p)||p.length===0)return "animate-fade-in";switch(p[0]?.animation){case "fade":return "animate-fade-in";case "slide":return "animate-slide-left";case "zoom":return "animate-zoom-in";case "custom":return "animate-custom";default:return "animate-fade-in"}},g=me__namespace.useMemo(()=>e?.background?e.background.startsWith("#")||/^[a-zA-Z]+$/.test(e.background)?{backgroundColor:e.background}:{backgroundImage:`url(${e.background})`,backgroundSize:"cover",backgroundPosition:"center",backgroundRepeat:"no-repeat"}:{},[e?.background]),T=me__namespace.useMemo(()=>["scene-container",d(),t].filter(Boolean).join(" "),[t,r,e?.transitions]),w=me__namespace.useMemo(()=>({...g,minHeight:e?.height?`${e.height*32}px`:"auto",width:e?.width?`${e.width*32}px`:"100%"}),[g,e?.height,e?.width]);return e?jsxRuntime.jsxs("div",{className:T,style:w,children:[e.background&&!e.background.startsWith("#")&&jsxRuntime.jsx("div",{className:"absolute inset-0 bg-black bg-opacity-40"}),jsxRuntime.jsxs("div",{className:"relative z-10 p-6",children:[jsxRuntime.jsx("h1",{className:"text-3xl font-bold text-gray-900 dark:text-white mb-4",children:i(o)}),a&&jsxRuntime.jsx("div",{className:"prose prose-lg dark:prose-invert max-w-none mb-6",children:jsxRuntime.jsx("p",{className:"text-gray-700 dark:text-gray-300 leading-relaxed",children:i(a)})}),e.objectives&&Array.isArray(e.objectives)&&e.objectives.length>0&&jsxRuntime.jsxs("div",{className:"mb-6",children:[jsxRuntime.jsx("h3",{className:"text-lg font-semibold text-gray-800 dark:text-gray-200 mb-2",children:"Objectives:"}),jsxRuntime.jsx("ul",{className:"space-y-2",children:e.objectives.map((p,D)=>jsxRuntime.jsxs("li",{className:`flex items-center space-x-2 ${p?.isCompleted?"text-green-600 dark:text-green-400":"text-gray-600 dark:text-gray-400"}`,children:[jsxRuntime.jsx("span",{className:"text-sm",children:p?.isCompleted?"\u2705":"\u{1F3AF}"}),jsxRuntime.jsx("span",{children:i(p?.description)||"Objective"}),p?.reward&&jsxRuntime.jsxs("span",{className:"text-xs bg-yellow-100 dark:bg-yellow-900 px-2 py-1 rounded",children:["+",i(p.reward)]})]},p?.id||D))})]}),n&&jsxRuntime.jsxs("div",{className:"mt-6 p-4 bg-gray-100 dark:bg-gray-800 rounded-lg",children:[jsxRuntime.jsx("h4",{className:"text-sm font-semibold mb-2",children:"Scene Information"}),jsxRuntime.jsxs("div",{className:"text-xs space-y-1",children:[jsxRuntime.jsxs("div",{children:["ID: ",i(e.id)||"Unknown"]}),jsxRuntime.jsxs("div",{children:["Dimensions: ",i(e.width)||"0"," \xD7 ",i(e.height)||"0"]}),jsxRuntime.jsxs("div",{children:["Entities: ",e.entities?i(e.entities.length):"0"]}),jsxRuntime.jsxs("div",{children:["Objectives: ",e.objectives?i(e.objectives.length):"0"]}),e.transitions&&jsxRuntime.jsxs("div",{children:["Transitions: ",i(e.transitions.length)]})]})]}),e.player?.startPosition&&n&&jsxRuntime.jsxs("div",{className:"mt-4 text-xs text-gray-500 dark:text-gray-400",children:["Player starts at: (",i(e.player.startPosition.x)||"0",",",i(e.player.startPosition.y)||"0",")"]})]})]}):jsxRuntime.jsxs("div",{className:"scene-container p-6",children:[jsxRuntime.jsx("h1",{className:"text-3xl font-bold text-gray-900 dark:text-white mb-4",children:"No Scene Data"}),jsxRuntime.jsx("p",{className:"text-gray-700 dark:text-gray-300",children:"Scene data is not available."})]})};var ut=({metrics:e,width:t=300,height:n=150,showEpisodes:r=50})=>{let i=me.useMemo(()=>{if(e.length===0)return {points:"",maxReward:0,minReward:0,hasData:false};let a=e.slice(-r).map(p=>p.totalReward),d=Math.max(...a),g=Math.min(...a),T=d-g||1;return {points:a.map((p,D)=>{let I=D/Math.max(a.length-1,1)*t,E=n-(p-g)/T*n;return `${I},${E}`}).join(" "),maxReward:d,minReward:g,hasData:true}},[e,r,t,n]);return jsxRuntime.jsxs("div",{className:"bg-gray-50 dark:bg-gray-800 p-3 r