@jackuait/blok 0.10.0-beta.6 → 0.10.0-beta.7
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.
- package/codemod/migrate-editorjs-to-blok.js +0 -2
- package/codemod/test.js +0 -6
- package/dist/blok.mjs +2 -2
- package/dist/chunks/_basePickBy-BHRNO12X.mjs +410 -0
- package/dist/chunks/_baseUniq-DtFPDBML.mjs +1045 -0
- package/dist/chunks/_getTag-ozrhqxk_.mjs +26 -0
- package/dist/chunks/arc-BEqJP9HX.mjs +80 -0
- package/dist/chunks/architecture-YZFGNWBL-Bcu-90pi.mjs +3 -0
- package/dist/chunks/architectureDiagram-Q4EWVU46-BMno5LCn.mjs +4066 -0
- package/dist/chunks/array-Cyf-61SV.mjs +6 -0
- package/dist/chunks/blockDiagram-DXYQGD6D-DlP_cPth.mjs +3259 -0
- package/dist/chunks/{blok-BdlR_lX6.mjs → blok-CiLRmoHI.mjs} +850 -855
- package/dist/chunks/c4Diagram-AHTNJAMY-BbVV8EXj.mjs +2956 -0
- package/dist/chunks/channel-DPcniO2B.mjs +5 -0
- package/dist/chunks/chunk-2KRD3SAO-CazES4VS.mjs +20 -0
- package/dist/chunks/chunk-336JU56O-heO72r_k.mjs +49 -0
- package/dist/chunks/chunk-426QAEUC-CmCcml1z.mjs +13 -0
- package/dist/chunks/chunk-4BX2VUAB-B10DxOza.mjs +19 -0
- package/dist/chunks/chunk-4TB4RGXK-B0snhZOU.mjs +3250 -0
- package/dist/chunks/chunk-55IACEB6-CGkn5ABd.mjs +8 -0
- package/dist/chunks/chunk-5FUZZQ4R-USdumo_u.mjs +3786 -0
- package/dist/chunks/chunk-5PVQY5BW-CxUGVzQL.mjs +1692 -0
- package/dist/chunks/chunk-67CJDMHE-Bvw55oRa.mjs +20 -0
- package/dist/chunks/chunk-7N4EOEYR-Bs2qDy88.mjs +29 -0
- package/dist/chunks/chunk-AA7GKIK3-Bss0LgrN.mjs +24 -0
- package/dist/chunks/chunk-BSJP7CBP-CpUW7gi5.mjs +83 -0
- package/dist/chunks/chunk-CIAEETIT-DlRbLLf3.mjs +20 -0
- package/dist/chunks/{chunk-Byubey_H.mjs → chunk-D6kmoKXy.mjs} +5 -5
- package/dist/chunks/chunk-EDXVE4YY-DEcX4XWm.mjs +26 -0
- package/dist/chunks/chunk-ENJZ2VHE-B4THRZkR.mjs +566 -0
- package/dist/chunks/chunk-FMBD7UC4-CF6BKEiV.mjs +5 -0
- package/dist/chunks/chunk-FOC6F5B3--xuza7Yn.mjs +20 -0
- package/dist/chunks/chunk-ICPOFSXX-BMja8cuy.mjs +3290 -0
- package/dist/chunks/chunk-K5T4RW27-CHEqGHFS.mjs +16370 -0
- package/dist/chunks/chunk-KGLVRYIC-DHYYpR8v.mjs +20 -0
- package/dist/chunks/chunk-LIHQZDEY-AvbOvyLE.mjs +55 -0
- package/dist/chunks/chunk-ORNJ4GCN-38fbR5OS.mjs +25 -0
- package/dist/chunks/chunk-OYMX7WX6-BiqlATPA.mjs +2038 -0
- package/dist/chunks/chunk-QZHKN3VN-DitZIvj8.mjs +12 -0
- package/dist/chunks/chunk-U2HBQHQK-DJytnHmZ.mjs +1875 -0
- package/dist/chunks/chunk-X2U36JSP-DlOifw1K.mjs +68 -0
- package/dist/chunks/chunk-XPW4576I-s4fsi4XO.mjs +1146 -0
- package/dist/chunks/chunk-YZCP3GAM-Ch258bXC.mjs +60 -0
- package/dist/chunks/chunk-ZZ45TVLE-DWziaKxP.mjs +33 -0
- package/dist/chunks/classDiagram-6PBFFD2Q-BOkAe08u.mjs +30 -0
- package/dist/chunks/classDiagram-v2-HSJHXN6E-DeKatSvh.mjs +30 -0
- package/dist/chunks/clone-CJCz7VRp.mjs +8 -0
- package/dist/chunks/{constants-Cp8O0UfP.mjs → constants-DFS8l39Y.mjs} +49 -50
- package/dist/chunks/cose-bilkent-S5V4N54A-CzLGVqvr.mjs +2246 -0
- package/dist/chunks/cytoscape.esm-D0iglm-M.mjs +18108 -0
- package/dist/chunks/dagre-KV5264BT-XbHSjleO.mjs +298 -0
- package/dist/chunks/dagre-XY8CZ1sg.mjs +1536 -0
- package/dist/chunks/defaultLocale-DFhS1600.mjs +201 -0
- package/dist/chunks/diagram-5BDNPKRD-CM7c3UTI.mjs +112 -0
- package/dist/chunks/diagram-G4DWMVQ6-Bhg4ps6b.mjs +546 -0
- package/dist/chunks/diagram-MMDJMWI5-C-UCVaxB.mjs +234 -0
- package/dist/chunks/diagram-TYMM5635-BOHSujSD.mjs +144 -0
- package/dist/chunks/dist-DHsXIYdd.mjs +59 -0
- package/dist/chunks/erDiagram-SMLLAGMA-CwKxXFMB.mjs +1712 -0
- package/dist/chunks/flowDiagram-DWJPFMVM-rQJKfyuO.mjs +4175 -0
- package/dist/chunks/ganttDiagram-T4ZO3ILL-DfaZirLX.mjs +3083 -0
- package/dist/chunks/gitGraph-7Q5UKJZL-BKG8cHGz.mjs +3 -0
- package/dist/chunks/gitGraphDiagram-UUTBAWPF-CRa-ymsI.mjs +792 -0
- package/dist/chunks/graphlib-CuDElSdG.mjs +223 -0
- package/dist/chunks/{i18next-loader-oDO9ZKUV.mjs → i18next-loader-CasQQb5s.mjs} +2 -2
- package/dist/chunks/info-OMHHGYJF-FKqYyUn9.mjs +3 -0
- package/dist/chunks/infoDiagram-42DDH7IO-CvyJU2nE.mjs +29 -0
- package/dist/chunks/init-JlKGZtuT.mjs +15 -0
- package/dist/chunks/ishikawaDiagram-UXIWVN3A-CIpbw1BK.mjs +719 -0
- package/dist/chunks/journeyDiagram-VCZTEJTY-H96UcUK9.mjs +885 -0
- package/dist/chunks/kanban-definition-6JOO6SKY-BYZT3srA.mjs +980 -0
- package/dist/chunks/{katex-NjLaA6AJ.mjs → katex-JyOgX6MW.mjs} +1 -1
- package/dist/chunks/{lightweight-i18n-DTySD6f6.mjs → lightweight-i18n-Cvv8CWh4.mjs} +13 -0
- package/dist/chunks/line-B9xUUA7k.mjs +34 -0
- package/dist/chunks/linear-Dj-1yA_B.mjs +289 -0
- package/dist/chunks/mermaid-parser.core-D6OPAUtM.mjs +57 -0
- package/dist/chunks/mermaid.core-BPN9ZHKQ.mjs +989 -0
- package/dist/{messages-B4lhNMKm2.mjs → chunks/messages--YKhFEDE.mjs} +28 -3
- package/dist/chunks/{messages-CF_PfacZ.mjs → messages-0Uwu1AMJ2.mjs} +26 -1
- package/dist/{messages-Bug6Du35.mjs → chunks/messages-1__0Ph4Q.mjs} +26 -1
- package/dist/chunks/{messages-CnQydQJd2.mjs → messages-4sm9Pb0C.mjs} +26 -1
- package/dist/chunks/{messages-BDXl53cy2.mjs → messages-4uxjtzKW.mjs} +26 -1
- package/dist/{messages-DQN1y6E9.mjs → chunks/messages-B-SwLgkQ.mjs} +28 -3
- package/dist/chunks/{messages-BlcRm2I3.mjs → messages-B1ylBxXQ.mjs} +26 -1
- package/dist/{messages-12_eyAo-.mjs → chunks/messages-B5m3dhKc.mjs} +26 -1
- package/dist/chunks/{messages-D8-N0FmU.mjs → messages-B6n2zDtv.mjs} +27 -2
- package/dist/chunks/{messages-BMq9k_lI.mjs → messages-BC9w4zAT.mjs} +26 -1
- package/dist/{messages-CsiGzUSP2.mjs → chunks/messages-BOj-7N3p.mjs} +26 -1
- package/dist/chunks/{messages-CvlMT1e62.mjs → messages-BRYHTS18.mjs} +26 -1
- package/dist/{messages-hrSlVSHp.mjs → chunks/messages-BSBbVjor.mjs} +33 -8
- package/dist/{messages-uCsQjz7M.mjs → chunks/messages-BUUkmUGc.mjs} +26 -1
- package/dist/chunks/{messages-DopbvJlg.mjs → messages-Bb3YEV2P.mjs} +31 -6
- package/dist/{messages-KqWQKmIu2.mjs → chunks/messages-Be_6YLzJ.mjs} +27 -2
- package/dist/chunks/{messages-BXn9Vzbx2.mjs → messages-BevRhv5d.mjs} +26 -1
- package/dist/chunks/{messages-DQ5ng0_t2.mjs → messages-Bhqr7Im2.mjs} +26 -1
- package/dist/{messages-B3Yhiycb2.mjs → chunks/messages-BpJFjSKa.mjs} +27 -2
- package/dist/chunks/{messages-BaoJwsEZ.mjs → messages-BqYlq_Bn.mjs} +26 -1
- package/dist/chunks/{messages-vN4T4r67.mjs → messages-BtAwCUfD.mjs} +26 -1
- package/dist/{messages-Cb3wXGnc.mjs → chunks/messages-Bthbp65G.mjs} +27 -2
- package/dist/{messages-x353UCBI.mjs → chunks/messages-BvHMZ8Pi2.mjs} +26 -1
- package/dist/{messages-BOE2mzCj2.mjs → chunks/messages-Bw1BE9jW.mjs} +26 -1
- package/dist/chunks/{messages-C5aCWL7B.mjs → messages-Bx6Wt285.mjs} +26 -1
- package/dist/{messages-C8f1I5EQ2.mjs → chunks/messages-BzslJRYv.mjs} +27 -2
- package/dist/chunks/{messages-CZ5Sbf8U.mjs → messages-C02M0Tpw.mjs} +26 -1
- package/dist/chunks/{messages-DN-194c32.mjs → messages-C1u3E9qg.mjs} +26 -1
- package/dist/chunks/{messages-DdmWzF5M.mjs → messages-C68WgSKk.mjs} +27 -2
- package/dist/chunks/{messages-Dgng6KN8.mjs → messages-C8w8JCP0.mjs} +28 -3
- package/dist/chunks/{messages-B5fKJXd6.mjs → messages-CFOZdSk4.mjs} +26 -1
- package/dist/chunks/{messages-5ArOv8cj.mjs → messages-CGOY79lr.mjs} +26 -1
- package/dist/{messages-mipkPgwQ2.mjs → chunks/messages-CGaSMZPu.mjs} +26 -1
- package/dist/{messages-Dq_v7slw2.mjs → chunks/messages-CJJgQ0BH.mjs} +26 -1
- package/dist/chunks/{messages-DUGEqDEG.mjs → messages-CTD6rtQj2.mjs} +26 -1
- package/dist/{messages-DIKCwGog.mjs → chunks/messages-CZymJML9.mjs} +30 -5
- package/dist/chunks/{messages-CcyIKgGU.mjs → messages-CfeFJbiv.mjs} +30 -5
- package/dist/chunks/{messages-BXSXk3oS2.mjs → messages-Cgatzu_z.mjs} +28 -3
- package/dist/{messages-CBPiFbEf2.mjs → chunks/messages-Ch2zBI602.mjs} +26 -1
- package/dist/chunks/{messages-yszqJukE.mjs → messages-CiAHsUfO.mjs} +26 -1
- package/dist/chunks/{messages-bmwto4UV.mjs → messages-Cuzq-tNW.mjs} +26 -1
- package/dist/{messages-JK9Okzsy2.mjs → chunks/messages-Cw4qiMwb.mjs} +26 -1
- package/dist/chunks/{messages-DSO2U-ul.mjs → messages-Cyh-mz40.mjs} +26 -1
- package/dist/{messages-DbZsJAff.mjs → chunks/messages-D-I2QO8H.mjs} +26 -1
- package/dist/chunks/{messages-BhcYsC_M2.mjs → messages-D0D2gruy.mjs} +26 -1
- package/dist/{messages-X80Nh0ib.mjs → chunks/messages-D1BKxfLD.mjs} +27 -2
- package/dist/chunks/{messages-CjVPwkVy.mjs → messages-D4eDs6R_.mjs} +26 -1
- package/dist/{messages-C5Uufygq.mjs → chunks/messages-D9Xr-hES.mjs} +26 -1
- package/dist/{messages-DkvQ-6HC2.mjs → chunks/messages-D9eJPHia.mjs} +28 -3
- package/dist/chunks/{messages-DRv4g-IA.mjs → messages-DBFWSzKY2.mjs} +26 -1
- package/dist/chunks/{messages-SSDr5fGF2.mjs → messages-DC0wu2S7.mjs} +26 -1
- package/dist/{messages-Bdk4ocMI.mjs → chunks/messages-DF9o19rG.mjs} +26 -1
- package/dist/chunks/{messages-DVKifYlq.mjs → messages-DFS_n986.mjs} +49 -24
- package/dist/{messages-CvvbLyTy2.mjs → chunks/messages-DGS4H30T.mjs} +26 -1
- package/dist/{messages-PvMdmlxI.mjs → chunks/messages-DKjddpzJ.mjs} +28 -3
- package/dist/chunks/{messages-DGD6BiGd.mjs → messages-DMvTdUXC.mjs} +28 -3
- package/dist/{messages-CD8K1g_t2.mjs → chunks/messages-DQUX-QYI2.mjs} +26 -1
- package/dist/chunks/{messages-CqgEz7C5.mjs → messages-DUigq8FO2.mjs} +26 -1
- package/dist/chunks/{messages-ByAqzAhB.mjs → messages-DY0FJdpH.mjs} +26 -1
- package/dist/{messages-DACg1XAu.mjs → chunks/messages-DfVXiqt-2.mjs} +26 -1
- package/dist/{messages-BYQ769S5.mjs → chunks/messages-DgZc9TJw.mjs} +26 -1
- package/dist/{messages-Dj79y02X.mjs → chunks/messages-QD4BCUDP.mjs} +26 -1
- package/dist/{messages-BeI2HORe2.mjs → chunks/messages-USmweex9.mjs} +26 -1
- package/dist/{messages-CEEzfqMO2.mjs → chunks/messages-a1JTi0Qm.mjs} +29 -4
- package/dist/chunks/{messages-Dz3UhEco2.mjs → messages-jcgCHPRn.mjs} +26 -1
- package/dist/{messages--cUQf9JX.mjs → chunks/messages-tnnqHpbd.mjs} +27 -2
- package/dist/chunks/{messages-DZwCufSb.mjs → messages-vzWKPLJO.mjs} +26 -1
- package/dist/chunks/{micromark-extension-math-CCEGWpdz.mjs → micromark-extension-math-Cz_ZZ_0Y.mjs} +1 -1
- package/dist/chunks/mindmap-definition-QFDTVHPH-BswFuNN6.mjs +1013 -0
- package/dist/chunks/ordinal-D1_lEgAO.mjs +65 -0
- package/dist/chunks/packet-4T2RLAQJ-DTUW2U0C.mjs +3 -0
- package/dist/chunks/path-6nYPAvNb.mjs +85 -0
- package/dist/chunks/pie-ZZUOXDRM-D-umqvEM.mjs +3 -0
- package/dist/chunks/pieDiagram-DEJITSTG-1WJgvK1w.mjs +179 -0
- package/dist/chunks/quadrantDiagram-34T5L4WZ-B_YH8QGl.mjs +1960 -0
- package/dist/chunks/radar-PYXPWWZC-DkQelf08.mjs +3 -0
- package/dist/chunks/requirementDiagram-MS252O5E-DRl0YJRI.mjs +2224 -0
- package/dist/chunks/rough.esm-CSWJruu5.mjs +1353 -0
- package/dist/chunks/sankeyDiagram-XADWPNL6-B-8IrknH.mjs +909 -0
- package/dist/chunks/sequenceDiagram-FGHM5R23-DTLb8qmO.mjs +4181 -0
- package/dist/chunks/src-CRgEHLPW.mjs +2149 -0
- package/dist/chunks/stateDiagram-FHFEXIEX-B0JFjLFy.mjs +218 -0
- package/dist/chunks/stateDiagram-v2-QKLJ7IA2-Co9CUU_z.mjs +28 -0
- package/dist/chunks/timeline-definition-GMOUNBTQ-CS9KTh-Q.mjs +1084 -0
- package/dist/chunks/{tools-DGOsJbHH.mjs → tools-CSYsrnud.mjs} +2116 -1268
- package/dist/chunks/treeView-SZITEDCU-DOOoyNP9.mjs +3 -0
- package/dist/chunks/treemap-W4RFUUIX-CsOoUA-u.mjs +3 -0
- package/dist/chunks/vennDiagram-DHZGUBPP-0BNu5Wna.mjs +1876 -0
- package/dist/chunks/wardley-RL74JXVD-CCzZcmEk.mjs +3 -0
- package/dist/chunks/wardleyDiagram-NUSXRM2D-Ca9XByNH.mjs +594 -0
- package/dist/chunks/xychartDiagram-5P7HB3ND-C8AyKUAE.mjs +2017 -0
- package/dist/cli.mjs +1 -1
- package/dist/full.mjs +3 -3
- package/dist/locales.mjs +80 -67
- package/dist/markdown.mjs +2 -2
- package/dist/{chunks/messages-9l49jauY.mjs → messages-5jvKxQNu2.mjs} +26 -1
- package/dist/{messages-CkySRhtd2.mjs → messages-7QD-X6XT2.mjs} +26 -1
- package/dist/{chunks/messages-Btr121zI2.mjs → messages-96iaAUds2.mjs} +27 -2
- package/dist/{chunks/messages-BAP2OAQk.mjs → messages-B19o-Teb.mjs} +28 -3
- package/dist/{messages-DJU4YLij.mjs → messages-B1ZUQagA.mjs} +26 -1
- package/dist/{messages-Dg2CDXZi2.mjs → messages-B7ieAJBd2.mjs} +26 -1
- package/dist/{messages-CByBLxWk.mjs → messages-BECMxmfX.mjs} +26 -1
- package/dist/{messages-CwCEcbWG.mjs → messages-BIHc0KHY.mjs} +27 -2
- package/dist/{messages-D8WvwU42.mjs → messages-BIoeoik5.mjs} +26 -1
- package/dist/{messages-D38h5XlF.mjs → messages-BJeGJksD.mjs} +26 -1
- package/dist/{messages-Cd23UgLV2.mjs → messages-BRZX964b2.mjs} +27 -2
- package/dist/{chunks/messages-B9N__q552.mjs → messages-BTQPpoM42.mjs} +29 -4
- package/dist/{messages-CUzBNjnc.mjs → messages-BYNcD6uR.mjs} +26 -1
- package/dist/{messages-DjWfVYHS2.mjs → messages-BYmmMDrN2.mjs} +26 -1
- package/dist/{chunks/messages-DkTxBa1V.mjs → messages-BbYq1pk-.mjs} +26 -1
- package/dist/{chunks/messages-BHhbHLoq.mjs → messages-BiUGXvYr2.mjs} +26 -1
- package/dist/{messages-So3SHdIc2.mjs → messages-BiiongNz2.mjs} +26 -1
- package/dist/{chunks/messages-BxBID_0B.mjs → messages-Bm0Feca1.mjs} +30 -5
- package/dist/{messages-C2veeQpU.mjs → messages-BmAn22OX.mjs} +26 -1
- package/dist/{messages-KbYSpNrE.mjs → messages-Bq3F2Tp_.mjs} +26 -1
- package/dist/{chunks/messages-Dux1S0-D2.mjs → messages-BsycN_JI2.mjs} +26 -1
- package/dist/{messages-DRU_IgoW.mjs → messages-BwHs4cm1.mjs} +30 -5
- package/dist/{messages-Cv-DKlZd.mjs → messages-CJTy6JZt.mjs} +26 -1
- package/dist/{chunks/messages-D7n_wJK7.mjs → messages-CR_L_UtK.mjs} +26 -1
- package/dist/{messages-DnhEzmXJ2.mjs → messages-CSUHBs4c2.mjs} +26 -1
- package/dist/{messages-C_HmWyXc2.mjs → messages-CWIXvnDf2.mjs} +26 -1
- package/dist/{messages-KSxF8eib.mjs → messages-CcF4y-E4.mjs} +26 -1
- package/dist/{chunks/messages-CL3mCbi6.mjs → messages-Ce6KVEbT.mjs} +27 -2
- package/dist/{chunks/messages-C-jA6Rf7.mjs → messages-Ci0KqX-J.mjs} +33 -8
- package/dist/{chunks/messages-DMyRdafk2.mjs → messages-CjbnogEC.mjs} +26 -1
- package/dist/{chunks/messages-BlO_37l_.mjs → messages-CmB406HW.mjs} +28 -3
- package/dist/{messages-Cho2VTAX.mjs → messages-CqXtJTpU.mjs} +26 -1
- package/dist/{messages-CWEL1WDy2.mjs → messages-D0aw5_0k2.mjs} +28 -3
- package/dist/{messages-CgEDVri-2.mjs → messages-D8FQWulF2.mjs} +26 -1
- package/dist/{chunks/messages-B5aAzExz.mjs → messages-DBiVgUs2.mjs} +27 -2
- package/dist/{chunks/messages-DYizZHT2.mjs → messages-DIJlIqlQ2.mjs} +26 -1
- package/dist/{messages-BPL7riv-.mjs → messages-DLX_iBDJ.mjs} +26 -1
- package/dist/{messages-vptt-pVF.mjs → messages-DLlc9QPw.mjs} +26 -1
- package/dist/{chunks/messages-876bKyUj2.mjs → messages-DMr62KiO2.mjs} +26 -1
- package/dist/{chunks/messages-CgedvWCf.mjs → messages-DPA-mMWC2.mjs} +27 -2
- package/dist/{messages-vcoib5Ga.mjs → messages-DTh9a8mR.mjs} +26 -1
- package/dist/{chunks/messages-DgEGJECT.mjs → messages-DY4IqlhY.mjs} +26 -1
- package/dist/{chunks/messages-CdzF0Hvl.mjs → messages-DYTTu0O12.mjs} +26 -1
- package/dist/{messages-rbox5gSb2.mjs → messages-DbySKTKt2.mjs} +28 -3
- package/dist/{chunks/messages-BGCQCeWd.mjs → messages-Ddnj2iTG2.mjs} +26 -1
- package/dist/{chunks/messages-CNEJxD8q2.mjs → messages-DkLU_rWm.mjs} +26 -1
- package/dist/{chunks/messages-FYl9woii2.mjs → messages-Dl3Sv6Rq2.mjs} +27 -2
- package/dist/{messages-Clsh86WQ.mjs → messages-Dl5Y2-Ia.mjs} +49 -24
- package/dist/{chunks/messages-CKRJDX0K2.mjs → messages-DnG0ef8t2.mjs} +28 -3
- package/dist/{chunks/messages-CyxDkx8a.mjs → messages-DnGJD4TL.mjs} +26 -1
- package/dist/{chunks/messages-DnJHflSh.mjs → messages-Dnp9N6RU2.mjs} +26 -1
- package/dist/{chunks/messages-Jps5Tc77.mjs → messages-Dvn35ksS.mjs} +26 -1
- package/dist/{messages-ChTWmxS8.mjs → messages-Dw__BcTj.mjs} +26 -1
- package/dist/{messages-D7juvhHp.mjs → messages-Dy-Y_nEI.mjs} +26 -1
- package/dist/{messages-CNNcKuGH.mjs → messages-E_ZuzGDt.mjs} +26 -1
- package/dist/{chunks/messages-DJO0ERQT.mjs → messages-F2xRoY1w.mjs} +26 -1
- package/dist/{messages-DqJTZbwt.mjs → messages-Smt4GBbj.mjs} +31 -6
- package/dist/{chunks/messages-D8dKkyII2.mjs → messages-aMXpHt5X2.mjs} +26 -1
- package/dist/{chunks/messages-DWD0ry9x.mjs → messages-aWZH50vu2.mjs} +28 -3
- package/dist/{chunks/messages-BbfLRqLh2.mjs → messages-dv19AkyJ.mjs} +26 -1
- package/dist/{chunks/messages-Dw2rmKMi2.mjs → messages-hWwSRF-2.mjs} +26 -1
- package/dist/{messages-En8LDjUB.mjs → messages-j7o5rT9s.mjs} +26 -1
- package/dist/{chunks/messages-NJsvFwJj.mjs → messages-nUVjeh7K.mjs} +27 -2
- package/dist/{messages-Cg1CF4pw.mjs → messages-nlhESX9t.mjs} +26 -1
- package/dist/{messages-CSl0Wla62.mjs → messages-rk-A1Wa42.mjs} +28 -3
- package/dist/{messages-nOe1gJYu.mjs → messages-xh2eOLvs.mjs} +26 -1
- package/dist/{messages-B_sKqaeK.mjs → messages-ynAe7ewZ.mjs} +26 -1
- package/dist/react.mjs +2 -2
- package/dist/tools.mjs +2 -2
- package/dist/vendor.LICENSE.txt +3254 -297
- package/package.json +7 -2
- package/src/components/constants/data-attributes.ts +0 -2
- package/src/components/i18n/locales/am/messages.json +26 -1
- package/src/components/i18n/locales/ar/messages.json +26 -1
- package/src/components/i18n/locales/az/messages.json +26 -1
- package/src/components/i18n/locales/bg/messages.json +26 -1
- package/src/components/i18n/locales/bn/messages.json +26 -1
- package/src/components/i18n/locales/bs/messages.json +28 -3
- package/src/components/i18n/locales/cs/messages.json +30 -5
- package/src/components/i18n/locales/da/messages.json +33 -8
- package/src/components/i18n/locales/de/messages.json +31 -6
- package/src/components/i18n/locales/dv/messages.json +26 -1
- package/src/components/i18n/locales/el/messages.json +26 -1
- package/src/components/i18n/locales/en/messages.json +13 -0
- package/src/components/i18n/locales/es/messages.json +27 -2
- package/src/components/i18n/locales/et/messages.json +30 -5
- package/src/components/i18n/locales/fa/messages.json +26 -1
- package/src/components/i18n/locales/fi/messages.json +26 -1
- package/src/components/i18n/locales/fil/messages.json +49 -24
- package/src/components/i18n/locales/fr/messages.json +27 -2
- package/src/components/i18n/locales/gu/messages.json +26 -1
- package/src/components/i18n/locales/he/messages.json +26 -1
- package/src/components/i18n/locales/hi/messages.json +26 -1
- package/src/components/i18n/locales/hr/messages.json +28 -3
- package/src/components/i18n/locales/hu/messages.json +27 -2
- package/src/components/i18n/locales/hy/messages.json +26 -1
- package/src/components/i18n/locales/id/messages.json +26 -1
- package/src/components/i18n/locales/it/messages.json +27 -2
- package/src/components/i18n/locales/ja/messages.json +26 -1
- package/src/components/i18n/locales/ka/messages.json +26 -1
- package/src/components/i18n/locales/km/messages.json +26 -1
- package/src/components/i18n/locales/kn/messages.json +26 -1
- package/src/components/i18n/locales/ko/messages.json +26 -1
- package/src/components/i18n/locales/ku/messages.json +26 -1
- package/src/components/i18n/locales/lo/messages.json +26 -1
- package/src/components/i18n/locales/lt/messages.json +26 -1
- package/src/components/i18n/locales/lv/messages.json +26 -1
- package/src/components/i18n/locales/mk/messages.json +26 -1
- package/src/components/i18n/locales/ml/messages.json +26 -1
- package/src/components/i18n/locales/mn/messages.json +26 -1
- package/src/components/i18n/locales/mr/messages.json +26 -1
- package/src/components/i18n/locales/ms/messages.json +28 -3
- package/src/components/i18n/locales/my/messages.json +26 -1
- package/src/components/i18n/locales/ne/messages.json +26 -1
- package/src/components/i18n/locales/nl/messages.json +28 -3
- package/src/components/i18n/locales/no/messages.json +29 -4
- package/src/components/i18n/locales/pa/messages.json +26 -1
- package/src/components/i18n/locales/pl/messages.json +27 -2
- package/src/components/i18n/locales/ps/messages.json +26 -1
- package/src/components/i18n/locales/pt/messages.json +27 -2
- package/src/components/i18n/locales/ro/messages.json +27 -2
- package/src/components/i18n/locales/ru/messages.json +26 -1
- package/src/components/i18n/locales/sd/messages.json +26 -1
- package/src/components/i18n/locales/si/messages.json +26 -1
- package/src/components/i18n/locales/sk/messages.json +28 -3
- package/src/components/i18n/locales/sl/messages.json +28 -3
- package/src/components/i18n/locales/sq/messages.json +27 -2
- package/src/components/i18n/locales/sr/messages.json +26 -1
- package/src/components/i18n/locales/sv/messages.json +28 -3
- package/src/components/i18n/locales/sw/messages.json +26 -1
- package/src/components/i18n/locales/ta/messages.json +26 -1
- package/src/components/i18n/locales/te/messages.json +26 -1
- package/src/components/i18n/locales/th/messages.json +26 -1
- package/src/components/i18n/locales/tr/messages.json +26 -1
- package/src/components/i18n/locales/ug/messages.json +26 -1
- package/src/components/i18n/locales/uk/messages.json +26 -1
- package/src/components/i18n/locales/ur/messages.json +26 -1
- package/src/components/i18n/locales/vi/messages.json +26 -1
- package/src/components/i18n/locales/yi/messages.json +26 -1
- package/src/components/i18n/locales/zh/messages.json +26 -1
- package/src/components/icons/index.ts +38 -0
- package/src/components/modules/ui.ts +0 -13
- package/src/stories/EditorModes.stories.ts +0 -60
- package/src/styles/main.css +39 -1
- package/src/tools/callout/emoji-picker/index.ts +3 -2
- package/src/tools/code/code-keyboard.ts +16 -9
- package/src/tools/code/constants.ts +26 -3
- package/src/tools/code/dom-builder.ts +40 -5
- package/src/tools/code/highlight-applier.ts +229 -0
- package/src/tools/code/index.ts +141 -1
- package/src/tools/code/mermaid-loader.ts +45 -0
- package/src/tools/code/shiki-loader.ts +135 -0
- package/src/tools/table/core/table-commands.ts +16 -0
- package/src/tools/table/core/table-controller.ts +29 -0
- package/src/tools/table/core/table-events.ts +17 -0
- package/src/tools/table/index.ts +194 -11
- package/src/tools/table/table-cell-blocks.ts +9 -6
- package/src/tools/table/table-cell-clipboard.ts +6 -1
- package/src/tools/table/table-cell-placement-picker.ts +133 -0
- package/src/tools/table/table-cell-selection.ts +174 -19
- package/src/tools/table/table-core.ts +321 -113
- package/src/tools/table/table-map.ts +279 -0
- package/src/tools/table/table-model.ts +901 -1
- package/src/tools/table/table-operations.ts +78 -44
- package/src/tools/table/table-resize.ts +19 -17
- package/src/tools/table/table-row-col-drag.ts +24 -10
- package/src/tools/table/types.ts +24 -2
- package/types/data-attributes.d.ts +0 -1
- package/types/tools/code.d.ts +2 -0
- /package/dist/chunks/{am-CS-JjQ0N.mjs → am-rVzV1W41.mjs} +0 -0
- /package/dist/chunks/{ar-Dt4XzR5U.mjs → ar-C710lkoH.mjs} +0 -0
- /package/dist/chunks/{az-CaDTXby8.mjs → az-BOp1pgua.mjs} +0 -0
- /package/dist/chunks/{bg-D1pLog-R.mjs → bg-CL9p09ZD.mjs} +0 -0
- /package/dist/chunks/{bn-Db_ae60m.mjs → bn-CNmSeyAy.mjs} +0 -0
- /package/dist/chunks/{bs-DJTg1R9e.mjs → bs-BRzMGqzk.mjs} +0 -0
- /package/dist/chunks/{cs-_Gc21gSL.mjs → cs-BYPBLmnF.mjs} +0 -0
- /package/dist/chunks/{da-xDB8uhCd.mjs → da-CBC_LR1c.mjs} +0 -0
- /package/dist/chunks/{de-B6gVjh1Z.mjs → de-DxRFMoAj.mjs} +0 -0
- /package/dist/chunks/{el-ClbRSnOs.mjs → el-Bk6YbySf.mjs} +0 -0
- /package/dist/chunks/{es-CuY9rnLK.mjs → es-DpT3FCMR.mjs} +0 -0
- /package/dist/chunks/{et-BLu5lDVc.mjs → et-DE9Dr_g9.mjs} +0 -0
- /package/dist/chunks/{fa-P3gnrZH8.mjs → fa-Banj1QUE.mjs} +0 -0
- /package/dist/chunks/{fi-B8PVHLjq.mjs → fi-DfN3M5ER.mjs} +0 -0
- /package/dist/chunks/{fil-B9JII5iF.mjs → fil-DbCsRS1d.mjs} +0 -0
- /package/dist/chunks/{fr-BWLDZdcc.mjs → fr-D1clKhgt.mjs} +0 -0
- /package/dist/chunks/{gu-BH3R_s4c.mjs → gu-1CsZyRwT.mjs} +0 -0
- /package/dist/chunks/{he-CCmeCVR_.mjs → he-qQdnL6eK.mjs} +0 -0
- /package/dist/chunks/{hi-BBav00DN.mjs → hi-DxM0Nff1.mjs} +0 -0
- /package/dist/chunks/{hr-B5ZX0r9G.mjs → hr-Onldyi-u.mjs} +0 -0
- /package/dist/chunks/{hu-1jgDa3YU.mjs → hu-CAn3pBuY.mjs} +0 -0
- /package/dist/chunks/{hy-LX4Kp2PE.mjs → hy-D43q7NxE.mjs} +0 -0
- /package/dist/chunks/{i18next-KNC_XV5x.mjs → i18next-BBGW2sDE.mjs} +0 -0
- /package/dist/chunks/{id-CcG40D1H.mjs → id-Xrw5Dd0Y.mjs} +0 -0
- /package/dist/chunks/{it-Cb8_K72W.mjs → it-CA9ZDMSc.mjs} +0 -0
- /package/dist/chunks/{ja-ipCH91mv.mjs → ja-D0J6WRFh.mjs} +0 -0
- /package/dist/chunks/{ka-BRvREIgq.mjs → ka-BZL7xDuY.mjs} +0 -0
- /package/dist/chunks/{km-BJwVw7Fg.mjs → km-BimgQZVU.mjs} +0 -0
- /package/dist/chunks/{kn-BPgUazCC.mjs → kn-C2n2cPHK.mjs} +0 -0
- /package/dist/chunks/{ko-CQLzxe7k.mjs → ko-n4Cn93D3.mjs} +0 -0
- /package/dist/chunks/{ku-BHhHu8Iz.mjs → ku-BYZCgT44.mjs} +0 -0
- /package/dist/chunks/{lo-DsTgYblY.mjs → lo-DVXiAE4N.mjs} +0 -0
- /package/dist/chunks/{lt-CDzHJm71.mjs → lt-B9KlQFnY.mjs} +0 -0
- /package/dist/chunks/{lv-MLLIAnIX.mjs → lv-BINeOdyx.mjs} +0 -0
- /package/dist/chunks/{mdast-util-math-yS0EygZV.mjs → mdast-util-math-CHYUxOHk.mjs} +0 -0
- /package/dist/chunks/{mk-DQdmUquZ.mjs → mk-_-QrPrLN.mjs} +0 -0
- /package/dist/chunks/{ml-DqehZnra.mjs → ml-KvJSC1KT.mjs} +0 -0
- /package/dist/chunks/{mn-4cFkKFjW.mjs → mn-CjFjWnRG.mjs} +0 -0
- /package/dist/chunks/{mr-DWiztOP4.mjs → mr-DqAZ7FRX.mjs} +0 -0
- /package/dist/chunks/{ms-BSz-iSnc.mjs → ms-BZcV4UG_.mjs} +0 -0
- /package/dist/chunks/{my-DbtbM1MW.mjs → my-97SC9jYN.mjs} +0 -0
- /package/dist/chunks/{ne-CqALWw_f.mjs → ne-Bs-M2TyF.mjs} +0 -0
- /package/dist/chunks/{nl-D_ra6RvH.mjs → nl-2ZwQilo-.mjs} +0 -0
- /package/dist/chunks/{no-Cg_kz_jl.mjs → no-fOQTpFq1.mjs} +0 -0
- /package/dist/chunks/{notifier-BOwxj_Ok.mjs → notifier-B1zCi9G1.mjs} +0 -0
- /package/dist/chunks/{pa-NLAsNqwY.mjs → pa-DLOqkMi0.mjs} +0 -0
- /package/dist/chunks/{pl-NHKp4YDg.mjs → pl-FYs9QrXU.mjs} +0 -0
- /package/dist/chunks/{ps-D1zEqNeg.mjs → ps-CTXe6pSe.mjs} +0 -0
- /package/dist/chunks/{pt-DBtqbUEB.mjs → pt-B1X4x7d1.mjs} +0 -0
- /package/dist/chunks/{ro-lqr63ai5.mjs → ro-Bf7S2FaR.mjs} +0 -0
- /package/dist/chunks/{ru-BycNnDyN.mjs → ru-B8lqnu_j.mjs} +0 -0
- /package/dist/chunks/{sd-DpHpIN9Z.mjs → sd-CHRYJm2r.mjs} +0 -0
- /package/dist/chunks/{si-BwiwaC7N.mjs → si-CI0Hs6vH.mjs} +0 -0
- /package/dist/chunks/{sk-CqRHT2Gp.mjs → sk-Bdvq1Kb_.mjs} +0 -0
- /package/dist/chunks/{sl-DA348uQ_.mjs → sl-B_qiFTV5.mjs} +0 -0
- /package/dist/chunks/{sq-D7JNgve1.mjs → sq-E0j1hysP.mjs} +0 -0
- /package/dist/chunks/{sr-D8RK6Kwp.mjs → sr-VPpVNTZw.mjs} +0 -0
- /package/dist/chunks/{sv-dwgT67ZG.mjs → sv-gKmDSR3d.mjs} +0 -0
- /package/dist/chunks/{sw-ZRRJnkem.mjs → sw-zeFLiO23.mjs} +0 -0
- /package/dist/chunks/{ta-5x4L5Krl.mjs → ta-Ci-j89hR.mjs} +0 -0
- /package/dist/chunks/{te-BZpEimwA.mjs → te-qyMI0M7a.mjs} +0 -0
- /package/dist/chunks/{th-Bhr-33kv.mjs → th-DPxHtpdb.mjs} +0 -0
- /package/dist/chunks/{tr-6tSNKGNB.mjs → tr-CRV6GS-G.mjs} +0 -0
- /package/dist/chunks/{ug-_e-jvr2b.mjs → ug-DW0YFpo5.mjs} +0 -0
- /package/dist/chunks/{uk-DooSc2Ja.mjs → uk-ssteuphK.mjs} +0 -0
- /package/dist/chunks/{ur-rb-krkIO.mjs → ur-qhY3-jY7.mjs} +0 -0
- /package/dist/chunks/{vi-CQkLn2AQ.mjs → vi-CHriMMC8.mjs} +0 -0
- /package/dist/chunks/{zh-CXQ40Q2_.mjs → zh-BJktawVN.mjs} +0 -0
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
import type { CellContent, LegacyCellContent, TableData } from './types';
|
|
1
|
+
import type { CellContent, CellPlacement, LegacyCellContent, TableData } from './types';
|
|
2
2
|
import { isCellWithBlocks } from './types';
|
|
3
3
|
|
|
4
|
+
export interface SelectionRect {
|
|
5
|
+
minRow: number;
|
|
6
|
+
maxRow: number;
|
|
7
|
+
minCol: number;
|
|
8
|
+
maxCol: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface MergeResult {
|
|
12
|
+
/** Block IDs that were moved from absorbed cells into the origin cell. */
|
|
13
|
+
blocksToRelocate: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
4
16
|
/**
|
|
5
17
|
* Validate that a string is a safe CSS color value.
|
|
6
18
|
*
|
|
@@ -120,6 +132,22 @@ export class TableModel {
|
|
|
120
132
|
cell.textColor = c.textColor;
|
|
121
133
|
}
|
|
122
134
|
|
|
135
|
+
if (c.placement !== undefined) {
|
|
136
|
+
cell.placement = c.placement;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (c.colspan !== undefined && c.colspan > 1) {
|
|
140
|
+
cell.colspan = c.colspan;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (c.rowspan !== undefined && c.rowspan > 1) {
|
|
144
|
+
cell.rowspan = c.rowspan;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (c.mergedInto !== undefined) {
|
|
148
|
+
cell.mergedInto = [...c.mergedInto];
|
|
149
|
+
}
|
|
150
|
+
|
|
123
151
|
return cell;
|
|
124
152
|
})
|
|
125
153
|
),
|
|
@@ -269,6 +297,25 @@ export class TableModel {
|
|
|
269
297
|
return this.contentGrid[row][col].textColor;
|
|
270
298
|
}
|
|
271
299
|
|
|
300
|
+
setCellPlacement(row: number, col: number, placement: CellPlacement | undefined): void {
|
|
301
|
+
if (!this.isInBounds(row, col)) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (placement === undefined) {
|
|
305
|
+
delete this.contentGrid[row][col].placement;
|
|
306
|
+
} else {
|
|
307
|
+
this.contentGrid[row][col].placement = placement;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
getCellPlacement(row: number, col: number): CellPlacement | undefined {
|
|
312
|
+
if (!this.isInBounds(row, col)) {
|
|
313
|
+
return undefined;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return this.contentGrid[row][col].placement;
|
|
317
|
+
}
|
|
318
|
+
|
|
272
319
|
// ─── Row operations ─────────────────────────────────────────────
|
|
273
320
|
|
|
274
321
|
/**
|
|
@@ -283,6 +330,8 @@ export class TableModel {
|
|
|
283
330
|
const newRow: CellContent[] = Array.from({ length: colCount }, () => ({ blocks: [] }));
|
|
284
331
|
|
|
285
332
|
this.contentGrid.splice(clampedIndex, 0, newRow);
|
|
333
|
+
this.shiftMergedIntoRows(clampedIndex, 1);
|
|
334
|
+
this.expandSpansForInsertedRow(clampedIndex);
|
|
286
335
|
this.rebuildBlockCellMap();
|
|
287
336
|
|
|
288
337
|
return {
|
|
@@ -300,6 +349,8 @@ export class TableModel {
|
|
|
300
349
|
return { type: 'delete-row', index, blocksToDelete: [] };
|
|
301
350
|
}
|
|
302
351
|
|
|
352
|
+
this.contractSpansForDeletedRow(index);
|
|
353
|
+
|
|
303
354
|
const blocksToDelete = this.collectBlocksInRow(index);
|
|
304
355
|
|
|
305
356
|
this.contentGrid.splice(index, 1);
|
|
@@ -308,6 +359,7 @@ export class TableModel {
|
|
|
308
359
|
this.blockCellMap.delete(id);
|
|
309
360
|
}
|
|
310
361
|
|
|
362
|
+
this.shiftMergedIntoRows(index, -1);
|
|
311
363
|
this.rebuildBlockCellMap();
|
|
312
364
|
|
|
313
365
|
return { type: 'delete-row', index, blocksToDelete };
|
|
@@ -321,9 +373,14 @@ export class TableModel {
|
|
|
321
373
|
return { type: 'move-row', index: from, toIndex: to };
|
|
322
374
|
}
|
|
323
375
|
|
|
376
|
+
if (this.isRowInvolvedInMerge(from)) {
|
|
377
|
+
return { type: 'move-row', index: from, toIndex: to };
|
|
378
|
+
}
|
|
379
|
+
|
|
324
380
|
const [moved] = this.contentGrid.splice(from, 1);
|
|
325
381
|
|
|
326
382
|
this.contentGrid.splice(to, 0, moved);
|
|
383
|
+
this.rebuildMergedIntoRowCoordinates(from, to);
|
|
327
384
|
this.rebuildBlockCellMap();
|
|
328
385
|
|
|
329
386
|
return { type: 'move-row', index: from, toIndex: to };
|
|
@@ -356,6 +413,8 @@ export class TableModel {
|
|
|
356
413
|
this.colWidthsValue.splice(clampedIndex, 0, insertWidth);
|
|
357
414
|
}
|
|
358
415
|
|
|
416
|
+
this.shiftMergedIntoCols(clampedIndex, 1);
|
|
417
|
+
this.expandSpansForInsertedCol(clampedIndex);
|
|
359
418
|
this.rebuildBlockCellMap();
|
|
360
419
|
|
|
361
420
|
return {
|
|
@@ -373,6 +432,8 @@ export class TableModel {
|
|
|
373
432
|
return { type: 'delete-column', index, blocksToDelete: [] };
|
|
374
433
|
}
|
|
375
434
|
|
|
435
|
+
this.contractSpansForDeletedCol(index);
|
|
436
|
+
|
|
376
437
|
const blocksToDelete = this.collectBlocksInColumn(index);
|
|
377
438
|
|
|
378
439
|
for (const row of this.contentGrid) {
|
|
@@ -391,6 +452,7 @@ export class TableModel {
|
|
|
391
452
|
this.colWidthsValue = undefined;
|
|
392
453
|
}
|
|
393
454
|
|
|
455
|
+
this.shiftMergedIntoCols(index, -1);
|
|
394
456
|
this.rebuildBlockCellMap();
|
|
395
457
|
|
|
396
458
|
return { type: 'delete-column', index, blocksToDelete };
|
|
@@ -404,6 +466,10 @@ export class TableModel {
|
|
|
404
466
|
return { type: 'move-column', index: from, toIndex: to };
|
|
405
467
|
}
|
|
406
468
|
|
|
469
|
+
if (this.isColInvolvedInMerge(from)) {
|
|
470
|
+
return { type: 'move-column', index: from, toIndex: to };
|
|
471
|
+
}
|
|
472
|
+
|
|
407
473
|
for (const row of this.contentGrid) {
|
|
408
474
|
const [moved] = row.splice(from, 1);
|
|
409
475
|
|
|
@@ -416,6 +482,7 @@ export class TableModel {
|
|
|
416
482
|
this.colWidthsValue.splice(to, 0, movedWidth);
|
|
417
483
|
}
|
|
418
484
|
|
|
485
|
+
this.rebuildMergedIntoColCoordinates(from, to);
|
|
419
486
|
this.rebuildBlockCellMap();
|
|
420
487
|
|
|
421
488
|
return { type: 'move-column', index: from, toIndex: to };
|
|
@@ -438,6 +505,247 @@ export class TableModel {
|
|
|
438
505
|
this.rebuildBlockCellMap();
|
|
439
506
|
}
|
|
440
507
|
|
|
508
|
+
// ─── Merge / Split ──────────────────────────────────────────────
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Check whether the given rectangle of cells can be merged.
|
|
512
|
+
* Returns true when the selection contains at least 2 grid positions,
|
|
513
|
+
* is fully in-bounds, and no existing merged cell partially overlaps
|
|
514
|
+
* the selection boundary.
|
|
515
|
+
*/
|
|
516
|
+
canMergeCells(rect: SelectionRect): boolean {
|
|
517
|
+
const { minRow, maxRow, minCol, maxCol } = rect;
|
|
518
|
+
|
|
519
|
+
// Must span at least 2 cells
|
|
520
|
+
if (minRow === maxRow && minCol === maxCol) {
|
|
521
|
+
return false;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Bounds check
|
|
525
|
+
if (minRow < 0 || maxRow >= this.rows || minCol < 0 || maxCol >= this.cols) {
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Check that no merged cell partially overlaps the selection boundary.
|
|
530
|
+
// A merged cell is allowed if it's fully inside the selection.
|
|
531
|
+
return this.contentGrid.slice(minRow, maxRow + 1).every((row, ri) => {
|
|
532
|
+
const r = minRow + ri;
|
|
533
|
+
|
|
534
|
+
return row.slice(minCol, maxCol + 1).every((cell, ci) => {
|
|
535
|
+
const c = minCol + ci;
|
|
536
|
+
|
|
537
|
+
// Check origin cells whose span extends beyond the selection
|
|
538
|
+
const colspan = cell.colspan ?? 1;
|
|
539
|
+
const rowspan = cell.rowspan ?? 1;
|
|
540
|
+
|
|
541
|
+
if (colspan > 1 || rowspan > 1) {
|
|
542
|
+
if (r + rowspan - 1 > maxRow || c + colspan - 1 > maxCol) {
|
|
543
|
+
return false;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Check spanned cells whose origin is outside the selection
|
|
548
|
+
if (cell.mergedInto !== undefined) {
|
|
549
|
+
const [originRow, originCol] = cell.mergedInto;
|
|
550
|
+
|
|
551
|
+
if (originRow < minRow || originCol < minCol) {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
return true;
|
|
557
|
+
});
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Merge cells in the given rectangle. The top-left cell becomes the
|
|
563
|
+
* origin with colspan/rowspan set. All other cells in the rectangle
|
|
564
|
+
* become spanned (mergedInto pointing to origin, blocks emptied).
|
|
565
|
+
*
|
|
566
|
+
* Blocks from absorbed cells are concatenated into the origin cell
|
|
567
|
+
* in row-major order.
|
|
568
|
+
*/
|
|
569
|
+
mergeCells(rect: SelectionRect): MergeResult {
|
|
570
|
+
const { minRow, maxRow, minCol, maxCol } = rect;
|
|
571
|
+
const result: MergeResult = { blocksToRelocate: [] };
|
|
572
|
+
|
|
573
|
+
if (!this.canMergeCells(rect)) {
|
|
574
|
+
return result;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
const origin = this.contentGrid[minRow][minCol];
|
|
578
|
+
|
|
579
|
+
// First, if any cell in the selection is itself an origin of a merge,
|
|
580
|
+
// split it so we work with flat cells
|
|
581
|
+
this.contentGrid.slice(minRow, maxRow + 1).forEach((row, ri) => {
|
|
582
|
+
const r = minRow + ri;
|
|
583
|
+
|
|
584
|
+
row.slice(minCol, maxCol + 1).forEach((cell, ci) => {
|
|
585
|
+
const c = minCol + ci;
|
|
586
|
+
|
|
587
|
+
if (r === minRow && c === minCol) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
if ((cell.colspan ?? 1) > 1 || (cell.rowspan ?? 1) > 1) {
|
|
592
|
+
this.splitCellInternal(r, c);
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
// Also split the origin if it was previously merged
|
|
598
|
+
if ((origin.colspan ?? 1) > 1 || (origin.rowspan ?? 1) > 1) {
|
|
599
|
+
this.splitCellInternal(minRow, minCol);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// Collect blocks from all cells in row-major order and move to origin
|
|
603
|
+
const collectedBlocks: string[] = [];
|
|
604
|
+
|
|
605
|
+
this.contentGrid.slice(minRow, maxRow + 1).forEach((_row, ri) => {
|
|
606
|
+
const r = minRow + ri;
|
|
607
|
+
|
|
608
|
+
this.contentGrid[r].slice(minCol, maxCol + 1).forEach((_cell, ci) => {
|
|
609
|
+
const c = minCol + ci;
|
|
610
|
+
const gridCell = this.contentGrid[r][c];
|
|
611
|
+
|
|
612
|
+
for (const blockId of gridCell.blocks) {
|
|
613
|
+
collectedBlocks.push(blockId);
|
|
614
|
+
|
|
615
|
+
if (r !== minRow || c !== minCol) {
|
|
616
|
+
result.blocksToRelocate.push(blockId);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// Clear non-origin cells
|
|
621
|
+
if (r !== minRow || c !== minCol) {
|
|
622
|
+
gridCell.blocks = [];
|
|
623
|
+
gridCell.mergedInto = [minRow, minCol];
|
|
624
|
+
delete gridCell.colspan;
|
|
625
|
+
delete gridCell.rowspan;
|
|
626
|
+
}
|
|
627
|
+
});
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
// Set origin cell
|
|
631
|
+
origin.blocks = collectedBlocks;
|
|
632
|
+
origin.colspan = maxCol - minCol + 1;
|
|
633
|
+
origin.rowspan = maxRow - minRow + 1;
|
|
634
|
+
delete origin.mergedInto;
|
|
635
|
+
// Reset placement to default (top-left) on merge
|
|
636
|
+
delete origin.placement;
|
|
637
|
+
|
|
638
|
+
// Normalize: remove colspan/rowspan if 1
|
|
639
|
+
if (origin.colspan === 1) {
|
|
640
|
+
delete origin.colspan;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (origin.rowspan === 1) {
|
|
644
|
+
delete origin.rowspan;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
this.rebuildBlockCellMap();
|
|
648
|
+
|
|
649
|
+
return result;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Split a merged cell at (row, col) back into individual cells.
|
|
654
|
+
* All content stays in the origin cell; freed cells become empty.
|
|
655
|
+
* No-op if the cell is not a merge origin.
|
|
656
|
+
*/
|
|
657
|
+
splitCell(row: number, col: number): void {
|
|
658
|
+
if (!this.isInBounds(row, col)) {
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
const cell = this.contentGrid[row][col];
|
|
663
|
+
|
|
664
|
+
if ((cell.colspan ?? 1) <= 1 && (cell.rowspan ?? 1) <= 1) {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
this.splitCellInternal(row, col);
|
|
669
|
+
this.rebuildBlockCellMap();
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Returns true if the cell at (row, col) is the origin of a merge
|
|
674
|
+
* (has colspan > 1 or rowspan > 1).
|
|
675
|
+
*/
|
|
676
|
+
isMergedCell(row: number, col: number): boolean {
|
|
677
|
+
if (!this.isInBounds(row, col)) {
|
|
678
|
+
return false;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
const cell = this.contentGrid[row][col];
|
|
682
|
+
|
|
683
|
+
return (cell.colspan ?? 1) > 1 || (cell.rowspan ?? 1) > 1;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Returns true if the cell at (row, col) is covered by another cell's merge
|
|
688
|
+
* (has mergedInto set).
|
|
689
|
+
*/
|
|
690
|
+
isSpannedCell(row: number, col: number): boolean {
|
|
691
|
+
if (!this.isInBounds(row, col)) {
|
|
692
|
+
return false;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
return this.contentGrid[row][col].mergedInto !== undefined;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Get the colspan and rowspan of the cell at (row, col).
|
|
700
|
+
* Returns {colspan: 1, rowspan: 1} for regular/spanned cells.
|
|
701
|
+
*/
|
|
702
|
+
getCellSpan(row: number, col: number): { colspan: number; rowspan: number } {
|
|
703
|
+
if (!this.isInBounds(row, col)) {
|
|
704
|
+
return { colspan: 1, rowspan: 1 };
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
const cell = this.contentGrid[row][col];
|
|
708
|
+
|
|
709
|
+
return {
|
|
710
|
+
colspan: cell.colspan ?? 1,
|
|
711
|
+
rowspan: cell.rowspan ?? 1,
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Internal split that doesn't rebuild the block cell map.
|
|
717
|
+
* Used by mergeCells to flatten existing merges before re-merging.
|
|
718
|
+
*/
|
|
719
|
+
private splitCellInternal(row: number, col: number): void {
|
|
720
|
+
const cell = this.contentGrid[row][col];
|
|
721
|
+
const colspan = cell.colspan ?? 1;
|
|
722
|
+
const rowspan = cell.rowspan ?? 1;
|
|
723
|
+
|
|
724
|
+
// Clear spanned cells
|
|
725
|
+
this.contentGrid.slice(row, Math.min(row + rowspan, this.rows)).forEach((_gridRow, ri) => {
|
|
726
|
+
const r = row + ri;
|
|
727
|
+
|
|
728
|
+
this.contentGrid[r].slice(col, Math.min(col + colspan, this.cols)).forEach((_spanned, ci) => {
|
|
729
|
+
const c = col + ci;
|
|
730
|
+
|
|
731
|
+
if (r === row && c === col) {
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
const spanned = this.contentGrid[r][c];
|
|
736
|
+
|
|
737
|
+
delete spanned.mergedInto;
|
|
738
|
+
spanned.blocks = [];
|
|
739
|
+
delete spanned.placement;
|
|
740
|
+
});
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
// Reset origin
|
|
744
|
+
delete cell.colspan;
|
|
745
|
+
delete cell.rowspan;
|
|
746
|
+
delete cell.placement;
|
|
747
|
+
}
|
|
748
|
+
|
|
441
749
|
// ─── Metadata setters ──────────────────────────────────────────
|
|
442
750
|
|
|
443
751
|
setWithHeadings(value: boolean): void {
|
|
@@ -526,6 +834,90 @@ export class TableModel {
|
|
|
526
834
|
});
|
|
527
835
|
});
|
|
528
836
|
|
|
837
|
+
// Invariant 5: merge spans in bounds
|
|
838
|
+
this.contentGrid.forEach((row, r) => {
|
|
839
|
+
row.forEach((cell, c) => {
|
|
840
|
+
const colspan = cell.colspan ?? 1;
|
|
841
|
+
const rowspan = cell.rowspan ?? 1;
|
|
842
|
+
|
|
843
|
+
if (colspan > 1 || rowspan > 1) {
|
|
844
|
+
if (r + rowspan > this.contentGrid.length || c + colspan > (this.contentGrid[0]?.length ?? 0)) {
|
|
845
|
+
throw new Error(
|
|
846
|
+
`Invariant violation: origin [${r},${c}] span extends beyond grid bounds (colspan=${colspan}, rowspan=${rowspan}, rows=${this.contentGrid.length}, cols=${this.contentGrid[0]?.length ?? 0})`
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
// Invariant 6: mergedInto references are valid
|
|
854
|
+
this.contentGrid.forEach((row, r) => {
|
|
855
|
+
row.forEach((cell, c) => {
|
|
856
|
+
if (cell.mergedInto === undefined) {
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
const [originRow, originCol] = cell.mergedInto;
|
|
861
|
+
|
|
862
|
+
// Must be in bounds
|
|
863
|
+
if (originRow < 0 || originRow >= this.contentGrid.length ||
|
|
864
|
+
originCol < 0 || originCol >= (this.contentGrid[0]?.length ?? 0)) {
|
|
865
|
+
throw new Error(
|
|
866
|
+
`Invariant violation: mergedInto at [${r},${c}] points to out-of-bounds [${originRow},${originCol}]`
|
|
867
|
+
);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
// Must point to a merge origin
|
|
871
|
+
const origin = this.contentGrid[originRow][originCol];
|
|
872
|
+
const oColspan = origin.colspan ?? 1;
|
|
873
|
+
const oRowspan = origin.rowspan ?? 1;
|
|
874
|
+
|
|
875
|
+
if (oColspan <= 1 && oRowspan <= 1) {
|
|
876
|
+
throw new Error(
|
|
877
|
+
`Invariant violation: mergedInto at [${r},${c}] points to [${originRow},${originCol}] which is not a merge origin`
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// Must be within the origin's span
|
|
882
|
+
if (r < originRow || r >= originRow + oRowspan ||
|
|
883
|
+
c < originCol || c >= originCol + oColspan) {
|
|
884
|
+
throw new Error(
|
|
885
|
+
`Invariant violation: mergedInto at [${r},${c}] is outside the span of origin [${originRow},${originCol}] (colspan=${oColspan}, rowspan=${oRowspan})`
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
});
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
// Invariant 7: every cell within an origin's span has mergedInto (except the origin itself)
|
|
892
|
+
this.contentGrid.forEach((row, r) => {
|
|
893
|
+
row.forEach((cell, c) => {
|
|
894
|
+
const colspan = cell.colspan ?? 1;
|
|
895
|
+
const rowspan = cell.rowspan ?? 1;
|
|
896
|
+
|
|
897
|
+
if (colspan <= 1 && rowspan <= 1) {
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
this.contentGrid.slice(r, r + rowspan).forEach((spanRow, dri) => {
|
|
902
|
+
const dr = r + dri;
|
|
903
|
+
|
|
904
|
+
spanRow.slice(c, c + colspan).forEach((spanned, dci) => {
|
|
905
|
+
const dc = c + dci;
|
|
906
|
+
|
|
907
|
+
if (dr === r && dc === c) {
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
if (!spanned?.mergedInto) {
|
|
912
|
+
throw new Error(
|
|
913
|
+
`Invariant violation: cell [${dr},${dc}] is within span of origin [${r},${c}] but has no mergedInto`
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
});
|
|
917
|
+
});
|
|
918
|
+
});
|
|
919
|
+
});
|
|
920
|
+
|
|
529
921
|
// Check map doesn't have extra entries
|
|
530
922
|
if (this.blockCellMap.size !== seenBlocks.size) {
|
|
531
923
|
throw new Error(
|
|
@@ -534,6 +926,498 @@ export class TableModel {
|
|
|
534
926
|
}
|
|
535
927
|
}
|
|
536
928
|
|
|
929
|
+
// ─── Merge-aware structural helpers ─────────────────────────────
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* Shift mergedInto row coordinates for all cells where mergedInto[0] >= startRow.
|
|
933
|
+
* Called after inserting (delta=1) or deleting (delta=-1) a row.
|
|
934
|
+
*/
|
|
935
|
+
private shiftMergedIntoRows(startRow: number, delta: number): void {
|
|
936
|
+
this.contentGrid.forEach((_row, r) => {
|
|
937
|
+
this.contentGrid[r].forEach((_cell, c) => {
|
|
938
|
+
const gridCell = this.contentGrid[r][c];
|
|
939
|
+
|
|
940
|
+
if (gridCell.mergedInto !== undefined && gridCell.mergedInto[0] >= startRow) {
|
|
941
|
+
gridCell.mergedInto = [gridCell.mergedInto[0] + delta, gridCell.mergedInto[1]];
|
|
942
|
+
}
|
|
943
|
+
});
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Shift mergedInto col coordinates for all cells where mergedInto[1] >= startCol.
|
|
949
|
+
* Called after inserting (delta=1) or deleting (delta=-1) a column.
|
|
950
|
+
*/
|
|
951
|
+
private shiftMergedIntoCols(startCol: number, delta: number): void {
|
|
952
|
+
this.contentGrid.forEach((_row, r) => {
|
|
953
|
+
this.contentGrid[r].forEach((_cell, c) => {
|
|
954
|
+
const gridCell = this.contentGrid[r][c];
|
|
955
|
+
|
|
956
|
+
if (gridCell.mergedInto !== undefined && gridCell.mergedInto[1] >= startCol) {
|
|
957
|
+
gridCell.mergedInto = [gridCell.mergedInto[0], gridCell.mergedInto[1] + delta];
|
|
958
|
+
}
|
|
959
|
+
});
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* After inserting a row at insertedRow, find origin cells above whose rowspan
|
|
965
|
+
* crosses the insertion point, increment their rowspan, and mark new cells as covered.
|
|
966
|
+
*/
|
|
967
|
+
private expandSpansForInsertedRow(insertedRow: number): void {
|
|
968
|
+
this.contentGrid.forEach((_row, r) => {
|
|
969
|
+
this.contentGrid[r].forEach((_cell, c) => {
|
|
970
|
+
const gridCell = this.contentGrid[r][c];
|
|
971
|
+
const rowspan = gridCell.rowspan ?? 1;
|
|
972
|
+
const colspan = gridCell.colspan ?? 1;
|
|
973
|
+
|
|
974
|
+
if (rowspan <= 1 && colspan <= 1) {
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
if (r >= insertedRow || r + rowspan <= insertedRow) {
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
// Increment rowspan to absorb the new row
|
|
983
|
+
gridCell.rowspan = rowspan + 1;
|
|
984
|
+
|
|
985
|
+
// Mark the new row's cells within the colspan as covered
|
|
986
|
+
this.markInsertedRowCells(insertedRow, r, c, colspan);
|
|
987
|
+
});
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
private markInsertedRowCells(insertedRow: number, originRow: number, originCol: number, colspan: number): void {
|
|
992
|
+
this.contentGrid[insertedRow].slice(originCol, originCol + colspan).forEach((_newCell, ci) => {
|
|
993
|
+
const dc = originCol + ci;
|
|
994
|
+
|
|
995
|
+
if (dc === originCol && originRow === insertedRow) {
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
const gridCell = this.contentGrid[insertedRow][dc];
|
|
999
|
+
|
|
1000
|
+
gridCell.mergedInto = [originRow, originCol];
|
|
1001
|
+
gridCell.blocks = [];
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* After inserting a column at insertedCol, find origin cells to the left whose colspan
|
|
1007
|
+
* crosses the insertion point, increment their colspan, and mark new cells as covered.
|
|
1008
|
+
*/
|
|
1009
|
+
private expandSpansForInsertedCol(insertedCol: number): void {
|
|
1010
|
+
this.contentGrid.forEach((_row, r) => {
|
|
1011
|
+
this.contentGrid[r].forEach((_cell, c) => {
|
|
1012
|
+
const gridCell = this.contentGrid[r][c];
|
|
1013
|
+
const rowspan = gridCell.rowspan ?? 1;
|
|
1014
|
+
const colspan = gridCell.colspan ?? 1;
|
|
1015
|
+
|
|
1016
|
+
if (rowspan <= 1 && colspan <= 1) {
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
if (c >= insertedCol || c + colspan <= insertedCol) {
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
gridCell.colspan = colspan + 1;
|
|
1025
|
+
|
|
1026
|
+
// Mark the new column's cells within the rowspan as covered
|
|
1027
|
+
this.markInsertedColCells(insertedCol, r, c, rowspan);
|
|
1028
|
+
});
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
private markInsertedColCells(insertedCol: number, originRow: number, originCol: number, rowspan: number): void {
|
|
1033
|
+
this.contentGrid.slice(originRow, originRow + rowspan).forEach((_gridRow, ri) => {
|
|
1034
|
+
const dr = originRow + ri;
|
|
1035
|
+
|
|
1036
|
+
if (dr === originRow && insertedCol === originCol) {
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
const gridCell = this.contentGrid[dr][insertedCol];
|
|
1040
|
+
|
|
1041
|
+
gridCell.mergedInto = [originRow, originCol];
|
|
1042
|
+
gridCell.blocks = [];
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* Before deleting a row, handle merge origins and covered cells in that row.
|
|
1048
|
+
* - If a cell is a merge origin with rowspan > 1: transfer to the row below.
|
|
1049
|
+
* - If a cell has mergedInto pointing to a different row: decrement origin's rowspan.
|
|
1050
|
+
*/
|
|
1051
|
+
private contractSpansForDeletedRow(rowIndex: number): void {
|
|
1052
|
+
const row = this.contentGrid[rowIndex];
|
|
1053
|
+
|
|
1054
|
+
row.forEach((_cell, c) => {
|
|
1055
|
+
const gridCell = this.contentGrid[rowIndex][c];
|
|
1056
|
+
|
|
1057
|
+
if ((gridCell.colspan ?? 1) > 1 || (gridCell.rowspan ?? 1) > 1) {
|
|
1058
|
+
this.handleOriginInDeletedRow(rowIndex, c);
|
|
1059
|
+
} else if (gridCell.mergedInto !== undefined) {
|
|
1060
|
+
this.handleCoveredInDeletedRow(rowIndex, c);
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
private handleOriginInDeletedRow(rowIndex: number, c: number): void {
|
|
1066
|
+
const cell = this.contentGrid[rowIndex][c];
|
|
1067
|
+
const rowspan = cell.rowspan ?? 1;
|
|
1068
|
+
const colspan = cell.colspan ?? 1;
|
|
1069
|
+
|
|
1070
|
+
if (rowspan <= 1) {
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
const newRowspan = rowspan - 1;
|
|
1075
|
+
const nextRow = rowIndex + 1;
|
|
1076
|
+
|
|
1077
|
+
if (nextRow < this.contentGrid.length) {
|
|
1078
|
+
this.transferOriginToNextRow(rowIndex, c, nextRow, rowspan, colspan, newRowspan);
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
delete cell.colspan;
|
|
1082
|
+
delete cell.rowspan;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
private transferOriginToNextRow(
|
|
1086
|
+
rowIndex: number, c: number, nextRow: number,
|
|
1087
|
+
rowspan: number, colspan: number, newRowspan: number
|
|
1088
|
+
): void {
|
|
1089
|
+
const cell = this.contentGrid[rowIndex][c];
|
|
1090
|
+
const newOrigin = this.contentGrid[nextRow][c];
|
|
1091
|
+
|
|
1092
|
+
newOrigin.blocks = [...cell.blocks];
|
|
1093
|
+
cell.blocks = [];
|
|
1094
|
+
|
|
1095
|
+
delete newOrigin.mergedInto;
|
|
1096
|
+
|
|
1097
|
+
if (newRowspan === 1 && colspan === 1) {
|
|
1098
|
+
delete newOrigin.colspan;
|
|
1099
|
+
delete newOrigin.rowspan;
|
|
1100
|
+
this.clearMergedIntoRefs(nextRow, rowIndex + rowspan, c, c + colspan, rowIndex, c, nextRow, c, undefined);
|
|
1101
|
+
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
if (newRowspan > 1) {
|
|
1106
|
+
newOrigin.rowspan = newRowspan;
|
|
1107
|
+
} else {
|
|
1108
|
+
delete newOrigin.rowspan;
|
|
1109
|
+
}
|
|
1110
|
+
if (colspan > 1) {
|
|
1111
|
+
newOrigin.colspan = colspan;
|
|
1112
|
+
} else {
|
|
1113
|
+
delete newOrigin.colspan;
|
|
1114
|
+
}
|
|
1115
|
+
this.clearMergedIntoRefs(nextRow, rowIndex + rowspan, c, c + colspan, rowIndex, c, nextRow, c, [nextRow, c]);
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
private handleCoveredInDeletedRow(rowIndex: number, c: number): void {
|
|
1119
|
+
const cell = this.contentGrid[rowIndex][c];
|
|
1120
|
+
const [originRow, originCol] = cell.mergedInto as [number, number];
|
|
1121
|
+
|
|
1122
|
+
if (originRow === rowIndex) {
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
const origin = this.contentGrid[originRow]?.[originCol];
|
|
1127
|
+
|
|
1128
|
+
if (!origin) {
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
const oRowspan = origin.rowspan ?? 1;
|
|
1133
|
+
const oColspan = origin.colspan ?? 1;
|
|
1134
|
+
const newRowspan = oRowspan - 1;
|
|
1135
|
+
|
|
1136
|
+
if (newRowspan === 1 && oColspan === 1) {
|
|
1137
|
+
delete origin.colspan;
|
|
1138
|
+
delete origin.rowspan;
|
|
1139
|
+
|
|
1140
|
+
this.clearMergedIntoRefsForDissolve(originRow, originRow + oRowspan, originCol, originCol + oColspan, originRow, originCol, rowIndex);
|
|
1141
|
+
} else {
|
|
1142
|
+
if (newRowspan > 1) {
|
|
1143
|
+
origin.rowspan = newRowspan;
|
|
1144
|
+
} else {
|
|
1145
|
+
delete origin.rowspan;
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
private clearMergedIntoRefs(
|
|
1151
|
+
startRow: number, endRow: number, startCol: number, endCol: number,
|
|
1152
|
+
oldOriginRow: number, oldOriginCol: number,
|
|
1153
|
+
skipRow: number, skipCol: number,
|
|
1154
|
+
newRef: [number, number] | undefined
|
|
1155
|
+
): void {
|
|
1156
|
+
this.contentGrid.slice(startRow, endRow).forEach((_gridRow, ri) => {
|
|
1157
|
+
const dr = startRow + ri;
|
|
1158
|
+
|
|
1159
|
+
this.contentGrid[dr].slice(startCol, endCol).forEach((_spanned, ci) => {
|
|
1160
|
+
const dc = startCol + ci;
|
|
1161
|
+
|
|
1162
|
+
if (dr === skipRow && dc === skipCol) {
|
|
1163
|
+
return;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
const spanned = this.contentGrid[dr]?.[dc];
|
|
1167
|
+
|
|
1168
|
+
if (spanned?.mergedInto?.[0] === oldOriginRow && spanned?.mergedInto?.[1] === oldOriginCol) {
|
|
1169
|
+
if (newRef === undefined) {
|
|
1170
|
+
delete spanned.mergedInto;
|
|
1171
|
+
} else {
|
|
1172
|
+
spanned.mergedInto = newRef;
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
private clearMergedIntoRefsForDissolve(
|
|
1180
|
+
startRow: number, endRow: number, startCol: number, endCol: number,
|
|
1181
|
+
skipOriginRow: number, skipOriginCol: number, deletedRow: number
|
|
1182
|
+
): void {
|
|
1183
|
+
this.contentGrid.slice(startRow, endRow).forEach((_gridRow, ri) => {
|
|
1184
|
+
const dr = startRow + ri;
|
|
1185
|
+
|
|
1186
|
+
if (dr === deletedRow) {
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
this.contentGrid[dr].slice(startCol, endCol).forEach((_spanned, ci) => {
|
|
1191
|
+
const dc = startCol + ci;
|
|
1192
|
+
|
|
1193
|
+
if (dr === skipOriginRow && dc === skipOriginCol) {
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
const spanned = this.contentGrid[dr]?.[dc];
|
|
1198
|
+
|
|
1199
|
+
if (spanned?.mergedInto) {
|
|
1200
|
+
delete spanned.mergedInto;
|
|
1201
|
+
}
|
|
1202
|
+
});
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
/**
|
|
1207
|
+
* Before deleting a column, handle merge origins and covered cells in that column.
|
|
1208
|
+
* Symmetric to contractSpansForDeletedRow.
|
|
1209
|
+
*/
|
|
1210
|
+
private contractSpansForDeletedCol(colIndex: number): void {
|
|
1211
|
+
this.contentGrid.forEach((_row, r) => {
|
|
1212
|
+
const gridCell = this.contentGrid[r][colIndex];
|
|
1213
|
+
|
|
1214
|
+
if ((gridCell.colspan ?? 1) > 1 || (gridCell.rowspan ?? 1) > 1) {
|
|
1215
|
+
this.handleOriginInDeletedCol(colIndex, r);
|
|
1216
|
+
} else if (gridCell.mergedInto !== undefined) {
|
|
1217
|
+
this.handleCoveredInDeletedCol(colIndex, r);
|
|
1218
|
+
}
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
private handleOriginInDeletedCol(colIndex: number, r: number): void {
|
|
1223
|
+
const cell = this.contentGrid[r][colIndex];
|
|
1224
|
+
const rowspan = cell.rowspan ?? 1;
|
|
1225
|
+
const colspan = cell.colspan ?? 1;
|
|
1226
|
+
|
|
1227
|
+
if (colspan <= 1) {
|
|
1228
|
+
return;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
const newColspan = colspan - 1;
|
|
1232
|
+
const nextCol = colIndex + 1;
|
|
1233
|
+
|
|
1234
|
+
if (nextCol < (this.contentGrid[r]?.length ?? 0)) {
|
|
1235
|
+
this.transferOriginToNextCol(colIndex, r, nextCol, rowspan, colspan, newColspan);
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
delete cell.colspan;
|
|
1239
|
+
delete cell.rowspan;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
private transferOriginToNextCol(
|
|
1243
|
+
colIndex: number, r: number, nextCol: number,
|
|
1244
|
+
rowspan: number, colspan: number, newColspan: number
|
|
1245
|
+
): void {
|
|
1246
|
+
const cell = this.contentGrid[r][colIndex];
|
|
1247
|
+
const newOrigin = this.contentGrid[r][nextCol];
|
|
1248
|
+
|
|
1249
|
+
newOrigin.blocks = [...cell.blocks];
|
|
1250
|
+
cell.blocks = [];
|
|
1251
|
+
delete newOrigin.mergedInto;
|
|
1252
|
+
|
|
1253
|
+
if (newColspan === 1 && rowspan === 1) {
|
|
1254
|
+
delete newOrigin.colspan;
|
|
1255
|
+
delete newOrigin.rowspan;
|
|
1256
|
+
this.clearMergedIntoRefs(r, r + rowspan, nextCol, colIndex + colspan, r, colIndex, r, nextCol, undefined);
|
|
1257
|
+
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
if (newColspan > 1) {
|
|
1262
|
+
newOrigin.colspan = newColspan;
|
|
1263
|
+
} else {
|
|
1264
|
+
delete newOrigin.colspan;
|
|
1265
|
+
}
|
|
1266
|
+
if (rowspan > 1) {
|
|
1267
|
+
newOrigin.rowspan = rowspan;
|
|
1268
|
+
} else {
|
|
1269
|
+
delete newOrigin.rowspan;
|
|
1270
|
+
}
|
|
1271
|
+
this.clearMergedIntoRefs(r, r + rowspan, nextCol, colIndex + colspan, r, colIndex, r, nextCol, [r, nextCol]);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
private handleCoveredInDeletedCol(colIndex: number, r: number): void {
|
|
1275
|
+
const cell = this.contentGrid[r][colIndex];
|
|
1276
|
+
const [originRow, originCol] = cell.mergedInto as [number, number];
|
|
1277
|
+
|
|
1278
|
+
if (originCol === colIndex) {
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
const origin = this.contentGrid[originRow]?.[originCol];
|
|
1283
|
+
|
|
1284
|
+
if (!origin) {
|
|
1285
|
+
return;
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
const oColspan = origin.colspan ?? 1;
|
|
1289
|
+
const oRowspan = origin.rowspan ?? 1;
|
|
1290
|
+
const newColspan = oColspan - 1;
|
|
1291
|
+
|
|
1292
|
+
if (newColspan === 1 && oRowspan === 1) {
|
|
1293
|
+
delete origin.colspan;
|
|
1294
|
+
delete origin.rowspan;
|
|
1295
|
+
|
|
1296
|
+
this.clearMergedIntoRefsForDissolveCol(originRow, originRow + oRowspan, originCol, originCol + oColspan, originRow, originCol, colIndex);
|
|
1297
|
+
} else {
|
|
1298
|
+
if (newColspan > 1) {
|
|
1299
|
+
origin.colspan = newColspan;
|
|
1300
|
+
} else {
|
|
1301
|
+
delete origin.colspan;
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
private clearMergedIntoRefsForDissolveCol(
|
|
1307
|
+
startRow: number, endRow: number, startCol: number, endCol: number,
|
|
1308
|
+
skipOriginRow: number, skipOriginCol: number, deletedCol: number
|
|
1309
|
+
): void {
|
|
1310
|
+
this.contentGrid.slice(startRow, endRow).forEach((_gridRow, ri) => {
|
|
1311
|
+
const dr = startRow + ri;
|
|
1312
|
+
|
|
1313
|
+
this.contentGrid[dr].slice(startCol, endCol).forEach((_spanned, ci) => {
|
|
1314
|
+
const dc = startCol + ci;
|
|
1315
|
+
|
|
1316
|
+
if (dr === skipOriginRow && dc === skipOriginCol) {
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
if (dc === deletedCol) {
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
const spanned = this.contentGrid[dr]?.[dc];
|
|
1325
|
+
|
|
1326
|
+
if (spanned?.mergedInto) {
|
|
1327
|
+
delete spanned.mergedInto;
|
|
1328
|
+
}
|
|
1329
|
+
});
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
/**
|
|
1334
|
+
* Check if any cell in a row is involved in a merge that extends beyond the row.
|
|
1335
|
+
*/
|
|
1336
|
+
private isRowInvolvedInMerge(rowIndex: number): boolean {
|
|
1337
|
+
const row = this.contentGrid[rowIndex];
|
|
1338
|
+
|
|
1339
|
+
return row.some(cell => {
|
|
1340
|
+
// Origin with rowspan > 1 means it extends to other rows
|
|
1341
|
+
if ((cell.rowspan ?? 1) > 1) {
|
|
1342
|
+
return true;
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
// Covered by a merge from a different row
|
|
1346
|
+
return cell.mergedInto !== undefined && cell.mergedInto[0] !== rowIndex;
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
/**
|
|
1351
|
+
* Check if any cell in a column is involved in a merge that extends beyond the column.
|
|
1352
|
+
*/
|
|
1353
|
+
private isColInvolvedInMerge(colIndex: number): boolean {
|
|
1354
|
+
return this.contentGrid.some(row => {
|
|
1355
|
+
const cell = row[colIndex];
|
|
1356
|
+
|
|
1357
|
+
// Origin with colspan > 1 means it extends to other columns
|
|
1358
|
+
if ((cell.colspan ?? 1) > 1) {
|
|
1359
|
+
return true;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
// Covered by a merge from a different column
|
|
1363
|
+
return cell.mergedInto !== undefined && cell.mergedInto[1] !== colIndex;
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
/**
|
|
1368
|
+
* After a row move (splice from, splice to), rebuild mergedInto row coordinates
|
|
1369
|
+
* by computing the index remapping.
|
|
1370
|
+
*/
|
|
1371
|
+
private rebuildMergedIntoRowCoordinates(from: number, to: number): void {
|
|
1372
|
+
const rowCount = this.contentGrid.length;
|
|
1373
|
+
const mapping = this.buildMoveMapping(rowCount, from, to);
|
|
1374
|
+
|
|
1375
|
+
this.contentGrid.forEach((_row, r) => {
|
|
1376
|
+
this.contentGrid[r].forEach((_cell, c) => {
|
|
1377
|
+
const gridCell = this.contentGrid[r][c];
|
|
1378
|
+
|
|
1379
|
+
if (gridCell.mergedInto !== undefined) {
|
|
1380
|
+
const oldOriginRow = gridCell.mergedInto[0];
|
|
1381
|
+
|
|
1382
|
+
gridCell.mergedInto = [mapping[oldOriginRow], gridCell.mergedInto[1]];
|
|
1383
|
+
}
|
|
1384
|
+
});
|
|
1385
|
+
});
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
/**
|
|
1389
|
+
* After a column move (splice from, splice to), rebuild mergedInto col coordinates
|
|
1390
|
+
* by computing the index remapping.
|
|
1391
|
+
*/
|
|
1392
|
+
private rebuildMergedIntoColCoordinates(from: number, to: number): void {
|
|
1393
|
+
const colCount = this.cols;
|
|
1394
|
+
const mapping = this.buildMoveMapping(colCount, from, to);
|
|
1395
|
+
|
|
1396
|
+
this.contentGrid.forEach((_row, r) => {
|
|
1397
|
+
this.contentGrid[r].forEach((_cell, c) => {
|
|
1398
|
+
const gridCell = this.contentGrid[r][c];
|
|
1399
|
+
|
|
1400
|
+
if (gridCell.mergedInto !== undefined) {
|
|
1401
|
+
const oldOriginCol = gridCell.mergedInto[1];
|
|
1402
|
+
|
|
1403
|
+
gridCell.mergedInto = [gridCell.mergedInto[0], mapping[oldOriginCol]];
|
|
1404
|
+
}
|
|
1405
|
+
});
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
private buildMoveMapping(count: number, from: number, to: number): number[] {
|
|
1410
|
+
return Array.from({ length: count }, (_, oldIdx) => {
|
|
1411
|
+
if (oldIdx === from) {
|
|
1412
|
+
return to;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
const afterRemove = oldIdx > from ? oldIdx - 1 : oldIdx;
|
|
1416
|
+
|
|
1417
|
+
return afterRemove >= to ? afterRemove + 1 : afterRemove;
|
|
1418
|
+
});
|
|
1419
|
+
}
|
|
1420
|
+
|
|
537
1421
|
// ─── Private helpers ────────────────────────────────────────────
|
|
538
1422
|
|
|
539
1423
|
/**
|
|
@@ -564,6 +1448,22 @@ export class TableModel {
|
|
|
564
1448
|
normalized.textColor = cell.textColor;
|
|
565
1449
|
}
|
|
566
1450
|
|
|
1451
|
+
if (cell.placement !== undefined) {
|
|
1452
|
+
normalized.placement = cell.placement;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
if (cell.colspan !== undefined && cell.colspan > 1) {
|
|
1456
|
+
normalized.colspan = cell.colspan;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
if (cell.rowspan !== undefined && cell.rowspan > 1) {
|
|
1460
|
+
normalized.rowspan = cell.rowspan;
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
if (cell.mergedInto !== undefined) {
|
|
1464
|
+
normalized.mergedInto = [...cell.mergedInto];
|
|
1465
|
+
}
|
|
1466
|
+
|
|
567
1467
|
return normalized;
|
|
568
1468
|
}
|
|
569
1469
|
|