@indiegems/gem-web-sdk 22.0.0 → 23.0.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 CHANGED
@@ -16,6 +16,53 @@ Its entries are grouped under up to five headings:
16
16
  - **Rebuild**: a type changed. Recompile against the new version; code that compiles today keeps compiling unless the entry says otherwise.
17
17
  - **New capability**: something a game can now do. Nothing changes unless you use it.
18
18
 
19
+ ## 23.0.0
20
+
21
+ *Written from the API facts alone; no summary was generated for this release.*
22
+
23
+ Upgrading from 22.0.0. Impact: required.
24
+
25
+ ### Must change
26
+
27
+ - PARENT_CONFORMANCE_VERSION changed its signature.
28
+ - GemFrame.requestArcade changed its signature.
29
+ - FRAME_TO_PARENT changed its signature.
30
+ - FrameMessage changed its signature.
31
+ - GemCapability changed its signature.
32
+ - PARENT_TO_FRAME changed its signature.
33
+ - ParentMessage changed its signature.
34
+
35
+ ### New capability
36
+
37
+ - ParentFixture.channel was added.
38
+ - ParentFixture.gameId was added.
39
+ - ParentUnderTest.deliverSocket was added.
40
+ - CharactersApi.refreshHeld was added.
41
+ - FriendsApi.inviteToPlay was added.
42
+ - FriendsApi.setInviteParams was added.
43
+ - FriendsApiDependencies.inviteToPlay was added.
44
+ - FriendsApiDependencies.setInviteParams was added.
45
+ - PlayInviteRequest was added.
46
+ - FrameCallbacks.onInventoryChanged was added.
47
+ - FrameCallbacks.onPlayInviteResult was added.
48
+ - FrameOptions.onInventoryChanged was added.
49
+ - FrameOptions.onPlayInviteResult was added.
50
+ - GemHost.answerPlayInvite was added.
51
+ - GemHost.relayInventoryEvent was added.
52
+ - GemHost.sendInventoryChanged was added.
53
+ - GemInventoryChanged was added.
54
+ - GemInviteParams was added.
55
+ - GemPlayInviteResult was added.
56
+ - GemRequestPlayInvite was added.
57
+ - HostCallbacks.onInviteParams was added.
58
+ - HostCallbacks.onRequestPlayInvite was added.
59
+ - HostOptions.onInviteParams was added.
60
+ - HostOptions.onRequestPlayInvite was added.
61
+ - validateGemInventoryChanged was added.
62
+ - validateGemInviteParams was added.
63
+ - validateGemPlayInviteResult was added.
64
+ - validateGemRequestPlayInvite was added.
65
+
19
66
  ## 22.0.0
20
67
 
21
68
  Upgrading from 21.1.1. Impact: required.
@@ -20,6 +20,8 @@ interface ParentFixture {
20
20
  readonly isActive: boolean;
21
21
  } | undefined;
22
22
  readonly reportError: (code: string, message?: string) => void;
23
+ readonly gameId: string;
24
+ readonly channel: "dev" | "test" | "release";
23
25
  }
24
26
  interface ParentUnderTest {
25
27
  start(): void;
@@ -28,6 +30,7 @@ interface ParentUnderTest {
28
30
  readonly protocolVersion: number | null;
29
31
  readonly surfacesShown?: number;
30
32
  dismiss?(): void;
33
+ deliverSocket?(raw: unknown): void;
31
34
  }
32
35
  type ParentFactory = (fixture: ParentFixture) => ParentUnderTest;
33
36
  interface ParentConformanceOptions {
@@ -50,7 +53,7 @@ interface ParentConformanceResult {
50
53
  readonly ok: boolean;
51
54
  readonly message?: string;
52
55
  }
53
- declare const PARENT_CONFORMANCE_VERSION = 6;
56
+ declare const PARENT_CONFORMANCE_VERSION = 7;
54
57
  declare const PARENT_CONFORMANCE_CASES: readonly ParentConformanceCase[];
55
58
  declare function runParentConformance(factory: ParentFactory, options: ParentConformanceOptions): Promise<readonly ParentConformanceResult[]>;
56
59
  export { PARENT_CONFORMANCE_CASES, PARENT_CONFORMANCE_VERSION, type ParentConformanceCase, ParentConformanceError, type ParentConformanceOptions, type ParentConformanceResult, type ParentFactory, type ParentFixture, type ParentState, type ParentUnderTest, runParentConformance };
@@ -681,6 +681,7 @@ declare class CharactersApi {
681
681
  private readonly scopes;
682
682
  constructor(api: GameApi, saves?: SavesOptions | undefined, identity?: (() => string | null) | undefined, resolveCurrencyId?: ((slugOrId: string) => Promise<string | undefined>) | undefined);
683
683
  private readonly scope;
684
+ refreshHeld(): void;
684
685
  list(signal?: AbortSignal): Promise<readonly Character[]>;
685
686
  get(id: string, signal?: AbortSignal): Promise<Character>;
686
687
  create(options: CreateCharacterOptions): Promise<Character>;
@@ -826,8 +827,13 @@ declare class FriendChallengeError extends GemApiError {
826
827
  readonly configVersion?: number;
827
828
  });
828
829
  }
830
+ interface PlayInviteRequest {
831
+ readonly params?: Readonly<Record<string, string>>;
832
+ }
829
833
  interface FriendsApiDependencies {
830
834
  readonly challenge?: (request: FriendChallengeRequest) => Promise<FriendChallengeOutcome>;
835
+ readonly inviteToPlay?: (request?: PlayInviteRequest) => Promise<boolean>;
836
+ readonly setInviteParams?: (params: Readonly<Record<string, string>> | null) => boolean;
831
837
  readonly launchedChallengeId?: string;
832
838
  }
833
839
  declare class FriendsApi {
@@ -835,6 +841,8 @@ declare class FriendsApi {
835
841
  constructor(api: GameApi, dependencies?: FriendsApiDependencies);
836
842
  list(options?: ListFriendsOptions): Promise<FriendsPage>;
837
843
  challenge(request: FriendChallengeRequest): Promise<FriendChallengeOutcome>;
844
+ inviteToPlay(request?: PlayInviteRequest): Promise<boolean>;
845
+ setInviteParams(params: Readonly<Record<string, string>> | null): boolean;
838
846
  inbox(options?: ListFriendChallengesOptions): Promise<FriendChallengesPage>;
839
847
  launchedChallenge(options?: {
840
848
  readonly signal?: AbortSignal;
@@ -1082,4 +1090,4 @@ interface PlayerBoost {
1082
1090
  readonly multipliers: readonly PlayerBoostMultiplier[];
1083
1091
  readonly expiresInDays?: number;
1084
1092
  }
1085
- export { AnalyticsApi, type AnalyticsApiOptions, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type Avatar3dFamily, type Base64String, type Boundary, type BucketConfig, type BucketResetInterval, type BytesResponse, CONDITIONAL_HEADERS, type CacheParam, type Challenge, type ChallengeWindow, ChallengesApi, type Character, CharactersApi, type ClientOptions, type Clock, type ConditionalRequestHeaders, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, type CreateCharacterOptions, CurrenciesApi, type CurrencyBalance, type CurrencyBucket, type CurrencyReadOptions, type CurrencyRow, type DescribeSaveOptions, type DirectPurchaseRequest, type DirectPurchaseResult, type EarnAllowance, type EarnAllowanceEvent, type EarnAllowancePeriod, type EarnAllowanceReadOptions, type EarnAllowanceSignal, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, EntityReadCache, type EntityRef, type EntityScope, type EntityType, type Friend, type FriendChallenge, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, type FriendChallengesPage, FriendsApi, type FriendsApiDependencies, type FriendsPage, type FunctionContext, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, type GameApi, type GameOrderSource, type GamePass, GemApiError, GemClient, type GemErrorReason, type GemFunction, GemFunctionError, type GemFunctionIdentity, GemSaveError, type GetLeaderboardOptions, type GetSaveOptions, type GetSettingOptions, type InitiateTransferOptions, InventoryApi, type InventoryItem, type InventoryOperation, type InventorySnapshot, type ItemCategory, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, type ListSavesOptions, type ListTransfersOptions, type LootRoll, MAX_PERIODS_BACK, MutationsApi, type Order, type OrderOptions, type OrderPageOptions, type OrderResult, type OrderSource, OrdersApi, type Page, type PassesApi, type PassesEvent, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlatformPrice, type PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, type PlayerScope, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry, ProfilesApi, type Progression, type ProgressionAchievement, ProgressionsApi, type PurchaseOptions, type PutBytesOptions, type PutSaveOptions, type PutSettingOptions, type RankedRow, type RecipeAvailability, type RecipeChange, type RecipeLock, type RecipeResult, type RecipeUsage, type RecipeUsageList, type RefusedPurchase, type RequestOptions, type SavePage, type SaveRecord, SavesApi, type SavesOptions, type SessionEndReason, type Setting, SettingsApi, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SlotInfo, type SnapshotCurrency, type SnapshotItem, type SnapshotOptions, type SnapshotPageOptions, type TokenGrant, type Transfer, type TransferDirection, TransfersApi, type Transport, TransportRefusal, type TransportRequest, type TransportResponse, type VersionedGetOptions, type VersionedResponse, type WornAvatar3d, asPlayerText, createGem, mapIdentity, platformIconUrl, text, toBase64 };
1093
+ export { AnalyticsApi, type AnalyticsApiOptions, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type Avatar3dFamily, type Base64String, type Boundary, type BucketConfig, type BucketResetInterval, type BytesResponse, CONDITIONAL_HEADERS, type CacheParam, type Challenge, type ChallengeWindow, ChallengesApi, type Character, CharactersApi, type ClientOptions, type Clock, type ConditionalRequestHeaders, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, type CreateCharacterOptions, CurrenciesApi, type CurrencyBalance, type CurrencyBucket, type CurrencyReadOptions, type CurrencyRow, type DescribeSaveOptions, type DirectPurchaseRequest, type DirectPurchaseResult, type EarnAllowance, type EarnAllowanceEvent, type EarnAllowancePeriod, type EarnAllowanceReadOptions, type EarnAllowanceSignal, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, EntityReadCache, type EntityRef, type EntityScope, type EntityType, type Friend, type FriendChallenge, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, type FriendChallengesPage, FriendsApi, type FriendsApiDependencies, type FriendsPage, type FunctionContext, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, type GameApi, type GameOrderSource, type GamePass, GemApiError, GemClient, type GemErrorReason, type GemFunction, GemFunctionError, type GemFunctionIdentity, GemSaveError, type GetLeaderboardOptions, type GetSaveOptions, type GetSettingOptions, type InitiateTransferOptions, InventoryApi, type InventoryItem, type InventoryOperation, type InventorySnapshot, type ItemCategory, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, type ListSavesOptions, type ListTransfersOptions, type LootRoll, MAX_PERIODS_BACK, MutationsApi, type Order, type OrderOptions, type OrderPageOptions, type OrderResult, type OrderSource, OrdersApi, type Page, type PassesApi, type PassesEvent, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlatformPrice, type PlayInviteRequest, type PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, type PlayerScope, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry, ProfilesApi, type Progression, type ProgressionAchievement, ProgressionsApi, type PurchaseOptions, type PutBytesOptions, type PutSaveOptions, type PutSettingOptions, type RankedRow, type RecipeAvailability, type RecipeChange, type RecipeLock, type RecipeResult, type RecipeUsage, type RecipeUsageList, type RefusedPurchase, type RequestOptions, type SavePage, type SaveRecord, SavesApi, type SavesOptions, type SessionEndReason, type Setting, SettingsApi, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SlotInfo, type SnapshotCurrency, type SnapshotItem, type SnapshotOptions, type SnapshotPageOptions, type TokenGrant, type Transfer, type TransferDirection, TransfersApi, type Transport, TransportRefusal, type TransportRequest, type TransportResponse, type VersionedGetOptions, type VersionedResponse, type WornAvatar3d, asPlayerText, createGem, mapIdentity, platformIconUrl, text, toBase64 };
package/dist/game.d.ts CHANGED
@@ -1076,6 +1076,7 @@ declare class CharactersApi {
1076
1076
  private readonly scopes;
1077
1077
  constructor(api: GameApi, saves?: SavesOptions | undefined, identity?: (() => string | null) | undefined, resolveCurrencyId?: ((slugOrId: string) => Promise<string | undefined>) | undefined);
1078
1078
  private readonly scope;
1079
+ refreshHeld(): void;
1079
1080
  list(signal?: AbortSignal): Promise<readonly Character[]>;
1080
1081
  get(id: string, signal?: AbortSignal): Promise<Character>;
1081
1082
  create(options: CreateCharacterOptions): Promise<Character>;
@@ -1406,8 +1407,13 @@ declare class FriendChallengeError extends GemApiError {
1406
1407
  readonly configVersion?: number;
1407
1408
  });
1408
1409
  }
1410
+ interface PlayInviteRequest {
1411
+ readonly params?: Readonly<Record<string, string>>;
1412
+ }
1409
1413
  interface FriendsApiDependencies {
1410
1414
  readonly challenge?: (request: FriendChallengeRequest) => Promise<FriendChallengeOutcome>;
1415
+ readonly inviteToPlay?: (request?: PlayInviteRequest) => Promise<boolean>;
1416
+ readonly setInviteParams?: (params: Readonly<Record<string, string>> | null) => boolean;
1411
1417
  readonly launchedChallengeId?: string;
1412
1418
  }
1413
1419
  declare class FriendsApi {
@@ -1415,6 +1421,8 @@ declare class FriendsApi {
1415
1421
  constructor(api: GameApi, dependencies?: FriendsApiDependencies);
1416
1422
  list(options?: ListFriendsOptions): Promise<FriendsPage>;
1417
1423
  challenge(request: FriendChallengeRequest): Promise<FriendChallengeOutcome>;
1424
+ inviteToPlay(request?: PlayInviteRequest): Promise<boolean>;
1425
+ setInviteParams(params: Readonly<Record<string, string>> | null): boolean;
1418
1426
  inbox(options?: ListFriendChallengesOptions): Promise<FriendChallengesPage>;
1419
1427
  launchedChallenge(options?: {
1420
1428
  readonly signal?: AbortSignal;
@@ -2198,6 +2206,10 @@ interface GemCohorts$1 {
2198
2206
  variantKey: string;
2199
2207
  }[];
2200
2208
  }
2209
+ interface GemInventoryChanged {
2210
+ readonly gem: typeof PROTOCOL;
2211
+ readonly type: "gem.inventoryChanged";
2212
+ }
2201
2213
  interface GemViewport$1 {
2202
2214
  readonly gem: typeof PROTOCOL;
2203
2215
  readonly type: "gem.viewport";
@@ -2435,6 +2447,29 @@ interface GemFriendChallengeResult {
2435
2447
  readonly retryAfterMs?: number;
2436
2448
  readonly detail?: string;
2437
2449
  }
2450
+ interface GemRequestPlayInvite {
2451
+ readonly gem: typeof PROTOCOL;
2452
+ readonly type: "gem.requestPlayInvite";
2453
+ readonly requestId: string;
2454
+ readonly params?: {
2455
+ key: string;
2456
+ value: string;
2457
+ }[];
2458
+ }
2459
+ interface GemPlayInviteResult {
2460
+ readonly gem: typeof PROTOCOL;
2461
+ readonly type: "gem.playInviteResult";
2462
+ readonly requestId: string;
2463
+ readonly shown: boolean;
2464
+ }
2465
+ interface GemInviteParams {
2466
+ readonly gem: typeof PROTOCOL;
2467
+ readonly type: "gem.inviteParams";
2468
+ readonly params?: {
2469
+ key: string;
2470
+ value: string;
2471
+ }[];
2472
+ }
2438
2473
  interface GemRequestAppLinks {
2439
2474
  readonly gem: typeof PROTOCOL;
2440
2475
  readonly type: "gem.requestAppLinks";
@@ -3152,6 +3187,7 @@ interface FramePlayer extends PlayerIdentity {
3152
3187
  readonly boost: PlayerBoost;
3153
3188
  }
3154
3189
  type GemArcadeAsk = Omit<GemRequestAppLinks, "gem"> | Omit<GemRequestOpenApp, "gem"> | Omit<GemRequestOpenGame, "gem"> | Omit<GemRequestSimilarGames, "gem"> | Omit<GemRequestStoreOffers, "gem"> | Omit<GemRequestStorePurchase, "gem"> | Omit<GemRequestStoreOfferSheet, "gem">;
3190
+ type GemFriendsWindowAsk = Omit<GemRequestPlayInvite, "gem"> | Omit<GemInviteParams, "gem">;
3155
3191
  type GemArcadeAnswer = GemAppLinksResult | GemOpenAppResult | GemOpenGameResult | GemSimilarGamesResult | GemStoreOffersResult | GemStorePurchaseResult | GemStorePurchaseSettled | GemStoreOfferSheetResult;
3156
3192
  interface FrameCallbacks {
3157
3193
  onToken?(msg: GemToken): void;
@@ -3161,6 +3197,7 @@ interface FrameCallbacks {
3161
3197
  onPrefs?(msg: GemPrefs$1): void;
3162
3198
  onCohorts?(msg: GemCohorts$1): void;
3163
3199
  onEarnAllowanceChanged?(): void;
3200
+ onInventoryChanged?(msg: GemInventoryChanged): void;
3164
3201
  onViewport?(msg: GemViewport$1): void;
3165
3202
  onWillTerminate?(msg: GemWillTerminate): void;
3166
3203
  onDevtools?(action: "open" | "close" | "toggle"): void;
@@ -3194,6 +3231,7 @@ interface FrameCallbacks {
3194
3231
  onSignInResult?(msg: GemSignInResult): void;
3195
3232
  onFriendChallengeResult?(msg: GemFriendChallengeResult): void;
3196
3233
  onArcadeAnswer?(msg: GemArcadeAnswer): void;
3234
+ onPlayInviteResult?(msg: GemPlayInviteResult): void;
3197
3235
  onError?(code: GemErrorCode, message?: string): void;
3198
3236
  onDropped?(code: GemErrorCode, message?: string): void;
3199
3237
  onStateChange?(state: FrameState): void;
@@ -3274,7 +3312,7 @@ declare class GemFrame {
3274
3312
  readyCalled(): boolean;
3275
3313
  requestSignIn(requestId: string): boolean;
3276
3314
  requestFriendChallenge(requestId: string, playerId: string, template: string, params?: Readonly<Record<string, string | number>>): boolean;
3277
- requestArcade(msg: GemArcadeAsk): boolean;
3315
+ requestArcade(msg: GemArcadeAsk | GemFriendsWindowAsk): boolean;
3278
3316
  close(): void;
3279
3317
  private transition;
3280
3318
  private refuseMalformed;
@@ -3735,4 +3773,4 @@ interface ExitAnalytics {
3735
3773
  }
3736
3774
  declare function leaveAndExit(rooms: ExitRooms, bridge: ExitBridge | null, reason?: string, analytics?: ExitAnalytics): Promise<void>;
3737
3775
  declare function createGem(options?: GemOptions): Gem;
3738
- 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, type AppLinksOutcome, type AppListing, type AppStore, type ArcadeApi, type ArcadeAvailability, type ArcadeOffer, type ArcadeOutcome, type ArcadeOutcomeKind, AuthError, type AuthFailure, type AuthState, type Avatar3dFamily, type Avatar3dOffer, type Avatar3dPrice, type Avatar3dPurchaseRequest, type AvatarRigNode, type AvatarRigs, type Avatars3dApi, type BootMark, type BootTimeline, type BrandingApi, type BrandingAsset, type BrandingAssetOptions, type BrandingCurrency, type BrandingImageOptions, type BrandingList, type BrandingLookup, type BrandingTheme, type BrandingVariant, 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 GameCard, type GameConfig, type GameMenu, type GameMenuItem, type GamePass, type GameServerLink, type GameSettingsApi, type Gem, GemApiError, type GemAudioChannels, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemControlBox, type GemCorner, type GemDevTools, GemFrame, GemFunctionError, type GemGameChoiceSetting, type GemGameSetting, type GemGameSettingBase, type GemGameSettingChange, type GemGameSettingIcon, type GemGameSettingOption, type GemGameSettingValue, type GemGameSliderSetting, type GemGameToggleSetting, type GemGraphicsQuality, type GemGraphicsRoute, type GemGraphicsRouteEntry, type GemIdentity, type GemInsets, type GemLook, type GemLookBase, type GemLookDelta, type GemLookOptions, type GemLookSpeed, type GemMatchApi, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPreferredRoute, 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 GraphicsApi, 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 MenuStyle, type MessageMeta, type MomentKind, type MomentResult, type MomentSignal, type MomentsApi, type MultiTransportSession, PLATFORM_EVENTS, type PassesApi, type PassesEvent, 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, type PlayerScope, PlayerText, type PreferredRouteOptions, type ProfileCallOptions, type ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PurchaseSettlement, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RewardCue, type RewardPresentation, type RewardedStatus, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerTokenGrant, type SessionEndReason, type ShareApi, ShareRefusal, type ShareRequest, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SimilarGamesOutcome, type SnapshotCurrency, type SnapshotItem, type StoreApi, type StoreOffersOutcome, type StoreSettlement, type TransportAdvert, type TransportKind, TransportRefusal, UNRELIABLE_CHANNEL_LABEL, type VibrationApi, type WalletVisibleOptions, type WornAvatar3d, asPlayerText, createBootTimeline, createGem, experimentSelection, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, text, webTransportAvailable };
3776
+ 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, type AppLinksOutcome, type AppListing, type AppStore, type ArcadeApi, type ArcadeAvailability, type ArcadeOffer, type ArcadeOutcome, type ArcadeOutcomeKind, AuthError, type AuthFailure, type AuthState, type Avatar3dFamily, type Avatar3dOffer, type Avatar3dPrice, type Avatar3dPurchaseRequest, type AvatarRigNode, type AvatarRigs, type Avatars3dApi, type BootMark, type BootTimeline, type BrandingApi, type BrandingAsset, type BrandingAssetOptions, type BrandingCurrency, type BrandingImageOptions, type BrandingList, type BrandingLookup, type BrandingTheme, type BrandingVariant, 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 GameCard, type GameConfig, type GameMenu, type GameMenuItem, type GamePass, type GameServerLink, type GameSettingsApi, type Gem, GemApiError, type GemAudioChannels, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemControlBox, type GemCorner, type GemDevTools, GemFrame, GemFunctionError, type GemGameChoiceSetting, type GemGameSetting, type GemGameSettingBase, type GemGameSettingChange, type GemGameSettingIcon, type GemGameSettingOption, type GemGameSettingValue, type GemGameSliderSetting, type GemGameToggleSetting, type GemGraphicsQuality, type GemGraphicsRoute, type GemGraphicsRouteEntry, type GemIdentity, type GemInsets, type GemLook, type GemLookBase, type GemLookDelta, type GemLookOptions, type GemLookSpeed, type GemMatchApi, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPreferredRoute, 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 GraphicsApi, 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 MenuStyle, type MessageMeta, type MomentKind, type MomentResult, type MomentSignal, type MomentsApi, type MultiTransportSession, PLATFORM_EVENTS, type PassesApi, type PassesEvent, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayInviteRequest, type PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, type PlayerScope, PlayerText, type PreferredRouteOptions, type ProfileCallOptions, type ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PurchaseSettlement, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RewardCue, type RewardPresentation, type RewardedStatus, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerTokenGrant, type SessionEndReason, type ShareApi, ShareRefusal, type ShareRequest, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SimilarGamesOutcome, type SnapshotCurrency, type SnapshotItem, type StoreApi, type StoreOffersOutcome, type StoreSettlement, type TransportAdvert, type TransportKind, TransportRefusal, UNRELIABLE_CHANNEL_LABEL, type VibrationApi, type WalletVisibleOptions, type WornAvatar3d, asPlayerText, createBootTimeline, createGem, experimentSelection, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, text, webTransportAvailable };
@@ -1,2 +1,2 @@
1
- var GemWebSdkBridgeBundle=(function(){'use strict';var j="GemWebSdkHandshake";function ie(){return typeof document>"u"?void 0:document.readyState}var B=()=>Date.now();function N(n={}){let e=n.win??window,t=e,r=t[j];if(r!==void 0)return r;let o=n.readyState??ie,s=n.now??B,d=[],i=[],u=y=>{let c=y.data;!c||c.type!=="gem.handshake"||(d.length>=4&&(d.shift(),i.shift(),p.dropped+=1),d.push(y),i.push(s()));};e.addEventListener("message",u);let p={events:d,times:i,dropped:0,late:o()==="complete",uninstall(){e.removeEventListener("message",u);}};return t[j]=p,p}function W(n,e,t={}){let r=n[j];if(r===void 0)return null;let o=t.ttlMs??9500,s=t.now??B,d=r.events.splice(0),i=r.times?.splice(0),u=0,p=0,y=false,c=s()-o;for(let h=d.length-1;h>=0;h--){let R=i?.[h];if(R!==void 0&&R<c){p+=1;continue}if(u+=1,e(d[h])===true){y=true;break}}return r.uninstall(),{capture:r,delivered:u,stale:p,accepted:y}}var l="gem-web-bridge",S={min:1,max:1},le=65536,z=8,x=5e3,V=1024;var w=Object.create(null),P="__malformed";var F=Object.create(null),de=Object.freeze([["gem.asyncOpponents.","asyncOpponents"],["gem.vibration.","vibration"],["gem.viewport.","reservedAreas"],["gem.moments.","moments"],["gem.prefs.","audioChannels"],["gem.share.","shareRemap"]]);function C(n){let e=F[n];if(e!==void 0)return e;for(let[t,r]of de)if(n.startsWith(t))return r}function me(n){let e=/^([a-z][a-z0-9+.-]*):\/\/([a-z0-9.-]+|\[[0-9a-f:.]+\])(:([0-9]{1,5}))?$/i.exec(n);return e===null?false:e[4]===void 0||Number(e[4])<=65535}function ue(n){let e;try{e=new URL(n);}catch{return false}return e.username!==""||e.password!==""?false:e.protocol==="https:"?true:e.protocol==="http:"&&(e.hostname==="localhost"||e.hostname==="127.0.0.1")}function ce(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function ge(n){return /^[a-z_]+$/.test(n)}function pe(n){return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(n)||/^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/.test(n)&&!n.includes("--")}function D(n,e,t){if(e>z)return `nesting deeper than ${z}`;if(++t.nodes>x)return `more than ${x} values`;if(t.bytes>t.cap)return `over the ${t.cap} byte limit`;if(n==null)return t.bytes+=4,null;let r=typeof n;if(r==="boolean")return t.bytes+=5,null;if(r==="number")return t.bytes+=8,null;if(r==="string")return t.bytes+=n.length*3+2,null;if(r!=="object")return `${r} is not plain data`;let o=n;if(t.seen.has(o))return "a repeated or cyclic object reference";if(t.seen.add(o),Array.isArray(n)){if(n.length>V)return `an array of ${n.length} entries, over the ${V} limit`;t.bytes+=2;for(let i of n){let u=D(i,e+1,t);if(u)return u}return null}let s=Object.getPrototypeOf(n);if(s!==Object.prototype&&s!==null)return "a value that is not a plain object";t.bytes+=2;let d=n;for(let i in d){if(!Object.prototype.hasOwnProperty.call(d,i))continue;if(++t.nodes>x)return `more than ${x} values`;if(t.bytes+=i.length*3+4,t.bytes>t.cap)return `over the ${t.cap} byte limit`;let u=D(d[i],e+1,t);if(u)return u}return null}function ye(n,e=le){let t={nodes:0,bytes:0,seen:new Set,cap:e},r=D(n,0,t);return r?`message contains ${r}`:t.bytes>e?`message is over the ${e} byte limit`:null}var fe={origin:[me,"not a well-formed origin"],url:[ue,"not a safe absolute http(s) URL"],bcp47:[ce,"not a well-formed BCP 47 tag"],code:[ge,"not a code of lower-case letters and underscores"],gameRef:[pe,"not a game id or web address"]};function K(n,e,t){for(let r of e){let o=t===""?r[0]:`${t}.${r[0]}`,s=n[r[0]];if(s==null){if(r[1]<"a")continue;return `${o}: required`}let d=M(s,r,o);if(d)return d}return null}function M(n,e,t){let r=e[1].toLowerCase();switch(r){case "u":return typeof n=="boolean"?null:M(n,typeof n=="string"?[e[0],"s",e[2]]:[e[0],"n",e[3],e[4]],t);case "s":{if(typeof n!="string")return `${t}: expected string`;if(n.length>e[2])return `${t}: exceeds ${e[2]} characters`;if(e[3]){let[o,s]=fe[e[3]];if(!o(n))return `${t}: ${s}`}return null}case "n":case "i":return typeof n!="number"||!(r=="i"?Number.isInteger:Number.isFinite)(n)?`${t}: expected ${r=="i"?"integer":"number"}`:n<e[2]||n>e[3]?`${t}: out of range ${e[2]}..${e[3]}`:null;case "b":return typeof n=="boolean"?null:`${t}: expected boolean`;case "e":{let o=e[2];return o.includes(n)?null:`${t}: not one of ${o.join("|")}`}case "o":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:K(n,e[2],t);case "j":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected a plain object`:null;case "a":{if(!Array.isArray(n))return `${t}: expected array`;if(n.length>e[2])return `${t}: exceeds ${e[2]} items`;let o=e[3],s=`${t}[]`;for(let d of n){if(d==null){if(o[1]<"a")continue;return `${s}: required`}let i=M(d,o,s);if(i)return i}return null}default:return `${t}: unknown kind ${String(r)}`}}var Y=Object.create(null);function a(n,e,t,r,o){return w[n]=t,r&&(F[n]=r),Y[n]=s=>{let d=ye(s,o);if(d)return d;if(typeof s!="object"||s===null||Array.isArray(s))return "message: expected object";let i=s;return i.gem!==l?"gem: wrong protocol marker":i.type!==n?`type: expected ${n}`:K(i,e,"")}}var b=["","s",64],m=["requestId","s",64],G=["matchId","s",64],f=["reason","S",64,"code"],v=["outcome","e",["ok","declined","unavailable"]];a("gem.handshake",[["versions","o",[["min","i",1,1e3],["max","i",1,1e3]]],["capabilities","A",64,b],["embedder","s",2048,"origin"],["unbidden","B"]],30);a("gem.handshake.accept",[["v","i",1,1e3],["capabilities","A",64,b]],5);a("gem.token",[["token","s",4096],["requestId","S",64],["generation","i",0,2147483647],["apiBaseUrl","S",512,"url"],["playerId","s",64],["gameId","s",64],["channel","e",["dev","test","release"]],["gameVersion","S",64],["expiresAt","i",0,4102444800],["chainEndsAt","i",0,4102444800],["allowDevTools","B"]],30);a("gem.token.denied",[m,["retryable","b"],["retryAfterMs","I",0,36e5],["reason","e",["chain_exhausted","unavailable"]],["correlationId","s",64]],30);a("gem.player",[["untrusted","o",[["displayName","s",64],["displayTag","S",80],["displayHandle","s",80]]],["playerId","S",64],["discriminator","S",8],["avatarIconUrl","S",2048,"url"],["avatarIconId","S",64],["avatar3dId","S",64],["avatar3dModelUrl","S",2048,"url"],["avatar3dIconUrl","S",2048,"url"],["avatars3d","A",8,["","o",[["family","s",32],["id","s",64],["modelUrl","s",256,"url"],["iconUrl","s",256,"url"]]]],["badges","A",2,["","o",[["itemId","s",64],["iconUrl","s",2048,"url"]]]],["displayTag","s",8],["avatarUrl","S",2048,"url"],["boost","O",[["multipliers","a",8,["","o",[["currencyId","s",64],["currencySlug","s",32],["multiplierBp","i",1e4,1e6]]]],["expiresInDays","I",1,7]]]],12);a("gem.pause",[["paused","b"]],120);a("gem.prefs",[["reducedMotion","b"],["muted","b"],["showFrameStats","B"],["music","B"],["sounds","B"],["locale","s",35,"bcp47"],["recommended","O",[["volume","i",0,100],["batterySaver","b"],["keyboardLayout","e",["wasd","arrows"]],["gamepadConfirm","e",["south","east"]],["vibration","b"],["lookSensitivity","I",20,400],["gamepadLookSensitivity","I",20,400],["invertLookY","B"],["touchMovement","S",16,"code"],["graphicsQuality","S",16,"code"],["graphicsQualityAuto","B"],["colorHelp","B"]]]],60);a("gem.cohorts",[["cohorts","a",8,["","o",[["experimentId","s",36],["variantKey","s",32]]]]],12,"cohorts");a("gem.earnAllowanceChanged",[],30,"earnAllowance");a("gem.viewport",[["insets","o",[["top","i",0,4096],["right","i",0,4096],["bottom","i",0,4096],["left","i",0,4096]]],["reserved","A",4,["","o",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384],["control","O",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384]]]]]]],60,"viewport");a("gem.deviceSettings",[["settings","J"]],12,"deviceSettings");a("gem.willTerminate",[["reason","e",["grant_expiring","session_ended","navigating","kill_switch"]],["graceMs","i",0,6e4]],10);a("gem.roomEvent",[["event","e",["updated","match_started","match_ready","match_failed","version_stale"]],["roomId","s",64],["matchId","S",64],["version","I",0,2147483647],["reason","S",64],["platform","E",["universal","mobile"]]],120,"rooms");a("gem.socketState",[["connected","b"],["reason","E",["connecting","dropped","watchdog","terminal"]]],12,"socketState");a("gem.seatedEvent",[["roomId","s",64]],60,"partySeating");a("gem.autoStartFailedEvent",[["roomId","s",64],["code","s",64]],30,"autoStartFailure");a("gem.ticketEvent",[["event","e",["queued","matched","expired","cancelled","failed"]],["ticketId","s",64],["partySize","I",1,64],["queuedAt","I",0,4102444800],["expiresAt","I",0,4102444800],["reason","S",64],["roomId","S",64]],60,"ticketEvents");a("gem.signalEvent",[["event","e",["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]],G,["data","j"]],1800,"p2p");a("gem.relayDraining",[G,["clusterTargetId","s",64],["relayIps","a",16,b],["drainingSince","s",40],["deadline","s",40]],60,"p2pRelayDrain");a("gem.dedicatedEvent",[["event","e",["answer","error","matchEnded"]],G,["sdp","S",10240],["sessionId","S",64],["code","S",64],["message","S",256],["reason","S",64]],120,"dedicated");a("gem.partyResult",[m,["partyId","S",64]],30,"parties");a("gem.clusterTarget",[["clusterTargetId","s",64],["clusterTargetIds","A",3,b]],12,"clusterTarget");a("gem.graphicsRoutes",[["entries","a",32,["","o",[["gpu","s",32],["route","S",32],["host","S",32]]]]],12,"graphicsRoutes");a("gem.devtools",[["action","e",["open","close","toggle"]]],30,"devtools");a("gem.screenshot",[["maxWidth","i",1,7680],["maxHeight","i",1,4320]],6,"screenshot");a("gem.screenshot.denied",[["reason","e",["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]],["retryable","b"]],12,"screenshot");a("gem.requestContext",[],12,"feedbackContext");a("gem.gameContext",[["context","j"]],12,"feedbackContext");a("gem.signal",[["signal","e",["join","offer","answer","ice","migrationAck","hostUnreachable"]],G,["data","j"]],1200,"p2p");a("gem.dedicatedOffer",[G,["sdp","s",10240],["intent","e",["initial","ice_restart","full_reconnect"]]],60,"dedicated");a("gem.partyRequest",[m],12,"parties");a("gem.ready",[],5);a("gem.engaged",[],5,"engagement");a("gem.progress",[["loaded","i",0,1099511627776],["total","i",0,1099511627776]],600);a("gem.requestToken",[m,["reason","e",["initial","expiring","rejected"]]],12);a("gem.requestLocalServer",[m,["gameRoomId","s",64]],6,"localHost");a("gem.localServer",[m,["serverId","S",128]],30,"localHost");a("gem.localServer.denied",[m,["retryable","b"],["reason","e",["refused","unavailable"]]],30,"localHost");a("gem.exit",[["reason","S",64]],5);a("gem.openExternal",[["url","s",2048,"url"]],6);a("gem.requestFullscreen",[["enabled","b"]],30);a("gem.audioState",[["muted","b"]],120,"audioState");a("gem.rewardCue",[["currencySlug","s",32],["cueId","S",64],["expected","I",1,1e9],["origin","O",[["x","i",0,16384],["y","i",0,16384]]]],60,"rewardCue");a("gem.rewardPresentation",[["mode","e",["arcade","game"]]],12,"rewardPresentation");a("gem.walletDisplay",[["visible","b"],["currencies","A",8,b],["score","B"]],60,"walletDisplay");a("gem.controlsDeclare",[["uses","o",[["lookSensitivity","S",16,"code"],["gamepadLookSensitivity","S",16,"code"],["invertLookY","S",16,"code"],["touchMovement","S",16,"code"]]]],60,"controls");a("gem.menu",[["settings","b"],["items","A",4,["","o",[["id","s",32],["label","s",40]]]]],60,"gameMenu");a("gem.menuSelect",[["entry","e",["settings","item"]],["id","S",32]],60,"gameMenu");a("gem.gemCorner",[["corner","e",["top-left","top-right","bottom-left","bottom-right"]]],12,"gemCorner");a("gem.menuStyle",[["ground","S",7],["accent","S",7]],12,"menuStyle");a("gem.settingsDeclare",[["settings","a",8,["","o",[["id","s",40],["label","s",40],["kind","e",["toggle","slider","choice"]],["value","u",40,-1e6,1e6],["quick","B"],["icon","S",16,"code"],["min","N",-1e6,1e6],["max","N",-1e6,1e6],["step","N",0,1e6],["options","A",4,["","o",[["id","s",40],["label","s",40]]]]]]]],120,"gameSettings");a("gem.settingChange",[["id","s",40],["value","u",40,-1e6,1e6]],120,"gameSettings");a("gem.requestShare",[["requestId","S",64],["params","a",16,["","o",[["key","s",64],["value","s",512]]]]],6,"share");a("gem.shareResult",[m,["outcome","e",["accepted","refused"]],f,["key","S",64]],30,"shareResult");a("gem.requestAvatarPicker",[["tab","E",["2d","3d"]]],6,"avatarPicker");a("gem.vibrate",[["pattern","a",99,["","i",0,1e4]]],600,"vibration");a("gem.frameStats",[["fps","i",0,1e3],["frameTimeP95Ms","i",0,1e5],["counts","E",["pageFrames","gameDraws"]]],120,"frameStats");a("gem.portraitBorders",[["name","S",40]],60,"portraitBorders");a("gem.error",[["code","e",["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]],["message","S",256]],60);a("gem.requestPurchase",[m,["purchaseKind","e",["item","recipe"]],["targetId","s",64],["currencySlug","s",32],["quantity","I",1,10],["catalogId","S",64],["origin","E",["sheet","direct_refused"]]],12,"purchases");a("gem.requestAvatar3dPurchase",[m,["itemId","s",64],["currencySlug","s",32]],12,"avatar3dPurchases");a("gem.purchaseResult",[m,v,f,["purchaseId","S",64]],30,"purchases");a("gem.purchaseSettled",[["purchaseKind","e",["item","recipe"]],["targetId","s",64],["catalogId","S",64],["quantity","i",1,10],["purchaseId","S",64]],30,"purchaseSettled");a("gem.deviceSettings.put",[m,["settings","j"]],30,"deviceSettings");a("gem.deviceSettings.result",[m,["outcome","e",["stored","too_large","unavailable"]]],30,"deviceSettings");a("gem.requestAd",[m,["placement","s",32],["format","e",["interstitial","rewarded"]]],6,"ads");a("gem.adResult",[m,["outcome","e",["shown","no_ad","unavailable"]]],12,"ads");a("gem.signalMoment",[m,["kind","e",["level_end","run_end","match_end","menu_return","other_break"]],["placement","S",32],["wall","B"]],6,"moments");a("gem.momentResult",[m,["shown","b"]],12,"moments");a("gem.requestSignIn",[m],6,"signIn");a("gem.signInResult",[m,["outcome","e",["signed_in","declined","unavailable"]]],12,"signIn");a("gem.requestFriendChallenge",[m,["playerId","s",64],["template","s",64],["params","J"]],12,"friendChallenges");a("gem.friendChallengeResult",[m,["outcome","e",["accepted","cancelled","refused","unavailable","rate_limited","invalid"]],["code","S",64],["param","S",64],["channel","S",16],["configVersion","I",0,9007199254740991],["retryAfterMs","I",0,864e5],["detail","S",300]],30,"friendChallenges");a("gem.requestAppLinks",[m],12,"appLinks");a("gem.appLinksResult",[m,v,f,["arcade","O",[["store","e",["app_store","google_play"]]]],["game","O",[["store","e",["app_store","google_play"]]]]],30,"appLinks");a("gem.requestOpenApp",[m,["target","e",["arcade","game"]]],6,"appLinks");a("gem.openAppResult",[m,v,f],30,"appLinks");a("gem.requestOpenGame",[m,["ref","s",40,"gameRef"]],6,"openGame");a("gem.openGameResult",[m,v,f],30,"openGame");a("gem.requestSimilarGames",[m,["limit","I",1,24]],12,"openGame");a("gem.similarGamesResult",[m,v,f,["games","a",24,["","o",[["gameId","s",36,"gameRef"],["slug","S",40,"gameRef"],["iconUrl","s",1024,"url"],["capsuleLandscapeUrl","s",1024,"url"],["capsulePortraitUrl","s",1024,"url"],["previewVideoUrl","S",1024,"url"],["previewPosterUrl","S",1024,"url"],["untrusted","o",[["name","s",64],["tagline","s",64],["shortDescription","s",320],["tags","a",10,["","s",32]]]]]]]],30,"openGame",524288);a("gem.requestStoreOffers",[m],12,"store");a("gem.storeOffersResult",[m,v,f,["offers","a",32,["","o",[["skuId","s",64],["kind","e",["gem_pack","boost","pass","bundle"]],["name","s",80],["description","s",400],["imageUrl","S",1024,"url"],["priceDisplay","s",32],["grant","O",[["currency","s",32],["amount","i",1,1e9]]]]]]],30,"store",262144);a("gem.requestStorePurchase",[m,["skuId","s",64]],12,"store");a("gem.storePurchaseResult",[m,v,f],30,"store");a("gem.storePurchaseSettled",[["skuId","s",64]],30,"store");a("gem.requestStoreOfferSheet",[m,["skuId","s",64]],12,"storeOfferSheet");a("gem.storeOfferSheetResult",[m,v,f],30,"storeOfferSheet");var T=Object.freeze(Y);w.__malformed=60;Object.freeze(w);Object.freeze(F);var he=/^[a-z0-9][a-z0-9_-]{0,39}$/;function ve(n){return typeof n=="string"&&he.test(n)}function J(n){if(n===null||ve(n))return n;let e=typeof n=="string"?JSON.stringify(n.length>48?`${n.slice(0,48)}\u2026`:n):`a value of type ${typeof n}`;console.warn(`[gem] showPortraitBorders: ${e} is not a border name, so nothing was sent. A name is 1 to 40 of a-z, 0-9, _ and -, starting with a letter or digit, exactly as your store page declares it under media.portrait_borders. Pass null for no art.`);}function Q(n){return typeof n=="string"&&/^[\w-]{1,64}$/.test(n)}var $={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)},k=class{constructor(e=$){this.clock=e;}clock;tokens=new Map;lastRefill=new Map;allow(e){let t=w[e];if(t===void 0)return false;let r=this.clock.now(),o=this.lastRefill.get(e)??r,s=this.tokens.get(e)??t,d=Math.max(0,r-o),i=Math.min(t,s+d*t/6e4);return i<1?(this.tokens.set(e,i),this.lastRefill.set(e,r),false):(this.tokens.set(e,i-1),this.lastRefill.set(e,r),true)}};function q(n,e){return n.toLowerCase()===e.toLowerCase()}function I(n){let e=n.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}function X(n,e){if(typeof e!="string"||e==="")return false;let t,r;try{t=new URL(n),r=new URL(e);}catch{return false}return t.protocol!=="http:"&&t.protocol!=="https:"||r.protocol!=="http:"&&r.protocol!=="https:"||t.username!==""||t.password!==""||t.pathname!=="/"||t.search!==""||t.hash!==""||t.port===""?false:I(t.hostname)&&I(r.hostname)}function Z(n,e){if(n.min>n.max||e.min>e.max)return null;let t=Math.min(n.max,e.max),r=Math.max(n.min,e.min);return t>=r?t:null}var ne="[gem: use gem.text.toPlain()]",ee=new Set,te;function Re(n){try{if(ee.has(n))return;let e=globalThis.location;if(te??=!!e?.port&&I(e.hostname??""),!te)return;ee.add(n),console.warn(`[gem] ${n} is PlayerText, turned into a string: players see ${ne}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
2
- ${new Error().stack}`);}catch{}}var U=class{#e;#t;constructor(e,t="player text"){this.#e=e,this.#t=t,Object.freeze(this);}toString(){return Re(this.#t),ne}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function H(n,e){return new U(n,e)}function re(n){return Math.min(16384,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}function Se(n,e){if(n!==true)return {visible:false};let t=[],r=false;for(let o of Array.isArray(e)?e:[])o==="score"?r=true:typeof o=="string"&&o.length>0&&o.length<=64&&!t.includes(o)&&t.push(o);return !r&&t.length===0?{visible:true}:{visible:true,currencies:t.slice(0,8),score:r}}function we(n){let e=[];for(let t of Array.isArray(n)?n:[]){if(e.length===4)break;if(typeof t!="object"||t===null)continue;let{id:r,label:o}=t;typeof r!="string"||r.length===0||r.length>32||typeof o!="string"||o.trim().length===0||e.some(s=>s.id===r)||e.push({id:r,label:o.trim().slice(0,40)});}return e.length===0?{settings:false}:{settings:false,items:e}}function ae(n,e){return Math.min(e,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}function be(n){let e=n.untrusted,t=H(e.displayName,"gem.player.displayName"),r=e.displayTag||e.displayHandle,o=r?H(r,"gem.player.displayTag"):void 0,s=n.discriminator||n.displayTag,d=s&&/^[0-9]{1,8}$/.test(s)?s:void 0,i=n.avatarIconUrl||n.avatarUrl,u=/^[\da-f]{8}(-[\da-f]{4}){3}-[\da-f]{12}$/i,p=n.avatarIconId,y=n.avatar3dId,c={displayName:t,displayHandle:o??t,badges:(n.badges??[]).map(g=>({itemId:g.itemId,iconUrl:g.iconUrl}))};n.playerId&&(c.playerId=n.playerId),d&&(c.discriminator=d),o&&(c.displayTag=o),i&&(c.avatarIconUrl=c.avatarUrl=i),p&&u.test(p)&&(c.avatarIconId=p),y&&u.test(y)&&(c.avatar3dId=y),n.avatar3dModelUrl&&(c.avatar3dModelUrl=n.avatar3dModelUrl),n.avatar3dIconUrl&&(c.avatar3dIconUrl=n.avatar3dIconUrl),n.avatars3d&&(c.avatars3d=n.avatars3d.filter(g=>u.test(g.id)&&/^[a-z][a-z0-9_]*$/.test(g.family)).filter((g,A,L)=>L.findIndex(_=>_.family==g.family)==A).map(({family:g,id:A,modelUrl:L,iconUrl:_})=>({family:g,id:A,modelUrl:L,iconUrl:_})));let h=n.boost,R=(h?.multipliers??[]).map(g=>({currencyId:g.currencyId,currencySlug:g.currencySlug,multiplier:g.multiplierBp/1e4})),E=R.some(g=>g.multiplier>1);return c.boost=E&&h?.expiresInDays?{active:E,multipliers:R,expiresInDays:h.expiresInDays}:{active:E,multipliers:R},c}var Ge=1e4,ke=["appLinks","openGame","store","storeOfferSheet"],Oe=["token","pause","menuSelect","settingChange","prefs","cohorts","viewport","willTerminate","localServer","roomEvent","seatedEvent","autoStartFailedEvent","ticketEvent","socketState","signalEvent","relayDraining","dedicatedEvent","clusterTarget","graphicsRoutes","partyResult","purchaseResult","purchaseSettled","shareResult","deviceSettings","adResult","momentResult","signInResult","friendChallengeResult"],xe=new WeakMap;var O=class{constructor(e){this.options=e;if(e.expectedSource===void 0||e.expectedSource===null)throw new Error("GemFrame: expectedSource is required and must not be null \u2014 pass window.parent. The handshake transfers the MessagePort, and origin alone does not say WHICH document on that origin sent it.");this.expectedSource=e.expectedSource,this.clock=e.clock??$,this.inbound=new k(this.clock),this.outbound=new k(this.clock);}options;state="waiting";port=null;version=null;peerCapabilities=[];unbidden=false;engagedSent=false;readyPending=false;readySent=false;settleWaiters=[];clock;inbound;outbound;expectedSource;get currentState(){return this.state}get parentCapabilities(){return this.peerCapabilities}parentSupports(e){return this.peerCapabilities.includes(e)}get protocolVersion(){return this.version}get unbiddenLaunch(){return this.unbidden}handleWindowMessage(e){if(e.source!==this.expectedSource)return this.refuse(e,"handshake did not come from the expected embedder window"),false;if(!(this.options.allowedEmbedders.some(i=>q(i,e.origin))||X(e.origin,this.options.selfOrigin)||(xe.get(this)??[]).some(i=>q(i,e.origin))))return this.refuse(e,`embedder '${e.origin}' is not in allowedEmbedders`),this.state==="waiting"&&this.transition("refused"),false;if(this.state==="connected")return this.fail("handshake_duplicate","this document already has a port"),false;if(this.state!=="waiting")return false;let r=T["gem.handshake"]?.(e.data);if(r)return this.refuse(e,`malformed handshake: ${r}`),false;let o=e.data;if(!q(o.embedder,e.origin))return this.refuse(e,`handshake claims embedder '${o.embedder}' but arrived from '${e.origin}'`),false;let s=e.ports?.[0];if(!s)return this.refuse(e,"handshake transferred no MessagePort"),false;let d=Z(S,o.versions);return d===null?(s.onmessage=null,s.postMessage({gem:l,type:"gem.error",code:"version_mismatch",message:`frame supports v${S.min}..v${S.max}`}),s.close(),this.transition("refused"),this.options.onError?.("version_mismatch"),false):(this.port=s,this.version=d,s.onmessage=i=>this.receive(i.data,i.ports??[]),s.start?.(),this.peerCapabilities=o.capabilities??[],this.unbidden=o.unbidden===true,s.postMessage({gem:l,type:"gem.handshake.accept",v: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=Ge){return this.state!=="waiting"?Promise.resolve(this.state):new Promise(t=>{let r=s=>{this.clock.clearTimeout(o),t(s);},o=this.clock.setTimeout(()=>{let s=this.settleWaiters.indexOf(r);s>=0&&this.settleWaiters.splice(s,1),t(this.state);},e);this.settleWaiters.push(r);})}progress(e,t){this.send({gem:l,type:"gem.progress",loaded:e,total:t});}requestToken(e,t){this.send({gem:l,type:"gem.requestToken",requestId:e,reason:t});}requestLocalServer(e,t){return this.parentSupports("localHost")?(this.send({gem:l,type:"gem.requestLocalServer",requestId:e,gameRoomId:t}),true):false}exit(e){this.send(e===void 0?{gem:l,type:"gem.exit"}:{gem:l,type:"gem.exit",reason:e});}openExternal(e){this.send({gem:l,type:"gem.openExternal",url:e});}requestFullscreen(e){this.send({gem:l,type:"gem.requestFullscreen",enabled:e});}reportMuted(e){return this.gated("audioState")?(this.send({gem:l,type:"gem.audioState",muted:e}),true):false}reportEngaged(){return this.engagedSent||!this.gated("engagement")||!this.send({gem:l,type:"gem.engaged"})?false:(this.engagedSent=true,true)}cueReward(e){if(!this.gated("rewardCue"))return false;let t={gem:l,type:"gem.rewardCue",currencySlug:String(e.currencySlug).slice(0,32)};return Q(e.cueId)&&(t.cueId=e.cueId),e.expected!==void 0&&Number.isFinite(e.expected)&&e.expected>=1&&(t.expected=Math.min(1e9,Math.round(e.expected))),e.origin&&(t.origin={x:re(e.origin.x),y:re(e.origin.y)}),this.send(t),true}showPortraitBorders(e){let t=J(e);return t===void 0||!this.gated("portraitBorders")?false:this.send(t===null?{gem:l,type:"gem.portraitBorders"}:{gem:l,type:"gem.portraitBorders",name:t})}setWalletVisible(e,t){return this.gated("walletDisplay")?this.send({gem:l,type:"gem.walletDisplay",...Se(e,t?.only)}):false}setMenu(e){return this.gated("gameMenu")?this.send({gem:l,type:"gem.menu",...we(e)}):false}declareSettings(e){return this.gated("gameSettings")?this.send({gem:l,type:"gem.settingsDeclare",settings:e}):false}setGemCorner(e){return this.gated("gemCorner")?this.send({gem:l,type:"gem.gemCorner",corner:e}):false}setRewardPresentation(e){return this.gated("rewardPresentation")?this.send({gem:l,type:"gem.rewardPresentation",mode:e}):false}setMenuStyle(e){return this.gated("menuStyle")?this.send(e===null?{gem:l,type:"gem.menuStyle"}:{gem:l,type:"gem.menuStyle",ground:e.ground,accent:e.accent}):false}requestShare(e,t){return this.gated("share")?this.send({gem:l,type:"gem.requestShare",...t===void 0?{}:{requestId:t},params:e.map(({key:r,value:o})=>({key:r,value:o}))}):false}requestAvatarPicker(e){return this.gated("avatarPicker")?this.send({gem:l,type:"gem.requestAvatarPicker",...e==="2d"||e==="3d"?{tab:e}:{}}):false}requestVibrate(e){return this.gated("vibration")?this.send({gem:l,type:"gem.vibrate",pattern:[...e]}):false}reportFrameStats(e){return this.gated("frameStats")?(this.send({gem:l,type:"gem.frameStats",fps:ae(e.fps,1e3),frameTimeP95Ms:ae(e.frameTimeP95Ms,1e5),counts:e.counts==="gameDraws"?"gameDraws":"pageFrames"}),true):false}sendGameContext(e){return this.state!=="connected"?false:(this.send({gem:l,type:"gem.gameContext",context:e}),true)}signal(e,t,r){this.send({gem:l,type:"gem.signal",signal:e,matchId:t,data:r});}dedicatedOffer(e,t,r){this.send({gem:l,type:"gem.dedicatedOffer",matchId:e,sdp:t,intent:r});}requestParty(e){return this.send({gem:l,type:"gem.partyRequest",requestId:e})}requestPurchase(e,t,r,o,s,d,i){return this.send({gem:l,type:"gem.requestPurchase",requestId:e,purchaseKind:t,targetId:r,currencySlug:o,...s===void 0?{}:{quantity:s},...d===void 0?{}:{catalogId:d},...i===void 0?{}:{origin:i}})}requestAvatar3dPurchase(e,t,r){return this.parentSupports("avatar3dPurchases")?this.send({gem:l,type:"gem.requestAvatar3dPurchase",requestId:e,itemId:t,currencySlug:r}):false}putDeviceSettings(e,t){return this.send({gem:l,type:"gem.deviceSettings.put",requestId:e,settings:t})}requestAd(e,t,r){return this.send({gem:l,type:"gem.requestAd",requestId:e,placement:t,format:r})}signalMoment(e,t,r,o){return this.send({gem:l,type:"gem.signalMoment",requestId:e,kind:t,...r===void 0?{}:{placement:r},...o===true?{wall:true}:{}})}readyCalled(){return this.readySent||this.readyPending}requestSignIn(e){return this.send({gem:l,type:"gem.requestSignIn",requestId:e})}requestFriendChallenge(e,t,r,o){return this.send({gem:l,type:"gem.requestFriendChallenge",requestId:e,playerId:t,template:r,...o===void 0?{}:{params:o}})}requestArcade(e){return this.gated(C(e.type))&&this.send({gem:l,...e})}close(){this.port&&(this.port.onmessage=null,this.port.close(),this.port=null),this.state!=="refused"&&this.transition("closed");}transition(e){if(this.state!==e){this.state=e;for(let t of this.settleWaiters.splice(0))t(e);this.options.onStateChange?.(e);}}refuseMalformed(e,t){if(!this.inbound.allow(P)){this.options.onDropped?.(e,t);return}this.fail(e,t);}dropUnknownType(e){this.inbound.allow(P)&&this.options.onDropped?.("unsupported",`ignored unknown message type '${e}'`);}refuse(e,t){e.ports?.[0]?.close?.(),this.inbound.allow(P)&&this.options.onRefused?.(t);}fail(e,t){this.options.onError?.(e,t),this.state==="connected"&&this.port&&this.send({gem:l,type:"gem.error",code:e,...t===void 0?{}:{message:t}});}gated(e){return this.state==="connected"&&this.parentSupports(e)}send(e){if(this.state!=="connected"||!this.port)return this.options.onDropped?.("internal",`dropped ${String(e.type)} before connect`),false;let t=e.type;if(!this.outbound.allow(t))return this.options.onError?.("rate_limited",`frame exceeded its own limit for ${t}`),false;let r=T[t]?.(e);return r?(this.options.onError?.("internal",`refusing to send malformed ${t}: ${r}`),false):(this.port.postMessage(this.version===null?e:{...e,v:this.version}),true)}receive(e,t=[]){let r=false;try{r=this.dispatchInbound(e,t);}finally{r||oe(t);}}dispatchInbound(e,t){if(this.state!=="connected")return false;let r=typeof e=="object"&&e!==null?e.type:void 0;if(typeof r!="string")return this.refuseMalformed("invalid_message","message has no type"),false;let o=T[r];if(!o)return this.dropUnknownType(r),false;if(!this.inbound.allow(r))return this.fail("rate_limited",`parent exceeded the limit for ${r}`),false;let s=C(r);if(s!==void 0&&!this.options.capabilities?.includes(s))return this.fail("unsupported_capability",`${r} requires the '${s}' capability, which this frame did not advertise`),false;let d=o(e);if(d)return this.fail("invalid_message",`${r}: ${d}`),false;let i=e;if(i.v!==this.version)return this.fail("invalid_message",`${r}: expected v ${String(this.version)}`),false;switch(r){case "gem.earnAllowanceChanged":this.options.onEarnAllowanceChanged?.();break;case "gem.devtools":this.options.onDevtools?.(i.action);break;case "gem.requestContext":this.options.onRequestContext?.();break;case "gem.screenshot":{let u=t[0];if(!u){this.options.onError?.("invalid_message","gem.screenshot transferred no MessagePort");break}let p={maxWidth:i.maxWidth,maxHeight:i.maxHeight};if(!this.options.onScreenshot){u.close(),this.screenshotDenied("not_wired",false);break}return oe(t.slice(1)),this.options.onScreenshot(p,u,(y,c)=>this.screenshotDenied(y,c)),true}case "gem.token.denied":this.options.onTokenDenied?.(i);break;case "gem.localServer.denied":this.options.onLocalServerDenied?.(i);break;case "gem.player":{this.options.onPlayer?.(be(i));break}case "gem.deviceSettings.result":this.options.onDeviceSettingsResult?.(i);break;case "gem.error":this.options.onError?.(i.code,i.message);break;default:if(Oe.includes(r.slice(4))){this.options[`on${r[4].toUpperCase()}${r.slice(5)}`]?.(i);break}if(ke.includes(C(r))){this.options.onArcadeAnswer?.(i);break}this.fail("unsupported",`no frame handler for '${r}'`);}return false}screenshotDenied(e,t){this.send({gem:l,type:"gem.screenshot.denied",reason:e,retryable:t});}};function oe(n){for(let e of n)try{e?.close?.();}catch{}}N();function Pe(n){if((n.expectedSource??window.parent)===window)throw new Error("GemWebSdkBridge.connect: this document is not framed (window.parent === window), so there is no embedder to hand it a port. A game runs inside the Gem Arcade iframe; opening it directly will never complete a handshake.");let e=new O({...n,expectedSource:n.expectedSource??window.parent}),t=r=>{let o=e.handleWindowMessage({data:r.data,origin:r.origin,source:r.source,ports:r.ports});return o&&window.removeEventListener("message",t),o};return window.addEventListener("message",t),W(window,t),e}var se={connect:Pe,GemFrame:O,PROTOCOL:l,SUPPORTED_VERSIONS:S};window.GemWebSdkBridge=se;var xn=se;return xn;})();
1
+ var GemWebSdkBridgeBundle=(function(){'use strict';var j="GemWebSdkHandshake";function ie(){return typeof document>"u"?void 0:document.readyState}var B=()=>Date.now();function N(n={}){let e=n.win??window,t=e,r=t[j];if(r!==void 0)return r;let o=n.readyState??ie,s=n.now??B,m=[],i=[],u=y=>{let c=y.data;!c||c.type!=="gem.handshake"||(m.length>=4&&(m.shift(),i.shift(),p.dropped+=1),m.push(y),i.push(s()));};e.addEventListener("message",u);let p={events:m,times:i,dropped:0,late:o()==="complete",uninstall(){e.removeEventListener("message",u);}};return t[j]=p,p}function W(n,e,t={}){let r=n[j];if(r===void 0)return null;let o=t.ttlMs??9500,s=t.now??B,m=r.events.splice(0),i=r.times?.splice(0),u=0,p=0,y=false,c=s()-o;for(let h=m.length-1;h>=0;h--){let R=i?.[h];if(R!==void 0&&R<c){p+=1;continue}if(u+=1,e(m[h])===true){y=true;break}}return r.uninstall(),{capture:r,delivered:u,stale:p,accepted:y}}var l="gem-web-bridge",S={min:1,max:1},le=65536,z=8,x=5e3,V=1024;var w=Object.create(null),P="__malformed";var F=Object.create(null),de=Object.freeze([["gem.asyncOpponents.","asyncOpponents"],["gem.vibration.","vibration"],["gem.viewport.","reservedAreas"],["gem.moments.","moments"],["gem.prefs.","audioChannels"],["gem.share.","shareRemap"]]);function C(n){let e=F[n];if(e!==void 0)return e;for(let[t,r]of de)if(n.startsWith(t))return r}function me(n){let e=/^([a-z][a-z0-9+.-]*):\/\/([a-z0-9.-]+|\[[0-9a-f:.]+\])(:([0-9]{1,5}))?$/i.exec(n);return e===null?false:e[4]===void 0||Number(e[4])<=65535}function ue(n){let e;try{e=new URL(n);}catch{return false}return e.username!==""||e.password!==""?false:e.protocol==="https:"?true:e.protocol==="http:"&&(e.hostname==="localhost"||e.hostname==="127.0.0.1")}function ce(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function ge(n){return /^[a-z_]+$/.test(n)}function pe(n){return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(n)||/^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/.test(n)&&!n.includes("--")}function D(n,e,t){if(e>z)return `nesting deeper than ${z}`;if(++t.nodes>x)return `more than ${x} values`;if(t.bytes>t.cap)return `over the ${t.cap} byte limit`;if(n==null)return t.bytes+=4,null;let r=typeof n;if(r==="boolean")return t.bytes+=5,null;if(r==="number")return t.bytes+=8,null;if(r==="string")return t.bytes+=n.length*3+2,null;if(r!=="object")return `${r} is not plain data`;let o=n;if(t.seen.has(o))return "a repeated or cyclic object reference";if(t.seen.add(o),Array.isArray(n)){if(n.length>V)return `an array of ${n.length} entries, over the ${V} limit`;t.bytes+=2;for(let i of n){let u=D(i,e+1,t);if(u)return u}return null}let s=Object.getPrototypeOf(n);if(s!==Object.prototype&&s!==null)return "a value that is not a plain object";t.bytes+=2;let m=n;for(let i in m){if(!Object.prototype.hasOwnProperty.call(m,i))continue;if(++t.nodes>x)return `more than ${x} values`;if(t.bytes+=i.length*3+4,t.bytes>t.cap)return `over the ${t.cap} byte limit`;let u=D(m[i],e+1,t);if(u)return u}return null}function ye(n,e=le){let t={nodes:0,bytes:0,seen:new Set,cap:e},r=D(n,0,t);return r?`message contains ${r}`:t.bytes>e?`message is over the ${e} byte limit`:null}var fe={origin:[me,"not a well-formed origin"],url:[ue,"not a safe absolute http(s) URL"],bcp47:[ce,"not a well-formed BCP 47 tag"],code:[ge,"not a code of lower-case letters and underscores"],gameRef:[pe,"not a game id or web address"]};function K(n,e,t){for(let r of e){let o=t===""?r[0]:`${t}.${r[0]}`,s=n[r[0]];if(s==null){if(r[1]<"a")continue;return `${o}: required`}let m=M(s,r,o);if(m)return m}return null}function M(n,e,t){let r=e[1].toLowerCase();switch(r){case "u":return typeof n=="boolean"?null:M(n,typeof n=="string"?[e[0],"s",e[2]]:[e[0],"n",e[3],e[4]],t);case "s":{if(typeof n!="string")return `${t}: expected string`;if(n.length>e[2])return `${t}: exceeds ${e[2]} characters`;if(e[3]){let[o,s]=fe[e[3]];if(!o(n))return `${t}: ${s}`}return null}case "n":case "i":return typeof n!="number"||!(r=="i"?Number.isInteger:Number.isFinite)(n)?`${t}: expected ${r=="i"?"integer":"number"}`:n<e[2]||n>e[3]?`${t}: out of range ${e[2]}..${e[3]}`:null;case "b":return typeof n=="boolean"?null:`${t}: expected boolean`;case "e":{let o=e[2];return o.includes(n)?null:`${t}: not one of ${o.join("|")}`}case "o":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:K(n,e[2],t);case "j":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected a plain object`:null;case "a":{if(!Array.isArray(n))return `${t}: expected array`;if(n.length>e[2])return `${t}: exceeds ${e[2]} items`;let o=e[3],s=`${t}[]`;for(let m of n){if(m==null){if(o[1]<"a")continue;return `${s}: required`}let i=M(m,o,s);if(i)return i}return null}default:return `${t}: unknown kind ${String(r)}`}}var Y=Object.create(null);function a(n,e,t,r,o){return w[n]=t,r&&(F[n]=r),Y[n]=s=>{let m=ye(s,o);if(m)return m;if(typeof s!="object"||s===null||Array.isArray(s))return "message: expected object";let i=s;return i.gem!==l?"gem: wrong protocol marker":i.type!==n?`type: expected ${n}`:K(i,e,"")}}var G=["","s",64],d=["requestId","s",64],b=["matchId","s",64],f=["reason","S",64,"code"],v=["outcome","e",["ok","declined","unavailable"]];a("gem.handshake",[["versions","o",[["min","i",1,1e3],["max","i",1,1e3]]],["capabilities","A",64,G],["embedder","s",2048,"origin"],["unbidden","B"]],30);a("gem.handshake.accept",[["v","i",1,1e3],["capabilities","A",64,G]],5);a("gem.token",[["token","s",4096],["requestId","S",64],["generation","i",0,2147483647],["apiBaseUrl","S",512,"url"],["playerId","s",64],["gameId","s",64],["channel","e",["dev","test","release"]],["gameVersion","S",64],["expiresAt","i",0,4102444800],["chainEndsAt","i",0,4102444800],["allowDevTools","B"]],30);a("gem.token.denied",[d,["retryable","b"],["retryAfterMs","I",0,36e5],["reason","e",["chain_exhausted","unavailable"]],["correlationId","s",64]],30);a("gem.player",[["untrusted","o",[["displayName","s",64],["displayTag","S",80],["displayHandle","s",80]]],["playerId","S",64],["discriminator","S",8],["avatarIconUrl","S",2048,"url"],["avatarIconId","S",64],["avatar3dId","S",64],["avatar3dModelUrl","S",2048,"url"],["avatar3dIconUrl","S",2048,"url"],["avatars3d","A",8,["","o",[["family","s",32],["id","s",64],["modelUrl","s",256,"url"],["iconUrl","s",256,"url"]]]],["badges","A",2,["","o",[["itemId","s",64],["iconUrl","s",2048,"url"]]]],["displayTag","s",8],["avatarUrl","S",2048,"url"],["boost","O",[["multipliers","a",8,["","o",[["currencyId","s",64],["currencySlug","s",32],["multiplierBp","i",1e4,1e6]]]],["expiresInDays","I",1,7]]]],12);a("gem.pause",[["paused","b"]],120);a("gem.prefs",[["reducedMotion","b"],["muted","b"],["showFrameStats","B"],["music","B"],["sounds","B"],["locale","s",35,"bcp47"],["recommended","O",[["volume","i",0,100],["batterySaver","b"],["keyboardLayout","e",["wasd","arrows"]],["gamepadConfirm","e",["south","east"]],["vibration","b"],["lookSensitivity","I",20,400],["gamepadLookSensitivity","I",20,400],["invertLookY","B"],["touchMovement","S",16,"code"],["graphicsQuality","S",16,"code"],["graphicsQualityAuto","B"],["colorHelp","B"]]]],60);a("gem.cohorts",[["cohorts","a",8,["","o",[["experimentId","s",36],["variantKey","s",32]]]]],12,"cohorts");a("gem.earnAllowanceChanged",[],30,"earnAllowance");a("gem.inventoryChanged",[],30,"inventoryChanged");a("gem.viewport",[["insets","o",[["top","i",0,4096],["right","i",0,4096],["bottom","i",0,4096],["left","i",0,4096]]],["reserved","A",4,["","o",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384],["control","O",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384]]]]]]],60,"viewport");a("gem.deviceSettings",[["settings","J"]],12,"deviceSettings");a("gem.willTerminate",[["reason","e",["grant_expiring","session_ended","navigating","kill_switch"]],["graceMs","i",0,6e4]],10);a("gem.roomEvent",[["event","e",["updated","match_started","match_ready","match_failed","version_stale"]],["roomId","s",64],["matchId","S",64],["version","I",0,2147483647],["reason","S",64],["platform","E",["universal","mobile"]]],120,"rooms");a("gem.socketState",[["connected","b"],["reason","E",["connecting","dropped","watchdog","terminal"]]],12,"socketState");a("gem.seatedEvent",[["roomId","s",64]],60,"partySeating");a("gem.autoStartFailedEvent",[["roomId","s",64],["code","s",64]],30,"autoStartFailure");a("gem.ticketEvent",[["event","e",["queued","matched","expired","cancelled","failed"]],["ticketId","s",64],["partySize","I",1,64],["queuedAt","I",0,4102444800],["expiresAt","I",0,4102444800],["reason","S",64],["roomId","S",64]],60,"ticketEvents");a("gem.signalEvent",[["event","e",["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]],b,["data","j"]],1800,"p2p");a("gem.relayDraining",[b,["clusterTargetId","s",64],["relayIps","a",16,G],["drainingSince","s",40],["deadline","s",40]],60,"p2pRelayDrain");a("gem.dedicatedEvent",[["event","e",["answer","error","matchEnded"]],b,["sdp","S",10240],["sessionId","S",64],["code","S",64],["message","S",256],["reason","S",64]],120,"dedicated");a("gem.partyResult",[d,["partyId","S",64]],30,"parties");a("gem.clusterTarget",[["clusterTargetId","s",64],["clusterTargetIds","A",3,G]],12,"clusterTarget");a("gem.graphicsRoutes",[["entries","a",32,["","o",[["gpu","s",32],["route","S",32],["host","S",32]]]]],12,"graphicsRoutes");a("gem.devtools",[["action","e",["open","close","toggle"]]],30,"devtools");a("gem.screenshot",[["maxWidth","i",1,7680],["maxHeight","i",1,4320]],6,"screenshot");a("gem.screenshot.denied",[["reason","e",["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]],["retryable","b"]],12,"screenshot");a("gem.requestContext",[],12,"feedbackContext");a("gem.gameContext",[["context","j"]],12,"feedbackContext");a("gem.signal",[["signal","e",["join","offer","answer","ice","migrationAck","hostUnreachable"]],b,["data","j"]],1200,"p2p");a("gem.dedicatedOffer",[b,["sdp","s",10240],["intent","e",["initial","ice_restart","full_reconnect"]]],60,"dedicated");a("gem.partyRequest",[d],12,"parties");a("gem.ready",[],5);a("gem.engaged",[],5,"engagement");a("gem.progress",[["loaded","i",0,1099511627776],["total","i",0,1099511627776]],600);a("gem.requestToken",[d,["reason","e",["initial","expiring","rejected"]]],12);a("gem.requestLocalServer",[d,["gameRoomId","s",64]],6,"localHost");a("gem.localServer",[d,["serverId","S",128]],30,"localHost");a("gem.localServer.denied",[d,["retryable","b"],["reason","e",["refused","unavailable"]]],30,"localHost");a("gem.exit",[["reason","S",64]],5);a("gem.openExternal",[["url","s",2048,"url"]],6);a("gem.requestFullscreen",[["enabled","b"]],30);a("gem.audioState",[["muted","b"]],120,"audioState");a("gem.rewardCue",[["currencySlug","s",32],["cueId","S",64],["expected","I",1,1e9],["origin","O",[["x","i",0,16384],["y","i",0,16384]]]],60,"rewardCue");a("gem.rewardPresentation",[["mode","e",["arcade","game"]]],12,"rewardPresentation");a("gem.walletDisplay",[["visible","b"],["currencies","A",8,G],["score","B"]],60,"walletDisplay");a("gem.controlsDeclare",[["uses","o",[["lookSensitivity","S",16,"code"],["gamepadLookSensitivity","S",16,"code"],["invertLookY","S",16,"code"],["touchMovement","S",16,"code"]]]],60,"controls");a("gem.menu",[["settings","b"],["items","A",4,["","o",[["id","s",32],["label","s",40]]]]],60,"gameMenu");a("gem.menuSelect",[["entry","e",["settings","item"]],["id","S",32]],60,"gameMenu");a("gem.gemCorner",[["corner","e",["top-left","top-right","bottom-left","bottom-right"]]],12,"gemCorner");a("gem.menuStyle",[["ground","S",7],["accent","S",7]],12,"menuStyle");a("gem.settingsDeclare",[["settings","a",8,["","o",[["id","s",40],["label","s",40],["kind","e",["toggle","slider","choice"]],["value","u",40,-1e6,1e6],["quick","B"],["icon","S",16,"code"],["min","N",-1e6,1e6],["max","N",-1e6,1e6],["step","N",0,1e6],["options","A",4,["","o",[["id","s",40],["label","s",40]]]]]]]],120,"gameSettings");a("gem.settingChange",[["id","s",40],["value","u",40,-1e6,1e6]],120,"gameSettings");a("gem.requestShare",[["requestId","S",64],["params","a",16,["","o",[["key","s",64],["value","s",512]]]]],6,"share");a("gem.shareResult",[d,["outcome","e",["accepted","refused"]],f,["key","S",64]],30,"shareResult");a("gem.requestAvatarPicker",[["tab","E",["2d","3d"]]],6,"avatarPicker");a("gem.vibrate",[["pattern","a",99,["","i",0,1e4]]],600,"vibration");a("gem.frameStats",[["fps","i",0,1e3],["frameTimeP95Ms","i",0,1e5],["counts","E",["pageFrames","gameDraws"]]],120,"frameStats");a("gem.portraitBorders",[["name","S",40]],60,"portraitBorders");a("gem.error",[["code","e",["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]],["message","S",256]],60);a("gem.requestPurchase",[d,["purchaseKind","e",["item","recipe"]],["targetId","s",64],["currencySlug","s",32],["quantity","I",1,10],["catalogId","S",64],["origin","E",["sheet","direct_refused"]]],12,"purchases");a("gem.requestAvatar3dPurchase",[d,["itemId","s",64],["currencySlug","s",32]],12,"avatar3dPurchases");a("gem.purchaseResult",[d,v,f,["purchaseId","S",64]],30,"purchases");a("gem.purchaseSettled",[["purchaseKind","e",["item","recipe"]],["targetId","s",64],["catalogId","S",64],["quantity","i",1,10],["purchaseId","S",64]],30,"purchaseSettled");a("gem.deviceSettings.put",[d,["settings","j"]],30,"deviceSettings");a("gem.deviceSettings.result",[d,["outcome","e",["stored","too_large","unavailable"]]],30,"deviceSettings");a("gem.requestAd",[d,["placement","s",32],["format","e",["interstitial","rewarded"]]],6,"ads");a("gem.adResult",[d,["outcome","e",["shown","no_ad","unavailable"]]],12,"ads");a("gem.signalMoment",[d,["kind","e",["level_end","run_end","match_end","menu_return","other_break"]],["placement","S",32],["wall","B"]],6,"moments");a("gem.momentResult",[d,["shown","b"]],12,"moments");a("gem.requestSignIn",[d],6,"signIn");a("gem.signInResult",[d,["outcome","e",["signed_in","declined","unavailable"]]],12,"signIn");a("gem.requestFriendChallenge",[d,["playerId","s",64],["template","s",64],["params","J"]],12,"friendChallenges");a("gem.friendChallengeResult",[d,["outcome","e",["accepted","cancelled","refused","unavailable","rate_limited","invalid"]],["code","S",64],["param","S",64],["channel","S",16],["configVersion","I",0,9007199254740991],["retryAfterMs","I",0,864e5],["detail","S",300]],30,"friendChallenges");a("gem.requestPlayInvite",[d,["params","A",16,["","o",[["key","s",64],["value","s",512]]]]],6,"playInvites");a("gem.playInviteResult",[d,["shown","b"]],12,"playInvites");a("gem.inviteParams",[["params","A",16,["","o",[["key","s",64],["value","s",512]]]]],30,"playInvites");a("gem.requestAppLinks",[d],12,"appLinks");a("gem.appLinksResult",[d,v,f,["arcade","O",[["store","e",["app_store","google_play"]]]],["game","O",[["store","e",["app_store","google_play"]]]]],30,"appLinks");a("gem.requestOpenApp",[d,["target","e",["arcade","game"]]],6,"appLinks");a("gem.openAppResult",[d,v,f],30,"appLinks");a("gem.requestOpenGame",[d,["ref","s",40,"gameRef"]],6,"openGame");a("gem.openGameResult",[d,v,f],30,"openGame");a("gem.requestSimilarGames",[d,["limit","I",1,24]],12,"openGame");a("gem.similarGamesResult",[d,v,f,["games","a",24,["","o",[["gameId","s",36,"gameRef"],["slug","S",40,"gameRef"],["iconUrl","s",1024,"url"],["capsuleLandscapeUrl","s",1024,"url"],["capsulePortraitUrl","s",1024,"url"],["previewVideoUrl","S",1024,"url"],["previewPosterUrl","S",1024,"url"],["untrusted","o",[["name","s",64],["tagline","s",64],["shortDescription","s",320],["tags","a",10,["","s",32]]]]]]]],30,"openGame",524288);a("gem.requestStoreOffers",[d],12,"store");a("gem.storeOffersResult",[d,v,f,["offers","a",32,["","o",[["skuId","s",64],["kind","e",["gem_pack","boost","pass","bundle"]],["name","s",80],["description","s",400],["imageUrl","S",1024,"url"],["priceDisplay","s",32],["grant","O",[["currency","s",32],["amount","i",1,1e9]]]]]]],30,"store",262144);a("gem.requestStorePurchase",[d,["skuId","s",64]],12,"store");a("gem.storePurchaseResult",[d,v,f],30,"store");a("gem.storePurchaseSettled",[["skuId","s",64]],30,"store");a("gem.requestStoreOfferSheet",[d,["skuId","s",64]],12,"storeOfferSheet");a("gem.storeOfferSheetResult",[d,v,f],30,"storeOfferSheet");var I=Object.freeze(Y);w.__malformed=60;Object.freeze(w);Object.freeze(F);var he=/^[a-z0-9][a-z0-9_-]{0,39}$/;function ve(n){return typeof n=="string"&&he.test(n)}function J(n){if(n===null||ve(n))return n;let e=typeof n=="string"?JSON.stringify(n.length>48?`${n.slice(0,48)}\u2026`:n):`a value of type ${typeof n}`;console.warn(`[gem] showPortraitBorders: ${e} is not a border name, so nothing was sent. A name is 1 to 40 of a-z, 0-9, _ and -, starting with a letter or digit, exactly as your store page declares it under media.portrait_borders. Pass null for no art.`);}function Q(n){return typeof n=="string"&&/^[\w-]{1,64}$/.test(n)}var $={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)},O=class{constructor(e=$){this.clock=e;}clock;tokens=new Map;lastRefill=new Map;allow(e){let t=w[e];if(t===void 0)return false;let r=this.clock.now(),o=this.lastRefill.get(e)??r,s=this.tokens.get(e)??t,m=Math.max(0,r-o),i=Math.min(t,s+m*t/6e4);return i<1?(this.tokens.set(e,i),this.lastRefill.set(e,r),false):(this.tokens.set(e,i-1),this.lastRefill.set(e,r),true)}};function q(n,e){return n.toLowerCase()===e.toLowerCase()}function T(n){let e=n.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}function X(n,e){if(typeof e!="string"||e==="")return false;let t,r;try{t=new URL(n),r=new URL(e);}catch{return false}return t.protocol!=="http:"&&t.protocol!=="https:"||r.protocol!=="http:"&&r.protocol!=="https:"||t.username!==""||t.password!==""||t.pathname!=="/"||t.search!==""||t.hash!==""||t.port===""?false:T(t.hostname)&&T(r.hostname)}function Z(n,e){if(n.min>n.max||e.min>e.max)return null;let t=Math.min(n.max,e.max),r=Math.max(n.min,e.min);return t>=r?t:null}var ne="[gem: use gem.text.toPlain()]",ee=new Set,te;function Re(n){try{if(ee.has(n))return;let e=globalThis.location;if(te??=!!e?.port&&T(e.hostname??""),!te)return;ee.add(n),console.warn(`[gem] ${n} is PlayerText, turned into a string: players see ${ne}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
2
+ ${new Error().stack}`);}catch{}}var U=class{#e;#t;constructor(e,t="player text"){this.#e=e,this.#t=t,Object.freeze(this);}toString(){return Re(this.#t),ne}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function H(n,e){return new U(n,e)}function re(n){return Math.min(16384,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}function Se(n,e){if(n!==true)return {visible:false};let t=[],r=false;for(let o of Array.isArray(e)?e:[])o==="score"?r=true:typeof o=="string"&&o.length>0&&o.length<=64&&!t.includes(o)&&t.push(o);return !r&&t.length===0?{visible:true}:{visible:true,currencies:t.slice(0,8),score:r}}function we(n){let e=[];for(let t of Array.isArray(n)?n:[]){if(e.length===4)break;if(typeof t!="object"||t===null)continue;let{id:r,label:o}=t;typeof r!="string"||r.length===0||r.length>32||typeof o!="string"||o.trim().length===0||e.some(s=>s.id===r)||e.push({id:r,label:o.trim().slice(0,40)});}return e.length===0?{settings:false}:{settings:false,items:e}}function ae(n,e){return Math.min(e,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}function Ge(n){let e=n.untrusted,t=H(e.displayName,"gem.player.displayName"),r=e.displayTag||e.displayHandle,o=r?H(r,"gem.player.displayTag"):void 0,s=n.discriminator||n.displayTag,m=s&&/^[0-9]{1,8}$/.test(s)?s:void 0,i=n.avatarIconUrl||n.avatarUrl,u=/^[\da-f]{8}(-[\da-f]{4}){3}-[\da-f]{12}$/i,p=n.avatarIconId,y=n.avatar3dId,c={displayName:t,displayHandle:o??t,badges:(n.badges??[]).map(g=>({itemId:g.itemId,iconUrl:g.iconUrl}))};n.playerId&&(c.playerId=n.playerId),m&&(c.discriminator=m),o&&(c.displayTag=o),i&&(c.avatarIconUrl=c.avatarUrl=i),p&&u.test(p)&&(c.avatarIconId=p),y&&u.test(y)&&(c.avatar3dId=y),n.avatar3dModelUrl&&(c.avatar3dModelUrl=n.avatar3dModelUrl),n.avatar3dIconUrl&&(c.avatar3dIconUrl=n.avatar3dIconUrl),n.avatars3d&&(c.avatars3d=n.avatars3d.filter(g=>u.test(g.id)&&/^[a-z][a-z0-9_]*$/.test(g.family)).filter((g,E,L)=>L.findIndex(_=>_.family==g.family)==E).map(({family:g,id:E,modelUrl:L,iconUrl:_})=>({family:g,id:E,modelUrl:L,iconUrl:_})));let h=n.boost,R=(h?.multipliers??[]).map(g=>({currencyId:g.currencyId,currencySlug:g.currencySlug,multiplier:g.multiplierBp/1e4})),A=R.some(g=>g.multiplier>1);return c.boost=A&&h?.expiresInDays?{active:A,multipliers:R,expiresInDays:h.expiresInDays}:{active:A,multipliers:R},c}var be=1e4,Oe=["appLinks","openGame","store","storeOfferSheet"],ke=["token","pause","menuSelect","settingChange","prefs","cohorts","viewport","willTerminate","localServer","roomEvent","seatedEvent","autoStartFailedEvent","ticketEvent","socketState","signalEvent","relayDraining","dedicatedEvent","clusterTarget","graphicsRoutes","partyResult","purchaseResult","purchaseSettled","inventoryChanged","shareResult","deviceSettings","adResult","momentResult","signInResult","friendChallengeResult","playInviteResult"],xe=new WeakMap;var k=class{constructor(e){this.options=e;if(e.expectedSource===void 0||e.expectedSource===null)throw new Error("GemFrame: expectedSource is required and must not be null \u2014 pass window.parent. The handshake transfers the MessagePort, and origin alone does not say WHICH document on that origin sent it.");this.expectedSource=e.expectedSource,this.clock=e.clock??$,this.inbound=new O(this.clock),this.outbound=new O(this.clock);}options;state="waiting";port=null;version=null;peerCapabilities=[];unbidden=false;engagedSent=false;readyPending=false;readySent=false;settleWaiters=[];clock;inbound;outbound;expectedSource;get currentState(){return this.state}get parentCapabilities(){return this.peerCapabilities}parentSupports(e){return this.peerCapabilities.includes(e)}get protocolVersion(){return this.version}get unbiddenLaunch(){return this.unbidden}handleWindowMessage(e){if(e.source!==this.expectedSource)return this.refuse(e,"handshake did not come from the expected embedder window"),false;if(!(this.options.allowedEmbedders.some(i=>q(i,e.origin))||X(e.origin,this.options.selfOrigin)||(xe.get(this)??[]).some(i=>q(i,e.origin))))return this.refuse(e,`embedder '${e.origin}' is not in allowedEmbedders`),this.state==="waiting"&&this.transition("refused"),false;if(this.state==="connected")return this.fail("handshake_duplicate","this document already has a port"),false;if(this.state!=="waiting")return false;let r=I["gem.handshake"]?.(e.data);if(r)return this.refuse(e,`malformed handshake: ${r}`),false;let o=e.data;if(!q(o.embedder,e.origin))return this.refuse(e,`handshake claims embedder '${o.embedder}' but arrived from '${e.origin}'`),false;let s=e.ports?.[0];if(!s)return this.refuse(e,"handshake transferred no MessagePort"),false;let m=Z(S,o.versions);return m===null?(s.onmessage=null,s.postMessage({gem:l,type:"gem.error",code:"version_mismatch",message:`frame supports v${S.min}..v${S.max}`}),s.close(),this.transition("refused"),this.options.onError?.("version_mismatch"),false):(this.port=s,this.version=m,s.onmessage=i=>this.receive(i.data,i.ports??[]),s.start?.(),this.peerCapabilities=o.capabilities??[],this.unbidden=o.unbidden===true,s.postMessage({gem:l,type:"gem.handshake.accept",v:m,...this.options.capabilities===void 0?{}:{capabilities:[...this.options.capabilities]}}),this.transition("connected"),this.readyPending&&(this.readyPending=false,this.ready()),true)}ready(){if(this.state!=="connected"||!this.port){this.readyPending=true;return}if(this.readySent){this.options.onDropped?.("internal","gem.ready was already sent; duplicate suppressed");return}this.readySent=true,this.send({gem:l,type:"gem.ready"});}settled(e=be){return this.state!=="waiting"?Promise.resolve(this.state):new Promise(t=>{let r=s=>{this.clock.clearTimeout(o),t(s);},o=this.clock.setTimeout(()=>{let s=this.settleWaiters.indexOf(r);s>=0&&this.settleWaiters.splice(s,1),t(this.state);},e);this.settleWaiters.push(r);})}progress(e,t){this.send({gem:l,type:"gem.progress",loaded:e,total:t});}requestToken(e,t){this.send({gem:l,type:"gem.requestToken",requestId:e,reason:t});}requestLocalServer(e,t){return this.parentSupports("localHost")?(this.send({gem:l,type:"gem.requestLocalServer",requestId:e,gameRoomId:t}),true):false}exit(e){this.send(e===void 0?{gem:l,type:"gem.exit"}:{gem:l,type:"gem.exit",reason:e});}openExternal(e){this.send({gem:l,type:"gem.openExternal",url:e});}requestFullscreen(e){this.send({gem:l,type:"gem.requestFullscreen",enabled:e});}reportMuted(e){return this.gated("audioState")?(this.send({gem:l,type:"gem.audioState",muted:e}),true):false}reportEngaged(){return this.engagedSent||!this.gated("engagement")||!this.send({gem:l,type:"gem.engaged"})?false:(this.engagedSent=true,true)}cueReward(e){if(!this.gated("rewardCue"))return false;let t={gem:l,type:"gem.rewardCue",currencySlug:String(e.currencySlug).slice(0,32)};return Q(e.cueId)&&(t.cueId=e.cueId),e.expected!==void 0&&Number.isFinite(e.expected)&&e.expected>=1&&(t.expected=Math.min(1e9,Math.round(e.expected))),e.origin&&(t.origin={x:re(e.origin.x),y:re(e.origin.y)}),this.send(t),true}showPortraitBorders(e){let t=J(e);return t===void 0||!this.gated("portraitBorders")?false:this.send(t===null?{gem:l,type:"gem.portraitBorders"}:{gem:l,type:"gem.portraitBorders",name:t})}setWalletVisible(e,t){return this.gated("walletDisplay")?this.send({gem:l,type:"gem.walletDisplay",...Se(e,t?.only)}):false}setMenu(e){return this.gated("gameMenu")?this.send({gem:l,type:"gem.menu",...we(e)}):false}declareSettings(e){return this.gated("gameSettings")?this.send({gem:l,type:"gem.settingsDeclare",settings:e}):false}setGemCorner(e){return this.gated("gemCorner")?this.send({gem:l,type:"gem.gemCorner",corner:e}):false}setRewardPresentation(e){return this.gated("rewardPresentation")?this.send({gem:l,type:"gem.rewardPresentation",mode:e}):false}setMenuStyle(e){return this.gated("menuStyle")?this.send(e===null?{gem:l,type:"gem.menuStyle"}:{gem:l,type:"gem.menuStyle",ground:e.ground,accent:e.accent}):false}requestShare(e,t){return this.gated("share")?this.send({gem:l,type:"gem.requestShare",...t===void 0?{}:{requestId:t},params:e.map(({key:r,value:o})=>({key:r,value:o}))}):false}requestAvatarPicker(e){return this.gated("avatarPicker")?this.send({gem:l,type:"gem.requestAvatarPicker",...e==="2d"||e==="3d"?{tab:e}:{}}):false}requestVibrate(e){return this.gated("vibration")?this.send({gem:l,type:"gem.vibrate",pattern:[...e]}):false}reportFrameStats(e){return this.gated("frameStats")?(this.send({gem:l,type:"gem.frameStats",fps:ae(e.fps,1e3),frameTimeP95Ms:ae(e.frameTimeP95Ms,1e5),counts:e.counts==="gameDraws"?"gameDraws":"pageFrames"}),true):false}sendGameContext(e){return this.state!=="connected"?false:(this.send({gem:l,type:"gem.gameContext",context:e}),true)}signal(e,t,r){this.send({gem:l,type:"gem.signal",signal:e,matchId:t,data:r});}dedicatedOffer(e,t,r){this.send({gem:l,type:"gem.dedicatedOffer",matchId:e,sdp:t,intent:r});}requestParty(e){return this.send({gem:l,type:"gem.partyRequest",requestId:e})}requestPurchase(e,t,r,o,s,m,i){return this.send({gem:l,type:"gem.requestPurchase",requestId:e,purchaseKind:t,targetId:r,currencySlug:o,...s===void 0?{}:{quantity:s},...m===void 0?{}:{catalogId:m},...i===void 0?{}:{origin:i}})}requestAvatar3dPurchase(e,t,r){return this.parentSupports("avatar3dPurchases")?this.send({gem:l,type:"gem.requestAvatar3dPurchase",requestId:e,itemId:t,currencySlug:r}):false}putDeviceSettings(e,t){return this.send({gem:l,type:"gem.deviceSettings.put",requestId:e,settings:t})}requestAd(e,t,r){return this.send({gem:l,type:"gem.requestAd",requestId:e,placement:t,format:r})}signalMoment(e,t,r,o){return this.send({gem:l,type:"gem.signalMoment",requestId:e,kind:t,...r===void 0?{}:{placement:r},...o===true?{wall:true}:{}})}readyCalled(){return this.readySent||this.readyPending}requestSignIn(e){return this.send({gem:l,type:"gem.requestSignIn",requestId:e})}requestFriendChallenge(e,t,r,o){return this.send({gem:l,type:"gem.requestFriendChallenge",requestId:e,playerId:t,template:r,...o===void 0?{}:{params:o}})}requestArcade(e){return this.gated(C(e.type))&&this.send({gem:l,...e})}close(){this.port&&(this.port.onmessage=null,this.port.close(),this.port=null),this.state!=="refused"&&this.transition("closed");}transition(e){if(this.state!==e){this.state=e;for(let t of this.settleWaiters.splice(0))t(e);this.options.onStateChange?.(e);}}refuseMalformed(e,t){if(!this.inbound.allow(P)){this.options.onDropped?.(e,t);return}this.fail(e,t);}dropUnknownType(e){this.inbound.allow(P)&&this.options.onDropped?.("unsupported",`ignored unknown message type '${e}'`);}refuse(e,t){e.ports?.[0]?.close?.(),this.inbound.allow(P)&&this.options.onRefused?.(t);}fail(e,t){this.options.onError?.(e,t),this.state==="connected"&&this.port&&this.send({gem:l,type:"gem.error",code:e,...t===void 0?{}:{message:t}});}gated(e){return this.state==="connected"&&this.parentSupports(e)}send(e){if(this.state!=="connected"||!this.port)return this.options.onDropped?.("internal",`dropped ${String(e.type)} before connect`),false;let t=e.type;if(!this.outbound.allow(t))return this.options.onError?.("rate_limited",`frame exceeded its own limit for ${t}`),false;let r=I[t]?.(e);return r?(this.options.onError?.("internal",`refusing to send malformed ${t}: ${r}`),false):(this.port.postMessage(this.version===null?e:{...e,v:this.version}),true)}receive(e,t=[]){let r=false;try{r=this.dispatchInbound(e,t);}finally{r||oe(t);}}dispatchInbound(e,t){if(this.state!=="connected")return false;let r=typeof e=="object"&&e!==null?e.type:void 0;if(typeof r!="string")return this.refuseMalformed("invalid_message","message has no type"),false;let o=I[r];if(!o)return this.dropUnknownType(r),false;if(!this.inbound.allow(r))return this.fail("rate_limited",`parent exceeded the limit for ${r}`),false;let s=C(r);if(s!==void 0&&!this.options.capabilities?.includes(s))return this.fail("unsupported_capability",`${r} requires the '${s}' capability, which this frame did not advertise`),false;let m=o(e);if(m)return this.fail("invalid_message",`${r}: ${m}`),false;let i=e;if(i.v!==this.version)return this.fail("invalid_message",`${r}: expected v ${String(this.version)}`),false;switch(r){case "gem.earnAllowanceChanged":this.options.onEarnAllowanceChanged?.();break;case "gem.devtools":this.options.onDevtools?.(i.action);break;case "gem.requestContext":this.options.onRequestContext?.();break;case "gem.screenshot":{let u=t[0];if(!u){this.options.onError?.("invalid_message","gem.screenshot transferred no MessagePort");break}let p={maxWidth:i.maxWidth,maxHeight:i.maxHeight};if(!this.options.onScreenshot){u.close(),this.screenshotDenied("not_wired",false);break}return oe(t.slice(1)),this.options.onScreenshot(p,u,(y,c)=>this.screenshotDenied(y,c)),true}case "gem.token.denied":this.options.onTokenDenied?.(i);break;case "gem.localServer.denied":this.options.onLocalServerDenied?.(i);break;case "gem.player":{this.options.onPlayer?.(Ge(i));break}case "gem.deviceSettings.result":this.options.onDeviceSettingsResult?.(i);break;case "gem.error":this.options.onError?.(i.code,i.message);break;default:if(ke.includes(r.slice(4))){this.options[`on${r[4].toUpperCase()}${r.slice(5)}`]?.(i);break}if(Oe.includes(C(r))){this.options.onArcadeAnswer?.(i);break}this.fail("unsupported",`no frame handler for '${r}'`);}return false}screenshotDenied(e,t){this.send({gem:l,type:"gem.screenshot.denied",reason:e,retryable:t});}};function oe(n){for(let e of n)try{e?.close?.();}catch{}}N();function Pe(n){if((n.expectedSource??window.parent)===window)throw new Error("GemWebSdkBridge.connect: this document is not framed (window.parent === window), so there is no embedder to hand it a port. A game runs inside the Gem Arcade iframe; opening it directly will never complete a handshake.");let e=new k({...n,expectedSource:n.expectedSource??window.parent}),t=r=>{let o=e.handleWindowMessage({data:r.data,origin:r.origin,source:r.source,ports:r.ports});return o&&window.removeEventListener("message",t),o};return window.addEventListener("message",t),W(window,t),e}var se={connect:Pe,GemFrame:k,PROTOCOL:l,SUPPORTED_VERSIONS:S};window.GemWebSdkBridge=se;var Tn=se;return Tn;})();