├── .editorconfig ├── .github └── workflows │ ├── coverage.yml │ ├── pr-test.yml │ ├── publish.yml │ └── release.yml ├── .gitignore ├── .vscode └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── dev ├── Computed.tsx ├── CustomRef.tsx ├── EffectScope.tsx ├── Lifecycle.tsx ├── Reactive.tsx ├── Reactivity.tsx ├── Readonly.tsx ├── Ref.tsx ├── ShallowReactive.tsx ├── ShallowRef.tsx ├── Watch.tsx ├── main.tsx ├── style.css └── utils.ts ├── eslint.config.js ├── index.html ├── logo.svg ├── package.json ├── pnpm-lock.yaml ├── prettier.config.js ├── scripts └── release.sh ├── src ├── _logger.ts ├── _utils.ts ├── computed.ts ├── effectScope.ts ├── index.ts ├── lifecycle.ts ├── reactive.ts ├── reactivity.ts ├── readonly.ts ├── ref.ts ├── watch.ts └── watchEffect.ts ├── tests ├── apis.spec.ts ├── computed.spec.ts ├── effectScope.spec.ts ├── lifecycle.spec.ts ├── reactive.spec.ts ├── reactivity.spec.ts ├── readonly.spec.ts ├── ref.spec.ts ├── watch.spec.ts └── watchEffect.spec.ts ├── tsconfig.json └── vite.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | tab_width = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yml: -------------------------------------------------------------------------------- 1 | name: Coverage 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build: 11 | name: Test Coverage 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: pnpm/action-setup@v4 16 | with: 17 | version: 9 18 | - uses: actions/setup-node@v4 19 | with: 20 | node-version: 'lts/*' 21 | cache: 'pnpm' 22 | 23 | - name: Install dependencies 24 | run: pnpm install 25 | 26 | - name: Test results & coverage 27 | run: pnpm run test:coverage 28 | 29 | - name: Upload test results to Codecov 30 | if: ${{ !cancelled() }} 31 | uses: codecov/test-results-action@v1 32 | with: 33 | token: ${{ secrets.CODECOV_TOKEN }} 34 | file: ./junit.xml 35 | 36 | - name: Upload coverage to Codecov 37 | uses: codecov/codecov-action@v4 38 | with: 39 | token: ${{ secrets.CODECOV_TOKEN }} 40 | directory: ./coverage/ 41 | -------------------------------------------------------------------------------- /.github/workflows/pr-test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | name: PR Test 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: pnpm/action-setup@v4 15 | with: 16 | version: 9 17 | - uses: actions/setup-node@v4 18 | with: 19 | node-version: 'lts/*' 20 | cache: 'pnpm' 21 | 22 | - name: Install dependencies 23 | run: pnpm install 24 | 25 | - name: Lint/Test/Build 26 | run: pnpm run ci 27 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages 3 | # Fork from: https://github.com/actions/starter-workflows/blob/master/ci/npm-publish.yml 4 | 5 | name: Publish 6 | 7 | on: 8 | release: 9 | types: [created] 10 | push: 11 | tags: 12 | - 'v*' 13 | workflow_dispatch: 14 | 15 | jobs: 16 | publish-npm: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: pnpm/action-setup@v4 21 | with: 22 | version: 9 23 | - uses: actions/setup-node@v4 24 | with: 25 | node-version: 'lts/*' 26 | cache: 'pnpm' 27 | registry-url: https://registry.npmjs.org/ 28 | 29 | - run: pnpm install 30 | - run: pnpm run ci 31 | - run: npm publish --access=public 32 | env: 33 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 34 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | build: 10 | name: Create Release 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v4 16 | 17 | - name: Create Release 18 | uses: surmon-china/create-release@v1.0.0 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | with: 22 | tag_name: ${{ github.ref }} 23 | release_name: ${{ github.ref }} 24 | body: | 25 | Please refer to [CHANGELOG.md](/CHANGELOG.md) for details. 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .cache 3 | node_modules 4 | *.log 5 | .idea 6 | package-lock.json 7 | npm-debug.log 8 | 9 | 10 | # output 11 | dist 12 | 13 | # Test Relative Folders 14 | coverage 15 | junit.xml 16 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "editor.defaultFormatter": "esbenp.prettier-vscode", 4 | "editor.formatOnSave": true 5 | } 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ### v1.0.0 (2024-09-05) 6 | 7 | #### Added 8 | 9 | - Export `watch` as `baseWatch` from `@vue/reactivity` 10 | - Introduced `useEffectScope` API. 11 | - Introduced `useCustomRef` API. 12 | - Introduced `useReadonly` and `useShallowReadonly` APIs. 13 | - Added JSDoc comments for all functions. 14 | - Added API documentation to `README.md`. 15 | - Added development mode. 16 | 17 | #### Changed 18 | 19 | - Refactored `watch`, `useWatch`, `watchEffect`, and `useWatchEffect` APIs. 20 | - Replaced `yarn` with `pnpm`. 21 | - Replaced `jest` with `vitest`. 22 | - Replaced `libundler` with `vite` as the bundler. 23 | - Upgraded `React` and `react-dom` peerDependencies versions. 24 | - Upgraded `@vue/reactivity` dependency to `>=3.5`. 25 | - Upgraded ESLint to v9. 26 | - Updated unit test scripts. 27 | 28 | #### Removed 29 | 30 | - Removed `batchedUpdates` API. 31 | 32 | ### v1.0.0-beta.2 (2024-08-15) 33 | 34 | No changes, just synced with `@vue/reactivity` [v3.5.0-beta.2](https://github.com/vuejs/core/blob/main/CHANGELOG.md#350-beta2-2024-08-15). 35 | 36 | ### v1.0.0-beta.1 (2024-08-12) 37 | 38 | #### Added 39 | 40 | - Introduced `useEffectScope` API. 41 | - Introduced `useCustomRef` API. 42 | - Introduced `useReadonly` and `useShallowReadonly` APIs. 43 | - Added JSDoc comments for all functions. 44 | - Added API documentation to `README.md`. 45 | - Added development mode. 46 | 47 | #### Changed 48 | 49 | - Refactored `watch`, `useWatch`, `watchEffect`, and `useWatchEffect` APIs. 50 | - Replaced `yarn` with `pnpm`. 51 | - Replaced `jest` with `vitest`. 52 | - Replaced `libundler` with `vite` as the bundler. 53 | - Upgraded `React` and `react-dom` peerDependencies versions. 54 | - Upgraded ESLint to v9. 55 | - Updated unit test scripts. 56 | 57 | #### Removed 58 | 59 | - Removed `batchedUpdates` API. 60 | 61 | #### Fixed 62 | 63 | - Fixed Issue [#6](https://github.com/veactjs/veact/issues/6). 64 | - Fixed Issue [#4](https://github.com/veactjs/veact/issues/4). 65 | 66 | ### v0.1.4 (2022-01-17) 67 | 68 | - upgrade reactivity deps 69 | - upgrade `libundler` 70 | 71 | ### v0.1.3 (2021-08-02) 72 | 73 | - upgrade reactivity deps 74 | - update document links with reactivity 75 | 76 | ### v0.1.2 (2021-07-27) 77 | 78 | - fix `peerDependencies` React version 79 | 80 | ### v0.1.0 (2021-07-27) 81 | 82 | - fix types 83 | 84 | ### v0.1.0 (2021-07-26) 85 | 86 | - lifecycle API 87 | - hooks API 88 | - watch API 89 | - support SSR 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Surmon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

4 | veact 5 |

6 | 7 | # Veact 8 | 9 | [![veact](https://img.shields.io/badge/WITH-VEACT-42a97a?style=for-the-badge&labelColor=35495d)](https://github.com/veactjs/veact) 10 |   11 | [![GitHub stars](https://img.shields.io/github/stars/veactjs/veact.svg?style=for-the-badge)](https://github.com/veactjs/veact/stargazers) 12 |   13 | [![npm](https://img.shields.io/npm/v/veact?color=c7343a&label=npm&style=for-the-badge)](https://www.npmjs.com/package/veact) 14 |   15 | [![Test Codecov](https://img.shields.io/codecov/c/github/veactjs/veact?style=for-the-badge)](https://codecov.io/gh/veactjs/veact) 16 |   17 | [![GitHub license](https://img.shields.io/github/license/veactjs/veact.svg?style=for-the-badge)](/LICENSE) 18 | 19 | A mutable state enhancer library for [`React`](https://github.com/facebook/react), built on top of [`@vue/reactivity`](https://github.com/vuejs/core/tree/main/packages/reactivity). 20 | 21 | #### Why Veact? 22 | 23 | If you’re frustrated with the repetitive task of defining `props`, `emits`, `slots` and `attrs` in Vue, sometimes struggling to keep track of types, and you value the simplicity of managing everything with interfaces in React, then Veact is for you. Veact effortlessly merges the low cognitive overhead of Vue’s mutable state with the robust type support and flexibility of React’s JSX. It strikes a perfect balance between the strengths of both frameworks, providing a near-flawless development experience—without the complexity and potential pitfalls of useEffect in React. 24 | 25 | Veact embodies what I believe is the **“best of both worlds”**—a powerful, yet intuitive library crafted to simplify and enhance your front-end development experience and efficiency. 26 | 27 | #### Who is using this library 🔥 28 | 29 | - [**veact-use**](https://github.com/veactjs/veact-use) Veact hooks. 30 | - [**surmon.admin**](https://github.com/surmon-china/surmon.admin) A CMS admin client for [surmon.me](https://github.com/surmon-china/surmon.me) blog. 31 | - ... 32 | 33 | #### API & examples 34 | 35 | - [API List](#api) 36 | - [Example: Lifecycle](#lifecycle) 37 | - [Example: Ref](#ref) 38 | - [Example: ShallowRef](#shallowref) 39 | - [Example: Reactive](#reactive) 40 | - [Example: Computed](#computed) 41 | - [Example: Watch](#watch) 42 | - [Example: EffectScope](#effectscope) 43 | - [Example: Reactivity](#reactivity) 44 | 45 | ## Installation 46 | 47 | ```bash 48 | # using npm 49 | npm install veact --save 50 | 51 | # using yarn 52 | yarn add veact 53 | 54 | # using pnpm 55 | pnpm add veact 56 | ``` 57 | 58 | ## Usage 59 | 60 | ### Lifecycle 61 | 62 | ```tsx 63 | import React from 'react' 64 | import { onMounted, onBeforeUnmount, onUpdated } from 'veact' 65 | 66 | export const Component: React.FC = () => { 67 | onMounted(() => { 68 | console.log('component mounted') 69 | }) 70 | 71 | onUpdated(() => { 72 | console.log('component updated') 73 | }) 74 | 75 | onBeforeUnmount(() => { 76 | console.log('component will unmount') 77 | }) 78 | 79 | return
component
80 | } 81 | ``` 82 | 83 | ### Ref 84 | 85 | ```tsx 86 | import React from 'react' 87 | import { useRef } from 'veact' 88 | 89 | export const Component: React.FC = () => { 90 | const count = useRef(0) 91 | const increment = () => { 92 | count.value++ 93 | } 94 | 95 | return ( 96 |
97 |

{count.value}

98 | 99 |
100 | ) 101 | } 102 | ``` 103 | 104 | ### ShallowRef 105 | 106 | ```tsx 107 | import React from 'react' 108 | import { useShallowRef } from 'veact' 109 | 110 | export const Component: React.FC = () => { 111 | const numbers = useShallowRef([1, 2, 3]) 112 | const resetNumbers = () => { 113 | numbers.value = [] 114 | } 115 | 116 | return ( 117 |
118 |

{numbers.value.length}

119 | 120 |
121 | ) 122 | } 123 | ``` 124 | 125 | ### Reactive 126 | 127 | ```tsx 128 | import React from 'react' 129 | import { useReactive } from 'veact' 130 | 131 | export const Component: React.FC = () => { 132 | const data = useReactive({ 133 | count: 10, 134 | nested: { count: 1 }, 135 | }) 136 | 137 | const incrementCount = () => { 138 | data.count++ 139 | } 140 | 141 | const incrementNestedCount = () => { 142 | data.nested.count++ 143 | } 144 | 145 | return ( 146 |
147 |

{data.count}

148 |

{data.nested.count}

149 | 150 | 151 |
152 | ) 153 | } 154 | ``` 155 | 156 | ### Computed 157 | 158 | ```tsx 159 | import React from 'react' 160 | import { useReactive, useComputed } from 'veact' 161 | 162 | export const Component: React.FC = () => { 163 | const data = useReactive({ 164 | year: 3, 165 | count: 4, 166 | }) 167 | 168 | const total = useComputed(() => { 169 | return data.count * data.year 170 | }) 171 | 172 | const incrementCount = () => { 173 | data.count++ 174 | } 175 | 176 | return ( 177 |
178 | {total.value} 179 | 180 |
181 | ) 182 | } 183 | ``` 184 | 185 | ### Watch 186 | 187 | ```tsx 188 | import React from 'react' 189 | import { useReactive, useWatch } from 'veact' 190 | 191 | export const Component: React.FC = () => { 192 | const data = useReactive({ 193 | count: 0, 194 | }) 195 | 196 | const incrementCount = () => { 197 | data.count++ 198 | } 199 | 200 | useWatch(data, (newData) => { 201 | console.log('data changed', newData) 202 | }) 203 | 204 | useWatch( 205 | () => data.count, 206 | (newCount) => { 207 | console.log('count changed', newCount) 208 | }, 209 | ) 210 | 211 | return ( 212 |
213 | {data.count} 214 | 215 |
216 | ) 217 | } 218 | ``` 219 | 220 | ### EffectScope 221 | 222 | ```tsx 223 | import React from 'react' 224 | import { watch, useRef, useEffectScope, onScopeDispose } from 'veact' 225 | 226 | export const Component: React.FC = () => { 227 | const scope = useEffectScope() 228 | const counter = useRef(0) 229 | 230 | const incrementCounter = () => { 231 | counter.value++ 232 | } 233 | 234 | scope.run(() => { 235 | const doubled = computed(() => counter.value * 2) 236 | watch(doubled, (newValue) => console.log(newValue)) 237 | watchEffect(() => console.log('doubled: ', doubled.value)) 238 | onScopeDispose(() => console.log('effect scope is stopped')) 239 | }) 240 | 241 | return ( 242 |
243 | {counter.value} 244 | 245 | 246 | 247 | 248 |
249 | ) 250 | } 251 | ``` 252 | 253 | ### Reactivity 254 | 255 | Converts some of the 'raw Vue' data, which is not already wrapped in a hook, into reactive hook data to ensure proper reactivity within the component. 256 | 257 | ```tsx 258 | import React from 'react' 259 | import { ref, useReactivity } from 'veact' 260 | 261 | // ref data without hooks 262 | const countRef = ref(0) 263 | 264 | export const Component: React.FC = () => { 265 | // to reactivity hook 266 | const count = useReactivity(() => countRef) 267 | const increment = () => { 268 | count.value++ 269 | } 270 | 271 | return ( 272 |
273 | {count.value} 274 | 275 |
276 | ) 277 | } 278 | ``` 279 | 280 | ## API 281 | 282 | All APIs listed here are implemented and provided by Veact. For additional exported types, please refer to [`index.ts`](/src/index.ts). 283 | 284 | Veact also re-exports all APIs from [`@vue/reactivity`](https://github.com/vuejs/core/blob/main/packages/reactivity/src/index.ts). 285 | 286 | | Veact API | Corresponding Capability | Description | 287 | | -------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 288 | | `onMounted` | React [`componentDidMount()`](https://react.dev/reference/react/Component#componentdidmount) | The function is called right after the component is mounted. | 289 | | `onUpdated` | React [`componentDidUpdate()`](https://react.dev/reference/react/Component#componentdidupdate) | The function is called immediately after the component is re-rendered with updated props or state. (This method is not invoked during the initial render.) | 290 | | `onBeforeUnmount` | React [`componentWillUnmount()`](https://react.dev/reference/react/Component#componentwillunmount) | The function is called right before the component is unmounted. | 291 | | `useRef` | Vue [`ref()`](https://vuejs.org/api/reactivity-core.html#ref) | Takes an inner value and returns a reactive and mutable ref object, which has a single property `.value` that points to the inner value. | 292 | | `useShallowRef` | Vue [`shallowRef()`](https://vuejs.org/api/reactivity-advanced.html#shallowref) | Shallow version of `useRef()`. | 293 | | `useCustomRef` | Vue [`customRef()`](https://vuejs.org/api/reactivity-advanced.html#customref) | Creates a customized ref with explicit control over its dependency tracking and updates triggering. | 294 | | `useReactive` | Vue [`reactive()`](https://vuejs.org/api/reactivity-core.html#reactive) | Returns a reactive proxy of the object. | 295 | | `useShallowReactive` | Vue [`shallowReactive()`](https://vuejs.org/api/reactivity-advanced.html#shallowreactive) | Shallow version of `useReactive()`. | 296 | | `useReadonly` | Vue [`readonly()`](https://vuejs.org/api/reactivity-core.html#readonly) | Takes an object (reactive or plain) or a ref and returns a readonly proxy to the original. | 297 | | `useShallowReadonly` | Vue [`shallowReadonly()`](https://vuejs.org/api/reactivity-advanced.html#shallowreadonly) | Shallow version of `useReadonly()`. | 298 | | `useComputed` | Vue [`computed()`](https://vuejs.org/api/reactivity-core.html#computed) | Takes a getter function and returns a readonly reactive ref object for the returned value from the getter. It can also take an object with get and set functions to create a writable ref object. | 299 | | `watch` | Vue [`watch()`](https://vuejs.org/api/reactivity-core.html#watch) | Watches one or more reactive data sources and invokes a callback function when the sources change. Unlike Vue (3.5.0), it does not support the `option.flush`. | 300 | | `useWatch` | Vue [`watch()`](https://vuejs.org/api/reactivity-core.html#watch) | Same as above, this is the hook implementation of `watch()`. | 301 | | `watchEffect` | Vue [`watchEffect()`](https://vuejs.org/api/reactivity-core.html#watcheffect) | Runs a function immediately while reactively tracking its dependencies and re-runs it whenever the dependencies are changed. Unlike Vue (3.5.0), it does not support the `option.flush`. | 302 | | `useWatchEffect` | Vue [`watchEffect()`](https://vuejs.org/api/reactivity-core.html#watcheffect) | Same as above, this is the hook implementation of `watchEffect()`. | 303 | | `useEffectScope` | Vue [`effectScope()`](https://vuejs.org/api/reactivity-advanced.html#effectscope) | Unlike `effectScope` in Vue, `useEffectScope().run()` will only execute once within the component and cannot contain any other hooks. | 304 | | `useReactivity` | Internal implementation in Veact | Converts some of the 'raw Vue' data, which is not already wrapped in a hook, into reactive hook data to ensure proper reactivity within the component. | 305 | 306 | ## Development 307 | 308 | ```bash 309 | # install dependencies 310 | pnpm install 311 | 312 | # dev 313 | pnpm run dev 314 | 315 | # lint 316 | pnpm run lint 317 | 318 | # test 319 | pnpm run test 320 | 321 | # build 322 | pnpm run build 323 | ``` 324 | 325 | ## Changelog 326 | 327 | Detailed changes for each release are documented in the [release notes](/CHANGELOG.md). 328 | 329 | ## License 330 | 331 | Licensed under the [MIT](/LICENSE) License. 332 | -------------------------------------------------------------------------------- /dev/Computed.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useReactive, useComputed } from '../src' 3 | import { useRenderCount } from './utils' 4 | 5 | export const Component: React.FC = () => { 6 | const renderCount = useRenderCount() 7 | 8 | const data = useReactive({ 9 | year: 3, 10 | count: 4, 11 | }) 12 | 13 | const doubleCount = useComputed({ 14 | get: () => data.count * 2, 15 | set: (val) => { 16 | data.count = val / 2 17 | }, 18 | }) 19 | 20 | const total = useComputed(() => { 21 | return data.count * data.year 22 | }) 23 | 24 | const incrementData = () => { 25 | data.count += 2 26 | data.year++ 27 | } 28 | 29 | const setDoubleCount = (value: number) => { 30 | doubleCount.value = value 31 | } 32 | 33 | return ( 34 |
35 | renderCount: {renderCount} 36 |
data = {JSON.stringify(data)}
37 |
year * count = {total.value}
38 |
doubleCount = {doubleCount.value}
39 | 40 | 41 |
42 | ) 43 | } 44 | -------------------------------------------------------------------------------- /dev/CustomRef.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useShallowRef, useCustomRef } from '../src' 3 | import { useRenderCount } from './utils' 4 | 5 | function useDebouncedRef(initValue: T, delay = 200) { 6 | const value = useShallowRef(initValue) 7 | const timeout = useShallowRef() 8 | return useCustomRef((track, trigger) => { 9 | return { 10 | get() { 11 | track() 12 | return value.value 13 | }, 14 | set(newValue) { 15 | window.clearTimeout(timeout.value) 16 | timeout.value = window.setTimeout(() => { 17 | value.value = newValue 18 | trigger() 19 | }, delay) 20 | }, 21 | } 22 | }) 23 | } 24 | 25 | export const Component: React.FC = () => { 26 | const renderCount = useRenderCount() 27 | 28 | const text = useDebouncedRef('hello') 29 | const setTextValue = (value: string) => { 30 | text.value = value 31 | } 32 | 33 | return ( 34 |
35 | renderCount: {renderCount} 36 |
text: {text.value}
37 | setTextValue(event.target.value)} /> 38 | 39 |
40 | ) 41 | } 42 | -------------------------------------------------------------------------------- /dev/EffectScope.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { watch, ref, reactive, useRef, useEffectScope } from '../src' 3 | import { useRenderCount } from './utils' 4 | 5 | const fooRef = ref(0) 6 | const barReactive = reactive({ bar: 10 }) 7 | 8 | export const Component: React.FC = () => { 9 | const renderCount = useRenderCount() 10 | 11 | const scope = useEffectScope() 12 | const fooWatchChanged = useRef(0) 13 | const barWatchChanged = useRef(0) 14 | 15 | const incrementFoo = () => { 16 | fooRef.value++ 17 | } 18 | 19 | const incrementBar = () => { 20 | barReactive.bar++ 21 | } 22 | 23 | scope.run(() => { 24 | watch(fooRef, () => { 25 | fooWatchChanged.value++ 26 | }) 27 | watch(barReactive, () => { 28 | barWatchChanged.value++ 29 | }) 30 | }) 31 | 32 | return ( 33 |
34 | renderCount: {renderCount} 35 |
foo.value = {fooRef.value}
36 |
bar object = {JSON.stringify(barReactive)}
37 |
fooWatchChanged: {fooWatchChanged.value}
38 |
barWatchChanged: {barWatchChanged.value}
39 | 40 | 41 |
42 | 43 | 44 | 45 |
46 | ) 47 | } 48 | -------------------------------------------------------------------------------- /dev/Lifecycle.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { onMounted, onBeforeUnmount, onUpdated } from '../src' 3 | import { useRenderCount } from './utils' 4 | 5 | export interface ComponentProps { 6 | onNewLog(log: string): void 7 | } 8 | 9 | export const Component: React.FC = (props) => { 10 | const renderCount = useRenderCount() 11 | 12 | onMounted(() => { 13 | props.onNewLog('Lifecycle component mounted') 14 | }) 15 | 16 | onUpdated(() => { 17 | // props.onNewLog('component updated') 18 | }) 19 | 20 | onBeforeUnmount(() => { 21 | props.onNewLog('Lifecycle component will unmount') 22 | }) 23 | 24 | return ( 25 |
26 |

Lifecycle component

27 | renderCount: {renderCount} 28 |
29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /dev/Reactive.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useReactive } from '../src' 3 | import { useRenderCount } from './utils' 4 | 5 | export const Component: React.FC = () => { 6 | const renderCount = useRenderCount() 7 | 8 | const object = useReactive({ 9 | data: 10, 10 | nested: { data: 1 }, 11 | }) 12 | 13 | const incrementData = () => { 14 | object.data++ 15 | } 16 | 17 | const incrementNestedData = () => { 18 | object.nested.data++ 19 | } 20 | 21 | return ( 22 |
23 | renderCount: {renderCount} 24 |
object = {JSON.stringify(object, null, 2)}
25 | 26 | 27 |
28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /dev/Reactivity.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { ref, reactive, computed, useReactivity, useComputed } from '../src' 3 | import { useRenderCount } from './utils' 4 | 5 | // ref 6 | const pureRef = ref(0) 7 | const fooRef = ref(0) 8 | // reactive 9 | const barReactive = reactive({ bar: 10 }) 10 | const doubleBar = computed(() => barReactive.bar * 2) 11 | 12 | export const Component: React.FC = () => { 13 | const renderCount = useRenderCount() 14 | 15 | // to reactivity hook 16 | const foo = useReactivity(() => fooRef) 17 | const bar = useReactivity(() => barReactive) 18 | const doubleFoo = useComputed(() => foo.value * 2) 19 | 20 | return ( 21 |
22 | renderCount: {renderCount} 23 |
foo.value = {foo.value}
24 |
foo * 2 = {doubleFoo.value}
25 |
bar = {bar.bar}
26 |
bar * 2 = {doubleBar.value}
27 |
pure.value = {pureRef.value}
28 | 29 | 30 | 31 |
32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /dev/Readonly.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { reactive, useReadonly, useShallowReadonly } from '../src' 3 | import { useRenderCount } from './utils' 4 | 5 | const dataObject = reactive({ 6 | data: 10, 7 | nested: { data: 1 }, 8 | }) 9 | 10 | export const Component: React.FC = () => { 11 | const renderCount = useRenderCount() 12 | 13 | const readonlyObject = useReadonly(dataObject) 14 | const shallowReadonlyObject = useShallowReadonly(dataObject) 15 | 16 | return ( 17 |
18 | renderCount: {renderCount} 19 |
shallowReadonlyObject = {JSON.stringify(shallowReadonlyObject, null, 2)}
20 | {/* @ts-ignore */} 21 | 22 | 23 |
24 |
readonlyObject = {JSON.stringify(readonlyObject, null, 2)}
25 | {/* @ts-ignore */} 26 | 27 | {/* @ts-ignore */} 28 | 29 |
30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /dev/Ref.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useRef } from '../src' 3 | import { useRenderCount } from './utils' 4 | 5 | export const Component: React.FC = () => { 6 | const renderCount = useRenderCount() 7 | 8 | const refData = useRef({ 9 | data: 10, 10 | nested: { data: 1 }, 11 | }) 12 | 13 | const incrementData = () => { 14 | refData.value.data++ 15 | } 16 | 17 | const incrementNestedData = () => { 18 | refData.value.nested.data++ 19 | } 20 | 21 | const incrementRefValues = () => { 22 | refData.value = { 23 | data: refData.value.data + 1, 24 | nested: { 25 | data: refData.value.nested.data + 1, 26 | }, 27 | } 28 | } 29 | 30 | return ( 31 |
32 | renderCount: {renderCount} 33 |
ref.value = {JSON.stringify(refData.value, null, 2)}
34 | 35 | 36 | 37 |
38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /dev/ShallowReactive.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useShallowReactive } from '../src' 3 | import { useRenderCount } from './utils' 4 | 5 | export const Component: React.FC = () => { 6 | const renderCount = useRenderCount() 7 | 8 | const object = useShallowReactive({ 9 | data: 10, 10 | nested: { data: 1 }, 11 | }) 12 | 13 | const incrementData = () => { 14 | object.data++ 15 | } 16 | 17 | const incrementNestedData = () => { 18 | object.nested.data++ 19 | } 20 | 21 | return ( 22 |
23 | renderCount: {renderCount} 24 |
object = {JSON.stringify(object, null, 2)}
25 | 26 | 27 |
28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /dev/ShallowRef.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useShallowRef } from '../src' 3 | import { useRenderCount } from './utils' 4 | 5 | export const Component: React.FC = () => { 6 | const renderCount = useRenderCount() 7 | 8 | const refData = useShallowRef({ 9 | data: 10, 10 | }) 11 | 12 | const incrementData = () => { 13 | refData.value.data++ 14 | } 15 | 16 | const incrementRefValues = () => { 17 | refData.value = { 18 | data: refData.value.data + 1, 19 | } 20 | } 21 | 22 | return ( 23 |
24 | renderCount: {renderCount} 25 |
ref.value = {JSON.stringify(refData.value, null, 2)}
26 | 27 | 28 |
29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /dev/Watch.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useRef, useReactive, useWatch, useWatchEffect, toRefs } from '../src' 3 | import { useRenderCount } from './utils' 4 | 5 | export const Component: React.FC = () => { 6 | const renderCount = useRenderCount() 7 | 8 | const dataWatchChanged = useRef(0) 9 | const countWatchChanged = useRef(0) 10 | const deep2WatchChanged = useRef(0) 11 | const deep4WatchChanged = useRef(0) 12 | const immediateWatchChanged = useRef(0) 13 | const onceWatchChanged = useRef(0) 14 | const watchEffectChanged = useRef(0) 15 | 16 | const data = useReactive({ 17 | count: 0, 18 | level1: { 19 | level2: { 20 | level3: { 21 | level4: 100, 22 | }, 23 | }, 24 | }, 25 | }) 26 | 27 | const incrementCount = () => { 28 | data.count++ 29 | } 30 | 31 | const incrementLevel4 = () => { 32 | data.level1.level2.level3.level4++ 33 | } 34 | 35 | useWatch(data, () => { 36 | dataWatchChanged.value++ 37 | }) 38 | 39 | useWatch( 40 | () => data.count, 41 | () => countWatchChanged.value++, 42 | ) 43 | 44 | useWatch(data, () => deep2WatchChanged.value++, { deep: 2 }) 45 | useWatch(data, () => deep4WatchChanged.value++, { deep: 4 }) 46 | useWatch(data, () => immediateWatchChanged.value++, { immediate: true }) 47 | useWatch(data, () => onceWatchChanged.value++, { once: true }) 48 | 49 | useWatchEffect(() => { 50 | console.debug(toRefs(data)) 51 | watchEffectChanged.value++ 52 | }) 53 | 54 | return ( 55 |
56 | renderCount: {renderCount} 57 |
data = {JSON.stringify(data, null, 2)}
58 |

dataWatchChanged: {dataWatchChanged.value}

59 |

countWatchChanged: {countWatchChanged.value}

60 |

deep2WatchChanged: {deep2WatchChanged.value}

61 |

deep4WatchChanged: {deep4WatchChanged.value}

62 |

immediateWatchChanged: {immediateWatchChanged.value}

63 |

onceWatchChanged: {onceWatchChanged.value}

64 |

watchEffectChanged: {watchEffectChanged.value}

65 | 66 | 67 |
68 | ) 69 | } 70 | -------------------------------------------------------------------------------- /dev/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | 4 | import { onMounted, useReactive, useRef } from '../src' 5 | import { Component as LifecycleCom } from './Lifecycle' 6 | import { Component as RefCom } from './Ref' 7 | import { Component as ShallowRefCom } from './ShallowRef' 8 | import { Component as CustomRefCom } from './CustomRef' 9 | import { Component as ReactiveCom } from './Reactive' 10 | import { Component as ShallowReactiveCom } from './ShallowReactive' 11 | import { Component as ComputedCom } from './Computed' 12 | import { Component as ReactivityCom } from './Reactivity' 13 | import { Component as WatchCom } from './Watch' 14 | import { Component as EffectScopeCom } from './EffectScope' 15 | import { Component as ReadonlyCom } from './Readonly' 16 | 17 | import './style.css' 18 | 19 | export const App: React.FC = () => { 20 | const lifecycleState = useRef(true) 21 | const toggleLifecycle = () => { 22 | lifecycleState.value = !lifecycleState.value 23 | } 24 | 25 | const logs = useReactive([]) 26 | const addNewLog = (log: string) => { 27 | console.log(log) 28 | logs.push(log) 29 | } 30 | 31 | onMounted(() => { 32 | addNewLog('App component mounted.') 33 | }) 34 | 35 | const modules = [ 36 | { 37 | title: 'Logs', 38 | element: ( 39 |
    40 | {logs.map((log, index) => ( 41 |
  • {log}
  • 42 | ))} 43 |
44 | ), 45 | }, 46 | { 47 | title: 'Lifecycle', 48 | element: ( 49 | <> 50 | 51 | {lifecycleState.value && } 52 | 53 | ), 54 | }, 55 | { 56 | title: 'Ref', 57 | element: , 58 | }, 59 | { 60 | title: 'ShallowRef', 61 | element: , 62 | }, 63 | { 64 | title: 'CustomRef', 65 | element: , 66 | }, 67 | { 68 | title: 'Reactive', 69 | element: , 70 | }, 71 | { 72 | title: 'ShallowReactive', 73 | element: , 74 | }, 75 | { 76 | title: 'Computed', 77 | element: , 78 | }, 79 | { 80 | title: 'Watch', 81 | element: , 82 | }, 83 | { 84 | title: 'EffectScope', 85 | element: , 86 | }, 87 | { 88 | title: 'Readonly', 89 | element: , 90 | }, 91 | { 92 | title: 'Reactivity', 93 | element: , 94 | }, 95 | ] 96 | 97 | return ( 98 |
99 | {modules.map((m, i) => ( 100 |
101 |

{m.title}

102 |
{m.element}
103 |
104 | ))} 105 |
106 | ) 107 | } 108 | 109 | ReactDOM.createRoot(document.getElementById('root')!).render() 110 | -------------------------------------------------------------------------------- /dev/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --body-bg-color: initial; 3 | --text-color: initial; 4 | } 5 | 6 | @media (prefers-color-scheme: dark) { 7 | :root { 8 | --body-bg-color: #1e2227; 9 | --text-color: #eee; 10 | } 11 | } 12 | 13 | @media (prefers-color-scheme: light) { 14 | :root { 15 | --body-bg-color: white; 16 | --text-color: black; 17 | } 18 | } 19 | 20 | body { 21 | margin: 0; 22 | background-color: var(--body-bg-color); 23 | color: var(--text-color); 24 | font-family: serif; 25 | user-select: none; 26 | } 27 | 28 | pre { 29 | font-size: 16px; 30 | line-height: 1.4; 31 | } 32 | 33 | button { 34 | padding: 4px 6px; 35 | margin: 4px; 36 | cursor: pointer; 37 | } 38 | 39 | .app { 40 | display: flex; 41 | flex-wrap: wrap; 42 | } 43 | 44 | .module { 45 | min-width: 210px; 46 | max-width: 380px; 47 | padding: 1rem; 48 | border: 1px solid #333; 49 | } 50 | 51 | .module .title { 52 | margin-top: 0; 53 | } 54 | -------------------------------------------------------------------------------- /dev/utils.ts: -------------------------------------------------------------------------------- 1 | import { useRef as useReactRef } from 'react' 2 | 3 | export const useRenderCount = () => { 4 | const renderCount = useReactRef(0) 5 | renderCount.current++ 6 | return renderCount.current 7 | } 8 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import globals from 'globals' 2 | import js from '@eslint/js' 3 | import ts from 'typescript-eslint' 4 | import prettier from 'eslint-plugin-prettier/recommended' 5 | 6 | const globalsConfig = { 7 | ...globals.node, 8 | ...globals.browser, 9 | } 10 | 11 | const rules = { 12 | 'prettier/prettier': 'error', 13 | 'prefer-const': 0, 14 | '@typescript-eslint/ban-ts-comment': 0, 15 | '@typescript-eslint/explicit-module-boundary-types': 0, 16 | '@typescript-eslint/no-unsafe-function-type': 0, 17 | '@typescript-eslint/no-explicit-any': 0, 18 | '@typescript-eslint/no-empty-function': 0, 19 | '@typescript-eslint/ban-types': 0, 20 | } 21 | 22 | export default [ 23 | { languageOptions: { globals: globalsConfig } }, 24 | js.configs.recommended, 25 | ...ts.configs.recommended, 26 | prettier, 27 | { rules }, 28 | { ignores: ['node_modules', 'dist'] }, 29 | ] 30 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Veact - dev 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /logo.svg: -------------------------------------------------------------------------------- 1 | 2 | logo 3 | 4 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "veact", 3 | "version": "1.0.0", 4 | "description": "Mutable state enhancer library for React by @vue/reactivity", 5 | "keywords": [ 6 | "React", 7 | "React mutable state", 8 | "React vue state", 9 | "React composition API", 10 | "React state library", 11 | "Vue reactivity" 12 | ], 13 | "license": "MIT", 14 | "author": "Surmon", 15 | "repository": "veactjs/veact", 16 | "homepage": "https://github.com/veactjs/veact", 17 | "funding": "https://github.com/veactjs/veact?sponsor=1", 18 | "files": [ 19 | "README.md", 20 | "CHANGELOG.md", 21 | "dist", 22 | "src" 23 | ], 24 | "sideEffects": false, 25 | "type": "module", 26 | "main": "./dist/veact.umd.cjs", 27 | "module": "./dist/veact.js", 28 | "browser": "./dist/veact.umd.cjs", 29 | "types": "./dist/veact.d.ts", 30 | "exports": { 31 | ".": { 32 | "types": "./dist/veact.d.ts", 33 | "import": "./dist/veact.js", 34 | "require": "./dist/veact.umd.cjs" 35 | } 36 | }, 37 | "scripts": { 38 | "dev": "vite", 39 | "build": "vite build", 40 | "lint": "eslint src", 41 | "format": "prettier --write --parser typescript \"src/**/*.ts\"", 42 | "test": "vitest run", 43 | "test:watch": "vitest watch", 44 | "test:coverage": "vitest run --coverage --reporter=junit --outputFile=./junit.xml", 45 | "ci": "npm run lint && npm run test && npm run build", 46 | "release": ". ./scripts/release.sh" 47 | }, 48 | "peerDependencies": { 49 | "react": "^16.8.0 || ^17 || ^18 || ^19", 50 | "react-dom": "^16.8.0 || ^17 || ^18 || ^19" 51 | }, 52 | "dependencies": { 53 | "@vue/reactivity": ">=3.5" 54 | }, 55 | "devDependencies": { 56 | "@eslint/js": "^9.x", 57 | "@testing-library/react": "^16.x", 58 | "@types/eslint": "^9.x", 59 | "@types/react": "^18.x", 60 | "@types/react-dom": "^18.x", 61 | "@vitejs/plugin-react": "^4.x", 62 | "@vitest/coverage-v8": "^2.x", 63 | "eslint": "^9.x", 64 | "eslint-config-prettier": "^9.x", 65 | "eslint-plugin-prettier": "^5.x", 66 | "globals": "^15.9.0", 67 | "happy-dom": "^15.x", 68 | "prettier": "^3.x", 69 | "react": "^18.x", 70 | "react-dom": "^18.x", 71 | "typescript": "^5.5.4", 72 | "typescript-eslint": "^8.x", 73 | "vite": "^5.x", 74 | "vite-plugin-dts": "^4.x", 75 | "vitest": "^2.x" 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@vue/reactivity': 12 | specifier: '>=3.5' 13 | version: 3.5.2 14 | devDependencies: 15 | '@eslint/js': 16 | specifier: ^9.x 17 | version: 9.9.1 18 | '@testing-library/react': 19 | specifier: ^16.x 20 | version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) 21 | '@types/eslint': 22 | specifier: ^9.x 23 | version: 9.6.1 24 | '@types/react': 25 | specifier: ^18.x 26 | version: 18.3.5 27 | '@types/react-dom': 28 | specifier: ^18.x 29 | version: 18.3.0 30 | '@vitejs/plugin-react': 31 | specifier: ^4.x 32 | version: 4.3.1(vite@5.4.3) 33 | '@vitest/coverage-v8': 34 | specifier: ^2.x 35 | version: 2.0.5(vitest@2.0.5(happy-dom@15.7.3)) 36 | eslint: 37 | specifier: ^9.x 38 | version: 9.9.1 39 | eslint-config-prettier: 40 | specifier: ^9.x 41 | version: 9.1.0(eslint@9.9.1) 42 | eslint-plugin-prettier: 43 | specifier: ^5.x 44 | version: 5.2.1(@types/eslint@9.6.1)(eslint-config-prettier@9.1.0(eslint@9.9.1))(eslint@9.9.1)(prettier@3.3.3) 45 | globals: 46 | specifier: ^15.9.0 47 | version: 15.9.0 48 | happy-dom: 49 | specifier: ^15.x 50 | version: 15.7.3 51 | prettier: 52 | specifier: ^3.x 53 | version: 3.3.3 54 | react: 55 | specifier: ^18.x 56 | version: 18.3.1 57 | react-dom: 58 | specifier: ^18.x 59 | version: 18.3.1(react@18.3.1) 60 | typescript: 61 | specifier: ^5.5.4 62 | version: 5.5.4 63 | typescript-eslint: 64 | specifier: ^8.x 65 | version: 8.4.0(eslint@9.9.1)(typescript@5.5.4) 66 | vite: 67 | specifier: ^5.x 68 | version: 5.4.3 69 | vite-plugin-dts: 70 | specifier: ^4.x 71 | version: 4.1.0(rollup@4.21.2)(typescript@5.5.4)(vite@5.4.3) 72 | vitest: 73 | specifier: ^2.x 74 | version: 2.0.5(happy-dom@15.7.3) 75 | 76 | packages: 77 | 78 | '@ampproject/remapping@2.3.0': 79 | resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} 80 | engines: {node: '>=6.0.0'} 81 | 82 | '@babel/code-frame@7.24.7': 83 | resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} 84 | engines: {node: '>=6.9.0'} 85 | 86 | '@babel/compat-data@7.25.4': 87 | resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} 88 | engines: {node: '>=6.9.0'} 89 | 90 | '@babel/core@7.25.2': 91 | resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} 92 | engines: {node: '>=6.9.0'} 93 | 94 | '@babel/generator@7.25.6': 95 | resolution: {integrity: sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==} 96 | engines: {node: '>=6.9.0'} 97 | 98 | '@babel/helper-compilation-targets@7.25.2': 99 | resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} 100 | engines: {node: '>=6.9.0'} 101 | 102 | '@babel/helper-module-imports@7.24.7': 103 | resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} 104 | engines: {node: '>=6.9.0'} 105 | 106 | '@babel/helper-module-transforms@7.25.2': 107 | resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} 108 | engines: {node: '>=6.9.0'} 109 | peerDependencies: 110 | '@babel/core': ^7.0.0 111 | 112 | '@babel/helper-plugin-utils@7.24.8': 113 | resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} 114 | engines: {node: '>=6.9.0'} 115 | 116 | '@babel/helper-simple-access@7.24.7': 117 | resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} 118 | engines: {node: '>=6.9.0'} 119 | 120 | '@babel/helper-string-parser@7.24.8': 121 | resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} 122 | engines: {node: '>=6.9.0'} 123 | 124 | '@babel/helper-validator-identifier@7.24.7': 125 | resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} 126 | engines: {node: '>=6.9.0'} 127 | 128 | '@babel/helper-validator-option@7.24.8': 129 | resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} 130 | engines: {node: '>=6.9.0'} 131 | 132 | '@babel/helpers@7.25.6': 133 | resolution: {integrity: sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==} 134 | engines: {node: '>=6.9.0'} 135 | 136 | '@babel/highlight@7.24.7': 137 | resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} 138 | engines: {node: '>=6.9.0'} 139 | 140 | '@babel/parser@7.25.6': 141 | resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==} 142 | engines: {node: '>=6.0.0'} 143 | hasBin: true 144 | 145 | '@babel/plugin-transform-react-jsx-self@7.24.7': 146 | resolution: {integrity: sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==} 147 | engines: {node: '>=6.9.0'} 148 | peerDependencies: 149 | '@babel/core': ^7.0.0-0 150 | 151 | '@babel/plugin-transform-react-jsx-source@7.24.7': 152 | resolution: {integrity: sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==} 153 | engines: {node: '>=6.9.0'} 154 | peerDependencies: 155 | '@babel/core': ^7.0.0-0 156 | 157 | '@babel/runtime@7.25.6': 158 | resolution: {integrity: sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==} 159 | engines: {node: '>=6.9.0'} 160 | 161 | '@babel/template@7.25.0': 162 | resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} 163 | engines: {node: '>=6.9.0'} 164 | 165 | '@babel/traverse@7.25.6': 166 | resolution: {integrity: sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==} 167 | engines: {node: '>=6.9.0'} 168 | 169 | '@babel/types@7.25.6': 170 | resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} 171 | engines: {node: '>=6.9.0'} 172 | 173 | '@bcoe/v8-coverage@0.2.3': 174 | resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} 175 | 176 | '@esbuild/aix-ppc64@0.21.5': 177 | resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} 178 | engines: {node: '>=12'} 179 | cpu: [ppc64] 180 | os: [aix] 181 | 182 | '@esbuild/android-arm64@0.21.5': 183 | resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} 184 | engines: {node: '>=12'} 185 | cpu: [arm64] 186 | os: [android] 187 | 188 | '@esbuild/android-arm@0.21.5': 189 | resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} 190 | engines: {node: '>=12'} 191 | cpu: [arm] 192 | os: [android] 193 | 194 | '@esbuild/android-x64@0.21.5': 195 | resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} 196 | engines: {node: '>=12'} 197 | cpu: [x64] 198 | os: [android] 199 | 200 | '@esbuild/darwin-arm64@0.21.5': 201 | resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} 202 | engines: {node: '>=12'} 203 | cpu: [arm64] 204 | os: [darwin] 205 | 206 | '@esbuild/darwin-x64@0.21.5': 207 | resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} 208 | engines: {node: '>=12'} 209 | cpu: [x64] 210 | os: [darwin] 211 | 212 | '@esbuild/freebsd-arm64@0.21.5': 213 | resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} 214 | engines: {node: '>=12'} 215 | cpu: [arm64] 216 | os: [freebsd] 217 | 218 | '@esbuild/freebsd-x64@0.21.5': 219 | resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} 220 | engines: {node: '>=12'} 221 | cpu: [x64] 222 | os: [freebsd] 223 | 224 | '@esbuild/linux-arm64@0.21.5': 225 | resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} 226 | engines: {node: '>=12'} 227 | cpu: [arm64] 228 | os: [linux] 229 | 230 | '@esbuild/linux-arm@0.21.5': 231 | resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} 232 | engines: {node: '>=12'} 233 | cpu: [arm] 234 | os: [linux] 235 | 236 | '@esbuild/linux-ia32@0.21.5': 237 | resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} 238 | engines: {node: '>=12'} 239 | cpu: [ia32] 240 | os: [linux] 241 | 242 | '@esbuild/linux-loong64@0.21.5': 243 | resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} 244 | engines: {node: '>=12'} 245 | cpu: [loong64] 246 | os: [linux] 247 | 248 | '@esbuild/linux-mips64el@0.21.5': 249 | resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} 250 | engines: {node: '>=12'} 251 | cpu: [mips64el] 252 | os: [linux] 253 | 254 | '@esbuild/linux-ppc64@0.21.5': 255 | resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} 256 | engines: {node: '>=12'} 257 | cpu: [ppc64] 258 | os: [linux] 259 | 260 | '@esbuild/linux-riscv64@0.21.5': 261 | resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} 262 | engines: {node: '>=12'} 263 | cpu: [riscv64] 264 | os: [linux] 265 | 266 | '@esbuild/linux-s390x@0.21.5': 267 | resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} 268 | engines: {node: '>=12'} 269 | cpu: [s390x] 270 | os: [linux] 271 | 272 | '@esbuild/linux-x64@0.21.5': 273 | resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} 274 | engines: {node: '>=12'} 275 | cpu: [x64] 276 | os: [linux] 277 | 278 | '@esbuild/netbsd-x64@0.21.5': 279 | resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} 280 | engines: {node: '>=12'} 281 | cpu: [x64] 282 | os: [netbsd] 283 | 284 | '@esbuild/openbsd-x64@0.21.5': 285 | resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} 286 | engines: {node: '>=12'} 287 | cpu: [x64] 288 | os: [openbsd] 289 | 290 | '@esbuild/sunos-x64@0.21.5': 291 | resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} 292 | engines: {node: '>=12'} 293 | cpu: [x64] 294 | os: [sunos] 295 | 296 | '@esbuild/win32-arm64@0.21.5': 297 | resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} 298 | engines: {node: '>=12'} 299 | cpu: [arm64] 300 | os: [win32] 301 | 302 | '@esbuild/win32-ia32@0.21.5': 303 | resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} 304 | engines: {node: '>=12'} 305 | cpu: [ia32] 306 | os: [win32] 307 | 308 | '@esbuild/win32-x64@0.21.5': 309 | resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} 310 | engines: {node: '>=12'} 311 | cpu: [x64] 312 | os: [win32] 313 | 314 | '@eslint-community/eslint-utils@4.4.0': 315 | resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} 316 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 317 | peerDependencies: 318 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 319 | 320 | '@eslint-community/regexpp@4.11.0': 321 | resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} 322 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} 323 | 324 | '@eslint/config-array@0.18.0': 325 | resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} 326 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 327 | 328 | '@eslint/eslintrc@3.1.0': 329 | resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} 330 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 331 | 332 | '@eslint/js@9.9.1': 333 | resolution: {integrity: sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==} 334 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 335 | 336 | '@eslint/object-schema@2.1.4': 337 | resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} 338 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 339 | 340 | '@humanwhocodes/module-importer@1.0.1': 341 | resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} 342 | engines: {node: '>=12.22'} 343 | 344 | '@humanwhocodes/retry@0.3.0': 345 | resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} 346 | engines: {node: '>=18.18'} 347 | 348 | '@isaacs/cliui@8.0.2': 349 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} 350 | engines: {node: '>=12'} 351 | 352 | '@istanbuljs/schema@0.1.3': 353 | resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} 354 | engines: {node: '>=8'} 355 | 356 | '@jridgewell/gen-mapping@0.3.5': 357 | resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} 358 | engines: {node: '>=6.0.0'} 359 | 360 | '@jridgewell/resolve-uri@3.1.2': 361 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 362 | engines: {node: '>=6.0.0'} 363 | 364 | '@jridgewell/set-array@1.2.1': 365 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} 366 | engines: {node: '>=6.0.0'} 367 | 368 | '@jridgewell/sourcemap-codec@1.5.0': 369 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 370 | 371 | '@jridgewell/trace-mapping@0.3.25': 372 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} 373 | 374 | '@microsoft/api-extractor-model@7.29.4': 375 | resolution: {integrity: sha512-LHOMxmT8/tU1IiiiHOdHFF83Qsi+V8d0kLfscG4EvQE9cafiR8blOYr8SfkQKWB1wgEilQgXJX3MIA4vetDLZw==} 376 | 377 | '@microsoft/api-extractor@7.47.4': 378 | resolution: {integrity: sha512-HKm+P4VNzWwvq1Ey+Jfhhj/3MjsD+ka2hbt8L5AcRM95lu1MFOYnz3XlU7Gr79Q/ZhOb7W/imAKeYrOI0bFydg==} 379 | hasBin: true 380 | 381 | '@microsoft/tsdoc-config@0.17.0': 382 | resolution: {integrity: sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==} 383 | 384 | '@microsoft/tsdoc@0.15.0': 385 | resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==} 386 | 387 | '@nodelib/fs.scandir@2.1.5': 388 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 389 | engines: {node: '>= 8'} 390 | 391 | '@nodelib/fs.stat@2.0.5': 392 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 393 | engines: {node: '>= 8'} 394 | 395 | '@nodelib/fs.walk@1.2.8': 396 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 397 | engines: {node: '>= 8'} 398 | 399 | '@pkgjs/parseargs@0.11.0': 400 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} 401 | engines: {node: '>=14'} 402 | 403 | '@pkgr/core@0.1.1': 404 | resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} 405 | engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} 406 | 407 | '@rollup/pluginutils@5.1.0': 408 | resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} 409 | engines: {node: '>=14.0.0'} 410 | peerDependencies: 411 | rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 412 | peerDependenciesMeta: 413 | rollup: 414 | optional: true 415 | 416 | '@rollup/rollup-android-arm-eabi@4.21.2': 417 | resolution: {integrity: sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==} 418 | cpu: [arm] 419 | os: [android] 420 | 421 | '@rollup/rollup-android-arm64@4.21.2': 422 | resolution: {integrity: sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==} 423 | cpu: [arm64] 424 | os: [android] 425 | 426 | '@rollup/rollup-darwin-arm64@4.21.2': 427 | resolution: {integrity: sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==} 428 | cpu: [arm64] 429 | os: [darwin] 430 | 431 | '@rollup/rollup-darwin-x64@4.21.2': 432 | resolution: {integrity: sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==} 433 | cpu: [x64] 434 | os: [darwin] 435 | 436 | '@rollup/rollup-linux-arm-gnueabihf@4.21.2': 437 | resolution: {integrity: sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==} 438 | cpu: [arm] 439 | os: [linux] 440 | 441 | '@rollup/rollup-linux-arm-musleabihf@4.21.2': 442 | resolution: {integrity: sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==} 443 | cpu: [arm] 444 | os: [linux] 445 | 446 | '@rollup/rollup-linux-arm64-gnu@4.21.2': 447 | resolution: {integrity: sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==} 448 | cpu: [arm64] 449 | os: [linux] 450 | 451 | '@rollup/rollup-linux-arm64-musl@4.21.2': 452 | resolution: {integrity: sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==} 453 | cpu: [arm64] 454 | os: [linux] 455 | 456 | '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': 457 | resolution: {integrity: sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==} 458 | cpu: [ppc64] 459 | os: [linux] 460 | 461 | '@rollup/rollup-linux-riscv64-gnu@4.21.2': 462 | resolution: {integrity: sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==} 463 | cpu: [riscv64] 464 | os: [linux] 465 | 466 | '@rollup/rollup-linux-s390x-gnu@4.21.2': 467 | resolution: {integrity: sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==} 468 | cpu: [s390x] 469 | os: [linux] 470 | 471 | '@rollup/rollup-linux-x64-gnu@4.21.2': 472 | resolution: {integrity: sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==} 473 | cpu: [x64] 474 | os: [linux] 475 | 476 | '@rollup/rollup-linux-x64-musl@4.21.2': 477 | resolution: {integrity: sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==} 478 | cpu: [x64] 479 | os: [linux] 480 | 481 | '@rollup/rollup-win32-arm64-msvc@4.21.2': 482 | resolution: {integrity: sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==} 483 | cpu: [arm64] 484 | os: [win32] 485 | 486 | '@rollup/rollup-win32-ia32-msvc@4.21.2': 487 | resolution: {integrity: sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==} 488 | cpu: [ia32] 489 | os: [win32] 490 | 491 | '@rollup/rollup-win32-x64-msvc@4.21.2': 492 | resolution: {integrity: sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==} 493 | cpu: [x64] 494 | os: [win32] 495 | 496 | '@rushstack/node-core-library@5.5.1': 497 | resolution: {integrity: sha512-ZutW56qIzH8xIOlfyaLQJFx+8IBqdbVCZdnj+XT1MorQ1JqqxHse8vbCpEM+2MjsrqcbxcgDIbfggB1ZSQ2A3g==} 498 | peerDependencies: 499 | '@types/node': '*' 500 | peerDependenciesMeta: 501 | '@types/node': 502 | optional: true 503 | 504 | '@rushstack/rig-package@0.5.3': 505 | resolution: {integrity: sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==} 506 | 507 | '@rushstack/terminal@0.13.3': 508 | resolution: {integrity: sha512-fc3zjXOw8E0pXS5t9vTiIPx9gHA0fIdTXsu9mT4WbH+P3mYvnrX0iAQ5a6NvyK1+CqYWBTw/wVNx7SDJkI+WYQ==} 509 | peerDependencies: 510 | '@types/node': '*' 511 | peerDependenciesMeta: 512 | '@types/node': 513 | optional: true 514 | 515 | '@rushstack/ts-command-line@4.22.3': 516 | resolution: {integrity: sha512-edMpWB3QhFFZ4KtSzS8WNjBgR4PXPPOVrOHMbb7kNpmQ1UFS9HdVtjCXg1H5fG+xYAbeE+TMPcVPUyX2p84STA==} 517 | 518 | '@testing-library/dom@10.4.0': 519 | resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} 520 | engines: {node: '>=18'} 521 | 522 | '@testing-library/react@16.0.1': 523 | resolution: {integrity: sha512-dSmwJVtJXmku+iocRhWOUFbrERC76TX2Mnf0ATODz8brzAZrMBbzLwQixlBSanZxR6LddK3eiwpSFZgDET1URg==} 524 | engines: {node: '>=18'} 525 | peerDependencies: 526 | '@testing-library/dom': ^10.0.0 527 | '@types/react': ^18.0.0 528 | '@types/react-dom': ^18.0.0 529 | react: ^18.0.0 530 | react-dom: ^18.0.0 531 | peerDependenciesMeta: 532 | '@types/react': 533 | optional: true 534 | '@types/react-dom': 535 | optional: true 536 | 537 | '@types/argparse@1.0.38': 538 | resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} 539 | 540 | '@types/aria-query@5.0.4': 541 | resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} 542 | 543 | '@types/babel__core@7.20.5': 544 | resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} 545 | 546 | '@types/babel__generator@7.6.8': 547 | resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} 548 | 549 | '@types/babel__template@7.4.4': 550 | resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} 551 | 552 | '@types/babel__traverse@7.20.6': 553 | resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} 554 | 555 | '@types/eslint@9.6.1': 556 | resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} 557 | 558 | '@types/estree@1.0.5': 559 | resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} 560 | 561 | '@types/json-schema@7.0.15': 562 | resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} 563 | 564 | '@types/prop-types@15.7.12': 565 | resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} 566 | 567 | '@types/react-dom@18.3.0': 568 | resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} 569 | 570 | '@types/react@18.3.5': 571 | resolution: {integrity: sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==} 572 | 573 | '@typescript-eslint/eslint-plugin@8.4.0': 574 | resolution: {integrity: sha512-rg8LGdv7ri3oAlenMACk9e+AR4wUV0yrrG+XKsGKOK0EVgeEDqurkXMPILG2836fW4ibokTB5v4b6Z9+GYQDEw==} 575 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 576 | peerDependencies: 577 | '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 578 | eslint: ^8.57.0 || ^9.0.0 579 | typescript: '*' 580 | peerDependenciesMeta: 581 | typescript: 582 | optional: true 583 | 584 | '@typescript-eslint/parser@8.4.0': 585 | resolution: {integrity: sha512-NHgWmKSgJk5K9N16GIhQ4jSobBoJwrmURaLErad0qlLjrpP5bECYg+wxVTGlGZmJbU03jj/dfnb6V9bw+5icsA==} 586 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 587 | peerDependencies: 588 | eslint: ^8.57.0 || ^9.0.0 589 | typescript: '*' 590 | peerDependenciesMeta: 591 | typescript: 592 | optional: true 593 | 594 | '@typescript-eslint/scope-manager@8.4.0': 595 | resolution: {integrity: sha512-n2jFxLeY0JmKfUqy3P70rs6vdoPjHK8P/w+zJcV3fk0b0BwRXC/zxRTEnAsgYT7MwdQDt/ZEbtdzdVC+hcpF0A==} 596 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 597 | 598 | '@typescript-eslint/type-utils@8.4.0': 599 | resolution: {integrity: sha512-pu2PAmNrl9KX6TtirVOrbLPLwDmASpZhK/XU7WvoKoCUkdtq9zF7qQ7gna0GBZFN0hci0vHaSusiL2WpsQk37A==} 600 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 601 | peerDependencies: 602 | typescript: '*' 603 | peerDependenciesMeta: 604 | typescript: 605 | optional: true 606 | 607 | '@typescript-eslint/types@8.4.0': 608 | resolution: {integrity: sha512-T1RB3KQdskh9t3v/qv7niK6P8yvn7ja1mS7QK7XfRVL6wtZ8/mFs/FHf4fKvTA0rKnqnYxl/uHFNbnEt0phgbw==} 609 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 610 | 611 | '@typescript-eslint/typescript-estree@8.4.0': 612 | resolution: {integrity: sha512-kJ2OIP4dQw5gdI4uXsaxUZHRwWAGpREJ9Zq6D5L0BweyOrWsL6Sz0YcAZGWhvKnH7fm1J5YFE1JrQL0c9dd53A==} 613 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 614 | peerDependencies: 615 | typescript: '*' 616 | peerDependenciesMeta: 617 | typescript: 618 | optional: true 619 | 620 | '@typescript-eslint/utils@8.4.0': 621 | resolution: {integrity: sha512-swULW8n1IKLjRAgciCkTCafyTHHfwVQFt8DovmaF69sKbOxTSFMmIZaSHjqO9i/RV0wIblaawhzvtva8Nmm7lQ==} 622 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 623 | peerDependencies: 624 | eslint: ^8.57.0 || ^9.0.0 625 | 626 | '@typescript-eslint/visitor-keys@8.4.0': 627 | resolution: {integrity: sha512-zTQD6WLNTre1hj5wp09nBIDiOc2U5r/qmzo7wxPn4ZgAjHql09EofqhF9WF+fZHzL5aCyaIpPcT2hyxl73kr9A==} 628 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 629 | 630 | '@vitejs/plugin-react@4.3.1': 631 | resolution: {integrity: sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==} 632 | engines: {node: ^14.18.0 || >=16.0.0} 633 | peerDependencies: 634 | vite: ^4.2.0 || ^5.0.0 635 | 636 | '@vitest/coverage-v8@2.0.5': 637 | resolution: {integrity: sha512-qeFcySCg5FLO2bHHSa0tAZAOnAUbp4L6/A5JDuj9+bt53JREl8hpLjLHEWF0e/gWc8INVpJaqA7+Ene2rclpZg==} 638 | peerDependencies: 639 | vitest: 2.0.5 640 | 641 | '@vitest/expect@2.0.5': 642 | resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} 643 | 644 | '@vitest/pretty-format@2.0.5': 645 | resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} 646 | 647 | '@vitest/runner@2.0.5': 648 | resolution: {integrity: sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==} 649 | 650 | '@vitest/snapshot@2.0.5': 651 | resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==} 652 | 653 | '@vitest/spy@2.0.5': 654 | resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} 655 | 656 | '@vitest/utils@2.0.5': 657 | resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} 658 | 659 | '@volar/language-core@2.4.2': 660 | resolution: {integrity: sha512-sONt5RLvLL1SlBdhyUSthZzuKePbJ7DwFFB9zT0eyWpDl+v7GXGh/RkPxxWaR22bIhYtTzp4Ka1MWatl/53Riw==} 661 | 662 | '@volar/source-map@2.4.2': 663 | resolution: {integrity: sha512-qiGfGgeZ5DEarPX3S+HcFktFCjfDrFPCXKeXNbrlB7v8cvtPRm8YVwoXOdGG1NhaL5rMlv5BZPVQyu4EdWWIvA==} 664 | 665 | '@volar/typescript@2.4.2': 666 | resolution: {integrity: sha512-m2uZduhaHO1SZuagi30OsjI/X1gwkaEAC+9wT/nCNAtJ5FqXEkKvUncHmffG7ESDZPlFFUBK4vJ0D9Hfr+f2EA==} 667 | 668 | '@vue/compiler-core@3.5.2': 669 | resolution: {integrity: sha512-1aP7FL2GkqfcskHWGg3lfWQpJnrmewKc+rNJ/hq9WNaAw4BEyJ5QbNChnqmbw+tJ409zdy1XWmUeXXMrCKJcQQ==} 670 | 671 | '@vue/compiler-dom@3.5.2': 672 | resolution: {integrity: sha512-QY4DpT8ZIUyu/ZA5gErpSEDocGNEbHmpkZIC/d5jbp/rUF0iOJNigAy3HCCKc0PMMhDlrcysO3ufQ6Ab4MpEcQ==} 673 | 674 | '@vue/compiler-vue2@2.7.16': 675 | resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} 676 | 677 | '@vue/language-core@2.0.29': 678 | resolution: {integrity: sha512-o2qz9JPjhdoVj8D2+9bDXbaI4q2uZTHQA/dbyZT4Bj1FR9viZxDJnLcKVHfxdn6wsOzRgpqIzJEEmSSvgMvDTQ==} 679 | peerDependencies: 680 | typescript: '*' 681 | peerDependenciesMeta: 682 | typescript: 683 | optional: true 684 | 685 | '@vue/reactivity@3.5.2': 686 | resolution: {integrity: sha512-lJwWL5bNht+2vIwU/+lnGdH+FKFxzz6z8WkoIJityPLiasWU+HDUvEsC7gm3JFwbTf7Kk+Nr9kJMaPy0HXwwxQ==} 687 | 688 | '@vue/shared@3.5.2': 689 | resolution: {integrity: sha512-Ce89WNFBzcDca/AgFTxgX4/K4iAyF7oFIp8Z5aBbFBNbtpwnQr+5pZOoHndxnjE2h+YFcipVMzs9UL11XB6dwA==} 690 | 691 | acorn-jsx@5.3.2: 692 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 693 | peerDependencies: 694 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 695 | 696 | acorn@8.12.1: 697 | resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} 698 | engines: {node: '>=0.4.0'} 699 | hasBin: true 700 | 701 | ajv-draft-04@1.0.0: 702 | resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} 703 | peerDependencies: 704 | ajv: ^8.5.0 705 | peerDependenciesMeta: 706 | ajv: 707 | optional: true 708 | 709 | ajv-formats@3.0.1: 710 | resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} 711 | peerDependencies: 712 | ajv: ^8.0.0 713 | peerDependenciesMeta: 714 | ajv: 715 | optional: true 716 | 717 | ajv@6.12.6: 718 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 719 | 720 | ajv@8.12.0: 721 | resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} 722 | 723 | ajv@8.13.0: 724 | resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==} 725 | 726 | ansi-regex@5.0.1: 727 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 728 | engines: {node: '>=8'} 729 | 730 | ansi-regex@6.0.1: 731 | resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} 732 | engines: {node: '>=12'} 733 | 734 | ansi-styles@3.2.1: 735 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 736 | engines: {node: '>=4'} 737 | 738 | ansi-styles@4.3.0: 739 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 740 | engines: {node: '>=8'} 741 | 742 | ansi-styles@5.2.0: 743 | resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} 744 | engines: {node: '>=10'} 745 | 746 | ansi-styles@6.2.1: 747 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 748 | engines: {node: '>=12'} 749 | 750 | argparse@1.0.10: 751 | resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} 752 | 753 | argparse@2.0.1: 754 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 755 | 756 | aria-query@5.3.0: 757 | resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} 758 | 759 | assertion-error@2.0.1: 760 | resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} 761 | engines: {node: '>=12'} 762 | 763 | balanced-match@1.0.2: 764 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 765 | 766 | brace-expansion@1.1.11: 767 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 768 | 769 | brace-expansion@2.0.1: 770 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 771 | 772 | braces@3.0.3: 773 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 774 | engines: {node: '>=8'} 775 | 776 | browserslist@4.23.3: 777 | resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} 778 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 779 | hasBin: true 780 | 781 | cac@6.7.14: 782 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 783 | engines: {node: '>=8'} 784 | 785 | callsites@3.1.0: 786 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 787 | engines: {node: '>=6'} 788 | 789 | caniuse-lite@1.0.30001657: 790 | resolution: {integrity: sha512-DPbJAlP8/BAXy3IgiWmZKItubb3TYGP0WscQQlVGIfT4s/YlFYVuJgyOsQNP7rJRChx/qdMeLJQJP0Sgg2yjNA==} 791 | 792 | chai@5.1.1: 793 | resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} 794 | engines: {node: '>=12'} 795 | 796 | chalk@2.4.2: 797 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 798 | engines: {node: '>=4'} 799 | 800 | chalk@4.1.2: 801 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 802 | engines: {node: '>=10'} 803 | 804 | check-error@2.1.1: 805 | resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} 806 | engines: {node: '>= 16'} 807 | 808 | color-convert@1.9.3: 809 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 810 | 811 | color-convert@2.0.1: 812 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 813 | engines: {node: '>=7.0.0'} 814 | 815 | color-name@1.1.3: 816 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 817 | 818 | color-name@1.1.4: 819 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 820 | 821 | compare-versions@6.1.1: 822 | resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} 823 | 824 | computeds@0.0.1: 825 | resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} 826 | 827 | concat-map@0.0.1: 828 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 829 | 830 | confbox@0.1.7: 831 | resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} 832 | 833 | convert-source-map@2.0.0: 834 | resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} 835 | 836 | cross-spawn@7.0.3: 837 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 838 | engines: {node: '>= 8'} 839 | 840 | csstype@3.1.3: 841 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 842 | 843 | de-indent@1.0.2: 844 | resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} 845 | 846 | debug@4.3.6: 847 | resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} 848 | engines: {node: '>=6.0'} 849 | peerDependencies: 850 | supports-color: '*' 851 | peerDependenciesMeta: 852 | supports-color: 853 | optional: true 854 | 855 | deep-eql@5.0.2: 856 | resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} 857 | engines: {node: '>=6'} 858 | 859 | deep-is@0.1.4: 860 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 861 | 862 | dequal@2.0.3: 863 | resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} 864 | engines: {node: '>=6'} 865 | 866 | dom-accessibility-api@0.5.16: 867 | resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} 868 | 869 | eastasianwidth@0.2.0: 870 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 871 | 872 | electron-to-chromium@1.5.14: 873 | resolution: {integrity: sha512-bEfPECb3fJ15eaDnu9LEJ2vPGD6W1vt7vZleSVyFhYuMIKm3vz/g9lt7IvEzgdwj58RjbPKUF2rXTCN/UW47tQ==} 874 | 875 | emoji-regex@8.0.0: 876 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 877 | 878 | emoji-regex@9.2.2: 879 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 880 | 881 | entities@4.5.0: 882 | resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} 883 | engines: {node: '>=0.12'} 884 | 885 | esbuild@0.21.5: 886 | resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} 887 | engines: {node: '>=12'} 888 | hasBin: true 889 | 890 | escalade@3.2.0: 891 | resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} 892 | engines: {node: '>=6'} 893 | 894 | escape-string-regexp@1.0.5: 895 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 896 | engines: {node: '>=0.8.0'} 897 | 898 | escape-string-regexp@4.0.0: 899 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 900 | engines: {node: '>=10'} 901 | 902 | eslint-config-prettier@9.1.0: 903 | resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} 904 | hasBin: true 905 | peerDependencies: 906 | eslint: '>=7.0.0' 907 | 908 | eslint-plugin-prettier@5.2.1: 909 | resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==} 910 | engines: {node: ^14.18.0 || >=16.0.0} 911 | peerDependencies: 912 | '@types/eslint': '>=8.0.0' 913 | eslint: '>=8.0.0' 914 | eslint-config-prettier: '*' 915 | prettier: '>=3.0.0' 916 | peerDependenciesMeta: 917 | '@types/eslint': 918 | optional: true 919 | eslint-config-prettier: 920 | optional: true 921 | 922 | eslint-scope@8.0.2: 923 | resolution: {integrity: sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==} 924 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 925 | 926 | eslint-visitor-keys@3.4.3: 927 | resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} 928 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 929 | 930 | eslint-visitor-keys@4.0.0: 931 | resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} 932 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 933 | 934 | eslint@9.9.1: 935 | resolution: {integrity: sha512-dHvhrbfr4xFQ9/dq+jcVneZMyRYLjggWjk6RVsIiHsP8Rz6yZ8LvZ//iU4TrZF+SXWG+JkNF2OyiZRvzgRDqMg==} 936 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 937 | hasBin: true 938 | peerDependencies: 939 | jiti: '*' 940 | peerDependenciesMeta: 941 | jiti: 942 | optional: true 943 | 944 | espree@10.1.0: 945 | resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} 946 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 947 | 948 | esquery@1.6.0: 949 | resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} 950 | engines: {node: '>=0.10'} 951 | 952 | esrecurse@4.3.0: 953 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 954 | engines: {node: '>=4.0'} 955 | 956 | estraverse@5.3.0: 957 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 958 | engines: {node: '>=4.0'} 959 | 960 | estree-walker@2.0.2: 961 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 962 | 963 | estree-walker@3.0.3: 964 | resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} 965 | 966 | esutils@2.0.3: 967 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 968 | engines: {node: '>=0.10.0'} 969 | 970 | execa@8.0.1: 971 | resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} 972 | engines: {node: '>=16.17'} 973 | 974 | fast-deep-equal@3.1.3: 975 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 976 | 977 | fast-diff@1.3.0: 978 | resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} 979 | 980 | fast-glob@3.3.2: 981 | resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} 982 | engines: {node: '>=8.6.0'} 983 | 984 | fast-json-stable-stringify@2.1.0: 985 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 986 | 987 | fast-levenshtein@2.0.6: 988 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 989 | 990 | fastq@1.17.1: 991 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} 992 | 993 | file-entry-cache@8.0.0: 994 | resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} 995 | engines: {node: '>=16.0.0'} 996 | 997 | fill-range@7.1.1: 998 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 999 | engines: {node: '>=8'} 1000 | 1001 | find-up@5.0.0: 1002 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} 1003 | engines: {node: '>=10'} 1004 | 1005 | flat-cache@4.0.1: 1006 | resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} 1007 | engines: {node: '>=16'} 1008 | 1009 | flatted@3.3.1: 1010 | resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} 1011 | 1012 | foreground-child@3.3.0: 1013 | resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} 1014 | engines: {node: '>=14'} 1015 | 1016 | fs-extra@7.0.1: 1017 | resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} 1018 | engines: {node: '>=6 <7 || >=8'} 1019 | 1020 | fsevents@2.3.3: 1021 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 1022 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 1023 | os: [darwin] 1024 | 1025 | function-bind@1.1.2: 1026 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 1027 | 1028 | gensync@1.0.0-beta.2: 1029 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} 1030 | engines: {node: '>=6.9.0'} 1031 | 1032 | get-func-name@2.0.2: 1033 | resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} 1034 | 1035 | get-stream@8.0.1: 1036 | resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} 1037 | engines: {node: '>=16'} 1038 | 1039 | glob-parent@5.1.2: 1040 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 1041 | engines: {node: '>= 6'} 1042 | 1043 | glob-parent@6.0.2: 1044 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 1045 | engines: {node: '>=10.13.0'} 1046 | 1047 | glob@10.4.5: 1048 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} 1049 | hasBin: true 1050 | 1051 | globals@11.12.0: 1052 | resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} 1053 | engines: {node: '>=4'} 1054 | 1055 | globals@14.0.0: 1056 | resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} 1057 | engines: {node: '>=18'} 1058 | 1059 | globals@15.9.0: 1060 | resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==} 1061 | engines: {node: '>=18'} 1062 | 1063 | graceful-fs@4.2.11: 1064 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 1065 | 1066 | graphemer@1.4.0: 1067 | resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} 1068 | 1069 | happy-dom@15.7.3: 1070 | resolution: {integrity: sha512-w3RUaYNXFJX5LiNVhOJLK4GqCB1bFj1FvELtpon3HrN8gUpS09V0Vvm4/BBRRj7mLUE1+ch8PKv1JxEp/0IHjA==} 1071 | engines: {node: '>=18.0.0'} 1072 | 1073 | has-flag@3.0.0: 1074 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 1075 | engines: {node: '>=4'} 1076 | 1077 | has-flag@4.0.0: 1078 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 1079 | engines: {node: '>=8'} 1080 | 1081 | hasown@2.0.2: 1082 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 1083 | engines: {node: '>= 0.4'} 1084 | 1085 | he@1.2.0: 1086 | resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} 1087 | hasBin: true 1088 | 1089 | html-escaper@2.0.2: 1090 | resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} 1091 | 1092 | human-signals@5.0.0: 1093 | resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} 1094 | engines: {node: '>=16.17.0'} 1095 | 1096 | ignore@5.3.2: 1097 | resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} 1098 | engines: {node: '>= 4'} 1099 | 1100 | import-fresh@3.3.0: 1101 | resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} 1102 | engines: {node: '>=6'} 1103 | 1104 | import-lazy@4.0.0: 1105 | resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} 1106 | engines: {node: '>=8'} 1107 | 1108 | imurmurhash@0.1.4: 1109 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 1110 | engines: {node: '>=0.8.19'} 1111 | 1112 | is-core-module@2.15.1: 1113 | resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} 1114 | engines: {node: '>= 0.4'} 1115 | 1116 | is-extglob@2.1.1: 1117 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 1118 | engines: {node: '>=0.10.0'} 1119 | 1120 | is-fullwidth-code-point@3.0.0: 1121 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 1122 | engines: {node: '>=8'} 1123 | 1124 | is-glob@4.0.3: 1125 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 1126 | engines: {node: '>=0.10.0'} 1127 | 1128 | is-number@7.0.0: 1129 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 1130 | engines: {node: '>=0.12.0'} 1131 | 1132 | is-path-inside@3.0.3: 1133 | resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} 1134 | engines: {node: '>=8'} 1135 | 1136 | is-stream@3.0.0: 1137 | resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} 1138 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1139 | 1140 | isexe@2.0.0: 1141 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 1142 | 1143 | istanbul-lib-coverage@3.2.2: 1144 | resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} 1145 | engines: {node: '>=8'} 1146 | 1147 | istanbul-lib-report@3.0.1: 1148 | resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} 1149 | engines: {node: '>=10'} 1150 | 1151 | istanbul-lib-source-maps@5.0.6: 1152 | resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} 1153 | engines: {node: '>=10'} 1154 | 1155 | istanbul-reports@3.1.7: 1156 | resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} 1157 | engines: {node: '>=8'} 1158 | 1159 | jackspeak@3.4.3: 1160 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} 1161 | 1162 | jju@1.4.0: 1163 | resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} 1164 | 1165 | js-tokens@4.0.0: 1166 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 1167 | 1168 | js-yaml@4.1.0: 1169 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 1170 | hasBin: true 1171 | 1172 | jsesc@2.5.2: 1173 | resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} 1174 | engines: {node: '>=4'} 1175 | hasBin: true 1176 | 1177 | json-buffer@3.0.1: 1178 | resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} 1179 | 1180 | json-schema-traverse@0.4.1: 1181 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 1182 | 1183 | json-schema-traverse@1.0.0: 1184 | resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} 1185 | 1186 | json-stable-stringify-without-jsonify@1.0.1: 1187 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} 1188 | 1189 | json5@2.2.3: 1190 | resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} 1191 | engines: {node: '>=6'} 1192 | hasBin: true 1193 | 1194 | jsonfile@4.0.0: 1195 | resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} 1196 | 1197 | keyv@4.5.4: 1198 | resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} 1199 | 1200 | kolorist@1.8.0: 1201 | resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} 1202 | 1203 | levn@0.4.1: 1204 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 1205 | engines: {node: '>= 0.8.0'} 1206 | 1207 | local-pkg@0.5.0: 1208 | resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} 1209 | engines: {node: '>=14'} 1210 | 1211 | locate-path@6.0.0: 1212 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} 1213 | engines: {node: '>=10'} 1214 | 1215 | lodash.merge@4.6.2: 1216 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 1217 | 1218 | lodash@4.17.21: 1219 | resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} 1220 | 1221 | loose-envify@1.4.0: 1222 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 1223 | hasBin: true 1224 | 1225 | loupe@3.1.1: 1226 | resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} 1227 | 1228 | lru-cache@10.4.3: 1229 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} 1230 | 1231 | lru-cache@5.1.1: 1232 | resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} 1233 | 1234 | lru-cache@6.0.0: 1235 | resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} 1236 | engines: {node: '>=10'} 1237 | 1238 | lz-string@1.5.0: 1239 | resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} 1240 | hasBin: true 1241 | 1242 | magic-string@0.30.11: 1243 | resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} 1244 | 1245 | magicast@0.3.5: 1246 | resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} 1247 | 1248 | make-dir@4.0.0: 1249 | resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} 1250 | engines: {node: '>=10'} 1251 | 1252 | merge-stream@2.0.0: 1253 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 1254 | 1255 | merge2@1.4.1: 1256 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 1257 | engines: {node: '>= 8'} 1258 | 1259 | micromatch@4.0.8: 1260 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 1261 | engines: {node: '>=8.6'} 1262 | 1263 | mimic-fn@4.0.0: 1264 | resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} 1265 | engines: {node: '>=12'} 1266 | 1267 | minimatch@3.0.8: 1268 | resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==} 1269 | 1270 | minimatch@3.1.2: 1271 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 1272 | 1273 | minimatch@9.0.5: 1274 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} 1275 | engines: {node: '>=16 || 14 >=14.17'} 1276 | 1277 | minipass@7.1.2: 1278 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} 1279 | engines: {node: '>=16 || 14 >=14.17'} 1280 | 1281 | mlly@1.7.1: 1282 | resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} 1283 | 1284 | ms@2.1.2: 1285 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 1286 | 1287 | muggle-string@0.4.1: 1288 | resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} 1289 | 1290 | nanoid@3.3.7: 1291 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 1292 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1293 | hasBin: true 1294 | 1295 | natural-compare@1.4.0: 1296 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 1297 | 1298 | node-releases@2.0.18: 1299 | resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} 1300 | 1301 | npm-run-path@5.3.0: 1302 | resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} 1303 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1304 | 1305 | onetime@6.0.0: 1306 | resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} 1307 | engines: {node: '>=12'} 1308 | 1309 | optionator@0.9.4: 1310 | resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} 1311 | engines: {node: '>= 0.8.0'} 1312 | 1313 | p-limit@3.1.0: 1314 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 1315 | engines: {node: '>=10'} 1316 | 1317 | p-locate@5.0.0: 1318 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 1319 | engines: {node: '>=10'} 1320 | 1321 | package-json-from-dist@1.0.0: 1322 | resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} 1323 | 1324 | parent-module@1.0.1: 1325 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 1326 | engines: {node: '>=6'} 1327 | 1328 | path-browserify@1.0.1: 1329 | resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} 1330 | 1331 | path-exists@4.0.0: 1332 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 1333 | engines: {node: '>=8'} 1334 | 1335 | path-key@3.1.1: 1336 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 1337 | engines: {node: '>=8'} 1338 | 1339 | path-key@4.0.0: 1340 | resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} 1341 | engines: {node: '>=12'} 1342 | 1343 | path-parse@1.0.7: 1344 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 1345 | 1346 | path-scurry@1.11.1: 1347 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} 1348 | engines: {node: '>=16 || 14 >=14.18'} 1349 | 1350 | pathe@1.1.2: 1351 | resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} 1352 | 1353 | pathval@2.0.0: 1354 | resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} 1355 | engines: {node: '>= 14.16'} 1356 | 1357 | picocolors@1.1.0: 1358 | resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} 1359 | 1360 | picomatch@2.3.1: 1361 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1362 | engines: {node: '>=8.6'} 1363 | 1364 | pkg-types@1.2.0: 1365 | resolution: {integrity: sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==} 1366 | 1367 | postcss@8.4.45: 1368 | resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==} 1369 | engines: {node: ^10 || ^12 || >=14} 1370 | 1371 | prelude-ls@1.2.1: 1372 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 1373 | engines: {node: '>= 0.8.0'} 1374 | 1375 | prettier-linter-helpers@1.0.0: 1376 | resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} 1377 | engines: {node: '>=6.0.0'} 1378 | 1379 | prettier@3.3.3: 1380 | resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} 1381 | engines: {node: '>=14'} 1382 | hasBin: true 1383 | 1384 | pretty-format@27.5.1: 1385 | resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} 1386 | engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} 1387 | 1388 | punycode@2.3.1: 1389 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 1390 | engines: {node: '>=6'} 1391 | 1392 | queue-microtask@1.2.3: 1393 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 1394 | 1395 | react-dom@18.3.1: 1396 | resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} 1397 | peerDependencies: 1398 | react: ^18.3.1 1399 | 1400 | react-is@17.0.2: 1401 | resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} 1402 | 1403 | react-refresh@0.14.2: 1404 | resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} 1405 | engines: {node: '>=0.10.0'} 1406 | 1407 | react@18.3.1: 1408 | resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} 1409 | engines: {node: '>=0.10.0'} 1410 | 1411 | regenerator-runtime@0.14.1: 1412 | resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} 1413 | 1414 | require-from-string@2.0.2: 1415 | resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} 1416 | engines: {node: '>=0.10.0'} 1417 | 1418 | resolve-from@4.0.0: 1419 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 1420 | engines: {node: '>=4'} 1421 | 1422 | resolve@1.22.8: 1423 | resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} 1424 | hasBin: true 1425 | 1426 | reusify@1.0.4: 1427 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1428 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1429 | 1430 | rollup@4.21.2: 1431 | resolution: {integrity: sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==} 1432 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 1433 | hasBin: true 1434 | 1435 | run-parallel@1.2.0: 1436 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 1437 | 1438 | scheduler@0.23.2: 1439 | resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} 1440 | 1441 | semver@6.3.1: 1442 | resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} 1443 | hasBin: true 1444 | 1445 | semver@7.5.4: 1446 | resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} 1447 | engines: {node: '>=10'} 1448 | hasBin: true 1449 | 1450 | semver@7.6.3: 1451 | resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} 1452 | engines: {node: '>=10'} 1453 | hasBin: true 1454 | 1455 | shebang-command@2.0.0: 1456 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1457 | engines: {node: '>=8'} 1458 | 1459 | shebang-regex@3.0.0: 1460 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1461 | engines: {node: '>=8'} 1462 | 1463 | siginfo@2.0.0: 1464 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 1465 | 1466 | signal-exit@4.1.0: 1467 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 1468 | engines: {node: '>=14'} 1469 | 1470 | source-map-js@1.2.0: 1471 | resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} 1472 | engines: {node: '>=0.10.0'} 1473 | 1474 | source-map@0.6.1: 1475 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 1476 | engines: {node: '>=0.10.0'} 1477 | 1478 | sprintf-js@1.0.3: 1479 | resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} 1480 | 1481 | stackback@0.0.2: 1482 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 1483 | 1484 | std-env@3.7.0: 1485 | resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} 1486 | 1487 | string-argv@0.3.2: 1488 | resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} 1489 | engines: {node: '>=0.6.19'} 1490 | 1491 | string-width@4.2.3: 1492 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 1493 | engines: {node: '>=8'} 1494 | 1495 | string-width@5.1.2: 1496 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 1497 | engines: {node: '>=12'} 1498 | 1499 | strip-ansi@6.0.1: 1500 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1501 | engines: {node: '>=8'} 1502 | 1503 | strip-ansi@7.1.0: 1504 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} 1505 | engines: {node: '>=12'} 1506 | 1507 | strip-final-newline@3.0.0: 1508 | resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} 1509 | engines: {node: '>=12'} 1510 | 1511 | strip-json-comments@3.1.1: 1512 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 1513 | engines: {node: '>=8'} 1514 | 1515 | supports-color@5.5.0: 1516 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 1517 | engines: {node: '>=4'} 1518 | 1519 | supports-color@7.2.0: 1520 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1521 | engines: {node: '>=8'} 1522 | 1523 | supports-color@8.1.1: 1524 | resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} 1525 | engines: {node: '>=10'} 1526 | 1527 | supports-preserve-symlinks-flag@1.0.0: 1528 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 1529 | engines: {node: '>= 0.4'} 1530 | 1531 | synckit@0.9.1: 1532 | resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==} 1533 | engines: {node: ^14.18.0 || >=16.0.0} 1534 | 1535 | test-exclude@7.0.1: 1536 | resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} 1537 | engines: {node: '>=18'} 1538 | 1539 | text-table@0.2.0: 1540 | resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} 1541 | 1542 | tinybench@2.9.0: 1543 | resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} 1544 | 1545 | tinypool@1.0.1: 1546 | resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} 1547 | engines: {node: ^18.0.0 || >=20.0.0} 1548 | 1549 | tinyrainbow@1.2.0: 1550 | resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} 1551 | engines: {node: '>=14.0.0'} 1552 | 1553 | tinyspy@3.0.0: 1554 | resolution: {integrity: sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==} 1555 | engines: {node: '>=14.0.0'} 1556 | 1557 | to-fast-properties@2.0.0: 1558 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} 1559 | engines: {node: '>=4'} 1560 | 1561 | to-regex-range@5.0.1: 1562 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1563 | engines: {node: '>=8.0'} 1564 | 1565 | ts-api-utils@1.3.0: 1566 | resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} 1567 | engines: {node: '>=16'} 1568 | peerDependencies: 1569 | typescript: '>=4.2.0' 1570 | 1571 | tslib@2.7.0: 1572 | resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} 1573 | 1574 | type-check@0.4.0: 1575 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 1576 | engines: {node: '>= 0.8.0'} 1577 | 1578 | typescript-eslint@8.4.0: 1579 | resolution: {integrity: sha512-67qoc3zQZe3CAkO0ua17+7aCLI0dU+sSQd1eKPGq06QE4rfQjstVXR6woHO5qQvGUa550NfGckT4tzh3b3c8Pw==} 1580 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1581 | peerDependencies: 1582 | typescript: '*' 1583 | peerDependenciesMeta: 1584 | typescript: 1585 | optional: true 1586 | 1587 | typescript@5.4.2: 1588 | resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} 1589 | engines: {node: '>=14.17'} 1590 | hasBin: true 1591 | 1592 | typescript@5.5.4: 1593 | resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} 1594 | engines: {node: '>=14.17'} 1595 | hasBin: true 1596 | 1597 | ufo@1.5.4: 1598 | resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} 1599 | 1600 | universalify@0.1.2: 1601 | resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} 1602 | engines: {node: '>= 4.0.0'} 1603 | 1604 | update-browserslist-db@1.1.0: 1605 | resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} 1606 | hasBin: true 1607 | peerDependencies: 1608 | browserslist: '>= 4.21.0' 1609 | 1610 | uri-js@4.4.1: 1611 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 1612 | 1613 | vite-node@2.0.5: 1614 | resolution: {integrity: sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==} 1615 | engines: {node: ^18.0.0 || >=20.0.0} 1616 | hasBin: true 1617 | 1618 | vite-plugin-dts@4.1.0: 1619 | resolution: {integrity: sha512-sRlmt9k2q8MrX4F2058N3KmB6WyJ3Ao6QaExOv1X99F3j0GhPziEz1zscWQ1q2r1PeFc96L7GIUu8Pl2DPr2Hg==} 1620 | engines: {node: ^14.18.0 || >=16.0.0} 1621 | peerDependencies: 1622 | typescript: '*' 1623 | vite: '*' 1624 | peerDependenciesMeta: 1625 | vite: 1626 | optional: true 1627 | 1628 | vite@5.4.3: 1629 | resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==} 1630 | engines: {node: ^18.0.0 || >=20.0.0} 1631 | hasBin: true 1632 | peerDependencies: 1633 | '@types/node': ^18.0.0 || >=20.0.0 1634 | less: '*' 1635 | lightningcss: ^1.21.0 1636 | sass: '*' 1637 | sass-embedded: '*' 1638 | stylus: '*' 1639 | sugarss: '*' 1640 | terser: ^5.4.0 1641 | peerDependenciesMeta: 1642 | '@types/node': 1643 | optional: true 1644 | less: 1645 | optional: true 1646 | lightningcss: 1647 | optional: true 1648 | sass: 1649 | optional: true 1650 | sass-embedded: 1651 | optional: true 1652 | stylus: 1653 | optional: true 1654 | sugarss: 1655 | optional: true 1656 | terser: 1657 | optional: true 1658 | 1659 | vitest@2.0.5: 1660 | resolution: {integrity: sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==} 1661 | engines: {node: ^18.0.0 || >=20.0.0} 1662 | hasBin: true 1663 | peerDependencies: 1664 | '@edge-runtime/vm': '*' 1665 | '@types/node': ^18.0.0 || >=20.0.0 1666 | '@vitest/browser': 2.0.5 1667 | '@vitest/ui': 2.0.5 1668 | happy-dom: '*' 1669 | jsdom: '*' 1670 | peerDependenciesMeta: 1671 | '@edge-runtime/vm': 1672 | optional: true 1673 | '@types/node': 1674 | optional: true 1675 | '@vitest/browser': 1676 | optional: true 1677 | '@vitest/ui': 1678 | optional: true 1679 | happy-dom: 1680 | optional: true 1681 | jsdom: 1682 | optional: true 1683 | 1684 | vscode-uri@3.0.8: 1685 | resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} 1686 | 1687 | vue-tsc@2.0.29: 1688 | resolution: {integrity: sha512-MHhsfyxO3mYShZCGYNziSbc63x7cQ5g9kvijV7dRe1TTXBRLxXyL0FnXWpUF1xII2mJ86mwYpYsUmMwkmerq7Q==} 1689 | hasBin: true 1690 | peerDependencies: 1691 | typescript: '>=5.0.0' 1692 | 1693 | webidl-conversions@7.0.0: 1694 | resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} 1695 | engines: {node: '>=12'} 1696 | 1697 | whatwg-mimetype@3.0.0: 1698 | resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} 1699 | engines: {node: '>=12'} 1700 | 1701 | which@2.0.2: 1702 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1703 | engines: {node: '>= 8'} 1704 | hasBin: true 1705 | 1706 | why-is-node-running@2.3.0: 1707 | resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} 1708 | engines: {node: '>=8'} 1709 | hasBin: true 1710 | 1711 | word-wrap@1.2.5: 1712 | resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} 1713 | engines: {node: '>=0.10.0'} 1714 | 1715 | wrap-ansi@7.0.0: 1716 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 1717 | engines: {node: '>=10'} 1718 | 1719 | wrap-ansi@8.1.0: 1720 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} 1721 | engines: {node: '>=12'} 1722 | 1723 | yallist@3.1.1: 1724 | resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} 1725 | 1726 | yallist@4.0.0: 1727 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} 1728 | 1729 | yocto-queue@0.1.0: 1730 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 1731 | engines: {node: '>=10'} 1732 | 1733 | snapshots: 1734 | 1735 | '@ampproject/remapping@2.3.0': 1736 | dependencies: 1737 | '@jridgewell/gen-mapping': 0.3.5 1738 | '@jridgewell/trace-mapping': 0.3.25 1739 | 1740 | '@babel/code-frame@7.24.7': 1741 | dependencies: 1742 | '@babel/highlight': 7.24.7 1743 | picocolors: 1.1.0 1744 | 1745 | '@babel/compat-data@7.25.4': {} 1746 | 1747 | '@babel/core@7.25.2': 1748 | dependencies: 1749 | '@ampproject/remapping': 2.3.0 1750 | '@babel/code-frame': 7.24.7 1751 | '@babel/generator': 7.25.6 1752 | '@babel/helper-compilation-targets': 7.25.2 1753 | '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) 1754 | '@babel/helpers': 7.25.6 1755 | '@babel/parser': 7.25.6 1756 | '@babel/template': 7.25.0 1757 | '@babel/traverse': 7.25.6 1758 | '@babel/types': 7.25.6 1759 | convert-source-map: 2.0.0 1760 | debug: 4.3.6 1761 | gensync: 1.0.0-beta.2 1762 | json5: 2.2.3 1763 | semver: 6.3.1 1764 | transitivePeerDependencies: 1765 | - supports-color 1766 | 1767 | '@babel/generator@7.25.6': 1768 | dependencies: 1769 | '@babel/types': 7.25.6 1770 | '@jridgewell/gen-mapping': 0.3.5 1771 | '@jridgewell/trace-mapping': 0.3.25 1772 | jsesc: 2.5.2 1773 | 1774 | '@babel/helper-compilation-targets@7.25.2': 1775 | dependencies: 1776 | '@babel/compat-data': 7.25.4 1777 | '@babel/helper-validator-option': 7.24.8 1778 | browserslist: 4.23.3 1779 | lru-cache: 5.1.1 1780 | semver: 6.3.1 1781 | 1782 | '@babel/helper-module-imports@7.24.7': 1783 | dependencies: 1784 | '@babel/traverse': 7.25.6 1785 | '@babel/types': 7.25.6 1786 | transitivePeerDependencies: 1787 | - supports-color 1788 | 1789 | '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': 1790 | dependencies: 1791 | '@babel/core': 7.25.2 1792 | '@babel/helper-module-imports': 7.24.7 1793 | '@babel/helper-simple-access': 7.24.7 1794 | '@babel/helper-validator-identifier': 7.24.7 1795 | '@babel/traverse': 7.25.6 1796 | transitivePeerDependencies: 1797 | - supports-color 1798 | 1799 | '@babel/helper-plugin-utils@7.24.8': {} 1800 | 1801 | '@babel/helper-simple-access@7.24.7': 1802 | dependencies: 1803 | '@babel/traverse': 7.25.6 1804 | '@babel/types': 7.25.6 1805 | transitivePeerDependencies: 1806 | - supports-color 1807 | 1808 | '@babel/helper-string-parser@7.24.8': {} 1809 | 1810 | '@babel/helper-validator-identifier@7.24.7': {} 1811 | 1812 | '@babel/helper-validator-option@7.24.8': {} 1813 | 1814 | '@babel/helpers@7.25.6': 1815 | dependencies: 1816 | '@babel/template': 7.25.0 1817 | '@babel/types': 7.25.6 1818 | 1819 | '@babel/highlight@7.24.7': 1820 | dependencies: 1821 | '@babel/helper-validator-identifier': 7.24.7 1822 | chalk: 2.4.2 1823 | js-tokens: 4.0.0 1824 | picocolors: 1.1.0 1825 | 1826 | '@babel/parser@7.25.6': 1827 | dependencies: 1828 | '@babel/types': 7.25.6 1829 | 1830 | '@babel/plugin-transform-react-jsx-self@7.24.7(@babel/core@7.25.2)': 1831 | dependencies: 1832 | '@babel/core': 7.25.2 1833 | '@babel/helper-plugin-utils': 7.24.8 1834 | 1835 | '@babel/plugin-transform-react-jsx-source@7.24.7(@babel/core@7.25.2)': 1836 | dependencies: 1837 | '@babel/core': 7.25.2 1838 | '@babel/helper-plugin-utils': 7.24.8 1839 | 1840 | '@babel/runtime@7.25.6': 1841 | dependencies: 1842 | regenerator-runtime: 0.14.1 1843 | 1844 | '@babel/template@7.25.0': 1845 | dependencies: 1846 | '@babel/code-frame': 7.24.7 1847 | '@babel/parser': 7.25.6 1848 | '@babel/types': 7.25.6 1849 | 1850 | '@babel/traverse@7.25.6': 1851 | dependencies: 1852 | '@babel/code-frame': 7.24.7 1853 | '@babel/generator': 7.25.6 1854 | '@babel/parser': 7.25.6 1855 | '@babel/template': 7.25.0 1856 | '@babel/types': 7.25.6 1857 | debug: 4.3.6 1858 | globals: 11.12.0 1859 | transitivePeerDependencies: 1860 | - supports-color 1861 | 1862 | '@babel/types@7.25.6': 1863 | dependencies: 1864 | '@babel/helper-string-parser': 7.24.8 1865 | '@babel/helper-validator-identifier': 7.24.7 1866 | to-fast-properties: 2.0.0 1867 | 1868 | '@bcoe/v8-coverage@0.2.3': {} 1869 | 1870 | '@esbuild/aix-ppc64@0.21.5': 1871 | optional: true 1872 | 1873 | '@esbuild/android-arm64@0.21.5': 1874 | optional: true 1875 | 1876 | '@esbuild/android-arm@0.21.5': 1877 | optional: true 1878 | 1879 | '@esbuild/android-x64@0.21.5': 1880 | optional: true 1881 | 1882 | '@esbuild/darwin-arm64@0.21.5': 1883 | optional: true 1884 | 1885 | '@esbuild/darwin-x64@0.21.5': 1886 | optional: true 1887 | 1888 | '@esbuild/freebsd-arm64@0.21.5': 1889 | optional: true 1890 | 1891 | '@esbuild/freebsd-x64@0.21.5': 1892 | optional: true 1893 | 1894 | '@esbuild/linux-arm64@0.21.5': 1895 | optional: true 1896 | 1897 | '@esbuild/linux-arm@0.21.5': 1898 | optional: true 1899 | 1900 | '@esbuild/linux-ia32@0.21.5': 1901 | optional: true 1902 | 1903 | '@esbuild/linux-loong64@0.21.5': 1904 | optional: true 1905 | 1906 | '@esbuild/linux-mips64el@0.21.5': 1907 | optional: true 1908 | 1909 | '@esbuild/linux-ppc64@0.21.5': 1910 | optional: true 1911 | 1912 | '@esbuild/linux-riscv64@0.21.5': 1913 | optional: true 1914 | 1915 | '@esbuild/linux-s390x@0.21.5': 1916 | optional: true 1917 | 1918 | '@esbuild/linux-x64@0.21.5': 1919 | optional: true 1920 | 1921 | '@esbuild/netbsd-x64@0.21.5': 1922 | optional: true 1923 | 1924 | '@esbuild/openbsd-x64@0.21.5': 1925 | optional: true 1926 | 1927 | '@esbuild/sunos-x64@0.21.5': 1928 | optional: true 1929 | 1930 | '@esbuild/win32-arm64@0.21.5': 1931 | optional: true 1932 | 1933 | '@esbuild/win32-ia32@0.21.5': 1934 | optional: true 1935 | 1936 | '@esbuild/win32-x64@0.21.5': 1937 | optional: true 1938 | 1939 | '@eslint-community/eslint-utils@4.4.0(eslint@9.9.1)': 1940 | dependencies: 1941 | eslint: 9.9.1 1942 | eslint-visitor-keys: 3.4.3 1943 | 1944 | '@eslint-community/regexpp@4.11.0': {} 1945 | 1946 | '@eslint/config-array@0.18.0': 1947 | dependencies: 1948 | '@eslint/object-schema': 2.1.4 1949 | debug: 4.3.6 1950 | minimatch: 3.1.2 1951 | transitivePeerDependencies: 1952 | - supports-color 1953 | 1954 | '@eslint/eslintrc@3.1.0': 1955 | dependencies: 1956 | ajv: 6.12.6 1957 | debug: 4.3.6 1958 | espree: 10.1.0 1959 | globals: 14.0.0 1960 | ignore: 5.3.2 1961 | import-fresh: 3.3.0 1962 | js-yaml: 4.1.0 1963 | minimatch: 3.1.2 1964 | strip-json-comments: 3.1.1 1965 | transitivePeerDependencies: 1966 | - supports-color 1967 | 1968 | '@eslint/js@9.9.1': {} 1969 | 1970 | '@eslint/object-schema@2.1.4': {} 1971 | 1972 | '@humanwhocodes/module-importer@1.0.1': {} 1973 | 1974 | '@humanwhocodes/retry@0.3.0': {} 1975 | 1976 | '@isaacs/cliui@8.0.2': 1977 | dependencies: 1978 | string-width: 5.1.2 1979 | string-width-cjs: string-width@4.2.3 1980 | strip-ansi: 7.1.0 1981 | strip-ansi-cjs: strip-ansi@6.0.1 1982 | wrap-ansi: 8.1.0 1983 | wrap-ansi-cjs: wrap-ansi@7.0.0 1984 | 1985 | '@istanbuljs/schema@0.1.3': {} 1986 | 1987 | '@jridgewell/gen-mapping@0.3.5': 1988 | dependencies: 1989 | '@jridgewell/set-array': 1.2.1 1990 | '@jridgewell/sourcemap-codec': 1.5.0 1991 | '@jridgewell/trace-mapping': 0.3.25 1992 | 1993 | '@jridgewell/resolve-uri@3.1.2': {} 1994 | 1995 | '@jridgewell/set-array@1.2.1': {} 1996 | 1997 | '@jridgewell/sourcemap-codec@1.5.0': {} 1998 | 1999 | '@jridgewell/trace-mapping@0.3.25': 2000 | dependencies: 2001 | '@jridgewell/resolve-uri': 3.1.2 2002 | '@jridgewell/sourcemap-codec': 1.5.0 2003 | 2004 | '@microsoft/api-extractor-model@7.29.4': 2005 | dependencies: 2006 | '@microsoft/tsdoc': 0.15.0 2007 | '@microsoft/tsdoc-config': 0.17.0 2008 | '@rushstack/node-core-library': 5.5.1 2009 | transitivePeerDependencies: 2010 | - '@types/node' 2011 | 2012 | '@microsoft/api-extractor@7.47.4': 2013 | dependencies: 2014 | '@microsoft/api-extractor-model': 7.29.4 2015 | '@microsoft/tsdoc': 0.15.0 2016 | '@microsoft/tsdoc-config': 0.17.0 2017 | '@rushstack/node-core-library': 5.5.1 2018 | '@rushstack/rig-package': 0.5.3 2019 | '@rushstack/terminal': 0.13.3 2020 | '@rushstack/ts-command-line': 4.22.3 2021 | lodash: 4.17.21 2022 | minimatch: 3.0.8 2023 | resolve: 1.22.8 2024 | semver: 7.5.4 2025 | source-map: 0.6.1 2026 | typescript: 5.4.2 2027 | transitivePeerDependencies: 2028 | - '@types/node' 2029 | 2030 | '@microsoft/tsdoc-config@0.17.0': 2031 | dependencies: 2032 | '@microsoft/tsdoc': 0.15.0 2033 | ajv: 8.12.0 2034 | jju: 1.4.0 2035 | resolve: 1.22.8 2036 | 2037 | '@microsoft/tsdoc@0.15.0': {} 2038 | 2039 | '@nodelib/fs.scandir@2.1.5': 2040 | dependencies: 2041 | '@nodelib/fs.stat': 2.0.5 2042 | run-parallel: 1.2.0 2043 | 2044 | '@nodelib/fs.stat@2.0.5': {} 2045 | 2046 | '@nodelib/fs.walk@1.2.8': 2047 | dependencies: 2048 | '@nodelib/fs.scandir': 2.1.5 2049 | fastq: 1.17.1 2050 | 2051 | '@pkgjs/parseargs@0.11.0': 2052 | optional: true 2053 | 2054 | '@pkgr/core@0.1.1': {} 2055 | 2056 | '@rollup/pluginutils@5.1.0(rollup@4.21.2)': 2057 | dependencies: 2058 | '@types/estree': 1.0.5 2059 | estree-walker: 2.0.2 2060 | picomatch: 2.3.1 2061 | optionalDependencies: 2062 | rollup: 4.21.2 2063 | 2064 | '@rollup/rollup-android-arm-eabi@4.21.2': 2065 | optional: true 2066 | 2067 | '@rollup/rollup-android-arm64@4.21.2': 2068 | optional: true 2069 | 2070 | '@rollup/rollup-darwin-arm64@4.21.2': 2071 | optional: true 2072 | 2073 | '@rollup/rollup-darwin-x64@4.21.2': 2074 | optional: true 2075 | 2076 | '@rollup/rollup-linux-arm-gnueabihf@4.21.2': 2077 | optional: true 2078 | 2079 | '@rollup/rollup-linux-arm-musleabihf@4.21.2': 2080 | optional: true 2081 | 2082 | '@rollup/rollup-linux-arm64-gnu@4.21.2': 2083 | optional: true 2084 | 2085 | '@rollup/rollup-linux-arm64-musl@4.21.2': 2086 | optional: true 2087 | 2088 | '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': 2089 | optional: true 2090 | 2091 | '@rollup/rollup-linux-riscv64-gnu@4.21.2': 2092 | optional: true 2093 | 2094 | '@rollup/rollup-linux-s390x-gnu@4.21.2': 2095 | optional: true 2096 | 2097 | '@rollup/rollup-linux-x64-gnu@4.21.2': 2098 | optional: true 2099 | 2100 | '@rollup/rollup-linux-x64-musl@4.21.2': 2101 | optional: true 2102 | 2103 | '@rollup/rollup-win32-arm64-msvc@4.21.2': 2104 | optional: true 2105 | 2106 | '@rollup/rollup-win32-ia32-msvc@4.21.2': 2107 | optional: true 2108 | 2109 | '@rollup/rollup-win32-x64-msvc@4.21.2': 2110 | optional: true 2111 | 2112 | '@rushstack/node-core-library@5.5.1': 2113 | dependencies: 2114 | ajv: 8.13.0 2115 | ajv-draft-04: 1.0.0(ajv@8.13.0) 2116 | ajv-formats: 3.0.1(ajv@8.13.0) 2117 | fs-extra: 7.0.1 2118 | import-lazy: 4.0.0 2119 | jju: 1.4.0 2120 | resolve: 1.22.8 2121 | semver: 7.5.4 2122 | 2123 | '@rushstack/rig-package@0.5.3': 2124 | dependencies: 2125 | resolve: 1.22.8 2126 | strip-json-comments: 3.1.1 2127 | 2128 | '@rushstack/terminal@0.13.3': 2129 | dependencies: 2130 | '@rushstack/node-core-library': 5.5.1 2131 | supports-color: 8.1.1 2132 | 2133 | '@rushstack/ts-command-line@4.22.3': 2134 | dependencies: 2135 | '@rushstack/terminal': 0.13.3 2136 | '@types/argparse': 1.0.38 2137 | argparse: 1.0.10 2138 | string-argv: 0.3.2 2139 | transitivePeerDependencies: 2140 | - '@types/node' 2141 | 2142 | '@testing-library/dom@10.4.0': 2143 | dependencies: 2144 | '@babel/code-frame': 7.24.7 2145 | '@babel/runtime': 7.25.6 2146 | '@types/aria-query': 5.0.4 2147 | aria-query: 5.3.0 2148 | chalk: 4.1.2 2149 | dom-accessibility-api: 0.5.16 2150 | lz-string: 1.5.0 2151 | pretty-format: 27.5.1 2152 | 2153 | '@testing-library/react@16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': 2154 | dependencies: 2155 | '@babel/runtime': 7.25.6 2156 | '@testing-library/dom': 10.4.0 2157 | react: 18.3.1 2158 | react-dom: 18.3.1(react@18.3.1) 2159 | optionalDependencies: 2160 | '@types/react': 18.3.5 2161 | '@types/react-dom': 18.3.0 2162 | 2163 | '@types/argparse@1.0.38': {} 2164 | 2165 | '@types/aria-query@5.0.4': {} 2166 | 2167 | '@types/babel__core@7.20.5': 2168 | dependencies: 2169 | '@babel/parser': 7.25.6 2170 | '@babel/types': 7.25.6 2171 | '@types/babel__generator': 7.6.8 2172 | '@types/babel__template': 7.4.4 2173 | '@types/babel__traverse': 7.20.6 2174 | 2175 | '@types/babel__generator@7.6.8': 2176 | dependencies: 2177 | '@babel/types': 7.25.6 2178 | 2179 | '@types/babel__template@7.4.4': 2180 | dependencies: 2181 | '@babel/parser': 7.25.6 2182 | '@babel/types': 7.25.6 2183 | 2184 | '@types/babel__traverse@7.20.6': 2185 | dependencies: 2186 | '@babel/types': 7.25.6 2187 | 2188 | '@types/eslint@9.6.1': 2189 | dependencies: 2190 | '@types/estree': 1.0.5 2191 | '@types/json-schema': 7.0.15 2192 | 2193 | '@types/estree@1.0.5': {} 2194 | 2195 | '@types/json-schema@7.0.15': {} 2196 | 2197 | '@types/prop-types@15.7.12': {} 2198 | 2199 | '@types/react-dom@18.3.0': 2200 | dependencies: 2201 | '@types/react': 18.3.5 2202 | 2203 | '@types/react@18.3.5': 2204 | dependencies: 2205 | '@types/prop-types': 15.7.12 2206 | csstype: 3.1.3 2207 | 2208 | '@typescript-eslint/eslint-plugin@8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1)(typescript@5.5.4))(eslint@9.9.1)(typescript@5.5.4)': 2209 | dependencies: 2210 | '@eslint-community/regexpp': 4.11.0 2211 | '@typescript-eslint/parser': 8.4.0(eslint@9.9.1)(typescript@5.5.4) 2212 | '@typescript-eslint/scope-manager': 8.4.0 2213 | '@typescript-eslint/type-utils': 8.4.0(eslint@9.9.1)(typescript@5.5.4) 2214 | '@typescript-eslint/utils': 8.4.0(eslint@9.9.1)(typescript@5.5.4) 2215 | '@typescript-eslint/visitor-keys': 8.4.0 2216 | eslint: 9.9.1 2217 | graphemer: 1.4.0 2218 | ignore: 5.3.2 2219 | natural-compare: 1.4.0 2220 | ts-api-utils: 1.3.0(typescript@5.5.4) 2221 | optionalDependencies: 2222 | typescript: 5.5.4 2223 | transitivePeerDependencies: 2224 | - supports-color 2225 | 2226 | '@typescript-eslint/parser@8.4.0(eslint@9.9.1)(typescript@5.5.4)': 2227 | dependencies: 2228 | '@typescript-eslint/scope-manager': 8.4.0 2229 | '@typescript-eslint/types': 8.4.0 2230 | '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.5.4) 2231 | '@typescript-eslint/visitor-keys': 8.4.0 2232 | debug: 4.3.6 2233 | eslint: 9.9.1 2234 | optionalDependencies: 2235 | typescript: 5.5.4 2236 | transitivePeerDependencies: 2237 | - supports-color 2238 | 2239 | '@typescript-eslint/scope-manager@8.4.0': 2240 | dependencies: 2241 | '@typescript-eslint/types': 8.4.0 2242 | '@typescript-eslint/visitor-keys': 8.4.0 2243 | 2244 | '@typescript-eslint/type-utils@8.4.0(eslint@9.9.1)(typescript@5.5.4)': 2245 | dependencies: 2246 | '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.5.4) 2247 | '@typescript-eslint/utils': 8.4.0(eslint@9.9.1)(typescript@5.5.4) 2248 | debug: 4.3.6 2249 | ts-api-utils: 1.3.0(typescript@5.5.4) 2250 | optionalDependencies: 2251 | typescript: 5.5.4 2252 | transitivePeerDependencies: 2253 | - eslint 2254 | - supports-color 2255 | 2256 | '@typescript-eslint/types@8.4.0': {} 2257 | 2258 | '@typescript-eslint/typescript-estree@8.4.0(typescript@5.5.4)': 2259 | dependencies: 2260 | '@typescript-eslint/types': 8.4.0 2261 | '@typescript-eslint/visitor-keys': 8.4.0 2262 | debug: 4.3.6 2263 | fast-glob: 3.3.2 2264 | is-glob: 4.0.3 2265 | minimatch: 9.0.5 2266 | semver: 7.6.3 2267 | ts-api-utils: 1.3.0(typescript@5.5.4) 2268 | optionalDependencies: 2269 | typescript: 5.5.4 2270 | transitivePeerDependencies: 2271 | - supports-color 2272 | 2273 | '@typescript-eslint/utils@8.4.0(eslint@9.9.1)(typescript@5.5.4)': 2274 | dependencies: 2275 | '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1) 2276 | '@typescript-eslint/scope-manager': 8.4.0 2277 | '@typescript-eslint/types': 8.4.0 2278 | '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.5.4) 2279 | eslint: 9.9.1 2280 | transitivePeerDependencies: 2281 | - supports-color 2282 | - typescript 2283 | 2284 | '@typescript-eslint/visitor-keys@8.4.0': 2285 | dependencies: 2286 | '@typescript-eslint/types': 8.4.0 2287 | eslint-visitor-keys: 3.4.3 2288 | 2289 | '@vitejs/plugin-react@4.3.1(vite@5.4.3)': 2290 | dependencies: 2291 | '@babel/core': 7.25.2 2292 | '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2) 2293 | '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.2) 2294 | '@types/babel__core': 7.20.5 2295 | react-refresh: 0.14.2 2296 | vite: 5.4.3 2297 | transitivePeerDependencies: 2298 | - supports-color 2299 | 2300 | '@vitest/coverage-v8@2.0.5(vitest@2.0.5(happy-dom@15.7.3))': 2301 | dependencies: 2302 | '@ampproject/remapping': 2.3.0 2303 | '@bcoe/v8-coverage': 0.2.3 2304 | debug: 4.3.6 2305 | istanbul-lib-coverage: 3.2.2 2306 | istanbul-lib-report: 3.0.1 2307 | istanbul-lib-source-maps: 5.0.6 2308 | istanbul-reports: 3.1.7 2309 | magic-string: 0.30.11 2310 | magicast: 0.3.5 2311 | std-env: 3.7.0 2312 | test-exclude: 7.0.1 2313 | tinyrainbow: 1.2.0 2314 | vitest: 2.0.5(happy-dom@15.7.3) 2315 | transitivePeerDependencies: 2316 | - supports-color 2317 | 2318 | '@vitest/expect@2.0.5': 2319 | dependencies: 2320 | '@vitest/spy': 2.0.5 2321 | '@vitest/utils': 2.0.5 2322 | chai: 5.1.1 2323 | tinyrainbow: 1.2.0 2324 | 2325 | '@vitest/pretty-format@2.0.5': 2326 | dependencies: 2327 | tinyrainbow: 1.2.0 2328 | 2329 | '@vitest/runner@2.0.5': 2330 | dependencies: 2331 | '@vitest/utils': 2.0.5 2332 | pathe: 1.1.2 2333 | 2334 | '@vitest/snapshot@2.0.5': 2335 | dependencies: 2336 | '@vitest/pretty-format': 2.0.5 2337 | magic-string: 0.30.11 2338 | pathe: 1.1.2 2339 | 2340 | '@vitest/spy@2.0.5': 2341 | dependencies: 2342 | tinyspy: 3.0.0 2343 | 2344 | '@vitest/utils@2.0.5': 2345 | dependencies: 2346 | '@vitest/pretty-format': 2.0.5 2347 | estree-walker: 3.0.3 2348 | loupe: 3.1.1 2349 | tinyrainbow: 1.2.0 2350 | 2351 | '@volar/language-core@2.4.2': 2352 | dependencies: 2353 | '@volar/source-map': 2.4.2 2354 | 2355 | '@volar/source-map@2.4.2': {} 2356 | 2357 | '@volar/typescript@2.4.2': 2358 | dependencies: 2359 | '@volar/language-core': 2.4.2 2360 | path-browserify: 1.0.1 2361 | vscode-uri: 3.0.8 2362 | 2363 | '@vue/compiler-core@3.5.2': 2364 | dependencies: 2365 | '@babel/parser': 7.25.6 2366 | '@vue/shared': 3.5.2 2367 | entities: 4.5.0 2368 | estree-walker: 2.0.2 2369 | source-map-js: 1.2.0 2370 | 2371 | '@vue/compiler-dom@3.5.2': 2372 | dependencies: 2373 | '@vue/compiler-core': 3.5.2 2374 | '@vue/shared': 3.5.2 2375 | 2376 | '@vue/compiler-vue2@2.7.16': 2377 | dependencies: 2378 | de-indent: 1.0.2 2379 | he: 1.2.0 2380 | 2381 | '@vue/language-core@2.0.29(typescript@5.5.4)': 2382 | dependencies: 2383 | '@volar/language-core': 2.4.2 2384 | '@vue/compiler-dom': 3.5.2 2385 | '@vue/compiler-vue2': 2.7.16 2386 | '@vue/shared': 3.5.2 2387 | computeds: 0.0.1 2388 | minimatch: 9.0.5 2389 | muggle-string: 0.4.1 2390 | path-browserify: 1.0.1 2391 | optionalDependencies: 2392 | typescript: 5.5.4 2393 | 2394 | '@vue/reactivity@3.5.2': 2395 | dependencies: 2396 | '@vue/shared': 3.5.2 2397 | 2398 | '@vue/shared@3.5.2': {} 2399 | 2400 | acorn-jsx@5.3.2(acorn@8.12.1): 2401 | dependencies: 2402 | acorn: 8.12.1 2403 | 2404 | acorn@8.12.1: {} 2405 | 2406 | ajv-draft-04@1.0.0(ajv@8.13.0): 2407 | optionalDependencies: 2408 | ajv: 8.13.0 2409 | 2410 | ajv-formats@3.0.1(ajv@8.13.0): 2411 | optionalDependencies: 2412 | ajv: 8.13.0 2413 | 2414 | ajv@6.12.6: 2415 | dependencies: 2416 | fast-deep-equal: 3.1.3 2417 | fast-json-stable-stringify: 2.1.0 2418 | json-schema-traverse: 0.4.1 2419 | uri-js: 4.4.1 2420 | 2421 | ajv@8.12.0: 2422 | dependencies: 2423 | fast-deep-equal: 3.1.3 2424 | json-schema-traverse: 1.0.0 2425 | require-from-string: 2.0.2 2426 | uri-js: 4.4.1 2427 | 2428 | ajv@8.13.0: 2429 | dependencies: 2430 | fast-deep-equal: 3.1.3 2431 | json-schema-traverse: 1.0.0 2432 | require-from-string: 2.0.2 2433 | uri-js: 4.4.1 2434 | 2435 | ansi-regex@5.0.1: {} 2436 | 2437 | ansi-regex@6.0.1: {} 2438 | 2439 | ansi-styles@3.2.1: 2440 | dependencies: 2441 | color-convert: 1.9.3 2442 | 2443 | ansi-styles@4.3.0: 2444 | dependencies: 2445 | color-convert: 2.0.1 2446 | 2447 | ansi-styles@5.2.0: {} 2448 | 2449 | ansi-styles@6.2.1: {} 2450 | 2451 | argparse@1.0.10: 2452 | dependencies: 2453 | sprintf-js: 1.0.3 2454 | 2455 | argparse@2.0.1: {} 2456 | 2457 | aria-query@5.3.0: 2458 | dependencies: 2459 | dequal: 2.0.3 2460 | 2461 | assertion-error@2.0.1: {} 2462 | 2463 | balanced-match@1.0.2: {} 2464 | 2465 | brace-expansion@1.1.11: 2466 | dependencies: 2467 | balanced-match: 1.0.2 2468 | concat-map: 0.0.1 2469 | 2470 | brace-expansion@2.0.1: 2471 | dependencies: 2472 | balanced-match: 1.0.2 2473 | 2474 | braces@3.0.3: 2475 | dependencies: 2476 | fill-range: 7.1.1 2477 | 2478 | browserslist@4.23.3: 2479 | dependencies: 2480 | caniuse-lite: 1.0.30001657 2481 | electron-to-chromium: 1.5.14 2482 | node-releases: 2.0.18 2483 | update-browserslist-db: 1.1.0(browserslist@4.23.3) 2484 | 2485 | cac@6.7.14: {} 2486 | 2487 | callsites@3.1.0: {} 2488 | 2489 | caniuse-lite@1.0.30001657: {} 2490 | 2491 | chai@5.1.1: 2492 | dependencies: 2493 | assertion-error: 2.0.1 2494 | check-error: 2.1.1 2495 | deep-eql: 5.0.2 2496 | loupe: 3.1.1 2497 | pathval: 2.0.0 2498 | 2499 | chalk@2.4.2: 2500 | dependencies: 2501 | ansi-styles: 3.2.1 2502 | escape-string-regexp: 1.0.5 2503 | supports-color: 5.5.0 2504 | 2505 | chalk@4.1.2: 2506 | dependencies: 2507 | ansi-styles: 4.3.0 2508 | supports-color: 7.2.0 2509 | 2510 | check-error@2.1.1: {} 2511 | 2512 | color-convert@1.9.3: 2513 | dependencies: 2514 | color-name: 1.1.3 2515 | 2516 | color-convert@2.0.1: 2517 | dependencies: 2518 | color-name: 1.1.4 2519 | 2520 | color-name@1.1.3: {} 2521 | 2522 | color-name@1.1.4: {} 2523 | 2524 | compare-versions@6.1.1: {} 2525 | 2526 | computeds@0.0.1: {} 2527 | 2528 | concat-map@0.0.1: {} 2529 | 2530 | confbox@0.1.7: {} 2531 | 2532 | convert-source-map@2.0.0: {} 2533 | 2534 | cross-spawn@7.0.3: 2535 | dependencies: 2536 | path-key: 3.1.1 2537 | shebang-command: 2.0.0 2538 | which: 2.0.2 2539 | 2540 | csstype@3.1.3: {} 2541 | 2542 | de-indent@1.0.2: {} 2543 | 2544 | debug@4.3.6: 2545 | dependencies: 2546 | ms: 2.1.2 2547 | 2548 | deep-eql@5.0.2: {} 2549 | 2550 | deep-is@0.1.4: {} 2551 | 2552 | dequal@2.0.3: {} 2553 | 2554 | dom-accessibility-api@0.5.16: {} 2555 | 2556 | eastasianwidth@0.2.0: {} 2557 | 2558 | electron-to-chromium@1.5.14: {} 2559 | 2560 | emoji-regex@8.0.0: {} 2561 | 2562 | emoji-regex@9.2.2: {} 2563 | 2564 | entities@4.5.0: {} 2565 | 2566 | esbuild@0.21.5: 2567 | optionalDependencies: 2568 | '@esbuild/aix-ppc64': 0.21.5 2569 | '@esbuild/android-arm': 0.21.5 2570 | '@esbuild/android-arm64': 0.21.5 2571 | '@esbuild/android-x64': 0.21.5 2572 | '@esbuild/darwin-arm64': 0.21.5 2573 | '@esbuild/darwin-x64': 0.21.5 2574 | '@esbuild/freebsd-arm64': 0.21.5 2575 | '@esbuild/freebsd-x64': 0.21.5 2576 | '@esbuild/linux-arm': 0.21.5 2577 | '@esbuild/linux-arm64': 0.21.5 2578 | '@esbuild/linux-ia32': 0.21.5 2579 | '@esbuild/linux-loong64': 0.21.5 2580 | '@esbuild/linux-mips64el': 0.21.5 2581 | '@esbuild/linux-ppc64': 0.21.5 2582 | '@esbuild/linux-riscv64': 0.21.5 2583 | '@esbuild/linux-s390x': 0.21.5 2584 | '@esbuild/linux-x64': 0.21.5 2585 | '@esbuild/netbsd-x64': 0.21.5 2586 | '@esbuild/openbsd-x64': 0.21.5 2587 | '@esbuild/sunos-x64': 0.21.5 2588 | '@esbuild/win32-arm64': 0.21.5 2589 | '@esbuild/win32-ia32': 0.21.5 2590 | '@esbuild/win32-x64': 0.21.5 2591 | 2592 | escalade@3.2.0: {} 2593 | 2594 | escape-string-regexp@1.0.5: {} 2595 | 2596 | escape-string-regexp@4.0.0: {} 2597 | 2598 | eslint-config-prettier@9.1.0(eslint@9.9.1): 2599 | dependencies: 2600 | eslint: 9.9.1 2601 | 2602 | eslint-plugin-prettier@5.2.1(@types/eslint@9.6.1)(eslint-config-prettier@9.1.0(eslint@9.9.1))(eslint@9.9.1)(prettier@3.3.3): 2603 | dependencies: 2604 | eslint: 9.9.1 2605 | prettier: 3.3.3 2606 | prettier-linter-helpers: 1.0.0 2607 | synckit: 0.9.1 2608 | optionalDependencies: 2609 | '@types/eslint': 9.6.1 2610 | eslint-config-prettier: 9.1.0(eslint@9.9.1) 2611 | 2612 | eslint-scope@8.0.2: 2613 | dependencies: 2614 | esrecurse: 4.3.0 2615 | estraverse: 5.3.0 2616 | 2617 | eslint-visitor-keys@3.4.3: {} 2618 | 2619 | eslint-visitor-keys@4.0.0: {} 2620 | 2621 | eslint@9.9.1: 2622 | dependencies: 2623 | '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1) 2624 | '@eslint-community/regexpp': 4.11.0 2625 | '@eslint/config-array': 0.18.0 2626 | '@eslint/eslintrc': 3.1.0 2627 | '@eslint/js': 9.9.1 2628 | '@humanwhocodes/module-importer': 1.0.1 2629 | '@humanwhocodes/retry': 0.3.0 2630 | '@nodelib/fs.walk': 1.2.8 2631 | ajv: 6.12.6 2632 | chalk: 4.1.2 2633 | cross-spawn: 7.0.3 2634 | debug: 4.3.6 2635 | escape-string-regexp: 4.0.0 2636 | eslint-scope: 8.0.2 2637 | eslint-visitor-keys: 4.0.0 2638 | espree: 10.1.0 2639 | esquery: 1.6.0 2640 | esutils: 2.0.3 2641 | fast-deep-equal: 3.1.3 2642 | file-entry-cache: 8.0.0 2643 | find-up: 5.0.0 2644 | glob-parent: 6.0.2 2645 | ignore: 5.3.2 2646 | imurmurhash: 0.1.4 2647 | is-glob: 4.0.3 2648 | is-path-inside: 3.0.3 2649 | json-stable-stringify-without-jsonify: 1.0.1 2650 | levn: 0.4.1 2651 | lodash.merge: 4.6.2 2652 | minimatch: 3.1.2 2653 | natural-compare: 1.4.0 2654 | optionator: 0.9.4 2655 | strip-ansi: 6.0.1 2656 | text-table: 0.2.0 2657 | transitivePeerDependencies: 2658 | - supports-color 2659 | 2660 | espree@10.1.0: 2661 | dependencies: 2662 | acorn: 8.12.1 2663 | acorn-jsx: 5.3.2(acorn@8.12.1) 2664 | eslint-visitor-keys: 4.0.0 2665 | 2666 | esquery@1.6.0: 2667 | dependencies: 2668 | estraverse: 5.3.0 2669 | 2670 | esrecurse@4.3.0: 2671 | dependencies: 2672 | estraverse: 5.3.0 2673 | 2674 | estraverse@5.3.0: {} 2675 | 2676 | estree-walker@2.0.2: {} 2677 | 2678 | estree-walker@3.0.3: 2679 | dependencies: 2680 | '@types/estree': 1.0.5 2681 | 2682 | esutils@2.0.3: {} 2683 | 2684 | execa@8.0.1: 2685 | dependencies: 2686 | cross-spawn: 7.0.3 2687 | get-stream: 8.0.1 2688 | human-signals: 5.0.0 2689 | is-stream: 3.0.0 2690 | merge-stream: 2.0.0 2691 | npm-run-path: 5.3.0 2692 | onetime: 6.0.0 2693 | signal-exit: 4.1.0 2694 | strip-final-newline: 3.0.0 2695 | 2696 | fast-deep-equal@3.1.3: {} 2697 | 2698 | fast-diff@1.3.0: {} 2699 | 2700 | fast-glob@3.3.2: 2701 | dependencies: 2702 | '@nodelib/fs.stat': 2.0.5 2703 | '@nodelib/fs.walk': 1.2.8 2704 | glob-parent: 5.1.2 2705 | merge2: 1.4.1 2706 | micromatch: 4.0.8 2707 | 2708 | fast-json-stable-stringify@2.1.0: {} 2709 | 2710 | fast-levenshtein@2.0.6: {} 2711 | 2712 | fastq@1.17.1: 2713 | dependencies: 2714 | reusify: 1.0.4 2715 | 2716 | file-entry-cache@8.0.0: 2717 | dependencies: 2718 | flat-cache: 4.0.1 2719 | 2720 | fill-range@7.1.1: 2721 | dependencies: 2722 | to-regex-range: 5.0.1 2723 | 2724 | find-up@5.0.0: 2725 | dependencies: 2726 | locate-path: 6.0.0 2727 | path-exists: 4.0.0 2728 | 2729 | flat-cache@4.0.1: 2730 | dependencies: 2731 | flatted: 3.3.1 2732 | keyv: 4.5.4 2733 | 2734 | flatted@3.3.1: {} 2735 | 2736 | foreground-child@3.3.0: 2737 | dependencies: 2738 | cross-spawn: 7.0.3 2739 | signal-exit: 4.1.0 2740 | 2741 | fs-extra@7.0.1: 2742 | dependencies: 2743 | graceful-fs: 4.2.11 2744 | jsonfile: 4.0.0 2745 | universalify: 0.1.2 2746 | 2747 | fsevents@2.3.3: 2748 | optional: true 2749 | 2750 | function-bind@1.1.2: {} 2751 | 2752 | gensync@1.0.0-beta.2: {} 2753 | 2754 | get-func-name@2.0.2: {} 2755 | 2756 | get-stream@8.0.1: {} 2757 | 2758 | glob-parent@5.1.2: 2759 | dependencies: 2760 | is-glob: 4.0.3 2761 | 2762 | glob-parent@6.0.2: 2763 | dependencies: 2764 | is-glob: 4.0.3 2765 | 2766 | glob@10.4.5: 2767 | dependencies: 2768 | foreground-child: 3.3.0 2769 | jackspeak: 3.4.3 2770 | minimatch: 9.0.5 2771 | minipass: 7.1.2 2772 | package-json-from-dist: 1.0.0 2773 | path-scurry: 1.11.1 2774 | 2775 | globals@11.12.0: {} 2776 | 2777 | globals@14.0.0: {} 2778 | 2779 | globals@15.9.0: {} 2780 | 2781 | graceful-fs@4.2.11: {} 2782 | 2783 | graphemer@1.4.0: {} 2784 | 2785 | happy-dom@15.7.3: 2786 | dependencies: 2787 | entities: 4.5.0 2788 | webidl-conversions: 7.0.0 2789 | whatwg-mimetype: 3.0.0 2790 | 2791 | has-flag@3.0.0: {} 2792 | 2793 | has-flag@4.0.0: {} 2794 | 2795 | hasown@2.0.2: 2796 | dependencies: 2797 | function-bind: 1.1.2 2798 | 2799 | he@1.2.0: {} 2800 | 2801 | html-escaper@2.0.2: {} 2802 | 2803 | human-signals@5.0.0: {} 2804 | 2805 | ignore@5.3.2: {} 2806 | 2807 | import-fresh@3.3.0: 2808 | dependencies: 2809 | parent-module: 1.0.1 2810 | resolve-from: 4.0.0 2811 | 2812 | import-lazy@4.0.0: {} 2813 | 2814 | imurmurhash@0.1.4: {} 2815 | 2816 | is-core-module@2.15.1: 2817 | dependencies: 2818 | hasown: 2.0.2 2819 | 2820 | is-extglob@2.1.1: {} 2821 | 2822 | is-fullwidth-code-point@3.0.0: {} 2823 | 2824 | is-glob@4.0.3: 2825 | dependencies: 2826 | is-extglob: 2.1.1 2827 | 2828 | is-number@7.0.0: {} 2829 | 2830 | is-path-inside@3.0.3: {} 2831 | 2832 | is-stream@3.0.0: {} 2833 | 2834 | isexe@2.0.0: {} 2835 | 2836 | istanbul-lib-coverage@3.2.2: {} 2837 | 2838 | istanbul-lib-report@3.0.1: 2839 | dependencies: 2840 | istanbul-lib-coverage: 3.2.2 2841 | make-dir: 4.0.0 2842 | supports-color: 7.2.0 2843 | 2844 | istanbul-lib-source-maps@5.0.6: 2845 | dependencies: 2846 | '@jridgewell/trace-mapping': 0.3.25 2847 | debug: 4.3.6 2848 | istanbul-lib-coverage: 3.2.2 2849 | transitivePeerDependencies: 2850 | - supports-color 2851 | 2852 | istanbul-reports@3.1.7: 2853 | dependencies: 2854 | html-escaper: 2.0.2 2855 | istanbul-lib-report: 3.0.1 2856 | 2857 | jackspeak@3.4.3: 2858 | dependencies: 2859 | '@isaacs/cliui': 8.0.2 2860 | optionalDependencies: 2861 | '@pkgjs/parseargs': 0.11.0 2862 | 2863 | jju@1.4.0: {} 2864 | 2865 | js-tokens@4.0.0: {} 2866 | 2867 | js-yaml@4.1.0: 2868 | dependencies: 2869 | argparse: 2.0.1 2870 | 2871 | jsesc@2.5.2: {} 2872 | 2873 | json-buffer@3.0.1: {} 2874 | 2875 | json-schema-traverse@0.4.1: {} 2876 | 2877 | json-schema-traverse@1.0.0: {} 2878 | 2879 | json-stable-stringify-without-jsonify@1.0.1: {} 2880 | 2881 | json5@2.2.3: {} 2882 | 2883 | jsonfile@4.0.0: 2884 | optionalDependencies: 2885 | graceful-fs: 4.2.11 2886 | 2887 | keyv@4.5.4: 2888 | dependencies: 2889 | json-buffer: 3.0.1 2890 | 2891 | kolorist@1.8.0: {} 2892 | 2893 | levn@0.4.1: 2894 | dependencies: 2895 | prelude-ls: 1.2.1 2896 | type-check: 0.4.0 2897 | 2898 | local-pkg@0.5.0: 2899 | dependencies: 2900 | mlly: 1.7.1 2901 | pkg-types: 1.2.0 2902 | 2903 | locate-path@6.0.0: 2904 | dependencies: 2905 | p-locate: 5.0.0 2906 | 2907 | lodash.merge@4.6.2: {} 2908 | 2909 | lodash@4.17.21: {} 2910 | 2911 | loose-envify@1.4.0: 2912 | dependencies: 2913 | js-tokens: 4.0.0 2914 | 2915 | loupe@3.1.1: 2916 | dependencies: 2917 | get-func-name: 2.0.2 2918 | 2919 | lru-cache@10.4.3: {} 2920 | 2921 | lru-cache@5.1.1: 2922 | dependencies: 2923 | yallist: 3.1.1 2924 | 2925 | lru-cache@6.0.0: 2926 | dependencies: 2927 | yallist: 4.0.0 2928 | 2929 | lz-string@1.5.0: {} 2930 | 2931 | magic-string@0.30.11: 2932 | dependencies: 2933 | '@jridgewell/sourcemap-codec': 1.5.0 2934 | 2935 | magicast@0.3.5: 2936 | dependencies: 2937 | '@babel/parser': 7.25.6 2938 | '@babel/types': 7.25.6 2939 | source-map-js: 1.2.0 2940 | 2941 | make-dir@4.0.0: 2942 | dependencies: 2943 | semver: 7.6.3 2944 | 2945 | merge-stream@2.0.0: {} 2946 | 2947 | merge2@1.4.1: {} 2948 | 2949 | micromatch@4.0.8: 2950 | dependencies: 2951 | braces: 3.0.3 2952 | picomatch: 2.3.1 2953 | 2954 | mimic-fn@4.0.0: {} 2955 | 2956 | minimatch@3.0.8: 2957 | dependencies: 2958 | brace-expansion: 1.1.11 2959 | 2960 | minimatch@3.1.2: 2961 | dependencies: 2962 | brace-expansion: 1.1.11 2963 | 2964 | minimatch@9.0.5: 2965 | dependencies: 2966 | brace-expansion: 2.0.1 2967 | 2968 | minipass@7.1.2: {} 2969 | 2970 | mlly@1.7.1: 2971 | dependencies: 2972 | acorn: 8.12.1 2973 | pathe: 1.1.2 2974 | pkg-types: 1.2.0 2975 | ufo: 1.5.4 2976 | 2977 | ms@2.1.2: {} 2978 | 2979 | muggle-string@0.4.1: {} 2980 | 2981 | nanoid@3.3.7: {} 2982 | 2983 | natural-compare@1.4.0: {} 2984 | 2985 | node-releases@2.0.18: {} 2986 | 2987 | npm-run-path@5.3.0: 2988 | dependencies: 2989 | path-key: 4.0.0 2990 | 2991 | onetime@6.0.0: 2992 | dependencies: 2993 | mimic-fn: 4.0.0 2994 | 2995 | optionator@0.9.4: 2996 | dependencies: 2997 | deep-is: 0.1.4 2998 | fast-levenshtein: 2.0.6 2999 | levn: 0.4.1 3000 | prelude-ls: 1.2.1 3001 | type-check: 0.4.0 3002 | word-wrap: 1.2.5 3003 | 3004 | p-limit@3.1.0: 3005 | dependencies: 3006 | yocto-queue: 0.1.0 3007 | 3008 | p-locate@5.0.0: 3009 | dependencies: 3010 | p-limit: 3.1.0 3011 | 3012 | package-json-from-dist@1.0.0: {} 3013 | 3014 | parent-module@1.0.1: 3015 | dependencies: 3016 | callsites: 3.1.0 3017 | 3018 | path-browserify@1.0.1: {} 3019 | 3020 | path-exists@4.0.0: {} 3021 | 3022 | path-key@3.1.1: {} 3023 | 3024 | path-key@4.0.0: {} 3025 | 3026 | path-parse@1.0.7: {} 3027 | 3028 | path-scurry@1.11.1: 3029 | dependencies: 3030 | lru-cache: 10.4.3 3031 | minipass: 7.1.2 3032 | 3033 | pathe@1.1.2: {} 3034 | 3035 | pathval@2.0.0: {} 3036 | 3037 | picocolors@1.1.0: {} 3038 | 3039 | picomatch@2.3.1: {} 3040 | 3041 | pkg-types@1.2.0: 3042 | dependencies: 3043 | confbox: 0.1.7 3044 | mlly: 1.7.1 3045 | pathe: 1.1.2 3046 | 3047 | postcss@8.4.45: 3048 | dependencies: 3049 | nanoid: 3.3.7 3050 | picocolors: 1.1.0 3051 | source-map-js: 1.2.0 3052 | 3053 | prelude-ls@1.2.1: {} 3054 | 3055 | prettier-linter-helpers@1.0.0: 3056 | dependencies: 3057 | fast-diff: 1.3.0 3058 | 3059 | prettier@3.3.3: {} 3060 | 3061 | pretty-format@27.5.1: 3062 | dependencies: 3063 | ansi-regex: 5.0.1 3064 | ansi-styles: 5.2.0 3065 | react-is: 17.0.2 3066 | 3067 | punycode@2.3.1: {} 3068 | 3069 | queue-microtask@1.2.3: {} 3070 | 3071 | react-dom@18.3.1(react@18.3.1): 3072 | dependencies: 3073 | loose-envify: 1.4.0 3074 | react: 18.3.1 3075 | scheduler: 0.23.2 3076 | 3077 | react-is@17.0.2: {} 3078 | 3079 | react-refresh@0.14.2: {} 3080 | 3081 | react@18.3.1: 3082 | dependencies: 3083 | loose-envify: 1.4.0 3084 | 3085 | regenerator-runtime@0.14.1: {} 3086 | 3087 | require-from-string@2.0.2: {} 3088 | 3089 | resolve-from@4.0.0: {} 3090 | 3091 | resolve@1.22.8: 3092 | dependencies: 3093 | is-core-module: 2.15.1 3094 | path-parse: 1.0.7 3095 | supports-preserve-symlinks-flag: 1.0.0 3096 | 3097 | reusify@1.0.4: {} 3098 | 3099 | rollup@4.21.2: 3100 | dependencies: 3101 | '@types/estree': 1.0.5 3102 | optionalDependencies: 3103 | '@rollup/rollup-android-arm-eabi': 4.21.2 3104 | '@rollup/rollup-android-arm64': 4.21.2 3105 | '@rollup/rollup-darwin-arm64': 4.21.2 3106 | '@rollup/rollup-darwin-x64': 4.21.2 3107 | '@rollup/rollup-linux-arm-gnueabihf': 4.21.2 3108 | '@rollup/rollup-linux-arm-musleabihf': 4.21.2 3109 | '@rollup/rollup-linux-arm64-gnu': 4.21.2 3110 | '@rollup/rollup-linux-arm64-musl': 4.21.2 3111 | '@rollup/rollup-linux-powerpc64le-gnu': 4.21.2 3112 | '@rollup/rollup-linux-riscv64-gnu': 4.21.2 3113 | '@rollup/rollup-linux-s390x-gnu': 4.21.2 3114 | '@rollup/rollup-linux-x64-gnu': 4.21.2 3115 | '@rollup/rollup-linux-x64-musl': 4.21.2 3116 | '@rollup/rollup-win32-arm64-msvc': 4.21.2 3117 | '@rollup/rollup-win32-ia32-msvc': 4.21.2 3118 | '@rollup/rollup-win32-x64-msvc': 4.21.2 3119 | fsevents: 2.3.3 3120 | 3121 | run-parallel@1.2.0: 3122 | dependencies: 3123 | queue-microtask: 1.2.3 3124 | 3125 | scheduler@0.23.2: 3126 | dependencies: 3127 | loose-envify: 1.4.0 3128 | 3129 | semver@6.3.1: {} 3130 | 3131 | semver@7.5.4: 3132 | dependencies: 3133 | lru-cache: 6.0.0 3134 | 3135 | semver@7.6.3: {} 3136 | 3137 | shebang-command@2.0.0: 3138 | dependencies: 3139 | shebang-regex: 3.0.0 3140 | 3141 | shebang-regex@3.0.0: {} 3142 | 3143 | siginfo@2.0.0: {} 3144 | 3145 | signal-exit@4.1.0: {} 3146 | 3147 | source-map-js@1.2.0: {} 3148 | 3149 | source-map@0.6.1: {} 3150 | 3151 | sprintf-js@1.0.3: {} 3152 | 3153 | stackback@0.0.2: {} 3154 | 3155 | std-env@3.7.0: {} 3156 | 3157 | string-argv@0.3.2: {} 3158 | 3159 | string-width@4.2.3: 3160 | dependencies: 3161 | emoji-regex: 8.0.0 3162 | is-fullwidth-code-point: 3.0.0 3163 | strip-ansi: 6.0.1 3164 | 3165 | string-width@5.1.2: 3166 | dependencies: 3167 | eastasianwidth: 0.2.0 3168 | emoji-regex: 9.2.2 3169 | strip-ansi: 7.1.0 3170 | 3171 | strip-ansi@6.0.1: 3172 | dependencies: 3173 | ansi-regex: 5.0.1 3174 | 3175 | strip-ansi@7.1.0: 3176 | dependencies: 3177 | ansi-regex: 6.0.1 3178 | 3179 | strip-final-newline@3.0.0: {} 3180 | 3181 | strip-json-comments@3.1.1: {} 3182 | 3183 | supports-color@5.5.0: 3184 | dependencies: 3185 | has-flag: 3.0.0 3186 | 3187 | supports-color@7.2.0: 3188 | dependencies: 3189 | has-flag: 4.0.0 3190 | 3191 | supports-color@8.1.1: 3192 | dependencies: 3193 | has-flag: 4.0.0 3194 | 3195 | supports-preserve-symlinks-flag@1.0.0: {} 3196 | 3197 | synckit@0.9.1: 3198 | dependencies: 3199 | '@pkgr/core': 0.1.1 3200 | tslib: 2.7.0 3201 | 3202 | test-exclude@7.0.1: 3203 | dependencies: 3204 | '@istanbuljs/schema': 0.1.3 3205 | glob: 10.4.5 3206 | minimatch: 9.0.5 3207 | 3208 | text-table@0.2.0: {} 3209 | 3210 | tinybench@2.9.0: {} 3211 | 3212 | tinypool@1.0.1: {} 3213 | 3214 | tinyrainbow@1.2.0: {} 3215 | 3216 | tinyspy@3.0.0: {} 3217 | 3218 | to-fast-properties@2.0.0: {} 3219 | 3220 | to-regex-range@5.0.1: 3221 | dependencies: 3222 | is-number: 7.0.0 3223 | 3224 | ts-api-utils@1.3.0(typescript@5.5.4): 3225 | dependencies: 3226 | typescript: 5.5.4 3227 | 3228 | tslib@2.7.0: {} 3229 | 3230 | type-check@0.4.0: 3231 | dependencies: 3232 | prelude-ls: 1.2.1 3233 | 3234 | typescript-eslint@8.4.0(eslint@9.9.1)(typescript@5.5.4): 3235 | dependencies: 3236 | '@typescript-eslint/eslint-plugin': 8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1)(typescript@5.5.4))(eslint@9.9.1)(typescript@5.5.4) 3237 | '@typescript-eslint/parser': 8.4.0(eslint@9.9.1)(typescript@5.5.4) 3238 | '@typescript-eslint/utils': 8.4.0(eslint@9.9.1)(typescript@5.5.4) 3239 | optionalDependencies: 3240 | typescript: 5.5.4 3241 | transitivePeerDependencies: 3242 | - eslint 3243 | - supports-color 3244 | 3245 | typescript@5.4.2: {} 3246 | 3247 | typescript@5.5.4: {} 3248 | 3249 | ufo@1.5.4: {} 3250 | 3251 | universalify@0.1.2: {} 3252 | 3253 | update-browserslist-db@1.1.0(browserslist@4.23.3): 3254 | dependencies: 3255 | browserslist: 4.23.3 3256 | escalade: 3.2.0 3257 | picocolors: 1.1.0 3258 | 3259 | uri-js@4.4.1: 3260 | dependencies: 3261 | punycode: 2.3.1 3262 | 3263 | vite-node@2.0.5: 3264 | dependencies: 3265 | cac: 6.7.14 3266 | debug: 4.3.6 3267 | pathe: 1.1.2 3268 | tinyrainbow: 1.2.0 3269 | vite: 5.4.3 3270 | transitivePeerDependencies: 3271 | - '@types/node' 3272 | - less 3273 | - lightningcss 3274 | - sass 3275 | - sass-embedded 3276 | - stylus 3277 | - sugarss 3278 | - supports-color 3279 | - terser 3280 | 3281 | vite-plugin-dts@4.1.0(rollup@4.21.2)(typescript@5.5.4)(vite@5.4.3): 3282 | dependencies: 3283 | '@microsoft/api-extractor': 7.47.4 3284 | '@rollup/pluginutils': 5.1.0(rollup@4.21.2) 3285 | '@volar/typescript': 2.4.2 3286 | '@vue/language-core': 2.0.29(typescript@5.5.4) 3287 | compare-versions: 6.1.1 3288 | debug: 4.3.6 3289 | kolorist: 1.8.0 3290 | local-pkg: 0.5.0 3291 | magic-string: 0.30.11 3292 | typescript: 5.5.4 3293 | vue-tsc: 2.0.29(typescript@5.5.4) 3294 | optionalDependencies: 3295 | vite: 5.4.3 3296 | transitivePeerDependencies: 3297 | - '@types/node' 3298 | - rollup 3299 | - supports-color 3300 | 3301 | vite@5.4.3: 3302 | dependencies: 3303 | esbuild: 0.21.5 3304 | postcss: 8.4.45 3305 | rollup: 4.21.2 3306 | optionalDependencies: 3307 | fsevents: 2.3.3 3308 | 3309 | vitest@2.0.5(happy-dom@15.7.3): 3310 | dependencies: 3311 | '@ampproject/remapping': 2.3.0 3312 | '@vitest/expect': 2.0.5 3313 | '@vitest/pretty-format': 2.0.5 3314 | '@vitest/runner': 2.0.5 3315 | '@vitest/snapshot': 2.0.5 3316 | '@vitest/spy': 2.0.5 3317 | '@vitest/utils': 2.0.5 3318 | chai: 5.1.1 3319 | debug: 4.3.6 3320 | execa: 8.0.1 3321 | magic-string: 0.30.11 3322 | pathe: 1.1.2 3323 | std-env: 3.7.0 3324 | tinybench: 2.9.0 3325 | tinypool: 1.0.1 3326 | tinyrainbow: 1.2.0 3327 | vite: 5.4.3 3328 | vite-node: 2.0.5 3329 | why-is-node-running: 2.3.0 3330 | optionalDependencies: 3331 | happy-dom: 15.7.3 3332 | transitivePeerDependencies: 3333 | - less 3334 | - lightningcss 3335 | - sass 3336 | - sass-embedded 3337 | - stylus 3338 | - sugarss 3339 | - supports-color 3340 | - terser 3341 | 3342 | vscode-uri@3.0.8: {} 3343 | 3344 | vue-tsc@2.0.29(typescript@5.5.4): 3345 | dependencies: 3346 | '@volar/typescript': 2.4.2 3347 | '@vue/language-core': 2.0.29(typescript@5.5.4) 3348 | semver: 7.6.3 3349 | typescript: 5.5.4 3350 | 3351 | webidl-conversions@7.0.0: {} 3352 | 3353 | whatwg-mimetype@3.0.0: {} 3354 | 3355 | which@2.0.2: 3356 | dependencies: 3357 | isexe: 2.0.0 3358 | 3359 | why-is-node-running@2.3.0: 3360 | dependencies: 3361 | siginfo: 2.0.0 3362 | stackback: 0.0.2 3363 | 3364 | word-wrap@1.2.5: {} 3365 | 3366 | wrap-ansi@7.0.0: 3367 | dependencies: 3368 | ansi-styles: 4.3.0 3369 | string-width: 4.2.3 3370 | strip-ansi: 6.0.1 3371 | 3372 | wrap-ansi@8.1.0: 3373 | dependencies: 3374 | ansi-styles: 6.2.1 3375 | string-width: 5.1.2 3376 | strip-ansi: 7.1.0 3377 | 3378 | yallist@3.1.1: {} 3379 | 3380 | yallist@4.0.0: {} 3381 | 3382 | yocto-queue@0.1.0: {} 3383 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | tabWidth: 2, 3 | semi: false, 4 | singleQuote: true, 5 | printWidth: 110, 6 | endOfLine: 'auto', 7 | } 8 | -------------------------------------------------------------------------------- /scripts/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | PKG_VERSION=$(jq -r '.version' package.json) 6 | 7 | git fetch origin v"$PKG_VERSION" || { 8 | npx standard-version --skip.changelog --skip.commit -a --release-as "$PKG_VERSION" 9 | git push --follow-tags origin main 10 | } 11 | -------------------------------------------------------------------------------- /src/_logger.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact.logger 3 | * @author Surmon 4 | */ 5 | 6 | const VEACT_NAME = 'veact' 7 | 8 | export const logger: Console = { 9 | ...console, 10 | log(...args: any) { 11 | console.log(`[${VEACT_NAME}]`, ...args) 12 | }, 13 | warn(...args: any) { 14 | console.warn(`[${VEACT_NAME}]`, ...args) 15 | }, 16 | error(...args: any) { 17 | console.error(`[${VEACT_NAME}]`, ...args) 18 | }, 19 | } 20 | -------------------------------------------------------------------------------- /src/_utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact.utils 3 | * @author Surmon 4 | */ 5 | 6 | import { useReducer } from 'react' 7 | 8 | export type ArgumentTypes = F extends (...args: infer A) => any ? A : never 9 | export type IfAny = 0 extends 1 & T ? Y : N 10 | 11 | export const increment = (s: number) => s + 1 12 | export const useForceUpdate = () => useReducer(increment, 0)[1] 13 | -------------------------------------------------------------------------------- /src/computed.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact.computed 3 | * @author Surmon 4 | */ 5 | 6 | import { useState as useReactState } from 'react' 7 | import { computed as vueComputed } from '@vue/reactivity' 8 | import type { 9 | ComputedRef, 10 | ComputedGetter, 11 | WritableComputedRef, 12 | WritableComputedOptions, 13 | DebuggerOptions, 14 | } from '@vue/reactivity' 15 | import { useWatch } from './watch' 16 | import { useForceUpdate } from './_utils' 17 | 18 | /** 19 | * Takes a getter function and returns a readonly reactive ref object for the 20 | * returned value from the getter. It can also take an object with get and set 21 | * functions to create a writable ref object. 22 | * 23 | * @param getter - Function that produces the next value. 24 | * @param debugOptions - For debugging. See {@link https://vuejs.org/guide/extras/reactivity-in-depth.html#computed-debugging Vue Computed Debugging}. 25 | * @see {@link https://vuejs.org/api/reactivity-core.html#computed Vue `computed()`} 26 | * 27 | * @example 28 | * ```js 29 | * // Creating a readonly computed ref: 30 | * const count = useRef(1) 31 | * const plusOne = useComputed(() => count.value + 1) 32 | * 33 | * console.log(plusOne.value) // 2 34 | * plusOne.value++ // error 35 | * ``` 36 | * 37 | * @example 38 | * ```js 39 | * // Creating a writable computed ref: 40 | * const count = useRef(1) 41 | * const plusOne = useComputed({ 42 | * get: () => count.value + 1, 43 | * set: (val) => { 44 | * count.value = val - 1 45 | * } 46 | * }) 47 | * 48 | * plusOne.value = 1 49 | * console.log(count.value) // 0 50 | * ``` 51 | */ 52 | export function useComputed(getter: ComputedGetter, debugOptions?: DebuggerOptions): ComputedRef 53 | export function useComputed( 54 | options: WritableComputedOptions, 55 | debugOptions?: DebuggerOptions, 56 | ): WritableComputedRef 57 | export function useComputed(arg1: any, arg2: any) { 58 | const [value] = useReactState(() => vueComputed(arg1, arg2)) 59 | const forceUpdate = useForceUpdate() 60 | useWatch(value, forceUpdate) 61 | return value 62 | } 63 | -------------------------------------------------------------------------------- /src/effectScope.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact.effectScope 3 | * @author Surmon 4 | */ 5 | 6 | import { useState as useReactState, useRef as useReactRef, useCallback as useReactCallback } from 'react' 7 | import { effectScope as vueEffectScope } from '@vue/reactivity' 8 | import { ArgumentTypes } from './_utils' 9 | 10 | /** 11 | * Creates an effect scope object which can capture the reactive effects (i.e. 12 | * computed and watchers) created within it so that these effects can be 13 | * disposed together. For detailed use cases of this API, please consult its 14 | * corresponding {@link https://github.com/vuejs/rfcs/blob/master/active-rfcs/0041-reactivity-effect-scope.md | RFC}. 15 | * 16 | * @param detached - Can be used to create a "detached" effect scope. 17 | * @see {@link https://vuejs.org/api/reactivity-advanced.html#effectscope Vue `effectScope()`} 18 | */ 19 | export function useEffectScope(...args: ArgumentTypes) { 20 | const hasRun = useReactRef(false) 21 | const [scope] = useReactState(() => vueEffectScope(...args)) 22 | const originalRunRef = useReactRef(scope.run) 23 | const runFn = useReactCallback((fn: () => T) => { 24 | if (!hasRun.current) { 25 | hasRun.current = true 26 | return originalRunRef.current.bind(scope)(fn) 27 | } else { 28 | return undefined 29 | } 30 | }, []) 31 | 32 | scope.run = runFn 33 | return scope 34 | } 35 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact 3 | * @author Surmon 4 | */ 5 | 6 | // redirect all APIs from @vue/reactivity 7 | export * from '@vue/reactivity' 8 | export { watch as baseWatch } from '@vue/reactivity' 9 | 10 | // lifecycle hooks 11 | export { onMounted, onUpdated, onBeforeUnmount } from './lifecycle' 12 | 13 | // ref and hooks 14 | export { useRef, useShallowRef, useCustomRef } from './ref' 15 | 16 | // reactive and hooks 17 | export { useReactive, useShallowReactive } from './reactive' 18 | 19 | // readonly and hooks 20 | export { useReadonly, useShallowReadonly } from './readonly' 21 | 22 | // computed and hooks 23 | export { useComputed } from './computed' 24 | 25 | // watch and hooks 26 | export { watch, useWatch } from './watch' 27 | export type { WatchOptions, MultiWatchSources } from './watch' 28 | 29 | // watchEffect and hooks 30 | export { watchEffect, useWatchEffect } from './watchEffect' 31 | export type { WatchEffectOptions } from './watchEffect' 32 | 33 | // effectScope hooks 34 | export { useEffectScope } from './effectScope' 35 | 36 | // reactivity enhancer hooks 37 | export { useReactivity } from './reactivity' 38 | -------------------------------------------------------------------------------- /src/lifecycle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact.lifecycle 3 | * @author Surmon 4 | */ 5 | 6 | import { useRef, useEffect } from 'react' 7 | 8 | /** 9 | * The function is called right after the component is mounted. 10 | * 11 | * @param fn 12 | * @see {@link https://react.dev/reference/react/Component#componentdidmount React `componentDidMount()`} 13 | */ 14 | export function onMounted(fn: () => any) { 15 | useEffect(() => { 16 | fn() 17 | }, []) 18 | } 19 | 20 | /** 21 | * The function is called right before the component is unmounted. 22 | * 23 | * @param fn 24 | * @see {@link https://react.dev/reference/react/Component#componentwillunmount React `componentWillUnmount()`} 25 | */ 26 | export function onBeforeUnmount(fn: () => void) { 27 | useEffect(() => { 28 | return () => { 29 | fn() 30 | } 31 | }, []) 32 | } 33 | 34 | /** 35 | * The function is called immediately after the component is re-rendered with updated props or state. 36 | * This method is not invoked during the initial render. 37 | * 38 | * @param fn 39 | * @see {@link https://react.dev/reference/react/Component#componentdidupdate React `componentDidUpdate()`} 40 | */ 41 | export function onUpdated(fn: () => void) { 42 | const isMounted = useRef(false) 43 | useEffect(() => { 44 | if (isMounted.current) { 45 | fn() 46 | } else { 47 | isMounted.current = true 48 | } 49 | }) 50 | } 51 | -------------------------------------------------------------------------------- /src/reactive.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact.reactive 3 | * @author Surmon 4 | */ 5 | 6 | import { useState as useReactState } from 'react' 7 | import { reactive as vueReactive, shallowReactive as vueShallowReactive } from '@vue/reactivity' 8 | import type { Reactive, ShallowReactive } from '@vue/reactivity' 9 | import { useWatch } from './watch' 10 | import { useForceUpdate } from './_utils' 11 | 12 | /** 13 | * Returns a reactive proxy of the object. 14 | * 15 | * The reactive conversion is "deep": it affects all nested properties. A 16 | * reactive object also deeply unwraps any properties that are refs while 17 | * maintaining reactivity. 18 | * 19 | * @param target - The source object. 20 | * @see {@link https://vuejs.org/api/reactivity-core.html#reactive Vue `reactive()`} 21 | * 22 | * @example 23 | * ```js 24 | * const obj = useReactive({ count: 0 }) 25 | * ``` 26 | */ 27 | export function useReactive(target: T): Reactive 28 | export function useReactive(target: object) { 29 | const [value] = useReactState(() => vueReactive(target)) 30 | const forceUpdate = useForceUpdate() 31 | useWatch(value, forceUpdate) 32 | return value 33 | } 34 | 35 | /** 36 | * Shallow version of {@link useReactive()}. 37 | * 38 | * Unlike {@link useReactive()}, there is no deep conversion: only root-level 39 | * properties are reactive for a shallow reactive object. Property values are 40 | * stored and exposed as-is - this also means properties with ref values will 41 | * not be automatically unwrapped. 42 | * 43 | * @param target - The source object. 44 | * @see {@link https://vuejs.org/api/reactivity-advanced.html#shallowreactive Vue `shallowReactive()`} 45 | * 46 | * @example 47 | * ```js 48 | * const state = useShallowReactive({ 49 | * foo: 1, 50 | * nested: { 51 | * bar: 2 52 | * } 53 | * }) 54 | * 55 | * // mutating state's own properties is reactive 56 | * state.foo++ 57 | * 58 | * // ...but does not convert nested objects 59 | * isReactive(state.nested) // false 60 | * 61 | * // NOT reactive 62 | * state.nested.bar++ 63 | * ``` 64 | */ 65 | export function useShallowReactive(target: T): ShallowReactive { 66 | const [value] = useReactState(() => vueShallowReactive(target)) 67 | const forceUpdate = useForceUpdate() 68 | useWatch(value, forceUpdate) 69 | return value 70 | } 71 | -------------------------------------------------------------------------------- /src/reactivity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact.reactivity 3 | * @author Surmon 4 | */ 5 | 6 | import { useWatch } from './watch' 7 | import { useForceUpdate } from './_utils' 8 | 9 | /** 10 | * Converts some of the 'raw Vue' data, which is not already wrapped in a hook, 11 | * into reactive hook data to ensure proper reactivity within the component. 12 | * 13 | * @param getter - A function that returns the data to be deeply watched. 14 | * @example 15 | * ```tsx 16 | * import React from 'react' 17 | * import { ref, useReactivity } from 'veact' 18 | * 19 | * const countRef = ref(0) 20 | * 21 | * export const Component: React.FC = () => { 22 | * // Convert to a reactivity hook 23 | * const count = useReactivity(() => countRef) 24 | * const increment = () => { 25 | * count.value++ 26 | * } 27 | * 28 | * return ( 29 | *
30 | * {count.value} 31 | * 32 | *
33 | * ) 34 | * } 35 | * ``` 36 | */ 37 | export function useReactivity(getter: () => T): T { 38 | const forceUpdate = useForceUpdate() 39 | // deep > watch > traverse(getter()) > ref | array | set | map | plain object(reactive) > force update 40 | useWatch(() => getter(), forceUpdate, { deep: true }) 41 | return getter() 42 | } 43 | -------------------------------------------------------------------------------- /src/readonly.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact.readonly 3 | * @author Surmon 4 | */ 5 | 6 | import { useState as useReactState } from 'react' 7 | import { readonly as vueReadonly, shallowReadonly as vueShallowReadonly } from '@vue/reactivity' 8 | import type { DeepReadonly, UnwrapNestedRefs } from '@vue/reactivity' 9 | import { useWatch } from './watch' 10 | import { useForceUpdate } from './_utils' 11 | 12 | /** 13 | * Takes an object (reactive or plain) or a ref and returns a readonly proxy to 14 | * the original. 15 | * 16 | * A readonly proxy is deep: any nested property accessed will be readonly as 17 | * well. It also has the same ref-unwrapping behavior as {@link useReactive()}, 18 | * except the unwrapped values will also be made readonly. 19 | * 20 | * @param target - The source object. 21 | * @see {@link https://vuejs.org/api/reactivity-core.html#readonly Vue `readonly()`} 22 | * 23 | * @example 24 | * ```js 25 | * const original = useReactive({ count: 0 }) 26 | * const copy = useReadonly(original) 27 | * 28 | * useWatchEffect(() => { 29 | * // works for reactivity tracking 30 | * console.log(copy.count) 31 | * }) 32 | * 33 | * // mutating original will trigger watchers relying on the copy 34 | * original.count++ 35 | * 36 | * // mutating the copy will fail and result in a warning 37 | * copy.count++ // warning! 38 | * ``` 39 | */ 40 | export function useReadonly(target: T): DeepReadonly> { 41 | const [value] = useReactState(() => vueReadonly(target)) 42 | const forceUpdate = useForceUpdate() 43 | useWatch(value, forceUpdate) 44 | return value 45 | } 46 | 47 | // https://vuejs.org/api/reactivity-advanced.html#shallowreadonly 48 | // useShallowReadonly 49 | 50 | /** 51 | * Shallow version of {@link useReadonly()}. 52 | * 53 | * Unlike {@link useReadonly()}, there is no deep conversion: only root-level 54 | * properties are made readonly. Property values are stored and exposed as-is - 55 | * this also means properties with ref values will not be automatically 56 | * unwrapped. 57 | * 58 | * @param target - The source object. 59 | * @see {@link https://vuejs.org/api/reactivity-advanced.html#shallowreadonly Vue `shallowReadonly()`} 60 | * 61 | * @example 62 | * ```js 63 | * const state = useShallowReadonly({ 64 | * foo: 1, 65 | * nested: { 66 | * bar: 2 67 | * } 68 | * }) 69 | * 70 | * // mutating state's own properties will fail 71 | * state.foo++ 72 | * 73 | * // ...but works on nested objects 74 | * isReadonly(state.nested) // false 75 | * 76 | * // works 77 | * state.nested.bar++ 78 | * ``` 79 | */ 80 | export function useShallowReadonly(target: T): Readonly { 81 | const [value] = useReactState(() => vueShallowReadonly(target)) 82 | const forceUpdate = useForceUpdate() 83 | useWatch(value, forceUpdate) 84 | return value 85 | } 86 | -------------------------------------------------------------------------------- /src/ref.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact.ref 3 | * @author Surmon 4 | */ 5 | 6 | import { useState as useReactState } from 'react' 7 | import { ref as vueRef, shallowRef as vueShallowRef, customRef as vueCustomRef } from '@vue/reactivity' 8 | import type { Ref, UnwrapRef, ShallowRef, CustomRefFactory } from '@vue/reactivity' 9 | import { useForceUpdate, IfAny } from './_utils' 10 | import { useWatch } from './watch' 11 | 12 | /** 13 | * Takes an inner value and returns a reactive and mutable ref object, which 14 | * has a single property `.value` that points to the inner value. 15 | * 16 | * @param value - The object to wrap in the ref. 17 | * @see {@link https://vuejs.org/api/reactivity-core.html#ref Vue `ref()`} 18 | * 19 | * @example 20 | * ```js 21 | * const count = useRef(0) 22 | * console.log(count.value) // 0 23 | * 24 | * count.value = 1 25 | * console.log(count.value) // 1 26 | * ``` 27 | */ 28 | export function useRef( 29 | value: T, 30 | ): [T] extends [Ref] ? IfAny, T> : Ref, UnwrapRef | T> 31 | export function useRef(): Ref 32 | export function useRef(initValue?: unknown) { 33 | const [refObject] = useReactState(() => vueRef(initValue)) 34 | const forceUpdate = useForceUpdate() 35 | useWatch(refObject, forceUpdate, { deep: true }) 36 | return refObject as unknown as any 37 | } 38 | 39 | /** 40 | * Shallow version of {@link useRef()}. 41 | * 42 | * @param value - The "inner value" for the shallow ref. 43 | * @see {@link https://vuejs.org/api/reactivity-advanced.html#shallowref Vue `shallowRef()`} 44 | * 45 | * @example 46 | * ```js 47 | * const state = useShallowRef({ count: 1 }) 48 | * // does NOT trigger change 49 | * state.value.count = 2 50 | * // does trigger change 51 | * state.value = { count: 2 } 52 | * ``` 53 | */ 54 | export function useShallowRef( 55 | value: T, 56 | ): Ref extends T ? (T extends Ref ? IfAny, T> : ShallowRef) : ShallowRef 57 | export function useShallowRef(): ShallowRef 58 | export function useShallowRef(initValue?: unknown) { 59 | const [shallowRefObject] = useReactState(() => vueShallowRef(initValue)) 60 | const forceUpdate = useForceUpdate() 61 | useWatch(shallowRefObject, forceUpdate) 62 | return shallowRefObject 63 | } 64 | 65 | /** 66 | * Creates a customized ref with explicit control over its dependency tracking 67 | * and updates triggering. 68 | * 69 | * @param factory - The function that receives the `track` and `trigger` callbacks. 70 | * @see {@link https://vuejs.org/api/reactivity-advanced.html#customref Vue `customRef()`} 71 | */ 72 | export function useCustomRef(factory: CustomRefFactory): Ref { 73 | const [customRefObject] = useReactState(() => vueCustomRef(factory)) 74 | const forceUpdate = useForceUpdate() 75 | useWatch(customRefObject, forceUpdate) 76 | return customRefObject 77 | } 78 | -------------------------------------------------------------------------------- /src/watch.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact.watch 3 | * @author Surmon 4 | */ 5 | 6 | import { useState as useReactState } from 'react' 7 | import { watch as vueWatch } from '@vue/reactivity' 8 | import type { 9 | ReactiveMarker, 10 | DebuggerOptions, 11 | WatchCallback, 12 | WatchSource, 13 | WatchHandle, 14 | } from '@vue/reactivity' 15 | import { onBeforeUnmount } from './lifecycle' 16 | import { logger } from './_logger' 17 | 18 | // changelog: https://github.com/vuejs/core/blob/main/CHANGELOG.md 19 | // https://github.com/vuejs/core/blob/main/packages/runtime-core/src/apiWatch.ts 20 | // https://github.com/vuejs/core/blob/main/packages/reactivity/src/watch.ts 21 | 22 | export interface WatchOptions extends DebuggerOptions { 23 | immediate?: Immediate 24 | deep?: boolean | number 25 | once?: boolean 26 | // The `flush` option is not supported in veact at the moment. 27 | // flush?: 'pre' | 'post' | 'sync' 28 | } 29 | 30 | export type MultiWatchSources = (WatchSource | object)[] 31 | 32 | type MaybeUndefined = I extends true ? T | undefined : T 33 | type MapSources = { 34 | [K in keyof T]: T[K] extends WatchSource 35 | ? MaybeUndefined 36 | : T[K] extends object 37 | ? MaybeUndefined 38 | : never 39 | } 40 | 41 | /** 42 | * Watches one or more reactive data sources and invokes a callback function when the sources change. 43 | * 44 | * @param source - The watcher's source. 45 | * @param callback - This function will be called when the source is changed. 46 | * @param options - An optional options object that does not support the `flush` option compared to Vue (3.5.0). 47 | * @see {@link https://vuejs.org/api/reactivity-core.html#watch Vue `watch()`} 48 | * 49 | * @example 50 | * ```js 51 | * const count = ref(0) 52 | * watch(count, (count, prevCount) => { 53 | * // ... 54 | * }) 55 | * ``` 56 | */ 57 | 58 | // overload: single source + cb 59 | export function watch = false>( 60 | source: WatchSource, 61 | callback: WatchCallback>, 62 | options?: WatchOptions, 63 | ): WatchHandle 64 | 65 | // overload: reactive array or tuple of multiple sources + cb 66 | export function watch, Immediate extends Readonly = false>( 67 | sources: readonly [...T] | T, 68 | callback: [T] extends [ReactiveMarker] 69 | ? WatchCallback> 70 | : WatchCallback, MapSources>, 71 | options?: WatchOptions, 72 | ): WatchHandle 73 | 74 | // overload: array of multiple sources + cb 75 | export function watch = false>( 76 | sources: [...T], 77 | callback: WatchCallback, MapSources>, 78 | options?: WatchOptions, 79 | ): WatchHandle 80 | 81 | // overload: watching reactive object w/ cb 82 | export function watch = false>( 83 | source: T, 84 | callback: WatchCallback>, 85 | options?: WatchOptions, 86 | ): WatchHandle 87 | 88 | // implementation 89 | export function watch = false>( 90 | source: T | WatchSource, 91 | callback: WatchCallback, 92 | options: WatchOptions = {}, 93 | ): WatchHandle { 94 | return vueWatch(source as any, callback, { 95 | ...options, 96 | onWarn: logger.warn, 97 | scheduler: (job) => job(), 98 | }) 99 | } 100 | 101 | /** 102 | * Watches one or more reactive data sources and invokes a callback function when the sources change. 103 | * 104 | * @param source - The watcher's source. 105 | * @param callback - This function will be called when the source is changed. 106 | * @param options - An optional options object that does not support the `flush` option compared to Vue (3.5.0). 107 | * @see {@link https://vuejs.org/api/reactivity-core.html#watch Vue `watch()`} 108 | * 109 | * @example 110 | * ```js 111 | * const count = useRef(0) 112 | * useWatch(count, (count, prevCount) => { 113 | * // ... 114 | * }) 115 | * ``` 116 | */ 117 | export const useWatch: typeof watch = (source: any, callback: any, options = {}) => { 118 | const [watchHandle] = useReactState(() => watch(source as any, callback, options)) 119 | onBeforeUnmount(() => watchHandle.stop()) 120 | return watchHandle 121 | } 122 | -------------------------------------------------------------------------------- /src/watchEffect.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module veact.watchEffect 3 | * @author Surmon 4 | */ 5 | 6 | import { useState as useReactState } from 'react' 7 | import { watch as vueWatch } from '@vue/reactivity' 8 | import type { WatchEffect, WatchHandle, DebuggerOptions } from '@vue/reactivity' 9 | import { onBeforeUnmount } from './lifecycle' 10 | import { logger } from './_logger' 11 | 12 | // changelog: https://github.com/vuejs/core/blob/main/CHANGELOG.md 13 | // https://github.com/vuejs/core/blob/main/packages/runtime-core/src/apiWatch.ts 14 | // https://github.com/vuejs/core/blob/main/packages/reactivity/src/watch.ts 15 | 16 | export type WatchEffectOptions = DebuggerOptions 17 | 18 | /** 19 | * Runs a function immediately while reactively tracking its dependencies and re-runs it whenever the dependencies are changed. 20 | * 21 | * @param effectFn - The effect function to run. 22 | * @param options - An optional options object that can be used to adjust the effect's flush timing or to debug the effect's dependencies; the `flush` option is not supported compared to Vue (3.5.0). 23 | * @see {@link https://vuejs.org/api/reactivity-core.html#watcheffect Vue `watchEffect()`} 24 | * 25 | * @example 26 | * ```js 27 | * const count = ref(0) 28 | * watchEffect(() => console.log(count.value)) 29 | * // -> logs 0 30 | * 31 | * count.value++ 32 | * // -> logs 1 33 | * ``` 34 | */ 35 | export function watchEffect(effectFn: WatchEffect, options: WatchEffectOptions = {}): WatchHandle { 36 | return vueWatch(effectFn, null, { 37 | ...options, 38 | onWarn: logger.warn, 39 | scheduler: (job) => job(), 40 | }) 41 | } 42 | 43 | /** 44 | * Runs a function immediately while reactively tracking its dependencies and re-runs it whenever the dependencies are changed. 45 | * 46 | * @param effect - The effect function to run. 47 | * @param options - An optional options object that can be used to adjust the effect's flush timing or to debug the effect's dependencies; the `flush` option is not supported compared to Vue (3.5.0). 48 | * @see {@link https://vuejs.org/api/reactivity-core.html#watcheffect Vue `watchEffect()`} 49 | * 50 | * @example 51 | * ```js 52 | * const count = useRef(0) 53 | * useWatchEffect(() => console.log(count.value)) 54 | * // -> logs 0 55 | * 56 | * count.value++ 57 | * // -> logs 1 58 | * ``` 59 | */ 60 | export const useWatchEffect: typeof watchEffect = (effect: any, options?: any) => { 61 | const [watchHandle] = useReactState(() => watchEffect(effect, options)) 62 | onBeforeUnmount(() => watchHandle.stop()) 63 | return watchHandle 64 | } 65 | -------------------------------------------------------------------------------- /tests/apis.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import * as vueReactivity from '@vue/reactivity' 3 | import * as veact from '../src' 4 | import { 5 | onMounted, 6 | onBeforeUnmount, 7 | onUpdated, 8 | useRef, 9 | useShallowRef, 10 | useCustomRef, 11 | useReactive, 12 | useShallowReactive, 13 | useReadonly, 14 | useShallowReadonly, 15 | useComputed, 16 | watch, 17 | useWatch, 18 | watchEffect, 19 | useWatchEffect, 20 | useEffectScope, 21 | useReactivity, 22 | } from '../src' 23 | 24 | test(' should be export all @vue/reactivity members', () => { 25 | expect(vueReactivity.watch).toBe(veact.baseWatch) 26 | expect( 27 | Object.keys(vueReactivity) 28 | .filter((key) => key !== 'watch') 29 | .every((key) => { 30 | const targetMember = (veact as any)[key] 31 | return targetMember && (vueReactivity as any)[key] === targetMember 32 | }), 33 | ).toBeTruthy() 34 | }) 35 | 36 | test(' should be the respective type', () => { 37 | const hooksTargetType = 'function' 38 | 39 | expect(typeof onMounted).toBe(hooksTargetType) 40 | expect(typeof onBeforeUnmount).toBe(hooksTargetType) 41 | expect(typeof onUpdated).toBe(hooksTargetType) 42 | expect(typeof useRef).toBe(hooksTargetType) 43 | expect(typeof useShallowRef).toBe(hooksTargetType) 44 | expect(typeof useCustomRef).toBe(hooksTargetType) 45 | expect(typeof useReactive).toBe(hooksTargetType) 46 | expect(typeof useShallowReactive).toBe(hooksTargetType) 47 | expect(typeof useReadonly).toBe(hooksTargetType) 48 | expect(typeof useShallowReadonly).toBe(hooksTargetType) 49 | expect(typeof useComputed).toBe(hooksTargetType) 50 | expect(typeof watch).toBe(hooksTargetType) 51 | expect(typeof useWatch).toBe(hooksTargetType) 52 | expect(typeof watchEffect).toBe(hooksTargetType) 53 | expect(typeof useWatchEffect).toBe(hooksTargetType) 54 | expect(typeof useEffectScope).toBe(hooksTargetType) 55 | expect(typeof useReactivity).toBe(hooksTargetType) 56 | }) 57 | -------------------------------------------------------------------------------- /tests/computed.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { renderHook, act } from '@testing-library/react' 3 | import { isRef, onUpdated, useRef, useComputed } from '../src' 4 | 5 | test(' readonly', () => { 6 | let renderCount = 0 7 | const { result } = renderHook(() => { 8 | onUpdated(() => renderCount++) 9 | const count = useRef(3) 10 | const doubled = useComputed(() => count.value * 2) 11 | return { count, doubled } 12 | }) 13 | 14 | expect(isRef(result.current.count)).toBeTruthy() 15 | expect(isRef(result.current.doubled)).toBeTruthy() 16 | expect(result.current.doubled.value).toBe(6) 17 | expect(renderCount).toBe(0) 18 | 19 | act(() => result.current.count.value++) 20 | expect(result.current.count.value).toBe(4) 21 | expect(result.current.doubled.value).toBe(8) 22 | expect(renderCount).toBe(1) 23 | }) 24 | 25 | test(' writable', () => { 26 | let renderCount = 0 27 | const { result } = renderHook(() => { 28 | onUpdated(() => renderCount++) 29 | const count = useRef(3) 30 | const doubled = useComputed({ 31 | set(value) { 32 | count.value = value / 2 33 | }, 34 | get() { 35 | return count.value * 2 36 | }, 37 | }) 38 | return { count, doubled } 39 | }) 40 | 41 | expect(isRef(result.current.count)).toBeTruthy() 42 | expect(isRef(result.current.doubled)).toBeTruthy() 43 | expect(result.current.doubled.value).toBe(6) 44 | expect(renderCount).toBe(0) 45 | 46 | act(() => result.current.count.value++) 47 | expect(result.current.count.value).toBe(4) 48 | expect(result.current.doubled.value).toBe(8) 49 | expect(renderCount).toBe(1) 50 | 51 | act(() => (result.current.doubled.value = 40)) 52 | expect(result.current.doubled.value).toBe(40) 53 | expect(result.current.count.value).toBe(20) 54 | expect(renderCount).toBe(2) 55 | }) 56 | -------------------------------------------------------------------------------- /tests/effectScope.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { renderHook, act } from '@testing-library/react' 3 | import { 4 | ref, 5 | reactive, 6 | useRef, 7 | watch, 8 | EffectScope, 9 | onUpdated, 10 | useEffectScope, 11 | getCurrentScope, 12 | onScopeDispose, 13 | } from '../src' 14 | 15 | test('', () => { 16 | let renderCount = 0 17 | let scopeRunCount = 0 18 | let scopeDisposed = false 19 | const foo = ref(0) 20 | const bar = reactive({ count: 10 }) 21 | 22 | const { result } = renderHook(() => { 23 | onUpdated(() => renderCount++) 24 | 25 | const scope = useEffectScope() 26 | const fooWatchChanged = useRef(0) 27 | const barWatchChanged = useRef(0) 28 | 29 | scope.run(() => { 30 | scopeRunCount++ 31 | watch(foo, () => { 32 | fooWatchChanged.value++ 33 | }) 34 | watch(bar, () => { 35 | barWatchChanged.value++ 36 | }) 37 | onScopeDispose(() => { 38 | scopeDisposed = true 39 | }) 40 | 41 | const currentScope = getCurrentScope() 42 | expect(currentScope).toBeDefined() 43 | expect(getCurrentScope()).toBe(currentScope) 44 | }) 45 | 46 | return { 47 | scope, 48 | fooWatchChanged, 49 | barWatchChanged, 50 | } 51 | }) 52 | 53 | expect(renderCount).toBe(0) 54 | expect(scopeRunCount).toBe(1) 55 | expect(scopeDisposed).toBe(false) 56 | expect(result.current.scope).toBeInstanceOf(EffectScope) 57 | 58 | act(() => foo.value++) 59 | expect(foo.value).toBe(1) 60 | expect(renderCount).toBe(1) 61 | expect(result.current.fooWatchChanged.value).toBe(1) 62 | expect(result.current.barWatchChanged.value).toBe(0) 63 | 64 | act(() => bar.count++) 65 | expect(bar.count).toBe(11) 66 | expect(renderCount).toBe(2) 67 | expect(result.current.fooWatchChanged.value).toBe(1) 68 | expect(result.current.barWatchChanged.value).toBe(1) 69 | 70 | act(() => result.current.scope.pause()) 71 | act(() => foo.value++) 72 | act(() => bar.count++) 73 | expect(result.current.fooWatchChanged.value).toBe(1) 74 | expect(result.current.barWatchChanged.value).toBe(1) 75 | expect(foo.value).toBe(2) 76 | expect(bar.count).toBe(12) 77 | expect(renderCount).toBe(2) 78 | expect(scopeDisposed).toBe(false) 79 | 80 | act(() => result.current.scope.resume()) 81 | expect(result.current.fooWatchChanged.value).toBe(2) 82 | expect(result.current.barWatchChanged.value).toBe(2) 83 | expect(renderCount).toBe(3) 84 | expect(scopeDisposed).toBe(false) 85 | 86 | act(() => result.current.scope.stop()) 87 | act(() => foo.value++) 88 | act(() => bar.count++) 89 | expect(result.current.fooWatchChanged.value).toBe(2) 90 | expect(result.current.barWatchChanged.value).toBe(2) 91 | expect(renderCount).toBe(3) 92 | expect(scopeDisposed).toBe(true) 93 | 94 | act(() => result.current.scope.resume()) 95 | act(() => foo.value++) 96 | act(() => bar.count++) 97 | expect(result.current.fooWatchChanged.value).toBe(2) 98 | expect(result.current.barWatchChanged.value).toBe(2) 99 | expect(renderCount).toBe(3) 100 | 101 | // Run only once 102 | expect(scopeRunCount).toBe(1) 103 | }) 104 | -------------------------------------------------------------------------------- /tests/lifecycle.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { renderHook, act } from '@testing-library/react' 3 | import { useRef, onMounted, onBeforeUnmount, onUpdated } from '../src' 4 | 5 | test('', () => { 6 | const testLogs: string[] = [] 7 | const hookRenderer = renderHook(() => { 8 | onMounted(() => { 9 | testLogs.push('onMounted') 10 | }) 11 | onUpdated(() => { 12 | testLogs.push('onUpdated') 13 | }) 14 | onBeforeUnmount(() => { 15 | testLogs.push('onBeforeUnmount') 16 | }) 17 | return useRef(0) 18 | }) 19 | 20 | act(() => hookRenderer.result.current.value++) 21 | 22 | expect(testLogs.length).toBe(2) 23 | expect(testLogs[0]).toBe('onMounted') 24 | expect(testLogs[1]).toBe('onUpdated') 25 | expect(hookRenderer.result.current.value).toBe(1) 26 | 27 | act(() => hookRenderer.result.current.value++) 28 | act(() => hookRenderer.result.current.value++) 29 | 30 | expect(testLogs.length).toBe(4) 31 | expect(testLogs[2]).toBe('onUpdated') 32 | expect(testLogs[3]).toBe('onUpdated') 33 | expect(hookRenderer.result.current.value).toBe(3) 34 | 35 | hookRenderer.unmount() 36 | 37 | expect(testLogs.length).toBe(5) 38 | expect(testLogs.at(-1)).toBe('onBeforeUnmount') 39 | }) 40 | -------------------------------------------------------------------------------- /tests/reactive.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { renderHook, act } from '@testing-library/react' 3 | import { onUpdated, isReactive, useReactive, useShallowReactive } from '../src' 4 | 5 | test('', () => { 6 | let renderCount = 0 7 | const { result } = renderHook(() => { 8 | onUpdated(() => renderCount++) 9 | return useReactive({ 10 | data: 10, 11 | nested: { data: 1 }, 12 | }) 13 | }) 14 | 15 | expect(result.current.data).toBe(10) 16 | expect(result.current.nested.data).toBe(1) 17 | expect(isReactive(result.current)).toBeTruthy() 18 | expect(isReactive(result.current.nested)).toBeTruthy() 19 | 20 | act(() => result.current.data++) 21 | expect(result.current.data).toBe(11) 22 | expect(renderCount).toBe(1) 23 | 24 | act(() => result.current.nested.data++) 25 | expect(result.current.nested.data).toBe(2) 26 | expect(renderCount).toBe(2) 27 | }) 28 | 29 | test('', () => { 30 | let renderCount = 0 31 | const { result } = renderHook(() => { 32 | onUpdated(() => renderCount++) 33 | return useShallowReactive({ 34 | data: 10, 35 | nested: { data: 1 }, 36 | }) 37 | }) 38 | 39 | expect(result.current.data).toBe(10) 40 | expect(result.current.nested.data).toBe(1) 41 | expect(isReactive(result.current)).toBeTruthy() 42 | expect(isReactive(result.current.nested)).toBeFalsy() 43 | 44 | act(() => result.current.nested.data++) 45 | expect(result.current.nested.data).toBe(2) 46 | expect(renderCount).toBe(0) 47 | 48 | act(() => result.current.data++) 49 | expect(result.current.data).toBe(11) 50 | expect(renderCount).toBe(1) 51 | }) 52 | -------------------------------------------------------------------------------- /tests/reactivity.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { renderHook, act } from '@testing-library/react' 3 | import { ref, reactive, isRef, isReactive, onUpdated, useReactivity } from '../src' 4 | 5 | test(' ', () => { 6 | let renderCount = 0 7 | const refCount = ref(0) 8 | const reactiveCount = reactive({ count: 10 }) 9 | const { result } = renderHook(() => { 10 | onUpdated(() => renderCount++) 11 | return useReactivity(() => ({ 12 | ref_: refCount, 13 | reactive_: reactiveCount, 14 | })) 15 | }) 16 | 17 | expect(isRef(result.current.ref_)).toBeTruthy() 18 | expect(isReactive(result.current.reactive_)).toBeTruthy() 19 | expect(result.current.ref_).toBe(refCount) 20 | expect(result.current.reactive_).toBe(reactiveCount) 21 | expect(result.current.ref_.value).toBe(0) 22 | 23 | act(() => refCount.value++) 24 | expect(result.current.ref_.value).toBe(1) 25 | expect(renderCount).toBe(1) 26 | 27 | act(() => reactiveCount.count++) 28 | expect(result.current.reactive_.count).toBe(11) 29 | expect(renderCount).toBe(2) 30 | 31 | act(() => result.current.reactive_.count++) 32 | expect(reactiveCount.count).toBe(12) 33 | expect(renderCount).toBe(3) 34 | }) 35 | -------------------------------------------------------------------------------- /tests/readonly.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect, vi, afterEach } from 'vitest' 2 | import { renderHook, act } from '@testing-library/react' 3 | import { reactive, isReactive, isReadonly, onUpdated, useReadonly, useShallowReadonly } from '../src' 4 | 5 | // for: [Vue warn] Set operation on key "xxx" failed: target is readonly. 6 | const consoleMock = vi.spyOn(console, 'warn').mockImplementation(() => undefined) 7 | afterEach(() => { 8 | consoleMock.mockReset() 9 | }) 10 | 11 | const dataObject = reactive({ 12 | data: 10, 13 | nested: { data: 1 }, 14 | }) 15 | 16 | test('', () => { 17 | let renderCount = 0 18 | const { result } = renderHook(() => { 19 | onUpdated(() => renderCount++) 20 | return useReadonly(dataObject) 21 | }) 22 | 23 | expect(result.current.data).toBe(10) 24 | expect(result.current.nested.data).toBe(1) 25 | expect(isReactive(result.current)).toBeTruthy() 26 | expect(isReactive(result.current.nested)).toBeTruthy() 27 | expect(isReadonly(result.current)).toBeTruthy() 28 | expect(isReadonly(result.current.nested)).toBeTruthy() 29 | 30 | // @ts-ignore 31 | act(() => result.current.data++) 32 | expect(result.current.data).toBe(10) 33 | expect(renderCount).toBe(0) 34 | 35 | // @ts-ignore 36 | act(() => result.current.nested.data++) 37 | expect(result.current.nested.data).toBe(1) 38 | expect(renderCount).toBe(0) 39 | 40 | expect(consoleMock).toHaveBeenCalledTimes(2) 41 | expect(consoleMock).toHaveBeenNthCalledWith( 42 | 1, 43 | `[Vue warn] Set operation on key "data" failed: target is readonly.`, 44 | result.current, 45 | ) 46 | expect(consoleMock).toHaveBeenNthCalledWith( 47 | 2, 48 | `[Vue warn] Set operation on key "data" failed: target is readonly.`, 49 | result.current.nested, 50 | ) 51 | }) 52 | 53 | test('', () => { 54 | let renderCount = 0 55 | const { result } = renderHook(() => { 56 | onUpdated(() => renderCount++) 57 | return useShallowReadonly(dataObject) 58 | }) 59 | 60 | expect(result.current.data).toBe(10) 61 | expect(result.current.nested.data).toBe(1) 62 | expect(isReactive(result.current)).toBeTruthy() 63 | expect(isReactive(result.current.nested)).toBeTruthy() 64 | expect(isReadonly(result.current)).toBeTruthy() 65 | expect(isReadonly(result.current.nested)).toBeFalsy() 66 | 67 | // @ts-ignore 68 | act(() => result.current.data++) 69 | expect(result.current.data).toBe(10) 70 | expect(renderCount).toBe(0) 71 | 72 | act(() => result.current.nested.data++) 73 | expect(result.current.nested.data).toBe(2) 74 | expect(renderCount).toBe(0) 75 | 76 | expect(consoleMock).toHaveBeenCalledOnce() 77 | expect(consoleMock).toHaveBeenLastCalledWith( 78 | `[Vue warn] Set operation on key "data" failed: target is readonly.`, 79 | result.current, 80 | ) 81 | }) 82 | -------------------------------------------------------------------------------- /tests/ref.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { renderHook, act } from '@testing-library/react' 3 | import { onUpdated, isRef, useRef, useShallowRef, useCustomRef } from '../src' 4 | 5 | test('', () => { 6 | let renderCount = 0 7 | const { result } = renderHook(() => { 8 | onUpdated(() => renderCount++) 9 | return useRef>({ count: 0 }) 10 | }) 11 | 12 | expect(result.current.value.count).toBe(0) 13 | expect(isRef(result.current)).toBeTruthy() 14 | 15 | act(() => result.current.value.count++) 16 | expect(result.current.value.count).toBe(1) 17 | expect(renderCount).toBe(1) 18 | 19 | act(() => result.current.value.count++) 20 | expect(result.current.value.count).toBe(2) 21 | expect(renderCount).toBe(2) 22 | 23 | act(() => (result.current.value = { name: 'veact' })) 24 | expect(result.current.value.name).toBe('veact') 25 | expect(renderCount).toBe(3) 26 | }) 27 | 28 | test('', () => { 29 | let renderCount = 0 30 | const { result } = renderHook(() => { 31 | onUpdated(() => renderCount++) 32 | return useShallowRef>({ count: 0 }) 33 | }) 34 | 35 | expect(result.current.value.count).toBe(0) 36 | expect(isRef(result.current)).toBeTruthy() 37 | 38 | act(() => result.current.value.count++) 39 | expect(result.current.value.count).toBe(1) 40 | expect(renderCount).toBe(0) 41 | 42 | act(() => (result.current.value = { name: 'veact' })) 43 | expect(result.current.value.name).toBe('veact') 44 | expect(renderCount).toBe(1) 45 | 46 | act(() => (result.current.value = { author: 'surmon' })) 47 | expect(result.current.value.name).toBeUndefined() 48 | expect(result.current.value.author).toBe('surmon') 49 | expect(renderCount).toBe(2) 50 | 51 | act(() => (result.current.value.author = '')) 52 | expect(result.current.value.author).toBe('') 53 | expect(renderCount).toBe(2) 54 | }) 55 | 56 | test('', () => { 57 | let renderCount = 0 58 | let refValue = 10 59 | const { result } = renderHook(() => { 60 | onUpdated(() => renderCount++) 61 | return useCustomRef((track, trigger) => ({ 62 | get() { 63 | track() 64 | return refValue 65 | }, 66 | set(newValue) { 67 | refValue = newValue 68 | trigger() 69 | }, 70 | })) 71 | }) 72 | 73 | expect(result.current.value).toBe(10) 74 | expect(isRef(result.current)).toBeTruthy() 75 | 76 | act(() => result.current.value++) 77 | expect(result.current.value).toBe(11) 78 | expect(renderCount).toBe(1) 79 | 80 | act(() => result.current.value++) 81 | expect(result.current.value).toBe(12) 82 | expect(renderCount).toBe(2) 83 | }) 84 | -------------------------------------------------------------------------------- /tests/watch.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { renderHook, act } from '@testing-library/react' 3 | import { ref, reactive, watch, useRef, useWatch, onUpdated, onWatcherCleanup } from '../src' 4 | 5 | test(' watchHandle / onCleanup / onWatcherCleanup', () => { 6 | const logs: any[] = [] 7 | const count = ref(0) 8 | 9 | const watchHandle = watch(count, (value, _, onCleanup) => { 10 | logs.push(value) 11 | onCleanup(() => logs.push('onCleanup')) 12 | onWatcherCleanup(() => logs.push('onWatcherCleanup')) 13 | }) 14 | 15 | expect(logs.length).toBe(0) 16 | expect(count.value).toBe(0) 17 | expect(watchHandle).toBeTypeOf('function') 18 | expect(watchHandle).toBeTypeOf('function') 19 | expect(watchHandle.pause).toBeTypeOf('function') 20 | expect(watchHandle.resume).toBeTypeOf('function') 21 | expect(watchHandle.stop).toBeTypeOf('function') 22 | 23 | count.value = 1 24 | expect(count.value).toBe(1) 25 | expect(logs[0]).toBe(1) 26 | 27 | watchHandle.pause() 28 | count.value = 2 29 | expect(logs.length).toBe(1) 30 | 31 | watchHandle.resume() 32 | count.value = 3 33 | expect(logs.at(-1)).toBe(3) 34 | expect(logs.length).toBe(7) 35 | 36 | watchHandle() 37 | expect(logs.length).toBe(9) 38 | expect(logs.at(-1)).toBe('onWatcherCleanup') 39 | expect(logs.at(-2)).toBe('onCleanup') 40 | expect(logs.at(-3)).toBe(3) 41 | 42 | count.value = 4 43 | expect(count.value).toBe(4) 44 | expect(logs.length).toBe(9) 45 | expect(logs.at(-1)).toBe('onWatcherCleanup') 46 | }) 47 | 48 | test(' { immediate: true }', () => { 49 | const logs: any[] = [] 50 | const count = ref(0) 51 | 52 | watch(count, (value) => logs.push(value), { immediate: true }) 53 | 54 | expect(count.value).toBe(0) 55 | expect(logs.length).toBe(1) 56 | expect(logs[0]).toBe(0) 57 | 58 | count.value = 1 59 | expect(logs.at(-1)).toBe(1) 60 | }) 61 | 62 | test(' { once: true }', () => { 63 | const logs: any[] = [] 64 | const count = ref(0) 65 | 66 | watch(count, (value) => logs.push(value), { once: true }) 67 | 68 | expect(count.value).toBe(0) 69 | expect(logs.length).toBe(0) 70 | 71 | count.value = 1 72 | expect(logs.length).toBe(1) 73 | expect(logs[0]).toBe(1) 74 | 75 | count.value = 2 76 | count.value = 3 77 | expect(logs.length).toBe(1) 78 | expect(logs[0]).toBe(1) 79 | }) 80 | 81 | test(' { deep }', () => { 82 | const watchTriggerCounts = { 83 | root: 0, 84 | default: 0, 85 | deepTrue: 0, 86 | deepFalse: 0, 87 | deep2: 0, 88 | deep4: 0, 89 | } 90 | 91 | const data = reactive({ 92 | root: 0, 93 | level1: { 94 | level2: { 95 | level3: { 96 | level4: 100, 97 | }, 98 | }, 99 | }, 100 | }) 101 | 102 | watch( 103 | () => data.root, 104 | () => watchTriggerCounts.root++, 105 | ) 106 | watch(data, () => watchTriggerCounts.default++) 107 | watch(data, () => watchTriggerCounts.deepTrue++, { deep: true }) 108 | watch(data, () => watchTriggerCounts.deepFalse++, { deep: false }) 109 | watch(data, () => watchTriggerCounts.deep2++, { deep: 2 }) 110 | watch(data, () => watchTriggerCounts.deep4++, { deep: 4 }) 111 | 112 | data.root++ 113 | data.root++ 114 | data.root++ 115 | data.level1.level2.level3.level4++ 116 | data.level1.level2.level3.level4++ 117 | data.level1.level2.level3.level4++ 118 | 119 | expect(watchTriggerCounts.root).toBe(3) 120 | expect(watchTriggerCounts.default).toBe(6) 121 | expect(watchTriggerCounts.deepTrue).toBe(6) 122 | expect(watchTriggerCounts.deepFalse).toBe(3) 123 | expect(watchTriggerCounts.deep2).toBe(3) 124 | expect(watchTriggerCounts.deep4).toBe(6) 125 | }) 126 | 127 | test(' ref', () => { 128 | const logs: any[] = [] 129 | const data = ref(0) 130 | watch(data, (value) => logs.push(value)) 131 | 132 | expect(logs.length).toBe(0) 133 | expect(data.value).toBe(0) 134 | 135 | data.value = 1 136 | expect(logs.length).toBe(1) 137 | expect(logs[0]).toBe(1) 138 | }) 139 | 140 | test(' [ref]', () => { 141 | const logs: any[] = [] 142 | const data = ref(0) 143 | watch([data], ([value]) => logs.push(value)) 144 | 145 | expect(logs.length).toBe(0) 146 | expect(data.value).toBe(0) 147 | 148 | data.value = 1 149 | expect(logs.length).toBe(1) 150 | expect(logs[0]).toBe(1) 151 | }) 152 | 153 | test(' () => ref.value', () => { 154 | const logs: any[] = [] 155 | const data = ref(0) 156 | watch( 157 | () => data.value, 158 | (value) => logs.push(value), 159 | ) 160 | 161 | expect(logs.length).toBe(0) 162 | expect(data.value).toBe(0) 163 | 164 | data.value = 1 165 | expect(data.value).toBe(1) 166 | expect(logs.length).toBe(1) 167 | expect(logs[0]).toBe(1) 168 | }) 169 | 170 | test(' () => [ref.value]', () => { 171 | const logs: any[] = [] 172 | const data = ref(0) 173 | watch( 174 | () => [data.value], 175 | ([value]) => logs.push(value), 176 | ) 177 | 178 | expect(logs.length).toBe(0) 179 | expect(data.value).toBe(0) 180 | 181 | data.value = 1 182 | expect(data.value).toBe(1) 183 | expect(logs.length).toBe(1) 184 | expect(logs[0]).toBe(1) 185 | }) 186 | 187 | test(' reactive', () => { 188 | const logs: boolean[] = [] 189 | const data = reactive({ visible: false }) 190 | watch(data, (newData) => logs.push(newData.visible)) 191 | 192 | expect(logs.length).toBe(0) 193 | expect(data.visible).toBe(false) 194 | 195 | data.visible = true 196 | expect(logs.length).toBe(1) 197 | expect(logs[0]).toBe(true) 198 | }) 199 | 200 | test(' () => JSON.stringify(reactive)', () => { 201 | let isEqual = false 202 | const logs: any[] = [] 203 | const data = reactive({ value: false }) 204 | watch( 205 | () => JSON.stringify(data), 206 | (newData, oldData) => { 207 | isEqual = newData === oldData 208 | logs.push(newData) 209 | }, 210 | ) 211 | 212 | expect(logs.length).toBe(0) 213 | expect(data.value).toBe(false) 214 | 215 | data.value = true 216 | expect(isEqual).toBe(false) 217 | expect(logs.length).toBe(1) 218 | expect(typeof logs[0]).toBe('string') 219 | }) 220 | 221 | test(' () => reactive[key]', () => { 222 | let count = 0 223 | const data = reactive({ value: false }) 224 | watch( 225 | () => data.value, 226 | () => count++, 227 | ) 228 | 229 | expect(count).toBe(0) 230 | data.value = true 231 | data.value = false 232 | data.value = true 233 | expect(count).toBe(3) 234 | }) 235 | 236 | test(' () => [ref.value, reactive[key]]', () => { 237 | const logs: any[] = [] 238 | const refData = ref(0) 239 | const reactiveData = reactive({ value: false }) 240 | watch( 241 | () => [refData.value, reactiveData.value] as const, 242 | (newData) => logs.push(...newData), 243 | ) 244 | 245 | expect(logs.length).toBe(0) 246 | 247 | refData.value++ 248 | expect(logs.length).toBe(2) 249 | expect(logs[0]).toBe(1) 250 | expect(logs[1]).toBe(false) 251 | 252 | reactiveData.value = true 253 | expect(logs.length).toBe(4) 254 | expect(logs[2]).toBe(1) 255 | expect(logs[3]).toBe(true) 256 | }) 257 | 258 | test(' [ref, reactive]', () => { 259 | const logs: any[] = [] 260 | const refData = ref(0) 261 | const reactiveData = reactive({ value: false }) 262 | watch([refData, reactiveData], (newData) => { 263 | logs.push(newData[0], newData[1].value) 264 | }) 265 | 266 | expect(logs.length).toBe(0) 267 | 268 | refData.value++ 269 | expect(logs.length).toBe(2) 270 | expect(logs[0]).toBe(1) 271 | expect(logs[1]).toBe(false) 272 | 273 | reactiveData.value = true 274 | expect(logs.length).toBe(4) 275 | expect(logs[2]).toBe(1) 276 | expect(logs[3]).toBe(true) 277 | }) 278 | 279 | test('', () => { 280 | let renderCount = 0 281 | const logs: any[] = [] 282 | const hookRender = renderHook(() => { 283 | const data = useRef(0) 284 | onUpdated(() => renderCount++) 285 | useWatch(data, (newValue, __, onCleanup) => { 286 | logs.push(newValue) 287 | onCleanup(() => logs.push('onCleanup')) 288 | }) 289 | return data 290 | }) 291 | 292 | expect(renderCount).toBe(0) 293 | expect(hookRender.result.current.value).toBe(0) 294 | 295 | act(() => hookRender.result.current.value++) 296 | expect(renderCount).toBe(1) 297 | expect(logs.length).toBe(1) 298 | expect(logs[0]).toBe(1) 299 | 300 | act(() => hookRender.result.current.value++) 301 | act(() => hookRender.result.current.value++) 302 | act(() => hookRender.result.current.value++) 303 | expect(renderCount).toBe(4) 304 | expect(logs.at(-1)).toBe(4) 305 | 306 | hookRender.unmount() 307 | expect(renderCount).toBe(4) 308 | expect(logs.at(-1)).toBe('onCleanup') 309 | }) 310 | -------------------------------------------------------------------------------- /tests/watchEffect.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { renderHook, act } from '@testing-library/react' 3 | import { ref, watchEffect, useWatchEffect, onEffectCleanup } from '../src' 4 | 5 | test(' watchHandle / onCleanup / onEffectCleanup', () => { 6 | const logs: any[] = [] 7 | const count = ref(0) 8 | const watchHandle = watchEffect((onCleanup) => { 9 | logs.push(count.value) 10 | onCleanup(() => logs.push('onCleanup')) 11 | onEffectCleanup(() => logs.push('onEffectCleanup')) 12 | }) 13 | 14 | expect(logs.length).toBe(1) 15 | expect(logs[0]).toBe(0) 16 | 17 | count.value++ 18 | expect(count.value).toBe(1) 19 | expect(logs.at(-1)).toBe(1) 20 | expect(logs.at(-2)).toBe('onCleanup') 21 | expect(logs.at(-3)).toBe('onEffectCleanup') 22 | 23 | count.value++ 24 | expect(count.value).toBe(2) 25 | expect(logs.at(-1)).toBe(2) 26 | expect(logs.at(-2)).toBe('onCleanup') 27 | 28 | watchHandle.pause() 29 | count.value++ 30 | expect(logs.length).toBe(7) 31 | 32 | watchHandle.resume() 33 | count.value++ 34 | expect(logs.at(-1)).toBe(4) 35 | 36 | watchHandle() 37 | expect(logs.at(-1)).toBe('onCleanup') 38 | expect(logs.at(-2)).toBe('onEffectCleanup') 39 | expect(logs.at(-3)).toBe(4) 40 | 41 | count.value++ 42 | expect(count.value).toBe(5) 43 | expect(logs.length).toBe(15) 44 | expect(logs.at(-1)).toBe('onCleanup') 45 | expect(logs.at(-2)).toBe('onEffectCleanup') 46 | }) 47 | 48 | test('', () => { 49 | let weTriggerCount = 0 50 | const logs: any[] = [] 51 | const count = ref(0) 52 | const hookRender = renderHook(() => { 53 | return useWatchEffect((onCleanup) => { 54 | weTriggerCount++ 55 | logs.push(count.value) 56 | onCleanup(() => logs.push('onCleanup')) 57 | }) 58 | }) 59 | 60 | expect(weTriggerCount).toBe(1) 61 | expect(logs.length).toBe(1) 62 | expect(logs[0]).toBe(0) 63 | 64 | act(() => count.value++) 65 | expect(weTriggerCount).toBe(2) 66 | expect(logs.at(-1)).toBe(1) 67 | 68 | hookRender.result.current.pause() 69 | act(() => count.value++) 70 | expect(weTriggerCount).toBe(2) 71 | 72 | hookRender.result.current.resume() 73 | expect(weTriggerCount).toBe(3) 74 | expect(logs.at(-1)).toBe(2) 75 | 76 | hookRender.unmount() 77 | expect(logs.at(-2)).toBe(2) 78 | expect(logs.at(-1)).toBe('onCleanup') 79 | }) 80 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 7 | "jsx": "react", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "resolveJsonModule": true, 11 | "declaration": true, 12 | "emitDeclarationOnly": true, 13 | "skipLibCheck": true, 14 | "noUnusedLocals": true, 15 | "noUnusedParameters": true, 16 | "noImplicitReturns": true, 17 | "outDir": "dist" 18 | }, 19 | "exclude": ["node_modules", "dist"] 20 | } 21 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import viteDts from 'vite-plugin-dts' 3 | import viteReact from '@vitejs/plugin-react' 4 | import { defineConfig } from 'vite' 5 | import packageJson from './package.json' 6 | 7 | const banner = ` 8 | /*! 9 | * ${packageJson.name} v${packageJson.version} 10 | * ${packageJson.homepage} 11 | * 12 | * Includes @vue/reactivity 13 | * https://github.com/vuejs/core/tree/main/packages/reactivity 14 | * 15 | * (c) 2021-present ${packageJson.author} and Veact contributors. 16 | * Released under the ${packageJson.license} License. 17 | * 18 | * Date: ${new Date().toISOString()} 19 | */ 20 | ` 21 | 22 | export default defineConfig({ 23 | // https://github.com/qmhc/vite-plugin-dts 24 | plugins: [viteReact(), viteDts({ rollupTypes: true })], 25 | test: { 26 | environment: 'happy-dom', 27 | coverage: { 28 | include: ['src/**/*'], 29 | }, 30 | }, 31 | build: { 32 | lib: { 33 | entry: './src/index.ts', 34 | name: 'veact', 35 | fileName: 'veact', 36 | }, 37 | rollupOptions: { 38 | external: ['react', 'react-dom', '@vue/reactivity'], 39 | output: { 40 | banner: `\n${banner}\n`, 41 | globals: { 42 | react: 'React', 43 | 'react-dom': 'ReactDOM', 44 | '@vue/reactivity': 'VueReactivity', 45 | }, 46 | }, 47 | }, 48 | }, 49 | }) 50 | --------------------------------------------------------------------------------