@hoardodile/ui 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/breadcrumb.js +3 -0
- package/dist/components/breadcrumb.js.map +1 -1
- package/dist/components/caption-bar.js +3 -0
- package/dist/components/caption-bar.js.map +1 -1
- package/dist/components/color-picker.js +3 -0
- package/dist/components/color-picker.js.map +1 -1
- package/dist/components/combobox.js +3 -0
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/dropdown-menu.js +3 -0
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/dropdown-select.js +3 -0
- package/dist/components/dropdown-select.js.map +1 -1
- package/dist/components/font-picker.js +3 -0
- package/dist/components/font-picker.js.map +1 -1
- package/dist/components/image-crop-panel.js +3 -0
- package/dist/components/image-crop-panel.js.map +1 -1
- package/dist/components/pagination-bar.js +3 -0
- package/dist/components/pagination-bar.js.map +1 -1
- package/dist/components/pagination.js +3 -0
- package/dist/components/pagination.js.map +1 -1
- package/dist/components/panel-toolbar.js +3 -0
- package/dist/components/panel-toolbar.js.map +1 -1
- package/dist/components/search-field.js +3 -0
- package/dist/components/search-field.js.map +1 -1
- package/dist/components/sidebar.js +3 -0
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/toast.js +3 -0
- package/dist/components/toast.js.map +1 -1
- package/dist/icons/actions.js +3 -0
- package/dist/icons/actions.js.map +1 -1
- package/dist/icons/registry.d.ts +2 -1
- package/dist/icons/registry.js +9 -1
- package/dist/icons/registry.js.map +1 -1
- package/dist/res-card-template/format.d.ts +21 -0
- package/dist/res-card-template/format.js +23 -0
- package/dist/res-card-template/format.js.map +1 -0
- package/dist/res-card-template/icon.d.ts +38 -0
- package/dist/res-card-template/icon.js +41 -0
- package/dist/res-card-template/icon.js.map +1 -0
- package/dist/res-card-template/index.d.ts +4 -0
- package/dist/res-card-template/index.js +331 -0
- package/dist/res-card-template/index.js.map +1 -0
- package/dist/res-card-template/template.d.ts +48 -0
- package/dist/res-card-template/template.js +333 -0
- package/dist/res-card-template/template.js.map +1 -0
- package/package.json +9 -2
- package/src/icons/registry.ts +8 -0
- package/src/res-card-template/format.test.ts +45 -0
- package/src/res-card-template/format.ts +36 -0
- package/src/res-card-template/icon.test.ts +100 -0
- package/src/res-card-template/icon.ts +86 -0
- package/src/res-card-template/index.ts +22 -0
- package/src/res-card-template/template.test.ts +457 -0
- package/src/res-card-template/template.ts +429 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/merge-config.ts","../../src/lib/utils.ts","../../src/components/button.tsx","../../src/hooks/use-dialog-footer-actions.ts","../../src/components/app-dialog.tsx","../../src/components/label.tsx","../../src/components/switch.tsx","../../src/icons/icon-style.ts","../../src/icons/registry.ts","../../src/components/toast.tsx","../../src/components/image-cropper.tsx","../../src/components/image-crop-panel.tsx"],"names":["ButtonPrimitive","jsx","SwitchPrimitive","GalleryBoldWeight","GalleryBoldDuotone","GalleryLinear","RefreshCircleBoldWeight","RefreshCircleBoldDuotone","RefreshCircleLinear","UploadBoldWeight","UploadBoldDuotone","UploadLinear","ToastPrimitive","useRef","useState","useEffect","useTranslation","useCallback","onSave","onSaved","onSavingChange","t","jsxs"],"mappings":"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","file":"image-crop-panel.js","sourcesContent":["import { extendTailwindMerge } from \"tailwind-merge\"\n\n// The app's `@theme inline` tokens (theme.css) generate utility names\n// tailwind-merge doesn't know, so it misclassifies them — e.g. `text-ui` is\n// parsed as a text color and dropped next to any `text-*` color. The default\n// class groups are theme-backed, so extending the theme (keys mirror the v4\n// token namespaces one-to-one) registers every custom utility with correct\n// conflict semantics. merge-config.test.ts pins this list against theme.css.\nexport const mergeTheme = {\n\ttext: [\"tiny\", \"ui\", \"doc\", \"doc-title\", \"doc-heading\", \"quote\"],\n\tspacing: [\"chip\", \"control\", \"nav\", \"sidebar\", \"panel\"],\n\ttracking: [\"label\"],\n\tshadow: [\"card\", \"dialog\"],\n\tcontainer: [\"reading\", \"medium\", \"content\"],\n\tfont: [\"doc\", \"heading\"],\n\tease: [\"standard\"],\n\tanimate: [\"skel\", \"pop\"],\n} as const\n\nexport const twMerge = extendTailwindMerge({\n\textend: { theme: mergeTheme },\n})\n","import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"./merge-config\"\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs))\n}\n","import { Button as ButtonPrimitive } from \"@base-ui/react/button\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@hoardodile/ui/lib/utils\"\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg text-ui font-medium whitespace-nowrap outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary px-4! text-primary-foreground hover:bg-primary/80\",\n outline:\n \"border-border bg-background shadow-xs hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-foreground\",\n ghost:\n \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n danger:\n \"bg-[color-mix(in_oklab,var(--destructive),black_12%)] text-white hover:bg-[color-mix(in_oklab,var(--destructive),black_4%)] focus-visible:border-destructive/40 focus-visible:ring-destructive/20 disabled:bg-destructive/10 disabled:text-muted-foreground dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-control gap-2 px-3 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n xs: \"h-6 gap-2 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-chip gap-2 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5\",\n lg: \"h-10 gap-2 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n icon: \"size-9\",\n \"icon-xs\":\n \"size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\":\n \"size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n active,\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props &\n VariantProps<typeof buttonVariants> & {\n /** Latched toggle state: accent fill, hover pinned so an active\n button never shifts. Callers keep choosing the matching aria\n attribute (`aria-pressed` / `aria-expanded`). */\n active?: boolean\n }) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(\n buttonVariants({ variant, size, className }),\n active && \"bg-accent text-accent-foreground hover:bg-accent\"\n )}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import { createContext, type ReactNode, useContext } from \"react\"\n\n/**\n * Footer action slot plumbing for `AppDialog` — the context shared\n * between the dialog shell (`@hoardodile/ui/components/app-dialog`) and\n * body panels that contribute their primary action through\n * `DialogFooterActions`, so action buttons land in the footer instead of\n * the body.\n */\n\ntype DialogFooterActionsValue = {\n\treadonly setFooterActions: (node: ReactNode | null) => void\n}\n\nconst DialogFooterActionsContext =\n\tcreateContext<DialogFooterActionsValue | null>(null)\n\n/** The nearest dialog's footer action slot, or null outside a dialog. */\nfunction useDialogFooterActions(): DialogFooterActionsValue | null {\n\treturn useContext(DialogFooterActionsContext)\n}\n\nexport { DialogFooterActionsContext, useDialogFooterActions }\n","import {\n\tDialog,\n\tDialogBody,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n} from \"./dialog\"\nimport {\n\tDialogFooterActionsContext,\n\tuseDialogFooterActions,\n} from \"@hoardodile/ui/hooks/use-dialog-footer-actions\"\nimport { cn } from \"@hoardodile/ui/lib/utils\"\nimport {\n\ttype ReactNode,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\"\n\n/** Dialog width tiers: the 320–480 narrow slot plus\n the wide working tiers — edit hubs, pickers and selectors get\n real estate; confirmations never leave the narrow slot. */\nexport type AppDialogSize = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\"\n\nconst sizeClasses: Record<AppDialogSize, string> = {\n\tsm: \"sm:max-w-sm\",\n\tmd: \"sm:max-w-md\",\n\tlg: \"sm:max-w-2xl\",\n\txl: \"sm:max-w-3xl\",\n\t\"2xl\": \"sm:max-w-4xl\",\n}\n\nexport { useDialogFooterActions }\n\n/**\n * Declarative footer action: renders nothing in the body and contributes\n * the node to the surrounding dialog's footer (appended after the\n * dialog's own `footer` prop). Panels embed their primary action this way\n * so action buttons live in the footer, never in the body. Outside a\n * dialog (sheets, pickers) it renders nothing — callers keep their inline\n * action bar as the fallback.\n */\nexport function DialogFooterActions({ children }: { children: ReactNode }) {\n\tconst slot = useDialogFooterActions()\n\tuseEffect(() => {\n\t\tif (slot === null) return\n\t\tslot.setFooterActions(children)\n\t\treturn () => slot.setFooterActions(null)\n\t}, [slot, children])\n\treturn null\n}\n\nexport type AppDialogProps = Readonly<{\n\topen: boolean\n\tonOpenChange: (open: boolean) => void\n\ttitle: ReactNode\n\t/** Uppercase section marker above the title (feature dialogs). */\n\teyebrow?: ReactNode\n\t/** Leading icon tile in the title row (feature dialogs). */\n\ticon?: ReactNode\n\t/** Danger register — the title ink takes the destructive hue; the\n\t danger itself stays in copy and the confirm button. */\n\tdanger?: boolean\n\t/** Width tier; defaults to `md` (the narrow form slot). */\n\tsize?: AppDialogSize\n\t/**\n\t * Drops the body padding for workspace bodies that own their layout\n\t * edge to edge (the two-pane editors); the header keeps its padding\n\t * and the footer becomes a plain bottom bar.\n\t */\n\tflush?: boolean\n\tdescription?: ReactNode\n\tchildren: ReactNode\n\t/** Leading footer actions; body panels may append theirs via\n\t {@link DialogFooterActions}. */\n\tfooter?: ReactNode\n\tcontentClassName?: string\n\t/** Passed to dialog overlay (e.g. disable backdrop blur over WebGL). */\n\toverlayClassName?: string\n\t/** Fade-only motion — lighter than default slide/zoom when over heavy surfaces. */\n\tcontentMotion?: \"default\" | \"minimal\"\n\t/** Defaults to true. Set to false to honour native auto-focus (rare). */\n\tsuppressAutoFocus?: boolean\n\tcontentTestId?: string\n}>\n\n/**\n * Standard dialog shell. Wires up `Dialog`/`DialogContent`/`DialogHeader`/\n * `DialogTitle` and an optional eyebrow, icon, description and footer so\n * callers stop re-stating the boilerplate. Use {@link ConfirmDialog} for\n * the common \"cancel + primary action\" pattern.\n */\nexport function AppDialog(props: AppDialogProps) {\n\tconst {\n\t\topen,\n\t\tonOpenChange,\n\t\ttitle,\n\t\teyebrow,\n\t\ticon,\n\t\tdanger,\n\t\tsize,\n\t\tflush,\n\t\tdescription,\n\t\tchildren,\n\t\tfooter,\n\t\tcontentClassName,\n\t\toverlayClassName,\n\t\tcontentMotion,\n\t\tsuppressAutoFocus = true,\n\t\tcontentTestId,\n\t} = props\n\t// Focusing the first focusable element on open would steal the caret\n\t// from the page underneath, jump scroll position, and on iOS\n\t// occasionally pop the soft keyboard before the user even reaches an\n\t// input. Routing focus to the dialog container itself keeps the\n\t// dialog accessible without those side effects.\n\tconst contentRef = useRef<HTMLDivElement | null>(null)\n\n\t// Footer actions contributed by body panels (DialogFooterActions):\n\t// appended after the dialog's own footer, reset when the dialog closes.\n\tconst [footerActions, setFooterActions] = useState<ReactNode>(null)\n\tconst actionsValue = useMemo(\n\t\t() => ({ setFooterActions }),\n\t\t[setFooterActions],\n\t)\n\n\treturn (\n\t\t<Dialog open={open} onOpenChange={onOpenChange}>\n\t\t\t<DialogContent\n\t\t\t\tref={contentRef}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tsize !== undefined && sizeClasses[size],\n\t\t\t\t\tflush && \"p-0\",\n\t\t\t\t\tcontentClassName,\n\t\t\t\t)}\n\t\t\t\toverlayClassName={overlayClassName}\n\t\t\t\tcontentMotion={contentMotion}\n\t\t\t\tinitialFocus={suppressAutoFocus ? contentRef : undefined}\n\t\t\t\tdata-testid={contentTestId}\n\t\t\t>\n\t\t\t\t<DialogHeader className={flush ? \"gap-4\" : undefined}>\n\t\t\t\t\t{eyebrow !== undefined ? (\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"text-tiny font-semibold tracking-label uppercase\",\n\t\t\t\t\t\t\t\tdanger ? \"text-destructive\" : \"text-muted-foreground\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{eyebrow}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<div className=\"flex min-w-0 items-center gap-3 pr-6\">\n\t\t\t\t\t\t{icon}\n\t\t\t\t\t\t<DialogTitle\n\t\t\t\t\t\t\tclassName={cn(\"truncate\", danger && \"text-destructive\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t</DialogTitle>\n\t\t\t\t\t</div>\n\t\t\t\t\t{description !== undefined ? (\n\t\t\t\t\t\t<DialogDescription>{description}</DialogDescription>\n\t\t\t\t\t) : null}\n\t\t\t\t</DialogHeader>\n\t\t\t\t{/* The header, body and footer must stay direct children of\n\t\t\t\t DialogContent — its arrangement logic recognises them by\n\t\t\t\t type, and a wrapper in between would re-wrap the body in a\n\t\t\t\t second DialogBody. The footer-actions context therefore\n\t\t\t\t wraps only the body's own content. */}\n\t\t\t\t<DialogBody className={flush ? \"p-0\" : undefined}>\n\t\t\t\t\t<DialogFooterActionsContext.Provider value={actionsValue}>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</DialogFooterActionsContext.Provider>\n\t\t\t\t</DialogBody>\n\t\t\t\t{(footer !== undefined && footer !== null) ||\n\t\t\t\tfooterActions !== null ? (\n\t\t\t\t\t<DialogFooter flush={flush}>\n\t\t\t\t\t\t{footer}\n\t\t\t\t\t\t{footerActions}\n\t\t\t\t\t</DialogFooter>\n\t\t\t\t) : null}\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t)\n}\n","\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@hoardodile/ui/lib/utils\"\n\nfunction Label({ className, ...props }: React.ComponentProps<\"label\">) {\n return (\n <label\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n","import { Switch as SwitchPrimitive } from \"@base-ui/react/switch\"\n\nimport { cn } from \"@hoardodile/ui/lib/utils\"\n\nfunction Switch({\n className,\n size = \"default\",\n ...props\n}: SwitchPrimitive.Root.Props & {\n size?: \"sm\" | \"default\"\n}) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n data-size={size}\n className={cn(\n \"peer group/switch relative inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent shadow-xs transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-5 data-[size=default]:w-9 data-[size=default]:p-[3px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className=\"pointer-events-none block rounded-full bg-background ring-1 ring-foreground/10 transition-transform group-data-[size=default]/switch:size-3.5 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%+2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground\"\n />\n </SwitchPrimitive.Root>\n )\n}\n\nexport { Switch }\n","import { type ComponentType, createElement, useSyncExternalStore } from \"react\"\nimport type { IconType } from \"../components/icon.tsx\"\n\n/**\n * Icon-mode-aware glyph wrapper (Settings → Icons in the host app).\n *\n * The active icon style lives as `data-icon-style` on `document.documentElement`\n * — the host app writes it from its preference store, plugin iframes receive\n * it through the `themeChanged` push — so this module needs no context or\n * injected state: a single shared `MutationObserver` watches the attribute\n * and every wrapped component re-renders through `useSyncExternalStore`\n * when it flips.\n *\n * Only `linear` needs a component swap: the boldDuotone glyphs change to\n * their thin-line linear counterparts. `grayscale` is pure CSS (theme.css\n * recolors the `.hd-icon` hook), so the store only tracks the mode.\n */\nexport type IconStyleValue = \"duotone\" | \"grayscale\" | \"linear\"\n\n/**\n * The parallel Solar weights an icon registers — named after Solar's own\n * weights (DESIGN.md — Iconography). Every icon carries all of them;\n * adding a mode here forces every registry entry to fill it in.\n */\nexport type IconMode = \"bold\" | \"boldDuotone\" | \"linear\"\n\n/** All three mode glyphs of one icon. Mandatory and complete by type. */\nexport type IconVariants = Record<IconMode, IconType>\n\nfunction readIconMode(): IconMode {\n\treturn document.documentElement.dataset.iconStyle === \"linear\"\n\t\t? \"linear\"\n\t\t: \"boldDuotone\"\n}\n\n// Never read `document` at module load — pure-logic consumers (node test\n// environments) import this module without a DOM. The first subscribe\n// (component mount) snapshots the current value.\nlet currentMode: IconMode = \"boldDuotone\"\nlet observer: MutationObserver | undefined\nconst listeners = new Set<() => void>()\n\nfunction ensureObserver(): void {\n\tif (observer !== undefined || typeof document === \"undefined\") return\n\tobserver = new MutationObserver(() => {\n\t\tconst next = readIconMode()\n\t\tif (next === currentMode) return\n\t\tcurrentMode = next\n\t\tfor (const cb of listeners) cb()\n\t})\n\tobserver.observe(document.documentElement, {\n\t\tattributes: true,\n\t\tattributeFilter: [\"data-icon-style\"],\n\t})\n}\n\nfunction subscribeIconStyle(callback: () => void): () => void {\n\tensureObserver()\n\tcurrentMode = readIconMode()\n\tlisteners.add(callback)\n\treturn () => {\n\t\tlisteners.delete(callback)\n\t}\n}\n\nfunction getIconStyleSnapshot(): IconMode {\n\treturn currentMode\n}\n\n/**\n * Wraps a Solar glyph family so its render follows the host's icon style.\n *\n * `createIcon({ bold, boldDuotone, linear })` — the three parallel weights\n * of one icon. Without a `mode` prop the wrapper renders the glyph for the\n * active icon style; an explicit `mode` overrides it (selected states pass\n * `\"bold\"` through `Icon`).\n *\n * Every wrapped render merges the `hd-icon` hook class, so the duotone /\n * grayscale CSS in theme.css applies to direct renders too. Returns\n * `undefined`-free components callable through the `Icon` wrapper or bare\n * JSX alike.\n */\nexport function createIcon(\n\tvariants: IconVariants,\n): ComponentType<Record<string, unknown>> {\n\tfunction Icon(props: Record<string, unknown>) {\n\t\tconst current = useSyncExternalStore(\n\t\t\tsubscribeIconStyle,\n\t\t\tgetIconStyleSnapshot,\n\t\t\t() => \"boldDuotone\",\n\t\t)\n\t\tconst { mode, ...rest } = props as { readonly mode?: IconMode } & Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>\n\t\tconst Component = variants[(mode ?? current) as IconMode]\n\t\tconst className =\n\t\t\ttypeof rest.className === \"string\"\n\t\t\t\t? `hd-icon ${rest.className}`\n\t\t\t\t: \"hd-icon\"\n\t\treturn createElement(Component, { ...rest, className })\n\t}\n\treturn Icon\n}\n","/**\n * Central Solar icon registry for the design system.\n *\n * Every Solar glyph the app renders is exported here through `createIcon`\n * from `@hoardodile/ui` — one component per glyph carrying the three\n * parallel Solar weights (bold / boldDuotone / linear). The wrapper picks\n * the glyph for the active icon style preference (Settings → Icons): in\n * `linear` style the boldDuotone glyphs swap to their thin-line linear\n * counterparts; an explicit `mode` prop overrides (`\"bold\"` for selected\n * states). Every export carries the `hd-icon` hook class so the\n * duotone/grayscale CSS in theme.css applies to direct renders too. All\n * exports are wrapped — never the raw glyphs. Importing Solar directly is\n * confined to this file and @hoardodile/ui internals — consumers import\n * the wrapped exports only.\n *\n * Structure — imports first, one block per Solar weight (bold / bold-duotone /\n * linear, alphabetical by glyph; every glyph has all three), then one\n * export section, alphabetical by name (ordinal, case-sensitive —\n * `BookTone`'s stem `Book` sorts before `Bookmark`):\n *\n * export const <Name> = createIcon({\n * bold: <Name>BoldWeight, — filled, single-color; selected states\n * boldDuotone: <Name>BoldDuotone, — two-tone, the default\n * linear: <Name>Linear, — thin-line; `linear` icon style\n * })\n *\n * Modes are parallel and mandatory: adding a member to `IconMode` forces\n * every entry to register it (guarded by icons.test.ts). One exception:\n * `MenuDots` maps its `linear` slot to the filled weight — the thin-line\n * dots read as noise at small sizes. Tree-shaking keeps only the variants\n * actually imported.\n */\n\nimport { AddCircleIcon as AddCircleBoldWeight } from \"@solar-icons/react/bold/add-circle\"\nimport { AlignLeftIcon as AlignLeftBoldWeight } from \"@solar-icons/react/bold/align-left\"\nimport { AltArrowDownIcon as AltArrowDownBoldWeight } from \"@solar-icons/react/bold/alt-arrow-down\"\nimport { AltArrowLeftIcon as AltArrowLeftBoldWeight } from \"@solar-icons/react/bold/alt-arrow-left\"\nimport { AltArrowRightIcon as AltArrowRightBoldWeight } from \"@solar-icons/react/bold/alt-arrow-right\"\nimport { AltArrowUpIcon as AltArrowUpBoldWeight } from \"@solar-icons/react/bold/alt-arrow-up\"\nimport { ArchiveIcon as ArchiveBoldWeight } from \"@solar-icons/react/bold/archive\"\nimport { ArrowRightIcon as ArrowRightBoldWeight } from \"@solar-icons/react/bold/arrow-right\"\nimport { ArrowToTopLeftIcon as ArrowToTopLeftBoldWeight } from \"@solar-icons/react/bold/arrow-to-top-left\"\nimport { ArrowToTopRightIcon as ArrowToTopRightBoldWeight } from \"@solar-icons/react/bold/arrow-to-top-right\"\nimport { BellIcon as BellBoldWeight } from \"@solar-icons/react/bold/bell\"\nimport { BoltIcon as BoltBoldWeight } from \"@solar-icons/react/bold/bolt\"\nimport { BookIcon as BookBoldWeight } from \"@solar-icons/react/bold/book\"\nimport { Book2Icon as Book2BoldWeight } from \"@solar-icons/react/bold/book-2\"\nimport { BookmarkIcon as BookmarkBoldWeight } from \"@solar-icons/react/bold/bookmark\"\nimport { BookmarkCircleIcon as BookmarkCircleBoldWeight } from \"@solar-icons/react/bold/bookmark-circle\"\nimport { BoxIcon as BoxBoldWeight } from \"@solar-icons/react/bold/box\"\nimport { BranchingPathsUpIcon as BranchingPathsUpBoldWeight } from \"@solar-icons/react/bold/branching-paths-up\"\nimport { BugIcon as BugBoldWeight } from \"@solar-icons/react/bold/bug\"\nimport { CalendarDateIcon as CalendarDateBoldWeight } from \"@solar-icons/react/bold/calendar-date\"\nimport { ChatRoundIcon as ChatRoundBoldWeight } from \"@solar-icons/react/bold/chat-round\"\nimport { ChatRoundDotsIcon as ChatRoundDotsBoldWeight } from \"@solar-icons/react/bold/chat-round-dots\"\nimport { ChatRoundLineIcon as ChatRoundLineBoldWeight } from \"@solar-icons/react/bold/chat-round-line\"\nimport { ChatSquareIcon as ChatSquareBoldWeight } from \"@solar-icons/react/bold/chat-square\"\nimport { CheckCircleIcon as CheckCircleBoldWeight } from \"@solar-icons/react/bold/check-circle\"\nimport { ChecklistIcon as ChecklistBoldWeight } from \"@solar-icons/react/bold/checklist\"\nimport { ClipboardListIcon as ClipboardListBoldWeight } from \"@solar-icons/react/bold/clipboard-list\"\nimport { ClockCircleIcon as ClockCircleBoldWeight } from \"@solar-icons/react/bold/clock-circle\"\nimport { CompassIcon as CompassBoldWeight } from \"@solar-icons/react/bold/compass\"\nimport { CopyIcon as CopyBoldWeight } from \"@solar-icons/react/bold/copy\"\nimport { CrownIcon as CrownBoldWeight } from \"@solar-icons/react/bold/crown\"\nimport { DangerTriangleIcon as DangerTriangleBoldWeight } from \"@solar-icons/react/bold/danger-triangle\"\nimport { DatabaseIcon as DatabaseBoldWeight } from \"@solar-icons/react/bold/database\"\nimport { DisketteIcon as DisketteBoldWeight } from \"@solar-icons/react/bold/diskette\"\nimport { DislikeIcon as DislikeBoldWeight } from \"@solar-icons/react/bold/dislike\"\nimport { DocumentAddIcon as DocumentAddBoldWeight } from \"@solar-icons/react/bold/document-add\"\nimport { DocumentTextIcon as DocumentTextBoldWeight } from \"@solar-icons/react/bold/document-text\"\nimport { DoubleAltArrowDownIcon as DoubleAltArrowDownBoldWeight } from \"@solar-icons/react/bold/double-alt-arrow-down\"\nimport { DownloadIcon as DownloadBoldWeight } from \"@solar-icons/react/bold/download\"\nimport { EraserIcon as EraserBoldWeight } from \"@solar-icons/react/bold/eraser\"\nimport { EyeIcon as EyeBoldWeight } from \"@solar-icons/react/bold/eye\"\nimport { FileIcon as FileBoldWeight } from \"@solar-icons/react/bold/file\"\nimport { FileRemoveIcon as FileRemoveBoldWeight } from \"@solar-icons/react/bold/file-remove\"\nimport { FileTextIcon as FileTextBoldWeight } from \"@solar-icons/react/bold/file-text\"\nimport { FilterIcon as FilterBoldWeight } from \"@solar-icons/react/bold/filter\"\nimport { FiltersIcon as FiltersBoldWeight } from \"@solar-icons/react/bold/filters\"\nimport { FolderIcon as FolderBoldWeight } from \"@solar-icons/react/bold/folder\"\nimport { FolderOpenIcon as FolderOpenBoldWeight } from \"@solar-icons/react/bold/folder-open\"\nimport { FolderPathConnectIcon as FolderPathConnectBoldWeight } from \"@solar-icons/react/bold/folder-path-connect\"\nimport { ForbiddenCircleIcon as ForbiddenCircleBoldWeight } from \"@solar-icons/react/bold/forbidden-circle\"\nimport { GalleryIcon as GalleryBoldWeight } from \"@solar-icons/react/bold/gallery\"\nimport { GalleryAddIcon as GalleryAddBoldWeight } from \"@solar-icons/react/bold/gallery-add\"\nimport { GalleryWideIcon as GalleryWideBoldWeight } from \"@solar-icons/react/bold/gallery-wide\"\nimport { GlobalIcon as GlobalBoldWeight } from \"@solar-icons/react/bold/global\"\nimport { GraphDownIcon as GraphDownBoldWeight } from \"@solar-icons/react/bold/graph-down\"\nimport { GraphUpIcon as GraphUpBoldWeight } from \"@solar-icons/react/bold/graph-up\"\nimport { HamburgerMenuIcon as HamburgerMenuBoldWeight } from \"@solar-icons/react/bold/hamburger-menu\"\nimport { HandHeartIcon as HandHeartBoldWeight } from \"@solar-icons/react/bold/hand-heart\"\nimport { HeartIcon as HeartBoldWeight } from \"@solar-icons/react/bold/heart\"\nimport { HelpIcon as HelpBoldWeight } from \"@solar-icons/react/bold/help\"\nimport { HistoryIcon as HistoryBoldWeight } from \"@solar-icons/react/bold/history\"\nimport { HomeAngleIcon as HomeAngleBoldWeight } from \"@solar-icons/react/bold/home-angle\"\nimport { InfoCircleIcon as InfoCircleBoldWeight } from \"@solar-icons/react/bold/info-circle\"\nimport { LayersIcon as LayersBoldWeight } from \"@solar-icons/react/bold/layers\"\nimport { LetterIcon as LetterBoldWeight } from \"@solar-icons/react/bold/letter\"\nimport { LikeIcon as LikeBoldWeight } from \"@solar-icons/react/bold/like\"\nimport { LinkIcon as LinkBoldWeight } from \"@solar-icons/react/bold/link\"\nimport { ListIcon as ListBoldWeight } from \"@solar-icons/react/bold/list\"\nimport { ListVerticalIcon as ListVerticalBoldWeight } from \"@solar-icons/react/bold/list-vertical\"\nimport { LockPasswordIcon as LockPasswordBoldWeight } from \"@solar-icons/react/bold/lock-password\"\nimport { Login2Icon as Login2BoldWeight } from \"@solar-icons/react/bold/login-2\"\nimport { LogoutIcon as LogoutBoldWeight } from \"@solar-icons/react/bold/logout\"\nimport { MagicWand2Icon as MagicWand2BoldWeight } from \"@solar-icons/react/bold/magic-wand-2\"\nimport { MagnifierIcon as MagnifierBoldWeight } from \"@solar-icons/react/bold/magnifier\"\nimport { MagnifierZoomInIcon as MagnifierZoomInBoldWeight } from \"@solar-icons/react/bold/magnifier-zoom-in\"\nimport { MagnifierZoomOutIcon as MagnifierZoomOutBoldWeight } from \"@solar-icons/react/bold/magnifier-zoom-out\"\nimport { MaximizeIcon as MaximizeBoldWeight } from \"@solar-icons/react/bold/maximize\"\nimport { MenuDotsIcon as MenuDotsBoldWeight } from \"@solar-icons/react/bold/menu-dots\"\nimport { MinimizeIcon as MinimizeBoldWeight } from \"@solar-icons/react/bold/minimize\"\nimport { MinusSquareIcon as MinusSquareBoldWeight } from \"@solar-icons/react/bold/minus-square\"\nimport { MonitorIcon as MonitorBoldWeight } from \"@solar-icons/react/bold/monitor\"\nimport { MonitorSmartphoneIcon as MonitorSmartphoneBoldWeight } from \"@solar-icons/react/bold/monitor-smartphone\"\nimport { MoonIcon as MoonBoldWeight } from \"@solar-icons/react/bold/moon\"\nimport { MoveToFolderIcon as MoveToFolderBoldWeight } from \"@solar-icons/react/bold/move-to-folder\"\nimport { MusicNotesIcon as MusicNotesBoldWeight } from \"@solar-icons/react/bold/music-notes\"\nimport { PaletteIcon as PaletteBoldWeight } from \"@solar-icons/react/bold/palette\"\nimport { PaletteRoundIcon as PaletteRoundBoldWeight } from \"@solar-icons/react/bold/palette-round\"\nimport { PauseIcon as PauseBoldWeight } from \"@solar-icons/react/bold/pause\"\nimport { PenIcon as PenBoldWeight } from \"@solar-icons/react/bold/pen\"\nimport { PenNewRoundIcon as PenNewRoundBoldWeight } from \"@solar-icons/react/bold/pen-new-round\"\nimport { PieChartIcon as PieChartBoldWeight } from \"@solar-icons/react/bold/pie-chart\"\nimport { PinIcon as PinBoldWeight } from \"@solar-icons/react/bold/pin\"\nimport { PlayIcon as PlayBoldWeight } from \"@solar-icons/react/bold/play\"\nimport { PlugCircleIcon as PlugCircleBoldWeight } from \"@solar-icons/react/bold/plug-circle\"\nimport { PlusMinusIcon as PlusMinusBoldWeight } from \"@solar-icons/react/bold/plus-minus\"\nimport { PulseIcon as PulseBoldWeight } from \"@solar-icons/react/bold/pulse\"\nimport { RefreshIcon as RefreshBoldWeight } from \"@solar-icons/react/bold/refresh\"\nimport { RefreshCircleIcon as RefreshCircleBoldWeight } from \"@solar-icons/react/bold/refresh-circle\"\nimport { ReorderIcon as ReorderBoldWeight } from \"@solar-icons/react/bold/reorder\"\nimport { RepeatIcon as RepeatBoldWeight } from \"@solar-icons/react/bold/repeat\"\nimport { ReplyIcon as ReplyBoldWeight } from \"@solar-icons/react/bold/reply\"\nimport { RestartIcon as RestartBoldWeight } from \"@solar-icons/react/bold/restart\"\nimport { RocketIcon as RocketBoldWeight } from \"@solar-icons/react/bold/rocket\"\nimport { RouteIcon as RouteBoldWeight } from \"@solar-icons/react/bold/route\"\nimport { ScaleIcon as ScaleBoldWeight } from \"@solar-icons/react/bold/scale\"\nimport { ServerIcon as ServerBoldWeight } from \"@solar-icons/react/bold/server\"\nimport { SettingsIcon as SettingsBoldWeight } from \"@solar-icons/react/bold/settings\"\nimport { ShareIcon as ShareBoldWeight } from \"@solar-icons/react/bold/share\"\nimport { ShieldCheckIcon as ShieldCheckBoldWeight } from \"@solar-icons/react/bold/shield-check\"\nimport { Shop2Icon as Shop2BoldWeight } from \"@solar-icons/react/bold/shop-2\"\nimport { SidebarMinimalisticIcon as SidebarMinimalisticBoldWeight } from \"@solar-icons/react/bold/sidebar-minimalistic\"\nimport { SliderHorizontalIcon as SliderHorizontalBoldWeight } from \"@solar-icons/react/bold/slider-horizontal\"\nimport { SmartphoneIcon as SmartphoneBoldWeight } from \"@solar-icons/react/bold/smartphone\"\nimport { SortIcon as SortBoldWeight } from \"@solar-icons/react/bold/sort\"\nimport { SortByTimeIcon as SortByTimeBoldWeight } from \"@solar-icons/react/bold/sort-by-time\"\nimport { SortHorizontalIcon as SortHorizontalBoldWeight } from \"@solar-icons/react/bold/sort-horizontal\"\nimport { SortVerticalIcon as SortVerticalBoldWeight } from \"@solar-icons/react/bold/sort-vertical\"\nimport { StarIcon as StarBoldWeight } from \"@solar-icons/react/bold/star\"\nimport { StructureIcon as StructureBoldWeight } from \"@solar-icons/react/bold/structure\"\nimport { SunIcon as SunBoldWeight } from \"@solar-icons/react/bold/sun\"\nimport { TagIcon as TagBoldWeight } from \"@solar-icons/react/bold/tag\"\nimport { TelescopeIcon as TelescopeBoldWeight } from \"@solar-icons/react/bold/telescope\"\nimport { TestTubeIcon as TestTubeBoldWeight } from \"@solar-icons/react/bold/test-tube\"\nimport { TextFormatIcon as TextFormatBoldWeight } from \"@solar-icons/react/bold/text-format\"\nimport { TransferHorizontalIcon as TransferHorizontalBoldWeight } from \"@solar-icons/react/bold/transfer-horizontal\"\nimport { TranslationIcon as TranslationBoldWeight } from \"@solar-icons/react/bold/translation\"\nimport { TrashBinMinimalisticIcon as TrashBinMinimalisticBoldWeight } from \"@solar-icons/react/bold/trash-bin-minimalistic\"\nimport { UndoLeftIcon as UndoLeftBoldWeight } from \"@solar-icons/react/bold/undo-left\"\nimport { UndoLeftRoundIcon as UndoLeftRoundBoldWeight } from \"@solar-icons/react/bold/undo-left-round\"\nimport { UndoRightIcon as UndoRightBoldWeight } from \"@solar-icons/react/bold/undo-right\"\nimport { UndoRightRoundIcon as UndoRightRoundBoldWeight } from \"@solar-icons/react/bold/undo-right-round\"\nimport { UploadIcon as UploadBoldWeight } from \"@solar-icons/react/bold/upload\"\nimport { UserIcon as UserBoldWeight } from \"@solar-icons/react/bold/user\"\nimport { UserIdIcon as UserIdBoldWeight } from \"@solar-icons/react/bold/user-id\"\nimport { UserMinusIcon as UserMinusBoldWeight } from \"@solar-icons/react/bold/user-minus\"\nimport { UserPlusIcon as UserPlusBoldWeight } from \"@solar-icons/react/bold/user-plus\"\nimport { UsersGroupRoundedIcon as UsersGroupRoundedBoldWeight } from \"@solar-icons/react/bold/users-group-rounded\"\nimport { UsersGroupTwoRoundedIcon as UsersGroupTwoRoundedBoldWeight } from \"@solar-icons/react/bold/users-group-two-rounded\"\nimport { VideoFrameIcon as VideoFrameBoldWeight } from \"@solar-icons/react/bold/video-frame\"\nimport { Widget2Icon as Widget2BoldWeight } from \"@solar-icons/react/bold/widget-2\"\nimport { Widget5Icon as Widget5BoldWeight } from \"@solar-icons/react/bold/widget-5\"\nimport { WindowFrameIcon as WindowFrameBoldWeight } from \"@solar-icons/react/bold/window-frame\"\nimport { AddCircleIcon as AddCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/add-circle\"\nimport { AlignLeftIcon as AlignLeftBoldDuotone } from \"@solar-icons/react/bold-duotone/align-left\"\nimport { AltArrowDownIcon as AltArrowDownBoldDuotone } from \"@solar-icons/react/bold-duotone/alt-arrow-down\"\nimport { AltArrowLeftIcon as AltArrowLeftBoldDuotone } from \"@solar-icons/react/bold-duotone/alt-arrow-left\"\nimport { AltArrowRightIcon as AltArrowRightBoldDuotone } from \"@solar-icons/react/bold-duotone/alt-arrow-right\"\nimport { AltArrowUpIcon as AltArrowUpBoldDuotone } from \"@solar-icons/react/bold-duotone/alt-arrow-up\"\nimport { ArchiveIcon as ArchiveBoldDuotone } from \"@solar-icons/react/bold-duotone/archive\"\nimport { ArrowRightIcon as ArrowRightBoldDuotone } from \"@solar-icons/react/bold-duotone/arrow-right\"\nimport { ArrowToTopLeftIcon as ArrowToTopLeftBoldDuotone } from \"@solar-icons/react/bold-duotone/arrow-to-top-left\"\nimport { ArrowToTopRightIcon as ArrowToTopRightBoldDuotone } from \"@solar-icons/react/bold-duotone/arrow-to-top-right\"\nimport { BellIcon as BellBoldDuotone } from \"@solar-icons/react/bold-duotone/bell\"\nimport { BoltIcon as BoltBoldDuotone } from \"@solar-icons/react/bold-duotone/bolt\"\nimport { BookIcon as BookBoldDuotone } from \"@solar-icons/react/bold-duotone/book\"\nimport { Book2Icon as Book2BoldDuotone } from \"@solar-icons/react/bold-duotone/book-2\"\nimport { BookmarkIcon as BookmarkBoldDuotone } from \"@solar-icons/react/bold-duotone/bookmark\"\nimport { BookmarkCircleIcon as BookmarkCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/bookmark-circle\"\nimport { BoxIcon as BoxBoldDuotone } from \"@solar-icons/react/bold-duotone/box\"\nimport { BranchingPathsUpIcon as BranchingPathsUpBoldDuotone } from \"@solar-icons/react/bold-duotone/branching-paths-up\"\nimport { BugIcon as BugBoldDuotone } from \"@solar-icons/react/bold-duotone/bug\"\nimport { CalendarDateIcon as CalendarDateBoldDuotone } from \"@solar-icons/react/bold-duotone/calendar-date\"\nimport { ChatRoundIcon as ChatRoundBoldDuotone } from \"@solar-icons/react/bold-duotone/chat-round\"\nimport { ChatRoundDotsIcon as ChatRoundDotsBoldDuotone } from \"@solar-icons/react/bold-duotone/chat-round-dots\"\nimport { ChatRoundLineIcon as ChatRoundLineBoldDuotone } from \"@solar-icons/react/bold-duotone/chat-round-line\"\nimport { ChatSquareIcon as ChatSquareBoldDuotone } from \"@solar-icons/react/bold-duotone/chat-square\"\nimport { CheckCircleIcon as CheckCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/check-circle\"\nimport { ChecklistIcon as ChecklistBoldDuotone } from \"@solar-icons/react/bold-duotone/checklist\"\nimport { ClipboardListIcon as ClipboardListBoldDuotone } from \"@solar-icons/react/bold-duotone/clipboard-list\"\nimport { ClockCircleIcon as ClockCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/clock-circle\"\nimport { CompassIcon as CompassBoldDuotone } from \"@solar-icons/react/bold-duotone/compass\"\nimport { CopyIcon as CopyBoldDuotone } from \"@solar-icons/react/bold-duotone/copy\"\nimport { CrownIcon as CrownBoldDuotone } from \"@solar-icons/react/bold-duotone/crown\"\nimport { DangerTriangleIcon as DangerTriangleBoldDuotone } from \"@solar-icons/react/bold-duotone/danger-triangle\"\nimport { DatabaseIcon as DatabaseBoldDuotone } from \"@solar-icons/react/bold-duotone/database\"\nimport { DisketteIcon as DisketteBoldDuotone } from \"@solar-icons/react/bold-duotone/diskette\"\nimport { DislikeIcon as DislikeBoldDuotone } from \"@solar-icons/react/bold-duotone/dislike\"\nimport { DocumentAddIcon as DocumentAddBoldDuotone } from \"@solar-icons/react/bold-duotone/document-add\"\nimport { DocumentTextIcon as DocumentTextBoldDuotone } from \"@solar-icons/react/bold-duotone/document-text\"\nimport { DoubleAltArrowDownIcon as DoubleAltArrowDownBoldDuotone } from \"@solar-icons/react/bold-duotone/double-alt-arrow-down\"\nimport { DownloadIcon as DownloadBoldDuotone } from \"@solar-icons/react/bold-duotone/download\"\nimport { EraserIcon as EraserBoldDuotone } from \"@solar-icons/react/bold-duotone/eraser\"\nimport { EyeIcon as EyeBoldDuotone } from \"@solar-icons/react/bold-duotone/eye\"\nimport { FileIcon as FileBoldDuotone } from \"@solar-icons/react/bold-duotone/file\"\nimport { FileRemoveIcon as FileRemoveBoldDuotone } from \"@solar-icons/react/bold-duotone/file-remove\"\nimport { FileTextIcon as FileTextBoldDuotone } from \"@solar-icons/react/bold-duotone/file-text\"\nimport { FilterIcon as FilterBoldDuotone } from \"@solar-icons/react/bold-duotone/filter\"\nimport { FiltersIcon as FiltersBoldDuotone } from \"@solar-icons/react/bold-duotone/filters\"\nimport { FolderIcon as FolderBoldDuotone } from \"@solar-icons/react/bold-duotone/folder\"\nimport { FolderOpenIcon as FolderOpenBoldDuotone } from \"@solar-icons/react/bold-duotone/folder-open\"\nimport { FolderPathConnectIcon as FolderPathConnectBoldDuotone } from \"@solar-icons/react/bold-duotone/folder-path-connect\"\nimport { ForbiddenCircleIcon as ForbiddenCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/forbidden-circle\"\nimport { GalleryIcon as GalleryBoldDuotone } from \"@solar-icons/react/bold-duotone/gallery\"\nimport { GalleryAddIcon as GalleryAddBoldDuotone } from \"@solar-icons/react/bold-duotone/gallery-add\"\nimport { GalleryWideIcon as GalleryWideBoldDuotone } from \"@solar-icons/react/bold-duotone/gallery-wide\"\nimport { GlobalIcon as GlobalBoldDuotone } from \"@solar-icons/react/bold-duotone/global\"\nimport { GraphDownIcon as GraphDownBoldDuotone } from \"@solar-icons/react/bold-duotone/graph-down\"\nimport { GraphUpIcon as GraphUpBoldDuotone } from \"@solar-icons/react/bold-duotone/graph-up\"\nimport { HamburgerMenuIcon as HamburgerMenuBoldDuotone } from \"@solar-icons/react/bold-duotone/hamburger-menu\"\nimport { HandHeartIcon as HandHeartBoldDuotone } from \"@solar-icons/react/bold-duotone/hand-heart\"\nimport { HeartIcon as HeartBoldDuotone } from \"@solar-icons/react/bold-duotone/heart\"\nimport { HelpIcon as HelpBoldDuotone } from \"@solar-icons/react/bold-duotone/help\"\nimport { HistoryIcon as HistoryBoldDuotone } from \"@solar-icons/react/bold-duotone/history\"\nimport { HomeAngleIcon as HomeAngleBoldDuotone } from \"@solar-icons/react/bold-duotone/home-angle\"\nimport { InfoCircleIcon as InfoCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/info-circle\"\nimport { LayersIcon as LayersBoldDuotone } from \"@solar-icons/react/bold-duotone/layers\"\nimport { LetterIcon as LetterBoldDuotone } from \"@solar-icons/react/bold-duotone/letter\"\nimport { LikeIcon as LikeBoldDuotone } from \"@solar-icons/react/bold-duotone/like\"\nimport { LinkIcon as LinkBoldDuotone } from \"@solar-icons/react/bold-duotone/link\"\nimport { ListIcon as ListBoldDuotone } from \"@solar-icons/react/bold-duotone/list\"\nimport { ListVerticalIcon as ListVerticalBoldDuotone } from \"@solar-icons/react/bold-duotone/list-vertical\"\nimport { LockPasswordIcon as LockPasswordBoldDuotone } from \"@solar-icons/react/bold-duotone/lock-password\"\nimport { Login2Icon as Login2BoldDuotone } from \"@solar-icons/react/bold-duotone/login-2\"\nimport { LogoutIcon as LogoutBoldDuotone } from \"@solar-icons/react/bold-duotone/logout\"\nimport { MagicWand2Icon as MagicWand2BoldDuotone } from \"@solar-icons/react/bold-duotone/magic-wand-2\"\nimport { MagnifierIcon as MagnifierBoldDuotone } from \"@solar-icons/react/bold-duotone/magnifier\"\nimport { MagnifierZoomInIcon as MagnifierZoomInBoldDuotone } from \"@solar-icons/react/bold-duotone/magnifier-zoom-in\"\nimport { MagnifierZoomOutIcon as MagnifierZoomOutBoldDuotone } from \"@solar-icons/react/bold-duotone/magnifier-zoom-out\"\nimport { MaximizeIcon as MaximizeBoldDuotone } from \"@solar-icons/react/bold-duotone/maximize\"\nimport { MenuDotsIcon as MenuDotsBoldDuotone } from \"@solar-icons/react/bold-duotone/menu-dots\"\nimport { MinimizeIcon as MinimizeBoldDuotone } from \"@solar-icons/react/bold-duotone/minimize\"\nimport { MinusSquareIcon as MinusSquareBoldDuotone } from \"@solar-icons/react/bold-duotone/minus-square\"\nimport { MonitorIcon as MonitorBoldDuotone } from \"@solar-icons/react/bold-duotone/monitor\"\nimport { MonitorSmartphoneIcon as MonitorSmartphoneBoldDuotone } from \"@solar-icons/react/bold-duotone/monitor-smartphone\"\nimport { MoonIcon as MoonBoldDuotone } from \"@solar-icons/react/bold-duotone/moon\"\nimport { MoveToFolderIcon as MoveToFolderBoldDuotone } from \"@solar-icons/react/bold-duotone/move-to-folder\"\nimport { MusicNotesIcon as MusicNotesBoldDuotone } from \"@solar-icons/react/bold-duotone/music-notes\"\nimport { PaletteIcon as PaletteBoldDuotone } from \"@solar-icons/react/bold-duotone/palette\"\nimport { PaletteRoundIcon as PaletteRoundBoldDuotone } from \"@solar-icons/react/bold-duotone/palette-round\"\nimport { PauseIcon as PauseBoldDuotone } from \"@solar-icons/react/bold-duotone/pause\"\nimport { PenIcon as PenBoldDuotone } from \"@solar-icons/react/bold-duotone/pen\"\nimport { PenNewRoundIcon as PenNewRoundBoldDuotone } from \"@solar-icons/react/bold-duotone/pen-new-round\"\nimport { PieChartIcon as PieChartBoldDuotone } from \"@solar-icons/react/bold-duotone/pie-chart\"\nimport { PinIcon as PinBoldDuotone } from \"@solar-icons/react/bold-duotone/pin\"\nimport { PlayIcon as PlayBoldDuotone } from \"@solar-icons/react/bold-duotone/play\"\nimport { PlugCircleIcon as PlugCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/plug-circle\"\nimport { PlusMinusIcon as PlusMinusBoldDuotone } from \"@solar-icons/react/bold-duotone/plus-minus\"\nimport { PulseIcon as PulseBoldDuotone } from \"@solar-icons/react/bold-duotone/pulse\"\nimport { RefreshIcon as RefreshBoldDuotone } from \"@solar-icons/react/bold-duotone/refresh\"\nimport { RefreshCircleIcon as RefreshCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/refresh-circle\"\nimport { ReorderIcon as ReorderBoldDuotone } from \"@solar-icons/react/bold-duotone/reorder\"\nimport { RepeatIcon as RepeatBoldDuotone } from \"@solar-icons/react/bold-duotone/repeat\"\nimport { ReplyIcon as ReplyBoldDuotone } from \"@solar-icons/react/bold-duotone/reply\"\nimport { RestartIcon as RestartBoldDuotone } from \"@solar-icons/react/bold-duotone/restart\"\nimport { RocketIcon as RocketBoldDuotone } from \"@solar-icons/react/bold-duotone/rocket\"\nimport { RouteIcon as RouteBoldDuotone } from \"@solar-icons/react/bold-duotone/route\"\nimport { ScaleIcon as ScaleBoldDuotone } from \"@solar-icons/react/bold-duotone/scale\"\nimport { ServerIcon as ServerBoldDuotone } from \"@solar-icons/react/bold-duotone/server\"\nimport { SettingsIcon as SettingsBoldDuotone } from \"@solar-icons/react/bold-duotone/settings\"\nimport { ShareIcon as ShareBoldDuotone } from \"@solar-icons/react/bold-duotone/share\"\nimport { ShieldCheckIcon as ShieldCheckBoldDuotone } from \"@solar-icons/react/bold-duotone/shield-check\"\nimport { Shop2Icon as Shop2BoldDuotone } from \"@solar-icons/react/bold-duotone/shop-2\"\nimport { SidebarMinimalisticIcon as SidebarMinimalisticBoldDuotone } from \"@solar-icons/react/bold-duotone/sidebar-minimalistic\"\nimport { SliderHorizontalIcon as SliderHorizontalBoldDuotone } from \"@solar-icons/react/bold-duotone/slider-horizontal\"\nimport { SmartphoneIcon as SmartphoneBoldDuotone } from \"@solar-icons/react/bold-duotone/smartphone\"\nimport { SortIcon as SortBoldDuotone } from \"@solar-icons/react/bold-duotone/sort\"\nimport { SortByTimeIcon as SortByTimeBoldDuotone } from \"@solar-icons/react/bold-duotone/sort-by-time\"\nimport { SortHorizontalIcon as SortHorizontalBoldDuotone } from \"@solar-icons/react/bold-duotone/sort-horizontal\"\nimport { SortVerticalIcon as SortVerticalBoldDuotone } from \"@solar-icons/react/bold-duotone/sort-vertical\"\nimport { StarIcon as StarBoldDuotone } from \"@solar-icons/react/bold-duotone/star\"\nimport { StructureIcon as StructureBoldDuotone } from \"@solar-icons/react/bold-duotone/structure\"\nimport { SunIcon as SunBoldDuotone } from \"@solar-icons/react/bold-duotone/sun\"\nimport { TagIcon as TagBoldDuotone } from \"@solar-icons/react/bold-duotone/tag\"\nimport { TelescopeIcon as TelescopeBoldDuotone } from \"@solar-icons/react/bold-duotone/telescope\"\nimport { TestTubeIcon as TestTubeBoldDuotone } from \"@solar-icons/react/bold-duotone/test-tube\"\nimport { TextFormatIcon as TextFormatBoldDuotone } from \"@solar-icons/react/bold-duotone/text-format\"\nimport { TransferHorizontalIcon as TransferHorizontalBoldDuotone } from \"@solar-icons/react/bold-duotone/transfer-horizontal\"\nimport { TranslationIcon as TranslationBoldDuotone } from \"@solar-icons/react/bold-duotone/translation\"\nimport { TrashBinMinimalisticIcon as TrashBinMinimalisticBoldDuotone } from \"@solar-icons/react/bold-duotone/trash-bin-minimalistic\"\nimport { UndoLeftIcon as UndoLeftBoldDuotone } from \"@solar-icons/react/bold-duotone/undo-left\"\nimport { UndoLeftRoundIcon as UndoLeftRoundBoldDuotone } from \"@solar-icons/react/bold-duotone/undo-left-round\"\nimport { UndoRightIcon as UndoRightBoldDuotone } from \"@solar-icons/react/bold-duotone/undo-right\"\nimport { UndoRightRoundIcon as UndoRightRoundBoldDuotone } from \"@solar-icons/react/bold-duotone/undo-right-round\"\nimport { UploadIcon as UploadBoldDuotone } from \"@solar-icons/react/bold-duotone/upload\"\nimport { UserIcon as UserBoldDuotone } from \"@solar-icons/react/bold-duotone/user\"\nimport { UserIdIcon as UserIdBoldDuotone } from \"@solar-icons/react/bold-duotone/user-id\"\nimport { UserMinusIcon as UserMinusBoldDuotone } from \"@solar-icons/react/bold-duotone/user-minus\"\nimport { UserPlusIcon as UserPlusBoldDuotone } from \"@solar-icons/react/bold-duotone/user-plus\"\nimport { UsersGroupRoundedIcon as UsersGroupRoundedBoldDuotone } from \"@solar-icons/react/bold-duotone/users-group-rounded\"\nimport { UsersGroupTwoRoundedIcon as UsersGroupTwoRoundedBoldDuotone } from \"@solar-icons/react/bold-duotone/users-group-two-rounded\"\nimport { VideoFrameIcon as VideoFrameBoldDuotone } from \"@solar-icons/react/bold-duotone/video-frame\"\nimport { Widget2Icon as Widget2BoldDuotone } from \"@solar-icons/react/bold-duotone/widget-2\"\nimport { Widget5Icon as Widget5BoldDuotone } from \"@solar-icons/react/bold-duotone/widget-5\"\nimport { WindowFrameIcon as WindowFrameBoldDuotone } from \"@solar-icons/react/bold-duotone/window-frame\"\nimport { AddCircleIcon as AddCircleLinear } from \"@solar-icons/react/linear/add-circle\"\nimport { AlignLeftIcon as AlignLeftLinear } from \"@solar-icons/react/linear/align-left\"\nimport { AltArrowDownIcon as AltArrowDownLinear } from \"@solar-icons/react/linear/alt-arrow-down\"\nimport { AltArrowLeftIcon as AltArrowLeftLinear } from \"@solar-icons/react/linear/alt-arrow-left\"\nimport { AltArrowRightIcon as AltArrowRightLinear } from \"@solar-icons/react/linear/alt-arrow-right\"\nimport { AltArrowUpIcon as AltArrowUpLinear } from \"@solar-icons/react/linear/alt-arrow-up\"\nimport { ArchiveIcon as ArchiveLinear } from \"@solar-icons/react/linear/archive\"\nimport { ArrowRightIcon as ArrowRightLinear } from \"@solar-icons/react/linear/arrow-right\"\nimport { ArrowToTopLeftIcon as ArrowToTopLeftLinear } from \"@solar-icons/react/linear/arrow-to-top-left\"\nimport { ArrowToTopRightIcon as ArrowToTopRightLinear } from \"@solar-icons/react/linear/arrow-to-top-right\"\nimport { BellIcon as BellLinear } from \"@solar-icons/react/linear/bell\"\nimport { BoltIcon as BoltLinear } from \"@solar-icons/react/linear/bolt\"\nimport { BookIcon as BookLinear } from \"@solar-icons/react/linear/book\"\nimport { Book2Icon as Book2Linear } from \"@solar-icons/react/linear/book-2\"\nimport { BookmarkIcon as BookmarkLinear } from \"@solar-icons/react/linear/bookmark\"\nimport { BookmarkCircleIcon as BookmarkCircleLinear } from \"@solar-icons/react/linear/bookmark-circle\"\nimport { BoxIcon as BoxLinear } from \"@solar-icons/react/linear/box\"\nimport { BranchingPathsUpIcon as BranchingPathsUpLinear } from \"@solar-icons/react/linear/branching-paths-up\"\nimport { BugIcon as BugLinear } from \"@solar-icons/react/linear/bug\"\nimport { CalendarDateIcon as CalendarDateLinear } from \"@solar-icons/react/linear/calendar-date\"\nimport { ChatRoundIcon as ChatRoundLinear } from \"@solar-icons/react/linear/chat-round\"\nimport { ChatRoundDotsIcon as ChatRoundDotsLinear } from \"@solar-icons/react/linear/chat-round-dots\"\nimport { ChatRoundLineIcon as ChatRoundLineLinear } from \"@solar-icons/react/linear/chat-round-line\"\nimport { ChatSquareIcon as ChatSquareLinear } from \"@solar-icons/react/linear/chat-square\"\nimport { CheckCircleIcon as CheckCircleLinear } from \"@solar-icons/react/linear/check-circle\"\nimport { ChecklistIcon as ChecklistLinear } from \"@solar-icons/react/linear/checklist\"\nimport { ClipboardListIcon as ClipboardListLinear } from \"@solar-icons/react/linear/clipboard-list\"\nimport { ClockCircleIcon as ClockCircleLinear } from \"@solar-icons/react/linear/clock-circle\"\nimport { CompassIcon as CompassLinear } from \"@solar-icons/react/linear/compass\"\nimport { CopyIcon as CopyLinear } from \"@solar-icons/react/linear/copy\"\nimport { CrownIcon as CrownLinear } from \"@solar-icons/react/linear/crown\"\nimport { DangerTriangleIcon as DangerTriangleLinear } from \"@solar-icons/react/linear/danger-triangle\"\nimport { DatabaseIcon as DatabaseLinear } from \"@solar-icons/react/linear/database\"\nimport { DisketteIcon as DisketteLinear } from \"@solar-icons/react/linear/diskette\"\nimport { DislikeIcon as DislikeLinear } from \"@solar-icons/react/linear/dislike\"\nimport { DocumentAddIcon as DocumentAddLinear } from \"@solar-icons/react/linear/document-add\"\nimport { DocumentTextIcon as DocumentTextLinear } from \"@solar-icons/react/linear/document-text\"\nimport { DoubleAltArrowDownIcon as DoubleAltArrowDownLinear } from \"@solar-icons/react/linear/double-alt-arrow-down\"\nimport { DownloadIcon as DownloadLinear } from \"@solar-icons/react/linear/download\"\nimport { EraserIcon as EraserLinear } from \"@solar-icons/react/linear/eraser\"\nimport { EyeIcon as EyeLinear } from \"@solar-icons/react/linear/eye\"\nimport { FileIcon as FileLinear } from \"@solar-icons/react/linear/file\"\nimport { FileRemoveIcon as FileRemoveLinear } from \"@solar-icons/react/linear/file-remove\"\nimport { FileTextIcon as FileTextLinear } from \"@solar-icons/react/linear/file-text\"\nimport { FilterIcon as FilterLinear } from \"@solar-icons/react/linear/filter\"\nimport { FiltersIcon as FiltersLinear } from \"@solar-icons/react/linear/filters\"\nimport { FolderIcon as FolderLinear } from \"@solar-icons/react/linear/folder\"\nimport { FolderOpenIcon as FolderOpenLinear } from \"@solar-icons/react/linear/folder-open\"\nimport { FolderPathConnectIcon as FolderPathConnectLinear } from \"@solar-icons/react/linear/folder-path-connect\"\nimport { ForbiddenCircleIcon as ForbiddenCircleLinear } from \"@solar-icons/react/linear/forbidden-circle\"\nimport { GalleryIcon as GalleryLinear } from \"@solar-icons/react/linear/gallery\"\nimport { GalleryAddIcon as GalleryAddLinear } from \"@solar-icons/react/linear/gallery-add\"\nimport { GalleryWideIcon as GalleryWideLinear } from \"@solar-icons/react/linear/gallery-wide\"\nimport { GlobalIcon as GlobalLinear } from \"@solar-icons/react/linear/global\"\nimport { GraphDownIcon as GraphDownLinear } from \"@solar-icons/react/linear/graph-down\"\nimport { GraphUpIcon as GraphUpLinear } from \"@solar-icons/react/linear/graph-up\"\nimport { HamburgerMenuIcon as HamburgerMenuLinear } from \"@solar-icons/react/linear/hamburger-menu\"\nimport { HandHeartIcon as HandHeartLinear } from \"@solar-icons/react/linear/hand-heart\"\nimport { HeartIcon as HeartLinear } from \"@solar-icons/react/linear/heart\"\nimport { HelpIcon as HelpLinear } from \"@solar-icons/react/linear/help\"\nimport { HistoryIcon as HistoryLinear } from \"@solar-icons/react/linear/history\"\nimport { HomeAngleIcon as HomeAngleLinear } from \"@solar-icons/react/linear/home-angle\"\nimport { InfoCircleIcon as InfoCircleLinear } from \"@solar-icons/react/linear/info-circle\"\nimport { LayersIcon as LayersLinear } from \"@solar-icons/react/linear/layers\"\nimport { LetterIcon as LetterLinear } from \"@solar-icons/react/linear/letter\"\nimport { LikeIcon as LikeLinear } from \"@solar-icons/react/linear/like\"\nimport { LinkIcon as LinkLinear } from \"@solar-icons/react/linear/link\"\nimport { ListIcon as ListLinear } from \"@solar-icons/react/linear/list\"\nimport { ListVerticalIcon as ListVerticalLinear } from \"@solar-icons/react/linear/list-vertical\"\nimport { LockPasswordIcon as LockPasswordLinear } from \"@solar-icons/react/linear/lock-password\"\nimport { Login2Icon as Login2Linear } from \"@solar-icons/react/linear/login-2\"\nimport { LogoutIcon as LogoutLinear } from \"@solar-icons/react/linear/logout\"\nimport { MagicWand2Icon as MagicWand2Linear } from \"@solar-icons/react/linear/magic-wand-2\"\nimport { MagnifierIcon as MagnifierLinear } from \"@solar-icons/react/linear/magnifier\"\nimport { MagnifierZoomInIcon as MagnifierZoomInLinear } from \"@solar-icons/react/linear/magnifier-zoom-in\"\nimport { MagnifierZoomOutIcon as MagnifierZoomOutLinear } from \"@solar-icons/react/linear/magnifier-zoom-out\"\nimport { MaximizeIcon as MaximizeLinear } from \"@solar-icons/react/linear/maximize\"\nimport { MinimizeIcon as MinimizeLinear } from \"@solar-icons/react/linear/minimize\"\nimport { MinusSquareIcon as MinusSquareLinear } from \"@solar-icons/react/linear/minus-square\"\nimport { MonitorIcon as MonitorLinear } from \"@solar-icons/react/linear/monitor\"\nimport { MonitorSmartphoneIcon as MonitorSmartphoneLinear } from \"@solar-icons/react/linear/monitor-smartphone\"\nimport { MoonIcon as MoonLinear } from \"@solar-icons/react/linear/moon\"\nimport { MoveToFolderIcon as MoveToFolderLinear } from \"@solar-icons/react/linear/move-to-folder\"\nimport { MusicNotesIcon as MusicNotesLinear } from \"@solar-icons/react/linear/music-notes\"\nimport { PaletteIcon as PaletteLinear } from \"@solar-icons/react/linear/palette\"\nimport { PaletteRoundIcon as PaletteRoundLinear } from \"@solar-icons/react/linear/palette-round\"\nimport { PauseIcon as PauseLinear } from \"@solar-icons/react/linear/pause\"\nimport { PenIcon as PenLinear } from \"@solar-icons/react/linear/pen\"\nimport { PenNewRoundIcon as PenNewRoundLinear } from \"@solar-icons/react/linear/pen-new-round\"\nimport { PieChartIcon as PieChartLinear } from \"@solar-icons/react/linear/pie-chart\"\nimport { PinIcon as PinLinear } from \"@solar-icons/react/linear/pin\"\nimport { PlayIcon as PlayLinear } from \"@solar-icons/react/linear/play\"\nimport { PlugCircleIcon as PlugCircleLinear } from \"@solar-icons/react/linear/plug-circle\"\nimport { PlusMinusIcon as PlusMinusLinear } from \"@solar-icons/react/linear/plus-minus\"\nimport { PulseIcon as PulseLinear } from \"@solar-icons/react/linear/pulse\"\nimport { RefreshIcon as RefreshLinear } from \"@solar-icons/react/linear/refresh\"\nimport { RefreshCircleIcon as RefreshCircleLinear } from \"@solar-icons/react/linear/refresh-circle\"\nimport { ReorderIcon as ReorderLinear } from \"@solar-icons/react/linear/reorder\"\nimport { RepeatIcon as RepeatLinear } from \"@solar-icons/react/linear/repeat\"\nimport { ReplyIcon as ReplyLinear } from \"@solar-icons/react/linear/reply\"\nimport { RestartIcon as RestartLinear } from \"@solar-icons/react/linear/restart\"\nimport { RocketIcon as RocketLinear } from \"@solar-icons/react/linear/rocket\"\nimport { RouteIcon as RouteLinear } from \"@solar-icons/react/linear/route\"\nimport { ScaleIcon as ScaleLinear } from \"@solar-icons/react/linear/scale\"\nimport { ServerIcon as ServerLinear } from \"@solar-icons/react/linear/server\"\nimport { SettingsIcon as SettingsLinear } from \"@solar-icons/react/linear/settings\"\nimport { ShareIcon as ShareLinear } from \"@solar-icons/react/linear/share\"\nimport { ShieldCheckIcon as ShieldCheckLinear } from \"@solar-icons/react/linear/shield-check\"\nimport { Shop2Icon as Shop2Linear } from \"@solar-icons/react/linear/shop-2\"\nimport { SidebarMinimalisticIcon as SidebarMinimalisticLinear } from \"@solar-icons/react/linear/sidebar-minimalistic\"\nimport { SliderHorizontalIcon as SliderHorizontalLinear } from \"@solar-icons/react/linear/slider-horizontal\"\nimport { SmartphoneIcon as SmartphoneLinear } from \"@solar-icons/react/linear/smartphone\"\nimport { SortIcon as SortLinear } from \"@solar-icons/react/linear/sort\"\nimport { SortByTimeIcon as SortByTimeLinear } from \"@solar-icons/react/linear/sort-by-time\"\nimport { SortHorizontalIcon as SortHorizontalLinear } from \"@solar-icons/react/linear/sort-horizontal\"\nimport { SortVerticalIcon as SortVerticalLinear } from \"@solar-icons/react/linear/sort-vertical\"\nimport { StarIcon as StarLinear } from \"@solar-icons/react/linear/star\"\nimport { StructureIcon as StructureLinear } from \"@solar-icons/react/linear/structure\"\nimport { SunIcon as SunLinear } from \"@solar-icons/react/linear/sun\"\nimport { TagIcon as TagLinear } from \"@solar-icons/react/linear/tag\"\nimport { TelescopeIcon as TelescopeLinear } from \"@solar-icons/react/linear/telescope\"\nimport { TestTubeIcon as TestTubeLinear } from \"@solar-icons/react/linear/test-tube\"\nimport { TextFormatIcon as TextFormatLinear } from \"@solar-icons/react/linear/text-format\"\nimport { TransferHorizontalIcon as TransferHorizontalLinear } from \"@solar-icons/react/linear/transfer-horizontal\"\nimport { TranslationIcon as TranslationLinear } from \"@solar-icons/react/linear/translation\"\nimport { TrashBinMinimalisticIcon as TrashBinMinimalisticLinear } from \"@solar-icons/react/linear/trash-bin-minimalistic\"\nimport { UndoLeftIcon as UndoLeftLinear } from \"@solar-icons/react/linear/undo-left\"\nimport { UndoLeftRoundIcon as UndoLeftRoundLinear } from \"@solar-icons/react/linear/undo-left-round\"\nimport { UndoRightIcon as UndoRightLinear } from \"@solar-icons/react/linear/undo-right\"\nimport { UndoRightRoundIcon as UndoRightRoundLinear } from \"@solar-icons/react/linear/undo-right-round\"\nimport { UploadIcon as UploadLinear } from \"@solar-icons/react/linear/upload\"\nimport { UserIcon as UserLinear } from \"@solar-icons/react/linear/user\"\nimport { UserIdIcon as UserIdLinear } from \"@solar-icons/react/linear/user-id\"\nimport { UserMinusIcon as UserMinusLinear } from \"@solar-icons/react/linear/user-minus\"\nimport { UserPlusIcon as UserPlusLinear } from \"@solar-icons/react/linear/user-plus\"\nimport { UsersGroupRoundedIcon as UsersGroupRoundedLinear } from \"@solar-icons/react/linear/users-group-rounded\"\nimport { UsersGroupTwoRoundedIcon as UsersGroupTwoRoundedLinear } from \"@solar-icons/react/linear/users-group-two-rounded\"\nimport { VideoFrameIcon as VideoFrameLinear } from \"@solar-icons/react/linear/video-frame\"\nimport { Widget2Icon as Widget2Linear } from \"@solar-icons/react/linear/widget-2\"\nimport { Widget5Icon as Widget5Linear } from \"@solar-icons/react/linear/widget-5\"\nimport { WindowFrameIcon as WindowFrameLinear } from \"@solar-icons/react/linear/window-frame\"\nimport { createIcon } from \"./icon-style\"\n\n// ── One icon per glyph - three parallel Solar weights ────────────\nexport const AddCircle = createIcon({\n\tbold: AddCircleBoldWeight,\n\tboldDuotone: AddCircleBoldDuotone,\n\tlinear: AddCircleLinear,\n})\nexport const AlignLeft = createIcon({\n\tbold: AlignLeftBoldWeight,\n\tboldDuotone: AlignLeftBoldDuotone,\n\tlinear: AlignLeftLinear,\n})\nexport const AltArrowDown = createIcon({\n\tbold: AltArrowDownBoldWeight,\n\tboldDuotone: AltArrowDownBoldDuotone,\n\tlinear: AltArrowDownLinear,\n})\nexport const AltArrowLeft = createIcon({\n\tbold: AltArrowLeftBoldWeight,\n\tboldDuotone: AltArrowLeftBoldDuotone,\n\tlinear: AltArrowLeftLinear,\n})\nexport const AltArrowRight = createIcon({\n\tbold: AltArrowRightBoldWeight,\n\tboldDuotone: AltArrowRightBoldDuotone,\n\tlinear: AltArrowRightLinear,\n})\nexport const AltArrowUp = createIcon({\n\tbold: AltArrowUpBoldWeight,\n\tboldDuotone: AltArrowUpBoldDuotone,\n\tlinear: AltArrowUpLinear,\n})\nexport const Archive = createIcon({\n\tbold: ArchiveBoldWeight,\n\tboldDuotone: ArchiveBoldDuotone,\n\tlinear: ArchiveLinear,\n})\nexport const ArrowRight = createIcon({\n\tbold: ArrowRightBoldWeight,\n\tboldDuotone: ArrowRightBoldDuotone,\n\tlinear: ArrowRightLinear,\n})\nexport const ArrowToTopLeft = createIcon({\n\tbold: ArrowToTopLeftBoldWeight,\n\tboldDuotone: ArrowToTopLeftBoldDuotone,\n\tlinear: ArrowToTopLeftLinear,\n})\nexport const ArrowToTopRight = createIcon({\n\tbold: ArrowToTopRightBoldWeight,\n\tboldDuotone: ArrowToTopRightBoldDuotone,\n\tlinear: ArrowToTopRightLinear,\n})\nexport const Bell = createIcon({\n\tbold: BellBoldWeight,\n\tboldDuotone: BellBoldDuotone,\n\tlinear: BellLinear,\n})\nexport const Bolt = createIcon({\n\tbold: BoltBoldWeight,\n\tboldDuotone: BoltBoldDuotone,\n\tlinear: BoltLinear,\n})\nexport const Book = createIcon({\n\tbold: BookBoldWeight,\n\tboldDuotone: BookBoldDuotone,\n\tlinear: BookLinear,\n})\nexport const Book2 = createIcon({\n\tbold: Book2BoldWeight,\n\tboldDuotone: Book2BoldDuotone,\n\tlinear: Book2Linear,\n})\nexport const Bookmark = createIcon({\n\tbold: BookmarkBoldWeight,\n\tboldDuotone: BookmarkBoldDuotone,\n\tlinear: BookmarkLinear,\n})\nexport const BookmarkCircle = createIcon({\n\tbold: BookmarkCircleBoldWeight,\n\tboldDuotone: BookmarkCircleBoldDuotone,\n\tlinear: BookmarkCircleLinear,\n})\nexport const Box = createIcon({\n\tbold: BoxBoldWeight,\n\tboldDuotone: BoxBoldDuotone,\n\tlinear: BoxLinear,\n})\nexport const BranchingPathsUp = createIcon({\n\tbold: BranchingPathsUpBoldWeight,\n\tboldDuotone: BranchingPathsUpBoldDuotone,\n\tlinear: BranchingPathsUpLinear,\n})\nexport const Bug = createIcon({\n\tbold: BugBoldWeight,\n\tboldDuotone: BugBoldDuotone,\n\tlinear: BugLinear,\n})\nexport const CalendarDate = createIcon({\n\tbold: CalendarDateBoldWeight,\n\tboldDuotone: CalendarDateBoldDuotone,\n\tlinear: CalendarDateLinear,\n})\nexport const ChatRound = createIcon({\n\tbold: ChatRoundBoldWeight,\n\tboldDuotone: ChatRoundBoldDuotone,\n\tlinear: ChatRoundLinear,\n})\nexport const ChatRoundDots = createIcon({\n\tbold: ChatRoundDotsBoldWeight,\n\tboldDuotone: ChatRoundDotsBoldDuotone,\n\tlinear: ChatRoundDotsLinear,\n})\nexport const ChatRoundLine = createIcon({\n\tbold: ChatRoundLineBoldWeight,\n\tboldDuotone: ChatRoundLineBoldDuotone,\n\tlinear: ChatRoundLineLinear,\n})\nexport const ChatSquare = createIcon({\n\tbold: ChatSquareBoldWeight,\n\tboldDuotone: ChatSquareBoldDuotone,\n\tlinear: ChatSquareLinear,\n})\nexport const CheckCircle = createIcon({\n\tbold: CheckCircleBoldWeight,\n\tboldDuotone: CheckCircleBoldDuotone,\n\tlinear: CheckCircleLinear,\n})\nexport const Checklist = createIcon({\n\tbold: ChecklistBoldWeight,\n\tboldDuotone: ChecklistBoldDuotone,\n\tlinear: ChecklistLinear,\n})\nexport const ClipboardList = createIcon({\n\tbold: ClipboardListBoldWeight,\n\tboldDuotone: ClipboardListBoldDuotone,\n\tlinear: ClipboardListLinear,\n})\nexport const ClockCircle = createIcon({\n\tbold: ClockCircleBoldWeight,\n\tboldDuotone: ClockCircleBoldDuotone,\n\tlinear: ClockCircleLinear,\n})\nexport const Compass = createIcon({\n\tbold: CompassBoldWeight,\n\tboldDuotone: CompassBoldDuotone,\n\tlinear: CompassLinear,\n})\nexport const Copy = createIcon({\n\tbold: CopyBoldWeight,\n\tboldDuotone: CopyBoldDuotone,\n\tlinear: CopyLinear,\n})\nexport const Crown = createIcon({\n\tbold: CrownBoldWeight,\n\tboldDuotone: CrownBoldDuotone,\n\tlinear: CrownLinear,\n})\nexport const DangerTriangle = createIcon({\n\tbold: DangerTriangleBoldWeight,\n\tboldDuotone: DangerTriangleBoldDuotone,\n\tlinear: DangerTriangleLinear,\n})\nexport const Database = createIcon({\n\tbold: DatabaseBoldWeight,\n\tboldDuotone: DatabaseBoldDuotone,\n\tlinear: DatabaseLinear,\n})\nexport const Diskette = createIcon({\n\tbold: DisketteBoldWeight,\n\tboldDuotone: DisketteBoldDuotone,\n\tlinear: DisketteLinear,\n})\nexport const Dislike = createIcon({\n\tbold: DislikeBoldWeight,\n\tboldDuotone: DislikeBoldDuotone,\n\tlinear: DislikeLinear,\n})\nexport const DocumentAdd = createIcon({\n\tbold: DocumentAddBoldWeight,\n\tboldDuotone: DocumentAddBoldDuotone,\n\tlinear: DocumentAddLinear,\n})\nexport const DocumentText = createIcon({\n\tbold: DocumentTextBoldWeight,\n\tboldDuotone: DocumentTextBoldDuotone,\n\tlinear: DocumentTextLinear,\n})\nexport const DoubleAltArrowDown = createIcon({\n\tbold: DoubleAltArrowDownBoldWeight,\n\tboldDuotone: DoubleAltArrowDownBoldDuotone,\n\tlinear: DoubleAltArrowDownLinear,\n})\nexport const Download = createIcon({\n\tbold: DownloadBoldWeight,\n\tboldDuotone: DownloadBoldDuotone,\n\tlinear: DownloadLinear,\n})\nexport const Eraser = createIcon({\n\tbold: EraserBoldWeight,\n\tboldDuotone: EraserBoldDuotone,\n\tlinear: EraserLinear,\n})\nexport const Eye = createIcon({\n\tbold: EyeBoldWeight,\n\tboldDuotone: EyeBoldDuotone,\n\tlinear: EyeLinear,\n})\nexport const File = createIcon({\n\tbold: FileBoldWeight,\n\tboldDuotone: FileBoldDuotone,\n\tlinear: FileLinear,\n})\nexport const FileRemove = createIcon({\n\tbold: FileRemoveBoldWeight,\n\tboldDuotone: FileRemoveBoldDuotone,\n\tlinear: FileRemoveLinear,\n})\nexport const FileText = createIcon({\n\tbold: FileTextBoldWeight,\n\tboldDuotone: FileTextBoldDuotone,\n\tlinear: FileTextLinear,\n})\nexport const Filter = createIcon({\n\tbold: FilterBoldWeight,\n\tboldDuotone: FilterBoldDuotone,\n\tlinear: FilterLinear,\n})\nexport const Filters = createIcon({\n\tbold: FiltersBoldWeight,\n\tboldDuotone: FiltersBoldDuotone,\n\tlinear: FiltersLinear,\n})\nexport const Folder = createIcon({\n\tbold: FolderBoldWeight,\n\tboldDuotone: FolderBoldDuotone,\n\tlinear: FolderLinear,\n})\nexport const FolderOpen = createIcon({\n\tbold: FolderOpenBoldWeight,\n\tboldDuotone: FolderOpenBoldDuotone,\n\tlinear: FolderOpenLinear,\n})\nexport const FolderPathConnect = createIcon({\n\tbold: FolderPathConnectBoldWeight,\n\tboldDuotone: FolderPathConnectBoldDuotone,\n\tlinear: FolderPathConnectLinear,\n})\nexport const ForbiddenCircle = createIcon({\n\tbold: ForbiddenCircleBoldWeight,\n\tboldDuotone: ForbiddenCircleBoldDuotone,\n\tlinear: ForbiddenCircleLinear,\n})\nexport const Gallery = createIcon({\n\tbold: GalleryBoldWeight,\n\tboldDuotone: GalleryBoldDuotone,\n\tlinear: GalleryLinear,\n})\nexport const GalleryAdd = createIcon({\n\tbold: GalleryAddBoldWeight,\n\tboldDuotone: GalleryAddBoldDuotone,\n\tlinear: GalleryAddLinear,\n})\nexport const GalleryWide = createIcon({\n\tbold: GalleryWideBoldWeight,\n\tboldDuotone: GalleryWideBoldDuotone,\n\tlinear: GalleryWideLinear,\n})\nexport const Global = createIcon({\n\tbold: GlobalBoldWeight,\n\tboldDuotone: GlobalBoldDuotone,\n\tlinear: GlobalLinear,\n})\nexport const GraphDown = createIcon({\n\tbold: GraphDownBoldWeight,\n\tboldDuotone: GraphDownBoldDuotone,\n\tlinear: GraphDownLinear,\n})\nexport const GraphUp = createIcon({\n\tbold: GraphUpBoldWeight,\n\tboldDuotone: GraphUpBoldDuotone,\n\tlinear: GraphUpLinear,\n})\nexport const HamburgerMenu = createIcon({\n\tbold: HamburgerMenuBoldWeight,\n\tboldDuotone: HamburgerMenuBoldDuotone,\n\tlinear: HamburgerMenuLinear,\n})\nexport const HandHeart = createIcon({\n\tbold: HandHeartBoldWeight,\n\tboldDuotone: HandHeartBoldDuotone,\n\tlinear: HandHeartLinear,\n})\nexport const Heart = createIcon({\n\tbold: HeartBoldWeight,\n\tboldDuotone: HeartBoldDuotone,\n\tlinear: HeartLinear,\n})\nexport const Help = createIcon({\n\tbold: HelpBoldWeight,\n\tboldDuotone: HelpBoldDuotone,\n\tlinear: HelpLinear,\n})\nexport const History = createIcon({\n\tbold: HistoryBoldWeight,\n\tboldDuotone: HistoryBoldDuotone,\n\tlinear: HistoryLinear,\n})\nexport const HomeAngle = createIcon({\n\tbold: HomeAngleBoldWeight,\n\tboldDuotone: HomeAngleBoldDuotone,\n\tlinear: HomeAngleLinear,\n})\nexport const InfoCircle = createIcon({\n\tbold: InfoCircleBoldWeight,\n\tboldDuotone: InfoCircleBoldDuotone,\n\tlinear: InfoCircleLinear,\n})\nexport const Layers = createIcon({\n\tbold: LayersBoldWeight,\n\tboldDuotone: LayersBoldDuotone,\n\tlinear: LayersLinear,\n})\nexport const Letter = createIcon({\n\tbold: LetterBoldWeight,\n\tboldDuotone: LetterBoldDuotone,\n\tlinear: LetterLinear,\n})\nexport const Like = createIcon({\n\tbold: LikeBoldWeight,\n\tboldDuotone: LikeBoldDuotone,\n\tlinear: LikeLinear,\n})\nexport const Link = createIcon({\n\tbold: LinkBoldWeight,\n\tboldDuotone: LinkBoldDuotone,\n\tlinear: LinkLinear,\n})\nexport const List = createIcon({\n\tbold: ListBoldWeight,\n\tboldDuotone: ListBoldDuotone,\n\tlinear: ListLinear,\n})\nexport const ListVertical = createIcon({\n\tbold: ListVerticalBoldWeight,\n\tboldDuotone: ListVerticalBoldDuotone,\n\tlinear: ListVerticalLinear,\n})\nexport const LockPassword = createIcon({\n\tbold: LockPasswordBoldWeight,\n\tboldDuotone: LockPasswordBoldDuotone,\n\tlinear: LockPasswordLinear,\n})\nexport const Login2 = createIcon({\n\tbold: Login2BoldWeight,\n\tboldDuotone: Login2BoldDuotone,\n\tlinear: Login2Linear,\n})\nexport const Logout = createIcon({\n\tbold: LogoutBoldWeight,\n\tboldDuotone: LogoutBoldDuotone,\n\tlinear: LogoutLinear,\n})\nexport const MagicWand2 = createIcon({\n\tbold: MagicWand2BoldWeight,\n\tboldDuotone: MagicWand2BoldDuotone,\n\tlinear: MagicWand2Linear,\n})\nexport const Magnifier = createIcon({\n\tbold: MagnifierBoldWeight,\n\tboldDuotone: MagnifierBoldDuotone,\n\tlinear: MagnifierLinear,\n})\nexport const MagnifierZoomIn = createIcon({\n\tbold: MagnifierZoomInBoldWeight,\n\tboldDuotone: MagnifierZoomInBoldDuotone,\n\tlinear: MagnifierZoomInLinear,\n})\nexport const MagnifierZoomOut = createIcon({\n\tbold: MagnifierZoomOutBoldWeight,\n\tboldDuotone: MagnifierZoomOutBoldDuotone,\n\tlinear: MagnifierZoomOutLinear,\n})\nexport const Maximize = createIcon({\n\tbold: MaximizeBoldWeight,\n\tboldDuotone: MaximizeBoldDuotone,\n\tlinear: MaximizeLinear,\n})\nexport const MenuDots = createIcon({\n\tbold: MenuDotsBoldWeight,\n\tboldDuotone: MenuDotsBoldDuotone,\n\tlinear: MenuDotsBoldWeight,\n})\nexport const Minimize = createIcon({\n\tbold: MinimizeBoldWeight,\n\tboldDuotone: MinimizeBoldDuotone,\n\tlinear: MinimizeLinear,\n})\nexport const MinusSquare = createIcon({\n\tbold: MinusSquareBoldWeight,\n\tboldDuotone: MinusSquareBoldDuotone,\n\tlinear: MinusSquareLinear,\n})\nexport const Monitor = createIcon({\n\tbold: MonitorBoldWeight,\n\tboldDuotone: MonitorBoldDuotone,\n\tlinear: MonitorLinear,\n})\nexport const MonitorSmartphone = createIcon({\n\tbold: MonitorSmartphoneBoldWeight,\n\tboldDuotone: MonitorSmartphoneBoldDuotone,\n\tlinear: MonitorSmartphoneLinear,\n})\nexport const Moon = createIcon({\n\tbold: MoonBoldWeight,\n\tboldDuotone: MoonBoldDuotone,\n\tlinear: MoonLinear,\n})\nexport const MoveToFolder = createIcon({\n\tbold: MoveToFolderBoldWeight,\n\tboldDuotone: MoveToFolderBoldDuotone,\n\tlinear: MoveToFolderLinear,\n})\nexport const MusicNotes = createIcon({\n\tbold: MusicNotesBoldWeight,\n\tboldDuotone: MusicNotesBoldDuotone,\n\tlinear: MusicNotesLinear,\n})\nexport const Palette = createIcon({\n\tbold: PaletteBoldWeight,\n\tboldDuotone: PaletteBoldDuotone,\n\tlinear: PaletteLinear,\n})\nexport const PaletteRound = createIcon({\n\tbold: PaletteRoundBoldWeight,\n\tboldDuotone: PaletteRoundBoldDuotone,\n\tlinear: PaletteRoundLinear,\n})\nexport const Pause = createIcon({\n\tbold: PauseBoldWeight,\n\tboldDuotone: PauseBoldDuotone,\n\tlinear: PauseLinear,\n})\nexport const Pen = createIcon({\n\tbold: PenBoldWeight,\n\tboldDuotone: PenBoldDuotone,\n\tlinear: PenLinear,\n})\nexport const PenNewRound = createIcon({\n\tbold: PenNewRoundBoldWeight,\n\tboldDuotone: PenNewRoundBoldDuotone,\n\tlinear: PenNewRoundLinear,\n})\nexport const PieChart = createIcon({\n\tbold: PieChartBoldWeight,\n\tboldDuotone: PieChartBoldDuotone,\n\tlinear: PieChartLinear,\n})\nexport const Pin = createIcon({\n\tbold: PinBoldWeight,\n\tboldDuotone: PinBoldDuotone,\n\tlinear: PinLinear,\n})\nexport const Play = createIcon({\n\tbold: PlayBoldWeight,\n\tboldDuotone: PlayBoldDuotone,\n\tlinear: PlayLinear,\n})\nexport const PlugCircle = createIcon({\n\tbold: PlugCircleBoldWeight,\n\tboldDuotone: PlugCircleBoldDuotone,\n\tlinear: PlugCircleLinear,\n})\nexport const PlusMinus = createIcon({\n\tbold: PlusMinusBoldWeight,\n\tboldDuotone: PlusMinusBoldDuotone,\n\tlinear: PlusMinusLinear,\n})\nexport const Pulse = createIcon({\n\tbold: PulseBoldWeight,\n\tboldDuotone: PulseBoldDuotone,\n\tlinear: PulseLinear,\n})\nexport const Refresh = createIcon({\n\tbold: RefreshBoldWeight,\n\tboldDuotone: RefreshBoldDuotone,\n\tlinear: RefreshLinear,\n})\nexport const RefreshCircle = createIcon({\n\tbold: RefreshCircleBoldWeight,\n\tboldDuotone: RefreshCircleBoldDuotone,\n\tlinear: RefreshCircleLinear,\n})\nexport const Reorder = createIcon({\n\tbold: ReorderBoldWeight,\n\tboldDuotone: ReorderBoldDuotone,\n\tlinear: ReorderLinear,\n})\nexport const Repeat = createIcon({\n\tbold: RepeatBoldWeight,\n\tboldDuotone: RepeatBoldDuotone,\n\tlinear: RepeatLinear,\n})\nexport const Reply = createIcon({\n\tbold: ReplyBoldWeight,\n\tboldDuotone: ReplyBoldDuotone,\n\tlinear: ReplyLinear,\n})\nexport const Restart = createIcon({\n\tbold: RestartBoldWeight,\n\tboldDuotone: RestartBoldDuotone,\n\tlinear: RestartLinear,\n})\nexport const Rocket = createIcon({\n\tbold: RocketBoldWeight,\n\tboldDuotone: RocketBoldDuotone,\n\tlinear: RocketLinear,\n})\nexport const Route = createIcon({\n\tbold: RouteBoldWeight,\n\tboldDuotone: RouteBoldDuotone,\n\tlinear: RouteLinear,\n})\nexport const Scale = createIcon({\n\tbold: ScaleBoldWeight,\n\tboldDuotone: ScaleBoldDuotone,\n\tlinear: ScaleLinear,\n})\nexport const Server = createIcon({\n\tbold: ServerBoldWeight,\n\tboldDuotone: ServerBoldDuotone,\n\tlinear: ServerLinear,\n})\nexport const Settings = createIcon({\n\tbold: SettingsBoldWeight,\n\tboldDuotone: SettingsBoldDuotone,\n\tlinear: SettingsLinear,\n})\nexport const Share = createIcon({\n\tbold: ShareBoldWeight,\n\tboldDuotone: ShareBoldDuotone,\n\tlinear: ShareLinear,\n})\nexport const ShieldCheck = createIcon({\n\tbold: ShieldCheckBoldWeight,\n\tboldDuotone: ShieldCheckBoldDuotone,\n\tlinear: ShieldCheckLinear,\n})\nexport const Shop2 = createIcon({\n\tbold: Shop2BoldWeight,\n\tboldDuotone: Shop2BoldDuotone,\n\tlinear: Shop2Linear,\n})\nexport const SidebarMinimalistic = createIcon({\n\tbold: SidebarMinimalisticBoldWeight,\n\tboldDuotone: SidebarMinimalisticBoldDuotone,\n\tlinear: SidebarMinimalisticLinear,\n})\nexport const SliderHorizontal = createIcon({\n\tbold: SliderHorizontalBoldWeight,\n\tboldDuotone: SliderHorizontalBoldDuotone,\n\tlinear: SliderHorizontalLinear,\n})\nexport const Smartphone = createIcon({\n\tbold: SmartphoneBoldWeight,\n\tboldDuotone: SmartphoneBoldDuotone,\n\tlinear: SmartphoneLinear,\n})\nexport const Sort = createIcon({\n\tbold: SortBoldWeight,\n\tboldDuotone: SortBoldDuotone,\n\tlinear: SortLinear,\n})\nexport const SortByTime = createIcon({\n\tbold: SortByTimeBoldWeight,\n\tboldDuotone: SortByTimeBoldDuotone,\n\tlinear: SortByTimeLinear,\n})\nexport const SortHorizontal = createIcon({\n\tbold: SortHorizontalBoldWeight,\n\tboldDuotone: SortHorizontalBoldDuotone,\n\tlinear: SortHorizontalLinear,\n})\nexport const SortVertical = createIcon({\n\tbold: SortVerticalBoldWeight,\n\tboldDuotone: SortVerticalBoldDuotone,\n\tlinear: SortVerticalLinear,\n})\nexport const Star = createIcon({\n\tbold: StarBoldWeight,\n\tboldDuotone: StarBoldDuotone,\n\tlinear: StarLinear,\n})\nexport const Structure = createIcon({\n\tbold: StructureBoldWeight,\n\tboldDuotone: StructureBoldDuotone,\n\tlinear: StructureLinear,\n})\nexport const Sun = createIcon({\n\tbold: SunBoldWeight,\n\tboldDuotone: SunBoldDuotone,\n\tlinear: SunLinear,\n})\nexport const Tag = createIcon({\n\tbold: TagBoldWeight,\n\tboldDuotone: TagBoldDuotone,\n\tlinear: TagLinear,\n})\nexport const Telescope = createIcon({\n\tbold: TelescopeBoldWeight,\n\tboldDuotone: TelescopeBoldDuotone,\n\tlinear: TelescopeLinear,\n})\nexport const TestTube = createIcon({\n\tbold: TestTubeBoldWeight,\n\tboldDuotone: TestTubeBoldDuotone,\n\tlinear: TestTubeLinear,\n})\nexport const TextFormat = createIcon({\n\tbold: TextFormatBoldWeight,\n\tboldDuotone: TextFormatBoldDuotone,\n\tlinear: TextFormatLinear,\n})\nexport const TransferHorizontal = createIcon({\n\tbold: TransferHorizontalBoldWeight,\n\tboldDuotone: TransferHorizontalBoldDuotone,\n\tlinear: TransferHorizontalLinear,\n})\nexport const Translation = createIcon({\n\tbold: TranslationBoldWeight,\n\tboldDuotone: TranslationBoldDuotone,\n\tlinear: TranslationLinear,\n})\nexport const TrashBinMinimalistic = createIcon({\n\tbold: TrashBinMinimalisticBoldWeight,\n\tboldDuotone: TrashBinMinimalisticBoldDuotone,\n\tlinear: TrashBinMinimalisticLinear,\n})\nexport const UndoLeft = createIcon({\n\tbold: UndoLeftBoldWeight,\n\tboldDuotone: UndoLeftBoldDuotone,\n\tlinear: UndoLeftLinear,\n})\nexport const UndoLeftRound = createIcon({\n\tbold: UndoLeftRoundBoldWeight,\n\tboldDuotone: UndoLeftRoundBoldDuotone,\n\tlinear: UndoLeftRoundLinear,\n})\nexport const UndoRight = createIcon({\n\tbold: UndoRightBoldWeight,\n\tboldDuotone: UndoRightBoldDuotone,\n\tlinear: UndoRightLinear,\n})\nexport const UndoRightRound = createIcon({\n\tbold: UndoRightRoundBoldWeight,\n\tboldDuotone: UndoRightRoundBoldDuotone,\n\tlinear: UndoRightRoundLinear,\n})\nexport const Upload = createIcon({\n\tbold: UploadBoldWeight,\n\tboldDuotone: UploadBoldDuotone,\n\tlinear: UploadLinear,\n})\nexport const User = createIcon({\n\tbold: UserBoldWeight,\n\tboldDuotone: UserBoldDuotone,\n\tlinear: UserLinear,\n})\nexport const UserId = createIcon({\n\tbold: UserIdBoldWeight,\n\tboldDuotone: UserIdBoldDuotone,\n\tlinear: UserIdLinear,\n})\nexport const UserMinus = createIcon({\n\tbold: UserMinusBoldWeight,\n\tboldDuotone: UserMinusBoldDuotone,\n\tlinear: UserMinusLinear,\n})\nexport const UserPlus = createIcon({\n\tbold: UserPlusBoldWeight,\n\tboldDuotone: UserPlusBoldDuotone,\n\tlinear: UserPlusLinear,\n})\nexport const UsersGroupRounded = createIcon({\n\tbold: UsersGroupRoundedBoldWeight,\n\tboldDuotone: UsersGroupRoundedBoldDuotone,\n\tlinear: UsersGroupRoundedLinear,\n})\nexport const UsersGroupTwoRounded = createIcon({\n\tbold: UsersGroupTwoRoundedBoldWeight,\n\tboldDuotone: UsersGroupTwoRoundedBoldDuotone,\n\tlinear: UsersGroupTwoRoundedLinear,\n})\nexport const VideoFrame = createIcon({\n\tbold: VideoFrameBoldWeight,\n\tboldDuotone: VideoFrameBoldDuotone,\n\tlinear: VideoFrameLinear,\n})\nexport const Widget2 = createIcon({\n\tbold: Widget2BoldWeight,\n\tboldDuotone: Widget2BoldDuotone,\n\tlinear: Widget2Linear,\n})\nexport const Widget5 = createIcon({\n\tbold: Widget5BoldWeight,\n\tboldDuotone: Widget5BoldDuotone,\n\tlinear: Widget5Linear,\n})\nexport const WindowFrame = createIcon({\n\tbold: WindowFrameBoldWeight,\n\tboldDuotone: WindowFrameBoldDuotone,\n\tlinear: WindowFrameLinear,\n})\n","import { CheckCircle } from \"@hoardodile/ui/icons/registry\"\nimport { DangerTriangle } from \"@hoardodile/ui/icons/registry\"\nimport { ForbiddenCircle } from \"@hoardodile/ui/icons/registry\"\nimport { InfoCircle } from \"@hoardodile/ui/icons/registry\"\nimport * as React from \"react\"\nimport { Toast as ToastPrimitive } from \"@base-ui/react/toast\"\nimport { useTranslation } from \"react-i18next\"\n\nimport { cn } from \"@hoardodile/ui/lib/utils\"\nimport { Button } from \"@hoardodile/ui/components/button\"\nimport { Cross } from \"@hoardodile/ui/icons/marks\"\nimport { Spinner } from \"@hoardodile/ui/components/spinner\"\n\nconst toast = ToastPrimitive.createToastManager()\n\nfunction ToastProvider({ ...props }: ToastPrimitive.Provider.Props) {\n return <ToastPrimitive.Provider {...props} />\n}\n\nfunction ToastPortal({ ...props }: ToastPrimitive.Portal.Props) {\n return <ToastPrimitive.Portal data-slot=\"toast-portal\" {...props} />\n}\n\nfunction ToastViewport({ className, ...props }: ToastPrimitive.Viewport.Props) {\n return (\n <ToastPrimitive.Viewport\n data-slot=\"toast-viewport\"\n className={cn(\n \"pointer-events-none fixed inset-x-4 bottom-4 z-50 mx-auto w-auto max-w-sm outline-none sm:right-4 sm:left-auto sm:mx-0 sm:w-full\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction Toast({ className, ...props }: ToastPrimitive.Root.Props) {\n return (\n <ToastPrimitive.Root\n data-slot=\"toast\"\n className={cn(\n \"group/toast pointer-events-auto absolute right-0 bottom-0 z-[calc(1000-var(--toast-index))] w-full origin-bottom rounded-2xl border bg-popover text-popover-foreground shadow-lg will-change-transform outline-none select-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n \"[--gap:0.75rem] [--height:var(--toast-frontmost-height,var(--toast-height))] [--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))]\",\n \"h-(--height) [transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-(var(--toast-index)*var(--peek))-(var(--shrink)*var(--height))))_scale(var(--scale))] [transition:transform_500ms_cubic-bezier(0.22,1,0.36,1),opacity_500ms,height_150ms]\",\n \"after:absolute after:top-full after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']\",\n \"data-expanded:h-(--toast-height) data-expanded:[transform:translateX(var(--toast-swipe-movement-x))_translateY(var(--offset-y))]\",\n \"data-limited:opacity-0 data-starting-style:[transform:translateY(150%)]\",\n \"[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateY(150%)]\",\n \"data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]\",\n \"data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]\",\n \"data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]\",\n \"data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]\",\n \"data-expanded:data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]\",\n \"data-expanded:data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]\",\n \"data-expanded:data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]\",\n \"data-expanded:data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ToastContent({ className, ...props }: ToastPrimitive.Content.Props) {\n return (\n <ToastPrimitive.Content\n data-slot=\"toast-content\"\n className={cn(\n \"flex h-full items-center gap-3 overflow-hidden p-4 transition-opacity duration-250 ease-[cubic-bezier(0.22,1,0.36,1)] data-behind:opacity-0 data-expanded:opacity-100\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ToastTitle({ className, ...props }: ToastPrimitive.Title.Props) {\n return (\n <ToastPrimitive.Title\n data-slot=\"toast-title\"\n className={cn(\"text-sm font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction ToastDescription({\n className,\n ...props\n}: ToastPrimitive.Description.Props) {\n return (\n <ToastPrimitive.Description\n data-slot=\"toast-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction ToastAction({\n className,\n render = <Button variant=\"outline\" size=\"sm\" />,\n ...props\n}: ToastPrimitive.Action.Props) {\n return (\n <ToastPrimitive.Action\n data-slot=\"toast-action\"\n render={render}\n className={cn(\"shrink-0\", className)}\n {...props}\n />\n )\n}\n\nfunction ToastClose({\n className,\n children,\n render = <Button variant=\"ghost\" size=\"icon-sm\" />,\n ...props\n}: ToastPrimitive.Close.Props) {\n const { t } = useTranslation(\"ui\", { useSuspense: false })\n return (\n <ToastPrimitive.Close\n data-slot=\"toast-close\"\n aria-label={t(\"aria.closeToast\")}\n render={render}\n className={cn(\n \"relative shrink-0 text-muted-foreground after:absolute after:-inset-2 after:content-[''] hover:text-foreground\",\n className\n )}\n {...props}\n >\n {children ?? (\n <Cross aria-hidden=\"true\" />\n )}\n </ToastPrimitive.Close>\n )\n}\n\nfunction ToastIcon({ type }: { type: string | undefined }) {\n let icon: React.ReactNode = null\n\n if (type === \"success\") {\n icon = (\n <CheckCircle className=\"text-emerald-500\" aria-hidden=\"true\" />\n )\n }\n\n if (type === \"info\") {\n icon = (\n <InfoCircle aria-hidden=\"true\" />\n )\n }\n\n if (type === \"warning\") {\n icon = (\n <DangerTriangle className=\"text-amber-500\" aria-hidden=\"true\" />\n )\n }\n\n if (type === \"error\") {\n icon = (\n <ForbiddenCircle className=\"text-destructive\" aria-hidden=\"true\" />\n )\n }\n\n if (type === \"loading\") {\n icon = (\n <Spinner className=\"size-4\" aria-hidden=\"true\" />\n )\n }\n\n if (!icon) {\n return null\n }\n\n return (\n <span\n data-slot=\"toast-icon\"\n className=\"shrink-0 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\"\n >\n {icon}\n </span>\n )\n}\n\nfunction ToastList() {\n const { toasts } = ToastPrimitive.useToastManager()\n\n return toasts.map((toastItem) => (\n <Toast key={toastItem.id} toast={toastItem}>\n <ToastContent>\n <ToastIcon type={toastItem.type} />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <ToastTitle />\n <ToastDescription />\n </div>\n <ToastAction />\n <ToastClose />\n </ToastContent>\n </Toast>\n ))\n}\n\nfunction Toaster({\n children,\n toastManager = toast,\n ...props\n}: ToastPrimitive.Provider.Props) {\n return (\n <ToastProvider toastManager={toastManager} {...props}>\n {children}\n <ToastPortal>\n <ToastViewport>\n <ToastList />\n </ToastViewport>\n </ToastPortal>\n </ToastProvider>\n )\n}\n\nconst createToastManager = ToastPrimitive.createToastManager\nconst useToastManager = ToastPrimitive.useToastManager\n\nexport {\n Toaster,\n Toast,\n ToastAction,\n ToastClose,\n ToastContent,\n ToastDescription,\n ToastPortal,\n ToastProvider,\n ToastTitle,\n ToastViewport,\n createToastManager,\n toast,\n useToastManager,\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\nimport ReactCrop, { type Crop } from \"react-image-crop\"\nimport \"react-image-crop/dist/ReactCrop.css\"\n\n/**\n * Output of {@link ImageCropper} once the user releases the selection\n * box. Contains the cropped pixel data ready to upload (PNG by default)\n * plus its dimensions.\n */\nexport type CroppedImage = {\n\treadonly blob: Blob\n\treadonly width: number\n\treadonly height: number\n\treadonly mimeType: string\n}\n\nexport type ImageCropperProps = {\n\t/** The source image as a data URL or object URL. */\n\treadonly src: string\n\t/**\n\t * Optional fixed aspect ratio (width / height). When omitted, the\n\t * user can crop freely.\n\t */\n\treadonly aspect?: number\n\t/**\n\t * Output mime type. Defaults to `image/png`. PNG preserves quality;\n\t * JPEG produces smaller files for photographic content.\n\t */\n\treadonly mimeType?: \"image/png\" | \"image/jpeg\" | \"image/webp\"\n\t/** JPEG/WebP quality (0..1). Ignored for PNG. */\n\treadonly quality?: number\n\t/**\n\t * Called whenever the cropped pixel rectangle changes and is non-empty.\n\t * The callback receives a function that, when invoked, produces the\n\t * final {@link CroppedImage}. The render is deferred to avoid running\n\t * the canvas pipeline on every drag tick.\n\t */\n\treadonly onCropReady: (render: () => Promise<CroppedImage>) => void\n\t/**\n\t * Called synchronously with a PNG `data:` URL whenever the crop\n\t * selection changes. PNG preserves alpha for the live preview (JPEG\n\t * would flatten transparency to black). Unlike blob URLs, `data:`\n\t * URLs never appear in the browser network tab and setting them as\n\t * image `src` cannot cause an infinite re-render loop.\n\t */\n\treadonly onPreviewChange?: (dataUrl: string) => void\n\t/**\n\t * Max CSS width for the source image in the crop stage. When omitted the\n\t * image relies on `max-w-full` to fill the parent width.\n\t */\n\treadonly displayMaxWidth?: number | string\n\t/**\n\t * Max CSS height for the source image in the crop stage (e.g. `80vh` for\n\t * large canvas captures). Defaults to `70vh`.\n\t */\n\treadonly displayMaxHeight?: number | string\n}\n\n/**\n * Free-aspect (or fixed-aspect when {@link ImageCropperProps.aspect} is\n * provided) image cropper. Wraps `react-image-crop` and exposes a\n * deferred `render()` callback so callers can rasterise the selection on\n * demand (typically when the user clicks \"save\").\n */\nexport function ImageCropper(props: ImageCropperProps) {\n\tconst {\n\t\tsrc,\n\t\taspect,\n\t\tmimeType = \"image/png\",\n\t\tquality = 0.92,\n\t\tdisplayMaxWidth,\n\t\tdisplayMaxHeight = \"70vh\",\n\t} = props\n\n\tconst imgRef = useRef<HTMLImageElement | null>(null)\n\tconst [crop, setCrop] = useState<Crop | undefined>(undefined)\n\tconst [completed, setCompleted] = useState<Crop | undefined>(undefined)\n\n\tconst handleImageLoad = useCallback(\n\t\t(e: React.SyntheticEvent<HTMLImageElement>) => {\n\t\t\tconst { naturalWidth, naturalHeight } = e.currentTarget\n\t\t\tconst initial = buildInitialCrop(naturalWidth, naturalHeight, aspect)\n\t\t\tsetCrop(initial)\n\t\t\tsetCompleted(initial)\n\t\t},\n\t\t[aspect],\n\t)\n\n\tconst onCropReady = props.onCropReady\n\tconst onPreviewChange = props.onPreviewChange\n\n\tuseEffect(() => {\n\t\tconst img = imgRef.current\n\t\tif (img === null || completed === undefined || completed.width === 0) {\n\t\t\treturn\n\t\t}\n\t\tonCropReady(() => renderCroppedImage(img, completed, mimeType, quality))\n\t\tif (onPreviewChange !== undefined) {\n\t\t\tonPreviewChange(renderPreviewDataUrl(img, completed))\n\t\t}\n\t}, [completed, mimeType, quality, onCropReady, onPreviewChange])\n\n\treturn (\n\t\t<div className=\"react-crop-theme flex min-h-0 w-full max-w-full flex-col items-center gap-2 overflow-hidden\">\n\t\t\t<ReactCrop\n\t\t\t\tclassName=\"max-w-full\"\n\t\t\t\tcrop={crop}\n\t\t\t\tonChange={(_, percentCrop) => setCrop(percentCrop)}\n\t\t\t\tonComplete={(_, percentCrop) => setCompleted(percentCrop)}\n\t\t\t\taspect={aspect}\n\t\t\t\tkeepSelection\n\t\t\t\truleOfThirds\n\t\t\t>\n\t\t\t\t{/* biome-ignore lint/a11y/useAltText: cropper preview lacks user-supplied alt */}\n\t\t\t\t<img\n\t\t\t\t\tref={imgRef}\n\t\t\t\t\tsrc={src}\n\t\t\t\t\tonLoad={handleImageLoad}\n\t\t\t\t\tclassName=\"h-auto max-w-full\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tmaxWidth: displayMaxWidth,\n\t\t\t\t\t\tmaxHeight: displayMaxHeight,\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</ReactCrop>\n\t\t</div>\n\t)\n}\n\nfunction buildInitialCrop(\n\timgWidth: number,\n\timgHeight: number,\n\taspect: number | undefined,\n): Crop {\n\tif (aspect === undefined) {\n\t\treturn { unit: \"%\" as const, x: 0, y: 0, width: 100, height: 100 }\n\t}\n\n\tconst imgAspect = imgWidth / imgHeight\n\tlet widthPct: number\n\tlet heightPct: number\n\n\tif (imgAspect >= aspect) {\n\t\t// Image is wider (or equal) than the target aspect: fit to height,\n\t\t// crop the sides.\n\t\theightPct = 100\n\t\twidthPct = (100 * aspect) / imgAspect\n\t} else {\n\t\t// Image is taller than the target aspect: fit to width, crop top/bottom.\n\t\twidthPct = 100\n\t\theightPct = (100 * imgAspect) / aspect\n\t}\n\n\treturn {\n\t\tunit: \"%\" as const,\n\t\tx: (100 - widthPct) / 2,\n\t\ty: (100 - heightPct) / 2,\n\t\twidth: widthPct,\n\t\theight: heightPct,\n\t}\n}\n\nclass CroppedImageRenderError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message)\n\t\tthis.name = \"CroppedImageRenderError\"\n\t}\n}\n\n/**\n * @throws CroppedImageRenderError when the canvas context is unavailable\n * or the browser refuses to encode the selected blob.\n */\nasync function renderCroppedImage(\n\timage: HTMLImageElement,\n\tcrop: Crop,\n\tmimeType: string,\n\tquality: number,\n): Promise<CroppedImage> {\n\tconst sourceRect = cropToNaturalRect(image, crop)\n\n\tconst canvas = document.createElement(\"canvas\")\n\tcanvas.width = sourceRect.sw\n\tcanvas.height = sourceRect.sh\n\tconst ctx = canvas.getContext(\"2d\")\n\tif (ctx === null) {\n\t\tthrow new CroppedImageRenderError(\"2d context is unavailable\")\n\t}\n\tctx.imageSmoothingQuality = \"high\"\n\tctx.drawImage(\n\t\timage,\n\t\tsourceRect.sx,\n\t\tsourceRect.sy,\n\t\tsourceRect.sw,\n\t\tsourceRect.sh,\n\t\t0,\n\t\t0,\n\t\tsourceRect.sw,\n\t\tsourceRect.sh,\n\t)\n\n\tconst blob = await new Promise<Blob | null>((resolve) => {\n\t\tcanvas.toBlob(resolve, mimeType, quality)\n\t})\n\tif (blob === null) {\n\t\tthrow new CroppedImageRenderError(\"toBlob returned null\")\n\t}\n\treturn { blob, width: sourceRect.sw, height: sourceRect.sh, mimeType }\n}\n\n/**\n * Render the current crop to a PNG `data:` URL synchronously.\n *\n * Unlike {@link renderCroppedImage}, this function does NOT create a\n * `blob:` URL and therefore does not appear in the browser network tab.\n * Preview uses PNG (not JPEG) so transparent regions stay transparent.\n */\nfunction renderPreviewDataUrl(image: HTMLImageElement, crop: Crop): string {\n\tconst sourceRect = cropToNaturalRect(image, crop)\n\n\tconst canvas = document.createElement(\"canvas\")\n\tcanvas.width = sourceRect.sw\n\tcanvas.height = sourceRect.sh\n\tconst ctx = canvas.getContext(\"2d\", { alpha: true })\n\tif (ctx === null) return \"\"\n\tctx.imageSmoothingQuality = \"high\"\n\tctx.drawImage(\n\t\timage,\n\t\tsourceRect.sx,\n\t\tsourceRect.sy,\n\t\tsourceRect.sw,\n\t\tsourceRect.sh,\n\t\t0,\n\t\t0,\n\t\tsourceRect.sw,\n\t\tsourceRect.sh,\n\t)\n\treturn canvas.toDataURL(\"image/png\")\n}\n\nfunction cropToNaturalRect(\n\timage: HTMLImageElement,\n\tcrop: Crop,\n): { sx: number; sy: number; sw: number; sh: number } {\n\tconst naturalWidth = image.naturalWidth\n\tconst naturalHeight = image.naturalHeight\n\n\tif (crop.unit === \"px\") {\n\t\treturn {\n\t\t\tsx: crop.x,\n\t\t\tsy: crop.y,\n\t\t\tsw: Math.max(1, Math.round(crop.width)),\n\t\t\tsh: Math.max(1, Math.round(crop.height)),\n\t\t}\n\t}\n\n\tconst sx = (crop.x / 100) * naturalWidth\n\tconst sy = (crop.y / 100) * naturalHeight\n\tconst swRaw = (crop.width / 100) * naturalWidth\n\tconst shRaw = (crop.height / 100) * naturalHeight\n\tconst sw = Math.max(1, Math.round(swRaw))\n\tconst sh = Math.max(1, Math.round(shRaw))\n\n\treturn { sx, sy, sw, sh }\n}\n","import {\n\tDialogFooterActions,\n\tuseDialogFooterActions,\n} from \"@hoardodile/ui/components/app-dialog\"\nimport { Button } from \"@hoardodile/ui/components/button\"\nimport { Label } from \"@hoardodile/ui/components/label\"\nimport { Switch } from \"@hoardodile/ui/components/switch\"\nimport { toast } from \"@hoardodile/ui/components/toast\"\nimport { Gallery, RefreshCircle, Upload } from \"@hoardodile/ui/icons/registry\"\nimport { cn } from \"@hoardodile/ui/lib/utils\"\nimport { useCallback, useEffect, useId, useRef, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport type { CroppedImage } from \"./image-cropper\"\nimport { ImageCropper } from \"./image-cropper\"\n\nexport type ImageCropPanelProps = {\n\treadonly aspect?: number\n\treadonly mimeType?: \"image/png\" | \"image/jpeg\" | \"image/webp\"\n\treadonly accept?: string\n\treadonly previewShape?: \"square\" | \"circle\"\n\treadonly previewWidth?: number\n\treadonly previewHeight?: number\n\t/**\n\t * Called when the user clicks \"save\". Receives the cropped image\n\t * payload. Should return a promise that resolves once the upload is\n\t * complete; the panel then notifies via {@link onSaved}.\n\t *\n\t * @throws The implementation may throw to surface an error toast.\n\t */\n\treadonly onSave: (cropped: CroppedImage) => Promise<unknown>\n\treadonly onSaved?: () => void\n\t/**\n\t * Called when the user clicks the action button but no image has been\n\t * selected. The parent (e.g. {@link ImageEditPanel}) can treat this as a\n\t * request to remove the existing image.\n\t */\n\treadonly onClear?: () => void\n\t/**\n\t * When set (e.g. canvas snapshot object URL), skips the empty picker and\n\t * shows the cropper immediately.\n\t */\n\treadonly initialSrc?: string\n\t/**\n\t * When false, hides file pick / drag-drop and \"reselect\" (preset image only).\n\t */\n\treadonly allowChangeSource?: boolean\n\t/** Notifies parent when an async save starts / finishes (for dialog guards). */\n\treadonly onSavingChange?: (saving: boolean) => void\n\t/** Exact size (px) of the empty picker frame / crop stage. Overrides the default 240×240. */\n\treadonly cropStageWidth?: number\n\treadonly cropStageHeight?: number\n\t/**\n\t * When true, the right-hand live preview is hidden until the user turns\n\t * the switch on (saves work over large captures / WebGL snapshots).\n\t */\n\treadonly showPreviewSwitch?: boolean\n\t/**\n\t * When true, the live preview pane is never rendered — the crop stage is\n\t * the only surface. Used by creation forms whose panel column has no\n\t * room for a side-by-side preview.\n\t */\n\treadonly hidePreview?: boolean\n\t/**\n\t * When true, the crop stage fills its parent width and keeps the aspect\n\t * ratio implied by {@link cropStageWidth} / {@link cropStageHeight}\n\t * (full-bleed `aspect-square w-full` panels). Ignored when only\n\t * one stage dimension is given.\n\t */\n\treadonly fillWidth?: boolean\n\t/** Extra classes on the root panel wrapper. */\n\treadonly panelClassName?: string\n\t/** Extra classes on the row that holds the crop stage + preview. */\n\treadonly containerClassName?: string\n\t/** Extra classes on the column wrapping the crop stage (e.g. flex-1 min-w-0). */\n\treadonly cropColumnClassName?: string\n\t/** Extra classes on the bordered crop stage box (merged with defaults via tailwind-merge). */\n\treadonly cropStageClassName?: string\n\t/** When true, the bottom save/remove action button is hidden. */\n\treadonly hideActionButton?: boolean\n\t/**\n\t * When true, automatically calls {@link onSave} after the user finishes\n\t * adjusting the crop (debounced by 600 ms). Useful when the action button\n\t * is hidden and the parent only needs the final crop at form-submit time.\n\t */\n\treadonly autoSaveOnCrop?: boolean\n}\n\n/**\n * Inline image picker + cropper with live preview.\n */\nexport function ImageCropPanel(props: ImageCropPanelProps) {\n\tconst {\n\t\taspect,\n\t\tmimeType = \"image/png\",\n\t\taccept = \"image/*\",\n\t\tpreviewShape = \"square\",\n\t\tpreviewWidth: previewWidthProp,\n\t\tpreviewHeight: previewHeightProp,\n\t\tonSave,\n\t\tonSaved,\n\t\tonClear,\n\t\tinitialSrc,\n\t\tallowChangeSource = true,\n\t\tonSavingChange,\n\t\tcropStageWidth,\n\t\tcropStageHeight,\n\t\tshowPreviewSwitch = false,\n\t\thidePreview = false,\n\t\tfillWidth = false,\n\t\tpanelClassName,\n\t\tcontainerClassName,\n\t\tcropColumnClassName,\n\t\tcropStageClassName,\n\t\thideActionButton = false,\n\t\tautoSaveOnCrop = false,\n\t} = props\n\tconst { t } = useTranslation(\"ui\", { useSuspense: false })\n\tconst footerSlot = useDialogFooterActions()\n\tconst previewWidth = previewWidthProp ?? cropStageWidth ?? 200\n\tconst previewHeight = previewHeightProp ?? cropStageHeight ?? 200\n\tconst effectiveCropWidth = cropStageWidth ?? 320\n\tconst effectiveCropHeight = cropStageHeight ?? 240\n\t// Full-bleed stage: the aspect ratio of the requested stage dimensions,\n\t// stretched to whatever width the parent column gives us.\n\tconst stageAspectRatio =\n\t\tfillWidth && cropStageWidth !== undefined && cropStageHeight !== undefined\n\t\t\t? `${cropStageWidth} / ${cropStageHeight}`\n\t\t\t: undefined\n\tconst previewToggleId = useId()\n\tconst fileInputRef = useRef<HTMLInputElement | null>(null)\n\tconst [imageSrc, setImageSrc] = useState<string | undefined>(initialSrc)\n\tconst renderRef = useRef<(() => Promise<CroppedImage>) | undefined>(undefined)\n\tconst [previewDataUrl, setPreviewDataUrl] = useState<string | undefined>(\n\t\tundefined,\n\t)\n\tconst [previewPaneOn, setPreviewPaneOn] = useState(false)\n\tconst [dragOver, setDragOver] = useState(false)\n\tconst [saving, setSaving] = useState(false)\n\tconst previewVisible = !hidePreview && (!showPreviewSwitch || previewPaneOn)\n\tconst autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n\t\tundefined,\n\t)\n\tconst callbacksRef = useRef({ onSave, onSaved, onSavingChange, t })\n\tcallbacksRef.current = { onSave, onSaved, onSavingChange, t }\n\n\tuseEffect(\n\t\tfunction syncInitialSrc() {\n\t\t\tif (initialSrc !== undefined) setImageSrc(initialSrc)\n\t\t},\n\t\t[initialSrc],\n\t)\n\n\tconst handleCropReady = useCallback(\n\t\t(render: () => Promise<CroppedImage>) => {\n\t\t\trenderRef.current = render\n\t\t\tif (autoSaveOnCrop) {\n\t\t\t\tif (autoSaveTimerRef.current) {\n\t\t\t\t\tclearTimeout(autoSaveTimerRef.current)\n\t\t\t\t}\n\t\t\t\tautoSaveTimerRef.current = setTimeout(() => {\n\t\t\t\t\trender()\n\t\t\t\t\t\t.then(async (cropped) => {\n\t\t\t\t\t\t\tconst { onSave, onSaved, onSavingChange, t } =\n\t\t\t\t\t\t\t\tcallbacksRef.current\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tsetSaving(true)\n\t\t\t\t\t\t\t\tonSavingChange?.(true)\n\t\t\t\t\t\t\t\tawait onSave(cropped)\n\t\t\t\t\t\t\t\tonSaved?.()\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\tconst msg = err instanceof Error ? err.message : String(err)\n\t\t\t\t\t\t\t\ttoast.add({\n\t\t\t\t\t\t\t\t\ttitle: msg || t(\"imageCrop.saveFailed\"),\n\t\t\t\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\tsetSaving(false)\n\t\t\t\t\t\t\t\tonSavingChange?.(false)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\t\tconst { t } = callbacksRef.current\n\t\t\t\t\t\t\tconst msg = err instanceof Error ? err.message : String(err)\n\t\t\t\t\t\t\ttoast.add({\n\t\t\t\t\t\t\t\ttitle: msg || t(\"imageCrop.saveFailed\"),\n\t\t\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t}, 600)\n\t\t\t}\n\t\t},\n\t\t[autoSaveOnCrop],\n\t)\n\n\tconst handlePreviewChange = useCallback((dataUrl: string) => {\n\t\tsetPreviewDataUrl(dataUrl)\n\t}, [])\n\n\tfunction handlePreviewToggle(on: boolean) {\n\t\tsetPreviewPaneOn(on)\n\t\tif (!on) setPreviewDataUrl(undefined)\n\t}\n\n\tfunction handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {\n\t\tconst file = e.target.files?.[0]\n\t\tif (file === undefined) return\n\t\treadFileAsDataUrl(file)\n\t}\n\n\tfunction handleDrop(e: React.DragEvent<HTMLElement>) {\n\t\te.preventDefault()\n\t\tsetDragOver(false)\n\t\tconst file = e.dataTransfer.files?.[0]\n\t\tif (file !== undefined) readFileAsDataUrl(file)\n\t}\n\n\tfunction readFileAsDataUrl(file: File) {\n\t\tconst reader = new FileReader()\n\t\treader.addEventListener(\"load\", () => {\n\t\t\tconst result = reader.result\n\t\t\tif (typeof result === \"string\") setImageSrc(result)\n\t\t})\n\t\treader.readAsDataURL(file)\n\t}\n\n\tfunction handleReselect() {\n\t\tif (autoSaveTimerRef.current) {\n\t\t\tclearTimeout(autoSaveTimerRef.current)\n\t\t\tautoSaveTimerRef.current = undefined\n\t\t}\n\t\tsetImageSrc(undefined)\n\t\trenderRef.current = undefined\n\t\tsetPreviewDataUrl(undefined)\n\t\tsetPreviewPaneOn(false)\n\t\tfileInputRef.current?.click()\n\t}\n\n\tasync function handleSave() {\n\t\tconst render = renderRef.current\n\t\tif (render === undefined) {\n\t\t\tonClear?.()\n\t\t\treturn\n\t\t}\n\t\tsetSaving(true)\n\t\tonSavingChange?.(true)\n\t\ttry {\n\t\t\tconst cropped = await render()\n\t\t\tawait onSave(cropped)\n\t\t\tonSaved?.()\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err)\n\t\t\ttoast.add({\n\t\t\t\ttitle: msg || t(\"imageCrop.saveFailed\"),\n\t\t\t\ttype: \"error\",\n\t\t\t})\n\t\t} finally {\n\t\t\tsetSaving(false)\n\t\t\tonSavingChange?.(false)\n\t\t}\n\t}\n\n\tconst previewRadiusClass =\n\t\tpreviewShape === \"circle\" ? \"rounded-full\" : \"rounded\"\n\n\tconst actionButton = (\n\t\t<Button\n\t\t\ttype=\"button\"\n\t\t\tonClick={handleSave}\n\t\t\tdisabled={saving}\n\t\t\tdata-testid=\"image-crop-save\"\n\t\t>\n\t\t\t{saving\n\t\t\t\t? t(\"imageCrop.saving\")\n\t\t\t\t: imageSrc === undefined\n\t\t\t\t\t? t(\"imageCrop.remove\")\n\t\t\t\t\t: t(\"imageCrop.save\")}\n\t\t</Button>\n\t)\n\n\treturn (\n\t\t<div className={cn(\"flex flex-col gap-4\", panelClassName)}>\n\t\t\t{allowChangeSource ? (\n\t\t\t\t<input\n\t\t\t\t\tref={fileInputRef}\n\t\t\t\t\ttype=\"file\"\n\t\t\t\t\taccept={accept}\n\t\t\t\t\tclassName=\"hidden\"\n\t\t\t\t\tonChange={handleFileChange}\n\t\t\t\t\tdata-testid=\"image-crop-file-input\"\n\t\t\t\t/>\n\t\t\t) : null}\n\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex flex-col items-center gap-6 py-2 sm:flex-row sm:items-center sm:justify-center\",\n\t\t\t\t\tcontainerClassName,\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"flex flex-col items-center gap-2\",\n\t\t\t\t\t\tstageAspectRatio !== undefined && \"w-full\",\n\t\t\t\t\t\tcropColumnClassName,\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{imageSrc === undefined ? (\n\t\t\t\t\t\tallowChangeSource ? (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tonClick={() => fileInputRef.current?.click()}\n\t\t\t\t\t\t\t\tonDragOver={(e) => {\n\t\t\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\t\t\tsetDragOver(true)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tonDragLeave={() => setDragOver(false)}\n\t\t\t\t\t\t\t\tonDrop={handleDrop}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"flex select-none flex-col items-center justify-center gap-2 rounded-md border border-border bg-muted text-muted-foreground transition-colors duration-300 hover:bg-accent hover:text-accent-foreground\",\n\t\t\t\t\t\t\t\t\tdragOver && \"bg-accent text-accent-foreground\",\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined && \"w-full\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tdata-testid=\"image-crop-frame\"\n\t\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined\n\t\t\t\t\t\t\t\t\t\t? { aspectRatio: stageAspectRatio }\n\t\t\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t\t\twidth: cropStageWidth ?? 240,\n\t\t\t\t\t\t\t\t\t\t\t\theight: cropStageHeight ?? 240,\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Upload className=\"size-5\" />\n\t\t\t\t\t\t\t\t<p className=\"text-sm\">{t(\"imageCrop.pickHint\")}</p>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"flex items-center justify-center rounded-md border border-dashed border-border text-sm text-muted-foreground\",\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined && \"w-full\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined\n\t\t\t\t\t\t\t\t\t\t? { aspectRatio: stageAspectRatio }\n\t\t\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t\t\twidth: cropStageWidth ?? 240,\n\t\t\t\t\t\t\t\t\t\t\t\theight: cropStageHeight ?? 240,\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{t(\"imageCrop.pickHint\")}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"flex min-h-0 items-center justify-center overflow-hidden rounded-md border border-border bg-card\",\n\t\t\t\t\t\t\t\tstageAspectRatio === undefined && \"max-w-90\",\n\t\t\t\t\t\t\t\tcropStageClassName,\n\t\t\t\t\t\t\t\tstageAspectRatio !== undefined && \"w-full\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\tstageAspectRatio !== undefined\n\t\t\t\t\t\t\t\t\t? { aspectRatio: stageAspectRatio }\n\t\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t\tminHeight: `${cropStageHeight}px`,\n\t\t\t\t\t\t\t\t\t\t\tminWidth: `${cropStageWidth}px`,\n\t\t\t\t\t\t\t\t\t\t\twidth: effectiveCropWidth,\n\t\t\t\t\t\t\t\t\t\t\theight: effectiveCropHeight,\n\t\t\t\t\t\t\t\t\t\t\tmaxWidth: effectiveCropWidth,\n\t\t\t\t\t\t\t\t\t\t\tmaxHeight: effectiveCropHeight,\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<ImageCropper\n\t\t\t\t\t\t\t\tsrc={imageSrc}\n\t\t\t\t\t\t\t\taspect={aspect}\n\t\t\t\t\t\t\t\tmimeType={mimeType}\n\t\t\t\t\t\t\t\tdisplayMaxWidth={\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined ? \"100%\" : effectiveCropWidth\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tdisplayMaxHeight={\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined\n\t\t\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t\t\t: effectiveCropHeight\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tonCropReady={handleCropReady}\n\t\t\t\t\t\t\t\tonPreviewChange={\n\t\t\t\t\t\t\t\t\tpreviewVisible ? handlePreviewChange : undefined\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t\t{imageSrc !== undefined && allowChangeSource ? (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\tonClick={handleReselect}\n\t\t\t\t\t\t\tclassName=\"text-muted-foreground text-xs\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<RefreshCircle className=\"mr-1 h-3.5 w-3.5\" />\n\t\t\t\t\t\t\t{t(\"imageCrop.reselect\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\n\t\t\t\t{previewVisible ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<div className={cn(\"hidden w-px bg-border sm:block h-40\")} />\n\t\t\t\t\t\t<div className={cn(\"block bg-border sm:hidden h-px w-32\")} />\n\n\t\t\t\t\t\t<div className={cn(\"flex shrink-0 flex-col items-center gap-1.5\")}>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tstyle={{ width: previewWidth, height: previewHeight }}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"flex items-center justify-center overflow-hidden border border-border bg-muted text-muted-foreground\",\n\t\t\t\t\t\t\t\t\tpreviewRadiusClass,\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tdata-testid=\"image-crop-preview\"\n\t\t\t\t\t\t\t\ttitle={t(\"imageCrop.previewLabel\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{previewDataUrl !== undefined ? (\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tsrc={previewDataUrl}\n\t\t\t\t\t\t\t\t\t\talt={t(\"imageCrop.previewAlt\")}\n\t\t\t\t\t\t\t\t\t\tclassName=\"max-h-full max-w-full object-cover\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Gallery className=\"h-10 w-10 opacity-60\" />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t) : null}\n\t\t\t</div>\n\n\t\t\t{showPreviewSwitch && imageSrc !== undefined ? (\n\t\t\t\t<div className={cn(\"flex items-center justify-center gap-2\")}>\n\t\t\t\t\t<Switch\n\t\t\t\t\t\tid={previewToggleId}\n\t\t\t\t\t\tchecked={previewPaneOn}\n\t\t\t\t\t\tonCheckedChange={handlePreviewToggle}\n\t\t\t\t\t\tdata-testid=\"image-crop-preview-toggle\"\n\t\t\t\t\t/>\n\t\t\t\t\t<Label\n\t\t\t\t\t\thtmlFor={previewToggleId}\n\t\t\t\t\t\tclassName=\"text-muted-foreground cursor-pointer text-sm font-normal\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"imageCrop.showPreview\")}\n\t\t\t\t\t</Label>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{/* The save/remove action lands on the surrounding dialog's\n\t\t\t footer row — side by side with Cancel. Outside a dialog it\n\t\t\t falls back to an inline row at the panel's bottom. */}\n\t\t\t{!hideActionButton &&\n\t\t\t\t(footerSlot === null ? (\n\t\t\t\t\t<div className={cn(\"flex justify-end pt-2\")}>{actionButton}</div>\n\t\t\t\t) : (\n\t\t\t\t\t<DialogFooterActions>{actionButton}</DialogFooterActions>\n\t\t\t\t))}\n\t\t</div>\n\t)\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/merge-config.ts","../../src/lib/utils.ts","../../src/components/button.tsx","../../src/hooks/use-dialog-footer-actions.ts","../../src/components/app-dialog.tsx","../../src/components/label.tsx","../../src/components/switch.tsx","../../src/icons/icon-style.ts","../../src/icons/registry.ts","../../src/components/toast.tsx","../../src/components/image-cropper.tsx","../../src/components/image-crop-panel.tsx"],"names":["ButtonPrimitive","jsx","SwitchPrimitive","GalleryBoldWeight","GalleryBoldDuotone","GalleryLinear","RefreshCircleBoldWeight","RefreshCircleBoldDuotone","RefreshCircleLinear","UploadBoldWeight","UploadBoldDuotone","UploadLinear","ToastPrimitive","useRef","useState","useEffect","useTranslation","useCallback","onSave","onSaved","onSavingChange","t","jsxs"],"mappings":"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","file":"image-crop-panel.js","sourcesContent":["import { extendTailwindMerge } from \"tailwind-merge\"\n\n// The app's `@theme inline` tokens (theme.css) generate utility names\n// tailwind-merge doesn't know, so it misclassifies them — e.g. `text-ui` is\n// parsed as a text color and dropped next to any `text-*` color. The default\n// class groups are theme-backed, so extending the theme (keys mirror the v4\n// token namespaces one-to-one) registers every custom utility with correct\n// conflict semantics. merge-config.test.ts pins this list against theme.css.\nexport const mergeTheme = {\n\ttext: [\"tiny\", \"ui\", \"doc\", \"doc-title\", \"doc-heading\", \"quote\"],\n\tspacing: [\"chip\", \"control\", \"nav\", \"sidebar\", \"panel\"],\n\ttracking: [\"label\"],\n\tshadow: [\"card\", \"dialog\"],\n\tcontainer: [\"reading\", \"medium\", \"content\"],\n\tfont: [\"doc\", \"heading\"],\n\tease: [\"standard\"],\n\tanimate: [\"skel\", \"pop\"],\n} as const\n\nexport const twMerge = extendTailwindMerge({\n\textend: { theme: mergeTheme },\n})\n","import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"./merge-config\"\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs))\n}\n","import { Button as ButtonPrimitive } from \"@base-ui/react/button\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@hoardodile/ui/lib/utils\"\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg text-ui font-medium whitespace-nowrap outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary px-4! text-primary-foreground hover:bg-primary/80\",\n outline:\n \"border-border bg-background shadow-xs hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-foreground\",\n ghost:\n \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n danger:\n \"bg-[color-mix(in_oklab,var(--destructive),black_12%)] text-white hover:bg-[color-mix(in_oklab,var(--destructive),black_4%)] focus-visible:border-destructive/40 focus-visible:ring-destructive/20 disabled:bg-destructive/10 disabled:text-muted-foreground dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-control gap-2 px-3 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n xs: \"h-6 gap-2 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-chip gap-2 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5\",\n lg: \"h-10 gap-2 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n icon: \"size-9\",\n \"icon-xs\":\n \"size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\":\n \"size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n active,\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props &\n VariantProps<typeof buttonVariants> & {\n /** Latched toggle state: accent fill, hover pinned so an active\n button never shifts. Callers keep choosing the matching aria\n attribute (`aria-pressed` / `aria-expanded`). */\n active?: boolean\n }) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(\n buttonVariants({ variant, size, className }),\n active && \"bg-accent text-accent-foreground hover:bg-accent\"\n )}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import { createContext, type ReactNode, useContext } from \"react\"\n\n/**\n * Footer action slot plumbing for `AppDialog` — the context shared\n * between the dialog shell (`@hoardodile/ui/components/app-dialog`) and\n * body panels that contribute their primary action through\n * `DialogFooterActions`, so action buttons land in the footer instead of\n * the body.\n */\n\ntype DialogFooterActionsValue = {\n\treadonly setFooterActions: (node: ReactNode | null) => void\n}\n\nconst DialogFooterActionsContext =\n\tcreateContext<DialogFooterActionsValue | null>(null)\n\n/** The nearest dialog's footer action slot, or null outside a dialog. */\nfunction useDialogFooterActions(): DialogFooterActionsValue | null {\n\treturn useContext(DialogFooterActionsContext)\n}\n\nexport { DialogFooterActionsContext, useDialogFooterActions }\n","import {\n\tDialog,\n\tDialogBody,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n} from \"./dialog\"\nimport {\n\tDialogFooterActionsContext,\n\tuseDialogFooterActions,\n} from \"@hoardodile/ui/hooks/use-dialog-footer-actions\"\nimport { cn } from \"@hoardodile/ui/lib/utils\"\nimport {\n\ttype ReactNode,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\"\n\n/** Dialog width tiers: the 320–480 narrow slot plus\n the wide working tiers — edit hubs, pickers and selectors get\n real estate; confirmations never leave the narrow slot. */\nexport type AppDialogSize = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\"\n\nconst sizeClasses: Record<AppDialogSize, string> = {\n\tsm: \"sm:max-w-sm\",\n\tmd: \"sm:max-w-md\",\n\tlg: \"sm:max-w-2xl\",\n\txl: \"sm:max-w-3xl\",\n\t\"2xl\": \"sm:max-w-4xl\",\n}\n\nexport { useDialogFooterActions }\n\n/**\n * Declarative footer action: renders nothing in the body and contributes\n * the node to the surrounding dialog's footer (appended after the\n * dialog's own `footer` prop). Panels embed their primary action this way\n * so action buttons live in the footer, never in the body. Outside a\n * dialog (sheets, pickers) it renders nothing — callers keep their inline\n * action bar as the fallback.\n */\nexport function DialogFooterActions({ children }: { children: ReactNode }) {\n\tconst slot = useDialogFooterActions()\n\tuseEffect(() => {\n\t\tif (slot === null) return\n\t\tslot.setFooterActions(children)\n\t\treturn () => slot.setFooterActions(null)\n\t}, [slot, children])\n\treturn null\n}\n\nexport type AppDialogProps = Readonly<{\n\topen: boolean\n\tonOpenChange: (open: boolean) => void\n\ttitle: ReactNode\n\t/** Uppercase section marker above the title (feature dialogs). */\n\teyebrow?: ReactNode\n\t/** Leading icon tile in the title row (feature dialogs). */\n\ticon?: ReactNode\n\t/** Danger register — the title ink takes the destructive hue; the\n\t danger itself stays in copy and the confirm button. */\n\tdanger?: boolean\n\t/** Width tier; defaults to `md` (the narrow form slot). */\n\tsize?: AppDialogSize\n\t/**\n\t * Drops the body padding for workspace bodies that own their layout\n\t * edge to edge (the two-pane editors); the header keeps its padding\n\t * and the footer becomes a plain bottom bar.\n\t */\n\tflush?: boolean\n\tdescription?: ReactNode\n\tchildren: ReactNode\n\t/** Leading footer actions; body panels may append theirs via\n\t {@link DialogFooterActions}. */\n\tfooter?: ReactNode\n\tcontentClassName?: string\n\t/** Passed to dialog overlay (e.g. disable backdrop blur over WebGL). */\n\toverlayClassName?: string\n\t/** Fade-only motion — lighter than default slide/zoom when over heavy surfaces. */\n\tcontentMotion?: \"default\" | \"minimal\"\n\t/** Defaults to true. Set to false to honour native auto-focus (rare). */\n\tsuppressAutoFocus?: boolean\n\tcontentTestId?: string\n}>\n\n/**\n * Standard dialog shell. Wires up `Dialog`/`DialogContent`/`DialogHeader`/\n * `DialogTitle` and an optional eyebrow, icon, description and footer so\n * callers stop re-stating the boilerplate. Use {@link ConfirmDialog} for\n * the common \"cancel + primary action\" pattern.\n */\nexport function AppDialog(props: AppDialogProps) {\n\tconst {\n\t\topen,\n\t\tonOpenChange,\n\t\ttitle,\n\t\teyebrow,\n\t\ticon,\n\t\tdanger,\n\t\tsize,\n\t\tflush,\n\t\tdescription,\n\t\tchildren,\n\t\tfooter,\n\t\tcontentClassName,\n\t\toverlayClassName,\n\t\tcontentMotion,\n\t\tsuppressAutoFocus = true,\n\t\tcontentTestId,\n\t} = props\n\t// Focusing the first focusable element on open would steal the caret\n\t// from the page underneath, jump scroll position, and on iOS\n\t// occasionally pop the soft keyboard before the user even reaches an\n\t// input. Routing focus to the dialog container itself keeps the\n\t// dialog accessible without those side effects.\n\tconst contentRef = useRef<HTMLDivElement | null>(null)\n\n\t// Footer actions contributed by body panels (DialogFooterActions):\n\t// appended after the dialog's own footer, reset when the dialog closes.\n\tconst [footerActions, setFooterActions] = useState<ReactNode>(null)\n\tconst actionsValue = useMemo(\n\t\t() => ({ setFooterActions }),\n\t\t[setFooterActions],\n\t)\n\n\treturn (\n\t\t<Dialog open={open} onOpenChange={onOpenChange}>\n\t\t\t<DialogContent\n\t\t\t\tref={contentRef}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tsize !== undefined && sizeClasses[size],\n\t\t\t\t\tflush && \"p-0\",\n\t\t\t\t\tcontentClassName,\n\t\t\t\t)}\n\t\t\t\toverlayClassName={overlayClassName}\n\t\t\t\tcontentMotion={contentMotion}\n\t\t\t\tinitialFocus={suppressAutoFocus ? contentRef : undefined}\n\t\t\t\tdata-testid={contentTestId}\n\t\t\t>\n\t\t\t\t<DialogHeader className={flush ? \"gap-4\" : undefined}>\n\t\t\t\t\t{eyebrow !== undefined ? (\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"text-tiny font-semibold tracking-label uppercase\",\n\t\t\t\t\t\t\t\tdanger ? \"text-destructive\" : \"text-muted-foreground\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{eyebrow}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<div className=\"flex min-w-0 items-center gap-3 pr-6\">\n\t\t\t\t\t\t{icon}\n\t\t\t\t\t\t<DialogTitle\n\t\t\t\t\t\t\tclassName={cn(\"truncate\", danger && \"text-destructive\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t</DialogTitle>\n\t\t\t\t\t</div>\n\t\t\t\t\t{description !== undefined ? (\n\t\t\t\t\t\t<DialogDescription>{description}</DialogDescription>\n\t\t\t\t\t) : null}\n\t\t\t\t</DialogHeader>\n\t\t\t\t{/* The header, body and footer must stay direct children of\n\t\t\t\t DialogContent — its arrangement logic recognises them by\n\t\t\t\t type, and a wrapper in between would re-wrap the body in a\n\t\t\t\t second DialogBody. The footer-actions context therefore\n\t\t\t\t wraps only the body's own content. */}\n\t\t\t\t<DialogBody className={flush ? \"p-0\" : undefined}>\n\t\t\t\t\t<DialogFooterActionsContext.Provider value={actionsValue}>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</DialogFooterActionsContext.Provider>\n\t\t\t\t</DialogBody>\n\t\t\t\t{(footer !== undefined && footer !== null) ||\n\t\t\t\tfooterActions !== null ? (\n\t\t\t\t\t<DialogFooter flush={flush}>\n\t\t\t\t\t\t{footer}\n\t\t\t\t\t\t{footerActions}\n\t\t\t\t\t</DialogFooter>\n\t\t\t\t) : null}\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t)\n}\n","\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@hoardodile/ui/lib/utils\"\n\nfunction Label({ className, ...props }: React.ComponentProps<\"label\">) {\n return (\n <label\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n","import { Switch as SwitchPrimitive } from \"@base-ui/react/switch\"\n\nimport { cn } from \"@hoardodile/ui/lib/utils\"\n\nfunction Switch({\n className,\n size = \"default\",\n ...props\n}: SwitchPrimitive.Root.Props & {\n size?: \"sm\" | \"default\"\n}) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n data-size={size}\n className={cn(\n \"peer group/switch relative inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent shadow-xs transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-5 data-[size=default]:w-9 data-[size=default]:p-[3px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className=\"pointer-events-none block rounded-full bg-background ring-1 ring-foreground/10 transition-transform group-data-[size=default]/switch:size-3.5 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%+2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground\"\n />\n </SwitchPrimitive.Root>\n )\n}\n\nexport { Switch }\n","import { type ComponentType, createElement, useSyncExternalStore } from \"react\"\nimport type { IconType } from \"../components/icon.tsx\"\n\n/**\n * Icon-mode-aware glyph wrapper (Settings → Icons in the host app).\n *\n * The active icon style lives as `data-icon-style` on `document.documentElement`\n * — the host app writes it from its preference store, plugin iframes receive\n * it through the `themeChanged` push — so this module needs no context or\n * injected state: a single shared `MutationObserver` watches the attribute\n * and every wrapped component re-renders through `useSyncExternalStore`\n * when it flips.\n *\n * Only `linear` needs a component swap: the boldDuotone glyphs change to\n * their thin-line linear counterparts. `grayscale` is pure CSS (theme.css\n * recolors the `.hd-icon` hook), so the store only tracks the mode.\n */\nexport type IconStyleValue = \"duotone\" | \"grayscale\" | \"linear\"\n\n/**\n * The parallel Solar weights an icon registers — named after Solar's own\n * weights (DESIGN.md — Iconography). Every icon carries all of them;\n * adding a mode here forces every registry entry to fill it in.\n */\nexport type IconMode = \"bold\" | \"boldDuotone\" | \"linear\"\n\n/** All three mode glyphs of one icon. Mandatory and complete by type. */\nexport type IconVariants = Record<IconMode, IconType>\n\nfunction readIconMode(): IconMode {\n\treturn document.documentElement.dataset.iconStyle === \"linear\"\n\t\t? \"linear\"\n\t\t: \"boldDuotone\"\n}\n\n// Never read `document` at module load — pure-logic consumers (node test\n// environments) import this module without a DOM. The first subscribe\n// (component mount) snapshots the current value.\nlet currentMode: IconMode = \"boldDuotone\"\nlet observer: MutationObserver | undefined\nconst listeners = new Set<() => void>()\n\nfunction ensureObserver(): void {\n\tif (observer !== undefined || typeof document === \"undefined\") return\n\tobserver = new MutationObserver(() => {\n\t\tconst next = readIconMode()\n\t\tif (next === currentMode) return\n\t\tcurrentMode = next\n\t\tfor (const cb of listeners) cb()\n\t})\n\tobserver.observe(document.documentElement, {\n\t\tattributes: true,\n\t\tattributeFilter: [\"data-icon-style\"],\n\t})\n}\n\nfunction subscribeIconStyle(callback: () => void): () => void {\n\tensureObserver()\n\tcurrentMode = readIconMode()\n\tlisteners.add(callback)\n\treturn () => {\n\t\tlisteners.delete(callback)\n\t}\n}\n\nfunction getIconStyleSnapshot(): IconMode {\n\treturn currentMode\n}\n\n/**\n * Wraps a Solar glyph family so its render follows the host's icon style.\n *\n * `createIcon({ bold, boldDuotone, linear })` — the three parallel weights\n * of one icon. Without a `mode` prop the wrapper renders the glyph for the\n * active icon style; an explicit `mode` overrides it (selected states pass\n * `\"bold\"` through `Icon`).\n *\n * Every wrapped render merges the `hd-icon` hook class, so the duotone /\n * grayscale CSS in theme.css applies to direct renders too. Returns\n * `undefined`-free components callable through the `Icon` wrapper or bare\n * JSX alike.\n */\nexport function createIcon(\n\tvariants: IconVariants,\n): ComponentType<Record<string, unknown>> {\n\tfunction Icon(props: Record<string, unknown>) {\n\t\tconst current = useSyncExternalStore(\n\t\t\tsubscribeIconStyle,\n\t\t\tgetIconStyleSnapshot,\n\t\t\t() => \"boldDuotone\",\n\t\t)\n\t\tconst { mode, ...rest } = props as { readonly mode?: IconMode } & Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>\n\t\tconst Component = variants[(mode ?? current) as IconMode]\n\t\tconst className =\n\t\t\ttypeof rest.className === \"string\"\n\t\t\t\t? `hd-icon ${rest.className}`\n\t\t\t\t: \"hd-icon\"\n\t\treturn createElement(Component, { ...rest, className })\n\t}\n\treturn Icon\n}\n","/**\n * Central Solar icon registry for the design system.\n *\n * Every Solar glyph the app renders is exported here through `createIcon`\n * from `@hoardodile/ui` — one component per glyph carrying the three\n * parallel Solar weights (bold / boldDuotone / linear). The wrapper picks\n * the glyph for the active icon style preference (Settings → Icons): in\n * `linear` style the boldDuotone glyphs swap to their thin-line linear\n * counterparts; an explicit `mode` prop overrides (`\"bold\"` for selected\n * states). Every export carries the `hd-icon` hook class so the\n * duotone/grayscale CSS in theme.css applies to direct renders too. All\n * exports are wrapped — never the raw glyphs. Importing Solar directly is\n * confined to this file and @hoardodile/ui internals — consumers import\n * the wrapped exports only.\n *\n * Structure — imports first, one block per Solar weight (bold / bold-duotone /\n * linear, alphabetical by glyph; every glyph has all three), then one\n * export section, alphabetical by name (ordinal, case-sensitive —\n * `BookTone`'s stem `Book` sorts before `Bookmark`):\n *\n * export const <Name> = createIcon({\n * bold: <Name>BoldWeight, — filled, single-color; selected states\n * boldDuotone: <Name>BoldDuotone, — two-tone, the default\n * linear: <Name>Linear, — thin-line; `linear` icon style\n * })\n *\n * Modes are parallel and mandatory: adding a member to `IconMode` forces\n * every entry to register it (guarded by icons.test.ts). One exception:\n * `MenuDots` maps its `linear` slot to the filled weight — the thin-line\n * dots read as noise at small sizes. Tree-shaking keeps only the variants\n * actually imported.\n */\n\nimport { AddCircleIcon as AddCircleBoldWeight } from \"@solar-icons/react/bold/add-circle\"\nimport { AlignLeftIcon as AlignLeftBoldWeight } from \"@solar-icons/react/bold/align-left\"\nimport { AltArrowDownIcon as AltArrowDownBoldWeight } from \"@solar-icons/react/bold/alt-arrow-down\"\nimport { AltArrowLeftIcon as AltArrowLeftBoldWeight } from \"@solar-icons/react/bold/alt-arrow-left\"\nimport { AltArrowRightIcon as AltArrowRightBoldWeight } from \"@solar-icons/react/bold/alt-arrow-right\"\nimport { AltArrowUpIcon as AltArrowUpBoldWeight } from \"@solar-icons/react/bold/alt-arrow-up\"\nimport { ArchiveIcon as ArchiveBoldWeight } from \"@solar-icons/react/bold/archive\"\nimport { ArrowRightIcon as ArrowRightBoldWeight } from \"@solar-icons/react/bold/arrow-right\"\nimport { ArrowToTopLeftIcon as ArrowToTopLeftBoldWeight } from \"@solar-icons/react/bold/arrow-to-top-left\"\nimport { ArrowToTopRightIcon as ArrowToTopRightBoldWeight } from \"@solar-icons/react/bold/arrow-to-top-right\"\nimport { BellIcon as BellBoldWeight } from \"@solar-icons/react/bold/bell\"\nimport { BoltIcon as BoltBoldWeight } from \"@solar-icons/react/bold/bolt\"\nimport { BookIcon as BookBoldWeight } from \"@solar-icons/react/bold/book\"\nimport { Book2Icon as Book2BoldWeight } from \"@solar-icons/react/bold/book-2\"\nimport { BookmarkIcon as BookmarkBoldWeight } from \"@solar-icons/react/bold/bookmark\"\nimport { BookmarkCircleIcon as BookmarkCircleBoldWeight } from \"@solar-icons/react/bold/bookmark-circle\"\nimport { BoxIcon as BoxBoldWeight } from \"@solar-icons/react/bold/box\"\nimport { BranchingPathsUpIcon as BranchingPathsUpBoldWeight } from \"@solar-icons/react/bold/branching-paths-up\"\nimport { BugIcon as BugBoldWeight } from \"@solar-icons/react/bold/bug\"\nimport { CalendarDateIcon as CalendarDateBoldWeight } from \"@solar-icons/react/bold/calendar-date\"\nimport { ChatRoundIcon as ChatRoundBoldWeight } from \"@solar-icons/react/bold/chat-round\"\nimport { ChatRoundDotsIcon as ChatRoundDotsBoldWeight } from \"@solar-icons/react/bold/chat-round-dots\"\nimport { ChatRoundLineIcon as ChatRoundLineBoldWeight } from \"@solar-icons/react/bold/chat-round-line\"\nimport { ChatSquareIcon as ChatSquareBoldWeight } from \"@solar-icons/react/bold/chat-square\"\nimport { CheckCircleIcon as CheckCircleBoldWeight } from \"@solar-icons/react/bold/check-circle\"\nimport { ChecklistIcon as ChecklistBoldWeight } from \"@solar-icons/react/bold/checklist\"\nimport { ClipboardListIcon as ClipboardListBoldWeight } from \"@solar-icons/react/bold/clipboard-list\"\nimport { ClockCircleIcon as ClockCircleBoldWeight } from \"@solar-icons/react/bold/clock-circle\"\nimport { CompassIcon as CompassBoldWeight } from \"@solar-icons/react/bold/compass\"\nimport { CopyIcon as CopyBoldWeight } from \"@solar-icons/react/bold/copy\"\nimport { CrownIcon as CrownBoldWeight } from \"@solar-icons/react/bold/crown\"\nimport { DangerTriangleIcon as DangerTriangleBoldWeight } from \"@solar-icons/react/bold/danger-triangle\"\nimport { DatabaseIcon as DatabaseBoldWeight } from \"@solar-icons/react/bold/database\"\nimport { DisketteIcon as DisketteBoldWeight } from \"@solar-icons/react/bold/diskette\"\nimport { DislikeIcon as DislikeBoldWeight } from \"@solar-icons/react/bold/dislike\"\nimport { DocumentAddIcon as DocumentAddBoldWeight } from \"@solar-icons/react/bold/document-add\"\nimport { DocumentTextIcon as DocumentTextBoldWeight } from \"@solar-icons/react/bold/document-text\"\nimport { DoubleAltArrowDownIcon as DoubleAltArrowDownBoldWeight } from \"@solar-icons/react/bold/double-alt-arrow-down\"\nimport { DownloadIcon as DownloadBoldWeight } from \"@solar-icons/react/bold/download\"\nimport { EraserIcon as EraserBoldWeight } from \"@solar-icons/react/bold/eraser\"\nimport { EyeIcon as EyeBoldWeight } from \"@solar-icons/react/bold/eye\"\nimport { FileIcon as FileBoldWeight } from \"@solar-icons/react/bold/file\"\nimport { FileRemoveIcon as FileRemoveBoldWeight } from \"@solar-icons/react/bold/file-remove\"\nimport { FileTextIcon as FileTextBoldWeight } from \"@solar-icons/react/bold/file-text\"\nimport { FilterIcon as FilterBoldWeight } from \"@solar-icons/react/bold/filter\"\nimport { FiltersIcon as FiltersBoldWeight } from \"@solar-icons/react/bold/filters\"\nimport { FolderIcon as FolderBoldWeight } from \"@solar-icons/react/bold/folder\"\nimport { FolderOpenIcon as FolderOpenBoldWeight } from \"@solar-icons/react/bold/folder-open\"\nimport { FolderPathConnectIcon as FolderPathConnectBoldWeight } from \"@solar-icons/react/bold/folder-path-connect\"\nimport { ForbiddenCircleIcon as ForbiddenCircleBoldWeight } from \"@solar-icons/react/bold/forbidden-circle\"\nimport { GalleryIcon as GalleryBoldWeight } from \"@solar-icons/react/bold/gallery\"\nimport { GalleryAddIcon as GalleryAddBoldWeight } from \"@solar-icons/react/bold/gallery-add\"\nimport { GalleryWideIcon as GalleryWideBoldWeight } from \"@solar-icons/react/bold/gallery-wide\"\nimport { GlobalIcon as GlobalBoldWeight } from \"@solar-icons/react/bold/global\"\nimport { GraphDownIcon as GraphDownBoldWeight } from \"@solar-icons/react/bold/graph-down\"\nimport { GraphUpIcon as GraphUpBoldWeight } from \"@solar-icons/react/bold/graph-up\"\nimport { HamburgerMenuIcon as HamburgerMenuBoldWeight } from \"@solar-icons/react/bold/hamburger-menu\"\nimport { HandHeartIcon as HandHeartBoldWeight } from \"@solar-icons/react/bold/hand-heart\"\nimport { HeartIcon as HeartBoldWeight } from \"@solar-icons/react/bold/heart\"\nimport { HelpIcon as HelpBoldWeight } from \"@solar-icons/react/bold/help\"\nimport { HistoryIcon as HistoryBoldWeight } from \"@solar-icons/react/bold/history\"\nimport { HomeAngleIcon as HomeAngleBoldWeight } from \"@solar-icons/react/bold/home-angle\"\nimport { InfoCircleIcon as InfoCircleBoldWeight } from \"@solar-icons/react/bold/info-circle\"\nimport { LayersIcon as LayersBoldWeight } from \"@solar-icons/react/bold/layers\"\nimport { LetterIcon as LetterBoldWeight } from \"@solar-icons/react/bold/letter\"\nimport { LikeIcon as LikeBoldWeight } from \"@solar-icons/react/bold/like\"\nimport { LinkIcon as LinkBoldWeight } from \"@solar-icons/react/bold/link\"\nimport { ListIcon as ListBoldWeight } from \"@solar-icons/react/bold/list\"\nimport { ListVerticalIcon as ListVerticalBoldWeight } from \"@solar-icons/react/bold/list-vertical\"\nimport { LockPasswordIcon as LockPasswordBoldWeight } from \"@solar-icons/react/bold/lock-password\"\nimport { Login2Icon as Login2BoldWeight } from \"@solar-icons/react/bold/login-2\"\nimport { LogoutIcon as LogoutBoldWeight } from \"@solar-icons/react/bold/logout\"\nimport { MagicWand2Icon as MagicWand2BoldWeight } from \"@solar-icons/react/bold/magic-wand-2\"\nimport { MagnifierIcon as MagnifierBoldWeight } from \"@solar-icons/react/bold/magnifier\"\nimport { MagnifierZoomInIcon as MagnifierZoomInBoldWeight } from \"@solar-icons/react/bold/magnifier-zoom-in\"\nimport { MagnifierZoomOutIcon as MagnifierZoomOutBoldWeight } from \"@solar-icons/react/bold/magnifier-zoom-out\"\nimport { MaximizeIcon as MaximizeBoldWeight } from \"@solar-icons/react/bold/maximize\"\nimport { MenuDotsIcon as MenuDotsBoldWeight } from \"@solar-icons/react/bold/menu-dots\"\nimport { MinimizeIcon as MinimizeBoldWeight } from \"@solar-icons/react/bold/minimize\"\nimport { MinusSquareIcon as MinusSquareBoldWeight } from \"@solar-icons/react/bold/minus-square\"\nimport { MonitorIcon as MonitorBoldWeight } from \"@solar-icons/react/bold/monitor\"\nimport { MonitorSmartphoneIcon as MonitorSmartphoneBoldWeight } from \"@solar-icons/react/bold/monitor-smartphone\"\nimport { MoonIcon as MoonBoldWeight } from \"@solar-icons/react/bold/moon\"\nimport { MoveToFolderIcon as MoveToFolderBoldWeight } from \"@solar-icons/react/bold/move-to-folder\"\nimport { MusicNotesIcon as MusicNotesBoldWeight } from \"@solar-icons/react/bold/music-notes\"\nimport { PaletteIcon as PaletteBoldWeight } from \"@solar-icons/react/bold/palette\"\nimport { PaletteRoundIcon as PaletteRoundBoldWeight } from \"@solar-icons/react/bold/palette-round\"\nimport { PauseIcon as PauseBoldWeight } from \"@solar-icons/react/bold/pause\"\nimport { PenIcon as PenBoldWeight } from \"@solar-icons/react/bold/pen\"\nimport { PenNewRoundIcon as PenNewRoundBoldWeight } from \"@solar-icons/react/bold/pen-new-round\"\nimport { PieChartIcon as PieChartBoldWeight } from \"@solar-icons/react/bold/pie-chart\"\nimport { PinIcon as PinBoldWeight } from \"@solar-icons/react/bold/pin\"\nimport { PlayIcon as PlayBoldWeight } from \"@solar-icons/react/bold/play\"\nimport { PlugCircleIcon as PlugCircleBoldWeight } from \"@solar-icons/react/bold/plug-circle\"\nimport { PlusMinusIcon as PlusMinusBoldWeight } from \"@solar-icons/react/bold/plus-minus\"\nimport { PulseIcon as PulseBoldWeight } from \"@solar-icons/react/bold/pulse\"\nimport { RefreshIcon as RefreshBoldWeight } from \"@solar-icons/react/bold/refresh\"\nimport { RefreshCircleIcon as RefreshCircleBoldWeight } from \"@solar-icons/react/bold/refresh-circle\"\nimport { ReorderIcon as ReorderBoldWeight } from \"@solar-icons/react/bold/reorder\"\nimport { RepeatIcon as RepeatBoldWeight } from \"@solar-icons/react/bold/repeat\"\nimport { ReplyIcon as ReplyBoldWeight } from \"@solar-icons/react/bold/reply\"\nimport { RestartIcon as RestartBoldWeight } from \"@solar-icons/react/bold/restart\"\nimport { RocketIcon as RocketBoldWeight } from \"@solar-icons/react/bold/rocket\"\nimport { RouteIcon as RouteBoldWeight } from \"@solar-icons/react/bold/route\"\nimport { ScaleIcon as ScaleBoldWeight } from \"@solar-icons/react/bold/scale\"\nimport { ServerIcon as ServerBoldWeight } from \"@solar-icons/react/bold/server\"\nimport { SettingsIcon as SettingsBoldWeight } from \"@solar-icons/react/bold/settings\"\nimport { ShareIcon as ShareBoldWeight } from \"@solar-icons/react/bold/share\"\nimport { ShieldCheckIcon as ShieldCheckBoldWeight } from \"@solar-icons/react/bold/shield-check\"\nimport { Shop2Icon as Shop2BoldWeight } from \"@solar-icons/react/bold/shop-2\"\nimport { SidebarMinimalisticIcon as SidebarMinimalisticBoldWeight } from \"@solar-icons/react/bold/sidebar-minimalistic\"\nimport { SliderHorizontalIcon as SliderHorizontalBoldWeight } from \"@solar-icons/react/bold/slider-horizontal\"\nimport { SmartphoneIcon as SmartphoneBoldWeight } from \"@solar-icons/react/bold/smartphone\"\nimport { SortIcon as SortBoldWeight } from \"@solar-icons/react/bold/sort\"\nimport { SortByTimeIcon as SortByTimeBoldWeight } from \"@solar-icons/react/bold/sort-by-time\"\nimport { SortHorizontalIcon as SortHorizontalBoldWeight } from \"@solar-icons/react/bold/sort-horizontal\"\nimport { SortVerticalIcon as SortVerticalBoldWeight } from \"@solar-icons/react/bold/sort-vertical\"\nimport { StarIcon as StarBoldWeight } from \"@solar-icons/react/bold/star\"\nimport { StructureIcon as StructureBoldWeight } from \"@solar-icons/react/bold/structure\"\nimport { SunIcon as SunBoldWeight } from \"@solar-icons/react/bold/sun\"\nimport { TagIcon as TagBoldWeight } from \"@solar-icons/react/bold/tag\"\nimport { TelescopeIcon as TelescopeBoldWeight } from \"@solar-icons/react/bold/telescope\"\nimport { TestTubeIcon as TestTubeBoldWeight } from \"@solar-icons/react/bold/test-tube\"\nimport { TextFormatIcon as TextFormatBoldWeight } from \"@solar-icons/react/bold/text-format\"\nimport { TransferHorizontalIcon as TransferHorizontalBoldWeight } from \"@solar-icons/react/bold/transfer-horizontal\"\nimport { TranslationIcon as TranslationBoldWeight } from \"@solar-icons/react/bold/translation\"\nimport { TrashBinMinimalisticIcon as TrashBinMinimalisticBoldWeight } from \"@solar-icons/react/bold/trash-bin-minimalistic\"\nimport { UndoLeftIcon as UndoLeftBoldWeight } from \"@solar-icons/react/bold/undo-left\"\nimport { UndoLeftRoundIcon as UndoLeftRoundBoldWeight } from \"@solar-icons/react/bold/undo-left-round\"\nimport { UndoRightIcon as UndoRightBoldWeight } from \"@solar-icons/react/bold/undo-right\"\nimport { UndoRightRoundIcon as UndoRightRoundBoldWeight } from \"@solar-icons/react/bold/undo-right-round\"\nimport { UploadIcon as UploadBoldWeight } from \"@solar-icons/react/bold/upload\"\nimport { UserIcon as UserBoldWeight } from \"@solar-icons/react/bold/user\"\nimport { UserIdIcon as UserIdBoldWeight } from \"@solar-icons/react/bold/user-id\"\nimport { UserMinusIcon as UserMinusBoldWeight } from \"@solar-icons/react/bold/user-minus\"\nimport { UserPlusIcon as UserPlusBoldWeight } from \"@solar-icons/react/bold/user-plus\"\nimport { UsersGroupRoundedIcon as UsersGroupRoundedBoldWeight } from \"@solar-icons/react/bold/users-group-rounded\"\nimport { UsersGroupTwoRoundedIcon as UsersGroupTwoRoundedBoldWeight } from \"@solar-icons/react/bold/users-group-two-rounded\"\nimport { VideoFrameIcon as VideoFrameBoldWeight } from \"@solar-icons/react/bold/video-frame\"\nimport { VideoFramePlayHorizontalIcon as VideoFramePlayHorizontalBoldWeight } from \"@solar-icons/react/bold/video-frame-play-horizontal\"\nimport { Widget2Icon as Widget2BoldWeight } from \"@solar-icons/react/bold/widget-2\"\nimport { Widget5Icon as Widget5BoldWeight } from \"@solar-icons/react/bold/widget-5\"\nimport { WindowFrameIcon as WindowFrameBoldWeight } from \"@solar-icons/react/bold/window-frame\"\nimport { AddCircleIcon as AddCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/add-circle\"\nimport { AlignLeftIcon as AlignLeftBoldDuotone } from \"@solar-icons/react/bold-duotone/align-left\"\nimport { AltArrowDownIcon as AltArrowDownBoldDuotone } from \"@solar-icons/react/bold-duotone/alt-arrow-down\"\nimport { AltArrowLeftIcon as AltArrowLeftBoldDuotone } from \"@solar-icons/react/bold-duotone/alt-arrow-left\"\nimport { AltArrowRightIcon as AltArrowRightBoldDuotone } from \"@solar-icons/react/bold-duotone/alt-arrow-right\"\nimport { AltArrowUpIcon as AltArrowUpBoldDuotone } from \"@solar-icons/react/bold-duotone/alt-arrow-up\"\nimport { ArchiveIcon as ArchiveBoldDuotone } from \"@solar-icons/react/bold-duotone/archive\"\nimport { ArrowRightIcon as ArrowRightBoldDuotone } from \"@solar-icons/react/bold-duotone/arrow-right\"\nimport { ArrowToTopLeftIcon as ArrowToTopLeftBoldDuotone } from \"@solar-icons/react/bold-duotone/arrow-to-top-left\"\nimport { ArrowToTopRightIcon as ArrowToTopRightBoldDuotone } from \"@solar-icons/react/bold-duotone/arrow-to-top-right\"\nimport { BellIcon as BellBoldDuotone } from \"@solar-icons/react/bold-duotone/bell\"\nimport { BoltIcon as BoltBoldDuotone } from \"@solar-icons/react/bold-duotone/bolt\"\nimport { BookIcon as BookBoldDuotone } from \"@solar-icons/react/bold-duotone/book\"\nimport { Book2Icon as Book2BoldDuotone } from \"@solar-icons/react/bold-duotone/book-2\"\nimport { BookmarkIcon as BookmarkBoldDuotone } from \"@solar-icons/react/bold-duotone/bookmark\"\nimport { BookmarkCircleIcon as BookmarkCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/bookmark-circle\"\nimport { BoxIcon as BoxBoldDuotone } from \"@solar-icons/react/bold-duotone/box\"\nimport { BranchingPathsUpIcon as BranchingPathsUpBoldDuotone } from \"@solar-icons/react/bold-duotone/branching-paths-up\"\nimport { BugIcon as BugBoldDuotone } from \"@solar-icons/react/bold-duotone/bug\"\nimport { CalendarDateIcon as CalendarDateBoldDuotone } from \"@solar-icons/react/bold-duotone/calendar-date\"\nimport { ChatRoundIcon as ChatRoundBoldDuotone } from \"@solar-icons/react/bold-duotone/chat-round\"\nimport { ChatRoundDotsIcon as ChatRoundDotsBoldDuotone } from \"@solar-icons/react/bold-duotone/chat-round-dots\"\nimport { ChatRoundLineIcon as ChatRoundLineBoldDuotone } from \"@solar-icons/react/bold-duotone/chat-round-line\"\nimport { ChatSquareIcon as ChatSquareBoldDuotone } from \"@solar-icons/react/bold-duotone/chat-square\"\nimport { CheckCircleIcon as CheckCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/check-circle\"\nimport { ChecklistIcon as ChecklistBoldDuotone } from \"@solar-icons/react/bold-duotone/checklist\"\nimport { ClipboardListIcon as ClipboardListBoldDuotone } from \"@solar-icons/react/bold-duotone/clipboard-list\"\nimport { ClockCircleIcon as ClockCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/clock-circle\"\nimport { CompassIcon as CompassBoldDuotone } from \"@solar-icons/react/bold-duotone/compass\"\nimport { CopyIcon as CopyBoldDuotone } from \"@solar-icons/react/bold-duotone/copy\"\nimport { CrownIcon as CrownBoldDuotone } from \"@solar-icons/react/bold-duotone/crown\"\nimport { DangerTriangleIcon as DangerTriangleBoldDuotone } from \"@solar-icons/react/bold-duotone/danger-triangle\"\nimport { DatabaseIcon as DatabaseBoldDuotone } from \"@solar-icons/react/bold-duotone/database\"\nimport { DisketteIcon as DisketteBoldDuotone } from \"@solar-icons/react/bold-duotone/diskette\"\nimport { DislikeIcon as DislikeBoldDuotone } from \"@solar-icons/react/bold-duotone/dislike\"\nimport { DocumentAddIcon as DocumentAddBoldDuotone } from \"@solar-icons/react/bold-duotone/document-add\"\nimport { DocumentTextIcon as DocumentTextBoldDuotone } from \"@solar-icons/react/bold-duotone/document-text\"\nimport { DoubleAltArrowDownIcon as DoubleAltArrowDownBoldDuotone } from \"@solar-icons/react/bold-duotone/double-alt-arrow-down\"\nimport { DownloadIcon as DownloadBoldDuotone } from \"@solar-icons/react/bold-duotone/download\"\nimport { EraserIcon as EraserBoldDuotone } from \"@solar-icons/react/bold-duotone/eraser\"\nimport { EyeIcon as EyeBoldDuotone } from \"@solar-icons/react/bold-duotone/eye\"\nimport { FileIcon as FileBoldDuotone } from \"@solar-icons/react/bold-duotone/file\"\nimport { FileRemoveIcon as FileRemoveBoldDuotone } from \"@solar-icons/react/bold-duotone/file-remove\"\nimport { FileTextIcon as FileTextBoldDuotone } from \"@solar-icons/react/bold-duotone/file-text\"\nimport { FilterIcon as FilterBoldDuotone } from \"@solar-icons/react/bold-duotone/filter\"\nimport { FiltersIcon as FiltersBoldDuotone } from \"@solar-icons/react/bold-duotone/filters\"\nimport { FolderIcon as FolderBoldDuotone } from \"@solar-icons/react/bold-duotone/folder\"\nimport { FolderOpenIcon as FolderOpenBoldDuotone } from \"@solar-icons/react/bold-duotone/folder-open\"\nimport { FolderPathConnectIcon as FolderPathConnectBoldDuotone } from \"@solar-icons/react/bold-duotone/folder-path-connect\"\nimport { ForbiddenCircleIcon as ForbiddenCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/forbidden-circle\"\nimport { GalleryIcon as GalleryBoldDuotone } from \"@solar-icons/react/bold-duotone/gallery\"\nimport { GalleryAddIcon as GalleryAddBoldDuotone } from \"@solar-icons/react/bold-duotone/gallery-add\"\nimport { GalleryWideIcon as GalleryWideBoldDuotone } from \"@solar-icons/react/bold-duotone/gallery-wide\"\nimport { GlobalIcon as GlobalBoldDuotone } from \"@solar-icons/react/bold-duotone/global\"\nimport { GraphDownIcon as GraphDownBoldDuotone } from \"@solar-icons/react/bold-duotone/graph-down\"\nimport { GraphUpIcon as GraphUpBoldDuotone } from \"@solar-icons/react/bold-duotone/graph-up\"\nimport { HamburgerMenuIcon as HamburgerMenuBoldDuotone } from \"@solar-icons/react/bold-duotone/hamburger-menu\"\nimport { HandHeartIcon as HandHeartBoldDuotone } from \"@solar-icons/react/bold-duotone/hand-heart\"\nimport { HeartIcon as HeartBoldDuotone } from \"@solar-icons/react/bold-duotone/heart\"\nimport { HelpIcon as HelpBoldDuotone } from \"@solar-icons/react/bold-duotone/help\"\nimport { HistoryIcon as HistoryBoldDuotone } from \"@solar-icons/react/bold-duotone/history\"\nimport { HomeAngleIcon as HomeAngleBoldDuotone } from \"@solar-icons/react/bold-duotone/home-angle\"\nimport { InfoCircleIcon as InfoCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/info-circle\"\nimport { LayersIcon as LayersBoldDuotone } from \"@solar-icons/react/bold-duotone/layers\"\nimport { LetterIcon as LetterBoldDuotone } from \"@solar-icons/react/bold-duotone/letter\"\nimport { LikeIcon as LikeBoldDuotone } from \"@solar-icons/react/bold-duotone/like\"\nimport { LinkIcon as LinkBoldDuotone } from \"@solar-icons/react/bold-duotone/link\"\nimport { ListIcon as ListBoldDuotone } from \"@solar-icons/react/bold-duotone/list\"\nimport { ListVerticalIcon as ListVerticalBoldDuotone } from \"@solar-icons/react/bold-duotone/list-vertical\"\nimport { LockPasswordIcon as LockPasswordBoldDuotone } from \"@solar-icons/react/bold-duotone/lock-password\"\nimport { Login2Icon as Login2BoldDuotone } from \"@solar-icons/react/bold-duotone/login-2\"\nimport { LogoutIcon as LogoutBoldDuotone } from \"@solar-icons/react/bold-duotone/logout\"\nimport { MagicWand2Icon as MagicWand2BoldDuotone } from \"@solar-icons/react/bold-duotone/magic-wand-2\"\nimport { MagnifierIcon as MagnifierBoldDuotone } from \"@solar-icons/react/bold-duotone/magnifier\"\nimport { MagnifierZoomInIcon as MagnifierZoomInBoldDuotone } from \"@solar-icons/react/bold-duotone/magnifier-zoom-in\"\nimport { MagnifierZoomOutIcon as MagnifierZoomOutBoldDuotone } from \"@solar-icons/react/bold-duotone/magnifier-zoom-out\"\nimport { MaximizeIcon as MaximizeBoldDuotone } from \"@solar-icons/react/bold-duotone/maximize\"\nimport { MenuDotsIcon as MenuDotsBoldDuotone } from \"@solar-icons/react/bold-duotone/menu-dots\"\nimport { MinimizeIcon as MinimizeBoldDuotone } from \"@solar-icons/react/bold-duotone/minimize\"\nimport { MinusSquareIcon as MinusSquareBoldDuotone } from \"@solar-icons/react/bold-duotone/minus-square\"\nimport { MonitorIcon as MonitorBoldDuotone } from \"@solar-icons/react/bold-duotone/monitor\"\nimport { MonitorSmartphoneIcon as MonitorSmartphoneBoldDuotone } from \"@solar-icons/react/bold-duotone/monitor-smartphone\"\nimport { MoonIcon as MoonBoldDuotone } from \"@solar-icons/react/bold-duotone/moon\"\nimport { MoveToFolderIcon as MoveToFolderBoldDuotone } from \"@solar-icons/react/bold-duotone/move-to-folder\"\nimport { MusicNotesIcon as MusicNotesBoldDuotone } from \"@solar-icons/react/bold-duotone/music-notes\"\nimport { PaletteIcon as PaletteBoldDuotone } from \"@solar-icons/react/bold-duotone/palette\"\nimport { PaletteRoundIcon as PaletteRoundBoldDuotone } from \"@solar-icons/react/bold-duotone/palette-round\"\nimport { PauseIcon as PauseBoldDuotone } from \"@solar-icons/react/bold-duotone/pause\"\nimport { PenIcon as PenBoldDuotone } from \"@solar-icons/react/bold-duotone/pen\"\nimport { PenNewRoundIcon as PenNewRoundBoldDuotone } from \"@solar-icons/react/bold-duotone/pen-new-round\"\nimport { PieChartIcon as PieChartBoldDuotone } from \"@solar-icons/react/bold-duotone/pie-chart\"\nimport { PinIcon as PinBoldDuotone } from \"@solar-icons/react/bold-duotone/pin\"\nimport { PlayIcon as PlayBoldDuotone } from \"@solar-icons/react/bold-duotone/play\"\nimport { PlugCircleIcon as PlugCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/plug-circle\"\nimport { PlusMinusIcon as PlusMinusBoldDuotone } from \"@solar-icons/react/bold-duotone/plus-minus\"\nimport { PulseIcon as PulseBoldDuotone } from \"@solar-icons/react/bold-duotone/pulse\"\nimport { RefreshIcon as RefreshBoldDuotone } from \"@solar-icons/react/bold-duotone/refresh\"\nimport { RefreshCircleIcon as RefreshCircleBoldDuotone } from \"@solar-icons/react/bold-duotone/refresh-circle\"\nimport { ReorderIcon as ReorderBoldDuotone } from \"@solar-icons/react/bold-duotone/reorder\"\nimport { RepeatIcon as RepeatBoldDuotone } from \"@solar-icons/react/bold-duotone/repeat\"\nimport { ReplyIcon as ReplyBoldDuotone } from \"@solar-icons/react/bold-duotone/reply\"\nimport { RestartIcon as RestartBoldDuotone } from \"@solar-icons/react/bold-duotone/restart\"\nimport { RocketIcon as RocketBoldDuotone } from \"@solar-icons/react/bold-duotone/rocket\"\nimport { RouteIcon as RouteBoldDuotone } from \"@solar-icons/react/bold-duotone/route\"\nimport { ScaleIcon as ScaleBoldDuotone } from \"@solar-icons/react/bold-duotone/scale\"\nimport { ServerIcon as ServerBoldDuotone } from \"@solar-icons/react/bold-duotone/server\"\nimport { SettingsIcon as SettingsBoldDuotone } from \"@solar-icons/react/bold-duotone/settings\"\nimport { ShareIcon as ShareBoldDuotone } from \"@solar-icons/react/bold-duotone/share\"\nimport { ShieldCheckIcon as ShieldCheckBoldDuotone } from \"@solar-icons/react/bold-duotone/shield-check\"\nimport { Shop2Icon as Shop2BoldDuotone } from \"@solar-icons/react/bold-duotone/shop-2\"\nimport { SidebarMinimalisticIcon as SidebarMinimalisticBoldDuotone } from \"@solar-icons/react/bold-duotone/sidebar-minimalistic\"\nimport { SliderHorizontalIcon as SliderHorizontalBoldDuotone } from \"@solar-icons/react/bold-duotone/slider-horizontal\"\nimport { SmartphoneIcon as SmartphoneBoldDuotone } from \"@solar-icons/react/bold-duotone/smartphone\"\nimport { SortIcon as SortBoldDuotone } from \"@solar-icons/react/bold-duotone/sort\"\nimport { SortByTimeIcon as SortByTimeBoldDuotone } from \"@solar-icons/react/bold-duotone/sort-by-time\"\nimport { SortHorizontalIcon as SortHorizontalBoldDuotone } from \"@solar-icons/react/bold-duotone/sort-horizontal\"\nimport { SortVerticalIcon as SortVerticalBoldDuotone } from \"@solar-icons/react/bold-duotone/sort-vertical\"\nimport { StarIcon as StarBoldDuotone } from \"@solar-icons/react/bold-duotone/star\"\nimport { StructureIcon as StructureBoldDuotone } from \"@solar-icons/react/bold-duotone/structure\"\nimport { SunIcon as SunBoldDuotone } from \"@solar-icons/react/bold-duotone/sun\"\nimport { TagIcon as TagBoldDuotone } from \"@solar-icons/react/bold-duotone/tag\"\nimport { TelescopeIcon as TelescopeBoldDuotone } from \"@solar-icons/react/bold-duotone/telescope\"\nimport { TestTubeIcon as TestTubeBoldDuotone } from \"@solar-icons/react/bold-duotone/test-tube\"\nimport { TextFormatIcon as TextFormatBoldDuotone } from \"@solar-icons/react/bold-duotone/text-format\"\nimport { TransferHorizontalIcon as TransferHorizontalBoldDuotone } from \"@solar-icons/react/bold-duotone/transfer-horizontal\"\nimport { TranslationIcon as TranslationBoldDuotone } from \"@solar-icons/react/bold-duotone/translation\"\nimport { TrashBinMinimalisticIcon as TrashBinMinimalisticBoldDuotone } from \"@solar-icons/react/bold-duotone/trash-bin-minimalistic\"\nimport { UndoLeftIcon as UndoLeftBoldDuotone } from \"@solar-icons/react/bold-duotone/undo-left\"\nimport { UndoLeftRoundIcon as UndoLeftRoundBoldDuotone } from \"@solar-icons/react/bold-duotone/undo-left-round\"\nimport { UndoRightIcon as UndoRightBoldDuotone } from \"@solar-icons/react/bold-duotone/undo-right\"\nimport { UndoRightRoundIcon as UndoRightRoundBoldDuotone } from \"@solar-icons/react/bold-duotone/undo-right-round\"\nimport { UploadIcon as UploadBoldDuotone } from \"@solar-icons/react/bold-duotone/upload\"\nimport { UserIcon as UserBoldDuotone } from \"@solar-icons/react/bold-duotone/user\"\nimport { UserIdIcon as UserIdBoldDuotone } from \"@solar-icons/react/bold-duotone/user-id\"\nimport { UserMinusIcon as UserMinusBoldDuotone } from \"@solar-icons/react/bold-duotone/user-minus\"\nimport { UserPlusIcon as UserPlusBoldDuotone } from \"@solar-icons/react/bold-duotone/user-plus\"\nimport { UsersGroupRoundedIcon as UsersGroupRoundedBoldDuotone } from \"@solar-icons/react/bold-duotone/users-group-rounded\"\nimport { UsersGroupTwoRoundedIcon as UsersGroupTwoRoundedBoldDuotone } from \"@solar-icons/react/bold-duotone/users-group-two-rounded\"\nimport { VideoFrameIcon as VideoFrameBoldDuotone } from \"@solar-icons/react/bold-duotone/video-frame\"\nimport { VideoFramePlayHorizontalIcon as VideoFramePlayHorizontalBoldDuotone } from \"@solar-icons/react/bold-duotone/video-frame-play-horizontal\"\nimport { Widget2Icon as Widget2BoldDuotone } from \"@solar-icons/react/bold-duotone/widget-2\"\nimport { Widget5Icon as Widget5BoldDuotone } from \"@solar-icons/react/bold-duotone/widget-5\"\nimport { WindowFrameIcon as WindowFrameBoldDuotone } from \"@solar-icons/react/bold-duotone/window-frame\"\nimport { AddCircleIcon as AddCircleLinear } from \"@solar-icons/react/linear/add-circle\"\nimport { AlignLeftIcon as AlignLeftLinear } from \"@solar-icons/react/linear/align-left\"\nimport { AltArrowDownIcon as AltArrowDownLinear } from \"@solar-icons/react/linear/alt-arrow-down\"\nimport { AltArrowLeftIcon as AltArrowLeftLinear } from \"@solar-icons/react/linear/alt-arrow-left\"\nimport { AltArrowRightIcon as AltArrowRightLinear } from \"@solar-icons/react/linear/alt-arrow-right\"\nimport { AltArrowUpIcon as AltArrowUpLinear } from \"@solar-icons/react/linear/alt-arrow-up\"\nimport { ArchiveIcon as ArchiveLinear } from \"@solar-icons/react/linear/archive\"\nimport { ArrowRightIcon as ArrowRightLinear } from \"@solar-icons/react/linear/arrow-right\"\nimport { ArrowToTopLeftIcon as ArrowToTopLeftLinear } from \"@solar-icons/react/linear/arrow-to-top-left\"\nimport { ArrowToTopRightIcon as ArrowToTopRightLinear } from \"@solar-icons/react/linear/arrow-to-top-right\"\nimport { BellIcon as BellLinear } from \"@solar-icons/react/linear/bell\"\nimport { BoltIcon as BoltLinear } from \"@solar-icons/react/linear/bolt\"\nimport { BookIcon as BookLinear } from \"@solar-icons/react/linear/book\"\nimport { Book2Icon as Book2Linear } from \"@solar-icons/react/linear/book-2\"\nimport { BookmarkIcon as BookmarkLinear } from \"@solar-icons/react/linear/bookmark\"\nimport { BookmarkCircleIcon as BookmarkCircleLinear } from \"@solar-icons/react/linear/bookmark-circle\"\nimport { BoxIcon as BoxLinear } from \"@solar-icons/react/linear/box\"\nimport { BranchingPathsUpIcon as BranchingPathsUpLinear } from \"@solar-icons/react/linear/branching-paths-up\"\nimport { BugIcon as BugLinear } from \"@solar-icons/react/linear/bug\"\nimport { CalendarDateIcon as CalendarDateLinear } from \"@solar-icons/react/linear/calendar-date\"\nimport { ChatRoundIcon as ChatRoundLinear } from \"@solar-icons/react/linear/chat-round\"\nimport { ChatRoundDotsIcon as ChatRoundDotsLinear } from \"@solar-icons/react/linear/chat-round-dots\"\nimport { ChatRoundLineIcon as ChatRoundLineLinear } from \"@solar-icons/react/linear/chat-round-line\"\nimport { ChatSquareIcon as ChatSquareLinear } from \"@solar-icons/react/linear/chat-square\"\nimport { CheckCircleIcon as CheckCircleLinear } from \"@solar-icons/react/linear/check-circle\"\nimport { ChecklistIcon as ChecklistLinear } from \"@solar-icons/react/linear/checklist\"\nimport { ClipboardListIcon as ClipboardListLinear } from \"@solar-icons/react/linear/clipboard-list\"\nimport { ClockCircleIcon as ClockCircleLinear } from \"@solar-icons/react/linear/clock-circle\"\nimport { CompassIcon as CompassLinear } from \"@solar-icons/react/linear/compass\"\nimport { CopyIcon as CopyLinear } from \"@solar-icons/react/linear/copy\"\nimport { CrownIcon as CrownLinear } from \"@solar-icons/react/linear/crown\"\nimport { DangerTriangleIcon as DangerTriangleLinear } from \"@solar-icons/react/linear/danger-triangle\"\nimport { DatabaseIcon as DatabaseLinear } from \"@solar-icons/react/linear/database\"\nimport { DisketteIcon as DisketteLinear } from \"@solar-icons/react/linear/diskette\"\nimport { DislikeIcon as DislikeLinear } from \"@solar-icons/react/linear/dislike\"\nimport { DocumentAddIcon as DocumentAddLinear } from \"@solar-icons/react/linear/document-add\"\nimport { DocumentTextIcon as DocumentTextLinear } from \"@solar-icons/react/linear/document-text\"\nimport { DoubleAltArrowDownIcon as DoubleAltArrowDownLinear } from \"@solar-icons/react/linear/double-alt-arrow-down\"\nimport { DownloadIcon as DownloadLinear } from \"@solar-icons/react/linear/download\"\nimport { EraserIcon as EraserLinear } from \"@solar-icons/react/linear/eraser\"\nimport { EyeIcon as EyeLinear } from \"@solar-icons/react/linear/eye\"\nimport { FileIcon as FileLinear } from \"@solar-icons/react/linear/file\"\nimport { FileRemoveIcon as FileRemoveLinear } from \"@solar-icons/react/linear/file-remove\"\nimport { FileTextIcon as FileTextLinear } from \"@solar-icons/react/linear/file-text\"\nimport { FilterIcon as FilterLinear } from \"@solar-icons/react/linear/filter\"\nimport { FiltersIcon as FiltersLinear } from \"@solar-icons/react/linear/filters\"\nimport { FolderIcon as FolderLinear } from \"@solar-icons/react/linear/folder\"\nimport { FolderOpenIcon as FolderOpenLinear } from \"@solar-icons/react/linear/folder-open\"\nimport { FolderPathConnectIcon as FolderPathConnectLinear } from \"@solar-icons/react/linear/folder-path-connect\"\nimport { ForbiddenCircleIcon as ForbiddenCircleLinear } from \"@solar-icons/react/linear/forbidden-circle\"\nimport { GalleryIcon as GalleryLinear } from \"@solar-icons/react/linear/gallery\"\nimport { GalleryAddIcon as GalleryAddLinear } from \"@solar-icons/react/linear/gallery-add\"\nimport { GalleryWideIcon as GalleryWideLinear } from \"@solar-icons/react/linear/gallery-wide\"\nimport { GlobalIcon as GlobalLinear } from \"@solar-icons/react/linear/global\"\nimport { GraphDownIcon as GraphDownLinear } from \"@solar-icons/react/linear/graph-down\"\nimport { GraphUpIcon as GraphUpLinear } from \"@solar-icons/react/linear/graph-up\"\nimport { HamburgerMenuIcon as HamburgerMenuLinear } from \"@solar-icons/react/linear/hamburger-menu\"\nimport { HandHeartIcon as HandHeartLinear } from \"@solar-icons/react/linear/hand-heart\"\nimport { HeartIcon as HeartLinear } from \"@solar-icons/react/linear/heart\"\nimport { HelpIcon as HelpLinear } from \"@solar-icons/react/linear/help\"\nimport { HistoryIcon as HistoryLinear } from \"@solar-icons/react/linear/history\"\nimport { HomeAngleIcon as HomeAngleLinear } from \"@solar-icons/react/linear/home-angle\"\nimport { InfoCircleIcon as InfoCircleLinear } from \"@solar-icons/react/linear/info-circle\"\nimport { LayersIcon as LayersLinear } from \"@solar-icons/react/linear/layers\"\nimport { LetterIcon as LetterLinear } from \"@solar-icons/react/linear/letter\"\nimport { LikeIcon as LikeLinear } from \"@solar-icons/react/linear/like\"\nimport { LinkIcon as LinkLinear } from \"@solar-icons/react/linear/link\"\nimport { ListIcon as ListLinear } from \"@solar-icons/react/linear/list\"\nimport { ListVerticalIcon as ListVerticalLinear } from \"@solar-icons/react/linear/list-vertical\"\nimport { LockPasswordIcon as LockPasswordLinear } from \"@solar-icons/react/linear/lock-password\"\nimport { Login2Icon as Login2Linear } from \"@solar-icons/react/linear/login-2\"\nimport { LogoutIcon as LogoutLinear } from \"@solar-icons/react/linear/logout\"\nimport { MagicWand2Icon as MagicWand2Linear } from \"@solar-icons/react/linear/magic-wand-2\"\nimport { MagnifierIcon as MagnifierLinear } from \"@solar-icons/react/linear/magnifier\"\nimport { MagnifierZoomInIcon as MagnifierZoomInLinear } from \"@solar-icons/react/linear/magnifier-zoom-in\"\nimport { MagnifierZoomOutIcon as MagnifierZoomOutLinear } from \"@solar-icons/react/linear/magnifier-zoom-out\"\nimport { MaximizeIcon as MaximizeLinear } from \"@solar-icons/react/linear/maximize\"\nimport { MinimizeIcon as MinimizeLinear } from \"@solar-icons/react/linear/minimize\"\nimport { MinusSquareIcon as MinusSquareLinear } from \"@solar-icons/react/linear/minus-square\"\nimport { MonitorIcon as MonitorLinear } from \"@solar-icons/react/linear/monitor\"\nimport { MonitorSmartphoneIcon as MonitorSmartphoneLinear } from \"@solar-icons/react/linear/monitor-smartphone\"\nimport { MoonIcon as MoonLinear } from \"@solar-icons/react/linear/moon\"\nimport { MoveToFolderIcon as MoveToFolderLinear } from \"@solar-icons/react/linear/move-to-folder\"\nimport { MusicNotesIcon as MusicNotesLinear } from \"@solar-icons/react/linear/music-notes\"\nimport { PaletteIcon as PaletteLinear } from \"@solar-icons/react/linear/palette\"\nimport { PaletteRoundIcon as PaletteRoundLinear } from \"@solar-icons/react/linear/palette-round\"\nimport { PauseIcon as PauseLinear } from \"@solar-icons/react/linear/pause\"\nimport { PenIcon as PenLinear } from \"@solar-icons/react/linear/pen\"\nimport { PenNewRoundIcon as PenNewRoundLinear } from \"@solar-icons/react/linear/pen-new-round\"\nimport { PieChartIcon as PieChartLinear } from \"@solar-icons/react/linear/pie-chart\"\nimport { PinIcon as PinLinear } from \"@solar-icons/react/linear/pin\"\nimport { PlayIcon as PlayLinear } from \"@solar-icons/react/linear/play\"\nimport { PlugCircleIcon as PlugCircleLinear } from \"@solar-icons/react/linear/plug-circle\"\nimport { PlusMinusIcon as PlusMinusLinear } from \"@solar-icons/react/linear/plus-minus\"\nimport { PulseIcon as PulseLinear } from \"@solar-icons/react/linear/pulse\"\nimport { RefreshIcon as RefreshLinear } from \"@solar-icons/react/linear/refresh\"\nimport { RefreshCircleIcon as RefreshCircleLinear } from \"@solar-icons/react/linear/refresh-circle\"\nimport { ReorderIcon as ReorderLinear } from \"@solar-icons/react/linear/reorder\"\nimport { RepeatIcon as RepeatLinear } from \"@solar-icons/react/linear/repeat\"\nimport { ReplyIcon as ReplyLinear } from \"@solar-icons/react/linear/reply\"\nimport { RestartIcon as RestartLinear } from \"@solar-icons/react/linear/restart\"\nimport { RocketIcon as RocketLinear } from \"@solar-icons/react/linear/rocket\"\nimport { RouteIcon as RouteLinear } from \"@solar-icons/react/linear/route\"\nimport { ScaleIcon as ScaleLinear } from \"@solar-icons/react/linear/scale\"\nimport { ServerIcon as ServerLinear } from \"@solar-icons/react/linear/server\"\nimport { SettingsIcon as SettingsLinear } from \"@solar-icons/react/linear/settings\"\nimport { ShareIcon as ShareLinear } from \"@solar-icons/react/linear/share\"\nimport { ShieldCheckIcon as ShieldCheckLinear } from \"@solar-icons/react/linear/shield-check\"\nimport { Shop2Icon as Shop2Linear } from \"@solar-icons/react/linear/shop-2\"\nimport { SidebarMinimalisticIcon as SidebarMinimalisticLinear } from \"@solar-icons/react/linear/sidebar-minimalistic\"\nimport { SliderHorizontalIcon as SliderHorizontalLinear } from \"@solar-icons/react/linear/slider-horizontal\"\nimport { SmartphoneIcon as SmartphoneLinear } from \"@solar-icons/react/linear/smartphone\"\nimport { SortIcon as SortLinear } from \"@solar-icons/react/linear/sort\"\nimport { SortByTimeIcon as SortByTimeLinear } from \"@solar-icons/react/linear/sort-by-time\"\nimport { SortHorizontalIcon as SortHorizontalLinear } from \"@solar-icons/react/linear/sort-horizontal\"\nimport { SortVerticalIcon as SortVerticalLinear } from \"@solar-icons/react/linear/sort-vertical\"\nimport { StarIcon as StarLinear } from \"@solar-icons/react/linear/star\"\nimport { StructureIcon as StructureLinear } from \"@solar-icons/react/linear/structure\"\nimport { SunIcon as SunLinear } from \"@solar-icons/react/linear/sun\"\nimport { TagIcon as TagLinear } from \"@solar-icons/react/linear/tag\"\nimport { TelescopeIcon as TelescopeLinear } from \"@solar-icons/react/linear/telescope\"\nimport { TestTubeIcon as TestTubeLinear } from \"@solar-icons/react/linear/test-tube\"\nimport { TextFormatIcon as TextFormatLinear } from \"@solar-icons/react/linear/text-format\"\nimport { TransferHorizontalIcon as TransferHorizontalLinear } from \"@solar-icons/react/linear/transfer-horizontal\"\nimport { TranslationIcon as TranslationLinear } from \"@solar-icons/react/linear/translation\"\nimport { TrashBinMinimalisticIcon as TrashBinMinimalisticLinear } from \"@solar-icons/react/linear/trash-bin-minimalistic\"\nimport { UndoLeftIcon as UndoLeftLinear } from \"@solar-icons/react/linear/undo-left\"\nimport { UndoLeftRoundIcon as UndoLeftRoundLinear } from \"@solar-icons/react/linear/undo-left-round\"\nimport { UndoRightIcon as UndoRightLinear } from \"@solar-icons/react/linear/undo-right\"\nimport { UndoRightRoundIcon as UndoRightRoundLinear } from \"@solar-icons/react/linear/undo-right-round\"\nimport { UploadIcon as UploadLinear } from \"@solar-icons/react/linear/upload\"\nimport { UserIcon as UserLinear } from \"@solar-icons/react/linear/user\"\nimport { UserIdIcon as UserIdLinear } from \"@solar-icons/react/linear/user-id\"\nimport { UserMinusIcon as UserMinusLinear } from \"@solar-icons/react/linear/user-minus\"\nimport { UserPlusIcon as UserPlusLinear } from \"@solar-icons/react/linear/user-plus\"\nimport { UsersGroupRoundedIcon as UsersGroupRoundedLinear } from \"@solar-icons/react/linear/users-group-rounded\"\nimport { UsersGroupTwoRoundedIcon as UsersGroupTwoRoundedLinear } from \"@solar-icons/react/linear/users-group-two-rounded\"\nimport { VideoFrameIcon as VideoFrameLinear } from \"@solar-icons/react/linear/video-frame\"\nimport { VideoFramePlayHorizontalIcon as VideoFramePlayHorizontalLinear } from \"@solar-icons/react/linear/video-frame-play-horizontal\"\nimport { Widget2Icon as Widget2Linear } from \"@solar-icons/react/linear/widget-2\"\nimport { Widget5Icon as Widget5Linear } from \"@solar-icons/react/linear/widget-5\"\nimport { WindowFrameIcon as WindowFrameLinear } from \"@solar-icons/react/linear/window-frame\"\nimport { createIcon } from \"./icon-style\"\n\n// ── One icon per glyph - three parallel Solar weights ────────────\nexport const AddCircle = createIcon({\n\tbold: AddCircleBoldWeight,\n\tboldDuotone: AddCircleBoldDuotone,\n\tlinear: AddCircleLinear,\n})\nexport const AlignLeft = createIcon({\n\tbold: AlignLeftBoldWeight,\n\tboldDuotone: AlignLeftBoldDuotone,\n\tlinear: AlignLeftLinear,\n})\nexport const AltArrowDown = createIcon({\n\tbold: AltArrowDownBoldWeight,\n\tboldDuotone: AltArrowDownBoldDuotone,\n\tlinear: AltArrowDownLinear,\n})\nexport const AltArrowLeft = createIcon({\n\tbold: AltArrowLeftBoldWeight,\n\tboldDuotone: AltArrowLeftBoldDuotone,\n\tlinear: AltArrowLeftLinear,\n})\nexport const AltArrowRight = createIcon({\n\tbold: AltArrowRightBoldWeight,\n\tboldDuotone: AltArrowRightBoldDuotone,\n\tlinear: AltArrowRightLinear,\n})\nexport const AltArrowUp = createIcon({\n\tbold: AltArrowUpBoldWeight,\n\tboldDuotone: AltArrowUpBoldDuotone,\n\tlinear: AltArrowUpLinear,\n})\nexport const Archive = createIcon({\n\tbold: ArchiveBoldWeight,\n\tboldDuotone: ArchiveBoldDuotone,\n\tlinear: ArchiveLinear,\n})\nexport const ArrowRight = createIcon({\n\tbold: ArrowRightBoldWeight,\n\tboldDuotone: ArrowRightBoldDuotone,\n\tlinear: ArrowRightLinear,\n})\nexport const ArrowToTopLeft = createIcon({\n\tbold: ArrowToTopLeftBoldWeight,\n\tboldDuotone: ArrowToTopLeftBoldDuotone,\n\tlinear: ArrowToTopLeftLinear,\n})\nexport const ArrowToTopRight = createIcon({\n\tbold: ArrowToTopRightBoldWeight,\n\tboldDuotone: ArrowToTopRightBoldDuotone,\n\tlinear: ArrowToTopRightLinear,\n})\nexport const Bell = createIcon({\n\tbold: BellBoldWeight,\n\tboldDuotone: BellBoldDuotone,\n\tlinear: BellLinear,\n})\nexport const Bolt = createIcon({\n\tbold: BoltBoldWeight,\n\tboldDuotone: BoltBoldDuotone,\n\tlinear: BoltLinear,\n})\nexport const Book = createIcon({\n\tbold: BookBoldWeight,\n\tboldDuotone: BookBoldDuotone,\n\tlinear: BookLinear,\n})\nexport const Book2 = createIcon({\n\tbold: Book2BoldWeight,\n\tboldDuotone: Book2BoldDuotone,\n\tlinear: Book2Linear,\n})\nexport const Bookmark = createIcon({\n\tbold: BookmarkBoldWeight,\n\tboldDuotone: BookmarkBoldDuotone,\n\tlinear: BookmarkLinear,\n})\nexport const BookmarkCircle = createIcon({\n\tbold: BookmarkCircleBoldWeight,\n\tboldDuotone: BookmarkCircleBoldDuotone,\n\tlinear: BookmarkCircleLinear,\n})\nexport const Box = createIcon({\n\tbold: BoxBoldWeight,\n\tboldDuotone: BoxBoldDuotone,\n\tlinear: BoxLinear,\n})\nexport const BranchingPathsUp = createIcon({\n\tbold: BranchingPathsUpBoldWeight,\n\tboldDuotone: BranchingPathsUpBoldDuotone,\n\tlinear: BranchingPathsUpLinear,\n})\nexport const Bug = createIcon({\n\tbold: BugBoldWeight,\n\tboldDuotone: BugBoldDuotone,\n\tlinear: BugLinear,\n})\nexport const CalendarDate = createIcon({\n\tbold: CalendarDateBoldWeight,\n\tboldDuotone: CalendarDateBoldDuotone,\n\tlinear: CalendarDateLinear,\n})\nexport const ChatRound = createIcon({\n\tbold: ChatRoundBoldWeight,\n\tboldDuotone: ChatRoundBoldDuotone,\n\tlinear: ChatRoundLinear,\n})\nexport const ChatRoundDots = createIcon({\n\tbold: ChatRoundDotsBoldWeight,\n\tboldDuotone: ChatRoundDotsBoldDuotone,\n\tlinear: ChatRoundDotsLinear,\n})\nexport const ChatRoundLine = createIcon({\n\tbold: ChatRoundLineBoldWeight,\n\tboldDuotone: ChatRoundLineBoldDuotone,\n\tlinear: ChatRoundLineLinear,\n})\nexport const ChatSquare = createIcon({\n\tbold: ChatSquareBoldWeight,\n\tboldDuotone: ChatSquareBoldDuotone,\n\tlinear: ChatSquareLinear,\n})\nexport const CheckCircle = createIcon({\n\tbold: CheckCircleBoldWeight,\n\tboldDuotone: CheckCircleBoldDuotone,\n\tlinear: CheckCircleLinear,\n})\nexport const Checklist = createIcon({\n\tbold: ChecklistBoldWeight,\n\tboldDuotone: ChecklistBoldDuotone,\n\tlinear: ChecklistLinear,\n})\nexport const ClipboardList = createIcon({\n\tbold: ClipboardListBoldWeight,\n\tboldDuotone: ClipboardListBoldDuotone,\n\tlinear: ClipboardListLinear,\n})\nexport const ClockCircle = createIcon({\n\tbold: ClockCircleBoldWeight,\n\tboldDuotone: ClockCircleBoldDuotone,\n\tlinear: ClockCircleLinear,\n})\nexport const Compass = createIcon({\n\tbold: CompassBoldWeight,\n\tboldDuotone: CompassBoldDuotone,\n\tlinear: CompassLinear,\n})\nexport const Copy = createIcon({\n\tbold: CopyBoldWeight,\n\tboldDuotone: CopyBoldDuotone,\n\tlinear: CopyLinear,\n})\nexport const Crown = createIcon({\n\tbold: CrownBoldWeight,\n\tboldDuotone: CrownBoldDuotone,\n\tlinear: CrownLinear,\n})\nexport const DangerTriangle = createIcon({\n\tbold: DangerTriangleBoldWeight,\n\tboldDuotone: DangerTriangleBoldDuotone,\n\tlinear: DangerTriangleLinear,\n})\nexport const Database = createIcon({\n\tbold: DatabaseBoldWeight,\n\tboldDuotone: DatabaseBoldDuotone,\n\tlinear: DatabaseLinear,\n})\nexport const Diskette = createIcon({\n\tbold: DisketteBoldWeight,\n\tboldDuotone: DisketteBoldDuotone,\n\tlinear: DisketteLinear,\n})\nexport const Dislike = createIcon({\n\tbold: DislikeBoldWeight,\n\tboldDuotone: DislikeBoldDuotone,\n\tlinear: DislikeLinear,\n})\nexport const DocumentAdd = createIcon({\n\tbold: DocumentAddBoldWeight,\n\tboldDuotone: DocumentAddBoldDuotone,\n\tlinear: DocumentAddLinear,\n})\nexport const DocumentText = createIcon({\n\tbold: DocumentTextBoldWeight,\n\tboldDuotone: DocumentTextBoldDuotone,\n\tlinear: DocumentTextLinear,\n})\nexport const DoubleAltArrowDown = createIcon({\n\tbold: DoubleAltArrowDownBoldWeight,\n\tboldDuotone: DoubleAltArrowDownBoldDuotone,\n\tlinear: DoubleAltArrowDownLinear,\n})\nexport const Download = createIcon({\n\tbold: DownloadBoldWeight,\n\tboldDuotone: DownloadBoldDuotone,\n\tlinear: DownloadLinear,\n})\nexport const Eraser = createIcon({\n\tbold: EraserBoldWeight,\n\tboldDuotone: EraserBoldDuotone,\n\tlinear: EraserLinear,\n})\nexport const Eye = createIcon({\n\tbold: EyeBoldWeight,\n\tboldDuotone: EyeBoldDuotone,\n\tlinear: EyeLinear,\n})\nexport const File = createIcon({\n\tbold: FileBoldWeight,\n\tboldDuotone: FileBoldDuotone,\n\tlinear: FileLinear,\n})\nexport const FileRemove = createIcon({\n\tbold: FileRemoveBoldWeight,\n\tboldDuotone: FileRemoveBoldDuotone,\n\tlinear: FileRemoveLinear,\n})\nexport const FileText = createIcon({\n\tbold: FileTextBoldWeight,\n\tboldDuotone: FileTextBoldDuotone,\n\tlinear: FileTextLinear,\n})\nexport const Filter = createIcon({\n\tbold: FilterBoldWeight,\n\tboldDuotone: FilterBoldDuotone,\n\tlinear: FilterLinear,\n})\nexport const Filters = createIcon({\n\tbold: FiltersBoldWeight,\n\tboldDuotone: FiltersBoldDuotone,\n\tlinear: FiltersLinear,\n})\nexport const Folder = createIcon({\n\tbold: FolderBoldWeight,\n\tboldDuotone: FolderBoldDuotone,\n\tlinear: FolderLinear,\n})\nexport const FolderOpen = createIcon({\n\tbold: FolderOpenBoldWeight,\n\tboldDuotone: FolderOpenBoldDuotone,\n\tlinear: FolderOpenLinear,\n})\nexport const FolderPathConnect = createIcon({\n\tbold: FolderPathConnectBoldWeight,\n\tboldDuotone: FolderPathConnectBoldDuotone,\n\tlinear: FolderPathConnectLinear,\n})\nexport const ForbiddenCircle = createIcon({\n\tbold: ForbiddenCircleBoldWeight,\n\tboldDuotone: ForbiddenCircleBoldDuotone,\n\tlinear: ForbiddenCircleLinear,\n})\nexport const Gallery = createIcon({\n\tbold: GalleryBoldWeight,\n\tboldDuotone: GalleryBoldDuotone,\n\tlinear: GalleryLinear,\n})\nexport const GalleryAdd = createIcon({\n\tbold: GalleryAddBoldWeight,\n\tboldDuotone: GalleryAddBoldDuotone,\n\tlinear: GalleryAddLinear,\n})\nexport const GalleryWide = createIcon({\n\tbold: GalleryWideBoldWeight,\n\tboldDuotone: GalleryWideBoldDuotone,\n\tlinear: GalleryWideLinear,\n})\nexport const Global = createIcon({\n\tbold: GlobalBoldWeight,\n\tboldDuotone: GlobalBoldDuotone,\n\tlinear: GlobalLinear,\n})\nexport const GraphDown = createIcon({\n\tbold: GraphDownBoldWeight,\n\tboldDuotone: GraphDownBoldDuotone,\n\tlinear: GraphDownLinear,\n})\nexport const GraphUp = createIcon({\n\tbold: GraphUpBoldWeight,\n\tboldDuotone: GraphUpBoldDuotone,\n\tlinear: GraphUpLinear,\n})\nexport const HamburgerMenu = createIcon({\n\tbold: HamburgerMenuBoldWeight,\n\tboldDuotone: HamburgerMenuBoldDuotone,\n\tlinear: HamburgerMenuLinear,\n})\nexport const HandHeart = createIcon({\n\tbold: HandHeartBoldWeight,\n\tboldDuotone: HandHeartBoldDuotone,\n\tlinear: HandHeartLinear,\n})\nexport const Heart = createIcon({\n\tbold: HeartBoldWeight,\n\tboldDuotone: HeartBoldDuotone,\n\tlinear: HeartLinear,\n})\nexport const Help = createIcon({\n\tbold: HelpBoldWeight,\n\tboldDuotone: HelpBoldDuotone,\n\tlinear: HelpLinear,\n})\nexport const History = createIcon({\n\tbold: HistoryBoldWeight,\n\tboldDuotone: HistoryBoldDuotone,\n\tlinear: HistoryLinear,\n})\nexport const HomeAngle = createIcon({\n\tbold: HomeAngleBoldWeight,\n\tboldDuotone: HomeAngleBoldDuotone,\n\tlinear: HomeAngleLinear,\n})\nexport const InfoCircle = createIcon({\n\tbold: InfoCircleBoldWeight,\n\tboldDuotone: InfoCircleBoldDuotone,\n\tlinear: InfoCircleLinear,\n})\nexport const Layers = createIcon({\n\tbold: LayersBoldWeight,\n\tboldDuotone: LayersBoldDuotone,\n\tlinear: LayersLinear,\n})\nexport const Letter = createIcon({\n\tbold: LetterBoldWeight,\n\tboldDuotone: LetterBoldDuotone,\n\tlinear: LetterLinear,\n})\nexport const Like = createIcon({\n\tbold: LikeBoldWeight,\n\tboldDuotone: LikeBoldDuotone,\n\tlinear: LikeLinear,\n})\nexport const Link = createIcon({\n\tbold: LinkBoldWeight,\n\tboldDuotone: LinkBoldDuotone,\n\tlinear: LinkLinear,\n})\nexport const List = createIcon({\n\tbold: ListBoldWeight,\n\tboldDuotone: ListBoldDuotone,\n\tlinear: ListLinear,\n})\nexport const ListVertical = createIcon({\n\tbold: ListVerticalBoldWeight,\n\tboldDuotone: ListVerticalBoldDuotone,\n\tlinear: ListVerticalLinear,\n})\nexport const LockPassword = createIcon({\n\tbold: LockPasswordBoldWeight,\n\tboldDuotone: LockPasswordBoldDuotone,\n\tlinear: LockPasswordLinear,\n})\nexport const Login2 = createIcon({\n\tbold: Login2BoldWeight,\n\tboldDuotone: Login2BoldDuotone,\n\tlinear: Login2Linear,\n})\nexport const Logout = createIcon({\n\tbold: LogoutBoldWeight,\n\tboldDuotone: LogoutBoldDuotone,\n\tlinear: LogoutLinear,\n})\nexport const MagicWand2 = createIcon({\n\tbold: MagicWand2BoldWeight,\n\tboldDuotone: MagicWand2BoldDuotone,\n\tlinear: MagicWand2Linear,\n})\nexport const Magnifier = createIcon({\n\tbold: MagnifierBoldWeight,\n\tboldDuotone: MagnifierBoldDuotone,\n\tlinear: MagnifierLinear,\n})\nexport const MagnifierZoomIn = createIcon({\n\tbold: MagnifierZoomInBoldWeight,\n\tboldDuotone: MagnifierZoomInBoldDuotone,\n\tlinear: MagnifierZoomInLinear,\n})\nexport const MagnifierZoomOut = createIcon({\n\tbold: MagnifierZoomOutBoldWeight,\n\tboldDuotone: MagnifierZoomOutBoldDuotone,\n\tlinear: MagnifierZoomOutLinear,\n})\nexport const Maximize = createIcon({\n\tbold: MaximizeBoldWeight,\n\tboldDuotone: MaximizeBoldDuotone,\n\tlinear: MaximizeLinear,\n})\nexport const MenuDots = createIcon({\n\tbold: MenuDotsBoldWeight,\n\tboldDuotone: MenuDotsBoldDuotone,\n\tlinear: MenuDotsBoldWeight,\n})\nexport const Minimize = createIcon({\n\tbold: MinimizeBoldWeight,\n\tboldDuotone: MinimizeBoldDuotone,\n\tlinear: MinimizeLinear,\n})\nexport const MinusSquare = createIcon({\n\tbold: MinusSquareBoldWeight,\n\tboldDuotone: MinusSquareBoldDuotone,\n\tlinear: MinusSquareLinear,\n})\nexport const Monitor = createIcon({\n\tbold: MonitorBoldWeight,\n\tboldDuotone: MonitorBoldDuotone,\n\tlinear: MonitorLinear,\n})\nexport const MonitorSmartphone = createIcon({\n\tbold: MonitorSmartphoneBoldWeight,\n\tboldDuotone: MonitorSmartphoneBoldDuotone,\n\tlinear: MonitorSmartphoneLinear,\n})\nexport const Moon = createIcon({\n\tbold: MoonBoldWeight,\n\tboldDuotone: MoonBoldDuotone,\n\tlinear: MoonLinear,\n})\nexport const MoveToFolder = createIcon({\n\tbold: MoveToFolderBoldWeight,\n\tboldDuotone: MoveToFolderBoldDuotone,\n\tlinear: MoveToFolderLinear,\n})\nexport const MusicNotes = createIcon({\n\tbold: MusicNotesBoldWeight,\n\tboldDuotone: MusicNotesBoldDuotone,\n\tlinear: MusicNotesLinear,\n})\nexport const Palette = createIcon({\n\tbold: PaletteBoldWeight,\n\tboldDuotone: PaletteBoldDuotone,\n\tlinear: PaletteLinear,\n})\nexport const PaletteRound = createIcon({\n\tbold: PaletteRoundBoldWeight,\n\tboldDuotone: PaletteRoundBoldDuotone,\n\tlinear: PaletteRoundLinear,\n})\nexport const Pause = createIcon({\n\tbold: PauseBoldWeight,\n\tboldDuotone: PauseBoldDuotone,\n\tlinear: PauseLinear,\n})\nexport const Pen = createIcon({\n\tbold: PenBoldWeight,\n\tboldDuotone: PenBoldDuotone,\n\tlinear: PenLinear,\n})\nexport const PenNewRound = createIcon({\n\tbold: PenNewRoundBoldWeight,\n\tboldDuotone: PenNewRoundBoldDuotone,\n\tlinear: PenNewRoundLinear,\n})\nexport const PieChart = createIcon({\n\tbold: PieChartBoldWeight,\n\tboldDuotone: PieChartBoldDuotone,\n\tlinear: PieChartLinear,\n})\nexport const Pin = createIcon({\n\tbold: PinBoldWeight,\n\tboldDuotone: PinBoldDuotone,\n\tlinear: PinLinear,\n})\nexport const Play = createIcon({\n\tbold: PlayBoldWeight,\n\tboldDuotone: PlayBoldDuotone,\n\tlinear: PlayLinear,\n})\nexport const PlugCircle = createIcon({\n\tbold: PlugCircleBoldWeight,\n\tboldDuotone: PlugCircleBoldDuotone,\n\tlinear: PlugCircleLinear,\n})\nexport const PlusMinus = createIcon({\n\tbold: PlusMinusBoldWeight,\n\tboldDuotone: PlusMinusBoldDuotone,\n\tlinear: PlusMinusLinear,\n})\nexport const Pulse = createIcon({\n\tbold: PulseBoldWeight,\n\tboldDuotone: PulseBoldDuotone,\n\tlinear: PulseLinear,\n})\nexport const Refresh = createIcon({\n\tbold: RefreshBoldWeight,\n\tboldDuotone: RefreshBoldDuotone,\n\tlinear: RefreshLinear,\n})\nexport const RefreshCircle = createIcon({\n\tbold: RefreshCircleBoldWeight,\n\tboldDuotone: RefreshCircleBoldDuotone,\n\tlinear: RefreshCircleLinear,\n})\nexport const Reorder = createIcon({\n\tbold: ReorderBoldWeight,\n\tboldDuotone: ReorderBoldDuotone,\n\tlinear: ReorderLinear,\n})\nexport const Repeat = createIcon({\n\tbold: RepeatBoldWeight,\n\tboldDuotone: RepeatBoldDuotone,\n\tlinear: RepeatLinear,\n})\nexport const Reply = createIcon({\n\tbold: ReplyBoldWeight,\n\tboldDuotone: ReplyBoldDuotone,\n\tlinear: ReplyLinear,\n})\nexport const Restart = createIcon({\n\tbold: RestartBoldWeight,\n\tboldDuotone: RestartBoldDuotone,\n\tlinear: RestartLinear,\n})\nexport const Rocket = createIcon({\n\tbold: RocketBoldWeight,\n\tboldDuotone: RocketBoldDuotone,\n\tlinear: RocketLinear,\n})\nexport const Route = createIcon({\n\tbold: RouteBoldWeight,\n\tboldDuotone: RouteBoldDuotone,\n\tlinear: RouteLinear,\n})\nexport const Scale = createIcon({\n\tbold: ScaleBoldWeight,\n\tboldDuotone: ScaleBoldDuotone,\n\tlinear: ScaleLinear,\n})\nexport const Server = createIcon({\n\tbold: ServerBoldWeight,\n\tboldDuotone: ServerBoldDuotone,\n\tlinear: ServerLinear,\n})\nexport const Settings = createIcon({\n\tbold: SettingsBoldWeight,\n\tboldDuotone: SettingsBoldDuotone,\n\tlinear: SettingsLinear,\n})\nexport const Share = createIcon({\n\tbold: ShareBoldWeight,\n\tboldDuotone: ShareBoldDuotone,\n\tlinear: ShareLinear,\n})\nexport const ShieldCheck = createIcon({\n\tbold: ShieldCheckBoldWeight,\n\tboldDuotone: ShieldCheckBoldDuotone,\n\tlinear: ShieldCheckLinear,\n})\nexport const Shop2 = createIcon({\n\tbold: Shop2BoldWeight,\n\tboldDuotone: Shop2BoldDuotone,\n\tlinear: Shop2Linear,\n})\nexport const SidebarMinimalistic = createIcon({\n\tbold: SidebarMinimalisticBoldWeight,\n\tboldDuotone: SidebarMinimalisticBoldDuotone,\n\tlinear: SidebarMinimalisticLinear,\n})\nexport const SliderHorizontal = createIcon({\n\tbold: SliderHorizontalBoldWeight,\n\tboldDuotone: SliderHorizontalBoldDuotone,\n\tlinear: SliderHorizontalLinear,\n})\nexport const Smartphone = createIcon({\n\tbold: SmartphoneBoldWeight,\n\tboldDuotone: SmartphoneBoldDuotone,\n\tlinear: SmartphoneLinear,\n})\nexport const Sort = createIcon({\n\tbold: SortBoldWeight,\n\tboldDuotone: SortBoldDuotone,\n\tlinear: SortLinear,\n})\nexport const SortByTime = createIcon({\n\tbold: SortByTimeBoldWeight,\n\tboldDuotone: SortByTimeBoldDuotone,\n\tlinear: SortByTimeLinear,\n})\nexport const SortHorizontal = createIcon({\n\tbold: SortHorizontalBoldWeight,\n\tboldDuotone: SortHorizontalBoldDuotone,\n\tlinear: SortHorizontalLinear,\n})\nexport const SortVertical = createIcon({\n\tbold: SortVerticalBoldWeight,\n\tboldDuotone: SortVerticalBoldDuotone,\n\tlinear: SortVerticalLinear,\n})\nexport const Star = createIcon({\n\tbold: StarBoldWeight,\n\tboldDuotone: StarBoldDuotone,\n\tlinear: StarLinear,\n})\nexport const Structure = createIcon({\n\tbold: StructureBoldWeight,\n\tboldDuotone: StructureBoldDuotone,\n\tlinear: StructureLinear,\n})\nexport const Sun = createIcon({\n\tbold: SunBoldWeight,\n\tboldDuotone: SunBoldDuotone,\n\tlinear: SunLinear,\n})\nexport const Tag = createIcon({\n\tbold: TagBoldWeight,\n\tboldDuotone: TagBoldDuotone,\n\tlinear: TagLinear,\n})\nexport const Telescope = createIcon({\n\tbold: TelescopeBoldWeight,\n\tboldDuotone: TelescopeBoldDuotone,\n\tlinear: TelescopeLinear,\n})\nexport const TestTube = createIcon({\n\tbold: TestTubeBoldWeight,\n\tboldDuotone: TestTubeBoldDuotone,\n\tlinear: TestTubeLinear,\n})\nexport const TextFormat = createIcon({\n\tbold: TextFormatBoldWeight,\n\tboldDuotone: TextFormatBoldDuotone,\n\tlinear: TextFormatLinear,\n})\nexport const TransferHorizontal = createIcon({\n\tbold: TransferHorizontalBoldWeight,\n\tboldDuotone: TransferHorizontalBoldDuotone,\n\tlinear: TransferHorizontalLinear,\n})\nexport const Translation = createIcon({\n\tbold: TranslationBoldWeight,\n\tboldDuotone: TranslationBoldDuotone,\n\tlinear: TranslationLinear,\n})\nexport const TrashBinMinimalistic = createIcon({\n\tbold: TrashBinMinimalisticBoldWeight,\n\tboldDuotone: TrashBinMinimalisticBoldDuotone,\n\tlinear: TrashBinMinimalisticLinear,\n})\nexport const UndoLeft = createIcon({\n\tbold: UndoLeftBoldWeight,\n\tboldDuotone: UndoLeftBoldDuotone,\n\tlinear: UndoLeftLinear,\n})\nexport const UndoLeftRound = createIcon({\n\tbold: UndoLeftRoundBoldWeight,\n\tboldDuotone: UndoLeftRoundBoldDuotone,\n\tlinear: UndoLeftRoundLinear,\n})\nexport const UndoRight = createIcon({\n\tbold: UndoRightBoldWeight,\n\tboldDuotone: UndoRightBoldDuotone,\n\tlinear: UndoRightLinear,\n})\nexport const UndoRightRound = createIcon({\n\tbold: UndoRightRoundBoldWeight,\n\tboldDuotone: UndoRightRoundBoldDuotone,\n\tlinear: UndoRightRoundLinear,\n})\nexport const Upload = createIcon({\n\tbold: UploadBoldWeight,\n\tboldDuotone: UploadBoldDuotone,\n\tlinear: UploadLinear,\n})\nexport const User = createIcon({\n\tbold: UserBoldWeight,\n\tboldDuotone: UserBoldDuotone,\n\tlinear: UserLinear,\n})\nexport const UserId = createIcon({\n\tbold: UserIdBoldWeight,\n\tboldDuotone: UserIdBoldDuotone,\n\tlinear: UserIdLinear,\n})\nexport const UserMinus = createIcon({\n\tbold: UserMinusBoldWeight,\n\tboldDuotone: UserMinusBoldDuotone,\n\tlinear: UserMinusLinear,\n})\nexport const UserPlus = createIcon({\n\tbold: UserPlusBoldWeight,\n\tboldDuotone: UserPlusBoldDuotone,\n\tlinear: UserPlusLinear,\n})\nexport const UsersGroupRounded = createIcon({\n\tbold: UsersGroupRoundedBoldWeight,\n\tboldDuotone: UsersGroupRoundedBoldDuotone,\n\tlinear: UsersGroupRoundedLinear,\n})\nexport const UsersGroupTwoRounded = createIcon({\n\tbold: UsersGroupTwoRoundedBoldWeight,\n\tboldDuotone: UsersGroupTwoRoundedBoldDuotone,\n\tlinear: UsersGroupTwoRoundedLinear,\n})\nexport const VideoFrame = createIcon({\n\tbold: VideoFrameBoldWeight,\n\tboldDuotone: VideoFrameBoldDuotone,\n\tlinear: VideoFrameLinear,\n})\nexport const VideoFramePlayHorizontal = createIcon({\n\tbold: VideoFramePlayHorizontalBoldWeight,\n\tboldDuotone: VideoFramePlayHorizontalBoldDuotone,\n\tlinear: VideoFramePlayHorizontalLinear,\n})\nexport const Widget2 = createIcon({\n\tbold: Widget2BoldWeight,\n\tboldDuotone: Widget2BoldDuotone,\n\tlinear: Widget2Linear,\n})\nexport const Widget5 = createIcon({\n\tbold: Widget5BoldWeight,\n\tboldDuotone: Widget5BoldDuotone,\n\tlinear: Widget5Linear,\n})\nexport const WindowFrame = createIcon({\n\tbold: WindowFrameBoldWeight,\n\tboldDuotone: WindowFrameBoldDuotone,\n\tlinear: WindowFrameLinear,\n})\n","import { CheckCircle } from \"@hoardodile/ui/icons/registry\"\nimport { DangerTriangle } from \"@hoardodile/ui/icons/registry\"\nimport { ForbiddenCircle } from \"@hoardodile/ui/icons/registry\"\nimport { InfoCircle } from \"@hoardodile/ui/icons/registry\"\nimport * as React from \"react\"\nimport { Toast as ToastPrimitive } from \"@base-ui/react/toast\"\nimport { useTranslation } from \"react-i18next\"\n\nimport { cn } from \"@hoardodile/ui/lib/utils\"\nimport { Button } from \"@hoardodile/ui/components/button\"\nimport { Cross } from \"@hoardodile/ui/icons/marks\"\nimport { Spinner } from \"@hoardodile/ui/components/spinner\"\n\nconst toast = ToastPrimitive.createToastManager()\n\nfunction ToastProvider({ ...props }: ToastPrimitive.Provider.Props) {\n return <ToastPrimitive.Provider {...props} />\n}\n\nfunction ToastPortal({ ...props }: ToastPrimitive.Portal.Props) {\n return <ToastPrimitive.Portal data-slot=\"toast-portal\" {...props} />\n}\n\nfunction ToastViewport({ className, ...props }: ToastPrimitive.Viewport.Props) {\n return (\n <ToastPrimitive.Viewport\n data-slot=\"toast-viewport\"\n className={cn(\n \"pointer-events-none fixed inset-x-4 bottom-4 z-50 mx-auto w-auto max-w-sm outline-none sm:right-4 sm:left-auto sm:mx-0 sm:w-full\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction Toast({ className, ...props }: ToastPrimitive.Root.Props) {\n return (\n <ToastPrimitive.Root\n data-slot=\"toast\"\n className={cn(\n \"group/toast pointer-events-auto absolute right-0 bottom-0 z-[calc(1000-var(--toast-index))] w-full origin-bottom rounded-2xl border bg-popover text-popover-foreground shadow-lg will-change-transform outline-none select-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n \"[--gap:0.75rem] [--height:var(--toast-frontmost-height,var(--toast-height))] [--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))]\",\n \"h-(--height) [transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-(var(--toast-index)*var(--peek))-(var(--shrink)*var(--height))))_scale(var(--scale))] [transition:transform_500ms_cubic-bezier(0.22,1,0.36,1),opacity_500ms,height_150ms]\",\n \"after:absolute after:top-full after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']\",\n \"data-expanded:h-(--toast-height) data-expanded:[transform:translateX(var(--toast-swipe-movement-x))_translateY(var(--offset-y))]\",\n \"data-limited:opacity-0 data-starting-style:[transform:translateY(150%)]\",\n \"[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateY(150%)]\",\n \"data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]\",\n \"data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]\",\n \"data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]\",\n \"data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]\",\n \"data-expanded:data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]\",\n \"data-expanded:data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]\",\n \"data-expanded:data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]\",\n \"data-expanded:data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ToastContent({ className, ...props }: ToastPrimitive.Content.Props) {\n return (\n <ToastPrimitive.Content\n data-slot=\"toast-content\"\n className={cn(\n \"flex h-full items-center gap-3 overflow-hidden p-4 transition-opacity duration-250 ease-[cubic-bezier(0.22,1,0.36,1)] data-behind:opacity-0 data-expanded:opacity-100\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ToastTitle({ className, ...props }: ToastPrimitive.Title.Props) {\n return (\n <ToastPrimitive.Title\n data-slot=\"toast-title\"\n className={cn(\"text-sm font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction ToastDescription({\n className,\n ...props\n}: ToastPrimitive.Description.Props) {\n return (\n <ToastPrimitive.Description\n data-slot=\"toast-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction ToastAction({\n className,\n render = <Button variant=\"outline\" size=\"sm\" />,\n ...props\n}: ToastPrimitive.Action.Props) {\n return (\n <ToastPrimitive.Action\n data-slot=\"toast-action\"\n render={render}\n className={cn(\"shrink-0\", className)}\n {...props}\n />\n )\n}\n\nfunction ToastClose({\n className,\n children,\n render = <Button variant=\"ghost\" size=\"icon-sm\" />,\n ...props\n}: ToastPrimitive.Close.Props) {\n const { t } = useTranslation(\"ui\", { useSuspense: false })\n return (\n <ToastPrimitive.Close\n data-slot=\"toast-close\"\n aria-label={t(\"aria.closeToast\")}\n render={render}\n className={cn(\n \"relative shrink-0 text-muted-foreground after:absolute after:-inset-2 after:content-[''] hover:text-foreground\",\n className\n )}\n {...props}\n >\n {children ?? (\n <Cross aria-hidden=\"true\" />\n )}\n </ToastPrimitive.Close>\n )\n}\n\nfunction ToastIcon({ type }: { type: string | undefined }) {\n let icon: React.ReactNode = null\n\n if (type === \"success\") {\n icon = (\n <CheckCircle className=\"text-emerald-500\" aria-hidden=\"true\" />\n )\n }\n\n if (type === \"info\") {\n icon = (\n <InfoCircle aria-hidden=\"true\" />\n )\n }\n\n if (type === \"warning\") {\n icon = (\n <DangerTriangle className=\"text-amber-500\" aria-hidden=\"true\" />\n )\n }\n\n if (type === \"error\") {\n icon = (\n <ForbiddenCircle className=\"text-destructive\" aria-hidden=\"true\" />\n )\n }\n\n if (type === \"loading\") {\n icon = (\n <Spinner className=\"size-4\" aria-hidden=\"true\" />\n )\n }\n\n if (!icon) {\n return null\n }\n\n return (\n <span\n data-slot=\"toast-icon\"\n className=\"shrink-0 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\"\n >\n {icon}\n </span>\n )\n}\n\nfunction ToastList() {\n const { toasts } = ToastPrimitive.useToastManager()\n\n return toasts.map((toastItem) => (\n <Toast key={toastItem.id} toast={toastItem}>\n <ToastContent>\n <ToastIcon type={toastItem.type} />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <ToastTitle />\n <ToastDescription />\n </div>\n <ToastAction />\n <ToastClose />\n </ToastContent>\n </Toast>\n ))\n}\n\nfunction Toaster({\n children,\n toastManager = toast,\n ...props\n}: ToastPrimitive.Provider.Props) {\n return (\n <ToastProvider toastManager={toastManager} {...props}>\n {children}\n <ToastPortal>\n <ToastViewport>\n <ToastList />\n </ToastViewport>\n </ToastPortal>\n </ToastProvider>\n )\n}\n\nconst createToastManager = ToastPrimitive.createToastManager\nconst useToastManager = ToastPrimitive.useToastManager\n\nexport {\n Toaster,\n Toast,\n ToastAction,\n ToastClose,\n ToastContent,\n ToastDescription,\n ToastPortal,\n ToastProvider,\n ToastTitle,\n ToastViewport,\n createToastManager,\n toast,\n useToastManager,\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\nimport ReactCrop, { type Crop } from \"react-image-crop\"\nimport \"react-image-crop/dist/ReactCrop.css\"\n\n/**\n * Output of {@link ImageCropper} once the user releases the selection\n * box. Contains the cropped pixel data ready to upload (PNG by default)\n * plus its dimensions.\n */\nexport type CroppedImage = {\n\treadonly blob: Blob\n\treadonly width: number\n\treadonly height: number\n\treadonly mimeType: string\n}\n\nexport type ImageCropperProps = {\n\t/** The source image as a data URL or object URL. */\n\treadonly src: string\n\t/**\n\t * Optional fixed aspect ratio (width / height). When omitted, the\n\t * user can crop freely.\n\t */\n\treadonly aspect?: number\n\t/**\n\t * Output mime type. Defaults to `image/png`. PNG preserves quality;\n\t * JPEG produces smaller files for photographic content.\n\t */\n\treadonly mimeType?: \"image/png\" | \"image/jpeg\" | \"image/webp\"\n\t/** JPEG/WebP quality (0..1). Ignored for PNG. */\n\treadonly quality?: number\n\t/**\n\t * Called whenever the cropped pixel rectangle changes and is non-empty.\n\t * The callback receives a function that, when invoked, produces the\n\t * final {@link CroppedImage}. The render is deferred to avoid running\n\t * the canvas pipeline on every drag tick.\n\t */\n\treadonly onCropReady: (render: () => Promise<CroppedImage>) => void\n\t/**\n\t * Called synchronously with a PNG `data:` URL whenever the crop\n\t * selection changes. PNG preserves alpha for the live preview (JPEG\n\t * would flatten transparency to black). Unlike blob URLs, `data:`\n\t * URLs never appear in the browser network tab and setting them as\n\t * image `src` cannot cause an infinite re-render loop.\n\t */\n\treadonly onPreviewChange?: (dataUrl: string) => void\n\t/**\n\t * Max CSS width for the source image in the crop stage. When omitted the\n\t * image relies on `max-w-full` to fill the parent width.\n\t */\n\treadonly displayMaxWidth?: number | string\n\t/**\n\t * Max CSS height for the source image in the crop stage (e.g. `80vh` for\n\t * large canvas captures). Defaults to `70vh`.\n\t */\n\treadonly displayMaxHeight?: number | string\n}\n\n/**\n * Free-aspect (or fixed-aspect when {@link ImageCropperProps.aspect} is\n * provided) image cropper. Wraps `react-image-crop` and exposes a\n * deferred `render()` callback so callers can rasterise the selection on\n * demand (typically when the user clicks \"save\").\n */\nexport function ImageCropper(props: ImageCropperProps) {\n\tconst {\n\t\tsrc,\n\t\taspect,\n\t\tmimeType = \"image/png\",\n\t\tquality = 0.92,\n\t\tdisplayMaxWidth,\n\t\tdisplayMaxHeight = \"70vh\",\n\t} = props\n\n\tconst imgRef = useRef<HTMLImageElement | null>(null)\n\tconst [crop, setCrop] = useState<Crop | undefined>(undefined)\n\tconst [completed, setCompleted] = useState<Crop | undefined>(undefined)\n\n\tconst handleImageLoad = useCallback(\n\t\t(e: React.SyntheticEvent<HTMLImageElement>) => {\n\t\t\tconst { naturalWidth, naturalHeight } = e.currentTarget\n\t\t\tconst initial = buildInitialCrop(naturalWidth, naturalHeight, aspect)\n\t\t\tsetCrop(initial)\n\t\t\tsetCompleted(initial)\n\t\t},\n\t\t[aspect],\n\t)\n\n\tconst onCropReady = props.onCropReady\n\tconst onPreviewChange = props.onPreviewChange\n\n\tuseEffect(() => {\n\t\tconst img = imgRef.current\n\t\tif (img === null || completed === undefined || completed.width === 0) {\n\t\t\treturn\n\t\t}\n\t\tonCropReady(() => renderCroppedImage(img, completed, mimeType, quality))\n\t\tif (onPreviewChange !== undefined) {\n\t\t\tonPreviewChange(renderPreviewDataUrl(img, completed))\n\t\t}\n\t}, [completed, mimeType, quality, onCropReady, onPreviewChange])\n\n\treturn (\n\t\t<div className=\"react-crop-theme flex min-h-0 w-full max-w-full flex-col items-center gap-2 overflow-hidden\">\n\t\t\t<ReactCrop\n\t\t\t\tclassName=\"max-w-full\"\n\t\t\t\tcrop={crop}\n\t\t\t\tonChange={(_, percentCrop) => setCrop(percentCrop)}\n\t\t\t\tonComplete={(_, percentCrop) => setCompleted(percentCrop)}\n\t\t\t\taspect={aspect}\n\t\t\t\tkeepSelection\n\t\t\t\truleOfThirds\n\t\t\t>\n\t\t\t\t{/* biome-ignore lint/a11y/useAltText: cropper preview lacks user-supplied alt */}\n\t\t\t\t<img\n\t\t\t\t\tref={imgRef}\n\t\t\t\t\tsrc={src}\n\t\t\t\t\tonLoad={handleImageLoad}\n\t\t\t\t\tclassName=\"h-auto max-w-full\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tmaxWidth: displayMaxWidth,\n\t\t\t\t\t\tmaxHeight: displayMaxHeight,\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</ReactCrop>\n\t\t</div>\n\t)\n}\n\nfunction buildInitialCrop(\n\timgWidth: number,\n\timgHeight: number,\n\taspect: number | undefined,\n): Crop {\n\tif (aspect === undefined) {\n\t\treturn { unit: \"%\" as const, x: 0, y: 0, width: 100, height: 100 }\n\t}\n\n\tconst imgAspect = imgWidth / imgHeight\n\tlet widthPct: number\n\tlet heightPct: number\n\n\tif (imgAspect >= aspect) {\n\t\t// Image is wider (or equal) than the target aspect: fit to height,\n\t\t// crop the sides.\n\t\theightPct = 100\n\t\twidthPct = (100 * aspect) / imgAspect\n\t} else {\n\t\t// Image is taller than the target aspect: fit to width, crop top/bottom.\n\t\twidthPct = 100\n\t\theightPct = (100 * imgAspect) / aspect\n\t}\n\n\treturn {\n\t\tunit: \"%\" as const,\n\t\tx: (100 - widthPct) / 2,\n\t\ty: (100 - heightPct) / 2,\n\t\twidth: widthPct,\n\t\theight: heightPct,\n\t}\n}\n\nclass CroppedImageRenderError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message)\n\t\tthis.name = \"CroppedImageRenderError\"\n\t}\n}\n\n/**\n * @throws CroppedImageRenderError when the canvas context is unavailable\n * or the browser refuses to encode the selected blob.\n */\nasync function renderCroppedImage(\n\timage: HTMLImageElement,\n\tcrop: Crop,\n\tmimeType: string,\n\tquality: number,\n): Promise<CroppedImage> {\n\tconst sourceRect = cropToNaturalRect(image, crop)\n\n\tconst canvas = document.createElement(\"canvas\")\n\tcanvas.width = sourceRect.sw\n\tcanvas.height = sourceRect.sh\n\tconst ctx = canvas.getContext(\"2d\")\n\tif (ctx === null) {\n\t\tthrow new CroppedImageRenderError(\"2d context is unavailable\")\n\t}\n\tctx.imageSmoothingQuality = \"high\"\n\tctx.drawImage(\n\t\timage,\n\t\tsourceRect.sx,\n\t\tsourceRect.sy,\n\t\tsourceRect.sw,\n\t\tsourceRect.sh,\n\t\t0,\n\t\t0,\n\t\tsourceRect.sw,\n\t\tsourceRect.sh,\n\t)\n\n\tconst blob = await new Promise<Blob | null>((resolve) => {\n\t\tcanvas.toBlob(resolve, mimeType, quality)\n\t})\n\tif (blob === null) {\n\t\tthrow new CroppedImageRenderError(\"toBlob returned null\")\n\t}\n\treturn { blob, width: sourceRect.sw, height: sourceRect.sh, mimeType }\n}\n\n/**\n * Render the current crop to a PNG `data:` URL synchronously.\n *\n * Unlike {@link renderCroppedImage}, this function does NOT create a\n * `blob:` URL and therefore does not appear in the browser network tab.\n * Preview uses PNG (not JPEG) so transparent regions stay transparent.\n */\nfunction renderPreviewDataUrl(image: HTMLImageElement, crop: Crop): string {\n\tconst sourceRect = cropToNaturalRect(image, crop)\n\n\tconst canvas = document.createElement(\"canvas\")\n\tcanvas.width = sourceRect.sw\n\tcanvas.height = sourceRect.sh\n\tconst ctx = canvas.getContext(\"2d\", { alpha: true })\n\tif (ctx === null) return \"\"\n\tctx.imageSmoothingQuality = \"high\"\n\tctx.drawImage(\n\t\timage,\n\t\tsourceRect.sx,\n\t\tsourceRect.sy,\n\t\tsourceRect.sw,\n\t\tsourceRect.sh,\n\t\t0,\n\t\t0,\n\t\tsourceRect.sw,\n\t\tsourceRect.sh,\n\t)\n\treturn canvas.toDataURL(\"image/png\")\n}\n\nfunction cropToNaturalRect(\n\timage: HTMLImageElement,\n\tcrop: Crop,\n): { sx: number; sy: number; sw: number; sh: number } {\n\tconst naturalWidth = image.naturalWidth\n\tconst naturalHeight = image.naturalHeight\n\n\tif (crop.unit === \"px\") {\n\t\treturn {\n\t\t\tsx: crop.x,\n\t\t\tsy: crop.y,\n\t\t\tsw: Math.max(1, Math.round(crop.width)),\n\t\t\tsh: Math.max(1, Math.round(crop.height)),\n\t\t}\n\t}\n\n\tconst sx = (crop.x / 100) * naturalWidth\n\tconst sy = (crop.y / 100) * naturalHeight\n\tconst swRaw = (crop.width / 100) * naturalWidth\n\tconst shRaw = (crop.height / 100) * naturalHeight\n\tconst sw = Math.max(1, Math.round(swRaw))\n\tconst sh = Math.max(1, Math.round(shRaw))\n\n\treturn { sx, sy, sw, sh }\n}\n","import {\n\tDialogFooterActions,\n\tuseDialogFooterActions,\n} from \"@hoardodile/ui/components/app-dialog\"\nimport { Button } from \"@hoardodile/ui/components/button\"\nimport { Label } from \"@hoardodile/ui/components/label\"\nimport { Switch } from \"@hoardodile/ui/components/switch\"\nimport { toast } from \"@hoardodile/ui/components/toast\"\nimport { Gallery, RefreshCircle, Upload } from \"@hoardodile/ui/icons/registry\"\nimport { cn } from \"@hoardodile/ui/lib/utils\"\nimport { useCallback, useEffect, useId, useRef, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport type { CroppedImage } from \"./image-cropper\"\nimport { ImageCropper } from \"./image-cropper\"\n\nexport type ImageCropPanelProps = {\n\treadonly aspect?: number\n\treadonly mimeType?: \"image/png\" | \"image/jpeg\" | \"image/webp\"\n\treadonly accept?: string\n\treadonly previewShape?: \"square\" | \"circle\"\n\treadonly previewWidth?: number\n\treadonly previewHeight?: number\n\t/**\n\t * Called when the user clicks \"save\". Receives the cropped image\n\t * payload. Should return a promise that resolves once the upload is\n\t * complete; the panel then notifies via {@link onSaved}.\n\t *\n\t * @throws The implementation may throw to surface an error toast.\n\t */\n\treadonly onSave: (cropped: CroppedImage) => Promise<unknown>\n\treadonly onSaved?: () => void\n\t/**\n\t * Called when the user clicks the action button but no image has been\n\t * selected. The parent (e.g. {@link ImageEditPanel}) can treat this as a\n\t * request to remove the existing image.\n\t */\n\treadonly onClear?: () => void\n\t/**\n\t * When set (e.g. canvas snapshot object URL), skips the empty picker and\n\t * shows the cropper immediately.\n\t */\n\treadonly initialSrc?: string\n\t/**\n\t * When false, hides file pick / drag-drop and \"reselect\" (preset image only).\n\t */\n\treadonly allowChangeSource?: boolean\n\t/** Notifies parent when an async save starts / finishes (for dialog guards). */\n\treadonly onSavingChange?: (saving: boolean) => void\n\t/** Exact size (px) of the empty picker frame / crop stage. Overrides the default 240×240. */\n\treadonly cropStageWidth?: number\n\treadonly cropStageHeight?: number\n\t/**\n\t * When true, the right-hand live preview is hidden until the user turns\n\t * the switch on (saves work over large captures / WebGL snapshots).\n\t */\n\treadonly showPreviewSwitch?: boolean\n\t/**\n\t * When true, the live preview pane is never rendered — the crop stage is\n\t * the only surface. Used by creation forms whose panel column has no\n\t * room for a side-by-side preview.\n\t */\n\treadonly hidePreview?: boolean\n\t/**\n\t * When true, the crop stage fills its parent width and keeps the aspect\n\t * ratio implied by {@link cropStageWidth} / {@link cropStageHeight}\n\t * (full-bleed `aspect-square w-full` panels). Ignored when only\n\t * one stage dimension is given.\n\t */\n\treadonly fillWidth?: boolean\n\t/** Extra classes on the root panel wrapper. */\n\treadonly panelClassName?: string\n\t/** Extra classes on the row that holds the crop stage + preview. */\n\treadonly containerClassName?: string\n\t/** Extra classes on the column wrapping the crop stage (e.g. flex-1 min-w-0). */\n\treadonly cropColumnClassName?: string\n\t/** Extra classes on the bordered crop stage box (merged with defaults via tailwind-merge). */\n\treadonly cropStageClassName?: string\n\t/** When true, the bottom save/remove action button is hidden. */\n\treadonly hideActionButton?: boolean\n\t/**\n\t * When true, automatically calls {@link onSave} after the user finishes\n\t * adjusting the crop (debounced by 600 ms). Useful when the action button\n\t * is hidden and the parent only needs the final crop at form-submit time.\n\t */\n\treadonly autoSaveOnCrop?: boolean\n}\n\n/**\n * Inline image picker + cropper with live preview.\n */\nexport function ImageCropPanel(props: ImageCropPanelProps) {\n\tconst {\n\t\taspect,\n\t\tmimeType = \"image/png\",\n\t\taccept = \"image/*\",\n\t\tpreviewShape = \"square\",\n\t\tpreviewWidth: previewWidthProp,\n\t\tpreviewHeight: previewHeightProp,\n\t\tonSave,\n\t\tonSaved,\n\t\tonClear,\n\t\tinitialSrc,\n\t\tallowChangeSource = true,\n\t\tonSavingChange,\n\t\tcropStageWidth,\n\t\tcropStageHeight,\n\t\tshowPreviewSwitch = false,\n\t\thidePreview = false,\n\t\tfillWidth = false,\n\t\tpanelClassName,\n\t\tcontainerClassName,\n\t\tcropColumnClassName,\n\t\tcropStageClassName,\n\t\thideActionButton = false,\n\t\tautoSaveOnCrop = false,\n\t} = props\n\tconst { t } = useTranslation(\"ui\", { useSuspense: false })\n\tconst footerSlot = useDialogFooterActions()\n\tconst previewWidth = previewWidthProp ?? cropStageWidth ?? 200\n\tconst previewHeight = previewHeightProp ?? cropStageHeight ?? 200\n\tconst effectiveCropWidth = cropStageWidth ?? 320\n\tconst effectiveCropHeight = cropStageHeight ?? 240\n\t// Full-bleed stage: the aspect ratio of the requested stage dimensions,\n\t// stretched to whatever width the parent column gives us.\n\tconst stageAspectRatio =\n\t\tfillWidth && cropStageWidth !== undefined && cropStageHeight !== undefined\n\t\t\t? `${cropStageWidth} / ${cropStageHeight}`\n\t\t\t: undefined\n\tconst previewToggleId = useId()\n\tconst fileInputRef = useRef<HTMLInputElement | null>(null)\n\tconst [imageSrc, setImageSrc] = useState<string | undefined>(initialSrc)\n\tconst renderRef = useRef<(() => Promise<CroppedImage>) | undefined>(undefined)\n\tconst [previewDataUrl, setPreviewDataUrl] = useState<string | undefined>(\n\t\tundefined,\n\t)\n\tconst [previewPaneOn, setPreviewPaneOn] = useState(false)\n\tconst [dragOver, setDragOver] = useState(false)\n\tconst [saving, setSaving] = useState(false)\n\tconst previewVisible = !hidePreview && (!showPreviewSwitch || previewPaneOn)\n\tconst autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n\t\tundefined,\n\t)\n\tconst callbacksRef = useRef({ onSave, onSaved, onSavingChange, t })\n\tcallbacksRef.current = { onSave, onSaved, onSavingChange, t }\n\n\tuseEffect(\n\t\tfunction syncInitialSrc() {\n\t\t\tif (initialSrc !== undefined) setImageSrc(initialSrc)\n\t\t},\n\t\t[initialSrc],\n\t)\n\n\tconst handleCropReady = useCallback(\n\t\t(render: () => Promise<CroppedImage>) => {\n\t\t\trenderRef.current = render\n\t\t\tif (autoSaveOnCrop) {\n\t\t\t\tif (autoSaveTimerRef.current) {\n\t\t\t\t\tclearTimeout(autoSaveTimerRef.current)\n\t\t\t\t}\n\t\t\t\tautoSaveTimerRef.current = setTimeout(() => {\n\t\t\t\t\trender()\n\t\t\t\t\t\t.then(async (cropped) => {\n\t\t\t\t\t\t\tconst { onSave, onSaved, onSavingChange, t } =\n\t\t\t\t\t\t\t\tcallbacksRef.current\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tsetSaving(true)\n\t\t\t\t\t\t\t\tonSavingChange?.(true)\n\t\t\t\t\t\t\t\tawait onSave(cropped)\n\t\t\t\t\t\t\t\tonSaved?.()\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\tconst msg = err instanceof Error ? err.message : String(err)\n\t\t\t\t\t\t\t\ttoast.add({\n\t\t\t\t\t\t\t\t\ttitle: msg || t(\"imageCrop.saveFailed\"),\n\t\t\t\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\tsetSaving(false)\n\t\t\t\t\t\t\t\tonSavingChange?.(false)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\t\tconst { t } = callbacksRef.current\n\t\t\t\t\t\t\tconst msg = err instanceof Error ? err.message : String(err)\n\t\t\t\t\t\t\ttoast.add({\n\t\t\t\t\t\t\t\ttitle: msg || t(\"imageCrop.saveFailed\"),\n\t\t\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t}, 600)\n\t\t\t}\n\t\t},\n\t\t[autoSaveOnCrop],\n\t)\n\n\tconst handlePreviewChange = useCallback((dataUrl: string) => {\n\t\tsetPreviewDataUrl(dataUrl)\n\t}, [])\n\n\tfunction handlePreviewToggle(on: boolean) {\n\t\tsetPreviewPaneOn(on)\n\t\tif (!on) setPreviewDataUrl(undefined)\n\t}\n\n\tfunction handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {\n\t\tconst file = e.target.files?.[0]\n\t\tif (file === undefined) return\n\t\treadFileAsDataUrl(file)\n\t}\n\n\tfunction handleDrop(e: React.DragEvent<HTMLElement>) {\n\t\te.preventDefault()\n\t\tsetDragOver(false)\n\t\tconst file = e.dataTransfer.files?.[0]\n\t\tif (file !== undefined) readFileAsDataUrl(file)\n\t}\n\n\tfunction readFileAsDataUrl(file: File) {\n\t\tconst reader = new FileReader()\n\t\treader.addEventListener(\"load\", () => {\n\t\t\tconst result = reader.result\n\t\t\tif (typeof result === \"string\") setImageSrc(result)\n\t\t})\n\t\treader.readAsDataURL(file)\n\t}\n\n\tfunction handleReselect() {\n\t\tif (autoSaveTimerRef.current) {\n\t\t\tclearTimeout(autoSaveTimerRef.current)\n\t\t\tautoSaveTimerRef.current = undefined\n\t\t}\n\t\tsetImageSrc(undefined)\n\t\trenderRef.current = undefined\n\t\tsetPreviewDataUrl(undefined)\n\t\tsetPreviewPaneOn(false)\n\t\tfileInputRef.current?.click()\n\t}\n\n\tasync function handleSave() {\n\t\tconst render = renderRef.current\n\t\tif (render === undefined) {\n\t\t\tonClear?.()\n\t\t\treturn\n\t\t}\n\t\tsetSaving(true)\n\t\tonSavingChange?.(true)\n\t\ttry {\n\t\t\tconst cropped = await render()\n\t\t\tawait onSave(cropped)\n\t\t\tonSaved?.()\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err)\n\t\t\ttoast.add({\n\t\t\t\ttitle: msg || t(\"imageCrop.saveFailed\"),\n\t\t\t\ttype: \"error\",\n\t\t\t})\n\t\t} finally {\n\t\t\tsetSaving(false)\n\t\t\tonSavingChange?.(false)\n\t\t}\n\t}\n\n\tconst previewRadiusClass =\n\t\tpreviewShape === \"circle\" ? \"rounded-full\" : \"rounded\"\n\n\tconst actionButton = (\n\t\t<Button\n\t\t\ttype=\"button\"\n\t\t\tonClick={handleSave}\n\t\t\tdisabled={saving}\n\t\t\tdata-testid=\"image-crop-save\"\n\t\t>\n\t\t\t{saving\n\t\t\t\t? t(\"imageCrop.saving\")\n\t\t\t\t: imageSrc === undefined\n\t\t\t\t\t? t(\"imageCrop.remove\")\n\t\t\t\t\t: t(\"imageCrop.save\")}\n\t\t</Button>\n\t)\n\n\treturn (\n\t\t<div className={cn(\"flex flex-col gap-4\", panelClassName)}>\n\t\t\t{allowChangeSource ? (\n\t\t\t\t<input\n\t\t\t\t\tref={fileInputRef}\n\t\t\t\t\ttype=\"file\"\n\t\t\t\t\taccept={accept}\n\t\t\t\t\tclassName=\"hidden\"\n\t\t\t\t\tonChange={handleFileChange}\n\t\t\t\t\tdata-testid=\"image-crop-file-input\"\n\t\t\t\t/>\n\t\t\t) : null}\n\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex flex-col items-center gap-6 py-2 sm:flex-row sm:items-center sm:justify-center\",\n\t\t\t\t\tcontainerClassName,\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"flex flex-col items-center gap-2\",\n\t\t\t\t\t\tstageAspectRatio !== undefined && \"w-full\",\n\t\t\t\t\t\tcropColumnClassName,\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{imageSrc === undefined ? (\n\t\t\t\t\t\tallowChangeSource ? (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tonClick={() => fileInputRef.current?.click()}\n\t\t\t\t\t\t\t\tonDragOver={(e) => {\n\t\t\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\t\t\tsetDragOver(true)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tonDragLeave={() => setDragOver(false)}\n\t\t\t\t\t\t\t\tonDrop={handleDrop}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"flex select-none flex-col items-center justify-center gap-2 rounded-md border border-border bg-muted text-muted-foreground transition-colors duration-300 hover:bg-accent hover:text-accent-foreground\",\n\t\t\t\t\t\t\t\t\tdragOver && \"bg-accent text-accent-foreground\",\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined && \"w-full\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tdata-testid=\"image-crop-frame\"\n\t\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined\n\t\t\t\t\t\t\t\t\t\t? { aspectRatio: stageAspectRatio }\n\t\t\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t\t\twidth: cropStageWidth ?? 240,\n\t\t\t\t\t\t\t\t\t\t\t\theight: cropStageHeight ?? 240,\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Upload className=\"size-5\" />\n\t\t\t\t\t\t\t\t<p className=\"text-sm\">{t(\"imageCrop.pickHint\")}</p>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"flex items-center justify-center rounded-md border border-dashed border-border text-sm text-muted-foreground\",\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined && \"w-full\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined\n\t\t\t\t\t\t\t\t\t\t? { aspectRatio: stageAspectRatio }\n\t\t\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t\t\twidth: cropStageWidth ?? 240,\n\t\t\t\t\t\t\t\t\t\t\t\theight: cropStageHeight ?? 240,\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{t(\"imageCrop.pickHint\")}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"flex min-h-0 items-center justify-center overflow-hidden rounded-md border border-border bg-card\",\n\t\t\t\t\t\t\t\tstageAspectRatio === undefined && \"max-w-90\",\n\t\t\t\t\t\t\t\tcropStageClassName,\n\t\t\t\t\t\t\t\tstageAspectRatio !== undefined && \"w-full\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\tstageAspectRatio !== undefined\n\t\t\t\t\t\t\t\t\t? { aspectRatio: stageAspectRatio }\n\t\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t\tminHeight: `${cropStageHeight}px`,\n\t\t\t\t\t\t\t\t\t\t\tminWidth: `${cropStageWidth}px`,\n\t\t\t\t\t\t\t\t\t\t\twidth: effectiveCropWidth,\n\t\t\t\t\t\t\t\t\t\t\theight: effectiveCropHeight,\n\t\t\t\t\t\t\t\t\t\t\tmaxWidth: effectiveCropWidth,\n\t\t\t\t\t\t\t\t\t\t\tmaxHeight: effectiveCropHeight,\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<ImageCropper\n\t\t\t\t\t\t\t\tsrc={imageSrc}\n\t\t\t\t\t\t\t\taspect={aspect}\n\t\t\t\t\t\t\t\tmimeType={mimeType}\n\t\t\t\t\t\t\t\tdisplayMaxWidth={\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined ? \"100%\" : effectiveCropWidth\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tdisplayMaxHeight={\n\t\t\t\t\t\t\t\t\tstageAspectRatio !== undefined\n\t\t\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t\t\t: effectiveCropHeight\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tonCropReady={handleCropReady}\n\t\t\t\t\t\t\t\tonPreviewChange={\n\t\t\t\t\t\t\t\t\tpreviewVisible ? handlePreviewChange : undefined\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t\t{imageSrc !== undefined && allowChangeSource ? (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\tonClick={handleReselect}\n\t\t\t\t\t\t\tclassName=\"text-muted-foreground text-xs\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<RefreshCircle className=\"mr-1 h-3.5 w-3.5\" />\n\t\t\t\t\t\t\t{t(\"imageCrop.reselect\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\n\t\t\t\t{previewVisible ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<div className={cn(\"hidden w-px bg-border sm:block h-40\")} />\n\t\t\t\t\t\t<div className={cn(\"block bg-border sm:hidden h-px w-32\")} />\n\n\t\t\t\t\t\t<div className={cn(\"flex shrink-0 flex-col items-center gap-1.5\")}>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tstyle={{ width: previewWidth, height: previewHeight }}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"flex items-center justify-center overflow-hidden border border-border bg-muted text-muted-foreground\",\n\t\t\t\t\t\t\t\t\tpreviewRadiusClass,\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tdata-testid=\"image-crop-preview\"\n\t\t\t\t\t\t\t\ttitle={t(\"imageCrop.previewLabel\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{previewDataUrl !== undefined ? (\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tsrc={previewDataUrl}\n\t\t\t\t\t\t\t\t\t\talt={t(\"imageCrop.previewAlt\")}\n\t\t\t\t\t\t\t\t\t\tclassName=\"max-h-full max-w-full object-cover\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Gallery className=\"h-10 w-10 opacity-60\" />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t) : null}\n\t\t\t</div>\n\n\t\t\t{showPreviewSwitch && imageSrc !== undefined ? (\n\t\t\t\t<div className={cn(\"flex items-center justify-center gap-2\")}>\n\t\t\t\t\t<Switch\n\t\t\t\t\t\tid={previewToggleId}\n\t\t\t\t\t\tchecked={previewPaneOn}\n\t\t\t\t\t\tonCheckedChange={handlePreviewToggle}\n\t\t\t\t\t\tdata-testid=\"image-crop-preview-toggle\"\n\t\t\t\t\t/>\n\t\t\t\t\t<Label\n\t\t\t\t\t\thtmlFor={previewToggleId}\n\t\t\t\t\t\tclassName=\"text-muted-foreground cursor-pointer text-sm font-normal\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"imageCrop.showPreview\")}\n\t\t\t\t\t</Label>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{/* The save/remove action lands on the surrounding dialog's\n\t\t\t footer row — side by side with Cancel. Outside a dialog it\n\t\t\t falls back to an inline row at the panel's bottom. */}\n\t\t\t{!hideActionButton &&\n\t\t\t\t(footerSlot === null ? (\n\t\t\t\t\t<div className={cn(\"flex justify-end pt-2\")}>{actionButton}</div>\n\t\t\t\t) : (\n\t\t\t\t\t<DialogFooterActions>{actionButton}</DialogFooterActions>\n\t\t\t\t))}\n\t\t</div>\n\t)\n}\n"]}
|