dev-kitty 1.0.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/index.js ADDED
@@ -0,0 +1,31 @@
1
+ "use strict";var E=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var O=(r,t,e)=>t in r?E(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var W=(r,t)=>{for(var e in t)E(r,e,{get:t[e],enumerable:!0})},q=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of F(t))!N.call(r,i)&&i!==e&&E(r,i,{get:()=>t[i],enumerable:!(n=B(t,i))||n.enumerable});return r};var X=r=>q(E({},"__esModule",{value:!0}),r);var s=(r,t,e)=>O(r,typeof t!="symbol"?t+"":t,e);var j={};W(j,{Kitty:()=>b,Overlay:()=>f,default:()=>$,destroy:()=>P,devKittyPlugin:()=>G,inject:()=>S});module.exports=X(j);var K=()=>{if(typeof window>"u")return!1;let r=window.location.hostname;return r==="localhost"||r==="127.0.0.1"||r.endsWith(".local")||r==="[::1]"};var f=class{constructor(){s(this,"container");s(this,"shadow");s(this,"shadowContainer");this.container=document.createElement("div"),this.container.id="dev-kitty-overlay",Object.assign(this.container.style,{position:"fixed",top:"0",left:"0",width:"100vw",height:"100vh",pointerEvents:"none",zIndex:"2147483647"}),this.shadow=this.container.attachShadow({mode:"open"}),this.shadowContainer=document.createElement("div"),this.shadowContainer.id="dev-kitty-root",Object.assign(this.shadowContainer.style,{width:"100%",height:"100%",position:"relative",overflow:"hidden"}),this.shadow.appendChild(this.shadowContainer)}mount(){document.getElementById("dev-kitty-overlay")||document.body.appendChild(this.container)}destroy(){this.container.parentNode&&this.container.parentNode.removeChild(this.container)}};var M=class{constructor(){s(this,"container",null);s(this,"element",null);s(this,"x",0);s(this,"y",0);s(this,"state","idle")}setPosition(t,e){this.x=t,this.y=e,this.element&&(this.element.style.transform=`translate(${Math.round(t)}px, ${Math.round(e)}px)`)}};var T=class T{constructor(){s(this,"element");s(this,"currentFrame",0);s(this,"animationTimer",0);s(this,"frameRate",250);this.element=document.createElement("div"),this.element.style.width="64px",this.element.style.height="64px",this.element.style.imageRendering="pixelated",this.element.innerHTML=T.SVG_TEMPLATE;let t=this.element.querySelector("svg");t&&(t.style.width="100%",t.style.height="100%")}getElement(){return this.element}update(t,e,n){this.animationTimer+=t,this.animationTimer>=this.frameRate&&(this.animationTimer=0,this.currentFrame=(this.currentFrame+1)%4,this.animate(e,n))}animate(t,e){let n=this.element.querySelector("svg");if(!n)return;let i=n.querySelector("#head"),l=n.querySelector("#body"),d=n.querySelector("#tail"),m=n.querySelector("#zzz"),a=n.querySelectorAll(".leg"),c=n.querySelectorAll(".eye");switch(e==="left"?this.element.style.transform="scaleX(-1)":this.element.style.transform="scaleX(1)",m.style.display="none",c.forEach(h=>h.setAttribute("fill","#fff")),a.forEach(h=>h.setAttribute("height","4")),d.setAttribute("transform",""),l.setAttribute("y","14"),i.setAttribute("y","8"),l.setAttribute("width","14"),t){case"walk-left":case"walk-right":case"chase-ball":case"zoomies":case"pounce":let h=this.currentFrame%2===0?2:0;a.forEach((o,H)=>{let w=H%2===0?h:2-h;o.setAttribute("y",(24+w).toString())}),d.setAttribute("transform",`rotate(${Math.sin(Date.now()/100)*15} 4 17)`),t==="zoomies"&&(this.element.style.transform+=` rotate(${Math.sin(Date.now()/50)*10}deg)`);break;case"sleep":c.forEach(o=>o.setAttribute("fill","transparent")),m.style.display="block",m.style.opacity=(.5+Math.sin(Date.now()/500)*.5).toString(),a.forEach(o=>o.setAttribute("height","2")),l.setAttribute("y","15"),i.setAttribute("y","9");break;case"sit":case"lick-paw":if(a.forEach(o=>o.setAttribute("height","2")),i.setAttribute("y","8"),t==="lick-paw"){let o=a[0];o.setAttribute("height","4"),o.setAttribute("y",(22+Math.sin(Date.now()/100)*2).toString())}break;case"poop":this.element.style.transform+=" rotate(10deg)",a.forEach(o=>o.setAttribute("height","2"));break;case"stretch":l.setAttribute("width",this.currentFrame%2===0?"16":"14");break;case"jump":a.forEach(o=>o.setAttribute("height","6"));break;case"stare":c.forEach(o=>{o.setAttribute("width","3"),o.setAttribute("height","3")});break;case"purr":let g=Math.sin(Date.now()/30)*1;i.setAttribute("y",(8+g).toString()),l.setAttribute("y",(14+g).toString());break;default:d.setAttribute("transform",`rotate(${Math.sin(Date.now()/300)*5} 4 17)`),Math.random()<.1&&c.forEach(o=>o.setAttribute("fill","transparent"));break}}showMessage(t,e=2e3){let n=this.element.querySelector("svg");if(!n)return;let i=n.querySelector("#bubble"),l=n.querySelector("#bubble-text");l.textContent=t,i.style.display="block",setTimeout(()=>{i.style.display="none"},e)}};s(T,"SVG_TEMPLATE",`
2
+ <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" shape-rendering="crispEdges">
3
+ <!-- Tail -->
4
+ <rect x="2" y="16" width="6" height="2" fill="#333" id="tail" />
5
+ <!-- Body -->
6
+ <rect x="8" y="14" width="14" height="10" fill="#333" id="body" />
7
+ <!-- Head -->
8
+ <rect x="16" y="8" width="10" height="10" fill="#333" id="head" />
9
+ <!-- Ears -->
10
+ <rect x="17" y="5" width="3" height="3" fill="#333" id="ear-l" />
11
+ <rect x="23" y="5" width="3" height="3" fill="#333" id="ear-r" />
12
+ <!-- Eyes -->
13
+ <rect x="19" y="11" width="2" height="2" fill="#fff" class="eye" />
14
+ <rect x="24" y="11" width="2" height="2" fill="#fff" class="eye" />
15
+ <!-- Nose -->
16
+ <rect x="23" y="14" width="2" height="1" fill="#ffb7b7" />
17
+ <!-- Legs -->
18
+ <rect x="9" y="24" width="3" height="4" fill="#333" class="leg leg-fl" />
19
+ <rect x="13" y="24" width="3" height="4" fill="#333" class="leg leg-fr" />
20
+ <rect x="17" y="24" width="3" height="4" fill="#333" class="leg leg-bl" />
21
+ <rect x="20" y="24" width="3" height="4" fill="#333" class="leg leg-br" />
22
+ <!-- Speech Bubble -->
23
+ <g id="bubble" style="display:none">
24
+ <rect x="0" y="0" width="30" height="10" rx="2" fill="white" stroke="#333" stroke-width="0.5" />
25
+ <text x="15" y="7" font-family="monospace" font-size="4" text-anchor="middle" fill="#333" id="bubble-text">MEOW</text>
26
+ </g>
27
+ <!-- Sleep Zzz (hidden by default) -->
28
+ <text x="2" y="10" font-family="Arial" font-size="6" fill="#aaa" id="zzz" style="display:none">Zzz</text>
29
+ </svg>
30
+ `);var k=T;var L=class{constructor(){s(this,"currentState","idle");s(this,"stateTimer",0);s(this,"speed",2.5);s(this,"mouseX",0);s(this,"mouseY",0);s(this,"isChasingMouse",!1);s(this,"facing","right");typeof window<"u"&&window.addEventListener("mousemove",t=>{this.mouseX=t.clientX,this.mouseY=t.clientY})}update(t,e,n,i){this.stateTimer+=t;let l=64,d=20,m=Math.sqrt(Math.pow(this.mouseX-(e+32),2)+Math.pow(this.mouseY-(n+32),2));if(m<200&&Math.random()<.05&&!this.isChasingMouse&&this.currentState!=="sleep"&&(this.isChasingMouse=!0,this.currentState="chase-ball"),this.isChasingMouse&&(m<40&&(this.isChasingMouse=!1,this.currentState="sit",this.stateTimer=0),m>500&&(this.isChasingMouse=!1)),this.stateTimer>this.getStateDuration(this.currentState)){this.stateTimer=0,this.isChasingMouse=!1;let H=this.currentState;this.currentState=this.getNextState(),this.currentState==="walk-left"&&(this.facing="left"),this.currentState==="walk-right"&&(this.facing="right")}let a=e,c=n,h=this.getSpeedForState(this.currentState);switch(this.currentState){case"walk-left":a-=h,this.facing="left";break;case"walk-right":a+=h,this.facing="right";break;case"zoomies":a+=(Math.random()-.5)*h*2;break;case"chase-ball":let w=(this.isChasingMouse?{x:this.mouseX,y:this.mouseY}:i||{x:a,y:c}).x-32-a;a+=Math.sign(w)*h,w!==0&&(this.facing=w<0?"left":"right");break;case"pounce":a+=(this.facing==="left"?-1:1)*h;break}a<d?(a=d,this.currentState==="walk-left"&&(this.currentState="walk-right")):a>window.innerWidth-l-d&&(a=window.innerWidth-l-d,this.currentState==="walk-right"&&(this.currentState="walk-left"));let g=window.innerHeight-80,o=g;return this.isChasingMouse&&(o=Math.min(this.mouseY-32,g)),c+=(o-c)*.1,{state:this.currentState,x:a,y:c,facing:this.facing}}getSpeedForState(t){switch(t){case"walk-left":case"walk-right":return this.speed;case"chase-ball":return this.speed*2.5;case"zoomies":return this.speed*5;case"pounce":return this.speed*4;default:return 0}}getStateDuration(t){switch(t){case"idle":return 1500+Math.random()*2e3;case"walk-left":case"walk-right":return 2e3+Math.random()*3e3;case"sleep":return 1e4+Math.random()*15e3;case"sit":return 3e3+Math.random()*4e3;case"poop":return 4e3;case"scratch":return 2e3;case"stare":return 3e3;case"stretch":return 2e3;case"zoomies":return 1500+Math.random()*1e3;case"lick-paw":return 3e3;case"pounce":return 800;case"purr":return 5e3;default:return 2e3}}getNextState(){let t=Math.random();return t<.15?"walk-left":t<.3?"walk-right":t<.45?"idle":t<.55?"sit":t<.65?"sleep":t<.72?"stare":t<.77?"lick-paw":t<.82?"scratch":t<.86?"stretch":t<.9?"jump":t<.93?"zoomies":t<.95?"pounce":t<.98?"purr":"poop"}getState(){return this.currentState}};var u=require("matter-js");var C=class{constructor(){s(this,"engine");s(this,"world");s(this,"floor",null);this.engine=u.Engine.create(),this.world=this.engine.world,this.engine.gravity.y=.5}update(t){let n=Math.min(t,16.666666666666668*2);u.Engine.update(this.engine,n)}addBall(t,e,n){let i=u.Bodies.circle(t,e,n,{restitution:.8,friction:.05,frictionAir:.02,label:"ball"});return u.World.add(this.world,i),i}addFloor(t,e){return this.floor&&u.World.remove(this.world,this.floor),this.floor=u.Bodies.rectangle(t/2,e+50,t,100,{isStatic:!0,label:"floor"}),u.World.add(this.world,this.floor),this.floor}};var v=require("matter-js");var A=class{constructor(t,e){s(this,"element");s(this,"body");this.body=e,this.element=document.createElement("div"),this.element.innerHTML="\u{1F9F6}",this.element.style.position="absolute",this.element.style.width="24px",this.element.style.height="24px",this.element.style.fontSize="20px",this.element.style.display="flex",this.element.style.alignItems="center",this.element.style.justifyContent="center",this.element.style.pointerEvents="auto",this.element.style.cursor="grab",this.element.style.zIndex="2147483646";let n=!1;this.element.addEventListener("mousedown",()=>{n=!0,this.element.style.cursor="grabbing",v.Body.setStatic(this.body,!0)}),window.addEventListener("mousemove",i=>{n&&v.Body.setPosition(this.body,{x:i.clientX,y:i.clientY})}),window.addEventListener("mouseup",()=>{n&&(n=!1,this.element.style.cursor="grab",v.Body.setStatic(this.body,!1),v.Body.setVelocity(this.body,{x:(Math.random()-.5)*10,y:-5}))}),t.appendChild(this.element)}update(){let{x:t,y:e}=this.body.position;this.element.style.transform=`translate(${t-12}px, ${e-12}px) rotate(${this.body.angle}rad)`}};var z=class{constructor(t,e,n){s(this,"element");s(this,"container");this.container=t,this.element=document.createElement("div"),this.element.innerHTML="\u{1F4A9}",this.element.style.position="absolute",this.element.style.left=`${e}px`,this.element.style.top=`${n}px`,this.element.style.fontSize="12px",this.element.style.pointerEvents="none",this.element.style.zIndex="2147483646";let i=document.createElement("div");i.innerHTML="\u3030\uFE0F",i.style.position="absolute",i.style.top="-10px",i.style.left="0",i.style.fontSize="8px",i.style.opacity="0.5",i.className="kitty-poop-smell",this.element.appendChild(i),this.container.appendChild(this.element),setTimeout(()=>{this.element.style.transition="opacity 2s",this.element.style.opacity="0",setTimeout(()=>{this.element.parentNode&&this.container.removeChild(this.element)},2e3)},3e4)}};var R=class{constructor(t){s(this,"steps",[]);s(this,"container");s(this,"maxSteps",50);this.container=t}addStep(t,e){let n={x:t,y:e,t:Date.now(),opacity:.4};this.steps.push(n);let i=document.createElement("div");if(i.style.position="absolute",i.style.left=`${t}px`,i.style.top=`${e}px`,i.style.width="4px",i.style.height="4px",i.style.background="rgba(0,0,0,0.1)",i.style.borderRadius="50%",i.style.pointerEvents="none",this.container.appendChild(i),this.steps.length>this.maxSteps){this.steps.shift();let l=this.container.firstChild;l&&this.container.removeChild(l)}setTimeout(()=>{i.parentNode&&(i.style.opacity="0"),setTimeout(()=>{i.parentNode&&this.container.removeChild(i)},1e3)},2e3)}};var V=require("gsap"),y=require("matter-js");var b=class extends M{constructor(){super();s(this,"sprite");s(this,"ai");s(this,"physics");s(this,"ball",null);s(this,"footsteps",null);s(this,"lastTime",0);s(this,"poops",[]);s(this,"lastStepX",0);s(this,"stepDistance",20);s(this,"laserActive",!1);s(this,"laserEl",null);this.sprite=new k,this.ai=new L,this.physics=new C,this.x=Math.random()*(window.innerWidth-64),this.y=window.innerHeight-80}mount(e){this.container=e,this.element=this.sprite.getElement(),this.element.style.position="absolute",this.element.style.zIndex="2147483647",this.container.appendChild(this.element),this.physics.addFloor(window.innerWidth,window.innerHeight),this.footsteps=new R(e),this.setupLaserPointer(),this.element.style.pointerEvents="auto",this.element.addEventListener("mousedown",()=>this.handleScaredJump()),setTimeout(()=>this.spawnBall(),5e3),window.addEventListener("resize",this.handleResize.bind(this)),this.setPosition(this.x,this.y),requestAnimationFrame(this.tick.bind(this))}handleResize(){this.physics.addFloor(window.innerWidth,window.innerHeight)}spawnBall(){if(!this.container)return;let e=this.physics.addBall(Math.random()*window.innerWidth,-50,12);this.ball=new A(this.container,e)}update(e){let n=this.ball?this.ball.body.position:void 0,{state:i,x:l,y:d,facing:m}=this.ai.update(e,this.x,this.y,n);if(Math.random()<.001){let a=["MEOW","PURR","HELLO","JS FTW","PET ME","I LOVE CODE","FEED ME","MEOWWW"];this.sprite.showMessage(a[Math.floor(Math.random()*a.length)])}if(i!==this.state&&(this.onStateChange(this.state,i),this.state=i),this.x=l,this.y=d,this.physics.update(e),this.ball&&this.ball.update(),(this.state.includes("walk")||this.state==="chase-ball"||this.state==="zoomies")&&Math.abs(this.x-this.lastStepX)>this.stepDistance&&(this.footsteps?.addStep(this.x+32,this.y+56),this.lastStepX=this.x),this.ball&&(i==="chase-ball"||i==="pounce")&&y.Vector.magnitude(y.Vector.sub(this.ball.body.position,{x:this.x+32,y:this.y+32}))<60){let c=y.Vector.create(m==="left"?-.08:.08,-.04);y.Body.applyForce(this.ball.body,this.ball.body.position,c)}this.sprite.update(e,i,m),this.setPosition(this.x,this.y)}onStateChange(e,n){n==="poop"&&this.container&&setTimeout(()=>{this.poops.push(new z(this.container,this.x+20,this.y+40))},2e3),n==="jump"&&(this.sprite.showMessage("BOING!",1e3),V.gsap.to(this.element,{y:this.y-100,duration:.5,ease:"power2.out",yoyo:!0,repeat:1,onComplete:()=>{this.setPosition(this.x,this.y)}})),n==="sleep"&&this.sprite.showMessage("Zzz...",2e3),n==="poop"&&this.sprite.showMessage("Oopsy!",2e3),n==="purr"&&this.sprite.showMessage("\u2764\uFE0F PURRR \u2764\uFE0F",3e3)}handleScaredJump(){(this.state==="sleep"||this.state==="idle"||this.state==="sit")&&(V.gsap.to(this.element,{x:"+=2",yoyo:!0,repeat:10,duration:.05}),setTimeout(()=>{this.onStateChange(this.state,"jump")},500))}setupLaserPointer(){window.addEventListener("keydown",e=>{e.shiftKey&&(this.laserActive=!0,this.showLaser())}),window.addEventListener("keyup",e=>{e.shiftKey||(this.laserActive=!1,this.hideLaser())}),window.addEventListener("mousemove",e=>{this.laserActive&&this.laserEl&&(this.laserEl.style.transform=`translate(${e.clientX-4}px, ${e.clientY-4}px)`,this.ai.mouseX=e.clientX,this.ai.mouseY=e.clientY,this.ai.isChasingMouse=!0)})}showLaser(){!this.container||this.laserEl||(this.laserEl=document.createElement("div"),Object.assign(this.laserEl.style,{position:"fixed",width:"8px",height:"8px",borderRadius:"50%",background:"red",boxShadow:"0 0 10px red",pointerEvents:"none",zIndex:"2147483647",top:"0",left:"0"}),this.container.appendChild(this.laserEl))}hideLaser(){this.laserEl&&this.laserEl.parentNode&&this.laserEl.parentNode.removeChild(this.laserEl),this.laserEl=null}tick(e){this.lastTime||(this.lastTime=e);let n=e-this.lastTime;this.lastTime=e,this.update(n),this.element&&this.element.parentNode&&requestAnimationFrame(this.tick.bind(this))}destroy(){this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null}};var S=()=>{K()&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",D):D())},p=null,x=null;function D(){p||(p=new f,p.mount(),x=new b,x.mount(p.shadowContainer))}var P=()=>{x&&x.destroy(),p&&p.destroy(),x=null,p=null};function G(){return{name:"vite-plugin-dev-kitty",apply:"serve",transformIndexHtml(r){return{html:r,tags:[{tag:"script",attrs:{type:"module"},children:'import "dev-kitty";',injectTo:"body"}]}}}}typeof window<"u"&&S();var $={init:S,plugin:G};0&&(module.exports={Kitty,Overlay,destroy,devKittyPlugin,inject});
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/core/environment.ts","../src/core/overlay.ts","../src/pets/basePet.ts","../src/pets/kitty/sprite.ts","../src/pets/kitty/ai.ts","../src/core/physics.ts","../src/pets/kitty/ball.ts","../src/pets/kitty/poop.ts","../src/pets/kitty/footsteps.ts","../src/pets/kitty/kitty.ts","../src/core/injector.ts","../src/plugins/vite.ts"],"sourcesContent":["import { inject } from './core/injector';\r\n\r\n// Auto-inject on import\r\nif (typeof window !== 'undefined') {\r\n inject();\r\n}\r\n\r\nimport { devKittyPlugin } from './plugins/vite';\r\n\r\nexport { inject, destroy } from './core/injector';\r\nexport { Kitty } from './pets/kitty/kitty';\r\nexport { Overlay } from './core/overlay';\r\nexport { devKittyPlugin };\r\n\r\n// Default export\r\nexport default {\r\n init: inject,\r\n plugin: devKittyPlugin\r\n};\r\n","export const isLocalhost = (): boolean => {\r\n if (typeof window === 'undefined') return false;\r\n\r\n const hostname = window.location.hostname;\r\n\r\n return (\r\n hostname === 'localhost' ||\r\n hostname === '127.0.0.1' ||\r\n hostname.endsWith('.local') ||\r\n hostname === '[::1]'\r\n );\r\n};\r\n","export class Overlay {\r\n private container: HTMLDivElement;\r\n private shadow: ShadowRoot;\r\n public shadowContainer: HTMLDivElement;\r\n\r\n constructor() {\r\n this.container = document.createElement('div');\r\n this.container.id = 'dev-kitty-overlay';\r\n \r\n // Core styles for the container\r\n Object.assign(this.container.style, {\r\n position: 'fixed',\r\n top: '0',\r\n left: '0',\r\n width: '100vw',\r\n height: '100vh',\r\n pointerEvents: 'none',\r\n zIndex: '2147483647',\r\n });\r\n\r\n this.shadow = this.container.attachShadow({ mode: 'open' });\r\n this.shadowContainer = document.createElement('div');\r\n this.shadowContainer.id = 'dev-kitty-root';\r\n \r\n // Root container in shadow DOM\r\n Object.assign(this.shadowContainer.style, {\r\n width: '100%',\r\n height: '100%',\r\n position: 'relative',\r\n overflow: 'hidden',\r\n });\r\n\r\n this.shadow.appendChild(this.shadowContainer);\r\n }\r\n\r\n mount() {\r\n if (!document.getElementById('dev-kitty-overlay')) {\r\n document.body.appendChild(this.container);\r\n }\r\n }\r\n\r\n destroy() {\r\n if (this.container.parentNode) {\r\n this.container.parentNode.removeChild(this.container);\r\n }\r\n }\r\n}\r\n","export abstract class BasePet {\r\n protected container: HTMLElement | null = null;\r\n protected element: HTMLElement | null = null;\r\n protected x: number = 0;\r\n protected y: number = 0;\r\n protected state: string = 'idle';\r\n\r\n abstract mount(container: HTMLElement): void;\r\n abstract update(delta: number): void;\r\n abstract destroy(): void;\r\n\r\n protected setPosition(x: number, y: number) {\r\n this.x = x;\r\n this.y = y;\r\n if (this.element) {\r\n // Rounding prevents pixel vibration/shimmering on modern displays\r\n this.element.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px)`;\r\n }\r\n }\r\n}\r\n","import { KittyState } from './ai';\r\n\r\nexport class KittySprite {\r\n private element: HTMLElement;\r\n private currentFrame: number = 0;\r\n private animationTimer: number = 0;\r\n private frameRate: number = 250;\r\n\r\n private static readonly SVG_TEMPLATE = `\r\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\" shape-rendering=\"crispEdges\">\r\n <!-- Tail -->\r\n <rect x=\"2\" y=\"16\" width=\"6\" height=\"2\" fill=\"#333\" id=\"tail\" />\r\n <!-- Body -->\r\n <rect x=\"8\" y=\"14\" width=\"14\" height=\"10\" fill=\"#333\" id=\"body\" />\r\n <!-- Head -->\r\n <rect x=\"16\" y=\"8\" width=\"10\" height=\"10\" fill=\"#333\" id=\"head\" />\r\n <!-- Ears -->\r\n <rect x=\"17\" y=\"5\" width=\"3\" height=\"3\" fill=\"#333\" id=\"ear-l\" />\r\n <rect x=\"23\" y=\"5\" width=\"3\" height=\"3\" fill=\"#333\" id=\"ear-r\" />\r\n <!-- Eyes -->\r\n <rect x=\"19\" y=\"11\" width=\"2\" height=\"2\" fill=\"#fff\" class=\"eye\" />\r\n <rect x=\"24\" y=\"11\" width=\"2\" height=\"2\" fill=\"#fff\" class=\"eye\" />\r\n <!-- Nose -->\r\n <rect x=\"23\" y=\"14\" width=\"2\" height=\"1\" fill=\"#ffb7b7\" />\r\n <!-- Legs -->\r\n <rect x=\"9\" y=\"24\" width=\"3\" height=\"4\" fill=\"#333\" class=\"leg leg-fl\" />\r\n <rect x=\"13\" y=\"24\" width=\"3\" height=\"4\" fill=\"#333\" class=\"leg leg-fr\" />\r\n <rect x=\"17\" y=\"24\" width=\"3\" height=\"4\" fill=\"#333\" class=\"leg leg-bl\" />\r\n <rect x=\"20\" y=\"24\" width=\"3\" height=\"4\" fill=\"#333\" class=\"leg leg-br\" />\r\n <!-- Speech Bubble -->\r\n <g id=\"bubble\" style=\"display:none\">\r\n <rect x=\"0\" y=\"0\" width=\"30\" height=\"10\" rx=\"2\" fill=\"white\" stroke=\"#333\" stroke-width=\"0.5\" />\r\n <text x=\"15\" y=\"7\" font-family=\"monospace\" font-size=\"4\" text-anchor=\"middle\" fill=\"#333\" id=\"bubble-text\">MEOW</text>\r\n </g>\r\n <!-- Sleep Zzz (hidden by default) -->\r\n <text x=\"2\" y=\"10\" font-family=\"Arial\" font-size=\"6\" fill=\"#aaa\" id=\"zzz\" style=\"display:none\">Zzz</text>\r\n </svg>\r\n `;\r\n\r\n constructor() {\r\n this.element = document.createElement('div');\r\n this.element.style.width = '64px';\r\n this.element.style.height = '64px';\r\n this.element.style.imageRendering = 'pixelated';\r\n this.element.innerHTML = KittySprite.SVG_TEMPLATE;\r\n \r\n const svg = this.element.querySelector('svg');\r\n if (svg) {\r\n svg.style.width = '100%';\r\n svg.style.height = '100%';\r\n }\r\n }\r\n\r\n getElement() {\r\n return this.element;\r\n }\r\n\r\n update(delta: number, state: KittyState, facing: 'left' | 'right') {\r\n this.animationTimer += delta;\r\n if (this.animationTimer >= this.frameRate) {\r\n this.animationTimer = 0;\r\n this.currentFrame = (this.currentFrame + 1) % 4;\r\n this.animate(state, facing);\r\n }\r\n }\r\n\r\n private animate(state: KittyState, facing: 'left' | 'right') {\r\n const svg = this.element.querySelector('svg');\r\n if (!svg) return;\r\n\r\n const head = svg.querySelector('#head') as SVGRectElement;\r\n const body = svg.querySelector('#body') as SVGRectElement;\r\n const tail = svg.querySelector('#tail') as SVGRectElement;\r\n const zzz = svg.querySelector('#zzz') as SVGTextElement;\r\n const legs = svg.querySelectorAll('.leg');\r\n const eyes = svg.querySelectorAll('.eye');\r\n\r\n // Handle Direction\r\n if (facing === 'left') {\r\n this.element.style.transform = 'scaleX(-1)';\r\n } else {\r\n this.element.style.transform = 'scaleX(1)';\r\n }\r\n\r\n // Reset basics\r\n zzz.style.display = 'none';\r\n eyes.forEach(e => (e as SVGRectElement).setAttribute('fill', '#fff'));\r\n legs.forEach(l => (l as SVGRectElement).setAttribute('height', '4'));\r\n tail.setAttribute('transform', '');\r\n body.setAttribute('y', '14');\r\n head.setAttribute('y', '8');\r\n body.setAttribute('width', '14');\r\n\r\n switch (state) {\r\n case 'walk-left':\r\n case 'walk-right':\r\n case 'chase-ball':\r\n case 'zoomies':\r\n case 'pounce':\r\n // Walk cycle\r\n const off = (this.currentFrame % 2 === 0) ? 2 : 0;\r\n legs.forEach((l, i) => {\r\n const legOff = (i % 2 === 0) ? off : 2 - off;\r\n (l as SVGRectElement).setAttribute('y', (24 + legOff).toString());\r\n });\r\n tail.setAttribute('transform', `rotate(${Math.sin(Date.now()/100)*15} 4 17)`);\r\n \r\n if (state === 'zoomies') {\r\n this.element.style.transform += ` rotate(${Math.sin(Date.now()/50)*10}deg)`;\r\n }\r\n break;\r\n\r\n case 'sleep':\r\n eyes.forEach(e => (e as SVGRectElement).setAttribute('fill', 'transparent'));\r\n zzz.style.display = 'block';\r\n zzz.style.opacity = (0.5 + Math.sin(Date.now()/500) * 0.5).toString();\r\n legs.forEach(l => (l as SVGRectElement).setAttribute('height', '2'));\r\n body.setAttribute('y', '15');\r\n head.setAttribute('y', '9');\r\n break;\r\n\r\n case 'sit':\r\n case 'lick-paw':\r\n legs.forEach(l => (l as SVGRectElement).setAttribute('height', '2'));\r\n head.setAttribute('y', '8');\r\n if (state === 'lick-paw') {\r\n const leg = legs[0] as SVGRectElement;\r\n leg.setAttribute('height', '4');\r\n leg.setAttribute('y', (22 + Math.sin(Date.now()/100)*2).toString());\r\n }\r\n break;\r\n\r\n case 'poop':\r\n this.element.style.transform += ' rotate(10deg)';\r\n legs.forEach(l => (l as SVGRectElement).setAttribute('height', '2'));\r\n break;\r\n\r\n case 'stretch':\r\n body.setAttribute('width', this.currentFrame % 2 === 0 ? '16' : '14');\r\n break;\r\n \r\n case 'jump':\r\n legs.forEach(l => (l as SVGRectElement).setAttribute('height', '6'));\r\n break;\r\n \r\n case 'stare':\r\n // Big eyes when staring\r\n eyes.forEach(e => {\r\n (e as SVGRectElement).setAttribute('width', '3');\r\n (e as SVGRectElement).setAttribute('height', '3');\r\n });\r\n break;\r\n\r\n case 'purr':\r\n const vib = Math.sin(Date.now()/30) * 1;\r\n head.setAttribute('y', (8 + vib).toString());\r\n body.setAttribute('y', (14 + vib).toString());\r\n break;\r\n\r\n default: // idle\r\n tail.setAttribute('transform', `rotate(${Math.sin(Date.now()/300)*5} 4 17)`);\r\n if (Math.random() < 0.1) eyes.forEach(e => (e as SVGRectElement).setAttribute('fill', 'transparent')); // Blink\r\n break;\r\n }\r\n }\r\n\r\n public showMessage(text: string, duration: number = 2000) {\r\n const svg = this.element.querySelector('svg');\r\n if (!svg) return;\r\n const bubble = svg.querySelector('#bubble') as SVGGElement;\r\n const bubbleText = svg.querySelector('#bubble-text') as SVGTextElement;\r\n \r\n bubbleText.textContent = text;\r\n bubble.style.display = 'block';\r\n \r\n setTimeout(() => {\r\n bubble.style.display = 'none';\r\n }, duration);\r\n }\r\n}\r\n","export type KittyState = \r\n | 'idle' \r\n | 'walk-left' \r\n | 'walk-right' \r\n | 'sleep' \r\n | 'sit' \r\n | 'stretch' \r\n | 'jump' \r\n | 'chase-ball' \r\n | 'poop' \r\n | 'scratch'\r\n | 'stare'\r\n | 'zoomies'\r\n | 'lick-paw'\r\n | 'pounce'\r\n | 'purr';\r\n\r\nexport class KittyAI {\r\n private currentState: KittyState = 'idle';\r\n private stateTimer: number = 0;\r\n private speed: number = 2.5;\r\n \r\n private mouseX: number = 0;\r\n private mouseY: number = 0;\r\n private isChasingMouse: boolean = false;\r\n\r\n private facing: 'left' | 'right' = 'right';\r\n\r\n constructor() {\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('mousemove', (e) => {\r\n this.mouseX = e.clientX;\r\n this.mouseY = e.clientY;\r\n });\r\n }\r\n }\r\n\r\n update(delta: number, currentX: number, currentY: number, ballPos?: { x: number, y: number }): { state: KittyState; x: number; y: number, facing: 'left' | 'right' } {\r\n this.stateTimer += delta;\r\n\r\n // --- ENFORCE SCREEN BOUNDARIES ---\r\n const width = 64; // Kitty width is roughly 64px\r\n const margin = 20;\r\n \r\n // Mouse proximity chasing (Cuteness factor)\r\n const distToMouse = Math.sqrt(Math.pow(this.mouseX - (currentX + 32), 2) + Math.pow(this.mouseY - (currentY + 32), 2));\r\n \r\n // Low probability to start chasing if close and not sleeping\r\n if (distToMouse < 200 && Math.random() < 0.05 && !this.isChasingMouse && this.currentState !== 'sleep') {\r\n this.isChasingMouse = true;\r\n this.currentState = 'chase-ball';\r\n }\r\n\r\n if (this.isChasingMouse) {\r\n if (distToMouse < 40) {\r\n this.isChasingMouse = false;\r\n this.currentState = 'sit';\r\n this.stateTimer = 0;\r\n }\r\n // If mouse gets too far, stop chasing\r\n if (distToMouse > 500) {\r\n this.isChasingMouse = false;\r\n }\r\n }\r\n\r\n // Normal State Transitions\r\n if (this.stateTimer > this.getStateDuration(this.currentState)) {\r\n this.stateTimer = 0;\r\n this.isChasingMouse = false;\r\n const oldState = this.currentState;\r\n this.currentState = this.getNextState();\r\n \r\n // Keep track of direction when walking starts\r\n if (this.currentState === 'walk-left') this.facing = 'left';\r\n if (this.currentState === 'walk-right') this.facing = 'right';\r\n }\r\n\r\n let nextX = currentX;\r\n let nextY = currentY;\r\n\r\n // Movement speeds\r\n const moveSpeed = this.getSpeedForState(this.currentState);\r\n\r\n switch (this.currentState) {\r\n case 'walk-left':\r\n nextX -= moveSpeed;\r\n this.facing = 'left';\r\n break;\r\n case 'walk-right':\r\n nextX += moveSpeed;\r\n this.facing = 'right';\r\n break;\r\n case 'zoomies':\r\n // Zoomies moves randomly but fast\r\n nextX += (Math.random() - 0.5) * moveSpeed * 2;\r\n break;\r\n case 'chase-ball':\r\n const target = this.isChasingMouse ? { x: this.mouseX, y: this.mouseY } : (ballPos || { x: nextX, y: nextY });\r\n const dx = (target.x - 32) - nextX;\r\n nextX += Math.sign(dx) * moveSpeed;\r\n if (dx !== 0) this.facing = dx < 0 ? 'left' : 'right';\r\n break;\r\n case 'pounce':\r\n // Pounce is a quick dash forward in current facing direction\r\n nextX += (this.facing === 'left' ? -1 : 1) * moveSpeed;\r\n break;\r\n }\r\n\r\n // Clamp X to screen\r\n if (nextX < margin) {\r\n nextX = margin;\r\n if (this.currentState === 'walk-left') this.currentState = 'walk-right';\r\n } else if (nextX > window.innerWidth - width - margin) {\r\n nextX = window.innerWidth - width - margin;\r\n if (this.currentState === 'walk-right') this.currentState = 'walk-left';\r\n }\r\n\r\n // Smooth Y movement\r\n const groundY = window.innerHeight - 80;\r\n let targetY = groundY;\r\n \r\n // Jump effect handles its own Y usually with GSAP, but we provide a base here\r\n if (this.isChasingMouse) targetY = Math.min(this.mouseY - 32, groundY);\r\n \r\n nextY += (targetY - nextY) * 0.1;\r\n\r\n return { state: this.currentState, x: nextX, y: nextY, facing: this.facing };\r\n }\r\n\r\n private getSpeedForState(state: KittyState): number {\r\n switch (state) {\r\n case 'walk-left':\r\n case 'walk-right': return this.speed;\r\n case 'chase-ball': return this.speed * 2.5;\r\n case 'zoomies': return this.speed * 5;\r\n case 'pounce': return this.speed * 4;\r\n default: return 0;\r\n }\r\n }\r\n\r\n private getStateDuration(state: KittyState): number {\r\n switch (state) {\r\n case 'idle': return 1500 + Math.random() * 2000;\r\n case 'walk-left':\r\n case 'walk-right': return 2000 + Math.random() * 3000;\r\n case 'sleep': return 10000 + Math.random() * 15000;\r\n case 'sit': return 3000 + Math.random() * 4000;\r\n case 'poop': return 4000;\r\n case 'scratch': return 2000;\r\n case 'stare': return 3000;\r\n case 'stretch': return 2000;\r\n case 'zoomies': return 1500 + Math.random() * 1000;\r\n case 'lick-paw': return 3000;\r\n case 'pounce': return 800;\r\n case 'purr': return 5000;\r\n default: return 2000;\r\n }\r\n }\r\n\r\n private getNextState(): KittyState {\r\n const roll = Math.random();\r\n // Weighted selection for better personality\r\n if (roll < 0.15) return 'walk-left';\r\n if (roll < 0.30) return 'walk-right';\r\n if (roll < 0.45) return 'idle';\r\n if (roll < 0.55) return 'sit';\r\n if (roll < 0.65) return 'sleep';\r\n if (roll < 0.72) return 'stare';\r\n if (roll < 0.77) return 'lick-paw';\r\n if (roll < 0.82) return 'scratch';\r\n if (roll < 0.86) return 'stretch';\r\n if (roll < 0.90) return 'jump';\r\n if (roll < 0.93) return 'zoomies';\r\n if (roll < 0.95) return 'pounce';\r\n if (roll < 0.98) return 'purr';\r\n return 'poop';\r\n }\r\n\r\n public getState(): KittyState {\r\n return this.currentState;\r\n }\r\n}\r\n","import { Engine, Render, World, Bodies, Body, Vector } from 'matter-js';\r\n\r\nexport class PhysicsEngine {\r\n public engine: Engine;\r\n public world: World;\r\n\r\n constructor() {\r\n this.engine = Engine.create();\r\n this.world = this.engine.world;\r\n this.engine.gravity.y = 0.5; // Custom gravity\r\n }\r\n\r\n update(delta: number) {\r\n // Matter.js warning fix: Use a fixed timestep or cap the delta\r\n const fixedTimeStep = 1000 / 60; // 16.666ms\r\n const cappedDelta = Math.min(delta, fixedTimeStep * 2); \r\n Engine.update(this.engine, cappedDelta);\r\n }\r\n\r\n addBall(x: number, y: number, radius: number) {\r\n const ball = Bodies.circle(x, y, radius, {\r\n restitution: 0.8,\r\n friction: 0.05,\r\n frictionAir: 0.02,\r\n label: 'ball'\r\n });\r\n World.add(this.world, ball);\r\n return ball;\r\n }\r\n\r\n private floor: Body | null = null;\r\n\r\n addFloor(width: number, height: number) {\r\n if (this.floor) World.remove(this.world, this.floor);\r\n this.floor = Bodies.rectangle(width / 2, height + 50, width, 100, {\r\n isStatic: true,\r\n label: 'floor'\r\n });\r\n World.add(this.world, this.floor);\r\n return this.floor;\r\n }\r\n}\r\n","import { Body } from 'matter-js';\r\n\r\nexport class YarnBall {\r\n public element: HTMLDivElement;\r\n public body: Body;\r\n\r\n constructor(container: HTMLElement, body: Body) {\r\n this.body = body;\r\n this.element = document.createElement('div');\r\n this.element.innerHTML = '🧶';\r\n this.element.style.position = 'absolute';\r\n this.element.style.width = '24px';\r\n this.element.style.height = '24px';\r\n this.element.style.fontSize = '20px';\r\n this.element.style.display = 'flex';\r\n this.element.style.alignItems = 'center';\r\n this.element.style.justifyContent = 'center';\r\n this.element.style.pointerEvents = 'auto'; // Allow interaction\r\n this.element.style.cursor = 'grab';\r\n this.element.style.zIndex = '2147483646';\r\n \r\n // Dragging Logic\r\n let isDragging = false;\r\n this.element.addEventListener('mousedown', () => {\r\n isDragging = true;\r\n this.element.style.cursor = 'grabbing';\r\n Body.setStatic(this.body, true);\r\n });\r\n\r\n window.addEventListener('mousemove', (e) => {\r\n if (!isDragging) return;\r\n Body.setPosition(this.body, { x: e.clientX, y: e.clientY });\r\n });\r\n\r\n window.addEventListener('mouseup', () => {\r\n if (!isDragging) return;\r\n isDragging = false;\r\n this.element.style.cursor = 'grab';\r\n Body.setStatic(this.body, false);\r\n // Give it a little toss\r\n Body.setVelocity(this.body, { x: (Math.random() - 0.5) * 10, y: -5 });\r\n });\r\n\r\n container.appendChild(this.element);\r\n }\r\n\r\n update() {\r\n const { x, y } = this.body.position;\r\n this.element.style.transform = `translate(${x - 12}px, ${y - 12}px) rotate(${this.body.angle}rad)`;\r\n }\r\n}\r\n","export class Poop {\r\n private element: HTMLDivElement;\r\n private container: HTMLElement;\r\n\r\n constructor(container: HTMLElement, x: number, y: number) {\r\n this.container = container;\r\n this.element = document.createElement('div');\r\n this.element.innerHTML = '💩';\r\n this.element.style.position = 'absolute';\r\n this.element.style.left = `${x}px`;\r\n this.element.style.top = `${y}px`;\r\n this.element.style.fontSize = '12px';\r\n this.element.style.pointerEvents = 'none';\r\n this.element.style.zIndex = '2147483646';\r\n \r\n // Smell animation\r\n const smell = document.createElement('div');\r\n smell.innerHTML = '〰️';\r\n smell.style.position = 'absolute';\r\n smell.style.top = '-10px';\r\n smell.style.left = '0';\r\n smell.style.fontSize = '8px';\r\n smell.style.opacity = '0.5';\r\n smell.className = 'kitty-poop-smell';\r\n this.element.appendChild(smell);\r\n\r\n this.container.appendChild(this.element);\r\n\r\n // Auto-remove after 30 seconds\r\n setTimeout(() => {\r\n this.element.style.transition = 'opacity 2s';\r\n this.element.style.opacity = '0';\r\n setTimeout(() => {\r\n if (this.element.parentNode) this.container.removeChild(this.element);\r\n }, 2000);\r\n }, 30000);\r\n }\r\n}\r\n","export interface Step {\r\n x: number;\r\n y: number;\r\n t: number;\r\n opacity: number;\r\n}\r\n\r\nexport class Footsteps {\r\n private steps: Step[] = [];\r\n private container: HTMLElement;\r\n private maxSteps = 50;\r\n\r\n constructor(container: HTMLElement) {\r\n this.container = container;\r\n }\r\n\r\n addStep(x: number, y: number) {\r\n const step: Step = { x, y, t: Date.now(), opacity: 0.4 };\r\n this.steps.push(step);\r\n \r\n const el = document.createElement('div');\r\n el.style.position = 'absolute';\r\n el.style.left = `${x}px`;\r\n el.style.top = `${y}px`;\r\n el.style.width = '4px';\r\n el.style.height = '4px';\r\n el.style.background = 'rgba(0,0,0,0.1)';\r\n el.style.borderRadius = '50%';\r\n el.style.pointerEvents = 'none';\r\n this.container.appendChild(el);\r\n\r\n if (this.steps.length > this.maxSteps) {\r\n this.steps.shift();\r\n const firstChild = this.container.firstChild;\r\n if (firstChild) this.container.removeChild(firstChild);\r\n }\r\n\r\n // Fade effect logic would be handled in update if we wanted high precision\r\n // For simplicity, we can use CSS animations or simple timeout\r\n setTimeout(() => {\r\n if (el.parentNode) el.style.opacity = '0';\r\n setTimeout(() => {\r\n if (el.parentNode) this.container.removeChild(el);\r\n }, 1000);\r\n }, 2000);\r\n }\r\n}\r\n","import { BasePet } from '../basePet';\r\nimport { KittySprite } from './sprite';\r\nimport { KittyAI, KittyState } from './ai';\r\nimport { PhysicsEngine } from '../../core/physics';\r\nimport { YarnBall } from './ball';\r\nimport { Poop } from './poop';\r\nimport { Footsteps } from './footsteps';\r\nimport { gsap } from 'gsap';\r\nimport { Body, Vector } from 'matter-js';\r\n\r\nexport class Kitty extends BasePet {\r\n private sprite: KittySprite;\r\n private ai: KittyAI;\r\n private physics: PhysicsEngine;\r\n private ball: YarnBall | null = null;\r\n private footsteps: Footsteps | null = null;\r\n private lastTime: number = 0;\r\n private poops: Poop[] = [];\r\n \r\n private lastStepX: number = 0;\r\n private stepDistance: number = 20;\r\n\r\n constructor() {\r\n super();\r\n this.sprite = new KittySprite();\r\n this.ai = new KittyAI();\r\n this.physics = new PhysicsEngine();\r\n this.x = Math.random() * (window.innerWidth - 64);\r\n this.y = window.innerHeight - 80;\r\n }\r\n\r\n mount(container: HTMLElement): void {\r\n this.container = container;\r\n this.element = this.sprite.getElement();\r\n this.element.style.position = 'absolute';\r\n this.element.style.zIndex = '2147483647';\r\n this.container.appendChild(this.element);\r\n \r\n this.physics.addFloor(window.innerWidth, window.innerHeight);\r\n this.footsteps = new Footsteps(container);\r\n \r\n // Funny Feature: Laser Pointer (hold Shift)\r\n this.setupLaserPointer();\r\n\r\n // Funny Feature: Scared Jump\r\n this.element.style.pointerEvents = 'auto';\r\n this.element.addEventListener('mousedown', () => this.handleScaredJump());\r\n \r\n // Randomly spawn a yarn ball\r\n setTimeout(() => this.spawnBall(), 5000);\r\n\r\n window.addEventListener('resize', this.handleResize.bind(this));\r\n\r\n this.setPosition(this.x, this.y);\r\n requestAnimationFrame(this.tick.bind(this));\r\n }\r\n\r\n private handleResize() {\r\n this.physics.addFloor(window.innerWidth, window.innerHeight);\r\n }\r\n\r\n private spawnBall() {\r\n if (!this.container) return;\r\n const body = this.physics.addBall(Math.random() * window.innerWidth, -50, 12);\r\n this.ball = new YarnBall(this.container, body);\r\n }\r\n\r\n update(delta: number): void {\r\n const ballPos = this.ball ? this.ball.body.position : undefined;\r\n const { state, x, y, facing } = this.ai.update(delta, this.x, this.y, ballPos);\r\n \r\n // Random Meow\r\n if (Math.random() < 0.001) {\r\n const texts = [\"MEOW\", \"PURR\", \"HELLO\", \"JS FTW\", \"PET ME\", \"I LOVE CODE\", \"FEED ME\", \"MEOWWW\"];\r\n this.sprite.showMessage(texts[Math.floor(Math.random() * texts.length)]);\r\n }\r\n\r\n // Handle State Changes\r\n if (state !== this.state) {\r\n this.onStateChange(this.state as KittyState, state);\r\n this.state = state;\r\n }\r\n\r\n this.x = x;\r\n this.y = y;\r\n\r\n // Physics update\r\n this.physics.update(delta);\r\n if (this.ball) this.ball.update();\r\n\r\n // Footprints\r\n if (this.state.includes('walk') || this.state === 'chase-ball' || this.state === 'zoomies') {\r\n if (Math.abs(this.x - this.lastStepX) > this.stepDistance) {\r\n this.footsteps?.addStep(this.x + 32, this.y + 56);\r\n this.lastStepX = this.x;\r\n }\r\n }\r\n\r\n // Interaction with ball\r\n if (this.ball && (state === 'chase-ball' || state === 'pounce')) {\r\n const dist = Vector.magnitude(Vector.sub(this.ball.body.position, { x: this.x + 32, y: this.y + 32 }));\r\n if (dist < 60) {\r\n // Kick the ball!\r\n const force = Vector.create(facing === 'left' ? -0.08 : 0.08, -0.04);\r\n Body.applyForce(this.ball.body, this.ball.body.position, force);\r\n }\r\n }\r\n\r\n this.sprite.update(delta, state, facing);\r\n this.setPosition(this.x, this.y);\r\n }\r\n\r\n private onStateChange(oldState: KittyState, newState: KittyState) {\r\n if (newState === 'poop' && this.container) {\r\n setTimeout(() => {\r\n this.poops.push(new Poop(this.container!, this.x + 20, this.y + 40));\r\n }, 2000);\r\n }\r\n\r\n if (newState === 'jump') {\r\n this.sprite.showMessage(\"BOING!\", 1000);\r\n gsap.to(this.element, {\r\n y: this.y - 100,\r\n duration: 0.5,\r\n ease: \"power2.out\",\r\n yoyo: true,\r\n repeat: 1,\r\n onComplete: () => {\r\n this.setPosition(this.x, this.y);\r\n }\r\n });\r\n }\r\n\r\n if (newState === 'sleep') {\r\n this.sprite.showMessage(\"Zzz...\", 2000);\r\n }\r\n\r\n if (newState === 'poop') {\r\n this.sprite.showMessage(\"Oopsy!\", 2000);\r\n }\r\n\r\n if (newState === 'purr') {\r\n this.sprite.showMessage(\"❤️ PURRR ❤️\", 3000);\r\n }\r\n }\r\n\r\n private handleScaredJump() {\r\n if (this.state === 'sleep' || this.state === 'idle' || this.state === 'sit') {\r\n // Add a \"vibration\" effect before jumping for comedy\r\n gsap.to(this.element, { x: \"+=2\", yoyo: true, repeat: 10, duration: 0.05 });\r\n setTimeout(() => {\r\n this.onStateChange(this.state as KittyState, 'jump');\r\n }, 500);\r\n }\r\n }\r\n\r\n private laserActive = false;\r\n private laserEl: HTMLDivElement | null = null;\r\n\r\n private setupLaserPointer() {\r\n window.addEventListener('keydown', (e) => {\r\n if (e.shiftKey) {\r\n this.laserActive = true;\r\n this.showLaser();\r\n }\r\n });\r\n window.addEventListener('keyup', (e) => {\r\n if (!e.shiftKey) {\r\n this.laserActive = false;\r\n this.hideLaser();\r\n }\r\n });\r\n window.addEventListener('mousemove', (e) => {\r\n if (this.laserActive && this.laserEl) {\r\n this.laserEl.style.transform = `translate(${e.clientX - 4}px, ${e.clientY - 4}px)`;\r\n // Force kitty AI to track laser using casting to bypass private access for demonstration\r\n (this.ai as any).mouseX = e.clientX;\r\n (this.ai as any).mouseY = e.clientY;\r\n (this.ai as any).isChasingMouse = true;\r\n }\r\n });\r\n }\r\n\r\n private showLaser() {\r\n if (!this.container || this.laserEl) return;\r\n this.laserEl = document.createElement('div');\r\n Object.assign(this.laserEl.style, {\r\n position: 'fixed',\r\n width: '8px',\r\n height: '8px',\r\n borderRadius: '50%',\r\n background: 'red',\r\n boxShadow: '0 0 10px red',\r\n pointerEvents: 'none',\r\n zIndex: '2147483647',\r\n top: '0',\r\n left: '0'\r\n });\r\n this.container.appendChild(this.laserEl);\r\n }\r\n\r\n private hideLaser() {\r\n if (this.laserEl && this.laserEl.parentNode) {\r\n this.laserEl.parentNode.removeChild(this.laserEl);\r\n }\r\n this.laserEl = null;\r\n }\r\n\r\n private tick(time: number) {\r\n if (!this.lastTime) this.lastTime = time;\r\n const delta = time - this.lastTime;\r\n this.lastTime = time;\r\n\r\n this.update(delta);\r\n \r\n if (this.element && this.element.parentNode) {\r\n requestAnimationFrame(this.tick.bind(this));\r\n }\r\n }\r\n\r\n destroy(): void {\r\n if (this.element && this.element.parentNode) {\r\n this.element.parentNode.removeChild(this.element);\r\n }\r\n this.element = null;\r\n // Cleanup other parts\r\n }\r\n}\r\n","import { isLocalhost } from './environment';\r\nimport { Overlay } from './overlay';\r\nimport { Kitty } from '../pets/kitty/kitty';\r\n\r\nexport const inject = () => {\r\n if (!isLocalhost()) return;\r\n\r\n // Wait for DOM to be ready\r\n if (document.readyState === 'loading') {\r\n document.addEventListener('DOMContentLoaded', init);\r\n } else {\r\n init();\r\n }\r\n};\r\n\r\nlet overlay: Overlay | null = null;\r\nlet kitty: Kitty | null = null;\r\n\r\nfunction init() {\r\n if (overlay) return; // Already initialized\r\n\r\n overlay = new Overlay();\r\n overlay.mount();\r\n\r\n kitty = new Kitty();\r\n kitty.mount(overlay.shadowContainer);\r\n}\r\n\r\nexport const destroy = () => {\r\n if (kitty) kitty.destroy();\r\n if (overlay) overlay.destroy();\r\n kitty = null;\r\n overlay = null;\r\n};\r\n","import type { Plugin } from 'vite';\r\n\r\nexport function devKittyPlugin(): Plugin {\r\n return {\r\n name: 'vite-plugin-dev-kitty',\r\n apply: 'serve', // Only in dev mode\r\n transformIndexHtml(html: string) {\r\n return {\r\n html,\r\n tags: [\r\n {\r\n tag: 'script',\r\n attrs: { type: 'module' },\r\n children: 'import \"dev-kitty\";',\r\n injectTo: 'body'\r\n }\r\n ]\r\n };\r\n }\r\n };\r\n}\r\n"],"mappings":"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","names":["index_exports","__export","Kitty","Overlay","index_default","destroy","devKittyPlugin","inject","__toCommonJS","isLocalhost","hostname","Overlay","__publicField","BasePet","__publicField","x","y","_KittySprite","__publicField","svg","delta","state","facing","head","body","tail","zzz","legs","eyes","e","l","off","i","legOff","leg","vib","text","duration","bubble","bubbleText","KittySprite","KittyAI","__publicField","e","delta","currentX","currentY","ballPos","width","margin","distToMouse","oldState","nextX","nextY","moveSpeed","dx","groundY","targetY","state","roll","import_matter_js","PhysicsEngine","__publicField","delta","cappedDelta","x","y","radius","ball","width","height","import_matter_js","YarnBall","container","body","__publicField","isDragging","e","x","y","Poop","container","x","y","__publicField","smell","Footsteps","container","__publicField","x","y","step","el","firstChild","import_gsap","import_matter_js","Kitty","BasePet","__publicField","KittySprite","KittyAI","PhysicsEngine","container","Footsteps","body","YarnBall","delta","ballPos","state","x","y","facing","texts","force","oldState","newState","Poop","time","inject","isLocalhost","init","overlay","kitty","Overlay","Kitty","destroy","devKittyPlugin","html","inject","index_default","inject","devKittyPlugin"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,31 @@
1
+ var B=Object.defineProperty;var F=(o,t,e)=>t in o?B(o,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[t]=e;var i=(o,t,e)=>F(o,typeof t!="symbol"?t+"":t,e);var H=()=>{if(typeof window>"u")return!1;let o=window.location.hostname;return o==="localhost"||o==="127.0.0.1"||o.endsWith(".local")||o==="[::1]"};var y=class{constructor(){i(this,"container");i(this,"shadow");i(this,"shadowContainer");this.container=document.createElement("div"),this.container.id="dev-kitty-overlay",Object.assign(this.container.style,{position:"fixed",top:"0",left:"0",width:"100vw",height:"100vh",pointerEvents:"none",zIndex:"2147483647"}),this.shadow=this.container.attachShadow({mode:"open"}),this.shadowContainer=document.createElement("div"),this.shadowContainer.id="dev-kitty-root",Object.assign(this.shadowContainer.style,{width:"100%",height:"100%",position:"relative",overflow:"hidden"}),this.shadow.appendChild(this.shadowContainer)}mount(){document.getElementById("dev-kitty-overlay")||document.body.appendChild(this.container)}destroy(){this.container.parentNode&&this.container.parentNode.removeChild(this.container)}};var w=class{constructor(){i(this,"container",null);i(this,"element",null);i(this,"x",0);i(this,"y",0);i(this,"state","idle")}setPosition(t,e){this.x=t,this.y=e,this.element&&(this.element.style.transform=`translate(${Math.round(t)}px, ${Math.round(e)}px)`)}};var x=class x{constructor(){i(this,"element");i(this,"currentFrame",0);i(this,"animationTimer",0);i(this,"frameRate",250);this.element=document.createElement("div"),this.element.style.width="64px",this.element.style.height="64px",this.element.style.imageRendering="pixelated",this.element.innerHTML=x.SVG_TEMPLATE;let t=this.element.querySelector("svg");t&&(t.style.width="100%",t.style.height="100%")}getElement(){return this.element}update(t,e,n){this.animationTimer+=t,this.animationTimer>=this.frameRate&&(this.animationTimer=0,this.currentFrame=(this.currentFrame+1)%4,this.animate(e,n))}animate(t,e){let n=this.element.querySelector("svg");if(!n)return;let s=n.querySelector("#head"),l=n.querySelector("#body"),d=n.querySelector("#tail"),m=n.querySelector("#zzz"),r=n.querySelectorAll(".leg"),c=n.querySelectorAll(".eye");switch(e==="left"?this.element.style.transform="scaleX(-1)":this.element.style.transform="scaleX(1)",m.style.display="none",c.forEach(h=>h.setAttribute("fill","#fff")),r.forEach(h=>h.setAttribute("height","4")),d.setAttribute("transform",""),l.setAttribute("y","14"),s.setAttribute("y","8"),l.setAttribute("width","14"),t){case"walk-left":case"walk-right":case"chase-ball":case"zoomies":case"pounce":let h=this.currentFrame%2===0?2:0;r.forEach((a,A)=>{let f=A%2===0?h:2-h;a.setAttribute("y",(24+f).toString())}),d.setAttribute("transform",`rotate(${Math.sin(Date.now()/100)*15} 4 17)`),t==="zoomies"&&(this.element.style.transform+=` rotate(${Math.sin(Date.now()/50)*10}deg)`);break;case"sleep":c.forEach(a=>a.setAttribute("fill","transparent")),m.style.display="block",m.style.opacity=(.5+Math.sin(Date.now()/500)*.5).toString(),r.forEach(a=>a.setAttribute("height","2")),l.setAttribute("y","15"),s.setAttribute("y","9");break;case"sit":case"lick-paw":if(r.forEach(a=>a.setAttribute("height","2")),s.setAttribute("y","8"),t==="lick-paw"){let a=r[0];a.setAttribute("height","4"),a.setAttribute("y",(22+Math.sin(Date.now()/100)*2).toString())}break;case"poop":this.element.style.transform+=" rotate(10deg)",r.forEach(a=>a.setAttribute("height","2"));break;case"stretch":l.setAttribute("width",this.currentFrame%2===0?"16":"14");break;case"jump":r.forEach(a=>a.setAttribute("height","6"));break;case"stare":c.forEach(a=>{a.setAttribute("width","3"),a.setAttribute("height","3")});break;case"purr":let p=Math.sin(Date.now()/30)*1;s.setAttribute("y",(8+p).toString()),l.setAttribute("y",(14+p).toString());break;default:d.setAttribute("transform",`rotate(${Math.sin(Date.now()/300)*5} 4 17)`),Math.random()<.1&&c.forEach(a=>a.setAttribute("fill","transparent"));break}}showMessage(t,e=2e3){let n=this.element.querySelector("svg");if(!n)return;let s=n.querySelector("#bubble"),l=n.querySelector("#bubble-text");l.textContent=t,s.style.display="block",setTimeout(()=>{s.style.display="none"},e)}};i(x,"SVG_TEMPLATE",`
2
+ <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" shape-rendering="crispEdges">
3
+ <!-- Tail -->
4
+ <rect x="2" y="16" width="6" height="2" fill="#333" id="tail" />
5
+ <!-- Body -->
6
+ <rect x="8" y="14" width="14" height="10" fill="#333" id="body" />
7
+ <!-- Head -->
8
+ <rect x="16" y="8" width="10" height="10" fill="#333" id="head" />
9
+ <!-- Ears -->
10
+ <rect x="17" y="5" width="3" height="3" fill="#333" id="ear-l" />
11
+ <rect x="23" y="5" width="3" height="3" fill="#333" id="ear-r" />
12
+ <!-- Eyes -->
13
+ <rect x="19" y="11" width="2" height="2" fill="#fff" class="eye" />
14
+ <rect x="24" y="11" width="2" height="2" fill="#fff" class="eye" />
15
+ <!-- Nose -->
16
+ <rect x="23" y="14" width="2" height="1" fill="#ffb7b7" />
17
+ <!-- Legs -->
18
+ <rect x="9" y="24" width="3" height="4" fill="#333" class="leg leg-fl" />
19
+ <rect x="13" y="24" width="3" height="4" fill="#333" class="leg leg-fr" />
20
+ <rect x="17" y="24" width="3" height="4" fill="#333" class="leg leg-bl" />
21
+ <rect x="20" y="24" width="3" height="4" fill="#333" class="leg leg-br" />
22
+ <!-- Speech Bubble -->
23
+ <g id="bubble" style="display:none">
24
+ <rect x="0" y="0" width="30" height="10" rx="2" fill="white" stroke="#333" stroke-width="0.5" />
25
+ <text x="15" y="7" font-family="monospace" font-size="4" text-anchor="middle" fill="#333" id="bubble-text">MEOW</text>
26
+ </g>
27
+ <!-- Sleep Zzz (hidden by default) -->
28
+ <text x="2" y="10" font-family="Arial" font-size="6" fill="#aaa" id="zzz" style="display:none">Zzz</text>
29
+ </svg>
30
+ `);var v=x;var S=class{constructor(){i(this,"currentState","idle");i(this,"stateTimer",0);i(this,"speed",2.5);i(this,"mouseX",0);i(this,"mouseY",0);i(this,"isChasingMouse",!1);i(this,"facing","right");typeof window<"u"&&window.addEventListener("mousemove",t=>{this.mouseX=t.clientX,this.mouseY=t.clientY})}update(t,e,n,s){this.stateTimer+=t;let l=64,d=20,m=Math.sqrt(Math.pow(this.mouseX-(e+32),2)+Math.pow(this.mouseY-(n+32),2));if(m<200&&Math.random()<.05&&!this.isChasingMouse&&this.currentState!=="sleep"&&(this.isChasingMouse=!0,this.currentState="chase-ball"),this.isChasingMouse&&(m<40&&(this.isChasingMouse=!1,this.currentState="sit",this.stateTimer=0),m>500&&(this.isChasingMouse=!1)),this.stateTimer>this.getStateDuration(this.currentState)){this.stateTimer=0,this.isChasingMouse=!1;let A=this.currentState;this.currentState=this.getNextState(),this.currentState==="walk-left"&&(this.facing="left"),this.currentState==="walk-right"&&(this.facing="right")}let r=e,c=n,h=this.getSpeedForState(this.currentState);switch(this.currentState){case"walk-left":r-=h,this.facing="left";break;case"walk-right":r+=h,this.facing="right";break;case"zoomies":r+=(Math.random()-.5)*h*2;break;case"chase-ball":let f=(this.isChasingMouse?{x:this.mouseX,y:this.mouseY}:s||{x:r,y:c}).x-32-r;r+=Math.sign(f)*h,f!==0&&(this.facing=f<0?"left":"right");break;case"pounce":r+=(this.facing==="left"?-1:1)*h;break}r<d?(r=d,this.currentState==="walk-left"&&(this.currentState="walk-right")):r>window.innerWidth-l-d&&(r=window.innerWidth-l-d,this.currentState==="walk-right"&&(this.currentState="walk-left"));let p=window.innerHeight-80,a=p;return this.isChasingMouse&&(a=Math.min(this.mouseY-32,p)),c+=(a-c)*.1,{state:this.currentState,x:r,y:c,facing:this.facing}}getSpeedForState(t){switch(t){case"walk-left":case"walk-right":return this.speed;case"chase-ball":return this.speed*2.5;case"zoomies":return this.speed*5;case"pounce":return this.speed*4;default:return 0}}getStateDuration(t){switch(t){case"idle":return 1500+Math.random()*2e3;case"walk-left":case"walk-right":return 2e3+Math.random()*3e3;case"sleep":return 1e4+Math.random()*15e3;case"sit":return 3e3+Math.random()*4e3;case"poop":return 4e3;case"scratch":return 2e3;case"stare":return 3e3;case"stretch":return 2e3;case"zoomies":return 1500+Math.random()*1e3;case"lick-paw":return 3e3;case"pounce":return 800;case"purr":return 5e3;default:return 2e3}}getNextState(){let t=Math.random();return t<.15?"walk-left":t<.3?"walk-right":t<.45?"idle":t<.55?"sit":t<.65?"sleep":t<.72?"stare":t<.77?"lick-paw":t<.82?"scratch":t<.86?"stretch":t<.9?"jump":t<.93?"zoomies":t<.95?"pounce":t<.98?"purr":"poop"}getState(){return this.currentState}};import{Engine as V,World as z,Bodies as G}from"matter-js";var E=class{constructor(){i(this,"engine");i(this,"world");i(this,"floor",null);this.engine=V.create(),this.world=this.engine.world,this.engine.gravity.y=.5}update(t){let n=Math.min(t,16.666666666666668*2);V.update(this.engine,n)}addBall(t,e,n){let s=G.circle(t,e,n,{restitution:.8,friction:.05,frictionAir:.02,label:"ball"});return z.add(this.world,s),s}addFloor(t,e){return this.floor&&z.remove(this.world,this.floor),this.floor=G.rectangle(t/2,e+50,t,100,{isStatic:!0,label:"floor"}),z.add(this.world,this.floor),this.floor}};import{Body as M}from"matter-js";var k=class{constructor(t,e){i(this,"element");i(this,"body");this.body=e,this.element=document.createElement("div"),this.element.innerHTML="\u{1F9F6}",this.element.style.position="absolute",this.element.style.width="24px",this.element.style.height="24px",this.element.style.fontSize="20px",this.element.style.display="flex",this.element.style.alignItems="center",this.element.style.justifyContent="center",this.element.style.pointerEvents="auto",this.element.style.cursor="grab",this.element.style.zIndex="2147483646";let n=!1;this.element.addEventListener("mousedown",()=>{n=!0,this.element.style.cursor="grabbing",M.setStatic(this.body,!0)}),window.addEventListener("mousemove",s=>{n&&M.setPosition(this.body,{x:s.clientX,y:s.clientY})}),window.addEventListener("mouseup",()=>{n&&(n=!1,this.element.style.cursor="grab",M.setStatic(this.body,!1),M.setVelocity(this.body,{x:(Math.random()-.5)*10,y:-5}))}),t.appendChild(this.element)}update(){let{x:t,y:e}=this.body.position;this.element.style.transform=`translate(${t-12}px, ${e-12}px) rotate(${this.body.angle}rad)`}};var T=class{constructor(t,e,n){i(this,"element");i(this,"container");this.container=t,this.element=document.createElement("div"),this.element.innerHTML="\u{1F4A9}",this.element.style.position="absolute",this.element.style.left=`${e}px`,this.element.style.top=`${n}px`,this.element.style.fontSize="12px",this.element.style.pointerEvents="none",this.element.style.zIndex="2147483646";let s=document.createElement("div");s.innerHTML="\u3030\uFE0F",s.style.position="absolute",s.style.top="-10px",s.style.left="0",s.style.fontSize="8px",s.style.opacity="0.5",s.className="kitty-poop-smell",this.element.appendChild(s),this.container.appendChild(this.element),setTimeout(()=>{this.element.style.transition="opacity 2s",this.element.style.opacity="0",setTimeout(()=>{this.element.parentNode&&this.container.removeChild(this.element)},2e3)},3e4)}};var L=class{constructor(t){i(this,"steps",[]);i(this,"container");i(this,"maxSteps",50);this.container=t}addStep(t,e){let n={x:t,y:e,t:Date.now(),opacity:.4};this.steps.push(n);let s=document.createElement("div");if(s.style.position="absolute",s.style.left=`${t}px`,s.style.top=`${e}px`,s.style.width="4px",s.style.height="4px",s.style.background="rgba(0,0,0,0.1)",s.style.borderRadius="50%",s.style.pointerEvents="none",this.container.appendChild(s),this.steps.length>this.maxSteps){this.steps.shift();let l=this.container.firstChild;l&&this.container.removeChild(l)}setTimeout(()=>{s.parentNode&&(s.style.opacity="0"),setTimeout(()=>{s.parentNode&&this.container.removeChild(s)},1e3)},2e3)}};import{gsap as K}from"gsap";import{Body as N,Vector as R}from"matter-js";var b=class extends w{constructor(){super();i(this,"sprite");i(this,"ai");i(this,"physics");i(this,"ball",null);i(this,"footsteps",null);i(this,"lastTime",0);i(this,"poops",[]);i(this,"lastStepX",0);i(this,"stepDistance",20);i(this,"laserActive",!1);i(this,"laserEl",null);this.sprite=new v,this.ai=new S,this.physics=new E,this.x=Math.random()*(window.innerWidth-64),this.y=window.innerHeight-80}mount(e){this.container=e,this.element=this.sprite.getElement(),this.element.style.position="absolute",this.element.style.zIndex="2147483647",this.container.appendChild(this.element),this.physics.addFloor(window.innerWidth,window.innerHeight),this.footsteps=new L(e),this.setupLaserPointer(),this.element.style.pointerEvents="auto",this.element.addEventListener("mousedown",()=>this.handleScaredJump()),setTimeout(()=>this.spawnBall(),5e3),window.addEventListener("resize",this.handleResize.bind(this)),this.setPosition(this.x,this.y),requestAnimationFrame(this.tick.bind(this))}handleResize(){this.physics.addFloor(window.innerWidth,window.innerHeight)}spawnBall(){if(!this.container)return;let e=this.physics.addBall(Math.random()*window.innerWidth,-50,12);this.ball=new k(this.container,e)}update(e){let n=this.ball?this.ball.body.position:void 0,{state:s,x:l,y:d,facing:m}=this.ai.update(e,this.x,this.y,n);if(Math.random()<.001){let r=["MEOW","PURR","HELLO","JS FTW","PET ME","I LOVE CODE","FEED ME","MEOWWW"];this.sprite.showMessage(r[Math.floor(Math.random()*r.length)])}if(s!==this.state&&(this.onStateChange(this.state,s),this.state=s),this.x=l,this.y=d,this.physics.update(e),this.ball&&this.ball.update(),(this.state.includes("walk")||this.state==="chase-ball"||this.state==="zoomies")&&Math.abs(this.x-this.lastStepX)>this.stepDistance&&(this.footsteps?.addStep(this.x+32,this.y+56),this.lastStepX=this.x),this.ball&&(s==="chase-ball"||s==="pounce")&&R.magnitude(R.sub(this.ball.body.position,{x:this.x+32,y:this.y+32}))<60){let c=R.create(m==="left"?-.08:.08,-.04);N.applyForce(this.ball.body,this.ball.body.position,c)}this.sprite.update(e,s,m),this.setPosition(this.x,this.y)}onStateChange(e,n){n==="poop"&&this.container&&setTimeout(()=>{this.poops.push(new T(this.container,this.x+20,this.y+40))},2e3),n==="jump"&&(this.sprite.showMessage("BOING!",1e3),K.to(this.element,{y:this.y-100,duration:.5,ease:"power2.out",yoyo:!0,repeat:1,onComplete:()=>{this.setPosition(this.x,this.y)}})),n==="sleep"&&this.sprite.showMessage("Zzz...",2e3),n==="poop"&&this.sprite.showMessage("Oopsy!",2e3),n==="purr"&&this.sprite.showMessage("\u2764\uFE0F PURRR \u2764\uFE0F",3e3)}handleScaredJump(){(this.state==="sleep"||this.state==="idle"||this.state==="sit")&&(K.to(this.element,{x:"+=2",yoyo:!0,repeat:10,duration:.05}),setTimeout(()=>{this.onStateChange(this.state,"jump")},500))}setupLaserPointer(){window.addEventListener("keydown",e=>{e.shiftKey&&(this.laserActive=!0,this.showLaser())}),window.addEventListener("keyup",e=>{e.shiftKey||(this.laserActive=!1,this.hideLaser())}),window.addEventListener("mousemove",e=>{this.laserActive&&this.laserEl&&(this.laserEl.style.transform=`translate(${e.clientX-4}px, ${e.clientY-4}px)`,this.ai.mouseX=e.clientX,this.ai.mouseY=e.clientY,this.ai.isChasingMouse=!0)})}showLaser(){!this.container||this.laserEl||(this.laserEl=document.createElement("div"),Object.assign(this.laserEl.style,{position:"fixed",width:"8px",height:"8px",borderRadius:"50%",background:"red",boxShadow:"0 0 10px red",pointerEvents:"none",zIndex:"2147483647",top:"0",left:"0"}),this.container.appendChild(this.laserEl))}hideLaser(){this.laserEl&&this.laserEl.parentNode&&this.laserEl.parentNode.removeChild(this.laserEl),this.laserEl=null}tick(e){this.lastTime||(this.lastTime=e);let n=e-this.lastTime;this.lastTime=e,this.update(n),this.element&&this.element.parentNode&&requestAnimationFrame(this.tick.bind(this))}destroy(){this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null}};var C=()=>{H()&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",D):D())},u=null,g=null;function D(){u||(u=new y,u.mount(),g=new b,g.mount(u.shadowContainer))}var O=()=>{g&&g.destroy(),u&&u.destroy(),g=null,u=null};function P(){return{name:"vite-plugin-dev-kitty",apply:"serve",transformIndexHtml(o){return{html:o,tags:[{tag:"script",attrs:{type:"module"},children:'import "dev-kitty";',injectTo:"body"}]}}}}typeof window<"u"&&C();var zt={init:C,plugin:P};export{b as Kitty,y as Overlay,zt as default,O as destroy,P as devKittyPlugin,C as inject};
31
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/environment.ts","../src/core/overlay.ts","../src/pets/basePet.ts","../src/pets/kitty/sprite.ts","../src/pets/kitty/ai.ts","../src/core/physics.ts","../src/pets/kitty/ball.ts","../src/pets/kitty/poop.ts","../src/pets/kitty/footsteps.ts","../src/pets/kitty/kitty.ts","../src/core/injector.ts","../src/plugins/vite.ts","../src/index.ts"],"sourcesContent":["export const isLocalhost = (): boolean => {\r\n if (typeof window === 'undefined') return false;\r\n\r\n const hostname = window.location.hostname;\r\n\r\n return (\r\n hostname === 'localhost' ||\r\n hostname === '127.0.0.1' ||\r\n hostname.endsWith('.local') ||\r\n hostname === '[::1]'\r\n );\r\n};\r\n","export class Overlay {\r\n private container: HTMLDivElement;\r\n private shadow: ShadowRoot;\r\n public shadowContainer: HTMLDivElement;\r\n\r\n constructor() {\r\n this.container = document.createElement('div');\r\n this.container.id = 'dev-kitty-overlay';\r\n \r\n // Core styles for the container\r\n Object.assign(this.container.style, {\r\n position: 'fixed',\r\n top: '0',\r\n left: '0',\r\n width: '100vw',\r\n height: '100vh',\r\n pointerEvents: 'none',\r\n zIndex: '2147483647',\r\n });\r\n\r\n this.shadow = this.container.attachShadow({ mode: 'open' });\r\n this.shadowContainer = document.createElement('div');\r\n this.shadowContainer.id = 'dev-kitty-root';\r\n \r\n // Root container in shadow DOM\r\n Object.assign(this.shadowContainer.style, {\r\n width: '100%',\r\n height: '100%',\r\n position: 'relative',\r\n overflow: 'hidden',\r\n });\r\n\r\n this.shadow.appendChild(this.shadowContainer);\r\n }\r\n\r\n mount() {\r\n if (!document.getElementById('dev-kitty-overlay')) {\r\n document.body.appendChild(this.container);\r\n }\r\n }\r\n\r\n destroy() {\r\n if (this.container.parentNode) {\r\n this.container.parentNode.removeChild(this.container);\r\n }\r\n }\r\n}\r\n","export abstract class BasePet {\r\n protected container: HTMLElement | null = null;\r\n protected element: HTMLElement | null = null;\r\n protected x: number = 0;\r\n protected y: number = 0;\r\n protected state: string = 'idle';\r\n\r\n abstract mount(container: HTMLElement): void;\r\n abstract update(delta: number): void;\r\n abstract destroy(): void;\r\n\r\n protected setPosition(x: number, y: number) {\r\n this.x = x;\r\n this.y = y;\r\n if (this.element) {\r\n // Rounding prevents pixel vibration/shimmering on modern displays\r\n this.element.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px)`;\r\n }\r\n }\r\n}\r\n","import { KittyState } from './ai';\r\n\r\nexport class KittySprite {\r\n private element: HTMLElement;\r\n private currentFrame: number = 0;\r\n private animationTimer: number = 0;\r\n private frameRate: number = 250;\r\n\r\n private static readonly SVG_TEMPLATE = `\r\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\" shape-rendering=\"crispEdges\">\r\n <!-- Tail -->\r\n <rect x=\"2\" y=\"16\" width=\"6\" height=\"2\" fill=\"#333\" id=\"tail\" />\r\n <!-- Body -->\r\n <rect x=\"8\" y=\"14\" width=\"14\" height=\"10\" fill=\"#333\" id=\"body\" />\r\n <!-- Head -->\r\n <rect x=\"16\" y=\"8\" width=\"10\" height=\"10\" fill=\"#333\" id=\"head\" />\r\n <!-- Ears -->\r\n <rect x=\"17\" y=\"5\" width=\"3\" height=\"3\" fill=\"#333\" id=\"ear-l\" />\r\n <rect x=\"23\" y=\"5\" width=\"3\" height=\"3\" fill=\"#333\" id=\"ear-r\" />\r\n <!-- Eyes -->\r\n <rect x=\"19\" y=\"11\" width=\"2\" height=\"2\" fill=\"#fff\" class=\"eye\" />\r\n <rect x=\"24\" y=\"11\" width=\"2\" height=\"2\" fill=\"#fff\" class=\"eye\" />\r\n <!-- Nose -->\r\n <rect x=\"23\" y=\"14\" width=\"2\" height=\"1\" fill=\"#ffb7b7\" />\r\n <!-- Legs -->\r\n <rect x=\"9\" y=\"24\" width=\"3\" height=\"4\" fill=\"#333\" class=\"leg leg-fl\" />\r\n <rect x=\"13\" y=\"24\" width=\"3\" height=\"4\" fill=\"#333\" class=\"leg leg-fr\" />\r\n <rect x=\"17\" y=\"24\" width=\"3\" height=\"4\" fill=\"#333\" class=\"leg leg-bl\" />\r\n <rect x=\"20\" y=\"24\" width=\"3\" height=\"4\" fill=\"#333\" class=\"leg leg-br\" />\r\n <!-- Speech Bubble -->\r\n <g id=\"bubble\" style=\"display:none\">\r\n <rect x=\"0\" y=\"0\" width=\"30\" height=\"10\" rx=\"2\" fill=\"white\" stroke=\"#333\" stroke-width=\"0.5\" />\r\n <text x=\"15\" y=\"7\" font-family=\"monospace\" font-size=\"4\" text-anchor=\"middle\" fill=\"#333\" id=\"bubble-text\">MEOW</text>\r\n </g>\r\n <!-- Sleep Zzz (hidden by default) -->\r\n <text x=\"2\" y=\"10\" font-family=\"Arial\" font-size=\"6\" fill=\"#aaa\" id=\"zzz\" style=\"display:none\">Zzz</text>\r\n </svg>\r\n `;\r\n\r\n constructor() {\r\n this.element = document.createElement('div');\r\n this.element.style.width = '64px';\r\n this.element.style.height = '64px';\r\n this.element.style.imageRendering = 'pixelated';\r\n this.element.innerHTML = KittySprite.SVG_TEMPLATE;\r\n \r\n const svg = this.element.querySelector('svg');\r\n if (svg) {\r\n svg.style.width = '100%';\r\n svg.style.height = '100%';\r\n }\r\n }\r\n\r\n getElement() {\r\n return this.element;\r\n }\r\n\r\n update(delta: number, state: KittyState, facing: 'left' | 'right') {\r\n this.animationTimer += delta;\r\n if (this.animationTimer >= this.frameRate) {\r\n this.animationTimer = 0;\r\n this.currentFrame = (this.currentFrame + 1) % 4;\r\n this.animate(state, facing);\r\n }\r\n }\r\n\r\n private animate(state: KittyState, facing: 'left' | 'right') {\r\n const svg = this.element.querySelector('svg');\r\n if (!svg) return;\r\n\r\n const head = svg.querySelector('#head') as SVGRectElement;\r\n const body = svg.querySelector('#body') as SVGRectElement;\r\n const tail = svg.querySelector('#tail') as SVGRectElement;\r\n const zzz = svg.querySelector('#zzz') as SVGTextElement;\r\n const legs = svg.querySelectorAll('.leg');\r\n const eyes = svg.querySelectorAll('.eye');\r\n\r\n // Handle Direction\r\n if (facing === 'left') {\r\n this.element.style.transform = 'scaleX(-1)';\r\n } else {\r\n this.element.style.transform = 'scaleX(1)';\r\n }\r\n\r\n // Reset basics\r\n zzz.style.display = 'none';\r\n eyes.forEach(e => (e as SVGRectElement).setAttribute('fill', '#fff'));\r\n legs.forEach(l => (l as SVGRectElement).setAttribute('height', '4'));\r\n tail.setAttribute('transform', '');\r\n body.setAttribute('y', '14');\r\n head.setAttribute('y', '8');\r\n body.setAttribute('width', '14');\r\n\r\n switch (state) {\r\n case 'walk-left':\r\n case 'walk-right':\r\n case 'chase-ball':\r\n case 'zoomies':\r\n case 'pounce':\r\n // Walk cycle\r\n const off = (this.currentFrame % 2 === 0) ? 2 : 0;\r\n legs.forEach((l, i) => {\r\n const legOff = (i % 2 === 0) ? off : 2 - off;\r\n (l as SVGRectElement).setAttribute('y', (24 + legOff).toString());\r\n });\r\n tail.setAttribute('transform', `rotate(${Math.sin(Date.now()/100)*15} 4 17)`);\r\n \r\n if (state === 'zoomies') {\r\n this.element.style.transform += ` rotate(${Math.sin(Date.now()/50)*10}deg)`;\r\n }\r\n break;\r\n\r\n case 'sleep':\r\n eyes.forEach(e => (e as SVGRectElement).setAttribute('fill', 'transparent'));\r\n zzz.style.display = 'block';\r\n zzz.style.opacity = (0.5 + Math.sin(Date.now()/500) * 0.5).toString();\r\n legs.forEach(l => (l as SVGRectElement).setAttribute('height', '2'));\r\n body.setAttribute('y', '15');\r\n head.setAttribute('y', '9');\r\n break;\r\n\r\n case 'sit':\r\n case 'lick-paw':\r\n legs.forEach(l => (l as SVGRectElement).setAttribute('height', '2'));\r\n head.setAttribute('y', '8');\r\n if (state === 'lick-paw') {\r\n const leg = legs[0] as SVGRectElement;\r\n leg.setAttribute('height', '4');\r\n leg.setAttribute('y', (22 + Math.sin(Date.now()/100)*2).toString());\r\n }\r\n break;\r\n\r\n case 'poop':\r\n this.element.style.transform += ' rotate(10deg)';\r\n legs.forEach(l => (l as SVGRectElement).setAttribute('height', '2'));\r\n break;\r\n\r\n case 'stretch':\r\n body.setAttribute('width', this.currentFrame % 2 === 0 ? '16' : '14');\r\n break;\r\n \r\n case 'jump':\r\n legs.forEach(l => (l as SVGRectElement).setAttribute('height', '6'));\r\n break;\r\n \r\n case 'stare':\r\n // Big eyes when staring\r\n eyes.forEach(e => {\r\n (e as SVGRectElement).setAttribute('width', '3');\r\n (e as SVGRectElement).setAttribute('height', '3');\r\n });\r\n break;\r\n\r\n case 'purr':\r\n const vib = Math.sin(Date.now()/30) * 1;\r\n head.setAttribute('y', (8 + vib).toString());\r\n body.setAttribute('y', (14 + vib).toString());\r\n break;\r\n\r\n default: // idle\r\n tail.setAttribute('transform', `rotate(${Math.sin(Date.now()/300)*5} 4 17)`);\r\n if (Math.random() < 0.1) eyes.forEach(e => (e as SVGRectElement).setAttribute('fill', 'transparent')); // Blink\r\n break;\r\n }\r\n }\r\n\r\n public showMessage(text: string, duration: number = 2000) {\r\n const svg = this.element.querySelector('svg');\r\n if (!svg) return;\r\n const bubble = svg.querySelector('#bubble') as SVGGElement;\r\n const bubbleText = svg.querySelector('#bubble-text') as SVGTextElement;\r\n \r\n bubbleText.textContent = text;\r\n bubble.style.display = 'block';\r\n \r\n setTimeout(() => {\r\n bubble.style.display = 'none';\r\n }, duration);\r\n }\r\n}\r\n","export type KittyState = \r\n | 'idle' \r\n | 'walk-left' \r\n | 'walk-right' \r\n | 'sleep' \r\n | 'sit' \r\n | 'stretch' \r\n | 'jump' \r\n | 'chase-ball' \r\n | 'poop' \r\n | 'scratch'\r\n | 'stare'\r\n | 'zoomies'\r\n | 'lick-paw'\r\n | 'pounce'\r\n | 'purr';\r\n\r\nexport class KittyAI {\r\n private currentState: KittyState = 'idle';\r\n private stateTimer: number = 0;\r\n private speed: number = 2.5;\r\n \r\n private mouseX: number = 0;\r\n private mouseY: number = 0;\r\n private isChasingMouse: boolean = false;\r\n\r\n private facing: 'left' | 'right' = 'right';\r\n\r\n constructor() {\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('mousemove', (e) => {\r\n this.mouseX = e.clientX;\r\n this.mouseY = e.clientY;\r\n });\r\n }\r\n }\r\n\r\n update(delta: number, currentX: number, currentY: number, ballPos?: { x: number, y: number }): { state: KittyState; x: number; y: number, facing: 'left' | 'right' } {\r\n this.stateTimer += delta;\r\n\r\n // --- ENFORCE SCREEN BOUNDARIES ---\r\n const width = 64; // Kitty width is roughly 64px\r\n const margin = 20;\r\n \r\n // Mouse proximity chasing (Cuteness factor)\r\n const distToMouse = Math.sqrt(Math.pow(this.mouseX - (currentX + 32), 2) + Math.pow(this.mouseY - (currentY + 32), 2));\r\n \r\n // Low probability to start chasing if close and not sleeping\r\n if (distToMouse < 200 && Math.random() < 0.05 && !this.isChasingMouse && this.currentState !== 'sleep') {\r\n this.isChasingMouse = true;\r\n this.currentState = 'chase-ball';\r\n }\r\n\r\n if (this.isChasingMouse) {\r\n if (distToMouse < 40) {\r\n this.isChasingMouse = false;\r\n this.currentState = 'sit';\r\n this.stateTimer = 0;\r\n }\r\n // If mouse gets too far, stop chasing\r\n if (distToMouse > 500) {\r\n this.isChasingMouse = false;\r\n }\r\n }\r\n\r\n // Normal State Transitions\r\n if (this.stateTimer > this.getStateDuration(this.currentState)) {\r\n this.stateTimer = 0;\r\n this.isChasingMouse = false;\r\n const oldState = this.currentState;\r\n this.currentState = this.getNextState();\r\n \r\n // Keep track of direction when walking starts\r\n if (this.currentState === 'walk-left') this.facing = 'left';\r\n if (this.currentState === 'walk-right') this.facing = 'right';\r\n }\r\n\r\n let nextX = currentX;\r\n let nextY = currentY;\r\n\r\n // Movement speeds\r\n const moveSpeed = this.getSpeedForState(this.currentState);\r\n\r\n switch (this.currentState) {\r\n case 'walk-left':\r\n nextX -= moveSpeed;\r\n this.facing = 'left';\r\n break;\r\n case 'walk-right':\r\n nextX += moveSpeed;\r\n this.facing = 'right';\r\n break;\r\n case 'zoomies':\r\n // Zoomies moves randomly but fast\r\n nextX += (Math.random() - 0.5) * moveSpeed * 2;\r\n break;\r\n case 'chase-ball':\r\n const target = this.isChasingMouse ? { x: this.mouseX, y: this.mouseY } : (ballPos || { x: nextX, y: nextY });\r\n const dx = (target.x - 32) - nextX;\r\n nextX += Math.sign(dx) * moveSpeed;\r\n if (dx !== 0) this.facing = dx < 0 ? 'left' : 'right';\r\n break;\r\n case 'pounce':\r\n // Pounce is a quick dash forward in current facing direction\r\n nextX += (this.facing === 'left' ? -1 : 1) * moveSpeed;\r\n break;\r\n }\r\n\r\n // Clamp X to screen\r\n if (nextX < margin) {\r\n nextX = margin;\r\n if (this.currentState === 'walk-left') this.currentState = 'walk-right';\r\n } else if (nextX > window.innerWidth - width - margin) {\r\n nextX = window.innerWidth - width - margin;\r\n if (this.currentState === 'walk-right') this.currentState = 'walk-left';\r\n }\r\n\r\n // Smooth Y movement\r\n const groundY = window.innerHeight - 80;\r\n let targetY = groundY;\r\n \r\n // Jump effect handles its own Y usually with GSAP, but we provide a base here\r\n if (this.isChasingMouse) targetY = Math.min(this.mouseY - 32, groundY);\r\n \r\n nextY += (targetY - nextY) * 0.1;\r\n\r\n return { state: this.currentState, x: nextX, y: nextY, facing: this.facing };\r\n }\r\n\r\n private getSpeedForState(state: KittyState): number {\r\n switch (state) {\r\n case 'walk-left':\r\n case 'walk-right': return this.speed;\r\n case 'chase-ball': return this.speed * 2.5;\r\n case 'zoomies': return this.speed * 5;\r\n case 'pounce': return this.speed * 4;\r\n default: return 0;\r\n }\r\n }\r\n\r\n private getStateDuration(state: KittyState): number {\r\n switch (state) {\r\n case 'idle': return 1500 + Math.random() * 2000;\r\n case 'walk-left':\r\n case 'walk-right': return 2000 + Math.random() * 3000;\r\n case 'sleep': return 10000 + Math.random() * 15000;\r\n case 'sit': return 3000 + Math.random() * 4000;\r\n case 'poop': return 4000;\r\n case 'scratch': return 2000;\r\n case 'stare': return 3000;\r\n case 'stretch': return 2000;\r\n case 'zoomies': return 1500 + Math.random() * 1000;\r\n case 'lick-paw': return 3000;\r\n case 'pounce': return 800;\r\n case 'purr': return 5000;\r\n default: return 2000;\r\n }\r\n }\r\n\r\n private getNextState(): KittyState {\r\n const roll = Math.random();\r\n // Weighted selection for better personality\r\n if (roll < 0.15) return 'walk-left';\r\n if (roll < 0.30) return 'walk-right';\r\n if (roll < 0.45) return 'idle';\r\n if (roll < 0.55) return 'sit';\r\n if (roll < 0.65) return 'sleep';\r\n if (roll < 0.72) return 'stare';\r\n if (roll < 0.77) return 'lick-paw';\r\n if (roll < 0.82) return 'scratch';\r\n if (roll < 0.86) return 'stretch';\r\n if (roll < 0.90) return 'jump';\r\n if (roll < 0.93) return 'zoomies';\r\n if (roll < 0.95) return 'pounce';\r\n if (roll < 0.98) return 'purr';\r\n return 'poop';\r\n }\r\n\r\n public getState(): KittyState {\r\n return this.currentState;\r\n }\r\n}\r\n","import { Engine, Render, World, Bodies, Body, Vector } from 'matter-js';\r\n\r\nexport class PhysicsEngine {\r\n public engine: Engine;\r\n public world: World;\r\n\r\n constructor() {\r\n this.engine = Engine.create();\r\n this.world = this.engine.world;\r\n this.engine.gravity.y = 0.5; // Custom gravity\r\n }\r\n\r\n update(delta: number) {\r\n // Matter.js warning fix: Use a fixed timestep or cap the delta\r\n const fixedTimeStep = 1000 / 60; // 16.666ms\r\n const cappedDelta = Math.min(delta, fixedTimeStep * 2); \r\n Engine.update(this.engine, cappedDelta);\r\n }\r\n\r\n addBall(x: number, y: number, radius: number) {\r\n const ball = Bodies.circle(x, y, radius, {\r\n restitution: 0.8,\r\n friction: 0.05,\r\n frictionAir: 0.02,\r\n label: 'ball'\r\n });\r\n World.add(this.world, ball);\r\n return ball;\r\n }\r\n\r\n private floor: Body | null = null;\r\n\r\n addFloor(width: number, height: number) {\r\n if (this.floor) World.remove(this.world, this.floor);\r\n this.floor = Bodies.rectangle(width / 2, height + 50, width, 100, {\r\n isStatic: true,\r\n label: 'floor'\r\n });\r\n World.add(this.world, this.floor);\r\n return this.floor;\r\n }\r\n}\r\n","import { Body } from 'matter-js';\r\n\r\nexport class YarnBall {\r\n public element: HTMLDivElement;\r\n public body: Body;\r\n\r\n constructor(container: HTMLElement, body: Body) {\r\n this.body = body;\r\n this.element = document.createElement('div');\r\n this.element.innerHTML = '🧶';\r\n this.element.style.position = 'absolute';\r\n this.element.style.width = '24px';\r\n this.element.style.height = '24px';\r\n this.element.style.fontSize = '20px';\r\n this.element.style.display = 'flex';\r\n this.element.style.alignItems = 'center';\r\n this.element.style.justifyContent = 'center';\r\n this.element.style.pointerEvents = 'auto'; // Allow interaction\r\n this.element.style.cursor = 'grab';\r\n this.element.style.zIndex = '2147483646';\r\n \r\n // Dragging Logic\r\n let isDragging = false;\r\n this.element.addEventListener('mousedown', () => {\r\n isDragging = true;\r\n this.element.style.cursor = 'grabbing';\r\n Body.setStatic(this.body, true);\r\n });\r\n\r\n window.addEventListener('mousemove', (e) => {\r\n if (!isDragging) return;\r\n Body.setPosition(this.body, { x: e.clientX, y: e.clientY });\r\n });\r\n\r\n window.addEventListener('mouseup', () => {\r\n if (!isDragging) return;\r\n isDragging = false;\r\n this.element.style.cursor = 'grab';\r\n Body.setStatic(this.body, false);\r\n // Give it a little toss\r\n Body.setVelocity(this.body, { x: (Math.random() - 0.5) * 10, y: -5 });\r\n });\r\n\r\n container.appendChild(this.element);\r\n }\r\n\r\n update() {\r\n const { x, y } = this.body.position;\r\n this.element.style.transform = `translate(${x - 12}px, ${y - 12}px) rotate(${this.body.angle}rad)`;\r\n }\r\n}\r\n","export class Poop {\r\n private element: HTMLDivElement;\r\n private container: HTMLElement;\r\n\r\n constructor(container: HTMLElement, x: number, y: number) {\r\n this.container = container;\r\n this.element = document.createElement('div');\r\n this.element.innerHTML = '💩';\r\n this.element.style.position = 'absolute';\r\n this.element.style.left = `${x}px`;\r\n this.element.style.top = `${y}px`;\r\n this.element.style.fontSize = '12px';\r\n this.element.style.pointerEvents = 'none';\r\n this.element.style.zIndex = '2147483646';\r\n \r\n // Smell animation\r\n const smell = document.createElement('div');\r\n smell.innerHTML = '〰️';\r\n smell.style.position = 'absolute';\r\n smell.style.top = '-10px';\r\n smell.style.left = '0';\r\n smell.style.fontSize = '8px';\r\n smell.style.opacity = '0.5';\r\n smell.className = 'kitty-poop-smell';\r\n this.element.appendChild(smell);\r\n\r\n this.container.appendChild(this.element);\r\n\r\n // Auto-remove after 30 seconds\r\n setTimeout(() => {\r\n this.element.style.transition = 'opacity 2s';\r\n this.element.style.opacity = '0';\r\n setTimeout(() => {\r\n if (this.element.parentNode) this.container.removeChild(this.element);\r\n }, 2000);\r\n }, 30000);\r\n }\r\n}\r\n","export interface Step {\r\n x: number;\r\n y: number;\r\n t: number;\r\n opacity: number;\r\n}\r\n\r\nexport class Footsteps {\r\n private steps: Step[] = [];\r\n private container: HTMLElement;\r\n private maxSteps = 50;\r\n\r\n constructor(container: HTMLElement) {\r\n this.container = container;\r\n }\r\n\r\n addStep(x: number, y: number) {\r\n const step: Step = { x, y, t: Date.now(), opacity: 0.4 };\r\n this.steps.push(step);\r\n \r\n const el = document.createElement('div');\r\n el.style.position = 'absolute';\r\n el.style.left = `${x}px`;\r\n el.style.top = `${y}px`;\r\n el.style.width = '4px';\r\n el.style.height = '4px';\r\n el.style.background = 'rgba(0,0,0,0.1)';\r\n el.style.borderRadius = '50%';\r\n el.style.pointerEvents = 'none';\r\n this.container.appendChild(el);\r\n\r\n if (this.steps.length > this.maxSteps) {\r\n this.steps.shift();\r\n const firstChild = this.container.firstChild;\r\n if (firstChild) this.container.removeChild(firstChild);\r\n }\r\n\r\n // Fade effect logic would be handled in update if we wanted high precision\r\n // For simplicity, we can use CSS animations or simple timeout\r\n setTimeout(() => {\r\n if (el.parentNode) el.style.opacity = '0';\r\n setTimeout(() => {\r\n if (el.parentNode) this.container.removeChild(el);\r\n }, 1000);\r\n }, 2000);\r\n }\r\n}\r\n","import { BasePet } from '../basePet';\r\nimport { KittySprite } from './sprite';\r\nimport { KittyAI, KittyState } from './ai';\r\nimport { PhysicsEngine } from '../../core/physics';\r\nimport { YarnBall } from './ball';\r\nimport { Poop } from './poop';\r\nimport { Footsteps } from './footsteps';\r\nimport { gsap } from 'gsap';\r\nimport { Body, Vector } from 'matter-js';\r\n\r\nexport class Kitty extends BasePet {\r\n private sprite: KittySprite;\r\n private ai: KittyAI;\r\n private physics: PhysicsEngine;\r\n private ball: YarnBall | null = null;\r\n private footsteps: Footsteps | null = null;\r\n private lastTime: number = 0;\r\n private poops: Poop[] = [];\r\n \r\n private lastStepX: number = 0;\r\n private stepDistance: number = 20;\r\n\r\n constructor() {\r\n super();\r\n this.sprite = new KittySprite();\r\n this.ai = new KittyAI();\r\n this.physics = new PhysicsEngine();\r\n this.x = Math.random() * (window.innerWidth - 64);\r\n this.y = window.innerHeight - 80;\r\n }\r\n\r\n mount(container: HTMLElement): void {\r\n this.container = container;\r\n this.element = this.sprite.getElement();\r\n this.element.style.position = 'absolute';\r\n this.element.style.zIndex = '2147483647';\r\n this.container.appendChild(this.element);\r\n \r\n this.physics.addFloor(window.innerWidth, window.innerHeight);\r\n this.footsteps = new Footsteps(container);\r\n \r\n // Funny Feature: Laser Pointer (hold Shift)\r\n this.setupLaserPointer();\r\n\r\n // Funny Feature: Scared Jump\r\n this.element.style.pointerEvents = 'auto';\r\n this.element.addEventListener('mousedown', () => this.handleScaredJump());\r\n \r\n // Randomly spawn a yarn ball\r\n setTimeout(() => this.spawnBall(), 5000);\r\n\r\n window.addEventListener('resize', this.handleResize.bind(this));\r\n\r\n this.setPosition(this.x, this.y);\r\n requestAnimationFrame(this.tick.bind(this));\r\n }\r\n\r\n private handleResize() {\r\n this.physics.addFloor(window.innerWidth, window.innerHeight);\r\n }\r\n\r\n private spawnBall() {\r\n if (!this.container) return;\r\n const body = this.physics.addBall(Math.random() * window.innerWidth, -50, 12);\r\n this.ball = new YarnBall(this.container, body);\r\n }\r\n\r\n update(delta: number): void {\r\n const ballPos = this.ball ? this.ball.body.position : undefined;\r\n const { state, x, y, facing } = this.ai.update(delta, this.x, this.y, ballPos);\r\n \r\n // Random Meow\r\n if (Math.random() < 0.001) {\r\n const texts = [\"MEOW\", \"PURR\", \"HELLO\", \"JS FTW\", \"PET ME\", \"I LOVE CODE\", \"FEED ME\", \"MEOWWW\"];\r\n this.sprite.showMessage(texts[Math.floor(Math.random() * texts.length)]);\r\n }\r\n\r\n // Handle State Changes\r\n if (state !== this.state) {\r\n this.onStateChange(this.state as KittyState, state);\r\n this.state = state;\r\n }\r\n\r\n this.x = x;\r\n this.y = y;\r\n\r\n // Physics update\r\n this.physics.update(delta);\r\n if (this.ball) this.ball.update();\r\n\r\n // Footprints\r\n if (this.state.includes('walk') || this.state === 'chase-ball' || this.state === 'zoomies') {\r\n if (Math.abs(this.x - this.lastStepX) > this.stepDistance) {\r\n this.footsteps?.addStep(this.x + 32, this.y + 56);\r\n this.lastStepX = this.x;\r\n }\r\n }\r\n\r\n // Interaction with ball\r\n if (this.ball && (state === 'chase-ball' || state === 'pounce')) {\r\n const dist = Vector.magnitude(Vector.sub(this.ball.body.position, { x: this.x + 32, y: this.y + 32 }));\r\n if (dist < 60) {\r\n // Kick the ball!\r\n const force = Vector.create(facing === 'left' ? -0.08 : 0.08, -0.04);\r\n Body.applyForce(this.ball.body, this.ball.body.position, force);\r\n }\r\n }\r\n\r\n this.sprite.update(delta, state, facing);\r\n this.setPosition(this.x, this.y);\r\n }\r\n\r\n private onStateChange(oldState: KittyState, newState: KittyState) {\r\n if (newState === 'poop' && this.container) {\r\n setTimeout(() => {\r\n this.poops.push(new Poop(this.container!, this.x + 20, this.y + 40));\r\n }, 2000);\r\n }\r\n\r\n if (newState === 'jump') {\r\n this.sprite.showMessage(\"BOING!\", 1000);\r\n gsap.to(this.element, {\r\n y: this.y - 100,\r\n duration: 0.5,\r\n ease: \"power2.out\",\r\n yoyo: true,\r\n repeat: 1,\r\n onComplete: () => {\r\n this.setPosition(this.x, this.y);\r\n }\r\n });\r\n }\r\n\r\n if (newState === 'sleep') {\r\n this.sprite.showMessage(\"Zzz...\", 2000);\r\n }\r\n\r\n if (newState === 'poop') {\r\n this.sprite.showMessage(\"Oopsy!\", 2000);\r\n }\r\n\r\n if (newState === 'purr') {\r\n this.sprite.showMessage(\"❤️ PURRR ❤️\", 3000);\r\n }\r\n }\r\n\r\n private handleScaredJump() {\r\n if (this.state === 'sleep' || this.state === 'idle' || this.state === 'sit') {\r\n // Add a \"vibration\" effect before jumping for comedy\r\n gsap.to(this.element, { x: \"+=2\", yoyo: true, repeat: 10, duration: 0.05 });\r\n setTimeout(() => {\r\n this.onStateChange(this.state as KittyState, 'jump');\r\n }, 500);\r\n }\r\n }\r\n\r\n private laserActive = false;\r\n private laserEl: HTMLDivElement | null = null;\r\n\r\n private setupLaserPointer() {\r\n window.addEventListener('keydown', (e) => {\r\n if (e.shiftKey) {\r\n this.laserActive = true;\r\n this.showLaser();\r\n }\r\n });\r\n window.addEventListener('keyup', (e) => {\r\n if (!e.shiftKey) {\r\n this.laserActive = false;\r\n this.hideLaser();\r\n }\r\n });\r\n window.addEventListener('mousemove', (e) => {\r\n if (this.laserActive && this.laserEl) {\r\n this.laserEl.style.transform = `translate(${e.clientX - 4}px, ${e.clientY - 4}px)`;\r\n // Force kitty AI to track laser using casting to bypass private access for demonstration\r\n (this.ai as any).mouseX = e.clientX;\r\n (this.ai as any).mouseY = e.clientY;\r\n (this.ai as any).isChasingMouse = true;\r\n }\r\n });\r\n }\r\n\r\n private showLaser() {\r\n if (!this.container || this.laserEl) return;\r\n this.laserEl = document.createElement('div');\r\n Object.assign(this.laserEl.style, {\r\n position: 'fixed',\r\n width: '8px',\r\n height: '8px',\r\n borderRadius: '50%',\r\n background: 'red',\r\n boxShadow: '0 0 10px red',\r\n pointerEvents: 'none',\r\n zIndex: '2147483647',\r\n top: '0',\r\n left: '0'\r\n });\r\n this.container.appendChild(this.laserEl);\r\n }\r\n\r\n private hideLaser() {\r\n if (this.laserEl && this.laserEl.parentNode) {\r\n this.laserEl.parentNode.removeChild(this.laserEl);\r\n }\r\n this.laserEl = null;\r\n }\r\n\r\n private tick(time: number) {\r\n if (!this.lastTime) this.lastTime = time;\r\n const delta = time - this.lastTime;\r\n this.lastTime = time;\r\n\r\n this.update(delta);\r\n \r\n if (this.element && this.element.parentNode) {\r\n requestAnimationFrame(this.tick.bind(this));\r\n }\r\n }\r\n\r\n destroy(): void {\r\n if (this.element && this.element.parentNode) {\r\n this.element.parentNode.removeChild(this.element);\r\n }\r\n this.element = null;\r\n // Cleanup other parts\r\n }\r\n}\r\n","import { isLocalhost } from './environment';\r\nimport { Overlay } from './overlay';\r\nimport { Kitty } from '../pets/kitty/kitty';\r\n\r\nexport const inject = () => {\r\n if (!isLocalhost()) return;\r\n\r\n // Wait for DOM to be ready\r\n if (document.readyState === 'loading') {\r\n document.addEventListener('DOMContentLoaded', init);\r\n } else {\r\n init();\r\n }\r\n};\r\n\r\nlet overlay: Overlay | null = null;\r\nlet kitty: Kitty | null = null;\r\n\r\nfunction init() {\r\n if (overlay) return; // Already initialized\r\n\r\n overlay = new Overlay();\r\n overlay.mount();\r\n\r\n kitty = new Kitty();\r\n kitty.mount(overlay.shadowContainer);\r\n}\r\n\r\nexport const destroy = () => {\r\n if (kitty) kitty.destroy();\r\n if (overlay) overlay.destroy();\r\n kitty = null;\r\n overlay = null;\r\n};\r\n","import type { Plugin } from 'vite';\r\n\r\nexport function devKittyPlugin(): Plugin {\r\n return {\r\n name: 'vite-plugin-dev-kitty',\r\n apply: 'serve', // Only in dev mode\r\n transformIndexHtml(html: string) {\r\n return {\r\n html,\r\n tags: [\r\n {\r\n tag: 'script',\r\n attrs: { type: 'module' },\r\n children: 'import \"dev-kitty\";',\r\n injectTo: 'body'\r\n }\r\n ]\r\n };\r\n }\r\n };\r\n}\r\n","import { inject } from './core/injector';\r\n\r\n// Auto-inject on import\r\nif (typeof window !== 'undefined') {\r\n inject();\r\n}\r\n\r\nimport { devKittyPlugin } from './plugins/vite';\r\n\r\nexport { inject, destroy } from './core/injector';\r\nexport { Kitty } from './pets/kitty/kitty';\r\nexport { Overlay } from './core/overlay';\r\nexport { devKittyPlugin };\r\n\r\n// Default export\r\nexport default {\r\n init: inject,\r\n plugin: devKittyPlugin\r\n};\r\n"],"mappings":"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","names":["isLocalhost","hostname","Overlay","__publicField","BasePet","__publicField","x","y","_KittySprite","__publicField","svg","delta","state","facing","head","body","tail","zzz","legs","eyes","e","l","off","i","legOff","leg","vib","text","duration","bubble","bubbleText","KittySprite","KittyAI","__publicField","e","delta","currentX","currentY","ballPos","width","margin","distToMouse","oldState","nextX","nextY","moveSpeed","dx","groundY","targetY","state","roll","Engine","World","Bodies","PhysicsEngine","__publicField","Engine","delta","cappedDelta","x","y","radius","ball","Bodies","World","width","height","Body","YarnBall","container","body","__publicField","isDragging","Body","e","x","y","Poop","container","x","y","__publicField","smell","Footsteps","container","__publicField","x","y","step","el","firstChild","gsap","Body","Vector","Kitty","BasePet","__publicField","KittySprite","KittyAI","PhysicsEngine","container","Footsteps","body","YarnBall","delta","ballPos","state","x","y","facing","texts","Vector","force","Body","oldState","newState","Poop","gsap","time","inject","isLocalhost","init","overlay","kitty","Overlay","Kitty","destroy","devKittyPlugin","html","inject","index_default","inject","devKittyPlugin"]}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "dev-kitty",
3
+ "version": "1.0.0",
4
+ "description": "A tiny animated pixel cat for your localhost development 🐱",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "sideEffects": false,
16
+ "scripts": {
17
+ "build": "tsup",
18
+ "dev": "tsup --watch",
19
+ "lint": "tsc --noEmit",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "files": ["dist"],
23
+ "keywords": [
24
+ "dev",
25
+ "cat",
26
+ "kitty",
27
+ "localhost",
28
+ "pixel-art",
29
+ "fun",
30
+ "developer-tools",
31
+ "overlay",
32
+ "animation"
33
+ ],
34
+ "author": "aswintt",
35
+ "license": "MIT",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/aswintt/dev-kitty"
39
+ },
40
+ "homepage": "https://github.com/aswintt/dev-kitty",
41
+ "bugs": {
42
+ "url": "https://github.com/aswintt/dev-kitty/issues"
43
+ },
44
+ "devDependencies": {
45
+ "@types/gsap": "^1.20.2",
46
+ "@types/matter-js": "^0.20.2",
47
+ "@types/node": "^25.2.3",
48
+ "tsup": "^8.5.1",
49
+ "typescript": "^5.9.3",
50
+ "vite": "^7.3.1"
51
+ },
52
+ "dependencies": {
53
+ "gsap": "^3.14.2",
54
+ "matter-js": "^0.20.0"
55
+ }
56
+ }