@phantomclient/plugin 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/chunks/{api-DhaU9Jsd.js → api-q8Jk0T10.js} +419 -357
- package/dist/lib/chunks/sdk-permissions-BQlOakj9.js +429 -0
- package/dist/lib/chunks/state-CAfC_MRc.js +34 -0
- package/dist/lib/guest.js +2509 -1576
- package/dist/lib/index.js +22 -22
- package/dist/lib/styles.css +1 -1
- package/dist/lib/vue.js +307 -222
- package/dist/runtime/chunks/api-0JFqyaCU.js +1 -0
- package/dist/runtime/chunks/sdk-permissions-DXVe00ho.js +1 -0
- package/dist/runtime/chunks/state-C-LOzJQV.js +1 -0
- package/dist/runtime/frame.html +3 -3
- package/dist/runtime/runtime.css +1 -1
- package/dist/runtime/runtime.js +4 -4
- package/dist/runtime/sdk-vue.js +1 -1
- package/dist/runtime/sdk.js +1 -1
- package/dist/types/index.d.ts +8143 -734
- package/dist/types/vue.d.ts +10520 -2284
- package/package.json +1 -1
- package/dist/lib/chunks/sdk-permissions-CyDMa4we.js +0 -429
- package/dist/lib/chunks/state-BGYMFLti.js +0 -34
- package/dist/runtime/chunks/api-DCkkcNDr.js +0 -1
- package/dist/runtime/chunks/sdk-permissions-AYsXGgro.js +0 -1
- package/dist/runtime/chunks/state-CyERnsrb.js +0 -1
package/dist/runtime/runtime.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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:
|
|
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});
|
|
1
|
+
import{i as un,s as dn,c as Fn,a as Ln,b as In,d as jn,j as Dn,S as zn,e as Hn,P as q,f as Wn}from"./chunks/sdk-permissions-DXVe00ho.js";import{M as fn,P as vt,X as Bn,a as qn,b as Un,C as De,c as $,r as Vn,N as $e,i as Gn}from"./chunks/api-0JFqyaCU.js";import{f as S,b as Ne,r as Yn,s as kt,P as Kn}from"./chunks/state-C-LOzJQV.js";import{i as Xn,t as Jn,d as Qn,o as ke,c as xe,a as le,b as ze,e as xt,f as Zn,g as Mt,h as St}from"./chunks/runtime-dom.esm-bundler-Dcouf4CU.js";class z extends Error{constructor(e,t,a=null){super(ea(t,a,e)),this.code=e,this.flash=a,this.name="BridgeError"}code;flash}function ea(n,e,t){if(typeof n=="string"&&n.trim()!=="")return na(n,e);const a=aa(n);if(a)return a;const r=typeof(e==null?void 0:e.name)=="string"?e.name.trim():"";return r||`The game answered with no reason (${t})`}const ta={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 na(n,e){const t=typeof(e==null?void 0:e.errorId)=="number"?e.errorId:0,a=ta[t];return!a||!/^\s*Error #\d+\s*$/.test(n)?n:`${n.trim()}: ${a}`}function aa(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 Et=2;function ce(n){return encodeURIComponent(JSON.stringify(n))}function wn(n){return JSON.parse(decodeURIComponent(n))}function ra(n){return typeof n=="object"&&n!==null&&"$handle"in n}function ia(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}}const sa="__AS3__.vec",oa=new Set(["*","Array","Boolean","Class","Date","Function","int","Number","Object","RegExp","String","uint","XML","XMLList"]);function la(n){return`${sa}::Vector.<${ca(n)}>`}function ca(n){const e=n.trim();if(!e)throw new TypeError("A vector needs the class of what it holds");if(e.includes("::")||oa.has(e))return e;const t=e.lastIndexOf(".");return t===-1?e:`${e.slice(0,t)}::${e.slice(t+1)}`}class ye{constructor(e,t=[]){this.className=e,this.args=t}className;args}class W{constructor(e,t,a){this.bridge=e,this.handle=t,this.className=a}bridge;handle;className;at(...e){return new se(this.bridge,{kind:"handle",handle:this.handle},e)}release(){return this.bridge.release([this])}}class se{constructor(e,t,a=[]){this.bridge=e,this.target=t,this.path=a}bridge;target;path;at(...e){return new se(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,a={}){return this.bridge.listen(this,e,t,a)}get entry(){return{target:this.target,path:[...this.path]}}}const ha=new Set(["drive-failed","track","hook","override","hook-dropped","hook-failed","watch","tick","overlay","key"]);class ua{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(a=>this.receive(a))}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 z("CLOSED","The game is closed")):new Promise((e,t)=>this.readyWaiters.push({resolve:e,reject:t}))}definition(e){return new se(this,{kind:"definition",name:e})}gameClient(){return new se(this,{kind:"client"})}stage(){return new se(this,{kind:"stage"})}construct(e,...t){return this.request({op:"construct",className:e,args:t.map(a=>this.encode(a))})}async vector(e,t=[]){const a=await this.construct(la(e));for(const r of t)await a.at("push").call(r);return a}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,a,r={}){if((r.read!==void 0||r.capture===!0)&&(await this.whenReady(),!this.featureList.includes("capturePaths")))throw new z("VERSION","This game is running a loader from before events could be read as they happen; listen without `read` and `capture`, or update Phantom");const i=this.nextId++;this.listeners.set(i,a);try{await this.request({op:"listen",target:e.target,path:[...e.path],event:t,listener:i,...r.read!==void 0?{read:r.read.map(s=>[...s])}:{},...r.capture===!0?{capture:!0}:{}})}catch(s){throw this.listeners.delete(i),s}return async()=>{!this.listeners.delete(i)||this.stateValue==="closed"||await this.request({op:"unlisten",listener:i})}}async subscribe(e,t,a){const r=this.nextId++;this.subscriptions.set(r,a);try{await this.request(e(r))}catch(i){throw this.subscriptions.delete(r),i}return async()=>{!this.subscriptions.delete(r)||this.stateValue==="closed"||await this.request(t(r))}}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,a){let r=0;const i=await this.subscribe(s=>(r=s,{op:"hook",registration:s,hook:e,rules:t}),s=>({op:"unhook",registration:s}),a);return{registration:r,stop:i}}watch(e,t,a){return this.subscribe(r=>({op:"watch",watch:r,entries:e.map(i=>({target:i.target,path:[...i.path]})),everyFrames:Math.max(1,Math.floor(t.everyFrames??1)),handles:t.handles??!1}),r=>({op:"unwatch",watch:r}),r=>{r.kind==="watch"&&a(r.values.map(i=>this.decode(i)),r.errors??null)})}async tick(e,t){const a=Math.max(1,Math.floor(e));let r=this.ticks.get(a);if(!r){const o=new Set,h=this.subscribe(l=>({op:"tick",tick:l,everyFrames:a}),l=>({op:"untick",tick:l}),l=>{if(l.kind==="tick")for(const c of[...o])c(l.frame,l.time)});r={listeners:o,started:h},this.ticks.set(a,r),h.catch(()=>{this.ticks.get(a)===r&&this.ticks.delete(a)})}const i=r;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(a)!==i)&&(this.ticks.delete(a),await(await i.started)()))}}highlight(e,t){return this.subscribe(a=>({op:"highlight",highlight:a,target:e.target,path:[...e.path],effect:t}),a=>({op:"unhighlight",highlight:a}),()=>{})}style(e,t){return this.subscribe(a=>({op:"style",style:a,target:e.target,path:[...e.path],format:t}),a=>({op:"unstyle",style:a}),()=>{})}invokeOriginal(e,t,a){return this.request({op:"invokeOriginal",registration:e,token:t,arguments:a===null?null:a.map(r=>this.encode(r))})}async overrideDone(e,t){this.stateValue!=="closed"&&await this.request({op:"overrideDone",registration:e,token:t})}onKey(e,t){return this.subscribe(a=>({op:"key",key:a,spec:e}),a=>({op:"unkey",key:a}),a=>{a.kind==="key"&&t(a)})}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]})}}async measure(e){return await this.request({op:"measure",...e})}async bounds(e){return await this.request({op:"bounds",node:e})}drive(e,t){return this.subscribe(a=>({op:"drive",drive:a,spec:e}),a=>({op:"undrive",drive:a}),a=>{a.kind==="drive-failed"&&(t==null||t(a.error))})}async collect(e,t){const r=await this.request({op:"collect",target:e.target,path:[...e.path],spec:t});return{items:Array.isArray(r==null?void 0:r.items)?r.items:[],total:typeof(r==null?void 0:r.total)=="number"?r.total:0}}track(e,t,{mode:a="displayList",everyFrames:r=15}={},i){return this.subscribe(s=>({op:"track",track:s,target:e.target,path:[...e.path],className:t,mode:a,everyFrames:r}),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:a=null,maxSize:r=0}={}){const i=await this.request({op:"snapshot",target:e.target,path:[...e.path],scale:t,background:a,maxSize:r});if(typeof i!="string")throw new z("FLASH","The picture came back empty");return i}note(e,t,a,r){if(t==="keys"||t==="clear")return this.request({op:"note",table:e,verb:t});if(!a)throw new TypeError(`A note to ${t} is kept beside an object; name the place`);const i={target:a.target,path:[...a.path]};return t==="write"?this.request({op:"note",table:e,verb:t,...i,value:this.encode(r)}):this.request({op:"note",table:e,verb:t,...i})}async find(e,t){const a=await this.request({op:"find",target:e.target,path:[...e.path],spec:t});return(Array.isArray(a)?a:[]).filter(r=>r instanceof W)}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(ce({id:t,op:"dispose",from:this.firstId,to:this.nextId}))}catch{}}this.stateValue="closed",this.stopReceiving();const e=new z("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,a)=>{const r=setTimeout(()=>a(new z("NOT_READY","The game has not started yet")),e);this.whenReady().then(()=>{clearTimeout(r),t()},i=>{clearTimeout(r),a(i)})})}encodeRequest(e){return ce({...e,id:this.nextId++})}request(e){if(this.stateValue==="closed")return Promise.reject(new z("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((a,r)=>{const i=setTimeout(()=>{this.pending.delete(t),r(new z("TIMEOUT",`The game did not answer "${e.op}" in ${this.timeoutMs}ms`))},this.timeoutMs);this.pending.set(t,{resolve:a,reject:r,timer:i});const s={...e,id:t};if(!this.batching||s.op==="hookTable"||s.op==="batch"){this.transport.send(ce(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(ce(e[0]));return}const t=this.nextId++,a=e.map(i=>i.id),r=setTimeout(()=>this.batches.delete(t),this.timeoutMs+1e3);this.batches.set(t,{ids:a,timer:r}),this.transport.send(ce({id:t,op:"batch",requests:e}))}settle(e,t){const a=this.pending.get(e);a&&(this.pending.delete(e),clearTimeout(a.timer),t.ok?a.resolve(this.decode(t.value)):a.reject(new z("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 W?{$handle:e.handle}:e instanceof ye?{$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,a])=>[t,this.encode(a)]))}decode(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(t=>this.decode(t));if(ra(e))return new W(this,e.$handle,e.className);if(!("$undefined"in e))return Object.fromEntries(Object.entries(e).map(([t,a])=>[t,this.decode(a)]))}receive(e){var t,a,r;if(this.stateValue==="closed")return;let i;try{i=wn(e)}catch{return}switch(i.kind){case"ready":if(i.version!==Et){const s=new z("VERSION",`The loader speaks bridge ${i.version}; this Phantom speaks ${Et}`);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((h,l)=>{i.ok?o&&l<o.length&&this.settle(h,o[l]):this.settle(h,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":(a=this.callbacks.get(i.callback))==null||a(...i.args.map(s=>this.decode(s)));return;case"uncaught":{const s=new z("FLASH",i.error.message,i.error);this.uncaughtListeners.forEach(o=>o(s));return}default:if(ha.has(i.kind)){const s=ia(i);s!==null&&((r=this.subscriptions.get(s))==null||r(i))}}}}const da=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],gn={r:.3086,g:.6094,b:.082};function Me(n,e){const t=new Array(20).fill(0);for(let a=0;a<4;a++)for(let r=0;r<5;r++){let i=r===4?e[a*5+4]:0;for(let s=0;s<4;s++)i+=e[a*5+s]*n[s*5+r];t[a*5+r]=i}return t}function mn(n){const e=n,{r:t,g:a,b:r}=gn;return[t*(1-e)+e,a*(1-e),r*(1-e),0,0,t*(1-e),a*(1-e)+e,r*(1-e),0,0,t*(1-e),a*(1-e),r*(1-e)+e,0,0,0,0,0,1,0]}function fa(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 wa(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 ga(n){const e=n*Math.PI/180,t=Math.cos(e),a=Math.sin(e),{r,g:i,b:s}=gn;return[r+t*(1-r)+a*-r,i+t*-i+a*-i,s+t*-s+a*(1-s),0,0,r+t*-r+a*.143,i+t*(1-i)+a*.14,s+t*-s+a*-.283,0,0,r+t*-r+a*-.6914,i+t*-i+a*i,s+t*(1-s)+a*s,0,0,0,0,0,1,0]}const ma={grayscale:mn(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 pn(n){if(typeof n=="string"){const t=ma[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)),a=r=>(n.tint>>r&255)*t;return{matrix:null,colorTransform:Tt({redMultiplier:1-t,greenMultiplier:1-t,blueMultiplier:1-t,redOffset:a(16),greenOffset:a(8),blueOffset:a(0)})}}if("transform"in n)return{matrix:null,colorTransform:Tt(n.transform)};let e=[...da];return n.saturation!==void 0&&(e=Me(e,mn(n.saturation))),n.hue!==void 0&&(e=Me(e,ga(n.hue))),n.contrast!==void 0&&(e=Me(e,wa(n.contrast))),n.brightness!==void 0&&(e=Me(e,fa(n.brightness))),{matrix:e,colorTransform:null}}function Tt(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 be(n={}){const e=n.recolor?pn(n.recolor):{matrix:null,colorTransform:null},a=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(a&&e.matrix)throw new TypeError("A highlight is a glow or a colour matrix, not both: use two highlights");const r=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:a,matrix:e.matrix,colorTransform:e.colorTransform,hide:n.hide??!1,pulse:r}}function B(n){const e=`${n.className}.${n.member}`;return n.kind==="getter"?`${e}@get`:n.kind==="setter"?`${e}@set`:e}const Fe=Symbol.for("phantom.hookRead"),oe=Symbol.for("phantom.hookTest"),Pe=200,pa=20;class ya{constructor(e){this.table=e;for(const t of e.hooks){this.byId.set(t.id,t);const a=B(t);this.byKey.has(a)||this.byKey.set(a,t);const r=this.byClass.get(t.className);r?r.push(t):this.byClass.set(t.className,[t])}}table;byKey=new Map;byId=new Map;byClass=new Map;get size(){return this.byId.size}names(){return[...this.byKey.keys()]}entries(){return[...this.byId.values()]}classNames(){return[...this.byClass.keys()]}inClass(e){return[...this.byClass.get(e)??[]]}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 J(n){return n.flatMap(e=>Array.isArray(e)?e:e.includes("::")?[e]:e.split(".").filter(Boolean))}function re(n){return Object.freeze({[Fe]:n})}function G(n,e,t){return Object.freeze({[oe]:t===void 0&&n==="exists"?{test:n,left:e}:{test:n,left:e,right:t}})}const ba={self:(...n)=>re({from:"self",path:J(n)}),arg:(n,...e)=>re({from:"arg",arg:n,path:J(e)}),returned:(...n)=>re({from:"return",path:J(n)}),fromClass:(n,...e)=>re({from:"class",name:n,path:J(e)}),place:(n,...e)=>re({from:"place",place:n,path:J(e)}),calls:()=>re({from:"calls"}),constant:n=>re({from:"constant",value:n}),equals:(n,e)=>G("equals",n,e),notEquals:(n,e)=>G("notEquals",n,e),less:(n,e)=>G("less",n,e),lessOrEqual:(n,e)=>G("lessOrEqual",n,e),greater:(n,e)=>G("greater",n,e),greaterOrEqual:(n,e)=>G("greaterOrEqual",n,e),contains:(n,e)=>G("contains",n,e),startsWith:(n,e)=>G("startsWith",n,e),endsWith:(n,e)=>G("endsWith",n,e),oneOf:(n,e)=>G("in",n,e),exists:n=>G("exists",n),all:(...n)=>Object.freeze({[oe]:{all:n}}),any:(...n)=>Object.freeze({[oe]:{any:n}}),not:n=>Object.freeze({[oe]:{not:n}})};function yn(n){return typeof n=="object"&&n!==null&&Fe in n}function bn(n){return typeof n=="object"&&n!==null&&oe in n}function rt(n,e,t,a){const r=u=>{if(typeof u=="number")return Ot(e,u);const d=e.parameters.findIndex(g=>g.name===u);if(d>=0)return d;if(/^\d+$/.test(u))return Ot(e,Number(u));const w=e.parameters.map(g=>g.name).join(", ")||"none";throw new TypeError(`${B(e)} has no argument "${u}" (its arguments: ${w})`)},i=u=>{if(!yn(u))return _e(u)??{from:"constant",value:de(n,u)};const d=u[Fe];switch(d.from){case"constant":return{from:"constant",value:de(n,d.value)};case"arg":return{from:"arg",index:r(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 w=_e(d.place,d.path);if(!w)throw new TypeError("rules.place takes a place in the game");return w}}},s=u=>{if(!bn(u)){const w=Object.entries(u).map(([g,f])=>({test:"equals",left:{from:"arg",index:r(g),path:[]},right:i(f)}));if(w.length===0)throw new TypeError("A hook condition names nothing to compare");return w.length===1?w[0]:{all:w}}const d=u[oe];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??(a?"enter":"none"),h=t.capture??{},l=vn(e,h.args,a,r);if(l.some(({path:u})=>u.length>0)&&!n.features.includes("capturePaths"))throw new Error(`The hook on ${B(e)} reads along from an argument, which this game's loader is from before; capture the argument itself, or update Phantom`);const c=l.map(({index:u,path:d})=>d.length===0?u:{index:u,path:d});return{observe:o==="both"?["enter","exit"]:o==="none"?[]:[o],capture:{args:c,self:it(h.self).map(([,u])=>u),value:h.value??!1,handles:h.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:r(u),value:i(d)})),replaceReturn:"replaceReturn"in t?i(t.replaceReturn):null,perFrame:t.perFrame??pa}}function Ot(n,e){if(!Number.isInteger(e)||e<0||n.parameters.length>0&&e>=n.parameters.length)throw new RangeError(`${B(n)} has no argument ${e}`);return e}function vn(n,e,t,a){const r=i=>{var s;return{name:((s=n.parameters[i])==null?void 0:s.name)??String(i),index:i,path:[]}};return e===!0||e===void 0&&t?n.parameters.map((i,s)=>r(s)):e===void 0?[]:Array.isArray(e)?e.map(i=>r(a(i))):Object.entries(e).map(([i,s])=>{const o=Array.isArray(s)?s.flatMap(c=>typeof c=="number"?[String(c)]:J([c])):J([s]),[h,...l]=o;if(h===void 0)throw new TypeError(`${B(n)}: "${i}" names no argument to read from`);return{name:i,index:a(h),path:l}})}function it(n){return n?Array.isArray(n)?n.map(e=>[e,J([e])]):Object.entries(n).map(([e,t])=>[e,J([t])]):[]}function kn(n,e){const t=a=>{if(!bn(a))throw new TypeError("A condition between calls has no call to read: compare with rules.equals and its like");const r=a[oe];return"all"in r?{all:r.all.map(t)}:"any"in r?{any:r.any.map(t)}:"not"in r?{not:t(r.not)}:r.test==="exists"?{test:r.test,left:me(n,r.left)}:{test:r.test,left:me(n,r.left),right:me(n,r.right)}};return t(e)}function _e(n,e=[]){const t=ae(n);return t?{from:"place",target:t.target,path:[...t.path,...e]}:null}function me(n,e){if(!yn(e))return _e(e)??{from:"constant",value:de(n,e)};const t=e[Fe];switch(t.from){case"constant":return{from:"constant",value:de(n,t.value)};case"class":return{from:"class",name:t.name,path:t.path};case"place":{const a=_e(t.place,t.path);if(!a)throw new TypeError("rules.place takes a place in the game");return a}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 de(n,e){if(e===void 0)return{$undefined:!0};if(e instanceof W||e instanceof ye)return n.encode(e);const t=ae(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(a=>de(n,a)):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([a,r])=>[a,de(n,r)])):e}function At(n,e,t){var a;const r=i=>{if(typeof i=="number")return i;const s=n.parameters.findIndex(o=>o.name===i);return s>=0?s:Number(i)};return vn(n,(a=e.capture)==null?void 0:a.args,t,r).map(({name:i})=>i)}async function va(n,e,t,a,r){var i;if(typeof a=="function")throw new TypeError(`phantom.flash.hook("${t}", ...) was given a function where its options go. A hook takes its options second and its listener third: hook(name, options, listener). An override is the other way about: override(name, handler, options).`);const s=e.find(t);if(!s)throw new TypeError(`There is no hook "${t}" in the hook table`);let o=a,h=it((i=a.capture)==null?void 0:i.self).map(([f])=>f),l=rt(n,s,a,r!==void 0),c=At(s,a,r!==void 0),u=!1;const{registration:d,stop:w}=await n.hook(s.id,l,f=>{switch(f.kind){case"hook":{if(!r)return;const m=(f.args??[]).map(b=>_(n,n.decode(b))),p={};c.forEach((b,v)=>{p[b]=m[v]});const y={};(f.self??[]).forEach((b,v)=>{y[h[v]??String(v)]=_(n,n.decode(b))}),r({phase:f.phase,call:f.call,args:p,argList:m,self:y,..."value"in f?{value:_(n,n.decode(f.value))}:{},skipped:f.skipped===!0,hook:s});return}case"hook-dropped":o.onDropped?o.onDropped(f.dropped):u||(u=!0,console.warn(`The hook on ${B(s)} went untold of ${f.dropped} calls in one frame: it hears at most ${l.perFrame} a frame. Raise perFrame (${Pe} is the most the game allows), narrow the hook with when/first/every, or pass onDropped to count them yourself. Said once per hook.`));return;case"hook-failed":{const m=new z("FLASH",`The hook on ${B(s)} failed and is off: ${f.error.message}`,f.error);o.onError?o.onError(m):console.error(m.message);return}}});return Object.assign(()=>w(),{registration:d,hook:s,update:async(f,m={})=>{var p;const y=rt(n,s,f,r!==void 0);await n.request({op:"rehook",registration:d,rules:y,resetCounts:m.resetCounts??!1}),o=f,l=y,h=it((p=f.capture)==null?void 0:p.self).map(([b])=>b),c=At(s,f,r!==void 0)},stats:async()=>(await n.request({op:"hookStats"})).find(m=>m.registration===d)??null})}function A(n){const e=ae(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 ue(n){return ae(n)!==null}async function ka(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 a=A(e);if(a.path.length===0)throw new TypeError("A repeat calls a method, so name one: `place.method`, not the object");const r=t.while?kn(n,t.while):null;return n.drive({writes:[],calls:[{target:a.target,path:a.path,args:(t.args??[]).map(i=>me(n,i)),times:Math.max(1,Math.trunc(t.times??1))}],everyFrames:Math.max(1,Math.trunc(t.everyFrames??1)),while:r,restore:!1,once:t.once===!0},t.onFailed)}async function st(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 a=e.map(({place:i,value:s})=>{const o=A(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:me(n,s)}}),r=t.while?kn(n,t.while):null;return n.drive({writes:a,everyFrames:Math.max(1,Math.trunc(t.everyFrames??1)),while:r,restore:t.restore!==!1,once:t.once===!0},t.onFailed)}const Le=Symbol.for("phantom.typedFlash");function xn(n){return typeof n=="function"&&n[Le]!==void 0}function N(n,e,t={}){const a={reference:e,handle:t.handle??null,className:t.className??null},r=o=>_(n,o),i={$get:()=>e.get().then(r),$set:async o=>e.set((await te(n,[o]))[0]),$keep:(o,h={})=>st(n,[{place:e,value:o}],h),$call:async(...o)=>r(await e.call(...await te(n,o))),$listen:(o,h)=>e.listen(o,l=>h(r(l))),$describe:()=>e.describe(),$at:(...o)=>N(n,e.at(...o)),$as:()=>N(n,e,{...a.handle?{handle:a.handle}:{}}),$release:()=>a.handle?a.handle.release():Promise.resolve(),$reference:e,$new:async(...o)=>{if(!a.className)throw new TypeError("Only a class can make objects with $new");return r(await n.construct(a.className,...await te(n,o)))},toJSON:()=>`[Flash ${xa(a)}]`},s=(()=>{});return new Proxy(s,{get:(o,h)=>{if(h===Le)return a;if(typeof h!="symbol"&&h!=="then")return Object.prototype.hasOwnProperty.call(i,h)?i[h]:N(n,e.at(h))},apply:async(o,h,l)=>r(await e.call(...await te(n,l)))})}function ae(n){return xn(n)?n[Le].reference:n instanceof W?n.at():n&&typeof n=="object"&&"target"in n&&"path"in n&&typeof n.at=="function"?n:null}function _(n,e){if(e instanceof W)return N(n,e.at(),{handle:e});if(Array.isArray(e))return e.map(t=>_(n,t));if(e&&typeof e=="object"){const t={};for(const[a,r]of Object.entries(e))t[a]=_(n,r);return t}return e}async function te(n,e){return Promise.all(e.map(t=>ot(n,t)))}async function ot(n,e){if(xn(e)){const t=e[Le];return t.handle&&t.reference.path.length===0?t.handle:t.reference.get()}if(typeof e=="function"){const t=e;return(...a)=>t(...a.map(r=>_(n,r)))}if(Array.isArray(e))return Promise.all(e.map(t=>ot(n,t)));if(e&&typeof e=="object"&&Object.getPrototypeOf(e)===Object.prototype){const t={};for(const[a,r]of Object.entries(e))t[a]=await ot(n,r);return t}return e}function xa({reference:n,className:e}){const t=n.target,a=t.kind==="definition"?t.name:t.kind==="handle"?`object ${t.handle}`:t.kind,r=n.path.join(".");return e??(r?`${a}.${r}`:a)}class Ma{constructor(e,t,a){this.bridge=e;const r=e.encode(t);this.callback=r.$callback,a!==void 0&&this.answers(a)}bridge;callback;stopped=!1;get argument(){return{$callback:this.callback}}async answers(e){if(this.stopped)return;await this.ready();const[t]=await te(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")}}async function Sa(n,e,t,a){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 r={fields:Ea(t)};a.skip!==void 0&&(r.skip=Math.max(0,Math.trunc(a.skip))),a.limit!==void 0&&(r.limit=Math.max(1,Math.trunc(a.limit))),a.handles!==void 0&&(r.handles=a.handles);const i=await n.collect(A(e),r);return{rows:i.items.map(s=>_(n,s)),total:i.total}}function Ea(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,a])=>({name:t,path:(Array.isArray(a)?a:String(a).split(".")).filter(r=>r.length>0)}))}const Ta=50;async function Oa(n,e,t,a={}){const r=typeof t=="string"?t:null;if(r!==null&&r.trim()==="")throw new TypeError("Name a class to describe, or give a place in the game");let i=null,s=null;if(a.live??!0)try{const l=r===null?Pa(t):n.definition(r);i=Ra(await l.describe())}catch(l){s=l instanceof Error?l.message:String(l)}const o=r??(i==null?void 0:i.name)??"",h=new Map;for(const l of o?e.inClass(o):[])Ca(h,l);return i&&Na(h,i),{className:o,liveClassName:(i==null?void 0:i.name)??null,base:i&&i.base&&i.base!=="Class"?i.base:null,members:[...h.values()].sort(La),liveError:s}}function Aa(n,e,t={}){var a;const r=e.trim().toLowerCase();if(!r)return[];const i=r.lastIndexOf("."),s=i>0?r.slice(0,i):"",o=i>0?r.slice(i+1):r,h=((a=t.inClass)==null?void 0:a.trim().toLowerCase())??"",l=Math.max(0,t.limit??Ta),c=[];for(const u of n.entries()){if(t.isStatic!==void 0&&u.isStatic!==t.isStatic||t.kind!==void 0&&u.kind!==t.kind)continue;const d=u.className.toLowerCase();if(h&&!d.includes(h)||s&&!d.includes(s))continue;const w=$a(d,u.member.toLowerCase(),o,s!=="");w!==null&&c.push({score:w,entry:u})}return c.sort((u,d)=>u.score-d.score||u.entry.className.localeCompare(d.entry.className)||u.entry.member.localeCompare(d.entry.member)||u.entry.kind.localeCompare(d.entry.kind)),c.slice(0,l).map(({entry:u})=>({hook:B(u),className:u.className,member:u.member,kind:u.kind,isStatic:u.isStatic,parameters:u.parameters.map(d=>({...d})),returns:u.returns,namespace:u.namespace}))}function $a(n,e,t,a){return t===""?3:e===t?0:e.startsWith(t)?1:e.includes(t)?2:a?null:n.includes(t)?4:null}function Pa(n){return A(n),ae(n)}function Ra(n){const e=n??{};return{name:typeof e.name=="string"?e.name.replace(/::/g,"."):"",base:typeof e.base=="string"?e.base.replace(/::/g,"."):"",methods:Array.isArray(e.methods)?e.methods:[],properties:Array.isArray(e.properties)?e.properties:[]}}function lt(n,e){return`${e?"static":"instance"} ${n}`}function Ca(n,e){var t;const a=e.member==="<constructor>",r=lt(e.member,e.isStatic),s=n.get(r)??{name:e.member,kind:a?"constructor":e.kind==="method"?"method":"property",isStatic:e.isStatic,access:null,type:"",parameters:[],hooks:[],namespace:e.namespace,from:"hooks"};s.hooks.push(B(e)),e.kind==="method"?(s.parameters=e.parameters.map(o=>({...o})),s.type||(s.type=e.returns)):(e.kind==="getter"&&!s.type&&(s.type=e.returns),e.kind==="setter"&&!s.type&&(s.type=((t=e.parameters[0])==null?void 0:t.type)??""),s.access=Fa(s.access,e.kind==="getter"?"read":"write")),n.set(r,s)}function Na(n,e){for(const t of e.methods){const a=lt(t.name,!1),r=n.get(a);if(r){r.from="both",r.type||(r.type=t.returns);continue}n.set(a,{name:t.name,kind:"method",isStatic:!1,access:null,type:t.returns,parameters:t.parameters.map((i,s)=>({name:String(s),type:i.type,optional:i.optional})),hooks:[],namespace:t.namespace,from:"live"})}for(const t of e.properties){const a=lt(t.name,!1),r=n.get(a),i=_a(t.access);if(r){r.from="both",r.type||(r.type=t.type),i&&(r.access=i);continue}n.set(a,{name:t.name,kind:"property",isStatic:!1,access:i,type:t.type,parameters:[],hooks:[],namespace:t.namespace,from:"live"})}}function _a(n){return n==="readonly"?"read":n==="writeonly"?"write":n==="readwrite"?"readwrite":null}function Fa(n,e){return n===null||n===e?e:"readwrite"}function La(n,e){const t=a=>a.kind==="constructor"?0:a.isStatic?2:1;return t(n)-t(e)||n.name.localeCompare(e.name)}class He{constructor(e,t,a,r,i,s,o){this.host=e,this.kind=t,this.id=a,this.name=r,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(),be(e))}tag(e,t={}){const{anchorX:a,anchorY:r,...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:a??0,y:r??this.tagY}})}onClick(e){const t=this.host.bridge;return this.kind!=="object"?this.place.$listen("mouseDown",()=>e(this)):t.stage().listen("mouseDown",a=>{const{stageX:r,stageY:i}=a??{};typeof r!="number"||typeof i!="number"||this.place.$reference.at("hitTestPoint").call(r,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 Ia{constructor(e){this.host=e}host;async players(){const e=this.host.bridge,t=e.definition("avatar.AvatarManager").at("avatarViewList"),a=await t.get(),r=a&&typeof a=="object"&&!(a instanceof W)?Object.keys(a):[],i=r.map(s=>a[s]).filter(s=>s instanceof W);try{const s=await Promise.all(r.map(o=>Q(t.at(o,"userName").get())));return r.map((o,h)=>new He(this.host,"player",o,typeof s[h]=="string"?s[h]:null,N(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"),a=await Q(t.at("length").get());if(typeof a!="number"||a<=0)return[];const r=Array.from({length:Math.min(a,500)},(l,c)=>String(c)),[i,s,o]=await Promise.all([Promise.all(r.map(l=>Q(t.at(l).get()))),Promise.all(r.map(l=>Q(t.at(l,"_actorId").get()))),Promise.all(r.map(l=>Q(t.at(l,"currAvatar","avName").get())))]),h=[];return r.forEach((l,c)=>{const u=i[c];if(!(u instanceof W))return;const d=o[c];h.push(new He(this.host,"npc",typeof s[c]=="string"?s[c]:l,typeof d=="string"&&d?d:null,N(e,u.at(),{handle:u}),-90,u))}),h}async objects(){const e=this.host.bridge,t=e.definition("room.RoomManagerWorld").at("instance","volumeManager","_volumeActors");let a;try{a=await t.at("length").get()}catch(c){throw c instanceof z&&c.code==="FLASH"?new z("FLASH",`The room's objects are private to the client, and this client does not reach them: ${c.message}`,c.flash):c}if(typeof a!="number"||a<=0)return[];const r=Array.from({length:Math.min(a,500)},(c,u)=>String(u)),[i,s]=await Promise.all([Promise.all(r.map(c=>Q(t.at(c,"name").get()))),Promise.all(r.map(c=>Q(t.at(c,"interactiveObjs","length").get())))]),o=[];r.forEach((c,u)=>{const d=s[u],w=i[u];for(let g=0;typeof d=="number"&&g<Math.min(d,50);g++)o.push([c,String(g),typeof w=="string"?w:null])});const h=await Promise.all(o.map(([c,u])=>Q(t.at(c,"interactiveObjs",u,"mc").get()))),l=[];return o.forEach(([c,u,d],w)=>{const g=h[w];g instanceof W&&l.push(new He(this.host,"object",`${d??c}#${u}`,d,N(e,g.at(),{handle:g}),0,g))}),l}}function Q(n){return n.catch(()=>null)}async function ja(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 a=e===void 0?{target:{kind:"stage"},path:[]}:A(e);return(await n.find(a,Da(t))).map(i=>N(n,i.at(),{handle:i}))}function Da(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 $t={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 za(n){return n===!0?"always":n===!1?"never":n??"empty"}function Ha(n,e={}){const t={phase:e.phase??"down",consume:e.consume??!1,whileTyping:za(e.whileTyping),repeat:e.repeat??!1};if(typeof n=="number")return{code:n,ctrl:null,shift:null,alt:null,...t};const a=n==="+"||n.endsWith("++"),r=(a?n.slice(0,-1):n).split("+").map(o=>o.trim()).filter(Boolean);a&&r.push("+");const i={ctrl:!1,shift:!1,alt:!1};let s=null;for(const o of r){const h=o.toLowerCase();h==="ctrl"||h==="control"||h==="cmd"||h==="meta"?i.ctrl=!0:h==="shift"?i.shift=!0:h==="alt"||h==="option"?i.alt=!0:h==="any"?s=null:s=Wa(o)}if(s===null&&!r.some(o=>o.toLowerCase()==="any"))throw new TypeError(`"${n}" names no key`);return{code:s,...i,...t}}function Wa(n){const e=n.toLowerCase();if(e in $t)return $t[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 a=/^num(?:pad)?([0-9])$/i.exec(n);if(a)return 96+Number(a[1]);if(n==="+")return 187;throw new TypeError(`Unknown key "${n}"`)}const Ba=new Set(["then","toJSON","toString","constructor","nodeType","tagName","inspect"]),qa=["overlay","entities","view","bridge"];function Mn(n){const e=new Set;if(n===null||typeof n!="object"&&typeof n!="function")return e;for(let t=n;t&&!(t===Object.prototype||t===Function.prototype);t=Object.getPrototypeOf(t))for(const a of Object.getOwnPropertyNames(t))a!=="constructor"&&e.add(a);return e}function Ua(n,e,t){if(Math.abs(n.length-e.length)>t)return t+1;let a=Array.from({length:e.length+1},(r,i)=>i);for(let r=1;r<=n.length;r++){const i=[r];for(let s=1;s<=e.length;s++)i[s]=Math.min(a[s]+1,i[s-1]+1,a[s-1]+(n[r-1]===e[s-1]?0:1));a=i}return a[e.length]}function Va(n,e){const t=n.length<=4?1:2;let a=null,r=t+1;for(const i of e){if(i.startsWith("_"))continue;const s=Ua(n.toLowerCase(),i.toLowerCase(),t);s<r&&(r=s,a=i)}return r<=t?a:null}function Ga(n,e,t){for(const r of qa){const i=n[r];if(!Mn(i).has(e))continue;return r!=="bridge"?`phantom.flash has no "${e}". phantom.flash.${r} has it: write phantom.flash.${r}.${e}.`:`phantom.flash has no "${e}". The bridge underneath has it: write phantom.flash.bridge.${e}.${e==="definition"?' For a class with its types, phantom.flash.use("avatar.AvatarManager") is the same object typed.':""}`}const a=Va(e,t);return a?`phantom.flash has no "${e}". Did you mean phantom.flash.${a}?`:`phantom.flash has no "${e}". Its own calls read, call and hook the client (use, global, hook, override, watch, find, hold); drawing is phantom.flash.overlay, the room's players and props are phantom.flash.entities, the camera is phantom.flash.view, and anything the declarations do not describe is phantom.flash.bridge.`}function Ya(n){const e=Mn(n);return new Proxy(n,{get(t,a,r){if(typeof a!="string"||a in t)return Reflect.get(t,a,r);if(!(Ba.has(a)||a.startsWith("__v_")||a.startsWith("$$")))throw new TypeError(Ga(t,a,e))}})}class Ka{constructor(e){this.bridge=e}bridge;table=null;async set(e,t){const[a]=await te(this.bridge,[t]);await this.bridge.note(await this.number(),"write",A(e),a)}async get(e){const t=await this.bridge.note(await this.number(),"read",A(e));return t==null?void 0:_(this.bridge,t)}async has(e){return await this.bridge.note(await this.number(),"has",A(e))===!0}async forget(e){return await this.bridge.note(await this.number(),"forget",A(e))===!0}async objects(){const e=await this.bridge.note(await this.number(),"keys");return Array.isArray(e)?e.filter(t=>t instanceof W).map(t=>N(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}}function ve(){const n=new Set;return{add(e){return n.add(e),()=>{n.delete(e)}},tell(e){for(const t of[...n])try{t(e)}catch(a){console.error("phantom.flash.overlay: a control listener failed",a)}}}}function Pt(n){return typeof n=="string"?{value:n,label:n}:{value:n.value,label:n.label??n.value}}function he(n,e,t){return Math.min(t,Math.max(e,n))}async function Xa(n,e){const{label:t="",checked:a=!1,boxSize:r=14,tickFill:i=2278750,disabled:s=!1,onChange:o,fill:h=1120295,stroke:l=10265519,font:c,...u}=e,d=ve();o&&d.add(o);const w=await n.group(u),g=await n.rect({parent:w,width:r,height:r,cornerRadius:3,fill:h,stroke:l,hand:!s}),f=await n.rect({parent:w,x:3,y:3,width:r-6,height:r-6,cornerRadius:2,fill:i,visible:a}),m=t?await n.text(t,{parent:w,x:r+6,y:Math.max(0,Math.round((r-12)/2)),...c?{font:c}:{},hand:!s}):null;let p=a,y=s;const b=async()=>{await f.update({visible:p}),await w.update({alpha:y?.5:1}),await g.update({hand:!y}),m&&await m.update({hand:!y})},v=()=>{y||(p=!p,b(),d.tell(p))};return g.on("click",v),m&&m.on("click",v),await b(),Object.assign(w,{value:()=>p,setValue:async M=>{p=M,await b()},setDisabled:async M=>{y=M,await b()},onChange:d.add})}async function Ja(n,e){const{choices:t=[],value:a="",placeholder:r="Choose...",rowHeight:i=16,maxRows:s=6,opens:o="down",disabled:h=!1,onChange:l,width:c=160,height:u=24,...d}=e,w=ve();l&&w.add(l);let g=t.map(Pt),f=a,m=h,p=null;const y=await n.group(d),b=()=>{var E;return((E=g.find(I=>I.value===f))==null?void 0:E.label)??r},v=await n.button(b(),{parent:y,width:c,height:u,hand:!m,disabled:m}),M=async()=>{const E=p;p=null,E&&await E.remove()},O=async()=>{if(m||p)return;const I=Math.max(1,Math.min(s,g.length))*i+8;p=await n.list({parent:y,x:0,y:o==="up"?-I:u+2,width:c,height:I,rows:g.map(F=>F.label),maxRows:Math.max(g.length,1)}),p.on("row",F=>{const U=g[F];M(),!(!U||U.value===f)&&(f=U.value,v.setLabel(b()),w.tell(f))})};return v.on("click",()=>{p?M():O()}),Object.assign(y,{value:()=>f,setValue:async E=>{f=E,await v.setLabel(b())},setChoices:async E=>{g=E.map(Pt),await M(),await v.setLabel(b())},setDisabled:async E=>{m=E,await M(),await v.setDisabled(E)},open:O,close:M,isOpen:()=>p!==null,onChange:w.add})}async function Qa(n,e){const{tabs:t=[],active:a,tabWidth:r,tabHeight:i=22,gap:s=2,activeFill:o=8141549,idleFill:h=3621201,onChange:l,font:c,...u}=e;if(t.length===0)throw new TypeError('overlay.tabs needs the tabs it is drawing: overlay.tabs({ tabs: [{ name: "one" }] })');const d=ve();l&&d.add(l);const w=await n.group(u),g=new Map,f=new Map;let m=a&&t.some(v=>v.name===a)?a:t[0].name,p=0;for(const v of t){const M=v.label??v.name,O=c?{font:c}:{},E=r??Math.ceil((await n.measure(M,O)).width)+16,I=await n.button(M,{parent:w,x:p,y:0,width:E,height:i,fill:v.name===m?o:h,...O});p+=E+s,f.set(v.name,I),g.set(v.name,await n.group({parent:w,y:i+s}))}const y=async()=>{await Promise.all([...f].map(([v,M])=>M.update({fill:v===m?o:h}))),await Promise.all([...g].map(([v,M])=>v===m?M.show():M.hide()))};for(const[v,M]of f)M.on("click",()=>{v!==m&&(m=v,y(),d.tell(v))});await y();const b=v=>{const M=g.get(v);if(!M)throw new TypeError(`There is no tab called "${v}"; these tabs are ${[...g.keys()].join(", ")}`);return M};return Object.assign(w,{value:()=>m,setValue:async v=>{b(v),m=v,await y()},show:async v=>{b(v),v!==m&&(m=v,await y(),d.tell(v))},page:b,onChange:d.add})}async function Za(n,e){const{width:t=240,height:a=160,step:r=24,onScroll:i,fill:s={color:0,alpha:.55},...o}=e,h=ve();i&&h.add(i);const l=await n.panel({...o,width:t,height:a,fill:s,stroke:null,cornerRadius:0,titleHeight:0,draggable:!1}),c=await n.group({parent:l});let u=0,d=0;const w=async()=>{const f=await c.bounds();d=Math.max(0,Math.round(f.y+u+f.height-a)),u>d&&await g(d)},g=async f=>{const m=Math.round(he(f,0,d));m!==u&&(u=m,await c.update({y:-u}),h.tell(u))};return l.on("wheel",({delta:f})=>{g(u-f*(r/3))}),await w(),Object.assign(l,{content:c,top:()=>u,scrollTo:g,scrollBy:f=>g(u+f),refresh:w,onScroll:h.add})}async function er(n,e){const{min:t=0,max:a=100,value:r,step:i,length:s=120,knobRadius:o=6,trackFill:h=3621201,knobFill:l=16777215,onChange:c,...u}=e;if(a<=t)throw new TypeError(`overlay.slider needs max above min; it was given ${t} and ${a}`);const d=ve();c&&d.add(c);const w=await n.group(u);await n.rect({parent:w,y:o-2,width:s,height:4,cornerRadius:2,fill:h});const g=a-t,f=b=>(he(b,t,a)-t)/g*s,m=b=>{const v=t+he(b,0,s)/s*g;return i&&i>0?he(Math.round(v/i)*i,t,a):v};let p=r===void 0?t:he(r,t,a);const y=await n.circle({parent:w,x:f(p),y:o,radius:o,fill:l,hand:!0,drag:{axis:"x",left:0,right:s,live:!0,...i&&i>0?{step:i/g*s}:{}}});return y.on("move",({x:b})=>{const v=m(b);v!==p&&(p=v,d.tell(p))}),Object.assign(w,{value:()=>p,setValue:async b=>{p=he(b,t,a),await y.update({x:f(p)})},onChange:d.add})}const tr=127;function Sn(n){const e=[],t=[];let a="",r=0;const i=()=>{const o={};for(const h of t)Object.assign(o,h.look);return o},s=()=>{if(a==="")return;const o={text:a,...i()},h=e[e.length-1];h&&or(h,o)?h.text+=a:e.push(o),a=""};for(;r<n.length;){const o=n[r];if(o!=="["){a+=o,r++;continue}if(n[r+1]==="["){a+="[",r+=2;continue}const h=n.indexOf("]",r+1),l=h<0?null:nr(n.slice(r+1,h));if(l===null){a+=o,r++;continue}if(l.closing){const c=sr(t,l.name);c<0?a+=n.slice(r,h+1):(s(),t.splice(c))}else s(),t.push({tag:l.name,look:l.look});r=h+1}return s(),e}function nr(n){if(n.startsWith("/")){const r=n.slice(1);return ar.has(r)?{name:r,closing:!0}:null}const e=n.indexOf("="),t=e<0?n:n.slice(0,e),a=e<0?null:n.slice(e+1);switch(t){case"b":return a===null?{name:t,closing:!1,look:{bold:!0}}:null;case"i":return a===null?{name:t,closing:!1,look:{italic:!0}}:null;case"u":return a===null?{name:t,closing:!1,look:{underline:!0}}:null;case"color":{const r=a===null?null:ir(a);return r===null?null:{name:t,closing:!1,look:{color:r}}}case"size":{const r=a===null?NaN:Number(a);return Number.isInteger(r)&&r>=1&&r<=tr?{name:t,closing:!1,look:{size:r}}:null}case"link":return a===null||a===""?null:{name:t,closing:!1,look:{link:a}};default:return null}}const ar=new Set(["b","i","u","color","size","link"]),rr="0123456789abcdef";function ir(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 a=0;for(const r of t){const i=rr.indexOf(r);if(i<0)return null;a=a*16+i}return a}function sr(n,e){for(let t=n.length-1;t>=0;t--)if(n[t].tag===e)return t;return-1}function or(n,e){return["color","bold","italic","underline","size","font","link"].every(a=>n[a]===e[a])}const We={className:"avatar.AvatarManager",path:["playerAvatarWorldView","parent"]},Rt=new Set(["click","down","up","over","out","hover","wheel"]);class lr{constructor(e){this.bridge=e}bridge;nodes=new Map;async draw(e,t={}){const{handle:a}=await this.make(e,t);return a}world(e={x:0,y:0},t={}){return{place:this.bridge.definition(We.className).at(We.path[0],We.path[1]),x:e.x,y:e.y,...t}}marker(e,t={}){const{kind:a="circle",...r}=t;return this.draw(a,{radius:8,...r,anchor:this.world(e)})}group(e={}){return this.draw("group",e)}text(e,t={}){return Be("text",e,"the words","overlay.text('hello', { x: 20 })"),this.draw("text",{...t,text:e})}rich(e,t={}){if(typeof e!="string"&&!Array.isArray(e))throw new TypeError("overlay.rich takes markup or spans first: overlay.rich('[b]hello[/b]', { x: 20 }). Its other fields go in the options.");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 Be("image",e,"the address","overlay.image('/path.png', { x: 20 })"),this.draw("image",{...t,url:e})}async input(e={}){const{handle:t,state:a}=await this.make("input",{width:200,height:24,fill:16777215,stroke:10265519,padding:4,...e,font:{color:1120295,...e.font}});return a.value=e.value??"",Object.assign(t,{value:()=>a.value,setValue:async i=>{a.value=i,a.removed||await this.bridge.draw(t.node,{value:i})},focus:async()=>{a.removed||await this.bridge.draw(t.node,{focus:!0})}})}async button(e,t={}){Be("button",e,"the label","overlay.button('Send', { x: 20 })");const{handle:a,state:r}=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(a,{setLabel:i=>r.removed?Promise.resolve():this.bridge.draw(a.node,{label:i}),setDisabled:i=>r.removed?Promise.resolve():this.bridge.draw(a.node,{disabled:i})})}async panel(e={}){const{onMove:t,onResize:a,...r}=e,{handle:i}=await this.make("panel",{width:260,height:200,fill:{color:1120295,alpha:.92},stroke:3621201,titleFill:2042167,titleHeight:22,cornerRadius:6,...r,titleFont:{color:16777215,bold:!0,...r.titleFont}}),s=i;return t&&s.on("move",t),a&&s.on("resize",a),s}async list(e={}){const{handle:t,state:a}=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:(...r)=>a.removed||r.length===0?Promise.resolve():this.bridge.draw(t.node,{append:r.map(qe)}),setRows:r=>a.removed?Promise.resolve():this.bridge.draw(t.node,{rows:r.map(qe)})})}checkbox(e={}){return Xa(this,e)}select(e={}){return Ja(this,e)}tabs(e){return Qa(this,e)}scroller(e={}){return Za(this,e)}slider(e={}){return er(this,e)}async measure(e,t={}){return await this.bridge.whenReady(),this.needs("measure","measuring text; draw it and read the node’s bounds instead"),this.bridge.measure({...typeof e=="string"?{text:e}:{spans:e},font:Nt(t.font??{}),padding:t.padding??0,...t.wrapWidth===void 0?{}:{wrapWidth:t.wrapWidth}})}row(e,t={}){return this.layout("row",e,t)}column(e,t={}){return this.layout("column",e,t)}async replace(e,t){return Ct("replace",e),await t.update({parent:null,host:null,replaces:e}),()=>t.remove()}async attach(e,t){return Ct("attach",e),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 layout(e,t,a){const r=a.gap??6,i=a.x??0,s=a.y??0,o=a.align??"start",h=t.filter(f=>this.nodes.has(f.node));if(h.length===0)return{width:0,height:0};const l=await Promise.all(h.map(f=>f.bounds())),c=Math.max(...l.map(f=>e==="row"?f.height:f.width));let u=e==="row"?i:s,d=0,w=0;const g=[];for(const[f,m]of h.entries()){const p=l[f],y=this.nodes.get(m.node),b=c-(e==="row"?p.height:p.width),v=o==="middle"?b/2:o==="end"?b:0,M=e==="row"?u:i+v,O=e==="row"?s+v:u,E=Math.round(y.x+(M-p.x)),I=Math.round(y.y+(O-p.y));(E!==y.x||I!==y.y)&&g.push(m.update({x:E,y:I})),d=Math.max(d,M-i+p.width),w=Math.max(w,O-s+p.height),u+=(e==="row"?p.width:p.height)+r}return await Promise.all(g),{width:d,height:w}}needs(e,t){if(!this.bridge.features.includes(e))throw new Error(`This game is running a loader from before ${t}`)}async allowed(e){await this.bridge.whenReady(),e.align!=null&&this.needs("align","aligning; place the node with x and y, and follow the stage yourself"),e.drag!=null&&this.needs("gestures","dragging; a panel is the one thing the player can move")}async make(e,t){var a;const r=this.bridge.allocate(),i={type:e,...this.specOf(t)};(i.align!==void 0||i.drag!==void 0)&&await this.allowed(i);const s={parent:t.parent?t.parent.node:null,children:new Set,listeners:new Map,failed:new Set,gone:new Set,stopHearing:()=>{},removed:!1,value:"",x:t.x??0,y:t.y??0};s.stopHearing=this.bridge.onSubscription(r,o=>{var h;if(o.kind==="overlay"){if(o.event==="failed"){s.failed.forEach(l=>l(o.message??"The image did not load"));return}(o.event==="change"||o.event==="submit")&&o.value!==void 0&&(s.value=o.value),o.event==="move"&&(s.x=o.x,s.y=o.y),(h=s.listeners.get(o.event))==null||h.forEach(l=>l(o))}}),this.nodes.set(r,s);try{await this.bridge.draw(r,i)}catch(o){throw s.stopHearing(),this.nodes.delete(r),o}return s.parent!==null&&((a=this.nodes.get(s.parent))==null||a.children.add(r)),{handle:this.handle(r,e,s),state:s}}handle(e,t,a){const r=()=>this.remove([e]);return Object.assign(r,{node:e,type:t,update:async s=>{var o,h;if(a.removed)return;const l=this.specOf(s);(l.align!==void 0||l.drag!==void 0)&&await this.allowed(l),s.x!==void 0&&(a.x=s.x),s.y!==void 0&&(a.y=s.y),"parent"in s&&(a.parent!==null&&((o=this.nodes.get(a.parent))==null||o.children.delete(e)),a.parent=s.parent?s.parent.node:null,a.parent!==null&&((h=this.nodes.get(a.parent))==null||h.children.add(e))),await this.bridge.draw(e,l)},bounds:async()=>{if(a.removed)throw new Error("That node has been removed, so it is nowhere and no size");return await this.bridge.whenReady(),this.needs("measure","measuring; a node cannot say where it is or how big"),this.bridge.bounds(e)},show:()=>a.removed?Promise.resolve():this.bridge.draw(e,{visible:!0}),hide:()=>a.removed?Promise.resolve():this.bridge.draw(e,{visible:!1}),remove:r,on:(s,o)=>{const h=o,l=g=>{switch(g.event){case"change":case"submit":case"link":h(g.value??"");return;case"focus":case"blur":h(void 0);return;case"row":h(g.index??-1);return;case"move":h({x:g.x,y:g.y});return;case"resize":h({width:g.width??0,height:g.height??0});return;case"wheel":h({x:g.x,y:g.y,delta:g.delta??0});return;default:h({x:g.x,y:g.y})}};let c=a.listeners.get(s);const u=!c||c.size===0;c||(c=new Set,a.listeners.set(s,c)),c.add(l);const d=Rt.has(s);u&&d&&this.sendMouse(e,a);let w=!1;return async()=>{w||(w=!0,c.delete(l),d&&c.size===0&&!a.removed&&await this.sendMouse(e,a))}},onFailed:s=>(a.failed.add(s),()=>{a.failed.delete(s)}),onRemoved:s=>a.removed?(s(),()=>{}):(a.gone.add(s),()=>{a.gone.delete(s)})})}async sendMouse(e,t){const a=[...t.listeners.entries()].filter(([r,i])=>Rt.has(r)&&i.size>0).map(([r])=>r);await this.bridge.draw(e,{mouse:a})}async remove(e){const t=[],a=[],r=s=>{var o;const h=this.nodes.get(s);!h||h.removed||(h.removed=!0,h.stopHearing(),this.nodes.delete(s),t.push(s),a.push(...h.gone),h.gone.clear(),h.children.forEach(r),h.parent!==null&&((o=this.nodes.get(h.parent))==null||o.children.delete(s)))};e.forEach(r);const i=e.filter(s=>t.includes(s));try{await this.bridge.erase(i)}finally{for(const s of a)try{s()}catch(o){console.error("phantom.flash.overlay: a removal listener failed",o)}}}specOf(e){const t={};for(const[a,r]of Object.entries(e))if(r!==void 0)switch(a){case"parent":t.parent=r===null?null:r.node;break;case"anchor":t.anchor=r===null?null:hr(r);break;case"host":case"replaces":t[a]=r===null?null:ur(r);break;case"fill":case"background":case"hoverFill":case"pressedFill":case"titleFill":t[a]=r===null?null:dr(r);break;case"stroke":t.stroke=r===null?null:fr(r);break;case"font":case"titleFont":t[a]=Nt(r);break;case"drag":t.drag=r===null||r===!1?null:r===!0?{}:r;break;case"rich":t.spans=r===null?null:typeof r=="string"?Sn(r):r;break;case"rows":case"append":t[a]=r.map(qe);break;default:t[a]=r}return t}}function cr(n){return typeof n=="function"&&typeof n.node=="number"}function Be(n,e,t,a){if(typeof e!="string")throw new TypeError(`overlay.${n} takes ${t} first: ${a}. Everything else goes in the options.`)}function Ct(n,e){if(cr(e))throw new TypeError(`overlay.${n} takes the client's place first and your node second: overlay.${n}(place, node).`)}function Nt(n){return{family:"_sans",size:12,color:16777215,bold:!1,italic:!1,...n}}function qe(n){if(typeof n=="string")return n||" ";const e=(Array.isArray(n)?n:Sn(n.markup)).filter(t=>t.text.length>0);return e.length?e:" "}function hr(n){const e=typeof n=="object"&&n!==null&&"place"in n?n:{place:n},t=A(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 ur(n){const e=typeof n=="object"&&n!==null&&"place"in n?n:{place:n},t=A(e.place);return{target:t.target,path:t.path,refreshFrames:e.refreshFrames??12}}function dr(n){return typeof n=="number"?{color:n,alpha:1}:{color:n.color,alpha:n.alpha??1}}function fr(n){return typeof n=="number"?{color:n,alpha:1,width:1}:{color:n.color,alpha:n.alpha??1,width:n.width??1}}async function wr(n,e,t,a,r={}){if(typeof a!="function")throw new TypeError(`phantom.flash.override("${t}", ...) was given ${pr(a)} where its handler goes. An override takes its handler second and its options third: override(name, handler, options). A hook is the other way about: hook(name, options, listener).`);const i=e.find(t);if(!i)throw new TypeError(`There is no hook "${t}" in the hook table`);const s=r.perFrame??Pe,o=r.sequential??!0,h={perFrame:s};r.when!==void 0&&(h.when=r.when),r.first!==void 0&&(h.first=r.first),r.every!==void 0&&(h.every=r.every),r.replaceArgs!==void 0&&(h.replaceArgs=r.replaceArgs),"returns"in r&&(h.skip={returns:r.returns});const l={...rt(n,i,h,!1),override:!0};let c=0,u=Promise.resolve(),d=!1;const w=B(i),g=async y=>{c++;let b=!1,v=!1;const M=y.args.map(F=>_(n,n.decode(F))),O=mr(i,M),E=i.isStatic?N(n,n.definition(i.className),{className:i.className}):_(n,n.decode(y.self)),I={hook:i,call:y.call,self:E,args:O,argList:M,arg:F=>M[gr(i,F)],original:async(...F)=>{if(v)throw new z("FLASH",`The call of ${w} has ended: its handler finished`);b=!0;const U=await n.invokeOriginal(f,y.token,F.length===0?null:await te(n,F));return _(n,U)}};try{await a(I)}catch(F){if(console.error(`The override of ${w} failed: ${F instanceof Error?F.message:String(F)}`),!b&&(r.onError??"original")==="original")try{await n.invokeOriginal(f,y.token,null)}catch(U){console.error(`The original ${w} failed after its override did: ${U instanceof Error?U.message:String(U)}`)}}finally{v=!0,c--;try{await n.overrideDone(f,y.token)}catch{}}},{registration:f,stop:m}=await n.hook(i.id,l,y=>{switch(y.kind){case"override":o?u=u.then(()=>g(y)):g(y);return;case"hook-dropped":r.onDropped?r.onDropped(y.dropped):d||(d=!0,console.warn(`The override of ${w} let ${y.dropped} calls through untouched in one frame: it catches at most ${s} a frame, and 256 may wait on handlers at once. `+(s<Pe?`Raise perFrame (${Pe} is the most the game allows), `:"Let the handler finish sooner, narrow the override with when/first/every, ")+"or pass onDropped to count them yourself. Said once per override."));return;case"hook-failed":console.error(`The override of ${w} failed and is off: ${y.error.message}`);return}}),p=Object.assign(()=>m(),{registration:f,hook:i,stats:async()=>(await n.request({op:"hookStats"})).find(b=>b.registration===f)??null});return Object.defineProperty(p,"running",{get:()=>c,enumerable:!0}),p}function ct(n){return n.parameters.map(e=>e.name).join(", ")||"none"}function gr(n,e){if(typeof e=="number"||/^\d+$/.test(e)){const a=Number(e);if(!Number.isInteger(a)||a<0||n.parameters.length>0&&!n.rest&&a>=n.parameters.length)throw new RangeError(`${B(n)} has no argument ${a} (its arguments: ${ct(n)})`);return a}const t=n.parameters.findIndex(a=>a.name===e);if(t>=0)return t;throw new TypeError(`${B(n)} has no argument "${e}" (its arguments: ${ct(n)})`)}function mr(n,e){const t={};return e.forEach((a,r)=>{var i;t[((i=n.parameters[r])==null?void 0:i.name)??String(r)]=a}),Object.defineProperty(t,Symbol.iterator,{value:()=>{throw new TypeError(`${B(n)}: call.args holds the arguments by name (${ct(n)}), so it does not destructure in order. Take call.argList for that, or call.arg(name) for one.`)}}),t}function pr(n){if(n===void 0)return"nothing";if(n===null)return"null";if(Array.isArray(n))return"a list";if(typeof n=="object"){const e=Object.keys(n).slice(0,4).join(", ");return e?`an options object (${e})`:"an object"}return`a ${typeof n}`}const yr=2,br=1e4,vr=12,kr=["room.RoomManagerWorld.sceneAssetsLoaded","gui.GuiHud.init"];async function _t(n,e){const t=Math.max(1,Math.trunc(e));let a=0,r=null,i=!1;return new Promise((s,o)=>{const h=l=>{i||(i=!0,r&&r().catch(()=>{}),s(l))};n.tick(1,l=>{a+=1,a>=t&&h(l)}).then(l=>{r=l,i&&l().catch(()=>{})}).catch(o)})}function Se(n){return n!=null&&n!==!1}function xr(n,e,t){const a=t.timeoutMs??br;return new Promise((r,i)=>{let s=!1,o=null,h;const l=c=>{s||(s=!0,h!==void 0&&clearTimeout(h),o&&o().catch(()=>{}),r(c))};Number.isFinite(a)&&(h=setTimeout(()=>l(null),Math.max(0,a))),n(c=>{if(s)return;let u=!1;try{u=e(c)}catch(d){s=!0,h!==void 0&&clearTimeout(h),o&&o().catch(()=>{}),i(d instanceof Error?d:new Error(String(d)));return}u&&l(c)}).then(c=>{o=c,s&&c().catch(()=>{})}).catch(c=>{s||(s=!0,h!==void 0&&clearTimeout(h),i(c instanceof Error?c:new Error(String(c))))})})}class Mr{constructor(e,t,a,r,i){this.bridge=e,this.table=t,this.source=a,this.attach=r,this.options=i}bridge;table;source;attach;options;live=!0;held=null;detach=null;looking=!1;again=!1;async look(){if(this.looking){this.again=!0;return}this.looking=!0;try{do this.again=!1,await this.lookOnce();while(this.again&&this.live)}finally{this.looking=!1}}async end(){this.live=!1,await this.letGo(!1),await this.bridge.note(this.table,"clear").catch(()=>{})}async lookOnce(){if(!this.live)return;const e=await this.find();if(!e)return this.letGo(!0);try{await this.lookAt(e)}finally{ue(this.source)||await Sr(e)}}async lookAt(e){let t;try{t=await this.bridge.note(this.table,"has",A(e))===!0}catch{return this.letGo(!0)}if(t&&this.held)return;const a=await ae(e).get().catch(()=>null);if(!(a instanceof W))return this.letGo(!0);if(await this.letGo(!1),!this.live){await a.release().catch(()=>{});return}try{await this.bridge.note(this.table,"write",a.at().entry,!0)}catch{await a.release().catch(()=>{});return}this.held=a;try{const r=await this.attach(N(this.bridge,a.at(),{handle:a}));typeof r=="function"&&(this.detach=r)}catch(r){this.failed(r)}this.live||await this.letGo(!1)}async find(){if(ue(this.source))return this.source;try{const e=await this.source();return ue(e)?e:null}catch{return null}}async letGo(e){var t,a;const r=this.held,i=this.detach;if(this.held=null,this.detach=null,i)try{await i()}catch(s){this.failed(s)}if(r&&(await this.bridge.note(this.table,"forget",r.at().entry).catch(()=>{}),await r.release().catch(()=>{}),e&&this.live))try{(a=(t=this.options).onGone)==null||a.call(t)}catch(s){this.failed(s)}}failed(e){if(this.options.onFailed){try{this.options.onFailed(e)}catch{}return}console.error("phantom.flash.whenever: what was put on the object failed",e)}}async function Sr(n){if(n instanceof W){await n.release().catch(()=>{});return}const e=n.$release;typeof e=="function"&&await e().catch(()=>{})}class Er{constructor(e){this.host=e}host;moments=new Map;async whenever(e,t,a={}){const r=this.host.bridge;if(await r.whenReady(),!r.features.includes("notes")||!r.features.includes("tick"))throw new Error("This game is running a loader from before notes; put it on the object yourself each time");if(!ue(e)&&typeof e!="function")throw new TypeError("Expected a place in the game, or a function that finds one");if(typeof t!="function")throw new TypeError("Expected a function to run on the object each time it is made");const i=new Mr(r,r.allocate(),e,t,a),s=()=>{i.look().catch(()=>{})},o=a.moments??kr;for(const u of o)this.join(u,i);const h=Math.max(1,Math.trunc(a.everyFrames??vr));let l;try{l=await r.tick(h,s)}catch(u){for(const d of o)this.leave(d,i);throw u}await i.look();let c=!1;return async()=>{if(!c){c=!0;for(const u of o)this.leave(u,i);await l().catch(()=>{}),await i.end()}}}join(e,t){let a=this.moments.get(e);if(!a){const r=new Set,i=this.host.hook(e,{phase:"exit",capture:{args:[]}},()=>{for(const s of[...r])s.look().catch(()=>{})}).catch(()=>null);a={keepers:r,stop:i},this.moments.set(e,a)}a.keepers.add(t)}leave(e,t){const a=this.moments.get(e);a&&(a.keepers.delete(t),!(a.keepers.size>0)&&(this.moments.delete(e),a.stop.then(r=>r==null?void 0:r().catch(()=>{}))))}}const Tr={fit:"showAll",stretch:"exactFit",fill:"noBorder",none:"noScale"};class Or{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(Tr[e])}hideHud(e){return this.bridge.highlight({target:{kind:"definition",name:"gui.GuiManager"},path:e?["mainHud",e]:["mainHud"]},be({hide:!0}))}hideLayer(e){return this.bridge.highlight({target:{kind:"definition",name:"gMainFrame"},path:["layerManager",e]},be({hide:!0}))}async setQuality(e){await this.bridge.stage().at("quality").set(e)}async setFrameRate(e){const t=this.bridge.stage().at("frameRate"),a=await t.get();return await t.set(Math.max(1,Math.min(120,e))),a}}class wt extends fn{format="json";envelope;constructor(e,t){super(e,t),this.envelope=Ar(e)}static create(e,t,a,r=-1,i="o"){const s=e==="toServer"?{t:"xt",b:{x:i,c:t,r,p:a}}:{t:"xt",b:{r,o:{_cmd:t,...a}}};return new wt(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 Ar(n){let e;try{e=JSON.parse(n)}catch(t){throw new vt(`Not JSON: ${t.message}`,"JSON_SYNTAX")}if(!Ft(e)||typeof e.t!="string"||!Ft(e.b))throw new vt('A JSON message is an object with "t" and "b"',"JSON_SYNTAX");return e}function Ft(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}class Lt extends fn{constructor(e,t,a=null){super(e,t),this.problem=a}problem;format="raw";get command(){return null}get room(){return null}serialize(){return this.raw}}function En(n,e){try{switch(n.charAt(0)){case"<":return new Un(n,e);case Bn:return new qn(n,e);case"{":return new wt(n,e);default:return new Lt(n,e)}}catch(t){return new Lt(n,e,t)}}const ht={send:"avatar.UserCommXtCommManager.onSendMessage",focusChat:"gui.ChatHistory.setFocusOnMsgText"};function $r(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 a="",r="";const i=()=>{a+=t.get(r.toLowerCase())??r,r=""};for(const s of n)s===" "||s===" "?(i(),a+=s):r+=s;return i(),a}function Pr(n,e){const t=n.toLowerCase();return e.some(a=>typeof a=="string"?a!==""&&t.includes(a.toLowerCase()):(a.lastIndex=0,a.test(n)))}async function Rr(n,e={}){const{arg:t,fromClass:a,equals:r,exists:i,all:s}=n.flash.rules,o=e.shortcuts??{},h=e.blocked??[],l=a("avatar.UserCommXtCommManager","_mainHud","chatBar","text01_chat","text"),c=[],u=gt(async()=>{for(const d of c.splice(0).reverse())await d().catch(()=>{})});try{c.push(await n.flash.hook(ht.send,{when:s(r(t("myMsg"),""),i(l)),replaceArgs:{myMsg:l}})),c.push(await n.flash.override(ht.send,async d=>{var w;const[g,f]=d.argList,m=typeof f=="string"?f:"";if(m.trim()!==""&&Pr(m,h)){(w=e.onBlocked)==null||w.call(e,m);return}const p=$r(m,o);p===m?await d.original():await d.original(g,p)},{sequential:!0}))}catch(d){throw await u(),d}return u}async function Cr(n,e={}){const t=e.style??{},a=n.flash.overlay,r=n.flash.use("gui.GuiManager").$at("mainHud"),i=e.maxLength??await n.flash.use("gui.GuiManager").$at("chatHist","chatMsgText","maxChars").$get().then(l=>typeof l=="number"&&l>0?l:70).catch(()=>70),s={family:t.font??"_sans",size:t.size??13},o=[],h=gt(async()=>{for(const l of o.splice(0).reverse())await l().catch(()=>{})});try{o.push(async()=>{await n.flash.use("gui.GuiManager").setFocusToChatText()});const l=await a.input({replaces:r.$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(()=>l.remove());const c=await a.button(t.buttonLabel??"Send",{replaces:r.$at("sendChatBtn"),fill:t.button??8141549,hoverFill:t.buttonHover??9133302,cornerRadius:t.cornerRadius??6,font:{...s,color:t.buttonText??16777215,bold:!0}});o.push(()=>c.remove());let u=!1;const d=async()=>{const w=l.value();if(!(u||w.trim()==="")){u=!0;try{await n.chat.say(w),await l.setValue(""),await l.focus()}finally{u=!1}}};return o.push(l.on("submit",()=>{d()})),o.push(c.on("click",()=>{d()})),o.push(await n.flash.hook(ht.focusChat,{skip:!0,phase:"enter",capture:{args:[]}},()=>{l.focus()})),(e.focus??!0)&&await l.focus(),Object.assign(h,{input:l,send:d})}catch(l){throw await h(),l}}const Nr=[16096779,1096065,3900150,15485081,9133302,15680580,1357990,15381256],Ue=22;async function _r(n,e={}){const t=e.style??{},a=n.flash.overlay,r=t.nameColors&&t.nameColors.length>0?t.nameColors:Nr,i=e.width??280,s=e.height??200,o={family:t.font??"_sans",size:t.size??12},h=new Map,l=[],c=gt(async()=>{for(const u of l.splice(0).reverse())await Promise.resolve(u()).catch(()=>{})});try{const u=await a.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:Ue,titleFont:{...o,color:t.titleText??16777215,bold:!0},...e.onMove?{onMove:e.onMove}:{}});l.push(()=>u.remove());const d=await a.list({parent:u,width:i,height:s-Ue,fill:null,maxRows:e.maxRows??200,font:{...o,color:t.text??15987958}});l.push(u.on("resize",p=>{var y;(y=e.onResize)==null||y.call(e,p),d.update({width:p.width,height:p.height-Ue})})),l.push(d.on("link",p=>{const y=h.get(p);if(y){if(e.onNameClick){e.onNameClick(y);return}Fr(n,y.userId)}}));const w=async p=>{let y=null;if(p.kind===De.free||p.kind===De.freeSafeChat?y=p.text:p.kind===De.safeChat&&(y=await n.chat.phrase(p.text).catch(()=>null)??null),y===null)return null;const b=n.room.players.get(p.userId),v=(b==null?void 0:b.avatarName)||(b==null?void 0:b.userName)||`#${p.userId}`,M=String(p.userId);return h.set(M,{userId:p.userId,name:v}),[{text:v,bold:!0,color:r[Math.abs(p.userId)%r.length],link:M},{text:`: ${y}`}]},f=(await Promise.all(n.chat.recent.map(w))).filter(p=>p!==null);f.length>0&&await d.append(...f);let m=Promise.resolve();return l.push(n.chat.onMessage(p=>{m=m.then(async()=>{const y=await w(p);y&&await d.append(y)}).catch(()=>{})})),Object.assign(c,{panel:u,note:p=>d.append({markup:p})})}catch(u){throw await c(),u}}async function Fr(n,e){const t=n.flash.use("avatar.AvatarManager").avatarViewList.$at(String(e)),a=await n.flash.highlight(t,{color:16436245,strength:3});setTimeout(()=>{a()},2e3)}function gt(n){let e=null;return()=>e??=n()}class Lr{constructor(e){return this.bridge=e,this.overlay=new lr(e),this.entities=new Ia(this),this.view=new Or(e),this.timing=new Er(this),Ya(this)}bridge;overlay;entities;view;rules=ba;hookIndex=null;timing;use(e){return N(this.bridge,this.bridge.definition(e),{className:e})}global(e){return N(this.bridge,this.bridge.definition(e))}stage(){return N(this.bridge,this.bridge.stage())}client(){return N(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(a=>new ya(a));t.catch(()=>{this.hookIndex===t&&(this.hookIndex=null)}),this.hookIndex=t}return this.hookIndex}async describe(e,t={}){return Oa(this.bridge,await this.hooks(),e,t)}async search(e,t={}){return Aa(await this.hooks(),e,t)}async hook(e,t={},a){return va(this.bridge,await this.hooks(),e,t,a)}async override(e,t,...[a]){return wr(this.bridge,await this.hooks(),e,t,a??{})}style(e,t){return this.bridge.style(A(e),t)}hold(e,t,a={}){return st(this.bridge,[{place:e,value:t}],a)}holdAll(e,t={}){return st(this.bridge,e,t)}repeat(e,t={}){return ka(this.bridge,e,t)}collect(e,t,a={}){return Sa(this.bridge,e,t,a)}async track(e,t,a={}){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 r=a.where===void 0?{target:{kind:"stage"},path:[]}:A(a.where),i=s=>s.filter(o=>o instanceof W).map(o=>N(this.bridge,o.at(),{handle:o}));return this.bridge.track(r,e,{...a.mode!==void 0?{mode:a.mode}:{},...a.everyFrames!==void 0?{everyFrames:a.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(A(e),t)}notes(){return new Ka(this.bridge)}async find(e,t){return await ja(this.bridge,t,e??{})}answering(e,t){return new Ma(this.bridge,e,t)}watch(e,t,a){const r=a;let i,s=[],o;if(Array.isArray(e))i="list",o=[...e];else if(jt(e))i="one",o=[e];else{i="record";const u=e;s=Object.keys(u),o=s.map(d=>u[d])}const h=o.map(A),l=u=>i==="one"?u[0]:i==="list"?u:Object.fromEntries(s.map((d,w)=>[d,u[w]]));let c=null;return this.bridge.watch(h,t,(u,d)=>{const w=u.map(m=>_(this.bridge,m)),g=l(w),f=h.map((m,p)=>(d==null?void 0:d[p])??null);r(g,c,i==="one"?f[0]:l(f)),c=g})}frames(e=1){return _t(this.bridge,e)}nextFrame(){return _t(this.bridge,1)}until(e,t,a={}){const r=typeof t=="function"?a:t??a,i=typeof t=="function"?t:h=>jr(h,jt(e)),s=r.everyFrames??yr,o=this.watch.bind(this);return xr(h=>o(e,{everyFrames:s},h),i,r)}whenever(e,t,a={}){return this.timing.whenever(e,t,a)}onTick(e,t={}){return this.bridge.tick(t.everyFrames??1,e)}highlight(e,t={}){return this.bridge.highlight(A(e),be(t))}hide(e){return this.bridge.highlight(A(e),be({hide:!0}))}recolor(e,t){const a=t?A(t):{target:{kind:"loader"},path:[]};return this.bridge.highlight(a,{glow:null,...pn(e),hide:!1,pulse:null})}onKey(e,t,a={}){return this.bridge.onKey(Ha(e,a),r=>Ir(t)({code:r.code,char:r.char,ctrl:r.ctrl,shift:r.shift,alt:r.alt,phase:r.phase,consumed:r.consumed===!0}))}}function Ir(n){return e=>{try{const t=n(e);t instanceof Promise&&t.catch(a=>It(a))}catch(t){It(t)}}}function It(n){console.error("phantom.flash.onKey: a listener failed",n)}function jr(n,e){return e?Se(n):Array.isArray(n)?n.every(Se):n&&typeof n=="object"?Object.values(n).every(Se):Se(n)}function jt(n){try{return A(n),!0}catch{return!1}}const Dr={avatarManager:"avatar.AvatarManager"},zr="com.sbi.loader.LoaderCache.fetchCDNURL",Dt=2e4;class Hr{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 a=this.reach(),r=zt(e);await this.unhook(Ve(r));const i=await a.replace(r,Ge(t)),s=[],o=await this.pointClientAt(r,i.url);return o&&(this.hooks.set(Ve(r),o),s.push("client")),s.push("proxy"),{...i,how:s,stop:()=>this.restore(r).then(()=>{})}}async restore(e){const t=this.reach(),a=zt(e);return await this.unhook(Ve(a)),t.restore(a)}replacements(){return this.reach().list()}onRequest(e){return this.reach().observe(e)}async replaceOnScreen(e,t,a={}){const{url:r,id:i}=await this.addressOf(t),{refreshFrames:s,...o}=a,h=await this.flash.overlay.image(r,{...o,replaces:s===void 0?e:{place:e,refreshFrames:s}});return{url:r,stop:async()=>{await h.remove(),i&&await this.reach().release(i)}}}async load(e,t={}){const a=this.flash.bridge,r=Ge(e),i=await a.construct("flash.display.Loader"),s=[];try{const o=await a.definition("flash.system.ApplicationDomain").at("currentDomain").get();s.push(()=>o.release());const h=await a.construct("flash.system.LoaderContext",!1,o);s.push(()=>h.release()),await h.at("allowCodeImport").set(t.allowCode===!0).catch(()=>{});const l=this.whenLoaded(i,t.timeoutMs??Dt);if(r.kind==="data-url"){const u=await this.decodeInFlash(r.url);s.push(()=>u.release()),await i.at("loadBytes").call(u,h)}else{const u=await this.reach().hold(r);s.push(()=>this.reach().release(u.id)),await i.at("load").call(new ye("flash.net.URLRequest",[u.url]),h)}await l;const c=await i.at("content").get();if(!c)throw new Error("Nothing was loaded");return{content:c,loader:i,unload:async()=>{await i.at("unloadAndStop").call().catch(()=>{}),await c.release().catch(()=>{}),await i.release().catch(()=>{})}}}catch(o){throw await i.release().catch(()=>{}),o}finally{for(const o of s)await o().catch(()=>{})}}async loadAddress(e,t={}){const a=this.flash.bridge,r=await a.construct("flash.display.Loader"),i=[];try{const s=await a.definition("flash.system.ApplicationDomain").at("currentDomain").get();i.push(()=>s.release());const o=await a.construct("flash.system.LoaderContext",!1,s);i.push(()=>o.release()),await o.at("allowCodeImport").set(t.allowCode===!0).catch(()=>{});const h=this.whenLoaded(r,t.timeoutMs??Dt);await r.at("load").call(new ye("flash.net.URLRequest",[e]),o),await h;const l=await r.at("content").get();if(!l)throw new Error("Nothing was loaded");return{content:l,loader:r,unload:async()=>{await r.at("unloadAndStop").call().catch(()=>{}),await l.release().catch(()=>{}),await r.release().catch(()=>{})}}}catch(s){throw await r.release().catch(()=>{}),s}finally{for(const s of i)await s().catch(()=>{})}}async pointClientAt(e,t){if(e.kind==="pattern")return null;const a=Wr(e.value);if(!a)return null;const{arg:r,equals:i,startsWith:s,any:o}=this.flash.rules,h=e.kind==="prefix"?s:i;try{return await this.flash.hook(zr,{when:o(h(r("assetPath"),a),h(r("assetPath"),`/${a}`)),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=Ge(e);if(t.kind==="data-url")return{url:t.url,id:null};const a=await this.reach().hold(t);return{url:a.url,id:a.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 a=await this.flash.bridge.definition("phantom.overlay.Base64").at("decode").call(e.slice(t+1));if(!a)throw new Error("The loader could not decode those bytes");return a}whenLoaded(e,t){const a=e.at("contentLoaderInfo");return new Promise((r,i)=>{const s=[],o=c=>{clearTimeout(h);for(const u of s.splice(0))u().catch(()=>{});c?i(c):r()},h=setTimeout(()=>o(new Error(`Flash did not load those bytes within ${t}ms`)),t),l=(c,u)=>a.listen(c,()=>o(u===null?null:new Error(u))).then(d=>s.push(d),d=>o(d));l("complete",null),l("ioError","Flash could not read those bytes"),l("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 Ve(n){return`${n.kind}:${n.value}`}function Wr(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 a=e.indexOf("/"),r=a===-1?e:e.slice(0,a);return a!==-1&&r.length>0&&Br(r)&&(e=e.slice(a+1)),e}function Br(n){for(const e of n)if(e<"0"||e>"9")return!1;return n.length>0}function zt(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 a=e.value.charAt(0)==="/"?e.value:`/${e.value}`;return{kind:t,value:a}}function Ge(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 a=n.bytes,r=a instanceof ArrayBuffer?new Uint8Array(a):a;if(!(r instanceof Uint8Array))throw new TypeError("bytes are a Uint8Array");return{kind:"bytes",bytes:r,...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 H={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"},qr={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"},ut={ink:1118483,line:3816e3,light:15790322,muted:10000543,accent:8141549,danger:15680580,size:12,cornerRadius:4},dt={ink:4403228,line:9071167,light:16643032,muted:9402972,accent:3123423,danger:13369344,size:11,cornerRadius:8},K={game:28,phantom:24},Ye=22,Ke=4,Ht={top:12,left:10,right:10,bottom:12},Wt=4293980400,Ur=12e4,Vr=500;function Z(n){return(...e)=>{try{const t=n(...e);t instanceof Promise&&t.catch(X)}catch(t){X(t)}}}function X(n){console.error("phantom.ui: a listener failed",n)}function Xe(n,e){console.warn(`phantom.ui: the picture ${n} did not load: ${e}`)}const Ee={game:110,phantom:96},ee=2,Bt=.5,Re="_sans";function Gr(n,e=Re){return{skin:n,font:e,...n==="game"?dt:ut}}const Yr={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."},Kr=/^[A-Za-z_][A-Za-z0-9_]*$/;function qt(n){if(!Kr.test(n))throw new TypeError(`"${n}" is not a symbol name: a symbol is named in letters, digits and underscores`);return n}const Ut={gui:{className:H.guiManager,path:["guiLayer"]},hud:{className:H.guiManager,path:["mainHud"]},room:{className:H.avatarManager,path:["playerAvatarWorldView","parent"]},avatarEditor:{className:H.guiManager,path:["avatarEditor","avEditor"]},denEditor:{className:H.denEditor,path:["staticEditor"]}},Vt="stage",Gt={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}},Xr=5,Yt=18,Jr={game:180,phantom:170},Qr=10,Zr=4,fe=8,Je=16,ei=240,Qe=20,ti=48,ni=-80,Kt={x:12,y:-10},P=8,Ze=22,Xt={game:320,phantom:300},ai={game:190,phantom:150},Te={x:60,y:90},ri={ok:0,yesNo:1,continueExit:2,continue:3};function ii(n,e,t={}){const a={slot:"layer"},r={slot:"callback"},i=t.name??null,s=qr[n];switch(n){case"message":return{className:s,args:[a,{slot:"skin"},e,!0,!0,t.modal??!1,t.draggable??!0,t.darken??!1,i]};case"ok":return{className:s,args:[a,e,t.darken??!0,null,!0,!0,t.modal??!0,t.draggable??!1,i]};case"yesNo":return{className:s,args:[a,e,t.darken??!0,r,null,!0,!0,t.modal??!0,t.draggable??!1,i]};case"okCancel":return{className:s,args:[a,e,t.darken??!0,r,null]};case"titled":return{className:s,args:[a,e,t.title??null,t.mediaId??370,r,!0,t.darken??!0]};case"parchment":return{className:s,args:[a,ri[t.buttons??"ok"],e,t.darken??!0,r,null]}}}function Jt(n){const e=Math.max(1,Math.floor(n.columns)),t=[];for(let a=0;a<Math.max(0,Math.floor(n.count));a++){const r=Math.floor(a/e),i=a%e;t.push({index:a,row:r,column:i,x:i*(n.tileWidth+n.gap),y:r*(n.tileHeight+n.gap),width:n.tileWidth,height:n.tileHeight})}return t}function si(n,e){const t=e.gap,a=n.length;if(a===0)return[];const r=(e.width+t)/a;return n.map((i,s)=>{const o=Math.round(s*r),h=s===a-1?e.width+t:Math.round((s+1)*r);return{index:s,value:i,x:o,width:Math.max(0,h-o-t)}})}function oi(n){const e=Math.max(0,n.contentHeight-n.viewHeight),t=Math.min(e,Math.max(0,n.offset)),a=n.minThumb??16,r=n.contentHeight>0?n.viewHeight/n.contentHeight:1,i=Math.max(Math.min(n.trackHeight,a),Math.min(n.trackHeight,Math.round(n.trackHeight*r))),s=n.trackHeight-i;return{offset:t,max:e,thumbY:e>0?Math.round(t/e*s):0,thumbHeight:i}}function li(n,e,t){const a=Math.max(1,Math.round(n-e-t+1)),r=-Math.floor(a/2);return{middle:a,middleY:r,topY:r-e,bottomY:r+a-1}}function ci(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,a=(s,o)=>{const h=t==null?void 0:t[s];return h!==void 0&&Number.isFinite(h)&&h>=2&&h<=o/4?Math.ceil(h):Ht[s]},r={top:a("top",n.height),left:a("left",n.width),right:a("right",n.width),bottom:a("bottom",n.height)},i={x:r.left+Ke,y:r.top,width:Math.max(0,Math.floor(n.width-r.left-r.right-2*Ke)),height:Math.max(Ye,Math.floor(n.height-r.top-r.bottom-Ke))};return{edge:r,measured:t!==null&&Object.keys(Ht).every(s=>r[s]===Math.ceil(t[s])),panel:i,titleHeight:Ye,body:{width:i.width,height:i.height-Ye}}}class hi{bridge;flash;drawn=new Set;popups=new Set;tags=new Map;symbolMaker=null;gameFont=null;defaultSkin="phantom";known={art:!1,palettes:!1};readyTimeoutMs=Ur;popup;constructor(e,t){this.bridge=e.flash,this.flash=t,this.popup=new ui((a,r,i,s,o)=>this.openPopup(a,r,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 a=[t.art?null:"its library art",t.palettes?null:"its colour palettes"].filter(Boolean);throw new Error(`The game has not loaded ${a.join(" or ")} yet: waited ${Math.round(e/1e3)} seconds`)}async theme(e){const t=e??this.defaultSkin;return Gr(t,t==="game"?await this.clientFont():Re)}symbols(){return Object.entries(Yr)}async hasSymbol(e){const t=qt(e);try{return await this.bridge.definition(H.resourceStack).at("hudAssetsLoaderInfo","applicationDomain","hasDefinition").call(t)===!0}catch{return!1}}async symbol(e,t={}){const a=qt(e);await this.waitFor({art:!0});const r=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,[a,t.localize===!0]),await(await this.nodeObject(r)).at("addChild").call(i),await this.adopt(r,{...t.parent===void 0||t.parent===null?{}:{parent:C(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(c){throw await r.remove(),i&&await this.bridge.release([i]).catch(()=>{}),c}const s=i,o=s.at(),h=new Set;return this.widget(r,t.skin??this.defaultSkin,{name:a,object:s,on:async(c,u)=>{const d=await o.listen(Qt[c],()=>u()),w=async()=>{h.delete(w),await d()};return h.add(w),w},size:async()=>({width:await s.at("width").get()??0,height:await s.at("height").get()??0})},async()=>{for(const c of[...h])await c().catch(()=>{});await this.bridge.release([s]).catch(()=>{})})}async window(e={}){const t=e.skin??this.defaultSkin,a=t==="game",r=a&&(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},h=a?30:24,l=await this.flash.overlay.panel({x:o.x,y:o.y,width:s.width,height:s.height,title:e.title??"",titleHeight:h,draggable:e.draggable!==!1,resizable:e.resizable===!0&&!a,cornerRadius:i.cornerRadius,fill:a?{color:i.light,alpha:0}:{color:i.ink,alpha:.94},stroke:a?null:i.line,titleFill:i.line,titleFont:{family:i.font,size:i.size+1,bold:!0,color:i.light},visible:!1});let c=null;if(r)try{c=await this.dressWindow(l,s.height)}catch(p){console.warn(`phantom.ui.window: the popup frame could not be drawn: ${Y(p)}`)}else a&&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=c?{x:c.layout.panel.x,y:c.layout.panel.y}:{x:0,y:0};if(c?await l.update({x:o.x+u.x,y:o.y+u.y,width:c.layout.panel.width,height:c.layout.panel.height,titleHeight:c.layout.titleHeight,titleFill:{color:i.line,alpha:.004},titleFont:{family:i.font,size:i.size+1,bold:!0,color:i.ink}}):a&&await l.update({fill:{color:dt.light,alpha:.96},stroke:{color:dt.line,width:2}}),e.parent)try{await this.adopt(l,{parent:C(e.parent)})}catch(p){throw await l.remove(),c&&await this.bridge.release(c.held).catch(()=>{}),p}const d=c?{width:c.width,height:c.height,bodyWidth:c.layout.body.width,bodyHeight:c.layout.body.height}:{...s,bodyWidth:s.width,bodyHeight:Math.max(0,s.height-h)},w=new Set,g=[],f=this.widget(l,t,{body:l,...d,framed:c!==null,move:(p,y)=>l.update({x:p+u.x,y:y+u.y}),setTitle:p=>l.update({title:p}),onClose:p=>(w.add(p),async()=>{w.delete(p)}),onMove:p=>{const y=l.on("move",({x:b,y:v})=>p({x:b-u.x,y:v-u.y}));return async()=>{await y()}}},async()=>{for(const p of g.splice(0))await p().catch(()=>{});c&&await this.bridge.release(c.held).catch(()=>{})}),m=()=>{f().then(()=>w.forEach(p=>p()))};if(e.closable!==!1&&(c!=null&&c.close)){const p=await c.close.at().listen(Qt.down,m);g.push(async()=>{await p()})}else e.closable!==!1&&(await this.flash.overlay.button("x",{parent:l,x:d.bodyWidth-(a?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 l.show(),f}async button(e,t={}){const a=t.skin??this.defaultSkin,r=await this.theme(a),i=this.box(t,{width:Ee[a],height:K[a]}),s=i.width??Ee[a],o=i.height??K[a],h=()=>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 l=t.image===void 0?null:await h(),c=e,u=l===null||t.imageOnly!==!0,d=t.disabled===!0;const w=await this.flash.overlay.button(u?c:"",{...l===null?i:{x:0,y:0,width:s,height:o,parent:l},...we(r,t.primary===!0),cornerRadius:r.cornerRadius,...t.disabled===void 0?{}:{disabled:t.disabled},font:{family:r.font,size:r.size,bold:!0,color:t.primary===!0||a==="phantom"?r.light:r.ink}}),g=o-ee*2,f=t.imageOnly===!0?{width:s-ee*2,height:g}:{width:g,height:g};let m=null;const p=async()=>{u||(u=!0,await w.setLabel(c))},y=async b=>{if(m){await m.update({url:b});return}m=await this.picture(b,{parent:l,x:ee,y:ee,...f,...d?{alpha:Bt}:{}},v=>{Xe("on a button",v),p().catch(X)})};return t.image!==void 0&&await y(t.image),this.widget(l??w,a,{label:()=>c,setLabel:async b=>{c=b,await w.setLabel(u?b:"")},setDisabled:async b=>{d=b,await w.setDisabled(b),m&&await m.update({alpha:b?Bt:1})},setImage:async b=>{if(l===null){if(b===null)return;l=await h(),await w.update({x:0,y:0,width:s,height:o,parent:l}),w.onRemoved(()=>{l.remove().catch(()=>{})})}if(b===null){const v=m;m=null,await(v==null?void 0:v.remove()),await p();return}u=t.imageOnly!==!0,await w.setLabel(u?c:""),await y(b)},onClick:b=>{const v=w.on("click",Z(b));return async()=>{await v()}}})}async label(e,t={}){const a=t.skin??this.defaultSkin,r=await this.theme(a),i=await this.flash.overlay.text(e,{x:t.x??0,y:t.y??0,...t.parent?{parent:C(t.parent)}:{},...t.visible===void 0?{}:{visible:t.visible},centered:t.centered===!0,font:{family:r.font,size:t.heading===!0?r.size+3:r.size,bold:t.heading===!0,color:t.muted===!0?r.muted:a==="game"?r.ink:r.light},...t.background===!0?{background:a==="game"?{color:r.light,alpha:.9}:{color:r.ink,alpha:.7},padding:4}:{}});return this.widget(i,a,{setText:s=>i.update({text:s})})}async input(e={}){const t=e.skin??this.defaultSkin,a=await this.theme(t),r=await this.flash.overlay.input({...this.box(e,{width:200,height:K[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"?a.light:16777215,stroke:a.line,cornerRadius:a.cornerRadius,font:{family:a.font,size:a.size,color:t==="game"?a.ink:1120295}});return this.widget(r,t,{value:()=>r.value(),setValue:i=>r.setValue(i),focus:()=>r.focus(),onChange:i=>{const s=r.on("change",Z(i));return async()=>{await s()}},onSubmit:i=>{const s=r.on("submit",Z(i));return async()=>{await s()}}})}async checkbox(e,t={}){const a=t.skin??this.defaultSkin,r=await this.theme(a),i=await this.flash.overlay.group({x:t.x??0,y:t.y??0,...t.parent?{parent:C(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,r.cornerRadius),fill:a==="game"?r.light:{color:r.ink,alpha:.9},hoverFill:a==="game"?16777215:{color:r.line,alpha:.9},stroke:r.line,font:{family:r.font,size:r.size,bold:!0,color:r.accent}});await this.flash.overlay.text(e,{parent:i,x:20,y:0,font:{family:r.font,size:r.size,color:a==="game"?r.ink:r.light}});const h=new Set,l=async c=>{s=c,await o.setLabel(c?"x":"")};return o.on("click",()=>{l(!s).then(()=>h.forEach(c=>c(s)))}),this.widget(i,a,{checked:()=>s,setChecked:l,onChange:c=>(h.add(c),async()=>{h.delete(c)})})}async dropdown(e){var t;const a=e.skin??this.defaultSkin,r=await this.theme(a),i=e.width??140,s=e.height??K[a],o=await this.flash.overlay.group({x:e.x??0,y:e.y??0,...e.parent?{parent:C(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}});let h=[...e.choices],l=e.value??((t=h[0])==null?void 0:t.value)??null;const c=f=>{var m;return((m=h.find(p=>p.value===f))==null?void 0:m.label)??e.placeholder??"Choose..."},u=await this.flash.overlay.button(c(l),{parent:o,width:i,height:s,cornerRadius:r.cornerRadius,...we(r,!1),font:{family:r.font,size:r.size,color:a==="game"?r.ink:r.light}}),d=await this.flash.overlay.list({parent:o,y:s+2,width:i,height:Math.min(140,Math.max(20,h.length*16+8)),visible:!1,fill:a==="game"?r.light:{color:r.ink,alpha:.96},stroke:r.line,cornerRadius:r.cornerRadius,rows:h.map(f=>f.label),font:{family:r.font,size:r.size,color:a==="game"?r.ink:r.light}});let w=!1;const g=new Set;return u.on("click",()=>{w=!w,w?d.show():d.hide()}),d.on("row",f=>{const m=h[f];w=!1,d.hide(),m&&(l=m.value,u.setLabel(m.label).then(()=>g.forEach(p=>p(m.value))))}),this.widget(o,a,{value:()=>l,setValue:async f=>{l=f,await u.setLabel(c(f))},setChoices:async f=>{h=[...f],await d.setRows(h.map(m=>m.label)),await u.setLabel(c(l))},onChange:f=>(g.add(f),async()=>{g.delete(f)})})}async tabs(e){var t;const a=e.skin??this.defaultSkin,r=await this.theme(a),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:C(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}),h=si(e.tabs.map(g=>g.value),{width:i,gap:2});let l=e.value??((t=e.tabs[0])==null?void 0:t.value)??"";const c=new Map,u=new Map,d=new Set;for(const g of h){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:r.cornerRadius,...we(r,f.value===l),font:{family:r.font,size:r.size,bold:f.value===l,color:f.value===l||a==="phantom"?r.light:r.ink}})),c.set(f.value,await this.flash.overlay.group({parent:o,y:s+4,visible:f.value===l}))}const w=async g=>{if(c.has(g)){l=g;for(const[f,m]of c)await(f===g?m.show():m.hide());for(const[f,m]of u)await m.update({...we(r,f===g),font:{family:r.font,size:r.size,bold:f===g,color:f===g||a==="phantom"?r.light:r.ink}})}};for(const[g,f]of u)f.on("click",()=>{w(g).then(()=>d.forEach(m=>m(g)))});return this.widget(o,a,{current:()=>l,select:w,body:g=>{const f=c.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,a=await this.theme(t),r=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"?a.light:{color:a.ink,alpha:.85},stroke:a.line,cornerRadius:a.cornerRadius,font:{family:a.font,size:a.size,color:t==="game"?a.ink:a.light}});return this.widget(r,t,{setRows:i=>r.setRows([...i]),append:(...i)=>r.append(...i),onRow:i=>{const s=r.on("row",Z(i));return async()=>{await s()}}})}async grid(e){const t=e.skin??this.defaultSkin,a=await this.theme(t),r={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:C(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}),s=new Set,o=[],h=async l=>{for(const u of o.splice(0))await u.remove();const c=Jt({count:l.length,...r});for(const u of c){const d=l[u.index],w=await this.flash.overlay.button(d.label??"",{parent:i,x:u.x,y:u.y,width:u.width,height:u.height,cornerRadius:a.cornerRadius,fill:d.color??(t==="game"?a.light:{color:a.ink,alpha:.9}),hoverFill:d.color??(t==="game"?16777215:a.line),pressedFill:d.color??a.accent,stroke:a.line,...d.disabled===void 0?{}:{disabled:d.disabled},font:{family:a.font,size:a.size-2,color:t==="game"?a.ink:a.light}});w.on("click",()=>s.forEach(g=>g(d.value,u.index))),o.push(w),d.image!==void 0&&o.push(await this.picture(d.image,{parent:i,x:u.x+ee,y:u.y+ee,width:u.width-ee*2,height:u.height-ee*2},g=>Xe(`on the grid tile ${d.value}`,g)))}};return await h(e.items),this.widget(i,t,{setItems:h,onSelect:l=>(s.add(l),async()=>{s.delete(l)})})}async image(e,t={}){const a=t.skin??this.defaultSkin,r=await this.theme(a),i=await this.flash.overlay.group({x:t.x??0,y:t.y??0,...t.parent?{parent:C(t.parent)}:{},...t.visible===void 0?{}:{visible:t.visible}}),s=new Set;let o=e,h=null,l=!1;const c=async()=>{if(l)return;l=!0;const d=t.width??K[a],w=t.height??K[a],g=await this.flash.overlay.group({parent:i,...t.centered===!0?{x:-Math.round(d/2),y:-Math.round(w/2)}:{}});h=g,await this.flash.overlay.rect({parent:g,width:d,height:w,cornerRadius:r.cornerRadius,fill:a==="game"?{color:r.light,alpha:.6}:{color:r.ink,alpha:.6},stroke:r.line}),!(t.alt===void 0||t.alt==="")&&await this.flash.overlay.text(t.alt,{parent:g,x:Math.round(d/2),y:Math.round(w/2),centered:!0,font:{family:r.font,size:r.size-1,color:r.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=>{Xe(t.alt===void 0?"drawn on its own":`of ${t.alt}`,d),c().catch(X),s.forEach(w=>w(d))});return this.widget(i,a,{source:()=>o,setSource:async d=>{o=d;const w=h;h=null,l=!1,await(w==null?void 0:w.remove()),await u.update({url:d})},onFailed:d=>{const w=Z(d);return s.add(w),async()=>{s.delete(w)}}})}async scroll(e={}){const t=e.skin??this.defaultSkin,a=await this.theme(t),r=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:r,height:i,titleHeight:0,draggable:!1,cornerRadius:a.cornerRadius,fill:t==="game"?{color:a.light,alpha:.9}:{color:a.ink,alpha:.85},stroke:a.line,...e.parent?{parent:C(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}),h=await this.flash.overlay.group({parent:o,x:0,y:0});let l=e.contentHeight??i,c=0;const u=async d=>{c=oi({contentHeight:l,viewHeight:i,offset:d,trackHeight:i}).offset,await h.update({y:-c})};for(const[d,w,g]of[["^",-s,0],["v",s,i-16]])(await this.flash.overlay.button(d,{parent:o,x:r-16,y:g,width:14,height:14,cornerRadius:Math.min(3,a.cornerRadius),...we(a,!1),font:{family:a.font,size:a.size-2,bold:!0,color:t==="game"?a.ink:a.light}})).on("click",()=>{u(c+w)});return this.widget(o,t,{body:h,offset:()=>c,scrollTo:u,setContentHeight:async d=>{l=d,await u(c)}})}async tooltip(e={}){const t=await this.bubble(e);return e.target&&this.explain(t,C(e.target)),t}async bubble(e){const t=e.skin??this.defaultSkin,a=e.text??"";if(t==="game"){const s=await this.clientTooltip(a,e);if(s)return s}const r=await this.theme(t),i=await this.flash.overlay.text(a,{x:e.x??0,y:e.y??0,visible:e.visible===!0,...e.parent?{parent:C(e.parent)}:{},background:t==="game"?{color:r.light,alpha:.95}:{color:r.ink,alpha:.92},padding:4,font:{family:r.font,size:r.size,color:t==="game"?r.ink:r.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 a=t.on("over",({x:s,y:o})=>{e.showAt(s+12,o-10).catch(X)}),r=t.on("out",()=>{e.hide().catch(X)}),i=t.onRemoved(()=>{e.remove().catch(X)});e.node.onRemoved(()=>{i(),a().catch(()=>{}),r().catch(()=>{})})}async progress(e={}){const t=e.skin??this.defaultSkin,a=await this.theme(t),r=e.width??200,i=e.height??16,s=await this.flash.overlay.group({x:e.x??0,y:e.y??0,...e.parent?{parent:C(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}});await this.flash.overlay.rect({parent:s,width:r,height:i,cornerRadius:a.cornerRadius,fill:t==="game"?a.light:{color:a.ink,alpha:.9},stroke:a.line});let o=Zt(e.value??0);const h=await this.flash.overlay.rect({parent:s,width:Math.round(r*o),height:i,cornerRadius:a.cornerRadius,fill:a.accent}),l=await this.flash.overlay.text(e.label??"",{parent:s,x:Math.round(r/2),y:Math.round(i/2),centered:!0,font:{family:a.font,size:a.size-1,bold:!0,color:t==="game"?a.ink:a.light}});return this.widget(s,t,{value:()=>o,setValue:async c=>{o=Zt(c),await h.update({width:Math.round(r*o)})},setLabel:c=>l.update({text:c})})}async colors(e={}){const t=e.skin??this.defaultSkin,a=e.columns??10,r=e.swatchWidth??24,i=e.swatchHeight??30,{values:s,indexes:o}=await this.palette(e.palette??1),h=new Set;let l=e.value??o[0]??0;const c=w=>{l=w,h.forEach(g=>g(w,s[w]??0))},u=Math.max(1,Math.ceil(o.length/a)),d=t==="game"?await this.clientColorTable({columns:a,rows:u,width:a*r,height:u*i,values:s,indexes:o,current:l,options:e,tell:c}):await this.swatchGrid({columns:a,swatchWidth:r,swatchHeight:i,values:s,indexes:o,current:l,options:e,tell:c});return this.widget(d,t,{value:()=>l,onPick:w=>(h.add(w),async()=>{h.delete(w)})})}async paletteValues(e="game"){const{values:t,indexes:a}=await this.palette(e);return a.map(r=>t[r]??0)}prompt(e,t={}){let a=()=>{};const r=new Promise(l=>{a=l});let i=!1,s=null;const o=async l=>{if(i)return;i=!0,this.popups.delete(h);const c=s;s=null,c&&await c().catch(()=>{}),a(l)},h=()=>o(null);return this.popups.add(h),(async()=>{const l=t.skin??this.defaultSkin,c=t.width??Xt[l],u=await this.window({skin:l,title:t.title??"",x:t.x??Te.x,y:t.y??Te.y,width:c,height:ai[l],closable:!0}),d=u.body,w=u.bodyWidth-2*P;await this.label(e,{skin:l,parent:d,x:P,y:P});const g=await this.input({skin:l,parent:d,x:P,y:P+Ze,width:w,...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(Ee[l],Math.floor((w-P)/2))},m=u.bodyHeight-P-K[l],p=await this.button(t.cancelLabel??"Cancel",{skin:l,parent:d,x:P,y:m,width:f.width}),y=await this.button(t.okLabel??"OK",{skin:l,parent:d,x:u.bodyWidth-P-f.width,y:m,width:f.width,primary:!0});if(s=async()=>{await u(),await this.flash.overlay.focusGame().catch(()=>{})},i){const b=s;s=null,await b();return}g.onSubmit(b=>{o(b)}),y.onClick(()=>{o(g.value())}),p.onClick(()=>{o(null)}),u.onClose(()=>{o(null)}),await g.focus()})().catch(l=>{console.error(`phantom.ui.prompt could not be drawn: ${Y(l)}`),o(null)}),Object.assign(r,{close:h})}choose(e,t,a={}){const r=t.map(u=>typeof u=="string"?{value:u,label:u}:u);let i=()=>{};const s=new Promise(u=>{i=u});let o=!1,h=null;const l=async u=>{if(o)return;o=!0,this.popups.delete(c);const d=h;h=null,d&&await d().catch(()=>{}),i(u)},c=()=>l(null);return this.popups.add(c),(async()=>{const u=a.skin??this.defaultSkin,d=a.width??Xt[u],w=Math.max(1,a.rows??Xr),g=Math.min(r.length||1,w)*Yt+2*P,f=await this.window({skin:u,title:a.title??"",x:a.x??Te.x,y:a.y??Te.y,width:d,height:P*4+Ze+g+K[u],closable:!0}),m=f.body,p=f.bodyWidth-2*P;await this.label(e,{skin:u,parent:m,x:P,y:P});const y=await this.list({skin:u,parent:m,x:P,y:P+Ze,width:p,height:g,rows:r.map(M=>M.label)}),b={width:Math.min(Ee[u],Math.floor((p-P)/2))},v=await this.button(a.cancelLabel??"Cancel",{skin:u,parent:m,x:f.bodyWidth-P-b.width,y:f.bodyHeight-P-K[u],width:b.width});if(h=async()=>{await f()},o){const M=h;h=null,await M();return}y.onRow(M=>{var O;l(((O=r[M])==null?void 0:O.value)??null)}),v.onClick(()=>{l(null)}),f.onClose(()=>{l(null)})})().catch(u=>{console.error(`phantom.ui.choose could not be drawn: ${Y(u)}`),l(null)}),Object.assign(s,{close:c})}menu(e,t={}){const a=e.map(c=>c==="-"?{label:"",value:null,disabled:!0,divider:!0,onSelect:void 0}:{label:c.label,value:c.value??c.label,disabled:c.disabled===!0,divider:!1,onSelect:c.onSelect});let r=()=>{};const i=new Promise(c=>{r=c});let s=!1,o=null;const h=async c=>{if(s)return;s=!0,this.popups.delete(l);const u=o;o=null,u&&await u().catch(()=>{}),r(c)},l=()=>h(null);return this.popups.add(l),(async()=>{const c=t.skin??this.defaultSkin,u=await this.theme(c),d=await this.stageSize(),w=Math.min(t.width??Jr[c],d.width),g=Math.min(Math.max(a.length,1),Math.max(1,t.rows??Qr)),f=Math.min(g*Yt+2*Zr,d.height),m=t.x===void 0&&t.y===void 0?await this.mouse():{x:t.x??0,y:t.y??0},p=m.x+w>d.width?Math.max(0,m.x-w):m.x,y=m.y+f>d.height?Math.max(0,m.y-f):m.y,b=await this.flash.overlay.rect({x:0,y:0,width:d.width,height:d.height,fill:{color:0,alpha:.01}});b.on("click",()=>{h(null)});const v=await this.list({skin:c,x:p,y,width:w,height:f,rows:a.map(M=>M.divider?[{text:"—".repeat(Math.max(4,Math.floor(w/9))),color:u.muted}]:M.disabled?[{text:M.label,color:u.muted}]:M.label)});if(o=async()=>{await v().catch(()=>{}),await b().catch(()=>{})},s){const M=o;o=null,await M();return}v.onRow(M=>{var O;const E=a[M];if(!(!E||E.divider||E.disabled||E.value===null)){try{(O=E.onSelect)==null||O.call(E)}catch(I){console.error(`A menu line's onSelect failed: ${Y(I)}`)}h(E.value)}})})().catch(c=>{console.error(`phantom.ui.menu could not be drawn: ${Y(c)}`),h(null)}),Object.assign(i,{close:l})}async menuButton(e,t,a={}){const{menu:r,...i}=a,s=await this.button(e,i),o=new Set;let h=t,l=!1;s.onClick(()=>{l||(l=!0,(async()=>{try{const u=typeof h=="function"?await h():h,d=await this.menu(u,{...a.skin?{skin:a.skin}:{},...r??{}});if(d===null)return;for(const w of[...o])try{w(d)}catch(g){console.error(`A menu button's onSelect failed: ${Y(g)}`)}}catch(u){console.error(`phantom.ui.menuButton could not open its menu: ${Y(u)}`)}finally{l=!1}})())});const c={onSelect:u=>(o.add(u),async()=>{o.delete(u)}),setItems:u=>{h=u}};for(const[u,d]of Object.entries(c))Object.defineProperty(s,u,{value:d,enumerable:!0,configurable:!0});return s}async notice(e,t={}){const a=t.skin??this.defaultSkin,r=await this.theme(a),i=t.seconds??6,s=t.width??ei,o=Math.max(Je,(a==="game"?s-ti:s)-2*fe),h=tt(e,tn(o,r.size)),l=await this.stageSize(),c={x:t.x??(l.width?l.width-s-Qe:Qe),y:t.y??Qe},u=await this.window({skin:a,title:t.title??"",x:c.x,y:c.y,width:s,height:2*fe+(h.length+1)*Je+(a==="game"?30:24),closable:t.closable!==!1,...t.draggable===void 0?{}:{draggable:t.draggable}}),d=Math.max(Je,Math.min(o,u.bodyWidth-2*fe)),w=tn(d,r.size),g=await this.label(tt(e,w).join(`
|
|
2
|
+
`),{skin:a,parent:u.body,x:fe,y:fe}),f=new Set;let m=!1;const p=i>0?setTimeout(()=>{u().catch(()=>{})},i*1e3):null,y=()=>{if(!m){m=!0,p&&clearTimeout(p);for(const b of[...f])Z(b)()}};return u.onClose(y),u.node.onRemoved(y),this.widget(u.node,a,{setText:async b=>{await g.setText(tt(b,w).join(`
|
|
3
|
+
`))},onClose:b=>(f.add(b),async()=>{f.delete(b)})},async()=>y())}async tag(e,t,a={}){const r=a.skin??this.defaultSkin,i=await this.theme(r),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=a.key??(typeof e=="number"?`player:${e}`:null),h=o?this.tags.get(o):void 0;h&&await h().catch(()=>{});const l=await this.flash.overlay.text(t,{anchor:{place:s,x:a.offsetX??0,y:a.offsetY??(typeof e=="number"?ni:0)},centered:!0,font:{family:i.font,size:a.heading===!0?i.size+3:i.size,bold:a.heading===!0,color:a.colour??(r==="game"?i.ink:i.light)},...a.background===!1?{outline:0}:{background:r==="game"?{color:i.light,alpha:.9}:{color:i.ink,alpha:.8},padding:4}}),c=a.seconds&&a.seconds>0?setTimeout(()=>{l.remove().catch(()=>{})},a.seconds*1e3):null,u=this.widget(l,r,{setText:d=>l.update({text:d})},async()=>{c&&clearTimeout(c),o&&this.tags.get(o)===u&&this.tags.delete(o)});return o&&this.tags.set(o,u),u}async tipOn(e,t,a={}){const r=a.skin??this.defaultSkin,i=await this.tooltip({skin:r,text:typeof t=="string"?t:""}),s=this.piece(e),o={x:a.offsetX??Kt.x,y:a.offsetY??Kt.y},h=async d=>{typeof t!="string"&&await i.setText(await t());const w=gi(d)??await this.mouse();await i.showAt(w.x+o.x,w.y+o.y)},l=await s.on("rollOver",d=>{h(d).catch(w=>{console.error(`phantom.ui.tipOn could not show the tooltip: ${Y(w)}`)})}),c=await s.on("rollOut",()=>{i.hide().catch(()=>{})});let u=!1;return async()=>{u||(u=!0,await l().catch(()=>{}),await c().catch(()=>{}),await i.remove().catch(()=>{}))}}async stageSize(){const e=this.bridge.stage(),[t,a]=await Promise.all([e.at("stageWidth").get().catch(()=>null),e.at("stageHeight").get().catch(()=>null)]);return{width:Ae(t),height:Ae(a)}}onStageResize(e){let t=!0,a=null;return(async()=>{const i=await this.bridge.stage().listen("resize",()=>{this.stageSize().then(s=>Z(e)(s)).catch(()=>{})});if(!t){await i();return}a=i})().catch(i=>{console.error(`phantom.ui.onStageResize could not hear the stage: ${Y(i)}`)}),()=>{t=!1;const i=a;a=null,i&&i().catch(()=>{})}}places(){const e=Object.keys(Ut);return[Vt,...e,...fi]}place(e){if(e===Vt)return this.bridge.stage();const t=Ut[e];return t?this.bridge.definition(t.className).at(...t.path):this.bridge.definition(H.guiManager).at("mainHud",e)}async attach(e,t){const a=C(t);return await this.flash.overlay.attach(this.placeOf(e),a),()=>a.remove()}async replace(e,t){const a=C(t);return await this.flash.overlay.replace(this.placeOf(e),a),()=>a.remove()}async hide(e){const t=await this.flash.hide(this.placeOf(e)),a=async()=>{this.drawn.delete(a),await t()};return this.drawn.add(a),a}piece(e,...t){return this.pieceOf(this.placeOf(e),t)}async feed(e,t,a={}){return typeof t=="function"?this.deferredFeed(e,t,a):this.insideFeed(e,t,a)}async insideFeed(e,t,a){if(!Object.keys(t).length)throw new TypeError(`A feed of ${e} names no argument to change`);let r=null,i=0;const s=await this.flash.hook(e,{phase:"enter",capture:{args:!0},replaceArgs:t,...a.when===void 0?{}:{when:a.when},...a.first===void 0?{}:{first:a.first},...a.every===void 0?{}:{every:a.every},...a.perFrame===void 0?{}:{perFrame:a.perFrame}},o=>{i+=1,r={method:e,call:o.call,args:[...o.argList],named:{...o.args},on:this.pieceOf(this.bridge.stage(),[])}});return this.feedOf(e,!0,s,()=>i,()=>r)}async deferredFeed(e,t,a){if(a.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 r=null,i=0;const s=async l=>{i+=1;const c={method:e,call:l.call,args:[...l.argList],named:{...l.args},on:this.pieceOf(ae(l.self)??this.bridge.stage(),[])};r=c;const u=await t(c);if(!u){await l.original();return}const d=[...c.args];for(const[w,g]of Object.entries(u)){const f=/^\d+$/.test(w)?Number(w):l.hook.parameters.findIndex(m=>m.name===w);if(f<0||f>=d.length){const m=l.hook.parameters.map(p=>p.name).join(", ");throw new TypeError(`${e} has no argument "${w}" (its arguments: ${m})`)}d[f]=g}await l.original(...d)},o={};a.when!==void 0&&(o.when=a.when),a.first!==void 0&&(o.first=a.first),a.every!==void 0&&(o.every=a.every),a.sequential!==void 0&&(o.sequential=a.sequential),a.perFrame!==void 0&&(o.perFrame=a.perFrame),a.returns!==void 0&&(o.returns=a.returns);const h=await this.flash.override(e,s,o);return this.feedOf(e,!1,h,()=>i,()=>r)}feedOf(e,t,a,r,i){const s=async()=>{this.drawn.delete(s),await a()};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:r,enumerable:!0}),Object.defineProperty(o,"last",{value:i,enumerable:!0}),o}screens(){return Object.keys(Gt)}onScreen(e,t){const a=Gt[e];let r=!0;const i=[];return(async()=>{for(const[o,h]of[[a.open,!0],[a.close,!1]]){const l=await this.flash.hook(o,{phase:h?"exit":"enter",capture:{args:[]}},()=>t({name:e,open:h,spot:a.spot}));if(!r){await l();return}i.push(l)}})().catch(o=>{console.error(`phantom.ui.onScreen could not hook ${e}: ${Y(o)}`)}),()=>{r=!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 a=ae(e);if(!a)throw new TypeError("Expected a place in the client, or one of Phantom's spots");const r=a.at(...t);return{place:r,at:(...s)=>this.pieceOf(r,s),exists:async()=>{try{const s=await r.get();return s!=null}catch{return!1}},get:async(...s)=>{try{const o=await r.at(...s).get();return _(this.bridge,o)??null}catch{return null}},set:(s,o)=>r.at(...typeof s=="string"?[s]:s).set(o),read:async(...s)=>{const o=await Promise.all(s.map(l=>r.at(l).get().catch(()=>null))),h={};return s.forEach((l,c)=>{h[l]=_(this.bridge,o[c]??null)}),h},call:async(s,...o)=>{const h=await te(this.bridge,o);return _(this.bridge,await r.at(s).call(...h))},on:async(s,o)=>{const h=await r.listen(s,c=>o(_(this.bridge,c))),l=async()=>{this.drawn.delete(l),await h()};return this.drawn.add(l),l},whenever:async(s,o={})=>{const h=await this.flash.whenever(r,c=>s(this.pieceOf(c,[])),o),l=async()=>{this.drawn.delete(l),await h()};return this.drawn.add(l),l},attach:s=>this.attach(r,s),replace:s=>this.replace(r,s),hide:()=>this.hide(r),use:()=>N(this.bridge,r)}}widget(e,t,a,r){let i=null;const s=()=>(i??=(async()=>{this.drawn.delete(o),r&&await r().catch(()=>{})})(),i),o=async()=>{await e.remove(),await s()};this.drawn.add(o),e.onRemoved(()=>{s()});const h={skin:t,node:e,move:(l,c)=>e.update({x:l,y:c}),show:()=>e.show(),hide:()=>e.hide(),remove:o,...a};for(const[l,c]of Object.entries(h))Object.defineProperty(o,l,{value:c,enumerable:!0,configurable:!0});return o}async picture(e,t,a){const r=await this.flash.overlay.image(e,t);return r.onFailed(Z(a)),r}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:C(e.parent)}:{},...e.visible===void 0?{}:{visible:e.visible}}}async anchorOf(e){if(typeof e=="number"){const r=(await this.flash.entities.players()).find(i=>i.id===String(e));return r?r.place:null}if(typeof e=="string")return this.place(e);if(ue(e))return e;const t=e.place;return ue(t)?t:null}async mouse(){const e=this.bridge.stage(),[t,a]=await Promise.all([e.at("mouseX").get().catch(()=>null),e.at("mouseY").get().catch(()=>null)]);return{x:Ae(t),y:Ae(a)}}placeOf(e){return typeof e=="string"?this.place(e):e}maker(){if(!this.symbolMaker){const e=this.bridge.definition(H.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 se(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 a=t.parent;if(a&&wi(a))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 a=Date.now()+Math.max(0,t);for(;;){const r=await this.status(),i=(!e.art||r.art)&&(!e.palettes||r.palettes),s=a-Date.now();if(i||s<=0||this.bridge.state==="closed")return r;await new Promise(o=>setTimeout(o,Math.min(Vr,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(H.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(H.fonts),t=this.known.palettes,a=(async()=>{for(const r of[["defaultFontFormat","font"],["defaultFont","fontName"]])try{const i=await e.at(...r).get();if(typeof i=="string"&&i.length>0)return i}catch{}return Re})();a.then(r=>{r===Re&&!t&&this.gameFont===a&&(this.gameFont=null)},()=>{this.gameFont===a&&(this.gameFont=null)}),this.gameFont=a}return this.gameFont}async frameOnly(e){const t=await e.at("numChildren").get()??0;for(let a=0;a<Math.min(t,32);a+=1){const r=await e.at("getChildAt").call(a);try{await r.at("name").get()!=="ba"&&await r.at("visible").set(!1)}finally{await this.bridge.release([r]).catch(()=>{})}}}async dressWindow(e,t){const r=await(await this.maker()).at("apply").call(null,["PopupSkin",!1]),i=[r];try{const s=r.at("ba"),[o,h]=await Promise.all([Oe(s.at("t","height")),Oe(s.at("b","height"))]),l=li(t,o,h);await Promise.all([s.at("m","height").set(l.middle),s.at("m","y").set(l.middleY),s.at("t","y").set(l.topY),s.at("b","y").set(l.bottomY)]),await this.frameOnly(r);const c=await this.boundsOf(s,r),u={width:Math.round(c.width),height:Math.round(c.height)},d=await this.parchmentOf(r,c).catch(()=>null),w=ci(u,d);await Promise.all([r.at("x").set(Math.round(-c.x-w.panel.x)),r.at("y").set(Math.round(-c.y-w.panel.y))]);const g=await this.nodeObject(e);i.push(g),await g.at("addChildAt").call(r,0);const f=await this.frameClose(g,w).catch(()=>null);return f&&i.push(f),{...u,layout:w,close:f,held:i}}catch(s){throw await this.bridge.release(i).catch(()=>{}),s}}async frameClose(e,t){const r=await(await this.maker()).at("apply").call(null,["closeBtn",!1]);try{const i=await this.boundsOf(r,r);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([r.at("scaleX").set(s),r.at("scaleY").set(s),r.at("x").set(Math.round(t.panel.width-2-(i.x+i.width)*s)),r.at("y").set(Math.round((t.titleHeight-i.height*s)/2-i.y*s))]),await e.at("addChild").call(r),r}catch(i){throw await this.bridge.release([r]).catch(()=>{}),i}}async boundsOf(e,t){const a=await e.at("getBounds").call(t);try{const[r,i,s,o]=await Promise.all(["x","y","width","height"].map(h=>Oe(a.at(h))));return{x:r,y:i,width:s,height:o}}finally{await this.bridge.release([a]).catch(()=>{})}}async parchmentOf(e,t){const a=Math.ceil(t.width),r=Math.ceil(t.height);if(a<=0||r<=0||a>2048||r>2048)return null;const i=await this.bridge.construct("flash.display.BitmapData",a,r,!0,0);try{await i.at("draw").call(e,new ye("flash.geom.Matrix",[1,0,0,1,-t.x,-t.y]));const s=await i.at("getPixel32").call(Math.floor(a/2),Math.floor(r/2));if(typeof s!="number"||s>>>24!==255)return null;const o=await i.at("getColorBoundsRect").call(Wt,(s&Wt)>>>0,!0);try{const[h,l,c,u]=await Promise.all(["x","y","width","height"].map(d=>Oe(o.at(d))));return{x:h,y:l,width:c,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 a;try{a=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 r=async i=>{await a.object.at("setToolTipText").call(i)};try{e&&await r(e)}catch{return await a.remove(),null}return Object.assign(a,{setText:r,showAt:async(i,s)=>{await a.node.update({x:i,y:s,visible:!0})}})}async palette(e){const t=await this.waitFor({palettes:!0}),a=this.bridge.definition(H.palette),r=t.palettes?await a.at("gamePalette").get():null,i=en(r);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,h)=>h)};const s=en(await a.at(e===1?"avatarPalette1":"avatarPalette2").get());return{values:i,indexes:s.length?s:i.map((o,h)=>h)}}async clientColorTable(e){const t=await this.flash.overlay.group({x:e.options.x??0,y:e.options.y??0,visible:!1});try{const a=await this.bridge.construct(H.colorTable);await a.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 r=await this.nodeObject(t);await r.at("addChild").call(a),await this.bridge.release([r,a]).catch(()=>{}),await this.adopt(t,{...e.options.parent?{parent:C(e.options.parent)}:{},visible:e.options.visible!==!1})}catch(a){throw await t.remove(),a}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:C(e.options.parent)}:{},...e.options.visible===void 0?{}:{visible:e.options.visible}}),a=Jt({count:e.indexes.length,columns:e.columns,tileWidth:e.swatchWidth,tileHeight:e.swatchHeight,gap:1}),r={color:ut.line,alpha:.6},i={color:ut.light,width:2},s=new Map;let o=e.current;for(const h of a){const l=e.indexes[h.index],c=await this.flash.overlay.button("",{parent:t,x:h.x,y:h.y,width:h.width,height:h.height,cornerRadius:2,fill:e.values[l]??0,hoverFill:e.values[l]??0,stroke:l===o?i:r});s.set(l,c),c.on("click",()=>{var u;const d=o;o=l,d!==l&&((u=s.get(d))==null||u.update({stroke:r}).catch(X),c.update({stroke:i}).catch(X)),e.tell(l)})}return t}openPopup(e,t,a,r,i){let s=()=>{};const o=new Promise(f=>{s=f});let h=null,l=!1,c=null;const u=f=>{l||(l=!0,c&&clearTimeout(c),c=null,this.popups.delete(w),s(f))},d=()=>{l||c||(c=setTimeout(()=>u(i),di))},w=async()=>{const f=h;h=null,u(i),f&&await f.at("destroy").call().catch(()=>{})};this.popups.add(w);const g=ii(e,t,a);return(async()=>{await this.waitFor({art:!0});const f=this.bridge.definition(a.layer==="load"?H.loadProgress:H.guiManager).at(a.layer==="load"?"loadLayer":"guiLayer"),m=[];for(const y of g.args){if(y!==null&&typeof y=="object"){if(y.slot==="layer")m.push(await f.get());else if(y.slot==="callback")m.push((...b)=>u(r(b[0]??null)));else{const b=await this.maker();m.push(await b.at("apply").call(null,["PopupSkin",!1]))}continue}m.push(y)}const p=await this.bridge.construct(g.className,...m);h=p,a.name!==void 0&&await p.at("name").set(a.name).catch(()=>{}),await p.at("closeCallback").set(()=>d()).catch(()=>{})})().catch(f=>{this.popups.delete(w),l||(l=!0,s(i)),console.error(`phantom.ui.popup.${e} could not open: ${Y(f)}`)}),Object.assign(o,{close:w})}}class ui{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,et,null)}yesNo(e,t={}){return this.open("yesNo",e,t,et,null)}titled(e,t={}){return this.open("titled",e,t,()=>{},void 0)}parchment(e,t={}){return this.open("parchment",e,t,et,null)}async closeAll(){await this.closeEverything()}}const di=50,Qt={click:"click",down:"mouseDown",up:"mouseUp",over:"rollOver",out:"rollOut"},fi=["chatBar","chatHist","chatTxt","sendChatBtn","safeChatBtn","actionsBtn","emotesBtn","denBtn","worldMapBtn","buddyListBtn","newsBtn","partyBtn","mySettingsBtn","money","zoneName"];function C(n){if(!n)throw new TypeError("Expected a widget or an overlay node");return typeof n.node=="number"?n:n.node}function wi(n){let e=!1;return n.onRemoved(()=>{e=!0})(),e}function we(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 et(n){if(n!==null&&typeof n=="object"&&!Array.isArray(n)){const e=n.status;if(typeof e=="boolean")return e}return null}function Zt(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 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 en(n){return Array.isArray(n)?n.map(e=>typeof e=="number"?e:0):[]}function tt(n,e){const t=[];for(const a of n.split(`
|
|
4
|
+
`)){let r="";for(const i of a.split(/\s+/).filter(Boolean))r?r.length+1+i.length<=e?r=`${r} ${i}`:(t.push(r),r=i):r=i;t.push(r)}return t.length?t:[""]}function tn(n,e){return Math.max(8,Math.floor(n/Math.max(1,e*.55)))}function gi(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 Ae(n){return typeof n=="number"&&Number.isFinite(n)&&n>0?n:0}const Tn=Symbol("phantom.call"),mi=new Set(["constructor","nodeType","tagName"]),nn=new Set;function pi(n,e,t){return new Proxy(n,{get(a,r,i){if(r===Tn)return e;if(typeof r=="symbol")return Reflect.get(a,r,i);if(r==="toString"||r==="toJSON")return()=>`[Phantom ${e}, a call]`;if(mi.has(r)||r.startsWith("__v_"))return Reflect.get(a,r,i);throw bi(e,r,t)}})}function yi(n){if(typeof n!="function")return null;const e=n[Tn];return typeof e=="string"?e:null}function bi(n,e,t){const a=vi(n,e);return S.development&&!nn.has(`${n}.${e}`)&&(nn.add(`${n}.${e}`),t(a)),new $("NOT_A_VALUE",a)}function vi(n,e){return un(n)&&dn(n)==="now"?`phantom.${n} takes a listener: phantom.${n}((...) => {}), and what it gives back stops it. Reading .${e} off it reads that function itself, not what the event carries.`:e==="then"?`await phantom.${n} awaits the call itself and hands the function straight back. Write await phantom.${n}(), with the brackets: a plugin asks Phantom for every value, so it awaits the call.`:`phantom.${n} is a call in a plugin: write await phantom.${n}(). Reading .${e} off it reads the call itself, not what it answers. A script has the SDK beside the game and reads phantom.${n} as a property; a plugin's frame has to ask Phantom for it.`}function Ce(n){return n instanceof $?{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:L(n)}}function On(n){const e=n&&typeof n.code=="string"&&n.code?n.code:"FAILED";return new $(e,(n==null?void 0:n.message)||"Phantom could not do this")}function pe(n){return ie(n,new WeakMap)}function ie(n,e){if(Xn(n))return ie(n.value,e);if(typeof n=="function"||typeof n=="symbol")return;if(typeof n!="object"||n===null)return n;const t=Jn(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 r=[];e.set(t,r);for(const i of t)r.push(ie(i,e));return r}if(t instanceof Map){const r=new Map;e.set(t,r);for(const[i,s]of t)r.set(ie(i,e),ie(s,e));return r}if(t instanceof Set){const r=new Set;e.set(t,r);for(const i of t)r.add(ie(i,e));return r}if(t instanceof Error)return Ce(t);const a={};e.set(t,a);for(const[r,i]of Object.entries(t)){const s=ie(i,e);s!==void 0&&(a[r]=s)}return a}function L(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"){const e=yi(n);return e?`[Phantom ${e}, a call]`:`[Function ${n.name||"anonymous"}]`}if(typeof n=="symbol"||typeof n=="bigint")return n.toString();try{const e=new WeakSet,t=JSON.stringify(pe(n),(a,r)=>{if(typeof r=="object"&&r!==null){if(e.has(r))return"[Circular]";e.add(r)}return typeof r=="bigint"?`${r}n`:r});return an(t??String(n))}catch{return an(String(n))}}const nt=1e4;function an(n){return n.length>nt?`${n.slice(0,nt)}… (${n.length-nt} more)`:n}const ki=["log","info","warn","error"];function xi(n,e){const t=new Map;let a=!1;for(const r of ki){const i=n[r].bind(n);t.set(r,i),n[r]=(...s)=>{if(i(...s),!a){a=!0;try{e(r,s.map(L))}finally{a=!1}}}}return()=>{for(const[r,i]of t)n[r]=i}}const mt={game:{id:"game",waiting:"the game to finish loading",detail:"The client is logged in and its world extension answers (phantom.session.ready). Until then a request can go quietly nowhere, which is why the client holds its own back too.",area:"session"},room:{id:"room",waiting:"the player to be in a room",detail:"The player is standing in a room. Read from the games Phantom already sends the frame, so it costs nothing and needs no permission.",area:null},language:{id:"language",waiting:"the game’s words to load",detail:"The client has its dictionary (phantom.localization.hasLocalizations), which arrives after login. Until then every text id translates to an empty string, so a plugin that recognises the game’s own wording has nothing to recognise it by.",area:"localization"},hud:{id:"hud",waiting:"the HUD to be drawn",detail:"The main HUD is on screen. The client makes it in GuiManager.init, once play has started, so anything hooked onto a HUD button before that is hooked onto nothing.",area:"gui"},interface:{id:"interface",waiting:"the game’s interface art to load",detail:"The client has its library art and its colour palettes (phantom.ui.status), which arrive as the player logs in. Drawing in the game skin, or reading a palette, needs them.",area:"ui"},shops:{id:"shops",waiting:"the item definitions to arrive",detail:"The client has its item definitions (phantom.shops.definitionsReady). Until then every item reads back as null, whether or not the id is real.",area:"shops"}},Mi=Object.keys(mt);function ne(n){const e=new Set(typeof n=="string"?[n]:n??[]);return Mi.filter(t=>e.has(t))}function An(n){const[e,...t]=ne(n);if(!e)return"It is ready.";const a=t.length===1?"one more thing":`${t.length} more things`;return`Waiting for ${mt[e].waiting}${t.length?`, and ${a} after it`:""}.`}function Si(n,e,t){return new Lr(new ua(Ei(n,e),{firstId:t}))}function Ei(n,e){const t=new Set;let a=null;const r=i=>{for(const s of t)s(i)};return{send(i){n.call("flash.request",e,[i]).catch(s=>{const o=Ti(i,s);o?r(o):n.log("warn",[`A Flash request was refused: ${L(s)}`])})},onMessage(i){return t.add(i),a??=n.subscribe("flash.messages",e,{event(s){const[o]=s;typeof o=="string"&&r(o)},ended(s){a=null,s&&n.log("warn",[`Flash stopped answering: ${s.message}`])}}),()=>{t.delete(i),!t.size&&a&&(a(),a=null)}}}}function Ti(n,e){let t;try{t=wn(n)}catch{return null}if(typeof(t==null?void 0:t.id)!="number")return null;const a=e instanceof $?e.code:"FAILED",r=e instanceof Error?e.message:L(e);return ce({kind:"result",id:t.id,ok:!1,error:{name:a,message:r,errorId:0}})}function Oi(n){let e=null,t=null;const a=()=>{const r=n.flash();return e??=new Hr({flash:r.bridge,content:Ai(n.port,n.game)},r),e};return{avatar:{view:()=>n.flash().bridge.definition(Dr.avatarManager).at("playerAvatarWorldView").get()},adventures:{record:()=>$i(n.remote)},realtime:{join:(r,i)=>Dn(n.remote.realtime,r,i),stayIn:(r,i,s)=>jn(n.remote.realtime,r,i,s)},customRooms:{prop:(r,i)=>In(n.remote.customRooms,r,i),object:(r,i)=>Ln(n.remote.customRooms,r,i),character:(r,i)=>Fn(n.remote.customRooms,r,i)},room:{surfaces:()=>Vn(n.flash().bridge)},content:{load:(r,i)=>a().load(r,i),replaceOnScreen:(r,i,s)=>a().replaceOnScreen(r,i,s)},ui:()=>{const r=n.flash();return t??=new hi({flash:r.bridge},r),t},recipes:{chatShortcuts:async r=>Rr(await at(n),r),customChatBox:async r=>Cr(await at(n),r),chatHistoryPanel:async r=>_r(await at(n),r)}}}function Ai(n,e){const t=()=>{throw new $("NOT_SUPPORTED","Only holding and releasing content happen in a frame")};return{hold:a=>n.call("content.hold",e,[a]),release:a=>n.call("content.release",e,[a]),replace:t,restore:t,list:t,observe:t}}function $i(n){const e=Date.now(),t=[];let a=null,r=null;const i=()=>{a===null&&n.adventures.current().then(o=>a??=(o==null?void 0:o.scriptDefId)??null).catch(()=>{}),r===null&&n.adventures.actor("diff_level").then(o=>r??=(o==null?void 0:o.state)??null).catch(()=>{})};i();const s=n.adventures.onStep(({time:o,...h})=>{i(),t.push({...h,at:o-e})});return{stop:()=>(s(),{version:1,scriptDefId:a,difficulty:r,steps:[...t]})}}async function at(n){const e=n.flash(),{remote:t}=n,a=[...await t.chat.recent()],r=new Map;for(const i of await t.room.players.list())r.set(i.userId,i);return t.room.players.onEnter(i=>r.set(i.userId,i)),t.room.players.onLeave(i=>r.delete(i.userId)),t.chat.onMessage(i=>a.push(i)),{flash:e,chat:{say:t.chat.say,phrase:t.chat.phrase,onMessage:t.chat.onMessage,recent:a},room:{players:{get:i=>r.get(i)??null}}}}function Pi(n,e){const t={};for(const a of Object.keys(zn)){const r=a.split(".");let i=t;for(const o of r.slice(0,-1))i=i[o]??={};const s=r[r.length-1];i[s]=un(a)?Ni(n,e,a,dn(a)):Ci(n,e,a)}return pt(t,"")}const Ri=new Set(["then","toJSON","constructor","nodeType","tagName"]);function pt(n,e){for(const[t,a]of Object.entries(Object.getOwnPropertyDescriptors(n))){const r=a.get||a.set?null:a.value;!r||typeof r!="object"||!a.writable||(n[t]=pt(r,`${e}${t}.`))}return new Proxy(Object.freeze(n),{get(t,a,r){if(typeof a!="string"||a in t)return Reflect.get(t,a,r);if(!(Ri.has(a)||a.startsWith("__v_")))throw new $("NOT_SUPPORTED",`phantom.${e}${a} 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 Ci(n,e,t){return $n(n,t,(...a)=>n.call(`sdk:${t}`,e,a))}function $n(n,e,t){return pi(t,e,a=>n.log("error",[a]))}function Ni(n,e,t,a){return $n(n,t,(...r)=>{const i=r.findIndex(u=>typeof u=="function");if(i===-1&&Hn(t))throw new TypeError(`${t} takes a listener function`);const s=i===-1?null:r[i],o=i===-1?r:[...r.slice(0,i),...r.slice(i+1)];let h=null;const l=a==="awaited"?new Promise((u,d)=>{h=(w,g)=>{h=null,w?u(w):d(g)}}):null,c=n.subscribe(`sdk:${t}`,e,{event:u=>s==null?void 0:s(...u),started:()=>h==null?void 0:h(()=>c()),ended(u){if(h){h(null,On(u??{code:"FAILED",message:`${t} could not be started`}));return}u&&n.log("warn",[`${t} stopped: ${u.code}: ${L(u.message)}`])}},{args:o,...i===-1?{}:{listenerAt:i}});return l??c})}const Pn=500,Rn=5e3,_i=12e4;function ft(n,e,t){return Math.min(t,e*2**Math.max(0,n-1))}const Fi={async game(n){const e=await n.call("session.ready");return(e==null?void 0:e.worldReady)===!0},room:async n=>{var e;return((e=n.view())==null?void 0:e.room)!=null},language:async n=>await n.call("localization.hasLocalizations")===!0,hud:async n=>await n.call("gui.bounds",["hud"])!=null,async interface(n){const e=await n.call("ui.status");return(e==null?void 0:e.art)===!0&&(e==null?void 0:e.palettes)===!0},shops:async n=>await n.call("shops.definitionsReady")===!0};function Li(n){let e=null;const t=new Set;let a=null;function r(c){return new Promise((u,d)=>{const w=setTimeout(()=>{t.delete(g),u()},c),g=f=>{clearTimeout(w),d(f)};t.add(g)})}function i(c){const u=c??n.boundGame();if(u)return u;throw new $("NO_GAME","This frame works with several games: name one, as ctx.ready.wait(what, { game }), from ctx.games()")}function s(c){if(!(!c.area||n.can(`sdk:${c.area}:read`)))throw new $("PERMISSION_DENIED",`Waiting for "${c.id}" reads sdk:${c.area}:read, which this plugin was not granted: add "${c.area}" to permissions.sdk`)}function o(c){return{call:(u,d=[])=>n.port.call(`sdk:${u}`,c,d).catch(()=>null),view:()=>n.games().find(u=>u.id===c)??null}}async function h(c,u){const d=ne(c);if(!d.length)return[];for(const f of d)s(mt[f]);const w=o(u??i(void 0)),g=await Promise.all(d.map(f=>Fi[f](w)));return d.filter((f,m)=>g[m]!==!0)}const l={async missing(c,u){return h(ne(c),i(u==null?void 0:u.game))},async check(c,u){return(await l.missing(c,u).catch(()=>[...ne(c)])).length===0},async wait(c,u){const d=ne(c),w=i(u==null?void 0:u.game),g=(u==null?void 0:u.timeoutMs)??_i,f=Number.isFinite(g)?Date.now()+g:1/0;for(let m=1;;m++){if(a)throw new $e(a,d);const p=await h(d,w);if(!p.length)return;if(Date.now()>=f)throw new $e(`${An(p)} It did not happen in ${Math.round(g/1e3)} seconds.`,p);await r(ft(m,Pn,Rn))}},waitingFor(c){const u=typeof c=="string"&&c.trim()?c.trim().slice(0,200):null;u!==e&&(e=u,n.onReason(e))}};return{api:l,missing:h,get reason(){return e},dispose(c){a=c,e=null;for(const u of[...t])u(new $e(c));t.clear()}}}function rn(n,e,t,a){const r=i=>({direction:a,...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 h=ji(o,a);h&&s(En(h.text,h.direction))},ended:o=>{o&&n.log("warn",[`Watching the traffic stopped: ${o.message}`])}},{filter:r(i)})},on(i,s){return n.subscribe("packets.intercept",e,{event:()=>{},intercepted:o=>{Ii(n,o,s)},ended:o=>{o&&n.log("warn",[`Hooking the traffic stopped: ${o.message}`])}},{filter:r(i)})}}}async function Ii(n,e,t){let a;try{a=En(e.text,e.direction),await t(a)}catch(r){n.log("error",[`A traffic hook failed: ${L(r)}`]),n.verdict(e.requestId,!1,null);return}n.verdict(e.requestId,a.dropped,a.modified?a.encode():null)}function ji(n,e){const[t,a]=n;if(typeof t=="string")return{text:t,direction:sn(a)?a:e};if(typeof t=="object"&&t!==null){const{text:r,direction:i}=t;if(typeof r=="string")return{text:r,direction:sn(i)?i:e}}return null}function sn(n){return n==="toServer"||n==="toClient"}function Di(n,e={}){const t=new Map,a=new Set,r=Li({port:n,boundGame:()=>Ne(S.role),games:()=>S.games,can:l=>on(S.granted.scopes,l),onReason:l=>{var c;return(c=e.onWaitingFor)==null?void 0:c.call(e,l)}}),i=new Set;function s(l){var c,u;const d=l??Ne(S.role);if(!d)throw new $("NO_GAME",((c=S.role)==null?void 0:c.kind)==="page"||((u=S.role)==null?void 0:u.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 w=t.get(d);return w||(w=zi(n,d),t.set(d,w)),w}function o(l){const c=l?S.players[l]:void 0;return c?{...S.preferences,...c}:S.preferences}return{ctx:{get plugin(){return S.plugin},get granted(){return S.granted},get preferences(){return S.preferences},get preferenceFields(){return S.preferenceFields},preferencesFor(l){const c=S.games.find(u=>u.id===String(l));return o((c==null?void 0:c.accountId)??null)},onPreferences(l){return i.add(l),()=>i.delete(l)},setPreferences:(l,c)=>n.call("preferences.set",(c==null?void 0:c.game)??null,[l&&typeof l=="object"?{...l}:{}]),snag:(l,c)=>{n.call("snag",null,[String(l),c===null?null:String(c)]).catch(u=>n.log("error",[`A snag could not be told: ${L(u)}`]))},get snags(){return S.snags},can:l=>on(S.granted.scopes,l),games:()=>[...S.games],onGames(l){return a.add(l),()=>a.delete(l)},phantom:s,ready:r.api,storage:{get:l=>n.call("storage.get",null,[String(l)]),set:(l,c)=>n.call("storage.set",null,[String(l),c]),remove:l=>n.call("storage.remove",null,[String(l)]),keys:()=>n.call("storage.keys",null,[])},async fetch(l,c){const u=await n.call("fetch",null,[String(l),c??{}]);return Hi(u)},copy:l=>n.call("copy",null,[String(l)]),notify:(l,c)=>n.call("notify",null,c===void 0?[String(l)]:[String(l),String(c)]),toast:(l,c)=>n.call("toast",null,[String(l),c??{}]),confirm:(l,c)=>n.call("confirm",null,[String(l),c??{}]),openUrl:l=>n.call("openUrl",null,[String(l)]),openPanel:(l,c)=>n.call("panel.open",(c==null?void 0:c.game)??null,[String(l)]),closePanel:(l,c)=>n.call("panel.close",(c==null?void 0:c.game)??null,[String(l)]),log:(...l)=>n.log("log",l.map(L))},ready:r,notifyGames(l){for(const c of[...a])try{c([...l])}catch(u){n.log("error",[`An onGames listener failed: ${L(u)}`])}},notifyPreferences(){for(const l of[...i])try{l(S.preferences)}catch(c){n.log("error",[`An onPreferences listener failed: ${L(c)}`])}},dispose(){r.dispose("The frame was closed"),a.clear(),i.clear(),t.clear()}}}function zi(n,e){let t=null;const a=()=>{if(t)return t;if(S.flashIds===null)throw new $("PERMISSION_DENIED","game.flash needs the flash scope, which this plugin was not granted");return t=Si(n,e,S.flashIds),t},r=Pi(n,e),i=Oi({port:n,game:e,remote:r,flash:a}),s={...r,avatar:Object.freeze({...r.avatar,...i.avatar}),adventures:Object.freeze({...r.adventures,...i.adventures}),content:Object.freeze({...r.content,...i.content}),realtime:Object.freeze({...r.realtime,...i.realtime}),customRooms:Object.freeze({...r.customRooms,...i.customRooms}),room:Object.freeze({...r.room,...i.room}),recipes:Object.freeze(i.recipes),id:e,server:rn(n,e,"toServer","toClient"),client:rn(n,e,"toClient","toServer")};return Object.defineProperties(s,{flash:{enumerable:!0,get:a},ui:{enumerable:!0,get:i.ui}}),pt(s,"")}function on(n,e){if(n.includes(e))return!0;if(!e.startsWith("network:"))return!1;const t=e.slice(8);return n.some(a=>{if(!a.startsWith("network:*."))return!1;const r=a.slice(9);return t.endsWith(r)&&t.length>r.length})}function Hi(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 Wi=6e4;function Bi(n,e={}){const t=e.prefix??`f${Math.random().toString(36).slice(2,10)}-`,a=e.timeoutMs??Wi;let r=0,i=!1;const s=new Map,o=new Map,h=()=>`${t}${r+=1}`;function l(f,m){if(!i)try{n({phantom:q,type:"log",level:f,values:m})}catch{}}function c(f,m,p){if(i)return Promise.reject(new $("FAILED","The frame was closed"));const y=h();return new Promise((b,v)=>{const M=setTimeout(()=>{s.delete(y),v(new $("TIMEOUT",`Phantom did not answer ${f} in ${a/1e3}s`))},a);s.set(y,{resolve:b,reject:v,timer:M});try{n({phantom:q,type:"call",id:y,method:f,game:m,args:pe(p)})}catch(O){clearTimeout(M),s.delete(y),v(new $("FAILED",`${f} could not be sent: ${L(O)}`))}})}function u(f,m,p,y={}){if(i)return g(()=>{var v;return(v=p.ended)==null?void 0:v.call(p,{code:"FAILED",message:"The frame was closed"})}),()=>{};const b=h();o.set(b,p);try{n({phantom:q,type:"subscribe",id:b,topic:f,game:m,...y.filter?{filter:pe(y.filter)}:{},...y.args?{args:pe(y.args)}:{},...typeof y.listenerAt=="number"?{listenerAt:y.listenerAt}:{}})}catch(v){throw o.delete(b),new $("FAILED",`${f} could not be heard: ${L(v)}`)}return()=>{!o.delete(b)||i||n({phantom:q,type:"unsubscribe",id:b})}}function d(f,m,p){i||n({phantom:q,type:"verdict",requestId:f,drop:m,text:p})}function w(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(On(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"subscribed":{const m=o.get(f.subscription);return m?(g(()=>{var p;return(p=m.started)==null?void 0:p.call(m)}),!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 p;return(p=m.ended)==null?void 0:p.call(m,f.error)}),!0):!1}}}function g(f){try{f()}catch(m){l("error",[`A listener failed: ${L(m)}`])}}return{call:c,subscribe:u,verdict:d,log:l,receive:w,close(f){if(!i){i=!0;for(const m of s.values())clearTimeout(m.timer),m.reject(new $("FAILED",f));s.clear(),o.clear()}}}}function qi(n,e,t=new Set){const a=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),a.add(i));for(const i of t)a.has(i)||n.style.removeProperty(i);const r=(e==null?void 0:e.mode)==="light"?"light":"dark";return n.dataset.theme=r,n.style.setProperty("color-scheme",r),a}const Ui=2e3,Vi=1e3,Gi=3e4;function Yi(n,e){Yn(e.development??!1);let t=!1,a=new Set,r=null,i=null;function s(k){var x;t||(n.post(k),(x=e.tap)==null||x.call(e,k))}const o=Bi(s);let h=null,l=null,c;const u=new Promise(k=>c=k);function d(){const k=w.ready.reason,x=h?{...h,reason:k}:k?{for:[],reason:k,attempt:0,nextInMs:null}:null,T=JSON.stringify(x);T!==l&&(l=T,s({phantom:q,type:"waiting",game:Ne(S.role),waiting:x}),x&&c())}const w=Di(o,{onWaitingFor:()=>d()}),g=w.ctx;kt(g);function f(k){var x;const T=Ce(k);try{s({phantom:q,type:"crash",error:T})}catch{}(x=n.view)==null||x.showError(T,S.development)}let m;const y=new Promise(k=>m=k).then(async()=>{try{const k=e.definition,x=await(typeof k=="function"?k():k);return r=Ki(x),!0}catch(k){return f(k),!1}}),b=y.then(async k=>{var x;if(!k||((x=S.role)==null?void 0:x.kind)!=="logic")return k;const T=ge(r==null?void 0:r.widgets);return s({phantom:q,type:"ready",implements:{pages:ge(r==null?void 0:r.pages),panels:ge(r==null?void 0:r.panels),commands:ge(r==null?void 0:r.commands),commandViews:ge(r==null?void 0:r.commandViews),...T.length?{widgets:T}:{}}}),!(r!=null&&r.setup)&&!M().length||await Promise.race([O(),u]),!0}),v=k=>new Promise(x=>setTimeout(x,k));function M(){return ne([...S.requires,...(r==null?void 0:r.requires)??[]])}async function O(){const k=r==null?void 0:r.setup,x=M(),T=Ne(S.role);x.length&&!T&&o.log("warn",[`definePlugin requires ${x.join(", ")}, but this plugin runs once for every game at once, so there is no one game to be ready. Wait inside setup instead, as ctx.ready.wait(what, { game }).`]);for(let R=0,D=0;!t;){if(x.length&&T){let j;try{j=await w.ready.missing(x,T)}catch(V){h=null,d(),f(V);return}if(j.length){const V=ft(D+=1,Pn,Rn);h={for:j,attempt:R,nextInMs:V},d(),await v(V);continue}D=0}R+=1;try{const j=await(k==null?void 0:k(g));h=null,d(),typeof j=="function"&&(t?bt(j):i=j);return}catch(j){const V=await E(j,x,T);if(!V){h=null,d(),f(j);return}const je=ft(R,Vi,Gi);o.log("warn",[`setup said the game is not ready (${L(j)}).`,`Try ${R} of it; Phantom will run it again in ${Math.round(je/1e3)}s.`]),h={for:V,attempt:R,nextInMs:je},d(),await v(je)}}}async function E(k,x,T){const R=x.length&&T?await w.ready.missing(x,T).catch(()=>[]):[];if(Gn(k)){const D=ne(k.waitingFor);return D.length?D:R}return R.length?R:null}function I(k){if(t||!Wn(k))return;const x=k;switch(x.type){case"init":F(x);return;case"games":S.games=Array.isArray(x.games)?x.games:[],w.notifyGames(S.games);return;case"snags":S.snags=Array.isArray(x.snags)?x.snags:[];return;case"stop":_n();return;case"mount":Cn(x);return;case"invoke":Nn(x);return;case"call-result":case"event":case"subscribed":case"subscription-ended":case"intercepted":o.receive(x);return}}function F(k){var x;n.root&&k.theme&&(a=qi(n.root,k.theme,a));const T=JSON.stringify([S.preferences,S.players]);Object.assign(S,{role:S.role??k.role??null,plugin:k.plugin??S.plugin,mode:((x=k.theme)==null?void 0:x.mode)==="light"?"light":"dark",granted:k.granted??{scopes:[]},requires:ne(k.requires),preferences:k.preferences??{},preferenceFields:Array.isArray(k.preferenceFields)?k.preferenceFields:[],players:k.players??{},snags:Array.isArray(k.snags)?k.snags:[],games:Array.isArray(k.games)?k.games:[],flashIds:typeof k.flashIds=="number"?k.flashIds:null,development:S.development||!!k.development,initialized:!0}),w.notifyGames(S.games),JSON.stringify([S.preferences,S.players])!==T&&w.notifyPreferences(),m()}const U=n.listen(I);async function Cn(k){var x,T;const[R]=await Promise.all([y,((x=n.loadStyles)==null?void 0:x.call(n))??Promise.resolve()]);t||((T=S.role)==null?void 0:T.kind)==="logic"||(Object.assign(S,{kind:k.kind,contribution:k.contribution,props:k.props??{}}),R&&yt())}function yt(){var k;if(!S.kind||!S.contribution)return;const[x,T]=S.kind==="page"?[r==null?void 0:r.pages,"pages"]:S.kind==="panel"?[r==null?void 0:r.panels,"panels"]:S.kind==="widget"?[r==null?void 0:r.widgets,"widgets"]:[r==null?void 0:r.commandViews,"commandViews"],R=x==null?void 0:x[S.contribution];if(!R){f(new $("NOT_SUPPORTED",`definePlugin has no ${T}["${S.contribution}"], so there is nothing to show here`));return}try{(k=n.view)==null||k.mount(R,g)}catch(D){f(D)}}async function Nn(k){var x,T;const R=(D,j)=>{try{s({phantom:q,type:"result",id:k.id,ok:D,...j})}catch(V){s({phantom:q,type:"result",id:k.id,ok:!1,error:Ce(new $("FAILED",`The answer could not be sent to Phantom: ${L(V)}`))})}};try{if(!await b||!r)throw new $("FAILED","The plugin did not load");if(h)throw new $e(`${An(h.for)} Its background code has not started, so the command was not run.`,h.for);if(k.kind!=="commands")throw new $("NOT_SUPPORTED",`Phantom asked for an unknown kind, "${k.kind}"`);const D=(x=r.commands)==null?void 0:x[k.contribution];if(typeof D!="function")throw new $("NOT_SUPPORTED",`definePlugin has no commands["${k.contribution}"] function`);const j={arguments:((T=k.input)==null?void 0:T.arguments)??{}},V=await D(j,g.phantom(k.game),g);R(!0,{value:pe(V??null)})}catch(D){R(!1,{error:Ce(D)})}}function bt(k){try{const x=k();x instanceof Promise&&x.catch(T=>Ie(T))}catch(x){Ie(x)}}function Ie(k){o.log("error",[`setup's cleanup failed: ${L(k)}`])}async function _n(){const k=i;if(i=null,k)try{await Promise.race([Promise.resolve(k()),new Promise(x=>setTimeout(x,Ui))])}catch(x){Ie(x)}s({phantom:q,type:"stopped"})}return{ctx:g,crash:f,log:(k,x)=>o.log(k,x),replaceDefinition(k){var x;r=k,((x=S.role)==null?void 0:x.kind)!=="logic"&&yt()},stop(){t||(i&&(bt(i),i=null),t=!0,U(),o.close("The frame was closed"),w.dispose(),kt(null))}}}function ge(n){return Object.keys(n??{})}function Ki(n){return!n||typeof n!="object"?{}:"default"in n&&n.default&&typeof n.default=="object"?n.default:n}const Xi={class:"flex flex-col p-3",role:"alert"},Ji={class:"flex flex-col gap-2 overflow-hidden rounded-lg border border-phantom-danger/25 bg-phantom-danger/10 px-3 py-2.5"},Qi={class:"flex items-start gap-2"},Zi={class:"min-w-0 flex-1"},es={class:"text-xs font-medium text-phantom-danger"},ts={class:"mt-0.5 break-words text-2xs text-phantom-text-soft"},ns=["textContent"],as={key:1,class:"text-2xs text-phantom-subtle"},rs=Qn({__name:"ErrorCard",props:{error:{},development:{type:Boolean},kind:{}},emits:["dismiss"],setup(n,{emit:e}){const t=n,a=e,r=Zn(()=>t.kind==="panel"?"This panel":t.kind==="page"?"This page":"This plugin");return(i,s)=>(ke(),xe("div",Xi,[le("div",Ji,[le("div",Qi,[s[1]||(s[1]=le("span",{class:"mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-phantom-danger","aria-hidden":"true"},null,-1)),le("div",Zi,[le("p",es,ze(r.value)+" stopped with an error",1),le("p",ts,ze(n.error.message),1)]),n.development?(ke(),xe("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=>a("dismiss"))}," Dismiss ")):xt("",!0)]),n.development&&n.error.stack?(ke(),xe("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:ze(n.error.stack)},null,8,ns)):n.development?xt("",!0):(ke(),xe("p",as," More is in the plugin's log, in Plugins. "))])]))}});function is(n){let e=null,t=null,a=-1;const r=()=>{const o=Math.ceil(Math.max(n.content.scrollHeight,n.content.getBoundingClientRect().height));o!==a&&(a=o,n.onResize(o))},i=typeof ResizeObserver>"u"?null:new ResizeObserver(r);i==null||i.observe(n.content);function s(){t==null||t.unmount(),t=null,n.content.hidden=!1}return{mount(o,h){s(),e==null||e.unmount(),document.documentElement.dataset.kind=S.kind??"",e=Mt({name:"PhantomPluginView",render:()=>St(o,{...S.props})}),e.provide(Kn,h),e.config.errorHandler=l=>n.onError(l),e.mount(n.content)},showError(o,h){t==null||t.unmount(),n.content.hidden=!0,t=Mt({render:()=>St(rs,{error:o,development:h,kind:S.kind,onDismiss:()=>s()})}),t.mount(n.errors),r()},unmount(){i==null||i.disconnect(),e==null||e.unmount(),t==null||t.unmount(),e=null,t=null}}}function ss(n){window.parent===window&&os();const e=ln("app"),t=ln("phantom-error");let a=null;function r(o){window.parent.postMessage(o,"*")}const i=is({content:e,errors:t,onError:o=>a==null?void 0:a.crash(o),onResize:o=>{document.documentElement.dataset.kind&&r({phantom:q,type:"resize",height:o})}});a=Yi({post:r,listen(o){const h=l=>{l.source===window.parent&&o(l.data)};return window.addEventListener("message",h),()=>window.removeEventListener("message",h)},root:document.documentElement,view:i,...n.loadStyles?{loadStyles:n.loadStyles}:{}},n);const s=a;return xi(console,(o,h)=>s.log(o,h)),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 h=o.target,l=h&&typeof h.closest=="function"?h.closest("a[href]"):null;if(!l)return;const c=l.getAttribute("href")??"";c.startsWith("#")||(o.preventDefault(),/^https:\/\//i.test(c)?s.ctx.openUrl(c).catch(()=>{}):s.log("warn",[`Only https links open from a plugin; this one goes to ${c}`]))}),s}function ln(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 os(){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 cn="/dist/plugin.js",ls="/dist/plugin.css";let hn=null;function cs(){return hn??=new Promise(n=>{const e=document.createElement("link");e.rel="stylesheet",e.href=ls,e.onload=e.onerror=()=>n(),document.head.append(e)}),hn}async function hs(){const n=await import(cn);if(!n.default)throw new Error(`${cn} has no default export. Export definePlugin({ ... }) as default.`);return n.default}ss({definition:hs,loadStyles:cs});
|