Mark Duppenthaler commited on
Commit
7f6ef8f
·
1 Parent(s): ca345b7

Updated table. No more individual rows, separate tabs for leaderboard type, export tables

Browse files
frontend/dist/assets/index-BWZpYvtq.css DELETED
@@ -1 +0,0 @@
1
- /*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,: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-y-reverse:0;--tw-border-style:solid;--tw-font-weight: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-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-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-500:oklch(63.7% .237 25.331);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-700:oklch(37.3% .034 259.733);--color-black:#000;--spacing:.25rem;--container-4xl:56rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--ease-in:cubic-bezier(.4,0,1,1);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--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%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,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;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{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}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:where(:root),:root:has(input.theme-controller[value=light]:checked),[data-theme=light]{color-scheme:light;--color-base-100:oklch(100% 0 0);--color-base-200:oklch(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% .006 285.885);--color-primary:oklch(45% .24 277.023);--color-primary-content:oklch(93% .034 272.788);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}@media (prefers-color-scheme:dark){:root{color-scheme:dark;--color-base-100:oklch(25.33% .016 252.42);--color-base-200:oklch(23.26% .014 253.1);--color-base-300:oklch(21.15% .012 254.09);--color-base-content:oklch(97.807% .029 256.847);--color-primary:oklch(58% .233 277.117);--color-primary-content:oklch(96% .018 272.314);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}}:root:has(input.theme-controller[value=light]:checked),[data-theme=light]{color-scheme:light;--color-base-100:oklch(100% 0 0);--color-base-200:oklch(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% .006 285.885);--color-primary:oklch(45% .24 277.023);--color-primary-content:oklch(93% .034 272.788);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}:root:has(input.theme-controller[value=dark]:checked),[data-theme=dark]{color-scheme:dark;--color-base-100:oklch(25.33% .016 252.42);--color-base-200:oklch(23.26% .014 253.1);--color-base-300:oklch(21.15% .012 254.09);--color-base-content:oklch(97.807% .029 256.847);--color-primary:oklch(58% .233 277.117);--color-primary-content:oklch(96% .018 272.314);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}@property --radialprogress{syntax: "<percentage>"; inherits: true; initial-value: 0%;}:root{scrollbar-color:currentColor #0000}@supports (color:color-mix(in lab,red,red)){:root{scrollbar-color:color-mix(in oklch,currentColor 35%,#0000)#0000}}:root{--fx-noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E")}:root:has(.modal-open,.modal[open],.modal:target,.modal-toggle:checked,.drawer:not([class*=drawer-open])>.drawer-toggle:checked){overflow:hidden}:where(:root:has(.modal-open,.modal[open],.modal:target,.modal-toggle:checked,.drawer:not(.drawer-open)>.drawer-toggle:checked)){scrollbar-gutter:stable;background-image:linear-gradient(var(--color-base-100),var(--color-base-100));--root-bg:var(--color-base-100)}@supports (color:color-mix(in lab,red,red)){:where(:root:has(.modal-open,.modal[open],.modal:target,.modal-toggle:checked,.drawer:not(.drawer-open)>.drawer-toggle:checked)){--root-bg:color-mix(in srgb,var(--color-base-100),oklch(0% 0 0) 40%)}}:where(.modal[open],.modal-open,.modal-toggle:checked+.modal):not(.modal-start,.modal-end){scrollbar-gutter:stable}:root,[data-theme]{background-color:var(--root-bg,var(--color-base-100));color:var(--color-base-content)}}@layer components;@layer utilities{.diff{webkit-user-select:none;-webkit-user-select:none;user-select:none;direction:ltr;grid-template-columns:auto 1fr;width:100%;display:grid;position:relative;overflow:hidden;container-type:inline-size}.diff:focus-visible,.diff:has(.diff-item-1:focus-visible){outline-style:var(--tw-outline-style);outline-offset:1px;outline-width:2px;outline-color:var(--color-base-content)}.diff:focus-visible .diff-resizer{min-width:90cqi;max-width:90cqi}.diff:has(.diff-item-2:focus-visible){outline-style:var(--tw-outline-style);outline-offset:1px;outline-width:2px}.diff:has(.diff-item-2:focus-visible) .diff-resizer{min-width:10cqi;max-width:10cqi}@supports (-webkit-overflow-scrolling:touch) and (overflow:-webkit-paged-x){.diff:focus .diff-resizer{min-width:10cqi;max-width:10cqi}.diff:has(.diff-item-1:focus) .diff-resizer{min-width:90cqi;max-width:90cqi}}.tab{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-align:center;webkit-user-select:none;-webkit-user-select:none;user-select:none;flex-wrap:wrap;justify-content:center;align-items:center;display:inline-flex;position:relative}@media (hover:hover){.tab:hover{color:var(--color-base-content)}}.tab{--tab-p:1rem;--tab-bg:var(--color-base-100);--tab-border-color:var(--color-base-300);--tab-radius-ss:0;--tab-radius-se:0;--tab-radius-es:0;--tab-radius-ee:0;--tab-order:0;--tab-radius-min:calc(.75rem - var(--border));order:var(--tab-order);height:var(--tab-height);border-color:#0000;padding-inline-start:var(--tab-p);padding-inline-end:var(--tab-p);font-size:.875rem}.tab:is(input[type=radio]){min-width:fit-content}.tab:is(input[type=radio]):after{content:attr(aria-label)}.tab:is(label){position:relative}.tab:is(label) input{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0;position:absolute;top:0;right:0;bottom:0;left:0}:is(.tab:checked,.tab:is(label:has(:checked)),.tab:is(.tab-active,[aria-selected=true]))+.tab-content{height:calc(100% - var(--tab-height) + var(--border));display:block}.tab:not(:checked,label:has(:checked),:hover,.tab-active,[aria-selected=true]){color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.tab:not(:checked,label:has(:checked),:hover,.tab-active,[aria-selected=true]){color:color-mix(in oklab,var(--color-base-content)50%,transparent)}}.tab:not(input):empty{cursor:default;flex-grow:1}.tab:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.tab:focus{outline-offset:2px;outline:2px solid #0000}}.tab:focus-visible,.tab:is(label:has(:checked:focus-visible)){outline-offset:-5px;outline:2px solid}.tab[disabled]{pointer-events:none;opacity:.4}.collapse-arrow>.collapse-title:after{content:"";transform-origin:75% 75%;pointer-events:none;top:1.9rem;width:.5rem;height:.5rem;transition-property:all;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);display:block;position:absolute;inset-inline-end:1.4rem;transform:translateY(-100%)rotate(45deg);box-shadow:2px 2px}.loading{pointer-events:none;aspect-ratio:1;vertical-align:middle;width:calc(var(--size-selector,.25rem)*6);background-color:currentColor;display:inline-block;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.pointer-events-none{pointer-events:none}.collapse:not(td,tr,colgroup){visibility:visible}.collapse{border-radius:var(--radius-box,1rem);isolation:isolate;grid-template-rows:max-content 0fr;width:100%;transition:grid-template-rows .2s;display:grid;position:relative;overflow:hidden}.collapse>input:is([type=checkbox],[type=radio]){-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0;z-index:1;grid-row-start:1;grid-column-start:1;width:100%;min-height:1lh;padding:1rem;padding-inline-end:3rem;transition:background-color .2s ease-out}.collapse:is([open],:focus:not(.collapse-close)),.collapse:not(.collapse-close):has(>input:is([type=checkbox],[type=radio]):checked){grid-template-rows:max-content 1fr}.collapse:is([open],:focus:not(.collapse-close))>.collapse-content,.collapse:not(.collapse-close)>:where(input:is([type=checkbox],[type=radio]):checked~.collapse-content){visibility:visible;min-height:fit-content}.collapse:focus-visible,.collapse:has(>input:is([type=checkbox],[type=radio]):focus-visible){outline-color:var(--color-base-content);outline-offset:2px;outline-width:2px;outline-style:solid}.collapse:not(.collapse-close)>input[type=checkbox],.collapse:not(.collapse-close)>input[type=radio]:not(:checked),.collapse:not(.collapse-close)>.collapse-title{cursor:pointer}.collapse:focus:not(.collapse-close,.collapse[open])>.collapse-title{cursor:unset}.collapse:is([open],:focus:not(.collapse-close))>:where(.collapse-content),.collapse:not(.collapse-close)>:where(input:is([type=checkbox],[type=radio]):checked~.collapse-content){padding-bottom:1rem;transition:padding .2s ease-out,background-color .2s ease-out}.collapse[open].collapse-arrow>.collapse-title:after,.collapse.collapse-open.collapse-arrow>.collapse-title:after{transform:translateY(-50%)rotate(225deg)}.collapse.collapse-open.collapse-plus>.collapse-title:after{content:"−"}.collapse.collapse-arrow:focus:not(.collapse-close)>.collapse-title:after,.collapse.collapse-arrow:not(.collapse-close)>input:is([type=checkbox],[type=radio]):checked~.collapse-title:after{transform:translateY(-50%)rotate(225deg)}.collapse[open].collapse-plus>.collapse-title:after,.collapse.collapse-plus:focus:not(.collapse-close)>.collapse-title:after,.collapse.collapse-plus:not(.collapse-close)>input:is([type=checkbox],[type=radio]):checked~.collapse-title:after{content:"−"}.collapse:is(details){width:100%}.collapse:is(details) summary{display:block;position:relative}.collapse:is(details) summary::-webkit-details-marker{display:none}.collapse:is(details) summary{outline:none}.collapse-content{visibility:hidden;min-height:0;cursor:unset;grid-row-start:2;grid-column-start:1;padding-left:1rem;padding-right:1rem;transition:visibility .2s,padding .2s ease-out,background-color .2s ease-out}.collapse{visibility:collapse}.visible{visibility:visible}.toggle{border:var(--border)solid currentColor;color:var(--input-color);cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;vertical-align:middle;webkit-user-select:none;-webkit-user-select:none;user-select:none;--radius-selector-max:calc(var(--radius-selector) + var(--radius-selector) + var(--radius-selector));border-radius:calc(var(--radius-selector) + min(var(--toggle-p),var(--radius-selector-max)) + min(var(--border),var(--radius-selector-max)));padding:var(--toggle-p);flex-shrink:0;grid-template-columns:0fr 1fr 1fr;place-content:center;display:inline-grid;position:relative;box-shadow:inset 0 1px}@supports (color:color-mix(in lab,red,red)){.toggle{box-shadow:0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000) inset}}.toggle{--input-color:var(--color-base-content);transition:color .3s,grid-template-columns .2s}@supports (color:color-mix(in lab,red,red)){.toggle{--input-color:color-mix(in oklab,var(--color-base-content)50%,#0000)}}.toggle{--toggle-p:calc(var(--size)*.125);--size:calc(var(--size-selector,.25rem)*6);width:calc((var(--size)*2) - (var(--border) + var(--toggle-p))*2);height:var(--size)}.toggle>*{z-index:1;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#0000;border:none;grid-column:2/span 1;grid-row-start:1;height:100%;padding:.125rem;transition:opacity .2s,rotate .4s}.toggle>:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.toggle>:focus{outline-offset:2px;outline:2px solid #0000}}.toggle>:nth-child(2){color:var(--color-base-100);rotate:none}.toggle>:nth-child(3){color:var(--color-base-100);opacity:0;rotate:-15deg}.toggle:has(:checked)>:nth-child(2){opacity:0;rotate:15deg}.toggle:has(:checked)>:nth-child(3){opacity:1;rotate:none}.toggle:before{aspect-ratio:1;border-radius:var(--radius-selector);--tw-content:"";content:var(--tw-content);height:100%;box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor;background-color:currentColor;grid-row-start:1;grid-column-start:2;transition:background-color .1s,translate .2s,inset-inline-start .2s;position:relative;inset-inline-start:0;translate:0}@supports (color:color-mix(in lab,red,red)){.toggle:before{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000)}}.toggle:before{background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise)}@media (forced-colors:active){.toggle:before{outline-style:var(--tw-outline-style);outline-offset:-1px;outline-width:1px}}@media print{.toggle:before{outline-offset:-1rem;outline:.25rem solid}}.toggle:focus-visible,.toggle:has(:focus-visible){outline-offset:2px;outline:2px solid}.toggle:checked,.toggle[aria-checked=true],.toggle:has(>input:checked){background-color:var(--color-base-100);--input-color:var(--color-base-content);grid-template-columns:1fr 1fr 0fr}:is(.toggle:checked,.toggle[aria-checked=true],.toggle:has(>input:checked)):before{background-color:currentColor}@starting-style{:is(.toggle:checked,.toggle[aria-checked=true],.toggle:has(>input:checked)):before{opacity:0}}.toggle:indeterminate{grid-template-columns:.5fr 1fr .5fr}.toggle:disabled{cursor:not-allowed;opacity:.3}.toggle:disabled:before{border:var(--border)solid currentColor;background-color:#0000}.input{cursor:text;border:var(--border)solid #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--color-base-100);vertical-align:middle;white-space:nowrap;width:clamp(3rem,20rem,100%);height:var(--size);touch-action:manipulation;border-color:var(--input-color);box-shadow:0 1px var(--input-color) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset;border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-shrink:1;align-items:center;gap:.5rem;padding-inline:.75rem;font-size:.875rem;display:inline-flex;position:relative}@supports (color:color-mix(in lab,red,red)){.input{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset}}.input{--size:calc(var(--size-field,.25rem)*10);--input-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.input{--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.input:where(input){display:inline-flex}.input :where(input){-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#0000;border:none;width:100%;height:100%;display:inline-flex}.input :where(input):focus,.input :where(input):focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.input :where(input):focus,.input :where(input):focus-within{outline-offset:2px;outline:2px solid #0000}}.input :where(input[type=url]),.input :where(input[type=email]){direction:ltr}.input :where(input[type=date]){display:inline-block}.input:focus,.input:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab,red,red)){.input:focus,.input:focus-within{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.input:focus,.input:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate;z-index:1}.input:has(>input[disabled]),.input:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.input:has(>input[disabled]),.input:is(:disabled,[disabled]){color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]))::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]))::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.input:has(>input[disabled]),.input:is(:disabled,[disabled]){box-shadow:none}.input:has(>input[disabled])>input[disabled]{cursor:not-allowed}.input::-webkit-date-and-time-value{text-align:inherit}.input[type=number]::-webkit-inner-spin-button{margin-block:-.75rem;margin-inline-end:-.75rem}.input::-webkit-calendar-picker-indicator{position:absolute;inset-inline-end:.75em}.table{border-radius:var(--radius-box);text-align:left;width:100%;font-size:.875rem;position:relative}.table:where(:dir(rtl),[dir=rtl],[dir=rtl] *){text-align:right}@media (hover:hover){:is(.table tr.row-hover,.table tr.row-hover:nth-child(2n)):hover{background-color:var(--color-base-200)}}.table :where(th,td){vertical-align:middle;padding-block:.75rem;padding-inline:1rem}.table :where(thead,tfoot){white-space:nowrap;color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.table :where(thead,tfoot){color:color-mix(in oklab,var(--color-base-content)60%,transparent)}}.table :where(thead,tfoot){font-size:.875rem;font-weight:600}.table :where(tfoot){border-top:var(--border)solid var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.table :where(tfoot){border-top:var(--border)solid color-mix(in oklch,var(--color-base-content)5%,#0000)}}.table :where(.table-pin-rows thead tr){z-index:1;background-color:var(--color-base-100);position:sticky;top:0}.table :where(.table-pin-rows tfoot tr){z-index:1;background-color:var(--color-base-100);position:sticky;bottom:0}.table :where(.table-pin-cols tr th){background-color:var(--color-base-100);position:sticky;left:0;right:0}.table :where(thead tr,tbody tr:not(:last-child)){border-bottom:var(--border)solid var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.table :where(thead tr,tbody tr:not(:last-child)){border-bottom:var(--border)solid color-mix(in oklch,var(--color-base-content)5%,#0000)}}.steps{counter-reset:step;grid-auto-columns:1fr;grid-auto-flow:column;display:inline-grid;overflow:auto hidden}.steps .step{text-align:center;--step-bg:var(--color-base-300);--step-fg:var(--color-base-content);grid-template-rows:40px 1fr;grid-template-columns:auto;place-items:center;min-width:4rem;display:grid}.steps .step:before{width:100%;height:.5rem;color:var(--step-bg);background-color:var(--step-bg);--tw-content:"";content:var(--tw-content);border:1px solid;grid-row-start:1;grid-column-start:1;margin-inline-start:-100%;top:0}.steps .step>.step-icon,.steps .step:not(:has(.step-icon)):after{content:counter(step);counter-increment:step;z-index:1;color:var(--step-fg);background-color:var(--step-bg);border:1px solid var(--step-bg);border-radius:3.40282e38px;grid-row-start:1;grid-column-start:1;place-self:center;place-items:center;width:2rem;height:2rem;display:grid;position:relative}.steps .step:first-child:before{content:none}.steps .step[data-content]:after{content:attr(data-content)}.steps .step-neutral+.step-neutral:before,.steps .step-neutral:after,.steps .step-neutral>.step-icon{--step-bg:var(--color-neutral);--step-fg:var(--color-neutral-content)}.steps .step-primary+.step-primary:before,.steps .step-primary:after,.steps .step-primary>.step-icon{--step-bg:var(--color-primary);--step-fg:var(--color-primary-content)}.steps .step-secondary+.step-secondary:before,.steps .step-secondary:after,.steps .step-secondary>.step-icon{--step-bg:var(--color-secondary);--step-fg:var(--color-secondary-content)}.steps .step-accent+.step-accent:before,.steps .step-accent:after,.steps .step-accent>.step-icon{--step-bg:var(--color-accent);--step-fg:var(--color-accent-content)}.steps .step-info+.step-info:before,.steps .step-info:after,.steps .step-info>.step-icon{--step-bg:var(--color-info);--step-fg:var(--color-info-content)}.steps .step-success+.step-success:before,.steps .step-success:after,.steps .step-success>.step-icon{--step-bg:var(--color-success);--step-fg:var(--color-success-content)}.steps .step-warning+.step-warning:before,.steps .step-warning:after,.steps .step-warning>.step-icon{--step-bg:var(--color-warning);--step-fg:var(--color-warning-content)}.steps .step-error+.step-error:before,.steps .step-error:after,.steps .step-error>.step-icon{--step-bg:var(--color-error);--step-fg:var(--color-error-content)}.range{-webkit-appearance:none;-moz-appearance:none;appearance:none;webkit-appearance:none;--range-thumb:var(--color-base-100);--range-thumb-size:calc(var(--size-selector,.25rem)*6);--range-progress:currentColor;--range-fill:1;--range-p:.25rem;--range-bg:currentColor}@supports (color:color-mix(in lab,red,red)){.range{--range-bg:color-mix(in oklab,currentColor 10%,#0000)}}.range{cursor:pointer;vertical-align:middle;--radius-selector-max:calc(var(--radius-selector) + var(--radius-selector) + var(--radius-selector));border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));width:clamp(3rem,20rem,100%);height:var(--range-thumb-size);background-color:#0000;border:none;overflow:hidden}[dir=rtl] .range{--range-dir:-1}.range:focus{outline:none}.range:focus-visible{outline-offset:2px;outline:2px solid}.range::-webkit-slider-runnable-track{background-color:var(--range-bg);border-radius:var(--radius-selector);width:100%;height:calc(var(--range-thumb-size)*.5)}@media (forced-colors:active){.range::-webkit-slider-runnable-track{border:1px solid}.range::-moz-range-track{border:1px solid}}.range::-webkit-slider-thumb{box-sizing:border-box;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));height:var(--range-thumb-size);width:var(--range-thumb-size);border:var(--range-p)solid;-webkit-appearance:none;-moz-appearance:none;appearance:none;webkit-appearance:none;color:var(--range-progress);box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor,0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill));background-color:currentColor;position:relative;top:50%;transform:translateY(-50%)}@supports (color:color-mix(in lab,red,red)){.range::-webkit-slider-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))}}.range::-moz-range-track{background-color:var(--range-bg);border-radius:var(--radius-selector);width:100%;height:calc(var(--range-thumb-size)*.5)}.range::-moz-range-thumb{box-sizing:border-box;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));height:var(--range-thumb-size);width:var(--range-thumb-size);border:var(--range-p)solid;color:var(--range-progress);box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor,0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill));background-color:currentColor;position:relative;top:50%}@supports (color:color-mix(in lab,red,red)){.range::-moz-range-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))}}.range:disabled{cursor:not-allowed;opacity:.3}.range\!{-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;webkit-appearance:none!important;--range-thumb:var(--color-base-100)!important;--range-thumb-size:calc(var(--size-selector,.25rem)*6)!important;--range-progress:currentColor!important;--range-fill:1!important;--range-p:.25rem!important;--range-bg:currentColor!important}@supports (color:color-mix(in lab,red,red)){.range\!{--range-bg:color-mix(in oklab,currentColor 10%,#0000)!important}}.range\!{cursor:pointer!important;vertical-align:middle!important;--radius-selector-max:calc(var(--radius-selector) + var(--radius-selector) + var(--radius-selector))!important;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)))!important;width:clamp(3rem,20rem,100%)!important;height:var(--range-thumb-size)!important;background-color:#0000!important;border:none!important;overflow:hidden!important}[dir=rtl] .range\!{--range-dir:-1!important}.range\!:focus{outline:none!important}.range\!:focus-visible{outline-offset:2px!important;outline:2px solid!important}.range\!::-webkit-slider-runnable-track{background-color:var(--range-bg)!important;border-radius:var(--radius-selector)!important;width:100%!important;height:calc(var(--range-thumb-size)*.5)!important}@media (forced-colors:active){.range\!::-webkit-slider-runnable-track{border:1px solid!important}.range\!::-moz-range-track{border:1px solid!important}}.range\!::-webkit-slider-thumb{box-sizing:border-box!important;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)))!important;height:var(--range-thumb-size)!important;width:var(--range-thumb-size)!important;border:var(--range-p)solid!important;-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;webkit-appearance:none!important;color:var(--range-progress)!important;box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor,0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))!important;background-color:currentColor!important;position:relative!important;top:50%!important;transform:translateY(-50%)!important}@supports (color:color-mix(in lab,red,red)){.range\!::-webkit-slider-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))!important}}.range\!::-moz-range-track{background-color:var(--range-bg)!important;border-radius:var(--radius-selector)!important;width:100%!important;height:calc(var(--range-thumb-size)*.5)!important}.range\!::-moz-range-thumb{box-sizing:border-box!important;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)))!important;height:var(--range-thumb-size)!important;width:var(--range-thumb-size)!important;border:var(--range-p)solid!important;color:var(--range-progress)!important;box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor,0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))!important;background-color:currentColor!important;position:relative!important;top:50%!important}@supports (color:color-mix(in lab,red,red)){.range\!::-moz-range-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))!important}}.range\!:disabled{cursor:not-allowed!important;opacity:.3!important}.tabs-border .tab{--tab-border-color:#0000 #0000 var(--tab-border-color)#0000;border-radius:var(--radius-field);position:relative}.tabs-border .tab:before{--tw-content:"";content:var(--tw-content);background-color:var(--tab-border-color);border-radius:var(--radius-field);width:80%;height:3px;transition:background-color .2s;position:absolute;bottom:0;left:10%}:is(.tabs-border .tab:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]),.tabs-border .tab:is(input:checked),.tabs-border .tab:is(label:has(:checked))):before{--tab-border-color:currentColor;border-top:3px solid}.select{border:var(--border)solid #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--color-base-100);vertical-align:middle;width:clamp(3rem,20rem,100%);height:var(--size);touch-action:manipulation;text-overflow:ellipsis;box-shadow:0 1px var(--input-color) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset;background-image:linear-gradient(45deg,#0000 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,#0000 50%);background-position:calc(100% - 20px) calc(1px + 50%),calc(100% - 16.1px) calc(1px + 50%);background-repeat:no-repeat;background-size:4px 4px,4px 4px;border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-shrink:1;align-items:center;gap:.375rem;padding-inline:1rem 1.75rem;font-size:.875rem;display:inline-flex;position:relative}@supports (color:color-mix(in lab,red,red)){.select{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset}}.select{border-color:var(--input-color);--input-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.select{--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.select{--size:calc(var(--size-field,.25rem)*10)}[dir=rtl] .select{background-position:12px calc(1px + 50%),16px calc(1px + 50%)}.select select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:inherit;border-radius:inherit;border-style:none;width:calc(100% + 2.75rem);height:calc(100% - 2px);margin-inline:-1rem -1.75rem;padding-inline:1rem 1.75rem}.select select:focus,.select select:focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.select select:focus,.select select:focus-within{outline-offset:2px;outline:2px solid #0000}}.select select:not(:last-child){background-image:none;margin-inline-end:-1.375rem}.select:focus,.select:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab,red,red)){.select:focus,.select:focus-within{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.select:focus,.select:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate;z-index:1}.select:has(>select[disabled]),.select:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.select:has(>select[disabled]),.select:is(:disabled,[disabled]){color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.select:has(>select[disabled]),.select:is(:disabled,[disabled]))::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){:is(.select:has(>select[disabled]),.select:is(:disabled,[disabled]))::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.select:has(>select[disabled])>select[disabled]{cursor:not-allowed}.timeline{display:flex;position:relative}.timeline>li{grid-template-rows:var(--timeline-row-start,minmax(0,1fr))auto var(--timeline-row-end,minmax(0,1fr));grid-template-columns:var(--timeline-col-start,minmax(0,1fr))auto var(--timeline-col-end,minmax(0,1fr));flex-shrink:0;align-items:center;display:grid;position:relative}.timeline>li>hr{border:none;width:100%}.timeline>li>hr:first-child{grid-row-start:2;grid-column-start:1}.timeline>li>hr:last-child{grid-area:2/3/auto/none}@media print{.timeline>li>hr{border:.1px solid var(--color-base-300)}}.timeline :where(hr){background-color:var(--color-base-300);height:.25rem}.timeline:has(.timeline-middle hr):first-child{border-start-start-radius:0;border-start-end-radius:var(--radius-selector);border-end-end-radius:var(--radius-selector);border-end-start-radius:0}.timeline:has(.timeline-middle hr):last-child,.timeline:not(:has(.timeline-middle)) :first-child hr:last-child{border-start-start-radius:var(--radius-selector);border-start-end-radius:0;border-end-end-radius:0;border-end-start-radius:var(--radius-selector)}.timeline:not(:has(.timeline-middle)) :last-child hr:first-child{border-start-start-radius:0;border-start-end-radius:var(--radius-selector);border-end-end-radius:var(--radius-selector);border-end-start-radius:0}.collapse-title{grid-row-start:1;grid-column-start:1;width:100%;min-height:1lh;padding:1rem;padding-inline-end:3rem;transition:background-color .2s ease-out;position:relative}.checkbox{border:var(--border)solid var(--input-color,var(--color-base-content))}@supports (color:color-mix(in lab,red,red)){.checkbox{border:var(--border)solid var(--input-color,color-mix(in oklab,var(--color-base-content)20%,#0000))}}.checkbox{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-selector);vertical-align:middle;color:var(--color-base-content);box-shadow:0 1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 0 #0000 inset,0 0 #0000;--size:calc(var(--size-selector,.25rem)*6);width:var(--size);height:var(--size);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);flex-shrink:0;padding:.25rem;transition:background-color .2s,box-shadow .2s;display:inline-block;position:relative}.checkbox:before{--tw-content:"";content:var(--tw-content);opacity:0;clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,70% 80%,70% 100%);width:100%;height:100%;box-shadow:0 3px oklch(100% 0 0/calc(var(--depth)*.1)) inset;background-color:currentColor;font-size:1rem;line-height:.75;transition:clip-path .3s .1s,opacity .1s .1s,rotate .3s .1s,translate .3s .1s;display:block;rotate:45deg}.checkbox:focus-visible{outline:2px solid var(--input-color,currentColor);outline-offset:2px}.checkbox:checked,.checkbox[aria-checked=true]{background-color:var(--input-color,#0000);box-shadow:0 0 #0000 inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px oklch(0% 0 0/calc(var(--depth)*.1))}:is(.checkbox:checked,.checkbox[aria-checked=true]):before{clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 0%,70% 0%,70% 100%);opacity:1}@media (forced-colors:active){:is(.checkbox:checked,.checkbox[aria-checked=true]):before{--tw-content:"✔︎";clip-path:none;background-color:#0000;rotate:none}}@media print{:is(.checkbox:checked,.checkbox[aria-checked=true]):before{--tw-content:"✔︎";clip-path:none;background-color:#0000;rotate:none}}.checkbox:indeterminate:before{opacity:1;clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,80% 80%,80% 100%);translate:0 -35%;rotate:none}.checkbox:disabled{cursor:not-allowed;opacity:.2}.radio{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;vertical-align:middle;border:var(--border)solid var(--input-color,currentColor);border-radius:3.40282e38px;flex-shrink:0;padding:.25rem;display:inline-block;position:relative}@supports (color:color-mix(in lab,red,red)){.radio{border:var(--border)solid var(--input-color,color-mix(in srgb,currentColor 20%,#0000))}}.radio{box-shadow:0 1px oklch(0% 0 0/calc(var(--depth)*.1)) inset;--size:calc(var(--size-selector,.25rem)*6);width:var(--size);height:var(--size);color:var(--input-color,currentColor)}.radio:before{--tw-content:"";content:var(--tw-content);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);border-radius:3.40282e38px;width:100%;height:100%;display:block}.radio:focus-visible{outline:2px solid}.radio:checked,.radio[aria-checked=true]{background-color:var(--color-base-100);border-color:currentColor;animation:.2s ease-out radio}:is(.radio:checked,.radio[aria-checked=true]):before{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px oklch(0% 0 0/calc(var(--depth)*.1));background-color:currentColor}@media (forced-colors:active){:is(.radio:checked,.radio[aria-checked=true]):before{outline-style:var(--tw-outline-style);outline-offset:-1px;outline-width:1px}}@media print{:is(.radio:checked,.radio[aria-checked=true]):before{outline-offset:-1rem;outline:.25rem solid}}.radio:disabled{cursor:not-allowed;opacity:.2}.stats{border-radius:var(--radius-box);grid-auto-flow:column;display:inline-grid;position:relative;overflow-x:auto}.progress{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-box);background-color:currentColor;width:100%;height:.5rem;position:relative;overflow:hidden}@supports (color:color-mix(in lab,red,red)){.progress{background-color:color-mix(in oklab,currentColor 20%,transparent)}}.progress{color:var(--color-base-content)}.progress:indeterminate{background-image:repeating-linear-gradient(90deg,currentColor -1% 10%,#0000 10% 90%);background-position-x:15%;background-size:200%;animation:5s ease-in-out infinite progress}@supports ((-moz-appearance:none)){.progress:indeterminate::-moz-progress-bar{background-color:#0000;background-image:repeating-linear-gradient(90deg,currentColor -1% 10%,#0000 10% 90%);background-position-x:15%;background-size:200%;animation:5s ease-in-out infinite progress}.progress::-moz-progress-bar{border-radius:var(--radius-box);background-color:currentColor}}@supports ((-webkit-appearance:none)){.progress::-webkit-progress-bar{border-radius:var(--radius-box);background-color:#0000}.progress::-webkit-progress-value{border-radius:var(--radius-box);background-color:currentColor}}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.top-0{top:calc(var(--spacing)*0)}.top-1\/2{top:50%}.top-12{top:calc(var(--spacing)*12)}.right-2{right:calc(var(--spacing)*2)}.left-0{left:calc(var(--spacing)*0)}.textarea{border:var(--border)solid #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-field);background-color:var(--color-base-100);vertical-align:middle;touch-action:manipulation;border-color:var(--input-color);width:clamp(3rem,20rem,100%);min-height:5rem;box-shadow:0 1px var(--input-color) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset;flex-shrink:1;padding-block:.5rem;padding-inline:.75rem;font-size:.875rem}@supports (color:color-mix(in lab,red,red)){.textarea{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset}}.textarea{--input-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.textarea{--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.textarea textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#0000;border:none}.textarea textarea:focus,.textarea textarea:focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.textarea textarea:focus,.textarea textarea:focus-within{outline-offset:2px;outline:2px solid #0000}}.textarea:focus,.textarea:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab,red,red)){.textarea:focus,.textarea:focus-within{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.textarea:focus,.textarea:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate}.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]){color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]))::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){:is(.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]))::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]){box-shadow:none}.textarea:has(>textarea[disabled])>textarea[disabled]{cursor:not-allowed}.stack{grid-template-rows:3px 4px 1fr 4px 3px;grid-template-columns:3px 4px 1fr 4px 3px;display:inline-grid}.stack>*{width:100%;height:100%}.stack>:nth-child(n+2){opacity:.7;width:100%}.stack>:nth-child(2){z-index:2;opacity:.9}.stack>:first-child{z-index:3;width:100%}:is(.stack,.stack.stack-bottom)>*{grid-area:3/3/6/4}:is(.stack,.stack.stack-bottom)>:nth-child(2){grid-area:2/2/5/5}:is(.stack,.stack.stack-bottom)>:first-child{grid-area:1/1/4/6}.stack.stack-top>*{grid-area:1/3/4/4}.stack.stack-top>:nth-child(2){grid-area:2/2/5/5}.stack.stack-top>:first-child{grid-area:3/1/6/6}.stack.stack-start>*{grid-area:3/1/4/4}.stack.stack-start>:nth-child(2){grid-area:2/2/5/5}.stack.stack-start>:first-child{grid-area:1/3/6/6}.stack.stack-end>*{grid-area:3/3/4/6}.stack.stack-end>:nth-child(2){grid-area:2/2/5/5}.stack.stack-end>:first-child{grid-area:1/1/6/4}.z-10{z-index:10}.z-20{z-index:20}.tab-content{order:var(--tabcontent-order);--tabcontent-radius-ss:0;--tabcontent-radius-se:0;--tabcontent-radius-es:0;--tabcontent-radius-ee:0;--tabcontent-order:1;width:100%;margin:var(--tabcontent-margin);border-color:#0000;border-width:var(--border);border-start-start-radius:var(--tabcontent-radius-ss);border-start-end-radius:var(--tabcontent-radius-se);border-end-end-radius:var(--tabcontent-radius-ee);border-end-start-radius:var(--tabcontent-radius-es);display:none}.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}}.container\!{width:100%!important}@media (min-width:40rem){.container\!{max-width:40rem!important}}@media (min-width:48rem){.container\!{max-width:48rem!important}}@media (min-width:64rem){.container\!{max-width:64rem!important}}@media (min-width:80rem){.container\!{max-width:80rem!important}}@media (min-width:96rem){.container\!{max-width:96rem!important}}.filter{flex-wrap:wrap;display:flex}.filter input[type=radio]{width:auto}.filter input{opacity:1;transition:margin .1s,opacity .3s,padding .3s,border-width .1s;overflow:hidden;scale:1}.filter input:not(:last-child){margin-inline-end:.25rem}.filter input.filter-reset{aspect-ratio:1}.filter input.filter-reset:after{content:"×"}.filter:not(:has(input:checked:not(.filter-reset))) .filter-reset,.filter:not(:has(input:checked:not(.filter-reset))) input[type=reset],.filter:has(input:checked:not(.filter-reset)) input:not(:checked,.filter-reset,input[type=reset]){opacity:0;border-width:0;width:0;margin-inline:0;padding-inline:0;scale:0}.mx-auto{margin-inline:auto}.input-sm{--size:calc(var(--size-field,.25rem)*8);font-size:.75rem}.input-sm[type=number]::-webkit-inner-spin-button{margin-block:-.5rem;margin-inline-end:-.75rem}.my-4{margin-block:calc(var(--spacing)*4)}.label{white-space:nowrap;color:currentColor;align-items:center;gap:.375rem;display:inline-flex}@supports (color:color-mix(in lab,red,red)){.label{color:color-mix(in oklab,currentColor 60%,transparent)}}.label:has(input){cursor:pointer}.label:is(.input>*,.select>*){white-space:nowrap;height:calc(100% - .5rem);font-size:inherit;align-items:center;padding-inline:.75rem;display:flex}.label:is(.input>*,.select>*):first-child{border-inline-end:var(--border)solid currentColor;margin-inline:-.75rem .75rem}@supports (color:color-mix(in lab,red,red)){.label:is(.input>*,.select>*):first-child{border-inline-end:var(--border)solid color-mix(in oklab,currentColor 10%,#0000)}}.label:is(.input>*,.select>*):last-child{border-inline-start:var(--border)solid currentColor;margin-inline:.75rem -.75rem}@supports (color:color-mix(in lab,red,red)){.label:is(.input>*,.select>*):last-child{border-inline-start:var(--border)solid color-mix(in oklab,currentColor 10%,#0000)}}.mt-8{margin-top:calc(var(--spacing)*8)}.mr-2{margin-right:calc(var(--spacing)*2)}.fieldset-legend{color:var(--color-base-content);justify-content:space-between;align-items:center;gap:.5rem;margin-bottom:-.25rem;padding-block:.5rem;font-weight:600;display:flex}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.status{aspect-ratio:1;border-radius:var(--radius-selector);background-color:var(--color-base-content);width:.5rem;height:.5rem;display:inline-block}@supports (color:color-mix(in lab,red,red)){.status{background-color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.status{vertical-align:middle;color:#0000004d;background-position:50%;background-repeat:no-repeat}@supports (color:color-mix(in lab,red,red)){.status{color:#0000004d}@supports (color:color-mix(in lab,red,red)){.status{color:color-mix(in oklab,var(--color-black)30%,transparent)}}}.status{background-image:radial-gradient(circle at 35% 30%,oklch(1 0 0/calc(var(--depth)*.5)),#0000);box-shadow:0 2px 3px -1px}@supports (color:color-mix(in lab,red,red)){.status{box-shadow:0 2px 3px -1px color-mix(in oklab,currentColor calc(var(--depth)*100%),#0000)}}.tabs{--tabs-height:auto;--tabs-direction:row;--tab-height:calc(var(--size-field,.25rem)*10);height:var(--tabs-height);flex-wrap:wrap;flex-direction:var(--tabs-direction);display:flex}.fieldset{grid-template-columns:1fr;grid-auto-rows:max-content;gap:.375rem;padding-block:.25rem;font-size:.75rem;display:grid}.card-title{font-size:var(--cardtitle-fs,1.125rem);align-items:center;gap:.5rem;font-weight:600;display:flex}.join{--join-ss:0;--join-se:0;--join-es:0;--join-ee:0;align-items:stretch;display:inline-flex}.join :where(.join-item){border-start-start-radius:var(--join-ss,0);border-start-end-radius:var(--join-se,0);border-end-end-radius:var(--join-ee,0);border-end-start-radius:var(--join-es,0)}.join :where(.join-item) *{--join-ss:var(--radius-field);--join-se:var(--radius-field);--join-es:var(--radius-field);--join-ee:var(--radius-field)}.join>.join-item:where(:first-child),.join :first-child:not(:last-child) :where(.join-item){--join-ss:var(--radius-field);--join-se:0;--join-es:var(--radius-field);--join-ee:0}.join>.join-item:where(:last-child),.join :last-child:not(:first-child) :where(.join-item){--join-ss:0;--join-se:var(--radius-field);--join-es:0;--join-ee:var(--radius-field)}.join>.join-item:where(:only-child),.join :only-child :where(.join-item){--join-ss:var(--radius-field);--join-se:var(--radius-field);--join-es:var(--radius-field);--join-ee:var(--radius-field)}.mask{vertical-align:middle;display:inline-block;-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.table{display:table}.h-4{height:calc(var(--spacing)*4)}.h-64{height:calc(var(--spacing)*64)}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-\[80vh\]{max-height:80vh}.min-h-screen{min-height:100vh}.loading-lg{width:calc(var(--size-selector,.25rem)*7)}.w-4{width:calc(var(--spacing)*4)}.w-11\/12{width:91.6667%}.w-48{width:calc(var(--spacing)*48)}.w-full{width:100%}.max-w-4xl{max-width:var(--container-4xl)}.max-w-full{max-width:100%}.min-w-\[220px\]{min-width:220px}.min-w-max{min-width:max-content}.flex-1{flex:1}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.link{cursor:pointer;text-decoration-line:underline}.link:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.link:focus{outline-offset:2px;outline:2px solid #0000}}.link:focus-visible{outline-offset:2px;outline:2px solid}.cursor-pointer{cursor:pointer}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-8{gap:calc(var(--spacing)*8)}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b-3{border-bottom-style:var(--tw-border-style);border-bottom-width:3px}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-700{border-color:var(--color-gray-700)}.border-b-gray-700{border-bottom-color:var(--color-gray-700)}.bg-base-100{background-color:var(--color-base-100)}.bg-base-200{background-color:var(--color-base-200)}.loading-spinner{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E")}.radio-sm{padding:.1875rem}.radio-sm[type=radio]{--size:calc(var(--size-selector,.25rem)*5)}.p-4{padding:calc(var(--spacing)*4)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.py-1{padding-block:calc(var(--spacing)*1)}.pt-4{padding-top:calc(var(--spacing)*4)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-8{padding-right:calc(var(--spacing)*8)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-10{padding-left:calc(var(--spacing)*10)}.text-center{text-align:center}.text-left{text-align:left}.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))}.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-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-gray-400{color:var(--color-gray-400)}.text-primary{color:var(--color-primary)}.text-red-500{color:var(--color-red-500)}.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)}.blur{--tw-blur:blur(8px);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,)}.invert{--tw-invert:invert(100%);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,)}.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,visibility,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\!{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,visibility,content-visibility,overlay,pointer-events!important;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function))!important;transition-duration:var(--tw-duration,var(--default-transition-duration))!important}.ease-in{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.hover\:bg-base-100:hover{background-color:var(--color-base-100)}.hover\:bg-base-200:hover{background-color:var(--color-base-200)}.hover\:bg-base-300:hover{background-color:var(--color-base-300)}}@media (min-width:48rem){.md\:w-1\/2{width:50%}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:gap-x-4{column-gap:calc(var(--spacing)*4)}}@media (min-width:64rem){.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}}@keyframes radio{0%{padding:5px}50%{padding:3px}}@keyframes skeleton{0%{background-position:150%}to{background-position:-50%}}@keyframes progress{50%{background-position-x:-115%}}@keyframes toast{0%{opacity:0;scale:.9}to{opacity:1;scale:1}}@keyframes dropdown{0%{opacity:0}}@keyframes rating{0%,40%{filter:brightness(1.05)contrast(1.05);scale:1.1}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}
 
 
frontend/dist/assets/index-BbusHoyK.css ADDED
@@ -0,0 +1 @@
 
 
1
+ /*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--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-y-reverse:0;--tw-border-style:solid;--tw-font-weight: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-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-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-500:oklch(63.7% .237 25.331);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-700:oklch(37.3% .034 259.733);--color-black:#000;--spacing:.25rem;--container-4xl:56rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--ease-in:cubic-bezier(.4,0,1,1);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--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%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,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;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{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}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:where(:root),:root:has(input.theme-controller[value=light]:checked),[data-theme=light]{color-scheme:light;--color-base-100:oklch(100% 0 0);--color-base-200:oklch(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% .006 285.885);--color-primary:oklch(45% .24 277.023);--color-primary-content:oklch(93% .034 272.788);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}@media (prefers-color-scheme:dark){:root{color-scheme:dark;--color-base-100:oklch(25.33% .016 252.42);--color-base-200:oklch(23.26% .014 253.1);--color-base-300:oklch(21.15% .012 254.09);--color-base-content:oklch(97.807% .029 256.847);--color-primary:oklch(58% .233 277.117);--color-primary-content:oklch(96% .018 272.314);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}}:root:has(input.theme-controller[value=light]:checked),[data-theme=light]{color-scheme:light;--color-base-100:oklch(100% 0 0);--color-base-200:oklch(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% .006 285.885);--color-primary:oklch(45% .24 277.023);--color-primary-content:oklch(93% .034 272.788);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}:root:has(input.theme-controller[value=dark]:checked),[data-theme=dark]{color-scheme:dark;--color-base-100:oklch(25.33% .016 252.42);--color-base-200:oklch(23.26% .014 253.1);--color-base-300:oklch(21.15% .012 254.09);--color-base-content:oklch(97.807% .029 256.847);--color-primary:oklch(58% .233 277.117);--color-primary-content:oklch(96% .018 272.314);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}@property --radialprogress{syntax: "<percentage>"; inherits: true; initial-value: 0%;}:root{scrollbar-color:currentColor #0000}@supports (color:color-mix(in lab,red,red)){:root{scrollbar-color:color-mix(in oklch,currentColor 35%,#0000)#0000}}:root{--fx-noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E")}:root:has(.modal-open,.modal[open],.modal:target,.modal-toggle:checked,.drawer:not([class*=drawer-open])>.drawer-toggle:checked){overflow:hidden}:where(:root:has(.modal-open,.modal[open],.modal:target,.modal-toggle:checked,.drawer:not(.drawer-open)>.drawer-toggle:checked)){scrollbar-gutter:stable;background-image:linear-gradient(var(--color-base-100),var(--color-base-100));--root-bg:var(--color-base-100)}@supports (color:color-mix(in lab,red,red)){:where(:root:has(.modal-open,.modal[open],.modal:target,.modal-toggle:checked,.drawer:not(.drawer-open)>.drawer-toggle:checked)){--root-bg:color-mix(in srgb,var(--color-base-100),oklch(0% 0 0) 40%)}}:where(.modal[open],.modal-open,.modal-toggle:checked+.modal):not(.modal-start,.modal-end){scrollbar-gutter:stable}:root,[data-theme]{background-color:var(--root-bg,var(--color-base-100));color:var(--color-base-content)}}@layer components;@layer utilities{.diff{webkit-user-select:none;-webkit-user-select:none;user-select:none;direction:ltr;grid-template-columns:auto 1fr;width:100%;display:grid;position:relative;overflow:hidden;container-type:inline-size}.diff:focus-visible,.diff:has(.diff-item-1:focus-visible){outline-style:var(--tw-outline-style);outline-offset:1px;outline-width:2px;outline-color:var(--color-base-content)}.diff:focus-visible .diff-resizer{min-width:90cqi;max-width:90cqi}.diff:has(.diff-item-2:focus-visible){outline-style:var(--tw-outline-style);outline-offset:1px;outline-width:2px}.diff:has(.diff-item-2:focus-visible) .diff-resizer{min-width:10cqi;max-width:10cqi}@supports (-webkit-overflow-scrolling:touch) and (overflow:-webkit-paged-x){.diff:focus .diff-resizer{min-width:10cqi;max-width:10cqi}.diff:has(.diff-item-1:focus) .diff-resizer{min-width:90cqi;max-width:90cqi}}.tab{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-align:center;webkit-user-select:none;-webkit-user-select:none;user-select:none;flex-wrap:wrap;justify-content:center;align-items:center;display:inline-flex;position:relative}@media (hover:hover){.tab:hover{color:var(--color-base-content)}}.tab{--tab-p:1rem;--tab-bg:var(--color-base-100);--tab-border-color:var(--color-base-300);--tab-radius-ss:0;--tab-radius-se:0;--tab-radius-es:0;--tab-radius-ee:0;--tab-order:0;--tab-radius-min:calc(.75rem - var(--border));order:var(--tab-order);height:var(--tab-height);border-color:#0000;padding-inline-start:var(--tab-p);padding-inline-end:var(--tab-p);font-size:.875rem}.tab:is(input[type=radio]){min-width:fit-content}.tab:is(input[type=radio]):after{content:attr(aria-label)}.tab:is(label){position:relative}.tab:is(label) input{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0;position:absolute;top:0;right:0;bottom:0;left:0}:is(.tab:checked,.tab:is(label:has(:checked)),.tab:is(.tab-active,[aria-selected=true]))+.tab-content{height:calc(100% - var(--tab-height) + var(--border));display:block}.tab:not(:checked,label:has(:checked),:hover,.tab-active,[aria-selected=true]){color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.tab:not(:checked,label:has(:checked),:hover,.tab-active,[aria-selected=true]){color:color-mix(in oklab,var(--color-base-content)50%,transparent)}}.tab:not(input):empty{cursor:default;flex-grow:1}.tab:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.tab:focus{outline-offset:2px;outline:2px solid #0000}}.tab:focus-visible,.tab:is(label:has(:checked:focus-visible)){outline-offset:-5px;outline:2px solid}.tab[disabled]{pointer-events:none;opacity:.4}.collapse-arrow>.collapse-title:after{content:"";transform-origin:75% 75%;pointer-events:none;top:1.9rem;width:.5rem;height:.5rem;transition-property:all;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);display:block;position:absolute;inset-inline-end:1.4rem;transform:translateY(-100%)rotate(45deg);box-shadow:2px 2px}:where(.btn){width:unset}.btn{cursor:pointer;text-align:center;vertical-align:middle;outline-offset:2px;webkit-user-select:none;-webkit-user-select:none;user-select:none;padding-inline:var(--btn-p);color:var(--btn-fg);--tw-prose-links:var(--btn-fg);height:var(--size);font-size:var(--fontsize,.875rem);outline-color:var(--btn-color,var(--color-base-content));background-color:var(--btn-bg);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--btn-noise);border-width:var(--border);border-style:solid;border-color:var(--btn-border);text-shadow:0 .5px oklch(100% 0 0/calc(var(--depth)*.15));touch-action:manipulation;box-shadow:0 .5px 0 .5px oklch(100% 0 0/calc(var(--depth)*6%)) inset,var(--btn-shadow);--size:calc(var(--size-field,.25rem)*10);--btn-bg:var(--btn-color,var(--color-base-200));--btn-fg:var(--color-base-content);--btn-p:1rem;--btn-border:var(--btn-bg);border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-wrap:nowrap;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;font-weight:600;transition-property:color,background-color,border-color,box-shadow;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);display:inline-flex}@supports (color:color-mix(in lab,red,red)){.btn{--btn-border:color-mix(in oklab,var(--btn-bg),#000 calc(var(--depth)*5%))}}.btn{--btn-shadow:0 3px 2px -2px var(--btn-bg),0 4px 3px -2px var(--btn-bg)}@supports (color:color-mix(in lab,red,red)){.btn{--btn-shadow:0 3px 2px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000),0 4px 3px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000)}}.btn{--btn-noise:var(--fx-noise)}.prose .btn{text-decoration-line:none}@media (hover:hover){.btn:hover{--btn-bg:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab,red,red)){.btn:hover{--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}}.btn:focus-visible{isolation:isolate;outline-width:2px;outline-style:solid}.btn:active:not(.btn-active){--btn-bg:var(--btn-color,var(--color-base-200));translate:0 .5px}@supports (color:color-mix(in lab,red,red)){.btn:active:not(.btn-active){--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 5%)}}.btn:active:not(.btn-active){--btn-border:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab,red,red)){.btn:active:not(.btn-active){--btn-border:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}.btn:active:not(.btn-active){--btn-shadow:0 0 0 0 oklch(0% 0 0/0),0 0 0 0 oklch(0% 0 0/0)}.btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){background-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}.btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){box-shadow:none}.btn:is(:disabled,[disabled],.btn-disabled){pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.btn:is(:disabled,[disabled],.btn-disabled){--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}@media (hover:hover){.btn:is(:disabled,[disabled],.btn-disabled):hover{pointer-events:none;background-color:var(--color-neutral)}@supports (color:color-mix(in lab,red,red)){.btn:is(:disabled,[disabled],.btn-disabled):hover{background-color:color-mix(in oklab,var(--color-neutral)20%,transparent)}}.btn:is(:disabled,[disabled],.btn-disabled):hover{--btn-border:#0000;--btn-fg:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.btn:is(:disabled,[disabled],.btn-disabled):hover{--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}}.btn:is(input[type=checkbox],input[type=radio]){-webkit-appearance:none;-moz-appearance:none;appearance:none}.btn:is(input[type=checkbox],input[type=radio]):after{content:attr(aria-label)}.btn:where(input:checked:not(.filter .btn)){--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content);isolation:isolate}.loading{pointer-events:none;aspect-ratio:1;vertical-align:middle;width:calc(var(--size-selector,.25rem)*6);background-color:currentColor;display:inline-block;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.pointer-events-none{pointer-events:none}.collapse:not(td,tr,colgroup){visibility:visible}.collapse{border-radius:var(--radius-box,1rem);isolation:isolate;grid-template-rows:max-content 0fr;width:100%;transition:grid-template-rows .2s;display:grid;position:relative;overflow:hidden}.collapse>input:is([type=checkbox],[type=radio]){-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0;z-index:1;grid-row-start:1;grid-column-start:1;width:100%;min-height:1lh;padding:1rem;padding-inline-end:3rem;transition:background-color .2s ease-out}.collapse:is([open],:focus:not(.collapse-close)),.collapse:not(.collapse-close):has(>input:is([type=checkbox],[type=radio]):checked){grid-template-rows:max-content 1fr}.collapse:is([open],:focus:not(.collapse-close))>.collapse-content,.collapse:not(.collapse-close)>:where(input:is([type=checkbox],[type=radio]):checked~.collapse-content){visibility:visible;min-height:fit-content}.collapse:focus-visible,.collapse:has(>input:is([type=checkbox],[type=radio]):focus-visible){outline-color:var(--color-base-content);outline-offset:2px;outline-width:2px;outline-style:solid}.collapse:not(.collapse-close)>input[type=checkbox],.collapse:not(.collapse-close)>input[type=radio]:not(:checked),.collapse:not(.collapse-close)>.collapse-title{cursor:pointer}.collapse:focus:not(.collapse-close,.collapse[open])>.collapse-title{cursor:unset}.collapse:is([open],:focus:not(.collapse-close))>:where(.collapse-content),.collapse:not(.collapse-close)>:where(input:is([type=checkbox],[type=radio]):checked~.collapse-content){padding-bottom:1rem;transition:padding .2s ease-out,background-color .2s ease-out}.collapse[open].collapse-arrow>.collapse-title:after,.collapse.collapse-open.collapse-arrow>.collapse-title:after{transform:translateY(-50%)rotate(225deg)}.collapse.collapse-open.collapse-plus>.collapse-title:after{content:"−"}.collapse.collapse-arrow:focus:not(.collapse-close)>.collapse-title:after,.collapse.collapse-arrow:not(.collapse-close)>input:is([type=checkbox],[type=radio]):checked~.collapse-title:after{transform:translateY(-50%)rotate(225deg)}.collapse[open].collapse-plus>.collapse-title:after,.collapse.collapse-plus:focus:not(.collapse-close)>.collapse-title:after,.collapse.collapse-plus:not(.collapse-close)>input:is([type=checkbox],[type=radio]):checked~.collapse-title:after{content:"−"}.collapse:is(details){width:100%}.collapse:is(details) summary{display:block;position:relative}.collapse:is(details) summary::-webkit-details-marker{display:none}.collapse:is(details) summary{outline:none}.collapse-content{visibility:hidden;min-height:0;cursor:unset;grid-row-start:2;grid-column-start:1;padding-left:1rem;padding-right:1rem;transition:visibility .2s,padding .2s ease-out,background-color .2s ease-out}.collapse{visibility:collapse}.visible{visibility:visible}.toggle{border:var(--border)solid currentColor;color:var(--input-color);cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;vertical-align:middle;webkit-user-select:none;-webkit-user-select:none;user-select:none;--radius-selector-max:calc(var(--radius-selector) + var(--radius-selector) + var(--radius-selector));border-radius:calc(var(--radius-selector) + min(var(--toggle-p),var(--radius-selector-max)) + min(var(--border),var(--radius-selector-max)));padding:var(--toggle-p);flex-shrink:0;grid-template-columns:0fr 1fr 1fr;place-content:center;display:inline-grid;position:relative;box-shadow:inset 0 1px}@supports (color:color-mix(in lab,red,red)){.toggle{box-shadow:0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000) inset}}.toggle{--input-color:var(--color-base-content);transition:color .3s,grid-template-columns .2s}@supports (color:color-mix(in lab,red,red)){.toggle{--input-color:color-mix(in oklab,var(--color-base-content)50%,#0000)}}.toggle{--toggle-p:calc(var(--size)*.125);--size:calc(var(--size-selector,.25rem)*6);width:calc((var(--size)*2) - (var(--border) + var(--toggle-p))*2);height:var(--size)}.toggle>*{z-index:1;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#0000;border:none;grid-column:2/span 1;grid-row-start:1;height:100%;padding:.125rem;transition:opacity .2s,rotate .4s}.toggle>:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.toggle>:focus{outline-offset:2px;outline:2px solid #0000}}.toggle>:nth-child(2){color:var(--color-base-100);rotate:none}.toggle>:nth-child(3){color:var(--color-base-100);opacity:0;rotate:-15deg}.toggle:has(:checked)>:nth-child(2){opacity:0;rotate:15deg}.toggle:has(:checked)>:nth-child(3){opacity:1;rotate:none}.toggle:before{aspect-ratio:1;border-radius:var(--radius-selector);--tw-content:"";content:var(--tw-content);height:100%;box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor;background-color:currentColor;grid-row-start:1;grid-column-start:2;transition:background-color .1s,translate .2s,inset-inline-start .2s;position:relative;inset-inline-start:0;translate:0}@supports (color:color-mix(in lab,red,red)){.toggle:before{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000)}}.toggle:before{background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise)}@media (forced-colors:active){.toggle:before{outline-style:var(--tw-outline-style);outline-offset:-1px;outline-width:1px}}@media print{.toggle:before{outline-offset:-1rem;outline:.25rem solid}}.toggle:focus-visible,.toggle:has(:focus-visible){outline-offset:2px;outline:2px solid}.toggle:checked,.toggle[aria-checked=true],.toggle:has(>input:checked){background-color:var(--color-base-100);--input-color:var(--color-base-content);grid-template-columns:1fr 1fr 0fr}:is(.toggle:checked,.toggle[aria-checked=true],.toggle:has(>input:checked)):before{background-color:currentColor}@starting-style{:is(.toggle:checked,.toggle[aria-checked=true],.toggle:has(>input:checked)):before{opacity:0}}.toggle:indeterminate{grid-template-columns:.5fr 1fr .5fr}.toggle:disabled{cursor:not-allowed;opacity:.3}.toggle:disabled:before{border:var(--border)solid currentColor;background-color:#0000}.input{cursor:text;border:var(--border)solid #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--color-base-100);vertical-align:middle;white-space:nowrap;width:clamp(3rem,20rem,100%);height:var(--size);touch-action:manipulation;border-color:var(--input-color);box-shadow:0 1px var(--input-color) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset;border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-shrink:1;align-items:center;gap:.5rem;padding-inline:.75rem;font-size:.875rem;display:inline-flex;position:relative}@supports (color:color-mix(in lab,red,red)){.input{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset}}.input{--size:calc(var(--size-field,.25rem)*10);--input-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.input{--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.input:where(input){display:inline-flex}.input :where(input){-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#0000;border:none;width:100%;height:100%;display:inline-flex}.input :where(input):focus,.input :where(input):focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.input :where(input):focus,.input :where(input):focus-within{outline-offset:2px;outline:2px solid #0000}}.input :where(input[type=url]),.input :where(input[type=email]){direction:ltr}.input :where(input[type=date]){display:inline-block}.input:focus,.input:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab,red,red)){.input:focus,.input:focus-within{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.input:focus,.input:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate;z-index:1}.input:has(>input[disabled]),.input:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.input:has(>input[disabled]),.input:is(:disabled,[disabled]){color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]))::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]))::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.input:has(>input[disabled]),.input:is(:disabled,[disabled]){box-shadow:none}.input:has(>input[disabled])>input[disabled]{cursor:not-allowed}.input::-webkit-date-and-time-value{text-align:inherit}.input[type=number]::-webkit-inner-spin-button{margin-block:-.75rem;margin-inline-end:-.75rem}.input::-webkit-calendar-picker-indicator{position:absolute;inset-inline-end:.75em}.table{border-radius:var(--radius-box);text-align:left;width:100%;font-size:.875rem;position:relative}.table:where(:dir(rtl),[dir=rtl],[dir=rtl] *){text-align:right}@media (hover:hover){:is(.table tr.row-hover,.table tr.row-hover:nth-child(2n)):hover{background-color:var(--color-base-200)}}.table :where(th,td){vertical-align:middle;padding-block:.75rem;padding-inline:1rem}.table :where(thead,tfoot){white-space:nowrap;color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.table :where(thead,tfoot){color:color-mix(in oklab,var(--color-base-content)60%,transparent)}}.table :where(thead,tfoot){font-size:.875rem;font-weight:600}.table :where(tfoot){border-top:var(--border)solid var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.table :where(tfoot){border-top:var(--border)solid color-mix(in oklch,var(--color-base-content)5%,#0000)}}.table :where(.table-pin-rows thead tr){z-index:1;background-color:var(--color-base-100);position:sticky;top:0}.table :where(.table-pin-rows tfoot tr){z-index:1;background-color:var(--color-base-100);position:sticky;bottom:0}.table :where(.table-pin-cols tr th){background-color:var(--color-base-100);position:sticky;left:0;right:0}.table :where(thead tr,tbody tr:not(:last-child)){border-bottom:var(--border)solid var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.table :where(thead tr,tbody tr:not(:last-child)){border-bottom:var(--border)solid color-mix(in oklch,var(--color-base-content)5%,#0000)}}.steps{counter-reset:step;grid-auto-columns:1fr;grid-auto-flow:column;display:inline-grid;overflow:auto hidden}.steps .step{text-align:center;--step-bg:var(--color-base-300);--step-fg:var(--color-base-content);grid-template-rows:40px 1fr;grid-template-columns:auto;place-items:center;min-width:4rem;display:grid}.steps .step:before{width:100%;height:.5rem;color:var(--step-bg);background-color:var(--step-bg);--tw-content:"";content:var(--tw-content);border:1px solid;grid-row-start:1;grid-column-start:1;margin-inline-start:-100%;top:0}.steps .step>.step-icon,.steps .step:not(:has(.step-icon)):after{content:counter(step);counter-increment:step;z-index:1;color:var(--step-fg);background-color:var(--step-bg);border:1px solid var(--step-bg);border-radius:3.40282e38px;grid-row-start:1;grid-column-start:1;place-self:center;place-items:center;width:2rem;height:2rem;display:grid;position:relative}.steps .step:first-child:before{content:none}.steps .step[data-content]:after{content:attr(data-content)}.steps .step-neutral+.step-neutral:before,.steps .step-neutral:after,.steps .step-neutral>.step-icon{--step-bg:var(--color-neutral);--step-fg:var(--color-neutral-content)}.steps .step-primary+.step-primary:before,.steps .step-primary:after,.steps .step-primary>.step-icon{--step-bg:var(--color-primary);--step-fg:var(--color-primary-content)}.steps .step-secondary+.step-secondary:before,.steps .step-secondary:after,.steps .step-secondary>.step-icon{--step-bg:var(--color-secondary);--step-fg:var(--color-secondary-content)}.steps .step-accent+.step-accent:before,.steps .step-accent:after,.steps .step-accent>.step-icon{--step-bg:var(--color-accent);--step-fg:var(--color-accent-content)}.steps .step-info+.step-info:before,.steps .step-info:after,.steps .step-info>.step-icon{--step-bg:var(--color-info);--step-fg:var(--color-info-content)}.steps .step-success+.step-success:before,.steps .step-success:after,.steps .step-success>.step-icon{--step-bg:var(--color-success);--step-fg:var(--color-success-content)}.steps .step-warning+.step-warning:before,.steps .step-warning:after,.steps .step-warning>.step-icon{--step-bg:var(--color-warning);--step-fg:var(--color-warning-content)}.steps .step-error+.step-error:before,.steps .step-error:after,.steps .step-error>.step-icon{--step-bg:var(--color-error);--step-fg:var(--color-error-content)}.range{-webkit-appearance:none;-moz-appearance:none;appearance:none;webkit-appearance:none;--range-thumb:var(--color-base-100);--range-thumb-size:calc(var(--size-selector,.25rem)*6);--range-progress:currentColor;--range-fill:1;--range-p:.25rem;--range-bg:currentColor}@supports (color:color-mix(in lab,red,red)){.range{--range-bg:color-mix(in oklab,currentColor 10%,#0000)}}.range{cursor:pointer;vertical-align:middle;--radius-selector-max:calc(var(--radius-selector) + var(--radius-selector) + var(--radius-selector));border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));width:clamp(3rem,20rem,100%);height:var(--range-thumb-size);background-color:#0000;border:none;overflow:hidden}[dir=rtl] .range{--range-dir:-1}.range:focus{outline:none}.range:focus-visible{outline-offset:2px;outline:2px solid}.range::-webkit-slider-runnable-track{background-color:var(--range-bg);border-radius:var(--radius-selector);width:100%;height:calc(var(--range-thumb-size)*.5)}@media (forced-colors:active){.range::-webkit-slider-runnable-track{border:1px solid}.range::-moz-range-track{border:1px solid}}.range::-webkit-slider-thumb{box-sizing:border-box;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));height:var(--range-thumb-size);width:var(--range-thumb-size);border:var(--range-p)solid;-webkit-appearance:none;-moz-appearance:none;appearance:none;webkit-appearance:none;color:var(--range-progress);box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor,0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill));background-color:currentColor;position:relative;top:50%;transform:translateY(-50%)}@supports (color:color-mix(in lab,red,red)){.range::-webkit-slider-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))}}.range::-moz-range-track{background-color:var(--range-bg);border-radius:var(--radius-selector);width:100%;height:calc(var(--range-thumb-size)*.5)}.range::-moz-range-thumb{box-sizing:border-box;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));height:var(--range-thumb-size);width:var(--range-thumb-size);border:var(--range-p)solid;color:var(--range-progress);box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor,0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill));background-color:currentColor;position:relative;top:50%}@supports (color:color-mix(in lab,red,red)){.range::-moz-range-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))}}.range:disabled{cursor:not-allowed;opacity:.3}.range\!{-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;webkit-appearance:none!important;--range-thumb:var(--color-base-100)!important;--range-thumb-size:calc(var(--size-selector,.25rem)*6)!important;--range-progress:currentColor!important;--range-fill:1!important;--range-p:.25rem!important;--range-bg:currentColor!important}@supports (color:color-mix(in lab,red,red)){.range\!{--range-bg:color-mix(in oklab,currentColor 10%,#0000)!important}}.range\!{cursor:pointer!important;vertical-align:middle!important;--radius-selector-max:calc(var(--radius-selector) + var(--radius-selector) + var(--radius-selector))!important;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)))!important;width:clamp(3rem,20rem,100%)!important;height:var(--range-thumb-size)!important;background-color:#0000!important;border:none!important;overflow:hidden!important}[dir=rtl] .range\!{--range-dir:-1!important}.range\!:focus{outline:none!important}.range\!:focus-visible{outline-offset:2px!important;outline:2px solid!important}.range\!::-webkit-slider-runnable-track{background-color:var(--range-bg)!important;border-radius:var(--radius-selector)!important;width:100%!important;height:calc(var(--range-thumb-size)*.5)!important}@media (forced-colors:active){.range\!::-webkit-slider-runnable-track{border:1px solid!important}.range\!::-moz-range-track{border:1px solid!important}}.range\!::-webkit-slider-thumb{box-sizing:border-box!important;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)))!important;height:var(--range-thumb-size)!important;width:var(--range-thumb-size)!important;border:var(--range-p)solid!important;-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;webkit-appearance:none!important;color:var(--range-progress)!important;box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor,0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))!important;background-color:currentColor!important;position:relative!important;top:50%!important;transform:translateY(-50%)!important}@supports (color:color-mix(in lab,red,red)){.range\!::-webkit-slider-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))!important}}.range\!::-moz-range-track{background-color:var(--range-bg)!important;border-radius:var(--radius-selector)!important;width:100%!important;height:calc(var(--range-thumb-size)*.5)!important}.range\!::-moz-range-thumb{box-sizing:border-box!important;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)))!important;height:var(--range-thumb-size)!important;width:var(--range-thumb-size)!important;border:var(--range-p)solid!important;color:var(--range-progress)!important;box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor,0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))!important;background-color:currentColor!important;position:relative!important;top:50%!important}@supports (color:color-mix(in lab,red,red)){.range\!::-moz-range-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100rem*var(--range-fill))!important}}.range\!:disabled{cursor:not-allowed!important;opacity:.3!important}.tabs-border .tab{--tab-border-color:#0000 #0000 var(--tab-border-color)#0000;border-radius:var(--radius-field);position:relative}.tabs-border .tab:before{--tw-content:"";content:var(--tw-content);background-color:var(--tab-border-color);border-radius:var(--radius-field);width:80%;height:3px;transition:background-color .2s;position:absolute;bottom:0;left:10%}:is(.tabs-border .tab:is(.tab-active,[aria-selected=true]):not(.tab-disabled,[disabled]),.tabs-border .tab:is(input:checked),.tabs-border .tab:is(label:has(:checked))):before{--tab-border-color:currentColor;border-top:3px solid}.select{border:var(--border)solid #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--color-base-100);vertical-align:middle;width:clamp(3rem,20rem,100%);height:var(--size);touch-action:manipulation;text-overflow:ellipsis;box-shadow:0 1px var(--input-color) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset;background-image:linear-gradient(45deg,#0000 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,#0000 50%);background-position:calc(100% - 20px) calc(1px + 50%),calc(100% - 16.1px) calc(1px + 50%);background-repeat:no-repeat;background-size:4px 4px,4px 4px;border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-shrink:1;align-items:center;gap:.375rem;padding-inline:1rem 1.75rem;font-size:.875rem;display:inline-flex;position:relative}@supports (color:color-mix(in lab,red,red)){.select{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset}}.select{border-color:var(--input-color);--input-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.select{--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.select{--size:calc(var(--size-field,.25rem)*10)}[dir=rtl] .select{background-position:12px calc(1px + 50%),16px calc(1px + 50%)}.select select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:inherit;border-radius:inherit;border-style:none;width:calc(100% + 2.75rem);height:calc(100% - 2px);margin-inline:-1rem -1.75rem;padding-inline:1rem 1.75rem}.select select:focus,.select select:focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.select select:focus,.select select:focus-within{outline-offset:2px;outline:2px solid #0000}}.select select:not(:last-child){background-image:none;margin-inline-end:-1.375rem}.select:focus,.select:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab,red,red)){.select:focus,.select:focus-within{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.select:focus,.select:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate;z-index:1}.select:has(>select[disabled]),.select:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.select:has(>select[disabled]),.select:is(:disabled,[disabled]){color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.select:has(>select[disabled]),.select:is(:disabled,[disabled]))::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){:is(.select:has(>select[disabled]),.select:is(:disabled,[disabled]))::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.select:has(>select[disabled])>select[disabled]{cursor:not-allowed}.timeline{display:flex;position:relative}.timeline>li{grid-template-rows:var(--timeline-row-start,minmax(0,1fr))auto var(--timeline-row-end,minmax(0,1fr));grid-template-columns:var(--timeline-col-start,minmax(0,1fr))auto var(--timeline-col-end,minmax(0,1fr));flex-shrink:0;align-items:center;display:grid;position:relative}.timeline>li>hr{border:none;width:100%}.timeline>li>hr:first-child{grid-row-start:2;grid-column-start:1}.timeline>li>hr:last-child{grid-area:2/3/auto/none}@media print{.timeline>li>hr{border:.1px solid var(--color-base-300)}}.timeline :where(hr){background-color:var(--color-base-300);height:.25rem}.timeline:has(.timeline-middle hr):first-child{border-start-start-radius:0;border-start-end-radius:var(--radius-selector);border-end-end-radius:var(--radius-selector);border-end-start-radius:0}.timeline:has(.timeline-middle hr):last-child,.timeline:not(:has(.timeline-middle)) :first-child hr:last-child{border-start-start-radius:var(--radius-selector);border-start-end-radius:0;border-end-end-radius:0;border-end-start-radius:var(--radius-selector)}.timeline:not(:has(.timeline-middle)) :last-child hr:first-child{border-start-start-radius:0;border-start-end-radius:var(--radius-selector);border-end-end-radius:var(--radius-selector);border-end-start-radius:0}.collapse-title{grid-row-start:1;grid-column-start:1;width:100%;min-height:1lh;padding:1rem;padding-inline-end:3rem;transition:background-color .2s ease-out;position:relative}.checkbox{border:var(--border)solid var(--input-color,var(--color-base-content))}@supports (color:color-mix(in lab,red,red)){.checkbox{border:var(--border)solid var(--input-color,color-mix(in oklab,var(--color-base-content)20%,#0000))}}.checkbox{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-selector);vertical-align:middle;color:var(--color-base-content);box-shadow:0 1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 0 #0000 inset,0 0 #0000;--size:calc(var(--size-selector,.25rem)*6);width:var(--size);height:var(--size);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);flex-shrink:0;padding:.25rem;transition:background-color .2s,box-shadow .2s;display:inline-block;position:relative}.checkbox:before{--tw-content:"";content:var(--tw-content);opacity:0;clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,70% 80%,70% 100%);width:100%;height:100%;box-shadow:0 3px oklch(100% 0 0/calc(var(--depth)*.1)) inset;background-color:currentColor;font-size:1rem;line-height:.75;transition:clip-path .3s .1s,opacity .1s .1s,rotate .3s .1s,translate .3s .1s;display:block;rotate:45deg}.checkbox:focus-visible{outline:2px solid var(--input-color,currentColor);outline-offset:2px}.checkbox:checked,.checkbox[aria-checked=true]{background-color:var(--input-color,#0000);box-shadow:0 0 #0000 inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px oklch(0% 0 0/calc(var(--depth)*.1))}:is(.checkbox:checked,.checkbox[aria-checked=true]):before{clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 0%,70% 0%,70% 100%);opacity:1}@media (forced-colors:active){:is(.checkbox:checked,.checkbox[aria-checked=true]):before{--tw-content:"✔︎";clip-path:none;background-color:#0000;rotate:none}}@media print{:is(.checkbox:checked,.checkbox[aria-checked=true]):before{--tw-content:"✔︎";clip-path:none;background-color:#0000;rotate:none}}.checkbox:indeterminate:before{opacity:1;clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,80% 80%,80% 100%);translate:0 -35%;rotate:none}.checkbox:disabled{cursor:not-allowed;opacity:.2}.radio{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;vertical-align:middle;border:var(--border)solid var(--input-color,currentColor);border-radius:3.40282e38px;flex-shrink:0;padding:.25rem;display:inline-block;position:relative}@supports (color:color-mix(in lab,red,red)){.radio{border:var(--border)solid var(--input-color,color-mix(in srgb,currentColor 20%,#0000))}}.radio{box-shadow:0 1px oklch(0% 0 0/calc(var(--depth)*.1)) inset;--size:calc(var(--size-selector,.25rem)*6);width:var(--size);height:var(--size);color:var(--input-color,currentColor)}.radio:before{--tw-content:"";content:var(--tw-content);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);border-radius:3.40282e38px;width:100%;height:100%;display:block}.radio:focus-visible{outline:2px solid}.radio:checked,.radio[aria-checked=true]{background-color:var(--color-base-100);border-color:currentColor;animation:.2s ease-out radio}:is(.radio:checked,.radio[aria-checked=true]):before{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px oklch(0% 0 0/calc(var(--depth)*.1));background-color:currentColor}@media (forced-colors:active){:is(.radio:checked,.radio[aria-checked=true]):before{outline-style:var(--tw-outline-style);outline-offset:-1px;outline-width:1px}}@media print{:is(.radio:checked,.radio[aria-checked=true]):before{outline-offset:-1rem;outline:.25rem solid}}.radio:disabled{cursor:not-allowed;opacity:.2}.stats{border-radius:var(--radius-box);grid-auto-flow:column;display:inline-grid;position:relative;overflow-x:auto}.progress{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-box);background-color:currentColor;width:100%;height:.5rem;position:relative;overflow:hidden}@supports (color:color-mix(in lab,red,red)){.progress{background-color:color-mix(in oklab,currentColor 20%,transparent)}}.progress{color:var(--color-base-content)}.progress:indeterminate{background-image:repeating-linear-gradient(90deg,currentColor -1% 10%,#0000 10% 90%);background-position-x:15%;background-size:200%;animation:5s ease-in-out infinite progress}@supports ((-moz-appearance:none)){.progress:indeterminate::-moz-progress-bar{background-color:#0000;background-image:repeating-linear-gradient(90deg,currentColor -1% 10%,#0000 10% 90%);background-position-x:15%;background-size:200%;animation:5s ease-in-out infinite progress}.progress::-moz-progress-bar{border-radius:var(--radius-box);background-color:currentColor}}@supports ((-webkit-appearance:none)){.progress::-webkit-progress-bar{border-radius:var(--radius-box);background-color:#0000}.progress::-webkit-progress-value{border-radius:var(--radius-box);background-color:currentColor}}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.top-0{top:calc(var(--spacing)*0)}.top-1\/2{top:50%}.top-12{top:calc(var(--spacing)*12)}.right-0{right:calc(var(--spacing)*0)}.right-2{right:calc(var(--spacing)*2)}.left-0{left:calc(var(--spacing)*0)}.textarea{border:var(--border)solid #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-field);background-color:var(--color-base-100);vertical-align:middle;touch-action:manipulation;border-color:var(--input-color);width:clamp(3rem,20rem,100%);min-height:5rem;box-shadow:0 1px var(--input-color) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset;flex-shrink:1;padding-block:.5rem;padding-inline:.75rem;font-size:.875rem}@supports (color:color-mix(in lab,red,red)){.textarea{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset}}.textarea{--input-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.textarea{--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.textarea textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#0000;border:none}.textarea textarea:focus,.textarea textarea:focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.textarea textarea:focus,.textarea textarea:focus-within{outline-offset:2px;outline:2px solid #0000}}.textarea:focus,.textarea:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab,red,red)){.textarea:focus,.textarea:focus-within{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.textarea:focus,.textarea:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate}.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]){color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]))::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){:is(.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]))::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]){box-shadow:none}.textarea:has(>textarea[disabled])>textarea[disabled]{cursor:not-allowed}.stack{grid-template-rows:3px 4px 1fr 4px 3px;grid-template-columns:3px 4px 1fr 4px 3px;display:inline-grid}.stack>*{width:100%;height:100%}.stack>:nth-child(n+2){opacity:.7;width:100%}.stack>:nth-child(2){z-index:2;opacity:.9}.stack>:first-child{z-index:3;width:100%}:is(.stack,.stack.stack-bottom)>*{grid-area:3/3/6/4}:is(.stack,.stack.stack-bottom)>:nth-child(2){grid-area:2/2/5/5}:is(.stack,.stack.stack-bottom)>:first-child{grid-area:1/1/4/6}.stack.stack-top>*{grid-area:1/3/4/4}.stack.stack-top>:nth-child(2){grid-area:2/2/5/5}.stack.stack-top>:first-child{grid-area:3/1/6/6}.stack.stack-start>*{grid-area:3/1/4/4}.stack.stack-start>:nth-child(2){grid-area:2/2/5/5}.stack.stack-start>:first-child{grid-area:1/3/6/6}.stack.stack-end>*{grid-area:3/3/4/6}.stack.stack-end>:nth-child(2){grid-area:2/2/5/5}.stack.stack-end>:first-child{grid-area:1/1/6/4}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.tab-content{order:var(--tabcontent-order);--tabcontent-radius-ss:0;--tabcontent-radius-se:0;--tabcontent-radius-es:0;--tabcontent-radius-ee:0;--tabcontent-order:1;width:100%;margin:var(--tabcontent-margin);border-color:#0000;border-width:var(--border);border-start-start-radius:var(--tabcontent-radius-ss);border-start-end-radius:var(--tabcontent-radius-se);border-end-end-radius:var(--tabcontent-radius-ee);border-end-start-radius:var(--tabcontent-radius-es);display:none}.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}}.container\!{width:100%!important}@media (min-width:40rem){.container\!{max-width:40rem!important}}@media (min-width:48rem){.container\!{max-width:48rem!important}}@media (min-width:64rem){.container\!{max-width:64rem!important}}@media (min-width:80rem){.container\!{max-width:80rem!important}}@media (min-width:96rem){.container\!{max-width:96rem!important}}.filter{flex-wrap:wrap;display:flex}.filter input[type=radio]{width:auto}.filter input{opacity:1;transition:margin .1s,opacity .3s,padding .3s,border-width .1s;overflow:hidden;scale:1}.filter input:not(:last-child){margin-inline-end:.25rem}.filter input.filter-reset{aspect-ratio:1}.filter input.filter-reset:after{content:"×"}.filter:not(:has(input:checked:not(.filter-reset))) .filter-reset,.filter:not(:has(input:checked:not(.filter-reset))) input[type=reset],.filter:has(input:checked:not(.filter-reset)) input:not(:checked,.filter-reset,input[type=reset]){opacity:0;border-width:0;width:0;margin-inline:0;padding-inline:0;scale:0}.mx-auto{margin-inline:auto}.input-sm{--size:calc(var(--size-field,.25rem)*8);font-size:.75rem}.input-sm[type=number]::-webkit-inner-spin-button{margin-block:-.5rem;margin-inline-end:-.75rem}.my-4{margin-block:calc(var(--spacing)*4)}.label{white-space:nowrap;color:currentColor;align-items:center;gap:.375rem;display:inline-flex}@supports (color:color-mix(in lab,red,red)){.label{color:color-mix(in oklab,currentColor 60%,transparent)}}.label:has(input){cursor:pointer}.label:is(.input>*,.select>*){white-space:nowrap;height:calc(100% - .5rem);font-size:inherit;align-items:center;padding-inline:.75rem;display:flex}.label:is(.input>*,.select>*):first-child{border-inline-end:var(--border)solid currentColor;margin-inline:-.75rem .75rem}@supports (color:color-mix(in lab,red,red)){.label:is(.input>*,.select>*):first-child{border-inline-end:var(--border)solid color-mix(in oklab,currentColor 10%,#0000)}}.label:is(.input>*,.select>*):last-child{border-inline-start:var(--border)solid currentColor;margin-inline:.75rem -.75rem}@supports (color:color-mix(in lab,red,red)){.label:is(.input>*,.select>*):last-child{border-inline-start:var(--border)solid color-mix(in oklab,currentColor 10%,#0000)}}.mt-8{margin-top:calc(var(--spacing)*8)}.mr-2{margin-right:calc(var(--spacing)*2)}.fieldset-legend{color:var(--color-base-content);justify-content:space-between;align-items:center;gap:.5rem;margin-bottom:-.25rem;padding-block:.5rem;font-weight:600;display:flex}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.status{aspect-ratio:1;border-radius:var(--radius-selector);background-color:var(--color-base-content);width:.5rem;height:.5rem;display:inline-block}@supports (color:color-mix(in lab,red,red)){.status{background-color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.status{vertical-align:middle;color:#0000004d;background-position:50%;background-repeat:no-repeat}@supports (color:color-mix(in lab,red,red)){.status{color:#0000004d}@supports (color:color-mix(in lab,red,red)){.status{color:color-mix(in oklab,var(--color-black)30%,transparent)}}}.status{background-image:radial-gradient(circle at 35% 30%,oklch(1 0 0/calc(var(--depth)*.5)),#0000);box-shadow:0 2px 3px -1px}@supports (color:color-mix(in lab,red,red)){.status{box-shadow:0 2px 3px -1px color-mix(in oklab,currentColor calc(var(--depth)*100%),#0000)}}.tabs{--tabs-height:auto;--tabs-direction:row;--tab-height:calc(var(--size-field,.25rem)*10);height:var(--tabs-height);flex-wrap:wrap;flex-direction:var(--tabs-direction);display:flex}.fieldset{grid-template-columns:1fr;grid-auto-rows:max-content;gap:.375rem;padding-block:.25rem;font-size:.75rem;display:grid}.card-title{font-size:var(--cardtitle-fs,1.125rem);align-items:center;gap:.5rem;font-weight:600;display:flex}.mask{vertical-align:middle;display:inline-block;-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.table{display:table}.btn-circle{width:var(--size);height:var(--size);border-radius:3.40282e38px;padding-inline:0}.h-4{height:calc(var(--spacing)*4)}.h-6{height:calc(var(--spacing)*6)}.h-64{height:calc(var(--spacing)*64)}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-\[80vh\]{max-height:80vh}.min-h-screen{min-height:100vh}.loading-lg{width:calc(var(--size-selector,.25rem)*7)}.w-4{width:calc(var(--spacing)*4)}.w-6{width:calc(var(--spacing)*6)}.w-11\/12{width:91.6667%}.w-48{width:calc(var(--spacing)*48)}.w-full{width:100%}.max-w-4xl{max-width:var(--container-4xl)}.max-w-full{max-width:100%}.min-w-\[220px\]{min-width:220px}.min-w-max{min-width:max-content}.flex-1{flex:1}.border-separate{border-collapse:separate}.border-spacing-0{--tw-border-spacing-x:calc(var(--spacing)*0);--tw-border-spacing-y:calc(var(--spacing)*0);border-spacing:var(--tw-border-spacing-x)var(--tw-border-spacing-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.link{cursor:pointer;text-decoration-line:underline}.link:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.link:focus{outline-offset:2px;outline:2px solid #0000}}.link:focus-visible{outline-offset:2px;outline:2px solid}.cursor-pointer{cursor:pointer}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-8{gap:calc(var(--spacing)*8)}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b-3{border-bottom-style:var(--tw-border-style);border-bottom-width:3px}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-700{border-color:var(--color-gray-700)}.border-b-gray-700{border-bottom-color:var(--color-gray-700)}.bg-base-100{background-color:var(--color-base-100)}.bg-base-200{background-color:var(--color-base-200)}.loading-spinner{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E")}.radio-sm{padding:.1875rem}.radio-sm[type=radio]{--size:calc(var(--size-selector,.25rem)*5)}.p-4{padding:calc(var(--spacing)*4)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.py-1{padding-block:calc(var(--spacing)*1)}.pt-4{padding-top:calc(var(--spacing)*4)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-8{padding-right:calc(var(--spacing)*8)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-10{padding-left:calc(var(--spacing)*10)}.text-center{text-align:center}.text-left{text-align:left}.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))}.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-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-gray-400{color:var(--color-gray-400)}.text-primary{color:var(--color-primary)}.text-red-500{color:var(--color-red-500)}.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)}.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible){--btn-shadow:"";--btn-bg:#0000;--btn-border:#0000;--btn-noise:none}.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible):not(:disabled,[disabled],.btn-disabled){--btn-fg:currentColor;outline-color:currentColor}@media (hover:none){.btn-ghost:hover:not(.btn-active,:active,:focus-visible,:disabled,[disabled],.btn-disabled){--btn-shadow:"";--btn-bg:#0000;--btn-border:#0000;--btn-noise:none;--btn-fg:currentColor}}.blur{--tw-blur:blur(8px);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,)}.invert{--tw-invert:invert(100%);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,)}.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,visibility,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\!{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,visibility,content-visibility,overlay,pointer-events!important;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function))!important;transition-duration:var(--tw-duration,var(--default-transition-duration))!important}.ease-in{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.hover\:bg-base-100:hover{background-color:var(--color-base-100)}.hover\:bg-base-200:hover{background-color:var(--color-base-200)}.hover\:bg-base-300:hover{background-color:var(--color-base-300)}}@media (min-width:48rem){.md\:w-1\/2{width:50%}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:gap-x-4{column-gap:calc(var(--spacing)*4)}}@media (min-width:64rem){.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}}@keyframes radio{0%{padding:5px}50%{padding:3px}}@keyframes skeleton{0%{background-position:150%}to{background-position:-50%}}@keyframes progress{50%{background-position-x:-115%}}@keyframes toast{0%{opacity:0;scale:.9}to{opacity:1;scale:1}}@keyframes dropdown{0%{opacity:0}}@keyframes rating{0%,40%{filter:brightness(1.05)contrast(1.05);scale:1.1}}@property --tw-border-spacing-x{syntax:"<length>";inherits:false;initial-value:0}@property --tw-border-spacing-y{syntax:"<length>";inherits:false;initial-value:0}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}
frontend/dist/assets/{index-D2ksG3qQ.js → index-GljWyhYi.js} RENAMED
The diff for this file is too large to render. See raw diff
 
frontend/dist/index.html CHANGED
@@ -5,8 +5,8 @@
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <title>🥇 Omni Seal Bench Watermarking Leaderboard</title>
8
- <script type="module" crossorigin src="/assets/index-D2ksG3qQ.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-BWZpYvtq.css">
10
  </head>
11
  <body>
12
  <div id="root"></div>
 
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <title>🥇 Omni Seal Bench Watermarking Leaderboard</title>
8
+ <script type="module" crossorigin src="/assets/index-GljWyhYi.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-BbusHoyK.css">
10
  </head>
11
  <body>
12
  <div id="root"></div>
frontend/package-lock.json CHANGED
@@ -8,6 +8,7 @@
8
  "name": "frontend",
9
  "version": "0.0.0",
10
  "dependencies": {
 
11
  "@tailwindcss/vite": "^4.0.0",
12
  "@types/wavesurfer.js": "^6.0.12",
13
  "react": "^18.3.1",
@@ -834,6 +835,15 @@
834
  "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
835
  }
836
  },
 
 
 
 
 
 
 
 
 
837
  "node_modules/@humanwhocodes/config-array": {
838
  "version": "0.13.0",
839
  "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
 
8
  "name": "frontend",
9
  "version": "0.0.0",
10
  "dependencies": {
11
+ "@heroicons/react": "^2.2.0",
12
  "@tailwindcss/vite": "^4.0.0",
13
  "@types/wavesurfer.js": "^6.0.12",
14
  "react": "^18.3.1",
 
835
  "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
836
  }
837
  },
838
+ "node_modules/@heroicons/react": {
839
+ "version": "2.2.0",
840
+ "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz",
841
+ "integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==",
842
+ "license": "MIT",
843
+ "peerDependencies": {
844
+ "react": ">= 16 || ^19.0.0-rc"
845
+ }
846
+ },
847
  "node_modules/@humanwhocodes/config-array": {
848
  "version": "0.13.0",
849
  "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
frontend/package.json CHANGED
@@ -10,6 +10,7 @@
10
  "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md,html}\""
11
  },
12
  "dependencies": {
 
13
  "@tailwindcss/vite": "^4.0.0",
14
  "@types/wavesurfer.js": "^6.0.12",
15
  "react": "^18.3.1",
@@ -32,4 +33,4 @@
32
  "typescript": "^5.4.5",
33
  "vite": "^5.2.10"
34
  }
35
- }
 
10
  "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md,html}\""
11
  },
12
  "dependencies": {
13
+ "@heroicons/react": "^2.2.0",
14
  "@tailwindcss/vite": "^4.0.0",
15
  "@types/wavesurfer.js": "^6.0.12",
16
  "react": "^18.3.1",
 
33
  "typescript": "^5.4.5",
34
  "vite": "^5.2.10"
35
  }
36
+ }
frontend/src/App.tsx CHANGED
@@ -1,17 +1,39 @@
1
  import { useState, useEffect } from 'react'
2
- import Examples from './components/Examples'
3
  import LeaderboardPage from './components/LeaderboardPage'
 
 
 
 
 
 
 
 
 
 
4
 
5
  function App() {
6
- const [activeTab, setActiveTab] = useState<
7
- 'leaderboard' | 'imageExamples' | 'audioExamples' | 'videoExamples'
8
- >('leaderboard')
9
  const [theme, setTheme] = useState<'dark' | 'light'>('dark')
10
 
11
  useEffect(() => {
12
  document.documentElement.setAttribute('data-theme', theme)
13
  }, [theme])
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  return (
16
  <div className="min-h-screen w-11/12 mx-auto">
17
  <div className="bg-base-100 my-4">
@@ -30,55 +52,20 @@ function App() {
30
  </div>
31
  </div>
32
 
33
- <div className="tabs tabs-border">
34
- <input
35
- type="radio"
36
- name="my_tabs_6"
37
- className="tab"
38
- aria-label="Leaderboard Table"
39
- checked={activeTab === 'leaderboard'}
40
- onChange={() => setActiveTab('leaderboard')}
41
- />
42
- <div className="tab-content bg-base-100 ">
43
- <LeaderboardPage />
44
- </div>
45
-
46
- <input
47
- type="radio"
48
- name="my_tabs_6"
49
- className="tab"
50
- aria-label="Image Examples"
51
- checked={activeTab === 'imageExamples'}
52
- onChange={() => setActiveTab('imageExamples')}
53
- />
54
- <div className="tab-content bg-base-100 ">
55
- {activeTab === 'imageExamples' ? <Examples fileType="image" /> : null}
56
- </div>
57
-
58
- <input
59
- type="radio"
60
- name="my_tabs_6"
61
- className="tab"
62
- aria-label="Audio Examples"
63
- checked={activeTab === 'audioExamples'}
64
- onChange={() => setActiveTab('audioExamples')}
65
- />
66
- <div className="tab-content bg-base-100 ">
67
- {activeTab === 'audioExamples' ? <Examples fileType="audio" /> : null}
68
- </div>
69
-
70
- <input
71
- type="radio"
72
- name="my_tabs_6"
73
- className="tab"
74
- aria-label="Video Examples"
75
- checked={activeTab === 'videoExamples'}
76
- onChange={() => setActiveTab('videoExamples')}
77
- />
78
- <div className="tab-content bg-base-100 ">
79
- {activeTab === 'videoExamples' ? <Examples fileType="video" /> : null}
80
- </div>
81
  </div>
 
82
  </div>
83
  )
84
  }
 
1
  import { useState, useEffect } from 'react'
 
2
  import LeaderboardPage from './components/LeaderboardPage'
3
+ import Examples from './components/Examples'
4
+
5
+ const TABS = [
6
+ { label: 'Audio', type: 'audio-leaderboard' },
7
+ { label: 'Image', type: 'image-leaderboard' },
8
+ { label: 'Video', type: 'video-leaderboard' },
9
+ { label: 'Image Examples', type: 'image-examples' },
10
+ { label: 'Audio Examples', type: 'audio-examples' },
11
+ { label: 'Video Examples', type: 'video-examples' },
12
+ ]
13
 
14
  function App() {
15
+ const [activeTab, setActiveTab] = useState<string>('audio-leaderboard')
 
 
16
  const [theme, setTheme] = useState<'dark' | 'light'>('dark')
17
 
18
  useEffect(() => {
19
  document.documentElement.setAttribute('data-theme', theme)
20
  }, [theme])
21
 
22
+ let content = null
23
+ if (activeTab === 'audio-leaderboard') {
24
+ content = <LeaderboardPage datasetType="audio" />
25
+ } else if (activeTab === 'image-leaderboard') {
26
+ content = <LeaderboardPage datasetType="image" />
27
+ } else if (activeTab === 'video-leaderboard') {
28
+ content = <LeaderboardPage datasetType="video" />
29
+ } else if (activeTab === 'image-examples') {
30
+ content = <Examples fileType="image" />
31
+ } else if (activeTab === 'audio-examples') {
32
+ content = <Examples fileType="audio" />
33
+ } else if (activeTab === 'video-examples') {
34
+ content = <Examples fileType="video" />
35
+ }
36
+
37
  return (
38
  <div className="min-h-screen w-11/12 mx-auto">
39
  <div className="bg-base-100 my-4">
 
52
  </div>
53
  </div>
54
 
55
+ <div className="tabs tabs-border mb-2 ">
56
+ {TABS.map((tab) => (
57
+ <input
58
+ key={tab.type}
59
+ type="radio"
60
+ name="leaderboard_tabs"
61
+ className="tab"
62
+ aria-label={tab.label}
63
+ checked={activeTab === tab.type}
64
+ onChange={() => setActiveTab(tab.type)}
65
+ />
66
+ ))}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  </div>
68
+ <div className="w-full ">{content}</div>
69
  </div>
70
  )
71
  }
frontend/src/components/IndependentMetricsTable.tsx CHANGED
@@ -1,69 +0,0 @@
1
- import React from 'react'
2
-
3
- interface Row {
4
- metric: string
5
- [key: string]: string | number
6
- }
7
-
8
- interface IndependentMetricsTableProps {
9
- independentMetrics: string[]
10
- tableHeader: string[]
11
- selectedModels: Set<string>
12
- tableRows: Row[]
13
- }
14
-
15
- const IndependentMetricsTable: React.FC<IndependentMetricsTableProps> = ({
16
- independentMetrics,
17
- tableHeader,
18
- selectedModels,
19
- tableRows,
20
- }) => {
21
- if (independentMetrics.length === 0) return null
22
- return (
23
- <div className="overflow-x-auto max-h-[80vh] overflow-y-auto">
24
- <table className="table w-full min-w-max border-gray-700 border">
25
- <thead>
26
- <tr>
27
- <th className="sticky left-0 top-0 bg-base-100 z-20 border-gray-700 border">Metric</th>
28
- {tableHeader
29
- .filter((model) => selectedModels.has(model))
30
- .map((model) => (
31
- <th
32
- key={`independent-${model}`}
33
- className="sticky top-0 bg-base-100 z-10 text-center text-xs border-gray-700 border"
34
- >
35
- {model}
36
- </th>
37
- ))}
38
- </tr>
39
- </thead>
40
- <tbody>
41
- {independentMetrics.sort().map((metric) => {
42
- const row = tableRows.find((r) => r.metric === metric)
43
- if (!row) return null
44
- return (
45
- <tr key={`independent-${metric}`} className="hover:bg-base-100">
46
- <td className="sticky left-0 bg-base-100 z-10 border-gray-700 border">{metric}</td>
47
- {tableHeader
48
- .filter((model) => selectedModels.has(model))
49
- .map((col) => {
50
- const cell = row[col]
51
- return (
52
- <td
53
- key={`independent-${metric}-${col}`}
54
- className="text-center border-gray-700 border"
55
- >
56
- {!isNaN(Number(cell)) ? Number(Number(cell).toFixed(3)) : cell}
57
- </td>
58
- )
59
- })}
60
- </tr>
61
- )
62
- })}
63
- </tbody>
64
- </table>
65
- </div>
66
- )
67
- }
68
-
69
- export default IndependentMetricsTable
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/components/LeaderboardPage.tsx CHANGED
@@ -6,14 +6,24 @@ import ModelFilter from './ModelFilter'
6
  import API from '../API'
7
  import LoadingSpinner from './LoadingSpinner'
8
 
9
- const LeaderboardPage: React.FC = () => {
10
- const datasetNames = [
11
- 'voxpopuli_1k/audio',
12
- 'ravdess_1k/audio',
13
- 'val2014_1k/image',
14
- 'sav_val_full/video',
15
- ]
 
 
 
 
 
16
  const [selectedDatasetName, setSelectedDatasetName] = useState(datasetNames[0])
 
 
 
 
 
17
  const [models, setModels] = useState<string[]>([])
18
  const [selectedModels, setSelectedModels] = useState<Set<string>>(new Set())
19
  const [loading, setLoading] = useState(true)
 
6
  import API from '../API'
7
  import LoadingSpinner from './LoadingSpinner'
8
 
9
+ interface LeaderboardPageProps {
10
+ datasetType: 'audio' | 'image' | 'video'
11
+ }
12
+
13
+ const DATASET_NAMES: { [type: string]: string[] } = {
14
+ audio: ['voxpopuli_1k/audio', 'ravdess_1k/audio'],
15
+ image: ['val2014_1k/image'],
16
+ video: ['sav_val_full/video'],
17
+ }
18
+
19
+ const LeaderboardPage: React.FC<LeaderboardPageProps> = ({ datasetType }) => {
20
+ const datasetNames = DATASET_NAMES[datasetType]
21
  const [selectedDatasetName, setSelectedDatasetName] = useState(datasetNames[0])
22
+
23
+ // Update selectedDatasetName when datasetType changes
24
+ useEffect(() => {
25
+ setSelectedDatasetName(DATASET_NAMES[datasetType][0])
26
+ }, [datasetType])
27
  const [models, setModels] = useState<string[]>([])
28
  const [selectedModels, setSelectedModels] = useState<Set<string>>(new Set())
29
  const [loading, setLoading] = useState(true)
frontend/src/components/LeaderboardTable.tsx CHANGED
@@ -1,7 +1,8 @@
1
  import React, { useEffect, useState } from 'react'
 
2
  import LeaderboardFilter from './LeaderboardFilter'
3
  import LoadingSpinner from './LoadingSpinner'
4
- import IndependentMetricsTable from './IndependentMetricsTable'
5
 
6
  interface LeaderboardTableProps {
7
  benchmarkData: any
@@ -213,7 +214,6 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, sele
213
 
214
  const getSortConfig = () => {
215
  // Find the first sorted column (overallMetric, model)
216
- console.log({ sortState })
217
  for (const overallMetric of overallMetrics) {
218
  if (!selectedOverallMetrics.has(overallMetric)) continue
219
  const models = tableHeader.filter((model) => selectedModels.has(model))
@@ -253,7 +253,6 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, sele
253
  const sortModelColumns = (models: string[], overallMetric: string): string[] => {
254
  // Column sort takes precedence; if no column sort, return models in default order
255
  const columnSortConfig = getColumnSortConfig()
256
- console.log({ columnSortConfig, overallMetric })
257
  if (columnSortConfig && columnSortConfig.overallMetric === overallMetric) {
258
  // Sort by average value for each model in this overallMetric
259
  return [...models].sort((a, b) => {
@@ -311,7 +310,7 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, sele
311
  }
312
 
313
  // Identify metrics that don't belong to any overall metric group
314
- const findStandaloneMetrics = (): string[] => {
315
  // Get all metrics from the table rows
316
  const allMetrics = tableRows.map((row) => row.metric as string)
317
 
@@ -469,8 +468,6 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, sele
469
  )
470
  })
471
 
472
- console.log({ modelOrderByOverallMetric })
473
-
474
  return (
475
  <div className="rounded">
476
  {error && <div className="text-red-500">{error}</div>}
@@ -482,11 +479,11 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, sele
482
  selectedOverallMetrics={selectedOverallMetrics}
483
  setSelectedOverallMetrics={setSelectedOverallMetrics}
484
  />
485
- <LeaderboardFilter
486
  groups={groupRows}
487
  selectedMetrics={selectedMetrics}
488
  setSelectedMetrics={setSelectedMetrics}
489
- />
490
  </div>
491
 
492
  {selectedModels.size === 0 || selectedMetrics.size === 0 ? (
@@ -495,28 +492,136 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, sele
495
  </div>
496
  ) : (
497
  <>
498
- {/* Standalone metrics table */}
499
- <IndependentMetricsTable
500
- independentMetrics={findStandaloneMetrics()}
501
  tableHeader={tableHeader}
502
  selectedModels={selectedModels}
503
  tableRows={tableRows}
504
  />
505
 
506
  {/* Main metrics table */}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
507
  <div className="overflow-x-auto max-h-[80vh] overflow-y-auto">
508
- <table className="table w-full min-w-max border-gray-700 border">
509
  <thead>
510
  <tr>
511
- <th className="sticky left-0 top-0 bg-base-100 z-20 border-gray-700 border">
512
- Attack Category Metrics
513
  </th>
514
  {overallMetrics
515
  .filter((metric) => selectedOverallMetrics.has(metric))
516
  .map((metric) => (
517
  <th
518
  key={`header-metric-${metric}`}
519
- className="bg-base-100 z-10 text-center text-xs border-gray-700 border"
520
  colSpan={modelOrderByOverallMetric[metric].length}
521
  >
522
  {metric}
@@ -524,7 +629,7 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, sele
524
  ))}
525
  </tr>
526
  <tr>
527
- <th className="sticky left-0 bg-base-100 z-10 border-gray-700 border"></th>
528
  {overallMetrics
529
  .filter((metric) => selectedOverallMetrics.has(metric))
530
  .map((metric) => (
@@ -535,7 +640,7 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, sele
535
  return (
536
  <th
537
  key={`${metric}-${model}`}
538
- className="sticky top-12 bg-base-100 z-10 text-center text-xs border-gray-700 border border-bottom-solid border-b-gray-700 border-b-3 cursor-pointer select-none"
539
  onClick={() => handleSort(metric, model)}
540
  >
541
  {model}
@@ -599,7 +704,7 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, sele
599
  className="bg-base-200 cursor-pointer hover:bg-base-300"
600
  onClick={() => toggleGroup(group)}
601
  >
602
- <td className="sticky left-0 bg-base-200 z-10 font-medium border-gray-700 border cursor-pointer select-none flex items-center gap-1">
603
  <span>{openGroupRows[group] ? '▼ ' : '▶ '}</span>
604
  <span className="flex-1">{group}</span>
605
  {/* Sort icon: only this triggers sort, and shows default if unsorted */}
@@ -671,13 +776,13 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, sele
671
  <React.Fragment key={`${group}-${subGroup}`}>
672
  {/* Subgroup row with average stats for the subgroup */}
673
  <tr
674
- className="bg-base-100 cursor-pointer hover:bg-base-200"
675
- onClick={() => toggleSubGroup(group, subGroup)}
676
  >
677
- <td className="sticky left-0 bg-base-100 z-10 pl-6 font-medium border-gray-700 border cursor-pointer select-none flex items-center gap-1">
678
- <span>
679
  {openSubGroupRows[group]?.[subGroup] ? '▼ ' : '▶ '}
680
- </span>
681
  <span className="flex-1">{subGroup}</span>
682
  <span
683
  className="ml-1 cursor-pointer"
@@ -739,223 +844,6 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, sele
739
  </tr>
740
 
741
  {/* Individual metric rows */}
742
- {openSubGroupRows[group]?.[subGroup] &&
743
- (() => {
744
- // Sorting logic for individual metric rows
745
- const sortConfig = getSortConfig()
746
- let sortedMetrics = [...visibleSubgroupMetrics]
747
- console.log(
748
- 'Sorting metrics for subgroup:',
749
- group,
750
- subGroup,
751
- 'with config:',
752
- sortConfig
753
- )
754
- if (sortConfig) {
755
- // Only sort metrics that match the selected overallMetric and model
756
- const allMetricsWithName = findAllMetricsForName(
757
- sortConfig.overallMetric
758
- )
759
- const metricsInSubgroupForThisMetric = sortedMetrics.filter(
760
- (m) => allMetricsWithName.includes(m)
761
- )
762
- const metricsNotInSubgroupForThisMetric =
763
- sortedMetrics.filter(
764
- (m) => !allMetricsWithName.includes(m)
765
- )
766
- // Only apply subcolumn sort to matching metrics, leave others in original order
767
- sortedMetrics = [
768
- ...sortRowsBySubcolumn(
769
- metricsInSubgroupForThisMetric,
770
- sortConfig.overallMetric,
771
- sortConfig.model,
772
- sortConfig.direction
773
- ),
774
- ...metricsNotInSubgroupForThisMetric,
775
- ]
776
- } else {
777
- // Fallback sort logic (category, overall, strength)
778
- sortedMetrics = sortedMetrics.sort((a, b) => {
779
- // For metrics with format {category}_{strength}_{overall_metric_name},
780
- // First sort by category, then by overall_metric_name, then by strength
781
-
782
- // First extract the overall metric group
783
- const getOverallMetricGroup = (metric: string) => {
784
- for (const overall of overallMetrics) {
785
- if (
786
- metric.endsWith(`_${overall}`) ||
787
- metric === overall
788
- ) {
789
- return overall
790
- }
791
- }
792
- return ''
793
- }
794
-
795
- const overallA = getOverallMetricGroup(a)
796
- const overallB = getOverallMetricGroup(b)
797
-
798
- // Extract the strength (last part before the overall metric)
799
- const stripOverall = (
800
- metric: string,
801
- overall: string
802
- ) => {
803
- if (metric.endsWith(`_${overall}`)) {
804
- // Remove the overall metric group and any preceding underscore
805
- const stripped = metric.slice(
806
- 0,
807
- metric.length - overall.length - 1
808
- )
809
- const parts = stripped.split('_')
810
- return parts.length > 0 ? parts[parts.length - 1] : ''
811
- }
812
- return metric
813
- }
814
-
815
- // Extract the category (what remains after removing strength and overall_metric_name)
816
- const getCategory = (metric: string, overall: string) => {
817
- if (metric.endsWith(`_${overall}`)) {
818
- const stripped = metric.slice(
819
- 0,
820
- metric.length - overall.length - 1
821
- )
822
- const parts = stripped.split('_')
823
- // Remove the last part (strength) and join the rest (category)
824
- return parts.length > 1
825
- ? parts.slice(0, parts.length - 1).join('_')
826
- : ''
827
- }
828
- return metric
829
- }
830
-
831
- const categoryA = getCategory(a, overallA)
832
- const categoryB = getCategory(b, overallB)
833
-
834
- // First sort by category
835
- if (categoryA !== categoryB) {
836
- return categoryA.localeCompare(categoryB)
837
- }
838
-
839
- // Then sort by overall metric name
840
- if (overallA !== overallB) {
841
- return overallA.localeCompare(overallB)
842
- }
843
-
844
- // Finally sort by strength
845
- const subA = stripOverall(a, overallA)
846
- const subB = stripOverall(b, overallB)
847
-
848
- // Try to parse subA and subB as numbers, handling k/m/b suffixes
849
- const parseNumber = (str: string) => {
850
- const match = str.match(/^\d+(?:\.\d+)?([kKmMbB]?)$/)
851
- if (!match) return NaN
852
- let [_, suffix] = match
853
- let value = parseFloat(str)
854
- switch (suffix?.toLowerCase()) {
855
- case 'k':
856
- value *= 1e3
857
- break
858
- case 'm':
859
- value *= 1e6
860
- break
861
- case 'b':
862
- value *= 1e9
863
- break
864
- }
865
- return value
866
- }
867
-
868
- const numA = parseNumber(subA)
869
- const numB = parseNumber(subB)
870
-
871
- if (!isNaN(numA) && !isNaN(numB)) {
872
- return numA - numB
873
- }
874
- // Fallback to string comparison if not both numbers
875
- return subA.localeCompare(subB)
876
- })
877
- }
878
- return sortedMetrics.map((metric) => {
879
- const row = tableRows.find((r) => r.metric === metric)
880
- if (!row) return null
881
-
882
- // Extract the metric name (after the underscore)
883
- const metricName = metric.includes('_')
884
- ? metric.split('_').slice(1).join('_')
885
- : metric
886
-
887
- return (
888
- <tr key={metric} className="hover:bg-base-100">
889
- <td className="sticky left-0 bg-base-100 z-10 pl-10 border-gray-700 border cursor-pointer select-none flex items-center gap-1">
890
- <span className="flex-1">{metric}</span>
891
- <span
892
- className="ml-1 cursor-pointer"
893
- onClick={(e) => {
894
- e.stopPropagation()
895
- handleColumnSort(group, subGroup, metric)
896
- }}
897
- title={
898
- getRowColumnSort(group, subGroup, metric)
899
- ? getRowColumnSort(group, subGroup, metric)
900
- ?.direction === 'asc'
901
- ? 'Sort descending'
902
- : 'Clear sort'
903
- : 'Sort by this row'
904
- }
905
- >
906
- {getRowColumnSort(group, subGroup, metric)
907
- ? getRowColumnSort(group, subGroup, metric)
908
- ?.direction === 'asc'
909
- ? '▲'
910
- : '▼'
911
- : '⇅'}
912
- </span>
913
- </td>
914
- {overallMetrics
915
- .filter((oMetric) =>
916
- selectedOverallMetrics.has(oMetric)
917
- )
918
- .map((oMetric) => {
919
- const isMatchingMetric =
920
- findAllMetricsForName(oMetric).includes(metric)
921
- if (!isMatchingMetric) {
922
- return (
923
- <React.Fragment key={`${metric}-${oMetric}`}>
924
- {modelOrderByOverallMetric[oMetric].map(
925
- (col) => (
926
- <td
927
- key={`${metric}-${oMetric}-${col}`}
928
- className="text-center border-gray-700 border"
929
- ></td>
930
- )
931
- )}
932
- </React.Fragment>
933
- )
934
- }
935
- return (
936
- <React.Fragment key={`${metric}-${oMetric}`}>
937
- {modelOrderByOverallMetric[oMetric].map(
938
- (col) => {
939
- const cell = row[col]
940
- return (
941
- <td
942
- key={`${metric}-${oMetric}-${col}`}
943
- className="text-center border-gray-700 border"
944
- >
945
- {!isNaN(Number(cell))
946
- ? Number(Number(cell).toFixed(3))
947
- : cell}
948
- </td>
949
- )
950
- }
951
- )}
952
- </React.Fragment>
953
- )
954
- })}
955
- </tr>
956
- )
957
- })
958
- })()}
959
  </React.Fragment>
960
  )
961
  })}
 
1
  import React, { useEffect, useState } from 'react'
2
+ import { ArrowDownTrayIcon } from '@heroicons/react/24/solid'
3
  import LeaderboardFilter from './LeaderboardFilter'
4
  import LoadingSpinner from './LoadingSpinner'
5
+ import QualityMetricsTable from './QualityMetricsTable'
6
 
7
  interface LeaderboardTableProps {
8
  benchmarkData: any
 
214
 
215
  const getSortConfig = () => {
216
  // Find the first sorted column (overallMetric, model)
 
217
  for (const overallMetric of overallMetrics) {
218
  if (!selectedOverallMetrics.has(overallMetric)) continue
219
  const models = tableHeader.filter((model) => selectedModels.has(model))
 
253
  const sortModelColumns = (models: string[], overallMetric: string): string[] => {
254
  // Column sort takes precedence; if no column sort, return models in default order
255
  const columnSortConfig = getColumnSortConfig()
 
256
  if (columnSortConfig && columnSortConfig.overallMetric === overallMetric) {
257
  // Sort by average value for each model in this overallMetric
258
  return [...models].sort((a, b) => {
 
310
  }
311
 
312
  // Identify metrics that don't belong to any overall metric group
313
+ const findQualityMetrics = (): string[] => {
314
  // Get all metrics from the table rows
315
  const allMetrics = tableRows.map((row) => row.metric as string)
316
 
 
468
  )
469
  })
470
 
 
 
471
  return (
472
  <div className="rounded">
473
  {error && <div className="text-red-500">{error}</div>}
 
479
  selectedOverallMetrics={selectedOverallMetrics}
480
  setSelectedOverallMetrics={setSelectedOverallMetrics}
481
  />
482
+ {/* <LeaderboardFilter
483
  groups={groupRows}
484
  selectedMetrics={selectedMetrics}
485
  setSelectedMetrics={setSelectedMetrics}
486
+ /> */}
487
  </div>
488
 
489
  {selectedModels.size === 0 || selectedMetrics.size === 0 ? (
 
492
  </div>
493
  ) : (
494
  <>
495
+ {/* Quality metrics table */}
496
+ <QualityMetricsTable
497
+ qualityMetrics={findQualityMetrics()}
498
  tableHeader={tableHeader}
499
  selectedModels={selectedModels}
500
  tableRows={tableRows}
501
  />
502
 
503
  {/* Main metrics table */}
504
+ <div className="relative flex justify-end mb-2">
505
+ <button
506
+ className="absolute top-0 right-0 btn btn-ghost btn-circle"
507
+ title="Export CSV"
508
+ onClick={() => {
509
+ // Export the main metrics table as displayed
510
+ // Build header row
511
+ const visibleMetrics = overallMetrics.filter((metric) =>
512
+ selectedOverallMetrics.has(metric)
513
+ )
514
+ const header = [
515
+ 'Attack Categories',
516
+ ...visibleMetrics.flatMap((metric) => modelOrderByOverallMetric[metric]),
517
+ ]
518
+ // Build data rows
519
+ const rows: (string | number)[][] = []
520
+ groupEntries.forEach(([group, subGroups]) => {
521
+ // Group row
522
+ const allGroupMetrics = Object.values(subGroups).flat()
523
+ const visibleGroupMetrics = filterMetricsByGroupAndSubgroup(
524
+ allGroupMetrics,
525
+ group
526
+ )
527
+ if (visibleGroupMetrics.length === 0) return
528
+ // Group row label
529
+ const groupRow: (string | number)[] = [group]
530
+ visibleMetrics.forEach((metric) => {
531
+ modelOrderByOverallMetric[metric].forEach((col) => {
532
+ const allMetricsWithName = findAllMetricsForName(metric)
533
+ const metricsInGroupForThisMetric = visibleGroupMetrics.filter((m) =>
534
+ allMetricsWithName.includes(m)
535
+ )
536
+ const stats = calculateStats(metricsInGroupForThisMetric, col)
537
+ groupRow.push(
538
+ !isNaN(stats.avg)
539
+ ? `${stats.avg.toFixed(3)} ± ${stats.stdDev.toFixed(3)}`
540
+ : 'N/A'
541
+ )
542
+ })
543
+ })
544
+ rows.push(groupRow)
545
+ // Subgroup rows
546
+ let subGroupEntries = Object.entries(subGroups)
547
+ subGroupEntries.forEach(([subGroup, metrics]) => {
548
+ const visibleSubgroupMetrics = filterMetricsByGroupAndSubgroup(
549
+ metrics,
550
+ group,
551
+ subGroup
552
+ )
553
+ if (visibleSubgroupMetrics.length === 0) return
554
+ const subGroupRow: (string | number)[] = [' ' + subGroup] // Indent subgroup
555
+ visibleMetrics.forEach((metric) => {
556
+ modelOrderByOverallMetric[metric].forEach((col) => {
557
+ const allMetricsWithName = findAllMetricsForName(metric)
558
+ const metricsInSubgroupForThisMetric = visibleSubgroupMetrics.filter(
559
+ (m) => allMetricsWithName.includes(m)
560
+ )
561
+ const stats = calculateStats(metricsInSubgroupForThisMetric, col)
562
+ subGroupRow.push(
563
+ !isNaN(stats.avg)
564
+ ? `${stats.avg.toFixed(3)} ± ${stats.stdDev.toFixed(3)}`
565
+ : 'N/A'
566
+ )
567
+ })
568
+ })
569
+ rows.push(subGroupRow)
570
+ // Individual metric rows
571
+ visibleSubgroupMetrics.forEach((metric) => {
572
+ const row = tableRows.find((r) => r.metric === metric)
573
+ if (!row) return
574
+ const metricRow: (string | number)[] = [' ' + metric] // Indent metric
575
+ visibleMetrics.forEach((oMetric) => {
576
+ if (!findAllMetricsForName(oMetric).includes(metric)) {
577
+ modelOrderByOverallMetric[oMetric].forEach(() => metricRow.push(''))
578
+ } else {
579
+ modelOrderByOverallMetric[oMetric].forEach((col) => {
580
+ const cell = row[col]
581
+ metricRow.push(
582
+ !isNaN(Number(cell)) ? Number(Number(cell).toFixed(3)) : cell
583
+ )
584
+ })
585
+ }
586
+ })
587
+ rows.push(metricRow)
588
+ })
589
+ })
590
+ })
591
+ // CSV encode
592
+ const csv = [header, ...rows]
593
+ .map((row) =>
594
+ row.map((cell) => `"${String(cell).replace(/"/g, '""')}"`).join(',')
595
+ )
596
+ .join('\n')
597
+ // Download
598
+ const blob = new Blob([csv], { type: 'text/csv' })
599
+ const url = URL.createObjectURL(blob)
600
+ const a = document.createElement('a')
601
+ a.href = url
602
+ a.download = 'leaderboard_metrics.csv'
603
+ document.body.appendChild(a)
604
+ a.click()
605
+ document.body.removeChild(a)
606
+ URL.revokeObjectURL(url)
607
+ }}
608
+ >
609
+ <ArrowDownTrayIcon className="h-6 w-6" />
610
+ </button>
611
+ </div>
612
  <div className="overflow-x-auto max-h-[80vh] overflow-y-auto">
613
+ <table className="table w-full min-w-max border-separate border-spacing-0 border-gray-700 border">
614
  <thead>
615
  <tr>
616
+ <th className="sticky left-0 top-0 bg-base-100 z-20 border border-gray-700">
617
+ Attack Categories
618
  </th>
619
  {overallMetrics
620
  .filter((metric) => selectedOverallMetrics.has(metric))
621
  .map((metric) => (
622
  <th
623
  key={`header-metric-${metric}`}
624
+ className="sticky top-0 bg-base-100 z-10 text-center text-xs border border-gray-700 select-none"
625
  colSpan={modelOrderByOverallMetric[metric].length}
626
  >
627
  {metric}
 
629
  ))}
630
  </tr>
631
  <tr>
632
+ <th className="sticky left-0 top-12 bg-base-100 z-30 border border-gray-700"></th>
633
  {overallMetrics
634
  .filter((metric) => selectedOverallMetrics.has(metric))
635
  .map((metric) => (
 
640
  return (
641
  <th
642
  key={`${metric}-${model}`}
643
+ className="sticky top-12 bg-base-100 z-10 text-center text-xs border border-gray-700 cursor-pointer select-none"
644
  onClick={() => handleSort(metric, model)}
645
  >
646
  {model}
 
704
  className="bg-base-200 cursor-pointer hover:bg-base-300"
705
  onClick={() => toggleGroup(group)}
706
  >
707
+ <td className="sticky left-0 bg-base-200 z-10 font-medium cursor-pointer select-none flex items-center">
708
  <span>{openGroupRows[group] ? '▼ ' : '▶ '}</span>
709
  <span className="flex-1">{group}</span>
710
  {/* Sort icon: only this triggers sort, and shows default if unsorted */}
 
776
  <React.Fragment key={`${group}-${subGroup}`}>
777
  {/* Subgroup row with average stats for the subgroup */}
778
  <tr
779
+ className="bg-base-100 hover:bg-base-200"
780
+ // onClick={() => toggleSubGroup(group, subGroup)}
781
  >
782
+ <td className="sticky left-0 bg-base-100 z-10 pl-6 font-medium flex items-center gap-1">
783
+ {/* <span>
784
  {openSubGroupRows[group]?.[subGroup] ? '▼ ' : '▶ '}
785
+ </span> */}
786
  <span className="flex-1">{subGroup}</span>
787
  <span
788
  className="ml-1 cursor-pointer"
 
844
  </tr>
845
 
846
  {/* Individual metric rows */}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
847
  </React.Fragment>
848
  )
849
  })}
frontend/src/components/LeaderboardTabs.tsx ADDED
File without changes
frontend/src/components/QualityMetricsTable.tsx ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from 'react'
2
+ import { ArrowDownTrayIcon } from '@heroicons/react/24/outline'
3
+
4
+ interface Row {
5
+ metric: string
6
+ [key: string]: string | number
7
+ }
8
+
9
+ interface QualityMetricsTableProps {
10
+ qualityMetrics: string[]
11
+ tableHeader: string[]
12
+ selectedModels: Set<string>
13
+ tableRows: Row[]
14
+ }
15
+
16
+ const QualityMetricsTable: React.FC<QualityMetricsTableProps> = ({
17
+ qualityMetrics,
18
+ tableHeader,
19
+ selectedModels,
20
+ tableRows,
21
+ }) => {
22
+ // Sorting state
23
+ const [rowSort, setRowSort] = useState<{ metric: string; direction: 'asc' | 'desc' } | null>(null)
24
+ const [columnSort, setColumnSort] = useState<{ model: string; direction: 'asc' | 'desc' } | null>(
25
+ null
26
+ )
27
+
28
+ // Handle row sort (sort columns by this metric)
29
+ const handleRowSort = (metric: string) => {
30
+ setColumnSort(null) // Only one sort active at a time
31
+ setRowSort((prev) => {
32
+ if (!prev || prev.metric !== metric) return { metric, direction: 'asc' }
33
+ if (prev.direction === 'asc') return { metric, direction: 'desc' }
34
+ return null // Remove sort
35
+ })
36
+ }
37
+
38
+ // Handle column sort (sort rows by this model)
39
+ const handleColumnSort = (model: string) => {
40
+ setRowSort(null) // Only one sort active at a time
41
+ setColumnSort((prev) => {
42
+ if (!prev || prev.model !== model) return { model, direction: 'asc' }
43
+ if (prev.direction === 'asc') return { model, direction: 'desc' }
44
+ return null // Remove sort
45
+ })
46
+ }
47
+
48
+ // Sort models (columns)
49
+ let sortedModels = tableHeader.filter((model) => selectedModels.has(model))
50
+ if (rowSort) {
51
+ // Sort columns by the value in the selected metric row
52
+ sortedModels = [...sortedModels].sort((a, b) => {
53
+ const row = tableRows.find((r) => r.metric === rowSort.metric)
54
+ if (!row) return 0
55
+ const valA = Number(row[a])
56
+ const valB = Number(row[b])
57
+ if (isNaN(valA) && isNaN(valB)) return 0
58
+ if (isNaN(valA)) return 1
59
+ if (isNaN(valB)) return -1
60
+ return rowSort.direction === 'asc' ? valA - valB : valB - valA
61
+ })
62
+ }
63
+
64
+ // Sort metrics (rows)
65
+ let sortedMetrics = [...qualityMetrics]
66
+ if (columnSort) {
67
+ // Sort rows by the value in the selected model column
68
+ sortedMetrics = [...sortedMetrics].sort((a, b) => {
69
+ const rowA = tableRows.find((r) => r.metric === a)
70
+ const rowB = tableRows.find((r) => r.metric === b)
71
+ if (!rowA || !rowB) return 0
72
+ const valA = Number(rowA[columnSort.model])
73
+ const valB = Number(rowB[columnSort.model])
74
+ if (isNaN(valA) && isNaN(valB)) return 0
75
+ if (isNaN(valA)) return 1
76
+ if (isNaN(valB)) return -1
77
+ return columnSort.direction === 'asc' ? valA - valB : valB - valA
78
+ })
79
+ }
80
+
81
+ // CSV export logic
82
+ function exportToCSV() {
83
+ // Build header row
84
+ const header = ['Metric', ...sortedModels]
85
+ // Build data rows
86
+ const rows = sortedMetrics
87
+ .map((metric) => {
88
+ const row = tableRows.find((r) => r.metric === metric)
89
+ if (!row) return null
90
+ return [
91
+ metric,
92
+ ...sortedModels.map((col) => {
93
+ const cell = row[col]
94
+ // Format as displayed
95
+ return !isNaN(Number(cell)) ? Number(Number(cell).toFixed(3)) : cell
96
+ }),
97
+ ]
98
+ })
99
+ .filter((row): row is (string | number)[] => !!row)
100
+ // Combine
101
+ const csv = [header, ...rows]
102
+ .map((row) => row.map((cell) => `"${String(cell).replace(/"/g, '""')}"`).join(','))
103
+ .join('\n')
104
+ // Download
105
+ const blob = new Blob([csv], { type: 'text/csv' })
106
+ const url = URL.createObjectURL(blob)
107
+ const a = document.createElement('a')
108
+ a.href = url
109
+ a.download = 'quality_metrics.csv'
110
+ document.body.appendChild(a)
111
+ a.click()
112
+ document.body.removeChild(a)
113
+ URL.revokeObjectURL(url)
114
+ }
115
+
116
+ if (qualityMetrics.length === 0) return null
117
+ return (
118
+ <div className="overflow-x-auto max-h-[80vh] overflow-y-auto">
119
+ <div className="flex justify-end mb-2">
120
+ <button className="btn btn-ghost btn-circle" title="Export CSV" onClick={exportToCSV}>
121
+ <ArrowDownTrayIcon className="h-6 w-6" />
122
+ </button>
123
+ </div>
124
+ <table className="table w-full min-w-max border-gray-700 border">
125
+ <thead>
126
+ <tr>
127
+ <th className="sticky left-0 top-0 bg-base-100 z-20 border-gray-700 border">Metric</th>
128
+ {sortedModels.map((model) => {
129
+ const isSorted = columnSort && columnSort.model === model
130
+ const direction = isSorted ? columnSort.direction : undefined
131
+ return (
132
+ <th
133
+ key={`quality-${model}`}
134
+ className="sticky top-0 bg-base-100 z-10 text-center text-xs border-gray-700 border cursor-pointer select-none"
135
+ onClick={() => handleColumnSort(model)}
136
+ title={
137
+ isSorted
138
+ ? direction === 'asc'
139
+ ? 'Sort descending'
140
+ : 'Clear sort'
141
+ : 'Sort by this column'
142
+ }
143
+ >
144
+ {model}
145
+ <span className="ml-1">{isSorted ? (direction === 'asc' ? '↑' : '↓') : '⇅'}</span>
146
+ </th>
147
+ )
148
+ })}
149
+ </tr>
150
+ </thead>
151
+ <tbody>
152
+ {sortedMetrics.map((metric) => {
153
+ const row = tableRows.find((r) => r.metric === metric)
154
+ if (!row) return null
155
+ const isSorted = rowSort && rowSort.metric === metric
156
+ const direction = isSorted ? rowSort.direction : undefined
157
+ return (
158
+ <tr key={`quality-${metric}`} className="hover:bg-base-100">
159
+ <td
160
+ className="sticky left-0 bg-base-100 z-10 border-gray-700 border cursor-pointer select-none"
161
+ onClick={() => handleRowSort(metric)}
162
+ title={
163
+ isSorted
164
+ ? direction === 'asc'
165
+ ? 'Sort descending'
166
+ : 'Clear sort'
167
+ : 'Sort by this row (sorts columns)'
168
+ }
169
+ >
170
+ {metric}
171
+ <span className="ml-1">{isSorted ? (direction === 'asc' ? '↑' : '↓') : '⇅'}</span>
172
+ </td>
173
+ {sortedModels.map((col) => {
174
+ const cell = row[col]
175
+ return (
176
+ <td
177
+ key={`quality-${metric}-${col}`}
178
+ className="text-center border-gray-700 border"
179
+ >
180
+ {!isNaN(Number(cell)) ? Number(Number(cell).toFixed(3)) : cell}
181
+ </td>
182
+ )
183
+ })}
184
+ </tr>
185
+ )
186
+ })}
187
+ </tbody>
188
+ </table>
189
+ </div>
190
+ )
191
+ }
192
+
193
+ export default QualityMetricsTable
tests/README.md ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Unit Tests for OmniSealBench
2
+
3
+ This directory contains unit tests for the OmniSealBench application.
4
+
5
+ ## Setup
6
+
7
+ Before running the tests, make sure you have installed the required dependencies:
8
+
9
+ ```bash
10
+ # Install pytest and other testing dependencies
11
+ pip install pytest pytest-cov
12
+
13
+ # If you're using the environment.yml file
14
+ conda env update -f backend/environment.yml
15
+ ```
16
+
17
+ ## Running Tests
18
+
19
+ To run all tests:
20
+
21
+ ```bash
22
+ # From the project root directory
23
+ pytest tests/
24
+
25
+ # With coverage report
26
+ pytest tests/ --cov=backend
27
+ ```
28
+
29
+ To run a specific test file:
30
+
31
+ ```bash
32
+ pytest tests/test_app.py
33
+ ```
34
+
35
+ To run a specific test function:
36
+
37
+ ```bash
38
+ pytest tests/test_app.py::test_index_route
39
+ ```
40
+
41
+ ## Test Structure
42
+
43
+ - `test_app.py`: Tests for the Flask application routes and helper functions
44
+ - `conftest.py`: Shared pytest fixtures for all test files
45
+ - `__init__.py`: Makes the tests directory a Python package for better test discovery
46
+
47
+ ## Mocking
48
+
49
+ The tests use `unittest.mock` to mock external dependencies like:
50
+ - File operations (reading CSV files)
51
+ - API calls (requests.get)
52
+ - Database connections
53
+
54
+ This ensures tests are isolated and don't depend on external services.
55
+
56
+ ## Adding New Tests
57
+
58
+ When adding new tests:
59
+
60
+ 1. Create a new test file if testing a new module
61
+ 2. Use descriptive test function names (e.g., `test_data_files_benchmark`)
62
+ 3. Add docstrings to explain what each test is checking
63
+ 4. Use fixtures from `conftest.py` when appropriate
64
+ 5. Mock external dependencies to ensure tests are isolated
tests/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ # This file makes the tests directory a Python package
2
+ # It allows for better test discovery and organization
tests/conftest.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This file contains shared pytest fixtures for all test files.
3
+ Fixtures defined here are automatically available to all test files.
4
+ """
5
+
6
+ import pytest
7
+ import os
8
+ import sys
9
+ from flask import Flask
10
+
11
+ # Add the parent directory to sys.path to allow importing from the backend package
12
+ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
13
+
14
+ # Import the Flask app for testing
15
+ from backend.app import app
16
+
17
+
18
+ @pytest.fixture
19
+ def client():
20
+ """Create a test client for the Flask app."""
21
+ app.config['TESTING'] = True
22
+ with app.test_client() as client:
23
+ yield client
24
+
25
+
26
+ @pytest.fixture
27
+ def app_context():
28
+ """Create an application context for the Flask app."""
29
+ with app.app_context():
30
+ yield
tests/test_app.py ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import pytest
4
+ from unittest.mock import patch, MagicMock, mock_open
5
+ import pandas as pd
6
+ from io import StringIO
7
+ from flask import Flask
8
+
9
+ # Import the Flask app and other necessary modules
10
+ from backend.app import app, get_leaderboard, get_chart
11
+
12
+
13
+ @pytest.fixture
14
+ def client():
15
+ """Create a test client for the Flask app."""
16
+ app.config['TESTING'] = True
17
+ with app.test_client() as client:
18
+ yield client
19
+
20
+
21
+ def test_index_route(client):
22
+ """Test the index route returns the index.html file."""
23
+ with patch('backend.app.send_from_directory') as mock_send:
24
+ mock_send.return_value = "index content"
25
+ response = client.get('/')
26
+ assert response.status_code == 200
27
+ mock_send.assert_called_once_with(app.static_folder, "index.html")
28
+
29
+
30
+ @patch('backend.app.pd.read_csv')
31
+ @patch('backend.app.get_dataset_config')
32
+ @patch('backend.app.get_leaderboard')
33
+ def test_data_files_benchmark(mock_get_leaderboard, mock_get_config, mock_read_csv, client):
34
+ """Test the data_files route with benchmark dataset type."""
35
+ # Mock the DataFrame and config
36
+ mock_df = pd.DataFrame({'model': ['model1', 'model2'], 'score': [0.9, 0.8]})
37
+ mock_read_csv.return_value = mock_df
38
+ mock_config = {'name': 'test_dataset'}
39
+ mock_get_config.return_value = mock_config
40
+ mock_get_leaderboard.return_value = "leaderboard data"
41
+
42
+ # Make the request
43
+ response = client.get('/data/test_dataset?dataset_type=benchmark')
44
+
45
+ # Assertions
46
+ mock_read_csv.assert_called_once()
47
+ mock_get_config.assert_called_once_with('test_dataset')
48
+ mock_get_leaderboard.assert_called_once_with(mock_config, mock_df)
49
+ assert response == "leaderboard data"
50
+
51
+
52
+ @patch('backend.app.pd.read_csv')
53
+ @patch('backend.app.get_dataset_config')
54
+ @patch('backend.app.get_chart')
55
+ def test_data_files_attacks_variations(mock_get_chart, mock_get_config, mock_read_csv, client):
56
+ """Test the data_files route with attacks_variations dataset type."""
57
+ # Mock the DataFrame and config
58
+ mock_df = pd.DataFrame({'model': ['model1', 'model2'], 'attack': ['a1', 'a2']})
59
+ mock_read_csv.return_value = mock_df
60
+ mock_config = {'name': 'test_dataset'}
61
+ mock_get_config.return_value = mock_config
62
+ mock_get_chart.return_value = "chart data"
63
+
64
+ # Make the request
65
+ response = client.get('/data/test_dataset?dataset_type=attacks_variations')
66
+
67
+ # Assertions
68
+ mock_read_csv.assert_called_once()
69
+ mock_get_config.assert_called_once_with('test_dataset')
70
+ mock_get_chart.assert_called_once_with(mock_config, mock_df)
71
+ assert response == "chart data"
72
+
73
+
74
+ def test_data_files_missing_dataset_type(client):
75
+ """Test the data_files route with missing dataset_type."""
76
+ response = client.get('/data/test_dataset')
77
+ assert response.status_code == 400
78
+ assert b"Dataset type not specified" in response.data
79
+
80
+
81
+ @patch('backend.app.pd.read_csv')
82
+ def test_data_files_file_not_found(mock_read_csv, client):
83
+ """Test the data_files route when file is not found."""
84
+ mock_read_csv.side_effect = FileNotFoundError()
85
+
86
+ response = client.get('/data/test_dataset?dataset_type=benchmark')
87
+
88
+ assert response.status_code == 404
89
+ assert b"File not found" in response.data
90
+
91
+
92
+ @patch('backend.app.image_examples_tab')
93
+ def test_example_files_image(mock_image_examples, client):
94
+ """Test the example_files route with image type."""
95
+ mock_image_examples.return_value = {"examples": ["image1", "image2"]}
96
+
97
+ response = client.get('/examples/image')
98
+
99
+ assert response.status_code == 200
100
+ data = json.loads(response.data)
101
+ assert "examples" in data
102
+ mock_image_examples.assert_called_once()
103
+
104
+
105
+ @patch('backend.app.audio_examples_tab')
106
+ def test_example_files_audio(mock_audio_examples, client):
107
+ """Test the example_files route with audio type."""
108
+ mock_audio_examples.return_value = {"examples": ["audio1", "audio2"]}
109
+
110
+ response = client.get('/examples/audio')
111
+
112
+ assert response.status_code == 200
113
+ data = json.loads(response.data)
114
+ assert "examples" in data
115
+ mock_audio_examples.assert_called_once()
116
+
117
+
118
+ @patch('backend.app.video_examples_tab')
119
+ def test_example_files_video(mock_video_examples, client):
120
+ """Test the example_files route with video type."""
121
+ mock_video_examples.return_value = {"examples": ["video1", "video2"]}
122
+
123
+ response = client.get('/examples/video')
124
+
125
+ assert response.status_code == 200
126
+ data = json.loads(response.data)
127
+ assert "examples" in data
128
+ mock_video_examples.assert_called_once()
129
+
130
+
131
+ def test_example_files_invalid_type(client):
132
+ """Test the example_files route with invalid type."""
133
+ response = client.get('/examples/invalid')
134
+
135
+ assert response.status_code == 400
136
+ assert b"Invalid example type" in response.data
137
+
138
+
139
+ @patch('backend.app.requests.get')
140
+ def test_proxy_valid_url(mock_requests_get, client):
141
+ """Test the proxy route with a valid URL."""
142
+ # Create a mock response
143
+ mock_response = MagicMock()
144
+ mock_response.status_code = 200
145
+ mock_response.content = b"test content"
146
+ mock_response.headers = {"Content-Type": "text/plain"}
147
+ mock_requests_get.return_value = mock_response
148
+
149
+ # Mock the ABS_DATASET_DOMAIN constant
150
+ with patch('backend.app.ABS_DATASET_DOMAIN', 'https://example.com'):
151
+ response = client.get('/proxy/https%3A%2F%2Fexample.com%2Ftest.txt')
152
+
153
+ assert response.status_code == 200
154
+ assert response.data == b"test content"
155
+ mock_requests_get.assert_called_once()
156
+
157
+
158
+ @patch('backend.app.requests.get')
159
+ def test_proxy_invalid_domain(mock_requests_get, client):
160
+ """Test the proxy route with an invalid domain."""
161
+ # Mock the ABS_DATASET_DOMAIN constant
162
+ with patch('backend.app.ABS_DATASET_DOMAIN', 'https://example.com'):
163
+ response = client.get('/proxy/https%3A%2F%2Fmalicious.com%2Ftest.txt')
164
+
165
+ assert response.status_code == 403
166
+ data = json.loads(response.data)
167
+ assert "error" in data
168
+ mock_requests_get.assert_not_called()
169
+
170
+
171
+ @patch('backend.app.requests.get')
172
+ def test_proxy_request_error(mock_requests_get, client):
173
+ """Test the proxy route when the request fails."""
174
+ mock_requests_get.side_effect = Exception("Connection error")
175
+
176
+ # Mock the ABS_DATASET_DOMAIN constant
177
+ with patch('backend.app.ABS_DATASET_DOMAIN', 'https://example.com'):
178
+ response = client.get('/proxy/https%3A%2F%2Fexample.com%2Ftest.txt')
179
+
180
+ assert response.status_code == 500
181
+ data = json.loads(response.data)
182
+ assert "error" in data
183
+
184
+
185
+ @patch('backend.app.get_old_format_dataframe')
186
+ @patch('backend.app.get_leaderboard_filters')
187
+ def test_get_leaderboard(mock_get_filters, mock_get_old_format):
188
+ """Test the get_leaderboard function."""
189
+ # Mock the input data
190
+ df = pd.DataFrame({'model': ['model1', 'model2'], 'score': [0.9, 0.8]})
191
+ config = {
192
+ 'first_cols': ['model'],
193
+ 'attack_scores': ['score'],
194
+ 'categories': ['category1']
195
+ }
196
+
197
+ # Mock the function returns
198
+ mock_get_old_format.return_value = df
199
+ mock_get_filters.return_value = (
200
+ {'group1': ['metric1', 'metric2']},
201
+ ['metric1']
202
+ )
203
+
204
+ # Call the function
205
+ response = get_leaderboard(config, df)
206
+
207
+ # Assertions
208
+ assert response.status_code == 200
209
+ data = json.loads(response.data)
210
+ assert 'groups' in data
211
+ assert 'default_selected_metrics' in data
212
+ assert 'rows' in data
213
+ mock_get_old_format.assert_called_once_with(df, config['first_cols'], config['attack_scores'])
214
+ mock_get_filters.assert_called_once_with(df, config['categories'])
215
+
216
+
217
+ @patch('backend.app.mk_variations')
218
+ def test_get_chart(mock_mk_variations):
219
+ """Test the get_chart function."""
220
+ # Mock the input data
221
+ df = pd.DataFrame({'model': ['model1', 'model2'], 'attack': ['a1', 'a2']})
222
+ config = {
223
+ 'attacks_with_variations': ['attack1', 'attack2']
224
+ }
225
+
226
+ # Mock the function return
227
+ mock_chart_data = {'chart': 'data'}
228
+ mock_mk_variations.return_value = mock_chart_data
229
+
230
+ # Call the function
231
+ response = get_chart(config, df)
232
+
233
+ # Assertions
234
+ assert response.status_code == 200
235
+ data = json.loads(response.data)
236
+ assert data == mock_chart_data
237
+ mock_mk_variations.assert_called_once_with(df, config['attacks_with_variations'])
238
+
239
+
240
+ # Add a test for the main function
241
+ def test_main():
242
+ """Test the main function."""
243
+ with patch('backend.app.app.run') as mock_run:
244
+ # We can't directly test __main__ block, but we can test the app.run call
245
+ # by importing and calling it in a test context
246
+ import backend.app
247
+ if hasattr(backend.app, 'main'): # If main function exists
248
+ backend.app.main()
249
+ mock_run.assert_called_once_with(host="0.0.0.0", port=7860, debug=True, use_reloader=True)