@pollinations/ui 0.1.0-alpha.0 → 0.1.0-alpha.1

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.
Files changed (64) hide show
  1. package/README.md +28 -65
  2. package/dist/{Chip-SM52sUbZ.d.cts → Chip-CQCq34kS.d.cts} +1 -1
  3. package/dist/{Chip-C5impfYd.d.ts → Chip-Cj4xG7Te.d.ts} +1 -1
  4. package/dist/{compositions/app-user.cjs → app-user-menu/sdk.cjs} +148 -148
  5. package/dist/app-user-menu/sdk.cjs.map +1 -0
  6. package/dist/{compositions/app-user.js → app-user-menu/sdk.js} +127 -127
  7. package/dist/app-user-menu/sdk.js.map +1 -0
  8. package/dist/app.css +94 -3
  9. package/dist/auth/index.cjs +2 -2
  10. package/dist/auth/index.cjs.map +1 -1
  11. package/dist/auth/index.js +2 -2
  12. package/dist/auth/index.js.map +1 -1
  13. package/dist/{models → gen}/index.cjs +40 -71
  14. package/dist/gen/index.cjs.map +1 -0
  15. package/dist/gen/index.d.cts +35 -0
  16. package/dist/gen/index.d.ts +35 -0
  17. package/dist/{models → gen}/index.js +31 -66
  18. package/dist/gen/index.js.map +1 -0
  19. package/dist/index.cjs +1594 -1142
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +268 -178
  22. package/dist/index.d.ts +268 -178
  23. package/dist/index.js +1581 -1134
  24. package/dist/index.js.map +1 -1
  25. package/dist/styles.css +1 -1
  26. package/dist/theme-jRPPBmld.d.cts +20 -0
  27. package/dist/theme-jRPPBmld.d.ts +20 -0
  28. package/dist/wallet/index.cjs +4 -4
  29. package/dist/wallet/index.cjs.map +1 -1
  30. package/dist/wallet/index.d.cts +2 -2
  31. package/dist/wallet/index.d.ts +2 -2
  32. package/dist/wallet/index.js +4 -4
  33. package/dist/wallet/index.js.map +1 -1
  34. package/package.json +9 -24
  35. package/dist/Button-BvLF_Km2.d.cts +0 -26
  36. package/dist/Button-DQAZzvyQ.d.ts +0 -26
  37. package/dist/auth/sdk.cjs +0 -221
  38. package/dist/auth/sdk.cjs.map +0 -1
  39. package/dist/auth/sdk.d.cts +0 -53
  40. package/dist/auth/sdk.d.ts +0 -53
  41. package/dist/auth/sdk.js +0 -188
  42. package/dist/auth/sdk.js.map +0 -1
  43. package/dist/compositions/app-user.cjs.map +0 -1
  44. package/dist/compositions/app-user.js.map +0 -1
  45. package/dist/modality/index.cjs +0 -86
  46. package/dist/modality/index.cjs.map +0 -1
  47. package/dist/modality/index.d.cts +0 -26
  48. package/dist/modality/index.d.ts +0 -26
  49. package/dist/modality/index.js +0 -59
  50. package/dist/modality/index.js.map +0 -1
  51. package/dist/models/index.cjs.map +0 -1
  52. package/dist/models/index.d.cts +0 -22
  53. package/dist/models/index.d.ts +0 -22
  54. package/dist/models/index.js.map +0 -1
  55. package/dist/theme-VMRlhqST.d.cts +0 -9
  56. package/dist/theme-VMRlhqST.d.ts +0 -9
  57. package/dist/wallet/sdk.cjs +0 -206
  58. package/dist/wallet/sdk.cjs.map +0 -1
  59. package/dist/wallet/sdk.d.cts +0 -33
  60. package/dist/wallet/sdk.d.ts +0 -33
  61. package/dist/wallet/sdk.js +0 -175
  62. package/dist/wallet/sdk.js.map +0 -1
  63. /package/dist/{compositions/app-user.d.cts → app-user-menu/sdk.d.cts} +0 -0
  64. /package/dist/{compositions/app-user.d.ts → app-user-menu/sdk.d.ts} +0 -0
package/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # @pollinations/ui
2
2
 
3
- Internal UI primitives for Pollinations apps. SDK-backed subpaths consume auth
4
- state from [`@pollinations/sdk/react`](../sdk/README.md#react-auth-provider);
5
- core primitives and display recipes stay SDK-free.
3
+ Internal UI primitives, compositions, and modules for Pollinations apps.
4
+ SDK-backed subpaths consume auth state from
5
+ [`@pollinations/sdk/react`](../sdk/README.md#react-auth-provider); core
6
+ primitives and display recipes stay SDK-free.
6
7
 
7
8
  ## Install
8
9
 
@@ -17,56 +18,22 @@ npm install @pollinations/ui
17
18
  npm install @pollinations/ui@alpha
18
19
  ```
19
20
 
20
- Install `@pollinations/sdk` too when using `@pollinations/ui/*/sdk`
21
- subpaths.
21
+ Install `@pollinations/sdk` too when using the
22
+ `@pollinations/ui/app-user-menu/sdk` subpath.
22
23
 
23
24
  ## Usage
24
25
 
25
26
  ```tsx
26
27
  import "@pollinations/ui/styles.css";
27
- import { PolliProvider, useAccountKeyUsage } from "@pollinations/sdk/react";
28
+ import { PolliProvider } from "@pollinations/sdk/react";
28
29
  import { Surface } from "@pollinations/ui";
29
- import {
30
- LoginButton,
31
- LogoutButton,
32
- UserAvatar,
33
- UserName,
34
- WhenLoggedIn,
35
- WhenLoggedOut,
36
- } from "@pollinations/ui/auth/sdk";
37
- import {
38
- Balance,
39
- KeyBudget,
40
- KeyExpiry,
41
- KeyModels,
42
- KeyPrefix,
43
- } from "@pollinations/ui/wallet/sdk";
44
-
45
- function RecentRequests() {
46
- const { data: usage } = useAccountKeyUsage({ days: 7, limit: 5 });
47
- return <span>{usage?.usage.length ?? 0} recent requests</span>;
48
- }
30
+ import { AppUserMenu } from "@pollinations/ui/app-user-menu/sdk";
49
31
 
50
32
  export function App() {
51
33
  return (
52
34
  <PolliProvider appKey="pk_your_publishable_key" permissions={["profile"]}>
53
35
  <Surface data-theme="amber">
54
- <WhenLoggedOut>
55
- <LoginButton theme="amber">
56
- Log in with Pollinations
57
- </LoginButton>
58
- </WhenLoggedOut>
59
- <WhenLoggedIn>
60
- <UserAvatar size="md" />
61
- <UserName />
62
- <Balance />
63
- <KeyPrefix />
64
- <KeyBudget />
65
- <KeyExpiry />
66
- <KeyModels />
67
- <RecentRequests />
68
- <LogoutButton theme="amber">Log out</LogoutButton>
69
- </WhenLoggedIn>
36
+ <AppUserMenu dashboardHref="https://enter.pollinations.ai" />
70
37
  </Surface>
71
38
  </PolliProvider>
72
39
  );
@@ -104,30 +71,25 @@ Wallet colors and utilities are bundled into the main stylesheet
104
71
  - `@pollinations/ui/auth` exports SDK-free auth modal pieces:
105
72
  `AuthModal`, `AuthModalHeader`, `AuthModalLoading`, `AuthInfoCard`, and
106
73
  `ErrorBanner`.
107
- - `@pollinations/ui/auth/sdk` exports identity/session components that read
108
- from the surrounding `<PolliProvider>`:
109
- - **null when not logged in (or before data loads):** `LogoutButton`,
110
- `UserAvatar`, `UserEmail`, `UserName`, `WhenLoggedIn`.
111
- - **shown only when logged out:** `LoginButton`, `WhenLoggedOut`.
112
-
113
- These are intentionally bare wrappers around `useAuth*` hooks. They render
114
- the data and nothing else — no default copy, no default theme, no default
115
- intent. The app composes layout, copy, and color.
116
74
  - `@pollinations/ui/wallet` exports SDK-free wallet-specific display helpers
117
75
  and recipes: `formatPollen`, `PaidChip`, `TierChip`, `WalletDot`,
118
76
  `WalletBalanceCard`, `PAID_BALANCE_CHART_COLOR`, and
119
77
  `TIER_BALANCE_CHART_COLOR`.
120
- - `@pollinations/ui/wallet/sdk` exports SDK-backed wallet components:
121
- `Balance`, `KeyBudget`, `KeyExpiry`, `KeyModels`, and `KeyPrefix`.
122
- - `@pollinations/ui/modality` exports model-modality color recipes.
78
+ - `@pollinations/ui/app-user-menu/sdk` exports the SDK-backed app account
79
+ menu module.
80
+ - `@pollinations/ui/gen` exports the generation UI — `ModelSelector`,
81
+ category labels, and the model-modality theme mapping.
123
82
  - `@pollinations/ui/assets/*` exports canonical Pollinations source SVGs:
124
83
  `logo.svg` and `logo-wordmark.svg`.
125
- - **Design primitives** — `Alert`, `Button`, `ButtonGroup`, `Chip`, `ChevronIcon`,
126
- `Collapsible`, `CopyButton`, `Dialog`, `Dropdown`, `ExternalLinkButton`,
127
- `IconButton`, `InfoTip`, `Input`, `MultiSelect`, `PeriodPicker`,
128
- `ScrollArea`, `Section`, `Slider`, `StatCard`, `Surface`, `Switch`,
129
- `Table`, `TableBody`, `TableCell`, `TableHead`, `TableHeaderCell`,
130
- `TableRow`, `TabButton`, `Tooltip`.
84
+ - **Design primitives** — `Button`, `ButtonGroup`, `Chip`, `ChevronIcon`,
85
+ `Dialog`, `DialogTitle`, `Dropdown`, `DropdownItem`, `Field`, `Heading`,
86
+ `IconButton`, `InlineLink`, `Input`, `ScrollArea`, `Slider`, `Surface`,
87
+ `Switch`, `TabButton`, `Table`, `TableBody`, `TableCell`, `TableHead`,
88
+ `TableHeaderCell`, `TableRow`, `Text`, `Textarea`, `Tooltip`.
89
+ - **Design compositions** — `Alert`, `CodeBlock`, `Collapsible`,
90
+ `CopyButton`, `ExternalLinkButton`, `FileUpload`, `InfoTip`, `LinkCard`,
91
+ `Markdown`, `MediaPlaceholder`, `MultiSelect`, `NavItem`, `PeriodPicker`,
92
+ `Prose`, `Section`, `StatCard`.
131
93
  - **Helpers** — `cn`, `useScrollLock`, `currentPeriod`,
132
94
  `getPeriodBucketKeys`, `periodBucketKeyToDate`.
133
95
  - **Theme** — `themes` (runtime array of theme names), `ThemeName` (type).
@@ -139,16 +101,17 @@ from `@pollinations/sdk/react` (`useAccountKeyUsage`, `useAccountKey`,
139
101
  ## Source Layout
140
102
 
141
103
  - `src/primitives/*` contains generic, SDK-free building blocks.
104
+ - `src/compositions/*` contains SDK-free recipes that compose primitives.
142
105
  - `src/modules/*` contains package-owned recipes with domain assumptions
143
- such as auth, wallet, and modality.
106
+ such as auth, wallet, app-user-menu, and gen.
144
107
  - Public subpath exports (`@pollinations/ui/auth`,
145
- `@pollinations/ui/auth/sdk`, `@pollinations/ui/wallet`,
146
- `@pollinations/ui/wallet/sdk`, `@pollinations/ui/modality`) are built
147
- directly from those modules.
108
+ `@pollinations/ui/wallet`, `@pollinations/ui/gen`,
109
+ `@pollinations/ui/app-user-menu/sdk`) are built directly from those source
110
+ layers.
148
111
 
149
112
  ## Theming
150
113
 
151
- Set `data-theme="amber" | "blue" | "pink" | "teal" | "violet" | "green"`
114
+ Set `data-theme="amber" | "blue" | "pink" | "coral" | "teal" | "violet" | "emerald"`
152
115
  on any ancestor (or per-component via the `theme` prop on Button-family
153
116
  components) to switch the cascade. Theme variables are defined in
154
117
  `styles.css` — import it once at your app entry.
@@ -1,5 +1,5 @@
1
1
  import { FC, ComponentPropsWithoutRef } from 'react';
2
- import { T as ThemeName } from './theme-VMRlhqST.cjs';
2
+ import { T as ThemeName } from './theme-jRPPBmld.cjs';
3
3
 
4
4
  /** Semantic chip labels for status and metadata badges. */
5
5
  type ChipIntent = "news" | "alpha" | "neutral" | "success" | "warning" | "danger";
@@ -1,5 +1,5 @@
1
1
  import { FC, ComponentPropsWithoutRef } from 'react';
2
- import { T as ThemeName } from './theme-VMRlhqST.js';
2
+ import { T as ThemeName } from './theme-jRPPBmld.js';
3
3
 
4
4
  /** Semantic chip labels for status and metadata badges. */
5
5
  type ChipIntent = "news" | "alpha" | "neutral" | "success" | "warning" | "danger";
@@ -17,20 +17,17 @@ var __copyProps = (to, from, except, desc) => {
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
- // src/compositions/app-user/index.ts
21
- var app_user_exports = {};
22
- __export(app_user_exports, {
20
+ // src/modules/app-user-menu/sdk.ts
21
+ var sdk_exports = {};
22
+ __export(sdk_exports, {
23
23
  AppUserMenu: () => AppUserMenu,
24
24
  isEmbeddedContext: () => isEmbeddedContext
25
25
  });
26
- module.exports = __toCommonJS(app_user_exports);
26
+ module.exports = __toCommonJS(sdk_exports);
27
27
 
28
- // src/compositions/app-user/AppUserMenu.tsx
28
+ // src/modules/app-user-menu/AppUserMenu.tsx
29
29
  var import_react10 = require("@pollinations/sdk/react");
30
30
 
31
- // src/modules/auth/LoginButton.tsx
32
- var import_react = require("@pollinations/sdk/react");
33
-
34
31
  // src/lib/cn.ts
35
32
  var import_clsx = require("clsx");
36
33
  var import_tailwind_merge = require("tailwind-merge");
@@ -39,8 +36,111 @@ function cn(...inputs) {
39
36
  return twMerge((0, import_clsx.clsx)(...inputs));
40
37
  }
41
38
 
42
- // src/primitives/Button.tsx
39
+ // src/primitives/ChevronIcon.tsx
43
40
  var import_jsx_runtime = require("react/jsx-runtime");
41
+ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
42
+ "svg",
43
+ {
44
+ "aria-hidden": "true",
45
+ width: "12",
46
+ height: "12",
47
+ viewBox: "0 0 12 12",
48
+ className: cn(
49
+ "polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out",
50
+ expanded && "polli:rotate-180",
51
+ className
52
+ ),
53
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
54
+ "path",
55
+ {
56
+ d: "M3 4.5 6 7.5l3-3",
57
+ fill: "none",
58
+ stroke: "currentColor",
59
+ strokeLinecap: "round",
60
+ strokeLinejoin: "round",
61
+ strokeWidth: "1.5"
62
+ }
63
+ )
64
+ }
65
+ );
66
+
67
+ // src/primitives/Dropdown.tsx
68
+ var import_popover = require("@ark-ui/react/popover");
69
+ var import_portal = require("@ark-ui/react/portal");
70
+ var import_react = require("react");
71
+ var import_jsx_runtime2 = require("react/jsx-runtime");
72
+ var DEFAULT_PANEL = "polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg";
73
+ var Dropdown = ({
74
+ theme,
75
+ trigger,
76
+ children,
77
+ align = "start",
78
+ open: openProp,
79
+ onOpenChange,
80
+ className
81
+ }) => {
82
+ const [internalOpen, setInternalOpen] = (0, import_react.useState)(false);
83
+ const isControlled = openProp !== void 0;
84
+ const open = isControlled ? openProp : internalOpen;
85
+ const setOpen = (next) => {
86
+ if (!isControlled) setInternalOpen(next);
87
+ onOpenChange?.(next);
88
+ };
89
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
90
+ import_popover.Popover.Root,
91
+ {
92
+ open,
93
+ onOpenChange: (details) => setOpen(details.open),
94
+ positioning: {
95
+ placement: align === "end" ? "bottom-end" : "bottom-start"
96
+ },
97
+ children: [
98
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_popover.Popover.Trigger, { asChild: true, children: trigger(open) }),
99
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_portal.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_popover.Popover.Positioner, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
100
+ import_popover.Popover.Content,
101
+ {
102
+ "data-theme": theme,
103
+ className: cn(
104
+ "polli:z-50 polli:overflow-hidden polli:focus:outline-none",
105
+ DEFAULT_PANEL,
106
+ className
107
+ ),
108
+ children: typeof children === "function" ? children(() => setOpen(false)) : children
109
+ }
110
+ ) }) })
111
+ ]
112
+ }
113
+ );
114
+ };
115
+
116
+ // src/primitives/DropdownItem.tsx
117
+ var import_jsx_runtime3 = require("react/jsx-runtime");
118
+ function DropdownItem({
119
+ as,
120
+ className,
121
+ children,
122
+ ...rest
123
+ }) {
124
+ const Component = as || "button";
125
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
126
+ Component,
127
+ {
128
+ ...Component === "button" ? { type: "button" } : void 0,
129
+ ...rest,
130
+ className: cn(
131
+ "polli-control polli:flex polli:w-full polli:cursor-pointer polli:items-center polli:gap-2 polli:rounded-lg polli:bg-transparent polli:px-3 polli:py-2 polli:text-left polli:text-sm polli:font-medium polli:text-theme-text-base polli:no-underline polli:transition-colors polli:hover:bg-theme-bg-hover polli:focus-visible:bg-theme-bg-hover",
132
+ className
133
+ ),
134
+ children
135
+ }
136
+ );
137
+ }
138
+
139
+ // src/modules/auth/LoginButton.tsx
140
+ var import_react2 = require("@pollinations/sdk/react");
141
+
142
+ // src/primitives/Button.tsx
143
+ var import_jsx_runtime4 = require("react/jsx-runtime");
44
144
  var sizes = {
45
145
  sm: "polli:px-2 polli:pt-0.5 polli:pb-1",
46
146
  md: "polli:px-4 polli:pt-1.5 polli:pb-2",
@@ -77,7 +177,7 @@ function Button({
77
177
  ...buttonProps
78
178
  }) {
79
179
  const Component = as || "button";
80
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
180
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
81
181
  Component,
82
182
  {
83
183
  "data-theme": intent ? void 0 : theme,
@@ -97,17 +197,17 @@ function Button({
97
197
  }
98
198
 
99
199
  // src/modules/auth/LoginButton.tsx
100
- var import_jsx_runtime2 = require("react/jsx-runtime");
200
+ var import_jsx_runtime5 = require("react/jsx-runtime");
101
201
  function LoginButton({ children, ...buttonProps }) {
102
- const { isLoggedIn } = (0, import_react.useAuthState)();
103
- const { login } = (0, import_react.useAuthActions)();
202
+ const { isLoggedIn } = (0, import_react2.useAuthState)();
203
+ const { login } = (0, import_react2.useAuthActions)();
104
204
  if (isLoggedIn) return null;
105
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Button, { ...buttonProps, onClick: () => login(), children });
205
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { ...buttonProps, onClick: () => login(), children });
106
206
  }
107
207
 
108
208
  // src/modules/auth/UserAvatar.tsx
109
- var import_react2 = require("@pollinations/sdk/react");
110
- var import_jsx_runtime3 = require("react/jsx-runtime");
209
+ var import_react3 = require("@pollinations/sdk/react");
210
+ var import_jsx_runtime6 = require("react/jsx-runtime");
111
211
  var sizeClass = {
112
212
  sm: "polli:w-6 polli:h-6 polli:text-xs",
113
213
  md: "polli:w-9 polli:h-9 polli:text-sm",
@@ -122,8 +222,8 @@ function initials(name) {
122
222
  return (first + last).toUpperCase() || null;
123
223
  }
124
224
  function UserAvatar({ size = "md", className }) {
125
- const { isLoggedIn } = (0, import_react2.useAuthState)();
126
- const { data: profile } = (0, import_react2.useAccountProfile)({ enabled: isLoggedIn });
225
+ const { isLoggedIn } = (0, import_react3.useAuthState)();
226
+ const { data: profile } = (0, import_react3.useAccountProfile)({ enabled: isLoggedIn });
127
227
  if (!isLoggedIn) return null;
128
228
  const base = cn(
129
229
  "polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:overflow-hidden polli:bg-theme-bg-pale polli:text-theme-text-strong polli:font-semibold polli:select-none",
@@ -131,7 +231,7 @@ function UserAvatar({ size = "md", className }) {
131
231
  className
132
232
  );
133
233
  if (profile?.image) {
134
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
234
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
135
235
  "img",
136
236
  {
137
237
  "data-polli": "user-avatar",
@@ -143,7 +243,7 @@ function UserAvatar({ size = "md", className }) {
143
243
  }
144
244
  const label = profile?.name ? initials(profile.name) : null;
145
245
  if (!label) return null;
146
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
246
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
147
247
  "div",
148
248
  {
149
249
  "data-polli": "user-avatar",
@@ -156,42 +256,42 @@ function UserAvatar({ size = "md", className }) {
156
256
  }
157
257
 
158
258
  // src/modules/auth/UserName.tsx
159
- var import_react3 = require("@pollinations/sdk/react");
160
- var import_jsx_runtime4 = require("react/jsx-runtime");
259
+ var import_react4 = require("@pollinations/sdk/react");
260
+ var import_jsx_runtime7 = require("react/jsx-runtime");
161
261
  function UserName({ className }) {
162
- const { isLoggedIn } = (0, import_react3.useAuthState)();
163
- const { data: profile } = (0, import_react3.useAccountProfile)({ enabled: isLoggedIn });
262
+ const { isLoggedIn } = (0, import_react4.useAuthState)();
263
+ const { data: profile } = (0, import_react4.useAccountProfile)({ enabled: isLoggedIn });
164
264
  if (!isLoggedIn || !profile) return null;
165
265
  const display = profile.name || profile.githubUsername;
166
266
  if (!display) return null;
167
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "data-polli": "user-name", className, children: display });
267
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "data-polli": "user-name", className, children: display });
168
268
  }
169
269
 
170
270
  // src/modules/auth/WhenLoggedIn.tsx
171
- var import_react4 = require("@pollinations/sdk/react");
172
- var import_react5 = require("react");
173
- var import_jsx_runtime5 = require("react/jsx-runtime");
271
+ var import_react5 = require("@pollinations/sdk/react");
272
+ var import_react6 = require("react");
273
+ var import_jsx_runtime8 = require("react/jsx-runtime");
174
274
  function WhenLoggedIn({ children }) {
175
- const { isLoggedIn } = (0, import_react4.useAuthState)();
275
+ const { isLoggedIn } = (0, import_react5.useAuthState)();
176
276
  if (!isLoggedIn) return null;
177
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react5.Fragment, { children });
277
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react6.Fragment, { children });
178
278
  }
179
279
 
180
280
  // src/modules/auth/WhenLoggedOut.tsx
181
- var import_react6 = require("@pollinations/sdk/react");
182
- var import_react7 = require("react");
183
- var import_jsx_runtime6 = require("react/jsx-runtime");
281
+ var import_react7 = require("@pollinations/sdk/react");
282
+ var import_react8 = require("react");
283
+ var import_jsx_runtime9 = require("react/jsx-runtime");
184
284
  function WhenLoggedOut({ children }) {
185
- const { isLoggedIn } = (0, import_react6.useAuthState)();
285
+ const { isLoggedIn } = (0, import_react7.useAuthState)();
186
286
  if (isLoggedIn) return null;
187
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react7.Fragment, { children });
287
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react8.Fragment, { children });
188
288
  }
189
289
 
190
290
  // src/modules/wallet/Balance.tsx
191
- var import_react8 = require("@pollinations/sdk/react");
291
+ var import_react9 = require("@pollinations/sdk/react");
192
292
 
193
293
  // src/primitives/Chip.tsx
194
- var import_jsx_runtime7 = require("react/jsx-runtime");
294
+ var import_jsx_runtime10 = require("react/jsx-runtime");
195
295
  var chipSizes = {
196
296
  sm: "polli:px-2 polli:py-0.5 polli:text-xs",
197
297
  md: "polli:px-2.5 polli:py-0.5 polli:text-sm",
@@ -200,10 +300,10 @@ var chipSizes = {
200
300
  var intentClasses2 = {
201
301
  news: "polli:bg-intent-news-bg-light polli:text-intent-news-text",
202
302
  alpha: "polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text",
203
- neutral: "polli:border polli:border-gray-400/70 polli:bg-gray-100/80 polli:text-gray-900",
204
- success: "polli:border polli:border-intent-success-border polli:bg-intent-success-bg-light polli:text-intent-success-text",
205
- warning: "polli:border polli:border-intent-warning-border polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
206
- danger: "polli:border polli:border-intent-danger-border polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
303
+ neutral: "polli:bg-ink-100/80 polli:text-ink-900",
304
+ success: "polli:bg-intent-success-bg-light polli:text-intent-success-text",
305
+ warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
306
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
207
307
  };
208
308
  var Chip = ({
209
309
  theme,
@@ -214,7 +314,7 @@ var Chip = ({
214
314
  ...rest
215
315
  }) => {
216
316
  const intentClass = intent ? intentClasses2[intent] : "polli:bg-theme-bg-active polli:text-theme-text-strong";
217
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
317
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
218
318
  "span",
219
319
  {
220
320
  ...rest,
@@ -260,12 +360,12 @@ function formatPollen(value) {
260
360
  }
261
361
 
262
362
  // src/modules/wallet/Balance.tsx
263
- var import_jsx_runtime8 = require("react/jsx-runtime");
363
+ var import_jsx_runtime11 = require("react/jsx-runtime");
264
364
  function Balance({ className } = {}) {
265
- const { isLoggedIn } = (0, import_react8.useAuthState)();
266
- const { data: balance } = (0, import_react8.useAccountBalance)({ enabled: isLoggedIn });
365
+ const { isLoggedIn } = (0, import_react9.useAuthState)();
366
+ const { data: balance } = (0, import_react9.useAccountBalance)({ enabled: isLoggedIn });
267
367
  if (!isLoggedIn || balance == null) return null;
268
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
368
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
269
369
  Chip,
270
370
  {
271
371
  "data-polli": "balance",
@@ -278,107 +378,7 @@ function Balance({ className } = {}) {
278
378
  );
279
379
  }
280
380
 
281
- // src/primitives/ChevronIcon.tsx
282
- var import_jsx_runtime9 = require("react/jsx-runtime");
283
- var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
284
- "svg",
285
- {
286
- "aria-hidden": "true",
287
- width: "12",
288
- height: "12",
289
- viewBox: "0 0 12 12",
290
- className: cn(
291
- "polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out",
292
- expanded && "polli:rotate-180",
293
- className
294
- ),
295
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
296
- "path",
297
- {
298
- d: "M3 4.5 6 7.5l3-3",
299
- fill: "none",
300
- stroke: "currentColor",
301
- strokeLinecap: "round",
302
- strokeLinejoin: "round",
303
- strokeWidth: "1.5"
304
- }
305
- )
306
- }
307
- );
308
-
309
- // src/primitives/Dropdown.tsx
310
- var import_popover = require("@ark-ui/react/popover");
311
- var import_portal = require("@ark-ui/react/portal");
312
- var import_react9 = require("react");
313
- var import_jsx_runtime10 = require("react/jsx-runtime");
314
- var DEFAULT_PANEL = "polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg";
315
- var Dropdown = ({
316
- theme,
317
- trigger,
318
- children,
319
- align = "start",
320
- open: openProp,
321
- onOpenChange,
322
- className
323
- }) => {
324
- const [internalOpen, setInternalOpen] = (0, import_react9.useState)(false);
325
- const isControlled = openProp !== void 0;
326
- const open = isControlled ? openProp : internalOpen;
327
- const setOpen = (next) => {
328
- if (!isControlled) setInternalOpen(next);
329
- onOpenChange?.(next);
330
- };
331
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
332
- import_popover.Popover.Root,
333
- {
334
- open,
335
- onOpenChange: (details) => setOpen(details.open),
336
- positioning: {
337
- placement: align === "end" ? "bottom-end" : "bottom-start"
338
- },
339
- children: [
340
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_popover.Popover.Trigger, { asChild: true, children: trigger(open) }),
341
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_portal.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_popover.Popover.Positioner, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
342
- import_popover.Popover.Content,
343
- {
344
- "data-theme": theme,
345
- className: cn(
346
- "polli:z-50 polli:overflow-hidden polli:focus:outline-none",
347
- DEFAULT_PANEL,
348
- className
349
- ),
350
- children: typeof children === "function" ? children(() => setOpen(false)) : children
351
- }
352
- ) }) })
353
- ]
354
- }
355
- );
356
- };
357
-
358
- // src/primitives/DropdownItem.tsx
359
- var import_jsx_runtime11 = require("react/jsx-runtime");
360
- function DropdownItem({
361
- as,
362
- className,
363
- children,
364
- ...rest
365
- }) {
366
- const Component = as || "button";
367
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
368
- Component,
369
- {
370
- ...Component === "button" ? { type: "button" } : void 0,
371
- ...rest,
372
- className: cn(
373
- "polli-control polli:flex polli:w-full polli:cursor-pointer polli:items-center polli:gap-2 polli:rounded-lg polli:bg-transparent polli:px-3 polli:py-2 polli:text-left polli:text-sm polli:font-medium polli:text-theme-text-base polli:no-underline polli:transition-colors polli:hover:bg-theme-bg-hover polli:focus-visible:bg-theme-bg-hover",
374
- className
375
- ),
376
- children
377
- }
378
- );
379
- }
380
-
381
- // src/compositions/app-user/AppUserMenu.tsx
381
+ // src/modules/app-user-menu/AppUserMenu.tsx
382
382
  var import_jsx_runtime12 = require("react/jsx-runtime");
383
383
  var defaultLabels = {
384
384
  authorize: "Authorize app",
@@ -494,4 +494,4 @@ function AppUserMenuContent({
494
494
  AppUserMenu,
495
495
  isEmbeddedContext
496
496
  });
497
- //# sourceMappingURL=app-user.cjs.map
497
+ //# sourceMappingURL=sdk.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/modules/app-user-menu/sdk.ts","../../src/modules/app-user-menu/AppUserMenu.tsx","../../src/lib/cn.ts","../../src/primitives/ChevronIcon.tsx","../../src/primitives/Dropdown.tsx","../../src/primitives/DropdownItem.tsx","../../src/modules/auth/LoginButton.tsx","../../src/primitives/Button.tsx","../../src/modules/auth/UserAvatar.tsx","../../src/modules/auth/UserName.tsx","../../src/modules/auth/WhenLoggedIn.tsx","../../src/modules/auth/WhenLoggedOut.tsx","../../src/modules/wallet/Balance.tsx","../../src/primitives/Chip.tsx","../../src/modules/wallet/format-pollen.ts"],"sourcesContent":["export {\n AppUserMenu,\n type AppUserMenuLabels,\n type AppUserMenuProps,\n isEmbeddedContext,\n} from \"./AppUserMenu.tsx\";\n","import { useAuthActions } from \"@pollinations/sdk/react\";\nimport { ChevronIcon } from \"../../primitives/ChevronIcon.tsx\";\nimport { Dropdown } from \"../../primitives/Dropdown.tsx\";\nimport { DropdownItem } from \"../../primitives/DropdownItem.tsx\";\nimport {\n LoginButton,\n UserAvatar,\n UserName,\n WhenLoggedIn,\n WhenLoggedOut,\n} from \"../auth/sdk.ts\";\nimport { Balance } from \"../wallet/sdk.ts\";\n\nexport type AppUserMenuLabels = {\n authorize: string;\n appUserMenu: string;\n topUpAccount: string;\n logout: string;\n};\n\nexport type AppUserMenuProps = {\n dashboardHref: string;\n labels?: Partial<AppUserMenuLabels>;\n hiddenWhenEmbedded?: boolean;\n embedQueryParam?: string;\n};\n\nconst defaultLabels: AppUserMenuLabels = {\n authorize: \"Authorize app\",\n appUserMenu: \"App user menu\",\n topUpAccount: \"Top up account\",\n logout: \"Log out from this app\",\n};\n\nexport function isEmbeddedContext(embedQueryParam = \"embed\"): boolean {\n if (typeof window === \"undefined\") return false;\n const search = new URLSearchParams(window.location.search);\n if (search.get(embedQueryParam) === \"1\") return true;\n try {\n return window.self !== window.top;\n } catch {\n return true;\n }\n}\n\nexport function AppUserMenu({\n dashboardHref,\n labels: labelOverrides,\n hiddenWhenEmbedded = false,\n embedQueryParam = \"embed\",\n}: AppUserMenuProps) {\n if (hiddenWhenEmbedded && isEmbeddedContext(embedQueryParam)) return null;\n\n return (\n <AppUserMenuContent\n dashboardHref={dashboardHref}\n labels={labelOverrides}\n />\n );\n}\n\nfunction AppUserMenuContent({\n dashboardHref,\n labels: labelOverrides,\n}: Pick<AppUserMenuProps, \"dashboardHref\" | \"labels\">) {\n const labels = { ...defaultLabels, ...labelOverrides };\n const { logout } = useAuthActions();\n\n return (\n <div data-theme=\"amber\" className=\"polli:flex polli:justify-end\">\n <WhenLoggedOut>\n <LoginButton theme=\"amber\">{labels.authorize}</LoginButton>\n </WhenLoggedOut>\n\n <WhenLoggedIn>\n <Dropdown\n theme=\"amber\"\n align=\"end\"\n className=\"polli:w-64 polli:p-1\"\n trigger={(open) => (\n <button\n type=\"button\"\n data-theme=\"amber\"\n aria-label={labels.appUserMenu}\n className=\"polli-control polli:flex polli:min-w-0 polli:items-center polli:gap-2 polli:rounded-full polli:bg-theme-bg-active polli:py-1 polli:pl-1 polli:pr-3 polli:text-theme-text-base polli:shadow-sm polli:transition-colors polli:hover:bg-theme-bg-hover\"\n >\n <UserAvatar\n size=\"md\"\n className=\"polli:h-8 polli:w-8\"\n />\n <span className=\"polli:flex polli:min-w-0 polli:flex-col polli:items-start polli:leading-tight\">\n <UserName className=\"polli:max-w-32 polli:truncate polli:text-sm polli:font-semibold\" />\n <Balance className=\"polli:bg-transparent polli:px-0 polli:py-0 polli:text-xs polli:text-theme-text-base\" />\n </span>\n <ChevronIcon\n expanded={open}\n className=\"polli:h-4 polli:w-4 polli:text-theme-text-base\"\n />\n </button>\n )}\n >\n {(close) => (\n <div\n data-theme=\"amber\"\n className=\"polli:flex polli:flex-col\"\n >\n <DropdownItem\n as=\"a\"\n href={dashboardHref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={close}\n >\n {labels.topUpAccount}\n </DropdownItem>\n <DropdownItem\n type=\"button\"\n onClick={() => {\n close();\n logout();\n }}\n >\n {labels.logout}\n </DropdownItem>\n </div>\n )}\n </Dropdown>\n </WhenLoggedIn>\n </div>\n );\n}\n","import { clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"polli\" });\n\n/** Internal class merge for polli:-prefixed package primitive classes. */\nexport function cn(...inputs: (string | undefined | null | false)[]) {\n return twMerge(clsx(...inputs));\n}\n","import type { FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\ntype ChevronIconProps = {\n /** Rotate 180° when expanded/open. */\n expanded?: boolean;\n className?: string;\n};\n\n/**\n * Canonical chevron used for collapsibles, dropdown triggers, and select pills\n * across the app. One icon everywhere.\n */\nexport const ChevronIcon: FC<ChevronIconProps> = ({ expanded, className }) => (\n <svg\n aria-hidden=\"true\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n className={cn(\n \"polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out\",\n expanded && \"polli:rotate-180\",\n className,\n )}\n >\n <path\n d=\"M3 4.5 6 7.5l3-3\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.5\"\n />\n </svg>\n);\n","import { Popover } from \"@ark-ui/react/popover\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { FC, ReactNode } from \"react\";\nimport { useState } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nconst DEFAULT_PANEL =\n \"polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg\";\n\nexport type DropdownProps = {\n theme: ThemeName;\n /** Trigger element; receives the current open state (e.g. to rotate a chevron). */\n trigger: (open: boolean) => ReactNode;\n /** Panel content. As a function, receives `close` to dismiss after a selection. */\n children: ReactNode | ((close: () => void) => ReactNode);\n /** Panel placement relative to the trigger. */\n align?: \"start\" | \"end\";\n /** Controlled open state. Omit to let the Dropdown manage its own. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Appended after the surface (widths, padding, max-height…). */\n className?: string;\n};\n\nexport const Dropdown: FC<DropdownProps> = ({\n theme,\n trigger,\n children,\n align = \"start\",\n open: openProp,\n onOpenChange,\n className,\n}) => {\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = openProp !== undefined;\n const open = isControlled ? openProp : internalOpen;\n\n const setOpen = (next: boolean) => {\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n };\n\n return (\n <Popover.Root\n open={open}\n onOpenChange={(details) => setOpen(details.open)}\n positioning={{\n placement: align === \"end\" ? \"bottom-end\" : \"bottom-start\",\n }}\n >\n <Popover.Trigger asChild>{trigger(open)}</Popover.Trigger>\n <Portal>\n <Popover.Positioner>\n <Popover.Content\n data-theme={theme}\n className={cn(\n \"polli:z-50 polli:overflow-hidden polli:focus:outline-none\",\n DEFAULT_PANEL,\n className,\n )}\n >\n {typeof children === \"function\"\n ? children(() => setOpen(false))\n : children}\n </Popover.Content>\n </Popover.Positioner>\n </Portal>\n </Popover.Root>\n );\n};\n","import type { PropsWithChildren } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\ntype BaseDropdownItemProps = {\n className?: string;\n};\n\nexport type DropdownItemProps<T extends React.ElementType = \"button\"> =\n PropsWithChildren<BaseDropdownItemProps> & {\n as?: T;\n } & Omit<\n React.ComponentPropsWithoutRef<T>,\n keyof BaseDropdownItemProps | \"as\"\n >;\n\nexport function DropdownItem<T extends React.ElementType = \"button\">({\n as,\n className,\n children,\n ...rest\n}: DropdownItemProps<T>) {\n const Component: React.ElementType = as || \"button\";\n return (\n <Component\n {...(Component === \"button\" ? { type: \"button\" } : undefined)}\n {...rest}\n className={cn(\n \"polli-control polli:flex polli:w-full polli:cursor-pointer polli:items-center polli:gap-2 polli:rounded-lg polli:bg-transparent polli:px-3 polli:py-2 polli:text-left polli:text-sm polli:font-medium polli:text-theme-text-base polli:no-underline polli:transition-colors polli:hover:bg-theme-bg-hover polli:focus-visible:bg-theme-bg-hover\",\n className,\n )}\n >\n {children}\n </Component>\n );\n}\n","import { useAuthActions, useAuthState } from \"@pollinations/sdk/react\";\nimport type { ReactNode } from \"react\";\nimport { Button, type ButtonProps } from \"../../primitives/Button.tsx\";\n\nexport type LoginButtonProps = Omit<\n ButtonProps<\"button\">,\n \"as\" | \"onClick\" | \"children\"\n> & {\n children: ReactNode;\n};\n\n/** Button that kicks off the auth redirect. `null` when already logged in. */\nexport function LoginButton({ children, ...buttonProps }: LoginButtonProps) {\n const { isLoggedIn } = useAuthState();\n const { login } = useAuthActions();\n if (isLoggedIn) return null;\n return (\n <Button {...buttonProps} onClick={() => login()}>\n {children}\n </Button>\n );\n}\n","import type { PropsWithChildren } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\n/** Button only supports `danger`. Label/status color recipes live on Chip. */\ntype ButtonIntent = \"danger\";\n\nconst sizes = {\n sm: \"polli:px-2 polli:pt-0.5 polli:pb-1\",\n md: \"polli:px-4 polli:pt-1.5 polli:pb-2\",\n lg: \"polli:px-6 polli:py-3\",\n} as const;\n\n// Cascade-driven base — reads [data-theme] vars.\nconst themeClasses =\n \"polli:bg-theme-bg-active polli:text-theme-text-base \" +\n \"polli:hover:bg-theme-bg-hover polli:transition-colors\";\n\n// Single intent: danger. Soft recipe — light tile + deep text, slightly\n// deeper bg on hover. No filled CTAs anywhere.\nconst intentClasses: Record<ButtonIntent, string> = {\n danger:\n \"polli:bg-intent-danger-bg-light polli:text-intent-danger-text \" +\n \"polli:hover:bg-intent-danger-bg-hover polli:transition-colors\",\n};\n\ntype BaseButtonProps = {\n /** Override the cascade theme for this button's subtree. Ignored when `intent` is set. */\n theme?: ThemeName;\n /** Only `\"danger\"` for now. */\n intent?: ButtonIntent;\n size?: keyof typeof sizes;\n className?: string;\n disabled?: boolean;\n};\n\nconst buttonClasses = ({\n theme: _theme,\n intent,\n size,\n className,\n disabled,\n}: BaseButtonProps & { disabled?: boolean }) => {\n const colorClasses = intent ? intentClasses[intent] : themeClasses;\n return cn(\n \"polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:self-center polli:font-medium polli:leading-normal polli:box-border\",\n disabled\n ? \"polli:opacity-50 polli:cursor-not-allowed\"\n : \"polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer\",\n colorClasses,\n sizes[size || \"md\"],\n className,\n );\n};\n\nexport type ButtonProps<T extends React.ElementType = \"button\"> =\n PropsWithChildren<BaseButtonProps> & {\n as?: T;\n } & Omit<React.ComponentPropsWithoutRef<T>, keyof BaseButtonProps | \"as\">;\n\nexport function Button<T extends React.ElementType = \"button\">({\n as,\n children,\n theme,\n intent,\n size,\n className,\n disabled,\n ...buttonProps\n}: ButtonProps<T>) {\n const Component: React.ElementType = as || \"button\";\n\n return (\n <Component\n // Cascade override only applies when `intent` is unset.\n data-theme={intent ? undefined : theme}\n data-intent={intent}\n className={buttonClasses({\n theme,\n intent,\n size,\n className,\n disabled,\n })}\n disabled={disabled}\n {...buttonProps}\n >\n {children}\n </Component>\n );\n}\n","import { useAccountProfile, useAuthState } from \"@pollinations/sdk/react\";\nimport { cn } from \"../../lib/cn.ts\";\n\nexport type UserAvatarProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n};\n\nconst sizeClass = {\n sm: \"polli:w-6 polli:h-6 polli:text-xs\",\n md: \"polli:w-9 polli:h-9 polli:text-sm\",\n lg: \"polli:w-12 polli:h-12 polli:text-base\",\n} as const;\n\nfunction initials(name: string): string | null {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return null;\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase() || null;\n const first = parts[0][0] ?? \"\";\n const last = parts[parts.length - 1][0] ?? \"\";\n return (first + last).toUpperCase() || null;\n}\n\n/** Avatar from `profile.image`, or initials from `profile.name`. `null` otherwise. */\nexport function UserAvatar({ size = \"md\", className }: UserAvatarProps) {\n const { isLoggedIn } = useAuthState();\n const { data: profile } = useAccountProfile({ enabled: isLoggedIn });\n if (!isLoggedIn) return null;\n\n const base = cn(\n \"polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:overflow-hidden polli:bg-theme-bg-pale polli:text-theme-text-strong polli:font-semibold polli:select-none\",\n sizeClass[size],\n className,\n );\n\n if (profile?.image) {\n return (\n <img\n data-polli=\"user-avatar\"\n src={profile.image}\n alt={profile.name ?? \"\"}\n className={base}\n />\n );\n }\n const label = profile?.name ? initials(profile.name) : null;\n if (!label) return null;\n return (\n <div\n data-polli=\"user-avatar\"\n role=\"img\"\n aria-label={profile?.name ?? undefined}\n className={base}\n >\n {label}\n </div>\n );\n}\n","import { useAccountProfile, useAuthState } from \"@pollinations/sdk/react\";\n\nexport type UserNameProps = { className?: string };\n\n/**\n * Renders the user's display name. Falls back to GitHub username when the\n * `profile` scope was not granted (or `name` is empty). `null` when logged\n * out, or when neither name nor GitHub username is available.\n */\nexport function UserName({ className }: UserNameProps) {\n const { isLoggedIn } = useAuthState();\n const { data: profile } = useAccountProfile({ enabled: isLoggedIn });\n if (!isLoggedIn || !profile) return null;\n const display = profile.name || profile.githubUsername;\n if (!display) return null;\n return (\n <span data-polli=\"user-name\" className={className}>\n {display}\n </span>\n );\n}\n","import { useAuthState } from \"@pollinations/sdk/react\";\nimport { Fragment, type ReactNode } from \"react\";\n\nexport type WhenLoggedInProps = { children: ReactNode };\n\n/** Renders `children` only when a user is signed in. */\nexport function WhenLoggedIn({ children }: WhenLoggedInProps) {\n const { isLoggedIn } = useAuthState();\n if (!isLoggedIn) return null;\n return <Fragment>{children}</Fragment>;\n}\n","import { useAuthState } from \"@pollinations/sdk/react\";\nimport { Fragment, type ReactNode } from \"react\";\n\nexport type WhenLoggedOutProps = { children: ReactNode };\n\n/** Renders `children` only when no user is signed in. */\nexport function WhenLoggedOut({ children }: WhenLoggedOutProps) {\n const { isLoggedIn } = useAuthState();\n if (isLoggedIn) return null;\n return <Fragment>{children}</Fragment>;\n}\n","import { useAccountBalance, useAuthState } from \"@pollinations/sdk/react\";\nimport { cn } from \"../../lib/cn.ts\";\nimport { Chip } from \"../../primitives/Chip.tsx\";\nimport { formatPollen } from \"./format-pollen.ts\";\n\nexport type BalanceProps = { className?: string };\n\n/** Renders the logged-in user's pollen balance. `null` until loaded. */\nexport function Balance({ className }: BalanceProps = {}) {\n const { isLoggedIn } = useAuthState();\n const { data: balance } = useAccountBalance({ enabled: isLoggedIn });\n if (!isLoggedIn || balance == null) return null;\n return (\n <Chip\n data-polli=\"balance\"\n className={cn(\"polli:tabular-nums\", className)}\n >\n {formatPollen(balance.balance)} pollen\n </Chip>\n );\n}\n","import type { ComponentPropsWithoutRef, FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\n/** Semantic chip labels for status and metadata badges. */\ntype ChipIntent =\n | \"news\"\n | \"alpha\"\n | \"neutral\"\n | \"success\"\n | \"warning\"\n | \"danger\";\n\nconst chipSizes = {\n sm: \"polli:px-2 polli:py-0.5 polli:text-xs\",\n md: \"polli:px-2.5 polli:py-0.5 polli:text-sm\",\n lg: \"polli:px-3 polli:py-1 polli:text-sm\",\n} as const;\n\nconst intentClasses: Record<ChipIntent, string> = {\n news: \"polli:bg-intent-news-bg-light polli:text-intent-news-text\",\n alpha: \"polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text\",\n neutral: \"polli:bg-ink-100/80 polli:text-ink-900\",\n success: \"polli:bg-intent-success-bg-light polli:text-intent-success-text\",\n warning: \"polli:bg-intent-warning-bg-light polli:text-intent-warning-text\",\n danger: \"polli:bg-intent-danger-bg-light polli:text-intent-danger-text\",\n};\n\nexport type ChipProps = ComponentPropsWithoutRef<\"span\"> & {\n /** Override the cascade theme for this chip's subtree. */\n theme?: ThemeName;\n /** Semantic intent. Wins over `theme` when set. */\n intent?: ChipIntent;\n size?: keyof typeof chipSizes;\n};\n\n// Static, rectangular colored container. Round shapes are reserved for buttons.\n// Reads `bg-theme-bg-active` / `text-theme-text-strong` from the cascade unless\n// `intent` is set (semantic, theme-independent).\nexport const Chip: FC<ChipProps> = ({\n theme,\n intent,\n size = \"md\",\n className,\n children,\n ...rest\n}) => {\n const intentClass = intent\n ? intentClasses[intent]\n : \"polli:bg-theme-bg-active polli:text-theme-text-strong\";\n return (\n <span\n {...rest}\n data-theme={theme}\n className={cn(\n \"polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-normal\",\n chipSizes[size],\n intentClass,\n className,\n )}\n >\n {children}\n </span>\n );\n};\n","// 5-digit budget for pollen display. Integer takes its space, decimals fill\n// the remainder (capped at 4), floor toward -infinity, trailing zeros stripped.\n// Integers needing >=6 digits switch to compact (K/M/B, 3 sig figs).\n// Decimal point and minus sign do not count toward the budget.\n\nconst BUDGET = 5;\nconst MAX_DECIMALS = 4;\nconst COMPACT_THRESHOLD = 100_000;\n\nfunction floorTo(value: number, decimals: number): number {\n const factor = 10 ** decimals;\n return Math.floor(value * factor) / factor;\n}\n\nfunction formatCompact(value: number): string {\n const abs = Math.abs(value);\n const sign = value < 0 ? \"-\" : \"\";\n const [unit, scale] =\n abs >= 1e9\n ? ([\"B\", 1e9] as const)\n : abs >= 1e6\n ? ([\"M\", 1e6] as const)\n : ([\"K\", 1e3] as const);\n const ratio = abs / scale;\n const intDigits = Math.max(1, Math.floor(Math.log10(ratio)) + 1);\n const decimals = Math.max(0, 3 - intDigits);\n const floored = floorTo(ratio, decimals);\n return `${sign}${Number(floored.toFixed(decimals)).toString()}${unit}`;\n}\n\nexport function formatPollen(value: number): string {\n if (!Number.isFinite(value) || value === 0) return \"0\";\n\n const abs = Math.abs(value);\n\n if (abs >= COMPACT_THRESHOLD) return formatCompact(value);\n\n const intDigits = abs >= 1 ? Math.floor(Math.log10(abs)) + 1 : 1;\n const decimals = Math.min(MAX_DECIMALS, Math.max(0, BUDGET - intDigits));\n const floored = floorTo(value, decimals);\n if (floored === 0) return \"0\";\n return Number(floored.toFixed(decimals)).toString();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,iBAA+B;;;ACA/B,kBAAqB;AACrB,4BAAoC;AAEpC,IAAM,cAAU,2CAAoB,EAAE,QAAQ,QAAQ,CAAC;AAGhD,SAAS,MAAM,QAA+C;AACjE,SAAO,YAAQ,kBAAK,GAAG,MAAM,CAAC;AAClC;;;ACiBQ;AAZD,IAAM,cAAoC,CAAC,EAAE,UAAU,UAAU,MACpE;AAAA,EAAC;AAAA;AAAA,IACG,eAAY;AAAA,IACZ,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,WAAW;AAAA,MACP;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,IACJ;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACG,GAAE;AAAA,QACF,MAAK;AAAA,QACL,QAAO;AAAA,QACP,eAAc;AAAA,QACd,gBAAe;AAAA,QACf,aAAY;AAAA;AAAA,IAChB;AAAA;AACJ;;;ACjCJ,qBAAwB;AACxB,oBAAuB;AAEvB,mBAAyB;AAyCjB,IAAAC,sBAAA;AArCR,IAAM,gBACF;AAiBG,IAAM,WAA8B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,MAAM;AAAA,EACN;AAAA,EACA;AACJ,MAAM;AACF,QAAM,CAAC,cAAc,eAAe,QAAI,uBAAS,KAAK;AACtD,QAAM,eAAe,aAAa;AAClC,QAAM,OAAO,eAAe,WAAW;AAEvC,QAAM,UAAU,CAAC,SAAkB;AAC/B,QAAI,CAAC,aAAc,iBAAgB,IAAI;AACvC,mBAAe,IAAI;AAAA,EACvB;AAEA,SACI;AAAA,IAAC,uBAAQ;AAAA,IAAR;AAAA,MACG;AAAA,MACA,cAAc,CAAC,YAAY,QAAQ,QAAQ,IAAI;AAAA,MAC/C,aAAa;AAAA,QACT,WAAW,UAAU,QAAQ,eAAe;AAAA,MAChD;AAAA,MAEA;AAAA,qDAAC,uBAAQ,SAAR,EAAgB,SAAO,MAAE,kBAAQ,IAAI,GAAE;AAAA,QACxC,6CAAC,wBACG,uDAAC,uBAAQ,YAAR,EACG;AAAA,UAAC,uBAAQ;AAAA,UAAR;AAAA,YACG,cAAY;AAAA,YACZ,WAAW;AAAA,cACP;AAAA,cACA;AAAA,cACA;AAAA,YACJ;AAAA,YAEC,iBAAO,aAAa,aACf,SAAS,MAAM,QAAQ,KAAK,CAAC,IAC7B;AAAA;AAAA,QACV,GACJ,GACJ;AAAA;AAAA;AAAA,EACJ;AAER;;;AC/CQ,IAAAC,sBAAA;AARD,SAAS,aAAqD;AAAA,EACjE;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACP,GAAyB;AACrB,QAAM,YAA+B,MAAM;AAC3C,SACI;AAAA,IAAC;AAAA;AAAA,MACI,GAAI,cAAc,WAAW,EAAE,MAAM,SAAS,IAAI;AAAA,MAClD,GAAG;AAAA,MACJ,WAAW;AAAA,QACP;AAAA,QACA;AAAA,MACJ;AAAA,MAEC;AAAA;AAAA,EACL;AAER;;;AClCA,IAAAC,gBAA6C;;;ACyErC,IAAAC,sBAAA;AAlER,IAAM,QAAQ;AAAA,EACV,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACR;AAGA,IAAM,eACF;AAKJ,IAAM,gBAA8C;AAAA,EAChD,QACI;AAER;AAYA,IAAM,gBAAgB,CAAC;AAAA,EACnB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,MAAgD;AAC5C,QAAM,eAAe,SAAS,cAAc,MAAM,IAAI;AACtD,SAAO;AAAA,IACH;AAAA,IACA,WACM,8CACA;AAAA,IACN;AAAA,IACA,MAAM,QAAQ,IAAI;AAAA,IAClB;AAAA,EACJ;AACJ;AAOO,SAAS,OAA+C;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACP,GAAmB;AACf,QAAM,YAA+B,MAAM;AAE3C,SACI;AAAA,IAAC;AAAA;AAAA,MAEG,cAAY,SAAS,SAAY;AAAA,MACjC,eAAa;AAAA,MACb,WAAW,cAAc;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACJ,CAAC;AAAA,MACD;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACL;AAER;;;ADzEQ,IAAAC,sBAAA;AALD,SAAS,YAAY,EAAE,UAAU,GAAG,YAAY,GAAqB;AACxE,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,QAAM,EAAE,MAAM,QAAI,8BAAe;AACjC,MAAI,WAAY,QAAO;AACvB,SACI,6CAAC,UAAQ,GAAG,aAAa,SAAS,MAAM,MAAM,GACzC,UACL;AAER;;;AErBA,IAAAC,gBAAgD;AAqCpC,IAAAC,sBAAA;AA7BZ,IAAM,YAAY;AAAA,EACd,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACR;AAEA,SAAS,SAAS,MAA6B;AAC3C,QAAM,QAAQ,KAAK,KAAK,EAAE,MAAM,KAAK,EAAE,OAAO,OAAO;AACrD,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,YAAY,KAAK;AACrE,QAAM,QAAQ,MAAM,CAAC,EAAE,CAAC,KAAK;AAC7B,QAAM,OAAO,MAAM,MAAM,SAAS,CAAC,EAAE,CAAC,KAAK;AAC3C,UAAQ,QAAQ,MAAM,YAAY,KAAK;AAC3C;AAGO,SAAS,WAAW,EAAE,OAAO,MAAM,UAAU,GAAoB;AACpE,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,QAAM,EAAE,MAAM,QAAQ,QAAI,iCAAkB,EAAE,SAAS,WAAW,CAAC;AACnE,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,OAAO;AAAA,IACT;AAAA,IACA,UAAU,IAAI;AAAA,IACd;AAAA,EACJ;AAEA,MAAI,SAAS,OAAO;AAChB,WACI;AAAA,MAAC;AAAA;AAAA,QACG,cAAW;AAAA,QACX,KAAK,QAAQ;AAAA,QACb,KAAK,QAAQ,QAAQ;AAAA,QACrB,WAAW;AAAA;AAAA,IACf;AAAA,EAER;AACA,QAAM,QAAQ,SAAS,OAAO,SAAS,QAAQ,IAAI,IAAI;AACvD,MAAI,CAAC,MAAO,QAAO;AACnB,SACI;AAAA,IAAC;AAAA;AAAA,MACG,cAAW;AAAA,MACX,MAAK;AAAA,MACL,cAAY,SAAS,QAAQ;AAAA,MAC7B,WAAW;AAAA,MAEV;AAAA;AAAA,EACL;AAER;;;ACzDA,IAAAC,gBAAgD;AAgBxC,IAAAC,sBAAA;AAPD,SAAS,SAAS,EAAE,UAAU,GAAkB;AACnD,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,QAAM,EAAE,MAAM,QAAQ,QAAI,iCAAkB,EAAE,SAAS,WAAW,CAAC;AACnE,MAAI,CAAC,cAAc,CAAC,QAAS,QAAO;AACpC,QAAM,UAAU,QAAQ,QAAQ,QAAQ;AACxC,MAAI,CAAC,QAAS,QAAO;AACrB,SACI,6CAAC,UAAK,cAAW,aAAY,WACxB,mBACL;AAER;;;ACpBA,IAAAC,gBAA6B;AAC7B,IAAAA,gBAAyC;AAQ9B,IAAAC,sBAAA;AAHJ,SAAS,aAAa,EAAE,SAAS,GAAsB;AAC1D,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,6CAAC,0BAAU,UAAS;AAC/B;;;ACVA,IAAAC,gBAA6B;AAC7B,IAAAA,gBAAyC;AAQ9B,IAAAC,sBAAA;AAHJ,SAAS,cAAc,EAAE,SAAS,GAAuB;AAC5D,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,MAAI,WAAY,QAAO;AACvB,SAAO,6CAAC,0BAAU,UAAS;AAC/B;;;ACVA,IAAAC,gBAAgD;;;ACmDxC,IAAAC,uBAAA;AAtCR,IAAM,YAAY;AAAA,EACd,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACR;AAEA,IAAMC,iBAA4C;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AACZ;AAaO,IAAM,OAAsB,CAAC;AAAA,EAChC;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,GAAG;AACP,MAAM;AACF,QAAM,cAAc,SACdA,eAAc,MAAM,IACpB;AACN,SACI;AAAA,IAAC;AAAA;AAAA,MACI,GAAG;AAAA,MACJ,cAAY;AAAA,MACZ,WAAW;AAAA,QACP;AAAA,QACA,UAAU,IAAI;AAAA,QACd;AAAA,QACA;AAAA,MACJ;AAAA,MAEC;AAAA;AAAA,EACL;AAER;;;AC3DA,IAAM,SAAS;AACf,IAAM,eAAe;AACrB,IAAM,oBAAoB;AAE1B,SAAS,QAAQ,OAAe,UAA0B;AACtD,QAAM,SAAS,MAAM;AACrB,SAAO,KAAK,MAAM,QAAQ,MAAM,IAAI;AACxC;AAEA,SAAS,cAAc,OAAuB;AAC1C,QAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,QAAM,OAAO,QAAQ,IAAI,MAAM;AAC/B,QAAM,CAAC,MAAM,KAAK,IACd,OAAO,MACA,CAAC,KAAK,GAAG,IACV,OAAO,MACJ,CAAC,KAAK,GAAG,IACT,CAAC,KAAK,GAAG;AACtB,QAAM,QAAQ,MAAM;AACpB,QAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,MAAM,KAAK,CAAC,IAAI,CAAC;AAC/D,QAAM,WAAW,KAAK,IAAI,GAAG,IAAI,SAAS;AAC1C,QAAM,UAAU,QAAQ,OAAO,QAAQ;AACvC,SAAO,GAAG,IAAI,GAAG,OAAO,QAAQ,QAAQ,QAAQ,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI;AACxE;AAEO,SAAS,aAAa,OAAuB;AAChD,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,UAAU,EAAG,QAAO;AAEnD,QAAM,MAAM,KAAK,IAAI,KAAK;AAE1B,MAAI,OAAO,kBAAmB,QAAO,cAAc,KAAK;AAExD,QAAM,YAAY,OAAO,IAAI,KAAK,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,IAAI;AAC/D,QAAM,WAAW,KAAK,IAAI,cAAc,KAAK,IAAI,GAAG,SAAS,SAAS,CAAC;AACvE,QAAM,UAAU,QAAQ,OAAO,QAAQ;AACvC,MAAI,YAAY,EAAG,QAAO;AAC1B,SAAO,OAAO,QAAQ,QAAQ,QAAQ,CAAC,EAAE,SAAS;AACtD;;;AF7BQ,IAAAC,uBAAA;AALD,SAAS,QAAQ,EAAE,UAAU,IAAkB,CAAC,GAAG;AACtD,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,QAAM,EAAE,MAAM,QAAQ,QAAI,iCAAkB,EAAE,SAAS,WAAW,CAAC;AACnE,MAAI,CAAC,cAAc,WAAW,KAAM,QAAO;AAC3C,SACI;AAAA,IAAC;AAAA;AAAA,MACG,cAAW;AAAA,MACX,WAAW,GAAG,sBAAsB,SAAS;AAAA,MAE5C;AAAA,qBAAa,QAAQ,OAAO;AAAA,QAAE;AAAA;AAAA;AAAA,EACnC;AAER;;;AXkCQ,IAAAC,uBAAA;AA3BR,IAAM,gBAAmC;AAAA,EACrC,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,QAAQ;AACZ;AAEO,SAAS,kBAAkB,kBAAkB,SAAkB;AAClE,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,SAAS,IAAI,gBAAgB,OAAO,SAAS,MAAM;AACzD,MAAI,OAAO,IAAI,eAAe,MAAM,IAAK,QAAO;AAChD,MAAI;AACA,WAAO,OAAO,SAAS,OAAO;AAAA,EAClC,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAEO,SAAS,YAAY;AAAA,EACxB;AAAA,EACA,QAAQ;AAAA,EACR,qBAAqB;AAAA,EACrB,kBAAkB;AACtB,GAAqB;AACjB,MAAI,sBAAsB,kBAAkB,eAAe,EAAG,QAAO;AAErE,SACI;AAAA,IAAC;AAAA;AAAA,MACG;AAAA,MACA,QAAQ;AAAA;AAAA,EACZ;AAER;AAEA,SAAS,mBAAmB;AAAA,EACxB;AAAA,EACA,QAAQ;AACZ,GAAuD;AACnD,QAAM,SAAS,EAAE,GAAG,eAAe,GAAG,eAAe;AACrD,QAAM,EAAE,OAAO,QAAI,+BAAe;AAElC,SACI,+CAAC,SAAI,cAAW,SAAQ,WAAU,gCAC9B;AAAA,kDAAC,iBACG,wDAAC,eAAY,OAAM,SAAS,iBAAO,WAAU,GACjD;AAAA,IAEA,8CAAC,gBACG;AAAA,MAAC;AAAA;AAAA,QACG,OAAM;AAAA,QACN,OAAM;AAAA,QACN,WAAU;AAAA,QACV,SAAS,CAAC,SACN;AAAA,UAAC;AAAA;AAAA,YACG,MAAK;AAAA,YACL,cAAW;AAAA,YACX,cAAY,OAAO;AAAA,YACnB,WAAU;AAAA,YAEV;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACG,MAAK;AAAA,kBACL,WAAU;AAAA;AAAA,cACd;AAAA,cACA,+CAAC,UAAK,WAAU,iFACZ;AAAA,8DAAC,YAAS,WAAU,mEAAkE;AAAA,gBACtF,8CAAC,WAAQ,WAAU,uFAAsF;AAAA,iBAC7G;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACG,UAAU;AAAA,kBACV,WAAU;AAAA;AAAA,cACd;AAAA;AAAA;AAAA,QACJ;AAAA,QAGH,WAAC,UACE;AAAA,UAAC;AAAA;AAAA,YACG,cAAW;AAAA,YACX,WAAU;AAAA,YAEV;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACG,IAAG;AAAA,kBACH,MAAM;AAAA,kBACN,QAAO;AAAA,kBACP,KAAI;AAAA,kBACJ,SAAS;AAAA,kBAER,iBAAO;AAAA;AAAA,cACZ;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACG,MAAK;AAAA,kBACL,SAAS,MAAM;AACX,0BAAM;AACN,2BAAO;AAAA,kBACX;AAAA,kBAEC,iBAAO;AAAA;AAAA,cACZ;AAAA;AAAA;AAAA,QACJ;AAAA;AAAA,IAER,GACJ;AAAA,KACJ;AAER;","names":["import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","intentClasses","import_jsx_runtime","import_jsx_runtime"]}