@indiegems/gem-web-sdk 13.4.2 → 14.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
- var Ce=Object.defineProperty;var Ie=(n,e)=>{for(var t in e)Ce(n,t,{get:e[t],enumerable:true});};globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:13.4.2]";var Ee={initialDelayMs:2e3,maxDelayMs:6e4};function Me(n,e){return e!==void 0?!e:n==="chain_exhausted"}var B=class{constructor(e){this.options=e;}options;grant=null;state="pending";failure=null;generation=0;inFlight=null;rejected=false;retry=null;failures=0;notBefore=0;disposed=false;get currentState(){return this.state}get lastFailure(){return this.failure}async get(){if(this.state==="lost")throw new _(this.failure??"unavailable","the session cannot be renewed");let e=this.seconds();if(this.grant&&e<this.grant.expiresAt-this.renewBefore())return this.grant.token;if(this.pastChainCeiling())throw new _("chain_exhausted","the token chain reached its ceiling");if(this.inFlight===null&&this.options.clock.now()<this.notBefore)throw new _(this.failure??"unavailable","the embedder asked for no new token yet; one is asked for when that wait is over");return this.refresh(this.nextReason())}pastChainCeiling(){return this.grant===null||this.seconds()<this.grant.chainEndsAt?false:(this.enter("lost","chain_exhausted"),true)}nextReason(){return this.rejected?"rejected":this.grant?"expiring":"initial"}invalidate(e){e!==void 0&&this.grant!==null&&this.grant.token!==e||this.rejected&&this.grant===null||(this.grant=null,this.generation+=1,this.inFlight=null,this.rejected=true,this.state!=="lost"&&this.enter("pending"));}accept(e){this.state!=="lost"&&(this.grant=e,this.rejected=false,this.enter("ready"));}close(e="unavailable"){this.grant=null,this.generation+=1,this.inFlight=null,this.enter("lost",e);}dispose(){this.disposed=true,this.cancelRetry();}scheduleRetry(e){if(this.cancelRetry(),this.failures+=1,this.notBefore=e===void 0?0:this.options.clock.now()+e,this.disposed)return;let{initialDelayMs:t,maxDelayMs:r}=Ee,o=Math.min(r,t*2**(this.failures-1)),a=Math.max(o/2,e??0)+Math.random()*(o/2);this.retry={handle:this.options.clock.setTimeout(()=>this.retryNow(),a)};}retryNow(){this.retry=null,this.notBefore=0,!(this.state==="lost"||this.pastChainCeiling())&&this.refresh(this.nextReason()).catch(()=>{});}cancelRetry(){this.retry!==null&&(this.options.clock.clearTimeout(this.retry.handle),this.retry=null);}refresh(e){if(this.inFlight)return this.inFlight;this.cancelRetry();let t=this.generation;this.enter("pending");let r=this.options.request(e).then(o=>{if(t!==this.generation)throw new _("internal","token arrived for a superseded generation");return this.grant=o,this.rejected=false,this.enter("ready"),o.token}).catch(o=>{let a=Le(o),{retryable:i,retryAfterMs:l}=o??{};throw t===this.generation&&(Me(a,typeof i=="boolean"?i:void 0)?this.enter("lost",a):(this.scheduleRetry(typeof l=="number"&&Number.isFinite(l)&&l>0?l:void 0),this.enter("degraded",a))),o instanceof _?o:new _(a,String(o))}).finally(()=>{this.inFlight===r&&(this.inFlight=null);});return this.inFlight=r,r}enter(e,t){(e==="ready"||e==="lost")&&this.cancelRetry(),e==="ready"&&(this.failures=0,this.notBefore=0),this.failure=t??(e==="ready"?null:this.failure),this.state!==e&&(this.state=e,this.options.onStateChange?.(e,t));}renewBefore(){return this.options.renewBeforeSeconds??60}seconds(){return Math.floor(this.options.clock.now()/1e3)}},_=class n extends Error{constructor(t,r){super(`auth ${t}: ${r}`);this.reason=t;this.name="AuthError";}reason;static isAuthError(t){if(t instanceof n)return true;let r=t;return r?.name==="AuthError"&&typeof r.reason=="string"}};function Le(n){if(n instanceof _)return n.reason;let e=n?.reason;return typeof e=="string"&&["chain_exhausted","unavailable","timeout","internal"].includes(e)?e:"internal"}var y=class n extends Error{retryable=false;constructor(e){super(e),this.name="TransportRefusal";}static isRefusal(e){if(e instanceof n)return true;let t=e;return t?.name==="TransportRefusal"&&t.retryable===false}},F=["if-match","if-none-match"],Y=4096;function qe(n){if(!n)return;let e={};for(let[t,r]of Object.entries(n)){let o=t.toLowerCase();if(!F.includes(o)||r===void 0)continue;let a=typeof r=="string"?$e(r):r;if(typeof a!="string"||a.length>Y||!je(a))throw new y(`the ${o} header value cannot be sent \u2014 it is not a string, is longer than ${Y} characters, or contains a character outside the range an HTTP header value may carry. This is a malformed request, not a server failure; the value is withheld here rather than written to logs.`);a!==""&&(e[o]=a);}return Object.freeze(e)}function $e(n){let e=o=>o===32||o===9||o===10||o===13,t=0,r=n.length;for(;t<r&&e(n.charCodeAt(t));)t++;for(;r>t&&e(n.charCodeAt(r-1));)r--;return n.slice(t,r)}function je(n){for(let e=0;e<n.length;e++){let t=n.charCodeAt(e);if(t!==9&&(t<32||t===127||t>255))return false}return true}function Be(n){let{bytes:e}=n;if(e!==void 0){if(Object.prototype.toString.call(e)!=="[object Uint8Array]")throw new y("the raw body is not a Uint8Array, so it cannot be sent as bytes. This is a malformed request, not a server failure.");if(n.body!==void 0)throw new y("the request carries both a JSON body and a raw body, and only one can be sent. This is a malformed request, not a server failure.");return new Uint8Array(e)}}function J(n,e){let t=e.replayUnauthorizedOnce??true;return {async request(r){let o={...r},a=qe(o.headers),i=Be(o),l=Object.freeze({...o,headers:a,...i===void 0?{}:{bytes:i}}),d=await e.tokenSource.get(),c=await n(l,d);if(c.status!==401||!t)return c;e.tokenSource.invalidate(d);let g=await e.tokenSource.get(),h=await n(l,g);if(h.status===401)throw e.tokenSource.close("unavailable"),new _("unavailable","the server refused a freshly minted token");return h}}}function X(n){let e=typeof n=="string"?new TextEncoder().encode(n):n;return btoa(Fe(e))}function Fe(n){let t="";for(let r=0;r<n.length;r+=32768)t+=String.fromCharCode(...n.subarray(r,r+32768));return t}var m=class extends Error{constructor(t,r,o,a,i){super(`${t} (${r}): ${o}`);this.reason=t;this.status=r;this.detail=o;this.retryAfterSeconds=a;this.code=i;this.name="GemApiError";}reason;status;detail;retryAfterSeconds;code;get retryable(){return this.reason==="unavailable"||this.reason==="rate_limited"}},Z=new WeakMap;function ee(n){return Z.get(n)??{}}var Ue=new Set([408,429,500,502,503,504]),Ne=6e4;function De(n){if(n===void 0)return 2;if(!Number.isInteger(n)||n<0||n>10)throw new y(`maxRetries must be a whole number between 0 and 10; received ${JSON.stringify(n)}. This is a configuration fault, not a server failure.`);return n}var C=class{constructor(e){this.options=e;}options;async get(e,t){return this.send({method:"GET",path:e,signal:t},true)}async getWithEtag(e,t={}){let r=await this.sendRaw({method:"GET",path:e,...t.signal===void 0?{}:{signal:t.signal},...t.ifNoneMatch===void 0?{}:{headers:{"if-none-match":t.ifNoneMatch}}},true),o=r.etag===void 0?{}:{etag:r.etag};return r.status===304?{modified:false,...o}:{modified:true,body:r.body,...o}}async put(e,t,r,o={}){return this.send({method:"PUT",path:e,body:t,signal:r,...L(o)},o.replaySafe===true,o.retryRateLimited!==false)}async post(e,t,r,o={}){return this.send({method:"POST",path:e,body:t,signal:r,...L(o)},o.replaySafe===true,o.retryRateLimited!==false)}async postBytes(e,t,r,o={}){let a=await this.sendRaw({method:"POST",path:e,bytes:t,responseType:"bytes",signal:r,...L(o)},o.replaySafe===true,o.retryRateLimited!==false);return {bytes:He(a.body),...a.invocationId===void 0?{}:{invocationId:a.invocationId}}}async patch(e,t,r,o={}){return this.send({method:"PATCH",path:e,body:t,signal:r,...L(o)},o.replaySafe===true,o.retryRateLimited!==false)}async delete(e,t,r={}){return this.send({method:"DELETE",path:e,signal:t,...L(r)},r.replaySafe===true,r.retryRateLimited!==false)}async send(e,t,r=true){return (await this.sendRaw(e,t,r)).body}async sendRaw(e,t,r=true){let o=t?De(this.options.maxRetries)+1:1,a=null;if(e.signal?.aborted)throw Q(e.signal);for(let i=0;i<o;i++){if(i>0&&await this.backoff(i,a,e.signal),e.signal?.aborted)throw Q(e.signal);let l;try{l=await this.options.transport.request(e);}catch(c){if(_.isAuthError(c)||y.isRefusal(c)||e.signal?.aborted||Ve(c))throw c;a=new m("unavailable",0,String(c));continue}if(l.status>=200&&l.status<300||l.status===304)return l;let d=We(l);if(!Ue.has(l.status)||l.status===429&&!r)throw d;a=d;}throw a??new m("unavailable",0,"no attempt was made")}backoff(e,t,r){if(r?.aborted)return Promise.resolve();let o=t?.retryAfterSeconds,a=o!==void 0?o*1e3:2**(e-1)*250,i=2**(e-1)*250,l=Math.min(Math.max(a,i),Ne);return new Promise(d=>{let c=this.options.clock,g=false,h=false,b,f=()=>{g||(g=true,h&&c.clearTimeout(b),r?.removeEventListener("abort",f),d());};r?.addEventListener("abort",f,{once:true}),b=c.setTimeout(f,l),h=true,g&&c.clearTimeout(b);})}};function He(n){if(n instanceof Uint8Array)return n;if(n==null)return new Uint8Array(0);let e=typeof n=="string"?n:JSON.stringify(n);return new TextEncoder().encode(e)}function L(n){return {...n.keepalive===void 0?{}:{keepalive:n.keepalive},...n.ifMatch===void 0?{}:{headers:{"if-match":n.ifMatch}}}}function Q(n){return n.reason!==void 0?n.reason:new DOMException("The operation was aborted.","AbortError")}function Ve(n){let e=n?.name;return e==="AbortError"||e==="TimeoutError"}function We(n){let e=Ke(n),t=Je(n.body),r={...t===void 0?{}:{details:t},...n.invocationId===void 0?{}:{invocationId:n.invocationId}};return Object.keys(r).length>0&&Z.set(e,r),e}var ze=new Map([["insufficient_funds","insufficient_funds"]]);function Ke(n){let{status:e,body:t}=n,r=Ye(t),o=n.retryAfterSeconds??Qe(t),a=Xe(t),i=a===void 0?void 0:ze.get(a);if(i!==void 0)return new m(i,e,r,void 0,a);switch(e){case 304:return new m("not_modified",e,r);case 400:case 422:return new m("invalid",e,r,void 0,a);case 403:return new m("forbidden",e,r,void 0,a);case 404:return new m("not_found",e,r,void 0,a);case 402:return new m("insufficient_funds",e,r,void 0,a);case 409:return new m("conflict",e,r,void 0,a);case 412:return new m("precondition_failed",e,r,void 0,a);case 413:return new m("too_large",e,r,void 0,a);case 429:return new m("rate_limited",e,r,o,a);default:return new m("unavailable",e,r,o,a)}}function Ye(n){if(typeof n=="string")return n;let e=n?.message;if(typeof e=="string")return e;let t=n?.error;if(typeof t=="string")return t;let r=t?.message;return typeof r=="string"?r:"no detail"}function Je(n){let t=n?.error?.details;return t===null?void 0:t}function Xe(n){let t=n?.error?.code;return typeof t=="string"&&t.length>0?t:void 0}function Qe(n){let e=n?.retryAfterSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function Ze(n){let e=n.lastIndexOf("@");return (e===-1?n:`***@${n.slice(e+1)}`).slice(0,200)}var en=new Set(F);function nn(n){if(!n)return {};let e={};for(let[t,r]of Object.entries(n))en.has(t.toLowerCase())&&(e[t.toLowerCase()]=r);return e}function ne(n){let e=n.fetch??globalThis.fetch.bind(globalThis);return J(async(t,r)=>{let o;try{o=new URL(n.baseUrl.replace(/\/+$/,""));}catch{throw new y("the configured baseUrl is not a valid URL. Its value is withheld here rather than written to logs. This is a configuration fault, not a server failure.")}let a;try{a=new URL(o.href.replace(/\/+$/,"")+t.path);}catch{throw new y(`${JSON.stringify(typeof t.path=="string"?Ze(t.path):"(a non-string path)")} does not form a valid URL against ${o.protocol}//${o.host}. This is a malformed request, not a server failure.`)}if(a.protocol!==o.protocol||a.host!==o.host)throw new y(`${JSON.stringify(a.pathname)} resolves to ${a.protocol}//${a.host}, not ${o.protocol}//${o.host}. A request path may not change the request's origin \u2014 it carries the play token.`);if(a.username!==""||a.password!==""){let f=o.username!==""||o.password!=="",p=a.username!==o.username||a.password!==o.password,k=f?p?"baseUrl (and possibly the request path)":"baseUrl":"request path";throw new y(`the ${k} puts credentials in the URL, which cannot be fetched (${t.method} ${a.pathname}). The value is withheld here rather than written to logs. This is a malformed request, not a server failure.`)}for(let[f,p]of Object.entries(n.defaultQuery??{}))a.searchParams.has(f)||a.searchParams.set(f,p);let i=t.bytes,l=t.bytes===void 0?void 0:"application/octet-stream";try{t.body!==void 0&&(i=JSON.stringify(t.body),l="application/json");}catch(f){throw new y(`the body of ${t.method} ${JSON.stringify(a.pathname)} could not be serialised to JSON: ${String(f)}. This is a bug in the request, not a server failure \u2014 retrying sends the same unserialisable value.`)}let d=await e(a.toString(),{method:t.method,headers:{authorization:`Bearer ${r}`,...l===void 0?{}:{"content-type":l},...nn(t.headers)},body:i,signal:t.signal,...t.keepalive===void 0?{}:{keepalive:t.keepalive},credentials:"omit",mode:"cors",redirect:"error",cache:"no-store",referrerPolicy:"no-referrer"}),c=null;if(t.responseType==="bytes"&&d.status>=200&&d.status<300)c=new Uint8Array(await d.arrayBuffer());else {let f=await d.text();if(f.length>0)try{c=JSON.parse(f);}catch{c=f;}}let g=d.headers.get("etag"),h=tn(d.headers.get("retry-after")),b=d.headers.get("x-gem-invocation-id");return {status:d.status,body:c,...g===null?{}:{etag:g},...h===void 0?{}:{retryAfterSeconds:h},...b===null||b===""?{}:{invocationId:b}}},n)}function tn(n){if(n===null)return;let e=n.trim();if(!/^\d+$/.test(e))return;let t=Number(e);return Number.isFinite(t)?t:void 0}var rn="gem-web-bridge";var I=65536,te=8,U=5e3,re=1024;var N=Object.create(null);var oe=Object.create(null);function on(n){let e=/^([a-z][a-z0-9+.-]*):\/\/([a-z0-9.-]+|\[[0-9a-f:.]+\])(:([0-9]{1,5}))?$/i.exec(n);return e===null?false:e[4]===void 0||Number(e[4])<=65535}function an(n){let e;try{e=new URL(n);}catch{return false}return e.username!==""||e.password!==""?false:e.protocol==="https:"?true:e.protocol==="http:"&&(e.hostname==="localhost"||e.hostname==="127.0.0.1")}function sn(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function ln(n){return /^[a-z_]+$/.test(n)}function H(n,e,t){if(e>te)return `nesting deeper than ${te}`;if(++t.nodes>U)return `more than ${U} values`;if(t.bytes>I)return `over the ${I} byte limit`;if(n==null)return t.bytes+=4,null;let r=typeof n;if(r==="boolean")return t.bytes+=5,null;if(r==="number")return t.bytes+=8,null;if(r==="string")return t.bytes+=n.length*3+2,null;if(r!=="object")return `${r} is not plain data`;let o=n;if(t.seen.has(o))return "a repeated or cyclic object reference";if(t.seen.add(o),Array.isArray(n)){if(n.length>re)return `an array of ${n.length} entries, over the ${re} limit`;t.bytes+=2;for(let l of n){let d=H(l,e+1,t);if(d)return d}return null}let a=Object.getPrototypeOf(n);if(a!==Object.prototype&&a!==null)return "a value that is not a plain object";t.bytes+=2;let i=n;for(let l in i){if(!Object.prototype.hasOwnProperty.call(i,l))continue;if(++t.nodes>U)return `more than ${U} values`;if(t.bytes+=l.length*3+4,t.bytes>I)return `over the ${I} byte limit`;let d=H(i[l],e+1,t);if(d)return d}return null}function dn(n){let e={nodes:0,bytes:0,seen:new Set},t=H(n,0,e);return t?`message contains ${t}`:e.bytes>I?`message is over the ${I} byte limit`:null}var un={origin:[on,"not a well-formed origin"],url:[an,"not a safe absolute http(s) URL"],bcp47:[sn,"not a well-formed BCP 47 tag"],code:[ln,"not a code of lower-case letters and underscores"]};function ae(n,e,t){for(let r of e){let o=t===""?r.n:`${t}.${r.n}`,a=n[r.n];if(a==null){if(r.o)continue;return `${o}: required`}let i=se(a,r,o);if(i)return i}return null}function se(n,e,t){switch(e.k){case "s":{if(typeof n!="string")return `${t}: expected string`;if(n.length>e.max)return `${t}: exceeds ${e.max} characters`;if(e.f){let[r,o]=un[e.f];if(!r(n))return `${t}: ${o}`}return null}case "i":return typeof n!="number"||!Number.isInteger(n)?`${t}: expected integer`:n<e.lo||n>e.hi?`${t}: out of range ${e.lo}..${e.hi}`:null;case "b":return typeof n=="boolean"?null:`${t}: expected boolean`;case "e":{let r=e.v;return r.includes(n)?null:`${t}: not one of ${r.join("|")}`}case "o":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:ae(n,e.fs,t);case "j":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected a plain object`:null;case "a":{if(!Array.isArray(n))return `${t}: expected array`;if(n.length>e.max)return `${t}: exceeds ${e.max} items`;let r=e.it,o=`${t}[]`;for(let a of n){if(a==null){if(r.o)continue;return `${o}: required`}let i=se(a,r,o);if(i)return i}return null}default:{let r=e.k;return `${t}: unknown kind ${String(r)}`}}}var ie=Object.create(null);function u(n,e,t,r){return N[n]=t,r&&(oe[n]=r),ie[n]=o=>{let a=dn(o);if(a)return a;if(typeof o!="object"||o===null||Array.isArray(o))return "message: expected object";let i=o;return i.gem!==rn?"gem: wrong protocol marker":i.type!==n?`type: expected ${n}`:ae(i,e,"")}}u("gem.handshake",[{n:"versions",k:"o",fs:[{n:"min",k:"i",lo:1,hi:1e3},{n:"max",k:"i",lo:1,hi:1e3}]},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}},{n:"embedder",k:"s",max:2048,f:"origin"},{n:"unbidden",k:"b",o:1}],30);u("gem.handshake.accept",[{n:"v",k:"i",lo:1,hi:1e3},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}}],5);u("gem.token",[{n:"token",k:"s",max:4096},{n:"requestId",k:"s",o:1,max:64},{n:"generation",k:"i",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"s",o:1,max:512,f:"url"},{n:"playerId",k:"s",max:64},{n:"gameId",k:"s",max:64},{n:"channel",k:"e",v:["dev","test","release"]},{n:"gameVersion",k:"s",o:1,max:64},{n:"expiresAt",k:"i",lo:0,hi:4102444800},{n:"chainEndsAt",k:"i",lo:0,hi:4102444800},{n:"allowDevTools",k:"b",o:1}],30);u("gem.token.denied",[{n:"requestId",k:"s",max:64},{n:"retryable",k:"b"},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:36e5},{n:"reason",k:"e",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"s",max:64}],30);u("gem.player",[{n:"untrusted",k:"o",fs:[{n:"displayName",k:"s",max:64},{n:"displayTag",k:"s",o:1,max:80},{n:"displayHandle",k:"s",max:80}]},{n:"playerId",k:"s",o:1,max:64},{n:"discriminator",k:"s",o:1,max:8},{n:"avatarIconUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatarIconId",k:"s",o:1,max:64},{n:"avatar3dId",k:"s",o:1,max:64},{n:"avatar3dModelUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatar3dIconUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatars3d",k:"a",o:1,max:8,it:{n:"",k:"o",fs:[{n:"family",k:"s",max:32},{n:"id",k:"s",max:64},{n:"modelUrl",k:"s",max:256,f:"url"},{n:"iconUrl",k:"s",max:256,f:"url"}]}},{n:"badges",k:"a",o:1,max:2,it:{n:"",k:"o",fs:[{n:"itemId",k:"s",max:64},{n:"iconUrl",k:"s",max:2048,f:"url"}]}},{n:"displayTag",k:"s",max:8},{n:"avatarUrl",k:"s",o:1,max:2048,f:"url"},{n:"boost",k:"o",o:1,fs:[{n:"multipliers",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"currencyId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"multiplierBp",k:"i",lo:1e4,hi:1e6}]}},{n:"expiresInDays",k:"i",o:1,lo:1,hi:7}]}],12);u("gem.pause",[{n:"paused",k:"b"}],120);u("gem.prefs",[{n:"reducedMotion",k:"b"},{n:"muted",k:"b"},{n:"showFrameStats",k:"b",o:1},{n:"locale",k:"s",max:35,f:"bcp47"},{n:"recommended",k:"o",o:1,fs:[{n:"volume",k:"i",lo:0,hi:100},{n:"batterySaver",k:"b"},{n:"keyboardLayout",k:"e",v:["wasd","arrows"]},{n:"gamepadConfirm",k:"e",v:["south","east"]},{n:"vibration",k:"b"},{n:"lookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"gamepadLookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"invertLookY",k:"b",o:1},{n:"touchMovement",k:"s",o:1,max:16,f:"code"},{n:"graphicsQuality",k:"s",o:1,max:16,f:"code"},{n:"graphicsQualityAuto",k:"b",o:1}]}],60);u("gem.cohorts",[{n:"cohorts",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"experimentId",k:"s",max:36},{n:"variantKey",k:"s",max:32}]}}],12,"cohorts");u("gem.earnAllowanceChanged",[],30,"earnAllowance");u("gem.viewport",[{n:"insets",k:"o",fs:[{n:"top",k:"i",lo:0,hi:4096},{n:"right",k:"i",lo:0,hi:4096},{n:"bottom",k:"i",lo:0,hi:4096},{n:"left",k:"i",lo:0,hi:4096}]},{n:"reserved",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384},{n:"width",k:"i",lo:0,hi:16384},{n:"height",k:"i",lo:0,hi:16384},{n:"control",k:"o",o:1,fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384},{n:"width",k:"i",lo:0,hi:16384},{n:"height",k:"i",lo:0,hi:16384}]}]}}],60,"viewport");u("gem.deviceSettings",[{n:"settings",k:"j",o:1}],12,"deviceSettings");u("gem.willTerminate",[{n:"reason",k:"e",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"i",lo:0,hi:6e4}],10);u("gem.roomEvent",[{n:"event",k:"e",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"s",max:64},{n:"matchId",k:"s",o:1,max:64},{n:"version",k:"i",o:1,lo:0,hi:2147483647},{n:"reason",k:"s",o:1,max:64},{n:"platform",k:"e",o:1,v:["universal","mobile"]}],120,"rooms");u("gem.socketState",[{n:"connected",k:"b"},{n:"reason",k:"e",o:1,v:["connecting","dropped","watchdog","terminal"]}],12,"socketState");u("gem.seatedEvent",[{n:"roomId",k:"s",max:64}],60,"partySeating");u("gem.autoStartFailedEvent",[{n:"roomId",k:"s",max:64},{n:"code",k:"s",max:64}],30,"autoStartFailure");u("gem.ticketEvent",[{n:"event",k:"e",v:["queued","matched","expired","cancelled","failed"]},{n:"ticketId",k:"s",max:64},{n:"partySize",k:"i",o:1,lo:1,hi:64},{n:"queuedAt",k:"i",o:1,lo:0,hi:4102444800},{n:"expiresAt",k:"i",o:1,lo:0,hi:4102444800},{n:"reason",k:"s",o:1,max:64},{n:"roomId",k:"s",o:1,max:64}],60,"ticketEvents");u("gem.signalEvent",[{n:"event",k:"e",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}],1800,"p2p");u("gem.dedicatedEvent",[{n:"event",k:"e",v:["answer","error","matchEnded"]},{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",o:1,max:10240},{n:"sessionId",k:"s",o:1,max:64},{n:"code",k:"s",o:1,max:64},{n:"message",k:"s",o:1,max:256},{n:"reason",k:"s",o:1,max:64}],120,"dedicated");u("gem.partyResult",[{n:"requestId",k:"s",max:64},{n:"partyId",k:"s",o:1,max:64}],30,"parties");u("gem.clusterTarget",[{n:"clusterTargetId",k:"s",max:64},{n:"clusterTargetIds",k:"a",o:1,max:3,it:{n:"",k:"s",max:64}}],12,"clusterTarget");u("gem.devtools",[{n:"action",k:"e",v:["open","close","toggle"]}],30,"devtools");u("gem.screenshot",[{n:"maxWidth",k:"i",lo:1,hi:7680},{n:"maxHeight",k:"i",lo:1,hi:4320}],6,"screenshot");u("gem.screenshot.denied",[{n:"reason",k:"e",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"b"}],12,"screenshot");u("gem.requestContext",[],12,"feedbackContext");u("gem.gameContext",[{n:"context",k:"j"}],12,"feedbackContext");u("gem.signal",[{n:"signal",k:"e",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}],1200,"p2p");u("gem.dedicatedOffer",[{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",max:10240},{n:"intent",k:"e",v:["initial","ice_restart","full_reconnect"]}],60,"dedicated");u("gem.partyRequest",[{n:"requestId",k:"s",max:64}],12,"parties");u("gem.ready",[],5);u("gem.engaged",[],5,"engagement");u("gem.progress",[{n:"loaded",k:"i",lo:0,hi:1099511627776},{n:"total",k:"i",lo:0,hi:1099511627776}],600);u("gem.requestToken",[{n:"requestId",k:"s",max:64},{n:"reason",k:"e",v:["initial","expiring","rejected"]}],12);u("gem.requestLocalServer",[{n:"requestId",k:"s",max:64},{n:"gameRoomId",k:"s",max:64}],6,"localHost");u("gem.localServer",[{n:"requestId",k:"s",max:64},{n:"serverId",k:"s",o:1,max:128}],30,"localHost");u("gem.localServer.denied",[{n:"requestId",k:"s",max:64},{n:"retryable",k:"b"},{n:"reason",k:"e",v:["refused","unavailable"]}],30,"localHost");u("gem.exit",[{n:"reason",k:"s",o:1,max:64}],5);u("gem.openExternal",[{n:"url",k:"s",max:2048,f:"url"}],6);u("gem.requestFullscreen",[{n:"enabled",k:"b"}],30);u("gem.audioState",[{n:"muted",k:"b"}],120,"audioState");u("gem.rewardCue",[{n:"currencySlug",k:"s",max:32},{n:"expected",k:"i",o:1,lo:1,hi:1e9},{n:"origin",k:"o",o:1,fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384}]}],60,"rewardCue");u("gem.walletDisplay",[{n:"visible",k:"b"},{n:"currencies",k:"a",o:1,max:8,it:{n:"",k:"s",max:64}},{n:"score",k:"b",o:1}],60,"walletDisplay");u("gem.controlsDeclare",[{n:"uses",k:"o",fs:[{n:"lookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"gamepadLookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"invertLookY",k:"s",o:1,max:16,f:"code"},{n:"touchMovement",k:"s",o:1,max:16,f:"code"}]}],60,"controls");u("gem.menu",[{n:"settings",k:"b"},{n:"items",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"id",k:"s",max:32},{n:"label",k:"s",max:40}]}}],60,"gameMenu");u("gem.menuSelect",[{n:"entry",k:"e",v:["settings","item"]},{n:"id",k:"s",o:1,max:32}],60,"gameMenu");u("gem.gemCorner",[{n:"corner",k:"e",v:["top-left","top-right","bottom-left","bottom-right"]}],12,"gemCorner");u("gem.requestShare",[{n:"params",k:"a",max:16,it:{n:"",k:"o",fs:[{n:"key",k:"s",max:64},{n:"value",k:"s",max:512}]}}],6,"share");u("gem.requestAvatarPicker",[{n:"tab",k:"e",o:1,v:["2d","3d"]}],6,"avatarPicker");u("gem.vibrate",[{n:"pattern",k:"a",max:99,it:{n:"",k:"i",lo:0,hi:1e4}}],600,"vibration");u("gem.frameStats",[{n:"fps",k:"i",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"i",lo:0,hi:1e5},{n:"counts",k:"e",o:1,v:["pageFrames","gameDraws"]}],120,"frameStats");u("gem.portraitBorders",[{n:"name",k:"s",o:1,max:40}],60,"portraitBorders");u("gem.error",[{n:"code",k:"e",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"s",o:1,max:256}],60);u("gem.requestPurchase",[{n:"requestId",k:"s",max:64},{n:"purchaseKind",k:"e",v:["item","recipe"]},{n:"targetId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"quantity",k:"i",o:1,lo:1,hi:10},{n:"catalogId",k:"s",o:1,max:64}],12,"purchases");u("gem.requestAvatar3dPurchase",[{n:"requestId",k:"s",max:64},{n:"itemId",k:"s",max:64},{n:"currencySlug",k:"s",max:32}],12,"avatar3dPurchases");u("gem.purchaseResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["ok","declined","unavailable"]},{n:"reason",k:"s",o:1,max:64,f:"code"},{n:"purchaseId",k:"s",o:1,max:64}],30,"purchases");u("gem.deviceSettings.put",[{n:"requestId",k:"s",max:64},{n:"settings",k:"j"}],30,"deviceSettings");u("gem.deviceSettings.result",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["stored","too_large","unavailable"]}],30,"deviceSettings");u("gem.requestAd",[{n:"requestId",k:"s",max:64},{n:"placement",k:"s",max:32},{n:"format",k:"e",v:["interstitial","rewarded"]}],6,"ads");u("gem.adResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["shown","no_ad","unavailable"]}],12,"ads");u("gem.signalMoment",[{n:"requestId",k:"s",max:64},{n:"kind",k:"e",v:["level_end","run_end","match_end","menu_return","other_break"]},{n:"placement",k:"s",o:1,max:32}],6,"moments");u("gem.momentResult",[{n:"requestId",k:"s",max:64},{n:"shown",k:"b"}],12,"moments");u("gem.requestSignIn",[{n:"requestId",k:"s",max:64}],6,"signIn");u("gem.signInResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["signed_in","declined","unavailable"]}],12,"signIn");u("gem.requestFriendChallenge",[{n:"requestId",k:"s",max:64},{n:"playerId",k:"s",max:64},{n:"template",k:"s",max:64},{n:"params",k:"j",o:1}],12,"friendChallenges");u("gem.friendChallengeResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["accepted","cancelled","refused","unavailable","rate_limited","invalid"]},{n:"code",k:"s",o:1,max:64},{n:"param",k:"s",o:1,max:64},{n:"channel",k:"s",o:1,max:16},{n:"configVersion",k:"i",o:1,lo:0,hi:9007199254740991},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:864e5},{n:"detail",k:"s",o:1,max:300}],30,"friendChallenges");Object.freeze(ie);N.__malformed=60;Object.freeze(N);Object.freeze(oe);var E={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)};function le(n){let e=n.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}var cn=1e4;function de(n,e){return V(n,e)}function V(n,e){if(typeof n.serverToken!="function"||typeof n.onServerToken!="function")throw new Error("this runtime delivers no game-server token: host.serverToken/onServerToken are missing. The server image running this bundle predates token delivery \u2014 the bundle cannot call gem-api on it.");let t=i=>({token:i.token,expiresAt:i.expiresAt,chainEndsAt:Number.POSITIVE_INFINITY}),r=null,o=new B({clock:e.clock,...e.onStateChange===void 0?{}:{onStateChange:e.onStateChange},request:()=>new Promise((i,l)=>{let d=e.clock.setTimeout(()=>{r=null,l({reason:"unavailable",retryable:true});},e.timeoutMs??cn);r={resolve:c=>{e.clock.clearTimeout(d),i(c);},reject:l,timer:d};})}),a=n.onServerToken(i=>{let l=t(i),d=r;if(d){r=null,d.resolve(l);return}o.accept(l);});return {source:o,dispose(){a(),o.dispose(),r&&(e.clock.clearTimeout(r.timer),r.reject({reason:"unavailable",retryable:false}),r=null);}}}var z={};Ie(z,{acceptTransfer:()=>mn,addEntityProgression:()=>gn,adminAction:()=>pn,cancelInventoryTransfer:()=>yn,claimEntityProgressionRewards:()=>fn,closeGameRoom:()=>hn,createEntityBatchOrder:()=>_n,createEntityOrder:()=>bn,createSession:()=>vn,deleteEntityGameSetting:()=>Rn,deleteEntitySave:()=>xn,deleteSession:()=>kn,deleteShowcaseValue:()=>Sn,executeEntityRecipe:()=>wn,finalizeSaveUpload:()=>An,getChannelAssignment:()=>Pn,getDropRates:()=>On,getEntityCurrency:()=>Tn,getEntityGameSetting:()=>Gn,getEntityInventory:()=>Cn,getEntityInventoryItem:()=>In,getEntityLeaderboard:()=>En,getEntityOrder:()=>Mn,getEntityProgression:()=>Ln,getEntityRecipeAvailability:()=>qn,getEntityRecipeUsage:()=>$n,getEntitySave:()=>jn,getEvent:()=>Bn,getGameRoomV2:()=>Fn,getLeaderboard:()=>Un,getPlayerGameProfile:()=>Nn,getPurchaseCatalog:()=>Dn,getResolvedTemplate:()=>Hn,getRoomArgs:()=>Vn,getShowcaseValue:()=>Wn,getTransferDetails:()=>zn,ingestAnalyticsEvents:()=>W,initiateInventoryTransfer:()=>Kn,invokeFunction:()=>Yn,kickPlayer:()=>Jn,listChallenges:()=>Xn,listEntityGameSettings:()=>Qn,listEntityOrders:()=>Zn,listEntityProgressions:()=>et,listEntitySaves:()=>nt,listEvents:()=>tt,listGameRooms:()=>rt,listResolvedTemplates:()=>ot,listTransfers:()=>at,maxEntityProgression:()=>st,putEntityGameSetting:()=>it,putRoomArgs:()=>lt,putShowcaseValue:()=>dt,rejectTransfer:()=>ut,reportMatchPlayers:()=>ct,requestSaveUploadUrl:()=>mt,resetEntityProgression:()=>gt,setMatchBackfill:()=>pt,simulateEntityOrder:()=>yt,transferHostV2:()=>ft,updateGameRoomV2:()=>ht});function s(n){let e=String(n);if(!/^[A-Za-z0-9_.-]{1,128}$/.test(e)||e==="."||e==="..")throw new TypeError(`${JSON.stringify(e)} is not a usable path segment \u2014 it is interpolated into a URL`);return encodeURIComponent(e)}async function mn(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/accept`;return n.client.post(r,void 0,t?.signal)}async function gn(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/add`;return n.client.post(i,o,a?.signal)}async function pn(n,e,t,r){let o=`/v1/voice/sessions/${s(e)}/admin`;return n.client.post(o,t,r?.signal)}async function yn(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/cancel`;return n.client.post(r,void 0,t?.signal)}async function fn(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/claim`;return n.client.post(i,o,a?.signal)}async function hn(n,e,t){let r=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.delete(r,t?.signal)}async function _n(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/batch`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function bn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function vn(n,e,t){return n.client.post("/v1/voice/sessions",e,t?.signal)}async function Rn(n,e,t,r,o){let a=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.delete(a,o?.signal)}async function xn(n,e,t,r,o){let a=`/v1/saves/${s(e)}/${s(t)}/${s(r)}`;return n.client.delete(a,o?.signal)}async function kn(n,e,t){let r=`/v1/voice/sessions/${s(e)}`;return n.client.delete(r,t?.signal)}async function Sn(n,e,t,r){let o=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.delete(o,r?.signal)}async function wn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/recipes/execute`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function An(n,e,t,r,o,a){let i=`/v1/saves/${s(e)}/${s(t)}/${s(r)}/finalize`;return n.client.post(i,o,a?.signal)}async function Pn(n,e,t){let r=`/v1/games/${s(n.gameId())}/config/channels/${s(e)}`;return n.client.getWithEtag(r,{...t?.signal===void 0?{}:{signal:t.signal},...t?.ifNoneMatch===void 0?{}:{ifNoneMatch:t.ifNoneMatch}})}async function On(n,e,t){let r=`/v1/inventory/loot-tables/${s(e)}/drop-rates`;return n.client.get(r,t?.signal)}async function Tn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/currencies/${s(r)}`;return n.client.get(a,o?.signal)}async function Gn(n,e,t,r,o){let a=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function Cn(n,e,t,r){let o=new URLSearchParams;r?.include_buckets!==void 0&&o.set("include_buckets",String(r?.include_buckets)),r?.include_custom_data!==void 0&&o.set("include_custom_data",String(r?.include_custom_data)),r?.currency_limit!==void 0&&o.set("currency_limit",String(r?.currency_limit)),r?.currency_cursor!==void 0&&o.set("currency_cursor",String(r?.currency_cursor)),r?.item_limit!==void 0&&o.set("item_limit",String(r?.item_limit)),r?.item_cursor!==void 0&&o.set("item_cursor",String(r?.item_cursor)),r?.progression_limit!==void 0&&o.set("progression_limit",String(r?.progression_limit)),r?.progression_cursor!==void 0&&o.set("progression_cursor",String(r?.progression_cursor));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function In(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/items/${s(r)}`;return n.client.get(a,o?.signal)}async function En(n,e,t,r,o){let a=new URLSearchParams;o?.bucket_1!==void 0&&a.set("bucket_1",String(o?.bucket_1)),o?.bucket_2!==void 0&&a.set("bucket_2",String(o?.bucket_2)),o?.limit!==void 0&&a.set("limit",String(o?.limit)),o?.periods_back!==void 0&&a.set("periods_back",String(o?.periods_back)),o?.period!==void 0&&a.set("period",String(o?.period)),o?.player_id!==void 0&&a.set("player_id",String(o?.player_id));let i=a.toString(),l=`/v1/leaderboards/${s(e)}/${s(t)}/${s(r)}`+(i?`?${i}`:"");return n.client.get(l,o?.signal)}async function Mn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/${s(r)}`;return n.client.get(a,o?.signal)}async function Ln(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}`;return n.client.get(a,o?.signal)}async function qn(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/catalogs/${s(r)}/recipes/${s(o)}/availability`;return n.client.get(i,a?.signal)}async function $n(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}/recipe-usage`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function jn(n,e,t,r,o){let a=`/v1/saves/${s(e)}/${s(t)}/${s(r)}`;return n.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function Bn(n,e,t){let r=`/v1/events/${s(e)}`;return n.client.get(r,t?.signal)}async function Fn(n,e,t){let r=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.getWithEtag(r,{...t?.signal===void 0?{}:{signal:t.signal},...t?.ifNoneMatch===void 0?{}:{ifNoneMatch:t.ifNoneMatch}})}async function Un(n,e,t){let r=new URLSearchParams;t?.bucket_1!==void 0&&r.set("bucket_1",String(t?.bucket_1)),t?.bucket_2!==void 0&&r.set("bucket_2",String(t?.bucket_2)),t?.periods_back!==void 0&&r.set("periods_back",String(t?.periods_back)),t?.period!==void 0&&r.set("period",String(t?.period)),t?.player_id!==void 0&&r.set("player_id",String(t?.player_id));let o=r.toString(),a=`/v1/leaderboards/${s(e)}`+(o?`?${o}`:"");return n.client.get(a,t?.signal)}async function Nn(n,e,t){let r=`/v1/profiles/players/${s(e)}`;return n.client.get(r,t?.signal)}async function Dn(n,e){let t=new URLSearchParams;e?.config_version!==void 0&&t.set("config_version",String(e?.config_version));let r=t.toString(),o="/v1/inventory/platform-funded-game-inventory-purchase-catalog"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function Hn(n,e,t){let r=`/v1/game-room-templates/${s(e)}`;return n.client.get(r,t?.signal)}async function Vn(n,e,t){let r=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/room-args`;return n.client.get(r,t?.signal)}async function Wn(n,e,t,r){let o=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.get(o,r?.signal)}async function zn(n,e,t){let r=`/v1/inventory/transfers/${s(e)}`;return n.client.get(r,t?.signal)}async function W(n,e,t){let r=`/v1/games/${s(n.gameId())}/analytics/events`;return n.client.post(r,e,t?.signal,{replaySafe:true,retryRateLimited:false})}async function Kn(n,e,t){return n.client.post("/v1/inventory/transfers",e,t?.signal)}async function Yn(n,e,t){return n.client.postBytes("/v1/functions/invoke",e,t?.signal)}async function Jn(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/kick/${s(t)}`;return n.client.post(o,void 0,r?.signal)}async function Xn(n,e){let t=new URLSearchParams;e?.periods_back!==void 0&&t.set("periods_back",String(e?.periods_back)),e?.player_id!==void 0&&t.set("player_id",String(e?.player_id));let r=t.toString(),o="/v1/challenges"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function Qn(n,e,t,r){let o=`/v1/settings/${s(e)}/${s(t)}`;return n.client.get(o,r?.signal)}async function Zn(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}/orders`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function et(n,e,t,r){let o=`/v1/inventory/${s(e)}/${s(t)}/progressions`;return n.client.get(o,r?.signal)}async function nt(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),i=`/v1/saves/${s(e)}/${s(t)}`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function tt(n,e){let t=new URLSearchParams;e?.include_inactive!==void 0&&t.set("include_inactive",String(e?.include_inactive)),e?.limit!==void 0&&t.set("limit",String(e?.limit)),e?.offset!==void 0&&t.set("offset",String(e?.offset));let r=t.toString(),o="/v1/events"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function rt(n,e){let t=new URLSearchParams;e?.status!==void 0&&t.set("status",String(e?.status)),e?.game_channel!==void 0&&t.set("game_channel",String(e?.game_channel)),e?.game_room_type!==void 0&&t.set("game_room_type",String(e?.game_room_type)),e?.template_id!==void 0&&t.set("template_id",String(e?.template_id)),e?.template_slug!==void 0&&t.set("template_slug",String(e?.template_slug)),e?.limit!==void 0&&t.set("limit",String(e?.limit)),e?.cursor!==void 0&&t.set("cursor",String(e?.cursor));let r=t.toString(),o=`/v1/games/${s(n.gameId())}/game-rooms`+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function ot(n,e){return n.client.get("/v1/game-room-templates",e?.signal)}async function at(n,e){let t=new URLSearchParams;e.entity_type!==void 0&&t.set("entity_type",String(e.entity_type)),e.entity_id!==void 0&&t.set("entity_id",String(e.entity_id)),e?.direction!==void 0&&t.set("direction",String(e?.direction)),e?.status!==void 0&&t.set("status",String(e?.status)),e?.cursor!==void 0&&t.set("cursor",String(e?.cursor)),e?.limit!==void 0&&t.set("limit",String(e?.limit));let r=t.toString(),o="/v1/inventory/transfers"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function st(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/max`;return n.client.post(i,o,a?.signal)}async function it(n,e,t,r,o,a){let i=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.put(i,o,a?.signal,{...a?.ifMatch===void 0?{}:{ifMatch:a.ifMatch}})}async function lt(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/room-args`;return n.client.put(o,t,r?.signal)}async function dt(n,e,t,r,o){let a=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.put(a,r,o?.signal)}async function ut(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/reject`;return n.client.post(r,void 0,t?.signal)}async function ct(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/matches/${s(e)}/players/report`;return n.client.post(o,t,r?.signal)}async function mt(n,e,t,r,o,a){let i=`/v1/saves/${s(e)}/${s(t)}/${s(r)}/upload-url`;return n.client.post(i,o,a?.signal,{replaySafe:true})}async function gt(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/reset`;return n.client.post(i,o,a?.signal)}async function pt(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/matches/${s(e)}/backfill`;return n.client.put(o,t,r?.signal)}async function yt(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/simulate`;return n.client.post(a,r,o?.signal)}async function ft(n,e,t,r){let o=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}/transfer/${s(t)}`;return n.client.post(o,void 0,r?.signal)}async function ht(n,e,t,r){let o=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.patch(o,t,r?.signal,{...r?.ifMatch===void 0?{}:{ifMatch:r.ifMatch}})}var ue="gem_";function ce(n,e){let t=e?.retryAfterSeconds,r=typeof t=="number"&&Number.isFinite(t)&&t>0?t*1e3:0,o=1e4*2**Math.min(Math.max(0,n-1),16);return Math.min(Math.max(r,o),3e5)}var vt=1e4,Rt=50,xt=1e3,kt=65536-4*1024,me=n=>typeof n=="number"?n:0,St=n=>typeof n=="string"?n:"";function ge(){let n=globalThis.crypto;return typeof n?.randomUUID=="function"?n.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.floor(Math.random()*16);return (e==="x"?t:t&3|8).toString(16)})}function wt(n){return n?.retryable===true}function At(n,e){let t=n??{},r=Array.isArray(t.rejected)?t.rejected.map(o=>{let a=o??{};return {index:me(a.index),code:St(a.code)}}):[];return {accepted:me(t.accepted),rejected:r,dropped:e,duplicate:t.duplicate===true}}function pe(n,e){return {event_uid:n.uid,name:n.name,offset_ms:Math.round(n.atMs)-e,player_id:n.playerId,dimensions:n.dimensions,measures:n.measures}}function ye(n){let e=Math.max(1,Math.floor(n.maxQueue??xt)),t={client:n.client,gameId:()=>n.gameId},r=[],o=0,a=null,i=false,l=null,d=0,c=0,g=false,h=false,b=v=>{n.log?.(v);},f=()=>{a!==null&&(n.clock.clearTimeout(a),a=null);},p=()=>Math.max(0,c-n.clock.now()),k=()=>{a!==null||i||l!==null||(a=n.clock.setTimeout(()=>{a=null,P().catch(()=>{});},Math.max(vt,p())));},w=()=>{let v=Math.min(r.length,100),R=128;for(let O=0;O<v;O+=1){let T=r[O];if(T===void 0)break;if(R+=JSON.stringify(pe(T,0)).length+1,R>kt)return Math.max(1,O)}return v};async function P(v){for(;l!==null;)await l.catch(()=>{});if(r.length===0)return {accepted:0,rejected:[],dropped:0,duplicate:false};let R=Te(v);l=R;try{return await R}finally{l===R&&(l=null),r.length>0&&k();}}async function Te(v){f();let R=r.splice(0,w()),O=o;o=0;let T=Math.round(n.clock.now()),j={batch_id:ge(),sent_at_ms:T,events:R.map(S=>pe(S,T))};try{let S=await W(t,j,v===void 0?void 0:{signal:v}),G=At(S,O);d=0,c=0;for(let Ge of G.rejected)b(`[gem] analytics: an event was refused (${Ge.code}). See the analytics_events section of your game config.`);return G}catch(S){if(wt(S)){for(r=[...R,...r],o+=O;r.length>e;)r.shift(),o+=1;d+=1,c=n.clock.now()+ce(d,S);}else b(`[gem] analytics: ${R.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(S)}`);throw S}}return {track(v,R,O={}){if(i)return;if(typeof v!="string"||v===""){h||(h=true,b(`[gem] analytics: '${R}' was not recorded \u2014 an event from a server has to name the player it is about. A game-server token names no player, so the platform cannot infer one; pass the id from join() or host.players().`));return}if(R.startsWith(ue)){g||(g=true,b(`[gem] analytics: '${R}' was not recorded \u2014 the gem_ prefix is reserved, and the platform's own events are client-sourced, so a server may not emit one at all. Name your event something else.`));return}let T={},j={};for(let[S,G]of Object.entries(O))typeof G=="string"?T[S]=G:typeof G=="number"&&Number.isFinite(G)&&(j[S]=G);for(;r.length>=e;)r.shift(),o+=1;r.push({uid:ge(),playerId:v,name:R,atMs:n.clock.now(),dimensions:T,measures:j}),r.length>=Rt&&l===null&&p()===0?P().catch(()=>{}):k();},flush:v=>P(v),get pending(){return r.length},dispose(){i=true,f(),r=[],o=0;}}}var Pt=new Map([["function_error",false],["function_failed",false],["function_timeout",false],["function_not_published",false],["function_input_too_large",false],["functions_not_configured",false],["forbidden",false],["function_capacity_unavailable",true],["function_host_unreachable",true],["function_host_error",true],["rate_limited",true],["service_unavailable",true]]),q=class extends m{constructor(e,t){super(e.reason,e.status,e.detail,e.retryAfterSeconds,e.code),this.name="GemFunctionError",Object.assign(this,t);}get retryable(){return (this.code===void 0?void 0:Pt.get(this.code))??super.retryable}},M=class{#e;constructor(e){this.#e=e;}async invoke(e,t={}){let r=Ot(e),o;try{o=await this.#e(r,t.signal===void 0?{}:{signal:t.signal});}catch(a){throw a instanceof m?Gt(a):a}return Tt(o)}};function Ot(n){if(n instanceof ArrayBuffer)return new Uint8Array(n);if(ArrayBuffer.isView(n))return new Uint8Array(n.buffer,n.byteOffset,n.byteLength);let e;try{e=JSON.stringify(n);}catch(t){throw new y(`the function input could not be serialised to JSON: ${String(t)}. Pass bytes, or a value JSON can carry. This is a bug in the call, not a server failure.`)}if(e===void 0)throw new y(`the function input is ${typeof n}, which JSON cannot carry. Pass bytes \u2014 an empty Uint8Array for no input \u2014 or a JSON value. This is a bug in the call, not a server failure.`);return new TextEncoder().encode(e)}function Tt(n){let{bytes:e}=n,t=()=>new TextDecoder("utf-8",{fatal:true}).decode(e);return {bytes:e,...n.invocationId===void 0?{}:{invocationId:n.invocationId},text:t,json:()=>JSON.parse(t())}}function Gt(n){let{details:e,invocationId:t}=ee(n),o=e?.untrusted?.message,a=e?.reason;return new q(n,{...t===void 0?{}:{invocationId:t},...n.code==="function_error"&&typeof o=="string"?{functionMessage:o}:{},...n.code==="function_failed"&&typeof a=="string"?{failure:a}:{}})}var A=n=>typeof n=="string"?n:"",Ct=/(?:Z|[+-]\d{2}:?\d{2})$/i;function fe(n){let e=A(n);if(!Ct.test(e))return 0;let t=Date.parse(e);return Number.isFinite(t)?Math.floor(t/1e3):0}var It=/^[0-9a-f]{1,64}$/,Et=/^[0-9a-f]{16}$/,Mt=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,Lt=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function qt(n){let e=A(n),t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!t)return;let[r,o,a]=[Number(t[1]),Number(t[2]),Number(t[3])],i=new Date(Date.UTC(r,o-1,a));return i.getUTCFullYear()===r&&i.getUTCMonth()===o-1&&i.getUTCDate()===a?e:void 0}var $t=4096,jt=new TextEncoder;function Bt(n){let e=A(n.challenge_data),t=A(n.challenge_data_hash);return e===""||!Et.test(t)?{}:jt.encode(e).length>$t?{}:{data:e,dataHash:t}}function Ft(n){let e=n??{},t=fe(e.period_start_at),r=fe(e.period_ends_at);if(t===0||r===0)return;let o=A(e.slug),a=A(e.seed),i=qt(e.period_local_date),l=A(e.boundary),d=A(e.reset_time);return {id:A(e.progression_definition_id),...o===""?{}:{slug:o},window:A(e.window),periodStartAt:t,periodEndsAt:r,...i===void 0?{}:{periodLocalDate:i},boundary:Mt.test(l)?l:"",resetTime:Lt.test(d)?d:"",seed:It.test(a)?a:"",...Bt(e)}}function he(n){if(n!==void 0&&(!Number.isInteger(n)||n<0||n>400))throw new TypeError(`periodsBack must be an integer between 0 and 400, got ${String(n)}`)}function _e(n){let e=n??{};return Array.isArray(e.challenges)?e.challenges.map(Ft).filter(t=>t!==void 0):[]}function be(n){return {async list(e){let{playerId:t,periodsBack:r,signal:o}=e??{};if(typeof t!="string"||t==="")throw new TypeError("gem.challenges.list needs { playerId }: a game-server token names no player, so the platform cannot tell whose period you mean. Pass the id from join() or gem.players().");he(r);let a=await n({player_id:t,...r===void 0?{}:{periods_back:r},...o===void 0?{}:{signal:o}});return _e(a)}}}function Ut(n){let e={};for(let[t,r]of Object.entries(z))if(typeof r=="function"){let o=r;e[t]=(...a)=>o(n,...a);}return e}function D(n,e={}){let t=e.clock??E,r=e.baseUrl??n.apiBaseUrl;if(!r)throw new Error("this runtime names no gem-api host (host.apiBaseUrl is missing). The server image running this bundle predates token delivery \u2014 the bundle cannot call gem-api on it.");let o=V(n,{clock:t,...e.onAuthStateChange===void 0?{}:{onStateChange:e.onAuthStateChange}}),a=ne({baseUrl:r,tokenSource:o.source,defaultQuery:{game_id:n.gameId,channel:n.channel},...e.fetch===void 0?{}:{fetch:e.fetch}}),i=new C({transport:a,clock:t}),l={gameId:n.gameId,channel:n.channel,matchId:n.matchId,...n.gameRoomId===void 0?{}:{gameRoomId:n.gameRoomId}},d=Ut({client:i,gameId:()=>l.gameId}),c=l.gameRoomId,g=n.endMatch,h=n.log,b=ye({client:i,clock:t,gameId:l.gameId,...typeof h=="function"?{log:p=>h.call(n,p)}:{}});return {identity:l,client:i,api:d,match:{end:async()=>{if(g===void 0)throw new Error("this runtime cannot end the match: the server image running this bundle predates host.endMatch, and only the platform half holds the allocation proof an end needs.");await g.call(n);},setBackfill:async(p,k)=>{let w=await d.setMatchBackfill(l.matchId,{open:p.open,...p.seats===void 0?{}:{seats:p.seats}},k===void 0?{}:{signal:k});return {open:w.open,seats:w.seats??null}},reportPlayers:async(p,k)=>(await d.reportMatchPlayers(l.matchId,{players:p.map(P=>({player_id:P.playerId,state:P.state}))},k===void 0?{}:{signal:k})).players.map(P=>({playerId:P.player_id,outcome:P.outcome}))},analytics:b,functions:new M(d.invokeFunction),challenges:be(d.listChallenges),...c===void 0?{}:{room:{get:p=>d.getGameRoomV2(c,p),args:async p=>{let k=await d.getGameRoomV2(c,p?.signal===void 0?{}:{signal:p.signal}),w=k.modified?k.body:void 0;if(w?.room_args==null||w.room_args_template==null)throw new m("not_found",404,"this room's template declares no room args",void 0,"room_args_not_defined");return {room_args:w.room_args,room_args_template:w.room_args_template}}}},dispose:()=>{b.dispose(),o.dispose();}}}var Nt=["explicit","stale_cleanup","game_room_closed","replaced","migration_failed","host_left","insufficient_players","all_left","expired","migration_rate_exceeded","game_room_gone","failed","idle","reclaimed"],Dt=new Set(Nt);function ve(n){return typeof n=="string"&&Dt.has(n)?n:"unknown"}var ke="[gem: use gem.text.toPlain()]",Re=new Set,xe;function Ht(n){try{if(Re.has(n))return;let e=globalThis.location;if(xe??=!!e?.port&&le(e.hostname??""),!xe)return;Re.add(n),console.warn(`[gem] ${n} is PlayerText, turned into a string: players see ${ke}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
2
- ${new Error().stack}`);}catch{}}var x=class{#e;#n;constructor(e,t="player text"){this.#e=e,this.#n=t,Object.freeze(this);}toString(){return Ht(this.#n),ke}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function $(n,e){return new x(n,e)}var Se={toPlain(n){return x.unwrap(n)},compare(n,e,t){let r=n instanceof x?x.unwrap(n):n,o=e instanceof x?x.unwrap(e):e;if(typeof Intl>"u"||typeof Intl.Collator!="function")return r<o?-1:r>o?1:0;let a;try{a=new Intl.Collator(t);}catch{a=new Intl.Collator;}return a.compare(r,o)},equals(n,e){let t=n instanceof x?x.unwrap(n):n,r=e instanceof x?x.unwrap(e):e;return t.normalize("NFC")===r.normalize("NFC")}};var we="the match has not started yet: the runtime hands over the host at `init`, and this was read before that. Read it from `init` or later \u2014 a bundle that needs a value at module scope is reading it one call too early.";function K(n,e={}){let t=e.clock??E,r=()=>{let l=n();if(l===null)throw new Error(we);return l},o=null,a=()=>{if(o===null)throw new Error(we);return o};return {server:{get identity(){return a().identity},get client(){return a().client},get api(){return a().api},get match(){return a().match},get analytics(){return a().analytics},get functions(){return a().functions},get challenges(){return a().challenges},get room(){return a().room},dispose(){o?.dispose();},get sizeClass(){return r().sizeClass},get roomArgs(){return r().roomArgs},get roster(){return r().roster},players(){return r().players()},profile(l){let c=r().profile?.(l);if(!c)return null;let g=c.displayName;return typeof g!="string"||g===""?null:{displayName:$(g,"profile.displayName"),...typeof c.displayTag=="string"&&c.displayTag!==""?{displayTag:$(c.displayTag,"profile.displayTag")}:{},...typeof c.discriminator=="string"?{discriminator:c.discriminator}:{}}},playerNumber(l){return r().playerNumber?.(l)},send(l,d,c){c===void 0?r().send(l,d):r().send(l,d,c);},broadcast(l,d){d===void 0?r().broadcast(l):r().broadcast(l,d);},kick(l,d){d===void 0?r().kick(l):r().kick(l,d);},log(l){r().log(l);},warn(l){r().warn(l);}},attach:()=>{o=D(r(),{...e,clock:t});}}}function Ae(n,e={}){let{server:t,attach:r}=K(()=>n,e);return r(),t}function Vt(n){if(n===void 0||typeof n.reason!="string"||n.reason==="")return;let e=n.platform_reason??n.endedReason;return {reason:n.reason,...e===void 0?{}:{endedReason:ve(e)}}}var Wt=1e4;function zt(n){let e=false;return t=>{if(e)return;let r;try{r=n.match.reportPlayers([{playerId:t,state:"connected"}],AbortSignal.timeout(Wt));}catch{return}r.catch(o=>{o instanceof m&&o.status>=400&&o.status<500&&(e=o.status!==429);});}}function Pe(n,e={}){return ()=>{let t=null,{server:r,attach:o}=K(()=>t,e),a=n(r),i={async init(d){t=d,o(),await a.init?.();},async shutdown(d){let c=Vt(d);try{await a.shutdown?.(c);}finally{r.dispose();}}},l=zt(r);return i.join=(d,c)=>(l(d),a.join?.(d,c)),a.leave&&(i.leave=(d,c)=>a.leave?.(d,c)),a.message&&(i.message=(d,c,g,h)=>a.message?.(d,c,g,h)),i}}var Kt=new Set(["unlocked","already_unlocked","suppressed"]);function Oe(n){let e=n?.changes;if(!Array.isArray(e))return [];let t=[];for(let r of e){let o=r??{};if(o.type!=="achievement_unlocked"||typeof o.outcome!="string"||!Kt.has(o.outcome)||typeof o.achievement_id!="string"||o.achievement_id==="")continue;let a=o.outcome;t.push({achievementId:o.achievement_id,progressionDefinitionId:typeof o.progression_definition_id=="string"?o.progression_definition_id:"",points:a==="unlocked"&&typeof o.points=="number"&&Number.isFinite(o.points)?o.points:0,outcome:a,...typeof o.reason=="string"?{reason:o.reason}:{}});}return t}export{_ as AuthError,F as CONDITIONAL_HEADERS,M as FunctionsApi,m as GemApiError,C as GemClient,q as GemFunctionError,x as PlayerText,y as TransportRefusal,Oe as achievementReceipts,$ as asPlayerText,D as createGemServer,de as createHostTokenSource,Ae as createMatchServer,Pe as defineServer,E as systemClock,Se as text,X as toBase64};//# sourceMappingURL=gem-web-sdk.server.js.map
1
+ var Ee=Object.defineProperty;var Ie=(n,e)=>{for(var t in e)Ee(n,t,{get:e[t],enumerable:true});};globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:14.0.0]";var Me={initialDelayMs:2e3,maxDelayMs:6e4};function Le(n,e){return e!==void 0?!e:n==="chain_exhausted"}var B=class{constructor(e){this.options=e;}options;grant=null;state="pending";failure=null;generation=0;inFlight=null;rejected=false;retry=null;failures=0;notBefore=0;disposed=false;get currentState(){return this.state}get lastFailure(){return this.failure}async get(){if(this.state==="lost")throw new b(this.failure??"unavailable","the session cannot be renewed");let e=this.seconds();if(this.grant&&e<this.grant.expiresAt-this.renewBefore())return this.grant.token;if(this.pastChainCeiling())throw new b("chain_exhausted","the token chain reached its ceiling");if(this.inFlight===null&&this.options.clock.now()<this.notBefore)throw new b(this.failure??"unavailable","the embedder asked for no new token yet; one is asked for when that wait is over");return this.refresh(this.nextReason())}pastChainCeiling(){return this.grant===null||this.seconds()<this.grant.chainEndsAt?false:(this.enter("lost","chain_exhausted"),true)}nextReason(){return this.rejected?"rejected":this.grant?"expiring":"initial"}invalidate(e){e!==void 0&&this.grant!==null&&this.grant.token!==e||this.rejected&&this.grant===null||(this.grant=null,this.generation+=1,this.inFlight=null,this.rejected=true,this.state!=="lost"&&this.enter("pending"));}accept(e){this.state!=="lost"&&(this.grant=e,this.rejected=false,this.enter("ready"));}close(e="unavailable"){this.grant=null,this.generation+=1,this.inFlight=null,this.enter("lost",e);}dispose(){this.disposed=true,this.cancelRetry();}scheduleRetry(e){if(this.cancelRetry(),this.failures+=1,this.notBefore=e===void 0?0:this.options.clock.now()+e,this.disposed)return;let{initialDelayMs:t,maxDelayMs:r}=Me,o=Math.min(r,t*2**(this.failures-1)),a=Math.max(o/2,e??0)+Math.random()*(o/2);this.retry={handle:this.options.clock.setTimeout(()=>this.retryNow(),a)};}retryNow(){this.retry=null,this.notBefore=0,!(this.state==="lost"||this.pastChainCeiling())&&this.refresh(this.nextReason()).catch(()=>{});}cancelRetry(){this.retry!==null&&(this.options.clock.clearTimeout(this.retry.handle),this.retry=null);}refresh(e){if(this.inFlight)return this.inFlight;this.cancelRetry();let t=this.generation;this.enter("pending");let r=this.options.request(e).then(o=>{if(t!==this.generation)throw new b("internal","token arrived for a superseded generation");return this.grant=o,this.rejected=false,this.enter("ready"),o.token}).catch(o=>{let a=qe(o),{retryable:s,retryAfterMs:l}=o??{};throw t===this.generation&&(Le(a,typeof s=="boolean"?s:void 0)?this.enter("lost",a):(this.scheduleRetry(typeof l=="number"&&Number.isFinite(l)&&l>0?l:void 0),this.enter("degraded",a))),o instanceof b?o:new b(a,String(o))}).finally(()=>{this.inFlight===r&&(this.inFlight=null);});return this.inFlight=r,r}enter(e,t){(e==="ready"||e==="lost")&&this.cancelRetry(),e==="ready"&&(this.failures=0,this.notBefore=0),this.failure=t??(e==="ready"?null:this.failure),this.state!==e&&(this.state=e,this.options.onStateChange?.(e,t));}renewBefore(){return this.options.renewBeforeSeconds??60}seconds(){return Math.floor(this.options.clock.now()/1e3)}},b=class n extends Error{constructor(t,r){super(`auth ${t}: ${r}`);this.reason=t;this.name="AuthError";}reason;static isAuthError(t){if(t instanceof n)return true;let r=t;return r?.name==="AuthError"&&typeof r.reason=="string"}};function qe(n){if(n instanceof b)return n.reason;let e=n?.reason;return typeof e=="string"&&["chain_exhausted","unavailable","timeout","internal"].includes(e)?e:"internal"}var f=class n extends Error{retryable=false;constructor(e){super(e),this.name="TransportRefusal";}static isRefusal(e){if(e instanceof n)return true;let t=e;return t?.name==="TransportRefusal"&&t.retryable===false}},U=["if-match","if-none-match"],X=4096;function $e(n){if(!n)return;let e={};for(let[t,r]of Object.entries(n)){let o=t.toLowerCase();if(!U.includes(o)||r===void 0)continue;let a=typeof r=="string"?je(r):r;if(typeof a!="string"||a.length>X||!Fe(a))throw new f(`the ${o} header value cannot be sent \u2014 it is not a string, is longer than ${X} characters, or contains a character outside the range an HTTP header value may carry. This is a malformed request, not a server failure; the value is withheld here rather than written to logs.`);a!==""&&(e[o]=a);}return Object.freeze(e)}function je(n){let e=o=>o===32||o===9||o===10||o===13,t=0,r=n.length;for(;t<r&&e(n.charCodeAt(t));)t++;for(;r>t&&e(n.charCodeAt(r-1));)r--;return n.slice(t,r)}function Fe(n){for(let e=0;e<n.length;e++){let t=n.charCodeAt(e);if(t!==9&&(t<32||t===127||t>255))return false}return true}function Be(n){let{bytes:e}=n;if(e!==void 0){if(Object.prototype.toString.call(e)!=="[object Uint8Array]")throw new f("the raw body is not a Uint8Array, so it cannot be sent as bytes. This is a malformed request, not a server failure.");if(n.body!==void 0)throw new f("the request carries both a JSON body and a raw body, and only one can be sent. This is a malformed request, not a server failure.");return new Uint8Array(e)}}function Q(n,e){let t=e.replayUnauthorizedOnce??true;return {async request(r){let o={...r},a=$e(o.headers),s=Be(o),l=Object.freeze({...o,headers:a,...s===void 0?{}:{bytes:s}}),u=await e.tokenSource.get(),c=await n(l,u);if(c.status!==401||!t)return c;e.tokenSource.invalidate(u);let g=await e.tokenSource.get(),_=await n(l,g);if(_.status===401)throw e.tokenSource.close("unavailable"),new b("unavailable","the server refused a freshly minted token");return _}}}function Z(n){let e=typeof n=="string"?new TextEncoder().encode(n):n;return btoa(Ue(e))}function Ue(n){let t="";for(let r=0;r<n.length;r+=32768)t+=String.fromCharCode(...n.subarray(r,r+32768));return t}var m=class extends Error{constructor(t,r,o,a,s){super(`${t} (${r}): ${o}`);this.reason=t;this.status=r;this.detail=o;this.retryAfterSeconds=a;this.code=s;this.name="GemApiError";}reason;status;detail;retryAfterSeconds;code;get retryable(){return this.reason==="unavailable"||this.reason==="rate_limited"}},ne=new WeakMap;function te(n){return ne.get(n)??{}}var Ne=new Set([408,429,500,502,503,504]),De=6e4;function He(n){if(n===void 0)return 2;if(!Number.isInteger(n)||n<0||n>10)throw new f(`maxRetries must be a whole number between 0 and 10; received ${JSON.stringify(n)}. This is a configuration fault, not a server failure.`);return n}var E=class{constructor(e){this.options=e;}options;async get(e,t){return this.send({method:"GET",path:e,signal:t},true)}async getWithEtag(e,t={}){let r=await this.sendRaw({method:"GET",path:e,...t.signal===void 0?{}:{signal:t.signal},...t.ifNoneMatch===void 0?{}:{headers:{"if-none-match":t.ifNoneMatch}}},true),o=r.etag===void 0?{}:{etag:r.etag};return r.status===304?{modified:false,...o}:{modified:true,body:r.body,...o}}async put(e,t,r,o={}){return this.send({method:"PUT",path:e,body:t,signal:r,...q(o)},o.replaySafe===true,o.retryRateLimited!==false)}async post(e,t,r,o={}){return this.send({method:"POST",path:e,body:t,signal:r,...q(o)},o.replaySafe===true,o.retryRateLimited!==false)}async postBytes(e,t,r,o={}){let a=await this.sendRaw({method:"POST",path:e,bytes:t,responseType:"bytes",signal:r,...q(o)},o.replaySafe===true,o.retryRateLimited!==false);return {bytes:Ve(a.body),...a.invocationId===void 0?{}:{invocationId:a.invocationId}}}async patch(e,t,r,o={}){return this.send({method:"PATCH",path:e,body:t,signal:r,...q(o)},o.replaySafe===true,o.retryRateLimited!==false)}async delete(e,t,r={}){return this.send({method:"DELETE",path:e,signal:t,...q(r)},r.replaySafe===true,r.retryRateLimited!==false)}async send(e,t,r=true){return (await this.sendRaw(e,t,r)).body}async sendRaw(e,t,r=true){let o=t?He(this.options.maxRetries)+1:1,a=null;if(e.signal?.aborted)throw ee(e.signal);for(let s=0;s<o;s++){if(s>0&&await this.backoff(s,a,e.signal),e.signal?.aborted)throw ee(e.signal);let l;try{l=await this.options.transport.request(e);}catch(c){if(b.isAuthError(c)||f.isRefusal(c)||e.signal?.aborted||We(c))throw c;a=new m("unavailable",0,String(c));continue}if(l.status>=200&&l.status<300||l.status===304)return l;let u=ze(l);if(!Ne.has(l.status)||l.status===429&&!r)throw u;a=u;}throw a??new m("unavailable",0,"no attempt was made")}backoff(e,t,r){if(r?.aborted)return Promise.resolve();let o=t?.retryAfterSeconds,a=o!==void 0?o*1e3:2**(e-1)*250,s=2**(e-1)*250,l=Math.min(Math.max(a,s),De);return new Promise(u=>{let c=this.options.clock,g=false,_=false,v,h=()=>{g||(g=true,_&&c.clearTimeout(v),r?.removeEventListener("abort",h),u());};r?.addEventListener("abort",h,{once:true}),v=c.setTimeout(h,l),_=true,g&&c.clearTimeout(v);})}};function Ve(n){if(n instanceof Uint8Array)return n;if(n==null)return new Uint8Array(0);let e=typeof n=="string"?n:JSON.stringify(n);return new TextEncoder().encode(e)}function q(n){return {...n.keepalive===void 0?{}:{keepalive:n.keepalive},...n.ifMatch===void 0?{}:{headers:{"if-match":n.ifMatch}}}}function ee(n){return n.reason!==void 0?n.reason:new DOMException("The operation was aborted.","AbortError")}function We(n){let e=n?.name;return e==="AbortError"||e==="TimeoutError"}function ze(n){let e=Ye(n),t=Xe(n.body),r={...t===void 0?{}:{details:t},...n.invocationId===void 0?{}:{invocationId:n.invocationId}};return Object.keys(r).length>0&&ne.set(e,r),e}var Ke=new Map([["insufficient_funds","insufficient_funds"]]);function Ye(n){let{status:e,body:t}=n,r=Je(t),o=n.retryAfterSeconds??Ze(t),a=Qe(t),s=a===void 0?void 0:Ke.get(a);if(s!==void 0)return new m(s,e,r,void 0,a);switch(e){case 304:return new m("not_modified",e,r);case 400:case 422:return new m("invalid",e,r,void 0,a);case 403:return new m("forbidden",e,r,void 0,a);case 404:return new m("not_found",e,r,void 0,a);case 402:return new m("insufficient_funds",e,r,void 0,a);case 409:return new m("conflict",e,r,void 0,a);case 412:return new m("precondition_failed",e,r,void 0,a);case 413:return new m("too_large",e,r,void 0,a);case 429:return new m("rate_limited",e,r,o,a);default:return new m("unavailable",e,r,o,a)}}function Je(n){if(typeof n=="string")return n;let e=n?.message;if(typeof e=="string")return e;let t=n?.error;if(typeof t=="string")return t;let r=t?.message;return typeof r=="string"?r:"no detail"}function Xe(n){let t=n?.error?.details;return t===null?void 0:t}function Qe(n){let t=n?.error?.code;return typeof t=="string"&&t.length>0?t:void 0}function Ze(n){let e=n?.retryAfterSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function en(n){let e=n.lastIndexOf("@");return (e===-1?n:`***@${n.slice(e+1)}`).slice(0,200)}var nn=new Set(U);function tn(n){if(!n)return {};let e={};for(let[t,r]of Object.entries(n))nn.has(t.toLowerCase())&&(e[t.toLowerCase()]=r);return e}function re(n){let e=n.fetch??globalThis.fetch.bind(globalThis);return Q(async(t,r)=>{let o;try{o=new URL(n.baseUrl.replace(/\/+$/,""));}catch{throw new f("the configured baseUrl is not a valid URL. Its value is withheld here rather than written to logs. This is a configuration fault, not a server failure.")}let a;try{a=new URL(o.href.replace(/\/+$/,"")+t.path);}catch{throw new f(`${JSON.stringify(typeof t.path=="string"?en(t.path):"(a non-string path)")} does not form a valid URL against ${o.protocol}//${o.host}. This is a malformed request, not a server failure.`)}if(a.protocol!==o.protocol||a.host!==o.host)throw new f(`${JSON.stringify(a.pathname)} resolves to ${a.protocol}//${a.host}, not ${o.protocol}//${o.host}. A request path may not change the request's origin \u2014 it carries the play token.`);if(a.username!==""||a.password!==""){let h=o.username!==""||o.password!=="",y=a.username!==o.username||a.password!==o.password,S=h?y?"baseUrl (and possibly the request path)":"baseUrl":"request path";throw new f(`the ${S} puts credentials in the URL, which cannot be fetched (${t.method} ${a.pathname}). The value is withheld here rather than written to logs. This is a malformed request, not a server failure.`)}for(let[h,y]of Object.entries(n.defaultQuery??{}))a.searchParams.has(h)||a.searchParams.set(h,y);let s=t.bytes,l=t.bytes===void 0?void 0:"application/octet-stream";try{t.body!==void 0&&(s=JSON.stringify(t.body),l="application/json");}catch(h){throw new f(`the body of ${t.method} ${JSON.stringify(a.pathname)} could not be serialised to JSON: ${String(h)}. This is a bug in the request, not a server failure \u2014 retrying sends the same unserialisable value.`)}let u=await e(a.toString(),{method:t.method,headers:{authorization:`Bearer ${r}`,...l===void 0?{}:{"content-type":l},...tn(t.headers)},body:s,signal:t.signal,...t.keepalive===void 0?{}:{keepalive:t.keepalive},credentials:"omit",mode:"cors",redirect:"error",cache:"no-store",referrerPolicy:"no-referrer"}),c=null;if(t.responseType==="bytes"&&u.status>=200&&u.status<300)c=new Uint8Array(await u.arrayBuffer());else {let h=await u.text();if(h.length>0)try{c=JSON.parse(h);}catch{c=h;}}let g=u.headers.get("etag"),_=rn(u.headers.get("retry-after")),v=u.headers.get("x-gem-invocation-id");return {status:u.status,body:c,...g===null?{}:{etag:g},..._===void 0?{}:{retryAfterSeconds:_},...v===null||v===""?{}:{invocationId:v}}},n)}function rn(n){if(n===null)return;let e=n.trim();if(!/^\d+$/.test(e))return;let t=Number(e);return Number.isFinite(t)?t:void 0}var on="gem-web-bridge";var I=65536,oe=8,N=5e3,ae=1024;var D=Object.create(null);var ie=Object.create(null);function an(n){let e=/^([a-z][a-z0-9+.-]*):\/\/([a-z0-9.-]+|\[[0-9a-f:.]+\])(:([0-9]{1,5}))?$/i.exec(n);return e===null?false:e[4]===void 0||Number(e[4])<=65535}function sn(n){let e;try{e=new URL(n);}catch{return false}return e.username!==""||e.password!==""?false:e.protocol==="https:"?true:e.protocol==="http:"&&(e.hostname==="localhost"||e.hostname==="127.0.0.1")}function ln(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function dn(n){return /^[a-z_]+$/.test(n)}function V(n,e,t){if(e>oe)return `nesting deeper than ${oe}`;if(++t.nodes>N)return `more than ${N} values`;if(t.bytes>I)return `over the ${I} byte limit`;if(n==null)return t.bytes+=4,null;let r=typeof n;if(r==="boolean")return t.bytes+=5,null;if(r==="number")return t.bytes+=8,null;if(r==="string")return t.bytes+=n.length*3+2,null;if(r!=="object")return `${r} is not plain data`;let o=n;if(t.seen.has(o))return "a repeated or cyclic object reference";if(t.seen.add(o),Array.isArray(n)){if(n.length>ae)return `an array of ${n.length} entries, over the ${ae} limit`;t.bytes+=2;for(let l of n){let u=V(l,e+1,t);if(u)return u}return null}let a=Object.getPrototypeOf(n);if(a!==Object.prototype&&a!==null)return "a value that is not a plain object";t.bytes+=2;let s=n;for(let l in s){if(!Object.prototype.hasOwnProperty.call(s,l))continue;if(++t.nodes>N)return `more than ${N} values`;if(t.bytes+=l.length*3+4,t.bytes>I)return `over the ${I} byte limit`;let u=V(s[l],e+1,t);if(u)return u}return null}function un(n){let e={nodes:0,bytes:0,seen:new Set},t=V(n,0,e);return t?`message contains ${t}`:e.bytes>I?`message is over the ${I} byte limit`:null}var cn={origin:[an,"not a well-formed origin"],url:[sn,"not a safe absolute http(s) URL"],bcp47:[ln,"not a well-formed BCP 47 tag"],code:[dn,"not a code of lower-case letters and underscores"]};function se(n,e,t){for(let r of e){let o=t===""?r.n:`${t}.${r.n}`,a=n[r.n];if(a==null){if(r.o)continue;return `${o}: required`}let s=W(a,r,o);if(s)return s}return null}function W(n,e,t){switch(e.k){case "u":return typeof n=="boolean"?null:W(n,{...e,k:typeof n=="string"?"s":"n"},t);case "s":{if(typeof n!="string")return `${t}: expected string`;if(n.length>e.max)return `${t}: exceeds ${e.max} characters`;if(e.f){let[r,o]=cn[e.f];if(!r(n))return `${t}: ${o}`}return null}case "n":case "i":return typeof n!="number"||!(e.k=="i"?Number.isInteger:Number.isFinite)(n)?`${t}: expected ${e.k=="i"?"integer":"number"}`:n<e.lo||n>e.hi?`${t}: out of range ${e.lo}..${e.hi}`:null;case "b":return typeof n=="boolean"?null:`${t}: expected boolean`;case "e":{let r=e.v;return r.includes(n)?null:`${t}: not one of ${r.join("|")}`}case "o":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:se(n,e.fs,t);case "j":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected a plain object`:null;case "a":{if(!Array.isArray(n))return `${t}: expected array`;if(n.length>e.max)return `${t}: exceeds ${e.max} items`;let r=e.it,o=`${t}[]`;for(let a of n){if(a==null){if(r.o)continue;return `${o}: required`}let s=W(a,r,o);if(s)return s}return null}default:{let r=e.k;return `${t}: unknown kind ${String(r)}`}}}var le=Object.create(null);function d(n,e,t,r){return D[n]=t,r&&(ie[n]=r),le[n]=o=>{let a=un(o);if(a)return a;if(typeof o!="object"||o===null||Array.isArray(o))return "message: expected object";let s=o;return s.gem!==on?"gem: wrong protocol marker":s.type!==n?`type: expected ${n}`:se(s,e,"")}}var p={n:"requestId",k:"s",max:64};d("gem.handshake",[{n:"versions",k:"o",fs:[{n:"min",k:"i",lo:1,hi:1e3},{n:"max",k:"i",lo:1,hi:1e3}]},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}},{n:"embedder",k:"s",max:2048,f:"origin"},{n:"unbidden",k:"b",o:1}],30);d("gem.handshake.accept",[{n:"v",k:"i",lo:1,hi:1e3},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}}],5);d("gem.token",[{n:"token",k:"s",max:4096},{n:"requestId",k:"s",o:1,max:64},{n:"generation",k:"i",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"s",o:1,max:512,f:"url"},{n:"playerId",k:"s",max:64},{n:"gameId",k:"s",max:64},{n:"channel",k:"e",v:["dev","test","release"]},{n:"gameVersion",k:"s",o:1,max:64},{n:"expiresAt",k:"i",lo:0,hi:4102444800},{n:"chainEndsAt",k:"i",lo:0,hi:4102444800},{n:"allowDevTools",k:"b",o:1}],30);d("gem.token.denied",[p,{n:"retryable",k:"b"},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:36e5},{n:"reason",k:"e",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"s",max:64}],30);d("gem.player",[{n:"untrusted",k:"o",fs:[{n:"displayName",k:"s",max:64},{n:"displayTag",k:"s",o:1,max:80},{n:"displayHandle",k:"s",max:80}]},{n:"playerId",k:"s",o:1,max:64},{n:"discriminator",k:"s",o:1,max:8},{n:"avatarIconUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatarIconId",k:"s",o:1,max:64},{n:"avatar3dId",k:"s",o:1,max:64},{n:"avatar3dModelUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatar3dIconUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatars3d",k:"a",o:1,max:8,it:{n:"",k:"o",fs:[{n:"family",k:"s",max:32},{n:"id",k:"s",max:64},{n:"modelUrl",k:"s",max:256,f:"url"},{n:"iconUrl",k:"s",max:256,f:"url"}]}},{n:"badges",k:"a",o:1,max:2,it:{n:"",k:"o",fs:[{n:"itemId",k:"s",max:64},{n:"iconUrl",k:"s",max:2048,f:"url"}]}},{n:"displayTag",k:"s",max:8},{n:"avatarUrl",k:"s",o:1,max:2048,f:"url"},{n:"boost",k:"o",o:1,fs:[{n:"multipliers",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"currencyId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"multiplierBp",k:"i",lo:1e4,hi:1e6}]}},{n:"expiresInDays",k:"i",o:1,lo:1,hi:7}]}],12);d("gem.pause",[{n:"paused",k:"b"}],120);d("gem.prefs",[{n:"reducedMotion",k:"b"},{n:"muted",k:"b"},{n:"showFrameStats",k:"b",o:1},{n:"locale",k:"s",max:35,f:"bcp47"},{n:"recommended",k:"o",o:1,fs:[{n:"volume",k:"i",lo:0,hi:100},{n:"batterySaver",k:"b"},{n:"keyboardLayout",k:"e",v:["wasd","arrows"]},{n:"gamepadConfirm",k:"e",v:["south","east"]},{n:"vibration",k:"b"},{n:"lookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"gamepadLookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"invertLookY",k:"b",o:1},{n:"touchMovement",k:"s",o:1,max:16,f:"code"},{n:"graphicsQuality",k:"s",o:1,max:16,f:"code"},{n:"graphicsQualityAuto",k:"b",o:1}]}],60);d("gem.cohorts",[{n:"cohorts",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"experimentId",k:"s",max:36},{n:"variantKey",k:"s",max:32}]}}],12,"cohorts");d("gem.earnAllowanceChanged",[],30,"earnAllowance");d("gem.viewport",[{n:"insets",k:"o",fs:[{n:"top",k:"i",lo:0,hi:4096},{n:"right",k:"i",lo:0,hi:4096},{n:"bottom",k:"i",lo:0,hi:4096},{n:"left",k:"i",lo:0,hi:4096}]},{n:"reserved",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384},{n:"width",k:"i",lo:0,hi:16384},{n:"height",k:"i",lo:0,hi:16384},{n:"control",k:"o",o:1,fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384},{n:"width",k:"i",lo:0,hi:16384},{n:"height",k:"i",lo:0,hi:16384}]}]}}],60,"viewport");d("gem.deviceSettings",[{n:"settings",k:"j",o:1}],12,"deviceSettings");d("gem.willTerminate",[{n:"reason",k:"e",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"i",lo:0,hi:6e4}],10);d("gem.roomEvent",[{n:"event",k:"e",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"s",max:64},{n:"matchId",k:"s",o:1,max:64},{n:"version",k:"i",o:1,lo:0,hi:2147483647},{n:"reason",k:"s",o:1,max:64},{n:"platform",k:"e",o:1,v:["universal","mobile"]}],120,"rooms");d("gem.socketState",[{n:"connected",k:"b"},{n:"reason",k:"e",o:1,v:["connecting","dropped","watchdog","terminal"]}],12,"socketState");d("gem.seatedEvent",[{n:"roomId",k:"s",max:64}],60,"partySeating");d("gem.autoStartFailedEvent",[{n:"roomId",k:"s",max:64},{n:"code",k:"s",max:64}],30,"autoStartFailure");d("gem.ticketEvent",[{n:"event",k:"e",v:["queued","matched","expired","cancelled","failed"]},{n:"ticketId",k:"s",max:64},{n:"partySize",k:"i",o:1,lo:1,hi:64},{n:"queuedAt",k:"i",o:1,lo:0,hi:4102444800},{n:"expiresAt",k:"i",o:1,lo:0,hi:4102444800},{n:"reason",k:"s",o:1,max:64},{n:"roomId",k:"s",o:1,max:64}],60,"ticketEvents");d("gem.signalEvent",[{n:"event",k:"e",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}],1800,"p2p");d("gem.dedicatedEvent",[{n:"event",k:"e",v:["answer","error","matchEnded"]},{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",o:1,max:10240},{n:"sessionId",k:"s",o:1,max:64},{n:"code",k:"s",o:1,max:64},{n:"message",k:"s",o:1,max:256},{n:"reason",k:"s",o:1,max:64}],120,"dedicated");d("gem.partyResult",[p,{n:"partyId",k:"s",o:1,max:64}],30,"parties");d("gem.clusterTarget",[{n:"clusterTargetId",k:"s",max:64},{n:"clusterTargetIds",k:"a",o:1,max:3,it:{n:"",k:"s",max:64}}],12,"clusterTarget");d("gem.devtools",[{n:"action",k:"e",v:["open","close","toggle"]}],30,"devtools");d("gem.screenshot",[{n:"maxWidth",k:"i",lo:1,hi:7680},{n:"maxHeight",k:"i",lo:1,hi:4320}],6,"screenshot");d("gem.screenshot.denied",[{n:"reason",k:"e",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"b"}],12,"screenshot");d("gem.requestContext",[],12,"feedbackContext");d("gem.gameContext",[{n:"context",k:"j"}],12,"feedbackContext");d("gem.signal",[{n:"signal",k:"e",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}],1200,"p2p");d("gem.dedicatedOffer",[{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",max:10240},{n:"intent",k:"e",v:["initial","ice_restart","full_reconnect"]}],60,"dedicated");d("gem.partyRequest",[p],12,"parties");d("gem.ready",[],5);d("gem.engaged",[],5,"engagement");d("gem.progress",[{n:"loaded",k:"i",lo:0,hi:1099511627776},{n:"total",k:"i",lo:0,hi:1099511627776}],600);d("gem.requestToken",[p,{n:"reason",k:"e",v:["initial","expiring","rejected"]}],12);d("gem.requestLocalServer",[p,{n:"gameRoomId",k:"s",max:64}],6,"localHost");d("gem.localServer",[p,{n:"serverId",k:"s",o:1,max:128}],30,"localHost");d("gem.localServer.denied",[p,{n:"retryable",k:"b"},{n:"reason",k:"e",v:["refused","unavailable"]}],30,"localHost");d("gem.exit",[{n:"reason",k:"s",o:1,max:64}],5);d("gem.openExternal",[{n:"url",k:"s",max:2048,f:"url"}],6);d("gem.requestFullscreen",[{n:"enabled",k:"b"}],30);d("gem.audioState",[{n:"muted",k:"b"}],120,"audioState");d("gem.rewardCue",[{n:"currencySlug",k:"s",max:32},{n:"expected",k:"i",o:1,lo:1,hi:1e9},{n:"origin",k:"o",o:1,fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384}]}],60,"rewardCue");d("gem.walletDisplay",[{n:"visible",k:"b"},{n:"currencies",k:"a",o:1,max:8,it:{n:"",k:"s",max:64}},{n:"score",k:"b",o:1}],60,"walletDisplay");d("gem.controlsDeclare",[{n:"uses",k:"o",fs:[{n:"lookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"gamepadLookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"invertLookY",k:"s",o:1,max:16,f:"code"},{n:"touchMovement",k:"s",o:1,max:16,f:"code"}]}],60,"controls");d("gem.menu",[{n:"settings",k:"b"},{n:"items",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"id",k:"s",max:32},{n:"label",k:"s",max:40}]}}],60,"gameMenu");d("gem.menuSelect",[{n:"entry",k:"e",v:["settings","item"]},{n:"id",k:"s",o:1,max:32}],60,"gameMenu");d("gem.gemCorner",[{n:"corner",k:"e",v:["top-left","top-right","bottom-left","bottom-right"]}],12,"gemCorner");d("gem.settingsDeclare",[{n:"settings",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"id",k:"s",max:40},{n:"label",k:"s",max:40},{n:"kind",k:"e",v:["toggle","slider","choice"]},{n:"value",k:"u",max:40,lo:-1e6,hi:1e6},{n:"quick",k:"b",o:1},{n:"icon",k:"s",o:1,max:16,f:"code"},{n:"min",k:"n",o:1,lo:-1e6,hi:1e6},{n:"max",k:"n",o:1,lo:-1e6,hi:1e6},{n:"step",k:"n",o:1,lo:0,hi:1e6},{n:"options",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"id",k:"s",max:40},{n:"label",k:"s",max:40}]}}]}}],120,"gameSettings");d("gem.settingChange",[{n:"id",k:"s",max:40},{n:"value",k:"u",max:40,lo:-1e6,hi:1e6}],120,"gameSettings");d("gem.requestShare",[{n:"params",k:"a",max:16,it:{n:"",k:"o",fs:[{n:"key",k:"s",max:64},{n:"value",k:"s",max:512}]}}],6,"share");d("gem.requestAvatarPicker",[{n:"tab",k:"e",o:1,v:["2d","3d"]}],6,"avatarPicker");d("gem.vibrate",[{n:"pattern",k:"a",max:99,it:{n:"",k:"i",lo:0,hi:1e4}}],600,"vibration");d("gem.frameStats",[{n:"fps",k:"i",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"i",lo:0,hi:1e5},{n:"counts",k:"e",o:1,v:["pageFrames","gameDraws"]}],120,"frameStats");d("gem.portraitBorders",[{n:"name",k:"s",o:1,max:40}],60,"portraitBorders");d("gem.error",[{n:"code",k:"e",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"s",o:1,max:256}],60);d("gem.requestPurchase",[p,{n:"purchaseKind",k:"e",v:["item","recipe"]},{n:"targetId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"quantity",k:"i",o:1,lo:1,hi:10},{n:"catalogId",k:"s",o:1,max:64}],12,"purchases");d("gem.requestAvatar3dPurchase",[p,{n:"itemId",k:"s",max:64},{n:"currencySlug",k:"s",max:32}],12,"avatar3dPurchases");d("gem.purchaseResult",[p,{n:"outcome",k:"e",v:["ok","declined","unavailable"]},{n:"reason",k:"s",o:1,max:64,f:"code"},{n:"purchaseId",k:"s",o:1,max:64}],30,"purchases");d("gem.deviceSettings.put",[p,{n:"settings",k:"j"}],30,"deviceSettings");d("gem.deviceSettings.result",[p,{n:"outcome",k:"e",v:["stored","too_large","unavailable"]}],30,"deviceSettings");d("gem.requestAd",[p,{n:"placement",k:"s",max:32},{n:"format",k:"e",v:["interstitial","rewarded"]}],6,"ads");d("gem.adResult",[p,{n:"outcome",k:"e",v:["shown","no_ad","unavailable"]}],12,"ads");d("gem.signalMoment",[p,{n:"kind",k:"e",v:["level_end","run_end","match_end","menu_return","other_break"]},{n:"placement",k:"s",o:1,max:32}],6,"moments");d("gem.momentResult",[p,{n:"shown",k:"b"}],12,"moments");d("gem.requestSignIn",[p],6,"signIn");d("gem.signInResult",[p,{n:"outcome",k:"e",v:["signed_in","declined","unavailable"]}],12,"signIn");d("gem.requestFriendChallenge",[p,{n:"playerId",k:"s",max:64},{n:"template",k:"s",max:64},{n:"params",k:"j",o:1}],12,"friendChallenges");d("gem.friendChallengeResult",[p,{n:"outcome",k:"e",v:["accepted","cancelled","refused","unavailable","rate_limited","invalid"]},{n:"code",k:"s",o:1,max:64},{n:"param",k:"s",o:1,max:64},{n:"channel",k:"s",o:1,max:16},{n:"configVersion",k:"i",o:1,lo:0,hi:9007199254740991},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:864e5},{n:"detail",k:"s",o:1,max:300}],30,"friendChallenges");Object.freeze(le);D.__malformed=60;Object.freeze(D);Object.freeze(ie);var M={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)};function de(n){let e=n.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}var mn=1e4;function ue(n,e){return z(n,e)}function z(n,e){if(typeof n.serverToken!="function"||typeof n.onServerToken!="function")throw new Error("this runtime delivers no game-server token: host.serverToken/onServerToken are missing. The server image running this bundle predates token delivery \u2014 the bundle cannot call gem-api on it.");let t=s=>({token:s.token,expiresAt:s.expiresAt,chainEndsAt:Number.POSITIVE_INFINITY}),r=null,o=new B({clock:e.clock,...e.onStateChange===void 0?{}:{onStateChange:e.onStateChange},request:()=>new Promise((s,l)=>{let u=e.clock.setTimeout(()=>{r=null,l({reason:"unavailable",retryable:true});},e.timeoutMs??mn);r={resolve:c=>{e.clock.clearTimeout(u),s(c);},reject:l,timer:u};})}),a=n.onServerToken(s=>{let l=t(s),u=r;if(u){r=null,u.resolve(l);return}o.accept(l);});return {source:o,dispose(){a(),o.dispose(),r&&(e.clock.clearTimeout(r.timer),r.reject({reason:"unavailable",retryable:false}),r=null);}}}var Y={};Ie(Y,{acceptTransfer:()=>gn,addEntityProgression:()=>pn,adminAction:()=>yn,cancelInventoryTransfer:()=>fn,claimEntityProgressionRewards:()=>hn,closeGameRoom:()=>_n,createEntityBatchOrder:()=>bn,createEntityOrder:()=>vn,createSession:()=>Rn,deleteEntityGameSetting:()=>xn,deleteEntitySave:()=>kn,deleteSession:()=>Sn,deleteShowcaseValue:()=>wn,executeEntityRecipe:()=>An,finalizeSaveUpload:()=>Pn,getChannelAssignment:()=>On,getDropRates:()=>Tn,getEntityCurrency:()=>Gn,getEntityGameSetting:()=>Cn,getEntityInventory:()=>En,getEntityInventoryItem:()=>In,getEntityLeaderboard:()=>Mn,getEntityOrder:()=>Ln,getEntityProgression:()=>qn,getEntityRecipeAvailability:()=>$n,getEntityRecipeUsage:()=>jn,getEntitySave:()=>Fn,getEvent:()=>Bn,getGameRoomV2:()=>Un,getLeaderboard:()=>Nn,getPlayerGameProfile:()=>Dn,getPurchaseCatalog:()=>Hn,getResolvedTemplate:()=>Vn,getRoomArgs:()=>Wn,getShowcaseValue:()=>zn,getTransferDetails:()=>Kn,ingestAnalyticsEvents:()=>K,initiateInventoryTransfer:()=>Yn,invokeFunction:()=>Jn,kickPlayer:()=>Xn,listChallenges:()=>Qn,listEntityGameSettings:()=>Zn,listEntityOrders:()=>et,listEntityProgressions:()=>nt,listEntitySaves:()=>tt,listEvents:()=>rt,listGameRooms:()=>ot,listResolvedTemplates:()=>at,listTransfers:()=>it,maxEntityProgression:()=>st,putEntityGameSetting:()=>lt,putRoomArgs:()=>dt,putShowcaseValue:()=>ut,rejectTransfer:()=>ct,reportMatchPlayers:()=>mt,requestSaveUploadUrl:()=>gt,resetEntityProgression:()=>pt,setMatchBackfill:()=>yt,simulateEntityOrder:()=>ft,transferHostV2:()=>ht,updateGameRoomV2:()=>_t});function i(n){let e=String(n);if(!/^[A-Za-z0-9_.-]{1,128}$/.test(e)||e==="."||e==="..")throw new TypeError(`${JSON.stringify(e)} is not a usable path segment \u2014 it is interpolated into a URL`);return encodeURIComponent(e)}async function gn(n,e,t){let r=`/v1/inventory/transfers/${i(e)}/accept`;return n.client.post(r,void 0,t?.signal)}async function pn(n,e,t,r,o,a){let s=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/add`;return n.client.post(s,o,a?.signal)}async function yn(n,e,t,r){let o=`/v1/voice/sessions/${i(e)}/admin`;return n.client.post(o,t,r?.signal)}async function fn(n,e,t){let r=`/v1/inventory/transfers/${i(e)}/cancel`;return n.client.post(r,void 0,t?.signal)}async function hn(n,e,t,r,o,a){let s=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/claim`;return n.client.post(s,o,a?.signal)}async function _n(n,e,t){let r=`/v1/games/${i(n.gameId())}/game-rooms/${i(e)}`;return n.client.delete(r,t?.signal)}async function bn(n,e,t,r,o){let a=`/v1/inventory/${i(e)}/${i(t)}/orders/batch`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function vn(n,e,t,r,o){let a=`/v1/inventory/${i(e)}/${i(t)}/orders`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function Rn(n,e,t){return n.client.post("/v1/voice/sessions",e,t?.signal)}async function xn(n,e,t,r,o){let a=`/v1/settings/${i(e)}/${i(t)}/${i(r)}`;return n.client.delete(a,o?.signal)}async function kn(n,e,t,r,o){let a=`/v1/saves/${i(e)}/${i(t)}/${i(r)}`;return n.client.delete(a,o?.signal)}async function Sn(n,e,t){let r=`/v1/voice/sessions/${i(e)}`;return n.client.delete(r,t?.signal)}async function wn(n,e,t,r){let o=`/v1/showcase/players/${i(e)}/${i(t)}`;return n.client.delete(o,r?.signal)}async function An(n,e,t,r,o){let a=`/v1/inventory/${i(e)}/${i(t)}/recipes/execute`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function Pn(n,e,t,r,o,a){let s=`/v1/saves/${i(e)}/${i(t)}/${i(r)}/finalize`;return n.client.post(s,o,a?.signal)}async function On(n,e,t){let r=`/v1/games/${i(n.gameId())}/config/channels/${i(e)}`;return n.client.getWithEtag(r,{...t?.signal===void 0?{}:{signal:t.signal},...t?.ifNoneMatch===void 0?{}:{ifNoneMatch:t.ifNoneMatch}})}async function Tn(n,e,t){let r=`/v1/inventory/loot-tables/${i(e)}/drop-rates`;return n.client.get(r,t?.signal)}async function Gn(n,e,t,r,o){let a=`/v1/inventory/${i(e)}/${i(t)}/currencies/${i(r)}`;return n.client.get(a,o?.signal)}async function Cn(n,e,t,r,o){let a=`/v1/settings/${i(e)}/${i(t)}/${i(r)}`;return n.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function En(n,e,t,r){let o=new URLSearchParams;r?.include_buckets!==void 0&&o.set("include_buckets",String(r?.include_buckets)),r?.include_custom_data!==void 0&&o.set("include_custom_data",String(r?.include_custom_data)),r?.currency_limit!==void 0&&o.set("currency_limit",String(r?.currency_limit)),r?.currency_cursor!==void 0&&o.set("currency_cursor",String(r?.currency_cursor)),r?.item_limit!==void 0&&o.set("item_limit",String(r?.item_limit)),r?.item_cursor!==void 0&&o.set("item_cursor",String(r?.item_cursor)),r?.progression_limit!==void 0&&o.set("progression_limit",String(r?.progression_limit)),r?.progression_cursor!==void 0&&o.set("progression_cursor",String(r?.progression_cursor));let a=o.toString(),s=`/v1/inventory/${i(e)}/${i(t)}`+(a?`?${a}`:"");return n.client.get(s,r?.signal)}async function In(n,e,t,r,o){let a=`/v1/inventory/${i(e)}/${i(t)}/items/${i(r)}`;return n.client.get(a,o?.signal)}async function Mn(n,e,t,r,o){let a=new URLSearchParams;o?.bucket_1!==void 0&&a.set("bucket_1",String(o?.bucket_1)),o?.bucket_2!==void 0&&a.set("bucket_2",String(o?.bucket_2)),o?.limit!==void 0&&a.set("limit",String(o?.limit)),o?.periods_back!==void 0&&a.set("periods_back",String(o?.periods_back)),o?.period!==void 0&&a.set("period",String(o?.period)),o?.player_id!==void 0&&a.set("player_id",String(o?.player_id));let s=a.toString(),l=`/v1/leaderboards/${i(e)}/${i(t)}/${i(r)}`+(s?`?${s}`:"");return n.client.get(l,o?.signal)}async function Ln(n,e,t,r,o){let a=`/v1/inventory/${i(e)}/${i(t)}/orders/${i(r)}`;return n.client.get(a,o?.signal)}async function qn(n,e,t,r,o){let a=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}`;return n.client.get(a,o?.signal)}async function $n(n,e,t,r,o,a){let s=`/v1/inventory/${i(e)}/${i(t)}/catalogs/${i(r)}/recipes/${i(o)}/availability`;return n.client.get(s,a?.signal)}async function jn(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit));let a=o.toString(),s=`/v1/inventory/${i(e)}/${i(t)}/recipe-usage`+(a?`?${a}`:"");return n.client.get(s,r?.signal)}async function Fn(n,e,t,r,o){let a=`/v1/saves/${i(e)}/${i(t)}/${i(r)}`;return n.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function Bn(n,e,t){let r=`/v1/events/${i(e)}`;return n.client.get(r,t?.signal)}async function Un(n,e,t){let r=`/v2/games/${i(n.gameId())}/game-rooms/${i(e)}`;return n.client.getWithEtag(r,{...t?.signal===void 0?{}:{signal:t.signal},...t?.ifNoneMatch===void 0?{}:{ifNoneMatch:t.ifNoneMatch}})}async function Nn(n,e,t){let r=new URLSearchParams;t?.bucket_1!==void 0&&r.set("bucket_1",String(t?.bucket_1)),t?.bucket_2!==void 0&&r.set("bucket_2",String(t?.bucket_2)),t?.periods_back!==void 0&&r.set("periods_back",String(t?.periods_back)),t?.period!==void 0&&r.set("period",String(t?.period)),t?.player_id!==void 0&&r.set("player_id",String(t?.player_id));let o=r.toString(),a=`/v1/leaderboards/${i(e)}`+(o?`?${o}`:"");return n.client.get(a,t?.signal)}async function Dn(n,e,t){let r=`/v1/profiles/players/${i(e)}`;return n.client.get(r,t?.signal)}async function Hn(n,e){let t=new URLSearchParams;e?.config_version!==void 0&&t.set("config_version",String(e?.config_version));let r=t.toString(),o="/v1/inventory/platform-funded-game-inventory-purchase-catalog"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function Vn(n,e,t){let r=`/v1/game-room-templates/${i(e)}`;return n.client.get(r,t?.signal)}async function Wn(n,e,t){let r=`/v1/games/${i(n.gameId())}/game-rooms/${i(e)}/room-args`;return n.client.get(r,t?.signal)}async function zn(n,e,t,r){let o=`/v1/showcase/players/${i(e)}/${i(t)}`;return n.client.get(o,r?.signal)}async function Kn(n,e,t){let r=`/v1/inventory/transfers/${i(e)}`;return n.client.get(r,t?.signal)}async function K(n,e,t){let r=`/v1/games/${i(n.gameId())}/analytics/events`;return n.client.post(r,e,t?.signal,{replaySafe:true,retryRateLimited:false})}async function Yn(n,e,t){return n.client.post("/v1/inventory/transfers",e,t?.signal)}async function Jn(n,e,t){return n.client.postBytes("/v1/functions/invoke",e,t?.signal)}async function Xn(n,e,t,r){let o=`/v1/games/${i(n.gameId())}/game-rooms/${i(e)}/kick/${i(t)}`;return n.client.post(o,void 0,r?.signal)}async function Qn(n,e){let t=new URLSearchParams;e?.periods_back!==void 0&&t.set("periods_back",String(e?.periods_back)),e?.player_id!==void 0&&t.set("player_id",String(e?.player_id));let r=t.toString(),o="/v1/challenges"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function Zn(n,e,t,r){let o=`/v1/settings/${i(e)}/${i(t)}`;return n.client.get(o,r?.signal)}async function et(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),s=`/v1/inventory/${i(e)}/${i(t)}/orders`+(a?`?${a}`:"");return n.client.get(s,r?.signal)}async function nt(n,e,t,r){let o=`/v1/inventory/${i(e)}/${i(t)}/progressions`;return n.client.get(o,r?.signal)}async function tt(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),s=`/v1/saves/${i(e)}/${i(t)}`+(a?`?${a}`:"");return n.client.get(s,r?.signal)}async function rt(n,e){let t=new URLSearchParams;e?.include_inactive!==void 0&&t.set("include_inactive",String(e?.include_inactive)),e?.limit!==void 0&&t.set("limit",String(e?.limit)),e?.offset!==void 0&&t.set("offset",String(e?.offset));let r=t.toString(),o="/v1/events"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function ot(n,e){let t=new URLSearchParams;e?.status!==void 0&&t.set("status",String(e?.status)),e?.game_channel!==void 0&&t.set("game_channel",String(e?.game_channel)),e?.game_room_type!==void 0&&t.set("game_room_type",String(e?.game_room_type)),e?.template_id!==void 0&&t.set("template_id",String(e?.template_id)),e?.template_slug!==void 0&&t.set("template_slug",String(e?.template_slug)),e?.limit!==void 0&&t.set("limit",String(e?.limit)),e?.cursor!==void 0&&t.set("cursor",String(e?.cursor));let r=t.toString(),o=`/v1/games/${i(n.gameId())}/game-rooms`+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function at(n,e){return n.client.get("/v1/game-room-templates",e?.signal)}async function it(n,e){let t=new URLSearchParams;e.entity_type!==void 0&&t.set("entity_type",String(e.entity_type)),e.entity_id!==void 0&&t.set("entity_id",String(e.entity_id)),e?.direction!==void 0&&t.set("direction",String(e?.direction)),e?.status!==void 0&&t.set("status",String(e?.status)),e?.cursor!==void 0&&t.set("cursor",String(e?.cursor)),e?.limit!==void 0&&t.set("limit",String(e?.limit));let r=t.toString(),o="/v1/inventory/transfers"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function st(n,e,t,r,o,a){let s=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/max`;return n.client.post(s,o,a?.signal)}async function lt(n,e,t,r,o,a){let s=`/v1/settings/${i(e)}/${i(t)}/${i(r)}`;return n.client.put(s,o,a?.signal,{...a?.ifMatch===void 0?{}:{ifMatch:a.ifMatch}})}async function dt(n,e,t,r){let o=`/v1/games/${i(n.gameId())}/game-rooms/${i(e)}/room-args`;return n.client.put(o,t,r?.signal)}async function ut(n,e,t,r,o){let a=`/v1/showcase/players/${i(e)}/${i(t)}`;return n.client.put(a,r,o?.signal)}async function ct(n,e,t){let r=`/v1/inventory/transfers/${i(e)}/reject`;return n.client.post(r,void 0,t?.signal)}async function mt(n,e,t,r){let o=`/v1/games/${i(n.gameId())}/matches/${i(e)}/players/report`;return n.client.post(o,t,r?.signal)}async function gt(n,e,t,r,o,a){let s=`/v1/saves/${i(e)}/${i(t)}/${i(r)}/upload-url`;return n.client.post(s,o,a?.signal,{replaySafe:true})}async function pt(n,e,t,r,o,a){let s=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/reset`;return n.client.post(s,o,a?.signal)}async function yt(n,e,t,r){let o=`/v1/games/${i(n.gameId())}/matches/${i(e)}/backfill`;return n.client.put(o,t,r?.signal)}async function ft(n,e,t,r,o){let a=`/v1/inventory/${i(e)}/${i(t)}/orders/simulate`;return n.client.post(a,r,o?.signal)}async function ht(n,e,t,r){let o=`/v2/games/${i(n.gameId())}/game-rooms/${i(e)}/transfer/${i(t)}`;return n.client.post(o,void 0,r?.signal)}async function _t(n,e,t,r){let o=`/v2/games/${i(n.gameId())}/game-rooms/${i(e)}`;return n.client.patch(o,t,r?.signal,{...r?.ifMatch===void 0?{}:{ifMatch:r.ifMatch}})}var ce="gem_";function me(n,e){let t=e?.retryAfterSeconds,r=typeof t=="number"&&Number.isFinite(t)&&t>0?t*1e3:0,o=1e4*2**Math.min(Math.max(0,n-1),16);return Math.min(Math.max(r,o),3e5)}var Rt=1e4,xt=50,kt=1e3,St=65536-4*1024,ge=n=>typeof n=="number"?n:0,wt=n=>typeof n=="string"?n:"";function pe(){let n=globalThis.crypto;return typeof n?.randomUUID=="function"?n.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.floor(Math.random()*16);return (e==="x"?t:t&3|8).toString(16)})}function At(n){return n?.retryable===true}function Pt(n,e){let t=n??{},r=Array.isArray(t.rejected)?t.rejected.map(o=>{let a=o??{};return {index:ge(a.index),code:wt(a.code)}}):[];return {accepted:ge(t.accepted),rejected:r,dropped:e,duplicate:t.duplicate===true}}function ye(n,e){return {event_uid:n.uid,name:n.name,offset_ms:Math.round(n.atMs)-e,player_id:n.playerId,dimensions:n.dimensions,measures:n.measures}}function fe(n){let e=Math.max(1,Math.floor(n.maxQueue??kt)),t={client:n.client,gameId:()=>n.gameId},r=[],o=0,a=null,s=false,l=null,u=0,c=0,g=false,_=false,v=R=>{n.log?.(R);},h=()=>{a!==null&&(n.clock.clearTimeout(a),a=null);},y=()=>Math.max(0,c-n.clock.now()),S=()=>{a!==null||s||l!==null||(a=n.clock.setTimeout(()=>{a=null,O().catch(()=>{});},Math.max(Rt,y())));},A=()=>{let R=Math.min(r.length,100),x=128;for(let T=0;T<R;T+=1){let G=r[T];if(G===void 0)break;if(x+=JSON.stringify(ye(G,0)).length+1,x>St)return Math.max(1,T)}return R};async function O(R){for(;l!==null;)await l.catch(()=>{});if(r.length===0)return {accepted:0,rejected:[],dropped:0,duplicate:false};let x=Ge(R);l=x;try{return await x}finally{l===x&&(l=null),r.length>0&&S();}}async function Ge(R){h();let x=r.splice(0,A()),T=o;o=0;let G=Math.round(n.clock.now()),F={batch_id:pe(),sent_at_ms:G,events:x.map(w=>ye(w,G))};try{let w=await K(t,F,R===void 0?void 0:{signal:R}),C=Pt(w,T);u=0,c=0;for(let Ce of C.rejected)v(`[gem] analytics: an event was refused (${Ce.code}). See the analytics_events section of your game config.`);return C}catch(w){if(At(w)){for(r=[...x,...r],o+=T;r.length>e;)r.shift(),o+=1;u+=1,c=n.clock.now()+me(u,w);}else v(`[gem] analytics: ${x.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(w)}`);throw w}}return {track(R,x,T={}){if(s)return;if(typeof R!="string"||R===""){_||(_=true,v(`[gem] analytics: '${x}' was not recorded \u2014 an event from a server has to name the player it is about. A game-server token names no player, so the platform cannot infer one; pass the id from join() or host.players().`));return}if(x.startsWith(ce)){g||(g=true,v(`[gem] analytics: '${x}' was not recorded \u2014 the gem_ prefix is reserved, and the platform's own events are client-sourced, so a server may not emit one at all. Name your event something else.`));return}let G={},F={};for(let[w,C]of Object.entries(T))typeof C=="string"?G[w]=C:typeof C=="number"&&Number.isFinite(C)&&(F[w]=C);for(;r.length>=e;)r.shift(),o+=1;r.push({uid:pe(),playerId:R,name:x,atMs:n.clock.now(),dimensions:G,measures:F}),r.length>=xt&&l===null&&y()===0?O().catch(()=>{}):S();},flush:R=>O(R),get pending(){return r.length},dispose(){s=true,h(),r=[],o=0;}}}var Ot=new Map([["function_error",false],["function_failed",false],["function_timeout",false],["function_not_published",false],["function_input_too_large",false],["functions_not_configured",false],["forbidden",false],["function_capacity_unavailable",true],["function_host_unreachable",true],["function_host_error",true],["rate_limited",true],["service_unavailable",true]]),$=class extends m{constructor(e,t){super(e.reason,e.status,e.detail,e.retryAfterSeconds,e.code),this.name="GemFunctionError",Object.assign(this,t);}get retryable(){return (this.code===void 0?void 0:Ot.get(this.code))??super.retryable}},L=class{#e;constructor(e){this.#e=e;}async invoke(e,t={}){let r=Tt(e),o;try{o=await this.#e(r,t.signal===void 0?{}:{signal:t.signal});}catch(a){throw a instanceof m?Ct(a):a}return Gt(o)}};function Tt(n){if(n instanceof ArrayBuffer)return new Uint8Array(n);if(ArrayBuffer.isView(n))return new Uint8Array(n.buffer,n.byteOffset,n.byteLength);let e;try{e=JSON.stringify(n);}catch(t){throw new f(`the function input could not be serialised to JSON: ${String(t)}. Pass bytes, or a value JSON can carry. This is a bug in the call, not a server failure.`)}if(e===void 0)throw new f(`the function input is ${typeof n}, which JSON cannot carry. Pass bytes \u2014 an empty Uint8Array for no input \u2014 or a JSON value. This is a bug in the call, not a server failure.`);return new TextEncoder().encode(e)}function Gt(n){let{bytes:e}=n,t=()=>new TextDecoder("utf-8",{fatal:true}).decode(e);return {bytes:e,...n.invocationId===void 0?{}:{invocationId:n.invocationId},text:t,json:()=>JSON.parse(t())}}function Ct(n){let{details:e,invocationId:t}=te(n),o=e?.untrusted?.message,a=e?.reason;return new $(n,{...t===void 0?{}:{invocationId:t},...n.code==="function_error"&&typeof o=="string"?{functionMessage:o}:{},...n.code==="function_failed"&&typeof a=="string"?{failure:a}:{}})}var P=n=>typeof n=="string"?n:"",Et=/(?:Z|[+-]\d{2}:?\d{2})$/i;function he(n){let e=P(n);if(!Et.test(e))return 0;let t=Date.parse(e);return Number.isFinite(t)?Math.floor(t/1e3):0}var It=/^[0-9a-f]{1,64}$/,Mt=/^[0-9a-f]{16}$/,Lt=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,qt=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function $t(n){let e=P(n),t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!t)return;let[r,o,a]=[Number(t[1]),Number(t[2]),Number(t[3])],s=new Date(Date.UTC(r,o-1,a));return s.getUTCFullYear()===r&&s.getUTCMonth()===o-1&&s.getUTCDate()===a?e:void 0}var jt=4096,Ft=new TextEncoder;function Bt(n){let e=P(n.challenge_data),t=P(n.challenge_data_hash);return e===""||!Mt.test(t)?{}:Ft.encode(e).length>jt?{}:{data:e,dataHash:t}}function Ut(n){let e=n??{},t=he(e.period_start_at),r=he(e.period_ends_at);if(t===0||r===0)return;let o=P(e.slug),a=P(e.seed),s=$t(e.period_local_date),l=P(e.boundary),u=P(e.reset_time);return {id:P(e.progression_definition_id),...o===""?{}:{slug:o},window:P(e.window),periodStartAt:t,periodEndsAt:r,...s===void 0?{}:{periodLocalDate:s},boundary:Lt.test(l)?l:"",resetTime:qt.test(u)?u:"",seed:It.test(a)?a:"",...Bt(e)}}function _e(n){if(n!==void 0&&(!Number.isInteger(n)||n<0||n>400))throw new TypeError(`periodsBack must be an integer between 0 and 400, got ${String(n)}`)}function be(n){let e=n??{};return Array.isArray(e.challenges)?e.challenges.map(Ut).filter(t=>t!==void 0):[]}function ve(n){return {async list(e){let{playerId:t,periodsBack:r,signal:o}=e??{};if(typeof t!="string"||t==="")throw new TypeError("gem.challenges.list needs { playerId }: a game-server token names no player, so the platform cannot tell whose period you mean. Pass the id from join() or gem.players().");_e(r);let a=await n({player_id:t,...r===void 0?{}:{periods_back:r},...o===void 0?{}:{signal:o}});return be(a)}}}function Nt(n){let e={};for(let[t,r]of Object.entries(Y))if(typeof r=="function"){let o=r;e[t]=(...a)=>o(n,...a);}return e}function H(n,e={}){let t=e.clock??M,r=e.baseUrl??n.apiBaseUrl;if(!r)throw new Error("this runtime names no gem-api host (host.apiBaseUrl is missing). The server image running this bundle predates token delivery \u2014 the bundle cannot call gem-api on it.");let o=z(n,{clock:t,...e.onAuthStateChange===void 0?{}:{onStateChange:e.onAuthStateChange}}),a=re({baseUrl:r,tokenSource:o.source,defaultQuery:{game_id:n.gameId,channel:n.channel},...e.fetch===void 0?{}:{fetch:e.fetch}}),s=new E({transport:a,clock:t}),l={gameId:n.gameId,channel:n.channel,matchId:n.matchId,...n.gameRoomId===void 0?{}:{gameRoomId:n.gameRoomId}},u=Nt({client:s,gameId:()=>l.gameId}),c=l.gameRoomId,g=n.endMatch,_=n.log,v=fe({client:s,clock:t,gameId:l.gameId,...typeof _=="function"?{log:y=>_.call(n,y)}:{}});return {identity:l,client:s,api:u,match:{end:async()=>{if(g===void 0)throw new Error("this runtime cannot end the match: the server image running this bundle predates host.endMatch, and only the platform half holds the allocation proof an end needs.");await g.call(n);},setBackfill:async(y,S)=>{let A=await u.setMatchBackfill(l.matchId,{open:y.open,...y.seats===void 0?{}:{seats:y.seats}},S===void 0?{}:{signal:S});return {open:A.open,seats:A.seats??null}},reportPlayers:async(y,S)=>(await u.reportMatchPlayers(l.matchId,{players:y.map(O=>({player_id:O.playerId,state:O.state}))},S===void 0?{}:{signal:S})).players.map(O=>({playerId:O.player_id,outcome:O.outcome}))},analytics:v,functions:new L(u.invokeFunction),challenges:ve(u.listChallenges),...c===void 0?{}:{room:{get:y=>u.getGameRoomV2(c,y),args:async y=>{let S=await u.getGameRoomV2(c,y?.signal===void 0?{}:{signal:y.signal}),A=S.modified?S.body:void 0;if(A?.room_args==null||A.room_args_template==null)throw new m("not_found",404,"this room's template declares no room args",void 0,"room_args_not_defined");return {room_args:A.room_args,room_args_template:A.room_args_template}}}},dispose:()=>{v.dispose(),o.dispose();}}}var Dt=["explicit","stale_cleanup","game_room_closed","replaced","migration_failed","host_left","insufficient_players","all_left","expired","migration_rate_exceeded","game_room_gone","failed","idle","reclaimed"],Ht=new Set(Dt);function Re(n){return typeof n=="string"&&Ht.has(n)?n:"unknown"}var Se="[gem: use gem.text.toPlain()]",xe=new Set,ke;function Vt(n){try{if(xe.has(n))return;let e=globalThis.location;if(ke??=!!e?.port&&de(e.hostname??""),!ke)return;xe.add(n),console.warn(`[gem] ${n} is PlayerText, turned into a string: players see ${Se}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
2
+ ${new Error().stack}`);}catch{}}var k=class{#e;#n;constructor(e,t="player text"){this.#e=e,this.#n=t,Object.freeze(this);}toString(){return Vt(this.#n),Se}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function j(n,e){return new k(n,e)}var we={toPlain(n){return k.unwrap(n)},compare(n,e,t){let r=n instanceof k?k.unwrap(n):n,o=e instanceof k?k.unwrap(e):e;if(typeof Intl>"u"||typeof Intl.Collator!="function")return r<o?-1:r>o?1:0;let a;try{a=new Intl.Collator(t);}catch{a=new Intl.Collator;}return a.compare(r,o)},equals(n,e){let t=n instanceof k?k.unwrap(n):n,r=e instanceof k?k.unwrap(e):e;return t.normalize("NFC")===r.normalize("NFC")}};var Ae="the match has not started yet: the runtime hands over the host at `init`, and this was read before that. Read it from `init` or later \u2014 a bundle that needs a value at module scope is reading it one call too early.";function J(n,e={}){let t=e.clock??M,r=()=>{let l=n();if(l===null)throw new Error(Ae);return l},o=null,a=()=>{if(o===null)throw new Error(Ae);return o};return {server:{get identity(){return a().identity},get client(){return a().client},get api(){return a().api},get match(){return a().match},get analytics(){return a().analytics},get functions(){return a().functions},get challenges(){return a().challenges},get room(){return a().room},dispose(){o?.dispose();},get sizeClass(){return r().sizeClass},get roomArgs(){return r().roomArgs},get roster(){return r().roster},players(){return r().players()},profile(l){let c=r().profile?.(l);if(!c)return null;let g=c.displayName;return typeof g!="string"||g===""?null:{displayName:j(g,"profile.displayName"),...typeof c.displayTag=="string"&&c.displayTag!==""?{displayTag:j(c.displayTag,"profile.displayTag")}:{},...typeof c.discriminator=="string"?{discriminator:c.discriminator}:{}}},playerNumber(l){return r().playerNumber?.(l)},send(l,u,c){c===void 0?r().send(l,u):r().send(l,u,c);},broadcast(l,u){u===void 0?r().broadcast(l):r().broadcast(l,u);},kick(l,u){u===void 0?r().kick(l):r().kick(l,u);},log(l){r().log(l);},warn(l){r().warn(l);}},attach:()=>{o=H(r(),{...e,clock:t});}}}function Pe(n,e={}){let{server:t,attach:r}=J(()=>n,e);return r(),t}function Wt(n){if(n===void 0||typeof n.reason!="string"||n.reason==="")return;let e=n.platform_reason??n.endedReason;return {reason:n.reason,...e===void 0?{}:{endedReason:Re(e)}}}var zt=1e4;function Kt(n){let e=false;return t=>{if(e)return;let r;try{r=n.match.reportPlayers([{playerId:t,state:"connected"}],AbortSignal.timeout(zt));}catch{return}r.catch(o=>{o instanceof m&&o.status>=400&&o.status<500&&(e=o.status!==429);});}}function Oe(n,e={}){return ()=>{let t=null,{server:r,attach:o}=J(()=>t,e),a=n(r),s={async init(u){t=u,o(),await a.init?.();},async shutdown(u){let c=Wt(u);try{await a.shutdown?.(c);}finally{r.dispose();}}},l=Kt(r);return s.join=(u,c)=>(l(u),a.join?.(u,c)),a.leave&&(s.leave=(u,c)=>a.leave?.(u,c)),a.message&&(s.message=(u,c,g,_)=>a.message?.(u,c,g,_)),s}}var Yt=new Set(["unlocked","already_unlocked","suppressed"]);function Te(n){let e=n?.changes;if(!Array.isArray(e))return [];let t=[];for(let r of e){let o=r??{};if(o.type!=="achievement_unlocked"||typeof o.outcome!="string"||!Yt.has(o.outcome)||typeof o.achievement_id!="string"||o.achievement_id==="")continue;let a=o.outcome;t.push({achievementId:o.achievement_id,progressionDefinitionId:typeof o.progression_definition_id=="string"?o.progression_definition_id:"",points:a==="unlocked"&&typeof o.points=="number"&&Number.isFinite(o.points)?o.points:0,outcome:a,...typeof o.reason=="string"?{reason:o.reason}:{}});}return t}export{b as AuthError,U as CONDITIONAL_HEADERS,L as FunctionsApi,m as GemApiError,E as GemClient,$ as GemFunctionError,k as PlayerText,f as TransportRefusal,Te as achievementReceipts,j as asPlayerText,H as createGemServer,ue as createHostTokenSource,Pe as createMatchServer,Oe as defineServer,M as systemClock,we as text,Z as toBase64};//# sourceMappingURL=gem-web-sdk.server.js.map
3
3
  //# sourceMappingURL=gem-web-sdk.server.js.map
package/dist/index.d.ts CHANGED
@@ -37,6 +37,7 @@ declare const PARENT_TO_FRAME: readonly [
37
37
  "gem.localServer",
38
38
  "gem.localServer.denied",
39
39
  "gem.menuSelect",
40
+ "gem.settingChange",
40
41
  "gem.error",
41
42
  "gem.purchaseResult",
42
43
  "gem.deviceSettings.result",
@@ -66,6 +67,7 @@ declare const FRAME_TO_PARENT: readonly [
66
67
  "gem.controlsDeclare",
67
68
  "gem.menu",
68
69
  "gem.gemCorner",
70
+ "gem.settingsDeclare",
69
71
  "gem.requestShare",
70
72
  "gem.requestAvatarPicker",
71
73
  "gem.vibrate",
@@ -80,7 +82,7 @@ declare const FRAME_TO_PARENT: readonly [
80
82
  "gem.requestSignIn",
81
83
  "gem.requestFriendChallenge"
82
84
  ];
83
- type GemCapability = "ads" | "signIn" | "purchases" | "avatar3dPurchases" | "friendChallenges" | "devtools" | "screenshot" | "feedbackContext" | "rooms" | "p2p" | "dedicated" | "clusterTarget" | "parties" | "autoStartFailure" | "ticketEvents" | "partySeating" | "socketState" | "audioState" | "rewardCue" | "frameStats" | "portraitBorders" | "engagement" | "viewport" | "reservedAreas" | "walletDisplay" | "localHost" | "cohorts" | "earnAllowance" | "deviceSettings" | "asyncOpponents" | "share" | "avatarPicker" | "vibration" | "gameMenu" | "controls" | "gemCorner" | "moments";
85
+ type GemCapability = "ads" | "signIn" | "purchases" | "avatar3dPurchases" | "friendChallenges" | "devtools" | "screenshot" | "feedbackContext" | "rooms" | "p2p" | "dedicated" | "clusterTarget" | "parties" | "autoStartFailure" | "ticketEvents" | "partySeating" | "socketState" | "audioState" | "rewardCue" | "frameStats" | "portraitBorders" | "engagement" | "viewport" | "reservedAreas" | "walletDisplay" | "localHost" | "cohorts" | "earnAllowance" | "deviceSettings" | "asyncOpponents" | "share" | "avatarPicker" | "vibration" | "gameMenu" | "controls" | "gemCorner" | "gameSettings" | "moments";
84
86
  declare const CAPABILITY_GATES: Readonly<Record<string, string>>;
85
87
  declare const CAPABILITY_NAMESPACE_GATES: ReadonlyArray<readonly [
86
88
  string,
@@ -455,6 +457,31 @@ interface GemGemCorner {
455
457
  readonly type: "gem.gemCorner";
456
458
  readonly corner: "top-left" | "top-right" | "bottom-left" | "bottom-right";
457
459
  }
460
+ interface GemSettingsDeclare {
461
+ readonly gem: typeof PROTOCOL;
462
+ readonly type: "gem.settingsDeclare";
463
+ readonly settings: {
464
+ id: string;
465
+ label: string;
466
+ kind: "toggle" | "slider" | "choice";
467
+ value: boolean | number | string;
468
+ quick?: boolean;
469
+ icon?: string;
470
+ min?: number;
471
+ max?: number;
472
+ step?: number;
473
+ options?: {
474
+ id: string;
475
+ label: string;
476
+ }[];
477
+ }[];
478
+ }
479
+ interface GemSettingChange {
480
+ readonly gem: typeof PROTOCOL;
481
+ readonly type: "gem.settingChange";
482
+ readonly id: string;
483
+ readonly value: boolean | number | string;
484
+ }
458
485
  interface GemRequestShare {
459
486
  readonly gem: typeof PROTOCOL;
460
487
  readonly type: "gem.requestShare";
@@ -585,8 +612,8 @@ interface GemFriendChallengeResult {
585
612
  readonly retryAfterMs?: number;
586
613
  readonly detail?: string;
587
614
  }
588
- type ParentMessage = GemHandshake | GemToken | GemTokenDenied | GemPlayer | GemPause | GemPrefs | GemCohorts | GemEarnAllowanceChanged | GemViewport | GemDeviceSettings | GemWillTerminate | GemRoomEvent | GemSocketState | GemSeatedEvent | GemAutoStartFailedEvent | GemTicketEvent | GemSignalEvent | GemDedicatedEvent | GemPartyResult | GemClusterTarget | GemDevtools | GemScreenshot | GemRequestContext | GemLocalServer | GemLocalServerDenied | GemMenuSelect | GemError | GemPurchaseResult | GemDeviceSettingsResult | GemAdResult | GemMomentResult | GemSignInResult | GemFriendChallengeResult;
589
- type FrameMessage = GemHandshakeAccept | GemScreenshotDenied | GemGameContext | GemSignal | GemDedicatedOffer | GemPartyRequest | GemReady | GemEngaged | GemProgress | GemRequestToken | GemRequestLocalServer | GemExit | GemOpenExternal | GemRequestFullscreen | GemAudioState | GemRewardCue | GemWalletDisplay | GemControlsDeclare | GemMenu | GemGemCorner | GemRequestShare | GemRequestAvatarPicker | GemVibrate | GemFrameStats | GemPortraitBorders | GemError | GemRequestPurchase | GemRequestAvatar3dPurchase | GemDeviceSettingsPut | GemRequestAd | GemSignalMoment | GemRequestSignIn | GemRequestFriendChallenge;
615
+ type ParentMessage = GemHandshake | GemToken | GemTokenDenied | GemPlayer | GemPause | GemPrefs | GemCohorts | GemEarnAllowanceChanged | GemViewport | GemDeviceSettings | GemWillTerminate | GemRoomEvent | GemSocketState | GemSeatedEvent | GemAutoStartFailedEvent | GemTicketEvent | GemSignalEvent | GemDedicatedEvent | GemPartyResult | GemClusterTarget | GemDevtools | GemScreenshot | GemRequestContext | GemLocalServer | GemLocalServerDenied | GemMenuSelect | GemSettingChange | GemError | GemPurchaseResult | GemDeviceSettingsResult | GemAdResult | GemMomentResult | GemSignInResult | GemFriendChallengeResult;
616
+ type FrameMessage = GemHandshakeAccept | GemScreenshotDenied | GemGameContext | GemSignal | GemDedicatedOffer | GemPartyRequest | GemReady | GemEngaged | GemProgress | GemRequestToken | GemRequestLocalServer | GemExit | GemOpenExternal | GemRequestFullscreen | GemAudioState | GemRewardCue | GemWalletDisplay | GemControlsDeclare | GemMenu | GemGemCorner | GemSettingsDeclare | GemRequestShare | GemRequestAvatarPicker | GemVibrate | GemFrameStats | GemPortraitBorders | GemError | GemRequestPurchase | GemRequestAvatar3dPurchase | GemDeviceSettingsPut | GemRequestAd | GemSignalMoment | GemRequestSignIn | GemRequestFriendChallenge;
590
617
  type GemMessage = ParentMessage | FrameMessage;
591
618
  type Rejection = string | null;
592
619
  declare function isOrigin(s: string): boolean;
@@ -637,6 +664,8 @@ declare const validateGemControlsDeclare: (raw: unknown) => Rejection;
637
664
  declare const validateGemMenu: (raw: unknown) => Rejection;
638
665
  declare const validateGemMenuSelect: (raw: unknown) => Rejection;
639
666
  declare const validateGemGemCorner: (raw: unknown) => Rejection;
667
+ declare const validateGemSettingsDeclare: (raw: unknown) => Rejection;
668
+ declare const validateGemSettingChange: (raw: unknown) => Rejection;
640
669
  declare const validateGemRequestShare: (raw: unknown) => Rejection;
641
670
  declare const validateGemRequestAvatarPicker: (raw: unknown) => Rejection;
642
671
  declare const validateGemVibrate: (raw: unknown) => Rejection;
@@ -836,6 +865,7 @@ interface HostCallbacks {
836
865
  onWalletDisplay?(msg: GemWalletDisplay): void;
837
866
  onMenu?(msg: GemMenu): void;
838
867
  onGemCorner?(msg: GemGemCorner): void;
868
+ onSettingsDeclare?(msg: GemSettingsDeclare): void;
839
869
  onFrameStats?(msg: GemFrameStats): void;
840
870
  onPortraitBorders?(name: string | null): void;
841
871
  onScreenshotDenied?(msg: GemScreenshotDenied): void;
@@ -885,6 +915,7 @@ declare class GemHost {
885
915
  private prefsCalls;
886
916
  private readonly knownMatches;
887
917
  private readonly askedMatches;
918
+ private declaredSettings;
888
919
  private readonly clock;
889
920
  private readonly inbound;
890
921
  private readonly outbound;
@@ -939,6 +970,7 @@ declare class GemHost {
939
970
  sendMenuSelect(choice: "settings" | {
940
971
  readonly id: string;
941
972
  }): boolean;
973
+ sendSettingChange(id: string, value: boolean | number | string): boolean;
942
974
  answerAd(requestId: string, outcome: "shown" | "no_ad" | "unavailable"): boolean;
943
975
  answerMoment(requestId: string, shown: boolean): boolean;
944
976
  answerSignIn(requestId: string, outcome: "signed_in" | "declined" | "unavailable"): boolean;
@@ -1112,6 +1144,7 @@ interface FrameCallbacks {
1112
1144
  onToken?(msg: GemToken): void;
1113
1145
  onPause?(msg: GemPause): void;
1114
1146
  onMenuSelect?(msg: GemMenuSelect): void;
1147
+ onSettingChange?(msg: GemSettingChange): void;
1115
1148
  onPrefs?(msg: GemPrefs): void;
1116
1149
  onCohorts?(msg: GemCohorts): void;
1117
1150
  onEarnAllowanceChanged?(): void;
@@ -1196,6 +1229,7 @@ declare class GemFrame {
1196
1229
  readonly id: string;
1197
1230
  readonly label: string;
1198
1231
  }>): boolean;
1232
+ declareSettings(settings: GemSettingsDeclare["settings"]): boolean;
1199
1233
  setGemCorner(corner: GemCorner): boolean;
1200
1234
  requestShare(params: ReadonlyArray<{
1201
1235
  readonly key: string;
@@ -2475,4 +2509,4 @@ interface P2pMatchApi {
2475
2509
  session(matchId: string): P2pSession | null;
2476
2510
  }
2477
2511
  declare function createP2pApi(options: P2pApiOptions): P2pMatchApi;
2478
- export { type AutoReconnectOptions, type AwaitMatchOptions, CAPABILITY_GATES, CAPABILITY_NAMESPACE_GATES, CHANNELS, CHANNEL_KINDS, type ChannelKind, type ClientPlatform, ClientTelemetry, type ClientTelemetryOptions, type ClientVersion, type Clock, type ClusterTarget, type ClusterTargetBridge, type ClusterTargetLike, type ClusterTargetListResolver, type ClusterTargetRefresher, type ClusterTargetResolver, type ClusterTargetSource, type ClusterTargetSourceOptions, type ConnectOptions, type CreateRoomOptions, INBOUND_EVENTS as DEDICATED_INBOUND_EVENTS, DEFAULT_WELCOME_CEILING_MS, DEVICE_SETTINGS_MAX_BYTES, type DataChannelLike$1 as DataChannelLike, type DedicatedServerApi, type DedicatedServerApiOptions, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DedicatedSignalTransport, DedicatedSignalingHub, type DedicatedSignalingOptions, type EstablishOptions, FRAME_TO_PARENT, type FailedMatch, type FrameCallbacks, type FrameMessage, type FrameOptions, type FrameState, type GemAdResult, type GemAudioState, type GemAutoStartFailedEvent, type GemCapability, type GemClusterTarget, type GemCohorts, type GemControlsDeclare, type GemDedicatedEvent, type GemDedicatedOffer, type GemDeviceSettings, type GemDeviceSettingsPut, type GemDeviceSettingsResult, type GemDevtools, type GemEarnAllowanceChanged, type GemEngaged, type GemError, type GemErrorCode, type GemExit, GemFrame, type GemFrameStats, type GemFriendChallengeResult, type GemGameContext, type GemGemCorner, type GemHandshake, type GemHandshakeAccept, GemHost, type GemLocalServer, type GemLocalServerDenied, type GemMenu, type GemMenuSelect, type GemMessage, type GemMomentResult, type GemOpenExternal, type GemPartyRequest, type GemPartyResult, type GemPause, type GemPlayer, type GemPortraitBorders, type GemPrefs, type GemProgress, type GemPurchaseResult, type GemReady, type GemRequestAd, type GemRequestAvatar3dPurchase, type GemRequestAvatarPicker, type GemRequestContext, type GemRequestFriendChallenge, type GemRequestFullscreen, type GemRequestLocalServer, type GemRequestPurchase, type GemRequestShare, type GemRequestSignIn, type GemRequestToken, type GemRewardCue, type GemRoomEvent, type GemScreenshot, type GemScreenshotDenied, type GemSeatedEvent, type GemSignInResult, type GemSignal, type GemSignalEvent, type GemSignalMoment, type GemSocketState, type GemTicketEvent, type GemToken, type GemTokenDenied, type GemVibrate, type GemViewport, type GemWalletDisplay, type GemWillTerminate, HANDSHAKE_TIMEOUT_MS, type HandshakeEvent, type HostCallbacks, HostMigration, type HostOptions, type HostState, type JoinCredential, type JoinExchange, type JoinRoomOptions, type JoinWelcome, type KeySource, type ListRoomsOptions, MALFORMED_INBOUND_KEY, MAX_ARRAY_LENGTH, MAX_CLUSTER_TARGETS, MAX_MESSAGE_BYTES, MAX_MESSAGE_DEPTH, MAX_MESSAGE_NODES, MAX_SIGNALS_PER_SECOND, MAX_SOCKET_FRAME_BYTES, MIGRATION_TIMEOUT_MS, type MatchAutoStartFailed, type MatchConnectionState, type MatchEnded, type MatchOutcome, type MatchOutcomeWaitOptions, type MatchReconnected, type MatchReconnecting, type MatchSession, type MatchSessionPhase, type MatchSuspended, type MatchTicket, type MatchTicketOutcome, type MatchTicketStatus, type MigrationState, type OfferRefusal, type OfferRequest, P2pApi, type P2pConnectOptions, P2pError, type P2pEventMap, type P2pEventName, type P2pFailure, type P2pMatchApi, type P2pPeer, P2pSession, PARENT_TO_FRAME, PROTOCOL, type ParentMessage, type PartyBridge, type PartyEventRelay, type PartyResolver, type PartyResolverOptions, type PartyTicket, type PartyTicketOutcome, type PartyTicketStatus, type PeerConnectionLike$1 as PeerConnectionLike, type PlayWithOutcome, PlayerText, type PortLike, type PortMessageHandler, type PresentCredentialOptions, type PurchaseRefusalCode, type QueueForMatchOptions, type QuickJoinOptions, RATE_LIMITS, RateLimiter, type ReadyMatch, type Rejection, type RelayedDedicatedEvent, type RelayedRoomEvent, type RelayedSignal, type RelayedTicketEvent, type ResolvedClientVersion, type Room, type RoomArgEntry, type RoomArgScalar, type RoomArgType, type RoomArgValue, type RoomArgs, RoomEmitter, type RoomEventMap, type RoomEventName, type RoomManager, type RoomManagerOptions, type RoomMember, type RoomOperationError, type RoomPage, type RoomStatus, type RoomSummary, RoomsApi, type RoomsApiOptions, SUPPORTED_VERSIONS, type SdpType$1 as SdpType, type SendPlayerInput, type SessionDescriptionLike$1 as SessionDescriptionLike, type SignalTransport, type SignalingAnswer, type SignalingChannel, SignalingClient, type SignalingIntent, type StartMatchOptions, type StartedMatch$1 as StartedMatch, TELEMETRY_EVENTS, TRANSPORT_LABELS, type TelemetrySample, type TokenDenial, type TokenGrant, type TransportLabel, type TurnLease, type UpdateRoomOptions, VALIDATORS, type VerifiedCredential, WEBRTC_DEDICATED, WEBRTC_P2P, WEB_ENGINE_VERSION, WEB_PROTOCOL_VERSION, type WindowLike, asPlayerText, awaitMatchOutcome, browserPeerConnection, buildDedicatedOfferFrame, buildSocketFrame, capabilityFor, createClusterTargetSource, createDedicatedServerApi, createKeySource, createP2pApi, createPartyResolver, createRoomManager, deviceSettingsByteLength, establishDataChannel, fingerprintOf, fingerprintsMatch, generateCertificate, isOrigin, listClusterTargets, memberFromWire, negotiateVersion, normaliseClusterTarget, normaliseClusterTargets, normaliseFingerprint, originsEqual, presentJoinCredential, projectDedicatedEvent, projectPartyEvent, projectSignal, roomArgValuesFromWire, roomArgsTemplateFromWire, roomFromWire, startMatch, summaryFromWire, systemClock, text, unavailableSignaling, validateGemAdResult, validateGemAudioState, validateGemAutoStartFailedEvent, validateGemClusterTarget, validateGemCohorts, validateGemControlsDeclare, validateGemDedicatedEvent, validateGemDedicatedOffer, validateGemDeviceSettings, validateGemDeviceSettingsPut, validateGemDeviceSettingsResult, validateGemDevtools, validateGemEarnAllowanceChanged, validateGemEngaged, validateGemError, validateGemExit, validateGemFrameStats, validateGemFriendChallengeResult, validateGemGameContext, validateGemGemCorner, validateGemHandshake, validateGemHandshakeAccept, validateGemLocalServer, validateGemLocalServerDenied, validateGemMenu, validateGemMenuSelect, validateGemMomentResult, validateGemOpenExternal, validateGemPartyRequest, validateGemPartyResult, validateGemPause, validateGemPlayer, validateGemPortraitBorders, validateGemPrefs, validateGemProgress, validateGemPurchaseResult, validateGemReady, validateGemRequestAd, validateGemRequestAvatar3dPurchase, validateGemRequestAvatarPicker, validateGemRequestContext, validateGemRequestFriendChallenge, validateGemRequestFullscreen, validateGemRequestLocalServer, validateGemRequestPurchase, validateGemRequestShare, validateGemRequestSignIn, validateGemRequestToken, validateGemRewardCue, validateGemRoomEvent, validateGemScreenshot, validateGemScreenshotDenied, validateGemSeatedEvent, validateGemSignInResult, validateGemSignal, validateGemSignalEvent, validateGemSignalMoment, validateGemSocketState, validateGemTicketEvent, validateGemToken, validateGemTokenDenied, validateGemVibrate, validateGemViewport, validateGemWalletDisplay, validateGemWillTerminate, validateSize, verifyCredential };
2512
+ export { type AutoReconnectOptions, type AwaitMatchOptions, CAPABILITY_GATES, CAPABILITY_NAMESPACE_GATES, CHANNELS, CHANNEL_KINDS, type ChannelKind, type ClientPlatform, ClientTelemetry, type ClientTelemetryOptions, type ClientVersion, type Clock, type ClusterTarget, type ClusterTargetBridge, type ClusterTargetLike, type ClusterTargetListResolver, type ClusterTargetRefresher, type ClusterTargetResolver, type ClusterTargetSource, type ClusterTargetSourceOptions, type ConnectOptions, type CreateRoomOptions, INBOUND_EVENTS as DEDICATED_INBOUND_EVENTS, DEFAULT_WELCOME_CEILING_MS, DEVICE_SETTINGS_MAX_BYTES, type DataChannelLike$1 as DataChannelLike, type DedicatedServerApi, type DedicatedServerApiOptions, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DedicatedSignalTransport, DedicatedSignalingHub, type DedicatedSignalingOptions, type EstablishOptions, FRAME_TO_PARENT, type FailedMatch, type FrameCallbacks, type FrameMessage, type FrameOptions, type FrameState, type GemAdResult, type GemAudioState, type GemAutoStartFailedEvent, type GemCapability, type GemClusterTarget, type GemCohorts, type GemControlsDeclare, type GemDedicatedEvent, type GemDedicatedOffer, type GemDeviceSettings, type GemDeviceSettingsPut, type GemDeviceSettingsResult, type GemDevtools, type GemEarnAllowanceChanged, type GemEngaged, type GemError, type GemErrorCode, type GemExit, GemFrame, type GemFrameStats, type GemFriendChallengeResult, type GemGameContext, type GemGemCorner, type GemHandshake, type GemHandshakeAccept, GemHost, type GemLocalServer, type GemLocalServerDenied, type GemMenu, type GemMenuSelect, type GemMessage, type GemMomentResult, type GemOpenExternal, type GemPartyRequest, type GemPartyResult, type GemPause, type GemPlayer, type GemPortraitBorders, type GemPrefs, type GemProgress, type GemPurchaseResult, type GemReady, type GemRequestAd, type GemRequestAvatar3dPurchase, type GemRequestAvatarPicker, type GemRequestContext, type GemRequestFriendChallenge, type GemRequestFullscreen, type GemRequestLocalServer, type GemRequestPurchase, type GemRequestShare, type GemRequestSignIn, type GemRequestToken, type GemRewardCue, type GemRoomEvent, type GemScreenshot, type GemScreenshotDenied, type GemSeatedEvent, type GemSettingChange, type GemSettingsDeclare, type GemSignInResult, type GemSignal, type GemSignalEvent, type GemSignalMoment, type GemSocketState, type GemTicketEvent, type GemToken, type GemTokenDenied, type GemVibrate, type GemViewport, type GemWalletDisplay, type GemWillTerminate, HANDSHAKE_TIMEOUT_MS, type HandshakeEvent, type HostCallbacks, HostMigration, type HostOptions, type HostState, type JoinCredential, type JoinExchange, type JoinRoomOptions, type JoinWelcome, type KeySource, type ListRoomsOptions, MALFORMED_INBOUND_KEY, MAX_ARRAY_LENGTH, MAX_CLUSTER_TARGETS, MAX_MESSAGE_BYTES, MAX_MESSAGE_DEPTH, MAX_MESSAGE_NODES, MAX_SIGNALS_PER_SECOND, MAX_SOCKET_FRAME_BYTES, MIGRATION_TIMEOUT_MS, type MatchAutoStartFailed, type MatchConnectionState, type MatchEnded, type MatchOutcome, type MatchOutcomeWaitOptions, type MatchReconnected, type MatchReconnecting, type MatchSession, type MatchSessionPhase, type MatchSuspended, type MatchTicket, type MatchTicketOutcome, type MatchTicketStatus, type MigrationState, type OfferRefusal, type OfferRequest, P2pApi, type P2pConnectOptions, P2pError, type P2pEventMap, type P2pEventName, type P2pFailure, type P2pMatchApi, type P2pPeer, P2pSession, PARENT_TO_FRAME, PROTOCOL, type ParentMessage, type PartyBridge, type PartyEventRelay, type PartyResolver, type PartyResolverOptions, type PartyTicket, type PartyTicketOutcome, type PartyTicketStatus, type PeerConnectionLike$1 as PeerConnectionLike, type PlayWithOutcome, PlayerText, type PortLike, type PortMessageHandler, type PresentCredentialOptions, type PurchaseRefusalCode, type QueueForMatchOptions, type QuickJoinOptions, RATE_LIMITS, RateLimiter, type ReadyMatch, type Rejection, type RelayedDedicatedEvent, type RelayedRoomEvent, type RelayedSignal, type RelayedTicketEvent, type ResolvedClientVersion, type Room, type RoomArgEntry, type RoomArgScalar, type RoomArgType, type RoomArgValue, type RoomArgs, RoomEmitter, type RoomEventMap, type RoomEventName, type RoomManager, type RoomManagerOptions, type RoomMember, type RoomOperationError, type RoomPage, type RoomStatus, type RoomSummary, RoomsApi, type RoomsApiOptions, SUPPORTED_VERSIONS, type SdpType$1 as SdpType, type SendPlayerInput, type SessionDescriptionLike$1 as SessionDescriptionLike, type SignalTransport, type SignalingAnswer, type SignalingChannel, SignalingClient, type SignalingIntent, type StartMatchOptions, type StartedMatch$1 as StartedMatch, TELEMETRY_EVENTS, TRANSPORT_LABELS, type TelemetrySample, type TokenDenial, type TokenGrant, type TransportLabel, type TurnLease, type UpdateRoomOptions, VALIDATORS, type VerifiedCredential, WEBRTC_DEDICATED, WEBRTC_P2P, WEB_ENGINE_VERSION, WEB_PROTOCOL_VERSION, type WindowLike, asPlayerText, awaitMatchOutcome, browserPeerConnection, buildDedicatedOfferFrame, buildSocketFrame, capabilityFor, createClusterTargetSource, createDedicatedServerApi, createKeySource, createP2pApi, createPartyResolver, createRoomManager, deviceSettingsByteLength, establishDataChannel, fingerprintOf, fingerprintsMatch, generateCertificate, isOrigin, listClusterTargets, memberFromWire, negotiateVersion, normaliseClusterTarget, normaliseClusterTargets, normaliseFingerprint, originsEqual, presentJoinCredential, projectDedicatedEvent, projectPartyEvent, projectSignal, roomArgValuesFromWire, roomArgsTemplateFromWire, roomFromWire, startMatch, summaryFromWire, systemClock, text, unavailableSignaling, validateGemAdResult, validateGemAudioState, validateGemAutoStartFailedEvent, validateGemClusterTarget, validateGemCohorts, validateGemControlsDeclare, validateGemDedicatedEvent, validateGemDedicatedOffer, validateGemDeviceSettings, validateGemDeviceSettingsPut, validateGemDeviceSettingsResult, validateGemDevtools, validateGemEarnAllowanceChanged, validateGemEngaged, validateGemError, validateGemExit, validateGemFrameStats, validateGemFriendChallengeResult, validateGemGameContext, validateGemGemCorner, validateGemHandshake, validateGemHandshakeAccept, validateGemLocalServer, validateGemLocalServerDenied, validateGemMenu, validateGemMenuSelect, validateGemMomentResult, validateGemOpenExternal, validateGemPartyRequest, validateGemPartyResult, validateGemPause, validateGemPlayer, validateGemPortraitBorders, validateGemPrefs, validateGemProgress, validateGemPurchaseResult, validateGemReady, validateGemRequestAd, validateGemRequestAvatar3dPurchase, validateGemRequestAvatarPicker, validateGemRequestContext, validateGemRequestFriendChallenge, validateGemRequestFullscreen, validateGemRequestLocalServer, validateGemRequestPurchase, validateGemRequestShare, validateGemRequestSignIn, validateGemRequestToken, validateGemRewardCue, validateGemRoomEvent, validateGemScreenshot, validateGemScreenshotDenied, validateGemSeatedEvent, validateGemSettingChange, validateGemSettingsDeclare, validateGemSignInResult, validateGemSignal, validateGemSignalEvent, validateGemSignalMoment, validateGemSocketState, validateGemTicketEvent, validateGemToken, validateGemTokenDenied, validateGemVibrate, validateGemViewport, validateGemWalletDisplay, validateGemWillTerminate, validateSize, verifyCredential };
package/dist/sdk.d.ts CHANGED
@@ -2254,6 +2254,31 @@ interface GemMenuSelect {
2254
2254
  readonly entry: "settings" | "item";
2255
2255
  readonly id?: string;
2256
2256
  }
2257
+ interface GemSettingsDeclare {
2258
+ readonly gem: typeof PROTOCOL;
2259
+ readonly type: "gem.settingsDeclare";
2260
+ readonly settings: {
2261
+ id: string;
2262
+ label: string;
2263
+ kind: "toggle" | "slider" | "choice";
2264
+ value: boolean | number | string;
2265
+ quick?: boolean;
2266
+ icon?: string;
2267
+ min?: number;
2268
+ max?: number;
2269
+ step?: number;
2270
+ options?: {
2271
+ id: string;
2272
+ label: string;
2273
+ }[];
2274
+ }[];
2275
+ }
2276
+ interface GemSettingChange {
2277
+ readonly gem: typeof PROTOCOL;
2278
+ readonly type: "gem.settingChange";
2279
+ readonly id: string;
2280
+ readonly value: boolean | number | string;
2281
+ }
2257
2282
  interface GemPurchaseResult {
2258
2283
  readonly gem: typeof PROTOCOL;
2259
2284
  readonly type: "gem.purchaseResult";
@@ -4489,6 +4514,7 @@ interface FrameCallbacks {
4489
4514
  onToken?(msg: GemToken): void;
4490
4515
  onPause?(msg: GemPause): void;
4491
4516
  onMenuSelect?(msg: GemMenuSelect): void;
4517
+ onSettingChange?(msg: GemSettingChange): void;
4492
4518
  onPrefs?(msg: GemPrefs$1): void;
4493
4519
  onCohorts?(msg: GemCohorts$1): void;
4494
4520
  onEarnAllowanceChanged?(): void;
@@ -4573,6 +4599,7 @@ declare class GemFrame {
4573
4599
  readonly id: string;
4574
4600
  readonly label: string;
4575
4601
  }>): boolean;
4602
+ declareSettings(settings: GemSettingsDeclare["settings"]): boolean;
4576
4603
  setGemCorner(corner: GemCorner): boolean;
4577
4604
  requestShare(params: ReadonlyArray<{
4578
4605
  readonly key: string;
@@ -4650,6 +4677,43 @@ interface ControlsApi {
4650
4677
  look(options?: GemLookOptions): GemLook;
4651
4678
  readonly LOOK_BASE: GemLookBase;
4652
4679
  }
4680
+ type GemGameSettingIcon = "music" | "sfx" | "voice" | "eye" | "text" | "hint" | "speed" | "bright" | "controls" | "star";
4681
+ type GemGameSettingValue = boolean | number | string;
4682
+ interface GemGameSettingBase {
4683
+ readonly id: string;
4684
+ readonly label: string;
4685
+ readonly icon?: GemGameSettingIcon;
4686
+ }
4687
+ interface GemGameToggleSetting extends GemGameSettingBase {
4688
+ readonly kind: "toggle";
4689
+ readonly value: boolean;
4690
+ readonly quick?: boolean;
4691
+ }
4692
+ interface GemGameSliderSetting extends GemGameSettingBase {
4693
+ readonly kind: "slider";
4694
+ readonly value: number;
4695
+ readonly min?: number;
4696
+ readonly max?: number;
4697
+ readonly step?: number;
4698
+ }
4699
+ interface GemGameSettingOption {
4700
+ readonly id: string;
4701
+ readonly label: string;
4702
+ }
4703
+ interface GemGameChoiceSetting extends GemGameSettingBase {
4704
+ readonly kind: "choice";
4705
+ readonly value: string;
4706
+ readonly options: readonly GemGameSettingOption[];
4707
+ }
4708
+ type GemGameSetting = GemGameToggleSetting | GemGameSliderSetting | GemGameChoiceSetting;
4709
+ interface GemGameSettingChange {
4710
+ readonly id: string;
4711
+ readonly value: GemGameSettingValue;
4712
+ }
4713
+ interface GameSettingsApi {
4714
+ declare(settings: readonly GemGameSetting[]): boolean;
4715
+ onChange(handler: (change: GemGameSettingChange) => void): () => void;
4716
+ }
4653
4717
  type GemGraphicsQuality = "low" | "medium" | "high";
4654
4718
  interface RewardedStatus {
4655
4719
  readonly declared: boolean;
@@ -4835,6 +4899,7 @@ interface Gem {
4835
4899
  readonly avatars3d: Avatars3dApi;
4836
4900
  readonly vibration: VibrationApi;
4837
4901
  readonly controls: ControlsApi;
4902
+ readonly settings: GameSettingsApi;
4838
4903
  readonly analytics: AnalyticsApi;
4839
4904
  readonly leaderboards: LeaderboardsApi;
4840
4905
  readonly challenges: ChallengesApi;
@@ -4881,4 +4946,4 @@ interface ExitAnalytics {
4881
4946
  }
4882
4947
  declare function leaveAndExit(rooms: ExitRooms, bridge: ExitBridge | null, reason?: string, analytics?: ExitAnalytics): Promise<void>;
4883
4948
  declare function createGem(options?: GemOptions): Gem;
4884
- export { ARCADE_EMBEDDERS, AVATAR_RIGS, type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection$1 as AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type Avatar3dFamily, type Avatar3dOffer, type Avatar3dPrice, type Avatar3dPurchaseRequest, type AvatarRigNode, type AvatarRigs, type Avatars3dApi, type Base64String, type BootMark, type BootTimeline, type BroadcastOptions, type BytesResponse, CONDITIONAL_HEADERS, type Challenge, type ChallengeWindow, ChallengesApi, type ClientOptions, type Clock, type ConditionalRequestHeaders, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, type ControlsApi, DEVICE_SETTINGS_MAX_BYTES, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DevToolsOpener, type DeviceSettings, type DeviceSettingsApi, type DeviceSettingsPutOutcome, type DirectPurchaseRequest, type DirectPurchaseResult, type EarnAllowance, type EarnAllowanceEvent, type EarnAllowancePeriod, type EarnAllowanceReadOptions, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, type EntityType$1 as EntityType, type ExitAnalytics, type ExitBridge, type ExitRooms, type FrameState, type Friend, type FriendChallenge, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, type FriendChallengesPage, FriendsApi, type FriendsPage, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, FunctionsApi, type GameApi, type GameConfig, type GameMenu, type GameMenuItem, type GameServerLink, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemControlBox, type GemCorner, type GemDevTools, type GemErrorReason, GemFrame, GemFunctionError, type GemGraphicsQuality, type GemIdentity, type GemInsets, type GemLook, type GemLookBase, type GemLookDelta, type GemLookOptions, type GemLookSpeed, type GemMatchApi, type GemMatchServer, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, type GemRecommendedSettings, type GemReservedArea, GemSaveError, type GemServer, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerIdentity, type GemServerLifecycle, type GemServerOptions, type GemServerProfile, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type HostTokenSource, type HostTokenSourceOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchBackfillState, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchPlayerReport, type MatchPlayerReportResult, type MatchServeOptions, type MatchTransport, type MessageMeta, type MomentKind, type MomentResult, type MomentSignal, type MomentsApi, type MultiTransportSession, PLATFORM_EVENTS, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayerBadge$1 as PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry$1 as ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RequestOptions, type RewardCue, type RewardedStatus, type RoomArgValue, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerApi, type ServerBundleHost, type ServerTokenGrant, type SessionEndReason, type ShareApi, type ShareRequest, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SnapshotCurrency, type SnapshotItem, type TokenGrant, type Transport, type TransportAdvert, type TransportKind, TransportRefusal, type TransportRequest, type TransportResponse, UNRELIABLE_CHANNEL_LABEL, type VersionedGetOptions, type VersionedResponse, type VibrationApi, type WalletVisibleOptions, type WornAvatar3d$1 as WornAvatar3d, asPlayerText, createBootTimeline, createGem, createGemServer, createHostTokenSource, createMatchServer, defineServer, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, systemClock, text, toBase64, webTransportAvailable };
4949
+ export { ARCADE_EMBEDDERS, AVATAR_RIGS, type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection$1 as AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type Avatar3dFamily, type Avatar3dOffer, type Avatar3dPrice, type Avatar3dPurchaseRequest, type AvatarRigNode, type AvatarRigs, type Avatars3dApi, type Base64String, type BootMark, type BootTimeline, type BroadcastOptions, type BytesResponse, CONDITIONAL_HEADERS, type Challenge, type ChallengeWindow, ChallengesApi, type ClientOptions, type Clock, type ConditionalRequestHeaders, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, type ControlsApi, DEVICE_SETTINGS_MAX_BYTES, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DevToolsOpener, type DeviceSettings, type DeviceSettingsApi, type DeviceSettingsPutOutcome, type DirectPurchaseRequest, type DirectPurchaseResult, type EarnAllowance, type EarnAllowanceEvent, type EarnAllowancePeriod, type EarnAllowanceReadOptions, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, type EntityType$1 as EntityType, type ExitAnalytics, type ExitBridge, type ExitRooms, type FrameState, type Friend, type FriendChallenge, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, type FriendChallengesPage, FriendsApi, type FriendsPage, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, FunctionsApi, type GameApi, type GameConfig, type GameMenu, type GameMenuItem, type GameServerLink, type GameSettingsApi, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemControlBox, type GemCorner, type GemDevTools, type GemErrorReason, GemFrame, GemFunctionError, type GemGameChoiceSetting, type GemGameSetting, type GemGameSettingBase, type GemGameSettingChange, type GemGameSettingIcon, type GemGameSettingOption, type GemGameSettingValue, type GemGameSliderSetting, type GemGameToggleSetting, type GemGraphicsQuality, type GemIdentity, type GemInsets, type GemLook, type GemLookBase, type GemLookDelta, type GemLookOptions, type GemLookSpeed, type GemMatchApi, type GemMatchServer, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, type GemRecommendedSettings, type GemReservedArea, GemSaveError, type GemServer, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerIdentity, type GemServerLifecycle, type GemServerOptions, type GemServerProfile, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type HostTokenSource, type HostTokenSourceOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchBackfillState, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchPlayerReport, type MatchPlayerReportResult, type MatchServeOptions, type MatchTransport, type MessageMeta, type MomentKind, type MomentResult, type MomentSignal, type MomentsApi, type MultiTransportSession, PLATFORM_EVENTS, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayerBadge$1 as PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry$1 as ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RequestOptions, type RewardCue, type RewardedStatus, type RoomArgValue, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerApi, type ServerBundleHost, type ServerTokenGrant, type SessionEndReason, type ShareApi, type ShareRequest, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SnapshotCurrency, type SnapshotItem, type TokenGrant, type Transport, type TransportAdvert, type TransportKind, TransportRefusal, type TransportRequest, type TransportResponse, UNRELIABLE_CHANNEL_LABEL, type VersionedGetOptions, type VersionedResponse, type VibrationApi, type WalletVisibleOptions, type WornAvatar3d$1 as WornAvatar3d, asPlayerText, createBootTimeline, createGem, createGemServer, createHostTokenSource, createMatchServer, defineServer, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, systemClock, text, toBase64, webTransportAvailable };
@@ -1,6 +1,6 @@
1
1
  # The function surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/function` v13.4.2, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
3
+ Generated from `@indiegems/gem-web-sdk/function` v14.0.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
4
4
 
5
5
  `@indiegems/gem-web-sdk/function` exports exactly the symbols on this page and nothing else.
6
6