@xapps-platform/marketplace-ui 0.1.15 → 0.1.17

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
@@ -118,7 +118,7 @@ function buildMarketplaceXmsCatalog(locale) {
118
118
  "xapp.current_plan_active": "Plan activ",
119
119
  "xapp.checkout_starting": "Se porne\u0219te checkout-ul...",
120
120
  "xapp.additive_unlock_action": "Cump\u0103r\u0103 suplimentul",
121
- "xapp.checkout_action": "Continu\u0103 spre checkout",
121
+ "xapp.checkout_action": "\xCEncepe checkout-ul",
122
122
  "xapp.subscription_status_label": "Stare abonament",
123
123
  "xapp.subscription_coverage_label": "Acoperire",
124
124
  "xapp.subscription_reason_label": "Motiv stare",
@@ -126,7 +126,11 @@ function buildMarketplaceXmsCatalog(locale) {
126
126
  "xapp.subscription_expiry_boundary_label": "Limit\u0103 expirare",
127
127
  "xapp.current_period_ends_label": "Perioada curent\u0103 se \xEEncheie la",
128
128
  "xapp.cancelled_at_label": "Anulat la",
129
- "xapp.credits_remaining_label": "Credite r\u0103mase",
129
+ "xapp.virtual_currency_label": "Moned\u0103 virtual\u0103",
130
+ "xapp.current_balances_label": "Solduri acum",
131
+ "xapp.current_credits_label": "Credite acum",
132
+ "xapp.credits_remaining_label": "Sold",
133
+ "xapp.credit_balance_label": "Credite",
130
134
  "xapp.add_on_unlocks_label": "Unlock-uri suplimentare",
131
135
  "xapp.subscription_refresh_action": "Actualizeaz\u0103 starea",
132
136
  "xapp.subscription_refreshing": "Se actualizeaz\u0103...",
@@ -148,7 +152,18 @@ function buildMarketplaceXmsCatalog(locale) {
148
152
  "xapp.subscription_management_hint_owner": "Administrarea avansat\u0103 a abonamentului este gestionat\u0103 de proprietarul aplica\u021Biei.",
149
153
  "xapp.subscription_management_open_action": "Deschide administrarea",
150
154
  "xapp.lifecycle_preview_at_label": "Previzualizare la",
151
- "xapp.lifecycle_preview_hint": "Ciclul de via\u021B\u0103 al abonamentului este previzualizat pentru momentul selectat."
155
+ "xapp.lifecycle_preview_hint": "Starea abonamentului este previzualizat\u0103 pentru momentul selectat.",
156
+ "xapp.history_route_subtitle": "Solduri, activitate recent\u0103 \u0219i cump\u0103r\u0103ri pentru {title}.",
157
+ "xapp.history_route_subtitle_default": "Solduri, activitate recent\u0103 \u0219i cump\u0103r\u0103ri pentru aceast\u0103 aplica\u021Bie.",
158
+ "xapp.plans_route_subtitle": "Acces, planuri \u0219i solduri pentru {title}.",
159
+ "xapp.plans_route_subtitle_default": "Acces, planuri \u0219i solduri pentru aceast\u0103 aplica\u021Bie.",
160
+ "xapp.plans_loading_title": "Se \xEEncarc\u0103 planurile",
161
+ "xapp.plans_loading_desc": "Se preg\u0103tesc planurile publicate, soldurile \u0219i accesul curent pentru aceast\u0103 aplica\u021Bie.",
162
+ "xapp.no_plans_available": "Momentan nu exist\u0103 planuri disponibile.",
163
+ "xapp.no_plans_available_desc": "Planurile publicate vor ap\u0103rea aici atunci c\xE2nd aceast\u0103 aplica\u021Bie expune un paywall.",
164
+ "xapp.checkout_hint": "Checkout-ul se deschide \xEEntr-o pagin\u0103 securizat\u0103 de plat\u0103 administrat\u0103 de platform\u0103.",
165
+ "xapp.current_plan_note": "Acest plan este deja activ pentru aceast\u0103 aplica\u021Bie.",
166
+ "xapp.owned_unlock_note": "Acest supliment este deja inclus \xEEn accesul curent."
152
167
  };
153
168
  }
154
169
  return {
@@ -161,15 +176,19 @@ function buildMarketplaceXmsCatalog(locale) {
161
176
  "xapp.current_plan_active": "Current plan active",
162
177
  "xapp.checkout_starting": "Starting checkout...",
163
178
  "xapp.additive_unlock_action": "Purchase add-on unlock",
164
- "xapp.checkout_action": "Continue to checkout",
165
- "xapp.subscription_status_label": "Subscription status",
179
+ "xapp.checkout_action": "Start checkout",
180
+ "xapp.subscription_status_label": "Subscription state",
166
181
  "xapp.subscription_coverage_label": "Coverage",
167
182
  "xapp.subscription_reason_label": "Status reason",
168
183
  "xapp.subscription_overdue_since_label": "Overdue since",
169
184
  "xapp.subscription_expiry_boundary_label": "Expiry boundary",
170
185
  "xapp.current_period_ends_label": "Current period ends",
171
186
  "xapp.cancelled_at_label": "Cancelled at",
172
- "xapp.credits_remaining_label": "Credits remaining",
187
+ "xapp.virtual_currency_label": "Currency",
188
+ "xapp.current_balances_label": "Balances now",
189
+ "xapp.current_credits_label": "Credits now",
190
+ "xapp.credits_remaining_label": "Balance",
191
+ "xapp.credit_balance_label": "Credits",
173
192
  "xapp.add_on_unlocks_label": "Add-on unlocks",
174
193
  "xapp.subscription_refresh_action": "Refresh status",
175
194
  "xapp.subscription_refreshing": "Refreshing...",
@@ -191,7 +210,18 @@ function buildMarketplaceXmsCatalog(locale) {
191
210
  "xapp.subscription_management_hint_owner": "Advanced subscription management is handled by the app owner.",
192
211
  "xapp.subscription_management_open_action": "Open management",
193
212
  "xapp.lifecycle_preview_at_label": "Preview as of",
194
- "xapp.lifecycle_preview_hint": "Subscription lifecycle is being previewed for the selected time."
213
+ "xapp.lifecycle_preview_hint": "Subscription state is being previewed for the selected time.",
214
+ "xapp.history_route_subtitle": "Balances, recent activity, and purchases for {title}.",
215
+ "xapp.history_route_subtitle_default": "Balances, recent activity, and purchases for this app.",
216
+ "xapp.plans_route_subtitle": "Access, plans, and balances for {title}.",
217
+ "xapp.plans_route_subtitle_default": "Access, plans, and balances for this app.",
218
+ "xapp.plans_loading_title": "Loading plans",
219
+ "xapp.plans_loading_desc": "Preparing published plans, balances, and current access for this app.",
220
+ "xapp.no_plans_available": "No plans are currently available.",
221
+ "xapp.no_plans_available_desc": "Published plans will appear here when this app exposes a paywall.",
222
+ "xapp.checkout_hint": "Checkout opens in a secure hosted payment page managed by the platform.",
223
+ "xapp.current_plan_note": "This plan is already active for this app.",
224
+ "xapp.owned_unlock_note": "This add-on is already included in the current access."
195
225
  };
196
226
  }
197
227
  var MARKETPLACE_CATALOGS = {
@@ -280,7 +310,7 @@ var MARKETPLACE_CATALOGS = {
280
310
  "activity.invoices_title": "Invoices",
281
311
  "activity.notifications_title": "Notifications",
282
312
  "activity.unavailable_requests_title": "Requests are unavailable",
283
- "activity.unavailable_monetization_title": "Monetization is unavailable in this host.",
313
+ "activity.unavailable_monetization_title": "Plans and balances are unavailable in this host.",
284
314
  "activity.unavailable_requests_desc": "This public catalog does not support viewing personal requests.",
285
315
  "activity.unavailable_payments_title": "Payments are unavailable in this host.",
286
316
  "activity.unavailable_invoices_title": "Invoices are unavailable in this host.",
@@ -289,8 +319,8 @@ var MARKETPLACE_CATALOGS = {
289
319
  "activity.subject_required_desc": "This host session is not associated with a user. Ask your host to create a catalog session with a subjectId.",
290
320
  "activity.showing_requests_for": "Showing requests for {title}",
291
321
  "activity.showing_requests_for_prefix": "Showing requests for",
292
- "activity.showing_monetization_for": "Showing XMS state for {title}",
293
- "activity.showing_monetization_for_prefix": "Showing XMS state for",
322
+ "activity.showing_monetization_for": "Showing plans and balances for {title}",
323
+ "activity.showing_monetization_for_prefix": "Showing plans and balances for",
294
324
  "activity.showing_payments_for": "Showing payment activity for {title}",
295
325
  "activity.showing_payments_for_prefix": "Showing payment activity for",
296
326
  "activity.showing_invoices_for": "Showing invoice records for {title}",
@@ -306,11 +336,11 @@ var MARKETPLACE_CATALOGS = {
306
336
  "activity.mark_read": "Mark read",
307
337
  "activity.unread_count": "{count} unread item{suffix}",
308
338
  "activity.loading_requests": "Loading requests...",
309
- "activity.loading_monetization": "Loading monetization state...",
339
+ "activity.loading_monetization": "Loading plans, balances, and recent activity...",
310
340
  "activity.no_requests": "No requests yet.",
311
- "activity.no_monetization": "No XMS-enabled apps are currently installed for this subject.",
312
- "activity.no_monetization_current": "No current monetization coverage was found for this subject.",
313
- "activity.no_monetization_history": "No monetization history was found for this subject.",
341
+ "activity.no_monetization": "No monetized apps are currently installed for this subject.",
342
+ "activity.no_monetization_current": "No current plans or balances were found for this subject.",
343
+ "activity.no_monetization_history": "No plan or balance history was found for this subject.",
314
344
  "activity.loading_payments": "Loading payments...",
315
345
  "activity.no_payments": "No payment activity found.",
316
346
  "activity.loading_payment_detail": "Loading payment details...",
@@ -325,21 +355,30 @@ var MARKETPLACE_CATALOGS = {
325
355
  "activity.loading_notifications": "Loading notifications...",
326
356
  "activity.no_notifications": "No notification activity found.",
327
357
  "activity.loading_notification_detail": "Loading notification details...",
328
- "activity.monetization_overview_hint": "Review current XMS access, subscriptions, and credits across the apps linked to this subject.",
329
- "activity.monetization_overview_hint_with_past": "Review current and past XMS access, subscriptions, and credits across this subject's apps.",
330
- "activity.monetization_card_subtitle": "Current XMS state, active access, subscriptions, and credits for this app.",
331
- "activity.monetization_focus_xapp": "Focus this app",
332
- "activity.monetization_show_past": "Show past apps",
333
- "activity.monetization_show_current_only": "Show current only",
334
- "activity.monetization_open_plans": "Open plans",
335
- "activity.monetization_access_label": "Current access",
336
- "activity.monetization_plan_label": "Current plan",
337
- "activity.monetization_credits_label": "Credits remaining",
358
+ "activity.monetization_overview_hint": "Review current plans, subscriptions, and balances across this subject's apps.",
359
+ "activity.monetization_overview_hint_with_past": "Review current and past plans, subscriptions, and balances across this subject's apps.",
360
+ "activity.monetization_summary_title": "Plans and balances",
361
+ "activity.monetization_summary_subtitle": "Review active plans, subscriptions, and balances before opening app details or history.",
362
+ "activity.monetization_summary_apps": "Apps",
363
+ "activity.monetization_summary_subscriptions": "Subscriptions",
364
+ "activity.monetization_summary_balances": "Balances",
365
+ "activity.monetization_summary_currencies": "Named currencies",
366
+ "activity.monetization_card_subtitle": "Current plans, balances, and subscription state for this app.",
367
+ "activity.monetization_focus_xapp": "Only this app",
368
+ "activity.monetization_show_past": "Include past apps",
369
+ "activity.monetization_show_current_only": "Only current apps",
370
+ "activity.monetization_open_plans": "View plans",
371
+ "activity.monetization_open_history": "View history",
372
+ "activity.monetization_access_label": "Access",
373
+ "activity.monetization_plan_label": "Plan",
374
+ "activity.monetization_credits_label": "Balance",
338
375
  "activity.monetization_subscription_label": "Subscription",
339
- "activity.monetization_coverage_label": "Coverage",
376
+ "activity.monetization_coverage_label": "Renewal state",
340
377
  "activity.monetization_renews_at": "Renews at",
341
- "activity.monetization_balance_state": "Balance state",
342
- "activity.monetization_source_label": "Source",
378
+ "activity.monetization_balance_state": "Balance status",
379
+ "activity.monetization_balances_label": "Balances",
380
+ "activity.monetization_source_label": "Origin",
381
+ "activity.monetization_no_currency": "No named currency",
343
382
  "activity.monetization_unknown": "Unknown",
344
383
  "activity.monetization_none": "None",
345
384
  "activity.monetization_no_source": "No source",
@@ -415,7 +454,9 @@ var MARKETPLACE_CATALOGS = {
415
454
  "xapp.update_available": "Update available",
416
455
  "xapp.about_title": "About",
417
456
  "xapp.available_views_title": "Available Views",
457
+ "xapp.open_to_access_views": "Open this app to start and install it automatically for your workspace.",
418
458
  "xapp.add_to_access_views": "Add this app to your workspace to access its available views.",
459
+ "xapp.update_to_access_views_auto": "Open a view to update the app automatically for your workspace.",
419
460
  "xapp.update_to_access_views": "An update is available. Please update the app to access its available views.",
420
461
  "xapp.load_as_user_to_access": "Load the catalog as a user to access this app.",
421
462
  "xapp.no_views_available": "No app views are currently available.",
@@ -439,10 +480,10 @@ var MARKETPLACE_CATALOGS = {
439
480
  "xapp.screenshots_title": "Screenshots",
440
481
  "xapp.screenshot_alt": "Screenshot {index}",
441
482
  "xapp.usage_credits_title": "Usage Credits",
442
- "xapp.current_access_title": "Current Access",
483
+ "xapp.current_access_title": "Current access",
443
484
  "xapp.access_state_label": "Access state",
444
485
  "xapp.access_state_available": "available",
445
- "xapp.subscription_status_label": "Subscription status",
486
+ "xapp.subscription_status_label": "Subscription state",
446
487
  "xapp.subscription_coverage_label": "Coverage",
447
488
  "xapp.subscription_reason_label": "Status reason",
448
489
  "xapp.subscription_overdue_since_label": "Overdue since",
@@ -465,8 +506,12 @@ var MARKETPLACE_CATALOGS = {
465
506
  "xapp.subscription_cancel_description": "The subscription will stop renewing. Current access remains available until the current period ends.",
466
507
  "xapp.subscription_cancel_failed": "Unable to cancel this subscription.",
467
508
  "xapp.lifecycle_preview_at_label": "Preview as of",
468
- "xapp.lifecycle_preview_hint": "Subscription lifecycle is being previewed for the selected time.",
469
- "xapp.credits_remaining_label": "Credits remaining",
509
+ "xapp.lifecycle_preview_hint": "Subscription state is being previewed for the selected time.",
510
+ "xapp.virtual_currency_label": "Currency",
511
+ "xapp.current_balances_label": "Balances now",
512
+ "xapp.current_credits_label": "Credits now",
513
+ "xapp.credits_remaining_label": "Balance",
514
+ "xapp.credit_balance_label": "Credits",
470
515
  "xapp.available_label": "Available",
471
516
  "xapp.ready_to_use": "{count} ready to use",
472
517
  "xapp.source_label": "Source",
@@ -608,8 +653,8 @@ var MARKETPLACE_CATALOGS = {
608
653
  "activity.subject_required_desc": "Aceast\u0103 sesiune de host nu este asociat\u0103 cu un utilizator. Cere hostului s\u0103 creeze o sesiune de catalog cu un subjectId.",
609
654
  "activity.showing_requests_for": "Se afi\u0219eaz\u0103 cererile pentru {title}",
610
655
  "activity.showing_requests_for_prefix": "Se afi\u0219eaz\u0103 cererile pentru",
611
- "activity.showing_monetization_for": "Se afi\u0219eaz\u0103 starea XMS pentru {title}",
612
- "activity.showing_monetization_for_prefix": "Se afi\u0219eaz\u0103 starea XMS pentru",
656
+ "activity.showing_monetization_for": "Se afi\u0219eaz\u0103 planurile \u0219i soldurile pentru {title}",
657
+ "activity.showing_monetization_for_prefix": "Se afi\u0219eaz\u0103 planurile \u0219i soldurile pentru",
613
658
  "activity.showing_payments_for": "Se afi\u0219eaz\u0103 activitatea pl\u0103\u021Bilor pentru {title}",
614
659
  "activity.showing_payments_for_prefix": "Se afi\u0219eaz\u0103 activitatea pl\u0103\u021Bilor pentru",
615
660
  "activity.showing_invoices_for": "Se afi\u0219eaz\u0103 facturile pentru {title}",
@@ -625,11 +670,11 @@ var MARKETPLACE_CATALOGS = {
625
670
  "activity.mark_read": "Marcheaz\u0103 ca citit",
626
671
  "activity.unread_count": "{count} notific{suffix} necitit{suffix2}",
627
672
  "activity.loading_requests": "Se \xEEncarc\u0103 cererile...",
628
- "activity.loading_monetization": "Se \xEEncarc\u0103 starea monetiz\u0103rii...",
673
+ "activity.loading_monetization": "Se \xEEncarc\u0103 planurile, soldurile \u0219i activitatea recent\u0103...",
629
674
  "activity.no_requests": "Nu exist\u0103 \xEEnc\u0103 cereri.",
630
- "activity.no_monetization": "Nu exist\u0103 \xEEnc\u0103 aplica\u021Bii cu XMS instalate pentru acest subiect.",
631
- "activity.no_monetization_current": "Nu a fost g\u0103sit\u0103 nicio acoperire curent\u0103 de monetizare pentru acest subiect.",
632
- "activity.no_monetization_history": "Nu a fost g\u0103sit niciun istoric de monetizare pentru acest subiect.",
675
+ "activity.no_monetization": "Nu exist\u0103 \xEEnc\u0103 aplica\u021Bii monetizate instalate pentru acest subiect.",
676
+ "activity.no_monetization_current": "Nu au fost g\u0103site planuri sau solduri curente pentru acest subiect.",
677
+ "activity.no_monetization_history": "Nu a fost g\u0103sit niciun istoric de planuri sau solduri pentru acest subiect.",
633
678
  "activity.loading_payments": "Se \xEEncarc\u0103 pl\u0103\u021Bile...",
634
679
  "activity.no_payments": "Nu a fost g\u0103sit\u0103 activitate de plat\u0103.",
635
680
  "activity.loading_payment_detail": "Se \xEEncarc\u0103 detaliile pl\u0103\u021Bii...",
@@ -644,21 +689,30 @@ var MARKETPLACE_CATALOGS = {
644
689
  "activity.loading_notifications": "Se \xEEncarc\u0103 notific\u0103rile...",
645
690
  "activity.no_notifications": "Nu a fost g\u0103sit\u0103 activitate de notificare.",
646
691
  "activity.loading_notification_detail": "Se \xEEncarc\u0103 detaliile notific\u0103rii...",
647
- "activity.monetization_overview_hint": "Revizuie\u0219te accesul XMS curent, abonamentele \u0219i creditele pentru aplica\u021Biile legate de acest subiect.",
648
- "activity.monetization_overview_hint_with_past": "Revizuie\u0219te accesul XMS curent \u0219i trecut, abonamentele \u0219i creditele pentru aplica\u021Biile acestui subiect.",
649
- "activity.monetization_card_subtitle": "Starea XMS curent\u0103, accesul activ, abonamentele \u0219i creditele pentru aceast\u0103 aplica\u021Bie.",
650
- "activity.monetization_focus_xapp": "Focalizeaz\u0103 aplica\u021Bia",
651
- "activity.monetization_show_past": "Arat\u0103 aplica\u021Biile anterioare",
652
- "activity.monetization_show_current_only": "Arat\u0103 doar aplica\u021Biile curente",
653
- "activity.monetization_open_plans": "Deschide planurile",
654
- "activity.monetization_access_label": "Acces curent",
655
- "activity.monetization_plan_label": "Plan curent",
656
- "activity.monetization_credits_label": "Credite r\u0103mase",
692
+ "activity.monetization_overview_hint": "Revizuie\u0219te planurile, abonamentele \u0219i soldurile curente pentru aplica\u021Biile legate de acest subiect.",
693
+ "activity.monetization_overview_hint_with_past": "Revizuie\u0219te planurile, abonamentele \u0219i soldurile curente \u0219i trecute pentru aplica\u021Biile acestui subiect.",
694
+ "activity.monetization_summary_title": "Planuri \u0219i solduri",
695
+ "activity.monetization_summary_subtitle": "Revizuie\u0219te planurile active, abonamentele \u0219i soldurile \xEEnainte s\u0103 deschizi detaliile aplica\u021Biei sau istoricul.",
696
+ "activity.monetization_summary_apps": "Aplica\u021Bii",
697
+ "activity.monetization_summary_subscriptions": "Abonamente",
698
+ "activity.monetization_summary_balances": "Solduri",
699
+ "activity.monetization_summary_currencies": "Monede nominale",
700
+ "activity.monetization_card_subtitle": "Planurile curente, soldurile \u0219i starea abonamentului pentru aceast\u0103 aplica\u021Bie.",
701
+ "activity.monetization_focus_xapp": "Doar aceast\u0103 aplica\u021Bie",
702
+ "activity.monetization_show_past": "Include aplica\u021Biile anterioare",
703
+ "activity.monetization_show_current_only": "Doar aplica\u021Biile curente",
704
+ "activity.monetization_open_plans": "Vezi planurile",
705
+ "activity.monetization_open_history": "Vezi istoricul",
706
+ "activity.monetization_access_label": "Acces",
707
+ "activity.monetization_plan_label": "Plan",
708
+ "activity.monetization_credits_label": "Sold",
657
709
  "activity.monetization_subscription_label": "Abonament",
658
- "activity.monetization_coverage_label": "Acoperire",
710
+ "activity.monetization_coverage_label": "Stare re\xEEnnoire",
659
711
  "activity.monetization_renews_at": "Se re\xEEnnoie\u0219te la",
660
- "activity.monetization_balance_state": "Stare sold",
661
- "activity.monetization_source_label": "Surs\u0103",
712
+ "activity.monetization_balance_state": "Status sold",
713
+ "activity.monetization_balances_label": "Solduri",
714
+ "activity.monetization_source_label": "Origine",
715
+ "activity.monetization_no_currency": "F\u0103r\u0103 moned\u0103 nominal\u0103",
662
716
  "activity.monetization_unknown": "Necunoscut",
663
717
  "activity.monetization_none": "Niciunul",
664
718
  "activity.monetization_no_source": "F\u0103r\u0103 surs\u0103",
@@ -734,7 +788,9 @@ var MARKETPLACE_CATALOGS = {
734
788
  "xapp.update_available": "Actualizare disponibil\u0103",
735
789
  "xapp.about_title": "Despre",
736
790
  "xapp.available_views_title": "Vizualiz\u0103ri disponibile",
791
+ "xapp.open_to_access_views": "Deschide aceast\u0103 aplica\u021Bie pentru a o porni \u0219i instala automat \xEEn spa\u021Biul t\u0103u de lucru.",
737
792
  "xapp.add_to_access_views": "Adaug\u0103 aceast\u0103 aplica\u021Bie \xEEn spa\u021Biul t\u0103u de lucru pentru a-i accesa vizualiz\u0103rile disponibile.",
793
+ "xapp.update_to_access_views_auto": "Deschide o vizualizare pentru a actualiza automat aplica\u021Bia \xEEn spa\u021Biul t\u0103u de lucru.",
738
794
  "xapp.update_to_access_views": "Este disponibil\u0103 o actualizare. Actualizeaz\u0103 aplica\u021Bia pentru a-i accesa vizualiz\u0103rile disponibile.",
739
795
  "xapp.load_as_user_to_access": "\xCEncarc\u0103 catalogul ca utilizator pentru a accesa aceast\u0103 aplica\u021Bie.",
740
796
  "xapp.no_views_available": "Nu exist\u0103 \xEEn prezent vizualiz\u0103ri disponibile pentru aplica\u021Bie.",
@@ -785,7 +841,11 @@ var MARKETPLACE_CATALOGS = {
785
841
  "xapp.subscription_cancel_failed": "Abonamentul nu a putut fi anulat.",
786
842
  "xapp.lifecycle_preview_at_label": "Previzualizare la",
787
843
  "xapp.lifecycle_preview_hint": "Ciclul de via\u021B\u0103 al abonamentului este previzualizat pentru momentul selectat.",
788
- "xapp.credits_remaining_label": "Credite r\u0103mase",
844
+ "xapp.virtual_currency_label": "Moned\u0103 virtual\u0103",
845
+ "xapp.current_balances_label": "Solduri curente",
846
+ "xapp.current_credits_label": "Credite acum",
847
+ "xapp.credits_remaining_label": "Sold",
848
+ "xapp.credit_balance_label": "Credite",
789
849
  "xapp.available_label": "Disponibile",
790
850
  "xapp.ready_to_use": "{count} gata de utilizare",
791
851
  "xapp.source_label": "Surs\u0103",
@@ -899,7 +959,8 @@ function applyMarketplaceThemeToDocument(theme) {
899
959
  ["radiusMd", ["--cx-radius-md", "--mx-radius-md"]],
900
960
  ["radius", ["--cx-radius", "--cx-radius-lg", "--mx-radius-md", "--mx-radius-lg"]],
901
961
  ["radiusLg", ["--cx-radius-lg", "--mx-radius-lg"]],
902
- ["fontFamily", ["--mx-font-family"]]
962
+ ["fontFamily", ["--xapps-font-family", "--mx-font-family"]],
963
+ ["displayFont", ["--xapps-display-font", "--mx-display-font"]]
903
964
  ];
904
965
  for (const [key, cssVars] of map) {
905
966
  const rawValue = theme[key];
@@ -1076,6 +1137,13 @@ function buildTokenSearch(token, search) {
1076
1137
  return out ? `?${out}` : "";
1077
1138
  }
1078
1139
 
1140
+ // src/utils/installationPolicy.ts
1141
+ function shouldHideMarketplaceVersions(input) {
1142
+ const installationPolicyResolved = input.installationPolicyResolved !== false;
1143
+ if (!installationPolicyResolved) return false;
1144
+ return input.installationPolicy?.mode === "auto_available" && input.installationPolicy?.update_mode === "auto_update_compatible";
1145
+ }
1146
+
1079
1147
  // src/utils/readers.ts
1080
1148
  function isRecord(value) {
1081
1149
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -1198,6 +1266,11 @@ function CatalogPage() {
1198
1266
  const mutationControlsReady = installationPolicyResolved || !host.subjectId || !canMutate;
1199
1267
  const autoUpdateMode = mutationControlsReady && (env?.installationPolicy ?? host.installationPolicy)?.update_mode === "auto_update_compatible" && Boolean(host.subjectId);
1200
1268
  const autoAvailableMode = mutationControlsReady && (env?.installationPolicy ?? host.installationPolicy)?.mode === "auto_available" && Boolean(host.subjectId);
1269
+ const hideVersions = shouldHideMarketplaceVersions({
1270
+ installationPolicy: env?.installationPolicy ?? host.installationPolicy ?? null,
1271
+ installationPolicyResolved,
1272
+ subjectId: host.subjectId
1273
+ });
1201
1274
  const loc = useLocation();
1202
1275
  const token = useQueryToken();
1203
1276
  const tokenSearch = buildTokenSearch(token, loc.search);
@@ -1494,7 +1567,7 @@ function CatalogPage() {
1494
1567
  /* @__PURE__ */ jsx6("span", { className: "mx-card-installed-badge-dot" }),
1495
1568
  t("common.added", void 0, "Added")
1496
1569
  ] }),
1497
- x.latest_version?.version && /* @__PURE__ */ jsxs3("div", { className: "mx-card-version", children: [
1570
+ !hideVersions && x.latest_version?.version && /* @__PURE__ */ jsxs3("div", { className: "mx-card-version", children: [
1498
1571
  "v",
1499
1572
  x.latest_version.version
1500
1573
  ] })
@@ -2130,17 +2203,54 @@ var XMS_COPY_CATALOG = {
2130
2203
  currentPlanActiveLabel: "Current plan active",
2131
2204
  startingCheckoutLabel: "Starting checkout...",
2132
2205
  purchaseAddOnUnlockLabel: "Purchase add-on unlock",
2133
- continueToCheckoutLabel: "Continue to checkout"
2206
+ continueToCheckoutLabel: "Continue to checkout",
2207
+ generalUpgradeFitLabel: "Flexible option",
2208
+ generalUpgradeSummary: "A general plan option for this app.",
2209
+ durableUnlockFitLabel: "One-time unlock",
2210
+ durableUnlockSummary: "Best when you want access without an ongoing subscription.",
2211
+ recurringMembershipFitLabel: "Subscription",
2212
+ recurringMembershipSummary: "Best when this app is meant to stay active through recurring coverage.",
2213
+ creditTopUpFitLabel: "Balance top-up",
2214
+ hybridUpgradeFitLabel: "Access + balance",
2215
+ creditPackFitSummary: (unitLabel) => `Best when the feature spends ${unitLabel} for each advanced action.`,
2216
+ hybridPackFitSummary: (unitLabel) => `Blends access coverage with bundled ${unitLabel} for mixed workflows.`,
2217
+ packageCurrencySignalLabel: (unitLabel) => `currency ${unitLabel}`,
2218
+ billedSignalLabel: (periodLabel) => `billed ${periodLabel}`,
2219
+ generalOfferingSummary: "Available plans for this app.",
2220
+ featurePaywallOfferingSummary: "Shown when this app needs extra access or balance.",
2221
+ defaultPaywallOfferingSummary: "Main plan selection for this app.",
2222
+ checkoutOfferingSummary: "Direct purchase flow for this app.",
2223
+ upgradeOfferingSummary: "Best for switching or upgrading your current plan.",
2224
+ featureDurableUnlockReason: "Aligned with one-time unlock access.",
2225
+ featureRecurringAccessReason: "Recurring membership also grants current access.",
2226
+ featureHybridAccessReason: "Hybrid package contributes to current access coverage.",
2227
+ featureSubscriptionDirectReason: "Matches the subscription requirement directly.",
2228
+ featureHybridSubscriptionReason: "Hybrid package can also cover part of the subscription shape.",
2229
+ creditRequirementCoveredLabel: (amountLabel) => `Covers the ${amountLabel} requirement.`,
2230
+ creditRequirementAddedLabel: (amountLabel) => `Adds ${amountLabel} toward the requirement.`,
2231
+ hybridCreditsSupportLabel: (unitLabel) => `Hybrid package can add bundled ${unitLabel} for this flow.`
2134
2232
  },
2135
2233
  surface: {
2136
2234
  plansTitle: "Plans",
2137
2235
  historyTitle: "History",
2138
- plansSubtitle: "Current access and published plans for this app",
2236
+ plansSubtitle: "Access, plans, and balances for this app",
2139
2237
  historySubtitle: "Recent monetization events, invoices, subscriptions, and wallet activity",
2238
+ offeringFallbackLabel: "Offering",
2239
+ packageFallbackLabel: "Package",
2240
+ paywallFallbackLabel: "Plans",
2241
+ availableLabel: "Available",
2242
+ unavailableLabel: "Unavailable",
2243
+ unknownLabel: "Unknown",
2244
+ yesLabel: "Yes",
2245
+ noLabel: "No",
2246
+ defaultBadgeLabel: "default",
2247
+ choosePackageActionLabel: "Choose package",
2248
+ noPaywallPackagesLabel: "No plans are currently available.",
2249
+ priceUnavailableLabel: "Price unavailable",
2140
2250
  plansLabel: "Plans",
2141
2251
  historyLabel: "History",
2142
2252
  closeLabel: "Close",
2143
- tabsAriaLabel: "XMS view",
2253
+ tabsAriaLabel: "Plans and history view",
2144
2254
  loadingLabel: "Loading plans...",
2145
2255
  subjectRequiredNotice: "Checkout requires a subject-bound catalog session. Start from a signed host session to purchase plans.",
2146
2256
  paymentCompletedNotice: "Payment completed and access was refreshed.",
@@ -2154,7 +2264,7 @@ var XMS_COPY_CATALOG = {
2154
2264
  subscriptionCancelConfirmMessage: "Cancel renewal for this subscription?",
2155
2265
  subscriptionCancelConfirmLabel: "Cancel subscription",
2156
2266
  subscriptionCancelDismissLabel: "Keep subscription",
2157
- missingPackageMetadataMessage: "This package is missing purchase metadata in the published paywall.",
2267
+ missingPackageMetadataMessage: "This package is missing purchase metadata in the published plans configuration.",
2158
2268
  missingIntentMessage: "Purchase intent was created without an identifier.",
2159
2269
  missingPaymentPageMessage: "Payment page is not available for this package.",
2160
2270
  startCheckoutFailedMessage: "Unable to start checkout for this package.",
@@ -2162,7 +2272,7 @@ var XMS_COPY_CATALOG = {
2162
2272
  currentCoverageTitle: "Current coverage",
2163
2273
  currentPlanLabel: "Current plan",
2164
2274
  membershipAccessLabel: "Membership access",
2165
- subscriptionStatusLabel: "Subscription status",
2275
+ subscriptionStatusLabel: "Subscription state",
2166
2276
  subscriptionCoverageLabel: "Coverage",
2167
2277
  subscriptionReasonLabel: "Status reason",
2168
2278
  currentPeriodEndsLabel: "Current period ends",
@@ -2186,7 +2296,10 @@ var XMS_COPY_CATALOG = {
2186
2296
  managementDestinationHintPublisherLabel: "Advanced subscription management is handled in the publisher app.",
2187
2297
  managementDestinationHintOwnerLabel: "Advanced subscription management is handled by the app owner.",
2188
2298
  openManagementDestinationActionLabel: "Open management",
2189
- creditsRemainingLabel: "Credits remaining",
2299
+ virtualCurrencyLabel: "Currency",
2300
+ currentCreditsLabel: "Credits now",
2301
+ creditsRemainingLabel: "Balance",
2302
+ creditBalanceLabel: "Credits",
2190
2303
  addOnUnlocksLabel: "Add-on unlocks",
2191
2304
  coverageActiveLabel: "Still covered",
2192
2305
  coverageInactiveLabel: "Not covered",
@@ -2198,11 +2311,14 @@ var XMS_COPY_CATALOG = {
2198
2311
  refreshingStatusActionLabel: "Refreshing...",
2199
2312
  cancelSubscriptionActionLabel: "Cancel subscription",
2200
2313
  cancellingSubscriptionActionLabel: "Cancelling...",
2201
- noPublishedPlansLabel: "No published plans are currently available.",
2202
- recentTimelineTitle: "Recent timeline",
2203
- recentTimelineSubtitle: "Latest monetization events correlated for this subject and app.",
2204
- historyAuditTitle: "History and audit",
2205
- historyAuditSubtitle: "Recent monetization records for this subject and app.",
2314
+ noPublishedPlansLabel: "No plans are currently available.",
2315
+ recentTimelineTitle: "Recent activity",
2316
+ recentTimelineSubtitle: "Latest subscription, balance, purchase, and invoice activity for this app.",
2317
+ historyAuditTitle: "Detailed history",
2318
+ historyAuditSubtitle: "Recent records grouped by subscriptions, balances, purchases, and invoices.",
2319
+ historyBalanceSummaryTitle: "Balances now",
2320
+ historyCreditSummaryTitle: "Credits now",
2321
+ historyBalanceSummarySubtitle: "Latest visible wallet balances grouped by virtual currency for this app.",
2206
2322
  noHistoryAvailableLabel: "No monetization history is available for this app yet.",
2207
2323
  historyGenericLabel: "History",
2208
2324
  historyPurchaseIntentsTitle: "Purchase intents",
@@ -2227,7 +2343,33 @@ var XMS_COPY_CATALOG = {
2227
2343
  historyAccessSnapshotsTitle: "Access snapshots",
2228
2344
  historyAccessSnapshotLabel: "Access snapshot",
2229
2345
  historyInvoicesTitle: "Invoices",
2230
- historyInvoiceLabel: "Invoice"
2346
+ historyInvoiceLabel: "Invoice",
2347
+ featureCurrentAccessMissingLabel: "Current access coverage is not active on this scope.",
2348
+ featureSubscriptionMissingLabel: "No active subscription is visible for this scope.",
2349
+ featureCreditsMissingLabel: (requiredLabel, availableLabel) => `This action needs ${requiredLabel}, but only ${availableLabel} are visible right now.`,
2350
+ featureBlockedSummary: (title) => `${title || "Feature"} is blocked on the current scope.`,
2351
+ featureReadySummary: (title) => `${title || "Feature"} can be unlocked from the current plan options.`,
2352
+ featureNeedMixedAccessLabel: "needs mixed access",
2353
+ featureNeedMembershipAndCreditsLabel: (unitLabel) => `needs membership + ${unitLabel}`,
2354
+ featureNeedMembershipLabel: "needs membership",
2355
+ featureNeedCreditsLabel: (unitLabel) => `needs ${unitLabel}`,
2356
+ featureNeedAccessLabel: "needs access",
2357
+ featureLockedLabel: "locked",
2358
+ featureGapShortLabel: (amountLabel) => `${amountLabel} short`,
2359
+ featureCurrentAccessMissingBadge: "current access missing",
2360
+ featureMembershipNotActiveBadge: "membership not active",
2361
+ featureCandidateLead: (selectedPackageTitle) => `${selectedPackageTitle || "Selected package"} is one package candidate for this access gap.`,
2362
+ featureCandidateFallbackLead: "Choose a plan option that covers the current access gap.",
2363
+ featureViewHybridOptionsLabel: "View hybrid options",
2364
+ featureViewMembershipOptionsLabel: "View membership options",
2365
+ featureViewCreditOptionsLabel: (unitLabel) => `View ${unitLabel} options`,
2366
+ featureViewUnlockOptionsLabel: "View unlock options",
2367
+ featureOpenPaywallLabel: "Open plans",
2368
+ featureUnlockCheckoutLabel: "Unlock with hosted checkout",
2369
+ featureStartMembershipCheckoutLabel: "Start membership checkout",
2370
+ featureBuyCreditsCheckoutLabel: (unitLabel) => `Buy ${unitLabel} with hosted checkout`,
2371
+ featureStartHybridCheckoutLabel: "Start hybrid checkout",
2372
+ featureCreatePaymentSessionLabel: "Create payment session"
2231
2373
  }
2232
2374
  },
2233
2375
  ro: {
@@ -2242,17 +2384,54 @@ var XMS_COPY_CATALOG = {
2242
2384
  currentPlanActiveLabel: "Plan activ",
2243
2385
  startingCheckoutLabel: "Se porne\u0219te checkout-ul...",
2244
2386
  purchaseAddOnUnlockLabel: "Cump\u0103r\u0103 suplimentul",
2245
- continueToCheckoutLabel: "Continu\u0103 spre checkout"
2387
+ continueToCheckoutLabel: "Continu\u0103 spre checkout",
2388
+ generalUpgradeFitLabel: "Op\u021Biune flexibil\u0103",
2389
+ generalUpgradeSummary: "O op\u021Biune general\u0103 de plan pentru aceast\u0103 aplica\u021Bie.",
2390
+ durableUnlockFitLabel: "Unlock unic",
2391
+ durableUnlockSummary: "Potrivit c\xE2nd vrei acces f\u0103r\u0103 un abonament recurent.",
2392
+ recurringMembershipFitLabel: "Abonament",
2393
+ recurringMembershipSummary: "Potrivit c\xE2nd aceast\u0103 aplica\u021Bie trebuie s\u0103 r\u0103m\xE2n\u0103 activ\u0103 prin acoperire recurent\u0103.",
2394
+ creditTopUpFitLabel: "Top-up sold",
2395
+ hybridUpgradeFitLabel: "Acces + sold",
2396
+ creditPackFitSummary: (unitLabel) => `Potrivit c\xE2nd func\u021Bia consum\u0103 ${unitLabel} pentru fiecare ac\u021Biune avansat\u0103.`,
2397
+ hybridPackFitSummary: (unitLabel) => `Combin\u0103 acoperirea accesului cu ${unitLabel} incluse pentru fluxuri mixte.`,
2398
+ packageCurrencySignalLabel: (unitLabel) => `moned\u0103 ${unitLabel}`,
2399
+ billedSignalLabel: (periodLabel) => `facturat ${periodLabel}`,
2400
+ generalOfferingSummary: "Planuri disponibile pentru aceast\u0103 aplica\u021Bie.",
2401
+ featurePaywallOfferingSummary: "Afi\u0219at c\xE2nd aceast\u0103 aplica\u021Bie are nevoie de acces sau sold suplimentar.",
2402
+ defaultPaywallOfferingSummary: "Selec\u021Bia principal\u0103 de planuri pentru aceast\u0103 aplica\u021Bie.",
2403
+ checkoutOfferingSummary: "Flux de cump\u0103rare direct pentru aceast\u0103 aplica\u021Bie.",
2404
+ upgradeOfferingSummary: "Potrivit pentru schimbarea sau \xEEmbun\u0103t\u0103\u021Birea planului curent.",
2405
+ featureDurableUnlockReason: "Se potrive\u0219te cu accesul de tip unlock unic.",
2406
+ featureRecurringAccessReason: "Abonamentul recurent ofer\u0103 \u0219i acces curent pentru acest flux.",
2407
+ featureHybridAccessReason: "Pachetul hibrid contribuie la acoperirea accesului curent.",
2408
+ featureSubscriptionDirectReason: "Se potrive\u0219te direct cu cerin\u021Ba de abonament.",
2409
+ featureHybridSubscriptionReason: "Pachetul hibrid poate acoperi \u0219i o parte din forma de abonament.",
2410
+ creditRequirementCoveredLabel: (amountLabel) => `Acoper\u0103 cerin\u021Ba de ${amountLabel}.`,
2411
+ creditRequirementAddedLabel: (amountLabel) => `Adaug\u0103 ${amountLabel} c\u0103tre cerin\u021B\u0103.`,
2412
+ hybridCreditsSupportLabel: (unitLabel) => `Pachetul hibrid poate ad\u0103uga ${unitLabel} incluse pentru acest flux.`
2246
2413
  },
2247
2414
  surface: {
2248
2415
  plansTitle: "Planuri",
2249
2416
  historyTitle: "Istoric",
2250
- plansSubtitle: "Accesul curent \u0219i planurile publicate pentru aceast\u0103 aplica\u021Bie",
2417
+ plansSubtitle: "Acces, planuri \u0219i solduri pentru aceast\u0103 aplica\u021Bie",
2251
2418
  historySubtitle: "Evenimente recente de monetizare, facturi, abonamente \u0219i activitate din portofel",
2419
+ offeringFallbackLabel: "Ofert\u0103",
2420
+ packageFallbackLabel: "Pachet",
2421
+ paywallFallbackLabel: "Planuri",
2422
+ availableLabel: "Disponibil",
2423
+ unavailableLabel: "Indisponibil",
2424
+ unknownLabel: "Necunoscut",
2425
+ yesLabel: "Da",
2426
+ noLabel: "Nu",
2427
+ defaultBadgeLabel: "implicit",
2428
+ choosePackageActionLabel: "Alege pachetul",
2429
+ noPaywallPackagesLabel: "Nu exist\u0103 momentan planuri disponibile.",
2430
+ priceUnavailableLabel: "Pre\u021B indisponibil",
2252
2431
  plansLabel: "Planuri",
2253
2432
  historyLabel: "Istoric",
2254
2433
  closeLabel: "\xCEnchide",
2255
- tabsAriaLabel: "Vizualizare XMS",
2434
+ tabsAriaLabel: "Vizualizare planuri \u0219i istoric",
2256
2435
  loadingLabel: "Se \xEEncarc\u0103 planurile...",
2257
2436
  subjectRequiredNotice: "Checkout-ul necesit\u0103 o sesiune de catalog asociat\u0103 unui subiect. Porne\u0219te dintr-o sesiune gazd\u0103 autentificat\u0103 pentru a cump\u0103ra planuri.",
2258
2437
  paymentCompletedNotice: "Plata a fost finalizat\u0103 \u0219i accesul a fost actualizat.",
@@ -2266,7 +2445,7 @@ var XMS_COPY_CATALOG = {
2266
2445
  subscriptionCancelConfirmMessage: "Anulezi re\xEEnnoirea acestui abonament?",
2267
2446
  subscriptionCancelConfirmLabel: "Anuleaz\u0103 abonamentul",
2268
2447
  subscriptionCancelDismissLabel: "P\u0103streaz\u0103 abonamentul",
2269
- missingPackageMetadataMessage: "Acest pachet nu are metadatele de cump\u0103rare necesare \xEEn paywall-ul publicat.",
2448
+ missingPackageMetadataMessage: "Acest pachet nu are metadatele de cump\u0103rare necesare \xEEn configura\u021Bia publicat\u0103 a planurilor.",
2270
2449
  missingIntentMessage: "Intentul de cump\u0103rare a fost creat f\u0103r\u0103 identificator.",
2271
2450
  missingPaymentPageMessage: "Pagina de plat\u0103 nu este disponibil\u0103 pentru acest pachet.",
2272
2451
  startCheckoutFailedMessage: "Nu s-a putut porni checkout-ul pentru acest pachet.",
@@ -2298,7 +2477,10 @@ var XMS_COPY_CATALOG = {
2298
2477
  managementDestinationHintPublisherLabel: "Administrarea avansat\u0103 a abonamentului se face \xEEn aplica\u021Bia publisherului.",
2299
2478
  managementDestinationHintOwnerLabel: "Administrarea avansat\u0103 a abonamentului este gestionat\u0103 de proprietarul aplica\u021Biei.",
2300
2479
  openManagementDestinationActionLabel: "Deschide administrarea",
2301
- creditsRemainingLabel: "Credite r\u0103mase",
2480
+ virtualCurrencyLabel: "Moned\u0103 virtual\u0103",
2481
+ currentCreditsLabel: "Credite acum",
2482
+ creditsRemainingLabel: "Sold",
2483
+ creditBalanceLabel: "Credite",
2302
2484
  addOnUnlocksLabel: "Unlock-uri suplimentare",
2303
2485
  coverageActiveLabel: "\xCEnc\u0103 activ",
2304
2486
  coverageInactiveLabel: "Neacoperit",
@@ -2310,11 +2492,14 @@ var XMS_COPY_CATALOG = {
2310
2492
  refreshingStatusActionLabel: "Se actualizeaz\u0103...",
2311
2493
  cancelSubscriptionActionLabel: "Anuleaz\u0103 abonamentul",
2312
2494
  cancellingSubscriptionActionLabel: "Se anuleaz\u0103...",
2313
- noPublishedPlansLabel: "Nu exist\u0103 planuri publicate disponibile \xEEn acest moment.",
2314
- recentTimelineTitle: "Cronologie recent\u0103",
2315
- recentTimelineSubtitle: "Cele mai recente evenimente de monetizare corelate pentru acest subiect \u0219i aceast\u0103 aplica\u021Bie.",
2316
- historyAuditTitle: "Istoric \u0219i audit",
2317
- historyAuditSubtitle: "\xCEnregistr\u0103ri recente de monetizare pentru acest subiect \u0219i aceast\u0103 aplica\u021Bie.",
2495
+ noPublishedPlansLabel: "Nu exist\u0103 planuri disponibile \xEEn acest moment.",
2496
+ recentTimelineTitle: "Activitate recent\u0103",
2497
+ recentTimelineSubtitle: "Cele mai recente actualiz\u0103ri pentru abonamente, solduri, cump\u0103r\u0103ri \u0219i facturi pentru aceast\u0103 aplica\u021Bie.",
2498
+ historyAuditTitle: "Istoric detaliat",
2499
+ historyAuditSubtitle: "\xCEnregistr\u0103ri recente grupate dup\u0103 abonamente, solduri, cump\u0103r\u0103ri \u0219i facturi.",
2500
+ historyBalanceSummaryTitle: "Solduri acum",
2501
+ historyCreditSummaryTitle: "Credite acum",
2502
+ historyBalanceSummarySubtitle: "Cele mai recente solduri vizibile din portofel, grupate dup\u0103 moneda virtual\u0103 pentru aceast\u0103 aplica\u021Bie.",
2318
2503
  noHistoryAvailableLabel: "Nu exist\u0103 \xEEnc\u0103 istoric de monetizare disponibil pentru aceast\u0103 aplica\u021Bie.",
2319
2504
  historyGenericLabel: "Istoric",
2320
2505
  historyPurchaseIntentsTitle: "Inten\u021Bii de cump\u0103rare",
@@ -2339,7 +2524,33 @@ var XMS_COPY_CATALOG = {
2339
2524
  historyAccessSnapshotsTitle: "Instantanee acces",
2340
2525
  historyAccessSnapshotLabel: "Instantaneu acces",
2341
2526
  historyInvoicesTitle: "Facturi",
2342
- historyInvoiceLabel: "Factur\u0103"
2527
+ historyInvoiceLabel: "Factur\u0103",
2528
+ featureCurrentAccessMissingLabel: "Acoperirea de acces curent nu este activ\u0103 pe acest scope.",
2529
+ featureSubscriptionMissingLabel: "Nu este vizibil niciun abonament activ pentru acest scope.",
2530
+ featureCreditsMissingLabel: (requiredLabel, availableLabel) => `Aceast\u0103 ac\u021Biune are nevoie de ${requiredLabel}, dar acum sunt vizibile doar ${availableLabel}.`,
2531
+ featureBlockedSummary: (title) => `${title || "Func\u021Bia"} este blocat\u0103 pe scope-ul curent.`,
2532
+ featureReadySummary: (title) => `${title || "Func\u021Bia"} poate fi deblocat\u0103 din op\u021Biunile curente de plan.`,
2533
+ featureNeedMixedAccessLabel: "necesit\u0103 acces mixt",
2534
+ featureNeedMembershipAndCreditsLabel: (unitLabel) => `necesit\u0103 abonament + ${unitLabel}`,
2535
+ featureNeedMembershipLabel: "necesit\u0103 abonament",
2536
+ featureNeedCreditsLabel: (unitLabel) => `necesit\u0103 ${unitLabel}`,
2537
+ featureNeedAccessLabel: "necesit\u0103 acces",
2538
+ featureLockedLabel: "blocat",
2539
+ featureGapShortLabel: (amountLabel) => `lipse\u0219te ${amountLabel}`,
2540
+ featureCurrentAccessMissingBadge: "lipse\u0219te accesul curent",
2541
+ featureMembershipNotActiveBadge: "abonamentul nu este activ",
2542
+ featureCandidateLead: (selectedPackageTitle) => `${selectedPackageTitle || "Pachetul selectat"} este un pachet candidat pentru acest gol de acces.`,
2543
+ featureCandidateFallbackLead: "Alege o op\u021Biune de plan care acoper\u0103 golul curent de acces.",
2544
+ featureViewHybridOptionsLabel: "Vezi op\u021Biunile hibride",
2545
+ featureViewMembershipOptionsLabel: "Vezi op\u021Biunile de abonament",
2546
+ featureViewCreditOptionsLabel: (unitLabel) => `Vezi op\u021Biunile ${unitLabel}`,
2547
+ featureViewUnlockOptionsLabel: "Vezi op\u021Biunile de unlock",
2548
+ featureOpenPaywallLabel: "Deschide planurile",
2549
+ featureUnlockCheckoutLabel: "Deblocheaz\u0103 prin checkout g\u0103zduit",
2550
+ featureStartMembershipCheckoutLabel: "Porne\u0219te checkout-ul de abonament",
2551
+ featureBuyCreditsCheckoutLabel: (unitLabel) => `Cump\u0103r\u0103 ${unitLabel} prin checkout g\u0103zduit`,
2552
+ featureStartHybridCheckoutLabel: "Porne\u0219te checkout-ul hibrid",
2553
+ featureCreatePaymentSessionLabel: "Creeaz\u0103 sesiunea de plat\u0103"
2343
2554
  }
2344
2555
  }
2345
2556
  };
@@ -2377,6 +2588,41 @@ function readLocalizedText(value, fallback = "") {
2377
2588
  const record = value;
2378
2589
  return readString4(record.en) || readString4(record.ro) || Object.values(record).map((item) => readString4(item)).find(Boolean) || fallback;
2379
2590
  }
2591
+ function readVirtualCurrencyDefinition(value) {
2592
+ const record = readRecord(value);
2593
+ if (!record) return null;
2594
+ const code = readString4(record.code);
2595
+ const name = readString4(record.name);
2596
+ if (!code && !name) return null;
2597
+ return record;
2598
+ }
2599
+ function hasNamedVirtualCurrency(value) {
2600
+ return Boolean(readVirtualCurrencyDefinition(value));
2601
+ }
2602
+ function formatVirtualCurrencyLabel(value, options) {
2603
+ const record = readVirtualCurrencyDefinition(value);
2604
+ if (!record) return "";
2605
+ const code = readString4(record.code);
2606
+ const name = readString4(record.name);
2607
+ if (options?.preferCode && code) return code;
2608
+ if (options?.includeCode && name && code && readLower2(name) !== readLower2(code)) {
2609
+ return `${name} (${code})`;
2610
+ }
2611
+ return name || code;
2612
+ }
2613
+ function formatVirtualCurrencyAmountLabel(input) {
2614
+ const amount = readString4(input.amount);
2615
+ if (!amount) return "";
2616
+ const currencyLabel = formatVirtualCurrencyLabel(input.virtualCurrency);
2617
+ if (currencyLabel) return `${amount} ${currencyLabel}`;
2618
+ const fallbackUnit = readString4(input.fallbackUnit);
2619
+ return fallbackUnit ? `${amount} ${fallbackUnit}` : amount;
2620
+ }
2621
+ function normalizeVirtualCurrencyDisplayLabel(label) {
2622
+ const normalized = readString4(label);
2623
+ if (!normalized) return "";
2624
+ return normalized.replace(/\s+\([^)]+\)\s*$/, "").trim() || normalized;
2625
+ }
2380
2626
  function escapeHtml(value) {
2381
2627
  return String(value ?? "").replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2382
2628
  }
@@ -2402,11 +2648,12 @@ function hasEffectiveCoverage(input) {
2402
2648
  return Boolean(input.accessProjection?.has_current_access);
2403
2649
  }
2404
2650
  function formatCoverageLabel(input) {
2651
+ const copy = buildXmsSurfaceCopy({ locale: input.locale });
2405
2652
  if (isExhaustedIncludedCreditAccess(input)) {
2406
2653
  return buildXmsPackageCopy(input.locale).consumedLabel;
2407
2654
  }
2408
- if (hasEffectiveCoverage(input)) return "Available";
2409
- return formatStateLabel(input.accessProjection?.entitlement_state, "Unavailable");
2655
+ if (hasEffectiveCoverage(input)) return copy.coverageActiveLabel;
2656
+ return copy.coverageInactiveLabel;
2410
2657
  }
2411
2658
  function resolveSubscriptionCoverageLabel(input) {
2412
2659
  const copy = buildXmsSurfaceCopy({ locale: input.locale });
@@ -2518,17 +2765,33 @@ function flattenXappMonetizationPaywallPackages(paywall) {
2518
2765
  out.push({
2519
2766
  offeringId: readString4(packageRecord.offering_id),
2520
2767
  offeringSlug: readString4(packageRecord.offering_slug),
2521
- offeringTitle: readString4(packageRecord.offering_slug) || "Offering",
2768
+ offeringTitle: readLocalizedText(
2769
+ packageRecord.offering_title,
2770
+ readString4(packageRecord.offering_slug) || buildXmsSurfaceCopy().offeringFallbackLabel
2771
+ ),
2522
2772
  offeringPlacement: readString4(packageRecord.offering_placement) || null,
2523
2773
  packageId: readString4(packageRecord.id),
2524
2774
  packageSlug: readString4(packageRecord.slug),
2525
- packageTitle: readString4(packageRecord.slug) || "Package",
2775
+ packageTitle: readLocalizedText(
2776
+ packageRecord.title,
2777
+ readLocalizedText(
2778
+ packageRecord.product?.title,
2779
+ readString4(packageRecord.slug) || buildXmsSurfaceCopy().packageFallbackLabel
2780
+ )
2781
+ ),
2526
2782
  packageKind: readString4(packageRecord.package_kind) || "standard",
2527
2783
  productId: readString4(packageRecord.product?.id),
2528
2784
  productSlug: readString4(packageRecord.product?.slug),
2785
+ productTitle: readLocalizedText(
2786
+ packageRecord.product?.title,
2787
+ readString4(packageRecord.product?.slug)
2788
+ ),
2529
2789
  productFamily: readString4(
2530
2790
  packageRecord.product?.product_family
2531
2791
  ),
2792
+ virtualCurrency: readVirtualCurrencyDefinition(
2793
+ packageRecord.product?.virtual_currency
2794
+ ) ?? null,
2532
2795
  productMetadata: packageRecord.product?.metadata && typeof packageRecord.product.metadata === "object" ? packageRecord.product.metadata : {},
2533
2796
  priceId: readString4(price?.id),
2534
2797
  amount: readString4(price?.amount),
@@ -2555,18 +2818,20 @@ function readPackageCredits(item) {
2555
2818
  }
2556
2819
  function buildMonetizationOfferingPresentation(input) {
2557
2820
  const record = input && typeof input === "object" && !Array.isArray(input) ? input : {};
2558
- const offeringLabel = readString4(record.offeringTitle) || formatStateLabel(record.offeringSlug, "Offering");
2821
+ const surfaceCopy = buildXmsSurfaceCopy({ locale: record.locale });
2822
+ const offeringLabel = readString4(record.offeringTitle) || formatStateLabel(record.offeringSlug, surfaceCopy.offeringFallbackLabel);
2559
2823
  const placementRaw = readLower2(record.offeringPlacement);
2560
2824
  const placementLabel = formatPlacementLabel(record.offeringPlacement);
2561
- let summary = "General offering surface for this xapp.";
2825
+ const copy = buildXmsPackageCopy(record.locale);
2826
+ let summary = copy.generalOfferingSummary;
2562
2827
  if (placementRaw.includes("feature") && placementRaw.includes("paywall")) {
2563
- summary = "Feature-paywall placement for gated in-app flows.";
2828
+ summary = copy.featurePaywallOfferingSummary;
2564
2829
  } else if (placementRaw.includes("paywall")) {
2565
- summary = "Default paywall placement for monetized upgrade prompts.";
2830
+ summary = copy.defaultPaywallOfferingSummary;
2566
2831
  } else if (placementRaw.includes("checkout")) {
2567
- summary = "Direct checkout placement for purchase-driven flows.";
2832
+ summary = copy.checkoutOfferingSummary;
2568
2833
  } else if (placementRaw.includes("upgrade")) {
2569
- summary = "Upgrade-oriented placement for membership and package switching.";
2834
+ summary = copy.upgradeOfferingSummary;
2570
2835
  }
2571
2836
  return {
2572
2837
  offeringLabel,
@@ -2576,7 +2841,13 @@ function buildMonetizationOfferingPresentation(input) {
2576
2841
  }
2577
2842
  function buildMonetizationPaywallPresentation(input) {
2578
2843
  const record = input && typeof input === "object" && !Array.isArray(input) ? input : {};
2579
- const paywallLabel = readLocalizedText(record.title, formatStateLabel(record.slug, "Paywall")) || "Paywall";
2844
+ const paywallLabel = readLocalizedText(
2845
+ record.title,
2846
+ formatStateLabel(
2847
+ record.slug,
2848
+ buildXmsSurfaceCopy({ locale: record.locale }).paywallFallbackLabel
2849
+ )
2850
+ ) || buildXmsSurfaceCopy({ locale: record.locale }).paywallFallbackLabel;
2580
2851
  const placementLabel = formatPlacementLabel(record.placement);
2581
2852
  const packages = flattenXappMonetizationPaywallPackages(record);
2582
2853
  const defaultPackageRef = readString4(record.default_package_ref);
@@ -2599,10 +2870,13 @@ function buildMonetizationPaywallRenderModel(input) {
2599
2870
  return {
2600
2871
  packageId: readString4(item.packageId),
2601
2872
  packageSlug: readString4(item.packageSlug),
2602
- packageTitle: readString4(item.packageTitle) || "Package",
2873
+ packageTitle: readString4(item.packageTitle) || buildXmsSurfaceCopy().packageFallbackLabel,
2603
2874
  productId: readString4(item.productId),
2604
2875
  productSlug: readString4(item.productSlug),
2605
2876
  productFamily: readString4(item.productFamily),
2877
+ virtualCurrencyCode: formatVirtualCurrencyLabel(item.virtualCurrency, { preferCode: true }),
2878
+ virtualCurrencyName: formatVirtualCurrencyLabel(item.virtualCurrency),
2879
+ virtualCurrencyLabel: formatVirtualCurrencyLabel(item.virtualCurrency, { includeCode: true }),
2606
2880
  productMetadata: item.productMetadata && typeof item.productMetadata === "object" && !Array.isArray(item.productMetadata) ? item.productMetadata : {},
2607
2881
  metadata: item.metadata && typeof item.metadata === "object" && !Array.isArray(item.metadata) ? item.metadata : {},
2608
2882
  description: readString4(item.description) || packagePresentation.summary,
@@ -2629,7 +2903,10 @@ var monetizationPlansSurfaceStyles = `
2629
2903
  display: grid;
2630
2904
  gap: 16px;
2631
2905
  color: var(--xapps-text-primary, #0f172a);
2632
- font-family: var(--xapps-font-family, Inter, "Segoe UI", sans-serif);
2906
+ font-family: var(
2907
+ --xapps-font-family,
2908
+ var(--mx-font-family, "Inter", "Segoe UI", system-ui, -apple-system, sans-serif)
2909
+ );
2633
2910
  }
2634
2911
  .xapps-xms-plans__header {
2635
2912
  display: grid;
@@ -2637,7 +2914,8 @@ var monetizationPlansSurfaceStyles = `
2637
2914
  }
2638
2915
  .xapps-xms-plans__title {
2639
2916
  margin: 0;
2640
- font: 700 1.05rem/1.15 var(--xapps-display-font, "IBM Plex Serif", Georgia, serif);
2917
+ font: 700 1.05rem/1.15
2918
+ var(--xapps-display-font, var(--mx-display-font, var(--mx-font-family, "Inter", "Segoe UI", system-ui, -apple-system, sans-serif)));
2641
2919
  letter-spacing: -0.01em;
2642
2920
  }
2643
2921
  .xapps-xms-plans__subtitle {
@@ -2664,7 +2942,8 @@ var monetizationPlansSurfaceStyles = `
2664
2942
  }
2665
2943
  .xapps-xms-plans__section-title {
2666
2944
  margin: 0;
2667
- font: 700 0.98rem/1.1 var(--xapps-display-font, "IBM Plex Serif", Georgia, serif);
2945
+ font: 700 0.98rem/1.1
2946
+ var(--xapps-display-font, var(--mx-display-font, var(--mx-font-family, "Inter", "Segoe UI", system-ui, -apple-system, sans-serif)));
2668
2947
  letter-spacing: -0.01em;
2669
2948
  }
2670
2949
  .xapps-xms-plans__meta {
@@ -2699,15 +2978,34 @@ var monetizationPlansSurfaceStyles = `
2699
2978
  .xapps-xms-plans__notice {
2700
2979
  padding: 10px 12px;
2701
2980
  border-radius: 12px;
2702
- background: color-mix(in srgb, var(--xapps-accent, #0f766e) 8%, var(--xapps-surface-bg, #ffffff));
2703
- color: color-mix(in srgb, var(--xapps-accent, #0f766e) 82%, var(--xapps-text-primary, #0f172a));
2981
+ border: 1px solid
2982
+ var(
2983
+ --xapps-paywall-notice-border,
2984
+ color-mix(in srgb, var(--xapps-accent, #0f766e) 18%, var(--xapps-border-color, transparent))
2985
+ );
2986
+ background: var(
2987
+ --xapps-paywall-notice-bg,
2988
+ color-mix(in srgb, var(--xapps-accent, #0f766e) 8%, var(--xapps-surface-bg, #ffffff))
2989
+ );
2990
+ color: var(
2991
+ --xapps-paywall-notice-text,
2992
+ color-mix(in srgb, var(--xapps-accent, #0f766e) 82%, var(--xapps-text-primary, #0f172a))
2993
+ );
2704
2994
  font-size: 13px;
2705
2995
  }
2706
2996
  .xapps-xms-plans__error {
2707
2997
  padding: 10px 12px;
2708
2998
  border-radius: 12px;
2709
- background: color-mix(in srgb, var(--xapps-danger, #dc2626) 8%, var(--xapps-surface-bg, #ffffff));
2710
- color: var(--xapps-danger, #b91c1c);
2999
+ border: 1px solid
3000
+ var(
3001
+ --xapps-paywall-danger-border,
3002
+ color-mix(in srgb, var(--xapps-danger, #dc2626) 18%, var(--xapps-border-color, transparent))
3003
+ );
3004
+ background: var(
3005
+ --xapps-paywall-danger-bg,
3006
+ color-mix(in srgb, var(--xapps-danger, #dc2626) 8%, var(--xapps-surface-bg, #ffffff))
3007
+ );
3008
+ color: var(--xapps-paywall-danger-text, var(--xapps-danger, #b91c1c));
2711
3009
  font-size: 13px;
2712
3010
  }
2713
3011
  .xapps-xms-plans__packages {
@@ -2723,12 +3021,24 @@ var monetizationPlansSurfaceStyles = `
2723
3021
  background: color-mix(in srgb, var(--xapps-surface-bg, #ffffff) 94%, var(--xapps-surface-subtle, #f8fafc));
2724
3022
  }
2725
3023
  .xapps-xms-plans__package.is-selected {
2726
- border-color: color-mix(in srgb, var(--xapps-accent, #2563eb) 34%, var(--xapps-border-color, transparent));
2727
- box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--xapps-accent, #2563eb) 12%, transparent);
3024
+ border-color: var(
3025
+ --xapps-paywall-selected-border,
3026
+ color-mix(in srgb, var(--xapps-accent, #2563eb) 34%, var(--xapps-border-color, transparent))
3027
+ );
3028
+ box-shadow: var(
3029
+ --xapps-paywall-selected-shadow,
3030
+ inset 0 0 0 1px color-mix(in srgb, var(--xapps-accent, #2563eb) 12%, transparent)
3031
+ );
2728
3032
  }
2729
3033
  .xapps-xms-plans__package.is-default {
2730
- border-color: color-mix(in srgb, var(--xapps-accent, #0f766e) 28%, var(--xapps-border-color, transparent));
2731
- box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--xapps-accent, #0f766e) 10%, transparent);
3034
+ border-color: var(
3035
+ --xapps-paywall-default-border,
3036
+ color-mix(in srgb, var(--xapps-accent, #0f766e) 28%, var(--xapps-border-color, transparent))
3037
+ );
3038
+ box-shadow: var(
3039
+ --xapps-paywall-default-shadow,
3040
+ inset 0 0 0 1px color-mix(in srgb, var(--xapps-accent, #0f766e) 10%, transparent)
3041
+ );
2732
3042
  }
2733
3043
  .xapps-xms-plans__package-head {
2734
3044
  display: flex;
@@ -2738,7 +3048,8 @@ var monetizationPlansSurfaceStyles = `
2738
3048
  }
2739
3049
  .xapps-xms-plans__package-title {
2740
3050
  margin: 0;
2741
- font: 700 0.98rem/1.15 var(--xapps-display-font, "IBM Plex Serif", Georgia, serif);
3051
+ font: 700 0.98rem/1.15
3052
+ var(--xapps-display-font, var(--mx-display-font, var(--mx-font-family, "Inter", "Segoe UI", system-ui, -apple-system, sans-serif)));
2742
3053
  letter-spacing: -0.01em;
2743
3054
  }
2744
3055
  .xapps-xms-plans__package-description {
@@ -2753,11 +3064,21 @@ var monetizationPlansSurfaceStyles = `
2753
3064
  white-space: nowrap;
2754
3065
  padding: 6px 10px;
2755
3066
  border-radius: 999px;
2756
- background: color-mix(in srgb, var(--xapps-accent, #0f766e) 7%, var(--xapps-surface-bg, #ffffff));
2757
- color: color-mix(in srgb, var(--xapps-accent, #0f766e) 28%, var(--xapps-text-primary, #1e293b));
3067
+ background: var(
3068
+ --xapps-paywall-money-bg,
3069
+ color-mix(in srgb, var(--xapps-accent, #0f766e) 7%, var(--xapps-surface-bg, #ffffff))
3070
+ );
3071
+ color: var(
3072
+ --xapps-paywall-money-text,
3073
+ color-mix(in srgb, var(--xapps-accent, #0f766e) 28%, var(--xapps-text-primary, #1e293b))
3074
+ );
2758
3075
  font-size: 12px;
2759
3076
  font-weight: 700;
2760
- border: 1px solid color-mix(in srgb, var(--xapps-accent, #0f766e) 14%, var(--xapps-border-color, transparent));
3077
+ border: 1px solid
3078
+ var(
3079
+ --xapps-paywall-primary-border,
3080
+ color-mix(in srgb, var(--xapps-accent, #0f766e) 14%, var(--xapps-border-color, transparent))
3081
+ );
2761
3082
  }
2762
3083
  .xapps-xms-plans__badges,
2763
3084
  .xapps-xms-plans__signals {
@@ -2775,13 +3096,25 @@ var monetizationPlansSurfaceStyles = `
2775
3096
  font-size: 12px;
2776
3097
  }
2777
3098
  .xapps-xms-plans__badge {
2778
- background: color-mix(in srgb, var(--xapps-accent, #2563eb) 8%, var(--xapps-surface-bg, #ffffff));
2779
- color: color-mix(in srgb, var(--xapps-accent, #2563eb) 66%, var(--xapps-text-primary, #1d4ed8));
3099
+ background: var(
3100
+ --xapps-paywall-badge-bg,
3101
+ color-mix(in srgb, var(--xapps-accent, #2563eb) 8%, var(--xapps-surface-bg, #ffffff))
3102
+ );
3103
+ color: var(
3104
+ --xapps-paywall-badge-text,
3105
+ color-mix(in srgb, var(--xapps-accent, #2563eb) 66%, var(--xapps-text-primary, #1d4ed8))
3106
+ );
2780
3107
  font-weight: 700;
2781
3108
  }
2782
3109
  .xapps-xms-plans__signal {
2783
- background: color-mix(in srgb, var(--xapps-text-primary, #0f172a) 4%, var(--xapps-surface-bg, #ffffff));
2784
- color: color-mix(in srgb, var(--xapps-text-primary, #0f172a) 42%, var(--xapps-text-secondary, #64748b));
3110
+ background: var(
3111
+ --xapps-paywall-signal-bg,
3112
+ color-mix(in srgb, var(--xapps-text-primary, #0f172a) 4%, var(--xapps-surface-bg, #ffffff))
3113
+ );
3114
+ color: var(
3115
+ --xapps-paywall-signal-text,
3116
+ color-mix(in srgb, var(--xapps-text-primary, #0f172a) 42%, var(--xapps-text-secondary, #64748b))
3117
+ );
2785
3118
  }
2786
3119
  .xapps-xms-plans__action {
2787
3120
  justify-self: start;
@@ -2794,7 +3127,7 @@ var monetizationPlansSurfaceStyles = `
2794
3127
  color-mix(in srgb, var(--xapps-accent, #0f766e) 94%, white),
2795
3128
  color-mix(in srgb, var(--xapps-accent-strong, var(--xapps-accent, #155e75)) 94%, black)
2796
3129
  );
2797
- color: #f8fafc;
3130
+ color: var(--xapps-paywall-action-text, #f8fafc);
2798
3131
  font-weight: 700;
2799
3132
  cursor: pointer;
2800
3133
  box-shadow: 0 10px 22px color-mix(in srgb, var(--xapps-accent, #0f766e) 18%, transparent);
@@ -2805,7 +3138,7 @@ var monetizationPlansSurfaceStyles = `
2805
3138
  }
2806
3139
  .xapps-xms-plans__action:hover,
2807
3140
  .xapps-xms-plans__action:focus-visible {
2808
- color: #f8fafc;
3141
+ color: var(--xapps-paywall-action-text, #f8fafc);
2809
3142
  filter: saturate(1.04) brightness(1.01);
2810
3143
  box-shadow: 0 14px 28px color-mix(in srgb, var(--xapps-accent, #0f766e) 24%, transparent);
2811
3144
  }
@@ -2836,19 +3169,40 @@ var monetizationPlansSurfaceStyles = `
2836
3169
  }
2837
3170
  .xapps-xms-plans__surface-action:hover,
2838
3171
  .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));
3172
+ border-color: var(
3173
+ --xapps-paywall-primary-border,
3174
+ color-mix(in srgb, var(--xapps-accent, #0f766e) 28%, var(--xapps-border-color, transparent))
3175
+ );
3176
+ background: var(
3177
+ --xapps-paywall-primary-bg,
3178
+ color-mix(in srgb, var(--xapps-accent, #0f766e) 7%, var(--xapps-surface-bg, #ffffff))
3179
+ );
3180
+ color: var(
3181
+ --xapps-paywall-primary-text,
3182
+ color-mix(in srgb, var(--xapps-accent, #0f766e) 24%, var(--xapps-text-primary, #0f172a))
3183
+ );
2842
3184
  }
2843
3185
  .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);
3186
+ border-color: var(
3187
+ --xapps-paywall-danger-border,
3188
+ color-mix(in srgb, var(--xapps-danger, #dc2626) 22%, var(--xapps-border-color, transparent))
3189
+ );
3190
+ color: var(--xapps-paywall-danger-text, var(--xapps-danger, #b91c1c));
2846
3191
  }
2847
3192
  .xapps-xms-plans__surface-action[data-variant="danger"]:hover,
2848
3193
  .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);
3194
+ border-color: var(
3195
+ --xapps-paywall-danger-border,
3196
+ color-mix(in srgb, var(--xapps-danger, #dc2626) 34%, var(--xapps-border-color, transparent))
3197
+ );
3198
+ background: var(
3199
+ --xapps-paywall-danger-bg,
3200
+ color-mix(in srgb, var(--xapps-danger, #dc2626) 8%, var(--xapps-surface-bg, #ffffff))
3201
+ );
3202
+ color: var(
3203
+ --xapps-paywall-danger-text,
3204
+ color-mix(in srgb, var(--xapps-danger, #dc2626) 72%, var(--xapps-text-primary, #991b1b))
3205
+ );
2852
3206
  }
2853
3207
  .xapps-xms-plans__surface-action[disabled] {
2854
3208
  cursor: not-allowed;
@@ -2912,7 +3266,8 @@ var monetizationPlansSurfaceStyles = `
2912
3266
  }
2913
3267
  .xapps-xms-plans__history-title {
2914
3268
  margin: 0;
2915
- font: 700 0.92rem/1.1 "IBM Plex Serif", Georgia, serif;
3269
+ font: 700 0.92rem/1.1
3270
+ var(--xapps-display-font, var(--mx-display-font, var(--mx-font-family, "Inter", "Segoe UI", system-ui, -apple-system, sans-serif)));
2916
3271
  }
2917
3272
  .xapps-xms-plans__history-count {
2918
3273
  color: #64748b;
@@ -2978,9 +3333,100 @@ function readHistoryBucket(history, key) {
2978
3333
  items
2979
3334
  };
2980
3335
  }
3336
+ function formatBalanceQuantity(value) {
3337
+ if (!Number.isFinite(value)) return "";
3338
+ const normalized = Math.round(value * 1e4) / 1e4;
3339
+ if (Number.isInteger(normalized)) return String(normalized);
3340
+ return normalized.toFixed(4).replace(/\.?0+$/, "");
3341
+ }
3342
+ function summarizeVirtualCurrencyBalances(input) {
3343
+ const record = readRecord(input) ?? {};
3344
+ const history = readRecord(record.history) ?? record;
3345
+ const walletAccounts = readHistoryBucket(history, "wallet_accounts").items;
3346
+ const accessSnapshots = readHistoryBucket(history, "access_snapshots").items;
3347
+ const aggregates = /* @__PURE__ */ new Map();
3348
+ const upsertBalance = (inputValue) => {
3349
+ const amount = readNumber(inputValue.amount, Number.NaN);
3350
+ if (!Number.isFinite(amount) || Math.abs(amount) < 1e-7) return;
3351
+ const label = formatVirtualCurrencyLabel(inputValue.virtualCurrency, {
3352
+ includeCode: true
3353
+ }) || readString4(inputValue.fallbackUnit) || readString4(inputValue.fallbackKey) || "Balance";
3354
+ const key = formatVirtualCurrencyLabel(inputValue.virtualCurrency, {
3355
+ preferCode: true
3356
+ }) || readString4(inputValue.fallbackKey) || label.toLowerCase();
3357
+ const existing = aggregates.get(key);
3358
+ if (existing) {
3359
+ existing.amount += amount;
3360
+ existing.accountCount += 1;
3361
+ return;
3362
+ }
3363
+ aggregates.set(key, {
3364
+ label,
3365
+ amount,
3366
+ accountCount: 1,
3367
+ virtualCurrency: inputValue.virtualCurrency ?? null,
3368
+ fallbackUnit: readString4(inputValue.fallbackUnit)
3369
+ });
3370
+ };
3371
+ for (const item of walletAccounts) {
3372
+ upsertBalance({
3373
+ amount: item.balance_remaining,
3374
+ virtualCurrency: item.virtual_currency,
3375
+ fallbackUnit: "credits",
3376
+ fallbackKey: item.product_slug || item.id
3377
+ });
3378
+ }
3379
+ if (aggregates.size === 0 && accessSnapshots.length > 0) {
3380
+ for (const item of accessSnapshots) {
3381
+ upsertBalance({
3382
+ amount: item.credits_remaining,
3383
+ virtualCurrency: item.virtual_currency,
3384
+ fallbackUnit: "credits",
3385
+ fallbackKey: item.tier || item.id
3386
+ });
3387
+ }
3388
+ }
3389
+ const balances = Array.from(aggregates.entries()).map(([key, item]) => {
3390
+ const amount = formatBalanceQuantity(item.amount);
3391
+ return {
3392
+ key,
3393
+ label: item.label,
3394
+ amount,
3395
+ amountLabel: formatVirtualCurrencyAmountLabel({
3396
+ amount,
3397
+ virtualCurrency: item.virtualCurrency,
3398
+ fallbackUnit: item.fallbackUnit
3399
+ }) || amount,
3400
+ accountCount: item.accountCount,
3401
+ hasNamedCurrency: hasNamedVirtualCurrency(item.virtualCurrency)
3402
+ };
3403
+ }).sort((left, right) => {
3404
+ const amountDiff = readNumber(right.amount) - readNumber(left.amount);
3405
+ if (Math.abs(amountDiff) > 1e-7) return amountDiff > 0 ? 1 : -1;
3406
+ return left.label.localeCompare(right.label);
3407
+ });
3408
+ return {
3409
+ balances,
3410
+ totalAccounts: walletAccounts.length,
3411
+ totalCurrencies: balances.length,
3412
+ totalNamedCurrencies: balances.filter((item) => item.hasNamedCurrency).length
3413
+ };
3414
+ }
2981
3415
  function readHistoryTitle(item, keys, fallback) {
2982
3416
  for (const key of keys) {
2983
- const value = readString4(item[key]);
3417
+ const segments = key.split(".");
3418
+ let current = item;
3419
+ for (const segment of segments) {
3420
+ const record = readRecord(current);
3421
+ current = record ? record[segment] : void 0;
3422
+ }
3423
+ if (key.startsWith("virtual_currency.")) {
3424
+ const value2 = formatVirtualCurrencyLabel(item.virtual_currency ?? current, {
3425
+ includeCode: true
3426
+ });
3427
+ if (value2) return value2;
3428
+ }
3429
+ const value = readString4(current);
2984
3430
  if (value) return value;
2985
3431
  }
2986
3432
  return fallback;
@@ -2988,7 +3434,25 @@ function readHistoryTitle(item, keys, fallback) {
2988
3434
  function readHistoryMeta(item, keys, locale) {
2989
3435
  const out = [];
2990
3436
  for (const key of keys) {
2991
- const value = key === "settlement_effect_detail" ? formatSettlementEffectDetailLabel(item.settlement_effect, item[key], locale) : key.endsWith("_at") ? formatPlansDateTime(item[key], locale) : readString4(item[key]);
3437
+ const segments = key.split(".");
3438
+ let current = item;
3439
+ for (const segment of segments) {
3440
+ const record = readRecord(current);
3441
+ current = record ? record[segment] : void 0;
3442
+ }
3443
+ const value = key === "settlement_effect_detail" ? formatSettlementEffectDetailLabel(item.settlement_effect, current, locale) : key === "balance_remaining" ? formatVirtualCurrencyAmountLabel({
3444
+ amount: current,
3445
+ virtualCurrency: item.virtual_currency,
3446
+ fallbackUnit: readString4(item.currency)
3447
+ }) : key === "amount" ? formatVirtualCurrencyAmountLabel({
3448
+ amount: current,
3449
+ virtualCurrency: item.virtual_currency,
3450
+ fallbackUnit: readString4(item.currency)
3451
+ }) : key === "credits_remaining" ? formatVirtualCurrencyAmountLabel({
3452
+ amount: current,
3453
+ virtualCurrency: item.virtual_currency,
3454
+ fallbackUnit: "credits"
3455
+ }) : key.endsWith("_at") ? formatPlansDateTime(current, locale) : readString4(current);
2992
3456
  if (value) out.push(formatStateLabel(value, value));
2993
3457
  }
2994
3458
  return out;
@@ -3040,9 +3504,17 @@ function formatSettlementEffectDetailLabel(effect, detail, locale) {
3040
3504
  }
3041
3505
  function buildTimelineHtml(input) {
3042
3506
  if (!input.total) return "";
3507
+ const items = [...input.items].sort((left, right) => {
3508
+ const leftAt = Date.parse(readString4(left.occurred_at));
3509
+ const rightAt = Date.parse(readString4(right.occurred_at));
3510
+ if (Number.isFinite(leftAt) && Number.isFinite(rightAt) && leftAt !== rightAt) {
3511
+ return rightAt - leftAt;
3512
+ }
3513
+ return readString4(right.id).localeCompare(readString4(left.id));
3514
+ });
3043
3515
  return `
3044
3516
  <div class="xapps-xms-plans__timeline">
3045
- ${input.items.map((item) => {
3517
+ ${items.map((item) => {
3046
3518
  const title = readString4(item.title) || readString4(item.id) || formatTimelineBucketLabel(item.bucket, input.locale);
3047
3519
  const when = formatPlansDateTime(item.occurred_at, input.locale);
3048
3520
  const meta = [
@@ -3056,7 +3528,11 @@ function buildTimelineHtml(input) {
3056
3528
  ),
3057
3529
  readString4(item.scope),
3058
3530
  readString4(item.correlation),
3059
- readString4(item.amount) && readString4(item.currency) ? `${readString4(item.amount)} ${readString4(item.currency)}` : readString4(item.amount),
3531
+ formatVirtualCurrencyAmountLabel({
3532
+ amount: item.amount,
3533
+ virtualCurrency: item.virtual_currency,
3534
+ fallbackUnit: readString4(item.currency)
3535
+ }),
3060
3536
  readString4(item.note)
3061
3537
  ].filter(Boolean);
3062
3538
  return `
@@ -3108,32 +3584,6 @@ function buildMonetizationHistorySections(input) {
3108
3584
  const { history, locale } = input;
3109
3585
  const copy = buildXmsSurfaceCopy({ locale });
3110
3586
  return [
3111
- buildHistorySectionHtml({
3112
- title: copy.historyPurchaseIntentsTitle,
3113
- total: readHistoryBucket(history, "purchase_intents").total,
3114
- items: readHistoryBucket(history, "purchase_intents").items,
3115
- locale,
3116
- itemTitleKeys: ["package_slug", "product_slug", "id"],
3117
- itemFallbackTitle: copy.historyPurchaseIntentLabel,
3118
- itemStatusKeys: ["status"],
3119
- itemMetaKeys: ["amount", "currency", "payment_lane", "updated_at"]
3120
- }),
3121
- buildHistorySectionHtml({
3122
- title: copy.historyTransactionsTitle,
3123
- total: readHistoryBucket(history, "transactions").total,
3124
- items: readHistoryBucket(history, "transactions").items,
3125
- locale,
3126
- itemTitleKeys: ["package_slug", "product_slug", "id"],
3127
- itemFallbackTitle: copy.historyTransactionLabel,
3128
- itemStatusKeys: ["status"],
3129
- itemMetaKeys: [
3130
- "amount",
3131
- "currency",
3132
- "settlement_effect",
3133
- "payment_session_id",
3134
- "occurred_at"
3135
- ]
3136
- }),
3137
3587
  buildHistorySectionHtml({
3138
3588
  title: copy.historySubscriptionsTitle,
3139
3589
  total: readHistoryBucket(history, "subscriptions").total,
@@ -3159,30 +3609,46 @@ function buildMonetizationHistorySections(input) {
3159
3609
  total: readHistoryBucket(history, "wallet_accounts").total,
3160
3610
  items: readHistoryBucket(history, "wallet_accounts").items,
3161
3611
  locale,
3162
- itemTitleKeys: ["product_slug", "id"],
3612
+ itemTitleKeys: ["virtual_currency.code", "product_slug", "id"],
3163
3613
  itemFallbackTitle: copy.historyWalletAccountLabel,
3164
3614
  itemStatusKeys: ["status"],
3165
- itemMetaKeys: ["currency", "balance_remaining", "updated_at"]
3615
+ itemMetaKeys: ["balance_remaining", "updated_at"]
3166
3616
  }),
3167
3617
  buildHistorySectionHtml({
3168
3618
  title: copy.historyWalletLedgerTitle,
3169
3619
  total: readHistoryBucket(history, "wallet_ledger").total,
3170
3620
  items: readHistoryBucket(history, "wallet_ledger").items,
3171
3621
  locale,
3172
- itemTitleKeys: ["event_kind", "wallet_product_slug", "id"],
3622
+ itemTitleKeys: ["event_kind", "virtual_currency.code", "wallet_product_slug", "id"],
3173
3623
  itemFallbackTitle: copy.historyWalletLedgerEntryLabel,
3174
3624
  itemStatusKeys: [],
3175
- itemMetaKeys: ["amount", "currency", "settlement_effect", "source_kind", "occurred_at"]
3625
+ itemMetaKeys: ["amount", "settlement_effect", "source_kind", "occurred_at"]
3176
3626
  }),
3177
3627
  buildHistorySectionHtml({
3178
- title: copy.historyAccessSnapshotsTitle,
3179
- total: readHistoryBucket(history, "access_snapshots").total,
3180
- items: readHistoryBucket(history, "access_snapshots").items,
3628
+ title: copy.historyTransactionsTitle,
3629
+ total: readHistoryBucket(history, "transactions").total,
3630
+ items: readHistoryBucket(history, "transactions").items,
3181
3631
  locale,
3182
- itemTitleKeys: ["tier", "id"],
3183
- itemFallbackTitle: copy.historyAccessSnapshotLabel,
3184
- itemStatusKeys: ["entitlement_state"],
3185
- itemMetaKeys: ["balance_state", "credits_remaining", "updated_at"]
3632
+ itemTitleKeys: ["package_slug", "product_slug", "id"],
3633
+ itemFallbackTitle: copy.historyTransactionLabel,
3634
+ itemStatusKeys: ["status"],
3635
+ itemMetaKeys: [
3636
+ "amount",
3637
+ "currency",
3638
+ "settlement_effect",
3639
+ "payment_session_id",
3640
+ "occurred_at"
3641
+ ]
3642
+ }),
3643
+ buildHistorySectionHtml({
3644
+ title: copy.historyPurchaseIntentsTitle,
3645
+ total: readHistoryBucket(history, "purchase_intents").total,
3646
+ items: readHistoryBucket(history, "purchase_intents").items,
3647
+ locale,
3648
+ itemTitleKeys: ["package_slug", "product_slug", "id"],
3649
+ itemFallbackTitle: copy.historyPurchaseIntentLabel,
3650
+ itemStatusKeys: ["status"],
3651
+ itemMetaKeys: ["amount", "currency", "payment_lane", "updated_at"]
3186
3652
  }),
3187
3653
  buildHistorySectionHtml({
3188
3654
  title: copy.historyInvoicesTitle,
@@ -3199,9 +3665,37 @@ function buildMonetizationHistorySections(input) {
3199
3665
  "owner_scope",
3200
3666
  "created_at"
3201
3667
  ]
3668
+ }),
3669
+ buildHistorySectionHtml({
3670
+ title: copy.historyAccessSnapshotsTitle,
3671
+ total: readHistoryBucket(history, "access_snapshots").total,
3672
+ items: readHistoryBucket(history, "access_snapshots").items,
3673
+ locale,
3674
+ itemTitleKeys: ["tier", "id"],
3675
+ itemFallbackTitle: copy.historyAccessSnapshotLabel,
3676
+ itemStatusKeys: ["entitlement_state"],
3677
+ itemMetaKeys: ["balance_state", "credits_remaining", "updated_at"]
3202
3678
  })
3203
3679
  ].filter(Boolean);
3204
3680
  }
3681
+ function buildMonetizationHistoryBalanceSummaryHtml(input) {
3682
+ const { history, locale } = input;
3683
+ const copy = buildXmsSurfaceCopy({ locale });
3684
+ const summary = summarizeVirtualCurrencyBalances(history);
3685
+ if (!summary.balances.length) return "";
3686
+ const summaryTitle = summary.totalNamedCurrencies > 0 ? copy.historyBalanceSummaryTitle : copy.historyCreditSummaryTitle;
3687
+ return `
3688
+ <section class="xapps-xms-plans__card">
3689
+ <h4 class="xapps-xms-plans__section-title">${escapeHtml(summaryTitle)}</h4>
3690
+ <div class="xapps-xms-plans__subtitle">${escapeHtml(copy.historyBalanceSummarySubtitle)}</div>
3691
+ <div class="xapps-xms-plans__badges">
3692
+ ${summary.balances.map(
3693
+ (item) => `<span class="xapps-xms-plans__badge">${escapeHtml(item.amountLabel)}</span>`
3694
+ ).join("")}
3695
+ </div>
3696
+ </section>
3697
+ `;
3698
+ }
3205
3699
  function buildMonetizationHistorySurfaceHtml(input, options = {}) {
3206
3700
  const record = readRecord(input) ?? {};
3207
3701
  const history = readRecord(record.history) ?? record;
@@ -3210,8 +3704,9 @@ function buildMonetizationHistorySurfaceHtml(input, options = {}) {
3210
3704
  const showHeader = options.showHeader !== false;
3211
3705
  const surfaceCopy = buildXmsSurfaceCopy({ locale });
3212
3706
  const historySections = buildMonetizationHistorySections({ history, locale });
3707
+ const balanceSummaryHtml = buildMonetizationHistoryBalanceSummaryHtml({ history, locale });
3213
3708
  const timeline = readHistoryBucket(history, "timeline");
3214
- const hasHistory = timeline.total || historySections.length;
3709
+ const hasHistory = Boolean(timeline.total || historySections.length || balanceSummaryHtml);
3215
3710
  return `
3216
3711
  ${includeStyles ? `<style>${monetizationPlansSurfaceStyles}</style>` : ""}
3217
3712
  <section class="xapps-xms-plans">
@@ -3225,6 +3720,7 @@ function buildMonetizationHistorySurfaceHtml(input, options = {}) {
3225
3720
  </div>` : ""}
3226
3721
  ${readString4(options.notice) ? `<div class="xapps-xms-plans__notice">${escapeHtml(readString4(options.notice))}</div>` : ""}
3227
3722
  ${readString4(options.error) ? `<div class="xapps-xms-plans__error">${escapeHtml(readString4(options.error))}</div>` : ""}
3723
+ ${balanceSummaryHtml}
3228
3724
  ${timeline.total ? `<section class="xapps-xms-plans__card">
3229
3725
  <h4 class="xapps-xms-plans__section-title">${escapeHtml(surfaceCopy.recentTimelineTitle)}</h4>
3230
3726
  <div class="xapps-xms-plans__subtitle">${escapeHtml(surfaceCopy.recentTimelineSubtitle)}</div>
@@ -3247,43 +3743,64 @@ function buildMonetizationHistorySurfaceHtml(input, options = {}) {
3247
3743
  }
3248
3744
  function buildMonetizationPackagePresentation(input) {
3249
3745
  const item = input && typeof input === "object" && !Array.isArray(input) ? input : {};
3746
+ const copy = buildXmsPackageCopy(item.locale);
3250
3747
  const packageKind = readString4(item.packageKind);
3251
3748
  const packageSlug = readLower2(item.packageSlug);
3252
3749
  const metadata = item.metadata && typeof item.metadata === "object" && !Array.isArray(item.metadata) ? item.metadata : {};
3253
3750
  const credits = readPackageCredits(item);
3751
+ const virtualCurrency = readVirtualCurrencyDefinition(item.virtualCurrency) ?? readVirtualCurrencyDefinition(
3752
+ item.productMetadata && typeof item.productMetadata === "object" ? item.productMetadata.virtual_currency : null
3753
+ );
3254
3754
  const moneyLabel = normalizeMoneyLabel(item);
3255
3755
  const offeringPresentation = buildMonetizationOfferingPresentation(item);
3256
- let fitLabel = "General upgrade";
3257
- let summary = "Useful as a general monetization upgrade for this creator scope.";
3756
+ let fitLabel = copy.generalUpgradeFitLabel;
3757
+ let summary = copy.generalUpgradeSummary;
3258
3758
  if (packageKind === "one_time_unlock") {
3259
- fitLabel = "Durable unlock";
3260
- summary = "Best when the feature mainly needs current access without ongoing membership.";
3759
+ fitLabel = copy.durableUnlockFitLabel;
3760
+ summary = copy.durableUnlockSummary;
3261
3761
  } else if (packageKind === "subscription") {
3262
- fitLabel = "Recurring membership";
3263
- summary = "Best when the feature depends on ongoing membership coverage.";
3762
+ fitLabel = copy.recurringMembershipFitLabel;
3763
+ summary = copy.recurringMembershipSummary;
3264
3764
  } else if (packageKind === "credit_pack") {
3265
- fitLabel = "Credit top-up";
3266
- summary = "Best when the feature spends credits for each advanced action.";
3765
+ const unitLabel = normalizeVirtualCurrencyDisplayLabel(
3766
+ formatVirtualCurrencyLabel(virtualCurrency, { includeCode: true })
3767
+ );
3768
+ fitLabel = copy.creditTopUpFitLabel;
3769
+ summary = copy.creditPackFitSummary(unitLabel || "credits");
3267
3770
  } else if (packageSlug.includes("hybrid")) {
3268
- fitLabel = "Hybrid upgrade";
3269
- summary = "Blends access coverage with bundled credits for mixed workflows.";
3771
+ const unitLabel = normalizeVirtualCurrencyDisplayLabel(
3772
+ formatVirtualCurrencyLabel(virtualCurrency, { includeCode: true })
3773
+ );
3774
+ fitLabel = copy.hybridUpgradeFitLabel;
3775
+ summary = copy.hybridPackFitSummary(unitLabel || "credits");
3270
3776
  }
3271
3777
  const signals = [];
3272
3778
  if (readString4(metadata.badge)) {
3273
3779
  signals.push(readString4(metadata.badge));
3274
3780
  }
3275
- if (credits > 0) {
3781
+ if (credits > 0 && virtualCurrency) {
3782
+ signals.push(
3783
+ formatVirtualCurrencyAmountLabel({
3784
+ amount: String(credits),
3785
+ virtualCurrency,
3786
+ fallbackUnit: "credits"
3787
+ })
3788
+ );
3789
+ } else if (credits > 0) {
3276
3790
  signals.push(`${credits} credits`);
3791
+ } else if (virtualCurrency) {
3792
+ signals.push(
3793
+ copy.packageCurrencySignalLabel(
3794
+ formatVirtualCurrencyLabel(virtualCurrency, { includeCode: true })
3795
+ )
3796
+ );
3277
3797
  }
3278
3798
  if (readString4(item.billingPeriod)) {
3279
- signals.push(`billed ${readString4(item.billingPeriod)}`);
3799
+ signals.push(copy.billedSignalLabel(readString4(item.billingPeriod)));
3280
3800
  }
3281
3801
  if (offeringPresentation.offeringLabel) {
3282
3802
  signals.push(offeringPresentation.offeringLabel);
3283
3803
  }
3284
- if (offeringPresentation.placementLabel && offeringPresentation.placementLabel !== "General placement") {
3285
- signals.push(offeringPresentation.placementLabel);
3286
- }
3287
3804
  return {
3288
3805
  fitLabel,
3289
3806
  summary,
@@ -3448,7 +3965,9 @@ function normalizeMoneyLabel(item) {
3448
3965
  const amount = readString4(item.amount);
3449
3966
  const currency = readString4(item.currency);
3450
3967
  const billingPeriod = readString4(item.billingPeriod);
3451
- if (!amount && !currency) return "Price unavailable";
3968
+ if (!amount && !currency) {
3969
+ return buildXmsSurfaceCopy({ locale: item.locale }).priceUnavailableLabel;
3970
+ }
3452
3971
  return `${amount} ${currency}${billingPeriod ? ` / ${billingPeriod}` : ""}`.trim();
3453
3972
  }
3454
3973
  function summarizeXappMonetizationSnapshot(input) {
@@ -3468,7 +3987,7 @@ function summarizeXappMonetizationSnapshot(input) {
3468
3987
  present: lifecycle.present,
3469
3988
  statusLabel: lifecycle.statusLabel || formatStateLabel(currentSubscription?.status),
3470
3989
  tierLabel: formatStateLabel(currentSubscription?.tier),
3471
- coverageLabel: lifecycle.coverageLabel || "Unknown",
3990
+ coverageLabel: lifecycle.coverageLabel || buildXmsSurfaceCopy().unknownLabel,
3472
3991
  coverageReasonLabel: lifecycle.reasonLabel || buildXmsSurfaceCopy().noOverdueRestrictionLabel,
3473
3992
  renewsAt: lifecycle.renewsAt,
3474
3993
  expiresAt: lifecycle.expiresAt || lifecycle.currentPeriodEndsAt,
@@ -3476,8 +3995,11 @@ function summarizeXappMonetizationSnapshot(input) {
3476
3995
  },
3477
3996
  wallet: {
3478
3997
  creditsRemaining: readString4(accessProjection?.credits_remaining) || "0",
3998
+ virtualCurrencyLabel: formatVirtualCurrencyLabel(accessProjection?.virtual_currency, {
3999
+ includeCode: true
4000
+ }),
3479
4001
  balanceStateLabel: formatStateLabel(accessProjection?.balance_state, "unknown"),
3480
- currentAccessLabel: hasEffectiveCoverage({ accessProjection, currentSubscription }) ? "Yes" : "No"
4002
+ currentAccessLabel: hasEffectiveCoverage({ accessProjection, currentSubscription }) ? buildXmsSurfaceCopy().yesLabel : buildXmsSurfaceCopy().noLabel
3481
4003
  }
3482
4004
  };
3483
4005
  }
@@ -3486,6 +4008,19 @@ function summarizeXappMonetizationSnapshot(input) {
3486
4008
  import { useCallback, useEffect as useEffect5, useMemo as useMemo4, useRef, useState as useState3 } from "react";
3487
4009
  import { Link as Link5, useLocation as useLocation3 } from "react-router-dom";
3488
4010
  import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
4011
+ function formatVirtualCurrencyLabel2(input, options) {
4012
+ const record = asRecord(input);
4013
+ const code = readString(record.code);
4014
+ const name = readString(record.name);
4015
+ if (name && code && options?.includeCode) return `${name} (${code})`;
4016
+ return name || code || "";
4017
+ }
4018
+ function formatVirtualCurrencyAmount(value, virtualCurrency) {
4019
+ const amount = readString(value);
4020
+ if (!amount) return "";
4021
+ const currencyLabel = formatVirtualCurrencyLabel2(virtualCurrency);
4022
+ return currencyLabel ? `${amount} ${currencyLabel}` : amount;
4023
+ }
3489
4024
  function useQueryToken3() {
3490
4025
  const loc = useLocation3();
3491
4026
  const qs = new URLSearchParams(loc.search);
@@ -3539,13 +4074,22 @@ function MonetizationPage() {
3539
4074
  const [xappTitle, setXappTitle] = useState3("");
3540
4075
  const visibilityRefreshRef = useRef(0);
3541
4076
  const isEmbedded = typeof window !== "undefined" && window.location.pathname.startsWith("/embed");
4077
+ const overview = useMemo4(
4078
+ () => ({
4079
+ apps: items.length,
4080
+ subscriptions: items.filter((item) => item.hasSubscription).length,
4081
+ namedCurrencies: items.filter((item) => item.hasNamedCurrency).length,
4082
+ balances: items.filter((item) => item.hasBalance).length
4083
+ }),
4084
+ [items]
4085
+ );
3542
4086
  const refresh = useCallback(async () => {
3543
4087
  if (!client.getMyXappMonetization) {
3544
4088
  setError(
3545
4089
  t(
3546
4090
  "activity.unavailable_monetization_title",
3547
4091
  void 0,
3548
- "Monetization is unavailable in this host."
4092
+ "Plans and balances are unavailable in this host."
3549
4093
  )
3550
4094
  );
3551
4095
  setItems([]);
@@ -3593,21 +4137,36 @@ function MonetizationPage() {
3593
4137
  try {
3594
4138
  const next = await Promise.all(
3595
4139
  deduped.map(async (item) => {
3596
- const detail = await client.getCatalogXapp(item.xappId, {
3597
- installationId: item.installationId || null
3598
- });
4140
+ const [detail, state] = await Promise.all([
4141
+ client.getCatalogXapp(item.xappId, {
4142
+ installationId: item.installationId || null
4143
+ }),
4144
+ client.getMyXappMonetization(item.xappId, {
4145
+ installationId: item.installationId || null,
4146
+ locale
4147
+ })
4148
+ ]);
3599
4149
  if (!xappIdFilter && !isMonetizationCandidate(detail)) return null;
3600
- const state = await client.getMyXappMonetization(item.xappId, {
3601
- installationId: item.installationId || null,
3602
- locale
3603
- });
3604
4150
  const summary = summarizeXappMonetizationSnapshot(state);
3605
4151
  const detailRecord = asRecord(detail);
4152
+ const accessProjection = asRecord(asRecord(state).access_projection);
4153
+ const virtualCurrencyLabel = formatVirtualCurrencyLabel2(
4154
+ accessProjection.virtual_currency,
4155
+ {
4156
+ includeCode: true
4157
+ }
4158
+ );
4159
+ const creditsRemainingLabel = formatVirtualCurrencyAmount(
4160
+ accessProjection.credits_remaining,
4161
+ accessProjection.virtual_currency
4162
+ ) || summary.wallet.creditsRemaining || "0";
4163
+ const hasLiveBalance = Boolean(readString(accessProjection.credits_remaining));
4164
+ const hasNamedCurrency = Boolean(virtualCurrencyLabel);
3606
4165
  const title = resolveMarketplaceText(asRecord(detailRecord.manifest).title, locale) || readFirstString(asRecord(detailRecord.xapp).name) || item.xappId;
3607
4166
  const subtitle = resolveMarketplaceText(asRecord(detailRecord.manifest).summary, locale) || resolveMarketplaceText(asRecord(detailRecord.manifest).description, locale) || t(
3608
4167
  "activity.monetization_card_subtitle",
3609
4168
  void 0,
3610
- "Current XMS state, active access, subscriptions, and credits for this app."
4169
+ "Access, plans, and balances for this app."
3611
4170
  );
3612
4171
  return {
3613
4172
  xappId: item.xappId,
@@ -3643,8 +4202,13 @@ function MonetizationPage() {
3643
4202
  "No recurring coverage"
3644
4203
  ),
3645
4204
  renewsAt: summary.currentSubscription.renewsAt || t("activity.monetization_not_scheduled", void 0, "Not scheduled"),
3646
- creditsRemaining: summary.wallet.creditsRemaining || "0",
3647
- balanceState: summary.wallet.balanceStateLabel || t("activity.monetization_balance_unknown", void 0, "unknown")
4205
+ virtualCurrencyLabel,
4206
+ balanceTitle: hasNamedCurrency ? t("activity.monetization_credits_label", void 0, "Balance") : t("xapp.credit_balance_label", void 0, "Credits"),
4207
+ creditsRemaining: creditsRemainingLabel,
4208
+ balanceState: summary.wallet.balanceStateLabel || t("activity.monetization_balance_unknown", void 0, "unknown"),
4209
+ hasSubscription: summary.currentSubscription.present,
4210
+ hasNamedCurrency,
4211
+ hasBalance: Boolean(hasLiveBalance || creditsRemainingLabel)
3648
4212
  };
3649
4213
  })
3650
4214
  );
@@ -3742,7 +4306,7 @@ function MonetizationPage() {
3742
4306
  return suffix ? `?${suffix}` : "";
3743
4307
  })()
3744
4308
  } : null;
3745
- return /* @__PURE__ */ jsxs5("div", { className: `mx-catalog-container ${isEmbedded ? "is-embedded" : ""}`, children: [
4309
+ return /* @__PURE__ */ jsxs5("div", { className: `mx-catalog-container mx-monetization-page ${isEmbedded ? "is-embedded" : ""}`, children: [
3746
4310
  /* @__PURE__ */ jsxs5("div", { className: "mx-breadcrumb", children: [
3747
4311
  /* @__PURE__ */ jsx9(Link5, { to: isEmbedded ? "/" : "/marketplace", children: t("common.marketplace", void 0, "Marketplace") }),
3748
4312
  xappLink && /* @__PURE__ */ jsxs5(Fragment4, { children: [
@@ -3811,40 +4375,100 @@ function MonetizationPage() {
3811
4375
  "."
3812
4376
  ] })
3813
4377
  ] }) : error ? /* @__PURE__ */ jsx9("div", { className: "mx-table-container mx-alert mx-alert-error", children: error }) : null,
3814
- xappIdFilter ? /* @__PURE__ */ jsxs5("div", { className: "mx-subtle-note", children: [
3815
- t("activity.showing_monetization_for_prefix", void 0, "Showing XMS state for"),
4378
+ xappIdFilter ? /* @__PURE__ */ jsx9("div", { className: "mx-table-container mx-subtle-note-card", children: /* @__PURE__ */ jsxs5("div", { className: "mx-subtle-note mx-subtle-note-compact", children: [
4379
+ t(
4380
+ "activity.showing_monetization_for_prefix",
4381
+ void 0,
4382
+ "Showing plans and balances for"
4383
+ ),
3816
4384
  " ",
3817
4385
  /* @__PURE__ */ jsx9("span", { className: "mx-subtle-note-strong", children: xappIdFilter })
3818
- ] }) : /* @__PURE__ */ jsx9("div", { className: "mx-subtle-note", children: showPast ? t(
4386
+ ] }) }) : /* @__PURE__ */ jsx9("div", { className: "mx-table-container mx-subtle-note-card", children: /* @__PURE__ */ jsx9("div", { className: "mx-subtle-note mx-subtle-note-compact", children: showPast ? t(
3819
4387
  "activity.monetization_overview_hint_with_past",
3820
4388
  void 0,
3821
- "Review current and past XMS access, subscriptions, and credits across this subject's apps."
4389
+ "Review current and past plans, subscriptions, and balances across this subject's apps."
3822
4390
  ) : t(
3823
4391
  "activity.monetization_overview_hint",
3824
4392
  void 0,
3825
- "Review current XMS access, subscriptions, and credits across the apps linked to this subject."
3826
- ) }),
3827
- busy ? /* @__PURE__ */ jsx9("div", { className: "mx-table-container", children: t("activity.loading_monetization", void 0, "Loading monetization state...") }) : null,
3828
- !busy && !error && items.length === 0 ? /* @__PURE__ */ jsx9("div", { className: "mx-table-container", children: showPast ? t(
3829
- "activity.no_monetization_history",
3830
- void 0,
3831
- "No monetization history was found for this subject."
3832
- ) : t(
3833
- "activity.no_monetization_current",
4393
+ "Review current plans, subscriptions, and balances across this subject's apps."
4394
+ ) }) }),
4395
+ /* @__PURE__ */ jsx9("section", { className: "mx-table-container mx-monetization-summary-card", children: /* @__PURE__ */ jsxs5("div", { className: "mx-monetization-card-body", children: [
4396
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-head", children: /* @__PURE__ */ jsxs5("div", { children: [
4397
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-kicker", children: t("activity.monetization_title", void 0, "Monetization") }),
4398
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-id", children: t("activity.monetization_summary_title", void 0, "Plans and balances") }),
4399
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-subtitle", children: t(
4400
+ "activity.monetization_summary_subtitle",
4401
+ void 0,
4402
+ "Review active plans, subscriptions, and balances before opening app details or history."
4403
+ ) })
4404
+ ] }) }),
4405
+ /* @__PURE__ */ jsxs5("div", { className: "mx-record-grid", children: [
4406
+ /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
4407
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_summary_apps", void 0, "Apps") }),
4408
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-value is-strong", children: overview.apps })
4409
+ ] }),
4410
+ /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
4411
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_summary_subscriptions", void 0, "Subscriptions") }),
4412
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-value is-strong", children: overview.subscriptions })
4413
+ ] }),
4414
+ /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
4415
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_summary_balances", void 0, "Balances") }),
4416
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-value is-strong", children: overview.balances })
4417
+ ] }),
4418
+ /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
4419
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_summary_currencies", void 0, "Named currencies") }),
4420
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-value is-strong", children: overview.namedCurrencies })
4421
+ ] })
4422
+ ] })
4423
+ ] }) }),
4424
+ busy ? /* @__PURE__ */ jsx9("div", { className: "mx-table-container", children: /* @__PURE__ */ jsx9("div", { className: "mx-loading-center mx-loading-table", children: t(
4425
+ "activity.loading_monetization",
3834
4426
  void 0,
3835
- "No current monetization coverage was found for this subject."
3836
- ) }) : null,
3837
- !busy && items.length > 0 ? /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-stack", children: items.map((item) => /* @__PURE__ */ jsxs5("section", { className: "mx-record-panel mx-record-panel-monetization", children: [
4427
+ "Loading plans, balances, and recent activity..."
4428
+ ) }) }) : null,
4429
+ !busy && !error && items.length === 0 ? /* @__PURE__ */ jsx9("div", { className: "mx-table-container", children: /* @__PURE__ */ jsxs5("div", { className: "mx-empty-catalog", children: [
4430
+ /* @__PURE__ */ jsx9("div", { className: "mx-empty-catalog-icon", children: "\u25CE" }),
4431
+ /* @__PURE__ */ jsx9("div", { className: "mx-empty-catalog-title", children: showPast ? t(
4432
+ "activity.no_monetization_history",
4433
+ void 0,
4434
+ "No plan or balance history was found for this subject."
4435
+ ) : t(
4436
+ "activity.no_monetization_current",
4437
+ void 0,
4438
+ "No current plans or balances were found for this subject."
4439
+ ) }),
4440
+ /* @__PURE__ */ jsx9("div", { className: "mx-empty-catalog-desc", children: showPast ? t(
4441
+ "activity.monetization_overview_hint_with_past",
4442
+ void 0,
4443
+ "Review current and past plans, subscriptions, and balances across this subject's apps."
4444
+ ) : t(
4445
+ "activity.monetization_overview_hint",
4446
+ void 0,
4447
+ "Review current plans, subscriptions, and balances across this subject's apps."
4448
+ ) })
4449
+ ] }) }) : null,
4450
+ !busy && items.length > 0 ? /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-stack", children: items.map((item) => /* @__PURE__ */ jsx9("section", { className: "mx-table-container mx-monetization-activity-card", children: /* @__PURE__ */ jsxs5("div", { className: "mx-monetization-card-body", children: [
3838
4451
  /* @__PURE__ */ jsxs5("div", { className: "mx-record-panel-head", children: [
3839
4452
  /* @__PURE__ */ jsxs5("div", { children: [
3840
4453
  /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-kicker", children: t("activity.monetization", void 0, "Monetization") }),
3841
4454
  /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-id", children: item.title }),
3842
- /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-subtitle", children: item.subtitle })
4455
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-panel-subtitle", children: item.subtitle }),
4456
+ /* @__PURE__ */ jsxs5("div", { className: "mx-monetization-card-badges", children: [
4457
+ /* @__PURE__ */ jsx9("span", { className: "mx-badge mx-badge-warning", children: item.accessLabel }),
4458
+ /* @__PURE__ */ jsx9(
4459
+ "span",
4460
+ {
4461
+ className: `mx-badge ${item.hasSubscription ? "mx-badge-success" : "mx-badge-warning"}`,
4462
+ children: item.subscriptionStatus
4463
+ }
4464
+ ),
4465
+ /* @__PURE__ */ jsx9("span", { className: "mx-tag", children: item.virtualCurrencyLabel || t("xapp.credit_balance_label", void 0, "Credits") })
4466
+ ] })
3843
4467
  ] }),
3844
4468
  /* @__PURE__ */ jsxs5("div", { className: "mx-record-actions mx-record-actions-monetization", children: [
3845
4469
  /* @__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") })
4470
+ /* @__PURE__ */ jsx9(Link5, { to: item.plansHref, className: "mx-btn mx-btn-primary", children: t("activity.monetization_open_plans", void 0, "View plans") }),
4471
+ /* @__PURE__ */ jsx9(Link5, { to: item.historyHref, className: "mx-btn mx-btn-secondary", children: t("activity.monetization_open_history", void 0, "View history") })
3848
4472
  ] }),
3849
4473
  /* @__PURE__ */ jsxs5("div", { className: "mx-action-group", children: [
3850
4474
  /* @__PURE__ */ jsx9(Link5, { to: item.detailHref, className: "mx-btn mx-btn-ghost", children: t("common.view_app_details", void 0, "View app details") }),
@@ -3864,47 +4488,53 @@ function MonetizationPage() {
3864
4488
  })()
3865
4489
  },
3866
4490
  className: "mx-btn mx-btn-ghost",
3867
- children: t("activity.monetization_focus_xapp", void 0, "Focus this app")
4491
+ children: t("activity.monetization_focus_xapp", void 0, "Only this app")
3868
4492
  }
3869
4493
  ) : null
3870
4494
  ] })
3871
4495
  ] })
3872
4496
  ] }),
3873
- /* @__PURE__ */ jsxs5("div", { className: "mx-record-grid", children: [
4497
+ /* @__PURE__ */ jsxs5("div", { className: "mx-record-grid mx-monetization-card-primary-grid", children: [
3874
4498
  /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
3875
- /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_access_label", void 0, "Current access") }),
4499
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_access_label", void 0, "Access") }),
3876
4500
  /* @__PURE__ */ jsx9("div", { className: "mx-record-value is-strong", children: item.accessLabel })
3877
4501
  ] }),
3878
4502
  /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
3879
- /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_plan_label", void 0, "Current plan") }),
4503
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_plan_label", void 0, "Plan") }),
3880
4504
  /* @__PURE__ */ jsx9("div", { className: "mx-record-value is-strong", children: item.tierLabel })
3881
4505
  ] }),
3882
- /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
3883
- /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_credits_label", void 0, "Credits remaining") }),
3884
- /* @__PURE__ */ jsx9("div", { className: "mx-record-value is-strong", children: item.creditsRemaining })
3885
- ] }),
3886
4506
  /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
3887
4507
  /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_subscription_label", void 0, "Subscription") }),
3888
4508
  /* @__PURE__ */ jsx9("div", { className: "mx-record-value", children: item.subscriptionStatus })
3889
4509
  ] }),
3890
4510
  /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
3891
- /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_coverage_label", void 0, "Coverage") }),
3892
- /* @__PURE__ */ jsx9("div", { className: "mx-record-value", children: item.subscriptionCoverage })
4511
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: item.balanceTitle }),
4512
+ /* @__PURE__ */ jsx9("div", { className: "mx-record-value is-strong", children: item.creditsRemaining })
3893
4513
  ] }),
3894
4514
  /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
3895
4515
  /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_renews_at", void 0, "Renews at") }),
3896
4516
  /* @__PURE__ */ jsx9("div", { className: "mx-record-value", children: item.renewsAt })
4517
+ ] })
4518
+ ] }),
4519
+ /* @__PURE__ */ jsxs5("div", { className: "mx-monetization-card-secondary", children: [
4520
+ item.hasNamedCurrency ? /* @__PURE__ */ jsxs5("div", { className: "mx-monetization-card-secondary-row", children: [
4521
+ /* @__PURE__ */ jsx9("span", { className: "mx-monetization-card-secondary-label", children: t("xapp.virtual_currency_label", void 0, "Currency") }),
4522
+ /* @__PURE__ */ jsx9("span", { className: "mx-monetization-card-secondary-value", children: item.virtualCurrencyLabel })
4523
+ ] }) : null,
4524
+ /* @__PURE__ */ jsxs5("div", { className: "mx-monetization-card-secondary-row", children: [
4525
+ /* @__PURE__ */ jsx9("span", { className: "mx-monetization-card-secondary-label", children: t("activity.monetization_coverage_label", void 0, "Renewal state") }),
4526
+ /* @__PURE__ */ jsx9("span", { className: "mx-monetization-card-secondary-value", children: item.subscriptionCoverage })
3897
4527
  ] }),
3898
- /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
3899
- /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_balance_state", void 0, "Balance state") }),
3900
- /* @__PURE__ */ jsx9("div", { className: "mx-record-value", children: item.balanceState })
4528
+ /* @__PURE__ */ jsxs5("div", { className: "mx-monetization-card-secondary-row", children: [
4529
+ /* @__PURE__ */ jsx9("span", { className: "mx-monetization-card-secondary-label", children: t("activity.monetization_balance_state", void 0, "Balance status") }),
4530
+ /* @__PURE__ */ jsx9("span", { className: "mx-monetization-card-secondary-value", children: item.balanceState })
3901
4531
  ] }),
3902
- /* @__PURE__ */ jsxs5("div", { className: "mx-record-field", children: [
3903
- /* @__PURE__ */ jsx9("div", { className: "mx-record-label", children: t("activity.monetization_source_label", void 0, "Source") }),
3904
- /* @__PURE__ */ jsx9("div", { className: "mx-record-value", children: item.sourceLabel })
4532
+ /* @__PURE__ */ jsxs5("div", { className: "mx-monetization-card-secondary-row", children: [
4533
+ /* @__PURE__ */ jsx9("span", { className: "mx-monetization-card-secondary-label", children: t("activity.monetization_source_label", void 0, "Origin") }),
4534
+ /* @__PURE__ */ jsx9("span", { className: "mx-monetization-card-secondary-value", children: item.sourceLabel })
3905
4535
  ] })
3906
4536
  ] })
3907
- ] }, item.xappId)) }) : null
4537
+ ] }) }, item.xappId)) }) : null
3908
4538
  ] });
3909
4539
  }
3910
4540
 
@@ -5124,6 +5754,11 @@ function RequestDetailPage() {
5124
5754
  const isTerminal = status === "COMPLETED" || status === "FAILED";
5125
5755
  const effectiveXappId = readFirstString(requestRecord.xapp_id, xappIdFilter);
5126
5756
  const effectiveXappTitle = resolveMarketplaceText(manifestRecord.title, locale) || readFirstString(requestRecord.xapp_name);
5757
+ const hideVersions = shouldHideMarketplaceVersions({
5758
+ installationPolicy: env?.installationPolicy ?? host.installationPolicy ?? null,
5759
+ installationPolicyResolved: env?.installationPolicyResolved,
5760
+ subjectId: host.subjectId
5761
+ });
5127
5762
  const xappCrumbLabel = effectiveXappTitle || effectiveXappId;
5128
5763
  const isEmbedded = typeof window !== "undefined" && window.location.pathname.startsWith("/embed");
5129
5764
  const marketplaceTo = {
@@ -5594,7 +6229,7 @@ function RequestDetailPage() {
5594
6229
  /* @__PURE__ */ jsx13("h2", { className: "mx-title mx-request-section-title", children: title }),
5595
6230
  /* @__PURE__ */ jsxs9("div", { className: "mx-request-meta-row", children: [
5596
6231
  /* @__PURE__ */ jsx13("span", { children: effectiveXappTitle || "\u2014" }),
5597
- readString(requestRecord.xapp_version) && /* @__PURE__ */ jsxs9(Fragment7, { children: [
6232
+ !hideVersions && readString(requestRecord.xapp_version) && /* @__PURE__ */ jsxs9(Fragment7, { children: [
5598
6233
  /* @__PURE__ */ jsx13("span", { children: "\xB7" }),
5599
6234
  /* @__PURE__ */ jsxs9("span", { children: [
5600
6235
  "v",
@@ -6007,6 +6642,11 @@ function RequestsPage() {
6007
6642
  const [error, setError] = useState7(null);
6008
6643
  const [busy, setBusy] = useState7(true);
6009
6644
  const [xappTitle, setXappTitle] = useState7("");
6645
+ const hideVersions = shouldHideMarketplaceVersions({
6646
+ installationPolicy: env?.installationPolicy ?? host.installationPolicy ?? null,
6647
+ installationPolicyResolved: env?.installationPolicyResolved,
6648
+ subjectId: host.subjectId
6649
+ });
6010
6650
  async function refresh(page = 1) {
6011
6651
  setError(null);
6012
6652
  setBusy(true);
@@ -6173,7 +6813,7 @@ function RequestsPage() {
6173
6813
  /* @__PURE__ */ jsx14("thead", { children: /* @__PURE__ */ jsxs10("tr", { children: [
6174
6814
  /* @__PURE__ */ jsx14("th", { scope: "col", children: t("common.id", void 0, "ID") }),
6175
6815
  /* @__PURE__ */ jsx14("th", { scope: "col", children: t("common.tool", void 0, "Tool") }),
6176
- /* @__PURE__ */ jsx14("th", { scope: "col", children: t("common.version", void 0, "Version") }),
6816
+ !hideVersions && /* @__PURE__ */ jsx14("th", { scope: "col", children: t("common.version", void 0, "Version") }),
6177
6817
  /* @__PURE__ */ jsx14("th", { scope: "col", children: t("common.status", void 0, "Status") }),
6178
6818
  /* @__PURE__ */ jsx14("th", { scope: "col", children: t("common.created", void 0, "Created") })
6179
6819
  ] }) }),
@@ -6233,7 +6873,7 @@ function RequestsPage() {
6233
6873
  ) })
6234
6874
  ] })
6235
6875
  ] }),
6236
- /* @__PURE__ */ jsx14(
6876
+ !hideVersions && /* @__PURE__ */ jsx14(
6237
6877
  "td",
6238
6878
  {
6239
6879
  className: "mx-cell-muted",
@@ -6456,6 +7096,30 @@ function formatDateTime2(value, locale) {
6456
7096
  return parsed.toISOString();
6457
7097
  }
6458
7098
  }
7099
+ function readVirtualCurrencyDefinition2(value) {
7100
+ const record = asRecord6(value);
7101
+ if (!record) return null;
7102
+ const code = readString6(record.code);
7103
+ const name = readString6(record.name);
7104
+ if (!code && !name) return null;
7105
+ return record;
7106
+ }
7107
+ function formatVirtualCurrencyLabel3(value, options) {
7108
+ const record = readVirtualCurrencyDefinition2(value);
7109
+ if (!record) return "";
7110
+ const code = readString6(record.code);
7111
+ const name = readString6(record.name);
7112
+ if (options?.includeCode && name && code && name.toLowerCase() !== code.toLowerCase()) {
7113
+ return `${name} (${code})`;
7114
+ }
7115
+ return name || code;
7116
+ }
7117
+ function formatVirtualCurrencyAmount2(value, virtualCurrency) {
7118
+ const amount = readString6(value);
7119
+ if (!amount) return "";
7120
+ const currencyLabel = formatVirtualCurrencyLabel3(virtualCurrency);
7121
+ return currencyLabel ? `${amount} ${currencyLabel}` : amount;
7122
+ }
6459
7123
  function normalizeUsageCreditSummary(value) {
6460
7124
  const summary = asRecord6(value);
6461
7125
  if (!summary) return null;
@@ -6527,7 +7191,7 @@ function buildMonetizationHookSummaryItems(manifest) {
6527
7191
  );
6528
7192
  baseItems.push({
6529
7193
  slug: "xms_after_payment_completed",
6530
- label: defaultInvoiceRef ? `XMS payment completed \xB7 ${defaultInvoiceRef}` : "XMS payment completed",
7194
+ label: defaultInvoiceRef ? `Payment completed \xB7 ${defaultInvoiceRef}` : "Payment completed",
6531
7195
  trigger: "after:payment_completed",
6532
7196
  headless: true,
6533
7197
  blocking: false,
@@ -6543,7 +7207,7 @@ function buildMonetizationHookSummaryItems(manifest) {
6543
7207
  const invoiceRef = readString6(config.invoice_ref ?? config.invoiceRef);
6544
7208
  baseItems.push({
6545
7209
  slug: `xms_after_payment_completed_${paymentGuardRef}`,
6546
- label: invoiceRef ? `XMS payment completed \xB7 ${paymentGuardRef} \xB7 ${invoiceRef}` : `XMS payment completed \xB7 ${paymentGuardRef}`,
7210
+ label: invoiceRef ? `Payment completed \xB7 ${paymentGuardRef} \xB7 ${invoiceRef}` : `Payment completed \xB7 ${paymentGuardRef}`,
6547
7211
  trigger: "after:payment_completed",
6548
7212
  headless: true,
6549
7213
  blocking: false,
@@ -6613,6 +7277,11 @@ function XappDetailPageContent(props) {
6613
7277
  const installationPolicyResolved = env?.installationPolicyResolved !== false;
6614
7278
  const mutationControlsReady = installationPolicyResolved || !hasSubject || !canMutate;
6615
7279
  const installationPolicy = env?.installationPolicy ?? host.installationPolicy ?? null;
7280
+ const hideVersions = shouldHideMarketplaceVersions({
7281
+ installationPolicy,
7282
+ installationPolicyResolved,
7283
+ subjectId: host.subjectId
7284
+ });
6616
7285
  const [data, setData] = useState8(null);
6617
7286
  const [monetization, setMonetization] = useState8(null);
6618
7287
  const [monetizationHistory, setMonetizationHistory] = useState8(
@@ -7024,6 +7693,25 @@ function XappDetailPageContent(props) {
7024
7693
  () => selectedPaywall ? flattenXappMonetizationPaywallPackages(selectedPaywall) : [],
7025
7694
  [selectedPaywall]
7026
7695
  );
7696
+ const resolvePaywallPackageLabel = useMemo9(() => {
7697
+ const labels = /* @__PURE__ */ new Map();
7698
+ for (const item of selectedPaywallPackageRecords) {
7699
+ const productMetadata = item.productMetadata && typeof item.productMetadata === "object" ? item.productMetadata : {};
7700
+ const label = readString6(item.packageTitle) || readString6(item.productTitle) || readString6(item.productSlug);
7701
+ if (!label) continue;
7702
+ for (const candidate of [
7703
+ item.packageSlug,
7704
+ item.productSlug,
7705
+ productMetadata.access_tier,
7706
+ item.packageId,
7707
+ item.productId
7708
+ ]) {
7709
+ const key = readString6(candidate).trim().toLowerCase();
7710
+ if (key && !labels.has(key)) labels.set(key, label);
7711
+ }
7712
+ }
7713
+ return (value) => labels.get(readString6(value).trim().toLowerCase()) || "";
7714
+ }, [selectedPaywallPackageRecords]);
7027
7715
  useEffect10(() => {
7028
7716
  if (focusedSection !== "plans" || !plansSectionRef.current) return;
7029
7717
  if (typeof plansSectionRef.current.scrollIntoView === "function") {
@@ -7312,7 +8000,9 @@ function XappDetailPageContent(props) {
7312
8000
  const status = readString6(item.status).trim().toLowerCase();
7313
8001
  return status === "active" || status === "grace_period";
7314
8002
  });
7315
- const additiveUnlockLabels = activeAdditiveEntitlements.map((item) => readString6(item.tier) || readString6(item.product_slug)).filter(Boolean).reduce((labels, label) => {
8003
+ const additiveUnlockLabels = activeAdditiveEntitlements.map(
8004
+ (item) => resolvePaywallPackageLabel(item.tier) || resolvePaywallPackageLabel(item.product_slug) || readString6(item.tier) || readString6(item.product_slug)
8005
+ ).filter(Boolean).reduce((labels, label) => {
7316
8006
  if (!labels.includes(label)) labels.push(label);
7317
8007
  return labels;
7318
8008
  }, []);
@@ -7331,6 +8021,7 @@ function XappDetailPageContent(props) {
7331
8021
  true
7332
8022
  );
7333
8023
  const currentTier = readString6(monetizationSubscription?.tier) || readString6(monetizationAccess?.tier);
8024
+ const currentTierLabel = resolvePaywallPackageLabel(currentTier) || currentTier;
7334
8025
  const balanceState = readString6(monetizationAccess?.balance_state);
7335
8026
  const subscriptionStatus = subscriptionLifecycle.statusLabel;
7336
8027
  const subscriptionCoverage = subscriptionLifecycle.coverageLabel;
@@ -7342,14 +8033,27 @@ function XappDetailPageContent(props) {
7342
8033
  const cancelledAt = formatDateTime2(subscriptionLifecycle.cancelledAt, locale);
7343
8034
  const expiresAt = formatDateTime2(subscriptionLifecycle.expiresAt, locale);
7344
8035
  const lifecyclePreviewAt = lifecyclePreviewEnabled ? formatDateTime2(routePreviewAt, locale) : "";
7345
- const creditsRemaining = readString6(monetizationAccess?.credits_remaining);
8036
+ const usageCreditAvailableCount = usageCreditSummary ? Math.max(0, usageCreditSummary.available_count) : null;
8037
+ const creditsRemaining = usageCreditAvailableCount != null ? String(usageCreditAvailableCount) : readString6(monetizationAccess?.credits_remaining);
8038
+ const accessVirtualCurrencyLabel = formatVirtualCurrencyLabel3(
8039
+ monetizationAccess?.virtual_currency,
8040
+ {
8041
+ includeCode: true
8042
+ }
8043
+ );
8044
+ const creditsRemainingLabel = formatVirtualCurrencyAmount2(
8045
+ creditsRemaining,
8046
+ monetizationAccess?.virtual_currency
8047
+ );
8048
+ const hasNamedAccessCurrency = Boolean(accessVirtualCurrencyLabel);
8049
+ const currentCreditBalanceLabel = hasNamedAccessCurrency ? t("xapp.credits_remaining_label", void 0, "Balance") : t("xapp.credit_balance_label", void 0, "Credits");
7346
8050
  const accessState = resolveMarketplaceDefaultAccessState({
7347
8051
  projection: monetizationAccessProjection,
7348
8052
  hasCatalogMonetization,
7349
8053
  availableLabel: t("xapp.access_state_available", void 0, "available")
7350
8054
  });
7351
8055
  const hasMonetizationState = Boolean(
7352
- currentTier || accessState || subscriptionStatus || subscriptionCoverage || subscriptionReason || overdueSince || expiryBoundaryAt || renewsAt || currentPeriodEndsAt || cancelledAt || expiresAt || lifecyclePreviewAt || creditsRemaining || additiveUnlockLabels.length > 0
8056
+ currentTierLabel || accessState || subscriptionStatus || subscriptionCoverage || subscriptionReason || overdueSince || expiryBoundaryAt || renewsAt || currentPeriodEndsAt || cancelledAt || expiresAt || lifecyclePreviewAt || accessVirtualCurrencyLabel || creditsRemaining || additiveUnlockLabels.length > 0
7353
8057
  );
7354
8058
  const manifestScreenshots = Array.isArray(manifest?.screenshots) ? manifest.screenshots.map((shot) => readString6(shot)).filter(Boolean) : [];
7355
8059
  const manifestTags = Array.isArray(manifest?.tags) ? manifest.tags.map((tag) => readString6(tag)).filter(Boolean) : [];
@@ -7362,17 +8066,17 @@ function XappDetailPageContent(props) {
7362
8066
  });
7363
8067
  }
7364
8068
  const currentAccessCard = hasMonetizationState ? /* @__PURE__ */ jsxs11("div", { className: "mx-sidebar-card", children: [
7365
- /* @__PURE__ */ jsx15("h3", { className: "mx-section-title mx-detail-sidebar-title", children: t("xapp.current_access_title", void 0, "Current Access") }),
7366
- currentTier ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
8069
+ /* @__PURE__ */ jsx15("h3", { className: "mx-section-title mx-detail-sidebar-title", children: t("xapp.current_access_title", void 0, "Current access") }),
8070
+ currentTierLabel ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
7367
8071
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.current_plan_label", void 0, "Current plan") }),
7368
- /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: currentTier })
8072
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: currentTierLabel })
7369
8073
  ] }) : null,
7370
8074
  accessState ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
7371
8075
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.access_state_label", void 0, "Access state") }),
7372
8076
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: accessState })
7373
8077
  ] }) : null,
7374
8078
  subscriptionStatus ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
7375
- /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.subscription_status_label", void 0, "Subscription status") }),
8079
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.subscription_status_label", void 0, "Subscription state") }),
7376
8080
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: subscriptionStatus })
7377
8081
  ] }) : null,
7378
8082
  subscriptionCoverage ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
@@ -7411,9 +8115,13 @@ function XappDetailPageContent(props) {
7411
8115
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.lifecycle_preview_at_label", void 0, "Preview as of") }),
7412
8116
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: lifecyclePreviewAt })
7413
8117
  ] }) : null,
8118
+ accessVirtualCurrencyLabel ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
8119
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.virtual_currency_label", void 0, "Currency") }),
8120
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: accessVirtualCurrencyLabel })
8121
+ ] }) : null,
7414
8122
  creditsRemaining ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item", children: [
7415
- /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.credits_remaining_label", void 0, "Credits remaining") }),
7416
- /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: creditsRemaining })
8123
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: currentCreditBalanceLabel }),
8124
+ /* @__PURE__ */ jsx15("span", { className: "mx-meta-value", children: creditsRemainingLabel || creditsRemaining })
7417
8125
  ] }) : null,
7418
8126
  additiveUnlockLabels.length > 0 ? /* @__PURE__ */ jsxs11("div", { className: "mx-meta-item mx-meta-item-top", children: [
7419
8127
  /* @__PURE__ */ jsx15("span", { className: "mx-meta-label", children: t("xapp.add_on_unlocks_label", void 0, "Add-on unlocks") }),
@@ -7422,7 +8130,7 @@ function XappDetailPageContent(props) {
7422
8130
  lifecyclePreviewAt ? /* @__PURE__ */ jsx15("div", { className: "mx-subtle-note", children: t(
7423
8131
  "xapp.lifecycle_preview_hint",
7424
8132
  void 0,
7425
- "Subscription lifecycle is being previewed for the selected time."
8133
+ "Subscription state is being previewed for the selected time."
7426
8134
  ) }) : null,
7427
8135
  subscriptionActionError ? /* @__PURE__ */ jsx15("div", { className: "mx-subtle-note", children: subscriptionActionError }) : null,
7428
8136
  monetizationSubscription?.id && (canRefreshSubscriptionAction && typeof client.refreshMyXappSubscriptionContractState === "function" || canCancelSubscriptionAction && subscriptionLifecycle.canCancel && typeof client.cancelMyXappSubscriptionContract === "function") ? /* @__PURE__ */ jsxs11("div", { className: "mx-detail-actions", children: [
@@ -7452,6 +8160,7 @@ function XappDetailPageContent(props) {
7452
8160
  const plansCard = selectedPaywallRenderModel ? /* @__PURE__ */ jsxs11("div", { className: "mx-sidebar-card", ref: plansSectionRef, children: [
7453
8161
  /* @__PURE__ */ jsx15("h3", { className: "mx-section-title mx-detail-sidebar-title", children: t("xapp.plan_options_title", void 0, "Plans") }),
7454
8162
  /* @__PURE__ */ jsxs11("div", { className: "mx-paywall-card-head", children: [
8163
+ /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-kicker", children: t("xapp.plan_options_title", void 0, "Plans") }),
7455
8164
  /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-title", children: selectedPaywallRenderModel.paywallLabel }),
7456
8165
  selectedPaywallRenderModel.summary ? /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-summary", children: selectedPaywallRenderModel.summary }) : null
7457
8166
  ] }),
@@ -7466,6 +8175,19 @@ function XappDetailPageContent(props) {
7466
8175
  const isCurrentPackage = purchasePolicy.status === "current_recurring_plan";
7467
8176
  const isOwnedAdditive = purchasePolicy.status === "owned_additive_unlock";
7468
8177
  const isAdditiveCompanion = purchasePolicy.transitionKind === "buy_additive_unlock" && subscriptionStatus === "active";
8178
+ const packageActionNote = isOwnedAdditive ? t(
8179
+ "xapp.owned_unlock_note",
8180
+ void 0,
8181
+ "This add-on is already included in the current access."
8182
+ ) : isCurrentPackage ? t(
8183
+ "xapp.current_plan_note",
8184
+ void 0,
8185
+ "This plan is already active for this app."
8186
+ ) : t(
8187
+ "xapp.checkout_hint",
8188
+ void 0,
8189
+ "Checkout opens in a secure hosted payment page managed by the platform."
8190
+ );
7469
8191
  return /* @__PURE__ */ jsxs11(
7470
8192
  "div",
7471
8193
  {
@@ -7490,17 +8212,24 @@ function XappDetailPageContent(props) {
7490
8212
  isAdditiveCompanion ? /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-summary", children: t(
7491
8213
  "xapp.additive_unlock_message",
7492
8214
  void 0,
7493
- "This one-time unlock is additive. It adds access on top of the active recurring membership instead of replacing it."
8215
+ "This one-time unlock is additive. It adds access on top of the active subscription instead of replacing it."
7494
8216
  ) }) : 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
8217
+ /* @__PURE__ */ jsxs11("div", { className: "mx-paywall-card-package-actions", children: [
8218
+ typeof client.prepareMyXappPurchaseIntent === "function" && typeof client.createMyXappPurchasePaymentSession === "function" && hasSubject && canMutate ? /* @__PURE__ */ jsx15(
8219
+ "button",
8220
+ {
8221
+ className: `mx-btn ${purchasePolicy.canPurchase && !checkoutBusyPackageSlug && !isOwnedAdditive && !isCurrentPackage ? "mx-btn-primary" : "mx-btn-secondary"}`,
8222
+ disabled: !purchasePolicy.canPurchase || checkoutBusyPackageSlug === normalizedPackageSlug,
8223
+ onClick: () => void startPackageCheckout(item.packageSlug),
8224
+ 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(
8225
+ "xapp.additive_unlock_action",
8226
+ void 0,
8227
+ "Purchase add-on unlock"
8228
+ ) : t("xapp.checkout_action", void 0, "Start checkout")
8229
+ }
8230
+ ) : null,
8231
+ /* @__PURE__ */ jsx15("div", { className: "mx-paywall-card-package-note", children: packageActionNote })
8232
+ ] })
7504
8233
  ]
7505
8234
  },
7506
8235
  `${item.packageId || item.packageSlug || normalizedPackageSlug}:${index}`
@@ -7520,11 +8249,11 @@ function XappDetailPageContent(props) {
7520
8249
  subtitle: title ? t(
7521
8250
  "xapp.history_route_subtitle",
7522
8251
  { title },
7523
- `Recent purchases, invoices, subscriptions, and credit activity for ${title}.`
8252
+ `Balances, recent activity, and purchases for ${title}.`
7524
8253
  ) : t(
7525
8254
  "xapp.history_route_subtitle_default",
7526
8255
  void 0,
7527
- "Recent purchases, invoices, subscriptions, and credit activity for this app."
8256
+ "Balances, recent activity, and purchases for this app."
7528
8257
  ),
7529
8258
  locale,
7530
8259
  showHeader: false
@@ -7535,7 +8264,15 @@ function XappDetailPageContent(props) {
7535
8264
  if (plansOnlyMode) {
7536
8265
  return /* @__PURE__ */ jsxs11("div", { className: `mx-detail-container ${isEmbedded ? "is-embedded" : ""}`, children: [
7537
8266
  error && /* @__PURE__ */ jsx15("div", { className: "mx-detail-error", children: error }),
7538
- busy && !data ? /* @__PURE__ */ jsx15("div", { className: "mx-sidebar-card mx-detail-empty", "aria-busy": "true", children: t("common.loading", void 0, "Loading...") }) : /* @__PURE__ */ jsxs11("div", { className: `mx-plans-route ${widgetHostedPlansMode ? "is-widget-hosted" : ""}`, children: [
8267
+ busy && !data ? /* @__PURE__ */ jsx15("div", { className: "mx-sidebar-card mx-detail-empty mx-plans-route-empty", "aria-busy": "true", children: /* @__PURE__ */ jsxs11("div", { className: "mx-empty-catalog", children: [
8268
+ /* @__PURE__ */ jsx15("div", { className: "mx-empty-catalog-icon", children: "\u25CE" }),
8269
+ /* @__PURE__ */ jsx15("div", { className: "mx-empty-catalog-title", children: t("xapp.plans_loading_title", void 0, "Loading plans") }),
8270
+ /* @__PURE__ */ jsx15("div", { className: "mx-empty-catalog-desc", children: t(
8271
+ "xapp.plans_loading_desc",
8272
+ void 0,
8273
+ "Preparing published plans, balances, and current access for this app."
8274
+ ) })
8275
+ ] }) }) : /* @__PURE__ */ jsxs11("div", { className: `mx-plans-route ${widgetHostedPlansMode ? "is-widget-hosted" : ""}`, children: [
7539
8276
  !widgetHostedPlansMode ? /* @__PURE__ */ jsxs11("div", { className: "mx-breadcrumb", children: [
7540
8277
  /* @__PURE__ */ jsx15(Link10, { to: marketplaceRootHref, children: t("common.marketplace", void 0, "Marketplace") }),
7541
8278
  /* @__PURE__ */ jsx15("span", { className: "mx-breadcrumb-sep", children: "/" }),
@@ -7548,19 +8285,19 @@ function XappDetailPageContent(props) {
7548
8285
  /* @__PURE__ */ jsx15("div", { className: "mx-plans-route-subtitle", children: routeSurfaceView === "history" ? title ? t(
7549
8286
  "xapp.history_route_subtitle",
7550
8287
  { title },
7551
- `Recent purchases, invoices, subscriptions, and credit activity for ${title}.`
8288
+ `Balances, recent activity, and purchases for ${title}.`
7552
8289
  ) : t(
7553
8290
  "xapp.history_route_subtitle_default",
7554
8291
  void 0,
7555
- "Recent purchases, invoices, subscriptions, and credit activity for this app."
8292
+ "Balances, recent activity, and purchases for this app."
7556
8293
  ) : title ? t(
7557
8294
  "xapp.plans_route_subtitle",
7558
8295
  { title },
7559
- `Current access and published plans for ${title}.`
8296
+ `Access, plans, and balances for ${title}.`
7560
8297
  ) : t(
7561
8298
  "xapp.plans_route_subtitle_default",
7562
8299
  void 0,
7563
- "Current access and published plans for this app."
8300
+ "Access, plans, and balances for this app."
7564
8301
  ) })
7565
8302
  ] }) : null,
7566
8303
  /* @__PURE__ */ jsx15("div", { className: "mx-plans-route-grid", children: /* @__PURE__ */ jsxs11("div", { className: "mx-plans-route-main", children: [
@@ -7571,11 +8308,19 @@ function XappDetailPageContent(props) {
7571
8308
  className: "mx-history-route-surface",
7572
8309
  dangerouslySetInnerHTML: { __html: historySurfaceHtml }
7573
8310
  }
7574
- ) : plansCard || /* @__PURE__ */ jsx15("div", { className: "mx-sidebar-card mx-detail-empty", children: t(
7575
- "xapp.no_plans_available",
7576
- void 0,
7577
- "No published plans are currently available."
7578
- ) })
8311
+ ) : plansCard || /* @__PURE__ */ jsx15("div", { className: "mx-sidebar-card mx-detail-empty mx-plans-route-empty", children: /* @__PURE__ */ jsxs11("div", { className: "mx-empty-catalog", children: [
8312
+ /* @__PURE__ */ jsx15("div", { className: "mx-empty-catalog-icon", children: "\u25CE" }),
8313
+ /* @__PURE__ */ jsx15("div", { className: "mx-empty-catalog-title", children: t(
8314
+ "xapp.no_plans_available",
8315
+ void 0,
8316
+ "No plans are currently available."
8317
+ ) }),
8318
+ /* @__PURE__ */ jsx15("div", { className: "mx-empty-catalog-desc", children: t(
8319
+ "xapp.no_plans_available_desc",
8320
+ void 0,
8321
+ "Published plans will appear here when this app exposes a paywall."
8322
+ ) })
8323
+ ] }) })
7579
8324
  ] }) })
7580
8325
  ] })
7581
8326
  ] });
@@ -7659,7 +8404,7 @@ function XappDetailPageContent(props) {
7659
8404
  description ? /* @__PURE__ */ jsx15("p", { className: "mx-detail-subtitle", children: description }) : null,
7660
8405
  /* @__PURE__ */ jsxs11("div", { className: "mx-detail-meta-row", children: [
7661
8406
  /* @__PURE__ */ jsx15("div", { className: "mx-card-slug", children: xappId }),
7662
- readString6(versionRecord?.version) && /* @__PURE__ */ jsxs11("div", { className: "mx-card-version mx-detail-version-pill", children: [
8407
+ !hideVersions && readString6(versionRecord?.version) && /* @__PURE__ */ jsxs11("div", { className: "mx-card-version mx-detail-version-pill", children: [
7663
8408
  "v",
7664
8409
  readString6(versionRecord?.version)
7665
8410
  ] }),
@@ -9441,7 +10186,7 @@ function useQueryToken11() {
9441
10186
  }
9442
10187
  function PublisherDetailPage() {
9443
10188
  const { publisherSlug = "" } = useParams4();
9444
- const { client, host } = useMarketplace();
10189
+ const { client, host, env } = useMarketplace();
9445
10190
  const { locale, t } = useMarketplaceI18n();
9446
10191
  const loc = useLocation11();
9447
10192
  const token = useQueryToken11();
@@ -9452,6 +10197,11 @@ function PublisherDetailPage() {
9452
10197
  const [items, setItems] = useState11([]);
9453
10198
  const [q, setQ] = useState11("");
9454
10199
  const installationsByXappId = host.getInstallationsByXappId();
10200
+ const hideVersions = shouldHideMarketplaceVersions({
10201
+ installationPolicy: env?.installationPolicy ?? host.installationPolicy ?? null,
10202
+ installationPolicyResolved: env?.installationPolicyResolved,
10203
+ subjectId: host.subjectId
10204
+ });
9455
10205
  async function refresh() {
9456
10206
  if (!publisherSlug) return;
9457
10207
  setBusy(true);
@@ -9604,7 +10354,7 @@ function PublisherDetailPage() {
9604
10354
  /* @__PURE__ */ jsx18("span", { className: "mx-card-installed-badge-dot" }),
9605
10355
  t("common.added", void 0, "Added")
9606
10356
  ] }),
9607
- x.latest_version?.version && /* @__PURE__ */ jsxs14("div", { className: "mx-card-version", children: [
10357
+ !hideVersions && x.latest_version?.version && /* @__PURE__ */ jsxs14("div", { className: "mx-card-version", children: [
9608
10358
  "v",
9609
10359
  x.latest_version.version
9610
10360
  ] })
@@ -9620,7 +10370,7 @@ function PublisherDetailPage() {
9620
10370
  {
9621
10371
  to: detailTo,
9622
10372
  className: "mx-btn mx-btn-ghost mx-btn-sm mx-card-footer-link",
9623
- children: "View details"
10373
+ children: t("catalog.view_details", void 0, "View details")
9624
10374
  }
9625
10375
  ) })
9626
10376
  ] }, x.id);
@@ -9648,6 +10398,223 @@ function MarketplaceApp() {
9648
10398
  /* @__PURE__ */ jsx19(Route, { path: "*", element: /* @__PURE__ */ jsx19(CatalogPage, {}) })
9649
10399
  ] });
9650
10400
  }
10401
+
10402
+ // src/httpMarketplaceClient.ts
10403
+ function readString7(value) {
10404
+ return typeof value === "string" ? value.trim() : "";
10405
+ }
10406
+ function encodeSegment(value) {
10407
+ return encodeURIComponent(String(value || "").trim());
10408
+ }
10409
+ function appendQuery(path, query) {
10410
+ const params = new URLSearchParams();
10411
+ for (const [key, rawValue] of Object.entries(query)) {
10412
+ if (rawValue === null || rawValue === void 0) continue;
10413
+ const value = typeof rawValue === "string" ? rawValue.trim() : typeof rawValue === "number" || typeof rawValue === "boolean" ? String(rawValue) : "";
10414
+ if (!value) continue;
10415
+ params.set(key, value);
10416
+ }
10417
+ const suffix = params.toString();
10418
+ if (!suffix) return path;
10419
+ return path.includes("?") ? `${path}&${suffix}` : `${path}?${suffix}`;
10420
+ }
10421
+ function resolveDefaultLocale(input) {
10422
+ if (typeof input === "function") {
10423
+ return readString7(input()) || null;
10424
+ }
10425
+ return readString7(input) || null;
10426
+ }
10427
+ function createHttpMarketplaceClient(options) {
10428
+ const { getJson, postJson, routes } = options;
10429
+ const supportsSubjectIdQuery = routes.supportsSubjectIdQuery === true;
10430
+ const addSubjectId = (subjectId) => supportsSubjectIdQuery ? { subjectId: readString7(subjectId) || void 0 } : {};
10431
+ return {
10432
+ async listCatalogXapps() {
10433
+ return getJson(routes.catalogListPath);
10434
+ },
10435
+ async getCatalogXapp(xappId, input) {
10436
+ return getJson(
10437
+ appendQuery(`${routes.catalogXappBasePath}/${encodeSegment(xappId)}`, {
10438
+ installationId: readString7(input?.installationId) || void 0
10439
+ })
10440
+ );
10441
+ },
10442
+ async getMyXappMonetization(xappId, input) {
10443
+ const locale = readString7(input?.locale) || resolveDefaultLocale(options.defaultLocale);
10444
+ return getJson(
10445
+ appendQuery(`${routes.myXappsBasePath}/${encodeSegment(xappId)}/monetization`, {
10446
+ ...addSubjectId(input?.subjectId),
10447
+ installationId: readString7(input?.installationId) || void 0,
10448
+ locale: locale || void 0,
10449
+ previewAt: readString7(input?.previewAt) || void 0
10450
+ })
10451
+ );
10452
+ },
10453
+ async cancelMyXappSubscriptionContract(input) {
10454
+ return postJson(
10455
+ appendQuery(
10456
+ `${routes.myXappsBasePath}/${encodeSegment(input.xappId)}/monetization/subscription-contracts/${encodeSegment(input.contractId)}/cancel`,
10457
+ {
10458
+ ...addSubjectId(input?.subjectId),
10459
+ installationId: readString7(input?.installationId) || void 0
10460
+ }
10461
+ ),
10462
+ {}
10463
+ );
10464
+ },
10465
+ async refreshMyXappSubscriptionContractState(input) {
10466
+ return postJson(
10467
+ appendQuery(
10468
+ `${routes.myXappsBasePath}/${encodeSegment(input.xappId)}/monetization/subscription-contracts/${encodeSegment(input.contractId)}/refresh-state`,
10469
+ {
10470
+ ...addSubjectId(input?.subjectId),
10471
+ installationId: readString7(input?.installationId) || void 0
10472
+ }
10473
+ ),
10474
+ {}
10475
+ );
10476
+ },
10477
+ async getMyXappMonetizationHistory(xappId, input) {
10478
+ return getJson(
10479
+ appendQuery(`${routes.myXappsBasePath}/${encodeSegment(xappId)}/monetization/history`, {
10480
+ ...addSubjectId(input?.subjectId),
10481
+ installationId: readString7(input?.installationId) || void 0,
10482
+ limit: typeof input?.limit === "number" && Number.isFinite(input.limit) && input.limit > 0 ? input.limit : void 0
10483
+ })
10484
+ );
10485
+ },
10486
+ async listMyMonetizedXapps(input) {
10487
+ return getJson(
10488
+ appendQuery(routes.myMonetizedXappsPath, {
10489
+ ...addSubjectId(input?.subjectId),
10490
+ currentOnly: typeof input?.currentOnly === "boolean" ? String(input.currentOnly) : void 0
10491
+ })
10492
+ );
10493
+ },
10494
+ async prepareMyXappPurchaseIntent(input) {
10495
+ return postJson(
10496
+ `${routes.myXappsBasePath}/${encodeSegment(input.xappId)}/monetization/purchase-intents/prepare`,
10497
+ {
10498
+ offering_id: input.offeringId,
10499
+ package_id: input.packageId,
10500
+ price_id: input.priceId,
10501
+ ...supportsSubjectIdQuery && readString7(input.subjectId) ? { subject_id: readString7(input.subjectId) } : {},
10502
+ ...readString7(input.installationId) ? { installation_id: readString7(input.installationId) } : {}
10503
+ }
10504
+ );
10505
+ },
10506
+ async createMyXappPurchasePaymentSession(input) {
10507
+ return postJson(
10508
+ `${routes.myXappsBasePath}/${encodeSegment(input.xappId)}/monetization/purchase-intents/${encodeSegment(input.intentId)}/payment-session`,
10509
+ {
10510
+ return_url: input.returnUrl,
10511
+ ...readString7(input.cancelUrl) ? { cancel_url: readString7(input.cancelUrl) } : {},
10512
+ ...readString7(input.pageUrl) ? { page_url: readString7(input.pageUrl) } : {},
10513
+ ...readString7(input.xappsResume) ? { xapps_resume: readString7(input.xappsResume) } : {},
10514
+ ...readString7(input.locale) ? { locale: readString7(input.locale) } : {}
10515
+ }
10516
+ );
10517
+ },
10518
+ async finalizeMyXappPurchasePaymentSession(input) {
10519
+ return postJson(
10520
+ `${routes.myXappsBasePath}/${encodeSegment(input.xappId)}/monetization/purchase-intents/${encodeSegment(input.intentId)}/payment-session/finalize`,
10521
+ {}
10522
+ );
10523
+ },
10524
+ async listMyRequests(input) {
10525
+ return getJson(
10526
+ appendQuery(routes.myRequestsPath, {
10527
+ xappId: readString7(input?.xappId) || void 0,
10528
+ toolName: readString7(input?.toolName) || void 0,
10529
+ page: typeof input?.page === "number" && Number.isFinite(input.page) ? input.page : void 0,
10530
+ pageSize: typeof input?.pageSize === "number" && Number.isFinite(input.pageSize) ? input.pageSize : void 0
10531
+ })
10532
+ );
10533
+ },
10534
+ async getMyRequest(id) {
10535
+ return getJson(`${routes.myRequestsPath}/${encodeSegment(id)}`);
10536
+ },
10537
+ async reconcileMyRequestPayment(input) {
10538
+ return postJson(`${routes.myRequestsPath}/${encodeSegment(input.requestId)}/payment/reconcile`, {
10539
+ ...readString7(input.paymentSessionId) ? { payment_session_id: readString7(input.paymentSessionId) } : {},
10540
+ ...readString7(input.returnUrl) ? { return_url: readString7(input.returnUrl) } : {},
10541
+ ...readString7(input.cancelUrl) ? { cancel_url: readString7(input.cancelUrl) } : {},
10542
+ ...readString7(input.xappsResume) ? { xapps_resume: readString7(input.xappsResume) } : {}
10543
+ });
10544
+ },
10545
+ async listMyPaymentSessions(input) {
10546
+ return getJson(
10547
+ appendQuery(routes.myPaymentSessionsPath, {
10548
+ paymentSessionId: readString7(input?.paymentSessionId) || void 0,
10549
+ xappId: readString7(input?.xappId) || void 0,
10550
+ installationId: readString7(input?.installationId) || void 0,
10551
+ toolName: readString7(input?.toolName) || void 0,
10552
+ status: readString7(input?.status) || void 0,
10553
+ issuer: readString7(input?.issuer) || void 0,
10554
+ createdFrom: readString7(input?.createdFrom) || void 0,
10555
+ createdTo: readString7(input?.createdTo) || void 0,
10556
+ limit: typeof input?.limit === "number" && Number.isFinite(input.limit) ? input.limit : void 0
10557
+ })
10558
+ );
10559
+ },
10560
+ async getMyPaymentSession(id) {
10561
+ return getJson(`${routes.myPaymentSessionsPath}/${encodeSegment(id)}`);
10562
+ },
10563
+ async listMyInvoices(input) {
10564
+ return getJson(
10565
+ appendQuery(routes.myInvoicesPath, {
10566
+ requestId: readString7(input?.requestId) || void 0,
10567
+ paymentSessionId: readString7(input?.paymentSessionId) || void 0,
10568
+ xappId: readString7(input?.xappId) || void 0,
10569
+ installationId: readString7(input?.installationId) || void 0,
10570
+ status: readString7(input?.status) || void 0,
10571
+ ownerScope: readString7(input?.ownerScope) || void 0,
10572
+ search: readString7(input?.search) || void 0,
10573
+ createdFrom: readString7(input?.createdFrom) || void 0,
10574
+ createdTo: readString7(input?.createdTo) || void 0,
10575
+ page: typeof input?.page === "number" && Number.isFinite(input.page) ? input.page : void 0,
10576
+ pageSize: typeof input?.pageSize === "number" && Number.isFinite(input.pageSize) ? input.pageSize : void 0
10577
+ })
10578
+ );
10579
+ },
10580
+ async getMyInvoiceHistory(id) {
10581
+ return getJson(`${routes.myInvoicesPath}/${encodeSegment(id)}/history`);
10582
+ },
10583
+ async listMyNotifications(input) {
10584
+ return getJson(
10585
+ appendQuery(routes.myNotificationsPath, {
10586
+ notificationId: readString7(input?.notificationId) || void 0,
10587
+ status: readString7(input?.status) || void 0,
10588
+ trigger: readString7(input?.trigger) || void 0,
10589
+ xappId: readString7(input?.xappId) || void 0,
10590
+ installationId: readString7(input?.installationId) || void 0,
10591
+ unread: typeof input?.unread === "boolean" ? String(input.unread) : void 0,
10592
+ limit: typeof input?.limit === "number" && Number.isFinite(input.limit) ? input.limit : void 0
10593
+ })
10594
+ );
10595
+ },
10596
+ async markMyNotificationRead(notificationId) {
10597
+ return postJson(`${routes.myNotificationsPath}/${encodeSegment(notificationId)}/read`, {});
10598
+ },
10599
+ async markAllMyNotificationsRead() {
10600
+ return postJson(`${routes.myNotificationsPath}/read-all`, {});
10601
+ },
10602
+ async getWidgetToken(installationId, widgetId) {
10603
+ if (typeof options.getWidgetToken === "function") {
10604
+ return options.getWidgetToken(installationId, widgetId);
10605
+ }
10606
+ if (!routes.widgetTokenPath) {
10607
+ throw new Error("Widget token path is not configured");
10608
+ }
10609
+ return getJson(
10610
+ appendQuery(routes.widgetTokenPath, {
10611
+ installationId,
10612
+ widgetId
10613
+ })
10614
+ );
10615
+ }
10616
+ };
10617
+ }
9651
10618
  export {
9652
10619
  CatalogPage,
9653
10620
  InvoicesPage,
@@ -9661,6 +10628,7 @@ export {
9661
10628
  WidgetView,
9662
10629
  XappDetailPage,
9663
10630
  XappPlansPage,
10631
+ createHttpMarketplaceClient,
9664
10632
  resolveMarketplaceText,
9665
10633
  resolvePaymentLockStateFromGuardSummary,
9666
10634
  useMarketplace,