@react-x11/components 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (721) hide show
  1. package/README.md +105 -38
  2. package/dist/charts/node.d.ts +12 -2
  3. package/dist/charts/node.d.ts.map +1 -1
  4. package/dist/charts/node.js +50 -16
  5. package/dist/charts/node.js.map +1 -1
  6. package/dist/charts/render.d.ts +12 -3
  7. package/dist/charts/render.d.ts.map +1 -1
  8. package/dist/charts/render.js +94 -25
  9. package/dist/charts/render.js.map +1 -1
  10. package/dist/code/index.d.ts.map +1 -1
  11. package/dist/code/index.js +3 -1
  12. package/dist/code/index.js.map +1 -1
  13. package/dist/code-editor/completion.d.ts.map +1 -1
  14. package/dist/code-editor/completion.js +3 -2
  15. package/dist/code-editor/completion.js.map +1 -1
  16. package/dist/code-editor/index.d.ts.map +1 -1
  17. package/dist/code-editor/index.js +19 -0
  18. package/dist/code-editor/index.js.map +1 -1
  19. package/dist/code-editor/node.d.ts +177 -7
  20. package/dist/code-editor/node.d.ts.map +1 -1
  21. package/dist/code-editor/node.js +1329 -164
  22. package/dist/code-editor/node.js.map +1 -1
  23. package/dist/code-language/languages/glsl.d.ts.map +1 -1
  24. package/dist/code-language/languages/glsl.js +10 -2
  25. package/dist/code-language/languages/glsl.js.map +1 -1
  26. package/dist/code-language/languages/javascript.d.ts.map +1 -1
  27. package/dist/code-language/languages/javascript.js +18 -3
  28. package/dist/code-language/languages/javascript.js.map +1 -1
  29. package/dist/code-language/languages/json.d.ts.map +1 -1
  30. package/dist/code-language/languages/json.js +10 -2
  31. package/dist/code-language/languages/json.js.map +1 -1
  32. package/dist/code-language/languages/shell.d.ts.map +1 -1
  33. package/dist/code-language/languages/shell.js +10 -2
  34. package/dist/code-language/languages/shell.js.map +1 -1
  35. package/dist/code-language/languages/sql.d.ts.map +1 -1
  36. package/dist/code-language/languages/sql.js +20 -2
  37. package/dist/code-language/languages/sql.js.map +1 -1
  38. package/dist/code-language/stream.d.ts +22 -0
  39. package/dist/code-language/stream.d.ts.map +1 -1
  40. package/dist/code-language/stream.js +259 -9
  41. package/dist/code-language/stream.js.map +1 -1
  42. package/dist/code-language/types.d.ts +5 -4
  43. package/dist/code-language/types.d.ts.map +1 -1
  44. package/dist/codeblock/index.d.ts +13 -2
  45. package/dist/codeblock/index.d.ts.map +1 -1
  46. package/dist/codeblock/index.js +20 -3
  47. package/dist/codeblock/index.js.map +1 -1
  48. package/dist/embed/client.d.ts +48 -3
  49. package/dist/embed/client.d.ts.map +1 -1
  50. package/dist/embed/client.js +79 -5
  51. package/dist/embed/client.js.map +1 -1
  52. package/dist/embed/index.d.ts +1 -1
  53. package/dist/embed/index.d.ts.map +1 -1
  54. package/dist/embed/index.js +1 -1
  55. package/dist/embed/index.js.map +1 -1
  56. package/dist/flow/draw.d.ts +50 -0
  57. package/dist/flow/draw.d.ts.map +1 -1
  58. package/dist/flow/draw.js +132 -33
  59. package/dist/flow/draw.js.map +1 -1
  60. package/dist/flow/gl/color.d.ts +13 -0
  61. package/dist/flow/gl/color.d.ts.map +1 -0
  62. package/dist/flow/gl/color.js +82 -0
  63. package/dist/flow/gl/color.js.map +1 -0
  64. package/dist/flow/gl/index.d.ts +60 -0
  65. package/dist/flow/gl/index.d.ts.map +1 -0
  66. package/dist/flow/gl/index.js +283 -0
  67. package/dist/flow/gl/index.js.map +1 -0
  68. package/dist/flow/gl/pack.d.ts +133 -0
  69. package/dist/flow/gl/pack.d.ts.map +1 -0
  70. package/dist/flow/gl/pack.js +408 -0
  71. package/dist/flow/gl/pack.js.map +1 -0
  72. package/dist/flow/gl/renderer.d.ts +95 -0
  73. package/dist/flow/gl/renderer.d.ts.map +1 -0
  74. package/dist/flow/gl/renderer.js +459 -0
  75. package/dist/flow/gl/renderer.js.map +1 -0
  76. package/dist/flow/gl/shaders.d.ts +79 -0
  77. package/dist/flow/gl/shaders.d.ts.map +1 -0
  78. package/dist/flow/gl/shaders.js +346 -0
  79. package/dist/flow/gl/shaders.js.map +1 -0
  80. package/dist/flow/gl/text.d.ts +318 -0
  81. package/dist/flow/gl/text.d.ts.map +1 -0
  82. package/dist/flow/gl/text.js +1103 -0
  83. package/dist/flow/gl/text.js.map +1 -0
  84. package/dist/flow/index.d.ts +1 -1
  85. package/dist/flow/index.d.ts.map +1 -1
  86. package/dist/flow/index.js +619 -64
  87. package/dist/flow/index.js.map +1 -1
  88. package/dist/flow/node.d.ts +621 -72
  89. package/dist/flow/node.d.ts.map +1 -1
  90. package/dist/flow/node.js +2253 -1018
  91. package/dist/flow/node.js.map +1 -1
  92. package/dist/flow/paint.d.ts +35 -0
  93. package/dist/flow/paint.d.ts.map +1 -0
  94. package/dist/flow/paint.js +393 -0
  95. package/dist/flow/paint.js.map +1 -0
  96. package/dist/flow/paths.d.ts +14 -0
  97. package/dist/flow/paths.d.ts.map +1 -1
  98. package/dist/flow/paths.js +45 -19
  99. package/dist/flow/paths.js.map +1 -1
  100. package/dist/flow/scene.d.ts +584 -0
  101. package/dist/flow/scene.d.ts.map +1 -0
  102. package/dist/flow/scene.js +1453 -0
  103. package/dist/flow/scene.js.map +1 -0
  104. package/dist/flow/types.d.ts +111 -1
  105. package/dist/flow/types.d.ts.map +1 -1
  106. package/dist/html/controls.d.ts +28 -0
  107. package/dist/html/controls.d.ts.map +1 -1
  108. package/dist/html/controls.js +52 -2
  109. package/dist/html/controls.js.map +1 -1
  110. package/dist/html/css/calc.d.ts +14 -0
  111. package/dist/html/css/calc.d.ts.map +1 -0
  112. package/dist/html/css/calc.js +344 -0
  113. package/dist/html/css/calc.js.map +1 -0
  114. package/dist/html/css/cascade.d.ts +240 -6
  115. package/dist/html/css/cascade.d.ts.map +1 -1
  116. package/dist/html/css/cascade.js +1327 -66
  117. package/dist/html/css/cascade.js.map +1 -1
  118. package/dist/html/css/color.d.ts +23 -0
  119. package/dist/html/css/color.d.ts.map +1 -0
  120. package/dist/html/css/color.js +740 -0
  121. package/dist/html/css/color.js.map +1 -0
  122. package/dist/html/css/content.d.ts +92 -0
  123. package/dist/html/css/content.d.ts.map +1 -0
  124. package/dist/html/css/content.js +388 -0
  125. package/dist/html/css/content.js.map +1 -0
  126. package/dist/html/css/counter-styles.d.ts +76 -0
  127. package/dist/html/css/counter-styles.d.ts.map +1 -0
  128. package/dist/html/css/counter-styles.js +893 -0
  129. package/dist/html/css/counter-styles.js.map +1 -0
  130. package/dist/html/css/decode.d.ts +12 -0
  131. package/dist/html/css/decode.d.ts.map +1 -0
  132. package/dist/html/css/decode.js +116 -0
  133. package/dist/html/css/decode.js.map +1 -0
  134. package/dist/html/css/parse.d.ts +110 -10
  135. package/dist/html/css/parse.d.ts.map +1 -1
  136. package/dist/html/css/parse.js +1473 -180
  137. package/dist/html/css/parse.js.map +1 -1
  138. package/dist/html/css/style.d.ts +498 -15
  139. package/dist/html/css/style.d.ts.map +1 -1
  140. package/dist/html/css/style.js +3698 -206
  141. package/dist/html/css/style.js.map +1 -1
  142. package/dist/html/css/ua.d.ts.map +1 -1
  143. package/dist/html/css/ua.js +57 -11
  144. package/dist/html/css/ua.js.map +1 -1
  145. package/dist/html/css/values.d.ts +37 -3
  146. package/dist/html/css/values.d.ts.map +1 -1
  147. package/dist/html/css/values.js +122 -48
  148. package/dist/html/css/values.js.map +1 -1
  149. package/dist/html/css/vars.d.ts +52 -0
  150. package/dist/html/css/vars.d.ts.map +1 -0
  151. package/dist/html/css/vars.js +358 -0
  152. package/dist/html/css/vars.js.map +1 -0
  153. package/dist/html/dom.d.ts +30 -4
  154. package/dist/html/dom.d.ts.map +1 -1
  155. package/dist/html/dom.js +278 -17
  156. package/dist/html/dom.js.map +1 -1
  157. package/dist/html/fonts.d.ts +106 -0
  158. package/dist/html/fonts.d.ts.map +1 -0
  159. package/dist/html/fonts.js +565 -0
  160. package/dist/html/fonts.js.map +1 -0
  161. package/dist/html/gif.d.ts +15 -0
  162. package/dist/html/gif.d.ts.map +1 -0
  163. package/dist/html/gif.js +229 -0
  164. package/dist/html/gif.js.map +1 -0
  165. package/dist/html/index.d.ts +50 -11
  166. package/dist/html/index.d.ts.map +1 -1
  167. package/dist/html/index.js +115 -9
  168. package/dist/html/index.js.map +1 -1
  169. package/dist/html/layout/block.d.ts +226 -3
  170. package/dist/html/layout/block.d.ts.map +1 -1
  171. package/dist/html/layout/block.js +2937 -197
  172. package/dist/html/layout/block.js.map +1 -1
  173. package/dist/html/layout/boxes.d.ts +340 -17
  174. package/dist/html/layout/boxes.d.ts.map +1 -1
  175. package/dist/html/layout/boxes.js +1714 -182
  176. package/dist/html/layout/boxes.js.map +1 -1
  177. package/dist/html/layout/cache.d.ts +58 -0
  178. package/dist/html/layout/cache.d.ts.map +1 -0
  179. package/dist/html/layout/cache.js +224 -0
  180. package/dist/html/layout/cache.js.map +1 -0
  181. package/dist/html/layout/collapse.d.ts +45 -0
  182. package/dist/html/layout/collapse.d.ts.map +1 -0
  183. package/dist/html/layout/collapse.js +246 -0
  184. package/dist/html/layout/collapse.js.map +1 -0
  185. package/dist/html/layout/css-grid.d.ts +7 -0
  186. package/dist/html/layout/css-grid.d.ts.map +1 -0
  187. package/dist/html/layout/css-grid.js +900 -0
  188. package/dist/html/layout/css-grid.js.map +1 -0
  189. package/dist/html/layout/flex.d.ts.map +1 -1
  190. package/dist/html/layout/flex.js +1025 -89
  191. package/dist/html/layout/flex.js.map +1 -1
  192. package/dist/html/layout/floats.d.ts +45 -6
  193. package/dist/html/layout/floats.d.ts.map +1 -1
  194. package/dist/html/layout/floats.js +113 -14
  195. package/dist/html/layout/floats.js.map +1 -1
  196. package/dist/html/layout/grid-lines.d.ts +39 -0
  197. package/dist/html/layout/grid-lines.d.ts.map +1 -0
  198. package/dist/html/layout/grid-lines.js +119 -0
  199. package/dist/html/layout/grid-lines.js.map +1 -0
  200. package/dist/html/layout/grid.d.ts +53 -0
  201. package/dist/html/layout/grid.d.ts.map +1 -0
  202. package/dist/html/layout/grid.js +153 -0
  203. package/dist/html/layout/grid.js.map +1 -0
  204. package/dist/html/layout/inline.d.ts +151 -1
  205. package/dist/html/layout/inline.d.ts.map +1 -1
  206. package/dist/html/layout/inline.js +3375 -174
  207. package/dist/html/layout/inline.js.map +1 -1
  208. package/dist/html/layout/shaping.d.ts +6 -0
  209. package/dist/html/layout/shaping.d.ts.map +1 -0
  210. package/dist/html/layout/shaping.js +100 -0
  211. package/dist/html/layout/shaping.js.map +1 -0
  212. package/dist/html/layout/table.d.ts +3 -0
  213. package/dist/html/layout/table.d.ts.map +1 -1
  214. package/dist/html/layout/table.js +681 -175
  215. package/dist/html/layout/table.js.map +1 -1
  216. package/dist/html/layout/tracks.d.ts +44 -0
  217. package/dist/html/layout/tracks.d.ts.map +1 -0
  218. package/dist/html/layout/tracks.js +349 -0
  219. package/dist/html/layout/tracks.js.map +1 -0
  220. package/dist/html/node.d.ts +172 -5
  221. package/dist/html/node.d.ts.map +1 -1
  222. package/dist/html/node.js +1336 -103
  223. package/dist/html/node.js.map +1 -1
  224. package/dist/html/paint.d.ts +92 -3
  225. package/dist/html/paint.d.ts.map +1 -1
  226. package/dist/html/paint.js +3503 -141
  227. package/dist/html/paint.js.map +1 -1
  228. package/dist/html/resources.d.ts +60 -14
  229. package/dist/html/resources.d.ts.map +1 -1
  230. package/dist/html/resources.js +122 -36
  231. package/dist/html/resources.js.map +1 -1
  232. package/dist/html/surfaces.d.ts +23 -0
  233. package/dist/html/surfaces.d.ts.map +1 -0
  234. package/dist/html/surfaces.js +68 -0
  235. package/dist/html/surfaces.js.map +1 -0
  236. package/dist/html/svg.d.ts +80 -0
  237. package/dist/html/svg.d.ts.map +1 -0
  238. package/dist/html/svg.js +435 -0
  239. package/dist/html/svg.js.map +1 -0
  240. package/dist/html/url.d.ts +23 -0
  241. package/dist/html/url.d.ts.map +1 -0
  242. package/dist/html/url.js +80 -0
  243. package/dist/html/url.js.map +1 -0
  244. package/dist/index.d.ts +2 -2
  245. package/dist/index.d.ts.map +1 -1
  246. package/dist/index.js +1 -1
  247. package/dist/index.js.map +1 -1
  248. package/dist/internal/collate.d.ts +3 -0
  249. package/dist/internal/collate.d.ts.map +1 -0
  250. package/dist/internal/collate.js +11 -0
  251. package/dist/internal/collate.js.map +1 -0
  252. package/dist/{markdown → internal/markdown}/ast.d.ts +23 -0
  253. package/dist/internal/markdown/ast.d.ts.map +1 -0
  254. package/dist/internal/markdown/ast.js +22 -0
  255. package/dist/internal/markdown/ast.js.map +1 -0
  256. package/dist/internal/markdown/parse.d.ts.map +1 -0
  257. package/dist/{markdown → internal/markdown}/parse.js +221 -30
  258. package/dist/internal/markdown/parse.js.map +1 -0
  259. package/dist/internal/markdown/stringify.d.ts +4 -0
  260. package/dist/internal/markdown/stringify.d.ts.map +1 -0
  261. package/dist/internal/markdown/stringify.js +684 -0
  262. package/dist/internal/markdown/stringify.js.map +1 -0
  263. package/dist/internal/markdown/tags.d.ts.map +1 -0
  264. package/dist/internal/markdown/tags.js.map +1 -0
  265. package/dist/internal/prewarm.d.ts +18 -0
  266. package/dist/internal/prewarm.d.ts.map +1 -0
  267. package/dist/internal/prewarm.js +42 -0
  268. package/dist/internal/prewarm.js.map +1 -0
  269. package/dist/internal/scroll.d.ts +3 -2
  270. package/dist/internal/scroll.d.ts.map +1 -1
  271. package/dist/internal/scroll.js +1 -0
  272. package/dist/internal/scroll.js.map +1 -1
  273. package/dist/internal/sdf.d.ts +20 -0
  274. package/dist/internal/sdf.d.ts.map +1 -0
  275. package/dist/internal/sdf.js +216 -0
  276. package/dist/internal/sdf.js.map +1 -0
  277. package/dist/internal/splice.d.ts +12 -0
  278. package/dist/internal/splice.d.ts.map +1 -0
  279. package/dist/internal/splice.js +23 -0
  280. package/dist/internal/splice.js.map +1 -0
  281. package/dist/internal/window.d.ts +12 -0
  282. package/dist/internal/window.d.ts.map +1 -1
  283. package/dist/internal/window.js +23 -6
  284. package/dist/internal/window.js.map +1 -1
  285. package/dist/maps/anchors.d.ts +103 -0
  286. package/dist/maps/anchors.d.ts.map +1 -0
  287. package/dist/maps/anchors.js +790 -0
  288. package/dist/maps/anchors.js.map +1 -0
  289. package/dist/maps/controller.d.ts +340 -0
  290. package/dist/maps/controller.d.ts.map +1 -0
  291. package/dist/maps/controller.js +822 -0
  292. package/dist/maps/controller.js.map +1 -0
  293. package/dist/maps/gl/buckets.d.ts +99 -0
  294. package/dist/maps/gl/buckets.d.ts.map +1 -0
  295. package/dist/maps/gl/buckets.js +365 -0
  296. package/dist/maps/gl/buckets.js.map +1 -0
  297. package/dist/maps/gl/build-worker.d.ts +15 -0
  298. package/dist/maps/gl/build-worker.d.ts.map +1 -0
  299. package/dist/maps/gl/build-worker.js +44 -0
  300. package/dist/maps/gl/build-worker.js.map +1 -0
  301. package/dist/maps/gl/color.d.ts +8 -0
  302. package/dist/maps/gl/color.d.ts.map +1 -0
  303. package/dist/maps/gl/color.js +57 -0
  304. package/dist/maps/gl/color.js.map +1 -0
  305. package/dist/maps/gl/cover.d.ts +70 -0
  306. package/dist/maps/gl/cover.d.ts.map +1 -0
  307. package/dist/maps/gl/cover.js +137 -0
  308. package/dist/maps/gl/cover.js.map +1 -0
  309. package/dist/maps/gl/index.d.ts +3 -0
  310. package/dist/maps/gl/index.d.ts.map +1 -0
  311. package/dist/maps/gl/index.js +20 -0
  312. package/dist/maps/gl/index.js.map +1 -0
  313. package/dist/maps/gl/markers.d.ts +28 -0
  314. package/dist/maps/gl/markers.d.ts.map +1 -0
  315. package/dist/maps/gl/markers.js +60 -0
  316. package/dist/maps/gl/markers.js.map +1 -0
  317. package/dist/maps/gl/overlays.d.ts +68 -0
  318. package/dist/maps/gl/overlays.d.ts.map +1 -0
  319. package/dist/maps/gl/overlays.js +300 -0
  320. package/dist/maps/gl/overlays.js.map +1 -0
  321. package/dist/maps/gl/pane.d.ts +12 -0
  322. package/dist/maps/gl/pane.d.ts.map +1 -0
  323. package/dist/maps/gl/pane.js +37 -0
  324. package/dist/maps/gl/pane.js.map +1 -0
  325. package/dist/maps/gl/placement.d.ts +124 -0
  326. package/dist/maps/gl/placement.d.ts.map +1 -0
  327. package/dist/maps/gl/placement.js +642 -0
  328. package/dist/maps/gl/placement.js.map +1 -0
  329. package/dist/maps/gl/renderer.d.ts +384 -0
  330. package/dist/maps/gl/renderer.d.ts.map +1 -0
  331. package/dist/maps/gl/renderer.js +1184 -0
  332. package/dist/maps/gl/renderer.js.map +1 -0
  333. package/dist/maps/gl/shaders.d.ts +121 -0
  334. package/dist/maps/gl/shaders.d.ts.map +1 -0
  335. package/dist/maps/gl/shaders.js +453 -0
  336. package/dist/maps/gl/shaders.js.map +1 -0
  337. package/dist/maps/gl/store.d.ts +125 -0
  338. package/dist/maps/gl/store.d.ts.map +1 -0
  339. package/dist/maps/gl/store.js +512 -0
  340. package/dist/maps/gl/store.js.map +1 -0
  341. package/dist/maps/gl/text.d.ts +283 -0
  342. package/dist/maps/gl/text.d.ts.map +1 -0
  343. package/dist/maps/gl/text.js +698 -0
  344. package/dist/maps/gl/text.js.map +1 -0
  345. package/dist/maps/gl/view.d.ts +345 -0
  346. package/dist/maps/gl/view.d.ts.map +1 -0
  347. package/dist/maps/gl/view.js +1209 -0
  348. package/dist/maps/gl/view.js.map +1 -0
  349. package/dist/maps/icons.d.ts +32 -0
  350. package/dist/maps/icons.d.ts.map +1 -0
  351. package/dist/maps/icons.js +151 -0
  352. package/dist/maps/icons.js.map +1 -0
  353. package/dist/maps/index.d.ts +3 -1
  354. package/dist/maps/index.d.ts.map +1 -1
  355. package/dist/maps/index.js +218 -52
  356. package/dist/maps/index.js.map +1 -1
  357. package/dist/maps/labels.d.ts +91 -18
  358. package/dist/maps/labels.d.ts.map +1 -1
  359. package/dist/maps/labels.js +376 -140
  360. package/dist/maps/labels.js.map +1 -1
  361. package/dist/maps/node.d.ts +179 -56
  362. package/dist/maps/node.d.ts.map +1 -1
  363. package/dist/maps/node.js +663 -537
  364. package/dist/maps/node.js.map +1 -1
  365. package/dist/maps/overlay.d.ts +72 -9
  366. package/dist/maps/overlay.d.ts.map +1 -1
  367. package/dist/maps/overlay.js +108 -28
  368. package/dist/maps/overlay.js.map +1 -1
  369. package/dist/maps/paint.d.ts +3 -0
  370. package/dist/maps/paint.d.ts.map +1 -1
  371. package/dist/maps/paint.js.map +1 -1
  372. package/dist/maps/proj.d.ts +62 -0
  373. package/dist/maps/proj.d.ts.map +1 -1
  374. package/dist/maps/proj.js +101 -0
  375. package/dist/maps/proj.js.map +1 -1
  376. package/dist/maps/renderer.d.ts +69 -0
  377. package/dist/maps/renderer.d.ts.map +1 -0
  378. package/dist/maps/renderer.js +66 -0
  379. package/dist/maps/renderer.js.map +1 -0
  380. package/dist/maps/sources.d.ts +30 -6
  381. package/dist/maps/sources.d.ts.map +1 -1
  382. package/dist/maps/sources.js +22 -3
  383. package/dist/maps/sources.js.map +1 -1
  384. package/dist/maps/style.d.ts +35 -0
  385. package/dist/maps/style.d.ts.map +1 -1
  386. package/dist/maps/style.js.map +1 -1
  387. package/dist/maps/styles.d.ts +12 -0
  388. package/dist/maps/styles.d.ts.map +1 -1
  389. package/dist/maps/styles.js +120 -6
  390. package/dist/maps/styles.js.map +1 -1
  391. package/dist/maps/theme.d.ts +19 -0
  392. package/dist/maps/theme.d.ts.map +1 -0
  393. package/dist/maps/theme.js +44 -0
  394. package/dist/maps/theme.js.map +1 -0
  395. package/dist/maps/tiles.d.ts +147 -27
  396. package/dist/maps/tiles.d.ts.map +1 -1
  397. package/dist/maps/tiles.js +221 -54
  398. package/dist/maps/tiles.js.map +1 -1
  399. package/dist/maps/types.d.ts +213 -21
  400. package/dist/maps/types.d.ts.map +1 -1
  401. package/dist/markdown/expressions.d.ts +1 -1
  402. package/dist/markdown/expressions.d.ts.map +1 -1
  403. package/dist/markdown/expressions.js.map +1 -1
  404. package/dist/markdown/index.d.ts +7 -6
  405. package/dist/markdown/index.d.ts.map +1 -1
  406. package/dist/markdown/index.js +121 -50
  407. package/dist/markdown/index.js.map +1 -1
  408. package/dist/markdown/spans.d.ts +1 -1
  409. package/dist/markdown/spans.d.ts.map +1 -1
  410. package/dist/markdown/spans.js +6 -0
  411. package/dist/markdown/spans.js.map +1 -1
  412. package/dist/media-player/index.d.ts +11 -3
  413. package/dist/media-player/index.d.ts.map +1 -1
  414. package/dist/media-player/index.js +13 -2
  415. package/dist/media-player/index.js.map +1 -1
  416. package/dist/qml/containers.d.ts.map +1 -1
  417. package/dist/qml/containers.js +6 -1
  418. package/dist/qml/containers.js.map +1 -1
  419. package/dist/qml/interaction.d.ts.map +1 -1
  420. package/dist/qml/interaction.js +38 -5
  421. package/dist/qml/interaction.js.map +1 -1
  422. package/dist/qml/layouts.d.ts.map +1 -1
  423. package/dist/qml/layouts.js +21 -6
  424. package/dist/qml/layouts.js.map +1 -1
  425. package/dist/qml/qtquick.d.ts.map +1 -1
  426. package/dist/qml/qtquick.js +9 -2
  427. package/dist/qml/qtquick.js.map +1 -1
  428. package/dist/qml/react.d.ts.map +1 -1
  429. package/dist/qml/react.js +9 -7
  430. package/dist/qml/react.js.map +1 -1
  431. package/dist/reorder/clock.d.ts +7 -0
  432. package/dist/reorder/clock.d.ts.map +1 -0
  433. package/dist/reorder/clock.js +26 -0
  434. package/dist/reorder/clock.js.map +1 -0
  435. package/dist/reorder/index.d.ts +25 -3
  436. package/dist/reorder/index.d.ts.map +1 -1
  437. package/dist/reorder/index.js +64 -19
  438. package/dist/reorder/index.js.map +1 -1
  439. package/dist/rich-text-editor/clipboard.d.ts +23 -0
  440. package/dist/rich-text-editor/clipboard.d.ts.map +1 -0
  441. package/dist/rich-text-editor/clipboard.js +307 -0
  442. package/dist/rich-text-editor/clipboard.js.map +1 -0
  443. package/dist/rich-text-editor/collab.d.ts +32 -0
  444. package/dist/rich-text-editor/collab.d.ts.map +1 -0
  445. package/dist/rich-text-editor/collab.js +55 -0
  446. package/dist/rich-text-editor/collab.js.map +1 -0
  447. package/dist/rich-text-editor/commands.d.ts +50 -0
  448. package/dist/rich-text-editor/commands.d.ts.map +1 -0
  449. package/dist/rich-text-editor/commands.js +376 -0
  450. package/dist/rich-text-editor/commands.js.map +1 -0
  451. package/dist/rich-text-editor/drag.d.ts +68 -0
  452. package/dist/rich-text-editor/drag.d.ts.map +1 -0
  453. package/dist/rich-text-editor/drag.js +148 -0
  454. package/dist/rich-text-editor/drag.js.map +1 -0
  455. package/dist/rich-text-editor/html.d.ts +145 -0
  456. package/dist/rich-text-editor/html.d.ts.map +1 -0
  457. package/dist/rich-text-editor/html.js +516 -0
  458. package/dist/rich-text-editor/html.js.map +1 -0
  459. package/dist/rich-text-editor/index.d.ts +252 -0
  460. package/dist/rich-text-editor/index.d.ts.map +1 -0
  461. package/dist/rich-text-editor/index.js +856 -0
  462. package/dist/rich-text-editor/index.js.map +1 -0
  463. package/dist/rich-text-editor/inline.d.ts +94 -0
  464. package/dist/rich-text-editor/inline.d.ts.map +1 -0
  465. package/dist/rich-text-editor/inline.js +252 -0
  466. package/dist/rich-text-editor/inline.js.map +1 -0
  467. package/dist/rich-text-editor/keymap.d.ts +71 -0
  468. package/dist/rich-text-editor/keymap.d.ts.map +1 -0
  469. package/dist/rich-text-editor/keymap.js +394 -0
  470. package/dist/rich-text-editor/keymap.js.map +1 -0
  471. package/dist/rich-text-editor/keys.d.ts +40 -0
  472. package/dist/rich-text-editor/keys.d.ts.map +1 -0
  473. package/dist/rich-text-editor/keys.js +202 -0
  474. package/dist/rich-text-editor/keys.js.map +1 -0
  475. package/dist/rich-text-editor/look.d.ts +71 -0
  476. package/dist/rich-text-editor/look.d.ts.map +1 -0
  477. package/dist/rich-text-editor/look.js +342 -0
  478. package/dist/rich-text-editor/look.js.map +1 -0
  479. package/dist/rich-text-editor/markdown.d.ts +18 -0
  480. package/dist/rich-text-editor/markdown.d.ts.map +1 -0
  481. package/dist/rich-text-editor/markdown.js +496 -0
  482. package/dist/rich-text-editor/markdown.js.map +1 -0
  483. package/dist/rich-text-editor/marks.d.ts +9 -0
  484. package/dist/rich-text-editor/marks.d.ts.map +1 -0
  485. package/dist/rich-text-editor/marks.js +83 -0
  486. package/dist/rich-text-editor/marks.js.map +1 -0
  487. package/dist/rich-text-editor/nodes.d.ts +135 -0
  488. package/dist/rich-text-editor/nodes.d.ts.map +1 -0
  489. package/dist/rich-text-editor/nodes.js +397 -0
  490. package/dist/rich-text-editor/nodes.js.map +1 -0
  491. package/dist/rich-text-editor/render.d.ts +68 -0
  492. package/dist/rich-text-editor/render.d.ts.map +1 -0
  493. package/dist/rich-text-editor/render.js +518 -0
  494. package/dist/rich-text-editor/render.js.map +1 -0
  495. package/dist/rich-text-editor/schema.d.ts +16 -0
  496. package/dist/rich-text-editor/schema.d.ts.map +1 -0
  497. package/dist/rich-text-editor/schema.js +386 -0
  498. package/dist/rich-text-editor/schema.js.map +1 -0
  499. package/dist/rich-text-editor/store.d.ts +11 -0
  500. package/dist/rich-text-editor/store.d.ts.map +1 -0
  501. package/dist/rich-text-editor/store.js +43 -0
  502. package/dist/rich-text-editor/store.js.map +1 -0
  503. package/dist/rich-text-editor/suggest.d.ts +127 -0
  504. package/dist/rich-text-editor/suggest.d.ts.map +1 -0
  505. package/dist/rich-text-editor/suggest.js +0 -0
  506. package/dist/rich-text-editor/suggest.js.map +1 -0
  507. package/dist/rich-text-editor/tables.d.ts +41 -0
  508. package/dist/rich-text-editor/tables.d.ts.map +1 -0
  509. package/dist/rich-text-editor/tables.js +204 -0
  510. package/dist/rich-text-editor/tables.js.map +1 -0
  511. package/dist/rich-text-editor/toolbar.d.ts +58 -0
  512. package/dist/rich-text-editor/toolbar.d.ts.map +1 -0
  513. package/dist/rich-text-editor/toolbar.js +548 -0
  514. package/dist/rich-text-editor/toolbar.js.map +1 -0
  515. package/dist/rich-text-editor/view.d.ts +368 -0
  516. package/dist/rich-text-editor/view.d.ts.map +1 -0
  517. package/dist/rich-text-editor/view.js +1968 -0
  518. package/dist/rich-text-editor/view.js.map +1 -0
  519. package/dist/rich-text-editor/virtual.d.ts +54 -0
  520. package/dist/rich-text-editor/virtual.d.ts.map +1 -0
  521. package/dist/rich-text-editor/virtual.js +279 -0
  522. package/dist/rich-text-editor/virtual.js.map +1 -0
  523. package/dist/richtext/node.d.ts +71 -4
  524. package/dist/richtext/node.d.ts.map +1 -1
  525. package/dist/richtext/node.js +233 -28
  526. package/dist/richtext/node.js.map +1 -1
  527. package/dist/richtext/runs.d.ts +13 -8
  528. package/dist/richtext/runs.d.ts.map +1 -1
  529. package/dist/richtext/runs.js +18 -8
  530. package/dist/richtext/runs.js.map +1 -1
  531. package/dist/table/index.d.ts.map +1 -1
  532. package/dist/table/index.js +23 -0
  533. package/dist/table/index.js.map +1 -1
  534. package/dist/table/rows.d.ts +3 -2
  535. package/dist/table/rows.d.ts.map +1 -1
  536. package/dist/table/rows.js +20 -6
  537. package/dist/table/rows.js.map +1 -1
  538. package/dist/terminal/backends.d.ts +4 -1
  539. package/dist/terminal/backends.d.ts.map +1 -1
  540. package/dist/terminal/backends.js.map +1 -1
  541. package/dist/terminal/index.d.ts +18 -7
  542. package/dist/terminal/index.d.ts.map +1 -1
  543. package/dist/terminal/index.js +32 -11
  544. package/dist/terminal/index.js.map +1 -1
  545. package/dist/terminal/vt/pty.d.ts +13 -2
  546. package/dist/terminal/vt/pty.d.ts.map +1 -1
  547. package/dist/terminal/vt/pty.js +18 -3
  548. package/dist/terminal/vt/pty.js.map +1 -1
  549. package/dist/terminal-output/index.d.ts.map +1 -1
  550. package/dist/terminal-output/index.js +6 -1
  551. package/dist/terminal-output/index.js.map +1 -1
  552. package/dist/three/canvas.d.ts.map +1 -1
  553. package/dist/three/canvas.js +85 -7
  554. package/dist/three/canvas.js.map +1 -1
  555. package/dist/three/events.d.ts +22 -4
  556. package/dist/three/events.d.ts.map +1 -1
  557. package/dist/three/events.js +34 -4
  558. package/dist/three/events.js.map +1 -1
  559. package/dist/tree/index.d.ts.map +1 -1
  560. package/dist/tree/index.js +17 -0
  561. package/dist/tree/index.js.map +1 -1
  562. package/package.json +59 -31
  563. package/src/charts/node.ts +68 -28
  564. package/src/charts/render.ts +120 -30
  565. package/src/code/index.ts +3 -1
  566. package/src/code-editor/completion.ts +3 -2
  567. package/src/code-editor/index.ts +19 -0
  568. package/src/code-editor/node.ts +1574 -184
  569. package/src/code-language/languages/glsl.ts +12 -2
  570. package/src/code-language/languages/javascript.ts +21 -4
  571. package/src/code-language/languages/json.ts +12 -2
  572. package/src/code-language/languages/shell.ts +12 -2
  573. package/src/code-language/languages/sql.ts +22 -2
  574. package/src/code-language/stream.ts +257 -17
  575. package/src/code-language/types.ts +5 -4
  576. package/src/codeblock/index.ts +20 -3
  577. package/src/embed/client.ts +102 -8
  578. package/src/embed/index.ts +2 -0
  579. package/src/flow/draw.ts +167 -41
  580. package/src/flow/gl/color.ts +85 -0
  581. package/src/flow/gl/index.ts +342 -0
  582. package/src/flow/gl/pack.ts +585 -0
  583. package/src/flow/gl/renderer.ts +679 -0
  584. package/src/flow/gl/shaders.ts +371 -0
  585. package/src/flow/gl/text.ts +1295 -0
  586. package/src/flow/index.ts +794 -67
  587. package/src/flow/node.ts +2496 -1256
  588. package/src/flow/paint.ts +511 -0
  589. package/src/flow/paths.ts +80 -15
  590. package/src/flow/scene.ts +2199 -0
  591. package/src/flow/types.ts +113 -1
  592. package/src/html/controls.ts +73 -2
  593. package/src/html/css/calc.ts +385 -0
  594. package/src/html/css/cascade.ts +1403 -62
  595. package/src/html/css/color.ts +755 -0
  596. package/src/html/css/content.ts +417 -0
  597. package/src/html/css/counter-styles.ts +973 -0
  598. package/src/html/css/decode.ts +130 -0
  599. package/src/html/css/parse.ts +1514 -160
  600. package/src/html/css/style.ts +4102 -222
  601. package/src/html/css/ua.ts +58 -12
  602. package/src/html/css/values.ts +150 -50
  603. package/src/html/css/vars.ts +348 -0
  604. package/src/html/dom.ts +284 -17
  605. package/src/html/fonts.ts +641 -0
  606. package/src/html/gif.ts +233 -0
  607. package/src/html/index.ts +180 -20
  608. package/src/html/layout/block.ts +3456 -230
  609. package/src/html/layout/boxes.ts +2100 -190
  610. package/src/html/layout/cache.ts +289 -0
  611. package/src/html/layout/collapse.ts +317 -0
  612. package/src/html/layout/css-grid.ts +1063 -0
  613. package/src/html/layout/flex.ts +1115 -106
  614. package/src/html/layout/floats.ts +128 -14
  615. package/src/html/layout/grid-lines.ts +141 -0
  616. package/src/html/layout/grid.ts +181 -0
  617. package/src/html/layout/inline.ts +3943 -192
  618. package/src/html/layout/shaping.ts +140 -0
  619. package/src/html/layout/table.ts +696 -186
  620. package/src/html/layout/tracks.ts +437 -0
  621. package/src/html/node.ts +1486 -121
  622. package/src/html/paint.ts +4293 -169
  623. package/src/html/resources.ts +161 -50
  624. package/src/html/surfaces.ts +81 -0
  625. package/src/html/svg.ts +493 -0
  626. package/src/html/url.ts +86 -0
  627. package/src/index.ts +4 -0
  628. package/src/internal/collate.ts +12 -0
  629. package/src/{markdown → internal/markdown}/ast.ts +35 -7
  630. package/src/{markdown → internal/markdown}/parse.ts +288 -35
  631. package/src/internal/markdown/stringify.ts +772 -0
  632. package/src/internal/prewarm.ts +45 -0
  633. package/src/internal/scroll.ts +5 -3
  634. package/src/internal/sdf.ts +227 -0
  635. package/src/internal/splice.ts +25 -0
  636. package/src/internal/window.ts +36 -5
  637. package/src/maps/anchors.ts +913 -0
  638. package/src/maps/controller.ts +1084 -0
  639. package/src/maps/gl/buckets.ts +461 -0
  640. package/src/maps/gl/build-worker.ts +66 -0
  641. package/src/maps/gl/color.ts +62 -0
  642. package/src/maps/gl/cover.ts +205 -0
  643. package/src/maps/gl/index.ts +23 -0
  644. package/src/maps/gl/markers.ts +83 -0
  645. package/src/maps/gl/overlays.ts +379 -0
  646. package/src/maps/gl/pane.ts +42 -0
  647. package/src/maps/gl/placement.ts +968 -0
  648. package/src/maps/gl/renderer.ts +1660 -0
  649. package/src/maps/gl/shaders.ts +489 -0
  650. package/src/maps/gl/store.ts +615 -0
  651. package/src/maps/gl/text.ts +868 -0
  652. package/src/maps/gl/view.ts +1489 -0
  653. package/src/maps/icons.ts +183 -0
  654. package/src/maps/index.ts +274 -81
  655. package/src/maps/labels.ts +457 -144
  656. package/src/maps/node.ts +832 -665
  657. package/src/maps/overlay.ts +148 -43
  658. package/src/maps/paint.ts +3 -0
  659. package/src/maps/proj.ts +118 -0
  660. package/src/maps/renderer.ts +155 -0
  661. package/src/maps/sources.ts +43 -6
  662. package/src/maps/style.ts +32 -0
  663. package/src/maps/styles.ts +215 -4
  664. package/src/maps/theme.ts +51 -0
  665. package/src/maps/tiles.ts +253 -62
  666. package/src/maps/types.ts +213 -21
  667. package/src/markdown/expressions.ts +5 -1
  668. package/src/markdown/index.ts +163 -78
  669. package/src/markdown/spans.ts +6 -1
  670. package/src/media-player/index.ts +18 -4
  671. package/src/qml/containers.tsx +6 -1
  672. package/src/qml/interaction.tsx +42 -5
  673. package/src/qml/layouts.tsx +21 -6
  674. package/src/qml/qtquick.tsx +9 -2
  675. package/src/qml/react.tsx +7 -5
  676. package/src/reorder/clock.ts +27 -0
  677. package/src/reorder/index.ts +100 -27
  678. package/src/rich-text-editor/clipboard.ts +439 -0
  679. package/src/rich-text-editor/collab.ts +91 -0
  680. package/src/rich-text-editor/commands.ts +448 -0
  681. package/src/rich-text-editor/dom-globals.d.ts +23 -0
  682. package/src/rich-text-editor/drag.ts +211 -0
  683. package/src/rich-text-editor/html.ts +619 -0
  684. package/src/rich-text-editor/index.ts +1364 -0
  685. package/src/rich-text-editor/inline.ts +345 -0
  686. package/src/rich-text-editor/keymap.ts +510 -0
  687. package/src/rich-text-editor/keys.ts +228 -0
  688. package/src/rich-text-editor/look.ts +427 -0
  689. package/src/rich-text-editor/markdown.ts +653 -0
  690. package/src/rich-text-editor/marks.ts +101 -0
  691. package/src/rich-text-editor/nodes.ts +497 -0
  692. package/src/rich-text-editor/render.ts +837 -0
  693. package/src/rich-text-editor/schema.ts +431 -0
  694. package/src/rich-text-editor/store.ts +39 -0
  695. package/src/rich-text-editor/suggest.ts +597 -0
  696. package/src/rich-text-editor/tables.ts +272 -0
  697. package/src/rich-text-editor/toolbar.ts +724 -0
  698. package/src/rich-text-editor/view.ts +2287 -0
  699. package/src/rich-text-editor/virtual.ts +372 -0
  700. package/src/richtext/node.ts +294 -44
  701. package/src/richtext/runs.ts +23 -12
  702. package/src/table/index.ts +29 -0
  703. package/src/table/rows.ts +18 -8
  704. package/src/terminal/backends.ts +4 -1
  705. package/src/terminal/index.ts +47 -15
  706. package/src/terminal/vt/pty.ts +16 -2
  707. package/src/terminal-output/index.ts +6 -1
  708. package/src/three/canvas.ts +102 -8
  709. package/src/three/events.ts +49 -9
  710. package/src/tree/index.ts +19 -0
  711. package/dist/markdown/ast.d.ts.map +0 -1
  712. package/dist/markdown/ast.js +0 -17
  713. package/dist/markdown/ast.js.map +0 -1
  714. package/dist/markdown/parse.d.ts.map +0 -1
  715. package/dist/markdown/parse.js.map +0 -1
  716. package/dist/markdown/tags.d.ts.map +0 -1
  717. package/dist/markdown/tags.js.map +0 -1
  718. /package/dist/{markdown → internal/markdown}/parse.d.ts +0 -0
  719. /package/dist/{markdown → internal/markdown}/tags.d.ts +0 -0
  720. /package/dist/{markdown → internal/markdown}/tags.js +0 -0
  721. /package/src/{markdown → internal/markdown}/tags.ts +0 -0
@@ -0,0 +1,913 @@
1
+ // Where in a tile a label *could* go, worked out once per tile and never per
2
+ // frame — and by both renderers: the GL renderer with a tile's buckets, on
3
+ // its build workers (`./gl/buckets.ts`), and the retained renderer when it
4
+ // collects a tile's candidates (`./labels.ts`). One answer, so a map names
5
+ // the same streets in the same places whichever of them draws it.
6
+ //
7
+ // A point label's place is its point. A line label's place is the hard
8
+ // part, and the answer here is the one that makes a street name easy to
9
+ // read and hard to notice: **on the street, along its centre line, on a
10
+ // stretch that is straight** — the name set as one straight run of type,
11
+ // never bent around a corner, sitting on the road it names rather than
12
+ // beside it. Three steps get there:
13
+ //
14
+ // 1. **Merge.** A street is one feature per segment in every schema there
15
+ // is — `street_labels` offers "Westminster Bridge Road" 24 times in one
16
+ // London tile — so the pieces of each name are joined end to end into
17
+ // the polylines they were cut from. Without this, a straight avenue cut
18
+ // at every cross street has no stretch longer than a block.
19
+ // 2. **Straighten.** Each polyline is walked into its maximal straight
20
+ // *runs*: stretches whose every vertex stays within {@link STRAIGHT} of
21
+ // the chord between the run's ends. A gentle curve is a run; a corner
22
+ // ends one.
23
+ // 3. **Anchor.** Each run offers a few anchors on its chord — its middle,
24
+ // the middle of every block between two intersections, and every
25
+ // {@link SPACING} along a long one — each carrying how much straight run
26
+ // lies either side of it and how far it is from the nearest
27
+ // intersection. Whether a label *fits* there is a question of its width
28
+ // in pixels and so of the zoom, and is left to placement; what is
29
+ // computed here is the geometry that answers it at any zoom.
30
+ //
31
+ // Intersections are found from the label layer itself: a vertex two
32
+ // differently named streets share is a junction. A name set across a junction
33
+ // hides the street that crosses there, so placement prefers an anchor whose
34
+ // label clears one — the middle of a block — to one that does not.
35
+ //
36
+ // Everything leaves as one Float32Array and a string table, so a worker can
37
+ // hand it over with the buckets (see `./gl/store.ts`).
38
+ import { GeomType, GeometryBuffer } from './mvt.js';
39
+ import type { FeatureCursor, VectorTile, VectorTileLayer } from './mvt.js';
40
+ import type { PreparedStyle } from './paint.js';
41
+ import { latFromMercatorY } from './proj.js';
42
+ import type { TileId } from './proj.js';
43
+ import type { SymbolLayer } from './style.js';
44
+
45
+ // --- the fit rules both renderers place by ------------------------------------
46
+
47
+ /** A line label is set level — on whole pixels, which is sharper — when its
48
+ * street is this close to level, in radians. */
49
+ export const LEVEL_SNAP = 0.03;
50
+ /** How far a line label's run may depart from straight, as a fraction of
51
+ * the text's size at the zoom it is drawn at. */
52
+ export const STRAIGHT_FRACTION = 0.3;
53
+ /** Run that must remain past each end of a line label, in text heights —
54
+ * a name that stops exactly at a corner reads as bent. */
55
+ export const LINE_MARGIN = 0.5;
56
+
57
+ /** A name's width before it is measured: a lower-ish bound, from how wide
58
+ * Latin and CJK glyphs run. Only ever used to rule out what cannot fit. */
59
+ export function estimateWidth(text: string, size: number): number {
60
+ let em = 0;
61
+ for (const ch of text) em += ch.codePointAt(0)! >= 0x2e80 ? 0.95 : 0.5;
62
+ return em * size;
63
+ }
64
+
65
+ /** Floats per anchor record. */
66
+ export const LABEL_STRIDE = 10;
67
+
68
+ /** Field offsets within an anchor record. */
69
+ export const LabelField = {
70
+ /** The anchor, in tile units. */
71
+ x: 0,
72
+ y: 1,
73
+ /** The baseline's direction, radians, y down — always upright (see
74
+ * {@link upright}), so no name is ever read upside down. */
75
+ angle: 2,
76
+ /** Tile units of straight run either side of the anchor — how long a
77
+ * label it can carry. `-1` for a point label, which carries any. */
78
+ avail: 3,
79
+ /** Tile units either side of the anchor before an intersection. */
80
+ clear: 4,
81
+ /** The straight run's whole length, tile units; `0` for a point. */
82
+ length: 5,
83
+ /** The run's greatest departure from its chord, tile units. */
84
+ dev: 6,
85
+ /** Index into {@link GlLabelData.texts}. */
86
+ text: 7,
87
+ /** Index into the prepared style's layers. */
88
+ layer: 8,
89
+ /** Importance within the layer: a road's class, a place's population. */
90
+ priority: 9,
91
+ } as const;
92
+
93
+ /** A tile's label anchors. */
94
+ export interface GlLabelData {
95
+ texts: string[];
96
+ /** {@link LABEL_STRIDE} floats per anchor; see {@link LabelField}. */
97
+ anchors: Float32Array;
98
+ count: number;
99
+ ms: number;
100
+ }
101
+
102
+ /** How far a run may depart from straight, in tile units: one pixel at
103
+ * the tile's own zoom (a 512-pixel tile is 4096 units), two at the next. */
104
+ export const STRAIGHT = 8;
105
+ /** The sharpest turn a run takes at one vertex, however small the
106
+ * departure — a kink reads as a corner under a line of text. */
107
+ const MAX_TURN = Math.cos((25 * Math.PI) / 180);
108
+ /** Anchors along a long run with no junction on it, in tile units — 256
109
+ * pixels at the tile's own zoom. */
110
+ export const SPACING = 2048;
111
+ /** The shortest run worth an anchor: 16 pixels at the tile's own zoom,
112
+ * which is a label only four levels of overzoom later. */
113
+ const MIN_RUN = 128;
114
+ /** "No junction within reach", in tile units. */
115
+ const FAR = 1e9;
116
+
117
+ /** A road's importance among roads: the order a map names them in. */
118
+ const ROAD_CLASS: Record<string, number> = {
119
+ motorway: 9,
120
+ trunk: 8,
121
+ primary: 7,
122
+ secondary: 6,
123
+ tertiary: 5,
124
+ unclassified: 4,
125
+ residential: 4,
126
+ living_street: 3,
127
+ pedestrian: 3,
128
+ service: 2,
129
+ track: 1,
130
+ footway: 1,
131
+ cycleway: 1,
132
+ path: 1,
133
+ bridleway: 1,
134
+ steps: 0,
135
+ };
136
+
137
+ const globals = globalThis as { performance?: { now(): number } };
138
+ const now = (): number => globals.performance?.now() ?? Date.now();
139
+
140
+ /** `collectLabels`' rule: the style's field, or the local `name` where a
141
+ * translation is missing — which is most features. */
142
+ function textOf(cursor: FeatureCursor, field: string): string {
143
+ const raw = cursor.get(field);
144
+ if (typeof raw === 'string' && raw.length > 0) return raw;
145
+ if (field === 'name') return '';
146
+ const local = cursor.get('name');
147
+ return typeof local === 'string' ? local : '';
148
+ }
149
+
150
+ function priorityOf(cursor: FeatureCursor): number {
151
+ const population = cursor.get('population');
152
+ if (typeof population === 'number' && population > 0) {
153
+ return Math.log10(population + 1);
154
+ }
155
+ const kind = cursor.get('kind');
156
+ return typeof kind === 'string' ? (ROAD_CLASS[kind] ?? 0) : 0;
157
+ }
158
+
159
+ /** A vertex as one number: tile coordinates are integers after scaling,
160
+ * and within ±32768 with the buffer included. */
161
+ const vertexKey = (x: number, y: number): number =>
162
+ (Math.round(x) + 32768) * 65536 + (Math.round(y) + 32768);
163
+
164
+ /** A growable array of anchor records. */
165
+ class AnchorWriter {
166
+ data = new Float32Array(LABEL_STRIDE * 256);
167
+ count = 0;
168
+
169
+ private _next(): number {
170
+ const at = this.count * LABEL_STRIDE;
171
+ if (at + LABEL_STRIDE > this.data.length) {
172
+ const grown = new Float32Array(this.data.length * 2);
173
+ grown.set(this.data);
174
+ this.data = grown;
175
+ }
176
+ this.count++;
177
+ return at;
178
+ }
179
+
180
+ point(x: number, y: number, text: number, layer: number, priority: number) {
181
+ const at = this._next();
182
+ const d = this.data;
183
+ d[at + LabelField.x] = x;
184
+ d[at + LabelField.y] = y;
185
+ d[at + LabelField.angle] = 0;
186
+ d[at + LabelField.avail] = -1;
187
+ d[at + LabelField.clear] = FAR;
188
+ d[at + LabelField.length] = 0;
189
+ d[at + LabelField.dev] = 0;
190
+ d[at + LabelField.text] = text;
191
+ d[at + LabelField.layer] = layer;
192
+ d[at + LabelField.priority] = priority;
193
+ }
194
+
195
+ line(
196
+ x: number,
197
+ y: number,
198
+ angle: number,
199
+ avail: number,
200
+ clear: number,
201
+ length: number,
202
+ dev: number,
203
+ text: number,
204
+ layer: number,
205
+ priority: number,
206
+ ) {
207
+ const at = this._next();
208
+ const d = this.data;
209
+ d[at + LabelField.x] = x;
210
+ d[at + LabelField.y] = y;
211
+ d[at + LabelField.angle] = angle;
212
+ d[at + LabelField.avail] = avail;
213
+ d[at + LabelField.clear] = clear;
214
+ d[at + LabelField.length] = length;
215
+ d[at + LabelField.dev] = dev;
216
+ d[at + LabelField.text] = text;
217
+ d[at + LabelField.layer] = layer;
218
+ d[at + LabelField.priority] = priority;
219
+ }
220
+
221
+ take(): Float32Array {
222
+ return this.data.slice(0, this.count * LABEL_STRIDE);
223
+ }
224
+ }
225
+
226
+ /** One name's pieces in one tile, before merging. */
227
+ interface LineGroup {
228
+ text: number;
229
+ priority: number;
230
+ parts: number[][];
231
+ }
232
+
233
+ /**
234
+ * A tile's label anchors, for every symbol layer of the style.
235
+ *
236
+ * `extent` is the tile-unit square the anchors are expressed in — the
237
+ * buckets' {@link import('./buckets.js').TILE_EXTENT}, passed in rather than
238
+ * imported so this module does not import the one that calls it. Anchors
239
+ * are kept only inside the tile's own square: the buffer past its edge is
240
+ * the neighbour's, and a label in it would be offered twice.
241
+ */
242
+ export function buildTileLabels(
243
+ tile: VectorTile,
244
+ prepared: PreparedStyle,
245
+ extent: number,
246
+ /** Which tile: what turns a `snapInto` distance in metres into tile
247
+ * units. Without it no distance can be known, and only a point already
248
+ * inside a polygon moves. */
249
+ id?: TileId,
250
+ ): GlLabelData {
251
+ const started = now();
252
+ const texts: string[] = [];
253
+ const index = new Map<string, number>();
254
+ const out = new AnchorWriter();
255
+ const buffer = new GeometryBuffer();
256
+
257
+ for (let i = 0; i < prepared.layers.length; i++) {
258
+ const { layer, filter } = prepared.layers[i];
259
+ if (layer.type !== 'symbol' || layer.visible === false) continue;
260
+ const source = tile.layers.get(layer.sourceLayer);
261
+ if (!source || source.length === 0) continue;
262
+ const symbol = layer as SymbolLayer;
263
+ const k = extent / source.extent;
264
+ const cursor = source.feature(0);
265
+ const groups = new Map<number, LineGroup>();
266
+ // Which name first touched each vertex, or -1 once a second did.
267
+ const touched = new Map<number, number>();
268
+ // A layer that snaps into polygons collects its points first — x, y,
269
+ // text, priority — since which point a polygon belongs to depends on
270
+ // every other point that could claim it.
271
+ const snap = symbol.snapInto;
272
+ const snaps: number[] | null = snap ? [] : null;
273
+
274
+ for (let f = 0; f < source.length; f++) {
275
+ source.seek(f, cursor);
276
+ if (!filter(cursor)) continue;
277
+ const text = textOf(cursor, symbol.textField);
278
+ if (text.length === 0) continue;
279
+ let t = index.get(text);
280
+ if (t === undefined) {
281
+ t = texts.length;
282
+ texts.push(text);
283
+ index.set(text, t);
284
+ }
285
+ const priority = priorityOf(cursor);
286
+ cursor.readGeometry(buffer);
287
+ if (buffer.points === 0) continue;
288
+
289
+ if (cursor.type === GeomType.LineString) {
290
+ let group = groups.get(t);
291
+ if (!group) {
292
+ group = { text: t, priority, parts: [] };
293
+ groups.set(t, group);
294
+ }
295
+ if (priority > group.priority) group.priority = priority;
296
+ for (let part = 0; part < buffer.parts; part++) {
297
+ const from = buffer.starts[part];
298
+ const to = buffer.starts[part + 1];
299
+ if (to - from < 2) continue;
300
+ const points: number[] = [];
301
+ for (let p = from; p < to; p++) {
302
+ const x = buffer.coords[p * 2] * k;
303
+ const y = buffer.coords[p * 2 + 1] * k;
304
+ // Consecutive duplicates would make zero-length segments, whose
305
+ // direction is undefined.
306
+ const n = points.length;
307
+ if (n > 0 && points[n - 2] === x && points[n - 1] === y) continue;
308
+ points.push(x, y);
309
+ const key = vertexKey(x, y);
310
+ const seen = touched.get(key);
311
+ if (seen === undefined) touched.set(key, t);
312
+ else if (seen !== t) touched.set(key, -1);
313
+ }
314
+ if (points.length >= 4) group.parts.push(points);
315
+ }
316
+ continue;
317
+ }
318
+
319
+ const anchor = pointAnchor(buffer, cursor.type);
320
+ if (!anchor) continue;
321
+ const x = anchor.x * k;
322
+ const y = anchor.y * k;
323
+ if (snaps && cursor.type === GeomType.Point) {
324
+ // The buffer's points too, and judged before the tile's square:
325
+ // a polygon near the edge is claimed by points on either side of
326
+ // it, and both tiles that hold it must see the same claims.
327
+ snaps.push(x, y, t, priority);
328
+ continue;
329
+ }
330
+ if (x < 0 || y < 0 || x >= extent || y >= extent) continue;
331
+ out.point(x, y, t, i, priority);
332
+ }
333
+
334
+ if (snap && snaps) {
335
+ const polygons = tile.layers.get(snap.sourceLayer);
336
+ const within = (snap.within ?? SNAP_WITHIN) / metresPerUnit(id, extent);
337
+ snapPoints(polygons, within, snaps, extent, i, out, buffer);
338
+ }
339
+
340
+ for (const group of groups.values()) {
341
+ for (const chain of mergeParts(group.parts)) {
342
+ anchorChain(chain, touched, extent, group, i, out);
343
+ }
344
+ }
345
+ }
346
+
347
+ return { texts, anchors: out.take(), count: out.count, ms: now() - started };
348
+ }
349
+
350
+ /** How far a point is taken to belong to a polygon it is outside, metres,
351
+ * where the layer does not say. An address point in the lot sits a few
352
+ * metres off its house; much past this, the nearest building is as often
353
+ * a neighbour's — the house the number is for not being mapped at all. */
354
+ const SNAP_WITHIN = 15;
355
+ /** The earth's circumference at the equator, metres (Web Mercator's). */
356
+ const EQUATOR = 40075016.686;
357
+
358
+ /** Metres on the ground per tile unit, at the tile's middle row. */
359
+ function metresPerUnit(id: TileId | undefined, extent: number): number {
360
+ const n = 2 ** (id?.z ?? 0);
361
+ const lat = id ? latFromMercatorY((id.y + 0.5) / n) : 0;
362
+ return (EQUATOR * Math.cos((lat * Math.PI) / 180)) / (n * extent);
363
+ }
364
+
365
+ /** One polygon's outer ring, in tile units: its points, its box, and the
366
+ * point inside it a label moved into it is set on. */
367
+ interface SnapRing {
368
+ points: number[];
369
+ x0: number;
370
+ y0: number;
371
+ x1: number;
372
+ y1: number;
373
+ cx: number;
374
+ cy: number;
375
+ }
376
+
377
+ /** The grid rings are found by, in tile units: a z14 tile is 16 cells a
378
+ * side, a few dozen buildings each. */
379
+ const SNAP_CELL = 256;
380
+ const snapCell = (gx: number, gy: number): number =>
381
+ (gx + 1024) * 4096 + (gy + 1024);
382
+
383
+ /**
384
+ * Point labels moved into the polygon each one belongs to — a house number
385
+ * into its house.
386
+ *
387
+ * A point inside a polygon belongs to it; one outside, to the nearest
388
+ * polygon whose outline is within `within` tile units. It moves only if it
389
+ * is the **one** point its polygon is claimed by: a duplex's two numbers, or
390
+ * a garage nearer the street than the house, would otherwise pile several
391
+ * numbers onto one roof — and collision would then keep one of them, on a
392
+ * building that is not only its own. Every point that does not move stays
393
+ * exactly where the data put it.
394
+ *
395
+ * `points` are the whole tile's, buffer included, so a polygon near the edge
396
+ * is claimed alike in both tiles that hold it; each point is then anchored
397
+ * only in the tile its own position is in, as every other point is. One
398
+ * whose polygon's middle is in the next tile over stays put rather than
399
+ * move out of the tile that offers it.
400
+ */
401
+ function snapPoints(
402
+ polygons: VectorTileLayer | undefined,
403
+ within: number,
404
+ points: readonly number[],
405
+ extent: number,
406
+ layer: number,
407
+ out: AnchorWriter,
408
+ buffer: GeometryBuffer,
409
+ ): void {
410
+ const count = points.length / 4;
411
+ const target = new Int32Array(count).fill(-1);
412
+ const rings = polygons ? snapRings(polygons, extent, buffer) : [];
413
+ if (rings.length > 0) {
414
+ const grid = new Map<number, number[]>();
415
+ rings.forEach((ring, r) => {
416
+ for (let gx = cellOf(ring.x0); gx <= cellOf(ring.x1); gx++) {
417
+ for (let gy = cellOf(ring.y0); gy <= cellOf(ring.y1); gy++) {
418
+ const key = snapCell(gx, gy);
419
+ const list = grid.get(key);
420
+ if (list) list.push(r);
421
+ else grid.set(key, [r]);
422
+ }
423
+ }
424
+ });
425
+ const claims = new Int32Array(rings.length);
426
+ // Which query last looked at each ring: a ring spanning several cells
427
+ // is one candidate, not several.
428
+ const seen = new Int32Array(rings.length).fill(-1);
429
+ for (let p = 0; p < count; p++) {
430
+ const r = ownerOf(
431
+ rings,
432
+ grid,
433
+ seen,
434
+ p,
435
+ points[p * 4],
436
+ points[p * 4 + 1],
437
+ within,
438
+ );
439
+ if (r >= 0) {
440
+ target[p] = r;
441
+ claims[r]++;
442
+ }
443
+ }
444
+ for (let p = 0; p < count; p++) {
445
+ if (target[p] >= 0 && claims[target[p]] !== 1) target[p] = -1;
446
+ }
447
+ }
448
+ for (let p = 0; p < count; p++) {
449
+ let x = points[p * 4];
450
+ let y = points[p * 4 + 1];
451
+ if (x < 0 || y < 0 || x >= extent || y >= extent) continue;
452
+ const r = target[p];
453
+ if (r >= 0) {
454
+ const ring = rings[r];
455
+ if (
456
+ ring.cx >= 0 &&
457
+ ring.cy >= 0 &&
458
+ ring.cx < extent &&
459
+ ring.cy < extent
460
+ ) {
461
+ x = ring.cx;
462
+ y = ring.cy;
463
+ }
464
+ }
465
+ out.point(x, y, points[p * 4 + 2], layer, points[p * 4 + 3]);
466
+ }
467
+ }
468
+
469
+ const cellOf = (v: number): number => Math.floor(v / SNAP_CELL);
470
+
471
+ /** Every polygon's outer rings, in tile units. Holes are not a building's
472
+ * own ground, and a courtyard is not where a number goes. */
473
+ function snapRings(
474
+ source: VectorTileLayer,
475
+ extent: number,
476
+ buffer: GeometryBuffer,
477
+ ): SnapRing[] {
478
+ const k = extent / source.extent;
479
+ const cursor = source.feature(0);
480
+ const rings: SnapRing[] = [];
481
+ for (let f = 0; f < source.length; f++) {
482
+ source.seek(f, cursor);
483
+ if (cursor.type !== GeomType.Polygon) continue;
484
+ cursor.readGeometry(buffer);
485
+ for (let part = 0; part < buffer.parts; part++) {
486
+ if (buffer.areas[part] <= 0) continue;
487
+ const from = buffer.starts[part];
488
+ const to = buffer.starts[part + 1];
489
+ if (to - from < 3) continue;
490
+ const points: number[] = [];
491
+ let x0 = Infinity;
492
+ let y0 = Infinity;
493
+ let x1 = -Infinity;
494
+ let y1 = -Infinity;
495
+ for (let p = from; p < to; p++) {
496
+ const x = buffer.coords[p * 2] * k;
497
+ const y = buffer.coords[p * 2 + 1] * k;
498
+ points.push(x, y);
499
+ if (x < x0) x0 = x;
500
+ if (x > x1) x1 = x;
501
+ if (y < y0) y0 = y;
502
+ if (y > y1) y1 = y;
503
+ }
504
+ const [cx, cy] = interiorPoint(points, x0, y0, x1, y1);
505
+ rings.push({ points, x0, y0, x1, y1, cx, cy });
506
+ }
507
+ }
508
+ return rings;
509
+ }
510
+
511
+ /**
512
+ * A point inside a ring to set a label on: its centroid, which is inside
513
+ * for all but the most contorted outline — 99.8% of the building rings in
514
+ * the tiles this was measured on — and where it is not, the middle of the
515
+ * widest span of the ring along the centroid's row.
516
+ */
517
+ function interiorPoint(
518
+ points: readonly number[],
519
+ x0: number,
520
+ y0: number,
521
+ x1: number,
522
+ y1: number,
523
+ ): [number, number] {
524
+ let area = 0;
525
+ let sx = 0;
526
+ let sy = 0;
527
+ const n = points.length;
528
+ for (let i = 0, j = n - 2; i < n; j = i, i += 2) {
529
+ const cross = points[j] * points[i + 1] - points[i] * points[j + 1];
530
+ area += cross;
531
+ sx += (points[j] + points[i]) * cross;
532
+ sy += (points[j + 1] + points[i + 1]) * cross;
533
+ }
534
+ if (area === 0) return [(x0 + x1) / 2, (y0 + y1) / 2];
535
+ const cx = sx / (3 * area);
536
+ const cy = sy / (3 * area);
537
+ if (insideRing(points, cx, cy)) return [cx, cy];
538
+ const crossings: number[] = [];
539
+ for (let i = 0, j = n - 2; i < n; j = i, i += 2) {
540
+ const ay = points[j + 1];
541
+ const by = points[i + 1];
542
+ if (ay > cy !== by > cy) {
543
+ crossings.push(
544
+ points[j] + ((cy - ay) / (by - ay)) * (points[i] - points[j]),
545
+ );
546
+ }
547
+ }
548
+ crossings.sort((a, b) => a - b);
549
+ let best = -1;
550
+ let mid = (x0 + x1) / 2;
551
+ for (let c = 0; c + 1 < crossings.length; c += 2) {
552
+ const span = crossings[c + 1] - crossings[c];
553
+ if (span > best) {
554
+ best = span;
555
+ mid = (crossings[c] + crossings[c + 1]) / 2;
556
+ }
557
+ }
558
+ return [mid, cy];
559
+ }
560
+
561
+ /** Even-odd: whether `x, y` is inside the ring. */
562
+ function insideRing(points: readonly number[], x: number, y: number): boolean {
563
+ let inside = false;
564
+ const n = points.length;
565
+ for (let i = 0, j = n - 2; i < n; j = i, i += 2) {
566
+ const xi = points[i];
567
+ const yi = points[i + 1];
568
+ const xj = points[j];
569
+ const yj = points[j + 1];
570
+ if (yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi) {
571
+ inside = !inside;
572
+ }
573
+ }
574
+ return inside;
575
+ }
576
+
577
+ /** How far `x, y` is from the ring's outline. */
578
+ function distanceToRing(points: readonly number[], x: number, y: number) {
579
+ let best = Infinity;
580
+ const n = points.length;
581
+ for (let i = 0, j = n - 2; i < n; j = i, i += 2) {
582
+ const ax = points[j];
583
+ const ay = points[j + 1];
584
+ const dx = points[i] - ax;
585
+ const dy = points[i + 1] - ay;
586
+ const length = dx * dx + dy * dy;
587
+ const t =
588
+ length > 0
589
+ ? Math.max(0, Math.min(1, ((x - ax) * dx + (y - ay) * dy) / length))
590
+ : 0;
591
+ const d = Math.hypot(x - ax - t * dx, y - ay - t * dy);
592
+ if (d < best) best = d;
593
+ }
594
+ return best;
595
+ }
596
+
597
+ /** The ring a point belongs to — the one it is inside, else the nearest
598
+ * within `within` — or -1. */
599
+ function ownerOf(
600
+ rings: readonly SnapRing[],
601
+ grid: Map<number, number[]>,
602
+ seen: Int32Array,
603
+ query: number,
604
+ x: number,
605
+ y: number,
606
+ within: number,
607
+ ): number {
608
+ let best = -1;
609
+ let bestDistance = within;
610
+ for (let gx = cellOf(x - within); gx <= cellOf(x + within); gx++) {
611
+ for (let gy = cellOf(y - within); gy <= cellOf(y + within); gy++) {
612
+ for (const r of grid.get(snapCell(gx, gy)) ?? []) {
613
+ if (seen[r] === query) continue;
614
+ seen[r] = query;
615
+ const ring = rings[r];
616
+ // Past the box by more than the distance allowed: not a candidate.
617
+ const bx = Math.max(ring.x0 - x, 0, x - ring.x1);
618
+ const by = Math.max(ring.y0 - y, 0, y - ring.y1);
619
+ if (bx > bestDistance || by > bestDistance) continue;
620
+ if (bx === 0 && by === 0 && insideRing(ring.points, x, y)) return r;
621
+ const d = distanceToRing(ring.points, x, y);
622
+ if (d <= bestDistance) {
623
+ best = r;
624
+ bestDistance = d;
625
+ }
626
+ }
627
+ }
628
+ }
629
+ return best;
630
+ }
631
+
632
+ /**
633
+ * Where a point-like feature's label goes: the point, or for a polygon the
634
+ * middle of its largest ring's box — a cheap stand-in for the pole of
635
+ * inaccessibility that lands inside every convex shape.
636
+ */
637
+ function pointAnchor(
638
+ buffer: GeometryBuffer,
639
+ type: GeomType,
640
+ ): { x: number; y: number } | null {
641
+ if (buffer.points === 0) return null;
642
+ if (type === GeomType.Point) {
643
+ return { x: buffer.coords[0], y: buffer.coords[1] };
644
+ }
645
+ let best = 0;
646
+ let bestArea = -1;
647
+ for (let part = 0; part < buffer.parts; part++) {
648
+ const area = Math.abs(buffer.areas[part]);
649
+ if (area > bestArea) {
650
+ bestArea = area;
651
+ best = part;
652
+ }
653
+ }
654
+ const b = best * 4;
655
+ return {
656
+ x: (buffer.partBounds[b] + buffer.partBounds[b + 2]) / 2,
657
+ y: (buffer.partBounds[b + 1] + buffer.partBounds[b + 3]) / 2,
658
+ };
659
+ }
660
+
661
+ /**
662
+ * Join one name's pieces into the polylines they were cut from.
663
+ *
664
+ * Pieces meet at shared end points, in either direction. Where more than one
665
+ * piece continues from a point — a fork, or a dual carriageway's two halves
666
+ * — the one that turns least is taken, so a chain follows the street the way
667
+ * a reader's eye does. Every piece is used exactly once.
668
+ */
669
+ export function mergeParts(parts: readonly number[][]): number[][] {
670
+ const ends = new Map<number, number[]>();
671
+ const add = (key: number, end: number): void => {
672
+ const list = ends.get(key);
673
+ if (list) list.push(end);
674
+ else ends.set(key, [end]);
675
+ };
676
+ for (let i = 0; i < parts.length; i++) {
677
+ const p = parts[i];
678
+ add(vertexKey(p[0], p[1]), i * 2);
679
+ add(vertexKey(p[p.length - 2], p[p.length - 1]), i * 2 + 1);
680
+ }
681
+ const used = new Uint8Array(parts.length);
682
+
683
+ /** The unused piece that continues from `(x, y)` heading `(dx, dy)` with
684
+ * the least turn, oriented to start there; or null. */
685
+ const next = (
686
+ x: number,
687
+ y: number,
688
+ dx: number,
689
+ dy: number,
690
+ ): number[] | null => {
691
+ const list = ends.get(vertexKey(x, y));
692
+ if (!list) return null;
693
+ let best: number[] | null = null;
694
+ let bestIndex = -1;
695
+ let bestDot = -Infinity;
696
+ for (const end of list) {
697
+ const i = end >> 1;
698
+ if (used[i]) continue;
699
+ const p = parts[i];
700
+ const oriented = end & 1 ? reversed(p) : p;
701
+ const ux = oriented[2] - oriented[0];
702
+ const uy = oriented[3] - oriented[1];
703
+ const len = Math.hypot(ux, uy) || 1;
704
+ const dot = (ux * dx + uy * dy) / len;
705
+ if (dot > bestDot) {
706
+ bestDot = dot;
707
+ best = oriented;
708
+ bestIndex = i;
709
+ }
710
+ }
711
+ if (best) used[bestIndex] = 1;
712
+ return best;
713
+ };
714
+
715
+ const chains: number[][] = [];
716
+ for (let i = 0; i < parts.length; i++) {
717
+ if (used[i]) continue;
718
+ used[i] = 1;
719
+ let chain = parts[i].slice();
720
+ // Forward from the end, then forward from the start of the reversed
721
+ // chain — which is backward from the original start.
722
+ for (let pass = 0; pass < 2; pass++) {
723
+ for (;;) {
724
+ const n = chain.length;
725
+ const dx = chain[n - 2] - chain[n - 4];
726
+ const dy = chain[n - 1] - chain[n - 3];
727
+ const len = Math.hypot(dx, dy) || 1;
728
+ const more = next(chain[n - 2], chain[n - 1], dx / len, dy / len);
729
+ if (!more) break;
730
+ for (let j = 2; j < more.length; j++) chain.push(more[j]);
731
+ }
732
+ chain = reversed(chain);
733
+ }
734
+ chains.push(chain);
735
+ }
736
+ return chains;
737
+ }
738
+
739
+ function reversed(points: readonly number[]): number[] {
740
+ const out = new Array<number>(points.length);
741
+ for (let i = 0, j = points.length - 2; j >= 0; i += 2, j -= 2) {
742
+ out[i] = points[j];
743
+ out[i + 1] = points[j + 1];
744
+ }
745
+ return out;
746
+ }
747
+
748
+ /** A maximal straight stretch of a chain: vertices `[from, to]`. */
749
+ export interface StraightRun {
750
+ from: number;
751
+ to: number;
752
+ /** The chord's length, and the furthest vertex from it. */
753
+ length: number;
754
+ dev: number;
755
+ }
756
+
757
+ /**
758
+ * A chain's maximal straight runs, greedily from its start: a run grows a
759
+ * vertex at a time while every vertex inside it stays within `tolerance`
760
+ * of the chord and no vertex turns sharper than {@link MAX_TURN}. A run
761
+ * ends at the last vertex that kept it straight, and the next one starts
762
+ * there, so runs share their end points and cover the whole chain.
763
+ */
764
+ export function straightRuns(
765
+ chain: readonly number[],
766
+ tolerance = STRAIGHT,
767
+ ): StraightRun[] {
768
+ const n = chain.length / 2;
769
+ const runs: StraightRun[] = [];
770
+ let from = 0;
771
+ while (from < n - 1) {
772
+ let to = from + 1;
773
+ let dev = 0;
774
+ while (to + 1 < n) {
775
+ const d = deviation(chain, from, to + 1);
776
+ if (d > tolerance || !gentle(chain, to)) break;
777
+ dev = d;
778
+ to++;
779
+ }
780
+ const length = Math.hypot(
781
+ chain[to * 2] - chain[from * 2],
782
+ chain[to * 2 + 1] - chain[from * 2 + 1],
783
+ );
784
+ runs.push({ from, to, length, dev });
785
+ from = to;
786
+ }
787
+ return runs;
788
+ }
789
+
790
+ /** The greatest distance of vertices strictly inside `(from, to)` from the
791
+ * chord between them. */
792
+ function deviation(chain: readonly number[], from: number, to: number): number {
793
+ const ax = chain[from * 2];
794
+ const ay = chain[from * 2 + 1];
795
+ const dx = chain[to * 2] - ax;
796
+ const dy = chain[to * 2 + 1] - ay;
797
+ const len = Math.hypot(dx, dy);
798
+ if (len === 0) return Infinity;
799
+ let worst = 0;
800
+ for (let m = from + 1; m < to; m++) {
801
+ const px = chain[m * 2] - ax;
802
+ const py = chain[m * 2 + 1] - ay;
803
+ // Off the chord's ends counts as off the chord: a run that doubles back
804
+ // is not straight however close its points stay to the line.
805
+ const along = (px * dx + py * dy) / len;
806
+ const off =
807
+ along < 0
808
+ ? Math.hypot(px, py)
809
+ : along > len
810
+ ? Math.hypot(px - dx, py - dy)
811
+ : Math.abs(px * dy - py * dx) / len;
812
+ if (off > worst) worst = off;
813
+ }
814
+ return worst;
815
+ }
816
+
817
+ /** Whether the turn at vertex `m` is gentle enough to stay in a run. */
818
+ function gentle(chain: readonly number[], m: number): boolean {
819
+ const ax = chain[m * 2] - chain[m * 2 - 2];
820
+ const ay = chain[m * 2 + 1] - chain[m * 2 - 1];
821
+ const bx = chain[m * 2 + 2] - chain[m * 2];
822
+ const by = chain[m * 2 + 3] - chain[m * 2 + 1];
823
+ const la = Math.hypot(ax, ay);
824
+ const lb = Math.hypot(bx, by);
825
+ if (la === 0 || lb === 0) return true;
826
+ return (ax * bx + ay * by) / (la * lb) >= MAX_TURN;
827
+ }
828
+
829
+ /** How far past vertical a name still reads bottom to top. */
830
+ const VERTICAL_BIAS = (10 * Math.PI) / 180;
831
+
832
+ /**
833
+ * A direction, turned to read left to right — and, near vertical, bottom
834
+ * to top: within [-π/2 - 10°, π/2 - 10°), y down, so -π/2 points up the
835
+ * screen. Without the bias, two streets a few degrees either side of
836
+ * vertical read in opposite directions side by side; with it, every
837
+ * near-vertical name reads the way maps set them, upward.
838
+ */
839
+ export function upright(angle: number): number {
840
+ let a = angle;
841
+ while (a >= Math.PI / 2 - VERTICAL_BIAS) a -= Math.PI;
842
+ while (a < -Math.PI / 2 - VERTICAL_BIAS) a += Math.PI;
843
+ return a;
844
+ }
845
+
846
+ /** Every anchor one merged chain offers. */
847
+ function anchorChain(
848
+ chain: readonly number[],
849
+ touched: Map<number, number>,
850
+ extent: number,
851
+ group: LineGroup,
852
+ layer: number,
853
+ out: AnchorWriter,
854
+ ): void {
855
+ for (const run of straightRuns(chain)) {
856
+ const L = run.length;
857
+ if (L < MIN_RUN) continue;
858
+ const ax = chain[run.from * 2];
859
+ const ay = chain[run.from * 2 + 1];
860
+ const ux = (chain[run.to * 2] - ax) / L;
861
+ const uy = (chain[run.to * 2 + 1] - ay) / L;
862
+ // Where along the chord the run's junctions are.
863
+ const junctions: number[] = [];
864
+ for (let m = run.from; m <= run.to; m++) {
865
+ const x = chain[m * 2];
866
+ const y = chain[m * 2 + 1];
867
+ if (touched.get(vertexKey(x, y)) !== -1) continue;
868
+ junctions.push((x - ax) * ux + (y - ay) * uy);
869
+ }
870
+ junctions.sort((a, b) => a - b);
871
+
872
+ // The run's middle, the middle of every block, and — on a run with no
873
+ // junction at all — every SPACING either side of the middle.
874
+ const at: number[] = [L / 2];
875
+ const bounds = [0, ...junctions, L];
876
+ for (let b = 0; b + 1 < bounds.length; b++) {
877
+ if (bounds[b + 1] - bounds[b] >= MIN_RUN) {
878
+ at.push((bounds[b] + bounds[b + 1]) / 2);
879
+ }
880
+ }
881
+ if (junctions.length === 0) {
882
+ for (let s = SPACING; L / 2 + s <= L - SPACING / 2; s += SPACING) {
883
+ at.push(L / 2 + s, L / 2 - s);
884
+ }
885
+ }
886
+ at.sort((a, b) => a - b);
887
+
888
+ const angle = upright(Math.atan2(uy, ux));
889
+ let last = -Infinity;
890
+ for (const s of at) {
891
+ // Two anchors closer than a few pixels are one anchor twice.
892
+ if (s - last < 32) continue;
893
+ last = s;
894
+ const x = ax + ux * s;
895
+ const y = ay + uy * s;
896
+ if (x < 0 || y < 0 || x >= extent || y >= extent) continue;
897
+ let clear = FAR;
898
+ for (const j of junctions) clear = Math.min(clear, Math.abs(j - s));
899
+ out.line(
900
+ x,
901
+ y,
902
+ angle,
903
+ Math.min(s, L - s),
904
+ clear,
905
+ L,
906
+ run.dev,
907
+ group.text,
908
+ layer,
909
+ group.priority,
910
+ );
911
+ }
912
+ }
913
+ }