@nubisco/ui 3.1.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/components/BlueprintCard.vue.d.ts.map +1 -1
  2. package/dist/components/Button.vue.d.ts.map +1 -1
  3. package/dist/components/Charts/GanttChart.vue.d.ts.map +1 -1
  4. package/dist/components/Charts/InterpolationChart.vue.d.ts.map +1 -1
  5. package/dist/components/Charts/shared/palette.d.ts +76 -1
  6. package/dist/components/Charts/shared/palette.d.ts.map +1 -1
  7. package/dist/components/CommandPalette.vue.d.ts.map +1 -1
  8. package/dist/components/Confirm.d.ts +199 -0
  9. package/dist/components/Confirm.env.d.ts +52 -0
  10. package/dist/components/Confirm.env.d.ts.map +1 -0
  11. package/dist/components/Confirm.vue.d.ts +61 -0
  12. package/dist/components/Confirm.vue.d.ts.map +1 -0
  13. package/dist/components/DatePicker.vue.d.ts +1 -1
  14. package/dist/components/InlineLoading.d.ts +37 -0
  15. package/dist/components/InlineLoading.vue.d.ts +30 -0
  16. package/dist/components/InlineLoading.vue.d.ts.map +1 -0
  17. package/dist/components/MenuItem.vue.d.ts +1 -1
  18. package/dist/components/Modal.d.ts +35 -1
  19. package/dist/components/Modal.vue.d.ts +10 -1
  20. package/dist/components/Modal.vue.d.ts.map +1 -1
  21. package/dist/components/NotificationCenter.d.ts +184 -0
  22. package/dist/components/NotificationCenter.vue.d.ts +130 -0
  23. package/dist/components/NotificationCenter.vue.d.ts.map +1 -0
  24. package/dist/components/NotificationCenterItem.d.ts +53 -0
  25. package/dist/components/NotificationCenterItem.vue.d.ts +36 -0
  26. package/dist/components/NotificationCenterItem.vue.d.ts.map +1 -0
  27. package/dist/components/ProgressBar.vue.d.ts.map +1 -1
  28. package/dist/components/Shell.d.ts +138 -8
  29. package/dist/components/Shell.vue.d.ts +30 -3
  30. package/dist/components/Shell.vue.d.ts.map +1 -1
  31. package/dist/components/ShellPanel.d.ts +16 -0
  32. package/dist/components/ShellPanel.vue.d.ts +1 -0
  33. package/dist/components/ShellPanel.vue.d.ts.map +1 -1
  34. package/dist/components/SidebarLink.d.ts +14 -1
  35. package/dist/components/Skeleton.d.ts +87 -0
  36. package/dist/components/Skeleton.vue.d.ts +17 -0
  37. package/dist/components/Skeleton.vue.d.ts.map +1 -0
  38. package/dist/components/Spinner.d.ts +80 -0
  39. package/dist/components/Spinner.overlay.d.ts +56 -0
  40. package/dist/components/Spinner.overlay.d.ts.map +1 -0
  41. package/dist/components/Spinner.vue.d.ts +25 -0
  42. package/dist/components/Spinner.vue.d.ts.map +1 -0
  43. package/dist/components/Stepper.context.d.ts +48 -0
  44. package/dist/components/Stepper.context.d.ts.map +1 -0
  45. package/dist/components/Stepper.d.ts +101 -0
  46. package/dist/components/Stepper.vue.d.ts +31 -0
  47. package/dist/components/Stepper.vue.d.ts.map +1 -0
  48. package/dist/components/StepperStep.vue.d.ts +24 -0
  49. package/dist/components/StepperStep.vue.d.ts.map +1 -0
  50. package/dist/components/TextInput.vue.d.ts +2 -2
  51. package/dist/components/TextInput.vue.d.ts.map +1 -1
  52. package/dist/components/Toast.vue.d.ts +43 -0
  53. package/dist/components/Toast.vue.d.ts.map +1 -1
  54. package/dist/components/Toaster.d.ts +93 -0
  55. package/dist/components/Toaster.vue.d.ts +30 -0
  56. package/dist/components/Toaster.vue.d.ts.map +1 -0
  57. package/dist/components/UserMenu.vue.d.ts.map +1 -1
  58. package/dist/components/index.d.ts.map +1 -1
  59. package/dist/composables/useConfirm.composable.d.ts +45 -0
  60. package/dist/composables/useConfirm.composable.d.ts.map +1 -0
  61. package/dist/composables/useInlineLoading.composable.d.ts +43 -0
  62. package/dist/composables/useInlineLoading.composable.d.ts.map +1 -0
  63. package/dist/composables/useLoadingAnnouncer.composable.d.ts +63 -0
  64. package/dist/composables/useLoadingAnnouncer.composable.d.ts.map +1 -0
  65. package/dist/composables/useScrollLock.composable.d.ts +47 -0
  66. package/dist/composables/useScrollLock.composable.d.ts.map +1 -0
  67. package/dist/composables/useShellSlot.composable.d.ts +193 -0
  68. package/dist/composables/useShellSlot.composable.d.ts.map +1 -0
  69. package/dist/composables/useToast.composable.d.ts +325 -0
  70. package/dist/composables/useToast.composable.d.ts.map +1 -0
  71. package/dist/directives/ToolTip.content.d.ts +20 -0
  72. package/dist/directives/ToolTip.content.d.ts.map +1 -0
  73. package/dist/directives/ToolTip.directive.d.ts +94 -8
  74. package/dist/directives/ToolTip.directive.d.ts.map +1 -1
  75. package/dist/global.d.ts +18 -0
  76. package/dist/index.cjs +8 -9
  77. package/dist/index.mjs +17653 -14503
  78. package/dist/main.d.ts +43 -2
  79. package/dist/main.d.ts.map +1 -1
  80. package/dist/ui.css +1 -1
  81. package/package.json +1 -1
  82. package/src/styles/_theme.scss +171 -0
  83. package/src/styles/directives/_tooltip.scss +143 -21
@@ -1 +1 @@
1
- {"version":3,"file":"Toast.vue.d.ts","sourceRoot":"","sources":["../../src/components/Toast.vue"],"names":[],"mappings":"AAgQA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAEpE,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,KAAK,WAAW,GAAG;IACf,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,SAAS,CAAA;CAChB,CAAC;AA8LJ,QAAA,MAAM,YAAY;;;;;WAlMN,MAAM;aADJ,aAAa;cAGZ,MAAM;SACX,SAAS;6EAmMjB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"Toast.vue.d.ts","sourceRoot":"","sources":["../../src/components/Toast.vue"],"names":[],"mappings":"AAsdA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAEpE,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,KAAK,WAAW,GAAG;IACf,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,SAAS,CAAA;IACf;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAClC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,KAAK,CAAA;IACzC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,uDAAuD;IACvD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC;AA8PJ,QAAA,MAAM,YAAY;;;;;;;WApSN,MAAM;UAiBP,OAAO,GAAG,QAAQ,GAAG,MAAM;aAlBxB,aAAa;gBA4BV,MAAM;cAlBR,MAAM;iBAgBH,MAAM;SAfd,SAAS;cASJ,WAAW,GAAG,QAAQ,GAAG,KAAK;aAc/B,OAAO;YAER,OAAO;WAER,MAAM;6EAmQhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -0,0 +1,93 @@
1
+ import type { IToastQueue } from '../composables/useToast.composable'
2
+
3
+ /**
4
+ * Where the stack sits.
5
+ *
6
+ * The suffix is the inline edge, so it follows the document direction rather
7
+ * than the screen: `-end` is the right in a left-to-right document and the
8
+ * left in Arabic or Hebrew. The audit found five different breakpoint scales
9
+ * and no shared idea of "the corner"; naming the edge logically is what stops
10
+ * a right-to-left build from putting the stack on top of the shell rail.
11
+ */
12
+ type TToasterPlacement =
13
+ | 'top-start'
14
+ | 'top'
15
+ | 'top-end'
16
+ | 'bottom-start'
17
+ | 'bottom'
18
+ | 'bottom-end'
19
+
20
+ interface IToasterProps {
21
+ /**
22
+ * Queue to render. Defaults to the shared `useToast()` queue.
23
+ *
24
+ * Pass one from `createToastQueue()` for anything that is not the
25
+ * application's own stack: a docs demo, a test, a second host inside a
26
+ * dialog. Two hosts rendering the same queue show and announce every
27
+ * message twice, and both write to `queue.max`; the host warns about it in
28
+ * development.
29
+ *
30
+ * It is read reactively, so binding a queue that is created after mount is
31
+ * safe.
32
+ */
33
+ queue?: IToastQueue
34
+ /**
35
+ * Corner or edge the stack grows from. `bottom-end` keeps it clear of the
36
+ * shell top bar, where the actions that raise most toasts live.
37
+ */
38
+ placement?: TToasterPlacement
39
+ /**
40
+ * Visible-slot cap. Extras wait in the queue and slide in as slots free up.
41
+ *
42
+ * The cap belongs to the queue, since admission happens in `push()` before
43
+ * any host renders, so this prop writes through to `queue.max` and restores
44
+ * the previous value when the host unmounts.
45
+ *
46
+ * There is deliberately **no default**. Leaving it off means the queue keeps
47
+ * whatever cap it was built with, so `createToastQueue({ max: 2 })` rendered
48
+ * by a bare `<NbToaster :queue="toast" />` shows two. A default here would
49
+ * silently overrule every queue configured through `createToastQueue`, which
50
+ * is the one place a consumer expects to set this. Set it on the prop only
51
+ * when the host is the thing that knows better than the queue: a demo, a
52
+ * dialog, a narrow viewport.
53
+ *
54
+ * The queue's own default, from `createToastQueue()`, is `3`.
55
+ */
56
+ max?: number
57
+ /** Accessible name of the region landmark. */
58
+ label?: string
59
+ /**
60
+ * Teleport target. Body keeps the stack out of every transformed ancestor.
61
+ *
62
+ * `false` turns the teleport off and renders the stack where the component
63
+ * sits. That is the server-rendering answer: `<Teleport>` does not render
64
+ * into its target on the server, it buffers into `ctx.teleports`, and an app
65
+ * that does not write that buffer into the target hydrates a stack the
66
+ * server never sent. Either splice `ctx.teleports.body` into your HTML
67
+ * template, or pass `:to="false"` and mount the host at the app root.
68
+ */
69
+ to?: string | false
70
+ /**
71
+ * Keyboard shortcut that moves focus into the stack and back out again.
72
+ * `'alt+t'` by default; pass `null` to remove it.
73
+ *
74
+ * Written as modifiers plus one key (`'alt+t'`, `'ctrl+shift+n'`). The
75
+ * terminal key is matched on its physical position (`event.code`), not on
76
+ * the character it produces, because Option on macOS is a character
77
+ * modifier: Option+T types a dagger, never a `t`.
78
+ *
79
+ * Without a hotkey, the only route to a toast's action is to tab past the
80
+ * rest of the document, which is a long way from wherever the user was, and
81
+ * the countdown is running while they travel.
82
+ */
83
+ hotkey?: string | null
84
+ /**
85
+ * Spoken form of the hotkey, appended once to the announcement of a toast
86
+ * that carries an action. Translate it with the rest of the interface, and
87
+ * change it if you change `hotkey`: it is a promise made to somebody who
88
+ * cannot see the stack, so it has to name a key that works.
89
+ */
90
+ hotkeyHint?: string
91
+ }
92
+
93
+ export type { IToasterProps, TToasterPlacement }
@@ -0,0 +1,30 @@
1
+ import type { IToasterProps } from './Toaster.d';
2
+ import { type IToastRecord, type TToastDismissReason } from '../composables/useToast.composable';
3
+ import type { IToastQueue } from '../composables/useToast.composable';
4
+ export type { TToasterPlacement } from './Toaster.d';
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
7
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<IToasterProps, {
8
+ queue: import("vue").ComputedRef<IToastQueue>;
9
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<IToasterProps> & Readonly<{}>, {
10
+ label: string;
11
+ max: number;
12
+ to: string | false;
13
+ placement: import("./Toaster.d").TToasterPlacement;
14
+ queue: IToastQueue;
15
+ hotkey: string | null;
16
+ hotkeyHint: string;
17
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
18
+ toast?: (props: {
19
+ toast: IToastRecord;
20
+ paused: boolean;
21
+ dismiss: (reason?: TToastDismissReason) => void;
22
+ action: () => Set<string>;
23
+ }) => any;
24
+ }>;
25
+ type __VLS_WithSlots<T, S> = T & {
26
+ new (): {
27
+ $slots: S;
28
+ };
29
+ };
30
+ //# sourceMappingURL=Toaster.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toaster.vue.d.ts","sourceRoot":"","sources":["../../src/components/Toaster.vue"],"names":[],"mappings":"AA+9BA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACzB,MAAM,oCAAoC,CAAA;AAG3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAErE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;wBAwB/B,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;;;;;;;;;;;YA41BN,CAAC,KAAK;;;2BAtEM,mBAAmB;;KAsER,KAAK,GAAG;EAWvC,CAAC;AAWL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"UserMenu.vue.d.ts","sourceRoot":"","sources":["../../src/components/UserMenu.vue"],"names":[],"mappings":"AAqfA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAiHpE,iBAAS,MAAM,SASd;AAED,iBAAS,KAAK,SAIb;AA0YD,QAAA,IAAI,OAAO;;;CAAU,EAAE,QAAQ;;CAAW,EAAE,QAAQ,IAAY,CAAE;AAClE,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC5C;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,GAC7C;IAAE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAQ9C,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6EAKd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"UserMenu.vue.d.ts","sourceRoot":"","sources":["../../src/components/UserMenu.vue"],"names":[],"mappings":"AA6fA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAyHpE,iBAAS,MAAM,SASd;AAED,iBAAS,KAAK,SAIb;AAkZD,QAAA,IAAI,OAAO;;;CAAU,EAAE,QAAQ;;CAAW,EAAE,QAAQ,IAAY,CAAE;AAClE,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC5C;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,GAC7C;IAAE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAQ9C,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6EAKd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;;iBA8Jf,GAAG;;AADlB,wBAMC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;;iBAgLf,GAAG;;AADlB,wBAMC"}
@@ -0,0 +1,45 @@
1
+ import type { IConfirmOptions } from '../components/Confirm.d';
2
+ /**
3
+ * Awaitable confirmation.
4
+ *
5
+ * ```ts
6
+ * const confirm = useConfirm()
7
+ * if (await confirm({ title: 'Delete environment', subject: env.name })) {
8
+ * await api.deleteEnvironment(env.id)
9
+ * }
10
+ * ```
11
+ *
12
+ * Resolves `true` only if the user confirmed (and, when `onConfirm` is
13
+ * supplied, only after that work succeeded). Escape, the overlay, the close
14
+ * button and the cancel button all resolve `false`. It never rejects: a
15
+ * failing `onConfirm` keeps the dialog open instead, so a rejected promise
16
+ * would have no honest meaning here.
17
+ */
18
+ export type TConfirmFn = (options: IConfirmOptions) => Promise<boolean>;
19
+ /**
20
+ * Cancels the dialog on screen and everything waiting behind it, resolving
21
+ * every outstanding `confirm()` to `false`, then tears the host down.
22
+ *
23
+ * Call it when the ground moves under a pending question: a route change, a
24
+ * signed-out session, a Tauri window closing. Without it a confirm asked
25
+ * about a record that no longer exists sits there waiting for an answer.
26
+ *
27
+ * Work already in flight is not cancelled, because nothing here can cancel a
28
+ * request it did not make. It is disowned: every entry is marked done, so
29
+ * when that request finally lands it resolves nothing, closes nothing and
30
+ * shows its failure to nobody. Pass an AbortSignal inside `onConfirm` if the
31
+ * call itself has to stop too.
32
+ */
33
+ export declare function dismissConfirms(): void;
34
+ /**
35
+ * Returns the `confirm()` function. It is a plain function over module state,
36
+ * not an injection, so it works in a component, in a Pinia store, in a router
37
+ * guard and in a plain module.
38
+ *
39
+ * Nothing to install and nothing to mount: the first call creates the host.
40
+ * That matters beyond convenience, because `window.confirm` is a documented
41
+ * no-op inside a Tauri webview and cannot be driven by a gamepad, so the
42
+ * alternative every app reached for is not available to two of ours.
43
+ */
44
+ export declare function useConfirm(): TConfirmFn;
45
+ //# sourceMappingURL=useConfirm.composable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useConfirm.composable.d.ts","sourceRoot":"","sources":["../../src/composables/useConfirm.composable.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,wBAAwB,CAAA;AAE5E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAiTvE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,IAAI,IAAI,CA8BtC;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,IAAI,UAAU,CAEvC"}
@@ -0,0 +1,43 @@
1
+ import { type Ref } from 'vue';
2
+ type TInlineLoadingStatus = 'inactive' | 'active' | 'finished' | 'error';
3
+ interface IUseInlineLoadingOptions {
4
+ /** Called when the wrapped action rejects, before the status flips to `error`. */
5
+ onError?: (error: unknown) => void;
6
+ }
7
+ interface IUseInlineLoading {
8
+ /** Bind to `NbInlineLoading`'s `status` prop. */
9
+ status: Readonly<Ref<TInlineLoadingStatus>>;
10
+ /** Whatever the last failed run rejected with, for logging or a message. */
11
+ error: Readonly<Ref<unknown>>;
12
+ /** Runs an async action and drives the status through the four states. */
13
+ run: <T>(action: () => Promise<T>) => Promise<T | undefined>;
14
+ /** Back to `inactive`. Bind to the component's `success` event. */
15
+ reset: () => void;
16
+ }
17
+ /**
18
+ * Drives the NbInlineLoading state machine for a single action.
19
+ *
20
+ * The audit found four apps that confirmed a successful save with nothing at
21
+ * all, and none of them were being careless: they were all writing the same
22
+ * try/catch/finally by hand and the finally reset the flag before anything
23
+ * could be shown. Handing the sequence over removes the chance to get it
24
+ * wrong.
25
+ *
26
+ * Two behaviours are worth knowing about:
27
+ *
28
+ * - Overlapping runs. If a second `run` starts while the first is in flight,
29
+ * only the newest one is allowed to write the status. A slow first save can
30
+ * no longer land on top of a fast second one and report the wrong outcome.
31
+ * - Rejections are absorbed, not rethrown. `run` is meant to be called from a
32
+ * click handler, where a rethrown rejection becomes an unhandled promise.
33
+ * The reason is kept in `error` and passed to `onError`, and the failure is
34
+ * visible in the UI, which is what the caller actually wanted.
35
+ *
36
+ * @example
37
+ * const save = useInlineLoading()
38
+ * // <NbButton @click="save.run(() => api.save(form))">Save</NbButton>
39
+ * // <NbInlineLoading :status="save.status.value" @success="save.reset" />
40
+ */
41
+ export declare function useInlineLoading(options?: IUseInlineLoadingOptions): IUseInlineLoading;
42
+ export type { TInlineLoadingStatus, IUseInlineLoading, IUseInlineLoadingOptions, };
43
+ //# sourceMappingURL=useInlineLoading.composable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInlineLoading.composable.d.ts","sourceRoot":"","sources":["../../src/composables/useInlineLoading.composable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AAG7C,KAAK,oBAAoB,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAA;AAExE,UAAU,wBAAwB;IAChC,kFAAkF;IAClF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CACnC;AAED,UAAU,iBAAiB;IACzB,iDAAiD;IACjD,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAA;IAC3C,4EAA4E;IAC5E,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IAC7B,0EAA0E;IAC1E,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;IAC5D,mEAAmE;IACnE,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,wBAA6B,GACrC,iBAAiB,CA0CnB;AAGD,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,wBAAwB,GACzB,CAAA"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Announces that a load has finished, from a component that is about to stop
3
+ * existing.
4
+ *
5
+ * A spinner or a skeleton says "this is loading" and then, when the work is
6
+ * done, it is unmounted. Sighted users see the content appear. A screen reader
7
+ * user gets silence: the live region that was doing the talking has been
8
+ * removed from the document, so nothing can be spoken through it, and the
9
+ * newly inserted content is not itself an update anyone is watching. Every
10
+ * loading indicator in the library shares this problem, and it is why the
11
+ * completion half of a load is the part that goes missing.
12
+ *
13
+ * The fix cannot live inside the component: to be heard, the message has to be
14
+ * written into a live region that is already in the document and stays there
15
+ * afterwards. So there is one shared region, owned by this module, appended to
16
+ * `<body>` the first time anything announces and reused from then on.
17
+ *
18
+ * Two details that matter more than they look:
19
+ *
20
+ * - The message is written on a later task, not synchronously. A live region
21
+ * that is inserted and filled in the same frame is frequently missed, and
22
+ * the announcement typically races the unmount that triggered it.
23
+ * - The same text twice in a row is not spoken twice by most screen readers,
24
+ * because the node's contents did not change. Clearing first makes the
25
+ * second "Invoices loaded" a real change.
26
+ *
27
+ * The delay is also what makes `suppressLoadingAnnouncement` possible, and that
28
+ * matters more than it sounds: an indicator is unmounted by the same state
29
+ * change that decides whether the load succeeded or failed, and it cannot read
30
+ * that decision. Vue does not update a component's props on the render that
31
+ * removes it, so a `:failed` prop set in the same tick is never seen by the
32
+ * teardown handler. The failure path speaks up instead. See the composable's
33
+ * docs and the "when the fetch fails" section of the skeleton page.
34
+ */
35
+ /**
36
+ * Speaks `message` politely. Called from a component's teardown, after the
37
+ * work it was covering has finished.
38
+ */
39
+ export declare function announceLoadingComplete(message: string | undefined): void;
40
+ /**
41
+ * Cancels the completion announcement for the load that is ending right now.
42
+ *
43
+ * Call it where the failure is known, before the state change that removes the
44
+ * indicator:
45
+ *
46
+ * ```ts
47
+ * catch (reason) {
48
+ * suppressLoadingAnnouncement()
49
+ * error.value = reason
50
+ * }
51
+ * ```
52
+ *
53
+ * The suppression covers anything queued for the rest of the current task, so
54
+ * it holds across the render that unmounts the spinner or skeleton and the
55
+ * teardown handler that would have announced. It then lifts by itself: the
56
+ * next load is a new load, and it is allowed to report its own ending.
57
+ */
58
+ export declare function suppressLoadingAnnouncement(): void;
59
+ /** The shared region, for tests. Null until something has announced. */
60
+ export declare function loadingAnnouncerRegion(): HTMLElement | null;
61
+ /** Test helper: removes the region and cancels anything queued. */
62
+ export declare function resetLoadingAnnouncer(): void;
63
+ //# sourceMappingURL=useLoadingAnnouncer.composable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLoadingAnnouncer.composable.d.ts","sourceRoot":"","sources":["../../src/composables/useLoadingAnnouncer.composable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAmCH;;;GAGG;AAEH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAezE;AAGD;;;;;;;;;;;;;;;;;GAiBG;AAEH,wBAAgB,2BAA2B,IAAI,IAAI,CAYlD;AAGD,wEAAwE;AACxE,wBAAgB,sBAAsB,IAAI,WAAW,GAAG,IAAI,CAE3D;AAED,mEAAmE;AACnE,wBAAgB,qBAAqB,IAAI,IAAI,CAQ5C"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The page scroll lock, counted, in one place.
3
+ *
4
+ * `document.body.style.overflow` is a single slot on a single element, so every
5
+ * component that wants to stop the page scrolling is writing to the same
6
+ * variable. Three of ours did, independently: NbModal (counted), NbCommandPalette
7
+ * (a raw assignment) and NbSpinner's page overlay (a save/restore pair of its
8
+ * own). Any two of them overlapping produced the same class of bug, and the
9
+ * worst ordering left the page permanently unscrollable with nothing on screen:
10
+ *
11
+ * 1. the spinner saves `''` and sets `hidden`
12
+ * 2. a modal opens, saves `hidden` as the value to put back
13
+ * 3. the spinner releases and restores `''`, so the page scrolls behind the
14
+ * open dialog
15
+ * 4. the modal closes and restores its saved `hidden`, forever
16
+ *
17
+ * A counter fixes it because the thing being tracked is not "am I locked" but
18
+ * "how many owners still need the lock". The original value is read once, when
19
+ * the count goes from zero to one, and put back once, when it returns to zero.
20
+ * Restoring the literal previous value (usually the empty string, meaning "not
21
+ * set by us") matters: an application that legitimately sets `overflow: hidden`
22
+ * on the body for its own layout keeps it.
23
+ *
24
+ * Owners hold a share rather than calling the module functions directly, so a
25
+ * component that unmounts mid-lock releases exactly one count and a component
26
+ * that locks twice still only holds one.
27
+ */
28
+ /** Adds one owner to the lock, taking the scrollbar away on the first. */
29
+ export declare function acquireScrollLock(): void;
30
+ /** Drops one owner. The page scrolls again only when the last one has gone. */
31
+ export declare function releaseScrollLock(): void;
32
+ /** How many owners hold the lock. Exposed for tests and for debugging. */
33
+ export declare function scrollLockDepth(): number;
34
+ /**
35
+ * One owner's share of the lock, tied to the calling scope.
36
+ *
37
+ * `lock()` and `unlock()` are idempotent for this owner, and the share is
38
+ * released automatically when the component goes away, which is the case that
39
+ * used to leak: a route change that unmounts a dialog without closing it.
40
+ */
41
+ export declare function useScrollLock(): {
42
+ lock: () => void;
43
+ unlock: () => void;
44
+ };
45
+ /** Test helper: forgets every owner and puts the body back as it was found. */
46
+ export declare function resetScrollLock(): void;
47
+ //# sourceMappingURL=useScrollLock.composable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useScrollLock.composable.d.ts","sourceRoot":"","sources":["../../src/composables/useScrollLock.composable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAOH,0EAA0E;AAC1E,wBAAgB,iBAAiB,IAAI,IAAI,CAOxC;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI;IAAE,IAAI,EAAE,MAAM,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAkBxE;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,IAAI,IAAI,CAMtC"}
@@ -0,0 +1,193 @@
1
+ import { defineComponent, type ComputedRef, type InjectionKey, type ShallowRef } from 'vue';
2
+ /**
3
+ * Shell regions a view is allowed to contribute controls to.
4
+ *
5
+ * These are exactly the regions `NbShell` renders as a single addressable
6
+ * element. `sidebar-*` is deliberately absent: navigation is the application's
7
+ * to declare once, not a per-view contribution, and a view that could inject
8
+ * rail items could also make the rail change shape on every route.
9
+ * `menubar` is absent because it is the legacy in-body bar, kept for the two
10
+ * apps that still pass it and not worth a new contract.
11
+ */
12
+ export type TShellSlotName = 'outer-menu' | 'inner-menu' | 'notification' | 'topbar-left' | 'topbar-right' | 'fixedbar' | 'bottom' | 'inspector';
13
+ /**
14
+ * What happens when two views hold the same region at the same time, which is
15
+ * the normal state of affairs for the frame or two a route transition takes.
16
+ *
17
+ * - `'last'` (default): the most recently registered contributor renders and
18
+ * the others stand down. The leaving view's controls disappear the moment
19
+ * the arriving view registers, so the topbar never shows two page titles or
20
+ * two Save buttons. When the newer contributor unmounts, the previous one
21
+ * becomes active again, which is what makes a contribution inside a dialog
22
+ * or a nested route behave.
23
+ * - `'all'`: every contributor renders, ordered by `order` then registration.
24
+ * For genuinely additive regions (a status chip from a background sync
25
+ * alongside the page's own actions).
26
+ */
27
+ export type TShellSlotClaim = 'last' | 'all';
28
+ export interface IShellSlotOptions {
29
+ /**
30
+ * Sort key within a region when `claim: 'all'`. Lower renders first (further
31
+ * left in a horizontal region, higher in a stacked one). Ties keep
32
+ * registration order. Ignored when `claim` is `'last'`, where there is only
33
+ * ever one contribution to place.
34
+ *
35
+ * Teleports append in mount order, which for concurrent views is whatever
36
+ * order the router happened to create them in. So under `claim: 'all'` the
37
+ * outlet wraps its content in a flex box carrying a CSS `order`, and that is
38
+ * what actually sorts the region. The wrapper inherits the region's own gap
39
+ * and cross-axis alignment (both with an explicit `inherit`), so
40
+ * contributions line up with static slot content rather than reading as a
41
+ * nested group.
42
+ *
43
+ * CSS `order` only sorts flex and grid children, and three of the eight
44
+ * regions (`outer-menu`, `inner-menu`, `notification`) are block containers
45
+ * whose internal layout belongs to the product, not to us. `NbShell`
46
+ * therefore switches exactly those three to a column flex container while a
47
+ * shared contribution is registered, and back when the last one leaves: see
48
+ * `sharedCount` below and `.nb-shell__region--ordered` in `Shell.vue`. The
49
+ * switch is scoped to the new API on purpose, so a product that never calls
50
+ * `useShellSlot` keeps byte-identical layout in the regions it already fills
51
+ * by hand.
52
+ * @default 0
53
+ */
54
+ order?: number;
55
+ /**
56
+ * How this contributor shares the region with others.
57
+ * @default 'last'
58
+ */
59
+ claim?: TShellSlotClaim;
60
+ }
61
+ /** One registered contributor, as the shell sees it. */
62
+ interface IShellSlotEntry {
63
+ id: number;
64
+ name: TShellSlotName;
65
+ order: number;
66
+ claim: TShellSlotClaim;
67
+ seq: number;
68
+ /**
69
+ * True while the contributor is alive but off screen, which in practice
70
+ * means a `<KeepAlive>`-cached route component that has been deactivated.
71
+ * Such an entry is skipped by `activeIds` and by `count`, so a cached page's
72
+ * controls neither render nor keep a region open.
73
+ */
74
+ deactivated: boolean;
75
+ }
76
+ /**
77
+ * The contract `NbShell` provides and `useShellSlot` consumes. Not public API:
78
+ * consumers go through the composable, which is the whole point of the piece.
79
+ */
80
+ export interface IShellSlotRegistry {
81
+ register(entry: IShellSlotEntry): void;
82
+ unregister(id: number): void;
83
+ /** The live host element for a region, or null before the shell has mounted it. */
84
+ elementFor(name: TShellSlotName): ShallowRef<HTMLElement | null>;
85
+ /** Ids that should render right now for a region, in render order. */
86
+ activeIds(name: TShellSlotName): ComputedRef<number[]>;
87
+ /**
88
+ * Suspend or resume a registration without losing it. Called from the
89
+ * composable's `onDeactivated` / `onActivated`, which is the only lifecycle
90
+ * pair `<KeepAlive>` gives us: a deactivated component is not unmounted, its
91
+ * effect scope is not disposed, and its teleported nodes stay exactly where
92
+ * they were.
93
+ */
94
+ setActive(id: number, active: boolean): void;
95
+ }
96
+ export declare const NB_SHELL_SLOT_KEY: InjectionKey<IShellSlotRegistry>;
97
+ export interface IShellSlot {
98
+ /** This contributor's id. Useful in tests and debugging; not needed to render. */
99
+ readonly id: number;
100
+ /** The region this contributor targets. */
101
+ readonly name: TShellSlotName;
102
+ /**
103
+ * The host element inside the shell. `null` until the shell has mounted the
104
+ * region, which is normal on the first tick: a view's `onMounted` runs
105
+ * BEFORE its ancestors'. Reactive, so anything bound to it corrects itself
106
+ * without a `nextTick` dance.
107
+ */
108
+ readonly target: Readonly<ShallowRef<HTMLElement | null>>;
109
+ /** True once `target` exists. */
110
+ readonly ready: ComputedRef<boolean>;
111
+ /**
112
+ * True when this contributor both has a target and has won the region under
113
+ * the current `claim`. `Outlet` already checks this; read it when you need
114
+ * to skip expensive work rather than just skip rendering.
115
+ */
116
+ readonly active: ComputedRef<boolean>;
117
+ /**
118
+ * Renders its default slot into the region. Use it as a component:
119
+ * `<component :is="topbar.Outlet"><NbButton ... /></component>`.
120
+ *
121
+ * Content stays owned by the view: it is teleported, not re-created, so its
122
+ * reactive state, event handlers and component instances are the view's.
123
+ */
124
+ readonly Outlet: ReturnType<typeof defineComponent>;
125
+ }
126
+ /**
127
+ * Contribute controls from a view into a region of the surrounding `NbShell`.
128
+ *
129
+ * Eight of our twelve applications solved this with a hand-rolled DOM id
130
+ * (`#cms-topbar`, `#ob-topbar-left`, `#page-actions`, five more), and every one
131
+ * of them re-derived the same two problems: the target element does not exist
132
+ * when the view mounts, and during a route transition two views hold the region
133
+ * at once. This composable is the supported answer to both.
134
+ *
135
+ * ```vue
136
+ * <script setup lang="ts">
137
+ * import { useShellSlot } from '@nubisco/ui'
138
+ * const topbar = useShellSlot('topbar-right')
139
+ * </script>
140
+ *
141
+ * <template>
142
+ * <topbar.Outlet>
143
+ * <NbButton size="sm" @click="save">Save</NbButton>
144
+ * </topbar.Outlet>
145
+ * <article>...</article>
146
+ * </template>
147
+ * ```
148
+ *
149
+ * Contributing also makes the region exist: `NbShell` counts registrations the
150
+ * same way it counts slot content, so a topbar with no static slots and no
151
+ * contributions is not rendered at all, and appears the moment a view claims
152
+ * it. Nothing to hide from the outside with a `:deep()` override.
153
+ *
154
+ * Under `<KeepAlive>` the contribution follows the page rather than the
155
+ * component instance. A cached route component that is deactivated releases the
156
+ * region on the way out and takes it back (as the newest claimant) on the way
157
+ * in, so `<router-view v-slot="{ Component }"><KeepAlive><component
158
+ * :is="Component" /></KeepAlive></router-view>` behaves the same as an
159
+ * uncached one.
160
+ *
161
+ * Outside an `NbShell` the composable is inert: `ready` stays false, `Outlet`
162
+ * renders nothing, no warning, no throw. That keeps a view usable in isolation
163
+ * (a storybook page, a unit test, a print route) without branching on it.
164
+ *
165
+ * The same is true inside a shell that is not rendering the region: a
166
+ * contribution to `topbar-left` under `<NbShell topbar="never">` has no host
167
+ * element to teleport into, so `ready` stays false and nothing renders. The
168
+ * shell warns about that case in development, because it is a configuration
169
+ * mistake rather than a legitimate isolated mount.
170
+ */
171
+ export declare function useShellSlot(name: TShellSlotName, options?: IShellSlotOptions): IShellSlot;
172
+ /**
173
+ * Builds the registry side of the contract. Called by `NbShell`; exported so
174
+ * the shell and the composable cannot drift apart, not as consumer API.
175
+ */
176
+ export declare function createShellSlotRegistry(): {
177
+ registry: IShellSlotRegistry;
178
+ /**
179
+ * Reactive count of *live* contributors per region, for the shell's own
180
+ * `v-if`. Deactivated (`<KeepAlive>`-cached) entries do not count, so a
181
+ * topbar opened by a page that has since been cached closes again.
182
+ */
183
+ count: (name: TShellSlotName) => number;
184
+ /**
185
+ * Reactive count of live `claim: 'all'` contributors per region. The shell
186
+ * uses it to decide whether a block region needs to become a flex container
187
+ * for the duration, which is the only way a CSS `order` can sort it.
188
+ */
189
+ sharedCount: (name: TShellSlotName) => number;
190
+ setElement: (name: TShellSlotName, el: HTMLElement | null) => void;
191
+ };
192
+ export {};
193
+ //# sourceMappingURL=useShellSlot.composable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useShellSlot.composable.d.ts","sourceRoot":"","sources":["../../src/composables/useShellSlot.composable.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EAWf,KAAK,WAAW,EAChB,KAAK,YAAY,EAEjB,KAAK,UAAU,EAEhB,MAAM,KAAK,CAAA;AAEZ;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GACtB,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,aAAa,GACb,cAAc,GACd,UAAU,GACV,QAAQ,GACR,WAAW,CAAA;AAEf;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,KAAK,CAAA;AAE5C,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,eAAe,CAAA;CACxB;AAED,wDAAwD;AACxD,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,eAAe,CAAA;IACtB,GAAG,EAAE,MAAM,CAAA;IACX;;;;;OAKG;IACH,WAAW,EAAE,OAAO,CAAA;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAA;IACtC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,mFAAmF;IACnF,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAChE,sEAAsE;IACtE,SAAS,CAAC,IAAI,EAAE,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAA;IACtD;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAA;CAC7C;AAED,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAAC,kBAAkB,CACrC,CAAA;AAO1B,MAAM,WAAW,UAAU;IACzB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAA;IACzD,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IACpC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAA;CACpD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,cAAc,EACpB,OAAO,GAAE,iBAAsB,GAC9B,UAAU,CAqGZ;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI;IACzC,QAAQ,EAAE,kBAAkB,CAAA;IAC5B;;;;OAIG;IACH,KAAK,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,MAAM,CAAA;IACvC;;;;OAIG;IACH,WAAW,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,MAAM,CAAA;IAC7C,UAAU,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;CACnE,CAwEA"}