@happyvertical/smrt-svelte 0.53.1 → 0.53.2

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 (254) hide show
  1. package/package.json +15 -15
  2. package/dist/__tests__/app-state.test.js +0 -156
  3. package/dist/__tests__/data-surface-bridge.test.js +0 -351
  4. package/dist/__tests__/provider-mode-harness.svelte +0 -14
  5. package/dist/__tests__/provider-mode-harness.svelte.d.ts +0 -11
  6. package/dist/__tests__/provider-mode-harness.svelte.d.ts.map +0 -1
  7. package/dist/__tests__/provider-mode-probe.svelte +0 -13
  8. package/dist/__tests__/provider-mode-probe.svelte.d.ts +0 -8
  9. package/dist/__tests__/provider-mode-probe.svelte.d.ts.map +0 -1
  10. package/dist/__tests__/provider-webmcp-harness.svelte +0 -14
  11. package/dist/__tests__/provider-webmcp-harness.svelte.d.ts +0 -8
  12. package/dist/__tests__/provider-webmcp-harness.svelte.d.ts.map +0 -1
  13. package/dist/__tests__/success-never-text.test.js +0 -100
  14. package/dist/__tests__/warm-clients.test.js +0 -186
  15. package/dist/browser-ai/adapters/llm/bitgpu-inference-backend.test.js +0 -464
  16. package/dist/browser-ai/adapters/llm/webllm-inference-backend.test.js +0 -646
  17. package/dist/browser-ai/adapters/stt/browser-speech.test.js +0 -113
  18. package/dist/browser-ai/adapters/stt/dictation-source.test.js +0 -52
  19. package/dist/browser-ai/svelte/components/__tests__/ModelStatusControl.test.js +0 -172
  20. package/dist/components/board/__tests__/Board.test.js +0 -498
  21. package/dist/components/board/__tests__/BoardSsrHarness.svelte +0 -30
  22. package/dist/components/board/__tests__/BoardSsrHarness.svelte.d.ts +0 -19
  23. package/dist/components/board/__tests__/BoardSsrHarness.svelte.d.ts.map +0 -1
  24. package/dist/components/forms/__tests__/AddressInput.behavior.test.js +0 -216
  25. package/dist/components/forms/__tests__/CheckboxInput.test.js +0 -92
  26. package/dist/components/forms/__tests__/DateRangeInput.behavior.test.js +0 -135
  27. package/dist/components/forms/__tests__/DateTimeInput.behavior.test.js +0 -113
  28. package/dist/components/forms/__tests__/FileUpload.error-alert.test.js +0 -37
  29. package/dist/components/forms/__tests__/FileUpload.native-form.test.js +0 -249
  30. package/dist/components/forms/__tests__/FileUpload.test.js +0 -90
  31. package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte +0 -24
  32. package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte.d.ts +0 -10
  33. package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte.d.ts.map +0 -1
  34. package/dist/components/forms/__tests__/Form.behavior.test.js +0 -137
  35. package/dist/components/forms/__tests__/Form.extraction.test.js +0 -68
  36. package/dist/components/forms/__tests__/Form.stt-error.test.js +0 -57
  37. package/dist/components/forms/__tests__/Form.test.js +0 -86
  38. package/dist/components/forms/__tests__/Form.ui-controls.test.js +0 -119
  39. package/dist/components/forms/__tests__/Form.webmcp.test.js +0 -2336
  40. package/dist/components/forms/__tests__/FormMicButton.test.js +0 -92
  41. package/dist/components/forms/__tests__/FormScope.test.js +0 -39
  42. package/dist/components/forms/__tests__/MeasurementInput.behavior.test.js +0 -129
  43. package/dist/components/forms/__tests__/MoneyInput.behavior.test.js +0 -124
  44. package/dist/components/forms/__tests__/NumberInput.behavior.test.js +0 -151
  45. package/dist/components/forms/__tests__/PhoneInput.behavior.test.js +0 -96
  46. package/dist/components/forms/__tests__/SearchInput.test.js +0 -79
  47. package/dist/components/forms/__tests__/SelectInput.behavior.test.js +0 -132
  48. package/dist/components/forms/__tests__/TextInput.behavior.test.js +0 -131
  49. package/dist/components/forms/__tests__/TextareaInput.behavior.test.js +0 -96
  50. package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte +0 -30
  51. package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte.d.ts +0 -7
  52. package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte.d.ts.map +0 -1
  53. package/dist/components/forms/__tests__/async-validation-form.fixture.svelte +0 -19
  54. package/dist/components/forms/__tests__/async-validation-form.fixture.svelte.d.ts +0 -9
  55. package/dist/components/forms/__tests__/async-validation-form.fixture.svelte.d.ts.map +0 -1
  56. package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte +0 -21
  57. package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte.d.ts +0 -8
  58. package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte.d.ts.map +0 -1
  59. package/dist/components/forms/__tests__/composite-inputs-a11y.test.js +0 -69
  60. package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte +0 -27
  61. package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte.d.ts +0 -9
  62. package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte.d.ts.map +0 -1
  63. package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte +0 -48
  64. package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte.d.ts +0 -10
  65. package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte.d.ts.map +0 -1
  66. package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte +0 -26
  67. package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte.d.ts +0 -13
  68. package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte.d.ts.map +0 -1
  69. package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte +0 -52
  70. package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte.d.ts +0 -16
  71. package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte.d.ts.map +0 -1
  72. package/dist/components/forms/__tests__/form-scope.fixture.svelte +0 -30
  73. package/dist/components/forms/__tests__/form-scope.fixture.svelte.d.ts +0 -10
  74. package/dist/components/forms/__tests__/form-scope.fixture.svelte.d.ts.map +0 -1
  75. package/dist/components/forms/__tests__/form-with-fields.fixture.svelte +0 -158
  76. package/dist/components/forms/__tests__/form-with-fields.fixture.svelte.d.ts +0 -51
  77. package/dist/components/forms/__tests__/form-with-fields.fixture.svelte.d.ts.map +0 -1
  78. package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte +0 -24
  79. package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte.d.ts +0 -11
  80. package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte.d.ts.map +0 -1
  81. package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte +0 -105
  82. package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte.d.ts +0 -42
  83. package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte.d.ts.map +0 -1
  84. package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte +0 -84
  85. package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte.d.ts +0 -14
  86. package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte.d.ts.map +0 -1
  87. package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte +0 -44
  88. package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte.d.ts +0 -9
  89. package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte.d.ts.map +0 -1
  90. package/dist/components/forms/__tests__/mic-keyboard-a11y.test.js +0 -74
  91. package/dist/components/forms/__tests__/policy-field.fixture.svelte +0 -35
  92. package/dist/components/forms/__tests__/policy-field.fixture.svelte.d.ts +0 -8
  93. package/dist/components/forms/__tests__/policy-field.fixture.svelte.d.ts.map +0 -1
  94. package/dist/components/forms/__tests__/rich-inputs-a11y.test.js +0 -87
  95. package/dist/components/settings/__tests__/SettingsCatalog.test.js +0 -69
  96. package/dist/components/settings/__tests__/catalog.test.js +0 -46
  97. package/dist/components/workspace/__tests__/AdminShell.responsive.test.js +0 -597
  98. package/dist/components/workspace/__tests__/AdminShell.test.js +0 -572
  99. package/dist/components/workspace/__tests__/RoleShell.test.js +0 -772
  100. package/dist/components/workspace/__tests__/TenantNav.test.js +0 -208
  101. package/dist/components/workspace/__tests__/WorkspaceAccountMenu.test.js +0 -79
  102. package/dist/components/workspace/__tests__/WorkspaceShell.test.js +0 -630
  103. package/dist/components/workspace/__tests__/admin-shell-header-overflow.test.js +0 -25
  104. package/dist/components/workspace/__tests__/admin-shell-hotkeys.test.js +0 -34
  105. package/dist/components/workspace/__tests__/admin-shell-mobile.test.js +0 -217
  106. package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte +0 -52
  107. package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte.d.ts +0 -23
  108. package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte.d.ts.map +0 -1
  109. package/dist/components/workspace/__tests__/admin-shell-page-contracts.test.js +0 -30
  110. package/dist/components/workspace/__tests__/admin-shell-responsive-state.test.js +0 -184
  111. package/dist/components/workspace/__tests__/admin-shell-settings.test.js +0 -25
  112. package/dist/components/workspace/__tests__/admin-shell-state.test.js +0 -286
  113. package/dist/components/workspace/__tests__/admin-shell-theme-hooks.test.js +0 -36
  114. package/dist/components/workspace/__tests__/breadcrumbs-helpers.test.js +0 -141
  115. package/dist/components/workspace/__tests__/context-forwarding-harness.svelte +0 -45
  116. package/dist/components/workspace/__tests__/context-forwarding-harness.svelte.d.ts +0 -21
  117. package/dist/components/workspace/__tests__/context-forwarding-harness.svelte.d.ts.map +0 -1
  118. package/dist/components/workspace/__tests__/define-tools-dock.test.js +0 -1188
  119. package/dist/components/workspace/__tests__/harness.svelte +0 -25
  120. package/dist/components/workspace/__tests__/harness.svelte.d.ts +0 -14
  121. package/dist/components/workspace/__tests__/harness.svelte.d.ts.map +0 -1
  122. package/dist/components/workspace/__tests__/index.test.js +0 -28
  123. package/dist/components/workspace/__tests__/legacy-index.test.js +0 -9
  124. package/dist/components/workspace/__tests__/manifest-nav-helpers.test.js +0 -24
  125. package/dist/components/workspace/__tests__/manifest-nav.test.js +0 -599
  126. package/dist/components/workspace/__tests__/nav-helpers.test.js +0 -95
  127. package/dist/components/workspace/__tests__/render-harness.svelte +0 -66
  128. package/dist/components/workspace/__tests__/render-harness.svelte.d.ts +0 -32
  129. package/dist/components/workspace/__tests__/render-harness.svelte.d.ts.map +0 -1
  130. package/dist/components/workspace/__tests__/render-tools-dock.test.js +0 -260
  131. package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte +0 -58
  132. package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte.d.ts +0 -16
  133. package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte.d.ts.map +0 -1
  134. package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte +0 -41
  135. package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte.d.ts +0 -13
  136. package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte.d.ts.map +0 -1
  137. package/dist/components/workspace/__tests__/shell-chrome-components.test.js +0 -108
  138. package/dist/components/workspace/__tests__/system-feed.test.js +0 -327
  139. package/dist/components/workspace/__tests__/test-icon.svelte +0 -17
  140. package/dist/components/workspace/__tests__/test-icon.svelte.d.ts +0 -19
  141. package/dist/components/workspace/__tests__/test-icon.svelte.d.ts.map +0 -1
  142. package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte +0 -38
  143. package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte.d.ts +0 -22
  144. package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte.d.ts.map +0 -1
  145. package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.d.ts +0 -66
  146. package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.d.ts.map +0 -1
  147. package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.js +0 -115
  148. package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.d.ts +0 -15
  149. package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.d.ts.map +0 -1
  150. package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.js +0 -7
  151. package/dist/components/workspace/__tests__/typed-tool-fixture.test.js +0 -115
  152. package/dist/components/workspace/__tests__/use-harness-orphan.svelte +0 -9
  153. package/dist/components/workspace/__tests__/use-harness-orphan.svelte.d.ts +0 -19
  154. package/dist/components/workspace/__tests__/use-harness-orphan.svelte.d.ts.map +0 -1
  155. package/dist/components/workspace/__tests__/use-harness.svelte +0 -23
  156. package/dist/components/workspace/__tests__/use-harness.svelte.d.ts +0 -8
  157. package/dist/components/workspace/__tests__/use-harness.svelte.d.ts.map +0 -1
  158. package/dist/components/workspace/__tests__/use-tools-dock.test.js +0 -33
  159. package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte +0 -43
  160. package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte.d.ts +0 -11
  161. package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte.d.ts.map +0 -1
  162. package/dist/components/workspace/server/__tests__/compose-availability.test.js +0 -383
  163. package/dist/components/workspace/server/__tests__/typed-context-fixture.d.ts +0 -78
  164. package/dist/components/workspace/server/__tests__/typed-context-fixture.d.ts.map +0 -1
  165. package/dist/components/workspace/server/__tests__/typed-context-fixture.js +0 -104
  166. package/dist/hooks/__tests__/stt-consumer.fixture.svelte +0 -25
  167. package/dist/hooks/__tests__/stt-consumer.fixture.svelte.d.ts +0 -15
  168. package/dist/hooks/__tests__/stt-consumer.fixture.svelte.d.ts.map +0 -1
  169. package/dist/hooks/__tests__/stt-ownership-harness.svelte +0 -42
  170. package/dist/hooks/__tests__/stt-ownership-harness.svelte.d.ts +0 -20
  171. package/dist/hooks/__tests__/stt-ownership-harness.svelte.d.ts.map +0 -1
  172. package/dist/hooks/__tests__/useSTT-ownership.test.js +0 -102
  173. package/dist/i18n/__tests__/server.spec.js +0 -57
  174. package/dist/internal/logger.test.js +0 -54
  175. package/dist/provider-mode.test.js +0 -86
  176. package/dist/provider-webmcp.test.js +0 -244
  177. package/dist/state/__tests__/app-state-ai-lifecycle.test.js +0 -240
  178. package/dist/state/__tests__/warm-clients.test.js +0 -40
  179. package/dist/web/__tests__/activity-feed-harness.svelte +0 -32
  180. package/dist/web/__tests__/activity-feed-harness.svelte.d.ts +0 -18
  181. package/dist/web/__tests__/activity-feed-harness.svelte.d.ts.map +0 -1
  182. package/dist/web/__tests__/activity-feed.integration.svelte.test.js +0 -190
  183. package/dist/web/__tests__/activity-feed.svelte.test.js +0 -235
  184. package/dist/web/__tests__/assistant-dock.integration.svelte.test.js +0 -204
  185. package/dist/web/__tests__/data-surface-conformance.integration.svelte.test.js +0 -1392
  186. package/dist/web/__tests__/harness.svelte +0 -25
  187. package/dist/web/__tests__/harness.svelte.d.ts +0 -15
  188. package/dist/web/__tests__/harness.svelte.d.ts.map +0 -1
  189. package/dist/web/__tests__/list-data-surface.fixture.svelte +0 -59
  190. package/dist/web/__tests__/list-data-surface.fixture.svelte.d.ts +0 -14
  191. package/dist/web/__tests__/list-data-surface.fixture.svelte.d.ts.map +0 -1
  192. package/dist/web/__tests__/list-data-surface.svelte.test.js +0 -106
  193. package/dist/web/__tests__/list-data-surface.test.js +0 -651
  194. package/dist/web/__tests__/list-sort-surface.fixture.svelte +0 -41
  195. package/dist/web/__tests__/list-sort-surface.fixture.svelte.d.ts +0 -15
  196. package/dist/web/__tests__/list-sort-surface.fixture.svelte.d.ts.map +0 -1
  197. package/dist/web/__tests__/list-sort-surface.svelte.test.js +0 -59
  198. package/dist/web/__tests__/live-collection.svelte.test.js +0 -185
  199. package/dist/web/__tests__/provider-ui-registry.fixture.svelte +0 -43
  200. package/dist/web/__tests__/provider-ui-registry.fixture.svelte.d.ts +0 -13
  201. package/dist/web/__tests__/provider-ui-registry.fixture.svelte.d.ts.map +0 -1
  202. package/dist/web/__tests__/provider-ui-registry.test.js +0 -235
  203. package/dist/web/__tests__/remote-query-harness.svelte +0 -27
  204. package/dist/web/__tests__/remote-query-harness.svelte.d.ts +0 -11
  205. package/dist/web/__tests__/remote-query-harness.svelte.d.ts.map +0 -1
  206. package/dist/web/__tests__/remote-query.svelte.test.js +0 -101
  207. package/dist/web/__tests__/surfaces.child.fixture.svelte +0 -69
  208. package/dist/web/__tests__/surfaces.child.fixture.svelte.d.ts +0 -16
  209. package/dist/web/__tests__/surfaces.child.fixture.svelte.d.ts.map +0 -1
  210. package/dist/web/__tests__/surfaces.fixture.svelte +0 -26
  211. package/dist/web/__tests__/surfaces.fixture.svelte.d.ts +0 -18
  212. package/dist/web/__tests__/surfaces.fixture.svelte.d.ts.map +0 -1
  213. package/dist/web/__tests__/surfaces.svelte.test.js +0 -140
  214. package/dist/web/__tests__/update-available-harness.svelte +0 -46
  215. package/dist/web/__tests__/update-available-harness.svelte.d.ts +0 -22
  216. package/dist/web/__tests__/update-available-harness.svelte.d.ts.map +0 -1
  217. package/dist/web/__tests__/update-available.svelte.test.js +0 -137
  218. package/dist/web/__tests__/view-intent-provider.fixture.svelte +0 -28
  219. package/dist/web/__tests__/view-intent-provider.fixture.svelte.d.ts +0 -13
  220. package/dist/web/__tests__/view-intent-provider.fixture.svelte.d.ts.map +0 -1
  221. package/dist/web/__tests__/view-intent.fixture.svelte +0 -33
  222. package/dist/web/__tests__/view-intent.fixture.svelte.d.ts +0 -15
  223. package/dist/web/__tests__/view-intent.fixture.svelte.d.ts.map +0 -1
  224. package/dist/web/__tests__/view-intent.intents.d.ts +0 -14
  225. package/dist/web/__tests__/view-intent.intents.d.ts.map +0 -1
  226. package/dist/web/__tests__/view-intent.intents.js +0 -38
  227. package/dist/web/__tests__/view-intent.svelte.test.js +0 -244
  228. package/dist/web/__tests__/webmcp-composed.child.fixture.svelte +0 -73
  229. package/dist/web/__tests__/webmcp-composed.child.fixture.svelte.d.ts +0 -8
  230. package/dist/web/__tests__/webmcp-composed.child.fixture.svelte.d.ts.map +0 -1
  231. package/dist/web/__tests__/webmcp-composed.fixture.svelte +0 -52
  232. package/dist/web/__tests__/webmcp-composed.fixture.svelte.d.ts +0 -12
  233. package/dist/web/__tests__/webmcp-composed.fixture.svelte.d.ts.map +0 -1
  234. package/dist/web/__tests__/webmcp-composed.integration.svelte.test.js +0 -251
  235. package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte +0 -16
  236. package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte.d.ts +0 -19
  237. package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte.d.ts.map +0 -1
  238. package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte +0 -11
  239. package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte.d.ts +0 -8
  240. package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte.d.ts.map +0 -1
  241. package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte +0 -20
  242. package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte.d.ts +0 -7
  243. package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte.d.ts.map +0 -1
  244. package/dist/web/__tests__/webmcp-harness-unannotated.svelte +0 -14
  245. package/dist/web/__tests__/webmcp-harness-unannotated.svelte.d.ts +0 -19
  246. package/dist/web/__tests__/webmcp-harness-unannotated.svelte.d.ts.map +0 -1
  247. package/dist/web/__tests__/webmcp-harness.svelte +0 -18
  248. package/dist/web/__tests__/webmcp-harness.svelte.d.ts +0 -7
  249. package/dist/web/__tests__/webmcp-harness.svelte.d.ts.map +0 -1
  250. package/dist/web/__tests__/webmcp-ssr.fixture.svelte +0 -13
  251. package/dist/web/__tests__/webmcp-ssr.fixture.svelte.d.ts +0 -19
  252. package/dist/web/__tests__/webmcp-ssr.fixture.svelte.d.ts.map +0 -1
  253. package/dist/web/__tests__/webmcp-ui.test.js +0 -723
  254. package/dist/web/__tests__/webmcp.test.js +0 -234
@@ -1,498 +0,0 @@
1
- import { expectNoA11yViolations } from '@happyvertical/smrt-ui/test-support/a11y';
2
- import { svelte } from '@sveltejs/vite-plugin-svelte';
3
- import { fireEvent, render, screen, within } from '@testing-library/svelte';
4
- import userEvent from '@testing-library/user-event';
5
- import { createRawSnippet, hydrate, unmount } from 'svelte';
6
- import { createServer } from 'vite';
7
- import { describe, expect, it, vi } from 'vitest';
8
- import Board from '../Board.svelte';
9
- import BoardSsrHarness from './BoardSsrHarness.svelte';
10
- const columns = [
11
- { id: 'new', label: 'New' },
12
- { id: 'assigned', label: 'Assigned' },
13
- ];
14
- const initialCards = [
15
- { id: 'a', subject: 'Password reset', queue: 'new' },
16
- { id: 'b', subject: 'Billing question', queue: 'new' },
17
- { id: 'c', subject: 'Reply needed', queue: 'assigned' },
18
- ];
19
- function cardSnippet() {
20
- return createRawSnippet((context) => ({
21
- render: () => `<strong>${context().card.subject}</strong>`,
22
- }));
23
- }
24
- function props(overrides = {}) {
25
- return {
26
- columns,
27
- defaultCards: initialCards,
28
- getCardColumnId: (card) => card.queue,
29
- setCardColumnId: (card, queue) => ({ ...card, queue }),
30
- getCardLabel: (card) => card.subject,
31
- card: cardSnippet(),
32
- label: 'Support queues',
33
- ...overrides,
34
- };
35
- }
36
- function lane(name) {
37
- return screen.getByRole('region', { name: new RegExp(name) });
38
- }
39
- describe('Board', () => {
40
- it('moves generic support cards in uncontrolled mode with a typed keyboard intent', async () => {
41
- const user = userEvent.setup();
42
- const onmove = vi.fn();
43
- const onselect = vi.fn();
44
- render((Board), {
45
- props: props({ onmove, onselect }),
46
- });
47
- const card = screen.getByRole('button', { name: 'Password reset' });
48
- card.focus();
49
- await user.keyboard(' ');
50
- await user.keyboard('{ArrowRight}');
51
- await user.keyboard(' ');
52
- expect(onmove).toHaveBeenCalledWith(expect.objectContaining({
53
- card: initialCards[0],
54
- source: { columnId: 'new', index: 0 },
55
- target: { columnId: 'assigned', index: 0 },
56
- }));
57
- expect(within(lane('Assigned')).getByText('Password reset')).toBeInTheDocument();
58
- expect(screen.getByText('Moved Password reset to Assigned, position 1 of 2.')).toBeInTheDocument();
59
- await vi.waitFor(() => expect(screen.getByRole('button', { name: 'Password reset' })).toHaveFocus());
60
- expect(onselect).not.toHaveBeenCalled();
61
- });
62
- it('keeps controlled cards authoritative unless optimistic presentation is requested', async () => {
63
- const user = userEvent.setup();
64
- const onmove = vi.fn();
65
- render((Board), {
66
- props: props({ cards: initialCards, onmove }),
67
- });
68
- const card = screen.getByRole('button', { name: 'Password reset' });
69
- card.focus();
70
- await user.keyboard(' ');
71
- await user.keyboard('{ArrowRight}');
72
- await user.keyboard('{Enter}');
73
- expect(onmove).toHaveBeenCalledOnce();
74
- expect(within(lane('New')).getByText('Password reset')).toBeInTheDocument();
75
- expect(within(lane('Assigned')).queryByText('Password reset')).not.toBeInTheDocument();
76
- });
77
- it('treats a controlled board without onmove as read-only', async () => {
78
- const user = userEvent.setup();
79
- const onselect = vi.fn();
80
- render((Board), {
81
- props: props({ cards: initialCards, onselect }),
82
- });
83
- const card = screen.getByRole('button', { name: 'Password reset' });
84
- expect(card).toHaveAttribute('draggable', 'false');
85
- expect(card).not.toHaveAttribute('aria-disabled');
86
- expect(card).not.toHaveClass('smrt-board__card--touch-drag');
87
- card.focus();
88
- await user.keyboard(' ');
89
- expect(screen.queryByText(/Picked up Password reset/)).not.toBeInTheDocument();
90
- expect(onselect).toHaveBeenCalledWith(initialCards[0]);
91
- });
92
- it('updates precomputed lane cards when controlled cards change', async () => {
93
- const onmove = vi.fn();
94
- const { rerender } = render((Board), {
95
- props: props({ cards: initialCards, onmove }),
96
- });
97
- expect(lane('New')).toHaveAccessibleName('New, 2 cards');
98
- const updatedCards = [
99
- { ...initialCards[0], queue: 'assigned' },
100
- ...initialCards.slice(1),
101
- ];
102
- await rerender(props({ cards: updatedCards, onmove }));
103
- expect(lane('New')).toHaveAccessibleName('New, 1 cards');
104
- expect(lane('Assigned')).toHaveAccessibleName('Assigned, 2 cards');
105
- expect(within(lane('Assigned')).getByText('Password reset')).toBeInTheDocument();
106
- });
107
- it('can disable same-column reordering without suppressing cross-column moves', async () => {
108
- const user = userEvent.setup();
109
- const onmove = vi.fn();
110
- render((Board), {
111
- props: props({ allowSameColumnReorder: false, onmove }),
112
- });
113
- const card = screen.getByRole('button', { name: 'Password reset' });
114
- card.focus();
115
- await user.keyboard(' ');
116
- await user.keyboard('{ArrowDown}');
117
- await user.keyboard('{Enter}');
118
- expect(onmove).not.toHaveBeenCalled();
119
- expect(screen.queryByText(/Moved Password reset/)).not.toBeInTheDocument();
120
- expect(within(lane('New')).getAllByRole('button')[0]).toHaveAccessibleName('Password reset');
121
- card.focus();
122
- await user.keyboard(' ');
123
- await user.keyboard('{ArrowRight}');
124
- await user.keyboard('{Enter}');
125
- expect(onmove).toHaveBeenCalledWith(expect.objectContaining({ target: { columnId: 'assigned', index: 0 } }));
126
- });
127
- it('does not emit a pointer same-column move when reordering is disabled', () => {
128
- const onmove = vi.fn();
129
- render((Board), {
130
- props: props({ allowSameColumnReorder: false, onmove }),
131
- });
132
- const card = screen.getByRole('button', { name: 'Password reset' });
133
- const sibling = screen.getByRole('button', { name: 'Billing question' });
134
- fireEvent.dragStart(card, { dataTransfer: { setData: vi.fn() } });
135
- fireEvent.drop(sibling, { clientY: 1 });
136
- expect(onmove).not.toHaveBeenCalled();
137
- expect(screen.queryByText(/Moved Password reset/)).not.toBeInTheDocument();
138
- });
139
- it('uses native pointer drag and drop to emit a move', () => {
140
- const onmove = vi.fn();
141
- render((Board), { props: props({ onmove }) });
142
- const card = screen.getByRole('button', { name: 'Password reset' });
143
- const destination = screen.getByRole('button', { name: 'Reply needed' });
144
- fireEvent.dragStart(card, { dataTransfer: { setData: vi.fn() } });
145
- fireEvent.drop(destination, { clientY: 1 });
146
- expect(onmove).toHaveBeenCalledWith(expect.objectContaining({
147
- source: { columnId: 'new', index: 0 },
148
- target: { columnId: 'assigned', index: 1 },
149
- }));
150
- });
151
- it('moves a card with touch Pointer Events after a drag threshold', async () => {
152
- const onmove = vi.fn();
153
- render((Board), { props: props({ onmove }) });
154
- const card = screen.getByRole('button', { name: 'Password reset' });
155
- const destination = screen.getByRole('button', { name: 'Reply needed' });
156
- Object.defineProperty(destination, 'getBoundingClientRect', {
157
- value: () => ({ top: 10, height: 20 }),
158
- });
159
- const originalElementFromPoint = document.elementFromPoint;
160
- Object.defineProperty(document, 'elementFromPoint', {
161
- configurable: true,
162
- value: vi.fn(() => destination),
163
- });
164
- fireEvent.pointerDown(card, {
165
- button: 0,
166
- clientX: 0,
167
- clientY: 0,
168
- pointerId: 7,
169
- pointerType: 'touch',
170
- });
171
- fireEvent.pointerMove(card, {
172
- clientX: 10,
173
- clientY: 10,
174
- pointerId: 7,
175
- pointerType: 'touch',
176
- });
177
- fireEvent.pointerUp(card, {
178
- clientX: 10,
179
- clientY: 10,
180
- pointerId: 7,
181
- pointerType: 'touch',
182
- });
183
- expect(onmove).toHaveBeenCalledWith(expect.objectContaining({
184
- source: { columnId: 'new', index: 0 },
185
- target: { columnId: 'assigned', index: 0 },
186
- }));
187
- Object.defineProperty(document, 'elementFromPoint', {
188
- configurable: true,
189
- value: originalElementFromPoint,
190
- });
191
- });
192
- it('moves a card with mouse Pointer Events after a drag threshold', () => {
193
- const onmove = vi.fn();
194
- render((Board), { props: props({ onmove }) });
195
- const card = screen.getByRole('button', { name: 'Password reset' });
196
- const destination = screen.getByRole('button', { name: 'Reply needed' });
197
- Object.defineProperty(destination, 'getBoundingClientRect', {
198
- value: () => ({ top: 10, height: 20 }),
199
- });
200
- const originalElementFromPoint = document.elementFromPoint;
201
- Object.defineProperty(document, 'elementFromPoint', {
202
- configurable: true,
203
- value: vi.fn(() => destination),
204
- });
205
- fireEvent.pointerDown(card, {
206
- button: 0,
207
- clientX: 0,
208
- clientY: 0,
209
- pointerId: 9,
210
- pointerType: 'mouse',
211
- });
212
- fireEvent.pointerMove(card, {
213
- clientX: 10,
214
- clientY: 10,
215
- pointerId: 9,
216
- pointerType: 'mouse',
217
- });
218
- fireEvent.pointerUp(card, {
219
- clientX: 10,
220
- clientY: 10,
221
- pointerId: 9,
222
- pointerType: 'mouse',
223
- });
224
- expect(onmove).toHaveBeenCalledWith(expect.objectContaining({ target: { columnId: 'assigned', index: 0 } }));
225
- Object.defineProperty(document, 'elementFromPoint', {
226
- configurable: true,
227
- value: originalElementFromPoint,
228
- });
229
- });
230
- it('cancels a mouse Pointer Event drag and restores card focus', async () => {
231
- render((Board), { props: props() });
232
- const card = screen.getByRole('button', { name: 'Password reset' });
233
- fireEvent.pointerDown(card, {
234
- button: 0,
235
- clientX: 0,
236
- clientY: 0,
237
- pointerId: 8,
238
- pointerType: 'mouse',
239
- });
240
- fireEvent.pointerMove(card, {
241
- clientX: 8,
242
- clientY: 0,
243
- pointerId: 8,
244
- pointerType: 'mouse',
245
- });
246
- fireEvent.pointerCancel(card, { pointerId: 8, pointerType: 'mouse' });
247
- expect(screen.getByText('Cancelled moving Password reset.')).toBeInTheDocument();
248
- await vi.waitFor(() => expect(card).toHaveFocus());
249
- });
250
- it('cancels a pointer drag that is hit-tested over another Board with shared column ids', async () => {
251
- const firstMove = vi.fn();
252
- const secondMove = vi.fn();
253
- render((Board), {
254
- props: props({ onmove: firstMove }),
255
- });
256
- render((Board), {
257
- props: props({ onmove: secondMove }),
258
- });
259
- const boards = screen.getAllByRole('region', { name: 'Support queues' });
260
- const firstCard = within(boards[0]).getByRole('button', {
261
- name: 'Password reset',
262
- });
263
- const secondDestination = within(boards[1]).getByRole('button', {
264
- name: 'Reply needed',
265
- });
266
- const originalElementFromPoint = document.elementFromPoint;
267
- Object.defineProperty(document, 'elementFromPoint', {
268
- configurable: true,
269
- value: vi.fn(() => secondDestination),
270
- });
271
- fireEvent.pointerDown(firstCard, {
272
- button: 0,
273
- clientX: 0,
274
- clientY: 0,
275
- pointerId: 10,
276
- pointerType: 'mouse',
277
- });
278
- fireEvent.pointerMove(firstCard, {
279
- clientX: 10,
280
- clientY: 0,
281
- pointerId: 10,
282
- pointerType: 'mouse',
283
- });
284
- fireEvent.pointerUp(firstCard, {
285
- clientX: 10,
286
- clientY: 0,
287
- pointerId: 10,
288
- pointerType: 'mouse',
289
- });
290
- expect(firstMove).not.toHaveBeenCalled();
291
- expect(secondMove).not.toHaveBeenCalled();
292
- expect(within(boards[0]).getByText('Cancelled moving Password reset.')).toBeInTheDocument();
293
- await vi.waitFor(() => expect(firstCard).toHaveFocus());
294
- Object.defineProperty(document, 'elementFromPoint', {
295
- configurable: true,
296
- value: originalElementFromPoint,
297
- });
298
- });
299
- it('rejects a pointer drop into a disabled lane, announces it, and restores focus', async () => {
300
- const onmove = vi.fn();
301
- render((Board), {
302
- props: props({
303
- columns: [columns[0], { ...columns[1], disabled: true }],
304
- onmove,
305
- }),
306
- });
307
- const card = screen.getByRole('button', { name: 'Password reset' });
308
- const destination = screen.getByRole('button', { name: 'Reply needed' });
309
- fireEvent.dragStart(card, { dataTransfer: { setData: vi.fn() } });
310
- fireEvent.drop(destination, { clientY: 1 });
311
- expect(onmove).not.toHaveBeenCalled();
312
- expect(screen.getByText('Assigned is unavailable.')).toBeInTheDocument();
313
- await vi.waitFor(() => expect(card).toHaveFocus());
314
- });
315
- it('restores an optimistic controlled move when persistence rejects', async () => {
316
- const user = userEvent.setup();
317
- const onmove = vi.fn().mockRejectedValue(new Error('offline'));
318
- render((Board), {
319
- props: props({ cards: initialCards, optimistic: true, onmove }),
320
- });
321
- const card = screen.getByRole('button', { name: 'Password reset' });
322
- card.focus();
323
- await user.keyboard(' ');
324
- await user.keyboard('{ArrowRight}');
325
- await user.keyboard('{Enter}');
326
- await vi.waitFor(() => expect(screen.getByText('Could not move Password reset. The board was restored.')).toBeInTheDocument());
327
- expect(within(lane('New')).getByText('Password reset')).toBeInTheDocument();
328
- expect(within(lane('Assigned')).queryByText('Password reset')).not.toBeInTheDocument();
329
- await vi.waitFor(() => expect(screen.getByRole('button', { name: 'Password reset' })).toHaveFocus());
330
- });
331
- it('announces pickup, supports cancellation, collapse controls, and is axe-clean', async () => {
332
- const user = userEvent.setup();
333
- const { container } = render((Board), {
334
- props: props({ collapsible: true }),
335
- });
336
- const card = screen.getByRole('button', { name: 'Password reset' });
337
- card.focus();
338
- await user.keyboard(' ');
339
- expect(screen.getByText(/Picked up Password reset\. Available destinations: New, Assigned\./)).toBeInTheDocument();
340
- await user.keyboard('{Escape}');
341
- expect(screen.getByText('Cancelled moving Password reset.')).toBeInTheDocument();
342
- const collapse = screen.getByRole('button', { name: 'Collapse New' });
343
- await user.click(collapse);
344
- expect(collapse).toHaveAttribute('aria-expanded', 'false');
345
- expect(screen.getByRole('button', { name: 'Expand New' })).toBeInTheDocument();
346
- await expectNoA11yViolations(container);
347
- });
348
- it('expands a collapsed keyboard destination before committing so the moved card remains visible', async () => {
349
- const user = userEvent.setup();
350
- render((Board), {
351
- props: props({ collapsible: true }),
352
- });
353
- await user.click(screen.getByRole('button', { name: 'Collapse Assigned' }));
354
- const card = screen.getByRole('button', { name: 'Password reset' });
355
- card.focus();
356
- await user.keyboard(' ');
357
- await user.keyboard('{ArrowRight}');
358
- await user.keyboard('{Enter}');
359
- expect(screen.getByRole('button', { name: 'Collapse Assigned' })).toHaveAttribute('aria-expanded', 'true');
360
- expect(within(lane('Assigned')).getByText('Password reset')).toBeInTheDocument();
361
- await vi.waitFor(() => expect(within(lane('Assigned')).getByRole('button', {
362
- name: 'Password reset',
363
- })).toHaveFocus());
364
- });
365
- it('allows ordinary selection after a cancelled keyboard pickup', async () => {
366
- const user = userEvent.setup();
367
- const onselect = vi.fn();
368
- render((Board), { props: props({ onselect }) });
369
- const card = screen.getByRole('button', { name: 'Password reset' });
370
- card.focus();
371
- await user.keyboard(' ');
372
- await user.keyboard('{Escape}');
373
- await new Promise((resolve) => window.setTimeout(resolve, 0));
374
- await user.click(card);
375
- expect(onselect).toHaveBeenCalledWith(initialCards[0]);
376
- });
377
- it('skips disabled lanes and announces the unavailable destination', async () => {
378
- const user = userEvent.setup();
379
- render((Board), {
380
- props: props({
381
- columns: [columns[0], { ...columns[1], disabled: true }],
382
- }),
383
- });
384
- const card = screen.getByRole('button', { name: 'Password reset' });
385
- card.focus();
386
- await user.keyboard(' ');
387
- await user.keyboard('{ArrowRight}');
388
- expect(screen.getByText('Assigned is unavailable.')).toBeInTheDocument();
389
- await user.keyboard('{Escape}');
390
- });
391
- it('allows a card to leave a disabled source lane', async () => {
392
- const user = userEvent.setup();
393
- const disabledSourceCards = [{ ...initialCards[0], queue: 'assigned' }];
394
- const onmove = vi.fn();
395
- render((Board), {
396
- props: props({
397
- columns: [{ ...columns[0] }, { ...columns[1], disabled: true }],
398
- defaultCards: disabledSourceCards,
399
- onmove,
400
- }),
401
- });
402
- const card = screen.getByRole('button', { name: 'Password reset' });
403
- expect(card).toHaveAttribute('draggable', 'true');
404
- card.focus();
405
- await user.keyboard(' ');
406
- await user.keyboard('{ArrowLeft}');
407
- await user.keyboard('{Enter}');
408
- expect(onmove).toHaveBeenCalledWith(expect.objectContaining({ target: { columnId: 'new', index: 0 } }));
409
- });
410
- it('serializes deferred move persistence and permits the next move only after the first settles', async () => {
411
- const user = userEvent.setup();
412
- let resolveFirst;
413
- let resolveSecond;
414
- const onmove = vi
415
- .fn()
416
- .mockImplementationOnce(() => new Promise((resolve) => {
417
- resolveFirst = resolve;
418
- }))
419
- .mockImplementationOnce(() => new Promise((resolve) => {
420
- resolveSecond = resolve;
421
- }));
422
- render((Board), { props: props({ onmove }) });
423
- const first = screen.getByRole('button', { name: 'Password reset' });
424
- first.focus();
425
- await user.keyboard(' ');
426
- await user.keyboard('{ArrowRight}');
427
- await user.keyboard('{Enter}');
428
- await vi.waitFor(() => expect(onmove).toHaveBeenCalledTimes(1));
429
- const second = screen.getByRole('button', { name: 'Billing question' });
430
- second.focus();
431
- await user.keyboard(' ');
432
- await user.keyboard('{ArrowRight}');
433
- await user.keyboard('{Enter}');
434
- expect(onmove).toHaveBeenCalledTimes(1);
435
- resolveFirst();
436
- await vi.waitFor(() => expect(within(lane('Assigned')).getByText('Password reset')).toBeInTheDocument());
437
- second.focus();
438
- await user.keyboard(' ');
439
- await user.keyboard('{ArrowRight}');
440
- await user.keyboard('{Enter}');
441
- await vi.waitFor(() => expect(onmove).toHaveBeenCalledTimes(2));
442
- resolveSecond();
443
- await vi.waitFor(() => expect(within(lane('Assigned')).getByText('Billing question')).toBeInTheDocument());
444
- });
445
- it('renders stable board structure on the server without domain imports', async () => {
446
- const vite = await createServer({
447
- appType: 'custom',
448
- configFile: false,
449
- plugins: [svelte()],
450
- root: process.cwd(),
451
- server: { middlewareMode: true },
452
- });
453
- const { default: SsrBoard } = await vite.ssrLoadModule('/src/components/board/__tests__/BoardSsrHarness.svelte');
454
- const { render: renderSsr } = await vite.ssrLoadModule('svelte/server');
455
- const result = renderSsr(SsrBoard);
456
- expect(result.body).toContain('Sales pipeline');
457
- expect(result.body).toContain('Acme');
458
- expect(result.body).toContain('lane-0');
459
- await vite.close();
460
- const host = document.createElement('div');
461
- host.innerHTML = result.body;
462
- document.body.append(host);
463
- const instance = hydrate(BoardSsrHarness, {
464
- target: host,
465
- });
466
- expect(within(host).getByRole('region', { name: 'Lead, 1 cards' })).toBeInTheDocument();
467
- expect(within(host).getByRole('button', { name: 'Acme' })).toBeInTheDocument();
468
- await unmount(instance);
469
- host.remove();
470
- });
471
- it('scopes live descriptions when board instances share card ids', async () => {
472
- const user = userEvent.setup();
473
- const { container } = render((Board), {
474
- props: props(),
475
- });
476
- render((Board), { props: props() });
477
- const boards = screen.getAllByRole('region', { name: 'Support queues' });
478
- expect(boards).toHaveLength(2);
479
- const firstCard = within(boards[0]).getByRole('button', {
480
- name: 'Password reset',
481
- });
482
- const secondCard = within(boards[1]).getByRole('button', {
483
- name: 'Password reset',
484
- });
485
- firstCard.focus();
486
- await user.keyboard(' ');
487
- const firstLiveId = firstCard.getAttribute('aria-describedby');
488
- await user.keyboard('{Escape}');
489
- secondCard.focus();
490
- await user.keyboard(' ');
491
- const secondLiveId = secondCard.getAttribute('aria-describedby');
492
- expect(firstLiveId).toBeTruthy();
493
- expect(secondLiveId).toBeTruthy();
494
- expect(firstLiveId).not.toBe(secondLiveId);
495
- expect(within(boards[0]).getByText('Cancelled moving Password reset.')).toHaveAttribute('id', firstLiveId);
496
- expect(within(boards[1]).getByText(/Picked up Password reset/)).toHaveAttribute('id', secondLiveId);
497
- });
498
- });
@@ -1,30 +0,0 @@
1
- <script lang="ts">
2
- import Board from '../Board.svelte';
3
- import type { BoardColumn } from '../types.js';
4
-
5
- interface SalesCard {
6
- id: string;
7
- company: string;
8
- stage: string;
9
- }
10
-
11
- const columns: BoardColumn[] = [
12
- { id: 'lead', label: 'Lead' },
13
- { id: 'won', label: 'Won' },
14
- ];
15
- const cards: SalesCard[] = [{ id: 'sale-1', company: 'Acme', stage: 'lead' }];
16
- </script>
17
-
18
- {#snippet salesCard({ card }: { card: SalesCard; column: BoardColumn; index: number; isDragging: boolean })}
19
- <strong>{card.company}</strong>
20
- {/snippet}
21
-
22
- <Board
23
- {columns}
24
- defaultCards={cards}
25
- getCardColumnId={(card) => card.stage}
26
- setCardColumnId={(card, stage) => ({ ...card, stage })}
27
- getCardLabel={(card) => card.company}
28
- card={salesCard}
29
- label="Sales pipeline"
30
- />
@@ -1,19 +0,0 @@
1
- interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
- new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
- $$bindings?: Bindings;
4
- } & Exports;
5
- (internal: unknown, props: {
6
- $$events?: Events;
7
- $$slots?: Slots;
8
- }): Exports & {
9
- $set?: any;
10
- $on?: any;
11
- };
12
- z_$$bindings?: Bindings;
13
- }
14
- declare const BoardSsrHarness: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
- [evt: string]: CustomEvent<any>;
16
- }, {}, {}, string>;
17
- type BoardSsrHarness = InstanceType<typeof BoardSsrHarness>;
18
- export default BoardSsrHarness;
19
- //# sourceMappingURL=BoardSsrHarness.svelte.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BoardSsrHarness.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/board/__tests__/BoardSsrHarness.svelte.ts"],"names":[],"mappings":"AA+BA,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,eAAe;;kBAA+E,CAAC;AACnF,KAAK,eAAe,GAAG,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,eAAe,eAAe,CAAC"}