@jackuait/blok 0.10.12 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blok.mjs +2 -2
- package/dist/chunks/{_basePickBy--UeZi0iS.mjs → _basePickBy-6gOwWeg0.mjs} +2 -2
- package/dist/chunks/{_baseUniq-C977U_l-.mjs → _baseUniq-BcOWmEX6.mjs} +2 -2
- package/dist/chunks/{arc-Woh6y3jm.mjs → arc-kVpio4JL.mjs} +2 -2
- package/dist/chunks/architecture-YZFGNWBL-BFcrDSEW.mjs +3 -0
- package/dist/chunks/{architectureDiagram-Q4EWVU46-GTqLmLqg.mjs → architectureDiagram-Q4EWVU46-CN6p4Aji.mjs} +19 -19
- package/dist/chunks/{blockDiagram-DXYQGD6D-CML01I1L.mjs → blockDiagram-DXYQGD6D-BvZWa5Rv.mjs} +12 -12
- package/dist/chunks/{blok-Cb7w54t6.mjs → blok-CUidffof.mjs} +1668 -1652
- package/dist/chunks/{c4Diagram-AHTNJAMY-C29OuYjO.mjs → c4Diagram-AHTNJAMY-Cmc2PsEs.mjs} +5 -5
- package/dist/chunks/{channel-Zp_OyvEW.mjs → channel-BTWFNzkv.mjs} +1 -1
- package/dist/chunks/{chunk-2KRD3SAO-mVfUZfox.mjs → chunk-2KRD3SAO-DWLzBIZw.mjs} +1 -1
- package/dist/chunks/{chunk-336JU56O-mJNxs0cr.mjs → chunk-336JU56O-DbaX7hyp.mjs} +7 -7
- package/dist/chunks/{chunk-426QAEUC-TajZlyP-.mjs → chunk-426QAEUC-pmH9mm_X.mjs} +2 -2
- package/dist/chunks/{chunk-4BX2VUAB-CsopMMb6.mjs → chunk-4BX2VUAB-B1LZI9QZ.mjs} +1 -1
- package/dist/chunks/{chunk-4TB4RGXK-DC963IrJ.mjs → chunk-4TB4RGXK-BC8qRYSD.mjs} +8 -8
- package/dist/chunks/{chunk-55IACEB6-yyL3mncJ.mjs → chunk-55IACEB6-CaLO8kWA.mjs} +1 -1
- package/dist/chunks/{chunk-5FUZZQ4R-Dr4NE8rh.mjs → chunk-5FUZZQ4R-DAWdfx4J.mjs} +7 -7
- package/dist/chunks/{chunk-5PVQY5BW-BP7ENjg7.mjs → chunk-5PVQY5BW-7Voh8aPS.mjs} +4 -4
- package/dist/chunks/{chunk-67CJDMHE-Dbl-PjEf.mjs → chunk-67CJDMHE-DSEGOn_f.mjs} +1 -1
- package/dist/chunks/{chunk-7N4EOEYR-p-g3cKuX.mjs → chunk-7N4EOEYR-CnSg1Hfu.mjs} +1 -1
- package/dist/chunks/{chunk-AA7GKIK3-Dt0Kr5Va.mjs → chunk-AA7GKIK3-BmatWFnp.mjs} +1 -1
- package/dist/chunks/{chunk-BSJP7CBP-DGU2WHwh.mjs → chunk-BSJP7CBP-BtFfqv7R.mjs} +1 -1
- package/dist/chunks/{chunk-CIAEETIT-BQ4crY5r.mjs → chunk-CIAEETIT-nVgPUEW1.mjs} +1 -1
- package/dist/chunks/{chunk-EDXVE4YY-B9_aGwkV.mjs → chunk-EDXVE4YY-e7599cf4.mjs} +2 -2
- package/dist/chunks/{chunk-ENJZ2VHE-23pY8ft5.mjs → chunk-ENJZ2VHE-DaMNdqfV.mjs} +10 -10
- package/dist/chunks/{chunk-FMBD7UC4-D_RQlBGX.mjs → chunk-FMBD7UC4-xT5c0WSd.mjs} +1 -1
- package/dist/chunks/{chunk-FOC6F5B3-CJfr-iwx.mjs → chunk-FOC6F5B3-AxSG6qaj.mjs} +1 -1
- package/dist/chunks/{chunk-ICPOFSXX-BOvOTlG6.mjs → chunk-ICPOFSXX-DbL0YBQf.mjs} +2 -2
- package/dist/chunks/{chunk-K5T4RW27-CHSI0vpp.mjs → chunk-K5T4RW27-CYdwJMQV.mjs} +5 -5
- package/dist/chunks/{chunk-KGLVRYIC-ngXT4XVA.mjs → chunk-KGLVRYIC-BwOmLwqF.mjs} +1 -1
- package/dist/chunks/{chunk-LIHQZDEY-CnP7bym1.mjs → chunk-LIHQZDEY-Csx8-523.mjs} +1 -1
- package/dist/chunks/{chunk-ORNJ4GCN-BPaghT45.mjs → chunk-ORNJ4GCN-CCDHRflI.mjs} +1 -1
- package/dist/chunks/{chunk-OYMX7WX6-CKjTvqTg.mjs → chunk-OYMX7WX6-BAoDgMPF.mjs} +6 -6
- package/dist/chunks/{chunk-QZHKN3VN-uW1N2UWF.mjs → chunk-QZHKN3VN-D1myzhE_.mjs} +1 -1
- package/dist/chunks/{chunk-U2HBQHQK-DiQOEtQH.mjs → chunk-U2HBQHQK-BXyrI_xP.mjs} +3 -3
- package/dist/chunks/{chunk-X2U36JSP-Cznp5Jm-.mjs → chunk-X2U36JSP-CXhWYelJ.mjs} +2 -2
- package/dist/chunks/{chunk-XPW4576I-W5t_agZI.mjs → chunk-XPW4576I-DOztVf6t.mjs} +1 -1
- package/dist/chunks/{chunk-YZCP3GAM-BV02tG_z.mjs → chunk-YZCP3GAM-DrkjtME-.mjs} +3 -3
- package/dist/chunks/{chunk-ZZ45TVLE-D28EyJ6R.mjs → chunk-ZZ45TVLE-CSFFLvxb.mjs} +3 -3
- package/dist/chunks/classDiagram-6PBFFD2Q-Ci3S9iu3.mjs +30 -0
- package/dist/chunks/classDiagram-v2-HSJHXN6E-BkaFKbgJ.mjs +30 -0
- package/dist/chunks/{clone-CUNvBGto.mjs → clone-WSLD7bVs.mjs} +1 -1
- package/dist/chunks/{constants-C0aZXxoO.mjs → constants-C4TrPxXY.mjs} +14 -12
- package/dist/chunks/{core-B7mxBIHA.mjs → core-D2KrVz4a.mjs} +1 -1
- package/dist/chunks/{cose-bilkent-S5V4N54A-D-Xgf_Xn.mjs → cose-bilkent-S5V4N54A-BXBidSxC.mjs} +2 -2
- package/dist/chunks/{cpp-DaTV1RSp.mjs → cpp-DnMQuZPn.mjs} +2 -2
- package/dist/chunks/{dagre-dysBn-m8.mjs → dagre-C7z2UZ4M.mjs} +6 -6
- package/dist/chunks/{dagre-KV5264BT-BB3SAlfA.mjs → dagre-KV5264BT-Ct6qUqKI.mjs} +15 -15
- package/dist/chunks/{diagram-5BDNPKRD-B1410bPG.mjs → diagram-5BDNPKRD-B9hNG7ht.mjs} +18 -18
- package/dist/chunks/{diagram-G4DWMVQ6-CdhBBETB.mjs → diagram-G4DWMVQ6-9_YOaVXe.mjs} +21 -21
- package/dist/chunks/{diagram-MMDJMWI5-B3HWfHe1.mjs → diagram-MMDJMWI5-DmStUoNk.mjs} +17 -17
- package/dist/chunks/{diagram-TYMM5635-D0JzRYCN.mjs → diagram-TYMM5635-DmrkkW85.mjs} +17 -17
- package/dist/chunks/{erDiagram-SMLLAGMA-DfIG0QBk.mjs → erDiagram-SMLLAGMA-5vkZ5DwJ.mjs} +14 -14
- package/dist/chunks/{flowDiagram-DWJPFMVM-BOL8JsQX.mjs → flowDiagram-DWJPFMVM-CGTiQBd7.mjs} +17 -17
- package/dist/chunks/{ganttDiagram-T4ZO3ILL-CiUr_YRw.mjs → ganttDiagram-T4ZO3ILL-BNtXyM0I.mjs} +7 -7
- package/dist/chunks/gitGraph-7Q5UKJZL-DxMmuJIv.mjs +3 -0
- package/dist/chunks/{gitGraphDiagram-UUTBAWPF-CtNkTTWO.mjs → gitGraphDiagram-UUTBAWPF-CmQR-xZp.mjs} +17 -17
- package/dist/chunks/{graphlib-BXNPwKuI.mjs → graphlib-BfwqhpXp.mjs} +3 -3
- package/dist/chunks/{graphql-DNumR9m-.mjs → graphql-4Htarzhp.mjs} +2 -2
- package/dist/chunks/{html-CanPsi1Y.mjs → html-DW39yhuS.mjs} +2 -2
- package/dist/chunks/{i18next-loader-453gJdot.mjs → i18next-loader-CyDs2NKf.mjs} +2 -2
- package/dist/chunks/info-OMHHGYJF-ChWZqC0a.mjs +3 -0
- package/dist/chunks/{infoDiagram-42DDH7IO-CD7nVBvi.mjs → infoDiagram-42DDH7IO-BbV_tozh.mjs} +14 -14
- package/dist/chunks/{isEmpty-D8B0aRsG.mjs → isEmpty-jlCmuYeg.mjs} +1 -1
- package/dist/chunks/{ishikawaDiagram-UXIWVN3A-BOaC9qJs.mjs → ishikawaDiagram-UXIWVN3A-DJBG3b-A.mjs} +6 -6
- package/dist/chunks/{journeyDiagram-VCZTEJTY-DKf55ZdJ.mjs → journeyDiagram-VCZTEJTY-BdMsFn3r.mjs} +6 -6
- package/dist/chunks/{kanban-definition-6JOO6SKY-D2CrAXqB.mjs → kanban-definition-6JOO6SKY-ncNaxcxH.mjs} +11 -11
- package/dist/chunks/{latex-DY1HNB4U.mjs → latex-BeVX0E4Z.mjs} +1 -1
- package/dist/chunks/{line-CuvDsrkE.mjs → line-CWJNfvdn.mjs} +3 -3
- package/dist/chunks/{linear-JRIqMpGQ.mjs → linear-BU4OjSPS.mjs} +3 -3
- package/dist/chunks/{lua-COOfzihE.mjs → lua-CPnWrc7C.mjs} +1 -1
- package/dist/chunks/{mdast-util-math-D56mMxhB.mjs → mdast-util-math-D42zbZda.mjs} +1 -1
- package/dist/chunks/{mermaid-parser.core-BhpZC2lA.mjs → mermaid-parser.core-DBhkcRo7.mjs} +10 -10
- package/dist/chunks/{mermaid.core-C40gcVfv.mjs → mermaid.core-uSzF9nF1.mjs} +45 -45
- package/dist/chunks/{micromark-extension-math-D-s54WWf.mjs → micromark-extension-math-x3wvkKaN.mjs} +2 -2
- package/dist/chunks/{mindmap-definition-QFDTVHPH-C-0fwUUS.mjs → mindmap-definition-QFDTVHPH-BfOyKFtC.mjs} +13 -13
- package/dist/chunks/notifier-B-wErJJB.mjs +73 -0
- package/dist/chunks/{ordinal-fyJMP-lj.mjs → ordinal-CN3SDQau.mjs} +1 -1
- package/dist/chunks/packet-4T2RLAQJ-7DW35MGl.mjs +3 -0
- package/dist/chunks/{php-DA-SOiqC.mjs → php-Dejkjxb5.mjs} +6 -6
- package/dist/chunks/pie-ZZUOXDRM-Dtuq0w2k.mjs +3 -0
- package/dist/chunks/{pieDiagram-DEJITSTG-BPyqheXv.mjs → pieDiagram-DEJITSTG-B1sjciNi.mjs} +21 -21
- package/dist/chunks/{quadrantDiagram-34T5L4WZ-kOZ1zIXB.mjs → quadrantDiagram-34T5L4WZ-CV838wf-.mjs} +4 -4
- package/dist/chunks/radar-PYXPWWZC-Bz4lwSbg.mjs +3 -0
- package/dist/chunks/{requirementDiagram-MS252O5E-C8Zkq6Lq.mjs → requirementDiagram-MS252O5E-CA3LUAVZ.mjs} +13 -13
- package/dist/chunks/{ruby-HDUjp8gK.mjs → ruby-Z7wCYjey.mjs} +11 -11
- package/dist/chunks/{sankeyDiagram-XADWPNL6-B0FhkAL9.mjs → sankeyDiagram-XADWPNL6-Cw8wB2YO.mjs} +3 -3
- package/dist/chunks/{sequenceDiagram-FGHM5R23-Dv2H5Lbc.mjs → sequenceDiagram-FGHM5R23-pm0MaeXC.mjs} +7 -7
- package/dist/chunks/{stateDiagram-FHFEXIEX-D1vcO7H_.mjs → stateDiagram-FHFEXIEX-CMcsvm0M.mjs} +17 -17
- package/dist/chunks/stateDiagram-v2-QKLJ7IA2-C4nZGNBm.mjs +28 -0
- package/dist/chunks/{timeline-definition-GMOUNBTQ-DJmJ0TPa.mjs → timeline-definition-GMOUNBTQ-DwHKPj3j.mjs} +6 -6
- package/dist/chunks/{tools-vS7102lG.mjs → tools-CmNY86rS.mjs} +116 -110
- package/dist/chunks/treeView-SZITEDCU-DPG9FJ6Q.mjs +3 -0
- package/dist/chunks/treemap-W4RFUUIX-N4tZJR1-.mjs +3 -0
- package/dist/chunks/types-BNvlbr9u.mjs +4 -0
- package/dist/chunks/{vennDiagram-DHZGUBPP-Dx1rMP24.mjs → vennDiagram-DHZGUBPP-Gfy0QWtB.mjs} +6 -6
- package/dist/chunks/wardley-RL74JXVD-C7Hzc5y2.mjs +3 -0
- package/dist/chunks/{wardleyDiagram-NUSXRM2D-Dnm6lvMn.mjs → wardleyDiagram-NUSXRM2D-ChZiL3a0.mjs} +15 -15
- package/dist/chunks/{xml-Dq1lpp8G.mjs → xml-C1PUeKuL.mjs} +1 -1
- package/dist/chunks/{xychartDiagram-5P7HB3ND-C9wFc2e9.mjs → xychartDiagram-5P7HB3ND-t_dhLiOA.mjs} +11 -11
- package/dist/full.mjs +3 -3
- package/dist/markdown.mjs +4 -4
- package/dist/react.mjs +2 -2
- package/dist/tools.mjs +2 -2
- package/package.json +1 -1
- package/src/blok.ts +5 -0
- package/src/components/modules/api/blocks.ts +34 -0
- package/src/components/modules/api/notifier.ts +24 -11
- package/src/components/modules/renderer.ts +7 -0
- package/src/components/ui/toolbox.ts +30 -25
- package/src/components/utils/notifier/draw.ts +43 -143
- package/src/components/utils/notifier/index.ts +76 -37
- package/src/components/utils/notifier/types.ts +3 -0
- package/src/components/utils/notifier.ts +17 -4
- package/src/components/utils/popover/popover-desktop.ts +23 -2
- package/src/styles/main.css +19 -0
- package/src/tools/callout/index.ts +8 -1
- package/src/tools/callout/types.ts +8 -1
- package/types/configs/blok-config.d.ts +15 -0
- package/types/configs/notifier.d.ts +11 -0
- package/dist/chunks/architecture-YZFGNWBL-aVO23UKm.mjs +0 -3
- package/dist/chunks/classDiagram-6PBFFD2Q-DXsClapu.mjs +0 -30
- package/dist/chunks/classDiagram-v2-HSJHXN6E-B6TlQ_PM.mjs +0 -30
- package/dist/chunks/gitGraph-7Q5UKJZL-B3aq166w.mjs +0 -3
- package/dist/chunks/info-OMHHGYJF-SX91-Wub.mjs +0 -3
- package/dist/chunks/notifier-PpnFhM0m.mjs +0 -96
- package/dist/chunks/packet-4T2RLAQJ-suhU85JN.mjs +0 -3
- package/dist/chunks/pie-ZZUOXDRM-DF5e16CP.mjs +0 -3
- package/dist/chunks/radar-PYXPWWZC-DgzodpRv.mjs +0 -3
- package/dist/chunks/stateDiagram-v2-QKLJ7IA2-AoHzFiaI.mjs +0 -28
- package/dist/chunks/treeView-SZITEDCU-C1mc9PWf.mjs +0 -3
- package/dist/chunks/treemap-W4RFUUIX-ClV9Slyp.mjs +0 -3
- package/dist/chunks/wardley-RL74JXVD-Dj7t7jHR.mjs +0 -3
- /package/dist/chunks/{am-Bbd7cTHS.mjs → am-JTszxMum.mjs} +0 -0
- /package/dist/chunks/{ar-Bo71sCQE.mjs → ar-CME8m7Ug.mjs} +0 -0
- /package/dist/chunks/{array-DbiMs_0t.mjs → array-B4E6ednJ.mjs} +0 -0
- /package/dist/chunks/{az-BnNrO_xK.mjs → az-CU1BXEnK.mjs} +0 -0
- /package/dist/chunks/{bg-CMd2n-OG.mjs → bg-C1QKbOOv.mjs} +0 -0
- /package/dist/chunks/{bn-B3lorfXA.mjs → bn-DbDE4DPn.mjs} +0 -0
- /package/dist/chunks/{bs-_zM8QBsA.mjs → bs-5jPxlF97.mjs} +0 -0
- /package/dist/chunks/{c-DmKJe6GM.mjs → c-CQrSye6K.mjs} +0 -0
- /package/dist/chunks/{ccount-C9Y7nqDe.mjs → ccount-B7is2MU0.mjs} +0 -0
- /package/dist/chunks/{cs-nodpmLBf.mjs → cs-BEZB2qcc.mjs} +0 -0
- /package/dist/chunks/{csharp-Drv96dbi.mjs → csharp-ByiKf6DR.mjs} +0 -0
- /package/dist/chunks/{css-82tNAoU6.mjs → css-BqsWMbBt.mjs} +0 -0
- /package/dist/chunks/{cytoscape.esm-DSb9a7HE.mjs → cytoscape.esm-CWkCAUzT.mjs} +0 -0
- /package/dist/chunks/{da-DwzgQcXQ.mjs → da-DXZ2uOgL.mjs} +0 -0
- /package/dist/chunks/{dart-DE9j8McI.mjs → dart-aYsezAEv.mjs} +0 -0
- /package/dist/chunks/{de-BvWPiNt6.mjs → de-D4FxC1Yq.mjs} +0 -0
- /package/dist/chunks/{default-qigT1Xpq.mjs → default-DPWNu2LM.mjs} +0 -0
- /package/dist/chunks/{defaultLocale-yTyMJ3IT.mjs → defaultLocale-BYV2aVaI.mjs} +0 -0
- /package/dist/chunks/{dist-X14EnMrO.mjs → dist-CKM-fjTE.mjs} +0 -0
- /package/dist/chunks/{dockerfile-D9DFksUy.mjs → dockerfile-1GBIWF66.mjs} +0 -0
- /package/dist/chunks/{el-B_D7wUrZ.mjs → el-DwIVDdku.mjs} +0 -0
- /package/dist/chunks/{engine-javascript-Bmmg8uL9.mjs → engine-javascript-CYa8VRAu.mjs} +0 -0
- /package/dist/chunks/{es-Bn_ZFyW9.mjs → es-DlO4MePt.mjs} +0 -0
- /package/dist/chunks/{et-CUcULjoh.mjs → et-BBSbb8pL.mjs} +0 -0
- /package/dist/chunks/{fa-BRhCTsOy.mjs → fa-DsJou-pw.mjs} +0 -0
- /package/dist/chunks/{fi-BEvyU9n6.mjs → fi-CsMgo7Wk.mjs} +0 -0
- /package/dist/chunks/{fil-Dlp1_W2B.mjs → fil-Dlw8sEta.mjs} +0 -0
- /package/dist/chunks/{fr-DJBeOAx1.mjs → fr-DeapG5NH.mjs} +0 -0
- /package/dist/chunks/{go-jyWjtO8q.mjs → go-4mRqLTld.mjs} +0 -0
- /package/dist/chunks/{gu-0hWvx16l.mjs → gu-klAnA_ns.mjs} +0 -0
- /package/dist/chunks/{he-CYe88qXp.mjs → he-9TdyXc1J.mjs} +0 -0
- /package/dist/chunks/{hi-DuLkkPWn.mjs → hi-DVOss_Zp.mjs} +0 -0
- /package/dist/chunks/{hr-BwCB1IMW.mjs → hr-CXo-QFLf.mjs} +0 -0
- /package/dist/chunks/{hu-C2dLyTeX.mjs → hu-B6uKq-NU.mjs} +0 -0
- /package/dist/chunks/{hy-DXKoDpv9.mjs → hy-B7CWqbUW.mjs} +0 -0
- /package/dist/chunks/{i18next-CLUkHqmV.mjs → i18next-BFvS_Rnh.mjs} +0 -0
- /package/dist/chunks/{id-D4chLuW_.mjs → id-C5d2QGEQ.mjs} +0 -0
- /package/dist/chunks/{init-BlLeEogJ.mjs → init-C3Dyaaly.mjs} +0 -0
- /package/dist/chunks/{isArrayLikeObject-DzUNFfIK.mjs → isArrayLikeObject-B-1mfvNK.mjs} +0 -0
- /package/dist/chunks/{it-Hto3G26t.mjs → it-BgPXC2_F.mjs} +0 -0
- /package/dist/chunks/{ja-UxHm_PPZ.mjs → ja-CQ7ujOz3.mjs} +0 -0
- /package/dist/chunks/{java-Dhv78FEb.mjs → java-DD_iwrM-.mjs} +0 -0
- /package/dist/chunks/{javascript-DilE9EuZ.mjs → javascript-CJBlE5PB.mjs} +0 -0
- /package/dist/chunks/{json-LUtHrtDA.mjs → json-yRGZVu2_.mjs} +0 -0
- /package/dist/chunks/{ka-BnjXwPUq.mjs → ka-DAPmSm_-.mjs} +0 -0
- /package/dist/chunks/{katex-B8jUB5Cv.mjs → katex-Bbz34ZLq.mjs} +0 -0
- /package/dist/chunks/{km-exgzZBIE.mjs → km-BJ9H-RbD.mjs} +0 -0
- /package/dist/chunks/{kn-DjjUg8aO.mjs → kn-CthdB8vH.mjs} +0 -0
- /package/dist/chunks/{ko-Cu0YUSV6.mjs → ko-DbEA41LU.mjs} +0 -0
- /package/dist/chunks/{kotlin-DFLPXbOQ.mjs → kotlin-BmkhKZGf.mjs} +0 -0
- /package/dist/chunks/{ku-D-IxJ0fx.mjs → ku-B_j9qSrv.mjs} +0 -0
- /package/dist/chunks/{lightweight-i18n-DSjG0iTr.mjs → lightweight-i18n-Bb_VS9v5.mjs} +0 -0
- /package/dist/chunks/{lo-BcwjJBcv.mjs → lo-DSklR1Zs.mjs} +0 -0
- /package/dist/chunks/{lt-Bt05MFPC.mjs → lt-C9aVbfRt.mjs} +0 -0
- /package/dist/chunks/{lv-B01TmEFW.mjs → lv-DLwMSEc0.mjs} +0 -0
- /package/dist/chunks/{markdown-C6pnqcPd.mjs → markdown-DSiOSAsn.mjs} +0 -0
- /package/dist/chunks/{mermaid-BKA834jS.mjs → mermaid-C2y_3PIg.mjs} +0 -0
- /package/dist/chunks/{messages-Bq7fo8X0.mjs → messages--c74ihtM.mjs} +0 -0
- /package/dist/chunks/{messages-zcqQ8x232.mjs → messages-041mNyU42.mjs} +0 -0
- /package/dist/chunks/{messages-v26RM5PC.mjs → messages-44SP7ajI.mjs} +0 -0
- /package/dist/chunks/{messages-x_eMclsl2.mjs → messages-7NvouWKA2.mjs} +0 -0
- /package/dist/chunks/{messages-9Nx7kteY2.mjs → messages-AnuHiDPc2.mjs} +0 -0
- /package/dist/chunks/{messages-CIre8L_r.mjs → messages-B1V7UT9I.mjs} +0 -0
- /package/dist/chunks/{messages-B9mzGzZ_.mjs → messages-B2Q9NH4D.mjs} +0 -0
- /package/dist/chunks/{messages-CWm_2RvD2.mjs → messages-B6j77WNV2.mjs} +0 -0
- /package/dist/chunks/{messages-DtssWM8x2.mjs → messages-BEV0lzGv2.mjs} +0 -0
- /package/dist/chunks/{messages-CRH0RWBs.mjs → messages-BG749_88.mjs} +0 -0
- /package/dist/chunks/{messages-x6y6csd52.mjs → messages-BGpGj8nJ2.mjs} +0 -0
- /package/dist/chunks/{messages-D3fu2FHB2.mjs → messages-BNYDShPm2.mjs} +0 -0
- /package/dist/chunks/{messages-CF0SW1zy.mjs → messages-BW--wNis.mjs} +0 -0
- /package/dist/chunks/{messages-Dobxrshu2.mjs → messages-B_Mqw9Dl2.mjs} +0 -0
- /package/dist/chunks/{messages-BmC2yhsC2.mjs → messages-BbYwT3FH2.mjs} +0 -0
- /package/dist/chunks/{messages-BkaUIuz-2.mjs → messages-Bda8jwos2.mjs} +0 -0
- /package/dist/chunks/{messages-C7E8C3-S.mjs → messages-BdpFAZGZ.mjs} +0 -0
- /package/dist/chunks/{messages-rNLuCrAb.mjs → messages-BmNLNUz_.mjs} +0 -0
- /package/dist/chunks/{messages-DPcc6xp-.mjs → messages-BnGtg6t4.mjs} +0 -0
- /package/dist/chunks/{messages-C9UIaF6N.mjs → messages-BnXkEkD_.mjs} +0 -0
- /package/dist/chunks/{messages-Bi629xgG.mjs → messages-BwtU06Ax.mjs} +0 -0
- /package/dist/chunks/{messages-D6_I0L06.mjs → messages-ByRcwLIO.mjs} +0 -0
- /package/dist/chunks/{messages-C9QhLDA2.mjs → messages-CHBH3EQG.mjs} +0 -0
- /package/dist/chunks/{messages-BJTwY1tq.mjs → messages-CIYU5iEj.mjs} +0 -0
- /package/dist/chunks/{messages-BSXBVdsp.mjs → messages-CJGOmFxi.mjs} +0 -0
- /package/dist/chunks/{messages-DmvWmURo.mjs → messages-CP7Ncgaf.mjs} +0 -0
- /package/dist/chunks/{messages-BK6AwU6C.mjs → messages-CP8YKa4F.mjs} +0 -0
- /package/dist/chunks/{messages-BUQTXTew2.mjs → messages-CUxaqK8t2.mjs} +0 -0
- /package/dist/chunks/{messages-CY76MvbX2.mjs → messages-CXDk_Rlr2.mjs} +0 -0
- /package/dist/chunks/{messages-CMMq-u7e.mjs → messages-CYZxR91M.mjs} +0 -0
- /package/dist/chunks/{messages-BSyO1EWC.mjs → messages-Cjm7Nj1C.mjs} +0 -0
- /package/dist/chunks/{messages-CAX3qQi0.mjs → messages-CjzZ6nxv.mjs} +0 -0
- /package/dist/chunks/{messages-x0kzc2oy.mjs → messages-CpVtcYqo.mjs} +0 -0
- /package/dist/chunks/{messages-mo5OrbVj2.mjs → messages-CumomgDd2.mjs} +0 -0
- /package/dist/chunks/{messages-E1tsNNG5.mjs → messages-CvCb4dCy.mjs} +0 -0
- /package/dist/chunks/{messages-Bo7Cbk_O.mjs → messages-D3DNj1jh.mjs} +0 -0
- /package/dist/chunks/{messages-PFfYbqlm.mjs → messages-D7d2U-tx.mjs} +0 -0
- /package/dist/chunks/{messages-DIVQmVS92.mjs → messages-DFWhnXF12.mjs} +0 -0
- /package/dist/chunks/{messages-nAdoEqRi.mjs → messages-DJr1x1i2.mjs} +0 -0
- /package/dist/chunks/{messages-DsMIxm6I2.mjs → messages-DN7PU5Un2.mjs} +0 -0
- /package/dist/chunks/{messages-DhoZXmg_.mjs → messages-DVh_Bwwq.mjs} +0 -0
- /package/dist/chunks/{messages-BsqBho4T.mjs → messages-DVwHxslb.mjs} +0 -0
- /package/dist/chunks/{messages-BPxMr5HC.mjs → messages-DZ1Pfnl0.mjs} +0 -0
- /package/dist/chunks/{messages--G2XLc8E.mjs → messages-Do3QV7QW.mjs} +0 -0
- /package/dist/chunks/{messages-Bhn5V9FQ2.mjs → messages-Drxwphbg2.mjs} +0 -0
- /package/dist/chunks/{messages-bIzBNzdr2.mjs → messages-DtloGH1v2.mjs} +0 -0
- /package/dist/chunks/{messages-DHzT8CZv.mjs → messages-Du0zg7UM.mjs} +0 -0
- /package/dist/chunks/{messages-z5pham9o.mjs → messages-DuA_D23n.mjs} +0 -0
- /package/dist/chunks/{messages-BS9zk4mI2.mjs → messages-DwKRw3jP2.mjs} +0 -0
- /package/dist/chunks/{messages-dGYum7sj2.mjs → messages-DzAYvMm72.mjs} +0 -0
- /package/dist/chunks/{messages-kKXlI5xZ.mjs → messages-Dzmge-lj.mjs} +0 -0
- /package/dist/chunks/{messages-CpLq4ZZg.mjs → messages-ETNAE7WV.mjs} +0 -0
- /package/dist/chunks/{messages-CrpOkt8c2.mjs → messages-F4r6ruTX2.mjs} +0 -0
- /package/dist/chunks/{messages-BCfsOOlp.mjs → messages-FNQdT9Da.mjs} +0 -0
- /package/dist/chunks/{messages-DiQkvwE32.mjs → messages-FYGyC6zk2.mjs} +0 -0
- /package/dist/chunks/{messages-B29Wm2zT.mjs → messages-ZS1Ro8ZB.mjs} +0 -0
- /package/dist/chunks/{messages-CJ8IkF1P.mjs → messages-dyhHlgE9.mjs} +0 -0
- /package/dist/chunks/{messages-DfLcy0CY.mjs → messages-fAEKtYXO.mjs} +0 -0
- /package/dist/chunks/{messages-DJYT0upW.mjs → messages-hhptyJO3.mjs} +0 -0
- /package/dist/chunks/{messages-3kHDtQLN.mjs → messages-hk4dinYI.mjs} +0 -0
- /package/dist/chunks/{messages-BimpUMRx.mjs → messages-knSLxvI6.mjs} +0 -0
- /package/dist/chunks/{messages-4Y8dL_1j2.mjs → messages-lORohDgW2.mjs} +0 -0
- /package/dist/chunks/{messages-Dass0QsQ.mjs → messages-mvnz8DvU.mjs} +0 -0
- /package/dist/chunks/{messages-DcUYfD6m.mjs → messages-pHWKsrcZ.mjs} +0 -0
- /package/dist/chunks/{messages-CR5irc8q.mjs → messages-q2McAyOz.mjs} +0 -0
- /package/dist/chunks/{messages-CEJtxBxU.mjs → messages-r62SI44r.mjs} +0 -0
- /package/dist/chunks/{messages-CKP6aUXN2.mjs → messages-uFdMhLbJ.mjs} +0 -0
- /package/dist/chunks/{micromark-factory-space-y4SDWQKm.mjs → micromark-factory-space-C6wz33de.mjs} +0 -0
- /package/dist/chunks/{mk-DlZNyDhn.mjs → mk-D96bSjMK.mjs} +0 -0
- /package/dist/chunks/{ml-CizMIOxl.mjs → ml-D1Ek94RG.mjs} +0 -0
- /package/dist/chunks/{mn-B_pDvxok.mjs → mn-CyNCFOYP.mjs} +0 -0
- /package/dist/chunks/{mr-D8D_7YmW.mjs → mr-CaA3xXVf.mjs} +0 -0
- /package/dist/chunks/{ms-CM93I8ec.mjs → ms-IZU-A3Qk.mjs} +0 -0
- /package/dist/chunks/{my-BGnGdDAV.mjs → my-C-AQLGIp.mjs} +0 -0
- /package/dist/chunks/{native-D0cfLXsM.mjs → native-CarRLbbJ.mjs} +0 -0
- /package/dist/chunks/{ne-C6ZmmqhH.mjs → ne-LaymXAjm.mjs} +0 -0
- /package/dist/chunks/{nl-UGFOU80W.mjs → nl-Dm1eVwTA.mjs} +0 -0
- /package/dist/chunks/{no-as-DKhC4.mjs → no-B2WicGhz.mjs} +0 -0
- /package/dist/chunks/{one-light-Di_o5Kb7.mjs → one-light-bqnXiA0I.mjs} +0 -0
- /package/dist/chunks/{pa-DiOAveAI.mjs → pa-ry61xHq9.mjs} +0 -0
- /package/dist/chunks/{path-7pA19U_d.mjs → path-Crax6eds.mjs} +0 -0
- /package/dist/chunks/{pl-DXk8ye3B.mjs → pl-DzCnx7eR.mjs} +0 -0
- /package/dist/chunks/{ps-CuxilZ3F.mjs → ps-DKXG6JHY.mjs} +0 -0
- /package/dist/chunks/{pt-DsT6E77q.mjs → pt-e09B0rEd.mjs} +0 -0
- /package/dist/chunks/{python-DYiHKGPV.mjs → python-tdu-oDWx.mjs} +0 -0
- /package/dist/chunks/{r-BZ4pC-Uz.mjs → r-D8fCyoTl.mjs} +0 -0
- /package/dist/chunks/{ro-CcAQOL-B.mjs → ro-HNnYR5pB.mjs} +0 -0
- /package/dist/chunks/{rough.esm-BPA_YwbP.mjs → rough.esm-CChKUjNP.mjs} +0 -0
- /package/dist/chunks/{ru-hD41D0Fd.mjs → ru-D_jTWgK8.mjs} +0 -0
- /package/dist/chunks/{rust-Db_HEGL5.mjs → rust-D5IQAarB.mjs} +0 -0
- /package/dist/chunks/{scala-B1kK21mu.mjs → scala-CbcMYkuq.mjs} +0 -0
- /package/dist/chunks/{sd-Biu7f00A.mjs → sd-B7bgXBin.mjs} +0 -0
- /package/dist/chunks/{shellscript-BBh7AxMC.mjs → shellscript-CZefq5l_.mjs} +0 -0
- /package/dist/chunks/{si-Bhto6prC.mjs → si-aQCsTBIp.mjs} +0 -0
- /package/dist/chunks/{sk-Ce7J4sHX.mjs → sk-Bjrct9rr.mjs} +0 -0
- /package/dist/chunks/{sl-Fz7idR9w.mjs → sl-DvS57kCB.mjs} +0 -0
- /package/dist/chunks/{sq-CnLb3bAQ.mjs → sq-BexoWiW2.mjs} +0 -0
- /package/dist/chunks/{sql-DHkazX4B.mjs → sql-C4ibVEDs.mjs} +0 -0
- /package/dist/chunks/{sr-Bc5JbF-b.mjs → sr-CXir4bLq.mjs} +0 -0
- /package/dist/chunks/{src-B3rrEIze.mjs → src-yreeH1hr.mjs} +0 -0
- /package/dist/chunks/{sv-B86P2LyK.mjs → sv-B_Owhjrs.mjs} +0 -0
- /package/dist/chunks/{sw-CnQXriTg.mjs → sw-B4p84FCO.mjs} +0 -0
- /package/dist/chunks/{swift-DZdprfb-.mjs → swift-Drpgj9J0.mjs} +0 -0
- /package/dist/chunks/{ta-CG4BbxjE.mjs → ta-BU_-jQ33.mjs} +0 -0
- /package/dist/chunks/{te-CkE35V1X.mjs → te-5FGke4TK.mjs} +0 -0
- /package/dist/chunks/{th-BCtkHu3E.mjs → th-DFyekAQ3.mjs} +0 -0
- /package/dist/chunks/{tr-D5Cexvko.mjs → tr-C7Zj3lX4.mjs} +0 -0
- /package/dist/chunks/{typescript-DhtGMhWX.mjs → typescript-Bnpf4OG6.mjs} +0 -0
- /package/dist/chunks/{ug-Bt9xMT4p.mjs → ug-DJwD0iui.mjs} +0 -0
- /package/dist/chunks/{uk-D1g7UV0v.mjs → uk-hkOj8kWN.mjs} +0 -0
- /package/dist/chunks/{ur-B69faQh_.mjs → ur-Cy5A8nFG.mjs} +0 -0
- /package/dist/chunks/{vi--gW42cZG.mjs → vi-CEt0cTzQ.mjs} +0 -0
- /package/dist/chunks/{vitesse-dark-B5oAIYZ5.mjs → vitesse-dark-dflHsflb.mjs} +0 -0
- /package/dist/chunks/{yaml-T4MCc8o4.mjs → yaml-CecI9urB.mjs} +0 -0
- /package/dist/chunks/{zh-DgQ6P8Lu.mjs → zh-BwQjLCGO.mjs} +0 -0
|
@@ -228,6 +228,8 @@ export class BlocksAPI extends Module {
|
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
this.Blok.ModificationsObserver.enable();
|
|
231
|
+
|
|
232
|
+
this.processPendingHashScroll();
|
|
231
233
|
}
|
|
232
234
|
|
|
233
235
|
/**
|
|
@@ -564,4 +566,36 @@ export class BlocksAPI extends Module {
|
|
|
564
566
|
throw new Error(`Index should be greater than or equal to 0`);
|
|
565
567
|
}
|
|
566
568
|
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* If Renderer.pendingHashScroll is set (hash-based scroll was deferred because the
|
|
572
|
+
* target block did not exist at init time), attempt to scroll to and select the block now.
|
|
573
|
+
* Always clears the pending hash afterward (one-shot).
|
|
574
|
+
*/
|
|
575
|
+
private processPendingHashScroll(): void {
|
|
576
|
+
const hash = this.Blok.Renderer.pendingHashScroll;
|
|
577
|
+
|
|
578
|
+
if (hash === null) {
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
this.Blok.Renderer.pendingHashScroll = null;
|
|
583
|
+
|
|
584
|
+
const el = document.querySelector(`[data-blok-id="${CSS.escape(hash)}"]`);
|
|
585
|
+
|
|
586
|
+
if (el === null) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
const topOffset = this.config.scrollToBlock?.topOffset ?? 0;
|
|
591
|
+
const y = el.getBoundingClientRect().top + window.scrollY - topOffset;
|
|
592
|
+
|
|
593
|
+
window.scrollTo({ top: y, behavior: 'smooth' });
|
|
594
|
+
|
|
595
|
+
const block = this.Blok.BlockManager.getBlockById(hash);
|
|
596
|
+
|
|
597
|
+
if (block !== undefined) {
|
|
598
|
+
this.Blok.BlockSelection.selectBlock(block);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
567
601
|
}
|
|
@@ -3,15 +3,24 @@ import type { ModuleConfig } from '../../../types-internal/module-config';
|
|
|
3
3
|
import { Module } from '../../__module';
|
|
4
4
|
import { Notifier } from '../../utils/notifier';
|
|
5
5
|
import type { ConfirmNotifierOptions, NotifierOptions, PromptNotifierOptions } from '../../utils/notifier/types';
|
|
6
|
+
import { DEFAULT_NOTIFIER_POSITION } from '../../utils/notifier/types';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
+
* Notifier API module — routes show() to the custom handler when the consumer
|
|
10
|
+
* provides one in BlokConfig.notifier, otherwise falls back to the built-in notifier.
|
|
9
11
|
*/
|
|
10
12
|
export class NotifierAPI extends Module {
|
|
11
13
|
/**
|
|
12
|
-
*
|
|
14
|
+
* Built-in notifier utility instance (used only when no custom handler is provided)
|
|
13
15
|
*/
|
|
14
|
-
private
|
|
16
|
+
private builtInNotifier: Notifier;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Optional consumer-provided notifier handler from BlokConfig
|
|
20
|
+
*/
|
|
21
|
+
private readonly customNotifier:
|
|
22
|
+
| ((options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions) => void)
|
|
23
|
+
| undefined;
|
|
15
24
|
|
|
16
25
|
/**
|
|
17
26
|
* @param moduleConfiguration - Module Configuration
|
|
@@ -19,12 +28,10 @@ export class NotifierAPI extends Module {
|
|
|
19
28
|
* @param moduleConfiguration.eventsDispatcher - Blok's event dispatcher
|
|
20
29
|
*/
|
|
21
30
|
constructor({ config, eventsDispatcher }: ModuleConfig) {
|
|
22
|
-
super({
|
|
23
|
-
config,
|
|
24
|
-
eventsDispatcher,
|
|
25
|
-
});
|
|
31
|
+
super({ config, eventsDispatcher });
|
|
26
32
|
|
|
27
|
-
this.
|
|
33
|
+
this.builtInNotifier = new Notifier(config.notifierPosition ?? DEFAULT_NOTIFIER_POSITION);
|
|
34
|
+
this.customNotifier = config.notifier;
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
/**
|
|
@@ -32,15 +39,21 @@ export class NotifierAPI extends Module {
|
|
|
32
39
|
*/
|
|
33
40
|
public get methods(): INotifier {
|
|
34
41
|
return {
|
|
35
|
-
show: (options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions): void =>
|
|
42
|
+
show: (options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions): void =>
|
|
43
|
+
this.show(options),
|
|
36
44
|
};
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
/**
|
|
40
|
-
* Show notification
|
|
48
|
+
* Show notification — delegates to custom handler if provided, else built-in
|
|
41
49
|
* @param {NotifierOptions} options - message option
|
|
42
50
|
*/
|
|
43
51
|
public show(options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions): void {
|
|
44
|
-
|
|
52
|
+
if (this.customNotifier !== undefined) {
|
|
53
|
+
this.customNotifier(options);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this.builtInNotifier.show(options);
|
|
45
58
|
}
|
|
46
59
|
}
|
|
@@ -37,6 +37,13 @@ export class Renderer extends Module {
|
|
|
37
37
|
*/
|
|
38
38
|
public pendingRender: Promise<void> | null = null;
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Decoded URL hash fragment that could not be scrolled to at init time
|
|
42
|
+
* because the target block was not yet in the DOM.
|
|
43
|
+
* Set by Blok constructor; consumed (and cleared) by BlocksAPI.render().
|
|
44
|
+
*/
|
|
45
|
+
public pendingHashScroll: string | null = null;
|
|
46
|
+
|
|
40
47
|
/**
|
|
41
48
|
* Resolve function for the current pendingRender promise.
|
|
42
49
|
* Called when the render operation is done (in finally block).
|
|
@@ -338,36 +338,41 @@ export class Toolbox extends EventsDispatcher<ToolboxEventMap> {
|
|
|
338
338
|
this.toggleRestrictedToolsHidden(true);
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
-
this.popover?.show();
|
|
342
|
-
|
|
343
341
|
/**
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
* the nested
|
|
347
|
-
*
|
|
342
|
+
* Always anchor the popover to a rect derived from the current context,
|
|
343
|
+
* never from the trigger element (plus button). The trigger rect is fragile:
|
|
344
|
+
* it can be hidden, offscreen, misaligned with the caret in nested containers
|
|
345
|
+
* (table cells, toggles, callouts), or detached from the block when the plus
|
|
346
|
+
* button sits at the block's top edge while the caret is elsewhere.
|
|
347
|
+
*
|
|
348
|
+
* - Slash open ("/"): anchor at the caret rect so the menu appears next to
|
|
349
|
+
* what the user is typing, in any block type at any nesting depth.
|
|
350
|
+
* - Plus button open: anchor at the current block's bounding rect so the
|
|
351
|
+
* menu appears below the block regardless of trigger placement.
|
|
352
|
+
*
|
|
353
|
+
* Set the position BEFORE show() so the first paint is already correct —
|
|
354
|
+
* popover.show() reads `params.position` via calculatePosition() and uses
|
|
355
|
+
* it instead of the trigger rect when present.
|
|
348
356
|
*/
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
*/
|
|
364
|
-
const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
|
|
365
|
-
|
|
366
|
-
if (currentBlock) {
|
|
367
|
-
this.popover.updatePosition(currentBlock.holder.getBoundingClientRect());
|
|
357
|
+
if (this.popover instanceof PopoverDesktop) {
|
|
358
|
+
const blockRect = currentBlock?.holder.getBoundingClientRect();
|
|
359
|
+
const caretRect = withSlash ? SelectionUtils.rect : undefined;
|
|
360
|
+
const caretRectIsDegenerate = caretRect !== undefined
|
|
361
|
+
&& caretRect.width === 0
|
|
362
|
+
&& caretRect.height === 0
|
|
363
|
+
&& caretRect.x === 0
|
|
364
|
+
&& caretRect.y === 0;
|
|
365
|
+
// Fall back to the block rect when selection is lost or returns a
|
|
366
|
+
// degenerate {0,0,0,0} rect — never anchor the popover at the page origin.
|
|
367
|
+
const anchorRect = caretRect !== undefined && !caretRectIsDegenerate ? caretRect : blockRect;
|
|
368
|
+
|
|
369
|
+
if (anchorRect !== undefined) {
|
|
370
|
+
this.popover.updatePosition(anchorRect);
|
|
368
371
|
}
|
|
369
372
|
}
|
|
370
373
|
|
|
374
|
+
this.popover?.show();
|
|
375
|
+
|
|
371
376
|
this.openedWithSlash = withSlash;
|
|
372
377
|
this.opened = true;
|
|
373
378
|
this.emit(ToolboxEvent.Opened);
|
|
@@ -1,123 +1,48 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { twJoin } from '../tw';
|
|
2
2
|
|
|
3
|
-
import type { NotifierOptions, ConfirmNotifierOptions, PromptNotifierOptions } from './types';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* SVG icons for notification styles.
|
|
7
|
-
* Each icon is 16x16, stroke-based for consistency.
|
|
8
|
-
*/
|
|
9
|
-
const ICONS = {
|
|
10
|
-
success: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6.25"/><path d="M5.5 8.25l1.75 1.75 3.25-3.5"/></svg>`,
|
|
11
|
-
error: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6.25"/><path d="M8 5.25v3"/><circle cx="8" cy="10.75" r="0.5" fill="currentColor" stroke="none"/></svg>`,
|
|
12
|
-
default: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6.25"/><path d="M8 7.25v3.25"/><circle cx="8" cy="5.25" r="0.5" fill="currentColor" stroke="none"/></svg>`,
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const CLOSE_ICON = `<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M2 2l6 6M8 2l-6 6"/></svg>`;
|
|
3
|
+
import type { NotifierOptions, ConfirmNotifierOptions, PromptNotifierOptions, NotifierPosition } from './types';
|
|
4
|
+
import { DEFAULT_NOTIFIER_POSITION } from './types';
|
|
16
5
|
|
|
17
6
|
export const CSS = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The wrapper class is built dynamically per-position.
|
|
9
|
+
* See getPositionClasses().
|
|
10
|
+
*/
|
|
11
|
+
wrapper: 'fixed z-[9999]',
|
|
22
12
|
notification: twJoin(
|
|
23
|
-
'relative flex items-
|
|
24
|
-
'bg-
|
|
25
|
-
'text-
|
|
26
|
-
'
|
|
27
|
-
'
|
|
13
|
+
'relative flex items-center justify-center mt-2 py-[10px] px-6',
|
|
14
|
+
'bg-[#1c1c1e] text-[#f5f5f5]',
|
|
15
|
+
'text-[15px] font-normal leading-[1.4] tracking-[-0.015em] wrap-break-word overflow-hidden',
|
|
16
|
+
'rounded-[14px]',
|
|
17
|
+
'shadow-[0_8px_32px_rgba(0,0,0,0.4),0_1px_4px_rgba(0,0,0,0.25)]',
|
|
18
|
+
'border border-white/[0.08]'
|
|
28
19
|
),
|
|
29
|
-
icon: 'shrink-0 mt-px',
|
|
30
|
-
iconSuccess: 'text-[#34c992]',
|
|
31
|
-
iconError: 'text-[#fb5d5d]',
|
|
32
|
-
iconDefault: 'text-[#9ca3af]',
|
|
33
20
|
messageWrapper: 'flex-1 min-w-0',
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
'hover:opacity-100'
|
|
39
|
-
),
|
|
40
|
-
btnsWrapper: 'flex flex-row flex-nowrap mt-[5px]',
|
|
41
|
-
btn: 'border-none rounded-[3px] text-[13px] py-[5px] px-2.5 cursor-pointer outline-hidden last:ml-2.5',
|
|
42
|
-
okBtn: 'bg-[#34c992] shadow-[0_1px_1px_0_rgba(18,49,35,0.05)] text-white hover:bg-[#2db583]',
|
|
43
|
-
cancelBtn: 'bg-[#f2f5f7] shadow-[0_2px_1px_0_rgba(16,19,29,0)] text-[#656b7c] hover:bg-[#e9ecee]',
|
|
21
|
+
btnsWrapper: 'flex flex-row flex-nowrap mt-[8px] gap-2',
|
|
22
|
+
btn: 'border-none rounded-[7px] text-[13px] py-[5px] px-3 cursor-pointer outline-hidden font-medium',
|
|
23
|
+
okBtn: 'bg-white/15 text-[#f5f5f5] hover:bg-white/25',
|
|
24
|
+
cancelBtn: 'bg-white/8 text-[#a1a1aa] hover:bg-white/12',
|
|
44
25
|
input: twJoin(
|
|
45
|
-
'max-w-[
|
|
46
|
-
'text-[13px] text-[#
|
|
47
|
-
'placeholder:text-
|
|
48
|
-
),
|
|
49
|
-
successNotification: twJoin(
|
|
50
|
-
'bg-[#fafffe]!',
|
|
51
|
-
'before:bg-[#41ffb1]!'
|
|
52
|
-
),
|
|
53
|
-
errorNotification: twJoin(
|
|
54
|
-
'bg-[#fffbfb]!',
|
|
55
|
-
'before:bg-[#fb5d5d]!'
|
|
26
|
+
'max-w-[140px] py-[5px] px-3 bg-white/10 border border-white/10 rounded-[7px]',
|
|
27
|
+
'text-[13px] text-[#e4e4e7] outline-hidden',
|
|
28
|
+
'placeholder:text-white/30 focus:border-white/20'
|
|
56
29
|
),
|
|
57
|
-
progressBar: twJoin(
|
|
58
|
-
'absolute bottom-0 left-0 h-[2px] rounded-b-[6px]',
|
|
59
|
-
'animate-notify-progress'
|
|
60
|
-
),
|
|
61
|
-
progressDefault: 'bg-[#d1d5db]',
|
|
62
|
-
progressSuccess: 'bg-[#41ffb1]',
|
|
63
|
-
progressError: 'bg-[#fb5d5d]',
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Creates an icon element for the notification.
|
|
68
|
-
*/
|
|
69
|
-
const createIcon = (style?: string): HTMLElement => {
|
|
70
|
-
const iconWrapper = document.createElement('span');
|
|
71
|
-
const resolvedStyle = style === 'success' || style === 'error' ? style : 'default';
|
|
72
|
-
|
|
73
|
-
iconWrapper.innerHTML = ICONS[resolvedStyle];
|
|
74
|
-
iconWrapper.setAttribute('data-blok-testid', 'notification-icon');
|
|
75
|
-
iconWrapper.setAttribute('data-blok-style', resolvedStyle);
|
|
76
|
-
|
|
77
|
-
const iconColorMap: Record<string, string> = {
|
|
78
|
-
success: CSS.iconSuccess,
|
|
79
|
-
error: CSS.iconError,
|
|
80
|
-
default: CSS.iconDefault,
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const colorClass = iconColorMap[resolvedStyle] ?? CSS.iconDefault;
|
|
84
|
-
|
|
85
|
-
iconWrapper.className = twJoin(CSS.icon, colorClass);
|
|
86
|
-
|
|
87
|
-
return iconWrapper;
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Creates a close (cross) button with an SVG icon.
|
|
92
|
-
*/
|
|
93
|
-
const createCloseButton = (): HTMLElement => {
|
|
94
|
-
const cross = document.createElement('div');
|
|
95
|
-
|
|
96
|
-
cross.className = CSS.crossBtn;
|
|
97
|
-
cross.setAttribute('data-blok-testid', 'notification-cross');
|
|
98
|
-
cross.innerHTML = CLOSE_ICON;
|
|
99
|
-
|
|
100
|
-
return cross;
|
|
101
30
|
};
|
|
102
31
|
|
|
103
32
|
/**
|
|
104
|
-
*
|
|
33
|
+
* Maps NotifierPosition to Tailwind positioning classes.
|
|
105
34
|
*/
|
|
106
|
-
export const
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
35
|
+
export const getPositionClasses = (position: NotifierPosition = DEFAULT_NOTIFIER_POSITION): string => {
|
|
36
|
+
const map: Record<NotifierPosition, string> = {
|
|
37
|
+
'bottom-left': 'bottom-5 left-5',
|
|
38
|
+
'bottom-right': 'bottom-5 right-5',
|
|
39
|
+
'bottom-center': 'bottom-5 left-1/2 -translate-x-1/2',
|
|
40
|
+
'top-left': 'top-5 left-5',
|
|
41
|
+
'top-right': 'top-5 right-5',
|
|
42
|
+
'top-center': 'top-5 left-1/2 -translate-x-1/2',
|
|
112
43
|
};
|
|
113
44
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
bar.className = twJoin(CSS.progressBar, colorClass);
|
|
117
|
-
bar.setAttribute('data-blok-testid', 'notification-progress');
|
|
118
|
-
bar.style.animationDuration = `${time ?? 8000}ms`;
|
|
119
|
-
|
|
120
|
-
return bar;
|
|
45
|
+
return map[position] ?? map['bottom-left'];
|
|
121
46
|
};
|
|
122
47
|
|
|
123
48
|
/**
|
|
@@ -128,19 +53,7 @@ export const alert = (options: NotifierOptions): HTMLElement => {
|
|
|
128
53
|
const notify = document.createElement('DIV');
|
|
129
54
|
const style = options.style;
|
|
130
55
|
|
|
131
|
-
|
|
132
|
-
if (style === 'success') {
|
|
133
|
-
return CSS.successNotification;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (style === 'error') {
|
|
137
|
-
return CSS.errorNotification;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return '';
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
notify.className = twMerge(CSS.notification, getStyleClasses());
|
|
56
|
+
notify.className = CSS.notification;
|
|
144
57
|
|
|
145
58
|
if (style) {
|
|
146
59
|
notify.setAttribute('data-blok-testid', `notification-${style}`);
|
|
@@ -148,12 +61,7 @@ export const alert = (options: NotifierOptions): HTMLElement => {
|
|
|
148
61
|
notify.setAttribute('data-blok-testid', 'notification');
|
|
149
62
|
}
|
|
150
63
|
|
|
151
|
-
//
|
|
152
|
-
const icon = createIcon(style);
|
|
153
|
-
|
|
154
|
-
notify.appendChild(icon);
|
|
155
|
-
|
|
156
|
-
// Message wrapper (flex child that holds message + buttons)
|
|
64
|
+
// Message wrapper
|
|
157
65
|
const messageWrapper = document.createElement('div');
|
|
158
66
|
|
|
159
67
|
messageWrapper.className = CSS.messageWrapper;
|
|
@@ -161,12 +69,6 @@ export const alert = (options: NotifierOptions): HTMLElement => {
|
|
|
161
69
|
messageWrapper.innerHTML = options.message;
|
|
162
70
|
notify.appendChild(messageWrapper);
|
|
163
71
|
|
|
164
|
-
// Close button
|
|
165
|
-
const cross = createCloseButton();
|
|
166
|
-
|
|
167
|
-
cross.addEventListener('click', () => notify.remove());
|
|
168
|
-
notify.appendChild(cross);
|
|
169
|
-
|
|
170
72
|
return notify;
|
|
171
73
|
};
|
|
172
74
|
|
|
@@ -180,7 +82,6 @@ export const confirm = (options: ConfirmNotifierOptions): HTMLElement => {
|
|
|
180
82
|
const btnsWrapper = document.createElement('div');
|
|
181
83
|
const okBtn = document.createElement('button');
|
|
182
84
|
const cancelBtn = document.createElement('button');
|
|
183
|
-
const crossBtn = notify.querySelector('[data-blok-testid="notification-cross"]');
|
|
184
85
|
const cancelHandler = options.cancelHandler;
|
|
185
86
|
const okHandler = options.okHandler;
|
|
186
87
|
|
|
@@ -200,10 +101,6 @@ export const confirm = (options: ConfirmNotifierOptions): HTMLElement => {
|
|
|
200
101
|
cancelBtn.addEventListener('click', cancelHandler);
|
|
201
102
|
}
|
|
202
103
|
|
|
203
|
-
if (cancelHandler && typeof cancelHandler === 'function' && crossBtn) {
|
|
204
|
-
crossBtn.addEventListener('click', cancelHandler);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
104
|
if (okHandler && typeof okHandler === 'function') {
|
|
208
105
|
okBtn.addEventListener('click', okHandler);
|
|
209
106
|
}
|
|
@@ -214,7 +111,6 @@ export const confirm = (options: ConfirmNotifierOptions): HTMLElement => {
|
|
|
214
111
|
btnsWrapper.appendChild(okBtn);
|
|
215
112
|
btnsWrapper.appendChild(cancelBtn);
|
|
216
113
|
|
|
217
|
-
// Append buttons to the message wrapper so they flow under the message text
|
|
218
114
|
if (messageWrapper) {
|
|
219
115
|
messageWrapper.appendChild(btnsWrapper);
|
|
220
116
|
} else {
|
|
@@ -234,7 +130,6 @@ export const prompt = (options: PromptNotifierOptions): HTMLElement => {
|
|
|
234
130
|
const btnsWrapper = document.createElement('div');
|
|
235
131
|
const okBtn = document.createElement('button');
|
|
236
132
|
const input = document.createElement('input');
|
|
237
|
-
const crossBtn = notify.querySelector('[data-blok-testid="notification-cross"]');
|
|
238
133
|
const cancelHandler = options.cancelHandler;
|
|
239
134
|
const okHandler = options.okHandler;
|
|
240
135
|
|
|
@@ -258,8 +153,12 @@ export const prompt = (options: PromptNotifierOptions): HTMLElement => {
|
|
|
258
153
|
input.type = options.inputType;
|
|
259
154
|
}
|
|
260
155
|
|
|
261
|
-
if (cancelHandler && typeof cancelHandler === 'function'
|
|
262
|
-
crossBtn.
|
|
156
|
+
if (cancelHandler && typeof cancelHandler === 'function') {
|
|
157
|
+
const crossBtn = notify.querySelector('[data-blok-testid="notification-cross"]');
|
|
158
|
+
|
|
159
|
+
if (crossBtn) {
|
|
160
|
+
crossBtn.addEventListener('click', cancelHandler);
|
|
161
|
+
}
|
|
263
162
|
}
|
|
264
163
|
|
|
265
164
|
if (okHandler && typeof okHandler === 'function') {
|
|
@@ -273,7 +172,6 @@ export const prompt = (options: PromptNotifierOptions): HTMLElement => {
|
|
|
273
172
|
btnsWrapper.appendChild(input);
|
|
274
173
|
btnsWrapper.appendChild(okBtn);
|
|
275
174
|
|
|
276
|
-
// Append to message wrapper for proper flex layout
|
|
277
175
|
if (messageWrapper) {
|
|
278
176
|
messageWrapper.appendChild(btnsWrapper);
|
|
279
177
|
} else {
|
|
@@ -283,11 +181,13 @@ export const prompt = (options: PromptNotifierOptions): HTMLElement => {
|
|
|
283
181
|
return notify;
|
|
284
182
|
};
|
|
285
183
|
|
|
286
|
-
export const getWrapper = (): HTMLElement => {
|
|
184
|
+
export const getWrapper = (position: NotifierPosition = DEFAULT_NOTIFIER_POSITION): HTMLElement => {
|
|
287
185
|
const wrapper = document.createElement('DIV');
|
|
186
|
+
const positionClasses = getPositionClasses(position);
|
|
288
187
|
|
|
289
|
-
wrapper.className = CSS.wrapper;
|
|
188
|
+
wrapper.className = twJoin(CSS.wrapper, positionClasses);
|
|
290
189
|
wrapper.setAttribute('data-blok-testid', 'notifier-container');
|
|
190
|
+
wrapper.setAttribute('data-blok-position', position);
|
|
291
191
|
|
|
292
192
|
return wrapper;
|
|
293
193
|
};
|
|
@@ -1,13 +1,29 @@
|
|
|
1
|
-
import { alert, confirm,
|
|
2
|
-
import type { NotifierOptions, ConfirmNotifierOptions, PromptNotifierOptions } from './types';
|
|
1
|
+
import { alert, confirm, getWrapper, prompt } from './draw';
|
|
2
|
+
import type { NotifierOptions, ConfirmNotifierOptions, PromptNotifierOptions, NotifierPosition } from './types';
|
|
3
|
+
import { DEFAULT_NOTIFIER_POSITION } from './types';
|
|
3
4
|
|
|
4
5
|
const DEFAULT_TIME = 8000;
|
|
5
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Returns the slide-in animation class based on position.
|
|
9
|
+
* Top positions slide down, bottom positions slide up.
|
|
10
|
+
*/
|
|
11
|
+
const getSlideInClass = (position: NotifierPosition): string => {
|
|
12
|
+
return position.startsWith('top') ? 'animate-notify-slide-in-top' : 'animate-notify-slide-in';
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Returns the slide-out animation class based on position.
|
|
17
|
+
*/
|
|
18
|
+
const getSlideOutClass = (position: NotifierPosition): string => {
|
|
19
|
+
return position.startsWith('top') ? 'animate-notify-slide-out-top' : 'animate-notify-slide-out';
|
|
20
|
+
};
|
|
21
|
+
|
|
6
22
|
/**
|
|
7
23
|
* Applies the exit animation and removes the element after it finishes.
|
|
8
24
|
*/
|
|
9
|
-
const dismissWithAnimation = (element: HTMLElement): void => {
|
|
10
|
-
element.classList.add(
|
|
25
|
+
const dismissWithAnimation = (element: HTMLElement, position: NotifierPosition): void => {
|
|
26
|
+
element.classList.add(getSlideOutClass(position));
|
|
11
27
|
|
|
12
28
|
element.addEventListener('animationend', () => {
|
|
13
29
|
element.remove();
|
|
@@ -15,37 +31,72 @@ const dismissWithAnimation = (element: HTMLElement): void => {
|
|
|
15
31
|
};
|
|
16
32
|
|
|
17
33
|
/**
|
|
18
|
-
*
|
|
34
|
+
* Fades and scales the element out quickly (replacement case), then calls onDone.
|
|
35
|
+
*/
|
|
36
|
+
const swapOut = (element: HTMLElement, onDone: () => void): void => {
|
|
37
|
+
element.classList.add('animate-notify-swap-out');
|
|
38
|
+
|
|
39
|
+
element.addEventListener('animationend', () => {
|
|
40
|
+
element.remove();
|
|
41
|
+
onDone();
|
|
42
|
+
}, { once: true });
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Prepare wrapper for notifications.
|
|
47
|
+
* If position changes, removes the old wrapper and creates a fresh one.
|
|
48
|
+
* @param {NotifierPosition} position - desired position
|
|
19
49
|
* @returns {HTMLElement}
|
|
20
50
|
*/
|
|
21
|
-
const prepare_ = (): HTMLElement => {
|
|
51
|
+
const prepare_ = (position: NotifierPosition = DEFAULT_NOTIFIER_POSITION): HTMLElement => {
|
|
22
52
|
const existingWrapper = document.querySelector('[data-blok-testid="notifier-container"]') as HTMLElement;
|
|
23
53
|
|
|
24
54
|
if (existingWrapper) {
|
|
25
|
-
|
|
55
|
+
// If position has changed, recreate the wrapper at the new location
|
|
56
|
+
if (existingWrapper.getAttribute('data-blok-position') !== position) {
|
|
57
|
+
existingWrapper.remove();
|
|
58
|
+
} else {
|
|
59
|
+
return existingWrapper;
|
|
60
|
+
}
|
|
26
61
|
}
|
|
27
62
|
|
|
28
|
-
const wrapper = getWrapper();
|
|
63
|
+
const wrapper = getWrapper(position);
|
|
29
64
|
|
|
30
65
|
document.body.appendChild(wrapper);
|
|
31
66
|
|
|
32
67
|
return wrapper;
|
|
33
68
|
};
|
|
34
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Appends the notification to the wrapper and starts its auto-dismiss timer.
|
|
72
|
+
*/
|
|
73
|
+
const appendNotify = (wrapper: HTMLElement, notify: HTMLElement, position: NotifierPosition, time: number): void => {
|
|
74
|
+
wrapper.appendChild(notify);
|
|
75
|
+
notify.classList.add(getSlideInClass(position));
|
|
76
|
+
notify.setAttribute('data-blok-bounce-in', 'true');
|
|
77
|
+
|
|
78
|
+
window.setTimeout(() => {
|
|
79
|
+
// Guard: element may have already been replaced
|
|
80
|
+
if (notify.isConnected) {
|
|
81
|
+
dismissWithAnimation(notify, position);
|
|
82
|
+
}
|
|
83
|
+
}, time);
|
|
84
|
+
};
|
|
85
|
+
|
|
35
86
|
/**
|
|
36
87
|
* Show new notification
|
|
37
88
|
* @param {NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions} options - notification options
|
|
89
|
+
* @param {NotifierPosition} position - notification container position
|
|
38
90
|
*/
|
|
39
|
-
export const show = (options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions): void => {
|
|
91
|
+
export const show = (options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions, position: NotifierPosition = DEFAULT_NOTIFIER_POSITION): void => {
|
|
40
92
|
if (!options.message) {
|
|
41
93
|
return;
|
|
42
94
|
}
|
|
43
95
|
|
|
44
|
-
const wrapper = prepare_();
|
|
45
|
-
|
|
96
|
+
const wrapper = prepare_(position);
|
|
46
97
|
const time = options.time || DEFAULT_TIME;
|
|
47
98
|
|
|
48
|
-
const
|
|
99
|
+
const buildNotify = (): HTMLElement => {
|
|
49
100
|
const type = options.type;
|
|
50
101
|
|
|
51
102
|
if (type === 'confirm') {
|
|
@@ -56,36 +107,24 @@ export const show = (options: NotifierOptions | ConfirmNotifierOptions | PromptN
|
|
|
56
107
|
return prompt(options as PromptNotifierOptions);
|
|
57
108
|
}
|
|
58
109
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// Add progress bar for auto-dismissing alerts
|
|
63
|
-
const progressBar = createProgressBar(options.style, time);
|
|
110
|
+
return alert(options);
|
|
111
|
+
};
|
|
64
112
|
|
|
65
|
-
|
|
113
|
+
const existing = wrapper.querySelector<HTMLElement>('[data-blok-testid]');
|
|
66
114
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (crossBtn) {
|
|
71
|
-
// Replace the basic remove handler with animated dismissal
|
|
72
|
-
const newCross = crossBtn.cloneNode(true) as HTMLElement;
|
|
73
|
-
|
|
74
|
-
crossBtn.replaceWith(newCross);
|
|
75
|
-
newCross.addEventListener('click', () => dismissWithAnimation(alertElement));
|
|
76
|
-
}
|
|
115
|
+
if (existing) {
|
|
116
|
+
// Cancel any in-progress swap-out on the existing element so we don't double-fire
|
|
117
|
+
existing.classList.remove('animate-notify-swap-out');
|
|
77
118
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}, time);
|
|
119
|
+
swapOut(existing, () => {
|
|
120
|
+
const notify = buildNotify();
|
|
81
121
|
|
|
82
|
-
|
|
83
|
-
|
|
122
|
+
appendNotify(wrapper, notify, position, time);
|
|
123
|
+
});
|
|
124
|
+
} else {
|
|
125
|
+
const notify = buildNotify();
|
|
84
126
|
|
|
85
|
-
|
|
86
|
-
wrapper.appendChild(notify);
|
|
87
|
-
notify.className = `${notify.className} animate-notify-slide-in`;
|
|
88
|
-
notify.setAttribute('data-blok-bounce-in', 'true');
|
|
127
|
+
appendNotify(wrapper, notify, position, time);
|
|
89
128
|
}
|
|
90
129
|
};
|
|
91
130
|
|