@feelflow/ffid-sdk 5.2.2 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -979,4 +979,4 @@ interface FFIDCookieLinkProps {
979
979
  }
980
980
  declare function FFIDCookieLink({ children, className, style, id, }: FFIDCookieLinkProps): React.JSX.Element;
981
981
 
982
- export { type GetCategoriesWire as $, ALL_DENIED_EXCEPT_NECESSARY as A, type FFIDConsentMergeWarning as B, CONSENT_COOKIE_MAX_AGE_SEC as C, DEFAULT_CONSENT_ERROR_MESSAGES as D, FFIDConsentMergeWarningSchema as E, type FFIDConsentResult as F, type GetConsentMeWire as G, type FFIDConsentSource as H, FFIDConsentSourceSchema as I, FFIDConsentStateSchema as J, FFIDConsentUpdateSchema as K, FFIDCookieBanner as L, type FFIDCookieBannerClassNames as M, type FFIDCookieBannerProps as N, FFIDCookieLink as O, type PostConsentWire as P, type FFIDCookieLinkProps as Q, FFIDCookiePolicySchema as R, FFIDCookieSettings as S, type FFIDCookieSettingsClassNames as T, type FFIDCookieSettingsProps as U, type FFIDInternalConsentSource as V, FFIDInternalConsentSourceSchema as W, type FFIDPublicConsentSource as X, FFIDPublicConsentSourceSchema as Y, FFID_CONSENT_ERROR_CODES as Z, FFID_CONSENT_NOT_DECIDED_STATE as _, type FFIDConsentState as a, GetCategoriesWireSchema as a0, GetConsentMeWireSchema as a1, type GetDocumentWire as a2, GetDocumentWireSchema as a3, type GtagBridge as a4, type GtagBridgeOptions as a5, type PostConsentRequest as a6, PostConsentRequestSchema as a7, PostConsentWireSchema as a8, type PostSyncRequest as a9, PostSyncRequestSchema as aa, PostSyncWireSchema as ab, PostWithdrawWireSchema as ac, type UseFFIDConsentPreferencesReturn as ad, type UseFFIDConsentReturn as ae, clearConsentDismissalTimestamp as af, clearConsentSessionMirror as ag, createGtagBridge as ah, decodeConsentCookie as ai, deleteConsentCookie as aj, encodeConsentCookie as ak, mapCategoriesToGtagParams as al, readConsentCookie as am, readConsentDismissalTimestamp as an, readConsentSessionMirror as ao, useFFIDConsent as ap, useFFIDConsentPreferences as aq, writeConsentCookie as ar, writeConsentDismissalTimestamp as as, writeConsentSessionMirror as at, type FFIDConsentUpdate as b, type FFIDConsentCategories as c, type FFIDConsentSyncResult as d, type FFIDConsentCategoryMetadata as e, type FFIDCookiePolicy as f, type PostSyncWire as g, type PostWithdrawWire as h, CONSENT_COOKIE_NAME as i, CONSENT_DISMISSAL_TIMESTAMP_KEY as j, CONSENT_SESSION_STORAGE_KEY as k, COOKIE_VERSION as l, DEFAULT_MERGE_WARNING_MESSAGES as m, DeviceIdSchema as n, FFIDAnalyticsProvider as o, type FFIDAnalyticsProviderProps as p, FFIDConsentCategoriesSchema as q, type FFIDConsentCategoryCode as r, FFIDConsentCategoryCodeSchema as s, FFIDConsentCategoryMetadataSchema as t, FFIDConsentContext as u, type FFIDConsentContextValue as v, FFIDConsentError as w, type FFIDConsentErrorCode as x, type FFIDConsentMergeStrategy as y, FFIDConsentMergeStrategySchema as z };
982
+ export { FFID_CONSENT_NOT_DECIDED_STATE as $, ALL_DENIED_EXCEPT_NECESSARY as A, type FFIDConsentMergeWarning as B, CONSENT_COOKIE_MAX_AGE_SEC as C, DEFAULT_CONSENT_ERROR_MESSAGES as D, type FFIDConsentMergeWarningEvent as E, type FFIDConsentResult as F, type GetConsentMeWire as G, FFIDConsentMergeWarningSchema as H, type FFIDConsentSource as I, FFIDConsentSourceSchema as J, FFIDConsentStateSchema as K, FFIDConsentUpdateSchema as L, FFIDCookieBanner as M, type FFIDCookieBannerClassNames as N, type FFIDCookieBannerProps as O, type PostConsentWire as P, FFIDCookieLink as Q, type FFIDCookieLinkProps as R, FFIDCookiePolicySchema as S, FFIDCookieSettings as T, type FFIDCookieSettingsClassNames as U, type FFIDCookieSettingsProps as V, type FFIDInternalConsentSource as W, FFIDInternalConsentSourceSchema as X, type FFIDPublicConsentSource as Y, FFIDPublicConsentSourceSchema as Z, FFID_CONSENT_ERROR_CODES as _, type FFIDConsentState as a, type GetCategoriesWire as a0, GetCategoriesWireSchema as a1, GetConsentMeWireSchema as a2, type GetDocumentWire as a3, GetDocumentWireSchema as a4, type GtagBridge as a5, type GtagBridgeOptions as a6, type PostConsentRequest as a7, PostConsentRequestSchema as a8, PostConsentWireSchema as a9, type PostSyncRequest as aa, PostSyncRequestSchema as ab, PostSyncWireSchema as ac, PostWithdrawWireSchema as ad, type UseFFIDConsentPreferencesReturn as ae, type UseFFIDConsentReturn as af, clearConsentDismissalTimestamp as ag, clearConsentSessionMirror as ah, createGtagBridge as ai, decodeConsentCookie as aj, deleteConsentCookie as ak, encodeConsentCookie as al, mapCategoriesToGtagParams as am, readConsentCookie as an, readConsentDismissalTimestamp as ao, readConsentSessionMirror as ap, useFFIDConsent as aq, useFFIDConsentPreferences as ar, writeConsentCookie as as, writeConsentDismissalTimestamp as at, writeConsentSessionMirror as au, type FFIDConsentUpdate as b, type FFIDConsentCategories as c, type FFIDConsentSyncResult as d, type FFIDConsentCategoryMetadata as e, type FFIDCookiePolicy as f, type PostSyncWire as g, type PostWithdrawWire as h, CONSENT_COOKIE_NAME as i, CONSENT_DISMISSAL_TIMESTAMP_KEY as j, CONSENT_SESSION_STORAGE_KEY as k, COOKIE_VERSION as l, DEFAULT_MERGE_WARNING_MESSAGES as m, DeviceIdSchema as n, FFIDAnalyticsProvider as o, type FFIDAnalyticsProviderProps as p, FFIDConsentCategoriesSchema as q, type FFIDConsentCategoryCode as r, FFIDConsentCategoryCodeSchema as s, FFIDConsentCategoryMetadataSchema as t, FFIDConsentContext as u, type FFIDConsentContextValue as v, FFIDConsentError as w, type FFIDConsentErrorCode as x, type FFIDConsentMergeStrategy as y, FFIDConsentMergeStrategySchema as z };
@@ -979,4 +979,4 @@ interface FFIDCookieLinkProps {
979
979
  }
980
980
  declare function FFIDCookieLink({ children, className, style, id, }: FFIDCookieLinkProps): React.JSX.Element;
981
981
 
982
- export { type GetCategoriesWire as $, ALL_DENIED_EXCEPT_NECESSARY as A, type FFIDConsentMergeWarning as B, CONSENT_COOKIE_MAX_AGE_SEC as C, DEFAULT_CONSENT_ERROR_MESSAGES as D, FFIDConsentMergeWarningSchema as E, type FFIDConsentResult as F, type GetConsentMeWire as G, type FFIDConsentSource as H, FFIDConsentSourceSchema as I, FFIDConsentStateSchema as J, FFIDConsentUpdateSchema as K, FFIDCookieBanner as L, type FFIDCookieBannerClassNames as M, type FFIDCookieBannerProps as N, FFIDCookieLink as O, type PostConsentWire as P, type FFIDCookieLinkProps as Q, FFIDCookiePolicySchema as R, FFIDCookieSettings as S, type FFIDCookieSettingsClassNames as T, type FFIDCookieSettingsProps as U, type FFIDInternalConsentSource as V, FFIDInternalConsentSourceSchema as W, type FFIDPublicConsentSource as X, FFIDPublicConsentSourceSchema as Y, FFID_CONSENT_ERROR_CODES as Z, FFID_CONSENT_NOT_DECIDED_STATE as _, type FFIDConsentState as a, GetCategoriesWireSchema as a0, GetConsentMeWireSchema as a1, type GetDocumentWire as a2, GetDocumentWireSchema as a3, type GtagBridge as a4, type GtagBridgeOptions as a5, type PostConsentRequest as a6, PostConsentRequestSchema as a7, PostConsentWireSchema as a8, type PostSyncRequest as a9, PostSyncRequestSchema as aa, PostSyncWireSchema as ab, PostWithdrawWireSchema as ac, type UseFFIDConsentPreferencesReturn as ad, type UseFFIDConsentReturn as ae, clearConsentDismissalTimestamp as af, clearConsentSessionMirror as ag, createGtagBridge as ah, decodeConsentCookie as ai, deleteConsentCookie as aj, encodeConsentCookie as ak, mapCategoriesToGtagParams as al, readConsentCookie as am, readConsentDismissalTimestamp as an, readConsentSessionMirror as ao, useFFIDConsent as ap, useFFIDConsentPreferences as aq, writeConsentCookie as ar, writeConsentDismissalTimestamp as as, writeConsentSessionMirror as at, type FFIDConsentUpdate as b, type FFIDConsentCategories as c, type FFIDConsentSyncResult as d, type FFIDConsentCategoryMetadata as e, type FFIDCookiePolicy as f, type PostSyncWire as g, type PostWithdrawWire as h, CONSENT_COOKIE_NAME as i, CONSENT_DISMISSAL_TIMESTAMP_KEY as j, CONSENT_SESSION_STORAGE_KEY as k, COOKIE_VERSION as l, DEFAULT_MERGE_WARNING_MESSAGES as m, DeviceIdSchema as n, FFIDAnalyticsProvider as o, type FFIDAnalyticsProviderProps as p, FFIDConsentCategoriesSchema as q, type FFIDConsentCategoryCode as r, FFIDConsentCategoryCodeSchema as s, FFIDConsentCategoryMetadataSchema as t, FFIDConsentContext as u, type FFIDConsentContextValue as v, FFIDConsentError as w, type FFIDConsentErrorCode as x, type FFIDConsentMergeStrategy as y, FFIDConsentMergeStrategySchema as z };
982
+ export { FFID_CONSENT_NOT_DECIDED_STATE as $, ALL_DENIED_EXCEPT_NECESSARY as A, type FFIDConsentMergeWarning as B, CONSENT_COOKIE_MAX_AGE_SEC as C, DEFAULT_CONSENT_ERROR_MESSAGES as D, type FFIDConsentMergeWarningEvent as E, type FFIDConsentResult as F, type GetConsentMeWire as G, FFIDConsentMergeWarningSchema as H, type FFIDConsentSource as I, FFIDConsentSourceSchema as J, FFIDConsentStateSchema as K, FFIDConsentUpdateSchema as L, FFIDCookieBanner as M, type FFIDCookieBannerClassNames as N, type FFIDCookieBannerProps as O, type PostConsentWire as P, FFIDCookieLink as Q, type FFIDCookieLinkProps as R, FFIDCookiePolicySchema as S, FFIDCookieSettings as T, type FFIDCookieSettingsClassNames as U, type FFIDCookieSettingsProps as V, type FFIDInternalConsentSource as W, FFIDInternalConsentSourceSchema as X, type FFIDPublicConsentSource as Y, FFIDPublicConsentSourceSchema as Z, FFID_CONSENT_ERROR_CODES as _, type FFIDConsentState as a, type GetCategoriesWire as a0, GetCategoriesWireSchema as a1, GetConsentMeWireSchema as a2, type GetDocumentWire as a3, GetDocumentWireSchema as a4, type GtagBridge as a5, type GtagBridgeOptions as a6, type PostConsentRequest as a7, PostConsentRequestSchema as a8, PostConsentWireSchema as a9, type PostSyncRequest as aa, PostSyncRequestSchema as ab, PostSyncWireSchema as ac, PostWithdrawWireSchema as ad, type UseFFIDConsentPreferencesReturn as ae, type UseFFIDConsentReturn as af, clearConsentDismissalTimestamp as ag, clearConsentSessionMirror as ah, createGtagBridge as ai, decodeConsentCookie as aj, deleteConsentCookie as ak, encodeConsentCookie as al, mapCategoriesToGtagParams as am, readConsentCookie as an, readConsentDismissalTimestamp as ao, readConsentSessionMirror as ap, useFFIDConsent as aq, useFFIDConsentPreferences as ar, writeConsentCookie as as, writeConsentDismissalTimestamp as at, writeConsentSessionMirror as au, type FFIDConsentUpdate as b, type FFIDConsentCategories as c, type FFIDConsentSyncResult as d, type FFIDConsentCategoryMetadata as e, type FFIDCookiePolicy as f, type PostSyncWire as g, type PostWithdrawWire as h, CONSENT_COOKIE_NAME as i, CONSENT_DISMISSAL_TIMESTAMP_KEY as j, CONSENT_SESSION_STORAGE_KEY as k, COOKIE_VERSION as l, DEFAULT_MERGE_WARNING_MESSAGES as m, DeviceIdSchema as n, FFIDAnalyticsProvider as o, type FFIDAnalyticsProviderProps as p, FFIDConsentCategoriesSchema as q, type FFIDConsentCategoryCode as r, FFIDConsentCategoryCodeSchema as s, FFIDConsentCategoryMetadataSchema as t, FFIDConsentContext as u, type FFIDConsentContextValue as v, FFIDConsentError as w, type FFIDConsentErrorCode as x, type FFIDConsentMergeStrategy as y, FFIDConsentMergeStrategySchema as z };
@@ -1467,6 +1467,34 @@ function FFIDCookieBanner({
1467
1467
  closeBanner,
1468
1468
  error
1469
1469
  } = useFFIDConsent();
1470
+ const [pendingAction, setPendingAction] = useState(null);
1471
+ const isSubmitting = pendingAction !== null;
1472
+ const runBannerSubmit = async (action, submit) => {
1473
+ if (isSubmitting) return;
1474
+ setPendingAction(action);
1475
+ try {
1476
+ const result = await submit();
1477
+ if (!result.ok) setPendingAction(null);
1478
+ } catch (err) {
1479
+ console.error(`[FFIDCookieBanner] ${action} action failed`, err);
1480
+ setPendingAction(null);
1481
+ }
1482
+ };
1483
+ const handleAcceptAll = () => runBannerSubmit("accept-all", acceptAll);
1484
+ const handleAcceptNecessaryOnly = async () => {
1485
+ await runBannerSubmit("necessary-only", acceptNecessaryOnly);
1486
+ };
1487
+ const handleOpenPreferences = async () => {
1488
+ if (isSubmitting) return;
1489
+ setPendingAction("preferences");
1490
+ try {
1491
+ await openPreferences();
1492
+ } catch (err) {
1493
+ console.error("[FFIDCookieBanner] preferences action failed", err);
1494
+ } finally {
1495
+ setPendingAction(null);
1496
+ }
1497
+ };
1470
1498
  if (!isBannerOpen) return null;
1471
1499
  return /* @__PURE__ */ jsxs(
1472
1500
  "div",
@@ -1474,6 +1502,7 @@ function FFIDCookieBanner({
1474
1502
  role: "dialog",
1475
1503
  "aria-modal": "false",
1476
1504
  "aria-label": "Cookie \u540C\u610F",
1505
+ "aria-busy": isSubmitting,
1477
1506
  className: className ?? classNames?.root,
1478
1507
  style: style ?? DEFAULT_STYLE,
1479
1508
  "data-testid": "ffid-cookie-banner",
@@ -1498,12 +1527,17 @@ function FFIDCookieBanner({
1498
1527
  {
1499
1528
  type: "button",
1500
1529
  className: classNames?.primaryButton,
1501
- style: DEFAULT_PRIMARY_STYLE,
1530
+ style: {
1531
+ ...DEFAULT_PRIMARY_STYLE,
1532
+ cursor: isSubmitting ? "wait" : DEFAULT_PRIMARY_STYLE.cursor
1533
+ },
1534
+ disabled: isSubmitting,
1535
+ "aria-disabled": isSubmitting,
1502
1536
  onClick: () => {
1503
- void acceptAll();
1537
+ void handleAcceptAll();
1504
1538
  },
1505
1539
  "data-testid": "ffid-cookie-banner-accept-all",
1506
- children: acceptAllLabel ?? "\u3059\u3079\u3066\u540C\u610F"
1540
+ children: pendingAction === "accept-all" ? "\u4FDD\u5B58\u4E2D..." : acceptAllLabel ?? "\u3059\u3079\u3066\u540C\u610F"
1507
1541
  }
1508
1542
  ),
1509
1543
  /* @__PURE__ */ jsx(
@@ -1511,12 +1545,17 @@ function FFIDCookieBanner({
1511
1545
  {
1512
1546
  type: "button",
1513
1547
  className: classNames?.secondaryButton,
1514
- style: DEFAULT_BUTTON_STYLE,
1548
+ style: {
1549
+ ...DEFAULT_BUTTON_STYLE,
1550
+ cursor: isSubmitting ? "wait" : DEFAULT_BUTTON_STYLE.cursor
1551
+ },
1552
+ disabled: isSubmitting,
1553
+ "aria-disabled": isSubmitting,
1515
1554
  onClick: () => {
1516
- void acceptNecessaryOnly();
1555
+ void handleAcceptNecessaryOnly();
1517
1556
  },
1518
1557
  "data-testid": "ffid-cookie-banner-necessary-only",
1519
- children: necessaryOnlyLabel ?? "\u540C\u610F\u3057\u306A\u3044"
1558
+ children: pendingAction === "necessary-only" ? "\u4FDD\u5B58\u4E2D..." : necessaryOnlyLabel ?? "\u540C\u610F\u3057\u306A\u3044"
1520
1559
  }
1521
1560
  ),
1522
1561
  /* @__PURE__ */ jsx(
@@ -1524,12 +1563,17 @@ function FFIDCookieBanner({
1524
1563
  {
1525
1564
  type: "button",
1526
1565
  className: classNames?.linkButton,
1527
- style: DEFAULT_BUTTON_STYLE,
1566
+ style: {
1567
+ ...DEFAULT_BUTTON_STYLE,
1568
+ cursor: isSubmitting ? "wait" : DEFAULT_BUTTON_STYLE.cursor
1569
+ },
1570
+ disabled: isSubmitting,
1571
+ "aria-disabled": isSubmitting,
1528
1572
  onClick: () => {
1529
- void openPreferences();
1573
+ void handleOpenPreferences();
1530
1574
  },
1531
1575
  "data-testid": "ffid-cookie-banner-preferences",
1532
- children: preferencesLabel ?? "\u8A73\u7D30\u8A2D\u5B9A"
1576
+ children: pendingAction === "preferences" ? "\u8AAD\u307F\u8FBC\u307F\u4E2D..." : preferencesLabel ?? "\u8A73\u7D30\u8A2D\u5B9A"
1533
1577
  }
1534
1578
  ),
1535
1579
  /* @__PURE__ */ jsx(
@@ -1537,7 +1581,12 @@ function FFIDCookieBanner({
1537
1581
  {
1538
1582
  type: "button",
1539
1583
  className: classNames?.closeButton,
1540
- style: DEFAULT_BUTTON_STYLE,
1584
+ style: {
1585
+ ...DEFAULT_BUTTON_STYLE,
1586
+ cursor: isSubmitting ? "wait" : DEFAULT_BUTTON_STYLE.cursor
1587
+ },
1588
+ disabled: isSubmitting,
1589
+ "aria-disabled": isSubmitting,
1541
1590
  onClick: () => {
1542
1591
  closeBanner();
1543
1592
  },
@@ -1590,7 +1639,13 @@ function FFIDCookieSettings({
1590
1639
  }) {
1591
1640
  const { isPreferencesOpen, closePreferences, error } = useFFIDConsent();
1592
1641
  const { state, categoryMetadata, save, withdraw } = useFFIDConsentPreferences();
1642
+ const [pendingAction, setPendingAction] = useState(null);
1643
+ const isSubmittingRef = useRef(false);
1593
1644
  const visible = open ?? isPreferencesOpen;
1645
+ const isSubmitting = pendingAction !== null;
1646
+ useEffect(() => {
1647
+ isSubmittingRef.current = isSubmitting;
1648
+ }, [isSubmitting]);
1594
1649
  const [draft, setDraft] = useState({
1595
1650
  functional: state.categories.functional,
1596
1651
  analytics: state.categories.analytics,
@@ -1607,6 +1662,22 @@ function FFIDCookieSettings({
1607
1662
  state.categories.analytics,
1608
1663
  state.categories.marketing
1609
1664
  ]);
1665
+ const runSettingsSubmit = async (action, submit) => {
1666
+ if (isSubmitting) return;
1667
+ setPendingAction(action);
1668
+ try {
1669
+ const result = await submit();
1670
+ if (result.ok) {
1671
+ closePreferences();
1672
+ return;
1673
+ }
1674
+ } catch (err) {
1675
+ console.error(`[FFIDCookieSettings] ${action} action failed`, err);
1676
+ }
1677
+ setPendingAction(null);
1678
+ };
1679
+ const handleWithdraw = () => runSettingsSubmit("withdraw", withdraw);
1680
+ const handleSave = () => runSettingsSubmit("save", () => save(draft));
1610
1681
  const openerRef = useRef(null);
1611
1682
  const modalRef = useRef(null);
1612
1683
  useEffect(() => {
@@ -1630,6 +1701,7 @@ function FFIDCookieSettings({
1630
1701
  const onKey = (e) => {
1631
1702
  if (e.key === "Escape") {
1632
1703
  e.stopPropagation();
1704
+ if (isSubmittingRef.current) return;
1633
1705
  closePreferences();
1634
1706
  return;
1635
1707
  }
@@ -1665,6 +1737,7 @@ function FFIDCookieSettings({
1665
1737
  className: classNames?.backdrop,
1666
1738
  style: DEFAULT_BACKDROP_STYLE,
1667
1739
  onClick: (e) => {
1740
+ if (isSubmitting) return;
1668
1741
  if (e.target === e.currentTarget) closePreferences();
1669
1742
  },
1670
1743
  "data-testid": "ffid-cookie-settings-backdrop",
@@ -1674,6 +1747,7 @@ function FFIDCookieSettings({
1674
1747
  role: "dialog",
1675
1748
  "aria-modal": "true",
1676
1749
  "aria-label": "Cookie \u8A2D\u5B9A",
1750
+ "aria-busy": isSubmitting,
1677
1751
  className: className ?? classNames?.root,
1678
1752
  style: DEFAULT_MODAL_STYLE,
1679
1753
  "data-testid": "ffid-cookie-settings",
@@ -1697,10 +1771,10 @@ function FFIDCookieSettings({
1697
1771
  {
1698
1772
  type: "checkbox",
1699
1773
  checked,
1700
- disabled: cat.isRequired,
1701
- "aria-disabled": cat.isRequired,
1774
+ disabled: cat.isRequired || isSubmitting,
1775
+ "aria-disabled": cat.isRequired || isSubmitting,
1702
1776
  onChange: (e) => {
1703
- if (cat.isRequired) return;
1777
+ if (cat.isRequired || isSubmitting) return;
1704
1778
  setDraft((d) => ({
1705
1779
  ...d,
1706
1780
  [cat.code]: e.target.checked
@@ -1733,19 +1807,20 @@ function FFIDCookieSettings({
1733
1807
  {
1734
1808
  type: "button",
1735
1809
  className: classNames?.secondaryButton,
1736
- onClick: async () => {
1737
- const result = await withdraw();
1738
- if (result.ok) closePreferences();
1810
+ onClick: () => {
1811
+ void handleWithdraw();
1739
1812
  },
1813
+ disabled: isSubmitting,
1814
+ "aria-disabled": isSubmitting,
1740
1815
  style: {
1741
1816
  padding: "10px 16px",
1742
1817
  borderRadius: "6px",
1743
1818
  border: "1px solid #d1d5db",
1744
1819
  background: "#fff",
1745
- cursor: "pointer"
1820
+ cursor: isSubmitting ? "wait" : "pointer"
1746
1821
  },
1747
1822
  "data-testid": "ffid-cookie-settings-withdraw",
1748
- children: "\u3059\u3079\u3066\u64A4\u56DE"
1823
+ children: pendingAction === "withdraw" ? "\u64A4\u56DE\u4E2D..." : "\u3059\u3079\u3066\u64A4\u56DE"
1749
1824
  }
1750
1825
  ) : null,
1751
1826
  /* @__PURE__ */ jsx(
@@ -1753,20 +1828,21 @@ function FFIDCookieSettings({
1753
1828
  {
1754
1829
  type: "button",
1755
1830
  className: classNames?.primaryButton,
1756
- onClick: async () => {
1757
- const result = await save(draft);
1758
- if (result.ok) closePreferences();
1831
+ onClick: () => {
1832
+ void handleSave();
1759
1833
  },
1834
+ disabled: isSubmitting,
1835
+ "aria-disabled": isSubmitting,
1760
1836
  style: {
1761
1837
  padding: "10px 16px",
1762
1838
  borderRadius: "6px",
1763
1839
  border: "1px solid #111827",
1764
1840
  background: "#111827",
1765
1841
  color: "#fff",
1766
- cursor: "pointer"
1842
+ cursor: isSubmitting ? "wait" : "pointer"
1767
1843
  },
1768
1844
  "data-testid": "ffid-cookie-settings-save",
1769
- children: "\u5909\u66F4\u3092\u4FDD\u5B58"
1845
+ children: pendingAction === "save" ? "\u4FDD\u5B58\u4E2D..." : "\u5909\u66F4\u3092\u4FDD\u5B58"
1770
1846
  }
1771
1847
  )
1772
1848
  ]
@@ -125,6 +125,7 @@ function normalizeUserinfo(raw) {
125
125
  subscription: raw.subscription ? {
126
126
  subscriptionId: raw.subscription.subscription_id ?? null,
127
127
  status: raw.subscription.status ?? null,
128
+ effectiveStatus: raw.subscription.effective_status ?? null,
128
129
  planCode: raw.subscription.plan_code ?? null,
129
130
  seatModel: raw.subscription.seat_model ?? null,
130
131
  memberRole: raw.subscription.member_role ?? null,
@@ -366,6 +367,7 @@ function createVerifyAccessToken(deps) {
366
367
  subscription: {
367
368
  subscription_id: introspectResponse.subscription.subscription_id ?? null,
368
369
  status: introspectResponse.subscription.status,
370
+ effective_status: introspectResponse.subscription.effective_status ?? null,
369
371
  plan_code: introspectResponse.subscription.plan_code,
370
372
  seat_model: introspectResponse.subscription.seat_model,
371
373
  member_role: introspectResponse.subscription.member_role,
@@ -840,7 +842,7 @@ function createProfileMethods(deps) {
840
842
  }
841
843
 
842
844
  // src/client/version-check.ts
843
- var SDK_VERSION = "5.2.2";
845
+ var SDK_VERSION = "5.3.0";
844
846
  var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
845
847
  var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
846
848
  function sdkHeaders() {
@@ -1469,6 +1469,34 @@ function FFIDCookieBanner({
1469
1469
  closeBanner,
1470
1470
  error
1471
1471
  } = useFFIDConsent();
1472
+ const [pendingAction, setPendingAction] = react.useState(null);
1473
+ const isSubmitting = pendingAction !== null;
1474
+ const runBannerSubmit = async (action, submit) => {
1475
+ if (isSubmitting) return;
1476
+ setPendingAction(action);
1477
+ try {
1478
+ const result = await submit();
1479
+ if (!result.ok) setPendingAction(null);
1480
+ } catch (err) {
1481
+ console.error(`[FFIDCookieBanner] ${action} action failed`, err);
1482
+ setPendingAction(null);
1483
+ }
1484
+ };
1485
+ const handleAcceptAll = () => runBannerSubmit("accept-all", acceptAll);
1486
+ const handleAcceptNecessaryOnly = async () => {
1487
+ await runBannerSubmit("necessary-only", acceptNecessaryOnly);
1488
+ };
1489
+ const handleOpenPreferences = async () => {
1490
+ if (isSubmitting) return;
1491
+ setPendingAction("preferences");
1492
+ try {
1493
+ await openPreferences();
1494
+ } catch (err) {
1495
+ console.error("[FFIDCookieBanner] preferences action failed", err);
1496
+ } finally {
1497
+ setPendingAction(null);
1498
+ }
1499
+ };
1472
1500
  if (!isBannerOpen) return null;
1473
1501
  return /* @__PURE__ */ jsxRuntime.jsxs(
1474
1502
  "div",
@@ -1476,6 +1504,7 @@ function FFIDCookieBanner({
1476
1504
  role: "dialog",
1477
1505
  "aria-modal": "false",
1478
1506
  "aria-label": "Cookie \u540C\u610F",
1507
+ "aria-busy": isSubmitting,
1479
1508
  className: className ?? classNames?.root,
1480
1509
  style: style ?? DEFAULT_STYLE,
1481
1510
  "data-testid": "ffid-cookie-banner",
@@ -1500,12 +1529,17 @@ function FFIDCookieBanner({
1500
1529
  {
1501
1530
  type: "button",
1502
1531
  className: classNames?.primaryButton,
1503
- style: DEFAULT_PRIMARY_STYLE,
1532
+ style: {
1533
+ ...DEFAULT_PRIMARY_STYLE,
1534
+ cursor: isSubmitting ? "wait" : DEFAULT_PRIMARY_STYLE.cursor
1535
+ },
1536
+ disabled: isSubmitting,
1537
+ "aria-disabled": isSubmitting,
1504
1538
  onClick: () => {
1505
- void acceptAll();
1539
+ void handleAcceptAll();
1506
1540
  },
1507
1541
  "data-testid": "ffid-cookie-banner-accept-all",
1508
- children: acceptAllLabel ?? "\u3059\u3079\u3066\u540C\u610F"
1542
+ children: pendingAction === "accept-all" ? "\u4FDD\u5B58\u4E2D..." : acceptAllLabel ?? "\u3059\u3079\u3066\u540C\u610F"
1509
1543
  }
1510
1544
  ),
1511
1545
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1513,12 +1547,17 @@ function FFIDCookieBanner({
1513
1547
  {
1514
1548
  type: "button",
1515
1549
  className: classNames?.secondaryButton,
1516
- style: DEFAULT_BUTTON_STYLE,
1550
+ style: {
1551
+ ...DEFAULT_BUTTON_STYLE,
1552
+ cursor: isSubmitting ? "wait" : DEFAULT_BUTTON_STYLE.cursor
1553
+ },
1554
+ disabled: isSubmitting,
1555
+ "aria-disabled": isSubmitting,
1517
1556
  onClick: () => {
1518
- void acceptNecessaryOnly();
1557
+ void handleAcceptNecessaryOnly();
1519
1558
  },
1520
1559
  "data-testid": "ffid-cookie-banner-necessary-only",
1521
- children: necessaryOnlyLabel ?? "\u540C\u610F\u3057\u306A\u3044"
1560
+ children: pendingAction === "necessary-only" ? "\u4FDD\u5B58\u4E2D..." : necessaryOnlyLabel ?? "\u540C\u610F\u3057\u306A\u3044"
1522
1561
  }
1523
1562
  ),
1524
1563
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1526,12 +1565,17 @@ function FFIDCookieBanner({
1526
1565
  {
1527
1566
  type: "button",
1528
1567
  className: classNames?.linkButton,
1529
- style: DEFAULT_BUTTON_STYLE,
1568
+ style: {
1569
+ ...DEFAULT_BUTTON_STYLE,
1570
+ cursor: isSubmitting ? "wait" : DEFAULT_BUTTON_STYLE.cursor
1571
+ },
1572
+ disabled: isSubmitting,
1573
+ "aria-disabled": isSubmitting,
1530
1574
  onClick: () => {
1531
- void openPreferences();
1575
+ void handleOpenPreferences();
1532
1576
  },
1533
1577
  "data-testid": "ffid-cookie-banner-preferences",
1534
- children: preferencesLabel ?? "\u8A73\u7D30\u8A2D\u5B9A"
1578
+ children: pendingAction === "preferences" ? "\u8AAD\u307F\u8FBC\u307F\u4E2D..." : preferencesLabel ?? "\u8A73\u7D30\u8A2D\u5B9A"
1535
1579
  }
1536
1580
  ),
1537
1581
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1539,7 +1583,12 @@ function FFIDCookieBanner({
1539
1583
  {
1540
1584
  type: "button",
1541
1585
  className: classNames?.closeButton,
1542
- style: DEFAULT_BUTTON_STYLE,
1586
+ style: {
1587
+ ...DEFAULT_BUTTON_STYLE,
1588
+ cursor: isSubmitting ? "wait" : DEFAULT_BUTTON_STYLE.cursor
1589
+ },
1590
+ disabled: isSubmitting,
1591
+ "aria-disabled": isSubmitting,
1543
1592
  onClick: () => {
1544
1593
  closeBanner();
1545
1594
  },
@@ -1592,7 +1641,13 @@ function FFIDCookieSettings({
1592
1641
  }) {
1593
1642
  const { isPreferencesOpen, closePreferences, error } = useFFIDConsent();
1594
1643
  const { state, categoryMetadata, save, withdraw } = useFFIDConsentPreferences();
1644
+ const [pendingAction, setPendingAction] = react.useState(null);
1645
+ const isSubmittingRef = react.useRef(false);
1595
1646
  const visible = open ?? isPreferencesOpen;
1647
+ const isSubmitting = pendingAction !== null;
1648
+ react.useEffect(() => {
1649
+ isSubmittingRef.current = isSubmitting;
1650
+ }, [isSubmitting]);
1596
1651
  const [draft, setDraft] = react.useState({
1597
1652
  functional: state.categories.functional,
1598
1653
  analytics: state.categories.analytics,
@@ -1609,6 +1664,22 @@ function FFIDCookieSettings({
1609
1664
  state.categories.analytics,
1610
1665
  state.categories.marketing
1611
1666
  ]);
1667
+ const runSettingsSubmit = async (action, submit) => {
1668
+ if (isSubmitting) return;
1669
+ setPendingAction(action);
1670
+ try {
1671
+ const result = await submit();
1672
+ if (result.ok) {
1673
+ closePreferences();
1674
+ return;
1675
+ }
1676
+ } catch (err) {
1677
+ console.error(`[FFIDCookieSettings] ${action} action failed`, err);
1678
+ }
1679
+ setPendingAction(null);
1680
+ };
1681
+ const handleWithdraw = () => runSettingsSubmit("withdraw", withdraw);
1682
+ const handleSave = () => runSettingsSubmit("save", () => save(draft));
1612
1683
  const openerRef = react.useRef(null);
1613
1684
  const modalRef = react.useRef(null);
1614
1685
  react.useEffect(() => {
@@ -1632,6 +1703,7 @@ function FFIDCookieSettings({
1632
1703
  const onKey = (e) => {
1633
1704
  if (e.key === "Escape") {
1634
1705
  e.stopPropagation();
1706
+ if (isSubmittingRef.current) return;
1635
1707
  closePreferences();
1636
1708
  return;
1637
1709
  }
@@ -1667,6 +1739,7 @@ function FFIDCookieSettings({
1667
1739
  className: classNames?.backdrop,
1668
1740
  style: DEFAULT_BACKDROP_STYLE,
1669
1741
  onClick: (e) => {
1742
+ if (isSubmitting) return;
1670
1743
  if (e.target === e.currentTarget) closePreferences();
1671
1744
  },
1672
1745
  "data-testid": "ffid-cookie-settings-backdrop",
@@ -1676,6 +1749,7 @@ function FFIDCookieSettings({
1676
1749
  role: "dialog",
1677
1750
  "aria-modal": "true",
1678
1751
  "aria-label": "Cookie \u8A2D\u5B9A",
1752
+ "aria-busy": isSubmitting,
1679
1753
  className: className ?? classNames?.root,
1680
1754
  style: DEFAULT_MODAL_STYLE,
1681
1755
  "data-testid": "ffid-cookie-settings",
@@ -1699,10 +1773,10 @@ function FFIDCookieSettings({
1699
1773
  {
1700
1774
  type: "checkbox",
1701
1775
  checked,
1702
- disabled: cat.isRequired,
1703
- "aria-disabled": cat.isRequired,
1776
+ disabled: cat.isRequired || isSubmitting,
1777
+ "aria-disabled": cat.isRequired || isSubmitting,
1704
1778
  onChange: (e) => {
1705
- if (cat.isRequired) return;
1779
+ if (cat.isRequired || isSubmitting) return;
1706
1780
  setDraft((d) => ({
1707
1781
  ...d,
1708
1782
  [cat.code]: e.target.checked
@@ -1735,19 +1809,20 @@ function FFIDCookieSettings({
1735
1809
  {
1736
1810
  type: "button",
1737
1811
  className: classNames?.secondaryButton,
1738
- onClick: async () => {
1739
- const result = await withdraw();
1740
- if (result.ok) closePreferences();
1812
+ onClick: () => {
1813
+ void handleWithdraw();
1741
1814
  },
1815
+ disabled: isSubmitting,
1816
+ "aria-disabled": isSubmitting,
1742
1817
  style: {
1743
1818
  padding: "10px 16px",
1744
1819
  borderRadius: "6px",
1745
1820
  border: "1px solid #d1d5db",
1746
1821
  background: "#fff",
1747
- cursor: "pointer"
1822
+ cursor: isSubmitting ? "wait" : "pointer"
1748
1823
  },
1749
1824
  "data-testid": "ffid-cookie-settings-withdraw",
1750
- children: "\u3059\u3079\u3066\u64A4\u56DE"
1825
+ children: pendingAction === "withdraw" ? "\u64A4\u56DE\u4E2D..." : "\u3059\u3079\u3066\u64A4\u56DE"
1751
1826
  }
1752
1827
  ) : null,
1753
1828
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1755,20 +1830,21 @@ function FFIDCookieSettings({
1755
1830
  {
1756
1831
  type: "button",
1757
1832
  className: classNames?.primaryButton,
1758
- onClick: async () => {
1759
- const result = await save(draft);
1760
- if (result.ok) closePreferences();
1833
+ onClick: () => {
1834
+ void handleSave();
1761
1835
  },
1836
+ disabled: isSubmitting,
1837
+ "aria-disabled": isSubmitting,
1762
1838
  style: {
1763
1839
  padding: "10px 16px",
1764
1840
  borderRadius: "6px",
1765
1841
  border: "1px solid #111827",
1766
1842
  background: "#111827",
1767
1843
  color: "#fff",
1768
- cursor: "pointer"
1844
+ cursor: isSubmitting ? "wait" : "pointer"
1769
1845
  },
1770
1846
  "data-testid": "ffid-cookie-settings-save",
1771
- children: "\u5909\u66F4\u3092\u4FDD\u5B58"
1847
+ children: pendingAction === "save" ? "\u4FDD\u5B58\u4E2D..." : "\u5909\u66F4\u3092\u4FDD\u5B58"
1772
1848
  }
1773
1849
  )
1774
1850
  ]
@@ -123,6 +123,7 @@ function normalizeUserinfo(raw) {
123
123
  subscription: raw.subscription ? {
124
124
  subscriptionId: raw.subscription.subscription_id ?? null,
125
125
  status: raw.subscription.status ?? null,
126
+ effectiveStatus: raw.subscription.effective_status ?? null,
126
127
  planCode: raw.subscription.plan_code ?? null,
127
128
  seatModel: raw.subscription.seat_model ?? null,
128
129
  memberRole: raw.subscription.member_role ?? null,
@@ -364,6 +365,7 @@ function createVerifyAccessToken(deps) {
364
365
  subscription: {
365
366
  subscription_id: introspectResponse.subscription.subscription_id ?? null,
366
367
  status: introspectResponse.subscription.status,
368
+ effective_status: introspectResponse.subscription.effective_status ?? null,
367
369
  plan_code: introspectResponse.subscription.plan_code,
368
370
  seat_model: introspectResponse.subscription.seat_model,
369
371
  member_role: introspectResponse.subscription.member_role,
@@ -838,7 +840,7 @@ function createProfileMethods(deps) {
838
840
  }
839
841
 
840
842
  // src/client/version-check.ts
841
- var SDK_VERSION = "5.2.2";
843
+ var SDK_VERSION = "5.3.0";
842
844
  var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
843
845
  var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
844
846
  function sdkHeaders() {
@@ -1,34 +1,34 @@
1
1
  'use strict';
2
2
 
3
- var chunkIVIUDNGA_cjs = require('../chunk-IVIUDNGA.cjs');
3
+ var chunkJSMMSHTG_cjs = require('../chunk-JSMMSHTG.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "FFIDAnnouncementBadge", {
8
8
  enumerable: true,
9
- get: function () { return chunkIVIUDNGA_cjs.FFIDAnnouncementBadge; }
9
+ get: function () { return chunkJSMMSHTG_cjs.FFIDAnnouncementBadge; }
10
10
  });
11
11
  Object.defineProperty(exports, "FFIDAnnouncementList", {
12
12
  enumerable: true,
13
- get: function () { return chunkIVIUDNGA_cjs.FFIDAnnouncementList; }
13
+ get: function () { return chunkJSMMSHTG_cjs.FFIDAnnouncementList; }
14
14
  });
15
15
  Object.defineProperty(exports, "FFIDInquiryForm", {
16
16
  enumerable: true,
17
- get: function () { return chunkIVIUDNGA_cjs.FFIDInquiryForm; }
17
+ get: function () { return chunkJSMMSHTG_cjs.FFIDInquiryForm; }
18
18
  });
19
19
  Object.defineProperty(exports, "FFIDLoginButton", {
20
20
  enumerable: true,
21
- get: function () { return chunkIVIUDNGA_cjs.FFIDLoginButton; }
21
+ get: function () { return chunkJSMMSHTG_cjs.FFIDLoginButton; }
22
22
  });
23
23
  Object.defineProperty(exports, "FFIDOrganizationSwitcher", {
24
24
  enumerable: true,
25
- get: function () { return chunkIVIUDNGA_cjs.FFIDOrganizationSwitcher; }
25
+ get: function () { return chunkJSMMSHTG_cjs.FFIDOrganizationSwitcher; }
26
26
  });
27
27
  Object.defineProperty(exports, "FFIDSubscriptionBadge", {
28
28
  enumerable: true,
29
- get: function () { return chunkIVIUDNGA_cjs.FFIDSubscriptionBadge; }
29
+ get: function () { return chunkJSMMSHTG_cjs.FFIDSubscriptionBadge; }
30
30
  });
31
31
  Object.defineProperty(exports, "FFIDUserMenu", {
32
32
  enumerable: true,
33
- get: function () { return chunkIVIUDNGA_cjs.FFIDUserMenu; }
33
+ get: function () { return chunkJSMMSHTG_cjs.FFIDUserMenu; }
34
34
  });
@@ -1,3 +1,3 @@
1
- export { S as FFIDAnnouncementBadge, av as FFIDAnnouncementBadgeClassNames, aw as FFIDAnnouncementBadgeProps, T as FFIDAnnouncementList, ax as FFIDAnnouncementListClassNames, ay as FFIDAnnouncementListProps, a0 as FFIDInquiryForm, a1 as FFIDInquiryFormCategoryItem, a2 as FFIDInquiryFormClassNames, a3 as FFIDInquiryFormLegalLayout, a4 as FFIDInquiryFormOrganization, a5 as FFIDInquiryFormPlaceholderContext, a6 as FFIDInquiryFormPrefill, a7 as FFIDInquiryFormProps, a8 as FFIDInquiryFormSubmitData, a9 as FFIDInquiryFormSubmitResult, ab as FFIDLoginButton, az as FFIDLoginButtonProps, ah as FFIDOrganizationSwitcher, aA as FFIDOrganizationSwitcherClassNames, aB as FFIDOrganizationSwitcherProps, am as FFIDSubscriptionBadge, aC as FFIDSubscriptionBadgeClassNames, aD as FFIDSubscriptionBadgeProps, ao as FFIDUserMenu, aE as FFIDUserMenuClassNames, aF as FFIDUserMenuProps } from '../index-CInGR4I9.cjs';
1
+ export { S as FFIDAnnouncementBadge, av as FFIDAnnouncementBadgeClassNames, aw as FFIDAnnouncementBadgeProps, T as FFIDAnnouncementList, ax as FFIDAnnouncementListClassNames, ay as FFIDAnnouncementListProps, a0 as FFIDInquiryForm, a1 as FFIDInquiryFormCategoryItem, a2 as FFIDInquiryFormClassNames, a3 as FFIDInquiryFormLegalLayout, a4 as FFIDInquiryFormOrganization, a5 as FFIDInquiryFormPlaceholderContext, a6 as FFIDInquiryFormPrefill, a7 as FFIDInquiryFormProps, a8 as FFIDInquiryFormSubmitData, a9 as FFIDInquiryFormSubmitResult, ab as FFIDLoginButton, az as FFIDLoginButtonProps, ah as FFIDOrganizationSwitcher, aA as FFIDOrganizationSwitcherClassNames, aB as FFIDOrganizationSwitcherProps, am as FFIDSubscriptionBadge, aC as FFIDSubscriptionBadgeClassNames, aD as FFIDSubscriptionBadgeProps, ao as FFIDUserMenu, aE as FFIDUserMenuClassNames, aF as FFIDUserMenuProps } from '../index-Iop5EM8B.cjs';
2
2
  import 'react/jsx-runtime';
3
3
  import 'react';
@@ -1,3 +1,3 @@
1
- export { S as FFIDAnnouncementBadge, av as FFIDAnnouncementBadgeClassNames, aw as FFIDAnnouncementBadgeProps, T as FFIDAnnouncementList, ax as FFIDAnnouncementListClassNames, ay as FFIDAnnouncementListProps, a0 as FFIDInquiryForm, a1 as FFIDInquiryFormCategoryItem, a2 as FFIDInquiryFormClassNames, a3 as FFIDInquiryFormLegalLayout, a4 as FFIDInquiryFormOrganization, a5 as FFIDInquiryFormPlaceholderContext, a6 as FFIDInquiryFormPrefill, a7 as FFIDInquiryFormProps, a8 as FFIDInquiryFormSubmitData, a9 as FFIDInquiryFormSubmitResult, ab as FFIDLoginButton, az as FFIDLoginButtonProps, ah as FFIDOrganizationSwitcher, aA as FFIDOrganizationSwitcherClassNames, aB as FFIDOrganizationSwitcherProps, am as FFIDSubscriptionBadge, aC as FFIDSubscriptionBadgeClassNames, aD as FFIDSubscriptionBadgeProps, ao as FFIDUserMenu, aE as FFIDUserMenuClassNames, aF as FFIDUserMenuProps } from '../index-CInGR4I9.js';
1
+ export { S as FFIDAnnouncementBadge, av as FFIDAnnouncementBadgeClassNames, aw as FFIDAnnouncementBadgeProps, T as FFIDAnnouncementList, ax as FFIDAnnouncementListClassNames, ay as FFIDAnnouncementListProps, a0 as FFIDInquiryForm, a1 as FFIDInquiryFormCategoryItem, a2 as FFIDInquiryFormClassNames, a3 as FFIDInquiryFormLegalLayout, a4 as FFIDInquiryFormOrganization, a5 as FFIDInquiryFormPlaceholderContext, a6 as FFIDInquiryFormPrefill, a7 as FFIDInquiryFormProps, a8 as FFIDInquiryFormSubmitData, a9 as FFIDInquiryFormSubmitResult, ab as FFIDLoginButton, az as FFIDLoginButtonProps, ah as FFIDOrganizationSwitcher, aA as FFIDOrganizationSwitcherClassNames, aB as FFIDOrganizationSwitcherProps, am as FFIDSubscriptionBadge, aC as FFIDSubscriptionBadgeClassNames, aD as FFIDSubscriptionBadgeProps, ao as FFIDUserMenu, aE as FFIDUserMenuClassNames, aF as FFIDUserMenuProps } from '../index-Iop5EM8B.js';
2
2
  import 'react/jsx-runtime';
3
3
  import 'react';
@@ -1 +1 @@
1
- export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-GZP7ZUG7.js';
1
+ export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-WI6KNKLQ.js';