@dwelle/excalidraw 0.5.0-da1c822 → 0.5.0-e56eec7

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 (382) hide show
  1. package/CHANGELOG.md +13 -2
  2. package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-RHODGCTM.js → blockDiagram-91b80b7a-NRABZKZA.js} +6 -6
  3. package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-W7NCR7LR.js → c4Diagram-b2a90758-56M32CJD.js} +4 -4
  4. package/dist/browser/dev/excalidraw-assets-dev/{chunk-TKRIVTWP.js → chunk-5EDB2FTV.js} +3 -3
  5. package/dist/browser/dev/excalidraw-assets-dev/{chunk-52OGG53V.js → chunk-6VTJEXQH.js} +3 -3
  6. package/dist/browser/dev/excalidraw-assets-dev/{chunk-J5HRUYQR.js → chunk-AKQDHN2W.js} +2 -2
  7. package/dist/browser/dev/excalidraw-assets-dev/chunk-AKQDHN2W.js.map +7 -0
  8. package/dist/browser/dev/excalidraw-assets-dev/{chunk-GF7VCOUM.js → chunk-C4OL7SRI.js} +3 -3
  9. package/dist/browser/dev/excalidraw-assets-dev/{chunk-BESQLMCW.js → chunk-E47I6Q7O.js} +5 -5
  10. package/dist/browser/dev/excalidraw-assets-dev/{chunk-UETNA2WX.js → chunk-KDIPICHB.js} +6377 -4340
  11. package/dist/browser/dev/excalidraw-assets-dev/chunk-KDIPICHB.js.map +7 -0
  12. package/dist/browser/dev/excalidraw-assets-dev/{chunk-5747M6KP.js → chunk-OH2YDYHX.js} +3 -3
  13. package/dist/browser/dev/excalidraw-assets-dev/{chunk-GPOYIZPX.js → chunk-PXBR5CBM.js} +28 -28
  14. package/dist/browser/dev/excalidraw-assets-dev/chunk-PXBR5CBM.js.map +7 -0
  15. package/dist/browser/dev/excalidraw-assets-dev/{chunk-GCA4S2OA.js → chunk-RTA6DTUV.js} +3 -3
  16. package/dist/browser/dev/excalidraw-assets-dev/{chunk-DQOPSCYA.js → chunk-TTH3BTHQ.js} +3 -3
  17. package/dist/browser/dev/excalidraw-assets-dev/{chunk-B2MHJWXZ.js → chunk-U4N7TEPH.js} +2 -2
  18. package/dist/browser/dev/excalidraw-assets-dev/{chunk-QFS4M5OJ.js → chunk-V3PA4IDR.js} +3 -3
  19. package/dist/browser/dev/excalidraw-assets-dev/{chunk-SLLUETBM.js → chunk-WFT6ZJE6.js} +7 -7
  20. package/dist/browser/dev/excalidraw-assets-dev/{chunk-PPHFJLL7.js → chunk-XZKEYTKS.js} +4 -4
  21. package/dist/browser/dev/excalidraw-assets-dev/{chunk-USLWOHUZ.js → chunk-YC6VTXEO.js} +4 -4
  22. package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-GJGBT4TV.js → classDiagram-30eddba6-EZJVINS6.js} +6 -6
  23. package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-LYWTIPJA.js → classDiagram-v2-f2df5561-XSUIN44A.js} +9 -9
  24. package/dist/browser/dev/excalidraw-assets-dev/{directory-open-01563666-UREMLRIT.js → directory-open-01563666-KOK2HSB6.js} +2 -2
  25. package/dist/browser/dev/excalidraw-assets-dev/{directory-open-4ed118d0-UN3BUDZZ.js → directory-open-4ed118d0-P3Q3CLF3.js} +2 -2
  26. package/dist/browser/dev/excalidraw-assets-dev/dist-O6HOTHQF.js +10 -0
  27. package/dist/browser/dev/excalidraw-assets-dev/{en-UW5C5KGW.js → en-PSBMWL4S.js} +2 -2
  28. package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-Z7U2XW2Y.js → erDiagram-47591fe2-U7FLWOG3.js} +5 -5
  29. package/dist/browser/dev/excalidraw-assets-dev/{file-open-002ab408-4QG336MG.js → file-open-002ab408-EQEHGU2J.js} +2 -2
  30. package/dist/browser/dev/excalidraw-assets-dev/{file-open-7c801643-3QI4ICCL.js → file-open-7c801643-QQT6O7P5.js} +2 -2
  31. package/dist/browser/dev/excalidraw-assets-dev/{file-save-3189631c-TNNERCWV.js → file-save-3189631c-YXX2C7C6.js} +2 -2
  32. package/dist/browser/dev/excalidraw-assets-dev/{file-save-745eba88-JFMH565P.js → file-save-745eba88-7G554KTZ.js} +2 -2
  33. package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-PARVG263.js → flowDiagram-5540d9b9-F2VP4JAA.js} +10 -10
  34. package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-ZJOPVRMB.js → flowDiagram-v2-3b53844e-2WQZZRND.js} +10 -10
  35. package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-ULPNBSZX.js → flowchart-elk-definition-5fe447d6-IW6O2F6C.js} +6 -6
  36. package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-ESSYVTJ4.js → ganttDiagram-9a3bba1f-B5RH7ZAO.js} +3 -3
  37. package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-6V6VVNNP.js → gitGraphDiagram-96e6b4ee-INGQRNLZ.js} +3 -3
  38. package/dist/browser/dev/excalidraw-assets-dev/{image-ZNQQXS62.css → image-FDQLNM24.css} +39 -16
  39. package/dist/browser/dev/excalidraw-assets-dev/image-FDQLNM24.css.map +7 -0
  40. package/dist/browser/dev/excalidraw-assets-dev/{image-3LTGFHLF.js → image-GMAHLVER.js} +6 -6
  41. package/dist/browser/dev/excalidraw-assets-dev/{image-blob-reduce.esm-KTX27DAY.js → image-blob-reduce.esm-OX75MRP3.js} +2 -2
  42. package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-I22FLFX3.js → infoDiagram-bcd20f53-43FMAUOR.js} +3 -3
  43. package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-WAO6F52C.js → journeyDiagram-4fe6b3dc-KFVOUX4I.js} +4 -4
  44. package/dist/browser/dev/excalidraw-assets-dev/{katex-NWA2YFOP.js → katex-A3GRORPB.js} +2 -2
  45. package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-K74IKX4Y.js → mindmap-definition-f354de21-D7S3CRQ4.js} +4 -4
  46. package/dist/browser/dev/excalidraw-assets-dev/{pica-3TH2EGXR.js → pica-ZAD7MTGA.js} +2 -2
  47. package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-DOB2LVE5.js → pieDiagram-79897490-OON2CRZ5.js} +3 -3
  48. package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-MJV2X7WI.js → quadrantDiagram-62f64e94-5APTNVVS.js} +3 -3
  49. package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-H4YM3XN7.js → requirementDiagram-05bf5f74-FM7WZVKU.js} +5 -5
  50. package/dist/browser/dev/excalidraw-assets-dev/{roundRect-4S3QV2NZ.js → roundRect-AYYHVX5X.js} +2 -2
  51. package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-7X74ABAN.js → sankeyDiagram-97764748-5HLEFFGY.js} +3 -3
  52. package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-PPDIJFQP.js → sequenceDiagram-acc0e65c-4ZRSNGPV.js} +4 -4
  53. package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-JVBR7N35.js → stateDiagram-0ff1cf1a-OLTPYRPP.js} +6 -6
  54. package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-QYAJLQJH.js → stateDiagram-v2-9a9d610d-N3XOTAEE.js} +9 -9
  55. package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-GL7U3WDB.js → timeline-definition-fea2a41d-5PDFIYJQ.js} +3 -3
  56. package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-4U4JE4TW.js → xychartDiagram-ab372869-VIWBP45Y.js} +4 -4
  57. package/dist/browser/dev/index.css +38 -15
  58. package/dist/browser/dev/index.css.map +2 -2
  59. package/dist/browser/dev/index.js +9 -5
  60. package/dist/browser/prod/excalidraw-assets/ar-SA-JA6F2FMJ-MVAFRXH2.js +10 -0
  61. package/dist/browser/prod/excalidraw-assets/az-AZ-GVIENQVH-DULWV7IG.js +1 -0
  62. package/dist/browser/prod/excalidraw-assets/bg-BG-YFNNHCEP-TOMMDX7A.js +5 -0
  63. package/dist/browser/prod/excalidraw-assets/{blockDiagram-91b80b7a-BO7MW3VX.js → blockDiagram-91b80b7a-ZBW6LBXS.js} +1 -1
  64. package/dist/browser/prod/excalidraw-assets/bn-BD-LMEIWSRD-U6EPN6XJ.js +5 -0
  65. package/dist/browser/prod/excalidraw-assets/{c4Diagram-b2a90758-VCUPBVHR.js → c4Diagram-b2a90758-GET6IFET.js} +1 -1
  66. package/dist/browser/prod/excalidraw-assets/ca-ES-C2WGCLOT-4Q2376G3.js +8 -0
  67. package/dist/browser/prod/excalidraw-assets/{chunk-O77Z7CWL.js → chunk-2UGPV7X3.js} +1 -1
  68. package/dist/browser/prod/excalidraw-assets/{chunk-B7CDQVNY.js → chunk-364WSJPQ.js} +21 -21
  69. package/dist/browser/prod/excalidraw-assets/{chunk-NM5B2RBP.js → chunk-4FM7RPKW.js} +1 -1
  70. package/dist/browser/prod/excalidraw-assets/{chunk-CVEF66PS.js → chunk-4SHJFNCN.js} +1 -1
  71. package/dist/browser/prod/excalidraw-assets/{chunk-22FVL4I7.js → chunk-6TNDONBF.js} +1 -1
  72. package/dist/browser/prod/excalidraw-assets/{chunk-QLNFR4AJ.js → chunk-BJTCWAK5.js} +1 -1
  73. package/dist/browser/prod/excalidraw-assets/chunk-CKRG5LOX.js +335 -0
  74. package/dist/browser/prod/excalidraw-assets/{chunk-3HZHH3PT.js → chunk-IW42BK4V.js} +1 -1
  75. package/dist/browser/prod/excalidraw-assets/{chunk-4JYQ3563.js → chunk-MRQWXP64.js} +1 -1
  76. package/dist/browser/prod/excalidraw-assets/{chunk-VXFFPRP2.js → chunk-OG2UUKMT.js} +1 -1
  77. package/dist/browser/prod/excalidraw-assets/chunk-Q6QP4TRB.js +11 -0
  78. package/dist/browser/prod/excalidraw-assets/{chunk-V7HUISEN.js → chunk-QBYA3CCP.js} +1 -1
  79. package/dist/browser/prod/excalidraw-assets/{chunk-5PWM36DG.js → chunk-S3O7MXSU.js} +1 -1
  80. package/dist/browser/prod/excalidraw-assets/chunk-SJBOQTFA.js +1 -0
  81. package/dist/browser/prod/excalidraw-assets/{chunk-3VCRCP5J.js → chunk-T7MBBIYG.js} +1 -1
  82. package/dist/browser/prod/excalidraw-assets/{chunk-HPA5W5VE.js → chunk-X7R4RA7C.js} +1 -1
  83. package/dist/browser/prod/excalidraw-assets/{chunk-7UJZVYSR.js → chunk-Y3NNVSMP.js} +1 -1
  84. package/dist/browser/prod/excalidraw-assets/{classDiagram-30eddba6-VXGNM3LI.js → classDiagram-30eddba6-MJ5GZSCE.js} +1 -1
  85. package/dist/browser/prod/excalidraw-assets/{classDiagram-v2-f2df5561-YALTASVE.js → classDiagram-v2-f2df5561-FU5PRXDD.js} +1 -1
  86. package/dist/browser/prod/excalidraw-assets/cs-CZ-F2NDIQMB-4NMYRMO2.js +11 -0
  87. package/dist/browser/prod/excalidraw-assets/da-DK-WBEQB3CJ-6YAF4DNI.js +5 -0
  88. package/dist/browser/prod/excalidraw-assets/de-DE-VEIMCP7R-NSRLPHDI.js +8 -0
  89. package/dist/browser/prod/excalidraw-assets/{directory-open-01563666-JWXY2QSC.js → directory-open-01563666-UG2J4T6L.js} +1 -1
  90. package/dist/browser/prod/excalidraw-assets/{directory-open-4ed118d0-6AL5X37W.js → directory-open-4ed118d0-FGQD6TMW.js} +1 -1
  91. package/dist/browser/prod/excalidraw-assets/dist-LI3DBBWR.js +1 -0
  92. package/dist/browser/prod/excalidraw-assets/el-GR-TKRKG5GQ-6N4GY2DI.js +10 -0
  93. package/dist/browser/prod/excalidraw-assets/{en-CPU3UVKT.js → en-MPFDZHEH.js} +1 -1
  94. package/dist/browser/prod/excalidraw-assets/en-Q552WR7L-QAV42NF3.js +1 -0
  95. package/dist/browser/prod/excalidraw-assets/{erDiagram-47591fe2-GKYANCN7.js → erDiagram-47591fe2-YGAMNOK6.js} +1 -1
  96. package/dist/browser/prod/excalidraw-assets/es-ES-TOLWEZNW-ODY4LX7F.js +9 -0
  97. package/dist/browser/prod/excalidraw-assets/eu-ES-7CDRJQWJ-KF3KSB2X.js +11 -0
  98. package/dist/browser/prod/excalidraw-assets/fa-IR-527E2XGU-WLLGMWYR.js +8 -0
  99. package/dist/browser/prod/excalidraw-assets/fi-FI-NLQ7RQGZ-EZLGQEWF.js +6 -0
  100. package/dist/browser/prod/excalidraw-assets/{file-open-002ab408-3EPJOH45.js → file-open-002ab408-WLX7QPS6.js} +1 -1
  101. package/dist/browser/prod/excalidraw-assets/{file-open-7c801643-QIP6HK4D.js → file-open-7c801643-YB6IH3XI.js} +1 -1
  102. package/dist/browser/prod/excalidraw-assets/{file-save-3189631c-4TQJBQCS.js → file-save-3189631c-MRYCXU63.js} +1 -1
  103. package/dist/browser/prod/excalidraw-assets/{file-save-745eba88-C4L3ZGCC.js → file-save-745eba88-UZEDMFLR.js} +1 -1
  104. package/dist/browser/prod/excalidraw-assets/{flowDiagram-5540d9b9-QBRW5SLP.js → flowDiagram-5540d9b9-V23UQWYJ.js} +1 -1
  105. package/dist/browser/prod/excalidraw-assets/flowDiagram-v2-3b53844e-UDC2ZAFT.js +1 -0
  106. package/dist/browser/prod/excalidraw-assets/{flowchart-elk-definition-5fe447d6-YYO2EYKS.js → flowchart-elk-definition-5fe447d6-N3ISH6AG.js} +1 -1
  107. package/dist/browser/prod/excalidraw-assets/fr-FR-KUHO4FLU-2OW7FE5V.js +9 -0
  108. package/dist/browser/prod/excalidraw-assets/{ganttDiagram-9a3bba1f-3B2DUUUQ.js → ganttDiagram-9a3bba1f-7SAN2TXA.js} +1 -1
  109. package/dist/browser/prod/excalidraw-assets/{gitGraphDiagram-96e6b4ee-G6CKXXWQ.js → gitGraphDiagram-96e6b4ee-EXV6PWXL.js} +1 -1
  110. package/dist/browser/prod/excalidraw-assets/gl-ES-NEXX3VBB-TESFDR6O.js +10 -0
  111. package/dist/browser/prod/excalidraw-assets/he-IL-MED2VGBZ-N4VYRCHF.js +10 -0
  112. package/dist/browser/prod/excalidraw-assets/hi-IN-5V633W7V-4VXVQ6GE.js +4 -0
  113. package/dist/browser/prod/excalidraw-assets/hu-HU-2FOZGVGR-7CHHZRPD.js +7 -0
  114. package/dist/browser/prod/excalidraw-assets/id-ID-I6BOLXTF-ULJRGCTU.js +10 -0
  115. package/dist/browser/prod/excalidraw-assets/image-ZKACJTPS.js +1 -0
  116. package/dist/browser/prod/excalidraw-assets/{image-blob-reduce.esm-5DTGAOOI.js → image-blob-reduce.esm-GOFU5DPX.js} +1 -1
  117. package/dist/browser/prod/excalidraw-assets/{infoDiagram-bcd20f53-WJTZJERL.js → infoDiagram-bcd20f53-LJZ36XP5.js} +1 -1
  118. package/dist/browser/prod/excalidraw-assets/it-IT-WKPQOK4P-C3FTW2QG.js +11 -0
  119. package/dist/browser/prod/excalidraw-assets/ja-JP-VKA4ISRU-EBXFDMUP.js +8 -0
  120. package/dist/browser/prod/excalidraw-assets/{journeyDiagram-4fe6b3dc-JF22KXXQ.js → journeyDiagram-4fe6b3dc-TFRSU2KH.js} +1 -1
  121. package/dist/browser/prod/excalidraw-assets/kaa-IKPRSBNY-URJPWZZH.js +1 -0
  122. package/dist/browser/prod/excalidraw-assets/kab-KAB-IE4PHQTZ-OMISFOMM.js +8 -0
  123. package/dist/browser/prod/excalidraw-assets/{katex-N6R5DPQX.js → katex-HAQKNIIQ.js} +1 -1
  124. package/dist/browser/prod/excalidraw-assets/kk-KZ-MNJT6XSV-56OVE4EH.js +1 -0
  125. package/dist/browser/prod/excalidraw-assets/km-KH-LADGDFXV-KI7V2Z5A.js +11 -0
  126. package/dist/browser/prod/excalidraw-assets/ko-KR-XD7AVF2F-EFYGITKM.js +9 -0
  127. package/dist/browser/prod/excalidraw-assets/ku-TR-4XBHKDQA-U25XLPMW.js +9 -0
  128. package/dist/browser/prod/excalidraw-assets/lt-LT-QC35R4YH-6TDSRONI.js +3 -0
  129. package/dist/browser/prod/excalidraw-assets/lv-LV-GSD5D3BA-KMXM2FQ7.js +7 -0
  130. package/dist/browser/prod/excalidraw-assets/{mindmap-definition-f354de21-7SH5STU3.js → mindmap-definition-f354de21-J3C2WSJB.js} +1 -1
  131. package/dist/browser/prod/excalidraw-assets/mr-IN-KOLSWM7Y-NVYC6JCO.js +13 -0
  132. package/dist/browser/prod/excalidraw-assets/my-MM-M53KMUET-A2ORJJ2D.js +1 -0
  133. package/dist/browser/prod/excalidraw-assets/nb-NO-XXC6U37A-L4O4DGCC.js +10 -0
  134. package/dist/browser/prod/excalidraw-assets/nl-NL-HCCJQEUO-7Q2LV5NM.js +8 -0
  135. package/dist/browser/prod/excalidraw-assets/nn-NO-6P7Z2PI2-TUT2PFEE.js +8 -0
  136. package/dist/browser/prod/excalidraw-assets/oc-FR-JRJKPLNT-SBQHJH7X.js +8 -0
  137. package/dist/browser/prod/excalidraw-assets/pa-IN-LZWLEPIB-7NKOXI65.js +4 -0
  138. package/dist/browser/prod/excalidraw-assets/percentages-UCQDHIQF-Q4IM6ZEB.js +1 -0
  139. package/dist/browser/prod/excalidraw-assets/{pica-KWHN2PJ6.js → pica-ABPXE5C5.js} +1 -1
  140. package/dist/browser/prod/excalidraw-assets/{pieDiagram-79897490-5O5EBEQB.js → pieDiagram-79897490-FMJ3ZAF7.js} +1 -1
  141. package/dist/browser/prod/excalidraw-assets/pl-PL-3WBLCXI2-E2SMTIVM.js +9 -0
  142. package/dist/browser/prod/excalidraw-assets/pt-BR-O3ZPTUNW-RS7M7EKX.js +9 -0
  143. package/dist/browser/prod/excalidraw-assets/pt-PT-7AQTSAFO-AEANJ2UN.js +9 -0
  144. package/dist/browser/prod/excalidraw-assets/{quadrantDiagram-62f64e94-JTY6WOKB.js → quadrantDiagram-62f64e94-YI32TPUI.js} +1 -1
  145. package/dist/browser/prod/excalidraw-assets/{requirementDiagram-05bf5f74-TSFQFY5X.js → requirementDiagram-05bf5f74-UO2ATL3U.js} +1 -1
  146. package/dist/browser/prod/excalidraw-assets/ro-RO-HJ65JYWV-35XNZ4QJ.js +11 -0
  147. package/dist/browser/prod/excalidraw-assets/{roundRect-PUCZURYS.js → roundRect-UKQBLFKQ.js} +1 -1
  148. package/dist/browser/prod/excalidraw-assets/ru-RU-P7ROIYNC-ERPG3GJT.js +9 -0
  149. package/dist/browser/prod/excalidraw-assets/{sankeyDiagram-97764748-7G2R6W67.js → sankeyDiagram-97764748-3RR36435.js} +1 -1
  150. package/dist/browser/prod/excalidraw-assets/{sequenceDiagram-acc0e65c-CTANNZCO.js → sequenceDiagram-acc0e65c-G2Q6J4UN.js} +1 -1
  151. package/dist/browser/prod/excalidraw-assets/si-LK-7ZSWVION-YHKN25MU.js +1 -0
  152. package/dist/browser/prod/excalidraw-assets/sk-SK-NXVBGLYY-IKQZT26E.js +6 -0
  153. package/dist/browser/prod/excalidraw-assets/sl-SI-VFTWOYNP-UPLNMI3E.js +6 -0
  154. package/dist/browser/prod/excalidraw-assets/{stateDiagram-0ff1cf1a-I5COLKZ4.js → stateDiagram-0ff1cf1a-QEYVXCSB.js} +1 -1
  155. package/dist/browser/prod/excalidraw-assets/{stateDiagram-v2-9a9d610d-IIHI3AJN.js → stateDiagram-v2-9a9d610d-3VKD7UYK.js} +1 -1
  156. package/dist/browser/prod/excalidraw-assets/sv-SE-YONBLQNW-ZG4TE7PV.js +10 -0
  157. package/dist/browser/prod/excalidraw-assets/ta-IN-BSETPMLX-FC54FMQJ.js +9 -0
  158. package/dist/browser/prod/excalidraw-assets/th-TH-URTRDITB-K6QQ2PRO.js +2 -0
  159. package/dist/browser/prod/excalidraw-assets/{timeline-definition-fea2a41d-CXTGKWI4.js → timeline-definition-fea2a41d-H4D6IYVJ.js} +1 -1
  160. package/dist/browser/prod/excalidraw-assets/tr-TR-N5SCAVTB-HMUEG6DN.js +7 -0
  161. package/dist/browser/prod/excalidraw-assets/uk-UA-LBCYVSQZ-DEJZCNRZ.js +6 -0
  162. package/dist/browser/prod/excalidraw-assets/vi-VN-POZWLIUU-EY6QFLQV.js +5 -0
  163. package/dist/browser/prod/excalidraw-assets/{xychartDiagram-ab372869-QZGPPHJP.js → xychartDiagram-ab372869-SUXFHV53.js} +1 -1
  164. package/dist/browser/prod/excalidraw-assets/zh-CN-FUF5V3SC-5UIL2T3T.js +10 -0
  165. package/dist/browser/prod/excalidraw-assets/zh-HK-OB4VW42C-3ID2CCZJ.js +1 -0
  166. package/dist/browser/prod/excalidraw-assets/zh-TW-5JPVKOM7-VUPJBABS.js +9 -0
  167. package/dist/browser/prod/index.css +1 -1
  168. package/dist/browser/prod/index.js +128 -1
  169. package/dist/dev/{en-R7FEFJGC.json → en-Q552WR7L.json} +1 -1
  170. package/dist/dev/index.css +38 -15
  171. package/dist/dev/index.css.map +2 -2
  172. package/dist/dev/index.js +4575 -2598
  173. package/dist/dev/index.js.map +4 -4
  174. package/dist/excalidraw/actions/actionAddToLibrary.d.ts +4 -4
  175. package/dist/excalidraw/actions/actionAddToLibrary.js +4 -3
  176. package/dist/excalidraw/actions/actionAlign.d.ts +20 -20
  177. package/dist/excalidraw/actions/actionAlign.js +7 -6
  178. package/dist/excalidraw/actions/actionBoundText.d.ts +7 -7
  179. package/dist/excalidraw/actions/actionBoundText.js +8 -4
  180. package/dist/excalidraw/actions/actionCanvas.d.ts +49 -49
  181. package/dist/excalidraw/actions/actionCanvas.js +16 -13
  182. package/dist/excalidraw/actions/actionClipboard.d.ts +24 -24
  183. package/dist/excalidraw/actions/actionClipboard.js +14 -13
  184. package/dist/excalidraw/actions/actionDeleteSelected.d.ts +8 -8
  185. package/dist/excalidraw/actions/actionDeleteSelected.js +6 -3
  186. package/dist/excalidraw/actions/actionDistribute.d.ts +8 -8
  187. package/dist/excalidraw/actions/actionDistribute.js +3 -2
  188. package/dist/excalidraw/actions/actionDuplicateSelection.d.ts +5 -6
  189. package/dist/excalidraw/actions/actionDuplicateSelection.js +7 -3
  190. package/dist/excalidraw/actions/actionElementLock.d.ts +8 -8
  191. package/dist/excalidraw/actions/actionElementLock.js +3 -2
  192. package/dist/excalidraw/actions/actionExport.d.ts +36 -36
  193. package/dist/excalidraw/actions/actionExport.js +15 -11
  194. package/dist/excalidraw/actions/actionFinalize.d.ts +8 -8
  195. package/dist/excalidraw/actions/actionFinalize.js +9 -5
  196. package/dist/excalidraw/actions/actionFlip.d.ts +9 -9
  197. package/dist/excalidraw/actions/actionFlip.js +10 -9
  198. package/dist/excalidraw/actions/actionFrame.d.ts +14 -169
  199. package/dist/excalidraw/actions/actionFrame.js +7 -6
  200. package/dist/excalidraw/actions/actionGroup.d.ts +11 -321
  201. package/dist/excalidraw/actions/actionGroup.js +9 -11
  202. package/dist/excalidraw/actions/actionHistory.d.ts +3 -2
  203. package/dist/excalidraw/actions/actionHistory.js +27 -28
  204. package/dist/excalidraw/actions/actionLinearEditor.d.ts +2 -2
  205. package/dist/excalidraw/actions/actionLinearEditor.js +2 -1
  206. package/dist/excalidraw/actions/actionLink.d.ts +5 -5
  207. package/dist/excalidraw/actions/actionLink.js +2 -1
  208. package/dist/excalidraw/actions/actionMenu.d.ts +8 -8
  209. package/dist/excalidraw/actions/actionMenu.js +4 -3
  210. package/dist/excalidraw/actions/actionNavigate.d.ts +3 -3
  211. package/dist/excalidraw/actions/actionNavigate.js +3 -2
  212. package/dist/excalidraw/actions/actionProperties.d.ts +32 -32
  213. package/dist/excalidraw/actions/actionProperties.js +18 -13
  214. package/dist/excalidraw/actions/actionSelectAll.d.ts +4 -4
  215. package/dist/excalidraw/actions/actionSelectAll.js +2 -1
  216. package/dist/excalidraw/actions/actionStyles.d.ts +9 -12
  217. package/dist/excalidraw/actions/actionStyles.js +4 -3
  218. package/dist/excalidraw/actions/actionToggleGridMode.d.ts +6 -4
  219. package/dist/excalidraw/actions/actionToggleGridMode.js +6 -2
  220. package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +4 -4
  221. package/dist/excalidraw/actions/actionToggleObjectsSnapMode.js +2 -1
  222. package/dist/excalidraw/actions/actionToggleStats.d.ts +4 -4
  223. package/dist/excalidraw/actions/actionToggleStats.js +2 -1
  224. package/dist/excalidraw/actions/actionToggleViewMode.d.ts +4 -4
  225. package/dist/excalidraw/actions/actionToggleViewMode.js +2 -1
  226. package/dist/excalidraw/actions/actionToggleZenMode.d.ts +4 -4
  227. package/dist/excalidraw/actions/actionToggleZenMode.js +2 -1
  228. package/dist/excalidraw/actions/actionZindex.d.ts +19 -19
  229. package/dist/excalidraw/actions/actionZindex.js +5 -4
  230. package/dist/excalidraw/actions/manager.d.ts +3 -3
  231. package/dist/excalidraw/actions/types.d.ts +4 -4
  232. package/dist/excalidraw/appState.d.ts +5 -5
  233. package/dist/excalidraw/change.d.ts +191 -0
  234. package/dist/excalidraw/change.js +894 -0
  235. package/dist/excalidraw/components/App.d.ts +22 -7
  236. package/dist/excalidraw/components/App.js +340 -130
  237. package/dist/excalidraw/components/CommandPalette/CommandPalette.js +1 -0
  238. package/dist/excalidraw/components/HelpDialog.js +1 -1
  239. package/dist/excalidraw/components/Sidebar/Sidebar.d.ts +2 -2
  240. package/dist/excalidraw/components/Stack.d.ts +2 -2
  241. package/dist/excalidraw/components/ToolButton.d.ts +1 -0
  242. package/dist/excalidraw/components/ToolButton.js +1 -1
  243. package/dist/excalidraw/components/canvases/InteractiveCanvas.d.ts +2 -1
  244. package/dist/excalidraw/components/canvases/InteractiveCanvas.js +1 -0
  245. package/dist/excalidraw/components/hyperlink/Hyperlink.js +3 -3
  246. package/dist/excalidraw/components/hyperlink/helpers.js +2 -3
  247. package/dist/excalidraw/components/icons.d.ts +1 -0
  248. package/dist/excalidraw/components/icons.js +1 -0
  249. package/dist/excalidraw/components/main-menu/DefaultItems.d.ts +1 -1
  250. package/dist/excalidraw/constants.d.ts +3 -3
  251. package/dist/excalidraw/constants.js +6 -3
  252. package/dist/excalidraw/data/reconcile.d.ts +6 -0
  253. package/dist/excalidraw/data/reconcile.js +49 -0
  254. package/dist/excalidraw/data/restore.d.ts +3 -3
  255. package/dist/excalidraw/data/restore.js +6 -7
  256. package/dist/excalidraw/data/transform.d.ts +1 -1
  257. package/dist/excalidraw/data/transform.js +4 -3
  258. package/dist/excalidraw/data/url.d.ts +1 -0
  259. package/dist/excalidraw/data/url.js +4 -1
  260. package/dist/excalidraw/element/binding.d.ts +64 -9
  261. package/dist/excalidraw/element/binding.js +634 -96
  262. package/dist/excalidraw/element/bounds.d.ts +0 -1
  263. package/dist/excalidraw/element/bounds.js +0 -3
  264. package/dist/excalidraw/element/collision.d.ts +14 -19
  265. package/dist/excalidraw/element/collision.js +36 -713
  266. package/dist/excalidraw/element/embeddable.d.ts +7 -4
  267. package/dist/excalidraw/element/embeddable.js +88 -27
  268. package/dist/excalidraw/element/index.d.ts +0 -1
  269. package/dist/excalidraw/element/index.js +0 -1
  270. package/dist/excalidraw/element/linearElementEditor.d.ts +11 -11
  271. package/dist/excalidraw/element/linearElementEditor.js +7 -5
  272. package/dist/excalidraw/element/mutateElement.d.ts +1 -2
  273. package/dist/excalidraw/element/newElement.d.ts +1 -1
  274. package/dist/excalidraw/element/newElement.js +2 -1
  275. package/dist/excalidraw/element/resizeElements.d.ts +1 -1
  276. package/dist/excalidraw/element/resizeElements.js +110 -86
  277. package/dist/excalidraw/element/resizeTest.d.ts +4 -4
  278. package/dist/excalidraw/element/resizeTest.js +55 -8
  279. package/dist/excalidraw/element/sizeHelpers.js +3 -0
  280. package/dist/excalidraw/element/textElement.d.ts +1 -2
  281. package/dist/excalidraw/element/textElement.js +5 -34
  282. package/dist/excalidraw/element/transformHandles.d.ts +22 -4
  283. package/dist/excalidraw/element/transformHandles.js +24 -3
  284. package/dist/excalidraw/element/typeChecks.d.ts +2 -2
  285. package/dist/excalidraw/element/types.d.ts +19 -6
  286. package/dist/excalidraw/errors.d.ts +3 -0
  287. package/dist/excalidraw/errors.js +3 -0
  288. package/dist/excalidraw/fractionalIndex.d.ts +40 -0
  289. package/dist/excalidraw/fractionalIndex.js +241 -0
  290. package/dist/excalidraw/frame.d.ts +1 -1
  291. package/dist/excalidraw/groups.d.ts +2 -0
  292. package/dist/excalidraw/groups.js +17 -0
  293. package/dist/excalidraw/history.d.ts +34 -46
  294. package/dist/excalidraw/history.js +100 -167
  295. package/dist/excalidraw/hooks/useEmitter.d.ts +2 -0
  296. package/dist/excalidraw/hooks/useEmitter.js +13 -0
  297. package/dist/excalidraw/index.d.ts +2 -0
  298. package/dist/excalidraw/index.js +2 -0
  299. package/dist/excalidraw/locales/en.json +1 -1
  300. package/dist/excalidraw/renderer/interactiveScene.d.ts +1 -1
  301. package/dist/excalidraw/renderer/interactiveScene.js +8 -7
  302. package/dist/excalidraw/renderer/staticScene.js +14 -3
  303. package/dist/excalidraw/renderer/staticSvgScene.js +10 -0
  304. package/dist/excalidraw/scene/Scene.d.ts +7 -6
  305. package/dist/excalidraw/scene/Scene.js +31 -16
  306. package/dist/excalidraw/scene/export.js +2 -1
  307. package/dist/excalidraw/scene/types.d.ts +2 -1
  308. package/dist/excalidraw/store.d.ts +99 -0
  309. package/dist/excalidraw/store.js +269 -0
  310. package/dist/excalidraw/types.d.ts +18 -4
  311. package/dist/excalidraw/utils.d.ts +6 -0
  312. package/dist/excalidraw/utils.js +7 -0
  313. package/dist/excalidraw/zindex.d.ts +2 -2
  314. package/dist/excalidraw/zindex.js +9 -13
  315. package/dist/prod/{en-R7FEFJGC.json → en-Q552WR7L.json} +1 -1
  316. package/dist/prod/index.css +1 -1
  317. package/dist/prod/index.js +44 -44
  318. package/dist/utils/collision.d.ts +4 -0
  319. package/dist/utils/collision.js +48 -0
  320. package/dist/utils/geometry/geometry.d.ts +71 -0
  321. package/dist/utils/geometry/geometry.js +674 -0
  322. package/dist/utils/geometry/shape.d.ts +56 -0
  323. package/dist/utils/geometry/shape.js +168 -0
  324. package/history.ts +161 -216
  325. package/package.json +2 -1
  326. package/dist/browser/dev/excalidraw-assets-dev/chunk-GPOYIZPX.js.map +0 -7
  327. package/dist/browser/dev/excalidraw-assets-dev/chunk-J5HRUYQR.js.map +0 -7
  328. package/dist/browser/dev/excalidraw-assets-dev/chunk-UETNA2WX.js.map +0 -7
  329. package/dist/browser/dev/excalidraw-assets-dev/dist-Y7S5GOTG.js +0 -10
  330. package/dist/browser/dev/excalidraw-assets-dev/image-ZNQQXS62.css.map +0 -7
  331. package/dist/browser/prod/excalidraw-assets/chunk-EEN6AFMH.js +0 -269
  332. package/dist/browser/prod/excalidraw-assets/dist-7FHVDAZ2.js +0 -1
  333. package/dist/browser/prod/excalidraw-assets/flowDiagram-v2-3b53844e-CRHRHP7H.js +0 -1
  334. package/dist/browser/prod/excalidraw-assets/image-VXYNPVOG.js +0 -1
  335. package/dist/browser/prod/excalidraw-assets/image-WE6NA2G6.css +0 -1
  336. /package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-RHODGCTM.js.map → blockDiagram-91b80b7a-NRABZKZA.js.map} +0 -0
  337. /package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-W7NCR7LR.js.map → c4Diagram-b2a90758-56M32CJD.js.map} +0 -0
  338. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-TKRIVTWP.js.map → chunk-5EDB2FTV.js.map} +0 -0
  339. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-52OGG53V.js.map → chunk-6VTJEXQH.js.map} +0 -0
  340. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-GF7VCOUM.js.map → chunk-C4OL7SRI.js.map} +0 -0
  341. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-BESQLMCW.js.map → chunk-E47I6Q7O.js.map} +0 -0
  342. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-5747M6KP.js.map → chunk-OH2YDYHX.js.map} +0 -0
  343. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-GCA4S2OA.js.map → chunk-RTA6DTUV.js.map} +0 -0
  344. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-DQOPSCYA.js.map → chunk-TTH3BTHQ.js.map} +0 -0
  345. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-B2MHJWXZ.js.map → chunk-U4N7TEPH.js.map} +0 -0
  346. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-QFS4M5OJ.js.map → chunk-V3PA4IDR.js.map} +0 -0
  347. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-SLLUETBM.js.map → chunk-WFT6ZJE6.js.map} +0 -0
  348. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-PPHFJLL7.js.map → chunk-XZKEYTKS.js.map} +0 -0
  349. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-USLWOHUZ.js.map → chunk-YC6VTXEO.js.map} +0 -0
  350. /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-GJGBT4TV.js.map → classDiagram-30eddba6-EZJVINS6.js.map} +0 -0
  351. /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-LYWTIPJA.js.map → classDiagram-v2-f2df5561-XSUIN44A.js.map} +0 -0
  352. /package/dist/browser/dev/excalidraw-assets-dev/{directory-open-01563666-UREMLRIT.js.map → directory-open-01563666-KOK2HSB6.js.map} +0 -0
  353. /package/dist/browser/dev/excalidraw-assets-dev/{directory-open-4ed118d0-UN3BUDZZ.js.map → directory-open-4ed118d0-P3Q3CLF3.js.map} +0 -0
  354. /package/dist/browser/dev/excalidraw-assets-dev/{dist-Y7S5GOTG.js.map → dist-O6HOTHQF.js.map} +0 -0
  355. /package/dist/browser/dev/excalidraw-assets-dev/{en-UW5C5KGW.js.map → en-PSBMWL4S.js.map} +0 -0
  356. /package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-Z7U2XW2Y.js.map → erDiagram-47591fe2-U7FLWOG3.js.map} +0 -0
  357. /package/dist/browser/dev/excalidraw-assets-dev/{file-open-002ab408-4QG336MG.js.map → file-open-002ab408-EQEHGU2J.js.map} +0 -0
  358. /package/dist/browser/dev/excalidraw-assets-dev/{file-open-7c801643-3QI4ICCL.js.map → file-open-7c801643-QQT6O7P5.js.map} +0 -0
  359. /package/dist/browser/dev/excalidraw-assets-dev/{file-save-3189631c-TNNERCWV.js.map → file-save-3189631c-YXX2C7C6.js.map} +0 -0
  360. /package/dist/browser/dev/excalidraw-assets-dev/{file-save-745eba88-JFMH565P.js.map → file-save-745eba88-7G554KTZ.js.map} +0 -0
  361. /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-PARVG263.js.map → flowDiagram-5540d9b9-F2VP4JAA.js.map} +0 -0
  362. /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-ZJOPVRMB.js.map → flowDiagram-v2-3b53844e-2WQZZRND.js.map} +0 -0
  363. /package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-ULPNBSZX.js.map → flowchart-elk-definition-5fe447d6-IW6O2F6C.js.map} +0 -0
  364. /package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-ESSYVTJ4.js.map → ganttDiagram-9a3bba1f-B5RH7ZAO.js.map} +0 -0
  365. /package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-6V6VVNNP.js.map → gitGraphDiagram-96e6b4ee-INGQRNLZ.js.map} +0 -0
  366. /package/dist/browser/dev/excalidraw-assets-dev/{image-3LTGFHLF.js.map → image-GMAHLVER.js.map} +0 -0
  367. /package/dist/browser/dev/excalidraw-assets-dev/{image-blob-reduce.esm-KTX27DAY.js.map → image-blob-reduce.esm-OX75MRP3.js.map} +0 -0
  368. /package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-I22FLFX3.js.map → infoDiagram-bcd20f53-43FMAUOR.js.map} +0 -0
  369. /package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-WAO6F52C.js.map → journeyDiagram-4fe6b3dc-KFVOUX4I.js.map} +0 -0
  370. /package/dist/browser/dev/excalidraw-assets-dev/{katex-NWA2YFOP.js.map → katex-A3GRORPB.js.map} +0 -0
  371. /package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-K74IKX4Y.js.map → mindmap-definition-f354de21-D7S3CRQ4.js.map} +0 -0
  372. /package/dist/browser/dev/excalidraw-assets-dev/{pica-3TH2EGXR.js.map → pica-ZAD7MTGA.js.map} +0 -0
  373. /package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-DOB2LVE5.js.map → pieDiagram-79897490-OON2CRZ5.js.map} +0 -0
  374. /package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-MJV2X7WI.js.map → quadrantDiagram-62f64e94-5APTNVVS.js.map} +0 -0
  375. /package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-H4YM3XN7.js.map → requirementDiagram-05bf5f74-FM7WZVKU.js.map} +0 -0
  376. /package/dist/browser/dev/excalidraw-assets-dev/{roundRect-4S3QV2NZ.js.map → roundRect-AYYHVX5X.js.map} +0 -0
  377. /package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-7X74ABAN.js.map → sankeyDiagram-97764748-5HLEFFGY.js.map} +0 -0
  378. /package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-PPDIJFQP.js.map → sequenceDiagram-acc0e65c-4ZRSNGPV.js.map} +0 -0
  379. /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-JVBR7N35.js.map → stateDiagram-0ff1cf1a-OLTPYRPP.js.map} +0 -0
  380. /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-QYAJLQJH.js.map → stateDiagram-v2-9a9d610d-N3XOTAEE.js.map} +0 -0
  381. /package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-GL7U3WDB.js.map → timeline-definition-fea2a41d-5PDFIYJQ.js.map} +0 -0
  382. /package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-4U4JE4TW.js.map → xychartDiagram-ab372869-VIWBP45Y.js.map} +0 -0
@@ -1,6 +1,12 @@
1
+ import * as GA from "../ga";
2
+ import * as GAPoint from "../gapoints";
3
+ import * as GADirection from "../gadirections";
4
+ import * as GALine from "../galines";
5
+ import * as GATransform from "../gatransforms";
6
+ import { getElementAbsoluteCoords } from "./bounds";
7
+ import { isPointOnShape } from "../../utils/collision";
1
8
  import { getElementAtPosition } from "../scene";
2
- import { isBindableElement, isBindingElement, isLinearElement, } from "./typeChecks";
3
- import { bindingBorderTest, distanceToBindableElement, maxBindingGap, determineFocusDistance, intersectElementWithLine, determineFocusPoint, } from "./collision";
9
+ import { isArrowElement, isBindableElement, isBindingElement, isBoundToContainer, isLinearElement, isTextElement, } from "./typeChecks";
4
10
  import { mutateElement } from "./mutateElement";
5
11
  import Scene from "../scene/Scene";
6
12
  import { LinearElementEditor } from "./linearElementEditor";
@@ -61,27 +67,27 @@ unboundFromElementIds, elementsMap) => {
61
67
  }
62
68
  }
63
69
  };
64
- export const bindOrUnbindSelectedElements = (selectedElements, elements, elementsMap) => {
70
+ export const bindOrUnbindSelectedElements = (selectedElements, app) => {
65
71
  selectedElements.forEach((selectedElement) => {
66
72
  if (isBindingElement(selectedElement)) {
67
- bindOrUnbindLinearElement(selectedElement, getElligibleElementForBindingElement(selectedElement, "start", elements, elementsMap), getElligibleElementForBindingElement(selectedElement, "end", elements, elementsMap), elementsMap);
73
+ bindOrUnbindLinearElement(selectedElement, getElligibleElementForBindingElement(selectedElement, "start", app), getElligibleElementForBindingElement(selectedElement, "end", app), app.scene.getNonDeletedElementsMap());
68
74
  }
69
75
  else if (isBindableElement(selectedElement)) {
70
- maybeBindBindableElement(selectedElement, elementsMap);
76
+ maybeBindBindableElement(selectedElement, app.scene.getNonDeletedElementsMap(), app);
71
77
  }
72
78
  });
73
79
  };
74
- const maybeBindBindableElement = (bindableElement, elementsMap) => {
75
- getElligibleElementsForBindableElementAndWhere(bindableElement, elementsMap).forEach(([linearElement, where]) => bindOrUnbindLinearElement(linearElement, where === "end" ? "keep" : bindableElement, where === "start" ? "keep" : bindableElement, elementsMap));
80
+ const maybeBindBindableElement = (bindableElement, elementsMap, app) => {
81
+ getElligibleElementsForBindableElementAndWhere(bindableElement, app).forEach(([linearElement, where]) => bindOrUnbindLinearElement(linearElement, where === "end" ? "keep" : bindableElement, where === "start" ? "keep" : bindableElement, elementsMap));
76
82
  };
77
- export const maybeBindLinearElement = (linearElement, appState, scene, pointerCoords, elementsMap) => {
83
+ export const maybeBindLinearElement = (linearElement, appState, pointerCoords, app) => {
78
84
  if (appState.startBoundElement != null) {
79
- bindLinearElement(linearElement, appState.startBoundElement, "start", elementsMap);
85
+ bindLinearElement(linearElement, appState.startBoundElement, "start", app.scene.getNonDeletedElementsMap());
80
86
  }
81
- const hoveredElement = getHoveredElementForBinding(pointerCoords, scene.getNonDeletedElements(), elementsMap);
87
+ const hoveredElement = getHoveredElementForBinding(pointerCoords, app);
82
88
  if (hoveredElement != null &&
83
89
  !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, hoveredElement, "end")) {
84
- bindLinearElement(linearElement, hoveredElement, "end", elementsMap);
90
+ bindLinearElement(linearElement, hoveredElement, "end", app.scene.getNonDeletedElementsMap());
85
91
  }
86
92
  };
87
93
  export const bindLinearElement = (linearElement, hoveredElement, startOrEnd, elementsMap) => {
@@ -112,7 +118,12 @@ export const isLinearElementSimpleAndAlreadyBound = (linearElement, alreadyBound
112
118
  export const unbindLinearElements = (elements, elementsMap) => {
113
119
  elements.forEach((element) => {
114
120
  if (isBindingElement(element)) {
115
- bindOrUnbindLinearElement(element, null, null, elementsMap);
121
+ if (element.startBinding !== null && element.endBinding !== null) {
122
+ bindOrUnbindLinearElement(element, null, null, elementsMap);
123
+ }
124
+ else {
125
+ bindOrUnbindLinearElement(element, element.startBinding ? "keep" : null, element.endBinding ? "keep" : null, elementsMap);
126
+ }
116
127
  }
117
128
  });
118
129
  };
@@ -125,9 +136,9 @@ const unbindLinearElement = (linearElement, startOrEnd) => {
125
136
  mutateElement(linearElement, { [field]: null });
126
137
  return binding.elementId;
127
138
  };
128
- export const getHoveredElementForBinding = (pointerCoords, elements, elementsMap) => {
129
- const hoveredElement = getElementAtPosition(elements, (element) => isBindableElement(element, false) &&
130
- bindingBorderTest(element, pointerCoords, elementsMap));
139
+ export const getHoveredElementForBinding = (pointerCoords, app) => {
140
+ const hoveredElement = getElementAtPosition(app.scene.getNonDeletedElements(), (element) => isBindableElement(element, false) &&
141
+ bindingBorderTest(element, pointerCoords, app));
131
142
  return hoveredElement;
132
143
  };
133
144
  const calculateFocusAndGap = (linearElement, hoveredElement, startOrEnd, elementsMap) => {
@@ -147,34 +158,38 @@ const calculateFocusAndGap = (linearElement, hoveredElement, startOrEnd, element
147
158
  // done before the `changedElement` is updated, and the `newSize` is passed
148
159
  // in explicitly.
149
160
  export const updateBoundElements = (changedElement, elementsMap, options) => {
150
- const boundLinearElements = (changedElement.boundElements ?? []).filter((el) => el.type === "arrow");
151
- if (boundLinearElements.length === 0) {
152
- return;
153
- }
154
161
  const { newSize, simultaneouslyUpdated } = options ?? {};
155
162
  const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(simultaneouslyUpdated);
156
- const scene = Scene.getScene(changedElement);
157
- getNonDeletedElements(scene, boundLinearElements.map((el) => el.id)).forEach((element) => {
158
- if (!isLinearElement(element)) {
163
+ if (!isBindableElement(changedElement)) {
164
+ return;
165
+ }
166
+ boundElementsVisitor(elementsMap, changedElement, (element) => {
167
+ if (!isLinearElement(element) || element.isDeleted) {
159
168
  return;
160
169
  }
161
- const bindableElement = changedElement;
162
170
  // In case the boundElements are stale
163
- if (!doesNeedUpdate(element, bindableElement)) {
171
+ if (!doesNeedUpdate(element, changedElement)) {
164
172
  return;
165
173
  }
166
- const startBinding = maybeCalculateNewGapWhenScaling(bindableElement, element.startBinding, newSize);
167
- const endBinding = maybeCalculateNewGapWhenScaling(bindableElement, element.endBinding, newSize);
174
+ const bindings = {
175
+ startBinding: maybeCalculateNewGapWhenScaling(changedElement, element.startBinding, newSize),
176
+ endBinding: maybeCalculateNewGapWhenScaling(changedElement, element.endBinding, newSize),
177
+ };
168
178
  // `linearElement` is being moved/scaled already, just update the binding
169
179
  if (simultaneouslyUpdatedElementIds.has(element.id)) {
170
- mutateElement(element, { startBinding, endBinding });
180
+ mutateElement(element, bindings);
171
181
  return;
172
182
  }
173
- updateBoundPoint(element, "start", startBinding, changedElement, elementsMap);
174
- updateBoundPoint(element, "end", endBinding, changedElement, elementsMap);
175
- const boundText = getBoundTextElement(element, scene.getNonDeletedElementsMap());
176
- if (boundText) {
177
- handleBindTextResize(element, scene.getNonDeletedElementsMap(), false);
183
+ bindableElementsVisitor(elementsMap, element, (bindableElement, bindingProp) => {
184
+ if (bindableElement &&
185
+ isBindableElement(bindableElement) &&
186
+ (bindingProp === "startBinding" || bindingProp === "endBinding")) {
187
+ updateBoundPoint(element, bindingProp, bindings[bindingProp], bindableElement, elementsMap);
188
+ }
189
+ });
190
+ const boundText = getBoundTextElement(element, elementsMap);
191
+ if (boundText && !boundText.isDeleted) {
192
+ handleBindTextResize(element, elementsMap, false);
178
193
  }
179
194
  });
180
195
  };
@@ -185,22 +200,18 @@ const doesNeedUpdate = (boundElement, changedElement) => {
185
200
  const getSimultaneouslyUpdatedElementIds = (simultaneouslyUpdated) => {
186
201
  return new Set((simultaneouslyUpdated || []).map((element) => element.id));
187
202
  };
188
- const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement, elementsMap) => {
203
+ const updateBoundPoint = (linearElement, startOrEnd, binding, bindableElement, elementsMap) => {
189
204
  if (binding == null ||
190
205
  // We only need to update the other end if this is a 2 point line element
191
- (binding.elementId !== changedElement.id && linearElement.points.length > 2)) {
192
- return;
193
- }
194
- const bindingElement = Scene.getScene(linearElement).getElement(binding.elementId);
195
- if (bindingElement == null) {
196
- // We're not cleaning up after deleted elements atm., so handle this case
206
+ (binding.elementId !== bindableElement.id &&
207
+ linearElement.points.length > 2)) {
197
208
  return;
198
209
  }
199
- const direction = startOrEnd === "start" ? -1 : 1;
210
+ const direction = startOrEnd === "startBinding" ? -1 : 1;
200
211
  const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;
201
212
  const adjacentPointIndex = edgePointIndex - direction;
202
213
  const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, adjacentPointIndex, elementsMap);
203
- const focusPointAbsolute = determineFocusPoint(bindingElement, binding.focus, adjacentPoint, elementsMap);
214
+ const focusPointAbsolute = determineFocusPoint(bindableElement, binding.focus, adjacentPoint, elementsMap);
204
215
  let newEdgePoint;
205
216
  // The linear element was not originally pointing inside the bound shape,
206
217
  // we can point directly at the focus point
@@ -208,7 +219,7 @@ const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement, el
208
219
  newEdgePoint = focusPointAbsolute;
209
220
  }
210
221
  else {
211
- const intersections = intersectElementWithLine(bindingElement, adjacentPoint, focusPointAbsolute, binding.gap, elementsMap);
222
+ const intersections = intersectElementWithLine(bindableElement, adjacentPoint, focusPointAbsolute, binding.gap, elementsMap);
212
223
  if (intersections.length === 0) {
213
224
  // This should never happen, since focusPoint should always be
214
225
  // inside the element, but just in case, bail out
@@ -224,7 +235,7 @@ const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement, el
224
235
  index: edgePointIndex,
225
236
  point: LinearElementEditor.pointFromAbsoluteCoords(linearElement, newEdgePoint, elementsMap),
226
237
  },
227
- ], { [startOrEnd === "start" ? "startBinding" : "endBinding"]: binding });
238
+ ], { [startOrEnd]: binding });
228
239
  };
229
240
  const maybeCalculateNewGapWhenScaling = (changedElement, currentBinding, newSize) => {
230
241
  if (currentBinding == null || newSize == null) {
@@ -237,28 +248,28 @@ const maybeCalculateNewGapWhenScaling = (changedElement, currentBinding, newSize
237
248
  return { elementId, gap: newGap, focus };
238
249
  };
239
250
  // TODO: this is a bottleneck, optimise
240
- export const getEligibleElementsForBinding = (selectedElements, elements, elementsMap) => {
251
+ export const getEligibleElementsForBinding = (selectedElements, app) => {
241
252
  const includedElementIds = new Set(selectedElements.map(({ id }) => id));
242
253
  return selectedElements.flatMap((selectedElement) => isBindingElement(selectedElement, false)
243
- ? getElligibleElementsForBindingElement(selectedElement, elements, elementsMap).filter((element) => !includedElementIds.has(element.id))
254
+ ? getElligibleElementsForBindingElement(selectedElement, app).filter((element) => !includedElementIds.has(element.id))
244
255
  : isBindableElement(selectedElement, false)
245
- ? getElligibleElementsForBindableElementAndWhere(selectedElement, elementsMap).filter((binding) => !includedElementIds.has(binding[0].id))
256
+ ? getElligibleElementsForBindableElementAndWhere(selectedElement, app).filter((binding) => !includedElementIds.has(binding[0].id))
246
257
  : []);
247
258
  };
248
- const getElligibleElementsForBindingElement = (linearElement, elements, elementsMap) => {
259
+ const getElligibleElementsForBindingElement = (linearElement, app) => {
249
260
  return [
250
- getElligibleElementForBindingElement(linearElement, "start", elements, elementsMap),
251
- getElligibleElementForBindingElement(linearElement, "end", elements, elementsMap),
261
+ getElligibleElementForBindingElement(linearElement, "start", app),
262
+ getElligibleElementForBindingElement(linearElement, "end", app),
252
263
  ].filter((element) => element != null);
253
264
  };
254
- const getElligibleElementForBindingElement = (linearElement, startOrEnd, elements, elementsMap) => {
255
- return getHoveredElementForBinding(getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap), elements, elementsMap);
265
+ const getElligibleElementForBindingElement = (linearElement, startOrEnd, app) => {
266
+ return getHoveredElementForBinding(getLinearElementEdgeCoors(linearElement, startOrEnd, app.scene.getNonDeletedElementsMap()), app);
256
267
  };
257
268
  const getLinearElementEdgeCoors = (linearElement, startOrEnd, elementsMap) => {
258
269
  const index = startOrEnd === "start" ? 0 : -1;
259
270
  return tupleToCoors(LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, index, elementsMap));
260
271
  };
261
- const getElligibleElementsForBindableElementAndWhere = (bindableElement, elementsMap) => {
272
+ const getElligibleElementsForBindableElementAndWhere = (bindableElement, app) => {
262
273
  const scene = Scene.getScene(bindableElement);
263
274
  return scene
264
275
  .getNonDeletedElements()
@@ -266,8 +277,8 @@ const getElligibleElementsForBindableElementAndWhere = (bindableElement, element
266
277
  if (!isBindingElement(element, false)) {
267
278
  return null;
268
279
  }
269
- const canBindStart = isLinearElementEligibleForNewBindingByBindable(element, "start", bindableElement, elementsMap);
270
- const canBindEnd = isLinearElementEligibleForNewBindingByBindable(element, "end", bindableElement, elementsMap);
280
+ const canBindStart = isLinearElementEligibleForNewBindingByBindable(element, "start", bindableElement, scene.getNonDeletedElementsMap(), app);
281
+ const canBindEnd = isLinearElementEligibleForNewBindingByBindable(element, "end", bindableElement, scene.getNonDeletedElementsMap(), app);
271
282
  if (!canBindStart && !canBindEnd) {
272
283
  return null;
273
284
  }
@@ -279,11 +290,11 @@ const getElligibleElementsForBindableElementAndWhere = (bindableElement, element
279
290
  })
280
291
  .filter((maybeElement) => maybeElement != null);
281
292
  };
282
- const isLinearElementEligibleForNewBindingByBindable = (linearElement, startOrEnd, bindableElement, elementsMap) => {
293
+ const isLinearElementEligibleForNewBindingByBindable = (linearElement, startOrEnd, bindableElement, elementsMap, app) => {
283
294
  const existingBinding = linearElement[startOrEnd === "start" ? "startBinding" : "endBinding"];
284
295
  return (existingBinding == null &&
285
296
  !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd) &&
286
- bindingBorderTest(bindableElement, getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap), elementsMap));
297
+ bindingBorderTest(bindableElement, getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap), app));
287
298
  };
288
299
  // We need to:
289
300
  // 1: Update elements not selected to point to duplicated elements
@@ -364,51 +375,578 @@ const newBindingAfterDuplication = (binding, oldIdToDuplicatedId) => {
364
375
  };
365
376
  };
366
377
  export const fixBindingsAfterDeletion = (sceneElements, deletedElements) => {
367
- const deletedElementIds = new Set(deletedElements.map((element) => element.id));
368
- // non-deleted which bindings need to be updated
369
- const affectedElements = new Set();
370
- deletedElements.forEach((deletedElement) => {
371
- if (isBindableElement(deletedElement)) {
372
- deletedElement.boundElements?.forEach((element) => {
373
- if (!deletedElementIds.has(element.id)) {
374
- affectedElements.add(element.id);
375
- }
376
- });
377
- }
378
- else if (isBindingElement(deletedElement)) {
379
- if (deletedElement.startBinding) {
380
- affectedElements.add(deletedElement.startBinding.elementId);
381
- }
382
- if (deletedElement.endBinding) {
383
- affectedElements.add(deletedElement.endBinding.elementId);
384
- }
385
- }
378
+ const elements = arrayToMap(sceneElements);
379
+ for (const element of deletedElements) {
380
+ BoundElement.unbindAffected(elements, element, mutateElement);
381
+ BindableElement.unbindAffected(elements, element, mutateElement);
382
+ }
383
+ };
384
+ const newBoundElements = (boundElements, idsToRemove, elementsToAdd = []) => {
385
+ if (!boundElements) {
386
+ return null;
387
+ }
388
+ const nextBoundElements = boundElements.filter((boundElement) => !idsToRemove.has(boundElement.id));
389
+ nextBoundElements.push(...elementsToAdd.map((x) => ({ id: x.id, type: x.type })));
390
+ return nextBoundElements;
391
+ };
392
+ export const bindingBorderTest = (element, { x, y }, app) => {
393
+ const threshold = maxBindingGap(element, element.width, element.height);
394
+ const shape = app.getElementShape(element);
395
+ return isPointOnShape([x, y], shape, threshold);
396
+ };
397
+ export const maxBindingGap = (element, elementWidth, elementHeight) => {
398
+ // Aligns diamonds with rectangles
399
+ const shapeRatio = element.type === "diamond" ? 1 / Math.sqrt(2) : 1;
400
+ const smallerDimension = shapeRatio * Math.min(elementWidth, elementHeight);
401
+ // We make the bindable boundary bigger for bigger elements
402
+ return Math.max(16, Math.min(0.25 * smallerDimension, 32));
403
+ };
404
+ export const distanceToBindableElement = (element, point, elementsMap) => {
405
+ switch (element.type) {
406
+ case "rectangle":
407
+ case "image":
408
+ case "text":
409
+ case "iframe":
410
+ case "embeddable":
411
+ case "frame":
412
+ case "magicframe":
413
+ return distanceToRectangle(element, point, elementsMap);
414
+ case "diamond":
415
+ return distanceToDiamond(element, point, elementsMap);
416
+ case "ellipse":
417
+ return distanceToEllipse(element, point, elementsMap);
418
+ }
419
+ };
420
+ const distanceToRectangle = (element, point, elementsMap) => {
421
+ const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point, elementsMap);
422
+ return Math.max(GAPoint.distanceToLine(pointRel, GALine.equation(0, 1, -hheight)), GAPoint.distanceToLine(pointRel, GALine.equation(1, 0, -hwidth)));
423
+ };
424
+ const distanceToDiamond = (element, point, elementsMap) => {
425
+ const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point, elementsMap);
426
+ const side = GALine.equation(hheight, hwidth, -hheight * hwidth);
427
+ return GAPoint.distanceToLine(pointRel, side);
428
+ };
429
+ export const distanceToEllipse = (element, point, elementsMap) => {
430
+ const [pointRel, tangent] = ellipseParamsForTest(element, point, elementsMap);
431
+ return -GALine.sign(tangent) * GAPoint.distanceToLine(pointRel, tangent);
432
+ };
433
+ const ellipseParamsForTest = (element, point, elementsMap) => {
434
+ const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point, elementsMap);
435
+ const [px, py] = GAPoint.toTuple(pointRel);
436
+ // We're working in positive quadrant, so start with `t = 45deg`, `tx=cos(t)`
437
+ let tx = 0.707;
438
+ let ty = 0.707;
439
+ const a = hwidth;
440
+ const b = hheight;
441
+ // This is a numerical method to find the params tx, ty at which
442
+ // the ellipse has the closest point to the given point
443
+ [0, 1, 2, 3].forEach((_) => {
444
+ const xx = a * tx;
445
+ const yy = b * ty;
446
+ const ex = ((a * a - b * b) * tx ** 3) / a;
447
+ const ey = ((b * b - a * a) * ty ** 3) / b;
448
+ const rx = xx - ex;
449
+ const ry = yy - ey;
450
+ const qx = px - ex;
451
+ const qy = py - ey;
452
+ const r = Math.hypot(ry, rx);
453
+ const q = Math.hypot(qy, qx);
454
+ tx = Math.min(1, Math.max(0, ((qx * r) / q + ex) / a));
455
+ ty = Math.min(1, Math.max(0, ((qy * r) / q + ey) / b));
456
+ const t = Math.hypot(ty, tx);
457
+ tx /= t;
458
+ ty /= t;
386
459
  });
387
- sceneElements
388
- .filter(({ id }) => affectedElements.has(id))
389
- .forEach((element) => {
390
- if (isBindableElement(element)) {
391
- mutateElement(element, {
392
- boundElements: newBoundElementsAfterDeletion(element.boundElements, deletedElementIds),
393
- });
394
- }
395
- else if (isBindingElement(element)) {
396
- mutateElement(element, {
397
- startBinding: newBindingAfterDeletion(element.startBinding, deletedElementIds),
398
- endBinding: newBindingAfterDeletion(element.endBinding, deletedElementIds),
399
- });
460
+ const closestPoint = GA.point(a * tx, b * ty);
461
+ const tangent = GALine.orthogonalThrough(pointRel, closestPoint);
462
+ return [pointRel, tangent];
463
+ };
464
+ // Returns:
465
+ // 1. the point relative to the elements (x, y) position
466
+ // 2. the point relative to the element's center with positive (x, y)
467
+ // 3. half element width
468
+ // 4. half element height
469
+ //
470
+ // Note that for linear elements the (x, y) position is not at the
471
+ // top right corner of their boundary.
472
+ //
473
+ // Rectangles, diamonds and ellipses are symmetrical over axes,
474
+ // and other elements have a rectangular boundary,
475
+ // so we only need to perform hit tests for the positive quadrant.
476
+ const pointRelativeToElement = (element, pointTuple, elementsMap) => {
477
+ const point = GAPoint.from(pointTuple);
478
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
479
+ const center = coordsCenter(x1, y1, x2, y2);
480
+ // GA has angle orientation opposite to `rotate`
481
+ const rotate = GATransform.rotation(center, element.angle);
482
+ const pointRotated = GATransform.apply(rotate, point);
483
+ const pointRelToCenter = GA.sub(pointRotated, GADirection.from(center));
484
+ const pointRelToCenterAbs = GAPoint.abs(pointRelToCenter);
485
+ const elementPos = GA.offset(element.x, element.y);
486
+ const pointRelToPos = GA.sub(pointRotated, elementPos);
487
+ const halfWidth = (x2 - x1) / 2;
488
+ const halfHeight = (y2 - y1) / 2;
489
+ return [pointRelToPos, pointRelToCenterAbs, halfWidth, halfHeight];
490
+ };
491
+ const relativizationToElementCenter = (element, elementsMap) => {
492
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
493
+ const center = coordsCenter(x1, y1, x2, y2);
494
+ // GA has angle orientation opposite to `rotate`
495
+ const rotate = GATransform.rotation(center, element.angle);
496
+ const translate = GA.reverse(GATransform.translation(GADirection.from(center)));
497
+ return GATransform.compose(rotate, translate);
498
+ };
499
+ const coordsCenter = (x1, y1, x2, y2) => {
500
+ return GA.point((x1 + x2) / 2, (y1 + y2) / 2);
501
+ };
502
+ // The focus distance is the oriented ratio between the size of
503
+ // the `element` and the "focus image" of the element on which
504
+ // all focus points lie, so it's a number between -1 and 1.
505
+ // The line going through `a` and `b` is a tangent to the "focus image"
506
+ // of the element.
507
+ export const determineFocusDistance = (element,
508
+ // Point on the line, in absolute coordinates
509
+ a,
510
+ // Another point on the line, in absolute coordinates (closer to element)
511
+ b, elementsMap) => {
512
+ const relateToCenter = relativizationToElementCenter(element, elementsMap);
513
+ const aRel = GATransform.apply(relateToCenter, GAPoint.from(a));
514
+ const bRel = GATransform.apply(relateToCenter, GAPoint.from(b));
515
+ const line = GALine.through(aRel, bRel);
516
+ const q = element.height / element.width;
517
+ const hwidth = element.width / 2;
518
+ const hheight = element.height / 2;
519
+ const n = line[2];
520
+ const m = line[3];
521
+ const c = line[1];
522
+ const mabs = Math.abs(m);
523
+ const nabs = Math.abs(n);
524
+ let ret;
525
+ switch (element.type) {
526
+ case "rectangle":
527
+ case "image":
528
+ case "text":
529
+ case "iframe":
530
+ case "embeddable":
531
+ case "frame":
532
+ case "magicframe":
533
+ ret = c / (hwidth * (nabs + q * mabs));
534
+ break;
535
+ case "diamond":
536
+ ret = mabs < nabs ? c / (nabs * hwidth) : c / (mabs * hheight);
537
+ break;
538
+ case "ellipse":
539
+ ret = c / (hwidth * Math.sqrt(n ** 2 + q ** 2 * m ** 2));
540
+ break;
541
+ }
542
+ return ret || 0;
543
+ };
544
+ export const determineFocusPoint = (element,
545
+ // The oriented, relative distance from the center of `element` of the
546
+ // returned focusPoint
547
+ focus, adjecentPoint, elementsMap) => {
548
+ if (focus === 0) {
549
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
550
+ const center = coordsCenter(x1, y1, x2, y2);
551
+ return GAPoint.toTuple(center);
552
+ }
553
+ const relateToCenter = relativizationToElementCenter(element, elementsMap);
554
+ const adjecentPointRel = GATransform.apply(relateToCenter, GAPoint.from(adjecentPoint));
555
+ const reverseRelateToCenter = GA.reverse(relateToCenter);
556
+ let point;
557
+ switch (element.type) {
558
+ case "rectangle":
559
+ case "image":
560
+ case "text":
561
+ case "diamond":
562
+ case "iframe":
563
+ case "embeddable":
564
+ case "frame":
565
+ case "magicframe":
566
+ point = findFocusPointForRectangulars(element, focus, adjecentPointRel);
567
+ break;
568
+ case "ellipse":
569
+ point = findFocusPointForEllipse(element, focus, adjecentPointRel);
570
+ break;
571
+ }
572
+ return GAPoint.toTuple(GATransform.apply(reverseRelateToCenter, point));
573
+ };
574
+ // Returns 2 or 0 intersection points between line going through `a` and `b`
575
+ // and the `element`, in ascending order of distance from `a`.
576
+ export const intersectElementWithLine = (element,
577
+ // Point on the line, in absolute coordinates
578
+ a,
579
+ // Another point on the line, in absolute coordinates
580
+ b,
581
+ // If given, the element is inflated by this value
582
+ gap = 0, elementsMap) => {
583
+ const relateToCenter = relativizationToElementCenter(element, elementsMap);
584
+ const aRel = GATransform.apply(relateToCenter, GAPoint.from(a));
585
+ const bRel = GATransform.apply(relateToCenter, GAPoint.from(b));
586
+ const line = GALine.through(aRel, bRel);
587
+ const reverseRelateToCenter = GA.reverse(relateToCenter);
588
+ const intersections = getSortedElementLineIntersections(element, line, aRel, gap);
589
+ return intersections.map((point) => GAPoint.toTuple(GATransform.apply(reverseRelateToCenter, point)));
590
+ };
591
+ const getSortedElementLineIntersections = (element,
592
+ // Relative to element center
593
+ line,
594
+ // Relative to element center
595
+ nearPoint, gap = 0) => {
596
+ let intersections;
597
+ switch (element.type) {
598
+ case "rectangle":
599
+ case "image":
600
+ case "text":
601
+ case "diamond":
602
+ case "iframe":
603
+ case "embeddable":
604
+ case "frame":
605
+ case "magicframe":
606
+ const corners = getCorners(element);
607
+ intersections = corners
608
+ .flatMap((point, i) => {
609
+ const edge = [point, corners[(i + 1) % 4]];
610
+ return intersectSegment(line, offsetSegment(edge, gap));
611
+ })
612
+ .concat(corners.flatMap((point) => getCircleIntersections(point, gap, line)));
613
+ break;
614
+ case "ellipse":
615
+ intersections = getEllipseIntersections(element, gap, line);
616
+ break;
617
+ }
618
+ if (intersections.length < 2) {
619
+ // Ignore the "edge" case of only intersecting with a single corner
620
+ return [];
621
+ }
622
+ const sortedIntersections = intersections.sort((i1, i2) => GAPoint.distance(i1, nearPoint) - GAPoint.distance(i2, nearPoint));
623
+ return [
624
+ sortedIntersections[0],
625
+ sortedIntersections[sortedIntersections.length - 1],
626
+ ];
627
+ };
628
+ const getCorners = (element, scale = 1) => {
629
+ const hx = (scale * element.width) / 2;
630
+ const hy = (scale * element.height) / 2;
631
+ switch (element.type) {
632
+ case "rectangle":
633
+ case "image":
634
+ case "text":
635
+ case "iframe":
636
+ case "embeddable":
637
+ case "frame":
638
+ case "magicframe":
639
+ return [
640
+ GA.point(hx, hy),
641
+ GA.point(hx, -hy),
642
+ GA.point(-hx, -hy),
643
+ GA.point(-hx, hy),
644
+ ];
645
+ case "diamond":
646
+ return [
647
+ GA.point(0, hy),
648
+ GA.point(hx, 0),
649
+ GA.point(0, -hy),
650
+ GA.point(-hx, 0),
651
+ ];
652
+ }
653
+ };
654
+ // Returns intersection of `line` with `segment`, with `segment` moved by
655
+ // `gap` in its polar direction.
656
+ // If intersection coincides with second segment point returns empty array.
657
+ const intersectSegment = (line, segment) => {
658
+ const [a, b] = segment;
659
+ const aDist = GAPoint.distanceToLine(a, line);
660
+ const bDist = GAPoint.distanceToLine(b, line);
661
+ if (aDist * bDist >= 0) {
662
+ // The intersection is outside segment `(a, b)`
663
+ return [];
664
+ }
665
+ return [GAPoint.intersect(line, GALine.through(a, b))];
666
+ };
667
+ const offsetSegment = (segment, distance) => {
668
+ const [a, b] = segment;
669
+ const offset = GATransform.translationOrthogonal(GADirection.fromTo(a, b), distance);
670
+ return [GATransform.apply(offset, a), GATransform.apply(offset, b)];
671
+ };
672
+ const getEllipseIntersections = (element, gap, line) => {
673
+ const a = element.width / 2 + gap;
674
+ const b = element.height / 2 + gap;
675
+ const m = line[2];
676
+ const n = line[3];
677
+ const c = line[1];
678
+ const squares = a * a * m * m + b * b * n * n;
679
+ const discr = squares - c * c;
680
+ if (squares === 0 || discr <= 0) {
681
+ return [];
682
+ }
683
+ const discrRoot = Math.sqrt(discr);
684
+ const xn = -a * a * m * c;
685
+ const yn = -b * b * n * c;
686
+ return [
687
+ GA.point((xn + a * b * n * discrRoot) / squares, (yn - a * b * m * discrRoot) / squares),
688
+ GA.point((xn - a * b * n * discrRoot) / squares, (yn + a * b * m * discrRoot) / squares),
689
+ ];
690
+ };
691
+ export const getCircleIntersections = (center, radius, line) => {
692
+ if (radius === 0) {
693
+ return GAPoint.distanceToLine(line, center) === 0 ? [center] : [];
694
+ }
695
+ const m = line[2];
696
+ const n = line[3];
697
+ const c = line[1];
698
+ const [a, b] = GAPoint.toTuple(center);
699
+ const r = radius;
700
+ const squares = m * m + n * n;
701
+ const discr = r * r * squares - (m * a + n * b + c) ** 2;
702
+ if (squares === 0 || discr <= 0) {
703
+ return [];
704
+ }
705
+ const discrRoot = Math.sqrt(discr);
706
+ const xn = a * n * n - b * m * n - m * c;
707
+ const yn = b * m * m - a * m * n - n * c;
708
+ return [
709
+ GA.point((xn + n * discrRoot) / squares, (yn - m * discrRoot) / squares),
710
+ GA.point((xn - n * discrRoot) / squares, (yn + m * discrRoot) / squares),
711
+ ];
712
+ };
713
+ // The focus point is the tangent point of the "focus image" of the
714
+ // `element`, where the tangent goes through `point`.
715
+ export const findFocusPointForEllipse = (ellipse,
716
+ // Between -1 and 1 (not 0) the relative size of the "focus image" of
717
+ // the element on which the focus point lies
718
+ relativeDistance,
719
+ // The point for which we're trying to find the focus point, relative
720
+ // to the ellipse center.
721
+ point) => {
722
+ const relativeDistanceAbs = Math.abs(relativeDistance);
723
+ const a = (ellipse.width * relativeDistanceAbs) / 2;
724
+ const b = (ellipse.height * relativeDistanceAbs) / 2;
725
+ const orientation = Math.sign(relativeDistance);
726
+ const [px, pyo] = GAPoint.toTuple(point);
727
+ // The calculation below can't handle py = 0
728
+ const py = pyo === 0 ? 0.0001 : pyo;
729
+ const squares = px ** 2 * b ** 2 + py ** 2 * a ** 2;
730
+ // Tangent mx + ny + 1 = 0
731
+ const m = (-px * b ** 2 +
732
+ orientation * py * Math.sqrt(Math.max(0, squares - a ** 2 * b ** 2))) /
733
+ squares;
734
+ let n = (-m * px - 1) / py;
735
+ if (n === 0) {
736
+ // if zero {-0, 0}, fall back to a same-sign value in the similar range
737
+ n = (Object.is(n, -0) ? -1 : 1) * 0.01;
738
+ }
739
+ const x = -(a ** 2 * m) / (n ** 2 * b ** 2 + m ** 2 * a ** 2);
740
+ return GA.point(x, (-m * x - 1) / n);
741
+ };
742
+ export const findFocusPointForRectangulars = (element,
743
+ // Between -1 and 1 for how far away should the focus point be relative
744
+ // to the size of the element. Sign determines orientation.
745
+ relativeDistance,
746
+ // The point for which we're trying to find the focus point, relative
747
+ // to the element center.
748
+ point) => {
749
+ const relativeDistanceAbs = Math.abs(relativeDistance);
750
+ const orientation = Math.sign(relativeDistance);
751
+ const corners = getCorners(element, relativeDistanceAbs);
752
+ let maxDistance = 0;
753
+ let tangentPoint = null;
754
+ corners.forEach((corner) => {
755
+ const distance = orientation * GALine.through(point, corner)[1];
756
+ if (distance > maxDistance) {
757
+ maxDistance = distance;
758
+ tangentPoint = corner;
400
759
  }
401
760
  });
761
+ return tangentPoint;
402
762
  };
403
- const newBindingAfterDeletion = (binding, deletedElementIds) => {
404
- if (binding == null || deletedElementIds.has(binding.elementId)) {
405
- return null;
763
+ export const bindingProperties = new Set([
764
+ "boundElements",
765
+ "frameId",
766
+ "containerId",
767
+ "startBinding",
768
+ "endBinding",
769
+ ]);
770
+ /**
771
+ * Tries to visit each bound element (does not have to be found).
772
+ */
773
+ const boundElementsVisitor = (elements, element, visit) => {
774
+ if (isBindableElement(element)) {
775
+ // create new instance so that possible mutations won't play a role in visiting order
776
+ const boundElements = element.boundElements?.slice() ?? [];
777
+ // last added text should be the one we keep (~previous are duplicates)
778
+ boundElements.forEach(({ id }) => {
779
+ visit(elements.get(id), "boundElements", id);
780
+ });
406
781
  }
407
- return binding;
408
782
  };
409
- const newBoundElementsAfterDeletion = (boundElements, deletedElementIds) => {
410
- if (!boundElements) {
411
- return null;
783
+ /**
784
+ * Tries to visit each bindable element (does not have to be found).
785
+ */
786
+ const bindableElementsVisitor = (elements, element, visit) => {
787
+ if (element.frameId) {
788
+ const id = element.frameId;
789
+ visit(elements.get(id), "frameId", id);
790
+ }
791
+ if (isBoundToContainer(element)) {
792
+ const id = element.containerId;
793
+ visit(elements.get(id), "containerId", id);
794
+ }
795
+ if (isArrowElement(element)) {
796
+ if (element.startBinding) {
797
+ const id = element.startBinding.elementId;
798
+ visit(elements.get(id), "startBinding", id);
799
+ }
800
+ if (element.endBinding) {
801
+ const id = element.endBinding.elementId;
802
+ visit(elements.get(id), "endBinding", id);
803
+ }
412
804
  }
413
- return boundElements.filter((ele) => !deletedElementIds.has(ele.id));
414
805
  };
806
+ /**
807
+ * Bound element containing bindings to `frameId`, `containerId`, `startBinding` or `endBinding`.
808
+ */
809
+ export class BoundElement {
810
+ /**
811
+ * Unbind the affected non deleted bindable elements (removing element from `boundElements`).
812
+ * - iterates non deleted bindable elements (`containerId` | `startBinding.elementId` | `endBinding.elementId`) of the current element
813
+ * - prepares updates to unbind each bindable element's `boundElements` from the current element
814
+ */
815
+ static unbindAffected(elements, boundElement, updateElementWith) {
816
+ if (!boundElement) {
817
+ return;
818
+ }
819
+ bindableElementsVisitor(elements, boundElement, (bindableElement) => {
820
+ // bindable element is deleted, this is fine
821
+ if (!bindableElement || bindableElement.isDeleted) {
822
+ return;
823
+ }
824
+ boundElementsVisitor(elements, bindableElement, (_, __, boundElementId) => {
825
+ if (boundElementId === boundElement.id) {
826
+ updateElementWith(bindableElement, {
827
+ boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElementId])),
828
+ });
829
+ }
830
+ });
831
+ });
832
+ }
833
+ /**
834
+ * Rebind the next affected non deleted bindable elements (adding element to `boundElements`).
835
+ * - iterates non deleted bindable elements (`containerId` | `startBinding.elementId` | `endBinding.elementId`) of the current element
836
+ * - prepares updates to rebind each bindable element's `boundElements` to the current element
837
+ *
838
+ * NOTE: rebind expects that affected elements were previously unbound with `BoundElement.unbindAffected`
839
+ */
840
+ static rebindAffected = (elements, boundElement, updateElementWith) => {
841
+ // don't try to rebind element that is deleted
842
+ if (!boundElement || boundElement.isDeleted) {
843
+ return;
844
+ }
845
+ bindableElementsVisitor(elements, boundElement, (bindableElement, bindingProp) => {
846
+ // unbind from bindable elements, as bindings from non deleted elements into deleted elements are incorrect
847
+ if (!bindableElement || bindableElement.isDeleted) {
848
+ updateElementWith(boundElement, { [bindingProp]: null });
849
+ return;
850
+ }
851
+ // frame bindings are unidirectional, there is nothing to rebind
852
+ if (bindingProp === "frameId") {
853
+ return;
854
+ }
855
+ if (bindableElement.boundElements?.find((x) => x.id === boundElement.id)) {
856
+ return;
857
+ }
858
+ if (isArrowElement(boundElement)) {
859
+ // rebind if not found!
860
+ updateElementWith(bindableElement, {
861
+ boundElements: newBoundElements(bindableElement.boundElements, new Set(), new Array(boundElement)),
862
+ });
863
+ }
864
+ if (isTextElement(boundElement)) {
865
+ if (!bindableElement.boundElements?.find((x) => x.type === "text")) {
866
+ // rebind only if there is no other text bound already
867
+ updateElementWith(bindableElement, {
868
+ boundElements: newBoundElements(bindableElement.boundElements, new Set(), new Array(boundElement)),
869
+ });
870
+ }
871
+ else {
872
+ // unbind otherwise
873
+ updateElementWith(boundElement, { [bindingProp]: null });
874
+ }
875
+ }
876
+ });
877
+ };
878
+ }
879
+ /**
880
+ * Bindable element containing bindings to `boundElements`.
881
+ */
882
+ export class BindableElement {
883
+ /**
884
+ * Unbind the affected non deleted bound elements (resetting `containerId`, `startBinding`, `endBinding` to `null`).
885
+ * - iterates through non deleted `boundElements` of the current element
886
+ * - prepares updates to unbind each bound element from the current element
887
+ */
888
+ static unbindAffected(elements, bindableElement, updateElementWith) {
889
+ if (!bindableElement) {
890
+ return;
891
+ }
892
+ boundElementsVisitor(elements, bindableElement, (boundElement) => {
893
+ // bound element is deleted, this is fine
894
+ if (!boundElement || boundElement.isDeleted) {
895
+ return;
896
+ }
897
+ bindableElementsVisitor(elements, boundElement, (_, bindingProp, bindableElementId) => {
898
+ // making sure there is an element to be unbound
899
+ if (bindableElementId === bindableElement.id) {
900
+ updateElementWith(boundElement, { [bindingProp]: null });
901
+ }
902
+ });
903
+ });
904
+ }
905
+ /**
906
+ * Rebind the affected non deleted bound elements (for now setting only `containerId`, as we cannot rebind arrows atm).
907
+ * - iterates through non deleted `boundElements` of the current element
908
+ * - prepares updates to rebind each bound element to the current element or unbind it from `boundElements` in case of conflicts
909
+ *
910
+ * NOTE: rebind expects that affected elements were previously unbound with `BindaleElement.unbindAffected`
911
+ */
912
+ static rebindAffected = (elements, bindableElement, updateElementWith) => {
913
+ // don't try to rebind element that is deleted (i.e. updated as deleted)
914
+ if (!bindableElement || bindableElement.isDeleted) {
915
+ return;
916
+ }
917
+ boundElementsVisitor(elements, bindableElement, (boundElement, _, boundElementId) => {
918
+ // unbind from bindable elements, as bindings from non deleted elements into deleted elements are incorrect
919
+ if (!boundElement || boundElement.isDeleted) {
920
+ updateElementWith(bindableElement, {
921
+ boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElementId])),
922
+ });
923
+ return;
924
+ }
925
+ if (isTextElement(boundElement)) {
926
+ const boundElements = bindableElement.boundElements?.slice() ?? [];
927
+ // check if this is the last element in the array, if not, there is an previously bound text which should be unbound
928
+ if (boundElements.reverse().find((x) => x.type === "text")?.id ===
929
+ boundElement.id) {
930
+ if (boundElement.containerId !== bindableElement.id) {
931
+ // rebind if not bound already!
932
+ updateElementWith(boundElement, {
933
+ containerId: bindableElement.id,
934
+ });
935
+ }
936
+ }
937
+ else {
938
+ if (boundElement.containerId !== null) {
939
+ // unbind if not unbound already
940
+ updateElementWith(boundElement, {
941
+ containerId: null,
942
+ });
943
+ }
944
+ // unbind from boundElements as the element got bound to some other element in the meantime
945
+ updateElementWith(bindableElement, {
946
+ boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElement.id])),
947
+ });
948
+ }
949
+ }
950
+ });
951
+ };
952
+ }