@phantomclient/plugin 0.1.1 → 0.1.2

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.
@@ -1 +1,4 @@
1
- import{j as Rt,S as $t,i as Ct,P as I,a as Ft}from"./chunks/sdk-permissions-BKJgZYgg.js";import{M as bt,P as De,X as Lt,a as Nt,b as It,C as ye,c as S}from"./chunks/api-ByZmAFMe.js";import{i as jt,t as _t,d as zt,o as re,c as ae,a as K,b as be,e as qe,f as Bt,g as We,h as Ue}from"./chunks/runtime-dom.esm-bundler-Dcouf4CU.js";import{f as k,b as Ht,r as Dt,s as Ve,P as qt}from"./chunks/state-BjAtxWlm.js";class C extends Error{constructor(e,t,r=null){super(Wt(t,r,e)),this.code=e,this.flash=r,this.name="BridgeError"}code;flash}function Wt(n,e,t){if(typeof n=="string"&&n.trim()!=="")return Vt(n,e);const r=Gt(n);if(r)return r;const a=typeof(e==null?void 0:e.name)=="string"?e.name.trim():"";return a||`The game answered with no reason (${t})`}const Ut={1006:"that member is not a method",1009:"something the call reached was null",1010:"that member is not there",1034:"a value was not of the type the member takes",1056:"that object has nowhere to put the value",1063:"the call was given the wrong number of arguments",1069:"the object has no member of that name",1502:"a script in the game ran for longer than the player allows",2007:"a value the call needs was null"};function Vt(n,e){const t=typeof(e==null?void 0:e.errorId)=="number"?e.errorId:0,r=Ut[t];return!r||!/^\s*Error #\d+\s*$/.test(n)?n:`${n.trim()}: ${r}`}function Gt(n){if(n==null)return"";if(typeof n=="string")return n.trim();if(typeof n!="object")return String(n);const e=n;if(typeof e.message=="string"&&e.message.trim()!=="")return e.message;try{const t=JSON.stringify(n);return t&&t!=="{}"?t:""}catch{return""}}const Ge=2;function X(n){return encodeURIComponent(JSON.stringify(n))}function vt(n){return JSON.parse(decodeURIComponent(n))}function Yt(n){return typeof n=="object"&&n!==null&&"$handle"in n}function Kt(n){switch(n.kind){case"result":return n.id;case"event":return n.listener;case"callback":return n.callback;case"hook":case"override":case"hook-dropped":case"hook-failed":return n.registration;case"watch":return n.watch;case"tick":return n.tick;case"overlay":return n.node;case"key":return n.key;case"drive-failed":return n.drive;case"track":return n.track;default:return null}}class fe{constructor(e,t=[]){this.className=e,this.args=t}className;args}class L{constructor(e,t,r){this.bridge=e,this.handle=t,this.className=r}bridge;handle;className;at(...e){return new V(this.bridge,{kind:"handle",handle:this.handle},e)}release(){return this.bridge.release([this])}}class V{constructor(e,t,r=[]){this.bridge=e,this.target=t,this.path=r}bridge;target;path;at(...e){return new V(this.bridge,this.target,[...this.path,...e])}get(){return this.bridge.request({op:"get",target:this.target,path:[...this.path]})}set(e){return this.bridge.request({op:"set",target:this.target,path:[...this.path],value:this.bridge.encode(e)}).then(()=>{})}call(...e){return this.bridge.request({op:"call",target:this.target,path:[...this.path],args:e.map(t=>this.bridge.encode(t))})}describe(){return this.bridge.request({op:"describe",target:this.target,path:[...this.path]})}listen(e,t){return this.bridge.listen(this,e,t)}get entry(){return{target:this.target,path:[...this.path]}}}const Xt=new Set(["drive-failed","track","hook","override","hook-dropped","hook-failed","watch","tick","overlay","key"]);class Jt{constructor(e,t={}){this.transport=e,this.timeoutMs=t.timeoutMs??5e3,this.firstId=t.firstId??1,this.nextId=this.firstId,this.batchOption=t.batch,this.stopReceiving=e.onMessage(r=>this.receive(r))}transport;stateValue="waiting";nextId;pending=new Map;listeners=new Map;callbacks=new Map;readyWaiters=[];clientListeners=new Set;uncaughtListeners=new Set;timeoutMs;stopReceiving;clientVersion=null;featureList=[];firstId;batchOption;queue=[];batches=new Map;subscriptions=new Map;ticks=new Map;get state(){return this.stateValue}get client(){return this.clientVersion}get features(){return this.featureList}allocate(){return this.nextId++}whenReady(){return this.stateValue==="ready"?Promise.resolve():this.stateValue==="closed"?Promise.reject(new C("CLOSED","The game is closed")):new Promise((e,t)=>this.readyWaiters.push({resolve:e,reject:t}))}definition(e){return new V(this,{kind:"definition",name:e})}gameClient(){return new V(this,{kind:"client"})}stage(){return new V(this,{kind:"stage"})}construct(e,...t){return this.request({op:"construct",className:e,args:t.map(r=>this.encode(r))})}onClient(e){return this.clientListeners.add(e),()=>this.clientListeners.delete(e)}onUncaught(e){return this.uncaughtListeners.add(e),()=>this.uncaughtListeners.delete(e)}async listen(e,t,r){const a=this.nextId++;this.listeners.set(a,r);try{await this.request({op:"listen",target:e.target,path:[...e.path],event:t,listener:a})}catch(i){throw this.listeners.delete(a),i}return async()=>{!this.listeners.delete(a)||this.stateValue==="closed"||await this.request({op:"unlisten",listener:a})}}async subscribe(e,t,r){const a=this.nextId++;this.subscriptions.set(a,r);try{await this.request(e(a))}catch(i){throw this.subscriptions.delete(a),i}return async()=>{!this.subscriptions.delete(a)||this.stateValue==="closed"||await this.request(t(a))}}onSubscription(e,t){return this.subscriptions.set(e,t),()=>{this.subscriptions.get(e)===t&&this.subscriptions.delete(e)}}async hookTable(e){return await this.request(e===void 0?{op:"hookTable"}:{op:"hookTable",url:e})}async hook(e,t,r){let a=0;const i=await this.subscribe(s=>(a=s,{op:"hook",registration:s,hook:e,rules:t}),s=>({op:"unhook",registration:s}),r);return{registration:a,stop:i}}watch(e,t,r){return this.subscribe(a=>({op:"watch",watch:a,entries:e.map(i=>({target:i.target,path:[...i.path]})),everyFrames:Math.max(1,Math.floor(t.everyFrames??1)),handles:t.handles??!1}),a=>({op:"unwatch",watch:a}),a=>{a.kind==="watch"&&r(a.values.map(i=>this.decode(i)),a.errors??null)})}async tick(e,t){const r=Math.max(1,Math.floor(e));let a=this.ticks.get(r);if(!a){const o=new Set,l=this.subscribe(c=>({op:"tick",tick:c,everyFrames:r}),c=>({op:"untick",tick:c}),c=>{if(c.kind==="tick")for(const h of[...o])h(c.frame,c.time)});a={listeners:o,started:l},this.ticks.set(r,a),l.catch(()=>{this.ticks.get(r)===a&&this.ticks.delete(r)})}const i=a;i.listeners.add(t);try{await i.started}catch(o){throw i.listeners.delete(t),o}let s=!1;return async()=>{s||(s=!0,i.listeners.delete(t),!(i.listeners.size>0||this.ticks.get(r)!==i)&&(this.ticks.delete(r),await(await i.started)()))}}highlight(e,t){return this.subscribe(r=>({op:"highlight",highlight:r,target:e.target,path:[...e.path],effect:t}),r=>({op:"unhighlight",highlight:r}),()=>{})}style(e,t){return this.subscribe(r=>({op:"style",style:r,target:e.target,path:[...e.path],format:t}),r=>({op:"unstyle",style:r}),()=>{})}invokeOriginal(e,t,r){return this.request({op:"invokeOriginal",registration:e,token:t,arguments:r===null?null:r.map(a=>this.encode(a))})}async overrideDone(e,t){this.stateValue!=="closed"&&await this.request({op:"overrideDone",registration:e,token:t})}onKey(e,t){return this.subscribe(r=>({op:"key",key:r,spec:e}),r=>({op:"unkey",key:r}),r=>{r.kind==="key"&&t(r)})}async draw(e,t){await this.request({op:"draw",node:e,spec:t})}async erase(e){if(!(e.length===0||this.stateValue==="closed")){for(const t of e)this.subscriptions.delete(t);await this.request({op:"erase",nodes:[...e]})}}drive(e,t){return this.subscribe(r=>({op:"drive",drive:r,spec:e}),r=>({op:"undrive",drive:r}),r=>{r.kind==="drive-failed"&&(t==null||t(r.error))})}async collect(e,t){const a=await this.request({op:"collect",target:e.target,path:[...e.path],spec:t});return{items:Array.isArray(a==null?void 0:a.items)?a.items:[],total:typeof(a==null?void 0:a.total)=="number"?a.total:0}}track(e,t,{mode:r="displayList",everyFrames:a=15}={},i){return this.subscribe(s=>({op:"track",track:s,target:e.target,path:[...e.path],className:t,mode:r,everyFrames:a}),s=>({op:"untrack",track:s}),s=>{s.kind==="track"&&i({added:s.added.map(o=>this.decode(o)),removed:s.removed.map(o=>this.decode(o))})})}async snapshot(e,{scale:t=1,background:r=null,maxSize:a=0}={}){const i=await this.request({op:"snapshot",target:e.target,path:[...e.path],scale:t,background:r,maxSize:a});if(typeof i!="string")throw new C("FLASH","The picture came back empty");return i}note(e,t,r,a){if(t==="keys"||t==="clear")return this.request({op:"note",table:e,verb:t});if(!r)throw new TypeError(`A note to ${t} is kept beside an object; name the place`);const i={target:r.target,path:[...r.path]};return t==="write"?this.request({op:"note",table:e,verb:t,...i,value:this.encode(a)}):this.request({op:"note",table:e,verb:t,...i})}async find(e,t){const r=await this.request({op:"find",target:e.target,path:[...e.path],spec:t});return(Array.isArray(r)?r:[]).filter(a=>a instanceof L)}async answer(e,t){this.stateValue!=="closed"&&await this.request({op:"answer",callback:e,...t===void 0?{}:{value:this.encode(t)}})}async release(e){e.length===0||this.stateValue==="closed"||await this.request({op:"release",handles:e.map(t=>t.handle)})}close(){if(this.stateValue==="closed")return;if(this.stateValue==="ready"&&this.featureList.includes("dispose")){const t=this.nextId++;try{this.transport.send(X({id:t,op:"dispose",from:this.firstId,to:this.nextId}))}catch{}}this.stateValue="closed",this.stopReceiving();const e=new C("CLOSED","The game was closed");for(const t of this.pending.values())clearTimeout(t.timer),t.reject(e);this.pending.clear();for(const t of this.batches.values())clearTimeout(t.timer);this.batches.clear(),this.queue=[],this.listeners.clear(),this.callbacks.clear(),this.subscriptions.clear(),this.ticks.clear(),this.readyWaiters.splice(0).forEach(t=>t.reject(e))}readyWithin(e){return new Promise((t,r)=>{const a=setTimeout(()=>r(new C("NOT_READY","The game has not started yet")),e);this.whenReady().then(()=>{clearTimeout(a),t()},i=>{clearTimeout(a),r(i)})})}encodeRequest(e){return X({...e,id:this.nextId++})}request(e){if(this.stateValue==="closed")return Promise.reject(new C("CLOSED","The game is closed"));if(this.stateValue!=="ready")return this.readyWithin(this.timeoutMs).then(()=>this.request(e));const t=this.nextId++;return new Promise((r,a)=>{const i=setTimeout(()=>{this.pending.delete(t),a(new C("TIMEOUT",`The game did not answer "${e.op}" in ${this.timeoutMs}ms`))},this.timeoutMs);this.pending.set(t,{resolve:r,reject:a,timer:i});const s={...e,id:t};if(!this.batching||s.op==="hookTable"||s.op==="batch"){this.transport.send(X(s));return}this.queue.push(s),this.queue.length===1&&queueMicrotask(()=>this.flush())})}get batching(){return this.batchOption??this.featureList.includes("batch")}flush(){const e=this.queue;if(this.queue=[],e.length===0||this.stateValue!=="ready")return;if(e.length===1){this.transport.send(X(e[0]));return}const t=this.nextId++,r=e.map(i=>i.id),a=setTimeout(()=>this.batches.delete(t),this.timeoutMs+1e3);this.batches.set(t,{ids:r,timer:a}),this.transport.send(X({id:t,op:"batch",requests:e}))}settle(e,t){const r=this.pending.get(e);r&&(this.pending.delete(e),clearTimeout(r.timer),t.ok?r.resolve(this.decode(t.value)):r.reject(new C("FLASH",t.error.message,t.error)))}encode(e){if(e===void 0)return{$undefined:!0};if(e===null||typeof e!="object"){if(typeof e=="function"){const t=this.nextId++;return this.callbacks.set(t,e),{$callback:t}}return e}return e instanceof L?{$handle:e.handle}:e instanceof fe?{$new:e.className,args:e.args.map(t=>this.encode(t))}:Array.isArray(e)?e.map(t=>this.encode(t)):Object.fromEntries(Object.entries(e).map(([t,r])=>[t,this.encode(r)]))}decode(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(t=>this.decode(t));if(Yt(e))return new L(this,e.$handle,e.className);if(!("$undefined"in e))return Object.fromEntries(Object.entries(e).map(([t,r])=>[t,this.decode(r)]))}receive(e){var t,r,a;if(this.stateValue==="closed")return;let i;try{i=vt(e)}catch{return}switch(i.kind){case"ready":if(i.version!==Ge){const s=new C("VERSION",`The loader speaks bridge ${i.version}; this Phantom speaks ${Ge}`);this.readyWaiters.splice(0).forEach(o=>o.reject(s)),this.close();return}this.stateValue="ready",this.clientVersion=i.client,this.featureList=Array.isArray(i.features)?[...i.features]:[],this.readyWaiters.splice(0).forEach(s=>s.resolve());return;case"client-loaded":this.clientListeners.forEach(s=>s(!0,null));return;case"client-failed":this.clientListeners.forEach(s=>s(!1,i.message));return;case"result":{const s=this.batches.get(i.id);if(s){this.batches.delete(i.id),clearTimeout(s.timer);const o=i.ok&&Array.isArray(i.value)?i.value:null;s.ids.forEach((l,c)=>{i.ok?o&&c<o.length&&this.settle(l,o[c]):this.settle(l,i)});return}this.settle(i.id,i.ok?{ok:!0,value:i.value}:i);return}case"event":(t=this.listeners.get(i.listener))==null||t(this.decode(i.event));return;case"callback":(r=this.callbacks.get(i.callback))==null||r(...i.args.map(s=>this.decode(s)));return;case"uncaught":{const s=new C("FLASH",i.error.message,i.error);this.uncaughtListeners.forEach(o=>o(s));return}default:if(Xt.has(i.kind)){const s=Kt(i);s!==null&&((a=this.subscriptions.get(s))==null||a(i))}}}}const Zt=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],kt={r:.3086,g:.6094,b:.082};function ie(n,e){const t=new Array(20).fill(0);for(let r=0;r<4;r++)for(let a=0;a<5;a++){let i=a===4?e[r*5+4]:0;for(let s=0;s<4;s++)i+=e[r*5+s]*n[s*5+a];t[r*5+a]=i}return t}function xt(n){const e=n,{r:t,g:r,b:a}=kt;return[t*(1-e)+e,r*(1-e),a*(1-e),0,0,t*(1-e),r*(1-e)+e,a*(1-e),0,0,t*(1-e),r*(1-e),a*(1-e)+e,0,0,0,0,0,1,0]}function Qt(n){const e=n*255;return[1,0,0,0,e,0,1,0,0,e,0,0,1,0,e,0,0,0,1,0]}function en(n){const e=n+1,t=128*(1-e);return[e,0,0,0,t,0,e,0,0,t,0,0,e,0,t,0,0,0,1,0]}function tn(n){const e=n*Math.PI/180,t=Math.cos(e),r=Math.sin(e),{r:a,g:i,b:s}=kt;return[a+t*(1-a)+r*-a,i+t*-i+r*-i,s+t*-s+r*(1-s),0,0,a+t*-a+r*.143,i+t*(1-i)+r*.14,s+t*-s+r*-.283,0,0,a+t*-a+r*-.6914,i+t*-i+r*i,s+t*(1-s)+r*s,0,0,0,0,0,1,0]}const nn={grayscale:xt(0),sepia:[.393,.769,.189,0,0,.349,.686,.168,0,0,.272,.534,.131,0,0,0,0,0,1,0],invert:[-1,0,0,0,255,0,-1,0,0,255,0,0,-1,0,255,0,0,0,1,0],night:[.45,0,0,0,0,0,.5,0,0,0,0,0,.8,0,20,0,0,0,1,0]};function Et(n){if(typeof n=="string"){const t=nn[n];if(!t)throw new TypeError(`Unknown colour look "${String(n)}"`);return{matrix:[...t],colorTransform:null}}if("matrix"in n){if(n.matrix.length!==20)throw new TypeError("A colour matrix has twenty numbers");return{matrix:[...n.matrix],colorTransform:null}}if("tint"in n){const t=Math.max(0,Math.min(1,n.amount??.5)),r=a=>(n.tint>>a&255)*t;return{matrix:null,colorTransform:Ye({redMultiplier:1-t,greenMultiplier:1-t,blueMultiplier:1-t,redOffset:r(16),greenOffset:r(8),blueOffset:r(0)})}}if("transform"in n)return{matrix:null,colorTransform:Ye(n.transform)};let e=[...Zt];return n.saturation!==void 0&&(e=ie(e,xt(n.saturation))),n.hue!==void 0&&(e=ie(e,tn(n.hue))),n.contrast!==void 0&&(e=ie(e,en(n.contrast))),n.brightness!==void 0&&(e=ie(e,Qt(n.brightness))),{matrix:e,colorTransform:null}}function Ye(n){return{redMultiplier:n.redMultiplier??1,greenMultiplier:n.greenMultiplier??1,blueMultiplier:n.blueMultiplier??1,alphaMultiplier:n.alphaMultiplier??1,redOffset:n.redOffset??0,greenOffset:n.greenOffset??0,blueOffset:n.blueOffset??0,alphaOffset:n.alphaOffset??0}}function ee(n={}){const e=n.recolor?Et(n.recolor):{matrix:null,colorTransform:null},r=n.glow??!(n.recolor||n.hide)?{color:n.color??9133302,alpha:n.alpha??1,blur:n.blur??8,strength:n.strength??2,inner:n.inner??!1,knockout:n.knockout??!1}:null;if(r&&e.matrix)throw new TypeError("A highlight is a glow or a colour matrix, not both: use two highlights");const a=n.pulse===void 0||n.pulse===!1?null:n.pulse===!0?{frames:60,from:.6,to:1}:{frames:n.pulse.frames??60,from:n.pulse.from??.6,to:n.pulse.to??1};return{glow:r,matrix:e.matrix,colorTransform:e.colorTransform,hide:n.hide??!1,pulse:a}}const pe=Symbol.for("phantom.typedFlash");function Tt(n){return typeof n=="function"&&n[pe]!==void 0}function R(n,e,t={}){const r={reference:e,handle:t.handle??null,className:t.className??null},a=o=>O(n,o),i={$get:()=>e.get().then(a),$set:async o=>e.set((await G(n,[o]))[0]),$listen:(o,l)=>e.listen(o,c=>l(a(c))),$describe:()=>e.describe(),$at:(...o)=>R(n,e.at(...o)),$as:()=>R(n,e,{...r.handle?{handle:r.handle}:{}}),$release:()=>r.handle?r.handle.release():Promise.resolve(),$reference:e,$new:async(...o)=>{if(!r.className)throw new TypeError("Only a class can make objects with $new");return a(await n.construct(r.className,...await G(n,o)))},toJSON:()=>`[Flash ${rn(r)}]`},s=(()=>{});return new Proxy(s,{get:(o,l)=>{if(l===pe)return r;if(typeof l!="symbol"&&l!=="then")return Object.prototype.hasOwnProperty.call(i,l)?i[l]:R(n,e.at(l))},apply:async(o,l,c)=>a(await e.call(...await G(n,c)))})}function te(n){return Tt(n)?n[pe].reference:n instanceof L?n.at():n&&typeof n=="object"&&"target"in n&&"path"in n&&typeof n.at=="function"?n:null}function O(n,e){if(e instanceof L)return R(n,e.at(),{handle:e});if(Array.isArray(e))return e.map(t=>O(n,t));if(e&&typeof e=="object"){const t={};for(const[r,a]of Object.entries(e))t[r]=O(n,a);return t}return e}async function G(n,e){return Promise.all(e.map(t=>Fe(n,t)))}async function Fe(n,e){if(Tt(e)){const t=e[pe];return t.handle&&t.reference.path.length===0?t.handle:t.reference.get()}if(typeof e=="function"){const t=e;return(...r)=>t(...r.map(a=>O(n,a)))}if(Array.isArray(e))return Promise.all(e.map(t=>Fe(n,t)));if(e&&typeof e=="object"&&Object.getPrototypeOf(e)===Object.prototype){const t={};for(const[r,a]of Object.entries(e))t[r]=await Fe(n,a);return t}return e}function rn({reference:n,className:e}){const t=n.target,r=t.kind==="definition"?t.name:t.kind==="handle"?`object ${t.handle}`:t.kind,a=n.path.join(".");return e??(a?`${r}.${a}`:r)}class an{constructor(e,t,r){this.bridge=e;const a=e.encode(t);this.callback=a.$callback,r!==void 0&&this.answers(r)}bridge;callback;stopped=!1;get argument(){return{$callback:this.callback}}async answers(e){if(this.stopped)return;await this.ready();const[t]=await G(this.bridge,[e]);await this.bridge.answer(this.callback,t)}async answersNothing(){this.stopped||(await this.ready(),await this.bridge.answer(this.callback))}async stop(){this.stopped||(this.stopped=!0,await this.bridge.answer(this.callback))}async ready(){if(await this.bridge.whenReady(),!this.bridge.features.includes("answer"))throw new Error("This game is running a loader from before answers; a function of yours gives the game nothing back")}}function T(n){const e=te(n);if(!e)throw new TypeError("Expected a place in Flash: a typed place, an object read from Flash, or a reference");return{target:e.target,path:[...e.path]}}async function sn(n,e,t,r){if(await n.whenReady(),!n.features.includes("collect"))throw new Error("This game is running a loader from before collects; read the items one by one");const a={fields:on(t)};r.skip!==void 0&&(a.skip=Math.max(0,Math.trunc(r.skip))),r.limit!==void 0&&(a.limit=Math.max(1,Math.trunc(r.limit))),r.handles!==void 0&&(a.handles=r.handles);const i=await n.collect(T(e),a);return{rows:i.items.map(s=>O(n,s)),total:i.total}}function on(n){const e=Array.isArray(n)?n.map(t=>[t,t]):Object.entries(n);if(e.length===0)throw new TypeError("A collect needs the members to read");return e.map(([t,r])=>({name:t,path:(Array.isArray(r)?r:String(r).split(".")).filter(a=>a.length>0)}))}function ne(n){const e=`${n.className}.${n.member}`;return n.kind==="getter"?`${e}@get`:n.kind==="setter"?`${e}@set`:e}const ge=Symbol.for("phantom.hookRead"),Y=Symbol.for("phantom.hookTest");class ln{constructor(e){this.table=e;for(const t of e.hooks){this.byId.set(t.id,t);const r=ne(t);this.byKey.has(r)||this.byKey.set(r,t)}}table;byKey=new Map;byId=new Map;get size(){return this.byId.size}names(){return[...this.byKey.keys()]}find(e){return e.startsWith("#")?this.byId.get(Number(e.slice(1)))??null:this.byKey.get(e)??this.byKey.get(`${e}@get`)??this.byKey.get(`${e}@set`)??null}}function W(n){return n.flatMap(e=>Array.isArray(e)?e:e.includes("::")?[e]:e.split(".").filter(Boolean))}function D(n){return Object.freeze({[ge]:n})}function N(n,e,t){return Object.freeze({[Y]:t===void 0&&n==="exists"?{test:n,left:e}:{test:n,left:e,right:t}})}const cn={self:(...n)=>D({from:"self",path:W(n)}),arg:(n,...e)=>D({from:"arg",arg:n,path:W(e)}),returned:(...n)=>D({from:"return",path:W(n)}),fromClass:(n,...e)=>D({from:"class",name:n,path:W(e)}),place:(n,...e)=>D({from:"place",place:n,path:W(e)}),calls:()=>D({from:"calls"}),constant:n=>D({from:"constant",value:n}),equals:(n,e)=>N("equals",n,e),notEquals:(n,e)=>N("notEquals",n,e),less:(n,e)=>N("less",n,e),lessOrEqual:(n,e)=>N("lessOrEqual",n,e),greater:(n,e)=>N("greater",n,e),greaterOrEqual:(n,e)=>N("greaterOrEqual",n,e),contains:(n,e)=>N("contains",n,e),startsWith:(n,e)=>N("startsWith",n,e),endsWith:(n,e)=>N("endsWith",n,e),oneOf:(n,e)=>N("in",n,e),exists:n=>N("exists",n),all:(...n)=>Object.freeze({[Y]:{all:n}}),any:(...n)=>Object.freeze({[Y]:{any:n}}),not:n=>Object.freeze({[Y]:{not:n}})};function Mt(n){return typeof n=="object"&&n!==null&&ge in n}function St(n){return typeof n=="object"&&n!==null&&Y in n}function Le(n,e,t,r){const a=u=>{if(typeof u=="number")return Ke(e,u);const d=e.parameters.findIndex(g=>g.name===u);if(d>=0)return d;if(/^\d+$/.test(u))return Ke(e,Number(u));const p=e.parameters.map(g=>g.name).join(", ")||"none";throw new TypeError(`${ne(e)} has no argument "${u}" (its arguments: ${p})`)},i=u=>{if(!Mt(u))return ue(u)??{from:"constant",value:J(n,u)};const d=u[ge];switch(d.from){case"constant":return{from:"constant",value:J(n,d.value)};case"arg":return{from:"arg",index:a(d.arg),path:d.path};case"self":return{from:"self",path:d.path};case"return":return{from:"return",path:d.path};case"class":return{from:"class",name:d.name,path:d.path};case"calls":return{from:"calls"};case"place":{const p=ue(d.place,d.path);if(!p)throw new TypeError("rules.place takes a place in the game");return p}}},s=u=>{if(!St(u)){const p=Object.entries(u).map(([g,f])=>({test:"equals",left:{from:"arg",index:a(g),path:[]},right:i(f)}));if(p.length===0)throw new TypeError("A hook condition names nothing to compare");return p.length===1?p[0]:{all:p}}const d=u[Y];return"all"in d?{all:d.all.map(s)}:"any"in d?{any:d.any.map(s)}:"not"in d?{not:s(d.not)}:d.test==="exists"?{test:d.test,left:i(d.left)}:{test:d.test,left:i(d.left),right:i(d.right)}},o=t.phase??(r?"enter":"none"),l=t.capture??{},c=e.parameters.map((u,d)=>d),h=l.args===!0||l.args===void 0&&r?c:(l.args??[]).map(a);return{observe:o==="both"?["enter","exit"]:o==="none"?[]:[o],capture:{args:h,self:Ne(l.self).map(([,u])=>u),value:l.value??!1,handles:l.handles??!1},when:t.when===void 0?null:s(t.when),first:t.first??null,every:t.every??null,skip:t.skip===void 0||t.skip===!1?null:t.skip===!0?{from:"constant",value:{$undefined:!0}}:i(t.skip.returns),replaceArgs:Object.entries(t.replaceArgs??{}).map(([u,d])=>({index:a(u),value:i(d)})),replaceReturn:"replaceReturn"in t?i(t.replaceReturn):null,perFrame:t.perFrame??20}}function Ke(n,e){if(!Number.isInteger(e)||e<0||n.parameters.length>0&&e>=n.parameters.length)throw new RangeError(`${ne(n)} has no argument ${e}`);return e}function Ne(n){return n?Array.isArray(n)?n.map(e=>[e,W([e])]):Object.entries(n).map(([e,t])=>[e,W([t])]):[]}function Ot(n,e){const t=r=>{if(!St(r))throw new TypeError("A condition between calls has no call to read: compare with rules.equals and its like");const a=r[Y];return"all"in a?{all:a.all.map(t)}:"any"in a?{any:a.any.map(t)}:"not"in a?{not:t(a.not)}:a.test==="exists"?{test:a.test,left:Q(n,a.left)}:{test:a.test,left:Q(n,a.left),right:Q(n,a.right)}};return t(e)}function ue(n,e=[]){const t=te(n);return t?{from:"place",target:t.target,path:[...t.path,...e]}:null}function Q(n,e){if(!Mt(e))return ue(e)??{from:"constant",value:J(n,e)};const t=e[ge];switch(t.from){case"constant":return{from:"constant",value:J(n,t.value)};case"class":return{from:"class",name:t.name,path:t.path};case"place":{const r=ue(t.place,t.path);if(!r)throw new TypeError("rules.place takes a place in the game");return r}default:throw new TypeError(`rules.${t.from} reads the call it is in; a value held between calls is a constant, rules.fromClass or a place`)}}function J(n,e){if(e===void 0)return{$undefined:!0};if(e instanceof L||e instanceof fe)return n.encode(e);const t=te(e);if(t){if(t.target.kind==="handle"&&t.path.length===0)return{$handle:t.target.handle};throw new TypeError("A place inside a list or object in a rule cannot be read there: pass the place on its own, or read it first")}if(typeof e=="function")throw new TypeError("A hook rule cannot call a function");return Array.isArray(e)?e.map(r=>J(n,r)):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,a])=>[r,J(n,a)])):e}async function hn(n,e,t,r,a){var i;const s=e.find(t);if(!s)throw new TypeError(`There is no hook "${t}" in the hook table`);let o=r,l=Ne((i=r.capture)==null?void 0:i.self).map(([p])=>p),c=Le(n,s,r,a!==void 0);const{registration:h,stop:u}=await n.hook(s.id,c,p=>{var g;switch(p.kind){case"hook":{if(!a)return;const f=(p.args??[]).map(b=>O(n,n.decode(b))),m={};c.capture.args.forEach((b,x)=>{var M;m[((M=s.parameters[b])==null?void 0:M.name)??String(b)]=f[x]});const w={};(p.self??[]).forEach((b,x)=>{w[l[x]??String(x)]=O(n,n.decode(b))}),a({phase:p.phase,call:p.call,args:m,argList:f,self:w,..."value"in p?{value:O(n,n.decode(p.value))}:{},skipped:p.skipped===!0,hook:s});return}case"hook-dropped":(g=o.onDropped)==null||g.call(o,p.dropped);return;case"hook-failed":{const f=new C("FLASH",`The hook on ${ne(s)} failed and is off: ${p.error.message}`,p.error);o.onError?o.onError(f):console.error(f.message);return}}});return Object.assign(()=>u(),{registration:h,hook:s,update:async(p,g={})=>{var f;const m=Le(n,s,p,a!==void 0);await n.request({op:"rehook",registration:h,rules:m,resetCounts:g.resetCounts??!1}),o=p,c=m,l=Ne((f=p.capture)==null?void 0:f.self).map(([w])=>w)},stats:async()=>(await n.request({op:"hookStats"})).find(g=>g.registration===h)??null})}async function un(n,e,t){if(await n.whenReady(),!n.features.includes("drive"))throw new Error("This game is running a loader from before repeated calls; call it yourself each frame");const r=T(e);if(r.path.length===0)throw new TypeError("A repeat calls a method, so name one: `place.method`, not the object");const a=t.while?Ot(n,t.while):null;return n.drive({writes:[],calls:[{target:r.target,path:r.path,args:(t.args??[]).map(i=>Q(n,i)),times:Math.max(1,Math.trunc(t.times??1))}],everyFrames:Math.max(1,Math.trunc(t.everyFrames??1)),while:a,restore:!1,once:t.once===!0},t.onFailed)}async function Xe(n,e,t){if(await n.whenReady(),!n.features.includes("drive"))throw new Error("This game is running a loader from before held values; write it yourself each frame");if(e.length===0)throw new TypeError("A hold needs a value to keep");const r=e.map(({place:i,value:s})=>{const o=T(i);if(o.path.length===0)throw new TypeError("A hold writes to a member, so name one: `place.member`, not the object");return{target:o.target,path:o.path,value:Q(n,s)}}),a=t.while?Ot(n,t.while):null;return n.drive({writes:r,everyFrames:Math.max(1,Math.trunc(t.everyFrames??1)),while:a,restore:t.restore!==!1,once:t.once===!0},t.onFailed)}class ve{constructor(e,t,r,a,i,s,o){this.host=e,this.kind=t,this.id=r,this.name=a,this.tagY=s,this.handle=o,this.place=i}host;kind;id;name;tagY;handle;place;highlight(e={}){return this.host.bridge.highlight(this.entry(),ee(e))}tag(e,t={}){const{anchorX:r,anchorY:a,...i}=t;return this.host.overlay.text(e,{centered:!0,font:{size:12,bold:!0,color:16777215},outline:0,...i,anchor:{place:this.place,x:r??0,y:a??this.tagY}})}onClick(e){const t=this.host.bridge;return this.kind!=="object"?this.place.$listen("mouseDown",()=>e(this)):t.stage().listen("mouseDown",r=>{const{stageX:a,stageY:i}=r??{};typeof a!="number"||typeof i!="number"||this.place.$reference.at("hitTestPoint").call(a,i,!0).then(s=>{s===!0&&e(this)}).catch(()=>{})})}async release(){this.handle&&await this.handle.release()}entry(){const e=this.place.$reference;return{target:e.target,path:[...e.path]}}}class dn{constructor(e){this.host=e}host;async players(){const e=this.host.bridge,t=e.definition("avatar.AvatarManager").at("avatarViewList"),r=await t.get(),a=r&&typeof r=="object"&&!(r instanceof L)?Object.keys(r):[],i=a.map(s=>r[s]).filter(s=>s instanceof L);try{const s=await Promise.all(a.map(o=>B(t.at(o,"userName").get())));return a.map((o,l)=>new ve(this.host,"player",o,typeof s[l]=="string"?s[l]:null,R(e,t.at(o)),-80,null))}finally{await e.release(i)}}async npcs(){const e=this.host.bridge,t=e.definition("quest.QuestManager").at("_questActors"),r=await B(t.at("length").get());if(typeof r!="number"||r<=0)return[];const a=Array.from({length:Math.min(r,500)},(c,h)=>String(h)),[i,s,o]=await Promise.all([Promise.all(a.map(c=>B(t.at(c).get()))),Promise.all(a.map(c=>B(t.at(c,"_actorId").get()))),Promise.all(a.map(c=>B(t.at(c,"currAvatar","avName").get())))]),l=[];return a.forEach((c,h)=>{const u=i[h];if(!(u instanceof L))return;const d=o[h];l.push(new ve(this.host,"npc",typeof s[h]=="string"?s[h]:c,typeof d=="string"&&d?d:null,R(e,u.at(),{handle:u}),-90,u))}),l}async objects(){const e=this.host.bridge,t=e.definition("room.RoomManagerWorld").at("instance","volumeManager","_volumeActors");let r;try{r=await t.at("length").get()}catch(h){throw h instanceof C&&h.code==="FLASH"?new C("FLASH",`The room's objects are private to the client, and this client does not reach them: ${h.message}`,h.flash):h}if(typeof r!="number"||r<=0)return[];const a=Array.from({length:Math.min(r,500)},(h,u)=>String(u)),[i,s]=await Promise.all([Promise.all(a.map(h=>B(t.at(h,"name").get()))),Promise.all(a.map(h=>B(t.at(h,"interactiveObjs","length").get())))]),o=[];a.forEach((h,u)=>{const d=s[u],p=i[u];for(let g=0;typeof d=="number"&&g<Math.min(d,50);g++)o.push([h,String(g),typeof p=="string"?p:null])});const l=await Promise.all(o.map(([h,u])=>B(t.at(h,"interactiveObjs",u,"mc").get()))),c=[];return o.forEach(([h,u,d],p)=>{const g=l[p];g instanceof L&&c.push(new ve(this.host,"object",`${d??h}#${u}`,d,R(e,g.at(),{handle:g}),0,g))}),c}}function B(n){return n.catch(()=>null)}async function fn(n,e,t){if(await n.whenReady(),!n.features.includes("find"))throw new Error("This game is running a loader from before searches; only a path reaches an object");const r=e===void 0?{target:{kind:"stage"},path:[]}:T(e);return(await n.find(r,pn(t))).map(i=>R(n,i.at(),{handle:i}))}function pn(n){const e={};return n.ofClass!==void 0&&(e.ofClass=n.ofClass),n.named!==void 0&&(e.named=n.named),n.containing!==void 0&&(e.containing=n.containing),n.visibleOnly!==void 0&&(e.visibleOnly=n.visibleOnly),n.through!==void 0&&(e.through=n.through),n.depth!==void 0&&(e.depth=n.depth),n.limit!==void 0&&(e.limit=n.limit),e}const Je={backspace:8,tab:9,enter:13,return:13,shift:16,control:17,ctrl:17,alt:18,pause:19,capslock:20,escape:27,esc:27,space:32,pageup:33,pagedown:34,end:35,home:36,left:37,arrowleft:37,up:38,arrowup:38,right:39,arrowright:39,down:40,arrowdown:40,insert:45,delete:46,";":186,"=":187,",":188,"-":189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222};function gn(n){return n===!0?"always":n===!1?"never":n??"empty"}function mn(n,e={}){const t={phase:e.phase??"down",consume:e.consume??!1,whileTyping:gn(e.whileTyping),repeat:e.repeat??!1};if(typeof n=="number")return{code:n,ctrl:null,shift:null,alt:null,...t};const r=n==="+"||n.endsWith("++"),a=(r?n.slice(0,-1):n).split("+").map(o=>o.trim()).filter(Boolean);r&&a.push("+");const i={ctrl:!1,shift:!1,alt:!1};let s=null;for(const o of a){const l=o.toLowerCase();l==="ctrl"||l==="control"||l==="cmd"||l==="meta"?i.ctrl=!0:l==="shift"?i.shift=!0:l==="alt"||l==="option"?i.alt=!0:l==="any"?s=null:s=wn(o)}if(s===null&&!a.some(o=>o.toLowerCase()==="any"))throw new TypeError(`"${n}" names no key`);return{code:s,...i,...t}}function wn(n){const e=n.toLowerCase();if(e in Je)return Je[e];if(/^[a-z0-9]$/i.test(n))return n.toUpperCase().charCodeAt(0);const t=/^f([1-9]|1[0-5])$/i.exec(n);if(t)return 111+Number(t[1]);const r=/^num(?:pad)?([0-9])$/i.exec(n);if(r)return 96+Number(r[1]);if(n==="+")return 187;throw new TypeError(`Unknown key "${n}"`)}class yn{constructor(e){this.bridge=e}bridge;table=null;async set(e,t){const[r]=await G(this.bridge,[t]);await this.bridge.note(await this.number(),"write",T(e),r)}async get(e){const t=await this.bridge.note(await this.number(),"read",T(e));return t==null?void 0:O(this.bridge,t)}async has(e){return await this.bridge.note(await this.number(),"has",T(e))===!0}async forget(e){return await this.bridge.note(await this.number(),"forget",T(e))===!0}async objects(){const e=await this.bridge.note(await this.number(),"keys");return Array.isArray(e)?e.filter(t=>t instanceof L).map(t=>R(this.bridge,t.at(),{handle:t})):[]}async clear(){this.table!==null&&await this.bridge.note(this.table,"clear")}async number(){if(await this.bridge.whenReady(),!this.bridge.features.includes("notes"))throw new Error("This game is running a loader from before notes; nothing can be kept beside its objects");return this.table??=this.bridge.allocate(),this.table}}const bn=127;function At(n){const e=[],t=[];let r="",a=0;const i=()=>{const o={};for(const l of t)Object.assign(o,l.look);return o},s=()=>{if(r==="")return;const o={text:r,...i()},l=e[e.length-1];l&&Mn(l,o)?l.text+=r:e.push(o),r=""};for(;a<n.length;){const o=n[a];if(o!=="["){r+=o,a++;continue}if(n[a+1]==="["){r+="[",a+=2;continue}const l=n.indexOf("]",a+1),c=l<0?null:vn(n.slice(a+1,l));if(c===null){r+=o,a++;continue}if(c.closing){const h=Tn(t,c.name);h<0?r+=n.slice(a,l+1):(s(),t.splice(h))}else s(),t.push({tag:c.name,look:c.look});a=l+1}return s(),e}function vn(n){if(n.startsWith("/")){const a=n.slice(1);return kn.has(a)?{name:a,closing:!0}:null}const e=n.indexOf("="),t=e<0?n:n.slice(0,e),r=e<0?null:n.slice(e+1);switch(t){case"b":return r===null?{name:t,closing:!1,look:{bold:!0}}:null;case"i":return r===null?{name:t,closing:!1,look:{italic:!0}}:null;case"u":return r===null?{name:t,closing:!1,look:{underline:!0}}:null;case"color":{const a=r===null?null:En(r);return a===null?null:{name:t,closing:!1,look:{color:a}}}case"size":{const a=r===null?NaN:Number(r);return Number.isInteger(a)&&a>=1&&a<=bn?{name:t,closing:!1,look:{size:a}}:null}case"link":return r===null||r===""?null:{name:t,closing:!1,look:{link:r}};default:return null}}const kn=new Set(["b","i","u","color","size","link"]),xn="0123456789abcdef";function En(n){const e=n.toLowerCase(),t=e.startsWith("#")?e.slice(1):e.startsWith("0x")?e.slice(2):null;if(t===null||t.length!==6)return null;let r=0;for(const a of t){const i=xn.indexOf(a);if(i<0)return null;r=r*16+i}return r}function Tn(n,e){for(let t=n.length-1;t>=0;t--)if(n[t].tag===e)return t;return-1}function Mn(n,e){return["color","bold","italic","underline","size","font","link"].every(r=>n[r]===e[r])}const ke={className:"avatar.AvatarManager",path:["playerAvatarWorldView","parent"]},Ze=new Set(["click","down","up","over","out"]);class Sn{constructor(e){this.bridge=e}bridge;nodes=new Map;async draw(e,t={}){const{handle:r}=await this.make(e,t);return r}world(e={x:0,y:0},t={}){return{place:this.bridge.definition(ke.className).at(ke.path[0],ke.path[1]),x:e.x,y:e.y,...t}}marker(e,t={}){const{kind:r="circle",...a}=t;return this.draw(r,{radius:8,...a,anchor:this.world(e)})}group(e={}){return this.draw("group",e)}text(e,t={}){return this.draw("text",{...t,text:e})}rich(e,t={}){return this.draw("text",{...t,rich:e})}rect(e){return this.draw("rect",e)}circle(e){return this.draw("circle",e)}line(e){return this.draw("line",e)}image(e,t={}){return this.draw("image",{...t,url:e})}async input(e={}){const{handle:t,state:r}=await this.make("input",{width:200,height:24,fill:16777215,stroke:10265519,padding:4,...e,font:{color:1120295,...e.font}});return r.value=e.value??"",Object.assign(t,{value:()=>r.value,setValue:async i=>{r.value=i,r.removed||await this.bridge.draw(t.node,{value:i})},focus:async()=>{r.removed||await this.bridge.draw(t.node,{focus:!0})}})}async button(e,t={}){const{handle:r,state:a}=await this.make("button",{width:72,height:24,fill:8141549,hoverFill:9133302,pressedFill:7153881,cornerRadius:4,...t,font:{color:16777215,bold:!0,...t.font},label:e});return Object.assign(r,{setLabel:i=>a.removed?Promise.resolve():this.bridge.draw(r.node,{label:i}),setDisabled:i=>a.removed?Promise.resolve():this.bridge.draw(r.node,{disabled:i})})}async panel(e={}){const{onMove:t,onResize:r,...a}=e,{handle:i}=await this.make("panel",{width:260,height:200,fill:{color:1120295,alpha:.92},stroke:3621201,titleFill:2042167,titleHeight:22,cornerRadius:6,...a,titleFont:{color:16777215,bold:!0,...a.titleFont}}),s=i;return t&&s.on("move",t),r&&s.on("resize",r),s}async list(e={}){const{handle:t,state:r}=await this.make("list",{width:240,height:160,fill:{color:0,alpha:.55},padding:4,...e,font:{color:16777215,...e.font}});return Object.assign(t,{append:(...a)=>r.removed||a.length===0?Promise.resolve():this.bridge.draw(t.node,{append:a.map(xe)}),setRows:a=>r.removed?Promise.resolve():this.bridge.draw(t.node,{rows:a.map(xe)})})}async replace(e,t){return await t.update({parent:null,host:null,replaces:e}),()=>t.remove()}async attach(e,t){return await t.update({parent:null,replaces:null,host:e}),()=>t.remove()}async focusGame(){await this.bridge.stage().at("focus").set(null)}async clear(){const e=[...this.nodes.entries()].filter(([,t])=>t.parent===null||!this.nodes.has(t.parent)).map(([t])=>t);await this.remove(e)}async make(e,t){var r;const a=this.bridge.allocate(),i={type:e,...this.specOf(t)},s={parent:t.parent?t.parent.node:null,children:new Set,listeners:new Map,failed:new Set,gone:new Set,stopHearing:()=>{},removed:!1,value:""};s.stopHearing=this.bridge.onSubscription(a,o=>{var l;if(o.kind==="overlay"){if(o.event==="failed"){s.failed.forEach(c=>c(o.message??"The image did not load"));return}(o.event==="change"||o.event==="submit")&&o.value!==void 0&&(s.value=o.value),(l=s.listeners.get(o.event))==null||l.forEach(c=>c(o))}}),this.nodes.set(a,s);try{await this.bridge.draw(a,i)}catch(o){throw s.stopHearing(),this.nodes.delete(a),o}return s.parent!==null&&((r=this.nodes.get(s.parent))==null||r.children.add(a)),{handle:this.handle(a,e,s),state:s}}handle(e,t,r){const a=()=>this.remove([e]);return Object.assign(a,{node:e,type:t,update:async s=>{var o,l;if(r.removed)return;const c=this.specOf(s);"parent"in s&&(r.parent!==null&&((o=this.nodes.get(r.parent))==null||o.children.delete(e)),r.parent=s.parent?s.parent.node:null,r.parent!==null&&((l=this.nodes.get(r.parent))==null||l.children.add(e))),await this.bridge.draw(e,c)},show:()=>r.removed?Promise.resolve():this.bridge.draw(e,{visible:!0}),hide:()=>r.removed?Promise.resolve():this.bridge.draw(e,{visible:!1}),remove:a,on:(s,o)=>{const l=o,c=g=>{switch(g.event){case"change":case"submit":case"link":l(g.value??"");return;case"focus":case"blur":l(void 0);return;case"row":l(g.index??-1);return;case"move":l({x:g.x,y:g.y});return;case"resize":l({width:g.width??0,height:g.height??0});return;default:l({x:g.x,y:g.y})}};let h=r.listeners.get(s);const u=!h||h.size===0;h||(h=new Set,r.listeners.set(s,h)),h.add(c);const d=Ze.has(s);u&&d&&this.sendMouse(e,r);let p=!1;return async()=>{p||(p=!0,h.delete(c),d&&h.size===0&&!r.removed&&await this.sendMouse(e,r))}},onFailed:s=>(r.failed.add(s),()=>{r.failed.delete(s)}),onRemoved:s=>r.removed?(s(),()=>{}):(r.gone.add(s),()=>{r.gone.delete(s)})})}async sendMouse(e,t){const r=[...t.listeners.entries()].filter(([a,i])=>Ze.has(a)&&i.size>0).map(([a])=>a);await this.bridge.draw(e,{mouse:r})}async remove(e){const t=[],r=[],a=s=>{var o;const l=this.nodes.get(s);!l||l.removed||(l.removed=!0,l.stopHearing(),this.nodes.delete(s),t.push(s),r.push(...l.gone),l.gone.clear(),l.children.forEach(a),l.parent!==null&&((o=this.nodes.get(l.parent))==null||o.children.delete(s)))};e.forEach(a);const i=e.filter(s=>t.includes(s));try{await this.bridge.erase(i)}finally{for(const s of r)try{s()}catch(o){console.error("phantom.flash.overlay: a removal listener failed",o)}}}specOf(e){const t={};for(const[r,a]of Object.entries(e))if(a!==void 0)switch(r){case"parent":t.parent=a===null?null:a.node;break;case"anchor":t.anchor=a===null?null:An(a);break;case"host":case"replaces":t[r]=a===null?null:Pn(a);break;case"fill":case"background":case"hoverFill":case"pressedFill":case"titleFill":t[r]=a===null?null:Rn(a);break;case"stroke":t.stroke=a===null?null:$n(a);break;case"font":case"titleFont":t[r]=On(a);break;case"rich":t.spans=a===null?null:typeof a=="string"?At(a):a;break;case"rows":case"append":t[r]=a.map(xe);break;default:t[r]=a}return t}}function On(n){return{family:"_sans",size:12,color:16777215,bold:!1,italic:!1,...n}}function xe(n){if(typeof n=="string")return n||" ";const e=(Array.isArray(n)?n:At(n.markup)).filter(t=>t.text.length>0);return e.length?e:" "}function An(n){const e=typeof n=="object"&&n!==null&&"place"in n?n:{place:n},t=T(e.place);return{target:t.target,path:t.path,x:e.x??0,y:e.y??0,refreshFrames:e.refreshFrames??12,hideWhenGone:e.hideWhenGone??!0}}function Pn(n){const e=typeof n=="object"&&n!==null&&"place"in n?n:{place:n},t=T(e.place);return{target:t.target,path:t.path,refreshFrames:e.refreshFrames??12}}function Rn(n){return typeof n=="number"?{color:n,alpha:1}:{color:n.color,alpha:n.alpha??1}}function $n(n){return typeof n=="number"?{color:n,alpha:1,width:1}:{color:n.color,alpha:n.alpha??1,width:n.width??1}}async function Cn(n,e,t,r,a={}){const i=e.find(t);if(!i)throw new TypeError(`There is no hook "${t}" in the hook table`);const s={perFrame:a.perFrame??50};a.when!==void 0&&(s.when=a.when),a.first!==void 0&&(s.first=a.first),a.every!==void 0&&(s.every=a.every),a.replaceArgs!==void 0&&(s.replaceArgs=a.replaceArgs),"returns"in a&&(s.skip={returns:a.returns});const o={...Le(n,i,s,!1),override:!0};let l=0,c=Promise.resolve();const h=ne(i),u=async f=>{l++;let m=!1,w=!1;const b=f.args.map(A=>O(n,n.decode(A))),x={};b.forEach((A,_)=>{var y;x[((y=i.parameters[_])==null?void 0:y.name)??String(_)]=A});const M=i.isStatic?R(n,n.definition(i.className),{className:i.className}):O(n,n.decode(f.self)),j={hook:i,call:f.call,self:M,args:x,argList:b,original:async(...A)=>{if(w)throw new C("FLASH",`The call of ${h} has ended: its handler finished`);m=!0;const _=await n.invokeOriginal(d,f.token,A.length===0?null:await G(n,A));return O(n,_)}};try{await r(j)}catch(A){if(console.error(`The override of ${h} failed: ${A instanceof Error?A.message:String(A)}`),!m&&(a.onError??"original")==="original")try{await n.invokeOriginal(d,f.token,null)}catch(_){console.error(`The original ${h} failed after its override did: ${_ instanceof Error?_.message:String(_)}`)}}finally{w=!0,l--;try{await n.overrideDone(d,f.token)}catch{}}},{registration:d,stop:p}=await n.hook(i.id,o,f=>{var m;switch(f.kind){case"override":a.sequential?c=c.then(()=>u(f)):u(f);return;case"hook-dropped":(m=a.onDropped)==null||m.call(a,f.dropped);return;case"hook-failed":console.error(`The override of ${h} failed and is off: ${f.error.message}`);return}}),g=Object.assign(()=>p(),{registration:d,hook:i,stats:async()=>(await n.request({op:"hookStats"})).find(m=>m.registration===d)??null});return Object.defineProperty(g,"running",{get:()=>l,enumerable:!0}),g}const Fn={fit:"showAll",stretch:"exactFit",fill:"noBorder",none:"noScale"};class Ln{constructor(e){this.bridge=e}bridge;async zoom(e){await this.bridge.definition("room.RoomManagerWorld").at("instance","updateRoomZoom").call(Math.round(e))}async zoomLevel(){return await this.bridge.definition("gMainFrame").at("layerManager","bkg","scaleX").get()*100}async stretch(e){await this.bridge.stage().at("scaleMode").set(Fn[e])}hideHud(e){return this.bridge.highlight({target:{kind:"definition",name:"gui.GuiManager"},path:e?["mainHud",e]:["mainHud"]},ee({hide:!0}))}hideLayer(e){return this.bridge.highlight({target:{kind:"definition",name:"gMainFrame"},path:["layerManager",e]},ee({hide:!0}))}async setQuality(e){await this.bridge.stage().at("quality").set(e)}async setFrameRate(e){const t=this.bridge.stage().at("frameRate"),r=await t.get();return await t.set(Math.max(1,Math.min(120,e))),r}}class ze extends bt{format="json";envelope;constructor(e,t){super(e,t),this.envelope=Nn(e)}static create(e,t,r,a=-1,i="o"){const s=e==="toServer"?{t:"xt",b:{x:i,c:t,r:a,p:r}}:{t:"xt",b:{r:a,o:{_cmd:t,...r}}};return new ze(JSON.stringify(s),e)}get type(){return this.envelope.t}get command(){var e;const t=this.direction==="toServer"?this.envelope.b.c:(e=this.envelope.b.o)==null?void 0:e._cmd;return typeof t=="string"?t:null}get room(){const e=this.envelope.b.r;return typeof e=="number"&&Number.isInteger(e)?e:null}get params(){if(this.direction==="toServer")return this.envelope.b.p??{};const{_cmd:e,...t}=this.envelope.b.o??{};return t}get value(){return this.envelope}edit(e){e(this.envelope),this.markModified()}serialize(){return JSON.stringify(this.envelope)}}function Nn(n){let e;try{e=JSON.parse(n)}catch(t){throw new De(`Not JSON: ${t.message}`,"JSON_SYNTAX")}if(!Qe(e)||typeof e.t!="string"||!Qe(e.b))throw new De('A JSON message is an object with "t" and "b"',"JSON_SYNTAX");return e}function Qe(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}class et extends bt{constructor(e,t,r=null){super(e,t),this.problem=r}problem;format="raw";get command(){return null}get room(){return null}serialize(){return this.raw}}function Pt(n,e){try{switch(n.charAt(0)){case"<":return new It(n,e);case Lt:return new Nt(n,e);case"{":return new ze(n,e);default:return new et(n,e)}}catch(t){return new et(n,e,t)}}const Ie={send:"avatar.UserCommXtCommManager.onSendMessage",focusChat:"gui.ChatHistory.setFocusOnMsgText"};function In(n,e){const t=new Map;for(const[s,o]of Object.entries(e))t.set(s.toLowerCase(),o);if(t.size===0)return n;let r="",a="";const i=()=>{r+=t.get(a.toLowerCase())??a,a=""};for(const s of n)s===" "||s===" "?(i(),r+=s):a+=s;return i(),r}function jn(n,e){const t=n.toLowerCase();return e.some(r=>typeof r=="string"?r!==""&&t.includes(r.toLowerCase()):(r.lastIndex=0,r.test(n)))}async function _n(n,e={}){const{arg:t,fromClass:r,equals:a,exists:i,all:s}=n.flash.rules,o=e.shortcuts??{},l=e.blocked??[],c=r("avatar.UserCommXtCommManager","_mainHud","chatBar","text01_chat","text"),h=[],u=Be(async()=>{for(const d of h.splice(0).reverse())await d().catch(()=>{})});try{h.push(await n.flash.hook(Ie.send,{when:s(a(t("myMsg"),""),i(c)),replaceArgs:{myMsg:c}})),h.push(await n.flash.override(Ie.send,async d=>{var p;const[g,f]=d.argList,m=typeof f=="string"?f:"";if(m.trim()!==""&&jn(m,l)){(p=e.onBlocked)==null||p.call(e,m);return}const w=In(m,o);w===m?await d.original():await d.original(g,w)},{sequential:!0}))}catch(d){throw await u(),d}return u}async function zn(n,e={}){const t=e.style??{},r=n.flash.overlay,a=n.flash.use("gui.GuiManager").$at("mainHud"),i=e.maxLength??await n.flash.use("gui.GuiManager").$at("chatHist","chatMsgText","maxChars").$get().then(c=>typeof c=="number"&&c>0?c:70).catch(()=>70),s={family:t.font??"_sans",size:t.size??13},o=[],l=Be(async()=>{for(const c of o.splice(0).reverse())await c().catch(()=>{})});try{o.push(async()=>{await n.flash.use("gui.GuiManager").setFocusToChatText()});const c=await r.input({replaces:a.$at("chatBar"),placeholder:t.placeholderText??"Say something",maxLength:i,fill:t.background??16777215,stroke:t.border??8141549,cornerRadius:t.cornerRadius??6,padding:6,font:{...s,color:t.text??1120295}});o.push(()=>c.remove());const h=await r.button(t.buttonLabel??"Send",{replaces:a.$at("sendChatBtn"),fill:t.button??8141549,hoverFill:t.buttonHover??9133302,cornerRadius:t.cornerRadius??6,font:{...s,color:t.buttonText??16777215,bold:!0}});o.push(()=>h.remove());let u=!1;const d=async()=>{const p=c.value();if(!(u||p.trim()==="")){u=!0;try{await n.chat.say(p),await c.setValue(""),await c.focus()}finally{u=!1}}};return o.push(c.on("submit",()=>{d()})),o.push(h.on("click",()=>{d()})),o.push(await n.flash.hook(Ie.focusChat,{skip:!0,phase:"enter",capture:{args:[]}},()=>{c.focus()})),(e.focus??!0)&&await c.focus(),Object.assign(l,{input:c,send:d})}catch(c){throw await l(),c}}const Bn=[16096779,1096065,3900150,15485081,9133302,15680580,1357990,15381256],Ee=22;async function Hn(n,e={}){const t=e.style??{},r=n.flash.overlay,a=t.nameColors&&t.nameColors.length>0?t.nameColors:Bn,i=e.width??280,s=e.height??200,o={family:t.font??"_sans",size:t.size??12},l=new Map,c=[],h=Be(async()=>{for(const u of c.splice(0).reverse())await Promise.resolve(u()).catch(()=>{})});try{const u=await r.panel({title:e.title??"Chat",x:e.x??12,y:e.y??60,width:i,height:s,resizable:!0,fill:{color:t.background??1120295,alpha:t.backgroundAlpha??.9},stroke:t.border??3621201,titleFill:t.titleBar??2042167,titleHeight:Ee,titleFont:{...o,color:t.titleText??16777215,bold:!0},...e.onMove?{onMove:e.onMove}:{}});c.push(()=>u.remove());const d=await r.list({parent:u,width:i,height:s-Ee,fill:null,maxRows:e.maxRows??200,font:{...o,color:t.text??15987958}});c.push(u.on("resize",w=>{var b;(b=e.onResize)==null||b.call(e,w),d.update({width:w.width,height:w.height-Ee})})),c.push(d.on("link",w=>{const b=l.get(w);if(b){if(e.onNameClick){e.onNameClick(b);return}Dn(n,b.userId)}}));const p=async w=>{let b=null;if(w.kind===ye.free||w.kind===ye.freeSafeChat?b=w.text:w.kind===ye.safeChat&&(b=await n.chat.phrase(w.text).catch(()=>null)??null),b===null)return null;const x=n.room.players.get(w.userId),M=(x==null?void 0:x.avatarName)||(x==null?void 0:x.userName)||`#${w.userId}`,j=String(w.userId);return l.set(j,{userId:w.userId,name:M}),[{text:M,bold:!0,color:a[Math.abs(w.userId)%a.length],link:j},{text:`: ${b}`}]},f=(await Promise.all(n.chat.recent.map(p))).filter(w=>w!==null);f.length>0&&await d.append(...f);let m=Promise.resolve();return c.push(n.chat.onMessage(w=>{m=m.then(async()=>{const b=await p(w);b&&await d.append(b)}).catch(()=>{})})),Object.assign(h,{panel:u,note:w=>d.append({markup:w})})}catch(u){throw await h(),u}}async function Dn(n,e){const t=n.flash.use("avatar.AvatarManager").avatarViewList.$at(String(e)),r=await n.flash.highlight(t,{color:16436245,strength:3});setTimeout(()=>{r()},2e3)}function Be(n){let e=null;return()=>e??=n()}class qn{constructor(e){this.bridge=e,this.overlay=new Sn(e),this.entities=new dn(this),this.view=new Ln(e)}bridge;overlay;entities;view;rules=cn;hookIndex=null;use(e){return R(this.bridge,this.bridge.definition(e),{className:e})}global(e){return R(this.bridge,this.bridge.definition(e))}stage(){return R(this.bridge,this.bridge.stage())}client(){return R(this.bridge,this.bridge.gameClient())}whenReady(){return this.bridge.whenReady()}hooks(e){if(e!==void 0||!this.hookIndex){const t=this.bridge.hookTable(e).then(r=>new ln(r));t.catch(()=>{this.hookIndex===t&&(this.hookIndex=null)}),this.hookIndex=t}return this.hookIndex}async hook(e,t={},r){return hn(this.bridge,await this.hooks(),e,t,r)}async override(e,t,...[r]){return Cn(this.bridge,await this.hooks(),e,t,r??{})}style(e,t){return this.bridge.style(T(e),t)}hold(e,t,r={}){return Xe(this.bridge,[{place:e,value:t}],r)}holdAll(e,t={}){return Xe(this.bridge,e,t)}repeat(e,t={}){return un(this.bridge,e,t)}collect(e,t,r={}){return sn(this.bridge,e,t,r)}async track(e,t,r={}){if(await this.bridge.whenReady(),!this.bridge.features.includes("track"))throw new Error("This game is running a loader from before lists; look for them yourself");const a=r.where===void 0?{target:{kind:"stage"},path:[]}:T(r.where),i=s=>s.filter(o=>o instanceof L).map(o=>R(this.bridge,o.at(),{handle:o}));return this.bridge.track(a,e,{...r.mode!==void 0?{mode:r.mode}:{},...r.everyFrames!==void 0?{everyFrames:r.everyFrames}:{}},({added:s,removed:o})=>t({added:i(s),removed:i(o)}))}async snapshot(e,t={}){if(await this.bridge.whenReady(),!this.bridge.features.includes("snapshot"))throw new Error("This game is running a loader from before pictures; nothing can be drawn");return this.bridge.snapshot(T(e),t)}notes(){return new yn(this.bridge)}async find(e,t){return await fn(this.bridge,t,e??{})}answering(e,t){return new an(this.bridge,e,t)}watch(e,t,r){const a=r;let i,s=[],o;if(Array.isArray(e))i="list",o=[...e];else if(Un(e))i="one",o=[e];else{i="record";const u=e;s=Object.keys(u),o=s.map(d=>u[d])}const l=o.map(T),c=u=>i==="one"?u[0]:i==="list"?u:Object.fromEntries(s.map((d,p)=>[d,u[p]]));let h=null;return this.bridge.watch(l,t,(u,d)=>{const p=u.map(m=>O(this.bridge,m)),g=c(p),f=l.map((m,w)=>(d==null?void 0:d[w])??null);a(g,h,i==="one"?f[0]:c(f)),h=g})}onTick(e,t={}){return this.bridge.tick(t.everyFrames??1,e)}highlight(e,t={}){return this.bridge.highlight(T(e),ee(t))}hide(e){return this.bridge.highlight(T(e),ee({hide:!0}))}recolor(e,t){const r=t?T(t):{target:{kind:"loader"},path:[]};return this.bridge.highlight(r,{glow:null,...Et(e),hide:!1,pulse:null})}onKey(e,t,r={}){return this.bridge.onKey(mn(e,r),a=>Wn(t)({code:a.code,char:a.char,ctrl:a.ctrl,shift:a.shift,alt:a.alt,phase:a.phase,consumed:a.consumed===!0}))}}function Wn(n){return e=>{try{const t=n(e);t instanceof Promise&&t.catch(r=>tt(r))}catch(t){tt(t)}}}function tt(n){console.error("phantom.flash.onKey: a listener failed",n)}function Un(n){try{return T(n),!0}catch{return!1}}const Vn={avatarManager:"avatar.AvatarManager"},Gn="com.sbi.loader.LoaderCache.fetchCDNURL",Yn=2e4;class Kn{channel;flash;hooks=new Map;constructor(e,t){this.channel=e.content??null,this.flash=t}get available(){return this.channel!==null}async replace(e,t){const r=this.reach(),a=nt(e);await this.unhook(Te(a));const i=await r.replace(a,Me(t)),s=[],o=await this.pointClientAt(a,i.url);return o&&(this.hooks.set(Te(a),o),s.push("client")),s.push("proxy"),{...i,how:s,stop:()=>this.restore(a).then(()=>{})}}async restore(e){const t=this.reach(),r=nt(e);return await this.unhook(Te(r)),t.restore(r)}replacements(){return this.reach().list()}onRequest(e){return this.reach().observe(e)}async replaceOnScreen(e,t,r={}){const{url:a,id:i}=await this.addressOf(t),{refreshFrames:s,...o}=r,l=await this.flash.overlay.image(a,{...o,replaces:s===void 0?e:{place:e,refreshFrames:s}});return{url:a,stop:async()=>{await l.remove(),i&&await this.reach().release(i)}}}async load(e,t={}){const r=this.flash.bridge,a=Me(e),i=await r.construct("flash.display.Loader"),s=[];try{const o=await r.definition("flash.system.ApplicationDomain").at("currentDomain").get();s.push(()=>o.release());const l=await r.construct("flash.system.LoaderContext",!1,o);s.push(()=>l.release()),await l.at("allowCodeImport").set(t.allowCode===!0).catch(()=>{});const c=this.whenLoaded(i,t.timeoutMs??Yn);if(a.kind==="data-url"){const u=await this.decodeInFlash(a.url);s.push(()=>u.release()),await i.at("loadBytes").call(u,l)}else{const u=await this.reach().hold(a);s.push(()=>this.reach().release(u.id)),await i.at("load").call(new fe("flash.net.URLRequest",[u.url]),l)}await c;const h=await i.at("content").get();if(!h)throw new Error("Nothing was loaded");return{content:h,loader:i,unload:async()=>{await i.at("unloadAndStop").call().catch(()=>{}),await h.release().catch(()=>{}),await i.release().catch(()=>{})}}}catch(o){throw await i.release().catch(()=>{}),o}finally{for(const o of s)await o().catch(()=>{})}}async pointClientAt(e,t){if(e.kind==="pattern")return null;const r=Xn(e.value);if(!r)return null;const{arg:a,equals:i,startsWith:s,any:o}=this.flash.rules,l=e.kind==="prefix"?s:i;try{return await this.flash.hook(Gn,{when:o(l(a("assetPath"),r),l(a("assetPath"),`/${r}`)),replaceReturn:t})}catch{return null}}async unhook(e){const t=this.hooks.get(e);t&&(this.hooks.delete(e),await t().catch(()=>{}))}async addressOf(e){const t=Me(e);if(t.kind==="data-url")return{url:t.url,id:null};const r=await this.reach().hold(t);return{url:r.url,id:r.id}}async decodeInFlash(e){const t=e.indexOf(",");if(t===-1||e.slice(0,t).indexOf(";base64")===-1)throw new Error("Only base64 data: URLs can be loaded into the client");const r=await this.flash.bridge.definition("phantom.overlay.Base64").at("decode").call(e.slice(t+1));if(!r)throw new Error("The loader could not decode those bytes");return r}whenLoaded(e,t){const r=e.at("contentLoaderInfo");return new Promise((a,i)=>{const s=[],o=h=>{clearTimeout(l);for(const u of s.splice(0))u().catch(()=>{});h?i(h):a()},l=setTimeout(()=>o(new Error(`Flash did not load those bytes within ${t}ms`)),t),c=(h,u)=>r.listen(h,()=>o(u===null?null:new Error(u))).then(d=>s.push(d),d=>o(d));c("complete",null),c("ioError","Flash could not read those bytes"),c("securityError","Flash refused those bytes")})}reach(){if(!this.channel)throw new Error("This game cannot replace content: it was made without a content origin");return this.channel}}function Te(n){return`${n.kind}:${n.value}`}function Xn(n){let e=n.charAt(0)==="/"?n.slice(1):n;const t=e.indexOf("?");t!==-1&&(e=e.slice(0,t)),e.slice(0,8)==="content/"&&(e=e.slice(8));const r=e.indexOf("/"),a=r===-1?e:e.slice(0,r);return r!==-1&&a.length>0&&Jn(a)&&(e=e.slice(r+1)),e}function Jn(n){for(const e of n)if(e<"0"||e>"9")return!1;return n.length>0}function nt(n){const e=typeof n=="string"?{kind:"path",value:n}:n;if(!e||typeof e.value!="string"||!e.value)throw new TypeError("A replacement matches a path, a prefix or a pattern");const t=e.kind;if(t!=="path"&&t!=="prefix"&&t!=="pattern")throw new TypeError(`${t} is not path, prefix or pattern`);const r=e.value.charAt(0)==="/"?e.value:`/${e.value}`;return{kind:t,value:r}}function Me(n){if(typeof n=="string")return n.slice(0,5).toLowerCase()==="data:"?{kind:"data-url",url:n}:{kind:"file",path:n};if(n instanceof ArrayBuffer)return{kind:"bytes",bytes:new Uint8Array(n)};if(ArrayBuffer.isView(n)){const e=n;return{kind:"bytes",bytes:new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}}if(n&&typeof n=="object"){const e="contentType"in n&&n.contentType?n.contentType:null,t=e?{contentType:e}:{};if("bytes"in n){const r=n.bytes,a=r instanceof ArrayBuffer?new Uint8Array(r):r;if(!(a instanceof Uint8Array))throw new TypeError("bytes are a Uint8Array");return{kind:"bytes",bytes:a,...t}}if("dataUrl"in n&&typeof n.dataUrl=="string")return{kind:"data-url",url:n.dataUrl,...t};if("file"in n&&typeof n.file=="string")return{kind:"file",path:n.file,...t}}throw new TypeError("A source is bytes, a data: URL, or the path of a file on this computer")}const $={definitionByName:"GETDEFINITIONBYNAME",resourceStack:"com.sbi.loader.ResourceStack",guiManager:"gui.GuiManager",loadProgress:"loadProgress.LoadProgress",denEditor:"gui.DenEditor",fonts:"gui.Fonts",palette:"com.sbi.graphics.PaletteHelper",colorTable:"gui.ColorTable",avatarManager:"avatar.AvatarManager"},Zn={message:"com.sbi.popup.SBMessage",ok:"com.sbi.popup.SBOkPopup",okCancel:"com.sbi.popup.SBOkCancelPopup",yesNo:"com.sbi.popup.SBYesNoPopup",titled:"com.sbi.popup.SBStandardTitlePopup",parchment:"com.sbi.popup.SBParchmentPopup"},je={ink:1118483,line:3816e3,light:15790322,muted:10000543,accent:8141549,danger:15680580,size:12,cornerRadius:4},_e={ink:4403228,line:9071167,light:16643032,muted:9402972,accent:3123423,danger:13369344,size:11,cornerRadius:8},Se={game:28,phantom:24},Oe=22,Ae=4,rt={top:12,left:10,right:10,bottom:12},at=4293980400,Qn=12e4,er=500;function se(n){return(...e)=>{try{const t=n(...e);t instanceof Promise&&t.catch(U)}catch(t){U(t)}}}function U(n){console.error("phantom.ui: a listener failed",n)}const tr={game:110,phantom:96},ce="_sans";function nr(n,e=ce){return{skin:n,font:e,...n==="game"?_e:je}}const rr={PopupSkin:"The plain popup frame: `ba` (its `t`, `m` and `b` slices) and `c`, its content box.",PopupContent:"What a plain popup shows: a `text` field the popup sizes itself around.",OkPopupSkin:"The frame of a popup with one button.",OkPopupContent:"An OK button (`okBtn`) and the `text` above it.",YesNoPopupSkin:"The frame of a popup with two buttons.",YesNoPopupContent:"Yes (`yesBtn`) and No (`noBtn`), and the `text` above them.",okCancelPopupContent:"OK (`okCancelBtn`) and Cancel (`cancelBtn`).",ConfirmSkin:"The frame the client asks you to confirm something in.",Tooltip:"The client's own tooltip (`gui.ToolTipPopup`): `txt`, and `l`, `m` and `r`.",HelpTxtBubble:"The bubble the client points at something it is explaining.",closeBtn:"The round close button in the corner of the client windows.",scrollbar2:"A scrollbar: `track`, `handle`, `topBtn` and `botBtn`.",BuddyListPopup:"The buddy list window's frame.",BuddyListContent:"What the buddy list shows inside that frame.",BD_AvatarEditorSkin:"The frame of the avatar editor's own dialog.",BD_AvatarEditorContent:"What that dialog shows.",DenEditorAsset:"The whole den editor, as the client builds it.",MySettings:"The settings window.",MainHud:"The whole HUD.",FreeNameBar:"The name bar above a player who is not a member.",memberNameBar:"The name bar above a member.",AnimsTitleBanner:"The banner the client puts a title in.",ChatBalloonAsset:"A chat balloon.",Cursor:"The client's own mouse cursor.",QuestPickupIcon:"The icon an adventure shows over something to pick up.",MinigameLobbySkin:"A minigame lobby's frame.",MinigameLobbyContent:"What a minigame lobby shows.",BroadcastPopupSkin:"The frame an announcement is shown in.",BroadcastPopupContent:"What an announcement shows.",DenLockPopupSkin:"The frame of the den's lock settings.",DenLockPopupContent:"What the den lock settings show.",ReportRulesPopupSkin:"The frame of the report window's rules.",ReportRulesPopupContent:"What the report rules show."},ar=/^[A-Za-z_][A-Za-z0-9_]*$/;function it(n){if(!ar.test(n))throw new TypeError(`"${n}" is not a symbol name: a symbol is named in letters, digits and underscores`);return n}const st={gui:{className:$.guiManager,path:["guiLayer"]},hud:{className:$.guiManager,path:["mainHud"]},room:{className:$.avatarManager,path:["playerAvatarWorldView","parent"]},avatarEditor:{className:$.guiManager,path:["avatarEditor","avEditor"]},denEditor:{className:$.denEditor,path:["staticEditor"]}},ot="stage",lt={avatarEditor:{open:"gui.AvatarEditor.init",close:"gui.AvatarEditor.destroy",spot:"avatarEditor"},denEditor:{open:"gui.DenEditor.init",close:"gui.DenEditor.destroy",spot:"denEditor"},settings:{open:"gui.MySettings.init",close:"gui.MySettings.destroy",spot:null},buddyList:{open:"buddy.BuddyList.init",close:"buddy.BuddyList.destroy",spot:null},petCreator:{open:"gui.PetCreator.init",close:"gui.PetCreator.destroy",spot:null},achievements:{open:"gui.AchievementViewer.init",close:"gui.AchievementViewer.destroy",spot:null},bulletinBoard:{open:"gui.BulletinBoard.init",close:"gui.BulletinBoard.destroy",spot:null},playerSearch:{open:"gui.PlayerSearch.init",close:"gui.PlayerSearch.destroy",spot:null},recycle:{open:"gui.RecycleItems.init",close:"gui.RecycleItems.destroy",spot:null},trade:{open:"gui.TradeManager.init",close:"gui.TradeManager.destroy",spot:null},petInventory:{open:"gui.PetInventory.init",close:"gui.PetInventory.destroy",spot:null},reportPlayer:{open:"gui.ReportAPlayer.init",close:"gui.ReportAPlayer.destroy",spot:null},serverSelector:{open:"gui.ServerSelector.init",close:"gui.ServerSelector.destroy",spot:null}},ir={ok:0,yesNo:1,continueExit:2,continue:3};function sr(n,e,t={}){const r={slot:"layer"},a={slot:"callback"},i=t.name??null,s=Zn[n];switch(n){case"message":return{className:s,args:[r,{slot:"skin"},e,!0,!0,t.modal??!1,t.draggable??!0,t.darken??!1,i]};case"ok":return{className:s,args:[r,e,t.darken??!0,null,!0,!0,t.modal??!0,t.draggable??!1,i]};case"yesNo":return{className:s,args:[r,e,t.darken??!0,a,null,!0,!0,t.modal??!0,t.draggable??!1,i]};case"okCancel":return{className:s,args:[r,e,t.darken??!0,a,null]};case"titled":return{className:s,args:[r,e,t.title??null,t.mediaId??370,a,!0,t.darken??!0]};case"parchment":return{className:s,args:[r,ir[t.buttons??"ok"],e,t.darken??!0,a,null]}}}function ct(n){const e=Math.max(1,Math.floor(n.columns)),t=[];for(let r=0;r<Math.max(0,Math.floor(n.count));r++){const a=Math.floor(r/e),i=r%e;t.push({index:r,row:a,column:i,x:i*(n.tileWidth+n.gap),y:a*(n.tileHeight+n.gap),width:n.tileWidth,height:n.tileHeight})}return t}function or(n,e){const t=e.gap,r=n.length;if(r===0)return[];const a=(e.width+t)/r;return n.map((i,s)=>{const o=Math.round(s*a),l=s===r-1?e.width+t:Math.round((s+1)*a);return{index:s,value:i,x:o,width:Math.max(0,l-o-t)}})}function lr(n){const e=Math.max(0,n.contentHeight-n.viewHeight),t=Math.min(e,Math.max(0,n.offset)),r=n.minThumb??16,a=n.contentHeight>0?n.viewHeight/n.contentHeight:1,i=Math.max(Math.min(n.trackHeight,r),Math.min(n.trackHeight,Math.round(n.trackHeight*a))),s=n.trackHeight-i;return{offset:t,max:e,thumbY:e>0?Math.round(t/e*s):0,thumbHeight:i}}function cr(n,e,t){const r=Math.max(1,Math.round(n-e-t+1)),a=-Math.floor(r/2);return{middle:r,middleY:a,topY:a-e,bottomY:a+r-1}}function hr(n,e){const t=e?{top:e.y,left:e.x,right:n.width-e.x-e.width,bottom:n.height-e.y-e.height}:null,r=(s,o)=>{const l=t==null?void 0:t[s];return l!==void 0&&Number.isFinite(l)&&l>=2&&l<=o/4?Math.ceil(l):rt[s]},a={top:r("top",n.height),left:r("left",n.width),right:r("right",n.width),bottom:r("bottom",n.height)},i={x:a.left+Ae,y:a.top,width:Math.max(0,Math.floor(n.width-a.left-a.right-2*Ae)),height:Math.max(Oe,Math.floor(n.height-a.top-a.bottom-Ae))};return{edge:a,measured:t!==null&&Object.keys(rt).every(s=>a[s]===Math.ceil(t[s])),panel:i,titleHeight:Oe,body:{width:i.width,height:i.height-Oe}}}class ur{bridge;flash;drawn=new Set;popups=new Set;symbolMaker=null;gameFont=null;defaultSkin="phantom";known={art:!1,palettes:!1};readyTimeoutMs=Qn;popup;constructor(e,t){this.bridge=e.flash,this.flash=t,this.popup=new dr((r,a,i,s,o)=>this.openPopup(r,a,i,s,o),()=>this.clear())}get skin(){return this.defaultSkin}set skin(e){this.defaultSkin=e}async status(){const[e,t]=await Promise.all([this.artLoaded(),this.palettesLoaded()]);return{art:e,palettes:t}}async ready(e=this.readyTimeoutMs){const t=await this.waitFor({art:!0,palettes:!0},e);if(t.art&&t.palettes)return t;const r=[t.art?null:"its library art",t.palettes?null:"its colour palettes"].filter(Boolean);throw new Error(`The game has not loaded ${r.join(" or ")} yet: waited ${Math.round(e/1e3)} seconds`)}async theme(e){const t=e??this.defaultSkin;return nr(t,t==="game"?await this.clientFont():ce)}symbols(){return Object.entries(rr)}async hasSymbol(e){const t=it(e);try{return await this.bridge.definition($.resourceStack).at("hudAssetsLoaderInfo","applicationDomain","hasDefinition").call(t)===!0}catch{return!1}}async symbol(e,t={}){const r=it(e);await this.waitFor({art:!0});const a=await this.flash.overlay.group({x:t.x??0,y:t.y??0,...t.scale===void 0?{}:{scale:t.scale},...t.visible===void 0?{}:{visible:t.visible}});let i=null;try{i=await(await this.maker()).at("apply").call(null,[r,t.localize===!0]),await(await this.nodeObject(a)).at("addChild").call(i),await this.adopt(a,{...t.parent===void 0||t.parent===null?{}:{parent:P(t.parent)},...t.host===void 0?{}:{host:t.host===null?null:this.placeOf(t.host)},...t.replaces===void 0?{}:{replaces:t.replaces===null?null:this.placeOf(t.replaces)}})}catch(h){throw await a.remove(),i&&await this.bridge.release([i]).catch(()=>{}),h}const s=i,o=s.at(),l=new Set;return this.widget(a,t.skin??this.defaultSkin,{name:r,object:s,on:async(h,u)=>{const d=await o.listen(ht[h],()=>u()),p=async()=>{l.delete(p),await d()};return l.add(p),p},size:async()=>({width:await s.at("width").get()??0,height:await s.at("height").get()??0})},async()=>{for(const h of[...l])await h().catch(()=>{});await this.bridge.release([s]).catch(()=>{})})}async window(e={}){const t=e.skin??this.defaultSkin,r=t==="game",a=r&&(await this.waitFor({art:!0})).art,i=await this.theme(t),s={width:e.width??280,height:e.height??200},o={x:e.x??40,y:e.y??40},l=r?30:24,c=await this.flash.overlay.panel({x:o.x,y:o.y,width:s.width,height:s.height,title:e.title??"",titleHeight:l,draggable:e.draggable!==!1,resizable:e.resizable===!0&&!r,cornerRadius:i.cornerRadius,fill:r?{color:i.light,alpha:0}:{color:i.ink,alpha:.94},stroke:r?null:i.line,titleFill:i.line,titleFont:{family:i.font,size:i.size+1,bold:!0,color:i.light},visible:!1});let h=null;if(a)try{h=await this.dressWindow(c,s.height)}catch(w){console.warn(`phantom.ui.window: the popup frame could not be drawn: ${Re(w)}`)}else r&&console.warn(`phantom.ui.window: the game has not loaded its popup art after ${Math.round(this.readyTimeoutMs/1e3)} seconds, so "${e.title??""}" is drawn in the game skin's colours instead`);const u=h?{x:h.layout.panel.x,y:h.layout.panel.y}:{x:0,y:0};if(h?await c.update({x:o.x+u.x,y:o.y+u.y,width:h.layout.panel.width,height:h.layout.panel.height,titleHeight:h.layout.titleHeight,titleFill:{color:i.line,alpha:.004},titleFont:{family:i.font,size:i.size+1,bold:!0,color:i.ink}}):r&&await c.update({fill:{color:_e.light,alpha:.96},stroke:{color:_e.line,width:2}}),e.parent)try{await this.adopt(c,{parent:P(e.parent)})}catch(w){throw await c.remove(),h&&await this.bridge.release(h.held).catch(()=>{}),w}const d=h?{width:h.width,height:h.height,bodyWidth:h.layout.body.width,bodyHeight:h.layout.body.height}:{...s,bodyWidth:s.width,bodyHeight:Math.max(0,s.height-l)},p=new Set,g=[],f=this.widget(c,t,{body:c,...d,framed:h!==null,move:(w,b)=>c.update({x:w+u.x,y:b+u.y}),setTitle:w=>c.update({title:w}),onClose:w=>(p.add(w),async()=>{p.delete(w)}),onMove:w=>{const b=c.on("move",({x,y:M})=>w({x:x-u.x,y:M-u.y}));return async()=>{await b()}}},async()=>{for(const w of g.splice(0))await w().catch(()=>{});h&&await this.bridge.release(h.held).catch(()=>{})}),m=()=>{f().then(()=>p.forEach(w=>w()))};if(e.closable!==!1&&(h!=null&&h.close)){const w=await h.close.at().listen(ht.down,m);g.push(async()=>{await w()})}else e.closable!==!1&&(await this.flash.overlay.button("x",{parent:c,x:d.bodyWidth-(r?26:24),y:2,width:18,height:16,cornerRadius:i.cornerRadius,fill:i.line,hoverFill:{color:i.danger,alpha:.8},font:{family:i.font,size:i.size,bold:!0,color:i.light}})).on("click",m);return e.visible!==!1&&await c.show(),f}async button(e,t={}){const r=t.skin??this.defaultSkin,a=await this.theme(r),i=await this.flash.overlay.button(e,{...this.box(t,{width:tr[r],height:Se[r]}),...Z(a,t.primary===!0),cornerRadius:a.cornerRadius,...t.disabled===void 0?{}:{disabled:t.disabled},font:{family:a.font,size:a.size,bold:!0,color:t.primary===!0||r==="phantom"?a.light:a.ink}});return this.widget(i,r,{setLabel:s=>i.setLabel(s),setDisabled:s=>i.setDisabled(s),onClick:s=>{const o=i.on("click",se(s));return async()=>{await o()}}})}async label(e,t={}){const r=t.skin??this.defaultSkin,a=await this.theme(r),i=await this.flash.overlay.text(e,{x:t.x??0,y:t.y??0,...t.parent?{parent:P(t.parent)}:{},...t.visible===void 0?{}:{visible:t.visible},centered:t.centered===!0,font:{family:a.font,size:t.heading===!0?a.size+3:a.size,bold:t.heading===!0,color:t.muted===!0?a.muted:r==="game"?a.ink:a.light},...t.background===!0?{background:r==="game"?{color:a.light,alpha:.9}:{color:a.ink,alpha:.7},padding:4}:{}});return this.widget(i,r,{setText:s=>i.update({text:s})})}async input(e={}){const t=e.skin??this.defaultSkin,r=await this.theme(t),a=await this.flash.overlay.input({...this.box(e,{width:200,height:Se[t]}),...e.value===void 0?{}:{value:e.value},...e.placeholder===void 0?{}:{placeholder:e.placeholder},...e.maxLength===void 0?{}:{maxLength:e.maxLength},...e.multiline===void 0?{}:{multiline:e.multiline},...e.disabled===void 0?{}:{disabled:e.disabled},fill:t==="game"?r.light:16777215,stroke:r.line,cornerRadius:r.cornerRadius,font:{family:r.font,size:r.size,color:t==="game"?r.ink:1120295}});return this.widget(a,t,{value:()=>a.value(),setValue:i=>a.setValue(i),focus:()=>a.focus(),onChange:i=>{const s=a.on("change",se(i));return async()=>{await s()}},onSubmit:i=>{const s=a.on("submit",se(i));return async()=>{await s()}}})}async checkbox(e,t={}){const r=t.skin??this.defaultSkin,a=await this.theme(r),i=await this.flash.overlay.group({x:t.x??0,y:t.y??0,...t.parent?{parent:P(t.parent)}:{},...t.visible===void 0?{}:{visible:t.visible}});let s=t.checked===!0;const o=await this.flash.overlay.button(s?"x":"",{parent:i,width:14,height:14,cornerRadius:Math.min(3,a.cornerRadius),fill:r==="game"?a.light:{color:a.ink,alpha:.9},hoverFill:r==="game"?16777215:{color:a.line,alpha:.9},stroke:a.line,font:{family:a.font,size:a.size,bold:!0,color:a.accent}});await this.flash.overlay.text(e,{parent:i,x:20,y:0,font:{family:a.font,size:a.size,color:r==="game"?a.ink:a.light}});const l=new Set,c=async h=>{s=h,await o.setLabel(h?"x":"")};return o.on("click",()=>{c(!s).then(()=>l.forEach(h=>h(s)))}),this.widget(i,r,{checked:()=>s,setChecked:c,onChange:h=>(l.add(h),async()=>{l.delete(h)})})}async dropdown(e){var t;const r=e.skin??this.defaultSkin,a=await this.theme(r),i=e.width??140,s=e.height??Se[r],o=await this.flash.overlay.group({x:e.x??0,y:e.y??0,...e.parent?{parent:P(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}});let l=[...e.choices],c=e.value??((t=l[0])==null?void 0:t.value)??null;const h=f=>{var m;return((m=l.find(w=>w.value===f))==null?void 0:m.label)??e.placeholder??"Choose..."},u=await this.flash.overlay.button(h(c),{parent:o,width:i,height:s,cornerRadius:a.cornerRadius,...Z(a,!1),font:{family:a.font,size:a.size,color:r==="game"?a.ink:a.light}}),d=await this.flash.overlay.list({parent:o,y:s+2,width:i,height:Math.min(140,Math.max(20,l.length*16+8)),visible:!1,fill:r==="game"?a.light:{color:a.ink,alpha:.96},stroke:a.line,cornerRadius:a.cornerRadius,rows:l.map(f=>f.label),font:{family:a.font,size:a.size,color:r==="game"?a.ink:a.light}});let p=!1;const g=new Set;return u.on("click",()=>{p=!p,p?d.show():d.hide()}),d.on("row",f=>{const m=l[f];p=!1,d.hide(),m&&(c=m.value,u.setLabel(m.label).then(()=>g.forEach(w=>w(m.value))))}),this.widget(o,r,{value:()=>c,setValue:async f=>{c=f,await u.setLabel(h(f))},setChoices:async f=>{l=[...f],await d.setRows(l.map(m=>m.label)),await u.setLabel(h(c))},onChange:f=>(g.add(f),async()=>{g.delete(f)})})}async tabs(e){var t;const r=e.skin??this.defaultSkin,a=await this.theme(r),i=e.width??260,s=e.tabHeight??22,o=await this.flash.overlay.group({x:e.x??0,y:e.y??0,...e.parent?{parent:P(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}),l=or(e.tabs.map(g=>g.value),{width:i,gap:2});let c=e.value??((t=e.tabs[0])==null?void 0:t.value)??"";const h=new Map,u=new Map,d=new Set;for(const g of l){const f=e.tabs[g.index];u.set(f.value,await this.flash.overlay.button(f.label,{parent:o,x:g.x,width:g.width,height:s,cornerRadius:a.cornerRadius,...Z(a,f.value===c),font:{family:a.font,size:a.size,bold:f.value===c,color:f.value===c||r==="phantom"?a.light:a.ink}})),h.set(f.value,await this.flash.overlay.group({parent:o,y:s+4,visible:f.value===c}))}const p=async g=>{if(h.has(g)){c=g;for(const[f,m]of h)await(f===g?m.show():m.hide());for(const[f,m]of u)await m.update({...Z(a,f===g),font:{family:a.font,size:a.size,bold:f===g,color:f===g||r==="phantom"?a.light:a.ink}})}};for(const[g,f]of u)f.on("click",()=>{p(g).then(()=>d.forEach(m=>m(g)))});return this.widget(o,r,{current:()=>c,select:p,body:g=>{const f=h.get(g);if(!f)throw new TypeError(`There is no tab called "${g}"`);return f},onSelect:g=>(d.add(g),async()=>{d.delete(g)})})}async list(e={}){const t=e.skin??this.defaultSkin,r=await this.theme(t),a=await this.flash.overlay.list({...this.box(e,{width:240,height:160}),...e.rows===void 0?{}:{rows:[...e.rows]},...e.maxRows===void 0?{}:{maxRows:e.maxRows},fill:t==="game"?r.light:{color:r.ink,alpha:.85},stroke:r.line,cornerRadius:r.cornerRadius,font:{family:r.font,size:r.size,color:t==="game"?r.ink:r.light}});return this.widget(a,t,{setRows:i=>a.setRows([...i]),append:(...i)=>a.append(...i),onRow:i=>{const s=a.on("row",se(i));return async()=>{await s()}}})}async grid(e){const t=e.skin??this.defaultSkin,r=await this.theme(t),a={columns:e.columns??4,tileWidth:e.tileWidth??48,tileHeight:e.tileHeight??48,gap:e.gap??4},i=await this.flash.overlay.group({x:e.x??0,y:e.y??0,...e.parent?{parent:P(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}),s=new Set,o=[],l=async c=>{for(const u of o.splice(0))await u.remove();const h=ct({count:c.length,...a});for(const u of h){const d=c[u.index],p=await this.flash.overlay.button(d.label??"",{parent:i,x:u.x,y:u.y,width:u.width,height:u.height,cornerRadius:r.cornerRadius,fill:d.color??(t==="game"?r.light:{color:r.ink,alpha:.9}),hoverFill:d.color??(t==="game"?16777215:r.line),pressedFill:d.color??r.accent,stroke:r.line,...d.disabled===void 0?{}:{disabled:d.disabled},font:{family:r.font,size:r.size-2,color:t==="game"?r.ink:r.light}});p.on("click",()=>s.forEach(g=>g(d.value,u.index))),o.push(p),d.image!==void 0&&o.push(await this.flash.overlay.image(d.image,{parent:i,x:u.x+2,y:u.y+2,width:u.width-4,height:u.height-4}))}};return await l(e.items),this.widget(i,t,{setItems:l,onSelect:c=>(s.add(c),async()=>{s.delete(c)})})}async scroll(e={}){const t=e.skin??this.defaultSkin,r=await this.theme(t),a=e.width??220,i=e.height??120,s=e.step??32,o=await this.flash.overlay.panel({x:e.x??0,y:e.y??0,width:a,height:i,titleHeight:0,draggable:!1,cornerRadius:r.cornerRadius,fill:t==="game"?{color:r.light,alpha:.9}:{color:r.ink,alpha:.85},stroke:r.line,...e.parent?{parent:P(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}),l=await this.flash.overlay.group({parent:o,x:0,y:0});let c=e.contentHeight??i,h=0;const u=async d=>{h=lr({contentHeight:c,viewHeight:i,offset:d,trackHeight:i}).offset,await l.update({y:-h})};for(const[d,p,g]of[["^",-s,0],["v",s,i-16]])(await this.flash.overlay.button(d,{parent:o,x:a-16,y:g,width:14,height:14,cornerRadius:Math.min(3,r.cornerRadius),...Z(r,!1),font:{family:r.font,size:r.size-2,bold:!0,color:t==="game"?r.ink:r.light}})).on("click",()=>{u(h+p)});return this.widget(o,t,{body:l,offset:()=>h,scrollTo:u,setContentHeight:async d=>{c=d,await u(h)}})}async tooltip(e={}){const t=await this.bubble(e);return e.target&&this.explain(t,P(e.target)),t}async bubble(e){const t=e.skin??this.defaultSkin,r=e.text??"";if(t==="game"){const s=await this.clientTooltip(r,e);if(s)return s}const a=await this.theme(t),i=await this.flash.overlay.text(r,{x:e.x??0,y:e.y??0,visible:e.visible===!0,...e.parent?{parent:P(e.parent)}:{},background:t==="game"?{color:a.light,alpha:.95}:{color:a.ink,alpha:.92},padding:4,font:{family:a.font,size:a.size,color:t==="game"?a.ink:a.light}});return this.widget(i,t,{setText:s=>i.update({text:s}),showAt:async(s,o)=>{await i.update({x:s,y:o,visible:!0})}})}explain(e,t){const r=t.on("over",({x:s,y:o})=>{e.showAt(s+12,o-10).catch(U)}),a=t.on("out",()=>{e.hide().catch(U)}),i=t.onRemoved(()=>{e.remove().catch(U)});e.node.onRemoved(()=>{i(),r().catch(()=>{}),a().catch(()=>{})})}async progress(e={}){const t=e.skin??this.defaultSkin,r=await this.theme(t),a=e.width??200,i=e.height??16,s=await this.flash.overlay.group({x:e.x??0,y:e.y??0,...e.parent?{parent:P(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}});await this.flash.overlay.rect({parent:s,width:a,height:i,cornerRadius:r.cornerRadius,fill:t==="game"?r.light:{color:r.ink,alpha:.9},stroke:r.line});let o=ut(e.value??0);const l=await this.flash.overlay.rect({parent:s,width:Math.round(a*o),height:i,cornerRadius:r.cornerRadius,fill:r.accent}),c=await this.flash.overlay.text(e.label??"",{parent:s,x:Math.round(a/2),y:Math.round(i/2),centered:!0,font:{family:r.font,size:r.size-1,bold:!0,color:t==="game"?r.ink:r.light}});return this.widget(s,t,{value:()=>o,setValue:async h=>{o=ut(h),await l.update({width:Math.round(a*o)})},setLabel:h=>c.update({text:h})})}async colors(e={}){const t=e.skin??this.defaultSkin,r=e.columns??10,a=e.swatchWidth??24,i=e.swatchHeight??30,{values:s,indexes:o}=await this.palette(e.palette??1),l=new Set;let c=e.value??o[0]??0;const h=p=>{c=p,l.forEach(g=>g(p,s[p]??0))},u=Math.max(1,Math.ceil(o.length/r)),d=t==="game"?await this.clientColorTable({columns:r,rows:u,width:r*a,height:u*i,values:s,indexes:o,current:c,options:e,tell:h}):await this.swatchGrid({columns:r,swatchWidth:a,swatchHeight:i,values:s,indexes:o,current:c,options:e,tell:h});return this.widget(d,t,{value:()=>c,onPick:p=>(l.add(p),async()=>{l.delete(p)})})}async paletteValues(e="game"){const{values:t,indexes:r}=await this.palette(e);return r.map(a=>t[a]??0)}places(){const e=Object.keys(st);return[ot,...e,...pr]}place(e){if(e===ot)return this.bridge.stage();const t=st[e];return t?this.bridge.definition(t.className).at(...t.path):this.bridge.definition($.guiManager).at("mainHud",e)}async attach(e,t){const r=P(t);return await this.flash.overlay.attach(this.placeOf(e),r),()=>r.remove()}async replace(e,t){const r=P(t);return await this.flash.overlay.replace(this.placeOf(e),r),()=>r.remove()}async hide(e){const t=await this.flash.hide(this.placeOf(e)),r=async()=>{this.drawn.delete(r),await t()};return this.drawn.add(r),r}piece(e,...t){return this.pieceOf(this.placeOf(e),t)}async feed(e,t,r={}){return typeof t=="function"?this.deferredFeed(e,t,r):this.insideFeed(e,t,r)}async insideFeed(e,t,r){if(!Object.keys(t).length)throw new TypeError(`A feed of ${e} names no argument to change`);let a=null,i=0;const s=await this.flash.hook(e,{phase:"enter",capture:{args:!0},replaceArgs:t,...r.when===void 0?{}:{when:r.when},...r.first===void 0?{}:{first:r.first},...r.every===void 0?{}:{every:r.every},...r.perFrame===void 0?{}:{perFrame:r.perFrame}},o=>{i+=1,a={method:e,call:o.call,args:[...o.argList],named:{...o.args},on:this.pieceOf(this.bridge.stage(),[])}});return this.feedOf(e,!0,s,()=>i,()=>a)}async deferredFeed(e,t,r){if(r.deferred!==!0)throw new TypeError(`A feed of ${e} was given a function, which cannot run inside the call: the client's method is skipped and run again once the function answers. A builder whose result the client uses in the same breath comes up empty that way. Give the arguments themselves to change them inside the call, or set "deferred" to say the waiting is understood.`);let a=null,i=0;const s=async c=>{i+=1;const h={method:e,call:c.call,args:[...c.argList],named:{...c.args},on:this.pieceOf(te(c.self)??this.bridge.stage(),[])};a=h;const u=await t(h);if(!u){await c.original();return}const d=[...h.args];for(const[p,g]of Object.entries(u)){const f=/^\d+$/.test(p)?Number(p):c.hook.parameters.findIndex(m=>m.name===p);if(f<0||f>=d.length){const m=c.hook.parameters.map(w=>w.name).join(", ");throw new TypeError(`${e} has no argument "${p}" (its arguments: ${m})`)}d[f]=g}await c.original(...d)},o={};r.when!==void 0&&(o.when=r.when),r.first!==void 0&&(o.first=r.first),r.every!==void 0&&(o.every=r.every),r.sequential!==void 0&&(o.sequential=r.sequential),r.perFrame!==void 0&&(o.perFrame=r.perFrame),r.returns!==void 0&&(o.returns=r.returns);const l=await this.flash.override(e,s,o);return this.feedOf(e,!1,l,()=>i,()=>a)}feedOf(e,t,r,a,i){const s=async()=>{this.drawn.delete(s),await r()};this.drawn.add(s);const o=s;return Object.defineProperty(o,"method",{value:e,enumerable:!0}),Object.defineProperty(o,"inside",{value:t,enumerable:!0}),Object.defineProperty(o,"calls",{get:a,enumerable:!0}),Object.defineProperty(o,"last",{value:i,enumerable:!0}),o}screens(){return Object.keys(lt)}onScreen(e,t){const r=lt[e];let a=!0;const i=[];return(async()=>{for(const[o,l]of[[r.open,!0],[r.close,!1]]){const c=await this.flash.hook(o,{phase:l?"exit":"enter",capture:{args:[]}},()=>t({name:e,open:l,spot:r.spot}));if(!a){await c();return}i.push(c)}})().catch(o=>{console.error(`phantom.ui.onScreen could not hook ${e}: ${Re(o)}`)}),()=>{a=!1;for(const o of i.splice(0))o().catch(()=>{})}}async clear(){for(const e of[...this.popups])await e().catch(()=>{});for(const e of[...this.drawn])await e().catch(()=>{})}pieceOf(e,t){const r=te(e);if(!r)throw new TypeError("Expected a place in the client, or one of Phantom's spots");const a=r.at(...t);return{place:a,at:(...s)=>this.pieceOf(a,s),exists:async()=>{try{const s=await a.get();return s!=null}catch{return!1}},get:async(...s)=>{try{const o=await a.at(...s).get();return O(this.bridge,o)??null}catch{return null}},set:(s,o)=>a.at(...typeof s=="string"?[s]:s).set(o),read:async(...s)=>{const o=await Promise.all(s.map(c=>a.at(c).get().catch(()=>null))),l={};return s.forEach((c,h)=>{l[c]=O(this.bridge,o[h]??null)}),l},call:async(s,...o)=>{const l=await G(this.bridge,o);return O(this.bridge,await a.at(s).call(...l))},on:async(s,o)=>{const l=await a.listen(s,h=>o(O(this.bridge,h))),c=async()=>{this.drawn.delete(c),await l()};return this.drawn.add(c),c},attach:s=>this.attach(a,s),replace:s=>this.replace(a,s),hide:()=>this.hide(a),use:()=>R(this.bridge,a)}}widget(e,t,r,a){let i=null;const s=()=>(i??=(async()=>{this.drawn.delete(o),a&&await a().catch(()=>{})})(),i),o=async()=>{await e.remove(),await s()};this.drawn.add(o),e.onRemoved(()=>{s()});const l={skin:t,node:e,move:(c,h)=>e.update({x:c,y:h}),show:()=>e.show(),hide:()=>e.hide(),remove:o,...r};for(const[c,h]of Object.entries(l))Object.defineProperty(o,c,{value:h,enumerable:!0,configurable:!0});return o}box(e,t){return{x:e.x??0,y:e.y??0,width:e.width??t.width,height:e.height??t.height,...e.parent?{parent:P(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}}placeOf(e){return typeof e=="string"?this.place(e):e}maker(){if(!this.symbolMaker){const e=this.bridge.definition($.definitionByName).get().then(t=>{if(!t)throw new TypeError("This client has no GETDEFINITIONBYNAME");return t});e.catch(()=>{this.symbolMaker===e&&(this.symbolMaker=null)}),this.symbolMaker=e}return this.symbolMaker}async nodeObject(e){const t=await new V(this.bridge,{kind:"overlay"},[]).at("getChildByName").call(`phantomNode${e.node}`);if(!t)throw new TypeError(`Overlay node ${e.node} is not drawn straight into the overlay, so it cannot be dressed`);return t}async adopt(e,t){const r=t.parent;if(r&&gr(r))throw new Error("What it was to be drawn in was taken off the screen before it could be put there");await e.update(t)}async waitFor(e,t=this.readyTimeoutMs){const r=Date.now()+Math.max(0,t);for(;;){const a=await this.status(),i=(!e.art||a.art)&&(!e.palettes||a.palettes),s=r-Date.now();if(i||s<=0||this.bridge.state==="closed")return a;await new Promise(o=>setTimeout(o,Math.min(er,s)))}}async artLoaded(){return this.known.art||(this.known.art=await this.hasSymbol("PopupSkin")),this.known.art}async palettesLoaded(){if(!this.known.palettes)try{const e=await this.bridge.definition($.palette).at("gamePalette").get();this.known.palettes=Array.isArray(e)&&e.length>0}catch{}return this.known.palettes}clientFont(){if(!this.gameFont){const e=this.bridge.definition($.fonts),t=this.known.palettes,r=(async()=>{for(const a of[["defaultFontFormat","font"],["defaultFont","fontName"]])try{const i=await e.at(...a).get();if(typeof i=="string"&&i.length>0)return i}catch{}return ce})();r.then(a=>{a===ce&&!t&&this.gameFont===r&&(this.gameFont=null)},()=>{this.gameFont===r&&(this.gameFont=null)}),this.gameFont=r}return this.gameFont}async frameOnly(e){const t=await e.at("numChildren").get()??0;for(let r=0;r<Math.min(t,32);r+=1){const a=await e.at("getChildAt").call(r);try{await a.at("name").get()!=="ba"&&await a.at("visible").set(!1)}finally{await this.bridge.release([a]).catch(()=>{})}}}async dressWindow(e,t){const a=await(await this.maker()).at("apply").call(null,["PopupSkin",!1]),i=[a];try{const s=a.at("ba"),[o,l]=await Promise.all([oe(s.at("t","height")),oe(s.at("b","height"))]),c=cr(t,o,l);await Promise.all([s.at("m","height").set(c.middle),s.at("m","y").set(c.middleY),s.at("t","y").set(c.topY),s.at("b","y").set(c.bottomY)]),await this.frameOnly(a);const h=await this.boundsOf(s,a),u={width:Math.round(h.width),height:Math.round(h.height)},d=await this.parchmentOf(a,h).catch(()=>null),p=hr(u,d);await Promise.all([a.at("x").set(Math.round(-h.x-p.panel.x)),a.at("y").set(Math.round(-h.y-p.panel.y))]);const g=await this.nodeObject(e);i.push(g),await g.at("addChildAt").call(a,0);const f=await this.frameClose(g,p).catch(()=>null);return f&&i.push(f),{...u,layout:p,close:f,held:i}}catch(s){throw await this.bridge.release(i).catch(()=>{}),s}}async frameClose(e,t){const a=await(await this.maker()).at("apply").call(null,["closeBtn",!1]);try{const i=await this.boundsOf(a,a);if(i.width<=0||i.height<=0)throw new TypeError("The close button has no size");const s=Math.min(1,(t.titleHeight-2)/i.height);return await Promise.all([a.at("scaleX").set(s),a.at("scaleY").set(s),a.at("x").set(Math.round(t.panel.width-2-(i.x+i.width)*s)),a.at("y").set(Math.round((t.titleHeight-i.height*s)/2-i.y*s))]),await e.at("addChild").call(a),a}catch(i){throw await this.bridge.release([a]).catch(()=>{}),i}}async boundsOf(e,t){const r=await e.at("getBounds").call(t);try{const[a,i,s,o]=await Promise.all(["x","y","width","height"].map(l=>oe(r.at(l))));return{x:a,y:i,width:s,height:o}}finally{await this.bridge.release([r]).catch(()=>{})}}async parchmentOf(e,t){const r=Math.ceil(t.width),a=Math.ceil(t.height);if(r<=0||a<=0||r>2048||a>2048)return null;const i=await this.bridge.construct("flash.display.BitmapData",r,a,!0,0);try{await i.at("draw").call(e,new fe("flash.geom.Matrix",[1,0,0,1,-t.x,-t.y]));const s=await i.at("getPixel32").call(Math.floor(r/2),Math.floor(a/2));if(typeof s!="number"||s>>>24!==255)return null;const o=await i.at("getColorBoundsRect").call(at,(s&at)>>>0,!0);try{const[l,c,h,u]=await Promise.all(["x","y","width","height"].map(d=>oe(o.at(d))));return{x:l,y:c,width:h,height:u}}finally{await this.bridge.release([o]).catch(()=>{})}}finally{await i.at("dispose").call().catch(()=>{}),await this.bridge.release([i]).catch(()=>{})}}async clientTooltip(e,t){let r;try{r=await this.symbol("Tooltip",{skin:"game",x:t.x??0,y:t.y??0,visible:t.visible===!0,...t.parent?{parent:t.parent}:{}})}catch{return null}const a=async i=>{await r.object.at("setToolTipText").call(i)};try{e&&await a(e)}catch{return await r.remove(),null}return Object.assign(r,{setText:a,showAt:async(i,s)=>{await r.node.update({x:i,y:s,visible:!0})}})}async palette(e){const t=await this.waitFor({palettes:!0}),r=this.bridge.definition($.palette),a=t.palettes?await r.at("gamePalette").get():null,i=dt(a);if(!i.length)throw new Error(`The game has not loaded its colour palettes yet: waited ${Math.round(this.readyTimeoutMs/1e3)} seconds`);if(e==="game")return{values:i,indexes:i.map((o,l)=>l)};const s=dt(await r.at(e===1?"avatarPalette1":"avatarPalette2").get());return{values:i,indexes:s.length?s:i.map((o,l)=>l)}}async clientColorTable(e){const t=await this.flash.overlay.group({x:e.options.x??0,y:e.options.y??0,visible:!1});try{const r=await this.bridge.construct($.colorTable);await r.at("init").call(0,e.width,e.height,e.columns,e.rows,e.values,e.indexes,e.current,(i,s)=>e.tell(Number(s)),-1);const a=await this.nodeObject(t);await a.at("addChild").call(r),await this.bridge.release([a,r]).catch(()=>{}),await this.adopt(t,{...e.options.parent?{parent:P(e.options.parent)}:{},visible:e.options.visible!==!1})}catch(r){throw await t.remove(),r}return t}async swatchGrid(e){const t=await this.flash.overlay.group({x:e.options.x??0,y:e.options.y??0,...e.options.parent?{parent:P(e.options.parent)}:{},...e.options.visible===void 0?{}:{visible:e.options.visible}}),r=ct({count:e.indexes.length,columns:e.columns,tileWidth:e.swatchWidth,tileHeight:e.swatchHeight,gap:1}),a={color:je.line,alpha:.6},i={color:je.light,width:2},s=new Map;let o=e.current;for(const l of r){const c=e.indexes[l.index],h=await this.flash.overlay.button("",{parent:t,x:l.x,y:l.y,width:l.width,height:l.height,cornerRadius:2,fill:e.values[c]??0,hoverFill:e.values[c]??0,stroke:c===o?i:a});s.set(c,h),h.on("click",()=>{var u;const d=o;o=c,d!==c&&((u=s.get(d))==null||u.update({stroke:a}).catch(U),h.update({stroke:i}).catch(U)),e.tell(c)})}return t}openPopup(e,t,r,a,i){let s=()=>{};const o=new Promise(f=>{s=f});let l=null,c=!1,h=null;const u=f=>{c||(c=!0,h&&clearTimeout(h),h=null,this.popups.delete(p),s(f))},d=()=>{c||h||(h=setTimeout(()=>u(i),fr))},p=async()=>{const f=l;l=null,u(i),f&&await f.at("destroy").call().catch(()=>{})};this.popups.add(p);const g=sr(e,t,r);return(async()=>{await this.waitFor({art:!0});const f=this.bridge.definition(r.layer==="load"?$.loadProgress:$.guiManager).at(r.layer==="load"?"loadLayer":"guiLayer"),m=[];for(const b of g.args){if(b!==null&&typeof b=="object"){if(b.slot==="layer")m.push(await f.get());else if(b.slot==="callback")m.push((...x)=>u(a(x[0]??null)));else{const x=await this.maker();m.push(await x.at("apply").call(null,["PopupSkin",!1]))}continue}m.push(b)}const w=await this.bridge.construct(g.className,...m);l=w,await w.at("closeCallback").set(()=>d()).catch(()=>{})})().catch(f=>{this.popups.delete(p),c||(c=!0,s(i)),console.error(`phantom.ui.popup.${e} could not open: ${Re(f)}`)}),Object.assign(o,{close:p})}}class dr{constructor(e,t){this.open=e,this.closeEverything=t}open;closeEverything;message(e,t={}){return this.open("message",e,t,()=>{},void 0)}ok(e,t={}){return this.open("ok",e,t,()=>{},void 0)}okCancel(e,t={}){return this.open("okCancel",e,t,Pe,null)}yesNo(e,t={}){return this.open("yesNo",e,t,Pe,null)}titled(e,t={}){return this.open("titled",e,t,()=>{},void 0)}parchment(e,t={}){return this.open("parchment",e,t,Pe,null)}async closeAll(){await this.closeEverything()}}const fr=50,ht={click:"click",down:"mouseDown",up:"mouseUp",over:"rollOver",out:"rollOut"},pr=["chatBar","chatHist","chatTxt","sendChatBtn","safeChatBtn","actionsBtn","emotesBtn","denBtn","worldMapBtn","buddyListBtn","newsBtn","partyBtn","mySettingsBtn","money","zoneName"];function P(n){if(!n)throw new TypeError("Expected a widget or an overlay node");return typeof n.node=="number"?n:n.node}function gr(n){let e=!1;return n.onRemoved(()=>{e=!0})(),e}function Z(n,e){return e?{fill:n.accent,hoverFill:{color:n.accent,alpha:.85},pressedFill:{color:n.accent,alpha:.7},stroke:n.line}:n.skin==="game"?{fill:n.light,hoverFill:16777215,pressedFill:n.line,stroke:n.line}:{fill:{color:n.ink,alpha:.92},hoverFill:n.line,pressedFill:{color:n.line,alpha:.7},stroke:n.line}}function Pe(n){if(n!==null&&typeof n=="object"&&!Array.isArray(n)){const e=n.status;if(typeof e=="boolean")return e}return null}function ut(n){return Number.isFinite(n)?Math.min(1,Math.max(0,n)):0}function Re(n){return n instanceof Error?n.message:String(n)}async function oe(n){const e=await n.get();if(typeof e!="number"||!Number.isFinite(e))throw new TypeError(`Expected a number at ${n.path.join(".")}, and read ${String(e)}`);return e}function dt(n){return Array.isArray(n)?n.map(e=>typeof e=="number"?e:0):[]}function he(n){return n instanceof S?{code:n.code,message:n.message,...n.stack?{stack:n.stack}:{}}:n instanceof Error?{code:"FAILED",message:n.message||n.name,...n.stack?{stack:n.stack}:{}}:{code:"FAILED",message:F(n)}}function mr(n){const e=n&&typeof n.code=="string"&&n.code?n.code:"FAILED";return new S(e,(n==null?void 0:n.message)||"Phantom could not do this")}function de(n){return q(n,new WeakMap)}function q(n,e){if(jt(n))return q(n.value,e);if(typeof n=="function"||typeof n=="symbol")return;if(typeof n!="object"||n===null)return n;const t=_t(n);if(e.has(t))return e.get(t);if(t instanceof Date||t instanceof RegExp||t instanceof ArrayBuffer||ArrayBuffer.isView(t))return t;if(Array.isArray(t)){const a=[];e.set(t,a);for(const i of t)a.push(q(i,e));return a}if(t instanceof Map){const a=new Map;e.set(t,a);for(const[i,s]of t)a.set(q(i,e),q(s,e));return a}if(t instanceof Set){const a=new Set;e.set(t,a);for(const i of t)a.add(q(i,e));return a}if(t instanceof Error)return he(t);const r={};e.set(t,r);for(const[a,i]of Object.entries(t)){const s=q(i,e);s!==void 0&&(r[a]=s)}return r}function F(n){if(typeof n=="string")return n;if(n instanceof Error)return n.stack||`${n.name}: ${n.message}`;if(n===void 0)return"undefined";if(typeof n=="function")return`[Function ${n.name||"anonymous"}]`;if(typeof n=="symbol"||typeof n=="bigint")return n.toString();try{const e=new WeakSet,t=JSON.stringify(de(n),(r,a)=>{if(typeof a=="object"&&a!==null){if(e.has(a))return"[Circular]";e.add(a)}return typeof a=="bigint"?`${a}n`:a});return ft(t??String(n))}catch{return ft(String(n))}}const $e=1e4;function ft(n){return n.length>$e?`${n.slice(0,$e)}… (${n.length-$e} more)`:n}const wr=["log","info","warn","error"];function yr(n,e){const t=new Map;let r=!1;for(const a of wr){const i=n[a].bind(n);t.set(a,i),n[a]=(...s)=>{if(i(...s),!r){r=!0;try{e(a,s.map(F))}finally{r=!1}}}}return()=>{for(const[a,i]of t)n[a]=i}}function br(n,e,t){return new qn(new Jt(vr(n,e),{firstId:t}))}function vr(n,e){const t=new Set;let r=null;const a=i=>{for(const s of t)s(i)};return{send(i){n.call("flash.request",e,[i]).catch(s=>{const o=kr(i,s);o?a(o):n.log("warn",[`A Flash request was refused: ${F(s)}`])})},onMessage(i){return t.add(i),r??=n.subscribe("flash.messages",e,{event(s){const[o]=s;typeof o=="string"&&a(o)},ended(s){r=null,s&&n.log("warn",[`Flash stopped answering: ${s.message}`])}}),()=>{t.delete(i),!t.size&&r&&(r(),r=null)}}}}function kr(n,e){let t;try{t=vt(n)}catch{return null}if(typeof(t==null?void 0:t.id)!="number")return null;const r=e instanceof S?e.code:"FAILED",a=e instanceof Error?e.message:F(e);return X({kind:"result",id:t.id,ok:!1,error:{name:r,message:a,errorId:0}})}function xr(n){let e=null,t=null;const r=()=>{const a=n.flash();return e??=new Kn({flash:a.bridge,content:Er(n.port,n.game)},a),e};return{avatar:{view:()=>n.flash().bridge.definition(Vn.avatarManager).at("playerAvatarWorldView").get()},adventures:{record:()=>Tr(n.remote)},realtime:{join:(a,i)=>Rt(n.remote.realtime,a,i)},content:{load:(a,i)=>r().load(a,i),replaceOnScreen:(a,i,s)=>r().replaceOnScreen(a,i,s)},ui:()=>{const a=n.flash();return t??=new ur({flash:a.bridge},a),t},recipes:{chatShortcuts:async a=>_n(await Ce(n),a),customChatBox:async a=>zn(await Ce(n),a),chatHistoryPanel:async a=>Hn(await Ce(n),a)}}}function Er(n,e){const t=()=>{throw new S("NOT_SUPPORTED","Only holding and releasing content happen in a frame")};return{hold:r=>n.call("content.hold",e,[r]),release:r=>n.call("content.release",e,[r]),replace:t,restore:t,list:t,observe:t}}function Tr(n){const e=Date.now(),t=[];let r=null,a=null;const i=()=>{r===null&&n.adventures.current().then(o=>r??=(o==null?void 0:o.scriptDefId)??null).catch(()=>{}),a===null&&n.adventures.actor("diff_level").then(o=>a??=(o==null?void 0:o.state)??null).catch(()=>{})};i();const s=n.adventures.onStep(({time:o,...l})=>{i(),t.push({...l,at:o-e})});return{stop:()=>(s(),{version:1,scriptDefId:r,difficulty:a,steps:[...t]})}}async function Ce(n){const e=n.flash(),{remote:t}=n,r=[...await t.chat.recent()],a=new Map;for(const i of await t.room.players.list())a.set(i.userId,i);return t.room.players.onEnter(i=>a.set(i.userId,i)),t.room.players.onLeave(i=>a.delete(i.userId)),t.chat.onMessage(i=>r.push(i)),{flash:e,chat:{say:t.chat.say,phrase:t.chat.phrase,onMessage:t.chat.onMessage,recent:r},room:{players:{get:i=>a.get(i)??null}}}}function Mr(n,e){const t={};for(const r of Object.keys($t)){const a=r.split(".");let i=t;for(const o of a.slice(0,-1))i=i[o]??={};const s=a[a.length-1];i[s]=Ct(r)?Ar(n,e,r):Or(n,e,r)}return He(t,"")}const Sr=new Set(["then","toJSON","constructor","nodeType","tagName"]);function He(n,e){for(const[t,r]of Object.entries(Object.getOwnPropertyDescriptors(n))){const a=r.get||r.set?null:r.value;!a||typeof a!="object"||!r.writable||(n[t]=He(a,`${e}${t}.`))}return new Proxy(Object.freeze(n),{get(t,r,a){if(typeof r!="string"||r in t)return Reflect.get(t,r,a);if(!(Sr.has(r)||r.startsWith("__v_")))throw new S("NOT_SUPPORTED",`phantom.${e}${r} is not in this Phantom's copy of the plugin SDK. Either the name is wrong, or Phantom is serving an older build of @phantomclient/plugin than this plugin was written against; building that package again gives every plugin the newer SDK.`)}})}function Or(n,e,t){return(...r)=>n.call(`sdk:${t}`,e,r)}function Ar(n,e,t){return r=>{if(typeof r!="function")throw new TypeError(`${t} takes a listener function`);return n.subscribe(`sdk:${t}`,e,{event:a=>r(...a),ended(a){a&&n.log("warn",[`${t} stopped: ${a.code}: ${F(a.message)}`])}})}}function pt(n,e,t,r){const a=i=>({direction:r,...i==="*"?{}:{commands:[...i]}});return{send(i){return n.call("packets.send",e,[t,String(i)])},watch(i,s){return n.subscribe("packets.watch",e,{event(o){const l=Rr(o,r);l&&s(Pt(l.text,l.direction))},ended:o=>{o&&n.log("warn",[`Watching the traffic stopped: ${o.message}`])}},a(i))},on(i,s){return n.subscribe("packets.intercept",e,{event:()=>{},intercepted:o=>{Pr(n,o,s)},ended:o=>{o&&n.log("warn",[`Hooking the traffic stopped: ${o.message}`])}},a(i))}}}async function Pr(n,e,t){let r;try{r=Pt(e.text,e.direction),await t(r)}catch(a){n.log("error",[`A traffic hook failed: ${F(a)}`]),n.verdict(e.requestId,!1,null);return}n.verdict(e.requestId,r.dropped,r.modified?r.encode():null)}function Rr(n,e){const[t,r]=n;if(typeof t=="string")return{text:t,direction:gt(r)?r:e};if(typeof t=="object"&&t!==null){const{text:a,direction:i}=t;if(typeof a=="string")return{text:a,direction:gt(i)?i:e}}return null}function gt(n){return n==="toServer"||n==="toClient"}function $r(n){const e=new Map,t=new Set;function r(i){var s,o;const l=i??Ht(k.role);if(!l)throw new S("NO_GAME",((s=k.role)==null?void 0:s.kind)==="page"||((o=k.role)==null?void 0:o.kind)==="logic"?"This frame works with several games: name one, as ctx.phantom(id), from ctx.games()":"This frame is not bound to a game yet");let c=e.get(l);return c||(c=Cr(n,l),e.set(l,c)),c}return{ctx:{get plugin(){return k.plugin},get granted(){return k.granted},get preferences(){return k.preferences},can:i=>Fr(k.granted.scopes,i),games:()=>[...k.games],onGames(i){return t.add(i),()=>t.delete(i)},phantom:r,storage:{get:i=>n.call("storage.get",null,[String(i)]),set:(i,s)=>n.call("storage.set",null,[String(i),s]),remove:i=>n.call("storage.remove",null,[String(i)]),keys:()=>n.call("storage.keys",null,[])},async fetch(i,s){const o=await n.call("fetch",null,[String(i),s??{}]);return Lr(o)},copy:i=>n.call("copy",null,[String(i)]),notify:(i,s)=>n.call("notify",null,s===void 0?[String(i)]:[String(i),String(s)]),toast:(i,s)=>n.call("toast",null,[String(i),s??{}]),confirm:(i,s)=>n.call("confirm",null,[String(i),s??{}]),openUrl:i=>n.call("openUrl",null,[String(i)]),log:(...i)=>n.log("log",i.map(F))},notifyGames(i){for(const s of[...t])try{s([...i])}catch(o){n.log("error",[`An onGames listener failed: ${F(o)}`])}},dispose(){t.clear(),e.clear()}}}function Cr(n,e){let t=null;const r=()=>{if(t)return t;if(k.flashIds===null)throw new S("PERMISSION_DENIED","game.flash needs the flash scope, which this plugin was not granted");return t=br(n,e,k.flashIds),t},a=Mr(n,e),i=xr({port:n,game:e,remote:a,flash:r}),s={...a,avatar:Object.freeze({...a.avatar,...i.avatar}),adventures:Object.freeze({...a.adventures,...i.adventures}),content:Object.freeze({...a.content,...i.content}),realtime:Object.freeze({...a.realtime,...i.realtime}),recipes:Object.freeze(i.recipes),id:e,server:pt(n,e,"toServer","toClient"),client:pt(n,e,"toClient","toServer")};return Object.defineProperties(s,{flash:{enumerable:!0,get:r},ui:{enumerable:!0,get:i.ui}}),He(s,"")}function Fr(n,e){if(n.includes(e))return!0;if(!e.startsWith("network:"))return!1;const t=e.slice(8);return n.some(r=>{if(!r.startsWith("network:*."))return!1;const a=r.slice(9);return t.endsWith(a)&&t.length>a.length})}function Lr(n){const e=n.body??"";return{status:n.status,ok:n.status>=200&&n.status<300,headers:n.headers??{},text:async()=>e,json:async()=>JSON.parse(e)}}const Nr=6e4;function Ir(n,e={}){const t=e.prefix??`f${Math.random().toString(36).slice(2,10)}-`,r=e.timeoutMs??Nr;let a=0,i=!1;const s=new Map,o=new Map,l=()=>`${t}${a+=1}`;function c(f,m){if(!i)try{n({phantom:I,type:"log",level:f,values:m})}catch{}}function h(f,m,w){if(i)return Promise.reject(new S("FAILED","The frame was closed"));const b=l();return new Promise((x,M)=>{const j=setTimeout(()=>{s.delete(b),M(new S("TIMEOUT",`Phantom did not answer ${f} in ${r/1e3}s`))},r);s.set(b,{resolve:x,reject:M,timer:j});try{n({phantom:I,type:"call",id:b,method:f,game:m,args:de(w)})}catch(A){clearTimeout(j),s.delete(b),M(new S("FAILED",`${f} could not be sent: ${F(A)}`))}})}function u(f,m,w,b){if(i)return()=>{};const x=l();o.set(x,w);try{n({phantom:I,type:"subscribe",id:x,topic:f,game:m,...b?{filter:de(b)}:{}})}catch(M){throw o.delete(x),new S("FAILED",`${f} could not be heard: ${F(M)}`)}return()=>{!o.delete(x)||i||n({phantom:I,type:"unsubscribe",id:x})}}function d(f,m,w){i||n({phantom:I,type:"verdict",requestId:f,drop:m,text:w})}function p(f){switch(f.type){case"call-result":{const m=s.get(f.id);return m?(s.delete(f.id),clearTimeout(m.timer),f.ok?m.resolve(f.value):m.reject(mr(f.error)),!0):!1}case"event":{const m=o.get(f.subscription);return m?(g(()=>m.event(Array.isArray(f.args)?f.args:[])),!0):!1}case"intercepted":{const m=o.get(f.subscription);return m!=null&&m.intercepted?(m.intercepted(f),!0):(d(f.requestId,!1,null),!!m)}case"subscription-ended":{const m=o.get(f.subscription);return m?(o.delete(f.subscription),g(()=>{var w;return(w=m.ended)==null?void 0:w.call(m,f.error)}),!0):!1}}}function g(f){try{f()}catch(m){c("error",[`A listener failed: ${F(m)}`])}}return{call:h,subscribe:u,verdict:d,log:c,receive:p,close(f){if(!i){i=!0;for(const m of s.values())clearTimeout(m.timer),m.reject(new S("FAILED",f));s.clear(),o.clear()}}}}function jr(n,e,t=new Set){const r=new Set;for(const[i,s]of Object.entries((e==null?void 0:e.variables)??{}))!i.startsWith("--phantom-")||typeof s!="string"||(n.style.setProperty(i,s),r.add(i));for(const i of t)r.has(i)||n.style.removeProperty(i);const a=(e==null?void 0:e.mode)==="light"?"light":"dark";return n.dataset.theme=a,n.style.setProperty("color-scheme",a),r}const _r=2e3;function zr(n,e){Dt(e.development??!1);let t=!1,r=new Set,a=null,i=null;function s(y){var v;t||(n.post(y),(v=e.tap)==null||v.call(e,y))}const o=Ir(s),l=$r(o),c=l.ctx;Ve(c);function h(y){var v;const E=he(y);try{s({phantom:I,type:"crash",error:E})}catch{}(v=n.view)==null||v.showError(E,k.development)}let u;const p=new Promise(y=>u=y).then(async()=>{try{const y=e.definition,v=await(typeof y=="function"?y():y);return a=Br(v),!0}catch(y){return h(y),!1}}),g=p.then(async y=>{var v;if(!y||((v=k.role)==null?void 0:v.kind)!=="logic")return y;if(s({phantom:I,type:"ready",implements:{pages:le(a==null?void 0:a.pages),panels:le(a==null?void 0:a.panels),commands:le(a==null?void 0:a.commands),commandViews:le(a==null?void 0:a.commandViews)}}),!(a!=null&&a.setup))return!0;try{const E=await a.setup(c);typeof E=="function"&&(t?j(E):i=E)}catch(E){h(E)}return!0});function f(y){if(t||!Ft(y))return;const v=y;switch(v.type){case"init":m(v);return;case"games":k.games=Array.isArray(v.games)?v.games:[],l.notifyGames(k.games);return;case"stop":_();return;case"mount":b(v);return;case"invoke":M(v);return;case"call-result":case"event":case"subscription-ended":case"intercepted":o.receive(v);return}}function m(y){var v;n.root&&y.theme&&(r=jr(n.root,y.theme,r)),Object.assign(k,{role:k.role??y.role??null,plugin:y.plugin??k.plugin,mode:((v=y.theme)==null?void 0:v.mode)==="light"?"light":"dark",granted:y.granted??{scopes:[]},preferences:y.preferences??{},games:Array.isArray(y.games)?y.games:[],flashIds:typeof y.flashIds=="number"?y.flashIds:null,development:k.development||!!y.development,initialized:!0}),l.notifyGames(k.games),u()}const w=n.listen(f);async function b(y){var v,E;const[H]=await Promise.all([p,((v=n.loadStyles)==null?void 0:v.call(n))??Promise.resolve()]);t||((E=k.role)==null?void 0:E.kind)==="logic"||(Object.assign(k,{kind:y.kind,contribution:y.contribution,props:y.props??{}}),H&&x())}function x(){var y;if(!k.kind||!k.contribution)return;const[v,E]=k.kind==="page"?[a==null?void 0:a.pages,"pages"]:k.kind==="panel"?[a==null?void 0:a.panels,"panels"]:[a==null?void 0:a.commandViews,"commandViews"],H=v==null?void 0:v[k.contribution];if(!H){h(new S("NOT_SUPPORTED",`definePlugin has no ${E}["${k.contribution}"], so there is nothing to show here`));return}try{(y=n.view)==null||y.mount(H,c)}catch(z){h(z)}}async function M(y){var v,E;const H=(z,me)=>{try{s({phantom:I,type:"result",id:y.id,ok:z,...me})}catch(we){s({phantom:I,type:"result",id:y.id,ok:!1,error:he(new S("FAILED",`The answer could not be sent to Phantom: ${F(we)}`))})}};try{if(!await g||!a)throw new S("FAILED","The plugin did not load");if(y.kind!=="commands")throw new S("NOT_SUPPORTED",`Phantom asked for an unknown kind, "${y.kind}"`);const z=(v=a.commands)==null?void 0:v[y.contribution];if(typeof z!="function")throw new S("NOT_SUPPORTED",`definePlugin has no commands["${y.contribution}"] function`);const me={arguments:((E=y.input)==null?void 0:E.arguments)??{}},we=await z(me,c.phantom(y.game),c);H(!0,{value:de(we??null)})}catch(z){H(!1,{error:he(z)})}}function j(y){try{const v=y();v instanceof Promise&&v.catch(E=>A(E))}catch(v){A(v)}}function A(y){o.log("error",[`setup's cleanup failed: ${F(y)}`])}async function _(){const y=i;if(i=null,y)try{await Promise.race([Promise.resolve(y()),new Promise(v=>setTimeout(v,_r))])}catch(v){A(v)}s({phantom:I,type:"stopped"})}return{ctx:c,crash:h,log:(y,v)=>o.log(y,v),replaceDefinition(y){var v;a=y,((v=k.role)==null?void 0:v.kind)!=="logic"&&x()},stop(){t||(i&&(j(i),i=null),t=!0,w(),o.close("The frame was closed"),l.dispose(),Ve(null))}}}function le(n){return Object.keys(n??{})}function Br(n){return!n||typeof n!="object"?{}:"default"in n&&n.default&&typeof n.default=="object"?n.default:n}const Hr={class:"flex flex-col p-3",role:"alert"},Dr={class:"flex flex-col gap-2 overflow-hidden rounded-lg border border-phantom-danger/25 bg-phantom-danger/10 px-3 py-2.5"},qr={class:"flex items-start gap-2"},Wr={class:"min-w-0 flex-1"},Ur={class:"text-xs font-medium text-phantom-danger"},Vr={class:"mt-0.5 break-words text-2xs text-phantom-text-soft"},Gr=["textContent"],Yr={key:1,class:"text-2xs text-phantom-subtle"},Kr=zt({__name:"ErrorCard",props:{error:{},development:{type:Boolean},kind:{}},emits:["dismiss"],setup(n,{emit:e}){const t=n,r=e,a=Bt(()=>t.kind==="panel"?"This panel":t.kind==="page"?"This page":"This plugin");return(i,s)=>(re(),ae("div",Hr,[K("div",Dr,[K("div",qr,[s[1]||(s[1]=K("span",{class:"mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-phantom-danger","aria-hidden":"true"},null,-1)),K("div",Wr,[K("p",Ur,be(a.value)+" stopped with an error",1),K("p",Vr,be(n.error.message),1)]),n.development?(re(),ae("button",{key:0,type:"button",class:"shrink-0 rounded px-1.5 text-2xs text-phantom-muted transition-colors hover:bg-phantom-danger/10 hover:text-phantom-text",onClick:s[0]||(s[0]=o=>r("dismiss"))}," Dismiss ")):qe("",!0)]),n.development&&n.error.stack?(re(),ae("pre",{key:0,class:"max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md bg-phantom-canvas/60 px-2.5 py-2 font-mono text-3xs text-phantom-muted",textContent:be(n.error.stack)},null,8,Gr)):n.development?qe("",!0):(re(),ae("p",Yr," More is in the plugin's log, in Plugins. "))])]))}});function Xr(n){let e=null,t=null,r=-1;const a=()=>{const o=Math.ceil(Math.max(n.content.scrollHeight,n.content.getBoundingClientRect().height));o!==r&&(r=o,n.onResize(o))},i=typeof ResizeObserver>"u"?null:new ResizeObserver(a);i==null||i.observe(n.content);function s(){t==null||t.unmount(),t=null,n.content.hidden=!1}return{mount(o,l){s(),e==null||e.unmount(),document.documentElement.dataset.kind=k.kind??"",e=We({name:"PhantomPluginView",render:()=>Ue(o,{...k.props})}),e.provide(qt,l),e.config.errorHandler=c=>n.onError(c),e.mount(n.content)},showError(o,l){t==null||t.unmount(),n.content.hidden=!0,t=We({render:()=>Ue(Kr,{error:o,development:l,kind:k.kind,onDismiss:()=>s()})}),t.mount(n.errors),a()},unmount(){i==null||i.disconnect(),e==null||e.unmount(),t==null||t.unmount(),e=null,t=null}}}function Jr(n){window.parent===window&&Zr();const e=mt("app"),t=mt("phantom-error");let r=null;function a(o){window.parent.postMessage(o,"*")}const i=Xr({content:e,errors:t,onError:o=>r==null?void 0:r.crash(o),onResize:o=>{document.documentElement.dataset.kind&&a({phantom:I,type:"resize",height:o})}});r=zr({post:a,listen(o){const l=c=>{c.source===window.parent&&o(c.data)};return window.addEventListener("message",l),()=>window.removeEventListener("message",l)},root:document.documentElement,view:i,...n.loadStyles?{loadStyles:n.loadStyles}:{}},n);const s=r;return yr(console,(o,l)=>s.log(o,l)),window.addEventListener("error",o=>{String(o.message).includes("ResizeObserver loop")||s.crash(o.error??o.message)}),window.addEventListener("unhandledrejection",o=>s.crash(o.reason)),window.addEventListener("pagehide",()=>{i.unmount(),s.stop()}),document.addEventListener("click",o=>{const l=o.target,c=l&&typeof l.closest=="function"?l.closest("a[href]"):null;if(!c)return;const h=c.getAttribute("href")??"";h.startsWith("#")||(o.preventDefault(),/^https:\/\//i.test(h)?s.ctx.openUrl(h).catch(()=>{}):s.log("warn",[`Only https links open from a plugin; this one goes to ${h}`]))}),s}function mt(n){const e=document.getElementById(n);if(e)return e;const t=document.createElement("div");return t.id=n,document.body.append(t),t}function Zr(){const n=document.createElement("p");n.className="m-6 max-w-md text-xs text-phantom-muted",n.textContent="This is a Phantom plugin frame. It runs inside Phantom: turn on Developer mode in Plugins, and a plugin served by phantom-plugin dev shows up there.",document.body.prepend(n)}const wt="/dist/plugin.js",Qr="/dist/plugin.css";let yt=null;function ea(){return yt??=new Promise(n=>{const e=document.createElement("link");e.rel="stylesheet",e.href=Qr,e.onload=e.onerror=()=>n(),document.head.append(e)}),yt}async function ta(){const n=await import(wt);if(!n.default)throw new Error(`${wt} has no default export. Export definePlugin({ ... }) as default.`);return n.default}Jr({definition:ta,loadStyles:ea});
1
+ import{c as Gt,a as Yt,b as Kt,s as Xt,j as Jt,S as Qt,i as Zt,d as en,e as tn,P as z,f as nn}from"./chunks/sdk-permissions-AYsXGgro.js";import{M as Lt,P as Ze,X as rn,a as an,b as sn,C as Ee,c as A,r as on}from"./chunks/api-DCkkcNDr.js";import{i as ln,t as cn,d as hn,o as ue,c as de,a as ee,b as Se,e as et,f as un,g as tt,h as nt}from"./chunks/runtime-dom.esm-bundler-Dcouf4CU.js";import{f as x,b as dn,r as fn,s as rt,P as gn}from"./chunks/state-CyERnsrb.js";class L extends Error{constructor(e,t,r=null){super(wn(t,r,e)),this.code=e,this.flash=r,this.name="BridgeError"}code;flash}function wn(n,e,t){if(typeof n=="string"&&n.trim()!=="")return mn(n,e);const r=yn(n);if(r)return r;const a=typeof(e==null?void 0:e.name)=="string"?e.name.trim():"";return a||`The game answered with no reason (${t})`}const pn={1006:"that member is not a method",1009:"something the call reached was null",1010:"that member is not there",1034:"a value was not of the type the member takes",1056:"that object has nowhere to put the value",1063:"the call was given the wrong number of arguments",1069:"the object has no member of that name",1502:"a script in the game ran for longer than the player allows",2007:"a value the call needs was null"};function mn(n,e){const t=typeof(e==null?void 0:e.errorId)=="number"?e.errorId:0,r=pn[t];return!r||!/^\s*Error #\d+\s*$/.test(n)?n:`${n.trim()}: ${r}`}function yn(n){if(n==null)return"";if(typeof n=="string")return n.trim();if(typeof n!="object")return String(n);const e=n;if(typeof e.message=="string"&&e.message.trim()!=="")return e.message;try{const t=JSON.stringify(n);return t&&t!=="{}"?t:""}catch{return""}}const at=2;function te(n){return encodeURIComponent(JSON.stringify(n))}function Nt(n){return JSON.parse(decodeURIComponent(n))}function bn(n){return typeof n=="object"&&n!==null&&"$handle"in n}function vn(n){switch(n.kind){case"result":return n.id;case"event":return n.listener;case"callback":return n.callback;case"hook":case"override":case"hook-dropped":case"hook-failed":return n.registration;case"watch":return n.watch;case"tick":return n.tick;case"overlay":return n.node;case"key":return n.key;case"drive-failed":return n.drive;case"track":return n.track;default:return null}}class ke{constructor(e,t=[]){this.className=e,this.args=t}className;args}class _{constructor(e,t,r){this.bridge=e,this.handle=t,this.className=r}bridge;handle;className;at(...e){return new J(this.bridge,{kind:"handle",handle:this.handle},e)}release(){return this.bridge.release([this])}}class J{constructor(e,t,r=[]){this.bridge=e,this.target=t,this.path=r}bridge;target;path;at(...e){return new J(this.bridge,this.target,[...this.path,...e])}get(){return this.bridge.request({op:"get",target:this.target,path:[...this.path]})}set(e){return this.bridge.request({op:"set",target:this.target,path:[...this.path],value:this.bridge.encode(e)}).then(()=>{})}call(...e){return this.bridge.request({op:"call",target:this.target,path:[...this.path],args:e.map(t=>this.bridge.encode(t))})}describe(){return this.bridge.request({op:"describe",target:this.target,path:[...this.path]})}listen(e,t){return this.bridge.listen(this,e,t)}get entry(){return{target:this.target,path:[...this.path]}}}const kn=new Set(["drive-failed","track","hook","override","hook-dropped","hook-failed","watch","tick","overlay","key"]);class xn{constructor(e,t={}){this.transport=e,this.timeoutMs=t.timeoutMs??5e3,this.firstId=t.firstId??1,this.nextId=this.firstId,this.batchOption=t.batch,this.stopReceiving=e.onMessage(r=>this.receive(r))}transport;stateValue="waiting";nextId;pending=new Map;listeners=new Map;callbacks=new Map;readyWaiters=[];clientListeners=new Set;uncaughtListeners=new Set;timeoutMs;stopReceiving;clientVersion=null;featureList=[];firstId;batchOption;queue=[];batches=new Map;subscriptions=new Map;ticks=new Map;get state(){return this.stateValue}get client(){return this.clientVersion}get features(){return this.featureList}allocate(){return this.nextId++}whenReady(){return this.stateValue==="ready"?Promise.resolve():this.stateValue==="closed"?Promise.reject(new L("CLOSED","The game is closed")):new Promise((e,t)=>this.readyWaiters.push({resolve:e,reject:t}))}definition(e){return new J(this,{kind:"definition",name:e})}gameClient(){return new J(this,{kind:"client"})}stage(){return new J(this,{kind:"stage"})}construct(e,...t){return this.request({op:"construct",className:e,args:t.map(r=>this.encode(r))})}onClient(e){return this.clientListeners.add(e),()=>this.clientListeners.delete(e)}onUncaught(e){return this.uncaughtListeners.add(e),()=>this.uncaughtListeners.delete(e)}async listen(e,t,r){const a=this.nextId++;this.listeners.set(a,r);try{await this.request({op:"listen",target:e.target,path:[...e.path],event:t,listener:a})}catch(i){throw this.listeners.delete(a),i}return async()=>{!this.listeners.delete(a)||this.stateValue==="closed"||await this.request({op:"unlisten",listener:a})}}async subscribe(e,t,r){const a=this.nextId++;this.subscriptions.set(a,r);try{await this.request(e(a))}catch(i){throw this.subscriptions.delete(a),i}return async()=>{!this.subscriptions.delete(a)||this.stateValue==="closed"||await this.request(t(a))}}onSubscription(e,t){return this.subscriptions.set(e,t),()=>{this.subscriptions.get(e)===t&&this.subscriptions.delete(e)}}async hookTable(e){return await this.request(e===void 0?{op:"hookTable"}:{op:"hookTable",url:e})}async hook(e,t,r){let a=0;const i=await this.subscribe(s=>(a=s,{op:"hook",registration:s,hook:e,rules:t}),s=>({op:"unhook",registration:s}),r);return{registration:a,stop:i}}watch(e,t,r){return this.subscribe(a=>({op:"watch",watch:a,entries:e.map(i=>({target:i.target,path:[...i.path]})),everyFrames:Math.max(1,Math.floor(t.everyFrames??1)),handles:t.handles??!1}),a=>({op:"unwatch",watch:a}),a=>{a.kind==="watch"&&r(a.values.map(i=>this.decode(i)),a.errors??null)})}async tick(e,t){const r=Math.max(1,Math.floor(e));let a=this.ticks.get(r);if(!a){const o=new Set,l=this.subscribe(c=>({op:"tick",tick:c,everyFrames:r}),c=>({op:"untick",tick:c}),c=>{if(c.kind==="tick")for(const h of[...o])h(c.frame,c.time)});a={listeners:o,started:l},this.ticks.set(r,a),l.catch(()=>{this.ticks.get(r)===a&&this.ticks.delete(r)})}const i=a;i.listeners.add(t);try{await i.started}catch(o){throw i.listeners.delete(t),o}let s=!1;return async()=>{s||(s=!0,i.listeners.delete(t),!(i.listeners.size>0||this.ticks.get(r)!==i)&&(this.ticks.delete(r),await(await i.started)()))}}highlight(e,t){return this.subscribe(r=>({op:"highlight",highlight:r,target:e.target,path:[...e.path],effect:t}),r=>({op:"unhighlight",highlight:r}),()=>{})}style(e,t){return this.subscribe(r=>({op:"style",style:r,target:e.target,path:[...e.path],format:t}),r=>({op:"unstyle",style:r}),()=>{})}invokeOriginal(e,t,r){return this.request({op:"invokeOriginal",registration:e,token:t,arguments:r===null?null:r.map(a=>this.encode(a))})}async overrideDone(e,t){this.stateValue!=="closed"&&await this.request({op:"overrideDone",registration:e,token:t})}onKey(e,t){return this.subscribe(r=>({op:"key",key:r,spec:e}),r=>({op:"unkey",key:r}),r=>{r.kind==="key"&&t(r)})}async draw(e,t){await this.request({op:"draw",node:e,spec:t})}async erase(e){if(!(e.length===0||this.stateValue==="closed")){for(const t of e)this.subscriptions.delete(t);await this.request({op:"erase",nodes:[...e]})}}drive(e,t){return this.subscribe(r=>({op:"drive",drive:r,spec:e}),r=>({op:"undrive",drive:r}),r=>{r.kind==="drive-failed"&&(t==null||t(r.error))})}async collect(e,t){const a=await this.request({op:"collect",target:e.target,path:[...e.path],spec:t});return{items:Array.isArray(a==null?void 0:a.items)?a.items:[],total:typeof(a==null?void 0:a.total)=="number"?a.total:0}}track(e,t,{mode:r="displayList",everyFrames:a=15}={},i){return this.subscribe(s=>({op:"track",track:s,target:e.target,path:[...e.path],className:t,mode:r,everyFrames:a}),s=>({op:"untrack",track:s}),s=>{s.kind==="track"&&i({added:s.added.map(o=>this.decode(o)),removed:s.removed.map(o=>this.decode(o))})})}async snapshot(e,{scale:t=1,background:r=null,maxSize:a=0}={}){const i=await this.request({op:"snapshot",target:e.target,path:[...e.path],scale:t,background:r,maxSize:a});if(typeof i!="string")throw new L("FLASH","The picture came back empty");return i}note(e,t,r,a){if(t==="keys"||t==="clear")return this.request({op:"note",table:e,verb:t});if(!r)throw new TypeError(`A note to ${t} is kept beside an object; name the place`);const i={target:r.target,path:[...r.path]};return t==="write"?this.request({op:"note",table:e,verb:t,...i,value:this.encode(a)}):this.request({op:"note",table:e,verb:t,...i})}async find(e,t){const r=await this.request({op:"find",target:e.target,path:[...e.path],spec:t});return(Array.isArray(r)?r:[]).filter(a=>a instanceof _)}async answer(e,t){this.stateValue!=="closed"&&await this.request({op:"answer",callback:e,...t===void 0?{}:{value:this.encode(t)}})}async release(e){e.length===0||this.stateValue==="closed"||await this.request({op:"release",handles:e.map(t=>t.handle)})}close(){if(this.stateValue==="closed")return;if(this.stateValue==="ready"&&this.featureList.includes("dispose")){const t=this.nextId++;try{this.transport.send(te({id:t,op:"dispose",from:this.firstId,to:this.nextId}))}catch{}}this.stateValue="closed",this.stopReceiving();const e=new L("CLOSED","The game was closed");for(const t of this.pending.values())clearTimeout(t.timer),t.reject(e);this.pending.clear();for(const t of this.batches.values())clearTimeout(t.timer);this.batches.clear(),this.queue=[],this.listeners.clear(),this.callbacks.clear(),this.subscriptions.clear(),this.ticks.clear(),this.readyWaiters.splice(0).forEach(t=>t.reject(e))}readyWithin(e){return new Promise((t,r)=>{const a=setTimeout(()=>r(new L("NOT_READY","The game has not started yet")),e);this.whenReady().then(()=>{clearTimeout(a),t()},i=>{clearTimeout(a),r(i)})})}encodeRequest(e){return te({...e,id:this.nextId++})}request(e){if(this.stateValue==="closed")return Promise.reject(new L("CLOSED","The game is closed"));if(this.stateValue!=="ready")return this.readyWithin(this.timeoutMs).then(()=>this.request(e));const t=this.nextId++;return new Promise((r,a)=>{const i=setTimeout(()=>{this.pending.delete(t),a(new L("TIMEOUT",`The game did not answer "${e.op}" in ${this.timeoutMs}ms`))},this.timeoutMs);this.pending.set(t,{resolve:r,reject:a,timer:i});const s={...e,id:t};if(!this.batching||s.op==="hookTable"||s.op==="batch"){this.transport.send(te(s));return}this.queue.push(s),this.queue.length===1&&queueMicrotask(()=>this.flush())})}get batching(){return this.batchOption??this.featureList.includes("batch")}flush(){const e=this.queue;if(this.queue=[],e.length===0||this.stateValue!=="ready")return;if(e.length===1){this.transport.send(te(e[0]));return}const t=this.nextId++,r=e.map(i=>i.id),a=setTimeout(()=>this.batches.delete(t),this.timeoutMs+1e3);this.batches.set(t,{ids:r,timer:a}),this.transport.send(te({id:t,op:"batch",requests:e}))}settle(e,t){const r=this.pending.get(e);r&&(this.pending.delete(e),clearTimeout(r.timer),t.ok?r.resolve(this.decode(t.value)):r.reject(new L("FLASH",t.error.message,t.error)))}encode(e){if(e===void 0)return{$undefined:!0};if(e===null||typeof e!="object"){if(typeof e=="function"){const t=this.nextId++;return this.callbacks.set(t,e),{$callback:t}}return e}return e instanceof _?{$handle:e.handle}:e instanceof ke?{$new:e.className,args:e.args.map(t=>this.encode(t))}:Array.isArray(e)?e.map(t=>this.encode(t)):Object.fromEntries(Object.entries(e).map(([t,r])=>[t,this.encode(r)]))}decode(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(t=>this.decode(t));if(bn(e))return new _(this,e.$handle,e.className);if(!("$undefined"in e))return Object.fromEntries(Object.entries(e).map(([t,r])=>[t,this.decode(r)]))}receive(e){var t,r,a;if(this.stateValue==="closed")return;let i;try{i=Nt(e)}catch{return}switch(i.kind){case"ready":if(i.version!==at){const s=new L("VERSION",`The loader speaks bridge ${i.version}; this Phantom speaks ${at}`);this.readyWaiters.splice(0).forEach(o=>o.reject(s)),this.close();return}this.stateValue="ready",this.clientVersion=i.client,this.featureList=Array.isArray(i.features)?[...i.features]:[],this.readyWaiters.splice(0).forEach(s=>s.resolve());return;case"client-loaded":this.clientListeners.forEach(s=>s(!0,null));return;case"client-failed":this.clientListeners.forEach(s=>s(!1,i.message));return;case"result":{const s=this.batches.get(i.id);if(s){this.batches.delete(i.id),clearTimeout(s.timer);const o=i.ok&&Array.isArray(i.value)?i.value:null;s.ids.forEach((l,c)=>{i.ok?o&&c<o.length&&this.settle(l,o[c]):this.settle(l,i)});return}this.settle(i.id,i.ok?{ok:!0,value:i.value}:i);return}case"event":(t=this.listeners.get(i.listener))==null||t(this.decode(i.event));return;case"callback":(r=this.callbacks.get(i.callback))==null||r(...i.args.map(s=>this.decode(s)));return;case"uncaught":{const s=new L("FLASH",i.error.message,i.error);this.uncaughtListeners.forEach(o=>o(s));return}default:if(kn.has(i.kind)){const s=vn(i);s!==null&&((a=this.subscriptions.get(s))==null||a(i))}}}}const Tn=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],_t={r:.3086,g:.6094,b:.082};function fe(n,e){const t=new Array(20).fill(0);for(let r=0;r<4;r++)for(let a=0;a<5;a++){let i=a===4?e[r*5+4]:0;for(let s=0;s<4;s++)i+=e[r*5+s]*n[s*5+a];t[r*5+a]=i}return t}function jt(n){const e=n,{r:t,g:r,b:a}=_t;return[t*(1-e)+e,r*(1-e),a*(1-e),0,0,t*(1-e),r*(1-e)+e,a*(1-e),0,0,t*(1-e),r*(1-e),a*(1-e)+e,0,0,0,0,0,1,0]}function On(n){const e=n*255;return[1,0,0,0,e,0,1,0,0,e,0,0,1,0,e,0,0,0,1,0]}function Mn(n){const e=n+1,t=128*(1-e);return[e,0,0,0,t,0,e,0,0,t,0,0,e,0,t,0,0,0,1,0]}function En(n){const e=n*Math.PI/180,t=Math.cos(e),r=Math.sin(e),{r:a,g:i,b:s}=_t;return[a+t*(1-a)+r*-a,i+t*-i+r*-i,s+t*-s+r*(1-s),0,0,a+t*-a+r*.143,i+t*(1-i)+r*.14,s+t*-s+r*-.283,0,0,a+t*-a+r*-.6914,i+t*-i+r*i,s+t*(1-s)+r*s,0,0,0,0,0,1,0]}const Sn={grayscale:jt(0),sepia:[.393,.769,.189,0,0,.349,.686,.168,0,0,.272,.534,.131,0,0,0,0,0,1,0],invert:[-1,0,0,0,255,0,-1,0,0,255,0,0,-1,0,255,0,0,0,1,0],night:[.45,0,0,0,0,0,.5,0,0,0,0,0,.8,0,20,0,0,0,1,0]};function zt(n){if(typeof n=="string"){const t=Sn[n];if(!t)throw new TypeError(`Unknown colour look "${String(n)}"`);return{matrix:[...t],colorTransform:null}}if("matrix"in n){if(n.matrix.length!==20)throw new TypeError("A colour matrix has twenty numbers");return{matrix:[...n.matrix],colorTransform:null}}if("tint"in n){const t=Math.max(0,Math.min(1,n.amount??.5)),r=a=>(n.tint>>a&255)*t;return{matrix:null,colorTransform:it({redMultiplier:1-t,greenMultiplier:1-t,blueMultiplier:1-t,redOffset:r(16),greenOffset:r(8),blueOffset:r(0)})}}if("transform"in n)return{matrix:null,colorTransform:it(n.transform)};let e=[...Tn];return n.saturation!==void 0&&(e=fe(e,jt(n.saturation))),n.hue!==void 0&&(e=fe(e,En(n.hue))),n.contrast!==void 0&&(e=fe(e,Mn(n.contrast))),n.brightness!==void 0&&(e=fe(e,On(n.brightness))),{matrix:e,colorTransform:null}}function it(n){return{redMultiplier:n.redMultiplier??1,greenMultiplier:n.greenMultiplier??1,blueMultiplier:n.blueMultiplier??1,alphaMultiplier:n.alphaMultiplier??1,redOffset:n.redOffset??0,greenOffset:n.greenOffset??0,blueOffset:n.blueOffset??0,alphaOffset:n.alphaOffset??0}}function ce(n={}){const e=n.recolor?zt(n.recolor):{matrix:null,colorTransform:null},r=n.glow??!(n.recolor||n.hide)?{color:n.color??9133302,alpha:n.alpha??1,blur:n.blur??8,strength:n.strength??2,inner:n.inner??!1,knockout:n.knockout??!1}:null;if(r&&e.matrix)throw new TypeError("A highlight is a glow or a colour matrix, not both: use two highlights");const a=n.pulse===void 0||n.pulse===!1?null:n.pulse===!0?{frames:60,from:.6,to:1}:{frames:n.pulse.frames??60,from:n.pulse.from??.6,to:n.pulse.to??1};return{glow:r,matrix:e.matrix,colorTransform:e.colorTransform,hide:n.hide??!1,pulse:a}}const xe=Symbol.for("phantom.typedFlash");function Ht(n){return typeof n=="function"&&n[xe]!==void 0}function C(n,e,t={}){const r={reference:e,handle:t.handle??null,className:t.className??null},a=o=>P(n,o),i={$get:()=>e.get().then(a),$set:async o=>e.set((await Q(n,[o]))[0]),$listen:(o,l)=>e.listen(o,c=>l(a(c))),$describe:()=>e.describe(),$at:(...o)=>C(n,e.at(...o)),$as:()=>C(n,e,{...r.handle?{handle:r.handle}:{}}),$release:()=>r.handle?r.handle.release():Promise.resolve(),$reference:e,$new:async(...o)=>{if(!r.className)throw new TypeError("Only a class can make objects with $new");return a(await n.construct(r.className,...await Q(n,o)))},toJSON:()=>`[Flash ${An(r)}]`},s=(()=>{});return new Proxy(s,{get:(o,l)=>{if(l===xe)return r;if(typeof l!="symbol"&&l!=="then")return Object.prototype.hasOwnProperty.call(i,l)?i[l]:C(n,e.at(l))},apply:async(o,l,c)=>a(await e.call(...await Q(n,c)))})}function ne(n){return Ht(n)?n[xe].reference:n instanceof _?n.at():n&&typeof n=="object"&&"target"in n&&"path"in n&&typeof n.at=="function"?n:null}function P(n,e){if(e instanceof _)return C(n,e.at(),{handle:e});if(Array.isArray(e))return e.map(t=>P(n,t));if(e&&typeof e=="object"){const t={};for(const[r,a]of Object.entries(e))t[r]=P(n,a);return t}return e}async function Q(n,e){return Promise.all(e.map(t=>qe(n,t)))}async function qe(n,e){if(Ht(e)){const t=e[xe];return t.handle&&t.reference.path.length===0?t.handle:t.reference.get()}if(typeof e=="function"){const t=e;return(...r)=>t(...r.map(a=>P(n,a)))}if(Array.isArray(e))return Promise.all(e.map(t=>qe(n,t)));if(e&&typeof e=="object"&&Object.getPrototypeOf(e)===Object.prototype){const t={};for(const[r,a]of Object.entries(e))t[r]=await qe(n,a);return t}return e}function An({reference:n,className:e}){const t=n.target,r=t.kind==="definition"?t.name:t.kind==="handle"?`object ${t.handle}`:t.kind,a=n.path.join(".");return e??(a?`${r}.${a}`:r)}class Pn{constructor(e,t,r){this.bridge=e;const a=e.encode(t);this.callback=a.$callback,r!==void 0&&this.answers(r)}bridge;callback;stopped=!1;get argument(){return{$callback:this.callback}}async answers(e){if(this.stopped)return;await this.ready();const[t]=await Q(this.bridge,[e]);await this.bridge.answer(this.callback,t)}async answersNothing(){this.stopped||(await this.ready(),await this.bridge.answer(this.callback))}async stop(){this.stopped||(this.stopped=!0,await this.bridge.answer(this.callback))}async ready(){if(await this.bridge.whenReady(),!this.bridge.features.includes("answer"))throw new Error("This game is running a loader from before answers; a function of yours gives the game nothing back")}}function E(n){const e=ne(n);if(!e)throw new TypeError("Expected a place in Flash: a typed place, an object read from Flash, or a reference");return{target:e.target,path:[...e.path]}}function st(n){return ne(n)!==null}async function Rn(n,e,t,r){if(await n.whenReady(),!n.features.includes("collect"))throw new Error("This game is running a loader from before collects; read the items one by one");const a={fields:Cn(t)};r.skip!==void 0&&(a.skip=Math.max(0,Math.trunc(r.skip))),r.limit!==void 0&&(a.limit=Math.max(1,Math.trunc(r.limit))),r.handles!==void 0&&(a.handles=r.handles);const i=await n.collect(E(e),a);return{rows:i.items.map(s=>P(n,s)),total:i.total}}function Cn(n){const e=Array.isArray(n)?n.map(t=>[t,t]):Object.entries(n);if(e.length===0)throw new TypeError("A collect needs the members to read");return e.map(([t,r])=>({name:t,path:(Array.isArray(r)?r:String(r).split(".")).filter(a=>a.length>0)}))}function he(n){const e=`${n.className}.${n.member}`;return n.kind==="getter"?`${e}@get`:n.kind==="setter"?`${e}@set`:e}const Te=Symbol.for("phantom.hookRead"),Z=Symbol.for("phantom.hookTest");class $n{constructor(e){this.table=e;for(const t of e.hooks){this.byId.set(t.id,t);const r=he(t);this.byKey.has(r)||this.byKey.set(r,t)}}table;byKey=new Map;byId=new Map;get size(){return this.byId.size}names(){return[...this.byKey.keys()]}find(e){return e.startsWith("#")?this.byId.get(Number(e.slice(1)))??null:this.byKey.get(e)??this.byKey.get(`${e}@get`)??this.byKey.get(`${e}@set`)??null}}function X(n){return n.flatMap(e=>Array.isArray(e)?e:e.includes("::")?[e]:e.split(".").filter(Boolean))}function G(n){return Object.freeze({[Te]:n})}function j(n,e,t){return Object.freeze({[Z]:t===void 0&&n==="exists"?{test:n,left:e}:{test:n,left:e,right:t}})}const Fn={self:(...n)=>G({from:"self",path:X(n)}),arg:(n,...e)=>G({from:"arg",arg:n,path:X(e)}),returned:(...n)=>G({from:"return",path:X(n)}),fromClass:(n,...e)=>G({from:"class",name:n,path:X(e)}),place:(n,...e)=>G({from:"place",place:n,path:X(e)}),calls:()=>G({from:"calls"}),constant:n=>G({from:"constant",value:n}),equals:(n,e)=>j("equals",n,e),notEquals:(n,e)=>j("notEquals",n,e),less:(n,e)=>j("less",n,e),lessOrEqual:(n,e)=>j("lessOrEqual",n,e),greater:(n,e)=>j("greater",n,e),greaterOrEqual:(n,e)=>j("greaterOrEqual",n,e),contains:(n,e)=>j("contains",n,e),startsWith:(n,e)=>j("startsWith",n,e),endsWith:(n,e)=>j("endsWith",n,e),oneOf:(n,e)=>j("in",n,e),exists:n=>j("exists",n),all:(...n)=>Object.freeze({[Z]:{all:n}}),any:(...n)=>Object.freeze({[Z]:{any:n}}),not:n=>Object.freeze({[Z]:{not:n}})};function Dt(n){return typeof n=="object"&&n!==null&&Te in n}function Bt(n){return typeof n=="object"&&n!==null&&Z in n}function Ue(n,e,t,r){const a=u=>{if(typeof u=="number")return ot(e,u);const d=e.parameters.findIndex(w=>w.name===u);if(d>=0)return d;if(/^\d+$/.test(u))return ot(e,Number(u));const g=e.parameters.map(w=>w.name).join(", ")||"none";throw new TypeError(`${he(e)} has no argument "${u}" (its arguments: ${g})`)},i=u=>{if(!Dt(u))return ve(u)??{from:"constant",value:re(n,u)};const d=u[Te];switch(d.from){case"constant":return{from:"constant",value:re(n,d.value)};case"arg":return{from:"arg",index:a(d.arg),path:d.path};case"self":return{from:"self",path:d.path};case"return":return{from:"return",path:d.path};case"class":return{from:"class",name:d.name,path:d.path};case"calls":return{from:"calls"};case"place":{const g=ve(d.place,d.path);if(!g)throw new TypeError("rules.place takes a place in the game");return g}}},s=u=>{if(!Bt(u)){const g=Object.entries(u).map(([w,f])=>({test:"equals",left:{from:"arg",index:a(w),path:[]},right:i(f)}));if(g.length===0)throw new TypeError("A hook condition names nothing to compare");return g.length===1?g[0]:{all:g}}const d=u[Z];return"all"in d?{all:d.all.map(s)}:"any"in d?{any:d.any.map(s)}:"not"in d?{not:s(d.not)}:d.test==="exists"?{test:d.test,left:i(d.left)}:{test:d.test,left:i(d.left),right:i(d.right)}},o=t.phase??(r?"enter":"none"),l=t.capture??{},c=e.parameters.map((u,d)=>d),h=l.args===!0||l.args===void 0&&r?c:(l.args??[]).map(a);return{observe:o==="both"?["enter","exit"]:o==="none"?[]:[o],capture:{args:h,self:Ve(l.self).map(([,u])=>u),value:l.value??!1,handles:l.handles??!1},when:t.when===void 0?null:s(t.when),first:t.first??null,every:t.every??null,skip:t.skip===void 0||t.skip===!1?null:t.skip===!0?{from:"constant",value:{$undefined:!0}}:i(t.skip.returns),replaceArgs:Object.entries(t.replaceArgs??{}).map(([u,d])=>({index:a(u),value:i(d)})),replaceReturn:"replaceReturn"in t?i(t.replaceReturn):null,perFrame:t.perFrame??20}}function ot(n,e){if(!Number.isInteger(e)||e<0||n.parameters.length>0&&e>=n.parameters.length)throw new RangeError(`${he(n)} has no argument ${e}`);return e}function Ve(n){return n?Array.isArray(n)?n.map(e=>[e,X([e])]):Object.entries(n).map(([e,t])=>[e,X([t])]):[]}function Wt(n,e){const t=r=>{if(!Bt(r))throw new TypeError("A condition between calls has no call to read: compare with rules.equals and its like");const a=r[Z];return"all"in a?{all:a.all.map(t)}:"any"in a?{any:a.any.map(t)}:"not"in a?{not:t(a.not)}:a.test==="exists"?{test:a.test,left:oe(n,a.left)}:{test:a.test,left:oe(n,a.left),right:oe(n,a.right)}};return t(e)}function ve(n,e=[]){const t=ne(n);return t?{from:"place",target:t.target,path:[...t.path,...e]}:null}function oe(n,e){if(!Dt(e))return ve(e)??{from:"constant",value:re(n,e)};const t=e[Te];switch(t.from){case"constant":return{from:"constant",value:re(n,t.value)};case"class":return{from:"class",name:t.name,path:t.path};case"place":{const r=ve(t.place,t.path);if(!r)throw new TypeError("rules.place takes a place in the game");return r}default:throw new TypeError(`rules.${t.from} reads the call it is in; a value held between calls is a constant, rules.fromClass or a place`)}}function re(n,e){if(e===void 0)return{$undefined:!0};if(e instanceof _||e instanceof ke)return n.encode(e);const t=ne(e);if(t){if(t.target.kind==="handle"&&t.path.length===0)return{$handle:t.target.handle};throw new TypeError("A place inside a list or object in a rule cannot be read there: pass the place on its own, or read it first")}if(typeof e=="function")throw new TypeError("A hook rule cannot call a function");return Array.isArray(e)?e.map(r=>re(n,r)):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,a])=>[r,re(n,a)])):e}async function In(n,e,t,r,a){var i;const s=e.find(t);if(!s)throw new TypeError(`There is no hook "${t}" in the hook table`);let o=r,l=Ve((i=r.capture)==null?void 0:i.self).map(([g])=>g),c=Ue(n,s,r,a!==void 0);const{registration:h,stop:u}=await n.hook(s.id,c,g=>{var w;switch(g.kind){case"hook":{if(!a)return;const f=(g.args??[]).map(y=>P(n,n.decode(y))),p={};c.capture.args.forEach((y,v)=>{var T;p[((T=s.parameters[y])==null?void 0:T.name)??String(y)]=f[v]});const m={};(g.self??[]).forEach((y,v)=>{m[l[v]??String(v)]=P(n,n.decode(y))}),a({phase:g.phase,call:g.call,args:p,argList:f,self:m,..."value"in g?{value:P(n,n.decode(g.value))}:{},skipped:g.skipped===!0,hook:s});return}case"hook-dropped":(w=o.onDropped)==null||w.call(o,g.dropped);return;case"hook-failed":{const f=new L("FLASH",`The hook on ${he(s)} failed and is off: ${g.error.message}`,g.error);o.onError?o.onError(f):console.error(f.message);return}}});return Object.assign(()=>u(),{registration:h,hook:s,update:async(g,w={})=>{var f;const p=Ue(n,s,g,a!==void 0);await n.request({op:"rehook",registration:h,rules:p,resetCounts:w.resetCounts??!1}),o=g,c=p,l=Ve((f=g.capture)==null?void 0:f.self).map(([m])=>m)},stats:async()=>(await n.request({op:"hookStats"})).find(w=>w.registration===h)??null})}async function Ln(n,e,t){if(await n.whenReady(),!n.features.includes("drive"))throw new Error("This game is running a loader from before repeated calls; call it yourself each frame");const r=E(e);if(r.path.length===0)throw new TypeError("A repeat calls a method, so name one: `place.method`, not the object");const a=t.while?Wt(n,t.while):null;return n.drive({writes:[],calls:[{target:r.target,path:r.path,args:(t.args??[]).map(i=>oe(n,i)),times:Math.max(1,Math.trunc(t.times??1))}],everyFrames:Math.max(1,Math.trunc(t.everyFrames??1)),while:a,restore:!1,once:t.once===!0},t.onFailed)}async function lt(n,e,t){if(await n.whenReady(),!n.features.includes("drive"))throw new Error("This game is running a loader from before held values; write it yourself each frame");if(e.length===0)throw new TypeError("A hold needs a value to keep");const r=e.map(({place:i,value:s})=>{const o=E(i);if(o.path.length===0)throw new TypeError("A hold writes to a member, so name one: `place.member`, not the object");return{target:o.target,path:o.path,value:oe(n,s)}}),a=t.while?Wt(n,t.while):null;return n.drive({writes:r,everyFrames:Math.max(1,Math.trunc(t.everyFrames??1)),while:a,restore:t.restore!==!1,once:t.once===!0},t.onFailed)}class Ae{constructor(e,t,r,a,i,s,o){this.host=e,this.kind=t,this.id=r,this.name=a,this.tagY=s,this.handle=o,this.place=i}host;kind;id;name;tagY;handle;place;highlight(e={}){return this.host.bridge.highlight(this.entry(),ce(e))}tag(e,t={}){const{anchorX:r,anchorY:a,...i}=t;return this.host.overlay.text(e,{centered:!0,font:{size:12,bold:!0,color:16777215},outline:0,...i,anchor:{place:this.place,x:r??0,y:a??this.tagY}})}onClick(e){const t=this.host.bridge;return this.kind!=="object"?this.place.$listen("mouseDown",()=>e(this)):t.stage().listen("mouseDown",r=>{const{stageX:a,stageY:i}=r??{};typeof a!="number"||typeof i!="number"||this.place.$reference.at("hitTestPoint").call(a,i,!0).then(s=>{s===!0&&e(this)}).catch(()=>{})})}async release(){this.handle&&await this.handle.release()}entry(){const e=this.place.$reference;return{target:e.target,path:[...e.path]}}}class Nn{constructor(e){this.host=e}host;async players(){const e=this.host.bridge,t=e.definition("avatar.AvatarManager").at("avatarViewList"),r=await t.get(),a=r&&typeof r=="object"&&!(r instanceof _)?Object.keys(r):[],i=a.map(s=>r[s]).filter(s=>s instanceof _);try{const s=await Promise.all(a.map(o=>q(t.at(o,"userName").get())));return a.map((o,l)=>new Ae(this.host,"player",o,typeof s[l]=="string"?s[l]:null,C(e,t.at(o)),-80,null))}finally{await e.release(i)}}async npcs(){const e=this.host.bridge,t=e.definition("quest.QuestManager").at("_questActors"),r=await q(t.at("length").get());if(typeof r!="number"||r<=0)return[];const a=Array.from({length:Math.min(r,500)},(c,h)=>String(h)),[i,s,o]=await Promise.all([Promise.all(a.map(c=>q(t.at(c).get()))),Promise.all(a.map(c=>q(t.at(c,"_actorId").get()))),Promise.all(a.map(c=>q(t.at(c,"currAvatar","avName").get())))]),l=[];return a.forEach((c,h)=>{const u=i[h];if(!(u instanceof _))return;const d=o[h];l.push(new Ae(this.host,"npc",typeof s[h]=="string"?s[h]:c,typeof d=="string"&&d?d:null,C(e,u.at(),{handle:u}),-90,u))}),l}async objects(){const e=this.host.bridge,t=e.definition("room.RoomManagerWorld").at("instance","volumeManager","_volumeActors");let r;try{r=await t.at("length").get()}catch(h){throw h instanceof L&&h.code==="FLASH"?new L("FLASH",`The room's objects are private to the client, and this client does not reach them: ${h.message}`,h.flash):h}if(typeof r!="number"||r<=0)return[];const a=Array.from({length:Math.min(r,500)},(h,u)=>String(u)),[i,s]=await Promise.all([Promise.all(a.map(h=>q(t.at(h,"name").get()))),Promise.all(a.map(h=>q(t.at(h,"interactiveObjs","length").get())))]),o=[];a.forEach((h,u)=>{const d=s[u],g=i[u];for(let w=0;typeof d=="number"&&w<Math.min(d,50);w++)o.push([h,String(w),typeof g=="string"?g:null])});const l=await Promise.all(o.map(([h,u])=>q(t.at(h,"interactiveObjs",u,"mc").get()))),c=[];return o.forEach(([h,u,d],g)=>{const w=l[g];w instanceof _&&c.push(new Ae(this.host,"object",`${d??h}#${u}`,d,C(e,w.at(),{handle:w}),0,w))}),c}}function q(n){return n.catch(()=>null)}async function _n(n,e,t){if(await n.whenReady(),!n.features.includes("find"))throw new Error("This game is running a loader from before searches; only a path reaches an object");const r=e===void 0?{target:{kind:"stage"},path:[]}:E(e);return(await n.find(r,jn(t))).map(i=>C(n,i.at(),{handle:i}))}function jn(n){const e={};return n.ofClass!==void 0&&(e.ofClass=n.ofClass),n.named!==void 0&&(e.named=n.named),n.containing!==void 0&&(e.containing=n.containing),n.visibleOnly!==void 0&&(e.visibleOnly=n.visibleOnly),n.through!==void 0&&(e.through=n.through),n.depth!==void 0&&(e.depth=n.depth),n.limit!==void 0&&(e.limit=n.limit),e}const ct={backspace:8,tab:9,enter:13,return:13,shift:16,control:17,ctrl:17,alt:18,pause:19,capslock:20,escape:27,esc:27,space:32,pageup:33,pagedown:34,end:35,home:36,left:37,arrowleft:37,up:38,arrowup:38,right:39,arrowright:39,down:40,arrowdown:40,insert:45,delete:46,";":186,"=":187,",":188,"-":189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222};function zn(n){return n===!0?"always":n===!1?"never":n??"empty"}function Hn(n,e={}){const t={phase:e.phase??"down",consume:e.consume??!1,whileTyping:zn(e.whileTyping),repeat:e.repeat??!1};if(typeof n=="number")return{code:n,ctrl:null,shift:null,alt:null,...t};const r=n==="+"||n.endsWith("++"),a=(r?n.slice(0,-1):n).split("+").map(o=>o.trim()).filter(Boolean);r&&a.push("+");const i={ctrl:!1,shift:!1,alt:!1};let s=null;for(const o of a){const l=o.toLowerCase();l==="ctrl"||l==="control"||l==="cmd"||l==="meta"?i.ctrl=!0:l==="shift"?i.shift=!0:l==="alt"||l==="option"?i.alt=!0:l==="any"?s=null:s=Dn(o)}if(s===null&&!a.some(o=>o.toLowerCase()==="any"))throw new TypeError(`"${n}" names no key`);return{code:s,...i,...t}}function Dn(n){const e=n.toLowerCase();if(e in ct)return ct[e];if(/^[a-z0-9]$/i.test(n))return n.toUpperCase().charCodeAt(0);const t=/^f([1-9]|1[0-5])$/i.exec(n);if(t)return 111+Number(t[1]);const r=/^num(?:pad)?([0-9])$/i.exec(n);if(r)return 96+Number(r[1]);if(n==="+")return 187;throw new TypeError(`Unknown key "${n}"`)}class Bn{constructor(e){this.bridge=e}bridge;table=null;async set(e,t){const[r]=await Q(this.bridge,[t]);await this.bridge.note(await this.number(),"write",E(e),r)}async get(e){const t=await this.bridge.note(await this.number(),"read",E(e));return t==null?void 0:P(this.bridge,t)}async has(e){return await this.bridge.note(await this.number(),"has",E(e))===!0}async forget(e){return await this.bridge.note(await this.number(),"forget",E(e))===!0}async objects(){const e=await this.bridge.note(await this.number(),"keys");return Array.isArray(e)?e.filter(t=>t instanceof _).map(t=>C(this.bridge,t.at(),{handle:t})):[]}async clear(){this.table!==null&&await this.bridge.note(this.table,"clear")}async number(){if(await this.bridge.whenReady(),!this.bridge.features.includes("notes"))throw new Error("This game is running a loader from before notes; nothing can be kept beside its objects");return this.table??=this.bridge.allocate(),this.table}}const Wn=127;function qt(n){const e=[],t=[];let r="",a=0;const i=()=>{const o={};for(const l of t)Object.assign(o,l.look);return o},s=()=>{if(r==="")return;const o={text:r,...i()},l=e[e.length-1];l&&Kn(l,o)?l.text+=r:e.push(o),r=""};for(;a<n.length;){const o=n[a];if(o!=="["){r+=o,a++;continue}if(n[a+1]==="["){r+="[",a+=2;continue}const l=n.indexOf("]",a+1),c=l<0?null:qn(n.slice(a+1,l));if(c===null){r+=o,a++;continue}if(c.closing){const h=Yn(t,c.name);h<0?r+=n.slice(a,l+1):(s(),t.splice(h))}else s(),t.push({tag:c.name,look:c.look});a=l+1}return s(),e}function qn(n){if(n.startsWith("/")){const a=n.slice(1);return Un.has(a)?{name:a,closing:!0}:null}const e=n.indexOf("="),t=e<0?n:n.slice(0,e),r=e<0?null:n.slice(e+1);switch(t){case"b":return r===null?{name:t,closing:!1,look:{bold:!0}}:null;case"i":return r===null?{name:t,closing:!1,look:{italic:!0}}:null;case"u":return r===null?{name:t,closing:!1,look:{underline:!0}}:null;case"color":{const a=r===null?null:Gn(r);return a===null?null:{name:t,closing:!1,look:{color:a}}}case"size":{const a=r===null?NaN:Number(r);return Number.isInteger(a)&&a>=1&&a<=Wn?{name:t,closing:!1,look:{size:a}}:null}case"link":return r===null||r===""?null:{name:t,closing:!1,look:{link:r}};default:return null}}const Un=new Set(["b","i","u","color","size","link"]),Vn="0123456789abcdef";function Gn(n){const e=n.toLowerCase(),t=e.startsWith("#")?e.slice(1):e.startsWith("0x")?e.slice(2):null;if(t===null||t.length!==6)return null;let r=0;for(const a of t){const i=Vn.indexOf(a);if(i<0)return null;r=r*16+i}return r}function Yn(n,e){for(let t=n.length-1;t>=0;t--)if(n[t].tag===e)return t;return-1}function Kn(n,e){return["color","bold","italic","underline","size","font","link"].every(r=>n[r]===e[r])}const Pe={className:"avatar.AvatarManager",path:["playerAvatarWorldView","parent"]},ht=new Set(["click","down","up","over","out"]);class Xn{constructor(e){this.bridge=e}bridge;nodes=new Map;async draw(e,t={}){const{handle:r}=await this.make(e,t);return r}world(e={x:0,y:0},t={}){return{place:this.bridge.definition(Pe.className).at(Pe.path[0],Pe.path[1]),x:e.x,y:e.y,...t}}marker(e,t={}){const{kind:r="circle",...a}=t;return this.draw(r,{radius:8,...a,anchor:this.world(e)})}group(e={}){return this.draw("group",e)}text(e,t={}){return this.draw("text",{...t,text:e})}rich(e,t={}){return this.draw("text",{...t,rich:e})}rect(e){return this.draw("rect",e)}circle(e){return this.draw("circle",e)}line(e){return this.draw("line",e)}image(e,t={}){return this.draw("image",{...t,url:e})}async input(e={}){const{handle:t,state:r}=await this.make("input",{width:200,height:24,fill:16777215,stroke:10265519,padding:4,...e,font:{color:1120295,...e.font}});return r.value=e.value??"",Object.assign(t,{value:()=>r.value,setValue:async i=>{r.value=i,r.removed||await this.bridge.draw(t.node,{value:i})},focus:async()=>{r.removed||await this.bridge.draw(t.node,{focus:!0})}})}async button(e,t={}){const{handle:r,state:a}=await this.make("button",{width:72,height:24,fill:8141549,hoverFill:9133302,pressedFill:7153881,cornerRadius:4,...t,font:{color:16777215,bold:!0,...t.font},label:e});return Object.assign(r,{setLabel:i=>a.removed?Promise.resolve():this.bridge.draw(r.node,{label:i}),setDisabled:i=>a.removed?Promise.resolve():this.bridge.draw(r.node,{disabled:i})})}async panel(e={}){const{onMove:t,onResize:r,...a}=e,{handle:i}=await this.make("panel",{width:260,height:200,fill:{color:1120295,alpha:.92},stroke:3621201,titleFill:2042167,titleHeight:22,cornerRadius:6,...a,titleFont:{color:16777215,bold:!0,...a.titleFont}}),s=i;return t&&s.on("move",t),r&&s.on("resize",r),s}async list(e={}){const{handle:t,state:r}=await this.make("list",{width:240,height:160,fill:{color:0,alpha:.55},padding:4,...e,font:{color:16777215,...e.font}});return Object.assign(t,{append:(...a)=>r.removed||a.length===0?Promise.resolve():this.bridge.draw(t.node,{append:a.map(Re)}),setRows:a=>r.removed?Promise.resolve():this.bridge.draw(t.node,{rows:a.map(Re)})})}async replace(e,t){return await t.update({parent:null,host:null,replaces:e}),()=>t.remove()}async attach(e,t){return await t.update({parent:null,replaces:null,host:e}),()=>t.remove()}async focusGame(){await this.bridge.stage().at("focus").set(null)}async clear(){const e=[...this.nodes.entries()].filter(([,t])=>t.parent===null||!this.nodes.has(t.parent)).map(([t])=>t);await this.remove(e)}async make(e,t){var r;const a=this.bridge.allocate(),i={type:e,...this.specOf(t)},s={parent:t.parent?t.parent.node:null,children:new Set,listeners:new Map,failed:new Set,gone:new Set,stopHearing:()=>{},removed:!1,value:""};s.stopHearing=this.bridge.onSubscription(a,o=>{var l;if(o.kind==="overlay"){if(o.event==="failed"){s.failed.forEach(c=>c(o.message??"The image did not load"));return}(o.event==="change"||o.event==="submit")&&o.value!==void 0&&(s.value=o.value),(l=s.listeners.get(o.event))==null||l.forEach(c=>c(o))}}),this.nodes.set(a,s);try{await this.bridge.draw(a,i)}catch(o){throw s.stopHearing(),this.nodes.delete(a),o}return s.parent!==null&&((r=this.nodes.get(s.parent))==null||r.children.add(a)),{handle:this.handle(a,e,s),state:s}}handle(e,t,r){const a=()=>this.remove([e]);return Object.assign(a,{node:e,type:t,update:async s=>{var o,l;if(r.removed)return;const c=this.specOf(s);"parent"in s&&(r.parent!==null&&((o=this.nodes.get(r.parent))==null||o.children.delete(e)),r.parent=s.parent?s.parent.node:null,r.parent!==null&&((l=this.nodes.get(r.parent))==null||l.children.add(e))),await this.bridge.draw(e,c)},show:()=>r.removed?Promise.resolve():this.bridge.draw(e,{visible:!0}),hide:()=>r.removed?Promise.resolve():this.bridge.draw(e,{visible:!1}),remove:a,on:(s,o)=>{const l=o,c=w=>{switch(w.event){case"change":case"submit":case"link":l(w.value??"");return;case"focus":case"blur":l(void 0);return;case"row":l(w.index??-1);return;case"move":l({x:w.x,y:w.y});return;case"resize":l({width:w.width??0,height:w.height??0});return;default:l({x:w.x,y:w.y})}};let h=r.listeners.get(s);const u=!h||h.size===0;h||(h=new Set,r.listeners.set(s,h)),h.add(c);const d=ht.has(s);u&&d&&this.sendMouse(e,r);let g=!1;return async()=>{g||(g=!0,h.delete(c),d&&h.size===0&&!r.removed&&await this.sendMouse(e,r))}},onFailed:s=>(r.failed.add(s),()=>{r.failed.delete(s)}),onRemoved:s=>r.removed?(s(),()=>{}):(r.gone.add(s),()=>{r.gone.delete(s)})})}async sendMouse(e,t){const r=[...t.listeners.entries()].filter(([a,i])=>ht.has(a)&&i.size>0).map(([a])=>a);await this.bridge.draw(e,{mouse:r})}async remove(e){const t=[],r=[],a=s=>{var o;const l=this.nodes.get(s);!l||l.removed||(l.removed=!0,l.stopHearing(),this.nodes.delete(s),t.push(s),r.push(...l.gone),l.gone.clear(),l.children.forEach(a),l.parent!==null&&((o=this.nodes.get(l.parent))==null||o.children.delete(s)))};e.forEach(a);const i=e.filter(s=>t.includes(s));try{await this.bridge.erase(i)}finally{for(const s of r)try{s()}catch(o){console.error("phantom.flash.overlay: a removal listener failed",o)}}}specOf(e){const t={};for(const[r,a]of Object.entries(e))if(a!==void 0)switch(r){case"parent":t.parent=a===null?null:a.node;break;case"anchor":t.anchor=a===null?null:Qn(a);break;case"host":case"replaces":t[r]=a===null?null:Zn(a);break;case"fill":case"background":case"hoverFill":case"pressedFill":case"titleFill":t[r]=a===null?null:er(a);break;case"stroke":t.stroke=a===null?null:tr(a);break;case"font":case"titleFont":t[r]=Jn(a);break;case"rich":t.spans=a===null?null:typeof a=="string"?qt(a):a;break;case"rows":case"append":t[r]=a.map(Re);break;default:t[r]=a}return t}}function Jn(n){return{family:"_sans",size:12,color:16777215,bold:!1,italic:!1,...n}}function Re(n){if(typeof n=="string")return n||" ";const e=(Array.isArray(n)?n:qt(n.markup)).filter(t=>t.text.length>0);return e.length?e:" "}function Qn(n){const e=typeof n=="object"&&n!==null&&"place"in n?n:{place:n},t=E(e.place);return{target:t.target,path:t.path,x:e.x??0,y:e.y??0,refreshFrames:e.refreshFrames??12,hideWhenGone:e.hideWhenGone??!0}}function Zn(n){const e=typeof n=="object"&&n!==null&&"place"in n?n:{place:n},t=E(e.place);return{target:t.target,path:t.path,refreshFrames:e.refreshFrames??12}}function er(n){return typeof n=="number"?{color:n,alpha:1}:{color:n.color,alpha:n.alpha??1}}function tr(n){return typeof n=="number"?{color:n,alpha:1,width:1}:{color:n.color,alpha:n.alpha??1,width:n.width??1}}async function nr(n,e,t,r,a={}){const i=e.find(t);if(!i)throw new TypeError(`There is no hook "${t}" in the hook table`);const s={perFrame:a.perFrame??50};a.when!==void 0&&(s.when=a.when),a.first!==void 0&&(s.first=a.first),a.every!==void 0&&(s.every=a.every),a.replaceArgs!==void 0&&(s.replaceArgs=a.replaceArgs),"returns"in a&&(s.skip={returns:a.returns});const o={...Ue(n,i,s,!1),override:!0};let l=0,c=Promise.resolve();const h=he(i),u=async f=>{l++;let p=!1,m=!1;const y=f.args.map(O=>P(n,n.decode(O))),v={};y.forEach((O,H)=>{var b;v[((b=i.parameters[H])==null?void 0:b.name)??String(H)]=O});const T=i.isStatic?C(n,n.definition(i.className),{className:i.className}):P(n,n.decode(f.self)),R={hook:i,call:f.call,self:T,args:v,argList:y,original:async(...O)=>{if(m)throw new L("FLASH",`The call of ${h} has ended: its handler finished`);p=!0;const H=await n.invokeOriginal(d,f.token,O.length===0?null:await Q(n,O));return P(n,H)}};try{await r(R)}catch(O){if(console.error(`The override of ${h} failed: ${O instanceof Error?O.message:String(O)}`),!p&&(a.onError??"original")==="original")try{await n.invokeOriginal(d,f.token,null)}catch(H){console.error(`The original ${h} failed after its override did: ${H instanceof Error?H.message:String(H)}`)}}finally{m=!0,l--;try{await n.overrideDone(d,f.token)}catch{}}},{registration:d,stop:g}=await n.hook(i.id,o,f=>{var p;switch(f.kind){case"override":a.sequential?c=c.then(()=>u(f)):u(f);return;case"hook-dropped":(p=a.onDropped)==null||p.call(a,f.dropped);return;case"hook-failed":console.error(`The override of ${h} failed and is off: ${f.error.message}`);return}}),w=Object.assign(()=>g(),{registration:d,hook:i,stats:async()=>(await n.request({op:"hookStats"})).find(p=>p.registration===d)??null});return Object.defineProperty(w,"running",{get:()=>l,enumerable:!0}),w}const rr={fit:"showAll",stretch:"exactFit",fill:"noBorder",none:"noScale"};class ar{constructor(e){this.bridge=e}bridge;async zoom(e){await this.bridge.definition("room.RoomManagerWorld").at("instance","updateRoomZoom").call(Math.round(e))}async zoomLevel(){return await this.bridge.definition("gMainFrame").at("layerManager","bkg","scaleX").get()*100}async stretch(e){await this.bridge.stage().at("scaleMode").set(rr[e])}hideHud(e){return this.bridge.highlight({target:{kind:"definition",name:"gui.GuiManager"},path:e?["mainHud",e]:["mainHud"]},ce({hide:!0}))}hideLayer(e){return this.bridge.highlight({target:{kind:"definition",name:"gMainFrame"},path:["layerManager",e]},ce({hide:!0}))}async setQuality(e){await this.bridge.stage().at("quality").set(e)}async setFrameRate(e){const t=this.bridge.stage().at("frameRate"),r=await t.get();return await t.set(Math.max(1,Math.min(120,e))),r}}class Xe extends Lt{format="json";envelope;constructor(e,t){super(e,t),this.envelope=ir(e)}static create(e,t,r,a=-1,i="o"){const s=e==="toServer"?{t:"xt",b:{x:i,c:t,r:a,p:r}}:{t:"xt",b:{r:a,o:{_cmd:t,...r}}};return new Xe(JSON.stringify(s),e)}get type(){return this.envelope.t}get command(){var e;const t=this.direction==="toServer"?this.envelope.b.c:(e=this.envelope.b.o)==null?void 0:e._cmd;return typeof t=="string"?t:null}get room(){const e=this.envelope.b.r;return typeof e=="number"&&Number.isInteger(e)?e:null}get params(){if(this.direction==="toServer")return this.envelope.b.p??{};const{_cmd:e,...t}=this.envelope.b.o??{};return t}get value(){return this.envelope}edit(e){e(this.envelope),this.markModified()}serialize(){return JSON.stringify(this.envelope)}}function ir(n){let e;try{e=JSON.parse(n)}catch(t){throw new Ze(`Not JSON: ${t.message}`,"JSON_SYNTAX")}if(!ut(e)||typeof e.t!="string"||!ut(e.b))throw new Ze('A JSON message is an object with "t" and "b"',"JSON_SYNTAX");return e}function ut(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}class dt extends Lt{constructor(e,t,r=null){super(e,t),this.problem=r}problem;format="raw";get command(){return null}get room(){return null}serialize(){return this.raw}}function Ut(n,e){try{switch(n.charAt(0)){case"<":return new sn(n,e);case rn:return new an(n,e);case"{":return new Xe(n,e);default:return new dt(n,e)}}catch(t){return new dt(n,e,t)}}const Ge={send:"avatar.UserCommXtCommManager.onSendMessage",focusChat:"gui.ChatHistory.setFocusOnMsgText"};function sr(n,e){const t=new Map;for(const[s,o]of Object.entries(e))t.set(s.toLowerCase(),o);if(t.size===0)return n;let r="",a="";const i=()=>{r+=t.get(a.toLowerCase())??a,a=""};for(const s of n)s===" "||s===" "?(i(),r+=s):a+=s;return i(),r}function or(n,e){const t=n.toLowerCase();return e.some(r=>typeof r=="string"?r!==""&&t.includes(r.toLowerCase()):(r.lastIndex=0,r.test(n)))}async function lr(n,e={}){const{arg:t,fromClass:r,equals:a,exists:i,all:s}=n.flash.rules,o=e.shortcuts??{},l=e.blocked??[],c=r("avatar.UserCommXtCommManager","_mainHud","chatBar","text01_chat","text"),h=[],u=Je(async()=>{for(const d of h.splice(0).reverse())await d().catch(()=>{})});try{h.push(await n.flash.hook(Ge.send,{when:s(a(t("myMsg"),""),i(c)),replaceArgs:{myMsg:c}})),h.push(await n.flash.override(Ge.send,async d=>{var g;const[w,f]=d.argList,p=typeof f=="string"?f:"";if(p.trim()!==""&&or(p,l)){(g=e.onBlocked)==null||g.call(e,p);return}const m=sr(p,o);m===p?await d.original():await d.original(w,m)},{sequential:!0}))}catch(d){throw await u(),d}return u}async function cr(n,e={}){const t=e.style??{},r=n.flash.overlay,a=n.flash.use("gui.GuiManager").$at("mainHud"),i=e.maxLength??await n.flash.use("gui.GuiManager").$at("chatHist","chatMsgText","maxChars").$get().then(c=>typeof c=="number"&&c>0?c:70).catch(()=>70),s={family:t.font??"_sans",size:t.size??13},o=[],l=Je(async()=>{for(const c of o.splice(0).reverse())await c().catch(()=>{})});try{o.push(async()=>{await n.flash.use("gui.GuiManager").setFocusToChatText()});const c=await r.input({replaces:a.$at("chatBar"),placeholder:t.placeholderText??"Say something",maxLength:i,fill:t.background??16777215,stroke:t.border??8141549,cornerRadius:t.cornerRadius??6,padding:6,font:{...s,color:t.text??1120295}});o.push(()=>c.remove());const h=await r.button(t.buttonLabel??"Send",{replaces:a.$at("sendChatBtn"),fill:t.button??8141549,hoverFill:t.buttonHover??9133302,cornerRadius:t.cornerRadius??6,font:{...s,color:t.buttonText??16777215,bold:!0}});o.push(()=>h.remove());let u=!1;const d=async()=>{const g=c.value();if(!(u||g.trim()==="")){u=!0;try{await n.chat.say(g),await c.setValue(""),await c.focus()}finally{u=!1}}};return o.push(c.on("submit",()=>{d()})),o.push(h.on("click",()=>{d()})),o.push(await n.flash.hook(Ge.focusChat,{skip:!0,phase:"enter",capture:{args:[]}},()=>{c.focus()})),(e.focus??!0)&&await c.focus(),Object.assign(l,{input:c,send:d})}catch(c){throw await l(),c}}const hr=[16096779,1096065,3900150,15485081,9133302,15680580,1357990,15381256],Ce=22;async function ur(n,e={}){const t=e.style??{},r=n.flash.overlay,a=t.nameColors&&t.nameColors.length>0?t.nameColors:hr,i=e.width??280,s=e.height??200,o={family:t.font??"_sans",size:t.size??12},l=new Map,c=[],h=Je(async()=>{for(const u of c.splice(0).reverse())await Promise.resolve(u()).catch(()=>{})});try{const u=await r.panel({title:e.title??"Chat",x:e.x??12,y:e.y??60,width:i,height:s,resizable:!0,fill:{color:t.background??1120295,alpha:t.backgroundAlpha??.9},stroke:t.border??3621201,titleFill:t.titleBar??2042167,titleHeight:Ce,titleFont:{...o,color:t.titleText??16777215,bold:!0},...e.onMove?{onMove:e.onMove}:{}});c.push(()=>u.remove());const d=await r.list({parent:u,width:i,height:s-Ce,fill:null,maxRows:e.maxRows??200,font:{...o,color:t.text??15987958}});c.push(u.on("resize",m=>{var y;(y=e.onResize)==null||y.call(e,m),d.update({width:m.width,height:m.height-Ce})})),c.push(d.on("link",m=>{const y=l.get(m);if(y){if(e.onNameClick){e.onNameClick(y);return}dr(n,y.userId)}}));const g=async m=>{let y=null;if(m.kind===Ee.free||m.kind===Ee.freeSafeChat?y=m.text:m.kind===Ee.safeChat&&(y=await n.chat.phrase(m.text).catch(()=>null)??null),y===null)return null;const v=n.room.players.get(m.userId),T=(v==null?void 0:v.avatarName)||(v==null?void 0:v.userName)||`#${m.userId}`,R=String(m.userId);return l.set(R,{userId:m.userId,name:T}),[{text:T,bold:!0,color:a[Math.abs(m.userId)%a.length],link:R},{text:`: ${y}`}]},f=(await Promise.all(n.chat.recent.map(g))).filter(m=>m!==null);f.length>0&&await d.append(...f);let p=Promise.resolve();return c.push(n.chat.onMessage(m=>{p=p.then(async()=>{const y=await g(m);y&&await d.append(y)}).catch(()=>{})})),Object.assign(h,{panel:u,note:m=>d.append({markup:m})})}catch(u){throw await h(),u}}async function dr(n,e){const t=n.flash.use("avatar.AvatarManager").avatarViewList.$at(String(e)),r=await n.flash.highlight(t,{color:16436245,strength:3});setTimeout(()=>{r()},2e3)}function Je(n){let e=null;return()=>e??=n()}class fr{constructor(e){this.bridge=e,this.overlay=new Xn(e),this.entities=new Nn(this),this.view=new ar(e)}bridge;overlay;entities;view;rules=Fn;hookIndex=null;use(e){return C(this.bridge,this.bridge.definition(e),{className:e})}global(e){return C(this.bridge,this.bridge.definition(e))}stage(){return C(this.bridge,this.bridge.stage())}client(){return C(this.bridge,this.bridge.gameClient())}whenReady(){return this.bridge.whenReady()}hooks(e){if(e!==void 0||!this.hookIndex){const t=this.bridge.hookTable(e).then(r=>new $n(r));t.catch(()=>{this.hookIndex===t&&(this.hookIndex=null)}),this.hookIndex=t}return this.hookIndex}async hook(e,t={},r){return In(this.bridge,await this.hooks(),e,t,r)}async override(e,t,...[r]){return nr(this.bridge,await this.hooks(),e,t,r??{})}style(e,t){return this.bridge.style(E(e),t)}hold(e,t,r={}){return lt(this.bridge,[{place:e,value:t}],r)}holdAll(e,t={}){return lt(this.bridge,e,t)}repeat(e,t={}){return Ln(this.bridge,e,t)}collect(e,t,r={}){return Rn(this.bridge,e,t,r)}async track(e,t,r={}){if(await this.bridge.whenReady(),!this.bridge.features.includes("track"))throw new Error("This game is running a loader from before lists; look for them yourself");const a=r.where===void 0?{target:{kind:"stage"},path:[]}:E(r.where),i=s=>s.filter(o=>o instanceof _).map(o=>C(this.bridge,o.at(),{handle:o}));return this.bridge.track(a,e,{...r.mode!==void 0?{mode:r.mode}:{},...r.everyFrames!==void 0?{everyFrames:r.everyFrames}:{}},({added:s,removed:o})=>t({added:i(s),removed:i(o)}))}async snapshot(e,t={}){if(await this.bridge.whenReady(),!this.bridge.features.includes("snapshot"))throw new Error("This game is running a loader from before pictures; nothing can be drawn");return this.bridge.snapshot(E(e),t)}notes(){return new Bn(this.bridge)}async find(e,t){return await _n(this.bridge,t,e??{})}answering(e,t){return new Pn(this.bridge,e,t)}watch(e,t,r){const a=r;let i,s=[],o;if(Array.isArray(e))i="list",o=[...e];else if(wr(e))i="one",o=[e];else{i="record";const u=e;s=Object.keys(u),o=s.map(d=>u[d])}const l=o.map(E),c=u=>i==="one"?u[0]:i==="list"?u:Object.fromEntries(s.map((d,g)=>[d,u[g]]));let h=null;return this.bridge.watch(l,t,(u,d)=>{const g=u.map(p=>P(this.bridge,p)),w=c(g),f=l.map((p,m)=>(d==null?void 0:d[m])??null);a(w,h,i==="one"?f[0]:c(f)),h=w})}onTick(e,t={}){return this.bridge.tick(t.everyFrames??1,e)}highlight(e,t={}){return this.bridge.highlight(E(e),ce(t))}hide(e){return this.bridge.highlight(E(e),ce({hide:!0}))}recolor(e,t){const r=t?E(t):{target:{kind:"loader"},path:[]};return this.bridge.highlight(r,{glow:null,...zt(e),hide:!1,pulse:null})}onKey(e,t,r={}){return this.bridge.onKey(Hn(e,r),a=>gr(t)({code:a.code,char:a.char,ctrl:a.ctrl,shift:a.shift,alt:a.alt,phase:a.phase,consumed:a.consumed===!0}))}}function gr(n){return e=>{try{const t=n(e);t instanceof Promise&&t.catch(r=>ft(r))}catch(t){ft(t)}}}function ft(n){console.error("phantom.flash.onKey: a listener failed",n)}function wr(n){try{return E(n),!0}catch{return!1}}const pr={avatarManager:"avatar.AvatarManager"},mr="com.sbi.loader.LoaderCache.fetchCDNURL",yr=2e4;class br{channel;flash;hooks=new Map;constructor(e,t){this.channel=e.content??null,this.flash=t}get available(){return this.channel!==null}async replace(e,t){const r=this.reach(),a=gt(e);await this.unhook($e(a));const i=await r.replace(a,Fe(t)),s=[],o=await this.pointClientAt(a,i.url);return o&&(this.hooks.set($e(a),o),s.push("client")),s.push("proxy"),{...i,how:s,stop:()=>this.restore(a).then(()=>{})}}async restore(e){const t=this.reach(),r=gt(e);return await this.unhook($e(r)),t.restore(r)}replacements(){return this.reach().list()}onRequest(e){return this.reach().observe(e)}async replaceOnScreen(e,t,r={}){const{url:a,id:i}=await this.addressOf(t),{refreshFrames:s,...o}=r,l=await this.flash.overlay.image(a,{...o,replaces:s===void 0?e:{place:e,refreshFrames:s}});return{url:a,stop:async()=>{await l.remove(),i&&await this.reach().release(i)}}}async load(e,t={}){const r=this.flash.bridge,a=Fe(e),i=await r.construct("flash.display.Loader"),s=[];try{const o=await r.definition("flash.system.ApplicationDomain").at("currentDomain").get();s.push(()=>o.release());const l=await r.construct("flash.system.LoaderContext",!1,o);s.push(()=>l.release()),await l.at("allowCodeImport").set(t.allowCode===!0).catch(()=>{});const c=this.whenLoaded(i,t.timeoutMs??yr);if(a.kind==="data-url"){const u=await this.decodeInFlash(a.url);s.push(()=>u.release()),await i.at("loadBytes").call(u,l)}else{const u=await this.reach().hold(a);s.push(()=>this.reach().release(u.id)),await i.at("load").call(new ke("flash.net.URLRequest",[u.url]),l)}await c;const h=await i.at("content").get();if(!h)throw new Error("Nothing was loaded");return{content:h,loader:i,unload:async()=>{await i.at("unloadAndStop").call().catch(()=>{}),await h.release().catch(()=>{}),await i.release().catch(()=>{})}}}catch(o){throw await i.release().catch(()=>{}),o}finally{for(const o of s)await o().catch(()=>{})}}async pointClientAt(e,t){if(e.kind==="pattern")return null;const r=vr(e.value);if(!r)return null;const{arg:a,equals:i,startsWith:s,any:o}=this.flash.rules,l=e.kind==="prefix"?s:i;try{return await this.flash.hook(mr,{when:o(l(a("assetPath"),r),l(a("assetPath"),`/${r}`)),replaceReturn:t})}catch{return null}}async unhook(e){const t=this.hooks.get(e);t&&(this.hooks.delete(e),await t().catch(()=>{}))}async addressOf(e){const t=Fe(e);if(t.kind==="data-url")return{url:t.url,id:null};const r=await this.reach().hold(t);return{url:r.url,id:r.id}}async decodeInFlash(e){const t=e.indexOf(",");if(t===-1||e.slice(0,t).indexOf(";base64")===-1)throw new Error("Only base64 data: URLs can be loaded into the client");const r=await this.flash.bridge.definition("phantom.overlay.Base64").at("decode").call(e.slice(t+1));if(!r)throw new Error("The loader could not decode those bytes");return r}whenLoaded(e,t){const r=e.at("contentLoaderInfo");return new Promise((a,i)=>{const s=[],o=h=>{clearTimeout(l);for(const u of s.splice(0))u().catch(()=>{});h?i(h):a()},l=setTimeout(()=>o(new Error(`Flash did not load those bytes within ${t}ms`)),t),c=(h,u)=>r.listen(h,()=>o(u===null?null:new Error(u))).then(d=>s.push(d),d=>o(d));c("complete",null),c("ioError","Flash could not read those bytes"),c("securityError","Flash refused those bytes")})}reach(){if(!this.channel)throw new Error("This game cannot replace content: it was made without a content origin");return this.channel}}function $e(n){return`${n.kind}:${n.value}`}function vr(n){let e=n.charAt(0)==="/"?n.slice(1):n;const t=e.indexOf("?");t!==-1&&(e=e.slice(0,t)),e.slice(0,8)==="content/"&&(e=e.slice(8));const r=e.indexOf("/"),a=r===-1?e:e.slice(0,r);return r!==-1&&a.length>0&&kr(a)&&(e=e.slice(r+1)),e}function kr(n){for(const e of n)if(e<"0"||e>"9")return!1;return n.length>0}function gt(n){const e=typeof n=="string"?{kind:"path",value:n}:n;if(!e||typeof e.value!="string"||!e.value)throw new TypeError("A replacement matches a path, a prefix or a pattern");const t=e.kind;if(t!=="path"&&t!=="prefix"&&t!=="pattern")throw new TypeError(`${t} is not path, prefix or pattern`);const r=e.value.charAt(0)==="/"?e.value:`/${e.value}`;return{kind:t,value:r}}function Fe(n){if(typeof n=="string")return n.slice(0,5).toLowerCase()==="data:"?{kind:"data-url",url:n}:{kind:"file",path:n};if(n instanceof ArrayBuffer)return{kind:"bytes",bytes:new Uint8Array(n)};if(ArrayBuffer.isView(n)){const e=n;return{kind:"bytes",bytes:new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}}if(n&&typeof n=="object"){const e="contentType"in n&&n.contentType?n.contentType:null,t=e?{contentType:e}:{};if("bytes"in n){const r=n.bytes,a=r instanceof ArrayBuffer?new Uint8Array(r):r;if(!(a instanceof Uint8Array))throw new TypeError("bytes are a Uint8Array");return{kind:"bytes",bytes:a,...t}}if("dataUrl"in n&&typeof n.dataUrl=="string")return{kind:"data-url",url:n.dataUrl,...t};if("file"in n&&typeof n.file=="string")return{kind:"file",path:n.file,...t}}throw new TypeError("A source is bytes, a data: URL, or the path of a file on this computer")}const F={definitionByName:"GETDEFINITIONBYNAME",resourceStack:"com.sbi.loader.ResourceStack",guiManager:"gui.GuiManager",loadProgress:"loadProgress.LoadProgress",denEditor:"gui.DenEditor",fonts:"gui.Fonts",palette:"com.sbi.graphics.PaletteHelper",colorTable:"gui.ColorTable",avatarManager:"avatar.AvatarManager"},xr={message:"com.sbi.popup.SBMessage",ok:"com.sbi.popup.SBOkPopup",okCancel:"com.sbi.popup.SBOkCancelPopup",yesNo:"com.sbi.popup.SBYesNoPopup",titled:"com.sbi.popup.SBStandardTitlePopup",parchment:"com.sbi.popup.SBParchmentPopup"},Ye={ink:1118483,line:3816e3,light:15790322,muted:10000543,accent:8141549,danger:15680580,size:12,cornerRadius:4},Ke={ink:4403228,line:9071167,light:16643032,muted:9402972,accent:3123423,danger:13369344,size:11,cornerRadius:8},D={game:28,phantom:24},Ie=22,Le=4,wt={top:12,left:10,right:10,bottom:12},pt=4293980400,Tr=12e4,Or=500;function U(n){return(...e)=>{try{const t=n(...e);t instanceof Promise&&t.catch(B)}catch(t){B(t)}}}function B(n){console.error("phantom.ui: a listener failed",n)}function Ne(n,e){console.warn(`phantom.ui: the picture ${n} did not load: ${e}`)}const ge={game:110,phantom:96},V=2,mt=.5,ye="_sans";function Mr(n,e=ye){return{skin:n,font:e,...n==="game"?Ke:Ye}}const Er={PopupSkin:"The plain popup frame: `ba` (its `t`, `m` and `b` slices) and `c`, its content box.",PopupContent:"What a plain popup shows: a `text` field the popup sizes itself around.",OkPopupSkin:"The frame of a popup with one button.",OkPopupContent:"An OK button (`okBtn`) and the `text` above it.",YesNoPopupSkin:"The frame of a popup with two buttons.",YesNoPopupContent:"Yes (`yesBtn`) and No (`noBtn`), and the `text` above them.",okCancelPopupContent:"OK (`okCancelBtn`) and Cancel (`cancelBtn`).",ConfirmSkin:"The frame the client asks you to confirm something in.",Tooltip:"The client's own tooltip (`gui.ToolTipPopup`): `txt`, and `l`, `m` and `r`.",HelpTxtBubble:"The bubble the client points at something it is explaining.",closeBtn:"The round close button in the corner of the client windows.",scrollbar2:"A scrollbar: `track`, `handle`, `topBtn` and `botBtn`.",BuddyListPopup:"The buddy list window's frame.",BuddyListContent:"What the buddy list shows inside that frame.",BD_AvatarEditorSkin:"The frame of the avatar editor's own dialog.",BD_AvatarEditorContent:"What that dialog shows.",DenEditorAsset:"The whole den editor, as the client builds it.",MySettings:"The settings window.",MainHud:"The whole HUD.",FreeNameBar:"The name bar above a player who is not a member.",memberNameBar:"The name bar above a member.",AnimsTitleBanner:"The banner the client puts a title in.",ChatBalloonAsset:"A chat balloon.",Cursor:"The client's own mouse cursor.",QuestPickupIcon:"The icon an adventure shows over something to pick up.",MinigameLobbySkin:"A minigame lobby's frame.",MinigameLobbyContent:"What a minigame lobby shows.",BroadcastPopupSkin:"The frame an announcement is shown in.",BroadcastPopupContent:"What an announcement shows.",DenLockPopupSkin:"The frame of the den's lock settings.",DenLockPopupContent:"What the den lock settings show.",ReportRulesPopupSkin:"The frame of the report window's rules.",ReportRulesPopupContent:"What the report rules show."},Sr=/^[A-Za-z_][A-Za-z0-9_]*$/;function yt(n){if(!Sr.test(n))throw new TypeError(`"${n}" is not a symbol name: a symbol is named in letters, digits and underscores`);return n}const bt={gui:{className:F.guiManager,path:["guiLayer"]},hud:{className:F.guiManager,path:["mainHud"]},room:{className:F.avatarManager,path:["playerAvatarWorldView","parent"]},avatarEditor:{className:F.guiManager,path:["avatarEditor","avEditor"]},denEditor:{className:F.denEditor,path:["staticEditor"]}},vt="stage",kt={avatarEditor:{open:"gui.AvatarEditor.init",close:"gui.AvatarEditor.destroy",spot:"avatarEditor"},denEditor:{open:"gui.DenEditor.init",close:"gui.DenEditor.destroy",spot:"denEditor"},settings:{open:"gui.MySettings.init",close:"gui.MySettings.destroy",spot:null},buddyList:{open:"buddy.BuddyList.init",close:"buddy.BuddyList.destroy",spot:null},petCreator:{open:"gui.PetCreator.init",close:"gui.PetCreator.destroy",spot:null},achievements:{open:"gui.AchievementViewer.init",close:"gui.AchievementViewer.destroy",spot:null},bulletinBoard:{open:"gui.BulletinBoard.init",close:"gui.BulletinBoard.destroy",spot:null},playerSearch:{open:"gui.PlayerSearch.init",close:"gui.PlayerSearch.destroy",spot:null},recycle:{open:"gui.RecycleItems.init",close:"gui.RecycleItems.destroy",spot:null},trade:{open:"gui.TradeManager.init",close:"gui.TradeManager.destroy",spot:null},petInventory:{open:"gui.PetInventory.init",close:"gui.PetInventory.destroy",spot:null},reportPlayer:{open:"gui.ReportAPlayer.init",close:"gui.ReportAPlayer.destroy",spot:null},serverSelector:{open:"gui.ServerSelector.init",close:"gui.ServerSelector.destroy",spot:null}},Ar=5,Pr=18,ae=8,_e=16,Rr=240,je=20,Cr=48,$r=-80,xt={x:12,y:-10},M=8,ze=22,Tt={game:320,phantom:300},Fr={game:190,phantom:150},we={x:60,y:90},Ir={ok:0,yesNo:1,continueExit:2,continue:3};function Lr(n,e,t={}){const r={slot:"layer"},a={slot:"callback"},i=t.name??null,s=xr[n];switch(n){case"message":return{className:s,args:[r,{slot:"skin"},e,!0,!0,t.modal??!1,t.draggable??!0,t.darken??!1,i]};case"ok":return{className:s,args:[r,e,t.darken??!0,null,!0,!0,t.modal??!0,t.draggable??!1,i]};case"yesNo":return{className:s,args:[r,e,t.darken??!0,a,null,!0,!0,t.modal??!0,t.draggable??!1,i]};case"okCancel":return{className:s,args:[r,e,t.darken??!0,a,null]};case"titled":return{className:s,args:[r,e,t.title??null,t.mediaId??370,a,!0,t.darken??!0]};case"parchment":return{className:s,args:[r,Ir[t.buttons??"ok"],e,t.darken??!0,a,null]}}}function Ot(n){const e=Math.max(1,Math.floor(n.columns)),t=[];for(let r=0;r<Math.max(0,Math.floor(n.count));r++){const a=Math.floor(r/e),i=r%e;t.push({index:r,row:a,column:i,x:i*(n.tileWidth+n.gap),y:a*(n.tileHeight+n.gap),width:n.tileWidth,height:n.tileHeight})}return t}function Nr(n,e){const t=e.gap,r=n.length;if(r===0)return[];const a=(e.width+t)/r;return n.map((i,s)=>{const o=Math.round(s*a),l=s===r-1?e.width+t:Math.round((s+1)*a);return{index:s,value:i,x:o,width:Math.max(0,l-o-t)}})}function _r(n){const e=Math.max(0,n.contentHeight-n.viewHeight),t=Math.min(e,Math.max(0,n.offset)),r=n.minThumb??16,a=n.contentHeight>0?n.viewHeight/n.contentHeight:1,i=Math.max(Math.min(n.trackHeight,r),Math.min(n.trackHeight,Math.round(n.trackHeight*a))),s=n.trackHeight-i;return{offset:t,max:e,thumbY:e>0?Math.round(t/e*s):0,thumbHeight:i}}function jr(n,e,t){const r=Math.max(1,Math.round(n-e-t+1)),a=-Math.floor(r/2);return{middle:r,middleY:a,topY:a-e,bottomY:a+r-1}}function zr(n,e){const t=e?{top:e.y,left:e.x,right:n.width-e.x-e.width,bottom:n.height-e.y-e.height}:null,r=(s,o)=>{const l=t==null?void 0:t[s];return l!==void 0&&Number.isFinite(l)&&l>=2&&l<=o/4?Math.ceil(l):wt[s]},a={top:r("top",n.height),left:r("left",n.width),right:r("right",n.width),bottom:r("bottom",n.height)},i={x:a.left+Le,y:a.top,width:Math.max(0,Math.floor(n.width-a.left-a.right-2*Le)),height:Math.max(Ie,Math.floor(n.height-a.top-a.bottom-Le))};return{edge:a,measured:t!==null&&Object.keys(wt).every(s=>a[s]===Math.ceil(t[s])),panel:i,titleHeight:Ie,body:{width:i.width,height:i.height-Ie}}}class Hr{bridge;flash;drawn=new Set;popups=new Set;tags=new Map;symbolMaker=null;gameFont=null;defaultSkin="phantom";known={art:!1,palettes:!1};readyTimeoutMs=Tr;popup;constructor(e,t){this.bridge=e.flash,this.flash=t,this.popup=new Dr((r,a,i,s,o)=>this.openPopup(r,a,i,s,o),()=>this.clear())}get skin(){return this.defaultSkin}set skin(e){this.defaultSkin=e}async status(){const[e,t]=await Promise.all([this.artLoaded(),this.palettesLoaded()]);return{art:e,palettes:t}}async ready(e=this.readyTimeoutMs){const t=await this.waitFor({art:!0,palettes:!0},e);if(t.art&&t.palettes)return t;const r=[t.art?null:"its library art",t.palettes?null:"its colour palettes"].filter(Boolean);throw new Error(`The game has not loaded ${r.join(" or ")} yet: waited ${Math.round(e/1e3)} seconds`)}async theme(e){const t=e??this.defaultSkin;return Mr(t,t==="game"?await this.clientFont():ye)}symbols(){return Object.entries(Er)}async hasSymbol(e){const t=yt(e);try{return await this.bridge.definition(F.resourceStack).at("hudAssetsLoaderInfo","applicationDomain","hasDefinition").call(t)===!0}catch{return!1}}async symbol(e,t={}){const r=yt(e);await this.waitFor({art:!0});const a=await this.flash.overlay.group({x:t.x??0,y:t.y??0,...t.scale===void 0?{}:{scale:t.scale},...t.visible===void 0?{}:{visible:t.visible}});let i=null;try{i=await(await this.maker()).at("apply").call(null,[r,t.localize===!0]),await(await this.nodeObject(a)).at("addChild").call(i),await this.adopt(a,{...t.parent===void 0||t.parent===null?{}:{parent:S(t.parent)},...t.host===void 0?{}:{host:t.host===null?null:this.placeOf(t.host)},...t.replaces===void 0?{}:{replaces:t.replaces===null?null:this.placeOf(t.replaces)}})}catch(h){throw await a.remove(),i&&await this.bridge.release([i]).catch(()=>{}),h}const s=i,o=s.at(),l=new Set;return this.widget(a,t.skin??this.defaultSkin,{name:r,object:s,on:async(h,u)=>{const d=await o.listen(Mt[h],()=>u()),g=async()=>{l.delete(g),await d()};return l.add(g),g},size:async()=>({width:await s.at("width").get()??0,height:await s.at("height").get()??0})},async()=>{for(const h of[...l])await h().catch(()=>{});await this.bridge.release([s]).catch(()=>{})})}async window(e={}){const t=e.skin??this.defaultSkin,r=t==="game",a=r&&(await this.waitFor({art:!0})).art,i=await this.theme(t),s={width:e.width??280,height:e.height??200},o={x:e.x??40,y:e.y??40},l=r?30:24,c=await this.flash.overlay.panel({x:o.x,y:o.y,width:s.width,height:s.height,title:e.title??"",titleHeight:l,draggable:e.draggable!==!1,resizable:e.resizable===!0&&!r,cornerRadius:i.cornerRadius,fill:r?{color:i.light,alpha:0}:{color:i.ink,alpha:.94},stroke:r?null:i.line,titleFill:i.line,titleFont:{family:i.font,size:i.size+1,bold:!0,color:i.light},visible:!1});let h=null;if(a)try{h=await this.dressWindow(c,s.height)}catch(m){console.warn(`phantom.ui.window: the popup frame could not be drawn: ${Y(m)}`)}else r&&console.warn(`phantom.ui.window: the game has not loaded its popup art after ${Math.round(this.readyTimeoutMs/1e3)} seconds, so "${e.title??""}" is drawn in the game skin's colours instead`);const u=h?{x:h.layout.panel.x,y:h.layout.panel.y}:{x:0,y:0};if(h?await c.update({x:o.x+u.x,y:o.y+u.y,width:h.layout.panel.width,height:h.layout.panel.height,titleHeight:h.layout.titleHeight,titleFill:{color:i.line,alpha:.004},titleFont:{family:i.font,size:i.size+1,bold:!0,color:i.ink}}):r&&await c.update({fill:{color:Ke.light,alpha:.96},stroke:{color:Ke.line,width:2}}),e.parent)try{await this.adopt(c,{parent:S(e.parent)})}catch(m){throw await c.remove(),h&&await this.bridge.release(h.held).catch(()=>{}),m}const d=h?{width:h.width,height:h.height,bodyWidth:h.layout.body.width,bodyHeight:h.layout.body.height}:{...s,bodyWidth:s.width,bodyHeight:Math.max(0,s.height-l)},g=new Set,w=[],f=this.widget(c,t,{body:c,...d,framed:h!==null,move:(m,y)=>c.update({x:m+u.x,y:y+u.y}),setTitle:m=>c.update({title:m}),onClose:m=>(g.add(m),async()=>{g.delete(m)}),onMove:m=>{const y=c.on("move",({x:v,y:T})=>m({x:v-u.x,y:T-u.y}));return async()=>{await y()}}},async()=>{for(const m of w.splice(0))await m().catch(()=>{});h&&await this.bridge.release(h.held).catch(()=>{})}),p=()=>{f().then(()=>g.forEach(m=>m()))};if(e.closable!==!1&&(h!=null&&h.close)){const m=await h.close.at().listen(Mt.down,p);w.push(async()=>{await m()})}else e.closable!==!1&&(await this.flash.overlay.button("x",{parent:c,x:d.bodyWidth-(r?26:24),y:2,width:18,height:16,cornerRadius:i.cornerRadius,fill:i.line,hoverFill:{color:i.danger,alpha:.8},font:{family:i.font,size:i.size,bold:!0,color:i.light}})).on("click",p);return e.visible!==!1&&await c.show(),f}async button(e,t={}){const r=t.skin??this.defaultSkin,a=await this.theme(r),i=this.box(t,{width:ge[r],height:D[r]}),s=i.width??ge[r],o=i.height??D[r],l=t.image===void 0?null:await this.flash.overlay.group({x:i.x??0,y:i.y??0,...i.parent?{parent:i.parent}:{},...i.visible===void 0?{}:{visible:i.visible}});let c=e,h=l===null||t.imageOnly!==!0,u=t.disabled===!0;const d=await this.flash.overlay.button(h?c:"",{...l===null?i:{x:0,y:0,width:s,height:o,parent:l},...ie(a,t.primary===!0),cornerRadius:a.cornerRadius,...t.disabled===void 0?{}:{disabled:t.disabled},font:{family:a.font,size:a.size,bold:!0,color:t.primary===!0||r==="phantom"?a.light:a.ink}}),g=o-V*2,w=t.imageOnly===!0?{width:s-V*2,height:g}:{width:g,height:g};let f=null;const p=async()=>{h||(h=!0,await d.setLabel(c))},m=async y=>{if(f){await f.update({url:y});return}f=await this.picture(y,{parent:l,x:V,y:V,...w,...u?{alpha:mt}:{}},v=>{Ne("on a button",v),p().catch(B)})};return t.image!==void 0&&await m(t.image),this.widget(l??d,r,{label:()=>c,setLabel:async y=>{c=y,await d.setLabel(h?y:"")},setDisabled:async y=>{u=y,await d.setDisabled(y),f&&await f.update({alpha:y?mt:1})},setImage:async y=>{if(l===null)throw new TypeError("This button was drawn without a picture, so there is nowhere to put one: give it `image` when it is drawn");if(y===null){const v=f;f=null,await(v==null?void 0:v.remove()),await p();return}h=t.imageOnly!==!0,await d.setLabel(h?c:""),await m(y)},onClick:y=>{const v=d.on("click",U(y));return async()=>{await v()}}})}async label(e,t={}){const r=t.skin??this.defaultSkin,a=await this.theme(r),i=await this.flash.overlay.text(e,{x:t.x??0,y:t.y??0,...t.parent?{parent:S(t.parent)}:{},...t.visible===void 0?{}:{visible:t.visible},centered:t.centered===!0,font:{family:a.font,size:t.heading===!0?a.size+3:a.size,bold:t.heading===!0,color:t.muted===!0?a.muted:r==="game"?a.ink:a.light},...t.background===!0?{background:r==="game"?{color:a.light,alpha:.9}:{color:a.ink,alpha:.7},padding:4}:{}});return this.widget(i,r,{setText:s=>i.update({text:s})})}async input(e={}){const t=e.skin??this.defaultSkin,r=await this.theme(t),a=await this.flash.overlay.input({...this.box(e,{width:200,height:D[t]}),...e.value===void 0?{}:{value:e.value},...e.placeholder===void 0?{}:{placeholder:e.placeholder},...e.maxLength===void 0?{}:{maxLength:e.maxLength},...e.multiline===void 0?{}:{multiline:e.multiline},...e.disabled===void 0?{}:{disabled:e.disabled},fill:t==="game"?r.light:16777215,stroke:r.line,cornerRadius:r.cornerRadius,font:{family:r.font,size:r.size,color:t==="game"?r.ink:1120295}});return this.widget(a,t,{value:()=>a.value(),setValue:i=>a.setValue(i),focus:()=>a.focus(),onChange:i=>{const s=a.on("change",U(i));return async()=>{await s()}},onSubmit:i=>{const s=a.on("submit",U(i));return async()=>{await s()}}})}async checkbox(e,t={}){const r=t.skin??this.defaultSkin,a=await this.theme(r),i=await this.flash.overlay.group({x:t.x??0,y:t.y??0,...t.parent?{parent:S(t.parent)}:{},...t.visible===void 0?{}:{visible:t.visible}});let s=t.checked===!0;const o=await this.flash.overlay.button(s?"x":"",{parent:i,width:14,height:14,cornerRadius:Math.min(3,a.cornerRadius),fill:r==="game"?a.light:{color:a.ink,alpha:.9},hoverFill:r==="game"?16777215:{color:a.line,alpha:.9},stroke:a.line,font:{family:a.font,size:a.size,bold:!0,color:a.accent}});await this.flash.overlay.text(e,{parent:i,x:20,y:0,font:{family:a.font,size:a.size,color:r==="game"?a.ink:a.light}});const l=new Set,c=async h=>{s=h,await o.setLabel(h?"x":"")};return o.on("click",()=>{c(!s).then(()=>l.forEach(h=>h(s)))}),this.widget(i,r,{checked:()=>s,setChecked:c,onChange:h=>(l.add(h),async()=>{l.delete(h)})})}async dropdown(e){var t;const r=e.skin??this.defaultSkin,a=await this.theme(r),i=e.width??140,s=e.height??D[r],o=await this.flash.overlay.group({x:e.x??0,y:e.y??0,...e.parent?{parent:S(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}});let l=[...e.choices],c=e.value??((t=l[0])==null?void 0:t.value)??null;const h=f=>{var p;return((p=l.find(m=>m.value===f))==null?void 0:p.label)??e.placeholder??"Choose..."},u=await this.flash.overlay.button(h(c),{parent:o,width:i,height:s,cornerRadius:a.cornerRadius,...ie(a,!1),font:{family:a.font,size:a.size,color:r==="game"?a.ink:a.light}}),d=await this.flash.overlay.list({parent:o,y:s+2,width:i,height:Math.min(140,Math.max(20,l.length*16+8)),visible:!1,fill:r==="game"?a.light:{color:a.ink,alpha:.96},stroke:a.line,cornerRadius:a.cornerRadius,rows:l.map(f=>f.label),font:{family:a.font,size:a.size,color:r==="game"?a.ink:a.light}});let g=!1;const w=new Set;return u.on("click",()=>{g=!g,g?d.show():d.hide()}),d.on("row",f=>{const p=l[f];g=!1,d.hide(),p&&(c=p.value,u.setLabel(p.label).then(()=>w.forEach(m=>m(p.value))))}),this.widget(o,r,{value:()=>c,setValue:async f=>{c=f,await u.setLabel(h(f))},setChoices:async f=>{l=[...f],await d.setRows(l.map(p=>p.label)),await u.setLabel(h(c))},onChange:f=>(w.add(f),async()=>{w.delete(f)})})}async tabs(e){var t;const r=e.skin??this.defaultSkin,a=await this.theme(r),i=e.width??260,s=e.tabHeight??22,o=await this.flash.overlay.group({x:e.x??0,y:e.y??0,...e.parent?{parent:S(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}),l=Nr(e.tabs.map(w=>w.value),{width:i,gap:2});let c=e.value??((t=e.tabs[0])==null?void 0:t.value)??"";const h=new Map,u=new Map,d=new Set;for(const w of l){const f=e.tabs[w.index];u.set(f.value,await this.flash.overlay.button(f.label,{parent:o,x:w.x,width:w.width,height:s,cornerRadius:a.cornerRadius,...ie(a,f.value===c),font:{family:a.font,size:a.size,bold:f.value===c,color:f.value===c||r==="phantom"?a.light:a.ink}})),h.set(f.value,await this.flash.overlay.group({parent:o,y:s+4,visible:f.value===c}))}const g=async w=>{if(h.has(w)){c=w;for(const[f,p]of h)await(f===w?p.show():p.hide());for(const[f,p]of u)await p.update({...ie(a,f===w),font:{family:a.font,size:a.size,bold:f===w,color:f===w||r==="phantom"?a.light:a.ink}})}};for(const[w,f]of u)f.on("click",()=>{g(w).then(()=>d.forEach(p=>p(w)))});return this.widget(o,r,{current:()=>c,select:g,body:w=>{const f=h.get(w);if(!f)throw new TypeError(`There is no tab called "${w}"`);return f},onSelect:w=>(d.add(w),async()=>{d.delete(w)})})}async list(e={}){const t=e.skin??this.defaultSkin,r=await this.theme(t),a=await this.flash.overlay.list({...this.box(e,{width:240,height:160}),...e.rows===void 0?{}:{rows:[...e.rows]},...e.maxRows===void 0?{}:{maxRows:e.maxRows},fill:t==="game"?r.light:{color:r.ink,alpha:.85},stroke:r.line,cornerRadius:r.cornerRadius,font:{family:r.font,size:r.size,color:t==="game"?r.ink:r.light}});return this.widget(a,t,{setRows:i=>a.setRows([...i]),append:(...i)=>a.append(...i),onRow:i=>{const s=a.on("row",U(i));return async()=>{await s()}}})}async grid(e){const t=e.skin??this.defaultSkin,r=await this.theme(t),a={columns:e.columns??4,tileWidth:e.tileWidth??48,tileHeight:e.tileHeight??48,gap:e.gap??4},i=await this.flash.overlay.group({x:e.x??0,y:e.y??0,...e.parent?{parent:S(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}),s=new Set,o=[],l=async c=>{for(const u of o.splice(0))await u.remove();const h=Ot({count:c.length,...a});for(const u of h){const d=c[u.index],g=await this.flash.overlay.button(d.label??"",{parent:i,x:u.x,y:u.y,width:u.width,height:u.height,cornerRadius:r.cornerRadius,fill:d.color??(t==="game"?r.light:{color:r.ink,alpha:.9}),hoverFill:d.color??(t==="game"?16777215:r.line),pressedFill:d.color??r.accent,stroke:r.line,...d.disabled===void 0?{}:{disabled:d.disabled},font:{family:r.font,size:r.size-2,color:t==="game"?r.ink:r.light}});g.on("click",()=>s.forEach(w=>w(d.value,u.index))),o.push(g),d.image!==void 0&&o.push(await this.picture(d.image,{parent:i,x:u.x+V,y:u.y+V,width:u.width-V*2,height:u.height-V*2},w=>Ne(`on the grid tile ${d.value}`,w)))}};return await l(e.items),this.widget(i,t,{setItems:l,onSelect:c=>(s.add(c),async()=>{s.delete(c)})})}async image(e,t={}){const r=t.skin??this.defaultSkin,a=await this.theme(r),i=await this.flash.overlay.group({x:t.x??0,y:t.y??0,...t.parent?{parent:S(t.parent)}:{},...t.visible===void 0?{}:{visible:t.visible}}),s=new Set;let o=e,l=null,c=!1;const h=async()=>{if(c)return;c=!0;const d=t.width??D[r],g=t.height??D[r],w=await this.flash.overlay.group({parent:i,...t.centered===!0?{x:-Math.round(d/2),y:-Math.round(g/2)}:{}});l=w,await this.flash.overlay.rect({parent:w,width:d,height:g,cornerRadius:a.cornerRadius,fill:r==="game"?{color:a.light,alpha:.6}:{color:a.ink,alpha:.6},stroke:a.line}),!(t.alt===void 0||t.alt==="")&&await this.flash.overlay.text(t.alt,{parent:w,x:Math.round(d/2),y:Math.round(g/2),centered:!0,font:{family:a.font,size:a.size-1,color:a.muted}})},u=await this.picture(o,{parent:i,...t.width===void 0?{}:{width:t.width},...t.height===void 0?{}:{height:t.height},...t.centered===void 0?{}:{centered:t.centered},...t.alpha===void 0?{}:{alpha:t.alpha}},d=>{Ne(t.alt===void 0?"drawn on its own":`of ${t.alt}`,d),h().catch(B),s.forEach(g=>g(d))});return this.widget(i,r,{source:()=>o,setSource:async d=>{o=d;const g=l;l=null,c=!1,await(g==null?void 0:g.remove()),await u.update({url:d})},onFailed:d=>{const g=U(d);return s.add(g),async()=>{s.delete(g)}}})}async scroll(e={}){const t=e.skin??this.defaultSkin,r=await this.theme(t),a=e.width??220,i=e.height??120,s=e.step??32,o=await this.flash.overlay.panel({x:e.x??0,y:e.y??0,width:a,height:i,titleHeight:0,draggable:!1,cornerRadius:r.cornerRadius,fill:t==="game"?{color:r.light,alpha:.9}:{color:r.ink,alpha:.85},stroke:r.line,...e.parent?{parent:S(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}),l=await this.flash.overlay.group({parent:o,x:0,y:0});let c=e.contentHeight??i,h=0;const u=async d=>{h=_r({contentHeight:c,viewHeight:i,offset:d,trackHeight:i}).offset,await l.update({y:-h})};for(const[d,g,w]of[["^",-s,0],["v",s,i-16]])(await this.flash.overlay.button(d,{parent:o,x:a-16,y:w,width:14,height:14,cornerRadius:Math.min(3,r.cornerRadius),...ie(r,!1),font:{family:r.font,size:r.size-2,bold:!0,color:t==="game"?r.ink:r.light}})).on("click",()=>{u(h+g)});return this.widget(o,t,{body:l,offset:()=>h,scrollTo:u,setContentHeight:async d=>{c=d,await u(h)}})}async tooltip(e={}){const t=await this.bubble(e);return e.target&&this.explain(t,S(e.target)),t}async bubble(e){const t=e.skin??this.defaultSkin,r=e.text??"";if(t==="game"){const s=await this.clientTooltip(r,e);if(s)return s}const a=await this.theme(t),i=await this.flash.overlay.text(r,{x:e.x??0,y:e.y??0,visible:e.visible===!0,...e.parent?{parent:S(e.parent)}:{},background:t==="game"?{color:a.light,alpha:.95}:{color:a.ink,alpha:.92},padding:4,font:{family:a.font,size:a.size,color:t==="game"?a.ink:a.light}});return this.widget(i,t,{setText:s=>i.update({text:s}),showAt:async(s,o)=>{await i.update({x:s,y:o,visible:!0})}})}explain(e,t){const r=t.on("over",({x:s,y:o})=>{e.showAt(s+12,o-10).catch(B)}),a=t.on("out",()=>{e.hide().catch(B)}),i=t.onRemoved(()=>{e.remove().catch(B)});e.node.onRemoved(()=>{i(),r().catch(()=>{}),a().catch(()=>{})})}async progress(e={}){const t=e.skin??this.defaultSkin,r=await this.theme(t),a=e.width??200,i=e.height??16,s=await this.flash.overlay.group({x:e.x??0,y:e.y??0,...e.parent?{parent:S(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}});await this.flash.overlay.rect({parent:s,width:a,height:i,cornerRadius:r.cornerRadius,fill:t==="game"?r.light:{color:r.ink,alpha:.9},stroke:r.line});let o=Et(e.value??0);const l=await this.flash.overlay.rect({parent:s,width:Math.round(a*o),height:i,cornerRadius:r.cornerRadius,fill:r.accent}),c=await this.flash.overlay.text(e.label??"",{parent:s,x:Math.round(a/2),y:Math.round(i/2),centered:!0,font:{family:r.font,size:r.size-1,bold:!0,color:t==="game"?r.ink:r.light}});return this.widget(s,t,{value:()=>o,setValue:async h=>{o=Et(h),await l.update({width:Math.round(a*o)})},setLabel:h=>c.update({text:h})})}async colors(e={}){const t=e.skin??this.defaultSkin,r=e.columns??10,a=e.swatchWidth??24,i=e.swatchHeight??30,{values:s,indexes:o}=await this.palette(e.palette??1),l=new Set;let c=e.value??o[0]??0;const h=g=>{c=g,l.forEach(w=>w(g,s[g]??0))},u=Math.max(1,Math.ceil(o.length/r)),d=t==="game"?await this.clientColorTable({columns:r,rows:u,width:r*a,height:u*i,values:s,indexes:o,current:c,options:e,tell:h}):await this.swatchGrid({columns:r,swatchWidth:a,swatchHeight:i,values:s,indexes:o,current:c,options:e,tell:h});return this.widget(d,t,{value:()=>c,onPick:g=>(l.add(g),async()=>{l.delete(g)})})}async paletteValues(e="game"){const{values:t,indexes:r}=await this.palette(e);return r.map(a=>t[a]??0)}prompt(e,t={}){let r=()=>{};const a=new Promise(c=>{r=c});let i=!1,s=null;const o=async c=>{if(i)return;i=!0,this.popups.delete(l);const h=s;s=null,h&&await h().catch(()=>{}),r(c)},l=()=>o(null);return this.popups.add(l),(async()=>{const c=t.skin??this.defaultSkin,h=t.width??Tt[c],u=await this.window({skin:c,title:t.title??"",x:t.x??we.x,y:t.y??we.y,width:h,height:Fr[c],closable:!0}),d=u.body,g=u.bodyWidth-2*M;await this.label(e,{skin:c,parent:d,x:M,y:M});const w=await this.input({skin:c,parent:d,x:M,y:M+ze,width:g,...t.value===void 0?{}:{value:t.value},...t.placeholder===void 0?{}:{placeholder:t.placeholder},...t.maxLength===void 0?{}:{maxLength:t.maxLength}}),f={width:Math.min(ge[c],Math.floor((g-M)/2))},p=u.bodyHeight-M-D[c],m=await this.button(t.cancelLabel??"Cancel",{skin:c,parent:d,x:M,y:p,width:f.width}),y=await this.button(t.okLabel??"OK",{skin:c,parent:d,x:u.bodyWidth-M-f.width,y:p,width:f.width,primary:!0});if(s=async()=>{await u(),await this.flash.overlay.focusGame().catch(()=>{})},i){const v=s;s=null,await v();return}w.onSubmit(v=>{o(v)}),y.onClick(()=>{o(w.value())}),m.onClick(()=>{o(null)}),u.onClose(()=>{o(null)}),await w.focus()})().catch(c=>{console.error(`phantom.ui.prompt could not be drawn: ${Y(c)}`),o(null)}),Object.assign(a,{close:l})}choose(e,t,r={}){const a=t.map(u=>typeof u=="string"?{value:u,label:u}:u);let i=()=>{};const s=new Promise(u=>{i=u});let o=!1,l=null;const c=async u=>{if(o)return;o=!0,this.popups.delete(h);const d=l;l=null,d&&await d().catch(()=>{}),i(u)},h=()=>c(null);return this.popups.add(h),(async()=>{const u=r.skin??this.defaultSkin,d=r.width??Tt[u],g=Math.max(1,r.rows??Ar),w=Math.min(a.length||1,g)*Pr+2*M,f=await this.window({skin:u,title:r.title??"",x:r.x??we.x,y:r.y??we.y,width:d,height:M*4+ze+w+D[u],closable:!0}),p=f.body,m=f.bodyWidth-2*M;await this.label(e,{skin:u,parent:p,x:M,y:M});const y=await this.list({skin:u,parent:p,x:M,y:M+ze,width:m,height:w,rows:a.map(R=>R.label)}),v={width:Math.min(ge[u],Math.floor((m-M)/2))},T=await this.button(r.cancelLabel??"Cancel",{skin:u,parent:p,x:f.bodyWidth-M-v.width,y:f.bodyHeight-M-D[u],width:v.width});if(l=async()=>{await f()},o){const R=l;l=null,await R();return}y.onRow(R=>{var O;c(((O=a[R])==null?void 0:O.value)??null)}),T.onClick(()=>{c(null)}),f.onClose(()=>{c(null)})})().catch(u=>{console.error(`phantom.ui.choose could not be drawn: ${Y(u)}`),c(null)}),Object.assign(s,{close:h})}async notice(e,t={}){const r=t.skin??this.defaultSkin,a=await this.theme(r),i=t.seconds??6,s=t.width??Rr,o=Math.max(_e,(r==="game"?s-Cr:s)-2*ae),l=De(e,At(o,a.size)),c=await this.stageSize(),h={x:t.x??(c.width?c.width-s-je:je),y:t.y??je},u=await this.window({skin:r,title:t.title??"",x:h.x,y:h.y,width:s,height:2*ae+(l.length+1)*_e+(r==="game"?30:24),closable:t.closable!==!1,...t.draggable===void 0?{}:{draggable:t.draggable}}),d=Math.max(_e,Math.min(o,u.bodyWidth-2*ae)),g=At(d,a.size),w=await this.label(De(e,g).join(`
2
+ `),{skin:r,parent:u.body,x:ae,y:ae}),f=new Set;let p=!1;const m=i>0?setTimeout(()=>{u().catch(()=>{})},i*1e3):null,y=()=>{if(!p){p=!0,m&&clearTimeout(m);for(const v of[...f])U(v)()}};return u.onClose(y),u.node.onRemoved(y),this.widget(u.node,r,{setText:async v=>{await w.setText(De(v,g).join(`
3
+ `))},onClose:v=>(f.add(v),async()=>{f.delete(v)})},async()=>y())}async tag(e,t,r={}){const a=r.skin??this.defaultSkin,i=await this.theme(a),s=await this.anchorOf(e);if(!s)throw new TypeError(typeof e=="number"?`No player with user id ${e} is in the room, so there is nothing to tag`:"Expected a player id, something from phantom.flash.entities, or a place in the client");const o=r.key??(typeof e=="number"?`player:${e}`:null),l=o?this.tags.get(o):void 0;l&&await l().catch(()=>{});const c=await this.flash.overlay.text(t,{anchor:{place:s,x:r.offsetX??0,y:r.offsetY??(typeof e=="number"?$r:0)},centered:!0,font:{family:i.font,size:r.heading===!0?i.size+3:i.size,bold:r.heading===!0,color:r.colour??(a==="game"?i.ink:i.light)},...r.background===!1?{outline:0}:{background:a==="game"?{color:i.light,alpha:.9}:{color:i.ink,alpha:.8},padding:4}}),h=r.seconds&&r.seconds>0?setTimeout(()=>{c.remove().catch(()=>{})},r.seconds*1e3):null,u=this.widget(c,a,{setText:d=>c.update({text:d})},async()=>{h&&clearTimeout(h),o&&this.tags.get(o)===u&&this.tags.delete(o)});return o&&this.tags.set(o,u),u}async tipOn(e,t,r={}){const a=r.skin??this.defaultSkin,i=await this.tooltip({skin:a,text:typeof t=="string"?t:""}),s=this.piece(e),o={x:r.offsetX??xt.x,y:r.offsetY??xt.y},l=async d=>{typeof t!="string"&&await i.setText(await t());const g=Ur(d)??await this.mouse();await i.showAt(g.x+o.x,g.y+o.y)},c=await s.on("rollOver",d=>{l(d).catch(g=>{console.error(`phantom.ui.tipOn could not show the tooltip: ${Y(g)}`)})}),h=await s.on("rollOut",()=>{i.hide().catch(()=>{})});let u=!1;return async()=>{u||(u=!0,await c().catch(()=>{}),await h().catch(()=>{}),await i.remove().catch(()=>{}))}}async stageSize(){const e=this.bridge.stage(),[t,r]=await Promise.all([e.at("stageWidth").get().catch(()=>null),e.at("stageHeight").get().catch(()=>null)]);return{width:me(t),height:me(r)}}onStageResize(e){let t=!0,r=null;return(async()=>{const i=await this.bridge.stage().listen("resize",()=>{this.stageSize().then(s=>U(e)(s)).catch(()=>{})});if(!t){await i();return}r=i})().catch(i=>{console.error(`phantom.ui.onStageResize could not hear the stage: ${Y(i)}`)}),()=>{t=!1;const i=r;r=null,i&&i().catch(()=>{})}}places(){const e=Object.keys(bt);return[vt,...e,...Wr]}place(e){if(e===vt)return this.bridge.stage();const t=bt[e];return t?this.bridge.definition(t.className).at(...t.path):this.bridge.definition(F.guiManager).at("mainHud",e)}async attach(e,t){const r=S(t);return await this.flash.overlay.attach(this.placeOf(e),r),()=>r.remove()}async replace(e,t){const r=S(t);return await this.flash.overlay.replace(this.placeOf(e),r),()=>r.remove()}async hide(e){const t=await this.flash.hide(this.placeOf(e)),r=async()=>{this.drawn.delete(r),await t()};return this.drawn.add(r),r}piece(e,...t){return this.pieceOf(this.placeOf(e),t)}async feed(e,t,r={}){return typeof t=="function"?this.deferredFeed(e,t,r):this.insideFeed(e,t,r)}async insideFeed(e,t,r){if(!Object.keys(t).length)throw new TypeError(`A feed of ${e} names no argument to change`);let a=null,i=0;const s=await this.flash.hook(e,{phase:"enter",capture:{args:!0},replaceArgs:t,...r.when===void 0?{}:{when:r.when},...r.first===void 0?{}:{first:r.first},...r.every===void 0?{}:{every:r.every},...r.perFrame===void 0?{}:{perFrame:r.perFrame}},o=>{i+=1,a={method:e,call:o.call,args:[...o.argList],named:{...o.args},on:this.pieceOf(this.bridge.stage(),[])}});return this.feedOf(e,!0,s,()=>i,()=>a)}async deferredFeed(e,t,r){if(r.deferred!==!0)throw new TypeError(`A feed of ${e} was given a function, which cannot run inside the call: the client's method is skipped and run again once the function answers. A builder whose result the client uses in the same breath comes up empty that way. Give the arguments themselves to change them inside the call, or set "deferred" to say the waiting is understood.`);let a=null,i=0;const s=async c=>{i+=1;const h={method:e,call:c.call,args:[...c.argList],named:{...c.args},on:this.pieceOf(ne(c.self)??this.bridge.stage(),[])};a=h;const u=await t(h);if(!u){await c.original();return}const d=[...h.args];for(const[g,w]of Object.entries(u)){const f=/^\d+$/.test(g)?Number(g):c.hook.parameters.findIndex(p=>p.name===g);if(f<0||f>=d.length){const p=c.hook.parameters.map(m=>m.name).join(", ");throw new TypeError(`${e} has no argument "${g}" (its arguments: ${p})`)}d[f]=w}await c.original(...d)},o={};r.when!==void 0&&(o.when=r.when),r.first!==void 0&&(o.first=r.first),r.every!==void 0&&(o.every=r.every),r.sequential!==void 0&&(o.sequential=r.sequential),r.perFrame!==void 0&&(o.perFrame=r.perFrame),r.returns!==void 0&&(o.returns=r.returns);const l=await this.flash.override(e,s,o);return this.feedOf(e,!1,l,()=>i,()=>a)}feedOf(e,t,r,a,i){const s=async()=>{this.drawn.delete(s),await r()};this.drawn.add(s);const o=s;return Object.defineProperty(o,"method",{value:e,enumerable:!0}),Object.defineProperty(o,"inside",{value:t,enumerable:!0}),Object.defineProperty(o,"calls",{get:a,enumerable:!0}),Object.defineProperty(o,"last",{value:i,enumerable:!0}),o}screens(){return Object.keys(kt)}onScreen(e,t){const r=kt[e];let a=!0;const i=[];return(async()=>{for(const[o,l]of[[r.open,!0],[r.close,!1]]){const c=await this.flash.hook(o,{phase:l?"exit":"enter",capture:{args:[]}},()=>t({name:e,open:l,spot:r.spot}));if(!a){await c();return}i.push(c)}})().catch(o=>{console.error(`phantom.ui.onScreen could not hook ${e}: ${Y(o)}`)}),()=>{a=!1;for(const o of i.splice(0))o().catch(()=>{})}}async clear(){for(const e of[...this.popups])await e().catch(()=>{});for(const e of[...this.drawn])await e().catch(()=>{})}pieceOf(e,t){const r=ne(e);if(!r)throw new TypeError("Expected a place in the client, or one of Phantom's spots");const a=r.at(...t);return{place:a,at:(...s)=>this.pieceOf(a,s),exists:async()=>{try{const s=await a.get();return s!=null}catch{return!1}},get:async(...s)=>{try{const o=await a.at(...s).get();return P(this.bridge,o)??null}catch{return null}},set:(s,o)=>a.at(...typeof s=="string"?[s]:s).set(o),read:async(...s)=>{const o=await Promise.all(s.map(c=>a.at(c).get().catch(()=>null))),l={};return s.forEach((c,h)=>{l[c]=P(this.bridge,o[h]??null)}),l},call:async(s,...o)=>{const l=await Q(this.bridge,o);return P(this.bridge,await a.at(s).call(...l))},on:async(s,o)=>{const l=await a.listen(s,h=>o(P(this.bridge,h))),c=async()=>{this.drawn.delete(c),await l()};return this.drawn.add(c),c},attach:s=>this.attach(a,s),replace:s=>this.replace(a,s),hide:()=>this.hide(a),use:()=>C(this.bridge,a)}}widget(e,t,r,a){let i=null;const s=()=>(i??=(async()=>{this.drawn.delete(o),a&&await a().catch(()=>{})})(),i),o=async()=>{await e.remove(),await s()};this.drawn.add(o),e.onRemoved(()=>{s()});const l={skin:t,node:e,move:(c,h)=>e.update({x:c,y:h}),show:()=>e.show(),hide:()=>e.hide(),remove:o,...r};for(const[c,h]of Object.entries(l))Object.defineProperty(o,c,{value:h,enumerable:!0,configurable:!0});return o}async picture(e,t,r){const a=await this.flash.overlay.image(e,t);return a.onFailed(U(r)),a}box(e,t){return{x:e.x??0,y:e.y??0,width:e.width??t.width,height:e.height??t.height,...e.parent?{parent:S(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}}async anchorOf(e){if(typeof e=="number"){const a=(await this.flash.entities.players()).find(i=>i.id===String(e));return a?a.place:null}if(typeof e=="string")return this.place(e);if(st(e))return e;const t=e.place;return st(t)?t:null}async mouse(){const e=this.bridge.stage(),[t,r]=await Promise.all([e.at("mouseX").get().catch(()=>null),e.at("mouseY").get().catch(()=>null)]);return{x:me(t),y:me(r)}}placeOf(e){return typeof e=="string"?this.place(e):e}maker(){if(!this.symbolMaker){const e=this.bridge.definition(F.definitionByName).get().then(t=>{if(!t)throw new TypeError("This client has no GETDEFINITIONBYNAME");return t});e.catch(()=>{this.symbolMaker===e&&(this.symbolMaker=null)}),this.symbolMaker=e}return this.symbolMaker}async nodeObject(e){const t=await new J(this.bridge,{kind:"overlay"},[]).at("getChildByName").call(`phantomNode${e.node}`);if(!t)throw new TypeError(`Overlay node ${e.node} is not drawn straight into the overlay, so it cannot be dressed`);return t}async adopt(e,t){const r=t.parent;if(r&&qr(r))throw new Error("What it was to be drawn in was taken off the screen before it could be put there");await e.update(t)}async waitFor(e,t=this.readyTimeoutMs){const r=Date.now()+Math.max(0,t);for(;;){const a=await this.status(),i=(!e.art||a.art)&&(!e.palettes||a.palettes),s=r-Date.now();if(i||s<=0||this.bridge.state==="closed")return a;await new Promise(o=>setTimeout(o,Math.min(Or,s)))}}async artLoaded(){return this.known.art||(this.known.art=await this.hasSymbol("PopupSkin")),this.known.art}async palettesLoaded(){if(!this.known.palettes)try{const e=await this.bridge.definition(F.palette).at("gamePalette").get();this.known.palettes=Array.isArray(e)&&e.length>0}catch{}return this.known.palettes}clientFont(){if(!this.gameFont){const e=this.bridge.definition(F.fonts),t=this.known.palettes,r=(async()=>{for(const a of[["defaultFontFormat","font"],["defaultFont","fontName"]])try{const i=await e.at(...a).get();if(typeof i=="string"&&i.length>0)return i}catch{}return ye})();r.then(a=>{a===ye&&!t&&this.gameFont===r&&(this.gameFont=null)},()=>{this.gameFont===r&&(this.gameFont=null)}),this.gameFont=r}return this.gameFont}async frameOnly(e){const t=await e.at("numChildren").get()??0;for(let r=0;r<Math.min(t,32);r+=1){const a=await e.at("getChildAt").call(r);try{await a.at("name").get()!=="ba"&&await a.at("visible").set(!1)}finally{await this.bridge.release([a]).catch(()=>{})}}}async dressWindow(e,t){const a=await(await this.maker()).at("apply").call(null,["PopupSkin",!1]),i=[a];try{const s=a.at("ba"),[o,l]=await Promise.all([pe(s.at("t","height")),pe(s.at("b","height"))]),c=jr(t,o,l);await Promise.all([s.at("m","height").set(c.middle),s.at("m","y").set(c.middleY),s.at("t","y").set(c.topY),s.at("b","y").set(c.bottomY)]),await this.frameOnly(a);const h=await this.boundsOf(s,a),u={width:Math.round(h.width),height:Math.round(h.height)},d=await this.parchmentOf(a,h).catch(()=>null),g=zr(u,d);await Promise.all([a.at("x").set(Math.round(-h.x-g.panel.x)),a.at("y").set(Math.round(-h.y-g.panel.y))]);const w=await this.nodeObject(e);i.push(w),await w.at("addChildAt").call(a,0);const f=await this.frameClose(w,g).catch(()=>null);return f&&i.push(f),{...u,layout:g,close:f,held:i}}catch(s){throw await this.bridge.release(i).catch(()=>{}),s}}async frameClose(e,t){const a=await(await this.maker()).at("apply").call(null,["closeBtn",!1]);try{const i=await this.boundsOf(a,a);if(i.width<=0||i.height<=0)throw new TypeError("The close button has no size");const s=Math.min(1,(t.titleHeight-2)/i.height);return await Promise.all([a.at("scaleX").set(s),a.at("scaleY").set(s),a.at("x").set(Math.round(t.panel.width-2-(i.x+i.width)*s)),a.at("y").set(Math.round((t.titleHeight-i.height*s)/2-i.y*s))]),await e.at("addChild").call(a),a}catch(i){throw await this.bridge.release([a]).catch(()=>{}),i}}async boundsOf(e,t){const r=await e.at("getBounds").call(t);try{const[a,i,s,o]=await Promise.all(["x","y","width","height"].map(l=>pe(r.at(l))));return{x:a,y:i,width:s,height:o}}finally{await this.bridge.release([r]).catch(()=>{})}}async parchmentOf(e,t){const r=Math.ceil(t.width),a=Math.ceil(t.height);if(r<=0||a<=0||r>2048||a>2048)return null;const i=await this.bridge.construct("flash.display.BitmapData",r,a,!0,0);try{await i.at("draw").call(e,new ke("flash.geom.Matrix",[1,0,0,1,-t.x,-t.y]));const s=await i.at("getPixel32").call(Math.floor(r/2),Math.floor(a/2));if(typeof s!="number"||s>>>24!==255)return null;const o=await i.at("getColorBoundsRect").call(pt,(s&pt)>>>0,!0);try{const[l,c,h,u]=await Promise.all(["x","y","width","height"].map(d=>pe(o.at(d))));return{x:l,y:c,width:h,height:u}}finally{await this.bridge.release([o]).catch(()=>{})}}finally{await i.at("dispose").call().catch(()=>{}),await this.bridge.release([i]).catch(()=>{})}}async clientTooltip(e,t){let r;try{r=await this.symbol("Tooltip",{skin:"game",x:t.x??0,y:t.y??0,visible:t.visible===!0,...t.parent?{parent:t.parent}:{}})}catch{return null}const a=async i=>{await r.object.at("setToolTipText").call(i)};try{e&&await a(e)}catch{return await r.remove(),null}return Object.assign(r,{setText:a,showAt:async(i,s)=>{await r.node.update({x:i,y:s,visible:!0})}})}async palette(e){const t=await this.waitFor({palettes:!0}),r=this.bridge.definition(F.palette),a=t.palettes?await r.at("gamePalette").get():null,i=St(a);if(!i.length)throw new Error(`The game has not loaded its colour palettes yet: waited ${Math.round(this.readyTimeoutMs/1e3)} seconds`);if(e==="game")return{values:i,indexes:i.map((o,l)=>l)};const s=St(await r.at(e===1?"avatarPalette1":"avatarPalette2").get());return{values:i,indexes:s.length?s:i.map((o,l)=>l)}}async clientColorTable(e){const t=await this.flash.overlay.group({x:e.options.x??0,y:e.options.y??0,visible:!1});try{const r=await this.bridge.construct(F.colorTable);await r.at("init").call(0,e.width,e.height,e.columns,e.rows,e.values,e.indexes,e.current,(i,s)=>e.tell(Number(s)),-1);const a=await this.nodeObject(t);await a.at("addChild").call(r),await this.bridge.release([a,r]).catch(()=>{}),await this.adopt(t,{...e.options.parent?{parent:S(e.options.parent)}:{},visible:e.options.visible!==!1})}catch(r){throw await t.remove(),r}return t}async swatchGrid(e){const t=await this.flash.overlay.group({x:e.options.x??0,y:e.options.y??0,...e.options.parent?{parent:S(e.options.parent)}:{},...e.options.visible===void 0?{}:{visible:e.options.visible}}),r=Ot({count:e.indexes.length,columns:e.columns,tileWidth:e.swatchWidth,tileHeight:e.swatchHeight,gap:1}),a={color:Ye.line,alpha:.6},i={color:Ye.light,width:2},s=new Map;let o=e.current;for(const l of r){const c=e.indexes[l.index],h=await this.flash.overlay.button("",{parent:t,x:l.x,y:l.y,width:l.width,height:l.height,cornerRadius:2,fill:e.values[c]??0,hoverFill:e.values[c]??0,stroke:c===o?i:a});s.set(c,h),h.on("click",()=>{var u;const d=o;o=c,d!==c&&((u=s.get(d))==null||u.update({stroke:a}).catch(B),h.update({stroke:i}).catch(B)),e.tell(c)})}return t}openPopup(e,t,r,a,i){let s=()=>{};const o=new Promise(f=>{s=f});let l=null,c=!1,h=null;const u=f=>{c||(c=!0,h&&clearTimeout(h),h=null,this.popups.delete(g),s(f))},d=()=>{c||h||(h=setTimeout(()=>u(i),Br))},g=async()=>{const f=l;l=null,u(i),f&&await f.at("destroy").call().catch(()=>{})};this.popups.add(g);const w=Lr(e,t,r);return(async()=>{await this.waitFor({art:!0});const f=this.bridge.definition(r.layer==="load"?F.loadProgress:F.guiManager).at(r.layer==="load"?"loadLayer":"guiLayer"),p=[];for(const y of w.args){if(y!==null&&typeof y=="object"){if(y.slot==="layer")p.push(await f.get());else if(y.slot==="callback")p.push((...v)=>u(a(v[0]??null)));else{const v=await this.maker();p.push(await v.at("apply").call(null,["PopupSkin",!1]))}continue}p.push(y)}const m=await this.bridge.construct(w.className,...p);l=m,await m.at("closeCallback").set(()=>d()).catch(()=>{})})().catch(f=>{this.popups.delete(g),c||(c=!0,s(i)),console.error(`phantom.ui.popup.${e} could not open: ${Y(f)}`)}),Object.assign(o,{close:g})}}class Dr{constructor(e,t){this.open=e,this.closeEverything=t}open;closeEverything;message(e,t={}){return this.open("message",e,t,()=>{},void 0)}ok(e,t={}){return this.open("ok",e,t,()=>{},void 0)}okCancel(e,t={}){return this.open("okCancel",e,t,He,null)}yesNo(e,t={}){return this.open("yesNo",e,t,He,null)}titled(e,t={}){return this.open("titled",e,t,()=>{},void 0)}parchment(e,t={}){return this.open("parchment",e,t,He,null)}async closeAll(){await this.closeEverything()}}const Br=50,Mt={click:"click",down:"mouseDown",up:"mouseUp",over:"rollOver",out:"rollOut"},Wr=["chatBar","chatHist","chatTxt","sendChatBtn","safeChatBtn","actionsBtn","emotesBtn","denBtn","worldMapBtn","buddyListBtn","newsBtn","partyBtn","mySettingsBtn","money","zoneName"];function S(n){if(!n)throw new TypeError("Expected a widget or an overlay node");return typeof n.node=="number"?n:n.node}function qr(n){let e=!1;return n.onRemoved(()=>{e=!0})(),e}function ie(n,e){return e?{fill:n.accent,hoverFill:{color:n.accent,alpha:.85},pressedFill:{color:n.accent,alpha:.7},stroke:n.line}:n.skin==="game"?{fill:n.light,hoverFill:16777215,pressedFill:n.line,stroke:n.line}:{fill:{color:n.ink,alpha:.92},hoverFill:n.line,pressedFill:{color:n.line,alpha:.7},stroke:n.line}}function He(n){if(n!==null&&typeof n=="object"&&!Array.isArray(n)){const e=n.status;if(typeof e=="boolean")return e}return null}function Et(n){return Number.isFinite(n)?Math.min(1,Math.max(0,n)):0}function Y(n){return n instanceof Error?n.message:String(n)}async function pe(n){const e=await n.get();if(typeof e!="number"||!Number.isFinite(e))throw new TypeError(`Expected a number at ${n.path.join(".")}, and read ${String(e)}`);return e}function St(n){return Array.isArray(n)?n.map(e=>typeof e=="number"?e:0):[]}function De(n,e){const t=[];for(const r of n.split(`
4
+ `)){let a="";for(const i of r.split(/\s+/).filter(Boolean))a?a.length+1+i.length<=e?a=`${a} ${i}`:(t.push(a),a=i):a=i;t.push(a)}return t.length?t:[""]}function At(n,e){return Math.max(8,Math.floor(n/Math.max(1,e*.55)))}function Ur(n){if(!n||typeof n!="object"||Array.isArray(n))return null;const{stageX:e,stageY:t}=n;return typeof e!="number"||typeof t!="number"?null:{x:e,y:t}}function me(n){return typeof n=="number"&&Number.isFinite(n)&&n>0?n:0}function be(n){return n instanceof A?{code:n.code,message:n.message,...n.stack?{stack:n.stack}:{}}:n instanceof Error?{code:"FAILED",message:n.message||n.name,...n.stack?{stack:n.stack}:{}}:{code:"FAILED",message:N(n)}}function Vt(n){const e=n&&typeof n.code=="string"&&n.code?n.code:"FAILED";return new A(e,(n==null?void 0:n.message)||"Phantom could not do this")}function le(n){return K(n,new WeakMap)}function K(n,e){if(ln(n))return K(n.value,e);if(typeof n=="function"||typeof n=="symbol")return;if(typeof n!="object"||n===null)return n;const t=cn(n);if(e.has(t))return e.get(t);if(t instanceof Date||t instanceof RegExp||t instanceof ArrayBuffer||ArrayBuffer.isView(t))return t;if(Array.isArray(t)){const a=[];e.set(t,a);for(const i of t)a.push(K(i,e));return a}if(t instanceof Map){const a=new Map;e.set(t,a);for(const[i,s]of t)a.set(K(i,e),K(s,e));return a}if(t instanceof Set){const a=new Set;e.set(t,a);for(const i of t)a.add(K(i,e));return a}if(t instanceof Error)return be(t);const r={};e.set(t,r);for(const[a,i]of Object.entries(t)){const s=K(i,e);s!==void 0&&(r[a]=s)}return r}function N(n){if(typeof n=="string")return n;if(n instanceof Error)return n.stack||`${n.name}: ${n.message}`;if(n===void 0)return"undefined";if(typeof n=="function")return`[Function ${n.name||"anonymous"}]`;if(typeof n=="symbol"||typeof n=="bigint")return n.toString();try{const e=new WeakSet,t=JSON.stringify(le(n),(r,a)=>{if(typeof a=="object"&&a!==null){if(e.has(a))return"[Circular]";e.add(a)}return typeof a=="bigint"?`${a}n`:a});return Pt(t??String(n))}catch{return Pt(String(n))}}const Be=1e4;function Pt(n){return n.length>Be?`${n.slice(0,Be)}… (${n.length-Be} more)`:n}const Vr=["log","info","warn","error"];function Gr(n,e){const t=new Map;let r=!1;for(const a of Vr){const i=n[a].bind(n);t.set(a,i),n[a]=(...s)=>{if(i(...s),!r){r=!0;try{e(a,s.map(N))}finally{r=!1}}}}return()=>{for(const[a,i]of t)n[a]=i}}function Yr(n,e,t){return new fr(new xn(Kr(n,e),{firstId:t}))}function Kr(n,e){const t=new Set;let r=null;const a=i=>{for(const s of t)s(i)};return{send(i){n.call("flash.request",e,[i]).catch(s=>{const o=Xr(i,s);o?a(o):n.log("warn",[`A Flash request was refused: ${N(s)}`])})},onMessage(i){return t.add(i),r??=n.subscribe("flash.messages",e,{event(s){const[o]=s;typeof o=="string"&&a(o)},ended(s){r=null,s&&n.log("warn",[`Flash stopped answering: ${s.message}`])}}),()=>{t.delete(i),!t.size&&r&&(r(),r=null)}}}}function Xr(n,e){let t;try{t=Nt(n)}catch{return null}if(typeof(t==null?void 0:t.id)!="number")return null;const r=e instanceof A?e.code:"FAILED",a=e instanceof Error?e.message:N(e);return te({kind:"result",id:t.id,ok:!1,error:{name:r,message:a,errorId:0}})}function Jr(n){let e=null,t=null;const r=()=>{const a=n.flash();return e??=new br({flash:a.bridge,content:Qr(n.port,n.game)},a),e};return{avatar:{view:()=>n.flash().bridge.definition(pr.avatarManager).at("playerAvatarWorldView").get()},adventures:{record:()=>Zr(n.remote)},realtime:{join:(a,i)=>Jt(n.remote.realtime,a,i),stayIn:(a,i,s)=>Xt(n.remote.realtime,a,i,s)},customRooms:{prop:(a,i)=>Kt(n.remote.customRooms,a,i),object:(a,i)=>Yt(n.remote.customRooms,a,i),character:(a,i)=>Gt(n.remote.customRooms,a,i)},room:{surfaces:()=>on(n.flash().bridge)},content:{load:(a,i)=>r().load(a,i),replaceOnScreen:(a,i,s)=>r().replaceOnScreen(a,i,s)},ui:()=>{const a=n.flash();return t??=new Hr({flash:a.bridge},a),t},recipes:{chatShortcuts:async a=>lr(await We(n),a),customChatBox:async a=>cr(await We(n),a),chatHistoryPanel:async a=>ur(await We(n),a)}}}function Qr(n,e){const t=()=>{throw new A("NOT_SUPPORTED","Only holding and releasing content happen in a frame")};return{hold:r=>n.call("content.hold",e,[r]),release:r=>n.call("content.release",e,[r]),replace:t,restore:t,list:t,observe:t}}function Zr(n){const e=Date.now(),t=[];let r=null,a=null;const i=()=>{r===null&&n.adventures.current().then(o=>r??=(o==null?void 0:o.scriptDefId)??null).catch(()=>{}),a===null&&n.adventures.actor("diff_level").then(o=>a??=(o==null?void 0:o.state)??null).catch(()=>{})};i();const s=n.adventures.onStep(({time:o,...l})=>{i(),t.push({...l,at:o-e})});return{stop:()=>(s(),{version:1,scriptDefId:r,difficulty:a,steps:[...t]})}}async function We(n){const e=n.flash(),{remote:t}=n,r=[...await t.chat.recent()],a=new Map;for(const i of await t.room.players.list())a.set(i.userId,i);return t.room.players.onEnter(i=>a.set(i.userId,i)),t.room.players.onLeave(i=>a.delete(i.userId)),t.chat.onMessage(i=>r.push(i)),{flash:e,chat:{say:t.chat.say,phrase:t.chat.phrase,onMessage:t.chat.onMessage,recent:r},room:{players:{get:i=>a.get(i)??null}}}}function ea(n,e){const t={};for(const r of Object.keys(Qt)){const a=r.split(".");let i=t;for(const o of a.slice(0,-1))i=i[o]??={};const s=a[a.length-1];i[s]=Zt(r)?ra(n,e,r,tn(r)):na(n,e,r)}return Qe(t,"")}const ta=new Set(["then","toJSON","constructor","nodeType","tagName"]);function Qe(n,e){for(const[t,r]of Object.entries(Object.getOwnPropertyDescriptors(n))){const a=r.get||r.set?null:r.value;!a||typeof a!="object"||!r.writable||(n[t]=Qe(a,`${e}${t}.`))}return new Proxy(Object.freeze(n),{get(t,r,a){if(typeof r!="string"||r in t)return Reflect.get(t,r,a);if(!(ta.has(r)||r.startsWith("__v_")))throw new A("NOT_SUPPORTED",`phantom.${e}${r} is not in this Phantom's copy of the plugin SDK. Either the name is wrong, or Phantom is serving an older build of @phantomclient/plugin than this plugin was written against; building that package again gives every plugin the newer SDK.`)}})}function na(n,e,t){return(...r)=>n.call(`sdk:${t}`,e,r)}function ra(n,e,t,r){return(...a)=>{const i=a.findIndex(u=>typeof u=="function");if(i===-1&&en(t))throw new TypeError(`${t} takes a listener function`);const s=i===-1?null:a[i],o=i===-1?a:[...a.slice(0,i),...a.slice(i+1)];let l=null;const c=r==="awaited"?new Promise((u,d)=>{l=(g,w)=>{l=null,g?u(g):d(w)}}):null,h=n.subscribe(`sdk:${t}`,e,{event:u=>s==null?void 0:s(...u),started:()=>l==null?void 0:l(()=>h()),ended(u){if(l){l(null,Vt(u??{code:"FAILED",message:`${t} could not be started`}));return}u&&n.log("warn",[`${t} stopped: ${u.code}: ${N(u.message)}`])}},{args:o,...i===-1?{}:{listenerAt:i}});return c??h}}function Rt(n,e,t,r){const a=i=>({direction:r,...i==="*"?{}:{commands:[...i]}});return{send(i){return n.call("packets.send",e,[t,String(i)])},watch(i,s){return n.subscribe("packets.watch",e,{event(o){const l=ia(o,r);l&&s(Ut(l.text,l.direction))},ended:o=>{o&&n.log("warn",[`Watching the traffic stopped: ${o.message}`])}},{filter:a(i)})},on(i,s){return n.subscribe("packets.intercept",e,{event:()=>{},intercepted:o=>{aa(n,o,s)},ended:o=>{o&&n.log("warn",[`Hooking the traffic stopped: ${o.message}`])}},{filter:a(i)})}}}async function aa(n,e,t){let r;try{r=Ut(e.text,e.direction),await t(r)}catch(a){n.log("error",[`A traffic hook failed: ${N(a)}`]),n.verdict(e.requestId,!1,null);return}n.verdict(e.requestId,r.dropped,r.modified?r.encode():null)}function ia(n,e){const[t,r]=n;if(typeof t=="string")return{text:t,direction:Ct(r)?r:e};if(typeof t=="object"&&t!==null){const{text:a,direction:i}=t;if(typeof a=="string")return{text:a,direction:Ct(i)?i:e}}return null}function Ct(n){return n==="toServer"||n==="toClient"}function sa(n){const e=new Map,t=new Set;function r(i){var s,o;const l=i??dn(x.role);if(!l)throw new A("NO_GAME",((s=x.role)==null?void 0:s.kind)==="page"||((o=x.role)==null?void 0:o.kind)==="logic"?"This frame works with several games: name one, as ctx.phantom(id), from ctx.games()":"This frame is not bound to a game yet");let c=e.get(l);return c||(c=oa(n,l),e.set(l,c)),c}return{ctx:{get plugin(){return x.plugin},get granted(){return x.granted},get preferences(){return x.preferences},can:i=>la(x.granted.scopes,i),games:()=>[...x.games],onGames(i){return t.add(i),()=>t.delete(i)},phantom:r,storage:{get:i=>n.call("storage.get",null,[String(i)]),set:(i,s)=>n.call("storage.set",null,[String(i),s]),remove:i=>n.call("storage.remove",null,[String(i)]),keys:()=>n.call("storage.keys",null,[])},async fetch(i,s){const o=await n.call("fetch",null,[String(i),s??{}]);return ca(o)},copy:i=>n.call("copy",null,[String(i)]),notify:(i,s)=>n.call("notify",null,s===void 0?[String(i)]:[String(i),String(s)]),toast:(i,s)=>n.call("toast",null,[String(i),s??{}]),confirm:(i,s)=>n.call("confirm",null,[String(i),s??{}]),openUrl:i=>n.call("openUrl",null,[String(i)]),openPanel:(i,s)=>n.call("panel.open",(s==null?void 0:s.game)??null,[String(i)]),closePanel:(i,s)=>n.call("panel.close",(s==null?void 0:s.game)??null,[String(i)]),log:(...i)=>n.log("log",i.map(N))},notifyGames(i){for(const s of[...t])try{s([...i])}catch(o){n.log("error",[`An onGames listener failed: ${N(o)}`])}},dispose(){t.clear(),e.clear()}}}function oa(n,e){let t=null;const r=()=>{if(t)return t;if(x.flashIds===null)throw new A("PERMISSION_DENIED","game.flash needs the flash scope, which this plugin was not granted");return t=Yr(n,e,x.flashIds),t},a=ea(n,e),i=Jr({port:n,game:e,remote:a,flash:r}),s={...a,avatar:Object.freeze({...a.avatar,...i.avatar}),adventures:Object.freeze({...a.adventures,...i.adventures}),content:Object.freeze({...a.content,...i.content}),realtime:Object.freeze({...a.realtime,...i.realtime}),customRooms:Object.freeze({...a.customRooms,...i.customRooms}),room:Object.freeze({...a.room,...i.room}),recipes:Object.freeze(i.recipes),id:e,server:Rt(n,e,"toServer","toClient"),client:Rt(n,e,"toClient","toServer")};return Object.defineProperties(s,{flash:{enumerable:!0,get:r},ui:{enumerable:!0,get:i.ui}}),Qe(s,"")}function la(n,e){if(n.includes(e))return!0;if(!e.startsWith("network:"))return!1;const t=e.slice(8);return n.some(r=>{if(!r.startsWith("network:*."))return!1;const a=r.slice(9);return t.endsWith(a)&&t.length>a.length})}function ca(n){const e=n.body??"";return{status:n.status,ok:n.status>=200&&n.status<300,headers:n.headers??{},text:async()=>e,json:async()=>JSON.parse(e)}}const ha=6e4;function ua(n,e={}){const t=e.prefix??`f${Math.random().toString(36).slice(2,10)}-`,r=e.timeoutMs??ha;let a=0,i=!1;const s=new Map,o=new Map,l=()=>`${t}${a+=1}`;function c(f,p){if(!i)try{n({phantom:z,type:"log",level:f,values:p})}catch{}}function h(f,p,m){if(i)return Promise.reject(new A("FAILED","The frame was closed"));const y=l();return new Promise((v,T)=>{const R=setTimeout(()=>{s.delete(y),T(new A("TIMEOUT",`Phantom did not answer ${f} in ${r/1e3}s`))},r);s.set(y,{resolve:v,reject:T,timer:R});try{n({phantom:z,type:"call",id:y,method:f,game:p,args:le(m)})}catch(O){clearTimeout(R),s.delete(y),T(new A("FAILED",`${f} could not be sent: ${N(O)}`))}})}function u(f,p,m,y={}){if(i)return w(()=>{var T;return(T=m.ended)==null?void 0:T.call(m,{code:"FAILED",message:"The frame was closed"})}),()=>{};const v=l();o.set(v,m);try{n({phantom:z,type:"subscribe",id:v,topic:f,game:p,...y.filter?{filter:le(y.filter)}:{},...y.args?{args:le(y.args)}:{},...typeof y.listenerAt=="number"?{listenerAt:y.listenerAt}:{}})}catch(T){throw o.delete(v),new A("FAILED",`${f} could not be heard: ${N(T)}`)}return()=>{!o.delete(v)||i||n({phantom:z,type:"unsubscribe",id:v})}}function d(f,p,m){i||n({phantom:z,type:"verdict",requestId:f,drop:p,text:m})}function g(f){switch(f.type){case"call-result":{const p=s.get(f.id);return p?(s.delete(f.id),clearTimeout(p.timer),f.ok?p.resolve(f.value):p.reject(Vt(f.error)),!0):!1}case"event":{const p=o.get(f.subscription);return p?(w(()=>p.event(Array.isArray(f.args)?f.args:[])),!0):!1}case"subscribed":{const p=o.get(f.subscription);return p?(w(()=>{var m;return(m=p.started)==null?void 0:m.call(p)}),!0):!1}case"intercepted":{const p=o.get(f.subscription);return p!=null&&p.intercepted?(p.intercepted(f),!0):(d(f.requestId,!1,null),!!p)}case"subscription-ended":{const p=o.get(f.subscription);return p?(o.delete(f.subscription),w(()=>{var m;return(m=p.ended)==null?void 0:m.call(p,f.error)}),!0):!1}}}function w(f){try{f()}catch(p){c("error",[`A listener failed: ${N(p)}`])}}return{call:h,subscribe:u,verdict:d,log:c,receive:g,close(f){if(!i){i=!0;for(const p of s.values())clearTimeout(p.timer),p.reject(new A("FAILED",f));s.clear(),o.clear()}}}}function da(n,e,t=new Set){const r=new Set;for(const[i,s]of Object.entries((e==null?void 0:e.variables)??{}))!i.startsWith("--phantom-")||typeof s!="string"||(n.style.setProperty(i,s),r.add(i));for(const i of t)r.has(i)||n.style.removeProperty(i);const a=(e==null?void 0:e.mode)==="light"?"light":"dark";return n.dataset.theme=a,n.style.setProperty("color-scheme",a),r}const fa=2e3;function ga(n,e){fn(e.development??!1);let t=!1,r=new Set,a=null,i=null;function s(b){var k;t||(n.post(b),(k=e.tap)==null||k.call(e,b))}const o=ua(s),l=sa(o),c=l.ctx;rt(c);function h(b){var k;const $=be(b);try{s({phantom:z,type:"crash",error:$})}catch{}(k=n.view)==null||k.showError($,x.development)}let u;const g=new Promise(b=>u=b).then(async()=>{try{const b=e.definition,k=await(typeof b=="function"?b():b);return a=wa(k),!0}catch(b){return h(b),!1}}),w=g.then(async b=>{var k;if(!b||((k=x.role)==null?void 0:k.kind)!=="logic")return b;const $=se(a==null?void 0:a.widgets);if(s({phantom:z,type:"ready",implements:{pages:se(a==null?void 0:a.pages),panels:se(a==null?void 0:a.panels),commands:se(a==null?void 0:a.commands),commandViews:se(a==null?void 0:a.commandViews),...$.length?{widgets:$}:{}}}),!(a!=null&&a.setup))return!0;try{const I=await a.setup(c);typeof I=="function"&&(t?R(I):i=I)}catch(I){h(I)}return!0});function f(b){if(t||!nn(b))return;const k=b;switch(k.type){case"init":p(k);return;case"games":x.games=Array.isArray(k.games)?k.games:[],l.notifyGames(x.games);return;case"stop":H();return;case"mount":y(k);return;case"invoke":T(k);return;case"call-result":case"event":case"subscribed":case"subscription-ended":case"intercepted":o.receive(k);return}}function p(b){var k;n.root&&b.theme&&(r=da(n.root,b.theme,r)),Object.assign(x,{role:x.role??b.role??null,plugin:b.plugin??x.plugin,mode:((k=b.theme)==null?void 0:k.mode)==="light"?"light":"dark",granted:b.granted??{scopes:[]},preferences:b.preferences??{},games:Array.isArray(b.games)?b.games:[],flashIds:typeof b.flashIds=="number"?b.flashIds:null,development:x.development||!!b.development,initialized:!0}),l.notifyGames(x.games),u()}const m=n.listen(f);async function y(b){var k,$;const[I]=await Promise.all([g,((k=n.loadStyles)==null?void 0:k.call(n))??Promise.resolve()]);t||(($=x.role)==null?void 0:$.kind)==="logic"||(Object.assign(x,{kind:b.kind,contribution:b.contribution,props:b.props??{}}),I&&v())}function v(){var b;if(!x.kind||!x.contribution)return;const[k,$]=x.kind==="page"?[a==null?void 0:a.pages,"pages"]:x.kind==="panel"?[a==null?void 0:a.panels,"panels"]:x.kind==="widget"?[a==null?void 0:a.widgets,"widgets"]:[a==null?void 0:a.commandViews,"commandViews"],I=k==null?void 0:k[x.contribution];if(!I){h(new A("NOT_SUPPORTED",`definePlugin has no ${$}["${x.contribution}"], so there is nothing to show here`));return}try{(b=n.view)==null||b.mount(I,c)}catch(W){h(W)}}async function T(b){var k,$;const I=(W,Oe)=>{try{s({phantom:z,type:"result",id:b.id,ok:W,...Oe})}catch(Me){s({phantom:z,type:"result",id:b.id,ok:!1,error:be(new A("FAILED",`The answer could not be sent to Phantom: ${N(Me)}`))})}};try{if(!await w||!a)throw new A("FAILED","The plugin did not load");if(b.kind!=="commands")throw new A("NOT_SUPPORTED",`Phantom asked for an unknown kind, "${b.kind}"`);const W=(k=a.commands)==null?void 0:k[b.contribution];if(typeof W!="function")throw new A("NOT_SUPPORTED",`definePlugin has no commands["${b.contribution}"] function`);const Oe={arguments:(($=b.input)==null?void 0:$.arguments)??{}},Me=await W(Oe,c.phantom(b.game),c);I(!0,{value:le(Me??null)})}catch(W){I(!1,{error:be(W)})}}function R(b){try{const k=b();k instanceof Promise&&k.catch($=>O($))}catch(k){O(k)}}function O(b){o.log("error",[`setup's cleanup failed: ${N(b)}`])}async function H(){const b=i;if(i=null,b)try{await Promise.race([Promise.resolve(b()),new Promise(k=>setTimeout(k,fa))])}catch(k){O(k)}s({phantom:z,type:"stopped"})}return{ctx:c,crash:h,log:(b,k)=>o.log(b,k),replaceDefinition(b){var k;a=b,((k=x.role)==null?void 0:k.kind)!=="logic"&&v()},stop(){t||(i&&(R(i),i=null),t=!0,m(),o.close("The frame was closed"),l.dispose(),rt(null))}}}function se(n){return Object.keys(n??{})}function wa(n){return!n||typeof n!="object"?{}:"default"in n&&n.default&&typeof n.default=="object"?n.default:n}const pa={class:"flex flex-col p-3",role:"alert"},ma={class:"flex flex-col gap-2 overflow-hidden rounded-lg border border-phantom-danger/25 bg-phantom-danger/10 px-3 py-2.5"},ya={class:"flex items-start gap-2"},ba={class:"min-w-0 flex-1"},va={class:"text-xs font-medium text-phantom-danger"},ka={class:"mt-0.5 break-words text-2xs text-phantom-text-soft"},xa=["textContent"],Ta={key:1,class:"text-2xs text-phantom-subtle"},Oa=hn({__name:"ErrorCard",props:{error:{},development:{type:Boolean},kind:{}},emits:["dismiss"],setup(n,{emit:e}){const t=n,r=e,a=un(()=>t.kind==="panel"?"This panel":t.kind==="page"?"This page":"This plugin");return(i,s)=>(ue(),de("div",pa,[ee("div",ma,[ee("div",ya,[s[1]||(s[1]=ee("span",{class:"mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-phantom-danger","aria-hidden":"true"},null,-1)),ee("div",ba,[ee("p",va,Se(a.value)+" stopped with an error",1),ee("p",ka,Se(n.error.message),1)]),n.development?(ue(),de("button",{key:0,type:"button",class:"shrink-0 rounded px-1.5 text-2xs text-phantom-muted transition-colors hover:bg-phantom-danger/10 hover:text-phantom-text",onClick:s[0]||(s[0]=o=>r("dismiss"))}," Dismiss ")):et("",!0)]),n.development&&n.error.stack?(ue(),de("pre",{key:0,class:"max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md bg-phantom-canvas/60 px-2.5 py-2 font-mono text-3xs text-phantom-muted",textContent:Se(n.error.stack)},null,8,xa)):n.development?et("",!0):(ue(),de("p",Ta," More is in the plugin's log, in Plugins. "))])]))}});function Ma(n){let e=null,t=null,r=-1;const a=()=>{const o=Math.ceil(Math.max(n.content.scrollHeight,n.content.getBoundingClientRect().height));o!==r&&(r=o,n.onResize(o))},i=typeof ResizeObserver>"u"?null:new ResizeObserver(a);i==null||i.observe(n.content);function s(){t==null||t.unmount(),t=null,n.content.hidden=!1}return{mount(o,l){s(),e==null||e.unmount(),document.documentElement.dataset.kind=x.kind??"",e=tt({name:"PhantomPluginView",render:()=>nt(o,{...x.props})}),e.provide(gn,l),e.config.errorHandler=c=>n.onError(c),e.mount(n.content)},showError(o,l){t==null||t.unmount(),n.content.hidden=!0,t=tt({render:()=>nt(Oa,{error:o,development:l,kind:x.kind,onDismiss:()=>s()})}),t.mount(n.errors),a()},unmount(){i==null||i.disconnect(),e==null||e.unmount(),t==null||t.unmount(),e=null,t=null}}}function Ea(n){window.parent===window&&Sa();const e=$t("app"),t=$t("phantom-error");let r=null;function a(o){window.parent.postMessage(o,"*")}const i=Ma({content:e,errors:t,onError:o=>r==null?void 0:r.crash(o),onResize:o=>{document.documentElement.dataset.kind&&a({phantom:z,type:"resize",height:o})}});r=ga({post:a,listen(o){const l=c=>{c.source===window.parent&&o(c.data)};return window.addEventListener("message",l),()=>window.removeEventListener("message",l)},root:document.documentElement,view:i,...n.loadStyles?{loadStyles:n.loadStyles}:{}},n);const s=r;return Gr(console,(o,l)=>s.log(o,l)),window.addEventListener("error",o=>{String(o.message).includes("ResizeObserver loop")||s.crash(o.error??o.message)}),window.addEventListener("unhandledrejection",o=>s.crash(o.reason)),window.addEventListener("pagehide",()=>{i.unmount(),s.stop()}),document.addEventListener("click",o=>{const l=o.target,c=l&&typeof l.closest=="function"?l.closest("a[href]"):null;if(!c)return;const h=c.getAttribute("href")??"";h.startsWith("#")||(o.preventDefault(),/^https:\/\//i.test(h)?s.ctx.openUrl(h).catch(()=>{}):s.log("warn",[`Only https links open from a plugin; this one goes to ${h}`]))}),s}function $t(n){const e=document.getElementById(n);if(e)return e;const t=document.createElement("div");return t.id=n,document.body.append(t),t}function Sa(){const n=document.createElement("p");n.className="m-6 max-w-md text-xs text-phantom-muted",n.textContent="This is a Phantom plugin frame. It runs inside Phantom: turn on Developer mode in Plugins, and a plugin served by phantom-plugin dev shows up there.",document.body.prepend(n)}const Ft="/dist/plugin.js",Aa="/dist/plugin.css";let It=null;function Pa(){return It??=new Promise(n=>{const e=document.createElement("link");e.rel="stylesheet",e.href=Aa,e.onload=e.onerror=()=>n(),document.head.append(e)}),It}async function Ra(){const n=await import(Ft);if(!n.default)throw new Error(`${Ft} has no default export. Export definePlugin({ ... }) as default.`);return n.default}Ea({definition:Ra,loadStyles:Pa});