/**
 * Bundled by jsDelivr using Rollup v4.62.2 and esbuild v0.28.1.
 * Original file: /npm/@persistlyapp/sdk@1.3.1/dist/index.js
 *
 * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
 */
var ne=typeof global<"u"?global:typeof self<"u"?self:typeof window<"u"?window:{},oe={},L=ne.performance||{};L.now||L.mozNow||L.msNow||L.oNow||L.webkitNow;var ut={versions:oe};const se=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;function f(n,t){if(!ae(n))throw new Error(`${t} must be an object.`);return n}function dt(n){const t=f(n,"Save"),e=f(t.metadata,"Save.metadata"),o=f(t.state,"Save.state"),s=t.playerRef,a=t.version,r=t.createdAt,h=t.updatedAt;if(typeof t.saveId!="string")throw new Error("Save.saveId must be a string.");if(typeof a!="number"||!Number.isInteger(a)||a<1)throw new Error("Save.version must be an integer greater than or equal to 1.");if(!ft(r))throw new Error("Save.createdAt must be a valid RFC 3339 date-time string.");if(!ft(h))throw new Error("Save.updatedAt must be a valid RFC 3339 date-time string.");if(!(typeof s=="string"||s===null))throw new Error("Save.playerRef must be a string or null.");return{saveId:t.saveId,playerRef:s,metadata:e,state:o,version:a,createdAt:r,updatedAt:h}}function lt(n){return structuredClone(n)}function ae(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}function ft(n){return typeof n=="string"&&se.test(n)&&!Number.isNaN(Date.parse(n))}class ce{snapshots=new Map;get(t){const e=this.snapshots.get(t);return e?lt(e):null}set(t){const e=dt(t);this.snapshots.set(e.saveId,lt(e))}clear(t){this.snapshots.delete(t)}}class S extends Error{status;code;details;constructor(t,e,o,s){super(o),this.status=t,this.code=e,this.details=s,this.name="PersistlyApiError"}}class ht extends S{constructor(t,e,o=400){super(o,"invalid_request",t,e),this.name="PersistlyInvalidRequestError"}}class yt extends S{constructor(t,e,o=401){super(o,"unauthorized",t,e),this.name="PersistlyUnauthorizedError"}}class mt extends S{constructor(t,e,o=403){super(o,"forbidden",t,e),this.name="PersistlyForbiddenError"}}class St extends S{constructor(t,e,o=404){super(o,"not_found",t,e),this.name="PersistlyNotFoundError"}}class wt extends S{constructor(t,e,o=409){super(o,"conflict",t,e),this.name="PersistlyConflictError"}}class U extends S{constructor(t,e,o=409){super(o,"slot_already_exists",t,e),this.name="PersistlySlotAlreadyExistsError"}}class pt extends S{constructor(t,e,o=409){super(o,"slot_archived",t,e),this.name="PersistlySlotArchivedError"}}class At extends S{constructor(t,e,o=410){super(o,"account_deleted",t,e),this.name="PersistlyAccountDeletedError"}}class gt extends S{constructor(t,e,o=410){super(o,"slot_deleted",t,e),this.name="PersistlySlotDeletedError"}}class vt extends S{constructor(t,e,o=400){super(o,"transfer_code_invalid",t,e),this.name="PersistlyTransferCodeInvalidError"}}class It extends S{constructor(t,e,o=400){super(o,"transfer_code_expired",t,e),this.name="PersistlyTransferCodeExpiredError"}}class bt extends S{constructor(t,e,o=400){super(o,"transfer_code_consumed",t,e),this.name="PersistlyTransferCodeConsumedError"}}class Ct extends S{constructor(t,e,o=429){super(o,"transfer_code_rate_limited",t,e),this.name="PersistlyTransferCodeRateLimitedError"}}class Dt extends S{constructor(t,e,o=403){super(o,"transfer_code_disabled",t,e),this.name="PersistlyTransferCodeDisabledError"}}class Pt extends S{constructor(t,e,o,s=400){const a=typeof e=="string",r=a?t:"provider_token_invalid",h=a?e:t,w=a?o:e,p=a?s:typeof o=="number"?o:400;super(p,r,h,w),this.name="PersistlyProviderTokenInvalidError"}}class Rt extends S{constructor(t,e,o,s=401){const a=typeof e=="string",r=a?t:"firebase_project_mismatch",h=a?e:t,w=a?o:e,p=a?s:typeof o=="number"?o:401;super(p,r,h,w),this.name="PersistlyFirebaseProjectMismatchError"}}class _t extends S{constructor(t,e,o,s=403){const a=typeof e=="string",r=a?t:"auth_provider_not_configured",h=a?e:t,w=a?o:e,p=a?s:typeof o=="number"?o:403;super(p,r,h,w),this.name="PersistlyAuthProviderNotConfiguredError"}}class j extends S{constructor(t,e,o=409){super(o,"account_auth_conflict",t,e),this.name="PersistlyAccountAuthConflictError"}}function re(n){return n instanceof j?!0:typeof n=="object"&&n!==null&&"code"in n&&n.code==="account_auth_conflict"}class z extends S{constructor(t,e,o=429){super(o,"rate_limited",t,e),this.name="PersistlyRateLimitedError"}}class H extends S{constructor(t,e,o=413){super(o,"payload_too_large",t,e),this.name="PersistlyPayloadTooLargeError"}}class kt extends S{constructor(t,e,o=500){super(o,"server_error",t,e),this.name="PersistlyServerError"}}class E extends Error{cause;constructor(t,e){super(t),this.cause=e,this.name="PersistlyTransportError"}}class c extends Error{constructor(t){super(t),this.name="PersistlyConfigurationError"}}class A extends c{constructor(t){super(t),this.name="PersistlyStorageError"}}function Tt(n,t,e,o){switch(t){case"invalid_request":return new ht(e,o,n);case"unauthorized":return new yt(e,o,n);case"forbidden":return new mt(e,o,n);case"not_found":return new St(e,o,n);case"conflict":return new wt(e,o,n);case"slot_already_exists":return new U(e,o,n);case"slot_archived":return new pt(e,o,n);case"account_deleted":return new At(e,o,n);case"slot_deleted":return new gt(e,o,n);case"transfer_code_invalid":return new vt(e,o,n);case"transfer_code_expired":return new It(e,o,n);case"transfer_code_consumed":return new bt(e,o,n);case"transfer_code_rate_limited":return new Ct(e,o,n);case"transfer_code_disabled":return new Dt(e,o,n);case"provider_token_invalid":case"firebase_token_invalid":case"firebase_token_expired":case"supabase_token_missing":case"supabase_token_invalid":case"supabase_token_expired":case"auth0_token_missing":case"auth0_token_invalid":case"auth0_token_expired":return new Pt(t,e,o,n);case"firebase_project_mismatch":case"supabase_project_mismatch":case"supabase_audience_mismatch":case"auth0_issuer_mismatch":case"auth0_audience_mismatch":return new Rt(t,e,o,n);case"auth_provider_not_configured":case"provider_not_configured":case"provider_not_enabled":case"provider_not_supported":case"supabase_project_url_required":case"supabase_project_url_invalid":case"auth0_domain_required":case"auth0_domain_invalid":return new _t(t,e,o,n);case"account_auth_conflict":return new j(e,o,n);case"rate_limited":return new z(e,o,n);case"payload_too_large":return new H(e,o,n);case"server_error":return new kt(e,o,n);default:{const s=t;throw new S(n,s,e,o)}}}var ie=16384,ue=262144,de={free:{monthlyRuntimeRequests:1e5,prodRuntimeRequestsPerMinute:60,stageRuntimeRequestsPerMinute:20,burstCapacityRequests:120,storageQuotaBytes:1073741824,restoreHistoryDays:1,normalSnapshotIntervalSeconds:1800,maxNormalSnapshotsPerSlot:24,accountDataMaxBytes:262144,slotDataMaxBytes:262144,slotInfoMaxBytes:16384,gameConfigMaxBytes:16384},starter:{monthlyRuntimeRequests:1e6,prodRuntimeRequestsPerMinute:300,stageRuntimeRequestsPerMinute:60,burstCapacityRequests:600,storageQuotaBytes:26843545600,restoreHistoryDays:7,normalSnapshotIntervalSeconds:600,maxNormalSnapshotsPerSlot:100,accountDataMaxBytes:524288,slotDataMaxBytes:524288,slotInfoMaxBytes:32768,gameConfigMaxBytes:32768},growth:{monthlyRuntimeRequests:5e6,prodRuntimeRequestsPerMinute:1200,stageRuntimeRequestsPerMinute:120,burstCapacityRequests:2400,storageQuotaBytes:107374182400,restoreHistoryDays:30,normalSnapshotIntervalSeconds:300,maxNormalSnapshotsPerSlot:300,accountDataMaxBytes:1048576,slotDataMaxBytes:1048576,slotInfoMaxBytes:65536,gameConfigMaxBytes:65536},pro:{monthlyRuntimeRequests:2e7,prodRuntimeRequestsPerMinute:3e3,stageRuntimeRequestsPerMinute:300,burstCapacityRequests:6e3,storageQuotaBytes:536870912e3,restoreHistoryDays:90,normalSnapshotIntervalSeconds:60,maxNormalSnapshotsPerSlot:1e3,accountDataMaxBytes:2097152,slotDataMaxBytes:2097152,slotInfoMaxBytes:131072,gameConfigMaxBytes:131072},creator_demo:{monthlyRuntimeRequests:1e5,prodRuntimeRequestsPerMinute:100,stageRuntimeRequestsPerMinute:30,burstCapacityRequests:200,storageQuotaBytes:1073741824,restoreHistoryDays:1,normalSnapshotIntervalSeconds:1800,maxNormalSnapshotsPerSlot:24,accountDataMaxBytes:262144,slotDataMaxBytes:262144,slotInfoMaxBytes:16384,gameConfigMaxBytes:16384}},le=["invalid_request","unauthorized","not_found","conflict","rate_limited","monthly_quota_exceeded","payload_too_large","server_error"],fe=["base_version_mismatch"],he={slotInfoMaxBytes:ie,slotDataMaxBytes:ue,planLimits:de,errorCodes:le,conflictReasons:fe};let O;function N(n){const t=ye();n.accountData&&M("accountData",n.accountData,t.accountDataMaxBytes),n.slotInfo&&M("slotInfo",n.slotInfo,t.slotInfoMaxBytes),n.data&&M("data",n.data,t.slotDataMaxBytes),n.metadata&&M("metadata",n.metadata,t.slotInfoMaxBytes),n.state&&M("state",n.state,t.slotDataMaxBytes)}function ye(){if(O)return O;const n=he;if(!Array.isArray(n.errorCodes)||!Array.isArray(n.conflictReasons))throw new Error("Pinned runtime-limits.json is malformed.");return O={slotInfoMaxBytes:W(n,"slotInfoMaxBytes",n.slotInfoMaxBytes),slotDataMaxBytes:W(n,"slotDataMaxBytes",n.slotDataMaxBytes),accountDataMaxBytes:W(n,"accountDataMaxBytes",n.slotDataMaxBytes),...xt(n.planLimits)?{planLimits:n.planLimits}:{},errorCodes:n.errorCodes,conflictReasons:n.conflictReasons},O}function M(n,t,e){const o=JSON.stringify(t);if(Se(o)>e)throw new H(`${me(n)} exceeds the maximum allowed size.`,{field:n,maxBytes:e})}function me(n){switch(n){case"accountData":return"Account data";case"slotInfo":return"Slot info";case"data":return"Data";case"state":return"State";case"metadata":return"Metadata"}}function W(n,t,e){if(!xt(n.planLimits))return e;let o=e;for(const s of Object.values(n.planLimits)){const a=s[t];typeof a=="number"&&Number.isFinite(a)&&a>o&&(o=a)}return o}function xt(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}function Se(n){return typeof TextEncoder<"u"?new TextEncoder().encode(n).byteLength:n.length}const _={Accepted:"accepted",Conflict:"conflict"},Lt="https://api.persistly.app",Et="1.3.1";class Nt{baseUrl;runtimeKey;cache;fetchImpl;diagnosticsHeaders;constructor(t){if(!t.runtimeKey)throw new c("PersistlyClient requires a non-empty runtimeKey.");const e=t.fetch??Ie(globalThis.fetch);if(typeof e!="function")throw new c("PersistlyClient requires a fetch implementation.");this.baseUrl=Lt.replace(/\/+$/,""),this.runtimeKey=t.runtimeKey,this.cache=t.cache??new ce,this.fetchImpl=e,this.diagnosticsHeaders=we(t)}async updateLocal(t){const e=X(t);return await this.cache.set(e),e}async getLocal(t){return ge(t,"getLocal"),await this.cache.get(t)}async createAccount(t){Me(t);const e=$e(t),o=await this.requestJson("/api/v1/accounts",{method:"POST",body:JSON.stringify(e)});return Mt(q(o))}async exchangeAccountAuthSession(t){const e=qe(t.provider,"exchangeAccountAuthSession"),o=Ke(t.token,"exchangeAccountAuthSession");if(t.accountId===void 0!=(t.accountSessionToken===void 0))throw new c("exchangeAccountAuthSession requires both accountId and accountSessionToken when linking to a current account.");const s=await this.requestJson("/api/v1/accounts/auth/session",{method:"POST",headers:t.accountSessionToken===void 0?{}:g(t.accountSessionToken,t.accountId),body:JSON.stringify({provider:e,token:o,...t.deviceLabel===void 0?{}:{deviceLabel:t.deviceLabel}})});return Ve(s)}async listLinkedAuthProviders(t){const e=v(t.accountId,"listLinkedAuthProviders");I(t.accountSessionToken,"listLinkedAuthProviders");const o=await this.requestJson("/api/v1/accounts/auth/providers",{method:"GET",headers:g(t.accountSessionToken,e)});return Oe(o)}async syncAccountData(t){const e=v(t.accountId,"syncAccountData");I(t.accountSessionToken,"syncAccountData"),Be(t),N({...t.accountData===void 0&&t.accountDataPatch===void 0?{}:{accountData:t.accountData??t.accountDataPatch}});const o={baseVersion:t.baseVersion};t.accountData!==void 0&&(o.accountData=t.accountData),t.accountDataPatch!==void 0&&(o.accountDataPatch=t.accountDataPatch);const s=await this.requestRaw(`/api/v1/accounts/${encodeURIComponent(e)}/data/sync`,{method:"POST",headers:g(t.accountSessionToken),body:JSON.stringify(o)}),a=await Q(s);if(s.status===200){const r=qt(a),h=await this.cache.get(e)??void 0,w=Kt(r,r.save??Ee({saveId:e,cached:h,accountData:t.accountData,accountDataPatch:t.accountDataPatch}));return await this.cache.set(w.save),w}if(s.status===409&&Bt(a)){const r=Ot(a,{saveId:e});return await this.cache.set(r.save),r}throw tt(s.status,a)}async loadAccount(t){return(await this.loadAccountEnvelope(t)).account}async loadAccountEnvelope(t){const e=v(t.accountId,"loadAccount");I(t.accountSessionToken,"loadAccount");const o=await this.requestJson(`/api/v1/accounts/${encodeURIComponent(e)}`,{method:"GET",headers:g(t.accountSessionToken)});return q(o)}async createTransferCode(t){const e=v(t.accountId,"createTransferCode");I(t.accountSessionToken,"createTransferCode");const o=await this.requestJson(`/api/v1/accounts/${encodeURIComponent(e)}/transfer-codes`,{method:"POST",headers:g(t.accountSessionToken),body:JSON.stringify(Ft(t))});return De(o)}async consumeTransferCode(t){const e=ve(t.transferCode,"consumeTransferCode"),o=await this.requestJson("/api/v1/account-transfer-codes/consume",{method:"POST",body:JSON.stringify(Ft({transferCode:e,...t.deviceLabel===void 0?{}:{deviceLabel:t.deviceLabel}}))});return Mt(q(o))}async deleteAccount(t){const e=v(t.accountId,"deleteAccount");I(t.accountSessionToken,"deleteAccount");const o=await this.requestJson(`/api/v1/accounts/${encodeURIComponent(e)}`,{method:"DELETE",headers:g(t.accountSessionToken)}),s=be(o);return await this.cache.clear(e),s}async createAccountSlot(t){const e=v(t.accountId,"createAccountSlot"),o=k(t.slotId,"createAccountSlot");I(t.accountSessionToken,"createAccountSlot"),N({slotInfo:t.slotInfo??{},data:t.data});const s=await this.requestJson(`/api/v1/accounts/${encodeURIComponent(e)}/slots`,{method:"POST",headers:g(t.accountSessionToken),body:JSON.stringify({slotId:o,slotInfo:t.slotInfo??{},data:t.data})});return Pe(q(s))}async loadAccountSlot(t){const e=v(t.accountId,"loadAccountSlot"),o=k(t.slotId,"loadAccountSlot");I(t.accountSessionToken,"loadAccountSlot");const s=await this.requestJson(`/api/v1/accounts/${encodeURIComponent(e)}/slots/${encodeURIComponent(o)}`,{method:"GET",headers:g(t.accountSessionToken)});return Z(s)}async deleteAccountSlot(t){const e=v(t.accountId,"deleteAccountSlot"),o=k(t.slotId,"deleteAccountSlot");I(t.accountSessionToken,"deleteAccountSlot");const s=await this.requestJson(`/api/v1/accounts/${encodeURIComponent(e)}/slots/${encodeURIComponent(o)}`,{method:"DELETE",headers:g(t.accountSessionToken)});return Ce(s)}async syncAccountSlot(t){const e=v(t.accountId,"syncAccountSlot"),o=k(t.slotId,"syncAccountSlot");I(t.accountSessionToken,"syncAccountSlot"),N({slotInfo:t.slotInfo??{},data:t.data});const s=Le(e,o),a=await this.cache.get(s)??void 0,r=t.baseVersion??a?.version;if(!r)throw new c("syncAccountSlot requires baseVersion unless the cache already holds a canonical slot snapshot for this accountId and slotId.");const h=await this.requestRaw(`/api/v1/accounts/${encodeURIComponent(e)}/slots/${encodeURIComponent(o)}/sync`,{method:"POST",headers:g(t.accountSessionToken),body:JSON.stringify({baseVersion:r,slotInfo:t.slotInfo,data:t.data})}),w=await Q(h);if(h.status===200){const p=qt(w),it=Kt(p,p.save??xe({saveId:s,cached:a,metadata:t.slotInfo,state:t.data}));return await this.cache.set(it.save),it}if(h.status===409&&Bt(w)){const p=Ot(w,{saveId:s});return await this.cache.set(p.save),p}throw tt(h.status,w)}async archiveAccountSlot(t){const e=v(t.accountId,"archiveAccountSlot"),o=k(t.slotId,"archiveAccountSlot");I(t.accountSessionToken,"archiveAccountSlot");const s=await this.requestJson(`/api/v1/accounts/${encodeURIComponent(e)}/slots/${encodeURIComponent(o)}/archive`,{method:"POST",headers:g(t.accountSessionToken)});return q(s)}async getRuntimeConfig(t={}){const e=Ae(t),o=await this.requestJson(e,{method:"GET"});return _e(o)}async requestJson(t,e){const o=await this.requestRaw(t,e),s=await Q(o);if(!o.ok)throw tt(o.status,s);return s}async requestRaw(t,e){try{return await this.fetchImpl(new URL(t,`${this.baseUrl}/`),{...e,headers:{authorization:`Bearer ${this.runtimeKey}`,"content-type":"application/json",...this.diagnosticsHeaders,...e.headers}})}catch(o){throw new E("Persistly request failed before the runtime API responded.",o)}}}function we(n){const t=$(n.sdkName)??"javascript",e=$(n.sdkVersion)??Et,o=$(n.platform)??pe(),s=$(n.engineVersion),a=$(n.clientVersion);return{"x-persistly-sdk":t,"x-persistly-sdk-version":e,"x-persistly-platform":o,...s===void 0?{}:{"x-persistly-engine-version":s},...a===void 0?{}:{"x-persistly-client-version":a}}}function pe(){return typeof window<"u"&&typeof document<"u"?"browser":typeof ut<"u"&&ut.versions?.node?"node":"javascript"}function $(n){const t=n?.trim();if(t&&/[\r\n]/u.test(t))throw new c("Persistly diagnostics values must be valid single-line HTTP header values.");return t||void 0}function Ae(n){if(n.gameConfigVersion===void 0)return"/api/v1/runtime-config";if(typeof n.gameConfigVersion!="number"||!Number.isInteger(n.gameConfigVersion)||n.gameConfigVersion<0)throw new c("getRuntimeConfig gameConfigVersion must be a non-negative integer.");return`/api/v1/runtime-config?gameConfigVersion=${encodeURIComponent(String(n.gameConfigVersion))}`}function ge(n,t){const e=n.trim();if(!e)throw new c(`${t} requires a non-empty saveId.`);return e}function v(n,t){const e=n.trim();if(!e)throw new c(`${t} requires a non-empty accountId.`);return e}function k(n,t){if(typeof n!="string"||!/^[A-Za-z0-9_.-]{1,64}$/.test(n))throw new c(`${t} slotId must match ^[A-Za-z0-9_.-]{1,64}$.`);return n}function I(n,t){if(typeof n!="string"||n.trim()==="")throw new c(`${t} requires a non-empty accountSessionToken.`);return n}function ve(n,t){if(typeof n!="string"||n.trim()==="")throw new c(`${t} requires a non-empty transferCode.`);return n.trim()}function g(n,t){return{...t===void 0?{}:{"x-persistly-account-id":t},"x-persistly-account-session":n}}function Ie(n){return typeof n!="function"?n:n.bind(globalThis)}async function Q(n){const t=await n.text();if(t.trim().length===0){if(n.ok)throw new E("Persistly response was unexpectedly empty.",null);return{error:{code:"server_error",message:`Persistly returned an empty error response with status ${n.status}.`}}}try{return JSON.parse(t)}catch(e){if(!n.ok)return{error:{code:"server_error",message:`Persistly returned a non-JSON error response with status ${n.status}.`,details:{rawBody:t.slice(0,500)}}};throw new E("Persistly response was not valid JSON.",e)}}function be(n){const t=m(n,"Delete account response");if(typeof t.accountId!="string"||t.accountId.trim()==="")throw new c("Delete account response accountId must be a non-empty string.");if(typeof t.deletedAt!="string"||Number.isNaN(Date.parse(t.deletedAt)))throw new c("Delete account response deletedAt must be a valid date-time string.");if(typeof t.deletedSlotCount!="number"||!Number.isInteger(t.deletedSlotCount)||t.deletedSlotCount<0)throw new c("Delete account response deletedSlotCount must be a non-negative integer.");if(typeof t.alreadyDeleted!="boolean")throw new c("Delete account response alreadyDeleted must be a boolean.");if(typeof t.cleanupQueued!="boolean")throw new c("Delete account response cleanupQueued must be a boolean.");return{accountId:t.accountId,deletedAt:t.deletedAt,deletedSlotCount:t.deletedSlotCount,alreadyDeleted:t.alreadyDeleted,cleanupQueued:t.cleanupQueued}}function Ce(n){const t=m(n,"Delete account slot response");if(typeof t.accountId!="string"||t.accountId.trim()==="")throw new c("Delete account slot response accountId must be a non-empty string.");if(typeof t.slotId!="string"||t.slotId.trim()==="")throw new c("Delete account slot response slotId must be a non-empty string.");if(typeof t.deletedAt!="string"||Number.isNaN(Date.parse(t.deletedAt)))throw new c("Delete account slot response deletedAt must be a valid date-time string.");if(typeof t.alreadyDeleted!="boolean")throw new c("Delete account slot response alreadyDeleted must be a boolean.");if(typeof t.cleanupQueued!="boolean")throw new c("Delete account slot response cleanupQueued must be a boolean.");return{accountId:t.accountId,slotId:t.slotId,deletedAt:t.deletedAt,alreadyDeleted:t.alreadyDeleted,cleanupQueued:t.cleanupQueued,...t.account===void 0?{}:{account:G(t.account)}}}function De(n){const t=m(n,"Create transfer code response"),e=t.expiresInSeconds;if(typeof t.transferCode!="string"||t.transferCode.trim()==="")throw new c("Create transfer code response transferCode must be a non-empty string.");if(typeof t.expiresAt!="string"||Number.isNaN(Date.parse(t.expiresAt)))throw new c("Create transfer code response expiresAt must be a valid date-time string.");if(typeof e!="number"||!Number.isInteger(e)||e<=0)throw new c("Create transfer code response expiresInSeconds must be a positive integer.");return{transferCode:t.transferCode,expiresAt:t.expiresAt,expiresInSeconds:e}}function q(n){const t=m(n,"Account response"),e=t.accountId,o=t.accountSessionToken,s=G(t.account??t),a=t.slot===void 0||t.slot===null?void 0:Z(t.slot),r=t.syncPolicy===void 0?void 0:Y(t.syncPolicy);if(typeof e!="string"||e.trim()==="")throw new c("Account response accountId must be a non-empty string.");if(!(o===void 0||typeof o=="string"))throw new c("Account response accountSessionToken must be a string when present.");return{accountId:e,...o===void 0?{}:{accountSessionToken:o},account:s,...a===void 0?{}:{slot:a},...r===void 0?{}:{syncPolicy:r}}}function Mt(n){if(typeof n.accountSessionToken!="string"||n.accountSessionToken.trim()==="")throw new c("Create account response must include a non-empty accountSessionToken.");if(n.syncPolicy===void 0)throw new c("Create account response must include syncPolicy.");return{...n,accountSessionToken:n.accountSessionToken,syncPolicy:n.syncPolicy}}function Pe(n){if(n.slot===void 0)throw new c("Create account slot response must include the slot.");return{...n,slot:n.slot}}function G(n){const t=m(n,"Account"),e=t.slots,o=t.version;if(typeof t.accountId!="string"||t.accountId.trim()==="")throw new c("Account.accountId must be a non-empty string.");if(!(e===void 0||Array.isArray(e)))throw new c("Account.slots must be an array when present.");if(!(o===void 0||typeof o=="number"&&Number.isInteger(o)&&o>=1))throw new c("Account.version must be a positive integer when present.");return{accountId:t.accountId,accountData:m(t.accountData??{},"Account.accountData"),slots:(e??[]).map((s,a)=>Re(s,`Account.slots[${a}]`)),...o===void 0?{}:{version:o}}}function Re(n,t){const e=m(n,t),o=e.version,s=e.status,a=e.updatedAt;if(typeof e.slotId!="string"||e.slotId.trim()==="")throw new c(`${t}.slotId must be a non-empty string.`);if(!(o===void 0||typeof o=="number"&&Number.isInteger(o)&&o>=1))throw new c(`${t}.version must be a positive integer when present.`);if(!(s===void 0||s==="active"||s==="archived"))throw new c(`${t}.status must be active or archived when present.`);if(!(a===void 0||typeof a=="string"))throw new c(`${t}.updatedAt must be a string when present.`);return{slotId:e.slotId,slotInfo:m(e.slotInfo??{},`${t}.slotInfo`),...o===void 0?{}:{version:o},...s===void 0?{}:{status:s},...a===void 0?{}:{updatedAt:a}}}function Z(n){const t=m(n,"Account slot");if(typeof t.slotId!="string"||t.slotId.trim()==="")throw new c("Account slot slotId must be a non-empty string.");if(typeof t.version!="number"||!Number.isInteger(t.version)||t.version<1)throw new c("Account slot version must be a positive integer.");if(t.updatedAt!==void 0&&typeof t.updatedAt!="string")throw new c("Account slot updatedAt must be a string when present.");return{slotId:t.slotId,slotInfo:m(t.slotInfo??{},"Account slot slotInfo"),data:m(t.data,"Account slot data"),version:t.version,updatedAt:t.updatedAt??Vt()}}function _e(n){const t=m(n,"Runtime config response"),e={syncPolicy:Y(t.syncPolicy)};return t.gameConfig!==void 0&&(e.gameConfig=ke(t.gameConfig)),e}function ke(n){const t=m(n,"Runtime game config");if(typeof t.enabled!="boolean")throw new c("gameConfig.enabled must be a boolean.");const e={enabled:t.enabled};if(t.version!==void 0&&(e.version=$t(t.version,"gameConfig.version")),t.unchanged!==void 0){if(typeof t.unchanged!="boolean")throw new c("gameConfig.unchanged must be a boolean.");e.unchanged=t.unchanged}if(t.sizeBytes!==void 0&&(e.sizeBytes=$t(t.sizeBytes,"gameConfig.sizeBytes")),t.hasData!==void 0){if(typeof t.hasData!="boolean")throw new c("gameConfig.hasData must be a boolean.");e.hasData=t.hasData}if(t.eventName!==void 0){if(typeof t.eventName!="string")throw new c("gameConfig.eventName must be a string.");e.eventName=t.eventName}return t.config!==void 0&&(e.config=m(t.config,"gameConfig.config")),e}function Y(n){const t=m(n,"Sync policy"),e=B(t.minRemoteSyncIntervalSeconds,"syncPolicy.minRemoteSyncIntervalSeconds"),o=B(t.forceSyncCooldownSeconds,"syncPolicy.forceSyncCooldownSeconds"),s=B(t.maxQueuedLocalSnapshots,"syncPolicy.maxQueuedLocalSnapshots");if(typeof t.syncOnAppBackground!="boolean")throw new c("syncPolicy.syncOnAppBackground must be a boolean.");if(typeof t.syncOnAppForeground!="boolean")throw new c("syncPolicy.syncOnAppForeground must be a boolean.");if(typeof t.syncOnReconnect!="boolean")throw new c("syncPolicy.syncOnReconnect must be a boolean.");return{minRemoteSyncIntervalSeconds:e,forceSyncCooldownSeconds:o,syncOnAppBackground:t.syncOnAppBackground,syncOnAppForeground:t.syncOnAppForeground,syncOnReconnect:t.syncOnReconnect,maxQueuedLocalSnapshots:s}}function B(n,t){if(typeof n!="number"||!Number.isInteger(n)||n<=0)throw new c(`${t} must be a positive integer.`);return n}function $t(n,t){if(typeof n!="number"||!Number.isInteger(n)||n<0)throw new c(`${t} must be a non-negative integer.`);return n}function Te(n,t){if(typeof n!="string"||Number.isNaN(Date.parse(n)))throw new c(`${t} must be a valid date-time string.`);return n}function qt(n){const t=m(n,"Accepted sync response");if(t.status!=="accepted")throw new c("Accepted sync response had an unexpected status.");const e=t.save===void 0?void 0:X(t.save),o=t.version??e?.version,s=t.updatedAt??e?.updatedAt,a=t.historyRetained??!1,r=t.warnings;if(typeof o!="number"||!Number.isInteger(o)||o<1)throw new c("Accepted sync response version must be an integer greater than or equal to 1.");if(typeof s!="string"||Number.isNaN(Date.parse(s)))throw new c("Accepted sync response updatedAt must be a valid date-time string.");if(typeof a!="boolean")throw new c("Accepted sync response historyRetained must be a boolean.");if(r!==void 0&&(!Array.isArray(r)||r.some(w=>typeof w!="string")))throw new c("Accepted sync response warnings must be an array of strings.");const h=r;return{status:_.Accepted,...e===void 0?{}:{save:e},version:o,updatedAt:s,historyRetained:a,...h===void 0?{}:{warnings:h}}}function Kt(n,t){return{...n,save:{...t,version:n.version,createdAt:t.createdAt===Vt()?n.updatedAt:t.createdAt,updatedAt:n.updatedAt}}}function xe(n){return{saveId:n.saveId,playerRef:n.cached?.playerRef??null,metadata:C(n.metadata??n.cached?.metadata??{}),state:C(n.state),version:1,createdAt:n.cached?.createdAt??new Date(0).toISOString(),updatedAt:new Date(0).toISOString()}}function Le(n,t){return`${n}:${t}`}function Vt(){return new Date(0).toISOString()}function Ee(n){const t=n.cached?m(n.cached.state,"Cached account state"):{},e=m(t.accountData??{},"Cached accountData"),o=n.accountData===void 0?{...e,...C(n.accountDataPatch??{})}:C(n.accountData);return{saveId:n.saveId,playerRef:n.cached?.playerRef??null,metadata:C(n.cached?.metadata??{}),state:{schema:"persistly.account.v1",accountData:o,slots:Array.isArray(t.slots)?structuredClone(t.slots):[]},version:1,createdAt:n.cached?.createdAt??new Date(0).toISOString(),updatedAt:new Date(0).toISOString()}}function C(n){return structuredClone(n)}function Ot(n,t={}){const e=m(n,"Conflict sync response"),o=m(e.details,"Conflict details");if(e.status!=="conflict")throw new c("Conflict sync response had an unexpected status.");if(o.reason!=="base_version_mismatch")throw new c("Conflict sync response had an unexpected reason.");return{status:_.Conflict,save:Ne(e,t.saveId),details:{reason:"base_version_mismatch"}}}function Ne(n,t){if(n.save!==void 0)return X(n.save);if(n.slot!==void 0){const e=Z(n.slot);return{saveId:t??e.slotId,playerRef:null,metadata:C(e.slotInfo),state:C(e.data),version:e.version,createdAt:e.updatedAt,updatedAt:e.updatedAt}}if(n.account!==void 0){const e=G(n.account),o=B(n.version??e.version,"Conflict account version"),s=Te(n.updatedAt,"Conflict account updatedAt");return{saveId:t??e.accountId,playerRef:null,metadata:{},state:{schema:"persistly.account.v1",accountData:C(e.accountData),slots:structuredClone(e.slots)},version:o,createdAt:s,updatedAt:s}}throw new c("Conflict sync response must include save, slot, or account.")}function Bt(n){return typeof n=="object"&&n!==null&&n.status==="conflict"}function Me(n){N({...n.accountData===void 0?{}:{accountData:n.accountData}}),n.slot&&(k(n.slot.slotId,"createAccount.slot"),N({slotInfo:n.slot.slotInfo??{},data:n.slot.data}))}function $e(n){return{...n.playerRef===void 0?{}:{playerRef:n.playerRef},...n.externalAccountRef===void 0?{}:{externalAccountRef:n.externalAccountRef},...n.accountData===void 0?{}:{accountData:n.accountData},...n.slot===void 0?{}:{slot:n.slot}}}function Ft(n){if(n.ttlSeconds!==void 0&&(typeof n.ttlSeconds!="number"||!Number.isInteger(n.ttlSeconds)||n.ttlSeconds<=0))throw new c("transfer code ttlSeconds must be a positive integer when provided.");return{...n.transferCode===void 0?{}:{transferCode:n.transferCode},...n.deviceLabel===void 0?{}:{deviceLabel:n.deviceLabel},...n.ttlSeconds===void 0?{}:{ttlSeconds:n.ttlSeconds}}}function qe(n,t){if(n!=="firebase"&&n!=="supabase"&&n!=="auth0")throw new c(`${t} provider must be "firebase", "supabase", or "auth0".`);return n}function Ke(n,t){if(typeof n!="string"||n.trim()==="")throw new c(`${t} requires a non-empty provider token.`);return n}function Ve(n){const t=m(n,"Auth session response"),e=t.linkedProvider;if(typeof t.accountId!="string"||t.accountId.trim()==="")throw new c("Auth session response accountId must be a non-empty string.");if(typeof t.accountSessionToken!="string"||t.accountSessionToken.trim()==="")throw new c("Auth session response accountSessionToken must be a non-empty string.");if(e!=="firebase"&&e!=="supabase"&&e!=="auth0")throw new c("Auth session response linkedProvider must be firebase, supabase, or auth0.");if(typeof t.isNewAccount!="boolean")throw new c("Auth session response isNewAccount must be a boolean.");if(typeof t.wasProviderNewForAccount!="boolean")throw new c("Auth session response wasProviderNewForAccount must be a boolean.");return{accountId:t.accountId,accountSessionToken:t.accountSessionToken,isNewAccount:t.isNewAccount,linkedProvider:e,wasProviderNewForAccount:t.wasProviderNewForAccount,...t.syncPolicy===void 0?{}:{syncPolicy:Y(t.syncPolicy)}}}function Oe(n){if(!Array.isArray(n))throw new c("Linked auth providers response must be an array.");return n.map((t,e)=>{const o=m(t,`Linked auth providers response[${e}]`),s=o.provider;if(s!=="firebase"&&s!=="supabase"&&s!=="auth0")throw new c(`Linked auth providers response[${e}].provider must be firebase, supabase, or auth0.`);const a=m(o.display,`Linked auth providers response[${e}].display`);if(typeof a.label!="string"||a.label.trim()==="")throw new c(`Linked auth providers response[${e}].display.label must be a non-empty string.`);if(a.emailHint!==void 0&&typeof a.emailHint!="string")throw new c(`Linked auth providers response[${e}].display.emailHint must be a string.`);if(typeof o.linkedAt!="string"||Number.isNaN(Date.parse(o.linkedAt)))throw new c(`Linked auth providers response[${e}].linkedAt must be a date-time string.`);if(o.lastUsedAt!==void 0&&(typeof o.lastUsedAt!="string"||Number.isNaN(Date.parse(o.lastUsedAt))))throw new c(`Linked auth providers response[${e}].lastUsedAt must be a date-time string.`);return{provider:s,display:{label:a.label,...a.emailHint===void 0?{}:{emailHint:a.emailHint}},linkedAt:o.linkedAt,...o.lastUsedAt===void 0?{}:{lastUsedAt:o.lastUsedAt}}})}function Be(n){if(n.accountData!==void 0&&n.accountDataPatch!==void 0)throw new c("syncAccountData accepts either accountData or accountDataPatch, not both.");if(n.accountData===void 0&&n.accountDataPatch===void 0)throw new c("syncAccountData requires accountData or accountDataPatch.")}function X(n){try{return dt(n)}catch(t){throw new c(t instanceof Error?t.message:"Save payload was malformed.")}}function tt(n,t){const e=m(t,"Error response"),o=m(e.error,"Error response payload"),s=o.code,a=o.message;if(!Fe(s))throw new c(`Persistly error code was unexpected: ${String(s)}`);if(typeof a!="string")throw new c("Persistly error message must be a string.");const r=o.details===void 0?void 0:m(o.details,"Error details");return Tt(n,s,a,r)}function m(n,t){try{return f(n,t)}catch(e){throw new c(e instanceof Error?e.message:`${t} must be an object.`)}}function Fe(n){return n==="invalid_request"||n==="unauthorized"||n==="forbidden"||n==="not_found"||n==="conflict"||n==="slot_already_exists"||n==="slot_archived"||n==="account_deleted"||n==="slot_deleted"||n==="transfer_code_invalid"||n==="transfer_code_expired"||n==="transfer_code_consumed"||n==="transfer_code_rate_limited"||n==="transfer_code_disabled"||n==="provider_not_supported"||n==="provider_not_enabled"||n==="provider_not_configured"||n==="provider_token_invalid"||n==="firebase_token_invalid"||n==="firebase_token_expired"||n==="firebase_project_mismatch"||n==="supabase_project_url_required"||n==="supabase_project_url_invalid"||n==="supabase_token_missing"||n==="supabase_token_invalid"||n==="supabase_token_expired"||n==="supabase_project_mismatch"||n==="supabase_audience_mismatch"||n==="auth0_domain_required"||n==="auth0_domain_invalid"||n==="auth0_token_missing"||n==="auth0_token_invalid"||n==="auth0_token_expired"||n==="auth0_issuer_mismatch"||n==="auth0_audience_mismatch"||n==="auth_provider_not_configured"||n==="account_auth_conflict"||n==="rate_limited"||n==="payload_too_large"||n==="server_error"}class Jt{drafts=new Map;get(t,e){const o=this.drafts.get(nt(t,e));return o?structuredClone(o):null}set(t,e,o){this.drafts.set(nt(t,e),structuredClone(o))}clear(t,e){this.drafts.delete(nt(t,e))}}class Je{storage;keyPrefix;constructor(t={}){const e=t.storage??globalThis.localStorage;if(!e)throw new Error("LocalStorageAutosaveDraftStore requires browser localStorage or an explicit storage implementation.");this.storage=e,this.keyPrefix=t.keyPrefix??"persistly:draft:"}get(t,e){const o=this.storage.getItem(this.resolveKey(t,e));return o===null?null:et(JSON.parse(o))}set(t,e,o){this.storage.setItem(this.resolveKey(t,e),JSON.stringify(et(o)))}clear(t,e){this.storage.removeItem(this.resolveKey(t,e))}resolveKey(t,e){return`${this.keyPrefix}${encodeURIComponent(t)}:${encodeURIComponent(e)}`}}class Ue{client;accountId;slotId;accountSessionToken;syncPolicy;draftStore;now;lastRemoteSyncAt;lastForceSyncAt=Number.NEGATIVE_INFINITY;constructor(t){this.client=t.client,this.accountId=t.accountId,this.slotId=t.slotId,this.accountSessionToken=t.accountSessionToken,this.syncPolicy=t.syncPolicy,this.draftStore=t.draftStore??new Jt,this.now=t.now??Date.now,this.lastRemoteSyncAt=this.now()}async recordLocalChange(t){await this.draftStore.set(this.accountId,this.slotId,et(t))}async tick(){return this.now()-this.lastRemoteSyncAt<this.syncPolicy.minRemoteSyncIntervalSeconds*1e3?null:await this.syncPendingDraft()}async forceSync(){return this.now()-this.lastForceSyncAt<this.syncPolicy.forceSyncCooldownSeconds*1e3?null:(this.lastForceSyncAt=this.now(),await this.syncPendingDraft())}async syncPendingDraft(){const t=await this.draftStore.get(this.accountId,this.slotId);if(!t)return null;const e=await this.client.syncAccountSlot({accountId:this.accountId,slotId:this.slotId,accountSessionToken:this.accountSessionToken,...t.metadata===void 0?{}:{metadata:t.metadata},data:t.state});return e.status===_.Accepted&&await this.draftStore.clear(this.accountId,this.slotId),this.lastRemoteSyncAt=this.now(),e}}function et(n){return{...n.metadata===void 0?{}:{metadata:n.metadata},state:n.state}}function nt(n,t){return`${n}:${t}`}const u={LocalSaved:"local_saved",LocalFound:"local_found",NotFound:"not_found",NoChanges:"no_changes",Cooldown:"cooldown",Synced:"synced",Conflict:"conflict",AuthRequired:"auth_required",Offline:"offline",RateLimited:"rate_limited"},d={Account:"account",Slot:"slot"},je=u,D="autosave",T="persistly.gameSaves.account.v1",ot="persistly.gameSaves.slotIndex.v1",K="persistly.gameSaves.slot.v1";class Ut{account;slots=new Map;async getAccount(){return Zt(this.account)}async setAccount(t){this.account=i(t)}async deleteAccount(){this.account=void 0}async getSlot(t){return Zt(this.slots.get(t))}async setSlot(t){this.slots.set(t.slotKey,i(t))}async deleteSlot(t){this.slots.delete(t)}async listSlotKeys(){return[...this.slots.keys()].sort()}}class ze{storage;keyPrefix;constructor(t){const e=t.storageHelper??globalThis.localStorage;if(!e)throw new c("PersistlyGameSaves localStorage storage requires browser localStorage or an explicit storageHelper.");this.storage=e,this.keyPrefix=`persistly:game-saves:${encodeURIComponent(t.runtimeKey)}:${encodeURIComponent(Qe(t,e))}`}async getAccount(){return tn(this.storage.getItem(this.accountKey()))}async setAccount(t){this.storage.setItem(this.accountKey(),JSON.stringify(t))}async deleteAccount(){this.storage.removeItem(this.accountKey())}async getSlot(t){return en(this.storage.getItem(this.slotKey(t)))}async setSlot(t){const e=await this.listSlotKeys();e.includes(t.slotKey)||this.storage.setItem(this.slotIndexKey(),JSON.stringify({schema:ot,slotKeys:[...e,t.slotKey].sort()})),this.storage.setItem(this.slotKey(t.slotKey),JSON.stringify(t))}async deleteSlot(t){this.storage.removeItem(this.slotKey(t));const e=(await this.listSlotKeys()).filter(o=>o!==t);this.storage.setItem(this.slotIndexKey(),JSON.stringify({schema:ot,slotKeys:e}))}async listSlotKeys(){const t=this.storage.getItem(this.slotIndexKey());return t===null?[]:nn(t)}accountKey(){return`${this.keyPrefix}:account`}slotIndexKey(){return`${this.keyPrefix}:slot-index`}slotKey(t){return`${this.keyPrefix}:slot:${encodeURIComponent(t)}`}}class He{async createAccount(){l()}async attachAccount(){l()}async createTransferCode(){l()}async attachWithTransferCode(){l()}async signInWithFirebaseToken(){l()}async signInWithSupabaseToken(){l()}async signInWithAuth0Token(){l()}async signInWithProvider(){l()}async connectWithFirebaseToken(){l()}async connectWithSupabaseToken(){l()}async connectWithAuth0Token(){l()}async connectProvider(){l()}async linkProvider(){l()}async listLinkedProviders(){l()}async signOut(){l()}async ensureAccount(){l()}async getAccountSession(){l()}async getAccountInfo(){l()}async getAccountData(){l()}async saveAccountData(){l()}async patchAccountData(){l()}async forceSyncAccount(){l()}async syncDueAccount(){l()}async loadData(){l()}async saveData(){l()}async inspectData(){l()}async loadSlot(){l()}async saveSlot(){l()}async listSlots(){l()}async inspectSlot(){l()}async refreshSlot(){l()}async forceSyncData(){l()}async forceSync(){l()}async syncDueSlots(){l()}async syncDue(){l()}async archiveSlot(){l()}async deleteAccount(){l()}async deleteSlot(){l()}async clearLocalAccount(){l()}async clearLocalSlot(){l()}async acceptCloudData(){l()}async overwriteCloudData(){l()}async keepLocalDataForLater(){l()}async acceptCloudVersion(){l()}async overwriteCloudVersion(){l()}async keepLocalForLater(){l()}}class jt{client;config;store;now;ignoreConfiguredAccountSessionSeed=!1;constructor(t){if(!t.runtimeKey)throw new c("PersistlyGameSaves requires a non-empty runtimeKey.");this.config=t,this.client=new Nt({runtimeKey:t.runtimeKey,...t.fetch===void 0?{}:{fetch:t.fetch},...t.sdkName===void 0?{}:{sdkName:t.sdkName},...t.sdkVersion===void 0?{}:{sdkVersion:t.sdkVersion},...t.clientVersion===void 0?{}:{clientVersion:t.clientVersion},...t.platform===void 0?{}:{platform:t.platform},...t.engineVersion===void 0?{}:{engineVersion:t.engineVersion}}),this.store=We(t),this.now=()=>new Date().toISOString()}async createAccount(){await this.assertNoExistingLocalAccountState("createAccount requires empty local account state. Call clearLocalAccount() before creating a different account.");const t=await this.getOrCreateLocalAccount(),e=await this.createRemoteAccount(t);if(!e.accountId)throw new c("createAccount could not resolve accountId.");return{status:u.Synced,target:d.Account,accountId:e.accountId,account:x(e)}}async attachAccount(t){await this.assertNoExistingLocalAccountState("attachAccount requires empty local account state. Call clearLocalAccount() before attaching a different account."),this.ignoreConfiguredAccountSessionSeed=!0;const e={schema:T,schemaVersion:1,accountId:t.accountId,accountSessionToken:t.accountSessionToken,metadata:{},accountData:{},slots:[],dirty:!1};await this.store.setAccount(e);const o=await this.loadRemoteAccount(e);return{status:u.Synced,target:d.Account,accountId:o.accountId??t.accountId,account:x(o)}}async createTransferCode(t={}){const e=await this.requireAccountSession("createTransferCode");return await this.client.createTransferCode({accountId:e.accountId,accountSessionToken:e.accountSessionToken,...t.deviceLabel===void 0?{}:{deviceLabel:t.deviceLabel},...t.ttlSeconds===void 0?{}:{ttlSeconds:t.ttlSeconds}})}async attachWithTransferCode(t,e={}){await this.assertNoExistingLocalAccountState("attachWithTransferCode requires empty local account state. Call clearLocalAccount() before attaching a transferred account."),this.ignoreConfiguredAccountSessionSeed=!0;const o=await this.client.consumeTransferCode({transferCode:t,...e.deviceLabel===void 0?{}:{deviceLabel:e.deviceLabel}}),s=P(o.account,o.accountSessionToken,o.syncPolicy);return await this.store.setAccount({...s,dirty:!1,lastRemoteSyncedAt:this.now()}),await this.materializeAccountSlotRefs(s),{status:u.Synced,target:d.Account,accountId:s.accountId??o.accountId,account:x(s)}}async signInWithFirebaseToken(t,e={}){return await this.signInWithProvider({provider:"firebase",token:t,...e.deviceLabel===void 0?{}:{deviceLabel:e.deviceLabel}})}async signInWithSupabaseToken(t,e={}){return await this.signInWithProvider({provider:"supabase",token:t,...e.deviceLabel===void 0?{}:{deviceLabel:e.deviceLabel}})}async signInWithAuth0Token(t,e={}){return await this.signInWithProvider({provider:"auth0",token:t,...e.deviceLabel===void 0?{}:{deviceLabel:e.deviceLabel}})}async signInWithProvider(t){const e=await this.getOrCreateLocalAccount(),o=await this.client.exchangeAccountAuthSession({...t,...R(e)?{accountId:e.accountId,accountSessionToken:e.accountSessionToken}:{}});return await this.store.setAccount({...e,accountId:o.accountId,accountSessionToken:o.accountSessionToken,...o.syncPolicy===void 0?{}:{syncPolicy:o.syncPolicy},dirty:e.dirty}),o}async connectWithFirebaseToken(t,e={}){return await this.connectProvider({provider:"firebase",token:t,...e.deviceLabel===void 0?{}:{deviceLabel:e.deviceLabel}})}async connectWithSupabaseToken(t,e={}){return await this.connectProvider({provider:"supabase",token:t,...e.deviceLabel===void 0?{}:{deviceLabel:e.deviceLabel}})}async connectWithAuth0Token(t,e={}){return await this.connectProvider({provider:"auth0",token:t,...e.deviceLabel===void 0?{}:{deviceLabel:e.deviceLabel}})}async connectProvider(t){return await this.linkProvider(t)}async linkProvider(t){const e=await this.getOrCreateLocalAccount();if(!R(e))throw new c("linkProvider requires accountId and accountSessionToken.");const o=await this.client.exchangeAccountAuthSession({...t,accountId:e.accountId,accountSessionToken:e.accountSessionToken});return await this.store.setAccount({...e,accountId:o.accountId,accountSessionToken:o.accountSessionToken,...o.syncPolicy===void 0?{}:{syncPolicy:o.syncPolicy}}),o}async listLinkedProviders(){const t=await this.getOrCreateLocalAccount();if(!R(t))throw new c("listLinkedProviders requires accountId and accountSessionToken.");return await this.client.listLinkedAuthProviders({accountId:t.accountId,accountSessionToken:t.accountSessionToken})}async signOut(){return await this.clearLocalAccount()}async ensureAccount(){const t=await this.getOrCreateLocalAccount();if(t.accountId&&t.accountSessionToken&&t.version!==void 0)return{status:u.LocalFound,target:d.Account,accountId:t.accountId,account:x(t)};const e=await this.createRemoteAccount(t);if(!e.accountId)throw new c("ensureAccount could not resolve accountId.");return{status:u.Synced,target:d.Account,accountId:e.accountId,account:x(e)}}async getAccountSession(t={}){const e=await this.store.getAccount();return e?.accountId?{accountId:e.accountId,...t.includeToken?{accountSessionToken:e.accountSessionToken}:{}}:{}}async getAccountInfo(){const t=await this.store.getAccount();return t?{status:u.LocalFound,target:d.Account,...t.accountId===void 0?{}:{accountId:t.accountId},accountData:i(t.accountData),slots:i(t.slots),...t.version===void 0?{}:{version:t.version},dirty:t.dirty,...t.cloudAccountData===void 0?{}:{lastCloudAccountData:i(t.cloudAccountData)},...t.cloudMetadata===void 0?{}:{lastCloudMetadata:i(t.cloudMetadata)},...t.cloudVersion===void 0?{}:{cloudVersion:t.cloudVersion},...t.lastRemoteSyncedAt===void 0?{}:{lastRemoteSyncedAt:t.lastRemoteSyncedAt}}:{status:u.NotFound,target:d.Account,dirty:!1}}async getAccountData(){return i((await this.store.getAccount())?.accountData??{})}async saveAccountData(t){const e=await this.getOrCreateLocalAccount();return await this.store.setAccount({...e,accountData:i(f(t,"accountData")),dirty:!0}),{status:u.LocalSaved,target:d.Account}}async patchAccountData(t){const e=f(t,"accountDataPatch"),o=await this.getOrCreateLocalAccount(),s=i(o.accountData);for(const[a,r]of Object.entries(e))r===null?delete s[a]:s[a]=r;return await this.store.setAccount({...o,accountData:s,dirty:!0}),{status:u.LocalSaved,target:d.Account}}async forceSyncAccount(t={}){let e=await this.getOrCreateLocalAccount();if(!e.dirty&&e.accountId)return R(e)&&e.version===void 0&&(e=await this.loadRemoteAccount(e)),this.emit({status:u.NoChanges,target:d.Account});if(!t.bypassCooldown&&!Qt(e.lastRemoteSyncedAt,e.syncPolicy))return this.emit({status:u.Cooldown,target:d.Account});try{if(R(e)&&e.version===void 0&&(e={...await this.loadRemoteAccount(e),accountData:e.accountData,dirty:e.dirty,...e.cloudAccountData===void 0?{}:{cloudAccountData:e.cloudAccountData},...e.cloudMetadata===void 0?{}:{cloudMetadata:e.cloudMetadata},...e.cloudVersion===void 0?{}:{cloudVersion:e.cloudVersion}},await this.store.setAccount(e)),!e.accountId||!e.accountSessionToken){if(this.requiresAuthSession())return this.emit({status:u.AuthRequired,target:d.Account});const a=await this.createRemoteAccount(e);return this.emit({status:u.Synced,target:d.Account,account:x(a)})}const o=await this.client.syncAccountData({accountId:e.accountId,accountSessionToken:e.accountSessionToken,baseVersion:e.version??1,accountData:e.accountData});if(o.status===_.Conflict){const a=Ze(o.save),r={...e,cloudAccountData:i(a),cloudMetadata:i(o.save.metadata),cloudVersion:o.save.version,dirty:!0};return await this.store.setAccount(r),this.emit({status:u.Conflict,target:d.Account,localState:i(e.accountData),cloudState:i(a),...e.version===void 0?{}:{localVersion:e.version},cloudVersion:o.save.version,cloudSave:o.save})}const s=Ge(o.save,e.accountSessionToken,e.syncPolicy);return await this.store.setAccount({...s,dirty:!1,lastRemoteSyncedAt:this.now()}),this.emit({status:u.Synced,target:d.Account,account:o.save,historyRetained:o.historyRetained,...o.warnings===void 0?{}:{warnings:o.warnings}})}catch(o){return this.mapSyncError(o,d.Account)}}async syncDueAccount(t={}){const e=await this.store.getAccount();return e?.dirty?!t.bypassCooldown&&!Gt(e.lastRemoteSyncedAt,e.syncPolicy)?{status:u.Cooldown,target:d.Account}:await this.forceSyncAccount({...t,bypassCooldown:!0}):{status:u.NoChanges,target:d.Account}}async loadSlot(t){return await this.inspectSlot(t)}async loadData(){return await this.loadSlot(D)}async inspectData(){return await this.inspectSlot(D)}async saveData(t,e={}){return await this.saveSlot(D,t,e)}async saveSlot(t,e,o={}){await this.getOrCreateLocalAccount();const s=b(t),a=await this.store.getSlot(s),r=a?.archived?void 0:a,h={schema:K,schemaVersion:1,slotKey:s,...r?.version===void 0?{}:{version:r.version},metadata:Wt(o.slotInfo??o.metadata??a?.metadata??{}),slotInfo:Wt(o.slotInfo??o.metadata??a?.metadata??{}),state:i(f(e,"slot.data")),...r?.cloudState===void 0?{}:{cloudState:r.cloudState},...r?.cloudMetadata===void 0?{}:{cloudMetadata:r.cloudMetadata},...r?.cloudVersion===void 0?{}:{cloudVersion:r.cloudVersion},dirty:!0,archived:!1,lastLocalSavedAt:this.now(),...r?.lastRemoteSyncedAt===void 0?{}:{lastRemoteSyncedAt:r.lastRemoteSyncedAt}};return await this.store.setSlot(h),{status:u.LocalSaved,target:d.Slot,...y(s)}}async listSlots(t={}){return(await Promise.all((await this.store.listSlotKeys()).map(o=>this.inspectSlot(o)))).filter(o=>t.includeArchived||!o.archived)}async inspectSlot(t){const e=b(t),o=await this.store.getSlot(e);return o?{status:u.LocalFound,target:d.Slot,...y(e),data:i(o.state),state:i(o.state),slotInfo:i(o.metadata),metadata:i(o.metadata),...o.version===void 0?{}:{version:o.version},dirty:o.dirty,archived:o.archived,...o.cloudState===void 0?{}:{lastCloudData:i(o.cloudState)},...o.cloudState===void 0?{}:{lastCloudState:i(o.cloudState)},...o.cloudMetadata===void 0?{}:{lastCloudSlotInfo:i(o.cloudMetadata)},...o.cloudMetadata===void 0?{}:{lastCloudMetadata:i(o.cloudMetadata)},...o.lastLocalSavedAt===void 0?{}:{lastLocalSavedAt:o.lastLocalSavedAt},...o.lastRemoteSyncedAt===void 0?{}:{lastRemoteSyncedAt:o.lastRemoteSyncedAt}}:{status:u.NotFound,target:d.Slot,...y(e),dirty:!1,archived:!1}}async refreshSlot(t){const e=b(t),o=await this.requireAccountSession("refreshSlot");let s=await this.store.getSlot(e);if(s?.version||(await this.materializeAccountSlotRefs(o),s=await this.store.getSlot(e)),!s?.version)return this.emit({status:u.NoChanges,target:d.Slot,...y(e)});try{const a=await this.client.loadAccountSlot({accountId:o.accountId,accountSessionToken:o.accountSessionToken,slotId:e}),r=st(o.accountId,a);return s.dirty?(await this.store.setSlot({...s,cloudState:i(a.data),cloudMetadata:i(a.slotInfo),cloudVersion:a.version}),this.emit({status:u.Conflict,target:d.Slot,...y(e),localData:i(s.state),cloudData:i(a.data),localState:i(s.state),cloudState:i(a.data),...s.version===void 0?{}:{localVersion:s.version},cloudVersion:a.version,cloudSave:r})):(await this.store.setSlot(F(e,r,a.data,a.slotInfo,this.now())),this.emit({status:u.Synced,target:d.Slot,...y(e),save:r}))}catch(a){return this.mapSyncError(a,d.Slot,e)}}async forceSyncData(t={}){return await this.forceSync(D,t)}async forceSync(t,e={}){const o=b(t),s=await this.store.getSlot(o);if(!s?.dirty)return this.emit({status:u.NoChanges,target:d.Slot,...y(o)});if(!e.bypassCooldown&&!Qt(s.lastRemoteSyncedAt,(await this.store.getAccount())?.syncPolicy))return this.emit({status:u.Cooldown,target:d.Slot,...y(o)});try{const a=s.version?await this.syncExistingSlot(s):await this.createAccountOrSlot(s);return this.emit(a)}catch(a){return this.mapSyncError(a,d.Slot,o)}}async syncDueSlots(t={}){const e=[];for(const o of await this.store.listSlotKeys()){const s=await this.store.getSlot(o);if(!s?.dirty){t.includeSkipped&&e.push({status:u.NoChanges,target:d.Slot,...y(o)});continue}if(!t.bypassCooldown&&!Gt(s.lastRemoteSyncedAt,(await this.store.getAccount())?.syncPolicy)){t.includeSkipped&&e.push({status:u.Cooldown,target:d.Slot,...y(o)});continue}e.push(await this.forceSync(o,{...t,bypassCooldown:!0}))}return e}async syncDue(t={}){const e=[];return((await this.store.getAccount())?.dirty||t.includeSkipped)&&e.push(await this.syncDueAccount(t)),e.push(...await this.syncDueSlots(t)),e}async archiveSlot(t){const e=b(t),o=await this.requireAccountSession("archiveSlot"),s=await this.store.getSlot(e);if(!s?.version)throw new c("archiveSlot requires a synced local slot.");try{const a=await this.client.archiveAccountSlot({accountId:o.accountId,accountSessionToken:o.accountSessionToken,slotId:e});return await this.store.setAccount({...P(a.account,o.accountSessionToken,a.syncPolicy??o.syncPolicy),dirty:!1,lastRemoteSyncedAt:this.now()}),await this.store.setSlot({...s,dirty:!1,archived:!0,lastRemoteSyncedAt:this.now()}),this.emit({status:u.Synced,target:d.Slot,...y(e)})}catch(a){return this.mapSyncError(a,d.Slot,e)}}async deleteAccount(){const t=await this.store.getAccount(),e=await this.store.listSlotKeys();if(!t?.accountId||!t.accountSessionToken){for(const a of e)await this.store.deleteSlot(a);return await this.store.deleteAccount(),this.ignoreConfiguredAccountSessionSeed=!0,this.emit({status:u.LocalSaved,target:d.Account})}const o=await this.requireAccountSession("deleteAccount"),s=await this.client.deleteAccount({accountId:o.accountId,accountSessionToken:o.accountSessionToken});for(const a of e)await this.store.deleteSlot(a);return await this.store.deleteAccount(),this.ignoreConfiguredAccountSessionSeed=!0,this.emit({status:u.Synced,target:d.Account,...s.cleanupQueued?{warnings:["delete_cleanup_queued"]}:{}})}async deleteSlot(t){const e=b(t),o=await this.store.getSlot(e);if(!o)return this.emit({status:u.NoChanges,target:d.Slot,...y(e)});if(!o.version){await this.store.deleteSlot(e);const r=await this.store.getAccount();return r&&await this.store.setAccount(zt(r,e)),this.emit({status:u.LocalSaved,target:d.Slot,...y(e)})}const s=await this.requireAccountSession("deleteSlot"),a=await this.client.deleteAccountSlot({accountId:s.accountId,accountSessionToken:s.accountSessionToken,slotId:e});return await this.store.deleteSlot(e),a.account?await this.store.setAccount({...P(a.account,s.accountSessionToken,s.syncPolicy),dirty:!1,lastRemoteSyncedAt:this.now()}):await this.store.setAccount(zt(s,e,this.now())),this.emit({status:u.Synced,target:d.Slot,...y(e),...a.cleanupQueued?{warnings:["delete_cleanup_queued"]}:{}})}async clearLocalAccount(){for(const t of await this.store.listSlotKeys())await this.store.deleteSlot(t);return await this.store.deleteAccount(),this.ignoreConfiguredAccountSessionSeed=!0,{status:u.LocalSaved,target:d.Account}}async clearLocalSlot(t){const e=b(t);return await this.store.deleteSlot(e),{status:u.LocalSaved,target:d.Slot,...y(e)}}async acceptCloudData(){return await this.acceptCloudVersion(D)}async overwriteCloudData(t={}){return await this.overwriteCloudVersion(D,t)}async keepLocalDataForLater(){return await this.keepLocalForLater(D)}async acceptCloudVersion(t){const e=b(t),o=await this.store.getSlot(e);return!o?.cloudState||o.cloudVersion===void 0?{status:u.NoChanges,target:d.Slot,...y(e)}:(await this.store.setSlot({...o,state:i(o.cloudState),metadata:at(o.cloudMetadata??o.metadata),version:o.cloudVersion,dirty:!1,lastRemoteSyncedAt:this.now()}),{status:u.Synced,target:d.Slot,...y(e)})}async overwriteCloudVersion(t,e={}){const o=b(t),s=await this.store.getSlot(o);return s?.dirty?(s.cloudVersion!==void 0&&await this.store.setSlot({...s,version:s.cloudVersion}),await this.forceSync(o,e)):{status:u.NoChanges,target:d.Slot,...y(o)}}async keepLocalForLater(t){const e=b(t),o=await this.store.getSlot(e);return o&&await this.store.setSlot({...o,dirty:!0}),{status:u.LocalSaved,target:d.Slot,...y(e)}}async createAccountOrSlot(t){let e=await this.getOrCreateLocalAccount();if(!e.accountId||!e.accountSessionToken){if(this.requiresAuthSession())return{status:u.AuthRequired,target:d.Slot,...y(t.slotKey)};const a=await this.client.createAccount({...this.config.playerRef===void 0?{}:{playerRef:this.config.playerRef},...this.config.externalAccountRef===void 0?{}:{externalAccountRef:this.config.externalAccountRef},accountData:e.accountData,slot:{slotId:t.slotKey,slotInfo:t.metadata,data:t.state}}),r=P(a.account,a.accountSessionToken,a.syncPolicy);if(await this.store.setAccount({...r,dirty:!1,lastRemoteSyncedAt:this.now()}),!a.slot)throw new c("Create account response did not include the requested initial slot.");const h=st(a.accountId,a.slot);return await this.store.setSlot(F(t.slotKey,h,t.state,t.metadata,this.now())),{status:u.Synced,target:d.Slot,...y(t.slotKey),save:h}}if(!R(e))throw new c("createAccountOrSlot requires accountId and accountSessionToken.");const o=e.accountId,s=e.accountSessionToken;e.version===void 0&&(e=await this.loadRemoteAccount(e));try{const a=await this.client.createAccountSlot({accountId:o,accountSessionToken:s,slotId:t.slotKey,slotInfo:t.metadata,data:t.state});await this.store.setAccount({...P(a.account,s,a.syncPolicy??e.syncPolicy),dirty:!1,lastRemoteSyncedAt:this.now()});const r=st(o,a.slot);return await this.store.setSlot(F(t.slotKey,r,t.state,t.metadata,this.now())),{status:u.Synced,target:d.Slot,...y(t.slotKey),save:r}}catch(a){if(!(a instanceof U))throw a;const r=await this.reconcileExistingRemoteSlot(t,o,s,e.syncPolicy);return await this.syncExistingSlot(r)}}async syncExistingSlot(t){const e=await this.requireAccountSession("forceSync");if(!t.version)throw new c("syncExistingSlot requires a synced local slot.");const o=t.version??t.cloudVersion,s=await this.client.syncAccountSlot({accountId:e.accountId,accountSessionToken:e.accountSessionToken,slotId:t.slotKey,...o===void 0?{}:{baseVersion:o},slotInfo:t.metadata,data:t.state});return s.status===_.Conflict?(await this.store.setSlot({...t,cloudState:i(s.save.state),cloudMetadata:i(s.save.metadata),cloudVersion:s.save.version,dirty:!0}),{status:u.Conflict,target:d.Slot,...y(t.slotKey),localData:i(t.state),cloudData:i(s.save.state),localState:i(t.state),cloudState:i(s.save.state),...t.version===void 0?{}:{localVersion:t.version},cloudVersion:s.save.version,cloudSave:s.save}):(await this.store.setSlot(F(t.slotKey,s.save,t.state,t.metadata,this.now())),{status:u.Synced,target:d.Slot,...y(t.slotKey),save:s.save,historyRetained:s.historyRetained,...s.warnings===void 0?{}:{warnings:s.warnings}})}async getOrCreateLocalAccount(){const t=await this.store.getAccount();if(t)return t;const e={schema:T,schemaVersion:1,...this.ignoreConfiguredAccountSessionSeed||this.config.accountId===void 0?{}:{accountId:this.config.accountId},...this.ignoreConfiguredAccountSessionSeed||this.config.accountSessionToken===void 0?{}:{accountSessionToken:this.config.accountSessionToken},...this.ignoreConfiguredAccountSessionSeed||this.config.accountId===void 0||this.config.accountSessionToken===void 0?{version:1}:{},metadata:{},accountData:{},slots:[],dirty:!1};return await this.store.setAccount(e),e}async createRemoteAccount(t){if(R(t))return await this.loadRemoteAccount(t);const e=await this.client.createAccount({...this.config.playerRef===void 0?{}:{playerRef:this.config.playerRef},...this.config.externalAccountRef===void 0?{}:{externalAccountRef:this.config.externalAccountRef},accountData:t.accountData}),o=P(e.account,e.accountSessionToken,e.syncPolicy);return await this.store.setAccount({...o,dirty:!1,lastRemoteSyncedAt:this.now()}),o}async requireAccountSession(t){let e=await this.getOrCreateLocalAccount();if(!R(e))throw new c(`${t} requires accountId and accountSessionToken.`);const o=e.accountId,s=e.accountSessionToken;return e.version===void 0&&(e=await this.loadRemoteAccount(e)),{...e,accountId:o,accountSessionToken:s}}requiresAuthSession(){return this.config.accountMode==="authRequired"}async loadRemoteAccount(t){const e=await this.client.loadAccountEnvelope({accountId:t.accountId,accountSessionToken:t.accountSessionToken}),o=e.syncPolicy??(await this.client.getRuntimeConfig()).syncPolicy,s=P(e.account,t.accountSessionToken,o);return await this.store.setAccount({...s,dirty:!1,lastRemoteSyncedAt:this.now()}),await this.materializeAccountSlotRefs(s),s}emit(t){return this.config.onSyncResult?.(t),t}mapSyncError(t,e,o){if(t instanceof z){const s=an(t.details);return this.emit({status:u.RateLimited,target:e,...o===void 0?{}:y(o),...s===void 0?{}:{retryAfterSeconds:s}})}if(t instanceof E||t instanceof Error&&/fetch|network|offline/i.test(t.message))return this.emit({status:u.Offline,target:e,...o===void 0?{}:y(o)});if(t instanceof S&&t.code==="rate_limited")return this.emit({status:u.RateLimited,target:e,...o===void 0?{}:y(o)});throw t}async reconcileExistingRemoteSlot(t,e,o,s){const a=await this.client.loadAccountEnvelope({accountId:e,accountSessionToken:o}),r=P(a.account,o,a.syncPolicy??s);await this.store.setAccount({...r,dirty:!1,lastRemoteSyncedAt:this.now()});const h=Xe(r.slots,t.slotKey);if(!h)throw new c(`Remote account reported slot_already_exists for ${t.slotKey} but did not expose a matching slot.`);const w=await this.client.loadAccountSlot({accountId:e,accountSessionToken:o,slotId:h.slotId}),p={...t,version:w.version,cloudState:i(w.data),cloudMetadata:i(w.slotInfo),cloudVersion:w.version,archived:!1,...t.lastRemoteSyncedAt===void 0?{}:{lastRemoteSyncedAt:t.lastRemoteSyncedAt}};return await this.store.setSlot(p),p}async assertNoExistingLocalAccountState(t){const e=await this.store.getAccount(),o=await this.store.listSlotKeys();if(!Ye(e)||o.length>0)throw new c(t)}async materializeAccountSlotRefs(t){for(const e of t.slots){const o=typeof e.slotKey=="string"?e.slotKey:"";if(!o||await this.store.getSlot(o))continue;const a="metadata"in e?at(f(e.metadata,`account.slots.${o}.metadata`)):{},r=e.archived===!0,h={schema:K,schemaVersion:1,slotKey:o,metadata:a,state:{},dirty:!1,archived:r};await this.store.setSlot(h)}}}class J{static shared=new He;static async start(t){return new jt(t)}static async configure(t){J.shared=await J.start(t)}}function We(n){return n.storage==="memory"?new Ut:n.storage==="localStorage"||n.storageHelper||globalThis.localStorage?new ze(n):new Ut}function Qe(n,t){if(n.localAccountKey)return n.localAccountKey;if(n.externalAccountRef)return`${n.externalAccountRef.provider}:${n.externalAccountRef.subject}`;if(n.playerRef)return n.playerRef;const e=`persistly:game-saves:${encodeURIComponent(n.runtimeKey)}:anonymous-device`,o=t.getItem(e);if(o)return o;const s=`anonymous:${cn()}`;return t.setItem(e,s),s}function Ge(n,t,e){const o=Ht(n);return{schema:T,schemaVersion:1,accountId:n.saveId,...t===void 0?{}:{accountSessionToken:t},version:n.version,metadata:i(n.metadata),accountData:i(o.accountData),slots:i(o.slots),dirty:!1,...e===void 0?{}:{syncPolicy:e}}}function P(n,t,e){return{schema:T,schemaVersion:1,accountId:n.accountId,...t===void 0?{}:{accountSessionToken:t},...n.version===void 0?{}:{version:n.version},metadata:{},accountData:i(n.accountData),slots:n.slots.map(o=>({slotKey:o.slotId,slotId:o.slotId,slotInfo:i(o.slotInfo),metadata:i(o.slotInfo),...o.version===void 0?{}:{version:o.version},...o.status===void 0?{}:{status:o.status},...o.updatedAt===void 0?{}:{updatedAt:o.updatedAt}})),dirty:!1,...e===void 0?{}:{syncPolicy:e}}}function st(n,t){return{saveId:`${n}:${t.slotId}`,playerRef:null,metadata:i(t.slotInfo),state:i(t.data),version:t.version,createdAt:t.updatedAt,updatedAt:t.updatedAt}}function x(n){return{saveId:n.accountId??"local_account",playerRef:null,metadata:i(n.metadata),state:{schema:"persistly.account.v1",accountData:i(n.accountData),slots:i(n.slots)},version:n.version??1,createdAt:n.lastRemoteSyncedAt??new Date(0).toISOString(),updatedAt:n.lastRemoteSyncedAt??new Date(0).toISOString()}}function zt(n,t,e){return{...n,slots:n.slots.filter(o=>o.slotKey!==t),...e===void 0?{}:{lastRemoteSyncedAt:e}}}function Ze(n){return i(Ht(n).accountData)}function Ye(n){return n?!n.accountId&&!n.accountSessionToken&&Object.keys(n.metadata).length===0&&Object.keys(n.accountData).length===0&&n.slots.length===0&&!n.dirty&&n.cloudAccountData===void 0&&n.cloudMetadata===void 0&&n.cloudVersion===void 0&&n.lastRemoteSyncedAt===void 0:!0}function Ht(n){const t=f(n.state,"account.state");if(t.schema!=="persistly.account.v1")throw new c("account.state.schema must be persistly.account.v1.");const e=t.slots;if(!Array.isArray(e))throw new c("account.state.slots must be an array.");return{accountData:f(t.accountData,"account.state.accountData"),slots:e.map((o,s)=>f(o,`account.state.slots[${s}]`))}}function Xe(n,t){for(const e of n)if((typeof e.slotId=="string"?e.slotId:e.slotKey)===t)return{slotId:t}}function F(n,t,e,o,s){return{schema:K,schemaVersion:1,slotKey:n,version:t.version,metadata:at(o),state:i(e),cloudState:i(t.state),cloudMetadata:i(t.metadata),cloudVersion:t.version,dirty:!1,archived:!1,lastRemoteSyncedAt:s}}function Wt(n){return i(f(n,"slot.metadata"))}function at(n){return i(f(n,"slot.metadata"))}function b(n){if(!/^[A-Za-z0-9_.-]{1,64}$/.test(n))throw new c("slotId must match ^[A-Za-z0-9_.-]{1,64}$.");return n}function Qt(n,t){return!n||!t?!0:Date.now()-Date.parse(n)>=t.forceSyncCooldownSeconds*1e3}function Gt(n,t){return!n||!t?!0:Date.now()-Date.parse(n)>=t.minRemoteSyncIntervalSeconds*1e3}function R(n){return typeof n.accountId=="string"&&typeof n.accountSessionToken=="string"}function tn(n){if(n===null)return;const t=ct(n,"account record");if(t.schema!==T)throw new A(`Stored account record schema is unsupported: ${String(t.schema)}.`);if(t.schemaVersion!==1)throw new A("Stored account record schemaVersion is unsupported.");return{schema:T,schemaVersion:1,...typeof t.accountId=="string"?{accountId:t.accountId}:{},...typeof t.accountSessionToken=="string"?{accountSessionToken:t.accountSessionToken}:{},...typeof t.version=="number"?{version:t.version}:{},metadata:f(t.metadata,"stored account.metadata"),accountData:f(t.accountData,"stored account.accountData"),slots:on(t.slots,"stored account.slots"),...t.cloudAccountData===void 0?{}:{cloudAccountData:f(t.cloudAccountData,"stored account.cloudAccountData")},...t.cloudMetadata===void 0?{}:{cloudMetadata:f(t.cloudMetadata,"stored account.cloudMetadata")},...typeof t.cloudVersion=="number"?{cloudVersion:t.cloudVersion}:{},dirty:t.dirty===!0,...typeof t.lastRemoteSyncedAt=="string"?{lastRemoteSyncedAt:t.lastRemoteSyncedAt}:{},...t.syncPolicy===void 0?{}:{syncPolicy:sn(t.syncPolicy)}}}function en(n){if(n===null)return;const t=ct(n,"slot record");if(t.schema!==K)throw new A(`Stored slot record schema is unsupported: ${String(t.schema)}.`);if(t.schemaVersion!==1)throw new A("Stored slot record schemaVersion is unsupported.");if(typeof t.slotKey!="string")throw new A("Stored slot record slotKey must be a string.");return{schema:K,schemaVersion:1,slotKey:t.slotKey,...typeof t.version=="number"?{version:t.version}:{},metadata:f(t.metadata,"stored slot.metadata"),state:f(t.state,"stored slot.state"),...t.cloudState===void 0?{}:{cloudState:f(t.cloudState,"stored slot.cloudState")},...t.cloudMetadata===void 0?{}:{cloudMetadata:f(t.cloudMetadata,"stored slot.cloudMetadata")},...typeof t.cloudVersion=="number"?{cloudVersion:t.cloudVersion}:{},dirty:t.dirty===!0,archived:t.archived===!0,...typeof t.lastLocalSavedAt=="string"?{lastLocalSavedAt:t.lastLocalSavedAt}:{},...typeof t.lastRemoteSyncedAt=="string"?{lastRemoteSyncedAt:t.lastRemoteSyncedAt}:{}}}function nn(n){const t=ct(n,"slot index");if(t.schema!==ot)throw new A(`Stored slot index schema is unsupported: ${String(t.schema)}.`);if(!Array.isArray(t.slotKeys))throw new A("Stored slot index slotKeys must be an array.");return t.slotKeys.filter(e=>typeof e=="string").sort()}function ct(n,t){try{return f(JSON.parse(n),`stored ${t}`)}catch(e){throw e instanceof A?e:new A(e instanceof Error?e.message:`Stored ${t} was malformed.`)}}function on(n,t){if(!Array.isArray(n))throw new A(`${t} must be an array.`);return n.map((e,o)=>f(e,`${t}[${o}]`))}function sn(n){const t=f(n,"stored account.syncPolicy");return{minRemoteSyncIntervalSeconds:rt(t.minRemoteSyncIntervalSeconds,"stored syncPolicy.minRemoteSyncIntervalSeconds"),forceSyncCooldownSeconds:rt(t.forceSyncCooldownSeconds,"stored syncPolicy.forceSyncCooldownSeconds"),syncOnAppBackground:t.syncOnAppBackground===!0,syncOnAppForeground:t.syncOnAppForeground===!0,syncOnReconnect:t.syncOnReconnect===!0,maxQueuedLocalSnapshots:rt(t.maxQueuedLocalSnapshots,"stored syncPolicy.maxQueuedLocalSnapshots")}}function rt(n,t){if(typeof n!="number"||!Number.isInteger(n)||n<=0)throw new A(`${t} must be a positive integer.`);return n}function an(n){const t=n?.retryAfterSeconds;return typeof t=="number"?t:void 0}function i(n){return structuredClone(n)}function Zt(n){return n===void 0?void 0:i(n)}function cn(){return Math.random().toString(36).slice(2,12)}function l(){throw new c("not_configured: call PersistlyGameSaves.configure() first")}function y(n){return{slotId:n,slotKey:n}}const V="persistly.account.v1";function Yt(n={}){const t=n.accountData===void 0?{}:f(n.accountData,"account.accountData"),e=n.slots===void 0?[]:te(n.slots);return{schema:V,accountData:structuredClone(t),slots:structuredClone(e)}}function rn(n,t,e){const o=Xt(n);return Yt({accountData:o.accountData,slots:[...o.slots,{slotId:ee(t),slotInfo:f(e,"slot.slotInfo")}]})}function un(n){try{return Xt(n),!0}catch{return!1}}function Xt(n){const t=f(n,"account");if(t.schema!==V)throw new Error(`account.schema must be ${V}.`);return{schema:V,accountData:f(t.accountData,"account.accountData"),slots:te(t.slots)}}function te(n){if(!Array.isArray(n))throw new Error("account.slots must be an array.");return n.map((t,e)=>{const o=f(t,`account.slots[${e}]`),s=o.version,a=o.status,r=o.updatedAt;if(!(s===void 0||typeof s=="number"&&Number.isInteger(s)&&s>=1))throw new Error(`account.slots[${e}].version must be a positive integer when present.`);if(!(a===void 0||a==="active"||a==="archived"))throw new Error(`account.slots[${e}].status must be active or archived when present.`);if(!(r===void 0||typeof r=="string"))throw new Error(`account.slots[${e}].updatedAt must be a string when present.`);return{slotId:ee(o.slotId,`account.slots[${e}].slotId`),slotInfo:f(o.slotInfo,`account.slots[${e}].slotInfo`),...s===void 0?{}:{version:s},...a===void 0?{}:{status:a},...r===void 0?{}:{updatedAt:r}}})}function ee(n,t="slotId"){if(typeof n!="string"||!/^[A-Za-z0-9_.-]{1,64}$/.test(n))throw new Error(`${t} must match ^[A-Za-z0-9_.-]{1,64}$.`);return n}export{Lt as DEFAULT_PERSISTLY_API_BASE_URL,Je as LocalStorageAutosaveDraftStore,Jt as MemoryAutosaveDraftStore,Et as PERSISTLY_JS_SDK_VERSION,j as PersistlyAccountAuthConflictError,At as PersistlyAccountDeletedError,V as PersistlyAccountSchema,S as PersistlyApiError,_t as PersistlyAuthProviderNotConfiguredError,Ue as PersistlyAutosaveManager,Nt as PersistlyClient,c as PersistlyConfigurationError,wt as PersistlyConflictError,D as PersistlyDefaultSlotKey,Rt as PersistlyFirebaseProjectMismatchError,mt as PersistlyForbiddenError,u as PersistlyGameSaveStatus,d as PersistlyGameSaveTarget,J as PersistlyGameSaves,jt as PersistlyGameSavesInstance,ht as PersistlyInvalidRequestError,St as PersistlyNotFoundError,H as PersistlyPayloadTooLargeError,Pt as PersistlyProviderTokenInvalidError,z as PersistlyRateLimitedError,kt as PersistlyServerError,U as PersistlySlotAlreadyExistsError,pt as PersistlySlotArchivedError,gt as PersistlySlotDeletedError,je as PersistlySlotStatus,A as PersistlyStorageError,_ as PersistlySyncStatus,bt as PersistlyTransferCodeConsumedError,Dt as PersistlyTransferCodeDisabledError,It as PersistlyTransferCodeExpiredError,vt as PersistlyTransferCodeInvalidError,Ct as PersistlyTransferCodeRateLimitedError,E as PersistlyTransportError,yt as PersistlyUnauthorizedError,rn as addSlotToAccountState,Yt as buildAccountState,Tt as createPersistlyApiError,re as isPersistlyAccountAuthConflict,un as isPersistlyAccountState};
//# sourceMappingURL=/sm/06e0d03b71ccc51b8bc2a1774970f5c155a80ab1643d23ea9b2d170ce5916931.map