@formicoidea/labre-core 0.23.0 → 0.23.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1624) hide show
  1. package/package.json +1 -1
  2. package/src/_pkgs/affine-block-attachment/adapters/extension.ts +9 -9
  3. package/src/_pkgs/affine-block-attachment/adapters/markdown.ts +85 -85
  4. package/src/_pkgs/affine-block-attachment/adapters/notion-html.ts +115 -115
  5. package/src/_pkgs/affine-block-attachment/attachment-block.ts +533 -533
  6. package/src/_pkgs/affine-block-attachment/attachment-edgeless-block.ts +72 -72
  7. package/src/_pkgs/affine-block-attachment/attachment-service.ts +51 -51
  8. package/src/_pkgs/affine-block-attachment/components/rename-model.ts +95 -95
  9. package/src/_pkgs/affine-block-attachment/components/styles.ts +64 -64
  10. package/src/_pkgs/affine-block-attachment/configs/slash-menu.ts +58 -58
  11. package/src/_pkgs/affine-block-attachment/configs/toolbar.ts +411 -411
  12. package/src/_pkgs/affine-block-attachment/edgeless-clipboard-config.ts +34 -34
  13. package/src/_pkgs/affine-block-attachment/embed.ts +305 -305
  14. package/src/_pkgs/affine-block-attachment/store.ts +17 -17
  15. package/src/_pkgs/affine-block-attachment/styles.ts +160 -160
  16. package/src/_pkgs/affine-block-attachment/utils.ts +216 -216
  17. package/src/_pkgs/affine-block-attachment/view.ts +51 -51
  18. package/src/_pkgs/affine-block-bookmark/adapters/extension.ts +13 -13
  19. package/src/_pkgs/affine-block-bookmark/adapters/html.ts +10 -10
  20. package/src/_pkgs/affine-block-bookmark/adapters/markdown/index.ts +12 -12
  21. package/src/_pkgs/affine-block-bookmark/adapters/markdown/markdown.ts +93 -93
  22. package/src/_pkgs/affine-block-bookmark/adapters/markdown/preprocessor.ts +263 -263
  23. package/src/_pkgs/affine-block-bookmark/adapters/notion-html.ts +71 -71
  24. package/src/_pkgs/affine-block-bookmark/adapters/plain-text.ts +9 -9
  25. package/src/_pkgs/affine-block-bookmark/bookmark-block.ts +291 -291
  26. package/src/_pkgs/affine-block-bookmark/bookmark-edgeless-block.ts +88 -88
  27. package/src/_pkgs/affine-block-bookmark/commands/insert-bookmark.ts +23 -23
  28. package/src/_pkgs/affine-block-bookmark/commands/insert-link-by-quick-search.ts +79 -79
  29. package/src/_pkgs/affine-block-bookmark/components/bookmark-card.ts +131 -131
  30. package/src/_pkgs/affine-block-bookmark/configs/slash-menu.ts +65 -65
  31. package/src/_pkgs/affine-block-bookmark/configs/toolbar.ts +625 -625
  32. package/src/_pkgs/affine-block-bookmark/edgeless-clipboard-config.ts +29 -29
  33. package/src/_pkgs/affine-block-bookmark/store.ts +17 -17
  34. package/src/_pkgs/affine-block-bookmark/styles.ts +282 -282
  35. package/src/_pkgs/affine-block-bookmark/utils.ts +47 -47
  36. package/src/_pkgs/affine-block-bookmark/view.ts +43 -43
  37. package/src/_pkgs/affine-block-callout/adapters/markdown.ts +207 -207
  38. package/src/_pkgs/affine-block-callout/callout-block.ts +132 -132
  39. package/src/_pkgs/affine-block-callout/callout-keymap.ts +34 -34
  40. package/src/_pkgs/affine-block-callout/configs/slash-menu.ts +67 -67
  41. package/src/_pkgs/affine-block-callout/emoji-menu.ts +34 -34
  42. package/src/_pkgs/affine-block-callout/store.ts +17 -17
  43. package/src/_pkgs/affine-block-callout/view.ts +30 -30
  44. package/src/_pkgs/affine-block-code/adapters/extension.ts +13 -13
  45. package/src/_pkgs/affine-block-code/adapters/html.ts +109 -109
  46. package/src/_pkgs/affine-block-code/adapters/markdown/index.ts +12 -12
  47. package/src/_pkgs/affine-block-code/adapters/markdown/markdown.ts +99 -99
  48. package/src/_pkgs/affine-block-code/adapters/markdown/preprocessor.ts +76 -76
  49. package/src/_pkgs/affine-block-code/adapters/notion-html.ts +59 -59
  50. package/src/_pkgs/affine-block-code/adapters/plain-text.ts +26 -26
  51. package/src/_pkgs/affine-block-code/clipboard/index.ts +173 -173
  52. package/src/_pkgs/affine-block-code/code-block-config.ts +19 -19
  53. package/src/_pkgs/affine-block-code/code-block-inline.ts +50 -50
  54. package/src/_pkgs/affine-block-code/code-block-service.ts +69 -69
  55. package/src/_pkgs/affine-block-code/code-block.ts +498 -498
  56. package/src/_pkgs/affine-block-code/code-keymap.ts +7 -7
  57. package/src/_pkgs/affine-block-code/code-preview-extension.ts +27 -27
  58. package/src/_pkgs/affine-block-code/code-toolbar/components/code-toolbar.ts +159 -159
  59. package/src/_pkgs/affine-block-code/code-toolbar/components/lang-button.ts +168 -168
  60. package/src/_pkgs/affine-block-code/code-toolbar/components/preview-button.ts +112 -112
  61. package/src/_pkgs/affine-block-code/code-toolbar/config.ts +284 -284
  62. package/src/_pkgs/affine-block-code/code-toolbar/context.ts +46 -46
  63. package/src/_pkgs/affine-block-code/code-toolbar/index.ts +173 -173
  64. package/src/_pkgs/affine-block-code/code-toolbar/utils.ts +16 -16
  65. package/src/_pkgs/affine-block-code/configs/slash-menu.ts +8 -8
  66. package/src/_pkgs/affine-block-code/highlight/affine-code-unit.ts +122 -122
  67. package/src/_pkgs/affine-block-code/markdown.ts +61 -61
  68. package/src/_pkgs/affine-block-code/store.ts +19 -19
  69. package/src/_pkgs/affine-block-code/styles.ts +73 -73
  70. package/src/_pkgs/affine-block-code/turbo/code-layout-handler.ts +73 -73
  71. package/src/_pkgs/affine-block-code/turbo/code-painter.worker.ts +53 -53
  72. package/src/_pkgs/affine-block-code/view.ts +65 -65
  73. package/src/_pkgs/affine-block-data-view/block-meta/base.ts +37 -37
  74. package/src/_pkgs/affine-block-data-view/block-meta/todo.ts +13 -13
  75. package/src/_pkgs/affine-block-data-view/columns/index.ts +22 -22
  76. package/src/_pkgs/affine-block-data-view/configs/slash-menu.ts +51 -51
  77. package/src/_pkgs/affine-block-data-view/data-source.ts +326 -326
  78. package/src/_pkgs/affine-block-data-view/data-view-block.ts +318 -318
  79. package/src/_pkgs/affine-block-data-view/data-view-model.ts +102 -102
  80. package/src/_pkgs/affine-block-data-view/data-view-spec.ts +8 -8
  81. package/src/_pkgs/affine-block-data-view/store.ts +15 -15
  82. package/src/_pkgs/affine-block-data-view/view.ts +28 -28
  83. package/src/_pkgs/affine-block-data-view/views/index.ts +11 -11
  84. package/src/_pkgs/affine-block-database/adapters/extension.ts +13 -13
  85. package/src/_pkgs/affine-block-database/adapters/html.ts +105 -105
  86. package/src/_pkgs/affine-block-database/adapters/markdown.ts +67 -67
  87. package/src/_pkgs/affine-block-database/adapters/notion-html.ts +358 -358
  88. package/src/_pkgs/affine-block-database/adapters/plain-text.ts +48 -48
  89. package/src/_pkgs/affine-block-database/adapters/utils.ts +109 -109
  90. package/src/_pkgs/affine-block-database/block-icons.ts +45 -45
  91. package/src/_pkgs/affine-block-database/commands.ts +69 -69
  92. package/src/_pkgs/affine-block-database/components/layout.ts +69 -69
  93. package/src/_pkgs/affine-block-database/components/title/index.ts +199 -199
  94. package/src/_pkgs/affine-block-database/config.ts +6 -6
  95. package/src/_pkgs/affine-block-database/configs/slash-menu.ts +83 -83
  96. package/src/_pkgs/affine-block-database/context/host-context.ts +4 -4
  97. package/src/_pkgs/affine-block-database/data-source.ts +667 -667
  98. package/src/_pkgs/affine-block-database/database-block.ts +468 -468
  99. package/src/_pkgs/affine-block-database/database-dnd-preview-block.ts +58 -58
  100. package/src/_pkgs/affine-block-database/detail-panel/block-renderer.ts +158 -158
  101. package/src/_pkgs/affine-block-database/detail-panel/note-renderer.ts +129 -129
  102. package/src/_pkgs/affine-block-database/index.ts +14 -14
  103. package/src/_pkgs/affine-block-database/properties/converts.ts +176 -176
  104. package/src/_pkgs/affine-block-database/properties/created-time/cell-renderer.ts +54 -54
  105. package/src/_pkgs/affine-block-database/properties/created-time/define.ts +30 -30
  106. package/src/_pkgs/affine-block-database/properties/index.ts +29 -29
  107. package/src/_pkgs/affine-block-database/properties/link/cell-renderer-css.ts +99 -99
  108. package/src/_pkgs/affine-block-database/properties/link/cell-renderer.ts +186 -186
  109. package/src/_pkgs/affine-block-database/properties/link/define.ts +25 -25
  110. package/src/_pkgs/affine-block-database/properties/model.ts +20 -20
  111. package/src/_pkgs/affine-block-database/properties/rich-text/cell-renderer.ts +430 -430
  112. package/src/_pkgs/affine-block-database/properties/rich-text/define.ts +77 -77
  113. package/src/_pkgs/affine-block-database/properties/title/cell-renderer-css.ts +31 -31
  114. package/src/_pkgs/affine-block-database/properties/title/cell-renderer.ts +23 -23
  115. package/src/_pkgs/affine-block-database/properties/title/define.ts +83 -83
  116. package/src/_pkgs/affine-block-database/properties/title/icon.ts +21 -21
  117. package/src/_pkgs/affine-block-database/properties/title/text.ts +319 -319
  118. package/src/_pkgs/affine-block-database/selection.ts +68 -68
  119. package/src/_pkgs/affine-block-database/service/index.ts +11 -11
  120. package/src/_pkgs/affine-block-database/store.ts +19 -19
  121. package/src/_pkgs/affine-block-database/utils/block-utils.ts +240 -240
  122. package/src/_pkgs/affine-block-database/utils/title-doc.ts +30 -30
  123. package/src/_pkgs/affine-block-database/view.ts +51 -51
  124. package/src/_pkgs/affine-block-database/views/index.ts +12 -12
  125. package/src/_pkgs/affine-block-divider/adapters/extension.ts +13 -13
  126. package/src/_pkgs/affine-block-divider/adapters/html.ts +53 -53
  127. package/src/_pkgs/affine-block-divider/adapters/markdown.ts +50 -50
  128. package/src/_pkgs/affine-block-divider/adapters/notion-html.ts +38 -38
  129. package/src/_pkgs/affine-block-divider/adapters/plain-text.ts +21 -21
  130. package/src/_pkgs/affine-block-divider/divider-block.ts +50 -50
  131. package/src/_pkgs/affine-block-divider/markdown.ts +63 -63
  132. package/src/_pkgs/affine-block-divider/store.ts +17 -17
  133. package/src/_pkgs/affine-block-divider/view.ts +26 -26
  134. package/src/_pkgs/affine-block-edgeless-text/edgeless-clipboard-config.ts +33 -33
  135. package/src/_pkgs/affine-block-edgeless-text/edgeless-text-block.ts +512 -512
  136. package/src/_pkgs/affine-block-edgeless-text/edgeless-toolbar/config.ts +19 -19
  137. package/src/_pkgs/affine-block-edgeless-text/store.ts +14 -14
  138. package/src/_pkgs/affine-block-edgeless-text/view.ts +37 -37
  139. package/src/_pkgs/affine-block-embed/common/adapters/html.ts +66 -66
  140. package/src/_pkgs/affine-block-embed/common/adapters/markdown.ts +58 -58
  141. package/src/_pkgs/affine-block-embed/common/adapters/notion-html.ts +89 -89
  142. package/src/_pkgs/affine-block-embed/common/adapters/plain-text.ts +40 -40
  143. package/src/_pkgs/affine-block-embed/common/embed-block-element.ts +207 -207
  144. package/src/_pkgs/affine-block-embed/common/insert-embed-card.ts +94 -94
  145. package/src/_pkgs/affine-block-embed/common/render-linked-doc.ts +205 -205
  146. package/src/_pkgs/affine-block-embed/common/to-edgeless-embed-block.ts +78 -78
  147. package/src/_pkgs/affine-block-embed/common/utils.ts +49 -49
  148. package/src/_pkgs/affine-block-embed/configs/toolbar.ts +686 -686
  149. package/src/_pkgs/affine-block-embed/embed-figma-block/adapters/extension.ts +13 -13
  150. package/src/_pkgs/affine-block-embed/embed-figma-block/adapters/html.ts +11 -11
  151. package/src/_pkgs/affine-block-embed/embed-figma-block/adapters/markdown.ts +11 -11
  152. package/src/_pkgs/affine-block-embed/embed-figma-block/adapters/notion-html.ts +14 -14
  153. package/src/_pkgs/affine-block-embed/embed-figma-block/adapters/plain-text.ts +10 -10
  154. package/src/_pkgs/affine-block-embed/embed-figma-block/configs/slash-menu.ts +47 -47
  155. package/src/_pkgs/affine-block-embed/embed-figma-block/edgeless-clipboard-config.ts +25 -25
  156. package/src/_pkgs/affine-block-embed/embed-figma-block/embed-edgeless-figma-block.ts +13 -13
  157. package/src/_pkgs/affine-block-embed/embed-figma-block/embed-figma-block.ts +126 -126
  158. package/src/_pkgs/affine-block-embed/embed-figma-block/embed-figma-service.ts +14 -14
  159. package/src/_pkgs/affine-block-embed/embed-figma-block/embed-figma-spec.ts +26 -26
  160. package/src/_pkgs/affine-block-embed/embed-figma-block/styles.ts +218 -218
  161. package/src/_pkgs/affine-block-embed/embed-github-block/adapters/extension.ts +13 -13
  162. package/src/_pkgs/affine-block-embed/embed-github-block/adapters/html.ts +11 -11
  163. package/src/_pkgs/affine-block-embed/embed-github-block/adapters/markdown.ts +10 -10
  164. package/src/_pkgs/affine-block-embed/embed-github-block/adapters/notion-html.ts +14 -14
  165. package/src/_pkgs/affine-block-embed/embed-github-block/adapters/plain-text.ts +10 -10
  166. package/src/_pkgs/affine-block-embed/embed-github-block/configs/slash-menu.ts +47 -47
  167. package/src/_pkgs/affine-block-embed/embed-github-block/edgeless-clipboard-config.ts +51 -51
  168. package/src/_pkgs/affine-block-embed/embed-github-block/embed-edgeless-github-block.ts +13 -13
  169. package/src/_pkgs/affine-block-embed/embed-github-block/embed-github-block.ts +271 -271
  170. package/src/_pkgs/affine-block-embed/embed-github-block/embed-github-service.ts +36 -36
  171. package/src/_pkgs/affine-block-embed/embed-github-block/embed-github-spec.ts +30 -30
  172. package/src/_pkgs/affine-block-embed/embed-github-block/utils.ts +182 -182
  173. package/src/_pkgs/affine-block-embed/embed-html-block/components/fullscreen-toolbar.ts +171 -171
  174. package/src/_pkgs/affine-block-embed/embed-html-block/configs/toolbar.ts +193 -193
  175. package/src/_pkgs/affine-block-embed/embed-html-block/edgeless-clipboard-config.ts +24 -24
  176. package/src/_pkgs/affine-block-embed/embed-html-block/embed-edgeless-html-block.ts +19 -19
  177. package/src/_pkgs/affine-block-embed/embed-html-block/embed-html-block.ts +114 -114
  178. package/src/_pkgs/affine-block-embed/embed-html-block/embed-html-spec.ts +19 -19
  179. package/src/_pkgs/affine-block-embed/embed-iframe-block/adapters/html.ts +55 -55
  180. package/src/_pkgs/affine-block-embed/embed-iframe-block/adapters/index.ts +15 -15
  181. package/src/_pkgs/affine-block-embed/embed-iframe-block/adapters/markdown.ts +46 -46
  182. package/src/_pkgs/affine-block-embed/embed-iframe-block/adapters/plain-text.ts +31 -31
  183. package/src/_pkgs/affine-block-embed/embed-iframe-block/commands/insert-embed-iframe-with-url.ts +107 -107
  184. package/src/_pkgs/affine-block-embed/embed-iframe-block/commands/insert-empty-embed-iframe.ts +55 -55
  185. package/src/_pkgs/affine-block-embed/embed-iframe-block/components/embed-iframe-error-card.ts +343 -343
  186. package/src/_pkgs/affine-block-embed/embed-iframe-block/components/embed-iframe-idle-card.ts +132 -132
  187. package/src/_pkgs/affine-block-embed/embed-iframe-block/components/embed-iframe-link-edit-popup.ts +122 -122
  188. package/src/_pkgs/affine-block-embed/embed-iframe-block/components/embed-iframe-link-input-base.ts +160 -160
  189. package/src/_pkgs/affine-block-embed/embed-iframe-block/components/embed-iframe-link-input-popup.ts +292 -292
  190. package/src/_pkgs/affine-block-embed/embed-iframe-block/components/embed-iframe-loading-card.ts +193 -193
  191. package/src/_pkgs/affine-block-embed/embed-iframe-block/configs/providers/excalidraw.ts +42 -42
  192. package/src/_pkgs/affine-block-embed/embed-iframe-block/configs/providers/generic.ts +75 -75
  193. package/src/_pkgs/affine-block-embed/embed-iframe-block/configs/providers/google-docs.ts +81 -81
  194. package/src/_pkgs/affine-block-embed/embed-iframe-block/configs/providers/google-drive.ts +197 -197
  195. package/src/_pkgs/affine-block-embed/embed-iframe-block/configs/providers/miro.ts +46 -46
  196. package/src/_pkgs/affine-block-embed/embed-iframe-block/configs/providers/spotify.ts +47 -47
  197. package/src/_pkgs/affine-block-embed/embed-iframe-block/configs/slash-menu/slash-menu.ts +37 -37
  198. package/src/_pkgs/affine-block-embed/embed-iframe-block/configs/toolbar.ts +492 -492
  199. package/src/_pkgs/affine-block-embed/embed-iframe-block/edgeless-clipboard-config.ts +37 -37
  200. package/src/_pkgs/affine-block-embed/embed-iframe-block/embed-edgeless-iframe-block.ts +119 -119
  201. package/src/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.ts +470 -470
  202. package/src/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-spec.ts +23 -23
  203. package/src/_pkgs/affine-block-embed/embed-iframe-block/utils.ts +75 -75
  204. package/src/_pkgs/affine-block-embed/embed-loom-block/adapters/extension.ts +13 -13
  205. package/src/_pkgs/affine-block-embed/embed-loom-block/adapters/html.ts +11 -11
  206. package/src/_pkgs/affine-block-embed/embed-loom-block/adapters/markdown.ts +11 -11
  207. package/src/_pkgs/affine-block-embed/embed-loom-block/adapters/notion-html.ts +14 -14
  208. package/src/_pkgs/affine-block-embed/embed-loom-block/adapters/plain-text.ts +10 -10
  209. package/src/_pkgs/affine-block-embed/embed-loom-block/configs/slash-menu.ts +47 -47
  210. package/src/_pkgs/affine-block-embed/embed-loom-block/edgeless-clipboard-config.ts +28 -28
  211. package/src/_pkgs/affine-block-embed/embed-loom-block/embed-edgeless-loom-bock.ts +13 -13
  212. package/src/_pkgs/affine-block-embed/embed-loom-block/embed-loom-block.ts +171 -171
  213. package/src/_pkgs/affine-block-embed/embed-loom-block/embed-loom-service.ts +25 -25
  214. package/src/_pkgs/affine-block-embed/embed-loom-block/embed-loom-spec.ts +30 -30
  215. package/src/_pkgs/affine-block-embed/embed-loom-block/utils.ts +75 -75
  216. package/src/_pkgs/affine-block-embed/embed-youtube-block/adapters/extension.ts +13 -13
  217. package/src/_pkgs/affine-block-embed/embed-youtube-block/adapters/html.ts +51 -51
  218. package/src/_pkgs/affine-block-embed/embed-youtube-block/adapters/markdown.ts +10 -10
  219. package/src/_pkgs/affine-block-embed/embed-youtube-block/adapters/notion-html.ts +14 -14
  220. package/src/_pkgs/affine-block-embed/embed-youtube-block/adapters/plain-text.ts +12 -12
  221. package/src/_pkgs/affine-block-embed/embed-youtube-block/configs/slash-menu.ts +47 -47
  222. package/src/_pkgs/affine-block-embed/embed-youtube-block/edgeless-clipboard-config.ts +42 -42
  223. package/src/_pkgs/affine-block-embed/embed-youtube-block/embed-edgeless-youtube-block.ts +13 -13
  224. package/src/_pkgs/affine-block-embed/embed-youtube-block/embed-youtube-block.ts +225 -225
  225. package/src/_pkgs/affine-block-embed/embed-youtube-block/embed-youtube-service.ts +35 -35
  226. package/src/_pkgs/affine-block-embed/embed-youtube-block/embed-youtube-spec.ts +30 -30
  227. package/src/_pkgs/affine-block-embed/embed-youtube-block/styles.ts +241 -241
  228. package/src/_pkgs/affine-block-embed/embed-youtube-block/utils.ts +114 -114
  229. package/src/_pkgs/affine-block-embed/store.ts +48 -48
  230. package/src/_pkgs/affine-block-embed/types.ts +23 -23
  231. package/src/_pkgs/affine-block-embed/view.ts +72 -72
  232. package/src/_pkgs/affine-block-embed-doc/common/render-linked-doc.ts +213 -213
  233. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/adapters/extension.ts +11 -11
  234. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/adapters/html.ts +63 -63
  235. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/adapters/markdown.ts +122 -122
  236. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/adapters/plain-text.ts +33 -33
  237. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/commands/insert-embed-linked-doc.ts +34 -34
  238. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/slash-menu.ts +84 -84
  239. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/toolbar.ts +513 -513
  240. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/edgeless-clipboard-config.ts +31 -31
  241. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/embed-edgeless-linked-doc-block.ts +71 -71
  242. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/embed-linked-doc-block.ts +628 -628
  243. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/embed-linked-doc-spec.ts +21 -21
  244. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/styles.ts +2232 -2232
  245. package/src/_pkgs/affine-block-embed-doc/embed-linked-doc-block/utils.ts +102 -102
  246. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/adapters/extension.ts +11 -11
  247. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/adapters/html.ts +88 -88
  248. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/adapters/markdown.ts +64 -64
  249. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/adapters/plain-text.ts +62 -62
  250. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/commands/insert-embed-synced-doc.ts +20 -20
  251. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/components/embed-synced-doc-card.ts +262 -262
  252. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/configs/edgeless-interaction.ts +87 -87
  253. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/configs/index.ts +18 -18
  254. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/configs/toolbar.ts +500 -500
  255. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/edgeless-clipboard-config.ts +27 -27
  256. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-edgeless-synced-doc-block.ts +196 -196
  257. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-synced-doc-block.ts +627 -627
  258. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-synced-doc-spec.ts +20 -20
  259. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/index.ts +8 -8
  260. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/init-height-extension.ts +65 -65
  261. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/styles.ts +1122 -1122
  262. package/src/_pkgs/affine-block-embed-doc/embed-synced-doc-block/utils.ts +74 -74
  263. package/src/_pkgs/affine-block-embed-doc/store.ts +25 -25
  264. package/src/_pkgs/affine-block-embed-doc/view.ts +40 -40
  265. package/src/_pkgs/affine-block-frame/edgeless-clipboard-config.ts +43 -43
  266. package/src/_pkgs/affine-block-frame/edgeless-toolbar/frame-dense-menu.ts +34 -34
  267. package/src/_pkgs/affine-block-frame/edgeless-toolbar/frame-menu.ts +104 -104
  268. package/src/_pkgs/affine-block-frame/edgeless-toolbar/frame-tool-button.ts +49 -49
  269. package/src/_pkgs/affine-block-frame/edgeless-toolbar/presentation-toolbar.ts +560 -560
  270. package/src/_pkgs/affine-block-frame/edgeless-toolbar/quick-tool.ts +16 -16
  271. package/src/_pkgs/affine-block-frame/frame-block.ts +208 -208
  272. package/src/_pkgs/affine-block-frame/frame-highlight-manager.ts +96 -96
  273. package/src/_pkgs/affine-block-frame/frame-manager.ts +503 -503
  274. package/src/_pkgs/affine-block-frame/frame-spec.ts +16 -16
  275. package/src/_pkgs/affine-block-frame/frame-tool.ts +108 -108
  276. package/src/_pkgs/affine-block-frame/frame-toolbar.ts +218 -218
  277. package/src/_pkgs/affine-block-frame/present/frame-order-button.ts +82 -82
  278. package/src/_pkgs/affine-block-frame/present/frame-order-menu.ts +265 -265
  279. package/src/_pkgs/affine-block-frame/present/navigator-bg-widget.ts +126 -126
  280. package/src/_pkgs/affine-block-frame/present/navigator-setting-button.ts +195 -195
  281. package/src/_pkgs/affine-block-frame/present/present-button.ts +40 -40
  282. package/src/_pkgs/affine-block-frame/present-tool.ts +12 -12
  283. package/src/_pkgs/affine-block-frame/store.ts +14 -14
  284. package/src/_pkgs/affine-block-frame/view.ts +39 -39
  285. package/src/_pkgs/affine-block-image/adapters/extension.ts +11 -11
  286. package/src/_pkgs/affine-block-image/adapters/html.ts +90 -90
  287. package/src/_pkgs/affine-block-image/adapters/markdown.ts +66 -66
  288. package/src/_pkgs/affine-block-image/adapters/notion-html.ts +82 -82
  289. package/src/_pkgs/affine-block-image/adapters/utils.ts +89 -89
  290. package/src/_pkgs/affine-block-image/commands/insert-images.ts +40 -40
  291. package/src/_pkgs/affine-block-image/components/image-block-fallback.ts +126 -126
  292. package/src/_pkgs/affine-block-image/components/page-image-block.ts +422 -422
  293. package/src/_pkgs/affine-block-image/configs/slash-menu.ts +32 -32
  294. package/src/_pkgs/affine-block-image/configs/toolbar.ts +174 -174
  295. package/src/_pkgs/affine-block-image/edgeless-clipboard-config.ts +30 -30
  296. package/src/_pkgs/affine-block-image/image-block.ts +194 -194
  297. package/src/_pkgs/affine-block-image/image-edgeless-block.ts +205 -205
  298. package/src/_pkgs/affine-block-image/image-resize-manager.ts +105 -105
  299. package/src/_pkgs/affine-block-image/image-service.ts +46 -46
  300. package/src/_pkgs/affine-block-image/image-spec.ts +29 -29
  301. package/src/_pkgs/affine-block-image/index.ts +11 -11
  302. package/src/_pkgs/affine-block-image/preview-image/edgeless.ts +25 -25
  303. package/src/_pkgs/affine-block-image/preview-image/page.ts +58 -58
  304. package/src/_pkgs/affine-block-image/store.ts +18 -18
  305. package/src/_pkgs/affine-block-image/turbo/image-layout-handler.ts +71 -71
  306. package/src/_pkgs/affine-block-image/turbo/image-painter.worker.ts +56 -56
  307. package/src/_pkgs/affine-block-image/utils.ts +433 -433
  308. package/src/_pkgs/affine-block-image/view.ts +27 -27
  309. package/src/_pkgs/affine-block-latex/adapters/extension.ts +11 -11
  310. package/src/_pkgs/affine-block-latex/adapters/markdown/index.ts +12 -12
  311. package/src/_pkgs/affine-block-latex/adapters/markdown/markdown.ts +55 -55
  312. package/src/_pkgs/affine-block-latex/adapters/markdown/preprocessor.ts +88 -88
  313. package/src/_pkgs/affine-block-latex/adapters/notion-html.ts +50 -50
  314. package/src/_pkgs/affine-block-latex/adapters/plain-text.ts +29 -29
  315. package/src/_pkgs/affine-block-latex/commands.ts +75 -75
  316. package/src/_pkgs/affine-block-latex/configs/slash-menu.ts +62 -62
  317. package/src/_pkgs/affine-block-latex/configs/tooltips.ts +41 -41
  318. package/src/_pkgs/affine-block-latex/latex-block.ts +158 -158
  319. package/src/_pkgs/affine-block-latex/store.ts +19 -19
  320. package/src/_pkgs/affine-block-latex/styles.ts +40 -40
  321. package/src/_pkgs/affine-block-latex/view.ts +27 -27
  322. package/src/_pkgs/affine-block-list/adapters/extension.ts +13 -13
  323. package/src/_pkgs/affine-block-list/adapters/html.ts +203 -203
  324. package/src/_pkgs/affine-block-list/adapters/markdown.ts +156 -156
  325. package/src/_pkgs/affine-block-list/adapters/notion-html.ts +116 -116
  326. package/src/_pkgs/affine-block-list/adapters/plain-text.ts +27 -27
  327. package/src/_pkgs/affine-block-list/commands/convert-to-numbered-list.ts +28 -28
  328. package/src/_pkgs/affine-block-list/commands/dedent-list.ts +165 -165
  329. package/src/_pkgs/affine-block-list/commands/indent-list.ts +147 -147
  330. package/src/_pkgs/affine-block-list/commands/list-to-paragraph.ts +44 -44
  331. package/src/_pkgs/affine-block-list/commands/split-list.ts +250 -250
  332. package/src/_pkgs/affine-block-list/commands/utils.ts +70 -70
  333. package/src/_pkgs/affine-block-list/list-block.ts +216 -216
  334. package/src/_pkgs/affine-block-list/list-keymap.ts +136 -136
  335. package/src/_pkgs/affine-block-list/markdown.ts +91 -91
  336. package/src/_pkgs/affine-block-list/store.ts +17 -17
  337. package/src/_pkgs/affine-block-list/turbo/list-layout-handler.ts +151 -151
  338. package/src/_pkgs/affine-block-list/turbo/list-painter.worker.ts +119 -119
  339. package/src/_pkgs/affine-block-list/utils/forward-delete.ts +75 -75
  340. package/src/_pkgs/affine-block-list/utils/get-list-icon.ts +78 -78
  341. package/src/_pkgs/affine-block-list/view.ts +30 -30
  342. package/src/_pkgs/affine-block-note/adapters/html.ts +44 -44
  343. package/src/_pkgs/affine-block-note/adapters/index.ts +30 -30
  344. package/src/_pkgs/affine-block-note/adapters/markdown.ts +131 -131
  345. package/src/_pkgs/affine-block-note/adapters/plain-text.ts +41 -41
  346. package/src/_pkgs/affine-block-note/commands/block-type.ts +247 -247
  347. package/src/_pkgs/affine-block-note/commands/change-note-display-mode.ts +60 -60
  348. package/src/_pkgs/affine-block-note/commands/dedent-block-to-root.ts +38 -38
  349. package/src/_pkgs/affine-block-note/commands/dedent-block.ts +67 -67
  350. package/src/_pkgs/affine-block-note/commands/dedent-blocks-to-root.ts +43 -43
  351. package/src/_pkgs/affine-block-note/commands/dedent-blocks.ts +87 -87
  352. package/src/_pkgs/affine-block-note/commands/indent-block.ts +74 -74
  353. package/src/_pkgs/affine-block-note/commands/indent-blocks.ts +125 -125
  354. package/src/_pkgs/affine-block-note/commands/select-block.ts +22 -22
  355. package/src/_pkgs/affine-block-note/commands/select-blocks-between.ts +53 -53
  356. package/src/_pkgs/affine-block-note/components/edgeless-note-background.ts +182 -182
  357. package/src/_pkgs/affine-block-note/components/edgeless-note-border-dropdown-menu.ts +42 -42
  358. package/src/_pkgs/affine-block-note/components/edgeless-note-display-mode-dropdown-menu.ts +58 -58
  359. package/src/_pkgs/affine-block-note/components/edgeless-note-mask.ts +84 -84
  360. package/src/_pkgs/affine-block-note/components/edgeless-note-shadow-menu.ts +206 -206
  361. package/src/_pkgs/affine-block-note/components/edgeless-note-style-panel.ts +434 -434
  362. package/src/_pkgs/affine-block-note/components/edgeless-page-block-title.ts +46 -46
  363. package/src/_pkgs/affine-block-note/config.ts +20 -20
  364. package/src/_pkgs/affine-block-note/configs/slash-menu.ts +125 -125
  365. package/src/_pkgs/affine-block-note/configs/toolbar.ts +350 -350
  366. package/src/_pkgs/affine-block-note/configs/tooltips.ts +330 -330
  367. package/src/_pkgs/affine-block-note/edgeless-clipboard-config.ts +28 -28
  368. package/src/_pkgs/affine-block-note/move-block.ts +129 -129
  369. package/src/_pkgs/affine-block-note/note-block.ts +34 -34
  370. package/src/_pkgs/affine-block-note/note-edgeless-block.css.ts +74 -74
  371. package/src/_pkgs/affine-block-note/note-edgeless-block.ts +499 -499
  372. package/src/_pkgs/affine-block-note/note-keymap.ts +611 -611
  373. package/src/_pkgs/affine-block-note/quick-action.ts +66 -66
  374. package/src/_pkgs/affine-block-note/store.ts +36 -36
  375. package/src/_pkgs/affine-block-note/turbo/note-layout-handler.ts +83 -83
  376. package/src/_pkgs/affine-block-note/turbo/note-painter.worker.ts +49 -49
  377. package/src/_pkgs/affine-block-note/view.ts +47 -47
  378. package/src/_pkgs/affine-block-paragraph/adapters/extension.ts +13 -13
  379. package/src/_pkgs/affine-block-paragraph/adapters/html.ts +359 -359
  380. package/src/_pkgs/affine-block-paragraph/adapters/markdown.ts +200 -200
  381. package/src/_pkgs/affine-block-paragraph/adapters/notion-html.ts +239 -239
  382. package/src/_pkgs/affine-block-paragraph/adapters/plain-text.ts +28 -28
  383. package/src/_pkgs/affine-block-paragraph/commands/add-paragraph.ts +56 -56
  384. package/src/_pkgs/affine-block-paragraph/commands/append-paragraph.ts +30 -30
  385. package/src/_pkgs/affine-block-paragraph/commands/dedent-paragraph.ts +114 -114
  386. package/src/_pkgs/affine-block-paragraph/commands/indent-paragraph.ts +156 -156
  387. package/src/_pkgs/affine-block-paragraph/commands/split-paragraph.ts +81 -81
  388. package/src/_pkgs/affine-block-paragraph/heading-icon.ts +92 -92
  389. package/src/_pkgs/affine-block-paragraph/markdown.ts +74 -74
  390. package/src/_pkgs/affine-block-paragraph/paragraph-block-config.ts +9 -9
  391. package/src/_pkgs/affine-block-paragraph/paragraph-block.ts +369 -369
  392. package/src/_pkgs/affine-block-paragraph/paragraph-keymap.ts +230 -230
  393. package/src/_pkgs/affine-block-paragraph/store.ts +17 -17
  394. package/src/_pkgs/affine-block-paragraph/styles.ts +158 -158
  395. package/src/_pkgs/affine-block-paragraph/turbo/paragraph-layout-handler.ts +106 -106
  396. package/src/_pkgs/affine-block-paragraph/turbo/paragraph-painter.worker.ts +115 -115
  397. package/src/_pkgs/affine-block-paragraph/utils/forward-delete.ts +94 -94
  398. package/src/_pkgs/affine-block-paragraph/utils/merge-with-prev.ts +184 -184
  399. package/src/_pkgs/affine-block-paragraph/view.ts +66 -66
  400. package/src/_pkgs/affine-block-root/adapters/extension.ts +11 -11
  401. package/src/_pkgs/affine-block-root/adapters/html.ts +135 -135
  402. package/src/_pkgs/affine-block-root/adapters/markdown.ts +36 -36
  403. package/src/_pkgs/affine-block-root/adapters/notion-html.ts +28 -28
  404. package/src/_pkgs/affine-block-root/clipboard/page-clipboard.ts +176 -176
  405. package/src/_pkgs/affine-block-root/clipboard/readonly-clipboard.ts +71 -71
  406. package/src/_pkgs/affine-block-root/configs/toolbar.ts +398 -398
  407. package/src/_pkgs/affine-block-root/edgeless/clipboard/canvas.ts +117 -117
  408. package/src/_pkgs/affine-block-root/edgeless/clipboard/clipboard.ts +715 -715
  409. package/src/_pkgs/affine-block-root/edgeless/clipboard/command.ts +218 -218
  410. package/src/_pkgs/affine-block-root/edgeless/clipboard/utils.ts +140 -140
  411. package/src/_pkgs/affine-block-root/edgeless/configs/toolbar/alignment.ts +293 -293
  412. package/src/_pkgs/affine-block-root/edgeless/configs/toolbar/index.ts +19 -19
  413. package/src/_pkgs/affine-block-root/edgeless/configs/toolbar/misc.ts +369 -369
  414. package/src/_pkgs/affine-block-root/edgeless/configs/toolbar/more.ts +435 -435
  415. package/src/_pkgs/affine-block-root/edgeless/configs/toolbar/render-linked-doc.ts +103 -96
  416. package/src/_pkgs/affine-block-root/edgeless/configs/toolbar/utils.ts +17 -17
  417. package/src/_pkgs/affine-block-root/edgeless/edgeless-keyboard.ts +753 -753
  418. package/src/_pkgs/affine-block-root/edgeless/edgeless-root-block.ts +524 -524
  419. package/src/_pkgs/affine-block-root/edgeless/edgeless-root-service.ts +231 -231
  420. package/src/_pkgs/affine-block-root/edgeless/edgeless-root-spec.ts +11 -11
  421. package/src/_pkgs/affine-block-root/edgeless/index.ts +9 -9
  422. package/src/_pkgs/affine-block-root/edgeless/interact-extensions/clone-ext.ts +32 -32
  423. package/src/_pkgs/affine-block-root/edgeless/utils/clipboard-utils.ts +97 -97
  424. package/src/_pkgs/affine-block-root/edgeless/utils/clone-utils.ts +237 -237
  425. package/src/_pkgs/affine-block-root/edgeless/utils/connector.ts +34 -34
  426. package/src/_pkgs/affine-block-root/edgeless/utils/crud.ts +37 -37
  427. package/src/_pkgs/affine-block-root/edgeless/utils/query.ts +104 -104
  428. package/src/_pkgs/affine-block-root/keyboard/keyboard-manager.ts +163 -163
  429. package/src/_pkgs/affine-block-root/keyboard/keymap.ts +16 -16
  430. package/src/_pkgs/affine-block-root/page/page-root-block.ts +422 -422
  431. package/src/_pkgs/affine-block-root/preview/edgeless-root-preview-block.ts +262 -262
  432. package/src/_pkgs/affine-block-root/preview/preview-root-block.ts +41 -41
  433. package/src/_pkgs/affine-block-root/store.ts +17 -17
  434. package/src/_pkgs/affine-block-root/view.ts +93 -93
  435. package/src/_pkgs/affine-block-surface/adapters/html-adapter/html.ts +20 -20
  436. package/src/_pkgs/affine-block-surface/adapters/markdown/element-adapter/index.ts +33 -33
  437. package/src/_pkgs/affine-block-surface/adapters/markdown/element-adapter/type.ts +29 -29
  438. package/src/_pkgs/affine-block-surface/adapters/markdown/markdown.ts +76 -76
  439. package/src/_pkgs/affine-block-surface/adapters/plain-text/element-adapter/index.ts +32 -32
  440. package/src/_pkgs/affine-block-surface/adapters/plain-text/element-adapter/type.ts +29 -29
  441. package/src/_pkgs/affine-block-surface/adapters/plain-text/plain-text.ts +77 -77
  442. package/src/_pkgs/affine-block-surface/adapters/type.ts +30 -30
  443. package/src/_pkgs/affine-block-surface/commands/auto-align.ts +157 -157
  444. package/src/_pkgs/affine-block-surface/commands/reassociate-connectors.ts +46 -46
  445. package/src/_pkgs/affine-block-surface/element-model/base.ts +4 -4
  446. package/src/_pkgs/affine-block-surface/element-model/index.ts +96 -96
  447. package/src/_pkgs/affine-block-surface/extensions/clipboard-config.ts +80 -80
  448. package/src/_pkgs/affine-block-surface/extensions/crud-extension.ts +181 -181
  449. package/src/_pkgs/affine-block-surface/extensions/dom-element-renderer.ts +30 -30
  450. package/src/_pkgs/affine-block-surface/extensions/edit-props-middleware-builder.ts +26 -26
  451. package/src/_pkgs/affine-block-surface/extensions/element-renderer.ts +31 -31
  452. package/src/_pkgs/affine-block-surface/extensions/export-manager/export-manager.ts +559 -559
  453. package/src/_pkgs/affine-block-surface/extensions/legacy-slot-extension.ts +39 -39
  454. package/src/_pkgs/affine-block-surface/extensions/query.ts +15 -15
  455. package/src/_pkgs/affine-block-surface/extensions/surface-middleware.ts +23 -23
  456. package/src/_pkgs/affine-block-surface/renderer/canvas-renderer.ts +472 -472
  457. package/src/_pkgs/affine-block-surface/renderer/dom-elements/index.ts +31 -31
  458. package/src/_pkgs/affine-block-surface/renderer/dom-renderer.ts +710 -710
  459. package/src/_pkgs/affine-block-surface/renderer/elements/index.ts +23 -23
  460. package/src/_pkgs/affine-block-surface/renderer/elements/type.ts +6 -6
  461. package/src/_pkgs/affine-block-surface/renderer/overlay.ts +57 -57
  462. package/src/_pkgs/affine-block-surface/renderer/tool-overlay.ts +44 -44
  463. package/src/_pkgs/affine-block-surface/store.ts +17 -17
  464. package/src/_pkgs/affine-block-surface/surface-block-void.ts +16 -16
  465. package/src/_pkgs/affine-block-surface/surface-block.ts +255 -255
  466. package/src/_pkgs/affine-block-surface/surface-model.ts +69 -69
  467. package/src/_pkgs/affine-block-surface/surface-transformer.ts +115 -115
  468. package/src/_pkgs/affine-block-surface/tool/default-tool.ts +374 -374
  469. package/src/_pkgs/affine-block-surface/tool/panning-utils.ts +46 -46
  470. package/src/_pkgs/affine-block-surface/utils/a-star.ts +299 -299
  471. package/src/_pkgs/affine-block-surface/utils/font.ts +47 -47
  472. package/src/_pkgs/affine-block-surface/utils/get-bg-grip-gap.ts +10 -10
  473. package/src/_pkgs/affine-block-surface/utils/get-last-props-key.ts +29 -29
  474. package/src/_pkgs/affine-block-surface/utils/get-surface-block.ts +16 -16
  475. package/src/_pkgs/affine-block-surface/utils/graph.ts +151 -151
  476. package/src/_pkgs/affine-block-surface/utils/update-xywh.ts +82 -82
  477. package/src/_pkgs/affine-block-surface/view.ts +45 -45
  478. package/src/_pkgs/affine-block-surface-ref/commands.ts +60 -60
  479. package/src/_pkgs/affine-block-surface-ref/components/placeholder.ts +131 -131
  480. package/src/_pkgs/affine-block-surface-ref/components/surface-ref-toolbar-title.ts +76 -76
  481. package/src/_pkgs/affine-block-surface-ref/configs/slash-menu.ts +164 -164
  482. package/src/_pkgs/affine-block-surface-ref/configs/toolbar.ts +100 -100
  483. package/src/_pkgs/affine-block-surface-ref/portal/generic-block.ts +82 -82
  484. package/src/_pkgs/affine-block-surface-ref/portal/note.ts +169 -169
  485. package/src/_pkgs/affine-block-surface-ref/store.ts +14 -14
  486. package/src/_pkgs/affine-block-surface-ref/surface-ref-block-edgeless.ts +80 -80
  487. package/src/_pkgs/affine-block-surface-ref/surface-ref-block.ts +511 -511
  488. package/src/_pkgs/affine-block-surface-ref/utils.ts +152 -152
  489. package/src/_pkgs/affine-block-surface-ref/view.ts +49 -49
  490. package/src/_pkgs/affine-block-table/adapters/extension.ts +13 -13
  491. package/src/_pkgs/affine-block-table/adapters/html.ts +129 -129
  492. package/src/_pkgs/affine-block-table/adapters/markdown.ts +82 -82
  493. package/src/_pkgs/affine-block-table/adapters/notion-html.ts +21 -21
  494. package/src/_pkgs/affine-block-table/adapters/plain-text.ts +79 -79
  495. package/src/_pkgs/affine-block-table/adapters/utils.ts +212 -212
  496. package/src/_pkgs/affine-block-table/add-button-css.ts +99 -99
  497. package/src/_pkgs/affine-block-table/add-button.ts +330 -330
  498. package/src/_pkgs/affine-block-table/color.ts +45 -45
  499. package/src/_pkgs/affine-block-table/commands.ts +52 -52
  500. package/src/_pkgs/affine-block-table/configs/slash-menu.ts +44 -44
  501. package/src/_pkgs/affine-block-table/selection-controller.ts +527 -527
  502. package/src/_pkgs/affine-block-table/selection-layer.ts +112 -112
  503. package/src/_pkgs/affine-block-table/selection-schema.ts +112 -112
  504. package/src/_pkgs/affine-block-table/store.ts +19 -19
  505. package/src/_pkgs/affine-block-table/table-block.ts +209 -209
  506. package/src/_pkgs/affine-block-table/table-cell-css.ts +154 -154
  507. package/src/_pkgs/affine-block-table/table-cell.ts +866 -866
  508. package/src/_pkgs/affine-block-table/table-data-manager.ts +382 -382
  509. package/src/_pkgs/affine-block-table/view.ts +29 -29
  510. package/src/_pkgs/affine-components/block-selection/index.ts +69 -69
  511. package/src/_pkgs/affine-components/block-zero-width/index.ts +59 -59
  512. package/src/_pkgs/affine-components/caption/block-caption.ts +188 -188
  513. package/src/_pkgs/affine-components/caption/captioned-block-component.ts +82 -82
  514. package/src/_pkgs/affine-components/card-style-dropdown-menu/dropdown-menu.ts +118 -118
  515. package/src/_pkgs/affine-components/citation/citation.ts +167 -167
  516. package/src/_pkgs/affine-components/color-picker/button.ts +207 -207
  517. package/src/_pkgs/affine-components/color-picker/color-panel.ts +260 -260
  518. package/src/_pkgs/affine-components/color-picker/color-picker.ts +677 -677
  519. package/src/_pkgs/affine-components/color-picker/icons.ts +71 -71
  520. package/src/_pkgs/affine-components/color-picker/styles.ts +308 -308
  521. package/src/_pkgs/affine-components/color-picker/types.ts +53 -53
  522. package/src/_pkgs/affine-components/color-picker/utils.ts +368 -368
  523. package/src/_pkgs/affine-components/context-menu/button.ts +302 -302
  524. package/src/_pkgs/affine-components/context-menu/group.ts +35 -35
  525. package/src/_pkgs/affine-components/context-menu/input.ts +254 -254
  526. package/src/_pkgs/affine-components/context-menu/item.ts +12 -12
  527. package/src/_pkgs/affine-components/context-menu/menu-renderer.ts +574 -574
  528. package/src/_pkgs/affine-components/context-menu/menu.ts +170 -170
  529. package/src/_pkgs/affine-components/context-menu/sub-menu.ts +194 -194
  530. package/src/_pkgs/affine-components/date-picker/date-picker.ts +626 -626
  531. package/src/_pkgs/affine-components/drop-indicator/drop-indicator.ts +51 -51
  532. package/src/_pkgs/affine-components/drop-indicator/file-drop-manager.ts +300 -300
  533. package/src/_pkgs/affine-components/edgeless-line-styles-panel/line-styles-panel.ts +113 -113
  534. package/src/_pkgs/affine-components/edgeless-line-width-panel/line-width-panel.ts +50 -50
  535. package/src/_pkgs/affine-components/edgeless-shape-color-picker/color-picker.ts +318 -318
  536. package/src/_pkgs/affine-components/embed-card-modal/embed-card-create-modal.ts +218 -218
  537. package/src/_pkgs/affine-components/embed-card-modal/embed-card-edit-modal.ts +468 -468
  538. package/src/_pkgs/affine-components/embed-card-modal/styles.ts +131 -131
  539. package/src/_pkgs/affine-components/filterable-list/index.ts +259 -259
  540. package/src/_pkgs/affine-components/filterable-list/styles.ts +109 -109
  541. package/src/_pkgs/affine-components/highlight-dropdown-menu/dropdown-menu.ts +123 -123
  542. package/src/_pkgs/affine-components/hover/controller.ts +201 -201
  543. package/src/_pkgs/affine-components/hover/middlewares/basic.ts +79 -79
  544. package/src/_pkgs/affine-components/link-preview/link.ts +65 -65
  545. package/src/_pkgs/affine-components/linked-doc-title/doc-title.ts +61 -61
  546. package/src/_pkgs/affine-components/notification/linked-doc.ts +45 -45
  547. package/src/_pkgs/affine-components/open-doc-dropdown-menu/dropdown-menu.ts +131 -131
  548. package/src/_pkgs/affine-components/peek/commands.ts +47 -47
  549. package/src/_pkgs/affine-components/peek/peekable.ts +137 -137
  550. package/src/_pkgs/affine-components/peek/service.ts +16 -16
  551. package/src/_pkgs/affine-components/peek/type.ts +70 -70
  552. package/src/_pkgs/affine-components/portal/helper.ts +225 -225
  553. package/src/_pkgs/affine-components/resource/resource.ts +230 -230
  554. package/src/_pkgs/affine-components/resource/status.ts +165 -165
  555. package/src/_pkgs/affine-components/size-dropdown-menu/dropdown-menu.ts +211 -211
  556. package/src/_pkgs/affine-components/slider/slider.ts +159 -159
  557. package/src/_pkgs/affine-components/slider/styles.ts +79 -79
  558. package/src/_pkgs/affine-components/smooth-corner/index.ts +184 -184
  559. package/src/_pkgs/affine-components/toast/create.ts +39 -39
  560. package/src/_pkgs/affine-components/toast/toast.ts +80 -80
  561. package/src/_pkgs/affine-components/toggle-button/toggle-button.ts +97 -97
  562. package/src/_pkgs/affine-components/toggle-switch/index.ts +88 -88
  563. package/src/_pkgs/affine-components/toolbar/config.ts +7 -7
  564. package/src/_pkgs/affine-components/toolbar/icon-button.ts +220 -220
  565. package/src/_pkgs/affine-components/toolbar/menu-button.ts +242 -242
  566. package/src/_pkgs/affine-components/toolbar/menu-context.ts +30 -30
  567. package/src/_pkgs/affine-components/toolbar/toolbar.ts +52 -52
  568. package/src/_pkgs/affine-components/toolbar/tooltip.ts +328 -328
  569. package/src/_pkgs/affine-components/toolbar/utils.ts +120 -120
  570. package/src/_pkgs/affine-components/view-dropdown-menu/dropdown-menu.ts +86 -86
  571. package/src/_pkgs/affine-ext-loader/base-provider.ts +69 -69
  572. package/src/_pkgs/affine-ext-loader/manager.ts +146 -146
  573. package/src/_pkgs/affine-ext-loader/store-manager.ts +47 -47
  574. package/src/_pkgs/affine-ext-loader/view-manager.ts +49 -49
  575. package/src/_pkgs/affine-foundation/clipboard.ts +65 -65
  576. package/src/_pkgs/affine-foundation/effects.ts +70 -70
  577. package/src/_pkgs/affine-foundation/store.ts +54 -54
  578. package/src/_pkgs/affine-foundation/view.ts +108 -108
  579. package/src/_pkgs/affine-fragment-adapter-panel/adapter-panel.ts +177 -177
  580. package/src/_pkgs/affine-fragment-adapter-panel/body/adapter-panel-body.ts +216 -216
  581. package/src/_pkgs/affine-fragment-adapter-panel/config.ts +28 -28
  582. package/src/_pkgs/affine-fragment-adapter-panel/header/adapter-menu.ts +86 -86
  583. package/src/_pkgs/affine-fragment-adapter-panel/header/adapter-panel-header.ts +119 -119
  584. package/src/_pkgs/affine-fragment-adapter-panel/view.ts +12 -12
  585. package/src/_pkgs/affine-fragment-doc-title/doc-title.ts +241 -241
  586. package/src/_pkgs/affine-fragment-doc-title/utils.ts +11 -11
  587. package/src/_pkgs/affine-fragment-doc-title/view.ts +12 -12
  588. package/src/_pkgs/affine-fragment-frame-panel/body/frame-panel-body.ts +436 -436
  589. package/src/_pkgs/affine-fragment-frame-panel/card/frame-card-title-editor.ts +126 -126
  590. package/src/_pkgs/affine-fragment-frame-panel/card/frame-card-title.ts +151 -151
  591. package/src/_pkgs/affine-fragment-frame-panel/card/frame-card.ts +254 -254
  592. package/src/_pkgs/affine-fragment-frame-panel/card/frame-preview.ts +263 -263
  593. package/src/_pkgs/affine-fragment-frame-panel/frame-panel.ts +92 -92
  594. package/src/_pkgs/affine-fragment-frame-panel/header/frame-panel-header.ts +248 -248
  595. package/src/_pkgs/affine-fragment-frame-panel/header/frames-setting-menu.ts +219 -219
  596. package/src/_pkgs/affine-fragment-frame-panel/utils/drag.ts +156 -156
  597. package/src/_pkgs/affine-fragment-frame-panel/view.ts +12 -12
  598. package/src/_pkgs/affine-fragment-outline/body/outline-notice.ts +94 -94
  599. package/src/_pkgs/affine-fragment-outline/body/outline-panel-body.ts +481 -481
  600. package/src/_pkgs/affine-fragment-outline/card/outline-card.ts +278 -278
  601. package/src/_pkgs/affine-fragment-outline/card/outline-preview.ts +228 -228
  602. package/src/_pkgs/affine-fragment-outline/config.ts +97 -97
  603. package/src/_pkgs/affine-fragment-outline/header/outline-panel-header.ts +90 -90
  604. package/src/_pkgs/affine-fragment-outline/header/outline-setting-menu.ts +47 -47
  605. package/src/_pkgs/affine-fragment-outline/mobile-outline-panel.ts +197 -197
  606. package/src/_pkgs/affine-fragment-outline/outline-panel.ts +118 -118
  607. package/src/_pkgs/affine-fragment-outline/outline-viewer.ts +325 -325
  608. package/src/_pkgs/affine-fragment-outline/utils/custom-events.ts +27 -27
  609. package/src/_pkgs/affine-fragment-outline/utils/query.ts +72 -72
  610. package/src/_pkgs/affine-fragment-outline/utils/scroll.ts +201 -201
  611. package/src/_pkgs/affine-fragment-outline/view.ts +12 -12
  612. package/src/_pkgs/affine-gfx-brush/adapter/markdown/index.ts +18 -18
  613. package/src/_pkgs/affine-gfx-brush/adapter/plain-text/index.ts +11 -11
  614. package/src/_pkgs/affine-gfx-brush/brush-tool.ts +200 -200
  615. package/src/_pkgs/affine-gfx-brush/element-renderer.ts +32 -32
  616. package/src/_pkgs/affine-gfx-brush/eraser-tool.ts +158 -158
  617. package/src/_pkgs/affine-gfx-brush/highlighter-tool.ts +179 -179
  618. package/src/_pkgs/affine-gfx-brush/store.ts +19 -19
  619. package/src/_pkgs/affine-gfx-brush/toolbar/components/eraser/eraser-tool-button.ts +75 -75
  620. package/src/_pkgs/affine-gfx-brush/toolbar/components/pen/pen-menu.ts +215 -215
  621. package/src/_pkgs/affine-gfx-brush/toolbar/components/pen/pen-tool-button.ts +195 -195
  622. package/src/_pkgs/affine-gfx-brush/toolbar/configs/brush.ts +120 -120
  623. package/src/_pkgs/affine-gfx-brush/toolbar/configs/highlighter.ts +139 -139
  624. package/src/_pkgs/affine-gfx-brush/toolbar/senior-tool.ts +15 -15
  625. package/src/_pkgs/affine-gfx-brush/view.ts +39 -39
  626. package/src/_pkgs/affine-gfx-connector/adapter/markdown/index.ts +26 -26
  627. package/src/_pkgs/affine-gfx-connector/adapter/plain-text/index.ts +14 -14
  628. package/src/_pkgs/affine-gfx-connector/adapter/text.ts +23 -23
  629. package/src/_pkgs/affine-gfx-connector/components/connector-handle.ts +263 -263
  630. package/src/_pkgs/affine-gfx-connector/connector-manager.ts +1858 -1858
  631. package/src/_pkgs/affine-gfx-connector/connector-tool.ts +279 -279
  632. package/src/_pkgs/affine-gfx-connector/connector-watcher.ts +190 -190
  633. package/src/_pkgs/affine-gfx-connector/element-renderer/connector-dom/index.ts +367 -367
  634. package/src/_pkgs/affine-gfx-connector/element-renderer/connector-dom.ts +11 -11
  635. package/src/_pkgs/affine-gfx-connector/element-renderer/index.ts +315 -315
  636. package/src/_pkgs/affine-gfx-connector/element-renderer/utils.ts +327 -327
  637. package/src/_pkgs/affine-gfx-connector/element-transform/connector-filter.ts +44 -44
  638. package/src/_pkgs/affine-gfx-connector/store.ts +21 -21
  639. package/src/_pkgs/affine-gfx-connector/text/edgeless-connector-label-editor.ts +394 -394
  640. package/src/_pkgs/affine-gfx-connector/text/text.ts +66 -66
  641. package/src/_pkgs/affine-gfx-connector/toolbar/config.ts +436 -436
  642. package/src/_pkgs/affine-gfx-connector/toolbar/connector-dense-menu.ts +58 -58
  643. package/src/_pkgs/affine-gfx-connector/toolbar/connector-menu.ts +153 -153
  644. package/src/_pkgs/affine-gfx-connector/toolbar/connector-tool-button.ts +79 -79
  645. package/src/_pkgs/affine-gfx-connector/toolbar/quick-tool.ts +15 -15
  646. package/src/_pkgs/affine-gfx-connector/view/view.ts +256 -256
  647. package/src/_pkgs/affine-gfx-connector/view.ts +38 -38
  648. package/src/_pkgs/affine-gfx-group/adapter/markdown/index.ts +25 -25
  649. package/src/_pkgs/affine-gfx-group/adapter/plain-text/index.ts +14 -14
  650. package/src/_pkgs/affine-gfx-group/adapter/text.ts +21 -21
  651. package/src/_pkgs/affine-gfx-group/command/group-api.ts +134 -134
  652. package/src/_pkgs/affine-gfx-group/element-renderer/consts.ts +6 -6
  653. package/src/_pkgs/affine-gfx-group/element-renderer/index.ts +67 -67
  654. package/src/_pkgs/affine-gfx-group/element-renderer/utils.ts +77 -77
  655. package/src/_pkgs/affine-gfx-group/element-view.ts +57 -57
  656. package/src/_pkgs/affine-gfx-group/group-watcher.ts +36 -36
  657. package/src/_pkgs/affine-gfx-group/interaction-ext.ts +45 -45
  658. package/src/_pkgs/affine-gfx-group/store.ts +21 -21
  659. package/src/_pkgs/affine-gfx-group/text/edgeless-group-title-editor.ts +189 -189
  660. package/src/_pkgs/affine-gfx-group/text/text.ts +33 -33
  661. package/src/_pkgs/affine-gfx-group/toolbar/config.ts +106 -106
  662. package/src/_pkgs/affine-gfx-group/view.ts +30 -30
  663. package/src/_pkgs/affine-gfx-link/link-tool.ts +13 -13
  664. package/src/_pkgs/affine-gfx-link/toolbar/link-dense-menu.ts +32 -32
  665. package/src/_pkgs/affine-gfx-link/toolbar/link-tool-button.ts +96 -96
  666. package/src/_pkgs/affine-gfx-link/view.ts +23 -23
  667. package/src/_pkgs/affine-gfx-mindmap/adapter/markdown/index.ts +69 -69
  668. package/src/_pkgs/affine-gfx-mindmap/adapter/plain-text/index.ts +13 -13
  669. package/src/_pkgs/affine-gfx-mindmap/adapter/utils.ts +65 -65
  670. package/src/_pkgs/affine-gfx-mindmap/element-renderer.ts +81 -81
  671. package/src/_pkgs/affine-gfx-mindmap/indicator-overlay/index.ts +301 -301
  672. package/src/_pkgs/affine-gfx-mindmap/interactivity/drag-utils.ts +190 -190
  673. package/src/_pkgs/affine-gfx-mindmap/interactivity/mind-map-drag.ts +465 -465
  674. package/src/_pkgs/affine-gfx-mindmap/store.ts +19 -19
  675. package/src/_pkgs/affine-gfx-mindmap/toolbar/assets.ts +46 -46
  676. package/src/_pkgs/affine-gfx-mindmap/toolbar/basket-elements.ts +206 -206
  677. package/src/_pkgs/affine-gfx-mindmap/toolbar/config.ts +199 -199
  678. package/src/_pkgs/affine-gfx-mindmap/toolbar/mindmap-importing-placeholder.ts +54 -54
  679. package/src/_pkgs/affine-gfx-mindmap/toolbar/mindmap-menu.ts +415 -415
  680. package/src/_pkgs/affine-gfx-mindmap/toolbar/mindmap-tool-button.ts +466 -466
  681. package/src/_pkgs/affine-gfx-mindmap/toolbar/senior-tool.ts +15 -15
  682. package/src/_pkgs/affine-gfx-mindmap/toolbar/utils/import-mindmap.ts +143 -143
  683. package/src/_pkgs/affine-gfx-mindmap/utils/index.ts +70 -70
  684. package/src/_pkgs/affine-gfx-mindmap/view/layout.ts +201 -201
  685. package/src/_pkgs/affine-gfx-mindmap/view/utils.ts +692 -692
  686. package/src/_pkgs/affine-gfx-mindmap/view/view.ts +378 -378
  687. package/src/_pkgs/affine-gfx-mindmap/view.ts +36 -36
  688. package/src/_pkgs/affine-gfx-note/components/note-display-mode-panel.ts +104 -104
  689. package/src/_pkgs/affine-gfx-note/components/note-shadow-panel.ts +144 -144
  690. package/src/_pkgs/affine-gfx-note/note-tool.ts +330 -330
  691. package/src/_pkgs/affine-gfx-note/overlay/overlay.ts +161 -161
  692. package/src/_pkgs/affine-gfx-note/toolbar/note-menu-config.ts +151 -151
  693. package/src/_pkgs/affine-gfx-note/toolbar/note-menu.ts +210 -210
  694. package/src/_pkgs/affine-gfx-note/toolbar/note-senior-button.ts +218 -218
  695. package/src/_pkgs/affine-gfx-note/toolbar/note-tool-button.ts +120 -120
  696. package/src/_pkgs/affine-gfx-note/toolbar/senior-tool.ts +11 -11
  697. package/src/_pkgs/affine-gfx-note/view.ts +23 -23
  698. package/src/_pkgs/affine-gfx-pointer/quick-tool/default-tool-button.ts +105 -105
  699. package/src/_pkgs/affine-gfx-pointer/quick-tool/quick-tool.ts +12 -12
  700. package/src/_pkgs/affine-gfx-pointer/snap/snap-manager.ts +139 -139
  701. package/src/_pkgs/affine-gfx-pointer/snap/snap-overlay.ts +816 -816
  702. package/src/_pkgs/affine-gfx-pointer/tools/empty-tool.ts +8 -8
  703. package/src/_pkgs/affine-gfx-pointer/tools/pan-tool.ts +110 -110
  704. package/src/_pkgs/affine-gfx-pointer/view.ts +30 -30
  705. package/src/_pkgs/affine-gfx-shape/adapter/markdown/index.ts +46 -46
  706. package/src/_pkgs/affine-gfx-shape/adapter/plain-text/index.ts +35 -35
  707. package/src/_pkgs/affine-gfx-shape/adapter/utils.ts +36 -36
  708. package/src/_pkgs/affine-gfx-shape/components/shape-panel.ts +65 -65
  709. package/src/_pkgs/affine-gfx-shape/components/shape-style-panel.ts +59 -59
  710. package/src/_pkgs/affine-gfx-shape/consts.ts +19 -19
  711. package/src/_pkgs/affine-gfx-shape/draggable/shape-draggable.ts +367 -367
  712. package/src/_pkgs/affine-gfx-shape/draggable/shape-menu.ts +212 -212
  713. package/src/_pkgs/affine-gfx-shape/draggable/shape-tool-button.ts +99 -99
  714. package/src/_pkgs/affine-gfx-shape/draggable/shape-tool-element.ts +326 -326
  715. package/src/_pkgs/affine-gfx-shape/draggable/utils.ts +150 -150
  716. package/src/_pkgs/affine-gfx-shape/element-renderer/highlighter.ts +41 -41
  717. package/src/_pkgs/affine-gfx-shape/element-renderer/shape/diamond.ts +66 -66
  718. package/src/_pkgs/affine-gfx-shape/element-renderer/shape/ellipse.ts +59 -59
  719. package/src/_pkgs/affine-gfx-shape/element-renderer/shape/index.ts +185 -185
  720. package/src/_pkgs/affine-gfx-shape/element-renderer/shape/polygon.ts +134 -134
  721. package/src/_pkgs/affine-gfx-shape/element-renderer/shape/rect.ts +98 -98
  722. package/src/_pkgs/affine-gfx-shape/element-renderer/shape/triangle.ts +65 -65
  723. package/src/_pkgs/affine-gfx-shape/element-renderer/shape/utils.ts +362 -362
  724. package/src/_pkgs/affine-gfx-shape/element-renderer/shape-dom/index.ts +228 -228
  725. package/src/_pkgs/affine-gfx-shape/element-renderer/shape-dom/utils.ts +59 -59
  726. package/src/_pkgs/affine-gfx-shape/element-renderer/shape-dom.ts +11 -11
  727. package/src/_pkgs/affine-gfx-shape/element-view.ts +612 -612
  728. package/src/_pkgs/affine-gfx-shape/overlay/diamond.ts +23 -23
  729. package/src/_pkgs/affine-gfx-shape/overlay/ellipse.ts +15 -15
  730. package/src/_pkgs/affine-gfx-shape/overlay/factory.ts +37 -37
  731. package/src/_pkgs/affine-gfx-shape/overlay/polygon-drawing-overlay.ts +195 -195
  732. package/src/_pkgs/affine-gfx-shape/overlay/polygon-vertex-editing-overlay.ts +1213 -1213
  733. package/src/_pkgs/affine-gfx-shape/overlay/polygon.ts +28 -28
  734. package/src/_pkgs/affine-gfx-shape/overlay/rect.ts +15 -15
  735. package/src/_pkgs/affine-gfx-shape/overlay/rounded-rect.ts +32 -32
  736. package/src/_pkgs/affine-gfx-shape/overlay/shape-overlay.ts +110 -110
  737. package/src/_pkgs/affine-gfx-shape/overlay/shape.ts +27 -27
  738. package/src/_pkgs/affine-gfx-shape/overlay/triangle.ts +22 -22
  739. package/src/_pkgs/affine-gfx-shape/overlay/utils.ts +59 -59
  740. package/src/_pkgs/affine-gfx-shape/polygon-tool.ts +430 -430
  741. package/src/_pkgs/affine-gfx-shape/shape-tool.ts +368 -368
  742. package/src/_pkgs/affine-gfx-shape/store.ts +19 -19
  743. package/src/_pkgs/affine-gfx-shape/text/edgeless-shape-text-editor.ts +411 -411
  744. package/src/_pkgs/affine-gfx-shape/toolbar/config.ts +361 -361
  745. package/src/_pkgs/affine-gfx-shape/toolbar/senior-tool.ts +15 -15
  746. package/src/_pkgs/affine-gfx-shape/toolbar/shape-menu-config.ts +81 -81
  747. package/src/_pkgs/affine-gfx-shape/view.ts +39 -39
  748. package/src/_pkgs/affine-gfx-template/services/template-middlewares.ts +344 -344
  749. package/src/_pkgs/affine-gfx-template/services/template.ts +432 -432
  750. package/src/_pkgs/affine-gfx-template/template-tool.ts +5 -5
  751. package/src/_pkgs/affine-gfx-template/toolbar/overlay-scrollbar.ts +174 -174
  752. package/src/_pkgs/affine-gfx-template/toolbar/template-panel.ts +517 -517
  753. package/src/_pkgs/affine-gfx-template/toolbar/template-tool-button.ts +225 -225
  754. package/src/_pkgs/affine-gfx-template/toolbar/utils.ts +33 -33
  755. package/src/_pkgs/affine-gfx-template/view.ts +25 -25
  756. package/src/_pkgs/affine-gfx-text/adapter/markdown/index.ts +24 -24
  757. package/src/_pkgs/affine-gfx-text/adapter/plain-text/index.ts +14 -14
  758. package/src/_pkgs/affine-gfx-text/adapter/text.ts +22 -22
  759. package/src/_pkgs/affine-gfx-text/commands/insert-edgeless-text.ts +114 -114
  760. package/src/_pkgs/affine-gfx-text/dblclick-add-edgeless-text.ts +52 -52
  761. package/src/_pkgs/affine-gfx-text/edgeless-text-editor.ts +487 -487
  762. package/src/_pkgs/affine-gfx-text/element-renderer/index.ts +94 -94
  763. package/src/_pkgs/affine-gfx-text/element-renderer/utils.ts +559 -559
  764. package/src/_pkgs/affine-gfx-text/element-view.ts +95 -95
  765. package/src/_pkgs/affine-gfx-text/store.ts +19 -19
  766. package/src/_pkgs/affine-gfx-text/tool.ts +66 -66
  767. package/src/_pkgs/affine-gfx-text/toolbar/actions.ts +396 -396
  768. package/src/_pkgs/affine-gfx-text/toolbar/config.ts +56 -56
  769. package/src/_pkgs/affine-gfx-text/toolbar/text-menu.ts +49 -49
  770. package/src/_pkgs/affine-gfx-text/view.ts +32 -32
  771. package/src/_pkgs/affine-gfx-turbo-renderer/layout/block-layout-provider.ts +29 -29
  772. package/src/_pkgs/affine-gfx-turbo-renderer/painter/painter.worker.ts +129 -129
  773. package/src/_pkgs/affine-gfx-turbo-renderer/renderer-utils.ts +222 -222
  774. package/src/_pkgs/affine-gfx-turbo-renderer/turbo-renderer.ts +431 -431
  775. package/src/_pkgs/affine-inline-comment/inline-comment-manager.ts +218 -218
  776. package/src/_pkgs/affine-inline-comment/inline-comment.ts +97 -97
  777. package/src/_pkgs/affine-inline-comment/inline-spec.ts +38 -38
  778. package/src/_pkgs/affine-inline-comment/utils.ts +64 -64
  779. package/src/_pkgs/affine-inline-comment/view.ts +22 -22
  780. package/src/_pkgs/affine-inline-footnote/adapters/markdown/inline-delta.ts +50 -50
  781. package/src/_pkgs/affine-inline-footnote/adapters/markdown/markdown-inline.ts +57 -57
  782. package/src/_pkgs/affine-inline-footnote/adapters/markdown/preprocessor.ts +54 -54
  783. package/src/_pkgs/affine-inline-footnote/footnote-node/footnote-config.ts +120 -120
  784. package/src/_pkgs/affine-inline-footnote/footnote-node/footnote-node.ts +279 -279
  785. package/src/_pkgs/affine-inline-footnote/footnote-node/footnote-popup-chip.ts +74 -74
  786. package/src/_pkgs/affine-inline-footnote/footnote-node/footnote-popup.ts +223 -223
  787. package/src/_pkgs/affine-inline-footnote/inline-spec.ts +32 -32
  788. package/src/_pkgs/affine-inline-footnote/store.ts +21 -21
  789. package/src/_pkgs/affine-inline-footnote/view.ts +21 -21
  790. package/src/_pkgs/affine-inline-latex/adapters/markdown/inline-delta.ts +21 -21
  791. package/src/_pkgs/affine-inline-latex/adapters/markdown/markdown-inline.ts +12 -12
  792. package/src/_pkgs/affine-inline-latex/adapters/plain-text/inline-delta.ts +21 -21
  793. package/src/_pkgs/affine-inline-latex/command.ts +74 -74
  794. package/src/_pkgs/affine-inline-latex/index.ts +9 -9
  795. package/src/_pkgs/affine-inline-latex/inline-spec.ts +40 -40
  796. package/src/_pkgs/affine-inline-latex/latex-node/latex-editor-menu.ts +210 -210
  797. package/src/_pkgs/affine-inline-latex/latex-node/latex-editor-unit.ts +55 -55
  798. package/src/_pkgs/affine-inline-latex/latex-node/latex-node.ts +265 -265
  799. package/src/_pkgs/affine-inline-latex/markdown.ts +180 -180
  800. package/src/_pkgs/affine-inline-latex/store.ts +21 -21
  801. package/src/_pkgs/affine-inline-latex/view.ts +29 -29
  802. package/src/_pkgs/affine-inline-link/adapters/html/html-inline.ts +70 -70
  803. package/src/_pkgs/affine-inline-link/adapters/html/inline-delta.ts +25 -25
  804. package/src/_pkgs/affine-inline-link/adapters/markdown/inline-delta.ts +36 -36
  805. package/src/_pkgs/affine-inline-link/adapters/markdown/markdown-inline.ts +52 -52
  806. package/src/_pkgs/affine-inline-link/adapters/notion-html/html-inline.ts +52 -52
  807. package/src/_pkgs/affine-inline-link/adapters/plain-text/inline-delta.ts +25 -25
  808. package/src/_pkgs/affine-inline-link/command.ts +42 -42
  809. package/src/_pkgs/affine-inline-link/inline-spec.ts +22 -22
  810. package/src/_pkgs/affine-inline-link/link-node/affine-link.ts +188 -188
  811. package/src/_pkgs/affine-inline-link/link-node/configs/toolbar.ts +365 -365
  812. package/src/_pkgs/affine-inline-link/link-node/link-popup/link-popup.ts +335 -335
  813. package/src/_pkgs/affine-inline-link/link-node/link-popup/styles.ts +162 -162
  814. package/src/_pkgs/affine-inline-link/link-node/link-popup/toggle-link-popup.ts +27 -27
  815. package/src/_pkgs/affine-inline-link/markdown.ts +53 -53
  816. package/src/_pkgs/affine-inline-link/store.ts +27 -27
  817. package/src/_pkgs/affine-inline-link/toolbar.ts +9 -9
  818. package/src/_pkgs/affine-inline-link/view.ts +23 -23
  819. package/src/_pkgs/affine-inline-mention/affine-mention.ts +150 -150
  820. package/src/_pkgs/affine-inline-mention/inline-spec.ts +34 -34
  821. package/src/_pkgs/affine-inline-mention/view.ts +21 -21
  822. package/src/_pkgs/affine-inline-preset/adapters/extensions.ts +21 -21
  823. package/src/_pkgs/affine-inline-preset/adapters/html/html-inline.ts +311 -311
  824. package/src/_pkgs/affine-inline-preset/adapters/html/inline-delta.ts +154 -154
  825. package/src/_pkgs/affine-inline-preset/adapters/markdown/inline-delta.ts +57 -57
  826. package/src/_pkgs/affine-inline-preset/adapters/markdown/markdown-inline.ts +98 -98
  827. package/src/_pkgs/affine-inline-preset/adapters/notion-html/html-inline.ts +256 -256
  828. package/src/_pkgs/affine-inline-preset/command/config.ts +138 -138
  829. package/src/_pkgs/affine-inline-preset/command/consts.ts +19 -19
  830. package/src/_pkgs/affine-inline-preset/command/delete-text.ts +81 -81
  831. package/src/_pkgs/affine-inline-preset/command/format-block.ts +75 -75
  832. package/src/_pkgs/affine-inline-preset/command/format-native.ts +53 -53
  833. package/src/_pkgs/affine-inline-preset/command/format-text.ts +94 -94
  834. package/src/_pkgs/affine-inline-preset/command/text-style.ts +110 -110
  835. package/src/_pkgs/affine-inline-preset/command/utils.ts +226 -226
  836. package/src/_pkgs/affine-inline-preset/default-inline-manager.ts +38 -38
  837. package/src/_pkgs/affine-inline-preset/index.ts +10 -10
  838. package/src/_pkgs/affine-inline-preset/inline-spec.ts +118 -118
  839. package/src/_pkgs/affine-inline-preset/keymap/basic.ts +78 -78
  840. package/src/_pkgs/affine-inline-preset/keymap/bracket.ts +162 -162
  841. package/src/_pkgs/affine-inline-preset/keymap/format.ts +36 -36
  842. package/src/_pkgs/affine-inline-preset/keymap/index.ts +15 -15
  843. package/src/_pkgs/affine-inline-preset/markdown.ts +284 -284
  844. package/src/_pkgs/affine-inline-preset/nodes/affine-text.ts +35 -35
  845. package/src/_pkgs/affine-inline-preset/store.ts +15 -15
  846. package/src/_pkgs/affine-inline-preset/view.ts +25 -25
  847. package/src/_pkgs/affine-inline-reference/adapters/html/inline-delta.ts +42 -42
  848. package/src/_pkgs/affine-inline-reference/adapters/markdown/inline-delta.ts +42 -42
  849. package/src/_pkgs/affine-inline-reference/adapters/plain-text/inline-delta.ts +33 -33
  850. package/src/_pkgs/affine-inline-reference/inline-spec.ts +57 -57
  851. package/src/_pkgs/affine-inline-reference/reference-node/configs/toolbar.ts +247 -247
  852. package/src/_pkgs/affine-inline-reference/reference-node/reference-config.ts +53 -53
  853. package/src/_pkgs/affine-inline-reference/reference-node/reference-node-slots.ts +30 -30
  854. package/src/_pkgs/affine-inline-reference/reference-node/reference-node.ts +318 -318
  855. package/src/_pkgs/affine-inline-reference/reference-node/reference-popup/reference-popup.ts +282 -282
  856. package/src/_pkgs/affine-inline-reference/reference-node/reference-popup/toggle-reference-popup.ts +27 -27
  857. package/src/_pkgs/affine-inline-reference/reference-node/types.ts +15 -15
  858. package/src/_pkgs/affine-inline-reference/store.ts +21 -21
  859. package/src/_pkgs/affine-inline-reference/toolbar.ts +9 -9
  860. package/src/_pkgs/affine-inline-reference/utils.ts +21 -21
  861. package/src/_pkgs/affine-inline-reference/view.ts +25 -25
  862. package/src/_pkgs/affine-model/blocks/attachment/attachment-model.ts +112 -112
  863. package/src/_pkgs/affine-model/blocks/attachment/attachment-transformer.ts +34 -34
  864. package/src/_pkgs/affine-model/blocks/bookmark/bookmark-model.ts +81 -81
  865. package/src/_pkgs/affine-model/blocks/callout/callout-model.ts +44 -44
  866. package/src/_pkgs/affine-model/blocks/code/code-model.ts +52 -52
  867. package/src/_pkgs/affine-model/blocks/database/database-model.ts +43 -43
  868. package/src/_pkgs/affine-model/blocks/divider/divider-model.ts +24 -24
  869. package/src/_pkgs/affine-model/blocks/edgeless-text/edgeless-text-model.ts +94 -94
  870. package/src/_pkgs/affine-model/blocks/embed/figma/figma-model.ts +21 -21
  871. package/src/_pkgs/affine-model/blocks/embed/figma/figma-schema.ts +28 -28
  872. package/src/_pkgs/affine-model/blocks/embed/github/github-model.ts +35 -35
  873. package/src/_pkgs/affine-model/blocks/embed/github/github-schema.ts +37 -37
  874. package/src/_pkgs/affine-model/blocks/embed/html/html-model.ts +17 -17
  875. package/src/_pkgs/affine-model/blocks/embed/html/html-schema.ts +25 -25
  876. package/src/_pkgs/affine-model/blocks/embed/iframe/iframe-model.ts +38 -38
  877. package/src/_pkgs/affine-model/blocks/embed/iframe/iframe-schema.ts +17 -17
  878. package/src/_pkgs/affine-model/blocks/embed/linked-doc/linked-doc-model.ts +24 -24
  879. package/src/_pkgs/affine-model/blocks/embed/linked-doc/linked-doc-schema.ts +30 -30
  880. package/src/_pkgs/affine-model/blocks/embed/loom/loom-model.ts +23 -23
  881. package/src/_pkgs/affine-model/blocks/embed/loom/loom-schema.ts +29 -29
  882. package/src/_pkgs/affine-model/blocks/embed/synced-doc/synced-doc-model.ts +30 -30
  883. package/src/_pkgs/affine-model/blocks/embed/synced-doc/synced-doc-schema.ts +39 -39
  884. package/src/_pkgs/affine-model/blocks/embed/types.ts +58 -58
  885. package/src/_pkgs/affine-model/blocks/embed/youtube/youtube-model.ts +26 -26
  886. package/src/_pkgs/affine-model/blocks/embed/youtube/youtube-schema.ts +33 -33
  887. package/src/_pkgs/affine-model/blocks/frame/frame-model.ts +163 -163
  888. package/src/_pkgs/affine-model/blocks/image/image-model.ts +59 -59
  889. package/src/_pkgs/affine-model/blocks/image/image-transformer.ts +34 -34
  890. package/src/_pkgs/affine-model/blocks/latex/latex-model.ts +47 -47
  891. package/src/_pkgs/affine-model/blocks/list/list-model.ts +56 -56
  892. package/src/_pkgs/affine-model/blocks/note/note-model.ts +167 -167
  893. package/src/_pkgs/affine-model/blocks/paragraph/paragraph-model.ts +62 -62
  894. package/src/_pkgs/affine-model/blocks/root/root-block-model.ts +65 -65
  895. package/src/_pkgs/affine-model/blocks/surface-ref/surface-ref-model.ts +34 -34
  896. package/src/_pkgs/affine-model/blocks/table/table-model.ts +71 -71
  897. package/src/_pkgs/affine-model/consts/doc.ts +94 -94
  898. package/src/_pkgs/affine-model/elements/bpmn/index.ts +2 -2
  899. package/src/_pkgs/affine-model/elements/bpmn/node.ts +42 -42
  900. package/src/_pkgs/affine-model/elements/bpmn/pool.ts +66 -66
  901. package/src/_pkgs/affine-model/elements/brush/brush.ts +219 -219
  902. package/src/_pkgs/affine-model/elements/connector/connector.ts +539 -539
  903. package/src/_pkgs/affine-model/elements/connector/local-connector.ts +58 -58
  904. package/src/_pkgs/affine-model/elements/cynefin/cynefin.ts +78 -78
  905. package/src/_pkgs/affine-model/elements/edgy/facets.ts +87 -87
  906. package/src/_pkgs/affine-model/elements/edgy/node.ts +37 -37
  907. package/src/_pkgs/affine-model/elements/estuarine/estuarine.ts +79 -79
  908. package/src/_pkgs/affine-model/elements/group/group.ts +121 -121
  909. package/src/_pkgs/affine-model/elements/highlighter/highlighter.ts +220 -220
  910. package/src/_pkgs/affine-model/elements/mindmap/mindmap.ts +974 -974
  911. package/src/_pkgs/affine-model/elements/shape/api/diamond.ts +120 -120
  912. package/src/_pkgs/affine-model/elements/shape/api/ellipse.ts +202 -202
  913. package/src/_pkgs/affine-model/elements/shape/api/polygon.ts +424 -424
  914. package/src/_pkgs/affine-model/elements/shape/api/rect.ts +119 -119
  915. package/src/_pkgs/affine-model/elements/shape/api/triangle.ts +116 -116
  916. package/src/_pkgs/affine-model/elements/shape/shape.ts +367 -367
  917. package/src/_pkgs/affine-model/elements/text/text.ts +92 -92
  918. package/src/_pkgs/affine-model/elements/wardley/node.ts +52 -52
  919. package/src/_pkgs/affine-model/elements/wardley/wardley.ts +160 -160
  920. package/src/_pkgs/affine-model/utils/helper.ts +74 -74
  921. package/src/_pkgs/affine-model/utils/types.ts +43 -43
  922. package/src/_pkgs/affine-rich-text/conversion.ts +136 -136
  923. package/src/_pkgs/affine-rich-text/dom.ts +172 -172
  924. package/src/_pkgs/affine-rich-text/hooks.ts +116 -116
  925. package/src/_pkgs/affine-rich-text/rich-text.ts +480 -480
  926. package/src/_pkgs/affine-rich-text/utils.ts +68 -68
  927. package/src/_pkgs/affine-shared/adapters/attachment.ts +147 -147
  928. package/src/_pkgs/affine-shared/adapters/clipboard/clipboard.ts +107 -107
  929. package/src/_pkgs/affine-shared/adapters/html/block-adapter.ts +31 -31
  930. package/src/_pkgs/affine-shared/adapters/html/delta-converter.ts +135 -135
  931. package/src/_pkgs/affine-shared/adapters/html/html.ts +400 -400
  932. package/src/_pkgs/affine-shared/adapters/image.ts +137 -137
  933. package/src/_pkgs/affine-shared/adapters/markdown/block-adapter.ts +31 -31
  934. package/src/_pkgs/affine-shared/adapters/markdown/delta-converter.ts +124 -124
  935. package/src/_pkgs/affine-shared/adapters/markdown/markdown.ts +414 -414
  936. package/src/_pkgs/affine-shared/adapters/markdown/preprocessor.ts +40 -40
  937. package/src/_pkgs/affine-shared/adapters/middlewares/callout-export-options.ts +45 -45
  938. package/src/_pkgs/affine-shared/adapters/middlewares/code.ts +11 -11
  939. package/src/_pkgs/affine-shared/adapters/middlewares/copy.ts +66 -66
  940. package/src/_pkgs/affine-shared/adapters/middlewares/doc-link.ts +44 -44
  941. package/src/_pkgs/affine-shared/adapters/middlewares/file-name.ts +27 -27
  942. package/src/_pkgs/affine-shared/adapters/middlewares/file-path.ts +14 -14
  943. package/src/_pkgs/affine-shared/adapters/middlewares/paste.ts +596 -596
  944. package/src/_pkgs/affine-shared/adapters/middlewares/proxy.ts +53 -53
  945. package/src/_pkgs/affine-shared/adapters/middlewares/replace-id.ts +256 -256
  946. package/src/_pkgs/affine-shared/adapters/middlewares/surface-ref-to-embed.ts +46 -46
  947. package/src/_pkgs/affine-shared/adapters/middlewares/title.ts +15 -15
  948. package/src/_pkgs/affine-shared/adapters/middlewares/upload.ts +118 -118
  949. package/src/_pkgs/affine-shared/adapters/mix-text.ts +360 -360
  950. package/src/_pkgs/affine-shared/adapters/notion-html/block-adapter.ts +33 -33
  951. package/src/_pkgs/affine-shared/adapters/notion-html/delta-converter.ts +105 -105
  952. package/src/_pkgs/affine-shared/adapters/notion-html/notion-html.ts +300 -300
  953. package/src/_pkgs/affine-shared/adapters/notion-text.ts +191 -191
  954. package/src/_pkgs/affine-shared/adapters/plain-text/block-adapter.ts +28 -28
  955. package/src/_pkgs/affine-shared/adapters/plain-text/delta-converter.ts +81 -81
  956. package/src/_pkgs/affine-shared/adapters/plain-text/plain-text.ts +324 -324
  957. package/src/_pkgs/affine-shared/adapters/types/adapter.ts +124 -124
  958. package/src/_pkgs/affine-shared/adapters/types/delta-converter.ts +61 -61
  959. package/src/_pkgs/affine-shared/adapters/types/preprocessor.ts +88 -88
  960. package/src/_pkgs/affine-shared/adapters/utils/text.ts +96 -96
  961. package/src/_pkgs/affine-shared/commands/block-crud/get-block-index.ts +33 -33
  962. package/src/_pkgs/affine-shared/commands/block-crud/get-first-content-block.ts +65 -65
  963. package/src/_pkgs/affine-shared/commands/block-crud/get-last-content-block.ts +67 -67
  964. package/src/_pkgs/affine-shared/commands/block-crud/get-next-block.ts +36 -36
  965. package/src/_pkgs/affine-shared/commands/block-crud/get-prev-block.ts +37 -37
  966. package/src/_pkgs/affine-shared/commands/block-crud/get-selected-blocks.ts +164 -164
  967. package/src/_pkgs/affine-shared/commands/model-crud/clear-and-select-first-model.ts +33 -33
  968. package/src/_pkgs/affine-shared/commands/model-crud/copy-selected-models.ts +25 -25
  969. package/src/_pkgs/affine-shared/commands/model-crud/delete-selected-models.ts +21 -21
  970. package/src/_pkgs/affine-shared/commands/model-crud/draft-selected-models.ts +50 -50
  971. package/src/_pkgs/affine-shared/commands/model-crud/duplicate-selected-model.ts +55 -55
  972. package/src/_pkgs/affine-shared/commands/model-crud/get-selected-models.ts +67 -67
  973. package/src/_pkgs/affine-shared/commands/model-crud/replace-selected-text-with-blocks.ts +399 -399
  974. package/src/_pkgs/affine-shared/commands/model-crud/retain-first-model.ts +19 -19
  975. package/src/_pkgs/affine-shared/commands/selection/focus-block-end.ts +37 -37
  976. package/src/_pkgs/affine-shared/commands/selection/focus-block-start.ts +23 -23
  977. package/src/_pkgs/affine-shared/commands/selection/get-block-selections.ts +10 -10
  978. package/src/_pkgs/affine-shared/commands/selection/get-selection-rects.ts +184 -184
  979. package/src/_pkgs/affine-shared/commands/selection/get-surface-selection.ts +10 -10
  980. package/src/_pkgs/affine-shared/commands/selection/get-text-selection.ts +10 -10
  981. package/src/_pkgs/affine-shared/commands/selection/is-nothing-selected.ts +24 -24
  982. package/src/_pkgs/affine-shared/commands/selection/types.ts +18 -18
  983. package/src/_pkgs/affine-shared/consts/index.ts +90 -90
  984. package/src/_pkgs/affine-shared/selection/hightlight.ts +66 -66
  985. package/src/_pkgs/affine-shared/selection/image.ts +33 -33
  986. package/src/_pkgs/affine-shared/services/auto-clear-selection-service.ts +12 -12
  987. package/src/_pkgs/affine-shared/services/block-meta-service.ts +104 -104
  988. package/src/_pkgs/affine-shared/services/citation-service/citation-service.ts +84 -84
  989. package/src/_pkgs/affine-shared/services/comment-service/block-comment-manager.ts +118 -118
  990. package/src/_pkgs/affine-shared/services/comment-service/comment-provider.ts +44 -44
  991. package/src/_pkgs/affine-shared/services/comment-service/utils.ts +50 -50
  992. package/src/_pkgs/affine-shared/services/doc-display-meta-service.ts +197 -197
  993. package/src/_pkgs/affine-shared/services/doc-mode-service.ts +109 -109
  994. package/src/_pkgs/affine-shared/services/drag-handle-config.ts +65 -65
  995. package/src/_pkgs/affine-shared/services/edit-props-store.ts +217 -217
  996. package/src/_pkgs/affine-shared/services/editor-setting-service.ts +41 -41
  997. package/src/_pkgs/affine-shared/services/embed-iframe/embed-iframe-config.ts +93 -93
  998. package/src/_pkgs/affine-shared/services/embed-iframe/embed-iframe-service.ts +152 -152
  999. package/src/_pkgs/affine-shared/services/embed-option-service.ts +65 -65
  1000. package/src/_pkgs/affine-shared/services/feature-flag-service.ts +65 -65
  1001. package/src/_pkgs/affine-shared/services/file-size-limit-service.ts +23 -23
  1002. package/src/_pkgs/affine-shared/services/font-loader/config.ts +379 -379
  1003. package/src/_pkgs/affine-shared/services/font-loader/font-loader-service.ts +62 -62
  1004. package/src/_pkgs/affine-shared/services/generate-url-service.ts +21 -21
  1005. package/src/_pkgs/affine-shared/services/index.ts +1 -0
  1006. package/src/_pkgs/affine-shared/services/link-preview-service/link-preview-cache.ts +240 -240
  1007. package/src/_pkgs/affine-shared/services/link-preview-service/link-preview-service.ts +210 -210
  1008. package/src/_pkgs/affine-shared/services/link-preview-service/link-preview-storage.ts +81 -81
  1009. package/src/_pkgs/affine-shared/services/linked-doc-creation-service.ts +34 -0
  1010. package/src/_pkgs/affine-shared/services/native-clipboard-service.ts +23 -23
  1011. package/src/_pkgs/affine-shared/services/notification-service.ts +123 -123
  1012. package/src/_pkgs/affine-shared/services/open-doc-config.ts +59 -59
  1013. package/src/_pkgs/affine-shared/services/page-viewport-service.ts +15 -15
  1014. package/src/_pkgs/affine-shared/services/parse-url-service.ts +22 -22
  1015. package/src/_pkgs/affine-shared/services/quick-search-service.ts +31 -31
  1016. package/src/_pkgs/affine-shared/services/sidebar-service.ts +18 -18
  1017. package/src/_pkgs/affine-shared/services/telemetry-service/block-lifecycle-watcher.ts +148 -148
  1018. package/src/_pkgs/affine-shared/services/telemetry-service/noop.ts +20 -20
  1019. package/src/_pkgs/affine-shared/services/telemetry-service/telemetry-service.ts +78 -78
  1020. package/src/_pkgs/affine-shared/services/theme-service.ts +195 -195
  1021. package/src/_pkgs/affine-shared/services/toolbar-service/context.ts +297 -297
  1022. package/src/_pkgs/affine-shared/services/toolbar-service/module.ts +9 -9
  1023. package/src/_pkgs/affine-shared/services/toolbar-service/registry.ts +64 -64
  1024. package/src/_pkgs/affine-shared/services/user-service/user-list-service.ts +28 -28
  1025. package/src/_pkgs/affine-shared/services/user-service/user-service.ts +24 -24
  1026. package/src/_pkgs/affine-shared/services/user-service/writer-info-service.ts +22 -22
  1027. package/src/_pkgs/affine-shared/services/viewport-element-service.ts +62 -62
  1028. package/src/_pkgs/affine-shared/services/virtual-keyboard-service.ts +23 -23
  1029. package/src/_pkgs/affine-shared/test-utils/affine-template.ts +316 -316
  1030. package/src/_pkgs/affine-shared/test-utils/affine-test-utils.ts +113 -113
  1031. package/src/_pkgs/affine-shared/test-utils/create-test-host.ts +248 -248
  1032. package/src/_pkgs/affine-shared/theme/css-variables.ts +132 -132
  1033. package/src/_pkgs/affine-shared/types/index.ts +74 -74
  1034. package/src/_pkgs/affine-shared/utils/button-popper.ts +161 -161
  1035. package/src/_pkgs/affine-shared/utils/collapsed/paragraph.ts +57 -57
  1036. package/src/_pkgs/affine-shared/utils/dnd/calc-drop-target.ts +208 -208
  1037. package/src/_pkgs/affine-shared/utils/dnd/get-drop-rect-by-point.ts +160 -160
  1038. package/src/_pkgs/affine-shared/utils/dnd/types.ts +29 -29
  1039. package/src/_pkgs/affine-shared/utils/dom/checker.ts +18 -18
  1040. package/src/_pkgs/affine-shared/utils/dom/point-to-block.ts +334 -334
  1041. package/src/_pkgs/affine-shared/utils/dom/point-to-range.ts +98 -98
  1042. package/src/_pkgs/affine-shared/utils/dom/query.ts +39 -39
  1043. package/src/_pkgs/affine-shared/utils/dom/viewport.ts +19 -19
  1044. package/src/_pkgs/affine-shared/utils/edgeless.ts +79 -79
  1045. package/src/_pkgs/affine-shared/utils/event.ts +362 -362
  1046. package/src/_pkgs/affine-shared/utils/file/filesys.ts +293 -293
  1047. package/src/_pkgs/affine-shared/utils/model/block-props.ts +6 -6
  1048. package/src/_pkgs/affine-shared/utils/model/checker.ts +34 -34
  1049. package/src/_pkgs/affine-shared/utils/model/doc.ts +38 -38
  1050. package/src/_pkgs/affine-shared/utils/model/get-content-block.ts +140 -140
  1051. package/src/_pkgs/affine-shared/utils/model/getter.ts +75 -75
  1052. package/src/_pkgs/affine-shared/utils/model/list.ts +103 -103
  1053. package/src/_pkgs/affine-shared/utils/model/merge-to-code-model.ts +33 -33
  1054. package/src/_pkgs/affine-shared/utils/model/transform-model.ts +31 -31
  1055. package/src/_pkgs/affine-shared/utils/reference.ts +44 -44
  1056. package/src/_pkgs/affine-shared/utils/title.ts +32 -32
  1057. package/src/_pkgs/affine-shared/utils/virtual-padding.ts +35 -35
  1058. package/src/_pkgs/affine-shared/utils/zod-schema.ts +219 -219
  1059. package/src/_pkgs/affine-widget-drag-handle/components/edgeless-preview/preview.ts +133 -133
  1060. package/src/_pkgs/affine-widget-drag-handle/drag-handle.ts +252 -252
  1061. package/src/_pkgs/affine-widget-drag-handle/helpers/preview-helper.ts +207 -207
  1062. package/src/_pkgs/affine-widget-drag-handle/helpers/rect-helper.ts +95 -95
  1063. package/src/_pkgs/affine-widget-drag-handle/helpers/selection-helper.ts +67 -67
  1064. package/src/_pkgs/affine-widget-drag-handle/index.ts +15 -15
  1065. package/src/_pkgs/affine-widget-drag-handle/middleware/blocks-filter.ts +119 -119
  1066. package/src/_pkgs/affine-widget-drag-handle/middleware/card-style-updater.ts +56 -56
  1067. package/src/_pkgs/affine-widget-drag-handle/middleware/new-id-cross-doc.ts +53 -53
  1068. package/src/_pkgs/affine-widget-drag-handle/middleware/reorder-list.ts +31 -31
  1069. package/src/_pkgs/affine-widget-drag-handle/styles.ts +86 -86
  1070. package/src/_pkgs/affine-widget-drag-handle/utils.ts +346 -346
  1071. package/src/_pkgs/affine-widget-drag-handle/view.ts +21 -21
  1072. package/src/_pkgs/affine-widget-drag-handle/watchers/drag-event-watcher.ts +1742 -1742
  1073. package/src/_pkgs/affine-widget-drag-handle/watchers/edgeless-watcher.ts +235 -235
  1074. package/src/_pkgs/affine-widget-drag-handle/watchers/keyboard-event-watcher.ts +24 -24
  1075. package/src/_pkgs/affine-widget-drag-handle/watchers/page-watcher.ts +21 -21
  1076. package/src/_pkgs/affine-widget-drag-handle/watchers/pointer-event-watcher.ts +366 -366
  1077. package/src/_pkgs/affine-widget-edgeless-auto-connect/index.ts +634 -634
  1078. package/src/_pkgs/affine-widget-edgeless-auto-connect/view.ts +23 -23
  1079. package/src/_pkgs/affine-widget-edgeless-dragging-area/edgeless-dragging-area-rect.ts +68 -68
  1080. package/src/_pkgs/affine-widget-edgeless-dragging-area/view.ts +23 -23
  1081. package/src/_pkgs/affine-widget-edgeless-selected-rect/auto-complete-panel.ts +680 -680
  1082. package/src/_pkgs/affine-widget-edgeless-selected-rect/edgeless-auto-complete.ts +787 -787
  1083. package/src/_pkgs/affine-widget-edgeless-selected-rect/edgeless-selected-rect.ts +844 -844
  1084. package/src/_pkgs/affine-widget-edgeless-selected-rect/resize-handles.ts +94 -94
  1085. package/src/_pkgs/affine-widget-edgeless-selected-rect/spec.ts +10 -10
  1086. package/src/_pkgs/affine-widget-edgeless-selected-rect/utils.ts +416 -416
  1087. package/src/_pkgs/affine-widget-edgeless-selected-rect/view.ts +23 -23
  1088. package/src/_pkgs/affine-widget-edgeless-toolbar/config/types.ts +28 -28
  1089. package/src/_pkgs/affine-widget-edgeless-toolbar/config/utils.ts +72 -72
  1090. package/src/_pkgs/affine-widget-edgeless-toolbar/context.ts +21 -21
  1091. package/src/_pkgs/affine-widget-edgeless-toolbar/create-popper.ts +103 -103
  1092. package/src/_pkgs/affine-widget-edgeless-toolbar/draggable/draggable-element.controller.ts +477 -477
  1093. package/src/_pkgs/affine-widget-edgeless-toolbar/draggable/types.ts +97 -97
  1094. package/src/_pkgs/affine-widget-edgeless-toolbar/menu/slide-menu.ts +184 -184
  1095. package/src/_pkgs/affine-widget-edgeless-toolbar/menu/toolbar-arrow-up-icon.ts +17 -17
  1096. package/src/_pkgs/affine-widget-edgeless-toolbar/mixins/quick-tool.mixin.ts +21 -21
  1097. package/src/_pkgs/affine-widget-edgeless-toolbar/mixins/tool.mixin.ts +171 -171
  1098. package/src/_pkgs/affine-widget-edgeless-toolbar/mixins/toolbar-button-with-menu.mixin.ts +20 -20
  1099. package/src/_pkgs/affine-widget-edgeless-toolbar/panel/font-family-panel.ts +57 -57
  1100. package/src/_pkgs/affine-widget-edgeless-toolbar/panel/font-weight-and-style-panel.ts +163 -163
  1101. package/src/_pkgs/affine-widget-edgeless-toolbar/view.ts +23 -23
  1102. package/src/_pkgs/affine-widget-edgeless-zoom-toolbar/index.ts +94 -94
  1103. package/src/_pkgs/affine-widget-edgeless-zoom-toolbar/view.ts +23 -23
  1104. package/src/_pkgs/affine-widget-edgeless-zoom-toolbar/zoom-bar-toggle-button.ts +113 -113
  1105. package/src/_pkgs/affine-widget-edgeless-zoom-toolbar/zoom-toolbar.ts +213 -213
  1106. package/src/_pkgs/affine-widget-frame-title/affine-frame-title-widget.ts +21 -21
  1107. package/src/_pkgs/affine-widget-frame-title/edgeless-frame-title-editor.ts +185 -185
  1108. package/src/_pkgs/affine-widget-frame-title/frame-title.ts +293 -293
  1109. package/src/_pkgs/affine-widget-frame-title/mount-frame-title-editor.ts +34 -34
  1110. package/src/_pkgs/affine-widget-frame-title/styles.ts +35 -35
  1111. package/src/_pkgs/affine-widget-frame-title/view.ts +23 -23
  1112. package/src/_pkgs/affine-widget-keyboard-toolbar/config.ts +1160 -1160
  1113. package/src/_pkgs/affine-widget-keyboard-toolbar/keyboard-tool-panel.ts +100 -100
  1114. package/src/_pkgs/affine-widget-keyboard-toolbar/keyboard-toolbar.ts +350 -350
  1115. package/src/_pkgs/affine-widget-keyboard-toolbar/position-controller.ts +42 -42
  1116. package/src/_pkgs/affine-widget-keyboard-toolbar/styles.ts +145 -145
  1117. package/src/_pkgs/affine-widget-keyboard-toolbar/view.ts +28 -28
  1118. package/src/_pkgs/affine-widget-keyboard-toolbar/widget.ts +148 -148
  1119. package/src/_pkgs/affine-widget-linked-doc/config.ts +230 -230
  1120. package/src/_pkgs/affine-widget-linked-doc/import-doc/import-doc.ts +297 -297
  1121. package/src/_pkgs/affine-widget-linked-doc/import-doc/index.ts +38 -38
  1122. package/src/_pkgs/affine-widget-linked-doc/import-doc/loader.ts +103 -103
  1123. package/src/_pkgs/affine-widget-linked-doc/linked-doc-popover.ts +428 -428
  1124. package/src/_pkgs/affine-widget-linked-doc/mobile-linked-doc-menu.ts +216 -216
  1125. package/src/_pkgs/affine-widget-linked-doc/styles.ts +163 -163
  1126. package/src/_pkgs/affine-widget-linked-doc/transformers/html.ts +218 -218
  1127. package/src/_pkgs/affine-widget-linked-doc/transformers/markdown.ts +283 -283
  1128. package/src/_pkgs/affine-widget-linked-doc/transformers/notion-html.ts +174 -174
  1129. package/src/_pkgs/affine-widget-linked-doc/transformers/utils.ts +115 -115
  1130. package/src/_pkgs/affine-widget-linked-doc/transformers/zip.ts +172 -172
  1131. package/src/_pkgs/affine-widget-linked-doc/view.ts +83 -83
  1132. package/src/_pkgs/affine-widget-linked-doc/widget.ts +344 -344
  1133. package/src/_pkgs/affine-widget-note-slicer/note-slicer.ts +451 -451
  1134. package/src/_pkgs/affine-widget-note-slicer/view.ts +23 -23
  1135. package/src/_pkgs/affine-widget-page-dragging-area/index.ts +331 -331
  1136. package/src/_pkgs/affine-widget-page-dragging-area/utils.ts +146 -146
  1137. package/src/_pkgs/affine-widget-page-dragging-area/view.ts +24 -24
  1138. package/src/_pkgs/affine-widget-remote-selection/doc/config.ts +5 -5
  1139. package/src/_pkgs/affine-widget-remote-selection/doc/doc-remote-selection.ts +398 -398
  1140. package/src/_pkgs/affine-widget-remote-selection/edgeless/index.ts +304 -304
  1141. package/src/_pkgs/affine-widget-remote-selection/index.ts +20 -20
  1142. package/src/_pkgs/affine-widget-remote-selection/manager/remote-color-manager.ts +42 -42
  1143. package/src/_pkgs/affine-widget-remote-selection/view.ts +27 -27
  1144. package/src/_pkgs/affine-widget-scroll-anchoring/index.ts +12 -12
  1145. package/src/_pkgs/affine-widget-scroll-anchoring/scroll-anchoring.ts +267 -267
  1146. package/src/_pkgs/affine-widget-scroll-anchoring/view.ts +21 -21
  1147. package/src/_pkgs/affine-widget-slash-menu/config.ts +189 -189
  1148. package/src/_pkgs/affine-widget-slash-menu/extensions.ts +51 -51
  1149. package/src/_pkgs/affine-widget-slash-menu/slash-menu-popover.ts +668 -668
  1150. package/src/_pkgs/affine-widget-slash-menu/styles.ts +109 -109
  1151. package/src/_pkgs/affine-widget-slash-menu/types.ts +59 -59
  1152. package/src/_pkgs/affine-widget-slash-menu/view.ts +22 -22
  1153. package/src/_pkgs/affine-widget-slash-menu/widget.ts +184 -184
  1154. package/src/_pkgs/affine-widget-toolbar/index.ts +12 -12
  1155. package/src/_pkgs/affine-widget-toolbar/toolbar.ts +705 -705
  1156. package/src/_pkgs/affine-widget-toolbar/utils.ts +432 -432
  1157. package/src/_pkgs/affine-widget-toolbar/view.ts +22 -22
  1158. package/src/_pkgs/affine-widget-viewport-overlay/index.ts +90 -90
  1159. package/src/_pkgs/affine-widget-viewport-overlay/view.ts +21 -21
  1160. package/src/_pkgs/data-view/core/common/properties.ts +283 -283
  1161. package/src/_pkgs/data-view/core/common/property-menu.ts +76 -76
  1162. package/src/_pkgs/data-view/core/component/button/button.ts +89 -89
  1163. package/src/_pkgs/data-view/core/component/overflow/overflow.ts +109 -109
  1164. package/src/_pkgs/data-view/core/component/tags/multi-tag-select.ts +606 -606
  1165. package/src/_pkgs/data-view/core/component/tags/multi-tag-view.ts +88 -88
  1166. package/src/_pkgs/data-view/core/data-source/base.ts +305 -305
  1167. package/src/_pkgs/data-view/core/data-view.ts +211 -211
  1168. package/src/_pkgs/data-view/core/detail/detail.ts +305 -305
  1169. package/src/_pkgs/data-view/core/detail/field.ts +286 -286
  1170. package/src/_pkgs/data-view/core/expression/ref/ref-view.ts +94 -94
  1171. package/src/_pkgs/data-view/core/expression/types.ts +22 -22
  1172. package/src/_pkgs/data-view/core/filter/add-filter.ts +67 -67
  1173. package/src/_pkgs/data-view/core/filter/literal/define.ts +154 -154
  1174. package/src/_pkgs/data-view/core/filter/literal/types.ts +19 -19
  1175. package/src/_pkgs/data-view/core/filter/utils.ts +66 -66
  1176. package/src/_pkgs/data-view/core/group-by/group-title.ts +231 -231
  1177. package/src/_pkgs/data-view/core/group-by/matcher.ts +41 -41
  1178. package/src/_pkgs/data-view/core/group-by/renderer/base.ts +40 -40
  1179. package/src/_pkgs/data-view/core/group-by/renderer/number-group.ts +65 -65
  1180. package/src/_pkgs/data-view/core/group-by/renderer/select-group.ts +119 -119
  1181. package/src/_pkgs/data-view/core/group-by/renderer/string-group.ts +53 -53
  1182. package/src/_pkgs/data-view/core/group-by/setting.ts +322 -322
  1183. package/src/_pkgs/data-view/core/group-by/trait.ts +362 -362
  1184. package/src/_pkgs/data-view/core/group-by/types.ts +41 -41
  1185. package/src/_pkgs/data-view/core/logical/type-presets.ts +67 -67
  1186. package/src/_pkgs/data-view/core/logical/type-variable.ts +76 -76
  1187. package/src/_pkgs/data-view/core/property/base-cell.ts +134 -134
  1188. package/src/_pkgs/data-view/core/property/manager.ts +44 -44
  1189. package/src/_pkgs/data-view/core/property/renderer.ts +25 -25
  1190. package/src/_pkgs/data-view/core/property/types.ts +99 -99
  1191. package/src/_pkgs/data-view/core/sort/add-sort.ts +53 -53
  1192. package/src/_pkgs/data-view/core/sort/utils.ts +108 -108
  1193. package/src/_pkgs/data-view/core/utils/uni-component/operation.ts +16 -16
  1194. package/src/_pkgs/data-view/core/utils/uni-component/render-template.ts +24 -24
  1195. package/src/_pkgs/data-view/core/utils/uni-component/uni-component.ts +156 -156
  1196. package/src/_pkgs/data-view/core/utils/uni-icon.ts +36 -36
  1197. package/src/_pkgs/data-view/core/view/data-view-base.ts +106 -106
  1198. package/src/_pkgs/data-view/core/view/data-view.ts +80 -80
  1199. package/src/_pkgs/data-view/core/view/types.ts +43 -43
  1200. package/src/_pkgs/data-view/core/view-manager/property.ts +270 -270
  1201. package/src/_pkgs/data-view/core/view-manager/row.ts +65 -65
  1202. package/src/_pkgs/data-view/core/view-manager/single-view.ts +286 -286
  1203. package/src/_pkgs/data-view/core/view-manager/view-manager.ts +130 -130
  1204. package/src/_pkgs/data-view/core/widget/types.ts +10 -10
  1205. package/src/_pkgs/data-view/core/widget/widget-base.ts +28 -28
  1206. package/src/_pkgs/data-view/property-presets/checkbox/cell-renderer.ts +121 -121
  1207. package/src/_pkgs/data-view/property-presets/converts.ts +45 -45
  1208. package/src/_pkgs/data-view/property-presets/date/cell-renderer.ts +167 -167
  1209. package/src/_pkgs/data-view/property-presets/multi-select/cell-renderer.ts +89 -89
  1210. package/src/_pkgs/data-view/property-presets/multi-select/define.ts +76 -76
  1211. package/src/_pkgs/data-view/property-presets/number/cell-renderer.ts +133 -133
  1212. package/src/_pkgs/data-view/property-presets/select/cell-renderer.ts +88 -88
  1213. package/src/_pkgs/data-view/property-presets/select/define.ts +73 -73
  1214. package/src/_pkgs/data-view/view-presets/kanban/define.ts +91 -91
  1215. package/src/_pkgs/data-view/view-presets/kanban/kanban-view-manager.ts +328 -328
  1216. package/src/_pkgs/data-view/view-presets/kanban/mobile/card.ts +225 -225
  1217. package/src/_pkgs/data-view/view-presets/kanban/mobile/cell.ts +178 -178
  1218. package/src/_pkgs/data-view/view-presets/kanban/mobile/group.ts +153 -153
  1219. package/src/_pkgs/data-view/view-presets/kanban/mobile/kanban-view-ui-logic.ts +170 -170
  1220. package/src/_pkgs/data-view/view-presets/kanban/mobile/menu.ts +122 -122
  1221. package/src/_pkgs/data-view/view-presets/kanban/pc/card.ts +337 -337
  1222. package/src/_pkgs/data-view/view-presets/kanban/pc/cell.ts +185 -185
  1223. package/src/_pkgs/data-view/view-presets/kanban/pc/controller/clipboard.ts +53 -53
  1224. package/src/_pkgs/data-view/view-presets/kanban/pc/controller/drag.ts +255 -255
  1225. package/src/_pkgs/data-view/view-presets/kanban/pc/controller/selection.ts +801 -801
  1226. package/src/_pkgs/data-view/view-presets/kanban/pc/group.ts +211 -211
  1227. package/src/_pkgs/data-view/view-presets/kanban/pc/header.ts +76 -76
  1228. package/src/_pkgs/data-view/view-presets/kanban/pc/kanban-view-ui-logic.ts +331 -331
  1229. package/src/_pkgs/data-view/view-presets/kanban/pc/menu.ts +114 -114
  1230. package/src/_pkgs/data-view/view-presets/table/mobile/cell.ts +170 -170
  1231. package/src/_pkgs/data-view/view-presets/table/mobile/column-header.ts +272 -272
  1232. package/src/_pkgs/data-view/view-presets/table/mobile/group.ts +166 -166
  1233. package/src/_pkgs/data-view/view-presets/table/mobile/header.ts +90 -90
  1234. package/src/_pkgs/data-view/view-presets/table/mobile/menu.ts +47 -47
  1235. package/src/_pkgs/data-view/view-presets/table/mobile/row.ts +150 -150
  1236. package/src/_pkgs/data-view/view-presets/table/mobile/table-view-ui-logic.ts +160 -160
  1237. package/src/_pkgs/data-view/view-presets/table/pc/cell.ts +161 -161
  1238. package/src/_pkgs/data-view/view-presets/table/pc/controller/clipboard.ts +323 -323
  1239. package/src/_pkgs/data-view/view-presets/table/pc/controller/drag-to-fill.ts +112 -112
  1240. package/src/_pkgs/data-view/view-presets/table/pc/controller/drag.ts +209 -209
  1241. package/src/_pkgs/data-view/view-presets/table/pc/controller/hotkeys.ts +416 -416
  1242. package/src/_pkgs/data-view/view-presets/table/pc/controller/selection.ts +1180 -1180
  1243. package/src/_pkgs/data-view/view-presets/table/pc/group.ts +311 -311
  1244. package/src/_pkgs/data-view/view-presets/table/pc/header/column-header.ts +143 -143
  1245. package/src/_pkgs/data-view/view-presets/table/pc/header/column-renderer.ts +98 -98
  1246. package/src/_pkgs/data-view/view-presets/table/pc/header/database-header-column.ts +500 -500
  1247. package/src/_pkgs/data-view/view-presets/table/pc/header/number-format-bar.ts +145 -145
  1248. package/src/_pkgs/data-view/view-presets/table/pc/header/styles.ts +349 -349
  1249. package/src/_pkgs/data-view/view-presets/table/pc/header/vertical-indicator.ts +163 -163
  1250. package/src/_pkgs/data-view/view-presets/table/pc/menu.ts +132 -132
  1251. package/src/_pkgs/data-view/view-presets/table/pc/row/row-select-checkbox.ts +80 -80
  1252. package/src/_pkgs/data-view/view-presets/table/pc/row/row.ts +306 -306
  1253. package/src/_pkgs/data-view/view-presets/table/pc/table-view-ui-logic.ts +220 -220
  1254. package/src/_pkgs/data-view/view-presets/table/pc-virtual/controller/clipboard.ts +324 -324
  1255. package/src/_pkgs/data-view/view-presets/table/pc-virtual/controller/drag-to-fill.ts +117 -117
  1256. package/src/_pkgs/data-view/view-presets/table/pc-virtual/controller/drag.ts +212 -212
  1257. package/src/_pkgs/data-view/view-presets/table/pc-virtual/controller/hotkeys.ts +418 -418
  1258. package/src/_pkgs/data-view/view-presets/table/pc-virtual/controller/selection.ts +1110 -1110
  1259. package/src/_pkgs/data-view/view-presets/table/pc-virtual/group/bottom/group-footer.ts +105 -105
  1260. package/src/_pkgs/data-view/view-presets/table/pc-virtual/group/bottom/stats/column-stats-bar.ts +51 -51
  1261. package/src/_pkgs/data-view/view-presets/table/pc-virtual/group/bottom/stats/column-stats-column.ts +246 -246
  1262. package/src/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-header.ts +138 -138
  1263. package/src/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-title-css.ts +63 -63
  1264. package/src/_pkgs/data-view/view-presets/table/pc-virtual/group/top/header/column-header.ts +135 -135
  1265. package/src/_pkgs/data-view/view-presets/table/pc-virtual/group/top/header/column-move-preview.ts +98 -98
  1266. package/src/_pkgs/data-view/view-presets/table/pc-virtual/group/top/header/number-format-bar.ts +147 -147
  1267. package/src/_pkgs/data-view/view-presets/table/pc-virtual/group/top/header/single-column-header.ts +497 -497
  1268. package/src/_pkgs/data-view/view-presets/table/pc-virtual/group/top/header/vertical-indicator.ts +169 -169
  1269. package/src/_pkgs/data-view/view-presets/table/pc-virtual/row/cell.ts +225 -225
  1270. package/src/_pkgs/data-view/view-presets/table/pc-virtual/row/menu.ts +132 -132
  1271. package/src/_pkgs/data-view/view-presets/table/pc-virtual/row/row-header.ts +128 -128
  1272. package/src/_pkgs/data-view/view-presets/table/pc-virtual/row/row-last.ts +65 -65
  1273. package/src/_pkgs/data-view/view-presets/table/pc-virtual/table-view-ui-logic.ts +321 -321
  1274. package/src/_pkgs/data-view/view-presets/table/pc-virtual/types.ts +41 -41
  1275. package/src/_pkgs/data-view/view-presets/table/pc-virtual/virtual/virtual-cell.ts +60 -60
  1276. package/src/_pkgs/data-view/view-presets/table/stats/column-stats-bar.ts +55 -55
  1277. package/src/_pkgs/data-view/view-presets/table/stats/column-stats-column.ts +246 -246
  1278. package/src/_pkgs/data-view/view-presets/table/table-view-manager.ts +395 -395
  1279. package/src/_pkgs/data-view/widget-presets/quick-setting-bar/context.ts +10 -10
  1280. package/src/_pkgs/data-view/widget-presets/quick-setting-bar/filter/condition-view.ts +311 -311
  1281. package/src/_pkgs/data-view/widget-presets/quick-setting-bar/filter/group-panel-view.ts +480 -480
  1282. package/src/_pkgs/data-view/widget-presets/quick-setting-bar/filter/index.ts +21 -21
  1283. package/src/_pkgs/data-view/widget-presets/quick-setting-bar/filter/list-view.ts +220 -220
  1284. package/src/_pkgs/data-view/widget-presets/quick-setting-bar/filter/root-panel-view.ts +437 -437
  1285. package/src/_pkgs/data-view/widget-presets/quick-setting-bar/index.ts +52 -52
  1286. package/src/_pkgs/data-view/widget-presets/quick-setting-bar/sort/index.ts +32 -32
  1287. package/src/_pkgs/data-view/widget-presets/quick-setting-bar/sort/root-panel.ts +240 -240
  1288. package/src/_pkgs/data-view/widget-presets/tools/presets/filter/filter.ts +122 -122
  1289. package/src/_pkgs/data-view/widget-presets/tools/presets/search/search.ts +189 -189
  1290. package/src/_pkgs/data-view/widget-presets/tools/presets/sort/sort.ts +127 -127
  1291. package/src/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.ts +51 -51
  1292. package/src/_pkgs/data-view/widget-presets/tools/presets/table-add-row/new-record-preview.ts +44 -44
  1293. package/src/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.ts +384 -384
  1294. package/src/_pkgs/data-view/widget-presets/tools/tools-view.ts +83 -83
  1295. package/src/_pkgs/data-view/widget-presets/views-bar/views-view.ts +319 -319
  1296. package/src/_pkgs/std/clipboard/clipboard-adapter.ts +33 -33
  1297. package/src/_pkgs/std/clipboard/clipboard.ts +323 -323
  1298. package/src/_pkgs/std/event/base.ts +62 -62
  1299. package/src/_pkgs/std/event/control/keyboard.ts +149 -149
  1300. package/src/_pkgs/std/event/control/pointer.ts +626 -626
  1301. package/src/_pkgs/std/event/dispatcher.ts +435 -435
  1302. package/src/_pkgs/std/event/keymap.ts +127 -127
  1303. package/src/_pkgs/std/event/utils.ts +17 -17
  1304. package/src/_pkgs/std/extension/block-view.ts +33 -33
  1305. package/src/_pkgs/std/extension/config.ts +44 -44
  1306. package/src/_pkgs/std/extension/dnd/index.ts +373 -373
  1307. package/src/_pkgs/std/extension/editor-life-cycle.ts +49 -49
  1308. package/src/_pkgs/std/extension/flavour.ts +26 -26
  1309. package/src/_pkgs/std/extension/keymap.ts +49 -49
  1310. package/src/_pkgs/std/extension/lifecycle-watcher.ts +70 -70
  1311. package/src/_pkgs/std/extension/service.ts +113 -113
  1312. package/src/_pkgs/std/extension/widget-view-map.ts +40 -40
  1313. package/src/_pkgs/std/gfx/controller.ts +284 -284
  1314. package/src/_pkgs/std/gfx/extension.ts +53 -53
  1315. package/src/_pkgs/std/gfx/grid.ts +513 -513
  1316. package/src/_pkgs/std/gfx/identifiers.ts +10 -10
  1317. package/src/_pkgs/std/gfx/interactivity/extension/base.ts +211 -211
  1318. package/src/_pkgs/std/gfx/interactivity/extension/view.ts +134 -134
  1319. package/src/_pkgs/std/gfx/interactivity/gfx-view-event-handler.ts +108 -108
  1320. package/src/_pkgs/std/gfx/interactivity/manager.ts +1111 -1111
  1321. package/src/_pkgs/std/gfx/interactivity/resize/manager.ts +657 -657
  1322. package/src/_pkgs/std/gfx/interactivity/types/drag.ts +73 -73
  1323. package/src/_pkgs/std/gfx/interactivity/types/resize.ts +41 -41
  1324. package/src/_pkgs/std/gfx/interactivity/types/view.ts +173 -173
  1325. package/src/_pkgs/std/gfx/keyboard.ts +51 -51
  1326. package/src/_pkgs/std/gfx/layer.ts +909 -909
  1327. package/src/_pkgs/std/gfx/model/base.ts +173 -173
  1328. package/src/_pkgs/std/gfx/model/gfx-block-model.ts +315 -315
  1329. package/src/_pkgs/std/gfx/model/surface/element-model.ts +598 -598
  1330. package/src/_pkgs/std/gfx/model/surface/local-element-model.ts +254 -254
  1331. package/src/_pkgs/std/gfx/model/surface/surface-model.ts +697 -697
  1332. package/src/_pkgs/std/gfx/selection.ts +408 -408
  1333. package/src/_pkgs/std/gfx/surface-middleware.ts +61 -61
  1334. package/src/_pkgs/std/gfx/tool/tool-controller.ts +635 -635
  1335. package/src/_pkgs/std/gfx/tool/tool.ts +125 -125
  1336. package/src/_pkgs/std/gfx/view/view-manager.ts +139 -139
  1337. package/src/_pkgs/std/gfx/view/view.ts +225 -225
  1338. package/src/_pkgs/std/gfx/viewport-element.ts +230 -230
  1339. package/src/_pkgs/std/gfx/viewport.ts +659 -659
  1340. package/src/_pkgs/std/identifier.ts +34 -34
  1341. package/src/_pkgs/std/inline/components/v-element.ts +113 -113
  1342. package/src/_pkgs/std/inline/components/v-line.ts +156 -156
  1343. package/src/_pkgs/std/inline/consts.ts +6 -6
  1344. package/src/_pkgs/std/inline/extensions/inline-manager.ts +124 -124
  1345. package/src/_pkgs/std/inline/extensions/inline-spec.ts +49 -49
  1346. package/src/_pkgs/std/inline/extensions/markdown-matcher.ts +30 -30
  1347. package/src/_pkgs/std/inline/extensions/type.ts +44 -44
  1348. package/src/_pkgs/std/inline/inline-editor.ts +296 -296
  1349. package/src/_pkgs/std/inline/range/inline-range-provider.ts +118 -118
  1350. package/src/_pkgs/std/inline/range/range-binding.ts +392 -392
  1351. package/src/_pkgs/std/inline/services/attribute.ts +106 -106
  1352. package/src/_pkgs/std/inline/services/delta.ts +153 -153
  1353. package/src/_pkgs/std/inline/services/event.ts +382 -382
  1354. package/src/_pkgs/std/inline/services/hook.ts +35 -35
  1355. package/src/_pkgs/std/inline/services/range.ts +394 -394
  1356. package/src/_pkgs/std/inline/services/render.ts +185 -185
  1357. package/src/_pkgs/std/inline/services/text.ts +140 -140
  1358. package/src/_pkgs/std/inline/types.ts +37 -37
  1359. package/src/_pkgs/std/inline/utils/attribute-renderer.ts +49 -49
  1360. package/src/_pkgs/std/inline/utils/delta-convert.ts +63 -63
  1361. package/src/_pkgs/std/inline/utils/embed.ts +47 -47
  1362. package/src/_pkgs/std/inline/utils/point-conversion.ts +191 -191
  1363. package/src/_pkgs/std/inline/utils/range-conversion.ts +368 -368
  1364. package/src/_pkgs/std/inline/utils/renderer.ts +18 -18
  1365. package/src/_pkgs/std/inline/utils/transform-input.ts +78 -78
  1366. package/src/_pkgs/std/scope/std-scope.ts +169 -169
  1367. package/src/_pkgs/std/selection/block.ts +33 -33
  1368. package/src/_pkgs/std/selection/cursor.ts +45 -45
  1369. package/src/_pkgs/std/selection/surface.ts +72 -72
  1370. package/src/_pkgs/std/selection/text.ts +117 -117
  1371. package/src/_pkgs/std/spec/type.ts +5 -5
  1372. package/src/_pkgs/std/utils/gfx.ts +32 -32
  1373. package/src/_pkgs/std/utils/layer.ts +175 -175
  1374. package/src/_pkgs/std/utils/tree.ts +137 -137
  1375. package/src/_pkgs/std/view/decorators/required.ts +58 -58
  1376. package/src/_pkgs/std/view/element/block-component.ts +315 -315
  1377. package/src/_pkgs/std/view/element/consts.ts +10 -10
  1378. package/src/_pkgs/std/view/element/gfx-block-component.ts +303 -303
  1379. package/src/_pkgs/std/view/element/lit-host.ts +197 -197
  1380. package/src/_pkgs/std/view/element/shadowless-element.ts +97 -97
  1381. package/src/_pkgs/std/view/element/widget-component.ts +98 -98
  1382. package/src/_pkgs/store/adapter/assets.ts +159 -159
  1383. package/src/_pkgs/store/adapter/base.ts +324 -324
  1384. package/src/_pkgs/store/extension/extension.ts +134 -134
  1385. package/src/_pkgs/store/extension/schema.ts +20 -20
  1386. package/src/_pkgs/store/extension/selection/base.ts +46 -46
  1387. package/src/_pkgs/store/extension/selection/identifier.ts +17 -17
  1388. package/src/_pkgs/store/extension/selection/selection-extension.ts +189 -189
  1389. package/src/_pkgs/store/extension/store-extension.ts +61 -61
  1390. package/src/_pkgs/store/extension/workspace/doc.ts +38 -38
  1391. package/src/_pkgs/store/extension/workspace/workspace.ts +30 -30
  1392. package/src/_pkgs/store/index.ts +27 -27
  1393. package/src/_pkgs/store/model/block/block-model.ts +158 -158
  1394. package/src/_pkgs/store/model/block/flat-sync-controller.ts +173 -173
  1395. package/src/_pkgs/store/model/block/sync-controller.ts +391 -391
  1396. package/src/_pkgs/store/model/store/crud.ts +397 -397
  1397. package/src/_pkgs/store/model/store/identifier.ts +5 -5
  1398. package/src/_pkgs/store/model/store/store.ts +1298 -1298
  1399. package/src/_pkgs/store/reactive/flat-native-y/initialize.ts +59 -59
  1400. package/src/_pkgs/store/reactive/proxy.ts +390 -390
  1401. package/src/_pkgs/store/reactive/text/text.ts +472 -472
  1402. package/src/_pkgs/store/schema/error.ts +10 -10
  1403. package/src/_pkgs/store/test/test-workspace.ts +231 -231
  1404. package/src/_pkgs/store/transformer/assets.ts +105 -105
  1405. package/src/_pkgs/store/transformer/transformer.ts +660 -660
  1406. package/src/_pkgs/sync/blob/engine.ts +205 -205
  1407. package/src/_pkgs/sync/doc/engine.ts +291 -291
  1408. package/src/_pkgs/sync/doc/peer.ts +451 -451
  1409. package/src/blocks/attachment/index.ts +1 -1
  1410. package/src/blocks/attachment/store.ts +1 -1
  1411. package/src/blocks/attachment/view.ts +1 -1
  1412. package/src/blocks/bookmark/index.ts +1 -1
  1413. package/src/blocks/bookmark/store.ts +1 -1
  1414. package/src/blocks/bookmark/view.ts +1 -1
  1415. package/src/blocks/callout/index.ts +1 -1
  1416. package/src/blocks/callout/store.ts +1 -1
  1417. package/src/blocks/callout/view.ts +1 -1
  1418. package/src/blocks/code/index.ts +1 -1
  1419. package/src/blocks/code/store.ts +1 -1
  1420. package/src/blocks/code/view.ts +1 -1
  1421. package/src/blocks/data-view/index.ts +1 -1
  1422. package/src/blocks/data-view/store.ts +1 -1
  1423. package/src/blocks/data-view/view.ts +1 -1
  1424. package/src/blocks/database/index.ts +1 -1
  1425. package/src/blocks/database/store.ts +1 -1
  1426. package/src/blocks/database/view.ts +1 -1
  1427. package/src/blocks/divider/index.ts +1 -1
  1428. package/src/blocks/divider/store.ts +1 -1
  1429. package/src/blocks/divider/view.ts +1 -1
  1430. package/src/blocks/edgeless-text/index.ts +1 -1
  1431. package/src/blocks/edgeless-text/store.ts +1 -1
  1432. package/src/blocks/edgeless-text/view.ts +1 -1
  1433. package/src/blocks/embed/index.ts +1 -1
  1434. package/src/blocks/embed/store.ts +1 -1
  1435. package/src/blocks/embed/view.ts +1 -1
  1436. package/src/blocks/embed-doc/index.ts +1 -1
  1437. package/src/blocks/embed-doc/store.ts +1 -1
  1438. package/src/blocks/embed-doc/view.ts +1 -1
  1439. package/src/blocks/frame/index.ts +1 -1
  1440. package/src/blocks/frame/store.ts +1 -1
  1441. package/src/blocks/frame/view.ts +1 -1
  1442. package/src/blocks/image/index.ts +1 -1
  1443. package/src/blocks/image/store.ts +1 -1
  1444. package/src/blocks/image/view.ts +1 -1
  1445. package/src/blocks/latex/index.ts +1 -1
  1446. package/src/blocks/latex/store.ts +1 -1
  1447. package/src/blocks/latex/view.ts +1 -1
  1448. package/src/blocks/list/index.ts +1 -1
  1449. package/src/blocks/list/store.ts +1 -1
  1450. package/src/blocks/list/view.ts +1 -1
  1451. package/src/blocks/note/index.ts +1 -1
  1452. package/src/blocks/note/store.ts +1 -1
  1453. package/src/blocks/note/view.ts +1 -1
  1454. package/src/blocks/paragraph/index.ts +1 -1
  1455. package/src/blocks/paragraph/store.ts +1 -1
  1456. package/src/blocks/paragraph/view.ts +1 -1
  1457. package/src/blocks/root/index.ts +1 -1
  1458. package/src/blocks/root/store.ts +1 -1
  1459. package/src/blocks/root/view.ts +1 -1
  1460. package/src/blocks/surface/index.ts +1 -1
  1461. package/src/blocks/surface/store.ts +1 -1
  1462. package/src/blocks/surface/view.ts +1 -1
  1463. package/src/blocks/surface-ref/index.ts +1 -1
  1464. package/src/blocks/surface-ref/store.ts +1 -1
  1465. package/src/blocks/surface-ref/view.ts +1 -1
  1466. package/src/blocks/table/index.ts +1 -1
  1467. package/src/blocks/table/store.ts +1 -1
  1468. package/src/blocks/table/view.ts +1 -1
  1469. package/src/components/block-selection.ts +1 -1
  1470. package/src/components/block-zero-width.ts +1 -1
  1471. package/src/components/caption.ts +1 -1
  1472. package/src/components/card-style-dropdown-menu.ts +1 -1
  1473. package/src/components/citation.ts +1 -1
  1474. package/src/components/color-picker.ts +1 -1
  1475. package/src/components/context-menu.ts +1 -1
  1476. package/src/components/date-picker.ts +1 -1
  1477. package/src/components/drop-indicator.ts +1 -1
  1478. package/src/components/edgeless-line-styles-panel.ts +1 -1
  1479. package/src/components/edgeless-line-width-panel.ts +1 -1
  1480. package/src/components/edgeless-shape-color-picker.ts +1 -1
  1481. package/src/components/embed-card-modal.ts +1 -1
  1482. package/src/components/filterable-list.ts +1 -1
  1483. package/src/components/highlight-dropdown-menu.ts +1 -1
  1484. package/src/components/hover.ts +1 -1
  1485. package/src/components/icon-button.ts +1 -1
  1486. package/src/components/icons.ts +1 -1
  1487. package/src/components/link-preview.ts +1 -1
  1488. package/src/components/linked-doc-title.ts +1 -1
  1489. package/src/components/notification.ts +1 -1
  1490. package/src/components/open-doc-dropdown-menu.ts +1 -1
  1491. package/src/components/peek.ts +1 -1
  1492. package/src/components/portal.ts +1 -1
  1493. package/src/components/resource.ts +1 -1
  1494. package/src/components/size-dropdown-menu.ts +1 -1
  1495. package/src/components/smooth-corner.ts +1 -1
  1496. package/src/components/toast.ts +1 -1
  1497. package/src/components/toggle-button.ts +1 -1
  1498. package/src/components/toggle-switch.ts +1 -1
  1499. package/src/components/toolbar.ts +1 -1
  1500. package/src/components/tooltip-content-with-shortcut.ts +1 -1
  1501. package/src/components/view-dropdown-menu.ts +1 -1
  1502. package/src/data-view/effects.ts +1 -1
  1503. package/src/data-view/index.ts +1 -1
  1504. package/src/effects.ts +34 -34
  1505. package/src/ext-loader/index.ts +1 -1
  1506. package/src/extensions/store.ts +83 -83
  1507. package/src/extensions/view.ts +143 -143
  1508. package/src/foundation/clipboard.ts +1 -1
  1509. package/src/foundation/store.ts +1 -1
  1510. package/src/foundation/view.ts +1 -1
  1511. package/src/fragments/adapter-panel/index.ts +1 -1
  1512. package/src/fragments/adapter-panel/view.ts +1 -1
  1513. package/src/fragments/doc-title/index.ts +1 -1
  1514. package/src/fragments/doc-title/view.ts +1 -1
  1515. package/src/fragments/frame-panel/index.ts +1 -1
  1516. package/src/fragments/frame-panel/view.ts +1 -1
  1517. package/src/fragments/outline/index.ts +1 -1
  1518. package/src/fragments/outline/view.ts +1 -1
  1519. package/src/gfx/brush/index.ts +1 -1
  1520. package/src/gfx/brush/store.ts +1 -1
  1521. package/src/gfx/brush/view.ts +1 -1
  1522. package/src/gfx/connector/index.ts +1 -1
  1523. package/src/gfx/connector/store.ts +1 -1
  1524. package/src/gfx/connector/view.ts +1 -1
  1525. package/src/gfx/group/index.ts +1 -1
  1526. package/src/gfx/group/store.ts +1 -1
  1527. package/src/gfx/group/view.ts +1 -1
  1528. package/src/gfx/link/index.ts +1 -1
  1529. package/src/gfx/link/view.ts +1 -1
  1530. package/src/gfx/mindmap/index.ts +1 -1
  1531. package/src/gfx/mindmap/store.ts +1 -1
  1532. package/src/gfx/mindmap/view.ts +1 -1
  1533. package/src/gfx/note/index.ts +1 -1
  1534. package/src/gfx/note/view.ts +1 -1
  1535. package/src/gfx/pointer/index.ts +1 -1
  1536. package/src/gfx/pointer/view.ts +1 -1
  1537. package/src/gfx/shape/index.ts +1 -1
  1538. package/src/gfx/shape/store.ts +1 -1
  1539. package/src/gfx/shape/view.ts +1 -1
  1540. package/src/gfx/template/index.ts +1 -1
  1541. package/src/gfx/template/view.ts +1 -1
  1542. package/src/gfx/text/index.ts +1 -1
  1543. package/src/gfx/text/store.ts +1 -1
  1544. package/src/gfx/text/view.ts +1 -1
  1545. package/src/gfx/turbo-renderer.ts +1 -1
  1546. package/src/global/di.ts +1 -1
  1547. package/src/global/disposable.ts +1 -1
  1548. package/src/global/env.ts +1 -1
  1549. package/src/global/exceptions.ts +1 -1
  1550. package/src/global/gfx.ts +1 -1
  1551. package/src/global/index.ts +1 -1
  1552. package/src/global/lit.ts +1 -1
  1553. package/src/global/types.ts +1 -1
  1554. package/src/global/utils.ts +1 -1
  1555. package/src/inlines/comment/index.ts +1 -1
  1556. package/src/inlines/footnote/index.ts +1 -1
  1557. package/src/inlines/footnote/store.ts +1 -1
  1558. package/src/inlines/footnote/view.ts +1 -1
  1559. package/src/inlines/latex/index.ts +1 -1
  1560. package/src/inlines/latex/store.ts +1 -1
  1561. package/src/inlines/latex/view.ts +1 -1
  1562. package/src/inlines/link/index.ts +1 -1
  1563. package/src/inlines/link/store.ts +1 -1
  1564. package/src/inlines/link/view.ts +1 -1
  1565. package/src/inlines/mention/index.ts +1 -1
  1566. package/src/inlines/mention/view.ts +1 -1
  1567. package/src/inlines/preset/index.ts +1 -1
  1568. package/src/inlines/preset/store.ts +1 -1
  1569. package/src/inlines/preset/view.ts +1 -1
  1570. package/src/inlines/reference/index.ts +1 -1
  1571. package/src/inlines/reference/store.ts +1 -1
  1572. package/src/inlines/reference/view.ts +1 -1
  1573. package/src/model/index.ts +1 -1
  1574. package/src/rich-text/effects.ts +1 -1
  1575. package/src/rich-text/index.ts +1 -1
  1576. package/src/schemas.ts +78 -78
  1577. package/src/shared/adapters.ts +1 -1
  1578. package/src/shared/commands.ts +1 -1
  1579. package/src/shared/consts.ts +1 -1
  1580. package/src/shared/selection.ts +1 -1
  1581. package/src/shared/services.ts +1 -1
  1582. package/src/shared/styles.ts +1 -1
  1583. package/src/shared/theme.ts +1 -1
  1584. package/src/shared/types.ts +1 -1
  1585. package/src/shared/utils.ts +1 -1
  1586. package/src/std/effects.ts +1 -1
  1587. package/src/std/gfx.ts +1 -1
  1588. package/src/std/index.ts +1 -1
  1589. package/src/std/inline.ts +1 -1
  1590. package/src/store/index.ts +3 -3
  1591. package/src/store/test.ts +1 -1
  1592. package/src/sync/index.ts +1 -1
  1593. package/src/widgets/drag-handle/index.ts +1 -1
  1594. package/src/widgets/drag-handle/view.ts +1 -1
  1595. package/src/widgets/edgeless-auto-connect/index.ts +1 -1
  1596. package/src/widgets/edgeless-auto-connect/view.ts +1 -1
  1597. package/src/widgets/edgeless-dragging-area/index.ts +1 -1
  1598. package/src/widgets/edgeless-dragging-area/view.ts +1 -1
  1599. package/src/widgets/edgeless-selected-rect/index.ts +1 -1
  1600. package/src/widgets/edgeless-selected-rect/view.ts +1 -1
  1601. package/src/widgets/edgeless-toolbar/index.ts +1 -1
  1602. package/src/widgets/edgeless-toolbar/view.ts +1 -1
  1603. package/src/widgets/edgeless-zoom-toolbar/index.ts +1 -1
  1604. package/src/widgets/edgeless-zoom-toolbar/view.ts +1 -1
  1605. package/src/widgets/frame-title/index.ts +1 -1
  1606. package/src/widgets/frame-title/view.ts +1 -1
  1607. package/src/widgets/keyboard-toolbar/index.ts +1 -1
  1608. package/src/widgets/keyboard-toolbar/view.ts +1 -1
  1609. package/src/widgets/linked-doc/index.ts +1 -1
  1610. package/src/widgets/linked-doc/view.ts +1 -1
  1611. package/src/widgets/note-slicer/index.ts +1 -1
  1612. package/src/widgets/note-slicer/view.ts +1 -1
  1613. package/src/widgets/page-dragging-area/index.ts +1 -1
  1614. package/src/widgets/page-dragging-area/view.ts +1 -1
  1615. package/src/widgets/remote-selection/index.ts +1 -1
  1616. package/src/widgets/remote-selection/view.ts +1 -1
  1617. package/src/widgets/scroll-anchoring/index.ts +1 -1
  1618. package/src/widgets/scroll-anchoring/view.ts +1 -1
  1619. package/src/widgets/slash-menu/index.ts +1 -1
  1620. package/src/widgets/slash-menu/view.ts +1 -1
  1621. package/src/widgets/toolbar/index.ts +1 -1
  1622. package/src/widgets/toolbar/view.ts +1 -1
  1623. package/src/widgets/viewport-overlay/index.ts +1 -1
  1624. package/src/widgets/viewport-overlay/view.ts +1 -1
@@ -1,1858 +1,1858 @@
1
- import { AStarRunner, Overlay } from '../affine-block-surface/index.js';
2
- import {
3
- type BrushElementModel,
4
- type Connection,
5
- ConnectorElementModel,
6
- ConnectorMode,
7
- DEFAULT_POLYGON_VERTICES,
8
- GroupElementModel,
9
- type LocalConnectorElementModel,
10
- ShapeElementModel,
11
- ShapeType,
12
- } from '../affine-model/index.js';
13
- import {
14
- EditPropsStore,
15
- ThemeProvider,
16
- } from '../affine-shared/services/index.js';
17
- import { BlockSuiteError } from '../global/exceptions/index.js';
18
- import type { IBound, IVec, IVec3 } from '../global/gfx/index.js';
19
- import {
20
- almostEqual,
21
- Bound,
22
- getBezierCurveBoundingBox,
23
- getBezierParameters,
24
- getBoundFromPoints,
25
- getBoundWithRotation,
26
- getPointFromBoundsWithRotation,
27
- isOverlap,
28
- isVecZero,
29
- lineIntersects,
30
- PI2,
31
- PointLocation,
32
- polygonCentroid,
33
- sign,
34
- toRadian,
35
- Vec,
36
- } from '../global/gfx/index.js';
37
- import { assertType } from '../global/utils/index.js';
38
- import type { BlockStdScope } from '../std/index.js';
39
- import type {
40
- GfxController,
41
- GfxLocalElementModel,
42
- GfxModel,
43
- } from '../std/gfx/index.js';
44
- import { effect } from '@preact/signals-core';
45
- import last from 'lodash-es/last';
46
-
47
- export type Connectable = Exclude<
48
- GfxModel,
49
- ConnectorElementModel | BrushElementModel | GroupElementModel
50
- >;
51
-
52
- export type OrthogonalConnectorInput = {
53
- startBound: Bound | null;
54
- endBound: Bound | null;
55
- startPoint: PointLocation;
56
- endPoint: PointLocation;
57
- };
58
-
59
- export const ConnectorEndpointLocations: IVec[] = [
60
- // At top
61
- [0.5, 0],
62
- // At right
63
- [1, 0.5],
64
- // At bottom
65
- [0.5, 1],
66
- // At left
67
- [0, 0.5],
68
- ];
69
-
70
- export const ConnectorEndpointLocationsWithCenter: IVec[] = [
71
- // At top
72
- [0.5, 0],
73
- // At right
74
- [1, 0.5],
75
- // At bottom
76
- [0.5, 1],
77
- // At left
78
- [0, 0.5],
79
- // At center
80
- [0.5, 0.5],
81
- ];
82
-
83
- export const ConnectorEndpointLocationsOnTriangle: IVec[] = [
84
- // At top
85
- [0.5, 0],
86
- // At right
87
- [0.75, 0.5],
88
- // At bottom
89
- [0.5, 1],
90
- // At left
91
- [0.25, 0.5],
92
- // At center
93
- [0.5, 0.5],
94
- ];
95
-
96
- /**
97
- * Checks if a GfxModel is a shape eligible for center anchor point.
98
- * Only Rect (including roundedRect), Ellipse, Diamond, and Triangle are eligible.
99
- * Triangle and other complex shapes are excluded.
100
- */
101
- export function isCenterAnchorEligible(ele: GfxModel): boolean {
102
- if (!(ele instanceof ShapeElementModel)) return false;
103
- const { shapeType } = ele;
104
- return (
105
- shapeType === ShapeType.Rect ||
106
- shapeType === ShapeType.Ellipse ||
107
- shapeType === ShapeType.Diamond ||
108
- shapeType === ShapeType.Triangle ||
109
- shapeType === ShapeType.Polygon
110
- );
111
- }
112
-
113
- /**
114
- * Returns the normalized [0..1] coordinate of a shape's center anchor.
115
- * For polygons this is the geometric centroid of the (normalized) vertices;
116
- * for all other eligible shapes it is the bounding-box center [0.5, 0.5].
117
- */
118
- function getCenterAnchorCoord(ele: GfxModel): IVec {
119
- if (ele instanceof ShapeElementModel && ele.shapeType === ShapeType.Polygon) {
120
- return polygonCentroid(ele.vertices ?? DEFAULT_POLYGON_VERTICES);
121
- }
122
- return [0.5, 0.5];
123
- }
124
-
125
- /**
126
- * Checks if the center anchor feature is enabled via the global toggle.
127
- * Defaults to true (enabled) when no value is stored in localStorage.
128
- */
129
- export function isCenterAnchorEnabled(std: BlockStdScope): boolean {
130
- const store = std.getOptional(EditPropsStore);
131
- if (!store) return true;
132
- return store.getStorage('connectorCenterAnchor') ?? true;
133
- }
134
-
135
- /**
136
- * Checks if a normalized anchor position is the shape's center anchor.
137
- * Shape-aware: for polygons the center is the geometric centroid, otherwise
138
- * the bounding-box center [0.5, 0.5].
139
- */
140
- function isCenterAnchorPosition(position: IVec, ele: GfxModel): boolean {
141
- const [cx, cy] = getCenterAnchorCoord(ele);
142
- return (
143
- almostEqual(position[0], cx, 0.001) && almostEqual(position[1], cy, 0.001)
144
- );
145
- }
146
-
147
- /**
148
- * For a center-anchored connector endpoint, computes the perimeter intersection
149
- * point so the connector visually terminates at the shape edge rather than
150
- * penetrating to the center. The logical anchor remains [0.5, 0.5] but the
151
- * visual endpoint is where the line from otherPoint to center crosses the
152
- * shape boundary.
153
- *
154
- * Handles each eligible shape type (Rect, roundedRect, Ellipse, Diamond, Triangle) by
155
- * using the shape's own getLineIntersections method, which dispatches to
156
- * shape-specific geometry (polygon boundary for Rect/Diamond, ellipse math
157
- * for Ellipse). For roundedRect, the polygon approximation of the bounding
158
- * rectangle is used, which is consistent with existing edge anchor behavior.
159
- *
160
- * The function extends the ray beyond the center to handle cases where
161
- * otherPoint is inside or very close to the shape, ensuring a boundary
162
- * intersection is always found.
163
- *
164
- * Returns a new PointLocation at the perimeter with an appropriate tangent,
165
- * or the original centerPoint if no intersection is found.
166
- */
167
- function computePerimeterPointForCenterAnchor(
168
- connectable: GfxModel,
169
- centerPoint: PointLocation,
170
- otherPoint: PointLocation
171
- ): PointLocation {
172
- const bound = Bound.deserialize(connectable.xywh);
173
- const center: IVec = [centerPoint[0], centerPoint[1]];
174
- const other: IVec = [otherPoint[0], otherPoint[1]];
175
-
176
- // Compute direction from other point to center
177
- let direction = Vec.sub(center, other);
178
- const dirLen = Vec.len(direction);
179
-
180
- // If the other point is effectively at the center (e.g. both endpoints
181
- // on the same shape center, or overlapping shapes), use a default
182
- // direction pointing right — this gives a deterministic perimeter point
183
- if (dirLen < 0.01) {
184
- direction = [1, 0];
185
- } else {
186
- direction = Vec.normalize(direction);
187
- }
188
-
189
- // Extend the ray well beyond the center through the shape to guarantee
190
- // it crosses the boundary, even when otherPoint is inside the shape.
191
- // Use the shape's diagonal length as a generous extension distance.
192
- const diagonal = Math.sqrt(bound.w * bound.w + bound.h * bound.h);
193
- const rayStart = Vec.sub(center, Vec.mul(direction, diagonal));
194
- const rayEnd = Vec.add(center, Vec.mul(direction, diagonal));
195
-
196
- // Use shape-specific line intersection (rect uses polygon, ellipse uses
197
- // analytic ellipse math, diamond uses polygon)
198
- const intersections = connectable.getLineIntersections(rayStart, rayEnd);
199
-
200
- if (intersections && intersections.length > 0) {
201
- // Pick the intersection closest to the other point — this is the
202
- // perimeter point that the connector should visually terminate at
203
- // (the "entry" side of the shape from the other endpoint's perspective)
204
- let bestIntersection = intersections[0];
205
- let bestDist = Vec.dist(bestIntersection, other);
206
-
207
- for (let i = 1; i < intersections.length; i++) {
208
- const dist = Vec.dist(intersections[i], other);
209
- if (dist < bestDist) {
210
- bestDist = dist;
211
- bestIntersection = intersections[i];
212
- }
213
- }
214
-
215
- // The intersection PointLocation already carries an appropriate tangent
216
- // from the shape's getLineIntersections (polygon tangent for Rect/Diamond,
217
- // ellipse normal-derived tangent for Ellipse), which the connector
218
- // routing engine uses for orthogonal/curve path computation.
219
- return bestIntersection;
220
- }
221
-
222
- // Fallback: use getNearestPoint on shape boundary from the other endpoint
223
- const nearest = connectable.getNearestPoint(other);
224
- if (nearest) {
225
- const relPos = bound.toRelative(nearest);
226
- return getConnectableRelativePosition(connectable, relPos);
227
- }
228
-
229
- return centerPoint;
230
- }
231
-
232
- export function isConnectorWithLabel(model: GfxModel | GfxLocalElementModel) {
233
- return model instanceof ConnectorElementModel && model.hasLabel();
234
- }
235
-
236
- export function calculateNearestLocation(
237
- point: IVec,
238
- bounds: IBound,
239
- locations = ConnectorEndpointLocations,
240
- shortestDistance = Number.POSITIVE_INFINITY
241
- ) {
242
- const { x, y, w, h } = bounds;
243
- return locations
244
- .map<IVec>(offset => [x + offset[0] * w, y + offset[1] * h])
245
- .map(point => getPointFromBoundsWithRotation(bounds, point))
246
- .reduce(
247
- (prev, curr, index) => {
248
- const d = Vec.dist(point, curr);
249
- if (d < shortestDistance) {
250
- const location = locations[index];
251
- shortestDistance = d;
252
- prev[0] = location[0];
253
- prev[1] = location[1];
254
- }
255
- return prev;
256
- },
257
- [...locations[0]]
258
- );
259
- }
260
-
261
- function rBound(ele: GfxModel, anti = false): IBound {
262
- const bound = Bound.deserialize(ele.xywh);
263
- return { ...bound, rotate: anti ? -ele.rotate : ele.rotate };
264
- }
265
-
266
- export function isConnectorAndBindingsAllSelected(
267
- connector: ConnectorElementModel | LocalConnectorElementModel,
268
- selected: GfxModel[]
269
- ) {
270
- const connectorSelected = selected.find(s => s.id === connector.id);
271
- if (!connectorSelected) {
272
- return false;
273
- }
274
- const { source, target } = connector;
275
- const startSelected = selected.find(s => s.id === source?.id);
276
- const endSelected = selected.find(s => s.id === target?.id);
277
- if (!source.id && !target.id) {
278
- return true;
279
- }
280
- if (!source.id && endSelected) {
281
- return true;
282
- }
283
- if (!target.id && startSelected) {
284
- return true;
285
- }
286
- if (startSelected && endSelected) {
287
- return true;
288
- }
289
- return false;
290
- }
291
-
292
- export function getAnchors(ele: GfxModel, includeCenterAnchor = true) {
293
- const bound = Bound.deserialize(ele.xywh);
294
- const offset = 10;
295
- const anchors: { point: PointLocation; coord: IVec }[] = [];
296
- const rotate = ele.rotate;
297
-
298
- // Elements that opt into center-only anchoring (e.g. Wardley nodes) expose a
299
- // single anchor at their center; links clip to the perimeter via
300
- // getLineIntersections.
301
- if ((ele as { centerAnchorOnly?: boolean }).centerAnchorOnly) {
302
- const centerPoint = getPointFromBoundsWithRotation(
303
- { ...bound, rotate },
304
- bound.center
305
- );
306
- return [{ point: new PointLocation(centerPoint), coord: [0.5, 0.5] as IVec }];
307
- }
308
-
309
- // For polygon shapes, generate anchors at each vertex and edge midpoint
310
- if (
311
- ele instanceof ShapeElementModel &&
312
- ele.shapeType === ShapeType.Polygon
313
- ) {
314
- const verts: number[][] = ele.vertices ?? DEFAULT_POLYGON_VERTICES;
315
-
316
- for (let i = 0; i < verts.length; i++) {
317
- const curr = verts[i];
318
- const next = verts[(i + 1) % verts.length];
319
-
320
- // CW edge direction in absolute space, with element rotation applied.
321
- // This matches the convention used by linePolygonIntersects / polygonGetPointTangent:
322
- // Vec.rot(CW_edge_direction, -π/2) yields the outward normal.
323
- const edx = (next[0] - curr[0]) * bound.w;
324
- const edy = (next[1] - curr[1]) * bound.h;
325
- const edLen = Math.sqrt(edx * edx + edy * edy) || 1;
326
- const edgeTangent: IVec = Vec.rot(
327
- [edx / edLen, edy / edLen],
328
- toRadian(rotate)
329
- );
330
-
331
- // --- Vertex anchor ---
332
- const vertCoord: IVec = [curr[0], curr[1]];
333
- const vertAbs: IVec = [
334
- bound.x + vertCoord[0] * bound.w,
335
- bound.y + vertCoord[1] * bound.h,
336
- ];
337
- const vertRotated = getPointFromBoundsWithRotation(
338
- { ...bound, rotate },
339
- vertAbs
340
- );
341
- anchors.push({
342
- point: new PointLocation(vertRotated, edgeTangent),
343
- coord: vertCoord,
344
- });
345
-
346
- // --- Edge midpoint anchor ---
347
- const midCoord: IVec = [
348
- (curr[0] + next[0]) / 2,
349
- (curr[1] + next[1]) / 2,
350
- ];
351
- const midAbs: IVec = [
352
- bound.x + midCoord[0] * bound.w,
353
- bound.y + midCoord[1] * bound.h,
354
- ];
355
- const midRotated = getPointFromBoundsWithRotation(
356
- { ...bound, rotate },
357
- midAbs
358
- );
359
- anchors.push({
360
- point: new PointLocation(midRotated, edgeTangent),
361
- coord: midCoord,
362
- });
363
- }
364
-
365
- // Center anchor at the polygon's geometric centroid (gated on the toggle).
366
- if (includeCenterAnchor) {
367
- const centroid = polygonCentroid(verts);
368
- const centroidAbs: IVec = [
369
- bound.x + centroid[0] * bound.w,
370
- bound.y + centroid[1] * bound.h,
371
- ];
372
- const centroidRotated = getPointFromBoundsWithRotation(
373
- { ...bound, rotate },
374
- centroidAbs
375
- );
376
- anchors.push({
377
- point: new PointLocation(centroidRotated),
378
- coord: centroid,
379
- });
380
- }
381
- return anchors;
382
- }
383
-
384
- (
385
- [
386
- [bound.center[0], bound.y - offset],
387
- [bound.center[0], bound.maxY + offset],
388
- [bound.x - offset, bound.center[1]],
389
- [bound.maxX + offset, bound.center[1]],
390
- ] satisfies IVec[]
391
- )
392
- .map(vec => getPointFromBoundsWithRotation({ ...bound, rotate }, vec))
393
- .forEach(vec => {
394
- const rst = ele.getLineIntersections(bound.center, vec);
395
- if (!rst) return;
396
-
397
- const originPoint = getPointFromBoundsWithRotation(
398
- { ...bound, rotate: -rotate },
399
- rst[0]
400
- );
401
- anchors.push({ point: rst[0], coord: bound.toRelative(originPoint) });
402
- });
403
-
404
- // Add center anchor for eligible shapes (Rect, roundedRect, Ellipse, Diamond, Triangle)
405
- if (includeCenterAnchor && isCenterAnchorEligible(ele)) {
406
- const centerPoint = getPointFromBoundsWithRotation(
407
- { ...bound, rotate },
408
- bound.center
409
- );
410
- const centerPointLocation = new PointLocation(centerPoint);
411
- anchors.push({ point: centerPointLocation, coord: [0.5, 0.5] });
412
- }
413
-
414
- return anchors;
415
- }
416
-
417
- function getConnectableRelativePosition(connectable: GfxModel, position: IVec) {
418
- const location = connectable.getRelativePointLocation(position);
419
- if (isVecZero(Vec.sub(position, [0, 0.5])))
420
- location.tangent = Vec.rot([0, -1], toRadian(connectable.rotate));
421
- else if (isVecZero(Vec.sub(position, [1, 0.5])))
422
- location.tangent = Vec.rot([0, 1], toRadian(connectable.rotate));
423
- else if (isVecZero(Vec.sub(position, [0.5, 0])))
424
- location.tangent = Vec.rot([1, 0], toRadian(connectable.rotate));
425
- else if (isVecZero(Vec.sub(position, [0.5, 1])))
426
- location.tangent = Vec.rot([-1, 0], toRadian(connectable.rotate));
427
- return location;
428
- }
429
-
430
- export function getNearestConnectableAnchor(
431
- ele: Connectable,
432
- point: IVec,
433
- includeCenterAnchor = true
434
- ) {
435
- const anchors = getAnchors(ele, includeCenterAnchor);
436
- return closestPoint(
437
- anchors.map(a => a.point),
438
- point
439
- );
440
- }
441
-
442
- function closestPoint(
443
- points: PointLocation[],
444
- point: IVec
445
- ): PointLocation | null {
446
- if (points.length === 0) return null;
447
- const rst = points.map(p => ({ p, d: Vec.dist(p, point) }));
448
- rst.sort((a, b) => a.d - b.d);
449
- return rst[0].p;
450
- }
451
-
452
- function computePoints(
453
- startPoint: IVec,
454
- endPoint: IVec,
455
- nextStartPoint: IVec,
456
- lastEndPoint: IVec,
457
- startBound: Bound | null,
458
- endBound: Bound | null,
459
- expandStartBound: Bound | null,
460
- expandEndBound: Bound | null
461
- ): [IVec3[], IVec3, IVec3, IVec3, IVec3] {
462
- const startPointVec3 = downscalePrecision(startPoint);
463
- const endPointVec3 = downscalePrecision(endPoint);
464
- let nextStartPointVec3 = downscalePrecision(nextStartPoint);
465
- let lastEndPointVec3 = downscalePrecision(lastEndPoint);
466
-
467
- const result = getConnectablePoints(
468
- startPointVec3,
469
- endPointVec3,
470
- nextStartPointVec3,
471
- lastEndPointVec3,
472
- startBound,
473
- endBound,
474
- expandStartBound,
475
- expandEndBound
476
- );
477
- const points = result.points;
478
- nextStartPointVec3 = result.nextStartPoint;
479
- lastEndPointVec3 = result.lastEndPoint;
480
- const finalPoints = filterConnectablePoints(
481
- filterConnectablePoints(points, expandStartBound?.expand(-1) ?? null),
482
- expandEndBound?.expand(-1) ?? null
483
- );
484
- return [
485
- finalPoints,
486
- startPointVec3,
487
- endPointVec3,
488
- nextStartPointVec3,
489
- lastEndPointVec3,
490
- ];
491
- }
492
-
493
- function downscalePrecision(point: IVec | IVec3): IVec3 {
494
- return [
495
- Number(point[0].toFixed(2)),
496
- Number(point[1].toFixed(2)),
497
- point[2] ?? 0,
498
- ];
499
- }
500
-
501
- function filterConnectablePoints<T extends IVec3 | IVec>(
502
- points: T[],
503
- bound: Bound | null
504
- ): T[] {
505
- return points.filter(point => {
506
- if (!bound) return true;
507
- return !bound.isPointInBound([point[0], point[1]]);
508
- });
509
- }
510
-
511
- function pushWithPriority(points: number[][], vecs: IVec[], priority = 0) {
512
- points.push(...vecs.map(vec => [...vec, priority]));
513
- }
514
-
515
- function pushLineIntersectsToPoints(
516
- points: IVec3[],
517
- aLine: IVec[],
518
- bLine: IVec[],
519
- priority = 0
520
- ) {
521
- const rst = lineIntersects(aLine[0], aLine[1], bLine[0], bLine[1], true);
522
- if (rst) {
523
- pushWithPriority(points, [rst], priority);
524
- }
525
- }
526
-
527
- function pushOuterPoints(
528
- points: IVec3[],
529
- expandStartBound: Bound,
530
- expandEndBound: Bound,
531
- outerBound: Bound
532
- ) {
533
- if (expandStartBound && expandEndBound && outerBound) {
534
- pushWithPriority(points, outerBound.getVerticesAndMidpoints());
535
- pushWithPriority(points, [outerBound.center], 2);
536
- [
537
- expandStartBound.upperLine,
538
- expandStartBound.horizontalLine,
539
- expandStartBound.lowerLine,
540
- expandEndBound.upperLine,
541
- expandEndBound.horizontalLine,
542
- expandEndBound.lowerLine,
543
- ].forEach(line => {
544
- pushLineIntersectsToPoints(points, line, outerBound.leftLine, 0);
545
- pushLineIntersectsToPoints(points, line, outerBound.rightLine, 0);
546
- });
547
- [
548
- expandStartBound.leftLine,
549
- expandStartBound.verticalLine,
550
- expandStartBound.rightLine,
551
- expandEndBound.leftLine,
552
- expandEndBound.verticalLine,
553
- expandEndBound.rightLine,
554
- ].forEach(line => {
555
- pushLineIntersectsToPoints(points, line, outerBound.upperLine, 0);
556
- pushLineIntersectsToPoints(points, line, outerBound.lowerLine, 0);
557
- });
558
- }
559
- }
560
-
561
- function pushBoundMidPoint(
562
- points: IVec3[],
563
- bound1: Bound,
564
- bound2: Bound,
565
- expandBound1: Bound,
566
- expandBound2: Bound
567
- ) {
568
- if (bound1.maxX < bound2.x) {
569
- const midX = (bound1.maxX + bound2.x) / 2;
570
- [
571
- expandBound1.horizontalLine,
572
- expandBound2.horizontalLine,
573
- expandBound1.upperLine,
574
- expandBound1.lowerLine,
575
- expandBound2.upperLine,
576
- expandBound2.lowerLine,
577
- ].forEach((line, index) => {
578
- pushLineIntersectsToPoints(
579
- points,
580
- line,
581
- [
582
- [midX, 0],
583
- [midX, 1],
584
- ],
585
- index === 0 || index === 1 ? 6 : 3
586
- );
587
- });
588
- }
589
- if (bound1.maxY < bound2.y) {
590
- const midY = (bound1.maxY + bound2.y) / 2;
591
- [
592
- expandBound1.verticalLine,
593
- expandBound2.verticalLine,
594
- expandBound1.leftLine,
595
- expandBound1.rightLine,
596
- expandBound2.leftLine,
597
- expandBound2.rightLine,
598
- ].forEach((line, index) => {
599
- pushLineIntersectsToPoints(
600
- points,
601
- line,
602
- [
603
- [0, midY],
604
- [1, midY],
605
- ],
606
- index === 0 || index === 1 ? 6 : 3
607
- );
608
- });
609
- }
610
- }
611
-
612
- function pushGapMidPoint(
613
- points: IVec3[],
614
- point: IVec3,
615
- bound: Bound,
616
- bound2: Bound,
617
- expandBound: Bound,
618
- expandBound2: Bound
619
- ) {
620
- /** on top or on bottom */
621
- if (
622
- almostEqual(point[1], bound.y, 0.02) ||
623
- almostEqual(point[1], bound.maxY, 0.02)
624
- ) {
625
- const rst = [
626
- bound.upperLine,
627
- bound.lowerLine,
628
- bound2.upperLine,
629
- bound2.lowerLine,
630
- ]
631
- .map(line => {
632
- return lineIntersects(
633
- [point[0], point[1]],
634
- [point[0], point[1] + 1],
635
- line[0],
636
- line[1],
637
- true
638
- );
639
- })
640
- .filter(p => p !== null);
641
- rst.sort((a, b) => a[1] - b[1]);
642
- const midPoint = Vec.lrp(rst[1], rst[2], 0.5);
643
- pushWithPriority(points, [midPoint], 6);
644
- [
645
- expandBound.leftLine,
646
- expandBound.rightLine,
647
- expandBound2.leftLine,
648
- expandBound2.rightLine,
649
- ].forEach(line => {
650
- pushLineIntersectsToPoints(
651
- points,
652
- [midPoint, [midPoint[0] + 1, midPoint[1]]],
653
- line,
654
- 0
655
- );
656
- });
657
- } else {
658
- const rst = [
659
- bound.leftLine,
660
- bound.rightLine,
661
- bound2.leftLine,
662
- bound2.rightLine,
663
- ]
664
- .map(line => {
665
- return lineIntersects(
666
- [point[0], point[1]],
667
- [point[0] + 1, point[1]],
668
- line[0],
669
- line[1],
670
- true
671
- );
672
- })
673
- .filter(p => p !== null);
674
- rst.sort((a, b) => a[0] - b[0]);
675
- const midPoint = Vec.lrp(rst[1], rst[2], 0.5);
676
- pushWithPriority(points, [midPoint], 6);
677
- [
678
- expandBound.upperLine,
679
- expandBound.lowerLine,
680
- expandBound2.upperLine,
681
- expandBound2.lowerLine,
682
- ].forEach(line => {
683
- pushLineIntersectsToPoints(
684
- points,
685
- [midPoint, [midPoint[0], midPoint[1] + 1]],
686
- line,
687
- 0
688
- );
689
- });
690
- }
691
- }
692
-
693
- function removeDulicatePoints(points: IVec[] | IVec3[]) {
694
- points = points.map(downscalePrecision);
695
- points.sort((a, b) => a[0] - b[0]);
696
- assertType<IVec3[]>(points);
697
- for (let i = 1; i < points.length - 1; i++) {
698
- const cur = points[i];
699
- const last = points[i - 1];
700
- if (almostEqual(cur[0], last[0], 0.02)) {
701
- cur[0] = last[0];
702
- }
703
- }
704
- points.sort((a, b) => a[1] - b[1]);
705
- for (let i = 1; i < points.length - 1; i++) {
706
- const cur = points[i];
707
- const last = points[i - 1];
708
- if (almostEqual(cur[1], last[1], 0.02)) {
709
- cur[1] = last[1];
710
- }
711
- }
712
- points.sort((a, b) => {
713
- if (a[0] < b[0]) return -1;
714
- if (a[0] > b[0]) return 1;
715
- if (a[1] < b[1]) return -1;
716
- if (a[1] > b[1]) return 1;
717
- return 0;
718
- });
719
- for (let i = 1; i < points.length; i++) {
720
- const cur = points[i];
721
- const last = points[i - 1];
722
- if (
723
- almostEqual(cur[0], last[0], 0.02) &&
724
- almostEqual(cur[1], last[1], 0.02)
725
- ) {
726
- if (cur[2] <= last[2]) points.splice(i, 1);
727
- else points.splice(i - 1, 1);
728
- i--;
729
- continue;
730
- }
731
- }
732
- return points;
733
- }
734
-
735
- function getConnectablePoints(
736
- startPoint: IVec3,
737
- endPoint: IVec3,
738
- nextStartPoint: IVec3,
739
- lastEndPoint: IVec3,
740
- startBound: Bound | null,
741
- endBound: Bound | null,
742
- expandStartBound: Bound | null,
743
- expandEndBound: Bound | null
744
- ) {
745
- const lineBound = Bound.fromPoints([
746
- [startPoint[0], startPoint[1]],
747
- [endPoint[0], endPoint[1]],
748
- ]);
749
- const outerBound =
750
- expandStartBound &&
751
- expandEndBound &&
752
- expandStartBound.unite(expandEndBound);
753
- let points = [nextStartPoint, lastEndPoint];
754
- pushWithPriority(points, lineBound.getVerticesAndMidpoints());
755
-
756
- if (!startBound || !endBound) {
757
- pushWithPriority(points, [lineBound.center], 3);
758
- }
759
- if (outerBound) {
760
- pushOuterPoints(points, expandStartBound, expandEndBound, outerBound);
761
- }
762
-
763
- if (startBound && endBound && expandStartBound && expandEndBound) {
764
- pushGapMidPoint(
765
- points,
766
- startPoint,
767
- startBound,
768
- endBound,
769
- expandStartBound,
770
- expandEndBound
771
- );
772
- pushGapMidPoint(
773
- points,
774
- endPoint,
775
- endBound,
776
- startBound,
777
- expandEndBound,
778
- expandStartBound
779
- );
780
- pushBoundMidPoint(
781
- points,
782
- startBound,
783
- endBound,
784
- expandStartBound,
785
- expandEndBound
786
- );
787
- pushBoundMidPoint(
788
- points,
789
- endBound,
790
- startBound,
791
- expandEndBound,
792
- expandStartBound
793
- );
794
- }
795
-
796
- if (expandStartBound) {
797
- pushWithPriority(points, expandStartBound.getVerticesAndMidpoints());
798
- pushWithPriority(
799
- points,
800
- expandStartBound.include([lastEndPoint[0], lastEndPoint[1]]).points
801
- );
802
- }
803
-
804
- if (expandEndBound) {
805
- pushWithPriority(points, expandEndBound.getVerticesAndMidpoints());
806
- pushWithPriority(
807
- points,
808
- expandEndBound.include([nextStartPoint[0], nextStartPoint[1]]).points
809
- );
810
- }
811
-
812
- points = removeDulicatePoints(points);
813
-
814
- const sorted = points.map(point => point[0] + ',' + point[1]).sort();
815
- sorted.forEach((cur, index) => {
816
- if (index === 0) return;
817
- if (cur === sorted[index - 1]) {
818
- throw new Error('duplicate point');
819
- }
820
- });
821
- const startEnds = [nextStartPoint, lastEndPoint].map(point => {
822
- return points.find(
823
- item =>
824
- almostEqual(item[0], point[0], 0.02) &&
825
- almostEqual(item[1], point[1], 0.02)
826
- );
827
- });
828
- if (!startEnds[0] || !startEnds[1]) {
829
- throw new BlockSuiteError(
830
- BlockSuiteError.ErrorCode.ValueNotExists,
831
- 'Failed to get start and end points when getting connectable points'
832
- );
833
- }
834
- return { points, nextStartPoint: startEnds[0], lastEndPoint: startEnds[1] };
835
- }
836
-
837
- function getDirectPath(startPoint: IVec, endPoint: IVec): IVec[] {
838
- if (
839
- almostEqual(startPoint[0], endPoint[0], 0.02) ||
840
- almostEqual(startPoint[1], endPoint[1], 0.02)
841
- ) {
842
- return [startPoint, endPoint];
843
- } else {
844
- const vec = Vec.sub(endPoint, startPoint);
845
- const mid: IVec = [startPoint[0], startPoint[1] + vec[1]];
846
- return [startPoint, mid, endPoint];
847
- }
848
- }
849
-
850
- function mergePath(points: IVec[] | IVec3[]) {
851
- if (points.length === 0) return [];
852
- const result: IVec[] = [[points[0][0], points[0][1]]];
853
- for (let i = 1; i < points.length - 1; i++) {
854
- const cur = points[i];
855
- const last = points[i - 1];
856
- const next = points[i + 1];
857
- if (
858
- almostEqual(last[0], cur[0], 0.02) &&
859
- almostEqual(cur[0], next[0], 0.02)
860
- )
861
- continue;
862
- if (
863
- almostEqual(last[1], cur[1], 0.02) &&
864
- almostEqual(cur[1], next[1], 0.02)
865
- )
866
- continue;
867
- result.push([cur[0], cur[1]]);
868
- }
869
- if (points.length !== 0) {
870
- result.push([points[points.length - 1][0], points[points.length - 1][1]]);
871
- }
872
- for (let i = 0; i < result.length - 1; i++) {
873
- const cur = result[i];
874
- const next = result[i + 1];
875
- const isAlmostEqual =
876
- almostEqual(cur[0], next[0], 0.02) || almostEqual(cur[1], next[1], 0.02);
877
- if (!isAlmostEqual) {
878
- console.warn('Expected equal points');
879
- console.warn(points);
880
- console.warn(result);
881
- }
882
- }
883
- return result;
884
- }
885
-
886
- function computeOffset(startBound: Bound | null, endBound: Bound | null) {
887
- const startOffset = [20, 20, 20, 20];
888
- const endOffset = [20, 20, 20, 20];
889
- if (!(startBound && endBound)) {
890
- return [startOffset, endOffset];
891
- }
892
- // left, top, right, bottom
893
- let overlap = isOverlap(startBound.upperLine, endBound.lowerLine, 0, false);
894
- let dist: number;
895
- if (overlap && startBound.upperLine[0][1] > endBound.lowerLine[0][1]) {
896
- dist = Vec.distanceToLineSegment(
897
- startBound.upperLine[0],
898
- startBound.upperLine[1],
899
- endBound.lowerLine[0],
900
- false
901
- );
902
- startOffset[1] = Math.max(Math.min(dist / 2, startOffset[1]), 0);
903
- }
904
-
905
- overlap = isOverlap(startBound.rightLine, endBound.leftLine, 1, false);
906
- if (overlap && startBound.rightLine[0][0] < endBound.leftLine[0][0]) {
907
- dist = Vec.distanceToLineSegment(
908
- startBound.rightLine[0],
909
- startBound.rightLine[1],
910
- endBound.leftLine[0],
911
- false
912
- );
913
- startOffset[2] = Math.max(Math.min(dist / 2, startOffset[2]), 0);
914
- }
915
-
916
- overlap = isOverlap(startBound.lowerLine, endBound.upperLine, 0, false);
917
- if (overlap && startBound.lowerLine[0][1] < endBound.upperLine[0][1]) {
918
- dist = Vec.distanceToLineSegment(
919
- startBound.lowerLine[0],
920
- startBound.lowerLine[1],
921
- endBound.upperLine[0],
922
- false
923
- );
924
- startOffset[3] = Math.max(Math.min(dist / 2, startOffset[3]), 0);
925
- }
926
-
927
- startOffset[0] = endOffset[2] =
928
- Math.min(startOffset[0], endOffset[2]) === 0
929
- ? 20
930
- : Math.min(startOffset[0], endOffset[2]);
931
- startOffset[1] = endOffset[3] =
932
- Math.min(startOffset[1], endOffset[3]) === 0
933
- ? 20
934
- : Math.min(startOffset[1], endOffset[3]);
935
- startOffset[2] = endOffset[0] =
936
- Math.min(startOffset[2], endOffset[0]) === 0
937
- ? 20
938
- : Math.min(startOffset[2], endOffset[0]);
939
- startOffset[3] = endOffset[1] =
940
- Math.min(startOffset[3], endOffset[1]) === 0
941
- ? 20
942
- : Math.min(startOffset[3], endOffset[1]);
943
-
944
- return [startOffset, endOffset];
945
- }
946
-
947
- function getNextPoint(
948
- bound: Bound,
949
- point: PointLocation,
950
- offsetX = 10,
951
- offsetY = 10,
952
- offsetW = 10,
953
- offsetH = 10
954
- ) {
955
- const result: IVec = [point[0], point[1]];
956
- if (almostEqual(bound.x, result[0])) result[0] -= offsetX;
957
- else if (almostEqual(bound.y, result[1])) result[1] -= offsetY;
958
- else if (almostEqual(bound.maxX, result[0])) result[0] += offsetW;
959
- else if (almostEqual(bound.maxY, result[1])) result[1] += offsetH;
960
- else {
961
- const direction = Vec.normalize(Vec.sub(result, bound.center));
962
- const xDirection = direction[0] > 0 ? 1 : -1;
963
- const yDirection = direction[1] > 0 ? 1 : -1;
964
-
965
- const slope =
966
- Math.abs(point.tangent[0]) < Math.abs(point.tangent[1]) ? 0 : 1;
967
- // if the slope is big, use the x direction
968
- if (slope === 0) {
969
- if (xDirection > 0) {
970
- const intersects = lineIntersects(
971
- bound.rightLine[0],
972
- bound.rightLine[1],
973
- result,
974
- [bound.maxX + 10, result[1]]
975
- );
976
- if (!intersects) {
977
- throw new BlockSuiteError(
978
- BlockSuiteError.ErrorCode.ValueNotExists,
979
- 'Failed to get line intersections for getNextPoint'
980
- );
981
- }
982
- result[0] = intersects[0] + offsetX;
983
- } else {
984
- const intersects = lineIntersects(
985
- bound.leftLine[0],
986
- bound.leftLine[1],
987
- result,
988
- [bound.x - 10, result[1]]
989
- );
990
- if (!intersects) {
991
- throw new BlockSuiteError(
992
- BlockSuiteError.ErrorCode.ValueNotExists,
993
- 'Failed to get line intersections for getNextPoint'
994
- );
995
- }
996
- result[0] = intersects[0] - offsetX;
997
- }
998
- } else {
999
- if (yDirection > 0) {
1000
- const intersects = lineIntersects(
1001
- bound.lowerLine[0],
1002
- bound.lowerLine[1],
1003
- result,
1004
- [result[0], bound.maxY + 10]
1005
- );
1006
- if (!intersects) {
1007
- throw new BlockSuiteError(
1008
- BlockSuiteError.ErrorCode.ValueNotExists,
1009
- 'Failed to get line intersections for getNextPoint'
1010
- );
1011
- }
1012
- result[1] = intersects[1] + offsetY;
1013
- } else {
1014
- const intersects = lineIntersects(
1015
- bound.upperLine[0],
1016
- bound.upperLine[1],
1017
- result,
1018
- [result[0], bound.y - 10]
1019
- );
1020
- if (!intersects) {
1021
- throw new BlockSuiteError(
1022
- BlockSuiteError.ErrorCode.ValueNotExists,
1023
- 'Failed to get line intersections for getNextPoint'
1024
- );
1025
- }
1026
- result[1] = intersects[1] - offsetY;
1027
- }
1028
- }
1029
- }
1030
- return result;
1031
- }
1032
-
1033
- function computeNextStartEndpoint(
1034
- startPoint: PointLocation,
1035
- endPoint: PointLocation,
1036
- startBound: Bound | null,
1037
- endBound: Bound | null,
1038
- startOffset: number[] | null,
1039
- endOffset: number[] | null
1040
- ) {
1041
- const nextStartPoint =
1042
- startBound && startOffset
1043
- ? getNextPoint(
1044
- startBound,
1045
- startPoint,
1046
- startOffset[0],
1047
- startOffset[1],
1048
- startOffset[2],
1049
- startOffset[3]
1050
- )
1051
- : startPoint;
1052
- const lastEndPoint =
1053
- endBound && endOffset
1054
- ? getNextPoint(
1055
- endBound,
1056
- endPoint,
1057
- endOffset[0],
1058
- endOffset[1],
1059
- endOffset[2],
1060
- endOffset[3]
1061
- )
1062
- : endPoint;
1063
- return [nextStartPoint, lastEndPoint];
1064
- }
1065
-
1066
- function adjustStartEndPoint(
1067
- startPoint: IVec3,
1068
- endPoint: IVec3,
1069
- startBound: Bound | null = null,
1070
- endBound: Bound | null = null
1071
- ) {
1072
- if (!endBound) {
1073
- if (
1074
- Math.abs(endPoint[0] - startPoint[0]) >
1075
- Math.abs(endPoint[1] - startPoint[1])
1076
- ) {
1077
- endPoint[0] += sign(endPoint[0] - startPoint[0]) * 20;
1078
- } else {
1079
- endPoint[1] += sign(endPoint[1] - startPoint[1]) * 20;
1080
- }
1081
- }
1082
- if (!startBound) {
1083
- if (
1084
- Math.abs(endPoint[0] - startPoint[0]) >
1085
- Math.abs(endPoint[1] - startPoint[1])
1086
- ) {
1087
- startPoint[0] -= sign(endPoint[0] - startPoint[0]) * 20;
1088
- } else {
1089
- startPoint[1] -= sign(endPoint[1] - startPoint[1]) * 20;
1090
- }
1091
- }
1092
- }
1093
-
1094
- function renderRect(
1095
- ctx: CanvasRenderingContext2D,
1096
- bounds: IBound,
1097
- color: string,
1098
- lineWidth: number
1099
- ) {
1100
- const { x, y, w, h } = bounds;
1101
- ctx.save();
1102
- ctx.beginPath();
1103
- ctx.strokeStyle = color;
1104
- ctx.lineWidth = lineWidth;
1105
- ctx.setLineDash([lineWidth * 2, lineWidth * 2]);
1106
- ctx.strokeRect(x, y, w, h);
1107
- ctx.closePath();
1108
- ctx.restore();
1109
- }
1110
-
1111
- export class ConnectionOverlay extends Overlay {
1112
- static override overlayName = 'connection';
1113
-
1114
- private _emphasisColor: string;
1115
-
1116
- private _themeDisposer: (() => void) | null = null;
1117
-
1118
- highlightPoint: IVec | null = null;
1119
-
1120
- points: IVec[] = [];
1121
-
1122
- sourceBounds: IBound | null = null;
1123
-
1124
- targetBounds: IBound | null = null;
1125
-
1126
- /**
1127
- * Checks whether the center anchor toggle is enabled.
1128
- * Returns true (enabled) by default if no stored value is found.
1129
- */
1130
- get centerAnchorEnabled(): boolean {
1131
- const store = this.gfx.std.getOptional(EditPropsStore);
1132
- if (!store) return true;
1133
- const value = store.getStorage('connectorCenterAnchor');
1134
- return value ?? true;
1135
- }
1136
-
1137
- constructor(gfx: GfxController) {
1138
- super(gfx);
1139
- this._emphasisColor = this._getEmphasisColor();
1140
- this._setupThemeListener();
1141
- }
1142
-
1143
- private _findConnectablesInViews() {
1144
- const gfx = this.gfx;
1145
- const bound = gfx.viewport.viewportBounds;
1146
- return gfx.getElementsByBound(bound).filter(ele => ele.connectable);
1147
- }
1148
-
1149
- private _getEmphasisColor(): string {
1150
- return getComputedStyle(this.gfx.std.host).getPropertyValue(
1151
- '--affine-text-emphasis-color'
1152
- );
1153
- }
1154
-
1155
- private _setupThemeListener(): void {
1156
- const themeService = this.gfx.std.get(ThemeProvider);
1157
- this._themeDisposer = effect(() => {
1158
- themeService.theme$;
1159
- this._emphasisColor = this._getEmphasisColor();
1160
- });
1161
- }
1162
-
1163
- _clearRect() {
1164
- this.points = [];
1165
- this.highlightPoint = null;
1166
- this._renderer?.refresh();
1167
- }
1168
-
1169
- override clear() {
1170
- this.sourceBounds = null;
1171
- this.targetBounds = null;
1172
- this._clearRect();
1173
- }
1174
-
1175
- override dispose() {
1176
- this._themeDisposer?.();
1177
- if (!this._renderer) return;
1178
- this._renderer.removeOverlay(this);
1179
- this._renderer = null;
1180
- }
1181
-
1182
- override render(ctx: CanvasRenderingContext2D): void {
1183
- const zoom = this.gfx.viewport.zoom;
1184
- const radius = 5 / zoom;
1185
- const color = this._emphasisColor;
1186
- ctx.globalAlpha = 0.6;
1187
- let lineWidth = 1 / zoom;
1188
- if (this.sourceBounds) {
1189
- renderRect(ctx, this.sourceBounds, color, lineWidth);
1190
- }
1191
- if (this.targetBounds) {
1192
- renderRect(ctx, this.targetBounds, color, lineWidth);
1193
- }
1194
-
1195
- lineWidth = 2 / zoom;
1196
- this.points.forEach(p => {
1197
- ctx.beginPath();
1198
- ctx.arc(p[0], p[1], radius, 0, PI2);
1199
- ctx.fillStyle = 'white';
1200
- ctx.strokeStyle = color;
1201
- ctx.lineWidth = lineWidth;
1202
- ctx.fill();
1203
- ctx.stroke();
1204
- ctx.closePath();
1205
- });
1206
-
1207
- ctx.globalAlpha = 1;
1208
- if (this.highlightPoint) {
1209
- ctx.beginPath();
1210
- ctx.arc(this.highlightPoint[0], this.highlightPoint[1], radius, 0, PI2);
1211
- ctx.fillStyle = color;
1212
- ctx.strokeStyle = color;
1213
- ctx.lineWidth = lineWidth;
1214
- ctx.fill();
1215
- ctx.stroke();
1216
- ctx.closePath();
1217
- }
1218
- }
1219
-
1220
- /**
1221
- * Render the connector at the given point. It will try to find
1222
- * the closest connectable element and render the connector. If the
1223
- * point is not close to any connectable element, it will just render
1224
- * the connector at the given point.
1225
- * @param point the point to render the connector
1226
- * @param excludedIds the ids of the elements that should be excluded
1227
- * @returns the connection result
1228
- */
1229
- renderConnector(point: IVec, excludedIds: string[] = []) {
1230
- const connectables = this._findConnectablesInViews();
1231
- const context = this.gfx;
1232
- const target = [];
1233
-
1234
- this._clearRect();
1235
-
1236
- let result: Connection | null = null;
1237
- // eslint-disable-next-line @typescript-eslint/prefer-for-of
1238
- for (let i = 0; i < connectables.length; i++) {
1239
- const connectable = connectables[i];
1240
- // first check if in excluedIds
1241
- if (excludedIds.includes(connectable.id)) continue;
1242
-
1243
- // then check if in expanded bound
1244
- const bound = Bound.deserialize(connectable.xywh);
1245
- const rotateBound = Bound.from(getBoundWithRotation(rBound(connectable)));
1246
- // FIXME: the real path needs to be expanded: diamod, ellipse, trangle.
1247
- if (!rotateBound.expand(10).isPointInBound(point)) continue;
1248
-
1249
- // then check if closes to anchors
1250
- const anchors = getAnchors(connectable, this.centerAnchorEnabled);
1251
- const len = anchors.length;
1252
- const pointerViewCoord = context.viewport.toViewCoord(point[0], point[1]);
1253
-
1254
- let shortestDistance = Number.POSITIVE_INFINITY;
1255
- let j = 0;
1256
-
1257
- this.points = anchors.map(a => a.point);
1258
-
1259
- for (; j < len; j++) {
1260
- const anchor = anchors[j];
1261
- const anchorViewCoord = context.viewport.toViewCoord(
1262
- anchor.point[0],
1263
- anchor.point[1]
1264
- );
1265
- const d = Vec.dist(anchorViewCoord, pointerViewCoord);
1266
- if (d < shortestDistance) {
1267
- shortestDistance = d;
1268
- target.push(connectable);
1269
- this.highlightPoint = anchor.point;
1270
- result = {
1271
- id: connectable.id,
1272
- position: anchor.coord,
1273
- };
1274
- }
1275
- }
1276
-
1277
- if (shortestDistance < 8 && result) break;
1278
-
1279
- // if not, check if closes to bound
1280
- const nearestPoint = connectable.getNearestPoint(point);
1281
-
1282
- if (Vec.dist(nearestPoint, point) < 8) {
1283
- this.highlightPoint = nearestPoint;
1284
- const originPoint = getPointFromBoundsWithRotation(
1285
- rBound(connectable, true),
1286
- nearestPoint
1287
- );
1288
- this._renderer?.refresh();
1289
- target.push(connectable);
1290
- result = {
1291
- id: connectable.id,
1292
- position: Vec.clampV(bound.toRelative(originPoint), 0, 1),
1293
- };
1294
- }
1295
-
1296
- if (result) continue;
1297
-
1298
- // if not, check if in inside of the element
1299
- if (
1300
- connectable.includesPoint(
1301
- point[0],
1302
- point[1],
1303
- {
1304
- ignoreTransparent: false,
1305
- },
1306
- this.gfx.std.host
1307
- )
1308
- ) {
1309
- target.push(connectable);
1310
- result = {
1311
- id: connectable.id,
1312
- };
1313
- }
1314
- }
1315
-
1316
- if (last(target) instanceof GroupElementModel) {
1317
- this.targetBounds = Bound.deserialize(last(target)!.xywh);
1318
- } else {
1319
- this.targetBounds = null;
1320
- }
1321
-
1322
- // at last, if not, just return the point
1323
- if (!result) {
1324
- result = {
1325
- position: point,
1326
- };
1327
- }
1328
-
1329
- this._renderer?.refresh();
1330
-
1331
- return result;
1332
- }
1333
- }
1334
-
1335
- export class PathGenerator {
1336
- protected _aStarRunner: AStarRunner | null = null;
1337
-
1338
- protected _prepareOrthogonalConnectorInfo(
1339
- connectorInfo: OrthogonalConnectorInput
1340
- ): [
1341
- IVec,
1342
- IVec,
1343
- IVec,
1344
- IVec,
1345
- Bound | null,
1346
- Bound | null,
1347
- Bound | null,
1348
- Bound | null,
1349
- ] {
1350
- const { startBound, endBound, startPoint, endPoint } = connectorInfo;
1351
-
1352
- const [startOffset, endOffset] = computeOffset(startBound, endBound);
1353
- const [nextStartPoint, lastEndPoint] = computeNextStartEndpoint(
1354
- startPoint,
1355
- endPoint,
1356
- startBound,
1357
- endBound,
1358
- startOffset,
1359
- endOffset
1360
- );
1361
- const expandStartBound = startBound
1362
- ? startBound.expand(
1363
- startOffset[0],
1364
- startOffset[1],
1365
- startOffset[2],
1366
- startOffset[3]
1367
- )
1368
- : null;
1369
- const expandEndBound = endBound
1370
- ? endBound.expand(endOffset[0], endOffset[1], endOffset[2], endOffset[3])
1371
- : null;
1372
-
1373
- return [
1374
- startPoint,
1375
- endPoint,
1376
- nextStartPoint,
1377
- lastEndPoint,
1378
- startBound,
1379
- endBound,
1380
- expandStartBound,
1381
- expandEndBound,
1382
- ];
1383
- }
1384
-
1385
- generateOrthogonalConnectorPath(input: OrthogonalConnectorInput): IVec[] {
1386
- const info = this._prepareOrthogonalConnectorInfo(input);
1387
- const [startPoint, endPoint, nextStartPoint, lastEndPoint] = info;
1388
- const [, , , , startBound, endBound, expandStartBound, expandEndBound] =
1389
- info;
1390
- const blocks = [];
1391
- const expandBlocks = [];
1392
- startBound && blocks.push(startBound.clone());
1393
- endBound && blocks.push(endBound.clone());
1394
- expandStartBound && expandBlocks.push(expandStartBound.clone());
1395
- expandEndBound && expandBlocks.push(expandEndBound.clone());
1396
-
1397
- if (
1398
- startBound &&
1399
- endBound &&
1400
- startBound.isPointInBound(endPoint) &&
1401
- endBound.isPointInBound(startPoint)
1402
- ) {
1403
- return getDirectPath(startPoint, endPoint);
1404
- }
1405
-
1406
- if (startBound && expandStartBound?.isPointInBound(endPoint, 0)) {
1407
- return getDirectPath(startPoint, endPoint);
1408
- }
1409
-
1410
- if (endBound && expandEndBound?.isPointInBound(startPoint, 0)) {
1411
- return getDirectPath(startPoint, endPoint);
1412
- }
1413
-
1414
- const points = computePoints(
1415
- startPoint,
1416
- endPoint,
1417
- nextStartPoint,
1418
- lastEndPoint,
1419
- startBound,
1420
- endBound,
1421
- expandStartBound,
1422
- expandEndBound
1423
- );
1424
- const finalPoints = points[0];
1425
- const [, startPointV3, endPointV3, nextStartPointV3, lastEndPointV3] =
1426
- points;
1427
-
1428
- adjustStartEndPoint(startPointV3, endPointV3, startBound, endBound);
1429
- this._aStarRunner = new AStarRunner(
1430
- finalPoints,
1431
- nextStartPointV3,
1432
- lastEndPointV3,
1433
- startPointV3,
1434
- endPointV3,
1435
- blocks,
1436
- expandBlocks
1437
- );
1438
- this._aStarRunner.run();
1439
- const path = this._aStarRunner.path;
1440
- if (!endBound) path.pop();
1441
- if (!startBound) path.shift();
1442
-
1443
- return mergePath(path);
1444
- }
1445
- }
1446
-
1447
- export class ConnectorPathGenerator extends PathGenerator {
1448
- constructor(
1449
- private readonly options: {
1450
- getElementById: (id: string) => GfxModel | null;
1451
- }
1452
- ) {
1453
- super();
1454
- }
1455
-
1456
- static updatePath(
1457
- connector: ConnectorElementModel | LocalConnectorElementModel,
1458
- path: PointLocation[] | null,
1459
- elementGetter?: (id: string) => GfxModel | null
1460
- ) {
1461
- const instance = new ConnectorPathGenerator({
1462
- getElementById: elementGetter ?? (() => null),
1463
- });
1464
-
1465
- const points = path ?? instance._generateConnectorPath(connector) ?? [];
1466
- const bound =
1467
- connector.mode === ConnectorMode.Curve
1468
- ? getBezierCurveBoundingBox(getBezierParameters(points))
1469
- : getBoundFromPoints(points);
1470
- const relativePoints = points.map((p: PointLocation) => {
1471
- return p.setVec(Vec.sub(p, [bound.x, bound.y]));
1472
- });
1473
-
1474
- connector.updatingPath = true;
1475
- // the property assignment order matters
1476
- connector.xywh = bound.serialize();
1477
- connector.path = relativePoints;
1478
-
1479
- // Updates Connector's Label position.
1480
- if (isConnectorWithLabel(connector)) {
1481
- const model = connector as ConnectorElementModel;
1482
- const [cx, cy] = model.getPointByOffsetDistance(
1483
- model.labelOffset.distance
1484
- );
1485
- const [, , w, h] = model.labelXYWH!;
1486
- model.labelXYWH = [cx - w / 2, cy - h / 2, w, h];
1487
- }
1488
-
1489
- connector.updatingPath = false;
1490
- }
1491
-
1492
- private _computeStartEndPoint(
1493
- connector: ConnectorElementModel | LocalConnectorElementModel
1494
- ) {
1495
- const { source, target } = connector;
1496
- const start = this._getConnectorEndElement(connector, 'source');
1497
- const end = this._getConnectorEndElement(connector, 'target');
1498
-
1499
- let startPoint: PointLocation | null = null;
1500
- let endPoint: PointLocation | null = null;
1501
- if (
1502
- source.id &&
1503
- !source.position &&
1504
- target.id &&
1505
- !target.position &&
1506
- start &&
1507
- end
1508
- ) {
1509
- const startAnchors = getAnchors(start);
1510
- const endAnchors = getAnchors(end);
1511
- let minDist = Infinity;
1512
- let minStartAnchor = new PointLocation();
1513
- let minEndAnchor = new PointLocation();
1514
- for (const sa of startAnchors) {
1515
- for (const ea of endAnchors) {
1516
- const dist = Vec.dist(sa.point, ea.point);
1517
- if (dist + 0.1 < minDist) {
1518
- minDist = dist;
1519
- minStartAnchor = sa.point;
1520
- minEndAnchor = ea.point;
1521
- }
1522
- }
1523
- }
1524
- startPoint = minStartAnchor;
1525
- endPoint = minEndAnchor;
1526
- } else {
1527
- startPoint = this._getConnectionPoint(connector, 'source');
1528
- endPoint = this._getConnectionPoint(connector, 'target');
1529
- }
1530
-
1531
- if (!startPoint || !endPoint) return [];
1532
-
1533
- // Adjust center-anchored endpoints to perimeter
1534
- return this._adjustCenterAnchorEndpoints(connector, startPoint, endPoint);
1535
- }
1536
-
1537
- private _generateConnectorPath(
1538
- connector: ConnectorElementModel | LocalConnectorElementModel
1539
- ) {
1540
- const { mode } = connector;
1541
- if (mode === ConnectorMode.Straight) {
1542
- return this._generateStraightConnectorPath(connector);
1543
- } else if (mode === ConnectorMode.Orthogonal) {
1544
- const start = this._getConnectorEndElement(connector, 'source');
1545
- const end = this._getConnectorEndElement(connector, 'target');
1546
-
1547
- const [startPoint, endPoint] = this._computeStartEndPoint(connector);
1548
-
1549
- const startBound = start
1550
- ? Bound.from(getBoundWithRotation(rBound(start)))
1551
- : null;
1552
- const endBound = end
1553
- ? Bound.from(getBoundWithRotation(rBound(end)))
1554
- : null;
1555
- const path = this.generateOrthogonalConnectorPath({
1556
- startPoint,
1557
- endPoint,
1558
- startBound,
1559
- endBound,
1560
- });
1561
- return path.map(p => new PointLocation(p));
1562
- } else if (mode === ConnectorMode.Curve) {
1563
- return this._generateCurveConnectorPath(connector);
1564
- }
1565
- throw new Error('unknown connector mode');
1566
- }
1567
-
1568
- private _generateCurveConnectorPath(
1569
- connector: ConnectorElementModel | LocalConnectorElementModel
1570
- ) {
1571
- const { source, target } = connector;
1572
- let startPoint: PointLocation | null = null;
1573
- let endPoint: PointLocation | null = null;
1574
-
1575
- if (source.id || target.id) {
1576
- if (!source.position && !target.position) {
1577
- const start = this._getConnectorEndElement(
1578
- connector,
1579
- 'source'
1580
- ) as Connectable;
1581
- const end = this._getConnectorEndElement(
1582
- connector,
1583
- 'target'
1584
- ) as Connectable;
1585
- const sb = Bound.deserialize(start.xywh);
1586
- const eb = Bound.deserialize(end.xywh);
1587
- startPoint = getNearestConnectableAnchor(start, eb.center);
1588
- endPoint = getNearestConnectableAnchor(end, sb.center);
1589
- } else {
1590
- startPoint = this._getConnectionPoint(connector, 'source');
1591
- endPoint = this._getConnectionPoint(connector, 'target');
1592
- }
1593
-
1594
- if (!startPoint || !endPoint) return [];
1595
-
1596
- // Adjust center-anchored endpoints to perimeter before computing
1597
- // control vectors, so tangent and position are correct
1598
- [startPoint, endPoint] = this._adjustCenterAnchorEndpoints(
1599
- connector,
1600
- startPoint,
1601
- endPoint
1602
- );
1603
-
1604
- if (source.id) {
1605
- const startTangentVertical = Vec.rot(startPoint.tangent, -Math.PI / 2);
1606
- startPoint.out = isVecZero(startTangentVertical)
1607
- ? Vec.mul(Vec.per(Vec.normalize(Vec.sub(startPoint, endPoint))), 20)
1608
- : Vec.mul(
1609
- startTangentVertical,
1610
- Math.max(
1611
- 100,
1612
- Math.abs(
1613
- Vec.pry(Vec.sub(endPoint, startPoint), startTangentVertical)
1614
- ) / 3
1615
- )
1616
- );
1617
- }
1618
- if (target.id) {
1619
- const endTangentVertical = Vec.rot(endPoint.tangent, -Math.PI / 2);
1620
- endPoint.in = isVecZero(endTangentVertical)
1621
- ? Vec.mul(Vec.per(Vec.normalize(Vec.sub(endPoint, startPoint))), 20)
1622
- : Vec.mul(
1623
- endTangentVertical,
1624
- Math.max(
1625
- 100,
1626
- Math.abs(
1627
- Vec.pry(Vec.sub(startPoint, endPoint), endTangentVertical)
1628
- ) / 3
1629
- )
1630
- );
1631
- }
1632
- return this._applyCurveControlPoint(connector, startPoint, endPoint);
1633
- } else {
1634
- startPoint = this._getConnectionPoint(connector, 'source');
1635
- endPoint = this._getConnectionPoint(connector, 'target');
1636
-
1637
- if (!startPoint || !endPoint) return [];
1638
-
1639
- if (
1640
- Math.abs(endPoint[0] - startPoint[0]) >
1641
- Math.abs(endPoint[1] - startPoint[1])
1642
- ) {
1643
- startPoint.out = [Vec.mul(Vec.sub(endPoint, startPoint), 2 / 3)[0], 0];
1644
- endPoint.in = [Vec.mul(Vec.sub(startPoint, endPoint), 2 / 3)[0], 0];
1645
- } else {
1646
- startPoint.out = [0, Vec.mul(Vec.sub(endPoint, startPoint), 2 / 3)[1]];
1647
- endPoint.in = [0, Vec.mul(Vec.sub(startPoint, endPoint), 2 / 3)[1]];
1648
- }
1649
- return this._applyCurveControlPoint(connector, startPoint, endPoint);
1650
- }
1651
- }
1652
-
1653
- /**
1654
- * If the connector has a curveControlPoint, recalculate absIn/absOut so the
1655
- * cubic Bézier passes exactly through the control point at t = 0.5.
1656
- *
1657
- * Given endpoints P0 (start) and P3 (end), and desired passthrough C:
1658
- * P1 = (4C − P3) / 3 → startPoint.out = P1 − P0
1659
- * P2 = (4C − P0) / 3 → endPoint.in = P2 − P3
1660
- *
1661
- * Proof: B(0.5) = (P0 + 3P1 + 3P2 + P3)/8
1662
- * = (P0 + (4C−P3) + (4C−P0) + P3)/8 = 8C/8 = C ✓
1663
- */
1664
- private _applyCurveControlPoint(
1665
- connector: ConnectorElementModel | LocalConnectorElementModel,
1666
- startPoint: PointLocation,
1667
- endPoint: PointLocation
1668
- ): PointLocation[] {
1669
- if (
1670
- connector instanceof ConnectorElementModel &&
1671
- connector.curveControlPoint
1672
- ) {
1673
- const C = connector.curveControlPoint;
1674
- const P0: IVec = [startPoint[0], startPoint[1]];
1675
- const P3: IVec = [endPoint[0], endPoint[1]];
1676
-
1677
- // out = P1 - P0 = (4C - P3 - 3P0) / 3
1678
- startPoint.out = Vec.div(
1679
- Vec.sub(Vec.sub(Vec.mul(C, 4), P3), Vec.mul(P0, 3)),
1680
- 3
1681
- );
1682
-
1683
- // in = P2 - P3 = (4C - P0 - 3P3) / 3
1684
- endPoint.in = Vec.div(
1685
- Vec.sub(Vec.sub(Vec.mul(C, 4), P0), Vec.mul(P3, 3)),
1686
- 3
1687
- );
1688
- }
1689
- return [startPoint, endPoint];
1690
- }
1691
-
1692
- private _generateStraightConnectorPath(
1693
- connector: ConnectorElementModel | LocalConnectorElementModel
1694
- ) {
1695
- const { source, target } = connector;
1696
- if (source.id && !source.position && target.id && !target.position) {
1697
- const start = this._getConnectorEndElement(
1698
- connector,
1699
- 'source'
1700
- ) as Connectable;
1701
- const end = this._getConnectorEndElement(
1702
- connector,
1703
- 'target'
1704
- ) as Connectable;
1705
- const sb = Bound.deserialize(start.xywh);
1706
- const eb = Bound.deserialize(end.xywh);
1707
- const startPoint = getNearestConnectableAnchor(start, eb.center);
1708
- const endPoint = getNearestConnectableAnchor(end, sb.center);
1709
- if (!startPoint || !endPoint) return [];
1710
- const [adjStart, adjEnd] = this._adjustCenterAnchorEndpoints(
1711
- connector,
1712
- startPoint,
1713
- endPoint
1714
- );
1715
- return [adjStart, adjEnd];
1716
- } else {
1717
- const endPoint = this._getConnectionPoint(connector, 'target');
1718
- const startPoint = this._getConnectionPoint(connector, 'source');
1719
- if (!startPoint || !endPoint) return [];
1720
- const [adjStart, adjEnd] = this._adjustCenterAnchorEndpoints(
1721
- connector,
1722
- startPoint,
1723
- endPoint
1724
- );
1725
- return [adjStart, adjEnd];
1726
- }
1727
- }
1728
-
1729
- /**
1730
- * Adjusts connector endpoints so that center-anchored endpoints visually
1731
- * terminate at the shape perimeter rather than at the center.
1732
- *
1733
- * For each endpoint, checks if the logical anchor is the center point
1734
- * [0.5, 0.5] on a center-eligible shape. If so, computes the perimeter
1735
- * intersection from the opposite endpoint toward the center, and replaces
1736
- * the endpoint with the perimeter point.
1737
- */
1738
- private _adjustCenterAnchorEndpoints(
1739
- connector: ConnectorElementModel | LocalConnectorElementModel,
1740
- startPoint: PointLocation,
1741
- endPoint: PointLocation
1742
- ): [PointLocation, PointLocation] {
1743
- const { source, target } = connector;
1744
- const start = this._getConnectorEndElement(connector, 'source');
1745
- const end = this._getConnectorEndElement(connector, 'target');
1746
-
1747
- let adjustedStart = startPoint;
1748
- let adjustedEnd = endPoint;
1749
-
1750
- // Check if source is center-anchored
1751
- if (start && source.id && isCenterAnchorEligible(start)) {
1752
- const isCenter = source.position
1753
- ? isCenterAnchorPosition(source.position, start)
1754
- : this._isPointAtShapeCenter(start, startPoint);
1755
- if (isCenter) {
1756
- adjustedStart = computePerimeterPointForCenterAnchor(
1757
- start,
1758
- startPoint,
1759
- endPoint
1760
- );
1761
- }
1762
- }
1763
-
1764
- // Check if target is center-anchored
1765
- if (end && target.id && isCenterAnchorEligible(end)) {
1766
- const isCenter = target.position
1767
- ? isCenterAnchorPosition(target.position, end)
1768
- : this._isPointAtShapeCenter(end, endPoint);
1769
- if (isCenter) {
1770
- adjustedEnd = computePerimeterPointForCenterAnchor(
1771
- end,
1772
- endPoint,
1773
- // Use adjusted start if it was modified, for accurate direction
1774
- adjustedStart
1775
- );
1776
- }
1777
- }
1778
-
1779
- return [adjustedStart, adjustedEnd];
1780
- }
1781
-
1782
- /**
1783
- * Checks if a PointLocation is at the center of a shape (for detecting
1784
- * auto-selected center anchors when no explicit position is set).
1785
- */
1786
- private _isPointAtShapeCenter(
1787
- connectable: GfxModel,
1788
- point: PointLocation
1789
- ): boolean {
1790
- const bound = Bound.deserialize(connectable.xywh);
1791
- const center = getPointFromBoundsWithRotation(
1792
- { ...bound, rotate: connectable.rotate },
1793
- bound.center
1794
- );
1795
- return (
1796
- almostEqual(point[0], center[0], 1) &&
1797
- almostEqual(point[1], center[1], 1)
1798
- );
1799
- }
1800
-
1801
- private _getConnectionPoint(
1802
- connector: ConnectorElementModel | LocalConnectorElementModel,
1803
- type: 'source' | 'target'
1804
- ): PointLocation | null {
1805
- const connection = connector[type];
1806
-
1807
- if (!connection) return null;
1808
-
1809
- const connectable = this._getConnectorEndElement(connector, type);
1810
-
1811
- if (!connectable && connection.position) {
1812
- return PointLocation.fromVec(connection.position);
1813
- }
1814
-
1815
- if (!connectable) return null;
1816
-
1817
- let point: PointLocation | null = null;
1818
-
1819
- if (connection.position) {
1820
- point = getConnectableRelativePosition(connectable, connection.position);
1821
- } else {
1822
- const anotherType = type === 'source' ? 'target' : 'source';
1823
- const otherPoint = this._getConnectionPoint(connector, anotherType);
1824
- if (otherPoint) {
1825
- point = getNearestConnectableAnchor(connectable, otherPoint);
1826
- }
1827
- }
1828
-
1829
- return point;
1830
- }
1831
-
1832
- private _getConnectorEndElement(
1833
- connector: ConnectorElementModel | LocalConnectorElementModel,
1834
- type: 'source' | 'target'
1835
- ): Connectable | null {
1836
- const id = connector[type].id;
1837
-
1838
- if (id) {
1839
- return this.options.getElementById(id) as Connectable;
1840
- }
1841
-
1842
- return null;
1843
- }
1844
-
1845
- hasRelatedElement(
1846
- connecter: ConnectorElementModel | LocalConnectorElementModel
1847
- ) {
1848
- const { source, target } = connecter;
1849
- if (
1850
- (source.id && !this.options.getElementById(source.id)) ||
1851
- (target.id && !this.options.getElementById(target.id))
1852
- ) {
1853
- return false;
1854
- }
1855
-
1856
- return true;
1857
- }
1858
- }
1
+ import { AStarRunner, Overlay } from '../affine-block-surface/index.js';
2
+ import {
3
+ type BrushElementModel,
4
+ type Connection,
5
+ ConnectorElementModel,
6
+ ConnectorMode,
7
+ DEFAULT_POLYGON_VERTICES,
8
+ GroupElementModel,
9
+ type LocalConnectorElementModel,
10
+ ShapeElementModel,
11
+ ShapeType,
12
+ } from '../affine-model/index.js';
13
+ import {
14
+ EditPropsStore,
15
+ ThemeProvider,
16
+ } from '../affine-shared/services/index.js';
17
+ import { BlockSuiteError } from '../global/exceptions/index.js';
18
+ import type { IBound, IVec, IVec3 } from '../global/gfx/index.js';
19
+ import {
20
+ almostEqual,
21
+ Bound,
22
+ getBezierCurveBoundingBox,
23
+ getBezierParameters,
24
+ getBoundFromPoints,
25
+ getBoundWithRotation,
26
+ getPointFromBoundsWithRotation,
27
+ isOverlap,
28
+ isVecZero,
29
+ lineIntersects,
30
+ PI2,
31
+ PointLocation,
32
+ polygonCentroid,
33
+ sign,
34
+ toRadian,
35
+ Vec,
36
+ } from '../global/gfx/index.js';
37
+ import { assertType } from '../global/utils/index.js';
38
+ import type { BlockStdScope } from '../std/index.js';
39
+ import type {
40
+ GfxController,
41
+ GfxLocalElementModel,
42
+ GfxModel,
43
+ } from '../std/gfx/index.js';
44
+ import { effect } from '@preact/signals-core';
45
+ import last from 'lodash-es/last';
46
+
47
+ export type Connectable = Exclude<
48
+ GfxModel,
49
+ ConnectorElementModel | BrushElementModel | GroupElementModel
50
+ >;
51
+
52
+ export type OrthogonalConnectorInput = {
53
+ startBound: Bound | null;
54
+ endBound: Bound | null;
55
+ startPoint: PointLocation;
56
+ endPoint: PointLocation;
57
+ };
58
+
59
+ export const ConnectorEndpointLocations: IVec[] = [
60
+ // At top
61
+ [0.5, 0],
62
+ // At right
63
+ [1, 0.5],
64
+ // At bottom
65
+ [0.5, 1],
66
+ // At left
67
+ [0, 0.5],
68
+ ];
69
+
70
+ export const ConnectorEndpointLocationsWithCenter: IVec[] = [
71
+ // At top
72
+ [0.5, 0],
73
+ // At right
74
+ [1, 0.5],
75
+ // At bottom
76
+ [0.5, 1],
77
+ // At left
78
+ [0, 0.5],
79
+ // At center
80
+ [0.5, 0.5],
81
+ ];
82
+
83
+ export const ConnectorEndpointLocationsOnTriangle: IVec[] = [
84
+ // At top
85
+ [0.5, 0],
86
+ // At right
87
+ [0.75, 0.5],
88
+ // At bottom
89
+ [0.5, 1],
90
+ // At left
91
+ [0.25, 0.5],
92
+ // At center
93
+ [0.5, 0.5],
94
+ ];
95
+
96
+ /**
97
+ * Checks if a GfxModel is a shape eligible for center anchor point.
98
+ * Only Rect (including roundedRect), Ellipse, Diamond, and Triangle are eligible.
99
+ * Triangle and other complex shapes are excluded.
100
+ */
101
+ export function isCenterAnchorEligible(ele: GfxModel): boolean {
102
+ if (!(ele instanceof ShapeElementModel)) return false;
103
+ const { shapeType } = ele;
104
+ return (
105
+ shapeType === ShapeType.Rect ||
106
+ shapeType === ShapeType.Ellipse ||
107
+ shapeType === ShapeType.Diamond ||
108
+ shapeType === ShapeType.Triangle ||
109
+ shapeType === ShapeType.Polygon
110
+ );
111
+ }
112
+
113
+ /**
114
+ * Returns the normalized [0..1] coordinate of a shape's center anchor.
115
+ * For polygons this is the geometric centroid of the (normalized) vertices;
116
+ * for all other eligible shapes it is the bounding-box center [0.5, 0.5].
117
+ */
118
+ function getCenterAnchorCoord(ele: GfxModel): IVec {
119
+ if (ele instanceof ShapeElementModel && ele.shapeType === ShapeType.Polygon) {
120
+ return polygonCentroid(ele.vertices ?? DEFAULT_POLYGON_VERTICES);
121
+ }
122
+ return [0.5, 0.5];
123
+ }
124
+
125
+ /**
126
+ * Checks if the center anchor feature is enabled via the global toggle.
127
+ * Defaults to true (enabled) when no value is stored in localStorage.
128
+ */
129
+ export function isCenterAnchorEnabled(std: BlockStdScope): boolean {
130
+ const store = std.getOptional(EditPropsStore);
131
+ if (!store) return true;
132
+ return store.getStorage('connectorCenterAnchor') ?? true;
133
+ }
134
+
135
+ /**
136
+ * Checks if a normalized anchor position is the shape's center anchor.
137
+ * Shape-aware: for polygons the center is the geometric centroid, otherwise
138
+ * the bounding-box center [0.5, 0.5].
139
+ */
140
+ function isCenterAnchorPosition(position: IVec, ele: GfxModel): boolean {
141
+ const [cx, cy] = getCenterAnchorCoord(ele);
142
+ return (
143
+ almostEqual(position[0], cx, 0.001) && almostEqual(position[1], cy, 0.001)
144
+ );
145
+ }
146
+
147
+ /**
148
+ * For a center-anchored connector endpoint, computes the perimeter intersection
149
+ * point so the connector visually terminates at the shape edge rather than
150
+ * penetrating to the center. The logical anchor remains [0.5, 0.5] but the
151
+ * visual endpoint is where the line from otherPoint to center crosses the
152
+ * shape boundary.
153
+ *
154
+ * Handles each eligible shape type (Rect, roundedRect, Ellipse, Diamond, Triangle) by
155
+ * using the shape's own getLineIntersections method, which dispatches to
156
+ * shape-specific geometry (polygon boundary for Rect/Diamond, ellipse math
157
+ * for Ellipse). For roundedRect, the polygon approximation of the bounding
158
+ * rectangle is used, which is consistent with existing edge anchor behavior.
159
+ *
160
+ * The function extends the ray beyond the center to handle cases where
161
+ * otherPoint is inside or very close to the shape, ensuring a boundary
162
+ * intersection is always found.
163
+ *
164
+ * Returns a new PointLocation at the perimeter with an appropriate tangent,
165
+ * or the original centerPoint if no intersection is found.
166
+ */
167
+ function computePerimeterPointForCenterAnchor(
168
+ connectable: GfxModel,
169
+ centerPoint: PointLocation,
170
+ otherPoint: PointLocation
171
+ ): PointLocation {
172
+ const bound = Bound.deserialize(connectable.xywh);
173
+ const center: IVec = [centerPoint[0], centerPoint[1]];
174
+ const other: IVec = [otherPoint[0], otherPoint[1]];
175
+
176
+ // Compute direction from other point to center
177
+ let direction = Vec.sub(center, other);
178
+ const dirLen = Vec.len(direction);
179
+
180
+ // If the other point is effectively at the center (e.g. both endpoints
181
+ // on the same shape center, or overlapping shapes), use a default
182
+ // direction pointing right — this gives a deterministic perimeter point
183
+ if (dirLen < 0.01) {
184
+ direction = [1, 0];
185
+ } else {
186
+ direction = Vec.normalize(direction);
187
+ }
188
+
189
+ // Extend the ray well beyond the center through the shape to guarantee
190
+ // it crosses the boundary, even when otherPoint is inside the shape.
191
+ // Use the shape's diagonal length as a generous extension distance.
192
+ const diagonal = Math.sqrt(bound.w * bound.w + bound.h * bound.h);
193
+ const rayStart = Vec.sub(center, Vec.mul(direction, diagonal));
194
+ const rayEnd = Vec.add(center, Vec.mul(direction, diagonal));
195
+
196
+ // Use shape-specific line intersection (rect uses polygon, ellipse uses
197
+ // analytic ellipse math, diamond uses polygon)
198
+ const intersections = connectable.getLineIntersections(rayStart, rayEnd);
199
+
200
+ if (intersections && intersections.length > 0) {
201
+ // Pick the intersection closest to the other point — this is the
202
+ // perimeter point that the connector should visually terminate at
203
+ // (the "entry" side of the shape from the other endpoint's perspective)
204
+ let bestIntersection = intersections[0];
205
+ let bestDist = Vec.dist(bestIntersection, other);
206
+
207
+ for (let i = 1; i < intersections.length; i++) {
208
+ const dist = Vec.dist(intersections[i], other);
209
+ if (dist < bestDist) {
210
+ bestDist = dist;
211
+ bestIntersection = intersections[i];
212
+ }
213
+ }
214
+
215
+ // The intersection PointLocation already carries an appropriate tangent
216
+ // from the shape's getLineIntersections (polygon tangent for Rect/Diamond,
217
+ // ellipse normal-derived tangent for Ellipse), which the connector
218
+ // routing engine uses for orthogonal/curve path computation.
219
+ return bestIntersection;
220
+ }
221
+
222
+ // Fallback: use getNearestPoint on shape boundary from the other endpoint
223
+ const nearest = connectable.getNearestPoint(other);
224
+ if (nearest) {
225
+ const relPos = bound.toRelative(nearest);
226
+ return getConnectableRelativePosition(connectable, relPos);
227
+ }
228
+
229
+ return centerPoint;
230
+ }
231
+
232
+ export function isConnectorWithLabel(model: GfxModel | GfxLocalElementModel) {
233
+ return model instanceof ConnectorElementModel && model.hasLabel();
234
+ }
235
+
236
+ export function calculateNearestLocation(
237
+ point: IVec,
238
+ bounds: IBound,
239
+ locations = ConnectorEndpointLocations,
240
+ shortestDistance = Number.POSITIVE_INFINITY
241
+ ) {
242
+ const { x, y, w, h } = bounds;
243
+ return locations
244
+ .map<IVec>(offset => [x + offset[0] * w, y + offset[1] * h])
245
+ .map(point => getPointFromBoundsWithRotation(bounds, point))
246
+ .reduce(
247
+ (prev, curr, index) => {
248
+ const d = Vec.dist(point, curr);
249
+ if (d < shortestDistance) {
250
+ const location = locations[index];
251
+ shortestDistance = d;
252
+ prev[0] = location[0];
253
+ prev[1] = location[1];
254
+ }
255
+ return prev;
256
+ },
257
+ [...locations[0]]
258
+ );
259
+ }
260
+
261
+ function rBound(ele: GfxModel, anti = false): IBound {
262
+ const bound = Bound.deserialize(ele.xywh);
263
+ return { ...bound, rotate: anti ? -ele.rotate : ele.rotate };
264
+ }
265
+
266
+ export function isConnectorAndBindingsAllSelected(
267
+ connector: ConnectorElementModel | LocalConnectorElementModel,
268
+ selected: GfxModel[]
269
+ ) {
270
+ const connectorSelected = selected.find(s => s.id === connector.id);
271
+ if (!connectorSelected) {
272
+ return false;
273
+ }
274
+ const { source, target } = connector;
275
+ const startSelected = selected.find(s => s.id === source?.id);
276
+ const endSelected = selected.find(s => s.id === target?.id);
277
+ if (!source.id && !target.id) {
278
+ return true;
279
+ }
280
+ if (!source.id && endSelected) {
281
+ return true;
282
+ }
283
+ if (!target.id && startSelected) {
284
+ return true;
285
+ }
286
+ if (startSelected && endSelected) {
287
+ return true;
288
+ }
289
+ return false;
290
+ }
291
+
292
+ export function getAnchors(ele: GfxModel, includeCenterAnchor = true) {
293
+ const bound = Bound.deserialize(ele.xywh);
294
+ const offset = 10;
295
+ const anchors: { point: PointLocation; coord: IVec }[] = [];
296
+ const rotate = ele.rotate;
297
+
298
+ // Elements that opt into center-only anchoring (e.g. Wardley nodes) expose a
299
+ // single anchor at their center; links clip to the perimeter via
300
+ // getLineIntersections.
301
+ if ((ele as { centerAnchorOnly?: boolean }).centerAnchorOnly) {
302
+ const centerPoint = getPointFromBoundsWithRotation(
303
+ { ...bound, rotate },
304
+ bound.center
305
+ );
306
+ return [{ point: new PointLocation(centerPoint), coord: [0.5, 0.5] as IVec }];
307
+ }
308
+
309
+ // For polygon shapes, generate anchors at each vertex and edge midpoint
310
+ if (
311
+ ele instanceof ShapeElementModel &&
312
+ ele.shapeType === ShapeType.Polygon
313
+ ) {
314
+ const verts: number[][] = ele.vertices ?? DEFAULT_POLYGON_VERTICES;
315
+
316
+ for (let i = 0; i < verts.length; i++) {
317
+ const curr = verts[i];
318
+ const next = verts[(i + 1) % verts.length];
319
+
320
+ // CW edge direction in absolute space, with element rotation applied.
321
+ // This matches the convention used by linePolygonIntersects / polygonGetPointTangent:
322
+ // Vec.rot(CW_edge_direction, -π/2) yields the outward normal.
323
+ const edx = (next[0] - curr[0]) * bound.w;
324
+ const edy = (next[1] - curr[1]) * bound.h;
325
+ const edLen = Math.sqrt(edx * edx + edy * edy) || 1;
326
+ const edgeTangent: IVec = Vec.rot(
327
+ [edx / edLen, edy / edLen],
328
+ toRadian(rotate)
329
+ );
330
+
331
+ // --- Vertex anchor ---
332
+ const vertCoord: IVec = [curr[0], curr[1]];
333
+ const vertAbs: IVec = [
334
+ bound.x + vertCoord[0] * bound.w,
335
+ bound.y + vertCoord[1] * bound.h,
336
+ ];
337
+ const vertRotated = getPointFromBoundsWithRotation(
338
+ { ...bound, rotate },
339
+ vertAbs
340
+ );
341
+ anchors.push({
342
+ point: new PointLocation(vertRotated, edgeTangent),
343
+ coord: vertCoord,
344
+ });
345
+
346
+ // --- Edge midpoint anchor ---
347
+ const midCoord: IVec = [
348
+ (curr[0] + next[0]) / 2,
349
+ (curr[1] + next[1]) / 2,
350
+ ];
351
+ const midAbs: IVec = [
352
+ bound.x + midCoord[0] * bound.w,
353
+ bound.y + midCoord[1] * bound.h,
354
+ ];
355
+ const midRotated = getPointFromBoundsWithRotation(
356
+ { ...bound, rotate },
357
+ midAbs
358
+ );
359
+ anchors.push({
360
+ point: new PointLocation(midRotated, edgeTangent),
361
+ coord: midCoord,
362
+ });
363
+ }
364
+
365
+ // Center anchor at the polygon's geometric centroid (gated on the toggle).
366
+ if (includeCenterAnchor) {
367
+ const centroid = polygonCentroid(verts);
368
+ const centroidAbs: IVec = [
369
+ bound.x + centroid[0] * bound.w,
370
+ bound.y + centroid[1] * bound.h,
371
+ ];
372
+ const centroidRotated = getPointFromBoundsWithRotation(
373
+ { ...bound, rotate },
374
+ centroidAbs
375
+ );
376
+ anchors.push({
377
+ point: new PointLocation(centroidRotated),
378
+ coord: centroid,
379
+ });
380
+ }
381
+ return anchors;
382
+ }
383
+
384
+ (
385
+ [
386
+ [bound.center[0], bound.y - offset],
387
+ [bound.center[0], bound.maxY + offset],
388
+ [bound.x - offset, bound.center[1]],
389
+ [bound.maxX + offset, bound.center[1]],
390
+ ] satisfies IVec[]
391
+ )
392
+ .map(vec => getPointFromBoundsWithRotation({ ...bound, rotate }, vec))
393
+ .forEach(vec => {
394
+ const rst = ele.getLineIntersections(bound.center, vec);
395
+ if (!rst) return;
396
+
397
+ const originPoint = getPointFromBoundsWithRotation(
398
+ { ...bound, rotate: -rotate },
399
+ rst[0]
400
+ );
401
+ anchors.push({ point: rst[0], coord: bound.toRelative(originPoint) });
402
+ });
403
+
404
+ // Add center anchor for eligible shapes (Rect, roundedRect, Ellipse, Diamond, Triangle)
405
+ if (includeCenterAnchor && isCenterAnchorEligible(ele)) {
406
+ const centerPoint = getPointFromBoundsWithRotation(
407
+ { ...bound, rotate },
408
+ bound.center
409
+ );
410
+ const centerPointLocation = new PointLocation(centerPoint);
411
+ anchors.push({ point: centerPointLocation, coord: [0.5, 0.5] });
412
+ }
413
+
414
+ return anchors;
415
+ }
416
+
417
+ function getConnectableRelativePosition(connectable: GfxModel, position: IVec) {
418
+ const location = connectable.getRelativePointLocation(position);
419
+ if (isVecZero(Vec.sub(position, [0, 0.5])))
420
+ location.tangent = Vec.rot([0, -1], toRadian(connectable.rotate));
421
+ else if (isVecZero(Vec.sub(position, [1, 0.5])))
422
+ location.tangent = Vec.rot([0, 1], toRadian(connectable.rotate));
423
+ else if (isVecZero(Vec.sub(position, [0.5, 0])))
424
+ location.tangent = Vec.rot([1, 0], toRadian(connectable.rotate));
425
+ else if (isVecZero(Vec.sub(position, [0.5, 1])))
426
+ location.tangent = Vec.rot([-1, 0], toRadian(connectable.rotate));
427
+ return location;
428
+ }
429
+
430
+ export function getNearestConnectableAnchor(
431
+ ele: Connectable,
432
+ point: IVec,
433
+ includeCenterAnchor = true
434
+ ) {
435
+ const anchors = getAnchors(ele, includeCenterAnchor);
436
+ return closestPoint(
437
+ anchors.map(a => a.point),
438
+ point
439
+ );
440
+ }
441
+
442
+ function closestPoint(
443
+ points: PointLocation[],
444
+ point: IVec
445
+ ): PointLocation | null {
446
+ if (points.length === 0) return null;
447
+ const rst = points.map(p => ({ p, d: Vec.dist(p, point) }));
448
+ rst.sort((a, b) => a.d - b.d);
449
+ return rst[0].p;
450
+ }
451
+
452
+ function computePoints(
453
+ startPoint: IVec,
454
+ endPoint: IVec,
455
+ nextStartPoint: IVec,
456
+ lastEndPoint: IVec,
457
+ startBound: Bound | null,
458
+ endBound: Bound | null,
459
+ expandStartBound: Bound | null,
460
+ expandEndBound: Bound | null
461
+ ): [IVec3[], IVec3, IVec3, IVec3, IVec3] {
462
+ const startPointVec3 = downscalePrecision(startPoint);
463
+ const endPointVec3 = downscalePrecision(endPoint);
464
+ let nextStartPointVec3 = downscalePrecision(nextStartPoint);
465
+ let lastEndPointVec3 = downscalePrecision(lastEndPoint);
466
+
467
+ const result = getConnectablePoints(
468
+ startPointVec3,
469
+ endPointVec3,
470
+ nextStartPointVec3,
471
+ lastEndPointVec3,
472
+ startBound,
473
+ endBound,
474
+ expandStartBound,
475
+ expandEndBound
476
+ );
477
+ const points = result.points;
478
+ nextStartPointVec3 = result.nextStartPoint;
479
+ lastEndPointVec3 = result.lastEndPoint;
480
+ const finalPoints = filterConnectablePoints(
481
+ filterConnectablePoints(points, expandStartBound?.expand(-1) ?? null),
482
+ expandEndBound?.expand(-1) ?? null
483
+ );
484
+ return [
485
+ finalPoints,
486
+ startPointVec3,
487
+ endPointVec3,
488
+ nextStartPointVec3,
489
+ lastEndPointVec3,
490
+ ];
491
+ }
492
+
493
+ function downscalePrecision(point: IVec | IVec3): IVec3 {
494
+ return [
495
+ Number(point[0].toFixed(2)),
496
+ Number(point[1].toFixed(2)),
497
+ point[2] ?? 0,
498
+ ];
499
+ }
500
+
501
+ function filterConnectablePoints<T extends IVec3 | IVec>(
502
+ points: T[],
503
+ bound: Bound | null
504
+ ): T[] {
505
+ return points.filter(point => {
506
+ if (!bound) return true;
507
+ return !bound.isPointInBound([point[0], point[1]]);
508
+ });
509
+ }
510
+
511
+ function pushWithPriority(points: number[][], vecs: IVec[], priority = 0) {
512
+ points.push(...vecs.map(vec => [...vec, priority]));
513
+ }
514
+
515
+ function pushLineIntersectsToPoints(
516
+ points: IVec3[],
517
+ aLine: IVec[],
518
+ bLine: IVec[],
519
+ priority = 0
520
+ ) {
521
+ const rst = lineIntersects(aLine[0], aLine[1], bLine[0], bLine[1], true);
522
+ if (rst) {
523
+ pushWithPriority(points, [rst], priority);
524
+ }
525
+ }
526
+
527
+ function pushOuterPoints(
528
+ points: IVec3[],
529
+ expandStartBound: Bound,
530
+ expandEndBound: Bound,
531
+ outerBound: Bound
532
+ ) {
533
+ if (expandStartBound && expandEndBound && outerBound) {
534
+ pushWithPriority(points, outerBound.getVerticesAndMidpoints());
535
+ pushWithPriority(points, [outerBound.center], 2);
536
+ [
537
+ expandStartBound.upperLine,
538
+ expandStartBound.horizontalLine,
539
+ expandStartBound.lowerLine,
540
+ expandEndBound.upperLine,
541
+ expandEndBound.horizontalLine,
542
+ expandEndBound.lowerLine,
543
+ ].forEach(line => {
544
+ pushLineIntersectsToPoints(points, line, outerBound.leftLine, 0);
545
+ pushLineIntersectsToPoints(points, line, outerBound.rightLine, 0);
546
+ });
547
+ [
548
+ expandStartBound.leftLine,
549
+ expandStartBound.verticalLine,
550
+ expandStartBound.rightLine,
551
+ expandEndBound.leftLine,
552
+ expandEndBound.verticalLine,
553
+ expandEndBound.rightLine,
554
+ ].forEach(line => {
555
+ pushLineIntersectsToPoints(points, line, outerBound.upperLine, 0);
556
+ pushLineIntersectsToPoints(points, line, outerBound.lowerLine, 0);
557
+ });
558
+ }
559
+ }
560
+
561
+ function pushBoundMidPoint(
562
+ points: IVec3[],
563
+ bound1: Bound,
564
+ bound2: Bound,
565
+ expandBound1: Bound,
566
+ expandBound2: Bound
567
+ ) {
568
+ if (bound1.maxX < bound2.x) {
569
+ const midX = (bound1.maxX + bound2.x) / 2;
570
+ [
571
+ expandBound1.horizontalLine,
572
+ expandBound2.horizontalLine,
573
+ expandBound1.upperLine,
574
+ expandBound1.lowerLine,
575
+ expandBound2.upperLine,
576
+ expandBound2.lowerLine,
577
+ ].forEach((line, index) => {
578
+ pushLineIntersectsToPoints(
579
+ points,
580
+ line,
581
+ [
582
+ [midX, 0],
583
+ [midX, 1],
584
+ ],
585
+ index === 0 || index === 1 ? 6 : 3
586
+ );
587
+ });
588
+ }
589
+ if (bound1.maxY < bound2.y) {
590
+ const midY = (bound1.maxY + bound2.y) / 2;
591
+ [
592
+ expandBound1.verticalLine,
593
+ expandBound2.verticalLine,
594
+ expandBound1.leftLine,
595
+ expandBound1.rightLine,
596
+ expandBound2.leftLine,
597
+ expandBound2.rightLine,
598
+ ].forEach((line, index) => {
599
+ pushLineIntersectsToPoints(
600
+ points,
601
+ line,
602
+ [
603
+ [0, midY],
604
+ [1, midY],
605
+ ],
606
+ index === 0 || index === 1 ? 6 : 3
607
+ );
608
+ });
609
+ }
610
+ }
611
+
612
+ function pushGapMidPoint(
613
+ points: IVec3[],
614
+ point: IVec3,
615
+ bound: Bound,
616
+ bound2: Bound,
617
+ expandBound: Bound,
618
+ expandBound2: Bound
619
+ ) {
620
+ /** on top or on bottom */
621
+ if (
622
+ almostEqual(point[1], bound.y, 0.02) ||
623
+ almostEqual(point[1], bound.maxY, 0.02)
624
+ ) {
625
+ const rst = [
626
+ bound.upperLine,
627
+ bound.lowerLine,
628
+ bound2.upperLine,
629
+ bound2.lowerLine,
630
+ ]
631
+ .map(line => {
632
+ return lineIntersects(
633
+ [point[0], point[1]],
634
+ [point[0], point[1] + 1],
635
+ line[0],
636
+ line[1],
637
+ true
638
+ );
639
+ })
640
+ .filter(p => p !== null);
641
+ rst.sort((a, b) => a[1] - b[1]);
642
+ const midPoint = Vec.lrp(rst[1], rst[2], 0.5);
643
+ pushWithPriority(points, [midPoint], 6);
644
+ [
645
+ expandBound.leftLine,
646
+ expandBound.rightLine,
647
+ expandBound2.leftLine,
648
+ expandBound2.rightLine,
649
+ ].forEach(line => {
650
+ pushLineIntersectsToPoints(
651
+ points,
652
+ [midPoint, [midPoint[0] + 1, midPoint[1]]],
653
+ line,
654
+ 0
655
+ );
656
+ });
657
+ } else {
658
+ const rst = [
659
+ bound.leftLine,
660
+ bound.rightLine,
661
+ bound2.leftLine,
662
+ bound2.rightLine,
663
+ ]
664
+ .map(line => {
665
+ return lineIntersects(
666
+ [point[0], point[1]],
667
+ [point[0] + 1, point[1]],
668
+ line[0],
669
+ line[1],
670
+ true
671
+ );
672
+ })
673
+ .filter(p => p !== null);
674
+ rst.sort((a, b) => a[0] - b[0]);
675
+ const midPoint = Vec.lrp(rst[1], rst[2], 0.5);
676
+ pushWithPriority(points, [midPoint], 6);
677
+ [
678
+ expandBound.upperLine,
679
+ expandBound.lowerLine,
680
+ expandBound2.upperLine,
681
+ expandBound2.lowerLine,
682
+ ].forEach(line => {
683
+ pushLineIntersectsToPoints(
684
+ points,
685
+ [midPoint, [midPoint[0], midPoint[1] + 1]],
686
+ line,
687
+ 0
688
+ );
689
+ });
690
+ }
691
+ }
692
+
693
+ function removeDulicatePoints(points: IVec[] | IVec3[]) {
694
+ points = points.map(downscalePrecision);
695
+ points.sort((a, b) => a[0] - b[0]);
696
+ assertType<IVec3[]>(points);
697
+ for (let i = 1; i < points.length - 1; i++) {
698
+ const cur = points[i];
699
+ const last = points[i - 1];
700
+ if (almostEqual(cur[0], last[0], 0.02)) {
701
+ cur[0] = last[0];
702
+ }
703
+ }
704
+ points.sort((a, b) => a[1] - b[1]);
705
+ for (let i = 1; i < points.length - 1; i++) {
706
+ const cur = points[i];
707
+ const last = points[i - 1];
708
+ if (almostEqual(cur[1], last[1], 0.02)) {
709
+ cur[1] = last[1];
710
+ }
711
+ }
712
+ points.sort((a, b) => {
713
+ if (a[0] < b[0]) return -1;
714
+ if (a[0] > b[0]) return 1;
715
+ if (a[1] < b[1]) return -1;
716
+ if (a[1] > b[1]) return 1;
717
+ return 0;
718
+ });
719
+ for (let i = 1; i < points.length; i++) {
720
+ const cur = points[i];
721
+ const last = points[i - 1];
722
+ if (
723
+ almostEqual(cur[0], last[0], 0.02) &&
724
+ almostEqual(cur[1], last[1], 0.02)
725
+ ) {
726
+ if (cur[2] <= last[2]) points.splice(i, 1);
727
+ else points.splice(i - 1, 1);
728
+ i--;
729
+ continue;
730
+ }
731
+ }
732
+ return points;
733
+ }
734
+
735
+ function getConnectablePoints(
736
+ startPoint: IVec3,
737
+ endPoint: IVec3,
738
+ nextStartPoint: IVec3,
739
+ lastEndPoint: IVec3,
740
+ startBound: Bound | null,
741
+ endBound: Bound | null,
742
+ expandStartBound: Bound | null,
743
+ expandEndBound: Bound | null
744
+ ) {
745
+ const lineBound = Bound.fromPoints([
746
+ [startPoint[0], startPoint[1]],
747
+ [endPoint[0], endPoint[1]],
748
+ ]);
749
+ const outerBound =
750
+ expandStartBound &&
751
+ expandEndBound &&
752
+ expandStartBound.unite(expandEndBound);
753
+ let points = [nextStartPoint, lastEndPoint];
754
+ pushWithPriority(points, lineBound.getVerticesAndMidpoints());
755
+
756
+ if (!startBound || !endBound) {
757
+ pushWithPriority(points, [lineBound.center], 3);
758
+ }
759
+ if (outerBound) {
760
+ pushOuterPoints(points, expandStartBound, expandEndBound, outerBound);
761
+ }
762
+
763
+ if (startBound && endBound && expandStartBound && expandEndBound) {
764
+ pushGapMidPoint(
765
+ points,
766
+ startPoint,
767
+ startBound,
768
+ endBound,
769
+ expandStartBound,
770
+ expandEndBound
771
+ );
772
+ pushGapMidPoint(
773
+ points,
774
+ endPoint,
775
+ endBound,
776
+ startBound,
777
+ expandEndBound,
778
+ expandStartBound
779
+ );
780
+ pushBoundMidPoint(
781
+ points,
782
+ startBound,
783
+ endBound,
784
+ expandStartBound,
785
+ expandEndBound
786
+ );
787
+ pushBoundMidPoint(
788
+ points,
789
+ endBound,
790
+ startBound,
791
+ expandEndBound,
792
+ expandStartBound
793
+ );
794
+ }
795
+
796
+ if (expandStartBound) {
797
+ pushWithPriority(points, expandStartBound.getVerticesAndMidpoints());
798
+ pushWithPriority(
799
+ points,
800
+ expandStartBound.include([lastEndPoint[0], lastEndPoint[1]]).points
801
+ );
802
+ }
803
+
804
+ if (expandEndBound) {
805
+ pushWithPriority(points, expandEndBound.getVerticesAndMidpoints());
806
+ pushWithPriority(
807
+ points,
808
+ expandEndBound.include([nextStartPoint[0], nextStartPoint[1]]).points
809
+ );
810
+ }
811
+
812
+ points = removeDulicatePoints(points);
813
+
814
+ const sorted = points.map(point => point[0] + ',' + point[1]).sort();
815
+ sorted.forEach((cur, index) => {
816
+ if (index === 0) return;
817
+ if (cur === sorted[index - 1]) {
818
+ throw new Error('duplicate point');
819
+ }
820
+ });
821
+ const startEnds = [nextStartPoint, lastEndPoint].map(point => {
822
+ return points.find(
823
+ item =>
824
+ almostEqual(item[0], point[0], 0.02) &&
825
+ almostEqual(item[1], point[1], 0.02)
826
+ );
827
+ });
828
+ if (!startEnds[0] || !startEnds[1]) {
829
+ throw new BlockSuiteError(
830
+ BlockSuiteError.ErrorCode.ValueNotExists,
831
+ 'Failed to get start and end points when getting connectable points'
832
+ );
833
+ }
834
+ return { points, nextStartPoint: startEnds[0], lastEndPoint: startEnds[1] };
835
+ }
836
+
837
+ function getDirectPath(startPoint: IVec, endPoint: IVec): IVec[] {
838
+ if (
839
+ almostEqual(startPoint[0], endPoint[0], 0.02) ||
840
+ almostEqual(startPoint[1], endPoint[1], 0.02)
841
+ ) {
842
+ return [startPoint, endPoint];
843
+ } else {
844
+ const vec = Vec.sub(endPoint, startPoint);
845
+ const mid: IVec = [startPoint[0], startPoint[1] + vec[1]];
846
+ return [startPoint, mid, endPoint];
847
+ }
848
+ }
849
+
850
+ function mergePath(points: IVec[] | IVec3[]) {
851
+ if (points.length === 0) return [];
852
+ const result: IVec[] = [[points[0][0], points[0][1]]];
853
+ for (let i = 1; i < points.length - 1; i++) {
854
+ const cur = points[i];
855
+ const last = points[i - 1];
856
+ const next = points[i + 1];
857
+ if (
858
+ almostEqual(last[0], cur[0], 0.02) &&
859
+ almostEqual(cur[0], next[0], 0.02)
860
+ )
861
+ continue;
862
+ if (
863
+ almostEqual(last[1], cur[1], 0.02) &&
864
+ almostEqual(cur[1], next[1], 0.02)
865
+ )
866
+ continue;
867
+ result.push([cur[0], cur[1]]);
868
+ }
869
+ if (points.length !== 0) {
870
+ result.push([points[points.length - 1][0], points[points.length - 1][1]]);
871
+ }
872
+ for (let i = 0; i < result.length - 1; i++) {
873
+ const cur = result[i];
874
+ const next = result[i + 1];
875
+ const isAlmostEqual =
876
+ almostEqual(cur[0], next[0], 0.02) || almostEqual(cur[1], next[1], 0.02);
877
+ if (!isAlmostEqual) {
878
+ console.warn('Expected equal points');
879
+ console.warn(points);
880
+ console.warn(result);
881
+ }
882
+ }
883
+ return result;
884
+ }
885
+
886
+ function computeOffset(startBound: Bound | null, endBound: Bound | null) {
887
+ const startOffset = [20, 20, 20, 20];
888
+ const endOffset = [20, 20, 20, 20];
889
+ if (!(startBound && endBound)) {
890
+ return [startOffset, endOffset];
891
+ }
892
+ // left, top, right, bottom
893
+ let overlap = isOverlap(startBound.upperLine, endBound.lowerLine, 0, false);
894
+ let dist: number;
895
+ if (overlap && startBound.upperLine[0][1] > endBound.lowerLine[0][1]) {
896
+ dist = Vec.distanceToLineSegment(
897
+ startBound.upperLine[0],
898
+ startBound.upperLine[1],
899
+ endBound.lowerLine[0],
900
+ false
901
+ );
902
+ startOffset[1] = Math.max(Math.min(dist / 2, startOffset[1]), 0);
903
+ }
904
+
905
+ overlap = isOverlap(startBound.rightLine, endBound.leftLine, 1, false);
906
+ if (overlap && startBound.rightLine[0][0] < endBound.leftLine[0][0]) {
907
+ dist = Vec.distanceToLineSegment(
908
+ startBound.rightLine[0],
909
+ startBound.rightLine[1],
910
+ endBound.leftLine[0],
911
+ false
912
+ );
913
+ startOffset[2] = Math.max(Math.min(dist / 2, startOffset[2]), 0);
914
+ }
915
+
916
+ overlap = isOverlap(startBound.lowerLine, endBound.upperLine, 0, false);
917
+ if (overlap && startBound.lowerLine[0][1] < endBound.upperLine[0][1]) {
918
+ dist = Vec.distanceToLineSegment(
919
+ startBound.lowerLine[0],
920
+ startBound.lowerLine[1],
921
+ endBound.upperLine[0],
922
+ false
923
+ );
924
+ startOffset[3] = Math.max(Math.min(dist / 2, startOffset[3]), 0);
925
+ }
926
+
927
+ startOffset[0] = endOffset[2] =
928
+ Math.min(startOffset[0], endOffset[2]) === 0
929
+ ? 20
930
+ : Math.min(startOffset[0], endOffset[2]);
931
+ startOffset[1] = endOffset[3] =
932
+ Math.min(startOffset[1], endOffset[3]) === 0
933
+ ? 20
934
+ : Math.min(startOffset[1], endOffset[3]);
935
+ startOffset[2] = endOffset[0] =
936
+ Math.min(startOffset[2], endOffset[0]) === 0
937
+ ? 20
938
+ : Math.min(startOffset[2], endOffset[0]);
939
+ startOffset[3] = endOffset[1] =
940
+ Math.min(startOffset[3], endOffset[1]) === 0
941
+ ? 20
942
+ : Math.min(startOffset[3], endOffset[1]);
943
+
944
+ return [startOffset, endOffset];
945
+ }
946
+
947
+ function getNextPoint(
948
+ bound: Bound,
949
+ point: PointLocation,
950
+ offsetX = 10,
951
+ offsetY = 10,
952
+ offsetW = 10,
953
+ offsetH = 10
954
+ ) {
955
+ const result: IVec = [point[0], point[1]];
956
+ if (almostEqual(bound.x, result[0])) result[0] -= offsetX;
957
+ else if (almostEqual(bound.y, result[1])) result[1] -= offsetY;
958
+ else if (almostEqual(bound.maxX, result[0])) result[0] += offsetW;
959
+ else if (almostEqual(bound.maxY, result[1])) result[1] += offsetH;
960
+ else {
961
+ const direction = Vec.normalize(Vec.sub(result, bound.center));
962
+ const xDirection = direction[0] > 0 ? 1 : -1;
963
+ const yDirection = direction[1] > 0 ? 1 : -1;
964
+
965
+ const slope =
966
+ Math.abs(point.tangent[0]) < Math.abs(point.tangent[1]) ? 0 : 1;
967
+ // if the slope is big, use the x direction
968
+ if (slope === 0) {
969
+ if (xDirection > 0) {
970
+ const intersects = lineIntersects(
971
+ bound.rightLine[0],
972
+ bound.rightLine[1],
973
+ result,
974
+ [bound.maxX + 10, result[1]]
975
+ );
976
+ if (!intersects) {
977
+ throw new BlockSuiteError(
978
+ BlockSuiteError.ErrorCode.ValueNotExists,
979
+ 'Failed to get line intersections for getNextPoint'
980
+ );
981
+ }
982
+ result[0] = intersects[0] + offsetX;
983
+ } else {
984
+ const intersects = lineIntersects(
985
+ bound.leftLine[0],
986
+ bound.leftLine[1],
987
+ result,
988
+ [bound.x - 10, result[1]]
989
+ );
990
+ if (!intersects) {
991
+ throw new BlockSuiteError(
992
+ BlockSuiteError.ErrorCode.ValueNotExists,
993
+ 'Failed to get line intersections for getNextPoint'
994
+ );
995
+ }
996
+ result[0] = intersects[0] - offsetX;
997
+ }
998
+ } else {
999
+ if (yDirection > 0) {
1000
+ const intersects = lineIntersects(
1001
+ bound.lowerLine[0],
1002
+ bound.lowerLine[1],
1003
+ result,
1004
+ [result[0], bound.maxY + 10]
1005
+ );
1006
+ if (!intersects) {
1007
+ throw new BlockSuiteError(
1008
+ BlockSuiteError.ErrorCode.ValueNotExists,
1009
+ 'Failed to get line intersections for getNextPoint'
1010
+ );
1011
+ }
1012
+ result[1] = intersects[1] + offsetY;
1013
+ } else {
1014
+ const intersects = lineIntersects(
1015
+ bound.upperLine[0],
1016
+ bound.upperLine[1],
1017
+ result,
1018
+ [result[0], bound.y - 10]
1019
+ );
1020
+ if (!intersects) {
1021
+ throw new BlockSuiteError(
1022
+ BlockSuiteError.ErrorCode.ValueNotExists,
1023
+ 'Failed to get line intersections for getNextPoint'
1024
+ );
1025
+ }
1026
+ result[1] = intersects[1] - offsetY;
1027
+ }
1028
+ }
1029
+ }
1030
+ return result;
1031
+ }
1032
+
1033
+ function computeNextStartEndpoint(
1034
+ startPoint: PointLocation,
1035
+ endPoint: PointLocation,
1036
+ startBound: Bound | null,
1037
+ endBound: Bound | null,
1038
+ startOffset: number[] | null,
1039
+ endOffset: number[] | null
1040
+ ) {
1041
+ const nextStartPoint =
1042
+ startBound && startOffset
1043
+ ? getNextPoint(
1044
+ startBound,
1045
+ startPoint,
1046
+ startOffset[0],
1047
+ startOffset[1],
1048
+ startOffset[2],
1049
+ startOffset[3]
1050
+ )
1051
+ : startPoint;
1052
+ const lastEndPoint =
1053
+ endBound && endOffset
1054
+ ? getNextPoint(
1055
+ endBound,
1056
+ endPoint,
1057
+ endOffset[0],
1058
+ endOffset[1],
1059
+ endOffset[2],
1060
+ endOffset[3]
1061
+ )
1062
+ : endPoint;
1063
+ return [nextStartPoint, lastEndPoint];
1064
+ }
1065
+
1066
+ function adjustStartEndPoint(
1067
+ startPoint: IVec3,
1068
+ endPoint: IVec3,
1069
+ startBound: Bound | null = null,
1070
+ endBound: Bound | null = null
1071
+ ) {
1072
+ if (!endBound) {
1073
+ if (
1074
+ Math.abs(endPoint[0] - startPoint[0]) >
1075
+ Math.abs(endPoint[1] - startPoint[1])
1076
+ ) {
1077
+ endPoint[0] += sign(endPoint[0] - startPoint[0]) * 20;
1078
+ } else {
1079
+ endPoint[1] += sign(endPoint[1] - startPoint[1]) * 20;
1080
+ }
1081
+ }
1082
+ if (!startBound) {
1083
+ if (
1084
+ Math.abs(endPoint[0] - startPoint[0]) >
1085
+ Math.abs(endPoint[1] - startPoint[1])
1086
+ ) {
1087
+ startPoint[0] -= sign(endPoint[0] - startPoint[0]) * 20;
1088
+ } else {
1089
+ startPoint[1] -= sign(endPoint[1] - startPoint[1]) * 20;
1090
+ }
1091
+ }
1092
+ }
1093
+
1094
+ function renderRect(
1095
+ ctx: CanvasRenderingContext2D,
1096
+ bounds: IBound,
1097
+ color: string,
1098
+ lineWidth: number
1099
+ ) {
1100
+ const { x, y, w, h } = bounds;
1101
+ ctx.save();
1102
+ ctx.beginPath();
1103
+ ctx.strokeStyle = color;
1104
+ ctx.lineWidth = lineWidth;
1105
+ ctx.setLineDash([lineWidth * 2, lineWidth * 2]);
1106
+ ctx.strokeRect(x, y, w, h);
1107
+ ctx.closePath();
1108
+ ctx.restore();
1109
+ }
1110
+
1111
+ export class ConnectionOverlay extends Overlay {
1112
+ static override overlayName = 'connection';
1113
+
1114
+ private _emphasisColor: string;
1115
+
1116
+ private _themeDisposer: (() => void) | null = null;
1117
+
1118
+ highlightPoint: IVec | null = null;
1119
+
1120
+ points: IVec[] = [];
1121
+
1122
+ sourceBounds: IBound | null = null;
1123
+
1124
+ targetBounds: IBound | null = null;
1125
+
1126
+ /**
1127
+ * Checks whether the center anchor toggle is enabled.
1128
+ * Returns true (enabled) by default if no stored value is found.
1129
+ */
1130
+ get centerAnchorEnabled(): boolean {
1131
+ const store = this.gfx.std.getOptional(EditPropsStore);
1132
+ if (!store) return true;
1133
+ const value = store.getStorage('connectorCenterAnchor');
1134
+ return value ?? true;
1135
+ }
1136
+
1137
+ constructor(gfx: GfxController) {
1138
+ super(gfx);
1139
+ this._emphasisColor = this._getEmphasisColor();
1140
+ this._setupThemeListener();
1141
+ }
1142
+
1143
+ private _findConnectablesInViews() {
1144
+ const gfx = this.gfx;
1145
+ const bound = gfx.viewport.viewportBounds;
1146
+ return gfx.getElementsByBound(bound).filter(ele => ele.connectable);
1147
+ }
1148
+
1149
+ private _getEmphasisColor(): string {
1150
+ return getComputedStyle(this.gfx.std.host).getPropertyValue(
1151
+ '--affine-text-emphasis-color'
1152
+ );
1153
+ }
1154
+
1155
+ private _setupThemeListener(): void {
1156
+ const themeService = this.gfx.std.get(ThemeProvider);
1157
+ this._themeDisposer = effect(() => {
1158
+ themeService.theme$;
1159
+ this._emphasisColor = this._getEmphasisColor();
1160
+ });
1161
+ }
1162
+
1163
+ _clearRect() {
1164
+ this.points = [];
1165
+ this.highlightPoint = null;
1166
+ this._renderer?.refresh();
1167
+ }
1168
+
1169
+ override clear() {
1170
+ this.sourceBounds = null;
1171
+ this.targetBounds = null;
1172
+ this._clearRect();
1173
+ }
1174
+
1175
+ override dispose() {
1176
+ this._themeDisposer?.();
1177
+ if (!this._renderer) return;
1178
+ this._renderer.removeOverlay(this);
1179
+ this._renderer = null;
1180
+ }
1181
+
1182
+ override render(ctx: CanvasRenderingContext2D): void {
1183
+ const zoom = this.gfx.viewport.zoom;
1184
+ const radius = 5 / zoom;
1185
+ const color = this._emphasisColor;
1186
+ ctx.globalAlpha = 0.6;
1187
+ let lineWidth = 1 / zoom;
1188
+ if (this.sourceBounds) {
1189
+ renderRect(ctx, this.sourceBounds, color, lineWidth);
1190
+ }
1191
+ if (this.targetBounds) {
1192
+ renderRect(ctx, this.targetBounds, color, lineWidth);
1193
+ }
1194
+
1195
+ lineWidth = 2 / zoom;
1196
+ this.points.forEach(p => {
1197
+ ctx.beginPath();
1198
+ ctx.arc(p[0], p[1], radius, 0, PI2);
1199
+ ctx.fillStyle = 'white';
1200
+ ctx.strokeStyle = color;
1201
+ ctx.lineWidth = lineWidth;
1202
+ ctx.fill();
1203
+ ctx.stroke();
1204
+ ctx.closePath();
1205
+ });
1206
+
1207
+ ctx.globalAlpha = 1;
1208
+ if (this.highlightPoint) {
1209
+ ctx.beginPath();
1210
+ ctx.arc(this.highlightPoint[0], this.highlightPoint[1], radius, 0, PI2);
1211
+ ctx.fillStyle = color;
1212
+ ctx.strokeStyle = color;
1213
+ ctx.lineWidth = lineWidth;
1214
+ ctx.fill();
1215
+ ctx.stroke();
1216
+ ctx.closePath();
1217
+ }
1218
+ }
1219
+
1220
+ /**
1221
+ * Render the connector at the given point. It will try to find
1222
+ * the closest connectable element and render the connector. If the
1223
+ * point is not close to any connectable element, it will just render
1224
+ * the connector at the given point.
1225
+ * @param point the point to render the connector
1226
+ * @param excludedIds the ids of the elements that should be excluded
1227
+ * @returns the connection result
1228
+ */
1229
+ renderConnector(point: IVec, excludedIds: string[] = []) {
1230
+ const connectables = this._findConnectablesInViews();
1231
+ const context = this.gfx;
1232
+ const target = [];
1233
+
1234
+ this._clearRect();
1235
+
1236
+ let result: Connection | null = null;
1237
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
1238
+ for (let i = 0; i < connectables.length; i++) {
1239
+ const connectable = connectables[i];
1240
+ // first check if in excluedIds
1241
+ if (excludedIds.includes(connectable.id)) continue;
1242
+
1243
+ // then check if in expanded bound
1244
+ const bound = Bound.deserialize(connectable.xywh);
1245
+ const rotateBound = Bound.from(getBoundWithRotation(rBound(connectable)));
1246
+ // FIXME: the real path needs to be expanded: diamod, ellipse, trangle.
1247
+ if (!rotateBound.expand(10).isPointInBound(point)) continue;
1248
+
1249
+ // then check if closes to anchors
1250
+ const anchors = getAnchors(connectable, this.centerAnchorEnabled);
1251
+ const len = anchors.length;
1252
+ const pointerViewCoord = context.viewport.toViewCoord(point[0], point[1]);
1253
+
1254
+ let shortestDistance = Number.POSITIVE_INFINITY;
1255
+ let j = 0;
1256
+
1257
+ this.points = anchors.map(a => a.point);
1258
+
1259
+ for (; j < len; j++) {
1260
+ const anchor = anchors[j];
1261
+ const anchorViewCoord = context.viewport.toViewCoord(
1262
+ anchor.point[0],
1263
+ anchor.point[1]
1264
+ );
1265
+ const d = Vec.dist(anchorViewCoord, pointerViewCoord);
1266
+ if (d < shortestDistance) {
1267
+ shortestDistance = d;
1268
+ target.push(connectable);
1269
+ this.highlightPoint = anchor.point;
1270
+ result = {
1271
+ id: connectable.id,
1272
+ position: anchor.coord,
1273
+ };
1274
+ }
1275
+ }
1276
+
1277
+ if (shortestDistance < 8 && result) break;
1278
+
1279
+ // if not, check if closes to bound
1280
+ const nearestPoint = connectable.getNearestPoint(point);
1281
+
1282
+ if (Vec.dist(nearestPoint, point) < 8) {
1283
+ this.highlightPoint = nearestPoint;
1284
+ const originPoint = getPointFromBoundsWithRotation(
1285
+ rBound(connectable, true),
1286
+ nearestPoint
1287
+ );
1288
+ this._renderer?.refresh();
1289
+ target.push(connectable);
1290
+ result = {
1291
+ id: connectable.id,
1292
+ position: Vec.clampV(bound.toRelative(originPoint), 0, 1),
1293
+ };
1294
+ }
1295
+
1296
+ if (result) continue;
1297
+
1298
+ // if not, check if in inside of the element
1299
+ if (
1300
+ connectable.includesPoint(
1301
+ point[0],
1302
+ point[1],
1303
+ {
1304
+ ignoreTransparent: false,
1305
+ },
1306
+ this.gfx.std.host
1307
+ )
1308
+ ) {
1309
+ target.push(connectable);
1310
+ result = {
1311
+ id: connectable.id,
1312
+ };
1313
+ }
1314
+ }
1315
+
1316
+ if (last(target) instanceof GroupElementModel) {
1317
+ this.targetBounds = Bound.deserialize(last(target)!.xywh);
1318
+ } else {
1319
+ this.targetBounds = null;
1320
+ }
1321
+
1322
+ // at last, if not, just return the point
1323
+ if (!result) {
1324
+ result = {
1325
+ position: point,
1326
+ };
1327
+ }
1328
+
1329
+ this._renderer?.refresh();
1330
+
1331
+ return result;
1332
+ }
1333
+ }
1334
+
1335
+ export class PathGenerator {
1336
+ protected _aStarRunner: AStarRunner | null = null;
1337
+
1338
+ protected _prepareOrthogonalConnectorInfo(
1339
+ connectorInfo: OrthogonalConnectorInput
1340
+ ): [
1341
+ IVec,
1342
+ IVec,
1343
+ IVec,
1344
+ IVec,
1345
+ Bound | null,
1346
+ Bound | null,
1347
+ Bound | null,
1348
+ Bound | null,
1349
+ ] {
1350
+ const { startBound, endBound, startPoint, endPoint } = connectorInfo;
1351
+
1352
+ const [startOffset, endOffset] = computeOffset(startBound, endBound);
1353
+ const [nextStartPoint, lastEndPoint] = computeNextStartEndpoint(
1354
+ startPoint,
1355
+ endPoint,
1356
+ startBound,
1357
+ endBound,
1358
+ startOffset,
1359
+ endOffset
1360
+ );
1361
+ const expandStartBound = startBound
1362
+ ? startBound.expand(
1363
+ startOffset[0],
1364
+ startOffset[1],
1365
+ startOffset[2],
1366
+ startOffset[3]
1367
+ )
1368
+ : null;
1369
+ const expandEndBound = endBound
1370
+ ? endBound.expand(endOffset[0], endOffset[1], endOffset[2], endOffset[3])
1371
+ : null;
1372
+
1373
+ return [
1374
+ startPoint,
1375
+ endPoint,
1376
+ nextStartPoint,
1377
+ lastEndPoint,
1378
+ startBound,
1379
+ endBound,
1380
+ expandStartBound,
1381
+ expandEndBound,
1382
+ ];
1383
+ }
1384
+
1385
+ generateOrthogonalConnectorPath(input: OrthogonalConnectorInput): IVec[] {
1386
+ const info = this._prepareOrthogonalConnectorInfo(input);
1387
+ const [startPoint, endPoint, nextStartPoint, lastEndPoint] = info;
1388
+ const [, , , , startBound, endBound, expandStartBound, expandEndBound] =
1389
+ info;
1390
+ const blocks = [];
1391
+ const expandBlocks = [];
1392
+ startBound && blocks.push(startBound.clone());
1393
+ endBound && blocks.push(endBound.clone());
1394
+ expandStartBound && expandBlocks.push(expandStartBound.clone());
1395
+ expandEndBound && expandBlocks.push(expandEndBound.clone());
1396
+
1397
+ if (
1398
+ startBound &&
1399
+ endBound &&
1400
+ startBound.isPointInBound(endPoint) &&
1401
+ endBound.isPointInBound(startPoint)
1402
+ ) {
1403
+ return getDirectPath(startPoint, endPoint);
1404
+ }
1405
+
1406
+ if (startBound && expandStartBound?.isPointInBound(endPoint, 0)) {
1407
+ return getDirectPath(startPoint, endPoint);
1408
+ }
1409
+
1410
+ if (endBound && expandEndBound?.isPointInBound(startPoint, 0)) {
1411
+ return getDirectPath(startPoint, endPoint);
1412
+ }
1413
+
1414
+ const points = computePoints(
1415
+ startPoint,
1416
+ endPoint,
1417
+ nextStartPoint,
1418
+ lastEndPoint,
1419
+ startBound,
1420
+ endBound,
1421
+ expandStartBound,
1422
+ expandEndBound
1423
+ );
1424
+ const finalPoints = points[0];
1425
+ const [, startPointV3, endPointV3, nextStartPointV3, lastEndPointV3] =
1426
+ points;
1427
+
1428
+ adjustStartEndPoint(startPointV3, endPointV3, startBound, endBound);
1429
+ this._aStarRunner = new AStarRunner(
1430
+ finalPoints,
1431
+ nextStartPointV3,
1432
+ lastEndPointV3,
1433
+ startPointV3,
1434
+ endPointV3,
1435
+ blocks,
1436
+ expandBlocks
1437
+ );
1438
+ this._aStarRunner.run();
1439
+ const path = this._aStarRunner.path;
1440
+ if (!endBound) path.pop();
1441
+ if (!startBound) path.shift();
1442
+
1443
+ return mergePath(path);
1444
+ }
1445
+ }
1446
+
1447
+ export class ConnectorPathGenerator extends PathGenerator {
1448
+ constructor(
1449
+ private readonly options: {
1450
+ getElementById: (id: string) => GfxModel | null;
1451
+ }
1452
+ ) {
1453
+ super();
1454
+ }
1455
+
1456
+ static updatePath(
1457
+ connector: ConnectorElementModel | LocalConnectorElementModel,
1458
+ path: PointLocation[] | null,
1459
+ elementGetter?: (id: string) => GfxModel | null
1460
+ ) {
1461
+ const instance = new ConnectorPathGenerator({
1462
+ getElementById: elementGetter ?? (() => null),
1463
+ });
1464
+
1465
+ const points = path ?? instance._generateConnectorPath(connector) ?? [];
1466
+ const bound =
1467
+ connector.mode === ConnectorMode.Curve
1468
+ ? getBezierCurveBoundingBox(getBezierParameters(points))
1469
+ : getBoundFromPoints(points);
1470
+ const relativePoints = points.map((p: PointLocation) => {
1471
+ return p.setVec(Vec.sub(p, [bound.x, bound.y]));
1472
+ });
1473
+
1474
+ connector.updatingPath = true;
1475
+ // the property assignment order matters
1476
+ connector.xywh = bound.serialize();
1477
+ connector.path = relativePoints;
1478
+
1479
+ // Updates Connector's Label position.
1480
+ if (isConnectorWithLabel(connector)) {
1481
+ const model = connector as ConnectorElementModel;
1482
+ const [cx, cy] = model.getPointByOffsetDistance(
1483
+ model.labelOffset.distance
1484
+ );
1485
+ const [, , w, h] = model.labelXYWH!;
1486
+ model.labelXYWH = [cx - w / 2, cy - h / 2, w, h];
1487
+ }
1488
+
1489
+ connector.updatingPath = false;
1490
+ }
1491
+
1492
+ private _computeStartEndPoint(
1493
+ connector: ConnectorElementModel | LocalConnectorElementModel
1494
+ ) {
1495
+ const { source, target } = connector;
1496
+ const start = this._getConnectorEndElement(connector, 'source');
1497
+ const end = this._getConnectorEndElement(connector, 'target');
1498
+
1499
+ let startPoint: PointLocation | null = null;
1500
+ let endPoint: PointLocation | null = null;
1501
+ if (
1502
+ source.id &&
1503
+ !source.position &&
1504
+ target.id &&
1505
+ !target.position &&
1506
+ start &&
1507
+ end
1508
+ ) {
1509
+ const startAnchors = getAnchors(start);
1510
+ const endAnchors = getAnchors(end);
1511
+ let minDist = Infinity;
1512
+ let minStartAnchor = new PointLocation();
1513
+ let minEndAnchor = new PointLocation();
1514
+ for (const sa of startAnchors) {
1515
+ for (const ea of endAnchors) {
1516
+ const dist = Vec.dist(sa.point, ea.point);
1517
+ if (dist + 0.1 < minDist) {
1518
+ minDist = dist;
1519
+ minStartAnchor = sa.point;
1520
+ minEndAnchor = ea.point;
1521
+ }
1522
+ }
1523
+ }
1524
+ startPoint = minStartAnchor;
1525
+ endPoint = minEndAnchor;
1526
+ } else {
1527
+ startPoint = this._getConnectionPoint(connector, 'source');
1528
+ endPoint = this._getConnectionPoint(connector, 'target');
1529
+ }
1530
+
1531
+ if (!startPoint || !endPoint) return [];
1532
+
1533
+ // Adjust center-anchored endpoints to perimeter
1534
+ return this._adjustCenterAnchorEndpoints(connector, startPoint, endPoint);
1535
+ }
1536
+
1537
+ private _generateConnectorPath(
1538
+ connector: ConnectorElementModel | LocalConnectorElementModel
1539
+ ) {
1540
+ const { mode } = connector;
1541
+ if (mode === ConnectorMode.Straight) {
1542
+ return this._generateStraightConnectorPath(connector);
1543
+ } else if (mode === ConnectorMode.Orthogonal) {
1544
+ const start = this._getConnectorEndElement(connector, 'source');
1545
+ const end = this._getConnectorEndElement(connector, 'target');
1546
+
1547
+ const [startPoint, endPoint] = this._computeStartEndPoint(connector);
1548
+
1549
+ const startBound = start
1550
+ ? Bound.from(getBoundWithRotation(rBound(start)))
1551
+ : null;
1552
+ const endBound = end
1553
+ ? Bound.from(getBoundWithRotation(rBound(end)))
1554
+ : null;
1555
+ const path = this.generateOrthogonalConnectorPath({
1556
+ startPoint,
1557
+ endPoint,
1558
+ startBound,
1559
+ endBound,
1560
+ });
1561
+ return path.map(p => new PointLocation(p));
1562
+ } else if (mode === ConnectorMode.Curve) {
1563
+ return this._generateCurveConnectorPath(connector);
1564
+ }
1565
+ throw new Error('unknown connector mode');
1566
+ }
1567
+
1568
+ private _generateCurveConnectorPath(
1569
+ connector: ConnectorElementModel | LocalConnectorElementModel
1570
+ ) {
1571
+ const { source, target } = connector;
1572
+ let startPoint: PointLocation | null = null;
1573
+ let endPoint: PointLocation | null = null;
1574
+
1575
+ if (source.id || target.id) {
1576
+ if (!source.position && !target.position) {
1577
+ const start = this._getConnectorEndElement(
1578
+ connector,
1579
+ 'source'
1580
+ ) as Connectable;
1581
+ const end = this._getConnectorEndElement(
1582
+ connector,
1583
+ 'target'
1584
+ ) as Connectable;
1585
+ const sb = Bound.deserialize(start.xywh);
1586
+ const eb = Bound.deserialize(end.xywh);
1587
+ startPoint = getNearestConnectableAnchor(start, eb.center);
1588
+ endPoint = getNearestConnectableAnchor(end, sb.center);
1589
+ } else {
1590
+ startPoint = this._getConnectionPoint(connector, 'source');
1591
+ endPoint = this._getConnectionPoint(connector, 'target');
1592
+ }
1593
+
1594
+ if (!startPoint || !endPoint) return [];
1595
+
1596
+ // Adjust center-anchored endpoints to perimeter before computing
1597
+ // control vectors, so tangent and position are correct
1598
+ [startPoint, endPoint] = this._adjustCenterAnchorEndpoints(
1599
+ connector,
1600
+ startPoint,
1601
+ endPoint
1602
+ );
1603
+
1604
+ if (source.id) {
1605
+ const startTangentVertical = Vec.rot(startPoint.tangent, -Math.PI / 2);
1606
+ startPoint.out = isVecZero(startTangentVertical)
1607
+ ? Vec.mul(Vec.per(Vec.normalize(Vec.sub(startPoint, endPoint))), 20)
1608
+ : Vec.mul(
1609
+ startTangentVertical,
1610
+ Math.max(
1611
+ 100,
1612
+ Math.abs(
1613
+ Vec.pry(Vec.sub(endPoint, startPoint), startTangentVertical)
1614
+ ) / 3
1615
+ )
1616
+ );
1617
+ }
1618
+ if (target.id) {
1619
+ const endTangentVertical = Vec.rot(endPoint.tangent, -Math.PI / 2);
1620
+ endPoint.in = isVecZero(endTangentVertical)
1621
+ ? Vec.mul(Vec.per(Vec.normalize(Vec.sub(endPoint, startPoint))), 20)
1622
+ : Vec.mul(
1623
+ endTangentVertical,
1624
+ Math.max(
1625
+ 100,
1626
+ Math.abs(
1627
+ Vec.pry(Vec.sub(startPoint, endPoint), endTangentVertical)
1628
+ ) / 3
1629
+ )
1630
+ );
1631
+ }
1632
+ return this._applyCurveControlPoint(connector, startPoint, endPoint);
1633
+ } else {
1634
+ startPoint = this._getConnectionPoint(connector, 'source');
1635
+ endPoint = this._getConnectionPoint(connector, 'target');
1636
+
1637
+ if (!startPoint || !endPoint) return [];
1638
+
1639
+ if (
1640
+ Math.abs(endPoint[0] - startPoint[0]) >
1641
+ Math.abs(endPoint[1] - startPoint[1])
1642
+ ) {
1643
+ startPoint.out = [Vec.mul(Vec.sub(endPoint, startPoint), 2 / 3)[0], 0];
1644
+ endPoint.in = [Vec.mul(Vec.sub(startPoint, endPoint), 2 / 3)[0], 0];
1645
+ } else {
1646
+ startPoint.out = [0, Vec.mul(Vec.sub(endPoint, startPoint), 2 / 3)[1]];
1647
+ endPoint.in = [0, Vec.mul(Vec.sub(startPoint, endPoint), 2 / 3)[1]];
1648
+ }
1649
+ return this._applyCurveControlPoint(connector, startPoint, endPoint);
1650
+ }
1651
+ }
1652
+
1653
+ /**
1654
+ * If the connector has a curveControlPoint, recalculate absIn/absOut so the
1655
+ * cubic Bézier passes exactly through the control point at t = 0.5.
1656
+ *
1657
+ * Given endpoints P0 (start) and P3 (end), and desired passthrough C:
1658
+ * P1 = (4C − P3) / 3 → startPoint.out = P1 − P0
1659
+ * P2 = (4C − P0) / 3 → endPoint.in = P2 − P3
1660
+ *
1661
+ * Proof: B(0.5) = (P0 + 3P1 + 3P2 + P3)/8
1662
+ * = (P0 + (4C−P3) + (4C−P0) + P3)/8 = 8C/8 = C ✓
1663
+ */
1664
+ private _applyCurveControlPoint(
1665
+ connector: ConnectorElementModel | LocalConnectorElementModel,
1666
+ startPoint: PointLocation,
1667
+ endPoint: PointLocation
1668
+ ): PointLocation[] {
1669
+ if (
1670
+ connector instanceof ConnectorElementModel &&
1671
+ connector.curveControlPoint
1672
+ ) {
1673
+ const C = connector.curveControlPoint;
1674
+ const P0: IVec = [startPoint[0], startPoint[1]];
1675
+ const P3: IVec = [endPoint[0], endPoint[1]];
1676
+
1677
+ // out = P1 - P0 = (4C - P3 - 3P0) / 3
1678
+ startPoint.out = Vec.div(
1679
+ Vec.sub(Vec.sub(Vec.mul(C, 4), P3), Vec.mul(P0, 3)),
1680
+ 3
1681
+ );
1682
+
1683
+ // in = P2 - P3 = (4C - P0 - 3P3) / 3
1684
+ endPoint.in = Vec.div(
1685
+ Vec.sub(Vec.sub(Vec.mul(C, 4), P0), Vec.mul(P3, 3)),
1686
+ 3
1687
+ );
1688
+ }
1689
+ return [startPoint, endPoint];
1690
+ }
1691
+
1692
+ private _generateStraightConnectorPath(
1693
+ connector: ConnectorElementModel | LocalConnectorElementModel
1694
+ ) {
1695
+ const { source, target } = connector;
1696
+ if (source.id && !source.position && target.id && !target.position) {
1697
+ const start = this._getConnectorEndElement(
1698
+ connector,
1699
+ 'source'
1700
+ ) as Connectable;
1701
+ const end = this._getConnectorEndElement(
1702
+ connector,
1703
+ 'target'
1704
+ ) as Connectable;
1705
+ const sb = Bound.deserialize(start.xywh);
1706
+ const eb = Bound.deserialize(end.xywh);
1707
+ const startPoint = getNearestConnectableAnchor(start, eb.center);
1708
+ const endPoint = getNearestConnectableAnchor(end, sb.center);
1709
+ if (!startPoint || !endPoint) return [];
1710
+ const [adjStart, adjEnd] = this._adjustCenterAnchorEndpoints(
1711
+ connector,
1712
+ startPoint,
1713
+ endPoint
1714
+ );
1715
+ return [adjStart, adjEnd];
1716
+ } else {
1717
+ const endPoint = this._getConnectionPoint(connector, 'target');
1718
+ const startPoint = this._getConnectionPoint(connector, 'source');
1719
+ if (!startPoint || !endPoint) return [];
1720
+ const [adjStart, adjEnd] = this._adjustCenterAnchorEndpoints(
1721
+ connector,
1722
+ startPoint,
1723
+ endPoint
1724
+ );
1725
+ return [adjStart, adjEnd];
1726
+ }
1727
+ }
1728
+
1729
+ /**
1730
+ * Adjusts connector endpoints so that center-anchored endpoints visually
1731
+ * terminate at the shape perimeter rather than at the center.
1732
+ *
1733
+ * For each endpoint, checks if the logical anchor is the center point
1734
+ * [0.5, 0.5] on a center-eligible shape. If so, computes the perimeter
1735
+ * intersection from the opposite endpoint toward the center, and replaces
1736
+ * the endpoint with the perimeter point.
1737
+ */
1738
+ private _adjustCenterAnchorEndpoints(
1739
+ connector: ConnectorElementModel | LocalConnectorElementModel,
1740
+ startPoint: PointLocation,
1741
+ endPoint: PointLocation
1742
+ ): [PointLocation, PointLocation] {
1743
+ const { source, target } = connector;
1744
+ const start = this._getConnectorEndElement(connector, 'source');
1745
+ const end = this._getConnectorEndElement(connector, 'target');
1746
+
1747
+ let adjustedStart = startPoint;
1748
+ let adjustedEnd = endPoint;
1749
+
1750
+ // Check if source is center-anchored
1751
+ if (start && source.id && isCenterAnchorEligible(start)) {
1752
+ const isCenter = source.position
1753
+ ? isCenterAnchorPosition(source.position, start)
1754
+ : this._isPointAtShapeCenter(start, startPoint);
1755
+ if (isCenter) {
1756
+ adjustedStart = computePerimeterPointForCenterAnchor(
1757
+ start,
1758
+ startPoint,
1759
+ endPoint
1760
+ );
1761
+ }
1762
+ }
1763
+
1764
+ // Check if target is center-anchored
1765
+ if (end && target.id && isCenterAnchorEligible(end)) {
1766
+ const isCenter = target.position
1767
+ ? isCenterAnchorPosition(target.position, end)
1768
+ : this._isPointAtShapeCenter(end, endPoint);
1769
+ if (isCenter) {
1770
+ adjustedEnd = computePerimeterPointForCenterAnchor(
1771
+ end,
1772
+ endPoint,
1773
+ // Use adjusted start if it was modified, for accurate direction
1774
+ adjustedStart
1775
+ );
1776
+ }
1777
+ }
1778
+
1779
+ return [adjustedStart, adjustedEnd];
1780
+ }
1781
+
1782
+ /**
1783
+ * Checks if a PointLocation is at the center of a shape (for detecting
1784
+ * auto-selected center anchors when no explicit position is set).
1785
+ */
1786
+ private _isPointAtShapeCenter(
1787
+ connectable: GfxModel,
1788
+ point: PointLocation
1789
+ ): boolean {
1790
+ const bound = Bound.deserialize(connectable.xywh);
1791
+ const center = getPointFromBoundsWithRotation(
1792
+ { ...bound, rotate: connectable.rotate },
1793
+ bound.center
1794
+ );
1795
+ return (
1796
+ almostEqual(point[0], center[0], 1) &&
1797
+ almostEqual(point[1], center[1], 1)
1798
+ );
1799
+ }
1800
+
1801
+ private _getConnectionPoint(
1802
+ connector: ConnectorElementModel | LocalConnectorElementModel,
1803
+ type: 'source' | 'target'
1804
+ ): PointLocation | null {
1805
+ const connection = connector[type];
1806
+
1807
+ if (!connection) return null;
1808
+
1809
+ const connectable = this._getConnectorEndElement(connector, type);
1810
+
1811
+ if (!connectable && connection.position) {
1812
+ return PointLocation.fromVec(connection.position);
1813
+ }
1814
+
1815
+ if (!connectable) return null;
1816
+
1817
+ let point: PointLocation | null = null;
1818
+
1819
+ if (connection.position) {
1820
+ point = getConnectableRelativePosition(connectable, connection.position);
1821
+ } else {
1822
+ const anotherType = type === 'source' ? 'target' : 'source';
1823
+ const otherPoint = this._getConnectionPoint(connector, anotherType);
1824
+ if (otherPoint) {
1825
+ point = getNearestConnectableAnchor(connectable, otherPoint);
1826
+ }
1827
+ }
1828
+
1829
+ return point;
1830
+ }
1831
+
1832
+ private _getConnectorEndElement(
1833
+ connector: ConnectorElementModel | LocalConnectorElementModel,
1834
+ type: 'source' | 'target'
1835
+ ): Connectable | null {
1836
+ const id = connector[type].id;
1837
+
1838
+ if (id) {
1839
+ return this.options.getElementById(id) as Connectable;
1840
+ }
1841
+
1842
+ return null;
1843
+ }
1844
+
1845
+ hasRelatedElement(
1846
+ connecter: ConnectorElementModel | LocalConnectorElementModel
1847
+ ) {
1848
+ const { source, target } = connecter;
1849
+ if (
1850
+ (source.id && !this.options.getElementById(source.id)) ||
1851
+ (target.id && !this.options.getElementById(target.id))
1852
+ ) {
1853
+ return false;
1854
+ }
1855
+
1856
+ return true;
1857
+ }
1858
+ }