an appview-less Bluesky client using Constellation and PDS Queries reddwarf.app
frontend spa bluesky reddwarf microcosm

post composer (no embeds yet)

rimar1337 06ea05da 9fc1ecc2

+1681
package-lock.json
··· 8 8 "dependencies": { 9 9 "@atproto/api": "^0.16.6", 10 10 "@atproto/oauth-client-browser": "^0.3.33", 11 + "@radix-ui/react-dropdown-menu": "^2.1.16", 11 12 "@tailwindcss/vite": "^4.0.6", 12 13 "@tanstack/query-sync-storage-persister": "^5.85.6", 13 14 "@tanstack/react-devtools": "^0.2.2", ··· 21 22 "idb-keyval": "^6.2.2", 22 23 "jotai": "^2.13.1", 23 24 "npm": "^11.6.2", 25 + "radix-ui": "^1.4.3", 24 26 "react": "^19.0.0", 25 27 "react-dom": "^19.0.0", 26 28 "react-player": "^3.3.2", ··· 1592 1594 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1593 1595 } 1594 1596 }, 1597 + "node_modules/@floating-ui/core": { 1598 + "version": "1.7.3", 1599 + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", 1600 + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", 1601 + "dependencies": { 1602 + "@floating-ui/utils": "^0.2.10" 1603 + } 1604 + }, 1605 + "node_modules/@floating-ui/dom": { 1606 + "version": "1.7.4", 1607 + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", 1608 + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", 1609 + "dependencies": { 1610 + "@floating-ui/core": "^1.7.3", 1611 + "@floating-ui/utils": "^0.2.10" 1612 + } 1613 + }, 1614 + "node_modules/@floating-ui/react-dom": { 1615 + "version": "2.1.6", 1616 + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", 1617 + "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", 1618 + "dependencies": { 1619 + "@floating-ui/dom": "^1.7.4" 1620 + }, 1621 + "peerDependencies": { 1622 + "react": ">=16.8.0", 1623 + "react-dom": ">=16.8.0" 1624 + } 1625 + }, 1626 + "node_modules/@floating-ui/utils": { 1627 + "version": "0.2.10", 1628 + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", 1629 + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==" 1630 + }, 1595 1631 "node_modules/@humanfs/core": { 1596 1632 "version": "0.19.1", 1597 1633 "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", ··· 1895 1931 "node": ">= 8" 1896 1932 } 1897 1933 }, 1934 + "node_modules/@radix-ui/number": { 1935 + "version": "1.1.1", 1936 + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", 1937 + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==" 1938 + }, 1939 + "node_modules/@radix-ui/primitive": { 1940 + "version": "1.1.3", 1941 + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", 1942 + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==" 1943 + }, 1944 + "node_modules/@radix-ui/react-accessible-icon": { 1945 + "version": "1.1.7", 1946 + "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.1.7.tgz", 1947 + "integrity": "sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==", 1948 + "dependencies": { 1949 + "@radix-ui/react-visually-hidden": "1.2.3" 1950 + }, 1951 + "peerDependencies": { 1952 + "@types/react": "*", 1953 + "@types/react-dom": "*", 1954 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 1955 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 1956 + }, 1957 + "peerDependenciesMeta": { 1958 + "@types/react": { 1959 + "optional": true 1960 + }, 1961 + "@types/react-dom": { 1962 + "optional": true 1963 + } 1964 + } 1965 + }, 1966 + "node_modules/@radix-ui/react-accordion": { 1967 + "version": "1.2.12", 1968 + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", 1969 + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", 1970 + "dependencies": { 1971 + "@radix-ui/primitive": "1.1.3", 1972 + "@radix-ui/react-collapsible": "1.1.12", 1973 + "@radix-ui/react-collection": "1.1.7", 1974 + "@radix-ui/react-compose-refs": "1.1.2", 1975 + "@radix-ui/react-context": "1.1.2", 1976 + "@radix-ui/react-direction": "1.1.1", 1977 + "@radix-ui/react-id": "1.1.1", 1978 + "@radix-ui/react-primitive": "2.1.3", 1979 + "@radix-ui/react-use-controllable-state": "1.2.2" 1980 + }, 1981 + "peerDependencies": { 1982 + "@types/react": "*", 1983 + "@types/react-dom": "*", 1984 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 1985 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 1986 + }, 1987 + "peerDependenciesMeta": { 1988 + "@types/react": { 1989 + "optional": true 1990 + }, 1991 + "@types/react-dom": { 1992 + "optional": true 1993 + } 1994 + } 1995 + }, 1996 + "node_modules/@radix-ui/react-alert-dialog": { 1997 + "version": "1.1.15", 1998 + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", 1999 + "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", 2000 + "dependencies": { 2001 + "@radix-ui/primitive": "1.1.3", 2002 + "@radix-ui/react-compose-refs": "1.1.2", 2003 + "@radix-ui/react-context": "1.1.2", 2004 + "@radix-ui/react-dialog": "1.1.15", 2005 + "@radix-ui/react-primitive": "2.1.3", 2006 + "@radix-ui/react-slot": "1.2.3" 2007 + }, 2008 + "peerDependencies": { 2009 + "@types/react": "*", 2010 + "@types/react-dom": "*", 2011 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2012 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2013 + }, 2014 + "peerDependenciesMeta": { 2015 + "@types/react": { 2016 + "optional": true 2017 + }, 2018 + "@types/react-dom": { 2019 + "optional": true 2020 + } 2021 + } 2022 + }, 2023 + "node_modules/@radix-ui/react-arrow": { 2024 + "version": "1.1.7", 2025 + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", 2026 + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", 2027 + "dependencies": { 2028 + "@radix-ui/react-primitive": "2.1.3" 2029 + }, 2030 + "peerDependencies": { 2031 + "@types/react": "*", 2032 + "@types/react-dom": "*", 2033 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2034 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2035 + }, 2036 + "peerDependenciesMeta": { 2037 + "@types/react": { 2038 + "optional": true 2039 + }, 2040 + "@types/react-dom": { 2041 + "optional": true 2042 + } 2043 + } 2044 + }, 2045 + "node_modules/@radix-ui/react-aspect-ratio": { 2046 + "version": "1.1.7", 2047 + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", 2048 + "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", 2049 + "dependencies": { 2050 + "@radix-ui/react-primitive": "2.1.3" 2051 + }, 2052 + "peerDependencies": { 2053 + "@types/react": "*", 2054 + "@types/react-dom": "*", 2055 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2056 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2057 + }, 2058 + "peerDependenciesMeta": { 2059 + "@types/react": { 2060 + "optional": true 2061 + }, 2062 + "@types/react-dom": { 2063 + "optional": true 2064 + } 2065 + } 2066 + }, 2067 + "node_modules/@radix-ui/react-avatar": { 2068 + "version": "1.1.10", 2069 + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", 2070 + "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", 2071 + "dependencies": { 2072 + "@radix-ui/react-context": "1.1.2", 2073 + "@radix-ui/react-primitive": "2.1.3", 2074 + "@radix-ui/react-use-callback-ref": "1.1.1", 2075 + "@radix-ui/react-use-is-hydrated": "0.1.0", 2076 + "@radix-ui/react-use-layout-effect": "1.1.1" 2077 + }, 2078 + "peerDependencies": { 2079 + "@types/react": "*", 2080 + "@types/react-dom": "*", 2081 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2082 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2083 + }, 2084 + "peerDependenciesMeta": { 2085 + "@types/react": { 2086 + "optional": true 2087 + }, 2088 + "@types/react-dom": { 2089 + "optional": true 2090 + } 2091 + } 2092 + }, 2093 + "node_modules/@radix-ui/react-checkbox": { 2094 + "version": "1.3.3", 2095 + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", 2096 + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", 2097 + "dependencies": { 2098 + "@radix-ui/primitive": "1.1.3", 2099 + "@radix-ui/react-compose-refs": "1.1.2", 2100 + "@radix-ui/react-context": "1.1.2", 2101 + "@radix-ui/react-presence": "1.1.5", 2102 + "@radix-ui/react-primitive": "2.1.3", 2103 + "@radix-ui/react-use-controllable-state": "1.2.2", 2104 + "@radix-ui/react-use-previous": "1.1.1", 2105 + "@radix-ui/react-use-size": "1.1.1" 2106 + }, 2107 + "peerDependencies": { 2108 + "@types/react": "*", 2109 + "@types/react-dom": "*", 2110 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2111 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2112 + }, 2113 + "peerDependenciesMeta": { 2114 + "@types/react": { 2115 + "optional": true 2116 + }, 2117 + "@types/react-dom": { 2118 + "optional": true 2119 + } 2120 + } 2121 + }, 2122 + "node_modules/@radix-ui/react-collapsible": { 2123 + "version": "1.1.12", 2124 + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", 2125 + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", 2126 + "dependencies": { 2127 + "@radix-ui/primitive": "1.1.3", 2128 + "@radix-ui/react-compose-refs": "1.1.2", 2129 + "@radix-ui/react-context": "1.1.2", 2130 + "@radix-ui/react-id": "1.1.1", 2131 + "@radix-ui/react-presence": "1.1.5", 2132 + "@radix-ui/react-primitive": "2.1.3", 2133 + "@radix-ui/react-use-controllable-state": "1.2.2", 2134 + "@radix-ui/react-use-layout-effect": "1.1.1" 2135 + }, 2136 + "peerDependencies": { 2137 + "@types/react": "*", 2138 + "@types/react-dom": "*", 2139 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2140 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2141 + }, 2142 + "peerDependenciesMeta": { 2143 + "@types/react": { 2144 + "optional": true 2145 + }, 2146 + "@types/react-dom": { 2147 + "optional": true 2148 + } 2149 + } 2150 + }, 2151 + "node_modules/@radix-ui/react-collection": { 2152 + "version": "1.1.7", 2153 + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", 2154 + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", 2155 + "dependencies": { 2156 + "@radix-ui/react-compose-refs": "1.1.2", 2157 + "@radix-ui/react-context": "1.1.2", 2158 + "@radix-ui/react-primitive": "2.1.3", 2159 + "@radix-ui/react-slot": "1.2.3" 2160 + }, 2161 + "peerDependencies": { 2162 + "@types/react": "*", 2163 + "@types/react-dom": "*", 2164 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2165 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2166 + }, 2167 + "peerDependenciesMeta": { 2168 + "@types/react": { 2169 + "optional": true 2170 + }, 2171 + "@types/react-dom": { 2172 + "optional": true 2173 + } 2174 + } 2175 + }, 2176 + "node_modules/@radix-ui/react-compose-refs": { 2177 + "version": "1.1.2", 2178 + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", 2179 + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", 2180 + "peerDependencies": { 2181 + "@types/react": "*", 2182 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2183 + }, 2184 + "peerDependenciesMeta": { 2185 + "@types/react": { 2186 + "optional": true 2187 + } 2188 + } 2189 + }, 2190 + "node_modules/@radix-ui/react-context": { 2191 + "version": "1.1.2", 2192 + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", 2193 + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", 2194 + "peerDependencies": { 2195 + "@types/react": "*", 2196 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2197 + }, 2198 + "peerDependenciesMeta": { 2199 + "@types/react": { 2200 + "optional": true 2201 + } 2202 + } 2203 + }, 2204 + "node_modules/@radix-ui/react-context-menu": { 2205 + "version": "2.2.16", 2206 + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.16.tgz", 2207 + "integrity": "sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==", 2208 + "dependencies": { 2209 + "@radix-ui/primitive": "1.1.3", 2210 + "@radix-ui/react-context": "1.1.2", 2211 + "@radix-ui/react-menu": "2.1.16", 2212 + "@radix-ui/react-primitive": "2.1.3", 2213 + "@radix-ui/react-use-callback-ref": "1.1.1", 2214 + "@radix-ui/react-use-controllable-state": "1.2.2" 2215 + }, 2216 + "peerDependencies": { 2217 + "@types/react": "*", 2218 + "@types/react-dom": "*", 2219 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2220 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2221 + }, 2222 + "peerDependenciesMeta": { 2223 + "@types/react": { 2224 + "optional": true 2225 + }, 2226 + "@types/react-dom": { 2227 + "optional": true 2228 + } 2229 + } 2230 + }, 2231 + "node_modules/@radix-ui/react-dialog": { 2232 + "version": "1.1.15", 2233 + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", 2234 + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", 2235 + "dependencies": { 2236 + "@radix-ui/primitive": "1.1.3", 2237 + "@radix-ui/react-compose-refs": "1.1.2", 2238 + "@radix-ui/react-context": "1.1.2", 2239 + "@radix-ui/react-dismissable-layer": "1.1.11", 2240 + "@radix-ui/react-focus-guards": "1.1.3", 2241 + "@radix-ui/react-focus-scope": "1.1.7", 2242 + "@radix-ui/react-id": "1.1.1", 2243 + "@radix-ui/react-portal": "1.1.9", 2244 + "@radix-ui/react-presence": "1.1.5", 2245 + "@radix-ui/react-primitive": "2.1.3", 2246 + "@radix-ui/react-slot": "1.2.3", 2247 + "@radix-ui/react-use-controllable-state": "1.2.2", 2248 + "aria-hidden": "^1.2.4", 2249 + "react-remove-scroll": "^2.6.3" 2250 + }, 2251 + "peerDependencies": { 2252 + "@types/react": "*", 2253 + "@types/react-dom": "*", 2254 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2255 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2256 + }, 2257 + "peerDependenciesMeta": { 2258 + "@types/react": { 2259 + "optional": true 2260 + }, 2261 + "@types/react-dom": { 2262 + "optional": true 2263 + } 2264 + } 2265 + }, 2266 + "node_modules/@radix-ui/react-direction": { 2267 + "version": "1.1.1", 2268 + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", 2269 + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", 2270 + "peerDependencies": { 2271 + "@types/react": "*", 2272 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2273 + }, 2274 + "peerDependenciesMeta": { 2275 + "@types/react": { 2276 + "optional": true 2277 + } 2278 + } 2279 + }, 2280 + "node_modules/@radix-ui/react-dismissable-layer": { 2281 + "version": "1.1.11", 2282 + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", 2283 + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", 2284 + "dependencies": { 2285 + "@radix-ui/primitive": "1.1.3", 2286 + "@radix-ui/react-compose-refs": "1.1.2", 2287 + "@radix-ui/react-primitive": "2.1.3", 2288 + "@radix-ui/react-use-callback-ref": "1.1.1", 2289 + "@radix-ui/react-use-escape-keydown": "1.1.1" 2290 + }, 2291 + "peerDependencies": { 2292 + "@types/react": "*", 2293 + "@types/react-dom": "*", 2294 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2295 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2296 + }, 2297 + "peerDependenciesMeta": { 2298 + "@types/react": { 2299 + "optional": true 2300 + }, 2301 + "@types/react-dom": { 2302 + "optional": true 2303 + } 2304 + } 2305 + }, 2306 + "node_modules/@radix-ui/react-dropdown-menu": { 2307 + "version": "2.1.16", 2308 + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", 2309 + "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", 2310 + "dependencies": { 2311 + "@radix-ui/primitive": "1.1.3", 2312 + "@radix-ui/react-compose-refs": "1.1.2", 2313 + "@radix-ui/react-context": "1.1.2", 2314 + "@radix-ui/react-id": "1.1.1", 2315 + "@radix-ui/react-menu": "2.1.16", 2316 + "@radix-ui/react-primitive": "2.1.3", 2317 + "@radix-ui/react-use-controllable-state": "1.2.2" 2318 + }, 2319 + "peerDependencies": { 2320 + "@types/react": "*", 2321 + "@types/react-dom": "*", 2322 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2323 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2324 + }, 2325 + "peerDependenciesMeta": { 2326 + "@types/react": { 2327 + "optional": true 2328 + }, 2329 + "@types/react-dom": { 2330 + "optional": true 2331 + } 2332 + } 2333 + }, 2334 + "node_modules/@radix-ui/react-focus-guards": { 2335 + "version": "1.1.3", 2336 + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", 2337 + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", 2338 + "peerDependencies": { 2339 + "@types/react": "*", 2340 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2341 + }, 2342 + "peerDependenciesMeta": { 2343 + "@types/react": { 2344 + "optional": true 2345 + } 2346 + } 2347 + }, 2348 + "node_modules/@radix-ui/react-focus-scope": { 2349 + "version": "1.1.7", 2350 + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", 2351 + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", 2352 + "dependencies": { 2353 + "@radix-ui/react-compose-refs": "1.1.2", 2354 + "@radix-ui/react-primitive": "2.1.3", 2355 + "@radix-ui/react-use-callback-ref": "1.1.1" 2356 + }, 2357 + "peerDependencies": { 2358 + "@types/react": "*", 2359 + "@types/react-dom": "*", 2360 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2361 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2362 + }, 2363 + "peerDependenciesMeta": { 2364 + "@types/react": { 2365 + "optional": true 2366 + }, 2367 + "@types/react-dom": { 2368 + "optional": true 2369 + } 2370 + } 2371 + }, 2372 + "node_modules/@radix-ui/react-form": { 2373 + "version": "0.1.8", 2374 + "resolved": "https://registry.npmjs.org/@radix-ui/react-form/-/react-form-0.1.8.tgz", 2375 + "integrity": "sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ==", 2376 + "dependencies": { 2377 + "@radix-ui/primitive": "1.1.3", 2378 + "@radix-ui/react-compose-refs": "1.1.2", 2379 + "@radix-ui/react-context": "1.1.2", 2380 + "@radix-ui/react-id": "1.1.1", 2381 + "@radix-ui/react-label": "2.1.7", 2382 + "@radix-ui/react-primitive": "2.1.3" 2383 + }, 2384 + "peerDependencies": { 2385 + "@types/react": "*", 2386 + "@types/react-dom": "*", 2387 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2388 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2389 + }, 2390 + "peerDependenciesMeta": { 2391 + "@types/react": { 2392 + "optional": true 2393 + }, 2394 + "@types/react-dom": { 2395 + "optional": true 2396 + } 2397 + } 2398 + }, 2399 + "node_modules/@radix-ui/react-hover-card": { 2400 + "version": "1.1.15", 2401 + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.15.tgz", 2402 + "integrity": "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==", 2403 + "dependencies": { 2404 + "@radix-ui/primitive": "1.1.3", 2405 + "@radix-ui/react-compose-refs": "1.1.2", 2406 + "@radix-ui/react-context": "1.1.2", 2407 + "@radix-ui/react-dismissable-layer": "1.1.11", 2408 + "@radix-ui/react-popper": "1.2.8", 2409 + "@radix-ui/react-portal": "1.1.9", 2410 + "@radix-ui/react-presence": "1.1.5", 2411 + "@radix-ui/react-primitive": "2.1.3", 2412 + "@radix-ui/react-use-controllable-state": "1.2.2" 2413 + }, 2414 + "peerDependencies": { 2415 + "@types/react": "*", 2416 + "@types/react-dom": "*", 2417 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2418 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2419 + }, 2420 + "peerDependenciesMeta": { 2421 + "@types/react": { 2422 + "optional": true 2423 + }, 2424 + "@types/react-dom": { 2425 + "optional": true 2426 + } 2427 + } 2428 + }, 2429 + "node_modules/@radix-ui/react-id": { 2430 + "version": "1.1.1", 2431 + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", 2432 + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", 2433 + "dependencies": { 2434 + "@radix-ui/react-use-layout-effect": "1.1.1" 2435 + }, 2436 + "peerDependencies": { 2437 + "@types/react": "*", 2438 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2439 + }, 2440 + "peerDependenciesMeta": { 2441 + "@types/react": { 2442 + "optional": true 2443 + } 2444 + } 2445 + }, 2446 + "node_modules/@radix-ui/react-label": { 2447 + "version": "2.1.7", 2448 + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", 2449 + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", 2450 + "dependencies": { 2451 + "@radix-ui/react-primitive": "2.1.3" 2452 + }, 2453 + "peerDependencies": { 2454 + "@types/react": "*", 2455 + "@types/react-dom": "*", 2456 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2457 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2458 + }, 2459 + "peerDependenciesMeta": { 2460 + "@types/react": { 2461 + "optional": true 2462 + }, 2463 + "@types/react-dom": { 2464 + "optional": true 2465 + } 2466 + } 2467 + }, 2468 + "node_modules/@radix-ui/react-menu": { 2469 + "version": "2.1.16", 2470 + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", 2471 + "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", 2472 + "dependencies": { 2473 + "@radix-ui/primitive": "1.1.3", 2474 + "@radix-ui/react-collection": "1.1.7", 2475 + "@radix-ui/react-compose-refs": "1.1.2", 2476 + "@radix-ui/react-context": "1.1.2", 2477 + "@radix-ui/react-direction": "1.1.1", 2478 + "@radix-ui/react-dismissable-layer": "1.1.11", 2479 + "@radix-ui/react-focus-guards": "1.1.3", 2480 + "@radix-ui/react-focus-scope": "1.1.7", 2481 + "@radix-ui/react-id": "1.1.1", 2482 + "@radix-ui/react-popper": "1.2.8", 2483 + "@radix-ui/react-portal": "1.1.9", 2484 + "@radix-ui/react-presence": "1.1.5", 2485 + "@radix-ui/react-primitive": "2.1.3", 2486 + "@radix-ui/react-roving-focus": "1.1.11", 2487 + "@radix-ui/react-slot": "1.2.3", 2488 + "@radix-ui/react-use-callback-ref": "1.1.1", 2489 + "aria-hidden": "^1.2.4", 2490 + "react-remove-scroll": "^2.6.3" 2491 + }, 2492 + "peerDependencies": { 2493 + "@types/react": "*", 2494 + "@types/react-dom": "*", 2495 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2496 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2497 + }, 2498 + "peerDependenciesMeta": { 2499 + "@types/react": { 2500 + "optional": true 2501 + }, 2502 + "@types/react-dom": { 2503 + "optional": true 2504 + } 2505 + } 2506 + }, 2507 + "node_modules/@radix-ui/react-menubar": { 2508 + "version": "1.1.16", 2509 + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.16.tgz", 2510 + "integrity": "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==", 2511 + "dependencies": { 2512 + "@radix-ui/primitive": "1.1.3", 2513 + "@radix-ui/react-collection": "1.1.7", 2514 + "@radix-ui/react-compose-refs": "1.1.2", 2515 + "@radix-ui/react-context": "1.1.2", 2516 + "@radix-ui/react-direction": "1.1.1", 2517 + "@radix-ui/react-id": "1.1.1", 2518 + "@radix-ui/react-menu": "2.1.16", 2519 + "@radix-ui/react-primitive": "2.1.3", 2520 + "@radix-ui/react-roving-focus": "1.1.11", 2521 + "@radix-ui/react-use-controllable-state": "1.2.2" 2522 + }, 2523 + "peerDependencies": { 2524 + "@types/react": "*", 2525 + "@types/react-dom": "*", 2526 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2527 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2528 + }, 2529 + "peerDependenciesMeta": { 2530 + "@types/react": { 2531 + "optional": true 2532 + }, 2533 + "@types/react-dom": { 2534 + "optional": true 2535 + } 2536 + } 2537 + }, 2538 + "node_modules/@radix-ui/react-navigation-menu": { 2539 + "version": "1.2.14", 2540 + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.14.tgz", 2541 + "integrity": "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==", 2542 + "dependencies": { 2543 + "@radix-ui/primitive": "1.1.3", 2544 + "@radix-ui/react-collection": "1.1.7", 2545 + "@radix-ui/react-compose-refs": "1.1.2", 2546 + "@radix-ui/react-context": "1.1.2", 2547 + "@radix-ui/react-direction": "1.1.1", 2548 + "@radix-ui/react-dismissable-layer": "1.1.11", 2549 + "@radix-ui/react-id": "1.1.1", 2550 + "@radix-ui/react-presence": "1.1.5", 2551 + "@radix-ui/react-primitive": "2.1.3", 2552 + "@radix-ui/react-use-callback-ref": "1.1.1", 2553 + "@radix-ui/react-use-controllable-state": "1.2.2", 2554 + "@radix-ui/react-use-layout-effect": "1.1.1", 2555 + "@radix-ui/react-use-previous": "1.1.1", 2556 + "@radix-ui/react-visually-hidden": "1.2.3" 2557 + }, 2558 + "peerDependencies": { 2559 + "@types/react": "*", 2560 + "@types/react-dom": "*", 2561 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2562 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2563 + }, 2564 + "peerDependenciesMeta": { 2565 + "@types/react": { 2566 + "optional": true 2567 + }, 2568 + "@types/react-dom": { 2569 + "optional": true 2570 + } 2571 + } 2572 + }, 2573 + "node_modules/@radix-ui/react-one-time-password-field": { 2574 + "version": "0.1.8", 2575 + "resolved": "https://registry.npmjs.org/@radix-ui/react-one-time-password-field/-/react-one-time-password-field-0.1.8.tgz", 2576 + "integrity": "sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg==", 2577 + "dependencies": { 2578 + "@radix-ui/number": "1.1.1", 2579 + "@radix-ui/primitive": "1.1.3", 2580 + "@radix-ui/react-collection": "1.1.7", 2581 + "@radix-ui/react-compose-refs": "1.1.2", 2582 + "@radix-ui/react-context": "1.1.2", 2583 + "@radix-ui/react-direction": "1.1.1", 2584 + "@radix-ui/react-primitive": "2.1.3", 2585 + "@radix-ui/react-roving-focus": "1.1.11", 2586 + "@radix-ui/react-use-controllable-state": "1.2.2", 2587 + "@radix-ui/react-use-effect-event": "0.0.2", 2588 + "@radix-ui/react-use-is-hydrated": "0.1.0", 2589 + "@radix-ui/react-use-layout-effect": "1.1.1" 2590 + }, 2591 + "peerDependencies": { 2592 + "@types/react": "*", 2593 + "@types/react-dom": "*", 2594 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2595 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2596 + }, 2597 + "peerDependenciesMeta": { 2598 + "@types/react": { 2599 + "optional": true 2600 + }, 2601 + "@types/react-dom": { 2602 + "optional": true 2603 + } 2604 + } 2605 + }, 2606 + "node_modules/@radix-ui/react-password-toggle-field": { 2607 + "version": "0.1.3", 2608 + "resolved": "https://registry.npmjs.org/@radix-ui/react-password-toggle-field/-/react-password-toggle-field-0.1.3.tgz", 2609 + "integrity": "sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw==", 2610 + "dependencies": { 2611 + "@radix-ui/primitive": "1.1.3", 2612 + "@radix-ui/react-compose-refs": "1.1.2", 2613 + "@radix-ui/react-context": "1.1.2", 2614 + "@radix-ui/react-id": "1.1.1", 2615 + "@radix-ui/react-primitive": "2.1.3", 2616 + "@radix-ui/react-use-controllable-state": "1.2.2", 2617 + "@radix-ui/react-use-effect-event": "0.0.2", 2618 + "@radix-ui/react-use-is-hydrated": "0.1.0" 2619 + }, 2620 + "peerDependencies": { 2621 + "@types/react": "*", 2622 + "@types/react-dom": "*", 2623 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2624 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2625 + }, 2626 + "peerDependenciesMeta": { 2627 + "@types/react": { 2628 + "optional": true 2629 + }, 2630 + "@types/react-dom": { 2631 + "optional": true 2632 + } 2633 + } 2634 + }, 2635 + "node_modules/@radix-ui/react-popover": { 2636 + "version": "1.1.15", 2637 + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", 2638 + "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", 2639 + "dependencies": { 2640 + "@radix-ui/primitive": "1.1.3", 2641 + "@radix-ui/react-compose-refs": "1.1.2", 2642 + "@radix-ui/react-context": "1.1.2", 2643 + "@radix-ui/react-dismissable-layer": "1.1.11", 2644 + "@radix-ui/react-focus-guards": "1.1.3", 2645 + "@radix-ui/react-focus-scope": "1.1.7", 2646 + "@radix-ui/react-id": "1.1.1", 2647 + "@radix-ui/react-popper": "1.2.8", 2648 + "@radix-ui/react-portal": "1.1.9", 2649 + "@radix-ui/react-presence": "1.1.5", 2650 + "@radix-ui/react-primitive": "2.1.3", 2651 + "@radix-ui/react-slot": "1.2.3", 2652 + "@radix-ui/react-use-controllable-state": "1.2.2", 2653 + "aria-hidden": "^1.2.4", 2654 + "react-remove-scroll": "^2.6.3" 2655 + }, 2656 + "peerDependencies": { 2657 + "@types/react": "*", 2658 + "@types/react-dom": "*", 2659 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2660 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2661 + }, 2662 + "peerDependenciesMeta": { 2663 + "@types/react": { 2664 + "optional": true 2665 + }, 2666 + "@types/react-dom": { 2667 + "optional": true 2668 + } 2669 + } 2670 + }, 2671 + "node_modules/@radix-ui/react-popper": { 2672 + "version": "1.2.8", 2673 + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", 2674 + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", 2675 + "dependencies": { 2676 + "@floating-ui/react-dom": "^2.0.0", 2677 + "@radix-ui/react-arrow": "1.1.7", 2678 + "@radix-ui/react-compose-refs": "1.1.2", 2679 + "@radix-ui/react-context": "1.1.2", 2680 + "@radix-ui/react-primitive": "2.1.3", 2681 + "@radix-ui/react-use-callback-ref": "1.1.1", 2682 + "@radix-ui/react-use-layout-effect": "1.1.1", 2683 + "@radix-ui/react-use-rect": "1.1.1", 2684 + "@radix-ui/react-use-size": "1.1.1", 2685 + "@radix-ui/rect": "1.1.1" 2686 + }, 2687 + "peerDependencies": { 2688 + "@types/react": "*", 2689 + "@types/react-dom": "*", 2690 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2691 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2692 + }, 2693 + "peerDependenciesMeta": { 2694 + "@types/react": { 2695 + "optional": true 2696 + }, 2697 + "@types/react-dom": { 2698 + "optional": true 2699 + } 2700 + } 2701 + }, 2702 + "node_modules/@radix-ui/react-portal": { 2703 + "version": "1.1.9", 2704 + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", 2705 + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", 2706 + "dependencies": { 2707 + "@radix-ui/react-primitive": "2.1.3", 2708 + "@radix-ui/react-use-layout-effect": "1.1.1" 2709 + }, 2710 + "peerDependencies": { 2711 + "@types/react": "*", 2712 + "@types/react-dom": "*", 2713 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2714 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2715 + }, 2716 + "peerDependenciesMeta": { 2717 + "@types/react": { 2718 + "optional": true 2719 + }, 2720 + "@types/react-dom": { 2721 + "optional": true 2722 + } 2723 + } 2724 + }, 2725 + "node_modules/@radix-ui/react-presence": { 2726 + "version": "1.1.5", 2727 + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", 2728 + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", 2729 + "dependencies": { 2730 + "@radix-ui/react-compose-refs": "1.1.2", 2731 + "@radix-ui/react-use-layout-effect": "1.1.1" 2732 + }, 2733 + "peerDependencies": { 2734 + "@types/react": "*", 2735 + "@types/react-dom": "*", 2736 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2737 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2738 + }, 2739 + "peerDependenciesMeta": { 2740 + "@types/react": { 2741 + "optional": true 2742 + }, 2743 + "@types/react-dom": { 2744 + "optional": true 2745 + } 2746 + } 2747 + }, 2748 + "node_modules/@radix-ui/react-primitive": { 2749 + "version": "2.1.3", 2750 + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", 2751 + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", 2752 + "dependencies": { 2753 + "@radix-ui/react-slot": "1.2.3" 2754 + }, 2755 + "peerDependencies": { 2756 + "@types/react": "*", 2757 + "@types/react-dom": "*", 2758 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2759 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2760 + }, 2761 + "peerDependenciesMeta": { 2762 + "@types/react": { 2763 + "optional": true 2764 + }, 2765 + "@types/react-dom": { 2766 + "optional": true 2767 + } 2768 + } 2769 + }, 2770 + "node_modules/@radix-ui/react-progress": { 2771 + "version": "1.1.7", 2772 + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz", 2773 + "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==", 2774 + "dependencies": { 2775 + "@radix-ui/react-context": "1.1.2", 2776 + "@radix-ui/react-primitive": "2.1.3" 2777 + }, 2778 + "peerDependencies": { 2779 + "@types/react": "*", 2780 + "@types/react-dom": "*", 2781 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2782 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2783 + }, 2784 + "peerDependenciesMeta": { 2785 + "@types/react": { 2786 + "optional": true 2787 + }, 2788 + "@types/react-dom": { 2789 + "optional": true 2790 + } 2791 + } 2792 + }, 2793 + "node_modules/@radix-ui/react-radio-group": { 2794 + "version": "1.3.8", 2795 + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", 2796 + "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", 2797 + "dependencies": { 2798 + "@radix-ui/primitive": "1.1.3", 2799 + "@radix-ui/react-compose-refs": "1.1.2", 2800 + "@radix-ui/react-context": "1.1.2", 2801 + "@radix-ui/react-direction": "1.1.1", 2802 + "@radix-ui/react-presence": "1.1.5", 2803 + "@radix-ui/react-primitive": "2.1.3", 2804 + "@radix-ui/react-roving-focus": "1.1.11", 2805 + "@radix-ui/react-use-controllable-state": "1.2.2", 2806 + "@radix-ui/react-use-previous": "1.1.1", 2807 + "@radix-ui/react-use-size": "1.1.1" 2808 + }, 2809 + "peerDependencies": { 2810 + "@types/react": "*", 2811 + "@types/react-dom": "*", 2812 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2813 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2814 + }, 2815 + "peerDependenciesMeta": { 2816 + "@types/react": { 2817 + "optional": true 2818 + }, 2819 + "@types/react-dom": { 2820 + "optional": true 2821 + } 2822 + } 2823 + }, 2824 + "node_modules/@radix-ui/react-roving-focus": { 2825 + "version": "1.1.11", 2826 + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", 2827 + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", 2828 + "dependencies": { 2829 + "@radix-ui/primitive": "1.1.3", 2830 + "@radix-ui/react-collection": "1.1.7", 2831 + "@radix-ui/react-compose-refs": "1.1.2", 2832 + "@radix-ui/react-context": "1.1.2", 2833 + "@radix-ui/react-direction": "1.1.1", 2834 + "@radix-ui/react-id": "1.1.1", 2835 + "@radix-ui/react-primitive": "2.1.3", 2836 + "@radix-ui/react-use-callback-ref": "1.1.1", 2837 + "@radix-ui/react-use-controllable-state": "1.2.2" 2838 + }, 2839 + "peerDependencies": { 2840 + "@types/react": "*", 2841 + "@types/react-dom": "*", 2842 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2843 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2844 + }, 2845 + "peerDependenciesMeta": { 2846 + "@types/react": { 2847 + "optional": true 2848 + }, 2849 + "@types/react-dom": { 2850 + "optional": true 2851 + } 2852 + } 2853 + }, 2854 + "node_modules/@radix-ui/react-scroll-area": { 2855 + "version": "1.2.10", 2856 + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", 2857 + "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", 2858 + "dependencies": { 2859 + "@radix-ui/number": "1.1.1", 2860 + "@radix-ui/primitive": "1.1.3", 2861 + "@radix-ui/react-compose-refs": "1.1.2", 2862 + "@radix-ui/react-context": "1.1.2", 2863 + "@radix-ui/react-direction": "1.1.1", 2864 + "@radix-ui/react-presence": "1.1.5", 2865 + "@radix-ui/react-primitive": "2.1.3", 2866 + "@radix-ui/react-use-callback-ref": "1.1.1", 2867 + "@radix-ui/react-use-layout-effect": "1.1.1" 2868 + }, 2869 + "peerDependencies": { 2870 + "@types/react": "*", 2871 + "@types/react-dom": "*", 2872 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2873 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2874 + }, 2875 + "peerDependenciesMeta": { 2876 + "@types/react": { 2877 + "optional": true 2878 + }, 2879 + "@types/react-dom": { 2880 + "optional": true 2881 + } 2882 + } 2883 + }, 2884 + "node_modules/@radix-ui/react-select": { 2885 + "version": "2.2.6", 2886 + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", 2887 + "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", 2888 + "dependencies": { 2889 + "@radix-ui/number": "1.1.1", 2890 + "@radix-ui/primitive": "1.1.3", 2891 + "@radix-ui/react-collection": "1.1.7", 2892 + "@radix-ui/react-compose-refs": "1.1.2", 2893 + "@radix-ui/react-context": "1.1.2", 2894 + "@radix-ui/react-direction": "1.1.1", 2895 + "@radix-ui/react-dismissable-layer": "1.1.11", 2896 + "@radix-ui/react-focus-guards": "1.1.3", 2897 + "@radix-ui/react-focus-scope": "1.1.7", 2898 + "@radix-ui/react-id": "1.1.1", 2899 + "@radix-ui/react-popper": "1.2.8", 2900 + "@radix-ui/react-portal": "1.1.9", 2901 + "@radix-ui/react-primitive": "2.1.3", 2902 + "@radix-ui/react-slot": "1.2.3", 2903 + "@radix-ui/react-use-callback-ref": "1.1.1", 2904 + "@radix-ui/react-use-controllable-state": "1.2.2", 2905 + "@radix-ui/react-use-layout-effect": "1.1.1", 2906 + "@radix-ui/react-use-previous": "1.1.1", 2907 + "@radix-ui/react-visually-hidden": "1.2.3", 2908 + "aria-hidden": "^1.2.4", 2909 + "react-remove-scroll": "^2.6.3" 2910 + }, 2911 + "peerDependencies": { 2912 + "@types/react": "*", 2913 + "@types/react-dom": "*", 2914 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2915 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2916 + }, 2917 + "peerDependenciesMeta": { 2918 + "@types/react": { 2919 + "optional": true 2920 + }, 2921 + "@types/react-dom": { 2922 + "optional": true 2923 + } 2924 + } 2925 + }, 2926 + "node_modules/@radix-ui/react-separator": { 2927 + "version": "1.1.7", 2928 + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", 2929 + "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", 2930 + "dependencies": { 2931 + "@radix-ui/react-primitive": "2.1.3" 2932 + }, 2933 + "peerDependencies": { 2934 + "@types/react": "*", 2935 + "@types/react-dom": "*", 2936 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2937 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2938 + }, 2939 + "peerDependenciesMeta": { 2940 + "@types/react": { 2941 + "optional": true 2942 + }, 2943 + "@types/react-dom": { 2944 + "optional": true 2945 + } 2946 + } 2947 + }, 2948 + "node_modules/@radix-ui/react-slider": { 2949 + "version": "1.3.6", 2950 + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz", 2951 + "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==", 2952 + "dependencies": { 2953 + "@radix-ui/number": "1.1.1", 2954 + "@radix-ui/primitive": "1.1.3", 2955 + "@radix-ui/react-collection": "1.1.7", 2956 + "@radix-ui/react-compose-refs": "1.1.2", 2957 + "@radix-ui/react-context": "1.1.2", 2958 + "@radix-ui/react-direction": "1.1.1", 2959 + "@radix-ui/react-primitive": "2.1.3", 2960 + "@radix-ui/react-use-controllable-state": "1.2.2", 2961 + "@radix-ui/react-use-layout-effect": "1.1.1", 2962 + "@radix-ui/react-use-previous": "1.1.1", 2963 + "@radix-ui/react-use-size": "1.1.1" 2964 + }, 2965 + "peerDependencies": { 2966 + "@types/react": "*", 2967 + "@types/react-dom": "*", 2968 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2969 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2970 + }, 2971 + "peerDependenciesMeta": { 2972 + "@types/react": { 2973 + "optional": true 2974 + }, 2975 + "@types/react-dom": { 2976 + "optional": true 2977 + } 2978 + } 2979 + }, 2980 + "node_modules/@radix-ui/react-slot": { 2981 + "version": "1.2.3", 2982 + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", 2983 + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", 2984 + "dependencies": { 2985 + "@radix-ui/react-compose-refs": "1.1.2" 2986 + }, 2987 + "peerDependencies": { 2988 + "@types/react": "*", 2989 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2990 + }, 2991 + "peerDependenciesMeta": { 2992 + "@types/react": { 2993 + "optional": true 2994 + } 2995 + } 2996 + }, 2997 + "node_modules/@radix-ui/react-switch": { 2998 + "version": "1.2.6", 2999 + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", 3000 + "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", 3001 + "dependencies": { 3002 + "@radix-ui/primitive": "1.1.3", 3003 + "@radix-ui/react-compose-refs": "1.1.2", 3004 + "@radix-ui/react-context": "1.1.2", 3005 + "@radix-ui/react-primitive": "2.1.3", 3006 + "@radix-ui/react-use-controllable-state": "1.2.2", 3007 + "@radix-ui/react-use-previous": "1.1.1", 3008 + "@radix-ui/react-use-size": "1.1.1" 3009 + }, 3010 + "peerDependencies": { 3011 + "@types/react": "*", 3012 + "@types/react-dom": "*", 3013 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3014 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3015 + }, 3016 + "peerDependenciesMeta": { 3017 + "@types/react": { 3018 + "optional": true 3019 + }, 3020 + "@types/react-dom": { 3021 + "optional": true 3022 + } 3023 + } 3024 + }, 3025 + "node_modules/@radix-ui/react-tabs": { 3026 + "version": "1.1.13", 3027 + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", 3028 + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", 3029 + "dependencies": { 3030 + "@radix-ui/primitive": "1.1.3", 3031 + "@radix-ui/react-context": "1.1.2", 3032 + "@radix-ui/react-direction": "1.1.1", 3033 + "@radix-ui/react-id": "1.1.1", 3034 + "@radix-ui/react-presence": "1.1.5", 3035 + "@radix-ui/react-primitive": "2.1.3", 3036 + "@radix-ui/react-roving-focus": "1.1.11", 3037 + "@radix-ui/react-use-controllable-state": "1.2.2" 3038 + }, 3039 + "peerDependencies": { 3040 + "@types/react": "*", 3041 + "@types/react-dom": "*", 3042 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3043 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3044 + }, 3045 + "peerDependenciesMeta": { 3046 + "@types/react": { 3047 + "optional": true 3048 + }, 3049 + "@types/react-dom": { 3050 + "optional": true 3051 + } 3052 + } 3053 + }, 3054 + "node_modules/@radix-ui/react-toast": { 3055 + "version": "1.2.15", 3056 + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.15.tgz", 3057 + "integrity": "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==", 3058 + "dependencies": { 3059 + "@radix-ui/primitive": "1.1.3", 3060 + "@radix-ui/react-collection": "1.1.7", 3061 + "@radix-ui/react-compose-refs": "1.1.2", 3062 + "@radix-ui/react-context": "1.1.2", 3063 + "@radix-ui/react-dismissable-layer": "1.1.11", 3064 + "@radix-ui/react-portal": "1.1.9", 3065 + "@radix-ui/react-presence": "1.1.5", 3066 + "@radix-ui/react-primitive": "2.1.3", 3067 + "@radix-ui/react-use-callback-ref": "1.1.1", 3068 + "@radix-ui/react-use-controllable-state": "1.2.2", 3069 + "@radix-ui/react-use-layout-effect": "1.1.1", 3070 + "@radix-ui/react-visually-hidden": "1.2.3" 3071 + }, 3072 + "peerDependencies": { 3073 + "@types/react": "*", 3074 + "@types/react-dom": "*", 3075 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3076 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3077 + }, 3078 + "peerDependenciesMeta": { 3079 + "@types/react": { 3080 + "optional": true 3081 + }, 3082 + "@types/react-dom": { 3083 + "optional": true 3084 + } 3085 + } 3086 + }, 3087 + "node_modules/@radix-ui/react-toggle": { 3088 + "version": "1.1.10", 3089 + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", 3090 + "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", 3091 + "dependencies": { 3092 + "@radix-ui/primitive": "1.1.3", 3093 + "@radix-ui/react-primitive": "2.1.3", 3094 + "@radix-ui/react-use-controllable-state": "1.2.2" 3095 + }, 3096 + "peerDependencies": { 3097 + "@types/react": "*", 3098 + "@types/react-dom": "*", 3099 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3100 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3101 + }, 3102 + "peerDependenciesMeta": { 3103 + "@types/react": { 3104 + "optional": true 3105 + }, 3106 + "@types/react-dom": { 3107 + "optional": true 3108 + } 3109 + } 3110 + }, 3111 + "node_modules/@radix-ui/react-toggle-group": { 3112 + "version": "1.1.11", 3113 + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz", 3114 + "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==", 3115 + "dependencies": { 3116 + "@radix-ui/primitive": "1.1.3", 3117 + "@radix-ui/react-context": "1.1.2", 3118 + "@radix-ui/react-direction": "1.1.1", 3119 + "@radix-ui/react-primitive": "2.1.3", 3120 + "@radix-ui/react-roving-focus": "1.1.11", 3121 + "@radix-ui/react-toggle": "1.1.10", 3122 + "@radix-ui/react-use-controllable-state": "1.2.2" 3123 + }, 3124 + "peerDependencies": { 3125 + "@types/react": "*", 3126 + "@types/react-dom": "*", 3127 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3128 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3129 + }, 3130 + "peerDependenciesMeta": { 3131 + "@types/react": { 3132 + "optional": true 3133 + }, 3134 + "@types/react-dom": { 3135 + "optional": true 3136 + } 3137 + } 3138 + }, 3139 + "node_modules/@radix-ui/react-toolbar": { 3140 + "version": "1.1.11", 3141 + "resolved": "https://registry.npmjs.org/@radix-ui/react-toolbar/-/react-toolbar-1.1.11.tgz", 3142 + "integrity": "sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==", 3143 + "dependencies": { 3144 + "@radix-ui/primitive": "1.1.3", 3145 + "@radix-ui/react-context": "1.1.2", 3146 + "@radix-ui/react-direction": "1.1.1", 3147 + "@radix-ui/react-primitive": "2.1.3", 3148 + "@radix-ui/react-roving-focus": "1.1.11", 3149 + "@radix-ui/react-separator": "1.1.7", 3150 + "@radix-ui/react-toggle-group": "1.1.11" 3151 + }, 3152 + "peerDependencies": { 3153 + "@types/react": "*", 3154 + "@types/react-dom": "*", 3155 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3156 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3157 + }, 3158 + "peerDependenciesMeta": { 3159 + "@types/react": { 3160 + "optional": true 3161 + }, 3162 + "@types/react-dom": { 3163 + "optional": true 3164 + } 3165 + } 3166 + }, 3167 + "node_modules/@radix-ui/react-tooltip": { 3168 + "version": "1.2.8", 3169 + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", 3170 + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", 3171 + "dependencies": { 3172 + "@radix-ui/primitive": "1.1.3", 3173 + "@radix-ui/react-compose-refs": "1.1.2", 3174 + "@radix-ui/react-context": "1.1.2", 3175 + "@radix-ui/react-dismissable-layer": "1.1.11", 3176 + "@radix-ui/react-id": "1.1.1", 3177 + "@radix-ui/react-popper": "1.2.8", 3178 + "@radix-ui/react-portal": "1.1.9", 3179 + "@radix-ui/react-presence": "1.1.5", 3180 + "@radix-ui/react-primitive": "2.1.3", 3181 + "@radix-ui/react-slot": "1.2.3", 3182 + "@radix-ui/react-use-controllable-state": "1.2.2", 3183 + "@radix-ui/react-visually-hidden": "1.2.3" 3184 + }, 3185 + "peerDependencies": { 3186 + "@types/react": "*", 3187 + "@types/react-dom": "*", 3188 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3189 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3190 + }, 3191 + "peerDependenciesMeta": { 3192 + "@types/react": { 3193 + "optional": true 3194 + }, 3195 + "@types/react-dom": { 3196 + "optional": true 3197 + } 3198 + } 3199 + }, 3200 + "node_modules/@radix-ui/react-use-callback-ref": { 3201 + "version": "1.1.1", 3202 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", 3203 + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", 3204 + "peerDependencies": { 3205 + "@types/react": "*", 3206 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3207 + }, 3208 + "peerDependenciesMeta": { 3209 + "@types/react": { 3210 + "optional": true 3211 + } 3212 + } 3213 + }, 3214 + "node_modules/@radix-ui/react-use-controllable-state": { 3215 + "version": "1.2.2", 3216 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", 3217 + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", 3218 + "dependencies": { 3219 + "@radix-ui/react-use-effect-event": "0.0.2", 3220 + "@radix-ui/react-use-layout-effect": "1.1.1" 3221 + }, 3222 + "peerDependencies": { 3223 + "@types/react": "*", 3224 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3225 + }, 3226 + "peerDependenciesMeta": { 3227 + "@types/react": { 3228 + "optional": true 3229 + } 3230 + } 3231 + }, 3232 + "node_modules/@radix-ui/react-use-effect-event": { 3233 + "version": "0.0.2", 3234 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", 3235 + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", 3236 + "dependencies": { 3237 + "@radix-ui/react-use-layout-effect": "1.1.1" 3238 + }, 3239 + "peerDependencies": { 3240 + "@types/react": "*", 3241 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3242 + }, 3243 + "peerDependenciesMeta": { 3244 + "@types/react": { 3245 + "optional": true 3246 + } 3247 + } 3248 + }, 3249 + "node_modules/@radix-ui/react-use-escape-keydown": { 3250 + "version": "1.1.1", 3251 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", 3252 + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", 3253 + "dependencies": { 3254 + "@radix-ui/react-use-callback-ref": "1.1.1" 3255 + }, 3256 + "peerDependencies": { 3257 + "@types/react": "*", 3258 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3259 + }, 3260 + "peerDependenciesMeta": { 3261 + "@types/react": { 3262 + "optional": true 3263 + } 3264 + } 3265 + }, 3266 + "node_modules/@radix-ui/react-use-is-hydrated": { 3267 + "version": "0.1.0", 3268 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", 3269 + "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", 3270 + "dependencies": { 3271 + "use-sync-external-store": "^1.5.0" 3272 + }, 3273 + "peerDependencies": { 3274 + "@types/react": "*", 3275 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3276 + }, 3277 + "peerDependenciesMeta": { 3278 + "@types/react": { 3279 + "optional": true 3280 + } 3281 + } 3282 + }, 3283 + "node_modules/@radix-ui/react-use-layout-effect": { 3284 + "version": "1.1.1", 3285 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", 3286 + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", 3287 + "peerDependencies": { 3288 + "@types/react": "*", 3289 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3290 + }, 3291 + "peerDependenciesMeta": { 3292 + "@types/react": { 3293 + "optional": true 3294 + } 3295 + } 3296 + }, 3297 + "node_modules/@radix-ui/react-use-previous": { 3298 + "version": "1.1.1", 3299 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", 3300 + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", 3301 + "peerDependencies": { 3302 + "@types/react": "*", 3303 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3304 + }, 3305 + "peerDependenciesMeta": { 3306 + "@types/react": { 3307 + "optional": true 3308 + } 3309 + } 3310 + }, 3311 + "node_modules/@radix-ui/react-use-rect": { 3312 + "version": "1.1.1", 3313 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", 3314 + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", 3315 + "dependencies": { 3316 + "@radix-ui/rect": "1.1.1" 3317 + }, 3318 + "peerDependencies": { 3319 + "@types/react": "*", 3320 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3321 + }, 3322 + "peerDependenciesMeta": { 3323 + "@types/react": { 3324 + "optional": true 3325 + } 3326 + } 3327 + }, 3328 + "node_modules/@radix-ui/react-use-size": { 3329 + "version": "1.1.1", 3330 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", 3331 + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", 3332 + "dependencies": { 3333 + "@radix-ui/react-use-layout-effect": "1.1.1" 3334 + }, 3335 + "peerDependencies": { 3336 + "@types/react": "*", 3337 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3338 + }, 3339 + "peerDependenciesMeta": { 3340 + "@types/react": { 3341 + "optional": true 3342 + } 3343 + } 3344 + }, 3345 + "node_modules/@radix-ui/react-visually-hidden": { 3346 + "version": "1.2.3", 3347 + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", 3348 + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", 3349 + "dependencies": { 3350 + "@radix-ui/react-primitive": "2.1.3" 3351 + }, 3352 + "peerDependencies": { 3353 + "@types/react": "*", 3354 + "@types/react-dom": "*", 3355 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3356 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3357 + }, 3358 + "peerDependenciesMeta": { 3359 + "@types/react": { 3360 + "optional": true 3361 + }, 3362 + "@types/react-dom": { 3363 + "optional": true 3364 + } 3365 + } 3366 + }, 3367 + "node_modules/@radix-ui/rect": { 3368 + "version": "1.1.1", 3369 + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", 3370 + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==" 3371 + }, 1898 3372 "node_modules/@rolldown/pluginutils": { 1899 3373 "version": "1.0.0-beta.27", 1900 3374 "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", ··· 3806 5280 "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 3807 5281 "dev": true, 3808 5282 "license": "Python-2.0" 5283 + }, 5284 + "node_modules/aria-hidden": { 5285 + "version": "1.2.6", 5286 + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", 5287 + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", 5288 + "dependencies": { 5289 + "tslib": "^2.0.0" 5290 + }, 5291 + "engines": { 5292 + "node": ">=10" 5293 + } 3809 5294 }, 3810 5295 "node_modules/aria-query": { 3811 5296 "version": "5.3.0", ··· 4716 6201 "node": ">=8" 4717 6202 } 4718 6203 }, 6204 + "node_modules/detect-node-es": { 6205 + "version": "1.1.0", 6206 + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", 6207 + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" 6208 + }, 4719 6209 "node_modules/diff": { 4720 6210 "version": "8.0.2", 4721 6211 "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", ··· 5735 7225 }, 5736 7226 "funding": { 5737 7227 "url": "https://github.com/sponsors/ljharb" 7228 + } 7229 + }, 7230 + "node_modules/get-nonce": { 7231 + "version": "1.0.1", 7232 + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", 7233 + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", 7234 + "engines": { 7235 + "node": ">=6" 5738 7236 } 5739 7237 }, 5740 7238 "node_modules/get-proto": { ··· 10338 11836 ], 10339 11837 "license": "MIT" 10340 11838 }, 11839 + "node_modules/radix-ui": { 11840 + "version": "1.4.3", 11841 + "resolved": "https://registry.npmjs.org/radix-ui/-/radix-ui-1.4.3.tgz", 11842 + "integrity": "sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==", 11843 + "dependencies": { 11844 + "@radix-ui/primitive": "1.1.3", 11845 + "@radix-ui/react-accessible-icon": "1.1.7", 11846 + "@radix-ui/react-accordion": "1.2.12", 11847 + "@radix-ui/react-alert-dialog": "1.1.15", 11848 + "@radix-ui/react-arrow": "1.1.7", 11849 + "@radix-ui/react-aspect-ratio": "1.1.7", 11850 + "@radix-ui/react-avatar": "1.1.10", 11851 + "@radix-ui/react-checkbox": "1.3.3", 11852 + "@radix-ui/react-collapsible": "1.1.12", 11853 + "@radix-ui/react-collection": "1.1.7", 11854 + "@radix-ui/react-compose-refs": "1.1.2", 11855 + "@radix-ui/react-context": "1.1.2", 11856 + "@radix-ui/react-context-menu": "2.2.16", 11857 + "@radix-ui/react-dialog": "1.1.15", 11858 + "@radix-ui/react-direction": "1.1.1", 11859 + "@radix-ui/react-dismissable-layer": "1.1.11", 11860 + "@radix-ui/react-dropdown-menu": "2.1.16", 11861 + "@radix-ui/react-focus-guards": "1.1.3", 11862 + "@radix-ui/react-focus-scope": "1.1.7", 11863 + "@radix-ui/react-form": "0.1.8", 11864 + "@radix-ui/react-hover-card": "1.1.15", 11865 + "@radix-ui/react-label": "2.1.7", 11866 + "@radix-ui/react-menu": "2.1.16", 11867 + "@radix-ui/react-menubar": "1.1.16", 11868 + "@radix-ui/react-navigation-menu": "1.2.14", 11869 + "@radix-ui/react-one-time-password-field": "0.1.8", 11870 + "@radix-ui/react-password-toggle-field": "0.1.3", 11871 + "@radix-ui/react-popover": "1.1.15", 11872 + "@radix-ui/react-popper": "1.2.8", 11873 + "@radix-ui/react-portal": "1.1.9", 11874 + "@radix-ui/react-presence": "1.1.5", 11875 + "@radix-ui/react-primitive": "2.1.3", 11876 + "@radix-ui/react-progress": "1.1.7", 11877 + "@radix-ui/react-radio-group": "1.3.8", 11878 + "@radix-ui/react-roving-focus": "1.1.11", 11879 + "@radix-ui/react-scroll-area": "1.2.10", 11880 + "@radix-ui/react-select": "2.2.6", 11881 + "@radix-ui/react-separator": "1.1.7", 11882 + "@radix-ui/react-slider": "1.3.6", 11883 + "@radix-ui/react-slot": "1.2.3", 11884 + "@radix-ui/react-switch": "1.2.6", 11885 + "@radix-ui/react-tabs": "1.1.13", 11886 + "@radix-ui/react-toast": "1.2.15", 11887 + "@radix-ui/react-toggle": "1.1.10", 11888 + "@radix-ui/react-toggle-group": "1.1.11", 11889 + "@radix-ui/react-toolbar": "1.1.11", 11890 + "@radix-ui/react-tooltip": "1.2.8", 11891 + "@radix-ui/react-use-callback-ref": "1.1.1", 11892 + "@radix-ui/react-use-controllable-state": "1.2.2", 11893 + "@radix-ui/react-use-effect-event": "0.0.2", 11894 + "@radix-ui/react-use-escape-keydown": "1.1.1", 11895 + "@radix-ui/react-use-is-hydrated": "0.1.0", 11896 + "@radix-ui/react-use-layout-effect": "1.1.1", 11897 + "@radix-ui/react-use-size": "1.1.1", 11898 + "@radix-ui/react-visually-hidden": "1.2.3" 11899 + }, 11900 + "peerDependencies": { 11901 + "@types/react": "*", 11902 + "@types/react-dom": "*", 11903 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 11904 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 11905 + }, 11906 + "peerDependenciesMeta": { 11907 + "@types/react": { 11908 + "optional": true 11909 + }, 11910 + "@types/react-dom": { 11911 + "optional": true 11912 + } 11913 + } 11914 + }, 10341 11915 "node_modules/react": { 10342 11916 "version": "19.1.1", 10343 11917 "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", ··· 10399 11973 "node": ">=0.10.0" 10400 11974 } 10401 11975 }, 11976 + "node_modules/react-remove-scroll": { 11977 + "version": "2.7.1", 11978 + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", 11979 + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", 11980 + "dependencies": { 11981 + "react-remove-scroll-bar": "^2.3.7", 11982 + "react-style-singleton": "^2.2.3", 11983 + "tslib": "^2.1.0", 11984 + "use-callback-ref": "^1.3.3", 11985 + "use-sidecar": "^1.1.3" 11986 + }, 11987 + "engines": { 11988 + "node": ">=10" 11989 + }, 11990 + "peerDependencies": { 11991 + "@types/react": "*", 11992 + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" 11993 + }, 11994 + "peerDependenciesMeta": { 11995 + "@types/react": { 11996 + "optional": true 11997 + } 11998 + } 11999 + }, 12000 + "node_modules/react-remove-scroll-bar": { 12001 + "version": "2.3.8", 12002 + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", 12003 + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", 12004 + "dependencies": { 12005 + "react-style-singleton": "^2.2.2", 12006 + "tslib": "^2.0.0" 12007 + }, 12008 + "engines": { 12009 + "node": ">=10" 12010 + }, 12011 + "peerDependencies": { 12012 + "@types/react": "*", 12013 + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" 12014 + }, 12015 + "peerDependenciesMeta": { 12016 + "@types/react": { 12017 + "optional": true 12018 + } 12019 + } 12020 + }, 12021 + "node_modules/react-style-singleton": { 12022 + "version": "2.2.3", 12023 + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", 12024 + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", 12025 + "dependencies": { 12026 + "get-nonce": "^1.0.0", 12027 + "tslib": "^2.0.0" 12028 + }, 12029 + "engines": { 12030 + "node": ">=10" 12031 + }, 12032 + "peerDependencies": { 12033 + "@types/react": "*", 12034 + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" 12035 + }, 12036 + "peerDependenciesMeta": { 12037 + "@types/react": { 12038 + "optional": true 12039 + } 12040 + } 12041 + }, 10402 12042 "node_modules/readdirp": { 10403 12043 "version": "3.6.0", 10404 12044 "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", ··· 11892 13532 "peer": true, 11893 13533 "dependencies": { 11894 13534 "punycode": "^2.1.0" 13535 + } 13536 + }, 13537 + "node_modules/use-callback-ref": { 13538 + "version": "1.3.3", 13539 + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", 13540 + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", 13541 + "dependencies": { 13542 + "tslib": "^2.0.0" 13543 + }, 13544 + "engines": { 13545 + "node": ">=10" 13546 + }, 13547 + "peerDependencies": { 13548 + "@types/react": "*", 13549 + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" 13550 + }, 13551 + "peerDependenciesMeta": { 13552 + "@types/react": { 13553 + "optional": true 13554 + } 13555 + } 13556 + }, 13557 + "node_modules/use-sidecar": { 13558 + "version": "1.1.3", 13559 + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", 13560 + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", 13561 + "dependencies": { 13562 + "detect-node-es": "^1.1.0", 13563 + "tslib": "^2.0.0" 13564 + }, 13565 + "engines": { 13566 + "node": ">=10" 13567 + }, 13568 + "peerDependencies": { 13569 + "@types/react": "*", 13570 + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" 13571 + }, 13572 + "peerDependenciesMeta": { 13573 + "@types/react": { 13574 + "optional": true 13575 + } 11895 13576 } 11896 13577 }, 11897 13578 "node_modules/use-sync-external-store": {
+2
package.json
··· 12 12 "dependencies": { 13 13 "@atproto/api": "^0.16.6", 14 14 "@atproto/oauth-client-browser": "^0.3.33", 15 + "@radix-ui/react-dropdown-menu": "^2.1.16", 15 16 "@tailwindcss/vite": "^4.0.6", 16 17 "@tanstack/query-sync-storage-persister": "^5.85.6", 17 18 "@tanstack/react-devtools": "^0.2.2", ··· 25 26 "idb-keyval": "^6.2.2", 26 27 "jotai": "^2.13.1", 27 28 "npm": "^11.6.2", 29 + "radix-ui": "^1.4.3", 28 30 "react": "^19.0.0", 29 31 "react-dom": "^19.0.0", 30 32 "react-player": "^3.3.2",
+225
src/components/Composer.tsx
··· 1 + import { RichText } from "@atproto/api"; 2 + import { useAtom } from "jotai"; 3 + import { useEffect, useState } from "react"; 4 + 5 + import { useAuth } from "~/providers/UnifiedAuthProvider"; 6 + import { composerAtom } from "~/utils/atoms"; 7 + import { useQueryPost } from "~/utils/useQuery"; 8 + 9 + import { ProfileThing } from "./Login"; 10 + import { UniversalPostRendererATURILoader } from "./UniversalPostRenderer"; 11 + 12 + const MAX_POST_LENGTH = 300 13 + 14 + export function Composer() { 15 + const [composerState, setComposerState] = useAtom(composerAtom); 16 + const { agent } = useAuth(); 17 + 18 + const [postText, setPostText] = useState(""); 19 + const [posting, setPosting] = useState(false); 20 + const [postSuccess, setPostSuccess] = useState(false); 21 + const [postError, setPostError] = useState<string | null>(null); 22 + 23 + useEffect(() => { 24 + setPostText(""); 25 + setPosting(false); 26 + setPostSuccess(false); 27 + setPostError(null); 28 + }, [composerState.kind]); 29 + 30 + const parentUri = 31 + composerState.kind === "reply" 32 + ? composerState.parent 33 + : composerState.kind === "quote" 34 + ? composerState.subject 35 + : undefined; 36 + 37 + const { data: parentPost, isLoading: isParentLoading } = useQueryPost(parentUri); 38 + 39 + async function handlePost() { 40 + if (!agent || !postText.trim() || postText.length > MAX_POST_LENGTH) return; 41 + 42 + setPosting(true); 43 + setPostError(null); 44 + 45 + try { 46 + const rt = new RichText({ text: postText }); 47 + await rt.detectFacets(agent); 48 + 49 + const record: Record<string, unknown> = { 50 + $type: "app.bsky.feed.post", 51 + text: rt.text, 52 + facets: rt.facets, 53 + createdAt: new Date().toISOString(), 54 + }; 55 + 56 + if (composerState.kind === "reply" && parentPost) { 57 + record.reply = { 58 + root: parentPost.value?.reply?.root ?? { 59 + uri: parentPost.uri, 60 + cid: parentPost.cid, 61 + }, 62 + parent: { 63 + uri: parentPost.uri, 64 + cid: parentPost.cid, 65 + }, 66 + }; 67 + } 68 + 69 + if (composerState.kind === "quote" && parentPost) { 70 + record.embed = { 71 + $type: "app.bsky.embed.record", 72 + record: { 73 + uri: parentPost.uri, 74 + cid: parentPost.cid, 75 + }, 76 + }; 77 + } 78 + 79 + await agent.com.atproto.repo.createRecord({ 80 + collection: "app.bsky.feed.post", 81 + repo: agent.assertDid, 82 + record, 83 + }); 84 + 85 + setPostSuccess(true); 86 + setPostText(""); 87 + 88 + setTimeout(() => { 89 + setPostSuccess(false); 90 + setComposerState({ kind: "closed" }); 91 + }, 1500); 92 + } catch (e: any) { 93 + setPostError(e?.message || "Failed to post"); 94 + } finally { 95 + setPosting(false); 96 + } 97 + } 98 + 99 + if (composerState.kind === "closed") { 100 + return null; 101 + } 102 + 103 + const getPlaceholder = () => { 104 + switch (composerState.kind) { 105 + case "reply": 106 + return "Post your reply"; 107 + case "quote": 108 + return "Add a comment..."; 109 + case "root": 110 + default: 111 + return "What's happening?!"; 112 + } 113 + }; 114 + 115 + const charsLeft = MAX_POST_LENGTH - postText.length; 116 + const isPostButtonDisabled = 117 + posting || 118 + !postText.trim() || 119 + isParentLoading || 120 + charsLeft < 0; 121 + 122 + return ( 123 + <div className="fixed inset-0 z-50 flex items-start justify-center pt-10 sm:pt-20 bg-black/40 dark:bg-black/50"> 124 + <div className="bg-gray-50 dark:bg-gray-950 border border-gray-200 dark:border-gray-700 rounded-2xl shadow-xl w-full max-w-xl relative mx-4"> 125 + <div className="flex flex-row justify-between p-2"> 126 + <button 127 + className="h-8 w-8 flex items-center justify-center rounded-full text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800" 128 + onClick={() => !posting && setComposerState({ kind: "closed" })} 129 + disabled={posting} 130 + aria-label="Close" 131 + > 132 + <svg 133 + xmlns="http://www.w3.org/2000/svg" 134 + width="20" 135 + height="20" 136 + viewBox="0 0 24 24" 137 + fill="none" 138 + stroke="currentColor" 139 + strokeWidth="2.5" 140 + strokeLinecap="round" 141 + strokeLinejoin="round" 142 + > 143 + <line x1="18" y1="6" x2="6" y2="18"></line> 144 + <line x1="6" y1="6" x2="18" y2="18"></line> 145 + </svg> 146 + </button> 147 + <div className="flex-1" /> 148 + <div className="flex items-center gap-4"> 149 + <span className={`text-sm ${charsLeft < 0 ? 'text-red-500' : 'text-gray-500'}`}> 150 + {charsLeft} 151 + </span> 152 + 153 + <button 154 + className="bg-gray-600 hover:bg-gray-700 text-white font-bold py-1 px-4 rounded-full disabled:opacity-50 disabled:cursor-not-allowed transition-colors" 155 + onClick={handlePost} 156 + disabled={isPostButtonDisabled} 157 + > 158 + {posting ? "Posting..." : "Post"} 159 + </button> 160 + </div> 161 + </div> 162 + 163 + {postSuccess ? ( 164 + <div className="flex flex-col items-center justify-center py-16"> 165 + <span className="text-gray-500 text-6xl mb-4">✓</span> 166 + <span className="text-xl font-bold text-black dark:text-white">Posted!</span> 167 + </div> 168 + ) : ( 169 + <div className="px-4"> 170 + {(composerState.kind === "reply") && ( 171 + <div className="mb-1 -mx-4"> 172 + {isParentLoading ? ( 173 + <div className="text-sm text-gray-500 animate-pulse"> 174 + Loading parent post... 175 + </div> 176 + ) : parentUri ? ( 177 + <UniversalPostRendererATURILoader atUri={parentUri} bottomReplyLine bottomBorder={false} /> 178 + ) : ( 179 + <div className="text-sm text-red-500 rounded-lg border border-red-500/50 p-3"> 180 + Could not load parent post. 181 + </div> 182 + )} 183 + </div> 184 + )} 185 + 186 + <div className="flex w-full gap-1 flex-col"> 187 + <ProfileThing agent={agent} large/> 188 + <div className="flex pl-[50px]"> 189 + <textarea 190 + className="w-full text-lg bg-transparent focus:outline-none resize-none placeholder:text-gray-500 text-black dark:text-white" 191 + rows={5} 192 + placeholder={getPlaceholder()} 193 + value={postText} 194 + onChange={(e) => setPostText(e.target.value)} 195 + disabled={posting} 196 + autoFocus 197 + /> 198 + </div> 199 + </div> 200 + {(composerState.kind === "quote") && ( 201 + <div className="mb-4 ml-[50px] rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden"> 202 + {isParentLoading ? ( 203 + <div className="text-sm text-gray-500 animate-pulse"> 204 + Loading parent post... 205 + </div> 206 + ) : parentUri ? ( 207 + <UniversalPostRendererATURILoader atUri={parentUri} isQuote /> 208 + ) : ( 209 + <div className="text-sm text-red-500 rounded-lg border border-red-500/50 p-3"> 210 + Could not load parent post. 211 + </div> 212 + )} 213 + </div> 214 + )} 215 + 216 + {postError && ( 217 + <div className="text-red-500 text-sm my-2 text-center">{postError}</div> 218 + )} 219 + 220 + </div> 221 + )} 222 + </div> 223 + </div> 224 + ); 225 + }
+74 -15
src/components/UniversalPostRenderer.tsx
··· 1 1 import { useNavigate } from "@tanstack/react-router"; 2 2 import DOMPurify from "dompurify"; 3 3 import { useAtom } from "jotai"; 4 + import { DropdownMenu } from "radix-ui"; 4 5 import * as React from "react"; 5 6 import { type SVGProps } from "react"; 6 7 7 - import { likedPostsAtom } from "~/utils/atoms"; 8 + import { composerAtom, likedPostsAtom } from "~/utils/atoms"; 8 9 import { useHydratedEmbed } from "~/utils/useHydrated"; 9 10 import { 10 11 useQueryConstellation, ··· 36 37 nopics?: boolean; 37 38 lightboxCallback?: (d: LightboxProps) => void; 38 39 maxReplies?: number; 40 + isQuote?: boolean; 39 41 } 40 42 41 43 // export async function cachedGetRecord({ ··· 146 148 nopics, 147 149 lightboxCallback, 148 150 maxReplies, 151 + isQuote, 149 152 }: UniversalPostRendererATURILoaderProps) { 150 153 // /*mass comment*/ console.log("atUri", atUri); 151 154 //const { get, set } = usePersistentStore(); ··· 407 410 path: ".reply.parent.uri", 408 411 } 409 412 ), 410 - enabled: !!atUri && !!maxReplies, 413 + enabled: !!atUri && !!maxReplies && !isQuote, 411 414 }); 412 415 413 416 const { ··· 419 422 420 423 // auto-fetch all pages 421 424 useEffect(() => { 422 - if (!maxReplies) return; 425 + if (!maxReplies || isQuote) return; 423 426 if ( 424 427 infinitequeryresults.hasNextPage && 425 428 !infinitequeryresults.isFetchingNextPage ··· 443 446 //const [oldestOpsReply, setOldestOpsReply] = useState<string | undefined>(undefined); 444 447 445 448 const { oldestOpsReply, oldestOpsReplyElseNewestNonOpsReply } = (() => { 446 - if (!replyAturis || replyAturis.length === 0 || !maxReplies) 449 + if (isQuote || !replyAturis || replyAturis.length === 0 || !maxReplies) 447 450 return { 448 451 oldestOpsReply: undefined, 449 452 oldestOpsReplyElseNewestNonOpsReply: undefined, ··· 524 527 nopics={nopics} 525 528 lightboxCallback={lightboxCallback} 526 529 maxReplies={maxReplies} 530 + isQuote={isQuote} 527 531 /> 528 - {oldestOpsReplyElseNewestNonOpsReply && ( 532 + {!isQuote && oldestOpsReplyElseNewestNonOpsReply && ( 529 533 <> 530 534 {/* <span>hello {maxReplies}</span> */} 531 535 <UniversalPostRendererATURILoader ··· 618 622 nopics, 619 623 lightboxCallback, 620 624 maxReplies, 625 + isQuote, 621 626 }: { 622 627 postRecord: any; 623 628 profileRecord: any; ··· 638 643 nopics?: boolean; 639 644 lightboxCallback?: (d: LightboxProps) => void; 640 645 maxReplies?: number; 646 + isQuote?: boolean; 641 647 }) { 642 648 // /*mass comment*/ console.log(`received aturi: ${aturi} of post content: ${postRecord}`); 643 649 const navigate = useNavigate(); ··· 838 844 nopics={nopics} 839 845 lightboxCallback={lightboxCallback} 840 846 maxReplies={maxReplies} 847 + isQuote={isQuote} 841 848 /> 842 849 </> 843 850 ); ··· 1322 1329 const [hasLiked, setHasLiked] = useState<boolean>( 1323 1330 post.uri in likedPosts || post.viewer?.like ? true : false 1324 1331 ); 1332 + const [, setComposerPost] = useAtom(composerAtom); 1325 1333 const { agent } = useAuth(); 1326 1334 const [likeUri, setLikeUri] = useState<string | undefined>(post.viewer?.like); 1327 1335 const [retweetUri, setRetweetUri] = useState<string | undefined>( ··· 1459 1467 //left: 16 + (42 / 2), 1460 1468 width: 2, 1461 1469 //height: "100%", 1462 - height: isRepost ? "calc(16px + 1rem - 6px)" : topReplyLine ? 8 - 6 : 16 - 6, 1470 + height: isRepost 1471 + ? "calc(16px + 1rem - 6px)" 1472 + : topReplyLine 1473 + ? 8 - 6 1474 + : 16 - 6, 1463 1475 // background: theme.textSecondary, 1464 1476 //opacity: 0.5, 1465 1477 // no flex here ··· 1473 1485 //top: isRepost ? "calc(16px + 1rem)" : 16, 1474 1486 //left: 16, 1475 1487 zIndex: 1, 1476 - top: isRepost ? "calc(16px + 1rem)" : isQuote ? 12 : topReplyLine ? 8 : 16, 1488 + top: isRepost 1489 + ? "calc(16px + 1rem)" 1490 + : isQuote 1491 + ? 12 1492 + : topReplyLine 1493 + ? 8 1494 + : 16, 1477 1495 left: isQuote ? 12 : 16, 1478 1496 }} 1479 1497 onClick={onProfileClick} ··· 1744 1762 }} 1745 1763 className="text-gray-500 dark:text-gray-400" 1746 1764 > 1747 - <span style={btnstyle}> 1748 - <MdiCommentOutline /> 1749 - {post.replyCount} 1750 - </span> 1751 1765 <HitSlopButton 1752 1766 onClick={() => { 1753 - repostOrUnrepostPost(); 1767 + setComposerPost({ kind: "reply", parent: post.uri }); 1754 1768 }} 1755 1769 style={{ 1756 1770 ...btnstyle, 1757 - ...(hasRetweeted ? { color: "#5CEFAA" } : {}), 1758 1771 }} 1759 1772 > 1760 - {hasRetweeted ? <MdiRepeatGreen /> : <MdiRepeat />} 1761 - {(post.repostCount || 0) + (hasRetweeted ? 1 : 0)} 1773 + <MdiCommentOutline /> 1774 + {post.replyCount} 1762 1775 </HitSlopButton> 1776 + <DropdownMenu.Root modal={false}> 1777 + <DropdownMenu.Trigger asChild> 1778 + <div 1779 + style={{ 1780 + ...btnstyle, 1781 + ...(hasRetweeted ? { color: "#5CEFAA" } : {}), 1782 + }} 1783 + aria-label="Repost or quote post" 1784 + > 1785 + {hasRetweeted ? <MdiRepeatGreen /> : <MdiRepeat />} 1786 + {post.repostCount ?? 0} 1787 + </div> 1788 + </DropdownMenu.Trigger> 1789 + 1790 + <DropdownMenu.Portal> 1791 + <DropdownMenu.Content 1792 + align="start" 1793 + sideOffset={5} 1794 + className="bg-white dark:bg-gray-800 rounded-lg shadow-xl border border-gray-200 dark:border-gray-700 w-32 z-50 overflow-hidden" 1795 + > 1796 + <DropdownMenu.Item 1797 + onSelect={repostOrUnrepostPost} 1798 + className="px-3 py-2 text-sm flex items-center gap-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-700" 1799 + > 1800 + <MdiRepeat 1801 + className={hasRetweeted ? "text-green-400" : ""} 1802 + /> 1803 + <span>{hasRetweeted ? "Undo Repost" : "Repost"}</span> 1804 + </DropdownMenu.Item> 1805 + 1806 + <DropdownMenu.Item 1807 + onSelect={() => { 1808 + setComposerPost({ 1809 + kind: "quote", 1810 + subject: post.uri, 1811 + }); 1812 + }} 1813 + className="px-3 py-2 text-sm flex items-center gap-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-700" 1814 + > 1815 + {/* You might want a specific quote icon here */} 1816 + <MdiCommentOutline /> 1817 + <span>Quote</span> 1818 + </DropdownMenu.Item> 1819 + </DropdownMenu.Content> 1820 + </DropdownMenu.Portal> 1821 + </DropdownMenu.Root> 1763 1822 <HitSlopButton 1764 1823 onClick={() => { 1765 1824 likeOrUnlikePost();
+8 -79
src/routes/__root.tsx
··· 12 12 useNavigate, 13 13 } from "@tanstack/react-router"; 14 14 import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"; 15 - import { useState } from "react"; 15 + import { useAtom } from "jotai"; 16 16 import * as React from "react"; 17 17 import { KeepAliveOutlet, KeepAliveProvider } from "tanstack-router-keepalive"; 18 18 19 + import { Composer } from "~/components/Composer"; 19 20 import { DefaultCatchBoundary } from "~/components/DefaultCatchBoundary"; 20 21 import Login from "~/components/Login"; 21 22 import { NotFound } from "~/components/NotFound"; 22 23 import { UnifiedAuthProvider, useAuth } from "~/providers/UnifiedAuthProvider"; 24 + import { composerAtom } from "~/utils/atoms"; 23 25 import { seo } from "~/utils/seo"; 24 26 25 27 export const Route = createRootRouteWithContext<{ ··· 117 119 ? "profile" 118 120 : "home"; 119 121 120 - const [postOpen, setPostOpen] = useState(false); 121 - const [postText, setPostText] = useState(""); 122 - const [posting, setPosting] = useState(false); 123 - const [postSuccess, setPostSuccess] = useState(false); 124 - const [postError, setPostError] = useState<string | null>(null); 125 - 126 - async function handlePost() { 127 - if (!agent) return; 128 - setPosting(true); 129 - setPostError(null); 130 - try { 131 - await agent.com.atproto.repo.createRecord({ 132 - collection: "app.bsky.feed.post", 133 - repo: agent.assertDid, 134 - record: { 135 - $type: "app.bsky.feed.post", 136 - text: postText, 137 - createdAt: new Date().toISOString(), 138 - }, 139 - }); 140 - setPostSuccess(true); 141 - setPostText(""); 142 - setTimeout(() => { 143 - setPostSuccess(false); 144 - setPostOpen(false); 145 - }, 1500); 146 - } catch (e: any) { 147 - setPostError(e?.message || "Failed to post"); 148 - } finally { 149 - setPosting(false); 150 - } 151 - } 122 + const [, setComposerPost] = useAtom(composerAtom); 152 123 153 124 return ( 154 125 <> 155 - {postOpen && ( 156 - <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40"> 157 - <div className="bg-white dark:bg-gray-900 rounded-lg shadow-lg p-6 w-full max-w-md relative"> 158 - <button 159 - className="absolute top-2 right-2 text-gray-400 hover:text-gray-700 dark:hover:text-gray-200" 160 - onClick={() => !posting && setPostOpen(false)} 161 - disabled={posting} 162 - aria-label="Close" 163 - > 164 - × 165 - </button> 166 - <h2 className="text-lg font-bold mb-2">Create Post</h2> 167 - {postSuccess ? ( 168 - <div className="flex flex-col items-center justify-center py-8"> 169 - <span className="text-green-500 text-4xl mb-2">✓</span> 170 - <span className="text-green-600">Posted!</span> 171 - </div> 172 - ) : ( 173 - <> 174 - <textarea 175 - className="w-full border rounded p-2 mb-2 dark:bg-gray-800 dark:border-gray-700" 176 - rows={4} 177 - placeholder="What's on your mind?" 178 - value={postText} 179 - onChange={(e) => setPostText(e.target.value)} 180 - disabled={posting} 181 - autoFocus 182 - /> 183 - {postError && ( 184 - <div className="text-red-500 text-sm mb-2">{postError}</div> 185 - )} 186 - <button 187 - className="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded disabled:opacity-50" 188 - onClick={handlePost} 189 - disabled={posting || !postText.trim()} 190 - > 191 - {posting ? "Posting..." : "Post"} 192 - </button> 193 - </> 194 - )} 195 - </div> 196 - </div> 197 - )} 126 + <Composer /> 198 127 199 128 <div className="min-h-screen flex justify-center bg-gray-50 dark:bg-gray-950"> 200 129 <nav className="hidden lg:flex h-screen w-[250px] flex-col gap-0 p-4 dark:border-gray-800 sticky top-0 self-start"> ··· 300 229 InactiveIcon={<IconMdiPencilOutline className="w-6 h-6" />} 301 230 ActiveIcon={<IconMdiPencilOutline className="w-6 h-6" />} 302 231 //active={true} 303 - onClickCallbback={() => setPostOpen(true)} 232 + onClickCallbback={() => setComposerPost({ kind: 'root' })} 304 233 text="Post" 305 234 /> 306 235 </div> ··· 540 469 InactiveIcon={<IconMdiPencilOutline className="w-6 h-6" />} 541 470 ActiveIcon={<IconMdiPencilOutline className="w-6 h-6" />} 542 471 //active={true} 543 - onClickCallbback={() => setPostOpen(true)} 472 + onClickCallbback={() => setComposerPost({ kind: 'root' })} 544 473 text="Post" 545 474 /> 546 475 </div> ··· 550 479 <button 551 480 className="lg:hidden fixed bottom-22 right-4 z-50 bg-gray-200 dark:bg-gray-800 hover:bg-gray-300 dark:hover:bg-gray-700 rounded-2xl w-14 h-14 flex items-center justify-center transition-all" 552 481 style={{ boxShadow: "0 4px 24px 0 rgba(0,0,0,0.12)" }} 553 - onClick={() => setPostOpen(true)} 482 + onClick={() => setComposerPost({ kind: 'root' })} 554 483 type="button" 555 484 aria-label="Create Post" 556 485 >
+7
src/utils/atoms.ts
··· 23 23 24 24 export const isAtTopAtom = atom<boolean>(true); 25 25 26 + type ComposerState = 27 + | { kind: 'closed' } 28 + | { kind: 'root' } 29 + | { kind: 'reply'; parent: string } 30 + | { kind: 'quote'; subject: string }; 31 + export const composerAtom = atom<ComposerState>({ kind: 'closed' }); 32 + 26 33 export const agentAtom = atom<Agent|null>(null); 27 34 export const authedAtom = atom<boolean>(false);