@indiegems/gem-web-sdk 5.10.0 → 5.12.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/brand/gem-icon-20-1.5x.png +0 -0
- package/brand/gem-icon-20-1x.png +0 -0
- package/brand/gem-icon-20-2x.png +0 -0
- package/brand/gem-icon-20-3x.png +0 -0
- package/brand/gem-icon-32-1.5x.png +0 -0
- package/brand/gem-icon-32-1x.png +0 -0
- package/brand/gem-icon-32-2x.png +0 -0
- package/brand/gem-icon-32-3x.png +0 -0
- package/dist/game.d.ts +56 -33
- package/dist/gem-web-sdk.bridge.js +1 -1
- package/dist/gem-web-sdk.esm.js +2 -2
- package/dist/gem-web-sdk.game.js +2 -2
- package/dist/gem-web-sdk.min.js +2 -2
- package/dist/gem-web-sdk.sdk.js +2 -2
- package/dist/gem-web-sdk.server.js +2 -2
- package/dist/index.d.ts +79 -22
- package/dist/sdk.d.ts +57 -34
- package/dist/server.d.ts +10 -2
- package/package.json +1 -1
- package/schema/bridge.v1.json +164 -33
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/game.d.ts
CHANGED
|
@@ -529,6 +529,16 @@ interface Progression {
|
|
|
529
529
|
readonly currentValue: number;
|
|
530
530
|
readonly completionCount: number;
|
|
531
531
|
readonly isCompleted: boolean;
|
|
532
|
+
readonly achievements?: readonly ProgressionAchievement[];
|
|
533
|
+
readonly achievementsUnavailable?: boolean;
|
|
534
|
+
}
|
|
535
|
+
interface ProgressionAchievement {
|
|
536
|
+
readonly id: string;
|
|
537
|
+
readonly threshold: number;
|
|
538
|
+
readonly points: number;
|
|
539
|
+
readonly hidden: boolean;
|
|
540
|
+
readonly unlockedAt?: number;
|
|
541
|
+
readonly revoked?: boolean;
|
|
532
542
|
}
|
|
533
543
|
interface CurrencyBucket {
|
|
534
544
|
readonly bucket: string;
|
|
@@ -1026,14 +1036,26 @@ declare class ChallengesApi {
|
|
|
1026
1036
|
constructor(api: GameApi);
|
|
1027
1037
|
list(options?: ListChallengesOptions): Promise<Challenge[]>;
|
|
1028
1038
|
}
|
|
1029
|
-
interface
|
|
1039
|
+
interface PlayerBadge {
|
|
1040
|
+
readonly itemId: string;
|
|
1041
|
+
readonly iconUrl: string;
|
|
1042
|
+
}
|
|
1043
|
+
interface PlayerIdentity {
|
|
1044
|
+
readonly playerId?: string;
|
|
1045
|
+
readonly displayName?: PlayerText;
|
|
1046
|
+
readonly discriminator?: string;
|
|
1047
|
+
readonly displayTag?: PlayerText;
|
|
1048
|
+
readonly avatarIconId?: string;
|
|
1049
|
+
readonly avatarIconUrl?: string;
|
|
1050
|
+
readonly badges: readonly PlayerBadge[];
|
|
1051
|
+
}
|
|
1052
|
+
declare function mapIdentity(row: unknown): PlayerIdentity;
|
|
1053
|
+
declare function platformIconUrl(url: string | undefined): string | undefined;
|
|
1054
|
+
interface LeaderboardEntry extends RankedRow, PlayerIdentity {
|
|
1030
1055
|
readonly rank: number;
|
|
1031
1056
|
readonly occurredAt: number;
|
|
1032
1057
|
readonly entityId?: string;
|
|
1033
1058
|
readonly entityType?: EntityType;
|
|
1034
|
-
readonly displayName?: string;
|
|
1035
|
-
readonly discriminator?: string;
|
|
1036
|
-
readonly displayTag?: string;
|
|
1037
1059
|
readonly stats?: Readonly<Record<string, number>>;
|
|
1038
1060
|
readonly properties?: Readonly<Record<string, unknown>>;
|
|
1039
1061
|
readonly isViewer?: boolean;
|
|
@@ -1095,11 +1117,8 @@ interface ShowcaseValue {
|
|
|
1095
1117
|
readonly value: unknown;
|
|
1096
1118
|
readonly updatedAt: number;
|
|
1097
1119
|
}
|
|
1098
|
-
interface ShowcaseFriendEntry {
|
|
1120
|
+
interface ShowcaseFriendEntry extends PlayerIdentity {
|
|
1099
1121
|
readonly playerId: string;
|
|
1100
|
-
readonly displayName?: string;
|
|
1101
|
-
readonly discriminator?: string;
|
|
1102
|
-
readonly displayTag?: string;
|
|
1103
1122
|
readonly value: unknown;
|
|
1104
1123
|
readonly isViewer: boolean;
|
|
1105
1124
|
readonly updatedAt: number;
|
|
@@ -1121,13 +1140,8 @@ declare class ShowcaseApi {
|
|
|
1121
1140
|
set(key: string, value: unknown, options?: ShowcaseCallOptions): Promise<ShowcaseValue>;
|
|
1122
1141
|
clear(key: string, options?: ShowcaseCallOptions): Promise<void>;
|
|
1123
1142
|
}
|
|
1124
|
-
interface Friend {
|
|
1143
|
+
interface Friend extends PlayerIdentity {
|
|
1125
1144
|
readonly playerId: string;
|
|
1126
|
-
readonly displayName?: string;
|
|
1127
|
-
readonly discriminator?: string;
|
|
1128
|
-
readonly displayTag?: string;
|
|
1129
|
-
readonly avatarIconId?: string;
|
|
1130
|
-
readonly avatarIconUrl?: string;
|
|
1131
1145
|
}
|
|
1132
1146
|
interface FriendsPage {
|
|
1133
1147
|
readonly friends: readonly Friend[];
|
|
@@ -1168,13 +1182,8 @@ interface ProfileShowcaseEntry {
|
|
|
1168
1182
|
readonly value: unknown;
|
|
1169
1183
|
readonly updatedAt: number;
|
|
1170
1184
|
}
|
|
1171
|
-
interface PlayerProfile {
|
|
1185
|
+
interface PlayerProfile extends PlayerIdentity {
|
|
1172
1186
|
readonly playerId: string;
|
|
1173
|
-
readonly displayName?: string;
|
|
1174
|
-
readonly discriminator?: string;
|
|
1175
|
-
readonly displayTag?: string;
|
|
1176
|
-
readonly avatarIconId?: string;
|
|
1177
|
-
readonly avatarIconUrl?: string;
|
|
1178
1187
|
readonly showcase: readonly ProfileShowcaseEntry[];
|
|
1179
1188
|
readonly generatedAt: number;
|
|
1180
1189
|
}
|
|
@@ -1455,16 +1464,13 @@ interface AutoReconnectOptions {
|
|
|
1455
1464
|
readonly attempts?: number;
|
|
1456
1465
|
readonly maxDelayMs?: number;
|
|
1457
1466
|
}
|
|
1458
|
-
interface RoomMember {
|
|
1467
|
+
interface RoomMember extends PlayerIdentity {
|
|
1459
1468
|
readonly playerId: string;
|
|
1460
1469
|
readonly isReady: boolean;
|
|
1461
1470
|
readonly role: string;
|
|
1462
1471
|
readonly joinedAt: number;
|
|
1463
1472
|
readonly groupId?: string;
|
|
1464
1473
|
readonly platform?: string;
|
|
1465
|
-
readonly displayName?: PlayerText;
|
|
1466
|
-
readonly displayTag?: PlayerText;
|
|
1467
|
-
readonly discriminator?: string;
|
|
1468
1474
|
}
|
|
1469
1475
|
interface Room {
|
|
1470
1476
|
readonly id: string;
|
|
@@ -1482,6 +1488,7 @@ interface Room {
|
|
|
1482
1488
|
readonly roomArgsTemplate?: readonly RoomArgEntry[];
|
|
1483
1489
|
readonly gameChannel: string;
|
|
1484
1490
|
readonly region?: string;
|
|
1491
|
+
readonly clusterTargetId?: string;
|
|
1485
1492
|
readonly matchId?: string;
|
|
1486
1493
|
readonly version: number;
|
|
1487
1494
|
readonly templateId?: string;
|
|
@@ -1491,6 +1498,10 @@ interface Room {
|
|
|
1491
1498
|
readonly updatedAt: number;
|
|
1492
1499
|
readonly startedAt?: number;
|
|
1493
1500
|
}
|
|
1501
|
+
interface MatchAutoStartFailed {
|
|
1502
|
+
readonly roomId: string;
|
|
1503
|
+
readonly code: string;
|
|
1504
|
+
}
|
|
1494
1505
|
interface RoomSummary {
|
|
1495
1506
|
readonly id: string;
|
|
1496
1507
|
readonly gameId: string;
|
|
@@ -1593,6 +1604,9 @@ interface RoomEventMap {
|
|
|
1593
1604
|
matchStartWaiting: [
|
|
1594
1605
|
StartMatchWaiting
|
|
1595
1606
|
];
|
|
1607
|
+
matchAutoStartFailed: [
|
|
1608
|
+
MatchAutoStartFailed
|
|
1609
|
+
];
|
|
1596
1610
|
matchAllocationStarted: [
|
|
1597
1611
|
string
|
|
1598
1612
|
];
|
|
@@ -1690,6 +1704,7 @@ interface RoomManager {
|
|
|
1690
1704
|
once<K extends RoomEventName>(event: K, listener: (...args: RoomEventMap[K]) => void): () => void;
|
|
1691
1705
|
handleRoomEvent(event: RelayedRoomEvent): void;
|
|
1692
1706
|
handleSeated(roomId: string): void;
|
|
1707
|
+
handleAutoStartFailed(roomId: string, code: string): void;
|
|
1693
1708
|
reconcileSeats(): Promise<void>;
|
|
1694
1709
|
reconcile(hint?: MatchEndHint): Promise<void>;
|
|
1695
1710
|
startPolling(intervalMs?: number): void;
|
|
@@ -1786,6 +1801,12 @@ interface GemSeatedEvent {
|
|
|
1786
1801
|
readonly type: "gem.seatedEvent";
|
|
1787
1802
|
readonly roomId: string;
|
|
1788
1803
|
}
|
|
1804
|
+
interface GemAutoStartFailedEvent {
|
|
1805
|
+
readonly gem: typeof PROTOCOL;
|
|
1806
|
+
readonly type: "gem.autoStartFailedEvent";
|
|
1807
|
+
readonly roomId: string;
|
|
1808
|
+
readonly code: string;
|
|
1809
|
+
}
|
|
1789
1810
|
interface GemSignalEvent {
|
|
1790
1811
|
readonly gem: typeof PROTOCOL;
|
|
1791
1812
|
readonly type: "gem.signalEvent";
|
|
@@ -1814,6 +1835,7 @@ interface GemClusterTarget {
|
|
|
1814
1835
|
readonly gem: typeof PROTOCOL;
|
|
1815
1836
|
readonly type: "gem.clusterTarget";
|
|
1816
1837
|
readonly clusterTargetId: string;
|
|
1838
|
+
readonly clusterTargetIds?: string[];
|
|
1817
1839
|
}
|
|
1818
1840
|
interface GemScreenshotDenied {
|
|
1819
1841
|
readonly gem: typeof PROTOCOL;
|
|
@@ -2379,6 +2401,11 @@ interface RewardCue {
|
|
|
2379
2401
|
};
|
|
2380
2402
|
}
|
|
2381
2403
|
type FrameState = "waiting" | "connected" | "refused" | "closed";
|
|
2404
|
+
interface FramePlayer extends PlayerIdentity {
|
|
2405
|
+
readonly displayName: PlayerText;
|
|
2406
|
+
readonly displayHandle: PlayerText;
|
|
2407
|
+
readonly avatarUrl?: string;
|
|
2408
|
+
}
|
|
2382
2409
|
interface FrameCallbacks {
|
|
2383
2410
|
onToken?(msg: GemToken): void;
|
|
2384
2411
|
onPause?(msg: GemPause): void;
|
|
@@ -2395,14 +2422,10 @@ interface FrameCallbacks {
|
|
|
2395
2422
|
onTokenDenied?(msg: GemTokenDenied): void;
|
|
2396
2423
|
onLocalServer?(msg: GemLocalServer): void;
|
|
2397
2424
|
onLocalServerDenied?(msg: GemLocalServerDenied): void;
|
|
2398
|
-
onPlayer?(player:
|
|
2399
|
-
displayName: PlayerText;
|
|
2400
|
-
displayHandle: PlayerText;
|
|
2401
|
-
displayTag: string;
|
|
2402
|
-
avatarUrl?: string;
|
|
2403
|
-
}): void;
|
|
2425
|
+
onPlayer?(player: FramePlayer): void;
|
|
2404
2426
|
onRoomEvent?(msg: GemRoomEvent): void;
|
|
2405
2427
|
onSeatedEvent?(msg: GemSeatedEvent): void;
|
|
2428
|
+
onAutoStartFailedEvent?(msg: GemAutoStartFailedEvent): void;
|
|
2406
2429
|
onSocketState?(msg: GemSocketState): void;
|
|
2407
2430
|
onSignalEvent?(msg: GemSignalEvent): void;
|
|
2408
2431
|
onDedicatedEvent?(msg: GemDedicatedEvent): void;
|
|
@@ -2478,6 +2501,7 @@ declare class GemFrame {
|
|
|
2478
2501
|
private screenshotDenied;
|
|
2479
2502
|
}
|
|
2480
2503
|
declare const DEVICE_SETTINGS_MAX_BYTES = 16384;
|
|
2504
|
+
declare const ARCADE_EMBEDDERS: readonly string[];
|
|
2481
2505
|
interface GemOptions {
|
|
2482
2506
|
readonly allowedEmbedders?: readonly string[];
|
|
2483
2507
|
readonly baseUrl?: string;
|
|
@@ -2510,10 +2534,9 @@ interface GemOptions {
|
|
|
2510
2534
|
}) => Promise<ImageBitmap | null>;
|
|
2511
2535
|
readonly handshakeWarningMs?: number | null;
|
|
2512
2536
|
}
|
|
2513
|
-
interface GemPlayer {
|
|
2537
|
+
interface GemPlayer extends PlayerIdentity {
|
|
2514
2538
|
readonly displayName: PlayerText;
|
|
2515
2539
|
readonly displayHandle: PlayerText;
|
|
2516
|
-
readonly displayTag: string;
|
|
2517
2540
|
readonly avatarUrl?: string;
|
|
2518
2541
|
}
|
|
2519
2542
|
interface GemPrefs {
|
|
@@ -2598,4 +2621,4 @@ interface ExitAnalytics {
|
|
|
2598
2621
|
}
|
|
2599
2622
|
declare function leaveAndExit(rooms: ExitRooms, bridge: ExitBridge | null, reason?: string, analytics?: ExitAnalytics): Promise<void>;
|
|
2600
2623
|
declare function createGem(options?: GemOptions): Gem;
|
|
2601
|
-
export { type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type BootMark, type BootTimeline, type Challenge, type ChallengeWindow, ChallengesApi, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, DEVICE_SETTINGS_MAX_BYTES, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DevToolsOpener, type DeviceSettings, type DeviceSettingsApi, type DeviceSettingsPutOutcome, type DirectPurchaseRequest, type DirectPurchaseResult, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, type EntityType, type ExitAnalytics, type ExitBridge, type ExitRooms, type FrameState, type Friend, FriendsApi, type FriendsPage, type GameConfig, type GameServerLink, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemDevTools, GemFrame, type GemIdentity, type GemInsets, type GemMatchApi, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, GemSaveError, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerLifecycle, type GemTerminationNotice, type GemViewport, type GetLeaderboardOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, LeaderboardsApi, type ListChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchServeOptions, type MatchTransport, type MessageMeta, type MultiTransportSession, PLATFORM_EVENTS, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, type PlatformEventName, type PlayerProfile, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, type PurchaseRequest, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RewardCue, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerTokenGrant, type SessionEndReason, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SnapshotCurrency, type SnapshotItem, type TransportAdvert, type TransportKind, TransportRefusal, UNRELIABLE_CHANNEL_LABEL, asPlayerText, createBootTimeline, createGem, leaveAndExit, markOnResolve, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, text, webTransportAvailable };
|
|
2624
|
+
export { ARCADE_EMBEDDERS, type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type BootMark, type BootTimeline, type Challenge, type ChallengeWindow, ChallengesApi, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, DEVICE_SETTINGS_MAX_BYTES, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DevToolsOpener, type DeviceSettings, type DeviceSettingsApi, type DeviceSettingsPutOutcome, type DirectPurchaseRequest, type DirectPurchaseResult, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, type EntityType, type ExitAnalytics, type ExitBridge, type ExitRooms, type FrameState, type Friend, FriendsApi, type FriendsPage, type GameConfig, type GameServerLink, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemDevTools, GemFrame, type GemIdentity, type GemInsets, type GemMatchApi, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, GemSaveError, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerLifecycle, type GemTerminationNotice, type GemViewport, type GetLeaderboardOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, LeaderboardsApi, type ListChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchServeOptions, type MatchTransport, type MessageMeta, type MultiTransportSession, PLATFORM_EVENTS, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, type PlatformEventName, type PlayerBadge, type PlayerIdentity, type PlayerProfile, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, type PurchaseRequest, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RewardCue, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerTokenGrant, type SessionEndReason, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SnapshotCurrency, type SnapshotItem, type TransportAdvert, type TransportKind, TransportRefusal, UNRELIABLE_CHANNEL_LABEL, asPlayerText, createBootTimeline, createGem, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, text, webTransportAvailable };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var GemWebSdkBridgeBundle=(function(){'use strict';var b="GemWebSdkHandshake";function z(){return typeof document>"u"?void 0:document.readyState}var C=()=>Date.now();function q(n={}){let e=n.win??window,t=e,r=t[b];if(r!==void 0)return r;let i=n.readyState??z,s=n.now??C,d=[],o=[],m=u=>{let g=u.data;!g||g.type!=="gem.handshake"||(d.length>=4&&(d.shift(),o.shift(),c.dropped+=1),d.push(u),o.push(s()));};e.addEventListener("message",m);let c={events:d,times:o,dropped:0,late:i()==="complete",uninstall(){e.removeEventListener("message",m);}};return t[b]=c,c}function I(n,e,t={}){let r=n[b];if(r===void 0)return null;let i=t.ttlMs??9500,s=t.now??C,d=r.events.splice(0),o=r.times?.splice(0),m=0,c=0,u=false,g=s()-i;for(let k=d.length-1;k>=0;k--){let E=o?.[k];if(E!==void 0&&E<g){c+=1;continue}if(m+=1,e(d[k])===true){u=true;break}}return r.uninstall(),{capture:r,delivered:m,stale:c,accepted:u}}var l="gem-web-bridge",y={min:1,max:1},p=65536,L=8,v=5e3,_=1024;function S(n){return Object.freeze(Object.assign(Object.create(null),n))}var j=S({"gem.handshake":30,"gem.handshake.accept":5,"gem.token":30,"gem.token.denied":30,"gem.player":12,"gem.pause":120,"gem.prefs":60,"gem.cohorts":12,"gem.viewport":60,"gem.deviceSettings":12,"gem.willTerminate":10,"gem.roomEvent":120,"gem.socketState":12,"gem.seatedEvent":60,"gem.signalEvent":1800,"gem.dedicatedEvent":120,"gem.partyResult":30,"gem.clusterTarget":12,"gem.devtools":30,"gem.screenshot":6,"gem.screenshot.denied":12,"gem.requestContext":12,"gem.gameContext":12,"gem.signal":1200,"gem.dedicatedOffer":60,"gem.partyRequest":12,"gem.ready":5,"gem.progress":600,"gem.requestToken":12,"gem.requestLocalServer":6,"gem.localServer":30,"gem.localServer.denied":30,"gem.exit":5,"gem.openExternal":6,"gem.requestFullscreen":30,"gem.audioState":120,"gem.rewardCue":60,"gem.frameStats":120,"gem.error":60,"gem.requestPurchase":12,"gem.purchaseResult":30,"gem.deviceSettings.put":30,"gem.deviceSettings.result":30,"gem.requestAd":6,"gem.adResult":12,"gem.requestSignIn":6,"gem.signInResult":12,__malformed:60}),x="__malformed";var B=S({"gem.requestAd":"ads","gem.adResult":"ads","gem.requestSignIn":"signIn","gem.signInResult":"signIn","gem.requestPurchase":"purchases","gem.purchaseResult":"purchases","gem.devtools":"devtools","gem.screenshot":"screenshot","gem.screenshot.denied":"screenshot","gem.requestContext":"feedbackContext","gem.gameContext":"feedbackContext","gem.roomEvent":"rooms","gem.signal":"p2p","gem.signalEvent":"p2p","gem.dedicatedOffer":"dedicated","gem.dedicatedEvent":"dedicated","gem.clusterTarget":"clusterTarget","gem.partyRequest":"parties","gem.partyResult":"parties","gem.seatedEvent":"partySeating","gem.socketState":"socketState","gem.audioState":"audioState","gem.rewardCue":"rewardCue","gem.frameStats":"frameStats","gem.viewport":"viewport","gem.requestLocalServer":"localHost","gem.localServer":"localHost","gem.localServer.denied":"localHost","gem.cohorts":"cohorts","gem.deviceSettings":"deviceSettings","gem.deviceSettings.put":"deviceSettings","gem.deviceSettings.result":"deviceSettings"}),K=Object.freeze([["gem.asyncOpponents.","asyncOpponents"]]);function A(n){let e=B[n];if(e!==void 0)return e;for(let[t,r]of K)if(n.startsWith(t))return r}function Y(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 X(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 J(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function R(n,e,t){if(e>L)return `nesting deeper than ${L}`;if(++t.nodes>v)return `more than ${v} values`;if(t.bytes>p)return `over the ${p} 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 i=n;if(t.seen.has(i))return "a repeated or cyclic object reference";if(t.seen.add(i),Array.isArray(n)){if(n.length>_)return `an array of ${n.length} entries, over the ${_} limit`;t.bytes+=2;for(let o of n){let m=R(o,e+1,t);if(m)return m}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 o in d){if(!Object.prototype.hasOwnProperty.call(d,o))continue;if(++t.nodes>v)return `more than ${v} values`;if(t.bytes+=o.length*3+4,t.bytes>p)return `over the ${p} byte limit`;let m=R(d[o],e+1,t);if(m)return m}return null}function Q(n){let e={nodes:0,bytes:0,seen:new Set},t=R(n,0,e);return t?`message contains ${t}`:e.bytes>p?`message is over the ${p} byte limit`:null}var Z={origin:[Y,"not a well-formed origin"],url:[X,"not a safe absolute http(s) URL"],bcp47:[J,"not a well-formed BCP 47 tag"]};function D(n,e,t){for(let r of e){let i=t===""?r.n:`${t}.${r.n}`,s=n[r.n];if(s==null){if(r.o)continue;return `${i}: required`}let d=M(s,r,i);if(d)return d}return null}function M(n,e,t){switch(e.k){case "string":{if(typeof n!="string")return `${t}: expected string`;if(n.length>e.max)return `${t}: exceeds ${e.max} characters`;if(e.f){let[r,i]=Z[e.f];if(!r(n))return `${t}: ${i}`}return null}case "int":return typeof n!="number"||!Number.isInteger(n)?`${t}: expected integer`:n<e.lo||n>e.hi?`${t}: out of range ${e.lo}..${e.hi}`:null;case "boolean":return typeof n=="boolean"?null:`${t}: expected boolean`;case "enum":{let r=e.v;return r.includes(n)?null:`${t}: not one of ${r.join("|")}`}case "object":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:D(n,e.fs,t);case "json":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected a plain object`:null;case "array":{if(!Array.isArray(n))return `${t}: expected array`;if(n.length>e.max)return `${t}: exceeds ${e.max} items`;let r=e.it,i=`${t}[]`;for(let s of n){if(s==null){if(r.o)continue;return `${i}: required`}let d=M(s,r,i);if(d)return d}return null}default:{let r=e.k;return `${t}: unknown kind ${String(r)}`}}}function a(n,e){return t=>{let r=Q(t);if(r)return r;if(typeof t!="object"||t===null||Array.isArray(t))return "message: expected object";let i=t;return i.gem!==l?"gem: wrong protocol marker":i.type!==n?`type: expected ${n}`:D(i,e,"")}}var ee=a("gem.handshake",[{n:"versions",k:"object",fs:[{n:"min",k:"int",lo:1,hi:1e3},{n:"max",k:"int",lo:1,hi:1e3}]},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}},{n:"embedder",k:"string",max:2048,f:"origin"}]),te=a("gem.handshake.accept",[{n:"v",k:"int",lo:1,hi:1e3},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}}]),ne=a("gem.token",[{n:"token",k:"string",max:4096},{n:"requestId",k:"string",o:1,max:64},{n:"generation",k:"int",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"string",o:1,max:512,f:"url"},{n:"playerId",k:"string",max:64},{n:"gameId",k:"string",max:64},{n:"channel",k:"enum",v:["dev","test","release"]},{n:"gameVersion",k:"string",o:1,max:64},{n:"expiresAt",k:"int",lo:0,hi:4102444800},{n:"chainEndsAt",k:"int",lo:0,hi:4102444800},{n:"allowDevTools",k:"boolean",o:1}]),re=a("gem.token.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"retryAfterMs",k:"int",o:1,lo:0,hi:36e5},{n:"reason",k:"enum",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"string",max:64}]),oe=a("gem.player",[{n:"untrusted",k:"object",fs:[{n:"displayName",k:"string",max:64},{n:"displayHandle",k:"string",max:80}]},{n:"displayTag",k:"string",max:8},{n:"avatarUrl",k:"string",o:1,max:2048,f:"url"}]),ae=a("gem.pause",[{n:"paused",k:"boolean"}]),se=a("gem.prefs",[{n:"reducedMotion",k:"boolean"},{n:"muted",k:"boolean"},{n:"showFrameStats",k:"boolean",o:1},{n:"locale",k:"string",max:35,f:"bcp47"}]),ie=a("gem.cohorts",[{n:"cohorts",k:"array",max:8,it:{n:"",k:"object",fs:[{n:"experimentId",k:"string",max:36},{n:"variantKey",k:"string",max:32}]}}]),de=a("gem.viewport",[{n:"insets",k:"object",fs:[{n:"top",k:"int",lo:0,hi:4096},{n:"right",k:"int",lo:0,hi:4096},{n:"bottom",k:"int",lo:0,hi:4096},{n:"left",k:"int",lo:0,hi:4096}]}]),le=a("gem.deviceSettings",[{n:"settings",k:"json",o:1}]),me=a("gem.willTerminate",[{n:"reason",k:"enum",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"int",lo:0,hi:6e4}]),ce=a("gem.roomEvent",[{n:"event",k:"enum",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"string",max:64},{n:"matchId",k:"string",o:1,max:64},{n:"version",k:"int",o:1,lo:0,hi:2147483647},{n:"reason",k:"string",o:1,max:64},{n:"platform",k:"enum",o:1,v:["universal","mobile"]}]),ue=a("gem.socketState",[{n:"connected",k:"boolean"},{n:"reason",k:"enum",o:1,v:["connecting","dropped","watchdog","terminal"]}]),ge=a("gem.seatedEvent",[{n:"roomId",k:"string",max:64}]),pe=a("gem.signalEvent",[{n:"event",k:"enum",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),ye=a("gem.dedicatedEvent",[{n:"event",k:"enum",v:["answer","error","matchEnded"]},{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",o:1,max:10240},{n:"sessionId",k:"string",o:1,max:64},{n:"code",k:"string",o:1,max:64},{n:"message",k:"string",o:1,max:256},{n:"reason",k:"string",o:1,max:64}]),fe=a("gem.partyResult",[{n:"requestId",k:"string",max:64},{n:"partyId",k:"string",o:1,max:64}]),he=a("gem.clusterTarget",[{n:"clusterTargetId",k:"string",max:64}]),ke=a("gem.devtools",[{n:"action",k:"enum",v:["open","close","toggle"]}]),ve=a("gem.screenshot",[{n:"maxWidth",k:"int",lo:1,hi:7680},{n:"maxHeight",k:"int",lo:1,hi:4320}]),xe=a("gem.screenshot.denied",[{n:"reason",k:"enum",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"boolean"}]),we=a("gem.requestContext",[]),be=a("gem.gameContext",[{n:"context",k:"json"}]),Re=a("gem.signal",[{n:"signal",k:"enum",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),Se=a("gem.dedicatedOffer",[{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",max:10240},{n:"intent",k:"enum",v:["initial","ice_restart","full_reconnect"]}]),Ge=a("gem.partyRequest",[{n:"requestId",k:"string",max:64}]),Oe=a("gem.ready",[]),Te=a("gem.progress",[{n:"loaded",k:"int",lo:0,hi:1099511627776},{n:"total",k:"int",lo:0,hi:1099511627776}]),Pe=a("gem.requestToken",[{n:"requestId",k:"string",max:64},{n:"reason",k:"enum",v:["initial","expiring","rejected"]}]),Ee=a("gem.requestLocalServer",[{n:"requestId",k:"string",max:64},{n:"gameRoomId",k:"string",max:64}]),Ce=a("gem.localServer",[{n:"requestId",k:"string",max:64},{n:"serverId",k:"string",o:1,max:128}]),qe=a("gem.localServer.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"reason",k:"enum",v:["refused","unavailable"]}]),Ie=a("gem.exit",[{n:"reason",k:"string",o:1,max:64}]),Le=a("gem.openExternal",[{n:"url",k:"string",max:2048,f:"url"}]),_e=a("gem.requestFullscreen",[{n:"enabled",k:"boolean"}]),je=a("gem.audioState",[{n:"muted",k:"boolean"}]),Ae=a("gem.rewardCue",[{n:"currencySlug",k:"string",max:32},{n:"expected",k:"int",o:1,lo:1,hi:1e9},{n:"origin",k:"object",o:1,fs:[{n:"x",k:"int",lo:0,hi:16384},{n:"y",k:"int",lo:0,hi:16384}]}]),De=a("gem.frameStats",[{n:"fps",k:"int",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"int",lo:0,hi:1e5}]),Me=a("gem.error",[{n:"code",k:"enum",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"string",o:1,max:256}]),Fe=a("gem.requestPurchase",[{n:"requestId",k:"string",max:64},{n:"purchaseKind",k:"enum",v:["item","recipe"]},{n:"targetId",k:"string",max:64},{n:"currencySlug",k:"string",max:32},{n:"quantity",k:"int",o:1,lo:1,hi:10},{n:"catalogId",k:"string",o:1,max:64}]),$e=a("gem.purchaseResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["ok","declined","unavailable"]},{n:"purchaseId",k:"string",o:1,max:64}]),He=a("gem.deviceSettings.put",[{n:"requestId",k:"string",max:64},{n:"settings",k:"json"}]),We=a("gem.deviceSettings.result",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["stored","too_large","unavailable"]}]),Ue=a("gem.requestAd",[{n:"requestId",k:"string",max:64},{n:"placement",k:"string",max:32},{n:"format",k:"enum",v:["interstitial","rewarded"]}]),Ne=a("gem.adResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["shown","no_ad","unavailable"]}]),Ve=a("gem.requestSignIn",[{n:"requestId",k:"string",max:64}]),ze=a("gem.signInResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["signed_in","declined","unavailable"]}]),w=S({"gem.handshake":ee,"gem.handshake.accept":te,"gem.token":ne,"gem.token.denied":re,"gem.player":oe,"gem.pause":ae,"gem.prefs":se,"gem.cohorts":ie,"gem.viewport":de,"gem.deviceSettings":le,"gem.willTerminate":me,"gem.roomEvent":ce,"gem.socketState":ue,"gem.seatedEvent":ge,"gem.signalEvent":pe,"gem.dedicatedEvent":ye,"gem.partyResult":fe,"gem.clusterTarget":he,"gem.devtools":ke,"gem.screenshot":ve,"gem.screenshot.denied":xe,"gem.requestContext":we,"gem.gameContext":be,"gem.signal":Re,"gem.dedicatedOffer":Se,"gem.partyRequest":Ge,"gem.ready":Oe,"gem.progress":Te,"gem.requestToken":Pe,"gem.requestLocalServer":Ee,"gem.localServer":Ce,"gem.localServer.denied":qe,"gem.exit":Ie,"gem.openExternal":Le,"gem.requestFullscreen":_e,"gem.audioState":je,"gem.rewardCue":Ae,"gem.frameStats":De,"gem.error":Me,"gem.requestPurchase":Fe,"gem.purchaseResult":$e,"gem.deviceSettings.put":He,"gem.deviceSettings.result":We,"gem.requestAd":Ue,"gem.adResult":Ne,"gem.requestSignIn":Ve,"gem.signInResult":ze});var G=class{#e;constructor(e){this.#e=e,Object.freeze(this);}toString(){return "[gem: use gem.text.toPlain()]"}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function O(n){return new G(n)}var T={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)},f=class{constructor(e=T){this.clock=e;}clock;tokens=new Map;lastRefill=new Map;allow(e){let t=j[e];if(t===void 0)return false;let r=this.clock.now(),i=this.lastRefill.get(e)??r,s=this.tokens.get(e)??t,d=Math.max(0,r-i),o=Math.min(t,s+d*t/6e4);return o<1?(this.tokens.set(e,o),this.lastRefill.set(e,r),false):(this.tokens.set(e,o-1),this.lastRefill.set(e,r),true)}};function P(n,e){return n.toLowerCase()===e.toLowerCase()}function F(n){let e=n.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}function $(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:F(t.hostname)&&F(r.hostname)}function H(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}function W(n){return Math.min(16384,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}function U(n,e){return Math.min(e,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}var Be=1e4,h=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??T,this.inbound=new f(this.clock),this.outbound=new f(this.clock);}options;state="waiting";port=null;version=null;peerCapabilities=[];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}handleWindowMessage(e){if(e.source!==this.expectedSource)return this.refuse(e,"handshake did not come from the expected embedder window"),false;if(!(this.options.allowedEmbedders.some(o=>P(o,e.origin))||$(e.origin,this.options.selfOrigin)))return this.refuse(e,`embedder '${e.origin}' is not in allowedEmbedders`),false;if(this.state==="connected")return this.fail("handshake_duplicate","this document already has a port"),false;if(this.state!=="waiting")return false;let r=w["gem.handshake"]?.(e.data);if(r)return this.refuse(e,`malformed handshake: ${r}`),false;let i=e.data;if(!P(i.embedder,e.origin))return this.refuse(e,`handshake claims embedder '${i.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=H(y,i.versions);return d===null?(s.onmessage=null,s.postMessage({gem:l,type:"gem.error",code:"version_mismatch",message:`frame supports v${y.min}..v${y.max}`}),s.close(),this.transition("refused"),this.options.onError?.("version_mismatch"),false):(this.port=s,this.version=d,s.onmessage=o=>this.receive(o.data,o.ports??[]),s.start?.(),this.peerCapabilities=i.capabilities??[],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=Be){return this.state!=="waiting"?Promise.resolve(this.state):new Promise(t=>{let r=s=>{this.clock.clearTimeout(i),t(s);},i=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.state!=="connected"||!this.parentSupports("audioState")?false:(this.send({gem:l,type:"gem.audioState",muted:e}),true)}cueReward(e){if(this.state!=="connected"||!this.parentSupports("rewardCue"))return false;let t={gem:l,type:"gem.rewardCue",currencySlug:String(e.currencySlug).slice(0,32)};return 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:W(e.origin.x),y:W(e.origin.y)}),this.send(t),true}reportFrameStats(e){return this.state!=="connected"||!this.parentSupports("frameStats")?false:(this.send({gem:l,type:"gem.frameStats",fps:U(e.fps,1e3),frameTimeP95Ms:U(e.frameTimeP95Ms,1e5)}),true)}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,i,s,d){return this.send({gem:l,type:"gem.requestPurchase",requestId:e,purchaseKind:t,targetId:r,currencySlug:i,...s===void 0?{}:{quantity:s},...d===void 0?{}:{catalogId:d}})}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})}requestSignIn(e){return this.send({gem:l,type:"gem.requestSignIn",requestId: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(x)){this.options.onDropped?.(e,t);return}this.fail(e,t);}dropUnknownType(e){this.inbound.allow(x)&&this.options.onDropped?.("unsupported",`ignored unknown message type '${e}'`);}refuse(e,t){e.ports?.[0]?.close?.(),this.inbound.allow(x)&&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}});}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=w[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||N(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 i=w[r];if(!i)return this.dropUnknownType(r),false;if(!this.inbound.allow(r))return this.fail("rate_limited",`parent exceeded the limit for ${r}`),false;let s=A(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=i(e);if(d)return this.fail("invalid_message",`${r}: ${d}`),false;let o=e;if(o.v!==this.version)return this.fail("invalid_message",`${r}: expected v ${String(this.version)}`),false;switch(r){case "gem.token":this.options.onToken?.(o);break;case "gem.pause":this.options.onPause?.(o);break;case "gem.prefs":this.options.onPrefs?.(o);break;case "gem.cohorts":this.options.onCohorts?.(o);break;case "gem.viewport":this.options.onViewport?.(o);break;case "gem.willTerminate":this.options.onWillTerminate?.(o);break;case "gem.devtools":this.options.onDevtools?.(o.action);break;case "gem.requestContext":this.options.onRequestContext?.();break;case "gem.screenshot":{let m=t[0];if(!m){this.options.onError?.("invalid_message","gem.screenshot transferred no MessagePort");break}let c={maxWidth:o.maxWidth,maxHeight:o.maxHeight};if(!this.options.onScreenshot){m.close(),this.screenshotDenied("not_wired",false);break}return N(t.slice(1)),this.options.onScreenshot(c,m,(u,g)=>this.screenshotDenied(u,g)),true}case "gem.token.denied":this.options.onTokenDenied?.(o);break;case "gem.localServer":this.options.onLocalServer?.(o);break;case "gem.localServer.denied":this.options.onLocalServerDenied?.(o);break;case "gem.player":{let m=o.untrusted;this.options.onPlayer?.({displayName:O(m.displayName),displayHandle:O(m.displayHandle),displayTag:o.displayTag,avatarUrl:o.avatarUrl});break}case "gem.roomEvent":this.options.onRoomEvent?.(o);break;case "gem.seatedEvent":this.options.onSeatedEvent?.(o);break;case "gem.socketState":this.options.onSocketState?.(o);break;case "gem.signalEvent":this.options.onSignalEvent?.(o);break;case "gem.dedicatedEvent":this.options.onDedicatedEvent?.(o);break;case "gem.clusterTarget":this.options.onClusterTarget?.(o);break;case "gem.partyResult":this.options.onPartyResult?.(o);break;case "gem.purchaseResult":this.options.onPurchaseResult?.(o);break;case "gem.deviceSettings":this.options.onDeviceSettings?.(o);break;case "gem.deviceSettings.result":this.options.onDeviceSettingsResult?.(o);break;case "gem.adResult":this.options.onAdResult?.(o);break;case "gem.signInResult":this.options.onSignInResult?.(o);break;case "gem.error":this.options.onError?.(o.code,o.message);break;default: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 N(n){for(let e of n)try{e?.close?.();}catch{}}q();function Ke(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 h({...n,expectedSource:n.expectedSource??window.parent}),t=r=>{let i=e.handleWindowMessage({data:r.data,origin:r.origin,source:r.source,ports:r.ports});return i&&window.removeEventListener("message",t),i};return window.addEventListener("message",t),I(window,t),e}var V={connect:Ke,GemFrame:h,PROTOCOL:l,SUPPORTED_VERSIONS:y};window.GemWebSdkBridge=V;var it=V;return it;})();
|
|
1
|
+
var GemWebSdkBridgeBundle=(function(){'use strict';var b="GemWebSdkHandshake";function z(){return typeof document>"u"?void 0:document.readyState}var C=()=>Date.now();function I(n={}){let e=n.win??window,t=e,r=t[b];if(r!==void 0)return r;let i=n.readyState??z,s=n.now??C,d=[],o=[],m=g=>{let u=g.data;!u||u.type!=="gem.handshake"||(d.length>=4&&(d.shift(),o.shift(),c.dropped+=1),d.push(g),o.push(s()));};e.addEventListener("message",m);let c={events:d,times:o,dropped:0,late:i()==="complete",uninstall(){e.removeEventListener("message",m);}};return t[b]=c,c}function q(n,e,t={}){let r=n[b];if(r===void 0)return null;let i=t.ttlMs??9500,s=t.now??C,d=r.events.splice(0),o=r.times?.splice(0),m=0,c=0,g=false,u=s()-i;for(let k=d.length-1;k>=0;k--){let P=o?.[k];if(P!==void 0&&P<u){c+=1;continue}if(m+=1,e(d[k])===true){g=true;break}}return r.uninstall(),{capture:r,delivered:m,stale:c,accepted:g}}var l="gem-web-bridge",y={min:1,max:1},p=65536,L=8,v=5e3,_=1024;function R(n){return Object.freeze(Object.assign(Object.create(null),n))}var j=R({"gem.handshake":30,"gem.handshake.accept":5,"gem.token":30,"gem.token.denied":30,"gem.player":12,"gem.pause":120,"gem.prefs":60,"gem.cohorts":12,"gem.viewport":60,"gem.deviceSettings":12,"gem.willTerminate":10,"gem.roomEvent":120,"gem.socketState":12,"gem.seatedEvent":60,"gem.autoStartFailedEvent":30,"gem.signalEvent":1800,"gem.dedicatedEvent":120,"gem.partyResult":30,"gem.clusterTarget":12,"gem.devtools":30,"gem.screenshot":6,"gem.screenshot.denied":12,"gem.requestContext":12,"gem.gameContext":12,"gem.signal":1200,"gem.dedicatedOffer":60,"gem.partyRequest":12,"gem.ready":5,"gem.progress":600,"gem.requestToken":12,"gem.requestLocalServer":6,"gem.localServer":30,"gem.localServer.denied":30,"gem.exit":5,"gem.openExternal":6,"gem.requestFullscreen":30,"gem.audioState":120,"gem.rewardCue":60,"gem.frameStats":120,"gem.error":60,"gem.requestPurchase":12,"gem.purchaseResult":30,"gem.deviceSettings.put":30,"gem.deviceSettings.result":30,"gem.requestAd":6,"gem.adResult":12,"gem.requestSignIn":6,"gem.signInResult":12,__malformed:60}),x="__malformed";var B=R({"gem.requestAd":"ads","gem.adResult":"ads","gem.requestSignIn":"signIn","gem.signInResult":"signIn","gem.requestPurchase":"purchases","gem.purchaseResult":"purchases","gem.devtools":"devtools","gem.screenshot":"screenshot","gem.screenshot.denied":"screenshot","gem.requestContext":"feedbackContext","gem.gameContext":"feedbackContext","gem.roomEvent":"rooms","gem.signal":"p2p","gem.signalEvent":"p2p","gem.dedicatedOffer":"dedicated","gem.dedicatedEvent":"dedicated","gem.clusterTarget":"clusterTarget","gem.partyRequest":"parties","gem.partyResult":"parties","gem.autoStartFailedEvent":"autoStartFailure","gem.seatedEvent":"partySeating","gem.socketState":"socketState","gem.audioState":"audioState","gem.rewardCue":"rewardCue","gem.frameStats":"frameStats","gem.viewport":"viewport","gem.requestLocalServer":"localHost","gem.localServer":"localHost","gem.localServer.denied":"localHost","gem.cohorts":"cohorts","gem.deviceSettings":"deviceSettings","gem.deviceSettings.put":"deviceSettings","gem.deviceSettings.result":"deviceSettings"}),K=Object.freeze([["gem.asyncOpponents.","asyncOpponents"]]);function A(n){let e=B[n];if(e!==void 0)return e;for(let[t,r]of K)if(n.startsWith(t))return r}function Y(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 X(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 J(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function S(n,e,t){if(e>L)return `nesting deeper than ${L}`;if(++t.nodes>v)return `more than ${v} values`;if(t.bytes>p)return `over the ${p} 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 i=n;if(t.seen.has(i))return "a repeated or cyclic object reference";if(t.seen.add(i),Array.isArray(n)){if(n.length>_)return `an array of ${n.length} entries, over the ${_} limit`;t.bytes+=2;for(let o of n){let m=S(o,e+1,t);if(m)return m}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 o in d){if(!Object.prototype.hasOwnProperty.call(d,o))continue;if(++t.nodes>v)return `more than ${v} values`;if(t.bytes+=o.length*3+4,t.bytes>p)return `over the ${p} byte limit`;let m=S(d[o],e+1,t);if(m)return m}return null}function Q(n){let e={nodes:0,bytes:0,seen:new Set},t=S(n,0,e);return t?`message contains ${t}`:e.bytes>p?`message is over the ${p} byte limit`:null}var Z={origin:[Y,"not a well-formed origin"],url:[X,"not a safe absolute http(s) URL"],bcp47:[J,"not a well-formed BCP 47 tag"]};function M(n,e,t){for(let r of e){let i=t===""?r.n:`${t}.${r.n}`,s=n[r.n];if(s==null){if(r.o)continue;return `${i}: required`}let d=D(s,r,i);if(d)return d}return null}function D(n,e,t){switch(e.k){case "string":{if(typeof n!="string")return `${t}: expected string`;if(n.length>e.max)return `${t}: exceeds ${e.max} characters`;if(e.f){let[r,i]=Z[e.f];if(!r(n))return `${t}: ${i}`}return null}case "int":return typeof n!="number"||!Number.isInteger(n)?`${t}: expected integer`:n<e.lo||n>e.hi?`${t}: out of range ${e.lo}..${e.hi}`:null;case "boolean":return typeof n=="boolean"?null:`${t}: expected boolean`;case "enum":{let r=e.v;return r.includes(n)?null:`${t}: not one of ${r.join("|")}`}case "object":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:M(n,e.fs,t);case "json":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected a plain object`:null;case "array":{if(!Array.isArray(n))return `${t}: expected array`;if(n.length>e.max)return `${t}: exceeds ${e.max} items`;let r=e.it,i=`${t}[]`;for(let s of n){if(s==null){if(r.o)continue;return `${i}: required`}let d=D(s,r,i);if(d)return d}return null}default:{let r=e.k;return `${t}: unknown kind ${String(r)}`}}}function a(n,e){return t=>{let r=Q(t);if(r)return r;if(typeof t!="object"||t===null||Array.isArray(t))return "message: expected object";let i=t;return i.gem!==l?"gem: wrong protocol marker":i.type!==n?`type: expected ${n}`:M(i,e,"")}}var ee=a("gem.handshake",[{n:"versions",k:"object",fs:[{n:"min",k:"int",lo:1,hi:1e3},{n:"max",k:"int",lo:1,hi:1e3}]},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}},{n:"embedder",k:"string",max:2048,f:"origin"}]),te=a("gem.handshake.accept",[{n:"v",k:"int",lo:1,hi:1e3},{n:"capabilities",k:"array",o:1,max:64,it:{n:"",k:"string",max:64}}]),ne=a("gem.token",[{n:"token",k:"string",max:4096},{n:"requestId",k:"string",o:1,max:64},{n:"generation",k:"int",lo:0,hi:2147483647},{n:"apiBaseUrl",k:"string",o:1,max:512,f:"url"},{n:"playerId",k:"string",max:64},{n:"gameId",k:"string",max:64},{n:"channel",k:"enum",v:["dev","test","release"]},{n:"gameVersion",k:"string",o:1,max:64},{n:"expiresAt",k:"int",lo:0,hi:4102444800},{n:"chainEndsAt",k:"int",lo:0,hi:4102444800},{n:"allowDevTools",k:"boolean",o:1}]),re=a("gem.token.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"retryAfterMs",k:"int",o:1,lo:0,hi:36e5},{n:"reason",k:"enum",v:["chain_exhausted","unavailable"]},{n:"correlationId",k:"string",max:64}]),oe=a("gem.player",[{n:"untrusted",k:"object",fs:[{n:"displayName",k:"string",max:64},{n:"displayTag",k:"string",o:1,max:80},{n:"displayHandle",k:"string",max:80}]},{n:"playerId",k:"string",o:1,max:64},{n:"discriminator",k:"string",o:1,max:8},{n:"avatarIconUrl",k:"string",o:1,max:2048,f:"url"},{n:"badges",k:"array",o:1,max:2,it:{n:"",k:"object",fs:[{n:"itemId",k:"string",max:64},{n:"iconUrl",k:"string",max:2048,f:"url"}]}},{n:"displayTag",k:"string",max:8},{n:"avatarUrl",k:"string",o:1,max:2048,f:"url"}]),ae=a("gem.pause",[{n:"paused",k:"boolean"}]),se=a("gem.prefs",[{n:"reducedMotion",k:"boolean"},{n:"muted",k:"boolean"},{n:"showFrameStats",k:"boolean",o:1},{n:"locale",k:"string",max:35,f:"bcp47"}]),ie=a("gem.cohorts",[{n:"cohorts",k:"array",max:8,it:{n:"",k:"object",fs:[{n:"experimentId",k:"string",max:36},{n:"variantKey",k:"string",max:32}]}}]),de=a("gem.viewport",[{n:"insets",k:"object",fs:[{n:"top",k:"int",lo:0,hi:4096},{n:"right",k:"int",lo:0,hi:4096},{n:"bottom",k:"int",lo:0,hi:4096},{n:"left",k:"int",lo:0,hi:4096}]}]),le=a("gem.deviceSettings",[{n:"settings",k:"json",o:1}]),me=a("gem.willTerminate",[{n:"reason",k:"enum",v:["grant_expiring","session_ended","navigating","kill_switch"]},{n:"graceMs",k:"int",lo:0,hi:6e4}]),ce=a("gem.roomEvent",[{n:"event",k:"enum",v:["updated","match_started","match_ready","match_failed","version_stale"]},{n:"roomId",k:"string",max:64},{n:"matchId",k:"string",o:1,max:64},{n:"version",k:"int",o:1,lo:0,hi:2147483647},{n:"reason",k:"string",o:1,max:64},{n:"platform",k:"enum",o:1,v:["universal","mobile"]}]),ge=a("gem.socketState",[{n:"connected",k:"boolean"},{n:"reason",k:"enum",o:1,v:["connecting","dropped","watchdog","terminal"]}]),ue=a("gem.seatedEvent",[{n:"roomId",k:"string",max:64}]),pe=a("gem.autoStartFailedEvent",[{n:"roomId",k:"string",max:64},{n:"code",k:"string",max:64}]),ye=a("gem.signalEvent",[{n:"event",k:"enum",v:["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),fe=a("gem.dedicatedEvent",[{n:"event",k:"enum",v:["answer","error","matchEnded"]},{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",o:1,max:10240},{n:"sessionId",k:"string",o:1,max:64},{n:"code",k:"string",o:1,max:64},{n:"message",k:"string",o:1,max:256},{n:"reason",k:"string",o:1,max:64}]),he=a("gem.partyResult",[{n:"requestId",k:"string",max:64},{n:"partyId",k:"string",o:1,max:64}]),ke=a("gem.clusterTarget",[{n:"clusterTargetId",k:"string",max:64},{n:"clusterTargetIds",k:"array",o:1,max:3,it:{n:"",k:"string",max:64}}]),ve=a("gem.devtools",[{n:"action",k:"enum",v:["open","close","toggle"]}]),xe=a("gem.screenshot",[{n:"maxWidth",k:"int",lo:1,hi:7680},{n:"maxHeight",k:"int",lo:1,hi:4320}]),we=a("gem.screenshot.denied",[{n:"reason",k:"enum",v:["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]},{n:"retryable",k:"boolean"}]),be=a("gem.requestContext",[]),Se=a("gem.gameContext",[{n:"context",k:"json"}]),Re=a("gem.signal",[{n:"signal",k:"enum",v:["join","offer","answer","ice","migrationAck","hostUnreachable"]},{n:"matchId",k:"string",max:64},{n:"data",k:"json"}]),Ge=a("gem.dedicatedOffer",[{n:"matchId",k:"string",max:64},{n:"sdp",k:"string",max:10240},{n:"intent",k:"enum",v:["initial","ice_restart","full_reconnect"]}]),Oe=a("gem.partyRequest",[{n:"requestId",k:"string",max:64}]),Te=a("gem.ready",[]),Ee=a("gem.progress",[{n:"loaded",k:"int",lo:0,hi:1099511627776},{n:"total",k:"int",lo:0,hi:1099511627776}]),Pe=a("gem.requestToken",[{n:"requestId",k:"string",max:64},{n:"reason",k:"enum",v:["initial","expiring","rejected"]}]),Ce=a("gem.requestLocalServer",[{n:"requestId",k:"string",max:64},{n:"gameRoomId",k:"string",max:64}]),Ie=a("gem.localServer",[{n:"requestId",k:"string",max:64},{n:"serverId",k:"string",o:1,max:128}]),qe=a("gem.localServer.denied",[{n:"requestId",k:"string",max:64},{n:"retryable",k:"boolean"},{n:"reason",k:"enum",v:["refused","unavailable"]}]),Le=a("gem.exit",[{n:"reason",k:"string",o:1,max:64}]),_e=a("gem.openExternal",[{n:"url",k:"string",max:2048,f:"url"}]),je=a("gem.requestFullscreen",[{n:"enabled",k:"boolean"}]),Ae=a("gem.audioState",[{n:"muted",k:"boolean"}]),Me=a("gem.rewardCue",[{n:"currencySlug",k:"string",max:32},{n:"expected",k:"int",o:1,lo:1,hi:1e9},{n:"origin",k:"object",o:1,fs:[{n:"x",k:"int",lo:0,hi:16384},{n:"y",k:"int",lo:0,hi:16384}]}]),De=a("gem.frameStats",[{n:"fps",k:"int",lo:0,hi:1e3},{n:"frameTimeP95Ms",k:"int",lo:0,hi:1e5}]),Fe=a("gem.error",[{n:"code",k:"enum",v:["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]},{n:"message",k:"string",o:1,max:256}]),$e=a("gem.requestPurchase",[{n:"requestId",k:"string",max:64},{n:"purchaseKind",k:"enum",v:["item","recipe"]},{n:"targetId",k:"string",max:64},{n:"currencySlug",k:"string",max:32},{n:"quantity",k:"int",o:1,lo:1,hi:10},{n:"catalogId",k:"string",o:1,max:64}]),He=a("gem.purchaseResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["ok","declined","unavailable"]},{n:"purchaseId",k:"string",o:1,max:64}]),Ue=a("gem.deviceSettings.put",[{n:"requestId",k:"string",max:64},{n:"settings",k:"json"}]),We=a("gem.deviceSettings.result",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["stored","too_large","unavailable"]}]),Ne=a("gem.requestAd",[{n:"requestId",k:"string",max:64},{n:"placement",k:"string",max:32},{n:"format",k:"enum",v:["interstitial","rewarded"]}]),Ve=a("gem.adResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["shown","no_ad","unavailable"]}]),ze=a("gem.requestSignIn",[{n:"requestId",k:"string",max:64}]),Be=a("gem.signInResult",[{n:"requestId",k:"string",max:64},{n:"outcome",k:"enum",v:["signed_in","declined","unavailable"]}]),w=R({"gem.handshake":ee,"gem.handshake.accept":te,"gem.token":ne,"gem.token.denied":re,"gem.player":oe,"gem.pause":ae,"gem.prefs":se,"gem.cohorts":ie,"gem.viewport":de,"gem.deviceSettings":le,"gem.willTerminate":me,"gem.roomEvent":ce,"gem.socketState":ge,"gem.seatedEvent":ue,"gem.autoStartFailedEvent":pe,"gem.signalEvent":ye,"gem.dedicatedEvent":fe,"gem.partyResult":he,"gem.clusterTarget":ke,"gem.devtools":ve,"gem.screenshot":xe,"gem.screenshot.denied":we,"gem.requestContext":be,"gem.gameContext":Se,"gem.signal":Re,"gem.dedicatedOffer":Ge,"gem.partyRequest":Oe,"gem.ready":Te,"gem.progress":Ee,"gem.requestToken":Pe,"gem.requestLocalServer":Ce,"gem.localServer":Ie,"gem.localServer.denied":qe,"gem.exit":Le,"gem.openExternal":_e,"gem.requestFullscreen":je,"gem.audioState":Ae,"gem.rewardCue":Me,"gem.frameStats":De,"gem.error":Fe,"gem.requestPurchase":$e,"gem.purchaseResult":He,"gem.deviceSettings.put":Ue,"gem.deviceSettings.result":We,"gem.requestAd":Ne,"gem.adResult":Ve,"gem.requestSignIn":ze,"gem.signInResult":Be});var G=class{#e;constructor(e){this.#e=e,Object.freeze(this);}toString(){return "[gem: use gem.text.toPlain()]"}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function O(n){return new G(n)}var T={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)},f=class{constructor(e=T){this.clock=e;}clock;tokens=new Map;lastRefill=new Map;allow(e){let t=j[e];if(t===void 0)return false;let r=this.clock.now(),i=this.lastRefill.get(e)??r,s=this.tokens.get(e)??t,d=Math.max(0,r-i),o=Math.min(t,s+d*t/6e4);return o<1?(this.tokens.set(e,o),this.lastRefill.set(e,r),false):(this.tokens.set(e,o-1),this.lastRefill.set(e,r),true)}};function E(n,e){return n.toLowerCase()===e.toLowerCase()}function F(n){let e=n.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}function $(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:F(t.hostname)&&F(r.hostname)}function H(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}function U(n){return Math.min(16384,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}function W(n,e){return Math.min(e,Math.max(0,Math.round(Number.isFinite(n)?n:0)))}function Ke(n){let e=n.untrusted,t=O(e.displayName),r=e.displayTag||e.displayHandle,i=r?O(r):void 0,s=n.discriminator||n.displayTag,d=s&&/^[0-9]{1,8}$/.test(s)?s:void 0,o=n.avatarIconUrl||n.avatarUrl,m={displayName:t,displayHandle:i??t,badges:(n.badges??[]).map(c=>({itemId:c.itemId,iconUrl:c.iconUrl}))};return n.playerId&&(m.playerId=n.playerId),d&&(m.discriminator=d),i&&(m.displayTag=i),o&&(m.avatarIconUrl=m.avatarUrl=o),m}var Ye=1e4,h=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??T,this.inbound=new f(this.clock),this.outbound=new f(this.clock);}options;state="waiting";port=null;version=null;peerCapabilities=[];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}handleWindowMessage(e){if(e.source!==this.expectedSource)return this.refuse(e,"handshake did not come from the expected embedder window"),false;if(!(this.options.allowedEmbedders.some(o=>E(o,e.origin))||$(e.origin,this.options.selfOrigin)))return this.refuse(e,`embedder '${e.origin}' is not in allowedEmbedders`),false;if(this.state==="connected")return this.fail("handshake_duplicate","this document already has a port"),false;if(this.state!=="waiting")return false;let r=w["gem.handshake"]?.(e.data);if(r)return this.refuse(e,`malformed handshake: ${r}`),false;let i=e.data;if(!E(i.embedder,e.origin))return this.refuse(e,`handshake claims embedder '${i.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=H(y,i.versions);return d===null?(s.onmessage=null,s.postMessage({gem:l,type:"gem.error",code:"version_mismatch",message:`frame supports v${y.min}..v${y.max}`}),s.close(),this.transition("refused"),this.options.onError?.("version_mismatch"),false):(this.port=s,this.version=d,s.onmessage=o=>this.receive(o.data,o.ports??[]),s.start?.(),this.peerCapabilities=i.capabilities??[],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=Ye){return this.state!=="waiting"?Promise.resolve(this.state):new Promise(t=>{let r=s=>{this.clock.clearTimeout(i),t(s);},i=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.state!=="connected"||!this.parentSupports("audioState")?false:(this.send({gem:l,type:"gem.audioState",muted:e}),true)}cueReward(e){if(this.state!=="connected"||!this.parentSupports("rewardCue"))return false;let t={gem:l,type:"gem.rewardCue",currencySlug:String(e.currencySlug).slice(0,32)};return 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:U(e.origin.x),y:U(e.origin.y)}),this.send(t),true}reportFrameStats(e){return this.state!=="connected"||!this.parentSupports("frameStats")?false:(this.send({gem:l,type:"gem.frameStats",fps:W(e.fps,1e3),frameTimeP95Ms:W(e.frameTimeP95Ms,1e5)}),true)}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,i,s,d){return this.send({gem:l,type:"gem.requestPurchase",requestId:e,purchaseKind:t,targetId:r,currencySlug:i,...s===void 0?{}:{quantity:s},...d===void 0?{}:{catalogId:d}})}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})}requestSignIn(e){return this.send({gem:l,type:"gem.requestSignIn",requestId: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(x)){this.options.onDropped?.(e,t);return}this.fail(e,t);}dropUnknownType(e){this.inbound.allow(x)&&this.options.onDropped?.("unsupported",`ignored unknown message type '${e}'`);}refuse(e,t){e.ports?.[0]?.close?.(),this.inbound.allow(x)&&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}});}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=w[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||N(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 i=w[r];if(!i)return this.dropUnknownType(r),false;if(!this.inbound.allow(r))return this.fail("rate_limited",`parent exceeded the limit for ${r}`),false;let s=A(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=i(e);if(d)return this.fail("invalid_message",`${r}: ${d}`),false;let o=e;if(o.v!==this.version)return this.fail("invalid_message",`${r}: expected v ${String(this.version)}`),false;switch(r){case "gem.token":this.options.onToken?.(o);break;case "gem.pause":this.options.onPause?.(o);break;case "gem.prefs":this.options.onPrefs?.(o);break;case "gem.cohorts":this.options.onCohorts?.(o);break;case "gem.viewport":this.options.onViewport?.(o);break;case "gem.willTerminate":this.options.onWillTerminate?.(o);break;case "gem.devtools":this.options.onDevtools?.(o.action);break;case "gem.requestContext":this.options.onRequestContext?.();break;case "gem.screenshot":{let m=t[0];if(!m){this.options.onError?.("invalid_message","gem.screenshot transferred no MessagePort");break}let c={maxWidth:o.maxWidth,maxHeight:o.maxHeight};if(!this.options.onScreenshot){m.close(),this.screenshotDenied("not_wired",false);break}return N(t.slice(1)),this.options.onScreenshot(c,m,(g,u)=>this.screenshotDenied(g,u)),true}case "gem.token.denied":this.options.onTokenDenied?.(o);break;case "gem.localServer":this.options.onLocalServer?.(o);break;case "gem.localServer.denied":this.options.onLocalServerDenied?.(o);break;case "gem.player":{this.options.onPlayer?.(Ke(o));break}case "gem.roomEvent":this.options.onRoomEvent?.(o);break;case "gem.seatedEvent":this.options.onSeatedEvent?.(o);break;case "gem.autoStartFailedEvent":this.options.onAutoStartFailedEvent?.(o);break;case "gem.socketState":this.options.onSocketState?.(o);break;case "gem.signalEvent":this.options.onSignalEvent?.(o);break;case "gem.dedicatedEvent":this.options.onDedicatedEvent?.(o);break;case "gem.clusterTarget":this.options.onClusterTarget?.(o);break;case "gem.partyResult":this.options.onPartyResult?.(o);break;case "gem.purchaseResult":this.options.onPurchaseResult?.(o);break;case "gem.deviceSettings":this.options.onDeviceSettings?.(o);break;case "gem.deviceSettings.result":this.options.onDeviceSettingsResult?.(o);break;case "gem.adResult":this.options.onAdResult?.(o);break;case "gem.signInResult":this.options.onSignInResult?.(o);break;case "gem.error":this.options.onError?.(o.code,o.message);break;default: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 N(n){for(let e of n)try{e?.close?.();}catch{}}I();function Xe(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 h({...n,expectedSource:n.expectedSource??window.parent}),t=r=>{let i=e.handleWindowMessage({data:r.data,origin:r.origin,source:r.source,ports:r.ports});return i&&window.removeEventListener("message",t),i};return window.addEventListener("message",t),q(window,t),e}var V={connect:Xe,GemFrame:h,PROTOCOL:l,SUPPORTED_VERSIONS:y};window.GemWebSdkBridge=V;var lt=V;return lt;})();
|