@indiegems/gem-web-sdk 23.2.0 → 23.3.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.
- package/CHANGELOG.md +18 -0
- package/dist/game.d.ts +3 -1
- package/dist/gem-web-sdk.bridge.js +2 -2
- package/dist/gem-web-sdk.conformance.js +2 -2
- package/dist/gem-web-sdk.esm.js +2 -2
- package/dist/gem-web-sdk.function.js +1 -1
- package/dist/gem-web-sdk.game.js +3 -3
- package/dist/gem-web-sdk.min.js +3 -3
- package/dist/gem-web-sdk.sdk.js +3 -3
- package/dist/gem-web-sdk.server.js +2 -2
- package/dist/index.d.ts +3 -1
- package/dist/sdk.d.ts +3 -1
- package/docs/analytics.md +40 -0
- package/docs/api/api-reference-function.md +3 -2
- package/docs/api/api-reference-game.md +57 -2
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +48 -4
- package/docs/arcade-and-store.md +4 -2
- package/docs/changelog.md +18 -0
- package/docs/getting-started.md +1 -1
- package/docs/manifest.json +16 -16
- package/docs/player-sign-in.md +51 -3
- package/docs/rewarded-ads.md +31 -0
- package/docs/server-bundles.md +2 -2
- package/docs/what-a-game-must-do.md +7 -4
- package/package.json +1 -1
- package/schema/bridge.v1.json +41 -0
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,24 @@ Its entries are grouped under up to five headings:
|
|
|
16
16
|
- **Rebuild**: a type changed. Recompile against the new version; code that compiles today keeps compiling unless the entry says otherwise.
|
|
17
17
|
- **New capability**: something a game can now do. Nothing changes unless you use it.
|
|
18
18
|
|
|
19
|
+
## 23.3.0
|
|
20
|
+
|
|
21
|
+
*Written from the API facts alone; no summary was generated for this release.*
|
|
22
|
+
|
|
23
|
+
Upgrading from 23.2.0. Impact: required.
|
|
24
|
+
|
|
25
|
+
### Must change
|
|
26
|
+
|
|
27
|
+
- FrameCallbacks.onPlayer changed its signature.
|
|
28
|
+
- FrameOptions.onPlayer changed its signature.
|
|
29
|
+
|
|
30
|
+
### New capability
|
|
31
|
+
|
|
32
|
+
- AccountApi.onSignInAvailableChange was added.
|
|
33
|
+
- AccountApi.signInAvailable was added.
|
|
34
|
+
- GemPlayer.signInAvailable was added.
|
|
35
|
+
- SendPlayerInput.signInAvailable was added.
|
|
36
|
+
|
|
19
37
|
## 23.2.0
|
|
20
38
|
|
|
21
39
|
*Written from the API facts alone; no summary was generated for this release.*
|
package/dist/game.d.ts
CHANGED
|
@@ -3155,6 +3155,8 @@ interface SignInOutcome {
|
|
|
3155
3155
|
readonly outcome: SignInOutcomeKind;
|
|
3156
3156
|
}
|
|
3157
3157
|
interface AccountApi {
|
|
3158
|
+
readonly signInAvailable: boolean;
|
|
3159
|
+
onSignInAvailableChange(listener: (available: boolean) => void): () => void;
|
|
3158
3160
|
requestSignIn(): Promise<SignInOutcome>;
|
|
3159
3161
|
}
|
|
3160
3162
|
interface PlayerBoostMultiplier {
|
|
@@ -3212,7 +3214,7 @@ interface FrameCallbacks {
|
|
|
3212
3214
|
onTokenDenied?(msg: GemTokenDenied): void;
|
|
3213
3215
|
onLocalServer?(msg: GemLocalServer): void;
|
|
3214
3216
|
onLocalServerDenied?(msg: GemLocalServerDenied): void;
|
|
3215
|
-
onPlayer?(player: FramePlayer): void;
|
|
3217
|
+
onPlayer?(player: FramePlayer, signInAvailable?: boolean): void;
|
|
3216
3218
|
onRoomEvent?(msg: GemRoomEvent): void;
|
|
3217
3219
|
onSeatedEvent?(msg: GemSeatedEvent): void;
|
|
3218
3220
|
onAutoStartFailedEvent?(msg: GemAutoStartFailedEvent): void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var GemWebSdkBridgeBundle=(function(){'use strict';var j="GemWebSdkHandshake";function ie(){return typeof document>"u"?void 0:document.readyState}var B=()=>Date.now();function N(n={}){let e=n.win??window,t=e,r=t[j];if(r!==void 0)return r;let o=n.readyState??ie,s=n.now??B,m=[],i=[],u=y=>{let c=y.data;!c||c.type!=="gem.handshake"||(m.length>=4&&(m.shift(),i.shift(),p.dropped+=1),m.push(y),i.push(s()));};e.addEventListener("message",u);let p={events:m,times:i,dropped:0,late:o()==="complete",uninstall(){e.removeEventListener("message",u);}};return t[j]=p,p}function W(n,e,t={}){let r=n[j];if(r===void 0)return null;let o=t.ttlMs??9500,s=t.now??B,m=r.events.splice(0),i=r.times?.splice(0),u=0,p=0,y=false,c=s()-o;for(let h=m.length-1;h>=0;h--){let R=i?.[h];if(R!==void 0&&R<c){p+=1;continue}if(u+=1,e(m[h])===true){y=true;break}}return r.uninstall(),{capture:r,delivered:u,stale:p,accepted:y}}var l="gem-web-bridge",S={min:1,max:1},le=65536,z=8,x=5e3,V=1024;var w=Object.create(null),P="__malformed";var F=Object.create(null),de=Object.freeze([["gem.asyncOpponents.","asyncOpponents"],["gem.textScale.","textScale"],["gem.vibration.","vibration"],["gem.viewport.","reservedAreas"],["gem.moments.","moments"],["gem.prefs.","audioChannels"],["gem.share.","shareRemap"]]);function C(n){let e=F[n];if(e!==void 0)return e;for(let[t,r]of de)if(n.startsWith(t))return r}function me(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 ue(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 ce(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function ge(n){return /^[a-z_]+$/.test(n)}function pe(n){return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(n)||/^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/.test(n)&&!n.includes("--")}function D(n,e,t){if(e>z)return `nesting deeper than ${z}`;if(++t.nodes>x)return `more than ${x} values`;if(t.bytes>t.cap)return `over the ${t.cap} 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>V)return `an array of ${n.length} entries, over the ${V} limit`;t.bytes+=2;for(let i of n){let u=D(i,e+1,t);if(u)return u}return null}let s=Object.getPrototypeOf(n);if(s!==Object.prototype&&s!==null)return "a value that is not a plain object";t.bytes+=2;let m=n;for(let i in m){if(!Object.prototype.hasOwnProperty.call(m,i))continue;if(++t.nodes>x)return `more than ${x} values`;if(t.bytes+=i.length*3+4,t.bytes>t.cap)return `over the ${t.cap} byte limit`;let u=D(m[i],e+1,t);if(u)return u}return null}function ye(n,e=le){let t={nodes:0,bytes:0,seen:new Set,cap:e},r=D(n,0,t);return r?`message contains ${r}`:t.bytes>e?`message is over the ${e} byte limit`:null}var fe={origin:[me,"not a well-formed origin"],url:[ue,"not a safe absolute http(s) URL"],bcp47:[ce,"not a well-formed BCP 47 tag"],code:[ge,"not a code of lower-case letters and underscores"],gameRef:[pe,"not a game id or web address"]};function K(n,e,t){for(let r of e){let o=t===""?r[0]:`${t}.${r[0]}`,s=n[r[0]];if(s==null){if(r[1]<"a")continue;return `${o}: required`}let m=M(s,r,o);if(m)return m}return null}function M(n,e,t){let r=e[1].toLowerCase();switch(r){case "u":return typeof n=="boolean"?null:M(n,typeof n=="string"?[e[0],"s",e[2]]:[e[0],"n",e[3],e[4]],t);case "s":{if(typeof n!="string")return `${t}: expected string`;if(n.length>e[2])return `${t}: exceeds ${e[2]} characters`;if(e[3]){let[o,s]=fe[e[3]];if(!o(n))return `${t}: ${s}`}return null}case "n":case "i":return typeof n!="number"||!(r=="i"?Number.isInteger:Number.isFinite)(n)?`${t}: expected ${r=="i"?"integer":"number"}`:n<e[2]||n>e[3]?`${t}: out of range ${e[2]}..${e[3]}`:null;case "b":return typeof n=="boolean"?null:`${t}: expected boolean`;case "e":{let o=e[2];return o.includes(n)?null:`${t}: not one of ${o.join("|")}`}case "o":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:K(n,e[2],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[2])return `${t}: exceeds ${e[2]} items`;let o=e[3],s=`${t}[]`;for(let m of n){if(m==null){if(o[1]<"a")continue;return `${s}: required`}let i=M(m,o,s);if(i)return i}return null}default:return `${t}: unknown kind ${String(r)}`}}var Y=Object.create(null);function a(n,e,t,r,o){return w[n]=t,r&&(F[n]=r),Y[n]=s=>{let m=ye(s,o);if(m)return m;if(typeof s!="object"||s===null||Array.isArray(s))return "message: expected object";let i=s;return i.gem!==l?"gem: wrong protocol marker":i.type!==n?`type: expected ${n}`:K(i,e,"")}}var G=["","s",64],d=["requestId","s",64],b=["matchId","s",64],f=["reason","S",64,"code"],v=["outcome","e",["ok","declined","unavailable"]];a("gem.handshake",[["versions","o",[["min","i",1,1e3],["max","i",1,1e3]]],["capabilities","A",64,G],["embedder","s",2048,"origin"],["unbidden","B"]],30);a("gem.handshake.accept",[["v","i",1,1e3],["capabilities","A",64,G]],5);a("gem.token",[["token","s",4096],["requestId","S",64],["generation","i",0,2147483647],["apiBaseUrl","S",512,"url"],["playerId","s",64],["gameId","s",64],["channel","e",["dev","test","release"]],["gameVersion","S",64],["expiresAt","i",0,4102444800],["chainEndsAt","i",0,4102444800],["allowDevTools","B"]],30);a("gem.token.denied",[d,["retryable","b"],["retryAfterMs","I",0,36e5],["reason","e",["chain_exhausted","unavailable"]],["correlationId","s",64]],30);a("gem.player",[["untrusted","o",[["displayName","s",64],["displayTag","S",80],["displayHandle","s",80]]],["playerId","S",64],["discriminator","S",8],["avatarIconUrl","S",2048,"url"],["avatarIconId","S",64],["avatar3dId","S",64],["avatar3dModelUrl","S",2048,"url"],["avatar3dIconUrl","S",2048,"url"],["avatars3d","A",8,["","o",[["family","s",32],["id","s",64],["modelUrl","s",256,"url"],["iconUrl","s",256,"url"]]]],["badges","A",2,["","o",[["itemId","s",64],["iconUrl","s",2048,"url"]]]],["displayTag","s",8],["avatarUrl","S",2048,"url"],["boost","O",[["multipliers","a",8,["","o",[["currencyId","s",64],["currencySlug","s",32],["multiplierBp","i",1e4,1e6]]]],["expiresInDays","I",1,7]]]],12);a("gem.pause",[["paused","b"]],120);a("gem.prefs",[["reducedMotion","b"],["muted","b"],["showFrameStats","B"],["music","B"],["sounds","B"],["locale","s",35,"bcp47"],["recommended","O",[["volume","i",0,100],["batterySaver","b"],["keyboardLayout","e",["wasd","arrows"]],["gamepadConfirm","e",["south","east"]],["vibration","b"],["lookSensitivity","I",20,400],["gamepadLookSensitivity","I",20,400],["invertLookY","B"],["touchMovement","S",16,"code"],["graphicsQuality","S",16,"code"],["graphicsQualityAuto","B"],["colorHelp","B"],["textScale","I",100,200]]]],60);a("gem.cohorts",[["cohorts","a",8,["","o",[["experimentId","s",36],["variantKey","s",32]]]]],12,"cohorts");a("gem.earnAllowanceChanged",[],30,"earnAllowance");a("gem.inventoryChanged",[],30,"inventoryChanged");a("gem.viewport",[["insets","o",[["top","i",0,4096],["right","i",0,4096],["bottom","i",0,4096],["left","i",0,4096]]],["reserved","A",4,["","o",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384],["control","O",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384]]]]]]],60,"viewport");a("gem.deviceSettings",[["settings","J"]],12,"deviceSettings");a("gem.willTerminate",[["reason","e",["grant_expiring","session_ended","navigating","kill_switch"]],["graceMs","i",0,6e4]],10);a("gem.roomEvent",[["event","e",["updated","match_started","match_ready","match_failed","version_stale"]],["roomId","s",64],["matchId","S",64],["version","I",0,2147483647],["reason","S",64],["platform","E",["universal","mobile"]]],120,"rooms");a("gem.socketState",[["connected","b"],["reason","E",["connecting","dropped","watchdog","terminal"]]],12,"socketState");a("gem.seatedEvent",[["roomId","s",64]],60,"partySeating");a("gem.autoStartFailedEvent",[["roomId","s",64],["code","s",64]],30,"autoStartFailure");a("gem.ticketEvent",[["event","e",["queued","matched","expired","cancelled","failed"]],["ticketId","s",64],["partySize","I",1,64],["queuedAt","I",0,4102444800],["expiresAt","I",0,4102444800],["reason","S",64],["roomId","S",64]],60,"ticketEvents");a("gem.signalEvent",[["event","e",["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]],b,["data","j"]],1800,"p2p");a("gem.relayDraining",[b,["clusterTargetId","s",64],["relayIps","a",16,G],["drainingSince","s",40],["deadline","s",40]],60,"p2pRelayDrain");a("gem.dedicatedEvent",[["event","e",["answer","error","matchEnded"]],b,["sdp","S",10240],["sessionId","S",64],["code","S",64],["message","S",256],["reason","S",64]],120,"dedicated");a("gem.partyResult",[d,["partyId","S",64]],30,"parties");a("gem.clusterTarget",[["clusterTargetId","s",64],["clusterTargetIds","A",3,G]],12,"clusterTarget");a("gem.graphicsRoutes",[["entries","a",32,["","o",[["gpu","s",32],["route","S",32],["host","S",32]]]]],12,"graphicsRoutes");a("gem.devtools",[["action","e",["open","close","toggle"]]],30,"devtools");a("gem.screenshot",[["maxWidth","i",1,7680],["maxHeight","i",1,4320]],6,"screenshot");a("gem.screenshot.denied",[["reason","e",["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]],["retryable","b"]],12,"screenshot");a("gem.requestContext",[],12,"feedbackContext");a("gem.gameContext",[["context","j"]],12,"feedbackContext");a("gem.signal",[["signal","e",["join","offer","answer","ice","migrationAck","hostUnreachable"]],b,["data","j"]],1200,"p2p");a("gem.dedicatedOffer",[b,["sdp","s",10240],["intent","e",["initial","ice_restart","full_reconnect"]]],60,"dedicated");a("gem.partyRequest",[d],12,"parties");a("gem.ready",[],5);a("gem.engaged",[],5,"engagement");a("gem.progress",[["loaded","i",0,1099511627776],["total","i",0,1099511627776]],600);a("gem.requestToken",[d,["reason","e",["initial","expiring","rejected"]]],12);a("gem.requestLocalServer",[d,["gameRoomId","s",64]],6,"localHost");a("gem.localServer",[d,["serverId","S",128]],30,"localHost");a("gem.localServer.denied",[d,["retryable","b"],["reason","e",["refused","unavailable"]]],30,"localHost");a("gem.exit",[["reason","S",64]],5);a("gem.openExternal",[["url","s",2048,"url"]],6);a("gem.requestFullscreen",[["enabled","b"]],30);a("gem.audioState",[["muted","b"]],120,"audioState");a("gem.rewardCue",[["currencySlug","s",32],["cueId","S",64],["expected","I",1,1e9],["origin","O",[["x","i",0,16384],["y","i",0,16384]]]],60,"rewardCue");a("gem.rewardPresentation",[["mode","e",["arcade","game"]]],12,"rewardPresentation");a("gem.walletDisplay",[["visible","b"],["currencies","A",8,G],["score","B"]],60,"walletDisplay");a("gem.controlsDeclare",[["uses","o",[["lookSensitivity","S",16,"code"],["gamepadLookSensitivity","S",16,"code"],["invertLookY","S",16,"code"],["touchMovement","S",16,"code"]]]],60,"controls");a("gem.menu",[["settings","b"],["items","A",4,["","o",[["id","s",32],["label","s",40]]]]],60,"gameMenu");a("gem.menuSelect",[["entry","e",["settings","item"]],["id","S",32]],60,"gameMenu");a("gem.gemCorner",[["corner","e",["top-left","top-right","bottom-left","bottom-right"]]],12,"gemCorner");a("gem.menuStyle",[["ground","S",7],["accent","S",7]],12,"menuStyle");a("gem.settingsDeclare",[["settings","a",8,["","o",[["id","s",40],["label","s",40],["kind","e",["toggle","slider","choice"]],["value","u",40,-1e6,1e6],["quick","B"],["icon","S",16,"code"],["min","N",-1e6,1e6],["max","N",-1e6,1e6],["step","N",0,1e6],["options","A",4,["","o",[["id","s",40],["label","s",40]]]]]]]],120,"gameSettings");a("gem.settingChange",[["id","s",40],["value","u",40,-1e6,1e6]],120,"gameSettings");a("gem.requestShare",[["requestId","S",64],["params","a",16,["","o",[["key","s",64],["value","s",512]]]]],6,"share");a("gem.shareResult",[d,["outcome","e",["accepted","refused"]],f,["key","S",64]],30,"shareResult");a("gem.requestAvatarPicker",[["tab","E",["2d","3d"]]],6,"avatarPicker");a("gem.vibrate",[["pattern","a",99,["","i",0,1e4]]],600,"vibration");a("gem.frameStats",[["fps","i",0,1e3],["frameTimeP95Ms","i",0,1e5],["counts","E",["pageFrames","gameDraws"]]],120,"frameStats");a("gem.portraitBorders",[["name","S",40]],60,"portraitBorders");a("gem.error",[["code","e",["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]],["message","S",256]],60);a("gem.requestPurchase",[d,["purchaseKind","e",["item","recipe"]],["targetId","s",64],["currencySlug","s",32],["quantity","I",1,10],["catalogId","S",64],["origin","E",["sheet","direct_refused"]]],12,"purchases");a("gem.requestAvatar3dPurchase",[d,["itemId","s",64],["currencySlug","s",32]],12,"avatar3dPurchases");a("gem.purchaseResult",[d,v,f,["purchaseId","S",64]],30,"purchases");a("gem.purchaseSettled",[["purchaseKind","e",["item","recipe"]],["targetId","s",64],["catalogId","S",64],["quantity","i",1,10],["purchaseId","S",64]],30,"purchaseSettled");a("gem.deviceSettings.put",[d,["settings","j"]],30,"deviceSettings");a("gem.deviceSettings.result",[d,["outcome","e",["stored","too_large","unavailable"]]],30,"deviceSettings");a("gem.requestAd",[d,["placement","s",32],["format","e",["interstitial","rewarded"]]],6,"ads");a("gem.adResult",[d,["outcome","e",["shown","no_ad","unavailable"]]],12,"ads");a("gem.signalMoment",[d,["kind","e",["level_end","run_end","match_end","menu_return","other_break"]],["placement","S",32],["wall","B"]],6,"moments");a("gem.momentResult",[d,["shown","b"]],12,"moments");a("gem.requestSignIn",[d],6,"signIn");a("gem.signInResult",[d,["outcome","e",["signed_in","declined","unavailable"]]],12,"signIn");a("gem.requestFriendChallenge",[d,["playerId","s",64],["template","s",64],["params","J"]],12,"friendChallenges");a("gem.friendChallengeResult",[d,["outcome","e",["accepted","cancelled","refused","unavailable","rate_limited","invalid"]],["code","S",64],["param","S",64],["channel","S",16],["configVersion","I",0,9007199254740991],["retryAfterMs","I",0,864e5],["detail","S",300]],30,"friendChallenges");a("gem.requestPlayInvite",[d,["params","A",16,["","o",[["key","s",64],["value","s",512]]]]],6,"playInvites");a("gem.playInviteResult",[d,["shown","b"]],12,"playInvites");a("gem.inviteParams",[["params","A",16,["","o",[["key","s",64],["value","s",512]]]]],30,"playInvites");a("gem.requestAppLinks",[d],12,"appLinks");a("gem.appLinksResult",[d,v,f,["arcade","O",[["store","e",["app_store","google_play"]]]],["game","O",[["store","e",["app_store","google_play"]]]]],30,"appLinks");a("gem.requestOpenApp",[d,["target","e",["arcade","game"]]],6,"appLinks");a("gem.openAppResult",[d,v,f],30,"appLinks");a("gem.requestOpenGame",[d,["ref","s",40,"gameRef"]],6,"openGame");a("gem.openGameResult",[d,v,f],30,"openGame");a("gem.requestSimilarGames",[d,["limit","I",1,24]],12,"openGame");a("gem.similarGamesResult",[d,v,f,["games","a",24,["","o",[["gameId","s",36,"gameRef"],["slug","S",40,"gameRef"],["iconUrl","s",1024,"url"],["capsuleLandscapeUrl","s",1024,"url"],["capsulePortraitUrl","s",1024,"url"],["previewVideoUrl","S",1024,"url"],["previewPosterUrl","S",1024,"url"],["untrusted","o",[["name","s",64],["tagline","s",64],["shortDescription","s",320],["tags","a",10,["","s",32]]]]]]]],30,"openGame",524288);a("gem.requestStoreOffers",[d],12,"store");a("gem.storeOffersResult",[d,v,f,["offers","a",32,["","o",[["skuId","s",64],["kind","e",["gem_pack","boost","pass","bundle"]],["name","s",80],["description","s",400],["imageUrl","S",1024,"url"],["priceDisplay","s",32],["grant","O",[["currency","s",32],["amount","i",1,1e9]]]]]]],30,"store",262144);a("gem.requestStorePurchase",[d,["skuId","s",64]],12,"store");a("gem.storePurchaseResult",[d,v,f],30,"store");a("gem.storePurchaseSettled",[["skuId","s",64]],30,"store");a("gem.requestStoreOfferSheet",[d,["skuId","s",64]],12,"storeOfferSheet");a("gem.storeOfferSheetResult",[d,v,f],30,"storeOfferSheet");var I=Object.freeze(Y);w.__malformed=60;Object.freeze(w);Object.freeze(F);var he=/^[a-z0-9][a-z0-9_-]{0,39}$/;function ve(n){return typeof n=="string"&&he.test(n)}function J(n){if(n===null||ve(n))return n;let e=typeof n=="string"?JSON.stringify(n.length>48?`${n.slice(0,48)}\u2026`:n):`a value of type ${typeof n}`;console.warn(`[gem] showPortraitBorders: ${e} is not a border name, so nothing was sent. A name is 1 to 40 of a-z, 0-9, _ and -, starting with a letter or digit, exactly as your store page declares it under media.portrait_borders. Pass null for no art.`);}function Q(n){return typeof n=="string"&&/^[\w-]{1,64}$/.test(n)}var $={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)},O=class{constructor(e=$){this.clock=e;}clock;tokens=new Map;lastRefill=new Map;allow(e){let t=w[e];if(t===void 0)return false;let r=this.clock.now(),o=this.lastRefill.get(e)??r,s=this.tokens.get(e)??t,m=Math.max(0,r-o),i=Math.min(t,s+m*t/6e4);return i<1?(this.tokens.set(e,i),this.lastRefill.set(e,r),false):(this.tokens.set(e,i-1),this.lastRefill.set(e,r),true)}};function q(n,e){return n.toLowerCase()===e.toLowerCase()}function T(n){let e=n.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}function X(n,e){if(typeof e!="string"||e==="")return false;let t,r;try{t=new URL(n),r=new URL(e);}catch{return false}return t.protocol!=="http:"&&t.protocol!=="https:"||r.protocol!=="http:"&&r.protocol!=="https:"||t.username!==""||t.password!==""||t.pathname!=="/"||t.search!==""||t.hash!==""||t.port===""?false:T(t.hostname)&&T(r.hostname)}function Z(n,e){if(n.min>n.max||e.min>e.max)return null;let t=Math.min(n.max,e.max),r=Math.max(n.min,e.min);return t>=r?t:null}var ne="[gem: use gem.text.toPlain()]",ee=new Set,te;function Re(n){try{if(ee.has(n))return;let e=globalThis.location;if(te??=!!e?.port&&T(e.hostname??""),!te)return;ee.add(n),console.warn(`[gem] ${n} is PlayerText, turned into a string: players see ${ne}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
|
|
2
|
-
${new Error().stack}`);}catch{}}var U=class{#e;#t;constructor(e,t="player text"){this.#e=e,this.#t=t,Object.freeze(this);}toString(){return Re(this.#t),ne}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function H(n,e){return new U(n,e)}function re(n){return Math.min(16384,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}function Se(n,e){if(n!==true)return {visible:false};let t=[],r=false;for(let o of Array.isArray(e)?e:[])o==="score"?r=true:typeof o=="string"&&o.length>0&&o.length<=64&&!t.includes(o)&&t.push(o);return !r&&t.length===0?{visible:true}:{visible:true,currencies:t.slice(0,8),score:r}}function we(n){let e=[];for(let t of Array.isArray(n)?n:[]){if(e.length===4)break;if(typeof t!="object"||t===null)continue;let{id:r,label:o}=t;typeof r!="string"||r.length===0||r.length>32||typeof o!="string"||o.trim().length===0||e.some(s=>s.id===r)||e.push({id:r,label:o.trim().slice(0,40)});}return e.length===0?{settings:false}:{settings:false,items:e}}function ae(n,e){return Math.min(e,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}function Ge(n){let e=n.untrusted,t=H(e.displayName,"gem.player.displayName"),r=e.displayTag||e.displayHandle,o=r?H(r,"gem.player.displayTag"):void 0,s=n.discriminator||n.displayTag,m=s&&/^[0-9]{1,8}$/.test(s)?s:void 0,i=n.avatarIconUrl||n.avatarUrl,u=/^[\da-f]{8}(-[\da-f]{4}){3}-[\da-f]{12}$/i,p=n.avatarIconId,y=n.avatar3dId,c={displayName:t,displayHandle:o??t,badges:(n.badges??[]).map(g=>({itemId:g.itemId,iconUrl:g.iconUrl}))};n.playerId&&(c.playerId=n.playerId),m&&(c.discriminator=m),o&&(c.displayTag=o),i&&(c.avatarIconUrl=c.avatarUrl=i),p&&u.test(p)&&(c.avatarIconId=p),y&&u.test(y)&&(c.avatar3dId=y),n.avatar3dModelUrl&&(c.avatar3dModelUrl=n.avatar3dModelUrl),n.avatar3dIconUrl&&(c.avatar3dIconUrl=n.avatar3dIconUrl),n.avatars3d&&(c.avatars3d=n.avatars3d.filter(g=>u.test(g.id)&&/^[a-z][a-z0-9_]*$/.test(g.family)).filter((g,E,L)=>L.findIndex(_=>_.family==g.family)==E).map(({family:g,id:E,modelUrl:L,iconUrl:_})=>({family:g,id:E,modelUrl:L,iconUrl:_})));let h=n.boost,R=(h?.multipliers??[]).map(g=>({currencyId:g.currencyId,currencySlug:g.currencySlug,multiplier:g.multiplierBp/1e4})),A=R.some(g=>g.multiplier>1);return c.boost=A&&h?.expiresInDays?{active:A,multipliers:R,expiresInDays:h.expiresInDays}:{active:A,multipliers:R},c}var be=1e4,Oe=["appLinks","openGame","store","storeOfferSheet"],ke=["token","pause","menuSelect","settingChange","prefs","cohorts","viewport","willTerminate","localServer","roomEvent","seatedEvent","autoStartFailedEvent","ticketEvent","socketState","signalEvent","relayDraining","dedicatedEvent","clusterTarget","graphicsRoutes","partyResult","purchaseResult","purchaseSettled","inventoryChanged","shareResult","deviceSettings","adResult","momentResult","signInResult","friendChallengeResult","playInviteResult"],xe=new WeakMap;var k=class{constructor(e){this.options=e;if(e.expectedSource===void 0||e.expectedSource===null)throw new Error("GemFrame: expectedSource is required and must not be null \u2014 pass window.parent. The handshake transfers the MessagePort, and origin alone does not say WHICH document on that origin sent it.");this.expectedSource=e.expectedSource,this.clock=e.clock??$,this.inbound=new O(this.clock),this.outbound=new O(this.clock);}options;state="waiting";port=null;version=null;peerCapabilities=[];unbidden=false;engagedSent=false;readyPending=false;readySent=false;settleWaiters=[];clock;inbound;outbound;expectedSource;get currentState(){return this.state}get parentCapabilities(){return this.peerCapabilities}parentSupports(e){return this.peerCapabilities.includes(e)}get protocolVersion(){return this.version}get unbiddenLaunch(){return this.unbidden}handleWindowMessage(e){if(e.source!==this.expectedSource)return this.refuse(e,"handshake did not come from the expected embedder window"),false;if(!(this.options.allowedEmbedders.some(i=>q(i,e.origin))||X(e.origin,this.options.selfOrigin)||(xe.get(this)??[]).some(i=>q(i,e.origin))))return this.refuse(e,`embedder '${e.origin}' is not in allowedEmbedders`),this.state==="waiting"&&this.transition("refused"),false;if(this.state==="connected")return this.fail("handshake_duplicate","this document already has a port"),false;if(this.state!=="waiting")return false;let r=I["gem.handshake"]?.(e.data);if(r)return this.refuse(e,`malformed handshake: ${r}`),false;let o=e.data;if(!q(o.embedder,e.origin))return this.refuse(e,`handshake claims embedder '${o.embedder}' but arrived from '${e.origin}'`),false;let s=e.ports?.[0];if(!s)return this.refuse(e,"handshake transferred no MessagePort"),false;let m=Z(S,o.versions);return m===null?(s.onmessage=null,s.postMessage({gem:l,type:"gem.error",code:"version_mismatch",message:`frame supports v${S.min}..v${S.max}`}),s.close(),this.transition("refused"),this.options.onError?.("version_mismatch"),false):(this.port=s,this.version=m,s.onmessage=i=>this.receive(i.data,i.ports??[]),s.start?.(),this.peerCapabilities=o.capabilities??[],this.unbidden=o.unbidden===true,s.postMessage({gem:l,type:"gem.handshake.accept",v:m,...this.options.capabilities===void 0?{}:{capabilities:[...this.options.capabilities]}}),this.transition("connected"),this.readyPending&&(this.readyPending=false,this.ready()),true)}ready(){if(this.state!=="connected"||!this.port){this.readyPending=true;return}if(this.readySent){this.options.onDropped?.("internal","gem.ready was already sent; duplicate suppressed");return}this.readySent=true,this.send({gem:l,type:"gem.ready"});}settled(e=be){return this.state!=="waiting"?Promise.resolve(this.state):new Promise(t=>{let r=s=>{this.clock.clearTimeout(o),t(s);},o=this.clock.setTimeout(()=>{let s=this.settleWaiters.indexOf(r);s>=0&&this.settleWaiters.splice(s,1),t(this.state);},e);this.settleWaiters.push(r);})}progress(e,t){this.send({gem:l,type:"gem.progress",loaded:e,total:t});}requestToken(e,t){this.send({gem:l,type:"gem.requestToken",requestId:e,reason:t});}requestLocalServer(e,t){return this.parentSupports("localHost")?(this.send({gem:l,type:"gem.requestLocalServer",requestId:e,gameRoomId:t}),true):false}exit(e){this.send(e===void 0?{gem:l,type:"gem.exit"}:{gem:l,type:"gem.exit",reason:e});}openExternal(e){this.send({gem:l,type:"gem.openExternal",url:e});}requestFullscreen(e){this.send({gem:l,type:"gem.requestFullscreen",enabled:e});}reportMuted(e){return this.gated("audioState")?(this.send({gem:l,type:"gem.audioState",muted:e}),true):false}reportEngaged(){return this.engagedSent||!this.gated("engagement")||!this.send({gem:l,type:"gem.engaged"})?false:(this.engagedSent=true,true)}cueReward(e){if(!this.gated("rewardCue"))return false;let t={gem:l,type:"gem.rewardCue",currencySlug:String(e.currencySlug).slice(0,32)};return Q(e.cueId)&&(t.cueId=e.cueId),e.expected!==void 0&&Number.isFinite(e.expected)&&e.expected>=1&&(t.expected=Math.min(1e9,Math.round(e.expected))),e.origin&&(t.origin={x:re(e.origin.x),y:re(e.origin.y)}),this.send(t),true}showPortraitBorders(e){let t=J(e);return t===void 0||!this.gated("portraitBorders")?false:this.send(t===null?{gem:l,type:"gem.portraitBorders"}:{gem:l,type:"gem.portraitBorders",name:t})}setWalletVisible(e,t){return this.gated("walletDisplay")?this.send({gem:l,type:"gem.walletDisplay",...Se(e,t?.only)}):false}setMenu(e){return this.gated("gameMenu")?this.send({gem:l,type:"gem.menu",...we(e)}):false}declareSettings(e){return this.gated("gameSettings")?this.send({gem:l,type:"gem.settingsDeclare",settings:e}):false}setGemCorner(e){return this.gated("gemCorner")?this.send({gem:l,type:"gem.gemCorner",corner:e}):false}setRewardPresentation(e){return this.gated("rewardPresentation")?this.send({gem:l,type:"gem.rewardPresentation",mode:e}):false}setMenuStyle(e){return this.gated("menuStyle")?this.send(e===null?{gem:l,type:"gem.menuStyle"}:{gem:l,type:"gem.menuStyle",ground:e.ground,accent:e.accent}):false}requestShare(e,t){return this.gated("share")?this.send({gem:l,type:"gem.requestShare",...t===void 0?{}:{requestId:t},params:e.map(({key:r,value:o})=>({key:r,value:o}))}):false}requestAvatarPicker(e){return this.gated("avatarPicker")?this.send({gem:l,type:"gem.requestAvatarPicker",...e==="2d"||e==="3d"?{tab:e}:{}}):false}requestVibrate(e){return this.gated("vibration")?this.send({gem:l,type:"gem.vibrate",pattern:[...e]}):false}reportFrameStats(e){return this.gated("frameStats")?(this.send({gem:l,type:"gem.frameStats",fps:ae(e.fps,1e3),frameTimeP95Ms:ae(e.frameTimeP95Ms,1e5),counts:e.counts==="gameDraws"?"gameDraws":"pageFrames"}),true):false}sendGameContext(e){return this.state!=="connected"?false:(this.send({gem:l,type:"gem.gameContext",context:e}),true)}signal(e,t,r){this.send({gem:l,type:"gem.signal",signal:e,matchId:t,data:r});}dedicatedOffer(e,t,r){this.send({gem:l,type:"gem.dedicatedOffer",matchId:e,sdp:t,intent:r});}requestParty(e){return this.send({gem:l,type:"gem.partyRequest",requestId:e})}requestPurchase(e,t,r,o,s,m,i){return this.send({gem:l,type:"gem.requestPurchase",requestId:e,purchaseKind:t,targetId:r,currencySlug:o,...s===void 0?{}:{quantity:s},...m===void 0?{}:{catalogId:m},...i===void 0?{}:{origin:i}})}requestAvatar3dPurchase(e,t,r){return this.parentSupports("avatar3dPurchases")?this.send({gem:l,type:"gem.requestAvatar3dPurchase",requestId:e,itemId:t,currencySlug:r}):false}putDeviceSettings(e,t){return this.send({gem:l,type:"gem.deviceSettings.put",requestId:e,settings:t})}requestAd(e,t,r){return this.send({gem:l,type:"gem.requestAd",requestId:e,placement:t,format:r})}signalMoment(e,t,r,o){return this.send({gem:l,type:"gem.signalMoment",requestId:e,kind:t,...r===void 0?{}:{placement:r},...o===true?{wall:true}:{}})}readyCalled(){return this.readySent||this.readyPending}requestSignIn(e){return this.send({gem:l,type:"gem.requestSignIn",requestId:e})}requestFriendChallenge(e,t,r,o){return this.send({gem:l,type:"gem.requestFriendChallenge",requestId:e,playerId:t,template:r,...o===void 0?{}:{params:o}})}requestArcade(e){return this.gated(C(e.type))&&this.send({gem:l,...e})}close(){this.port&&(this.port.onmessage=null,this.port.close(),this.port=null),this.state!=="refused"&&this.transition("closed");}transition(e){if(this.state!==e){this.state=e;for(let t of this.settleWaiters.splice(0))t(e);this.options.onStateChange?.(e);}}refuseMalformed(e,t){if(!this.inbound.allow(P)){this.options.onDropped?.(e,t);return}this.fail(e,t);}dropUnknownType(e){this.inbound.allow(P)&&this.options.onDropped?.("unsupported",`ignored unknown message type '${e}'`);}refuse(e,t){e.ports?.[0]?.close?.(),this.inbound.allow(P)&&this.options.onRefused?.(t);}fail(e,t){this.options.onError?.(e,t),this.state==="connected"&&this.port&&this.send({gem:l,type:"gem.error",code:e,...t===void 0?{}:{message:t}});}gated(e){return this.state==="connected"&&this.parentSupports(e)}send(e){if(this.state!=="connected"||!this.port)return this.options.onDropped?.("internal",`dropped ${String(e.type)} before connect`),false;let t=e.type;if(!this.outbound.allow(t))return this.options.onError?.("rate_limited",`frame exceeded its own limit for ${t}`),false;let r=I[t]?.(e);return r?(this.options.onError?.("internal",`refusing to send malformed ${t}: ${r}`),false):(this.port.postMessage(this.version===null?e:{...e,v:this.version}),true)}receive(e,t=[]){let r=false;try{r=this.dispatchInbound(e,t);}finally{r||oe(t);}}dispatchInbound(e,t){if(this.state!=="connected")return false;let r=typeof e=="object"&&e!==null?e.type:void 0;if(typeof r!="string")return this.refuseMalformed("invalid_message","message has no type"),false;let o=I[r];if(!o)return this.dropUnknownType(r),false;if(!this.inbound.allow(r))return this.fail("rate_limited",`parent exceeded the limit for ${r}`),false;let s=C(r);if(s!==void 0&&!this.options.capabilities?.includes(s))return this.fail("unsupported_capability",`${r} requires the '${s}' capability, which this frame did not advertise`),false;let m=o(e);if(m)return this.fail("invalid_message",`${r}: ${m}`),false;let i=e;if(i.v!==this.version)return this.fail("invalid_message",`${r}: expected v ${String(this.version)}`),false;switch(r){case "gem.earnAllowanceChanged":this.options.onEarnAllowanceChanged?.();break;case "gem.devtools":this.options.onDevtools?.(i.action);break;case "gem.requestContext":this.options.onRequestContext?.();break;case "gem.screenshot":{let u=t[0];if(!u){this.options.onError?.("invalid_message","gem.screenshot transferred no MessagePort");break}let p={maxWidth:i.maxWidth,maxHeight:i.maxHeight};if(!this.options.onScreenshot){u.close(),this.screenshotDenied("not_wired",false);break}return oe(t.slice(1)),this.options.onScreenshot(p,u,(y,c)=>this.screenshotDenied(y,c)),true}case "gem.token.denied":this.options.onTokenDenied?.(i);break;case "gem.localServer.denied":this.options.onLocalServerDenied?.(i);break;case "gem.player":{this.options.onPlayer?.(Ge(i));break}case "gem.deviceSettings.result":this.options.onDeviceSettingsResult?.(i);break;case "gem.error":this.options.onError?.(i.code,i.message);break;default:if(ke.includes(r.slice(4))){this.options[`on${r[4].toUpperCase()}${r.slice(5)}`]?.(i);break}if(Oe.includes(C(r))){this.options.onArcadeAnswer?.(i);break}this.fail("unsupported",`no frame handler for '${r}'`);}return false}screenshotDenied(e,t){this.send({gem:l,type:"gem.screenshot.denied",reason:e,retryable:t});}};function oe(n){for(let e of n)try{e?.close?.();}catch{}}N();function Pe(n){if((n.expectedSource??window.parent)===window)throw new Error("GemWebSdkBridge.connect: this document is not framed (window.parent === window), so there is no embedder to hand it a port. A game runs inside the Gem Arcade iframe; opening it directly will never complete a handshake.");let e=new k({...n,expectedSource:n.expectedSource??window.parent}),t=r=>{let o=e.handleWindowMessage({data:r.data,origin:r.origin,source:r.source,ports:r.ports});return o&&window.removeEventListener("message",t),o};return window.addEventListener("message",t),W(window,t),e}var se={connect:Pe,GemFrame:k,PROTOCOL:l,SUPPORTED_VERSIONS:S};window.GemWebSdkBridge=se;var Tn=se;return Tn;})();
|
|
1
|
+
var GemWebSdkBridgeBundle=(function(){'use strict';var j="GemWebSdkHandshake";function ie(){return typeof document>"u"?void 0:document.readyState}var B=()=>Date.now();function N(n={}){let e=n.win??window,t=e,r=t[j];if(r!==void 0)return r;let o=n.readyState??ie,s=n.now??B,m=[],i=[],u=y=>{let c=y.data;!c||c.type!=="gem.handshake"||(m.length>=4&&(m.shift(),i.shift(),p.dropped+=1),m.push(y),i.push(s()));};e.addEventListener("message",u);let p={events:m,times:i,dropped:0,late:o()==="complete",uninstall(){e.removeEventListener("message",u);}};return t[j]=p,p}function W(n,e,t={}){let r=n[j];if(r===void 0)return null;let o=t.ttlMs??9500,s=t.now??B,m=r.events.splice(0),i=r.times?.splice(0),u=0,p=0,y=false,c=s()-o;for(let h=m.length-1;h>=0;h--){let R=i?.[h];if(R!==void 0&&R<c){p+=1;continue}if(u+=1,e(m[h])===true){y=true;break}}return r.uninstall(),{capture:r,delivered:u,stale:p,accepted:y}}var l="gem-web-bridge",S={min:1,max:1},le=65536,z=8,x=5e3,V=1024;var w=Object.create(null),P="__malformed";var F=Object.create(null),de=Object.freeze([["gem.asyncOpponents.","asyncOpponents"],["gem.textScale.","textScale"],["gem.vibration.","vibration"],["gem.viewport.","reservedAreas"],["gem.moments.","moments"],["gem.prefs.","audioChannels"],["gem.share.","shareRemap"]]);function C(n){let e=F[n];if(e!==void 0)return e;for(let[t,r]of de)if(n.startsWith(t))return r}function me(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 ue(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 ce(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function ge(n){return /^[a-z_]+$/.test(n)}function pe(n){return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(n)||/^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/.test(n)&&!n.includes("--")}function D(n,e,t){if(e>z)return `nesting deeper than ${z}`;if(++t.nodes>x)return `more than ${x} values`;if(t.bytes>t.cap)return `over the ${t.cap} 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>V)return `an array of ${n.length} entries, over the ${V} limit`;t.bytes+=2;for(let i of n){let u=D(i,e+1,t);if(u)return u}return null}let s=Object.getPrototypeOf(n);if(s!==Object.prototype&&s!==null)return "a value that is not a plain object";t.bytes+=2;let m=n;for(let i in m){if(!Object.prototype.hasOwnProperty.call(m,i))continue;if(++t.nodes>x)return `more than ${x} values`;if(t.bytes+=i.length*3+4,t.bytes>t.cap)return `over the ${t.cap} byte limit`;let u=D(m[i],e+1,t);if(u)return u}return null}function ye(n,e=le){let t={nodes:0,bytes:0,seen:new Set,cap:e},r=D(n,0,t);return r?`message contains ${r}`:t.bytes>e?`message is over the ${e} byte limit`:null}var fe={origin:[me,"not a well-formed origin"],url:[ue,"not a safe absolute http(s) URL"],bcp47:[ce,"not a well-formed BCP 47 tag"],code:[ge,"not a code of lower-case letters and underscores"],gameRef:[pe,"not a game id or web address"]};function K(n,e,t){for(let r of e){let o=t===""?r[0]:`${t}.${r[0]}`,s=n[r[0]];if(s==null){if(r[1]<"a")continue;return `${o}: required`}let m=M(s,r,o);if(m)return m}return null}function M(n,e,t){let r=e[1].toLowerCase();switch(r){case "u":return typeof n=="boolean"?null:M(n,typeof n=="string"?[e[0],"s",e[2]]:[e[0],"n",e[3],e[4]],t);case "s":{if(typeof n!="string")return `${t}: expected string`;if(n.length>e[2])return `${t}: exceeds ${e[2]} characters`;if(e[3]){let[o,s]=fe[e[3]];if(!o(n))return `${t}: ${s}`}return null}case "n":case "i":return typeof n!="number"||!(r=="i"?Number.isInteger:Number.isFinite)(n)?`${t}: expected ${r=="i"?"integer":"number"}`:n<e[2]||n>e[3]?`${t}: out of range ${e[2]}..${e[3]}`:null;case "b":return typeof n=="boolean"?null:`${t}: expected boolean`;case "e":{let o=e[2];return o.includes(n)?null:`${t}: not one of ${o.join("|")}`}case "o":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:K(n,e[2],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[2])return `${t}: exceeds ${e[2]} items`;let o=e[3],s=`${t}[]`;for(let m of n){if(m==null){if(o[1]<"a")continue;return `${s}: required`}let i=M(m,o,s);if(i)return i}return null}default:return `${t}: unknown kind ${String(r)}`}}var Y=Object.create(null);function a(n,e,t,r,o){return w[n]=t,r&&(F[n]=r),Y[n]=s=>{let m=ye(s,o);if(m)return m;if(typeof s!="object"||s===null||Array.isArray(s))return "message: expected object";let i=s;return i.gem!==l?"gem: wrong protocol marker":i.type!==n?`type: expected ${n}`:K(i,e,"")}}var b=["","s",64],d=["requestId","s",64],G=["matchId","s",64],f=["reason","S",64,"code"],v=["outcome","e",["ok","declined","unavailable"]];a("gem.handshake",[["versions","o",[["min","i",1,1e3],["max","i",1,1e3]]],["capabilities","A",64,b],["embedder","s",2048,"origin"],["unbidden","B"]],30);a("gem.handshake.accept",[["v","i",1,1e3],["capabilities","A",64,b]],5);a("gem.token",[["token","s",4096],["requestId","S",64],["generation","i",0,2147483647],["apiBaseUrl","S",512,"url"],["playerId","s",64],["gameId","s",64],["channel","e",["dev","test","release"]],["gameVersion","S",64],["expiresAt","i",0,4102444800],["chainEndsAt","i",0,4102444800],["allowDevTools","B"]],30);a("gem.token.denied",[d,["retryable","b"],["retryAfterMs","I",0,36e5],["reason","e",["chain_exhausted","unavailable"]],["correlationId","s",64]],30);a("gem.player",[["untrusted","o",[["displayName","s",64],["displayTag","S",80],["displayHandle","s",80]]],["playerId","S",64],["discriminator","S",8],["avatarIconUrl","S",2048,"url"],["avatarIconId","S",64],["avatar3dId","S",64],["avatar3dModelUrl","S",2048,"url"],["avatar3dIconUrl","S",2048,"url"],["avatars3d","A",8,["","o",[["family","s",32],["id","s",64],["modelUrl","s",256,"url"],["iconUrl","s",256,"url"]]]],["badges","A",2,["","o",[["itemId","s",64],["iconUrl","s",2048,"url"]]]],["displayTag","s",8],["avatarUrl","S",2048,"url"],["boost","O",[["multipliers","a",8,["","o",[["currencyId","s",64],["currencySlug","s",32],["multiplierBp","i",1e4,1e6]]]],["expiresInDays","I",1,7]]],["signInAvailable","B"]],12);a("gem.pause",[["paused","b"]],120);a("gem.prefs",[["reducedMotion","b"],["muted","b"],["showFrameStats","B"],["music","B"],["sounds","B"],["locale","s",35,"bcp47"],["recommended","O",[["volume","i",0,100],["batterySaver","b"],["keyboardLayout","e",["wasd","arrows"]],["gamepadConfirm","e",["south","east"]],["vibration","b"],["lookSensitivity","I",20,400],["gamepadLookSensitivity","I",20,400],["invertLookY","B"],["touchMovement","S",16,"code"],["graphicsQuality","S",16,"code"],["graphicsQualityAuto","B"],["colorHelp","B"],["textScale","I",100,200]]]],60);a("gem.cohorts",[["cohorts","a",8,["","o",[["experimentId","s",36],["variantKey","s",32]]]]],12,"cohorts");a("gem.earnAllowanceChanged",[],30,"earnAllowance");a("gem.inventoryChanged",[],30,"inventoryChanged");a("gem.viewport",[["insets","o",[["top","i",0,4096],["right","i",0,4096],["bottom","i",0,4096],["left","i",0,4096]]],["reserved","A",4,["","o",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384],["control","O",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384]]]]]]],60,"viewport");a("gem.deviceSettings",[["settings","J"]],12,"deviceSettings");a("gem.willTerminate",[["reason","e",["grant_expiring","session_ended","navigating","kill_switch"]],["graceMs","i",0,6e4]],10);a("gem.roomEvent",[["event","e",["updated","match_started","match_ready","match_failed","version_stale"]],["roomId","s",64],["matchId","S",64],["version","I",0,2147483647],["reason","S",64],["platform","E",["universal","mobile"]]],120,"rooms");a("gem.socketState",[["connected","b"],["reason","E",["connecting","dropped","watchdog","terminal"]]],12,"socketState");a("gem.seatedEvent",[["roomId","s",64]],60,"partySeating");a("gem.autoStartFailedEvent",[["roomId","s",64],["code","s",64]],30,"autoStartFailure");a("gem.ticketEvent",[["event","e",["queued","matched","expired","cancelled","failed"]],["ticketId","s",64],["partySize","I",1,64],["queuedAt","I",0,4102444800],["expiresAt","I",0,4102444800],["reason","S",64],["roomId","S",64]],60,"ticketEvents");a("gem.signalEvent",[["event","e",["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]],G,["data","j"]],1800,"p2p");a("gem.relayDraining",[G,["clusterTargetId","s",64],["relayIps","a",16,b],["drainingSince","s",40],["deadline","s",40]],60,"p2pRelayDrain");a("gem.dedicatedEvent",[["event","e",["answer","error","matchEnded"]],G,["sdp","S",10240],["sessionId","S",64],["code","S",64],["message","S",256],["reason","S",64]],120,"dedicated");a("gem.partyResult",[d,["partyId","S",64]],30,"parties");a("gem.clusterTarget",[["clusterTargetId","s",64],["clusterTargetIds","A",3,b]],12,"clusterTarget");a("gem.graphicsRoutes",[["entries","a",32,["","o",[["gpu","s",32],["route","S",32],["host","S",32]]]]],12,"graphicsRoutes");a("gem.devtools",[["action","e",["open","close","toggle"]]],30,"devtools");a("gem.screenshot",[["maxWidth","i",1,7680],["maxHeight","i",1,4320]],6,"screenshot");a("gem.screenshot.denied",[["reason","e",["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]],["retryable","b"]],12,"screenshot");a("gem.requestContext",[],12,"feedbackContext");a("gem.gameContext",[["context","j"]],12,"feedbackContext");a("gem.signal",[["signal","e",["join","offer","answer","ice","migrationAck","hostUnreachable"]],G,["data","j"]],1200,"p2p");a("gem.dedicatedOffer",[G,["sdp","s",10240],["intent","e",["initial","ice_restart","full_reconnect"]]],60,"dedicated");a("gem.partyRequest",[d],12,"parties");a("gem.ready",[],5);a("gem.engaged",[],5,"engagement");a("gem.progress",[["loaded","i",0,1099511627776],["total","i",0,1099511627776]],600);a("gem.requestToken",[d,["reason","e",["initial","expiring","rejected"]]],12);a("gem.requestLocalServer",[d,["gameRoomId","s",64]],6,"localHost");a("gem.localServer",[d,["serverId","S",128]],30,"localHost");a("gem.localServer.denied",[d,["retryable","b"],["reason","e",["refused","unavailable"]]],30,"localHost");a("gem.exit",[["reason","S",64]],5);a("gem.openExternal",[["url","s",2048,"url"]],6);a("gem.requestFullscreen",[["enabled","b"]],30);a("gem.audioState",[["muted","b"]],120,"audioState");a("gem.rewardCue",[["currencySlug","s",32],["cueId","S",64],["expected","I",1,1e9],["origin","O",[["x","i",0,16384],["y","i",0,16384]]]],60,"rewardCue");a("gem.rewardPresentation",[["mode","e",["arcade","game"]]],12,"rewardPresentation");a("gem.walletDisplay",[["visible","b"],["currencies","A",8,b],["score","B"]],60,"walletDisplay");a("gem.controlsDeclare",[["uses","o",[["lookSensitivity","S",16,"code"],["gamepadLookSensitivity","S",16,"code"],["invertLookY","S",16,"code"],["touchMovement","S",16,"code"]]]],60,"controls");a("gem.menu",[["settings","b"],["items","A",4,["","o",[["id","s",32],["label","s",40]]]]],60,"gameMenu");a("gem.menuSelect",[["entry","e",["settings","item"]],["id","S",32]],60,"gameMenu");a("gem.gemCorner",[["corner","e",["top-left","top-right","bottom-left","bottom-right"]]],12,"gemCorner");a("gem.menuStyle",[["ground","S",7],["accent","S",7]],12,"menuStyle");a("gem.settingsDeclare",[["settings","a",8,["","o",[["id","s",40],["label","s",40],["kind","e",["toggle","slider","choice"]],["value","u",40,-1e6,1e6],["quick","B"],["icon","S",16,"code"],["min","N",-1e6,1e6],["max","N",-1e6,1e6],["step","N",0,1e6],["options","A",4,["","o",[["id","s",40],["label","s",40]]]]]]]],120,"gameSettings");a("gem.settingChange",[["id","s",40],["value","u",40,-1e6,1e6]],120,"gameSettings");a("gem.requestShare",[["requestId","S",64],["params","a",16,["","o",[["key","s",64],["value","s",512]]]]],6,"share");a("gem.shareResult",[d,["outcome","e",["accepted","refused"]],f,["key","S",64]],30,"shareResult");a("gem.requestAvatarPicker",[["tab","E",["2d","3d"]]],6,"avatarPicker");a("gem.vibrate",[["pattern","a",99,["","i",0,1e4]]],600,"vibration");a("gem.frameStats",[["fps","i",0,1e3],["frameTimeP95Ms","i",0,1e5],["counts","E",["pageFrames","gameDraws"]]],120,"frameStats");a("gem.portraitBorders",[["name","S",40]],60,"portraitBorders");a("gem.error",[["code","e",["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]],["message","S",256]],60);a("gem.requestPurchase",[d,["purchaseKind","e",["item","recipe"]],["targetId","s",64],["currencySlug","s",32],["quantity","I",1,10],["catalogId","S",64],["origin","E",["sheet","direct_refused"]]],12,"purchases");a("gem.requestAvatar3dPurchase",[d,["itemId","s",64],["currencySlug","s",32]],12,"avatar3dPurchases");a("gem.purchaseResult",[d,v,f,["purchaseId","S",64]],30,"purchases");a("gem.purchaseSettled",[["purchaseKind","e",["item","recipe"]],["targetId","s",64],["catalogId","S",64],["quantity","i",1,10],["purchaseId","S",64]],30,"purchaseSettled");a("gem.deviceSettings.put",[d,["settings","j"]],30,"deviceSettings");a("gem.deviceSettings.result",[d,["outcome","e",["stored","too_large","unavailable"]]],30,"deviceSettings");a("gem.requestAd",[d,["placement","s",32],["format","e",["interstitial","rewarded"]]],6,"ads");a("gem.adResult",[d,["outcome","e",["shown","no_ad","unavailable"]]],12,"ads");a("gem.signalMoment",[d,["kind","e",["level_end","run_end","match_end","menu_return","other_break"]],["placement","S",32],["wall","B"]],6,"moments");a("gem.momentResult",[d,["shown","b"]],12,"moments");a("gem.requestSignIn",[d],6,"signIn");a("gem.signInResult",[d,["outcome","e",["signed_in","declined","unavailable"]]],12,"signIn");a("gem.requestFriendChallenge",[d,["playerId","s",64],["template","s",64],["params","J"]],12,"friendChallenges");a("gem.friendChallengeResult",[d,["outcome","e",["accepted","cancelled","refused","unavailable","rate_limited","invalid"]],["code","S",64],["param","S",64],["channel","S",16],["configVersion","I",0,9007199254740991],["retryAfterMs","I",0,864e5],["detail","S",300]],30,"friendChallenges");a("gem.requestPlayInvite",[d,["params","A",16,["","o",[["key","s",64],["value","s",512]]]]],6,"playInvites");a("gem.playInviteResult",[d,["shown","b"]],12,"playInvites");a("gem.inviteParams",[["params","A",16,["","o",[["key","s",64],["value","s",512]]]]],30,"playInvites");a("gem.requestAppLinks",[d],12,"appLinks");a("gem.appLinksResult",[d,v,f,["arcade","O",[["store","e",["app_store","google_play"]]]],["game","O",[["store","e",["app_store","google_play"]]]]],30,"appLinks");a("gem.requestOpenApp",[d,["target","e",["arcade","game"]]],6,"appLinks");a("gem.openAppResult",[d,v,f],30,"appLinks");a("gem.requestOpenGame",[d,["ref","s",40,"gameRef"]],6,"openGame");a("gem.openGameResult",[d,v,f],30,"openGame");a("gem.requestSimilarGames",[d,["limit","I",1,24]],12,"openGame");a("gem.similarGamesResult",[d,v,f,["games","a",24,["","o",[["gameId","s",36,"gameRef"],["slug","S",40,"gameRef"],["iconUrl","s",1024,"url"],["capsuleLandscapeUrl","s",1024,"url"],["capsulePortraitUrl","s",1024,"url"],["previewVideoUrl","S",1024,"url"],["previewPosterUrl","S",1024,"url"],["untrusted","o",[["name","s",64],["tagline","s",64],["shortDescription","s",320],["tags","a",10,["","s",32]]]]]]]],30,"openGame",524288);a("gem.requestStoreOffers",[d],12,"store");a("gem.storeOffersResult",[d,v,f,["offers","a",32,["","o",[["skuId","s",64],["kind","e",["gem_pack","boost","pass","bundle"]],["name","s",80],["description","s",400],["imageUrl","S",1024,"url"],["priceDisplay","s",32],["grant","O",[["currency","s",32],["amount","i",1,1e9]]]]]]],30,"store",262144);a("gem.requestStorePurchase",[d,["skuId","s",64]],12,"store");a("gem.storePurchaseResult",[d,v,f],30,"store");a("gem.storePurchaseSettled",[["skuId","s",64]],30,"store");a("gem.requestStoreOfferSheet",[d,["skuId","s",64]],12,"storeOfferSheet");a("gem.storeOfferSheetResult",[d,v,f],30,"storeOfferSheet");var I=Object.freeze(Y);w.__malformed=60;Object.freeze(w);Object.freeze(F);var he=/^[a-z0-9][a-z0-9_-]{0,39}$/;function ve(n){return typeof n=="string"&&he.test(n)}function J(n){if(n===null||ve(n))return n;let e=typeof n=="string"?JSON.stringify(n.length>48?`${n.slice(0,48)}\u2026`:n):`a value of type ${typeof n}`;console.warn(`[gem] showPortraitBorders: ${e} is not a border name, so nothing was sent. A name is 1 to 40 of a-z, 0-9, _ and -, starting with a letter or digit, exactly as your store page declares it under media.portrait_borders. Pass null for no art.`);}function Q(n){return typeof n=="string"&&/^[\w-]{1,64}$/.test(n)}var $={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)},O=class{constructor(e=$){this.clock=e;}clock;tokens=new Map;lastRefill=new Map;allow(e){let t=w[e];if(t===void 0)return false;let r=this.clock.now(),o=this.lastRefill.get(e)??r,s=this.tokens.get(e)??t,m=Math.max(0,r-o),i=Math.min(t,s+m*t/6e4);return i<1?(this.tokens.set(e,i),this.lastRefill.set(e,r),false):(this.tokens.set(e,i-1),this.lastRefill.set(e,r),true)}};function q(n,e){return n.toLowerCase()===e.toLowerCase()}function T(n){let e=n.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}function X(n,e){if(typeof e!="string"||e==="")return false;let t,r;try{t=new URL(n),r=new URL(e);}catch{return false}return t.protocol!=="http:"&&t.protocol!=="https:"||r.protocol!=="http:"&&r.protocol!=="https:"||t.username!==""||t.password!==""||t.pathname!=="/"||t.search!==""||t.hash!==""||t.port===""?false:T(t.hostname)&&T(r.hostname)}function Z(n,e){if(n.min>n.max||e.min>e.max)return null;let t=Math.min(n.max,e.max),r=Math.max(n.min,e.min);return t>=r?t:null}var ne="[gem: use gem.text.toPlain()]",ee=new Set,te;function Re(n){try{if(ee.has(n))return;let e=globalThis.location;if(te??=!!e?.port&&T(e.hostname??""),!te)return;ee.add(n),console.warn(`[gem] ${n} is PlayerText, turned into a string: players see ${ne}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
|
|
2
|
+
${new Error().stack}`);}catch{}}var U=class{#e;#t;constructor(e,t="player text"){this.#e=e,this.#t=t,Object.freeze(this);}toString(){return Re(this.#t),ne}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function H(n,e){return new U(n,e)}function re(n){return Math.min(16384,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}function Se(n,e){if(n!==true)return {visible:false};let t=[],r=false;for(let o of Array.isArray(e)?e:[])o==="score"?r=true:typeof o=="string"&&o.length>0&&o.length<=64&&!t.includes(o)&&t.push(o);return !r&&t.length===0?{visible:true}:{visible:true,currencies:t.slice(0,8),score:r}}function we(n){let e=[];for(let t of Array.isArray(n)?n:[]){if(e.length===4)break;if(typeof t!="object"||t===null)continue;let{id:r,label:o}=t;typeof r!="string"||r.length===0||r.length>32||typeof o!="string"||o.trim().length===0||e.some(s=>s.id===r)||e.push({id:r,label:o.trim().slice(0,40)});}return e.length===0?{settings:false}:{settings:false,items:e}}function ae(n,e){return Math.min(e,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}function be(n){let e=n.untrusted,t=H(e.displayName,"gem.player.displayName"),r=e.displayTag||e.displayHandle,o=r?H(r,"gem.player.displayTag"):void 0,s=n.discriminator||n.displayTag,m=s&&/^[0-9]{1,8}$/.test(s)?s:void 0,i=n.avatarIconUrl||n.avatarUrl,u=/^[\da-f]{8}(-[\da-f]{4}){3}-[\da-f]{12}$/i,p=n.avatarIconId,y=n.avatar3dId,c={displayName:t,displayHandle:o??t,badges:(n.badges??[]).map(g=>({itemId:g.itemId,iconUrl:g.iconUrl}))};n.playerId&&(c.playerId=n.playerId),m&&(c.discriminator=m),o&&(c.displayTag=o),i&&(c.avatarIconUrl=c.avatarUrl=i),p&&u.test(p)&&(c.avatarIconId=p),y&&u.test(y)&&(c.avatar3dId=y),n.avatar3dModelUrl&&(c.avatar3dModelUrl=n.avatar3dModelUrl),n.avatar3dIconUrl&&(c.avatar3dIconUrl=n.avatar3dIconUrl),n.avatars3d&&(c.avatars3d=n.avatars3d.filter(g=>u.test(g.id)&&/^[a-z][a-z0-9_]*$/.test(g.family)).filter((g,E,L)=>L.findIndex(_=>_.family==g.family)==E).map(({family:g,id:E,modelUrl:L,iconUrl:_})=>({family:g,id:E,modelUrl:L,iconUrl:_})));let h=n.boost,R=(h?.multipliers??[]).map(g=>({currencyId:g.currencyId,currencySlug:g.currencySlug,multiplier:g.multiplierBp/1e4})),A=R.some(g=>g.multiplier>1);return c.boost=A&&h?.expiresInDays?{active:A,multipliers:R,expiresInDays:h.expiresInDays}:{active:A,multipliers:R},c}var Ge=1e4,Oe=["appLinks","openGame","store","storeOfferSheet"],ke=["token","pause","menuSelect","settingChange","prefs","cohorts","viewport","willTerminate","localServer","roomEvent","seatedEvent","autoStartFailedEvent","ticketEvent","socketState","signalEvent","relayDraining","dedicatedEvent","clusterTarget","graphicsRoutes","partyResult","purchaseResult","purchaseSettled","inventoryChanged","shareResult","deviceSettings","adResult","momentResult","signInResult","friendChallengeResult","playInviteResult"],xe=new WeakMap;var k=class{constructor(e){this.options=e;if(e.expectedSource===void 0||e.expectedSource===null)throw new Error("GemFrame: expectedSource is required and must not be null \u2014 pass window.parent. The handshake transfers the MessagePort, and origin alone does not say WHICH document on that origin sent it.");this.expectedSource=e.expectedSource,this.clock=e.clock??$,this.inbound=new O(this.clock),this.outbound=new O(this.clock);}options;state="waiting";port=null;version=null;peerCapabilities=[];unbidden=false;engagedSent=false;readyPending=false;readySent=false;settleWaiters=[];clock;inbound;outbound;expectedSource;get currentState(){return this.state}get parentCapabilities(){return this.peerCapabilities}parentSupports(e){return this.peerCapabilities.includes(e)}get protocolVersion(){return this.version}get unbiddenLaunch(){return this.unbidden}handleWindowMessage(e){if(e.source!==this.expectedSource)return this.refuse(e,"handshake did not come from the expected embedder window"),false;if(!(this.options.allowedEmbedders.some(i=>q(i,e.origin))||X(e.origin,this.options.selfOrigin)||(xe.get(this)??[]).some(i=>q(i,e.origin))))return this.refuse(e,`embedder '${e.origin}' is not in allowedEmbedders`),this.state==="waiting"&&this.transition("refused"),false;if(this.state==="connected")return this.fail("handshake_duplicate","this document already has a port"),false;if(this.state!=="waiting")return false;let r=I["gem.handshake"]?.(e.data);if(r)return this.refuse(e,`malformed handshake: ${r}`),false;let o=e.data;if(!q(o.embedder,e.origin))return this.refuse(e,`handshake claims embedder '${o.embedder}' but arrived from '${e.origin}'`),false;let s=e.ports?.[0];if(!s)return this.refuse(e,"handshake transferred no MessagePort"),false;let m=Z(S,o.versions);return m===null?(s.onmessage=null,s.postMessage({gem:l,type:"gem.error",code:"version_mismatch",message:`frame supports v${S.min}..v${S.max}`}),s.close(),this.transition("refused"),this.options.onError?.("version_mismatch"),false):(this.port=s,this.version=m,s.onmessage=i=>this.receive(i.data,i.ports??[]),s.start?.(),this.peerCapabilities=o.capabilities??[],this.unbidden=o.unbidden===true,s.postMessage({gem:l,type:"gem.handshake.accept",v:m,...this.options.capabilities===void 0?{}:{capabilities:[...this.options.capabilities]}}),this.transition("connected"),this.readyPending&&(this.readyPending=false,this.ready()),true)}ready(){if(this.state!=="connected"||!this.port){this.readyPending=true;return}if(this.readySent){this.options.onDropped?.("internal","gem.ready was already sent; duplicate suppressed");return}this.readySent=true,this.send({gem:l,type:"gem.ready"});}settled(e=Ge){return this.state!=="waiting"?Promise.resolve(this.state):new Promise(t=>{let r=s=>{this.clock.clearTimeout(o),t(s);},o=this.clock.setTimeout(()=>{let s=this.settleWaiters.indexOf(r);s>=0&&this.settleWaiters.splice(s,1),t(this.state);},e);this.settleWaiters.push(r);})}progress(e,t){this.send({gem:l,type:"gem.progress",loaded:e,total:t});}requestToken(e,t){this.send({gem:l,type:"gem.requestToken",requestId:e,reason:t});}requestLocalServer(e,t){return this.parentSupports("localHost")?(this.send({gem:l,type:"gem.requestLocalServer",requestId:e,gameRoomId:t}),true):false}exit(e){this.send(e===void 0?{gem:l,type:"gem.exit"}:{gem:l,type:"gem.exit",reason:e});}openExternal(e){this.send({gem:l,type:"gem.openExternal",url:e});}requestFullscreen(e){this.send({gem:l,type:"gem.requestFullscreen",enabled:e});}reportMuted(e){return this.gated("audioState")?(this.send({gem:l,type:"gem.audioState",muted:e}),true):false}reportEngaged(){return this.engagedSent||!this.gated("engagement")||!this.send({gem:l,type:"gem.engaged"})?false:(this.engagedSent=true,true)}cueReward(e){if(!this.gated("rewardCue"))return false;let t={gem:l,type:"gem.rewardCue",currencySlug:String(e.currencySlug).slice(0,32)};return Q(e.cueId)&&(t.cueId=e.cueId),e.expected!==void 0&&Number.isFinite(e.expected)&&e.expected>=1&&(t.expected=Math.min(1e9,Math.round(e.expected))),e.origin&&(t.origin={x:re(e.origin.x),y:re(e.origin.y)}),this.send(t),true}showPortraitBorders(e){let t=J(e);return t===void 0||!this.gated("portraitBorders")?false:this.send(t===null?{gem:l,type:"gem.portraitBorders"}:{gem:l,type:"gem.portraitBorders",name:t})}setWalletVisible(e,t){return this.gated("walletDisplay")?this.send({gem:l,type:"gem.walletDisplay",...Se(e,t?.only)}):false}setMenu(e){return this.gated("gameMenu")?this.send({gem:l,type:"gem.menu",...we(e)}):false}declareSettings(e){return this.gated("gameSettings")?this.send({gem:l,type:"gem.settingsDeclare",settings:e}):false}setGemCorner(e){return this.gated("gemCorner")?this.send({gem:l,type:"gem.gemCorner",corner:e}):false}setRewardPresentation(e){return this.gated("rewardPresentation")?this.send({gem:l,type:"gem.rewardPresentation",mode:e}):false}setMenuStyle(e){return this.gated("menuStyle")?this.send(e===null?{gem:l,type:"gem.menuStyle"}:{gem:l,type:"gem.menuStyle",ground:e.ground,accent:e.accent}):false}requestShare(e,t){return this.gated("share")?this.send({gem:l,type:"gem.requestShare",...t===void 0?{}:{requestId:t},params:e.map(({key:r,value:o})=>({key:r,value:o}))}):false}requestAvatarPicker(e){return this.gated("avatarPicker")?this.send({gem:l,type:"gem.requestAvatarPicker",...e==="2d"||e==="3d"?{tab:e}:{}}):false}requestVibrate(e){return this.gated("vibration")?this.send({gem:l,type:"gem.vibrate",pattern:[...e]}):false}reportFrameStats(e){return this.gated("frameStats")?(this.send({gem:l,type:"gem.frameStats",fps:ae(e.fps,1e3),frameTimeP95Ms:ae(e.frameTimeP95Ms,1e5),counts:e.counts==="gameDraws"?"gameDraws":"pageFrames"}),true):false}sendGameContext(e){return this.state!=="connected"?false:(this.send({gem:l,type:"gem.gameContext",context:e}),true)}signal(e,t,r){this.send({gem:l,type:"gem.signal",signal:e,matchId:t,data:r});}dedicatedOffer(e,t,r){this.send({gem:l,type:"gem.dedicatedOffer",matchId:e,sdp:t,intent:r});}requestParty(e){return this.send({gem:l,type:"gem.partyRequest",requestId:e})}requestPurchase(e,t,r,o,s,m,i){return this.send({gem:l,type:"gem.requestPurchase",requestId:e,purchaseKind:t,targetId:r,currencySlug:o,...s===void 0?{}:{quantity:s},...m===void 0?{}:{catalogId:m},...i===void 0?{}:{origin:i}})}requestAvatar3dPurchase(e,t,r){return this.parentSupports("avatar3dPurchases")?this.send({gem:l,type:"gem.requestAvatar3dPurchase",requestId:e,itemId:t,currencySlug:r}):false}putDeviceSettings(e,t){return this.send({gem:l,type:"gem.deviceSettings.put",requestId:e,settings:t})}requestAd(e,t,r){return this.send({gem:l,type:"gem.requestAd",requestId:e,placement:t,format:r})}signalMoment(e,t,r,o){return this.send({gem:l,type:"gem.signalMoment",requestId:e,kind:t,...r===void 0?{}:{placement:r},...o===true?{wall:true}:{}})}readyCalled(){return this.readySent||this.readyPending}requestSignIn(e){return this.send({gem:l,type:"gem.requestSignIn",requestId:e})}requestFriendChallenge(e,t,r,o){return this.send({gem:l,type:"gem.requestFriendChallenge",requestId:e,playerId:t,template:r,...o===void 0?{}:{params:o}})}requestArcade(e){return this.gated(C(e.type))&&this.send({gem:l,...e})}close(){this.port&&(this.port.onmessage=null,this.port.close(),this.port=null),this.state!=="refused"&&this.transition("closed");}transition(e){if(this.state!==e){this.state=e;for(let t of this.settleWaiters.splice(0))t(e);this.options.onStateChange?.(e);}}refuseMalformed(e,t){if(!this.inbound.allow(P)){this.options.onDropped?.(e,t);return}this.fail(e,t);}dropUnknownType(e){this.inbound.allow(P)&&this.options.onDropped?.("unsupported",`ignored unknown message type '${e}'`);}refuse(e,t){e.ports?.[0]?.close?.(),this.inbound.allow(P)&&this.options.onRefused?.(t);}fail(e,t){this.options.onError?.(e,t),this.state==="connected"&&this.port&&this.send({gem:l,type:"gem.error",code:e,...t===void 0?{}:{message:t}});}gated(e){return this.state==="connected"&&this.parentSupports(e)}send(e){if(this.state!=="connected"||!this.port)return this.options.onDropped?.("internal",`dropped ${String(e.type)} before connect`),false;let t=e.type;if(!this.outbound.allow(t))return this.options.onError?.("rate_limited",`frame exceeded its own limit for ${t}`),false;let r=I[t]?.(e);return r?(this.options.onError?.("internal",`refusing to send malformed ${t}: ${r}`),false):(this.port.postMessage(this.version===null?e:{...e,v:this.version}),true)}receive(e,t=[]){let r=false;try{r=this.dispatchInbound(e,t);}finally{r||oe(t);}}dispatchInbound(e,t){if(this.state!=="connected")return false;let r=typeof e=="object"&&e!==null?e.type:void 0;if(typeof r!="string")return this.refuseMalformed("invalid_message","message has no type"),false;let o=I[r];if(!o)return this.dropUnknownType(r),false;if(!this.inbound.allow(r))return this.fail("rate_limited",`parent exceeded the limit for ${r}`),false;let s=C(r);if(s!==void 0&&!this.options.capabilities?.includes(s))return this.fail("unsupported_capability",`${r} requires the '${s}' capability, which this frame did not advertise`),false;let m=o(e);if(m)return this.fail("invalid_message",`${r}: ${m}`),false;let i=e;if(i.v!==this.version)return this.fail("invalid_message",`${r}: expected v ${String(this.version)}`),false;switch(r){case "gem.earnAllowanceChanged":this.options.onEarnAllowanceChanged?.();break;case "gem.devtools":this.options.onDevtools?.(i.action);break;case "gem.requestContext":this.options.onRequestContext?.();break;case "gem.screenshot":{let u=t[0];if(!u){this.options.onError?.("invalid_message","gem.screenshot transferred no MessagePort");break}let p={maxWidth:i.maxWidth,maxHeight:i.maxHeight};if(!this.options.onScreenshot){u.close(),this.screenshotDenied("not_wired",false);break}return oe(t.slice(1)),this.options.onScreenshot(p,u,(y,c)=>this.screenshotDenied(y,c)),true}case "gem.token.denied":this.options.onTokenDenied?.(i);break;case "gem.localServer.denied":this.options.onLocalServerDenied?.(i);break;case "gem.player":{let u=i;this.options.onPlayer?.(be(u),u.signInAvailable);break}case "gem.deviceSettings.result":this.options.onDeviceSettingsResult?.(i);break;case "gem.error":this.options.onError?.(i.code,i.message);break;default:if(ke.includes(r.slice(4))){this.options[`on${r[4].toUpperCase()}${r.slice(5)}`]?.(i);break}if(Oe.includes(C(r))){this.options.onArcadeAnswer?.(i);break}this.fail("unsupported",`no frame handler for '${r}'`);}return false}screenshotDenied(e,t){this.send({gem:l,type:"gem.screenshot.denied",reason:e,retryable:t});}};function oe(n){for(let e of n)try{e?.close?.();}catch{}}N();function Pe(n){if((n.expectedSource??window.parent)===window)throw new Error("GemWebSdkBridge.connect: this document is not framed (window.parent === window), so there is no embedder to hand it a port. A game runs inside the Gem Arcade iframe; opening it directly will never complete a handshake.");let e=new k({...n,expectedSource:n.expectedSource??window.parent}),t=r=>{let o=e.handleWindowMessage({data:r.data,origin:r.origin,source:r.source,ports:r.ports});return o&&window.removeEventListener("message",t),o};return window.addEventListener("message",t),W(window,t),e}var se={connect:Pe,GemFrame:k,PROTOCOL:l,SUPPORTED_VERSIONS:S};window.GemWebSdkBridge=se;var Tn=se;return Tn;})();
|