@indiegems/gem-web-sdk 13.3.3 → 13.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/game.d.ts +17 -1
- package/dist/gem-web-sdk.bridge.js +1 -1
- package/dist/gem-web-sdk.esm.js +3 -3
- 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 +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/sdk.d.ts +18 -1
- package/dist/server-api.d.ts +1 -0
- package/dist/server.d.ts +1 -0
- package/docs/analytics.md +44 -1
- package/docs/api/api-reference-function.md +1 -1
- package/docs/api/api-reference-game.md +130 -3
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +132 -4
- package/docs/changelog.md +20 -0
- package/docs/getting-started.md +19 -13
- package/docs/inventory-and-catalogs.md +21 -0
- package/docs/manifest.json +18 -18
- package/docs/p2p-and-parties.md +32 -3
- package/docs/rewarded-ads.md +53 -32
- package/docs/rooms-and-matches.md +49 -1
- package/docs/server-bundles.md +2 -2
- package/docs/what-a-game-must-do.md +150 -51
- package/package.json +1 -1
- package/schema/bridge.v1.json +22 -1
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,26 @@ 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
|
+
## 13.4.1
|
|
20
|
+
|
|
21
|
+
Upgrading from 13.4.0. Impact: none.
|
|
22
|
+
|
|
23
|
+
Nothing in this release asks anything of a game.
|
|
24
|
+
|
|
25
|
+
## 13.4.0
|
|
26
|
+
|
|
27
|
+
Upgrading from 13.3.3. Impact: required.
|
|
28
|
+
|
|
29
|
+
### Rebuild
|
|
30
|
+
|
|
31
|
+
- The reserved areas accepted by GemHost.sendViewport and the reserved list on GemViewport now allow an optional control box on each area. The field is additive and optional, so existing code keeps working. Recompile your game; no code change is needed unless you want to use the new field.
|
|
32
|
+
|
|
33
|
+
### New capability
|
|
34
|
+
|
|
35
|
+
- Each reserved area can now carry the box of the control inside it, with x, y, width and height. Reserved areas are keep-out zones that extend to the frame edges, so their middle is not the middle of the control. When you want to align your own interface with the Arcade control, for example to centre a top bar on it, read the control box from the area instead of deriving it from the keep-out zone. The field is absent for an area with no control, so check for it first.
|
|
36
|
+
- The room manager now exposes a read-only playWith value. When the Arcade opens your game to play with a friend or party member, a quick-join may land the player in that person's room. The value tells your game whether the player joined somebody or no such room was available. It is null when the game was not opened this way, and it never says who the other player is. Use it to adjust your lobby or welcome messaging.
|
|
37
|
+
- Catalog recipes now include an icon_url field with the platform-hosted icon. The Arcade purchase sheet already draws this icon, and your game can show the same icon in its own shop or inventory screens instead of shipping a separate copy.
|
|
38
|
+
|
|
19
39
|
## 13.3.3
|
|
20
40
|
|
|
21
41
|
Upgrading from 13.3.2. Impact: none.
|
package/dist/game.d.ts
CHANGED
|
@@ -552,6 +552,7 @@ type SnapshotRecipe = {
|
|
|
552
552
|
"display_name"?: string | null;
|
|
553
553
|
"event_id"?: string | null;
|
|
554
554
|
"grants"?: RecipeOperation[] | null;
|
|
555
|
+
"icon_url"?: string | null;
|
|
555
556
|
"id": string;
|
|
556
557
|
"loot_table_id"?: string | null;
|
|
557
558
|
"max_uses"?: number | null;
|
|
@@ -1693,6 +1694,7 @@ interface RoomArgEntry {
|
|
|
1693
1694
|
readonly maxLength?: number;
|
|
1694
1695
|
}
|
|
1695
1696
|
type RoomStatus = "open" | "in_game" | "closed" | (string & {});
|
|
1697
|
+
type PlayWithOutcome = "joined" | "unavailable";
|
|
1696
1698
|
type MatchConnectionState = "disconnected" | "connecting" | "connected" | "suspended";
|
|
1697
1699
|
type MatchSessionPhase = "none" | "starting" | "ready" | "connected" | "suspended" | "ended" | (string & {});
|
|
1698
1700
|
interface MatchSession {
|
|
@@ -2034,6 +2036,7 @@ interface RoomManager {
|
|
|
2034
2036
|
readonly isInRoom: boolean;
|
|
2035
2037
|
readonly isHost: boolean;
|
|
2036
2038
|
readonly members: readonly Room["members"][number][];
|
|
2039
|
+
readonly playWith: PlayWithOutcome | null;
|
|
2037
2040
|
on<K extends RoomEventName>(event: K, listener: (...args: RoomEventMap[K]) => void): () => void;
|
|
2038
2041
|
off<K extends RoomEventName>(event: K, listener: (...args: RoomEventMap[K]) => void): void;
|
|
2039
2042
|
once<K extends RoomEventName>(event: K, listener: (...args: RoomEventMap[K]) => void): () => void;
|
|
@@ -2122,6 +2125,12 @@ interface GemViewport$1 {
|
|
|
2122
2125
|
y: number;
|
|
2123
2126
|
width: number;
|
|
2124
2127
|
height: number;
|
|
2128
|
+
control?: {
|
|
2129
|
+
x: number;
|
|
2130
|
+
y: number;
|
|
2131
|
+
width: number;
|
|
2132
|
+
height: number;
|
|
2133
|
+
};
|
|
2125
2134
|
}[];
|
|
2126
2135
|
}
|
|
2127
2136
|
interface GemDeviceSettings {
|
|
@@ -3121,6 +3130,13 @@ interface GemReservedArea {
|
|
|
3121
3130
|
readonly y: number;
|
|
3122
3131
|
readonly width: number;
|
|
3123
3132
|
readonly height: number;
|
|
3133
|
+
readonly control?: GemControlBox;
|
|
3134
|
+
}
|
|
3135
|
+
interface GemControlBox {
|
|
3136
|
+
readonly x: number;
|
|
3137
|
+
readonly y: number;
|
|
3138
|
+
readonly width: number;
|
|
3139
|
+
readonly height: number;
|
|
3124
3140
|
}
|
|
3125
3141
|
interface WalletVisibleOptions {
|
|
3126
3142
|
readonly only?: readonly string[];
|
|
@@ -3211,4 +3227,4 @@ interface ExitAnalytics {
|
|
|
3211
3227
|
}
|
|
3212
3228
|
declare function leaveAndExit(rooms: ExitRooms, bridge: ExitBridge | null, reason?: string, analytics?: ExitAnalytics): Promise<void>;
|
|
3213
3229
|
declare function createGem(options?: GemOptions): Gem;
|
|
3214
|
-
export { ARCADE_EMBEDDERS, AVATAR_RIGS, type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type Avatar3dFamily, type Avatar3dOffer, type Avatar3dPrice, type Avatar3dPurchaseRequest, type AvatarRigNode, type AvatarRigs, type Avatars3dApi, type BootMark, type BootTimeline, type Challenge, type ChallengeWindow, ChallengesApi, 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, 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 GameConfig, type GameMenu, type GameMenuItem, type GameServerLink, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemCorner, type GemDevTools, GemFrame, GemFunctionError, type GemGraphicsQuality, type GemIdentity, type GemInsets, type GemLook, type GemLookBase, type GemLookDelta, type GemLookOptions, type GemLookSpeed, type GemMatchApi, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, type GemRecommendedSettings, type GemReservedArea, GemSaveError, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerLifecycle, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchServeOptions, type MatchTransport, type MessageMeta, type MomentKind, type MomentResult, type MomentSignal, type MomentsApi, type MultiTransportSession, PLATFORM_EVENTS, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RewardCue, type RewardedStatus, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, 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 TransportAdvert, type TransportKind, TransportRefusal, UNRELIABLE_CHANNEL_LABEL, type VibrationApi, type WalletVisibleOptions, type WornAvatar3d, asPlayerText, createBootTimeline, createGem, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, text, webTransportAvailable };
|
|
3230
|
+
export { ARCADE_EMBEDDERS, AVATAR_RIGS, type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type Avatar3dFamily, type Avatar3dOffer, type Avatar3dPrice, type Avatar3dPurchaseRequest, type AvatarRigNode, type AvatarRigs, type Avatars3dApi, type BootMark, type BootTimeline, type Challenge, type ChallengeWindow, ChallengesApi, 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, 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 GameConfig, type GameMenu, type GameMenuItem, type GameServerLink, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemControlBox, type GemCorner, type GemDevTools, GemFrame, GemFunctionError, type GemGraphicsQuality, type GemIdentity, type GemInsets, type GemLook, type GemLookBase, type GemLookDelta, type GemLookOptions, type GemLookSpeed, type GemMatchApi, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, type GemRecommendedSettings, type GemReservedArea, GemSaveError, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerLifecycle, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchServeOptions, type MatchTransport, type MessageMeta, type MomentKind, type MomentResult, type MomentSignal, type MomentsApi, type MultiTransportSession, PLATFORM_EVENTS, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RewardCue, type RewardedStatus, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, 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 TransportAdvert, type TransportKind, TransportRefusal, UNRELIABLE_CHANNEL_LABEL, type VibrationApi, type WalletVisibleOptions, type WornAvatar3d, asPlayerText, createBootTimeline, createGem, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, text, webTransportAvailable };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var GemWebSdkBridgeBundle=(function(){'use strict';var E="GemWebSdkHandshake";function te(){return typeof document>"u"?void 0:document.readyState}var j=()=>Date.now();function D(t={}){let e=t.win??window,n=e,r=n[E];if(r!==void 0)return r;let s=t.readyState??te,i=t.now??j,d=[],a=[],m=p=>{let c=p.data;!c||c.type!=="gem.handshake"||(d.length>=4&&(d.shift(),a.shift(),g.dropped+=1),d.push(p),a.push(i()));};e.addEventListener("message",m);let g={events:d,times:a,dropped:0,late:s()==="complete",uninstall(){e.removeEventListener("message",m);}};return n[E]=g,g}function F(t,e,n={}){let r=t[E];if(r===void 0)return null;let s=n.ttlMs??9500,i=n.now??j,d=r.events.splice(0),a=r.times?.splice(0),m=0,g=0,p=false,c=i()-s;for(let y=d.length-1;y>=0;y--){let f=a?.[y];if(f!==void 0&&f<c){g+=1;continue}if(m+=1,e(d[y])===true){p=true;break}}return r.uninstall(),{capture:r,delivered:m,stale:g,accepted:p}}var l="gem-web-bridge",k={min:1,max:1},h=65536,$=8,w=5e3,U=1024;var v=Object.create(null),R="__malformed";var q=Object.create(null),re=Object.freeze([["gem.asyncOpponents.","asyncOpponents"],["gem.vibration.","vibration"],["gem.viewport.","reservedAreas"],["gem.moments.","moments"]]);function H(t){let e=q[t];if(e!==void 0)return e;for(let[n,r]of re)if(t.startsWith(n))return r}function oe(t){let e=/^([a-z][a-z0-9+.-]*):\/\/([a-z0-9.-]+|\[[0-9a-f:.]+\])(:([0-9]{1,5}))?$/i.exec(t);return e===null?false:e[4]===void 0||Number(e[4])<=65535}function ae(t){let e;try{e=new URL(t);}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 se(t){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(t)}function ie(t){return /^[a-z_]+$/.test(t)}function I(t,e,n){if(e>$)return `nesting deeper than ${$}`;if(++n.nodes>w)return `more than ${w} values`;if(n.bytes>h)return `over the ${h} byte limit`;if(t==null)return n.bytes+=4,null;let r=typeof t;if(r==="boolean")return n.bytes+=5,null;if(r==="number")return n.bytes+=8,null;if(r==="string")return n.bytes+=t.length*3+2,null;if(r!=="object")return `${r} is not plain data`;let s=t;if(n.seen.has(s))return "a repeated or cyclic object reference";if(n.seen.add(s),Array.isArray(t)){if(t.length>U)return `an array of ${t.length} entries, over the ${U} limit`;n.bytes+=2;for(let a of t){let m=I(a,e+1,n);if(m)return m}return null}let i=Object.getPrototypeOf(t);if(i!==Object.prototype&&i!==null)return "a value that is not a plain object";n.bytes+=2;let d=t;for(let a in d){if(!Object.prototype.hasOwnProperty.call(d,a))continue;if(++n.nodes>w)return `more than ${w} values`;if(n.bytes+=a.length*3+4,n.bytes>h)return `over the ${h} byte limit`;let m=I(d[a],e+1,n);if(m)return m}return null}function le(t){let e={nodes:0,bytes:0,seen:new Set},n=I(t,0,e);return n?`message contains ${n}`:e.bytes>h?`message is over the ${h} byte limit`:null}var de={origin:[oe,"not a well-formed origin"],url:[ae,"not a safe absolute http(s) URL"],bcp47:[se,"not a well-formed BCP 47 tag"],code:[ie,"not a code of lower-case letters and underscores"]};function W(t,e,n){for(let r of e){let s=n===""?r.n:`${n}.${r.n}`,i=t[r.n];if(i==null){if(r.o)continue;return `${s}: required`}let d=B(i,r,s);if(d)return d}return null}function B(t,e,n){switch(e.k){case "s":{if(typeof t!="string")return `${n}: expected string`;if(t.length>e.max)return `${n}: exceeds ${e.max} characters`;if(e.f){let[r,s]=de[e.f];if(!r(t))return `${n}: ${s}`}return null}case "i":return typeof t!="number"||!Number.isInteger(t)?`${n}: expected integer`:t<e.lo||t>e.hi?`${n}: out of range ${e.lo}..${e.hi}`:null;case "b":return typeof t=="boolean"?null:`${n}: expected boolean`;case "e":{let r=e.v;return r.includes(t)?null:`${n}: not one of ${r.join("|")}`}case "o":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected object`:W(t,e.fs,n);case "j":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected a plain object`:null;case "a":{if(!Array.isArray(t))return `${n}: expected array`;if(t.length>e.max)return `${n}: exceeds ${e.max} items`;let r=e.it,s=`${n}[]`;for(let i of t){if(i==null){if(r.o)continue;return `${s}: required`}let d=B(i,r,s);if(d)return d}return null}default:{let r=e.k;return `${n}: unknown kind ${String(r)}`}}}var N=Object.create(null);function o(t,e,n,r){return v[t]=n,r&&(q[t]=r),N[t]=s=>{let i=le(s);if(i)return i;if(typeof s!="object"||s===null||Array.isArray(s))return "message: expected object";let d=s;return d.gem!==l?"gem: wrong protocol marker":d.type!==t?`type: expected ${t}`:W(d,e,"")}}o("gem.handshake",[{n:"versions",k:"o",fs:[{n:"min",k:"i",lo:1,hi:1e3},{n:"max",k:"i",lo:1,hi:1e3}]},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}},{n:"embedder",k:"s",max:2048,f:"origin"},{n:"unbidden",k:"b",o:1}],30);o("gem.handshake.accept",[{n:"v",k:"i",lo:1,hi:1e3},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}}],5);o("gem.token",[{n:"token",k:"s",max:4096},{n:"requestId",k:"s",o:1,max:64},{n:"generation",k:"i",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"s",o:1,max:512,f:"url"},{n:"playerId",k:"s",max:64},{n:"gameId",k:"s",max:64},{n:"channel",k:"e",v:["dev","test","release"]},{n:"gameVersion",k:"s",o:1,max:64},{n:"expiresAt",k:"i",lo:0,hi:4102444800},{n:"chainEndsAt",k:"i",lo:0,hi:4102444800},{n:"allowDevTools",k:"b",o:1}],30);o("gem.token.denied",[{n:"requestId",k:"s",max:64},{n:"retryable",k:"b"},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:36e5},{n:"reason",k:"e",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"s",max:64}],30);o("gem.player",[{n:"untrusted",k:"o",fs:[{n:"displayName",k:"s",max:64},{n:"displayTag",k:"s",o:1,max:80},{n:"displayHandle",k:"s",max:80}]},{n:"playerId",k:"s",o:1,max:64},{n:"discriminator",k:"s",o:1,max:8},{n:"avatarIconUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatarIconId",k:"s",o:1,max:64},{n:"avatar3dId",k:"s",o:1,max:64},{n:"avatar3dModelUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatar3dIconUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatars3d",k:"a",o:1,max:8,it:{n:"",k:"o",fs:[{n:"family",k:"s",max:32},{n:"id",k:"s",max:64},{n:"modelUrl",k:"s",max:256,f:"url"},{n:"iconUrl",k:"s",max:256,f:"url"}]}},{n:"badges",k:"a",o:1,max:2,it:{n:"",k:"o",fs:[{n:"itemId",k:"s",max:64},{n:"iconUrl",k:"s",max:2048,f:"url"}]}},{n:"displayTag",k:"s",max:8},{n:"avatarUrl",k:"s",o:1,max:2048,f:"url"},{n:"boost",k:"o",o:1,fs:[{n:"multipliers",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"currencyId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"multiplierBp",k:"i",lo:1e4,hi:1e6}]}},{n:"expiresInDays",k:"i",o:1,lo:1,hi:7}]}],12);o("gem.pause",[{n:"paused",k:"b"}],120);o("gem.prefs",[{n:"reducedMotion",k:"b"},{n:"muted",k:"b"},{n:"showFrameStats",k:"b",o:1},{n:"locale",k:"s",max:35,f:"bcp47"},{n:"recommended",k:"o",o:1,fs:[{n:"volume",k:"i",lo:0,hi:100},{n:"batterySaver",k:"b"},{n:"keyboardLayout",k:"e",v:["wasd","arrows"]},{n:"gamepadConfirm",k:"e",v:["south","east"]},{n:"vibration",k:"b"},{n:"lookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"gamepadLookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"invertLookY",k:"b",o:1},{n:"touchMovement",k:"s",o:1,max:16,f:"code"},{n:"graphicsQuality",k:"s",o:1,max:16,f:"code"},{n:"graphicsQualityAuto",k:"b",o:1}]}],60);o("gem.cohorts",[{n:"cohorts",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"experimentId",k:"s",max:36},{n:"variantKey",k:"s",max:32}]}}],12,"cohorts");o("gem.earnAllowanceChanged",[],30,"earnAllowance");o("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}]}}],60,"viewport");o("gem.deviceSettings",[{n:"settings",k:"j",o:1}],12,"deviceSettings");o("gem.willTerminate",[{n:"reason",k:"e",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"i",lo:0,hi:6e4}],10);o("gem.roomEvent",[{n:"event",k:"e",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"s",max:64},{n:"matchId",k:"s",o:1,max:64},{n:"version",k:"i",o:1,lo:0,hi:2147483647},{n:"reason",k:"s",o:1,max:64},{n:"platform",k:"e",o:1,v:["universal","mobile"]}],120,"rooms");o("gem.socketState",[{n:"connected",k:"b"},{n:"reason",k:"e",o:1,v:["connecting","dropped","watchdog","terminal"]}],12,"socketState");o("gem.seatedEvent",[{n:"roomId",k:"s",max:64}],60,"partySeating");o("gem.autoStartFailedEvent",[{n:"roomId",k:"s",max:64},{n:"code",k:"s",max:64}],30,"autoStartFailure");o("gem.ticketEvent",[{n:"event",k:"e",v:["queued","matched","expired","cancelled","failed"]},{n:"ticketId",k:"s",max:64},{n:"partySize",k:"i",o:1,lo:1,hi:64},{n:"queuedAt",k:"i",o:1,lo:0,hi:4102444800},{n:"expiresAt",k:"i",o:1,lo:0,hi:4102444800},{n:"reason",k:"s",o:1,max:64},{n:"roomId",k:"s",o:1,max:64}],60,"ticketEvents");o("gem.signalEvent",[{n:"event",k:"e",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}],1800,"p2p");o("gem.dedicatedEvent",[{n:"event",k:"e",v:["answer","error","matchEnded"]},{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",o:1,max:10240},{n:"sessionId",k:"s",o:1,max:64},{n:"code",k:"s",o:1,max:64},{n:"message",k:"s",o:1,max:256},{n:"reason",k:"s",o:1,max:64}],120,"dedicated");o("gem.partyResult",[{n:"requestId",k:"s",max:64},{n:"partyId",k:"s",o:1,max:64}],30,"parties");o("gem.clusterTarget",[{n:"clusterTargetId",k:"s",max:64},{n:"clusterTargetIds",k:"a",o:1,max:3,it:{n:"",k:"s",max:64}}],12,"clusterTarget");o("gem.devtools",[{n:"action",k:"e",v:["open","close","toggle"]}],30,"devtools");o("gem.screenshot",[{n:"maxWidth",k:"i",lo:1,hi:7680},{n:"maxHeight",k:"i",lo:1,hi:4320}],6,"screenshot");o("gem.screenshot.denied",[{n:"reason",k:"e",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"b"}],12,"screenshot");o("gem.requestContext",[],12,"feedbackContext");o("gem.gameContext",[{n:"context",k:"j"}],12,"feedbackContext");o("gem.signal",[{n:"signal",k:"e",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}],1200,"p2p");o("gem.dedicatedOffer",[{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",max:10240},{n:"intent",k:"e",v:["initial","ice_restart","full_reconnect"]}],60,"dedicated");o("gem.partyRequest",[{n:"requestId",k:"s",max:64}],12,"parties");o("gem.ready",[],5);o("gem.engaged",[],5,"engagement");o("gem.progress",[{n:"loaded",k:"i",lo:0,hi:1099511627776},{n:"total",k:"i",lo:0,hi:1099511627776}],600);o("gem.requestToken",[{n:"requestId",k:"s",max:64},{n:"reason",k:"e",v:["initial","expiring","rejected"]}],12);o("gem.requestLocalServer",[{n:"requestId",k:"s",max:64},{n:"gameRoomId",k:"s",max:64}],6,"localHost");o("gem.localServer",[{n:"requestId",k:"s",max:64},{n:"serverId",k:"s",o:1,max:128}],30,"localHost");o("gem.localServer.denied",[{n:"requestId",k:"s",max:64},{n:"retryable",k:"b"},{n:"reason",k:"e",v:["refused","unavailable"]}],30,"localHost");o("gem.exit",[{n:"reason",k:"s",o:1,max:64}],5);o("gem.openExternal",[{n:"url",k:"s",max:2048,f:"url"}],6);o("gem.requestFullscreen",[{n:"enabled",k:"b"}],30);o("gem.audioState",[{n:"muted",k:"b"}],120,"audioState");o("gem.rewardCue",[{n:"currencySlug",k:"s",max:32},{n:"expected",k:"i",o:1,lo:1,hi:1e9},{n:"origin",k:"o",o:1,fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384}]}],60,"rewardCue");o("gem.walletDisplay",[{n:"visible",k:"b"},{n:"currencies",k:"a",o:1,max:8,it:{n:"",k:"s",max:64}},{n:"score",k:"b",o:1}],60,"walletDisplay");o("gem.controlsDeclare",[{n:"uses",k:"o",fs:[{n:"lookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"gamepadLookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"invertLookY",k:"s",o:1,max:16,f:"code"},{n:"touchMovement",k:"s",o:1,max:16,f:"code"}]}],60,"controls");o("gem.menu",[{n:"settings",k:"b"},{n:"items",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"id",k:"s",max:32},{n:"label",k:"s",max:40}]}}],60,"gameMenu");o("gem.menuSelect",[{n:"entry",k:"e",v:["settings","item"]},{n:"id",k:"s",o:1,max:32}],60,"gameMenu");o("gem.gemCorner",[{n:"corner",k:"e",v:["top-left","top-right","bottom-left","bottom-right"]}],12,"gemCorner");o("gem.requestShare",[{n:"params",k:"a",max:16,it:{n:"",k:"o",fs:[{n:"key",k:"s",max:64},{n:"value",k:"s",max:512}]}}],6,"share");o("gem.requestAvatarPicker",[{n:"tab",k:"e",o:1,v:["2d","3d"]}],6,"avatarPicker");o("gem.vibrate",[{n:"pattern",k:"a",max:99,it:{n:"",k:"i",lo:0,hi:1e4}}],600,"vibration");o("gem.frameStats",[{n:"fps",k:"i",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"i",lo:0,hi:1e5},{n:"counts",k:"e",o:1,v:["pageFrames","gameDraws"]}],120,"frameStats");o("gem.portraitBorders",[{n:"name",k:"s",o:1,max:40}],60,"portraitBorders");o("gem.error",[{n:"code",k:"e",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"s",o:1,max:256}],60);o("gem.requestPurchase",[{n:"requestId",k:"s",max:64},{n:"purchaseKind",k:"e",v:["item","recipe"]},{n:"targetId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"quantity",k:"i",o:1,lo:1,hi:10},{n:"catalogId",k:"s",o:1,max:64}],12,"purchases");o("gem.requestAvatar3dPurchase",[{n:"requestId",k:"s",max:64},{n:"itemId",k:"s",max:64},{n:"currencySlug",k:"s",max:32}],12,"avatar3dPurchases");o("gem.purchaseResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["ok","declined","unavailable"]},{n:"reason",k:"s",o:1,max:64,f:"code"},{n:"purchaseId",k:"s",o:1,max:64}],30,"purchases");o("gem.deviceSettings.put",[{n:"requestId",k:"s",max:64},{n:"settings",k:"j"}],30,"deviceSettings");o("gem.deviceSettings.result",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["stored","too_large","unavailable"]}],30,"deviceSettings");o("gem.requestAd",[{n:"requestId",k:"s",max:64},{n:"placement",k:"s",max:32},{n:"format",k:"e",v:["interstitial","rewarded"]}],6,"ads");o("gem.adResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["shown","no_ad","unavailable"]}],12,"ads");o("gem.signalMoment",[{n:"requestId",k:"s",max:64},{n:"kind",k:"e",v:["level_end","run_end","match_end","menu_return","other_break"]},{n:"placement",k:"s",o:1,max:32}],6,"moments");o("gem.momentResult",[{n:"requestId",k:"s",max:64},{n:"shown",k:"b"}],12,"moments");o("gem.requestSignIn",[{n:"requestId",k:"s",max:64}],6,"signIn");o("gem.signInResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["signed_in","declined","unavailable"]}],12,"signIn");o("gem.requestFriendChallenge",[{n:"requestId",k:"s",max:64},{n:"playerId",k:"s",max:64},{n:"template",k:"s",max:64},{n:"params",k:"j",o:1}],12,"friendChallenges");o("gem.friendChallengeResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["accepted","cancelled","refused","unavailable","rate_limited","invalid"]},{n:"code",k:"s",o:1,max:64},{n:"param",k:"s",o:1,max:64},{n:"channel",k:"s",o:1,max:16},{n:"configVersion",k:"i",o:1,lo:0,hi:9007199254740991},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:864e5},{n:"detail",k:"s",o:1,max:300}],30,"friendChallenges");var S=Object.freeze(N);v.__malformed=60;Object.freeze(v);Object.freeze(q);var me=/^[a-z0-9][a-z0-9_-]{0,39}$/;function ce(t){return typeof t=="string"&&me.test(t)}function V(t){if(t===null||ce(t))return t;let e=typeof t=="string"?JSON.stringify(t.length>48?`${t.slice(0,48)}\u2026`:t):`a value of type ${typeof t}`;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.`);}var L={now:()=>Date.now(),setTimeout:(t,e)=>setTimeout(t,e),clearTimeout:t=>clearTimeout(t)},x=class{constructor(e=L){this.clock=e;}clock;tokens=new Map;lastRefill=new Map;allow(e){let n=v[e];if(n===void 0)return false;let r=this.clock.now(),s=this.lastRefill.get(e)??r,i=this.tokens.get(e)??n,d=Math.max(0,r-s),a=Math.min(n,i+d*n/6e4);return a<1?(this.tokens.set(e,a),this.lastRefill.set(e,r),false):(this.tokens.set(e,a-1),this.lastRefill.set(e,r),true)}};function A(t,e){return t.toLowerCase()===e.toLowerCase()}function G(t){let e=t.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}function z(t,e){if(typeof e!="string"||e==="")return false;let n,r;try{n=new URL(t),r=new URL(e);}catch{return false}return n.protocol!=="http:"&&n.protocol!=="https:"||r.protocol!=="http:"&&r.protocol!=="https:"||n.username!==""||n.password!==""||n.pathname!=="/"||n.search!==""||n.hash!==""||n.port===""?false:G(n.hostname)&&G(r.hostname)}function Y(t,e){if(t.min>t.max||e.min>e.max)return null;let n=Math.min(t.max,e.max),r=Math.max(t.min,e.min);return n>=r?n:null}var Q="[gem: use gem.text.toPlain()]",K=new Set,J;function ue(t){try{if(K.has(t))return;let e=globalThis.location;if(J??=!!e?.port&&G(e.hostname??""),!J)return;K.add(t),console.warn(`[gem] ${t} is PlayerText, turned into a string: players see ${Q}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
|
|
1
|
+
var GemWebSdkBridgeBundle=(function(){'use strict';var E="GemWebSdkHandshake";function te(){return typeof document>"u"?void 0:document.readyState}var j=()=>Date.now();function D(t={}){let e=t.win??window,n=e,r=n[E];if(r!==void 0)return r;let s=t.readyState??te,i=t.now??j,d=[],a=[],m=p=>{let c=p.data;!c||c.type!=="gem.handshake"||(d.length>=4&&(d.shift(),a.shift(),g.dropped+=1),d.push(p),a.push(i()));};e.addEventListener("message",m);let g={events:d,times:a,dropped:0,late:s()==="complete",uninstall(){e.removeEventListener("message",m);}};return n[E]=g,g}function F(t,e,n={}){let r=t[E];if(r===void 0)return null;let s=n.ttlMs??9500,i=n.now??j,d=r.events.splice(0),a=r.times?.splice(0),m=0,g=0,p=false,c=i()-s;for(let y=d.length-1;y>=0;y--){let f=a?.[y];if(f!==void 0&&f<c){g+=1;continue}if(m+=1,e(d[y])===true){p=true;break}}return r.uninstall(),{capture:r,delivered:m,stale:g,accepted:p}}var l="gem-web-bridge",k={min:1,max:1},h=65536,$=8,w=5e3,U=1024;var v=Object.create(null),R="__malformed";var q=Object.create(null),re=Object.freeze([["gem.asyncOpponents.","asyncOpponents"],["gem.vibration.","vibration"],["gem.viewport.","reservedAreas"],["gem.moments.","moments"]]);function H(t){let e=q[t];if(e!==void 0)return e;for(let[n,r]of re)if(t.startsWith(n))return r}function oe(t){let e=/^([a-z][a-z0-9+.-]*):\/\/([a-z0-9.-]+|\[[0-9a-f:.]+\])(:([0-9]{1,5}))?$/i.exec(t);return e===null?false:e[4]===void 0||Number(e[4])<=65535}function ae(t){let e;try{e=new URL(t);}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 se(t){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(t)}function ie(t){return /^[a-z_]+$/.test(t)}function I(t,e,n){if(e>$)return `nesting deeper than ${$}`;if(++n.nodes>w)return `more than ${w} values`;if(n.bytes>h)return `over the ${h} byte limit`;if(t==null)return n.bytes+=4,null;let r=typeof t;if(r==="boolean")return n.bytes+=5,null;if(r==="number")return n.bytes+=8,null;if(r==="string")return n.bytes+=t.length*3+2,null;if(r!=="object")return `${r} is not plain data`;let s=t;if(n.seen.has(s))return "a repeated or cyclic object reference";if(n.seen.add(s),Array.isArray(t)){if(t.length>U)return `an array of ${t.length} entries, over the ${U} limit`;n.bytes+=2;for(let a of t){let m=I(a,e+1,n);if(m)return m}return null}let i=Object.getPrototypeOf(t);if(i!==Object.prototype&&i!==null)return "a value that is not a plain object";n.bytes+=2;let d=t;for(let a in d){if(!Object.prototype.hasOwnProperty.call(d,a))continue;if(++n.nodes>w)return `more than ${w} values`;if(n.bytes+=a.length*3+4,n.bytes>h)return `over the ${h} byte limit`;let m=I(d[a],e+1,n);if(m)return m}return null}function le(t){let e={nodes:0,bytes:0,seen:new Set},n=I(t,0,e);return n?`message contains ${n}`:e.bytes>h?`message is over the ${h} byte limit`:null}var de={origin:[oe,"not a well-formed origin"],url:[ae,"not a safe absolute http(s) URL"],bcp47:[se,"not a well-formed BCP 47 tag"],code:[ie,"not a code of lower-case letters and underscores"]};function W(t,e,n){for(let r of e){let s=n===""?r.n:`${n}.${r.n}`,i=t[r.n];if(i==null){if(r.o)continue;return `${s}: required`}let d=B(i,r,s);if(d)return d}return null}function B(t,e,n){switch(e.k){case "s":{if(typeof t!="string")return `${n}: expected string`;if(t.length>e.max)return `${n}: exceeds ${e.max} characters`;if(e.f){let[r,s]=de[e.f];if(!r(t))return `${n}: ${s}`}return null}case "i":return typeof t!="number"||!Number.isInteger(t)?`${n}: expected integer`:t<e.lo||t>e.hi?`${n}: out of range ${e.lo}..${e.hi}`:null;case "b":return typeof t=="boolean"?null:`${n}: expected boolean`;case "e":{let r=e.v;return r.includes(t)?null:`${n}: not one of ${r.join("|")}`}case "o":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected object`:W(t,e.fs,n);case "j":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected a plain object`:null;case "a":{if(!Array.isArray(t))return `${n}: expected array`;if(t.length>e.max)return `${n}: exceeds ${e.max} items`;let r=e.it,s=`${n}[]`;for(let i of t){if(i==null){if(r.o)continue;return `${s}: required`}let d=B(i,r,s);if(d)return d}return null}default:{let r=e.k;return `${n}: unknown kind ${String(r)}`}}}var N=Object.create(null);function o(t,e,n,r){return v[t]=n,r&&(q[t]=r),N[t]=s=>{let i=le(s);if(i)return i;if(typeof s!="object"||s===null||Array.isArray(s))return "message: expected object";let d=s;return d.gem!==l?"gem: wrong protocol marker":d.type!==t?`type: expected ${t}`:W(d,e,"")}}o("gem.handshake",[{n:"versions",k:"o",fs:[{n:"min",k:"i",lo:1,hi:1e3},{n:"max",k:"i",lo:1,hi:1e3}]},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}},{n:"embedder",k:"s",max:2048,f:"origin"},{n:"unbidden",k:"b",o:1}],30);o("gem.handshake.accept",[{n:"v",k:"i",lo:1,hi:1e3},{n:"capabilities",k:"a",o:1,max:64,it:{n:"",k:"s",max:64}}],5);o("gem.token",[{n:"token",k:"s",max:4096},{n:"requestId",k:"s",o:1,max:64},{n:"generation",k:"i",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"s",o:1,max:512,f:"url"},{n:"playerId",k:"s",max:64},{n:"gameId",k:"s",max:64},{n:"channel",k:"e",v:["dev","test","release"]},{n:"gameVersion",k:"s",o:1,max:64},{n:"expiresAt",k:"i",lo:0,hi:4102444800},{n:"chainEndsAt",k:"i",lo:0,hi:4102444800},{n:"allowDevTools",k:"b",o:1}],30);o("gem.token.denied",[{n:"requestId",k:"s",max:64},{n:"retryable",k:"b"},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:36e5},{n:"reason",k:"e",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"s",max:64}],30);o("gem.player",[{n:"untrusted",k:"o",fs:[{n:"displayName",k:"s",max:64},{n:"displayTag",k:"s",o:1,max:80},{n:"displayHandle",k:"s",max:80}]},{n:"playerId",k:"s",o:1,max:64},{n:"discriminator",k:"s",o:1,max:8},{n:"avatarIconUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatarIconId",k:"s",o:1,max:64},{n:"avatar3dId",k:"s",o:1,max:64},{n:"avatar3dModelUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatar3dIconUrl",k:"s",o:1,max:2048,f:"url"},{n:"avatars3d",k:"a",o:1,max:8,it:{n:"",k:"o",fs:[{n:"family",k:"s",max:32},{n:"id",k:"s",max:64},{n:"modelUrl",k:"s",max:256,f:"url"},{n:"iconUrl",k:"s",max:256,f:"url"}]}},{n:"badges",k:"a",o:1,max:2,it:{n:"",k:"o",fs:[{n:"itemId",k:"s",max:64},{n:"iconUrl",k:"s",max:2048,f:"url"}]}},{n:"displayTag",k:"s",max:8},{n:"avatarUrl",k:"s",o:1,max:2048,f:"url"},{n:"boost",k:"o",o:1,fs:[{n:"multipliers",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"currencyId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"multiplierBp",k:"i",lo:1e4,hi:1e6}]}},{n:"expiresInDays",k:"i",o:1,lo:1,hi:7}]}],12);o("gem.pause",[{n:"paused",k:"b"}],120);o("gem.prefs",[{n:"reducedMotion",k:"b"},{n:"muted",k:"b"},{n:"showFrameStats",k:"b",o:1},{n:"locale",k:"s",max:35,f:"bcp47"},{n:"recommended",k:"o",o:1,fs:[{n:"volume",k:"i",lo:0,hi:100},{n:"batterySaver",k:"b"},{n:"keyboardLayout",k:"e",v:["wasd","arrows"]},{n:"gamepadConfirm",k:"e",v:["south","east"]},{n:"vibration",k:"b"},{n:"lookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"gamepadLookSensitivity",k:"i",o:1,lo:20,hi:400},{n:"invertLookY",k:"b",o:1},{n:"touchMovement",k:"s",o:1,max:16,f:"code"},{n:"graphicsQuality",k:"s",o:1,max:16,f:"code"},{n:"graphicsQualityAuto",k:"b",o:1}]}],60);o("gem.cohorts",[{n:"cohorts",k:"a",max:8,it:{n:"",k:"o",fs:[{n:"experimentId",k:"s",max:36},{n:"variantKey",k:"s",max:32}]}}],12,"cohorts");o("gem.earnAllowanceChanged",[],30,"earnAllowance");o("gem.viewport",[{n:"insets",k:"o",fs:[{n:"top",k:"i",lo:0,hi:4096},{n:"right",k:"i",lo:0,hi:4096},{n:"bottom",k:"i",lo:0,hi:4096},{n:"left",k:"i",lo:0,hi:4096}]},{n:"reserved",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384},{n:"width",k:"i",lo:0,hi:16384},{n:"height",k:"i",lo:0,hi:16384},{n:"control",k:"o",o:1,fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384},{n:"width",k:"i",lo:0,hi:16384},{n:"height",k:"i",lo:0,hi:16384}]}]}}],60,"viewport");o("gem.deviceSettings",[{n:"settings",k:"j",o:1}],12,"deviceSettings");o("gem.willTerminate",[{n:"reason",k:"e",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"i",lo:0,hi:6e4}],10);o("gem.roomEvent",[{n:"event",k:"e",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"s",max:64},{n:"matchId",k:"s",o:1,max:64},{n:"version",k:"i",o:1,lo:0,hi:2147483647},{n:"reason",k:"s",o:1,max:64},{n:"platform",k:"e",o:1,v:["universal","mobile"]}],120,"rooms");o("gem.socketState",[{n:"connected",k:"b"},{n:"reason",k:"e",o:1,v:["connecting","dropped","watchdog","terminal"]}],12,"socketState");o("gem.seatedEvent",[{n:"roomId",k:"s",max:64}],60,"partySeating");o("gem.autoStartFailedEvent",[{n:"roomId",k:"s",max:64},{n:"code",k:"s",max:64}],30,"autoStartFailure");o("gem.ticketEvent",[{n:"event",k:"e",v:["queued","matched","expired","cancelled","failed"]},{n:"ticketId",k:"s",max:64},{n:"partySize",k:"i",o:1,lo:1,hi:64},{n:"queuedAt",k:"i",o:1,lo:0,hi:4102444800},{n:"expiresAt",k:"i",o:1,lo:0,hi:4102444800},{n:"reason",k:"s",o:1,max:64},{n:"roomId",k:"s",o:1,max:64}],60,"ticketEvents");o("gem.signalEvent",[{n:"event",k:"e",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}],1800,"p2p");o("gem.dedicatedEvent",[{n:"event",k:"e",v:["answer","error","matchEnded"]},{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",o:1,max:10240},{n:"sessionId",k:"s",o:1,max:64},{n:"code",k:"s",o:1,max:64},{n:"message",k:"s",o:1,max:256},{n:"reason",k:"s",o:1,max:64}],120,"dedicated");o("gem.partyResult",[{n:"requestId",k:"s",max:64},{n:"partyId",k:"s",o:1,max:64}],30,"parties");o("gem.clusterTarget",[{n:"clusterTargetId",k:"s",max:64},{n:"clusterTargetIds",k:"a",o:1,max:3,it:{n:"",k:"s",max:64}}],12,"clusterTarget");o("gem.devtools",[{n:"action",k:"e",v:["open","close","toggle"]}],30,"devtools");o("gem.screenshot",[{n:"maxWidth",k:"i",lo:1,hi:7680},{n:"maxHeight",k:"i",lo:1,hi:4320}],6,"screenshot");o("gem.screenshot.denied",[{n:"reason",k:"e",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"b"}],12,"screenshot");o("gem.requestContext",[],12,"feedbackContext");o("gem.gameContext",[{n:"context",k:"j"}],12,"feedbackContext");o("gem.signal",[{n:"signal",k:"e",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"s",max:64},{n:"data",k:"j"}],1200,"p2p");o("gem.dedicatedOffer",[{n:"matchId",k:"s",max:64},{n:"sdp",k:"s",max:10240},{n:"intent",k:"e",v:["initial","ice_restart","full_reconnect"]}],60,"dedicated");o("gem.partyRequest",[{n:"requestId",k:"s",max:64}],12,"parties");o("gem.ready",[],5);o("gem.engaged",[],5,"engagement");o("gem.progress",[{n:"loaded",k:"i",lo:0,hi:1099511627776},{n:"total",k:"i",lo:0,hi:1099511627776}],600);o("gem.requestToken",[{n:"requestId",k:"s",max:64},{n:"reason",k:"e",v:["initial","expiring","rejected"]}],12);o("gem.requestLocalServer",[{n:"requestId",k:"s",max:64},{n:"gameRoomId",k:"s",max:64}],6,"localHost");o("gem.localServer",[{n:"requestId",k:"s",max:64},{n:"serverId",k:"s",o:1,max:128}],30,"localHost");o("gem.localServer.denied",[{n:"requestId",k:"s",max:64},{n:"retryable",k:"b"},{n:"reason",k:"e",v:["refused","unavailable"]}],30,"localHost");o("gem.exit",[{n:"reason",k:"s",o:1,max:64}],5);o("gem.openExternal",[{n:"url",k:"s",max:2048,f:"url"}],6);o("gem.requestFullscreen",[{n:"enabled",k:"b"}],30);o("gem.audioState",[{n:"muted",k:"b"}],120,"audioState");o("gem.rewardCue",[{n:"currencySlug",k:"s",max:32},{n:"expected",k:"i",o:1,lo:1,hi:1e9},{n:"origin",k:"o",o:1,fs:[{n:"x",k:"i",lo:0,hi:16384},{n:"y",k:"i",lo:0,hi:16384}]}],60,"rewardCue");o("gem.walletDisplay",[{n:"visible",k:"b"},{n:"currencies",k:"a",o:1,max:8,it:{n:"",k:"s",max:64}},{n:"score",k:"b",o:1}],60,"walletDisplay");o("gem.controlsDeclare",[{n:"uses",k:"o",fs:[{n:"lookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"gamepadLookSensitivity",k:"s",o:1,max:16,f:"code"},{n:"invertLookY",k:"s",o:1,max:16,f:"code"},{n:"touchMovement",k:"s",o:1,max:16,f:"code"}]}],60,"controls");o("gem.menu",[{n:"settings",k:"b"},{n:"items",k:"a",o:1,max:4,it:{n:"",k:"o",fs:[{n:"id",k:"s",max:32},{n:"label",k:"s",max:40}]}}],60,"gameMenu");o("gem.menuSelect",[{n:"entry",k:"e",v:["settings","item"]},{n:"id",k:"s",o:1,max:32}],60,"gameMenu");o("gem.gemCorner",[{n:"corner",k:"e",v:["top-left","top-right","bottom-left","bottom-right"]}],12,"gemCorner");o("gem.requestShare",[{n:"params",k:"a",max:16,it:{n:"",k:"o",fs:[{n:"key",k:"s",max:64},{n:"value",k:"s",max:512}]}}],6,"share");o("gem.requestAvatarPicker",[{n:"tab",k:"e",o:1,v:["2d","3d"]}],6,"avatarPicker");o("gem.vibrate",[{n:"pattern",k:"a",max:99,it:{n:"",k:"i",lo:0,hi:1e4}}],600,"vibration");o("gem.frameStats",[{n:"fps",k:"i",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"i",lo:0,hi:1e5},{n:"counts",k:"e",o:1,v:["pageFrames","gameDraws"]}],120,"frameStats");o("gem.portraitBorders",[{n:"name",k:"s",o:1,max:40}],60,"portraitBorders");o("gem.error",[{n:"code",k:"e",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"s",o:1,max:256}],60);o("gem.requestPurchase",[{n:"requestId",k:"s",max:64},{n:"purchaseKind",k:"e",v:["item","recipe"]},{n:"targetId",k:"s",max:64},{n:"currencySlug",k:"s",max:32},{n:"quantity",k:"i",o:1,lo:1,hi:10},{n:"catalogId",k:"s",o:1,max:64}],12,"purchases");o("gem.requestAvatar3dPurchase",[{n:"requestId",k:"s",max:64},{n:"itemId",k:"s",max:64},{n:"currencySlug",k:"s",max:32}],12,"avatar3dPurchases");o("gem.purchaseResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["ok","declined","unavailable"]},{n:"reason",k:"s",o:1,max:64,f:"code"},{n:"purchaseId",k:"s",o:1,max:64}],30,"purchases");o("gem.deviceSettings.put",[{n:"requestId",k:"s",max:64},{n:"settings",k:"j"}],30,"deviceSettings");o("gem.deviceSettings.result",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["stored","too_large","unavailable"]}],30,"deviceSettings");o("gem.requestAd",[{n:"requestId",k:"s",max:64},{n:"placement",k:"s",max:32},{n:"format",k:"e",v:["interstitial","rewarded"]}],6,"ads");o("gem.adResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["shown","no_ad","unavailable"]}],12,"ads");o("gem.signalMoment",[{n:"requestId",k:"s",max:64},{n:"kind",k:"e",v:["level_end","run_end","match_end","menu_return","other_break"]},{n:"placement",k:"s",o:1,max:32}],6,"moments");o("gem.momentResult",[{n:"requestId",k:"s",max:64},{n:"shown",k:"b"}],12,"moments");o("gem.requestSignIn",[{n:"requestId",k:"s",max:64}],6,"signIn");o("gem.signInResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["signed_in","declined","unavailable"]}],12,"signIn");o("gem.requestFriendChallenge",[{n:"requestId",k:"s",max:64},{n:"playerId",k:"s",max:64},{n:"template",k:"s",max:64},{n:"params",k:"j",o:1}],12,"friendChallenges");o("gem.friendChallengeResult",[{n:"requestId",k:"s",max:64},{n:"outcome",k:"e",v:["accepted","cancelled","refused","unavailable","rate_limited","invalid"]},{n:"code",k:"s",o:1,max:64},{n:"param",k:"s",o:1,max:64},{n:"channel",k:"s",o:1,max:16},{n:"configVersion",k:"i",o:1,lo:0,hi:9007199254740991},{n:"retryAfterMs",k:"i",o:1,lo:0,hi:864e5},{n:"detail",k:"s",o:1,max:300}],30,"friendChallenges");var S=Object.freeze(N);v.__malformed=60;Object.freeze(v);Object.freeze(q);var me=/^[a-z0-9][a-z0-9_-]{0,39}$/;function ce(t){return typeof t=="string"&&me.test(t)}function V(t){if(t===null||ce(t))return t;let e=typeof t=="string"?JSON.stringify(t.length>48?`${t.slice(0,48)}\u2026`:t):`a value of type ${typeof t}`;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.`);}var L={now:()=>Date.now(),setTimeout:(t,e)=>setTimeout(t,e),clearTimeout:t=>clearTimeout(t)},x=class{constructor(e=L){this.clock=e;}clock;tokens=new Map;lastRefill=new Map;allow(e){let n=v[e];if(n===void 0)return false;let r=this.clock.now(),s=this.lastRefill.get(e)??r,i=this.tokens.get(e)??n,d=Math.max(0,r-s),a=Math.min(n,i+d*n/6e4);return a<1?(this.tokens.set(e,a),this.lastRefill.set(e,r),false):(this.tokens.set(e,a-1),this.lastRefill.set(e,r),true)}};function A(t,e){return t.toLowerCase()===e.toLowerCase()}function G(t){let e=t.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}function z(t,e){if(typeof e!="string"||e==="")return false;let n,r;try{n=new URL(t),r=new URL(e);}catch{return false}return n.protocol!=="http:"&&n.protocol!=="https:"||r.protocol!=="http:"&&r.protocol!=="https:"||n.username!==""||n.password!==""||n.pathname!=="/"||n.search!==""||n.hash!==""||n.port===""?false:G(n.hostname)&&G(r.hostname)}function Y(t,e){if(t.min>t.max||e.min>e.max)return null;let n=Math.min(t.max,e.max),r=Math.max(t.min,e.min);return n>=r?n:null}var Q="[gem: use gem.text.toPlain()]",K=new Set,J;function ue(t){try{if(K.has(t))return;let e=globalThis.location;if(J??=!!e?.port&&G(e.hostname??""),!J)return;K.add(t),console.warn(`[gem] ${t} is PlayerText, turned into a string: players see ${Q}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
|
|
2
2
|
${new Error().stack}`);}catch{}}var M=class{#e;#n;constructor(e,n="player text"){this.#e=e,this.#n=n,Object.freeze(this);}toString(){return ue(this.#n),Q}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function _(t,e){return new M(t,e)}function X(t){return Math.min(16384,Math.max(0,Math.round(Number.isFinite(t)?t:0)))}function ge(t,e){if(t!==true)return {visible:false};let n=[],r=false;for(let s of Array.isArray(e)?e:[])s==="score"?r=true:typeof s=="string"&&s.length>0&&s.length<=64&&!n.includes(s)&&n.push(s);return !r&&n.length===0?{visible:true}:{visible:true,currencies:n.slice(0,8),score:r}}function pe(t){let e=[];for(let n of Array.isArray(t)?t:[]){if(e.length===4)break;if(typeof n!="object"||n===null)continue;let{id:r,label:s}=n;typeof r!="string"||r.length===0||r.length>32||typeof s!="string"||s.trim().length===0||e.some(i=>i.id===r)||e.push({id:r,label:s.trim().slice(0,40)});}return e.length===0?{settings:false}:{settings:false,items:e}}function Z(t,e){return Math.min(e,Math.max(0,Math.round(Number.isFinite(t)?t:0)))}function ye(t){let e=t.untrusted,n=_(e.displayName,"gem.player.displayName"),r=e.displayTag||e.displayHandle,s=r?_(r,"gem.player.displayTag"):void 0,i=t.discriminator||t.displayTag,d=i&&/^[0-9]{1,8}$/.test(i)?i:void 0,a=t.avatarIconUrl||t.avatarUrl,m=/^[\da-f]{8}(-[\da-f]{4}){3}-[\da-f]{12}$/i,g=t.avatarIconId,p=t.avatar3dId,c={displayName:n,displayHandle:s??n,badges:(t.badges??[]).map(u=>({itemId:u.itemId,iconUrl:u.iconUrl}))};t.playerId&&(c.playerId=t.playerId),d&&(c.discriminator=d),s&&(c.displayTag=s),a&&(c.avatarIconUrl=c.avatarUrl=a),g&&m.test(g)&&(c.avatarIconId=g),p&&m.test(p)&&(c.avatar3dId=p),t.avatar3dModelUrl&&(c.avatar3dModelUrl=t.avatar3dModelUrl),t.avatar3dIconUrl&&(c.avatar3dIconUrl=t.avatar3dIconUrl),t.avatars3d&&(c.avatars3d=t.avatars3d.filter(u=>m.test(u.id)&&/^[a-z][a-z0-9_]*$/.test(u.family)).filter((u,C,P)=>P.findIndex(T=>T.family==u.family)==C).map(({family:u,id:C,modelUrl:P,iconUrl:T})=>({family:u,id:C,modelUrl:P,iconUrl:T})));let y=t.boost,f=(y?.multipliers??[]).map(u=>({currencyId:u.currencyId,currencySlug:u.currencySlug,multiplier:u.multiplierBp/1e4})),O=f.some(u=>u.multiplier>1);return c.boost=O&&y?.expiresInDays?{active:O,multipliers:f,expiresInDays:y.expiresInDays}:{active:O,multipliers:f},c}var fe=1e4,b=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??L,this.inbound=new x(this.clock),this.outbound=new x(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(a=>A(a,e.origin))||z(e.origin,this.options.selfOrigin)))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=S["gem.handshake"]?.(e.data);if(r)return this.refuse(e,`malformed handshake: ${r}`),false;let s=e.data;if(!A(s.embedder,e.origin))return this.refuse(e,`handshake claims embedder '${s.embedder}' but arrived from '${e.origin}'`),false;let i=e.ports?.[0];if(!i)return this.refuse(e,"handshake transferred no MessagePort"),false;let d=Y(k,s.versions);return d===null?(i.onmessage=null,i.postMessage({gem:l,type:"gem.error",code:"version_mismatch",message:`frame supports v${k.min}..v${k.max}`}),i.close(),this.transition("refused"),this.options.onError?.("version_mismatch"),false):(this.port=i,this.version=d,i.onmessage=a=>this.receive(a.data,a.ports??[]),i.start?.(),this.peerCapabilities=s.capabilities??[],this.unbidden=s.unbidden===true,i.postMessage({gem:l,type:"gem.handshake.accept",v:d,...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=fe){return this.state!=="waiting"?Promise.resolve(this.state):new Promise(n=>{let r=i=>{this.clock.clearTimeout(s),n(i);},s=this.clock.setTimeout(()=>{let i=this.settleWaiters.indexOf(r);i>=0&&this.settleWaiters.splice(i,1),n(this.state);},e);this.settleWaiters.push(r);})}progress(e,n){this.send({gem:l,type:"gem.progress",loaded:e,total:n});}requestToken(e,n){this.send({gem:l,type:"gem.requestToken",requestId:e,reason:n});}requestLocalServer(e,n){return this.parentSupports("localHost")?(this.send({gem:l,type:"gem.requestLocalServer",requestId:e,gameRoomId:n}),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 n={gem:l,type:"gem.rewardCue",currencySlug:String(e.currencySlug).slice(0,32)};return e.expected!==void 0&&Number.isFinite(e.expected)&&e.expected>=1&&(n.expected=Math.min(1e9,Math.round(e.expected))),e.origin&&(n.origin={x:X(e.origin.x),y:X(e.origin.y)}),this.send(n),true}showPortraitBorders(e){let n=V(e);return n===void 0||!this.gated("portraitBorders")?false:this.send(n===null?{gem:l,type:"gem.portraitBorders"}:{gem:l,type:"gem.portraitBorders",name:n})}setWalletVisible(e,n){return this.gated("walletDisplay")?this.send({gem:l,type:"gem.walletDisplay",...ge(e,n?.only)}):false}setMenu(e){return this.gated("gameMenu")?this.send({gem:l,type:"gem.menu",...pe(e)}):false}setGemCorner(e){return this.gated("gemCorner")?this.send({gem:l,type:"gem.gemCorner",corner:e}):false}requestShare(e){return this.gated("share")?this.send({gem:l,type:"gem.requestShare",params:e.map(({key:n,value:r})=>({key:n,value:r}))}):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:Z(e.fps,1e3),frameTimeP95Ms:Z(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,n,r){this.send({gem:l,type:"gem.signal",signal:e,matchId:n,data:r});}dedicatedOffer(e,n,r){this.send({gem:l,type:"gem.dedicatedOffer",matchId:e,sdp:n,intent:r});}requestParty(e){return this.send({gem:l,type:"gem.partyRequest",requestId:e})}requestPurchase(e,n,r,s,i,d){return this.send({gem:l,type:"gem.requestPurchase",requestId:e,purchaseKind:n,targetId:r,currencySlug:s,...i===void 0?{}:{quantity:i},...d===void 0?{}:{catalogId:d}})}requestAvatar3dPurchase(e,n,r){return this.parentSupports("avatar3dPurchases")?this.send({gem:l,type:"gem.requestAvatar3dPurchase",requestId:e,itemId:n,currencySlug:r}):false}putDeviceSettings(e,n){return this.send({gem:l,type:"gem.deviceSettings.put",requestId:e,settings:n})}requestAd(e,n,r){return this.send({gem:l,type:"gem.requestAd",requestId:e,placement:n,format:r})}signalMoment(e,n,r){return this.send({gem:l,type:"gem.signalMoment",requestId:e,kind:n,...r===void 0?{}:{placement:r}})}readyCalled(){return this.readySent||this.readyPending}requestSignIn(e){return this.send({gem:l,type:"gem.requestSignIn",requestId:e})}requestFriendChallenge(e,n,r,s){return this.send({gem:l,type:"gem.requestFriendChallenge",requestId:e,playerId:n,template:r,...s===void 0?{}:{params:s}})}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 n of this.settleWaiters.splice(0))n(e);this.options.onStateChange?.(e);}}refuseMalformed(e,n){if(!this.inbound.allow(R)){this.options.onDropped?.(e,n);return}this.fail(e,n);}dropUnknownType(e){this.inbound.allow(R)&&this.options.onDropped?.("unsupported",`ignored unknown message type '${e}'`);}refuse(e,n){e.ports?.[0]?.close?.(),this.inbound.allow(R)&&this.options.onRefused?.(n);}fail(e,n){this.options.onError?.(e,n),this.state==="connected"&&this.port&&this.send({gem:l,type:"gem.error",code:e,...n===void 0?{}:{message:n}});}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 n=e.type;if(!this.outbound.allow(n))return this.options.onError?.("rate_limited",`frame exceeded its own limit for ${n}`),false;let r=S[n]?.(e);return r?(this.options.onError?.("internal",`refusing to send malformed ${n}: ${r}`),false):(this.port.postMessage(this.version===null?e:{...e,v:this.version}),true)}receive(e,n=[]){let r=false;try{r=this.dispatchInbound(e,n);}finally{r||ee(n);}}dispatchInbound(e,n){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 s=S[r];if(!s)return this.dropUnknownType(r),false;if(!this.inbound.allow(r))return this.fail("rate_limited",`parent exceeded the limit for ${r}`),false;let i=H(r);if(i!==void 0&&!this.options.capabilities?.includes(i))return this.fail("unsupported_capability",`${r} requires the '${i}' capability, which this frame did not advertise`),false;let d=s(e);if(d)return this.fail("invalid_message",`${r}: ${d}`),false;let a=e;if(a.v!==this.version)return this.fail("invalid_message",`${r}: expected v ${String(this.version)}`),false;switch(r){case "gem.token":this.options.onToken?.(a);break;case "gem.pause":this.options.onPause?.(a);break;case "gem.menuSelect":this.options.onMenuSelect?.(a);break;case "gem.prefs":this.options.onPrefs?.(a);break;case "gem.cohorts":this.options.onCohorts?.(a);break;case "gem.earnAllowanceChanged":this.options.onEarnAllowanceChanged?.();break;case "gem.viewport":this.options.onViewport?.(a);break;case "gem.willTerminate":this.options.onWillTerminate?.(a);break;case "gem.devtools":this.options.onDevtools?.(a.action);break;case "gem.requestContext":this.options.onRequestContext?.();break;case "gem.screenshot":{let m=n[0];if(!m){this.options.onError?.("invalid_message","gem.screenshot transferred no MessagePort");break}let g={maxWidth:a.maxWidth,maxHeight:a.maxHeight};if(!this.options.onScreenshot){m.close(),this.screenshotDenied("not_wired",false);break}return ee(n.slice(1)),this.options.onScreenshot(g,m,(p,c)=>this.screenshotDenied(p,c)),true}case "gem.token.denied":this.options.onTokenDenied?.(a);break;case "gem.localServer":this.options.onLocalServer?.(a);break;case "gem.localServer.denied":this.options.onLocalServerDenied?.(a);break;case "gem.player":{this.options.onPlayer?.(ye(a));break}case "gem.roomEvent":this.options.onRoomEvent?.(a);break;case "gem.seatedEvent":this.options.onSeatedEvent?.(a);break;case "gem.autoStartFailedEvent":this.options.onAutoStartFailedEvent?.(a);break;case "gem.ticketEvent":this.options.onTicketEvent?.(a);break;case "gem.socketState":this.options.onSocketState?.(a);break;case "gem.signalEvent":this.options.onSignalEvent?.(a);break;case "gem.dedicatedEvent":this.options.onDedicatedEvent?.(a);break;case "gem.clusterTarget":this.options.onClusterTarget?.(a);break;case "gem.partyResult":this.options.onPartyResult?.(a);break;case "gem.purchaseResult":this.options.onPurchaseResult?.(a);break;case "gem.deviceSettings":this.options.onDeviceSettings?.(a);break;case "gem.deviceSettings.result":this.options.onDeviceSettingsResult?.(a);break;case "gem.adResult":this.options.onAdResult?.(a);break;case "gem.momentResult":this.options.onMomentResult?.(a);break;case "gem.signInResult":this.options.onSignInResult?.(a);break;case "gem.friendChallengeResult":this.options.onFriendChallengeResult?.(a);break;case "gem.error":this.options.onError?.(a.code,a.message);break;default:this.fail("unsupported",`no frame handler for '${r}'`);}return false}screenshotDenied(e,n){this.send({gem:l,type:"gem.screenshot.denied",reason:e,retryable:n});}};function ee(t){for(let e of t)try{e?.close?.();}catch{}}D();function he(t){if((t.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 b({...t,expectedSource:t.expectedSource??window.parent}),n=r=>{let s=e.handleWindowMessage({data:r.data,origin:r.origin,source:r.source,ports:r.ports});return s&&window.removeEventListener("message",n),s};return window.addEventListener("message",n),F(window,n),e}var ne={connect:he,GemFrame:b,PROTOCOL:l,SUPPORTED_VERSIONS:k};window.GemWebSdkBridge=ne;var Nn=ne;return Nn;})();
|