made-refine 0.2.20 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/babel.cjs +5 -1
- package/dist/index.d.mts +22 -4
- package/dist/index.d.ts +22 -4
- package/dist/index.js +1525 -793
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1526 -794
- package/dist/index.mjs.map +1 -1
- package/dist/preload/preload.js +26 -3
- package/dist/preload.js +25 -3
- package/dist/preload.js.map +1 -1
- package/dist/preload.mjs +10 -3
- package/dist/preload.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/{utils-CpmjloNg.d.mts → utils-ovHeRo0g.d.mts} +20 -16
- package/dist/{utils-CpmjloNg.d.ts → utils-ovHeRo0g.d.ts} +20 -16
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +292 -198
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +292 -198
- package/dist/utils.mjs.map +1 -1
- package/package.json +14 -3
package/dist/index.js
CHANGED
|
@@ -87,7 +87,7 @@ var React8 = __toESM(require("react"));
|
|
|
87
87
|
var React = __toESM(require("react"));
|
|
88
88
|
|
|
89
89
|
// dist/styles.css
|
|
90
|
-
var styles_default = '/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */\n@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-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@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-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--font-weight-thin:100;--font-weight-extralight:200;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-weight-black:900;--leading-relaxed:1.625;--radius-sm:calc(.5rem - 4px);--radius-md:calc(.5rem - 2px);--radius-xl:.75rem;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-xl:24px;--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);--color-border:#e6e6e6;--color-ring:#262626;--color-background:#fff;--color-foreground:#171717;--color-primary:#171717;--color-primary-foreground:#fafafa;--color-secondary-foreground:#171717;--color-destructive:#ef4444;--color-destructive-foreground:#fafafa;--color-muted:#f2f2f2;--color-muted-foreground:#737373;--color-popover-foreground:#171717}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,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;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root,:host{color-scheme:light;color:var(--color-foreground)}@media (prefers-color-scheme:dark){:root,:host(:not([data-theme])),:host([data-theme=system]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}}:host([data-theme=dark]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}*,:before,:after{--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-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:var(--color-background);--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;border-color:var(--color-border)}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing)*0)}.top-1\\/2{top:50%}.left-1\\.5{left:calc(var(--spacing)*1.5)}.left-1\\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-3{left:calc(var(--spacing)*3)}.z-\\[99990\\]{z-index:99990}.z-\\[99991\\]{z-index:99991}.z-\\[99998\\]{z-index:99998}.z-\\[99999\\]{z-index:99999}.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}}.m-4{margin:calc(var(--spacing)*4)}.mx-0\\.5{margin-inline:calc(var(--spacing)*.5)}.mx-2{margin-inline:calc(var(--spacing)*2)}.my-0\\.5{margin-block:calc(var(--spacing)*.5)}.my-1{margin-block:calc(var(--spacing)*1)}.mt-0{margin-top:calc(var(--spacing)*0)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2\\.5{margin-top:calc(var(--spacing)*2.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.ml-0{margin-left:calc(var(--spacing)*0)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.block{display:block}.contents{display:contents}.flex{display:flex}.flow-root{display:flow-root}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.inline-grid{display:inline-grid}.list-item{display:list-item}.size-1{width:calc(var(--spacing)*1);height:calc(var(--spacing)*1)}.size-2\\.5{width:calc(var(--spacing)*2.5);height:calc(var(--spacing)*2.5)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-full{width:100%;height:100%}.h-0\\.5{height:calc(var(--spacing)*.5)}.h-2{height:calc(var(--spacing)*2)}.h-3\\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-\\[150px\\]{height:150px}.h-auto{height:auto}.h-fit{height:fit-content}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-\\[240px\\]{max-height:240px}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\\[18px\\]{min-height:18px}.w-0\\.5{width:calc(var(--spacing)*.5)}.w-2{width:calc(var(--spacing)*2)}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-14{width:calc(var(--spacing)*14)}.w-\\[1\\.5px\\]{width:1.5px}.w-\\[60px\\]{width:60px}.w-\\[68px\\]{width:68px}.w-\\[180px\\]{width:180px}.w-\\[200px\\]{width:200px}.w-\\[240px\\]{width:240px}.w-\\[260px\\]{width:260px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-\\[18px\\]{min-width:18px}.min-w-\\[20px\\]{min-width:20px}.min-w-\\[100px\\]{min-width:100px}.min-w-\\[120px\\]{min-width:120px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.origin-\\(--transform-origin\\){transform-origin:var(--transform-origin)}.-translate-x-1\\/2{--tw-translate-x:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);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,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.\\[appearance\\:textfield\\]{appearance:textfield}.appearance-none{appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\\[0fr\\]{grid-template-columns:0fr}.grid-cols-\\[1fr\\]{grid-template-columns:1fr}.grid-rows-\\[0fr\\]{grid-template-rows:0fr}.grid-rows-\\[1fr\\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-around{justify-content:space-around}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-evenly{justify-content:space-evenly}.justify-start{justify-content:flex-start}.gap-0\\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-\\[2px\\]{gap:2px}.gap-\\[4px\\]{gap:4px}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-hidden{overflow-y:hidden}.rounded{border-radius:.25rem}.rounded-\\[6px\\]{border-radius:6px}.rounded-\\[8px\\]{border-radius:8px}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-tl{border-top-left-radius:.25rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-bl{border-bottom-left-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-dotted{--tw-border-style:dotted;border-style:dotted}.border-double{--tw-border-style:double;border-style:double}.border-none{--tw-border-style:none;border-style:none}.border-solid{--tw-border-style:solid;border-style:solid}.\\[border-top-style\\:solid\\]{border-top-style:solid}.\\[border-right-style\\:dashed\\]{border-right-style:dashed}.\\[border-bottom-style\\:dashed\\]{border-bottom-style:dashed}.\\[border-bottom-style\\:dotted\\]{border-bottom-style:dotted}.\\[border-bottom-style\\:solid\\]{border-bottom-style:solid}.\\[border-left-style\\:double\\]{border-left-style:double}.\\[border-left-style\\:solid\\]{border-left-style:solid}.border-border{border-color:var(--color-border)}.border-border\\/30{border-color:#e6e6e64d}@supports (color:color-mix(in lab, red, red)){.border-border\\/30{border-color:color-mix(in oklab,var(--color-border)30%,transparent)}}.border-border\\/50{border-color:#e6e6e680}@supports (color:color-mix(in lab, red, red)){.border-border\\/50{border-color:color-mix(in oklab,var(--color-border)50%,transparent)}}.border-foreground\\/10{border-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.border-foreground\\/10{border-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.border-transparent{border-color:#0000}.border-white{border-color:var(--color-white)}.bg-\\[canvas\\]{background-color:canvas}.bg-background{background-color:var(--color-background)}.bg-background\\/85{background-color:#ffffffd9}@supports (color:color-mix(in lab, red, red)){.bg-background\\/85{background-color:color-mix(in oklab,var(--color-background)85%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-border{background-color:var(--color-border)}.bg-destructive{background-color:var(--color-destructive)}.bg-foreground{background-color:var(--color-foreground)}.bg-foreground\\/25{background-color:#17171740}@supports (color:color-mix(in lab, red, red)){.bg-foreground\\/25{background-color:color-mix(in oklab,var(--color-foreground)25%,transparent)}}.bg-muted{background-color:var(--color-muted)}.bg-muted-foreground\\/30{background-color:#7373734d}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\\/30{background-color:color-mix(in oklab,var(--color-muted-foreground)30%,transparent)}}.bg-primary{background-color:var(--color-primary)}.bg-transparent{background-color:#0000}.fill-border{fill:var(--color-border)}.p-0{padding:calc(var(--spacing)*0)}.p-0\\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-0{padding-block:calc(var(--spacing)*0)}.py-0\\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-3\\.5{padding-block:calc(var(--spacing)*3.5)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2\\.5{padding-top:calc(var(--spacing)*2.5)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pt-\\[13px\\]{padding-top:13px}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-1\\.5{padding-right:calc(var(--spacing)*1.5)}.pr-2{padding-right:calc(var(--spacing)*2)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-1\\.5{padding-bottom:calc(var(--spacing)*1.5)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pl-0{padding-left:calc(var(--spacing)*0)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-7{padding-left:calc(var(--spacing)*7)}.text-center{text-align:center}.text-justify{text-align:justify}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[7px\\]{font-size:7px}.text-\\[9px\\]{font-size:9px}.text-\\[10px\\]{font-size:10px}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-extralight{--tw-font-weight:var(--font-weight-extralight);font-weight:var(--font-weight-extralight)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.font-thin{--tw-font-weight:var(--font-weight-thin);font-weight:var(--font-weight-thin)}.\\[overflow-wrap\\:anywhere\\]{overflow-wrap:anywhere}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-background{color:var(--color-background)}.text-blue-500{color:var(--color-blue-500)}.text-destructive-foreground{color:var(--color-destructive-foreground)}.text-foreground{color:var(--color-foreground)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-muted-foreground{color:var(--color-muted-foreground)}.text-popover-foreground{color:var(--color-popover-foreground)}.text-primary{color:var(--color-primary)}.text-primary-foreground{color:var(--color-primary-foreground)}.text-red-500{color:var(--color-red-500)}.text-secondary-foreground{color:var(--color-secondary-foreground)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xs{--tw-shadow:0 1px var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.3\\)\\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_4px_6px_-1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[inset_0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-white{--tw-ring-color:var(--color-white)}.outline,.outline-1{outline-style:var(--tw-outline-style);outline-width:1px}.outline-border{outline-color:var(--color-border)}.outline-foreground\\/10{outline-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.outline-foreground\\/10{outline-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.outline-red-500\\/70{outline-color:#fb2c36b3}@supports (color:color-mix(in lab, red, red)){.outline-red-500\\/70{outline-color:color-mix(in oklab,var(--color-red-500)70%,transparent)}}.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,)}.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,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[color\\,background-color\\]{transition-property:color,background-color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[opacity\\,background-color\\,color\\]{transition-property:opacity,background-color,color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[transform\\,scale\\,opacity\\]{transition-property:transform,scale,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.animate-in{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\\[-ms-overflow-style\\:none\\]{-ms-overflow-style:none}.\\[scrollbar-width\\:none\\]{scrollbar-width:none}.duration-150{animation-duration:.15s}.duration-200{animation-duration:.2s}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{animation-timing-function:cubic-bezier(0,0,.2,1)}.fade-in-0{--tw-enter-opacity:0}.running{animation-play-state:running}.zoom-in-95{--tw-enter-scale:.95}@media (hover:hover){.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\\/pin\\:inline:is(:where(.group\\/pin):hover *){display:inline}}.file\\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\\:bg-transparent::file-selector-button{background-color:#0000}.file\\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\\:text-foreground::file-selector-button{color:var(--color-foreground)}.placeholder\\:text-muted-foreground::placeholder{color:var(--color-muted-foreground)}.placeholder\\:text-red-400::placeholder{color:var(--color-red-400)}.focus-within\\:ring-1:focus-within{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-within\\:ring-ring:focus-within{--tw-ring-color:var(--color-ring)}.focus-within\\:outline-none:focus-within{--tw-outline-style:none;outline-style:none}.focus-within\\:ring-inset:focus-within{--tw-ring-inset:inset}@media (hover:hover){.hover\\:scale-\\[1\\.67\\]:hover{scale:1.67}.hover\\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\\:bg-destructive\\/90:hover{background-color:#ef4444e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-destructive\\/90:hover{background-color:color-mix(in oklab,var(--color-destructive)90%,transparent)}}.hover\\:bg-foreground\\/80:hover{background-color:#171717cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-foreground\\/80:hover{background-color:color-mix(in oklab,var(--color-foreground)80%,transparent)}}.hover\\:bg-muted:hover{background-color:var(--color-muted)}.hover\\:bg-muted-foreground\\/10:hover{background-color:#7373731a}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted-foreground\\/10:hover{background-color:color-mix(in oklab,var(--color-muted-foreground)10%,transparent)}}.hover\\:bg-muted\\/50:hover{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/50:hover{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.hover\\:bg-muted\\/80:hover{background-color:#f2f2f2cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/80:hover{background-color:color-mix(in oklab,var(--color-muted)80%,transparent)}}.hover\\:bg-primary\\/90:hover{background-color:#171717e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-primary\\/90:hover{background-color:color-mix(in oklab,var(--color-primary)90%,transparent)}}.hover\\:text-foreground:hover{color:var(--color-foreground)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\:ring-ring:focus-visible{--tw-ring-color:var(--color-ring)}.focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-inset:focus-visible{--tw-ring-inset:inset}.active\\:cursor-grabbing:active{cursor:grabbing}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.data-ending-style\\:scale-90[data-ending-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-ending-style\\:opacity-0[data-ending-style]{opacity:0}.data-instant\\:transition-none[data-instant]{transition-property:none}.data-starting-style\\:scale-90[data-starting-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-starting-style\\:opacity-0[data-starting-style]{opacity:0}.data-\\[highlighted\\]\\:bg-muted[data-highlighted]{background-color:var(--color-muted)}.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.data-\\[highlighted\\]\\:text-foreground[data-highlighted]{color:var(--color-foreground)}@media (prefers-color-scheme:dark){.dark\\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dark\\:-outline-offset-1{outline-offset:calc(1px*-1)}}.\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.\\[\\&_svg\\]\\:size-3\\.5 svg{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.\\[\\&\\:\\:-webkit-inner-spin-button\\]\\:appearance-none::-webkit-inner-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-outer-spin-button\\]\\:appearance-none::-webkit-outer-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-scrollbar\\]\\:hidden::-webkit-scrollbar{display:none}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition:none;animation:none}}.lucide{stroke-width:1px}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@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-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{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-outline-style{syntax:"*";inherits:false;initial-value:solid}@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-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes pulse{50%{opacity:.5}}';
|
|
90
|
+
var styles_default = '/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */\n@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-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@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-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--font-weight-thin:100;--font-weight-extralight:200;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-weight-black:900;--leading-relaxed:1.625;--radius-sm:calc(.5rem - 4px);--radius-md:calc(.5rem - 2px);--radius-xl:.75rem;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-xl:24px;--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);--color-border:#e6e6e6;--color-ring:#262626;--color-background:#fff;--color-foreground:#171717;--color-primary:#171717;--color-primary-foreground:#fafafa;--color-secondary-foreground:#171717;--color-destructive:#ef4444;--color-destructive-foreground:#fafafa;--color-muted:#f2f2f2;--color-muted-foreground:#737373;--color-popover-foreground:#171717}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,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;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root,:host{color-scheme:light;color:var(--color-foreground)}@media (prefers-color-scheme:dark){:root,:host(:not([data-theme])),:host([data-theme=system]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}}:host([data-theme=dark]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}*,:before,:after{--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-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:var(--color-background);--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;border-color:var(--color-border)}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing)*0)}.top-1\\/2{top:50%}.left-1\\.5{left:calc(var(--spacing)*1.5)}.left-1\\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-3{left:calc(var(--spacing)*3)}.isolate{isolation:isolate}.z-\\[99990\\]{z-index:99990}.z-\\[99991\\]{z-index:99991}.z-\\[99998\\]{z-index:99998}.z-\\[99999\\]{z-index:99999}.\\!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}}.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}}.m-4{margin:calc(var(--spacing)*4)}.mx-0\\.5{margin-inline:calc(var(--spacing)*.5)}.mx-2{margin-inline:calc(var(--spacing)*2)}.my-0\\.5{margin-block:calc(var(--spacing)*.5)}.my-1{margin-block:calc(var(--spacing)*1)}.mt-0{margin-top:calc(var(--spacing)*0)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2\\.5{margin-top:calc(var(--spacing)*2.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.ml-0{margin-left:calc(var(--spacing)*0)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.block{display:block}.contents{display:contents}.flex{display:flex}.flow-root{display:flow-root}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.inline-grid{display:inline-grid}.list-item{display:list-item}.table{display:table}.size-1{width:calc(var(--spacing)*1);height:calc(var(--spacing)*1)}.size-2\\.5{width:calc(var(--spacing)*2.5);height:calc(var(--spacing)*2.5)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-full{width:100%;height:100%}.h-0\\.5{height:calc(var(--spacing)*.5)}.h-2{height:calc(var(--spacing)*2)}.h-3\\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-\\[150px\\]{height:150px}.h-auto{height:auto}.h-fit{height:fit-content}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-\\[240px\\]{max-height:240px}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\\[18px\\]{min-height:18px}.w-0\\.5{width:calc(var(--spacing)*.5)}.w-2{width:calc(var(--spacing)*2)}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-14{width:calc(var(--spacing)*14)}.w-\\[1\\.5px\\]{width:1.5px}.w-\\[60px\\]{width:60px}.w-\\[68px\\]{width:68px}.w-\\[180px\\]{width:180px}.w-\\[200px\\]{width:200px}.w-\\[240px\\]{width:240px}.w-\\[260px\\]{width:260px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-\\[18px\\]{min-width:18px}.min-w-\\[20px\\]{min-width:20px}.min-w-\\[100px\\]{min-width:100px}.min-w-\\[120px\\]{min-width:120px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.origin-\\(--transform-origin\\){transform-origin:var(--transform-origin)}.-translate-x-1\\/2{--tw-translate-x:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.rotate-45{rotate:45deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.\\[appearance\\:textfield\\]{appearance:textfield}.appearance-none{appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\\[0fr\\]{grid-template-columns:0fr}.grid-cols-\\[1fr\\]{grid-template-columns:1fr}.grid-rows-\\[0fr\\]{grid-template-rows:0fr}.grid-rows-\\[1fr\\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-around{justify-content:space-around}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-evenly{justify-content:space-evenly}.justify-start{justify-content:flex-start}.gap-0\\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-\\[2px\\]{gap:2px}.gap-\\[4px\\]{gap:4px}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-hidden{overflow-y:hidden}.rounded{border-radius:.25rem}.rounded-\\[6px\\]{border-radius:6px}.rounded-\\[8px\\]{border-radius:8px}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-tl{border-top-left-radius:.25rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-bl{border-bottom-left-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-dotted{--tw-border-style:dotted;border-style:dotted}.border-double{--tw-border-style:double;border-style:double}.border-none{--tw-border-style:none;border-style:none}.border-solid{--tw-border-style:solid;border-style:solid}.\\[border-top-style\\:solid\\]{border-top-style:solid}.\\[border-right-style\\:dashed\\]{border-right-style:dashed}.\\[border-bottom-style\\:dashed\\]{border-bottom-style:dashed}.\\[border-bottom-style\\:dotted\\]{border-bottom-style:dotted}.\\[border-bottom-style\\:solid\\]{border-bottom-style:solid}.\\[border-left-style\\:double\\]{border-left-style:double}.\\[border-left-style\\:solid\\]{border-left-style:solid}.border-border{border-color:var(--color-border)}.border-border\\/30{border-color:#e6e6e64d}@supports (color:color-mix(in lab, red, red)){.border-border\\/30{border-color:color-mix(in oklab,var(--color-border)30%,transparent)}}.border-border\\/50{border-color:#e6e6e680}@supports (color:color-mix(in lab, red, red)){.border-border\\/50{border-color:color-mix(in oklab,var(--color-border)50%,transparent)}}.border-foreground\\/10{border-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.border-foreground\\/10{border-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.border-transparent{border-color:#0000}.border-white{border-color:var(--color-white)}.bg-\\[canvas\\]{background-color:canvas}.bg-background{background-color:var(--color-background)}.bg-background\\/85{background-color:#ffffffd9}@supports (color:color-mix(in lab, red, red)){.bg-background\\/85{background-color:color-mix(in oklab,var(--color-background)85%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-border{background-color:var(--color-border)}.bg-destructive{background-color:var(--color-destructive)}.bg-foreground{background-color:var(--color-foreground)}.bg-foreground\\/25{background-color:#17171740}@supports (color:color-mix(in lab, red, red)){.bg-foreground\\/25{background-color:color-mix(in oklab,var(--color-foreground)25%,transparent)}}.bg-muted{background-color:var(--color-muted)}.bg-muted-foreground\\/30{background-color:#7373734d}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\\/30{background-color:color-mix(in oklab,var(--color-muted-foreground)30%,transparent)}}.bg-primary{background-color:var(--color-primary)}.bg-red-500{background-color:var(--color-red-500)}.bg-transparent{background-color:#0000}.fill-border{fill:var(--color-border)}.p-0{padding:calc(var(--spacing)*0)}.p-0\\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-0{padding-block:calc(var(--spacing)*0)}.py-0\\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-3\\.5{padding-block:calc(var(--spacing)*3.5)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2\\.5{padding-top:calc(var(--spacing)*2.5)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pt-\\[13px\\]{padding-top:13px}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-1\\.5{padding-right:calc(var(--spacing)*1.5)}.pr-2{padding-right:calc(var(--spacing)*2)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-1\\.5{padding-bottom:calc(var(--spacing)*1.5)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pl-0{padding-left:calc(var(--spacing)*0)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-7{padding-left:calc(var(--spacing)*7)}.text-center{text-align:center}.text-justify{text-align:justify}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[7px\\]{font-size:7px}.text-\\[9px\\]{font-size:9px}.text-\\[10px\\]{font-size:10px}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-extralight{--tw-font-weight:var(--font-weight-extralight);font-weight:var(--font-weight-extralight)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.font-thin{--tw-font-weight:var(--font-weight-thin);font-weight:var(--font-weight-thin)}.\\[overflow-wrap\\:anywhere\\]{overflow-wrap:anywhere}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-background{color:var(--color-background)}.text-blue-500{color:var(--color-blue-500)}.text-destructive-foreground{color:var(--color-destructive-foreground)}.text-foreground{color:var(--color-foreground)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-muted-foreground{color:var(--color-muted-foreground)}.text-popover-foreground{color:var(--color-popover-foreground)}.text-primary{color:var(--color-primary)}.text-primary-foreground{color:var(--color-primary-foreground)}.text-red-500{color:var(--color-red-500)}.text-secondary-foreground{color:var(--color-secondary-foreground)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xs{--tw-shadow:0 1px var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.3\\)\\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_4px_6px_-1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[inset_0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-white{--tw-ring-color:var(--color-white)}.outline,.outline-1{outline-style:var(--tw-outline-style);outline-width:1px}.outline-border{outline-color:var(--color-border)}.outline-foreground\\/10{outline-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.outline-foreground\\/10{outline-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.outline-red-500\\/70{outline-color:#fb2c36b3}@supports (color:color-mix(in lab, red, red)){.outline-red-500\\/70{outline-color:color-mix(in oklab,var(--color-red-500)70%,transparent)}}.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,)}.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,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[color\\,background-color\\]{transition-property:color,background-color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[opacity\\,background-color\\,color\\]{transition-property:opacity,background-color,color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[transform\\,scale\\,opacity\\]{transition-property:transform,scale,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.animate-in{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\\[-ms-overflow-style\\:none\\]{-ms-overflow-style:none}.\\[scrollbar-width\\:none\\]{scrollbar-width:none}.duration-150{animation-duration:.15s}.duration-200{animation-duration:.2s}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{animation-timing-function:cubic-bezier(0,0,.2,1)}.fade-in-0{--tw-enter-opacity:0}.running{animation-play-state:running}.zoom-in-95{--tw-enter-scale:.95}@media (hover:hover){.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\\/pin\\:inline:is(:where(.group\\/pin):hover *){display:inline}}.file\\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\\:bg-transparent::file-selector-button{background-color:#0000}.file\\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\\:text-foreground::file-selector-button{color:var(--color-foreground)}.placeholder\\:text-muted-foreground::placeholder{color:var(--color-muted-foreground)}.placeholder\\:text-red-400::placeholder{color:var(--color-red-400)}.focus-within\\:ring-1:focus-within{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-within\\:ring-ring:focus-within{--tw-ring-color:var(--color-ring)}.focus-within\\:outline-none:focus-within{--tw-outline-style:none;outline-style:none}.focus-within\\:ring-inset:focus-within{--tw-ring-inset:inset}@media (hover:hover){.hover\\:scale-\\[1\\.67\\]:hover{scale:1.67}.hover\\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\\:bg-destructive\\/90:hover{background-color:#ef4444e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-destructive\\/90:hover{background-color:color-mix(in oklab,var(--color-destructive)90%,transparent)}}.hover\\:bg-foreground\\/80:hover{background-color:#171717cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-foreground\\/80:hover{background-color:color-mix(in oklab,var(--color-foreground)80%,transparent)}}.hover\\:bg-muted:hover{background-color:var(--color-muted)}.hover\\:bg-muted-foreground\\/10:hover{background-color:#7373731a}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted-foreground\\/10:hover{background-color:color-mix(in oklab,var(--color-muted-foreground)10%,transparent)}}.hover\\:bg-muted\\/50:hover{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/50:hover{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.hover\\:bg-muted\\/80:hover{background-color:#f2f2f2cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/80:hover{background-color:color-mix(in oklab,var(--color-muted)80%,transparent)}}.hover\\:bg-primary\\/90:hover{background-color:#171717e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-primary\\/90:hover{background-color:color-mix(in oklab,var(--color-primary)90%,transparent)}}.hover\\:text-foreground:hover{color:var(--color-foreground)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\:ring-ring:focus-visible{--tw-ring-color:var(--color-ring)}.focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-inset:focus-visible{--tw-ring-inset:inset}.active\\:cursor-grabbing:active{cursor:grabbing}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.data-ending-style\\:scale-90[data-ending-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-ending-style\\:opacity-0[data-ending-style]{opacity:0}.data-instant\\:transition-none[data-instant]{transition-property:none}.data-starting-style\\:scale-90[data-starting-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-starting-style\\:opacity-0[data-starting-style]{opacity:0}.data-\\[highlighted\\]\\:bg-muted[data-highlighted]{background-color:var(--color-muted)}.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.data-\\[highlighted\\]\\:text-foreground[data-highlighted]{color:var(--color-foreground)}@media (prefers-color-scheme:dark){.dark\\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dark\\:-outline-offset-1{outline-offset:calc(1px*-1)}}.\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.\\[\\&_svg\\]\\:size-3\\.5 svg{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.\\[\\&\\:\\:-webkit-inner-spin-button\\]\\:appearance-none::-webkit-inner-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-outer-spin-button\\]\\:appearance-none::-webkit-outer-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-scrollbar\\]\\:hidden::-webkit-scrollbar{display:none}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition:none;animation:none}}.lucide{stroke-width:1px}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@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-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{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-outline-style{syntax:"*";inherits:false;initial-value:solid}@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-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes pulse{50%{opacity:.5}}';
|
|
91
91
|
|
|
92
92
|
// src/portal-container.tsx
|
|
93
93
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -477,10 +477,30 @@ function getSourceFromFiber(fiber) {
|
|
|
477
477
|
if (fromDebugStack?.fileName) return fromDebugStack;
|
|
478
478
|
return null;
|
|
479
479
|
}
|
|
480
|
+
var REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref");
|
|
481
|
+
var REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo");
|
|
482
|
+
function resolveComponentName(type) {
|
|
483
|
+
let current = type;
|
|
484
|
+
for (let depth = 0; depth < 4 && current != null; depth++) {
|
|
485
|
+
const name = current.displayName || (typeof current === "function" ? current.name : void 0);
|
|
486
|
+
if (name) return name;
|
|
487
|
+
if (typeof current !== "object") return null;
|
|
488
|
+
if (current.$$typeof === REACT_MEMO_TYPE) {
|
|
489
|
+
current = current.type;
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
if (current.$$typeof === REACT_FORWARD_REF_TYPE) {
|
|
493
|
+
current = current.render;
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
496
|
+
return null;
|
|
497
|
+
}
|
|
498
|
+
return null;
|
|
499
|
+
}
|
|
480
500
|
function buildFrame(fiber) {
|
|
481
501
|
const type = fiber?.type;
|
|
482
502
|
if (typeof type !== "function" && typeof type !== "object") return null;
|
|
483
|
-
const name = type
|
|
503
|
+
const name = resolveComponentName(type);
|
|
484
504
|
if (!name || name === "Fragment") return null;
|
|
485
505
|
const frame = { name };
|
|
486
506
|
const source = getSourceFromFiber(fiber);
|
|
@@ -552,14 +572,7 @@ function getReactComponentInfo(element) {
|
|
|
552
572
|
}
|
|
553
573
|
return { ...getRenderStack(fiber), elementSourceFile };
|
|
554
574
|
}
|
|
555
|
-
var EXCLUDED_PROP_KEYS = /* @__PURE__ */ new Set([
|
|
556
|
-
"className",
|
|
557
|
-
"style",
|
|
558
|
-
"children",
|
|
559
|
-
"ref",
|
|
560
|
-
"key",
|
|
561
|
-
"render"
|
|
562
|
-
]);
|
|
575
|
+
var EXCLUDED_PROP_KEYS = /* @__PURE__ */ new Set(["className", "style", "children", "ref", "key", "render"]);
|
|
563
576
|
function serializePropValue(value) {
|
|
564
577
|
if (typeof value === "function") return "[function]";
|
|
565
578
|
if (typeof value === "symbol") return void 0;
|
|
@@ -670,19 +683,7 @@ function classifyComponentFiber(fiber, frames, elementSourceFile) {
|
|
|
670
683
|
return { isComponentPrimitive: false };
|
|
671
684
|
}
|
|
672
685
|
|
|
673
|
-
// src/utils.ts
|
|
674
|
-
function clamp(value, min, max) {
|
|
675
|
-
if (!Number.isFinite(value)) return min;
|
|
676
|
-
if (max < min) return min;
|
|
677
|
-
return Math.max(min, Math.min(max, value));
|
|
678
|
-
}
|
|
679
|
-
function isInputFocused() {
|
|
680
|
-
let active = document.activeElement;
|
|
681
|
-
while (active?.shadowRoot?.activeElement) {
|
|
682
|
-
active = active.shadowRoot.activeElement;
|
|
683
|
-
}
|
|
684
|
-
return active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable;
|
|
685
|
-
}
|
|
686
|
+
// src/utils/computed-styles.ts
|
|
686
687
|
function getComputedStyles(element) {
|
|
687
688
|
const computed = window.getComputedStyle(element);
|
|
688
689
|
return {
|
|
@@ -791,6 +792,255 @@ function getOriginalInlineStyles(element) {
|
|
|
791
792
|
}
|
|
792
793
|
return styles;
|
|
793
794
|
}
|
|
795
|
+
function getComputedTypography(element) {
|
|
796
|
+
const computed = window.getComputedStyle(element);
|
|
797
|
+
let textVerticalAlign = "flex-start";
|
|
798
|
+
if (computed.display === "flex" || computed.display === "inline-flex") {
|
|
799
|
+
const alignItems = computed.alignItems;
|
|
800
|
+
if (alignItems === "center") textVerticalAlign = "center";
|
|
801
|
+
else if (alignItems === "flex-end" || alignItems === "end") textVerticalAlign = "flex-end";
|
|
802
|
+
}
|
|
803
|
+
const lineHeight = computed.lineHeight === "normal" ? {
|
|
804
|
+
numericValue: parseFloat(computed.fontSize) * 1.2,
|
|
805
|
+
unit: "px",
|
|
806
|
+
raw: `${Math.round(parseFloat(computed.fontSize) * 1.2)}px`
|
|
807
|
+
} : parsePropertyValue(computed.lineHeight);
|
|
808
|
+
const fontSize = parseFloat(computed.fontSize);
|
|
809
|
+
let letterSpacing;
|
|
810
|
+
if (computed.letterSpacing === "normal") {
|
|
811
|
+
letterSpacing = { numericValue: 0, unit: "em", raw: "0em" };
|
|
812
|
+
} else {
|
|
813
|
+
const parsed = parsePropertyValue(computed.letterSpacing);
|
|
814
|
+
if (parsed.unit === "px" && fontSize > 0) {
|
|
815
|
+
const emValue = Math.round(parsed.numericValue / fontSize * 100) / 100;
|
|
816
|
+
letterSpacing = { numericValue: emValue, unit: "em", raw: `${emValue}em` };
|
|
817
|
+
} else {
|
|
818
|
+
letterSpacing = parsed;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
return {
|
|
822
|
+
fontFamily: computed.fontFamily,
|
|
823
|
+
fontWeight: computed.fontWeight,
|
|
824
|
+
fontSize: parsePropertyValue(computed.fontSize),
|
|
825
|
+
lineHeight,
|
|
826
|
+
letterSpacing,
|
|
827
|
+
textAlign: computed.textAlign,
|
|
828
|
+
textVerticalAlign
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
function getComputedSizing(element) {
|
|
832
|
+
return {
|
|
833
|
+
width: getSizingValue(element, "width"),
|
|
834
|
+
height: getSizingValue(element, "height")
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
var TEXT_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
838
|
+
"p",
|
|
839
|
+
"h1",
|
|
840
|
+
"h2",
|
|
841
|
+
"h3",
|
|
842
|
+
"h4",
|
|
843
|
+
"h5",
|
|
844
|
+
"h6",
|
|
845
|
+
"span",
|
|
846
|
+
"label",
|
|
847
|
+
"a",
|
|
848
|
+
"strong",
|
|
849
|
+
"em",
|
|
850
|
+
"small",
|
|
851
|
+
"blockquote",
|
|
852
|
+
"li",
|
|
853
|
+
"td",
|
|
854
|
+
"th",
|
|
855
|
+
"caption",
|
|
856
|
+
"figcaption",
|
|
857
|
+
"legend",
|
|
858
|
+
"dt",
|
|
859
|
+
"dd",
|
|
860
|
+
"abbr",
|
|
861
|
+
"cite",
|
|
862
|
+
"code",
|
|
863
|
+
"pre"
|
|
864
|
+
]);
|
|
865
|
+
function hasDirectNonWhitespaceText(element) {
|
|
866
|
+
return Array.from(element.childNodes).some(
|
|
867
|
+
(node) => node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
var TRANSPARENT_COLOR = { hex: "000000", alpha: 0, raw: "transparent" };
|
|
871
|
+
function isVisibleBorderSide(side) {
|
|
872
|
+
return side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0;
|
|
873
|
+
}
|
|
874
|
+
function hasVisibleOutline(computed) {
|
|
875
|
+
return computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
|
|
876
|
+
}
|
|
877
|
+
function parseVisibleColor(value, fallbackCurrentColor) {
|
|
878
|
+
const raw = value.trim();
|
|
879
|
+
const lowered = raw.toLowerCase();
|
|
880
|
+
if (!raw || lowered === "none" || lowered === "transparent") {
|
|
881
|
+
return null;
|
|
882
|
+
}
|
|
883
|
+
const resolved = /^currentcolor$/i.test(raw) ? fallbackCurrentColor ?? raw : raw;
|
|
884
|
+
const parsed = parseColorValue(resolved);
|
|
885
|
+
if (parsed.alpha <= 0) {
|
|
886
|
+
return null;
|
|
887
|
+
}
|
|
888
|
+
return parsed;
|
|
889
|
+
}
|
|
890
|
+
function addUniqueColor(colors, color) {
|
|
891
|
+
if (!color) return;
|
|
892
|
+
colors.set(`${color.hex}:${color.alpha}`, color);
|
|
893
|
+
}
|
|
894
|
+
function isTextRenderingFormControl(element) {
|
|
895
|
+
if (element instanceof HTMLTextAreaElement) return true;
|
|
896
|
+
if (element instanceof HTMLSelectElement) return true;
|
|
897
|
+
if (element instanceof HTMLButtonElement) return true;
|
|
898
|
+
if (element instanceof HTMLInputElement) {
|
|
899
|
+
const textlessInputTypes = /* @__PURE__ */ new Set([
|
|
900
|
+
"hidden",
|
|
901
|
+
"checkbox",
|
|
902
|
+
"radio",
|
|
903
|
+
"range",
|
|
904
|
+
"color",
|
|
905
|
+
"file",
|
|
906
|
+
"image"
|
|
907
|
+
]);
|
|
908
|
+
return !textlessInputTypes.has(element.type.toLowerCase());
|
|
909
|
+
}
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
function hasRenderableTextNode(element) {
|
|
913
|
+
if (element.isContentEditable) return true;
|
|
914
|
+
if (isTextRenderingFormControl(element)) return true;
|
|
915
|
+
if (!element.textContent?.trim()) return false;
|
|
916
|
+
if (hasDirectNonWhitespaceText(element)) return true;
|
|
917
|
+
const tagName = element.tagName.toLowerCase();
|
|
918
|
+
return TEXT_ELEMENT_TAGS.has(tagName) || element.children.length === 0;
|
|
919
|
+
}
|
|
920
|
+
function getComputedBoxShadow(element) {
|
|
921
|
+
const computed = window.getComputedStyle(element);
|
|
922
|
+
const value = computed.boxShadow.trim();
|
|
923
|
+
return value || "none";
|
|
924
|
+
}
|
|
925
|
+
function getComputedColorStyles(element) {
|
|
926
|
+
const computed = window.getComputedStyle(element);
|
|
927
|
+
const borderSides = [
|
|
928
|
+
{
|
|
929
|
+
style: computed.borderTopStyle,
|
|
930
|
+
width: computed.borderTopWidth,
|
|
931
|
+
color: computed.borderTopColor
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
style: computed.borderRightStyle,
|
|
935
|
+
width: computed.borderRightWidth,
|
|
936
|
+
color: computed.borderRightColor
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
style: computed.borderBottomStyle,
|
|
940
|
+
width: computed.borderBottomWidth,
|
|
941
|
+
color: computed.borderBottomColor
|
|
942
|
+
},
|
|
943
|
+
{
|
|
944
|
+
style: computed.borderLeftStyle,
|
|
945
|
+
width: computed.borderLeftWidth,
|
|
946
|
+
color: computed.borderLeftColor
|
|
947
|
+
}
|
|
948
|
+
];
|
|
949
|
+
const visibleBorderSide = borderSides.find((side) => isVisibleBorderSide(side));
|
|
950
|
+
const hasBorder = Boolean(visibleBorderSide);
|
|
951
|
+
const hasOutline = hasVisibleOutline(computed);
|
|
952
|
+
return {
|
|
953
|
+
backgroundColor: parseColorValue(computed.backgroundColor),
|
|
954
|
+
color: parseColorValue(computed.color),
|
|
955
|
+
borderColor: hasBorder && visibleBorderSide ? parseColorValue(visibleBorderSide.color) : TRANSPARENT_COLOR,
|
|
956
|
+
outlineColor: hasOutline ? parseColorValue(computed.outlineColor) : TRANSPARENT_COLOR
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
function getSelectionColors(element) {
|
|
960
|
+
const uniqueColors = /* @__PURE__ */ new Map();
|
|
961
|
+
const queue = [element];
|
|
962
|
+
for (let index = 0; index < queue.length; index++) {
|
|
963
|
+
const node = queue[index];
|
|
964
|
+
const computed = window.getComputedStyle(node);
|
|
965
|
+
if (computed.display === "none") {
|
|
966
|
+
continue;
|
|
967
|
+
}
|
|
968
|
+
const isVisibilityHidden = computed.visibility === "hidden" || computed.visibility === "collapse";
|
|
969
|
+
const currentTextColor = computed.color;
|
|
970
|
+
if (!isVisibilityHidden) {
|
|
971
|
+
addUniqueColor(uniqueColors, parseVisibleColor(computed.backgroundColor));
|
|
972
|
+
if (node instanceof HTMLElement && hasRenderableTextNode(node)) {
|
|
973
|
+
addUniqueColor(uniqueColors, parseVisibleColor(currentTextColor));
|
|
974
|
+
}
|
|
975
|
+
const borderSides = [
|
|
976
|
+
{
|
|
977
|
+
style: computed.borderTopStyle,
|
|
978
|
+
width: computed.borderTopWidth,
|
|
979
|
+
color: computed.borderTopColor
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
style: computed.borderRightStyle,
|
|
983
|
+
width: computed.borderRightWidth,
|
|
984
|
+
color: computed.borderRightColor
|
|
985
|
+
},
|
|
986
|
+
{
|
|
987
|
+
style: computed.borderBottomStyle,
|
|
988
|
+
width: computed.borderBottomWidth,
|
|
989
|
+
color: computed.borderBottomColor
|
|
990
|
+
},
|
|
991
|
+
{
|
|
992
|
+
style: computed.borderLeftStyle,
|
|
993
|
+
width: computed.borderLeftWidth,
|
|
994
|
+
color: computed.borderLeftColor
|
|
995
|
+
}
|
|
996
|
+
];
|
|
997
|
+
for (const side of borderSides) {
|
|
998
|
+
if (!isVisibleBorderSide(side)) continue;
|
|
999
|
+
addUniqueColor(uniqueColors, parseVisibleColor(side.color, currentTextColor));
|
|
1000
|
+
}
|
|
1001
|
+
if (hasVisibleOutline(computed)) {
|
|
1002
|
+
addUniqueColor(uniqueColors, parseVisibleColor(computed.outlineColor, currentTextColor));
|
|
1003
|
+
}
|
|
1004
|
+
if (node instanceof SVGElement) {
|
|
1005
|
+
const fillColor = parseVisibleColor(computed.getPropertyValue("fill"), currentTextColor) ?? parseVisibleColor(node.getAttribute("fill") ?? "", currentTextColor);
|
|
1006
|
+
const strokeColor = parseVisibleColor(computed.getPropertyValue("stroke"), currentTextColor) ?? parseVisibleColor(node.getAttribute("stroke") ?? "", currentTextColor);
|
|
1007
|
+
addUniqueColor(uniqueColors, fillColor);
|
|
1008
|
+
addUniqueColor(uniqueColors, strokeColor);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
for (const child of node.children) {
|
|
1012
|
+
queue.push(child);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
return Array.from(uniqueColors.values());
|
|
1016
|
+
}
|
|
1017
|
+
function getAllComputedStyles(element) {
|
|
1018
|
+
const { spacing, borderRadius, flex } = getComputedStyles(element);
|
|
1019
|
+
return {
|
|
1020
|
+
spacing,
|
|
1021
|
+
borderRadius,
|
|
1022
|
+
border: getComputedBorderStyles(element),
|
|
1023
|
+
flex,
|
|
1024
|
+
sizing: getComputedSizing(element),
|
|
1025
|
+
color: getComputedColorStyles(element),
|
|
1026
|
+
boxShadow: getComputedBoxShadow(element),
|
|
1027
|
+
typography: getComputedTypography(element)
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// src/utils.ts
|
|
1032
|
+
function clamp(value, min, max) {
|
|
1033
|
+
if (!Number.isFinite(value)) return min;
|
|
1034
|
+
if (max < min) return min;
|
|
1035
|
+
return Math.max(min, Math.min(max, value));
|
|
1036
|
+
}
|
|
1037
|
+
function isInputFocused() {
|
|
1038
|
+
let active = document.activeElement;
|
|
1039
|
+
while (active?.shadowRoot?.activeElement) {
|
|
1040
|
+
active = active.shadowRoot.activeElement;
|
|
1041
|
+
}
|
|
1042
|
+
return active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable;
|
|
1043
|
+
}
|
|
794
1044
|
var spacingScale = { 0: "0", 1: "px", 2: "0.5", 4: "1", 8: "2", 12: "3", 16: "4", 20: "5", 24: "6", 32: "8" };
|
|
795
1045
|
var tailwindClassMap = {
|
|
796
1046
|
padding: { prefix: "p", scale: spacingScale },
|
|
@@ -1117,7 +1367,7 @@ var typographyPropertyToCSSMap = {
|
|
|
1117
1367
|
textAlign: "text-align",
|
|
1118
1368
|
textVerticalAlign: "align-items"
|
|
1119
1369
|
};
|
|
1120
|
-
var
|
|
1370
|
+
var TEXT_ELEMENT_TAGS2 = /* @__PURE__ */ new Set([
|
|
1121
1371
|
"p",
|
|
1122
1372
|
"h1",
|
|
1123
1373
|
"h2",
|
|
@@ -1145,55 +1395,23 @@ var TEXT_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
|
1145
1395
|
"code",
|
|
1146
1396
|
"pre"
|
|
1147
1397
|
]);
|
|
1148
|
-
function
|
|
1398
|
+
function hasDirectNonWhitespaceText2(element) {
|
|
1149
1399
|
return Array.from(element.childNodes).some(
|
|
1150
1400
|
(node) => node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())
|
|
1151
1401
|
);
|
|
1152
1402
|
}
|
|
1153
1403
|
function isTextElement2(element) {
|
|
1154
1404
|
const tagName = element.tagName.toLowerCase();
|
|
1155
|
-
if (
|
|
1156
|
-
return true;
|
|
1157
|
-
}
|
|
1158
|
-
if (
|
|
1159
|
-
return true;
|
|
1160
|
-
}
|
|
1161
|
-
if (element.children.length === 0 && element.textContent?.trim()) {
|
|
1162
|
-
return true;
|
|
1163
|
-
}
|
|
1164
|
-
return false;
|
|
1165
|
-
}
|
|
1166
|
-
function getComputedTypography(element) {
|
|
1167
|
-
const computed = window.getComputedStyle(element);
|
|
1168
|
-
let textVerticalAlign = "flex-start";
|
|
1169
|
-
if (computed.display === "flex" || computed.display === "inline-flex") {
|
|
1170
|
-
const alignItems = computed.alignItems;
|
|
1171
|
-
if (alignItems === "center") textVerticalAlign = "center";
|
|
1172
|
-
else if (alignItems === "flex-end" || alignItems === "end") textVerticalAlign = "flex-end";
|
|
1173
|
-
}
|
|
1174
|
-
const lineHeight = computed.lineHeight === "normal" ? { numericValue: parseFloat(computed.fontSize) * 1.2, unit: "px", raw: `${Math.round(parseFloat(computed.fontSize) * 1.2)}px` } : parsePropertyValue(computed.lineHeight);
|
|
1175
|
-
const fontSize = parseFloat(computed.fontSize);
|
|
1176
|
-
let letterSpacing;
|
|
1177
|
-
if (computed.letterSpacing === "normal") {
|
|
1178
|
-
letterSpacing = { numericValue: 0, unit: "em", raw: "0em" };
|
|
1179
|
-
} else {
|
|
1180
|
-
const parsed = parsePropertyValue(computed.letterSpacing);
|
|
1181
|
-
if (parsed.unit === "px" && fontSize > 0) {
|
|
1182
|
-
const emValue = Math.round(parsed.numericValue / fontSize * 100) / 100;
|
|
1183
|
-
letterSpacing = { numericValue: emValue, unit: "em", raw: `${emValue}em` };
|
|
1184
|
-
} else {
|
|
1185
|
-
letterSpacing = parsed;
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
return {
|
|
1189
|
-
fontFamily: computed.fontFamily,
|
|
1190
|
-
fontWeight: computed.fontWeight,
|
|
1191
|
-
fontSize: parsePropertyValue(computed.fontSize),
|
|
1192
|
-
lineHeight,
|
|
1193
|
-
letterSpacing,
|
|
1194
|
-
textAlign: computed.textAlign,
|
|
1195
|
-
textVerticalAlign
|
|
1196
|
-
};
|
|
1405
|
+
if (TEXT_ELEMENT_TAGS2.has(tagName)) {
|
|
1406
|
+
return true;
|
|
1407
|
+
}
|
|
1408
|
+
if (hasDirectNonWhitespaceText2(element)) {
|
|
1409
|
+
return true;
|
|
1410
|
+
}
|
|
1411
|
+
if (element.children.length === 0 && element.textContent?.trim()) {
|
|
1412
|
+
return true;
|
|
1413
|
+
}
|
|
1414
|
+
return false;
|
|
1197
1415
|
}
|
|
1198
1416
|
function detectSizingMode(element, dimension) {
|
|
1199
1417
|
const computed = window.getComputedStyle(element);
|
|
@@ -1242,12 +1460,6 @@ function getSizingValue(element, dimension) {
|
|
|
1242
1460
|
}
|
|
1243
1461
|
};
|
|
1244
1462
|
}
|
|
1245
|
-
function getComputedSizing(element) {
|
|
1246
|
-
return {
|
|
1247
|
-
width: getSizingValue(element, "width"),
|
|
1248
|
-
height: getSizingValue(element, "height")
|
|
1249
|
-
};
|
|
1250
|
-
}
|
|
1251
1463
|
function sizingValueToCSS(sizing) {
|
|
1252
1464
|
switch (sizing.mode) {
|
|
1253
1465
|
case "fill":
|
|
@@ -1356,134 +1568,6 @@ function parseColorValue(cssValue) {
|
|
|
1356
1568
|
}
|
|
1357
1569
|
return parseNamedColor(raw);
|
|
1358
1570
|
}
|
|
1359
|
-
var TRANSPARENT_COLOR = { hex: "000000", alpha: 0, raw: "transparent" };
|
|
1360
|
-
function isVisibleBorderSide(side) {
|
|
1361
|
-
return side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0;
|
|
1362
|
-
}
|
|
1363
|
-
function hasVisibleOutline(computed) {
|
|
1364
|
-
return computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
|
|
1365
|
-
}
|
|
1366
|
-
function parseVisibleColor(value, fallbackCurrentColor) {
|
|
1367
|
-
const raw = value.trim();
|
|
1368
|
-
const lowered = raw.toLowerCase();
|
|
1369
|
-
if (!raw || lowered === "none" || lowered === "transparent") {
|
|
1370
|
-
return null;
|
|
1371
|
-
}
|
|
1372
|
-
const resolved = /^currentcolor$/i.test(raw) ? fallbackCurrentColor ?? raw : raw;
|
|
1373
|
-
const parsed = parseColorValue(resolved);
|
|
1374
|
-
if (parsed.alpha <= 0) {
|
|
1375
|
-
return null;
|
|
1376
|
-
}
|
|
1377
|
-
return parsed;
|
|
1378
|
-
}
|
|
1379
|
-
function addUniqueColor(colors, color) {
|
|
1380
|
-
if (!color) return;
|
|
1381
|
-
colors.set(`${color.hex}:${color.alpha}`, color);
|
|
1382
|
-
}
|
|
1383
|
-
function isTextRenderingFormControl(element) {
|
|
1384
|
-
if (element instanceof HTMLTextAreaElement) return true;
|
|
1385
|
-
if (element instanceof HTMLSelectElement) return true;
|
|
1386
|
-
if (element instanceof HTMLButtonElement) return true;
|
|
1387
|
-
if (element instanceof HTMLInputElement) {
|
|
1388
|
-
const textlessInputTypes = /* @__PURE__ */ new Set([
|
|
1389
|
-
"hidden",
|
|
1390
|
-
"checkbox",
|
|
1391
|
-
"radio",
|
|
1392
|
-
"range",
|
|
1393
|
-
"color",
|
|
1394
|
-
"file",
|
|
1395
|
-
"image"
|
|
1396
|
-
]);
|
|
1397
|
-
return !textlessInputTypes.has(element.type.toLowerCase());
|
|
1398
|
-
}
|
|
1399
|
-
return false;
|
|
1400
|
-
}
|
|
1401
|
-
function hasRenderableTextNode(element) {
|
|
1402
|
-
if (element.isContentEditable) return true;
|
|
1403
|
-
if (isTextRenderingFormControl(element)) return true;
|
|
1404
|
-
if (!element.textContent?.trim()) return false;
|
|
1405
|
-
if (hasDirectNonWhitespaceText(element)) return true;
|
|
1406
|
-
const tagName = element.tagName.toLowerCase();
|
|
1407
|
-
return TEXT_ELEMENT_TAGS.has(tagName) || element.children.length === 0;
|
|
1408
|
-
}
|
|
1409
|
-
function getComputedBoxShadow(element) {
|
|
1410
|
-
const computed = window.getComputedStyle(element);
|
|
1411
|
-
const value = computed.boxShadow.trim();
|
|
1412
|
-
return value || "none";
|
|
1413
|
-
}
|
|
1414
|
-
function getComputedColorStyles(element) {
|
|
1415
|
-
const computed = window.getComputedStyle(element);
|
|
1416
|
-
const borderSides = [
|
|
1417
|
-
{ style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
|
|
1418
|
-
{ style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
|
|
1419
|
-
{ style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
|
|
1420
|
-
{ style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
|
|
1421
|
-
];
|
|
1422
|
-
const visibleBorderSide = borderSides.find((side) => isVisibleBorderSide(side));
|
|
1423
|
-
const hasBorder = Boolean(visibleBorderSide);
|
|
1424
|
-
const hasOutline = hasVisibleOutline(computed);
|
|
1425
|
-
return {
|
|
1426
|
-
backgroundColor: parseColorValue(computed.backgroundColor),
|
|
1427
|
-
color: parseColorValue(computed.color),
|
|
1428
|
-
borderColor: hasBorder && visibleBorderSide ? parseColorValue(visibleBorderSide.color) : TRANSPARENT_COLOR,
|
|
1429
|
-
outlineColor: hasOutline ? parseColorValue(computed.outlineColor) : TRANSPARENT_COLOR
|
|
1430
|
-
};
|
|
1431
|
-
}
|
|
1432
|
-
function getSelectionColors(element) {
|
|
1433
|
-
const uniqueColors = /* @__PURE__ */ new Map();
|
|
1434
|
-
const queue = [element];
|
|
1435
|
-
for (let index = 0; index < queue.length; index++) {
|
|
1436
|
-
const node = queue[index];
|
|
1437
|
-
const computed = window.getComputedStyle(node);
|
|
1438
|
-
if (computed.display === "none") {
|
|
1439
|
-
continue;
|
|
1440
|
-
}
|
|
1441
|
-
const isVisibilityHidden = computed.visibility === "hidden" || computed.visibility === "collapse";
|
|
1442
|
-
const currentTextColor = computed.color;
|
|
1443
|
-
if (!isVisibilityHidden) {
|
|
1444
|
-
addUniqueColor(uniqueColors, parseVisibleColor(computed.backgroundColor));
|
|
1445
|
-
if (node instanceof HTMLElement && hasRenderableTextNode(node)) {
|
|
1446
|
-
addUniqueColor(uniqueColors, parseVisibleColor(currentTextColor));
|
|
1447
|
-
}
|
|
1448
|
-
const borderSides = [
|
|
1449
|
-
{ style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
|
|
1450
|
-
{ style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
|
|
1451
|
-
{ style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
|
|
1452
|
-
{ style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
|
|
1453
|
-
];
|
|
1454
|
-
for (const side of borderSides) {
|
|
1455
|
-
if (!isVisibleBorderSide(side)) continue;
|
|
1456
|
-
addUniqueColor(uniqueColors, parseVisibleColor(side.color, currentTextColor));
|
|
1457
|
-
}
|
|
1458
|
-
if (hasVisibleOutline(computed)) {
|
|
1459
|
-
addUniqueColor(uniqueColors, parseVisibleColor(computed.outlineColor, currentTextColor));
|
|
1460
|
-
}
|
|
1461
|
-
if (node instanceof SVGElement) {
|
|
1462
|
-
const fillColor = parseVisibleColor(computed.getPropertyValue("fill"), currentTextColor) ?? parseVisibleColor(node.getAttribute("fill") ?? "", currentTextColor);
|
|
1463
|
-
const strokeColor = parseVisibleColor(computed.getPropertyValue("stroke"), currentTextColor) ?? parseVisibleColor(node.getAttribute("stroke") ?? "", currentTextColor);
|
|
1464
|
-
addUniqueColor(uniqueColors, fillColor);
|
|
1465
|
-
addUniqueColor(uniqueColors, strokeColor);
|
|
1466
|
-
}
|
|
1467
|
-
}
|
|
1468
|
-
for (const child of node.children) {
|
|
1469
|
-
queue.push(child);
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
return Array.from(uniqueColors.values());
|
|
1473
|
-
}
|
|
1474
|
-
function getAllComputedStyles(element) {
|
|
1475
|
-
const { spacing, borderRadius, flex } = getComputedStyles(element);
|
|
1476
|
-
return {
|
|
1477
|
-
spacing,
|
|
1478
|
-
borderRadius,
|
|
1479
|
-
border: getComputedBorderStyles(element),
|
|
1480
|
-
flex,
|
|
1481
|
-
sizing: getComputedSizing(element),
|
|
1482
|
-
color: getComputedColorStyles(element),
|
|
1483
|
-
boxShadow: getComputedBoxShadow(element),
|
|
1484
|
-
typography: getComputedTypography(element)
|
|
1485
|
-
};
|
|
1486
|
-
}
|
|
1487
1571
|
var colorPropertyToCSSMap = {
|
|
1488
1572
|
backgroundColor: "background-color",
|
|
1489
1573
|
color: "color",
|
|
@@ -1938,7 +2022,7 @@ function findChildAtPoint(parent, clientX, clientY) {
|
|
|
1938
2022
|
return clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom;
|
|
1939
2023
|
});
|
|
1940
2024
|
if (hit) return hit;
|
|
1941
|
-
if (children.length === 1 && !
|
|
2025
|
+
if (children.length === 1 && !hasDirectNonWhitespaceText2(parent)) return children[0];
|
|
1942
2026
|
return null;
|
|
1943
2027
|
}
|
|
1944
2028
|
function elementFromPointWithoutOverlays(x, y) {
|
|
@@ -2492,7 +2576,7 @@ function buildElementContext(locator) {
|
|
|
2492
2576
|
return buildLocatorContextLines(locator).join("\n");
|
|
2493
2577
|
}
|
|
2494
2578
|
function hasSessionEditChanges(edit) {
|
|
2495
|
-
return Object.keys(edit.pendingStyles).length > 0 || Boolean(edit.textEdit) || Boolean(edit.move);
|
|
2579
|
+
return Object.keys(edit.pendingStyles).length > 0 || Boolean(edit.textEdit) || Boolean(edit.move) || Boolean(edit.deleted);
|
|
2496
2580
|
}
|
|
2497
2581
|
function partitionMultiSelectedEdits(elements, sessionEditsRef) {
|
|
2498
2582
|
const editsWithChanges = [];
|
|
@@ -3014,7 +3098,7 @@ function buildMoveEntries(edits) {
|
|
|
3014
3098
|
let noopMoveCount = 0;
|
|
3015
3099
|
for (const edit of edits) {
|
|
3016
3100
|
const move = edit.move;
|
|
3017
|
-
if (!move) continue;
|
|
3101
|
+
if (!move || edit.deleted) continue;
|
|
3018
3102
|
const subject = buildAnchorRef(
|
|
3019
3103
|
getElementDisplayName(edit.element) || edit.locator.tagName,
|
|
3020
3104
|
edit.locator.domSelector,
|
|
@@ -3173,19 +3257,22 @@ function getExportContentProfile(edits, comments, movePlanOrContext) {
|
|
|
3173
3257
|
hasCssEdits: edits.some((e) => Object.keys(e.pendingStyles).length > 0),
|
|
3174
3258
|
hasTextEdits: edits.some((e) => e.textEdit != null),
|
|
3175
3259
|
hasMoves: moveOpCount > 0,
|
|
3176
|
-
hasComments: comments.length > 0
|
|
3260
|
+
hasComments: comments.length > 0,
|
|
3261
|
+
hasDeletes: edits.some((e) => e.deleted)
|
|
3177
3262
|
};
|
|
3178
3263
|
}
|
|
3179
3264
|
function buildExportInstruction(profile) {
|
|
3180
3265
|
const { hasCssEdits, hasTextEdits, hasMoves, hasComments } = profile;
|
|
3181
|
-
|
|
3182
|
-
if (!hasCssEdits && !hasTextEdits && !hasMoves)
|
|
3266
|
+
const hasDeletes = Boolean(profile.hasDeletes);
|
|
3267
|
+
if (!hasCssEdits && !hasTextEdits && !hasMoves && !hasComments && !hasDeletes) return "";
|
|
3268
|
+
if (!hasCssEdits && !hasTextEdits && !hasMoves && !hasDeletes) {
|
|
3183
3269
|
return hasComments ? "Address this feedback on the UI. Use the provided source location and selector to find each element in the codebase." : "";
|
|
3184
3270
|
}
|
|
3185
3271
|
const parts = [];
|
|
3186
3272
|
if (hasCssEdits) parts.push("Apply the CSS changes to the targeted elements using the project's existing styling approach (Tailwind, CSS modules, etc.). Map values to existing CSS variables, design tokens, or utility classes already used in the project whenever possible.");
|
|
3187
3273
|
if (hasTextEdits) parts.push("Update the text content as specified.");
|
|
3188
3274
|
if (hasMoves) parts.push("Implement the move plan below directly in source code. For `structural_move`, reorder/reparent elements using the target anchors. For `layout_refactor`, apply the listed flex/grid refactor steps. Do NOT simulate movement with absolute positioning, left/top offsets, transform, or margin hacks.");
|
|
3275
|
+
if (hasDeletes) parts.push("Delete the elements marked for deletion from the source code \u2014 remove their markup/JSX (and any now-dead props, handlers, or imports they solely used).");
|
|
3189
3276
|
if (hasComments) parts.push("Address the comments on the relevant elements.");
|
|
3190
3277
|
return `${parts.join(" ")} Use the provided source locations, selectors, and context HTML to locate each element in the codebase.`;
|
|
3191
3278
|
}
|
|
@@ -3220,6 +3307,13 @@ function buildSessionExport(edits, comments = [], options) {
|
|
|
3220
3307
|
blocks.push(planLines.join("\n"));
|
|
3221
3308
|
}
|
|
3222
3309
|
for (const edit of edits) {
|
|
3310
|
+
if (edit.deleted) {
|
|
3311
|
+
const lines = buildLocatorContextLines(edit.locator);
|
|
3312
|
+
lines.push("");
|
|
3313
|
+
lines.push("action: delete this element \u2014 remove it from the source");
|
|
3314
|
+
blocks.push(lines.join("\n"));
|
|
3315
|
+
continue;
|
|
3316
|
+
}
|
|
3223
3317
|
const moveIntent = getMoveIntentForEdit(edit, planContext);
|
|
3224
3318
|
const hasMove = Boolean(moveIntent);
|
|
3225
3319
|
const hasStyleOrText = Object.keys(edit.pendingStyles).length > 0 || edit.textEdit != null;
|
|
@@ -4128,6 +4222,7 @@ function useSessionManager({
|
|
|
4128
4222
|
sessionEditsRef,
|
|
4129
4223
|
removedSessionEditsRef,
|
|
4130
4224
|
undoStackRef,
|
|
4225
|
+
onElementInsertedRef,
|
|
4131
4226
|
pushUndo,
|
|
4132
4227
|
setState,
|
|
4133
4228
|
setSessionEditCount
|
|
@@ -4324,27 +4419,48 @@ function useSessionManager({
|
|
|
4324
4419
|
selectElement(firstChild);
|
|
4325
4420
|
}
|
|
4326
4421
|
}, [getSelectableChild, selectElement]);
|
|
4422
|
+
const centerElementOnBody = React3.useCallback((element, size) => {
|
|
4423
|
+
const bodyRect = document.body.getBoundingClientRect();
|
|
4424
|
+
const scaleX = document.body.offsetWidth > 0 ? bodyRect.width / document.body.offsetWidth : 1;
|
|
4425
|
+
const scaleY = document.body.offsetHeight > 0 ? bodyRect.height / document.body.offsetHeight : 1;
|
|
4426
|
+
const fallbackWidth = size?.width ?? element.offsetWidth ?? 0;
|
|
4427
|
+
const fallbackHeight = size?.height ?? element.offsetHeight ?? 0;
|
|
4428
|
+
const measuredRect = element.getBoundingClientRect();
|
|
4429
|
+
const width = measuredRect.width || fallbackWidth;
|
|
4430
|
+
const height = measuredRect.height || fallbackHeight;
|
|
4431
|
+
const left = Math.round((window.innerWidth / 2 - bodyRect.left) / scaleX - width / 2);
|
|
4432
|
+
const top = Math.round((window.innerHeight / 2 - bodyRect.top) / scaleY - height / 2);
|
|
4433
|
+
element.style.left = `${left}px`;
|
|
4434
|
+
element.style.top = `${top}px`;
|
|
4435
|
+
}, []);
|
|
4327
4436
|
const insertElement = React3.useCallback((kind) => {
|
|
4328
4437
|
if (!stateRef.current.editModeActive) return;
|
|
4329
4438
|
saveCurrentToSession();
|
|
4330
4439
|
const restoreSelection = buildSelectionSnapshot();
|
|
4331
4440
|
const selectedEl = stateRef.current.selectedElement;
|
|
4332
|
-
const
|
|
4333
|
-
const
|
|
4334
|
-
const
|
|
4335
|
-
const element = document.createElement("div");
|
|
4441
|
+
const insertsAsSibling = kind === "frame" || kind === "text";
|
|
4442
|
+
const hasSelection = insertsAsSibling && selectedEl !== null && selectedEl !== document.body && selectedEl.parentElement !== null;
|
|
4443
|
+
const element = document.createElement(kind === "text" ? "p" : "div");
|
|
4336
4444
|
element.id = nextGeneratedCanvasId(kind);
|
|
4337
4445
|
element.setAttribute(GENERATED_CANVAS_NODE_ATTR, kind);
|
|
4338
|
-
element.style.width = `${width}px`;
|
|
4339
|
-
element.style.height = `${height}px`;
|
|
4340
4446
|
element.style.boxSizing = "border-box";
|
|
4341
4447
|
if (kind === "frame") {
|
|
4448
|
+
element.style.width = "100px";
|
|
4449
|
+
element.style.height = "100px";
|
|
4342
4450
|
element.style.background = "#F5F5F5";
|
|
4343
4451
|
element.style.border = "1px solid #E0E0E0";
|
|
4344
|
-
} else {
|
|
4452
|
+
} else if (kind === "div") {
|
|
4453
|
+
element.style.width = "160px";
|
|
4454
|
+
element.style.height = "96px";
|
|
4345
4455
|
element.style.borderRadius = "12px";
|
|
4346
4456
|
element.style.border = "1px solid rgba(13, 153, 255, 0.35)";
|
|
4347
4457
|
element.style.background = "rgba(13, 153, 255, 0.08)";
|
|
4458
|
+
} else {
|
|
4459
|
+
element.textContent = "Text";
|
|
4460
|
+
element.style.display = "inline-block";
|
|
4461
|
+
element.style.margin = "0";
|
|
4462
|
+
element.style.minHeight = "24px";
|
|
4463
|
+
element.style.textAlign = "center";
|
|
4348
4464
|
}
|
|
4349
4465
|
if (hasSelection) {
|
|
4350
4466
|
const insertionParent = selectedEl.parentElement;
|
|
@@ -4355,16 +4471,22 @@ function useSessionManager({
|
|
|
4355
4471
|
insertionParent.appendChild(element);
|
|
4356
4472
|
}
|
|
4357
4473
|
} else {
|
|
4358
|
-
const bodyRect = document.body.getBoundingClientRect();
|
|
4359
|
-
const scaleX = document.body.offsetWidth > 0 ? bodyRect.width / document.body.offsetWidth : 1;
|
|
4360
|
-
const scaleY = document.body.offsetHeight > 0 ? bodyRect.height / document.body.offsetHeight : 1;
|
|
4361
|
-
const left = Math.round((window.innerWidth / 2 - bodyRect.left) / scaleX - width / 2);
|
|
4362
|
-
const top = Math.round((window.innerHeight / 2 - bodyRect.top) / scaleY - height / 2);
|
|
4363
4474
|
element.style.position = "absolute";
|
|
4364
|
-
element.style.left = `${left}px`;
|
|
4365
|
-
element.style.top = `${top}px`;
|
|
4366
4475
|
element.style.zIndex = "1";
|
|
4367
|
-
|
|
4476
|
+
if (kind === "text") {
|
|
4477
|
+
element.style.left = "0px";
|
|
4478
|
+
element.style.top = "0px";
|
|
4479
|
+
element.style.visibility = "hidden";
|
|
4480
|
+
document.body.appendChild(element);
|
|
4481
|
+
centerElementOnBody(element);
|
|
4482
|
+
element.style.visibility = "";
|
|
4483
|
+
} else {
|
|
4484
|
+
centerElementOnBody(
|
|
4485
|
+
element,
|
|
4486
|
+
kind === "frame" ? { width: 100, height: 100 } : { width: 160, height: 96 }
|
|
4487
|
+
);
|
|
4488
|
+
document.body.appendChild(element);
|
|
4489
|
+
}
|
|
4368
4490
|
}
|
|
4369
4491
|
pushUndo({
|
|
4370
4492
|
type: "structure",
|
|
@@ -4379,7 +4501,8 @@ function useSessionManager({
|
|
|
4379
4501
|
primaryElement: element,
|
|
4380
4502
|
pushUndo: false
|
|
4381
4503
|
});
|
|
4382
|
-
|
|
4504
|
+
onElementInsertedRef.current?.(kind, element);
|
|
4505
|
+
}, [applySelection, buildSelectionSnapshot, centerElementOnBody, onElementInsertedRef, pushUndo, saveCurrentToSession, stateRef]);
|
|
4383
4506
|
const groupSelection = React3.useCallback(() => {
|
|
4384
4507
|
const selected = getSanitizedSelection(stateRef.current.selectedElements);
|
|
4385
4508
|
if (selected.length < 2) return;
|
|
@@ -4475,9 +4598,17 @@ function useSessionManager({
|
|
|
4475
4598
|
}));
|
|
4476
4599
|
const sessionSnapshots = /* @__PURE__ */ new Map();
|
|
4477
4600
|
for (const el of selected) {
|
|
4478
|
-
const
|
|
4479
|
-
|
|
4480
|
-
sessionEditsRef.current.
|
|
4601
|
+
const existing = sessionEditsRef.current.get(el);
|
|
4602
|
+
sessionSnapshots.set(el, existing ?? null);
|
|
4603
|
+
sessionEditsRef.current.set(el, existing ? { ...existing, deleted: true } : {
|
|
4604
|
+
element: el,
|
|
4605
|
+
locator: getElementLocator(el),
|
|
4606
|
+
originalStyles: {},
|
|
4607
|
+
pendingStyles: {},
|
|
4608
|
+
move: null,
|
|
4609
|
+
textEdit: null,
|
|
4610
|
+
deleted: true
|
|
4611
|
+
});
|
|
4481
4612
|
}
|
|
4482
4613
|
syncSessionItemCount();
|
|
4483
4614
|
for (const { element } of snapshots) {
|
|
@@ -4498,7 +4629,8 @@ function useSessionManager({
|
|
|
4498
4629
|
}
|
|
4499
4630
|
}
|
|
4500
4631
|
for (const [el, edit] of sessionSnapshots) {
|
|
4501
|
-
sessionEditsRef.current.set(el, edit);
|
|
4632
|
+
if (edit) sessionEditsRef.current.set(el, edit);
|
|
4633
|
+
else sessionEditsRef.current.delete(el);
|
|
4502
4634
|
}
|
|
4503
4635
|
syncSessionItemCount();
|
|
4504
4636
|
}
|
|
@@ -4889,7 +5021,7 @@ function useSessionManager({
|
|
|
4889
5021
|
saveCurrentToSession();
|
|
4890
5022
|
const edits = [];
|
|
4891
5023
|
for (const edit of sessionEditsRef.current.values()) {
|
|
4892
|
-
if (!edit.element.isConnected) {
|
|
5024
|
+
if (!edit.element.isConnected && !edit.deleted) {
|
|
4893
5025
|
sessionEditsRef.current.delete(edit.element);
|
|
4894
5026
|
continue;
|
|
4895
5027
|
}
|
|
@@ -5058,6 +5190,7 @@ ${exportMarkdown}`);
|
|
|
5058
5190
|
|
|
5059
5191
|
// src/use-text-and-comments.ts
|
|
5060
5192
|
var React4 = __toESM(require("react"));
|
|
5193
|
+
var GENERATED_CANVAS_NODE_ATTR2 = "data-made-refine-canvas-node";
|
|
5061
5194
|
function clampUnit(value) {
|
|
5062
5195
|
if (!Number.isFinite(value)) return 0;
|
|
5063
5196
|
return Math.max(0, Math.min(1, value));
|
|
@@ -5093,6 +5226,94 @@ function useTextAndComments({
|
|
|
5093
5226
|
editingElement.style.outlineOffset = "";
|
|
5094
5227
|
editingElement.style.cursor = originalCursor;
|
|
5095
5228
|
editingElement.blur();
|
|
5229
|
+
const isGeneratedTextElement = editingElement.getAttribute(GENERATED_CANVAS_NODE_ATTR2) === "text";
|
|
5230
|
+
const shouldDeleteGeneratedText = isGeneratedTextElement && newText.trim().length === 0;
|
|
5231
|
+
if (shouldDeleteGeneratedText) {
|
|
5232
|
+
const parent = editingElement.parentElement;
|
|
5233
|
+
const nextSibling = editingElement.nextSibling;
|
|
5234
|
+
const current = stateRef.current;
|
|
5235
|
+
const removedComments = current.comments.filter((comment) => comment.element === editingElement);
|
|
5236
|
+
const removedCommentIds = new Set(removedComments.map((comment) => comment.id));
|
|
5237
|
+
const remainingComments = current.comments.filter((comment) => comment.element !== editingElement);
|
|
5238
|
+
const restoredActiveCommentId = current.activeCommentId && removedCommentIds.has(current.activeCommentId) ? current.activeCommentId : null;
|
|
5239
|
+
const existingSessionEdit = existing ? {
|
|
5240
|
+
...existing,
|
|
5241
|
+
originalStyles: { ...existing.originalStyles },
|
|
5242
|
+
pendingStyles: { ...existing.pendingStyles },
|
|
5243
|
+
move: existing.move ? { ...existing.move } : null,
|
|
5244
|
+
textEdit: existing.textEdit ? { ...existing.textEdit } : null
|
|
5245
|
+
} : null;
|
|
5246
|
+
const restoreSelection = {
|
|
5247
|
+
isOpen: current.isOpen,
|
|
5248
|
+
selectedElement: current.selectedElement,
|
|
5249
|
+
selectedElements: [...current.selectedElements],
|
|
5250
|
+
selectionAnchorElement: current.selectionAnchorElement,
|
|
5251
|
+
originalStyles: { ...current.originalStyles },
|
|
5252
|
+
pendingStyles: { ...current.pendingStyles }
|
|
5253
|
+
};
|
|
5254
|
+
sessionEditsRef.current.delete(editingElement);
|
|
5255
|
+
if (editingElement.isConnected) {
|
|
5256
|
+
editingElement.remove();
|
|
5257
|
+
}
|
|
5258
|
+
pushUndo({
|
|
5259
|
+
type: "structure",
|
|
5260
|
+
restoreSelection,
|
|
5261
|
+
undo: () => {
|
|
5262
|
+
editingElement.textContent = previousText;
|
|
5263
|
+
if (!editingElement.isConnected && parent?.isConnected) {
|
|
5264
|
+
if (nextSibling && nextSibling.parentNode === parent) {
|
|
5265
|
+
parent.insertBefore(editingElement, nextSibling);
|
|
5266
|
+
} else {
|
|
5267
|
+
parent.appendChild(editingElement);
|
|
5268
|
+
}
|
|
5269
|
+
}
|
|
5270
|
+
if (existingSessionEdit) {
|
|
5271
|
+
sessionEditsRef.current.set(editingElement, existingSessionEdit);
|
|
5272
|
+
}
|
|
5273
|
+
setState((prev) => ({
|
|
5274
|
+
...prev,
|
|
5275
|
+
comments: current.comments,
|
|
5276
|
+
activeCommentId: restoredActiveCommentId ?? prev.activeCommentId
|
|
5277
|
+
}));
|
|
5278
|
+
syncSessionItemCount(current.comments);
|
|
5279
|
+
}
|
|
5280
|
+
});
|
|
5281
|
+
syncSessionItemCount(remainingComments);
|
|
5282
|
+
setState((prev) => {
|
|
5283
|
+
const selectionContainsElement = prev.selectedElement === editingElement || prev.selectionAnchorElement === editingElement || prev.selectedElements.includes(editingElement);
|
|
5284
|
+
if (!selectionContainsElement) {
|
|
5285
|
+
return prev.textEditingElement === editingElement ? {
|
|
5286
|
+
...prev,
|
|
5287
|
+
comments: prev.comments.filter((comment) => comment.element !== editingElement),
|
|
5288
|
+
activeCommentId: prev.activeCommentId && removedCommentIds.has(prev.activeCommentId) ? null : prev.activeCommentId,
|
|
5289
|
+
textEditingElement: null
|
|
5290
|
+
} : prev;
|
|
5291
|
+
}
|
|
5292
|
+
return {
|
|
5293
|
+
...prev,
|
|
5294
|
+
isOpen: false,
|
|
5295
|
+
selectedElement: null,
|
|
5296
|
+
selectedElements: [],
|
|
5297
|
+
selectionAnchorElement: null,
|
|
5298
|
+
elementInfo: null,
|
|
5299
|
+
computedSpacing: null,
|
|
5300
|
+
computedBorderRadius: null,
|
|
5301
|
+
computedBorder: null,
|
|
5302
|
+
computedFlex: null,
|
|
5303
|
+
computedSizing: null,
|
|
5304
|
+
computedColor: null,
|
|
5305
|
+
computedBoxShadow: null,
|
|
5306
|
+
computedTypography: null,
|
|
5307
|
+
isComponentPrimitive: false,
|
|
5308
|
+
comments: remainingComments,
|
|
5309
|
+
activeCommentId: restoredActiveCommentId ? null : prev.activeCommentId,
|
|
5310
|
+
originalStyles: {},
|
|
5311
|
+
pendingStyles: {},
|
|
5312
|
+
textEditingElement: null
|
|
5313
|
+
};
|
|
5314
|
+
});
|
|
5315
|
+
return;
|
|
5316
|
+
}
|
|
5096
5317
|
if (newText !== previousText) {
|
|
5097
5318
|
pushUndo({ type: "textEdit", element: editingElement, originalText, previousText });
|
|
5098
5319
|
removedSessionEditsRef.current.delete(editingElement);
|
|
@@ -5611,28 +5832,30 @@ async function toClientResponse(response) {
|
|
|
5611
5832
|
const data = await readJsonRecord(response);
|
|
5612
5833
|
const bodyOk = data?.ok;
|
|
5613
5834
|
const parsedOk = typeof bodyOk === "boolean" ? bodyOk : response.ok;
|
|
5835
|
+
const ok = parsedOk && response.ok;
|
|
5614
5836
|
return {
|
|
5615
|
-
ok
|
|
5616
|
-
id: readString(data, "id") ?? ""
|
|
5837
|
+
ok,
|
|
5838
|
+
id: readString(data, "id") ?? "",
|
|
5839
|
+
...!ok ? { errorKind: "rejected" } : {}
|
|
5617
5840
|
};
|
|
5618
5841
|
}
|
|
5619
5842
|
async function postWithSessionToken(path, payload) {
|
|
5620
5843
|
const idempotencyKey = createIdempotencyKey();
|
|
5621
5844
|
let session = await bootstrapSession();
|
|
5622
|
-
if (!session) return { ok: false, id: "" };
|
|
5845
|
+
if (!session) return { ok: false, id: "", errorKind: "network" };
|
|
5623
5846
|
let response;
|
|
5624
5847
|
try {
|
|
5625
5848
|
response = await sendAnnotationRequest(session, path, payload, idempotencyKey);
|
|
5626
5849
|
} catch {
|
|
5627
|
-
return { ok: false, id: "" };
|
|
5850
|
+
return { ok: false, id: "", errorKind: "network" };
|
|
5628
5851
|
}
|
|
5629
5852
|
if (response.status === 401 || response.status === 403) {
|
|
5630
5853
|
session = await refreshSessionToken(session) ?? await bootstrapSession(true);
|
|
5631
|
-
if (!session) return { ok: false, id: "" };
|
|
5854
|
+
if (!session) return { ok: false, id: "", errorKind: "network" };
|
|
5632
5855
|
try {
|
|
5633
5856
|
response = await sendAnnotationRequest(session, path, payload, idempotencyKey);
|
|
5634
5857
|
} catch {
|
|
5635
|
-
return { ok: false, id: "" };
|
|
5858
|
+
return { ok: false, id: "", errorKind: "network" };
|
|
5636
5859
|
}
|
|
5637
5860
|
}
|
|
5638
5861
|
return toClientResponse(response);
|
|
@@ -5685,8 +5908,10 @@ function buildLocatorPayload(locator) {
|
|
|
5685
5908
|
}
|
|
5686
5909
|
function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrentToSession, removeSessionEdit, deleteComment }) {
|
|
5687
5910
|
const [agentAvailable, setAgentAvailable] = React5.useState(false);
|
|
5911
|
+
const [lastSendFailure, setLastSendFailure] = React5.useState(null);
|
|
5688
5912
|
const isMountedRef = React5.useRef(true);
|
|
5689
5913
|
React5.useEffect(() => {
|
|
5914
|
+
isMountedRef.current = true;
|
|
5690
5915
|
return () => {
|
|
5691
5916
|
isMountedRef.current = false;
|
|
5692
5917
|
};
|
|
@@ -5743,7 +5968,7 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5743
5968
|
const resolvedPlanContext = movePlanContext ?? buildMovePlanContext(editsForPlan);
|
|
5744
5969
|
const includeBatchMoveEnvelope = Boolean(options?.includeBatchMoveEnvelope && sessionEdit.move);
|
|
5745
5970
|
const isBatchSend = Boolean(allEdits && allEdits.length > 1);
|
|
5746
|
-
const exportMarkdown = sessionEdit.move ? buildSessionExport(
|
|
5971
|
+
const exportMarkdown = sessionEdit.move || sessionEdit.deleted ? buildSessionExport(
|
|
5747
5972
|
includeBatchMoveEnvelope ? editsForPlan : [sessionEdit],
|
|
5748
5973
|
[],
|
|
5749
5974
|
{
|
|
@@ -5759,7 +5984,7 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5759
5984
|
}));
|
|
5760
5985
|
const moveIntent = sessionEdit.move ? getMoveIntentForEdit(sessionEdit, resolvedPlanContext) : null;
|
|
5761
5986
|
const movePlan = includeBatchMoveEnvelope ? resolvedPlanContext.movePlan : null;
|
|
5762
|
-
const hasMeaningfulPayload = changes.length > 0 || sessionEdit.textEdit != null || moveIntent != null;
|
|
5987
|
+
const hasMeaningfulPayload = changes.length > 0 || sessionEdit.textEdit != null || moveIntent != null || Boolean(sessionEdit.deleted);
|
|
5763
5988
|
if (!hasMeaningfulPayload) return true;
|
|
5764
5989
|
const profile = getExportContentProfile(
|
|
5765
5990
|
[sessionEdit],
|
|
@@ -5773,17 +5998,44 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5773
5998
|
textChange: sessionEdit.textEdit ?? null,
|
|
5774
5999
|
moveIntent,
|
|
5775
6000
|
...movePlan ? { movePlan } : {},
|
|
6001
|
+
...sessionEdit.deleted ? { deleted: true } : {},
|
|
5776
6002
|
exportMarkdown: withInstruction(profile, exportMarkdown)
|
|
5777
6003
|
});
|
|
5778
6004
|
if (result.ok) {
|
|
5779
6005
|
removeSessionEdit(sessionEdit.element);
|
|
6006
|
+
updateAgentAvailability(true);
|
|
6007
|
+
} else {
|
|
6008
|
+
const kind = result.errorKind === "network" ? "unreachable" : "rejected";
|
|
6009
|
+
updateAgentAvailability(result.errorKind === "network" ? false : true);
|
|
6010
|
+
if (options?._isBatchCall) {
|
|
6011
|
+
options._batchFailKinds?.push(result.errorKind ?? "rejected");
|
|
6012
|
+
} else if (isMountedRef.current) {
|
|
6013
|
+
setLastSendFailure({
|
|
6014
|
+
reason: kind,
|
|
6015
|
+
failedEditElements: [sessionEdit.element],
|
|
6016
|
+
failedCommentIds: [],
|
|
6017
|
+
at: Date.now()
|
|
6018
|
+
});
|
|
6019
|
+
}
|
|
5780
6020
|
}
|
|
5781
|
-
return
|
|
5782
|
-
} catch {
|
|
5783
|
-
|
|
6021
|
+
return result.ok;
|
|
6022
|
+
} catch (err) {
|
|
6023
|
+
updateAgentAvailability(false);
|
|
6024
|
+
if (options?._isBatchCall) {
|
|
6025
|
+
throw err;
|
|
6026
|
+
}
|
|
6027
|
+
if (isMountedRef.current) {
|
|
6028
|
+
setLastSendFailure({
|
|
6029
|
+
reason: "unreachable",
|
|
6030
|
+
failedEditElements: [sessionEdit.element],
|
|
6031
|
+
failedCommentIds: [],
|
|
6032
|
+
at: Date.now()
|
|
6033
|
+
});
|
|
6034
|
+
}
|
|
6035
|
+
return false;
|
|
5784
6036
|
}
|
|
5785
6037
|
}, [updateAgentAvailability, removeSessionEdit]);
|
|
5786
|
-
const sendSessionCommentToAgent = React5.useCallback(async (comment) => {
|
|
6038
|
+
const sendSessionCommentToAgent = React5.useCallback(async (comment, _options) => {
|
|
5787
6039
|
const exportMarkdown = buildCommentExport(comment.locator, comment.text, comment.replies);
|
|
5788
6040
|
const commentProfile = { hasCssEdits: false, hasTextEdits: false, hasMoves: false, hasComments: true };
|
|
5789
6041
|
try {
|
|
@@ -5795,13 +6047,40 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5795
6047
|
});
|
|
5796
6048
|
if (result.ok) {
|
|
5797
6049
|
deleteComment(comment.id);
|
|
6050
|
+
updateAgentAvailability(true);
|
|
6051
|
+
} else {
|
|
6052
|
+
const kind = result.errorKind === "network" ? "unreachable" : "rejected";
|
|
6053
|
+
updateAgentAvailability(result.errorKind === "network" ? false : true);
|
|
6054
|
+
if (_options?._isBatchCall) {
|
|
6055
|
+
_options._batchFailKinds?.push(result.errorKind ?? "rejected");
|
|
6056
|
+
} else if (isMountedRef.current) {
|
|
6057
|
+
setLastSendFailure({
|
|
6058
|
+
reason: kind,
|
|
6059
|
+
failedEditElements: [],
|
|
6060
|
+
failedCommentIds: [comment.id],
|
|
6061
|
+
at: Date.now()
|
|
6062
|
+
});
|
|
6063
|
+
}
|
|
5798
6064
|
}
|
|
5799
|
-
return
|
|
5800
|
-
} catch {
|
|
5801
|
-
|
|
6065
|
+
return result.ok;
|
|
6066
|
+
} catch (err) {
|
|
6067
|
+
updateAgentAvailability(false);
|
|
6068
|
+
if (_options?._isBatchCall) {
|
|
6069
|
+
throw err;
|
|
6070
|
+
}
|
|
6071
|
+
if (isMountedRef.current) {
|
|
6072
|
+
setLastSendFailure({
|
|
6073
|
+
reason: "unreachable",
|
|
6074
|
+
failedEditElements: [],
|
|
6075
|
+
failedCommentIds: [comment.id],
|
|
6076
|
+
at: Date.now()
|
|
6077
|
+
});
|
|
6078
|
+
}
|
|
6079
|
+
return false;
|
|
5802
6080
|
}
|
|
5803
6081
|
}, [updateAgentAvailability, deleteComment]);
|
|
5804
6082
|
const sendEditToAgent2 = React5.useCallback(async () => {
|
|
6083
|
+
if (isMountedRef.current) setLastSendFailure(null);
|
|
5805
6084
|
const current = stateRef.current;
|
|
5806
6085
|
if (current.selectedElements.length > 1) {
|
|
5807
6086
|
saveCurrentToSession();
|
|
@@ -5836,9 +6115,28 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5836
6115
|
removeSessionEdit(el);
|
|
5837
6116
|
}
|
|
5838
6117
|
}
|
|
6118
|
+
updateAgentAvailability(true);
|
|
6119
|
+
} else {
|
|
6120
|
+
updateAgentAvailability(result.errorKind === "network" ? false : true);
|
|
6121
|
+
if (isMountedRef.current) {
|
|
6122
|
+
setLastSendFailure({
|
|
6123
|
+
reason: result.errorKind === "network" ? "unreachable" : "rejected",
|
|
6124
|
+
failedEditElements: editsWithChanges.map((e) => e.element),
|
|
6125
|
+
failedCommentIds: [],
|
|
6126
|
+
at: Date.now()
|
|
6127
|
+
});
|
|
6128
|
+
}
|
|
5839
6129
|
}
|
|
5840
|
-
return
|
|
6130
|
+
return result.ok;
|
|
5841
6131
|
} catch {
|
|
6132
|
+
if (isMountedRef.current) {
|
|
6133
|
+
setLastSendFailure({
|
|
6134
|
+
reason: "unreachable",
|
|
6135
|
+
failedEditElements: editsWithChanges.map((e) => e.element),
|
|
6136
|
+
failedCommentIds: [],
|
|
6137
|
+
at: Date.now()
|
|
6138
|
+
});
|
|
6139
|
+
}
|
|
5842
6140
|
return updateAgentAvailability(false);
|
|
5843
6141
|
}
|
|
5844
6142
|
}
|
|
@@ -5861,11 +6159,13 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5861
6159
|
return sendSessionEditToAgent(editToSend);
|
|
5862
6160
|
}, [canSendEditToAgent, sendSessionEditToAgent, saveCurrentToSession]);
|
|
5863
6161
|
const sendCommentToAgent2 = React5.useCallback(async (id) => {
|
|
6162
|
+
if (isMountedRef.current) setLastSendFailure(null);
|
|
5864
6163
|
const comment = stateRef.current.comments.find((c) => c.id === id);
|
|
5865
6164
|
if (!comment) return false;
|
|
5866
6165
|
return sendSessionCommentToAgent(comment);
|
|
5867
6166
|
}, [sendSessionCommentToAgent]);
|
|
5868
6167
|
const sendAllSessionItemsToAgent = React5.useCallback(async () => {
|
|
6168
|
+
if (isMountedRef.current) setLastSendFailure(null);
|
|
5869
6169
|
const items = getSessionItems();
|
|
5870
6170
|
const current = stateRef.current;
|
|
5871
6171
|
const contextOnlyBlocks = getContextOnlyBlocks(current.selectedElements, items);
|
|
@@ -5874,25 +6174,44 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5874
6174
|
const movePlanContext = buildMovePlanContext(allEdits);
|
|
5875
6175
|
let moveEnvelopeSent = false;
|
|
5876
6176
|
let allSucceeded = true;
|
|
6177
|
+
const failedEditElements = [];
|
|
6178
|
+
const failedCommentIds = [];
|
|
6179
|
+
let anyThrown = false;
|
|
6180
|
+
const batchFailKinds = [];
|
|
5877
6181
|
for (const item of items) {
|
|
5878
6182
|
let succeeded;
|
|
5879
6183
|
if (item.type === "edit") {
|
|
5880
6184
|
const hasMoveIntent = Boolean(item.edit.move && getMoveIntentForEdit(item.edit, movePlanContext));
|
|
5881
6185
|
const includeBatchMoveEnvelope = hasMoveIntent && !moveEnvelopeSent;
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
6186
|
+
try {
|
|
6187
|
+
succeeded = await sendSessionEditToAgent(
|
|
6188
|
+
item.edit,
|
|
6189
|
+
allEdits,
|
|
6190
|
+
movePlanContext,
|
|
6191
|
+
{ includeBatchMoveEnvelope, _isBatchCall: true, _batchFailKinds: batchFailKinds }
|
|
6192
|
+
);
|
|
6193
|
+
if (!succeeded) failedEditElements.push(item.edit.element);
|
|
6194
|
+
} catch {
|
|
6195
|
+
succeeded = false;
|
|
6196
|
+
anyThrown = true;
|
|
6197
|
+
failedEditElements.push(item.edit.element);
|
|
6198
|
+
}
|
|
5888
6199
|
if (includeBatchMoveEnvelope) moveEnvelopeSent = true;
|
|
5889
6200
|
} else {
|
|
5890
|
-
|
|
6201
|
+
try {
|
|
6202
|
+
succeeded = await sendSessionCommentToAgent(item.comment, { _isBatchCall: true, _batchFailKinds: batchFailKinds });
|
|
6203
|
+
if (!succeeded) failedCommentIds.push(item.comment.id);
|
|
6204
|
+
} catch {
|
|
6205
|
+
succeeded = false;
|
|
6206
|
+
anyThrown = true;
|
|
6207
|
+
failedCommentIds.push(item.comment.id);
|
|
6208
|
+
}
|
|
5891
6209
|
}
|
|
5892
6210
|
if (!succeeded) {
|
|
5893
6211
|
allSucceeded = false;
|
|
5894
6212
|
}
|
|
5895
6213
|
}
|
|
6214
|
+
let contextBlockFailed = false;
|
|
5896
6215
|
if (contextOnlyBlocks.length > 0) {
|
|
5897
6216
|
const primaryEl = current.selectedElements.find(
|
|
5898
6217
|
(el) => el.isConnected && !allEdits.some((e) => e.element === el)
|
|
@@ -5906,16 +6225,39 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5906
6225
|
moveIntent: null,
|
|
5907
6226
|
exportMarkdown: contextOnlyBlocks.join("\n\n")
|
|
5908
6227
|
});
|
|
5909
|
-
if (
|
|
6228
|
+
if (result.ok) {
|
|
6229
|
+
updateAgentAvailability(true);
|
|
6230
|
+
} else {
|
|
6231
|
+
updateAgentAvailability(result.errorKind === "network" ? false : true);
|
|
6232
|
+
allSucceeded = false;
|
|
6233
|
+
contextBlockFailed = true;
|
|
6234
|
+
}
|
|
5910
6235
|
} catch {
|
|
6236
|
+
updateAgentAvailability(false);
|
|
5911
6237
|
allSucceeded = false;
|
|
6238
|
+
anyThrown = true;
|
|
6239
|
+
contextBlockFailed = true;
|
|
5912
6240
|
}
|
|
5913
6241
|
}
|
|
5914
6242
|
}
|
|
6243
|
+
if (!allSucceeded && isMountedRef.current) {
|
|
6244
|
+
const reason = anyThrown || batchFailKinds.includes("network") ? "unreachable" : "rejected";
|
|
6245
|
+
setLastSendFailure({
|
|
6246
|
+
reason,
|
|
6247
|
+
failedEditElements,
|
|
6248
|
+
failedCommentIds,
|
|
6249
|
+
at: Date.now()
|
|
6250
|
+
});
|
|
6251
|
+
}
|
|
5915
6252
|
return allSucceeded;
|
|
5916
|
-
}, [getSessionItems, sendSessionCommentToAgent, sendSessionEditToAgent]);
|
|
6253
|
+
}, [getSessionItems, sendSessionCommentToAgent, sendSessionEditToAgent, updateAgentAvailability]);
|
|
6254
|
+
const clearSendFailure = React5.useCallback(() => {
|
|
6255
|
+
if (isMountedRef.current) setLastSendFailure(null);
|
|
6256
|
+
}, []);
|
|
5917
6257
|
return {
|
|
5918
6258
|
agentAvailable,
|
|
6259
|
+
lastSendFailure,
|
|
6260
|
+
clearSendFailure,
|
|
5919
6261
|
canSendEditToAgent,
|
|
5920
6262
|
sendEditToAgent: sendEditToAgent2,
|
|
5921
6263
|
sendCommentToAgent: sendCommentToAgent2,
|
|
@@ -5962,7 +6304,9 @@ function useKeyboardShortcuts({
|
|
|
5962
6304
|
const s = stateRef.current;
|
|
5963
6305
|
const undoShortcutPressed = usesMetaForUndo ? e.metaKey && !e.ctrlKey && !e.altKey : e.ctrlKey && !e.metaKey && !e.altKey;
|
|
5964
6306
|
if (undoShortcutPressed && e.key === "z" && !e.shiftKey) {
|
|
6307
|
+
if (!s.editModeActive) return;
|
|
5965
6308
|
if (s.textEditingElement) return;
|
|
6309
|
+
if (isInputFocused()) return;
|
|
5966
6310
|
e.preventDefault();
|
|
5967
6311
|
undo();
|
|
5968
6312
|
return;
|
|
@@ -6017,6 +6361,11 @@ function useKeyboardShortcuts({
|
|
|
6017
6361
|
insertElement("frame");
|
|
6018
6362
|
return;
|
|
6019
6363
|
}
|
|
6364
|
+
if (lowerKey === "t") {
|
|
6365
|
+
e.preventDefault();
|
|
6366
|
+
insertElement("text");
|
|
6367
|
+
return;
|
|
6368
|
+
}
|
|
6020
6369
|
if (lowerKey === "d") {
|
|
6021
6370
|
e.preventDefault();
|
|
6022
6371
|
insertElement("div");
|
|
@@ -6679,6 +7028,10 @@ function DirectEditProvider({ children }) {
|
|
|
6679
7028
|
const undoStackRef = React8.useRef([]);
|
|
6680
7029
|
const sessionEditsRef = React8.useRef(/* @__PURE__ */ new Map());
|
|
6681
7030
|
const removedSessionEditsRef = React8.useRef(/* @__PURE__ */ new WeakSet());
|
|
7031
|
+
const commentDraftTextRef = React8.useRef("");
|
|
7032
|
+
const commentDraftBlockedHandlerRef = React8.useRef(null);
|
|
7033
|
+
const onElementInsertedRef = React8.useRef(null);
|
|
7034
|
+
const textInsertRafRef = React8.useRef(null);
|
|
6682
7035
|
const [sessionEditCount, setSessionEditCount] = React8.useState(0);
|
|
6683
7036
|
const stateRef = React8.useRef(state);
|
|
6684
7037
|
React8.useEffect(() => {
|
|
@@ -6713,12 +7066,13 @@ function DirectEditProvider({ children }) {
|
|
|
6713
7066
|
clearSessionEdits,
|
|
6714
7067
|
groupSelection,
|
|
6715
7068
|
deleteSelection,
|
|
6716
|
-
insertElement
|
|
7069
|
+
insertElement: insertElementBase
|
|
6717
7070
|
} = useSessionManager({
|
|
6718
7071
|
stateRef,
|
|
6719
7072
|
sessionEditsRef,
|
|
6720
7073
|
removedSessionEditsRef,
|
|
6721
7074
|
undoStackRef,
|
|
7075
|
+
onElementInsertedRef,
|
|
6722
7076
|
pushUndo,
|
|
6723
7077
|
setState,
|
|
6724
7078
|
setSessionEditCount
|
|
@@ -6768,6 +7122,41 @@ function DirectEditProvider({ children }) {
|
|
|
6768
7122
|
syncSessionItemCount,
|
|
6769
7123
|
setState
|
|
6770
7124
|
});
|
|
7125
|
+
React8.useEffect(() => {
|
|
7126
|
+
onElementInsertedRef.current = (kind, element) => {
|
|
7127
|
+
if (kind === "text") {
|
|
7128
|
+
if (textInsertRafRef.current) {
|
|
7129
|
+
cancelAnimationFrame(textInsertRafRef.current);
|
|
7130
|
+
}
|
|
7131
|
+
textInsertRafRef.current = requestAnimationFrame(() => {
|
|
7132
|
+
textInsertRafRef.current = null;
|
|
7133
|
+
if (element.isConnected) {
|
|
7134
|
+
startTextEditing(element);
|
|
7135
|
+
}
|
|
7136
|
+
});
|
|
7137
|
+
}
|
|
7138
|
+
};
|
|
7139
|
+
return () => {
|
|
7140
|
+
if (textInsertRafRef.current) {
|
|
7141
|
+
cancelAnimationFrame(textInsertRafRef.current);
|
|
7142
|
+
textInsertRafRef.current = null;
|
|
7143
|
+
}
|
|
7144
|
+
onElementInsertedRef.current = null;
|
|
7145
|
+
};
|
|
7146
|
+
}, [startTextEditing]);
|
|
7147
|
+
const setCommentDraftText = React8.useCallback((text) => {
|
|
7148
|
+
commentDraftTextRef.current = text;
|
|
7149
|
+
}, []);
|
|
7150
|
+
const setCommentDraftBlockedHandler = React8.useCallback((handler) => {
|
|
7151
|
+
commentDraftBlockedHandlerRef.current = handler;
|
|
7152
|
+
}, []);
|
|
7153
|
+
const hasPendingCommentDraft = React8.useCallback(() => {
|
|
7154
|
+
const activeCommentId = stateRef.current.activeCommentId;
|
|
7155
|
+
if (!activeCommentId) return false;
|
|
7156
|
+
const active = stateRef.current.comments.find((comment) => comment.id === activeCommentId);
|
|
7157
|
+
if (!active) return false;
|
|
7158
|
+
return active.text.trim().length === 0 && commentDraftTextRef.current.trim().length > 0;
|
|
7159
|
+
}, []);
|
|
6771
7160
|
const { toggleCanvas, enterCanvas, exitCanvas, setCanvasZoom, fitCanvasToViewport, zoomCanvasTo100 } = useCanvas({
|
|
6772
7161
|
stateRef,
|
|
6773
7162
|
setState
|
|
@@ -6904,6 +7293,8 @@ function DirectEditProvider({ children }) {
|
|
|
6904
7293
|
}, [state.editModeActive]);
|
|
6905
7294
|
const {
|
|
6906
7295
|
agentAvailable,
|
|
7296
|
+
lastSendFailure,
|
|
7297
|
+
clearSendFailure,
|
|
6907
7298
|
canSendEditToAgent,
|
|
6908
7299
|
sendEditToAgent: sendEditToAgent2,
|
|
6909
7300
|
sendCommentToAgent: sendCommentToAgent2,
|
|
@@ -6930,6 +7321,16 @@ function DirectEditProvider({ children }) {
|
|
|
6930
7321
|
} catch {
|
|
6931
7322
|
}
|
|
6932
7323
|
}, []);
|
|
7324
|
+
const insertElement = React8.useCallback((kind) => {
|
|
7325
|
+
if (hasPendingCommentDraft()) {
|
|
7326
|
+
commentDraftBlockedHandlerRef.current?.();
|
|
7327
|
+
return;
|
|
7328
|
+
}
|
|
7329
|
+
if (stateRef.current.textEditingElement) {
|
|
7330
|
+
commitTextEditing();
|
|
7331
|
+
}
|
|
7332
|
+
insertElementBase(kind);
|
|
7333
|
+
}, [commitTextEditing, hasPendingCommentDraft, insertElementBase, stateRef]);
|
|
6933
7334
|
useKeyboardShortcuts({
|
|
6934
7335
|
stateRef,
|
|
6935
7336
|
toggleEditMode,
|
|
@@ -6959,9 +7360,10 @@ function DirectEditProvider({ children }) {
|
|
|
6959
7360
|
const stateContextValue = React8.useMemo(() => ({
|
|
6960
7361
|
...state,
|
|
6961
7362
|
agentAvailable,
|
|
7363
|
+
lastSendFailure,
|
|
6962
7364
|
sessionEditCount,
|
|
6963
7365
|
multiSelectContextCount
|
|
6964
|
-
}), [agentAvailable, state, sessionEditCount, multiSelectContextCount]);
|
|
7366
|
+
}), [agentAvailable, lastSendFailure, state, sessionEditCount, multiSelectContextCount]);
|
|
6965
7367
|
const actionsContextValue = React8.useMemo(() => ({
|
|
6966
7368
|
selectElement,
|
|
6967
7369
|
selectElements,
|
|
@@ -6984,6 +7386,7 @@ function DirectEditProvider({ children }) {
|
|
|
6984
7386
|
updateTypographyProperty,
|
|
6985
7387
|
resetToOriginal,
|
|
6986
7388
|
exportEdits,
|
|
7389
|
+
clearSendFailure,
|
|
6987
7390
|
canSendEditToAgent,
|
|
6988
7391
|
sendEditToAgent: sendEditToAgent2,
|
|
6989
7392
|
sendAllSessionItemsToAgent,
|
|
@@ -7008,6 +7411,8 @@ function DirectEditProvider({ children }) {
|
|
|
7008
7411
|
removeSessionEdit,
|
|
7009
7412
|
startTextEditing,
|
|
7010
7413
|
commitTextEditing,
|
|
7414
|
+
setCommentDraftText,
|
|
7415
|
+
setCommentDraftBlockedHandler,
|
|
7011
7416
|
groupSelection,
|
|
7012
7417
|
deleteSelection,
|
|
7013
7418
|
insertElement,
|
|
@@ -7037,6 +7442,7 @@ function DirectEditProvider({ children }) {
|
|
|
7037
7442
|
updateTypographyProperty,
|
|
7038
7443
|
resetToOriginal,
|
|
7039
7444
|
exportEdits,
|
|
7445
|
+
clearSendFailure,
|
|
7040
7446
|
canSendEditToAgent,
|
|
7041
7447
|
sendEditToAgent2,
|
|
7042
7448
|
sendAllSessionItemsToAgent,
|
|
@@ -7061,6 +7467,8 @@ function DirectEditProvider({ children }) {
|
|
|
7061
7467
|
removeSessionEdit,
|
|
7062
7468
|
startTextEditing,
|
|
7063
7469
|
commitTextEditing,
|
|
7470
|
+
setCommentDraftText,
|
|
7471
|
+
setCommentDraftBlockedHandler,
|
|
7064
7472
|
groupSelection,
|
|
7065
7473
|
deleteSelection,
|
|
7066
7474
|
insertElement,
|
|
@@ -7412,10 +7820,223 @@ function createDragInteractionGuard() {
|
|
|
7412
7820
|
};
|
|
7413
7821
|
}
|
|
7414
7822
|
return {
|
|
7415
|
-
activate,
|
|
7416
|
-
deactivate
|
|
7823
|
+
activate,
|
|
7824
|
+
deactivate
|
|
7825
|
+
};
|
|
7826
|
+
}
|
|
7827
|
+
|
|
7828
|
+
// src/utils/resize-geometry.ts
|
|
7829
|
+
function toFinite(value, fallback) {
|
|
7830
|
+
if (!Number.isFinite(value)) return fallback;
|
|
7831
|
+
return value;
|
|
7832
|
+
}
|
|
7833
|
+
function multiplyMatrix(left, right) {
|
|
7834
|
+
return {
|
|
7835
|
+
a: left.a * right.a + left.c * right.b,
|
|
7836
|
+
b: left.b * right.a + left.d * right.b,
|
|
7837
|
+
c: left.a * right.c + left.c * right.d,
|
|
7838
|
+
d: left.b * right.c + left.d * right.d
|
|
7839
|
+
};
|
|
7840
|
+
}
|
|
7841
|
+
function splitTransformArgs(raw) {
|
|
7842
|
+
return raw.trim().replace(/,/g, " ").split(/\s+/).filter(Boolean);
|
|
7843
|
+
}
|
|
7844
|
+
function parseAngleRadians(value) {
|
|
7845
|
+
const numeric = Number.parseFloat(value);
|
|
7846
|
+
if (!Number.isFinite(numeric)) return 0;
|
|
7847
|
+
const unit = value.trim().replace(String(numeric), "").trim().toLowerCase();
|
|
7848
|
+
switch (unit) {
|
|
7849
|
+
case "rad":
|
|
7850
|
+
return numeric;
|
|
7851
|
+
case "turn":
|
|
7852
|
+
return numeric * Math.PI * 2;
|
|
7853
|
+
case "grad":
|
|
7854
|
+
return numeric * Math.PI / 200;
|
|
7855
|
+
case "deg":
|
|
7856
|
+
case "":
|
|
7857
|
+
default:
|
|
7858
|
+
return numeric * Math.PI / 180;
|
|
7859
|
+
}
|
|
7860
|
+
}
|
|
7861
|
+
function parseTransformFunction(name, rawArgs) {
|
|
7862
|
+
const args = splitTransformArgs(rawArgs);
|
|
7863
|
+
switch (name.toLowerCase()) {
|
|
7864
|
+
case "matrix": {
|
|
7865
|
+
if (args.length < 4) return null;
|
|
7866
|
+
const [a, b, c, d] = args.map(Number.parseFloat);
|
|
7867
|
+
if (![a, b, c, d].every(Number.isFinite)) return null;
|
|
7868
|
+
return { a, b, c, d };
|
|
7869
|
+
}
|
|
7870
|
+
case "matrix3d": {
|
|
7871
|
+
if (args.length < 16) return null;
|
|
7872
|
+
const values = args.map(Number.parseFloat);
|
|
7873
|
+
if (!values.every(Number.isFinite)) return null;
|
|
7874
|
+
return { a: values[0], b: values[1], c: values[4], d: values[5] };
|
|
7875
|
+
}
|
|
7876
|
+
case "scale": {
|
|
7877
|
+
const scaleX = Number.parseFloat(args[0] ?? "1");
|
|
7878
|
+
const scaleY = Number.parseFloat(args[1] ?? args[0] ?? "1");
|
|
7879
|
+
if (!Number.isFinite(scaleX) || !Number.isFinite(scaleY)) return null;
|
|
7880
|
+
return { a: scaleX, b: 0, c: 0, d: scaleY };
|
|
7881
|
+
}
|
|
7882
|
+
case "scalex": {
|
|
7883
|
+
const scaleX = Number.parseFloat(args[0] ?? "1");
|
|
7884
|
+
if (!Number.isFinite(scaleX)) return null;
|
|
7885
|
+
return { a: scaleX, b: 0, c: 0, d: 1 };
|
|
7886
|
+
}
|
|
7887
|
+
case "scaley": {
|
|
7888
|
+
const scaleY = Number.parseFloat(args[0] ?? "1");
|
|
7889
|
+
if (!Number.isFinite(scaleY)) return null;
|
|
7890
|
+
return { a: 1, b: 0, c: 0, d: scaleY };
|
|
7891
|
+
}
|
|
7892
|
+
case "rotate": {
|
|
7893
|
+
const angle = parseAngleRadians(args[0] ?? "0deg");
|
|
7894
|
+
const cos = Math.cos(angle);
|
|
7895
|
+
const sin = Math.sin(angle);
|
|
7896
|
+
return { a: cos, b: sin, c: -sin, d: cos };
|
|
7897
|
+
}
|
|
7898
|
+
case "translate":
|
|
7899
|
+
case "translatex":
|
|
7900
|
+
case "translatey":
|
|
7901
|
+
return { a: 1, b: 0, c: 0, d: 1 };
|
|
7902
|
+
default:
|
|
7903
|
+
return null;
|
|
7904
|
+
}
|
|
7905
|
+
}
|
|
7906
|
+
function parseTransformMatrix(transform) {
|
|
7907
|
+
const functionPattern = /([a-zA-Z0-9]+)\(([^)]*)\)/g;
|
|
7908
|
+
let matrix = { a: 1, b: 0, c: 0, d: 1 };
|
|
7909
|
+
let matched = false;
|
|
7910
|
+
for (const match of transform.matchAll(functionPattern)) {
|
|
7911
|
+
const next = parseTransformFunction(match[1], match[2]);
|
|
7912
|
+
if (!next) return null;
|
|
7913
|
+
matrix = multiplyMatrix(matrix, next);
|
|
7914
|
+
matched = true;
|
|
7915
|
+
}
|
|
7916
|
+
return matched ? matrix : null;
|
|
7917
|
+
}
|
|
7918
|
+
function scaleFromMatrix(matrix) {
|
|
7919
|
+
return {
|
|
7920
|
+
scaleX: Math.hypot(matrix.a, matrix.b) || 1,
|
|
7921
|
+
scaleY: Math.hypot(matrix.c, matrix.d) || 1
|
|
7922
|
+
};
|
|
7923
|
+
}
|
|
7924
|
+
function getRenderedOffsetScale(element) {
|
|
7925
|
+
const rect = element.getBoundingClientRect();
|
|
7926
|
+
const width = element.offsetWidth;
|
|
7927
|
+
const height = element.offsetHeight;
|
|
7928
|
+
if (width <= 0 || height <= 0 || rect.width <= 0 || rect.height <= 0) return null;
|
|
7929
|
+
return {
|
|
7930
|
+
scaleX: rect.width / width,
|
|
7931
|
+
scaleY: rect.height / height
|
|
7932
|
+
};
|
|
7933
|
+
}
|
|
7934
|
+
function clampSize(value, minSize = 1) {
|
|
7935
|
+
const safeMin = Math.max(1, toFinite(minSize, 1));
|
|
7936
|
+
const safeValue = toFinite(value, safeMin);
|
|
7937
|
+
return Math.max(safeMin, safeValue);
|
|
7938
|
+
}
|
|
7939
|
+
function getElementScale(element) {
|
|
7940
|
+
const transform = getComputedStyle(element).transform;
|
|
7941
|
+
if (!transform || transform === "none") {
|
|
7942
|
+
return getRenderedOffsetScale(element) ?? { scaleX: 1, scaleY: 1 };
|
|
7943
|
+
}
|
|
7944
|
+
let transformMatrix = null;
|
|
7945
|
+
if (typeof DOMMatrix !== "undefined") {
|
|
7946
|
+
try {
|
|
7947
|
+
const matrix = new DOMMatrix(transform);
|
|
7948
|
+
transformMatrix = matrix;
|
|
7949
|
+
} catch {
|
|
7950
|
+
}
|
|
7951
|
+
}
|
|
7952
|
+
transformMatrix = transformMatrix ?? parseTransformMatrix(transform);
|
|
7953
|
+
if (!transformMatrix) return getRenderedOffsetScale(element) ?? { scaleX: 1, scaleY: 1 };
|
|
7954
|
+
const localScale = scaleFromMatrix(transformMatrix);
|
|
7955
|
+
const rect = element.getBoundingClientRect();
|
|
7956
|
+
const width = element.offsetWidth;
|
|
7957
|
+
const height = element.offsetHeight;
|
|
7958
|
+
if (width <= 0 || height <= 0 || rect.width <= 0 || rect.height <= 0) return localScale;
|
|
7959
|
+
const transformedWidth = Math.abs(transformMatrix.a) * width + Math.abs(transformMatrix.c) * height;
|
|
7960
|
+
const transformedHeight = Math.abs(transformMatrix.b) * width + Math.abs(transformMatrix.d) * height;
|
|
7961
|
+
if (transformedWidth <= 0 || transformedHeight <= 0) return localScale;
|
|
7962
|
+
return {
|
|
7963
|
+
scaleX: rect.width / transformedWidth * localScale.scaleX,
|
|
7964
|
+
scaleY: rect.height / transformedHeight * localScale.scaleY
|
|
7417
7965
|
};
|
|
7418
7966
|
}
|
|
7967
|
+
function computeEdgeSize({
|
|
7968
|
+
handle,
|
|
7969
|
+
startWidth,
|
|
7970
|
+
startHeight,
|
|
7971
|
+
dx,
|
|
7972
|
+
dy,
|
|
7973
|
+
minSize = 1
|
|
7974
|
+
}) {
|
|
7975
|
+
const baseWidth = clampSize(startWidth, minSize);
|
|
7976
|
+
const baseHeight = clampSize(startHeight, minSize);
|
|
7977
|
+
switch (handle) {
|
|
7978
|
+
case "right":
|
|
7979
|
+
return { width: clampSize(baseWidth + dx, minSize), height: baseHeight };
|
|
7980
|
+
case "left":
|
|
7981
|
+
return { width: clampSize(baseWidth - dx, minSize), height: baseHeight };
|
|
7982
|
+
case "bottom":
|
|
7983
|
+
return { width: baseWidth, height: clampSize(baseHeight + dy, minSize) };
|
|
7984
|
+
case "top":
|
|
7985
|
+
return { width: baseWidth, height: clampSize(baseHeight - dy, minSize) };
|
|
7986
|
+
}
|
|
7987
|
+
}
|
|
7988
|
+
function computeCornerProportionalSize({
|
|
7989
|
+
handle,
|
|
7990
|
+
startWidth,
|
|
7991
|
+
startHeight,
|
|
7992
|
+
dx,
|
|
7993
|
+
dy,
|
|
7994
|
+
minSize = 1
|
|
7995
|
+
}) {
|
|
7996
|
+
const baseWidth = clampSize(startWidth, minSize);
|
|
7997
|
+
const baseHeight = clampSize(startHeight, minSize);
|
|
7998
|
+
const ratio = baseWidth > 0 && baseHeight > 0 ? baseWidth / baseHeight : 1;
|
|
7999
|
+
const widthSign = handle === "top-left" || handle === "bottom-left" ? -1 : 1;
|
|
8000
|
+
const heightSign = handle === "top-left" || handle === "top-right" ? -1 : 1;
|
|
8001
|
+
const rawWidth = baseWidth + widthSign * dx;
|
|
8002
|
+
const rawHeight = baseHeight + heightSign * dy;
|
|
8003
|
+
const widthIntent = clampSize(rawWidth, minSize);
|
|
8004
|
+
const heightIntent = clampSize(rawHeight, minSize);
|
|
8005
|
+
const widthChange = Math.abs(widthIntent - baseWidth) / Math.max(baseWidth, 1);
|
|
8006
|
+
const heightChange = Math.abs(heightIntent - baseHeight) / Math.max(baseHeight, 1);
|
|
8007
|
+
if (widthChange >= heightChange) {
|
|
8008
|
+
const width2 = clampSize(widthIntent, minSize);
|
|
8009
|
+
const height2 = clampSize(width2 / Math.max(ratio, 1e-4), minSize);
|
|
8010
|
+
return { width: width2, height: height2 };
|
|
8011
|
+
}
|
|
8012
|
+
const height = clampSize(heightIntent, minSize);
|
|
8013
|
+
const width = clampSize(height * ratio, minSize);
|
|
8014
|
+
return { width, height };
|
|
8015
|
+
}
|
|
8016
|
+
function computeFillRenderedWidth(element) {
|
|
8017
|
+
const parent = element.parentElement;
|
|
8018
|
+
if (!parent) return null;
|
|
8019
|
+
const parentComputed = window.getComputedStyle(parent);
|
|
8020
|
+
const elementComputed = window.getComputedStyle(element);
|
|
8021
|
+
const parentClientWidth = parent.clientWidth;
|
|
8022
|
+
const parentPaddingLeft = parseFloat(parentComputed.paddingLeft) || 0;
|
|
8023
|
+
const parentPaddingRight = parseFloat(parentComputed.paddingRight) || 0;
|
|
8024
|
+
const parentContentWidth = parentClientWidth - parentPaddingLeft - parentPaddingRight;
|
|
8025
|
+
if (!Number.isFinite(parentContentWidth) || parentContentWidth <= 0) {
|
|
8026
|
+
return null;
|
|
8027
|
+
}
|
|
8028
|
+
const elementPaddingLeft = parseFloat(elementComputed.paddingLeft) || 0;
|
|
8029
|
+
const elementPaddingRight = parseFloat(elementComputed.paddingRight) || 0;
|
|
8030
|
+
const elementBorderLeft = parseFloat(elementComputed.borderLeftWidth) || 0;
|
|
8031
|
+
const elementBorderRight = parseFloat(elementComputed.borderRightWidth) || 0;
|
|
8032
|
+
if (elementComputed.boxSizing === "border-box") {
|
|
8033
|
+
return clampSize(parentContentWidth, 1);
|
|
8034
|
+
}
|
|
8035
|
+
return clampSize(
|
|
8036
|
+
parentContentWidth + elementPaddingLeft + elementPaddingRight + elementBorderLeft + elementBorderRight,
|
|
8037
|
+
1
|
|
8038
|
+
);
|
|
8039
|
+
}
|
|
7419
8040
|
|
|
7420
8041
|
// src/use-move.ts
|
|
7421
8042
|
var INITIAL_DRAG_STATE = {
|
|
@@ -7489,10 +8110,14 @@ function useMove({ onMoveComplete }) {
|
|
|
7489
8110
|
const onMoveCompleteRef = React12.useRef(onMoveComplete);
|
|
7490
8111
|
const dragOptionsRef = React12.useRef(DEFAULT_DRAG_OPTIONS);
|
|
7491
8112
|
const dragGuardRef = React12.useRef(createDragInteractionGuard());
|
|
7492
|
-
const initialRectRef = React12.useRef(
|
|
7493
|
-
|
|
7494
|
-
|
|
8113
|
+
const initialRectRef = React12.useRef({
|
|
8114
|
+
x: 0,
|
|
8115
|
+
y: 0,
|
|
8116
|
+
scaleX: 1,
|
|
8117
|
+
scaleY: 1
|
|
8118
|
+
});
|
|
7495
8119
|
const originalTransformRef = React12.useRef("");
|
|
8120
|
+
const composeBaseRef = React12.useRef("");
|
|
7496
8121
|
const reorderPreviewRef = React12.useRef(/* @__PURE__ */ new Map());
|
|
7497
8122
|
React12.useEffect(() => {
|
|
7498
8123
|
dragStateRef.current = dragState;
|
|
@@ -7506,79 +8131,85 @@ function useMove({ onMoveComplete }) {
|
|
|
7506
8131
|
}
|
|
7507
8132
|
reorderPreviewRef.current.clear();
|
|
7508
8133
|
}, []);
|
|
7509
|
-
const setReorderPreviewTransform = React12.useCallback(
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
8134
|
+
const setReorderPreviewTransform = React12.useCallback(
|
|
8135
|
+
(element, transform) => {
|
|
8136
|
+
const existing = reorderPreviewRef.current.get(element);
|
|
8137
|
+
if (!existing) {
|
|
8138
|
+
reorderPreviewRef.current.set(element, {
|
|
8139
|
+
transform: element.style.transform,
|
|
8140
|
+
transition: element.style.transition
|
|
8141
|
+
});
|
|
8142
|
+
}
|
|
8143
|
+
const originalTransition = reorderPreviewRef.current.get(element)?.transition ?? element.style.transition;
|
|
8144
|
+
element.style.transition = withTransformTransition(originalTransition);
|
|
8145
|
+
element.style.transform = transform;
|
|
8146
|
+
},
|
|
8147
|
+
[]
|
|
8148
|
+
);
|
|
8149
|
+
const applyReorderPreview = React12.useCallback(
|
|
8150
|
+
(target, draggedElement, originalParent) => {
|
|
8151
|
+
if (!target || !draggedElement) {
|
|
8152
|
+
clearReorderPreview();
|
|
8153
|
+
return;
|
|
8154
|
+
}
|
|
8155
|
+
const container = target.container;
|
|
8156
|
+
const containerChildren = Array.from(container.children).filter(
|
|
8157
|
+
(child) => child instanceof HTMLElement
|
|
8158
|
+
);
|
|
8159
|
+
const siblings = containerChildren.filter((child) => child !== draggedElement);
|
|
8160
|
+
const insertIndex = getInsertIndex(siblings, target.insertBefore);
|
|
8161
|
+
if (insertIndex === null) {
|
|
8162
|
+
clearReorderPreview();
|
|
8163
|
+
return;
|
|
8164
|
+
}
|
|
8165
|
+
const draggedRect = draggedElement.getBoundingClientRect();
|
|
8166
|
+
const isHorizontal = isHorizontalDirection(target.flexDirection);
|
|
8167
|
+
const dragSize = isHorizontal ? draggedRect.width : draggedRect.height;
|
|
8168
|
+
if (!Number.isFinite(dragSize) || dragSize <= 0) {
|
|
8169
|
+
clearReorderPreview();
|
|
8170
|
+
return;
|
|
8171
|
+
}
|
|
8172
|
+
const sign = forwardVisualSign(target.flexDirection);
|
|
8173
|
+
const shiftedElements = /* @__PURE__ */ new Map();
|
|
8174
|
+
if (container === originalParent) {
|
|
8175
|
+
const originalIndex = containerChildren.indexOf(draggedElement);
|
|
8176
|
+
if (originalIndex >= 0) {
|
|
8177
|
+
if (insertIndex > originalIndex) {
|
|
8178
|
+
const shift = -sign * dragSize;
|
|
8179
|
+
for (let i = originalIndex; i < insertIndex; i++) {
|
|
8180
|
+
const sibling = siblings[i];
|
|
8181
|
+
if (sibling) shiftedElements.set(sibling, shift);
|
|
8182
|
+
}
|
|
8183
|
+
} else if (insertIndex < originalIndex) {
|
|
8184
|
+
const shift = sign * dragSize;
|
|
8185
|
+
for (let i = insertIndex; i < originalIndex; i++) {
|
|
8186
|
+
const sibling = siblings[i];
|
|
8187
|
+
if (sibling) shiftedElements.set(sibling, shift);
|
|
8188
|
+
}
|
|
7559
8189
|
}
|
|
7560
8190
|
}
|
|
8191
|
+
} else {
|
|
8192
|
+
const shift = sign * dragSize;
|
|
8193
|
+
for (let i = insertIndex; i < siblings.length; i++) {
|
|
8194
|
+
shiftedElements.set(siblings[i], shift);
|
|
8195
|
+
}
|
|
7561
8196
|
}
|
|
7562
|
-
|
|
7563
|
-
const
|
|
7564
|
-
for (
|
|
7565
|
-
|
|
8197
|
+
const axis = isHorizontal ? "x" : "y";
|
|
8198
|
+
const keep = new Set(shiftedElements.keys());
|
|
8199
|
+
for (const [element, snapshot2] of reorderPreviewRef.current) {
|
|
8200
|
+
if (!keep.has(element)) {
|
|
8201
|
+
element.style.transform = snapshot2.transform;
|
|
8202
|
+
element.style.transition = snapshot2.transition;
|
|
8203
|
+
reorderPreviewRef.current.delete(element);
|
|
8204
|
+
}
|
|
7566
8205
|
}
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
for (const [element, snapshot2] of reorderPreviewRef.current) {
|
|
7571
|
-
if (!keep.has(element)) {
|
|
7572
|
-
element.style.transform = snapshot2.transform;
|
|
7573
|
-
element.style.transition = snapshot2.transition;
|
|
7574
|
-
reorderPreviewRef.current.delete(element);
|
|
8206
|
+
for (const [element, shift] of shiftedElements) {
|
|
8207
|
+
const baseTransform = reorderPreviewRef.current.get(element)?.transform ?? element.style.transform;
|
|
8208
|
+
setReorderPreviewTransform(element, withAxisTranslate(baseTransform, axis, shift));
|
|
7575
8209
|
}
|
|
7576
|
-
}
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
setReorderPreviewTransform(element, withAxisTranslate(baseTransform, axis, shift));
|
|
7580
|
-
}
|
|
7581
|
-
}, [clearReorderPreview, setReorderPreviewTransform]);
|
|
8210
|
+
},
|
|
8211
|
+
[clearReorderPreview, setReorderPreviewTransform]
|
|
8212
|
+
);
|
|
7582
8213
|
const cancelDrag = React12.useCallback(() => {
|
|
7583
8214
|
const current = dragStateRef.current;
|
|
7584
8215
|
if (current.draggedElement) {
|
|
@@ -7587,6 +8218,7 @@ function useMove({ onMoveComplete }) {
|
|
|
7587
8218
|
}
|
|
7588
8219
|
clearReorderPreview();
|
|
7589
8220
|
originalTransformRef.current = "";
|
|
8221
|
+
composeBaseRef.current = "";
|
|
7590
8222
|
initialRectRef.current = { x: 0, y: 0, scaleX: 1, scaleY: 1 };
|
|
7591
8223
|
dragOptionsRef.current = DEFAULT_DRAG_OPTIONS;
|
|
7592
8224
|
dragGuardRef.current.deactivate();
|
|
@@ -7608,6 +8240,7 @@ function useMove({ onMoveComplete }) {
|
|
|
7608
8240
|
draggedElement.style.opacity = "";
|
|
7609
8241
|
clearReorderPreview();
|
|
7610
8242
|
originalTransformRef.current = "";
|
|
8243
|
+
composeBaseRef.current = "";
|
|
7611
8244
|
initialRectRef.current = { x: 0, y: 0, scaleX: 1, scaleY: 1 };
|
|
7612
8245
|
const dragMode = dragOptionsRef.current.mode;
|
|
7613
8246
|
dragOptionsRef.current = DEFAULT_DRAG_OPTIONS;
|
|
@@ -7636,7 +8269,13 @@ function useMove({ onMoveComplete }) {
|
|
|
7636
8269
|
const deltaX = (current.ghostPosition.x - rect.left) / scaleX;
|
|
7637
8270
|
const deltaY = (current.ghostPosition.y - rect.top) / scaleY;
|
|
7638
8271
|
if ((Math.abs(deltaX) > 0.5 || Math.abs(deltaY) > 0.5) && originalParent) {
|
|
7639
|
-
moveInfo = {
|
|
8272
|
+
moveInfo = {
|
|
8273
|
+
originalParent,
|
|
8274
|
+
originalPreviousSibling,
|
|
8275
|
+
originalNextSibling,
|
|
8276
|
+
mode: "position",
|
|
8277
|
+
positionDelta: { x: deltaX, y: deltaY }
|
|
8278
|
+
};
|
|
7640
8279
|
}
|
|
7641
8280
|
}
|
|
7642
8281
|
} else if (target && tryReparent(draggedElement, target, originalParent, originalNextSibling)) {
|
|
@@ -7662,13 +8301,21 @@ function useMove({ onMoveComplete }) {
|
|
|
7662
8301
|
const previousSibling = element.previousElementSibling;
|
|
7663
8302
|
const nextSibling = element.nextElementSibling;
|
|
7664
8303
|
dragOptionsRef.current = normalizeStartDragOptions(options);
|
|
8304
|
+
const { scaleX, scaleY } = getElementScale(element);
|
|
7665
8305
|
initialRectRef.current = {
|
|
7666
8306
|
x: rect.left,
|
|
7667
8307
|
y: rect.top,
|
|
7668
|
-
scaleX
|
|
7669
|
-
scaleY
|
|
8308
|
+
scaleX,
|
|
8309
|
+
scaleY
|
|
7670
8310
|
};
|
|
7671
|
-
|
|
8311
|
+
const inlineTransform = element.style.transform;
|
|
8312
|
+
originalTransformRef.current = inlineTransform;
|
|
8313
|
+
if (inlineTransform) {
|
|
8314
|
+
composeBaseRef.current = inlineTransform;
|
|
8315
|
+
} else {
|
|
8316
|
+
const computed = getComputedStyle(element).transform;
|
|
8317
|
+
composeBaseRef.current = computed && computed !== "none" ? computed : "";
|
|
8318
|
+
}
|
|
7672
8319
|
dragGuardRef.current.activate();
|
|
7673
8320
|
setDragState({
|
|
7674
8321
|
isDragging: true,
|
|
@@ -7701,7 +8348,8 @@ function useMove({ onMoveComplete }) {
|
|
|
7701
8348
|
const { x, y, scaleX, scaleY } = initialRectRef.current;
|
|
7702
8349
|
const dx = (e.clientX - dragOffset.x - x) / scaleX;
|
|
7703
8350
|
const dy = (e.clientY - dragOffset.y - y) / scaleY;
|
|
7704
|
-
|
|
8351
|
+
const base = composeBaseRef.current;
|
|
8352
|
+
draggedElement.style.transform = base ? `translate(${dx}px, ${dy}px) ${base}` : `translate(${dx}px, ${dy}px)`;
|
|
7705
8353
|
}
|
|
7706
8354
|
if (dragOptionsRef.current.mode === "position") {
|
|
7707
8355
|
let container2 = findLayoutContainerAtPoint(
|
|
@@ -7742,19 +8390,9 @@ function useMove({ onMoveComplete }) {
|
|
|
7742
8390
|
}
|
|
7743
8391
|
return;
|
|
7744
8392
|
}
|
|
7745
|
-
const container = dragOptionsRef.current.constrainToOriginalParent ? originalParent : findContainerAtPoint(
|
|
7746
|
-
e.clientX,
|
|
7747
|
-
e.clientY,
|
|
7748
|
-
draggedElement,
|
|
7749
|
-
originalParent
|
|
7750
|
-
);
|
|
8393
|
+
const container = dragOptionsRef.current.constrainToOriginalParent ? originalParent : findContainerAtPoint(e.clientX, e.clientY, draggedElement, originalParent);
|
|
7751
8394
|
if (container && draggedElement) {
|
|
7752
|
-
const dropPos = calculateDropPosition(
|
|
7753
|
-
container,
|
|
7754
|
-
e.clientX,
|
|
7755
|
-
e.clientY,
|
|
7756
|
-
draggedElement
|
|
7757
|
-
);
|
|
8395
|
+
const dropPos = calculateDropPosition(container, e.clientX, e.clientY, draggedElement);
|
|
7758
8396
|
if (dropPos) {
|
|
7759
8397
|
const nextTarget = {
|
|
7760
8398
|
container,
|
|
@@ -8127,7 +8765,10 @@ function isSelectableElement(element) {
|
|
|
8127
8765
|
if (!(element instanceof HTMLElement)) return false;
|
|
8128
8766
|
if (!element.isConnected) return false;
|
|
8129
8767
|
if (element === document.body || element === document.documentElement) return false;
|
|
8130
|
-
if (element.matches(
|
|
8768
|
+
if (element.matches(
|
|
8769
|
+
"[data-direct-edit], [data-direct-edit-host], script, style, link, meta, noscript"
|
|
8770
|
+
))
|
|
8771
|
+
return false;
|
|
8131
8772
|
const rect = element.getBoundingClientRect();
|
|
8132
8773
|
if (rect.width <= 0 || rect.height <= 0) return false;
|
|
8133
8774
|
const computed = window.getComputedStyle(element);
|
|
@@ -8145,7 +8786,9 @@ function compareDomOrder2(a, b) {
|
|
|
8145
8786
|
}
|
|
8146
8787
|
function collectMarqueeTargets(rect) {
|
|
8147
8788
|
const hits = Array.from(document.querySelectorAll("*")).filter(isSelectableElement).filter((element) => rectsIntersect(rect, element.getBoundingClientRect()));
|
|
8148
|
-
const deepestHits = hits.filter(
|
|
8789
|
+
const deepestHits = hits.filter(
|
|
8790
|
+
(element) => !hits.some((other) => other !== element && element.contains(other))
|
|
8791
|
+
);
|
|
8149
8792
|
deepestHits.sort(compareDomOrder2);
|
|
8150
8793
|
return deepestHits;
|
|
8151
8794
|
}
|
|
@@ -8568,6 +9211,7 @@ function SelectedCommentComposer({
|
|
|
8568
9211
|
comment,
|
|
8569
9212
|
attentionNonce,
|
|
8570
9213
|
draftRef,
|
|
9214
|
+
onDraftTextChange,
|
|
8571
9215
|
onSubmit,
|
|
8572
9216
|
onCancel
|
|
8573
9217
|
}) {
|
|
@@ -8613,7 +9257,8 @@ function SelectedCommentComposer({
|
|
|
8613
9257
|
}, [attentionNonce]);
|
|
8614
9258
|
React17.useEffect(() => {
|
|
8615
9259
|
if (draftRef) draftRef.current = text;
|
|
8616
|
-
|
|
9260
|
+
onDraftTextChange?.(text);
|
|
9261
|
+
}, [draftRef, onDraftTextChange, text]);
|
|
8617
9262
|
const submit = React17.useCallback(() => {
|
|
8618
9263
|
const nextText = text.trim();
|
|
8619
9264
|
if (!nextText) return;
|
|
@@ -8672,161 +9317,89 @@ function SelectedCommentComposer({
|
|
|
8672
9317
|
} else if (e.key === "Escape") {
|
|
8673
9318
|
onCancel();
|
|
8674
9319
|
}
|
|
8675
|
-
}
|
|
8676
|
-
}
|
|
8677
|
-
),
|
|
8678
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
8679
|
-
Button,
|
|
8680
|
-
{
|
|
8681
|
-
type: "button",
|
|
8682
|
-
variant: "ghost",
|
|
8683
|
-
size: "icon",
|
|
8684
|
-
className: cn(
|
|
8685
|
-
"size-7 shrink-0 self-start",
|
|
8686
|
-
text.trim() ? "bg-blue-500 text-white hover:bg-blue-600" : "bg-muted text-muted-foreground"
|
|
8687
|
-
),
|
|
8688
|
-
disabled: !text.trim(),
|
|
8689
|
-
onClick: submit,
|
|
8690
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react.ArrowUp, {})
|
|
8691
|
-
}
|
|
8692
|
-
)
|
|
8693
|
-
]
|
|
8694
|
-
}
|
|
8695
|
-
);
|
|
8696
|
-
}
|
|
8697
|
-
|
|
8698
|
-
// src/move-overlay.tsx
|
|
8699
|
-
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
8700
|
-
var BLUE2 = "#0D99FF";
|
|
8701
|
-
function MoveOverlay({ dropIndicator }) {
|
|
8702
|
-
if (!dropIndicator) {
|
|
8703
|
-
return null;
|
|
8704
|
-
}
|
|
8705
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
8706
|
-
"svg",
|
|
8707
|
-
{
|
|
8708
|
-
"data-direct-edit": "move-overlay",
|
|
8709
|
-
style: {
|
|
8710
|
-
position: "fixed",
|
|
8711
|
-
inset: 0,
|
|
8712
|
-
width: "100vw",
|
|
8713
|
-
height: "100vh",
|
|
8714
|
-
pointerEvents: "none",
|
|
8715
|
-
zIndex: 99997
|
|
8716
|
-
},
|
|
8717
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
8718
|
-
"rect",
|
|
8719
|
-
{
|
|
8720
|
-
x: dropIndicator.x,
|
|
8721
|
-
y: dropIndicator.y,
|
|
8722
|
-
width: dropIndicator.width,
|
|
8723
|
-
height: dropIndicator.height,
|
|
8724
|
-
fill: BLUE2
|
|
8725
|
-
}
|
|
8726
|
-
)
|
|
8727
|
-
}
|
|
8728
|
-
);
|
|
8729
|
-
}
|
|
8730
|
-
|
|
8731
|
-
// src/selection-overlay.tsx
|
|
8732
|
-
var React19 = __toESM(require("react"));
|
|
8733
|
-
var import_lucide_react2 = require("lucide-react");
|
|
8734
|
-
|
|
8735
|
-
// src/use-selection-resize.ts
|
|
8736
|
-
var React18 = __toESM(require("react"));
|
|
8737
|
-
|
|
8738
|
-
// src/utils/resize-geometry.ts
|
|
8739
|
-
function toFinite(value, fallback) {
|
|
8740
|
-
if (!Number.isFinite(value)) return fallback;
|
|
8741
|
-
return value;
|
|
8742
|
-
}
|
|
8743
|
-
function clampSize(value, minSize = 1) {
|
|
8744
|
-
const safeMin = Math.max(1, toFinite(minSize, 1));
|
|
8745
|
-
const safeValue = toFinite(value, safeMin);
|
|
8746
|
-
return Math.max(safeMin, safeValue);
|
|
8747
|
-
}
|
|
8748
|
-
function computeEdgeSize({
|
|
8749
|
-
handle,
|
|
8750
|
-
startWidth,
|
|
8751
|
-
startHeight,
|
|
8752
|
-
dx,
|
|
8753
|
-
dy,
|
|
8754
|
-
minSize = 1
|
|
8755
|
-
}) {
|
|
8756
|
-
const baseWidth = clampSize(startWidth, minSize);
|
|
8757
|
-
const baseHeight = clampSize(startHeight, minSize);
|
|
8758
|
-
switch (handle) {
|
|
8759
|
-
case "right":
|
|
8760
|
-
return { width: clampSize(baseWidth + dx, minSize), height: baseHeight };
|
|
8761
|
-
case "left":
|
|
8762
|
-
return { width: clampSize(baseWidth - dx, minSize), height: baseHeight };
|
|
8763
|
-
case "bottom":
|
|
8764
|
-
return { width: baseWidth, height: clampSize(baseHeight + dy, minSize) };
|
|
8765
|
-
case "top":
|
|
8766
|
-
return { width: baseWidth, height: clampSize(baseHeight - dy, minSize) };
|
|
8767
|
-
}
|
|
8768
|
-
}
|
|
8769
|
-
function computeCornerProportionalSize({
|
|
8770
|
-
handle,
|
|
8771
|
-
startWidth,
|
|
8772
|
-
startHeight,
|
|
8773
|
-
dx,
|
|
8774
|
-
dy,
|
|
8775
|
-
minSize = 1
|
|
8776
|
-
}) {
|
|
8777
|
-
const baseWidth = clampSize(startWidth, minSize);
|
|
8778
|
-
const baseHeight = clampSize(startHeight, minSize);
|
|
8779
|
-
const ratio = baseWidth > 0 && baseHeight > 0 ? baseWidth / baseHeight : 1;
|
|
8780
|
-
const widthSign = handle === "top-left" || handle === "bottom-left" ? -1 : 1;
|
|
8781
|
-
const heightSign = handle === "top-left" || handle === "top-right" ? -1 : 1;
|
|
8782
|
-
const rawWidth = baseWidth + widthSign * dx;
|
|
8783
|
-
const rawHeight = baseHeight + heightSign * dy;
|
|
8784
|
-
const widthIntent = clampSize(rawWidth, minSize);
|
|
8785
|
-
const heightIntent = clampSize(rawHeight, minSize);
|
|
8786
|
-
const widthChange = Math.abs(widthIntent - baseWidth) / Math.max(baseWidth, 1);
|
|
8787
|
-
const heightChange = Math.abs(heightIntent - baseHeight) / Math.max(baseHeight, 1);
|
|
8788
|
-
if (widthChange >= heightChange) {
|
|
8789
|
-
const width2 = clampSize(widthIntent, minSize);
|
|
8790
|
-
const height2 = clampSize(width2 / Math.max(ratio, 1e-4), minSize);
|
|
8791
|
-
return { width: width2, height: height2 };
|
|
8792
|
-
}
|
|
8793
|
-
const height = clampSize(heightIntent, minSize);
|
|
8794
|
-
const width = clampSize(height * ratio, minSize);
|
|
8795
|
-
return { width, height };
|
|
9320
|
+
}
|
|
9321
|
+
}
|
|
9322
|
+
),
|
|
9323
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
9324
|
+
Button,
|
|
9325
|
+
{
|
|
9326
|
+
type: "button",
|
|
9327
|
+
variant: "ghost",
|
|
9328
|
+
size: "icon",
|
|
9329
|
+
className: cn(
|
|
9330
|
+
"size-7 shrink-0 self-start",
|
|
9331
|
+
text.trim() ? "bg-blue-500 text-white hover:bg-blue-600" : "bg-muted text-muted-foreground"
|
|
9332
|
+
),
|
|
9333
|
+
disabled: !text.trim(),
|
|
9334
|
+
onClick: submit,
|
|
9335
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react.ArrowUp, {})
|
|
9336
|
+
}
|
|
9337
|
+
)
|
|
9338
|
+
]
|
|
9339
|
+
}
|
|
9340
|
+
);
|
|
8796
9341
|
}
|
|
8797
|
-
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
|
|
8803
|
-
const parentPaddingLeft = parseFloat(parentComputed.paddingLeft) || 0;
|
|
8804
|
-
const parentPaddingRight = parseFloat(parentComputed.paddingRight) || 0;
|
|
8805
|
-
const parentContentWidth = parentClientWidth - parentPaddingLeft - parentPaddingRight;
|
|
8806
|
-
if (!Number.isFinite(parentContentWidth) || parentContentWidth <= 0) {
|
|
9342
|
+
|
|
9343
|
+
// src/move-overlay.tsx
|
|
9344
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
9345
|
+
var BLUE2 = "#0D99FF";
|
|
9346
|
+
function MoveOverlay({ dropIndicator }) {
|
|
9347
|
+
if (!dropIndicator) {
|
|
8807
9348
|
return null;
|
|
8808
9349
|
}
|
|
8809
|
-
|
|
8810
|
-
|
|
8811
|
-
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
9350
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
9351
|
+
"svg",
|
|
9352
|
+
{
|
|
9353
|
+
"data-direct-edit": "move-overlay",
|
|
9354
|
+
style: {
|
|
9355
|
+
position: "fixed",
|
|
9356
|
+
inset: 0,
|
|
9357
|
+
width: "100vw",
|
|
9358
|
+
height: "100vh",
|
|
9359
|
+
pointerEvents: "none",
|
|
9360
|
+
zIndex: 99997
|
|
9361
|
+
},
|
|
9362
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
9363
|
+
"rect",
|
|
9364
|
+
{
|
|
9365
|
+
x: dropIndicator.x,
|
|
9366
|
+
y: dropIndicator.y,
|
|
9367
|
+
width: dropIndicator.width,
|
|
9368
|
+
height: dropIndicator.height,
|
|
9369
|
+
fill: BLUE2
|
|
9370
|
+
}
|
|
9371
|
+
)
|
|
9372
|
+
}
|
|
8819
9373
|
);
|
|
8820
9374
|
}
|
|
8821
9375
|
|
|
9376
|
+
// src/selection-overlay.tsx
|
|
9377
|
+
var React19 = __toESM(require("react"));
|
|
9378
|
+
var import_lucide_react2 = require("lucide-react");
|
|
9379
|
+
|
|
8822
9380
|
// src/use-selection-resize.ts
|
|
9381
|
+
var React18 = __toESM(require("react"));
|
|
8823
9382
|
var MIN_SIZE_PX = 1;
|
|
8824
9383
|
var SNAP_IN_PX = 2;
|
|
8825
9384
|
var SNAP_OUT_PX = 6;
|
|
8826
9385
|
var EPSILON = 1e-4;
|
|
8827
9386
|
var EDGE_HANDLES = /* @__PURE__ */ new Set(["top", "right", "bottom", "left"]);
|
|
8828
|
-
var WIDTH_HANDLES = /* @__PURE__ */ new Set([
|
|
8829
|
-
|
|
9387
|
+
var WIDTH_HANDLES = /* @__PURE__ */ new Set([
|
|
9388
|
+
"left",
|
|
9389
|
+
"right",
|
|
9390
|
+
"top-left",
|
|
9391
|
+
"top-right",
|
|
9392
|
+
"bottom-left",
|
|
9393
|
+
"bottom-right"
|
|
9394
|
+
]);
|
|
9395
|
+
var HEIGHT_HANDLES = /* @__PURE__ */ new Set([
|
|
9396
|
+
"top",
|
|
9397
|
+
"bottom",
|
|
9398
|
+
"top-left",
|
|
9399
|
+
"top-right",
|
|
9400
|
+
"bottom-left",
|
|
9401
|
+
"bottom-right"
|
|
9402
|
+
]);
|
|
8830
9403
|
function createSizingValue(mode, numericValue) {
|
|
8831
9404
|
const rounded = Math.max(MIN_SIZE_PX, Math.round(clampSize(numericValue, MIN_SIZE_PX)));
|
|
8832
9405
|
return {
|
|
@@ -8848,125 +9421,135 @@ function useSelectionResize({
|
|
|
8848
9421
|
}) {
|
|
8849
9422
|
const cleanupRef = React18.useRef(null);
|
|
8850
9423
|
const txCounterRef = React18.useRef(0);
|
|
8851
|
-
const emitSizingChange = React18.useCallback(
|
|
8852
|
-
|
|
8853
|
-
|
|
9424
|
+
const emitSizingChange = React18.useCallback(
|
|
9425
|
+
(changes, options) => {
|
|
9426
|
+
onResizeSizingChange?.(changes, options);
|
|
9427
|
+
},
|
|
9428
|
+
[onResizeSizingChange]
|
|
9429
|
+
);
|
|
8854
9430
|
React18.useEffect(() => {
|
|
8855
9431
|
return () => {
|
|
8856
9432
|
cleanupRef.current?.();
|
|
8857
9433
|
cleanupRef.current = null;
|
|
8858
9434
|
};
|
|
8859
9435
|
}, []);
|
|
8860
|
-
const getResizeHandlePointerDown = React18.useCallback(
|
|
8861
|
-
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
|
|
8866
|
-
|
|
8867
|
-
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
transactionId
|
|
8877
|
-
|
|
8878
|
-
|
|
8879
|
-
|
|
8880
|
-
|
|
8881
|
-
|
|
8882
|
-
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
|
|
8888
|
-
|
|
8889
|
-
|
|
8890
|
-
const
|
|
8891
|
-
|
|
8892
|
-
|
|
8893
|
-
|
|
8894
|
-
|
|
8895
|
-
|
|
8896
|
-
|
|
8897
|
-
|
|
8898
|
-
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
8903
|
-
|
|
8904
|
-
|
|
8905
|
-
|
|
8906
|
-
|
|
8907
|
-
|
|
8908
|
-
|
|
8909
|
-
|
|
8910
|
-
|
|
8911
|
-
|
|
8912
|
-
if (state.
|
|
8913
|
-
|
|
8914
|
-
|
|
9436
|
+
const getResizeHandlePointerDown = React18.useCallback(
|
|
9437
|
+
(handle) => {
|
|
9438
|
+
return (e) => {
|
|
9439
|
+
if (!enabled || !onResizeSizingChange) return;
|
|
9440
|
+
if (e.button !== 0) return;
|
|
9441
|
+
e.preventDefault();
|
|
9442
|
+
e.stopPropagation();
|
|
9443
|
+
cleanupRef.current?.();
|
|
9444
|
+
const rect = selectedElement.getBoundingClientRect();
|
|
9445
|
+
const offsetWidth = selectedElement.offsetWidth;
|
|
9446
|
+
const offsetHeight = selectedElement.offsetHeight;
|
|
9447
|
+
const startWidth = clampSize(offsetWidth > 0 ? offsetWidth : rect.width, MIN_SIZE_PX);
|
|
9448
|
+
const startHeight = clampSize(offsetHeight > 0 ? offsetHeight : rect.height, MIN_SIZE_PX);
|
|
9449
|
+
const { scaleX: rawScaleX, scaleY: rawScaleY } = getElementScale(selectedElement);
|
|
9450
|
+
const scaleX = Math.max(EPSILON, rawScaleX);
|
|
9451
|
+
const scaleY = Math.max(EPSILON, rawScaleY);
|
|
9452
|
+
const transactionId = `resize-${Date.now()}-${txCounterRef.current++}`;
|
|
9453
|
+
const state = {
|
|
9454
|
+
transactionId,
|
|
9455
|
+
handle,
|
|
9456
|
+
startClientX: e.clientX,
|
|
9457
|
+
startClientY: e.clientY,
|
|
9458
|
+
startWidth,
|
|
9459
|
+
startHeight,
|
|
9460
|
+
scaleX,
|
|
9461
|
+
scaleY,
|
|
9462
|
+
fillTargetWidth: computeFillRenderedWidth(selectedElement),
|
|
9463
|
+
fillLocked: detectSizingMode(selectedElement, "width") === "fill"
|
|
9464
|
+
};
|
|
9465
|
+
emitSizingChange({}, { transactionId: state.transactionId, phase: "start" });
|
|
9466
|
+
const onPointerMove = (moveEvent) => {
|
|
9467
|
+
const dx = (moveEvent.clientX - state.startClientX) / state.scaleX;
|
|
9468
|
+
const dy = (moveEvent.clientY - state.startClientY) / state.scaleY;
|
|
9469
|
+
const nextSize = isEdgeHandle(state.handle) ? computeEdgeSize({
|
|
9470
|
+
handle: state.handle,
|
|
9471
|
+
startWidth: state.startWidth,
|
|
9472
|
+
startHeight: state.startHeight,
|
|
9473
|
+
dx,
|
|
9474
|
+
dy,
|
|
9475
|
+
minSize: MIN_SIZE_PX
|
|
9476
|
+
}) : computeCornerProportionalSize({
|
|
9477
|
+
handle: state.handle,
|
|
9478
|
+
startWidth: state.startWidth,
|
|
9479
|
+
startHeight: state.startHeight,
|
|
9480
|
+
dx,
|
|
9481
|
+
dy,
|
|
9482
|
+
minSize: MIN_SIZE_PX
|
|
9483
|
+
});
|
|
9484
|
+
const nextWidth = Math.max(MIN_SIZE_PX, Math.round(nextSize.width));
|
|
9485
|
+
const nextHeight = Math.max(MIN_SIZE_PX, Math.round(nextSize.height));
|
|
9486
|
+
const changes = {};
|
|
9487
|
+
if (WIDTH_HANDLES.has(state.handle)) {
|
|
9488
|
+
if (state.fillTargetWidth !== null) {
|
|
9489
|
+
const distance = Math.abs(nextWidth - state.fillTargetWidth);
|
|
9490
|
+
if (state.fillLocked) {
|
|
9491
|
+
if (distance > SNAP_OUT_PX) {
|
|
9492
|
+
state.fillLocked = false;
|
|
9493
|
+
}
|
|
9494
|
+
} else if (distance <= SNAP_IN_PX) {
|
|
9495
|
+
state.fillLocked = true;
|
|
8915
9496
|
}
|
|
8916
|
-
} else
|
|
8917
|
-
state.fillLocked =
|
|
9497
|
+
} else {
|
|
9498
|
+
state.fillLocked = false;
|
|
9499
|
+
}
|
|
9500
|
+
if (state.fillLocked) {
|
|
9501
|
+
const fillWidth = state.fillTargetWidth ?? nextWidth;
|
|
9502
|
+
changes.width = createSizingValue("fill", fillWidth);
|
|
9503
|
+
} else {
|
|
9504
|
+
changes.width = createSizingValue("fixed", nextWidth);
|
|
8918
9505
|
}
|
|
8919
|
-
} else {
|
|
8920
|
-
state.fillLocked = false;
|
|
8921
9506
|
}
|
|
8922
|
-
if (state.
|
|
8923
|
-
|
|
8924
|
-
changes.width = createSizingValue("fill", fillWidth);
|
|
8925
|
-
} else {
|
|
8926
|
-
changes.width = createSizingValue("fixed", nextWidth);
|
|
9507
|
+
if (HEIGHT_HANDLES.has(state.handle)) {
|
|
9508
|
+
changes.height = createSizingValue("fixed", nextHeight);
|
|
8927
9509
|
}
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
8931
|
-
|
|
8932
|
-
|
|
8933
|
-
|
|
9510
|
+
if (Object.keys(changes).length === 0) return;
|
|
9511
|
+
emitSizingChange(changes, { transactionId: state.transactionId, phase: "update" });
|
|
9512
|
+
};
|
|
9513
|
+
const stop = () => {
|
|
9514
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
9515
|
+
window.removeEventListener("pointerup", stop);
|
|
9516
|
+
window.removeEventListener("pointercancel", stop);
|
|
9517
|
+
window.removeEventListener("blur", stop);
|
|
9518
|
+
cleanupRef.current = null;
|
|
9519
|
+
emitSizingChange({}, { transactionId: state.transactionId, phase: "end" });
|
|
9520
|
+
};
|
|
9521
|
+
cleanupRef.current = stop;
|
|
9522
|
+
window.addEventListener("pointermove", onPointerMove);
|
|
9523
|
+
window.addEventListener("pointerup", stop);
|
|
9524
|
+
window.addEventListener("pointercancel", stop);
|
|
9525
|
+
window.addEventListener("blur", stop);
|
|
8934
9526
|
};
|
|
8935
|
-
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
9527
|
+
},
|
|
9528
|
+
[emitSizingChange, enabled, onResizeSizingChange, selectedElement]
|
|
9529
|
+
);
|
|
9530
|
+
const getResizeHandleDoubleClick = React18.useCallback(
|
|
9531
|
+
(handle) => {
|
|
9532
|
+
return (e) => {
|
|
9533
|
+
if (!enabled || !onResizeSizingChange) return;
|
|
9534
|
+
if (!isEdgeHandle(handle)) return;
|
|
9535
|
+
const hasElementChildren = selectedElement.children.length > 0;
|
|
9536
|
+
const hasTextContent = Boolean(selectedElement.textContent?.trim());
|
|
9537
|
+
const isEligibleElement = hasElementChildren || hasTextContent;
|
|
9538
|
+
if (!isEligibleElement) return;
|
|
9539
|
+
e.preventDefault();
|
|
9540
|
+
e.stopPropagation();
|
|
9541
|
+
const rect = selectedElement.getBoundingClientRect();
|
|
9542
|
+
const width = Math.max(MIN_SIZE_PX, Math.round(rect.width));
|
|
9543
|
+
const height = Math.max(MIN_SIZE_PX, Math.round(rect.height));
|
|
9544
|
+
if (handle === "left" || handle === "right") {
|
|
9545
|
+
emitSizingChange({ width: createSizingValue("fit", width) });
|
|
9546
|
+
} else {
|
|
9547
|
+
emitSizingChange({ height: createSizingValue("fit", height) });
|
|
9548
|
+
}
|
|
8942
9549
|
};
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
window.addEventListener("pointercancel", stop);
|
|
8947
|
-
window.addEventListener("blur", stop);
|
|
8948
|
-
};
|
|
8949
|
-
}, [emitSizingChange, enabled, onResizeSizingChange, selectedElement]);
|
|
8950
|
-
const getResizeHandleDoubleClick = React18.useCallback((handle) => {
|
|
8951
|
-
return (e) => {
|
|
8952
|
-
if (!enabled || !onResizeSizingChange) return;
|
|
8953
|
-
if (!isEdgeHandle(handle)) return;
|
|
8954
|
-
const hasElementChildren = selectedElement.children.length > 0;
|
|
8955
|
-
const hasTextContent = Boolean(selectedElement.textContent?.trim());
|
|
8956
|
-
const isEligibleElement = hasElementChildren || hasTextContent;
|
|
8957
|
-
if (!isEligibleElement) return;
|
|
8958
|
-
e.preventDefault();
|
|
8959
|
-
e.stopPropagation();
|
|
8960
|
-
const rect = selectedElement.getBoundingClientRect();
|
|
8961
|
-
const width = Math.max(MIN_SIZE_PX, Math.round(rect.width));
|
|
8962
|
-
const height = Math.max(MIN_SIZE_PX, Math.round(rect.height));
|
|
8963
|
-
if (handle === "left" || handle === "right") {
|
|
8964
|
-
emitSizingChange({ width: createSizingValue("fit", width) });
|
|
8965
|
-
} else {
|
|
8966
|
-
emitSizingChange({ height: createSizingValue("fit", height) });
|
|
8967
|
-
}
|
|
8968
|
-
};
|
|
8969
|
-
}, [emitSizingChange, enabled, onResizeSizingChange, selectedElement]);
|
|
9550
|
+
},
|
|
9551
|
+
[emitSizingChange, enabled, onResizeSizingChange, selectedElement]
|
|
9552
|
+
);
|
|
8970
9553
|
return {
|
|
8971
9554
|
getResizeHandlePointerDown,
|
|
8972
9555
|
getResizeHandleDoubleClick
|
|
@@ -9591,17 +10174,20 @@ function getGroupBounds(rects) {
|
|
|
9591
10174
|
if (rects.length === 0) {
|
|
9592
10175
|
return { left: 0, top: 0, right: 0, bottom: 0 };
|
|
9593
10176
|
}
|
|
9594
|
-
return rects.reduce(
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
10177
|
+
return rects.reduce(
|
|
10178
|
+
(bounds, rect) => ({
|
|
10179
|
+
left: Math.min(bounds.left, rect.left),
|
|
10180
|
+
top: Math.min(bounds.top, rect.top),
|
|
10181
|
+
right: Math.max(bounds.right, rect.right),
|
|
10182
|
+
bottom: Math.max(bounds.bottom, rect.bottom)
|
|
10183
|
+
}),
|
|
10184
|
+
{
|
|
10185
|
+
left: rects[0].left,
|
|
10186
|
+
top: rects[0].top,
|
|
10187
|
+
right: rects[0].right,
|
|
10188
|
+
bottom: rects[0].bottom
|
|
10189
|
+
}
|
|
10190
|
+
);
|
|
9605
10191
|
}
|
|
9606
10192
|
function MultiSelectionOverlay({ selectedElements }) {
|
|
9607
10193
|
const elements = React20.useMemo(
|
|
@@ -9610,10 +10196,12 @@ function MultiSelectionOverlay({ selectedElements }) {
|
|
|
9610
10196
|
);
|
|
9611
10197
|
const [selectionRects, setSelectionRects] = React20.useState([]);
|
|
9612
10198
|
const updateRects = React20.useCallback(() => {
|
|
9613
|
-
setSelectionRects(
|
|
9614
|
-
element
|
|
9615
|
-
|
|
9616
|
-
|
|
10199
|
+
setSelectionRects(
|
|
10200
|
+
elements.map((element) => ({
|
|
10201
|
+
element,
|
|
10202
|
+
rect: element.getBoundingClientRect()
|
|
10203
|
+
}))
|
|
10204
|
+
);
|
|
9617
10205
|
}, [elements]);
|
|
9618
10206
|
React20.useLayoutEffect(() => {
|
|
9619
10207
|
updateRects();
|
|
@@ -11968,6 +12556,7 @@ function PanelFooter({
|
|
|
11968
12556
|
onExportEdits,
|
|
11969
12557
|
onSendToAgent,
|
|
11970
12558
|
showSendButton = true,
|
|
12559
|
+
sendFailureReason,
|
|
11971
12560
|
onPointerDown,
|
|
11972
12561
|
onPointerMove,
|
|
11973
12562
|
onPointerUp,
|
|
@@ -11976,6 +12565,13 @@ function PanelFooter({
|
|
|
11976
12565
|
const [copied, setCopied] = React30.useState(false);
|
|
11977
12566
|
const [copyError, setCopyError] = React30.useState(false);
|
|
11978
12567
|
const [sendStatus, setSendStatus] = React30.useState("idle");
|
|
12568
|
+
const prevCanTriggerSendRef = React30.useRef(canTriggerSend);
|
|
12569
|
+
React30.useEffect(() => {
|
|
12570
|
+
if (prevCanTriggerSendRef.current !== canTriggerSend) {
|
|
12571
|
+
prevCanTriggerSendRef.current = canTriggerSend;
|
|
12572
|
+
setSendStatus("idle");
|
|
12573
|
+
}
|
|
12574
|
+
}, [canTriggerSend]);
|
|
11979
12575
|
const handleCopy = async () => {
|
|
11980
12576
|
if (!onExportEdits) return;
|
|
11981
12577
|
const success = await onExportEdits();
|
|
@@ -11989,6 +12585,7 @@ function PanelFooter({
|
|
|
11989
12585
|
setCopyError(true);
|
|
11990
12586
|
setTimeout(() => setCopyError(false), 2e3);
|
|
11991
12587
|
};
|
|
12588
|
+
const sendTooltipLabel = sendStatus === "offline" ? sendFailureReason === "unreachable" ? "Agent unreachable \u2014 click to retry" : "Agent rejected the edit \u2014 click to retry" : "Apply changes via agent";
|
|
11992
12589
|
const handleSendToAgent = async () => {
|
|
11993
12590
|
if (!onSendToAgent || sendStatus === "sending") return;
|
|
11994
12591
|
setSendStatus("sending");
|
|
@@ -11998,7 +12595,6 @@ function PanelFooter({
|
|
|
11998
12595
|
setTimeout(() => setSendStatus("idle"), 2e3);
|
|
11999
12596
|
} else {
|
|
12000
12597
|
setSendStatus("offline");
|
|
12001
|
-
setTimeout(() => setSendStatus("idle"), 2e3);
|
|
12002
12598
|
}
|
|
12003
12599
|
};
|
|
12004
12600
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
@@ -12026,7 +12622,7 @@ function PanelFooter({
|
|
|
12026
12622
|
children: copyError ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.X, { className: "text-red-500" }) : copied ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Check, { className: "text-green-500" }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Copy, {})
|
|
12027
12623
|
}
|
|
12028
12624
|
) }),
|
|
12029
|
-
showSendButton && onSendToAgent && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: !canTriggerSend || sendStatus === "sending" ? "cursor-not-allowed" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Tip, { label:
|
|
12625
|
+
showSendButton && onSendToAgent && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: !canTriggerSend || sendStatus === "sending" ? "cursor-not-allowed" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Tip, { label: sendTooltipLabel, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
12030
12626
|
Button,
|
|
12031
12627
|
{
|
|
12032
12628
|
variant: "outline",
|
|
@@ -12721,6 +13317,7 @@ function DirectEditPanelInner({
|
|
|
12721
13317
|
onSendToAgent,
|
|
12722
13318
|
canSendToAgent = false,
|
|
12723
13319
|
showSendButton = true,
|
|
13320
|
+
sendFailureReason,
|
|
12724
13321
|
className,
|
|
12725
13322
|
style,
|
|
12726
13323
|
panelRef,
|
|
@@ -12783,89 +13380,91 @@ function DirectEditPanelInner({
|
|
|
12783
13380
|
sectionRefs
|
|
12784
13381
|
}
|
|
12785
13382
|
),
|
|
12786
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
12787
|
-
|
|
12788
|
-
|
|
12789
|
-
|
|
12790
|
-
|
|
12791
|
-
|
|
12792
|
-
|
|
12793
|
-
|
|
12794
|
-
|
|
12795
|
-
|
|
12796
|
-
|
|
12797
|
-
|
|
12798
|
-
|
|
12799
|
-
|
|
12800
|
-
|
|
12801
|
-
|
|
12802
|
-
|
|
12803
|
-
|
|
12804
|
-
|
|
12805
|
-
|
|
12806
|
-
|
|
12807
|
-
|
|
12808
|
-
|
|
12809
|
-
|
|
12810
|
-
|
|
12811
|
-
|
|
12812
|
-
|
|
12813
|
-
|
|
12814
|
-
|
|
12815
|
-
|
|
12816
|
-
|
|
12817
|
-
|
|
12818
|
-
|
|
12819
|
-
|
|
12820
|
-
|
|
12821
|
-
|
|
12822
|
-
|
|
12823
|
-
|
|
12824
|
-
|
|
12825
|
-
|
|
12826
|
-
|
|
12827
|
-
|
|
12828
|
-
|
|
12829
|
-
|
|
12830
|
-
|
|
12831
|
-
|
|
12832
|
-
|
|
12833
|
-
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
|
|
12837
|
-
|
|
12838
|
-
|
|
12839
|
-
|
|
12840
|
-
|
|
12841
|
-
|
|
12842
|
-
|
|
12843
|
-
|
|
12844
|
-
|
|
12845
|
-
|
|
12846
|
-
|
|
12847
|
-
|
|
12848
|
-
|
|
12849
|
-
|
|
12850
|
-
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
|
|
12860
|
-
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
12864
|
-
|
|
12865
|
-
|
|
12866
|
-
|
|
12867
|
-
|
|
12868
|
-
|
|
13383
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
13384
|
+
"div",
|
|
13385
|
+
{
|
|
13386
|
+
className: "flex-1 overflow-y-auto backdrop-blur-xl bg-background/85",
|
|
13387
|
+
ref: scrollRef,
|
|
13388
|
+
onWheelCapture: (e) => e.stopPropagation(),
|
|
13389
|
+
children: [
|
|
13390
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
13391
|
+
LayoutSection,
|
|
13392
|
+
{
|
|
13393
|
+
elementInfo,
|
|
13394
|
+
computedFlex,
|
|
13395
|
+
computedSpacing,
|
|
13396
|
+
computedSizing,
|
|
13397
|
+
onToggleFlex,
|
|
13398
|
+
onUpdateFlex,
|
|
13399
|
+
onUpdateSpacing,
|
|
13400
|
+
onUpdateSizing,
|
|
13401
|
+
sectionRef: sectionRefs.layout
|
|
13402
|
+
}
|
|
13403
|
+
),
|
|
13404
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { ref: sectionRefs.radius, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(CollapsibleSection, { title: "Radius", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
13405
|
+
BorderRadiusInputs,
|
|
13406
|
+
{
|
|
13407
|
+
values: {
|
|
13408
|
+
topLeft: computedBorderRadius.borderTopLeftRadius,
|
|
13409
|
+
topRight: computedBorderRadius.borderTopRightRadius,
|
|
13410
|
+
bottomRight: computedBorderRadius.borderBottomRightRadius,
|
|
13411
|
+
bottomLeft: computedBorderRadius.borderBottomLeftRadius
|
|
13412
|
+
},
|
|
13413
|
+
onChange: onUpdateBorderRadius
|
|
13414
|
+
}
|
|
13415
|
+
) }) }),
|
|
13416
|
+
computedColor && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { ref: sectionRefs.fill, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
13417
|
+
BackgroundFillSection,
|
|
13418
|
+
{
|
|
13419
|
+
backgroundColor: computedColor.backgroundColor,
|
|
13420
|
+
onSetCSS,
|
|
13421
|
+
pendingStyles
|
|
13422
|
+
}
|
|
13423
|
+
) }),
|
|
13424
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { ref: sectionRefs.border, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
13425
|
+
BorderSection,
|
|
13426
|
+
{
|
|
13427
|
+
border: computedBorder,
|
|
13428
|
+
borderColor: computedColor?.borderColor,
|
|
13429
|
+
outlineColor: computedColor?.outlineColor,
|
|
13430
|
+
borderStyleControlPreference,
|
|
13431
|
+
onChange: onUpdateBorder,
|
|
13432
|
+
onBatchChange: onBatchUpdateBorder,
|
|
13433
|
+
onBorderColorChange: (value) => onUpdateColor("borderColor", value),
|
|
13434
|
+
onOutlineColorChange: (value) => onUpdateColor("outlineColor", value),
|
|
13435
|
+
onSetCSS,
|
|
13436
|
+
pendingStyles
|
|
13437
|
+
}
|
|
13438
|
+
) }),
|
|
13439
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { ref: sectionRefs.shadow, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
13440
|
+
ShadowSection,
|
|
13441
|
+
{
|
|
13442
|
+
boxShadow: computedBoxShadow,
|
|
13443
|
+
onSetCSS,
|
|
13444
|
+
pendingStyles
|
|
13445
|
+
}
|
|
13446
|
+
) }),
|
|
13447
|
+
elementInfo.isTextElement && computedTypography && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { ref: sectionRefs.text, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(CollapsibleSection, { title: "Text", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TypographyInputs, { typography: computedTypography, onUpdate: onUpdateTypography }) }) }),
|
|
13448
|
+
computedColor && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { ref: sectionRefs.colors, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(CollapsibleSection, { title: "Selection colors", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
13449
|
+
FillSection,
|
|
13450
|
+
{
|
|
13451
|
+
textColor: computedColor.color,
|
|
13452
|
+
borderColor: computedColor.borderColor,
|
|
13453
|
+
outlineColor: computedColor.outlineColor,
|
|
13454
|
+
selectionColors,
|
|
13455
|
+
onTextChange: (value) => onUpdateColor("color", value),
|
|
13456
|
+
onBorderColorChange: (value) => onUpdateColor("borderColor", value),
|
|
13457
|
+
onOutlineColorChange: (value) => onUpdateColor("outlineColor", value),
|
|
13458
|
+
onSelectionColorChange: onReplaceSelectionColor,
|
|
13459
|
+
onSelectionColorTarget: onSelectSelectionColorTarget,
|
|
13460
|
+
hasTextContent: elementInfo.isTextElement,
|
|
13461
|
+
showBorderColor: computedColor.borderColor.alpha > 0,
|
|
13462
|
+
showOutlineColor: computedColor.outlineColor.alpha > 0
|
|
13463
|
+
}
|
|
13464
|
+
) }) })
|
|
13465
|
+
]
|
|
13466
|
+
}
|
|
13467
|
+
),
|
|
12869
13468
|
(onExportEdits || showSendButton && onSendToAgent) && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
12870
13469
|
PanelFooter,
|
|
12871
13470
|
{
|
|
@@ -12874,6 +13473,7 @@ function DirectEditPanelInner({
|
|
|
12874
13473
|
onExportEdits,
|
|
12875
13474
|
onSendToAgent,
|
|
12876
13475
|
showSendButton,
|
|
13476
|
+
sendFailureReason,
|
|
12877
13477
|
onPointerDown: onHeaderPointerDown,
|
|
12878
13478
|
onPointerMove: onHeaderPointerMove,
|
|
12879
13479
|
onPointerUp: onHeaderPointerUp,
|
|
@@ -12908,7 +13508,8 @@ function DirectEditPanelContent() {
|
|
|
12908
13508
|
comments,
|
|
12909
13509
|
activeCommentId,
|
|
12910
13510
|
textEditingElement,
|
|
12911
|
-
agentAvailable
|
|
13511
|
+
agentAvailable,
|
|
13512
|
+
lastSendFailure
|
|
12912
13513
|
} = useDirectEditState();
|
|
12913
13514
|
const {
|
|
12914
13515
|
selectParent,
|
|
@@ -12936,11 +13537,15 @@ function DirectEditPanelContent() {
|
|
|
12936
13537
|
addCommentReply,
|
|
12937
13538
|
deleteComment,
|
|
12938
13539
|
exportComment,
|
|
13540
|
+
exportEdits,
|
|
13541
|
+
sendEditToAgent: sendEditToAgent2,
|
|
12939
13542
|
sendCommentToAgent: sendCommentToAgent2,
|
|
12940
13543
|
setActiveCommentId,
|
|
12941
13544
|
startTextEditing,
|
|
12942
13545
|
toggleEditMode,
|
|
12943
|
-
deleteSelection
|
|
13546
|
+
deleteSelection,
|
|
13547
|
+
setCommentDraftText,
|
|
13548
|
+
setCommentDraftBlockedHandler
|
|
12944
13549
|
} = useDirectEditActions();
|
|
12945
13550
|
const {
|
|
12946
13551
|
position,
|
|
@@ -12962,46 +13567,67 @@ function DirectEditPanelContent() {
|
|
|
12962
13567
|
});
|
|
12963
13568
|
React34.useEffect(() => {
|
|
12964
13569
|
commentDraftRef.current = "";
|
|
12965
|
-
|
|
13570
|
+
setCommentDraftText("");
|
|
13571
|
+
}, [activeCommentId, setCommentDraftText]);
|
|
12966
13572
|
const activeDraftComment = React34.useMemo(() => {
|
|
12967
13573
|
if (!commentTargetElement || !activeCommentId) return null;
|
|
12968
13574
|
const active = comments.find((comment) => comment.id === activeCommentId);
|
|
12969
|
-
if (!active || active.text.trim().length > 0 || active.element !== commentTargetElement)
|
|
13575
|
+
if (!active || active.text.trim().length > 0 || active.element !== commentTargetElement)
|
|
13576
|
+
return null;
|
|
12970
13577
|
return active;
|
|
12971
13578
|
}, [activeCommentId, commentTargetElement, comments]);
|
|
12972
|
-
const { isActive: measurementActive, hoveredElement, measurements, mousePosition } = useMeasurement(
|
|
12973
|
-
isOpen ? selectedElement : null
|
|
12974
|
-
);
|
|
12975
13579
|
const {
|
|
12976
|
-
|
|
12977
|
-
|
|
12978
|
-
|
|
12979
|
-
|
|
13580
|
+
isActive: measurementActive,
|
|
13581
|
+
hoveredElement,
|
|
13582
|
+
measurements,
|
|
13583
|
+
mousePosition
|
|
13584
|
+
} = useMeasurement(isOpen ? selectedElement : null);
|
|
13585
|
+
const { dragState, dropIndicator, startDrag } = useMove({
|
|
12980
13586
|
onMoveComplete: handleMoveComplete
|
|
12981
13587
|
});
|
|
12982
13588
|
const triggerCommentInputAttention = React34.useCallback((commentId) => {
|
|
12983
|
-
setCommentInputAttention(
|
|
13589
|
+
setCommentInputAttention(
|
|
13590
|
+
(prev) => prev?.commentId === commentId ? { commentId, nonce: prev.nonce + 1 } : { commentId, nonce: 1 }
|
|
13591
|
+
);
|
|
12984
13592
|
}, []);
|
|
12985
|
-
|
|
12986
|
-
if (!activeCommentId)
|
|
12987
|
-
|
|
12988
|
-
|
|
12989
|
-
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
return
|
|
12994
|
-
|
|
12995
|
-
|
|
12996
|
-
|
|
12997
|
-
|
|
13593
|
+
React34.useEffect(() => {
|
|
13594
|
+
if (!activeCommentId) {
|
|
13595
|
+
setCommentDraftBlockedHandler(null);
|
|
13596
|
+
return;
|
|
13597
|
+
}
|
|
13598
|
+
setCommentDraftBlockedHandler(() => {
|
|
13599
|
+
triggerCommentInputAttention(activeCommentId);
|
|
13600
|
+
});
|
|
13601
|
+
return () => {
|
|
13602
|
+
setCommentDraftBlockedHandler(null);
|
|
13603
|
+
};
|
|
13604
|
+
}, [activeCommentId, setCommentDraftBlockedHandler, triggerCommentInputAttention]);
|
|
13605
|
+
const hasPendingCommentDraft = React34.useCallback(
|
|
13606
|
+
(nextCommentId = null) => {
|
|
13607
|
+
if (!activeCommentId) return false;
|
|
13608
|
+
if (nextCommentId && nextCommentId === activeCommentId) return false;
|
|
12998
13609
|
const active = comments.find((comment) => comment.id === activeCommentId);
|
|
12999
|
-
if (active
|
|
13000
|
-
|
|
13610
|
+
if (!active) return false;
|
|
13611
|
+
const hasUnsentDraft = active.text.trim().length === 0 && commentDraftRef.current.trim().length > 0;
|
|
13612
|
+
if (!hasUnsentDraft) return false;
|
|
13613
|
+
triggerCommentInputAttention(active.id);
|
|
13614
|
+
return true;
|
|
13615
|
+
},
|
|
13616
|
+
[activeCommentId, comments, triggerCommentInputAttention]
|
|
13617
|
+
);
|
|
13618
|
+
const handleSetActiveComment = React34.useCallback(
|
|
13619
|
+
(id) => {
|
|
13620
|
+
if (hasPendingCommentDraft(id)) return;
|
|
13621
|
+
if (activeCommentId && activeCommentId !== id) {
|
|
13622
|
+
const active = comments.find((comment) => comment.id === activeCommentId);
|
|
13623
|
+
if (active && active.text.trim().length === 0) {
|
|
13624
|
+
deleteComment(active.id);
|
|
13625
|
+
}
|
|
13001
13626
|
}
|
|
13002
|
-
|
|
13003
|
-
|
|
13004
|
-
|
|
13627
|
+
setActiveCommentId(id);
|
|
13628
|
+
},
|
|
13629
|
+
[activeCommentId, comments, hasPendingCommentDraft, deleteComment, setActiveCommentId]
|
|
13630
|
+
);
|
|
13005
13631
|
const handleCommentPillClick = React34.useCallback(() => {
|
|
13006
13632
|
if (activeDraftComment) {
|
|
13007
13633
|
handleSetActiveComment(null);
|
|
@@ -13009,13 +13635,23 @@ function DirectEditPanelContent() {
|
|
|
13009
13635
|
}
|
|
13010
13636
|
if (hasPendingCommentDraft()) return;
|
|
13011
13637
|
if (!commentTargetElement) return;
|
|
13012
|
-
const existingDraft = comments.find(
|
|
13638
|
+
const existingDraft = comments.find(
|
|
13639
|
+
(comment) => comment.element === commentTargetElement && comment.text.trim().length === 0
|
|
13640
|
+
);
|
|
13013
13641
|
if (existingDraft) {
|
|
13014
13642
|
setActiveCommentId(existingDraft.id);
|
|
13015
13643
|
return;
|
|
13016
13644
|
}
|
|
13017
13645
|
addComment(commentTargetElement, getElementCommentAnchor(commentTargetElement));
|
|
13018
|
-
}, [
|
|
13646
|
+
}, [
|
|
13647
|
+
activeDraftComment,
|
|
13648
|
+
handleSetActiveComment,
|
|
13649
|
+
hasPendingCommentDraft,
|
|
13650
|
+
commentTargetElement,
|
|
13651
|
+
comments,
|
|
13652
|
+
setActiveCommentId,
|
|
13653
|
+
addComment
|
|
13654
|
+
]);
|
|
13019
13655
|
React34.useEffect(() => {
|
|
13020
13656
|
const previous = previousCommentTriggerRef.current;
|
|
13021
13657
|
previousCommentTriggerRef.current = { editModeActive, commentTargetElement };
|
|
@@ -13091,6 +13727,7 @@ function DirectEditPanelContent() {
|
|
|
13091
13727
|
comment: activeDraftComment,
|
|
13092
13728
|
attentionNonce: commentInputAttention?.commentId === activeDraftComment.id ? commentInputAttention.nonce : 0,
|
|
13093
13729
|
draftRef: commentDraftRef,
|
|
13730
|
+
onDraftTextChange: setCommentDraftText,
|
|
13094
13731
|
onSubmit: (text) => submitCommentDraft(activeDraftComment.id, text),
|
|
13095
13732
|
onCancel: () => handleSetActiveComment(null)
|
|
13096
13733
|
}
|
|
@@ -13111,58 +13748,81 @@ function DirectEditPanelContent() {
|
|
|
13111
13748
|
if (pageTitle.length > 0) return pageTitle;
|
|
13112
13749
|
return getElementDisplayName(pageFrameElement);
|
|
13113
13750
|
}, [pageFrameElement]);
|
|
13114
|
-
const handleSelectSelectionColorTarget = React34.useCallback(
|
|
13115
|
-
|
|
13116
|
-
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13121
|
-
|
|
13122
|
-
const
|
|
13123
|
-
|
|
13124
|
-
|
|
13125
|
-
|
|
13126
|
-
|
|
13127
|
-
|
|
13128
|
-
const currentTextColor = computed.color;
|
|
13129
|
-
const matches = (raw, fallback) => {
|
|
13130
|
-
const parsed = parseVisibleColor3(raw, fallback);
|
|
13131
|
-
return Boolean(parsed && toKey(parsed) === targetKey);
|
|
13751
|
+
const handleSelectSelectionColorTarget = React34.useCallback(
|
|
13752
|
+
(targetColor) => {
|
|
13753
|
+
if (!selectedElement) return;
|
|
13754
|
+
const toKey = (color) => `${color.hex.toUpperCase()}:${Math.round(color.alpha)}`;
|
|
13755
|
+
const targetKey = toKey(targetColor);
|
|
13756
|
+
const hasOwnText2 = (node) => Array.from(node.childNodes).some(
|
|
13757
|
+
(child) => child.nodeType === Node.TEXT_NODE && (child.textContent ?? "").trim().length > 0
|
|
13758
|
+
);
|
|
13759
|
+
const parseVisibleColor3 = (raw, fallbackCurrentColor) => {
|
|
13760
|
+
const trimmed = raw.trim();
|
|
13761
|
+
if (!trimmed || trimmed === "none" || trimmed === "transparent") return null;
|
|
13762
|
+
const resolved = trimmed.toLowerCase() === "currentcolor" ? fallbackCurrentColor ?? trimmed : trimmed;
|
|
13763
|
+
const parsed = parseColorValue(resolved);
|
|
13764
|
+
return parsed.alpha > 0 ? parsed : null;
|
|
13132
13765
|
};
|
|
13133
|
-
|
|
13134
|
-
|
|
13135
|
-
|
|
13136
|
-
|
|
13137
|
-
|
|
13138
|
-
|
|
13139
|
-
|
|
13140
|
-
|
|
13141
|
-
|
|
13142
|
-
|
|
13766
|
+
const hasMatchingColor = (node) => {
|
|
13767
|
+
const computed = window.getComputedStyle(node);
|
|
13768
|
+
const currentTextColor = computed.color;
|
|
13769
|
+
const matches = (raw, fallback) => {
|
|
13770
|
+
const parsed = parseVisibleColor3(raw, fallback);
|
|
13771
|
+
return Boolean(parsed && toKey(parsed) === targetKey);
|
|
13772
|
+
};
|
|
13773
|
+
if (matches(computed.backgroundColor)) return true;
|
|
13774
|
+
if (hasOwnText2(node) && matches(currentTextColor)) return true;
|
|
13775
|
+
const borderSides = [
|
|
13776
|
+
{
|
|
13777
|
+
style: computed.borderTopStyle,
|
|
13778
|
+
width: computed.borderTopWidth,
|
|
13779
|
+
color: computed.borderTopColor
|
|
13780
|
+
},
|
|
13781
|
+
{
|
|
13782
|
+
style: computed.borderRightStyle,
|
|
13783
|
+
width: computed.borderRightWidth,
|
|
13784
|
+
color: computed.borderRightColor
|
|
13785
|
+
},
|
|
13786
|
+
{
|
|
13787
|
+
style: computed.borderBottomStyle,
|
|
13788
|
+
width: computed.borderBottomWidth,
|
|
13789
|
+
color: computed.borderBottomColor
|
|
13790
|
+
},
|
|
13791
|
+
{
|
|
13792
|
+
style: computed.borderLeftStyle,
|
|
13793
|
+
width: computed.borderLeftWidth,
|
|
13794
|
+
color: computed.borderLeftColor
|
|
13795
|
+
}
|
|
13796
|
+
];
|
|
13797
|
+
for (const side of borderSides) {
|
|
13798
|
+
if (side.style !== "none" && parseFloat(side.width) > 0 && matches(side.color, currentTextColor)) {
|
|
13799
|
+
return true;
|
|
13800
|
+
}
|
|
13801
|
+
}
|
|
13802
|
+
if (computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0 && matches(computed.outlineColor, currentTextColor)) {
|
|
13143
13803
|
return true;
|
|
13144
13804
|
}
|
|
13805
|
+
if (node instanceof SVGGraphicsElement) {
|
|
13806
|
+
const fillMatch = matches(computed.getPropertyValue("fill"), currentTextColor) || matches(node.getAttribute("fill") ?? "", currentTextColor);
|
|
13807
|
+
const strokeMatch = matches(computed.getPropertyValue("stroke"), currentTextColor) || matches(node.getAttribute("stroke") ?? "", currentTextColor);
|
|
13808
|
+
if (fillMatch || strokeMatch) return true;
|
|
13809
|
+
}
|
|
13810
|
+
return false;
|
|
13811
|
+
};
|
|
13812
|
+
const descendants = Array.from(selectedElement.querySelectorAll("*"));
|
|
13813
|
+
const firstDescendantMatch = descendants.find(
|
|
13814
|
+
(node) => node instanceof HTMLElement && hasMatchingColor(node)
|
|
13815
|
+
);
|
|
13816
|
+
if (firstDescendantMatch) {
|
|
13817
|
+
selectElement(firstDescendantMatch);
|
|
13818
|
+
return;
|
|
13145
13819
|
}
|
|
13146
|
-
if (
|
|
13147
|
-
|
|
13148
|
-
}
|
|
13149
|
-
if (node instanceof SVGGraphicsElement) {
|
|
13150
|
-
const fillMatch = matches(computed.getPropertyValue("fill"), currentTextColor) || matches(node.getAttribute("fill") ?? "", currentTextColor);
|
|
13151
|
-
const strokeMatch = matches(computed.getPropertyValue("stroke"), currentTextColor) || matches(node.getAttribute("stroke") ?? "", currentTextColor);
|
|
13152
|
-
if (fillMatch || strokeMatch) return true;
|
|
13820
|
+
if (hasMatchingColor(selectedElement)) {
|
|
13821
|
+
selectElement(selectedElement);
|
|
13153
13822
|
}
|
|
13154
|
-
|
|
13155
|
-
|
|
13156
|
-
|
|
13157
|
-
const firstDescendantMatch = descendants.find((node) => node instanceof HTMLElement && hasMatchingColor(node));
|
|
13158
|
-
if (firstDescendantMatch) {
|
|
13159
|
-
selectElement(firstDescendantMatch);
|
|
13160
|
-
return;
|
|
13161
|
-
}
|
|
13162
|
-
if (hasMatchingColor(selectedElement)) {
|
|
13163
|
-
selectElement(selectedElement);
|
|
13164
|
-
}
|
|
13165
|
-
}, [selectedElement, selectElement]);
|
|
13823
|
+
},
|
|
13824
|
+
[selectedElement, selectElement]
|
|
13825
|
+
);
|
|
13166
13826
|
const handleMoveStart = (e, targetElement, options) => {
|
|
13167
13827
|
const elementToDrag = targetElement ?? selectedElement;
|
|
13168
13828
|
if (elementToDrag) {
|
|
@@ -13251,7 +13911,11 @@ function DirectEditPanelContent() {
|
|
|
13251
13911
|
hoveredElement,
|
|
13252
13912
|
measurements: [
|
|
13253
13913
|
...measurements,
|
|
13254
|
-
...calculateGuidelineMeasurements(
|
|
13914
|
+
...calculateGuidelineMeasurements(
|
|
13915
|
+
selectedElement,
|
|
13916
|
+
getStoredGuidelines(),
|
|
13917
|
+
mousePosition
|
|
13918
|
+
)
|
|
13255
13919
|
]
|
|
13256
13920
|
}
|
|
13257
13921
|
),
|
|
@@ -13306,6 +13970,9 @@ function DirectEditPanelContent() {
|
|
|
13306
13970
|
onSelectSelectionColorTarget: handleSelectSelectionColorTarget,
|
|
13307
13971
|
onUpdateTypography: updateTypographyProperty,
|
|
13308
13972
|
onReset: resetToOriginal,
|
|
13973
|
+
onExportEdits: exportEdits,
|
|
13974
|
+
onSendToAgent: agentAvailable ? sendEditToAgent2 : void 0,
|
|
13975
|
+
sendFailureReason: lastSendFailure?.reason ?? null,
|
|
13309
13976
|
className: "fixed z-[99999]",
|
|
13310
13977
|
style: {
|
|
13311
13978
|
left: position.x,
|
|
@@ -14240,7 +14907,8 @@ function EditsPopover({
|
|
|
14240
14907
|
onExportAllEdits,
|
|
14241
14908
|
onClearSessionEdits,
|
|
14242
14909
|
onRemoveSessionEdit,
|
|
14243
|
-
onDeleteComment
|
|
14910
|
+
onDeleteComment,
|
|
14911
|
+
sendFailure
|
|
14244
14912
|
}) {
|
|
14245
14913
|
const [copied, setCopied] = React38.useState(false);
|
|
14246
14914
|
const editsPopupRef = React38.useRef(null);
|
|
@@ -14253,6 +14921,7 @@ function EditsPopover({
|
|
|
14253
14921
|
const visibleItems = React38.useMemo(() => {
|
|
14254
14922
|
return editsSnapshot.filter((item) => {
|
|
14255
14923
|
if (item.type === "comment") return true;
|
|
14924
|
+
if (item.edit.deleted) return true;
|
|
14256
14925
|
if (!item.edit.move) return true;
|
|
14257
14926
|
const moveIntent = getMoveIntentForEdit(item.edit, movePlanContext);
|
|
14258
14927
|
const hasStyleOrText = Object.keys(item.edit.pendingStyles).length > 0 || item.edit.textEdit != null;
|
|
@@ -14357,12 +15026,15 @@ ${text}`);
|
|
|
14357
15026
|
visibleItems.length === 0 && multiSelectContextItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "px-3 pb-3 pt-1 text-xs text-muted-foreground", children: "No edits or comments yet." }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "max-h-[240px] overflow-y-auto px-1 py-1", children: [
|
|
14358
15027
|
visibleItems.map((item, i) => {
|
|
14359
15028
|
const isEdit = item.type === "edit";
|
|
15029
|
+
const isDeleted = isEdit && Boolean(item.edit.deleted);
|
|
14360
15030
|
const moveIntent = isEdit && item.edit.move ? getMoveIntentForEdit(item.edit, movePlanContext) : null;
|
|
14361
15031
|
const isMoved = Boolean(moveIntent);
|
|
14362
15032
|
const locator = isEdit ? item.edit.locator : item.comment.locator;
|
|
14363
15033
|
const componentName = locator.reactStack[0]?.name ?? locator.tagName;
|
|
14364
15034
|
let valueSummary = "";
|
|
14365
|
-
if (isEdit) {
|
|
15035
|
+
if (isEdit && isDeleted) {
|
|
15036
|
+
valueSummary = locator.textPreview || locator.domSelector || locator.tagName;
|
|
15037
|
+
} else if (isEdit) {
|
|
14366
15038
|
const entries = Object.entries(item.edit.pendingStyles);
|
|
14367
15039
|
const editValues = [];
|
|
14368
15040
|
for (const [prop, value] of entries) {
|
|
@@ -14383,6 +15055,7 @@ ${text}`);
|
|
|
14383
15055
|
}
|
|
14384
15056
|
valueSummary = commentValues.join(", ");
|
|
14385
15057
|
}
|
|
15058
|
+
const failed = isEdit ? sendFailure?.failedEditElements.includes(item.edit.element) : sendFailure?.failedCommentIds.includes(item.comment.id);
|
|
14386
15059
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
14387
15060
|
"div",
|
|
14388
15061
|
{
|
|
@@ -14401,13 +15074,16 @@ ${text}`);
|
|
|
14401
15074
|
},
|
|
14402
15075
|
children: [
|
|
14403
15076
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "min-w-0 flex flex-1 flex-col items-start gap-[4px]", children: [
|
|
14404
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
14405
|
-
"
|
|
14406
|
-
|
|
14407
|
-
|
|
15077
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
15078
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Badge, { variant: "secondary", className: "h-6 shrink-0 px-1.5 text-xs", children: [
|
|
15079
|
+
"@<",
|
|
15080
|
+
componentName,
|
|
15081
|
+
">"
|
|
15082
|
+
] }),
|
|
15083
|
+
failed && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Badge, { variant: "default", className: "h-6 shrink-0 px-1.5 text-xs bg-red-500 text-white border-transparent", children: "Failed" })
|
|
14408
15084
|
] }),
|
|
14409
15085
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "min-w-0 max-w-full truncate text-xs text-muted-foreground", children: [
|
|
14410
|
-
isEdit ? isMoved ? "moved: " : "edit: " : "comment: ",
|
|
15086
|
+
isEdit ? isDeleted ? "deleted: " : isMoved ? "moved: " : "edit: " : "comment: ",
|
|
14411
15087
|
truncateText(valueSummary, 128)
|
|
14412
15088
|
] })
|
|
14413
15089
|
] }),
|
|
@@ -14659,6 +15335,7 @@ function SettingsPopover({
|
|
|
14659
15335
|
{ label: "Undo", keys: isMac ? [/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react16.Command, { className: "size-2.5" }, "cmd"), "Z"] : ["Ctrl", "Z"] },
|
|
14660
15336
|
{ label: "Group selection", keys: isMac ? [/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react16.Command, { className: "size-2.5" }, "cmd"), "G"] : ["Ctrl", "G"] },
|
|
14661
15337
|
{ label: "Add frame", keys: ["F"] },
|
|
15338
|
+
{ label: "Add text", keys: ["T"] },
|
|
14662
15339
|
{ label: "Add div", keys: ["D"] },
|
|
14663
15340
|
{ label: "Add to selection", keys: [/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react16.ArrowBigUp, { className: "size-3" }, "shift"), "Click"] },
|
|
14664
15341
|
{ label: "Marquee select", keys: ["Drag"] },
|
|
@@ -14701,6 +15378,8 @@ function DirectEditToolbarInner({
|
|
|
14701
15378
|
onExportAllEdits,
|
|
14702
15379
|
onSendAllToAgents,
|
|
14703
15380
|
agentAvailable = true,
|
|
15381
|
+
sendFailureReason,
|
|
15382
|
+
sendFailure,
|
|
14704
15383
|
onClearSessionEdits,
|
|
14705
15384
|
onRemoveSessionEdit,
|
|
14706
15385
|
onDeleteComment,
|
|
@@ -14710,7 +15389,8 @@ function DirectEditToolbarInner({
|
|
|
14710
15389
|
onToggleCanvas,
|
|
14711
15390
|
onSetCanvasZoom,
|
|
14712
15391
|
onZoomTo100,
|
|
14713
|
-
onFitToViewport
|
|
15392
|
+
onFitToViewport,
|
|
15393
|
+
onInsertElement
|
|
14714
15394
|
}) {
|
|
14715
15395
|
const container = usePortalContainer();
|
|
14716
15396
|
const toolbarRef = React40.useRef(null);
|
|
@@ -14719,7 +15399,8 @@ function DirectEditToolbarInner({
|
|
|
14719
15399
|
const [activePopover, setActivePopover] = React40.useState(null);
|
|
14720
15400
|
const [applyStatus, setApplyStatus] = React40.useState("idle");
|
|
14721
15401
|
const applyTimerRef = React40.useRef(null);
|
|
14722
|
-
const showApplyButton = agentAvailable && Boolean(onSendAllToAgents);
|
|
15402
|
+
const showApplyButton = (agentAvailable || applyStatus !== "idle") && Boolean(onSendAllToAgents);
|
|
15403
|
+
const showInsertButtons = Boolean(onInsertElement);
|
|
14723
15404
|
const totalItemCount = sessionEditCount + multiSelectCount;
|
|
14724
15405
|
const sizeCacheRef = React40.useRef({});
|
|
14725
15406
|
React40.useEffect(() => {
|
|
@@ -14773,6 +15454,16 @@ function DirectEditToolbarInner({
|
|
|
14773
15454
|
setApplyStatus("idle");
|
|
14774
15455
|
}, 2e3);
|
|
14775
15456
|
}, []);
|
|
15457
|
+
const prevTotalItemCountRef = React40.useRef(totalItemCount);
|
|
15458
|
+
React40.useEffect(() => {
|
|
15459
|
+
if (prevTotalItemCountRef.current !== totalItemCount) {
|
|
15460
|
+
prevTotalItemCountRef.current = totalItemCount;
|
|
15461
|
+
if (applyStatus === "offline") {
|
|
15462
|
+
setApplyStatus("idle");
|
|
15463
|
+
}
|
|
15464
|
+
}
|
|
15465
|
+
}, [totalItemCount, applyStatus]);
|
|
15466
|
+
const applyTooltipLabel = applyStatus === "offline" ? sendFailureReason === "unreachable" ? "Agent unreachable \u2014 click to retry" : "Agent rejected the edit \u2014 click to retry" : "Apply all changes via agent";
|
|
14776
15467
|
const handleApplyAll = React40.useCallback(async () => {
|
|
14777
15468
|
if (!onSendAllToAgents || totalItemCount === 0 || applyStatus === "sending") return;
|
|
14778
15469
|
setApplyStatus("sending");
|
|
@@ -14782,8 +15473,12 @@ function DirectEditToolbarInner({
|
|
|
14782
15473
|
} catch {
|
|
14783
15474
|
success = false;
|
|
14784
15475
|
}
|
|
14785
|
-
|
|
14786
|
-
|
|
15476
|
+
if (success) {
|
|
15477
|
+
setApplyStatus("sent");
|
|
15478
|
+
scheduleApplyReset();
|
|
15479
|
+
} else {
|
|
15480
|
+
setApplyStatus("offline");
|
|
15481
|
+
}
|
|
14787
15482
|
}, [applyStatus, onSendAllToAgents, scheduleApplyReset, totalItemCount]);
|
|
14788
15483
|
const dragHandlers = React40.useMemo(() => ({
|
|
14789
15484
|
onPointerDown: handlePointerDown,
|
|
@@ -14864,6 +15559,38 @@ function DirectEditToolbarInner({
|
|
|
14864
15559
|
},
|
|
14865
15560
|
...dragHandlers,
|
|
14866
15561
|
children: [
|
|
15562
|
+
showInsertButtons && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
15563
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(Tooltip, { children: [
|
|
15564
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
15565
|
+
TooltipTrigger,
|
|
15566
|
+
{
|
|
15567
|
+
className: cn(toolbarBtnClass, "text-muted-foreground hover:bg-muted hover:text-foreground"),
|
|
15568
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
15569
|
+
onClick: () => onInsertElement?.("frame"),
|
|
15570
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react17.Square, { className: "size-4" })
|
|
15571
|
+
}
|
|
15572
|
+
),
|
|
15573
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(TooltipContent, { side: tooltipSide, className: "inline-flex items-center gap-1.5", children: [
|
|
15574
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: "Add frame" }),
|
|
15575
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("kbd", { className: kbdClass, children: "F" })
|
|
15576
|
+
] })
|
|
15577
|
+
] }),
|
|
15578
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(Tooltip, { children: [
|
|
15579
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
15580
|
+
TooltipTrigger,
|
|
15581
|
+
{
|
|
15582
|
+
className: cn(toolbarBtnClass, "text-muted-foreground hover:bg-muted hover:text-foreground"),
|
|
15583
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
15584
|
+
onClick: () => onInsertElement?.("text"),
|
|
15585
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react17.Type, { className: "size-4" })
|
|
15586
|
+
}
|
|
15587
|
+
),
|
|
15588
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(TooltipContent, { side: tooltipSide, className: "inline-flex items-center gap-1.5", children: [
|
|
15589
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: "Add text" }),
|
|
15590
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("kbd", { className: kbdClass, children: "T" })
|
|
15591
|
+
] })
|
|
15592
|
+
] })
|
|
15593
|
+
] }),
|
|
14867
15594
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14868
15595
|
EditsPopover,
|
|
14869
15596
|
{
|
|
@@ -14876,7 +15603,8 @@ function DirectEditToolbarInner({
|
|
|
14876
15603
|
onExportAllEdits,
|
|
14877
15604
|
onClearSessionEdits,
|
|
14878
15605
|
onRemoveSessionEdit,
|
|
14879
|
-
onDeleteComment
|
|
15606
|
+
onDeleteComment,
|
|
15607
|
+
sendFailure
|
|
14880
15608
|
}
|
|
14881
15609
|
),
|
|
14882
15610
|
showApplyButton && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(Tooltip, { children: [
|
|
@@ -14900,7 +15628,7 @@ function DirectEditToolbarInner({
|
|
|
14900
15628
|
]
|
|
14901
15629
|
}
|
|
14902
15630
|
),
|
|
14903
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(TooltipContent, { side: tooltipSide, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children:
|
|
15631
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(TooltipContent, { side: tooltipSide, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: applyTooltipLabel }) })
|
|
14904
15632
|
] }),
|
|
14905
15633
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14906
15634
|
"div",
|
|
@@ -14962,7 +15690,7 @@ function DirectEditToolbarInner({
|
|
|
14962
15690
|
return toolbar;
|
|
14963
15691
|
}
|
|
14964
15692
|
function DirectEditToolbarContent() {
|
|
14965
|
-
const { editModeActive, theme, sessionEditCount, multiSelectContextCount, selectedElements, canvas, agentAvailable } = useDirectEditState();
|
|
15693
|
+
const { editModeActive, theme, sessionEditCount, multiSelectContextCount, selectedElements, canvas, agentAvailable, lastSendFailure } = useDirectEditState();
|
|
14966
15694
|
const {
|
|
14967
15695
|
toggleEditMode,
|
|
14968
15696
|
setTheme,
|
|
@@ -14972,6 +15700,7 @@ function DirectEditToolbarContent() {
|
|
|
14972
15700
|
clearSessionEdits,
|
|
14973
15701
|
removeSessionEdit,
|
|
14974
15702
|
deleteComment,
|
|
15703
|
+
insertElement,
|
|
14975
15704
|
toggleCanvas,
|
|
14976
15705
|
setCanvasZoom,
|
|
14977
15706
|
zoomCanvasTo100,
|
|
@@ -14994,6 +15723,8 @@ function DirectEditToolbarContent() {
|
|
|
14994
15723
|
onExportAllEdits: exportAllEdits,
|
|
14995
15724
|
onSendAllToAgents: sendAllSessionItemsToAgent,
|
|
14996
15725
|
agentAvailable,
|
|
15726
|
+
sendFailureReason: lastSendFailure?.reason ?? null,
|
|
15727
|
+
sendFailure: lastSendFailure,
|
|
14997
15728
|
onClearSessionEdits: clearSessionEdits,
|
|
14998
15729
|
onRemoveSessionEdit: removeSessionEdit,
|
|
14999
15730
|
onDeleteComment: deleteComment,
|
|
@@ -15002,7 +15733,8 @@ function DirectEditToolbarContent() {
|
|
|
15002
15733
|
onToggleCanvas: toggleCanvas,
|
|
15003
15734
|
onSetCanvasZoom: setCanvasZoom,
|
|
15004
15735
|
onZoomTo100: zoomCanvasTo100,
|
|
15005
|
-
onFitToViewport: fitCanvasToViewport
|
|
15736
|
+
onFitToViewport: fitCanvasToViewport,
|
|
15737
|
+
onInsertElement: insertElement
|
|
15006
15738
|
}
|
|
15007
15739
|
);
|
|
15008
15740
|
}
|