@fastbackr/react 0.0.0-stage → 0.0.3

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.
@@ -0,0 +1,1615 @@
1
+ "use client";
2
+ import { rememberVisible } from "@fastbackr/core/boot";
3
+ import { createContext, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import { ApiClient, Layer, Selection, TokenSource, anchorBox, captureAnchor, captureScreenshot, consumeThreadLink, isCovered, isReflowed, pageContext, pathBreak, placeBox, plainKey, position, preloadScreenshot, regionBox, resolveAnchor, skeleton, threadLink, watchNavigation } from "@fastbackr/core";
6
+ import { createPortal } from "react-dom";
7
+ import { mergeProps } from "@base-ui/react/merge-props";
8
+ import { useRender } from "@base-ui/react/use-render";
9
+ import { cva } from "class-variance-authority";
10
+ import { cn } from "cn";
11
+ import { LIMITS, THREAD_STATUSES } from "@fastbackr/core/contract";
12
+ import { Button } from "@base-ui/react/button";
13
+ import { Input } from "@base-ui/react/input";
14
+ import { RiAddLine, RiArrowDownSLine, RiChat3Line, RiCheckLine, RiCloseLine, RiPencilLine } from "@remixicon/react";
15
+ import { Checkbox } from "@base-ui/react/checkbox";
16
+ import { Separator } from "@base-ui/react/separator";
17
+ //#region \0virtual:fastbackr-styles
18
+ var _virtual_fastbackr_styles_default = "/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (display:block){:host,:host{--shimmer-angle:20deg}*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:\"\";--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0;--scroll-fade-t:0px;--scroll-fade-b:0px;--scroll-fade-s:0px;--scroll-fade-e:0px;--scroll-fade-mask:initial;--shimmer-image:initial;--shimmer-text-fill:initial}}}@layer theme{:host,:host{--font-sans:var(--font-sans);--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-widest:.1em;--leading-snug:1.375;--leading-normal:1.5;--radius-xl:calc(var(--radius) * 1.4);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--blur-xs:4px;--perspective-normal:500px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Noto Sans\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab, var(--ring) 50%, transparent)}}body{background-color:var(--background);color:var(--foreground)}button:not(:disabled),[role=button]:not(:disabled){cursor:pointer}}@layer components;@layer utilities{.\\@container\\/card-header{container:card-header/inline-size}.\\@container\\/field-group{container:field-group/inline-size}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{inset-inline:0}.inset-y-0{inset-block:0}.top-1\\.5{top:calc(var(--spacing) * 1.5)}.top-1\\/2{top:50%}.top-2\\.5{top:calc(var(--spacing) * 2.5)}.top-3{top:calc(var(--spacing) * 3)}.top-3\\.5{top:calc(var(--spacing) * 3.5)}.top-4{top:calc(var(--spacing) * 4)}.right-0{right:0}.right-1{right:var(--spacing)}.right-2{right:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.right-4{right:calc(var(--spacing) * 4)}.right-full{right:100%}.bottom-0{bottom:0}.bottom-4{bottom:calc(var(--spacing) * 4)}.bottom-22{bottom:calc(var(--spacing) * 22)}.bottom-\\[calc\\(100\\%\\+6px\\)\\]{bottom:calc(100% + 6px)}.left-1\\/2{left:50%}.isolate{isolation:isolate}.-z-1{z-index:calc(1 * -1)}.-z-10{z-index:calc(10 * -1)}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.col-start-2{grid-column-start:2}.row-span-2{grid-row:span 2/span 2}.row-start-1{grid-row-start:1}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-3\\.5{margin-inline:calc(var(--spacing) * 3.5)}.mx-auto{margin-inline:auto}.-my-2{margin-block:calc(var(--spacing) * -2)}.my-1{margin-block:var(--spacing)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-auto{margin-top:auto}.-mr-1{margin-right:calc(var(--spacing) * -1)}.-mr-1\\.5{margin-right:calc(var(--spacing) * -1.5)}.mr-1\\.5{margin-right:calc(var(--spacing) * 1.5)}.mb-1\\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.no-scrollbar::-webkit-scrollbar{display:none}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-row{display:table-row}.field-sizing-content{field-sizing:content}.aspect-square{aspect-ratio:1}.size-2\\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-3\\!{width:calc(var(--spacing) * 3)!important;height:calc(var(--spacing) * 3)!important}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.size-16{width:calc(var(--spacing) * 16);height:calc(var(--spacing) * 16)}.size-full{width:100%;height:100%}.h-\\(--accordion-panel-height\\){height:var(--accordion-panel-height)}.h-2\\.5{height:calc(var(--spacing) * 2.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-\\[calc\\(100\\%-1px\\)\\]{height:calc(100% - 1px)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-svh{height:100svh}.max-h-\\(--available-height\\){max-height:var(--available-height)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-\\[calc\\(100vh-110px\\)\\]{max-height:calc(100vh - 110px)}.min-h-0{min-height:0}.min-h-16{min-height:calc(var(--spacing) * 16)}.min-h-24{min-height:calc(var(--spacing) * 24)}.min-h-28{min-height:calc(var(--spacing) * 28)}.min-h-svh{min-height:100svh}.w-\\(--anchor-width\\){width:var(--anchor-width)}.w-\\(--sidebar-width\\){width:var(--sidebar-width)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-36{width:calc(var(--spacing) * 36)}.w-48{width:calc(var(--spacing) * 48)}.w-\\[350px\\]{width:350px}.w-\\[420px\\]{width:420px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.max-w-\\(--skeleton-width\\){max-width:var(--skeleton-width)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-\\[440px\\]{max-width:440px}.max-w-\\[calc\\(100\\%-2rem\\)\\]{max-width:calc(100% - 2rem)}.max-w-\\[calc\\(100vw-2rem\\)\\]{max-width:calc(100vw - 2rem)}.max-w-\\[calc\\(100vw-24px\\)\\]{max-width:calc(100vw - 24px)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-5{min-width:calc(var(--spacing) * 5)}.min-w-7{min-width:calc(var(--spacing) * 7)}.min-w-8{min-width:calc(var(--spacing) * 8)}.min-w-9{min-width:calc(var(--spacing) * 9)}.min-w-10{min-width:calc(var(--spacing) * 10)}.min-w-36{min-width:calc(var(--spacing) * 36)}.min-w-48{min-width:calc(var(--spacing) * 48)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.caption-bottom{caption-side:bottom}.origin-\\(--transform-origin\\){transform-origin:var(--transform-origin)}.-translate-x-1\\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-px{--tw-translate-x:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-px{--tw-translate-x:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\\[calc\\(-50\\%-2px\\)\\]{--tw-translate-y:calc(-50% - 2px);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-45{rotate:45deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-fade-in{animation:.6s ease-in both fade-in}.animate-fade-in-left{animation:.6s ease-in-out both fade-in-left}.animate-fade-out{animation:.6s ease-out both fade-out}.animate-fade-out-right{animation:.6s ease-out both fade-out-right}.animate-flip-in-x{animation:.6s ease-out both flip-in-x}.animate-pulse{animation:2s cubic-bezier(.4,0,.6,1) infinite pulse}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.list-disc{list-style-type:disc}.auto-rows-min{grid-auto-rows:min-content}.grid-rows-\\[auto_1fr\\]{grid-template-rows:auto 1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.place-content-center{place-content:center}.place-items-center{place-items:center}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-\\(--card-spacing\\){gap:var(--card-spacing)}.gap-0{gap:0}.gap-0\\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-7{gap:calc(var(--spacing) * 7)}.gap-\\[--spacing\\(var\\(--gap\\)\\)\\]{gap:calc(var(--spacing) * var(--gap))}:where(.-space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * -2) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * -2) * calc(1 - var(--tw-space-x-reverse)))}.self-start{align-self:flex-start}.justify-self-end{justify-self:flex-end}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded-2xl{border-radius:calc(var(--radius) * 1.8)}.rounded-4xl{border-radius:calc(var(--radius) * 2.6)}.rounded-\\[2px\\]{border-radius:2px}.rounded-\\[6px\\]{border-radius:6px}.rounded-\\[14px_14px_14px_3px\\]{border-radius:14px 14px 14px 3px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) * .8)}.rounded-xl{border-radius:calc(var(--radius) * 1.4)}.rounded-t-xl{border-top-left-radius:calc(var(--radius) * 1.4);border-top-right-radius:calc(var(--radius) * 1.4)}.rounded-b-xl{border-bottom-right-radius:calc(var(--radius) * 1.4);border-bottom-left-radius:calc(var(--radius) * 1.4)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-background{border-color:var(--background)}.border-border{border-color:var(--border)}.border-input{border-color:var(--input)}.border-sidebar-border{border-color:var(--sidebar-border)}.border-transparent{border-color:#0000}.bg-background{background-color:var(--background)}.bg-black\\/80{background-color:#000c}@supports (color:color-mix(in lab, red, red)){.bg-black\\/80{background-color:color-mix(in oklab, var(--color-black) 80%, transparent)}}.bg-border,.bg-border\\/50{background-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.bg-border\\/50{background-color:color-mix(in oklab, var(--border) 50%, transparent)}}.bg-card{background-color:var(--card)}.bg-destructive,.bg-destructive\\/10{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\\/10{background-color:color-mix(in oklab, var(--destructive) 10%, transparent)}}.bg-foreground{background-color:var(--foreground)}.bg-input\\/30{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.bg-input\\/30{background-color:color-mix(in oklab, var(--input) 30%, transparent)}}.bg-muted,.bg-muted\\/50{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\\/50{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.bg-popover{background-color:var(--popover)}.bg-primary,.bg-primary\\/15{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.bg-primary\\/15{background-color:color-mix(in oklab, var(--primary) 15%, transparent)}}.bg-secondary{background-color:var(--secondary)}.bg-sidebar{background-color:var(--sidebar)}.bg-sidebar-border{background-color:var(--sidebar-border)}.bg-transparent{background-color:#0000}.bg-clip-padding{background-clip:padding-box}.fill-foreground{fill:var(--foreground)}.object-cover{object-fit:cover}.object-top{object-position:top}.p-0{padding:0}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-\\[3px\\]{padding:3px}.px-\\(--card-spacing\\){padding-inline:var(--card-spacing)}.px-1{padding-inline:var(--spacing)}.px-1\\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-\\(--card-spacing\\){padding-block:var(--card-spacing)}.py-0{padding-block:0}.py-0\\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-8{padding-block:calc(var(--spacing) * 8)}.pt-0{padding-top:0}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pl-1\\.5{padding-left:calc(var(--spacing) * 1.5)}.pl-3{padding-left:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-heading,.font-sans{font-family:var(--font-sans)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[10px\\]{font-size:10px}.text-\\[11px\\]{font-size:11px}.leading-none{--tw-leading:1;line-height:1}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.text-balance{text-wrap:balance}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-background{color:var(--background)}.text-card-foreground{color:var(--card-foreground)}.text-current{color:currentColor}.text-destructive{color:var(--destructive)}.text-foreground,.text-foreground\\/60{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\\/60{color:color-mix(in oklab, var(--foreground) 60%, transparent)}}.text-link{color:var(--link)}.text-muted-foreground{color:var(--muted-foreground)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-sidebar-foreground,.text-sidebar-foreground\\/70{color:var(--sidebar-foreground)}@supports (color:color-mix(in lab, red, red)){.text-sidebar-foreground\\/70{color:color-mix(in oklab, var(--sidebar-foreground) 70%, transparent)}}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline-offset-4{text-underline-offset:4px}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.bg-blend-color{background-blend-mode:color}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\\[0_0_0_1px_var\\(--sidebar-border\\)\\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--sidebar-border));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-background{--tw-ring-color:var(--background)}.ring-foreground\\/5{--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.ring-foreground\\/5{--tw-ring-color:color-mix(in oklab, var(--foreground) 5%, transparent)}}.ring-foreground\\/10{--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.ring-foreground\\/10{--tw-ring-color:color-mix(in oklab, var(--foreground) 10%, transparent)}}.ring-sidebar-ring{--tw-ring-color:var(--sidebar-ring)}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.outline-2{outline-style:var(--tw-outline-style);outline-width:2px}.outline-offset-2{outline-offset:2px}.outline-primary{outline-color:var(--primary)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[left\\,right\\,width\\]{transition-property:left,right,width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[margin\\,opacity\\]{transition-property:margin,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[width\\,height\\,padding\\]{transition-property:width,height,padding;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[width\\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-none{transition-property:none}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-linear{--tw-ease:linear;transition-timing-function:linear}.animate-delay-250{animation-delay:.25s}.animate-duration-150{animation-duration:.15s}.animate-duration-250{animation-duration:.25s}.animate-duration-300{animation-duration:.3s}.outline-dashed{--tw-outline-style:dashed;outline-style:dashed}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\\[--card-spacing\\:--spacing\\(6\\)\\]{--card-spacing:calc(var(--spacing) * 6)}.\\[--radius\\:var\\(--radius-xl\\)\\]{--radius:var(--radius-xl)}.perspective-normal{perspective:var(--perspective-normal)}:is(.\\*\\:pointer-events-auto>*){pointer-events:auto}:is(.\\*\\:w-full>*){width:100%}.not-last\\:border-b:not(:last-child){border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.group-focus-within\\/menu-item\\:opacity-100:is(:where(.group\\/menu-item):focus-within *){opacity:1}@media (hover:hover){.group-hover\\/menu-item\\:opacity-100:is(:where(.group\\/menu-item):hover *){opacity:1}}.group-focus\\/dropdown-menu-item\\:text-accent-foreground:is(:where(.group\\/dropdown-menu-item):focus *){color:var(--accent-foreground)}.group-has-disabled\\/field\\:opacity-50:is(:where(.group\\/field):has(:disabled) *){opacity:.5}.group-has-data-\\[sidebar\\=menu-action\\]\\/menu-item\\:pr-8:is(:where(.group\\/menu-item):has([data-sidebar=menu-action]) *){padding-right:calc(var(--spacing) * 8)}.group-has-data-\\[size\\=lg\\]\\/avatar-group\\:size-10:is(:where(.group\\/avatar-group):has([data-size=lg]) *){width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.group-has-data-\\[size\\=sm\\]\\/avatar-group\\:size-6:is(:where(.group\\/avatar-group):has([data-size=sm]) *){width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.group-has-data-horizontal\\/field\\:text-balance:is(:where(.group\\/field):has(:where([data-orientation=horizontal])) *){text-wrap:balance}.group-has-\\[\\:focus-visible\\]\\/field-label\\:ring-0:is(:where(.group\\/field-label):has(:focus-visible) *){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.group-has-\\[\\:focus-visible\\]\\/field-label\\:not-data-checked\\:border-input:is(:where(.group\\/field-label):has(:focus-visible) *):not(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){border-color:var(--input)}.group-has-\\[\\>svg\\]\\/alert\\:col-start-2:is(:where(.group\\/alert):has(>svg) *){grid-column-start:2}.group-aria-expanded\\/accordion-trigger\\:hidden:is(:where(.group\\/accordion-trigger)[aria-expanded=true] *){display:none}.group-aria-expanded\\/accordion-trigger\\:inline:is(:where(.group\\/accordion-trigger)[aria-expanded=true] *){display:inline}.group-data-\\[collapsible\\=icon\\]\\:-mt-8:is(:where(.group)[data-collapsible=icon] *){margin-top:calc(var(--spacing) * -8)}.group-data-\\[collapsible\\=icon\\]\\:hidden:is(:where(.group)[data-collapsible=icon] *){display:none}.group-data-\\[collapsible\\=icon\\]\\:size-8\\!:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--spacing) * 8)!important;height:calc(var(--spacing) * 8)!important}.group-data-\\[collapsible\\=icon\\]\\:w-\\(--sidebar-width-icon\\):is(:where(.group)[data-collapsible=icon] *){width:var(--sidebar-width-icon)}.group-data-\\[collapsible\\=icon\\]\\:w-\\[calc\\(var\\(--sidebar-width-icon\\)\\+\\(--spacing\\(4\\)\\)\\)\\]:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)))}.group-data-\\[collapsible\\=icon\\]\\:w-\\[calc\\(var\\(--sidebar-width-icon\\)\\+\\(--spacing\\(4\\)\\)\\+2px\\)\\]:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)) + 2px)}.group-data-\\[collapsible\\=icon\\]\\:overflow-hidden:is(:where(.group)[data-collapsible=icon] *){overflow:hidden}.group-data-\\[collapsible\\=icon\\]\\:p-0\\!:is(:where(.group)[data-collapsible=icon] *){padding:0!important}.group-data-\\[collapsible\\=icon\\]\\:p-2\\!:is(:where(.group)[data-collapsible=icon] *){padding:calc(var(--spacing) * 2)!important}.group-data-\\[collapsible\\=icon\\]\\:opacity-0:is(:where(.group)[data-collapsible=icon] *){opacity:0}.group-data-\\[collapsible\\=offcanvas\\]\\:w-0:is(:where(.group)[data-collapsible=offcanvas] *){width:0}.group-data-\\[collapsible\\=offcanvas\\]\\:translate-x-0:is(:where(.group)[data-collapsible=offcanvas] *){--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}.group-data-\\[disabled\\=true\\]\\:pointer-events-none:is(:where(.group)[data-disabled=true] *){pointer-events:none}.group-data-\\[disabled\\=true\\]\\:opacity-50:is(:where(.group)[data-disabled=true] *),.group-data-\\[disabled\\=true\\]\\/field\\:opacity-50:is(:where(.group\\/field)[data-disabled=true] *){opacity:.5}.group-data-\\[side\\=left\\]\\:-right-4:is(:where(.group)[data-side=left] *){right:calc(var(--spacing) * -4)}.group-data-\\[side\\=left\\]\\:border-r:is(:where(.group)[data-side=left] *){border-right-style:var(--tw-border-style);border-right-width:1px}.group-data-\\[side\\=right\\]\\:left-0:is(:where(.group)[data-side=right] *){left:0}.group-data-\\[side\\=right\\]\\:rotate-180:is(:where(.group)[data-side=right] *){rotate:180deg}.group-data-\\[side\\=right\\]\\:border-l:is(:where(.group)[data-side=right] *){border-left-style:var(--tw-border-style);border-left-width:1px}.group-data-\\[size\\=default\\]\\/avatar\\:size-2\\.5:is(:where(.group\\/avatar)[data-size=default] *){width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.group-data-\\[size\\=lg\\]\\/avatar\\:size-3:is(:where(.group\\/avatar)[data-size=lg] *){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.group-data-\\[size\\=sm\\]\\/alert-dialog-content\\:grid:is(:where(.group\\/alert-dialog-content)[data-size=sm] *){display:grid}.group-data-\\[size\\=sm\\]\\/alert-dialog-content\\:grid-cols-2:is(:where(.group\\/alert-dialog-content)[data-size=sm] *){grid-template-columns:repeat(2,minmax(0,1fr))}.group-data-\\[size\\=sm\\]\\/avatar\\:size-2:is(:where(.group\\/avatar)[data-size=sm] *){width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.group-data-\\[size\\=sm\\]\\/avatar\\:text-xs:is(:where(.group\\/avatar)[data-size=sm] *){font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.group-data-\\[spacing\\=0\\]\\/toggle-group\\:rounded-none:is(:where(.group\\/toggle-group)[data-spacing=\"0\"] *){border-radius:0}.group-data-\\[spacing\\=0\\]\\/toggle-group\\:px-3:is(:where(.group\\/toggle-group)[data-spacing=\"0\"] *){padding-inline:calc(var(--spacing) * 3)}.group-data-\\[spacing\\=0\\]\\/toggle-group\\:shadow-none:is(:where(.group\\/toggle-group)[data-spacing=\"0\"] *){--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.group-data-\\[variant\\=floating\\]\\:rounded-lg:is(:where(.group)[data-variant=floating] *){border-radius:var(--radius)}.group-data-\\[variant\\=floating\\]\\:shadow-sm:is(:where(.group)[data-variant=floating] *){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.group-data-\\[variant\\=floating\\]\\:ring-1:is(:where(.group)[data-variant=floating] *){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.group-data-\\[variant\\=floating\\]\\:ring-sidebar-border:is(:where(.group)[data-variant=floating] *){--tw-ring-color:var(--sidebar-border)}.group-data-\\[variant\\=line\\]\\/tabs-list\\:bg-transparent:is(:where(.group\\/tabs-list)[data-variant=line] *){background-color:#0000}.group-data-\\[variant\\=outline\\]\\/field-group\\:-mb-2:is(:where(.group\\/field-group)[data-variant=outline] *){margin-bottom:calc(var(--spacing) * -2)}.group-data-horizontal\\/tabs\\:h-9:is(:where(.group\\/tabs):where([data-orientation=horizontal]) *){height:calc(var(--spacing) * 9)}.group-data-vertical\\/tabs\\:h-fit:is(:where(.group\\/tabs):where([data-orientation=vertical]) *){height:fit-content}.group-data-vertical\\/tabs\\:w-full:is(:where(.group\\/tabs):where([data-orientation=vertical]) *){width:100%}.group-data-vertical\\/tabs\\:flex-col:is(:where(.group\\/tabs):where([data-orientation=vertical]) *){flex-direction:column}.group-data-vertical\\/tabs\\:justify-start:is(:where(.group\\/tabs):where([data-orientation=vertical]) *){justify-content:flex-start}.group-data-vertical\\/tabs\\:rounded-2xl:is(:where(.group\\/tabs):where([data-orientation=vertical]) *){border-radius:calc(var(--radius) * 1.8)}.group-data-vertical\\/tabs\\:px-2\\.5:is(:where(.group\\/tabs):where([data-orientation=vertical]) *){padding-inline:calc(var(--spacing) * 2.5)}.group-data-vertical\\/tabs\\:py-1\\.5:is(:where(.group\\/tabs):where([data-orientation=vertical]) *){padding-block:calc(var(--spacing) * 1.5)}@media (hover:hover){.peer-hover\\/menu-button\\:text-sidebar-accent-foreground:is(:where(.peer\\/menu-button):hover~*){color:var(--sidebar-accent-foreground)}}.peer-disabled\\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\\:opacity-50:is(:where(.peer):disabled~*){opacity:.5}.peer-data-\\[size\\=default\\]\\/menu-button\\:top-1\\.5:is(:where(.peer\\/menu-button)[data-size=default]~*){top:calc(var(--spacing) * 1.5)}.peer-data-\\[size\\=default\\]\\/menu-button\\:top-2:is(:where(.peer\\/menu-button)[data-size=default]~*){top:calc(var(--spacing) * 2)}.peer-data-\\[size\\=lg\\]\\/menu-button\\:top-2\\.5:is(:where(.peer\\/menu-button)[data-size=lg]~*){top:calc(var(--spacing) * 2.5)}.peer-data-\\[size\\=sm\\]\\/menu-button\\:top-1:is(:where(.peer\\/menu-button)[data-size=sm]~*){top:var(--spacing)}.peer-data-active\\/menu-button\\:text-sidebar-accent-foreground:is(:is(:where(.peer\\/menu-button):where([data-state=active]),:where(.peer\\/menu-button):where([data-active]:not([data-active=false])))~*){color:var(--sidebar-accent-foreground)}.file\\:inline-flex::file-selector-button{display:inline-flex}.file\\:h-7::file-selector-button{height:calc(var(--spacing) * 7)}.file\\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\\:bg-transparent::file-selector-button{background-color:#0000}.file\\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.after\\:absolute:after{content:var(--tw-content);position:absolute}.after\\:-inset-2:after{content:var(--tw-content);inset:calc(var(--spacing) * -2)}.after\\:inset-0:after{content:var(--tw-content);inset:0}.after\\:-inset-x-3:after{content:var(--tw-content);inset-inline:calc(var(--spacing) * -3)}.after\\:-inset-y-2:after{content:var(--tw-content);inset-block:calc(var(--spacing) * -2)}.after\\:inset-y-0:after{content:var(--tw-content);inset-block:0}.after\\:start-1\\/2:after{content:var(--tw-content);inset-inline-start:50%}.after\\:w-\\[2px\\]:after{content:var(--tw-content);width:2px}.after\\:rounded-full:after{content:var(--tw-content);border-radius:3.40282e38px}.after\\:border:after{content:var(--tw-content);border-style:var(--tw-border-style);border-width:1px}.after\\:border-border:after{content:var(--tw-content);border-color:var(--border)}.after\\:bg-foreground:after{content:var(--tw-content);background-color:var(--foreground)}.after\\:opacity-0:after{content:var(--tw-content);opacity:0}.after\\:mix-blend-darken:after{content:var(--tw-content);mix-blend-mode:darken}.after\\:transition-opacity:after{content:var(--tw-content);transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.group-data-\\[collapsible\\=offcanvas\\]\\:after\\:left-full:is(:where(.group)[data-collapsible=offcanvas] *):after{content:var(--tw-content);left:100%}.group-data-horizontal\\/tabs\\:after\\:inset-x-0:is(:where(.group\\/tabs):where([data-orientation=horizontal]) *):after{content:var(--tw-content);inset-inline:0}.group-data-horizontal\\/tabs\\:after\\:bottom-\\[-5px\\]:is(:where(.group\\/tabs):where([data-orientation=horizontal]) *):after{content:var(--tw-content);bottom:-5px}.group-data-horizontal\\/tabs\\:after\\:h-0\\.5:is(:where(.group\\/tabs):where([data-orientation=horizontal]) *):after{content:var(--tw-content);height:calc(var(--spacing) * .5)}.group-data-vertical\\/tabs\\:after\\:inset-y-0:is(:where(.group\\/tabs):where([data-orientation=vertical]) *):after{content:var(--tw-content);inset-block:0}.group-data-vertical\\/tabs\\:after\\:-right-1:is(:where(.group\\/tabs):where([data-orientation=vertical]) *):after{content:var(--tw-content);right:calc(var(--spacing) * -1)}.group-data-vertical\\/tabs\\:after\\:w-0\\.5:is(:where(.group\\/tabs):where([data-orientation=vertical]) *):after{content:var(--tw-content);width:calc(var(--spacing) * .5)}.last\\:mt-0:last-child{margin-top:0}@media (hover:hover){.hover\\:bg-\\[color-mix\\(in_oklch\\,var\\(--secondary\\)\\,var\\(--foreground\\)_5\\%\\)\\]:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-\\[color-mix\\(in_oklch\\,var\\(--secondary\\)\\,var\\(--foreground\\)_5\\%\\)\\]:hover{background-color:color-mix(in oklch,var(--secondary),var(--foreground) 5%)}}.hover\\:bg-destructive\\/20:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-destructive\\/20:hover{background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.hover\\:bg-input\\/50:hover{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-input\\/50:hover{background-color:color-mix(in oklab, var(--input) 50%, transparent)}}.hover\\:bg-muted:hover,.hover\\:bg-muted\\/50:hover{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/50:hover{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.hover\\:bg-primary\\/80:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-primary\\/80:hover{background-color:color-mix(in oklab, var(--primary) 80%, transparent)}}.hover\\:bg-sidebar-accent:hover{background-color:var(--sidebar-accent)}.hover\\:text-foreground:hover{color:var(--foreground)}.hover\\:text-muted-foreground:hover{color:var(--muted-foreground)}.hover\\:text-sidebar-accent-foreground:hover{color:var(--sidebar-accent-foreground)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:shadow-\\[0_0_0_1px_var\\(--sidebar-accent\\)\\]:hover{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--sidebar-accent));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hover\\:group-data-\\[collapsible\\=offcanvas\\]\\:bg-sidebar:hover:is(:where(.group)[data-collapsible=offcanvas] *){background-color:var(--sidebar)}.hover\\:after\\:bg-sidebar-border:hover:after{content:var(--tw-content);background-color:var(--sidebar-border)}}.focus\\:z-10:focus{z-index:10}.focus\\:bg-accent:focus{background-color:var(--accent)}.focus\\:text-accent-foreground:focus,:is(.focus\\:\\*\\*\\:text-accent-foreground:focus *),:is(.not-data-\\[variant\\=destructive\\]\\:focus\\:\\*\\*\\:text-accent-foreground:not([data-variant=destructive]):focus *){color:var(--accent-foreground)}.focus-visible\\:z-10:focus-visible{z-index:10}.focus-visible\\:border-destructive\\/40:focus-visible{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.focus-visible\\:border-destructive\\/40:focus-visible{border-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.focus-visible\\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\\:ring-\\[3px\\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\\:ring-destructive\\/20:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.focus-visible\\:ring-destructive\\/20:focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.focus-visible\\:ring-ring\\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\\:ring-ring\\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.focus-visible\\:outline-1:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\\:outline-ring:focus-visible{outline-color:var(--ring)}.active\\:bg-sidebar-accent:active{background-color:var(--sidebar-accent)}.active\\:text-sidebar-accent-foreground:active{color:var(--sidebar-accent-foreground)}.active\\:not-aria-\\[haspopup\\]\\:translate-y-px:active:not([aria-haspopup]){--tw-translate-y:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}:where([data-side=left]) .in-data-\\[side\\=left\\]\\:cursor-w-resize{cursor:w-resize}:where([data-side=right]) .in-data-\\[side\\=right\\]\\:cursor-e-resize{cursor:e-resize}.has-aria-expanded\\:bg-muted\\/50:has([aria-expanded=true]){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.has-aria-expanded\\:bg-muted\\/50:has([aria-expanded=true]){background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.has-data-\\[icon\\=inline-end\\]\\:pr-1\\.5:has([data-icon=inline-end]){padding-right:calc(var(--spacing) * 1.5)}.has-data-\\[icon\\=inline-end\\]\\:pr-2:has([data-icon=inline-end]){padding-right:calc(var(--spacing) * 2)}.has-data-\\[icon\\=inline-end\\]\\:pr-2\\.5:has([data-icon=inline-end]){padding-right:calc(var(--spacing) * 2.5)}.has-data-\\[icon\\=inline-end\\]\\:pr-3:has([data-icon=inline-end]){padding-right:calc(var(--spacing) * 3)}.group-data-\\[spacing\\=0\\]\\/toggle-group\\:has-data-\\[icon\\=inline-end\\]\\:pr-2\\.5:is(:where(.group\\/toggle-group)[data-spacing=\"0\"] *):has([data-icon=inline-end]){padding-right:calc(var(--spacing) * 2.5)}.has-data-\\[icon\\=inline-start\\]\\:pl-1\\.5:has([data-icon=inline-start]){padding-left:calc(var(--spacing) * 1.5)}.has-data-\\[icon\\=inline-start\\]\\:pl-2:has([data-icon=inline-start]){padding-left:calc(var(--spacing) * 2)}.has-data-\\[icon\\=inline-start\\]\\:pl-2\\.5:has([data-icon=inline-start]){padding-left:calc(var(--spacing) * 2.5)}.has-data-\\[icon\\=inline-start\\]\\:pl-3:has([data-icon=inline-start]){padding-left:calc(var(--spacing) * 3)}.group-data-\\[spacing\\=0\\]\\/toggle-group\\:has-data-\\[icon\\=inline-start\\]\\:pl-2\\.5:is(:where(.group\\/toggle-group)[data-spacing=\"0\"] *):has([data-icon=inline-start]){padding-left:calc(var(--spacing) * 2.5)}.has-data-\\[slot\\=alert-action\\]\\:relative:has([data-slot=alert-action]){position:relative}.has-data-\\[slot\\=alert-action\\]\\:pr-18:has([data-slot=alert-action]){padding-right:calc(var(--spacing) * 18)}.has-data-\\[slot\\=alert-dialog-media\\]\\:grid-rows-\\[auto_auto_1fr\\]:has([data-slot=alert-dialog-media]){grid-template-rows:auto auto 1fr}.has-data-\\[slot\\=alert-dialog-media\\]\\:gap-x-6:has([data-slot=alert-dialog-media]){column-gap:calc(var(--spacing) * 6)}.has-data-\\[slot\\=card-action\\]\\:grid-cols-\\[1fr_auto\\]:has([data-slot=card-action]){grid-template-columns:1fr auto}.has-data-\\[slot\\=card-description\\]\\:grid-rows-\\[auto_auto\\]:has([data-slot=card-description]){grid-template-rows:auto auto}.has-data-\\[slot\\=kbd\\]\\:pr-1\\.5:has([data-slot=kbd]){padding-right:calc(var(--spacing) * 1.5)}.has-data-\\[variant\\=inset\\]\\:bg-sidebar:has([data-variant=inset]){background-color:var(--sidebar)}.has-data-checked\\:border-primary\\/30:has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.has-data-checked\\:border-primary\\/30:has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){border-color:color-mix(in oklab, var(--primary) 30%, transparent)}}.has-data-checked\\:bg-primary\\/5:has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.has-data-checked\\:bg-primary\\/5:has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){background-color:color-mix(in oklab, var(--primary) 5%, transparent)}}.has-\\[\\>\\[data-slot\\=checkbox-group\\]\\]\\:gap-3:has(>[data-slot=checkbox-group]){gap:calc(var(--spacing) * 3)}.has-\\[\\>\\[data-slot\\=field-content\\]\\]\\:items-start:has(>[data-slot=field-content]){align-items:flex-start}.has-\\[\\>\\[data-slot\\=field\\]\\]\\:w-full:has(>[data-slot=field]){width:100%}.has-\\[\\>\\[data-slot\\=field\\]\\]\\:flex-col:has(>[data-slot=field]){flex-direction:column}.has-\\[\\>\\[data-slot\\=field\\]\\]\\:rounded-xl:has(>[data-slot=field]){border-radius:calc(var(--radius) * 1.4)}.has-\\[\\>\\[data-slot\\=field\\]\\]\\:border:has(>[data-slot=field]){border-style:var(--tw-border-style);border-width:1px}@media (hover:hover){.has-\\[\\>\\[data-slot\\=field\\]\\]\\:not-has-\\[\\:disabled\\,\\[data-disabled\\]\\]\\:hover\\:bg-input\\/40:has(>[data-slot=field]):not(:has(:is(:disabled,[data-disabled]))):hover{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.has-\\[\\>\\[data-slot\\=field\\]\\]\\:not-has-\\[\\:disabled\\,\\[data-disabled\\]\\]\\:hover\\:bg-input\\/40:has(>[data-slot=field]):not(:has(:is(:disabled,[data-disabled]))):hover{background-color:color-mix(in oklab, var(--input) 40%, transparent)}}}.has-\\[\\>\\[data-slot\\=field\\]\\]\\:has-\\[\\:focus-visible\\]\\:border-ring:has(>[data-slot=field]):has(:focus-visible){border-color:var(--ring)}.has-\\[\\>\\[data-slot\\=field\\]\\]\\:has-\\[\\:focus-visible\\]\\:ring-\\[3px\\]:has(>[data-slot=field]):has(:focus-visible){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-\\[\\>\\[data-slot\\=field\\]\\]\\:has-\\[\\:focus-visible\\]\\:ring-ring\\/50:has(>[data-slot=field]):has(:focus-visible){--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.has-\\[\\>\\[data-slot\\=field\\]\\]\\:has-\\[\\:focus-visible\\]\\:ring-ring\\/50:has(>[data-slot=field]):has(:focus-visible){--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.has-\\[\\>\\[data-slot\\=radio-group\\]\\]\\:gap-3:has(>[data-slot=radio-group]){gap:calc(var(--spacing) * 3)}.has-\\[\\>img\\:first-child\\]\\:pt-0:has(>img:first-child){padding-top:0}.has-\\[\\>svg\\]\\:grid-cols-\\[auto_1fr\\]:has(>svg){grid-template-columns:auto 1fr}.has-\\[\\>svg\\]\\:gap-x-2\\.5:has(>svg){column-gap:calc(var(--spacing) * 2.5)}.aria-disabled\\:pointer-events-none[aria-disabled=true]{pointer-events:none}.aria-disabled\\:opacity-50[aria-disabled=true]{opacity:.5}.aria-expanded\\:bg-muted[aria-expanded=true]{background-color:var(--muted)}.aria-expanded\\:bg-secondary[aria-expanded=true]{background-color:var(--secondary)}.aria-expanded\\:text-foreground[aria-expanded=true]{color:var(--foreground)}.aria-expanded\\:text-secondary-foreground[aria-expanded=true]{color:var(--secondary-foreground)}.aria-expanded\\:opacity-100[aria-expanded=true]{opacity:1}.aria-invalid\\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\\:ring-\\[3px\\][aria-invalid=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.aria-invalid\\:ring-destructive\\/20[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.aria-invalid\\:ring-destructive\\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.aria-invalid\\:aria-checked\\:border-primary[aria-invalid=true][aria-checked=true]{border-color:var(--primary)}.aria-pressed\\:bg-muted[aria-pressed=true]{background-color:var(--muted)}.data-ending-style\\:h-0[data-ending-style]{height:0}.data-ending-style\\:opacity-0[data-ending-style]{opacity:0}.data-inset\\:pl-9\\.5[data-inset]{padding-left:calc(var(--spacing) * 9.5)}.data-popup-open\\:bg-accent[data-popup-open]{background-color:var(--accent)}.data-popup-open\\:text-accent-foreground[data-popup-open]{color:var(--accent-foreground)}.data-starting-style\\:h-0[data-starting-style]{height:0}.data-starting-style\\:opacity-0[data-starting-style]{opacity:0}.data-\\[invalid\\=true\\]\\:text-destructive[data-invalid=true]{color:var(--destructive)}.data-\\[side\\=bottom\\]\\:inset-x-0[data-side=bottom]{inset-inline:0}.data-\\[side\\=bottom\\]\\:top-1[data-side=bottom]{top:var(--spacing)}.data-\\[side\\=bottom\\]\\:bottom-0[data-side=bottom]{bottom:0}.data-\\[side\\=bottom\\]\\:h-auto[data-side=bottom]{height:auto}.data-\\[side\\=bottom\\]\\:border-t[data-side=bottom]{border-top-style:var(--tw-border-style);border-top-width:1px}.data-\\[side\\=bottom\\]\\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:calc(2*var(--spacing)*-1)}.data-\\[side\\=bottom\\]\\:data-ending-style\\:translate-y-\\[2\\.5rem\\][data-side=bottom][data-ending-style],.data-\\[side\\=bottom\\]\\:data-starting-style\\:translate-y-\\[2\\.5rem\\][data-side=bottom][data-starting-style]{--tw-translate-y:2.5rem;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=inline-end\\]\\:top-1\\/2\\![data-side=inline-end]{top:50%!important}.data-\\[side\\=inline-end\\]\\:-left-1[data-side=inline-end]{left:calc(var(--spacing) * -1)}.data-\\[side\\=inline-end\\]\\:translate-x-\\[1\\.5px\\][data-side=inline-end]{--tw-translate-x:1.5px;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=inline-end\\]\\:-translate-y-1\\/2[data-side=inline-end]{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=inline-end\\]\\:slide-in-from-left-2[data-side=inline-end]{--tw-enter-translate-x:calc(2*var(--spacing)*-1)}.data-\\[side\\=inline-start\\]\\:top-1\\/2\\![data-side=inline-start]{top:50%!important}.data-\\[side\\=inline-start\\]\\:-right-1[data-side=inline-start]{right:calc(var(--spacing) * -1)}.data-\\[side\\=inline-start\\]\\:translate-x-\\[-1\\.5px\\][data-side=inline-start]{--tw-translate-x:-1.5px;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=inline-start\\]\\:-translate-y-1\\/2[data-side=inline-start]{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=inline-start\\]\\:slide-in-from-right-2[data-side=inline-start]{--tw-enter-translate-x:calc(2*var(--spacing))}.data-\\[side\\=left\\]\\:inset-y-0[data-side=left]{inset-block:0}.data-\\[side\\=left\\]\\:top-1\\/2\\![data-side=left]{top:50%!important}.data-\\[side\\=left\\]\\:-right-1[data-side=left]{right:calc(var(--spacing) * -1)}.data-\\[side\\=left\\]\\:left-0[data-side=left]{left:0}.data-\\[side\\=left\\]\\:h-full[data-side=left]{height:100%}.data-\\[side\\=left\\]\\:w-3\\/4[data-side=left]{width:75%}.data-\\[side\\=left\\]\\:translate-x-\\[-1\\.5px\\][data-side=left]{--tw-translate-x:-1.5px;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=left\\]\\:-translate-y-1\\/2[data-side=left]{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=left\\]\\:border-r[data-side=left]{border-right-style:var(--tw-border-style);border-right-width:1px}.data-\\[side\\=left\\]\\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:calc(2*var(--spacing))}.data-\\[side\\=left\\]\\:group-data-\\[collapsible\\=offcanvas\\]\\:left-\\[calc\\(var\\(--sidebar-width\\)\\*-1\\)\\][data-side=left]:is(:where(.group)[data-collapsible=offcanvas] *){left:calc(var(--sidebar-width) * -1)}.data-\\[side\\=left\\]\\:data-ending-style\\:translate-x-\\[-2\\.5rem\\][data-side=left][data-ending-style],.data-\\[side\\=left\\]\\:data-starting-style\\:translate-x-\\[-2\\.5rem\\][data-side=left][data-starting-style]{--tw-translate-x:-2.5rem;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=right\\]\\:inset-y-0[data-side=right]{inset-block:0}.data-\\[side\\=right\\]\\:top-1\\/2\\![data-side=right]{top:50%!important}.data-\\[side\\=right\\]\\:right-0[data-side=right]{right:0}.data-\\[side\\=right\\]\\:-left-1[data-side=right]{left:calc(var(--spacing) * -1)}.data-\\[side\\=right\\]\\:h-full[data-side=right]{height:100%}.data-\\[side\\=right\\]\\:w-3\\/4[data-side=right]{width:75%}.data-\\[side\\=right\\]\\:translate-x-\\[1\\.5px\\][data-side=right]{--tw-translate-x:1.5px;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=right\\]\\:-translate-y-1\\/2[data-side=right]{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=right\\]\\:border-l[data-side=right]{border-left-style:var(--tw-border-style);border-left-width:1px}.data-\\[side\\=right\\]\\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:calc(2*var(--spacing)*-1)}.data-\\[side\\=right\\]\\:group-data-\\[collapsible\\=offcanvas\\]\\:right-\\[calc\\(var\\(--sidebar-width\\)\\*-1\\)\\][data-side=right]:is(:where(.group)[data-collapsible=offcanvas] *){right:calc(var(--sidebar-width) * -1)}.data-\\[side\\=right\\]\\:data-ending-style\\:translate-x-\\[2\\.5rem\\][data-side=right][data-ending-style],.data-\\[side\\=right\\]\\:data-starting-style\\:translate-x-\\[2\\.5rem\\][data-side=right][data-starting-style]{--tw-translate-x:2.5rem;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=top\\]\\:inset-x-0[data-side=top]{inset-inline:0}.data-\\[side\\=top\\]\\:top-0[data-side=top]{top:0}.data-\\[side\\=top\\]\\:-bottom-2\\.5[data-side=top]{bottom:calc(var(--spacing) * -2.5)}.data-\\[side\\=top\\]\\:h-auto[data-side=top]{height:auto}.data-\\[side\\=top\\]\\:border-b[data-side=top]{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.data-\\[side\\=top\\]\\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:calc(2*var(--spacing))}.data-\\[side\\=top\\]\\:data-ending-style\\:translate-y-\\[-2\\.5rem\\][data-side=top][data-ending-style],.data-\\[side\\=top\\]\\:data-starting-style\\:translate-y-\\[-2\\.5rem\\][data-side=top][data-starting-style]{--tw-translate-y:-2.5rem;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[size\\=default\\]\\:max-w-xs[data-size=default]{max-width:var(--container-xs)}.data-\\[size\\=lg\\]\\:size-10[data-size=lg]{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.data-\\[size\\=md\\]\\:text-sm[data-size=md]{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.data-\\[size\\=sm\\]\\:size-6[data-size=sm]{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.data-\\[size\\=sm\\]\\:max-w-xs[data-size=sm]{max-width:var(--container-xs)}.data-\\[size\\=sm\\]\\:text-xs[data-size=sm]{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.data-\\[size\\=sm\\]\\:\\[--card-spacing\\:--spacing\\(4\\)\\][data-size=sm]{--card-spacing:calc(var(--spacing) * 4)}:is(.\\*\\*\\:data-\\[slot\\=accordion-trigger-icon\\]\\:ml-auto *)[data-slot=accordion-trigger-icon]{margin-left:auto}:is(.\\*\\*\\:data-\\[slot\\=accordion-trigger-icon\\]\\:size-4 *)[data-slot=accordion-trigger-icon]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}:is(.\\*\\*\\:data-\\[slot\\=accordion-trigger-icon\\]\\:text-muted-foreground *)[data-slot=accordion-trigger-icon]{color:var(--muted-foreground)}:is(.\\*\\:data-\\[slot\\=alert-description\\]\\:text-destructive\\/90>*)[data-slot=alert-description]{color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){:is(.\\*\\:data-\\[slot\\=alert-description\\]\\:text-destructive\\/90>*)[data-slot=alert-description]{color:color-mix(in oklab, var(--destructive) 90%, transparent)}}:is(.\\*\\:data-\\[slot\\=avatar\\]\\:ring-2>*)[data-slot=avatar]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(.\\*\\:data-\\[slot\\=avatar\\]\\:ring-background>*)[data-slot=avatar]{--tw-ring-color:var(--background)}.data-\\[slot\\=checkbox-group\\]\\:gap-3[data-slot=checkbox-group]{gap:calc(var(--spacing) * 3)}:is(.\\*\\:data-\\[slot\\=field\\]\\:p-4>*)[data-slot=field]{padding:calc(var(--spacing) * 4)}:is(.\\*\\:data-\\[slot\\=field-group\\]\\:gap-4>*)[data-slot=field-group]{gap:calc(var(--spacing) * 4)}:is(.\\*\\:data-\\[slot\\=field-label\\]\\:flex-auto>*)[data-slot=field-label]{flex:auto}:is(.\\*\\*\\:data-\\[slot\\=kbd\\]\\:relative *)[data-slot=kbd]{position:relative}:is(.\\*\\*\\:data-\\[slot\\=kbd\\]\\:isolate *)[data-slot=kbd]{isolation:isolate}:is(.\\*\\*\\:data-\\[slot\\=kbd\\]\\:z-50 *)[data-slot=kbd]{z-index:50}:is(.\\*\\*\\:data-\\[slot\\=kbd\\]\\:rounded-4xl *)[data-slot=kbd]{border-radius:calc(var(--radius) * 2.6)}.group-data-horizontal\\/toggle-group\\:data-\\[spacing\\=0\\]\\:first\\:rounded-l-3xl:is(:where(.group\\/toggle-group):where([data-orientation=horizontal]) *)[data-spacing=\"0\"]:first-child{border-top-left-radius:calc(var(--radius) * 2.2);border-bottom-left-radius:calc(var(--radius) * 2.2)}.group-data-vertical\\/toggle-group\\:data-\\[spacing\\=0\\]\\:first\\:rounded-t-3xl:is(:where(.group\\/toggle-group):where([data-orientation=vertical]) *)[data-spacing=\"0\"]:first-child{border-top-left-radius:calc(var(--radius) * 2.2);border-top-right-radius:calc(var(--radius) * 2.2)}.group-data-horizontal\\/toggle-group\\:data-\\[spacing\\=0\\]\\:last\\:rounded-r-3xl:is(:where(.group\\/toggle-group):where([data-orientation=horizontal]) *)[data-spacing=\"0\"]:last-child{border-top-right-radius:calc(var(--radius) * 2.2);border-bottom-right-radius:calc(var(--radius) * 2.2)}.group-data-vertical\\/toggle-group\\:data-\\[spacing\\=0\\]\\:last\\:rounded-b-3xl:is(:where(.group\\/toggle-group):where([data-orientation=vertical]) *)[data-spacing=\"0\"]:last-child{border-bottom-right-radius:calc(var(--radius) * 2.2);border-bottom-left-radius:calc(var(--radius) * 2.2)}.data-\\[state\\=delayed-open\\]\\:animate-in[data-state=delayed-open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\\[state\\=delayed-open\\]\\:fade-in-0[data-state=delayed-open]{--tw-enter-opacity:0}.data-\\[state\\=delayed-open\\]\\:zoom-in-95[data-state=delayed-open]{--tw-enter-scale:.95}.data-\\[state\\=on\\]\\:bg-muted[data-state=on],.data-\\[state\\=selected\\]\\:bg-muted[data-state=selected]{background-color:var(--muted)}.data-\\[variant\\=destructive\\]\\:text-destructive[data-variant=destructive]{color:var(--destructive)}.data-\\[variant\\=destructive\\]\\:focus\\:bg-destructive\\/10[data-variant=destructive]:focus{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.data-\\[variant\\=destructive\\]\\:focus\\:bg-destructive\\/10[data-variant=destructive]:focus{background-color:color-mix(in oklab, var(--destructive) 10%, transparent)}}.data-\\[variant\\=destructive\\]\\:focus\\:text-destructive[data-variant=destructive]:focus{color:var(--destructive)}.data-\\[variant\\=label\\]\\:text-sm[data-variant=label]{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.data-\\[variant\\=legend\\]\\:text-base[data-variant=legend]{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.data-\\[variant\\=line\\]\\:rounded-none[data-variant=line]{border-radius:0}.data-\\[spacing\\=0\\]\\:data-\\[variant\\=outline\\]\\:rounded-4xl[data-spacing=\"0\"][data-variant=outline]{border-radius:calc(var(--radius) * 2.6)}.group-data-horizontal\\/toggle-group\\:data-\\[spacing\\=0\\]\\:data-\\[variant\\=outline\\]\\:border-l-0:is(:where(.group\\/toggle-group):where([data-orientation=horizontal]) *)[data-spacing=\"0\"][data-variant=outline]{border-left-style:var(--tw-border-style);border-left-width:0}.group-data-vertical\\/toggle-group\\:data-\\[spacing\\=0\\]\\:data-\\[variant\\=outline\\]\\:border-t-0:is(:where(.group\\/toggle-group):where([data-orientation=vertical]) *)[data-spacing=\"0\"][data-variant=outline]{border-top-style:var(--tw-border-style);border-top-width:0}.group-data-horizontal\\/toggle-group\\:data-\\[spacing\\=0\\]\\:data-\\[variant\\=outline\\]\\:first\\:border-l:is(:where(.group\\/toggle-group):where([data-orientation=horizontal]) *)[data-spacing=\"0\"][data-variant=outline]:first-child{border-left-style:var(--tw-border-style);border-left-width:1px}.group-data-vertical\\/toggle-group\\:data-\\[spacing\\=0\\]\\:data-\\[variant\\=outline\\]\\:first\\:border-t:is(:where(.group\\/toggle-group):where([data-orientation=vertical]) *)[data-spacing=\"0\"][data-variant=outline]:first-child{border-top-style:var(--tw-border-style);border-top-width:1px}.nth-last-2\\:-mt-1:nth-last-child(2){margin-top:calc(var(--spacing) * -1)}@supports ((-webkit-backdrop-filter:var(--tw)) or (backdrop-filter:var(--tw))){.supports-backdrop-filter\\:backdrop-blur-xs{--tw-backdrop-blur:blur(var(--blur-xs));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}}@media (prefers-reduced-motion:reduce){.motion-reduce\\:animate-none{animation:none}}@media (min-width:40rem){.sm\\:right-\\[22px\\]{right:22px}.sm\\:bottom-\\[22px\\]{bottom:22px}.sm\\:flex{display:flex}.sm\\:w-52{width:calc(var(--spacing) * 52)}.sm\\:max-w-md{max-width:var(--container-md)}.sm\\:flex-row{flex-direction:row}.sm\\:justify-end{justify-content:flex-end}.sm\\:group-data-\\[size\\=default\\]\\/alert-dialog-content\\:row-span-2:is(:where(.group\\/alert-dialog-content)[data-size=default] *){grid-row:span 2/span 2}.sm\\:group-data-\\[size\\=default\\]\\/alert-dialog-content\\:place-items-start:is(:where(.group\\/alert-dialog-content)[data-size=default] *){place-items:start}.sm\\:group-data-\\[size\\=default\\]\\/alert-dialog-content\\:text-left:is(:where(.group\\/alert-dialog-content)[data-size=default] *){text-align:left}.sm\\:group-data-\\[size\\=default\\]\\/alert-dialog-content\\:group-has-data-\\[slot\\=alert-dialog-media\\]\\/alert-dialog-content\\:col-start-2:is(:where(.group\\/alert-dialog-content)[data-size=default] *):is(:where(.group\\/alert-dialog-content):has([data-slot=alert-dialog-media]) *){grid-column-start:2}.sm\\:group-data-\\[size\\=default\\]\\/alert-dialog-content\\:has-data-\\[slot\\=alert-dialog-media\\]\\:grid-rows-\\[auto_1fr\\]:is(:where(.group\\/alert-dialog-content)[data-size=default] *):has([data-slot=alert-dialog-media]){grid-template-rows:auto 1fr}.data-\\[side\\=left\\]\\:sm\\:max-w-sm[data-side=left],.data-\\[side\\=right\\]\\:sm\\:max-w-sm[data-side=right]{max-width:var(--container-sm)}.data-\\[size\\=default\\]\\:sm\\:max-w-md[data-size=default]{max-width:var(--container-md)}}@media (min-width:48rem){.md\\:block{display:block}.md\\:flex{display:flex}.md\\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.md\\:text-pretty{text-wrap:pretty}.md\\:opacity-0{opacity:0}.md\\:peer-data-\\[variant\\=inset\\]\\:m-2:is(:where(.peer)[data-variant=inset]~*){margin:calc(var(--spacing) * 2)}.md\\:peer-data-\\[variant\\=inset\\]\\:ml-0:is(:where(.peer)[data-variant=inset]~*){margin-left:0}.md\\:peer-data-\\[variant\\=inset\\]\\:rounded-xl:is(:where(.peer)[data-variant=inset]~*){border-radius:calc(var(--radius) * 1.4)}.md\\:peer-data-\\[variant\\=inset\\]\\:shadow-sm:is(:where(.peer)[data-variant=inset]~*){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.md\\:peer-data-\\[variant\\=inset\\]\\:peer-data-\\[state\\=collapsed\\]\\:ml-2:is(:where(.peer)[data-variant=inset]~*):is(:where(.peer)[data-state=collapsed]~*){margin-left:calc(var(--spacing) * 2)}.md\\:after\\:hidden:after{content:var(--tw-content);display:none}}@container field-group (min-width:28rem){.\\@md\\/field-group\\:flex-row{flex-direction:row}.\\@md\\/field-group\\:items-center{align-items:center}:is(.\\@md\\/field-group\\:\\*\\:w-auto>*){width:auto}.\\@md\\/field-group\\:has-\\[\\>\\[data-slot\\=field-content\\]\\]\\:items-start:has(>[data-slot=field-content]){align-items:flex-start}:is(.\\@md\\/field-group\\:\\*\\:data-\\[slot\\=field-label\\]\\:flex-auto>*)[data-slot=field-label]{flex:auto}}.ltr\\:-translate-x-1\\/2:where(:dir(ltr),[dir=ltr],[dir=ltr] *),.rtl\\:-translate-x-1\\/2:where(:dir(rtl),[dir=rtl],[dir=rtl] *){--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.dark\\:bg-destructive\\/20:is(.dark *){background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:bg-destructive\\/20:is(.dark *){background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.dark\\:bg-input\\/30:is(.dark *){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\\:bg-input\\/30:is(.dark *){background-color:color-mix(in oklab, var(--input) 30%, transparent)}}.dark\\:text-muted-foreground:is(.dark *){color:var(--muted-foreground)}.dark\\:ring-foreground\\/10:is(.dark *){--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.dark\\:ring-foreground\\/10:is(.dark *){--tw-ring-color:color-mix(in oklab, var(--foreground) 10%, transparent)}}.dark\\:after\\:mix-blend-lighten:is(.dark *):after{content:var(--tw-content);mix-blend-mode:lighten}@media (hover:hover){.dark\\:hover\\:bg-destructive\\/30:is(.dark *):hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:hover\\:bg-destructive\\/30:is(.dark *):hover{background-color:color-mix(in oklab, var(--destructive) 30%, transparent)}}.dark\\:hover\\:bg-muted\\/50:is(.dark *):hover{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.dark\\:hover\\:bg-muted\\/50:is(.dark *):hover{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.dark\\:hover\\:text-foreground:is(.dark *):hover{color:var(--foreground)}}.dark\\:focus-visible\\:ring-destructive\\/40:is(.dark *):focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:focus-visible\\:ring-destructive\\/40:is(.dark *):focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\\:has-data-checked\\:border-primary\\/20:is(.dark *):has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark\\:has-data-checked\\:border-primary\\/20:is(.dark *):has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){border-color:color-mix(in oklab, var(--primary) 20%, transparent)}}.dark\\:has-data-checked\\:bg-primary\\/10:is(.dark *):has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark\\:has-data-checked\\:bg-primary\\/10:is(.dark *):has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){background-color:color-mix(in oklab, var(--primary) 10%, transparent)}}.dark\\:aria-invalid\\:border-destructive\\/50:is(.dark *)[aria-invalid=true]{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:aria-invalid\\:border-destructive\\/50:is(.dark *)[aria-invalid=true]{border-color:color-mix(in oklab, var(--destructive) 50%, transparent)}}.dark\\:aria-invalid\\:ring-destructive\\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:aria-invalid\\:ring-destructive\\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\\:data-\\[variant\\=destructive\\]\\:focus\\:bg-destructive\\/20:is(.dark *)[data-variant=destructive]:focus{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:data-\\[variant\\=destructive\\]\\:focus\\:bg-destructive\\/20:is(.dark *)[data-variant=destructive]:focus{background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.data-open\\:animate-accordion-down:where([data-state=open]),.data-open\\:animate-accordion-down:where([data-open]:not([data-open=false])){animation:accordion-down var(--tw-animation-duration,var(--tw-duration,.2s))var(--tw-ease,ease-out)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-open\\:animate-in:where([data-state=open]),.data-open\\:animate-in:where([data-open]:not([data-open=false])){animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-open\\:bg-accent:where([data-state=open]),.data-open\\:bg-accent:where([data-open]:not([data-open=false])){background-color:var(--accent)}.data-open\\:bg-muted\\/50:where([data-state=open]),.data-open\\:bg-muted\\/50:where([data-open]:not([data-open=false])){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.data-open\\:bg-muted\\/50:where([data-state=open]),.data-open\\:bg-muted\\/50:where([data-open]:not([data-open=false])){background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.data-open\\:text-accent-foreground:where([data-state=open]),.data-open\\:text-accent-foreground:where([data-open]:not([data-open=false])){color:var(--accent-foreground)}.data-open\\:fade-in-0:where([data-state=open]),.data-open\\:fade-in-0:where([data-open]:not([data-open=false])){--tw-enter-opacity:0}.data-open\\:zoom-in-95:where([data-state=open]),.data-open\\:zoom-in-95:where([data-open]:not([data-open=false])){--tw-enter-scale:.95}@media (hover:hover){:is(.data-open\\:hover\\:bg-sidebar-accent:where([data-state=open]),.data-open\\:hover\\:bg-sidebar-accent:where([data-open]:not([data-open=false]))):hover{background-color:var(--sidebar-accent)}:is(.data-open\\:hover\\:text-sidebar-accent-foreground:where([data-state=open]),.data-open\\:hover\\:text-sidebar-accent-foreground:where([data-open]:not([data-open=false]))):hover{color:var(--sidebar-accent-foreground)}}.data-closed\\:animate-accordion-up:where([data-state=closed]),.data-closed\\:animate-accordion-up:where([data-closed]:not([data-closed=false])){animation:accordion-up var(--tw-animation-duration,var(--tw-duration,.2s))var(--tw-ease,ease-out)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-closed\\:animate-out:where([data-state=closed]),.data-closed\\:animate-out:where([data-closed]:not([data-closed=false])){animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-closed\\:overflow-hidden:where([data-state=closed]),.data-closed\\:overflow-hidden:where([data-closed]:not([data-closed=false])){overflow:hidden}.data-closed\\:fade-out-0:where([data-state=closed]),.data-closed\\:fade-out-0:where([data-closed]:not([data-closed=false])){--tw-exit-opacity:0}.data-closed\\:zoom-out-95:where([data-state=closed]),.data-closed\\:zoom-out-95:where([data-closed]:not([data-closed=false])){--tw-exit-scale:.95}.data-checked\\:border-primary:where([data-state=checked]),.data-checked\\:border-primary:where([data-checked]:not([data-checked=false])){border-color:var(--primary)}.data-checked\\:bg-primary:where([data-state=checked]),.data-checked\\:bg-primary:where([data-checked]:not([data-checked=false])){background-color:var(--primary)}.data-checked\\:text-primary-foreground:where([data-state=checked]),.data-checked\\:text-primary-foreground:where([data-checked]:not([data-checked=false])){color:var(--primary-foreground)}.group-has-\\[\\:focus-visible\\]\\/field-label\\:data-checked\\:border-primary:is(:where(.group\\/field-label):has(:focus-visible) *):where([data-state=checked]),.group-has-\\[\\:focus-visible\\]\\/field-label\\:data-checked\\:border-primary:is(:where(.group\\/field-label):has(:focus-visible) *):where([data-checked]:not([data-checked=false])){border-color:var(--primary)}.dark\\:data-checked\\:bg-primary:is(.dark *):where([data-state=checked]),.dark\\:data-checked\\:bg-primary:is(.dark *):where([data-checked]:not([data-checked=false])){background-color:var(--primary)}.data-disabled\\:pointer-events-none:where([data-disabled=true]),.data-disabled\\:pointer-events-none:where([data-disabled]:not([data-disabled=false])){pointer-events:none}.data-disabled\\:opacity-50:where([data-disabled=true]),.data-disabled\\:opacity-50:where([data-disabled]:not([data-disabled=false])){opacity:.5}.data-active\\:bg-background:where([data-state=active]),.data-active\\:bg-background:where([data-active]:not([data-active=false])){background-color:var(--background)}.data-active\\:bg-sidebar-accent:where([data-state=active]),.data-active\\:bg-sidebar-accent:where([data-active]:not([data-active=false])){background-color:var(--sidebar-accent)}.data-active\\:font-medium:where([data-state=active]),.data-active\\:font-medium:where([data-active]:not([data-active=false])){--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.data-active\\:text-foreground:where([data-state=active]),.data-active\\:text-foreground:where([data-active]:not([data-active=false])){color:var(--foreground)}.data-active\\:text-sidebar-accent-foreground:where([data-state=active]),.data-active\\:text-sidebar-accent-foreground:where([data-active]:not([data-active=false])){color:var(--sidebar-accent-foreground)}.group-data-\\[variant\\=line\\]\\/tabs-list\\:data-active\\:bg-transparent:is(:where(.group\\/tabs-list)[data-variant=line] *):where([data-state=active]),.group-data-\\[variant\\=line\\]\\/tabs-list\\:data-active\\:bg-transparent:is(:where(.group\\/tabs-list)[data-variant=line] *):where([data-active]:not([data-active=false])){background-color:#0000}:is(.group-data-\\[variant\\=line\\]\\/tabs-list\\:data-active\\:after\\:opacity-100:is(:where(.group\\/tabs-list)[data-variant=line] *):where([data-state=active]),.group-data-\\[variant\\=line\\]\\/tabs-list\\:data-active\\:after\\:opacity-100:is(:where(.group\\/tabs-list)[data-variant=line] *):where([data-active]:not([data-active=false]))):after{content:var(--tw-content);opacity:1}.dark\\:data-active\\:border-input:is(.dark *):where([data-state=active]),.dark\\:data-active\\:border-input:is(.dark *):where([data-active]:not([data-active=false])){border-color:var(--input)}.dark\\:data-active\\:bg-input\\/30:is(.dark *):where([data-state=active]),.dark\\:data-active\\:bg-input\\/30:is(.dark *):where([data-active]:not([data-active=false])){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\\:data-active\\:bg-input\\/30:is(.dark *):where([data-state=active]),.dark\\:data-active\\:bg-input\\/30:is(.dark *):where([data-active]:not([data-active=false])){background-color:color-mix(in oklab, var(--input) 30%, transparent)}}.dark\\:data-active\\:text-foreground:is(.dark *):where([data-state=active]),.dark\\:data-active\\:text-foreground:is(.dark *):where([data-active]:not([data-active=false])){color:var(--foreground)}.dark\\:group-data-\\[variant\\=line\\]\\/tabs-list\\:data-active\\:border-transparent:is(.dark *):is(:where(.group\\/tabs-list)[data-variant=line] *):where([data-state=active]),.dark\\:group-data-\\[variant\\=line\\]\\/tabs-list\\:data-active\\:border-transparent:is(.dark *):is(:where(.group\\/tabs-list)[data-variant=line] *):where([data-active]:not([data-active=false])){border-color:#0000}.dark\\:group-data-\\[variant\\=line\\]\\/tabs-list\\:data-active\\:bg-transparent:is(.dark *):is(:where(.group\\/tabs-list)[data-variant=line] *):where([data-state=active]),.dark\\:group-data-\\[variant\\=line\\]\\/tabs-list\\:data-active\\:bg-transparent:is(.dark *):is(:where(.group\\/tabs-list)[data-variant=line] *):where([data-active]:not([data-active=false])){background-color:#0000}.data-horizontal\\:h-px:where([data-orientation=horizontal]){height:1px}.data-horizontal\\:w-full:where([data-orientation=horizontal]){width:100%}.data-horizontal\\:flex-col:where([data-orientation=horizontal]){flex-direction:column}.data-vertical\\:w-px:where([data-orientation=vertical]){width:1px}.data-vertical\\:flex-col:where([data-orientation=vertical]){flex-direction:column}.data-vertical\\:items-stretch:where([data-orientation=vertical]){align-items:stretch}.data-vertical\\:self-stretch:where([data-orientation=vertical]){align-self:stretch}.\\[\\&_a\\]\\:underline a{text-decoration-line:underline}.\\[\\&_a\\]\\:underline-offset-3 a{text-underline-offset:3px}@media (hover:hover){.\\[\\&_a\\]\\:hover\\:text-foreground a:hover{color:var(--foreground)}}.\\[\\&_p\\:not\\(\\:last-child\\)\\]\\:mb-4 p:not(:last-child){margin-bottom:calc(var(--spacing) * 4)}.\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.\\[\\&_svg\\]\\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.\\[\\&_svg\\:not\\(\\[class\\*\\=\\'size-\\'\\]\\)\\]\\:size-3 svg:not([class*=size-]){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\\[\\&_svg\\:not\\(\\[class\\*\\=\\'size-\\'\\]\\)\\]\\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\\[\\&_tr\\]\\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\\[\\&_tr\\:last-child\\]\\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\\[\\&\\:has\\(\\[role\\=checkbox\\]\\)\\]\\:pr-0:has([role=checkbox]){padding-right:0}.\\[\\.border-b\\]\\:pb-\\(--card-spacing\\).border-b{padding-bottom:var(--card-spacing)}.\\[\\.border-t\\]\\:pt-\\(--card-spacing\\).border-t{padding-top:var(--card-spacing)}:is(.\\*\\:\\[a\\]\\:underline>*):is(a){text-decoration-line:underline}:is(.\\*\\:\\[a\\]\\:underline-offset-3>*):is(a){text-underline-offset:3px}@media (hover:hover){.\\[a\\]\\:hover\\:bg-destructive\\/20:is(a):hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.\\[a\\]\\:hover\\:bg-destructive\\/20:is(a):hover{background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.\\[a\\]\\:hover\\:bg-muted:is(a):hover{background-color:var(--muted)}.\\[a\\]\\:hover\\:bg-primary\\/80:is(a):hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.\\[a\\]\\:hover\\:bg-primary\\/80:is(a):hover{background-color:color-mix(in oklab, var(--primary) 80%, transparent)}}.\\[a\\]\\:hover\\:bg-secondary\\/80:is(a):hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.\\[a\\]\\:hover\\:bg-secondary\\/80:is(a):hover{background-color:color-mix(in oklab, var(--secondary) 80%, transparent)}}.\\[a\\]\\:hover\\:text-muted-foreground:is(a):hover{color:var(--muted-foreground)}:is(.\\*\\:\\[a\\]\\:hover\\:text-foreground>*):is(a):hover{color:var(--foreground)}}:is(.\\*\\:\\[img\\:first-child\\]\\:rounded-t-xl>*):is(img:first-child){border-top-left-radius:calc(var(--radius) * 1.4);border-top-right-radius:calc(var(--radius) * 1.4)}:is(.\\*\\:\\[img\\:last-child\\]\\:rounded-b-xl>*):is(img:last-child){border-bottom-right-radius:calc(var(--radius) * 1.4);border-bottom-left-radius:calc(var(--radius) * 1.4)}:is(.\\*\\:\\[svg\\]\\:row-span-2>*):is(svg){grid-row:span 2/span 2}:is(.\\*\\:\\[svg\\]\\:translate-y-0\\.5>*):is(svg){--tw-translate-y:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}:is(.\\*\\:\\[svg\\]\\:text-current>*):is(svg){color:currentColor}:is(.data-\\[variant\\=destructive\\]\\:\\*\\:\\[svg\\]\\:text-destructive[data-variant=destructive]>*):is(svg){color:var(--destructive)}:is(.\\*\\:\\[svg\\:not\\(\\[class\\*\\=\\'size-\\'\\]\\)\\]\\:size-4>*):is(svg:not([class*=size-])){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}:is(.\\*\\:\\[svg\\:not\\(\\[class\\*\\=\\'size-\\'\\]\\)\\]\\:size-8>*):is(svg:not([class*=size-])){width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.\\[\\&\\>\\.sr-only\\]\\:w-auto>.sr-only{width:auto}.has-\\[\\>\\[data-slot\\=field-content\\]\\]\\:\\[\\&\\>\\[role\\=checkbox\\]\\,\\[role\\=radio\\]\\]\\:mt-px:has(>[data-slot=field-content])>[role=checkbox],.has-\\[\\>\\[data-slot\\=field-content\\]\\]\\:\\[\\&\\>\\[role\\=checkbox\\]\\,\\[role\\=radio\\]\\]\\:mt-px:has(>[data-slot=field-content]) [role=radio]{margin-top:1px}@container field-group (min-width:28rem){.\\@md\\/field-group\\:has-\\[\\>\\[data-slot\\=field-content\\]\\]\\:\\[\\&\\>\\[role\\=checkbox\\]\\,\\[role\\=radio\\]\\]\\:mt-px:has(>[data-slot=field-content])>[role=checkbox],.\\@md\\/field-group\\:has-\\[\\>\\[data-slot\\=field-content\\]\\]\\:\\[\\&\\>\\[role\\=checkbox\\]\\,\\[role\\=radio\\]\\]\\:mt-px:has(>[data-slot=field-content]) [role=radio]{margin-top:1px}}.\\[\\&\\>a\\]\\:underline>a{text-decoration-line:underline}.\\[\\&\\>a\\]\\:underline-offset-4>a{text-underline-offset:4px}.\\[\\&\\>a\\:hover\\]\\:text-primary>a:hover{color:var(--primary)}.\\[\\&\\>button\\]\\:hidden>button{display:none}.\\[\\&\\>span\\:last-child\\]\\:truncate>span:last-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.\\[\\&\\>svg\\]\\:pointer-events-none>svg{pointer-events:none}.\\[\\&\\>svg\\]\\:size-3\\!>svg{width:calc(var(--spacing) * 3)!important;height:calc(var(--spacing) * 3)!important}.\\[\\&\\>svg\\]\\:size-3\\.5>svg{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\\[\\&\\>svg\\]\\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\\[\\&\\>svg\\]\\:shrink-0>svg{flex-shrink:0}.\\[\\&\\>svg\\]\\:text-sidebar-accent-foreground>svg{color:var(--sidebar-accent-foreground)}.group-has-data-\\[size\\=lg\\]\\/avatar-group\\:\\[\\&\\>svg\\]\\:size-5:is(:where(.group\\/avatar-group):has([data-size=lg]) *)>svg{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.group-has-data-\\[size\\=sm\\]\\/avatar-group\\:\\[\\&\\>svg\\]\\:size-3:is(:where(.group\\/avatar-group):has([data-size=sm]) *)>svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.group-data-\\[size\\=default\\]\\/avatar\\:\\[\\&\\>svg\\]\\:size-2:is(:where(.group\\/avatar)[data-size=default] *)>svg,.group-data-\\[size\\=lg\\]\\/avatar\\:\\[\\&\\>svg\\]\\:size-2:is(:where(.group\\/avatar)[data-size=lg] *)>svg{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.group-data-\\[size\\=sm\\]\\/avatar\\:\\[\\&\\>svg\\]\\:hidden:is(:where(.group\\/avatar)[data-size=sm] *)>svg{display:none}.\\[\\&\\>tr\\]\\:last\\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}[data-side=left][data-collapsible=offcanvas] .\\[\\[data-side\\=left\\]\\[data-collapsible\\=offcanvas\\]_\\&\\]\\:-right-2{right:calc(var(--spacing) * -2)}[data-side=left][data-state=collapsed] .\\[\\[data-side\\=left\\]\\[data-state\\=collapsed\\]_\\&\\]\\:cursor-e-resize{cursor:e-resize}[data-side=right][data-collapsible=offcanvas] .\\[\\[data-side\\=right\\]\\[data-collapsible\\=offcanvas\\]_\\&\\]\\:-left-2{left:calc(var(--spacing) * -2)}[data-side=right][data-state=collapsed] .\\[\\[data-side\\=right\\]\\[data-state\\=collapsed\\]_\\&\\]\\:cursor-w-resize{cursor:w-resize}[data-variant=legend]+.\\[\\[data-variant\\=legend\\]\\+\\&\\]\\:-mt-1\\.5{margin-top:calc(var(--spacing) * -1.5)}.animate-dialog{opacity:var(--tw-anim-dialog-start-opacity,0);translate:var(--tw-anim-dialog-start-translate,0 1.5rem);scale:var(--tw-anim-dialog-start-scale,.96);will-change:opacity, translate, scale;transition:opacity var(--tw-anim-dialog-duration,.35s) ease, translate var(--tw-anim-dialog-duration,.35s) var(--tw-anim-dialog-easing,cubic-bezier(.22, 1, .36, 1)), scale var(--tw-anim-dialog-duration,.35s) var(--tw-anim-dialog-easing,cubic-bezier(.22, 1, .36, 1)), overlay var(--tw-anim-dialog-duration,.35s) ease allow-discrete, display var(--tw-anim-dialog-duration,.35s) ease allow-discrete}.animate-dialog[open]{opacity:1;translate:0;scale:1}.animate-dialog[open].is-closing,.animate-dialog[open].is-opening{opacity:var(--tw-anim-dialog-start-opacity,0);translate:var(--tw-anim-dialog-start-translate,0 1.5rem);scale:var(--tw-anim-dialog-start-scale,.96)}@starting-style{.animate-dialog[open]{opacity:var(--tw-anim-dialog-start-opacity,0);translate:var(--tw-anim-dialog-start-translate,0 1.5rem);scale:var(--tw-anim-dialog-start-scale,.96)}}.animate-dialog::backdrop{opacity:0;background:var(--tw-anim-dialog-backdrop-background,#0f172a94);-webkit-backdrop-filter:var(--tw-anim-dialog-backdrop-filter,blur(8px));backdrop-filter:var(--tw-anim-dialog-backdrop-filter,blur(8px));transition:opacity var(--tw-anim-dialog-duration,.35s) ease, overlay var(--tw-anim-dialog-duration,.35s) ease allow-discrete, display var(--tw-anim-dialog-duration,.35s) ease allow-discrete}.animate-dialog[open]::backdrop{opacity:1}.animate-dialog[open].is-closing::backdrop,.animate-dialog[open].is-opening::backdrop{opacity:0}@starting-style{.animate-dialog[open]::backdrop{opacity:0}}}@media (prefers-reduced-motion:reduce){.shimmer{-webkit-text-fill-color:currentColor;background-image:none;animation:none}}:host{--background:oklch(100% 0 0);--foreground:oklch(14.8% .004 228.8);--card:oklch(100% 0 0);--card-foreground:oklch(14.8% .004 228.8);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.8% .004 228.8);--primary:oklch(84.1% .238 128.85);--link:oklch(45.3% .124 130.933);--primary-foreground:oklch(40.5% .101 131.063);--secondary:oklch(96.7% .001 286.375);--secondary-foreground:oklch(21% .006 285.885);--muted:oklch(96.3% .002 197.1);--muted-foreground:oklch(56% .021 213.5);--accent:oklch(96.3% .002 197.1);--accent-foreground:oklch(21.8% .008 223.9);--destructive:oklch(57.7% .245 27.325);--border:oklch(92.5% .005 214.3);--input:oklch(92.5% .005 214.3);--ring:oklch(72.3% .014 214.4);--chart-1:oklch(89.7% .196 126.665);--chart-2:oklch(76.8% .233 130.85);--chart-3:oklch(64.8% .2 131.684);--chart-4:oklch(53.2% .157 131.589);--chart-5:oklch(45.3% .124 130.933);--radius:.625rem;--sidebar:oklch(98.7% .002 197.1);--sidebar-foreground:oklch(14.8% .004 228.8);--sidebar-primary:oklch(64.8% .2 131.684);--sidebar-primary-foreground:oklch(98.6% .031 120.757);--sidebar-accent:oklch(96.3% .002 197.1);--sidebar-accent-foreground:oklch(21.8% .008 223.9);--sidebar-border:oklch(92.5% .005 214.3);--sidebar-ring:oklch(72.3% .014 214.4)}.dark{--background:oklch(14.8% .004 228.8);--foreground:oklch(98.7% .002 197.1);--card:oklch(21.8% .008 223.9);--card-foreground:oklch(98.7% .002 197.1);--popover:oklch(21.8% .008 223.9);--popover-foreground:oklch(98.7% .002 197.1);--primary:oklch(76.8% .233 130.85);--link:var(--primary);--primary-foreground:oklch(40.5% .101 131.063);--secondary:oklch(27.4% .006 286.033);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(27.5% .011 216.9);--muted-foreground:oklch(72.3% .014 214.4);--accent:oklch(27.5% .011 216.9);--accent-foreground:oklch(98.7% .002 197.1);--destructive:oklch(70.4% .191 22.216);--border:oklch(100% 0 0/.1);--input:oklch(100% 0 0/.15);--ring:oklch(56% .021 213.5);--chart-1:oklch(89.7% .196 126.665);--chart-2:oklch(76.8% .233 130.85);--chart-3:oklch(64.8% .2 131.684);--chart-4:oklch(53.2% .157 131.589);--chart-5:oklch(45.3% .124 130.933);--sidebar:oklch(21.8% .008 223.9);--sidebar-foreground:oklch(98.7% .002 197.1);--sidebar-primary:oklch(76.8% .233 130.85);--sidebar-primary-foreground:oklch(27.4% .072 132.109);--sidebar-accent:oklch(27.5% .011 216.9);--sidebar-accent-foreground:oklch(98.7% .002 197.1);--sidebar-border:oklch(100% 0 0/.1);--sidebar-ring:oklch(56% .021 213.5)}:host{--font-sans:ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;font-family:var(--font-sans);color:var(--foreground);-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5}.fb-or{transition:opacity .3s}[data-named] .fb-or{opacity:0}.fb-glow,.fb-halo{border-radius:inherit;z-index:-1;pointer-events:none;opacity:0;transition:opacity .3s;position:absolute;inset:-2px;overflow:hidden}.fb-halo{filter:blur(14px);inset:-3px}[data-glow] .fb-glow{opacity:1}[data-glow] .fb-halo{opacity:.75}.fb-glow:before,.fb-halo:before{content:\"\";aspect-ratio:1;background:conic-gradient(#0000,#ff3b30 4%,#ff9500 7%,#fc0 10%,#34c759 13%,#007aff 16%,#af52de 19%,#0000 23%);width:max(200%,480px);animation:4s linear infinite paused fb-spin;position:absolute;top:50%;left:50%;translate:-50% -50%}[data-glow] .fb-glow:before,[data-glow] .fb-halo:before{animation-play-state:running}.fb-glow:after{content:\"\";border-radius:inherit;background:var(--background);position:absolute;inset:2px}@keyframes fb-spin{to{rotate:360deg}}.fb-surface{animation:.25s ease-out backwards fb-expand}[data-leaving] .fb-surface{animation:.25s ease-in .15s both fb-collapse}@keyframes fb-expand{0%{clip-path:inset(0 0 0 calc(100% - 52px) round 9999px)}to{clip-path:inset(0 round 9999px)}}@keyframes fb-collapse{0%{clip-path:inset(0 round 9999px)}20%{opacity:1}to{clip-path:inset(0 0 0 calc(100% - 52px) round 9999px);opacity:0}}.selection-outline{z-index:-1;border:2px solid var(--chart-3);background:var(--primary);position:fixed}@supports (color:color-mix(in lab, red, red)){.selection-outline{background:color-mix(in oklch, var(--primary) 12%, transparent)}}.selection-outline{pointer-events:none;border-radius:4px}@media (prefers-reduced-motion:reduce){.fb-or,.fb-glow,.fb-halo{transition:none}.fb-glow:before,.fb-halo:before,.fb-surface,[data-leaving] .fb-surface{animation:none}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}@keyframes accordion-down{0%{height:0}to{height:var(--radix-accordion-content-height,var(--accordion-panel-height,auto))}}@keyframes accordion-up{0%{height:var(--radix-accordion-content-height,var(--accordion-panel-height,auto))}to{height:0}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-out{0%{opacity:1}to{opacity:0}}@keyframes fade-in-left{0%{opacity:0;transform:translate(20px)}to{opacity:1;transform:translate(0)}}@keyframes fade-out-right{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(20px)}}@keyframes flip-in-x{0%{opacity:0;transform:rotateY(90deg)}to{opacity:1;transform:rotateY(0)}}\n";
19
+ //#endregion
20
+ //#region ../ui/src/components/badge.tsx
21
+ const badgeVariants = cva("group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!", {
22
+ variants: { variant: {
23
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
24
+ secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
25
+ destructive: "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
26
+ outline: "border-border bg-input/30 text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
27
+ ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
28
+ link: "text-primary underline-offset-4 hover:underline"
29
+ } },
30
+ defaultVariants: { variant: "default" }
31
+ });
32
+ function Badge({ className, variant = "default", render, ...props }) {
33
+ return useRender({
34
+ defaultTagName: "span",
35
+ props: mergeProps({ className: cn(badgeVariants({ variant }), className) }, props),
36
+ render,
37
+ state: {
38
+ slot: "badge",
39
+ variant
40
+ }
41
+ });
42
+ }
43
+ //#endregion
44
+ //#region src/frame.ts
45
+ const PAINT_INTERVAL_MS = 32;
46
+ function createFrameLoop(signal) {
47
+ const callbacks = /* @__PURE__ */ new Set();
48
+ let last = 0;
49
+ let frame = requestAnimationFrame(function paint(time) {
50
+ if (time - last > PAINT_INTERVAL_MS) {
51
+ last = time;
52
+ for (const callback of callbacks) callback();
53
+ }
54
+ frame = requestAnimationFrame(paint);
55
+ });
56
+ signal.addEventListener("abort", () => cancelAnimationFrame(frame));
57
+ return { add(callback) {
58
+ callbacks.add(callback);
59
+ return () => callbacks.delete(callback);
60
+ } };
61
+ }
62
+ const FrameContext = createContext(null);
63
+ function useFrame(callback) {
64
+ const loop = useContext(FrameContext);
65
+ const latest = useRef(callback);
66
+ useLayoutEffect(() => {
67
+ latest.current = callback;
68
+ callback();
69
+ });
70
+ useEffect(() => loop?.add(() => latest.current()), [loop]);
71
+ }
72
+ //#endregion
73
+ //#region src/badges.tsx
74
+ const shownAnchor = (thread) => thread.suggestion?.anchor ?? thread.anchor;
75
+ function Badges({ groups, activeId, open }) {
76
+ const nodes = useRef(/* @__PURE__ */ new Map());
77
+ const outline = useRef(null);
78
+ const [hovered, setHovered] = useState(null);
79
+ useFrame(() => {
80
+ const boxes = new Map(groups.map((group) => {
81
+ const box = anchorBox(group.anchor, group.target);
82
+ return [group.key, box && !isCovered(group.target, box) ? box : null];
83
+ }));
84
+ for (const [key, box] of boxes) {
85
+ const node = nodes.current.get(key);
86
+ if (!node) continue;
87
+ node.hidden = !box;
88
+ if (!box) continue;
89
+ const x = Math.max(0, Math.min(innerWidth - 30, box.x + box.width - 8));
90
+ node.style.left = `${x}px`;
91
+ node.style.top = `${Math.max(0, box.y - 12)}px`;
92
+ }
93
+ const lit = groups.find((group) => group.key === hovered) ?? groups.find((group) => group.threads.some((thread) => thread.id === activeId));
94
+ if (outline.current) placeBox(outline.current, (lit && boxes.get(lit.key)) ?? null);
95
+ });
96
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
97
+ ref: outline,
98
+ hidden: true,
99
+ className: "selection-outline"
100
+ }), groups.map((group) => {
101
+ const [first] = group.threads;
102
+ if (!first) return null;
103
+ const many = group.threads.length > 1;
104
+ return /* @__PURE__ */ jsxs("button", {
105
+ type: "button",
106
+ ref: (node) => {
107
+ if (node) nodes.current.set(group.key, node);
108
+ else nodes.current.delete(group.key);
109
+ },
110
+ hidden: true,
111
+ "aria-label": (many ? `${group.threads.length} comment threads` : `Comment ${first.number}`) + (group.moved ? ", moved" : ""),
112
+ onClick: () => open(group.threads),
113
+ onPointerEnter: () => setHovered(group.key),
114
+ onPointerLeave: () => setHovered((key) => key === group.key ? null : key),
115
+ className: cn("pointer-events-auto fixed grid h-7 min-w-7 cursor-pointer place-items-center rounded-[14px_14px_14px_3px] border-2 border-background bg-primary px-1.5 text-xs font-bold text-primary-foreground shadow-md hover:bg-primary/80", group.moved && "outline-2 outline-offset-2 outline-primary outline-dashed"),
116
+ children: [many ? group.threads.length : first.number, group.moved && /* @__PURE__ */ jsx(Badge, {
117
+ variant: "secondary",
118
+ className: "absolute top-1/2 right-full mr-1.5 -translate-y-1/2 shadow-md",
119
+ children: "Moved"
120
+ })]
121
+ }, group.key);
122
+ })] });
123
+ }
124
+ //#endregion
125
+ //#region ../ui/src/components/button.tsx
126
+ const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center rounded-4xl border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-[3px] 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", {
127
+ variants: {
128
+ variant: {
129
+ default: "bg-primary text-primary-foreground hover:bg-primary/80",
130
+ outline: "border-border bg-input/30 hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
131
+ secondary: "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
132
+ ghost: "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
133
+ destructive: "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",
134
+ link: "text-primary underline-offset-4 hover:underline"
135
+ },
136
+ size: {
137
+ default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
138
+ xs: "h-6 gap-1 px-2.5 text-xs has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3",
139
+ sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
140
+ lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
141
+ icon: "size-9",
142
+ "icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
143
+ "icon-sm": "size-8",
144
+ "icon-lg": "size-10"
145
+ }
146
+ },
147
+ defaultVariants: {
148
+ variant: "default",
149
+ size: "default"
150
+ }
151
+ });
152
+ function Button$1({ className, variant = "default", size = "default", ...props }) {
153
+ return /* @__PURE__ */ jsx(Button, {
154
+ "data-slot": "button",
155
+ className: cn(buttonVariants({
156
+ variant,
157
+ size,
158
+ className
159
+ })),
160
+ ...props
161
+ });
162
+ }
163
+ //#endregion
164
+ //#region ../ui/src/components/input.tsx
165
+ function Input$1({ className, type, ...props }) {
166
+ return /* @__PURE__ */ jsx(Input, {
167
+ type,
168
+ "data-slot": "input",
169
+ className: cn("h-9 w-full min-w-0 rounded-4xl border border-input bg-input/30 px-3 py-1 text-base transition-colors outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-[3px] aria-invalid:ring-destructive/20 md:text-sm dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className),
170
+ ...props
171
+ });
172
+ }
173
+ //#endregion
174
+ //#region src/logo.tsx
175
+ const WORDMARK = "M7 0V-71H56V-58H14L23 -67V-34L14 -41H55V-28H14L23 -35V0ZM78 1Q69 1 64 -3Q59 -7 59 -13Q59 -20 63 -24Q68 -28 77 -30L94 -33Q94 -39 92 -41Q89 -44 85 -44Q81 -44 78 -42Q76 -40 75 -36L60 -37Q61 -46 68 -50Q74 -55 85 -55Q97 -55 103 -49Q109 -43 109 -32V-14Q109 -12 110 -11Q110 -10 112 -10H113V0Q113 0 111 0Q110 1 108 1Q105 1 102 -1Q99 -2 98 -4Q96 -7 96 -12L97 -11Q96 -7 94 -5Q91 -2 87 0Q83 1 78 1ZM81 -9Q85 -9 88 -11Q91 -12 92 -15Q94 -18 94 -21V-24L82 -21Q78 -21 76 -19Q74 -17 74 -15Q74 -12 76 -11Q78 -9 81 -9ZM141 1Q132 1 127 -1Q121 -3 118 -8Q115 -12 115 -17L130 -17Q131 -14 133 -12Q136 -9 141 -9Q145 -9 147 -11Q149 -12 149 -15Q149 -16 148 -18Q148 -19 145 -20Q143 -20 138 -21Q130 -23 125 -25Q120 -27 118 -30Q116 -33 116 -38Q116 -45 122 -50Q128 -55 140 -55Q148 -55 153 -52Q158 -50 161 -46Q164 -42 164 -36L149 -36Q149 -38 148 -40Q146 -42 144 -43Q143 -44 140 -44Q136 -44 134 -43Q132 -41 132 -38Q132 -36 133 -35Q134 -34 136 -33Q138 -32 142 -32Q150 -30 155 -28Q160 -26 162 -23Q165 -20 165 -15Q165 -10 162 -6Q159 -3 153 -1Q148 1 141 1ZM192 0Q184 0 180 -4Q176 -8 176 -16V-66H191V-18Q191 -14 193 -13Q194 -11 198 -11H205V0ZM167 -42V-54H205V-42ZM242 1Q236 1 232 -1Q228 -4 226 -8L226 0H211V-71H226V-46Q228 -50 233 -52Q237 -55 242 -55Q249 -55 254 -51Q259 -48 262 -42Q264 -35 264 -27Q264 -18 262 -12Q259 -6 254 -2Q249 1 242 1ZM238 -10Q243 -10 246 -15Q249 -19 249 -27Q249 -35 246 -39Q243 -43 238 -43Q234 -43 232 -41Q229 -39 228 -36Q226 -32 226 -27Q226 -22 228 -18Q229 -14 232 -12Q234 -10 238 -10ZM288 1Q279 1 274 -3Q269 -7 269 -13Q269 -20 273 -24Q278 -28 287 -30L304 -33Q304 -39 301 -41Q299 -44 295 -44Q290 -44 288 -42Q286 -40 285 -36L270 -37Q271 -46 278 -50Q284 -55 295 -55Q307 -55 313 -49Q319 -43 319 -32V-14Q319 -12 320 -11Q320 -10 322 -10H323V0Q323 0 321 0Q319 1 318 1Q315 1 312 -1Q309 -2 308 -4Q306 -7 306 -12L307 -11Q306 -7 304 -5Q301 -2 297 0Q293 1 288 1ZM291 -9Q295 -9 298 -11Q301 -12 302 -15Q304 -18 304 -21V-24L292 -21Q288 -21 286 -19Q284 -17 284 -15Q284 -12 286 -11Q288 -9 291 -9ZM352 1Q344 1 338 -2Q332 -6 328 -12Q325 -18 325 -27Q325 -35 328 -42Q332 -48 338 -51Q344 -55 352 -55Q359 -55 365 -52Q370 -50 374 -45Q377 -40 378 -34L363 -33Q362 -38 359 -41Q356 -43 352 -43Q346 -43 343 -39Q340 -35 340 -27Q340 -19 343 -15Q346 -10 352 -10Q356 -10 359 -13Q362 -16 363 -21L378 -20Q377 -14 374 -9Q371 -4 365 -1Q359 1 352 1ZM384 0V-71H399V-32L419 -54H437L416 -32L438 0H421L406 -23L399 -15V0ZM442 0V-54H456L457 -38L456 -38Q457 -46 460 -50Q463 -54 469 -54H474V-41H469Q465 -41 462 -40Q460 -39 458 -37Q457 -34 457 -30V0Z";
176
+ function Logo({ className }) {
177
+ return /* @__PURE__ */ jsxs("svg", {
178
+ viewBox: "0 -71 567 72",
179
+ role: "img",
180
+ "aria-label": "Fastbackr",
181
+ className,
182
+ children: [/* @__PURE__ */ jsx("circle", {
183
+ cx: "28",
184
+ cy: "-35.5",
185
+ r: "28",
186
+ fill: "var(--primary)"
187
+ }), /* @__PURE__ */ jsx("path", {
188
+ transform: "translate(93 0)",
189
+ d: WORDMARK,
190
+ fill: "currentColor"
191
+ })]
192
+ });
193
+ }
194
+ //#endregion
195
+ //#region src/bar.tsx
196
+ const GLOW_MS = 10250;
197
+ const FLASH_MS = 2e3;
198
+ const ANONYMOUS_NAME = "Anonymous";
199
+ const CLOSE_TITLE = "Close Fastbackr in this browser. Press f three times to bring it back.";
200
+ function Bar(props) {
201
+ const [leaving, setLeaving] = useState(false);
202
+ const [flashing, setFlashing] = useState(false);
203
+ const seenFlash = useRef(props.flashRequest);
204
+ useEffect(() => {
205
+ if (props.flashRequest === seenFlash.current) return;
206
+ seenFlash.current = props.flashRequest;
207
+ setFlashing(true);
208
+ const timer = setTimeout(() => setFlashing(false), FLASH_MS);
209
+ return () => clearTimeout(timer);
210
+ }, [props.flashRequest]);
211
+ const minimize = () => {
212
+ if (matchMedia("(prefers-reduced-motion: reduce)").matches) props.minimize();
213
+ else {
214
+ setLeaving(true);
215
+ props.showFab();
216
+ }
217
+ };
218
+ const shared = {
219
+ ...props,
220
+ minimize,
221
+ leaving,
222
+ flashing,
223
+ collapsed: props.minimize
224
+ };
225
+ return props.reviewer ? /* @__PURE__ */ jsx(SignedIn, {
226
+ ...shared,
227
+ reviewer: props.reviewer
228
+ }) : /* @__PURE__ */ jsx(SignedOut, { ...shared });
229
+ }
230
+ const BAR = "pointer-events-auto fixed right-4 bottom-4 flex max-w-[calc(100vw-2rem)] items-center gap-2 rounded-full p-2 sm:right-[22px] sm:bottom-[22px]";
231
+ const ENTER = "animate-fade-in-left animate-duration-250 animate-delay-250 motion-reduce:animate-none";
232
+ const LEAVE = "animate-fade-out-right animate-duration-150 motion-reduce:animate-none";
233
+ function navProps({ leaving, flashing }, glow = false) {
234
+ return {
235
+ "aria-label": "Fastbackr bar",
236
+ "data-leaving": leaving || void 0,
237
+ "data-glow": glow || flashing || void 0,
238
+ className: cn(BAR, leaving && "pointer-events-none")
239
+ };
240
+ }
241
+ function Glow({ leaving }) {
242
+ return /* @__PURE__ */ jsxs("div", {
243
+ "aria-hidden": "true",
244
+ className: cn("absolute inset-0 -z-1 rounded-full motion-reduce:animate-none", leaving ? "animate-fade-out animate-duration-150" : "animate-fade-in animate-duration-250 animate-delay-250"),
245
+ children: [/* @__PURE__ */ jsx("div", { className: "fb-halo" }), /* @__PURE__ */ jsx("div", { className: "fb-glow" })]
246
+ });
247
+ }
248
+ function Surface({ leaving, collapsed }) {
249
+ return /* @__PURE__ */ jsx("div", {
250
+ "aria-hidden": "true",
251
+ className: "fb-surface absolute inset-0 -z-10 rounded-full bg-background shadow-xl ring-1 ring-foreground/10",
252
+ onAnimationEnd: (event) => {
253
+ if (leaving && event.animationName === "fb-collapse" && event.target === event.currentTarget) collapsed();
254
+ }
255
+ });
256
+ }
257
+ function Author({ name, verified, strong = false }) {
258
+ return /* @__PURE__ */ jsxs("span", {
259
+ className: "inline-flex min-w-0 items-center gap-1.5",
260
+ children: [strong ? /* @__PURE__ */ jsx("strong", {
261
+ className: "truncate font-semibold",
262
+ children: name
263
+ }) : /* @__PURE__ */ jsx("span", {
264
+ className: "truncate",
265
+ children: name
266
+ }), !verified && /* @__PURE__ */ jsx(Badge, {
267
+ variant: "outline",
268
+ children: "guest"
269
+ })]
270
+ });
271
+ }
272
+ function WindowButtons({ minimize, close, size, className, iconClassName }) {
273
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button$1, {
274
+ variant: "ghost",
275
+ size,
276
+ className,
277
+ "aria-label": "Minimize",
278
+ title: "Minimize",
279
+ onClick: minimize,
280
+ children: /* @__PURE__ */ jsx(RiArrowDownSLine, {
281
+ "aria-hidden": "true",
282
+ className: iconClassName
283
+ })
284
+ }), /* @__PURE__ */ jsx(Button$1, {
285
+ variant: "ghost",
286
+ size,
287
+ className,
288
+ "aria-label": "Close",
289
+ title: CLOSE_TITLE,
290
+ onClick: close,
291
+ children: /* @__PURE__ */ jsx(RiCloseLine, {
292
+ "aria-hidden": "true",
293
+ className: iconClassName
294
+ })
295
+ })] });
296
+ }
297
+ const PILL = "h-4 rounded-full bg-background shadow-md ring-1 ring-foreground/10";
298
+ const TAB = `${PILL} hover:bg-muted`;
299
+ function TopRow(props) {
300
+ return /* @__PURE__ */ jsxs("div", {
301
+ className: cn("pointer-events-none absolute inset-x-0 bottom-[calc(100%+6px)] flex items-center justify-between gap-1 *:pointer-events-auto", props.leaving ? LEAVE : ENTER),
302
+ children: [/* @__PURE__ */ jsx("span", {
303
+ className: `${PILL} flex items-center px-1.5`,
304
+ children: /* @__PURE__ */ jsx(Logo, { className: "h-2.5 w-auto" })
305
+ }), /* @__PURE__ */ jsxs("span", {
306
+ className: "flex gap-1",
307
+ children: [props.signIn && /* @__PURE__ */ jsx(Button$1, {
308
+ variant: "ghost",
309
+ className: `${TAB} px-1.5 text-[10px]`,
310
+ onClick: props.signIn,
311
+ children: "Sign in"
312
+ }), /* @__PURE__ */ jsx(WindowButtons, {
313
+ ...props,
314
+ size: "icon-xs",
315
+ className: `${TAB} size-4`,
316
+ iconClassName: "size-3!"
317
+ })]
318
+ })]
319
+ });
320
+ }
321
+ function Identity({ reviewer, changeName }) {
322
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
323
+ "aria-hidden": "true",
324
+ className: "grid size-6 shrink-0 place-items-center rounded-full bg-muted text-xs font-semibold text-muted-foreground uppercase",
325
+ children: reviewer.name.trim().charAt(0) || "?"
326
+ }), /* @__PURE__ */ jsx("span", {
327
+ className: "truncate",
328
+ children: reviewer.name
329
+ })] });
330
+ const className = "max-w-40 gap-2 pr-3 pl-1.5";
331
+ return reviewer.verified ? /* @__PURE__ */ jsx("span", {
332
+ className: cn(className, "inline-flex h-9 min-w-0 items-center text-sm font-medium"),
333
+ title: `Signed in as ${reviewer.name}`,
334
+ children: content
335
+ }) : /* @__PURE__ */ jsxs(Button$1, {
336
+ variant: "ghost",
337
+ className: cn(className, "min-w-0"),
338
+ title: "Change name",
339
+ "aria-label": `${reviewer.name}, change name`,
340
+ onClick: changeName,
341
+ children: [content, /* @__PURE__ */ jsx(RiPencilLine, {
342
+ "aria-hidden": "true",
343
+ className: "text-muted-foreground"
344
+ })]
345
+ });
346
+ }
347
+ function SignedIn(props) {
348
+ const { reviewer, count, leaving } = props;
349
+ return /* @__PURE__ */ jsxs("nav", {
350
+ ...navProps(props),
351
+ children: [
352
+ /* @__PURE__ */ jsx(Surface, { ...props }),
353
+ /* @__PURE__ */ jsx(Glow, { leaving }),
354
+ /* @__PURE__ */ jsx(TopRow, {
355
+ leaving,
356
+ minimize: props.minimize,
357
+ close: props.close
358
+ }),
359
+ /* @__PURE__ */ jsxs("div", {
360
+ className: cn("flex min-w-0 items-center gap-2", leaving ? LEAVE : ENTER),
361
+ children: [
362
+ /* @__PURE__ */ jsx(Identity, {
363
+ reviewer,
364
+ changeName: props.changeName
365
+ }),
366
+ /* @__PURE__ */ jsxs(Button$1, {
367
+ variant: "outline",
368
+ onClick: props.toggleDrawer,
369
+ "aria-label": `Feedback, ${count} open on this page`,
370
+ children: [
371
+ /* @__PURE__ */ jsx(RiChat3Line, { "aria-hidden": "true" }),
372
+ "Feedback",
373
+ count > 0 && /* @__PURE__ */ jsx(Badge, {
374
+ variant: "outline",
375
+ className: "-mr-1 bg-background tabular-nums",
376
+ children: count
377
+ })
378
+ ]
379
+ }),
380
+ /* @__PURE__ */ jsx(Button$1, {
381
+ size: "icon",
382
+ "aria-label": "New comment",
383
+ "aria-keyshortcuts": "c",
384
+ title: "New comment (c)",
385
+ onClick: props.comment,
386
+ children: /* @__PURE__ */ jsx(RiAddLine, {
387
+ "aria-hidden": "true",
388
+ className: "size-6"
389
+ })
390
+ })
391
+ ]
392
+ })
393
+ ]
394
+ });
395
+ }
396
+ function SignedOut(props) {
397
+ const { leaving } = props;
398
+ const [name, setName] = useState(props.guestName === ANONYMOUS_NAME ? "" : props.guestName);
399
+ const [busy, setBusy] = useState(false);
400
+ const [typed, setTyped] = useState(false);
401
+ const input = useRef(null);
402
+ const named = Boolean(name.trim());
403
+ const [glowed, setGlowed] = useState(false);
404
+ useEffect(() => {
405
+ const timer = setTimeout(() => setGlowed(true), GLOW_MS);
406
+ return () => clearTimeout(timer);
407
+ }, []);
408
+ const go = (as) => {
409
+ setBusy(true);
410
+ props.continueAsGuest(as).finally(() => setBusy(false));
411
+ };
412
+ return /* @__PURE__ */ jsxs("nav", {
413
+ ...navProps(props, !named && !glowed),
414
+ "data-named": named || void 0,
415
+ children: [
416
+ /* @__PURE__ */ jsx(Surface, { ...props }),
417
+ /* @__PURE__ */ jsx(Glow, { leaving }),
418
+ /* @__PURE__ */ jsx(TopRow, {
419
+ leaving,
420
+ minimize: props.minimize,
421
+ close: props.close,
422
+ signIn: props.canSignIn ? props.signIn : void 0
423
+ }),
424
+ /* @__PURE__ */ jsxs("form", {
425
+ className: cn("flex items-center gap-2", leaving ? LEAVE : ENTER),
426
+ onSubmit: (event) => {
427
+ event.preventDefault();
428
+ if (named) go(name);
429
+ },
430
+ children: [
431
+ /* @__PURE__ */ jsx(Input$1, {
432
+ name: "name",
433
+ "aria-label": "Your name",
434
+ autoComplete: "name",
435
+ placeholder: "Comment with your name",
436
+ maxLength: LIMITS.reviewerNameChars,
437
+ ref: input,
438
+ value: name,
439
+ onChange: (event) => {
440
+ setName(event.target.value);
441
+ setTyped(true);
442
+ },
443
+ className: "w-48 flex-1 sm:w-52"
444
+ }),
445
+ /* @__PURE__ */ jsx("span", {
446
+ className: "fb-or text-xs text-muted-foreground",
447
+ children: "or"
448
+ }),
449
+ /* @__PURE__ */ jsx("div", {
450
+ className: "grid w-36 perspective-normal",
451
+ children: /* @__PURE__ */ jsx("div", {
452
+ className: cn("flex gap-1.5", typed && "animate-flip-in-x animate-duration-300 motion-reduce:animate-none"),
453
+ children: named ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button$1, {
454
+ type: "submit",
455
+ className: "flex-1 font-semibold",
456
+ disabled: busy,
457
+ children: "Save"
458
+ }), /* @__PURE__ */ jsx(Button$1, {
459
+ type: "button",
460
+ variant: "destructive",
461
+ size: "icon",
462
+ "aria-label": "Clear name",
463
+ title: "Clear name",
464
+ disabled: busy,
465
+ onClick: () => {
466
+ setName("");
467
+ input.current?.focus();
468
+ },
469
+ children: /* @__PURE__ */ jsx(RiCloseLine, { "aria-hidden": "true" })
470
+ })] }) : /* @__PURE__ */ jsx(Button$1, {
471
+ type: "button",
472
+ className: "flex-1 font-semibold",
473
+ disabled: busy,
474
+ onClick: () => go(ANONYMOUS_NAME),
475
+ children: "Anonymously"
476
+ })
477
+ }, named ? "named" : "anonymous")
478
+ })
479
+ ]
480
+ })
481
+ ]
482
+ });
483
+ }
484
+ //#endregion
485
+ //#region ../ui/src/components/card.tsx
486
+ function Card({ className, size = "default", ...props }) {
487
+ return /* @__PURE__ */ jsx("div", {
488
+ "data-slot": "card",
489
+ "data-size": size,
490
+ className: cn("group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-2xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(6)] has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(4)] *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl", className),
491
+ ...props
492
+ });
493
+ }
494
+ //#endregion
495
+ //#region ../ui/src/components/checkbox.tsx
496
+ function Checkbox$1({ className, ...props }) {
497
+ return /* @__PURE__ */ jsx(Checkbox.Root, {
498
+ "data-slot": "checkbox",
499
+ className: cn("peer relative flex size-4 shrink-0 items-center justify-center rounded-[6px] border border-input transition-shadow outline-none group-has-disabled/field:opacity-50 group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-[3px] aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground group-has-[:focus-visible]/field-label:data-checked:border-primary dark:data-checked:bg-primary", className),
500
+ ...props,
501
+ children: /* @__PURE__ */ jsx(Checkbox.Indicator, {
502
+ "data-slot": "checkbox-indicator",
503
+ className: "grid place-content-center text-current transition-none [&>svg]:size-3.5",
504
+ children: /* @__PURE__ */ jsx(RiCheckLine, {})
505
+ })
506
+ });
507
+ }
508
+ //#endregion
509
+ //#region ../ui/src/components/label.tsx
510
+ function Label({ className, ...props }) {
511
+ return /* @__PURE__ */ jsx("label", {
512
+ "data-slot": "label",
513
+ className: cn("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", className),
514
+ ...props
515
+ });
516
+ }
517
+ //#endregion
518
+ //#region ../ui/src/components/textarea.tsx
519
+ function Textarea({ className, ...props }) {
520
+ return /* @__PURE__ */ jsx("textarea", {
521
+ "data-slot": "textarea",
522
+ className: cn("flex field-sizing-content min-h-16 w-full resize-none rounded-xl border border-input bg-input/30 px-3 py-3 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-[3px] aria-invalid:ring-destructive/20 md:text-sm dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className),
523
+ ...props
524
+ });
525
+ }
526
+ //#endregion
527
+ //#region src/panel.tsx
528
+ const PANEL = "pointer-events-auto fixed w-[350px] max-w-[calc(100vw-24px)] px-4 shadow-xl";
529
+ function PanelHeading({ eyebrow, title, children }) {
530
+ return /* @__PURE__ */ jsxs("div", { children: [
531
+ /* @__PURE__ */ jsx("div", {
532
+ className: "text-[10px] tracking-widest text-muted-foreground uppercase",
533
+ children: eyebrow
534
+ }),
535
+ /* @__PURE__ */ jsx("h2", {
536
+ className: "text-base font-semibold",
537
+ children: title
538
+ }),
539
+ children
540
+ ] });
541
+ }
542
+ const sendOnModEnter = (send) => (event) => {
543
+ if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
544
+ event.preventDefault();
545
+ send();
546
+ }
547
+ };
548
+ //#endregion
549
+ //#region src/composer.tsx
550
+ function draftKey(pageKey, target) {
551
+ const anchor = captureAnchor(target);
552
+ return `new:${pageKey}:${anchor.stableId ?? anchor.elementId ?? anchor.selectorCandidates[0]}`;
553
+ }
554
+ function Composer(props) {
555
+ const { selection, drafts, pageKey } = props;
556
+ const { target, region } = selection;
557
+ const key = useMemo(() => draftKey(pageKey, target), [pageKey, target]);
558
+ const [body, setBody] = useState(() => drafts.get(key) ?? "");
559
+ const [saving, setSaving] = useState(false);
560
+ const [screenshot, setScreenshot] = useState(true);
561
+ const panel = useRef(null);
562
+ const textarea = useRef(null);
563
+ useEffect(() => {
564
+ setBody(drafts.get(key) ?? "");
565
+ textarea.current?.focus();
566
+ }, [drafts, key]);
567
+ useFrame(() => {
568
+ if (panel.current) position(panel.current, regionBox(target, region), Boolean(region));
569
+ });
570
+ const write = (value) => {
571
+ setBody(value);
572
+ drafts.set(key, value);
573
+ };
574
+ const submit = async () => {
575
+ const text = body.trim();
576
+ if (!text) {
577
+ textarea.current?.focus();
578
+ return;
579
+ }
580
+ setSaving(true);
581
+ try {
582
+ if (await props.save(selection, text, screenshot)) {
583
+ drafts.delete(key);
584
+ props.close();
585
+ }
586
+ } finally {
587
+ setSaving(false);
588
+ }
589
+ };
590
+ const [first] = props.existing;
591
+ const plural = props.existing.length === 1 ? "" : "s";
592
+ return /* @__PURE__ */ jsxs(Card, {
593
+ ref: panel,
594
+ size: "sm",
595
+ "aria-label": "New comment",
596
+ className: PANEL,
597
+ children: [
598
+ /* @__PURE__ */ jsxs("div", {
599
+ className: "flex items-center justify-between gap-2",
600
+ children: [/* @__PURE__ */ jsx("h2", {
601
+ className: "text-base font-semibold",
602
+ children: "New comment"
603
+ }), /* @__PURE__ */ jsx(Button$1, {
604
+ variant: "ghost",
605
+ size: "icon-xs",
606
+ className: "-mr-1.5",
607
+ "aria-label": "Close",
608
+ title: "Close",
609
+ onClick: props.close,
610
+ children: /* @__PURE__ */ jsx(RiCloseLine, { "aria-hidden": "true" })
611
+ })]
612
+ }),
613
+ first && /* @__PURE__ */ jsxs(Button$1, {
614
+ variant: "ghost",
615
+ className: "self-start",
616
+ onClick: () => {
617
+ props.openThread(first.id);
618
+ props.close();
619
+ },
620
+ children: [
621
+ "Read ",
622
+ props.existing.length,
623
+ " existing comment",
624
+ plural
625
+ ]
626
+ }),
627
+ /* @__PURE__ */ jsx(Textarea, {
628
+ ref: textarea,
629
+ "aria-label": "Your comment",
630
+ placeholder: "What could be better?",
631
+ maxLength: LIMITS.bodyChars,
632
+ value: body,
633
+ onChange: (event) => write(event.target.value),
634
+ onKeyDown: sendOnModEnter(() => void submit()),
635
+ className: "min-h-28"
636
+ }),
637
+ /* @__PURE__ */ jsxs("div", {
638
+ className: "flex items-center justify-between gap-2",
639
+ children: [props.canScreenshot && /* @__PURE__ */ jsxs(Label, {
640
+ className: "text-xs font-normal text-muted-foreground",
641
+ children: [/* @__PURE__ */ jsx(Checkbox$1, {
642
+ checked: screenshot,
643
+ onCheckedChange: (checked) => setScreenshot(checked)
644
+ }), "Take screenshot"]
645
+ }), /* @__PURE__ */ jsx(Button$1, {
646
+ className: "ml-auto",
647
+ disabled: saving,
648
+ onClick: () => void submit(),
649
+ children: "Save"
650
+ })]
651
+ })
652
+ ]
653
+ });
654
+ }
655
+ //#endregion
656
+ //#region src/controller.ts
657
+ const ERROR_MS = 6e3;
658
+ const RELOCATE_IDLE_MS = 2e3;
659
+ var FeedbackController = class {
660
+ state;
661
+ options;
662
+ signal;
663
+ tokens;
664
+ api;
665
+ picker;
666
+ listeners = /* @__PURE__ */ new Set();
667
+ resolutions = /* @__PURE__ */ new Map();
668
+ pendingComment = false;
669
+ pageRequest = 0;
670
+ listRequest = 0;
671
+ detailRequest = 0;
672
+ errorTimer = 0;
673
+ relocated = /* @__PURE__ */ new Set();
674
+ relocateTimer = 0;
675
+ constructor(options, layer, signal) {
676
+ this.options = options;
677
+ this.signal = signal;
678
+ this.state = {
679
+ reviewer: null,
680
+ guestName: "",
681
+ page: pageContext(options),
682
+ threads: [],
683
+ groups: [],
684
+ composer: null,
685
+ conversation: null,
686
+ drawer: {
687
+ open: false,
688
+ status: "open",
689
+ page: "",
690
+ list: { items: [] }
691
+ },
692
+ error: null
693
+ };
694
+ this.tokens = new TokenSource({
695
+ getToken: options.getToken,
696
+ onChange: (reviewer) => this.reviewerChanged(reviewer)
697
+ });
698
+ this.api = new ApiClient(options.endpoint, this.tokens);
699
+ this.picker = new Selection(layer, (target, point, region) => this.select(target, point, region), () => {});
700
+ layer.follow(() => this.updateBadges(this.state.threads), signal);
701
+ const restoreHistory = watchNavigation(() => this.navigate(), signal);
702
+ signal.addEventListener("abort", () => {
703
+ restoreHistory();
704
+ this.picker.destroy();
705
+ clearTimeout(this.errorTimer);
706
+ clearTimeout(this.relocateTimer);
707
+ });
708
+ this.set({ guestName: this.tokens.guest()?.name ?? "" });
709
+ this.connect();
710
+ }
711
+ subscribe = (listener) => {
712
+ this.listeners.add(listener);
713
+ return () => this.listeners.delete(listener);
714
+ };
715
+ getSnapshot = () => this.state;
716
+ set(patch) {
717
+ if (this.signal.aborted) return;
718
+ this.state = {
719
+ ...this.state,
720
+ ...patch
721
+ };
722
+ for (const listener of this.listeners) listener();
723
+ }
724
+ setDrawer(patch) {
725
+ this.set({ drawer: {
726
+ ...this.state.drawer,
727
+ ...patch
728
+ } });
729
+ }
730
+ closedDrawer() {
731
+ return {
732
+ ...this.state.drawer,
733
+ open: false
734
+ };
735
+ }
736
+ showError = (message) => {
737
+ clearTimeout(this.errorTimer);
738
+ this.set({ error: {
739
+ message,
740
+ id: (this.state.error?.id ?? 0) + 1
741
+ } });
742
+ this.errorTimer = window.setTimeout(() => this.set({ error: null }), ERROR_MS);
743
+ };
744
+ failed(error) {
745
+ if (this.signal.aborted) return;
746
+ if (error instanceof DOMException && error.name === "AbortError") return;
747
+ this.showError(error instanceof Error ? error.message : "Feedback is unavailable. Try again.");
748
+ }
749
+ async connect() {
750
+ try {
751
+ await this.tokens.token();
752
+ } catch (error) {
753
+ this.failed(error);
754
+ }
755
+ }
756
+ reviewerChanged(reviewer) {
757
+ if (this.signal.aborted) return;
758
+ const before = this.state.reviewer;
759
+ this.set({
760
+ reviewer,
761
+ guestName: this.tokens.guest()?.name ?? ""
762
+ });
763
+ if (!reviewer) {
764
+ this.signedOut();
765
+ return;
766
+ }
767
+ if (this.pendingComment) this.startSelection();
768
+ if (before?.id === reviewer.id && before.verified === reviewer.verified) return;
769
+ this.signedIn(!before);
770
+ }
771
+ async signedIn(arriving) {
772
+ await this.refreshAnchors();
773
+ if (this.state.drawer.open) this.loadDrawer();
774
+ if (arriving) {
775
+ const id = consumeThreadLink();
776
+ if (id) {
777
+ this.setDrawer({ open: true });
778
+ await this.openThread(id, true);
779
+ }
780
+ }
781
+ }
782
+ signedOut() {
783
+ this.picker.clear();
784
+ this.resolutions.clear();
785
+ this.forgetRelocations();
786
+ this.set({
787
+ threads: [],
788
+ groups: [],
789
+ composer: null,
790
+ conversation: null,
791
+ drawer: this.closedDrawer()
792
+ });
793
+ }
794
+ continueAsGuest = async (name) => {
795
+ try {
796
+ if (!await this.tokens.continueAsGuest(name)) this.showError(this.options.signIn ? "This site does not take guest comments. Sign in to comment." : "This site does not take guest comments.");
797
+ } catch (error) {
798
+ this.failed(error);
799
+ }
800
+ };
801
+ changeName = () => this.tokens.forgetGuestName();
802
+ signIn = async () => {
803
+ rememberVisible(true);
804
+ try {
805
+ await this.options.signIn?.();
806
+ } catch (error) {
807
+ this.failed(error);
808
+ return;
809
+ }
810
+ if (this.signal.aborted) return;
811
+ this.tokens.invalidate();
812
+ await this.connect();
813
+ };
814
+ comment = () => {
815
+ this.pendingComment = true;
816
+ if (this.state.reviewer) this.startSelection();
817
+ };
818
+ startSelection = () => {
819
+ if (!this.state.reviewer) return;
820
+ this.pendingComment = false;
821
+ this.closePanels();
822
+ this.picker.start();
823
+ };
824
+ select(target, point, region) {
825
+ if (this.tokens.features.screenshots) preloadScreenshot();
826
+ this.set({ composer: region ? {
827
+ target,
828
+ point,
829
+ region
830
+ } : {
831
+ target,
832
+ point
833
+ } });
834
+ }
835
+ closeComposer = () => {
836
+ this.picker.clear();
837
+ this.set({ composer: null });
838
+ };
839
+ closePanels = () => {
840
+ this.picker.clear();
841
+ this.detailRequest++;
842
+ this.set({
843
+ composer: null,
844
+ conversation: null,
845
+ drawer: this.closedDrawer()
846
+ });
847
+ };
848
+ existing(target) {
849
+ return this.state.threads.filter((thread) => this.resolutions.get(thread.id)?.element === target);
850
+ }
851
+ get canScreenshot() {
852
+ return this.tokens.features.screenshots;
853
+ }
854
+ save = async (selection, body, screenshot) => {
855
+ const { target, point, region } = selection;
856
+ const anchor = captureAnchor(target, point, region);
857
+ const image = screenshot && this.canScreenshot ? captureScreenshot(region ? {
858
+ target,
859
+ region
860
+ } : { target }) : null;
861
+ let thread;
862
+ try {
863
+ thread = await this.api.createThread({
864
+ page: this.state.page,
865
+ anchor,
866
+ body
867
+ }, this.signal);
868
+ } catch (error) {
869
+ this.failed(error);
870
+ return false;
871
+ }
872
+ this.refreshAnchors();
873
+ if (image) this.uploadScreenshot(thread.id, image);
874
+ return true;
875
+ };
876
+ async uploadScreenshot(id, screenshot) {
877
+ try {
878
+ const image = await screenshot;
879
+ if (!image || this.signal.aborted) return;
880
+ await this.api.uploadScreenshot(id, image, this.signal);
881
+ } catch {}
882
+ }
883
+ screenshot = (id, signal) => this.api.getScreenshot(id, signal);
884
+ navigate() {
885
+ const next = pageContext(this.options);
886
+ if (next.key === this.state.page.key) return;
887
+ this.picker.clear();
888
+ this.detailRequest++;
889
+ this.resolutions.clear();
890
+ this.forgetRelocations();
891
+ this.set({
892
+ page: next,
893
+ composer: null,
894
+ conversation: null,
895
+ threads: [],
896
+ groups: []
897
+ });
898
+ if (this.state.reviewer) {
899
+ this.refreshAnchors();
900
+ if (this.state.drawer.open) this.loadDrawer();
901
+ }
902
+ }
903
+ async refreshAnchors() {
904
+ if (!this.state.reviewer) return;
905
+ const generation = ++this.pageRequest;
906
+ try {
907
+ const result = await this.api.listThreads({
908
+ status: "open",
909
+ page: this.state.page.key
910
+ }, this.signal);
911
+ if (generation !== this.pageRequest || this.signal.aborted) return;
912
+ this.updateBadges(result.items);
913
+ } catch (error) {
914
+ this.failed(error);
915
+ }
916
+ }
917
+ updateBadges(threads) {
918
+ this.resolutions = /* @__PURE__ */ new Map();
919
+ const groups = /* @__PURE__ */ new Map();
920
+ for (const thread of threads) {
921
+ const anchor = shownAnchor(thread);
922
+ const found = resolveAnchor(anchor);
923
+ this.resolutions.set(thread.id, found);
924
+ if (!found.element) continue;
925
+ const areas = groups.get(found.element) ?? /* @__PURE__ */ new Map();
926
+ const area = JSON.stringify([anchor.region ?? null, Boolean(thread.suggestion)]);
927
+ areas.set(area, [...areas.get(area) ?? [], thread]);
928
+ groups.set(found.element, areas);
929
+ }
930
+ const badges = [];
931
+ for (const [target, areas] of groups) for (const grouped of areas.values()) {
932
+ const first = grouped[0];
933
+ if (first) badges.push({
934
+ key: grouped.map((thread) => thread.id).join(","),
935
+ target,
936
+ anchor: shownAnchor(first),
937
+ threads: grouped,
938
+ moved: Boolean(first.suggestion)
939
+ });
940
+ }
941
+ this.set({
942
+ threads,
943
+ groups: badges
944
+ });
945
+ this.scheduleRelocation();
946
+ }
947
+ forgetRelocations() {
948
+ clearTimeout(this.relocateTimer);
949
+ this.relocated.clear();
950
+ }
951
+ scheduleRelocation() {
952
+ clearTimeout(this.relocateTimer);
953
+ if (!this.state.reviewer?.verified) return;
954
+ this.relocateTimer = window.setTimeout(() => void this.relocate(), RELOCATE_IDLE_MS);
955
+ }
956
+ async relocate() {
957
+ const { reviewer, page, threads } = this.state;
958
+ if (!reviewer?.verified) return;
959
+ for (const thread of threads) {
960
+ if (this.signal.aborted || this.state.page.key !== page.key) return;
961
+ const state = this.resolutions.get(thread.id)?.state;
962
+ if (state !== "orphan" && state !== "ambiguous" || !thread.anchor.path || thread.suggestion || thread.pageKey !== page.key || this.relocated.has(thread.id)) continue;
963
+ this.relocated.add(thread.id);
964
+ const request = relocationRequest(thread);
965
+ if (!request) continue;
966
+ try {
967
+ const { suggestion } = await this.api.relocate(thread.id, request, this.signal);
968
+ if (!suggestion || this.state.page.key !== page.key) continue;
969
+ this.patchThread(thread.id, (current) => ({
970
+ ...current,
971
+ suggestion
972
+ }));
973
+ } catch {}
974
+ }
975
+ }
976
+ patchThread(id, change) {
977
+ const open = this.state.conversation;
978
+ if (open?.detail.thread.id === id) this.set({ conversation: {
979
+ ...open,
980
+ detail: {
981
+ ...open.detail,
982
+ thread: change(open.detail.thread)
983
+ }
984
+ } });
985
+ if (this.state.threads.some((thread) => thread.id === id)) this.updateBadges(this.state.threads.map((thread) => thread.id === id ? change(thread) : thread));
986
+ }
987
+ decideSuggestion = async (thread, decision) => {
988
+ const { suggestion } = thread;
989
+ if (!suggestion) return false;
990
+ let next;
991
+ try {
992
+ next = await this.api.decideSuggestion(thread.id, {
993
+ suggestionId: suggestion.id,
994
+ decision
995
+ }, this.signal);
996
+ } catch (error) {
997
+ this.failed(error);
998
+ return false;
999
+ }
1000
+ this.patchThread(thread.id, () => next);
1001
+ const open = this.state.conversation;
1002
+ if (open?.detail.thread.id === thread.id && !open.inDrawer && !resolveAnchor(shownAnchor(next)).element) this.set({
1003
+ conversation: {
1004
+ ...open,
1005
+ inDrawer: true
1006
+ },
1007
+ drawer: {
1008
+ ...this.state.drawer,
1009
+ open: true
1010
+ }
1011
+ });
1012
+ return true;
1013
+ };
1014
+ openBadge = (threads) => {
1015
+ const [first] = threads;
1016
+ if (threads.length === 1 && first) {
1017
+ this.openThread(first.id, false);
1018
+ return;
1019
+ }
1020
+ this.setDrawer({
1021
+ open: true,
1022
+ page: this.state.page.key
1023
+ });
1024
+ this.loadDrawer();
1025
+ };
1026
+ toggleDrawer = () => {
1027
+ if (this.state.drawer.open) {
1028
+ this.closeDrawer();
1029
+ return;
1030
+ }
1031
+ this.setDrawer({ open: true });
1032
+ this.loadDrawer();
1033
+ };
1034
+ closeDrawer = () => {
1035
+ this.detailRequest++;
1036
+ const inDrawer = this.state.conversation?.inDrawer;
1037
+ this.set({
1038
+ drawer: this.closedDrawer(),
1039
+ conversation: inDrawer ? null : this.state.conversation
1040
+ });
1041
+ };
1042
+ setDrawerFilter = (patch) => {
1043
+ this.setDrawer(patch);
1044
+ this.loadDrawer();
1045
+ };
1046
+ refresh = () => {
1047
+ Promise.all([this.loadDrawer(), this.refreshAnchors()]);
1048
+ };
1049
+ loadDrawer = async () => {
1050
+ if (!this.state.reviewer) return;
1051
+ const generation = ++this.listRequest;
1052
+ this.detailRequest++;
1053
+ const { status, page } = this.state.drawer;
1054
+ this.set({
1055
+ conversation: null,
1056
+ drawer: {
1057
+ ...this.state.drawer,
1058
+ list: {
1059
+ items: [],
1060
+ message: "Loading feedback…"
1061
+ }
1062
+ }
1063
+ });
1064
+ try {
1065
+ const query = page ? {
1066
+ status,
1067
+ page
1068
+ } : { status };
1069
+ const result = await this.api.listThreads(query, this.signal);
1070
+ if (generation !== this.listRequest || this.signal.aborted) return;
1071
+ this.setDrawer({ list: { items: result.items } });
1072
+ } catch (error) {
1073
+ this.setDrawer({ list: {
1074
+ items: [],
1075
+ message: "Could not load feedback. Use Refresh to try again."
1076
+ } });
1077
+ this.failed(error);
1078
+ }
1079
+ };
1080
+ openThread = async (id, inDrawer) => {
1081
+ if (!this.state.reviewer) return;
1082
+ this.picker.clear();
1083
+ this.set({ composer: null });
1084
+ const generation = ++this.detailRequest;
1085
+ try {
1086
+ const detail = await this.api.getThread(id, this.signal);
1087
+ if (generation !== this.detailRequest || this.signal.aborted) return;
1088
+ const { thread } = detail;
1089
+ const visible = thread.pageKey === this.state.page.key && Boolean(resolveAnchor(shownAnchor(thread)).element);
1090
+ const shownInDrawer = inDrawer || !visible;
1091
+ this.set({
1092
+ conversation: {
1093
+ detail,
1094
+ inDrawer: shownInDrawer
1095
+ },
1096
+ drawer: shownInDrawer ? {
1097
+ ...this.state.drawer,
1098
+ open: true
1099
+ } : this.state.drawer
1100
+ });
1101
+ } catch (error) {
1102
+ this.failed(error);
1103
+ }
1104
+ };
1105
+ closeConversation = () => {
1106
+ this.detailRequest++;
1107
+ this.set({ conversation: null });
1108
+ };
1109
+ async reloadThread() {
1110
+ const open = this.state.conversation;
1111
+ await Promise.all([open ? this.openThread(open.detail.thread.id, open.inDrawer) : null, this.refreshAnchors()]);
1112
+ }
1113
+ reply = async (thread, body) => {
1114
+ try {
1115
+ await this.api.createMessage(thread.id, { body }, this.signal);
1116
+ } catch (error) {
1117
+ this.failed(error);
1118
+ return false;
1119
+ }
1120
+ await this.reloadThread();
1121
+ return true;
1122
+ };
1123
+ toggleStatus = async (thread) => {
1124
+ try {
1125
+ await this.api.updateThread(thread.id, { status: thread.status === "open" ? "done" : "open" }, this.signal);
1126
+ await this.reloadThread();
1127
+ } catch (error) {
1128
+ this.failed(error);
1129
+ }
1130
+ };
1131
+ };
1132
+ function relocationRequest(thread) {
1133
+ const found = pathBreak(thread.anchor);
1134
+ if (!found || found.breakAt === thread.anchor.path?.length) return null;
1135
+ const request = {
1136
+ breakAt: found.breakAt,
1137
+ skeleton: skeleton(found.root)
1138
+ };
1139
+ return new TextEncoder().encode(JSON.stringify(request)).length > LIMITS.relocateBytes ? null : request;
1140
+ }
1141
+ //#endregion
1142
+ //#region ../ui/src/components/separator.tsx
1143
+ function Separator$1({ className, orientation = "horizontal", ...props }) {
1144
+ return /* @__PURE__ */ jsx(Separator, {
1145
+ "data-slot": "separator",
1146
+ orientation,
1147
+ className: cn("shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch", className),
1148
+ ...props
1149
+ });
1150
+ }
1151
+ //#endregion
1152
+ //#region src/conversation.tsx
1153
+ function Screenshot({ threadId, load }) {
1154
+ const [url, setUrl] = useState(null);
1155
+ useEffect(() => {
1156
+ const request = new AbortController();
1157
+ let objectUrl = null;
1158
+ setUrl(null);
1159
+ load(threadId, request.signal).then((image) => {
1160
+ if (request.signal.aborted) return;
1161
+ objectUrl = URL.createObjectURL(image);
1162
+ setUrl(objectUrl);
1163
+ }).catch(() => {});
1164
+ return () => {
1165
+ request.abort();
1166
+ if (objectUrl) URL.revokeObjectURL(objectUrl);
1167
+ };
1168
+ }, [threadId, load]);
1169
+ if (!url) return null;
1170
+ return /* @__PURE__ */ jsx("a", {
1171
+ href: url,
1172
+ target: "_blank",
1173
+ rel: "noopener",
1174
+ title: "Open full size",
1175
+ className: "block overflow-hidden rounded-xl border",
1176
+ children: /* @__PURE__ */ jsx("img", {
1177
+ src: url,
1178
+ alt: "Screenshot of the page when this comment was made",
1179
+ className: "block h-auto max-h-64 w-full object-cover object-top",
1180
+ onError: () => setUrl(null)
1181
+ })
1182
+ });
1183
+ }
1184
+ function notice(thread, pageKey, resolution) {
1185
+ if (thread.pageKey !== pageKey) return null;
1186
+ const width = thread.anchor.viewport?.width;
1187
+ const leftAt = width ? ` It was left at ${Math.round(width)}px wide.` : "";
1188
+ if (resolution.state === "orphan" || resolution.state === "ambiguous") return `Orphan — element not found in this view. It may be in a closed dialog or have changed.${leftAt}`;
1189
+ if (resolution.state === "hidden") return `This element is hidden in the current view.${leftAt}`;
1190
+ if (resolution.element && isReflowed(thread.anchor, resolution.element)) return `The layout has changed since this area was drawn, so the whole element is outlined.${leftAt}`;
1191
+ return null;
1192
+ }
1193
+ function Conversation(props) {
1194
+ const { detail, inDrawer, drafts, showError } = props;
1195
+ const { thread, messages } = detail;
1196
+ const draftKey = `reply:${thread.id}`;
1197
+ const [body, setBody] = useState(() => drafts.get(draftKey) ?? "");
1198
+ const [sending, setSending] = useState(false);
1199
+ const [deciding, setDeciding] = useState(false);
1200
+ const panel = useRef(null);
1201
+ const anchor = shownAnchor(thread);
1202
+ const resolution = useMemo(() => resolveAnchor(anchor), [anchor, props.layout]);
1203
+ useFrame(() => {
1204
+ if (inDrawer || !panel.current) return;
1205
+ const target = resolution.element;
1206
+ position(panel.current, target ? anchorBox(anchor, target) : null);
1207
+ });
1208
+ const decide = async (decision) => {
1209
+ setDeciding(true);
1210
+ try {
1211
+ await props.decideSuggestion(thread, decision);
1212
+ } finally {
1213
+ setDeciding(false);
1214
+ }
1215
+ };
1216
+ const send = async () => {
1217
+ const text = body.trim();
1218
+ if (!text) return;
1219
+ setSending(true);
1220
+ try {
1221
+ if (await props.reply(thread, text)) {
1222
+ drafts.delete(draftKey);
1223
+ setBody("");
1224
+ }
1225
+ } finally {
1226
+ setSending(false);
1227
+ }
1228
+ };
1229
+ const locate = () => {
1230
+ if (thread.pageKey === props.pageKey) {
1231
+ const target = resolution.element;
1232
+ if (!target) {
1233
+ showError("This element is not on the page right now.");
1234
+ return;
1235
+ }
1236
+ const reduced = matchMedia("(prefers-reduced-motion: reduce)").matches;
1237
+ target.scrollIntoView({
1238
+ block: "center",
1239
+ behavior: reduced ? "instant" : "smooth"
1240
+ });
1241
+ return;
1242
+ }
1243
+ const href = threadLink(location.href, thread.path, thread.id);
1244
+ if (href) location.assign(href);
1245
+ else showError("This comment's page is not on this site.");
1246
+ };
1247
+ const copyLink = async () => {
1248
+ const href = threadLink(location.href, thread.path, thread.id);
1249
+ if (!href) {
1250
+ showError("This comment's page is not on this site.");
1251
+ return;
1252
+ }
1253
+ try {
1254
+ await navigator.clipboard.writeText(href);
1255
+ } catch {
1256
+ showError(`Could not copy the link: ${href}`);
1257
+ }
1258
+ };
1259
+ const suggestion = thread.pageKey === props.pageKey ? thread.suggestion : void 0;
1260
+ const warning = suggestion ? null : notice(thread, props.pageKey, resolution);
1261
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
1262
+ /* @__PURE__ */ jsxs("div", {
1263
+ className: "flex items-center justify-between gap-2",
1264
+ children: [/* @__PURE__ */ jsx(Button$1, {
1265
+ variant: "ghost",
1266
+ size: "xs",
1267
+ onClick: inDrawer ? props.backToList : props.close,
1268
+ children: inDrawer ? "← All feedback" : "Close"
1269
+ }), /* @__PURE__ */ jsx(Button$1, {
1270
+ size: "xs",
1271
+ onClick: () => props.toggleStatus(thread),
1272
+ children: thread.status === "open" ? "Mark done" : "Reopen"
1273
+ })]
1274
+ }),
1275
+ /* @__PURE__ */ jsx(PanelHeading, {
1276
+ eyebrow: thread.status,
1277
+ title: `Comment #${thread.number}`,
1278
+ children: /* @__PURE__ */ jsx("div", {
1279
+ className: "text-xs text-muted-foreground",
1280
+ children: thread.path
1281
+ })
1282
+ }),
1283
+ warning && /* @__PURE__ */ jsx("div", {
1284
+ className: "rounded-xl bg-primary/15 px-3 py-2 text-xs text-primary-foreground",
1285
+ children: warning
1286
+ }),
1287
+ suggestion && /* @__PURE__ */ jsxs("div", {
1288
+ className: "flex flex-col gap-2 rounded-xl bg-primary/15 px-3 py-2 text-xs text-primary-foreground",
1289
+ children: [/* @__PURE__ */ jsxs("p", { children: [
1290
+ "This part of the page changed. We think the comment belongs here (",
1291
+ Math.round(suggestion.confidence * 100),
1292
+ "% sure)."
1293
+ ] }), props.canDecide && /* @__PURE__ */ jsxs("div", {
1294
+ className: "flex gap-2",
1295
+ children: [/* @__PURE__ */ jsx(Button$1, {
1296
+ size: "xs",
1297
+ disabled: deciding,
1298
+ onClick: () => void decide("accept"),
1299
+ children: "Yes, it's here"
1300
+ }), /* @__PURE__ */ jsx(Button$1, {
1301
+ variant: "outline",
1302
+ size: "xs",
1303
+ disabled: deciding,
1304
+ onClick: () => void decide("reject"),
1305
+ children: "No"
1306
+ })]
1307
+ })]
1308
+ }),
1309
+ /* @__PURE__ */ jsxs("div", {
1310
+ className: "flex items-center justify-between gap-2",
1311
+ children: [/* @__PURE__ */ jsx(Button$1, {
1312
+ variant: "ghost",
1313
+ size: "xs",
1314
+ onClick: locate,
1315
+ children: "Locate on page"
1316
+ }), /* @__PURE__ */ jsx(Button$1, {
1317
+ variant: "ghost",
1318
+ size: "xs",
1319
+ onClick: () => void copyLink(),
1320
+ children: "Copy link"
1321
+ })]
1322
+ }),
1323
+ thread.hasScreenshot && /* @__PURE__ */ jsx(Screenshot, {
1324
+ threadId: thread.id,
1325
+ load: props.loadScreenshot
1326
+ }),
1327
+ /* @__PURE__ */ jsx("div", {
1328
+ className: "flex flex-col",
1329
+ children: messages.map((message) => /* @__PURE__ */ jsxs("article", {
1330
+ className: "flex flex-col gap-2 py-3",
1331
+ children: [
1332
+ /* @__PURE__ */ jsxs("div", {
1333
+ className: "flex items-center justify-between gap-2 text-xs text-muted-foreground",
1334
+ children: [/* @__PURE__ */ jsx("span", {
1335
+ className: "text-foreground",
1336
+ children: /* @__PURE__ */ jsx(Author, {
1337
+ name: message.authorName,
1338
+ verified: message.authorVerified,
1339
+ strong: true
1340
+ })
1341
+ }), /* @__PURE__ */ jsx("span", { children: new Date(message.createdAt).toLocaleString() })]
1342
+ }),
1343
+ /* @__PURE__ */ jsx("p", {
1344
+ className: "break-words whitespace-pre-wrap",
1345
+ children: message.body
1346
+ }),
1347
+ /* @__PURE__ */ jsx(Separator$1, { className: "mt-1" })
1348
+ ]
1349
+ }, message.id))
1350
+ }),
1351
+ /* @__PURE__ */ jsx(Textarea, {
1352
+ "aria-label": "Reply",
1353
+ placeholder: "Write a reply…",
1354
+ maxLength: LIMITS.bodyChars,
1355
+ value: body,
1356
+ onChange: (event) => {
1357
+ setBody(event.target.value);
1358
+ drafts.set(draftKey, event.target.value);
1359
+ },
1360
+ onKeyDown: sendOnModEnter(() => void send()),
1361
+ className: "min-h-24"
1362
+ }),
1363
+ /* @__PURE__ */ jsx(Button$1, {
1364
+ className: "self-start",
1365
+ disabled: sending,
1366
+ onClick: () => void send(),
1367
+ children: "Reply"
1368
+ })
1369
+ ] });
1370
+ if (inDrawer) return /* @__PURE__ */ jsx("div", {
1371
+ className: "flex flex-col gap-3 p-4",
1372
+ children: content
1373
+ });
1374
+ return /* @__PURE__ */ jsx(Card, {
1375
+ ref: panel,
1376
+ size: "sm",
1377
+ "aria-label": `Comment #${thread.number}`,
1378
+ className: `${PANEL} max-h-[calc(100vh-110px)] overflow-auto`,
1379
+ children: content
1380
+ });
1381
+ }
1382
+ //#endregion
1383
+ //#region src/drawer.tsx
1384
+ const STATUS_FILTERS = [...THREAD_STATUSES, "all"];
1385
+ function Drawer(props) {
1386
+ const [page, setPage] = useState(props.page);
1387
+ const { items, message } = props.list;
1388
+ return /* @__PURE__ */ jsxs(Card, {
1389
+ size: "sm",
1390
+ "aria-label": "Feedback",
1391
+ className: "pointer-events-auto fixed top-3 right-3 bottom-22 w-[420px] max-w-[calc(100vw-24px)] gap-0 py-0 shadow-xl",
1392
+ children: [/* @__PURE__ */ jsxs("div", {
1393
+ className: "flex items-center justify-between gap-3 border-b px-5 py-4",
1394
+ children: [/* @__PURE__ */ jsx("h2", {
1395
+ className: "text-lg font-semibold",
1396
+ children: props.detail?.title ?? "Feedback"
1397
+ }), /* @__PURE__ */ jsx(Button$1, {
1398
+ variant: "ghost",
1399
+ size: "xs",
1400
+ onClick: props.close,
1401
+ children: "Close"
1402
+ })]
1403
+ }), props.detail ? /* @__PURE__ */ jsx("div", {
1404
+ className: "flex-1 overflow-auto",
1405
+ children: props.detail.content
1406
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
1407
+ className: "flex flex-wrap items-center gap-2 border-b px-4 py-3",
1408
+ children: [
1409
+ /* @__PURE__ */ jsx("select", {
1410
+ "aria-label": "Status",
1411
+ value: props.status,
1412
+ onChange: (event) => props.setStatus(STATUS_FILTERS.find((value) => value === event.target.value) ?? "open"),
1413
+ className: "h-8 rounded-4xl border border-input bg-input/30 px-3 text-sm",
1414
+ children: STATUS_FILTERS.map((value) => /* @__PURE__ */ jsx("option", {
1415
+ value,
1416
+ children: value.charAt(0).toUpperCase() + value.slice(1)
1417
+ }, value))
1418
+ }),
1419
+ /* @__PURE__ */ jsx(Button$1, {
1420
+ variant: "outline",
1421
+ size: "sm",
1422
+ onClick: props.refresh,
1423
+ children: "Refresh"
1424
+ }),
1425
+ /* @__PURE__ */ jsx(Input$1, {
1426
+ "aria-label": "Page filter",
1427
+ placeholder: "Filter by page path",
1428
+ value: page,
1429
+ onChange: (event) => setPage(event.target.value),
1430
+ onBlur: () => props.setPage(page.trim()),
1431
+ onKeyDown: (event) => {
1432
+ if (event.key === "Enter") props.setPage(page.trim());
1433
+ },
1434
+ className: "h-8 text-xs"
1435
+ })
1436
+ ]
1437
+ }), /* @__PURE__ */ jsxs("div", {
1438
+ className: "flex-1 overflow-auto px-2 pb-3",
1439
+ children: [(message || !items.length) && /* @__PURE__ */ jsx("p", {
1440
+ className: "px-4 py-8 text-center text-muted-foreground",
1441
+ children: message ?? "No feedback here yet. Click a place on the page to comment."
1442
+ }), items.map((thread) => {
1443
+ const replies = thread.messageCount - 1;
1444
+ const plural = replies === 1 ? "y" : "ies";
1445
+ return /* @__PURE__ */ jsxs("button", {
1446
+ type: "button",
1447
+ onClick: () => props.openThread(thread.id),
1448
+ className: "block w-full cursor-pointer border-b px-3 py-4 text-left hover:bg-muted",
1449
+ children: [
1450
+ /* @__PURE__ */ jsxs("span", {
1451
+ className: "mb-1.5 flex justify-between gap-2 text-[11px] text-muted-foreground",
1452
+ children: [/* @__PURE__ */ jsxs("span", { children: [
1453
+ "#",
1454
+ thread.number,
1455
+ " · ",
1456
+ thread.status
1457
+ ] }), /* @__PURE__ */ jsx(Author, {
1458
+ name: thread.authorName,
1459
+ verified: thread.authorVerified
1460
+ })]
1461
+ }),
1462
+ /* @__PURE__ */ jsx("span", {
1463
+ className: "block break-words whitespace-pre-wrap",
1464
+ children: thread.excerpt
1465
+ }),
1466
+ /* @__PURE__ */ jsxs("span", {
1467
+ className: "mt-2 block text-[11px] text-muted-foreground",
1468
+ children: [
1469
+ thread.path,
1470
+ " ·",
1471
+ " ",
1472
+ replies ? `${replies} repl${plural}` : "No replies"
1473
+ ]
1474
+ })
1475
+ ]
1476
+ }, thread.id);
1477
+ })]
1478
+ })] })]
1479
+ });
1480
+ }
1481
+ //#endregion
1482
+ //#region src/app.tsx
1483
+ function App(props) {
1484
+ const [shell, setShell] = useState(null);
1485
+ const { options } = props;
1486
+ useEffect(() => {
1487
+ const abort = new AbortController();
1488
+ const layer = new Layer(_virtual_fastbackr_styles_default);
1489
+ const container = document.createElement("div");
1490
+ container.className = "contents";
1491
+ layer.root.append(container);
1492
+ const loop = createFrameLoop(abort.signal);
1493
+ loop.add(() => layer.sync());
1494
+ const controller = new FeedbackController(options, layer, abort.signal);
1495
+ loop.add(() => controller.picker.paint());
1496
+ setShell({
1497
+ container,
1498
+ loop,
1499
+ controller
1500
+ });
1501
+ return () => {
1502
+ abort.abort();
1503
+ layer.destroy();
1504
+ };
1505
+ }, [options]);
1506
+ if (!shell) return null;
1507
+ return createPortal(/* @__PURE__ */ jsx(FrameContext, {
1508
+ value: shell.loop,
1509
+ children: /* @__PURE__ */ jsx(Feedback, {
1510
+ ...props,
1511
+ controller: shell.controller
1512
+ })
1513
+ }), shell.container);
1514
+ }
1515
+ function Feedback(props) {
1516
+ const { controller, drafts, commentRequest, hideFab } = props;
1517
+ const state = useSyncExternalStore(controller.subscribe, controller.getSnapshot);
1518
+ const { reviewer, conversation, drawer, composer, page, error } = state;
1519
+ useLayoutEffect(() => {
1520
+ hideFab();
1521
+ }, [hideFab]);
1522
+ useEffect(() => {
1523
+ if (commentRequest) controller.comment();
1524
+ }, [controller, commentRequest]);
1525
+ useEffect(() => {
1526
+ const abort = new AbortController();
1527
+ document.addEventListener("keydown", (event) => {
1528
+ if (!plainKey(event)) return;
1529
+ if (event.key.toLowerCase() === "c" && controller.state.reviewer) {
1530
+ event.preventDefault();
1531
+ controller.startSelection();
1532
+ }
1533
+ const { composer, conversation, drawer } = controller.state;
1534
+ const panelOpen = Boolean(composer || conversation || drawer.open);
1535
+ if (event.key === "Escape" && !controller.picker.active && panelOpen) {
1536
+ event.preventDefault();
1537
+ event.stopPropagation();
1538
+ controller.closePanels();
1539
+ }
1540
+ }, { signal: abort.signal });
1541
+ return () => abort.abort();
1542
+ }, [controller]);
1543
+ const thread = conversation && /* @__PURE__ */ jsx(Conversation, {
1544
+ detail: conversation.detail,
1545
+ inDrawer: conversation.inDrawer,
1546
+ pageKey: page.key,
1547
+ drafts,
1548
+ showError: controller.showError,
1549
+ layout: state.groups,
1550
+ close: controller.closeConversation,
1551
+ backToList: () => void controller.loadDrawer(),
1552
+ toggleStatus: (thread) => void controller.toggleStatus(thread),
1553
+ reply: controller.reply,
1554
+ canDecide: reviewer?.verified === true,
1555
+ decideSuggestion: controller.decideSuggestion,
1556
+ loadScreenshot: controller.screenshot
1557
+ }, conversation.detail.thread.id);
1558
+ return /* @__PURE__ */ jsxs("div", {
1559
+ className: "font-sans text-sm text-foreground antialiased",
1560
+ children: [
1561
+ /* @__PURE__ */ jsx(Badges, {
1562
+ groups: state.groups,
1563
+ activeId: conversation ? conversation.detail.thread.id : null,
1564
+ open: controller.openBadge
1565
+ }),
1566
+ drawer.open && /* @__PURE__ */ jsx(Drawer, {
1567
+ status: drawer.status,
1568
+ page: drawer.page,
1569
+ list: drawer.list,
1570
+ detail: conversation?.inDrawer ? {
1571
+ title: `Comment #${conversation.detail.thread.number}`,
1572
+ content: thread
1573
+ } : null,
1574
+ setStatus: (status) => controller.setDrawerFilter({ status }),
1575
+ setPage: (page) => controller.setDrawerFilter({ page }),
1576
+ refresh: controller.refresh,
1577
+ openThread: (id) => void controller.openThread(id, true),
1578
+ close: controller.closeDrawer
1579
+ }),
1580
+ conversation && !conversation.inDrawer && thread,
1581
+ composer && reviewer && /* @__PURE__ */ jsx(Composer, {
1582
+ selection: composer,
1583
+ drafts,
1584
+ pageKey: page.key,
1585
+ canScreenshot: controller.canScreenshot,
1586
+ existing: controller.existing(composer.target),
1587
+ openThread: (id) => void controller.openThread(id, false),
1588
+ close: controller.closeComposer,
1589
+ save: controller.save
1590
+ }),
1591
+ /* @__PURE__ */ jsx(Bar, {
1592
+ reviewer,
1593
+ count: state.threads.length,
1594
+ guestName: state.guestName,
1595
+ canSignIn: Boolean(props.options.signIn),
1596
+ comment: controller.startSelection,
1597
+ toggleDrawer: controller.toggleDrawer,
1598
+ minimize: props.minimize,
1599
+ showFab: props.showFab,
1600
+ flashRequest: props.flashRequest,
1601
+ close: props.close,
1602
+ continueAsGuest: controller.continueAsGuest,
1603
+ signIn: () => void controller.signIn(),
1604
+ changeName: controller.changeName
1605
+ }, reviewer?.id ?? "signed-out"),
1606
+ error && /* @__PURE__ */ jsx("div", {
1607
+ role: "alert",
1608
+ className: "pointer-events-auto fixed top-4 left-1/2 max-w-[440px] -translate-x-1/2 rounded-2xl bg-destructive px-4 py-2.5 text-white shadow-lg",
1609
+ children: error.message
1610
+ }, error.id)
1611
+ ]
1612
+ });
1613
+ }
1614
+ //#endregion
1615
+ export { App as default };