@indiegems/gem-web-sdk 7.5.0 → 7.7.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 +886 -0
- package/README.md +1 -0
- package/dist/function.d.ts +994 -0
- package/dist/game.d.ts +26 -5
- package/dist/gem-web-sdk.bridge.js +1 -1
- package/dist/gem-web-sdk.esm.js +1 -1
- package/dist/gem-web-sdk.function.js +3 -0
- package/dist/gem-web-sdk.game.js +2 -2
- package/dist/gem-web-sdk.min.js +2 -2
- package/dist/gem-web-sdk.sdk.js +2 -2
- package/dist/gem-web-sdk.server-api.js +1 -1
- package/dist/gem-web-sdk.server.js +2 -2
- package/dist/sdk.d.ts +62 -11
- package/dist/server-api.d.ts +33 -6
- package/dist/server.d.ts +36 -6
- package/docs/analytics.md +2 -3
- package/docs/api/api-reference-game.md +392 -41
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +377 -20
- package/docs/changelog.md +886 -0
- package/docs/daily-challenges.md +14 -2
- package/docs/getting-started.md +8 -6
- package/docs/leaderboards.md +140 -0
- package/docs/manifest.json +24 -14
- package/docs/server-bundles.md +2 -2
- package/docs/serverless-functions-js.md +139 -0
- package/docs/serverless-functions.md +35 -5
- package/docs/what-a-game-must-do.md +39 -26
- package/package.json +7 -2
- package/schema/bridge.v1.json +1 -1
package/dist/game.d.ts
CHANGED
|
@@ -223,7 +223,7 @@ type OrderBySpec = {
|
|
|
223
223
|
"column": RunValueColumn;
|
|
224
224
|
"direction": SortDirection;
|
|
225
225
|
};
|
|
226
|
-
type OrderSource = "real_money_purchase" | "real_money_refund" | "full_game_purchase" | "full_game_refund" | "platform_purchase" | "reward" | "admin" | "system" | "promo" | "game_consume" | "play" | "recipe" | "transfer" | "platform_funded_game_inventory_purchase";
|
|
226
|
+
type OrderSource = "real_money_purchase" | "real_money_refund" | "full_game_purchase" | "full_game_refund" | "platform_purchase" | "reward" | "admin" | "system" | "promo" | "game_consume" | "play" | "recipe" | "transfer" | "platform_funded_game_inventory_purchase" | "earning_reset";
|
|
227
227
|
type OverflowBehavior = "fail" | "clamp" | "allow";
|
|
228
228
|
type PityEffect = "guarantee_tier" | {
|
|
229
229
|
"weight_boost": {
|
|
@@ -482,6 +482,7 @@ type SnapshotLeaderboard = {
|
|
|
482
482
|
"id": string;
|
|
483
483
|
"max_size": number;
|
|
484
484
|
"order_by": OrderBySpec[];
|
|
485
|
+
"per_period"?: boolean;
|
|
485
486
|
"run_type": string;
|
|
486
487
|
"update_frequency_seconds": number;
|
|
487
488
|
};
|
|
@@ -547,7 +548,7 @@ type SnapshotRewardedPlacement = {
|
|
|
547
548
|
"cooldown_seconds": number;
|
|
548
549
|
"grants": SnapshotRewardGrant[];
|
|
549
550
|
"max_held"?: number | null;
|
|
550
|
-
"max_per_day"
|
|
551
|
+
"max_per_day"?: number | null;
|
|
551
552
|
"placement": string;
|
|
552
553
|
"reward_class": string;
|
|
553
554
|
"without_ads": string;
|
|
@@ -557,6 +558,7 @@ type SnapshotRunType = {
|
|
|
557
558
|
"bucket_1_name"?: string | null;
|
|
558
559
|
"bucket_2_allowed_values"?: string[] | null;
|
|
559
560
|
"bucket_2_name"?: string | null;
|
|
561
|
+
"challenge"?: string | null;
|
|
560
562
|
"float_value_1_name"?: string | null;
|
|
561
563
|
"float_value_2_name"?: string | null;
|
|
562
564
|
"id": string;
|
|
@@ -1136,6 +1138,15 @@ interface PlayerIdentity {
|
|
|
1136
1138
|
}
|
|
1137
1139
|
declare function mapIdentity(row: unknown): PlayerIdentity;
|
|
1138
1140
|
declare function platformIconUrl(url: string | undefined): string | undefined;
|
|
1141
|
+
interface LeaderboardPeriod {
|
|
1142
|
+
readonly id: string;
|
|
1143
|
+
readonly localDate?: string;
|
|
1144
|
+
readonly startAt?: number;
|
|
1145
|
+
readonly endsAt?: number;
|
|
1146
|
+
readonly opensAt: number;
|
|
1147
|
+
readonly closesAt: number;
|
|
1148
|
+
readonly final: boolean;
|
|
1149
|
+
}
|
|
1139
1150
|
interface LeaderboardEntry extends RankedRow, PlayerIdentity {
|
|
1140
1151
|
readonly rank: number;
|
|
1141
1152
|
readonly occurredAt: number;
|
|
@@ -1153,6 +1164,7 @@ interface Leaderboard {
|
|
|
1153
1164
|
readonly entries: readonly LeaderboardEntry[];
|
|
1154
1165
|
readonly generatedAt: number;
|
|
1155
1166
|
readonly updateFrequencySeconds?: number;
|
|
1167
|
+
readonly period?: LeaderboardPeriod;
|
|
1156
1168
|
}
|
|
1157
1169
|
interface RankedRow {
|
|
1158
1170
|
readonly rank: number;
|
|
@@ -1176,14 +1188,20 @@ interface EntityLeaderboard {
|
|
|
1176
1188
|
readonly totalRuns: number;
|
|
1177
1189
|
readonly totalRunsExact: boolean;
|
|
1178
1190
|
readonly generatedAt: number;
|
|
1191
|
+
readonly period?: LeaderboardPeriod;
|
|
1192
|
+
}
|
|
1193
|
+
interface PeriodOptions {
|
|
1194
|
+
readonly periodsBack?: number;
|
|
1195
|
+
readonly period?: string;
|
|
1196
|
+
readonly playerId?: string;
|
|
1179
1197
|
}
|
|
1180
|
-
interface EntityLeaderboardOptions {
|
|
1198
|
+
interface EntityLeaderboardOptions extends PeriodOptions {
|
|
1181
1199
|
readonly bucket1?: string;
|
|
1182
1200
|
readonly bucket2?: string;
|
|
1183
1201
|
readonly limit?: number;
|
|
1184
1202
|
readonly signal?: AbortSignal;
|
|
1185
1203
|
}
|
|
1186
|
-
interface GetLeaderboardOptions {
|
|
1204
|
+
interface GetLeaderboardOptions extends PeriodOptions {
|
|
1187
1205
|
readonly bucket1?: string;
|
|
1188
1206
|
readonly bucket2?: string;
|
|
1189
1207
|
readonly signal?: AbortSignal;
|
|
@@ -2726,6 +2744,9 @@ interface DeviceSettingsApi {
|
|
|
2726
2744
|
wait(timeoutMs?: number): Promise<DeviceSettings | null>;
|
|
2727
2745
|
put(settings: DeviceSettings): Promise<DeviceSettingsPutOutcome>;
|
|
2728
2746
|
}
|
|
2747
|
+
declare class GemUnframedError extends Error {
|
|
2748
|
+
constructor();
|
|
2749
|
+
}
|
|
2729
2750
|
declare const DEVICE_SETTINGS_MAX_BYTES = 16384;
|
|
2730
2751
|
declare const ARCADE_EMBEDDERS: readonly string[];
|
|
2731
2752
|
interface GemOptions {
|
|
@@ -2862,4 +2883,4 @@ interface ExitAnalytics {
|
|
|
2862
2883
|
}
|
|
2863
2884
|
declare function leaveAndExit(rooms: ExitRooms, bridge: ExitBridge | null, reason?: string, analytics?: ExitAnalytics): Promise<void>;
|
|
2864
2885
|
declare function createGem(options?: GemOptions): Gem;
|
|
2865
|
-
export { ARCADE_EMBEDDERS, 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 BootMark, type BootTimeline, type Challenge, type ChallengeWindow, ChallengesApi, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, 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, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, FriendsApi, type FriendsPage, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, FunctionsApi, type GameConfig, type GameServerLink, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemDevTools, GemFrame, GemFunctionError, type GemIdentity, type GemInsets, type GemMatchApi, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, type GemReservedArea, GemSaveError, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerLifecycle, type GemTerminationNotice, type GemViewport, type GetLeaderboardOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, LeaderboardsApi, type ListChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchServeOptions, type MatchTransport, type MessageMeta, type MultiTransportSession, PLATFORM_EVENTS, 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 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 WalletVisibleOptions, asPlayerText, createBootTimeline, createGem, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, text, webTransportAvailable };
|
|
2886
|
+
export { ARCADE_EMBEDDERS, 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 BootMark, type BootTimeline, type Challenge, type ChallengeWindow, ChallengesApi, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, 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, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, FriendsApi, type FriendsPage, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, FunctionsApi, type GameConfig, type GameServerLink, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemDevTools, GemFrame, GemFunctionError, type GemIdentity, type GemInsets, type GemMatchApi, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, 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 ListFriendsOptions, MAX_PERIODS_BACK, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchServeOptions, type MatchTransport, type MessageMeta, type MultiTransportSession, PLATFORM_EVENTS, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayerBadge, 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 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 WalletVisibleOptions, asPlayerText, createBootTimeline, createGem, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, text, webTransportAvailable };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var GemWebSdkBridgeBundle=(function(){'use strict';var w="GemWebSdkHandshake";function B(){return typeof document>"u"?void 0:document.readyState}var P=()=>Date.now();function I(t={}){let e=t.win??window,n=e,r=n[w];if(r!==void 0)return r;let s=t.readyState??B,i=t.now??P,l=[],o=[],m=c=>{let p=c.data;!p||p.type!=="gem.handshake"||(l.length>=4&&(l.shift(),o.shift(),u.dropped+=1),l.push(c),o.push(i()));};e.addEventListener("message",m);let u={events:l,times:o,dropped:0,late:s()==="complete",uninstall(){e.removeEventListener("message",m);}};return n[w]=u,u}function q(t,e,n={}){let r=t[w];if(r===void 0)return null;let s=n.ttlMs??9500,i=n.now??P,l=r.events.splice(0),o=r.times?.splice(0),m=0,u=0,c=false,p=i()-s;for(let g=l.length-1;g>=0;g--){let E=o?.[g];if(E!==void 0&&E<p){u+=1;continue}if(m+=1,e(l[g])===true){c=true;break}}return r.uninstall(),{capture:r,delivered:m,stale:u,accepted:c}}var d="gem-web-bridge",f={min:1,max:1},y=65536,L=8,v=5e3,A=1024;function S(t){return Object.freeze(Object.assign(Object.create(null),t))}var j=S({"gem.handshake":30,"gem.handshake.accept":5,"gem.token":30,"gem.token.denied":30,"gem.player":12,"gem.pause":120,"gem.prefs":60,"gem.cohorts":12,"gem.earnAllowanceChanged":30,"gem.viewport":60,"gem.deviceSettings":12,"gem.willTerminate":10,"gem.roomEvent":120,"gem.socketState":12,"gem.seatedEvent":60,"gem.autoStartFailedEvent":30,"gem.signalEvent":1800,"gem.dedicatedEvent":120,"gem.partyResult":30,"gem.clusterTarget":12,"gem.devtools":30,"gem.screenshot":6,"gem.screenshot.denied":12,"gem.requestContext":12,"gem.gameContext":12,"gem.signal":1200,"gem.dedicatedOffer":60,"gem.partyRequest":12,"gem.ready":5,"gem.engaged":5,"gem.progress":600,"gem.requestToken":12,"gem.requestLocalServer":6,"gem.localServer":30,"gem.localServer.denied":30,"gem.exit":5,"gem.openExternal":6,"gem.requestFullscreen":30,"gem.audioState":120,"gem.rewardCue":60,"gem.walletDisplay":60,"gem.requestShare":6,"gem.frameStats":120,"gem.error":60,"gem.requestPurchase":12,"gem.purchaseResult":30,"gem.deviceSettings.put":30,"gem.deviceSettings.result":30,"gem.requestAd":6,"gem.adResult":12,"gem.requestSignIn":6,"gem.signInResult":12,"gem.requestFriendChallenge":12,"gem.friendChallengeResult":30,__malformed:60}),x="__malformed";var z=S({"gem.requestAd":"ads","gem.adResult":"ads","gem.requestSignIn":"signIn","gem.signInResult":"signIn","gem.requestPurchase":"purchases","gem.purchaseResult":"purchases","gem.requestFriendChallenge":"friendChallenges","gem.friendChallengeResult":"friendChallenges","gem.devtools":"devtools","gem.screenshot":"screenshot","gem.screenshot.denied":"screenshot","gem.requestContext":"feedbackContext","gem.gameContext":"feedbackContext","gem.roomEvent":"rooms","gem.signal":"p2p","gem.signalEvent":"p2p","gem.dedicatedOffer":"dedicated","gem.dedicatedEvent":"dedicated","gem.clusterTarget":"clusterTarget","gem.partyRequest":"parties","gem.partyResult":"parties","gem.autoStartFailedEvent":"autoStartFailure","gem.seatedEvent":"partySeating","gem.socketState":"socketState","gem.audioState":"audioState","gem.rewardCue":"rewardCue","gem.frameStats":"frameStats","gem.engaged":"engagement","gem.viewport":"viewport","gem.walletDisplay":"walletDisplay","gem.requestLocalServer":"localHost","gem.localServer":"localHost","gem.localServer.denied":"localHost","gem.cohorts":"cohorts","gem.earnAllowanceChanged":"earnAllowance","gem.deviceSettings":"deviceSettings","gem.deviceSettings.put":"deviceSettings","gem.deviceSettings.result":"deviceSettings","gem.requestShare":"share"}),K=Object.freeze([["gem.asyncOpponents.","asyncOpponents"],["gem.viewport.","reservedAreas"]]);function _(t){let e=z[t];if(e!==void 0)return e;for(let[n,r]of K)if(t.startsWith(n))return r}function Y(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 X(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 J(t){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(t)}function Q(t){return /^[a-z_]+$/.test(t)}function R(t,e,n){if(e>L)return `nesting deeper than ${L}`;if(++n.nodes>v)return `more than ${v} values`;if(n.bytes>y)return `over the ${y} 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>A)return `an array of ${t.length} entries, over the ${A} limit`;n.bytes+=2;for(let o of t){let m=R(o,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 l=t;for(let o in l){if(!Object.prototype.hasOwnProperty.call(l,o))continue;if(++n.nodes>v)return `more than ${v} values`;if(n.bytes+=o.length*3+4,n.bytes>y)return `over the ${y} byte limit`;let m=R(l[o],e+1,n);if(m)return m}return null}function Z(t){let e={nodes:0,bytes:0,seen:new Set},n=R(t,0,e);return n?`message contains ${n}`:e.bytes>y?`message is over the ${y} byte limit`:null}var ee={origin:[Y,"not a well-formed origin"],url:[X,"not a safe absolute http(s) URL"],bcp47:[J,"not a well-formed BCP 47 tag"],code:[Q,"not a code of lower-case letters and underscores"]};function D(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 l=F(i,r,s);if(l)return l}return null}function F(t,e,n){switch(e.k){case "string":{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]=ee[e.f];if(!r(t))return `${n}: ${s}`}return null}case "int":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 "boolean":return typeof t=="boolean"?null:`${n}: expected boolean`;case "enum":{let r=e.v;return r.includes(t)?null:`${n}: not one of ${r.join("|")}`}case "object":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected object`:D(t,e.fs,n);case "json":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected a plain object`:null;case "array":{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 l=F(i,r,s);if(l)return l}return null}default:{let r=e.k;return `${n}: unknown kind ${String(r)}`}}}function a(t,e){return n=>{let r=Z(n);if(r)return r;if(typeof n!="object"||n===null||Array.isArray(n))return "message: expected object";let s=n;return s.gem!==d?"gem: wrong protocol marker":s.type!==t?`type: expected ${t}`:D(s,e,"")}}var ne=a("gem.handshake",[{n:"versions",k:"object",fs:[{n:"min",k:"int",lo:1,hi:1e3},{n:"max",k:"int",lo:1,hi:1e3}]},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}},{n:"embedder",k:"string",max:2048,f:"origin"},{n:"unbidden",k:"boolean",o:1}]),te=a("gem.handshake.accept",[{n:"v",k:"int",lo:1,hi:1e3},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}}]),re=a("gem.token",[{n:"token",k:"string",max:4096},{n:"requestId",k:"string",o:1,max:64},{n:"generation",k:"int",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"string",o:1,max:512,f:"url"},{n:"playerId",k:"string",max:64},{n:"gameId",k:"string",max:64},{n:"channel",k:"enum",v:["dev","test","release"]},{n:"gameVersion",k:"string",o:1,max:64},{n:"expiresAt",k:"int",lo:0,hi:4102444800},{n:"chainEndsAt",k:"int",lo:0,hi:4102444800},{n:"allowDevTools",k:"boolean",o:1}]),oe=a("gem.token.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"retryAfterMs",k:"int",o:1,lo:0,hi:36e5},{n:"reason",k:"enum",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"string",max:64}]),ae=a("gem.player",[{n:"untrusted",k:"object",fs:[{n:"displayName",k:"string",max:64},{n:"displayTag",k:"string",o:1,max:80},{n:"displayHandle",k:"string",max:80}]},{n:"playerId",k:"string",o:1,max:64},{n:"discriminator",k:"string",o:1,max:8},{n:"avatarIconUrl",k:"string",o:1,max:2048,f:"url"},{n:"badges",k:"array",o:1,max:2,it:{n:"",k:"object",fs:[{n:"itemId",k:"string",max:64},{n:"iconUrl",k:"string",max:2048,f:"url"}]}},{n:"displayTag",k:"string",max:8},{n:"avatarUrl",k:"string",o:1,max:2048,f:"url"},{n:"boost",k:"object",o:1,fs:[{n:"multipliers",k:"array",max:8,it:{n:"",k:"object",fs:[{n:"currencyId",k:"string",max:64},{n:"currencySlug",k:"string",max:32},{n:"multiplierBp",k:"int",lo:1e4,hi:1e6}]}},{n:"expiresInDays",k:"int",o:1,lo:1,hi:7}]}]),se=a("gem.pause",[{n:"paused",k:"boolean"}]),ie=a("gem.prefs",[{n:"reducedMotion",k:"boolean"},{n:"muted",k:"boolean"},{n:"showFrameStats",k:"boolean",o:1},{n:"locale",k:"string",max:35,f:"bcp47"}]),le=a("gem.cohorts",[{n:"cohorts",k:"array",max:8,it:{n:"",k:"object",fs:[{n:"experimentId",k:"string",max:36},{n:"variantKey",k:"string",max:32}]}}]),de=a("gem.earnAllowanceChanged",[]),me=a("gem.viewport",[{n:"insets",k:"object",fs:[{n:"top",k:"int",lo:0,hi:4096},{n:"right",k:"int",lo:0,hi:4096},{n:"bottom",k:"int",lo:0,hi:4096},{n:"left",k:"int",lo:0,hi:4096}]},{n:"reserved",k:"array",o:1,max:4,it:{n:"",k:"object",fs:[{n:"x",k:"int",lo:0,hi:16384},{n:"y",k:"int",lo:0,hi:16384},{n:"width",k:"int",lo:0,hi:16384},{n:"height",k:"int",lo:0,hi:16384}]}}]),ge=a("gem.deviceSettings",[{n:"settings",k:"json",o:1}]),ue=a("gem.willTerminate",[{n:"reason",k:"enum",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"int",lo:0,hi:6e4}]),ce=a("gem.roomEvent",[{n:"event",k:"enum",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"string",max:64},{n:"matchId",k:"string",o:1,max:64},{n:"version",k:"int",o:1,lo:0,hi:2147483647},{n:"reason",k:"string",o:1,max:64},{n:"platform",k:"enum",o:1,v:["universal","mobile"]}]),pe=a("gem.socketState",[{n:"connected",k:"boolean"},{n:"reason",k:"enum",o:1,v:["connecting","dropped","watchdog","terminal"]}]),ye=a("gem.seatedEvent",[{n:"roomId",k:"string",max:64}]),fe=a("gem.autoStartFailedEvent",[{n:"roomId",k:"string",max:64},{n:"code",k:"string",max:64}]),he=a("gem.signalEvent",[{n:"event",k:"enum",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),ke=a("gem.dedicatedEvent",[{n:"event",k:"enum",v:["answer","error","matchEnded"]},{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",o:1,max:10240},{n:"sessionId",k:"string",o:1,max:64},{n:"code",k:"string",o:1,max:64},{n:"message",k:"string",o:1,max:256},{n:"reason",k:"string",o:1,max:64}]),ve=a("gem.partyResult",[{n:"requestId",k:"string",max:64},{n:"partyId",k:"string",o:1,max:64}]),xe=a("gem.clusterTarget",[{n:"clusterTargetId",k:"string",max:64},{n:"clusterTargetIds",k:"array",o:1,max:3,it:{n:"",k:"string",max:64}}]),be=a("gem.devtools",[{n:"action",k:"enum",v:["open","close","toggle"]}]),we=a("gem.screenshot",[{n:"maxWidth",k:"int",lo:1,hi:7680},{n:"maxHeight",k:"int",lo:1,hi:4320}]),Re=a("gem.screenshot.denied",[{n:"reason",k:"enum",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"boolean"}]),Se=a("gem.requestContext",[]),Ge=a("gem.gameContext",[{n:"context",k:"json"}]),Oe=a("gem.signal",[{n:"signal",k:"enum",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),Ce=a("gem.dedicatedOffer",[{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",max:10240},{n:"intent",k:"enum",v:["initial","ice_restart","full_reconnect"]}]),Te=a("gem.partyRequest",[{n:"requestId",k:"string",max:64}]),Ee=a("gem.ready",[]),Pe=a("gem.engaged",[]),Ie=a("gem.progress",[{n:"loaded",k:"int",lo:0,hi:1099511627776},{n:"total",k:"int",lo:0,hi:1099511627776}]),qe=a("gem.requestToken",[{n:"requestId",k:"string",max:64},{n:"reason",k:"enum",v:["initial","expiring","rejected"]}]),Le=a("gem.requestLocalServer",[{n:"requestId",k:"string",max:64},{n:"gameRoomId",k:"string",max:64}]),Ae=a("gem.localServer",[{n:"requestId",k:"string",max:64},{n:"serverId",k:"string",o:1,max:128}]),je=a("gem.localServer.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"reason",k:"enum",v:["refused","unavailable"]}]),_e=a("gem.exit",[{n:"reason",k:"string",o:1,max:64}]),De=a("gem.openExternal",[{n:"url",k:"string",max:2048,f:"url"}]),Fe=a("gem.requestFullscreen",[{n:"enabled",k:"boolean"}]),Me=a("gem.audioState",[{n:"muted",k:"boolean"}]),$e=a("gem.rewardCue",[{n:"currencySlug",k:"string",max:32},{n:"expected",k:"int",o:1,lo:1,hi:1e9},{n:"origin",k:"object",o:1,fs:[{n:"x",k:"int",lo:0,hi:16384},{n:"y",k:"int",lo:0,hi:16384}]}]),He=a("gem.walletDisplay",[{n:"visible",k:"boolean"},{n:"currencies",k:"array",o:1,max:8,it:{n:"",k:"string",max:64}},{n:"score",k:"boolean",o:1}]),Ue=a("gem.requestShare",[{n:"params",k:"array",max:16,it:{n:"",k:"object",fs:[{n:"key",k:"string",max:64},{n:"value",k:"string",max:512}]}}]),We=a("gem.frameStats",[{n:"fps",k:"int",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"int",lo:0,hi:1e5}]),Ne=a("gem.error",[{n:"code",k:"enum",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"string",o:1,max:256}]),Ve=a("gem.requestPurchase",[{n:"requestId",k:"string",max:64},{n:"purchaseKind",k:"enum",v:["item","recipe"]},{n:"targetId",k:"string",max:64},{n:"currencySlug",k:"string",max:32},{n:"quantity",k:"int",o:1,lo:1,hi:10},{n:"catalogId",k:"string",o:1,max:64}]),Be=a("gem.purchaseResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["ok","declined","unavailable"]},{n:"reason",k:"string",o:1,max:64,f:"code"},{n:"purchaseId",k:"string",o:1,max:64}]),ze=a("gem.deviceSettings.put",[{n:"requestId",k:"string",max:64},{n:"settings",k:"json"}]),Ke=a("gem.deviceSettings.result",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["stored","too_large","unavailable"]}]),Ye=a("gem.requestAd",[{n:"requestId",k:"string",max:64},{n:"placement",k:"string",max:32},{n:"format",k:"enum",v:["interstitial","rewarded"]}]),Xe=a("gem.adResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["shown","no_ad","unavailable"]}]),Je=a("gem.requestSignIn",[{n:"requestId",k:"string",max:64}]),Qe=a("gem.signInResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["signed_in","declined","unavailable"]}]),Ze=a("gem.requestFriendChallenge",[{n:"requestId",k:"string",max:64},{n:"playerId",k:"string",max:64},{n:"template",k:"string",max:64},{n:"params",k:"json",o:1}]),en=a("gem.friendChallengeResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["accepted","cancelled","refused","unavailable","rate_limited","invalid"]},{n:"code",k:"string",o:1,max:64},{n:"param",k:"string",o:1,max:64},{n:"channel",k:"string",o:1,max:16},{n:"configVersion",k:"int",o:1,lo:0,hi:9007199254740991},{n:"retryAfterMs",k:"int",o:1,lo:0,hi:864e5},{n:"detail",k:"string",o:1,max:300}]),b=S({"gem.handshake":ne,"gem.handshake.accept":te,"gem.token":re,"gem.token.denied":oe,"gem.player":ae,"gem.pause":se,"gem.prefs":ie,"gem.cohorts":le,"gem.earnAllowanceChanged":de,"gem.viewport":me,"gem.deviceSettings":ge,"gem.willTerminate":ue,"gem.roomEvent":ce,"gem.socketState":pe,"gem.seatedEvent":ye,"gem.autoStartFailedEvent":fe,"gem.signalEvent":he,"gem.dedicatedEvent":ke,"gem.partyResult":ve,"gem.clusterTarget":xe,"gem.devtools":be,"gem.screenshot":we,"gem.screenshot.denied":Re,"gem.requestContext":Se,"gem.gameContext":Ge,"gem.signal":Oe,"gem.dedicatedOffer":Ce,"gem.partyRequest":Te,"gem.ready":Ee,"gem.engaged":Pe,"gem.progress":Ie,"gem.requestToken":qe,"gem.requestLocalServer":Le,"gem.localServer":Ae,"gem.localServer.denied":je,"gem.exit":_e,"gem.openExternal":De,"gem.requestFullscreen":Fe,"gem.audioState":Me,"gem.rewardCue":$e,"gem.walletDisplay":He,"gem.requestShare":Ue,"gem.frameStats":We,"gem.error":Ne,"gem.requestPurchase":Ve,"gem.purchaseResult":Be,"gem.deviceSettings.put":ze,"gem.deviceSettings.result":Ke,"gem.requestAd":Ye,"gem.adResult":Xe,"gem.requestSignIn":Je,"gem.signInResult":Qe,"gem.requestFriendChallenge":Ze,"gem.friendChallengeResult":en});var G=class{#e;constructor(e){this.#e=e,Object.freeze(this);}toString(){return "[gem: use gem.text.toPlain()]"}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function O(t){return new G(t)}var C={now:()=>Date.now(),setTimeout:(t,e)=>setTimeout(t,e),clearTimeout:t=>clearTimeout(t)},h=class{constructor(e=C){this.clock=e;}clock;tokens=new Map;lastRefill=new Map;allow(e){let n=j[e];if(n===void 0)return false;let r=this.clock.now(),s=this.lastRefill.get(e)??r,i=this.tokens.get(e)??n,l=Math.max(0,r-s),o=Math.min(n,i+l*n/6e4);return o<1?(this.tokens.set(e,o),this.lastRefill.set(e,r),false):(this.tokens.set(e,o-1),this.lastRefill.set(e,r),true)}};function T(t,e){return t.toLowerCase()===e.toLowerCase()}function M(t){let e=t.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}function $(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:M(n.hostname)&&M(r.hostname)}function H(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}function U(t){return Math.min(16384,Math.max(0,Math.round(Number.isFinite(t)?t:0)))}function nn(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 W(t,e){return Math.min(e,Math.max(0,Math.round(Number.isFinite(t)?t:0)))}function tn(t){let e=t.untrusted,n=O(e.displayName),r=e.displayTag||e.displayHandle,s=r?O(r):void 0,i=t.discriminator||t.displayTag,l=i&&/^[0-9]{1,8}$/.test(i)?i:void 0,o=t.avatarIconUrl||t.avatarUrl,m={displayName:n,displayHandle:s??n,badges:(t.badges??[]).map(g=>({itemId:g.itemId,iconUrl:g.iconUrl}))};t.playerId&&(m.playerId=t.playerId),l&&(m.discriminator=l),s&&(m.displayTag=s),o&&(m.avatarIconUrl=m.avatarUrl=o);let u=t.boost,c=(u?.multipliers??[]).map(g=>({currencyId:g.currencyId,currencySlug:g.currencySlug,multiplier:g.multiplierBp/1e4})),p=c.some(g=>g.multiplier>1);return m.boost=p&&u?.expiresInDays?{active:p,multipliers:c,expiresInDays:u.expiresInDays}:{active:p,multipliers:c},m}var rn=1e4,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??C,this.inbound=new h(this.clock),this.outbound=new h(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(o=>T(o,e.origin))||$(e.origin,this.options.selfOrigin)))return this.refuse(e,`embedder '${e.origin}' is not in allowedEmbedders`),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=b["gem.handshake"]?.(e.data);if(r)return this.refuse(e,`malformed handshake: ${r}`),false;let s=e.data;if(!T(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 l=H(f,s.versions);return l===null?(i.onmessage=null,i.postMessage({gem:d,type:"gem.error",code:"version_mismatch",message:`frame supports v${f.min}..v${f.max}`}),i.close(),this.transition("refused"),this.options.onError?.("version_mismatch"),false):(this.port=i,this.version=l,i.onmessage=o=>this.receive(o.data,o.ports??[]),i.start?.(),this.peerCapabilities=s.capabilities??[],this.unbidden=s.unbidden===true,i.postMessage({gem:d,type:"gem.handshake.accept",v:l,...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:d,type:"gem.ready"});}settled(e=rn){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:d,type:"gem.progress",loaded:e,total:n});}requestToken(e,n){this.send({gem:d,type:"gem.requestToken",requestId:e,reason:n});}requestLocalServer(e,n){return this.parentSupports("localHost")?(this.send({gem:d,type:"gem.requestLocalServer",requestId:e,gameRoomId:n}),true):false}exit(e){this.send(e===void 0?{gem:d,type:"gem.exit"}:{gem:d,type:"gem.exit",reason:e});}openExternal(e){this.send({gem:d,type:"gem.openExternal",url:e});}requestFullscreen(e){this.send({gem:d,type:"gem.requestFullscreen",enabled:e});}reportMuted(e){return this.state!=="connected"||!this.parentSupports("audioState")?false:(this.send({gem:d,type:"gem.audioState",muted:e}),true)}reportEngaged(){return this.engagedSent||this.state!=="connected"||!this.parentSupports("engagement")||!this.send({gem:d,type:"gem.engaged"})?false:(this.engagedSent=true,true)}cueReward(e){if(this.state!=="connected"||!this.parentSupports("rewardCue"))return false;let n={gem:d,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:U(e.origin.x),y:U(e.origin.y)}),this.send(n),true}setWalletVisible(e,n){return this.state!=="connected"||!this.parentSupports("walletDisplay")?false:this.send({gem:d,type:"gem.walletDisplay",...nn(e,n?.only)})}requestShare(e){return this.state!=="connected"||!this.parentSupports("share")?false:this.send({gem:d,type:"gem.requestShare",params:e.map(({key:n,value:r})=>({key:n,value:r}))})}reportFrameStats(e){return this.state!=="connected"||!this.parentSupports("frameStats")?false:(this.send({gem:d,type:"gem.frameStats",fps:W(e.fps,1e3),frameTimeP95Ms:W(e.frameTimeP95Ms,1e5)}),true)}sendGameContext(e){return this.state!=="connected"?false:(this.send({gem:d,type:"gem.gameContext",context:e}),true)}signal(e,n,r){this.send({gem:d,type:"gem.signal",signal:e,matchId:n,data:r});}dedicatedOffer(e,n,r){this.send({gem:d,type:"gem.dedicatedOffer",matchId:e,sdp:n,intent:r});}requestParty(e){return this.send({gem:d,type:"gem.partyRequest",requestId:e})}requestPurchase(e,n,r,s,i,l){return this.send({gem:d,type:"gem.requestPurchase",requestId:e,purchaseKind:n,targetId:r,currencySlug:s,...i===void 0?{}:{quantity:i},...l===void 0?{}:{catalogId:l}})}putDeviceSettings(e,n){return this.send({gem:d,type:"gem.deviceSettings.put",requestId:e,settings:n})}requestAd(e,n,r){return this.send({gem:d,type:"gem.requestAd",requestId:e,placement:n,format:r})}requestSignIn(e){return this.send({gem:d,type:"gem.requestSignIn",requestId:e})}requestFriendChallenge(e,n,r,s){return this.send({gem:d,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(x)){this.options.onDropped?.(e,n);return}this.fail(e,n);}dropUnknownType(e){this.inbound.allow(x)&&this.options.onDropped?.("unsupported",`ignored unknown message type '${e}'`);}refuse(e,n){e.ports?.[0]?.close?.(),this.inbound.allow(x)&&this.options.onRefused?.(n);}fail(e,n){this.options.onError?.(e,n),this.state==="connected"&&this.port&&this.send({gem:d,type:"gem.error",code:e,...n===void 0?{}:{message:n}});}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=b[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||N(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=b[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=_(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 l=s(e);if(l)return this.fail("invalid_message",`${r}: ${l}`),false;let o=e;if(o.v!==this.version)return this.fail("invalid_message",`${r}: expected v ${String(this.version)}`),false;switch(r){case "gem.token":this.options.onToken?.(o);break;case "gem.pause":this.options.onPause?.(o);break;case "gem.prefs":this.options.onPrefs?.(o);break;case "gem.cohorts":this.options.onCohorts?.(o);break;case "gem.earnAllowanceChanged":this.options.onEarnAllowanceChanged?.();break;case "gem.viewport":this.options.onViewport?.(o);break;case "gem.willTerminate":this.options.onWillTerminate?.(o);break;case "gem.devtools":this.options.onDevtools?.(o.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 u={maxWidth:o.maxWidth,maxHeight:o.maxHeight};if(!this.options.onScreenshot){m.close(),this.screenshotDenied("not_wired",false);break}return N(n.slice(1)),this.options.onScreenshot(u,m,(c,p)=>this.screenshotDenied(c,p)),true}case "gem.token.denied":this.options.onTokenDenied?.(o);break;case "gem.localServer":this.options.onLocalServer?.(o);break;case "gem.localServer.denied":this.options.onLocalServerDenied?.(o);break;case "gem.player":{this.options.onPlayer?.(tn(o));break}case "gem.roomEvent":this.options.onRoomEvent?.(o);break;case "gem.seatedEvent":this.options.onSeatedEvent?.(o);break;case "gem.autoStartFailedEvent":this.options.onAutoStartFailedEvent?.(o);break;case "gem.socketState":this.options.onSocketState?.(o);break;case "gem.signalEvent":this.options.onSignalEvent?.(o);break;case "gem.dedicatedEvent":this.options.onDedicatedEvent?.(o);break;case "gem.clusterTarget":this.options.onClusterTarget?.(o);break;case "gem.partyResult":this.options.onPartyResult?.(o);break;case "gem.purchaseResult":this.options.onPurchaseResult?.(o);break;case "gem.deviceSettings":this.options.onDeviceSettings?.(o);break;case "gem.deviceSettings.result":this.options.onDeviceSettingsResult?.(o);break;case "gem.adResult":this.options.onAdResult?.(o);break;case "gem.signInResult":this.options.onSignInResult?.(o);break;case "gem.friendChallengeResult":this.options.onFriendChallengeResult?.(o);break;case "gem.error":this.options.onError?.(o.code,o.message);break;default:this.fail("unsupported",`no frame handler for '${r}'`);}return false}screenshotDenied(e,n){this.send({gem:d,type:"gem.screenshot.denied",reason:e,retryable:n});}};function N(t){for(let e of t)try{e?.close?.();}catch{}}I();function on(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 k({...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),q(window,n),e}var V={connect:on,GemFrame:k,PROTOCOL:d,SUPPORTED_VERSIONS:f};window.GemWebSdkBridge=V;var kn=V;return kn;})();
|
|
1
|
+
var GemWebSdkBridgeBundle=(function(){'use strict';var b="GemWebSdkHandshake";function B(){return typeof document>"u"?void 0:document.readyState}var P=()=>Date.now();function I(t={}){let e=t.win??window,n=e,r=n[b];if(r!==void 0)return r;let s=t.readyState??B,i=t.now??P,l=[],o=[],m=c=>{let p=c.data;!p||p.type!=="gem.handshake"||(l.length>=4&&(l.shift(),o.shift(),u.dropped+=1),l.push(c),o.push(i()));};e.addEventListener("message",m);let u={events:l,times:o,dropped:0,late:s()==="complete",uninstall(){e.removeEventListener("message",m);}};return n[b]=u,u}function q(t,e,n={}){let r=t[b];if(r===void 0)return null;let s=n.ttlMs??9500,i=n.now??P,l=r.events.splice(0),o=r.times?.splice(0),m=0,u=0,c=false,p=i()-s;for(let g=l.length-1;g>=0;g--){let E=o?.[g];if(E!==void 0&&E<p){u+=1;continue}if(m+=1,e(l[g])===true){c=true;break}}return r.uninstall(),{capture:r,delivered:m,stale:u,accepted:c}}var d="gem-web-bridge",f={min:1,max:1},y=65536,L=8,v=5e3,A=1024;function S(t){return Object.freeze(Object.assign(Object.create(null),t))}var j=S({"gem.handshake":30,"gem.handshake.accept":5,"gem.token":30,"gem.token.denied":30,"gem.player":12,"gem.pause":120,"gem.prefs":60,"gem.cohorts":12,"gem.earnAllowanceChanged":30,"gem.viewport":60,"gem.deviceSettings":12,"gem.willTerminate":10,"gem.roomEvent":120,"gem.socketState":12,"gem.seatedEvent":60,"gem.autoStartFailedEvent":30,"gem.signalEvent":1800,"gem.dedicatedEvent":120,"gem.partyResult":30,"gem.clusterTarget":12,"gem.devtools":30,"gem.screenshot":6,"gem.screenshot.denied":12,"gem.requestContext":12,"gem.gameContext":12,"gem.signal":1200,"gem.dedicatedOffer":60,"gem.partyRequest":12,"gem.ready":5,"gem.engaged":5,"gem.progress":600,"gem.requestToken":12,"gem.requestLocalServer":6,"gem.localServer":30,"gem.localServer.denied":30,"gem.exit":5,"gem.openExternal":6,"gem.requestFullscreen":30,"gem.audioState":120,"gem.rewardCue":60,"gem.walletDisplay":60,"gem.requestShare":6,"gem.frameStats":120,"gem.error":60,"gem.requestPurchase":12,"gem.purchaseResult":30,"gem.deviceSettings.put":30,"gem.deviceSettings.result":30,"gem.requestAd":6,"gem.adResult":12,"gem.requestSignIn":6,"gem.signInResult":12,"gem.requestFriendChallenge":12,"gem.friendChallengeResult":30,__malformed:60}),x="__malformed";var z=S({"gem.requestAd":"ads","gem.adResult":"ads","gem.requestSignIn":"signIn","gem.signInResult":"signIn","gem.requestPurchase":"purchases","gem.purchaseResult":"purchases","gem.requestFriendChallenge":"friendChallenges","gem.friendChallengeResult":"friendChallenges","gem.devtools":"devtools","gem.screenshot":"screenshot","gem.screenshot.denied":"screenshot","gem.requestContext":"feedbackContext","gem.gameContext":"feedbackContext","gem.roomEvent":"rooms","gem.signal":"p2p","gem.signalEvent":"p2p","gem.dedicatedOffer":"dedicated","gem.dedicatedEvent":"dedicated","gem.clusterTarget":"clusterTarget","gem.partyRequest":"parties","gem.partyResult":"parties","gem.autoStartFailedEvent":"autoStartFailure","gem.seatedEvent":"partySeating","gem.socketState":"socketState","gem.audioState":"audioState","gem.rewardCue":"rewardCue","gem.frameStats":"frameStats","gem.engaged":"engagement","gem.viewport":"viewport","gem.walletDisplay":"walletDisplay","gem.requestLocalServer":"localHost","gem.localServer":"localHost","gem.localServer.denied":"localHost","gem.cohorts":"cohorts","gem.earnAllowanceChanged":"earnAllowance","gem.deviceSettings":"deviceSettings","gem.deviceSettings.put":"deviceSettings","gem.deviceSettings.result":"deviceSettings","gem.requestShare":"share"}),K=Object.freeze([["gem.asyncOpponents.","asyncOpponents"],["gem.viewport.","reservedAreas"]]);function _(t){let e=z[t];if(e!==void 0)return e;for(let[n,r]of K)if(t.startsWith(n))return r}function Y(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 X(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 J(t){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(t)}function Q(t){return /^[a-z_]+$/.test(t)}function R(t,e,n){if(e>L)return `nesting deeper than ${L}`;if(++n.nodes>v)return `more than ${v} values`;if(n.bytes>y)return `over the ${y} 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>A)return `an array of ${t.length} entries, over the ${A} limit`;n.bytes+=2;for(let o of t){let m=R(o,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 l=t;for(let o in l){if(!Object.prototype.hasOwnProperty.call(l,o))continue;if(++n.nodes>v)return `more than ${v} values`;if(n.bytes+=o.length*3+4,n.bytes>y)return `over the ${y} byte limit`;let m=R(l[o],e+1,n);if(m)return m}return null}function Z(t){let e={nodes:0,bytes:0,seen:new Set},n=R(t,0,e);return n?`message contains ${n}`:e.bytes>y?`message is over the ${y} byte limit`:null}var ee={origin:[Y,"not a well-formed origin"],url:[X,"not a safe absolute http(s) URL"],bcp47:[J,"not a well-formed BCP 47 tag"],code:[Q,"not a code of lower-case letters and underscores"]};function D(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 l=F(i,r,s);if(l)return l}return null}function F(t,e,n){switch(e.k){case "string":{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]=ee[e.f];if(!r(t))return `${n}: ${s}`}return null}case "int":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 "boolean":return typeof t=="boolean"?null:`${n}: expected boolean`;case "enum":{let r=e.v;return r.includes(t)?null:`${n}: not one of ${r.join("|")}`}case "object":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected object`:D(t,e.fs,n);case "json":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected a plain object`:null;case "array":{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 l=F(i,r,s);if(l)return l}return null}default:{let r=e.k;return `${n}: unknown kind ${String(r)}`}}}function a(t,e){return n=>{let r=Z(n);if(r)return r;if(typeof n!="object"||n===null||Array.isArray(n))return "message: expected object";let s=n;return s.gem!==d?"gem: wrong protocol marker":s.type!==t?`type: expected ${t}`:D(s,e,"")}}var ne=a("gem.handshake",[{n:"versions",k:"object",fs:[{n:"min",k:"int",lo:1,hi:1e3},{n:"max",k:"int",lo:1,hi:1e3}]},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}},{n:"embedder",k:"string",max:2048,f:"origin"},{n:"unbidden",k:"boolean",o:1}]),te=a("gem.handshake.accept",[{n:"v",k:"int",lo:1,hi:1e3},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}}]),re=a("gem.token",[{n:"token",k:"string",max:4096},{n:"requestId",k:"string",o:1,max:64},{n:"generation",k:"int",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"string",o:1,max:512,f:"url"},{n:"playerId",k:"string",max:64},{n:"gameId",k:"string",max:64},{n:"channel",k:"enum",v:["dev","test","release"]},{n:"gameVersion",k:"string",o:1,max:64},{n:"expiresAt",k:"int",lo:0,hi:4102444800},{n:"chainEndsAt",k:"int",lo:0,hi:4102444800},{n:"allowDevTools",k:"boolean",o:1}]),oe=a("gem.token.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"retryAfterMs",k:"int",o:1,lo:0,hi:36e5},{n:"reason",k:"enum",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"string",max:64}]),ae=a("gem.player",[{n:"untrusted",k:"object",fs:[{n:"displayName",k:"string",max:64},{n:"displayTag",k:"string",o:1,max:80},{n:"displayHandle",k:"string",max:80}]},{n:"playerId",k:"string",o:1,max:64},{n:"discriminator",k:"string",o:1,max:8},{n:"avatarIconUrl",k:"string",o:1,max:2048,f:"url"},{n:"badges",k:"array",o:1,max:2,it:{n:"",k:"object",fs:[{n:"itemId",k:"string",max:64},{n:"iconUrl",k:"string",max:2048,f:"url"}]}},{n:"displayTag",k:"string",max:8},{n:"avatarUrl",k:"string",o:1,max:2048,f:"url"},{n:"boost",k:"object",o:1,fs:[{n:"multipliers",k:"array",max:8,it:{n:"",k:"object",fs:[{n:"currencyId",k:"string",max:64},{n:"currencySlug",k:"string",max:32},{n:"multiplierBp",k:"int",lo:1e4,hi:1e6}]}},{n:"expiresInDays",k:"int",o:1,lo:1,hi:7}]}]),se=a("gem.pause",[{n:"paused",k:"boolean"}]),ie=a("gem.prefs",[{n:"reducedMotion",k:"boolean"},{n:"muted",k:"boolean"},{n:"showFrameStats",k:"boolean",o:1},{n:"locale",k:"string",max:35,f:"bcp47"}]),le=a("gem.cohorts",[{n:"cohorts",k:"array",max:8,it:{n:"",k:"object",fs:[{n:"experimentId",k:"string",max:36},{n:"variantKey",k:"string",max:32}]}}]),de=a("gem.earnAllowanceChanged",[]),me=a("gem.viewport",[{n:"insets",k:"object",fs:[{n:"top",k:"int",lo:0,hi:4096},{n:"right",k:"int",lo:0,hi:4096},{n:"bottom",k:"int",lo:0,hi:4096},{n:"left",k:"int",lo:0,hi:4096}]},{n:"reserved",k:"array",o:1,max:4,it:{n:"",k:"object",fs:[{n:"x",k:"int",lo:0,hi:16384},{n:"y",k:"int",lo:0,hi:16384},{n:"width",k:"int",lo:0,hi:16384},{n:"height",k:"int",lo:0,hi:16384}]}}]),ge=a("gem.deviceSettings",[{n:"settings",k:"json",o:1}]),ue=a("gem.willTerminate",[{n:"reason",k:"enum",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"int",lo:0,hi:6e4}]),ce=a("gem.roomEvent",[{n:"event",k:"enum",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"string",max:64},{n:"matchId",k:"string",o:1,max:64},{n:"version",k:"int",o:1,lo:0,hi:2147483647},{n:"reason",k:"string",o:1,max:64},{n:"platform",k:"enum",o:1,v:["universal","mobile"]}]),pe=a("gem.socketState",[{n:"connected",k:"boolean"},{n:"reason",k:"enum",o:1,v:["connecting","dropped","watchdog","terminal"]}]),ye=a("gem.seatedEvent",[{n:"roomId",k:"string",max:64}]),fe=a("gem.autoStartFailedEvent",[{n:"roomId",k:"string",max:64},{n:"code",k:"string",max:64}]),he=a("gem.signalEvent",[{n:"event",k:"enum",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),ke=a("gem.dedicatedEvent",[{n:"event",k:"enum",v:["answer","error","matchEnded"]},{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",o:1,max:10240},{n:"sessionId",k:"string",o:1,max:64},{n:"code",k:"string",o:1,max:64},{n:"message",k:"string",o:1,max:256},{n:"reason",k:"string",o:1,max:64}]),ve=a("gem.partyResult",[{n:"requestId",k:"string",max:64},{n:"partyId",k:"string",o:1,max:64}]),xe=a("gem.clusterTarget",[{n:"clusterTargetId",k:"string",max:64},{n:"clusterTargetIds",k:"array",o:1,max:3,it:{n:"",k:"string",max:64}}]),we=a("gem.devtools",[{n:"action",k:"enum",v:["open","close","toggle"]}]),be=a("gem.screenshot",[{n:"maxWidth",k:"int",lo:1,hi:7680},{n:"maxHeight",k:"int",lo:1,hi:4320}]),Re=a("gem.screenshot.denied",[{n:"reason",k:"enum",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"boolean"}]),Se=a("gem.requestContext",[]),Ge=a("gem.gameContext",[{n:"context",k:"json"}]),Oe=a("gem.signal",[{n:"signal",k:"enum",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),Ce=a("gem.dedicatedOffer",[{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",max:10240},{n:"intent",k:"enum",v:["initial","ice_restart","full_reconnect"]}]),Te=a("gem.partyRequest",[{n:"requestId",k:"string",max:64}]),Ee=a("gem.ready",[]),Pe=a("gem.engaged",[]),Ie=a("gem.progress",[{n:"loaded",k:"int",lo:0,hi:1099511627776},{n:"total",k:"int",lo:0,hi:1099511627776}]),qe=a("gem.requestToken",[{n:"requestId",k:"string",max:64},{n:"reason",k:"enum",v:["initial","expiring","rejected"]}]),Le=a("gem.requestLocalServer",[{n:"requestId",k:"string",max:64},{n:"gameRoomId",k:"string",max:64}]),Ae=a("gem.localServer",[{n:"requestId",k:"string",max:64},{n:"serverId",k:"string",o:1,max:128}]),je=a("gem.localServer.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"reason",k:"enum",v:["refused","unavailable"]}]),_e=a("gem.exit",[{n:"reason",k:"string",o:1,max:64}]),De=a("gem.openExternal",[{n:"url",k:"string",max:2048,f:"url"}]),Fe=a("gem.requestFullscreen",[{n:"enabled",k:"boolean"}]),Me=a("gem.audioState",[{n:"muted",k:"boolean"}]),$e=a("gem.rewardCue",[{n:"currencySlug",k:"string",max:32},{n:"expected",k:"int",o:1,lo:1,hi:1e9},{n:"origin",k:"object",o:1,fs:[{n:"x",k:"int",lo:0,hi:16384},{n:"y",k:"int",lo:0,hi:16384}]}]),He=a("gem.walletDisplay",[{n:"visible",k:"boolean"},{n:"currencies",k:"array",o:1,max:8,it:{n:"",k:"string",max:64}},{n:"score",k:"boolean",o:1}]),Ue=a("gem.requestShare",[{n:"params",k:"array",max:16,it:{n:"",k:"object",fs:[{n:"key",k:"string",max:64},{n:"value",k:"string",max:512}]}}]),We=a("gem.frameStats",[{n:"fps",k:"int",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"int",lo:0,hi:1e5}]),Ne=a("gem.error",[{n:"code",k:"enum",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"string",o:1,max:256}]),Ve=a("gem.requestPurchase",[{n:"requestId",k:"string",max:64},{n:"purchaseKind",k:"enum",v:["item","recipe"]},{n:"targetId",k:"string",max:64},{n:"currencySlug",k:"string",max:32},{n:"quantity",k:"int",o:1,lo:1,hi:10},{n:"catalogId",k:"string",o:1,max:64}]),Be=a("gem.purchaseResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["ok","declined","unavailable"]},{n:"reason",k:"string",o:1,max:64,f:"code"},{n:"purchaseId",k:"string",o:1,max:64}]),ze=a("gem.deviceSettings.put",[{n:"requestId",k:"string",max:64},{n:"settings",k:"json"}]),Ke=a("gem.deviceSettings.result",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["stored","too_large","unavailable"]}]),Ye=a("gem.requestAd",[{n:"requestId",k:"string",max:64},{n:"placement",k:"string",max:32},{n:"format",k:"enum",v:["interstitial","rewarded"]}]),Xe=a("gem.adResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["shown","no_ad","unavailable"]}]),Je=a("gem.requestSignIn",[{n:"requestId",k:"string",max:64}]),Qe=a("gem.signInResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["signed_in","declined","unavailable"]}]),Ze=a("gem.requestFriendChallenge",[{n:"requestId",k:"string",max:64},{n:"playerId",k:"string",max:64},{n:"template",k:"string",max:64},{n:"params",k:"json",o:1}]),en=a("gem.friendChallengeResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["accepted","cancelled","refused","unavailable","rate_limited","invalid"]},{n:"code",k:"string",o:1,max:64},{n:"param",k:"string",o:1,max:64},{n:"channel",k:"string",o:1,max:16},{n:"configVersion",k:"int",o:1,lo:0,hi:9007199254740991},{n:"retryAfterMs",k:"int",o:1,lo:0,hi:864e5},{n:"detail",k:"string",o:1,max:300}]),w=S({"gem.handshake":ne,"gem.handshake.accept":te,"gem.token":re,"gem.token.denied":oe,"gem.player":ae,"gem.pause":se,"gem.prefs":ie,"gem.cohorts":le,"gem.earnAllowanceChanged":de,"gem.viewport":me,"gem.deviceSettings":ge,"gem.willTerminate":ue,"gem.roomEvent":ce,"gem.socketState":pe,"gem.seatedEvent":ye,"gem.autoStartFailedEvent":fe,"gem.signalEvent":he,"gem.dedicatedEvent":ke,"gem.partyResult":ve,"gem.clusterTarget":xe,"gem.devtools":we,"gem.screenshot":be,"gem.screenshot.denied":Re,"gem.requestContext":Se,"gem.gameContext":Ge,"gem.signal":Oe,"gem.dedicatedOffer":Ce,"gem.partyRequest":Te,"gem.ready":Ee,"gem.engaged":Pe,"gem.progress":Ie,"gem.requestToken":qe,"gem.requestLocalServer":Le,"gem.localServer":Ae,"gem.localServer.denied":je,"gem.exit":_e,"gem.openExternal":De,"gem.requestFullscreen":Fe,"gem.audioState":Me,"gem.rewardCue":$e,"gem.walletDisplay":He,"gem.requestShare":Ue,"gem.frameStats":We,"gem.error":Ne,"gem.requestPurchase":Ve,"gem.purchaseResult":Be,"gem.deviceSettings.put":ze,"gem.deviceSettings.result":Ke,"gem.requestAd":Ye,"gem.adResult":Xe,"gem.requestSignIn":Je,"gem.signInResult":Qe,"gem.requestFriendChallenge":Ze,"gem.friendChallengeResult":en});var G=class{#e;constructor(e){this.#e=e,Object.freeze(this);}toString(){return "[gem: use gem.text.toPlain()]"}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function O(t){return new G(t)}var C={now:()=>Date.now(),setTimeout:(t,e)=>setTimeout(t,e),clearTimeout:t=>clearTimeout(t)},h=class{constructor(e=C){this.clock=e;}clock;tokens=new Map;lastRefill=new Map;allow(e){let n=j[e];if(n===void 0)return false;let r=this.clock.now(),s=this.lastRefill.get(e)??r,i=this.tokens.get(e)??n,l=Math.max(0,r-s),o=Math.min(n,i+l*n/6e4);return o<1?(this.tokens.set(e,o),this.lastRefill.set(e,r),false):(this.tokens.set(e,o-1),this.lastRefill.set(e,r),true)}};function T(t,e){return t.toLowerCase()===e.toLowerCase()}function M(t){let e=t.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}function $(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:M(n.hostname)&&M(r.hostname)}function H(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}function U(t){return Math.min(16384,Math.max(0,Math.round(Number.isFinite(t)?t:0)))}function nn(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 W(t,e){return Math.min(e,Math.max(0,Math.round(Number.isFinite(t)?t:0)))}function tn(t){let e=t.untrusted,n=O(e.displayName),r=e.displayTag||e.displayHandle,s=r?O(r):void 0,i=t.discriminator||t.displayTag,l=i&&/^[0-9]{1,8}$/.test(i)?i:void 0,o=t.avatarIconUrl||t.avatarUrl,m={displayName:n,displayHandle:s??n,badges:(t.badges??[]).map(g=>({itemId:g.itemId,iconUrl:g.iconUrl}))};t.playerId&&(m.playerId=t.playerId),l&&(m.discriminator=l),s&&(m.displayTag=s),o&&(m.avatarIconUrl=m.avatarUrl=o);let u=t.boost,c=(u?.multipliers??[]).map(g=>({currencyId:g.currencyId,currencySlug:g.currencySlug,multiplier:g.multiplierBp/1e4})),p=c.some(g=>g.multiplier>1);return m.boost=p&&u?.expiresInDays?{active:p,multipliers:c,expiresInDays:u.expiresInDays}:{active:p,multipliers:c},m}var rn=1e4,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??C,this.inbound=new h(this.clock),this.outbound=new h(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(o=>T(o,e.origin))||$(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=w["gem.handshake"]?.(e.data);if(r)return this.refuse(e,`malformed handshake: ${r}`),false;let s=e.data;if(!T(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 l=H(f,s.versions);return l===null?(i.onmessage=null,i.postMessage({gem:d,type:"gem.error",code:"version_mismatch",message:`frame supports v${f.min}..v${f.max}`}),i.close(),this.transition("refused"),this.options.onError?.("version_mismatch"),false):(this.port=i,this.version=l,i.onmessage=o=>this.receive(o.data,o.ports??[]),i.start?.(),this.peerCapabilities=s.capabilities??[],this.unbidden=s.unbidden===true,i.postMessage({gem:d,type:"gem.handshake.accept",v:l,...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:d,type:"gem.ready"});}settled(e=rn){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:d,type:"gem.progress",loaded:e,total:n});}requestToken(e,n){this.send({gem:d,type:"gem.requestToken",requestId:e,reason:n});}requestLocalServer(e,n){return this.parentSupports("localHost")?(this.send({gem:d,type:"gem.requestLocalServer",requestId:e,gameRoomId:n}),true):false}exit(e){this.send(e===void 0?{gem:d,type:"gem.exit"}:{gem:d,type:"gem.exit",reason:e});}openExternal(e){this.send({gem:d,type:"gem.openExternal",url:e});}requestFullscreen(e){this.send({gem:d,type:"gem.requestFullscreen",enabled:e});}reportMuted(e){return this.state!=="connected"||!this.parentSupports("audioState")?false:(this.send({gem:d,type:"gem.audioState",muted:e}),true)}reportEngaged(){return this.engagedSent||this.state!=="connected"||!this.parentSupports("engagement")||!this.send({gem:d,type:"gem.engaged"})?false:(this.engagedSent=true,true)}cueReward(e){if(this.state!=="connected"||!this.parentSupports("rewardCue"))return false;let n={gem:d,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:U(e.origin.x),y:U(e.origin.y)}),this.send(n),true}setWalletVisible(e,n){return this.state!=="connected"||!this.parentSupports("walletDisplay")?false:this.send({gem:d,type:"gem.walletDisplay",...nn(e,n?.only)})}requestShare(e){return this.state!=="connected"||!this.parentSupports("share")?false:this.send({gem:d,type:"gem.requestShare",params:e.map(({key:n,value:r})=>({key:n,value:r}))})}reportFrameStats(e){return this.state!=="connected"||!this.parentSupports("frameStats")?false:(this.send({gem:d,type:"gem.frameStats",fps:W(e.fps,1e3),frameTimeP95Ms:W(e.frameTimeP95Ms,1e5)}),true)}sendGameContext(e){return this.state!=="connected"?false:(this.send({gem:d,type:"gem.gameContext",context:e}),true)}signal(e,n,r){this.send({gem:d,type:"gem.signal",signal:e,matchId:n,data:r});}dedicatedOffer(e,n,r){this.send({gem:d,type:"gem.dedicatedOffer",matchId:e,sdp:n,intent:r});}requestParty(e){return this.send({gem:d,type:"gem.partyRequest",requestId:e})}requestPurchase(e,n,r,s,i,l){return this.send({gem:d,type:"gem.requestPurchase",requestId:e,purchaseKind:n,targetId:r,currencySlug:s,...i===void 0?{}:{quantity:i},...l===void 0?{}:{catalogId:l}})}putDeviceSettings(e,n){return this.send({gem:d,type:"gem.deviceSettings.put",requestId:e,settings:n})}requestAd(e,n,r){return this.send({gem:d,type:"gem.requestAd",requestId:e,placement:n,format:r})}requestSignIn(e){return this.send({gem:d,type:"gem.requestSignIn",requestId:e})}requestFriendChallenge(e,n,r,s){return this.send({gem:d,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(x)){this.options.onDropped?.(e,n);return}this.fail(e,n);}dropUnknownType(e){this.inbound.allow(x)&&this.options.onDropped?.("unsupported",`ignored unknown message type '${e}'`);}refuse(e,n){e.ports?.[0]?.close?.(),this.inbound.allow(x)&&this.options.onRefused?.(n);}fail(e,n){this.options.onError?.(e,n),this.state==="connected"&&this.port&&this.send({gem:d,type:"gem.error",code:e,...n===void 0?{}:{message:n}});}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=w[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||N(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=w[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=_(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 l=s(e);if(l)return this.fail("invalid_message",`${r}: ${l}`),false;let o=e;if(o.v!==this.version)return this.fail("invalid_message",`${r}: expected v ${String(this.version)}`),false;switch(r){case "gem.token":this.options.onToken?.(o);break;case "gem.pause":this.options.onPause?.(o);break;case "gem.prefs":this.options.onPrefs?.(o);break;case "gem.cohorts":this.options.onCohorts?.(o);break;case "gem.earnAllowanceChanged":this.options.onEarnAllowanceChanged?.();break;case "gem.viewport":this.options.onViewport?.(o);break;case "gem.willTerminate":this.options.onWillTerminate?.(o);break;case "gem.devtools":this.options.onDevtools?.(o.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 u={maxWidth:o.maxWidth,maxHeight:o.maxHeight};if(!this.options.onScreenshot){m.close(),this.screenshotDenied("not_wired",false);break}return N(n.slice(1)),this.options.onScreenshot(u,m,(c,p)=>this.screenshotDenied(c,p)),true}case "gem.token.denied":this.options.onTokenDenied?.(o);break;case "gem.localServer":this.options.onLocalServer?.(o);break;case "gem.localServer.denied":this.options.onLocalServerDenied?.(o);break;case "gem.player":{this.options.onPlayer?.(tn(o));break}case "gem.roomEvent":this.options.onRoomEvent?.(o);break;case "gem.seatedEvent":this.options.onSeatedEvent?.(o);break;case "gem.autoStartFailedEvent":this.options.onAutoStartFailedEvent?.(o);break;case "gem.socketState":this.options.onSocketState?.(o);break;case "gem.signalEvent":this.options.onSignalEvent?.(o);break;case "gem.dedicatedEvent":this.options.onDedicatedEvent?.(o);break;case "gem.clusterTarget":this.options.onClusterTarget?.(o);break;case "gem.partyResult":this.options.onPartyResult?.(o);break;case "gem.purchaseResult":this.options.onPurchaseResult?.(o);break;case "gem.deviceSettings":this.options.onDeviceSettings?.(o);break;case "gem.deviceSettings.result":this.options.onDeviceSettingsResult?.(o);break;case "gem.adResult":this.options.onAdResult?.(o);break;case "gem.signInResult":this.options.onSignInResult?.(o);break;case "gem.friendChallengeResult":this.options.onFriendChallengeResult?.(o);break;case "gem.error":this.options.onError?.(o.code,o.message);break;default:this.fail("unsupported",`no frame handler for '${r}'`);}return false}screenshotDenied(e,n){this.send({gem:d,type:"gem.screenshot.denied",reason:e,retryable:n});}};function N(t){for(let e of t)try{e?.close?.();}catch{}}I();function on(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 k({...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),q(window,n),e}var V={connect:on,GemFrame:k,PROTOCOL:d,SUPPORTED_VERSIONS:f};window.GemWebSdkBridge=V;var kn=V;return kn;})();
|