@k2b/ui 0.26.0 → 0.28.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 (231) hide show
  1. package/README.md +1 -1
  2. package/dist/base.css +147 -2
  3. package/dist/browser/actions/ContextMenu.js +30 -4
  4. package/dist/browser/actions/ContextMenu.js.map +1 -1
  5. package/dist/browser/actions/Dropdown.js +184 -158
  6. package/dist/browser/actions/Dropdown.js.map +1 -1
  7. package/dist/browser/actions/GestureMenu.js +71 -138
  8. package/dist/browser/actions/GestureMenu.js.map +1 -1
  9. package/dist/browser/actions/Toolbar.js +379 -48
  10. package/dist/browser/actions/Toolbar.js.map +1 -1
  11. package/dist/browser/actions/index.js.map +1 -1
  12. package/dist/browser/actions/menu-rows.js +15 -0
  13. package/dist/browser/actions/menu-rows.js.map +1 -0
  14. package/dist/browser/actions/menu-sheet.js +154 -0
  15. package/dist/browser/actions/menu-sheet.js.map +1 -0
  16. package/dist/browser/actions/toolbar-messages.js +20 -0
  17. package/dist/browser/actions/toolbar-messages.js.map +1 -0
  18. package/dist/browser/chart-inspection.js +3 -0
  19. package/dist/browser/chart-inspection.js.map +1 -0
  20. package/dist/browser/chat/ChatComposer.js +1020 -431
  21. package/dist/browser/chat/ChatComposer.js.map +1 -1
  22. package/dist/browser/chat/chat-behavior.js +4 -0
  23. package/dist/browser/chat/chat-behavior.js.map +1 -1
  24. package/dist/browser/chat/chat-messages.js +33 -1
  25. package/dist/browser/chat/chat-messages.js.map +1 -1
  26. package/dist/browser/chat/command-search.js +173 -0
  27. package/dist/browser/chat/command-search.js.map +1 -0
  28. package/dist/browser/chat/composer-document.js +1 -1
  29. package/dist/browser/chat/composer-document.js.map +1 -1
  30. package/dist/browser/chat/index.js +2 -0
  31. package/dist/browser/chat/index.js.map +1 -1
  32. package/dist/browser/chat/reaction-people.js +15 -0
  33. package/dist/browser/chat/reaction-people.js.map +1 -0
  34. package/dist/browser/content/CalendarDayView.js +28 -3
  35. package/dist/browser/content/CalendarDayView.js.map +1 -1
  36. package/dist/browser/content/Chart.js +6 -15
  37. package/dist/browser/content/Chart.js.map +1 -1
  38. package/dist/browser/content/ChartSnapshotView.js +7 -10
  39. package/dist/browser/content/ChartSnapshotView.js.map +1 -1
  40. package/dist/browser/content/MessageRow.js +330 -448
  41. package/dist/browser/content/MessageRow.js.map +1 -1
  42. package/dist/browser/content/ReactionBar.js +419 -0
  43. package/dist/browser/content/ReactionBar.js.map +1 -0
  44. package/dist/browser/content/chart-inspection-core.js +557 -0
  45. package/dist/browser/content/chart-inspection-core.js.map +1 -0
  46. package/dist/browser/content/chart-inspection.js +10 -445
  47. package/dist/browser/content/chart-inspection.js.map +1 -1
  48. package/dist/browser/content/chart-line-gaps.js +1 -1
  49. package/dist/browser/content/chart-line-gaps.js.map +1 -1
  50. package/dist/browser/content/chart-snapshot.js +1 -1
  51. package/dist/browser/content/chart-snapshot.js.map +1 -1
  52. package/dist/browser/content/index.js +1 -0
  53. package/dist/browser/content/index.js.map +1 -1
  54. package/dist/browser/feedback/dialog-core.js +135 -23
  55. package/dist/browser/feedback/dialog-core.js.map +1 -1
  56. package/dist/browser/index.js +1 -0
  57. package/dist/browser/index.js.map +1 -1
  58. package/dist/browser/input-mode.js +40 -0
  59. package/dist/browser/input-mode.js.map +1 -0
  60. package/dist/browser/inputs/Combobox.js +4 -2
  61. package/dist/browser/inputs/Combobox.js.map +1 -1
  62. package/dist/browser/inputs/FileDropTarget.js +24 -9
  63. package/dist/browser/inputs/FileDropTarget.js.map +1 -1
  64. package/dist/browser/inputs/FileInputs.js +2 -2
  65. package/dist/browser/inputs/FileInputs.js.map +1 -1
  66. package/dist/browser/inputs/SelectChip.js +52 -12
  67. package/dist/browser/inputs/SelectChip.js.map +1 -1
  68. package/dist/browser/inputs/emoji/EmojiPicker.js +13 -0
  69. package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -1
  70. package/dist/browser/inputs/file-drop.js.map +1 -1
  71. package/dist/browser/layout/AppWorkspace.js +708 -515
  72. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  73. package/dist/browser/layout/BottomSheet.js +8 -0
  74. package/dist/browser/layout/BottomSheet.js.map +1 -1
  75. package/dist/browser/layout/DetailPanel.js +283 -197
  76. package/dist/browser/layout/DetailPanel.js.map +1 -1
  77. package/dist/browser/layout/Discussion.js +233 -185
  78. package/dist/browser/layout/Discussion.js.map +1 -1
  79. package/dist/browser/layout/TableOfContents.js +10 -2
  80. package/dist/browser/layout/TableOfContents.js.map +1 -1
  81. package/dist/browser/layout/app-workspace-controller.js +155 -23
  82. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  83. package/dist/browser/layout/app-workspace-state.js +5 -1
  84. package/dist/browser/layout/app-workspace-state.js.map +1 -1
  85. package/dist/browser/layout/detail-panel-messages.js +35 -0
  86. package/dist/browser/layout/detail-panel-messages.js.map +1 -0
  87. package/dist/browser/layout/index.js +1 -1
  88. package/dist/browser/layout/index.js.map +1 -1
  89. package/dist/browser/surfaces/Avatar.js +50 -20
  90. package/dist/browser/surfaces/Avatar.js.map +1 -1
  91. package/dist/browser/surfaces/AvatarStack.js +406 -0
  92. package/dist/browser/surfaces/AvatarStack.js.map +1 -0
  93. package/dist/browser/surfaces/avatar-messages.js +8 -2
  94. package/dist/browser/surfaces/avatar-messages.js.map +1 -1
  95. package/dist/browser/surfaces/index.js +1 -0
  96. package/dist/browser/surfaces/index.js.map +1 -1
  97. package/dist/ssr/actions/ContextMenu.js +21 -3
  98. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  99. package/dist/ssr/actions/Dropdown.js +140 -72
  100. package/dist/ssr/actions/Dropdown.js.map +1 -1
  101. package/dist/ssr/actions/GestureMenu.js +52 -106
  102. package/dist/ssr/actions/GestureMenu.js.map +1 -1
  103. package/dist/ssr/actions/Toolbar.js +294 -14
  104. package/dist/ssr/actions/Toolbar.js.map +1 -1
  105. package/dist/ssr/actions/index.js.map +1 -1
  106. package/dist/ssr/actions/menu-rows.js +15 -0
  107. package/dist/ssr/actions/menu-rows.js.map +1 -0
  108. package/dist/ssr/actions/menu-sheet.js +138 -0
  109. package/dist/ssr/actions/menu-sheet.js.map +1 -0
  110. package/dist/ssr/actions/toolbar-messages.js +20 -0
  111. package/dist/ssr/actions/toolbar-messages.js.map +1 -0
  112. package/dist/ssr/chart-inspection.js +3 -0
  113. package/dist/ssr/chart-inspection.js.map +1 -0
  114. package/dist/ssr/chat/ChatComposer.js +604 -113
  115. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  116. package/dist/ssr/chat/chat-behavior.js +4 -0
  117. package/dist/ssr/chat/chat-behavior.js.map +1 -1
  118. package/dist/ssr/chat/chat-messages.js +33 -1
  119. package/dist/ssr/chat/chat-messages.js.map +1 -1
  120. package/dist/ssr/chat/command-search.js +173 -0
  121. package/dist/ssr/chat/command-search.js.map +1 -0
  122. package/dist/ssr/chat/composer-document.js +1 -1
  123. package/dist/ssr/chat/composer-document.js.map +1 -1
  124. package/dist/ssr/chat/index.js +2 -0
  125. package/dist/ssr/chat/index.js.map +1 -1
  126. package/dist/ssr/chat/reaction-people.js +15 -0
  127. package/dist/ssr/chat/reaction-people.js.map +1 -0
  128. package/dist/ssr/content/CalendarDayView.js +28 -3
  129. package/dist/ssr/content/CalendarDayView.js.map +1 -1
  130. package/dist/ssr/content/Chart.js +6 -15
  131. package/dist/ssr/content/Chart.js.map +1 -1
  132. package/dist/ssr/content/ChartSnapshotView.js +7 -10
  133. package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
  134. package/dist/ssr/content/MessageRow.js +98 -152
  135. package/dist/ssr/content/MessageRow.js.map +1 -1
  136. package/dist/ssr/content/ReactionBar.js +304 -0
  137. package/dist/ssr/content/ReactionBar.js.map +1 -0
  138. package/dist/ssr/content/chart-inspection-core.js +557 -0
  139. package/dist/ssr/content/chart-inspection-core.js.map +1 -0
  140. package/dist/ssr/content/chart-inspection.js +10 -445
  141. package/dist/ssr/content/chart-inspection.js.map +1 -1
  142. package/dist/ssr/content/chart-line-gaps.js +1 -1
  143. package/dist/ssr/content/chart-line-gaps.js.map +1 -1
  144. package/dist/ssr/content/chart-snapshot.js +1 -1
  145. package/dist/ssr/content/chart-snapshot.js.map +1 -1
  146. package/dist/ssr/content/index.js +1 -0
  147. package/dist/ssr/content/index.js.map +1 -1
  148. package/dist/ssr/feedback/dialog-core.js +135 -23
  149. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  150. package/dist/ssr/index.js +1 -0
  151. package/dist/ssr/index.js.map +1 -1
  152. package/dist/ssr/input-mode.js +40 -0
  153. package/dist/ssr/input-mode.js.map +1 -0
  154. package/dist/ssr/inputs/Combobox.js +4 -2
  155. package/dist/ssr/inputs/Combobox.js.map +1 -1
  156. package/dist/ssr/inputs/FileDropTarget.js +17 -5
  157. package/dist/ssr/inputs/FileDropTarget.js.map +1 -1
  158. package/dist/ssr/inputs/FileInputs.js +2 -2
  159. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  160. package/dist/ssr/inputs/SelectChip.js +44 -11
  161. package/dist/ssr/inputs/SelectChip.js.map +1 -1
  162. package/dist/ssr/inputs/emoji/EmojiPicker.js +12 -0
  163. package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -1
  164. package/dist/ssr/inputs/file-drop.js.map +1 -1
  165. package/dist/ssr/layout/AppWorkspace.js +242 -105
  166. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  167. package/dist/ssr/layout/BottomSheet.js +8 -0
  168. package/dist/ssr/layout/BottomSheet.js.map +1 -1
  169. package/dist/ssr/layout/DetailPanel.js +112 -58
  170. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  171. package/dist/ssr/layout/Discussion.js +63 -36
  172. package/dist/ssr/layout/Discussion.js.map +1 -1
  173. package/dist/ssr/layout/TableOfContents.js +10 -2
  174. package/dist/ssr/layout/TableOfContents.js.map +1 -1
  175. package/dist/ssr/layout/app-workspace-controller.js +155 -23
  176. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  177. package/dist/ssr/layout/app-workspace-state.js +5 -1
  178. package/dist/ssr/layout/app-workspace-state.js.map +1 -1
  179. package/dist/ssr/layout/detail-panel-messages.js +35 -0
  180. package/dist/ssr/layout/detail-panel-messages.js.map +1 -0
  181. package/dist/ssr/layout/index.js +1 -1
  182. package/dist/ssr/layout/index.js.map +1 -1
  183. package/dist/ssr/surfaces/Avatar.js +20 -2
  184. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  185. package/dist/ssr/surfaces/AvatarStack.js +286 -0
  186. package/dist/ssr/surfaces/AvatarStack.js.map +1 -0
  187. package/dist/ssr/surfaces/avatar-messages.js +8 -2
  188. package/dist/ssr/surfaces/avatar-messages.js.map +1 -1
  189. package/dist/ssr/surfaces/index.js +1 -0
  190. package/dist/ssr/surfaces/index.js.map +1 -1
  191. package/dist/styles.css +1 -1
  192. package/dist/types/actions/ContextMenu.d.ts +8 -0
  193. package/dist/types/actions/Dropdown.d.ts +12 -5
  194. package/dist/types/actions/GestureMenu.d.ts +6 -4
  195. package/dist/types/actions/Toolbar.d.ts +20 -0
  196. package/dist/types/actions/index.d.ts +1 -1
  197. package/dist/types/actions/menu-rows.d.ts +5 -0
  198. package/dist/types/actions/menu-sheet.d.ts +22 -0
  199. package/dist/types/actions/toolbar-messages.d.ts +8 -0
  200. package/dist/types/chart-inspection.d.ts +2 -0
  201. package/dist/types/chat/ChatComposer.d.ts +51 -2
  202. package/dist/types/chat/chat-behavior.d.ts +4 -0
  203. package/dist/types/chat/chat-messages.d.ts +17 -2
  204. package/dist/types/chat/command-search.d.ts +41 -0
  205. package/dist/types/chat/index.d.ts +3 -1
  206. package/dist/types/chat/reaction-people.d.ts +9 -0
  207. package/dist/types/content/Chart.d.ts +2 -2
  208. package/dist/types/content/MessageRow.d.ts +3 -10
  209. package/dist/types/content/ReactionBar.d.ts +32 -0
  210. package/dist/types/content/chart-inspection-core.d.ts +61 -0
  211. package/dist/types/content/chart-inspection.d.ts +4 -20
  212. package/dist/types/content/chart-snapshot.d.ts +1 -1
  213. package/dist/types/content/index.d.ts +2 -1
  214. package/dist/types/feedback/dialog-core.d.ts +16 -1
  215. package/dist/types/index.d.ts +1 -0
  216. package/dist/types/input-mode.d.ts +7 -0
  217. package/dist/types/inputs/FileDropTarget.d.ts +6 -3
  218. package/dist/types/inputs/SelectChip.d.ts +6 -0
  219. package/dist/types/inputs/file-drop.d.ts +2 -0
  220. package/dist/types/layout/AppWorkspace.d.ts +13 -1
  221. package/dist/types/layout/BottomSheet.d.ts +8 -0
  222. package/dist/types/layout/DetailPanel.d.ts +11 -0
  223. package/dist/types/layout/Discussion.d.ts +8 -0
  224. package/dist/types/layout/TableOfContents.d.ts +2 -0
  225. package/dist/types/layout/detail-panel-messages.d.ts +15 -0
  226. package/dist/types/layout/index.d.ts +1 -1
  227. package/dist/types/surfaces/Avatar.d.ts +12 -0
  228. package/dist/types/surfaces/AvatarStack.d.ts +41 -0
  229. package/dist/types/surfaces/avatar-messages.d.ts +3 -0
  230. package/dist/types/surfaces/index.d.ts +3 -1
  231. package/package.json +9 -4
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["inputs/emoji/EmojiPicker.tsx"],"sourcesContent":["import {\n createEffect,\n createMemo,\n createSelector,\n createSignal,\n createUniqueId,\n For,\n type JSX,\n on,\n onCleanup,\n onMount,\n Show,\n untrack,\n} from \"solid-js\";\nimport { Button } from \"../../actions/Button\";\nimport { returnFocus, ringOnReturn } from \"../../internal/focus-return\";\nimport { useLocale } from \"../../intl/locale\";\nimport { useUiMessages } from \"../../intl/messages\";\nimport {\n EMOJI_GROUPS,\n EMOJI_SKIN_TONES,\n type EmojiEntry,\n type EmojiGroupKey,\n type EmojiIndex,\n type EmojiSkinTone,\n emojiInTone,\n emojiName,\n findEmoji,\n loadEmojiIndex,\n RECENT_EMOJI_LIMIT,\n searchEmoji,\n} from \"./emoji-index\";\nimport { type EmojiMessages, useEmojiMessages } from \"./emoji-messages\";\n\n/** Emoji per row. Keyboard navigation moves by rows of this length. */\nconst COLUMNS = 8;\n/** Search results render in blocks of this many rows, so the browser lays out only the blocks in view. */\nconst RESULT_BLOCK = 8 * COLUMNS;\nconst TONE_SAMPLE = \"✋\";\nconst TONE_SAMPLE_LIGHT = \"✋\\u{1F3FB}\";\n\nexport type EmojiPickerProps = {\n /** Called with the chosen emoji, in the chosen skin tone where it has one. */\n onPick: (emoji: string) => void;\n /** Recently used emoji, most recent first, shown as the first group. The application stores them; see `rememberEmoji`. */\n recent?: readonly string[];\n /** The skin tone for emoji that have one. Defaults to `0`, the default yellow. */\n skinTone?: EmojiSkinTone;\n /** Shows the skin-tone choice. The application stores the tone and passes it back as `skinTone`. */\n onSkinToneChange?: (tone: EmojiSkinTone) => void;\n /** Escape in an empty search field asks to close the surface the picker sits in. */\n onClose?: () => void;\n /** Moves focus into the search field once the picker is shown. */\n autofocus?: boolean;\n /** The picker's accessible name. Defaults to \"Emoji\". */\n label?: string;\n class?: string;\n};\n\ntype Section = { key: EmojiGroupKey | \"recent\"; items: readonly Item[] };\ntype Item = { emoji: string; entry?: EmojiEntry };\n\nconst groupTitle = (messages: EmojiMessages, key: Section[\"key\"]): string => {\n switch (key) {\n case \"recent\":\n return messages.emojiRecent;\n case \"smileys\":\n return messages.emojiSmileys;\n case \"people\":\n return messages.emojiPeople;\n case \"animals\":\n return messages.emojiAnimals;\n case \"food\":\n return messages.emojiFood;\n case \"travel\":\n return messages.emojiTravel;\n case \"activities\":\n return messages.emojiActivities;\n case \"objects\":\n return messages.emojiObjects;\n case \"symbols\":\n return messages.emojiSymbols;\n case \"flags\":\n return messages.emojiFlags;\n }\n};\n\nconst toneLabel = (messages: EmojiMessages, tone: EmojiSkinTone): string =>\n [\n messages.emojiToneDefault,\n messages.emojiToneLight,\n messages.emojiToneMediumLight,\n messages.emojiToneMedium,\n messages.emojiToneMediumDark,\n messages.emojiToneDark,\n ][tone]!;\n\nconst toneSample = (tone: EmojiSkinTone): string =>\n tone === 0 ? TONE_SAMPLE : TONE_SAMPLE_LIGHT.replace(\"\\u{1F3FB}\", String.fromCodePoint(0x1f3fb + tone - 1));\n\n/** Where `index` moves for an arrow key in rows of `COLUMNS`, where every section starts a new row. */\nexport const nextEmojiIndex = (\n sizes: readonly number[],\n index: number,\n key: \"ArrowLeft\" | \"ArrowRight\" | \"ArrowUp\" | \"ArrowDown\",\n): number => {\n const total = sizes.reduce((sum, size) => sum + size, 0);\n if (total === 0) return -1;\n if (index < 0) return 0;\n if (key === \"ArrowLeft\") return Math.max(0, index - 1);\n if (key === \"ArrowRight\") return Math.min(total - 1, index + 1);\n const starts: number[] = [];\n sizes.reduce((start, size) => (starts.push(start), start + size), 0);\n const section = starts.findLastIndex((start, position) => start <= index && sizes[position]! > 0);\n const offset = index - starts[section]!;\n const column = offset % COLUMNS;\n const size = sizes[section]!;\n if (key === \"ArrowUp\") {\n if (offset >= COLUMNS) return index - COLUMNS;\n for (let previous = section - 1; previous >= 0; previous--) {\n if (!sizes[previous]) continue;\n const lastRow = Math.floor((sizes[previous]! - 1) / COLUMNS) * COLUMNS;\n return starts[previous]! + Math.min(lastRow + column, sizes[previous]! - 1);\n }\n return index;\n }\n if (offset + COLUMNS < size) return index + COLUMNS;\n // A shorter last row: the last emoji of the section is below.\n if (Math.floor(offset / COLUMNS) < Math.floor((size - 1) / COLUMNS)) return starts[section]! + size - 1;\n for (let next = section + 1; next < sizes.length; next++) {\n if (sizes[next]) return starts[next]! + Math.min(column, sizes[next]! - 1);\n }\n return index;\n};\n\n/**\n * A search field, the groups, and a grid of emoji. Search finds English and German names, keywords and GitHub\n * shortcodes. The focus stays in the search field: arrow keys move through the grid, Enter picks.\n */\nfunction EmojiPickerPanel(props: EmojiPickerProps): JSX.Element {\n const messages = useUiMessages();\n const text = useEmojiMessages();\n const locale = useLocale();\n const id = `k2b-emoji-${createUniqueId().replace(/[^A-Za-z0-9_-]/g, \"-\")}`;\n const [index, setIndex] = createSignal<EmojiIndex>();\n const [failed, setFailed] = createSignal(false);\n const [query, setQuery] = createSignal(\"\");\n const [active, setActive] = createSignal(0);\n const isActive = createSelector(active);\n const [tonesOpen, setTonesOpen] = createSignal(false);\n const [currentGroup, setCurrentGroup] = createSignal<Section[\"key\"]>();\n /** Up or down moved into the grid; from then on, left and right move there too, until the search changes. */\n const [gridEntered, setGridEntered] = createSignal(false);\n let searchRef: HTMLInputElement | undefined;\n let scrollRef: HTMLDivElement | undefined;\n let toneButtonRef: HTMLButtonElement | undefined;\n let tonesRef: HTMLDivElement | undefined;\n let groupsRef: HTMLDivElement | undefined;\n /** Keyboard moves scroll the active emoji into view; the pointer does not. */\n let revealActive = false;\n\n const load = () => {\n setFailed(false);\n loadEmojiIndex().then(setIndex, () => setFailed(true));\n };\n onMount(load);\n\n const tone = () => props.skinTone ?? 0;\n const searching = () => query().trim().length > 0;\n // The groups render once and stay while a search shows its results above them, so clearing a search is instant.\n const groups = createMemo((): readonly Section[] => {\n const data = index();\n if (!data) return [];\n const recent: Section = {\n key: \"recent\",\n items: (props.recent ?? []).slice(0, RECENT_EMOJI_LIMIT).map((emoji) => ({ emoji, entry: findEmoji(data, emoji) })),\n };\n const all = EMOJI_GROUPS.map(\n (group): Section => ({\n key: group.key,\n items: data.entries.filter((entry) => entry.group === group.id).map((entry) => ({ emoji: emojiInTone(entry, tone()), entry })),\n }),\n );\n return recent.items.length ? [recent, ...all] : all;\n });\n const groupStarts = createMemo(() => {\n const starts: number[] = [];\n groups().reduce((start, section) => (starts.push(start), start + section.items.length), 0);\n return starts;\n });\n const results = createMemo((): readonly Item[] => {\n const data = index();\n if (!data || !searching()) return [];\n return searchEmoji(data, query()).map((entry) => ({ emoji: emojiInTone(entry, tone()), entry }));\n });\n const resultBlocks = createMemo(() =>\n Array.from({ length: Math.ceil(results().length / RESULT_BLOCK) }, (_, block) =>\n results().slice(block * RESULT_BLOCK, (block + 1) * RESULT_BLOCK),\n ),\n );\n /** The sizes of the visible sections, for the arrow keys. */\n const sizes = () => (searching() ? [results().length] : groups().map((section) => section.items.length));\n const items = createMemo(() => (searching() ? results() : groups().flatMap((section) => section.items)));\n const activeItem = () => items()[active()];\n const optionId = (position: number, list = searching() ? \"r\" : \"g\") => `${id}-${list}${position}`;\n const nameOf = (item: Item) => (item.entry ? emojiName(item.entry, locale()) : item.emoji);\n /** Where an element sits in the list, from its top. */\n const offsetOf = (element: Element) =>\n element.getBoundingClientRect().top - scrollRef!.getBoundingClientRect().top + scrollRef!.scrollTop;\n\n // A new search starts at its best match; the groups at their top.\n createEffect(\n on([query, index], () => {\n setActive(0);\n if (scrollRef) scrollRef.scrollTop = 0;\n }),\n );\n\n createEffect(() => {\n const position = active();\n if (!revealActive) return;\n revealActive = false;\n const option = document.getElementById(optionId(position));\n if (!option || !scrollRef) return;\n // Sticky group titles cover the top of the list; an emoji in a first row scrolls with its title.\n const covered = option.closest(\"[role='group']\")?.querySelector<HTMLElement>(\"[data-emoji-heading]\")?.offsetHeight ?? 0;\n const top = offsetOf(option) - covered;\n const bottom = offsetOf(option) + option.offsetHeight;\n if (top < scrollRef.scrollTop) scrollRef.scrollTop = top;\n else if (bottom > scrollRef.scrollTop + scrollRef.clientHeight) scrollRef.scrollTop = bottom - scrollRef.clientHeight;\n });\n\n /** The group whose title sits at the top of the list, for the group bar. */\n const syncGroup = () => {\n if (!scrollRef || searching()) return;\n const top = scrollRef.scrollTop + 1;\n let current: Section[\"key\"] | undefined;\n for (const group of scrollRef.querySelectorAll<HTMLElement>(\"[data-emoji-group]\")) {\n if (offsetOf(group) <= top) current = group.dataset.emojiGroup as Section[\"key\"];\n }\n setCurrentGroup(current ?? groups()[0]?.key);\n };\n createEffect(on([groups, searching], () => queueMicrotask(syncGroup)));\n\n onMount(() => {\n if (props.autofocus) queueMicrotask(() => searchRef?.focus({ preventScroll: true }));\n });\n\n const pick = (item: Item | undefined) => {\n if (item) props.onPick(item.emoji);\n };\n\n const showGroup = (key: Section[\"key\"]) => {\n setQuery(\"\");\n queueMicrotask(() => {\n const group = scrollRef?.querySelector<HTMLElement>(`[data-emoji-group=\"${key}\"]`);\n if (!group || !scrollRef) return;\n scrollRef.scrollTop = offsetOf(group);\n const position = groups().findIndex((section) => section.key === key);\n if (position >= 0) setActive(groupStarts()[position]!);\n syncGroup();\n });\n };\n\n const onSearchKeyDown = (event: KeyboardEvent) => {\n // WebKit ends the composition before the keydown of the Enter that confirms it; that keydown keeps keyCode 229.\n if (event.isComposing || event.keyCode === 229) return;\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\" || event.key === \"ArrowUp\" || event.key === \"ArrowDown\") {\n // Left and right edit a search until up or down enters the grid.\n if ((event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") && query() && !gridEntered()) return;\n event.preventDefault();\n revealActive = true;\n setGridEntered(true);\n setActive(nextEmojiIndex(sizes(), active(), event.key));\n return;\n }\n if (event.key === \"Enter\") {\n event.preventDefault();\n pick(activeItem());\n return;\n }\n if (event.key === \"Escape\") {\n if (query()) {\n event.preventDefault();\n event.stopPropagation();\n setQuery(\"\");\n return;\n }\n if (props.onClose) {\n event.preventDefault();\n event.stopPropagation();\n props.onClose();\n }\n }\n };\n\n const openTones = () => {\n setTonesOpen(true);\n queueMicrotask(() => tonesRef?.querySelector<HTMLElement>(\"[aria-checked='true']\")?.focus());\n };\n const closeTones = (focusButton: boolean) => {\n setTonesOpen(false);\n if (focusButton) queueMicrotask(() => toneButtonRef?.focus());\n };\n /** As in any radio group, the arrow keys choose; Enter, Space, a click or Escape close the choice. */\n const onTonesKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\" || event.key === \"ArrowUp\" || event.key === \"ArrowDown\") {\n event.preventDefault();\n const step = event.key === \"ArrowLeft\" || event.key === \"ArrowUp\" ? -1 : 1;\n const next = EMOJI_SKIN_TONES[(tone() + step + EMOJI_SKIN_TONES.length) % EMOJI_SKIN_TONES.length]!;\n props.onSkinToneChange?.(next);\n queueMicrotask(() => tonesRef?.querySelector<HTMLElement>(`[data-tone=\"${next}\"]`)?.focus());\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n closeTones(true);\n }\n };\n\n /** The group bar is one tab stop; arrow keys move along it. */\n const onGroupsKeyDown = (event: KeyboardEvent) => {\n const buttons = [...(groupsRef?.querySelectorAll<HTMLButtonElement>(\"button\") ?? [])];\n const current = buttons.indexOf(document.activeElement as HTMLButtonElement);\n const target =\n event.key === \"ArrowLeft\"\n ? current - 1\n : event.key === \"ArrowRight\"\n ? current + 1\n : event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? buttons.length - 1\n : undefined;\n if (target === undefined) return;\n event.preventDefault();\n buttons[(target + buttons.length) % buttons.length]?.focus();\n };\n const groupKeys = createMemo((): Section[\"key\"][] => [\n ...(props.recent?.length ? ([\"recent\"] as const) : []),\n ...EMOJI_GROUPS.map((group) => group.key),\n ]);\n const groupIcon = (key: Section[\"key\"]) =>\n key === \"recent\" ? \"ti ti-clock\" : (EMOJI_GROUPS.find((group) => group.key === key)?.icon ?? \"ti ti-mood-smile\");\n const tabStop = () => currentGroup() ?? groupKeys()[0];\n\n /** The grid shares its pointer listeners; the target's position says which emoji it is. */\n const itemAt = (event: Event): number | undefined => {\n const option = (event.target as Element | null)?.closest<HTMLElement>(\"[data-emoji-index]\");\n return option ? Number(option.dataset.emojiIndex) : undefined;\n };\n\n // A button, so that a tap is a click on every engine; the focus stays in the search field.\n const option = (item: Item, list: \"r\" | \"g\", position: () => number) => (\n <button\n id={optionId(position(), list)}\n type=\"button\"\n role=\"option\"\n tabIndex={-1}\n class=\"k2b-emoji-picker__option\"\n aria-selected={isActive(position())}\n aria-label={nameOf(item)}\n data-emoji-index={position()}\n data-active={isActive(position()) ? \"true\" : undefined}\n onClick={() => pick(item)}\n >\n {item.emoji}\n </button>\n );\n\n return (\n <div class={`k2b-emoji-picker ${props.class ?? \"\"}`} role=\"group\" aria-label={props.label ?? text().emojiPicker}>\n <div class=\"k2b-emoji-picker__header\">\n <div class=\"k2b-emoji-picker__search\" inert={tonesOpen()}>\n <i class=\"ti ti-search\" aria-hidden=\"true\" />\n <input\n ref={searchRef}\n type=\"search\"\n role=\"combobox\"\n aria-label={text().emojiSearch}\n aria-expanded=\"true\"\n aria-controls={`${id}-list`}\n aria-autocomplete=\"list\"\n aria-activedescendant={activeItem() ? optionId(active()) : undefined}\n placeholder={text().emojiSearch}\n autocomplete=\"off\"\n spellcheck={false}\n enterkeyhint=\"done\"\n value={query()}\n onInput={(event) => {\n setQuery(event.currentTarget.value);\n setGridEntered(false);\n }}\n onKeyDown={onSearchKeyDown}\n />\n </div>\n <Show when={props.onSkinToneChange}>\n <button\n ref={toneButtonRef}\n type=\"button\"\n class=\"k2b-emoji-picker__tone-button\"\n aria-label={text().emojiSkinTone}\n aria-haspopup=\"true\"\n aria-expanded={tonesOpen()}\n title={`${text().emojiSkinTone}: ${toneLabel(text(), tone())}`}\n inert={tonesOpen()}\n onClick={openTones}\n >\n <span aria-hidden=\"true\">{toneSample(tone())}</span>\n </button>\n {/* The tones cover the header in place, so nothing below moves. */}\n <Show when={tonesOpen()}>\n <div\n ref={tonesRef}\n class=\"k2b-emoji-picker__tones\"\n role=\"radiogroup\"\n aria-label={text().emojiSkinTone}\n onKeyDown={onTonesKeyDown}\n onFocusOut={(event) => {\n if (!tonesRef?.contains(event.relatedTarget as Node | null)) closeTones(false);\n }}\n >\n <For each={EMOJI_SKIN_TONES}>\n {(value) => (\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={value === tone()}\n aria-label={toneLabel(text(), value)}\n title={toneLabel(text(), value)}\n tabIndex={value === tone() ? 0 : -1}\n data-tone={value}\n onClick={() => {\n props.onSkinToneChange?.(value);\n closeTones(true);\n }}\n >\n <span aria-hidden=\"true\">{toneSample(value)}</span>\n </button>\n )}\n </For>\n </div>\n </Show>\n </Show>\n </div>\n\n <div ref={groupsRef} class=\"k2b-emoji-picker__groups\" role=\"toolbar\" aria-label={text().emojiGroups} onKeyDown={onGroupsKeyDown}>\n <For each={groupKeys()}>\n {(key) => (\n <button\n type=\"button\"\n aria-label={groupTitle(text(), key)}\n title={groupTitle(text(), key)}\n aria-current={!searching() && currentGroup() === key ? \"true\" : undefined}\n tabIndex={key === tabStop() ? 0 : -1}\n disabled={!index()}\n onClick={() => showGroup(key)}\n >\n <i class={groupIcon(key)} aria-hidden=\"true\" />\n </button>\n )}\n </For>\n </div>\n\n <div ref={scrollRef} class=\"k2b-emoji-picker__scroll\" onScroll={syncGroup}>\n <Show\n when={index()}\n fallback={\n <div class=\"k2b-emoji-picker__state\" role=\"status\">\n <Show\n when={failed()}\n fallback={\n <>\n <i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">{messages().loading}</span>\n </>\n }\n >\n <span>{text().emojiLoadFailed}</span>\n <Button size=\"sm\" variant=\"subtle\" onClick={load}>\n {messages().retry}\n </Button>\n </Show>\n </div>\n }\n >\n <div\n id={`${id}-list`}\n role=\"listbox\"\n class=\"k2b-emoji-picker__list\"\n aria-label={props.label ?? text().emojiPicker}\n onPointerMove={(event) => {\n const position = itemAt(event);\n if (position !== undefined && !isActive(position) && event.pointerType === \"mouse\") setActive(position);\n }}\n onMouseDown={(event) => {\n // The focus stays in the search field, where the keyboard works.\n if (itemAt(event) !== undefined) event.preventDefault();\n }}\n >\n <Show when={searching()}>\n <div role=\"group\" aria-label={messages().searchResults}>\n <For each={resultBlocks()}>\n {(block, blockIndex) => (\n <div\n class=\"k2b-emoji-picker__grid k2b-emoji-picker__block\"\n style={{ \"--k2b-emoji-rows\": String(Math.ceil(block.length / COLUMNS)) }}\n >\n <For each={block}>{(item, itemIndex) => option(item, \"r\", () => blockIndex() * RESULT_BLOCK + itemIndex())}</For>\n </div>\n )}\n </For>\n </div>\n </Show>\n <div class=\"k2b-emoji-picker__all\" hidden={searching()}>\n <For each={groups()}>\n {(section, sectionIndex) => (\n <div\n role=\"group\"\n class=\"k2b-emoji-picker__section\"\n data-emoji-group={section.key}\n aria-labelledby={`${id}-${section.key}`}\n style={{ \"--k2b-emoji-rows\": String(Math.ceil(section.items.length / COLUMNS)) }}\n >\n <div id={`${id}-${section.key}`} class=\"k2b-emoji-picker__heading\" data-emoji-heading>\n {groupTitle(text(), section.key)}\n </div>\n <div class=\"k2b-emoji-picker__grid\">\n <For each={section.items}>\n {(item, itemIndex) => option(item, \"g\", () => groupStarts()[sectionIndex()]! + itemIndex())}\n </For>\n </div>\n </div>\n )}\n </For>\n </div>\n </div>\n <Show when={searching() && results().length === 0}>\n <div class=\"k2b-emoji-picker__state\" role=\"status\">\n {text().emojiNoResults}\n </div>\n </Show>\n </Show>\n </div>\n\n <div class=\"k2b-emoji-picker__preview\" aria-hidden=\"true\">\n <Show when={activeItem()}>\n {(item) => (\n <>\n <span class=\"k2b-emoji-picker__preview-emoji\">{item().emoji}</span>\n <span class=\"k2b-emoji-picker__preview-name\">{nameOf(item())}</span>\n <Show when={item().entry?.shortcodes[0]}>{(code) => <span class=\"k2b-emoji-picker__preview-code\">:{code()}:</span>}</Show>\n </>\n )}\n </Show>\n </div>\n </div>\n );\n}\n\nexport type EmojiPickerPopoverProps = Omit<EmojiPickerProps, \"onClose\" | \"autofocus\"> & {\n /** The control the picker opens next to. The picker is open while this is set. */\n anchor: HTMLElement | null | undefined;\n /** Called after a pick, on Escape, on a click outside, and on another press of the anchor. */\n onClose: () => void;\n};\n\nconst touchOnlyQuery = \"(any-pointer: coarse) and (not (any-pointer: fine))\";\nconst GAP = 6;\nconst MARGIN = 8;\n\n/**\n * The picker next to a control, such as the composer's emoji button or a message's \"Add reaction\". It opens above the\n * control where there is room and below it otherwise, closes after a pick, and returns the focus to where it was.\n */\nfunction EmojiPickerPopover(props: EmojiPickerPopoverProps): JSX.Element {\n let surface: HTMLDivElement | undefined;\n /** Where the focus was when the picker opened, and whether a keyboard opened it. */\n let previous: HTMLElement | null = null;\n let ring = false;\n /** An anchor pressed while the picker was open closes it; the same click must not open it again. */\n let pressedAnchor: HTMLElement | undefined;\n const [shown, setShown] = createSignal<HTMLElement>();\n\n const place = () => {\n const anchor = shown();\n if (!surface || !anchor) return;\n // An anchor that left the page, such as a row a virtual list recycled, takes the picker with it.\n if (!anchor.isConnected) {\n hide();\n props.onClose();\n return;\n }\n // The visible part of the page: a phone's keyboard shrinks only the visual viewport.\n const viewport = window.visualViewport;\n const view = {\n top: (viewport?.offsetTop ?? 0) + MARGIN,\n bottom: (viewport ? viewport.offsetTop + viewport.height : window.innerHeight) - MARGIN,\n left: (viewport?.offsetLeft ?? 0) + MARGIN,\n right: (viewport ? viewport.offsetLeft + viewport.width : window.innerWidth) - MARGIN,\n };\n surface.style.setProperty(\"--k2b-emoji-popover-height\", `${Math.round(view.bottom - view.top)}px`);\n const box = anchor.getBoundingClientRect();\n const size = surface.getBoundingClientRect();\n const above = box.top - GAP - size.height;\n const below = box.bottom + GAP;\n const top = above >= view.top || below + size.height > view.bottom ? above : below;\n // Aligned with the anchor's end, like a menu at the end of a composer.\n const left = box.right - size.width;\n surface.style.left = `${Math.round(Math.max(view.left, Math.min(left, view.right - size.width)))}px`;\n surface.style.top = `${Math.round(Math.max(view.top, Math.min(top, view.bottom - size.height)))}px`;\n };\n\n const restoreFocus = () => {\n // A pick that moved the focus on purpose, such as into a composer, keeps it there.\n const focused = document.activeElement;\n if (focused && focused !== document.body && !surface?.contains(focused)) return;\n if (previous?.isConnected) returnFocus(previous, ring);\n };\n\n const hide = () => {\n restoreFocus();\n if (surface?.matches(\":popover-open\")) surface.hidePopover();\n setShown(undefined);\n };\n\n const pressed = (event: PointerEvent) => {\n const anchor = shown();\n pressedAnchor = anchor && event.target instanceof Node && anchor.contains(event.target) ? anchor : undefined;\n };\n\n /** A key press on the anchor dismisses nothing on its way, unlike a pointer: its click closes the open picker. */\n const clicked = (event: MouseEvent) => {\n const anchor = shown();\n if (!anchor || !(event.target instanceof Node) || !anchor.contains(event.target)) return;\n pressedAnchor = anchor;\n hide();\n props.onClose();\n };\n\n createEffect(() => {\n const anchor = props.anchor ?? undefined;\n untrack(() => {\n if (!anchor) {\n if (shown()) hide();\n return;\n }\n if (anchor === pressedAnchor) {\n // The press that closed the picker also asked to open it: it stays closed.\n pressedAnchor = undefined;\n props.onClose();\n return;\n }\n if (shown() === anchor || !surface) return;\n // Moving to another anchor keeps the picker open and the focus to return to.\n if (!shown()) {\n previous = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n ring = ringOnReturn(previous ?? anchor);\n }\n setShown(anchor);\n if (!surface.matches(\":popover-open\")) surface.showPopover();\n place();\n });\n });\n\n /** The page scrolled under the anchor; the picker's own list scrolling moves nothing. */\n const scrolled = (event: Event) => {\n if (!(event.target instanceof Node && surface?.contains(event.target))) place();\n };\n\n onMount(() => {\n window.addEventListener(\"resize\", place);\n window.addEventListener(\"scroll\", scrolled, true);\n window.visualViewport?.addEventListener(\"resize\", place);\n window.visualViewport?.addEventListener(\"scroll\", place);\n document.addEventListener(\"pointerdown\", pressed, true);\n document.addEventListener(\"click\", clicked, true);\n // The picker renders into the open surface after it is shown; its size places it.\n const observer = typeof ResizeObserver === \"function\" && surface ? new ResizeObserver(place) : undefined;\n if (surface) observer?.observe(surface);\n onCleanup(() => {\n observer?.disconnect();\n window.removeEventListener(\"resize\", place);\n window.removeEventListener(\"scroll\", scrolled, true);\n window.visualViewport?.removeEventListener(\"resize\", place);\n window.visualViewport?.removeEventListener(\"scroll\", place);\n document.removeEventListener(\"pointerdown\", pressed, true);\n document.removeEventListener(\"click\", clicked, true);\n if (surface?.matches(\":popover-open\")) hide();\n });\n });\n\n const touchOnly = () => typeof matchMedia === \"function\" && matchMedia(touchOnlyQuery).matches;\n\n return (\n <div\n ref={surface}\n popover=\"auto\"\n class=\"k2b-emoji-picker-popover\"\n onToggle={(event) => {\n if ((event as ToggleEvent).newState === \"open\") return;\n // Light dismissal by the browser: a click outside, Escape, or another popover.\n if (shown()) {\n setShown(undefined);\n restoreFocus();\n props.onClose();\n }\n // The pressed anchor is forgotten once its click has had the chance to reopen the picker.\n setTimeout(() => {\n pressedAnchor = undefined;\n });\n }}\n >\n <Show when={shown()}>\n <EmojiPickerPanel\n onPick={(emoji) => {\n props.onPick(emoji);\n hide();\n props.onClose();\n }}\n recent={props.recent}\n skinTone={props.skinTone}\n onSkinToneChange={props.onSkinToneChange}\n label={props.label}\n class={props.class}\n // A phone's keyboard would cover the emoji; a touch-only device searches after a tap on the field.\n autofocus={!touchOnly()}\n onClose={() => {\n hide();\n props.onClose();\n }}\n />\n </Show>\n </div>\n );\n}\n\n/** The emoji picker. `EmojiPicker.Popover` opens it next to a control. */\nexport const EmojiPicker = Object.assign(EmojiPickerPanel, { Popover: EmojiPickerPopover });\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["inputs/emoji/EmojiPicker.tsx"],"sourcesContent":["import {\n createEffect,\n createMemo,\n createSelector,\n createSignal,\n createUniqueId,\n For,\n type JSX,\n on,\n onCleanup,\n onMount,\n Show,\n untrack,\n} from \"solid-js\";\nimport { Button } from \"../../actions/Button\";\nimport { returnFocus, ringOnReturn } from \"../../internal/focus-return\";\nimport { useLocale } from \"../../intl/locale\";\nimport { useUiMessages } from \"../../intl/messages\";\nimport {\n EMOJI_GROUPS,\n EMOJI_SKIN_TONES,\n type EmojiEntry,\n type EmojiGroupKey,\n type EmojiIndex,\n type EmojiSkinTone,\n emojiInTone,\n emojiName,\n findEmoji,\n loadEmojiIndex,\n RECENT_EMOJI_LIMIT,\n searchEmoji,\n} from \"./emoji-index\";\nimport { type EmojiMessages, useEmojiMessages } from \"./emoji-messages\";\n\n/** Emoji per row. Keyboard navigation moves by rows of this length. */\nconst COLUMNS = 8;\n/** Search results render in blocks of this many rows, so the browser lays out only the blocks in view. */\nconst RESULT_BLOCK = 8 * COLUMNS;\nconst TONE_SAMPLE = \"✋\";\nconst TONE_SAMPLE_LIGHT = \"✋\\u{1F3FB}\";\n\nexport type EmojiPickerProps = {\n /** Called with the chosen emoji, in the chosen skin tone where it has one. */\n onPick: (emoji: string) => void;\n /** Recently used emoji, most recent first, shown as the first group. The application stores them; see `rememberEmoji`. */\n recent?: readonly string[];\n /** The skin tone for emoji that have one. Defaults to `0`, the default yellow. */\n skinTone?: EmojiSkinTone;\n /** Shows the skin-tone choice. The application stores the tone and passes it back as `skinTone`. */\n onSkinToneChange?: (tone: EmojiSkinTone) => void;\n /** Escape in an empty search field asks to close the surface the picker sits in. */\n onClose?: () => void;\n /** Moves focus into the search field once the picker is shown. */\n autofocus?: boolean;\n /** The picker's accessible name. Defaults to \"Emoji\". */\n label?: string;\n class?: string;\n};\n\ntype Section = { key: EmojiGroupKey | \"recent\"; items: readonly Item[] };\ntype Item = { emoji: string; entry?: EmojiEntry };\n\nconst groupTitle = (messages: EmojiMessages, key: Section[\"key\"]): string => {\n switch (key) {\n case \"recent\":\n return messages.emojiRecent;\n case \"smileys\":\n return messages.emojiSmileys;\n case \"people\":\n return messages.emojiPeople;\n case \"animals\":\n return messages.emojiAnimals;\n case \"food\":\n return messages.emojiFood;\n case \"travel\":\n return messages.emojiTravel;\n case \"activities\":\n return messages.emojiActivities;\n case \"objects\":\n return messages.emojiObjects;\n case \"symbols\":\n return messages.emojiSymbols;\n case \"flags\":\n return messages.emojiFlags;\n }\n};\n\nconst toneLabel = (messages: EmojiMessages, tone: EmojiSkinTone): string =>\n [\n messages.emojiToneDefault,\n messages.emojiToneLight,\n messages.emojiToneMediumLight,\n messages.emojiToneMedium,\n messages.emojiToneMediumDark,\n messages.emojiToneDark,\n ][tone]!;\n\nconst toneSample = (tone: EmojiSkinTone): string =>\n tone === 0 ? TONE_SAMPLE : TONE_SAMPLE_LIGHT.replace(\"\\u{1F3FB}\", String.fromCodePoint(0x1f3fb + tone - 1));\n\n/** Where `index` moves for an arrow key in rows of `COLUMNS`, where every section starts a new row. */\nexport const nextEmojiIndex = (\n sizes: readonly number[],\n index: number,\n key: \"ArrowLeft\" | \"ArrowRight\" | \"ArrowUp\" | \"ArrowDown\",\n): number => {\n const total = sizes.reduce((sum, size) => sum + size, 0);\n if (total === 0) return -1;\n if (index < 0) return 0;\n if (key === \"ArrowLeft\") return Math.max(0, index - 1);\n if (key === \"ArrowRight\") return Math.min(total - 1, index + 1);\n const starts: number[] = [];\n sizes.reduce((start, size) => (starts.push(start), start + size), 0);\n const section = starts.findLastIndex((start, position) => start <= index && sizes[position]! > 0);\n const offset = index - starts[section]!;\n const column = offset % COLUMNS;\n const size = sizes[section]!;\n if (key === \"ArrowUp\") {\n if (offset >= COLUMNS) return index - COLUMNS;\n for (let previous = section - 1; previous >= 0; previous--) {\n if (!sizes[previous]) continue;\n const lastRow = Math.floor((sizes[previous]! - 1) / COLUMNS) * COLUMNS;\n return starts[previous]! + Math.min(lastRow + column, sizes[previous]! - 1);\n }\n return index;\n }\n if (offset + COLUMNS < size) return index + COLUMNS;\n // A shorter last row: the last emoji of the section is below.\n if (Math.floor(offset / COLUMNS) < Math.floor((size - 1) / COLUMNS)) return starts[section]! + size - 1;\n for (let next = section + 1; next < sizes.length; next++) {\n if (sizes[next]) return starts[next]! + Math.min(column, sizes[next]! - 1);\n }\n return index;\n};\n\n/**\n * A search field, the groups, and a grid of emoji. Search finds English and German names, keywords and GitHub\n * shortcodes. The focus stays in the search field: arrow keys move through the grid, Enter picks.\n */\nfunction EmojiPickerPanel(props: EmojiPickerProps): JSX.Element {\n const messages = useUiMessages();\n const text = useEmojiMessages();\n const locale = useLocale();\n const id = `k2b-emoji-${createUniqueId().replace(/[^A-Za-z0-9_-]/g, \"-\")}`;\n const [index, setIndex] = createSignal<EmojiIndex>();\n const [failed, setFailed] = createSignal(false);\n const [query, setQuery] = createSignal(\"\");\n const [active, setActive] = createSignal(0);\n const isActive = createSelector(active);\n const [tonesOpen, setTonesOpen] = createSignal(false);\n const [currentGroup, setCurrentGroup] = createSignal<Section[\"key\"]>();\n /** Up or down moved into the grid; from then on, left and right move there too, until the search changes. */\n const [gridEntered, setGridEntered] = createSignal(false);\n let searchRef: HTMLInputElement | undefined;\n let scrollRef: HTMLDivElement | undefined;\n let toneButtonRef: HTMLButtonElement | undefined;\n let tonesRef: HTMLDivElement | undefined;\n let groupsRef: HTMLDivElement | undefined;\n /** Keyboard moves scroll the active emoji into view; the pointer does not. */\n let revealActive = false;\n\n const load = () => {\n setFailed(false);\n loadEmojiIndex().then(setIndex, () => setFailed(true));\n };\n onMount(load);\n\n const tone = () => props.skinTone ?? 0;\n const searching = () => query().trim().length > 0;\n // The groups render once and stay while a search shows its results above them, so clearing a search is instant.\n const groups = createMemo((): readonly Section[] => {\n const data = index();\n if (!data) return [];\n const recent: Section = {\n key: \"recent\",\n items: (props.recent ?? []).slice(0, RECENT_EMOJI_LIMIT).map((emoji) => ({ emoji, entry: findEmoji(data, emoji) })),\n };\n const all = EMOJI_GROUPS.map(\n (group): Section => ({\n key: group.key,\n items: data.entries.filter((entry) => entry.group === group.id).map((entry) => ({ emoji: emojiInTone(entry, tone()), entry })),\n }),\n );\n return recent.items.length ? [recent, ...all] : all;\n });\n const groupStarts = createMemo(() => {\n const starts: number[] = [];\n groups().reduce((start, section) => (starts.push(start), start + section.items.length), 0);\n return starts;\n });\n const results = createMemo((): readonly Item[] => {\n const data = index();\n if (!data || !searching()) return [];\n return searchEmoji(data, query()).map((entry) => ({ emoji: emojiInTone(entry, tone()), entry }));\n });\n const resultBlocks = createMemo(() =>\n Array.from({ length: Math.ceil(results().length / RESULT_BLOCK) }, (_, block) =>\n results().slice(block * RESULT_BLOCK, (block + 1) * RESULT_BLOCK),\n ),\n );\n /** The sizes of the visible sections, for the arrow keys. */\n const sizes = () => (searching() ? [results().length] : groups().map((section) => section.items.length));\n const items = createMemo(() => (searching() ? results() : groups().flatMap((section) => section.items)));\n const activeItem = () => items()[active()];\n const optionId = (position: number, list = searching() ? \"r\" : \"g\") => `${id}-${list}${position}`;\n const nameOf = (item: Item) => (item.entry ? emojiName(item.entry, locale()) : item.emoji);\n /** Where an element sits in the list, from its top. */\n const offsetOf = (element: Element) =>\n element.getBoundingClientRect().top - scrollRef!.getBoundingClientRect().top + scrollRef!.scrollTop;\n\n // A new search starts at its best match; the groups at their top.\n createEffect(\n on([query, index], () => {\n setActive(0);\n if (scrollRef) scrollRef.scrollTop = 0;\n }),\n );\n\n createEffect(() => {\n const position = active();\n if (!revealActive) return;\n revealActive = false;\n const option = document.getElementById(optionId(position));\n if (!option || !scrollRef) return;\n // Sticky group titles cover the top of the list; an emoji in a first row scrolls with its title.\n const covered = option.closest(\"[role='group']\")?.querySelector<HTMLElement>(\"[data-emoji-heading]\")?.offsetHeight ?? 0;\n const top = offsetOf(option) - covered;\n const bottom = offsetOf(option) + option.offsetHeight;\n if (top < scrollRef.scrollTop) scrollRef.scrollTop = top;\n else if (bottom > scrollRef.scrollTop + scrollRef.clientHeight) scrollRef.scrollTop = bottom - scrollRef.clientHeight;\n });\n\n /** The group whose title sits at the top of the list, for the group bar. */\n const syncGroup = () => {\n if (!scrollRef || searching()) return;\n const top = scrollRef.scrollTop + 1;\n let current: Section[\"key\"] | undefined;\n for (const group of scrollRef.querySelectorAll<HTMLElement>(\"[data-emoji-group]\")) {\n if (offsetOf(group) <= top) current = group.dataset.emojiGroup as Section[\"key\"];\n }\n setCurrentGroup(current ?? groups()[0]?.key);\n };\n createEffect(on([groups, searching], () => queueMicrotask(syncGroup)));\n\n onMount(() => {\n if (props.autofocus) queueMicrotask(() => searchRef?.focus({ preventScroll: true }));\n });\n\n const pick = (item: Item | undefined) => {\n if (item) props.onPick(item.emoji);\n };\n\n const showGroup = (key: Section[\"key\"]) => {\n setQuery(\"\");\n queueMicrotask(() => {\n const group = scrollRef?.querySelector<HTMLElement>(`[data-emoji-group=\"${key}\"]`);\n if (!group || !scrollRef) return;\n scrollRef.scrollTop = offsetOf(group);\n const position = groups().findIndex((section) => section.key === key);\n if (position >= 0) setActive(groupStarts()[position]!);\n syncGroup();\n });\n };\n\n const onSearchKeyDown = (event: KeyboardEvent) => {\n // WebKit ends the composition before the keydown of the Enter that confirms it; that keydown keeps keyCode 229.\n if (event.isComposing || event.keyCode === 229) return;\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\" || event.key === \"ArrowUp\" || event.key === \"ArrowDown\") {\n // Left and right edit a search until up or down enters the grid.\n if ((event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") && query() && !gridEntered()) return;\n event.preventDefault();\n revealActive = true;\n setGridEntered(true);\n setActive(nextEmojiIndex(sizes(), active(), event.key));\n return;\n }\n if (event.key === \"Enter\") {\n event.preventDefault();\n pick(activeItem());\n return;\n }\n if (event.key === \"Escape\") {\n if (query()) {\n event.preventDefault();\n event.stopPropagation();\n setQuery(\"\");\n return;\n }\n if (props.onClose) {\n event.preventDefault();\n event.stopPropagation();\n props.onClose();\n }\n }\n };\n\n const openTones = () => {\n setTonesOpen(true);\n queueMicrotask(() => tonesRef?.querySelector<HTMLElement>(\"[aria-checked='true']\")?.focus());\n };\n const closeTones = (focusButton: boolean) => {\n setTonesOpen(false);\n if (focusButton) queueMicrotask(() => toneButtonRef?.focus());\n };\n /** As in any radio group, the arrow keys choose; Enter, Space, a click or Escape close the choice. */\n const onTonesKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\" || event.key === \"ArrowUp\" || event.key === \"ArrowDown\") {\n event.preventDefault();\n const step = event.key === \"ArrowLeft\" || event.key === \"ArrowUp\" ? -1 : 1;\n const next = EMOJI_SKIN_TONES[(tone() + step + EMOJI_SKIN_TONES.length) % EMOJI_SKIN_TONES.length]!;\n props.onSkinToneChange?.(next);\n queueMicrotask(() => tonesRef?.querySelector<HTMLElement>(`[data-tone=\"${next}\"]`)?.focus());\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n closeTones(true);\n }\n };\n\n /** The group bar is one tab stop; arrow keys move along it. */\n const onGroupsKeyDown = (event: KeyboardEvent) => {\n const buttons = [...(groupsRef?.querySelectorAll<HTMLButtonElement>(\"button\") ?? [])];\n const current = buttons.indexOf(document.activeElement as HTMLButtonElement);\n const target =\n event.key === \"ArrowLeft\"\n ? current - 1\n : event.key === \"ArrowRight\"\n ? current + 1\n : event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? buttons.length - 1\n : undefined;\n if (target === undefined) return;\n event.preventDefault();\n buttons[(target + buttons.length) % buttons.length]?.focus();\n };\n const groupKeys = createMemo((): Section[\"key\"][] => [\n ...(props.recent?.length ? ([\"recent\"] as const) : []),\n ...EMOJI_GROUPS.map((group) => group.key),\n ]);\n const groupIcon = (key: Section[\"key\"]) =>\n key === \"recent\" ? \"ti ti-clock\" : (EMOJI_GROUPS.find((group) => group.key === key)?.icon ?? \"ti ti-mood-smile\");\n const tabStop = () => currentGroup() ?? groupKeys()[0];\n\n /** The grid shares its pointer listeners; the target's position says which emoji it is. */\n const itemAt = (event: Event): number | undefined => {\n const option = (event.target as Element | null)?.closest<HTMLElement>(\"[data-emoji-index]\");\n return option ? Number(option.dataset.emojiIndex) : undefined;\n };\n\n // A button, so that a tap is a click on every engine; the focus stays in the search field.\n const option = (item: Item, list: \"r\" | \"g\", position: () => number) => (\n <button\n id={optionId(position(), list)}\n type=\"button\"\n role=\"option\"\n tabIndex={-1}\n class=\"k2b-emoji-picker__option\"\n aria-selected={isActive(position())}\n aria-label={nameOf(item)}\n data-emoji-index={position()}\n data-active={isActive(position()) ? \"true\" : undefined}\n onClick={() => pick(item)}\n >\n {item.emoji}\n </button>\n );\n\n return (\n <div class={`k2b-emoji-picker ${props.class ?? \"\"}`} role=\"group\" aria-label={props.label ?? text().emojiPicker}>\n <div class=\"k2b-emoji-picker__header\">\n <div class=\"k2b-emoji-picker__search\" inert={tonesOpen()}>\n <i class=\"ti ti-search\" aria-hidden=\"true\" />\n <input\n ref={searchRef}\n type=\"search\"\n role=\"combobox\"\n aria-label={text().emojiSearch}\n aria-expanded=\"true\"\n aria-controls={`${id}-list`}\n aria-autocomplete=\"list\"\n aria-activedescendant={activeItem() ? optionId(active()) : undefined}\n placeholder={text().emojiSearch}\n autocomplete=\"off\"\n spellcheck={false}\n enterkeyhint=\"done\"\n value={query()}\n onInput={(event) => {\n setQuery(event.currentTarget.value);\n setGridEntered(false);\n }}\n onKeyDown={onSearchKeyDown}\n />\n </div>\n <Show when={props.onSkinToneChange}>\n <button\n ref={toneButtonRef}\n type=\"button\"\n class=\"k2b-emoji-picker__tone-button\"\n aria-label={text().emojiSkinTone}\n aria-haspopup=\"true\"\n aria-expanded={tonesOpen()}\n title={`${text().emojiSkinTone}: ${toneLabel(text(), tone())}`}\n inert={tonesOpen()}\n onClick={openTones}\n >\n <span aria-hidden=\"true\">{toneSample(tone())}</span>\n </button>\n {/* The tones cover the header in place, so nothing below moves. */}\n <Show when={tonesOpen()}>\n <div\n ref={tonesRef}\n class=\"k2b-emoji-picker__tones\"\n role=\"radiogroup\"\n aria-label={text().emojiSkinTone}\n onKeyDown={onTonesKeyDown}\n onFocusOut={(event) => {\n if (!tonesRef?.contains(event.relatedTarget as Node | null)) closeTones(false);\n }}\n >\n <For each={EMOJI_SKIN_TONES}>\n {(value) => (\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={value === tone()}\n aria-label={toneLabel(text(), value)}\n title={toneLabel(text(), value)}\n tabIndex={value === tone() ? 0 : -1}\n data-tone={value}\n onClick={() => {\n props.onSkinToneChange?.(value);\n closeTones(true);\n }}\n >\n <span aria-hidden=\"true\">{toneSample(value)}</span>\n </button>\n )}\n </For>\n </div>\n </Show>\n </Show>\n </div>\n\n <div ref={groupsRef} class=\"k2b-emoji-picker__groups\" role=\"toolbar\" aria-label={text().emojiGroups} onKeyDown={onGroupsKeyDown}>\n <For each={groupKeys()}>\n {(key) => (\n <button\n type=\"button\"\n aria-label={groupTitle(text(), key)}\n title={groupTitle(text(), key)}\n aria-current={!searching() && currentGroup() === key ? \"true\" : undefined}\n tabIndex={key === tabStop() ? 0 : -1}\n disabled={!index()}\n onClick={() => showGroup(key)}\n >\n <i class={groupIcon(key)} aria-hidden=\"true\" />\n </button>\n )}\n </For>\n </div>\n\n <div ref={scrollRef} class=\"k2b-emoji-picker__scroll\" onScroll={syncGroup}>\n <Show\n when={index()}\n fallback={\n <div class=\"k2b-emoji-picker__state\" role=\"status\">\n <Show\n when={failed()}\n fallback={\n <>\n <i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">{messages().loading}</span>\n </>\n }\n >\n <span>{text().emojiLoadFailed}</span>\n <Button size=\"sm\" variant=\"subtle\" onClick={load}>\n {messages().retry}\n </Button>\n </Show>\n </div>\n }\n >\n <div\n id={`${id}-list`}\n role=\"listbox\"\n class=\"k2b-emoji-picker__list\"\n aria-label={props.label ?? text().emojiPicker}\n onPointerMove={(event) => {\n const position = itemAt(event);\n if (position !== undefined && !isActive(position) && event.pointerType === \"mouse\") setActive(position);\n }}\n onMouseDown={(event) => {\n // The focus stays in the search field, where the keyboard works.\n if (itemAt(event) !== undefined) event.preventDefault();\n }}\n >\n <Show when={searching()}>\n <div role=\"group\" aria-label={messages().searchResults}>\n <For each={resultBlocks()}>\n {(block, blockIndex) => (\n <div\n class=\"k2b-emoji-picker__grid k2b-emoji-picker__block\"\n style={{ \"--k2b-emoji-rows\": String(Math.ceil(block.length / COLUMNS)) }}\n >\n <For each={block}>{(item, itemIndex) => option(item, \"r\", () => blockIndex() * RESULT_BLOCK + itemIndex())}</For>\n </div>\n )}\n </For>\n </div>\n </Show>\n <div class=\"k2b-emoji-picker__all\" hidden={searching()}>\n <For each={groups()}>\n {(section, sectionIndex) => (\n <div\n role=\"group\"\n class=\"k2b-emoji-picker__section\"\n data-emoji-group={section.key}\n aria-labelledby={`${id}-${section.key}`}\n style={{ \"--k2b-emoji-rows\": String(Math.ceil(section.items.length / COLUMNS)) }}\n >\n <div id={`${id}-${section.key}`} class=\"k2b-emoji-picker__heading\" data-emoji-heading>\n {groupTitle(text(), section.key)}\n </div>\n <div class=\"k2b-emoji-picker__grid\">\n <For each={section.items}>\n {(item, itemIndex) => option(item, \"g\", () => groupStarts()[sectionIndex()]! + itemIndex())}\n </For>\n </div>\n </div>\n )}\n </For>\n </div>\n </div>\n <Show when={searching() && results().length === 0}>\n <div class=\"k2b-emoji-picker__state\" role=\"status\">\n {text().emojiNoResults}\n </div>\n </Show>\n </Show>\n </div>\n\n <div class=\"k2b-emoji-picker__preview\" aria-hidden=\"true\">\n <Show when={activeItem()}>\n {(item) => (\n <>\n <span class=\"k2b-emoji-picker__preview-emoji\">{item().emoji}</span>\n <span class=\"k2b-emoji-picker__preview-name\">{nameOf(item())}</span>\n <Show when={item().entry?.shortcodes[0]}>{(code) => <span class=\"k2b-emoji-picker__preview-code\">:{code()}:</span>}</Show>\n </>\n )}\n </Show>\n </div>\n </div>\n );\n}\n\nexport type EmojiPickerPopoverProps = Omit<EmojiPickerProps, \"onClose\" | \"autofocus\"> & {\n /** The control the picker opens next to. The picker is open while this is set. */\n anchor: HTMLElement | null | undefined;\n /** Called after a pick, on Escape, on a click outside, and on another press of the anchor. */\n onClose: () => void;\n};\n\nconst touchOnlyQuery = \"(any-pointer: coarse) and (not (any-pointer: fine))\";\nconst GAP = 6;\nconst MARGIN = 8;\n\n/**\n * The picker next to a control, such as the composer's emoji button or a message's \"Add reaction\". It opens above the\n * control where there is room and below it otherwise, closes after a pick, and returns the focus to where it was.\n */\nfunction EmojiPickerPopover(props: EmojiPickerPopoverProps): JSX.Element {\n let surface: HTMLDivElement | undefined;\n /** Where the focus was when the picker opened, and whether a keyboard opened it. */\n let previous: HTMLElement | null = null;\n let ring = false;\n /** An anchor pressed while the picker was open closes it; the same click must not open it again. */\n let pressedAnchor: HTMLElement | undefined;\n const [shown, setShown] = createSignal<HTMLElement>();\n let expandedAnchor: HTMLElement | undefined;\n let previousExpanded: string | null = null;\n const restoreExpanded = () => {\n if (previousExpanded === null) expandedAnchor?.removeAttribute(\"aria-expanded\");\n else expandedAnchor?.setAttribute(\"aria-expanded\", previousExpanded);\n expandedAnchor = undefined;\n };\n\n const place = () => {\n const anchor = shown();\n if (!surface || !anchor) return;\n // An anchor that left the page, such as a row a virtual list recycled, takes the picker with it.\n if (!anchor.isConnected) {\n hide();\n props.onClose();\n return;\n }\n // The visible part of the page: a phone's keyboard shrinks only the visual viewport.\n const viewport = window.visualViewport;\n const view = {\n top: (viewport?.offsetTop ?? 0) + MARGIN,\n bottom: (viewport ? viewport.offsetTop + viewport.height : window.innerHeight) - MARGIN,\n left: (viewport?.offsetLeft ?? 0) + MARGIN,\n right: (viewport ? viewport.offsetLeft + viewport.width : window.innerWidth) - MARGIN,\n };\n surface.style.setProperty(\"--k2b-emoji-popover-height\", `${Math.round(view.bottom - view.top)}px`);\n const box = anchor.getBoundingClientRect();\n const size = surface.getBoundingClientRect();\n const above = box.top - GAP - size.height;\n const below = box.bottom + GAP;\n const top = above >= view.top || below + size.height > view.bottom ? above : below;\n // Aligned with the anchor's end, like a menu at the end of a composer.\n const left = box.right - size.width;\n surface.style.left = `${Math.round(Math.max(view.left, Math.min(left, view.right - size.width)))}px`;\n surface.style.top = `${Math.round(Math.max(view.top, Math.min(top, view.bottom - size.height)))}px`;\n };\n\n const restoreFocus = () => {\n // A pick that moved the focus on purpose, such as into a composer, keeps it there.\n const focused = document.activeElement;\n if (focused && focused !== document.body && !surface?.contains(focused)) return;\n if (previous?.isConnected) returnFocus(previous, ring);\n };\n\n const hide = () => {\n restoreExpanded();\n restoreFocus();\n if (surface?.matches(\":popover-open\")) surface.hidePopover();\n setShown(undefined);\n };\n\n const pressed = (event: PointerEvent) => {\n const anchor = shown();\n pressedAnchor = anchor && event.target instanceof Node && anchor.contains(event.target) ? anchor : undefined;\n };\n\n /** A key press on the anchor dismisses nothing on its way, unlike a pointer: its click closes the open picker. */\n const clicked = (event: MouseEvent) => {\n const anchor = shown();\n if (!anchor || !(event.target instanceof Node) || !anchor.contains(event.target)) return;\n pressedAnchor = anchor;\n hide();\n props.onClose();\n };\n\n createEffect(() => {\n const anchor = props.anchor ?? undefined;\n untrack(() => {\n if (!anchor) {\n if (shown()) hide();\n return;\n }\n if (anchor === pressedAnchor) {\n // The press that closed the picker also asked to open it: it stays closed.\n pressedAnchor = undefined;\n props.onClose();\n return;\n }\n if (shown() === anchor || !surface) return;\n // Moving to another anchor keeps the picker open and the focus to return to.\n if (!shown()) {\n previous = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n ring = ringOnReturn(previous ?? anchor);\n }\n restoreExpanded();\n expandedAnchor = anchor;\n previousExpanded = anchor.getAttribute(\"aria-expanded\");\n anchor.setAttribute(\"aria-expanded\", \"true\");\n setShown(anchor);\n if (!surface.matches(\":popover-open\")) surface.showPopover();\n place();\n });\n });\n\n /** The page scrolled under the anchor; the picker's own list scrolling moves nothing. */\n const scrolled = (event: Event) => {\n if (!(event.target instanceof Node && surface?.contains(event.target))) place();\n };\n\n onMount(() => {\n window.addEventListener(\"resize\", place);\n window.addEventListener(\"scroll\", scrolled, true);\n window.visualViewport?.addEventListener(\"resize\", place);\n window.visualViewport?.addEventListener(\"scroll\", place);\n document.addEventListener(\"pointerdown\", pressed, true);\n document.addEventListener(\"click\", clicked, true);\n // The picker renders into the open surface after it is shown; its size places it.\n const observer = typeof ResizeObserver === \"function\" && surface ? new ResizeObserver(place) : undefined;\n if (surface) observer?.observe(surface);\n onCleanup(() => {\n observer?.disconnect();\n window.removeEventListener(\"resize\", place);\n window.removeEventListener(\"scroll\", scrolled, true);\n window.visualViewport?.removeEventListener(\"resize\", place);\n window.visualViewport?.removeEventListener(\"scroll\", place);\n document.removeEventListener(\"pointerdown\", pressed, true);\n document.removeEventListener(\"click\", clicked, true);\n restoreExpanded();\n if (surface?.matches(\":popover-open\")) hide();\n });\n });\n\n const touchOnly = () => typeof matchMedia === \"function\" && matchMedia(touchOnlyQuery).matches;\n\n return (\n <div\n ref={surface}\n popover=\"auto\"\n class=\"k2b-emoji-picker-popover\"\n onToggle={(event) => {\n if ((event as ToggleEvent).newState === \"open\") return;\n // Light dismissal by the browser: a click outside, Escape, or another popover.\n if (shown()) {\n restoreExpanded();\n setShown(undefined);\n restoreFocus();\n props.onClose();\n }\n // The pressed anchor is forgotten once its click has had the chance to reopen the picker.\n setTimeout(() => {\n pressedAnchor = undefined;\n });\n }}\n >\n <Show when={shown()}>\n <EmojiPickerPanel\n onPick={(emoji) => {\n props.onPick(emoji);\n hide();\n props.onClose();\n }}\n recent={props.recent}\n skinTone={props.skinTone}\n onSkinToneChange={props.onSkinToneChange}\n label={props.label}\n class={props.class}\n // A phone's keyboard would cover the emoji; a touch-only device searches after a tap on the field.\n autofocus={!touchOnly()}\n onClose={() => {\n hide();\n props.onClose();\n }}\n />\n </Show>\n </div>\n );\n}\n\n/** The emoji picker. `EmojiPicker.Popover` opens it next to a control. */\nexport const EmojiPicker = Object.assign(EmojiPickerPanel, { Popover: EmojiPickerPopover });\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SACE,YAAY,EACZ,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,GAAG,EAEH,EAAE,EACF,SAAS,EACT,OAAO,EACP,IAAI,EACJ,OAAO,QACF,UAAU;AACjB,SAAS,MAAM,QAAQ,sBAAsB;AAC7C,SAAS,WAAW,EAAE,YAAY,QAAQ,6BAA6B;AACvE,SAAS,SAAS,QAAQ,mBAAmB;AAC7C,SAAS,aAAa,QAAQ,qBAAqB;AACnD,SACE,YAAY,EACZ,gBAAgB,EAKhB,WAAW,EACX,SAAS,EACT,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,WAAW,QACN,eAAe;AACtB,SAA6B,gBAAgB,QAAQ,kBAAkB;;AAEvE;AACA,MAAM,OAAO,GAAG,CAAC;AACjB;AACA,MAAM,YAAY,GAAG,CAAC,GAAG,OAAO;AAChC,MAAM,WAAW,GAAG,GAAG;AACvB,MAAM,iBAAiB,GAAG,YAAY;AAuBtC,MAAM,UAAU,GAAG,CAAC,QAAuB,EAAE,GAAmB,KAAa;EAC3E,QAAQ,GAAG;IACT,KAAK,QAAQ;MACX,OAAO,QAAQ,CAAC,WAAW;IAC7B,KAAK,SAAS;MACZ,OAAO,QAAQ,CAAC,YAAY;IAC9B,KAAK,QAAQ;MACX,OAAO,QAAQ,CAAC,WAAW;IAC7B,KAAK,SAAS;MACZ,OAAO,QAAQ,CAAC,YAAY;IAC9B,KAAK,MAAM;MACT,OAAO,QAAQ,CAAC,SAAS;IAC3B,KAAK,QAAQ;MACX,OAAO,QAAQ,CAAC,WAAW;IAC7B,KAAK,YAAY;MACf,OAAO,QAAQ,CAAC,eAAe;IACjC,KAAK,SAAS;MACZ,OAAO,QAAQ,CAAC,YAAY;IAC9B,KAAK,SAAS;MACZ,OAAO,QAAQ,CAAC,YAAY;IAC9B,KAAK,OAAO;MACV,OAAO,QAAQ,CAAC,UAAU;EAC9B;AACF,CAAC;AAED,MAAM,SAAS,GAAG,CAAC,QAAuB,EAAE,IAAmB,KAC7D,CACE,QAAQ,CAAC,gBAAgB,EACzB,QAAQ,CAAC,cAAc,EACvB,QAAQ,CAAC,oBAAoB,EAC7B,QAAQ,CAAC,eAAe,EACxB,QAAQ,CAAC,mBAAmB,EAC5B,QAAQ,CAAC,aAAa,CACvB,CAAC,IAAI,CAAE;AAEV,MAAM,UAAU,GAAI,IAAmB,IACrC,IAAI,KAAK,CAAC,GAAG,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,aAAa,CAAC,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;;AAE7G;AACA,OAAO,MAAM,cAAc,GAAG,CAC5B,KAAwB,EACxB,KAAa,EACb,GAAyD,KAC9C;EACX,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC;EACxD,IAAI,KAAK,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;EAC1B,IAAI,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC;EACvB,IAAI,GAAG,KAAK,WAAW,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;EACtD,IAAI,GAAG,KAAK,YAAY,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;EAC/D,MAAM,MAAgB,GAAG,EAAE;EAC3B,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;EACpE,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,EAAE,QAAQ,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAI,CAAC,CAAC;EACjG,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC,OAAO,CAAE;EACvC,MAAM,MAAM,GAAG,MAAM,GAAG,OAAO;EAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAE;EAC5B,IAAI,GAAG,KAAK,SAAS,EAAE;IACrB,IAAI,MAAM,IAAI,OAAO,EAAE,OAAO,KAAK,GAAG,OAAO;IAC7C,KAAK,IAAI,QAAQ,GAAG,OAAO,GAAG,CAAC,EAAE,QAAQ,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE;MAC1D,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE;MACtB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAI,CAAC,IAAI,OAAO,CAAC,GAAG,OAAO;MACtE,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAI,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAI,CAAC,CAAC;IAC7E;IACA,OAAO,KAAK;EACd;EACA,IAAI,MAAM,GAAG,OAAO,GAAG,IAAI,EAAE,OAAO,KAAK,GAAG,OAAO;EACnD;EACA,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,OAAO,CAAC,EAAE,OAAO,MAAM,CAAC,OAAO,CAAC,GAAI,IAAI,GAAG,CAAC;EACvG,KAAK,IAAI,IAAI,GAAG,OAAO,GAAG,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;IACxD,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAI,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,GAAI,CAAC,CAAC;EAC5E;EACA,OAAO,KAAK;AACd,CAAC;;AAED;AACA;AACA;AACA;AACA,SAAS,gBAAgB,CAAC,KAAuB,EAAe;EAC9D,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC;EAChC,MAAM,IAAI,GAAG,gBAAgB,CAAC,CAAC;EAC/B,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;EAC1B,MAAM,EAAE,GAAG,aAAa,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,EAAE;EAC1E,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAa,CAAC;EACpD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC;EAC/C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAC,EAAE,CAAC;EAC1C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;EAC3C,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC;EACvC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC;EACrD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,YAAY,CAAiB,CAAC;EACtE;EACA,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC;EACzD,IAAI,SAAuC;EAC3C,IAAI,SAAqC;EACzC,IAAI,aAA4C;EAChD,IAAI,QAAoC;EACxC,IAAI,SAAqC;EACzC;EACA,IAAI,YAAY,GAAG,KAAK;EAExB,MAAM,IAAI,GAAG,MAAM;IACjB,SAAS,CAAC,KAAK,CAAC;IAChB,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;EACxD,CAAC;EACD,OAAO,CAAC,IAAI,CAAC;EAEb,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,QAAQ,IAAI,CAAC;EACtC,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;EACjD;EACA,MAAM,MAAM,GAAG,UAAU,CAAC,MAA0B;IAClD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC;IACpB,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE;IACpB,MAAM,MAAe,GAAG;MACtB,GAAG,EAAE,QAAQ;MACb,KAAK,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,GAAG,CAAE,KAAK,KAAM;QAAE,KAAK;QAAE,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,KAAK;MAAE,CAAC,CAAC;IACpH,CAAC;IACD,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CACzB,KAAK,KAAe;MACnB,GAAG,EAAE,KAAK,CAAC,GAAG;MACd,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAE,KAAK,IAAK,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAE,KAAK,KAAM;QAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QAAE;MAAM,CAAC,CAAC;IAC/H,CAAC,CACH,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG;EACrD,CAAC,CAAC;EACF,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM;IACnC,MAAM,MAAgB,GAAG,EAAE;IAC3B,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1F,OAAO,MAAM;EACf,CAAC,CAAC;EACF,MAAM,OAAO,GAAG,UAAU,CAAC,MAAuB;IAChD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC;IACpB,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE;IACpC,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAE,KAAK,KAAM;MAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;MAAE;IAAM,CAAC,CAAC,CAAC;EAClG,CAAC,CAAC;EACF,MAAM,YAAY,GAAG,UAAU,CAAC,MAC9B,KAAK,CAAC,IAAI,CAAC;IAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,YAAY;EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,KAC1E,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,YAAY,EAAE,CAAC,KAAK,GAAG,CAAC,IAAI,YAAY,CAClE,CACF,CAAC;EACD;EACA,MAAM,KAAK,GAAG,MAAO,SAAS,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAE,OAAO,IAAK,OAAO,CAAC,KAAK,CAAC,MAAM,CAAE;EACxG,MAAM,KAAK,GAAG,UAAU,CAAC,MAAO,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAE,OAAO,IAAK,OAAO,CAAC,KAAK,CAAE,CAAC;EACxG,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;EAC1C,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAE,IAAI,GAAG,SAAS,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,KAAK,GAAG,EAAE,IAAI,IAAI,GAAG,QAAQ,EAAE;EACjG,MAAM,MAAM,GAAI,IAAU,IAAM,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAM;EAC1F;EACA,MAAM,QAAQ,GAAI,OAAgB,IAChC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAE,SAAS;;EAErG;EACA,YAAY,CACV,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,MAAM;IACvB,SAAS,CAAC,CAAC,CAAC;IACZ,IAAI,SAAS,EAAE,SAAS,CAAC,SAAS,GAAG,CAAC;EACxC,CAAC,CACH,CAAC;EAED,YAAY,CAAC,MAAM;IACjB,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC;IACzB,IAAI,CAAC,YAAY,EAAE;IACnB,YAAY,GAAG,KAAK;IACpB,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE;IAC3B;IACA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,aAAa,CAAc,sBAAsB,CAAC,EAAE,YAAY,IAAI,CAAC;IACvH,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO;IACtC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,YAAY;IACrD,IAAI,GAAG,GAAG,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,SAAS,GAAG,GAAG,CAAC,KACpD,IAAI,MAAM,GAAG,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,YAAY,EAAE,SAAS,CAAC,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC,YAAY;EACvH,CAAC,CAAC;;EAEF;EACA,MAAM,SAAS,GAAG,MAAM;IACtB,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC,EAAE;IAC/B,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,GAAG,CAAC;IACnC,IAAI,OAAmC;IACvC,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,gBAAgB,CAAc,oBAAoB,CAAC,EAAE;MACjF,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,UAA4B;IAClF;IACA,eAAe,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;EAC9C,CAAC;EACD,YAAY,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;EAEtE,OAAO,CAAC,MAAM;IACZ,IAAI,KAAK,CAAC,SAAS,EAAE,cAAc,CAAC,MAAM,SAAS,EAAE,KAAK,CAAC;MAAE,aAAa,EAAE;IAAK,CAAC,CAAC,CAAC;EACtF,CAAC,CAAC;EAEF,MAAM,IAAI,GAAI,IAAsB,IAAK;IACvC,IAAI,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;EACpC,CAAC;EAED,MAAM,SAAS,GAAI,GAAmB,IAAK;IACzC,QAAQ,CAAC,EAAE,CAAC;IACZ,cAAc,CAAC,MAAM;MACnB,MAAM,KAAK,GAAG,SAAS,EAAE,aAAa,CAAc,sBAAsB,GAAG,IAAI,CAAC;MAClF,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,EAAE;MAC1B,SAAS,CAAC,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC;MACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAE,OAAO,IAAK,OAAO,CAAC,GAAG,KAAK,GAAG,CAAC;MACrE,IAAI,QAAQ,IAAI,CAAC,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAE,CAAC;MACtD,SAAS,CAAC,CAAC;IACb,CAAC,CAAC;EACJ,CAAC;EAED,MAAM,eAAe,GAAI,KAAoB,IAAK;IAChD;IACA,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO,KAAK,GAAG,EAAE;IAChD,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,YAAY,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,EAAE;MACnH;MACA,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,YAAY,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE;MAC5F,KAAK,CAAC,cAAc,CAAC,CAAC;MACtB,YAAY,GAAG,IAAI;MACnB,cAAc,CAAC,IAAI,CAAC;MACpB,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;MACvD;IACF;IACA,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE;MACzB,KAAK,CAAC,cAAc,CAAC,CAAC;MACtB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;MAClB;IACF;IACA,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE;MAC1B,IAAI,KAAK,CAAC,CAAC,EAAE;QACX,KAAK,CAAC,cAAc,CAAC,CAAC;QACtB,KAAK,CAAC,eAAe,CAAC,CAAC;QACvB,QAAQ,CAAC,EAAE,CAAC;QACZ;MACF;MACA,IAAI,KAAK,CAAC,OAAO,EAAE;QACjB,KAAK,CAAC,cAAc,CAAC,CAAC;QACtB,KAAK,CAAC,eAAe,CAAC,CAAC;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;MACjB;IACF;EACF,CAAC;EAED,MAAM,SAAS,GAAG,MAAM;IACtB,YAAY,CAAC,IAAI,CAAC;IAClB,cAAc,CAAC,MAAM,QAAQ,EAAE,aAAa,CAAc,uBAAuB,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;EAC9F,CAAC;EACD,MAAM,UAAU,GAAI,WAAoB,IAAK;IAC3C,YAAY,CAAC,KAAK,CAAC;IACnB,IAAI,WAAW,EAAE,cAAc,CAAC,MAAM,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC;EAC/D,CAAC;EACD;EACA,MAAM,cAAc,GAAI,KAAoB,IAAK;IAC/C,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,YAAY,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,EAAE;MACnH,KAAK,CAAC,cAAc,CAAC,CAAC;MACtB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC;MAC1E,MAAM,IAAI,GAAG,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,gBAAgB,CAAC,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAE;MACnG,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC;MAC9B,cAAc,CAAC,MAAM,QAAQ,EAAE,aAAa,CAAc,eAAe,IAAI,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAC9F,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE;MACjC,KAAK,CAAC,cAAc,CAAC,CAAC;MACtB,KAAK,CAAC,eAAe,CAAC,CAAC;MACvB,UAAU,CAAC,IAAI,CAAC;IAClB;EACF,CAAC;;EAED;EACA,MAAM,eAAe,GAAI,KAAoB,IAAK;IAChD,MAAM,OAAO,GAAG,CAAC,IAAI,SAAS,EAAE,gBAAgB,CAAoB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACrF,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAkC,CAAC;IAC5E,MAAM,MAAM,GACV,KAAK,CAAC,GAAG,KAAK,WAAW,GACrB,OAAO,GAAG,CAAC,GACX,KAAK,CAAC,GAAG,KAAK,YAAY,GACxB,OAAO,GAAG,CAAC,GACX,KAAK,CAAC,GAAG,KAAK,MAAM,GAClB,CAAC,GACD,KAAK,CAAC,GAAG,KAAK,KAAK,GACjB,OAAO,CAAC,MAAM,GAAG,CAAC,GAClB,SAAS;IACrB,IAAI,MAAM,KAAK,SAAS,EAAE;IAC1B,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,OAAO,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;EAC9D,CAAC;EACD,MAAM,SAAS,GAAG,UAAU,CAAC,MAAwB,CACnD,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,GAAI,CAAC,QAAQ,CAAC,GAAa,EAAE,CAAC,EACtD,GAAG,YAAY,CAAC,GAAG,CAAE,KAAK,IAAK,KAAK,CAAC,GAAG,CAAC,CAC1C,CAAC;EACF,MAAM,SAAS,GAAI,GAAmB,IACpC,GAAG,KAAK,QAAQ,GAAG,aAAa,GAAI,YAAY,CAAC,IAAI,CAAE,KAAK,IAAK,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,IAAI,IAAI,kBAAmB;EAClH,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;;EAEtD;EACA,MAAM,MAAM,GAAI,KAAY,IAAyB;IACnD,MAAM,MAAM,GAAI,KAAK,CAAC,MAAM,EAAqB,OAAO,CAAc,oBAAoB,CAAC;IAC3F,OAAO,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS;EAC/D,CAAC;;EAED;EACA,MAAM,MAAM,GAAG,CAAC,IAAU,EAAE,IAAe,EAAE,QAAsB;IAAA;IAAA,eAWtD,MAAM,IAAI,CAAC,IAAI,CAAC;IAAA,qBAExB,IAAI,CAAC,KAAK;IAAA;MAAA,UAXP,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC;QAAA,OAKf,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAA,OACvB,MAAM,CAAC,IAAI,CAAC;QAAA,OACN,QAAQ,CAAC,CAAC;QAAA,OACf,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,SAAS;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;IAAA;MAAA;MAAA;MAAA;MAAA;MAAA;IAAA;IAAA;IAAA;EAAA,IAKzD;EAED;IAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;IAAA,kBAuBqB,eAAe;IAAA,gBAJhB,KAAK,IAAK;MAClB,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC;MACnC,cAAc,CAAC,KAAK,CAAC;IACvB,CAAC;IAAA,YAhBI,SAAS;IAAA,oDAAT,SAAS;IAAA,uCAKC,GAAG,EAAE,OAAO;IAAA,oCAKf,KAAK;IAAA,kCAUpB,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,gBAAgB;MAAA;MAAA;QAAA;UAAA;YAAA;UAAA,gBAUrB,SAAS;UAAA,aARb,aAAa;UAAA,sDAAb,aAAa;UAAA,sBAUQ,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;UAAA;YAAA,WAPhC,IAAI,CAAC,CAAC,CAAC,aAAa;cAAA,OAEjB,SAAS,CAAC,CAAC;cAAA,OACnB,GAAG,IAAI,CAAC,CAAC,CAAC,aAAa,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE;cAAA,OACvD,SAAS,CAAC,CAAC;YAAA;YAAA;YAAA;YAAA;YAAA;UAAA;YAAA;YAAA;YAAA;YAAA;UAAA;UAAA;UAAA;QAAA,wBAMnB,IAAI;UAAA,IAAC,IAAI;YAAA,OAAE,SAAS,CAAC,CAAC;UAAA;UAAA;YAAA;YAAA,mBAON,KAAK,IAAK;cACrB,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,aAA4B,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC;YAChF,CAAC;YAAA,kBAHU,cAAc;YAAA,aAJpB,QAAQ;YAAA,sDAAR,QAAQ;YAAA,kCASZ,GAAG;cAAC,IAAI,EAAE,gBAAgB;cAAA,UACvB,KAAK;gBAAA;kBAAA;gBAAA,iBASM,MAAM;kBACb,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC;kBAC/B,UAAU,CAAC,IAAI,CAAC;gBAClB,CAAC;gBAAA,oCAJU,KAAK;gBAAA,uBAMU,UAAU,CAAC,KAAK,CAAC;gBAAA;kBAAA,YAV7B,KAAK,KAAK,IAAI,CAAC,CAAC;oBAAA,QAClB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC;oBAAA,QAC7B,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC;oBAAA,QACrB,KAAK,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;kBAAA;kBAAA;kBAAA;kBAAA;kBAAA;gBAAA;kBAAA;kBAAA;kBAAA;kBAAA;gBAAA;gBAAA;gBAAA;cAAA;YAStC;YAAA,mDAvBS,IAAI,CAAC,CAAC,CAAC,aAAa;YAAA;YAAA;UAAA;QAAA;MAAA;IAAA;IAAA,mBA8BwE,eAAe;IAAA,aAArH,SAAS;IAAA,uDAAT,SAAS;IAAA,mCAChB,GAAG;MAAA,IAAC,IAAI;QAAA,OAAE,SAAS,CAAC,CAAC;MAAA;MAAA,UAClB,GAAG;QAAA;UAAA;QAAA,iBAQQ,MAAM,SAAS,CAAC,GAAG,CAAC;QAAA;UAAA,YALjB,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC;YAAA,QAC5B,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC;YAAA,QAChB,CAAC,SAAS,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,SAAS;YAAA,QAC/D,GAAG,KAAK,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAAA,QAC1B,CAAC,KAAK,CAAC,CAAC;YAAA,QAGR,SAAS,CAAC,GAAG,CAAC;UAAA;UAAA;UAAA;UAAA;UAAA;UAAA;UAAA;QAAA;UAAA;UAAA;UAAA;UAAA;UAAA;UAAA;QAAA;QAAA;QAAA;MAAA;IAE3B;IAAA,kCAI2D,SAAS;IAAA,aAA/D,SAAS;IAAA,uDAAT,SAAS;IAAA,mCAChB,IAAI;MAAA,IACH,IAAI;QAAA,OAAE,KAAK,CAAC,CAAC;MAAA;MAAA,IACb,QAAQ;QAAA;UAAA;UAAA,mCAEH,IAAI;YAAA,IACH,IAAI;cAAA,OAAE,MAAM,CAAC,CAAC;YAAA;YAAA,IACd,QAAQ;cAAA;gBAAA;gBAAA,uBAGuB,QAAQ,CAAC,CAAC,CAAC,OAAO;gBAAA;cAAA;YAAA;YAAA;cAAA;gBAAA;gBAAA,uBAI1C,IAAI,CAAC,CAAC,CAAC,eAAe;gBAAA;cAAA,wBAC5B,MAAM;gBAAC,IAAI;gBAAM,OAAO;gBAAU,OAAO,EAAE,IAAI;gBAAA;kBAAA,OAC7C,QAAQ,CAAC,CAAC,CAAC,KAAK;gBAAA;cAAA;YAAA;UAAA;UAAA;QAAA;MAAA;MAAA;QAAA;UAAA;YAAA;YAAA;YAAA;UAAA,qBAeT,KAAK,IAAK;YACtB;YACA,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;UACzD,CAAC;UAAA,uBAPe,KAAK,IAAK;YACxB,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;YAC9B,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,WAAW,KAAK,OAAO,EAAE,SAAS,CAAC,QAAQ,CAAC;UACzG,CAAC;UAAA,6BAPG,GAAG,EAAE,OAAO;UAAA,mCAaf,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,SAAS,CAAC,CAAC;YAAA;YAAA;cAAA;cAAA,mCAElB,GAAG;gBAAA,IAAC,IAAI;kBAAA,OAAE,YAAY,CAAC,CAAC;gBAAA;gBAAA,UACtB,CAAC,KAAK,EAAE,UAAU;kBAAA;kBAAA,mCAKd,GAAG;oBAAC,IAAI,EAAE,KAAK;oBAAA,UAAG,CAAC,IAAI,EAAE,SAAS,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC,CAAC,GAAG,YAAY,GAAG,SAAS,CAAC,CAAC;kBAAC;kBAAA,+DAF7E,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;kBAAA;gBAAA;cAIzE;cAAA,oDATyB,QAAQ,CAAC,CAAC,CAAC,aAAa;cAAA;YAAA;UAAA;UAAA,mCAcrD,GAAG;YAAA,IAAC,IAAI;cAAA,OAAE,MAAM,CAAC,CAAC;YAAA;YAAA,UAChB,CAAC,OAAO,EAAE,YAAY;cAAA;gBAAA;gBAAA;cAAA,uBAShB,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC;cAAA,mCAG/B,GAAG;gBAAA,IAAC,IAAI;kBAAA,OAAE,OAAO,CAAC,KAAK;gBAAA;gBAAA,UACrB,CAAC,IAAI,EAAE,SAAS,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAI,SAAS,CAAC,CAAC;cAAC;cAAA;gBAAA,YAT7E,OAAO,CAAC,GAAG;kBAAA,QACZ,GAAG,EAAE,IAAI,OAAO,CAAC,GAAG,EAAE;kBAAA,QACV,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;kBAAA,QAErE,GAAG,EAAE,IAAI,OAAO,CAAC,GAAG,EAAE;gBAAA;gBAAA;gBAAA;gBAAA;gBAAA;cAAA;gBAAA;gBAAA;gBAAA;gBAAA;cAAA;cAAA;YAAA;UASlC;UAAA;YAAA,WA3CO,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW;cAAA,OAwBF,SAAS,CAAC,CAAC;YAAA;YAAA;YAAA;UAAA;YAAA;YAAA;UAAA;UAAA;UAAA;QAAA,wBAuBvD,IAAI;UAAA,IAAC,IAAI;YAAA,OAAE,wBAAS,CAAC,CAAC,OAAI,OAAO,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC;UAAA;UAAA;YAAA;YAAA,uBAE5C,IAAI,CAAC,CAAC,CAAC,cAAc;YAAA;UAAA;QAAA;MAAA;IAAA;IAAA,mCAO3B,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,UAAU,CAAC,CAAC;MAAA;MAAA,UACpB,IAAI;QAAA;QAAA,uBAE6C,IAAI,CAAC,CAAC,CAAC,KAAK;QAAA;MAAA;QAAA;QAAA,uBACb,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAAA;MAAA,wBAC3D,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;QAAA;QAAA,UAAI,IAAI;UAAA;YAAA;YAAA;YAAA;YAAA;UAAA,iBAAoD,IAAI;UAAA;QAAA;MAAW;IAErH;IAAA;MAAA,YAtLK,oBAAoB,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;QAAA,QAA2B,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW;QAAA,QAE9D,SAAS,CAAC,CAAC;QAAA,QAMxC,IAAI,CAAC,CAAC,CAAC,WAAW;QAAA,QAIP,UAAU,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS;QAAA,QACvD,IAAI,CAAC,CAAC,CAAC,WAAW;QAAA,QA8D4C,IAAI,CAAC,CAAC,CAAC,WAAW;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;IAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;IAAA;IAAA,6CA1DtF,KAAK,CAAC,CAAC;IAAA;IAAA;EAAA;AA0K1B;AASA,MAAM,cAAc,GAAG,qDAAqD;AAC5E,MAAM,GAAG,GAAG,CAAC;AACb,MAAM,MAAM,GAAG,CAAC;;AAEhB;AACA;AACA;AACA;AACA,SAAS,kBAAkB,CAAC,KAA8B,EAAe;EACvE,IAAI,OAAmC;EACvC;EACA,IAAI,QAA4B,GAAG,IAAI;EACvC,IAAI,IAAI,GAAG,KAAK;EAChB;EACA,IAAI,aAAsC;EAC1C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAc,CAAC;EACrD,IAAI,cAAuC;EAC3C,IAAI,gBAA+B,GAAG,IAAI;EAC1C,MAAM,eAAe,GAAG,MAAM;IAC5B,IAAI,gBAAgB,KAAK,IAAI,EAAE,cAAc,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC,KAC3E,cAAc,EAAE,YAAY,CAAC,eAAe,EAAE,gBAAgB,CAAC;IACpE,cAAc,GAAG,SAAS;EAC5B,CAAC;EAED,MAAM,KAAK,GAAG,MAAM;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC;IACtB,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE;IACzB;IACA,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE;MACvB,IAAI,CAAC,CAAC;MACN,KAAK,CAAC,OAAO,CAAC,CAAC;MACf;IACF;IACA;IACA,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc;IACtC,MAAM,IAAI,GAAG;MACX,GAAG,EAAE,CAAC,QAAQ,EAAE,SAAS,IAAI,CAAC,IAAI,MAAM;MACxC,MAAM,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC,SAAS,GAAG,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM;MACvF,IAAI,EAAE,CAAC,QAAQ,EAAE,UAAU,IAAI,CAAC,IAAI,MAAM;MAC1C,KAAK,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC,UAAU,GAAG,QAAQ,CAAC,KAAK,GAAG,MAAM,CAAC,UAAU,IAAI;IACjF,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,4BAA4B,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;IAClG,MAAM,GAAG,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM;IACzC,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG;IAC9B,MAAM,GAAG,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK,GAAG,KAAK;IAClF;IACA,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;IACnC,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;IACpG,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;EACrG,CAAC;EAED,MAAM,YAAY,GAAG,MAAM;IACzB;IACA,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa;IACtC,IAAI,OAAO,IAAI,OAAO,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE;IACzE,IAAI,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC;EACxD,CAAC;EAED,MAAM,IAAI,GAAG,MAAM;IACjB,eAAe,CAAC,CAAC;IACjB,YAAY,CAAC,CAAC;IACd,IAAI,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5D,QAAQ,CAAC,SAAS,CAAC;EACrB,CAAC;EAED,MAAM,OAAO,GAAI,KAAmB,IAAK;IACvC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC;IACtB,aAAa,GAAG,MAAM,IAAI,KAAK,CAAC,MAAM,YAAY,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS;EAC9G,CAAC;;EAED;EACA,MAAM,OAAO,GAAI,KAAiB,IAAK;IACrC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,IAAI,EAAE,KAAK,CAAC,MAAM,YAAY,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;IAClF,aAAa,GAAG,MAAM;IACtB,IAAI,CAAC,CAAC;IACN,KAAK,CAAC,OAAO,CAAC,CAAC;EACjB,CAAC;EAED,YAAY,CAAC,MAAM;IACjB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,SAAS;IACxC,OAAO,CAAC,MAAM;MACZ,IAAI,CAAC,MAAM,EAAE;QACX,IAAI,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACnB;MACF;MACA,IAAI,MAAM,KAAK,aAAa,EAAE;QAC5B;QACA,aAAa,GAAG,SAAS;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf;MACF;MACA,IAAI,KAAK,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,OAAO,EAAE;MACpC;MACA,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;QACZ,QAAQ,GAAG,QAAQ,CAAC,aAAa,YAAY,WAAW,GAAG,QAAQ,CAAC,aAAa,GAAG,IAAI;QACxF,IAAI,GAAG,YAAY,CAAC,QAAQ,IAAI,MAAM,CAAC;MACzC;MACA,eAAe,CAAC,CAAC;MACjB,cAAc,GAAG,MAAM;MACvB,gBAAgB,GAAG,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC;MACvD,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC;MAC5C,QAAQ,CAAC,MAAM,CAAC;MAChB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;MAC5D,KAAK,CAAC,CAAC;IACT,CAAC,CAAC;EACJ,CAAC,CAAC;;EAEF;EACA,MAAM,QAAQ,GAAI,KAAY,IAAK;IACjC,IAAI,EAAE,KAAK,CAAC,MAAM,YAAY,IAAI,IAAI,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;EACjF,CAAC;EAED,OAAO,CAAC,MAAM;IACZ,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC;IACxC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC;IACjD,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC;IACxD,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC;IACxD,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;IACvD,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;IACjD;IACA,MAAM,QAAQ,GAAG,OAAO,cAAc,KAAK,UAAU,IAAI,OAAO,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,SAAS;IACxG,IAAI,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC;IACvC,SAAS,CAAC,MAAM;MACd,QAAQ,EAAE,UAAU,CAAC,CAAC;MACtB,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC;MAC3C,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC;MACpD,MAAM,CAAC,cAAc,EAAE,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC;MAC3D,MAAM,CAAC,cAAc,EAAE,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC;MAC3D,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;MAC1D,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;MACpD,eAAe,CAAC,CAAC;MACjB,IAAI,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC,CAAC;EACJ,CAAC,CAAC;EAEF,MAAM,SAAS,GAAG,MAAM,OAAO,UAAU,KAAK,UAAU,IAAI,UAAU,CAAC,cAAc,CAAC,CAAC,OAAO;EAE9F;IAAA;IAAA,kCAKe,KAAK,IAAK;MACnB,IAAK,KAAK,CAAiB,QAAQ,KAAK,MAAM,EAAE;MAChD;MACA,IAAI,KAAK,CAAC,CAAC,EAAE;QACX,eAAe,CAAC,CAAC;QACjB,QAAQ,CAAC,SAAS,CAAC;QACnB,YAAY,CAAC,CAAC;QACd,KAAK,CAAC,OAAO,CAAC,CAAC;MACjB;MACA;MACA,UAAU,CAAC,MAAM;QACf,aAAa,GAAG,SAAS;MAC3B,CAAC,CAAC;IACJ,CAAC;IAAA,aAhBI,OAAO;IAAA,uDAAP,OAAO;IAAA,mCAkBX,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,CAAC;MAAA;MAAA;QAAA,yBAChB,gBAAgB;UACf,MAAM,EAAG,KAAK,IAAK;YACjB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;YACnB,IAAI,CAAC,CAAC;YACN,KAAK,CAAC,OAAO,CAAC,CAAC;UACjB,CAAC;UAAA,IACD,MAAM;YAAA,OAAE,KAAK,CAAC,MAAM;UAAA;UAAA,IACpB,QAAQ;YAAA,OAAE,KAAK,CAAC,QAAQ;UAAA;UAAA,IACxB,gBAAgB;YAAA,OAAE,KAAK,CAAC,gBAAgB;UAAA;UAAA,IACxC,KAAK;YAAA,OAAE,KAAK,CAAC,KAAK;UAAA;UAAA;YAAA,OACX,KAAK,CAAC,KAAK;UAAA;UAAA,IAElB,SAAS;YAAA,OAAE,CAAC,SAAS,CAAC,CAAC;UAAA;UACvB,OAAO,EAAE,MAAM;YACb,IAAI,CAAC,CAAC;YACN,KAAK,CAAC,OAAO,CAAC,CAAC;UACjB;QAAC;MAAA;IAAA;IAAA;EAAA;AAKX;;AAEA;AACA,OAAO,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE;EAAE,OAAO,EAAE;AAAmB,CAAC,CAAC;AAAC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["inputs/file-drop.ts"],"sourcesContent":["import { text } from \"@k2b/stdlib\";\nimport { checkMimeType } from \"@k2b/stdlib/browser\";\nimport { type Accessor, createSignal } from \"solid-js\";\nimport { announce } from \"../feedback/announce\";\nimport { toast } from \"../feedback/toast\";\nimport type { FileDropMessages } from \"./file-drop-messages\";\n\nexport type FileDropRejection = {\n file: File;\n /** `type` misses `accept`, `size` exceeds `maxSize`, `count` is past `maxFiles` or the single file of `multiple={false}`. */\n reason: \"type\" | \"size\" | \"count\";\n};\n\nexport type FileDropDetails = {\n /** The drop's data, readable only while `onDrop` runs synchronously; read folder entries before the first `await`. */\n dataTransfer: DataTransfer;\n /** Files left out by `accept`, `maxSize`, or the file count; the user has already been told. */\n rejected: readonly FileDropRejection[];\n};\n\nexport type FileDropOptions = {\n /** One sentence that says what dropping does here, such as \"Drop to attach to the message\". */\n label: string;\n /** `<input accept>` syntax, such as `\"image/*,.pdf\"`. */\n accept?: string;\n /** Defaults to `true`; `false` takes the first fitting file. */\n multiple?: boolean;\n /** The most files one drop hands over. */\n maxFiles?: number;\n /** The largest file in bytes. */\n maxSize?: number;\n disabled?: boolean;\n /**\n * Called synchronously in the drop with the files that fit. `files` is empty only when the drop carried no file\n * objects at all, as some engines hand over dropped folders; `details.dataTransfer.items` still has their entries.\n */\n onDrop: (files: File[], details: FileDropDetails) => void | Promise<void>;\n};\n\nexport type FileDropTargetEntry = {\n options: FileDropOptions;\n messages: () => FileDropMessages;\n locale: () => string;\n /** Set for regions: the area the overlay covers. Specific targets are keyed by their element. */\n region?: () => Element | undefined;\n /** Set for regions: where the target itself is rendered; a region whose host is hidden takes no drops. */\n host?: () => Element | undefined;\n};\n\nexport type FileDropHover = { entry: FileDropTargetEntry; element: Element; invalid: boolean };\n\nexport type FileDropSession = {\n /** Regions that show their overlay during this drag: eligible, visible, and not inside another shown region. */\n shown: readonly FileDropTargetEntry[];\n hover: FileDropHover | null;\n};\n\nexport type FileDropEngine = {\n session: Accessor<FileDropSession | null>;\n /** Changes on every drag movement, so overlays can follow a region that moved or resized. */\n frame: Accessor<number>;\n addRegion: (entry: FileDropTargetEntry) => () => void;\n setTarget: (element: Element, entry: FileDropTargetEntry) => void;\n};\n\n/** The marker a hovered specific target carries for its ring; regions show their own overlay instead. */\nexport const FILE_DROP_ATTRIBUTE = \"data-file-drop\";\n\n/** Where a region without `for` looks for its area: the nearest dialog, workspace detail, or workspace main area. */\nexport const FILE_DROP_DEFAULT_REGION = \"dialog, .k2b-app-workspace__detail, .k2b-app-workspace__main\";\n\n/**\n * The type every drag that starts in a page carries. Such a drag holds page content, never files from outside, even\n * an image that carries one. Marking the drag itself leaves nothing behind when it never reports its end, as when its\n * start is cancelled or its source is removed.\n */\nconst PAGE_DRAG_TYPE = \"application/x-k2b-page-drag\";\n\n/** How long after the last drag event a pointer move means the drag ended; a drag over the page repeats them sooner. */\nconst DRAG_SILENCE_MS = 600;\n\nconst engines = new WeakMap<Document, FileDropEngine>();\n\nconst isFileDrag = (event: DragEvent) => {\n const types = Array.from(event.dataTransfer?.types ?? []);\n return types.includes(\"Files\") && !types.includes(PAGE_DRAG_TYPE);\n};\n\nconst elementOf = (target: EventTarget | null): Element | null =>\n target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n\nconst isModal = (dialog: Element) => {\n try {\n return dialog.matches(\":modal\");\n } catch {\n // An engine without `:modal` has no modal dialogs to defer to.\n return false;\n }\n};\n\n/**\n * The topmost modal dialog. Everything outside of it is inert, so a drag over the page lands inside it; only a drag\n * over other top-layer content falls back to the last modal dialog in the document.\n */\nconst topModal = (doc: Document, target: EventTarget | null): Element | null => {\n for (let dialog = elementOf(target)?.closest(\"dialog\"); dialog; dialog = dialog.parentElement?.closest(\"dialog\"))\n if (isModal(dialog)) return dialog;\n return Array.from(doc.querySelectorAll(\"dialog[open]\")).filter(isModal).at(-1) ?? null;\n};\n\n/** Sorts dropped files into the ones a target takes and the ones it leaves out, in drop order. */\nexport const partitionDroppedFiles = (\n files: readonly File[],\n options: Pick<FileDropOptions, \"accept\" | \"multiple\" | \"maxFiles\" | \"maxSize\">,\n): { accepted: File[]; rejected: FileDropRejection[] } => {\n const limit = options.multiple === false ? 1 : (options.maxFiles ?? Number.POSITIVE_INFINITY);\n const accepted: File[] = [];\n const rejected: FileDropRejection[] = [];\n for (const file of files) {\n if (options.accept && !checkMimeType(file, options.accept)) rejected.push({ file, reason: \"type\" });\n else if (options.maxSize !== undefined && file.size > options.maxSize) rejected.push({ file, reason: \"size\" });\n else if (accepted.length >= limit) rejected.push({ file, reason: \"count\" });\n else accepted.push(file);\n }\n return { accepted, rejected };\n};\n\n/**\n * During a drag only the types are readable, and only in some engines. A drag is refused when none of them can fit.\n * An extension in `accept` matches by file name, and systems report differing types for one extension (a `.csv` may be\n * `application/vnd.ms-excel`), so with one the drop decides.\n */\nexport const refusesDraggedTypes = (types: readonly string[], accept: string | undefined): boolean => {\n if (!accept || accept.split(\",\").some((entry) => entry.trim().startsWith(\".\"))) return false;\n return types.length > 0 && types.every((type) => type !== \"\" && !checkMimeType(type, accept));\n};\n\nconst invalidDrag = (event: DragEvent, options: FileDropOptions) =>\n refusesDraggedTypes(\n Array.from(event.dataTransfer?.items ?? [])\n .filter((item) => item.kind === \"file\")\n .map((item) => item.type),\n options.accept,\n );\n\nconst MAX_NAMES = 3;\nconst nameList = (files: readonly File[], messages: FileDropMessages) => {\n const names = files.slice(0, MAX_NAMES).map((file) => file.name);\n return files.length > MAX_NAMES ? `${names.join(\", \")} ${messages.fileDropMore({ count: files.length - MAX_NAMES })}` : names.join(\", \");\n};\n\nexport const fileDropRejectionMessage = (\n rejected: readonly FileDropRejection[],\n options: Pick<FileDropOptions, \"multiple\" | \"maxFiles\" | \"maxSize\">,\n messages: FileDropMessages,\n locale: string,\n): string => {\n const lines: string[] = [];\n const of = (reason: FileDropRejection[\"reason\"]) => rejected.filter((entry) => entry.reason === reason).map((entry) => entry.file);\n const type = of(\"type\");\n const size = of(\"size\");\n const count = of(\"count\");\n if (type.length) lines.push(messages.fileDropRejectedType({ names: nameList(type, messages) }));\n if (size.length)\n lines.push(\n messages.fileDropRejectedSize({ names: nameList(size, messages), limit: text.pprintBytes(options.maxSize ?? 0, { locale }) }),\n );\n if (count.length)\n lines.push(\n messages.fileDropRejectedCount({ names: nameList(count, messages), max: options.multiple === false ? 1 : (options.maxFiles ?? 1) }),\n );\n return lines.join(\"\\n\");\n};\n\nconst createEngine = (doc: Document): FileDropEngine => {\n const view = doc.defaultView;\n const regions = new Set<FileDropTargetEntry>();\n const targets = new WeakMap<Element, FileDropTargetEntry>();\n const [session, setSession] = createSignal<FileDropSession | null>(null);\n const [frame, setFrame] = createSignal(0);\n /** Elements the drag has entered and not yet left; the drag is over the window while any remains. */\n const entered = new Set<EventTarget>();\n let lastDragEvent = 0;\n let marked: Element | null = null;\n let frameRequest = 0;\n\n const mark = (hover: FileDropHover | null) => {\n if (marked && marked !== hover?.element) marked.removeAttribute(FILE_DROP_ATTRIBUTE);\n marked = null;\n if (!hover || hover.entry.region) return;\n marked = hover.element;\n marked.setAttribute(FILE_DROP_ATTRIBUTE, hover.invalid ? \"invalid\" : \"over\");\n };\n\n const regionElement = (entry: FileDropTargetEntry) => {\n const element = entry.region?.();\n return element?.isConnected ? element : undefined;\n };\n\n /** Whether nothing between the target's host and its area hides it, as a dialog stack hides its lower levels. */\n const displayed = (host: Element | undefined, area: Element) => {\n for (let element: Element | null | undefined = host; element && element !== area; element = element.parentElement)\n if (view?.getComputedStyle(element).display === \"none\") return false;\n return true;\n };\n\n /** A region takes part when it is enabled, displayed, and not behind a modal dialog it is not inside of. */\n const eligible = (entry: FileDropTargetEntry, modal: Element | null) => {\n const element = regionElement(entry);\n if (!element || entry.options.disabled) return false;\n return (!modal || modal.contains(element)) && displayed(entry.host?.(), element);\n };\n const rendered = (element: Element) => element === doc.documentElement || element.getClientRects().length > 0;\n\n const begin = (target: EventTarget | null) => {\n const modal = topModal(doc, target);\n const candidates = [...regions].filter((entry) => eligible(entry, modal) && rendered(regionElement(entry)!));\n // The latest region on an element replaces earlier ones; a region inside another shown one acts as a specific target.\n const byElement = new Map<Element, FileDropTargetEntry>();\n for (const entry of candidates) byElement.set(regionElement(entry)!, entry);\n const shown = [...byElement].filter(\n ([element]) => ![...byElement.keys()].some((other) => other !== element && other.contains(element)),\n );\n setSession({ shown: shown.map(([, entry]) => entry), hover: null });\n const first = shown[0]?.[1];\n if (first) announce(first.options.label);\n };\n\n const end = () => {\n entered.clear();\n mark(null);\n if (session()) setSession(null);\n };\n\n const resolve = (target: EventTarget | null): { entry: FileDropTargetEntry; element: Element } | null => {\n const modal = topModal(doc, target);\n for (let element = elementOf(target); element; element = element.parentElement) {\n const specific = targets.get(element);\n if (specific && !specific.options.disabled) return { entry: specific, element };\n let region: FileDropTargetEntry | undefined;\n for (const entry of regions) if (regionElement(entry) === element && eligible(entry, modal)) region = entry;\n if (region) return { entry: region, element };\n }\n return null;\n };\n\n const hoverFrom = (event: DragEvent) => {\n const current = session();\n if (!current) return null;\n const found = resolve(event.target);\n const hover = found ? { ...found, invalid: invalidDrag(event, found.entry.options) } : null;\n const previous = current.hover;\n if (previous?.entry !== hover?.entry || previous?.element !== hover?.element || previous?.invalid !== hover?.invalid) {\n mark(hover);\n setSession({ ...current, hover });\n }\n return hover;\n };\n\n /** Over a page with a region, a file never falls through to the browser, which would open it and leave the page. */\n const guarding = () => [...regions].some((entry) => regionElement(entry));\n\n const accept = (event: DragEvent, hover: FileDropHover | null) => {\n if (!hover && !guarding()) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = hover && !hover.invalid ? \"copy\" : \"none\";\n };\n\n const requestFrame = () => {\n if (frameRequest || !view) return;\n frameRequest = view.requestAnimationFrame(() => {\n frameRequest = 0;\n setFrame((value) => value + 1);\n });\n };\n\n const deliver = (entry: FileDropTargetEntry, dataTransfer: DataTransfer) => {\n const { options } = entry;\n const files = Array.from(dataTransfer.files);\n const { accepted, rejected } = partitionDroppedFiles(files, options);\n const messages = entry.messages();\n if (rejected.length) toast.error(fileDropRejectionMessage(rejected, options, messages, entry.locale()));\n if (!accepted.length && files.length) return;\n if (accepted.length)\n announce(\n accepted.length === 1\n ? messages.fileDropDroppedOne({ name: accepted[0]!.name })\n : messages.fileDropDropped({ count: accepted.length }),\n );\n void options.onDrop(accepted, { dataTransfer, rejected });\n };\n\n const listeners: Record<string, (event: Event) => void> = {\n dragstart: (event) => {\n (event as DragEvent).dataTransfer?.setData(PAGE_DRAG_TYPE, \"\");\n },\n dragenter: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n lastDragEvent = event.timeStamp;\n if (event.target) entered.add(event.target);\n if (!session()) begin(event.target);\n accept(drag, hoverFrom(drag));\n },\n dragover: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n lastDragEvent = event.timeStamp;\n // An engine may skip the first dragenter; the drag still counts as over the window.\n if (!session()) {\n if (event.target) entered.add(event.target);\n begin(event.target);\n }\n accept(drag, hoverFrom(drag));\n requestFrame();\n },\n dragleave: (event) => {\n if (!session()) return;\n if (event.target) entered.delete(event.target);\n // An element removed during the drag never reports leaving.\n for (const target of entered) if (target instanceof Node && !target.isConnected) entered.delete(target);\n if (entered.size === 0) end();\n },\n drop: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n const found = resolve(event.target);\n end();\n if (!found) {\n if (guarding()) event.preventDefault();\n return;\n }\n // The most specific target owns the drop; editors and other handlers below it never see the files.\n event.preventDefault();\n event.stopPropagation();\n if (drag.dataTransfer) deliver(found.entry, drag.dataTransfer);\n },\n keydown: (event) => {\n if ((event as KeyboardEvent).key === \"Escape\" && session()) end();\n },\n // Engines send no pointer moves during a drag: one long after the last drag event means the drag ended somewhere the\n // page did not see. One right after it belongs to another pointer, such as a second finger on a touch screen.\n pointermove: (event) => {\n if (session() && event.timeStamp - lastDragEvent > DRAG_SILENCE_MS) end();\n },\n visibilitychange: () => {\n if (doc.visibilityState === \"hidden\") end();\n },\n };\n\n let installed = false;\n const install = () => {\n if (installed || !view) return;\n installed = true;\n for (const [type, listener] of Object.entries(listeners))\n (type === \"visibilitychange\" ? doc : view).addEventListener(type, listener, { capture: true });\n };\n\n return {\n session,\n frame,\n addRegion: (entry) => {\n install();\n regions.add(entry);\n return () => {\n regions.delete(entry);\n const current = session();\n if (current?.hover?.entry === entry) {\n mark(null);\n setSession({ ...current, hover: null });\n }\n };\n },\n setTarget: (element, entry) => {\n install();\n targets.set(element, entry);\n },\n };\n};\n\n/**\n * The document an element lives in. A freshly rendered element still belongs to the inert document of the template it\n * was cloned from; until it is inserted, that is the page's document.\n */\nexport const liveDocument = (element: Element): Document => (element.ownerDocument.defaultView ? element.ownerDocument : document);\n\n/** The one drag tracker of a document, shared by every drop target in it. */\nexport const fileDropEngine = (doc: Document): FileDropEngine => {\n let engine = engines.get(doc);\n if (!engine) {\n engine = createEngine(doc);\n engines.set(doc, engine);\n }\n return engine;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["inputs/file-drop.ts"],"sourcesContent":["import { text } from \"@k2b/stdlib\";\nimport { checkMimeType } from \"@k2b/stdlib/browser\";\nimport { type Accessor, createSignal } from \"solid-js\";\nimport { announce } from \"../feedback/announce\";\nimport { toast } from \"../feedback/toast\";\nimport type { FileDropMessages } from \"./file-drop-messages\";\n\nexport type FileDropRejection = {\n file: File;\n /** `type` misses `accept`, `size` exceeds `maxSize`, `count` is past `maxFiles` or the single file of `multiple={false}`. */\n reason: \"type\" | \"size\" | \"count\";\n};\n\nexport type FileDropDetails = {\n /** The drop's data, readable only while `onDrop` runs synchronously; read folder entries before the first `await`. */\n dataTransfer: DataTransfer;\n /** Files left out by `accept`, `maxSize`, or the file count; the user has already been told. */\n rejected: readonly FileDropRejection[];\n};\n\nexport type FileDropOptions = {\n /** One sentence that says what dropping does here, such as \"Drop to attach to the message\". */\n label: string;\n /** `<input accept>` syntax, such as `\"image/*,.pdf\"`. */\n accept?: string;\n /** Defaults to `true`; `false` takes the first fitting file. */\n multiple?: boolean;\n /** The most files one drop hands over. */\n maxFiles?: number;\n /** The largest file in bytes. */\n maxSize?: number;\n disabled?: boolean;\n /**\n * Called synchronously in the drop with the files that fit. `files` is empty only when the drop carried no file\n * objects at all, as some engines hand over dropped folders; `details.dataTransfer.items` still has their entries.\n */\n onDrop: (files: File[], details: FileDropDetails) => void | Promise<void>;\n};\n\nexport type FileDropTargetEntry = {\n options: FileDropOptions;\n messages: () => FileDropMessages;\n locale: () => string;\n /** Set for regions: the area the overlay covers. Specific targets are keyed by their element. */\n region?: () => Element | undefined;\n /** Set for regions: where the target itself is rendered; a region whose host is hidden takes no drops. */\n host?: () => Element | undefined;\n /** Set for specific targets that show the drop sentence themselves, so the area's overlay does not repeat it. */\n labelled?: boolean;\n};\n\nexport type FileDropHover = { entry: FileDropTargetEntry; element: Element; invalid: boolean };\n\nexport type FileDropSession = {\n /** Regions that show their overlay during this drag: eligible, visible, and not inside another shown region. */\n shown: readonly FileDropTargetEntry[];\n hover: FileDropHover | null;\n};\n\nexport type FileDropEngine = {\n session: Accessor<FileDropSession | null>;\n /** Changes on every drag movement, so overlays can follow a region that moved or resized. */\n frame: Accessor<number>;\n addRegion: (entry: FileDropTargetEntry) => () => void;\n setTarget: (element: Element, entry: FileDropTargetEntry) => void;\n};\n\n/** The marker a hovered specific target carries for its ring; regions show their own overlay instead. */\nexport const FILE_DROP_ATTRIBUTE = \"data-file-drop\";\n\n/** Where a region without `for` looks for its area: the nearest dialog, workspace detail, or workspace main area. */\nexport const FILE_DROP_DEFAULT_REGION = \"dialog, .k2b-app-workspace__detail, .k2b-app-workspace__main\";\n\n/**\n * The type every drag that starts in a page carries. Such a drag holds page content, never files from outside, even\n * an image that carries one. Marking the drag itself leaves nothing behind when it never reports its end, as when its\n * start is cancelled or its source is removed.\n */\nconst PAGE_DRAG_TYPE = \"application/x-k2b-page-drag\";\n\n/** How long after the last drag event a pointer move means the drag ended; a drag over the page repeats them sooner. */\nconst DRAG_SILENCE_MS = 600;\n\nconst engines = new WeakMap<Document, FileDropEngine>();\n\nconst isFileDrag = (event: DragEvent) => {\n const types = Array.from(event.dataTransfer?.types ?? []);\n return types.includes(\"Files\") && !types.includes(PAGE_DRAG_TYPE);\n};\n\nconst elementOf = (target: EventTarget | null): Element | null =>\n target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n\nconst isModal = (dialog: Element) => {\n try {\n return dialog.matches(\":modal\");\n } catch {\n // An engine without `:modal` has no modal dialogs to defer to.\n return false;\n }\n};\n\n/**\n * The topmost modal dialog. Everything outside of it is inert, so a drag over the page lands inside it; only a drag\n * over other top-layer content falls back to the last modal dialog in the document.\n */\nconst topModal = (doc: Document, target: EventTarget | null): Element | null => {\n for (let dialog = elementOf(target)?.closest(\"dialog\"); dialog; dialog = dialog.parentElement?.closest(\"dialog\"))\n if (isModal(dialog)) return dialog;\n return Array.from(doc.querySelectorAll(\"dialog[open]\")).filter(isModal).at(-1) ?? null;\n};\n\n/** Sorts dropped files into the ones a target takes and the ones it leaves out, in drop order. */\nexport const partitionDroppedFiles = (\n files: readonly File[],\n options: Pick<FileDropOptions, \"accept\" | \"multiple\" | \"maxFiles\" | \"maxSize\">,\n): { accepted: File[]; rejected: FileDropRejection[] } => {\n const limit = options.multiple === false ? 1 : (options.maxFiles ?? Number.POSITIVE_INFINITY);\n const accepted: File[] = [];\n const rejected: FileDropRejection[] = [];\n for (const file of files) {\n if (options.accept && !checkMimeType(file, options.accept)) rejected.push({ file, reason: \"type\" });\n else if (options.maxSize !== undefined && file.size > options.maxSize) rejected.push({ file, reason: \"size\" });\n else if (accepted.length >= limit) rejected.push({ file, reason: \"count\" });\n else accepted.push(file);\n }\n return { accepted, rejected };\n};\n\n/**\n * During a drag only the types are readable, and only in some engines. A drag is refused when none of them can fit.\n * An extension in `accept` matches by file name, and systems report differing types for one extension (a `.csv` may be\n * `application/vnd.ms-excel`), so with one the drop decides.\n */\nexport const refusesDraggedTypes = (types: readonly string[], accept: string | undefined): boolean => {\n if (!accept || accept.split(\",\").some((entry) => entry.trim().startsWith(\".\"))) return false;\n return types.length > 0 && types.every((type) => type !== \"\" && !checkMimeType(type, accept));\n};\n\nconst invalidDrag = (event: DragEvent, options: FileDropOptions) =>\n refusesDraggedTypes(\n Array.from(event.dataTransfer?.items ?? [])\n .filter((item) => item.kind === \"file\")\n .map((item) => item.type),\n options.accept,\n );\n\nconst MAX_NAMES = 3;\nconst nameList = (files: readonly File[], messages: FileDropMessages) => {\n const names = files.slice(0, MAX_NAMES).map((file) => file.name);\n return files.length > MAX_NAMES ? `${names.join(\", \")} ${messages.fileDropMore({ count: files.length - MAX_NAMES })}` : names.join(\", \");\n};\n\nexport const fileDropRejectionMessage = (\n rejected: readonly FileDropRejection[],\n options: Pick<FileDropOptions, \"multiple\" | \"maxFiles\" | \"maxSize\">,\n messages: FileDropMessages,\n locale: string,\n): string => {\n const lines: string[] = [];\n const of = (reason: FileDropRejection[\"reason\"]) => rejected.filter((entry) => entry.reason === reason).map((entry) => entry.file);\n const type = of(\"type\");\n const size = of(\"size\");\n const count = of(\"count\");\n if (type.length) lines.push(messages.fileDropRejectedType({ names: nameList(type, messages) }));\n if (size.length)\n lines.push(\n messages.fileDropRejectedSize({ names: nameList(size, messages), limit: text.pprintBytes(options.maxSize ?? 0, { locale }) }),\n );\n if (count.length)\n lines.push(\n messages.fileDropRejectedCount({ names: nameList(count, messages), max: options.multiple === false ? 1 : (options.maxFiles ?? 1) }),\n );\n return lines.join(\"\\n\");\n};\n\nconst createEngine = (doc: Document): FileDropEngine => {\n const view = doc.defaultView;\n const regions = new Set<FileDropTargetEntry>();\n const targets = new WeakMap<Element, FileDropTargetEntry>();\n const [session, setSession] = createSignal<FileDropSession | null>(null);\n const [frame, setFrame] = createSignal(0);\n /** Elements the drag has entered and not yet left; the drag is over the window while any remains. */\n const entered = new Set<EventTarget>();\n let lastDragEvent = 0;\n let marked: Element | null = null;\n let frameRequest = 0;\n\n const mark = (hover: FileDropHover | null) => {\n if (marked && marked !== hover?.element) marked.removeAttribute(FILE_DROP_ATTRIBUTE);\n marked = null;\n if (!hover || hover.entry.region) return;\n marked = hover.element;\n marked.setAttribute(FILE_DROP_ATTRIBUTE, hover.invalid ? \"invalid\" : \"over\");\n };\n\n const regionElement = (entry: FileDropTargetEntry) => {\n const element = entry.region?.();\n return element?.isConnected ? element : undefined;\n };\n\n /** Whether nothing between the target's host and its area hides it, as a dialog stack hides its lower levels. */\n const displayed = (host: Element | undefined, area: Element) => {\n for (let element: Element | null | undefined = host; element && element !== area; element = element.parentElement)\n if (view?.getComputedStyle(element).display === \"none\") return false;\n return true;\n };\n\n /** A region takes part when it is enabled, displayed, and not behind a modal dialog it is not inside of. */\n const eligible = (entry: FileDropTargetEntry, modal: Element | null) => {\n const element = regionElement(entry);\n if (!element || entry.options.disabled) return false;\n return (!modal || modal.contains(element)) && displayed(entry.host?.(), element);\n };\n const rendered = (element: Element) => element === doc.documentElement || element.getClientRects().length > 0;\n\n const begin = (target: EventTarget | null) => {\n const modal = topModal(doc, target);\n const candidates = [...regions].filter((entry) => eligible(entry, modal) && rendered(regionElement(entry)!));\n // The latest region on an element replaces earlier ones; a region inside another shown one acts as a specific target.\n const byElement = new Map<Element, FileDropTargetEntry>();\n for (const entry of candidates) byElement.set(regionElement(entry)!, entry);\n const shown = [...byElement].filter(\n ([element]) => ![...byElement.keys()].some((other) => other !== element && other.contains(element)),\n );\n setSession({ shown: shown.map(([, entry]) => entry), hover: null });\n const first = shown[0]?.[1];\n if (first) announce(first.options.label);\n };\n\n const end = () => {\n entered.clear();\n mark(null);\n if (session()) setSession(null);\n };\n\n const resolve = (target: EventTarget | null): { entry: FileDropTargetEntry; element: Element } | null => {\n const modal = topModal(doc, target);\n for (let element = elementOf(target); element; element = element.parentElement) {\n const specific = targets.get(element);\n if (specific && !specific.options.disabled) return { entry: specific, element };\n let region: FileDropTargetEntry | undefined;\n for (const entry of regions) if (regionElement(entry) === element && eligible(entry, modal)) region = entry;\n if (region) return { entry: region, element };\n }\n return null;\n };\n\n const hoverFrom = (event: DragEvent) => {\n const current = session();\n if (!current) return null;\n const found = resolve(event.target);\n const hover = found ? { ...found, invalid: invalidDrag(event, found.entry.options) } : null;\n const previous = current.hover;\n if (previous?.entry !== hover?.entry || previous?.element !== hover?.element || previous?.invalid !== hover?.invalid) {\n mark(hover);\n setSession({ ...current, hover });\n }\n return hover;\n };\n\n /** Over a page with a region, a file never falls through to the browser, which would open it and leave the page. */\n const guarding = () => [...regions].some((entry) => regionElement(entry));\n\n const accept = (event: DragEvent, hover: FileDropHover | null) => {\n if (!hover && !guarding()) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = hover && !hover.invalid ? \"copy\" : \"none\";\n };\n\n const requestFrame = () => {\n if (frameRequest || !view) return;\n frameRequest = view.requestAnimationFrame(() => {\n frameRequest = 0;\n setFrame((value) => value + 1);\n });\n };\n\n const deliver = (entry: FileDropTargetEntry, dataTransfer: DataTransfer) => {\n const { options } = entry;\n const files = Array.from(dataTransfer.files);\n const { accepted, rejected } = partitionDroppedFiles(files, options);\n const messages = entry.messages();\n if (rejected.length) toast.error(fileDropRejectionMessage(rejected, options, messages, entry.locale()));\n if (!accepted.length && files.length) return;\n if (accepted.length)\n announce(\n accepted.length === 1\n ? messages.fileDropDroppedOne({ name: accepted[0]!.name })\n : messages.fileDropDropped({ count: accepted.length }),\n );\n void options.onDrop(accepted, { dataTransfer, rejected });\n };\n\n const listeners: Record<string, (event: Event) => void> = {\n dragstart: (event) => {\n (event as DragEvent).dataTransfer?.setData(PAGE_DRAG_TYPE, \"\");\n },\n dragenter: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n lastDragEvent = event.timeStamp;\n if (event.target) entered.add(event.target);\n if (!session()) begin(event.target);\n accept(drag, hoverFrom(drag));\n },\n dragover: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n lastDragEvent = event.timeStamp;\n // An engine may skip the first dragenter; the drag still counts as over the window.\n if (!session()) {\n if (event.target) entered.add(event.target);\n begin(event.target);\n }\n accept(drag, hoverFrom(drag));\n requestFrame();\n },\n dragleave: (event) => {\n if (!session()) return;\n if (event.target) entered.delete(event.target);\n // An element removed during the drag never reports leaving.\n for (const target of entered) if (target instanceof Node && !target.isConnected) entered.delete(target);\n if (entered.size === 0) end();\n },\n drop: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n const found = resolve(event.target);\n end();\n if (!found) {\n if (guarding()) event.preventDefault();\n return;\n }\n // The most specific target owns the drop; editors and other handlers below it never see the files.\n event.preventDefault();\n event.stopPropagation();\n if (drag.dataTransfer) deliver(found.entry, drag.dataTransfer);\n },\n keydown: (event) => {\n if ((event as KeyboardEvent).key === \"Escape\" && session()) end();\n },\n // Engines send no pointer moves during a drag: one long after the last drag event means the drag ended somewhere the\n // page did not see. One right after it belongs to another pointer, such as a second finger on a touch screen.\n pointermove: (event) => {\n if (session() && event.timeStamp - lastDragEvent > DRAG_SILENCE_MS) end();\n },\n visibilitychange: () => {\n if (doc.visibilityState === \"hidden\") end();\n },\n };\n\n let installed = false;\n const install = () => {\n if (installed || !view) return;\n installed = true;\n for (const [type, listener] of Object.entries(listeners))\n (type === \"visibilitychange\" ? doc : view).addEventListener(type, listener, { capture: true });\n };\n\n return {\n session,\n frame,\n addRegion: (entry) => {\n install();\n regions.add(entry);\n return () => {\n regions.delete(entry);\n const current = session();\n if (current?.hover?.entry === entry) {\n mark(null);\n setSession({ ...current, hover: null });\n }\n };\n },\n setTarget: (element, entry) => {\n install();\n targets.set(element, entry);\n },\n };\n};\n\n/**\n * The document an element lives in. A freshly rendered element still belongs to the inert document of the template it\n * was cloned from; until it is inserted, that is the page's document.\n */\nexport const liveDocument = (element: Element): Document => (element.ownerDocument.defaultView ? element.ownerDocument : document);\n\n/** The one drag tracker of a document, shared by every drop target in it. */\nexport const fileDropEngine = (doc: Document): FileDropEngine => {\n let engine = engines.get(doc);\n if (!engine) {\n engine = createEngine(doc);\n engines.set(doc, engine);\n }\n return engine;\n};\n"],"mappings":"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","ignoreList":[]}