@xapps-platform/marketplace-ui 0.1.14 → 0.1.15

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/dist/index.js CHANGED
@@ -106,6 +106,94 @@ function useI18n() {
106
106
 
107
107
  // src/i18n.tsx
108
108
  import { jsx as jsx2 } from "react/jsx-runtime";
109
+ function buildMarketplaceXmsCatalog(locale) {
110
+ if (locale === "ro") {
111
+ return {
112
+ "xapp.current_plan_label": "Plan curent",
113
+ "xapp.selected_label": "Selectat",
114
+ "xapp.default_label": "Implicit",
115
+ "xapp.owned_unlock_label": "Unlock de\u021Binut",
116
+ "xapp.additive_unlock_label": "Supliment cu abonament",
117
+ "xapp.owned_unlock_active": "Unlock deja activ",
118
+ "xapp.current_plan_active": "Plan activ",
119
+ "xapp.checkout_starting": "Se porne\u0219te checkout-ul...",
120
+ "xapp.additive_unlock_action": "Cump\u0103r\u0103 suplimentul",
121
+ "xapp.checkout_action": "Continu\u0103 spre checkout",
122
+ "xapp.subscription_status_label": "Stare abonament",
123
+ "xapp.subscription_coverage_label": "Acoperire",
124
+ "xapp.subscription_reason_label": "Motiv stare",
125
+ "xapp.subscription_overdue_since_label": "Restant din",
126
+ "xapp.subscription_expiry_boundary_label": "Limit\u0103 expirare",
127
+ "xapp.current_period_ends_label": "Perioada curent\u0103 se \xEEncheie la",
128
+ "xapp.cancelled_at_label": "Anulat la",
129
+ "xapp.credits_remaining_label": "Credite r\u0103mase",
130
+ "xapp.add_on_unlocks_label": "Unlock-uri suplimentare",
131
+ "xapp.subscription_refresh_action": "Actualizeaz\u0103 starea",
132
+ "xapp.subscription_refreshing": "Se actualizeaz\u0103...",
133
+ "xapp.subscription_cancel_action": "Anuleaz\u0103 abonamentul",
134
+ "xapp.subscription_cancelling": "Se anuleaz\u0103...",
135
+ "xapp.subscription_operator_authority_label": "Autoritate operator",
136
+ "xapp.subscription_management_destination_label": "Administreaz\u0103 \xEEn",
137
+ "xapp.subscription_operator_authority_gateway": "Gateway",
138
+ "xapp.subscription_operator_authority_tenant": "Tenant",
139
+ "xapp.subscription_operator_authority_publisher": "Publisher",
140
+ "xapp.subscription_operator_authority_owner": "Proprietar aplica\u021Bie",
141
+ "xapp.subscription_management_destination_gateway": "Administrare gateway",
142
+ "xapp.subscription_management_destination_tenant": "Aplica\u021Bia tenantului",
143
+ "xapp.subscription_management_destination_publisher": "Aplica\u021Bia publisherului",
144
+ "xapp.subscription_management_destination_owner": "Proprietarul aplica\u021Biei",
145
+ "xapp.subscription_management_hint_gateway": "Administrarea avansat\u0103 a abonamentului se face \xEEn administrarea gateway-ului.",
146
+ "xapp.subscription_management_hint_tenant": "Administrarea avansat\u0103 a abonamentului se face \xEEn aplica\u021Bia tenantului.",
147
+ "xapp.subscription_management_hint_publisher": "Administrarea avansat\u0103 a abonamentului se face \xEEn aplica\u021Bia publisherului.",
148
+ "xapp.subscription_management_hint_owner": "Administrarea avansat\u0103 a abonamentului este gestionat\u0103 de proprietarul aplica\u021Biei.",
149
+ "xapp.subscription_management_open_action": "Deschide administrarea",
150
+ "xapp.lifecycle_preview_at_label": "Previzualizare la",
151
+ "xapp.lifecycle_preview_hint": "Ciclul de via\u021B\u0103 al abonamentului este previzualizat pentru momentul selectat."
152
+ };
153
+ }
154
+ return {
155
+ "xapp.current_plan_label": "Current plan",
156
+ "xapp.selected_label": "Selected",
157
+ "xapp.default_label": "Default",
158
+ "xapp.owned_unlock_label": "Owned unlock",
159
+ "xapp.additive_unlock_label": "Add-on with membership",
160
+ "xapp.owned_unlock_active": "Owned unlock active",
161
+ "xapp.current_plan_active": "Current plan active",
162
+ "xapp.checkout_starting": "Starting checkout...",
163
+ "xapp.additive_unlock_action": "Purchase add-on unlock",
164
+ "xapp.checkout_action": "Continue to checkout",
165
+ "xapp.subscription_status_label": "Subscription status",
166
+ "xapp.subscription_coverage_label": "Coverage",
167
+ "xapp.subscription_reason_label": "Status reason",
168
+ "xapp.subscription_overdue_since_label": "Overdue since",
169
+ "xapp.subscription_expiry_boundary_label": "Expiry boundary",
170
+ "xapp.current_period_ends_label": "Current period ends",
171
+ "xapp.cancelled_at_label": "Cancelled at",
172
+ "xapp.credits_remaining_label": "Credits remaining",
173
+ "xapp.add_on_unlocks_label": "Add-on unlocks",
174
+ "xapp.subscription_refresh_action": "Refresh status",
175
+ "xapp.subscription_refreshing": "Refreshing...",
176
+ "xapp.subscription_cancel_action": "Cancel subscription",
177
+ "xapp.subscription_cancelling": "Cancelling...",
178
+ "xapp.subscription_operator_authority_label": "Operator authority",
179
+ "xapp.subscription_management_destination_label": "Manage in",
180
+ "xapp.subscription_operator_authority_gateway": "Gateway",
181
+ "xapp.subscription_operator_authority_tenant": "Tenant",
182
+ "xapp.subscription_operator_authority_publisher": "Publisher",
183
+ "xapp.subscription_operator_authority_owner": "App owner",
184
+ "xapp.subscription_management_destination_gateway": "Gateway admin",
185
+ "xapp.subscription_management_destination_tenant": "Tenant app",
186
+ "xapp.subscription_management_destination_publisher": "Publisher app",
187
+ "xapp.subscription_management_destination_owner": "App owner",
188
+ "xapp.subscription_management_hint_gateway": "Advanced subscription management is handled in Gateway admin.",
189
+ "xapp.subscription_management_hint_tenant": "Advanced subscription management is handled in the tenant app.",
190
+ "xapp.subscription_management_hint_publisher": "Advanced subscription management is handled in the publisher app.",
191
+ "xapp.subscription_management_hint_owner": "Advanced subscription management is handled by the app owner.",
192
+ "xapp.subscription_management_open_action": "Open management",
193
+ "xapp.lifecycle_preview_at_label": "Preview as of",
194
+ "xapp.lifecycle_preview_hint": "Subscription lifecycle is being previewed for the selected time."
195
+ };
196
+ }
109
197
  var MARKETPLACE_CATALOGS = {
110
198
  en: {
111
199
  "common.id": "ID",
@@ -301,6 +389,7 @@ var MARKETPLACE_CATALOGS = {
301
389
  "activity.guard_action_confirm_action": "Confirm action",
302
390
  "activity.guard_action_confirm_action_message": "Confirm action ({message})",
303
391
  "activity.guard_action_custom": "Action: {kind}",
392
+ ...buildMarketplaceXmsCatalog("en"),
304
393
  "status.unread": "Unread",
305
394
  "status.read": "Read",
306
395
  "common.back": "Back",
@@ -351,16 +440,6 @@ var MARKETPLACE_CATALOGS = {
351
440
  "xapp.screenshot_alt": "Screenshot {index}",
352
441
  "xapp.usage_credits_title": "Usage Credits",
353
442
  "xapp.current_access_title": "Current Access",
354
- "xapp.current_plan_label": "Current plan",
355
- "xapp.selected_label": "Selected",
356
- "xapp.default_label": "Default",
357
- "xapp.owned_unlock_label": "Owned unlock",
358
- "xapp.additive_unlock_label": "Add-on with membership",
359
- "xapp.owned_unlock_active": "Owned unlock active",
360
- "xapp.current_plan_active": "Current plan active",
361
- "xapp.checkout_starting": "Starting checkout...",
362
- "xapp.additive_unlock_action": "Purchase add-on unlock",
363
- "xapp.checkout_action": "Continue to checkout",
364
443
  "xapp.access_state_label": "Access state",
365
444
  "xapp.access_state_available": "available",
366
445
  "xapp.subscription_status_label": "Subscription status",
@@ -374,7 +453,19 @@ var MARKETPLACE_CATALOGS = {
374
453
  "xapp.subscription_reason_past_due_after_period_end": "Current period ended without successful renewal",
375
454
  "xapp.subscription_reason_expired_after_boundary": "Expiry boundary reached",
376
455
  "xapp.renews_at_label": "Renews at",
456
+ "xapp.current_period_ends_label": "Current period ends",
457
+ "xapp.cancelled_at_label": "Cancelled at",
377
458
  "xapp.expires_at_label": "Expires at",
459
+ "xapp.subscription_refresh_action": "Refresh status",
460
+ "xapp.subscription_refreshing": "Refreshing...",
461
+ "xapp.subscription_refresh_failed": "Unable to refresh subscription state.",
462
+ "xapp.subscription_cancel_action": "Cancel subscription",
463
+ "xapp.subscription_cancelling": "Cancelling...",
464
+ "xapp.subscription_cancel_title": "Cancel subscription?",
465
+ "xapp.subscription_cancel_description": "The subscription will stop renewing. Current access remains available until the current period ends.",
466
+ "xapp.subscription_cancel_failed": "Unable to cancel this subscription.",
467
+ "xapp.lifecycle_preview_at_label": "Preview as of",
468
+ "xapp.lifecycle_preview_hint": "Subscription lifecycle is being previewed for the selected time.",
378
469
  "xapp.credits_remaining_label": "Credits remaining",
379
470
  "xapp.available_label": "Available",
380
471
  "xapp.ready_to_use": "{count} ready to use",
@@ -617,6 +708,7 @@ var MARKETPLACE_CATALOGS = {
617
708
  "activity.guard_action_confirm_action": "Confirm\u0103 ac\u021Biunea",
618
709
  "activity.guard_action_confirm_action_message": "Confirm\u0103 ac\u021Biunea ({message})",
619
710
  "activity.guard_action_custom": "Ac\u021Biune: {kind}",
711
+ ...buildMarketplaceXmsCatalog("ro"),
620
712
  "status.unread": "Necitit",
621
713
  "status.read": "Citit",
622
714
  "common.back": "\xCEnapoi",
@@ -667,16 +759,6 @@ var MARKETPLACE_CATALOGS = {
667
759
  "xapp.screenshot_alt": "Captur\u0103 de ecran {index}",
668
760
  "xapp.usage_credits_title": "Credite de utilizare",
669
761
  "xapp.current_access_title": "Acces curent",
670
- "xapp.current_plan_label": "Plan curent",
671
- "xapp.selected_label": "Selectat",
672
- "xapp.default_label": "Implicit",
673
- "xapp.owned_unlock_label": "Unlock de\u021Binut",
674
- "xapp.additive_unlock_label": "Supliment cu abonament",
675
- "xapp.owned_unlock_active": "Unlock deja activ",
676
- "xapp.current_plan_active": "Plan activ",
677
- "xapp.checkout_starting": "Se porne\u0219te checkout-ul...",
678
- "xapp.additive_unlock_action": "Cump\u0103r\u0103 suplimentul",
679
- "xapp.checkout_action": "Continu\u0103 spre checkout",
680
762
  "xapp.access_state_label": "Stare acces",
681
763
  "xapp.access_state_available": "disponibil",
682
764
  "xapp.subscription_status_label": "Stare abonament",
@@ -690,7 +772,19 @@ var MARKETPLACE_CATALOGS = {
690
772
  "xapp.subscription_reason_past_due_after_period_end": "Perioada curent\u0103 s-a \xEEncheiat f\u0103r\u0103 re\xEEnnoire reu\u0219it\u0103",
691
773
  "xapp.subscription_reason_expired_after_boundary": "A fost atins\u0103 limita de expirare",
692
774
  "xapp.renews_at_label": "Se re\xEEnnoie\u0219te la",
775
+ "xapp.current_period_ends_label": "Perioada curent\u0103 se \xEEncheie la",
776
+ "xapp.cancelled_at_label": "Anulat la",
693
777
  "xapp.expires_at_label": "Expir\u0103 la",
778
+ "xapp.subscription_refresh_action": "Actualizeaz\u0103 starea",
779
+ "xapp.subscription_refreshing": "Se actualizeaz\u0103...",
780
+ "xapp.subscription_refresh_failed": "Starea abonamentului nu a putut fi actualizat\u0103.",
781
+ "xapp.subscription_cancel_action": "Anuleaz\u0103 abonamentul",
782
+ "xapp.subscription_cancelling": "Se anuleaz\u0103...",
783
+ "xapp.subscription_cancel_title": "Anulezi abonamentul?",
784
+ "xapp.subscription_cancel_description": "Abonamentul nu se va mai re\xEEnnoi. Accesul curent r\u0103m\xE2ne disponibil p\xE2n\u0103 la sf\xE2r\u0219itul perioadei curente.",
785
+ "xapp.subscription_cancel_failed": "Abonamentul nu a putut fi anulat.",
786
+ "xapp.lifecycle_preview_at_label": "Previzualizare la",
787
+ "xapp.lifecycle_preview_hint": "Ciclul de via\u021B\u0103 al abonamentului este previzualizat pentru momentul selectat.",
694
788
  "xapp.credits_remaining_label": "Credite r\u0103mase",
695
789
  "xapp.available_label": "Disponibile",
696
790
  "xapp.ready_to_use": "{count} gata de utilizare",
@@ -2012,20 +2106,13 @@ function InvoicesPage() {
2012
2106
  ] });
2013
2107
  }
2014
2108
 
2015
- // ../browser-host/src/xms.ts
2109
+ // ../browser-host/src/xmsCopy.ts
2016
2110
  function readString3(value) {
2017
2111
  return String(value ?? "").trim();
2018
2112
  }
2019
- function readNumber(value, fallback = 0) {
2020
- const parsed = Number(value);
2021
- return Number.isFinite(parsed) ? parsed : fallback;
2022
- }
2023
2113
  function readLower(value) {
2024
2114
  return readString3(value).toLowerCase();
2025
2115
  }
2026
- function readBoolean(value, fallback = false) {
2027
- return typeof value === "boolean" ? value : fallback;
2028
- }
2029
2116
  function isRomanianLocale(value) {
2030
2117
  const locale = readLower(value);
2031
2118
  return locale === "ro" || locale.startsWith("ro-");
@@ -2059,6 +2146,14 @@ var XMS_COPY_CATALOG = {
2059
2146
  paymentCompletedNotice: "Payment completed and access was refreshed.",
2060
2147
  checkoutCancelledNotice: "Checkout was cancelled before completion.",
2061
2148
  paymentFailedNotice: "Payment failed before access could be issued.",
2149
+ subscriptionRefreshCompletedNotice: "Subscription status was refreshed.",
2150
+ subscriptionRefreshFailedNotice: "Subscription status could not be refreshed.",
2151
+ subscriptionCancelCompletedNotice: "Subscription renewal was cancelled.",
2152
+ subscriptionCancelFailedNotice: "Subscription could not be cancelled.",
2153
+ subscriptionCancelConfirmTitle: "Cancel subscription",
2154
+ subscriptionCancelConfirmMessage: "Cancel renewal for this subscription?",
2155
+ subscriptionCancelConfirmLabel: "Cancel subscription",
2156
+ subscriptionCancelDismissLabel: "Keep subscription",
2062
2157
  missingPackageMetadataMessage: "This package is missing purchase metadata in the published paywall.",
2063
2158
  missingIntentMessage: "Purchase intent was created without an identifier.",
2064
2159
  missingPaymentPageMessage: "Payment page is not available for this package.",
@@ -2068,10 +2163,41 @@ var XMS_COPY_CATALOG = {
2068
2163
  currentPlanLabel: "Current plan",
2069
2164
  membershipAccessLabel: "Membership access",
2070
2165
  subscriptionStatusLabel: "Subscription status",
2166
+ subscriptionCoverageLabel: "Coverage",
2167
+ subscriptionReasonLabel: "Status reason",
2168
+ currentPeriodEndsLabel: "Current period ends",
2071
2169
  renewsAtLabel: "Renews at",
2072
2170
  expiresAtLabel: "Expires at",
2171
+ overdueSinceLabel: "Overdue since",
2172
+ expiryBoundaryLabel: "Expiry boundary",
2173
+ cancelledAtLabel: "Cancelled at",
2174
+ operatorAuthorityLabel: "Operator authority",
2175
+ managementDestinationLabel: "Manage in",
2176
+ operatorAuthorityGatewayLabel: "Gateway",
2177
+ operatorAuthorityTenantLabel: "Tenant",
2178
+ operatorAuthorityPublisherLabel: "Publisher",
2179
+ operatorAuthorityOwnerLabel: "App owner",
2180
+ managementDestinationGatewayLabel: "Gateway admin",
2181
+ managementDestinationTenantLabel: "Tenant app",
2182
+ managementDestinationPublisherLabel: "Publisher app",
2183
+ managementDestinationOwnerLabel: "App owner",
2184
+ managementDestinationHintGatewayLabel: "Advanced subscription management is handled in Gateway admin.",
2185
+ managementDestinationHintTenantLabel: "Advanced subscription management is handled in the tenant app.",
2186
+ managementDestinationHintPublisherLabel: "Advanced subscription management is handled in the publisher app.",
2187
+ managementDestinationHintOwnerLabel: "Advanced subscription management is handled by the app owner.",
2188
+ openManagementDestinationActionLabel: "Open management",
2073
2189
  creditsRemainingLabel: "Credits remaining",
2074
2190
  addOnUnlocksLabel: "Add-on unlocks",
2191
+ coverageActiveLabel: "Still covered",
2192
+ coverageInactiveLabel: "Not covered",
2193
+ noOverdueRestrictionLabel: "No active overdue restriction.",
2194
+ reasonGraceCoveredPastDueLabel: "Coverage remains during grace period",
2195
+ reasonPastDueAfterPeriodEndLabel: "Current period ended without successful renewal",
2196
+ reasonExpiredAfterBoundaryLabel: "Expiry boundary reached",
2197
+ refreshStatusActionLabel: "Refresh status",
2198
+ refreshingStatusActionLabel: "Refreshing...",
2199
+ cancelSubscriptionActionLabel: "Cancel subscription",
2200
+ cancellingSubscriptionActionLabel: "Cancelling...",
2075
2201
  noPublishedPlansLabel: "No published plans are currently available.",
2076
2202
  recentTimelineTitle: "Recent timeline",
2077
2203
  recentTimelineSubtitle: "Latest monetization events correlated for this subject and app.",
@@ -2083,6 +2209,13 @@ var XMS_COPY_CATALOG = {
2083
2209
  historyPurchaseIntentLabel: "Purchase intent",
2084
2210
  historyTransactionsTitle: "Transactions",
2085
2211
  historyTransactionLabel: "Transaction",
2212
+ historySettlementDetailDisputeWarningNeedsResponse: "Dispute warning: response needed",
2213
+ historySettlementDetailDisputeWarningUnderReview: "Dispute warning under review",
2214
+ historySettlementDetailDisputeWarningClosed: "Dispute warning closed",
2215
+ historySettlementDetailDisputeNeedsResponse: "Dispute needs response",
2216
+ historySettlementDetailDisputeUnderReview: "Dispute under review",
2217
+ historySettlementDetailDisputeWon: "Dispute won",
2218
+ historySettlementDetailDisputeLost: "Dispute lost",
2086
2219
  historySubscriptionsTitle: "Subscriptions",
2087
2220
  historySubscriptionContractLabel: "Subscription contract",
2088
2221
  historyEntitlementsTitle: "Entitlements",
@@ -2125,6 +2258,14 @@ var XMS_COPY_CATALOG = {
2125
2258
  paymentCompletedNotice: "Plata a fost finalizat\u0103 \u0219i accesul a fost actualizat.",
2126
2259
  checkoutCancelledNotice: "Checkout-ul a fost anulat \xEEnainte de finalizare.",
2127
2260
  paymentFailedNotice: "Plata a e\u0219uat \xEEnainte ca accesul s\u0103 poat\u0103 fi acordat.",
2261
+ subscriptionRefreshCompletedNotice: "Starea abonamentului a fost actualizat\u0103.",
2262
+ subscriptionRefreshFailedNotice: "Starea abonamentului nu a putut fi actualizat\u0103.",
2263
+ subscriptionCancelCompletedNotice: "Re\xEEnnoirea abonamentului a fost anulat\u0103.",
2264
+ subscriptionCancelFailedNotice: "Abonamentul nu a putut fi anulat.",
2265
+ subscriptionCancelConfirmTitle: "Anuleaz\u0103 abonamentul",
2266
+ subscriptionCancelConfirmMessage: "Anulezi re\xEEnnoirea acestui abonament?",
2267
+ subscriptionCancelConfirmLabel: "Anuleaz\u0103 abonamentul",
2268
+ subscriptionCancelDismissLabel: "P\u0103streaz\u0103 abonamentul",
2128
2269
  missingPackageMetadataMessage: "Acest pachet nu are metadatele de cump\u0103rare necesare \xEEn paywall-ul publicat.",
2129
2270
  missingIntentMessage: "Intentul de cump\u0103rare a fost creat f\u0103r\u0103 identificator.",
2130
2271
  missingPaymentPageMessage: "Pagina de plat\u0103 nu este disponibil\u0103 pentru acest pachet.",
@@ -2134,10 +2275,41 @@ var XMS_COPY_CATALOG = {
2134
2275
  currentPlanLabel: "Plan curent",
2135
2276
  membershipAccessLabel: "Acces de membru",
2136
2277
  subscriptionStatusLabel: "Stare abonament",
2278
+ subscriptionCoverageLabel: "Acoperire",
2279
+ subscriptionReasonLabel: "Motiv stare",
2280
+ currentPeriodEndsLabel: "Perioada curent\u0103 se \xEEncheie la",
2137
2281
  renewsAtLabel: "Se re\xEEnnoie\u0219te la",
2138
2282
  expiresAtLabel: "Expir\u0103 la",
2283
+ overdueSinceLabel: "Restant din",
2284
+ expiryBoundaryLabel: "Limit\u0103 expirare",
2285
+ cancelledAtLabel: "Anulat la",
2286
+ operatorAuthorityLabel: "Autoritate operator",
2287
+ managementDestinationLabel: "Administreaz\u0103 \xEEn",
2288
+ operatorAuthorityGatewayLabel: "Gateway",
2289
+ operatorAuthorityTenantLabel: "Tenant",
2290
+ operatorAuthorityPublisherLabel: "Publisher",
2291
+ operatorAuthorityOwnerLabel: "Proprietar aplica\u021Bie",
2292
+ managementDestinationGatewayLabel: "Administrare gateway",
2293
+ managementDestinationTenantLabel: "Aplica\u021Bia tenantului",
2294
+ managementDestinationPublisherLabel: "Aplica\u021Bia publisherului",
2295
+ managementDestinationOwnerLabel: "Proprietarul aplica\u021Biei",
2296
+ managementDestinationHintGatewayLabel: "Administrarea avansat\u0103 a abonamentului se face \xEEn administrarea gateway-ului.",
2297
+ managementDestinationHintTenantLabel: "Administrarea avansat\u0103 a abonamentului se face \xEEn aplica\u021Bia tenantului.",
2298
+ managementDestinationHintPublisherLabel: "Administrarea avansat\u0103 a abonamentului se face \xEEn aplica\u021Bia publisherului.",
2299
+ managementDestinationHintOwnerLabel: "Administrarea avansat\u0103 a abonamentului este gestionat\u0103 de proprietarul aplica\u021Biei.",
2300
+ openManagementDestinationActionLabel: "Deschide administrarea",
2139
2301
  creditsRemainingLabel: "Credite r\u0103mase",
2140
2302
  addOnUnlocksLabel: "Unlock-uri suplimentare",
2303
+ coverageActiveLabel: "\xCEnc\u0103 activ",
2304
+ coverageInactiveLabel: "Neacoperit",
2305
+ noOverdueRestrictionLabel: "Nu exist\u0103 restric\u021Bii active de \xEEnt\xE2rziere.",
2306
+ reasonGraceCoveredPastDueLabel: "Accesul r\u0103m\xE2ne activ \xEEn perioada de gra\u021Bie",
2307
+ reasonPastDueAfterPeriodEndLabel: "Perioada curent\u0103 s-a \xEEncheiat f\u0103r\u0103 o re\xEEnnoire reu\u0219it\u0103",
2308
+ reasonExpiredAfterBoundaryLabel: "A fost atins\u0103 limita de expirare",
2309
+ refreshStatusActionLabel: "Actualizeaz\u0103 starea",
2310
+ refreshingStatusActionLabel: "Se actualizeaz\u0103...",
2311
+ cancelSubscriptionActionLabel: "Anuleaz\u0103 abonamentul",
2312
+ cancellingSubscriptionActionLabel: "Se anuleaz\u0103...",
2141
2313
  noPublishedPlansLabel: "Nu exist\u0103 planuri publicate disponibile \xEEn acest moment.",
2142
2314
  recentTimelineTitle: "Cronologie recent\u0103",
2143
2315
  recentTimelineSubtitle: "Cele mai recente evenimente de monetizare corelate pentru acest subiect \u0219i aceast\u0103 aplica\u021Bie.",
@@ -2149,6 +2321,13 @@ var XMS_COPY_CATALOG = {
2149
2321
  historyPurchaseIntentLabel: "Inten\u021Bie de cump\u0103rare",
2150
2322
  historyTransactionsTitle: "Tranzac\u021Bii",
2151
2323
  historyTransactionLabel: "Tranzac\u021Bie",
2324
+ historySettlementDetailDisputeWarningNeedsResponse: "Avertisment disput\u0103: este necesar un r\u0103spuns",
2325
+ historySettlementDetailDisputeWarningUnderReview: "Avertisment disput\u0103 \xEEn analiz\u0103",
2326
+ historySettlementDetailDisputeWarningClosed: "Avertisment disput\u0103 \xEEnchis",
2327
+ historySettlementDetailDisputeNeedsResponse: "Disput\u0103 ce necesit\u0103 r\u0103spuns",
2328
+ historySettlementDetailDisputeUnderReview: "Disput\u0103 \xEEn analiz\u0103",
2329
+ historySettlementDetailDisputeWon: "Disput\u0103 c\xE2\u0219tigat\u0103",
2330
+ historySettlementDetailDisputeLost: "Disput\u0103 pierdut\u0103",
2152
2331
  historySubscriptionsTitle: "Abonamente",
2153
2332
  historySubscriptionContractLabel: "Contract de abonament",
2154
2333
  historyEntitlementsTitle: "Drepturi de acces",
@@ -2170,15 +2349,33 @@ function resolveXmsCopyLocale(locale) {
2170
2349
  function buildXmsPackageCopy(locale) {
2171
2350
  return XMS_COPY_CATALOG[resolveXmsCopyLocale(locale)].package;
2172
2351
  }
2352
+ function buildXmsSurfaceCopy(input) {
2353
+ return XMS_COPY_CATALOG[resolveXmsCopyLocale(input?.locale)].surface;
2354
+ }
2355
+
2356
+ // ../browser-host/src/xms.ts
2357
+ function readString4(value) {
2358
+ return String(value ?? "").trim();
2359
+ }
2360
+ function readNumber(value, fallback = 0) {
2361
+ const parsed = Number(value);
2362
+ return Number.isFinite(parsed) ? parsed : fallback;
2363
+ }
2364
+ function readLower2(value) {
2365
+ return readString4(value).toLowerCase();
2366
+ }
2367
+ function readBoolean(value, fallback = false) {
2368
+ return typeof value === "boolean" ? value : fallback;
2369
+ }
2173
2370
  function readLocalizedText(value, fallback = "") {
2174
2371
  if (typeof value === "string") {
2175
- return readString3(value) || fallback;
2372
+ return readString4(value) || fallback;
2176
2373
  }
2177
2374
  if (!value || typeof value !== "object" || Array.isArray(value)) {
2178
2375
  return fallback;
2179
2376
  }
2180
2377
  const record = value;
2181
- return readString3(record.en) || readString3(record.ro) || Object.values(record).map((item) => readString3(item)).find(Boolean) || fallback;
2378
+ return readString4(record.en) || readString4(record.ro) || Object.values(record).map((item) => readString4(item)).find(Boolean) || fallback;
2182
2379
  }
2183
2380
  function escapeHtml(value) {
2184
2381
  return String(value ?? "").replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
@@ -2188,7 +2385,7 @@ function readRecord(value) {
2188
2385
  return value;
2189
2386
  }
2190
2387
  function formatStateLabel(value, fallback = "\u2014") {
2191
- const raw = readString3(value);
2388
+ const raw = readString4(value);
2192
2389
  if (!raw) return fallback;
2193
2390
  return raw.replace(/_/g, " ");
2194
2391
  }
@@ -2196,8 +2393,8 @@ function hasPositiveCredits(accessProjection) {
2196
2393
  return readNumber(accessProjection?.credits_remaining, 0) > 0;
2197
2394
  }
2198
2395
  function isExhaustedIncludedCreditAccess(input) {
2199
- const balanceState = readLower(input.accessProjection?.balance_state);
2200
- const entitlementState = readLower(input.accessProjection?.entitlement_state);
2396
+ const balanceState = readLower2(input.accessProjection?.balance_state);
2397
+ const entitlementState = readLower2(input.accessProjection?.entitlement_state);
2201
2398
  return !input.currentSubscription && entitlementState === "active" && !hasPositiveCredits(input.accessProjection) && (balanceState === "empty" || balanceState === "insufficient");
2202
2399
  }
2203
2400
  function hasEffectiveCoverage(input) {
@@ -2211,11 +2408,68 @@ function formatCoverageLabel(input) {
2211
2408
  if (hasEffectiveCoverage(input)) return "Available";
2212
2409
  return formatStateLabel(input.accessProjection?.entitlement_state, "Unavailable");
2213
2410
  }
2411
+ function resolveSubscriptionCoverageLabel(input) {
2412
+ const copy = buildXmsSurfaceCopy({ locale: input.locale });
2413
+ if (typeof input.overduePolicy?.has_current_access === "boolean") {
2414
+ return input.overduePolicy.has_current_access ? copy.coverageActiveLabel : copy.coverageInactiveLabel;
2415
+ }
2416
+ const status = readLower2(input.currentSubscription?.status);
2417
+ if (status === "active" || status === "trialing" || status === "grace" || status === "cancelled") {
2418
+ return copy.coverageActiveLabel;
2419
+ }
2420
+ if (status === "past_due" || status === "expired" || status === "suspended") {
2421
+ return copy.coverageInactiveLabel;
2422
+ }
2423
+ return "";
2424
+ }
2425
+ function resolveSubscriptionReasonLabel(input) {
2426
+ const copy = buildXmsSurfaceCopy({ locale: input.locale });
2427
+ const reason = readLower2(input.overduePolicy?.effective_status_reason);
2428
+ if (!reason) return "";
2429
+ if (reason === "grace_covered_past_due") return copy.reasonGraceCoveredPastDueLabel;
2430
+ if (reason === "past_due_after_period_end") return copy.reasonPastDueAfterPeriodEndLabel;
2431
+ if (reason === "expired_after_boundary") return copy.reasonExpiredAfterBoundaryLabel;
2432
+ return formatStateLabel(reason, "");
2433
+ }
2434
+ function buildXmsSubscriptionLifecycleSummary(input) {
2435
+ const currentSubscription = readRecord(input.currentSubscription ?? input.current_subscription);
2436
+ const overduePolicy = currentSubscription?.overdue_policy && typeof currentSubscription.overdue_policy === "object" && !Array.isArray(currentSubscription.overdue_policy) ? currentSubscription.overdue_policy : null;
2437
+ const status = readLower2(currentSubscription?.status);
2438
+ const renewsAt = readString4(currentSubscription?.renews_at) || null;
2439
+ const currentPeriodEndsAt = readString4(currentSubscription?.current_period_ends_at) || null;
2440
+ const expiresAt = readString4(currentSubscription?.expired_at) || null;
2441
+ const cancelledAt = readString4(currentSubscription?.cancelled_at) || null;
2442
+ const overdueSince = readString4(overduePolicy?.overdue_since) || null;
2443
+ const expiryBoundaryAt = readString4(overduePolicy?.expiry_boundary_at) || null;
2444
+ return {
2445
+ present: Boolean(currentSubscription),
2446
+ status,
2447
+ statusLabel: formatStateLabel(currentSubscription?.status, ""),
2448
+ coverageLabel: resolveSubscriptionCoverageLabel({
2449
+ currentSubscription,
2450
+ overduePolicy,
2451
+ locale: input.locale
2452
+ }),
2453
+ reasonCode: readString4(overduePolicy?.effective_status_reason) || null,
2454
+ reasonLabel: resolveSubscriptionReasonLabel({
2455
+ overduePolicy,
2456
+ locale: input.locale
2457
+ }),
2458
+ renewsAt,
2459
+ currentPeriodEndsAt,
2460
+ expiresAt,
2461
+ cancelledAt,
2462
+ overdueSince,
2463
+ expiryBoundaryAt,
2464
+ canCancel: Boolean(currentSubscription) && (status === "active" || status === "trialing" || status === "grace" || status === "past_due"),
2465
+ canRefresh: Boolean(currentSubscription)
2466
+ };
2467
+ }
2214
2468
  function listXappMonetizationPaywalls(items) {
2215
2469
  return (Array.isArray(items) ? items : []).filter((item) => item && typeof item === "object" && !Array.isArray(item)).map((item) => item);
2216
2470
  }
2217
2471
  function buildPaywallPlacementCandidates(value) {
2218
- const raw = readLower(value);
2472
+ const raw = readLower2(value);
2219
2473
  if (!raw) return [];
2220
2474
  const out = /* @__PURE__ */ new Set([raw]);
2221
2475
  if (raw === "paywall" || raw === "default_paywall") {
@@ -2242,15 +2496,15 @@ function buildPaywallPlacementCandidates(value) {
2242
2496
  }
2243
2497
  function selectXappMonetizationPaywall(input) {
2244
2498
  const paywalls = listXappMonetizationPaywalls(input.paywalls);
2245
- const slug = readLower(input.slug);
2246
- const placement = readLower(input.placement);
2499
+ const slug = readLower2(input.slug);
2500
+ const placement = readLower2(input.placement);
2247
2501
  if (slug) {
2248
- const matched = paywalls.find((item) => readLower(item.slug) === slug);
2502
+ const matched = paywalls.find((item) => readLower2(item.slug) === slug);
2249
2503
  if (matched) return matched;
2250
2504
  }
2251
2505
  if (placement) {
2252
2506
  const candidates = buildPaywallPlacementCandidates(placement);
2253
- const matched = paywalls.find((item) => candidates.includes(readLower(item.placement)));
2507
+ const matched = paywalls.find((item) => candidates.includes(readLower2(item.placement)));
2254
2508
  if (matched) return matched;
2255
2509
  }
2256
2510
  return paywalls[0] || null;
@@ -2262,23 +2516,24 @@ function flattenXappMonetizationPaywallPackages(paywall) {
2262
2516
  const packageRecord = pkg && typeof pkg === "object" && !Array.isArray(pkg) ? pkg : {};
2263
2517
  const price = Array.isArray(packageRecord.prices) ? packageRecord.prices[0] || null : null;
2264
2518
  out.push({
2265
- offeringId: readString3(packageRecord.offering_id),
2266
- offeringSlug: readString3(packageRecord.offering_slug),
2267
- offeringTitle: readString3(packageRecord.offering_slug) || "Offering",
2268
- offeringPlacement: readString3(packageRecord.offering_placement) || null,
2269
- packageId: readString3(packageRecord.id),
2270
- packageSlug: readString3(packageRecord.slug),
2271
- packageTitle: readString3(packageRecord.slug) || "Package",
2272
- packageKind: readString3(packageRecord.package_kind) || "standard",
2273
- productId: readString3(packageRecord.product?.id),
2274
- productSlug: readString3(packageRecord.product?.slug),
2275
- productFamily: readString3(
2519
+ offeringId: readString4(packageRecord.offering_id),
2520
+ offeringSlug: readString4(packageRecord.offering_slug),
2521
+ offeringTitle: readString4(packageRecord.offering_slug) || "Offering",
2522
+ offeringPlacement: readString4(packageRecord.offering_placement) || null,
2523
+ packageId: readString4(packageRecord.id),
2524
+ packageSlug: readString4(packageRecord.slug),
2525
+ packageTitle: readString4(packageRecord.slug) || "Package",
2526
+ packageKind: readString4(packageRecord.package_kind) || "standard",
2527
+ productId: readString4(packageRecord.product?.id),
2528
+ productSlug: readString4(packageRecord.product?.slug),
2529
+ productFamily: readString4(
2276
2530
  packageRecord.product?.product_family
2277
2531
  ),
2278
- priceId: readString3(price?.id),
2279
- amount: readString3(price?.amount),
2280
- currency: readString3(price?.currency),
2281
- billingPeriod: readString3(price?.billing_period) || null,
2532
+ productMetadata: packageRecord.product?.metadata && typeof packageRecord.product.metadata === "object" ? packageRecord.product.metadata : {},
2533
+ priceId: readString4(price?.id),
2534
+ amount: readString4(price?.amount),
2535
+ currency: readString4(price?.currency),
2536
+ billingPeriod: readString4(price?.billing_period) || null,
2282
2537
  purchasePolicy: readProjectedPurchasePolicy(packageRecord.purchase_policy),
2283
2538
  metadata: packageRecord.metadata && typeof packageRecord.metadata === "object" ? packageRecord.metadata : {}
2284
2539
  });
@@ -2286,7 +2541,7 @@ function flattenXappMonetizationPaywallPackages(paywall) {
2286
2541
  return out.filter((item) => item.offeringId && item.packageId && item.priceId);
2287
2542
  }
2288
2543
  function formatPlacementLabel(value, fallback = "General placement") {
2289
- const raw = readString3(value);
2544
+ const raw = readString4(value);
2290
2545
  if (!raw) return fallback;
2291
2546
  return raw.replace(/[_-]+/g, " ");
2292
2547
  }
@@ -2300,8 +2555,8 @@ function readPackageCredits(item) {
2300
2555
  }
2301
2556
  function buildMonetizationOfferingPresentation(input) {
2302
2557
  const record = input && typeof input === "object" && !Array.isArray(input) ? input : {};
2303
- const offeringLabel = readString3(record.offeringTitle) || formatStateLabel(record.offeringSlug, "Offering");
2304
- const placementRaw = readLower(record.offeringPlacement);
2558
+ const offeringLabel = readString4(record.offeringTitle) || formatStateLabel(record.offeringSlug, "Offering");
2559
+ const placementRaw = readLower2(record.offeringPlacement);
2305
2560
  const placementLabel = formatPlacementLabel(record.offeringPlacement);
2306
2561
  let summary = "General offering surface for this xapp.";
2307
2562
  if (placementRaw.includes("feature") && placementRaw.includes("paywall")) {
@@ -2324,38 +2579,39 @@ function buildMonetizationPaywallPresentation(input) {
2324
2579
  const paywallLabel = readLocalizedText(record.title, formatStateLabel(record.slug, "Paywall")) || "Paywall";
2325
2580
  const placementLabel = formatPlacementLabel(record.placement);
2326
2581
  const packages = flattenXappMonetizationPaywallPackages(record);
2327
- const defaultPackageRef = readString3(record.default_package_ref);
2328
- const defaultPackage = packages.find((item) => readString3(item.packageSlug) === defaultPackageRef) || packages[0] || null;
2582
+ const defaultPackageRef = readString4(record.default_package_ref);
2583
+ const defaultPackage = packages.find((item) => readString4(item.packageSlug) === defaultPackageRef) || packages[0] || null;
2329
2584
  const summary = readLocalizedText(record.description) || (placementLabel === "General placement" ? "Presentation surface for monetized package selection." : `${placementLabel} surface for monetized package selection.`);
2330
2585
  return {
2331
2586
  paywallLabel,
2332
2587
  placementLabel,
2333
2588
  summary,
2334
- defaultPackageLabel: defaultPackage ? readString3(defaultPackage.packageTitle) : "",
2589
+ defaultPackageLabel: defaultPackage ? readString4(defaultPackage.packageTitle) : "",
2335
2590
  packageCountLabel: `${packages.length} package${packages.length === 1 ? "" : "s"}`
2336
2591
  };
2337
2592
  }
2338
2593
  function buildMonetizationPaywallRenderModel(input) {
2339
2594
  const record = input && typeof input === "object" && !Array.isArray(input) ? input : {};
2340
2595
  const presentation = buildMonetizationPaywallPresentation(record);
2341
- const defaultPackageRef = readString3(record.default_package_ref);
2596
+ const defaultPackageRef = readString4(record.default_package_ref);
2342
2597
  const packages = flattenXappMonetizationPaywallPackages(record).map((item) => {
2343
2598
  const packagePresentation = buildMonetizationPackagePresentation(item);
2344
2599
  return {
2345
- packageId: readString3(item.packageId),
2346
- packageSlug: readString3(item.packageSlug),
2347
- packageTitle: readString3(item.packageTitle) || "Package",
2348
- productId: readString3(item.productId),
2349
- productSlug: readString3(item.productSlug),
2350
- productFamily: readString3(item.productFamily),
2600
+ packageId: readString4(item.packageId),
2601
+ packageSlug: readString4(item.packageSlug),
2602
+ packageTitle: readString4(item.packageTitle) || "Package",
2603
+ productId: readString4(item.productId),
2604
+ productSlug: readString4(item.productSlug),
2605
+ productFamily: readString4(item.productFamily),
2606
+ productMetadata: item.productMetadata && typeof item.productMetadata === "object" && !Array.isArray(item.productMetadata) ? item.productMetadata : {},
2351
2607
  metadata: item.metadata && typeof item.metadata === "object" && !Array.isArray(item.metadata) ? item.metadata : {},
2352
- description: readString3(item.description) || packagePresentation.summary,
2608
+ description: readString4(item.description) || packagePresentation.summary,
2353
2609
  fitLabel: packagePresentation.fitLabel,
2354
2610
  moneyLabel: packagePresentation.moneyLabel,
2355
2611
  offeringLabel: packagePresentation.offeringLabel,
2356
2612
  placementLabel: packagePresentation.placementLabel,
2357
2613
  signals: packagePresentation.signals,
2358
- isDefault: Boolean(defaultPackageRef) && readString3(item.packageSlug) === defaultPackageRef
2614
+ isDefault: Boolean(defaultPackageRef) && readString4(item.packageSlug) === defaultPackageRef
2359
2615
  };
2360
2616
  });
2361
2617
  const badges = [presentation.placementLabel, presentation.packageCountLabel];
@@ -2415,6 +2671,11 @@ var monetizationPlansSurfaceStyles = `
2415
2671
  display: grid;
2416
2672
  gap: 10px;
2417
2673
  }
2674
+ .xapps-xms-plans__surface-actions {
2675
+ display: flex;
2676
+ flex-wrap: wrap;
2677
+ gap: 10px;
2678
+ }
2418
2679
  .xapps-xms-plans__meta-row {
2419
2680
  display: flex;
2420
2681
  justify-content: space-between;
@@ -2558,6 +2819,42 @@ var monetizationPlansSurfaceStyles = `
2558
2819
  transform: none;
2559
2820
  box-shadow: none;
2560
2821
  }
2822
+ .xapps-xms-plans__surface-action {
2823
+ min-height: 38px;
2824
+ border-radius: 12px;
2825
+ padding: 9px 13px;
2826
+ border: 1px solid color-mix(in srgb, var(--xapps-border-color, rgba(148, 163, 184, 0.24)) 92%, transparent);
2827
+ background: color-mix(in srgb, var(--xapps-surface-bg, #ffffff) 96%, var(--xapps-surface-subtle, #f8fafc));
2828
+ color: var(--xapps-text-primary, #0f172a);
2829
+ font-weight: 700;
2830
+ cursor: pointer;
2831
+ transition:
2832
+ border-color 0.18s ease,
2833
+ background-color 0.18s ease,
2834
+ color 0.18s ease,
2835
+ box-shadow 0.18s ease;
2836
+ }
2837
+ .xapps-xms-plans__surface-action:hover,
2838
+ .xapps-xms-plans__surface-action:focus-visible {
2839
+ border-color: color-mix(in srgb, var(--xapps-accent, #0f766e) 28%, var(--xapps-border-color, transparent));
2840
+ background: color-mix(in srgb, var(--xapps-accent, #0f766e) 7%, var(--xapps-surface-bg, #ffffff));
2841
+ color: color-mix(in srgb, var(--xapps-accent, #0f766e) 24%, var(--xapps-text-primary, #0f172a));
2842
+ }
2843
+ .xapps-xms-plans__surface-action[data-variant="danger"] {
2844
+ border-color: color-mix(in srgb, var(--xapps-danger, #dc2626) 22%, var(--xapps-border-color, transparent));
2845
+ color: var(--xapps-danger, #b91c1c);
2846
+ }
2847
+ .xapps-xms-plans__surface-action[data-variant="danger"]:hover,
2848
+ .xapps-xms-plans__surface-action[data-variant="danger"]:focus-visible {
2849
+ border-color: color-mix(in srgb, var(--xapps-danger, #dc2626) 34%, var(--xapps-border-color, transparent));
2850
+ background: color-mix(in srgb, var(--xapps-danger, #dc2626) 8%, var(--xapps-surface-bg, #ffffff));
2851
+ color: var(--xapps-danger, #991b1b);
2852
+ }
2853
+ .xapps-xms-plans__surface-action[disabled] {
2854
+ cursor: not-allowed;
2855
+ opacity: 0.6;
2856
+ box-shadow: none;
2857
+ }
2561
2858
  .xapps-xms-plans__empty {
2562
2859
  color: var(--xapps-text-secondary, #64748b);
2563
2860
  font-size: 14px;
@@ -2655,7 +2952,7 @@ var monetizationPlansSurfaceStyles = `
2655
2952
  }
2656
2953
  `;
2657
2954
  function formatPlansDateTime(value, locale = "en") {
2658
- const raw = readString3(value);
2955
+ const raw = readString4(value);
2659
2956
  if (!raw) return "";
2660
2957
  const parsed = new Date(raw);
2661
2958
  if (Number.isNaN(parsed.getTime())) return raw;
@@ -2683,7 +2980,7 @@ function readHistoryBucket(history, key) {
2683
2980
  }
2684
2981
  function readHistoryTitle(item, keys, fallback) {
2685
2982
  for (const key of keys) {
2686
- const value = readString3(item[key]);
2983
+ const value = readString4(item[key]);
2687
2984
  if (value) return value;
2688
2985
  }
2689
2986
  return fallback;
@@ -2691,13 +2988,13 @@ function readHistoryTitle(item, keys, fallback) {
2691
2988
  function readHistoryMeta(item, keys, locale) {
2692
2989
  const out = [];
2693
2990
  for (const key of keys) {
2694
- const value = key.endsWith("_at") ? formatPlansDateTime(item[key], locale) : readString3(item[key]);
2991
+ const value = key === "settlement_effect_detail" ? formatSettlementEffectDetailLabel(item.settlement_effect, item[key], locale) : key.endsWith("_at") ? formatPlansDateTime(item[key], locale) : readString4(item[key]);
2695
2992
  if (value) out.push(formatStateLabel(value, value));
2696
2993
  }
2697
2994
  return out;
2698
2995
  }
2699
2996
  function formatTimelineBucketLabel(value, locale) {
2700
- const normalized = readLower(value);
2997
+ const normalized = readLower2(value);
2701
2998
  const copy = buildXmsSurfaceCopy({ locale });
2702
2999
  if (!normalized) return copy.historyGenericLabel;
2703
3000
  if (normalized === "purchase_intents") return copy.historyPurchaseIntentLabel;
@@ -2709,20 +3006,58 @@ function formatTimelineBucketLabel(value, locale) {
2709
3006
  if (normalized === "invoices") return copy.historyInvoiceLabel;
2710
3007
  return formatStateLabel(normalized, normalized);
2711
3008
  }
3009
+ function formatSettlementEffectDetailLabel(effect, detail, locale) {
3010
+ const rawDetail = readString4(detail);
3011
+ if (!rawDetail) return null;
3012
+ const normalizedEffect = readLower2(effect);
3013
+ const normalizedDetail = readLower2(detail);
3014
+ const copy = buildXmsSurfaceCopy({ locale });
3015
+ if (normalizedEffect === "transaction_chargeback") {
3016
+ if (normalizedDetail === "warning_needs_response") {
3017
+ return copy.historySettlementDetailDisputeWarningNeedsResponse;
3018
+ }
3019
+ if (normalizedDetail === "warning_under_review") {
3020
+ return copy.historySettlementDetailDisputeWarningUnderReview;
3021
+ }
3022
+ if (normalizedDetail === "warning_closed") {
3023
+ return copy.historySettlementDetailDisputeWarningClosed;
3024
+ }
3025
+ if (normalizedDetail === "needs_response") {
3026
+ return copy.historySettlementDetailDisputeNeedsResponse;
3027
+ }
3028
+ if (normalizedDetail === "under_review") {
3029
+ return copy.historySettlementDetailDisputeUnderReview;
3030
+ }
3031
+ if (normalizedDetail === "won") {
3032
+ return copy.historySettlementDetailDisputeWon;
3033
+ }
3034
+ if (normalizedDetail === "lost") {
3035
+ return copy.historySettlementDetailDisputeLost;
3036
+ }
3037
+ return normalizedDetail.replace(/_/g, " ");
3038
+ }
3039
+ return rawDetail;
3040
+ }
2712
3041
  function buildTimelineHtml(input) {
2713
3042
  if (!input.total) return "";
2714
3043
  return `
2715
3044
  <div class="xapps-xms-plans__timeline">
2716
3045
  ${input.items.map((item) => {
2717
- const title = readString3(item.title) || readString3(item.id) || formatTimelineBucketLabel(item.bucket, input.locale);
3046
+ const title = readString4(item.title) || readString4(item.id) || formatTimelineBucketLabel(item.bucket, input.locale);
2718
3047
  const when = formatPlansDateTime(item.occurred_at, input.locale);
2719
3048
  const meta = [
2720
3049
  formatTimelineBucketLabel(item.bucket, input.locale),
2721
- readString3(item.status) ? formatStateLabel(item.status, readString3(item.status)) : "",
2722
- readString3(item.scope),
2723
- readString3(item.correlation),
2724
- readString3(item.amount) && readString3(item.currency) ? `${readString3(item.amount)} ${readString3(item.currency)}` : readString3(item.amount),
2725
- readString3(item.note)
3050
+ readString4(item.status) ? formatStateLabel(item.status, readString4(item.status)) : "",
3051
+ readString4(item.settlement_effect) ? formatStateLabel(item.settlement_effect, readString4(item.settlement_effect)) : "",
3052
+ formatSettlementEffectDetailLabel(
3053
+ item.settlement_effect,
3054
+ item.settlement_effect_detail,
3055
+ input.locale
3056
+ ),
3057
+ readString4(item.scope),
3058
+ readString4(item.correlation),
3059
+ readString4(item.amount) && readString4(item.currency) ? `${readString4(item.amount)} ${readString4(item.currency)}` : readString4(item.amount),
3060
+ readString4(item.note)
2726
3061
  ].filter(Boolean);
2727
3062
  return `
2728
3063
  <div class="xapps-xms-plans__timeline-item">
@@ -2749,7 +3084,7 @@ function buildHistorySectionHtml(input) {
2749
3084
  ${input.items.map((item) => {
2750
3085
  const title = readHistoryTitle(item, input.itemTitleKeys, input.itemFallbackTitle);
2751
3086
  const statusKeys = input.itemStatusKeys || [];
2752
- const status = statusKeys.map((key) => readString3(item[key])).find(Boolean);
3087
+ const status = statusKeys.map((key) => readString4(item[key])).find(Boolean);
2753
3088
  const meta = readHistoryMeta(item, input.itemMetaKeys, input.locale);
2754
3089
  return `
2755
3090
  <div class="xapps-xms-plans__history-item">
@@ -2791,7 +3126,13 @@ function buildMonetizationHistorySections(input) {
2791
3126
  itemTitleKeys: ["package_slug", "product_slug", "id"],
2792
3127
  itemFallbackTitle: copy.historyTransactionLabel,
2793
3128
  itemStatusKeys: ["status"],
2794
- itemMetaKeys: ["amount", "currency", "payment_session_id", "occurred_at"]
3129
+ itemMetaKeys: [
3130
+ "amount",
3131
+ "currency",
3132
+ "settlement_effect",
3133
+ "payment_session_id",
3134
+ "occurred_at"
3135
+ ]
2795
3136
  }),
2796
3137
  buildHistorySectionHtml({
2797
3138
  title: copy.historySubscriptionsTitle,
@@ -2831,7 +3172,7 @@ function buildMonetizationHistorySections(input) {
2831
3172
  itemTitleKeys: ["event_kind", "wallet_product_slug", "id"],
2832
3173
  itemFallbackTitle: copy.historyWalletLedgerEntryLabel,
2833
3174
  itemStatusKeys: [],
2834
- itemMetaKeys: ["amount", "currency", "source_kind", "occurred_at"]
3175
+ itemMetaKeys: ["amount", "currency", "settlement_effect", "source_kind", "occurred_at"]
2835
3176
  }),
2836
3177
  buildHistorySectionHtml({
2837
3178
  title: copy.historyAccessSnapshotsTitle,
@@ -2851,17 +3192,20 @@ function buildMonetizationHistorySections(input) {
2851
3192
  itemTitleKeys: ["invoice_identifier", "id"],
2852
3193
  itemFallbackTitle: copy.historyInvoiceLabel,
2853
3194
  itemStatusKeys: ["status"],
2854
- itemMetaKeys: ["provider_key", "owner_scope", "created_at"]
3195
+ itemMetaKeys: [
3196
+ "settlement_effect",
3197
+ "settlement_effect_detail",
3198
+ "provider_key",
3199
+ "owner_scope",
3200
+ "created_at"
3201
+ ]
2855
3202
  })
2856
3203
  ].filter(Boolean);
2857
3204
  }
2858
- function buildXmsSurfaceCopy(input) {
2859
- return XMS_COPY_CATALOG[resolveXmsCopyLocale(input?.locale)].surface;
2860
- }
2861
3205
  function buildMonetizationHistorySurfaceHtml(input, options = {}) {
2862
3206
  const record = readRecord(input) ?? {};
2863
3207
  const history = readRecord(record.history) ?? record;
2864
- const locale = readString3(options.locale) || "en";
3208
+ const locale = readString4(options.locale) || "en";
2865
3209
  const includeStyles = options.includeStyles !== false;
2866
3210
  const showHeader = options.showHeader !== false;
2867
3211
  const surfaceCopy = buildXmsSurfaceCopy({ locale });
@@ -2873,14 +3217,14 @@ function buildMonetizationHistorySurfaceHtml(input, options = {}) {
2873
3217
  <section class="xapps-xms-plans">
2874
3218
  ${showHeader ? `<div class="xapps-xms-plans__header">
2875
3219
  <h3 class="xapps-xms-plans__title">${escapeHtml(
2876
- readString3(options.title) || surfaceCopy.historyTitle
3220
+ readString4(options.title) || surfaceCopy.historyTitle
2877
3221
  )}</h3>
2878
- ${readString3(options.subtitle) ? `<div class="xapps-xms-plans__subtitle">${escapeHtml(
2879
- readString3(options.subtitle)
3222
+ ${readString4(options.subtitle) ? `<div class="xapps-xms-plans__subtitle">${escapeHtml(
3223
+ readString4(options.subtitle)
2880
3224
  )}</div>` : ""}
2881
3225
  </div>` : ""}
2882
- ${readString3(options.notice) ? `<div class="xapps-xms-plans__notice">${escapeHtml(readString3(options.notice))}</div>` : ""}
2883
- ${readString3(options.error) ? `<div class="xapps-xms-plans__error">${escapeHtml(readString3(options.error))}</div>` : ""}
3226
+ ${readString4(options.notice) ? `<div class="xapps-xms-plans__notice">${escapeHtml(readString4(options.notice))}</div>` : ""}
3227
+ ${readString4(options.error) ? `<div class="xapps-xms-plans__error">${escapeHtml(readString4(options.error))}</div>` : ""}
2884
3228
  ${timeline.total ? `<section class="xapps-xms-plans__card">
2885
3229
  <h4 class="xapps-xms-plans__section-title">${escapeHtml(surfaceCopy.recentTimelineTitle)}</h4>
2886
3230
  <div class="xapps-xms-plans__subtitle">${escapeHtml(surfaceCopy.recentTimelineSubtitle)}</div>
@@ -2903,8 +3247,8 @@ function buildMonetizationHistorySurfaceHtml(input, options = {}) {
2903
3247
  }
2904
3248
  function buildMonetizationPackagePresentation(input) {
2905
3249
  const item = input && typeof input === "object" && !Array.isArray(input) ? input : {};
2906
- const packageKind = readString3(item.packageKind);
2907
- const packageSlug = readLower(item.packageSlug);
3250
+ const packageKind = readString4(item.packageKind);
3251
+ const packageSlug = readLower2(item.packageSlug);
2908
3252
  const metadata = item.metadata && typeof item.metadata === "object" && !Array.isArray(item.metadata) ? item.metadata : {};
2909
3253
  const credits = readPackageCredits(item);
2910
3254
  const moneyLabel = normalizeMoneyLabel(item);
@@ -2925,14 +3269,14 @@ function buildMonetizationPackagePresentation(input) {
2925
3269
  summary = "Blends access coverage with bundled credits for mixed workflows.";
2926
3270
  }
2927
3271
  const signals = [];
2928
- if (readString3(metadata.badge)) {
2929
- signals.push(readString3(metadata.badge));
3272
+ if (readString4(metadata.badge)) {
3273
+ signals.push(readString4(metadata.badge));
2930
3274
  }
2931
3275
  if (credits > 0) {
2932
3276
  signals.push(`${credits} credits`);
2933
3277
  }
2934
- if (readString3(item.billingPeriod)) {
2935
- signals.push(`billed ${readString3(item.billingPeriod)}`);
3278
+ if (readString4(item.billingPeriod)) {
3279
+ signals.push(`billed ${readString4(item.billingPeriod)}`);
2936
3280
  }
2937
3281
  if (offeringPresentation.offeringLabel) {
2938
3282
  signals.push(offeringPresentation.offeringLabel);
@@ -2952,26 +3296,39 @@ function buildMonetizationPackagePresentation(input) {
2952
3296
  }
2953
3297
  function collectPackageOwnershipCandidates(item) {
2954
3298
  const metadata = item.metadata && typeof item.metadata === "object" && !Array.isArray(item.metadata) ? item.metadata : {};
3299
+ const productMetadata = item.productMetadata && typeof item.productMetadata === "object" && !Array.isArray(item.productMetadata) ? item.productMetadata : {};
3300
+ return [
3301
+ readLower2(item.productSlug),
3302
+ readLower2(item.packageSlug),
3303
+ readLower2(metadata.tier),
3304
+ readLower2(metadata.access_tier),
3305
+ readLower2(productMetadata.tier),
3306
+ readLower2(productMetadata.access_tier)
3307
+ ].filter(Boolean);
3308
+ }
3309
+ function collectCurrentSubscriptionCandidates(currentSubscription) {
3310
+ const metadata = currentSubscription.metadata && typeof currentSubscription.metadata === "object" ? currentSubscription.metadata : currentSubscription.metadata_jsonb && typeof currentSubscription.metadata_jsonb === "object" ? currentSubscription.metadata_jsonb : {};
2955
3311
  return [
2956
- readLower(item.productSlug),
2957
- readLower(item.packageSlug),
2958
- readLower(metadata.tier),
2959
- readLower(metadata.access_tier)
3312
+ readLower2(currentSubscription.product_slug),
3313
+ readLower2(currentSubscription.tier),
3314
+ readLower2(metadata.product_slug),
3315
+ readLower2(metadata.tier),
3316
+ readLower2(metadata.access_tier)
2960
3317
  ].filter(Boolean);
2961
3318
  }
2962
3319
  function hasActiveRecurringSubscription(currentSubscription) {
2963
3320
  const record = currentSubscription && typeof currentSubscription === "object" && !Array.isArray(currentSubscription) ? currentSubscription : {};
2964
- const status = readLower(record.status);
3321
+ const status = readLower2(record.status);
2965
3322
  if (!status || status === "expired") return false;
2966
- const expiredAt = readString3(record.expired_at);
3323
+ const expiredAt = readString4(record.expired_at);
2967
3324
  if (!expiredAt) return true;
2968
3325
  const expiresAtMs = Date.parse(expiredAt);
2969
3326
  return Number.isNaN(expiresAtMs) || expiresAtMs > Date.now();
2970
3327
  }
2971
3328
  function hasCurrentOwnedEntitlement(entitlement) {
2972
- const status = readLower(entitlement.status);
3329
+ const status = readLower2(entitlement.status);
2973
3330
  if (status !== "active" && status !== "grace_period") return false;
2974
- const expiresAt = readString3(entitlement.expires_at);
3331
+ const expiresAt = readString4(entitlement.expires_at);
2975
3332
  if (!expiresAt) return true;
2976
3333
  const expiresAtMs = Date.parse(expiresAt);
2977
3334
  return Number.isNaN(expiresAtMs) || expiresAtMs > Date.now();
@@ -2979,14 +3336,14 @@ function hasCurrentOwnedEntitlement(entitlement) {
2979
3336
  function readProjectedPurchasePolicy(value) {
2980
3337
  const record = value && typeof value === "object" && !Array.isArray(value) ? value : null;
2981
3338
  if (!record) return null;
2982
- const status = readLower(record.status);
2983
- const transitionKind = readLower(record.transition_kind ?? record.transitionKind);
3339
+ const status = readLower2(record.status);
3340
+ const transitionKind = readLower2(record.transition_kind ?? record.transitionKind);
2984
3341
  if (!status || !transitionKind) return null;
2985
3342
  return {
2986
3343
  canPurchase: readBoolean(record.can_purchase ?? record.canPurchase, true),
2987
3344
  status: status === "current_recurring_plan" || status === "owned_additive_unlock" ? status : "available",
2988
3345
  transitionKind: transitionKind === "start_recurring" || transitionKind === "replace_recurring" || transitionKind === "buy_additive_unlock" || transitionKind === "buy_credit_pack" || transitionKind === "activate_hybrid" ? transitionKind : "none",
2989
- reason: readString3(record.reason) || null
3346
+ reason: readString4(record.reason) || null
2990
3347
  };
2991
3348
  }
2992
3349
  function resolveMonetizationPackagePurchasePolicy(input) {
@@ -2995,20 +3352,23 @@ function resolveMonetizationPackagePurchasePolicy(input) {
2995
3352
  if (projectedPolicy) return projectedPolicy;
2996
3353
  const currentSubscription = input.currentSubscription && typeof input.currentSubscription === "object" && !Array.isArray(input.currentSubscription) ? input.currentSubscription : {};
2997
3354
  const additiveEntitlements = Array.isArray(input.additiveEntitlements) ? input.additiveEntitlements : [];
2998
- const productFamily = readLower(item.productFamily);
2999
- const packageKind = readLower(item.packageKind);
3000
- const productId = readLower(item.productId);
3001
- const currentSubscriptionProductId = readLower(currentSubscription.product_id);
3355
+ const productFamily = readLower2(item.productFamily);
3356
+ const packageKind = readLower2(item.packageKind);
3357
+ const productId = readLower2(item.productId);
3358
+ const currentSubscriptionProductId = readLower2(currentSubscription.product_id);
3002
3359
  const includedCredits = readPackageCredits(item);
3003
3360
  const ownershipCandidates = new Set(collectPackageOwnershipCandidates(item));
3361
+ const currentSubscriptionCandidates = new Set(
3362
+ collectCurrentSubscriptionCandidates(currentSubscription)
3363
+ );
3004
3364
  const ownedAdditiveUnlock = additiveEntitlements.some((entry) => {
3005
3365
  const entitlement = entry && typeof entry === "object" && !Array.isArray(entry) ? entry : {};
3006
3366
  if (!hasCurrentOwnedEntitlement(entitlement)) return false;
3007
- const entitlementProductId = readLower(entitlement.product_id);
3367
+ const entitlementProductId = readLower2(entitlement.product_id);
3008
3368
  if (productId && entitlementProductId && productId === entitlementProductId) return true;
3009
3369
  const candidateValues = [
3010
- readLower(entitlement.product_slug),
3011
- readLower(entitlement.tier)
3370
+ readLower2(entitlement.product_slug),
3371
+ readLower2(entitlement.tier)
3012
3372
  ].filter(Boolean);
3013
3373
  return candidateValues.some((value) => ownershipCandidates.has(value));
3014
3374
  });
@@ -3020,6 +3380,14 @@ function resolveMonetizationPackagePurchasePolicy(input) {
3020
3380
  reason: "current_recurring_plan"
3021
3381
  };
3022
3382
  }
3383
+ if (hasActiveRecurringSubscription(currentSubscription) && Array.from(ownershipCandidates).some((value) => currentSubscriptionCandidates.has(value))) {
3384
+ return {
3385
+ canPurchase: false,
3386
+ status: "current_recurring_plan",
3387
+ transitionKind: "none",
3388
+ reason: "current_recurring_plan"
3389
+ };
3390
+ }
3023
3391
  const consumableOneTimeUnlock = (productFamily === "one_time_unlock" || packageKind === "one_time_unlock") && includedCredits > 0;
3024
3392
  if (consumableOneTimeUnlock) {
3025
3393
  return {
@@ -3077,9 +3445,9 @@ function resolveMonetizationPackagePurchasePolicy(input) {
3077
3445
  };
3078
3446
  }
3079
3447
  function normalizeMoneyLabel(item) {
3080
- const amount = readString3(item.amount);
3081
- const currency = readString3(item.currency);
3082
- const billingPeriod = readString3(item.billingPeriod);
3448
+ const amount = readString4(item.amount);
3449
+ const currency = readString4(item.currency);
3450
+ const billingPeriod = readString4(item.billingPeriod);
3083
3451
  if (!amount && !currency) return "Price unavailable";
3084
3452
  return `${amount} ${currency}${billingPeriod ? ` / ${billingPeriod}` : ""}`.trim();
3085
3453
  }
@@ -3087,7 +3455,7 @@ function summarizeXappMonetizationSnapshot(input) {
3087
3455
  const record = input && typeof input === "object" && !Array.isArray(input) ? input : {};
3088
3456
  const accessProjection = record.access_projection && typeof record.access_projection === "object" && !Array.isArray(record.access_projection) ? record.access_projection : null;
3089
3457
  const currentSubscription = record.current_subscription && typeof record.current_subscription === "object" && !Array.isArray(record.current_subscription) ? record.current_subscription : null;
3090
- const overduePolicy = currentSubscription?.overdue_policy && typeof currentSubscription.overdue_policy === "object" && !Array.isArray(currentSubscription.overdue_policy) ? currentSubscription.overdue_policy : null;
3458
+ const lifecycle = buildXmsSubscriptionLifecycleSummary({ currentSubscription });
3091
3459
  return {
3092
3460
  accessCoverage: {
3093
3461
  available: hasEffectiveCoverage({ accessProjection, currentSubscription }),
@@ -3097,17 +3465,17 @@ function summarizeXappMonetizationSnapshot(input) {
3097
3465
  sourceRefLabel: formatStateLabel(accessProjection?.source_ref)
3098
3466
  },
3099
3467
  currentSubscription: {
3100
- present: Boolean(currentSubscription),
3101
- statusLabel: formatStateLabel(currentSubscription?.status),
3468
+ present: lifecycle.present,
3469
+ statusLabel: lifecycle.statusLabel || formatStateLabel(currentSubscription?.status),
3102
3470
  tierLabel: formatStateLabel(currentSubscription?.tier),
3103
- coverageLabel: overduePolicy?.has_current_access ? "Still active" : "Expired or blocked",
3104
- coverageReasonLabel: overduePolicy?.effective_status_reason ? formatStateLabel(overduePolicy.effective_status_reason) : "No active overdue restriction.",
3105
- renewsAt: readString3(currentSubscription?.renews_at) || null,
3106
- expiresAt: readString3(currentSubscription?.current_period_ends_at) || null,
3471
+ coverageLabel: lifecycle.coverageLabel || "Unknown",
3472
+ coverageReasonLabel: lifecycle.reasonLabel || buildXmsSurfaceCopy().noOverdueRestrictionLabel,
3473
+ renewsAt: lifecycle.renewsAt,
3474
+ expiresAt: lifecycle.expiresAt || lifecycle.currentPeriodEndsAt,
3107
3475
  paymentSessionIdLabel: formatStateLabel(currentSubscription?.payment_session_id)
3108
3476
  },
3109
3477
  wallet: {
3110
- creditsRemaining: readString3(accessProjection?.credits_remaining) || "0",
3478
+ creditsRemaining: readString4(accessProjection?.credits_remaining) || "0",
3111
3479
  balanceStateLabel: formatStateLabel(accessProjection?.balance_state, "unknown"),
3112
3480
  currentAccessLabel: hasEffectiveCoverage({ accessProjection, currentSubscription }) ? "Yes" : "No"
3113
3481
  }
@@ -3471,30 +3839,35 @@ function MonetizationPage() {
3471
3839
  /* @__PURE__ */ jsxs5("div", { children: [
3472
3840
  /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-kicker", children: t("activity.monetization", void 0, "Monetization") }),
3473
3841
  /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-id", children: item.title }),
3474
- /* @__PURE__ */ jsx9("div", { className: "mx-subtle-note mx-subtle-note-compact", children: item.subtitle })
3842
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-subtitle", children: item.subtitle })
3475
3843
  ] }),
3476
- /* @__PURE__ */ jsxs5("div", { className: "mx-record-actions", children: [
3477
- !xappIdFilter ? /* @__PURE__ */ jsx9(
3478
- Link5,
3479
- {
3480
- to: {
3481
- pathname: isEmbedded ? "/monetization" : "/marketplace/monetization",
3482
- search: (() => {
3483
- const qs = new URLSearchParams();
3484
- if (token) qs.set("token", token);
3485
- qs.set("xappId", item.xappId);
3486
- if (item.installationId) qs.set("installationId", item.installationId);
3487
- const suffix = qs.toString();
3488
- return suffix ? `?${suffix}` : "";
3489
- })()
3490
- },
3491
- className: "mx-btn mx-btn-ghost",
3492
- children: t("activity.monetization_focus_xapp", void 0, "Focus this app")
3493
- }
3494
- ) : null,
3495
- /* @__PURE__ */ jsx9(Link5, { to: item.plansHref, className: "mx-btn mx-btn-primary", children: t("activity.monetization_open_plans", void 0, "Open plans") }),
3496
- /* @__PURE__ */ jsx9(Link5, { to: item.historyHref, className: "mx-btn mx-btn-secondary", children: t("activity.monetization_open_history", void 0, "Open history") }),
3497
- /* @__PURE__ */ jsx9(Link5, { to: item.detailHref, className: "mx-btn mx-btn-ghost", children: t("common.view_app_details", void 0, "View app details") })
3844
+ /* @__PURE__ */ jsxs5("div", { className: "mx-record-actions mx-record-actions-monetization", children: [
3845
+ /* @__PURE__ */ jsxs5("div", { className: "mx-action-group", children: [
3846
+ /* @__PURE__ */ jsx9(Link5, { to: item.plansHref, className: "mx-btn mx-btn-primary", children: t("activity.monetization_open_plans", void 0, "Open plans") }),
3847
+ /* @__PURE__ */ jsx9(Link5, { to: item.historyHref, className: "mx-btn mx-btn-secondary", children: t("activity.monetization_open_history", void 0, "Open history") })
3848
+ ] }),
3849
+ /* @__PURE__ */ jsxs5("div", { className: "mx-action-group", children: [
3850
+ /* @__PURE__ */ jsx9(Link5, { to: item.detailHref, className: "mx-btn mx-btn-ghost", children: t("common.view_app_details", void 0, "View app details") }),
3851
+ !xappIdFilter ? /* @__PURE__ */ jsx9(
3852
+ Link5,
3853
+ {
3854
+ to: {
3855
+ pathname: isEmbedded ? "/monetization" : "/marketplace/monetization",
3856
+ search: (() => {
3857
+ const qs = new URLSearchParams();
3858
+ if (token) qs.set("token", token);
3859
+ qs.set("xappId", item.xappId);
3860
+ if (item.installationId)
3861
+ qs.set("installationId", item.installationId);
3862
+ const suffix = qs.toString();
3863
+ return suffix ? `?${suffix}` : "";
3864
+ })()
3865
+ },
3866
+ className: "mx-btn mx-btn-ghost",
3867
+ children: t("activity.monetization_focus_xapp", void 0, "Focus this app")
3868
+ }
3869
+ ) : null
3870
+ ] })
3498
3871
  ] })
3499
3872
  ] }),
3500
3873
  /* @__PURE__ */ jsxs5("div", { className: "mx-record-grid", children: [
@@ -4386,7 +4759,7 @@ function SchemaOutputView({ schema, value }) {
4386
4759
  function asRecord3(value) {
4387
4760
  return value && typeof value === "object" ? value : {};
4388
4761
  }
4389
- function readString4(value) {
4762
+ function readString5(value) {
4390
4763
  return typeof value === "string" ? value.trim() : "";
4391
4764
  }
4392
4765
  function resolveAction(summary) {
@@ -4401,13 +4774,13 @@ function resolveAction(summary) {
4401
4774
  return {};
4402
4775
  }
4403
4776
  function normalizeActionKind(raw) {
4404
- return readString4(raw).toLowerCase();
4777
+ return readString5(raw).toLowerCase();
4405
4778
  }
4406
4779
  function resolveText(t, key, fallback) {
4407
4780
  return typeof t === "function" ? t(key, fallback) : fallback;
4408
4781
  }
4409
4782
  function isSettledPaymentStatus(value) {
4410
- const normalized = readString4(value).toLowerCase();
4783
+ const normalized = readString5(value).toLowerCase();
4411
4784
  return normalized === "paid" || normalized === "settled" || normalized === "succeeded" || normalized === "completed";
4412
4785
  }
4413
4786
  function resolveCtaLabel(actionKind, t) {
@@ -4448,7 +4821,7 @@ function resolveLockMessage(reason, paymentAttemptState, reconcileState, t) {
4448
4821
  "Payment is not settled. Complete a new payment attempt."
4449
4822
  );
4450
4823
  }
4451
- const attempt = readString4(paymentAttemptState).toLowerCase();
4824
+ const attempt = readString5(paymentAttemptState).toLowerCase();
4452
4825
  if (attempt === "requires_action") {
4453
4826
  return resolveText(
4454
4827
  t,
@@ -4494,13 +4867,13 @@ function resolvePaymentLockStateFromGuardSummary(summaryInput, options) {
4494
4867
  const summary = asRecord3(summaryInput);
4495
4868
  const action = resolveAction(summary);
4496
4869
  const actionKind = normalizeActionKind(String(action.kind ?? summary.reason ?? ""));
4497
- const actionUrl = readString4(action.url);
4498
- const reason = readString4(summary.reason).toLowerCase();
4870
+ const actionUrl = readString5(action.url);
4871
+ const reason = readString5(summary.reason).toLowerCase();
4499
4872
  const monetizationState = asRecord3(summary.monetization_state);
4500
- const paymentSessionId = readString4(monetizationState.payment_session_id) || readString4(action.payment_session_id);
4501
- const paymentAttemptState = readString4(monetizationState.payment_attempt_state).toLowerCase();
4873
+ const paymentSessionId = readString5(monetizationState.payment_session_id) || readString5(action.payment_session_id);
4874
+ const paymentAttemptState = readString5(monetizationState.payment_attempt_state).toLowerCase();
4502
4875
  const reconcileState = (() => {
4503
- const candidate = readString4(options?.reconcileState).toLowerCase();
4876
+ const candidate = readString5(options?.reconcileState).toLowerCase();
4504
4877
  if (candidate === "confirming_payment" || candidate === "still_pending" || candidate === "confirmed_paid" || candidate === "failed") {
4505
4878
  return candidate;
4506
4879
  }
@@ -4508,7 +4881,7 @@ function resolvePaymentLockStateFromGuardSummary(summaryInput, options) {
4508
4881
  })();
4509
4882
  const isPaymentKind = actionKind === "complete_payment" || actionKind === "payment_required";
4510
4883
  const isPaymentReason = reason === "payment_required" || reason === "payment_evidence_missing" || reason === "payment_receipt_already_used";
4511
- const requestStatus = readString4(options?.requestStatus).toUpperCase();
4884
+ const requestStatus = readString5(options?.requestStatus).toUpperCase();
4512
4885
  const paymentSettled = isSettledPaymentStatus(options?.paymentStatus);
4513
4886
  const isHeldForPayment = requestStatus === "PAYMENT_PENDING";
4514
4887
  const isResolvedPastHold = paymentSettled && requestStatus !== "" && !isHeldForPayment;
@@ -5992,7 +6365,7 @@ function asRecord6(value) {
5992
6365
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
5993
6366
  return value;
5994
6367
  }
5995
- function readString5(value) {
6368
+ function readString6(value) {
5996
6369
  return typeof value === "string" ? value.trim() : "";
5997
6370
  }
5998
6371
  function readBoolean2(value, fallback) {
@@ -6067,7 +6440,7 @@ function stripMonetizationCheckoutReturnParams(search) {
6067
6440
  return rendered ? `?${rendered}` : "";
6068
6441
  }
6069
6442
  function formatDateTime2(value, locale) {
6070
- const raw = readString5(value);
6443
+ const raw = readString6(value);
6071
6444
  if (!raw) return "";
6072
6445
  const parsed = new Date(raw);
6073
6446
  if (Number.isNaN(parsed.getTime())) return raw;
@@ -6097,7 +6470,7 @@ function normalizeUsageCreditSummary(value) {
6097
6470
  const byTool = byToolRaw.map((entry) => {
6098
6471
  const record = asRecord6(entry);
6099
6472
  if (!record) return null;
6100
- const toolName = readString5(record.tool_name);
6473
+ const toolName = readString6(record.tool_name);
6101
6474
  if (!toolName) return null;
6102
6475
  return {
6103
6476
  tool_name: toolName,
@@ -6123,14 +6496,14 @@ function normalizeUsageCreditSummary(value) {
6123
6496
  reserved_active_count: reservedActiveCount,
6124
6497
  reserved_stale_count: reservedStaleCount,
6125
6498
  consumed_count: consumedCount,
6126
- updated_at: readString5(summary.updated_at) || null,
6499
+ updated_at: readString6(summary.updated_at) || null,
6127
6500
  by_tool: byTool
6128
6501
  };
6129
6502
  }
6130
6503
  function normalizeGuardPolicyKind(policy) {
6131
6504
  if (policy === "all" || policy === "any") return policy;
6132
6505
  const policyObj = asRecord6(policy);
6133
- const mode = readString5(policyObj?.mode);
6506
+ const mode = readString6(policyObj?.mode);
6134
6507
  return mode === "any" ? "any" : "all";
6135
6508
  }
6136
6509
  function defaultBlockingForTrigger(trigger) {
@@ -6149,7 +6522,7 @@ function buildMonetizationHookSummaryItems(manifest) {
6149
6522
  return [];
6150
6523
  }
6151
6524
  const baseItems = [];
6152
- const defaultInvoiceRef = readString5(
6525
+ const defaultInvoiceRef = readString6(
6153
6526
  afterPaymentCompleted.invoice_ref ?? afterPaymentCompleted.invoiceRef
6154
6527
  );
6155
6528
  baseItems.push({
@@ -6167,7 +6540,7 @@ function buildMonetizationHookSummaryItems(manifest) {
6167
6540
  for (const [paymentGuardRef, rawValue] of Object.entries(byPaymentGuardRef ?? {})) {
6168
6541
  const config = asRecord6(rawValue);
6169
6542
  if (!config || readBoolean2(config.enabled, true) === false) continue;
6170
- const invoiceRef = readString5(config.invoice_ref ?? config.invoiceRef);
6543
+ const invoiceRef = readString6(config.invoice_ref ?? config.invoiceRef);
6171
6544
  baseItems.push({
6172
6545
  slug: `xms_after_payment_completed_${paymentGuardRef}`,
6173
6546
  label: invoiceRef ? `XMS payment completed \xB7 ${paymentGuardRef} \xB7 ${invoiceRef}` : `XMS payment completed \xB7 ${paymentGuardRef}`,
@@ -6258,9 +6631,17 @@ function XappDetailPageContent(props) {
6258
6631
  const [checkoutBusyPackageSlug, setCheckoutBusyPackageSlug] = useState8("");
6259
6632
  const [checkoutError, setCheckoutError] = useState8(null);
6260
6633
  const [checkoutNotice, setCheckoutNotice] = useState8(null);
6634
+ const [subscriptionActionBusy, setSubscriptionActionBusy] = useState8(
6635
+ ""
6636
+ );
6637
+ const [subscriptionActionError, setSubscriptionActionError] = useState8(null);
6638
+ const [cancelSubscriptionConfirmOpen, setCancelSubscriptionConfirmOpen] = useState8(false);
6261
6639
  const checkoutFinalizeKeyRef = useRef2("");
6262
6640
  const installationsByXappId = hasSubject ? host.getInstallationsByXappId() : {};
6263
6641
  const routeInstallationId = String(routeQuery.get("installationId") || "").trim();
6642
+ const routePreviewAt = String(
6643
+ routeQuery.get("previewAt") || routeQuery.get("preview_at") || ""
6644
+ ).trim();
6264
6645
  const installation = xappId && installationsByXappId[String(xappId)] ? installationsByXappId[String(xappId)] : xappId && routeInstallationId ? {
6265
6646
  installationId: routeInstallationId,
6266
6647
  xappId: String(xappId)
@@ -6271,6 +6652,7 @@ function XappDetailPageContent(props) {
6271
6652
  const widgetsEnabled = Boolean(hasSubject) && (Boolean(installation) || autoAvailableMode) && (!updateAvailable || autoUpdateMode);
6272
6653
  const isEmbedded = window.location.pathname.startsWith("/embed");
6273
6654
  const singleXappMode = env?.singleXappMode;
6655
+ const lifecyclePreviewEnabled = env?.devMode === true;
6274
6656
  const routeSurfaceView = routeView === "history" ? "history" : "plans";
6275
6657
  const refresh = useCallback2(async () => {
6276
6658
  if (!xappId) return;
@@ -6282,7 +6664,7 @@ function XappDetailPageContent(props) {
6282
6664
  });
6283
6665
  setData(asRecord6(res));
6284
6666
  } catch (e) {
6285
- setError(readString5(asRecord6(e)?.message) || String(e));
6667
+ setError(readString6(asRecord6(e)?.message) || String(e));
6286
6668
  } finally {
6287
6669
  setBusy(false);
6288
6670
  }
@@ -6296,13 +6678,22 @@ function XappDetailPageContent(props) {
6296
6678
  try {
6297
6679
  const next = await client.getMyXappMonetization(currentXappId, {
6298
6680
  installationId: installation?.installationId ?? null,
6299
- locale
6681
+ locale,
6682
+ previewAt: lifecyclePreviewEnabled ? routePreviewAt || null : null
6300
6683
  });
6301
6684
  setMonetization(next);
6302
6685
  } catch {
6303
6686
  setMonetization(null);
6304
6687
  }
6305
- }, [client, host.subjectId, installation?.installationId, locale, xappId]);
6688
+ }, [
6689
+ client,
6690
+ host.subjectId,
6691
+ installation?.installationId,
6692
+ lifecyclePreviewEnabled,
6693
+ locale,
6694
+ routePreviewAt,
6695
+ xappId
6696
+ ]);
6306
6697
  const refreshMonetizationHistory = useCallback2(async () => {
6307
6698
  const currentXappId = String(xappId ?? "").trim();
6308
6699
  if (!currentXappId || !host.subjectId || typeof client.getMyXappMonetizationHistory !== "function") {
@@ -6373,18 +6764,18 @@ function XappDetailPageContent(props) {
6373
6764
  const xappRecord = asRecord6(data?.xapp);
6374
6765
  const versionRecord = asRecord6(data?.version);
6375
6766
  const publisherRecord = asRecord6(xappRecord?.publisher);
6376
- const title = resolveMarketplaceText(manifest?.title, locale) || readString5(xappRecord?.name) || t("xapp.kicker_default", void 0, "Xapp");
6377
- const description = resolveMarketplaceText(manifest?.description, locale) || readString5(xappRecord?.description) || "";
6378
- const imageUrl = readString5(manifest?.image) || "https://picsum.photos/seed/xapps-detail/840/360";
6767
+ const title = resolveMarketplaceText(manifest?.title, locale) || readString6(xappRecord?.name) || t("xapp.kicker_default", void 0, "Xapp");
6768
+ const description = resolveMarketplaceText(manifest?.description, locale) || readString6(xappRecord?.description) || "";
6769
+ const imageUrl = readString6(manifest?.image) || "https://picsum.photos/seed/xapps-detail/840/360";
6379
6770
  const widgets = Array.isArray(data?.widgets) ? data.widgets.filter((widget) => Boolean(asRecord6(widget))) : [];
6380
6771
  const defaultWidget = useMemo9(() => {
6381
6772
  const def = widgets.find((w) => readBoolean2(w.default, false));
6382
6773
  return def || widgets[0] || null;
6383
6774
  }, [widgets]);
6384
6775
  const requestedWidget = useMemo9(() => {
6385
- const desiredToolName = readString5(queryToolName);
6776
+ const desiredToolName = readString6(queryToolName);
6386
6777
  if (!desiredToolName) return defaultWidget;
6387
- return widgets.find((widget) => readString5(widget.bind_tool_name) === desiredToolName) || defaultWidget;
6778
+ return widgets.find((widget) => readString6(widget.bind_tool_name) === desiredToolName) || defaultWidget;
6388
6779
  }, [defaultWidget, queryToolName, widgets]);
6389
6780
  const backTo = {
6390
6781
  pathname: isEmbedded ? "/embed/catalog" : "..",
@@ -6406,8 +6797,8 @@ function XappDetailPageContent(props) {
6406
6797
  };
6407
6798
  const terms = asRecord6(manifest?.terms);
6408
6799
  const termsTitle = resolveMarketplaceText(terms?.title, locale) || t("xapp.terms_title", void 0, "Terms & Conditions");
6409
- const termsText = resolveMarketplaceText(terms?.text, locale) || readString5(terms?.text);
6410
- const termsUrl = readString5(terms?.url);
6800
+ const termsText = resolveMarketplaceText(terms?.text, locale) || readString6(terms?.text);
6801
+ const termsUrl = readString6(terms?.url);
6411
6802
  const hasTermsContent = Boolean(termsText || termsUrl);
6412
6803
  const requiresTerms = Boolean(terms || action === "install" || action === "update");
6413
6804
  function requestInstallForWidget(widgetId, widgetName = null, acceptedTerms = false, openAfterInstall = false) {
@@ -6423,13 +6814,13 @@ function XappDetailPageContent(props) {
6423
6814
  }
6424
6815
  function requestUpdateForWidget(widgetId, acceptedTerms = false) {
6425
6816
  if (!installation?.installationId || !host.requestUpdate) return;
6426
- const activeWidget = widgetId && Array.isArray(widgets) ? widgets.find((entry) => readString5(entry.id) === widgetId) || null : null;
6817
+ const activeWidget = widgetId && Array.isArray(widgets) ? widgets.find((entry) => readString6(entry.id) === widgetId) || null : null;
6427
6818
  host.requestUpdate({
6428
6819
  installationId: installation.installationId,
6429
6820
  xappId: String(xappId ?? ""),
6430
6821
  widgetId,
6431
6822
  xappTitle: String(title),
6432
- widgetName: resolveMarketplaceText(activeWidget?.title, locale) || readString5(activeWidget?.name) || null,
6823
+ widgetName: resolveMarketplaceText(activeWidget?.title, locale) || readString6(activeWidget?.name) || null,
6433
6824
  ...acceptedTerms ? { termsAccepted: true } : {}
6434
6825
  });
6435
6826
  }
@@ -6485,7 +6876,7 @@ function XappDetailPageContent(props) {
6485
6876
  if (action === "install") {
6486
6877
  setTermsAccepted(false);
6487
6878
  setTermsAction("install");
6488
- setTermsWidgetId(readString5(defaultWidget?.id) || null);
6879
+ setTermsWidgetId(readString6(defaultWidget?.id) || null);
6489
6880
  setTermsWidgetName(resolveMarketplaceText(defaultWidget?.title, locale) || null);
6490
6881
  setTermsOpen(true);
6491
6882
  return;
@@ -6503,20 +6894,20 @@ function XappDetailPageContent(props) {
6503
6894
  if (env?.embedMode) return;
6504
6895
  if (!requestedWidget || !widgetsEnabled) return;
6505
6896
  const widget = requestedWidget;
6506
- const widgetId = readString5(widget?.id);
6897
+ const widgetId = readString6(widget?.id);
6507
6898
  if (!widgetId) return;
6508
6899
  const key = [
6509
6900
  String(xappId ?? ""),
6510
6901
  installation?.installationId || "auto",
6511
6902
  widgetId,
6512
- readString5(queryToolName)
6903
+ readString6(queryToolName)
6513
6904
  ].join(":");
6514
6905
  if (autoOpenedWidgetKeyRef.current === key) return;
6515
6906
  autoOpenedWidgetKeyRef.current = key;
6516
6907
  launchWidgetForSubject(
6517
6908
  widgetId,
6518
- resolveMarketplaceText(widget?.title, locale) || readString5(widget?.widget_name) || readString5(widget?.name) || t("common.widget", void 0, "Widget"),
6519
- readString5(widget?.bind_tool_name)
6909
+ resolveMarketplaceText(widget?.title, locale) || readString6(widget?.widget_name) || readString6(widget?.name) || t("common.widget", void 0, "Widget"),
6910
+ readString6(widget?.bind_tool_name)
6520
6911
  );
6521
6912
  }, [
6522
6913
  action,
@@ -6562,8 +6953,8 @@ function XappDetailPageContent(props) {
6562
6953
  }
6563
6954
  return t("activity.requests_title", void 0, "Requests");
6564
6955
  }
6565
- const publisherSlug = readString5(publisherRecord?.slug);
6566
- const publisherName = readString5(publisherRecord?.name) || publisherSlug;
6956
+ const publisherSlug = readString6(publisherRecord?.slug);
6957
+ const publisherName = readString6(publisherRecord?.name) || publisherSlug;
6567
6958
  const publisherTo = publisherSlug ? {
6568
6959
  pathname: isEmbedded ? `/publishers/${encodeURIComponent(publisherSlug)}` : `/marketplace/publishers/${encodeURIComponent(publisherSlug)}`,
6569
6960
  search: tokenSearch
@@ -6574,8 +6965,8 @@ function XappDetailPageContent(props) {
6574
6965
  const guardItems = guardsRaw.map((raw) => {
6575
6966
  const guard = asRecord6(raw);
6576
6967
  if (!guard) return null;
6577
- const trigger = readString5(guard.trigger);
6578
- const slug = readString5(guard.slug);
6968
+ const trigger = readString6(guard.trigger);
6969
+ const slug = readString6(guard.slug);
6579
6970
  if (!trigger || !slug) return null;
6580
6971
  const policyKind = normalizeGuardPolicyKind(policyMap[trigger]);
6581
6972
  return {
@@ -6615,7 +7006,7 @@ function XappDetailPageContent(props) {
6615
7006
  );
6616
7007
  const selectedPaywall = useMemo9(
6617
7008
  () => monetizationPaywalls.find(
6618
- (item) => readString5(asRecord6(item)?.slug).trim().toLowerCase() === requestedPaywallSlug
7009
+ (item) => readString6(asRecord6(item)?.slug).trim().toLowerCase() === requestedPaywallSlug
6619
7010
  ) || selectXappMonetizationPaywall({
6620
7011
  paywalls: monetizationPaywalls,
6621
7012
  placement: "default_paywall"
@@ -6693,7 +7084,8 @@ function XappDetailPageContent(props) {
6693
7084
  if (typeof client.getMyXappMonetization === "function") {
6694
7085
  const next = await client.getMyXappMonetization(currentXappId, {
6695
7086
  installationId: installation?.installationId ?? null,
6696
- locale
7087
+ locale,
7088
+ previewAt: lifecyclePreviewEnabled ? routePreviewAt || null : null
6697
7089
  });
6698
7090
  if (!cancelled) setMonetization(next);
6699
7091
  }
@@ -6705,7 +7097,7 @@ function XappDetailPageContent(props) {
6705
7097
  }
6706
7098
  } catch (error2) {
6707
7099
  if (cancelled) return;
6708
- const message = readString5(asRecord6(error2)?.message) || (error2 instanceof Error ? error2.message : "") || t(
7100
+ const message = readString6(asRecord6(error2)?.message) || (error2 instanceof Error ? error2.message : "") || t(
6709
7101
  "xapp.checkout_finalize_failed",
6710
7102
  void 0,
6711
7103
  "Payment returned, but access refresh did not complete yet."
@@ -6727,9 +7119,56 @@ function XappDetailPageContent(props) {
6727
7119
  paymentReturnIntentId,
6728
7120
  paymentReturnSessionId,
6729
7121
  paymentReturnStatus,
7122
+ lifecyclePreviewEnabled,
7123
+ routePreviewAt,
6730
7124
  t,
6731
7125
  xappId
6732
7126
  ]);
7127
+ async function refreshSubscriptionLifecycle() {
7128
+ const currentXappId = String(xappId ?? "").trim();
7129
+ const contractId = readString6(monetizationSubscription?.id);
7130
+ if (!currentXappId || !contractId || typeof client.refreshMyXappSubscriptionContractState !== "function") {
7131
+ return;
7132
+ }
7133
+ setSubscriptionActionBusy("refresh");
7134
+ setSubscriptionActionError(null);
7135
+ try {
7136
+ await client.refreshMyXappSubscriptionContractState({
7137
+ xappId: currentXappId,
7138
+ contractId
7139
+ });
7140
+ await refreshMonetization();
7141
+ await refreshMonetizationHistory();
7142
+ } catch (error2) {
7143
+ const message = readString6(asRecord6(error2)?.message) || (error2 instanceof Error ? error2.message : "") || t("xapp.subscription_refresh_failed", void 0, "Unable to refresh subscription state.");
7144
+ setSubscriptionActionError(message);
7145
+ } finally {
7146
+ setSubscriptionActionBusy("");
7147
+ }
7148
+ }
7149
+ async function cancelSubscriptionLifecycle() {
7150
+ const currentXappId = String(xappId ?? "").trim();
7151
+ const contractId = readString6(monetizationSubscription?.id);
7152
+ if (!currentXappId || !contractId || typeof client.cancelMyXappSubscriptionContract !== "function") {
7153
+ return;
7154
+ }
7155
+ setSubscriptionActionBusy("cancel");
7156
+ setSubscriptionActionError(null);
7157
+ try {
7158
+ await client.cancelMyXappSubscriptionContract({
7159
+ xappId: currentXappId,
7160
+ contractId
7161
+ });
7162
+ await refreshMonetization();
7163
+ await refreshMonetizationHistory();
7164
+ setCancelSubscriptionConfirmOpen(false);
7165
+ } catch (error2) {
7166
+ const message = readString6(asRecord6(error2)?.message) || (error2 instanceof Error ? error2.message : "") || t("xapp.subscription_cancel_failed", void 0, "Unable to cancel this subscription.");
7167
+ setSubscriptionActionError(message);
7168
+ } finally {
7169
+ setSubscriptionActionBusy("");
7170
+ }
7171
+ }
6733
7172
  async function finalizeCurrentUserCheckoutIntent(currentXappId, intentId) {
6734
7173
  if (typeof client.finalizeMyXappPurchasePaymentSession !== "function") {
6735
7174
  throw new Error(
@@ -6751,7 +7190,8 @@ function XappDetailPageContent(props) {
6751
7190
  if (typeof client.getMyXappMonetization === "function") {
6752
7191
  const next = await client.getMyXappMonetization(currentXappId, {
6753
7192
  installationId: installation?.installationId ?? null,
6754
- locale
7193
+ locale,
7194
+ previewAt: lifecyclePreviewEnabled ? routePreviewAt || null : null
6755
7195
  });
6756
7196
  setMonetization(next);
6757
7197
  }
@@ -6775,7 +7215,7 @@ function XappDetailPageContent(props) {
6775
7215
  return;
6776
7216
  }
6777
7217
  const pkg = selectedPaywallPackageRecords.find(
6778
- (item) => readString5(item.packageSlug).trim().toLowerCase() === normalizedSlug
7218
+ (item) => readString6(item.packageSlug).trim().toLowerCase() === normalizedSlug
6779
7219
  );
6780
7220
  if (pkg) {
6781
7221
  const purchasePolicy = getPackagePurchasePolicy(pkg);
@@ -6794,9 +7234,9 @@ function XappDetailPageContent(props) {
6794
7234
  return;
6795
7235
  }
6796
7236
  }
6797
- const offeringId = readString5(pkg?.offeringId);
6798
- const packageId = readString5(pkg?.packageId);
6799
- const priceId = readString5(pkg?.priceId);
7237
+ const offeringId = readString6(pkg?.offeringId);
7238
+ const packageId = readString6(pkg?.packageId);
7239
+ const priceId = readString6(pkg?.priceId);
6800
7240
  if (!offeringId || !packageId || !priceId) {
6801
7241
  setCheckoutError(
6802
7242
  t(
@@ -6836,10 +7276,10 @@ function XappDetailPageContent(props) {
6836
7276
  locale
6837
7277
  });
6838
7278
  const paymentPageUrl = normalizeHostedCheckoutUrl({
6839
- paymentPageUrl: readString5(payment.payment_page_url),
7279
+ paymentPageUrl: readString6(payment.payment_page_url),
6840
7280
  apiBaseUrl: env?.apiBaseUrl || null
6841
7281
  });
6842
- const paymentStatus = readString5(payment.payment_session?.status).trim().toLowerCase();
7282
+ const paymentStatus = readString6(payment.payment_session?.status).trim().toLowerCase();
6843
7283
  if (!paymentPageUrl && (paymentStatus === "paid" || paymentStatus === "completed")) {
6844
7284
  await finalizeCurrentUserCheckoutIntent(
6845
7285
  String(xappId),
@@ -6858,7 +7298,7 @@ function XappDetailPageContent(props) {
6858
7298
  }
6859
7299
  navigateToHostedCheckout(paymentPageUrl);
6860
7300
  } catch (error2) {
6861
- const message = readString5(asRecord6(error2)?.message) || (error2 instanceof Error ? error2.message : "") || t("xapp.checkout_start_failed", void 0, "Unable to start checkout for this package.");
7301
+ const message = readString6(asRecord6(error2)?.message) || (error2 instanceof Error ? error2.message : "") || t("xapp.checkout_start_failed", void 0, "Unable to start checkout for this package.");
6862
7302
  setCheckoutError(message);
6863
7303
  } finally {
6864
7304
  setCheckoutBusyPackageSlug("");
@@ -6869,44 +7309,50 @@ function XappDetailPageContent(props) {
6869
7309
  const monetizationSubscription = asRecord6(monetization?.current_subscription);
6870
7310
  const additiveEntitlements = Array.isArray(monetization?.additive_entitlements) ? monetization.additive_entitlements.map((item) => asRecord6(item)).filter((item) => item ? Object.keys(item).length > 0 : false) : [];
6871
7311
  const activeAdditiveEntitlements = additiveEntitlements.filter((item) => {
6872
- const status = readString5(item.status).trim().toLowerCase();
7312
+ const status = readString6(item.status).trim().toLowerCase();
6873
7313
  return status === "active" || status === "grace_period";
6874
7314
  });
6875
- const additiveUnlockLabels = activeAdditiveEntitlements.map((item) => readString5(item.tier) || readString5(item.product_slug)).filter(Boolean);
6876
- const overduePolicy = asRecord6(monetizationSubscription?.overdue_policy);
6877
- const currentTier = readString5(monetizationSubscription?.tier) || readString5(monetizationAccess?.tier);
6878
- const balanceState = readString5(monetizationAccess?.balance_state);
6879
- const subscriptionStatus = readString5(monetizationSubscription?.status);
6880
- const subscriptionCoverage = typeof overduePolicy?.has_current_access === "boolean" ? overduePolicy.has_current_access ? t("xapp.subscription_coverage_active", void 0, "Still covered") : t("xapp.subscription_coverage_inactive", void 0, "Not covered") : null;
6881
- const subscriptionReasonKey = readString5(overduePolicy?.effective_status_reason);
6882
- const subscriptionReason = subscriptionReasonKey === "grace_covered_past_due" ? t(
6883
- "xapp.subscription_reason_grace_covered_past_due",
6884
- void 0,
6885
- "Coverage remains during grace period"
6886
- ) : subscriptionReasonKey === "past_due_after_period_end" ? t(
6887
- "xapp.subscription_reason_past_due_after_period_end",
6888
- void 0,
6889
- "Current period ended without successful renewal"
6890
- ) : subscriptionReasonKey === "expired_after_boundary" ? t(
6891
- "xapp.subscription_reason_expired_after_boundary",
6892
- void 0,
6893
- "Expiry boundary reached"
6894
- ) : null;
6895
- const overdueSince = formatDateTime2(overduePolicy?.overdue_since, locale);
6896
- const expiryBoundaryAt = formatDateTime2(overduePolicy?.expiry_boundary_at, locale);
6897
- const renewsAt = formatDateTime2(monetizationSubscription?.renews_at, locale);
6898
- const expiresAt = formatDateTime2(monetizationSubscription?.expired_at, locale) || formatDateTime2(monetizationSubscription?.current_period_ends_at, locale);
6899
- const creditsRemaining = readString5(monetizationAccess?.credits_remaining);
7315
+ const additiveUnlockLabels = activeAdditiveEntitlements.map((item) => readString6(item.tier) || readString6(item.product_slug)).filter(Boolean).reduce((labels, label) => {
7316
+ if (!labels.includes(label)) labels.push(label);
7317
+ return labels;
7318
+ }, []);
7319
+ const subscriptionLifecycle = buildXmsSubscriptionLifecycleSummary({
7320
+ currentSubscription: monetizationSubscription,
7321
+ locale
7322
+ });
7323
+ const subscriptionManagement = asRecord6(monetizationSubscription?.subscription_management);
7324
+ const subscriptionSubjectActions = asRecord6(subscriptionManagement?.subject_actions);
7325
+ const canRefreshSubscriptionAction = readBoolean2(
7326
+ asRecord6(subscriptionSubjectActions?.refresh_status)?.available,
7327
+ true
7328
+ );
7329
+ const canCancelSubscriptionAction = readBoolean2(
7330
+ asRecord6(subscriptionSubjectActions?.cancel_subscription)?.available,
7331
+ true
7332
+ );
7333
+ const currentTier = readString6(monetizationSubscription?.tier) || readString6(monetizationAccess?.tier);
7334
+ const balanceState = readString6(monetizationAccess?.balance_state);
7335
+ const subscriptionStatus = subscriptionLifecycle.statusLabel;
7336
+ const subscriptionCoverage = subscriptionLifecycle.coverageLabel;
7337
+ const subscriptionReason = subscriptionLifecycle.reasonLabel;
7338
+ const overdueSince = formatDateTime2(subscriptionLifecycle.overdueSince, locale);
7339
+ const expiryBoundaryAt = formatDateTime2(subscriptionLifecycle.expiryBoundaryAt, locale);
7340
+ const renewsAt = formatDateTime2(subscriptionLifecycle.renewsAt, locale);
7341
+ const currentPeriodEndsAt = formatDateTime2(subscriptionLifecycle.currentPeriodEndsAt, locale);
7342
+ const cancelledAt = formatDateTime2(subscriptionLifecycle.cancelledAt, locale);
7343
+ const expiresAt = formatDateTime2(subscriptionLifecycle.expiresAt, locale);
7344
+ const lifecyclePreviewAt = lifecyclePreviewEnabled ? formatDateTime2(routePreviewAt, locale) : "";
7345
+ const creditsRemaining = readString6(monetizationAccess?.credits_remaining);
6900
7346
  const accessState = resolveMarketplaceDefaultAccessState({
6901
7347
  projection: monetizationAccessProjection,
6902
7348
  hasCatalogMonetization,
6903
7349
  availableLabel: t("xapp.access_state_available", void 0, "available")
6904
7350
  });
6905
7351
  const hasMonetizationState = Boolean(
6906
- currentTier || accessState || subscriptionStatus || subscriptionCoverage || subscriptionReason || overdueSince || expiryBoundaryAt || renewsAt || expiresAt || creditsRemaining || additiveUnlockLabels.length > 0
7352
+ currentTier || accessState || subscriptionStatus || subscriptionCoverage || subscriptionReason || overdueSince || expiryBoundaryAt || renewsAt || currentPeriodEndsAt || cancelledAt || expiresAt || lifecyclePreviewAt || creditsRemaining || additiveUnlockLabels.length > 0
6907
7353
  );
6908
- const manifestScreenshots = Array.isArray(manifest?.screenshots) ? manifest.screenshots.map((shot) => readString5(shot)).filter(Boolean) : [];
6909
- const manifestTags = Array.isArray(manifest?.tags) ? manifest.tags.map((tag) => readString5(tag)).filter(Boolean) : [];
7354
+ const manifestScreenshots = Array.isArray(manifest?.screenshots) ? manifest.screenshots.map((shot) => readString6(shot)).filter(Boolean) : [];
7355
+ const manifestTags = Array.isArray(manifest?.tags) ? manifest.tags.map((tag) => readString6(tag)).filter(Boolean) : [];
6910
7356
  function getPackagePurchasePolicy(item) {
6911
7357
  return resolveMonetizationPackagePurchasePolicy({
6912
7358
  item,
@@ -6949,17 +7395,58 @@ function XappDetailPageContent(props) {
6949
7395
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.renews_at_label", void 0, "Renews at") }),
6950
7396
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: renewsAt })
6951
7397
  ] }) : null,
7398
+ currentPeriodEndsAt ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
7399
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.current_period_ends_label", void 0, "Current period ends") }),
7400
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: currentPeriodEndsAt })
7401
+ ] }) : null,
7402
+ cancelledAt ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
7403
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.cancelled_at_label", void 0, "Cancelled at") }),
7404
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: cancelledAt })
7405
+ ] }) : null,
6952
7406
  expiresAt ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
6953
7407
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.expires_at_label", void 0, "Expires at") }),
6954
7408
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: expiresAt })
6955
7409
  ] }) : null,
7410
+ lifecyclePreviewAt ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
7411
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.lifecycle_preview_at_label", void 0, "Preview as of") }),
7412
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: lifecyclePreviewAt })
7413
+ ] }) : null,
6956
7414
  creditsRemaining ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
6957
7415
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.credits_remaining_label", void 0, "Credits remaining") }),
6958
7416
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: creditsRemaining })
6959
7417
  ] }) : null,
6960
7418
  additiveUnlockLabels.length > 0 ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item mx-meta-item-top", children: [
6961
7419
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.add_on_unlocks_label", void 0, "Add-on unlocks") }),
6962
- /* @__PURE__ */ jsx15("div", { className: "mx-meta-value mx-meta-stack-sm", children: additiveUnlockLabels.map((label) => /* @__PURE__ */ jsx15("div", { children: label }, label)) })
7420
+ /* @__PURE__ */ jsx15("div", { className: "mx-meta-value mx-meta-stack-sm", children: additiveUnlockLabels.map((label, index) => /* @__PURE__ */ jsx15("div", { children: label }, `${label}:${index}`)) })
7421
+ ] }) : null,
7422
+ lifecyclePreviewAt ? /* @__PURE__ */ jsx15("div", { className: "mx-subtle-note", children: t(
7423
+ "xapp.lifecycle_preview_hint",
7424
+ void 0,
7425
+ "Subscription lifecycle is being previewed for the selected time."
7426
+ ) }) : null,
7427
+ subscriptionActionError ? /* @__PURE__ */ jsx15("div", { className: "mx-subtle-note", children: subscriptionActionError }) : null,
7428
+ monetizationSubscription?.id && (canRefreshSubscriptionAction && typeof client.refreshMyXappSubscriptionContractState === "function" || canCancelSubscriptionAction && subscriptionLifecycle.canCancel && typeof client.cancelMyXappSubscriptionContract === "function") ? /* @__PURE__ */ jsxs11("div", { className: "mx-detail-actions", children: [
7429
+ canRefreshSubscriptionAction && typeof client.refreshMyXappSubscriptionContractState === "function" ? /* @__PURE__ */ jsx15(
7430
+ "button",
7431
+ {
7432
+ className: "mx-btn mx-btn-secondary",
7433
+ disabled: subscriptionActionBusy !== "",
7434
+ onClick: () => {
7435
+ void refreshSubscriptionLifecycle();
7436
+ },
7437
+ children: subscriptionActionBusy === "refresh" ? t("xapp.subscription_refreshing", void 0, "Refreshing...") : t("xapp.subscription_refresh_action", void 0, "Refresh status")
7438
+ }
7439
+ ) : null,
7440
+ canCancelSubscriptionAction && subscriptionLifecycle.canCancel && typeof client.cancelMyXappSubscriptionContract === "function" ? /* @__PURE__ */ jsx15(
7441
+ "button",
7442
+ {
7443
+ className: "mx-btn mx-btn-outline",
7444
+ "data-variant": "danger",
7445
+ disabled: subscriptionActionBusy !== "",
7446
+ onClick: () => setCancelSubscriptionConfirmOpen(true),
7447
+ children: subscriptionActionBusy === "cancel" ? t("xapp.subscription_cancelling", void 0, "Cancelling...") : t("xapp.subscription_cancel_action", void 0, "Cancel subscription")
7448
+ }
7449
+ ) : null
6963
7450
  ] }) : null
6964
7451
  ] }) : null;
6965
7452
  const plansCard = selectedPaywallRenderModel ? /* @__PURE__ */ jsxs11("div", { className: "mx-sidebar-card", ref: plansSectionRef, children: [
@@ -6969,55 +7456,57 @@ function XappDetailPageContent(props) {
6969
7456
  selectedPaywallRenderModel.summary ? /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-summary", children: selectedPaywallRenderModel.summary }) : null
6970
7457
  ] }),
6971
7458
  selectedPaywallRenderModel.badges.length > 0 ? /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-badges", children: selectedPaywallRenderModel.badges.map((badge) => /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-badge", children: badge }, badge)) }) : null,
6972
- /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-packages", children: selectedPaywallRenderModel.packages.map((item) => {
6973
- const normalizedPackageSlug = item.packageSlug.trim().toLowerCase();
6974
- const purchasePolicy = getPackagePurchasePolicy(item);
6975
- const packageSignals = item.signals.filter(
6976
- (signal) => !(purchasePolicy.transitionKind === "replace_recurring" && signal.toLowerCase().includes("trial"))
6977
- );
6978
- const isCurrentPackage = purchasePolicy.status === "current_recurring_plan";
6979
- const isOwnedAdditive = purchasePolicy.status === "owned_additive_unlock";
6980
- const isAdditiveCompanion = purchasePolicy.transitionKind === "buy_additive_unlock" && subscriptionStatus === "active";
6981
- return /* @__PURE__ */ jsxs11(
6982
- "div",
6983
- {
6984
- className: `mx-paywall-card-package ${item.isDefault ? "is-default" : ""} ${selectedPaywallPackageSlug && normalizedPackageSlug === selectedPaywallPackageSlug ? "is-selected" : ""}`,
6985
- children: [
6986
- /* @__PURE__ */ jsxs11("div", { className: "mx-paywall-card-package-head", children: [
6987
- /* @__PURE__ */ jsxs11("div", { children: [
6988
- /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-package-title", children: item.packageTitle }),
6989
- item.description ? /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-package-description", children: item.description }) : null
7459
+ /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-packages", children: selectedPaywallRenderModel.packages.map(
7460
+ (item, index) => {
7461
+ const normalizedPackageSlug = item.packageSlug.trim().toLowerCase();
7462
+ const purchasePolicy = getPackagePurchasePolicy(item);
7463
+ const packageSignals = item.signals.filter(
7464
+ (signal) => !(purchasePolicy.transitionKind === "replace_recurring" && signal.toLowerCase().includes("trial"))
7465
+ );
7466
+ const isCurrentPackage = purchasePolicy.status === "current_recurring_plan";
7467
+ const isOwnedAdditive = purchasePolicy.status === "owned_additive_unlock";
7468
+ const isAdditiveCompanion = purchasePolicy.transitionKind === "buy_additive_unlock" && subscriptionStatus === "active";
7469
+ return /* @__PURE__ */ jsxs11(
7470
+ "div",
7471
+ {
7472
+ className: `mx-paywall-card-package ${item.isDefault ? "is-default" : ""} ${selectedPaywallPackageSlug && normalizedPackageSlug === selectedPaywallPackageSlug ? "is-selected" : ""}`,
7473
+ children: [
7474
+ /* @__PURE__ */ jsxs11("div", { className: "mx-paywall-card-package-head", children: [
7475
+ /* @__PURE__ */ jsxs11("div", { children: [
7476
+ /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-package-title", children: item.packageTitle }),
7477
+ item.description ? /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-package-description", children: item.description }) : null
7478
+ ] }),
7479
+ /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-money", children: item.moneyLabel })
6990
7480
  ] }),
6991
- /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-money", children: item.moneyLabel })
6992
- ] }),
6993
- /* @__PURE__ */ jsxs11("div", { className: "mx-paywall-card-package-meta", children: [
6994
- /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-fit", children: item.fitLabel }),
6995
- selectedPaywallPackageSlug && normalizedPackageSlug === selectedPaywallPackageSlug ? /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-default", children: t("xapp.selected_label", void 0, "Selected") }) : null,
6996
- isOwnedAdditive ? /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-default", children: t("xapp.owned_unlock_label", void 0, "Owned unlock") }) : null,
6997
- isCurrentPackage && !isOwnedAdditive ? /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-default", children: t("xapp.current_plan_label", void 0, "Current plan") }) : null,
6998
- isAdditiveCompanion ? /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-default", children: t("xapp.additive_unlock_label", void 0, "Add-on with membership") }) : null,
6999
- item.isDefault ? /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-default", children: t("xapp.default_label", void 0, "Default") }) : null
7000
- ] }),
7001
- packageSignals.length > 0 ? /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-signals", children: packageSignals.map((signal) => /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-signal", children: signal }, signal)) }) : null,
7002
- isAdditiveCompanion ? /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-summary", children: t(
7003
- "xapp.additive_unlock_message",
7004
- void 0,
7005
- "This one-time unlock is additive. It adds access on top of the active recurring membership instead of replacing it."
7006
- ) }) : null,
7007
- typeof client.prepareMyXappPurchaseIntent === "function" && typeof client.createMyXappPurchasePaymentSession === "function" && hasSubject && canMutate ? /* @__PURE__ */ jsx15(
7008
- "button",
7009
- {
7010
- className: "mx-btn mx-btn-secondary",
7011
- disabled: !purchasePolicy.canPurchase || checkoutBusyPackageSlug === normalizedPackageSlug,
7012
- onClick: () => void startPackageCheckout(item.packageSlug),
7013
- children: isOwnedAdditive ? t("xapp.owned_unlock_active", void 0, "Owned unlock active") : isCurrentPackage ? t("xapp.current_plan_active", void 0, "Current plan active") : checkoutBusyPackageSlug === normalizedPackageSlug ? t("xapp.checkout_starting", void 0, "Starting checkout...") : isAdditiveCompanion ? t("xapp.additive_unlock_action", void 0, "Purchase add-on unlock") : t("xapp.checkout_action", void 0, "Continue to checkout")
7014
- }
7015
- ) : null
7016
- ]
7017
- },
7018
- item.packageId || item.packageSlug
7019
- );
7020
- }) }),
7481
+ /* @__PURE__ */ jsxs11("div", { className: "mx-paywall-card-package-meta", children: [
7482
+ /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-fit", children: item.fitLabel }),
7483
+ selectedPaywallPackageSlug && normalizedPackageSlug === selectedPaywallPackageSlug ? /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-default", children: t("xapp.selected_label", void 0, "Selected") }) : null,
7484
+ isOwnedAdditive ? /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-default", children: t("xapp.owned_unlock_label", void 0, "Owned unlock") }) : null,
7485
+ isCurrentPackage && !isOwnedAdditive ? /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-default", children: t("xapp.current_plan_label", void 0, "Current plan") }) : null,
7486
+ isAdditiveCompanion ? /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-default", children: t("xapp.additive_unlock_label", void 0, "Add-on with membership") }) : null,
7487
+ item.isDefault ? /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-package-default", children: t("xapp.default_label", void 0, "Default") }) : null
7488
+ ] }),
7489
+ packageSignals.length > 0 ? /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-signals", children: packageSignals.map((signal) => /* @__PURE__ */ jsx15("span", { className: "mx-paywall-card-signal", children: signal }, signal)) }) : null,
7490
+ isAdditiveCompanion ? /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-summary", children: t(
7491
+ "xapp.additive_unlock_message",
7492
+ void 0,
7493
+ "This one-time unlock is additive. It adds access on top of the active recurring membership instead of replacing it."
7494
+ ) }) : null,
7495
+ typeof client.prepareMyXappPurchaseIntent === "function" && typeof client.createMyXappPurchasePaymentSession === "function" && hasSubject && canMutate ? /* @__PURE__ */ jsx15(
7496
+ "button",
7497
+ {
7498
+ className: "mx-btn mx-btn-secondary",
7499
+ disabled: !purchasePolicy.canPurchase || checkoutBusyPackageSlug === normalizedPackageSlug,
7500
+ onClick: () => void startPackageCheckout(item.packageSlug),
7501
+ children: isOwnedAdditive ? t("xapp.owned_unlock_active", void 0, "Owned unlock active") : isCurrentPackage ? t("xapp.current_plan_active", void 0, "Current plan active") : checkoutBusyPackageSlug === normalizedPackageSlug ? t("xapp.checkout_starting", void 0, "Starting checkout...") : isAdditiveCompanion ? t("xapp.additive_unlock_action", void 0, "Purchase add-on unlock") : t("xapp.checkout_action", void 0, "Continue to checkout")
7502
+ }
7503
+ ) : null
7504
+ ]
7505
+ },
7506
+ `${item.packageId || item.packageSlug || normalizedPackageSlug}:${index}`
7507
+ );
7508
+ }
7509
+ ) }),
7021
7510
  checkoutNotice ? /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-summary", children: checkoutNotice }) : null,
7022
7511
  checkoutError ? /* @__PURE__ */ jsx15("div", { className: "mx-payment-lock-error", children: checkoutError }) : null
7023
7512
  ] }) : null;
@@ -7170,9 +7659,9 @@ function XappDetailPageContent(props) {
7170
7659
  description ? /* @__PURE__ */ jsx15("p", { className: "mx-detail-subtitle", children: description }) : null,
7171
7660
  /* @__PURE__ */ jsxs11("div", { className: "mx-detail-meta-row", children: [
7172
7661
  /* @__PURE__ */ jsx15("div", { className: "mx-card-slug", children: xappId }),
7173
- readString5(versionRecord?.version) && /* @__PURE__ */ jsxs11("div", { className: "mx-card-version mx-detail-version-pill", children: [
7662
+ readString6(versionRecord?.version) && /* @__PURE__ */ jsxs11("div", { className: "mx-card-version mx-detail-version-pill", children: [
7174
7663
  "v",
7175
- readString5(versionRecord?.version)
7664
+ readString6(versionRecord?.version)
7176
7665
  ] }),
7177
7666
  updateAvailable ? /* @__PURE__ */ jsx15("div", { className: "mx-detail-update-pill", children: t("xapp.update_available", void 0, "Update available") }) : null
7178
7667
  ] })
@@ -7207,7 +7696,7 @@ function XappDetailPageContent(props) {
7207
7696
  if (requiresTerms) {
7208
7697
  setTermsAccepted(false);
7209
7698
  setTermsAction("install");
7210
- setTermsWidgetId(readString5(defaultWidget?.id) || null);
7699
+ setTermsWidgetId(readString6(defaultWidget?.id) || null);
7211
7700
  setTermsWidgetName(
7212
7701
  resolveMarketplaceText(defaultWidget?.title, locale) || null
7213
7702
  );
@@ -7215,7 +7704,7 @@ function XappDetailPageContent(props) {
7215
7704
  return;
7216
7705
  }
7217
7706
  requestInstallForWidget(
7218
- readString5(defaultWidget?.id) || null,
7707
+ readString6(defaultWidget?.id) || null,
7219
7708
  resolveMarketplaceText(defaultWidget?.title, locale) || null,
7220
7709
  false,
7221
7710
  autoAvailableMode
@@ -7271,7 +7760,7 @@ function XappDetailPageContent(props) {
7271
7760
  void 0,
7272
7761
  "No app views are currently available."
7273
7762
  ) }) : /* @__PURE__ */ jsx15("div", { className: "mx-detail-widget-list", children: widgets.map((w, idx) => {
7274
- const name = resolveMarketplaceText(w.title, locale) || readString5(w.widget_name) || readString5(w.name) || readString5(w.id) || t("common.widget", void 0, "Widget");
7763
+ const name = resolveMarketplaceText(w.title, locale) || readString6(w.widget_name) || readString6(w.name) || readString6(w.id) || t("common.widget", void 0, "Widget");
7275
7764
  const disabled = !widgetsEnabled;
7276
7765
  const isDefault = readBoolean2(w.default, false) || idx === 0 && !widgets.some((ww) => readBoolean2(ww.default, false));
7277
7766
  const widgetType = String(w.type || "").toLowerCase();
@@ -7282,9 +7771,9 @@ function XappDetailPageContent(props) {
7282
7771
  className: `mx-detail-widget-card ${disabled ? "is-disabled" : ""} ${isDefault ? "is-default" : ""}`,
7283
7772
  onClick: () => {
7284
7773
  if (!widgetsEnabled) return;
7285
- const widgetId = readString5(w.id);
7774
+ const widgetId = readString6(w.id);
7286
7775
  if (!widgetId) return;
7287
- launchWidgetForSubject(widgetId, name, readString5(w.bind_tool_name));
7776
+ launchWidgetForSubject(widgetId, name, readString6(w.bind_tool_name));
7288
7777
  },
7289
7778
  children: [
7290
7779
  /* @__PURE__ */ jsx15("div", { className: "mx-detail-widget-icon", children: widgetType === "read" ? /* @__PURE__ */ jsxs11(
@@ -7319,7 +7808,7 @@ function XappDetailPageContent(props) {
7319
7808
  ) }),
7320
7809
  /* @__PURE__ */ jsxs11("div", { className: "mx-detail-widget-body", children: [
7321
7810
  /* @__PURE__ */ jsx15("div", { className: "mx-detail-widget-name", children: name }),
7322
- readString5(w.bind_tool_name) && /* @__PURE__ */ jsx15("div", { className: "mx-detail-widget-tool", children: readString5(w.bind_tool_name) }),
7811
+ readString6(w.bind_tool_name) && /* @__PURE__ */ jsx15("div", { className: "mx-detail-widget-tool", children: readString6(w.bind_tool_name) }),
7323
7812
  /* @__PURE__ */ jsxs11("div", { className: "mx-detail-widget-badges", children: [
7324
7813
  isDefault && /* @__PURE__ */ jsx15("span", { className: "mx-detail-widget-badge is-primary", children: t("xapp.widget_primary", void 0, "Primary") }),
7325
7814
  widgetType && /* @__PURE__ */ jsx15("span", { className: "mx-detail-widget-badge", children: widgetType })
@@ -7609,12 +8098,12 @@ function XappDetailPageContent(props) {
7609
8098
  {
7610
8099
  className: "mx-btn mx-btn-primary mx-detail-primary-cta",
7611
8100
  onClick: () => {
7612
- const widgetId = readString5(defaultWidget.id);
8101
+ const widgetId = readString6(defaultWidget.id);
7613
8102
  if (!widgetId) return;
7614
8103
  launchWidgetForSubject(
7615
8104
  widgetId,
7616
- resolveMarketplaceText(defaultWidget?.title, locale) || readString5(defaultWidget?.widget_name) || readString5(defaultWidget?.name) || t("common.widget", void 0, "Widget"),
7617
- readString5(defaultWidget?.bind_tool_name)
8105
+ resolveMarketplaceText(defaultWidget?.title, locale) || readString6(defaultWidget?.widget_name) || readString6(defaultWidget?.name) || t("common.widget", void 0, "Widget"),
8106
+ readString6(defaultWidget?.bind_tool_name)
7618
8107
  );
7619
8108
  },
7620
8109
  children: openAppLabel
@@ -7834,7 +8323,7 @@ function XappDetailPageContent(props) {
7834
8323
  disabled: !termsAccepted,
7835
8324
  onClick: () => {
7836
8325
  requestInstallForWidget(
7837
- termsWidgetId ?? readString5(defaultWidget?.id) ?? null,
8326
+ termsWidgetId ?? readString6(defaultWidget?.id) ?? null,
7838
8327
  termsWidgetName || resolveMarketplaceText(defaultWidget?.title, locale) || null,
7839
8328
  true,
7840
8329
  autoAvailableMode
@@ -7864,6 +8353,23 @@ function XappDetailPageContent(props) {
7864
8353
  ) : null
7865
8354
  ] })
7866
8355
  ] }) }),
8356
+ /* @__PURE__ */ jsx15(
8357
+ ConfirmActionModal,
8358
+ {
8359
+ open: cancelSubscriptionConfirmOpen,
8360
+ title: t("xapp.subscription_cancel_title", void 0, "Cancel subscription?"),
8361
+ description: t(
8362
+ "xapp.subscription_cancel_description",
8363
+ void 0,
8364
+ "The subscription will stop renewing. Current access remains available until the current period ends."
8365
+ ),
8366
+ confirmLabel: t("xapp.subscription_cancel_action", void 0, "Cancel subscription"),
8367
+ onCancel: () => setCancelSubscriptionConfirmOpen(false),
8368
+ onConfirm: () => {
8369
+ void cancelSubscriptionLifecycle();
8370
+ }
8371
+ }
8372
+ ),
7867
8373
  /* @__PURE__ */ jsx15(
7868
8374
  ConfirmActionModal,
7869
8375
  {