@indiegems/gem-web-sdk 7.9.0 → 7.9.1

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 ve=Object.defineProperty;var Re=(n,e)=>{for(var t in e)ve(n,t,{get:e[t],enumerable:true});};globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:7.9.0]";function xe(n,e){return e!==void 0?!e:n==="chain_exhausted"}var $=class{constructor(e){this.options=e;}options;grant=null;state="pending";failure=null;generation=0;inFlight=null;rejected=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.grant&&e>=this.grant.chainEndsAt)throw this.enter("lost","chain_exhausted"),new _("chain_exhausted","the token chain reached its ceiling");return this.refresh(this.nextReason())}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);}refresh(e){if(this.inFlight)return this.inFlight;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 s=Se(o),a=o?.retryable;throw t===this.generation&&this.enter(xe(s,typeof a=="boolean"?a:void 0)?"lost":"degraded",s),o instanceof _?o:new _(s,String(o))}).finally(()=>{this.inFlight===r&&(this.inFlight=null);});return this.inFlight=r,r}enter(e,t){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 Se(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 p=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}},j=["if-match","if-none-match"],W=4096;function ke(n){if(!n)return;let e={};for(let[t,r]of Object.entries(n)){let o=t.toLowerCase();if(!j.includes(o)||r===void 0)continue;let s=typeof r=="string"?we(r):r;if(typeof s!="string"||s.length>W||!Ae(s))throw new p(`the ${o} header value cannot be sent \u2014 it is not a string, is longer than ${W} 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.`);s!==""&&(e[o]=s);}return Object.freeze(e)}function we(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 Ae(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 Te(n){let{bytes:e}=n;if(e!==void 0){if(Object.prototype.toString.call(e)!=="[object Uint8Array]")throw new p("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 p("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 z(n,e){let t=e.replayUnauthorizedOnce??true;return {async request(r){let o={...r},s=ke(o.headers),a=Te(o),l=Object.freeze({...o,headers:s,...a===void 0?{}:{bytes:a}}),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(),b=await n(l,g);if(b.status===401)throw e.tokenSource.close("unavailable"),new _("unavailable","the server refused a freshly minted token");return b}}}function K(n){let e=typeof n=="string"?new TextEncoder().encode(n):n;return btoa(Pe(e))}function Pe(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,s,a){super(`${t} (${r}): ${o}`);this.reason=t;this.status=r;this.detail=o;this.retryAfterSeconds=s;this.code=a;this.name="GemApiError";}reason;status;detail;retryAfterSeconds;code;get retryable(){return this.reason==="unavailable"||this.reason==="rate_limited"}},J=new WeakMap;function X(n){return J.get(n)??{}}var Oe=new Set([408,429,500,502,503,504]),Ge=6e4;function Ee(n){if(n===void 0)return 2;if(!Number.isInteger(n)||n<0||n>10)throw new p(`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 P=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,...C(o)},o.replaySafe===true)}async post(e,t,r,o={}){return this.send({method:"POST",path:e,body:t,signal:r,...C(o)},o.replaySafe===true)}async postBytes(e,t,r,o={}){let s=await this.sendRaw({method:"POST",path:e,bytes:t,responseType:"bytes",signal:r,...C(o)},o.replaySafe===true);return {bytes:Ce(s.body),...s.invocationId===void 0?{}:{invocationId:s.invocationId}}}async patch(e,t,r,o={}){return this.send({method:"PATCH",path:e,body:t,signal:r,...C(o)},o.replaySafe===true)}async delete(e,t,r={}){return this.send({method:"DELETE",path:e,signal:t,...C(r)},r.replaySafe===true)}async send(e,t){return (await this.sendRaw(e,t)).body}async sendRaw(e,t){let r=t?Ee(this.options.maxRetries)+1:1,o=null;if(e.signal?.aborted)throw Y(e.signal);for(let s=0;s<r;s++){if(s>0&&await this.backoff(s,o,e.signal),e.signal?.aborted)throw Y(e.signal);let a;try{a=await this.options.transport.request(e);}catch(d){if(_.isAuthError(d)||p.isRefusal(d)||e.signal?.aborted||Ie(d))throw d;o=new m("unavailable",0,String(d));continue}if(a.status>=200&&a.status<300||a.status===304)return a;let l=qe(a);if(!Oe.has(a.status))throw l;o=l;}throw o??new m("unavailable",0,"no attempt was made")}backoff(e,t,r){if(r?.aborted)return Promise.resolve();let o=t?.retryAfterSeconds,s=o!==void 0?o*1e3:2**(e-1)*250,a=2**(e-1)*250,l=Math.min(Math.max(s,a),Ge);return new Promise(d=>{let c=this.options.clock,g=false,b=false,x,f=()=>{g||(g=true,b&&c.clearTimeout(x),r?.removeEventListener("abort",f),d());};r?.addEventListener("abort",f,{once:true}),x=c.setTimeout(f,l),b=true,g&&c.clearTimeout(x);})}};function Ce(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 C(n){return {...n.keepalive===void 0?{}:{keepalive:n.keepalive},...n.ifMatch===void 0?{}:{headers:{"if-match":n.ifMatch}}}}function Y(n){return n.reason!==void 0?n.reason:new DOMException("The operation was aborted.","AbortError")}function Ie(n){let e=n?.name;return e==="AbortError"||e==="TimeoutError"}function qe(n){let e=$e(n),t=Me(n.body),r={...t===void 0?{}:{details:t},...n.invocationId===void 0?{}:{invocationId:n.invocationId}};return Object.keys(r).length>0&&J.set(e,r),e}var Le=new Map([["insufficient_funds","insufficient_funds"]]);function $e(n){let{status:e,body:t}=n,r=je(t),o=n.retryAfterSeconds??Ue(t),s=Fe(t),a=s===void 0?void 0:Le.get(s);if(a!==void 0)return new m(a,e,r,void 0,s);switch(e){case 304:return new m("not_modified",e,r);case 400:case 422:return new m("invalid",e,r,void 0,s);case 403:return new m("forbidden",e,r,void 0,s);case 404:return new m("not_found",e,r,void 0,s);case 402:return new m("insufficient_funds",e,r,void 0,s);case 409:return new m("conflict",e,r,void 0,s);case 412:return new m("precondition_failed",e,r,void 0,s);case 413:return new m("too_large",e,r,void 0,s);case 429:return new m("rate_limited",e,r,o,s);default:return new m("unavailable",e,r,o,s)}}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 Me(n){let t=n?.error?.details;return t===null?void 0:t}function Fe(n){let t=n?.error?.code;return typeof t=="string"&&t.length>0?t:void 0}function Ue(n){let e=n?.retryAfterSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function Be(n){let e=n.lastIndexOf("@");return (e===-1?n:`***@${n.slice(e+1)}`).slice(0,200)}var Ne=new Set(j);function De(n){if(!n)return {};let e={};for(let[t,r]of Object.entries(n))Ne.has(t.toLowerCase())&&(e[t.toLowerCase()]=r);return e}function Q(n){let e=n.fetch??globalThis.fetch.bind(globalThis);return z(async(t,r)=>{let o;try{o=new URL(n.baseUrl.replace(/\/+$/,""));}catch{throw new p("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 s;try{s=new URL(o.href.replace(/\/+$/,"")+t.path);}catch{throw new p(`${JSON.stringify(typeof t.path=="string"?Be(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(s.protocol!==o.protocol||s.host!==o.host)throw new p(`${JSON.stringify(s.pathname)} resolves to ${s.protocol}//${s.host}, not ${o.protocol}//${o.host}. A request path may not change the request's origin \u2014 it carries the play token.`);if(s.username!==""||s.password!==""){let f=o.username!==""||o.password!=="",v=s.username!==o.username||s.password!==o.password,y=f?v?"baseUrl (and possibly the request path)":"baseUrl":"request path";throw new p(`the ${y} puts credentials in the URL, which cannot be fetched (${t.method} ${s.pathname}). The value is withheld here rather than written to logs. This is a malformed request, not a server failure.`)}for(let[f,v]of Object.entries(n.defaultQuery??{}))s.searchParams.has(f)||s.searchParams.set(f,v);let a=t.bytes,l=t.bytes===void 0?void 0:"application/octet-stream";try{t.body!==void 0&&(a=JSON.stringify(t.body),l="application/json");}catch(f){throw new p(`the body of ${t.method} ${JSON.stringify(s.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(s.toString(),{method:t.method,headers:{authorization:`Bearer ${r}`,...l===void 0?{}:{"content-type":l},...De(t.headers)},body:a,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"),b=He(d.headers.get("retry-after")),x=d.headers.get("x-gem-invocation-id");return {status:d.status,body:c,...g===null?{}:{etag:g},...b===void 0?{}:{retryAfterSeconds:b},...x===null||x===""?{}:{invocationId:x}}},n)}function He(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 Ve="gem-web-bridge";var O=65536,Z=8,M=5e3,ee=1024;function B(n){return Object.freeze(Object.assign(Object.create(null),n))}B({"gem.handshake":30,"gem.handshake.accept":5,"gem.token":30,"gem.token.denied":30,"gem.player":12,"gem.pause":120,"gem.prefs":60,"gem.cohorts":12,"gem.earnAllowanceChanged":30,"gem.viewport":60,"gem.deviceSettings":12,"gem.willTerminate":10,"gem.roomEvent":120,"gem.socketState":12,"gem.seatedEvent":60,"gem.autoStartFailedEvent":30,"gem.signalEvent":1800,"gem.dedicatedEvent":120,"gem.partyResult":30,"gem.clusterTarget":12,"gem.devtools":30,"gem.screenshot":6,"gem.screenshot.denied":12,"gem.requestContext":12,"gem.gameContext":12,"gem.signal":1200,"gem.dedicatedOffer":60,"gem.partyRequest":12,"gem.ready":5,"gem.engaged":5,"gem.progress":600,"gem.requestToken":12,"gem.requestLocalServer":6,"gem.localServer":30,"gem.localServer.denied":30,"gem.exit":5,"gem.openExternal":6,"gem.requestFullscreen":30,"gem.audioState":120,"gem.rewardCue":60,"gem.walletDisplay":60,"gem.menu":60,"gem.menuSelect":60,"gem.requestShare":6,"gem.frameStats":120,"gem.error":60,"gem.requestPurchase":12,"gem.purchaseResult":30,"gem.deviceSettings.put":30,"gem.deviceSettings.result":30,"gem.requestAd":6,"gem.adResult":12,"gem.requestSignIn":6,"gem.signInResult":12,"gem.requestFriendChallenge":12,"gem.friendChallengeResult":30,__malformed:60});B({"gem.requestAd":"ads","gem.adResult":"ads","gem.requestSignIn":"signIn","gem.signInResult":"signIn","gem.requestPurchase":"purchases","gem.purchaseResult":"purchases","gem.requestFriendChallenge":"friendChallenges","gem.friendChallengeResult":"friendChallenges","gem.devtools":"devtools","gem.screenshot":"screenshot","gem.screenshot.denied":"screenshot","gem.requestContext":"feedbackContext","gem.gameContext":"feedbackContext","gem.roomEvent":"rooms","gem.signal":"p2p","gem.signalEvent":"p2p","gem.dedicatedOffer":"dedicated","gem.dedicatedEvent":"dedicated","gem.clusterTarget":"clusterTarget","gem.partyRequest":"parties","gem.partyResult":"parties","gem.autoStartFailedEvent":"autoStartFailure","gem.seatedEvent":"partySeating","gem.socketState":"socketState","gem.audioState":"audioState","gem.rewardCue":"rewardCue","gem.frameStats":"frameStats","gem.engaged":"engagement","gem.viewport":"viewport","gem.walletDisplay":"walletDisplay","gem.requestLocalServer":"localHost","gem.localServer":"localHost","gem.localServer.denied":"localHost","gem.cohorts":"cohorts","gem.earnAllowanceChanged":"earnAllowance","gem.deviceSettings":"deviceSettings","gem.deviceSettings.put":"deviceSettings","gem.deviceSettings.result":"deviceSettings","gem.requestShare":"share","gem.menu":"gameMenu","gem.menuSelect":"gameMenu"});function ze(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 Ke(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 Ye(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function Je(n){return /^[a-z_]+$/.test(n)}function U(n,e,t){if(e>Z)return `nesting deeper than ${Z}`;if(++t.nodes>M)return `more than ${M} values`;if(t.bytes>O)return `over the ${O} 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>ee)return `an array of ${n.length} entries, over the ${ee} limit`;t.bytes+=2;for(let l of n){let d=U(l,e+1,t);if(d)return d}return null}let s=Object.getPrototypeOf(n);if(s!==Object.prototype&&s!==null)return "a value that is not a plain object";t.bytes+=2;let a=n;for(let l in a){if(!Object.prototype.hasOwnProperty.call(a,l))continue;if(++t.nodes>M)return `more than ${M} values`;if(t.bytes+=l.length*3+4,t.bytes>O)return `over the ${O} byte limit`;let d=U(a[l],e+1,t);if(d)return d}return null}function Xe(n){let e={nodes:0,bytes:0,seen:new Set},t=U(n,0,e);return t?`message contains ${t}`:e.bytes>O?`message is over the ${O} byte limit`:null}var Qe={origin:[ze,"not a well-formed origin"],url:[Ke,"not a safe absolute http(s) URL"],bcp47:[Ye,"not a well-formed BCP 47 tag"],code:[Je,"not a code of lower-case letters and underscores"]};function ne(n,e,t){for(let r of e){let o=t===""?r.n:`${t}.${r.n}`,s=n[r.n];if(s==null){if(r.o)continue;return `${o}: required`}let a=te(s,r,o);if(a)return a}return null}function te(n,e,t){switch(e.k){case "string":{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]=Qe[e.f];if(!r(n))return `${t}: ${o}`}return null}case "int":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 "boolean":return typeof n=="boolean"?null:`${t}: expected boolean`;case "enum":{let r=e.v;return r.includes(n)?null:`${t}: not one of ${r.join("|")}`}case "object":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:ne(n,e.fs,t);case "json":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected a plain object`:null;case "array":{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 s of n){if(s==null){if(r.o)continue;return `${o}: required`}let a=te(s,r,o);if(a)return a}return null}default:{let r=e.k;return `${t}: unknown kind ${String(r)}`}}}function u(n,e){return t=>{let r=Xe(t);if(r)return r;if(typeof t!="object"||t===null||Array.isArray(t))return "message: expected object";let o=t;return o.gem!==Ve?"gem: wrong protocol marker":o.type!==n?`type: expected ${n}`:ne(o,e,"")}}var Ze=u("gem.handshake",[{n:"versions",k:"object",fs:[{n:"min",k:"int",lo:1,hi:1e3},{n:"max",k:"int",lo:1,hi:1e3}]},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}},{n:"embedder",k:"string",max:2048,f:"origin"},{n:"unbidden",k:"boolean",o:1}]),en=u("gem.handshake.accept",[{n:"v",k:"int",lo:1,hi:1e3},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}}]),nn=u("gem.token",[{n:"token",k:"string",max:4096},{n:"requestId",k:"string",o:1,max:64},{n:"generation",k:"int",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"string",o:1,max:512,f:"url"},{n:"playerId",k:"string",max:64},{n:"gameId",k:"string",max:64},{n:"channel",k:"enum",v:["dev","test","release"]},{n:"gameVersion",k:"string",o:1,max:64},{n:"expiresAt",k:"int",lo:0,hi:4102444800},{n:"chainEndsAt",k:"int",lo:0,hi:4102444800},{n:"allowDevTools",k:"boolean",o:1}]),tn=u("gem.token.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"retryAfterMs",k:"int",o:1,lo:0,hi:36e5},{n:"reason",k:"enum",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"string",max:64}]),rn=u("gem.player",[{n:"untrusted",k:"object",fs:[{n:"displayName",k:"string",max:64},{n:"displayTag",k:"string",o:1,max:80},{n:"displayHandle",k:"string",max:80}]},{n:"playerId",k:"string",o:1,max:64},{n:"discriminator",k:"string",o:1,max:8},{n:"avatarIconUrl",k:"string",o:1,max:2048,f:"url"},{n:"badges",k:"array",o:1,max:2,it:{n:"",k:"object",fs:[{n:"itemId",k:"string",max:64},{n:"iconUrl",k:"string",max:2048,f:"url"}]}},{n:"displayTag",k:"string",max:8},{n:"avatarUrl",k:"string",o:1,max:2048,f:"url"},{n:"boost",k:"object",o:1,fs:[{n:"multipliers",k:"array",max:8,it:{n:"",k:"object",fs:[{n:"currencyId",k:"string",max:64},{n:"currencySlug",k:"string",max:32},{n:"multiplierBp",k:"int",lo:1e4,hi:1e6}]}},{n:"expiresInDays",k:"int",o:1,lo:1,hi:7}]}]),on=u("gem.pause",[{n:"paused",k:"boolean"}]),sn=u("gem.prefs",[{n:"reducedMotion",k:"boolean"},{n:"muted",k:"boolean"},{n:"showFrameStats",k:"boolean",o:1},{n:"locale",k:"string",max:35,f:"bcp47"}]),an=u("gem.cohorts",[{n:"cohorts",k:"array",max:8,it:{n:"",k:"object",fs:[{n:"experimentId",k:"string",max:36},{n:"variantKey",k:"string",max:32}]}}]),ln=u("gem.earnAllowanceChanged",[]),dn=u("gem.viewport",[{n:"insets",k:"object",fs:[{n:"top",k:"int",lo:0,hi:4096},{n:"right",k:"int",lo:0,hi:4096},{n:"bottom",k:"int",lo:0,hi:4096},{n:"left",k:"int",lo:0,hi:4096}]},{n:"reserved",k:"array",o:1,max:4,it:{n:"",k:"object",fs:[{n:"x",k:"int",lo:0,hi:16384},{n:"y",k:"int",lo:0,hi:16384},{n:"width",k:"int",lo:0,hi:16384},{n:"height",k:"int",lo:0,hi:16384}]}}]),un=u("gem.deviceSettings",[{n:"settings",k:"json",o:1}]),cn=u("gem.willTerminate",[{n:"reason",k:"enum",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"int",lo:0,hi:6e4}]),gn=u("gem.roomEvent",[{n:"event",k:"enum",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"string",max:64},{n:"matchId",k:"string",o:1,max:64},{n:"version",k:"int",o:1,lo:0,hi:2147483647},{n:"reason",k:"string",o:1,max:64},{n:"platform",k:"enum",o:1,v:["universal","mobile"]}]),mn=u("gem.socketState",[{n:"connected",k:"boolean"},{n:"reason",k:"enum",o:1,v:["connecting","dropped","watchdog","terminal"]}]),pn=u("gem.seatedEvent",[{n:"roomId",k:"string",max:64}]),yn=u("gem.autoStartFailedEvent",[{n:"roomId",k:"string",max:64},{n:"code",k:"string",max:64}]),fn=u("gem.signalEvent",[{n:"event",k:"enum",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),hn=u("gem.dedicatedEvent",[{n:"event",k:"enum",v:["answer","error","matchEnded"]},{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",o:1,max:10240},{n:"sessionId",k:"string",o:1,max:64},{n:"code",k:"string",o:1,max:64},{n:"message",k:"string",o:1,max:256},{n:"reason",k:"string",o:1,max:64}]),_n=u("gem.partyResult",[{n:"requestId",k:"string",max:64},{n:"partyId",k:"string",o:1,max:64}]),bn=u("gem.clusterTarget",[{n:"clusterTargetId",k:"string",max:64},{n:"clusterTargetIds",k:"array",o:1,max:3,it:{n:"",k:"string",max:64}}]),vn=u("gem.devtools",[{n:"action",k:"enum",v:["open","close","toggle"]}]),Rn=u("gem.screenshot",[{n:"maxWidth",k:"int",lo:1,hi:7680},{n:"maxHeight",k:"int",lo:1,hi:4320}]),xn=u("gem.screenshot.denied",[{n:"reason",k:"enum",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"boolean"}]),Sn=u("gem.requestContext",[]),kn=u("gem.gameContext",[{n:"context",k:"json"}]),wn=u("gem.signal",[{n:"signal",k:"enum",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),An=u("gem.dedicatedOffer",[{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",max:10240},{n:"intent",k:"enum",v:["initial","ice_restart","full_reconnect"]}]),Tn=u("gem.partyRequest",[{n:"requestId",k:"string",max:64}]),Pn=u("gem.ready",[]),On=u("gem.engaged",[]),Gn=u("gem.progress",[{n:"loaded",k:"int",lo:0,hi:1099511627776},{n:"total",k:"int",lo:0,hi:1099511627776}]),En=u("gem.requestToken",[{n:"requestId",k:"string",max:64},{n:"reason",k:"enum",v:["initial","expiring","rejected"]}]),Cn=u("gem.requestLocalServer",[{n:"requestId",k:"string",max:64},{n:"gameRoomId",k:"string",max:64}]),In=u("gem.localServer",[{n:"requestId",k:"string",max:64},{n:"serverId",k:"string",o:1,max:128}]),qn=u("gem.localServer.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"reason",k:"enum",v:["refused","unavailable"]}]),Ln=u("gem.exit",[{n:"reason",k:"string",o:1,max:64}]),$n=u("gem.openExternal",[{n:"url",k:"string",max:2048,f:"url"}]),jn=u("gem.requestFullscreen",[{n:"enabled",k:"boolean"}]),Mn=u("gem.audioState",[{n:"muted",k:"boolean"}]),Fn=u("gem.rewardCue",[{n:"currencySlug",k:"string",max:32},{n:"expected",k:"int",o:1,lo:1,hi:1e9},{n:"origin",k:"object",o:1,fs:[{n:"x",k:"int",lo:0,hi:16384},{n:"y",k:"int",lo:0,hi:16384}]}]),Un=u("gem.walletDisplay",[{n:"visible",k:"boolean"},{n:"currencies",k:"array",o:1,max:8,it:{n:"",k:"string",max:64}},{n:"score",k:"boolean",o:1}]),Bn=u("gem.menu",[{n:"settings",k:"boolean"},{n:"items",k:"array",o:1,max:4,it:{n:"",k:"object",fs:[{n:"id",k:"string",max:32},{n:"label",k:"string",max:40}]}}]),Nn=u("gem.menuSelect",[{n:"entry",k:"enum",v:["settings","item"]},{n:"id",k:"string",o:1,max:32}]),Dn=u("gem.requestShare",[{n:"params",k:"array",max:16,it:{n:"",k:"object",fs:[{n:"key",k:"string",max:64},{n:"value",k:"string",max:512}]}}]),Hn=u("gem.frameStats",[{n:"fps",k:"int",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"int",lo:0,hi:1e5}]),Vn=u("gem.error",[{n:"code",k:"enum",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"string",o:1,max:256}]),Wn=u("gem.requestPurchase",[{n:"requestId",k:"string",max:64},{n:"purchaseKind",k:"enum",v:["item","recipe"]},{n:"targetId",k:"string",max:64},{n:"currencySlug",k:"string",max:32},{n:"quantity",k:"int",o:1,lo:1,hi:10},{n:"catalogId",k:"string",o:1,max:64}]),zn=u("gem.purchaseResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["ok","declined","unavailable"]},{n:"reason",k:"string",o:1,max:64,f:"code"},{n:"purchaseId",k:"string",o:1,max:64}]),Kn=u("gem.deviceSettings.put",[{n:"requestId",k:"string",max:64},{n:"settings",k:"json"}]),Yn=u("gem.deviceSettings.result",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["stored","too_large","unavailable"]}]),Jn=u("gem.requestAd",[{n:"requestId",k:"string",max:64},{n:"placement",k:"string",max:32},{n:"format",k:"enum",v:["interstitial","rewarded"]}]),Xn=u("gem.adResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["shown","no_ad","unavailable"]}]),Qn=u("gem.requestSignIn",[{n:"requestId",k:"string",max:64}]),Zn=u("gem.signInResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["signed_in","declined","unavailable"]}]),et=u("gem.requestFriendChallenge",[{n:"requestId",k:"string",max:64},{n:"playerId",k:"string",max:64},{n:"template",k:"string",max:64},{n:"params",k:"json",o:1}]),nt=u("gem.friendChallengeResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["accepted","cancelled","refused","unavailable","rate_limited","invalid"]},{n:"code",k:"string",o:1,max:64},{n:"param",k:"string",o:1,max:64},{n:"channel",k:"string",o:1,max:16},{n:"configVersion",k:"int",o:1,lo:0,hi:9007199254740991},{n:"retryAfterMs",k:"int",o:1,lo:0,hi:864e5},{n:"detail",k:"string",o:1,max:300}]);B({"gem.handshake":Ze,"gem.handshake.accept":en,"gem.token":nn,"gem.token.denied":tn,"gem.player":rn,"gem.pause":on,"gem.prefs":sn,"gem.cohorts":an,"gem.earnAllowanceChanged":ln,"gem.viewport":dn,"gem.deviceSettings":un,"gem.willTerminate":cn,"gem.roomEvent":gn,"gem.socketState":mn,"gem.seatedEvent":pn,"gem.autoStartFailedEvent":yn,"gem.signalEvent":fn,"gem.dedicatedEvent":hn,"gem.partyResult":_n,"gem.clusterTarget":bn,"gem.devtools":vn,"gem.screenshot":Rn,"gem.screenshot.denied":xn,"gem.requestContext":Sn,"gem.gameContext":kn,"gem.signal":wn,"gem.dedicatedOffer":An,"gem.partyRequest":Tn,"gem.ready":Pn,"gem.engaged":On,"gem.progress":Gn,"gem.requestToken":En,"gem.requestLocalServer":Cn,"gem.localServer":In,"gem.localServer.denied":qn,"gem.exit":Ln,"gem.openExternal":$n,"gem.requestFullscreen":jn,"gem.audioState":Mn,"gem.rewardCue":Fn,"gem.walletDisplay":Un,"gem.menu":Bn,"gem.menuSelect":Nn,"gem.requestShare":Dn,"gem.frameStats":Hn,"gem.error":Vn,"gem.requestPurchase":Wn,"gem.purchaseResult":zn,"gem.deviceSettings.put":Kn,"gem.deviceSettings.result":Yn,"gem.requestAd":Jn,"gem.adResult":Xn,"gem.requestSignIn":Qn,"gem.signInResult":Zn,"gem.requestFriendChallenge":et,"gem.friendChallengeResult":nt});var G={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)};var tt=1e4;function re(n,e){return N(n,e)}function N(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=a=>({token:a.token,expiresAt:a.expiresAt,chainEndsAt:Number.POSITIVE_INFINITY}),r=null,o=new $({clock:e.clock,...e.onStateChange===void 0?{}:{onStateChange:e.onStateChange},request:()=>new Promise((a,l)=>{let d=e.clock.setTimeout(()=>{r=null,l({reason:"unavailable",retryable:true});},e.timeoutMs??tt);r={resolve:c=>{e.clock.clearTimeout(d),a(c);},reject:l,timer:d};})}),s=n.onServerToken(a=>{let l=t(a),d=r;if(d){r=null,d.resolve(l);return}o.accept(l);});return {source:o,dispose(){s(),r&&(e.clock.clearTimeout(r.timer),r.reject({reason:"unavailable",retryable:false}),r=null);}}}var H={};Re(H,{acceptTransfer:()=>rt,addEntityProgression:()=>ot,adminAction:()=>st,cancelInventoryTransfer:()=>it,claimEntityProgressionRewards:()=>at,closeGameRoom:()=>lt,createEntityBatchOrder:()=>dt,createEntityOrder:()=>ut,createSession:()=>ct,deleteEntityGameSetting:()=>gt,deleteEntitySave:()=>mt,deleteSession:()=>pt,deleteShowcaseValue:()=>yt,executeEntityRecipe:()=>ft,finalizeSaveUpload:()=>ht,getChannelAssignment:()=>_t,getDropRates:()=>bt,getEntityCurrency:()=>vt,getEntityGameSetting:()=>Rt,getEntityInventory:()=>xt,getEntityInventoryItem:()=>St,getEntityLeaderboard:()=>kt,getEntityOrder:()=>wt,getEntityProgression:()=>At,getEntityRecipeAvailability:()=>Tt,getEntityRecipeUsage:()=>Pt,getEntitySave:()=>Ot,getEvent:()=>Gt,getGameRoomV2:()=>Et,getLeaderboard:()=>Ct,getPlayerGameProfile:()=>It,getPurchaseCatalog:()=>qt,getResolvedTemplate:()=>Lt,getRoomArgs:()=>$t,getShowcaseValue:()=>jt,getTransferDetails:()=>Mt,ingestAnalyticsEvents:()=>D,initiateInventoryTransfer:()=>Ft,invokeFunction:()=>Ut,kickPlayer:()=>Bt,listChallenges:()=>Nt,listEntityGameSettings:()=>Dt,listEntityOrders:()=>Ht,listEntityProgressions:()=>Vt,listEntitySaves:()=>Wt,listEvents:()=>zt,listGameRooms:()=>Kt,listResolvedTemplates:()=>Yt,listTransfers:()=>Jt,maxEntityProgression:()=>Xt,putEntityGameSetting:()=>Qt,putRoomArgs:()=>Zt,putShowcaseValue:()=>er,rejectTransfer:()=>nr,requestSaveUploadUrl:()=>tr,resetEntityProgression:()=>rr,simulateEntityOrder:()=>or,transferHostV2:()=>sr,updateGameRoomV2:()=>ir});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 rt(n,e,t){let r=`/v1/inventory/transfers/${i(e)}/accept`;return n.client.post(r,void 0,t?.signal)}async function ot(n,e,t,r,o,s){let a=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/add`;return n.client.post(a,o,s?.signal)}async function st(n,e,t,r){let o=`/v1/voice/sessions/${i(e)}/admin`;return n.client.post(o,t,r?.signal)}async function it(n,e,t){let r=`/v1/inventory/transfers/${i(e)}/cancel`;return n.client.post(r,void 0,t?.signal)}async function at(n,e,t,r,o,s){let a=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/claim`;return n.client.post(a,o,s?.signal)}async function lt(n,e,t){let r=`/v1/games/${i(n.gameId())}/game-rooms/${i(e)}`;return n.client.delete(r,t?.signal)}async function dt(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/orders/batch`;return n.client.post(s,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function ut(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/orders`;return n.client.post(s,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function ct(n,e,t){return n.client.post("/v1/voice/sessions",e,t?.signal)}async function gt(n,e,t,r,o){let s=`/v1/settings/${i(e)}/${i(t)}/${i(r)}`;return n.client.delete(s,o?.signal)}async function mt(n,e,t,r,o){let s=`/v1/saves/${i(e)}/${i(t)}/${i(r)}`;return n.client.delete(s,o?.signal)}async function pt(n,e,t){let r=`/v1/voice/sessions/${i(e)}`;return n.client.delete(r,t?.signal)}async function yt(n,e,t,r){let o=`/v1/showcase/players/${i(e)}/${i(t)}`;return n.client.delete(o,r?.signal)}async function ft(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/recipes/execute`;return n.client.post(s,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function ht(n,e,t,r,o,s){let a=`/v1/saves/${i(e)}/${i(t)}/${i(r)}/finalize`;return n.client.post(a,o,s?.signal)}async function _t(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 bt(n,e,t){let r=`/v1/inventory/loot-tables/${i(e)}/drop-rates`;return n.client.get(r,t?.signal)}async function vt(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/currencies/${i(r)}`;return n.client.get(s,o?.signal)}async function Rt(n,e,t,r,o){let s=`/v1/settings/${i(e)}/${i(t)}/${i(r)}`;return n.client.getWithEtag(s,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function xt(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 s=o.toString(),a=`/v1/inventory/${i(e)}/${i(t)}`+(s?`?${s}`:"");return n.client.get(a,r?.signal)}async function St(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/items/${i(r)}`;return n.client.get(s,o?.signal)}async function kt(n,e,t,r,o){let s=new URLSearchParams;o?.bucket_1!==void 0&&s.set("bucket_1",String(o?.bucket_1)),o?.bucket_2!==void 0&&s.set("bucket_2",String(o?.bucket_2)),o?.limit!==void 0&&s.set("limit",String(o?.limit)),o?.periods_back!==void 0&&s.set("periods_back",String(o?.periods_back)),o?.period!==void 0&&s.set("period",String(o?.period)),o?.player_id!==void 0&&s.set("player_id",String(o?.player_id));let a=s.toString(),l=`/v1/leaderboards/${i(e)}/${i(t)}/${i(r)}`+(a?`?${a}`:"");return n.client.get(l,o?.signal)}async function wt(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/orders/${i(r)}`;return n.client.get(s,o?.signal)}async function At(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}`;return n.client.get(s,o?.signal)}async function Tt(n,e,t,r,o,s){let a=`/v1/inventory/${i(e)}/${i(t)}/catalogs/${i(r)}/recipes/${i(o)}/availability`;return n.client.get(a,s?.signal)}async function Pt(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit));let s=o.toString(),a=`/v1/inventory/${i(e)}/${i(t)}/recipe-usage`+(s?`?${s}`:"");return n.client.get(a,r?.signal)}async function Ot(n,e,t,r,o){let s=`/v1/saves/${i(e)}/${i(t)}/${i(r)}`;return n.client.getWithEtag(s,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function Gt(n,e,t){let r=`/v1/events/${i(e)}`;return n.client.get(r,t?.signal)}async function Et(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 Ct(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(),s=`/v1/leaderboards/${i(e)}`+(o?`?${o}`:"");return n.client.get(s,t?.signal)}async function It(n,e,t){let r=`/v1/profiles/players/${i(e)}`;return n.client.get(r,t?.signal)}async function qt(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 Lt(n,e,t){let r=`/v1/game-room-templates/${i(e)}`;return n.client.get(r,t?.signal)}async function $t(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 jt(n,e,t,r){let o=`/v1/showcase/players/${i(e)}/${i(t)}`;return n.client.get(o,r?.signal)}async function Mt(n,e,t){let r=`/v1/inventory/transfers/${i(e)}`;return n.client.get(r,t?.signal)}async function D(n,e,t){let r=`/v1/games/${i(n.gameId())}/analytics/events`;return n.client.post(r,e,t?.signal,{replaySafe:true})}async function Ft(n,e,t){return n.client.post("/v1/inventory/transfers",e,t?.signal)}async function Ut(n,e,t){return n.client.postBytes("/v1/functions/invoke",e,t?.signal)}async function Bt(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 Nt(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 Dt(n,e,t,r){let o=`/v1/settings/${i(e)}/${i(t)}`;return n.client.get(o,r?.signal)}async function Ht(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 s=o.toString(),a=`/v1/inventory/${i(e)}/${i(t)}/orders`+(s?`?${s}`:"");return n.client.get(a,r?.signal)}async function Vt(n,e,t,r){let o=`/v1/inventory/${i(e)}/${i(t)}/progressions`;return n.client.get(o,r?.signal)}async function Wt(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 s=o.toString(),a=`/v1/saves/${i(e)}/${i(t)}`+(s?`?${s}`:"");return n.client.get(a,r?.signal)}async function zt(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 Kt(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 Yt(n,e){return n.client.get("/v1/game-room-templates",e?.signal)}async function Jt(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 Xt(n,e,t,r,o,s){let a=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/max`;return n.client.post(a,o,s?.signal)}async function Qt(n,e,t,r,o,s){let a=`/v1/settings/${i(e)}/${i(t)}/${i(r)}`;return n.client.put(a,o,s?.signal,{...s?.ifMatch===void 0?{}:{ifMatch:s.ifMatch}})}async function Zt(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 er(n,e,t,r,o){let s=`/v1/showcase/players/${i(e)}/${i(t)}`;return n.client.put(s,r,o?.signal)}async function nr(n,e,t){let r=`/v1/inventory/transfers/${i(e)}/reject`;return n.client.post(r,void 0,t?.signal)}async function tr(n,e,t,r,o,s){let a=`/v1/saves/${i(e)}/${i(t)}/${i(r)}/upload-url`;return n.client.post(a,o,s?.signal,{replaySafe:true})}async function rr(n,e,t,r,o,s){let a=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/reset`;return n.client.post(a,o,s?.signal)}async function or(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/orders/simulate`;return n.client.post(s,r,o?.signal)}async function sr(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 ir(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 oe="gem_";var dr=1e4,ur=50,cr=1e3,gr=65536-4*1024,se=n=>typeof n=="number"?n:0,mr=n=>typeof n=="string"?n:"";function ie(){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 pr(n){return n?.retryable===true}function yr(n,e){let t=n??{},r=Array.isArray(t.rejected)?t.rejected.map(o=>{let s=o??{};return {index:se(s.index),code:mr(s.code)}}):[];return {accepted:se(t.accepted),rejected:r,dropped:e,duplicate:t.duplicate===true}}function ae(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 le(n){let e=Math.max(1,Math.floor(n.maxQueue??cr)),t={client:n.client,gameId:()=>n.gameId},r=[],o=0,s=null,a=false,l=false,d=false,c=false,g=y=>{n.log?.(y);},b=()=>{s!==null&&(n.clock.clearTimeout(s),s=null);},x=()=>{s!==null||a||l||(s=n.clock.setTimeout(()=>{s=null,v().catch(()=>{});},dr));},f=()=>{let y=Math.min(r.length,100),h=128;for(let w=0;w<y;w+=1){let A=r[w];if(A===void 0)break;if(h+=JSON.stringify(ae(A,0)).length+1,h>gr)return Math.max(1,w)}return y};async function v(y){if(r.length===0)return {accepted:0,rejected:[],dropped:0,duplicate:false};b();let h=r.splice(0,f()),w=o;o=0;let A=Math.round(n.clock.now()),L={batch_id:ie(),sent_at_ms:A,events:h.map(S=>ae(S,A))};l=true;try{let S=await D(t,L,y===void 0?void 0:{signal:y}),T=yr(S,w);for(let be of T.rejected)g(`[gem] analytics: an event was refused (${be.code}). See the analytics_events section of your game config.`);return T}catch(S){if(pr(S))for(r=[...h,...r],o+=w;r.length>e;)r.shift(),o+=1;else g(`[gem] analytics: ${h.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(S)}`);throw S}finally{l=false,r.length>0&&x();}}return {track(y,h,w={}){if(a)return;if(typeof y!="string"||y===""){c||(c=true,g(`[gem] analytics: '${h}' 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(h.startsWith(oe)){d||(d=true,g(`[gem] analytics: '${h}' 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 A={},L={};for(let[S,T]of Object.entries(w))typeof T=="string"?A[S]=T:typeof T=="number"&&Number.isFinite(T)&&(L[S]=T);for(;r.length>=e;)r.shift(),o+=1;r.push({uid:ie(),playerId:y,name:h,atMs:n.clock.now(),dimensions:A,measures:L}),r.length>=ur?v().catch(()=>{}):x();},flush:y=>v(y),get pending(){return r.length},dispose(){a=true,b(),r=[],o=0;}}}var fr=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]]),I=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:fr.get(this.code))??super.retryable}},E=class{#e;constructor(e){this.#e=e;}async invoke(e,t={}){let r=hr(e),o;try{o=await this.#e(r,t.signal===void 0?{}:{signal:t.signal});}catch(s){throw s instanceof m?br(s):s}return _r(o)}};function hr(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 p(`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 p(`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 _r(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 br(n){let{details:e,invocationId:t}=X(n),o=e?.untrusted?.message,s=e?.reason;return new I(n,{...t===void 0?{}:{invocationId:t},...n.code==="function_error"&&typeof o=="string"?{functionMessage:o}:{},...n.code==="function_failed"&&typeof s=="string"?{failure:s}:{}})}var k=n=>typeof n=="string"?n:"",vr=/(?:Z|[+-]\d{2}:?\d{2})$/i;function de(n){let e=k(n);if(!vr.test(e))return 0;let t=Date.parse(e);return Number.isFinite(t)?Math.floor(t/1e3):0}var Rr=/^[0-9a-f]{1,64}$/,xr=/^[0-9a-f]{16}$/,Sr=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,kr=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function wr(n){let e=k(n),t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!t)return;let[r,o,s]=[Number(t[1]),Number(t[2]),Number(t[3])],a=new Date(Date.UTC(r,o-1,s));return a.getUTCFullYear()===r&&a.getUTCMonth()===o-1&&a.getUTCDate()===s?e:void 0}var Ar=4096,Tr=new TextEncoder;function Pr(n){let e=k(n.challenge_data),t=k(n.challenge_data_hash);return e===""||!xr.test(t)?{}:Tr.encode(e).length>Ar?{}:{data:e,dataHash:t}}function Or(n){let e=n??{},t=de(e.period_start_at),r=de(e.period_ends_at);if(t===0||r===0)return;let o=k(e.slug),s=k(e.seed),a=wr(e.period_local_date),l=k(e.boundary),d=k(e.reset_time);return {id:k(e.progression_definition_id),...o===""?{}:{slug:o},window:k(e.window),periodStartAt:t,periodEndsAt:r,...a===void 0?{}:{periodLocalDate:a},boundary:Sr.test(l)?l:"",resetTime:kr.test(d)?d:"",seed:Rr.test(s)?s:"",...Pr(e)}}function ue(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 ce(n){let e=n??{};return Array.isArray(e.challenges)?e.challenges.map(Or).filter(t=>t!==void 0):[]}function ge(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().");ue(r);let s=await n({player_id:t,...r===void 0?{}:{periods_back:r},...o===void 0?{}:{signal:o}});return ce(s)}}}function Gr(n){let e={};for(let[t,r]of Object.entries(H))if(typeof r=="function"){let o=r;e[t]=(...s)=>o(n,...s);}return e}function F(n,e={}){let t=e.clock??G,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=N(n,{clock:t,...e.onAuthStateChange===void 0?{}:{onStateChange:e.onAuthStateChange}}),s=Q({baseUrl:r,tokenSource:o.source,defaultQuery:{game_id:n.gameId,channel:n.channel},...e.fetch===void 0?{}:{fetch:e.fetch}}),a=new P({transport:s,clock:t}),l={gameId:n.gameId,channel:n.channel,matchId:n.matchId,...n.gameRoomId===void 0?{}:{gameRoomId:n.gameRoomId}},d=Gr({client:a,gameId:()=>l.gameId}),c=l.gameRoomId,g=n.endMatch,b=n.log,x=le({client:a,clock:t,gameId:l.gameId,...typeof b=="function"?{log:v=>b.call(n,v)}:{}});return {identity:l,client:a,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);}},analytics:x,functions:new E(d.invokeFunction),challenges:ge(d.listChallenges),...c===void 0?{}:{room:{get:v=>d.getGameRoomV2(c,v),args:async v=>{let y=await d.getGameRoomV2(c,v?.signal===void 0?{}:{signal:v.signal}),h=y.modified?y.body:void 0;if(h?.room_args==null||h.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:h.room_args,room_args_template:h.room_args_template}}}},dispose:()=>{x.dispose(),o.dispose();}}}var Er=["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"],Cr=new Set(Er);function me(n){return typeof n=="string"&&Cr.has(n)?n:"unknown"}var R=class{#e;constructor(e){this.#e=e,Object.freeze(this);}toString(){return "[gem: use gem.text.toPlain()]"}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function q(n){return new R(n)}var pe={toPlain(n){return R.unwrap(n)},compare(n,e,t){let r=n instanceof R?R.unwrap(n):n,o=e instanceof R?R.unwrap(e):e,s;try{s=new Intl.Collator(t);}catch{s=new Intl.Collator;}return s.compare(r,o)},equals(n,e){let t=n instanceof R?R.unwrap(n):n,r=e instanceof R?R.unwrap(e):e;return t.normalize("NFC")===r.normalize("NFC")}};var ye="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 V(n,e={}){let t=e.clock??G,r=()=>{let l=n();if(l===null)throw new Error(ye);return l},o=null,s=()=>{if(o===null)throw new Error(ye);return o};return {server:{get identity(){return s().identity},get client(){return s().client},get api(){return s().api},get match(){return s().match},get analytics(){return s().analytics},get functions(){return s().functions},get challenges(){return s().challenges},get room(){return s().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:q(g),...typeof c.displayTag=="string"&&c.displayTag!==""?{displayTag:q(c.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=F(r(),{...e,clock:t});}}}function fe(n,e={}){let{server:t,attach:r}=V(()=>n,e);return r(),t}function Ir(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:me(e)}}}function he(n,e={}){return ()=>{let t=null,{server:r,attach:o}=V(()=>t,e),s=n(r),a={async init(l){t=l,o(),await s.init?.();},async shutdown(l){let d=Ir(l);try{await s.shutdown?.(d);}finally{r.dispose();}}};return s.join&&(a.join=(l,d)=>s.join?.(l,d)),s.leave&&(a.leave=(l,d)=>s.leave?.(l,d)),s.message&&(a.message=(l,d,c,g)=>s.message?.(l,d,c,g)),a}}var qr=new Set(["unlocked","already_unlocked","suppressed"]);function _e(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"||!qr.has(o.outcome)||typeof o.achievement_id!="string"||o.achievement_id==="")continue;let s=o.outcome;t.push({achievementId:o.achievement_id,progressionDefinitionId:typeof o.progression_definition_id=="string"?o.progression_definition_id:"",points:s==="unlocked"&&typeof o.points=="number"&&Number.isFinite(o.points)?o.points:0,outcome:s,...typeof o.reason=="string"?{reason:o.reason}:{}});}return t}
1
+ var ve=Object.defineProperty;var Re=(n,e)=>{for(var t in e)ve(n,t,{get:e[t],enumerable:true});};globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:7.9.1]";function xe(n,e){return e!==void 0?!e:n==="chain_exhausted"}var $=class{constructor(e){this.options=e;}options;grant=null;state="pending";failure=null;generation=0;inFlight=null;rejected=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.grant&&e>=this.grant.chainEndsAt)throw this.enter("lost","chain_exhausted"),new _("chain_exhausted","the token chain reached its ceiling");return this.refresh(this.nextReason())}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);}refresh(e){if(this.inFlight)return this.inFlight;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 s=Se(o),a=o?.retryable;throw t===this.generation&&this.enter(xe(s,typeof a=="boolean"?a:void 0)?"lost":"degraded",s),o instanceof _?o:new _(s,String(o))}).finally(()=>{this.inFlight===r&&(this.inFlight=null);});return this.inFlight=r,r}enter(e,t){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 Se(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 p=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}},j=["if-match","if-none-match"],W=4096;function ke(n){if(!n)return;let e={};for(let[t,r]of Object.entries(n)){let o=t.toLowerCase();if(!j.includes(o)||r===void 0)continue;let s=typeof r=="string"?we(r):r;if(typeof s!="string"||s.length>W||!Ae(s))throw new p(`the ${o} header value cannot be sent \u2014 it is not a string, is longer than ${W} 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.`);s!==""&&(e[o]=s);}return Object.freeze(e)}function we(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 Ae(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 Te(n){let{bytes:e}=n;if(e!==void 0){if(Object.prototype.toString.call(e)!=="[object Uint8Array]")throw new p("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 p("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 z(n,e){let t=e.replayUnauthorizedOnce??true;return {async request(r){let o={...r},s=ke(o.headers),a=Te(o),l=Object.freeze({...o,headers:s,...a===void 0?{}:{bytes:a}}),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(),b=await n(l,g);if(b.status===401)throw e.tokenSource.close("unavailable"),new _("unavailable","the server refused a freshly minted token");return b}}}function K(n){let e=typeof n=="string"?new TextEncoder().encode(n):n;return btoa(Pe(e))}function Pe(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,s,a){super(`${t} (${r}): ${o}`);this.reason=t;this.status=r;this.detail=o;this.retryAfterSeconds=s;this.code=a;this.name="GemApiError";}reason;status;detail;retryAfterSeconds;code;get retryable(){return this.reason==="unavailable"||this.reason==="rate_limited"}},J=new WeakMap;function X(n){return J.get(n)??{}}var Oe=new Set([408,429,500,502,503,504]),Ge=6e4;function Ee(n){if(n===void 0)return 2;if(!Number.isInteger(n)||n<0||n>10)throw new p(`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 P=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,...C(o)},o.replaySafe===true)}async post(e,t,r,o={}){return this.send({method:"POST",path:e,body:t,signal:r,...C(o)},o.replaySafe===true)}async postBytes(e,t,r,o={}){let s=await this.sendRaw({method:"POST",path:e,bytes:t,responseType:"bytes",signal:r,...C(o)},o.replaySafe===true);return {bytes:Ce(s.body),...s.invocationId===void 0?{}:{invocationId:s.invocationId}}}async patch(e,t,r,o={}){return this.send({method:"PATCH",path:e,body:t,signal:r,...C(o)},o.replaySafe===true)}async delete(e,t,r={}){return this.send({method:"DELETE",path:e,signal:t,...C(r)},r.replaySafe===true)}async send(e,t){return (await this.sendRaw(e,t)).body}async sendRaw(e,t){let r=t?Ee(this.options.maxRetries)+1:1,o=null;if(e.signal?.aborted)throw Y(e.signal);for(let s=0;s<r;s++){if(s>0&&await this.backoff(s,o,e.signal),e.signal?.aborted)throw Y(e.signal);let a;try{a=await this.options.transport.request(e);}catch(d){if(_.isAuthError(d)||p.isRefusal(d)||e.signal?.aborted||Ie(d))throw d;o=new m("unavailable",0,String(d));continue}if(a.status>=200&&a.status<300||a.status===304)return a;let l=qe(a);if(!Oe.has(a.status))throw l;o=l;}throw o??new m("unavailable",0,"no attempt was made")}backoff(e,t,r){if(r?.aborted)return Promise.resolve();let o=t?.retryAfterSeconds,s=o!==void 0?o*1e3:2**(e-1)*250,a=2**(e-1)*250,l=Math.min(Math.max(s,a),Ge);return new Promise(d=>{let c=this.options.clock,g=false,b=false,x,f=()=>{g||(g=true,b&&c.clearTimeout(x),r?.removeEventListener("abort",f),d());};r?.addEventListener("abort",f,{once:true}),x=c.setTimeout(f,l),b=true,g&&c.clearTimeout(x);})}};function Ce(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 C(n){return {...n.keepalive===void 0?{}:{keepalive:n.keepalive},...n.ifMatch===void 0?{}:{headers:{"if-match":n.ifMatch}}}}function Y(n){return n.reason!==void 0?n.reason:new DOMException("The operation was aborted.","AbortError")}function Ie(n){let e=n?.name;return e==="AbortError"||e==="TimeoutError"}function qe(n){let e=$e(n),t=Me(n.body),r={...t===void 0?{}:{details:t},...n.invocationId===void 0?{}:{invocationId:n.invocationId}};return Object.keys(r).length>0&&J.set(e,r),e}var Le=new Map([["insufficient_funds","insufficient_funds"]]);function $e(n){let{status:e,body:t}=n,r=je(t),o=n.retryAfterSeconds??Ue(t),s=Fe(t),a=s===void 0?void 0:Le.get(s);if(a!==void 0)return new m(a,e,r,void 0,s);switch(e){case 304:return new m("not_modified",e,r);case 400:case 422:return new m("invalid",e,r,void 0,s);case 403:return new m("forbidden",e,r,void 0,s);case 404:return new m("not_found",e,r,void 0,s);case 402:return new m("insufficient_funds",e,r,void 0,s);case 409:return new m("conflict",e,r,void 0,s);case 412:return new m("precondition_failed",e,r,void 0,s);case 413:return new m("too_large",e,r,void 0,s);case 429:return new m("rate_limited",e,r,o,s);default:return new m("unavailable",e,r,o,s)}}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 Me(n){let t=n?.error?.details;return t===null?void 0:t}function Fe(n){let t=n?.error?.code;return typeof t=="string"&&t.length>0?t:void 0}function Ue(n){let e=n?.retryAfterSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function Be(n){let e=n.lastIndexOf("@");return (e===-1?n:`***@${n.slice(e+1)}`).slice(0,200)}var Ne=new Set(j);function De(n){if(!n)return {};let e={};for(let[t,r]of Object.entries(n))Ne.has(t.toLowerCase())&&(e[t.toLowerCase()]=r);return e}function Q(n){let e=n.fetch??globalThis.fetch.bind(globalThis);return z(async(t,r)=>{let o;try{o=new URL(n.baseUrl.replace(/\/+$/,""));}catch{throw new p("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 s;try{s=new URL(o.href.replace(/\/+$/,"")+t.path);}catch{throw new p(`${JSON.stringify(typeof t.path=="string"?Be(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(s.protocol!==o.protocol||s.host!==o.host)throw new p(`${JSON.stringify(s.pathname)} resolves to ${s.protocol}//${s.host}, not ${o.protocol}//${o.host}. A request path may not change the request's origin \u2014 it carries the play token.`);if(s.username!==""||s.password!==""){let f=o.username!==""||o.password!=="",v=s.username!==o.username||s.password!==o.password,y=f?v?"baseUrl (and possibly the request path)":"baseUrl":"request path";throw new p(`the ${y} puts credentials in the URL, which cannot be fetched (${t.method} ${s.pathname}). The value is withheld here rather than written to logs. This is a malformed request, not a server failure.`)}for(let[f,v]of Object.entries(n.defaultQuery??{}))s.searchParams.has(f)||s.searchParams.set(f,v);let a=t.bytes,l=t.bytes===void 0?void 0:"application/octet-stream";try{t.body!==void 0&&(a=JSON.stringify(t.body),l="application/json");}catch(f){throw new p(`the body of ${t.method} ${JSON.stringify(s.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(s.toString(),{method:t.method,headers:{authorization:`Bearer ${r}`,...l===void 0?{}:{"content-type":l},...De(t.headers)},body:a,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"),b=He(d.headers.get("retry-after")),x=d.headers.get("x-gem-invocation-id");return {status:d.status,body:c,...g===null?{}:{etag:g},...b===void 0?{}:{retryAfterSeconds:b},...x===null||x===""?{}:{invocationId:x}}},n)}function He(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 Ve="gem-web-bridge";var O=65536,Z=8,M=5e3,ee=1024;function B(n){return Object.freeze(Object.assign(Object.create(null),n))}B({"gem.handshake":30,"gem.handshake.accept":5,"gem.token":30,"gem.token.denied":30,"gem.player":12,"gem.pause":120,"gem.prefs":60,"gem.cohorts":12,"gem.earnAllowanceChanged":30,"gem.viewport":60,"gem.deviceSettings":12,"gem.willTerminate":10,"gem.roomEvent":120,"gem.socketState":12,"gem.seatedEvent":60,"gem.autoStartFailedEvent":30,"gem.signalEvent":1800,"gem.dedicatedEvent":120,"gem.partyResult":30,"gem.clusterTarget":12,"gem.devtools":30,"gem.screenshot":6,"gem.screenshot.denied":12,"gem.requestContext":12,"gem.gameContext":12,"gem.signal":1200,"gem.dedicatedOffer":60,"gem.partyRequest":12,"gem.ready":5,"gem.engaged":5,"gem.progress":600,"gem.requestToken":12,"gem.requestLocalServer":6,"gem.localServer":30,"gem.localServer.denied":30,"gem.exit":5,"gem.openExternal":6,"gem.requestFullscreen":30,"gem.audioState":120,"gem.rewardCue":60,"gem.walletDisplay":60,"gem.menu":60,"gem.menuSelect":60,"gem.requestShare":6,"gem.frameStats":120,"gem.error":60,"gem.requestPurchase":12,"gem.purchaseResult":30,"gem.deviceSettings.put":30,"gem.deviceSettings.result":30,"gem.requestAd":6,"gem.adResult":12,"gem.requestSignIn":6,"gem.signInResult":12,"gem.requestFriendChallenge":12,"gem.friendChallengeResult":30,__malformed:60});B({"gem.requestAd":"ads","gem.adResult":"ads","gem.requestSignIn":"signIn","gem.signInResult":"signIn","gem.requestPurchase":"purchases","gem.purchaseResult":"purchases","gem.requestFriendChallenge":"friendChallenges","gem.friendChallengeResult":"friendChallenges","gem.devtools":"devtools","gem.screenshot":"screenshot","gem.screenshot.denied":"screenshot","gem.requestContext":"feedbackContext","gem.gameContext":"feedbackContext","gem.roomEvent":"rooms","gem.signal":"p2p","gem.signalEvent":"p2p","gem.dedicatedOffer":"dedicated","gem.dedicatedEvent":"dedicated","gem.clusterTarget":"clusterTarget","gem.partyRequest":"parties","gem.partyResult":"parties","gem.autoStartFailedEvent":"autoStartFailure","gem.seatedEvent":"partySeating","gem.socketState":"socketState","gem.audioState":"audioState","gem.rewardCue":"rewardCue","gem.frameStats":"frameStats","gem.engaged":"engagement","gem.viewport":"viewport","gem.walletDisplay":"walletDisplay","gem.requestLocalServer":"localHost","gem.localServer":"localHost","gem.localServer.denied":"localHost","gem.cohorts":"cohorts","gem.earnAllowanceChanged":"earnAllowance","gem.deviceSettings":"deviceSettings","gem.deviceSettings.put":"deviceSettings","gem.deviceSettings.result":"deviceSettings","gem.requestShare":"share","gem.menu":"gameMenu","gem.menuSelect":"gameMenu"});function ze(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 Ke(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 Ye(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function Je(n){return /^[a-z_]+$/.test(n)}function U(n,e,t){if(e>Z)return `nesting deeper than ${Z}`;if(++t.nodes>M)return `more than ${M} values`;if(t.bytes>O)return `over the ${O} 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>ee)return `an array of ${n.length} entries, over the ${ee} limit`;t.bytes+=2;for(let l of n){let d=U(l,e+1,t);if(d)return d}return null}let s=Object.getPrototypeOf(n);if(s!==Object.prototype&&s!==null)return "a value that is not a plain object";t.bytes+=2;let a=n;for(let l in a){if(!Object.prototype.hasOwnProperty.call(a,l))continue;if(++t.nodes>M)return `more than ${M} values`;if(t.bytes+=l.length*3+4,t.bytes>O)return `over the ${O} byte limit`;let d=U(a[l],e+1,t);if(d)return d}return null}function Xe(n){let e={nodes:0,bytes:0,seen:new Set},t=U(n,0,e);return t?`message contains ${t}`:e.bytes>O?`message is over the ${O} byte limit`:null}var Qe={origin:[ze,"not a well-formed origin"],url:[Ke,"not a safe absolute http(s) URL"],bcp47:[Ye,"not a well-formed BCP 47 tag"],code:[Je,"not a code of lower-case letters and underscores"]};function ne(n,e,t){for(let r of e){let o=t===""?r.n:`${t}.${r.n}`,s=n[r.n];if(s==null){if(r.o)continue;return `${o}: required`}let a=te(s,r,o);if(a)return a}return null}function te(n,e,t){switch(e.k){case "string":{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]=Qe[e.f];if(!r(n))return `${t}: ${o}`}return null}case "int":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 "boolean":return typeof n=="boolean"?null:`${t}: expected boolean`;case "enum":{let r=e.v;return r.includes(n)?null:`${t}: not one of ${r.join("|")}`}case "object":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:ne(n,e.fs,t);case "json":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected a plain object`:null;case "array":{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 s of n){if(s==null){if(r.o)continue;return `${o}: required`}let a=te(s,r,o);if(a)return a}return null}default:{let r=e.k;return `${t}: unknown kind ${String(r)}`}}}function u(n,e){return t=>{let r=Xe(t);if(r)return r;if(typeof t!="object"||t===null||Array.isArray(t))return "message: expected object";let o=t;return o.gem!==Ve?"gem: wrong protocol marker":o.type!==n?`type: expected ${n}`:ne(o,e,"")}}var Ze=u("gem.handshake",[{n:"versions",k:"object",fs:[{n:"min",k:"int",lo:1,hi:1e3},{n:"max",k:"int",lo:1,hi:1e3}]},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}},{n:"embedder",k:"string",max:2048,f:"origin"},{n:"unbidden",k:"boolean",o:1}]),en=u("gem.handshake.accept",[{n:"v",k:"int",lo:1,hi:1e3},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}}]),nn=u("gem.token",[{n:"token",k:"string",max:4096},{n:"requestId",k:"string",o:1,max:64},{n:"generation",k:"int",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"string",o:1,max:512,f:"url"},{n:"playerId",k:"string",max:64},{n:"gameId",k:"string",max:64},{n:"channel",k:"enum",v:["dev","test","release"]},{n:"gameVersion",k:"string",o:1,max:64},{n:"expiresAt",k:"int",lo:0,hi:4102444800},{n:"chainEndsAt",k:"int",lo:0,hi:4102444800},{n:"allowDevTools",k:"boolean",o:1}]),tn=u("gem.token.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"retryAfterMs",k:"int",o:1,lo:0,hi:36e5},{n:"reason",k:"enum",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"string",max:64}]),rn=u("gem.player",[{n:"untrusted",k:"object",fs:[{n:"displayName",k:"string",max:64},{n:"displayTag",k:"string",o:1,max:80},{n:"displayHandle",k:"string",max:80}]},{n:"playerId",k:"string",o:1,max:64},{n:"discriminator",k:"string",o:1,max:8},{n:"avatarIconUrl",k:"string",o:1,max:2048,f:"url"},{n:"badges",k:"array",o:1,max:2,it:{n:"",k:"object",fs:[{n:"itemId",k:"string",max:64},{n:"iconUrl",k:"string",max:2048,f:"url"}]}},{n:"displayTag",k:"string",max:8},{n:"avatarUrl",k:"string",o:1,max:2048,f:"url"},{n:"boost",k:"object",o:1,fs:[{n:"multipliers",k:"array",max:8,it:{n:"",k:"object",fs:[{n:"currencyId",k:"string",max:64},{n:"currencySlug",k:"string",max:32},{n:"multiplierBp",k:"int",lo:1e4,hi:1e6}]}},{n:"expiresInDays",k:"int",o:1,lo:1,hi:7}]}]),on=u("gem.pause",[{n:"paused",k:"boolean"}]),sn=u("gem.prefs",[{n:"reducedMotion",k:"boolean"},{n:"muted",k:"boolean"},{n:"showFrameStats",k:"boolean",o:1},{n:"locale",k:"string",max:35,f:"bcp47"}]),an=u("gem.cohorts",[{n:"cohorts",k:"array",max:8,it:{n:"",k:"object",fs:[{n:"experimentId",k:"string",max:36},{n:"variantKey",k:"string",max:32}]}}]),ln=u("gem.earnAllowanceChanged",[]),dn=u("gem.viewport",[{n:"insets",k:"object",fs:[{n:"top",k:"int",lo:0,hi:4096},{n:"right",k:"int",lo:0,hi:4096},{n:"bottom",k:"int",lo:0,hi:4096},{n:"left",k:"int",lo:0,hi:4096}]},{n:"reserved",k:"array",o:1,max:4,it:{n:"",k:"object",fs:[{n:"x",k:"int",lo:0,hi:16384},{n:"y",k:"int",lo:0,hi:16384},{n:"width",k:"int",lo:0,hi:16384},{n:"height",k:"int",lo:0,hi:16384}]}}]),un=u("gem.deviceSettings",[{n:"settings",k:"json",o:1}]),cn=u("gem.willTerminate",[{n:"reason",k:"enum",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"int",lo:0,hi:6e4}]),gn=u("gem.roomEvent",[{n:"event",k:"enum",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"string",max:64},{n:"matchId",k:"string",o:1,max:64},{n:"version",k:"int",o:1,lo:0,hi:2147483647},{n:"reason",k:"string",o:1,max:64},{n:"platform",k:"enum",o:1,v:["universal","mobile"]}]),mn=u("gem.socketState",[{n:"connected",k:"boolean"},{n:"reason",k:"enum",o:1,v:["connecting","dropped","watchdog","terminal"]}]),pn=u("gem.seatedEvent",[{n:"roomId",k:"string",max:64}]),yn=u("gem.autoStartFailedEvent",[{n:"roomId",k:"string",max:64},{n:"code",k:"string",max:64}]),fn=u("gem.signalEvent",[{n:"event",k:"enum",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),hn=u("gem.dedicatedEvent",[{n:"event",k:"enum",v:["answer","error","matchEnded"]},{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",o:1,max:10240},{n:"sessionId",k:"string",o:1,max:64},{n:"code",k:"string",o:1,max:64},{n:"message",k:"string",o:1,max:256},{n:"reason",k:"string",o:1,max:64}]),_n=u("gem.partyResult",[{n:"requestId",k:"string",max:64},{n:"partyId",k:"string",o:1,max:64}]),bn=u("gem.clusterTarget",[{n:"clusterTargetId",k:"string",max:64},{n:"clusterTargetIds",k:"array",o:1,max:3,it:{n:"",k:"string",max:64}}]),vn=u("gem.devtools",[{n:"action",k:"enum",v:["open","close","toggle"]}]),Rn=u("gem.screenshot",[{n:"maxWidth",k:"int",lo:1,hi:7680},{n:"maxHeight",k:"int",lo:1,hi:4320}]),xn=u("gem.screenshot.denied",[{n:"reason",k:"enum",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"boolean"}]),Sn=u("gem.requestContext",[]),kn=u("gem.gameContext",[{n:"context",k:"json"}]),wn=u("gem.signal",[{n:"signal",k:"enum",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),An=u("gem.dedicatedOffer",[{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",max:10240},{n:"intent",k:"enum",v:["initial","ice_restart","full_reconnect"]}]),Tn=u("gem.partyRequest",[{n:"requestId",k:"string",max:64}]),Pn=u("gem.ready",[]),On=u("gem.engaged",[]),Gn=u("gem.progress",[{n:"loaded",k:"int",lo:0,hi:1099511627776},{n:"total",k:"int",lo:0,hi:1099511627776}]),En=u("gem.requestToken",[{n:"requestId",k:"string",max:64},{n:"reason",k:"enum",v:["initial","expiring","rejected"]}]),Cn=u("gem.requestLocalServer",[{n:"requestId",k:"string",max:64},{n:"gameRoomId",k:"string",max:64}]),In=u("gem.localServer",[{n:"requestId",k:"string",max:64},{n:"serverId",k:"string",o:1,max:128}]),qn=u("gem.localServer.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"reason",k:"enum",v:["refused","unavailable"]}]),Ln=u("gem.exit",[{n:"reason",k:"string",o:1,max:64}]),$n=u("gem.openExternal",[{n:"url",k:"string",max:2048,f:"url"}]),jn=u("gem.requestFullscreen",[{n:"enabled",k:"boolean"}]),Mn=u("gem.audioState",[{n:"muted",k:"boolean"}]),Fn=u("gem.rewardCue",[{n:"currencySlug",k:"string",max:32},{n:"expected",k:"int",o:1,lo:1,hi:1e9},{n:"origin",k:"object",o:1,fs:[{n:"x",k:"int",lo:0,hi:16384},{n:"y",k:"int",lo:0,hi:16384}]}]),Un=u("gem.walletDisplay",[{n:"visible",k:"boolean"},{n:"currencies",k:"array",o:1,max:8,it:{n:"",k:"string",max:64}},{n:"score",k:"boolean",o:1}]),Bn=u("gem.menu",[{n:"settings",k:"boolean"},{n:"items",k:"array",o:1,max:4,it:{n:"",k:"object",fs:[{n:"id",k:"string",max:32},{n:"label",k:"string",max:40}]}}]),Nn=u("gem.menuSelect",[{n:"entry",k:"enum",v:["settings","item"]},{n:"id",k:"string",o:1,max:32}]),Dn=u("gem.requestShare",[{n:"params",k:"array",max:16,it:{n:"",k:"object",fs:[{n:"key",k:"string",max:64},{n:"value",k:"string",max:512}]}}]),Hn=u("gem.frameStats",[{n:"fps",k:"int",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"int",lo:0,hi:1e5}]),Vn=u("gem.error",[{n:"code",k:"enum",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"string",o:1,max:256}]),Wn=u("gem.requestPurchase",[{n:"requestId",k:"string",max:64},{n:"purchaseKind",k:"enum",v:["item","recipe"]},{n:"targetId",k:"string",max:64},{n:"currencySlug",k:"string",max:32},{n:"quantity",k:"int",o:1,lo:1,hi:10},{n:"catalogId",k:"string",o:1,max:64}]),zn=u("gem.purchaseResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["ok","declined","unavailable"]},{n:"reason",k:"string",o:1,max:64,f:"code"},{n:"purchaseId",k:"string",o:1,max:64}]),Kn=u("gem.deviceSettings.put",[{n:"requestId",k:"string",max:64},{n:"settings",k:"json"}]),Yn=u("gem.deviceSettings.result",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["stored","too_large","unavailable"]}]),Jn=u("gem.requestAd",[{n:"requestId",k:"string",max:64},{n:"placement",k:"string",max:32},{n:"format",k:"enum",v:["interstitial","rewarded"]}]),Xn=u("gem.adResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["shown","no_ad","unavailable"]}]),Qn=u("gem.requestSignIn",[{n:"requestId",k:"string",max:64}]),Zn=u("gem.signInResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["signed_in","declined","unavailable"]}]),et=u("gem.requestFriendChallenge",[{n:"requestId",k:"string",max:64},{n:"playerId",k:"string",max:64},{n:"template",k:"string",max:64},{n:"params",k:"json",o:1}]),nt=u("gem.friendChallengeResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["accepted","cancelled","refused","unavailable","rate_limited","invalid"]},{n:"code",k:"string",o:1,max:64},{n:"param",k:"string",o:1,max:64},{n:"channel",k:"string",o:1,max:16},{n:"configVersion",k:"int",o:1,lo:0,hi:9007199254740991},{n:"retryAfterMs",k:"int",o:1,lo:0,hi:864e5},{n:"detail",k:"string",o:1,max:300}]);B({"gem.handshake":Ze,"gem.handshake.accept":en,"gem.token":nn,"gem.token.denied":tn,"gem.player":rn,"gem.pause":on,"gem.prefs":sn,"gem.cohorts":an,"gem.earnAllowanceChanged":ln,"gem.viewport":dn,"gem.deviceSettings":un,"gem.willTerminate":cn,"gem.roomEvent":gn,"gem.socketState":mn,"gem.seatedEvent":pn,"gem.autoStartFailedEvent":yn,"gem.signalEvent":fn,"gem.dedicatedEvent":hn,"gem.partyResult":_n,"gem.clusterTarget":bn,"gem.devtools":vn,"gem.screenshot":Rn,"gem.screenshot.denied":xn,"gem.requestContext":Sn,"gem.gameContext":kn,"gem.signal":wn,"gem.dedicatedOffer":An,"gem.partyRequest":Tn,"gem.ready":Pn,"gem.engaged":On,"gem.progress":Gn,"gem.requestToken":En,"gem.requestLocalServer":Cn,"gem.localServer":In,"gem.localServer.denied":qn,"gem.exit":Ln,"gem.openExternal":$n,"gem.requestFullscreen":jn,"gem.audioState":Mn,"gem.rewardCue":Fn,"gem.walletDisplay":Un,"gem.menu":Bn,"gem.menuSelect":Nn,"gem.requestShare":Dn,"gem.frameStats":Hn,"gem.error":Vn,"gem.requestPurchase":Wn,"gem.purchaseResult":zn,"gem.deviceSettings.put":Kn,"gem.deviceSettings.result":Yn,"gem.requestAd":Jn,"gem.adResult":Xn,"gem.requestSignIn":Qn,"gem.signInResult":Zn,"gem.requestFriendChallenge":et,"gem.friendChallengeResult":nt});var G={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)};var tt=1e4;function re(n,e){return N(n,e)}function N(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=a=>({token:a.token,expiresAt:a.expiresAt,chainEndsAt:Number.POSITIVE_INFINITY}),r=null,o=new $({clock:e.clock,...e.onStateChange===void 0?{}:{onStateChange:e.onStateChange},request:()=>new Promise((a,l)=>{let d=e.clock.setTimeout(()=>{r=null,l({reason:"unavailable",retryable:true});},e.timeoutMs??tt);r={resolve:c=>{e.clock.clearTimeout(d),a(c);},reject:l,timer:d};})}),s=n.onServerToken(a=>{let l=t(a),d=r;if(d){r=null,d.resolve(l);return}o.accept(l);});return {source:o,dispose(){s(),r&&(e.clock.clearTimeout(r.timer),r.reject({reason:"unavailable",retryable:false}),r=null);}}}var H={};Re(H,{acceptTransfer:()=>rt,addEntityProgression:()=>ot,adminAction:()=>st,cancelInventoryTransfer:()=>it,claimEntityProgressionRewards:()=>at,closeGameRoom:()=>lt,createEntityBatchOrder:()=>dt,createEntityOrder:()=>ut,createSession:()=>ct,deleteEntityGameSetting:()=>gt,deleteEntitySave:()=>mt,deleteSession:()=>pt,deleteShowcaseValue:()=>yt,executeEntityRecipe:()=>ft,finalizeSaveUpload:()=>ht,getChannelAssignment:()=>_t,getDropRates:()=>bt,getEntityCurrency:()=>vt,getEntityGameSetting:()=>Rt,getEntityInventory:()=>xt,getEntityInventoryItem:()=>St,getEntityLeaderboard:()=>kt,getEntityOrder:()=>wt,getEntityProgression:()=>At,getEntityRecipeAvailability:()=>Tt,getEntityRecipeUsage:()=>Pt,getEntitySave:()=>Ot,getEvent:()=>Gt,getGameRoomV2:()=>Et,getLeaderboard:()=>Ct,getPlayerGameProfile:()=>It,getPurchaseCatalog:()=>qt,getResolvedTemplate:()=>Lt,getRoomArgs:()=>$t,getShowcaseValue:()=>jt,getTransferDetails:()=>Mt,ingestAnalyticsEvents:()=>D,initiateInventoryTransfer:()=>Ft,invokeFunction:()=>Ut,kickPlayer:()=>Bt,listChallenges:()=>Nt,listEntityGameSettings:()=>Dt,listEntityOrders:()=>Ht,listEntityProgressions:()=>Vt,listEntitySaves:()=>Wt,listEvents:()=>zt,listGameRooms:()=>Kt,listResolvedTemplates:()=>Yt,listTransfers:()=>Jt,maxEntityProgression:()=>Xt,putEntityGameSetting:()=>Qt,putRoomArgs:()=>Zt,putShowcaseValue:()=>er,rejectTransfer:()=>nr,requestSaveUploadUrl:()=>tr,resetEntityProgression:()=>rr,simulateEntityOrder:()=>or,transferHostV2:()=>sr,updateGameRoomV2:()=>ir});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 rt(n,e,t){let r=`/v1/inventory/transfers/${i(e)}/accept`;return n.client.post(r,void 0,t?.signal)}async function ot(n,e,t,r,o,s){let a=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/add`;return n.client.post(a,o,s?.signal)}async function st(n,e,t,r){let o=`/v1/voice/sessions/${i(e)}/admin`;return n.client.post(o,t,r?.signal)}async function it(n,e,t){let r=`/v1/inventory/transfers/${i(e)}/cancel`;return n.client.post(r,void 0,t?.signal)}async function at(n,e,t,r,o,s){let a=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/claim`;return n.client.post(a,o,s?.signal)}async function lt(n,e,t){let r=`/v1/games/${i(n.gameId())}/game-rooms/${i(e)}`;return n.client.delete(r,t?.signal)}async function dt(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/orders/batch`;return n.client.post(s,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function ut(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/orders`;return n.client.post(s,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function ct(n,e,t){return n.client.post("/v1/voice/sessions",e,t?.signal)}async function gt(n,e,t,r,o){let s=`/v1/settings/${i(e)}/${i(t)}/${i(r)}`;return n.client.delete(s,o?.signal)}async function mt(n,e,t,r,o){let s=`/v1/saves/${i(e)}/${i(t)}/${i(r)}`;return n.client.delete(s,o?.signal)}async function pt(n,e,t){let r=`/v1/voice/sessions/${i(e)}`;return n.client.delete(r,t?.signal)}async function yt(n,e,t,r){let o=`/v1/showcase/players/${i(e)}/${i(t)}`;return n.client.delete(o,r?.signal)}async function ft(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/recipes/execute`;return n.client.post(s,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function ht(n,e,t,r,o,s){let a=`/v1/saves/${i(e)}/${i(t)}/${i(r)}/finalize`;return n.client.post(a,o,s?.signal)}async function _t(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 bt(n,e,t){let r=`/v1/inventory/loot-tables/${i(e)}/drop-rates`;return n.client.get(r,t?.signal)}async function vt(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/currencies/${i(r)}`;return n.client.get(s,o?.signal)}async function Rt(n,e,t,r,o){let s=`/v1/settings/${i(e)}/${i(t)}/${i(r)}`;return n.client.getWithEtag(s,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function xt(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 s=o.toString(),a=`/v1/inventory/${i(e)}/${i(t)}`+(s?`?${s}`:"");return n.client.get(a,r?.signal)}async function St(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/items/${i(r)}`;return n.client.get(s,o?.signal)}async function kt(n,e,t,r,o){let s=new URLSearchParams;o?.bucket_1!==void 0&&s.set("bucket_1",String(o?.bucket_1)),o?.bucket_2!==void 0&&s.set("bucket_2",String(o?.bucket_2)),o?.limit!==void 0&&s.set("limit",String(o?.limit)),o?.periods_back!==void 0&&s.set("periods_back",String(o?.periods_back)),o?.period!==void 0&&s.set("period",String(o?.period)),o?.player_id!==void 0&&s.set("player_id",String(o?.player_id));let a=s.toString(),l=`/v1/leaderboards/${i(e)}/${i(t)}/${i(r)}`+(a?`?${a}`:"");return n.client.get(l,o?.signal)}async function wt(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/orders/${i(r)}`;return n.client.get(s,o?.signal)}async function At(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}`;return n.client.get(s,o?.signal)}async function Tt(n,e,t,r,o,s){let a=`/v1/inventory/${i(e)}/${i(t)}/catalogs/${i(r)}/recipes/${i(o)}/availability`;return n.client.get(a,s?.signal)}async function Pt(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit));let s=o.toString(),a=`/v1/inventory/${i(e)}/${i(t)}/recipe-usage`+(s?`?${s}`:"");return n.client.get(a,r?.signal)}async function Ot(n,e,t,r,o){let s=`/v1/saves/${i(e)}/${i(t)}/${i(r)}`;return n.client.getWithEtag(s,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function Gt(n,e,t){let r=`/v1/events/${i(e)}`;return n.client.get(r,t?.signal)}async function Et(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 Ct(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(),s=`/v1/leaderboards/${i(e)}`+(o?`?${o}`:"");return n.client.get(s,t?.signal)}async function It(n,e,t){let r=`/v1/profiles/players/${i(e)}`;return n.client.get(r,t?.signal)}async function qt(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 Lt(n,e,t){let r=`/v1/game-room-templates/${i(e)}`;return n.client.get(r,t?.signal)}async function $t(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 jt(n,e,t,r){let o=`/v1/showcase/players/${i(e)}/${i(t)}`;return n.client.get(o,r?.signal)}async function Mt(n,e,t){let r=`/v1/inventory/transfers/${i(e)}`;return n.client.get(r,t?.signal)}async function D(n,e,t){let r=`/v1/games/${i(n.gameId())}/analytics/events`;return n.client.post(r,e,t?.signal,{replaySafe:true})}async function Ft(n,e,t){return n.client.post("/v1/inventory/transfers",e,t?.signal)}async function Ut(n,e,t){return n.client.postBytes("/v1/functions/invoke",e,t?.signal)}async function Bt(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 Nt(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 Dt(n,e,t,r){let o=`/v1/settings/${i(e)}/${i(t)}`;return n.client.get(o,r?.signal)}async function Ht(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 s=o.toString(),a=`/v1/inventory/${i(e)}/${i(t)}/orders`+(s?`?${s}`:"");return n.client.get(a,r?.signal)}async function Vt(n,e,t,r){let o=`/v1/inventory/${i(e)}/${i(t)}/progressions`;return n.client.get(o,r?.signal)}async function Wt(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 s=o.toString(),a=`/v1/saves/${i(e)}/${i(t)}`+(s?`?${s}`:"");return n.client.get(a,r?.signal)}async function zt(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 Kt(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 Yt(n,e){return n.client.get("/v1/game-room-templates",e?.signal)}async function Jt(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 Xt(n,e,t,r,o,s){let a=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/max`;return n.client.post(a,o,s?.signal)}async function Qt(n,e,t,r,o,s){let a=`/v1/settings/${i(e)}/${i(t)}/${i(r)}`;return n.client.put(a,o,s?.signal,{...s?.ifMatch===void 0?{}:{ifMatch:s.ifMatch}})}async function Zt(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 er(n,e,t,r,o){let s=`/v1/showcase/players/${i(e)}/${i(t)}`;return n.client.put(s,r,o?.signal)}async function nr(n,e,t){let r=`/v1/inventory/transfers/${i(e)}/reject`;return n.client.post(r,void 0,t?.signal)}async function tr(n,e,t,r,o,s){let a=`/v1/saves/${i(e)}/${i(t)}/${i(r)}/upload-url`;return n.client.post(a,o,s?.signal,{replaySafe:true})}async function rr(n,e,t,r,o,s){let a=`/v1/inventory/${i(e)}/${i(t)}/progressions/${i(r)}/reset`;return n.client.post(a,o,s?.signal)}async function or(n,e,t,r,o){let s=`/v1/inventory/${i(e)}/${i(t)}/orders/simulate`;return n.client.post(s,r,o?.signal)}async function sr(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 ir(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 oe="gem_";var dr=1e4,ur=50,cr=1e3,gr=65536-4*1024,se=n=>typeof n=="number"?n:0,mr=n=>typeof n=="string"?n:"";function ie(){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 pr(n){return n?.retryable===true}function yr(n,e){let t=n??{},r=Array.isArray(t.rejected)?t.rejected.map(o=>{let s=o??{};return {index:se(s.index),code:mr(s.code)}}):[];return {accepted:se(t.accepted),rejected:r,dropped:e,duplicate:t.duplicate===true}}function ae(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 le(n){let e=Math.max(1,Math.floor(n.maxQueue??cr)),t={client:n.client,gameId:()=>n.gameId},r=[],o=0,s=null,a=false,l=false,d=false,c=false,g=y=>{n.log?.(y);},b=()=>{s!==null&&(n.clock.clearTimeout(s),s=null);},x=()=>{s!==null||a||l||(s=n.clock.setTimeout(()=>{s=null,v().catch(()=>{});},dr));},f=()=>{let y=Math.min(r.length,100),h=128;for(let w=0;w<y;w+=1){let A=r[w];if(A===void 0)break;if(h+=JSON.stringify(ae(A,0)).length+1,h>gr)return Math.max(1,w)}return y};async function v(y){if(r.length===0)return {accepted:0,rejected:[],dropped:0,duplicate:false};b();let h=r.splice(0,f()),w=o;o=0;let A=Math.round(n.clock.now()),L={batch_id:ie(),sent_at_ms:A,events:h.map(S=>ae(S,A))};l=true;try{let S=await D(t,L,y===void 0?void 0:{signal:y}),T=yr(S,w);for(let be of T.rejected)g(`[gem] analytics: an event was refused (${be.code}). See the analytics_events section of your game config.`);return T}catch(S){if(pr(S))for(r=[...h,...r],o+=w;r.length>e;)r.shift(),o+=1;else g(`[gem] analytics: ${h.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(S)}`);throw S}finally{l=false,r.length>0&&x();}}return {track(y,h,w={}){if(a)return;if(typeof y!="string"||y===""){c||(c=true,g(`[gem] analytics: '${h}' 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(h.startsWith(oe)){d||(d=true,g(`[gem] analytics: '${h}' 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 A={},L={};for(let[S,T]of Object.entries(w))typeof T=="string"?A[S]=T:typeof T=="number"&&Number.isFinite(T)&&(L[S]=T);for(;r.length>=e;)r.shift(),o+=1;r.push({uid:ie(),playerId:y,name:h,atMs:n.clock.now(),dimensions:A,measures:L}),r.length>=ur?v().catch(()=>{}):x();},flush:y=>v(y),get pending(){return r.length},dispose(){a=true,b(),r=[],o=0;}}}var fr=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]]),I=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:fr.get(this.code))??super.retryable}},E=class{#e;constructor(e){this.#e=e;}async invoke(e,t={}){let r=hr(e),o;try{o=await this.#e(r,t.signal===void 0?{}:{signal:t.signal});}catch(s){throw s instanceof m?br(s):s}return _r(o)}};function hr(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 p(`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 p(`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 _r(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 br(n){let{details:e,invocationId:t}=X(n),o=e?.untrusted?.message,s=e?.reason;return new I(n,{...t===void 0?{}:{invocationId:t},...n.code==="function_error"&&typeof o=="string"?{functionMessage:o}:{},...n.code==="function_failed"&&typeof s=="string"?{failure:s}:{}})}var k=n=>typeof n=="string"?n:"",vr=/(?:Z|[+-]\d{2}:?\d{2})$/i;function de(n){let e=k(n);if(!vr.test(e))return 0;let t=Date.parse(e);return Number.isFinite(t)?Math.floor(t/1e3):0}var Rr=/^[0-9a-f]{1,64}$/,xr=/^[0-9a-f]{16}$/,Sr=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,kr=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function wr(n){let e=k(n),t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!t)return;let[r,o,s]=[Number(t[1]),Number(t[2]),Number(t[3])],a=new Date(Date.UTC(r,o-1,s));return a.getUTCFullYear()===r&&a.getUTCMonth()===o-1&&a.getUTCDate()===s?e:void 0}var Ar=4096,Tr=new TextEncoder;function Pr(n){let e=k(n.challenge_data),t=k(n.challenge_data_hash);return e===""||!xr.test(t)?{}:Tr.encode(e).length>Ar?{}:{data:e,dataHash:t}}function Or(n){let e=n??{},t=de(e.period_start_at),r=de(e.period_ends_at);if(t===0||r===0)return;let o=k(e.slug),s=k(e.seed),a=wr(e.period_local_date),l=k(e.boundary),d=k(e.reset_time);return {id:k(e.progression_definition_id),...o===""?{}:{slug:o},window:k(e.window),periodStartAt:t,periodEndsAt:r,...a===void 0?{}:{periodLocalDate:a},boundary:Sr.test(l)?l:"",resetTime:kr.test(d)?d:"",seed:Rr.test(s)?s:"",...Pr(e)}}function ue(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 ce(n){let e=n??{};return Array.isArray(e.challenges)?e.challenges.map(Or).filter(t=>t!==void 0):[]}function ge(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().");ue(r);let s=await n({player_id:t,...r===void 0?{}:{periods_back:r},...o===void 0?{}:{signal:o}});return ce(s)}}}function Gr(n){let e={};for(let[t,r]of Object.entries(H))if(typeof r=="function"){let o=r;e[t]=(...s)=>o(n,...s);}return e}function F(n,e={}){let t=e.clock??G,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=N(n,{clock:t,...e.onAuthStateChange===void 0?{}:{onStateChange:e.onAuthStateChange}}),s=Q({baseUrl:r,tokenSource:o.source,defaultQuery:{game_id:n.gameId,channel:n.channel},...e.fetch===void 0?{}:{fetch:e.fetch}}),a=new P({transport:s,clock:t}),l={gameId:n.gameId,channel:n.channel,matchId:n.matchId,...n.gameRoomId===void 0?{}:{gameRoomId:n.gameRoomId}},d=Gr({client:a,gameId:()=>l.gameId}),c=l.gameRoomId,g=n.endMatch,b=n.log,x=le({client:a,clock:t,gameId:l.gameId,...typeof b=="function"?{log:v=>b.call(n,v)}:{}});return {identity:l,client:a,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);}},analytics:x,functions:new E(d.invokeFunction),challenges:ge(d.listChallenges),...c===void 0?{}:{room:{get:v=>d.getGameRoomV2(c,v),args:async v=>{let y=await d.getGameRoomV2(c,v?.signal===void 0?{}:{signal:v.signal}),h=y.modified?y.body:void 0;if(h?.room_args==null||h.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:h.room_args,room_args_template:h.room_args_template}}}},dispose:()=>{x.dispose(),o.dispose();}}}var Er=["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"],Cr=new Set(Er);function me(n){return typeof n=="string"&&Cr.has(n)?n:"unknown"}var R=class{#e;constructor(e){this.#e=e,Object.freeze(this);}toString(){return "[gem: use gem.text.toPlain()]"}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function q(n){return new R(n)}var pe={toPlain(n){return R.unwrap(n)},compare(n,e,t){let r=n instanceof R?R.unwrap(n):n,o=e instanceof R?R.unwrap(e):e,s;try{s=new Intl.Collator(t);}catch{s=new Intl.Collator;}return s.compare(r,o)},equals(n,e){let t=n instanceof R?R.unwrap(n):n,r=e instanceof R?R.unwrap(e):e;return t.normalize("NFC")===r.normalize("NFC")}};var ye="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 V(n,e={}){let t=e.clock??G,r=()=>{let l=n();if(l===null)throw new Error(ye);return l},o=null,s=()=>{if(o===null)throw new Error(ye);return o};return {server:{get identity(){return s().identity},get client(){return s().client},get api(){return s().api},get match(){return s().match},get analytics(){return s().analytics},get functions(){return s().functions},get challenges(){return s().challenges},get room(){return s().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:q(g),...typeof c.displayTag=="string"&&c.displayTag!==""?{displayTag:q(c.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=F(r(),{...e,clock:t});}}}function fe(n,e={}){let{server:t,attach:r}=V(()=>n,e);return r(),t}function Ir(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:me(e)}}}function he(n,e={}){return ()=>{let t=null,{server:r,attach:o}=V(()=>t,e),s=n(r),a={async init(l){t=l,o(),await s.init?.();},async shutdown(l){let d=Ir(l);try{await s.shutdown?.(d);}finally{r.dispose();}}};return s.join&&(a.join=(l,d)=>s.join?.(l,d)),s.leave&&(a.leave=(l,d)=>s.leave?.(l,d)),s.message&&(a.message=(l,d,c,g)=>s.message?.(l,d,c,g)),a}}var qr=new Set(["unlocked","already_unlocked","suppressed"]);function _e(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"||!qr.has(o.outcome)||typeof o.achievement_id!="string"||o.achievement_id==="")continue;let s=o.outcome;t.push({achievementId:o.achievement_id,progressionDefinitionId:typeof o.progression_definition_id=="string"?o.progression_definition_id:"",points:s==="unlocked"&&typeof o.points=="number"&&Number.isFinite(o.points)?o.points:0,outcome:s,...typeof o.reason=="string"?{reason:o.reason}:{}});}return t}
2
2
  export{_ as AuthError,j as CONDITIONAL_HEADERS,E as FunctionsApi,m as GemApiError,P as GemClient,I as GemFunctionError,R as PlayerText,p as TransportRefusal,_e as achievementReceipts,q as asPlayerText,F as createGemServer,re as createHostTokenSource,fe as createMatchServer,he as defineServer,G as systemClock,pe as text,K as toBase64};//# sourceMappingURL=gem-web-sdk.server.js.map
3
3
  //# sourceMappingURL=gem-web-sdk.server.js.map
@@ -1,6 +1,6 @@
1
1
  # The browser surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/sdk` v7.9.0. Every symbol below links to its page on the Gem Arcade developer site.
3
+ Generated from `@indiegems/gem-web-sdk/sdk` v7.9.1. Every symbol below links to its page on the Gem Arcade developer site.
4
4
 
5
5
  `@indiegems/gem-web-sdk/sdk` is the one import a game writes, wherever its code runs. `@indiegems/gem-web-sdk/game` exports exactly the symbols on this page and nothing else, for a build that wants only this half.
6
6
 
@@ -6794,7 +6794,7 @@ readonly reserved: readonly GemReservedArea[]
6794
6794
  ```
6795
6795
 
6796
6796
  Rectangles of your frame the arcade's own controls cover — its menu button
6797
- in the top-right corner, and the wallets beside it while they are shown (see
6797
+ in the top-right corner, and the wallets in the middle of the top row while they are shown (see
6798
6798
  `setWalletVisible`). Keep essential UI and touch targets out of them. Empty
6799
6799
  when the arcade covers nothing.
6800
6800
 
@@ -7755,8 +7755,13 @@ setWalletVisible(visible: boolean, options?: WalletVisibleOptions): boolean
7755
7755
  ```
7756
7756
 
7757
7757
  Show or hide the player's wallets — Gems, Tickets, the achievement score —
7758
- that the arcade draws over your game. **They are shown until you say
7759
- otherwise**: hide them during gameplay, show them again on your menus.
7758
+ that an embedder draws over your game.
7759
+
7760
+ **The Gem Arcade no longer acts on this** (since 2026-10-04): it shows
7761
+ every wallet the whole time, during play too, and this call — still
7762
+ accepted, still returning `true` there — hides nothing. Lay every screen
7763
+ out below the arcade's row (`gem.viewport.reserved`). Another embedder
7764
+ may still honour it, where it works as described below.
7760
7765
 
7761
7766
  ```js
7762
7767
  level.onStart = () => gem.setWalletVisible(false);
@@ -7768,10 +7773,9 @@ ticketStore.onOpen = () => gem.setWalletVisible(true, { only: ['ARCADE_TICKETS']
7768
7773
  **It is screen state, not a toggle.** Each call is the whole answer and
7769
7774
  replaces the last. While hidden, the arcade still pops a wallet up for a
7770
7775
  moment when something happens to it — a reward you cued, a spend, a
7771
- landing — and your state never cancels that. Shown wallets cover part of
7772
- your frame's top-right corner, beside the arcade's menu button, which
7773
- arrives as a rectangle in `gem.viewport.reserved`; hiding them gives that
7774
- space back. A wallet the
7776
+ landing — and your state never cancels that. Shown wallets cover the
7777
+ middle of your frame's top row, each arriving as a rectangle in
7778
+ `gem.viewport.reserved`; hiding them gives that space back. A wallet the
7775
7779
  arcade pops up for a moment floats over your game and moves nothing.
7776
7780
 
7777
7781
  **Never draw a platform balance yourself**, and never show a pending state
@@ -1,6 +1,6 @@
1
1
  # The server surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/sdk` v7.9.0. Every symbol below links to its page on the Gem Arcade developer site.
3
+ Generated from `@indiegems/gem-web-sdk/sdk` v7.9.1. Every symbol below links to its page on the Gem Arcade developer site.
4
4
 
5
5
  `@indiegems/gem-web-sdk/sdk` is the one import a game writes, wherever its code runs. `@indiegems/gem-web-sdk/server` exports exactly the symbols on this page and nothing else, for a build that wants only this half.
6
6
 
@@ -2,7 +2,7 @@
2
2
  "schema_version": 1,
3
3
  "source": {
4
4
  "repo": "IndieGems/gem-web-sdk",
5
- "version": "7.9.0"
5
+ "version": "7.9.1"
6
6
  },
7
7
  "entries": [
8
8
  {
@@ -8218,7 +8218,7 @@
8218
8218
  "url": "https://gemarcade.com/developer/api/game#gemviewport-reserved",
8219
8219
  "signature": "readonly reserved: readonly GemReservedArea[]",
8220
8220
  "documented": true,
8221
- "summary": "Rectangles of your frame the arcade's own controls cover — its menu button\nin the top-right corner, and the wallets beside it while they are shown (see\n`setWalletVisible`). Keep essential UI and touch targets out of them. Empty\nwhen the arcade covers nothing.\n\nA stylesheet reads the per-corner custom properties the SDK stamps from\nthese instead — `--gem-reserved-tl-height` and friends.",
8221
+ "summary": "Rectangles of your frame the arcade's own controls cover — its menu button\nin the top-right corner, and the wallets in the middle of the top row while they are shown (see\n`setWalletVisible`). Keep essential UI and touch targets out of them. Empty\nwhen the arcade covers nothing.\n\nA stylesheet reads the per-corner custom properties the SDK stamps from\nthese instead — `--gem-reserved-tl-height` and friends.",
8222
8222
  "deprecated": null,
8223
8223
  "params": [],
8224
8224
  "returns": null,
@@ -9198,7 +9198,7 @@
9198
9198
  "url": "https://gemarcade.com/developer/api/game#gem-setwalletvisible",
9199
9199
  "signature": "setWalletVisible(visible: boolean, options?: WalletVisibleOptions): boolean",
9200
9200
  "documented": true,
9201
- "summary": "Show or hide the player's wallets — Gems, Tickets, the achievement score —\nthat the arcade draws over your game. **They are shown until you say\notherwise**: hide them during gameplay, show them again on your menus.\n\n```js\nlevel.onStart = () => gem.setWalletVisible(false);\nmenu.onOpen = () => gem.setWalletVisible(true);\n// A screen that sells in one currency may narrow it:\nticketStore.onOpen = () => gem.setWalletVisible(true, { only: ['ARCADE_TICKETS'] });\n```\n\n**It is screen state, not a toggle.** Each call is the whole answer and\nreplaces the last. While hidden, the arcade still pops a wallet up for a\nmoment when something happens to it — a reward you cued, a spend, a\nlanding — and your state never cancels that. Shown wallets cover part of\nyour frame's top-right corner, beside the arcade's menu button, which\narrives as a rectangle in `gem.viewport.reserved`; hiding them gives that\nspace back. A wallet the\narcade pops up for a moment floats over your game and moves nothing.\n\n**Never draw a platform balance yourself**, and never show a pending state\nfor one: the arcade takes every figure from the platform. If this returns\n`false`, do nothing in its place.",
9201
+ "summary": "Show or hide the player's wallets — Gems, Tickets, the achievement score —\nthat an embedder draws over your game.\n\n**The Gem Arcade no longer acts on this** (since 2026-10-04): it shows\nevery wallet the whole time, during play too, and this call — still\naccepted, still returning `true` there — hides nothing. Lay every screen\nout below the arcade's row (`gem.viewport.reserved`). Another embedder\nmay still honour it, where it works as described below.\n\n```js\nlevel.onStart = () => gem.setWalletVisible(false);\nmenu.onOpen = () => gem.setWalletVisible(true);\n// A screen that sells in one currency may narrow it:\nticketStore.onOpen = () => gem.setWalletVisible(true, { only: ['ARCADE_TICKETS'] });\n```\n\n**It is screen state, not a toggle.** Each call is the whole answer and\nreplaces the last. While hidden, the arcade still pops a wallet up for a\nmoment when something happens to it — a reward you cued, a spend, a\nlanding — and your state never cancels that. Shown wallets cover the\nmiddle of your frame's top row, each arriving as a rectangle in\n`gem.viewport.reserved`; hiding them gives that space back. A wallet the\narcade pops up for a moment floats over your game and moves nothing.\n\n**Never draw a platform balance yourself**, and never show a pending state\nfor one: the arcade takes every figure from the platform. If this returns\n`false`, do nothing in its place.",
9202
9202
  "deprecated": null,
9203
9203
  "params": [
9204
9204
  {
package/docs/changelog.md CHANGED
@@ -16,6 +16,75 @@ Its entries are grouped under up to five headings:
16
16
  - **Rebuild**: a type changed. Recompile against the new version; code that compiles today keeps compiling unless the entry says otherwise.
17
17
  - **New capability**: something a game can now do. Nothing changes unless you use it.
18
18
 
19
+ ## 7.9.1
20
+
21
+ Upgrading from 7.9.0. Impact: none.
22
+
23
+ Nothing in this release asks anything of a game.
24
+
25
+ ## 7.9.0
26
+
27
+ Upgrading from 7.8.1. Impact: required.
28
+
29
+ ### Must change
30
+
31
+ - A link your game shares can no longer carry a parameter named build. The Arcade now reads that key for itself and removes it before your game starts, so the share request refuses it with a TypeError that names the key. Rename the parameter if your game shares one by that name.
32
+
33
+ ### Rebuild
34
+
35
+ - GemCapability gained gameMenu, and the bridge's message lists and unions in both directions gained the two new menu messages. A switch that assumes it knows every GemCapability value must handle the new one. Other code that compiles today keeps compiling.
36
+
37
+ ### New capability
38
+
39
+ - gem.setMenu adds to the Arcade's menu, the one control the Arcade keeps over a game in its top right corner. Give onSettings and the menu gains a settings entry that opens your own settings screen, and give items for up to four entries of your own, each with an id, a label you have already translated and an onSelect handler. Each call is the whole answer and replaces the last, so call it again when the entries change. It returns true when the Arcade was told. After awaitBridge has settled, draw a settings button of your own only when it returns false. The Arcade pauses your game while its menu is open and resumes it before your handler runs.
40
+
41
+ ## 7.8.1
42
+
43
+ Upgrading from 7.8.0. Impact: none.
44
+
45
+ Nothing in this release asks anything of a game.
46
+
47
+ ## 7.8.0
48
+
49
+ Upgrading from 7.7.0. Impact: recommended.
50
+
51
+ ### May stop
52
+
53
+ - The SDK now stops accidental text selection, the long-press copy menu and the tap highlight across your game's document, so a game can drop its own rules for that. Your own style rules always win, and inputs, text areas and editable content stay typeable and selectable. Text a player could select and copy before no longer is, unless your own styles make it selectable. Pass selectableText as true to createGem only if your game is mostly text a player should be able to copy.
54
+
55
+ ### New capability
56
+
57
+ - A room says whether it is self-hosted in selfHosted: its dedicated server runs on the machine of the player who created it, as it does in the Gem editor. The SDK asks for such a room on your behalf where the embedder hosts locally, and there is no option for a game to set. It is false on every room a player in the Arcade is in.
58
+
59
+ ## 7.7.0
60
+
61
+ Upgrading from 7.6.0. Impact: required.
62
+
63
+ ### Must change
64
+
65
+ - In the server API types, occurred_at on a leaderboard row and on an entity leaderboard row is now optional and may be null. Code that assumes it is always a number must handle it missing. LeaderboardResponse and EntityLeaderboardResponse are now written as the shared LeaderboardPeriodFields joined with their own fields, so every field they had is still there.
66
+
67
+ ### Rebuild
68
+
69
+ - Server API unions gained values. OrderSource has earning_reset, and InventoryChange has a new earning_limits_reset change. A switch that assumes it knows every OrderSource value or every InventoryChange type must handle the new one. Other code that compiles today keeps compiling.
70
+ - The server API reads getLeaderboard and getEntityLeaderboard accept three more options, periods_back, period and player_id, and the option types GetLeaderboardOptions and EntityLeaderboardOptions now extend the new PeriodOptions. Code that compiles today keeps compiling.
71
+
72
+ ### New capability
73
+
74
+ - gem.leaderboards can read a board scoped to one period of a challenge, such as today's board or this week's. Every read takes periodsBack, where 0 is the current period and 1 is the one before, or period, the id of a period from an earlier result. Name at most one of them. A result from such a board carries period, which says which period it is, when it opens and closes, and whether it is final. A serverless function or a dedicated server passes playerId so the board answers for that player's own day. On a board that is not scoped to periods, both selectors are refused rather than ignored.
75
+
76
+ ## 7.6.0
77
+
78
+ Upgrading from 7.5.0. Impact: required.
79
+
80
+ ### Must change
81
+
82
+ - createGem now throws GemUnframedError when the page is opened on its own instead of inside a frame. Before, such a game constructed and then waited for a bridge that never came, with no player, no saves and no config. Run your game where it is framed and handed an identity: the Arcade, the Gem editor or the Gem dev host. A game that is only ever played there changes nothing. When the framing page is not one the game allows, the refusal is now final: awaitBridge, awaitIdentity, awaitPlayer and awaitCohorts answer at once instead of timing out.
83
+
84
+ ### New capability
85
+
86
+ - A serverless function written in JavaScript can use the SDK through a new function entry of the package. createGem there returns the same platform-backed calls a browser game makes, bound to the player who called the function. Nothing is retried, a conditional save is refused before it is sent, and gem.functions and gem.gameConfig throw because a function has neither. This entry is in the package only.
87
+
19
88
  ## 7.5.0
20
89
 
21
90
  Upgrading from 7.4.2. Impact: required.
@@ -50,7 +50,7 @@ either way.
50
50
  ```jsonc
51
51
  // package.json
52
52
  "dependencies": {
53
- "@indiegems/gem-web-sdk": "7.9.0"
53
+ "@indiegems/gem-web-sdk": "7.9.1"
54
54
  }
55
55
  ```
56
56
 
@@ -33,8 +33,8 @@
33
33
  },
34
34
  {
35
35
  "file": "changelog.md",
36
- "sha256": "3398bf6f55c503520167dc9cfbee06da7f0552125a4b2050d7e508096c8e256f",
37
- "updated": "2026-10-02T21:36:48Z"
36
+ "sha256": "8a2e021addc2980433e722ba6ca2c7f5fa81cb8eac921e0bda28e44e3484d09d",
37
+ "updated": "2026-10-05T17:22:40Z"
38
38
  },
39
39
  {
40
40
  "file": "cross-promotion.md",
@@ -68,8 +68,8 @@
68
68
  },
69
69
  {
70
70
  "file": "getting-started.md",
71
- "sha256": "63a367fdcf79abee6a7978057cb1b7065f0365cd6fa5a895cbd2b18f76d29701",
72
- "updated": "2026-10-03T22:38:04Z"
71
+ "sha256": "3c38e5b14c78b70b107d5e5b5499fa9340975d602642a8eb91f2dd969d1b605b",
72
+ "updated": "2026-10-05T17:22:40Z"
73
73
  },
74
74
  {
75
75
  "file": "inventory-and-catalogs.md",
@@ -118,8 +118,8 @@
118
118
  },
119
119
  {
120
120
  "file": "server-bundles.md",
121
- "sha256": "419a1587827f494f638f331571a6385f4de080efb062e83656a9d2c50ee3473b",
122
- "updated": "2026-10-03T22:38:04Z"
121
+ "sha256": "13f5846ad8ee3d27e83916b8d95b4d3fdfcbeb85f94e095cc0c04e14dc2577b2",
122
+ "updated": "2026-10-05T17:22:40Z"
123
123
  },
124
124
  {
125
125
  "file": "serverless-functions-js.md",
@@ -138,8 +138,8 @@
138
138
  },
139
139
  {
140
140
  "file": "what-a-game-must-do.md",
141
- "sha256": "e5d0e2622077d4e41d1f1786c834e6280356f525146193285d062c4209ac33bd",
142
- "updated": "2026-10-03T22:11:20Z"
141
+ "sha256": "f44c1fd73678b1b569c59bc94bb55cfa2bdb957d798f5985ea5b3024865ed4a6",
142
+ "updated": "2026-10-04T19:51:47Z"
143
143
  }
144
144
  ]
145
145
  }
@@ -80,8 +80,8 @@ To check the download yourself: the package npm serves is, byte for byte, the fi
80
80
  also publishes on its download host, with the hash beside it:
81
81
 
82
82
  ```bash
83
- curl -fsSL -O https://downloads.gemarcade.com/sdk/v7.9.0/gem-web-sdk.tgz
84
- curl -fsSL https://downloads.gemarcade.com/sdk/v7.9.0/gem-web-sdk.tgz.sri
83
+ curl -fsSL -O https://downloads.gemarcade.com/sdk/v7.9.1/gem-web-sdk.tgz
84
+ curl -fsSL https://downloads.gemarcade.com/sdk/v7.9.1/gem-web-sdk.tgz.sri
85
85
  openssl dgst -sha384 -binary gem-web-sdk.tgz | openssl base64 -A
86
86
  ```
87
87