@indiegems/gem-web-sdk 10.3.1 → 10.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
- var Re=Object.defineProperty;var xe=(n,e)=>{for(var t in e)Re(n,t,{get:e[t],enumerable:true});};globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:10.3.1]";function Se(n,e){return e!==void 0?!e:n==="chain_exhausted"}var M=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 R(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 R("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 R("internal","token arrived for a superseded generation");return this.grant=o,this.rejected=false,this.enter("ready"),o.token}).catch(o=>{let a=ke(o),i=o?.retryable;throw t===this.generation&&this.enter(Se(a,typeof i=="boolean"?i:void 0)?"lost":"degraded",a),o instanceof R?o:new R(a,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)}},R=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 ke(n){if(n instanceof R)return n.reason;let e=n?.reason;return typeof e=="string"&&["chain_exhausted","unavailable","timeout","internal"].includes(e)?e:"internal"}var h=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}},$=["if-match","if-none-match"],V=4096;function we(n){if(!n)return;let e={};for(let[t,r]of Object.entries(n)){let o=t.toLowerCase();if(!$.includes(o)||r===void 0)continue;let a=typeof r=="string"?Ae(r):r;if(typeof a!="string"||a.length>V||!Pe(a))throw new h(`the ${o} header value cannot be sent \u2014 it is not a string, is longer than ${V} characters, or contains a character outside the range an HTTP header value may carry. This is a malformed request, not a server failure; the value is withheld here rather than written to logs.`);a!==""&&(e[o]=a);}return Object.freeze(e)}function Ae(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 Pe(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 h("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 h("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 W(n,e){let t=e.replayUnauthorizedOnce??true;return {async request(r){let o={...r},a=we(o.headers),i=Te(o),d=Object.freeze({...o,headers:a,...i===void 0?{}:{bytes:i}}),l=await e.tokenSource.get(),c=await n(d,l);if(c.status!==401||!t)return c;e.tokenSource.invalidate(l);let p=await e.tokenSource.get(),b=await n(d,p);if(b.status===401)throw e.tokenSource.close("unavailable"),new R("unavailable","the server refused a freshly minted token");return b}}}function z(n){let e=typeof n=="string"?new TextEncoder().encode(n):n;return btoa(Oe(e))}function Oe(n){let t="";for(let r=0;r<n.length;r+=32768)t+=String.fromCharCode(...n.subarray(r,r+32768));return t}var g=class extends Error{constructor(t,r,o,a,i){super(`${t} (${r}): ${o}`);this.reason=t;this.status=r;this.detail=o;this.retryAfterSeconds=a;this.code=i;this.name="GemApiError";}reason;status;detail;retryAfterSeconds;code;get retryable(){return this.reason==="unavailable"||this.reason==="rate_limited"}},Y=new WeakMap;function J(n){return Y.get(n)??{}}var Ge=new Set([408,429,500,502,503,504]),Ce=6e4;function Ee(n){if(n===void 0)return 2;if(!Number.isInteger(n)||n<0||n>10)throw new h(`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 T=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,...E(o)},o.replaySafe===true)}async post(e,t,r,o={}){return this.send({method:"POST",path:e,body:t,signal:r,...E(o)},o.replaySafe===true)}async postBytes(e,t,r,o={}){let a=await this.sendRaw({method:"POST",path:e,bytes:t,responseType:"bytes",signal:r,...E(o)},o.replaySafe===true);return {bytes:Ie(a.body),...a.invocationId===void 0?{}:{invocationId:a.invocationId}}}async patch(e,t,r,o={}){return this.send({method:"PATCH",path:e,body:t,signal:r,...E(o)},o.replaySafe===true)}async delete(e,t,r={}){return this.send({method:"DELETE",path:e,signal:t,...E(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 K(e.signal);for(let a=0;a<r;a++){if(a>0&&await this.backoff(a,o,e.signal),e.signal?.aborted)throw K(e.signal);let i;try{i=await this.options.transport.request(e);}catch(l){if(R.isAuthError(l)||h.isRefusal(l)||e.signal?.aborted||qe(l))throw l;o=new g("unavailable",0,String(l));continue}if(i.status>=200&&i.status<300||i.status===304)return i;let d=Le(i);if(!Ge.has(i.status))throw d;o=d;}throw o??new g("unavailable",0,"no attempt was made")}backoff(e,t,r){if(r?.aborted)return Promise.resolve();let o=t?.retryAfterSeconds,a=o!==void 0?o*1e3:2**(e-1)*250,i=2**(e-1)*250,d=Math.min(Math.max(a,i),Ce);return new Promise(l=>{let c=this.options.clock,p=false,b=false,S,_=()=>{p||(p=true,b&&c.clearTimeout(S),r?.removeEventListener("abort",_),l());};r?.addEventListener("abort",_,{once:true}),S=c.setTimeout(_,d),b=true,p&&c.clearTimeout(S);})}};function Ie(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 E(n){return {...n.keepalive===void 0?{}:{keepalive:n.keepalive},...n.ifMatch===void 0?{}:{headers:{"if-match":n.ifMatch}}}}function K(n){return n.reason!==void 0?n.reason:new DOMException("The operation was aborted.","AbortError")}function qe(n){let e=n?.name;return e==="AbortError"||e==="TimeoutError"}function Le(n){let e=$e(n),t=Fe(n.body),r={...t===void 0?{}:{details:t},...n.invocationId===void 0?{}:{invocationId:n.invocationId}};return Object.keys(r).length>0&&Y.set(e,r),e}var Me=new Map([["insufficient_funds","insufficient_funds"]]);function $e(n){let{status:e,body:t}=n,r=je(t),o=n.retryAfterSeconds??Ue(t),a=Be(t),i=a===void 0?void 0:Me.get(a);if(i!==void 0)return new g(i,e,r,void 0,a);switch(e){case 304:return new g("not_modified",e,r);case 400:case 422:return new g("invalid",e,r,void 0,a);case 403:return new g("forbidden",e,r,void 0,a);case 404:return new g("not_found",e,r,void 0,a);case 402:return new g("insufficient_funds",e,r,void 0,a);case 409:return new g("conflict",e,r,void 0,a);case 412:return new g("precondition_failed",e,r,void 0,a);case 413:return new g("too_large",e,r,void 0,a);case 429:return new g("rate_limited",e,r,o,a);default:return new g("unavailable",e,r,o,a)}}function je(n){if(typeof n=="string")return n;let e=n?.message;if(typeof e=="string")return e;let t=n?.error;if(typeof t=="string")return t;let r=t?.message;return typeof r=="string"?r:"no detail"}function Fe(n){let t=n?.error?.details;return t===null?void 0:t}function Be(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 Ne(n){let e=n.lastIndexOf("@");return (e===-1?n:`***@${n.slice(e+1)}`).slice(0,200)}var De=new Set($);function He(n){if(!n)return {};let e={};for(let[t,r]of Object.entries(n))De.has(t.toLowerCase())&&(e[t.toLowerCase()]=r);return e}function X(n){let e=n.fetch??globalThis.fetch.bind(globalThis);return W(async(t,r)=>{let o;try{o=new URL(n.baseUrl.replace(/\/+$/,""));}catch{throw new h("the configured baseUrl is not a valid URL. Its value is withheld here rather than written to logs. This is a configuration fault, not a server failure.")}let a;try{a=new URL(o.href.replace(/\/+$/,"")+t.path);}catch{throw new h(`${JSON.stringify(typeof t.path=="string"?Ne(t.path):"(a non-string path)")} does not form a valid URL against ${o.protocol}//${o.host}. This is a malformed request, not a server failure.`)}if(a.protocol!==o.protocol||a.host!==o.host)throw new h(`${JSON.stringify(a.pathname)} resolves to ${a.protocol}//${a.host}, not ${o.protocol}//${o.host}. A request path may not change the request's origin \u2014 it carries the play token.`);if(a.username!==""||a.password!==""){let _=o.username!==""||o.password!=="",y=a.username!==o.username||a.password!==o.password,m=_?y?"baseUrl (and possibly the request path)":"baseUrl":"request path";throw new h(`the ${m} puts credentials in the URL, which cannot be fetched (${t.method} ${a.pathname}). The value is withheld here rather than written to logs. This is a malformed request, not a server failure.`)}for(let[_,y]of Object.entries(n.defaultQuery??{}))a.searchParams.has(_)||a.searchParams.set(_,y);let i=t.bytes,d=t.bytes===void 0?void 0:"application/octet-stream";try{t.body!==void 0&&(i=JSON.stringify(t.body),d="application/json");}catch(_){throw new h(`the body of ${t.method} ${JSON.stringify(a.pathname)} could not be serialised to JSON: ${String(_)}. This is a bug in the request, not a server failure \u2014 retrying sends the same unserialisable value.`)}let l=await e(a.toString(),{method:t.method,headers:{authorization:`Bearer ${r}`,...d===void 0?{}:{"content-type":d},...He(t.headers)},body:i,signal:t.signal,...t.keepalive===void 0?{}:{keepalive:t.keepalive},credentials:"omit",mode:"cors",redirect:"error",cache:"no-store",referrerPolicy:"no-referrer"}),c=null;if(t.responseType==="bytes"&&l.status>=200&&l.status<300)c=new Uint8Array(await l.arrayBuffer());else {let _=await l.text();if(_.length>0)try{c=JSON.parse(_);}catch{c=_;}}let p=l.headers.get("etag"),b=Ve(l.headers.get("retry-after")),S=l.headers.get("x-gem-invocation-id");return {status:l.status,body:c,...p===null?{}:{etag:p},...b===void 0?{}:{retryAfterSeconds:b},...S===null||S===""?{}:{invocationId:S}}},n)}function Ve(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 We="gem-web-bridge";var O=65536,Q=8,j=5e3,Z=1024;function ee(n){return Object.freeze(Object.assign(Object.create(null),n))}ee({"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.controlsDeclare":60,"gem.menu":60,"gem.menuSelect":60,"gem.requestShare":6,"gem.requestAvatarPicker":6,"gem.vibrate":600,"gem.frameStats":120,"gem.portraitBorders":60,"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});ee({"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.portraitBorders":"portraitBorders","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.requestAvatarPicker":"avatarPicker","gem.vibrate":"vibration","gem.menu":"gameMenu","gem.menuSelect":"gameMenu","gem.controlsDeclare":"controls"});function Ke(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 Ye(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 Je(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function Xe(n){return /^[a-z_]+$/.test(n)}function B(n,e,t){if(e>Q)return `nesting deeper than ${Q}`;if(++t.nodes>j)return `more than ${j} 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>Z)return `an array of ${n.length} entries, over the ${Z} limit`;t.bytes+=2;for(let d of n){let l=B(d,e+1,t);if(l)return l}return null}let a=Object.getPrototypeOf(n);if(a!==Object.prototype&&a!==null)return "a value that is not a plain object";t.bytes+=2;let i=n;for(let d in i){if(!Object.prototype.hasOwnProperty.call(i,d))continue;if(++t.nodes>j)return `more than ${j} values`;if(t.bytes+=d.length*3+4,t.bytes>O)return `over the ${O} byte limit`;let l=B(i[d],e+1,t);if(l)return l}return null}function Qe(n){let e={nodes:0,bytes:0,seen:new Set},t=B(n,0,e);return t?`message contains ${t}`:e.bytes>O?`message is over the ${O} byte limit`:null}var Ze={origin:[Ke,"not a well-formed origin"],url:[Ye,"not a safe absolute http(s) URL"],bcp47:[Je,"not a well-formed BCP 47 tag"],code:[Xe,"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}`,a=n[r.n];if(a==null){if(r.o)continue;return `${o}: required`}let i=te(a,r,o);if(i)return i}return null}function te(n,e,t){switch(e.k){case "s":{if(typeof n!="string")return `${t}: expected string`;if(n.length>e.max)return `${t}: exceeds ${e.max} characters`;if(e.f){let[r,o]=Ze[e.f];if(!r(n))return `${t}: ${o}`}return null}case "i":return typeof n!="number"||!Number.isInteger(n)?`${t}: expected integer`:n<e.lo||n>e.hi?`${t}: out of range ${e.lo}..${e.hi}`:null;case "b":return typeof n=="boolean"?null:`${t}: expected boolean`;case "e":{let r=e.v;return r.includes(n)?null:`${t}: not one of ${r.join("|")}`}case "o":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:ne(n,e.fs,t);case "j":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected a plain object`:null;case "a":{if(!Array.isArray(n))return `${t}: expected array`;if(n.length>e.max)return `${t}: exceeds ${e.max} items`;let r=e.it,o=`${t}[]`;for(let a of n){if(a==null){if(r.o)continue;return `${o}: required`}let i=te(a,r,o);if(i)return i}return null}default:{let r=e.k;return `${t}: unknown kind ${String(r)}`}}}var re=Object.create(null);function u(n,e){return re[n]=t=>{let r=Qe(t);if(r)return r;if(typeof t!="object"||t===null||Array.isArray(t))return "message: expected object";let o=t;return o.gem!==We?"gem: wrong protocol marker":o.type!==n?`type: expected ${n}`:ne(o,e,"")}}u("gem.handshake",[{n:"versions",k:"o",fs:[{n:"min",k:"i",lo:1,hi:1e3},{n:"max",k:"i",lo:1,hi:1e3}]},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}},{n:"embedder",k:"s",max:2048,f:"origin"},{n:"unbidden",k:"b",o:1}]);u("gem.handshake.accept",[{n:"v",k:"i",lo:1,hi:1e3},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}}]);u("gem.token",[{n:"token",k:"s",max:4096},{n:"requestId",k:"s",o:1,max:64},{n:"generation",k:"i",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"s",o:1,max:512,f:"url"},{n:"playerId",k:"s",max:64},{n:"gameId",k:"s",max:64},{n:"channel",k:"e",v:["dev","test","release"]},{n:"gameVersion",k:"s",o:1,max:64},{n:"expiresAt",k:"i",lo:0,hi:4102444800},{n:"chainEndsAt",k:"i",lo:0,hi:4102444800},{n:"allowDevTools",k:"b",o:1}]);u("gem.token.denied",[{n:"requestId",k:"s",max:64},{n:"retryable",k:"b"},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:36e5},{n:"reason",k:"e",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"s",max:64}]);u("gem.player",[{n:"untrusted",k:"o",fs:[{n:"displayName",k:"s",max:64},{n:"displayTag",k:"s",o:1,max:80},{n:"displayHandle",k:"s",max:80}]},{n:"playerId",k:"s",o:1,max:64},{n:"discriminator",k:"s",o:1,max:8},{n:"avatarIconUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatarIconId",k:"s",o:1,max:64},{n:"badges",k:"a",o:1,max:2,it:{n:"",k:"o",fs:[{n:"itemId",k:"s",max:64},{n:"iconUrl",k:"s",max:2048,f:"url"}]}},{n:"displayTag",k:"s",max:8},{n:"avatarUrl",k:"s",o:1,max:2048,f:"url"},{n:"boost",k:"o",o:1,fs:[{n:"multipliers",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"currencyId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"multiplierBp",k:"i",lo:1e4,hi:1e6}]}},{n:"expiresInDays",k:"i",o:1,lo:1,hi:7}]}]);u("gem.pause",[{n:"paused",k:"b"}]);u("gem.prefs",[{n:"reducedMotion",k:"b"},{n:"muted",k:"b"},{n:"showFrameStats",k:"b",o:1},{n:"locale",k:"s",max:35,f:"bcp47"},{n:"recommended",k:"o",o:1,fs:[{n:"volume",k:"i",lo:0,hi:100},{n:"batterySaver",k:"b"},{n:"keyboardLayout",k:"e",v:["wasd","arrows"]},{n:"gamepadConfirm",k:"e",v:["south","east"]},{n:"vibration",k:"b"},{n:"lookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"gamepadLookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"invertLookY",k:"b",o:1},{n:"touchMovement",k:"s",o:1,max:16,f:"code"}]}]);u("gem.cohorts",[{n:"cohorts",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"experimentId",k:"s",max:36},{n:"variantKey",k:"s",max:32}]}}]);u("gem.earnAllowanceChanged",[]);u("gem.viewport",[{n:"insets",k:"o",fs:[{n:"top",k:"i",lo:0,hi:4096},{n:"right",k:"i",lo:0,hi:4096},{n:"bottom",k:"i",lo:0,hi:4096},{n:"left",k:"i",lo:0,hi:4096}]},{n:"reserved",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384},{n:"width",k:"i",lo:0,hi:16384},{n:"height",k:"i",lo:0,hi:16384}]}}]);u("gem.deviceSettings",[{n:"settings",k:"j",o:1}]);u("gem.willTerminate",[{n:"reason",k:"e",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"i",lo:0,hi:6e4}]);u("gem.roomEvent",[{n:"event",k:"e",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"s",max:64},{n:"matchId",k:"s",o:1,max:64},{n:"version",k:"i",o:1,lo:0,hi:2147483647},{n:"reason",k:"s",o:1,max:64},{n:"platform",k:"e",o:1,v:["universal","mobile"]}]);u("gem.socketState",[{n:"connected",k:"b"},{n:"reason",k:"e",o:1,v:["connecting","dropped","watchdog","terminal"]}]);u("gem.seatedEvent",[{n:"roomId",k:"s",max:64}]);u("gem.autoStartFailedEvent",[{n:"roomId",k:"s",max:64},{n:"code",k:"s",max:64}]);u("gem.signalEvent",[{n:"event",k:"e",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}]);u("gem.dedicatedEvent",[{n:"event",k:"e",v:["answer","error","matchEnded"]},{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",o:1,max:10240},{n:"sessionId",k:"s",o:1,max:64},{n:"code",k:"s",o:1,max:64},{n:"message",k:"s",o:1,max:256},{n:"reason",k:"s",o:1,max:64}]);u("gem.partyResult",[{n:"requestId",k:"s",max:64},{n:"partyId",k:"s",o:1,max:64}]);u("gem.clusterTarget",[{n:"clusterTargetId",k:"s",max:64},{n:"clusterTargetIds",k:"a",o:1,max:3,it:{n:"",k:"s",max:64}}]);u("gem.devtools",[{n:"action",k:"e",v:["open","close","toggle"]}]);u("gem.screenshot",[{n:"maxWidth",k:"i",lo:1,hi:7680},{n:"maxHeight",k:"i",lo:1,hi:4320}]);u("gem.screenshot.denied",[{n:"reason",k:"e",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"b"}]);u("gem.requestContext",[]);u("gem.gameContext",[{n:"context",k:"j"}]);u("gem.signal",[{n:"signal",k:"e",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}]);u("gem.dedicatedOffer",[{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",max:10240},{n:"intent",k:"e",v:["initial","ice_restart","full_reconnect"]}]);u("gem.partyRequest",[{n:"requestId",k:"s",max:64}]);u("gem.ready",[]);u("gem.engaged",[]);u("gem.progress",[{n:"loaded",k:"i",lo:0,hi:1099511627776},{n:"total",k:"i",lo:0,hi:1099511627776}]);u("gem.requestToken",[{n:"requestId",k:"s",max:64},{n:"reason",k:"e",v:["initial","expiring","rejected"]}]);u("gem.requestLocalServer",[{n:"requestId",k:"s",max:64},{n:"gameRoomId",k:"s",max:64}]);u("gem.localServer",[{n:"requestId",k:"s",max:64},{n:"serverId",k:"s",o:1,max:128}]);u("gem.localServer.denied",[{n:"requestId",k:"s",max:64},{n:"retryable",k:"b"},{n:"reason",k:"e",v:["refused","unavailable"]}]);u("gem.exit",[{n:"reason",k:"s",o:1,max:64}]);u("gem.openExternal",[{n:"url",k:"s",max:2048,f:"url"}]);u("gem.requestFullscreen",[{n:"enabled",k:"b"}]);u("gem.audioState",[{n:"muted",k:"b"}]);u("gem.rewardCue",[{n:"currencySlug",k:"s",max:32},{n:"expected",k:"i",o:1,lo:1,hi:1e9},{n:"origin",k:"o",o:1,fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384}]}]);u("gem.walletDisplay",[{n:"visible",k:"b"},{n:"currencies",k:"a",o:1,max:8,it:{n:"",k:"s",max:64}},{n:"score",k:"b",o:1}]);u("gem.controlsDeclare",[{n:"uses",k:"o",fs:[{n:"lookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"gamepadLookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"invertLookY",k:"s",o:1,max:16,f:"code"},{n:"touchMovement",k:"s",o:1,max:16,f:"code"}]}]);u("gem.menu",[{n:"settings",k:"b"},{n:"items",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"id",k:"s",max:32},{n:"label",k:"s",max:40}]}}]);u("gem.menuSelect",[{n:"entry",k:"e",v:["settings","item"]},{n:"id",k:"s",o:1,max:32}]);u("gem.requestShare",[{n:"params",k:"a",max:16,it:{n:"",k:"o",fs:[{n:"key",k:"s",max:64},{n:"value",k:"s",max:512}]}}]);u("gem.requestAvatarPicker",[]);u("gem.vibrate",[{n:"pattern",k:"a",max:99,it:{n:"",k:"i",lo:0,hi:1e4}}]);u("gem.frameStats",[{n:"fps",k:"i",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"i",lo:0,hi:1e5}]);u("gem.portraitBorders",[{n:"name",k:"s",o:1,max:40}]);u("gem.error",[{n:"code",k:"e",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"s",o:1,max:256}]);u("gem.requestPurchase",[{n:"requestId",k:"s",max:64},{n:"purchaseKind",k:"e",v:["item","recipe"]},{n:"targetId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"quantity",k:"i",o:1,lo:1,hi:10},{n:"catalogId",k:"s",o:1,max:64}]);u("gem.purchaseResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["ok","declined","unavailable"]},{n:"reason",k:"s",o:1,max:64,f:"code"},{n:"purchaseId",k:"s",o:1,max:64}]);u("gem.deviceSettings.put",[{n:"requestId",k:"s",max:64},{n:"settings",k:"j"}]);u("gem.deviceSettings.result",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["stored","too_large","unavailable"]}]);u("gem.requestAd",[{n:"requestId",k:"s",max:64},{n:"placement",k:"s",max:32},{n:"format",k:"e",v:["interstitial","rewarded"]}]);u("gem.adResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["shown","no_ad","unavailable"]}]);u("gem.requestSignIn",[{n:"requestId",k:"s",max:64}]);u("gem.signInResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["signed_in","declined","unavailable"]}]);u("gem.requestFriendChallenge",[{n:"requestId",k:"s",max:64},{n:"playerId",k:"s",max:64},{n:"template",k:"s",max:64},{n:"params",k:"j",o:1}]);u("gem.friendChallengeResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["accepted","cancelled","refused","unavailable","rate_limited","invalid"]},{n:"code",k:"s",o:1,max:64},{n:"param",k:"s",o:1,max:64},{n:"channel",k:"s",o:1,max:16},{n:"configVersion",k:"i",o:1,lo:0,hi:9007199254740991},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:864e5},{n:"detail",k:"s",o:1,max:300}]);Object.freeze(re);var G={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)};var en=1e4;function oe(n,e){return U(n,e)}function U(n,e){if(typeof n.serverToken!="function"||typeof n.onServerToken!="function")throw new Error("this runtime delivers no game-server token: host.serverToken/onServerToken are missing. The server image running this bundle predates token delivery \u2014 the bundle cannot call gem-api on it.");let t=i=>({token:i.token,expiresAt:i.expiresAt,chainEndsAt:Number.POSITIVE_INFINITY}),r=null,o=new M({clock:e.clock,...e.onStateChange===void 0?{}:{onStateChange:e.onStateChange},request:()=>new Promise((i,d)=>{let l=e.clock.setTimeout(()=>{r=null,d({reason:"unavailable",retryable:true});},e.timeoutMs??en);r={resolve:c=>{e.clock.clearTimeout(l),i(c);},reject:d,timer:l};})}),a=n.onServerToken(i=>{let d=t(i),l=r;if(l){r=null,l.resolve(d);return}o.accept(d);});return {source:o,dispose(){a(),r&&(e.clock.clearTimeout(r.timer),r.reject({reason:"unavailable",retryable:false}),r=null);}}}var D={};xe(D,{acceptTransfer:()=>nn,addEntityProgression:()=>tn,adminAction:()=>rn,cancelInventoryTransfer:()=>on,claimEntityProgressionRewards:()=>an,closeGameRoom:()=>sn,createEntityBatchOrder:()=>ln,createEntityOrder:()=>dn,createSession:()=>un,deleteEntityGameSetting:()=>cn,deleteEntitySave:()=>mn,deleteSession:()=>gn,deleteShowcaseValue:()=>pn,executeEntityRecipe:()=>yn,finalizeSaveUpload:()=>fn,getChannelAssignment:()=>hn,getDropRates:()=>_n,getEntityCurrency:()=>bn,getEntityGameSetting:()=>vn,getEntityInventory:()=>Rn,getEntityInventoryItem:()=>xn,getEntityLeaderboard:()=>Sn,getEntityOrder:()=>kn,getEntityProgression:()=>wn,getEntityRecipeAvailability:()=>An,getEntityRecipeUsage:()=>Pn,getEntitySave:()=>Tn,getEvent:()=>On,getGameRoomV2:()=>Gn,getLeaderboard:()=>Cn,getPlayerGameProfile:()=>En,getPurchaseCatalog:()=>In,getResolvedTemplate:()=>qn,getRoomArgs:()=>Ln,getShowcaseValue:()=>Mn,getTransferDetails:()=>$n,ingestAnalyticsEvents:()=>N,initiateInventoryTransfer:()=>jn,invokeFunction:()=>Fn,kickPlayer:()=>Bn,listChallenges:()=>Un,listEntityGameSettings:()=>Nn,listEntityOrders:()=>Dn,listEntityProgressions:()=>Hn,listEntitySaves:()=>Vn,listEvents:()=>Wn,listGameRooms:()=>zn,listResolvedTemplates:()=>Kn,listTransfers:()=>Yn,maxEntityProgression:()=>Jn,putEntityGameSetting:()=>Xn,putRoomArgs:()=>Qn,putShowcaseValue:()=>Zn,rejectTransfer:()=>et,reportMatchPlayers:()=>nt,requestSaveUploadUrl:()=>tt,resetEntityProgression:()=>rt,setMatchBackfill:()=>ot,simulateEntityOrder:()=>at,transferHostV2:()=>st,updateGameRoomV2:()=>it});function s(n){let e=String(n);if(!/^[A-Za-z0-9_.-]{1,128}$/.test(e)||e==="."||e==="..")throw new TypeError(`${JSON.stringify(e)} is not a usable path segment \u2014 it is interpolated into a URL`);return encodeURIComponent(e)}async function nn(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/accept`;return n.client.post(r,void 0,t?.signal)}async function tn(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/add`;return n.client.post(i,o,a?.signal)}async function rn(n,e,t,r){let o=`/v1/voice/sessions/${s(e)}/admin`;return n.client.post(o,t,r?.signal)}async function on(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/cancel`;return n.client.post(r,void 0,t?.signal)}async function an(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/claim`;return n.client.post(i,o,a?.signal)}async function sn(n,e,t){let r=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.delete(r,t?.signal)}async function ln(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/batch`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function dn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function un(n,e,t){return n.client.post("/v1/voice/sessions",e,t?.signal)}async function cn(n,e,t,r,o){let a=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.delete(a,o?.signal)}async function mn(n,e,t,r,o){let a=`/v1/saves/${s(e)}/${s(t)}/${s(r)}`;return n.client.delete(a,o?.signal)}async function gn(n,e,t){let r=`/v1/voice/sessions/${s(e)}`;return n.client.delete(r,t?.signal)}async function pn(n,e,t,r){let o=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.delete(o,r?.signal)}async function yn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/recipes/execute`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function fn(n,e,t,r,o,a){let i=`/v1/saves/${s(e)}/${s(t)}/${s(r)}/finalize`;return n.client.post(i,o,a?.signal)}async function hn(n,e,t){let r=`/v1/games/${s(n.gameId())}/config/channels/${s(e)}`;return n.client.getWithEtag(r,{...t?.signal===void 0?{}:{signal:t.signal},...t?.ifNoneMatch===void 0?{}:{ifNoneMatch:t.ifNoneMatch}})}async function _n(n,e,t){let r=`/v1/inventory/loot-tables/${s(e)}/drop-rates`;return n.client.get(r,t?.signal)}async function bn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/currencies/${s(r)}`;return n.client.get(a,o?.signal)}async function vn(n,e,t,r,o){let a=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function Rn(n,e,t,r){let o=new URLSearchParams;r?.include_buckets!==void 0&&o.set("include_buckets",String(r?.include_buckets)),r?.include_custom_data!==void 0&&o.set("include_custom_data",String(r?.include_custom_data)),r?.currency_limit!==void 0&&o.set("currency_limit",String(r?.currency_limit)),r?.currency_cursor!==void 0&&o.set("currency_cursor",String(r?.currency_cursor)),r?.item_limit!==void 0&&o.set("item_limit",String(r?.item_limit)),r?.item_cursor!==void 0&&o.set("item_cursor",String(r?.item_cursor)),r?.progression_limit!==void 0&&o.set("progression_limit",String(r?.progression_limit)),r?.progression_cursor!==void 0&&o.set("progression_cursor",String(r?.progression_cursor));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function xn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/items/${s(r)}`;return n.client.get(a,o?.signal)}async function Sn(n,e,t,r,o){let a=new URLSearchParams;o?.bucket_1!==void 0&&a.set("bucket_1",String(o?.bucket_1)),o?.bucket_2!==void 0&&a.set("bucket_2",String(o?.bucket_2)),o?.limit!==void 0&&a.set("limit",String(o?.limit)),o?.periods_back!==void 0&&a.set("periods_back",String(o?.periods_back)),o?.period!==void 0&&a.set("period",String(o?.period)),o?.player_id!==void 0&&a.set("player_id",String(o?.player_id));let i=a.toString(),d=`/v1/leaderboards/${s(e)}/${s(t)}/${s(r)}`+(i?`?${i}`:"");return n.client.get(d,o?.signal)}async function kn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/${s(r)}`;return n.client.get(a,o?.signal)}async function wn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}`;return n.client.get(a,o?.signal)}async function An(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/catalogs/${s(r)}/recipes/${s(o)}/availability`;return n.client.get(i,a?.signal)}async function Pn(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}/recipe-usage`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function Tn(n,e,t,r,o){let a=`/v1/saves/${s(e)}/${s(t)}/${s(r)}`;return n.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function On(n,e,t){let r=`/v1/events/${s(e)}`;return n.client.get(r,t?.signal)}async function Gn(n,e,t){let r=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.getWithEtag(r,{...t?.signal===void 0?{}:{signal:t.signal},...t?.ifNoneMatch===void 0?{}:{ifNoneMatch:t.ifNoneMatch}})}async function Cn(n,e,t){let r=new URLSearchParams;t?.bucket_1!==void 0&&r.set("bucket_1",String(t?.bucket_1)),t?.bucket_2!==void 0&&r.set("bucket_2",String(t?.bucket_2)),t?.periods_back!==void 0&&r.set("periods_back",String(t?.periods_back)),t?.period!==void 0&&r.set("period",String(t?.period)),t?.player_id!==void 0&&r.set("player_id",String(t?.player_id));let o=r.toString(),a=`/v1/leaderboards/${s(e)}`+(o?`?${o}`:"");return n.client.get(a,t?.signal)}async function En(n,e,t){let r=`/v1/profiles/players/${s(e)}`;return n.client.get(r,t?.signal)}async function In(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 qn(n,e,t){let r=`/v1/game-room-templates/${s(e)}`;return n.client.get(r,t?.signal)}async function Ln(n,e,t){let r=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/room-args`;return n.client.get(r,t?.signal)}async function Mn(n,e,t,r){let o=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.get(o,r?.signal)}async function $n(n,e,t){let r=`/v1/inventory/transfers/${s(e)}`;return n.client.get(r,t?.signal)}async function N(n,e,t){let r=`/v1/games/${s(n.gameId())}/analytics/events`;return n.client.post(r,e,t?.signal,{replaySafe:true})}async function jn(n,e,t){return n.client.post("/v1/inventory/transfers",e,t?.signal)}async function Fn(n,e,t){return n.client.postBytes("/v1/functions/invoke",e,t?.signal)}async function Bn(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/kick/${s(t)}`;return n.client.post(o,void 0,r?.signal)}async function Un(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 Nn(n,e,t,r){let o=`/v1/settings/${s(e)}/${s(t)}`;return n.client.get(o,r?.signal)}async function Dn(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}/orders`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function Hn(n,e,t,r){let o=`/v1/inventory/${s(e)}/${s(t)}/progressions`;return n.client.get(o,r?.signal)}async function Vn(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),i=`/v1/saves/${s(e)}/${s(t)}`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function Wn(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 zn(n,e){let t=new URLSearchParams;e?.status!==void 0&&t.set("status",String(e?.status)),e?.game_channel!==void 0&&t.set("game_channel",String(e?.game_channel)),e?.game_room_type!==void 0&&t.set("game_room_type",String(e?.game_room_type)),e?.template_id!==void 0&&t.set("template_id",String(e?.template_id)),e?.template_slug!==void 0&&t.set("template_slug",String(e?.template_slug)),e?.limit!==void 0&&t.set("limit",String(e?.limit)),e?.cursor!==void 0&&t.set("cursor",String(e?.cursor));let r=t.toString(),o=`/v1/games/${s(n.gameId())}/game-rooms`+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function Kn(n,e){return n.client.get("/v1/game-room-templates",e?.signal)}async function Yn(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 Jn(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/max`;return n.client.post(i,o,a?.signal)}async function Xn(n,e,t,r,o,a){let i=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.put(i,o,a?.signal,{...a?.ifMatch===void 0?{}:{ifMatch:a.ifMatch}})}async function Qn(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/room-args`;return n.client.put(o,t,r?.signal)}async function Zn(n,e,t,r,o){let a=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.put(a,r,o?.signal)}async function et(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/reject`;return n.client.post(r,void 0,t?.signal)}async function nt(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/matches/${s(e)}/players/report`;return n.client.post(o,t,r?.signal)}async function tt(n,e,t,r,o,a){let i=`/v1/saves/${s(e)}/${s(t)}/${s(r)}/upload-url`;return n.client.post(i,o,a?.signal,{replaySafe:true})}async function rt(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/reset`;return n.client.post(i,o,a?.signal)}async function ot(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/matches/${s(e)}/backfill`;return n.client.put(o,t,r?.signal)}async function at(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/simulate`;return n.client.post(a,r,o?.signal)}async function st(n,e,t,r){let o=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}/transfer/${s(t)}`;return n.client.post(o,void 0,r?.signal)}async function it(n,e,t,r){let o=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.patch(o,t,r?.signal,{...r?.ifMatch===void 0?{}:{ifMatch:r.ifMatch}})}var ae="gem_";var ut=1e4,ct=50,mt=1e3,gt=65536-4*1024,se=n=>typeof n=="number"?n:0,pt=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 yt(n){return n?.retryable===true}function ft(n,e){let t=n??{},r=Array.isArray(t.rejected)?t.rejected.map(o=>{let a=o??{};return {index:se(a.index),code:pt(a.code)}}):[];return {accepted:se(t.accepted),rejected:r,dropped:e,duplicate:t.duplicate===true}}function le(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 de(n){let e=Math.max(1,Math.floor(n.maxQueue??mt)),t={client:n.client,gameId:()=>n.gameId},r=[],o=0,a=null,i=false,d=false,l=false,c=false,p=m=>{n.log?.(m);},b=()=>{a!==null&&(n.clock.clearTimeout(a),a=null);},S=()=>{a!==null||i||d||(a=n.clock.setTimeout(()=>{a=null,y().catch(()=>{});},ut));},_=()=>{let m=Math.min(r.length,100),f=128;for(let v=0;v<m;v+=1){let A=r[v];if(A===void 0)break;if(f+=JSON.stringify(le(A,0)).length+1,f>gt)return Math.max(1,v)}return m};async function y(m){if(r.length===0)return {accepted:0,rejected:[],dropped:0,duplicate:false};b();let f=r.splice(0,_()),v=o;o=0;let A=Math.round(n.clock.now()),L={batch_id:ie(),sent_at_ms:A,events:f.map(k=>le(k,A))};d=true;try{let k=await N(t,L,m===void 0?void 0:{signal:m}),P=ft(k,v);for(let ve of P.rejected)p(`[gem] analytics: an event was refused (${ve.code}). See the analytics_events section of your game config.`);return P}catch(k){if(yt(k))for(r=[...f,...r],o+=v;r.length>e;)r.shift(),o+=1;else p(`[gem] analytics: ${f.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(k)}`);throw k}finally{d=false,r.length>0&&S();}}return {track(m,f,v={}){if(i)return;if(typeof m!="string"||m===""){c||(c=true,p(`[gem] analytics: '${f}' 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(f.startsWith(ae)){l||(l=true,p(`[gem] analytics: '${f}' 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[k,P]of Object.entries(v))typeof P=="string"?A[k]=P:typeof P=="number"&&Number.isFinite(P)&&(L[k]=P);for(;r.length>=e;)r.shift(),o+=1;r.push({uid:ie(),playerId:m,name:f,atMs:n.clock.now(),dimensions:A,measures:L}),r.length>=ct?y().catch(()=>{}):S();},flush:m=>y(m),get pending(){return r.length},dispose(){i=true,b(),r=[],o=0;}}}var ht=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 g{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:ht.get(this.code))??super.retryable}},C=class{#e;constructor(e){this.#e=e;}async invoke(e,t={}){let r=_t(e),o;try{o=await this.#e(r,t.signal===void 0?{}:{signal:t.signal});}catch(a){throw a instanceof g?vt(a):a}return bt(o)}};function _t(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 h(`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 h(`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 bt(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 vt(n){let{details:e,invocationId:t}=J(n),o=e?.untrusted?.message,a=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 a=="string"?{failure:a}:{}})}var w=n=>typeof n=="string"?n:"",Rt=/(?:Z|[+-]\d{2}:?\d{2})$/i;function ue(n){let e=w(n);if(!Rt.test(e))return 0;let t=Date.parse(e);return Number.isFinite(t)?Math.floor(t/1e3):0}var xt=/^[0-9a-f]{1,64}$/,St=/^[0-9a-f]{16}$/,kt=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,wt=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function At(n){let e=w(n),t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!t)return;let[r,o,a]=[Number(t[1]),Number(t[2]),Number(t[3])],i=new Date(Date.UTC(r,o-1,a));return i.getUTCFullYear()===r&&i.getUTCMonth()===o-1&&i.getUTCDate()===a?e:void 0}var Pt=4096,Tt=new TextEncoder;function Ot(n){let e=w(n.challenge_data),t=w(n.challenge_data_hash);return e===""||!St.test(t)?{}:Tt.encode(e).length>Pt?{}:{data:e,dataHash:t}}function Gt(n){let e=n??{},t=ue(e.period_start_at),r=ue(e.period_ends_at);if(t===0||r===0)return;let o=w(e.slug),a=w(e.seed),i=At(e.period_local_date),d=w(e.boundary),l=w(e.reset_time);return {id:w(e.progression_definition_id),...o===""?{}:{slug:o},window:w(e.window),periodStartAt:t,periodEndsAt:r,...i===void 0?{}:{periodLocalDate:i},boundary:kt.test(d)?d:"",resetTime:wt.test(l)?l:"",seed:xt.test(a)?a:"",...Ot(e)}}function ce(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 me(n){let e=n??{};return Array.isArray(e.challenges)?e.challenges.map(Gt).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().");ce(r);let a=await n({player_id:t,...r===void 0?{}:{periods_back:r},...o===void 0?{}:{signal:o}});return me(a)}}}function Ct(n){let e={};for(let[t,r]of Object.entries(D))if(typeof r=="function"){let o=r;e[t]=(...a)=>o(n,...a);}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=U(n,{clock:t,...e.onAuthStateChange===void 0?{}:{onStateChange:e.onAuthStateChange}}),a=X({baseUrl:r,tokenSource:o.source,defaultQuery:{game_id:n.gameId,channel:n.channel},...e.fetch===void 0?{}:{fetch:e.fetch}}),i=new T({transport:a,clock:t}),d={gameId:n.gameId,channel:n.channel,matchId:n.matchId,...n.gameRoomId===void 0?{}:{gameRoomId:n.gameRoomId}},l=Ct({client:i,gameId:()=>d.gameId}),c=d.gameRoomId,p=n.endMatch,b=n.log,S=de({client:i,clock:t,gameId:d.gameId,...typeof b=="function"?{log:y=>b.call(n,y)}:{}});return {identity:d,client:i,api:l,match:{end:async()=>{if(p===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 p.call(n);},setBackfill:async(y,m)=>{let f=await l.setMatchBackfill(d.matchId,{open:y.open,...y.seats===void 0?{}:{seats:y.seats}},m===void 0?{}:{signal:m});return {open:f.open,seats:f.seats??null}},reportPlayers:async(y,m)=>(await l.reportMatchPlayers(d.matchId,{players:y.map(v=>({player_id:v.playerId,state:v.state}))},m===void 0?{}:{signal:m})).players.map(v=>({playerId:v.player_id,outcome:v.outcome}))},analytics:S,functions:new C(l.invokeFunction),challenges:ge(l.listChallenges),...c===void 0?{}:{room:{get:y=>l.getGameRoomV2(c,y),args:async y=>{let m=await l.getGameRoomV2(c,y?.signal===void 0?{}:{signal:y.signal}),f=m.modified?m.body:void 0;if(f?.room_args==null||f.room_args_template==null)throw new g("not_found",404,"this room's template declares no room args",void 0,"room_args_not_defined");return {room_args:f.room_args,room_args_template:f.room_args_template}}}},dispose:()=>{S.dispose(),o.dispose();}}}var Et=["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"],It=new Set(Et);function pe(n){return typeof n=="string"&&It.has(n)?n:"unknown"}var x=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 x(n)}var ye={toPlain(n){return x.unwrap(n)},compare(n,e,t){let r=n instanceof x?x.unwrap(n):n,o=e instanceof x?x.unwrap(e):e,a;try{a=new Intl.Collator(t);}catch{a=new Intl.Collator;}return a.compare(r,o)},equals(n,e){let t=n instanceof x?x.unwrap(n):n,r=e instanceof x?x.unwrap(e):e;return t.normalize("NFC")===r.normalize("NFC")}};var fe="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 H(n,e={}){let t=e.clock??G,r=()=>{let d=n();if(d===null)throw new Error(fe);return d},o=null,a=()=>{if(o===null)throw new Error(fe);return o};return {server:{get identity(){return a().identity},get client(){return a().client},get api(){return a().api},get match(){return a().match},get analytics(){return a().analytics},get functions(){return a().functions},get challenges(){return a().challenges},get room(){return a().room},dispose(){o?.dispose();},get sizeClass(){return r().sizeClass},get roomArgs(){return r().roomArgs},get roster(){return r().roster},players(){return r().players()},profile(d){let c=r().profile?.(d);if(!c)return null;let p=c.displayName;return typeof p!="string"||p===""?null:{displayName:q(p),...typeof c.displayTag=="string"&&c.displayTag!==""?{displayTag:q(c.displayTag)}:{},...typeof c.discriminator=="string"?{discriminator:c.discriminator}:{}}},playerNumber(d){return r().playerNumber?.(d)},send(d,l,c){c===void 0?r().send(d,l):r().send(d,l,c);},broadcast(d,l){l===void 0?r().broadcast(d):r().broadcast(d,l);},kick(d,l){l===void 0?r().kick(d):r().kick(d,l);},log(d){r().log(d);},warn(d){r().warn(d);}},attach:()=>{o=F(r(),{...e,clock:t});}}}function he(n,e={}){let{server:t,attach:r}=H(()=>n,e);return r(),t}function qt(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:pe(e)}}}var Lt=1e4;function Mt(n){let e=false;return t=>{if(e)return;let r;try{r=n.match.reportPlayers([{playerId:t,state:"connected"}],AbortSignal.timeout(Lt));}catch{return}r.catch(o=>{o instanceof g&&o.status>=400&&o.status<500&&(e=o.status!==429);});}}function _e(n,e={}){return ()=>{let t=null,{server:r,attach:o}=H(()=>t,e),a=n(r),i={async init(l){t=l,o(),await a.init?.();},async shutdown(l){let c=qt(l);try{await a.shutdown?.(c);}finally{r.dispose();}}},d=Mt(r);return i.join=(l,c)=>(d(l),a.join?.(l,c)),a.leave&&(i.leave=(l,c)=>a.leave?.(l,c)),a.message&&(i.message=(l,c,p,b)=>a.message?.(l,c,p,b)),i}}var $t=new Set(["unlocked","already_unlocked","suppressed"]);function be(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"||!$t.has(o.outcome)||typeof o.achievement_id!="string"||o.achievement_id==="")continue;let a=o.outcome;t.push({achievementId:o.achievement_id,progressionDefinitionId:typeof o.progression_definition_id=="string"?o.progression_definition_id:"",points:a==="unlocked"&&typeof o.points=="number"&&Number.isFinite(o.points)?o.points:0,outcome:a,...typeof o.reason=="string"?{reason:o.reason}:{}});}return t}
1
+ var Re=Object.defineProperty;var xe=(n,e)=>{for(var t in e)Re(n,t,{get:e[t],enumerable:true});};globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:10.4.0]";function Se(n,e){return e!==void 0?!e:n==="chain_exhausted"}var M=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 R(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 R("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 R("internal","token arrived for a superseded generation");return this.grant=o,this.rejected=false,this.enter("ready"),o.token}).catch(o=>{let a=ke(o),i=o?.retryable;throw t===this.generation&&this.enter(Se(a,typeof i=="boolean"?i:void 0)?"lost":"degraded",a),o instanceof R?o:new R(a,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)}},R=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 ke(n){if(n instanceof R)return n.reason;let e=n?.reason;return typeof e=="string"&&["chain_exhausted","unavailable","timeout","internal"].includes(e)?e:"internal"}var h=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}},$=["if-match","if-none-match"],V=4096;function we(n){if(!n)return;let e={};for(let[t,r]of Object.entries(n)){let o=t.toLowerCase();if(!$.includes(o)||r===void 0)continue;let a=typeof r=="string"?Ae(r):r;if(typeof a!="string"||a.length>V||!Pe(a))throw new h(`the ${o} header value cannot be sent \u2014 it is not a string, is longer than ${V} characters, or contains a character outside the range an HTTP header value may carry. This is a malformed request, not a server failure; the value is withheld here rather than written to logs.`);a!==""&&(e[o]=a);}return Object.freeze(e)}function Ae(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 Pe(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 h("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 h("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 W(n,e){let t=e.replayUnauthorizedOnce??true;return {async request(r){let o={...r},a=we(o.headers),i=Te(o),d=Object.freeze({...o,headers:a,...i===void 0?{}:{bytes:i}}),l=await e.tokenSource.get(),c=await n(d,l);if(c.status!==401||!t)return c;e.tokenSource.invalidate(l);let p=await e.tokenSource.get(),b=await n(d,p);if(b.status===401)throw e.tokenSource.close("unavailable"),new R("unavailable","the server refused a freshly minted token");return b}}}function z(n){let e=typeof n=="string"?new TextEncoder().encode(n):n;return btoa(Oe(e))}function Oe(n){let t="";for(let r=0;r<n.length;r+=32768)t+=String.fromCharCode(...n.subarray(r,r+32768));return t}var g=class extends Error{constructor(t,r,o,a,i){super(`${t} (${r}): ${o}`);this.reason=t;this.status=r;this.detail=o;this.retryAfterSeconds=a;this.code=i;this.name="GemApiError";}reason;status;detail;retryAfterSeconds;code;get retryable(){return this.reason==="unavailable"||this.reason==="rate_limited"}},Y=new WeakMap;function J(n){return Y.get(n)??{}}var Ge=new Set([408,429,500,502,503,504]),Ce=6e4;function Ee(n){if(n===void 0)return 2;if(!Number.isInteger(n)||n<0||n>10)throw new h(`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 T=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,...E(o)},o.replaySafe===true)}async post(e,t,r,o={}){return this.send({method:"POST",path:e,body:t,signal:r,...E(o)},o.replaySafe===true)}async postBytes(e,t,r,o={}){let a=await this.sendRaw({method:"POST",path:e,bytes:t,responseType:"bytes",signal:r,...E(o)},o.replaySafe===true);return {bytes:Ie(a.body),...a.invocationId===void 0?{}:{invocationId:a.invocationId}}}async patch(e,t,r,o={}){return this.send({method:"PATCH",path:e,body:t,signal:r,...E(o)},o.replaySafe===true)}async delete(e,t,r={}){return this.send({method:"DELETE",path:e,signal:t,...E(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 K(e.signal);for(let a=0;a<r;a++){if(a>0&&await this.backoff(a,o,e.signal),e.signal?.aborted)throw K(e.signal);let i;try{i=await this.options.transport.request(e);}catch(l){if(R.isAuthError(l)||h.isRefusal(l)||e.signal?.aborted||qe(l))throw l;o=new g("unavailable",0,String(l));continue}if(i.status>=200&&i.status<300||i.status===304)return i;let d=Le(i);if(!Ge.has(i.status))throw d;o=d;}throw o??new g("unavailable",0,"no attempt was made")}backoff(e,t,r){if(r?.aborted)return Promise.resolve();let o=t?.retryAfterSeconds,a=o!==void 0?o*1e3:2**(e-1)*250,i=2**(e-1)*250,d=Math.min(Math.max(a,i),Ce);return new Promise(l=>{let c=this.options.clock,p=false,b=false,S,_=()=>{p||(p=true,b&&c.clearTimeout(S),r?.removeEventListener("abort",_),l());};r?.addEventListener("abort",_,{once:true}),S=c.setTimeout(_,d),b=true,p&&c.clearTimeout(S);})}};function Ie(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 E(n){return {...n.keepalive===void 0?{}:{keepalive:n.keepalive},...n.ifMatch===void 0?{}:{headers:{"if-match":n.ifMatch}}}}function K(n){return n.reason!==void 0?n.reason:new DOMException("The operation was aborted.","AbortError")}function qe(n){let e=n?.name;return e==="AbortError"||e==="TimeoutError"}function Le(n){let e=$e(n),t=Fe(n.body),r={...t===void 0?{}:{details:t},...n.invocationId===void 0?{}:{invocationId:n.invocationId}};return Object.keys(r).length>0&&Y.set(e,r),e}var Me=new Map([["insufficient_funds","insufficient_funds"]]);function $e(n){let{status:e,body:t}=n,r=je(t),o=n.retryAfterSeconds??Ue(t),a=Be(t),i=a===void 0?void 0:Me.get(a);if(i!==void 0)return new g(i,e,r,void 0,a);switch(e){case 304:return new g("not_modified",e,r);case 400:case 422:return new g("invalid",e,r,void 0,a);case 403:return new g("forbidden",e,r,void 0,a);case 404:return new g("not_found",e,r,void 0,a);case 402:return new g("insufficient_funds",e,r,void 0,a);case 409:return new g("conflict",e,r,void 0,a);case 412:return new g("precondition_failed",e,r,void 0,a);case 413:return new g("too_large",e,r,void 0,a);case 429:return new g("rate_limited",e,r,o,a);default:return new g("unavailable",e,r,o,a)}}function je(n){if(typeof n=="string")return n;let e=n?.message;if(typeof e=="string")return e;let t=n?.error;if(typeof t=="string")return t;let r=t?.message;return typeof r=="string"?r:"no detail"}function Fe(n){let t=n?.error?.details;return t===null?void 0:t}function Be(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 Ne(n){let e=n.lastIndexOf("@");return (e===-1?n:`***@${n.slice(e+1)}`).slice(0,200)}var De=new Set($);function He(n){if(!n)return {};let e={};for(let[t,r]of Object.entries(n))De.has(t.toLowerCase())&&(e[t.toLowerCase()]=r);return e}function X(n){let e=n.fetch??globalThis.fetch.bind(globalThis);return W(async(t,r)=>{let o;try{o=new URL(n.baseUrl.replace(/\/+$/,""));}catch{throw new h("the configured baseUrl is not a valid URL. Its value is withheld here rather than written to logs. This is a configuration fault, not a server failure.")}let a;try{a=new URL(o.href.replace(/\/+$/,"")+t.path);}catch{throw new h(`${JSON.stringify(typeof t.path=="string"?Ne(t.path):"(a non-string path)")} does not form a valid URL against ${o.protocol}//${o.host}. This is a malformed request, not a server failure.`)}if(a.protocol!==o.protocol||a.host!==o.host)throw new h(`${JSON.stringify(a.pathname)} resolves to ${a.protocol}//${a.host}, not ${o.protocol}//${o.host}. A request path may not change the request's origin \u2014 it carries the play token.`);if(a.username!==""||a.password!==""){let _=o.username!==""||o.password!=="",y=a.username!==o.username||a.password!==o.password,m=_?y?"baseUrl (and possibly the request path)":"baseUrl":"request path";throw new h(`the ${m} puts credentials in the URL, which cannot be fetched (${t.method} ${a.pathname}). The value is withheld here rather than written to logs. This is a malformed request, not a server failure.`)}for(let[_,y]of Object.entries(n.defaultQuery??{}))a.searchParams.has(_)||a.searchParams.set(_,y);let i=t.bytes,d=t.bytes===void 0?void 0:"application/octet-stream";try{t.body!==void 0&&(i=JSON.stringify(t.body),d="application/json");}catch(_){throw new h(`the body of ${t.method} ${JSON.stringify(a.pathname)} could not be serialised to JSON: ${String(_)}. This is a bug in the request, not a server failure \u2014 retrying sends the same unserialisable value.`)}let l=await e(a.toString(),{method:t.method,headers:{authorization:`Bearer ${r}`,...d===void 0?{}:{"content-type":d},...He(t.headers)},body:i,signal:t.signal,...t.keepalive===void 0?{}:{keepalive:t.keepalive},credentials:"omit",mode:"cors",redirect:"error",cache:"no-store",referrerPolicy:"no-referrer"}),c=null;if(t.responseType==="bytes"&&l.status>=200&&l.status<300)c=new Uint8Array(await l.arrayBuffer());else {let _=await l.text();if(_.length>0)try{c=JSON.parse(_);}catch{c=_;}}let p=l.headers.get("etag"),b=Ve(l.headers.get("retry-after")),S=l.headers.get("x-gem-invocation-id");return {status:l.status,body:c,...p===null?{}:{etag:p},...b===void 0?{}:{retryAfterSeconds:b},...S===null||S===""?{}:{invocationId:S}}},n)}function Ve(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 We="gem-web-bridge";var O=65536,Q=8,j=5e3,Z=1024;function ee(n){return Object.freeze(Object.assign(Object.create(null),n))}ee({"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.controlsDeclare":60,"gem.menu":60,"gem.menuSelect":60,"gem.requestShare":6,"gem.requestAvatarPicker":6,"gem.vibrate":600,"gem.frameStats":120,"gem.portraitBorders":60,"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});ee({"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.portraitBorders":"portraitBorders","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.requestAvatarPicker":"avatarPicker","gem.vibrate":"vibration","gem.menu":"gameMenu","gem.menuSelect":"gameMenu","gem.controlsDeclare":"controls"});function Ke(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 Ye(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 Je(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function Xe(n){return /^[a-z_]+$/.test(n)}function B(n,e,t){if(e>Q)return `nesting deeper than ${Q}`;if(++t.nodes>j)return `more than ${j} 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>Z)return `an array of ${n.length} entries, over the ${Z} limit`;t.bytes+=2;for(let d of n){let l=B(d,e+1,t);if(l)return l}return null}let a=Object.getPrototypeOf(n);if(a!==Object.prototype&&a!==null)return "a value that is not a plain object";t.bytes+=2;let i=n;for(let d in i){if(!Object.prototype.hasOwnProperty.call(i,d))continue;if(++t.nodes>j)return `more than ${j} values`;if(t.bytes+=d.length*3+4,t.bytes>O)return `over the ${O} byte limit`;let l=B(i[d],e+1,t);if(l)return l}return null}function Qe(n){let e={nodes:0,bytes:0,seen:new Set},t=B(n,0,e);return t?`message contains ${t}`:e.bytes>O?`message is over the ${O} byte limit`:null}var Ze={origin:[Ke,"not a well-formed origin"],url:[Ye,"not a safe absolute http(s) URL"],bcp47:[Je,"not a well-formed BCP 47 tag"],code:[Xe,"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}`,a=n[r.n];if(a==null){if(r.o)continue;return `${o}: required`}let i=te(a,r,o);if(i)return i}return null}function te(n,e,t){switch(e.k){case "s":{if(typeof n!="string")return `${t}: expected string`;if(n.length>e.max)return `${t}: exceeds ${e.max} characters`;if(e.f){let[r,o]=Ze[e.f];if(!r(n))return `${t}: ${o}`}return null}case "i":return typeof n!="number"||!Number.isInteger(n)?`${t}: expected integer`:n<e.lo||n>e.hi?`${t}: out of range ${e.lo}..${e.hi}`:null;case "b":return typeof n=="boolean"?null:`${t}: expected boolean`;case "e":{let r=e.v;return r.includes(n)?null:`${t}: not one of ${r.join("|")}`}case "o":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:ne(n,e.fs,t);case "j":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected a plain object`:null;case "a":{if(!Array.isArray(n))return `${t}: expected array`;if(n.length>e.max)return `${t}: exceeds ${e.max} items`;let r=e.it,o=`${t}[]`;for(let a of n){if(a==null){if(r.o)continue;return `${o}: required`}let i=te(a,r,o);if(i)return i}return null}default:{let r=e.k;return `${t}: unknown kind ${String(r)}`}}}var re=Object.create(null);function u(n,e){return re[n]=t=>{let r=Qe(t);if(r)return r;if(typeof t!="object"||t===null||Array.isArray(t))return "message: expected object";let o=t;return o.gem!==We?"gem: wrong protocol marker":o.type!==n?`type: expected ${n}`:ne(o,e,"")}}u("gem.handshake",[{n:"versions",k:"o",fs:[{n:"min",k:"i",lo:1,hi:1e3},{n:"max",k:"i",lo:1,hi:1e3}]},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}},{n:"embedder",k:"s",max:2048,f:"origin"},{n:"unbidden",k:"b",o:1}]);u("gem.handshake.accept",[{n:"v",k:"i",lo:1,hi:1e3},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}}]);u("gem.token",[{n:"token",k:"s",max:4096},{n:"requestId",k:"s",o:1,max:64},{n:"generation",k:"i",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"s",o:1,max:512,f:"url"},{n:"playerId",k:"s",max:64},{n:"gameId",k:"s",max:64},{n:"channel",k:"e",v:["dev","test","release"]},{n:"gameVersion",k:"s",o:1,max:64},{n:"expiresAt",k:"i",lo:0,hi:4102444800},{n:"chainEndsAt",k:"i",lo:0,hi:4102444800},{n:"allowDevTools",k:"b",o:1}]);u("gem.token.denied",[{n:"requestId",k:"s",max:64},{n:"retryable",k:"b"},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:36e5},{n:"reason",k:"e",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"s",max:64}]);u("gem.player",[{n:"untrusted",k:"o",fs:[{n:"displayName",k:"s",max:64},{n:"displayTag",k:"s",o:1,max:80},{n:"displayHandle",k:"s",max:80}]},{n:"playerId",k:"s",o:1,max:64},{n:"discriminator",k:"s",o:1,max:8},{n:"avatarIconUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatarIconId",k:"s",o:1,max:64},{n:"badges",k:"a",o:1,max:2,it:{n:"",k:"o",fs:[{n:"itemId",k:"s",max:64},{n:"iconUrl",k:"s",max:2048,f:"url"}]}},{n:"displayTag",k:"s",max:8},{n:"avatarUrl",k:"s",o:1,max:2048,f:"url"},{n:"boost",k:"o",o:1,fs:[{n:"multipliers",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"currencyId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"multiplierBp",k:"i",lo:1e4,hi:1e6}]}},{n:"expiresInDays",k:"i",o:1,lo:1,hi:7}]}]);u("gem.pause",[{n:"paused",k:"b"}]);u("gem.prefs",[{n:"reducedMotion",k:"b"},{n:"muted",k:"b"},{n:"showFrameStats",k:"b",o:1},{n:"locale",k:"s",max:35,f:"bcp47"},{n:"recommended",k:"o",o:1,fs:[{n:"volume",k:"i",lo:0,hi:100},{n:"batterySaver",k:"b"},{n:"keyboardLayout",k:"e",v:["wasd","arrows"]},{n:"gamepadConfirm",k:"e",v:["south","east"]},{n:"vibration",k:"b"},{n:"lookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"gamepadLookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"invertLookY",k:"b",o:1},{n:"touchMovement",k:"s",o:1,max:16,f:"code"},{n:"graphicsQuality",k:"s",o:1,max:16,f:"code"},{n:"graphicsQualityAuto",k:"b",o:1}]}]);u("gem.cohorts",[{n:"cohorts",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"experimentId",k:"s",max:36},{n:"variantKey",k:"s",max:32}]}}]);u("gem.earnAllowanceChanged",[]);u("gem.viewport",[{n:"insets",k:"o",fs:[{n:"top",k:"i",lo:0,hi:4096},{n:"right",k:"i",lo:0,hi:4096},{n:"bottom",k:"i",lo:0,hi:4096},{n:"left",k:"i",lo:0,hi:4096}]},{n:"reserved",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384},{n:"width",k:"i",lo:0,hi:16384},{n:"height",k:"i",lo:0,hi:16384}]}}]);u("gem.deviceSettings",[{n:"settings",k:"j",o:1}]);u("gem.willTerminate",[{n:"reason",k:"e",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"i",lo:0,hi:6e4}]);u("gem.roomEvent",[{n:"event",k:"e",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"s",max:64},{n:"matchId",k:"s",o:1,max:64},{n:"version",k:"i",o:1,lo:0,hi:2147483647},{n:"reason",k:"s",o:1,max:64},{n:"platform",k:"e",o:1,v:["universal","mobile"]}]);u("gem.socketState",[{n:"connected",k:"b"},{n:"reason",k:"e",o:1,v:["connecting","dropped","watchdog","terminal"]}]);u("gem.seatedEvent",[{n:"roomId",k:"s",max:64}]);u("gem.autoStartFailedEvent",[{n:"roomId",k:"s",max:64},{n:"code",k:"s",max:64}]);u("gem.signalEvent",[{n:"event",k:"e",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}]);u("gem.dedicatedEvent",[{n:"event",k:"e",v:["answer","error","matchEnded"]},{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",o:1,max:10240},{n:"sessionId",k:"s",o:1,max:64},{n:"code",k:"s",o:1,max:64},{n:"message",k:"s",o:1,max:256},{n:"reason",k:"s",o:1,max:64}]);u("gem.partyResult",[{n:"requestId",k:"s",max:64},{n:"partyId",k:"s",o:1,max:64}]);u("gem.clusterTarget",[{n:"clusterTargetId",k:"s",max:64},{n:"clusterTargetIds",k:"a",o:1,max:3,it:{n:"",k:"s",max:64}}]);u("gem.devtools",[{n:"action",k:"e",v:["open","close","toggle"]}]);u("gem.screenshot",[{n:"maxWidth",k:"i",lo:1,hi:7680},{n:"maxHeight",k:"i",lo:1,hi:4320}]);u("gem.screenshot.denied",[{n:"reason",k:"e",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"b"}]);u("gem.requestContext",[]);u("gem.gameContext",[{n:"context",k:"j"}]);u("gem.signal",[{n:"signal",k:"e",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}]);u("gem.dedicatedOffer",[{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",max:10240},{n:"intent",k:"e",v:["initial","ice_restart","full_reconnect"]}]);u("gem.partyRequest",[{n:"requestId",k:"s",max:64}]);u("gem.ready",[]);u("gem.engaged",[]);u("gem.progress",[{n:"loaded",k:"i",lo:0,hi:1099511627776},{n:"total",k:"i",lo:0,hi:1099511627776}]);u("gem.requestToken",[{n:"requestId",k:"s",max:64},{n:"reason",k:"e",v:["initial","expiring","rejected"]}]);u("gem.requestLocalServer",[{n:"requestId",k:"s",max:64},{n:"gameRoomId",k:"s",max:64}]);u("gem.localServer",[{n:"requestId",k:"s",max:64},{n:"serverId",k:"s",o:1,max:128}]);u("gem.localServer.denied",[{n:"requestId",k:"s",max:64},{n:"retryable",k:"b"},{n:"reason",k:"e",v:["refused","unavailable"]}]);u("gem.exit",[{n:"reason",k:"s",o:1,max:64}]);u("gem.openExternal",[{n:"url",k:"s",max:2048,f:"url"}]);u("gem.requestFullscreen",[{n:"enabled",k:"b"}]);u("gem.audioState",[{n:"muted",k:"b"}]);u("gem.rewardCue",[{n:"currencySlug",k:"s",max:32},{n:"expected",k:"i",o:1,lo:1,hi:1e9},{n:"origin",k:"o",o:1,fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384}]}]);u("gem.walletDisplay",[{n:"visible",k:"b"},{n:"currencies",k:"a",o:1,max:8,it:{n:"",k:"s",max:64}},{n:"score",k:"b",o:1}]);u("gem.controlsDeclare",[{n:"uses",k:"o",fs:[{n:"lookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"gamepadLookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"invertLookY",k:"s",o:1,max:16,f:"code"},{n:"touchMovement",k:"s",o:1,max:16,f:"code"}]}]);u("gem.menu",[{n:"settings",k:"b"},{n:"items",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"id",k:"s",max:32},{n:"label",k:"s",max:40}]}}]);u("gem.menuSelect",[{n:"entry",k:"e",v:["settings","item"]},{n:"id",k:"s",o:1,max:32}]);u("gem.requestShare",[{n:"params",k:"a",max:16,it:{n:"",k:"o",fs:[{n:"key",k:"s",max:64},{n:"value",k:"s",max:512}]}}]);u("gem.requestAvatarPicker",[]);u("gem.vibrate",[{n:"pattern",k:"a",max:99,it:{n:"",k:"i",lo:0,hi:1e4}}]);u("gem.frameStats",[{n:"fps",k:"i",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"i",lo:0,hi:1e5}]);u("gem.portraitBorders",[{n:"name",k:"s",o:1,max:40}]);u("gem.error",[{n:"code",k:"e",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"s",o:1,max:256}]);u("gem.requestPurchase",[{n:"requestId",k:"s",max:64},{n:"purchaseKind",k:"e",v:["item","recipe"]},{n:"targetId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"quantity",k:"i",o:1,lo:1,hi:10},{n:"catalogId",k:"s",o:1,max:64}]);u("gem.purchaseResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["ok","declined","unavailable"]},{n:"reason",k:"s",o:1,max:64,f:"code"},{n:"purchaseId",k:"s",o:1,max:64}]);u("gem.deviceSettings.put",[{n:"requestId",k:"s",max:64},{n:"settings",k:"j"}]);u("gem.deviceSettings.result",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["stored","too_large","unavailable"]}]);u("gem.requestAd",[{n:"requestId",k:"s",max:64},{n:"placement",k:"s",max:32},{n:"format",k:"e",v:["interstitial","rewarded"]}]);u("gem.adResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["shown","no_ad","unavailable"]}]);u("gem.requestSignIn",[{n:"requestId",k:"s",max:64}]);u("gem.signInResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["signed_in","declined","unavailable"]}]);u("gem.requestFriendChallenge",[{n:"requestId",k:"s",max:64},{n:"playerId",k:"s",max:64},{n:"template",k:"s",max:64},{n:"params",k:"j",o:1}]);u("gem.friendChallengeResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["accepted","cancelled","refused","unavailable","rate_limited","invalid"]},{n:"code",k:"s",o:1,max:64},{n:"param",k:"s",o:1,max:64},{n:"channel",k:"s",o:1,max:16},{n:"configVersion",k:"i",o:1,lo:0,hi:9007199254740991},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:864e5},{n:"detail",k:"s",o:1,max:300}]);Object.freeze(re);var G={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)};var en=1e4;function oe(n,e){return U(n,e)}function U(n,e){if(typeof n.serverToken!="function"||typeof n.onServerToken!="function")throw new Error("this runtime delivers no game-server token: host.serverToken/onServerToken are missing. The server image running this bundle predates token delivery \u2014 the bundle cannot call gem-api on it.");let t=i=>({token:i.token,expiresAt:i.expiresAt,chainEndsAt:Number.POSITIVE_INFINITY}),r=null,o=new M({clock:e.clock,...e.onStateChange===void 0?{}:{onStateChange:e.onStateChange},request:()=>new Promise((i,d)=>{let l=e.clock.setTimeout(()=>{r=null,d({reason:"unavailable",retryable:true});},e.timeoutMs??en);r={resolve:c=>{e.clock.clearTimeout(l),i(c);},reject:d,timer:l};})}),a=n.onServerToken(i=>{let d=t(i),l=r;if(l){r=null,l.resolve(d);return}o.accept(d);});return {source:o,dispose(){a(),r&&(e.clock.clearTimeout(r.timer),r.reject({reason:"unavailable",retryable:false}),r=null);}}}var D={};xe(D,{acceptTransfer:()=>nn,addEntityProgression:()=>tn,adminAction:()=>rn,cancelInventoryTransfer:()=>on,claimEntityProgressionRewards:()=>an,closeGameRoom:()=>sn,createEntityBatchOrder:()=>ln,createEntityOrder:()=>dn,createSession:()=>un,deleteEntityGameSetting:()=>cn,deleteEntitySave:()=>mn,deleteSession:()=>gn,deleteShowcaseValue:()=>pn,executeEntityRecipe:()=>yn,finalizeSaveUpload:()=>fn,getChannelAssignment:()=>hn,getDropRates:()=>_n,getEntityCurrency:()=>bn,getEntityGameSetting:()=>vn,getEntityInventory:()=>Rn,getEntityInventoryItem:()=>xn,getEntityLeaderboard:()=>Sn,getEntityOrder:()=>kn,getEntityProgression:()=>wn,getEntityRecipeAvailability:()=>An,getEntityRecipeUsage:()=>Pn,getEntitySave:()=>Tn,getEvent:()=>On,getGameRoomV2:()=>Gn,getLeaderboard:()=>Cn,getPlayerGameProfile:()=>En,getPurchaseCatalog:()=>In,getResolvedTemplate:()=>qn,getRoomArgs:()=>Ln,getShowcaseValue:()=>Mn,getTransferDetails:()=>$n,ingestAnalyticsEvents:()=>N,initiateInventoryTransfer:()=>jn,invokeFunction:()=>Fn,kickPlayer:()=>Bn,listChallenges:()=>Un,listEntityGameSettings:()=>Nn,listEntityOrders:()=>Dn,listEntityProgressions:()=>Hn,listEntitySaves:()=>Vn,listEvents:()=>Wn,listGameRooms:()=>zn,listResolvedTemplates:()=>Kn,listTransfers:()=>Yn,maxEntityProgression:()=>Jn,putEntityGameSetting:()=>Xn,putRoomArgs:()=>Qn,putShowcaseValue:()=>Zn,rejectTransfer:()=>et,reportMatchPlayers:()=>nt,requestSaveUploadUrl:()=>tt,resetEntityProgression:()=>rt,setMatchBackfill:()=>ot,simulateEntityOrder:()=>at,transferHostV2:()=>st,updateGameRoomV2:()=>it});function s(n){let e=String(n);if(!/^[A-Za-z0-9_.-]{1,128}$/.test(e)||e==="."||e==="..")throw new TypeError(`${JSON.stringify(e)} is not a usable path segment \u2014 it is interpolated into a URL`);return encodeURIComponent(e)}async function nn(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/accept`;return n.client.post(r,void 0,t?.signal)}async function tn(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/add`;return n.client.post(i,o,a?.signal)}async function rn(n,e,t,r){let o=`/v1/voice/sessions/${s(e)}/admin`;return n.client.post(o,t,r?.signal)}async function on(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/cancel`;return n.client.post(r,void 0,t?.signal)}async function an(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/claim`;return n.client.post(i,o,a?.signal)}async function sn(n,e,t){let r=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.delete(r,t?.signal)}async function ln(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/batch`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function dn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function un(n,e,t){return n.client.post("/v1/voice/sessions",e,t?.signal)}async function cn(n,e,t,r,o){let a=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.delete(a,o?.signal)}async function mn(n,e,t,r,o){let a=`/v1/saves/${s(e)}/${s(t)}/${s(r)}`;return n.client.delete(a,o?.signal)}async function gn(n,e,t){let r=`/v1/voice/sessions/${s(e)}`;return n.client.delete(r,t?.signal)}async function pn(n,e,t,r){let o=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.delete(o,r?.signal)}async function yn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/recipes/execute`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function fn(n,e,t,r,o,a){let i=`/v1/saves/${s(e)}/${s(t)}/${s(r)}/finalize`;return n.client.post(i,o,a?.signal)}async function hn(n,e,t){let r=`/v1/games/${s(n.gameId())}/config/channels/${s(e)}`;return n.client.getWithEtag(r,{...t?.signal===void 0?{}:{signal:t.signal},...t?.ifNoneMatch===void 0?{}:{ifNoneMatch:t.ifNoneMatch}})}async function _n(n,e,t){let r=`/v1/inventory/loot-tables/${s(e)}/drop-rates`;return n.client.get(r,t?.signal)}async function bn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/currencies/${s(r)}`;return n.client.get(a,o?.signal)}async function vn(n,e,t,r,o){let a=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function Rn(n,e,t,r){let o=new URLSearchParams;r?.include_buckets!==void 0&&o.set("include_buckets",String(r?.include_buckets)),r?.include_custom_data!==void 0&&o.set("include_custom_data",String(r?.include_custom_data)),r?.currency_limit!==void 0&&o.set("currency_limit",String(r?.currency_limit)),r?.currency_cursor!==void 0&&o.set("currency_cursor",String(r?.currency_cursor)),r?.item_limit!==void 0&&o.set("item_limit",String(r?.item_limit)),r?.item_cursor!==void 0&&o.set("item_cursor",String(r?.item_cursor)),r?.progression_limit!==void 0&&o.set("progression_limit",String(r?.progression_limit)),r?.progression_cursor!==void 0&&o.set("progression_cursor",String(r?.progression_cursor));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function xn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/items/${s(r)}`;return n.client.get(a,o?.signal)}async function Sn(n,e,t,r,o){let a=new URLSearchParams;o?.bucket_1!==void 0&&a.set("bucket_1",String(o?.bucket_1)),o?.bucket_2!==void 0&&a.set("bucket_2",String(o?.bucket_2)),o?.limit!==void 0&&a.set("limit",String(o?.limit)),o?.periods_back!==void 0&&a.set("periods_back",String(o?.periods_back)),o?.period!==void 0&&a.set("period",String(o?.period)),o?.player_id!==void 0&&a.set("player_id",String(o?.player_id));let i=a.toString(),d=`/v1/leaderboards/${s(e)}/${s(t)}/${s(r)}`+(i?`?${i}`:"");return n.client.get(d,o?.signal)}async function kn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/${s(r)}`;return n.client.get(a,o?.signal)}async function wn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}`;return n.client.get(a,o?.signal)}async function An(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/catalogs/${s(r)}/recipes/${s(o)}/availability`;return n.client.get(i,a?.signal)}async function Pn(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}/recipe-usage`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function Tn(n,e,t,r,o){let a=`/v1/saves/${s(e)}/${s(t)}/${s(r)}`;return n.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function On(n,e,t){let r=`/v1/events/${s(e)}`;return n.client.get(r,t?.signal)}async function Gn(n,e,t){let r=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.getWithEtag(r,{...t?.signal===void 0?{}:{signal:t.signal},...t?.ifNoneMatch===void 0?{}:{ifNoneMatch:t.ifNoneMatch}})}async function Cn(n,e,t){let r=new URLSearchParams;t?.bucket_1!==void 0&&r.set("bucket_1",String(t?.bucket_1)),t?.bucket_2!==void 0&&r.set("bucket_2",String(t?.bucket_2)),t?.periods_back!==void 0&&r.set("periods_back",String(t?.periods_back)),t?.period!==void 0&&r.set("period",String(t?.period)),t?.player_id!==void 0&&r.set("player_id",String(t?.player_id));let o=r.toString(),a=`/v1/leaderboards/${s(e)}`+(o?`?${o}`:"");return n.client.get(a,t?.signal)}async function En(n,e,t){let r=`/v1/profiles/players/${s(e)}`;return n.client.get(r,t?.signal)}async function In(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 qn(n,e,t){let r=`/v1/game-room-templates/${s(e)}`;return n.client.get(r,t?.signal)}async function Ln(n,e,t){let r=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/room-args`;return n.client.get(r,t?.signal)}async function Mn(n,e,t,r){let o=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.get(o,r?.signal)}async function $n(n,e,t){let r=`/v1/inventory/transfers/${s(e)}`;return n.client.get(r,t?.signal)}async function N(n,e,t){let r=`/v1/games/${s(n.gameId())}/analytics/events`;return n.client.post(r,e,t?.signal,{replaySafe:true})}async function jn(n,e,t){return n.client.post("/v1/inventory/transfers",e,t?.signal)}async function Fn(n,e,t){return n.client.postBytes("/v1/functions/invoke",e,t?.signal)}async function Bn(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/kick/${s(t)}`;return n.client.post(o,void 0,r?.signal)}async function Un(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 Nn(n,e,t,r){let o=`/v1/settings/${s(e)}/${s(t)}`;return n.client.get(o,r?.signal)}async function Dn(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}/orders`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function Hn(n,e,t,r){let o=`/v1/inventory/${s(e)}/${s(t)}/progressions`;return n.client.get(o,r?.signal)}async function Vn(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),i=`/v1/saves/${s(e)}/${s(t)}`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function Wn(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 zn(n,e){let t=new URLSearchParams;e?.status!==void 0&&t.set("status",String(e?.status)),e?.game_channel!==void 0&&t.set("game_channel",String(e?.game_channel)),e?.game_room_type!==void 0&&t.set("game_room_type",String(e?.game_room_type)),e?.template_id!==void 0&&t.set("template_id",String(e?.template_id)),e?.template_slug!==void 0&&t.set("template_slug",String(e?.template_slug)),e?.limit!==void 0&&t.set("limit",String(e?.limit)),e?.cursor!==void 0&&t.set("cursor",String(e?.cursor));let r=t.toString(),o=`/v1/games/${s(n.gameId())}/game-rooms`+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function Kn(n,e){return n.client.get("/v1/game-room-templates",e?.signal)}async function Yn(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 Jn(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/max`;return n.client.post(i,o,a?.signal)}async function Xn(n,e,t,r,o,a){let i=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.put(i,o,a?.signal,{...a?.ifMatch===void 0?{}:{ifMatch:a.ifMatch}})}async function Qn(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/room-args`;return n.client.put(o,t,r?.signal)}async function Zn(n,e,t,r,o){let a=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.put(a,r,o?.signal)}async function et(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/reject`;return n.client.post(r,void 0,t?.signal)}async function nt(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/matches/${s(e)}/players/report`;return n.client.post(o,t,r?.signal)}async function tt(n,e,t,r,o,a){let i=`/v1/saves/${s(e)}/${s(t)}/${s(r)}/upload-url`;return n.client.post(i,o,a?.signal,{replaySafe:true})}async function rt(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/reset`;return n.client.post(i,o,a?.signal)}async function ot(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/matches/${s(e)}/backfill`;return n.client.put(o,t,r?.signal)}async function at(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/simulate`;return n.client.post(a,r,o?.signal)}async function st(n,e,t,r){let o=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}/transfer/${s(t)}`;return n.client.post(o,void 0,r?.signal)}async function it(n,e,t,r){let o=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.patch(o,t,r?.signal,{...r?.ifMatch===void 0?{}:{ifMatch:r.ifMatch}})}var ae="gem_";var ut=1e4,ct=50,mt=1e3,gt=65536-4*1024,se=n=>typeof n=="number"?n:0,pt=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 yt(n){return n?.retryable===true}function ft(n,e){let t=n??{},r=Array.isArray(t.rejected)?t.rejected.map(o=>{let a=o??{};return {index:se(a.index),code:pt(a.code)}}):[];return {accepted:se(t.accepted),rejected:r,dropped:e,duplicate:t.duplicate===true}}function le(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 de(n){let e=Math.max(1,Math.floor(n.maxQueue??mt)),t={client:n.client,gameId:()=>n.gameId},r=[],o=0,a=null,i=false,d=false,l=false,c=false,p=m=>{n.log?.(m);},b=()=>{a!==null&&(n.clock.clearTimeout(a),a=null);},S=()=>{a!==null||i||d||(a=n.clock.setTimeout(()=>{a=null,y().catch(()=>{});},ut));},_=()=>{let m=Math.min(r.length,100),f=128;for(let v=0;v<m;v+=1){let A=r[v];if(A===void 0)break;if(f+=JSON.stringify(le(A,0)).length+1,f>gt)return Math.max(1,v)}return m};async function y(m){if(r.length===0)return {accepted:0,rejected:[],dropped:0,duplicate:false};b();let f=r.splice(0,_()),v=o;o=0;let A=Math.round(n.clock.now()),L={batch_id:ie(),sent_at_ms:A,events:f.map(k=>le(k,A))};d=true;try{let k=await N(t,L,m===void 0?void 0:{signal:m}),P=ft(k,v);for(let ve of P.rejected)p(`[gem] analytics: an event was refused (${ve.code}). See the analytics_events section of your game config.`);return P}catch(k){if(yt(k))for(r=[...f,...r],o+=v;r.length>e;)r.shift(),o+=1;else p(`[gem] analytics: ${f.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(k)}`);throw k}finally{d=false,r.length>0&&S();}}return {track(m,f,v={}){if(i)return;if(typeof m!="string"||m===""){c||(c=true,p(`[gem] analytics: '${f}' 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(f.startsWith(ae)){l||(l=true,p(`[gem] analytics: '${f}' 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[k,P]of Object.entries(v))typeof P=="string"?A[k]=P:typeof P=="number"&&Number.isFinite(P)&&(L[k]=P);for(;r.length>=e;)r.shift(),o+=1;r.push({uid:ie(),playerId:m,name:f,atMs:n.clock.now(),dimensions:A,measures:L}),r.length>=ct?y().catch(()=>{}):S();},flush:m=>y(m),get pending(){return r.length},dispose(){i=true,b(),r=[],o=0;}}}var ht=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 g{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:ht.get(this.code))??super.retryable}},C=class{#e;constructor(e){this.#e=e;}async invoke(e,t={}){let r=_t(e),o;try{o=await this.#e(r,t.signal===void 0?{}:{signal:t.signal});}catch(a){throw a instanceof g?vt(a):a}return bt(o)}};function _t(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 h(`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 h(`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 bt(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 vt(n){let{details:e,invocationId:t}=J(n),o=e?.untrusted?.message,a=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 a=="string"?{failure:a}:{}})}var w=n=>typeof n=="string"?n:"",Rt=/(?:Z|[+-]\d{2}:?\d{2})$/i;function ue(n){let e=w(n);if(!Rt.test(e))return 0;let t=Date.parse(e);return Number.isFinite(t)?Math.floor(t/1e3):0}var xt=/^[0-9a-f]{1,64}$/,St=/^[0-9a-f]{16}$/,kt=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,wt=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function At(n){let e=w(n),t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!t)return;let[r,o,a]=[Number(t[1]),Number(t[2]),Number(t[3])],i=new Date(Date.UTC(r,o-1,a));return i.getUTCFullYear()===r&&i.getUTCMonth()===o-1&&i.getUTCDate()===a?e:void 0}var Pt=4096,Tt=new TextEncoder;function Ot(n){let e=w(n.challenge_data),t=w(n.challenge_data_hash);return e===""||!St.test(t)?{}:Tt.encode(e).length>Pt?{}:{data:e,dataHash:t}}function Gt(n){let e=n??{},t=ue(e.period_start_at),r=ue(e.period_ends_at);if(t===0||r===0)return;let o=w(e.slug),a=w(e.seed),i=At(e.period_local_date),d=w(e.boundary),l=w(e.reset_time);return {id:w(e.progression_definition_id),...o===""?{}:{slug:o},window:w(e.window),periodStartAt:t,periodEndsAt:r,...i===void 0?{}:{periodLocalDate:i},boundary:kt.test(d)?d:"",resetTime:wt.test(l)?l:"",seed:xt.test(a)?a:"",...Ot(e)}}function ce(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 me(n){let e=n??{};return Array.isArray(e.challenges)?e.challenges.map(Gt).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().");ce(r);let a=await n({player_id:t,...r===void 0?{}:{periods_back:r},...o===void 0?{}:{signal:o}});return me(a)}}}function Ct(n){let e={};for(let[t,r]of Object.entries(D))if(typeof r=="function"){let o=r;e[t]=(...a)=>o(n,...a);}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=U(n,{clock:t,...e.onAuthStateChange===void 0?{}:{onStateChange:e.onAuthStateChange}}),a=X({baseUrl:r,tokenSource:o.source,defaultQuery:{game_id:n.gameId,channel:n.channel},...e.fetch===void 0?{}:{fetch:e.fetch}}),i=new T({transport:a,clock:t}),d={gameId:n.gameId,channel:n.channel,matchId:n.matchId,...n.gameRoomId===void 0?{}:{gameRoomId:n.gameRoomId}},l=Ct({client:i,gameId:()=>d.gameId}),c=d.gameRoomId,p=n.endMatch,b=n.log,S=de({client:i,clock:t,gameId:d.gameId,...typeof b=="function"?{log:y=>b.call(n,y)}:{}});return {identity:d,client:i,api:l,match:{end:async()=>{if(p===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 p.call(n);},setBackfill:async(y,m)=>{let f=await l.setMatchBackfill(d.matchId,{open:y.open,...y.seats===void 0?{}:{seats:y.seats}},m===void 0?{}:{signal:m});return {open:f.open,seats:f.seats??null}},reportPlayers:async(y,m)=>(await l.reportMatchPlayers(d.matchId,{players:y.map(v=>({player_id:v.playerId,state:v.state}))},m===void 0?{}:{signal:m})).players.map(v=>({playerId:v.player_id,outcome:v.outcome}))},analytics:S,functions:new C(l.invokeFunction),challenges:ge(l.listChallenges),...c===void 0?{}:{room:{get:y=>l.getGameRoomV2(c,y),args:async y=>{let m=await l.getGameRoomV2(c,y?.signal===void 0?{}:{signal:y.signal}),f=m.modified?m.body:void 0;if(f?.room_args==null||f.room_args_template==null)throw new g("not_found",404,"this room's template declares no room args",void 0,"room_args_not_defined");return {room_args:f.room_args,room_args_template:f.room_args_template}}}},dispose:()=>{S.dispose(),o.dispose();}}}var Et=["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"],It=new Set(Et);function pe(n){return typeof n=="string"&&It.has(n)?n:"unknown"}var x=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 x(n)}var ye={toPlain(n){return x.unwrap(n)},compare(n,e,t){let r=n instanceof x?x.unwrap(n):n,o=e instanceof x?x.unwrap(e):e,a;try{a=new Intl.Collator(t);}catch{a=new Intl.Collator;}return a.compare(r,o)},equals(n,e){let t=n instanceof x?x.unwrap(n):n,r=e instanceof x?x.unwrap(e):e;return t.normalize("NFC")===r.normalize("NFC")}};var fe="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 H(n,e={}){let t=e.clock??G,r=()=>{let d=n();if(d===null)throw new Error(fe);return d},o=null,a=()=>{if(o===null)throw new Error(fe);return o};return {server:{get identity(){return a().identity},get client(){return a().client},get api(){return a().api},get match(){return a().match},get analytics(){return a().analytics},get functions(){return a().functions},get challenges(){return a().challenges},get room(){return a().room},dispose(){o?.dispose();},get sizeClass(){return r().sizeClass},get roomArgs(){return r().roomArgs},get roster(){return r().roster},players(){return r().players()},profile(d){let c=r().profile?.(d);if(!c)return null;let p=c.displayName;return typeof p!="string"||p===""?null:{displayName:q(p),...typeof c.displayTag=="string"&&c.displayTag!==""?{displayTag:q(c.displayTag)}:{},...typeof c.discriminator=="string"?{discriminator:c.discriminator}:{}}},playerNumber(d){return r().playerNumber?.(d)},send(d,l,c){c===void 0?r().send(d,l):r().send(d,l,c);},broadcast(d,l){l===void 0?r().broadcast(d):r().broadcast(d,l);},kick(d,l){l===void 0?r().kick(d):r().kick(d,l);},log(d){r().log(d);},warn(d){r().warn(d);}},attach:()=>{o=F(r(),{...e,clock:t});}}}function he(n,e={}){let{server:t,attach:r}=H(()=>n,e);return r(),t}function qt(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:pe(e)}}}var Lt=1e4;function Mt(n){let e=false;return t=>{if(e)return;let r;try{r=n.match.reportPlayers([{playerId:t,state:"connected"}],AbortSignal.timeout(Lt));}catch{return}r.catch(o=>{o instanceof g&&o.status>=400&&o.status<500&&(e=o.status!==429);});}}function _e(n,e={}){return ()=>{let t=null,{server:r,attach:o}=H(()=>t,e),a=n(r),i={async init(l){t=l,o(),await a.init?.();},async shutdown(l){let c=qt(l);try{await a.shutdown?.(c);}finally{r.dispose();}}},d=Mt(r);return i.join=(l,c)=>(d(l),a.join?.(l,c)),a.leave&&(i.leave=(l,c)=>a.leave?.(l,c)),a.message&&(i.message=(l,c,p,b)=>a.message?.(l,c,p,b)),i}}var $t=new Set(["unlocked","already_unlocked","suppressed"]);function be(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"||!$t.has(o.outcome)||typeof o.achievement_id!="string"||o.achievement_id==="")continue;let a=o.outcome;t.push({achievementId:o.achievement_id,progressionDefinitionId:typeof o.progression_definition_id=="string"?o.progression_definition_id:"",points:a==="unlocked"&&typeof o.points=="number"&&Number.isFinite(o.points)?o.points:0,outcome:a,...typeof o.reason=="string"?{reason:o.reason}:{}});}return t}
2
2
  export{R as AuthError,$ as CONDITIONAL_HEADERS,C as FunctionsApi,g as GemApiError,T as GemClient,I as GemFunctionError,x as PlayerText,h as TransportRefusal,be as achievementReceipts,q as asPlayerText,F as createGemServer,oe as createHostTokenSource,he as createMatchServer,_e as defineServer,G as systemClock,ye as text,z as toBase64};//# sourceMappingURL=gem-web-sdk.server.js.map
3
3
  //# sourceMappingURL=gem-web-sdk.server.js.map
package/dist/index.d.ts CHANGED
@@ -173,6 +173,8 @@ interface GemPrefs {
173
173
  gamepadLookSensitivity?: number;
174
174
  invertLookY?: boolean;
175
175
  touchMovement?: string;
176
+ graphicsQuality?: string;
177
+ graphicsQualityAuto?: boolean;
176
178
  };
177
179
  }
178
180
  interface GemCohorts {
@@ -894,6 +896,8 @@ declare class GemHost {
894
896
  gamepadLookSensitivity?: number;
895
897
  invertLookY?: boolean;
896
898
  touchMovement?: "floating" | "fixed";
899
+ graphicsQuality?: "low" | "medium" | "high";
900
+ graphicsQualityAuto?: boolean;
897
901
  };
898
902
  }): void;
899
903
  sendCohorts(cohorts: ReadonlyArray<{
@@ -0,0 +1,49 @@
1
+ type GemGraphicsQuality = "low" | "medium" | "high";
2
+ type QualityChangeReason = "down" | "up" | "reset";
3
+ interface QualityGovernorGem {
4
+ readonly prefs: {
5
+ readonly recommended: {
6
+ readonly batterySaver: boolean;
7
+ readonly graphicsQuality?: string;
8
+ readonly graphicsQualityAuto?: boolean;
9
+ } | null;
10
+ } | null;
11
+ readonly paused?: boolean;
12
+ }
13
+ interface QualityGovernorOptions<L> {
14
+ readonly levels: readonly L[] | number;
15
+ readonly gem?: QualityGovernorGem | null;
16
+ readonly start?: L;
17
+ readonly auto?: boolean;
18
+ readonly targetFps?: number;
19
+ readonly manual?: boolean;
20
+ readonly onChange?: (level: L, reason: QualityChangeReason) => void;
21
+ readonly requestFrame?: (callback: (time: number) => void) => number;
22
+ readonly cancelFrame?: (handle: number) => void;
23
+ readonly hidden?: () => boolean;
24
+ }
25
+ interface QualityGovernorStats {
26
+ readonly fps: number;
27
+ readonly p90Ms: number;
28
+ readonly budgetMs: number;
29
+ readonly frames: number;
30
+ readonly changes: number;
31
+ readonly index: number;
32
+ readonly startIndex: number;
33
+ readonly maxIndex: number;
34
+ readonly held: boolean;
35
+ readonly paused: boolean;
36
+ }
37
+ interface QualityGovernor<L> {
38
+ readonly level: L;
39
+ readonly stats: QualityGovernorStats;
40
+ frame(dtMs: number): void;
41
+ dispose(): void;
42
+ }
43
+ declare function createQualityGovernor<const L extends string>(options: QualityGovernorOptions<L> & {
44
+ readonly levels: readonly L[];
45
+ }): QualityGovernor<L>;
46
+ declare function createQualityGovernor(options: QualityGovernorOptions<number> & {
47
+ readonly levels: number;
48
+ }): QualityGovernor<number>;
49
+ export { type GemGraphicsQuality, type QualityChangeReason, type QualityGovernor, type QualityGovernorGem, type QualityGovernorOptions, type QualityGovernorStats, createQualityGovernor };
package/dist/sdk.d.ts CHANGED
@@ -2034,6 +2034,8 @@ interface GemPrefs$1 {
2034
2034
  gamepadLookSensitivity?: number;
2035
2035
  invertLookY?: boolean;
2036
2036
  touchMovement?: string;
2037
+ graphicsQuality?: string;
2038
+ graphicsQualityAuto?: boolean;
2037
2039
  };
2038
2040
  }
2039
2041
  interface GemCohorts$1 {
@@ -4509,6 +4511,7 @@ interface ControlsApi {
4509
4511
  look(options?: GemLookOptions): GemLook;
4510
4512
  readonly LOOK_BASE: GemLookBase;
4511
4513
  }
4514
+ type GemGraphicsQuality = "low" | "medium" | "high";
4512
4515
  interface RewardedStatus {
4513
4516
  readonly declared: boolean;
4514
4517
  readonly grantable: boolean;
@@ -4599,6 +4602,8 @@ interface GemRecommendedSettings {
4599
4602
  readonly gamepadLookSensitivity: number;
4600
4603
  readonly invertLookY: boolean;
4601
4604
  readonly touchMovement: "floating" | "fixed";
4605
+ readonly graphicsQuality: GemGraphicsQuality;
4606
+ readonly graphicsQualityAuto: boolean;
4602
4607
  }
4603
4608
  interface GemCohort {
4604
4609
  readonly experimentId: string;
@@ -4671,6 +4676,7 @@ interface Gem {
4671
4676
  readonly functions: FunctionsApi;
4672
4677
  awaitPlayer(timeoutMs?: number): Promise<GemPlayer | null>;
4673
4678
  readonly prefs: GemPrefs | null;
4679
+ readonly paused: boolean;
4674
4680
  readonly cohorts: GemCohorts | null;
4675
4681
  readonly viewport: GemViewport | null;
4676
4682
  awaitCohorts(timeoutMs?: number): Promise<GemCohorts | null>;
@@ -4704,4 +4710,4 @@ interface ExitAnalytics {
4704
4710
  }
4705
4711
  declare function leaveAndExit(rooms: ExitRooms, bridge: ExitBridge | null, reason?: string, analytics?: ExitAnalytics): Promise<void>;
4706
4712
  declare function createGem(options?: GemOptions): Gem;
4707
- export { ARCADE_EMBEDDERS, type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection$1 as AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type Base64String, type BootMark, type BootTimeline, type BroadcastOptions, type BytesResponse, CONDITIONAL_HEADERS, type Challenge, type ChallengeWindow, ChallengesApi, type ClientOptions, type Clock, type ConditionalRequestHeaders, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, type ControlsApi, DEVICE_SETTINGS_MAX_BYTES, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DevToolsOpener, type DeviceSettings, type DeviceSettingsApi, type DeviceSettingsPutOutcome, type DirectPurchaseRequest, type DirectPurchaseResult, type EarnAllowance, type EarnAllowanceEvent, type EarnAllowancePeriod, type EarnAllowanceReadOptions, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, type EntityType$1 as EntityType, type ExitAnalytics, type ExitBridge, type ExitRooms, type FrameState, type Friend, type FriendChallenge, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, type FriendChallengesPage, FriendsApi, type FriendsPage, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, FunctionsApi, type GameApi, type GameConfig, type GameMenu, type GameMenuItem, type GameServerLink, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemControlChoice, type GemControlsDeclaration, type GemDevTools, type GemErrorReason, GemFrame, GemFunctionError, type GemIdentity, type GemInsets, type GemLook, type GemLookBase, type GemLookDelta, type GemLookOptions, type GemLookSpeed, type GemMatchApi, type GemMatchServer, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, type GemRecommendedSettings, type GemReservedArea, GemSaveError, type GemServer, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerIdentity, type GemServerLifecycle, type GemServerOptions, type GemServerProfile, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type HostTokenSource, type HostTokenSourceOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchBackfillState, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchPlayerReport, type MatchPlayerReportResult, type MatchServeOptions, type MatchTransport, type MessageMeta, type MultiTransportSession, PLATFORM_EVENTS, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayerBadge$1 as PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry$1 as ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RequestOptions, type RewardCue, type RewardedStatus, type RoomArgValue, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerApi, type ServerBundleHost, type ServerTokenGrant, type SessionEndReason, type ShareApi, type ShareRequest, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SnapshotCurrency, type SnapshotItem, type TokenGrant, type Transport, type TransportAdvert, type TransportKind, TransportRefusal, type TransportRequest, type TransportResponse, UNRELIABLE_CHANNEL_LABEL, type VersionedGetOptions, type VersionedResponse, type VibrationApi, type WalletVisibleOptions, asPlayerText, createBootTimeline, createGem, createGemServer, createHostTokenSource, createMatchServer, defineServer, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, systemClock, text, toBase64, webTransportAvailable };
4713
+ export { ARCADE_EMBEDDERS, type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection$1 as AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type Base64String, type BootMark, type BootTimeline, type BroadcastOptions, type BytesResponse, CONDITIONAL_HEADERS, type Challenge, type ChallengeWindow, ChallengesApi, type ClientOptions, type Clock, type ConditionalRequestHeaders, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, type ControlsApi, DEVICE_SETTINGS_MAX_BYTES, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DevToolsOpener, type DeviceSettings, type DeviceSettingsApi, type DeviceSettingsPutOutcome, type DirectPurchaseRequest, type DirectPurchaseResult, type EarnAllowance, type EarnAllowanceEvent, type EarnAllowancePeriod, type EarnAllowanceReadOptions, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, type EntityType$1 as EntityType, type ExitAnalytics, type ExitBridge, type ExitRooms, type FrameState, type Friend, type FriendChallenge, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, type FriendChallengesPage, FriendsApi, type FriendsPage, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, FunctionsApi, type GameApi, type GameConfig, type GameMenu, type GameMenuItem, type GameServerLink, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemControlChoice, type GemControlsDeclaration, type GemDevTools, type GemErrorReason, GemFrame, GemFunctionError, type GemGraphicsQuality, type GemIdentity, type GemInsets, type GemLook, type GemLookBase, type GemLookDelta, type GemLookOptions, type GemLookSpeed, type GemMatchApi, type GemMatchServer, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, type GemRecommendedSettings, type GemReservedArea, GemSaveError, type GemServer, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerIdentity, type GemServerLifecycle, type GemServerOptions, type GemServerProfile, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type HostTokenSource, type HostTokenSourceOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchBackfillState, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchPlayerReport, type MatchPlayerReportResult, type MatchServeOptions, type MatchTransport, type MessageMeta, type MultiTransportSession, PLATFORM_EVENTS, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayerBadge$1 as PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry$1 as ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RequestOptions, type RewardCue, type RewardedStatus, type RoomArgValue, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerApi, type ServerBundleHost, type ServerTokenGrant, type SessionEndReason, type ShareApi, type ShareRequest, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SnapshotCurrency, type SnapshotItem, type TokenGrant, type Transport, type TransportAdvert, type TransportKind, TransportRefusal, type TransportRequest, type TransportResponse, UNRELIABLE_CHANNEL_LABEL, type VersionedGetOptions, type VersionedResponse, type VibrationApi, type WalletVisibleOptions, asPlayerText, createBootTimeline, createGem, createGemServer, createHostTokenSource, createMatchServer, defineServer, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, systemClock, text, toBase64, webTransportAvailable };
@@ -1,6 +1,6 @@
1
1
  # The browser surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/sdk` v10.3.1, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
3
+ Generated from `@indiegems/gem-web-sdk/sdk` v10.4.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
4
4
 
5
5
  `@indiegems/gem-web-sdk/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
 
@@ -7704,9 +7704,10 @@ readonly recommended: GemRecommendedSettings | null
7704
7704
  ```
7705
7705
 
7706
7706
  The player's Arcade-wide defaults for this device — a volume, battery
7707
- saver, a keyboard layout, the gamepad's confirm button, vibration, and the
7707
+ saver, a keyboard layout, the gamepad's confirm button, vibration, the
7708
7708
  camera and controls settings (look sensitivity, gamepad look sensitivity,
7709
- invert look, touch movement) — or `null` when the Arcade did not send them.
7709
+ invert look, touch movement) and a starting graphics quality — or `null`
7710
+ when the Arcade did not send them.
7710
7711
 
7711
7712
  **Recommendations only; the player's own choice in your game wins.** Start
7712
7713
  a setting from here while the player has made no choice of their own for
@@ -7838,6 +7839,36 @@ On a touch screen, the movement thumbstick the player wants: `'floating'`
7838
7839
  appears where the thumb lands, `'fixed'` stays in one place. `'floating'`
7839
7840
  when the Arcade did not say. Your game draws the stick.
7840
7841
 
7842
+ <a id="gemrecommendedsettings-graphicsquality"></a>
7843
+
7844
+ ## GemRecommendedSettings.graphicsQuality
7845
+
7846
+ ```ts
7847
+ readonly graphicsQuality: GemGraphicsQuality
7848
+ ```
7849
+
7850
+ The graphics quality to START at on this device: `'low'`, `'medium'` or
7851
+ `'high'`. The Arcade picks it per device — the tier it detected, or the
7852
+ player's own Graphics choice — so a game opens at a quality that suits the
7853
+ device instead of guessing. A starting point, not a cap: while
7854
+ `graphicsQualityAuto` is true your game may adapt from here as it runs,
7855
+ and `createQualityGovernor` from `@indiegems/gem-web-sdk/quality` does
7856
+ that for you. When the Arcade did not say, `'low'` with `batterySaver`
7857
+ on and `'medium'` otherwise.
7858
+
7859
+ <a id="gemrecommendedsettings-graphicsqualityauto"></a>
7860
+
7861
+ ## GemRecommendedSettings.graphicsQualityAuto
7862
+
7863
+ ```ts
7864
+ readonly graphicsQualityAuto: boolean
7865
+ ```
7866
+
7867
+ Whether the Arcade chose `graphicsQuality` for this device (`true`, the
7868
+ player left Graphics on Auto) or the player picked it by hand (`false`).
7869
+ While it is `false`, hold that quality: never step it down or up on your
7870
+ own. `true` when the Arcade did not say.
7871
+
7841
7872
  <a id="gemcohort"></a>
7842
7873
 
7843
7874
  ## GemCohort
@@ -8931,6 +8962,20 @@ honouring them is part of the platform's release checklist.
8931
8962
  Read it at the moment you need it rather than caching it: the locale can
8932
8963
  change mid-session.
8933
8964
 
8965
+ <a id="gem-paused"></a>
8966
+
8967
+ ## Gem.paused
8968
+
8969
+ ```ts
8970
+ readonly paused: boolean
8971
+ ```
8972
+
8973
+ Whether the arcade has your game paused right now: `true` from an
8974
+ `onPause(true)` until the `onPause(false)` that follows it, `false` before
8975
+ any. The same pause `onPause` tells you about, readable at any moment —
8976
+ for code that was not around when the edge arrived, such as a frame-time
8977
+ monitor deciding whether a slow frame counts.
8978
+
8934
8979
  <a id="gem-cohorts"></a>
8935
8980
 
8936
8981
  ## Gem.cohorts
@@ -11692,6 +11737,17 @@ readonly code: "unknown_currency" | "not_purchasable" | "no_price_in_currency" |
11692
11737
  Which check refused: `unknown_currency`, `not_purchasable`,
11693
11738
  `no_price_in_currency` or `quantity_invalid`.
11694
11739
 
11740
+ <a id="gemgraphicsquality"></a>
11741
+
11742
+ ## GemGraphicsQuality
11743
+
11744
+ ```ts
11745
+ type GemGraphicsQuality = "low" | "medium" | "high"
11746
+ ```
11747
+
11748
+ A graphics quality tier: `'low'`, `'medium'` or `'high'`. What
11749
+ `gem.prefs.recommended.graphicsQuality` holds.
11750
+
11695
11751
  <a id="servertokengrant"></a>
11696
11752
 
11697
11753
  ## ServerTokenGrant
@@ -1,6 +1,6 @@
1
1
  # The server surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/sdk` v10.3.1, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
3
+ Generated from `@indiegems/gem-web-sdk/sdk` v10.4.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
4
4
 
5
5
  `@indiegems/gem-web-sdk/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