@prosekit/web 0.7.9 → 0.7.10

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 (111) hide show
  1. package/dist/{get-default-state-Bqluw34o.js → get-default-state-BzBimBWi.js} +1 -1
  2. package/dist/get-default-state-BzBimBWi.js.map +1 -0
  3. package/dist/{get-safe-editor-view-DJlcheeV.js → get-safe-editor-view-Dt9Amrcn.js} +1 -1
  4. package/dist/{get-safe-editor-view-DJlcheeV.js.map → get-safe-editor-view-Dt9Amrcn.js.map} +1 -1
  5. package/dist/{inject-style-DYQXx-cE.js → inject-style-BaFaVQvj.js} +7 -7
  6. package/dist/inject-style-BaFaVQvj.js.map +1 -0
  7. package/dist/prosekit-web-autocomplete.d.ts.map +1 -1
  8. package/dist/prosekit-web-autocomplete.js +3 -3
  9. package/dist/prosekit-web-autocomplete.js.map +1 -1
  10. package/dist/prosekit-web-block-handle.d.ts.map +1 -1
  11. package/dist/prosekit-web-block-handle.js +4 -4
  12. package/dist/prosekit-web-block-handle.js.map +1 -1
  13. package/dist/prosekit-web-drop-indicator.d.ts.map +1 -1
  14. package/dist/prosekit-web-drop-indicator.js +2 -2
  15. package/dist/prosekit-web-drop-indicator.js.map +1 -1
  16. package/dist/prosekit-web-inline-popover.d.ts.map +1 -1
  17. package/dist/prosekit-web-inline-popover.js +1 -1
  18. package/dist/prosekit-web-inline-popover.js.map +1 -1
  19. package/dist/prosekit-web-popover.d.ts.map +1 -1
  20. package/dist/prosekit-web-popover.js.map +1 -1
  21. package/dist/prosekit-web-resizable.d.ts.map +1 -1
  22. package/dist/prosekit-web-resizable.js.map +1 -1
  23. package/dist/prosekit-web-table-handle.d.ts.map +1 -1
  24. package/dist/prosekit-web-table-handle.js +22 -22
  25. package/dist/prosekit-web-table-handle.js.map +1 -1
  26. package/dist/prosekit-web-tooltip.d.ts.map +1 -1
  27. package/dist/prosekit-web-tooltip.js.map +1 -1
  28. package/dist/prosekit-web.d.ts +80 -1
  29. package/dist/prosekit-web.d.ts.map +1 -0
  30. package/dist/prosekit-web.js +95 -1
  31. package/dist/prosekit-web.js.map +1 -0
  32. package/dist/{use-editor-extension-B_5BbYvf.js → use-editor-extension-B2WuUfnd.js} +1 -1
  33. package/dist/use-editor-extension-B2WuUfnd.js.map +1 -0
  34. package/dist/{use-scrolling-BjI3cuLt.js → use-scrolling-BjVzAkiZ.js} +3 -1
  35. package/dist/use-scrolling-BjVzAkiZ.js.map +1 -0
  36. package/package.json +11 -11
  37. package/src/components/autocomplete/autocomplete-empty/types.ts +1 -4
  38. package/src/components/autocomplete/autocomplete-item/setup.ts +2 -10
  39. package/src/components/autocomplete/autocomplete-item/types.ts +2 -8
  40. package/src/components/autocomplete/autocomplete-list/setup.ts +5 -21
  41. package/src/components/autocomplete/autocomplete-list/types.ts +2 -10
  42. package/src/components/autocomplete/autocomplete-popover/helpers.spec.ts +1 -5
  43. package/src/components/autocomplete/autocomplete-popover/setup.ts +4 -20
  44. package/src/components/autocomplete/autocomplete-popover/types.ts +1 -4
  45. package/src/components/autocomplete/context.ts +1 -4
  46. package/src/components/block-handle/block-handle-add/setup.ts +1 -5
  47. package/src/components/block-handle/block-handle-add/types.ts +1 -4
  48. package/src/components/block-handle/block-handle-draggable/setup.ts +3 -18
  49. package/src/components/block-handle/block-handle-draggable/types.ts +1 -4
  50. package/src/components/block-handle/block-handle-popover/pointer-move.ts +2 -10
  51. package/src/components/block-handle/block-handle-popover/setup.ts +4 -22
  52. package/src/components/block-handle/block-handle-popover/types.ts +1 -4
  53. package/src/components/block-handle/context.ts +1 -4
  54. package/src/components/drop-indicator/drop-indicator/setup.ts +3 -15
  55. package/src/components/drop-indicator/drop-indicator/types.ts +1 -4
  56. package/src/components/inline-popover/inline-popover/setup.ts +1 -4
  57. package/src/components/inline-popover/inline-popover/types.ts +1 -4
  58. package/src/components/inline-popover/inline-popover/virtual-selection-element.ts +1 -5
  59. package/src/components/popover/popover-content/types.ts +2 -8
  60. package/src/components/popover/popover-root/types.ts +2 -8
  61. package/src/components/popover/popover-trigger/types.ts +2 -8
  62. package/src/components/resizable/context.ts +1 -4
  63. package/src/components/resizable/resizable-handle/calc-resize.spec.ts +1 -4
  64. package/src/components/resizable/resizable-handle/setup.ts +2 -15
  65. package/src/components/resizable/resizable-handle/types.ts +1 -4
  66. package/src/components/resizable/resizable-root/setup.ts +4 -20
  67. package/src/components/resizable/resizable-root/types.ts +1 -4
  68. package/src/components/table-handle/context.ts +2 -8
  69. package/src/components/table-handle/dnd.ts +9 -15
  70. package/src/components/table-handle/hooks/use-drop.ts +2 -11
  71. package/src/components/table-handle/table-handle-column-root/setup.ts +2 -13
  72. package/src/components/table-handle/table-handle-column-root/types.ts +1 -4
  73. package/src/components/table-handle/table-handle-column-trigger/setup.ts +3 -14
  74. package/src/components/table-handle/table-handle-column-trigger/types.ts +1 -4
  75. package/src/components/table-handle/table-handle-drag-preview/render-preview.ts +1 -4
  76. package/src/components/table-handle/table-handle-drag-preview/setup.ts +3 -13
  77. package/src/components/table-handle/table-handle-drag-preview/types.ts +1 -4
  78. package/src/components/table-handle/table-handle-drag-preview/updater.ts +3 -14
  79. package/src/components/table-handle/table-handle-drop-indicator/setup.ts +6 -10
  80. package/src/components/table-handle/table-handle-drop-indicator/types.ts +1 -4
  81. package/src/components/table-handle/table-handle-drop-indicator/updater.ts +5 -19
  82. package/src/components/table-handle/table-handle-popover-content/setup.ts +2 -9
  83. package/src/components/table-handle/table-handle-popover-content/types.ts +2 -10
  84. package/src/components/table-handle/table-handle-popover-item/setup.ts +2 -8
  85. package/src/components/table-handle/table-handle-popover-item/types.ts +2 -10
  86. package/src/components/table-handle/table-handle-root/setup.ts +2 -9
  87. package/src/components/table-handle/table-handle-root/types.ts +1 -4
  88. package/src/components/table-handle/table-handle-row-root/setup.ts +2 -9
  89. package/src/components/table-handle/table-handle-row-root/types.ts +2 -9
  90. package/src/components/table-handle/table-handle-row-trigger/setup.ts +3 -14
  91. package/src/components/table-handle/table-handle-row-trigger/types.ts +1 -4
  92. package/src/components/table-handle/utils.ts +1 -4
  93. package/src/components/tooltip/tooltip-content/types.ts +2 -8
  94. package/src/components/tooltip/tooltip-root/types.ts +2 -8
  95. package/src/components/tooltip/tooltip-trigger/types.ts +2 -8
  96. package/src/hooks/use-editor-extension.ts +2 -9
  97. package/src/hooks/use-editor-focus-event.ts +2 -9
  98. package/src/hooks/use-editor-typing.ts +2 -10
  99. package/src/hooks/use-editor-update-event.ts +2 -9
  100. package/src/hooks/use-first-rendering.ts +1 -6
  101. package/src/hooks/use-keymap.ts +2 -9
  102. package/src/hooks/use-scrolling.ts +3 -6
  103. package/src/hooks/use-selecting.ts +1 -5
  104. package/src/index.ts +1 -1
  105. package/src/queue-extension.ts +93 -0
  106. package/src/utils/get-default-state.spec.ts +2 -10
  107. package/src/utils/get-default-state.ts +1 -5
  108. package/dist/get-default-state-Bqluw34o.js.map +0 -1
  109. package/dist/inject-style-DYQXx-cE.js.map +0 -1
  110. package/dist/use-editor-extension-B_5BbYvf.js.map +0 -1
  111. package/dist/use-scrolling-BjI3cuLt.js.map +0 -1
package/src/index.ts CHANGED
@@ -1 +1 @@
1
- export {}
1
+ export { queueExtension } from './queue-extension'
@@ -0,0 +1,93 @@
1
+ import type { Editor, Extension } from '@prosekit/core'
2
+
3
+ /**
4
+
5
+ @internal
6
+
7
+ Queues an extension to be added to the editor in the next task. Returns a
8
+ dispose function that can be used to remove the extension in the next task.
9
+
10
+ Why?
11
+
12
+ Let's take React as an example.
13
+
14
+ `editor.use(extension)` is synchronous. If the extension adds a node view that
15
+ is controlled by `@prosemirror-adapter/react`, adding this extension will
16
+ cause `prosemirror-adapter` to set UI state synchronously (e.g. `setState`
17
+ returned by `useState` in React).
18
+
19
+ ProseMirror is a sync-based framework. When updating node view, ProseMirror
20
+ will first stop DOMObserver, then update the DOM, then resume DOMObserver.
21
+ `prosemirror-adapter` needs to call `React.flushSync()` to update the DOM
22
+ synchronously right after React state is updated, before ProseMirror resumes
23
+ DOMObserver.
24
+
25
+ If we call `editor.use(extension)` directly in `useEffect`, we eventually are
26
+ doing something like this:
27
+
28
+ ```ts
29
+ React.useEffect(() => {
30
+ React.flushSync(() => {
31
+ setState(newState)
32
+ })
33
+ }, [])
34
+ ```
35
+
36
+ This breaks the async nature of React, and causes the following React
37
+ warning:
38
+
39
+ ```
40
+ flushSync was called from inside a lifecycle method. React cannot flush when
41
+ React is already rendering. Consider moving this call to a scheduler task or
42
+ micro task.
43
+ ```
44
+
45
+ To fix this, we need to queue the extension addition to the editor in the next
46
+ task or in the next microtask.
47
+
48
+ ```ts
49
+ // In the next microtask
50
+ React.useEffect(() => {
51
+ queueMicrotask(() => {
52
+ React.flushSync(() => {
53
+ setState(newState)
54
+ })
55
+ })
56
+ }, [])
57
+
58
+ // In the next task
59
+ React.useEffect(() => {
60
+ setTimeout(() => {
61
+ React.flushSync(() => {
62
+ setState(newState)
63
+ })
64
+ })
65
+ }, [])
66
+ ```
67
+
68
+ I chose to use `setTimeout` instead of `queueMicrotask` because
69
+ `queueMicrotask` causes another React act warning `An update to %s inside a
70
+ test was not wrapped in act(...)` during testing.
71
+
72
+ Although the example above is based on React, this is a general pattern for
73
+ any async based UI framework, including Svelte.
74
+
75
+ */
76
+ export function queueExtension(editor: Editor, extension: Extension): VoidFunction {
77
+ let canceled = false
78
+ let dispose: VoidFunction | undefined
79
+ const timeout = setTimeout(() => {
80
+ if (canceled) return
81
+ dispose?.()
82
+ dispose = editor.use(extension)
83
+ })
84
+
85
+ return () => {
86
+ canceled = true
87
+ clearTimeout(timeout)
88
+ setTimeout(() => {
89
+ dispose?.()
90
+ dispose = undefined
91
+ })
92
+ }
93
+ }
@@ -1,13 +1,5 @@
1
- import {
2
- createSignal,
3
- type PropDeclarations,
4
- type SignalState,
5
- } from '@aria-ui/core'
6
- import {
7
- describe,
8
- expect,
9
- it,
10
- } from 'vitest'
1
+ import { createSignal, type PropDeclarations, type SignalState } from '@aria-ui/core'
2
+ import { describe, expect, it } from 'vitest'
11
3
 
12
4
  import { getStateWithDefaults } from './get-default-state'
13
5
 
@@ -1,8 +1,4 @@
1
- import {
2
- createSignal,
3
- type PropDeclarations,
4
- type SignalState,
5
- } from '@aria-ui/core'
1
+ import { createSignal, type PropDeclarations, type SignalState } from '@aria-ui/core'
6
2
 
7
3
  export function getStateWithDefaults<
8
4
  Props extends Record<string, any> = Record<string, any>,
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-default-state-Bqluw34o.js","names":[],"sources":["../src/utils/get-default-state.ts"],"sourcesContent":["import {\n createSignal,\n type PropDeclarations,\n type SignalState,\n} from '@aria-ui/core'\n\nexport function getStateWithDefaults<\n Props extends Record<string, any> = Record<string, any>,\n>(\n state: Partial<SignalState<Props>>,\n props: PropDeclarations<Props>,\n): SignalState<Props> {\n const merged = { ...state } as SignalState<Props>\n\n for (const key of Object.keys(props) as (keyof Props)[]) {\n if (!merged[key]) {\n merged[key] = createSignal(props[key].default)\n }\n }\n\n return merged\n}\n"],"mappings":";;;AAMA,SAAgB,qBAGd,OACA,OACoB;CACpB,MAAM,SAAS,EAAE,GAAG,OAAO;AAE3B,MAAK,MAAM,OAAO,OAAO,KAAK,MAAM,CAClC,KAAI,CAAC,OAAO,KACV,QAAO,OAAO,aAAa,MAAM,KAAK,QAAQ;AAIlD,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"inject-style-DYQXx-cE.js","names":["styles: string[]","source","target","cssProps: string[]"],"sources":["../src/utils/clone-element.ts","../src/utils/inject-style.ts"],"sourcesContent":["import { getId } from '@ocavue/utils'\n\n/**\n * Creates a deep clone of an Element, including all computed styles so that\n * it looks almost exactly the same as the original element.\n */\nexport function deepCloneElement<T extends Element>(element: T, important = false): [T, string] {\n const clonedElement = element.cloneNode(true) as T\n const style = deepCopyStyles(element, clonedElement, important)\n return [clonedElement, style]\n}\n\n/**\n * Creates a clone of an Element, including all computed styles so that\n * it looks similar enough to the original element.\n */\nexport function cloneElement<T extends Element>(element: T, important = false): [T, string] {\n const clonedElement = element.cloneNode() as T\n const style = copyStyles(element, clonedElement, important)\n return [clonedElement, style]\n}\n\nfunction deepCopyStyles(source: Element, target: Element, important: boolean): string {\n const sources = [source]\n const targets = [target]\n const styles: string[] = []\n\n while (sources.length > 0 && sources.length === targets.length) {\n const source = sources.pop()\n const target = targets.pop()\n\n if (!source || !target) {\n break\n }\n\n const style = copyStyles(source, target, important)\n if (style) {\n styles.push(style)\n }\n\n sources.push(...source.children)\n targets.push(...target.children)\n }\n\n return styles.join('\\n')\n}\n\nfunction copyStyles(source: Element, target: Element, important: boolean): string {\n if (!source || !target) {\n return ''\n }\n\n const view = source.ownerDocument?.defaultView\n if (!view) {\n return ''\n }\n\n // Known issue: pseudo styles are not copied.\n const sourceStyle = view.getComputedStyle(source)\n const targetStyle = (target as HTMLElement | SVGElement | MathMLElement).style\n\n if (!sourceStyle || !targetStyle) {\n return ''\n }\n\n for (const key of sourceStyle) {\n targetStyle.setProperty(\n key,\n sourceStyle.getPropertyValue(key),\n // Enforce important to avoid the style being overridden when the element\n // is connected to the page.\n // See https://github.com/prosekit/prosekit/issues/1185 for more details.\n important ? 'important' : (sourceStyle.getPropertyPriority(key) || ''),\n )\n }\n\n const styles: string[] = []\n for (const pseudoSelector of [':before', ':after']) {\n const sourcePseudoStyle = view.getComputedStyle(source, pseudoSelector)\n const targetPseudoStyle = view.getComputedStyle(target, pseudoSelector)\n\n if (!sourcePseudoStyle) {\n continue\n }\n\n const content = sourcePseudoStyle.getPropertyValue('content')\n const hasPseudoElement = content && content !== 'none' && content !== 'normal'\n\n if (!hasPseudoElement) {\n continue\n }\n\n const cssProps: string[] = []\n for (const property of sourcePseudoStyle) {\n const sourceValue = sourcePseudoStyle.getPropertyValue(property)\n const sourcePriority = sourcePseudoStyle.getPropertyPriority(property)\n const targetValue = targetPseudoStyle.getPropertyValue(property)\n const targetPriority = targetPseudoStyle.getPropertyPriority(property)\n if (sourceValue !== targetValue || sourcePriority !== targetPriority) {\n cssProps.push(`${property}: ${sourceValue}${sourcePriority ? ' !important' : ''};`)\n }\n }\n\n const uniqueClassName = `clone-pseudo-element-${getId()}`\n target.classList.add(uniqueClassName)\n styles.push(`.${uniqueClassName}${pseudoSelector} { ${cssProps.join(' ')} }`)\n }\n\n return styles.join('\\n')\n}\n","import { getDocument } from '@ocavue/utils'\n\nexport function injectStyle(container: HTMLElement, styleText: string): void {\n if (!styleText) {\n return\n }\n const document = getDocument(container)\n const style = document.createElement('style')\n style.textContent = styleText\n container.appendChild(style)\n}\n"],"mappings":";;;;;;;AAMA,SAAgB,iBAAoC,SAAY,YAAY,OAAoB;CAC9F,MAAM,gBAAgB,QAAQ,UAAU,KAAK;AAE7C,QAAO,CAAC,eADM,eAAe,SAAS,eAAe,UAAU,CAClC;;;;;;AAO/B,SAAgB,aAAgC,SAAY,YAAY,OAAoB;CAC1F,MAAM,gBAAgB,QAAQ,WAAW;AAEzC,QAAO,CAAC,eADM,WAAW,SAAS,eAAe,UAAU,CAC9B;;AAG/B,SAAS,eAAe,QAAiB,QAAiB,WAA4B;CACpF,MAAM,UAAU,CAAC,OAAO;CACxB,MAAM,UAAU,CAAC,OAAO;CACxB,MAAMA,SAAmB,EAAE;AAE3B,QAAO,QAAQ,SAAS,KAAK,QAAQ,WAAW,QAAQ,QAAQ;EAC9D,MAAMC,WAAS,QAAQ,KAAK;EAC5B,MAAMC,WAAS,QAAQ,KAAK;AAE5B,MAAI,CAACD,YAAU,CAACC,SACd;EAGF,MAAM,QAAQ,WAAWD,UAAQC,UAAQ,UAAU;AACnD,MAAI,MACF,QAAO,KAAK,MAAM;AAGpB,UAAQ,KAAK,GAAGD,SAAO,SAAS;AAChC,UAAQ,KAAK,GAAGC,SAAO,SAAS;;AAGlC,QAAO,OAAO,KAAK,KAAK;;AAG1B,SAAS,WAAW,QAAiB,QAAiB,WAA4B;AAChF,KAAI,CAAC,UAAU,CAAC,OACd,QAAO;CAGT,MAAM,OAAO,OAAO,eAAe;AACnC,KAAI,CAAC,KACH,QAAO;CAIT,MAAM,cAAc,KAAK,iBAAiB,OAAO;CACjD,MAAM,cAAe,OAAoD;AAEzE,KAAI,CAAC,eAAe,CAAC,YACnB,QAAO;AAGT,MAAK,MAAM,OAAO,YAChB,aAAY,YACV,KACA,YAAY,iBAAiB,IAAI,EAIjC,YAAY,cAAe,YAAY,oBAAoB,IAAI,IAAI,GACpE;CAGH,MAAMF,SAAmB,EAAE;AAC3B,MAAK,MAAM,kBAAkB,CAAC,WAAW,SAAS,EAAE;EAClD,MAAM,oBAAoB,KAAK,iBAAiB,QAAQ,eAAe;EACvE,MAAM,oBAAoB,KAAK,iBAAiB,QAAQ,eAAe;AAEvE,MAAI,CAAC,kBACH;EAGF,MAAM,UAAU,kBAAkB,iBAAiB,UAAU;AAG7D,MAAI,EAFqB,WAAW,YAAY,UAAU,YAAY,UAGpE;EAGF,MAAMG,WAAqB,EAAE;AAC7B,OAAK,MAAM,YAAY,mBAAmB;GACxC,MAAM,cAAc,kBAAkB,iBAAiB,SAAS;GAChE,MAAM,iBAAiB,kBAAkB,oBAAoB,SAAS;GACtE,MAAM,cAAc,kBAAkB,iBAAiB,SAAS;GAChE,MAAM,iBAAiB,kBAAkB,oBAAoB,SAAS;AACtE,OAAI,gBAAgB,eAAe,mBAAmB,eACpD,UAAS,KAAK,GAAG,SAAS,IAAI,cAAc,iBAAiB,gBAAgB,GAAG,GAAG;;EAIvF,MAAM,kBAAkB,wBAAwB,OAAO;AACvD,SAAO,UAAU,IAAI,gBAAgB;AACrC,SAAO,KAAK,IAAI,kBAAkB,eAAe,KAAK,SAAS,KAAK,IAAI,CAAC,IAAI;;AAG/E,QAAO,OAAO,KAAK,KAAK;;;;;AC1G1B,SAAgB,YAAY,WAAwB,WAAyB;AAC3E,KAAI,CAAC,UACH;CAGF,MAAM,QADW,YAAY,UAAU,CAChB,cAAc,QAAQ;AAC7C,OAAM,cAAc;AACpB,WAAU,YAAY,MAAM"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-editor-extension-B_5BbYvf.js","names":[],"sources":["../src/hooks/use-editor-extension.ts"],"sourcesContent":["import {\n useEffect,\n type ConnectableElement,\n type ReadonlySignal,\n} from '@aria-ui/core'\nimport type {\n Editor,\n Extension,\n} from '@prosekit/core'\n\nexport function useEditorExtension(\n host: ConnectableElement,\n editor: ReadonlySignal<Editor | null>,\n extension: Extension,\n): void {\n useEffect(host, () => {\n return editor.get()?.use(extension)\n })\n}\n"],"mappings":";;;AAUA,SAAgB,mBACd,MACA,QACA,WACM;AACN,WAAU,YAAY;AACpB,SAAO,OAAO,KAAK,EAAE,IAAI,UAAU;GACnC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-scrolling-BjI3cuLt.js","names":[],"sources":["../src/utils/assign-styles.ts","../src/hooks/use-scrolling.ts"],"sourcesContent":["import type { ConditionalPick } from 'type-fest'\n\n// Only include CSS properties whose value type is `string`\ntype StringStyleDeclaration = Partial<ConditionalPick<CSSStyleDeclaration, string>>\n\n/**\n * A type-safe version of `Object.assign` for `element.style`.\n */\nexport function assignStyles(\n element: HTMLElement | SVGElement | MathMLElement,\n styles: StringStyleDeclaration,\n): void {\n Object.assign(element.style, styles)\n}\n","import {\n createSignal,\n useEffect,\n type ConnectableElement,\n type ReadonlySignal,\n} from '@aria-ui/core'\nimport { getNearestOverflowAncestor } from '@zag-js/dom-query'\n\nexport function useScrolling(host: ConnectableElement): ReadonlySignal<boolean> {\n const scrolling = createSignal(false)\n\n useEffect(host, () => {\n const scrollableParent = getNearestOverflowAncestor(host)\n\n const handleScroll = () => {\n scrolling.set(true)\n }\n\n const handleMouseMove = () => {\n scrolling.set(false)\n }\n\n scrollableParent.addEventListener('scroll', handleScroll, { passive: true })\n window.addEventListener('mousemove', handleMouseMove, { passive: true })\n\n return () => {\n scrollableParent.removeEventListener('scroll', handleScroll)\n window.removeEventListener('mousemove', handleMouseMove)\n }\n })\n\n return scrolling\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,aACd,SACA,QACM;AACN,QAAO,OAAO,QAAQ,OAAO,OAAO;;;;;ACJtC,SAAgB,aAAa,MAAmD;CAC9E,MAAM,YAAY,aAAa,MAAM;AAErC,WAAU,YAAY;EACpB,MAAM,mBAAmB,2BAA2B,KAAK;EAEzD,MAAM,qBAAqB;AACzB,aAAU,IAAI,KAAK;;EAGrB,MAAM,wBAAwB;AAC5B,aAAU,IAAI,MAAM;;AAGtB,mBAAiB,iBAAiB,UAAU,cAAc,EAAE,SAAS,MAAM,CAAC;AAC5E,SAAO,iBAAiB,aAAa,iBAAiB,EAAE,SAAS,MAAM,CAAC;AAExE,eAAa;AACX,oBAAiB,oBAAoB,UAAU,aAAa;AAC5D,UAAO,oBAAoB,aAAa,gBAAgB;;GAE1D;AAEF,QAAO"}