@uselets/ui 1.20.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/README.md +322 -425
  2. package/dist/as-child-Dxg3Xo1G.d.ts +41 -0
  3. package/dist/cli/uselets.mjs +5 -4
  4. package/dist/cli/uselets.mjs.map +1 -1
  5. package/dist/components/accordion.d.ts +12 -8
  6. package/dist/components/accordion.js +1 -1
  7. package/dist/components/accordion.js.map +1 -1
  8. package/dist/components/alert-dialog.d.ts +20 -15
  9. package/dist/components/alert-dialog.js +1 -1
  10. package/dist/components/alert-dialog.js.map +1 -1
  11. package/dist/components/alert.d.ts +1 -1
  12. package/dist/components/alert.js +1 -1
  13. package/dist/components/alert.js.map +1 -1
  14. package/dist/components/anchor.d.ts +3 -5
  15. package/dist/components/anchor.js +1 -1
  16. package/dist/components/anchor.js.map +1 -1
  17. package/dist/components/area-chart.d.ts +54 -0
  18. package/dist/components/area-chart.js +1 -1
  19. package/dist/components/area-chart.js.map +1 -1
  20. package/dist/components/avatar.d.ts +12 -7
  21. package/dist/components/avatar.js +1 -1
  22. package/dist/components/avatar.js.map +1 -1
  23. package/dist/components/badge.d.ts +3 -5
  24. package/dist/components/badge.js +1 -1
  25. package/dist/components/badge.js.map +1 -1
  26. package/dist/components/bar-chart.d.ts +48 -0
  27. package/dist/components/bar-chart.js +1 -1
  28. package/dist/components/bar-chart.js.map +1 -1
  29. package/dist/components/bottom-nav.d.ts +7 -3
  30. package/dist/components/bottom-nav.js +1 -1
  31. package/dist/components/bottom-nav.js.map +1 -1
  32. package/dist/components/breadcrumb.d.ts +3 -4
  33. package/dist/components/breadcrumb.js +1 -1
  34. package/dist/components/breadcrumb.js.map +1 -1
  35. package/dist/components/button-group.d.ts +3 -4
  36. package/dist/components/button-group.js +1 -1
  37. package/dist/components/button-group.js.map +1 -1
  38. package/dist/components/button.d.ts +8 -4
  39. package/dist/components/button.js +1 -1
  40. package/dist/components/button.js.map +1 -1
  41. package/dist/components/calendar.d.ts +4 -0
  42. package/dist/components/calendar.js +1 -1
  43. package/dist/components/calendar.js.map +1 -1
  44. package/dist/components/card.d.ts +4 -0
  45. package/dist/components/card.js +1 -1
  46. package/dist/components/card.js.map +1 -1
  47. package/dist/components/carousel.d.ts +11 -3
  48. package/dist/components/carousel.js +1 -1
  49. package/dist/components/carousel.js.map +1 -1
  50. package/dist/components/center.d.ts +1 -1
  51. package/dist/components/center.js +1 -1
  52. package/dist/components/center.js.map +1 -1
  53. package/dist/components/chart.js +4 -4
  54. package/dist/components/chart.js.map +1 -1
  55. package/dist/components/checkbox.d.ts +14 -4
  56. package/dist/components/checkbox.js +1 -1
  57. package/dist/components/checkbox.js.map +1 -1
  58. package/dist/components/code.js +1 -1
  59. package/dist/components/code.js.map +1 -1
  60. package/dist/components/collapsible.d.ts +8 -7
  61. package/dist/components/collapsible.js +1 -1
  62. package/dist/components/collapsible.js.map +1 -1
  63. package/dist/components/combobox.d.ts +48 -26
  64. package/dist/components/combobox.js +1 -1
  65. package/dist/components/combobox.js.map +1 -1
  66. package/dist/components/command.d.ts +16 -2
  67. package/dist/components/command.js +1 -1
  68. package/dist/components/command.js.map +1 -1
  69. package/dist/components/container.d.ts +1 -1
  70. package/dist/components/container.js +1 -1
  71. package/dist/components/container.js.map +1 -1
  72. package/dist/components/data-table.d.ts +177 -2
  73. package/dist/components/data-table.js +1 -1
  74. package/dist/components/data-table.js.map +1 -1
  75. package/dist/components/date-range-picker.d.ts +24 -2
  76. package/dist/components/date-range-picker.js +1 -1
  77. package/dist/components/date-range-picker.js.map +1 -1
  78. package/dist/components/dialog.d.ts +33 -15
  79. package/dist/components/dialog.js +1 -1
  80. package/dist/components/dialog.js.map +1 -1
  81. package/dist/components/direction.d.ts +7 -0
  82. package/dist/components/direction.js +1 -0
  83. package/dist/components/donut-chart.d.ts +12 -0
  84. package/dist/components/donut-chart.js +1 -1
  85. package/dist/components/donut-chart.js.map +1 -1
  86. package/dist/components/drawer.d.ts +33 -15
  87. package/dist/components/drawer.js +1 -1
  88. package/dist/components/drawer.js.map +1 -1
  89. package/dist/components/dropdown-menu.d.ts +36 -26
  90. package/dist/components/dropdown-menu.js +1 -1
  91. package/dist/components/dropdown-menu.js.map +1 -1
  92. package/dist/components/dropzone.d.ts +19 -0
  93. package/dist/components/dropzone.js +1 -1
  94. package/dist/components/dropzone.js.map +1 -1
  95. package/dist/components/empty.js +1 -1
  96. package/dist/components/empty.js.map +1 -1
  97. package/dist/components/field.d.ts +16 -4
  98. package/dist/components/field.js +1 -1
  99. package/dist/components/field.js.map +1 -1
  100. package/dist/components/flex.d.ts +1 -1
  101. package/dist/components/flex.js +1 -1
  102. package/dist/components/flex.js.map +1 -1
  103. package/dist/components/grid.d.ts +13 -0
  104. package/dist/components/grid.js +1 -1
  105. package/dist/components/grid.js.map +1 -1
  106. package/dist/components/group.d.ts +1 -1
  107. package/dist/components/group.js +1 -1
  108. package/dist/components/group.js.map +1 -1
  109. package/dist/components/heading.d.ts +3 -5
  110. package/dist/components/heading.js +1 -1
  111. package/dist/components/heading.js.map +1 -1
  112. package/dist/components/hover-card.d.ts +7 -6
  113. package/dist/components/hover-card.js +1 -1
  114. package/dist/components/hover-card.js.map +1 -1
  115. package/dist/components/input-group.d.ts +2 -2
  116. package/dist/components/input-group.js +1 -1
  117. package/dist/components/input-group.js.map +1 -1
  118. package/dist/components/input-otp.d.ts +4 -2
  119. package/dist/components/input-otp.js +1 -1
  120. package/dist/components/input-otp.js.map +1 -1
  121. package/dist/components/input.d.ts +1 -1
  122. package/dist/components/input.js +1 -1
  123. package/dist/components/input.js.map +1 -1
  124. package/dist/components/kbd.js +1 -1
  125. package/dist/components/kbd.js.map +1 -1
  126. package/dist/components/label.d.ts +3 -4
  127. package/dist/components/label.js +1 -1
  128. package/dist/components/label.js.map +1 -1
  129. package/dist/components/list.d.ts +8 -5
  130. package/dist/components/list.js +1 -1
  131. package/dist/components/list.js.map +1 -1
  132. package/dist/components/logo.d.ts +113 -0
  133. package/dist/components/logo.js +1 -1
  134. package/dist/components/marker.d.ts +4 -5
  135. package/dist/components/marker.js +1 -1
  136. package/dist/components/marker.js.map +1 -1
  137. package/dist/components/mask-input.d.ts +6 -0
  138. package/dist/components/mask-input.js +1 -1
  139. package/dist/components/mask-input.js.map +1 -1
  140. package/dist/components/native-select.d.ts +5 -1
  141. package/dist/components/native-select.js +1 -1
  142. package/dist/components/native-select.js.map +1 -1
  143. package/dist/components/navigation-menu.d.ts +19 -20
  144. package/dist/components/navigation-menu.js +1 -1
  145. package/dist/components/navigation-menu.js.map +1 -1
  146. package/dist/components/number-field.d.ts +18 -13
  147. package/dist/components/number-field.js +1 -1
  148. package/dist/components/number-field.js.map +1 -1
  149. package/dist/components/pagination.d.ts +9 -0
  150. package/dist/components/pagination.js +1 -1
  151. package/dist/components/pagination.js.map +1 -1
  152. package/dist/components/phone-input.d.ts +6 -0
  153. package/dist/components/phone-input.js +1 -1
  154. package/dist/components/phone-input.js.map +1 -1
  155. package/dist/components/pie-chart.d.ts +53 -0
  156. package/dist/components/pie-chart.js +1 -1
  157. package/dist/components/pie-chart.js.map +1 -1
  158. package/dist/components/popover.d.ts +13 -12
  159. package/dist/components/popover.js +1 -1
  160. package/dist/components/popover.js.map +1 -1
  161. package/dist/components/progress.d.ts +9 -3
  162. package/dist/components/progress.js +1 -1
  163. package/dist/components/progress.js.map +1 -1
  164. package/dist/components/radio-group.d.ts +20 -6
  165. package/dist/components/radio-group.js +1 -1
  166. package/dist/components/radio-group.js.map +1 -1
  167. package/dist/components/resizable.d.ts +1 -0
  168. package/dist/components/resizable.js +1 -1
  169. package/dist/components/resizable.js.map +1 -1
  170. package/dist/components/ring-progress.d.ts +9 -1
  171. package/dist/components/ring-progress.js +1 -1
  172. package/dist/components/ring-progress.js.map +1 -1
  173. package/dist/components/scroll-area.d.ts +3 -3
  174. package/dist/components/scroll-area.js +1 -1
  175. package/dist/components/scroll-area.js.map +1 -1
  176. package/dist/components/select.d.ts +25 -20
  177. package/dist/components/select.js +1 -1
  178. package/dist/components/select.js.map +1 -1
  179. package/dist/components/separator.d.ts +9 -4
  180. package/dist/components/separator.js +1 -1
  181. package/dist/components/separator.js.map +1 -1
  182. package/dist/components/sidebar.d.ts +63 -18
  183. package/dist/components/sidebar.js +1 -1
  184. package/dist/components/sidebar.js.map +1 -1
  185. package/dist/components/simple-grid.d.ts +7 -0
  186. package/dist/components/simple-grid.js +1 -1
  187. package/dist/components/simple-grid.js.map +1 -1
  188. package/dist/components/skeleton.d.ts +4 -0
  189. package/dist/components/skeleton.js +1 -1
  190. package/dist/components/skeleton.js.map +1 -1
  191. package/dist/components/slider.d.ts +2 -2
  192. package/dist/components/slider.js +1 -1
  193. package/dist/components/slider.js.map +1 -1
  194. package/dist/components/sonner.js +1 -1
  195. package/dist/components/sonner.js.map +1 -1
  196. package/dist/components/spinner.d.ts +1 -1
  197. package/dist/components/spinner.js +1 -1
  198. package/dist/components/spinner.js.map +1 -1
  199. package/dist/components/stack.d.ts +1 -1
  200. package/dist/components/stack.js +1 -1
  201. package/dist/components/stack.js.map +1 -1
  202. package/dist/components/stepper.d.ts +46 -25
  203. package/dist/components/stepper.js +1 -1
  204. package/dist/components/stepper.js.map +1 -1
  205. package/dist/components/switch.d.ts +17 -3
  206. package/dist/components/switch.js +1 -1
  207. package/dist/components/switch.js.map +1 -1
  208. package/dist/components/table.d.ts +10 -1
  209. package/dist/components/table.js +1 -1
  210. package/dist/components/table.js.map +1 -1
  211. package/dist/components/tabs.d.ts +14 -10
  212. package/dist/components/tabs.js +1 -1
  213. package/dist/components/tabs.js.map +1 -1
  214. package/dist/components/text.d.ts +3 -5
  215. package/dist/components/text.js +1 -1
  216. package/dist/components/text.js.map +1 -1
  217. package/dist/components/textarea.d.ts +1 -1
  218. package/dist/components/textarea.js +1 -1
  219. package/dist/components/textarea.js.map +1 -1
  220. package/dist/components/theme.d.ts +12 -0
  221. package/dist/components/theme.js +1 -1
  222. package/dist/components/theme.js.map +1 -1
  223. package/dist/components/timeline.d.ts +25 -1
  224. package/dist/components/timeline.js +1 -1
  225. package/dist/components/timeline.js.map +1 -1
  226. package/dist/components/toggle-group.d.ts +16 -6
  227. package/dist/components/toggle-group.js +1 -1
  228. package/dist/components/toggle-group.js.map +1 -1
  229. package/dist/components/toggle.d.ts +4 -4
  230. package/dist/components/toggle.js +1 -1
  231. package/dist/components/toggle.js.map +1 -1
  232. package/dist/components/tooltip.d.ts +15 -8
  233. package/dist/components/tooltip.js +1 -1
  234. package/dist/components/tooltip.js.map +1 -1
  235. package/dist/components/unstyled-button.d.ts +3 -5
  236. package/dist/components/unstyled-button.js +1 -1
  237. package/dist/components/unstyled-button.js.map +1 -1
  238. package/dist/components/visibility.d.ts +2 -0
  239. package/dist/components/visibility.js +1 -1
  240. package/dist/components/visibility.js.map +1 -1
  241. package/dist/hooks/use-breakpoint-value.d.ts +1 -0
  242. package/dist/hooks/use-breakpoint-value.js.map +1 -1
  243. package/dist/hooks/use-breakpoint.d.ts +1 -0
  244. package/dist/hooks/use-breakpoint.js.map +1 -1
  245. package/dist/hooks/use-disclosure.d.ts +3 -0
  246. package/dist/hooks/use-disclosure.js +1 -1
  247. package/dist/hooks/use-disclosure.js.map +1 -1
  248. package/dist/hooks/use-document-visibility.d.ts +1 -0
  249. package/dist/hooks/use-document-visibility.js.map +1 -1
  250. package/dist/hooks/use-hotkeys.d.ts +1 -1
  251. package/dist/hooks/use-hotkeys.js +1 -1
  252. package/dist/hooks/use-idle.d.ts +9 -0
  253. package/dist/hooks/use-idle.js.map +1 -1
  254. package/dist/hooks/use-interval.d.ts +1 -0
  255. package/dist/hooks/use-interval.js.map +1 -1
  256. package/dist/hooks/use-local-storage.d.ts +6 -0
  257. package/dist/hooks/use-local-storage.js +1 -1
  258. package/dist/hooks/use-local-storage.js.map +1 -1
  259. package/dist/hooks/use-mask.d.ts +1 -0
  260. package/dist/hooks/use-mask.js.map +1 -1
  261. package/dist/hooks/use-mobile.d.ts +1 -0
  262. package/dist/hooks/use-mobile.js.map +1 -1
  263. package/dist/index.d.ts +9 -7
  264. package/dist/index.js +1 -1
  265. package/dist/lib/as-child.d.ts +2 -0
  266. package/dist/lib/as-child.js +2 -0
  267. package/dist/lib/as-child.js.map +1 -0
  268. package/dist/lib/badge.js.map +1 -1
  269. package/dist/lib/button.js.map +1 -1
  270. package/dist/lib/color.js.map +1 -1
  271. package/dist/lib/compose-refs.js +1 -1
  272. package/dist/lib/compose-refs.js.map +1 -1
  273. package/dist/lib/progress.js.map +1 -1
  274. package/dist/lib/utils.d.ts +1 -1
  275. package/dist/lib/utils.js.map +1 -1
  276. package/dist/logo--R3_XDgA.js +2 -0
  277. package/dist/logo--R3_XDgA.js.map +1 -0
  278. package/dist/postcss.config.js.map +1 -1
  279. package/dist/resolve-class-name-BurP8ngI.js +2 -0
  280. package/dist/resolve-class-name-BurP8ngI.js.map +1 -0
  281. package/dist/skills/uselets-ui/SKILL.md +9 -3
  282. package/dist/skills/uselets-ui/references/component-catalog.md +31 -16
  283. package/dist/skills/uselets-ui/references/migration-v1-to-v2.md +599 -0
  284. package/dist/skills/uselets-ui/references/package-guide.md +23 -7
  285. package/dist/styles/base.css +21 -0
  286. package/dist/{use-hotkeys-DOjcX9Tt.d.ts → use-hotkeys-D1_TEIwN.d.ts} +2 -1
  287. package/dist/use-hotkeys-YDJmGWX6.js.map +1 -1
  288. package/package.json +18 -19
  289. package/skills/uselets-ui/SKILL.md +9 -3
  290. package/skills/uselets-ui/references/component-catalog.md +31 -16
  291. package/skills/uselets-ui/references/migration-v1-to-v2.md +599 -0
  292. package/skills/uselets-ui/references/package-guide.md +23 -7
  293. package/dist/data-table-DWWVGWbU.d.ts +0 -4184
  294. package/dist/logo-B0thHtTS.js +0 -2
  295. package/dist/logo-B0thHtTS.js.map +0 -1
@@ -21,8 +21,8 @@ If the package is not installed yet, use the bundled references as a snapshot an
21
21
 
22
22
  ## Requirements
23
23
 
24
- - React `>=19`
25
- - React DOM `>=19`
24
+ - React `^19.2`
25
+ - React DOM `^19.2`
26
26
  - Tailwind CSS 4
27
27
 
28
28
  ## Installation
@@ -121,6 +121,22 @@ If the app needs Tailwind v4 PostCSS setup, reuse the package preset:
121
121
  export { default } from '@uselets/ui/postcss.config'
122
122
  ```
123
123
 
124
+ Vite apps may use `@tailwindcss/vite` instead of PostCSS (use one integration, never both):
125
+
126
+ - Install `tailwindcss` and `@tailwindcss/vite`; register `tailwindcss()` in `plugins` of `vite.config.ts`; do not create `postcss.config.mjs`.
127
+ - Prefer `@tailwindcss/vite` when the project uses isolated installs (pnpm, Bun workspaces). With `@tailwindcss/postcss` under Vite plus isolated installs, the build fails with `Can't resolve 'tailwind-scrollbar'` because the theme's `@plugin` is resolved from the app's stylesheet. Fix by switching to `@tailwindcss/vite` (or adding `tailwind-scrollbar` to the app's dependencies).
128
+ - Non-Vite bundlers (for example Next.js) keep `@tailwindcss/postcss` with `@uselets/ui/postcss.config`.
129
+
130
+ ```ts
131
+ // vite.config.ts
132
+ import tailwindcss from '@tailwindcss/vite'
133
+ import { defineConfig } from 'vite'
134
+
135
+ export default defineConfig({
136
+ plugins: [tailwindcss()]
137
+ })
138
+ ```
139
+
124
140
  When the app uses installed `@uselets/ui` components, add a Tailwind source directive so component classes from the package are generated:
125
141
 
126
142
  ```css
@@ -218,7 +234,7 @@ Examples:
218
234
  import { Tooltip, TooltipProvider } from '@uselets/ui/tooltip'
219
235
 
220
236
  export function AppRoot({ children }: { children: React.ReactNode }) {
221
- return <TooltipProvider delayDuration={200}>{children}</TooltipProvider>
237
+ return <TooltipProvider delay={200}>{children}</TooltipProvider>
222
238
  }
223
239
 
224
240
  export function SaveButton() {
@@ -302,13 +318,13 @@ Additional tokens:
302
318
 
303
319
  The `Button` component can apply those palette families directly through `color: UIColor`, with `primary` as the default. Its public variants are `solid`, `secondary`, `outline`, `subtle`, `ghost`, and `link`, with `solid` as the default. Its public sizes are `xs`, `sm`, `md`, `lg`, `xl`, `icon-xs`, `icon-sm`, `icon`, `icon-lg`, and `icon-xl`; `loading` shows a centered spinner, keeps native button content invisible to preserve size, and disables the button without dimming it.
304
320
 
305
- The `Checkbox` component can be used as a bare checkbox or with `label?: React.ReactNode`. It supports `size: 'sm' | 'md' | 'lg'` and `color: UIColor`, with `primary` as the default color. When `label` is provided, it composes the package `Label`, accepts `labelProps` for that label, and generates an accessible `id`/`htmlFor` pair when no `id` prop is passed. Composed label text follows checkbox size: `sm` 12px, `md` 14px, and `lg` 20px.
321
+ The `Checkbox` component can be used as a bare checkbox or with `label?: React.ReactNode`. It supports `size: 'sm' | 'md' | 'lg'` and `color: UIColor`, with `primary` as the default color. When `label` is provided, it composes the package `Label`, accepts `labelProps` for that label, and generates an accessible `id`/`htmlFor` pair when no `id` prop is passed. Composed label text follows checkbox size: `sm` 12px, `md` 14px, and `lg` 18px. Pass `description?: React.ReactNode` (and `descriptionProps`) to render muted helper text (a `<p>`) below the label, linked to the control via `aria-describedby`; description text is `sm` 12px, `md` 12px, `lg` 14px.
306
322
 
307
- The `Switch` component can be used as a bare switch or with `label?: React.ReactNode`. It supports `size: 'sm' | 'md' | 'lg'` and `color: UIColor`, with `green` as the default color. The `color` prop controls only the checked track and indicator color; unchecked remains neutral. Track size is `sm` 34x16px, `md` 42x20px, and `lg` 48x22px. The thumb and its internal indicator scale with the selected size. Composed label text follows switch size: `sm` 12px, `md` 14px, and `lg` 20px.
323
+ The `Switch` component can be used as a bare switch or with `label?: React.ReactNode`. It supports `size: 'sm' | 'md' | 'lg'` and `color: UIColor`, with `green` as the default color. The `color` prop controls only the checked track and indicator color; unchecked remains neutral. Track size is `sm` 30x14px, `md` 34x16px, and `lg` 42x20px (control heights match `Checkbox`). The thumb and its internal indicator scale with the selected size. Composed label text follows switch size: `sm` 12px, `md` 14px, and `lg` 18px. `description?: React.ReactNode` (and `descriptionProps`) works the same as on `Checkbox`.
308
324
 
309
325
  The `TabsList` component supports `variant: 'line' | 'enclosed'`, with `line` as the default, and `grow?: boolean` for equal-width horizontal tabs. The `line` variant keeps a neutral border line across tabs and uses the `primary` color for the active indicator; use `enclosed` for the filled container treatment.
310
326
 
311
- The `RadioGroup` component supports `color: UIColor`, with `primary` as the default group color. `RadioGroupItem` can be used as a bare radio item inside `RadioGroup` or with `label?: React.ReactNode`; it supports `size: 'sm' | 'md' | 'lg'` and optional `color: UIColor` item overrides. Composed label text follows item size: `sm` 12px, `md` 14px, and `lg` 20px.
327
+ The `RadioGroup` component supports `color: UIColor`, with `primary` as the default group color. `RadioGroupItem` can be used as a bare radio item inside `RadioGroup` or with `label?: React.ReactNode`; it supports `size: 'sm' | 'md' | 'lg'` and optional `color: UIColor` item overrides. Composed label text follows item size: `sm` 12px, `md` 14px, and `lg` 18px. `description?: React.ReactNode` (and `descriptionProps`) works the same as on `Checkbox`.
312
328
 
313
329
  The `DateRangePicker` component is a compound popover date range picker built on `Calendar` range mode. Use `DateRange | null` for controlled values; applying an empty draft or resetting emits `null` through `onValueChange`. Fixed presets, relative-day inputs, date inputs, and the calendar all edit the same draft, and `DateRangePickerPreset` displays a selected state when its range matches the current draft by calendar day.
314
330
 
@@ -349,7 +365,7 @@ import { Table, TableContainer } from '@uselets/ui/table'
349
365
  </DataTableRoot>
350
366
  ```
351
367
 
352
- `DataTableRoot` accepts either `{ columns, data, ...options }` (uncontrolled — creates the `table` instance internally) or `{ table }` (controlled — table instance comes from `useDataTable` called by the consumer). Use the controlled form whenever you need access to the `table` instance in the same scope as the JSX (e.g. for virtualization or external action buttons).
368
+ `DataTableRoot` accepts either `{ columns, data, ...options }` (uncontrolled — creates the `table` instance internally) or `{ table }` (controlled — table instance comes from `useDataTable` called by the consumer). In the uncontrolled form, pagination is on while a `<DataTablePagination />` is rendered inside the root and off otherwise (all rows); an explicit `enablePagination` overrides that. In the controlled form, `useDataTable` defaults to `enablePagination: false` — pass `true` when rendering `<DataTablePagination />`. Use the controlled form whenever you need access to the `table` instance in the same scope as the JSX (e.g. for virtualization or external action buttons).
353
369
 
354
370
  ### Virtualized lists (bring your own virtualizer)
355
371