@mieweb/ui 0.11.0-dev.30 → 0.11.0-dev.32
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/agent/README.md +7 -7
- package/agent/agents/mieweb-ui-design.agent.md +8 -3
- package/agent/agents/mieweb-ui-i18n.agent.md +91 -0
- package/agent/agents/mieweb-ui-styling.agent.md +1 -1
- package/agent/skills/mieweb-ui-catalog/SKILL.md +15 -10
- package/agent/skills/mieweb-ui-catalog/selection-guidance.md +14 -7
- package/agent/skills/mieweb-ui-i18n-checklist/SKILL.md +133 -0
- package/dist/CsvBlock-AV4VM7JT.cjs +18 -0
- package/dist/{CsvBlock-RGO7JXHJ.cjs.map → CsvBlock-AV4VM7JT.cjs.map} +1 -1
- package/dist/CsvBlock-XBNYCEMP.js +9 -0
- package/dist/{CsvBlock-CFXSDPBI.js.map → CsvBlock-XBNYCEMP.js.map} +1 -1
- package/dist/HtmlPreviewBlock-DQAVD6IO.cjs +18 -0
- package/dist/{HtmlPreviewBlock-VBYXCXVT.cjs.map → HtmlPreviewBlock-DQAVD6IO.cjs.map} +1 -1
- package/dist/HtmlPreviewBlock-QQHRNLIY.js +9 -0
- package/dist/{HtmlPreviewBlock-Z2GCK325.js.map → HtmlPreviewBlock-QQHRNLIY.js.map} +1 -1
- package/dist/MermaidBlock-LHGYKC23.cjs +18 -0
- package/dist/{MermaidBlock-I2R2BQOX.cjs.map → MermaidBlock-LHGYKC23.cjs.map} +1 -1
- package/dist/MermaidBlock-QPKMIP3B.js +9 -0
- package/dist/{MermaidBlock-XCAK7IA5.js.map → MermaidBlock-QPKMIP3B.js.map} +1 -1
- package/dist/SurveyBlock-6DPTWHKI.js +9 -0
- package/dist/{SurveyBlock-KI5JOWCL.js.map → SurveyBlock-6DPTWHKI.js.map} +1 -1
- package/dist/SurveyBlock-6IXNVHS5.cjs +18 -0
- package/dist/{SurveyBlock-UKSGISRT.cjs.map → SurveyBlock-6IXNVHS5.cjs.map} +1 -1
- package/dist/{chunk-7XKM6V2K.cjs → chunk-2OXNJJHJ.cjs} +8 -8
- package/dist/{chunk-7XKM6V2K.cjs.map → chunk-2OXNJJHJ.cjs.map} +1 -1
- package/dist/{chunk-AJPFQF3H.cjs → chunk-2R3ILG4Y.cjs} +11 -11
- package/dist/{chunk-AJPFQF3H.cjs.map → chunk-2R3ILG4Y.cjs.map} +1 -1
- package/dist/{chunk-XQHDQ64G.cjs → chunk-2Z2GFDRS.cjs} +4 -4
- package/dist/{chunk-XQHDQ64G.cjs.map → chunk-2Z2GFDRS.cjs.map} +1 -1
- package/dist/{chunk-GM32IDVL.cjs → chunk-32ZILZ2T.cjs} +6 -6
- package/dist/{chunk-GM32IDVL.cjs.map → chunk-32ZILZ2T.cjs.map} +1 -1
- package/dist/{chunk-VOEXGDL5.js → chunk-33Y3KQWL.js} +3 -3
- package/dist/{chunk-VOEXGDL5.js.map → chunk-33Y3KQWL.js.map} +1 -1
- package/dist/{chunk-GYXSF6BJ.cjs → chunk-3IKIRGHI.cjs} +6 -6
- package/dist/{chunk-GYXSF6BJ.cjs.map → chunk-3IKIRGHI.cjs.map} +1 -1
- package/dist/{chunk-5HKZR6UG.js → chunk-43L4KGLU.js} +4 -4
- package/dist/{chunk-5HKZR6UG.js.map → chunk-43L4KGLU.js.map} +1 -1
- package/dist/{chunk-6BNZLN4B.cjs → chunk-4I5V6SXP.cjs} +10 -10
- package/dist/{chunk-6BNZLN4B.cjs.map → chunk-4I5V6SXP.cjs.map} +1 -1
- package/dist/{chunk-NUFUV43P.cjs → chunk-4UDEMJE4.cjs} +2 -2
- package/dist/chunk-4UDEMJE4.cjs.map +1 -0
- package/dist/{chunk-L5Y52F2E.cjs → chunk-4VSK3EE5.cjs} +4 -4
- package/dist/{chunk-L5Y52F2E.cjs.map → chunk-4VSK3EE5.cjs.map} +1 -1
- package/dist/{chunk-Y7ZJZLJY.js → chunk-566FIEPE.js} +4 -4
- package/dist/{chunk-Y7ZJZLJY.js.map → chunk-566FIEPE.js.map} +1 -1
- package/dist/{chunk-UTIPENPW.cjs → chunk-67SD6VPF.cjs} +5 -5
- package/dist/{chunk-UTIPENPW.cjs.map → chunk-67SD6VPF.cjs.map} +1 -1
- package/dist/{chunk-6CGM5H4J.js → chunk-6LIC3DKE.js} +2 -2
- package/dist/chunk-6LIC3DKE.js.map +1 -0
- package/dist/{chunk-6N7NMOSV.js → chunk-76ECYE5G.js} +3 -3
- package/dist/{chunk-6N7NMOSV.js.map → chunk-76ECYE5G.js.map} +1 -1
- package/dist/{chunk-56VTM4OX.js → chunk-7LKTIZLR.js} +3 -3
- package/dist/{chunk-56VTM4OX.js.map → chunk-7LKTIZLR.js.map} +1 -1
- package/dist/{chunk-7C5W744U.cjs → chunk-ARRJRFPD.cjs} +8 -8
- package/dist/{chunk-7C5W744U.cjs.map → chunk-ARRJRFPD.cjs.map} +1 -1
- package/dist/{chunk-5KGYTNOA.cjs → chunk-BP4LXRC6.cjs} +9 -9
- package/dist/{chunk-5KGYTNOA.cjs.map → chunk-BP4LXRC6.cjs.map} +1 -1
- package/dist/{chunk-UNFDIBKJ.js → chunk-CLNTWFEB.js} +3 -3
- package/dist/{chunk-UNFDIBKJ.js.map → chunk-CLNTWFEB.js.map} +1 -1
- package/dist/{chunk-X5JOEZVR.js → chunk-CRSJRWN2.js} +4 -4
- package/dist/{chunk-X5JOEZVR.js.map → chunk-CRSJRWN2.js.map} +1 -1
- package/dist/{chunk-FIKO4WR6.js → chunk-CVMD2A3J.js} +3 -3
- package/dist/{chunk-FIKO4WR6.js.map → chunk-CVMD2A3J.js.map} +1 -1
- package/dist/{chunk-SMPLM6K3.js → chunk-DG3CXR24.js} +5 -5
- package/dist/{chunk-SMPLM6K3.js.map → chunk-DG3CXR24.js.map} +1 -1
- package/dist/{chunk-LRAAJRE7.cjs → chunk-DO7EED3B.cjs} +154 -154
- package/dist/{chunk-LRAAJRE7.cjs.map → chunk-DO7EED3B.cjs.map} +1 -1
- package/dist/{chunk-UJDWFDKE.js → chunk-DXKE4YZT.js} +3 -3
- package/dist/{chunk-UJDWFDKE.js.map → chunk-DXKE4YZT.js.map} +1 -1
- package/dist/{chunk-KQ6GLYFZ.cjs → chunk-ECKIFQSD.cjs} +6 -6
- package/dist/{chunk-KQ6GLYFZ.cjs.map → chunk-ECKIFQSD.cjs.map} +1 -1
- package/dist/{chunk-4P27Y52M.js → chunk-EPKPHWIL.js} +4 -4
- package/dist/{chunk-4P27Y52M.js.map → chunk-EPKPHWIL.js.map} +1 -1
- package/dist/{chunk-RIUQP2QS.cjs → chunk-FNSFMM4F.cjs} +5 -5
- package/dist/{chunk-RIUQP2QS.cjs.map → chunk-FNSFMM4F.cjs.map} +1 -1
- package/dist/{chunk-3Y3ZCDNF.cjs → chunk-FQUSSPXX.cjs} +19 -19
- package/dist/{chunk-3Y3ZCDNF.cjs.map → chunk-FQUSSPXX.cjs.map} +1 -1
- package/dist/{chunk-ANMX7YDL.cjs → chunk-FSARTLUE.cjs} +4 -4
- package/dist/{chunk-ANMX7YDL.cjs.map → chunk-FSARTLUE.cjs.map} +1 -1
- package/dist/{chunk-ERACGSDY.cjs → chunk-G42V64UW.cjs} +8 -8
- package/dist/{chunk-ERACGSDY.cjs.map → chunk-G42V64UW.cjs.map} +1 -1
- package/dist/{chunk-UUI7WXI5.js → chunk-GAI6SRJ3.js} +3 -3
- package/dist/{chunk-UUI7WXI5.js.map → chunk-GAI6SRJ3.js.map} +1 -1
- package/dist/{chunk-4I6BW3FB.js → chunk-GLRKXJCR.js} +3 -3
- package/dist/{chunk-4I6BW3FB.js.map → chunk-GLRKXJCR.js.map} +1 -1
- package/dist/{chunk-NPKPCYAT.cjs → chunk-GM376OD6.cjs} +17 -17
- package/dist/{chunk-NPKPCYAT.cjs.map → chunk-GM376OD6.cjs.map} +1 -1
- package/dist/{chunk-DXEPYK3I.cjs → chunk-HGJHWI7W.cjs} +5 -3
- package/dist/chunk-HGJHWI7W.cjs.map +1 -0
- package/dist/{chunk-6ZA574PU.cjs → chunk-IIV5GNSK.cjs} +5 -5
- package/dist/{chunk-6ZA574PU.cjs.map → chunk-IIV5GNSK.cjs.map} +1 -1
- package/dist/{chunk-XPVQI3MM.cjs → chunk-INMDLVUB.cjs} +17 -2
- package/dist/chunk-INMDLVUB.cjs.map +1 -0
- package/dist/{chunk-RZSSQ7AT.js → chunk-JATLYCS4.js} +3 -3
- package/dist/{chunk-RZSSQ7AT.js.map → chunk-JATLYCS4.js.map} +1 -1
- package/dist/{chunk-4NB4WOGU.cjs → chunk-JCO62XMU.cjs} +6 -6
- package/dist/{chunk-4NB4WOGU.cjs.map → chunk-JCO62XMU.cjs.map} +1 -1
- package/dist/{chunk-QR7B6UPR.js → chunk-JN2CL7MK.js} +3 -3
- package/dist/{chunk-QR7B6UPR.js.map → chunk-JN2CL7MK.js.map} +1 -1
- package/dist/{chunk-FBCDYTWM.js → chunk-JNSSA4YN.js} +3 -3
- package/dist/{chunk-FBCDYTWM.js.map → chunk-JNSSA4YN.js.map} +1 -1
- package/dist/{chunk-BIQIE3VW.js → chunk-JQAGNAY2.js} +5 -5
- package/dist/{chunk-BIQIE3VW.js.map → chunk-JQAGNAY2.js.map} +1 -1
- package/dist/{chunk-TOJ56HKQ.cjs → chunk-KD7YD6US.cjs} +8 -8
- package/dist/{chunk-TOJ56HKQ.cjs.map → chunk-KD7YD6US.cjs.map} +1 -1
- package/dist/{chunk-5LNLB2XT.js → chunk-KSQQBFDQ.js} +3 -3
- package/dist/{chunk-5LNLB2XT.js.map → chunk-KSQQBFDQ.js.map} +1 -1
- package/dist/{chunk-3NOVISM6.js → chunk-L52HKEUD.js} +3 -3
- package/dist/{chunk-3NOVISM6.js.map → chunk-L52HKEUD.js.map} +1 -1
- package/dist/{chunk-IXUIOR4K.cjs → chunk-M42FTWY2.cjs} +6 -6
- package/dist/{chunk-IXUIOR4K.cjs.map → chunk-M42FTWY2.cjs.map} +1 -1
- package/dist/{chunk-32ZCJOSR.cjs → chunk-N7AIZWQS.cjs} +4 -4
- package/dist/{chunk-32ZCJOSR.cjs.map → chunk-N7AIZWQS.cjs.map} +1 -1
- package/dist/{chunk-P7D7BYFE.js → chunk-NA3NRLX2.js} +4 -4
- package/dist/{chunk-P7D7BYFE.js.map → chunk-NA3NRLX2.js.map} +1 -1
- package/dist/{chunk-Y424YL55.js → chunk-OLA7OYAS.js} +3 -3
- package/dist/{chunk-Y424YL55.js.map → chunk-OLA7OYAS.js.map} +1 -1
- package/dist/{chunk-F6W62K4J.js → chunk-OWYWRBED.js} +3 -3
- package/dist/{chunk-F6W62K4J.js.map → chunk-OWYWRBED.js.map} +1 -1
- package/dist/{chunk-RSJGTWLM.js → chunk-OYLZ5PF2.js} +3 -3
- package/dist/{chunk-RSJGTWLM.js.map → chunk-OYLZ5PF2.js.map} +1 -1
- package/dist/{chunk-7XC6E4BT.cjs → chunk-PJN4HM2X.cjs} +37 -37
- package/dist/{chunk-7XC6E4BT.cjs.map → chunk-PJN4HM2X.cjs.map} +1 -1
- package/dist/{chunk-NIO3XVUV.js → chunk-PLBWZW4F.js} +4 -4
- package/dist/{chunk-NIO3XVUV.js.map → chunk-PLBWZW4F.js.map} +1 -1
- package/dist/{chunk-XI74P5F2.cjs → chunk-PW2E7YBD.cjs} +5 -5
- package/dist/{chunk-XI74P5F2.cjs.map → chunk-PW2E7YBD.cjs.map} +1 -1
- package/dist/{chunk-HDY7YQFX.js → chunk-Q5APDRMO.js} +3 -3
- package/dist/{chunk-HDY7YQFX.js.map → chunk-Q5APDRMO.js.map} +1 -1
- package/dist/{chunk-FGLIP6YR.js → chunk-QATEO4KC.js} +4 -4
- package/dist/{chunk-FGLIP6YR.js.map → chunk-QATEO4KC.js.map} +1 -1
- package/dist/{chunk-254QK722.cjs → chunk-QHCAWDMG.cjs} +18 -7
- package/dist/chunk-QHCAWDMG.cjs.map +1 -0
- package/dist/{chunk-7HFZL5V5.js → chunk-QNJEDBIN.js} +4 -4
- package/dist/{chunk-7HFZL5V5.js.map → chunk-QNJEDBIN.js.map} +1 -1
- package/dist/{chunk-AIJYZP7M.js → chunk-R3MJKY63.js} +6 -6
- package/dist/{chunk-AIJYZP7M.js.map → chunk-R3MJKY63.js.map} +1 -1
- package/dist/{chunk-N54FYWG6.js → chunk-R5P7NAJQ.js} +4 -4
- package/dist/{chunk-N54FYWG6.js.map → chunk-R5P7NAJQ.js.map} +1 -1
- package/dist/{chunk-BWSZ2BHJ.cjs → chunk-S6457ZNC.cjs} +5 -5
- package/dist/{chunk-BWSZ2BHJ.cjs.map → chunk-S6457ZNC.cjs.map} +1 -1
- package/dist/{chunk-Z2OOJGHL.cjs → chunk-SCYLVQWA.cjs} +53 -53
- package/dist/{chunk-Z2OOJGHL.cjs.map → chunk-SCYLVQWA.cjs.map} +1 -1
- package/dist/{chunk-7IRTD4JT.cjs → chunk-SGDNEIJM.cjs} +4 -4
- package/dist/{chunk-7IRTD4JT.cjs.map → chunk-SGDNEIJM.cjs.map} +1 -1
- package/dist/{chunk-4JXO5JTE.js → chunk-SNAMNKFH.js} +17 -2
- package/dist/chunk-SNAMNKFH.js.map +1 -0
- package/dist/{chunk-GW4RFJZ5.js → chunk-TUYWCUKH.js} +18 -7
- package/dist/chunk-TUYWCUKH.js.map +1 -0
- package/dist/{chunk-CLQW724U.cjs → chunk-TXB3UHIO.cjs} +9 -9
- package/dist/{chunk-CLQW724U.cjs.map → chunk-TXB3UHIO.cjs.map} +1 -1
- package/dist/{chunk-4RI3CQGE.js → chunk-ULEX7OOJ.js} +4 -4
- package/dist/{chunk-4RI3CQGE.js.map → chunk-ULEX7OOJ.js.map} +1 -1
- package/dist/{chunk-KDW6BD4O.cjs → chunk-UVVZD3AS.cjs} +4 -4
- package/dist/{chunk-KDW6BD4O.cjs.map → chunk-UVVZD3AS.cjs.map} +1 -1
- package/dist/{chunk-MA3Y6AYA.cjs → chunk-V2KSJLUL.cjs} +8 -8
- package/dist/{chunk-MA3Y6AYA.cjs.map → chunk-V2KSJLUL.cjs.map} +1 -1
- package/dist/{chunk-SW2E7XKY.cjs → chunk-VIVS44IG.cjs} +9 -9
- package/dist/{chunk-SW2E7XKY.cjs.map → chunk-VIVS44IG.cjs.map} +1 -1
- package/dist/{chunk-GVM6DTR5.js → chunk-VP3XNLUL.js} +5 -3
- package/dist/chunk-VP3XNLUL.js.map +1 -0
- package/dist/{chunk-IGDO62KR.cjs → chunk-VVKUYQER.cjs} +5 -5
- package/dist/{chunk-IGDO62KR.cjs.map → chunk-VVKUYQER.cjs.map} +1 -1
- package/dist/{chunk-BJ6ABRSQ.cjs → chunk-WG2ANSDG.cjs} +6 -6
- package/dist/{chunk-BJ6ABRSQ.cjs.map → chunk-WG2ANSDG.cjs.map} +1 -1
- package/dist/{chunk-WFBUBT54.js → chunk-WX2XB6FP.js} +3 -3
- package/dist/{chunk-WFBUBT54.js.map → chunk-WX2XB6FP.js.map} +1 -1
- package/dist/{chunk-7QW6TU4X.js → chunk-YCPWQWQQ.js} +3 -3
- package/dist/{chunk-7QW6TU4X.js.map → chunk-YCPWQWQQ.js.map} +1 -1
- package/dist/{chunk-DSQCYX7L.js → chunk-YSIFPHLX.js} +7 -7
- package/dist/{chunk-DSQCYX7L.js.map → chunk-YSIFPHLX.js.map} +1 -1
- package/dist/{chunk-2X54ZLT6.js → chunk-ZFJJMDV3.js} +4 -4
- package/dist/{chunk-2X54ZLT6.js.map → chunk-ZFJJMDV3.js.map} +1 -1
- package/dist/{chunk-PYI2IWNX.cjs → chunk-ZOSM6D7F.cjs} +4 -4
- package/dist/{chunk-PYI2IWNX.cjs.map → chunk-ZOSM6D7F.cjs.map} +1 -1
- package/dist/components/ActionPlan/index.cjs +6 -6
- package/dist/components/ActionPlan/index.js +4 -4
- package/dist/components/ActivityFeed/index.cjs +6 -6
- package/dist/components/ActivityFeed/index.js +4 -4
- package/dist/components/AlertDialog/index.cjs +7 -7
- package/dist/components/AlertDialog/index.js +3 -3
- package/dist/components/AssociationList/index.cjs +6 -6
- package/dist/components/AssociationList/index.js +4 -4
- package/dist/components/Button/index.cjs +4 -4
- package/dist/components/Button/index.d.cts +1 -1
- package/dist/components/Button/index.d.ts +1 -1
- package/dist/components/Button/index.js +2 -2
- package/dist/components/CalendarView/index.cjs +5 -5
- package/dist/components/CalendarView/index.js +3 -3
- package/dist/components/CustomizableDashboard/index.cjs +10 -10
- package/dist/components/CustomizableDashboard/index.js +3 -3
- package/dist/components/EmailEditor/index.cjs +14 -14
- package/dist/components/EmailEditor/index.js +5 -5
- package/dist/components/FieldHistory/index.cjs +6 -6
- package/dist/components/FieldHistory/index.js +4 -4
- package/dist/components/FloatingWindow/index.cjs +5 -5
- package/dist/components/FloatingWindow/index.js +3 -3
- package/dist/components/ListView/index.cjs +5 -5
- package/dist/components/ListView/index.js +3 -3
- package/dist/components/Markdown/index.cjs +17 -17
- package/dist/components/Markdown/index.js +8 -8
- package/dist/components/MediaEditor/index.cjs +12 -12
- package/dist/components/MediaEditor/index.d.cts +13 -0
- package/dist/components/MediaEditor/index.d.ts +13 -0
- package/dist/components/MediaEditor/index.js +7 -7
- package/dist/components/MediaFeed/index.cjs +6 -6
- package/dist/components/MediaFeed/index.js +5 -5
- package/dist/components/MediaPlayer/index.cjs +7 -7
- package/dist/components/MediaPlayer/index.js +4 -4
- package/dist/components/MegaMenu/index.cjs +6 -6
- package/dist/components/MegaMenu/index.js +3 -3
- package/dist/components/RadialExplorer/index.cjs +4 -4
- package/dist/components/RadialExplorer/index.js +3 -3
- package/dist/components/RecordHeader/index.cjs +5 -5
- package/dist/components/RecordHeader/index.d.cts +1 -1
- package/dist/components/RecordHeader/index.d.ts +1 -1
- package/dist/components/RecordHeader/index.js +3 -3
- package/dist/components/RichTextEditor/index.cjs +6 -6
- package/dist/components/RichTextEditor/index.js +3 -3
- package/dist/components/SectionSpyNav/index.cjs +4 -4
- package/dist/components/SectionSpyNav/index.js +3 -3
- package/dist/components/SuperChat/index.cjs +9 -9
- package/dist/components/SuperChat/index.js +5 -5
- package/dist/components/Textarea/index.cjs +7 -7
- package/dist/components/Textarea/index.js +4 -4
- package/dist/components/TranscriptView/index.cjs +2 -2
- package/dist/components/TranscriptView/index.d.cts +14 -1
- package/dist/components/TranscriptView/index.d.ts +14 -1
- package/dist/components/TranscriptView/index.js +1 -1
- package/dist/components/ViewSet/index.cjs +6 -6
- package/dist/components/ViewSet/index.js +5 -5
- package/dist/datavis.cjs +3 -3
- package/dist/datavis.js +2 -2
- package/dist/deck.cjs +15 -15
- package/dist/deck.js +2 -2
- package/dist/esheet.cjs +130 -130
- package/dist/esheet.js +8 -8
- package/dist/hooks/index.cjs +12 -12
- package/dist/hooks/index.d.cts +15 -2
- package/dist/hooks/index.d.ts +15 -2
- package/dist/hooks/index.js +3 -3
- package/dist/index.cjs +2056 -418
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +178 -87
- package/dist/index.d.ts +178 -87
- package/dist/index.js +1693 -55
- package/dist/index.js.map +1 -1
- package/dist/{model-Y7WRIGGA.cjs → model-NPW2JMHZ.cjs} +20 -20
- package/dist/{model-Y7WRIGGA.cjs.map → model-NPW2JMHZ.cjs.map} +1 -1
- package/dist/{model-WFFZRQMY.js → model-SG5H3TCJ.js} +6 -6
- package/dist/{model-WFFZRQMY.js.map → model-SG5H3TCJ.js.map} +1 -1
- package/dist/org-chart.cjs +4 -4
- package/dist/org-chart.js +2 -2
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/dist/templates.cjs +38 -38
- package/dist/templates.js +3 -3
- package/package.json +1 -1
- package/dist/CsvBlock-CFXSDPBI.js +0 -9
- package/dist/CsvBlock-RGO7JXHJ.cjs +0 -18
- package/dist/HtmlPreviewBlock-VBYXCXVT.cjs +0 -18
- package/dist/HtmlPreviewBlock-Z2GCK325.js +0 -9
- package/dist/MermaidBlock-I2R2BQOX.cjs +0 -18
- package/dist/MermaidBlock-XCAK7IA5.js +0 -9
- package/dist/SurveyBlock-KI5JOWCL.js +0 -9
- package/dist/SurveyBlock-UKSGISRT.cjs +0 -18
- package/dist/chunk-254QK722.cjs.map +0 -1
- package/dist/chunk-4JXO5JTE.js.map +0 -1
- package/dist/chunk-6CGM5H4J.js.map +0 -1
- package/dist/chunk-DXEPYK3I.cjs.map +0 -1
- package/dist/chunk-GVM6DTR5.js.map +0 -1
- package/dist/chunk-GW4RFJZ5.js.map +0 -1
- package/dist/chunk-NUFUV43P.cjs.map +0 -1
- package/dist/chunk-XPVQI3MM.cjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ export { askOzwell, askOzwellStream, decodeTo16kMono, endsWithDone, getDictation
|
|
|
4
4
|
import { loadWhatPrints, saveWhatPrints, clearWhatPrints } from './chunk-74ENCTIK.js';
|
|
5
5
|
export { clearVoiceprints, clearWhatPrints, getVoiceprints, loadWhatPrints, saveWhatPrints, setVoiceprints } from './chunk-74ENCTIK.js';
|
|
6
6
|
export { Rating, ReviewCard, defaultRatingLabels, defaultReviewCardLabels } from './chunk-CBBKWRLG.js';
|
|
7
|
-
export { RecordHeader, defaultRecordHeaderLabels } from './chunk-
|
|
7
|
+
export { RecordHeader, defaultRecordHeaderLabels } from './chunk-PLBWZW4F.js';
|
|
8
8
|
export { RecordLayout, defaultRecordLayoutLabels } from './chunk-EGPDT7SM.js';
|
|
9
9
|
export { TagEditor, defaultTagEditorLabels } from './chunk-DGHS5IVD.js';
|
|
10
10
|
export { UserPicker, defaultUserPickerLabels } from './chunk-SZSRGUVO.js';
|
|
@@ -21,22 +21,22 @@ export { bluehiveBrand } from './chunk-PJEL5ZZV.js';
|
|
|
21
21
|
import './chunk-GY5SP4ST.js';
|
|
22
22
|
export { CalendarHeatmap, defaultCalendarHeatmapLabels } from './chunk-EPCUPHEO.js';
|
|
23
23
|
export { CompletenessMeter, defaultCompletenessMeterLabels, getCompleteness } from './chunk-RLVYWUXG.js';
|
|
24
|
-
export { FieldHistory, defaultFieldHistoryLabels } from './chunk-
|
|
24
|
+
export { FieldHistory, defaultFieldHistoryLabels } from './chunk-76ECYE5G.js';
|
|
25
25
|
export { LogoUploader, defaultLogoUploaderLabels } from './chunk-WQHBMZSC.js';
|
|
26
26
|
export { PhiMask, defaultPhiMaskLabels } from './chunk-DHGCLPFZ.js';
|
|
27
27
|
export { PropertyList, defaultPropertyListLabels } from './chunk-7HUTR6RX.js';
|
|
28
28
|
export { InlineEdit, defaultInlineEditLabels } from './chunk-M3VPGJMV.js';
|
|
29
|
-
export { ViewSet } from './chunk-
|
|
29
|
+
export { ViewSet } from './chunk-ULEX7OOJ.js';
|
|
30
30
|
export { TranscriptView, formatTimestampMs } from './chunk-LAEIVOIY.js';
|
|
31
31
|
export { PlayButton, VideoCard } from './chunk-43K7OQ3E.js';
|
|
32
32
|
export { VisuallyHidden } from './chunk-H2CIKJQI.js';
|
|
33
33
|
export { MONTH_LETTERS, MONTH_NAMES, YearTimeline, resolveCurrent } from './chunk-MUYUFOGL.js';
|
|
34
|
-
export { ActionPlan, defaultActionPlanLabels } from './chunk-
|
|
35
|
-
export { ActivityFeed, defaultActivityFeedLabels } from './chunk-
|
|
34
|
+
export { ActionPlan, defaultActionPlanLabels } from './chunk-EPKPHWIL.js';
|
|
35
|
+
export { ActivityFeed, defaultActivityFeedLabels } from './chunk-CRSJRWN2.js';
|
|
36
36
|
import './chunk-YGS2TRMP.js';
|
|
37
|
-
export { AssociationList, defaultAssociationListLabels } from './chunk-
|
|
37
|
+
export { AssociationList, defaultAssociationListLabels } from './chunk-43L4KGLU.js';
|
|
38
38
|
import './chunk-FTEZNCRI.js';
|
|
39
|
-
import './chunk-
|
|
39
|
+
import './chunk-OLA7OYAS.js';
|
|
40
40
|
import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from './chunk-5ILCNY74.js';
|
|
41
41
|
export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from './chunk-5ILCNY74.js';
|
|
42
42
|
import { Text } from './chunk-3YSIZ2CK.js';
|
|
@@ -56,7 +56,7 @@ import { notifyComposerMigrationOnce, ChatComposer, DEFAULT_MAX_FILE_SIZE, DEFAU
|
|
|
56
56
|
export { AttachmentPicker, AttachmentPreviewItem, CameraButton, ChatComposer, ComposerModelSelector, DragDropZone, generateAttachmentId, getFileType, validateFile } from './chunk-DAAJ3B2T.js';
|
|
57
57
|
export { DateButton, DatePicker, RadioOption, SchedulePicker, TimeButton, TimePicker, dateButtonVariants, radioOptionVariants, timeButtonVariants } from './chunk-23AYDOCH.js';
|
|
58
58
|
export { ScrollArea, scrollAreaVariants } from './chunk-HS25RPDW.js';
|
|
59
|
-
export { SectionSpyNav } from './chunk-
|
|
59
|
+
export { SectionSpyNav } from './chunk-CVMD2A3J.js';
|
|
60
60
|
export { AnimatedNumber, SliderCalculator } from './chunk-DT3X3RBM.js';
|
|
61
61
|
export { PhoneInput, PhoneInputGroup } from './chunk-QDNHN7R2.js';
|
|
62
62
|
import { Progress } from './chunk-P4E3K3ND.js';
|
|
@@ -66,58 +66,59 @@ export { ReadingProgressBar } from './chunk-WKSUL2ZN.js';
|
|
|
66
66
|
export { DictationButton, defaultDictationLabels, useDictation } from './chunk-MZA2LDS4.js';
|
|
67
67
|
import { RecordButton } from './chunk-MQOYDQTF.js';
|
|
68
68
|
export { RecordButton, formatDuration, recordButtonVariants } from './chunk-MQOYDQTF.js';
|
|
69
|
-
export { FillerWordsModal, MediaEditor, SilenceSettingsModal, SpeedMarkerMenu, WordEditorModal } from './chunk-
|
|
69
|
+
export { FillerWordsModal, MediaEditor, SilenceSettingsModal, SpeedMarkerMenu, WordEditorModal } from './chunk-R3MJKY63.js';
|
|
70
|
+
import { Slider } from './chunk-V5VPECJI.js';
|
|
70
71
|
export { Slider, sliderRangeVariants, sliderThumbVariants, sliderTrackVariants } from './chunk-V5VPECJI.js';
|
|
71
|
-
export { MediaFeed } from './chunk-
|
|
72
|
+
export { MediaFeed } from './chunk-ZFJJMDV3.js';
|
|
72
73
|
import './chunk-RISZWWEQ.js';
|
|
73
|
-
export { MediaPlayer, inferMediaKind, mediaPlayerVariants } from './chunk-
|
|
74
|
-
import { normalizePath, MegaMenuBar } from './chunk-
|
|
75
|
-
export { MegaMenu, MegaMenuBar, normalizePath } from './chunk-
|
|
74
|
+
export { MediaPlayer, inferMediaKind, mediaPlayerVariants } from './chunk-R5P7NAJQ.js';
|
|
75
|
+
import { normalizePath, MegaMenuBar } from './chunk-GLRKXJCR.js';
|
|
76
|
+
export { MegaMenu, MegaMenuBar, normalizePath } from './chunk-GLRKXJCR.js';
|
|
76
77
|
export { OrbitRing } from './chunk-SUS3WFY3.js';
|
|
77
|
-
export { RadialExplorer } from './chunk-
|
|
78
|
+
export { RadialExplorer } from './chunk-33Y3KQWL.js';
|
|
78
79
|
export { Pagination, SimplePagination, paginationButtonVariants } from './chunk-PFKRHNYV.js';
|
|
79
80
|
export { FreshnessBadge, FreshnessDot, daysSince, freshnessLevel } from './chunk-HQ3XPCHG.js';
|
|
80
81
|
export { GanttView, defaultGanttLabels } from './chunk-Y4QNLW7W.js';
|
|
81
82
|
export { GlossaryTooltip } from './chunk-SRMTRD7F.js';
|
|
82
83
|
export { Kbd, KeyboardShortcutsOverlay } from './chunk-JMAZ2GKT.js';
|
|
83
|
-
export { ListView, itemVariants as listViewItemVariants } from './chunk-
|
|
84
|
-
export { CodeBlock, MarkdownRenderer, highlightCode, useMarkdown } from './chunk-
|
|
85
|
-
export { SurveyBlock } from './chunk-
|
|
86
|
-
export { CsvBlock } from './chunk-
|
|
87
|
-
export { HtmlPreviewBlock } from './chunk-
|
|
88
|
-
export { MermaidBlock } from './chunk-
|
|
89
|
-
export { FenceBlock } from './chunk-
|
|
84
|
+
export { ListView, itemVariants as listViewItemVariants } from './chunk-CLNTWFEB.js';
|
|
85
|
+
export { CodeBlock, MarkdownRenderer, highlightCode, useMarkdown } from './chunk-YSIFPHLX.js';
|
|
86
|
+
export { SurveyBlock } from './chunk-OYLZ5PF2.js';
|
|
87
|
+
export { CsvBlock } from './chunk-NA3NRLX2.js';
|
|
88
|
+
export { HtmlPreviewBlock } from './chunk-QATEO4KC.js';
|
|
89
|
+
export { MermaidBlock } from './chunk-YCPWQWQQ.js';
|
|
90
|
+
export { FenceBlock } from './chunk-Q5APDRMO.js';
|
|
90
91
|
export { CopyButton } from './chunk-5QZ73PZC.js';
|
|
91
92
|
import { CountryDropdownBase } from './chunk-OTIKWEFZ.js';
|
|
92
93
|
export { CountryCodeDropdown, formatE164, validatePhoneNumber } from './chunk-OTIKWEFZ.js';
|
|
93
|
-
export { CustomizableDashboard, DashboardCustomizePanel, consolidateColumns, mergeColumnOrder, moveAcrossColumns, reorderOnDrop, requiredColumns } from './chunk-
|
|
94
|
+
export { CustomizableDashboard, DashboardCustomizePanel, consolidateColumns, mergeColumnOrder, moveAcrossColumns, reorderOnDrop, requiredColumns } from './chunk-OWYWRBED.js';
|
|
94
95
|
export { Sheet, SheetBody, SheetClose, SheetDescription, SheetFooter, SheetHeader, SheetTitle, sheetContentVariants, sheetOverlayVariants } from './chunk-LMBXJZLG.js';
|
|
95
|
-
export { EMAIL_BLOCK_TYPES, EmailEditor, createDefaultDesignSettings, createEmailBlock, createEmailHtmlSanitizer, createEmptyEmailContentTree, defaultEmailEditorLabels, generateEmailBlockId, renderEmailMjml } from './chunk-
|
|
96
|
+
export { EMAIL_BLOCK_TYPES, EmailEditor, createDefaultDesignSettings, createEmailBlock, createEmailHtmlSanitizer, createEmptyEmailContentTree, defaultEmailEditorLabels, generateEmailBlockId, renderEmailMjml } from './chunk-JQAGNAY2.js';
|
|
96
97
|
import './chunk-XBAAHOCP.js';
|
|
97
98
|
import { Tabs, TabsList, TabsTrigger, TabsContent } from './chunk-ME7EVT6F.js';
|
|
98
99
|
export { Tabs, TabsContent, TabsList, TabsTrigger, tabsListVariants, tabsTriggerVariants } from './chunk-ME7EVT6F.js';
|
|
99
100
|
import { Switch, switchThumbVariants, switchTrackVariants } from './chunk-AQ564XO7.js';
|
|
100
101
|
export { Switch, switchThumbVariants, switchTrackVariants } from './chunk-AQ564XO7.js';
|
|
101
102
|
export { FilterSummaryBar } from './chunk-6SCQ7FKT.js';
|
|
102
|
-
export { FloatingWindow, MinimizedWindow } from './chunk-
|
|
103
|
+
export { FloatingWindow, MinimizedWindow } from './chunk-DXKE4YZT.js';
|
|
103
104
|
export { Breadcrumb, BreadcrumbSlash } from './chunk-SCXELRRZ.js';
|
|
104
105
|
import './chunk-OF7NTZ2I.js';
|
|
105
|
-
export { CalendarView, defaultCalendarLabels } from './chunk-
|
|
106
|
+
export { CalendarView, defaultCalendarLabels } from './chunk-JATLYCS4.js';
|
|
106
107
|
import './chunk-XXA4NZUC.js';
|
|
107
108
|
export { ClampedText } from './chunk-VU3ZMJBN.js';
|
|
108
109
|
export { CollabStatus, defaultCollabStatusLabels, useYjsCollabStatus } from './chunk-UY2EZYIC.js';
|
|
109
110
|
export { Collapsible, CollapsibleContent, CollapsibleTrigger } from './chunk-VSRO4PAI.js';
|
|
110
111
|
import { Alert, AlertTitle, AlertDescription } from './chunk-3JWAABYI.js';
|
|
111
112
|
export { Alert, AlertDescription, AlertTitle, alertVariants } from './chunk-3JWAABYI.js';
|
|
112
|
-
import { AlertDialog } from './chunk-
|
|
113
|
-
export { AlertDialog, ConfirmDialogProvider, defaultAlertDialogLabels, useConfirm } from './chunk-
|
|
113
|
+
import { AlertDialog } from './chunk-7LKTIZLR.js';
|
|
114
|
+
export { AlertDialog, ConfirmDialogProvider, defaultAlertDialogLabels, useConfirm } from './chunk-7LKTIZLR.js';
|
|
114
115
|
export { AudioPlayer, ProgressBar, audioPlayerVariants, formatTime as formatAudioTime, playButtonVariants } from './chunk-C4GEPUE7.js';
|
|
115
116
|
export { AudioRecorder, audioRecorderVariants, controlButtonVariants, formatTime, waveformContainerVariants } from './chunk-2DW4PUJD.js';
|
|
116
117
|
export { Autocomplete } from './chunk-UBOVDAD7.js';
|
|
117
118
|
export { BoardView, cardVariants as boardViewCardVariants, defaultBoardLabels } from './chunk-F7SZSOB3.js';
|
|
118
|
-
export { BenchmarkTableSection, ComparisonSection, CtaSection, FaqSection, FeatureGridSection, HeroSection, LandingPage, LeadFormSection, LinkGroupsSection, LogoCloudSection, MetricListSection, PdfEmbedSection, PricingSection, ProcessStepsSection, RankedListSection, ReportByline, ReportLegend, ReportMethodology, ResourceCardsSection, SplitContentSection, StatsSection, TestimonialSection, TileCartogramSection, VideoSection, defaultLeadFormFields, landingPresets, quartileBuckets, usStateTiles, validateLandingPage } from './chunk-
|
|
119
|
+
export { BenchmarkTableSection, ComparisonSection, CtaSection, FaqSection, FeatureGridSection, HeroSection, LandingPage, LeadFormSection, LinkGroupsSection, LogoCloudSection, MetricListSection, PdfEmbedSection, PricingSection, ProcessStepsSection, RankedListSection, ReportByline, ReportLegend, ReportMethodology, ResourceCardsSection, SplitContentSection, StatsSection, TestimonialSection, TileCartogramSection, VideoSection, defaultLeadFormFields, landingPresets, quartileBuckets, usStateTiles, validateLandingPage } from './chunk-566FIEPE.js';
|
|
119
120
|
import './chunk-IQ4KQJAO.js';
|
|
120
|
-
export { MetricStatusBadge, SectionHeading, SectionShell, TemplateIcon, defaultMetricStatusLabels, templateIcons } from './chunk-
|
|
121
|
+
export { MetricStatusBadge, SectionHeading, SectionShell, TemplateIcon, defaultMetricStatusLabels, templateIcons } from './chunk-JNSSA4YN.js';
|
|
121
122
|
import { useCommandK, useIsMobile, useMediaQuery } from './chunk-YG7BR76Y.js';
|
|
122
123
|
export { KEYBOARD_INSET_VAR, KEYBOARD_OPEN_ATTRIBUTE, KEYBOARD_SOURCE_ATTRIBUTE, VISUAL_VIEWPORT_HEIGHT_VAR, VISUAL_VIEWPORT_OFFSET_TOP_VAR, localStorageOrderAdapter, mergeOrder, useCommandK, useIsDesktop, useIsLargeDesktop, useIsMobile, useIsMobileOrTablet, useIsSmallTablet, useIsTablet, useKeyboardInset, useKeyboardShortcut, useMediaQuery, useOrderPersistence } from './chunk-YG7BR76Y.js';
|
|
123
124
|
export { useYouTubeHoverPreview } from './chunk-POWS35OT.js';
|
|
@@ -126,13 +127,15 @@ import { useStickToBottom, useStreamEndedBelowFold } from './chunk-BM35CACB.js';
|
|
|
126
127
|
export { useStickToBottom, useStreamEndedBelowFold } from './chunk-BM35CACB.js';
|
|
127
128
|
import { useScrollSpy } from './chunk-WBGUYSWY.js';
|
|
128
129
|
export { useScrollSpy } from './chunk-WBGUYSWY.js';
|
|
129
|
-
export { DEFAULT_FILLER_WORDS, DEFAULT_MIN_SILENCE_MS, DEFAULT_NL_SILENCE_MS, buildPlaybackSegments, getSpeedAtIndex, initEditableWords, insertSilences, useTranscriptEdits } from './chunk-
|
|
130
|
-
|
|
131
|
-
export {
|
|
130
|
+
export { DEFAULT_FILLER_WORDS, DEFAULT_MIN_SILENCE_MS, DEFAULT_NL_SILENCE_MS, buildPlaybackSegments, getSpeedAtIndex, initEditableWords, insertSilences, useTranscriptEdits } from './chunk-GAI6SRJ3.js';
|
|
131
|
+
import { PLAYBACK_SPEEDS, isSilenceType } from './chunk-6LIC3DKE.js';
|
|
132
|
+
export { PLAYBACK_SPEEDS } from './chunk-6LIC3DKE.js';
|
|
133
|
+
import { useMediaTransport } from './chunk-TUYWCUKH.js';
|
|
134
|
+
export { useMediaTransport } from './chunk-TUYWCUKH.js';
|
|
132
135
|
export { useUrlTab } from './chunk-CVNPNZMX.js';
|
|
133
136
|
import './chunk-7XUN3OQT.js';
|
|
134
137
|
export { formatPhoneNumber, isPhoneNumberEmpty, isValidPhoneNumber, unformatPhoneNumber } from './chunk-ZVPJ2MH6.js';
|
|
135
|
-
export { miewebUIPreset, miewebUISafelist } from './chunk-
|
|
138
|
+
export { miewebUIPreset, miewebUISafelist } from './chunk-SNAMNKFH.js';
|
|
136
139
|
export { Accordion } from './chunk-BHKGVFTY.js';
|
|
137
140
|
import './chunk-H2Y7HZV5.js';
|
|
138
141
|
export { AvatarGroup, defaultAvatarGroupLabels } from './chunk-DVDT7TX7.js';
|
|
@@ -143,10 +146,10 @@ import { Spinner, SpinnerWithLabel } from './chunk-UA7E7PDS.js';
|
|
|
143
146
|
export { FullPageSpinner, Spinner, SpinnerWithLabel, spinnerVariants } from './chunk-UA7E7PDS.js';
|
|
144
147
|
import { evaluateDue, completedKeys, normalizeOrders } from './chunk-Y5KEFV5O.js';
|
|
145
148
|
export { buildChartOrderRows, buildEncounterOrderRows, dueForOrder, evaluateDue, evaluateProgram, isApplicable } from './chunk-Y5KEFV5O.js';
|
|
146
|
-
import { parseSig, labelToMedicationFields, MedicationEditor, useCodeLookupConfig } from './chunk-
|
|
147
|
-
export { ALLERGY_TYPE_LABELS, AllergyList, AllergyManager, Assessment, CodeLookupProvider, ConditionEditor, DateRangeFilter, DateRangePicker, MEDICATION_STATUS_LABELS, MedicationEditor, MedicationList, MedicationReconciliation, ORDER_TYPE_META, ORDER_TYPE_SEARCH_DOMAINS, calculateDateRange, doseFormToQuantityUnit, getDefaultPresets, getExtendedPresets, isConditionCodetype, labelToMedicationFields, lookupToMedicationFields, normalizeConditionCodingSystem, orderTypeForCodetype, parseMedicationLabel, parseSig, useCodeLookupConfig } from './chunk-
|
|
148
|
-
import { currentAssertion, CodingChips, toolbarKeyNav } from './chunk-
|
|
149
|
-
export { CHANGE_TYPE_LABELS, CONCERN_STATUS_LABELS, CodingChips, ProblemList, RowActionToolbar, RowIconButton, UncertaintyBadge, concernGroupKey, concernHistoryContent, currentAssertion, toolbarKeyNav } from './chunk-
|
|
149
|
+
import { parseSig, labelToMedicationFields, MedicationEditor, useCodeLookupConfig } from './chunk-DG3CXR24.js';
|
|
150
|
+
export { ALLERGY_TYPE_LABELS, AllergyList, AllergyManager, Assessment, CodeLookupProvider, ConditionEditor, DateRangeFilter, DateRangePicker, MEDICATION_STATUS_LABELS, MedicationEditor, MedicationList, MedicationReconciliation, ORDER_TYPE_META, ORDER_TYPE_SEARCH_DOMAINS, calculateDateRange, doseFormToQuantityUnit, getDefaultPresets, getExtendedPresets, isConditionCodetype, labelToMedicationFields, lookupToMedicationFields, normalizeConditionCodingSystem, orderTypeForCodetype, parseMedicationLabel, parseSig, useCodeLookupConfig } from './chunk-DG3CXR24.js';
|
|
151
|
+
import { currentAssertion, CodingChips, toolbarKeyNav } from './chunk-KSQQBFDQ.js';
|
|
152
|
+
export { CHANGE_TYPE_LABELS, CONCERN_STATUS_LABELS, CodingChips, ProblemList, RowActionToolbar, RowIconButton, UncertaintyBadge, concernGroupKey, concernHistoryContent, currentAssertion, toolbarKeyNav } from './chunk-KSQQBFDQ.js';
|
|
150
153
|
import { Tooltip } from './chunk-YFWDS6MX.js';
|
|
151
154
|
export { Tooltip } from './chunk-YFWDS6MX.js';
|
|
152
155
|
import { ButtonGroup } from './chunk-BBLEGF5L.js';
|
|
@@ -157,9 +160,9 @@ import { Label } from './chunk-I3WGZPI6.js';
|
|
|
157
160
|
export { Label, labelVariants } from './chunk-I3WGZPI6.js';
|
|
158
161
|
import { DateInput } from './chunk-I6Y2KLTZ.js';
|
|
159
162
|
export { DateInput } from './chunk-I6Y2KLTZ.js';
|
|
160
|
-
import { Textarea } from './chunk-
|
|
161
|
-
export { TextAreaRich as RichTextArea, TextAreaPlain, TextAreaRich, Textarea, htmlToPlain, plainToHtml, textareaVariants } from './chunk-
|
|
162
|
-
export { MacroLibrary, RichTextEditor, convertAngleBracketsToMustache, processDictation } from './chunk-
|
|
163
|
+
import { Textarea } from './chunk-L52HKEUD.js';
|
|
164
|
+
export { TextAreaRich as RichTextArea, TextAreaPlain, TextAreaRich, Textarea, htmlToPlain, plainToHtml, textareaVariants } from './chunk-L52HKEUD.js';
|
|
165
|
+
export { MacroLibrary, RichTextEditor, convertAngleBracketsToMustache, processDictation } from './chunk-JN2CL7MK.js';
|
|
163
166
|
import './chunk-5YOT4DVH.js';
|
|
164
167
|
export { Separator, separatorVariants } from './chunk-OQWZYKJM.js';
|
|
165
168
|
import { Select } from './chunk-VCI2Y7ST.js';
|
|
@@ -202,10 +205,10 @@ export { RTL_LOCALES, isRtl, isRtlLocale, useDirection } from './chunk-YVKBXNPK.
|
|
|
202
205
|
import { Badge } from './chunk-522WJIVI.js';
|
|
203
206
|
export { Badge, badgeVariants } from './chunk-522WJIVI.js';
|
|
204
207
|
import './chunk-N5JDL4VE.js';
|
|
205
|
-
import { Button } from './chunk-
|
|
206
|
-
export { Button } from './chunk-
|
|
207
|
-
import { buttonVariants } from './chunk-
|
|
208
|
-
export { buttonVariants } from './chunk-
|
|
208
|
+
import { Button } from './chunk-WX2XB6FP.js';
|
|
209
|
+
export { Button } from './chunk-WX2XB6FP.js';
|
|
210
|
+
import { buttonVariants } from './chunk-VP3XNLUL.js';
|
|
211
|
+
export { buttonVariants } from './chunk-VP3XNLUL.js';
|
|
209
212
|
export { isDarkMode, useIsDarkMode } from './chunk-RUGHNFQG.js';
|
|
210
213
|
import { AnimatedPresence, Animated } from './chunk-F4N67NAF.js';
|
|
211
214
|
export { Animated, AnimatedPresence, motionPresets, useMotionRuntime } from './chunk-F4N67NAF.js';
|
|
@@ -216,7 +219,8 @@ import * as React13 from 'react';
|
|
|
216
219
|
import React13__default, { createContext, useState, useEffect, useCallback, useMemo, useContext, useRef, useId } from 'react';
|
|
217
220
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
218
221
|
import { cva } from 'class-variance-authority';
|
|
219
|
-
import { AudioWaveform, FileUp, X, AlertCircle,
|
|
222
|
+
import { AudioWaveform, Play, Pause, FileUp, X, AlertCircle, VolumeX, Volume2, Minimize2, Maximize2, ZoomOut, ZoomIn, LocateFixed, Search, FolderUp, Upload, Edit2, Check, ChevronUp, ChevronDown as ChevronDown$1, Calendar as Calendar$1, Phone as Phone$1, Mail as Mail$1, Clock as Clock$1, MapPin, Shield, ChevronRight as ChevronRight$1, Building2, SlidersHorizontal, Trash2 as Trash2$1, Pencil as Pencil$1, Plus as Plus$1, ExternalLink as ExternalLink$1, Link, AlertTriangle as AlertTriangle$1, RefreshCw, ChevronLeft } from 'lucide-react';
|
|
223
|
+
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
220
224
|
import * as ReactDOM from 'react-dom';
|
|
221
225
|
import { createPortal } from 'react-dom';
|
|
222
226
|
|
|
@@ -5851,6 +5855,1640 @@ function VisitScribe({
|
|
|
5851
5855
|
}
|
|
5852
5856
|
);
|
|
5853
5857
|
}
|
|
5858
|
+
|
|
5859
|
+
// src/components/AI/HeyOzwell/TranscriptPlayer/model.ts
|
|
5860
|
+
var SPEAKER_COLORS2 = [
|
|
5861
|
+
"#dc2626",
|
|
5862
|
+
"#a3b818",
|
|
5863
|
+
"#16a34a",
|
|
5864
|
+
"#2563eb",
|
|
5865
|
+
"#9333ea",
|
|
5866
|
+
"#ea580c",
|
|
5867
|
+
"#0891b2",
|
|
5868
|
+
"#db2777"
|
|
5869
|
+
];
|
|
5870
|
+
var UNKNOWN_SPEAKER_ID = "";
|
|
5871
|
+
var UTTERANCE_GAP_SECONDS = 1.5;
|
|
5872
|
+
var MIN_VIEW_SECONDS = 10;
|
|
5873
|
+
var DEFAULT_VIEW_SECONDS = 300;
|
|
5874
|
+
var seconds = (ms) => ms / 1e3;
|
|
5875
|
+
var finiteSeconds = (ms) => Number.isFinite(ms) ? ms / 1e3 : 0;
|
|
5876
|
+
function toUtterances(transcript) {
|
|
5877
|
+
if (transcript.segments?.length)
|
|
5878
|
+
return transcript.segments.map((s, i) => ({
|
|
5879
|
+
id: `u${i}`,
|
|
5880
|
+
speakerId: s.speakerId ?? UNKNOWN_SPEAKER_ID,
|
|
5881
|
+
start: seconds(s.startMs),
|
|
5882
|
+
end: seconds(s.endMs),
|
|
5883
|
+
text: s.text.trim(),
|
|
5884
|
+
...s.overlapSpeakerIds?.length ? { overlapSpeakerIds: s.overlapSpeakerIds } : {}
|
|
5885
|
+
})).sort((a, b) => a.start - b.start);
|
|
5886
|
+
const out = [];
|
|
5887
|
+
const words = [...transcript.words].sort((a, b) => a.startMs - b.startMs);
|
|
5888
|
+
for (const word of words) {
|
|
5889
|
+
if (isSilenceType(word.wordType)) continue;
|
|
5890
|
+
const speakerId = word.speakerId ?? UNKNOWN_SPEAKER_ID;
|
|
5891
|
+
const last = out[out.length - 1];
|
|
5892
|
+
if (last && last.speakerId === speakerId && seconds(word.startMs) - last.end <= UTTERANCE_GAP_SECONDS) {
|
|
5893
|
+
last.end = Math.max(last.end, seconds(word.endMs));
|
|
5894
|
+
last.text = `${last.text} ${word.text}`.trim();
|
|
5895
|
+
} else {
|
|
5896
|
+
out.push({
|
|
5897
|
+
id: `u${out.length}`,
|
|
5898
|
+
speakerId,
|
|
5899
|
+
start: seconds(word.startMs),
|
|
5900
|
+
end: seconds(word.endMs),
|
|
5901
|
+
text: word.text.trim()
|
|
5902
|
+
});
|
|
5903
|
+
}
|
|
5904
|
+
}
|
|
5905
|
+
return out;
|
|
5906
|
+
}
|
|
5907
|
+
function toLaneSegments(transcript, utterances) {
|
|
5908
|
+
const source = transcript.speakerActivity?.length ? transcript.speakerActivity.map((a) => ({
|
|
5909
|
+
speakerId: a.speakerId || UNKNOWN_SPEAKER_ID,
|
|
5910
|
+
start: seconds(a.startMs),
|
|
5911
|
+
end: seconds(a.endMs)
|
|
5912
|
+
})) : utterances;
|
|
5913
|
+
return source.filter((s) => s.end > s.start).map((s, i) => ({
|
|
5914
|
+
id: `s${i}`,
|
|
5915
|
+
speakerId: s.speakerId,
|
|
5916
|
+
start: s.start,
|
|
5917
|
+
end: s.end
|
|
5918
|
+
})).sort((a, b) => a.start - b.start);
|
|
5919
|
+
}
|
|
5920
|
+
function toSpeakers(transcript, ids, speakerLabels, unknownName) {
|
|
5921
|
+
const order = [
|
|
5922
|
+
.../* @__PURE__ */ new Set([...(transcript.speakers ?? []).map((s) => s.id), ...ids])
|
|
5923
|
+
];
|
|
5924
|
+
return order.map((id, i) => ({
|
|
5925
|
+
id,
|
|
5926
|
+
name: speakerLabels?.[id] ?? transcript.speakers?.find((s) => s.id === id)?.name ?? (id === UNKNOWN_SPEAKER_ID ? unknownName : id),
|
|
5927
|
+
color: SPEAKER_COLORS2[i % SPEAKER_COLORS2.length]
|
|
5928
|
+
}));
|
|
5929
|
+
}
|
|
5930
|
+
function talkTime(segments) {
|
|
5931
|
+
const bySpeaker = /* @__PURE__ */ new Map();
|
|
5932
|
+
for (const s of segments) {
|
|
5933
|
+
const list = bySpeaker.get(s.speakerId) ?? [];
|
|
5934
|
+
list.push(s);
|
|
5935
|
+
bySpeaker.set(s.speakerId, list);
|
|
5936
|
+
}
|
|
5937
|
+
const totals = /* @__PURE__ */ new Map();
|
|
5938
|
+
for (const [id, list] of bySpeaker) {
|
|
5939
|
+
list.sort((a, b) => a.start - b.start);
|
|
5940
|
+
let total = 0;
|
|
5941
|
+
let end = -Infinity;
|
|
5942
|
+
for (const { start, end: stop } of list) {
|
|
5943
|
+
if (stop <= end) continue;
|
|
5944
|
+
total += stop - Math.max(start, end);
|
|
5945
|
+
end = stop;
|
|
5946
|
+
}
|
|
5947
|
+
totals.set(id, total);
|
|
5948
|
+
}
|
|
5949
|
+
return totals;
|
|
5950
|
+
}
|
|
5951
|
+
function hasOverlap(segments) {
|
|
5952
|
+
let latest = null;
|
|
5953
|
+
for (const s of segments) {
|
|
5954
|
+
if (latest && s.start < latest.end && s.speakerId !== latest.speakerId)
|
|
5955
|
+
return true;
|
|
5956
|
+
if (!latest || s.end > latest.end) latest = s;
|
|
5957
|
+
}
|
|
5958
|
+
return false;
|
|
5959
|
+
}
|
|
5960
|
+
function activeUtteranceAt(utterances, time) {
|
|
5961
|
+
let found = null;
|
|
5962
|
+
for (const u of utterances) {
|
|
5963
|
+
if (u.start > time) break;
|
|
5964
|
+
if (time < u.end) found = u;
|
|
5965
|
+
}
|
|
5966
|
+
return found;
|
|
5967
|
+
}
|
|
5968
|
+
function filterUtterances(utterances, hidden, query) {
|
|
5969
|
+
const needle = query.trim().toLowerCase();
|
|
5970
|
+
return utterances.filter(
|
|
5971
|
+
(u) => !hidden.has(u.speakerId) && (!needle || u.text.toLowerCase().includes(needle))
|
|
5972
|
+
);
|
|
5973
|
+
}
|
|
5974
|
+
function clampView(view, duration) {
|
|
5975
|
+
const span = Math.min(
|
|
5976
|
+
Math.max(view.span, Math.min(MIN_VIEW_SECONDS, duration)),
|
|
5977
|
+
duration
|
|
5978
|
+
);
|
|
5979
|
+
const start = Math.min(Math.max(0, view.start), Math.max(0, duration - span));
|
|
5980
|
+
return { start, span };
|
|
5981
|
+
}
|
|
5982
|
+
function initialView(duration) {
|
|
5983
|
+
return clampView({ start: 0, span: DEFAULT_VIEW_SECONDS }, duration);
|
|
5984
|
+
}
|
|
5985
|
+
function zoomView(view, factor, anchor, duration) {
|
|
5986
|
+
const span = view.span * factor;
|
|
5987
|
+
const ratio = view.span > 0 ? (anchor - view.start) / view.span : 0;
|
|
5988
|
+
return clampView({ start: anchor - ratio * span, span }, duration);
|
|
5989
|
+
}
|
|
5990
|
+
function followView(view, time, duration) {
|
|
5991
|
+
if (time >= view.start && time <= view.start + view.span * 0.95) return view;
|
|
5992
|
+
return clampView(
|
|
5993
|
+
{ start: time - view.span * 0.05, span: view.span },
|
|
5994
|
+
duration
|
|
5995
|
+
);
|
|
5996
|
+
}
|
|
5997
|
+
var TICK_STEPS = [1, 2, 5, 10, 15, 30, 60, 120, 300, 600, 900, 1800, 3600];
|
|
5998
|
+
function ticksFor(view, maxTicks = 8) {
|
|
5999
|
+
const step = TICK_STEPS.find((s) => view.span / s <= maxTicks) ?? TICK_STEPS[TICK_STEPS.length - 1];
|
|
6000
|
+
const ticks = [];
|
|
6001
|
+
for (let t = Math.ceil(view.start / step) * step; t <= view.start + view.span; t += step)
|
|
6002
|
+
ticks.push(t);
|
|
6003
|
+
return ticks;
|
|
6004
|
+
}
|
|
6005
|
+
function formatClock(totalSeconds) {
|
|
6006
|
+
const s = Math.max(0, Math.floor(totalSeconds));
|
|
6007
|
+
const h = Math.floor(s / 3600);
|
|
6008
|
+
const m = Math.floor(s % 3600 / 60);
|
|
6009
|
+
const ss = String(s % 60).padStart(2, "0");
|
|
6010
|
+
return h > 0 ? `${h}:${String(m).padStart(2, "0")}:${ss}` : `${m}:${ss}`;
|
|
6011
|
+
}
|
|
6012
|
+
function formatSpan(totalSeconds) {
|
|
6013
|
+
return totalSeconds < 60 ? `${Math.max(0, totalSeconds).toFixed(1)}s` : formatClock(totalSeconds);
|
|
6014
|
+
}
|
|
6015
|
+
|
|
6016
|
+
// src/components/AI/HeyOzwell/TranscriptPlayer/labels.ts
|
|
6017
|
+
var DEFAULT_TRANSCRIPT_PLAYER_LABELS = {
|
|
6018
|
+
recording: "Recording",
|
|
6019
|
+
play: "Play",
|
|
6020
|
+
pause: "Pause",
|
|
6021
|
+
mute: "Mute",
|
|
6022
|
+
unmute: "Unmute",
|
|
6023
|
+
volume: "Volume",
|
|
6024
|
+
playbackSpeed: "Playback speed",
|
|
6025
|
+
fullScreen: "Full screen",
|
|
6026
|
+
exitFullScreen: "Exit full screen",
|
|
6027
|
+
seek: "Seek",
|
|
6028
|
+
zoomIn: "Zoom in",
|
|
6029
|
+
zoomOut: "Zoom out",
|
|
6030
|
+
followPlayback: "Follow playback",
|
|
6031
|
+
earlier: "Earlier",
|
|
6032
|
+
later: "Later",
|
|
6033
|
+
visibleWindow: "Visible part of the recording",
|
|
6034
|
+
noRecording: "No recording available.",
|
|
6035
|
+
loadError: "The recording could not be loaded.",
|
|
6036
|
+
playError: "Playback failed.",
|
|
6037
|
+
noActivity: "No speaker activity.",
|
|
6038
|
+
allSpeakersHidden: "All speakers are hidden.",
|
|
6039
|
+
transcript: "Transcript",
|
|
6040
|
+
searchTranscript: "Search transcript",
|
|
6041
|
+
searchPlaceholder: "Search transcript\u2026",
|
|
6042
|
+
showSpeakers: "Show speakers",
|
|
6043
|
+
allSpeakers: "All speakers",
|
|
6044
|
+
someSpeakers: "Some speakers",
|
|
6045
|
+
noTranscript: "No transcript for this recording.",
|
|
6046
|
+
noMatches: "No lines match the search or speaker filter.",
|
|
6047
|
+
noWords: "(no words)",
|
|
6048
|
+
backToCurrent: "Back to current",
|
|
6049
|
+
speakers: "Speakers",
|
|
6050
|
+
noSpeakers: "No speakers detected.",
|
|
6051
|
+
overlapNote: "People talked over each other, so shares can add up to more than 100%.",
|
|
6052
|
+
hint: "Hover a coloured segment for details, then click it (or a transcript line) to play just that part. Drag the box in the overview to move through long recordings.",
|
|
6053
|
+
unknownSpeaker: "Unknown speaker",
|
|
6054
|
+
formatDuration: formatSpan,
|
|
6055
|
+
formatSpeed: (rate) => `${rate}x`,
|
|
6056
|
+
formatShare: (fraction) => `${Math.round(fraction * 100)}%`,
|
|
6057
|
+
segmentRange: (start, end, length) => `${start} \u2013 ${end} (${length})`,
|
|
6058
|
+
speakingTurns: (speaker) => `${speaker} speaking turns`,
|
|
6059
|
+
segment: (speaker, start, end, length) => `${speaker}, ${start} to ${end} (${length})`,
|
|
6060
|
+
playSegment: (segment) => `Play ${segment}`,
|
|
6061
|
+
playLine: (speaker, time) => `Play ${speaker} at ${time}`,
|
|
6062
|
+
overlapWith: (speakers) => `Overlaps ${speakers}`,
|
|
6063
|
+
seekValue: (current, total) => `${current} of ${total}`,
|
|
6064
|
+
windowValue: (start, end) => `${start} to ${end}`
|
|
6065
|
+
};
|
|
6066
|
+
var PEAKS_PER_SECOND = 50;
|
|
6067
|
+
var MAX_DECODE_BYTES = 50 * 1024 * 1024;
|
|
6068
|
+
function computePeaks(samples, sampleRate, perSecond = PEAKS_PER_SECOND) {
|
|
6069
|
+
const bucket = Math.max(1, Math.floor(sampleRate / perSecond));
|
|
6070
|
+
const data = new Float32Array(Math.ceil(samples.length / bucket));
|
|
6071
|
+
let max = 0;
|
|
6072
|
+
for (let i = 0; i < samples.length; i++) {
|
|
6073
|
+
const v = Math.abs(samples[i]);
|
|
6074
|
+
const b = Math.floor(i / bucket);
|
|
6075
|
+
if (v > data[b]) data[b] = v;
|
|
6076
|
+
if (v > max) max = v;
|
|
6077
|
+
}
|
|
6078
|
+
if (max > 0) for (let i = 0; i < data.length; i++) data[i] /= max;
|
|
6079
|
+
return { data, perSecond: sampleRate / bucket };
|
|
6080
|
+
}
|
|
6081
|
+
function useWaveformPeaks(src, provided) {
|
|
6082
|
+
const [decoded, setDecoded] = React13.useState(null);
|
|
6083
|
+
React13.useEffect(() => {
|
|
6084
|
+
setDecoded(null);
|
|
6085
|
+
if (provided || !src) return;
|
|
6086
|
+
const abort = new AbortController();
|
|
6087
|
+
fetch(src, { signal: abort.signal }).then((response) => response.blob()).then((blob) => {
|
|
6088
|
+
if (blob.size > MAX_DECODE_BYTES) return;
|
|
6089
|
+
return decodeTo16kMono(blob).then((samples) => {
|
|
6090
|
+
if (!abort.signal.aborted) setDecoded(computePeaks(samples, 16e3));
|
|
6091
|
+
});
|
|
6092
|
+
}).catch(() => {
|
|
6093
|
+
});
|
|
6094
|
+
return () => abort.abort();
|
|
6095
|
+
}, [src, provided]);
|
|
6096
|
+
return provided ?? decoded;
|
|
6097
|
+
}
|
|
6098
|
+
var ROW_GRID = "grid grid-cols-[6.5rem_minmax(0,1fr)] items-center gap-x-3";
|
|
6099
|
+
var HIDE_DELAY_MS = 150;
|
|
6100
|
+
var viewFraction = (time, view) => view.span > 0 ? Math.min(1, Math.max(0, (time - view.start) / view.span)) : 0;
|
|
6101
|
+
var timeAtPointer = (clientX, element, view) => {
|
|
6102
|
+
const rect = element.getBoundingClientRect();
|
|
6103
|
+
const ratio = rect.width > 0 ? (clientX - rect.left) / rect.width : 0;
|
|
6104
|
+
return view.start + Math.min(1, Math.max(0, ratio)) * view.span;
|
|
6105
|
+
};
|
|
6106
|
+
function describe(segment, name, labels) {
|
|
6107
|
+
return labels.segment(
|
|
6108
|
+
name,
|
|
6109
|
+
formatClock(segment.start),
|
|
6110
|
+
formatClock(segment.end),
|
|
6111
|
+
labels.formatDuration(segment.end - segment.start)
|
|
6112
|
+
);
|
|
6113
|
+
}
|
|
6114
|
+
var SpeakerLanes = React13.memo(function SpeakerLanes2({
|
|
6115
|
+
speakers,
|
|
6116
|
+
segments,
|
|
6117
|
+
view,
|
|
6118
|
+
playingId,
|
|
6119
|
+
onPlaySegment,
|
|
6120
|
+
onPause,
|
|
6121
|
+
onSeek,
|
|
6122
|
+
labels
|
|
6123
|
+
}) {
|
|
6124
|
+
const [hovered, setHovered] = React13.useState(null);
|
|
6125
|
+
const [focusedId, setFocusedId] = React13.useState(null);
|
|
6126
|
+
const hideTimer = React13.useRef(void 0);
|
|
6127
|
+
const show = (segment) => {
|
|
6128
|
+
window.clearTimeout(hideTimer.current);
|
|
6129
|
+
setHovered(segment);
|
|
6130
|
+
};
|
|
6131
|
+
const hide = () => {
|
|
6132
|
+
window.clearTimeout(hideTimer.current);
|
|
6133
|
+
hideTimer.current = window.setTimeout(
|
|
6134
|
+
() => setHovered(null),
|
|
6135
|
+
HIDE_DELAY_MS
|
|
6136
|
+
);
|
|
6137
|
+
};
|
|
6138
|
+
React13.useEffect(() => () => window.clearTimeout(hideTimer.current), []);
|
|
6139
|
+
React13.useEffect(() => {
|
|
6140
|
+
window.clearTimeout(hideTimer.current);
|
|
6141
|
+
setHovered(null);
|
|
6142
|
+
}, [segments]);
|
|
6143
|
+
const lanesRef = React13.useRef(null);
|
|
6144
|
+
const isOpen = hovered !== null;
|
|
6145
|
+
React13.useEffect(() => {
|
|
6146
|
+
if (!isOpen) return;
|
|
6147
|
+
const onKeyDown = (event) => {
|
|
6148
|
+
if (event.key !== "Escape" || event.defaultPrevented) return;
|
|
6149
|
+
if (lanesRef.current?.contains(document.activeElement))
|
|
6150
|
+
event.stopPropagation();
|
|
6151
|
+
window.clearTimeout(hideTimer.current);
|
|
6152
|
+
setHovered(null);
|
|
6153
|
+
};
|
|
6154
|
+
document.addEventListener("keydown", onKeyDown, true);
|
|
6155
|
+
return () => document.removeEventListener("keydown", onKeyDown, true);
|
|
6156
|
+
}, [isOpen]);
|
|
6157
|
+
const end = view.start + view.span;
|
|
6158
|
+
const visible = segments.filter(
|
|
6159
|
+
(s) => s.end > view.start && s.start < end || s.id === focusedId
|
|
6160
|
+
);
|
|
6161
|
+
const onSegmentKey = (event) => {
|
|
6162
|
+
const keys = {
|
|
6163
|
+
ArrowRight: (i, n) => Math.min(n - 1, i + 1),
|
|
6164
|
+
ArrowLeft: (i) => Math.max(0, i - 1),
|
|
6165
|
+
Home: () => 0,
|
|
6166
|
+
End: (_, n) => n - 1
|
|
6167
|
+
};
|
|
6168
|
+
const next = keys[event.key];
|
|
6169
|
+
const buttons = event.currentTarget.parentElement?.querySelectorAll(
|
|
6170
|
+
"[data-segment]"
|
|
6171
|
+
);
|
|
6172
|
+
if (!next || !buttons?.length) return;
|
|
6173
|
+
event.preventDefault();
|
|
6174
|
+
const index = Array.from(buttons).indexOf(event.currentTarget);
|
|
6175
|
+
buttons[next(index, buttons.length)]?.focus();
|
|
6176
|
+
};
|
|
6177
|
+
return /* @__PURE__ */ jsx("div", { ref: lanesRef, className: "space-y-1.5", children: speakers.map((speaker) => {
|
|
6178
|
+
const lane = visible.filter((s) => s.speakerId === speaker.id);
|
|
6179
|
+
return /* @__PURE__ */ jsxs("div", { className: ROW_GRID, children: [
|
|
6180
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground truncate text-xs", children: speaker.name }),
|
|
6181
|
+
/* @__PURE__ */ jsxs(
|
|
6182
|
+
"div",
|
|
6183
|
+
{
|
|
6184
|
+
role: "group",
|
|
6185
|
+
"aria-label": labels.speakingTurns(speaker.name),
|
|
6186
|
+
className: "bg-muted relative h-4 cursor-pointer rounded-sm",
|
|
6187
|
+
onClick: (e) => {
|
|
6188
|
+
if (e.target === e.currentTarget)
|
|
6189
|
+
onSeek(timeAtPointer(e.clientX, e.currentTarget, view));
|
|
6190
|
+
},
|
|
6191
|
+
children: [
|
|
6192
|
+
lane.map((segment, i) => {
|
|
6193
|
+
const left = viewFraction(segment.start, view);
|
|
6194
|
+
const width = viewFraction(segment.end, view) - left;
|
|
6195
|
+
const isPlaying = segment.id === playingId;
|
|
6196
|
+
return /* @__PURE__ */ jsx(
|
|
6197
|
+
"button",
|
|
6198
|
+
{
|
|
6199
|
+
type: "button",
|
|
6200
|
+
"data-segment": true,
|
|
6201
|
+
tabIndex: i === 0 ? 0 : -1,
|
|
6202
|
+
"aria-label": describe(segment, speaker.name, labels),
|
|
6203
|
+
"aria-pressed": isPlaying,
|
|
6204
|
+
onClick: () => isPlaying ? onPause() : onPlaySegment(segment),
|
|
6205
|
+
onKeyDown: onSegmentKey,
|
|
6206
|
+
onMouseEnter: () => show(segment),
|
|
6207
|
+
onMouseLeave: hide,
|
|
6208
|
+
onFocus: () => {
|
|
6209
|
+
setFocusedId(segment.id);
|
|
6210
|
+
show(segment);
|
|
6211
|
+
},
|
|
6212
|
+
onBlur: () => {
|
|
6213
|
+
setFocusedId(null);
|
|
6214
|
+
hide();
|
|
6215
|
+
},
|
|
6216
|
+
className: cn(
|
|
6217
|
+
// The outline keeps every turn's edges at 3:1+ against the lane, whatever the speaker colour.
|
|
6218
|
+
"focus-visible:ring-ring absolute inset-y-0 rounded-sm ring-inset focus-visible:ring-2 focus-visible:outline-none",
|
|
6219
|
+
isPlaying ? "ring-foreground ring-2" : "ring-foreground/70 ring-1"
|
|
6220
|
+
),
|
|
6221
|
+
style: {
|
|
6222
|
+
// rtl-ignore -- time axis inside the player's dir="ltr" timeline, matches clientX seek math
|
|
6223
|
+
left: `${left * 100}%`,
|
|
6224
|
+
width: `${width * 100}%`,
|
|
6225
|
+
minWidth: 2,
|
|
6226
|
+
backgroundColor: speaker.color
|
|
6227
|
+
}
|
|
6228
|
+
},
|
|
6229
|
+
segment.id
|
|
6230
|
+
);
|
|
6231
|
+
}),
|
|
6232
|
+
hovered?.speakerId === speaker.id && /* @__PURE__ */ jsxs(
|
|
6233
|
+
"div",
|
|
6234
|
+
{
|
|
6235
|
+
className: "absolute bottom-full z-20 mb-2 flex -translate-x-1/2 items-center gap-2 rounded-lg bg-neutral-900 px-2.5 py-1.5 text-xs whitespace-nowrap text-white shadow-md dark:bg-neutral-100 dark:text-neutral-900",
|
|
6236
|
+
style: {
|
|
6237
|
+
// Kept off the edges so the centred tooltip is never clipped.
|
|
6238
|
+
// rtl-ignore -- time axis inside the player's dir="ltr" timeline
|
|
6239
|
+
left: `${Math.min(85, Math.max(15, viewFraction((hovered.start + hovered.end) / 2, view) * 100))}%`
|
|
6240
|
+
},
|
|
6241
|
+
onMouseEnter: () => show(hovered),
|
|
6242
|
+
onMouseLeave: hide,
|
|
6243
|
+
children: [
|
|
6244
|
+
/* @__PURE__ */ jsx(
|
|
6245
|
+
Button,
|
|
6246
|
+
{
|
|
6247
|
+
type: "button",
|
|
6248
|
+
variant: "primary",
|
|
6249
|
+
size: "icon-sm",
|
|
6250
|
+
tabIndex: -1,
|
|
6251
|
+
"aria-label": labels.playSegment(
|
|
6252
|
+
describe(hovered, speaker.name, labels)
|
|
6253
|
+
),
|
|
6254
|
+
onClick: () => onPlaySegment(hovered),
|
|
6255
|
+
className: "h-6 w-6 rounded-full",
|
|
6256
|
+
children: /* @__PURE__ */ jsx(Play, { "aria-hidden": "true", className: "h-3 w-3 fill-current" })
|
|
6257
|
+
}
|
|
6258
|
+
),
|
|
6259
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
6260
|
+
/* @__PURE__ */ jsx("span", { className: "block font-semibold", children: speaker.name }),
|
|
6261
|
+
/* @__PURE__ */ jsx("span", { className: "tabular-nums opacity-75", children: labels.segmentRange(
|
|
6262
|
+
formatClock(hovered.start),
|
|
6263
|
+
formatClock(hovered.end),
|
|
6264
|
+
labels.formatDuration(hovered.end - hovered.start)
|
|
6265
|
+
) })
|
|
6266
|
+
] })
|
|
6267
|
+
]
|
|
6268
|
+
}
|
|
6269
|
+
)
|
|
6270
|
+
]
|
|
6271
|
+
}
|
|
6272
|
+
)
|
|
6273
|
+
] }, speaker.id);
|
|
6274
|
+
}) });
|
|
6275
|
+
});
|
|
6276
|
+
function SpeakerPanel({
|
|
6277
|
+
speakers,
|
|
6278
|
+
talkTime: talkTime2,
|
|
6279
|
+
duration,
|
|
6280
|
+
hidden,
|
|
6281
|
+
onToggle,
|
|
6282
|
+
overlapping,
|
|
6283
|
+
labels
|
|
6284
|
+
}) {
|
|
6285
|
+
const headingId = React13.useId();
|
|
6286
|
+
return /* @__PURE__ */ jsxs(
|
|
6287
|
+
"section",
|
|
6288
|
+
{
|
|
6289
|
+
"aria-labelledby": headingId,
|
|
6290
|
+
className: "border-border bg-card text-card-foreground rounded-xl border p-4",
|
|
6291
|
+
children: [
|
|
6292
|
+
/* @__PURE__ */ jsx("h3", { id: headingId, className: "mb-3 text-sm font-semibold", children: labels.speakers }),
|
|
6293
|
+
speakers.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: labels.noSpeakers }) : /* @__PURE__ */ jsx("ul", { className: "space-y-2.5", children: speakers.map((speaker) => {
|
|
6294
|
+
const seconds2 = talkTime2.get(speaker.id) ?? 0;
|
|
6295
|
+
const share = duration > 0 ? seconds2 / duration : 0;
|
|
6296
|
+
return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2 text-sm", children: [
|
|
6297
|
+
/* @__PURE__ */ jsx(
|
|
6298
|
+
"span",
|
|
6299
|
+
{
|
|
6300
|
+
"aria-hidden": "true",
|
|
6301
|
+
className: "h-2.5 w-2.5 shrink-0 rounded-full",
|
|
6302
|
+
style: { backgroundColor: speaker.color }
|
|
6303
|
+
}
|
|
6304
|
+
),
|
|
6305
|
+
/* @__PURE__ */ jsx(
|
|
6306
|
+
Checkbox,
|
|
6307
|
+
{
|
|
6308
|
+
size: "sm",
|
|
6309
|
+
label: speaker.name,
|
|
6310
|
+
checked: !hidden.has(speaker.id),
|
|
6311
|
+
onChange: () => onToggle(speaker.id),
|
|
6312
|
+
className: "shrink-0"
|
|
6313
|
+
}
|
|
6314
|
+
),
|
|
6315
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground ms-auto tabular-nums", children: labels.formatDuration(seconds2) }),
|
|
6316
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground min-w-10 text-end tabular-nums", children: labels.formatShare(share) })
|
|
6317
|
+
] }, speaker.id);
|
|
6318
|
+
}) }),
|
|
6319
|
+
overlapping && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-3 text-xs", children: labels.overlapNote })
|
|
6320
|
+
]
|
|
6321
|
+
}
|
|
6322
|
+
);
|
|
6323
|
+
}
|
|
6324
|
+
var HEIGHT = 28;
|
|
6325
|
+
function TimelineOverview({
|
|
6326
|
+
speakers,
|
|
6327
|
+
segments,
|
|
6328
|
+
duration,
|
|
6329
|
+
view,
|
|
6330
|
+
currentTime,
|
|
6331
|
+
onViewChange,
|
|
6332
|
+
labels
|
|
6333
|
+
}) {
|
|
6334
|
+
const canvasRef = React13.useRef(null);
|
|
6335
|
+
const trackRef = React13.useRef(null);
|
|
6336
|
+
const dragOffset = React13.useRef(null);
|
|
6337
|
+
const [width, setWidth] = React13.useState(0);
|
|
6338
|
+
const whole = { start: 0, span: duration };
|
|
6339
|
+
React13.useEffect(() => {
|
|
6340
|
+
const canvas = canvasRef.current;
|
|
6341
|
+
if (!canvas) return;
|
|
6342
|
+
const observer = new ResizeObserver(
|
|
6343
|
+
() => setWidth(canvas.clientWidth || 0)
|
|
6344
|
+
);
|
|
6345
|
+
observer.observe(canvas);
|
|
6346
|
+
return () => observer.disconnect();
|
|
6347
|
+
}, []);
|
|
6348
|
+
React13.useEffect(() => {
|
|
6349
|
+
const canvas = canvasRef.current;
|
|
6350
|
+
const ctx = canvas?.getContext("2d");
|
|
6351
|
+
if (!canvas || !ctx || width === 0) return;
|
|
6352
|
+
const dpr = window.devicePixelRatio || 1;
|
|
6353
|
+
canvas.width = width * dpr;
|
|
6354
|
+
canvas.height = HEIGHT * dpr;
|
|
6355
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
6356
|
+
ctx.clearRect(0, 0, width, HEIGHT);
|
|
6357
|
+
if (duration <= 0 || speakers.length === 0) return;
|
|
6358
|
+
const row = Math.min(6, HEIGHT / speakers.length);
|
|
6359
|
+
const top = (HEIGHT - row * speakers.length) / 2;
|
|
6360
|
+
speakers.forEach((speaker, i) => {
|
|
6361
|
+
ctx.fillStyle = speaker.color;
|
|
6362
|
+
for (const s of segments) {
|
|
6363
|
+
if (s.speakerId !== speaker.id) continue;
|
|
6364
|
+
const x = s.start / duration * width;
|
|
6365
|
+
const w = Math.max(1, (s.end - s.start) / duration * width);
|
|
6366
|
+
ctx.fillRect(x, top + i * row + 1, w, row - 1);
|
|
6367
|
+
}
|
|
6368
|
+
});
|
|
6369
|
+
}, [speakers, segments, duration, width]);
|
|
6370
|
+
const pan = (delta) => onViewChange(clampView({ ...view, start: view.start + delta }, duration));
|
|
6371
|
+
const onPointerDown = (event) => {
|
|
6372
|
+
if (!trackRef.current) return;
|
|
6373
|
+
const t = timeAtPointer(event.clientX, trackRef.current, whole);
|
|
6374
|
+
const insideWindow = t >= view.start && t <= view.start + view.span;
|
|
6375
|
+
dragOffset.current = insideWindow ? t - view.start : view.span / 2;
|
|
6376
|
+
onViewChange(
|
|
6377
|
+
clampView({ ...view, start: t - dragOffset.current }, duration)
|
|
6378
|
+
);
|
|
6379
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
6380
|
+
};
|
|
6381
|
+
const onPointerMove = (event) => {
|
|
6382
|
+
if (dragOffset.current === null || !trackRef.current) return;
|
|
6383
|
+
const t = timeAtPointer(event.clientX, trackRef.current, whole);
|
|
6384
|
+
onViewChange(
|
|
6385
|
+
clampView({ ...view, start: t - dragOffset.current }, duration)
|
|
6386
|
+
);
|
|
6387
|
+
};
|
|
6388
|
+
const endDrag = () => {
|
|
6389
|
+
dragOffset.current = null;
|
|
6390
|
+
};
|
|
6391
|
+
const onKeyDown = (event) => {
|
|
6392
|
+
const step = {
|
|
6393
|
+
ArrowLeft: -view.span / 10,
|
|
6394
|
+
ArrowRight: view.span / 10,
|
|
6395
|
+
PageUp: -view.span,
|
|
6396
|
+
PageDown: view.span,
|
|
6397
|
+
Home: -duration,
|
|
6398
|
+
End: duration
|
|
6399
|
+
};
|
|
6400
|
+
if (!(event.key in step)) return;
|
|
6401
|
+
event.preventDefault();
|
|
6402
|
+
pan(step[event.key]);
|
|
6403
|
+
};
|
|
6404
|
+
const left = viewFraction(view.start, whole);
|
|
6405
|
+
const right = viewFraction(view.start + view.span, whole);
|
|
6406
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
6407
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
6408
|
+
/* @__PURE__ */ jsx(
|
|
6409
|
+
Button,
|
|
6410
|
+
{
|
|
6411
|
+
type: "button",
|
|
6412
|
+
variant: "ghost",
|
|
6413
|
+
size: "icon-sm",
|
|
6414
|
+
"aria-label": labels.earlier,
|
|
6415
|
+
disabled: view.start <= 0,
|
|
6416
|
+
onClick: () => pan(-view.span),
|
|
6417
|
+
className: "shrink-0",
|
|
6418
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true", className: "h-4 w-4" })
|
|
6419
|
+
}
|
|
6420
|
+
),
|
|
6421
|
+
/* @__PURE__ */ jsxs(
|
|
6422
|
+
"div",
|
|
6423
|
+
{
|
|
6424
|
+
ref: trackRef,
|
|
6425
|
+
className: "bg-muted/60 border-border relative flex-1 cursor-pointer touch-none rounded border",
|
|
6426
|
+
onPointerDown,
|
|
6427
|
+
onPointerMove,
|
|
6428
|
+
onPointerUp: endDrag,
|
|
6429
|
+
onPointerCancel: endDrag,
|
|
6430
|
+
children: [
|
|
6431
|
+
/* @__PURE__ */ jsx(
|
|
6432
|
+
"canvas",
|
|
6433
|
+
{
|
|
6434
|
+
ref: canvasRef,
|
|
6435
|
+
"aria-hidden": "true",
|
|
6436
|
+
className: "block w-full",
|
|
6437
|
+
style: { height: HEIGHT }
|
|
6438
|
+
}
|
|
6439
|
+
),
|
|
6440
|
+
/* @__PURE__ */ jsx(
|
|
6441
|
+
"div",
|
|
6442
|
+
{
|
|
6443
|
+
role: "slider",
|
|
6444
|
+
tabIndex: 0,
|
|
6445
|
+
"aria-label": labels.visibleWindow,
|
|
6446
|
+
"aria-valuemin": 0,
|
|
6447
|
+
"aria-valuemax": Math.round(duration),
|
|
6448
|
+
"aria-valuenow": Math.round(view.start),
|
|
6449
|
+
"aria-valuetext": labels.windowValue(
|
|
6450
|
+
formatClock(view.start),
|
|
6451
|
+
formatClock(view.start + view.span)
|
|
6452
|
+
),
|
|
6453
|
+
onKeyDown,
|
|
6454
|
+
className: "border-primary-500 bg-primary-500/15 focus-visible:ring-ring absolute inset-y-0 cursor-grab rounded border focus-visible:ring-2 focus-visible:outline-none active:cursor-grabbing",
|
|
6455
|
+
style: {
|
|
6456
|
+
// rtl-ignore -- time axis inside the player's dir="ltr" timeline, matches clientX drag math
|
|
6457
|
+
left: `${left * 100}%`,
|
|
6458
|
+
width: `${Math.max(0.5, (right - left) * 100)}%`
|
|
6459
|
+
}
|
|
6460
|
+
}
|
|
6461
|
+
),
|
|
6462
|
+
/* @__PURE__ */ jsx(
|
|
6463
|
+
"span",
|
|
6464
|
+
{
|
|
6465
|
+
"aria-hidden": "true",
|
|
6466
|
+
className: "bg-foreground pointer-events-none absolute inset-y-0 w-px",
|
|
6467
|
+
style: {
|
|
6468
|
+
// rtl-ignore -- time axis inside the player's dir="ltr" timeline
|
|
6469
|
+
left: `${viewFraction(currentTime, whole) * 100}%`
|
|
6470
|
+
}
|
|
6471
|
+
}
|
|
6472
|
+
)
|
|
6473
|
+
]
|
|
6474
|
+
}
|
|
6475
|
+
),
|
|
6476
|
+
/* @__PURE__ */ jsx(
|
|
6477
|
+
Button,
|
|
6478
|
+
{
|
|
6479
|
+
type: "button",
|
|
6480
|
+
variant: "ghost",
|
|
6481
|
+
size: "icon-sm",
|
|
6482
|
+
"aria-label": labels.later,
|
|
6483
|
+
disabled: view.start + view.span >= duration,
|
|
6484
|
+
onClick: () => pan(view.span),
|
|
6485
|
+
className: "shrink-0",
|
|
6486
|
+
children: /* @__PURE__ */ jsx(ChevronRight$1, { "aria-hidden": "true", className: "h-4 w-4" })
|
|
6487
|
+
}
|
|
6488
|
+
)
|
|
6489
|
+
] }),
|
|
6490
|
+
/* @__PURE__ */ jsx(
|
|
6491
|
+
"div",
|
|
6492
|
+
{
|
|
6493
|
+
"aria-hidden": "true",
|
|
6494
|
+
className: "text-muted-foreground relative mx-9 mt-1 h-4 text-[11px] tabular-nums",
|
|
6495
|
+
children: ticksFor(whole).map((t) => /* @__PURE__ */ jsx(
|
|
6496
|
+
"span",
|
|
6497
|
+
{
|
|
6498
|
+
className: "absolute -translate-x-1/2",
|
|
6499
|
+
style: {
|
|
6500
|
+
// rtl-ignore -- time axis inside the player's dir="ltr" timeline
|
|
6501
|
+
left: `${viewFraction(t, whole) * 100}%`
|
|
6502
|
+
},
|
|
6503
|
+
children: formatClock(t)
|
|
6504
|
+
},
|
|
6505
|
+
t
|
|
6506
|
+
))
|
|
6507
|
+
}
|
|
6508
|
+
)
|
|
6509
|
+
] });
|
|
6510
|
+
}
|
|
6511
|
+
var VIRTUALIZE_AFTER = 150;
|
|
6512
|
+
var FOLLOW_SCROLL_MS = 400;
|
|
6513
|
+
var USER_SCROLL_KEYS = /* @__PURE__ */ new Set([
|
|
6514
|
+
"ArrowUp",
|
|
6515
|
+
"ArrowDown",
|
|
6516
|
+
"PageUp",
|
|
6517
|
+
"PageDown",
|
|
6518
|
+
"Home",
|
|
6519
|
+
"End"
|
|
6520
|
+
]);
|
|
6521
|
+
function highlight(text, query) {
|
|
6522
|
+
const needle = query.trim();
|
|
6523
|
+
if (!needle) return text;
|
|
6524
|
+
const escaped = needle.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6525
|
+
return text.split(new RegExp(`(${escaped})`, "gi")).map(
|
|
6526
|
+
(part, i) => i % 2 === 1 ? /* @__PURE__ */ jsx("mark", { className: "rounded-sm bg-yellow-200 dark:bg-yellow-700", children: part }, i) : part
|
|
6527
|
+
);
|
|
6528
|
+
}
|
|
6529
|
+
var Row = React13.memo(function Row2({
|
|
6530
|
+
utterance,
|
|
6531
|
+
speaker,
|
|
6532
|
+
overlap,
|
|
6533
|
+
active,
|
|
6534
|
+
playing,
|
|
6535
|
+
query,
|
|
6536
|
+
onPlay,
|
|
6537
|
+
onPause,
|
|
6538
|
+
labels,
|
|
6539
|
+
setSize,
|
|
6540
|
+
posInSet
|
|
6541
|
+
}) {
|
|
6542
|
+
const name = speaker?.name ?? labels.unknownSpeaker;
|
|
6543
|
+
const color = speaker?.color ?? "currentColor";
|
|
6544
|
+
const time = formatClock(utterance.start);
|
|
6545
|
+
return (
|
|
6546
|
+
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions -- whole-row click target; keyboard users use the row's play button
|
|
6547
|
+
/* @__PURE__ */ jsxs(
|
|
6548
|
+
"div",
|
|
6549
|
+
{
|
|
6550
|
+
role: "listitem",
|
|
6551
|
+
"data-id": utterance.id,
|
|
6552
|
+
"aria-current": active || void 0,
|
|
6553
|
+
"aria-setsize": setSize,
|
|
6554
|
+
"aria-posinset": posInSet,
|
|
6555
|
+
onClick: () => onPlay(utterance),
|
|
6556
|
+
className: cn(
|
|
6557
|
+
"flex cursor-pointer items-start gap-3 rounded-lg px-2 py-2 text-sm",
|
|
6558
|
+
active ? "bg-primary-50 dark:bg-primary-950/40" : "hover:bg-muted/60"
|
|
6559
|
+
),
|
|
6560
|
+
children: [
|
|
6561
|
+
/* @__PURE__ */ jsx(
|
|
6562
|
+
Button,
|
|
6563
|
+
{
|
|
6564
|
+
type: "button",
|
|
6565
|
+
variant: "ghost",
|
|
6566
|
+
size: "icon-sm",
|
|
6567
|
+
"aria-label": labels.playLine(name, time),
|
|
6568
|
+
"aria-pressed": playing,
|
|
6569
|
+
onClick: (e) => {
|
|
6570
|
+
e.stopPropagation();
|
|
6571
|
+
if (playing) onPause();
|
|
6572
|
+
else onPlay(utterance);
|
|
6573
|
+
},
|
|
6574
|
+
className: "border-border text-foreground h-6 w-6 shrink-0 rounded-full border",
|
|
6575
|
+
children: playing ? /* @__PURE__ */ jsx(Pause, { "aria-hidden": "true", className: "h-3 w-3 fill-current" }) : /* @__PURE__ */ jsx(Play, { "aria-hidden": "true", className: "ms-0.5 h-3 w-3 fill-current" })
|
|
6576
|
+
}
|
|
6577
|
+
),
|
|
6578
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground w-12 shrink-0 pt-0.5 text-xs tabular-nums", children: time }),
|
|
6579
|
+
/* @__PURE__ */ jsxs(
|
|
6580
|
+
"span",
|
|
6581
|
+
{
|
|
6582
|
+
className: "text-foreground flex w-24 shrink-0 items-center gap-1.5 rounded px-1.5 py-0.5 text-xs font-medium",
|
|
6583
|
+
style: {
|
|
6584
|
+
backgroundColor: `color-mix(in srgb, ${color} 12%, transparent)`
|
|
6585
|
+
},
|
|
6586
|
+
children: [
|
|
6587
|
+
/* @__PURE__ */ jsx(
|
|
6588
|
+
"span",
|
|
6589
|
+
{
|
|
6590
|
+
"aria-hidden": "true",
|
|
6591
|
+
className: "h-2 w-2 shrink-0 rounded-full",
|
|
6592
|
+
style: { backgroundColor: color }
|
|
6593
|
+
}
|
|
6594
|
+
),
|
|
6595
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: name })
|
|
6596
|
+
]
|
|
6597
|
+
}
|
|
6598
|
+
),
|
|
6599
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
6600
|
+
utterance.text ? highlight(utterance.text, query) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground italic", children: labels.noWords }),
|
|
6601
|
+
overlap && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground border-border ms-2 inline-block max-w-full rounded border px-1.5 text-[11px] break-words", children: labels.overlapWith(overlap) })
|
|
6602
|
+
] })
|
|
6603
|
+
]
|
|
6604
|
+
}
|
|
6605
|
+
)
|
|
6606
|
+
);
|
|
6607
|
+
});
|
|
6608
|
+
function TranscriptList({
|
|
6609
|
+
utterances,
|
|
6610
|
+
speakersById,
|
|
6611
|
+
activeId,
|
|
6612
|
+
playingId,
|
|
6613
|
+
query,
|
|
6614
|
+
onPlay,
|
|
6615
|
+
onPause,
|
|
6616
|
+
emptyMessage,
|
|
6617
|
+
labels
|
|
6618
|
+
}) {
|
|
6619
|
+
const scrollRef = React13.useRef(null);
|
|
6620
|
+
const [detached, setDetached] = React13.useState(false);
|
|
6621
|
+
const followUntil = React13.useRef(0);
|
|
6622
|
+
const virtualize = utterances.length > VIRTUALIZE_AFTER;
|
|
6623
|
+
const virtualizer = useVirtualizer({
|
|
6624
|
+
count: virtualize ? utterances.length : 0,
|
|
6625
|
+
getScrollElement: () => scrollRef.current,
|
|
6626
|
+
estimateSize: () => 40,
|
|
6627
|
+
overscan: 12,
|
|
6628
|
+
getItemKey: (index) => utterances[index]?.id ?? index
|
|
6629
|
+
});
|
|
6630
|
+
const scrollToActive = React13.useCallback(() => {
|
|
6631
|
+
if (!activeId) return;
|
|
6632
|
+
followUntil.current = Date.now() + FOLLOW_SCROLL_MS;
|
|
6633
|
+
if (virtualize) {
|
|
6634
|
+
const index = utterances.findIndex((u) => u.id === activeId);
|
|
6635
|
+
if (index >= 0) virtualizer.scrollToIndex(index, { align: "auto" });
|
|
6636
|
+
return;
|
|
6637
|
+
}
|
|
6638
|
+
const container = scrollRef.current;
|
|
6639
|
+
const line = container?.querySelector(`[data-id="${activeId}"]`)?.getBoundingClientRect();
|
|
6640
|
+
if (!container || !line) return;
|
|
6641
|
+
const view = container.getBoundingClientRect();
|
|
6642
|
+
if (line.top < view.top || line.height > container.clientHeight)
|
|
6643
|
+
container.scrollTop += line.top - view.top;
|
|
6644
|
+
else if (line.bottom > view.bottom)
|
|
6645
|
+
container.scrollTop += line.bottom - view.bottom;
|
|
6646
|
+
}, [activeId, utterances, virtualize, virtualizer]);
|
|
6647
|
+
React13.useEffect(() => {
|
|
6648
|
+
if (!detached) scrollToActive();
|
|
6649
|
+
}, [activeId, detached, scrollToActive]);
|
|
6650
|
+
const onScroll = () => {
|
|
6651
|
+
const container = scrollRef.current;
|
|
6652
|
+
if (detached || !activeId || !container || Date.now() < followUntil.current)
|
|
6653
|
+
return;
|
|
6654
|
+
const line = container.querySelector(`[data-id="${activeId}"]`)?.getBoundingClientRect();
|
|
6655
|
+
const view = container.getBoundingClientRect();
|
|
6656
|
+
if (!line || line.bottom <= view.top || line.top >= view.bottom)
|
|
6657
|
+
setDetached(true);
|
|
6658
|
+
};
|
|
6659
|
+
const play = React13.useCallback(
|
|
6660
|
+
(u) => {
|
|
6661
|
+
setDetached(false);
|
|
6662
|
+
onPlay(u);
|
|
6663
|
+
},
|
|
6664
|
+
[onPlay]
|
|
6665
|
+
);
|
|
6666
|
+
const row = (u, index) => /* @__PURE__ */ jsx(
|
|
6667
|
+
Row,
|
|
6668
|
+
{
|
|
6669
|
+
utterance: u,
|
|
6670
|
+
speaker: speakersById.get(u.speakerId),
|
|
6671
|
+
overlap: u.overlapSpeakerIds?.map((id) => speakersById.get(id)?.name ?? id).join(", "),
|
|
6672
|
+
active: u.id === activeId,
|
|
6673
|
+
playing: u.id === playingId,
|
|
6674
|
+
query,
|
|
6675
|
+
onPlay: play,
|
|
6676
|
+
onPause,
|
|
6677
|
+
labels,
|
|
6678
|
+
setSize: index === void 0 ? void 0 : utterances.length,
|
|
6679
|
+
posInSet: index === void 0 ? void 0 : index + 1
|
|
6680
|
+
}
|
|
6681
|
+
);
|
|
6682
|
+
if (utterances.length === 0)
|
|
6683
|
+
return /* @__PURE__ */ jsx(
|
|
6684
|
+
"p",
|
|
6685
|
+
{
|
|
6686
|
+
role: "status",
|
|
6687
|
+
className: "text-muted-foreground flex h-80 items-center justify-center p-6 text-center text-sm",
|
|
6688
|
+
children: emptyMessage
|
|
6689
|
+
}
|
|
6690
|
+
);
|
|
6691
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
6692
|
+
/* @__PURE__ */ jsx(
|
|
6693
|
+
"div",
|
|
6694
|
+
{
|
|
6695
|
+
ref: scrollRef,
|
|
6696
|
+
role: "list",
|
|
6697
|
+
"aria-label": labels.transcript,
|
|
6698
|
+
tabIndex: 0,
|
|
6699
|
+
onWheel: () => setDetached(true),
|
|
6700
|
+
onTouchMove: () => setDetached(true),
|
|
6701
|
+
onScroll,
|
|
6702
|
+
onKeyDown: (e) => {
|
|
6703
|
+
if (e.target === e.currentTarget && USER_SCROLL_KEYS.has(e.key))
|
|
6704
|
+
setDetached(true);
|
|
6705
|
+
},
|
|
6706
|
+
className: "focus-visible:ring-ring h-80 overflow-y-auto rounded-lg focus-visible:ring-2 focus-visible:outline-none",
|
|
6707
|
+
children: virtualize ? /* @__PURE__ */ jsx(
|
|
6708
|
+
"div",
|
|
6709
|
+
{
|
|
6710
|
+
className: "relative w-full",
|
|
6711
|
+
style: { height: virtualizer.getTotalSize() },
|
|
6712
|
+
children: virtualizer.getVirtualItems().map((item) => /* @__PURE__ */ jsx(
|
|
6713
|
+
"div",
|
|
6714
|
+
{
|
|
6715
|
+
"data-index": item.index,
|
|
6716
|
+
ref: virtualizer.measureElement,
|
|
6717
|
+
className: "absolute inset-x-0 top-0",
|
|
6718
|
+
style: { transform: `translateY(${item.start}px)` },
|
|
6719
|
+
children: row(utterances[item.index], item.index)
|
|
6720
|
+
},
|
|
6721
|
+
item.key
|
|
6722
|
+
))
|
|
6723
|
+
}
|
|
6724
|
+
) : utterances.map((u) => /* @__PURE__ */ jsx(React13.Fragment, { children: row(u) }, u.id))
|
|
6725
|
+
}
|
|
6726
|
+
),
|
|
6727
|
+
detached && activeId && /* @__PURE__ */ jsx(
|
|
6728
|
+
Button,
|
|
6729
|
+
{
|
|
6730
|
+
type: "button",
|
|
6731
|
+
variant: "primary",
|
|
6732
|
+
size: "sm",
|
|
6733
|
+
onClick: () => {
|
|
6734
|
+
setDetached(false);
|
|
6735
|
+
scrollToActive();
|
|
6736
|
+
},
|
|
6737
|
+
className: "absolute end-4 bottom-3 rounded-full shadow",
|
|
6738
|
+
children: labels.backToCurrent
|
|
6739
|
+
}
|
|
6740
|
+
)
|
|
6741
|
+
] });
|
|
6742
|
+
}
|
|
6743
|
+
function usePlayback(src) {
|
|
6744
|
+
const audioRef = React13.useRef(null);
|
|
6745
|
+
const rangeRef = React13.useRef(null);
|
|
6746
|
+
const [currentTime, setCurrentTime] = React13.useState(0);
|
|
6747
|
+
const [volume, setVolumeState] = React13.useState(1);
|
|
6748
|
+
const [error, setError] = React13.useState(null);
|
|
6749
|
+
const [range, setRangeState] = React13.useState(null);
|
|
6750
|
+
const setRange = React13.useCallback((next) => {
|
|
6751
|
+
rangeRef.current = next;
|
|
6752
|
+
setRangeState(next);
|
|
6753
|
+
}, []);
|
|
6754
|
+
const stopAtRangeEnd = React13.useCallback(
|
|
6755
|
+
(audio) => {
|
|
6756
|
+
const r = rangeRef.current;
|
|
6757
|
+
if (!r || audio.currentTime < r.end) return false;
|
|
6758
|
+
audio.pause();
|
|
6759
|
+
audio.currentTime = r.end;
|
|
6760
|
+
setCurrentTime(r.end);
|
|
6761
|
+
setRange(null);
|
|
6762
|
+
return true;
|
|
6763
|
+
},
|
|
6764
|
+
[setRange]
|
|
6765
|
+
);
|
|
6766
|
+
const transport = useMediaTransport({
|
|
6767
|
+
errorLabel: "recording",
|
|
6768
|
+
onError: () => setError("load"),
|
|
6769
|
+
// rAF is paused in background tabs; timeupdate still fires, so it also keeps time and enforces the interval end.
|
|
6770
|
+
onTimeUpdate: (ms) => {
|
|
6771
|
+
const audio = audioRef.current;
|
|
6772
|
+
if (audio && stopAtRangeEnd(audio)) return;
|
|
6773
|
+
setCurrentTime(ms / 1e3);
|
|
6774
|
+
},
|
|
6775
|
+
onStateChange: (state) => {
|
|
6776
|
+
if (state === "paused" && audioRef.current)
|
|
6777
|
+
setCurrentTime(audioRef.current.currentTime);
|
|
6778
|
+
},
|
|
6779
|
+
onEnded: () => setRange(null)
|
|
6780
|
+
});
|
|
6781
|
+
const {
|
|
6782
|
+
setMediaElement: attachTransport,
|
|
6783
|
+
isPlaying: playing,
|
|
6784
|
+
durationMs,
|
|
6785
|
+
playbackRate: rate,
|
|
6786
|
+
setPlaybackRate: setRate,
|
|
6787
|
+
seekToMs,
|
|
6788
|
+
pause
|
|
6789
|
+
} = transport;
|
|
6790
|
+
const volumeRef = React13.useRef(volume);
|
|
6791
|
+
volumeRef.current = volume;
|
|
6792
|
+
const setMediaElement = React13.useCallback(
|
|
6793
|
+
(element) => {
|
|
6794
|
+
audioRef.current = element;
|
|
6795
|
+
if (element) element.volume = volumeRef.current;
|
|
6796
|
+
attachTransport(element);
|
|
6797
|
+
},
|
|
6798
|
+
[attachTransport]
|
|
6799
|
+
);
|
|
6800
|
+
React13.useEffect(() => {
|
|
6801
|
+
setCurrentTime(0);
|
|
6802
|
+
setError(null);
|
|
6803
|
+
setRange(null);
|
|
6804
|
+
}, [src, setRange]);
|
|
6805
|
+
React13.useEffect(() => {
|
|
6806
|
+
const audio = audioRef.current;
|
|
6807
|
+
if (!playing || !audio) return;
|
|
6808
|
+
let frame = 0;
|
|
6809
|
+
const tick = () => {
|
|
6810
|
+
setCurrentTime(audio.currentTime);
|
|
6811
|
+
if (!stopAtRangeEnd(audio)) frame = requestAnimationFrame(tick);
|
|
6812
|
+
};
|
|
6813
|
+
frame = requestAnimationFrame(tick);
|
|
6814
|
+
return () => cancelAnimationFrame(frame);
|
|
6815
|
+
}, [playing, stopAtRangeEnd]);
|
|
6816
|
+
const start = React13.useCallback((audio) => {
|
|
6817
|
+
setError((e) => e === "play" ? null : e);
|
|
6818
|
+
audio.play()?.catch((e) => {
|
|
6819
|
+
if (e?.name !== "AbortError")
|
|
6820
|
+
setError("play");
|
|
6821
|
+
});
|
|
6822
|
+
}, []);
|
|
6823
|
+
const play = React13.useCallback(() => {
|
|
6824
|
+
const audio = audioRef.current;
|
|
6825
|
+
if (!audio) return;
|
|
6826
|
+
setRange(null);
|
|
6827
|
+
if (audio.ended) audio.currentTime = 0;
|
|
6828
|
+
start(audio);
|
|
6829
|
+
}, [start, setRange]);
|
|
6830
|
+
const seek = React13.useCallback(
|
|
6831
|
+
(time) => {
|
|
6832
|
+
const audio = audioRef.current;
|
|
6833
|
+
if (!audio) return;
|
|
6834
|
+
const max = Number.isFinite(audio.duration) ? audio.duration : time;
|
|
6835
|
+
const t = Math.min(Math.max(0, time), max);
|
|
6836
|
+
const r = rangeRef.current;
|
|
6837
|
+
if (r && (t < r.start || t >= r.end)) setRange(null);
|
|
6838
|
+
seekToMs(t * 1e3);
|
|
6839
|
+
setCurrentTime(t);
|
|
6840
|
+
},
|
|
6841
|
+
[setRange, seekToMs]
|
|
6842
|
+
);
|
|
6843
|
+
const playRange = React13.useCallback(
|
|
6844
|
+
(next) => {
|
|
6845
|
+
const audio = audioRef.current;
|
|
6846
|
+
if (!audio) return;
|
|
6847
|
+
const playable = next.end > next.start;
|
|
6848
|
+
setRange(playable ? next : null);
|
|
6849
|
+
seekToMs(next.start * 1e3);
|
|
6850
|
+
setCurrentTime(next.start);
|
|
6851
|
+
if (playable) start(audio);
|
|
6852
|
+
else pause();
|
|
6853
|
+
},
|
|
6854
|
+
[start, pause, setRange, seekToMs]
|
|
6855
|
+
);
|
|
6856
|
+
const setVolume = React13.useCallback((next) => {
|
|
6857
|
+
setVolumeState(next);
|
|
6858
|
+
if (audioRef.current) audioRef.current.volume = next;
|
|
6859
|
+
}, []);
|
|
6860
|
+
return {
|
|
6861
|
+
setMediaElement,
|
|
6862
|
+
playing,
|
|
6863
|
+
currentTime,
|
|
6864
|
+
duration: durationMs / 1e3,
|
|
6865
|
+
rate,
|
|
6866
|
+
volume,
|
|
6867
|
+
error,
|
|
6868
|
+
range,
|
|
6869
|
+
play,
|
|
6870
|
+
pause,
|
|
6871
|
+
toggle: playing ? pause : play,
|
|
6872
|
+
seek,
|
|
6873
|
+
playRange,
|
|
6874
|
+
setRate,
|
|
6875
|
+
setVolume
|
|
6876
|
+
};
|
|
6877
|
+
}
|
|
6878
|
+
var BAR_PITCH = 3;
|
|
6879
|
+
var BAR_WIDTH = 2;
|
|
6880
|
+
function Waveform({
|
|
6881
|
+
peaks,
|
|
6882
|
+
view,
|
|
6883
|
+
currentTime
|
|
6884
|
+
}) {
|
|
6885
|
+
const canvasRef = React13.useRef(null);
|
|
6886
|
+
const [width, setWidth] = React13.useState(0);
|
|
6887
|
+
React13.useEffect(() => {
|
|
6888
|
+
const canvas = canvasRef.current;
|
|
6889
|
+
if (!canvas) return;
|
|
6890
|
+
const observer = new ResizeObserver(
|
|
6891
|
+
() => setWidth(canvas.clientWidth || 0)
|
|
6892
|
+
);
|
|
6893
|
+
observer.observe(canvas);
|
|
6894
|
+
return () => observer.disconnect();
|
|
6895
|
+
}, []);
|
|
6896
|
+
React13.useEffect(() => {
|
|
6897
|
+
const canvas = canvasRef.current;
|
|
6898
|
+
const ctx = canvas?.getContext("2d");
|
|
6899
|
+
if (!canvas || !ctx || width === 0) return;
|
|
6900
|
+
const height = canvas.clientHeight;
|
|
6901
|
+
const dpr = window.devicePixelRatio || 1;
|
|
6902
|
+
const bufferWidth = Math.round(width * dpr);
|
|
6903
|
+
const bufferHeight = Math.round(height * dpr);
|
|
6904
|
+
if (canvas.width !== bufferWidth || canvas.height !== bufferHeight) {
|
|
6905
|
+
canvas.width = bufferWidth;
|
|
6906
|
+
canvas.height = bufferHeight;
|
|
6907
|
+
}
|
|
6908
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
6909
|
+
ctx.clearRect(0, 0, width, height);
|
|
6910
|
+
if (!peaks || view.span <= 0) return;
|
|
6911
|
+
ctx.fillStyle = getComputedStyle(canvas).color;
|
|
6912
|
+
const secondsPerPx = view.span / width;
|
|
6913
|
+
for (let x = 0; x < width; x += BAR_PITCH) {
|
|
6914
|
+
const t0 = view.start + x * secondsPerPx;
|
|
6915
|
+
const from = Math.floor(t0 * peaks.perSecond);
|
|
6916
|
+
const to = Math.max(
|
|
6917
|
+
from + 1,
|
|
6918
|
+
Math.ceil((t0 + BAR_PITCH * secondsPerPx) * peaks.perSecond)
|
|
6919
|
+
);
|
|
6920
|
+
let peak = 0;
|
|
6921
|
+
for (let i = from; i < to && i < peaks.data.length; i++)
|
|
6922
|
+
if (peaks.data[i] > peak) peak = peaks.data[i];
|
|
6923
|
+
const bar = Math.max(1, peak * height);
|
|
6924
|
+
ctx.globalAlpha = t0 < currentTime ? 1 : 0.35;
|
|
6925
|
+
ctx.fillRect(x, (height - bar) / 2, BAR_WIDTH, bar);
|
|
6926
|
+
}
|
|
6927
|
+
}, [peaks, view, currentTime, width]);
|
|
6928
|
+
return /* @__PURE__ */ jsx(
|
|
6929
|
+
"canvas",
|
|
6930
|
+
{
|
|
6931
|
+
ref: canvasRef,
|
|
6932
|
+
"aria-hidden": "true",
|
|
6933
|
+
className: "text-primary-600 dark:text-primary-400 block h-14 w-full"
|
|
6934
|
+
}
|
|
6935
|
+
);
|
|
6936
|
+
}
|
|
6937
|
+
var SEEK_STEP_SECONDS = 5;
|
|
6938
|
+
var ALL_SPEAKERS = "all";
|
|
6939
|
+
var SOME_SPEAKERS = "some";
|
|
6940
|
+
var SPEAKER_PREFIX = "speaker:";
|
|
6941
|
+
function inertOutside(element) {
|
|
6942
|
+
const changed = [];
|
|
6943
|
+
for (let node = element; node && node !== document.body; node = node.parentElement) {
|
|
6944
|
+
for (const sibling of Array.from(node.parentElement?.children ?? [])) {
|
|
6945
|
+
if (sibling === node || sibling.hasAttribute("inert")) continue;
|
|
6946
|
+
sibling.setAttribute("inert", "");
|
|
6947
|
+
changed.push(sibling);
|
|
6948
|
+
}
|
|
6949
|
+
}
|
|
6950
|
+
return () => changed.forEach((el) => el.removeAttribute("inert"));
|
|
6951
|
+
}
|
|
6952
|
+
var TRACK_OFFSET = "7.25rem";
|
|
6953
|
+
var pressedButton = "aria-pressed:bg-primary-50 aria-pressed:text-primary-800 dark:aria-pressed:bg-primary-950 dark:aria-pressed:text-primary-200";
|
|
6954
|
+
function TranscriptPlayer({
|
|
6955
|
+
src,
|
|
6956
|
+
transcript,
|
|
6957
|
+
speakerLabels,
|
|
6958
|
+
peaks: providedPeaks,
|
|
6959
|
+
labels: labelOverrides,
|
|
6960
|
+
className
|
|
6961
|
+
}) {
|
|
6962
|
+
const rootRef = React13.useRef(null);
|
|
6963
|
+
const fullscreenButtonRef = React13.useRef(null);
|
|
6964
|
+
const transcriptHeadingId = React13.useId();
|
|
6965
|
+
const labels = React13.useMemo(
|
|
6966
|
+
() => ({ ...DEFAULT_TRANSCRIPT_PLAYER_LABELS, ...labelOverrides }),
|
|
6967
|
+
[labelOverrides]
|
|
6968
|
+
);
|
|
6969
|
+
const playback = usePlayback(src);
|
|
6970
|
+
const peaks = useWaveformPeaks(src, providedPeaks);
|
|
6971
|
+
const utterances = React13.useMemo(
|
|
6972
|
+
() => toUtterances(transcript),
|
|
6973
|
+
[transcript]
|
|
6974
|
+
);
|
|
6975
|
+
const segments = React13.useMemo(
|
|
6976
|
+
() => toLaneSegments(transcript, utterances),
|
|
6977
|
+
[transcript, utterances]
|
|
6978
|
+
);
|
|
6979
|
+
const speakers = React13.useMemo(
|
|
6980
|
+
() => toSpeakers(
|
|
6981
|
+
transcript,
|
|
6982
|
+
[
|
|
6983
|
+
...segments.map((s) => s.speakerId),
|
|
6984
|
+
...utterances.flatMap((u) => [
|
|
6985
|
+
u.speakerId,
|
|
6986
|
+
...u.overlapSpeakerIds ?? []
|
|
6987
|
+
])
|
|
6988
|
+
],
|
|
6989
|
+
speakerLabels,
|
|
6990
|
+
labels.unknownSpeaker
|
|
6991
|
+
),
|
|
6992
|
+
[transcript, segments, utterances, speakerLabels, labels.unknownSpeaker]
|
|
6993
|
+
);
|
|
6994
|
+
const speakersById = React13.useMemo(
|
|
6995
|
+
() => new Map(speakers.map((s) => [s.id, s])),
|
|
6996
|
+
[speakers]
|
|
6997
|
+
);
|
|
6998
|
+
const talk = React13.useMemo(() => talkTime(segments), [segments]);
|
|
6999
|
+
const overlapping = React13.useMemo(() => hasOverlap(segments), [segments]);
|
|
7000
|
+
const dataEnd = React13.useMemo(
|
|
7001
|
+
() => [
|
|
7002
|
+
finiteSeconds(transcript.durationMs),
|
|
7003
|
+
...segments.map((s) => s.end),
|
|
7004
|
+
...utterances.map((u) => u.end)
|
|
7005
|
+
].reduce((end, t) => Number.isFinite(t) && t > end ? t : end, 0),
|
|
7006
|
+
[transcript.durationMs, segments, utterances]
|
|
7007
|
+
);
|
|
7008
|
+
const duration = Math.max(playback.duration, dataEnd);
|
|
7009
|
+
const [userView, setUserView] = React13.useState(null);
|
|
7010
|
+
const [follow, setFollow] = React13.useState(true);
|
|
7011
|
+
const [hidden, setHidden] = React13.useState(/* @__PURE__ */ new Set());
|
|
7012
|
+
const [query, setQuery] = React13.useState("");
|
|
7013
|
+
const [fullscreen, setFullscreen] = React13.useState(false);
|
|
7014
|
+
const [lastVolume, setLastVolume] = React13.useState(1);
|
|
7015
|
+
React13.useEffect(() => {
|
|
7016
|
+
setUserView(null);
|
|
7017
|
+
setFollow(true);
|
|
7018
|
+
setHidden(/* @__PURE__ */ new Set());
|
|
7019
|
+
setQuery("");
|
|
7020
|
+
}, [src]);
|
|
7021
|
+
const view = React13.useMemo(
|
|
7022
|
+
() => clampView(userView ?? initialView(duration), duration),
|
|
7023
|
+
[userView, duration]
|
|
7024
|
+
);
|
|
7025
|
+
const { currentTime, playing } = playback;
|
|
7026
|
+
React13.useEffect(() => {
|
|
7027
|
+
if (!follow || !playing) return;
|
|
7028
|
+
const next = followView(view, currentTime, duration);
|
|
7029
|
+
if (next.start !== view.start) setUserView(next);
|
|
7030
|
+
}, [follow, playing, currentTime, duration, view]);
|
|
7031
|
+
React13.useEffect(() => {
|
|
7032
|
+
const onChange = () => {
|
|
7033
|
+
if (!document.fullscreenElement) setFullscreen(false);
|
|
7034
|
+
};
|
|
7035
|
+
document.addEventListener("fullscreenchange", onChange);
|
|
7036
|
+
return () => document.removeEventListener("fullscreenchange", onChange);
|
|
7037
|
+
}, []);
|
|
7038
|
+
React13.useEffect(() => {
|
|
7039
|
+
const root = rootRef.current;
|
|
7040
|
+
const button = fullscreenButtonRef.current;
|
|
7041
|
+
if (!fullscreen || !root) return;
|
|
7042
|
+
const restore = inertOutside(root);
|
|
7043
|
+
const onKeyDown = (event) => {
|
|
7044
|
+
if (event.key !== "Escape" || document.fullscreenElement) return;
|
|
7045
|
+
const target = event.target;
|
|
7046
|
+
if (target?.closest?.('[aria-expanded="true"]')) return;
|
|
7047
|
+
if (target?.type === "search" && target.value) return;
|
|
7048
|
+
setFullscreen(false);
|
|
7049
|
+
};
|
|
7050
|
+
document.addEventListener("keydown", onKeyDown);
|
|
7051
|
+
return () => {
|
|
7052
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
7053
|
+
restore();
|
|
7054
|
+
if (document.fullscreenElement === document.documentElement)
|
|
7055
|
+
void document.exitFullscreen?.()?.catch(() => {
|
|
7056
|
+
});
|
|
7057
|
+
button?.focus();
|
|
7058
|
+
};
|
|
7059
|
+
}, [fullscreen]);
|
|
7060
|
+
const visibleSpeakers = React13.useMemo(
|
|
7061
|
+
() => speakers.filter((s) => !hidden.has(s.id)),
|
|
7062
|
+
[speakers, hidden]
|
|
7063
|
+
);
|
|
7064
|
+
const visibleSegments = React13.useMemo(
|
|
7065
|
+
() => segments.filter((s) => !hidden.has(s.speakerId)),
|
|
7066
|
+
[segments, hidden]
|
|
7067
|
+
);
|
|
7068
|
+
const shown = React13.useMemo(
|
|
7069
|
+
() => filterUtterances(utterances, hidden, query),
|
|
7070
|
+
[utterances, hidden, query]
|
|
7071
|
+
);
|
|
7072
|
+
const active = activeUtteranceAt(shown, currentTime);
|
|
7073
|
+
const playingId = playing && playback.range?.id || null;
|
|
7074
|
+
const canPlay = Boolean(src) && playback.error !== "load";
|
|
7075
|
+
const { playRange, seek, pause } = playback;
|
|
7076
|
+
const seekTo = React13.useCallback(
|
|
7077
|
+
(time) => {
|
|
7078
|
+
seek(time);
|
|
7079
|
+
if (follow)
|
|
7080
|
+
setUserView(
|
|
7081
|
+
(current) => followView(
|
|
7082
|
+
clampView(current ?? initialView(duration), duration),
|
|
7083
|
+
Math.min(Math.max(0, time), duration),
|
|
7084
|
+
duration
|
|
7085
|
+
)
|
|
7086
|
+
);
|
|
7087
|
+
},
|
|
7088
|
+
[seek, follow, duration]
|
|
7089
|
+
);
|
|
7090
|
+
const playSegment = React13.useCallback(
|
|
7091
|
+
(s) => {
|
|
7092
|
+
setFollow(true);
|
|
7093
|
+
playRange(s);
|
|
7094
|
+
},
|
|
7095
|
+
[playRange]
|
|
7096
|
+
);
|
|
7097
|
+
const playUtterance = React13.useCallback(
|
|
7098
|
+
(u) => {
|
|
7099
|
+
setFollow(true);
|
|
7100
|
+
playRange(u);
|
|
7101
|
+
},
|
|
7102
|
+
[playRange]
|
|
7103
|
+
);
|
|
7104
|
+
const navigate = (next) => {
|
|
7105
|
+
setFollow(false);
|
|
7106
|
+
setUserView(next);
|
|
7107
|
+
};
|
|
7108
|
+
const zoom = (factor) => {
|
|
7109
|
+
const anchor = currentTime >= view.start && currentTime <= view.start + view.span ? currentTime : view.start + view.span / 2;
|
|
7110
|
+
setUserView(zoomView(view, factor, anchor, duration));
|
|
7111
|
+
};
|
|
7112
|
+
const toggleSpeaker = React13.useCallback((id) => {
|
|
7113
|
+
setHidden((prev) => {
|
|
7114
|
+
const next = new Set(prev);
|
|
7115
|
+
if (next.has(id)) next.delete(id);
|
|
7116
|
+
else next.add(id);
|
|
7117
|
+
return next;
|
|
7118
|
+
});
|
|
7119
|
+
}, []);
|
|
7120
|
+
const visibleIds = visibleSpeakers.map((s) => s.id);
|
|
7121
|
+
const filterValue = hidden.size === 0 ? ALL_SPEAKERS : visibleIds.length === 1 ? SPEAKER_PREFIX + visibleIds[0] : SOME_SPEAKERS;
|
|
7122
|
+
const onSeekKey = (event) => {
|
|
7123
|
+
const step = {
|
|
7124
|
+
ArrowLeft: -SEEK_STEP_SECONDS,
|
|
7125
|
+
ArrowRight: SEEK_STEP_SECONDS,
|
|
7126
|
+
Home: -duration,
|
|
7127
|
+
End: duration
|
|
7128
|
+
};
|
|
7129
|
+
if (event.key === " " || event.key === "Enter") {
|
|
7130
|
+
event.preventDefault();
|
|
7131
|
+
playback.toggle();
|
|
7132
|
+
} else if (event.key in step) {
|
|
7133
|
+
event.preventDefault();
|
|
7134
|
+
seekTo(currentTime + step[event.key]);
|
|
7135
|
+
}
|
|
7136
|
+
};
|
|
7137
|
+
const toggleFullscreen = () => {
|
|
7138
|
+
if (fullscreen) {
|
|
7139
|
+
setFullscreen(false);
|
|
7140
|
+
if (document.fullscreenElement) void document.exitFullscreen?.();
|
|
7141
|
+
return;
|
|
7142
|
+
}
|
|
7143
|
+
setFullscreen(true);
|
|
7144
|
+
void document.documentElement.requestFullscreen?.()?.catch(() => {
|
|
7145
|
+
});
|
|
7146
|
+
};
|
|
7147
|
+
const playhead = viewFraction(currentTime, view);
|
|
7148
|
+
const playheadVisible = duration > 0 && currentTime >= view.start && currentTime <= view.start + view.span;
|
|
7149
|
+
return /* @__PURE__ */ jsxs(
|
|
7150
|
+
"div",
|
|
7151
|
+
{
|
|
7152
|
+
ref: rootRef,
|
|
7153
|
+
className: cn(
|
|
7154
|
+
"text-foreground flex flex-col gap-4",
|
|
7155
|
+
fullscreen && "bg-background fixed inset-0 z-50 overflow-y-auto p-6",
|
|
7156
|
+
className
|
|
7157
|
+
),
|
|
7158
|
+
children: [
|
|
7159
|
+
src && // eslint-disable-next-line jsx-a11y/media-has-caption -- the synced transcript below is the text alternative
|
|
7160
|
+
/* @__PURE__ */ jsx(
|
|
7161
|
+
"audio",
|
|
7162
|
+
{
|
|
7163
|
+
ref: playback.setMediaElement,
|
|
7164
|
+
src,
|
|
7165
|
+
preload: "metadata"
|
|
7166
|
+
},
|
|
7167
|
+
src
|
|
7168
|
+
),
|
|
7169
|
+
/* @__PURE__ */ jsxs(
|
|
7170
|
+
"section",
|
|
7171
|
+
{
|
|
7172
|
+
"aria-label": labels.recording,
|
|
7173
|
+
className: "border-border bg-card text-card-foreground sticky top-0 z-10 rounded-xl border p-4",
|
|
7174
|
+
children: [
|
|
7175
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3 flex flex-wrap items-center gap-x-4 gap-y-2", children: [
|
|
7176
|
+
/* @__PURE__ */ jsx(
|
|
7177
|
+
Button,
|
|
7178
|
+
{
|
|
7179
|
+
type: "button",
|
|
7180
|
+
variant: "primary",
|
|
7181
|
+
size: "icon",
|
|
7182
|
+
onClick: playback.toggle,
|
|
7183
|
+
disabled: !canPlay,
|
|
7184
|
+
"aria-label": playing ? labels.pause : labels.play,
|
|
7185
|
+
className: "shrink-0 rounded-full",
|
|
7186
|
+
children: playing ? /* @__PURE__ */ jsx(Pause, { "aria-hidden": "true", className: "h-4 w-4 fill-current" }) : /* @__PURE__ */ jsx(
|
|
7187
|
+
Play,
|
|
7188
|
+
{
|
|
7189
|
+
"aria-hidden": "true",
|
|
7190
|
+
className: "ms-0.5 h-4 w-4 fill-current"
|
|
7191
|
+
}
|
|
7192
|
+
)
|
|
7193
|
+
}
|
|
7194
|
+
),
|
|
7195
|
+
/* @__PURE__ */ jsxs("span", { dir: "ltr", className: "text-sm tabular-nums", children: [
|
|
7196
|
+
formatClock(currentTime),
|
|
7197
|
+
" ",
|
|
7198
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
7199
|
+
"/ ",
|
|
7200
|
+
formatClock(duration)
|
|
7201
|
+
] })
|
|
7202
|
+
] }),
|
|
7203
|
+
playback.error && /* @__PURE__ */ jsx("span", { role: "alert", className: "text-destructive text-sm", children: playback.error === "load" ? labels.loadError : labels.playError }),
|
|
7204
|
+
!src && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: labels.noRecording }),
|
|
7205
|
+
/* @__PURE__ */ jsxs("div", { className: "ms-auto flex items-center gap-2", children: [
|
|
7206
|
+
/* @__PURE__ */ jsx(
|
|
7207
|
+
Button,
|
|
7208
|
+
{
|
|
7209
|
+
type: "button",
|
|
7210
|
+
variant: "ghost",
|
|
7211
|
+
size: "icon-sm",
|
|
7212
|
+
"aria-label": playback.volume === 0 ? labels.unmute : labels.mute,
|
|
7213
|
+
onClick: () => {
|
|
7214
|
+
if (playback.volume === 0) playback.setVolume(lastVolume || 1);
|
|
7215
|
+
else {
|
|
7216
|
+
setLastVolume(playback.volume);
|
|
7217
|
+
playback.setVolume(0);
|
|
7218
|
+
}
|
|
7219
|
+
},
|
|
7220
|
+
children: playback.volume === 0 ? /* @__PURE__ */ jsx(VolumeX, { "aria-hidden": "true", className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Volume2, { "aria-hidden": "true", className: "h-4 w-4" })
|
|
7221
|
+
}
|
|
7222
|
+
),
|
|
7223
|
+
/* @__PURE__ */ jsx(
|
|
7224
|
+
Slider,
|
|
7225
|
+
{
|
|
7226
|
+
"aria-label": labels.volume,
|
|
7227
|
+
min: 0,
|
|
7228
|
+
max: 1,
|
|
7229
|
+
step: 0.05,
|
|
7230
|
+
value: playback.volume,
|
|
7231
|
+
onValueChange: playback.setVolume,
|
|
7232
|
+
size: "sm",
|
|
7233
|
+
className: "w-24"
|
|
7234
|
+
}
|
|
7235
|
+
),
|
|
7236
|
+
/* @__PURE__ */ jsx(
|
|
7237
|
+
Select,
|
|
7238
|
+
{
|
|
7239
|
+
"aria-label": labels.playbackSpeed,
|
|
7240
|
+
size: "sm",
|
|
7241
|
+
className: "w-20",
|
|
7242
|
+
value: String(playback.rate),
|
|
7243
|
+
onValueChange: (v) => playback.setRate(Number(v)),
|
|
7244
|
+
options: PLAYBACK_SPEEDS.map((s) => ({
|
|
7245
|
+
value: String(s),
|
|
7246
|
+
label: labels.formatSpeed(s)
|
|
7247
|
+
}))
|
|
7248
|
+
}
|
|
7249
|
+
),
|
|
7250
|
+
/* @__PURE__ */ jsx(
|
|
7251
|
+
Button,
|
|
7252
|
+
{
|
|
7253
|
+
ref: fullscreenButtonRef,
|
|
7254
|
+
type: "button",
|
|
7255
|
+
variant: "ghost",
|
|
7256
|
+
size: "icon-sm",
|
|
7257
|
+
"aria-label": fullscreen ? labels.exitFullScreen : labels.fullScreen,
|
|
7258
|
+
onClick: toggleFullscreen,
|
|
7259
|
+
children: fullscreen ? /* @__PURE__ */ jsx(Minimize2, { "aria-hidden": "true", className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Maximize2, { "aria-hidden": "true", className: "h-4 w-4" })
|
|
7260
|
+
}
|
|
7261
|
+
)
|
|
7262
|
+
] })
|
|
7263
|
+
] }),
|
|
7264
|
+
/* @__PURE__ */ jsxs("div", { dir: "ltr", className: "relative space-y-1.5", children: [
|
|
7265
|
+
/* @__PURE__ */ jsxs("div", { className: ROW_GRID, children: [
|
|
7266
|
+
/* @__PURE__ */ jsx("span", {}),
|
|
7267
|
+
/* @__PURE__ */ jsx(
|
|
7268
|
+
"div",
|
|
7269
|
+
{
|
|
7270
|
+
role: "slider",
|
|
7271
|
+
tabIndex: 0,
|
|
7272
|
+
"aria-label": labels.seek,
|
|
7273
|
+
"aria-valuemin": 0,
|
|
7274
|
+
"aria-valuemax": Math.round(duration),
|
|
7275
|
+
"aria-valuenow": Math.round(currentTime),
|
|
7276
|
+
"aria-valuetext": labels.seekValue(
|
|
7277
|
+
formatClock(currentTime),
|
|
7278
|
+
formatClock(duration)
|
|
7279
|
+
),
|
|
7280
|
+
onKeyDown: onSeekKey,
|
|
7281
|
+
onClick: (e) => seekTo(timeAtPointer(e.clientX, e.currentTarget, view)),
|
|
7282
|
+
className: "focus-visible:ring-ring cursor-pointer rounded focus-visible:ring-2 focus-visible:outline-none",
|
|
7283
|
+
children: /* @__PURE__ */ jsx(Waveform, { peaks, view, currentTime })
|
|
7284
|
+
}
|
|
7285
|
+
)
|
|
7286
|
+
] }),
|
|
7287
|
+
visibleSpeakers.length > 0 ? /* @__PURE__ */ jsx(
|
|
7288
|
+
SpeakerLanes,
|
|
7289
|
+
{
|
|
7290
|
+
speakers: visibleSpeakers,
|
|
7291
|
+
segments: visibleSegments,
|
|
7292
|
+
view,
|
|
7293
|
+
playingId,
|
|
7294
|
+
onPlaySegment: playSegment,
|
|
7295
|
+
onPause: pause,
|
|
7296
|
+
onSeek: seekTo,
|
|
7297
|
+
labels
|
|
7298
|
+
},
|
|
7299
|
+
src ?? ""
|
|
7300
|
+
) : /* @__PURE__ */ jsx("p", { className: "text-muted-foreground py-2 text-center text-xs", children: speakers.length ? labels.allSpeakersHidden : labels.noActivity }),
|
|
7301
|
+
/* @__PURE__ */ jsxs("div", { className: cn(ROW_GRID, "h-4"), "aria-hidden": "true", children: [
|
|
7302
|
+
/* @__PURE__ */ jsx("span", {}),
|
|
7303
|
+
/* @__PURE__ */ jsx("div", { className: "text-muted-foreground relative text-[11px] tabular-nums", children: ticksFor(view).map((t) => /* @__PURE__ */ jsx(
|
|
7304
|
+
"span",
|
|
7305
|
+
{
|
|
7306
|
+
className: "absolute -translate-x-1/2",
|
|
7307
|
+
style: {
|
|
7308
|
+
// rtl-ignore -- time axis inside the player's dir="ltr" timeline
|
|
7309
|
+
left: `${viewFraction(t, view) * 100}%`
|
|
7310
|
+
},
|
|
7311
|
+
children: formatClock(t)
|
|
7312
|
+
},
|
|
7313
|
+
t
|
|
7314
|
+
)) })
|
|
7315
|
+
] }),
|
|
7316
|
+
playheadVisible && /* @__PURE__ */ jsxs(
|
|
7317
|
+
"div",
|
|
7318
|
+
{
|
|
7319
|
+
"aria-hidden": "true",
|
|
7320
|
+
className: "pointer-events-none absolute inset-y-0",
|
|
7321
|
+
style: {
|
|
7322
|
+
// rtl-ignore -- time axis inside the player's dir="ltr" timeline
|
|
7323
|
+
left: `calc(${TRACK_OFFSET} + (100% - ${TRACK_OFFSET}) * ${playhead})`
|
|
7324
|
+
},
|
|
7325
|
+
children: [
|
|
7326
|
+
/* @__PURE__ */ jsx("span", { className: "bg-primary-600 absolute inset-y-0 w-0.5 -translate-x-1/2" }),
|
|
7327
|
+
/* @__PURE__ */ jsx("span", { className: "bg-primary-800 absolute -top-5 -translate-x-1/2 rounded px-1 text-[10px] font-medium text-white tabular-nums", children: formatClock(currentTime) })
|
|
7328
|
+
]
|
|
7329
|
+
}
|
|
7330
|
+
)
|
|
7331
|
+
] }),
|
|
7332
|
+
/* @__PURE__ */ jsxs("div", { dir: "ltr", className: cn(ROW_GRID, "mt-3 items-start"), children: [
|
|
7333
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
7334
|
+
/* @__PURE__ */ jsx(
|
|
7335
|
+
Button,
|
|
7336
|
+
{
|
|
7337
|
+
type: "button",
|
|
7338
|
+
variant: "ghost",
|
|
7339
|
+
size: "icon-sm",
|
|
7340
|
+
"aria-label": labels.zoomOut,
|
|
7341
|
+
disabled: view.span >= duration,
|
|
7342
|
+
onClick: () => zoom(2),
|
|
7343
|
+
children: /* @__PURE__ */ jsx(ZoomOut, { "aria-hidden": "true", className: "h-4 w-4" })
|
|
7344
|
+
}
|
|
7345
|
+
),
|
|
7346
|
+
/* @__PURE__ */ jsx(
|
|
7347
|
+
Button,
|
|
7348
|
+
{
|
|
7349
|
+
type: "button",
|
|
7350
|
+
variant: "ghost",
|
|
7351
|
+
size: "icon-sm",
|
|
7352
|
+
"aria-label": labels.zoomIn,
|
|
7353
|
+
disabled: view.span <= Math.min(MIN_VIEW_SECONDS, duration),
|
|
7354
|
+
onClick: () => zoom(0.5),
|
|
7355
|
+
children: /* @__PURE__ */ jsx(ZoomIn, { "aria-hidden": "true", className: "h-4 w-4" })
|
|
7356
|
+
}
|
|
7357
|
+
),
|
|
7358
|
+
/* @__PURE__ */ jsx(
|
|
7359
|
+
Button,
|
|
7360
|
+
{
|
|
7361
|
+
type: "button",
|
|
7362
|
+
variant: "ghost",
|
|
7363
|
+
size: "icon-sm",
|
|
7364
|
+
className: pressedButton,
|
|
7365
|
+
"aria-label": labels.followPlayback,
|
|
7366
|
+
"aria-pressed": follow,
|
|
7367
|
+
onClick: () => setFollow((f) => !f),
|
|
7368
|
+
children: /* @__PURE__ */ jsx(LocateFixed, { "aria-hidden": "true", className: "h-4 w-4" })
|
|
7369
|
+
}
|
|
7370
|
+
)
|
|
7371
|
+
] }),
|
|
7372
|
+
/* @__PURE__ */ jsx(
|
|
7373
|
+
TimelineOverview,
|
|
7374
|
+
{
|
|
7375
|
+
speakers: visibleSpeakers,
|
|
7376
|
+
segments: visibleSegments,
|
|
7377
|
+
duration,
|
|
7378
|
+
view,
|
|
7379
|
+
currentTime,
|
|
7380
|
+
onViewChange: navigate,
|
|
7381
|
+
labels
|
|
7382
|
+
}
|
|
7383
|
+
)
|
|
7384
|
+
] })
|
|
7385
|
+
]
|
|
7386
|
+
}
|
|
7387
|
+
),
|
|
7388
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 lg:grid-cols-[minmax(0,1fr)_18rem]", children: [
|
|
7389
|
+
/* @__PURE__ */ jsxs(
|
|
7390
|
+
"section",
|
|
7391
|
+
{
|
|
7392
|
+
"aria-labelledby": transcriptHeadingId,
|
|
7393
|
+
className: "border-border bg-card text-card-foreground rounded-xl border p-4",
|
|
7394
|
+
children: [
|
|
7395
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3 flex flex-wrap items-center gap-3", children: [
|
|
7396
|
+
/* @__PURE__ */ jsx("h3", { id: transcriptHeadingId, className: "text-base font-semibold", children: labels.transcript }),
|
|
7397
|
+
/* @__PURE__ */ jsxs("div", { className: "relative min-w-40 flex-1", children: [
|
|
7398
|
+
/* @__PURE__ */ jsx(
|
|
7399
|
+
Search,
|
|
7400
|
+
{
|
|
7401
|
+
"aria-hidden": "true",
|
|
7402
|
+
className: "text-muted-foreground pointer-events-none absolute start-2.5 top-1/2 h-4 w-4 -translate-y-1/2"
|
|
7403
|
+
}
|
|
7404
|
+
),
|
|
7405
|
+
/* @__PURE__ */ jsx(
|
|
7406
|
+
Input,
|
|
7407
|
+
{
|
|
7408
|
+
type: "search",
|
|
7409
|
+
label: labels.searchTranscript,
|
|
7410
|
+
hideLabel: true,
|
|
7411
|
+
placeholder: labels.searchPlaceholder,
|
|
7412
|
+
value: query,
|
|
7413
|
+
onChange: (e) => setQuery(e.target.value),
|
|
7414
|
+
size: "sm",
|
|
7415
|
+
className: "ps-8"
|
|
7416
|
+
}
|
|
7417
|
+
)
|
|
7418
|
+
] }),
|
|
7419
|
+
/* @__PURE__ */ jsx(
|
|
7420
|
+
Select,
|
|
7421
|
+
{
|
|
7422
|
+
"aria-label": labels.showSpeakers,
|
|
7423
|
+
size: "sm",
|
|
7424
|
+
className: "w-44",
|
|
7425
|
+
value: filterValue,
|
|
7426
|
+
onValueChange: (v) => {
|
|
7427
|
+
if (v === ALL_SPEAKERS) setHidden(/* @__PURE__ */ new Set());
|
|
7428
|
+
else if (v.startsWith(SPEAKER_PREFIX)) {
|
|
7429
|
+
const id = v.slice(SPEAKER_PREFIX.length);
|
|
7430
|
+
setHidden(
|
|
7431
|
+
new Set(
|
|
7432
|
+
speakers.filter((s) => s.id !== id).map((s) => s.id)
|
|
7433
|
+
)
|
|
7434
|
+
);
|
|
7435
|
+
}
|
|
7436
|
+
},
|
|
7437
|
+
options: [
|
|
7438
|
+
{ value: ALL_SPEAKERS, label: labels.allSpeakers },
|
|
7439
|
+
...speakers.map((s) => ({
|
|
7440
|
+
value: SPEAKER_PREFIX + s.id,
|
|
7441
|
+
label: s.name
|
|
7442
|
+
})),
|
|
7443
|
+
...filterValue === SOME_SPEAKERS ? [
|
|
7444
|
+
{
|
|
7445
|
+
value: SOME_SPEAKERS,
|
|
7446
|
+
label: labels.someSpeakers,
|
|
7447
|
+
disabled: true
|
|
7448
|
+
}
|
|
7449
|
+
] : []
|
|
7450
|
+
]
|
|
7451
|
+
}
|
|
7452
|
+
)
|
|
7453
|
+
] }),
|
|
7454
|
+
/* @__PURE__ */ jsx(
|
|
7455
|
+
TranscriptList,
|
|
7456
|
+
{
|
|
7457
|
+
utterances: shown,
|
|
7458
|
+
speakersById,
|
|
7459
|
+
activeId: active?.id ?? null,
|
|
7460
|
+
playingId,
|
|
7461
|
+
query,
|
|
7462
|
+
onPlay: playUtterance,
|
|
7463
|
+
onPause: pause,
|
|
7464
|
+
labels,
|
|
7465
|
+
emptyMessage: utterances.length === 0 ? labels.noTranscript : labels.noMatches
|
|
7466
|
+
},
|
|
7467
|
+
src ?? ""
|
|
7468
|
+
)
|
|
7469
|
+
]
|
|
7470
|
+
}
|
|
7471
|
+
),
|
|
7472
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
7473
|
+
/* @__PURE__ */ jsx(
|
|
7474
|
+
SpeakerPanel,
|
|
7475
|
+
{
|
|
7476
|
+
speakers,
|
|
7477
|
+
talkTime: talk,
|
|
7478
|
+
duration,
|
|
7479
|
+
hidden,
|
|
7480
|
+
onToggle: toggleSpeaker,
|
|
7481
|
+
overlapping,
|
|
7482
|
+
labels
|
|
7483
|
+
}
|
|
7484
|
+
),
|
|
7485
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground bg-muted/50 rounded-xl p-4 text-xs", children: labels.hint })
|
|
7486
|
+
] })
|
|
7487
|
+
] })
|
|
7488
|
+
]
|
|
7489
|
+
}
|
|
7490
|
+
);
|
|
7491
|
+
}
|
|
5854
7492
|
function normalizeString(value) {
|
|
5855
7493
|
return value.trim().replace(/\s+/g, " ").toLowerCase();
|
|
5856
7494
|
}
|
|
@@ -6096,12 +7734,12 @@ function ReconciliationProposalRow({
|
|
|
6096
7734
|
);
|
|
6097
7735
|
}
|
|
6098
7736
|
function relativeTimeLabel(date) {
|
|
6099
|
-
const
|
|
6100
|
-
if (
|
|
6101
|
-
if (
|
|
6102
|
-
if (
|
|
6103
|
-
if (
|
|
6104
|
-
if (
|
|
7737
|
+
const seconds2 = Math.max(0, Math.round((Date.now() - date.getTime()) / 1e3));
|
|
7738
|
+
if (seconds2 < 45) return "just now";
|
|
7739
|
+
if (seconds2 < 90) return "1 minute ago";
|
|
7740
|
+
if (seconds2 < 3600) return `${Math.round(seconds2 / 60)} minutes ago`;
|
|
7741
|
+
if (seconds2 < 5400) return "1 hour ago";
|
|
7742
|
+
if (seconds2 < 86400) return `${Math.round(seconds2 / 3600)} hours ago`;
|
|
6105
7743
|
return date.toLocaleString();
|
|
6106
7744
|
}
|
|
6107
7745
|
function SourcePill({ source }) {
|
|
@@ -14508,11 +16146,11 @@ function StatusPill({
|
|
|
14508
16146
|
}
|
|
14509
16147
|
);
|
|
14510
16148
|
}
|
|
14511
|
-
function CountdownDisplay({ seconds }) {
|
|
14512
|
-
if (
|
|
16149
|
+
function CountdownDisplay({ seconds: seconds2 }) {
|
|
16150
|
+
if (seconds2 <= 0) return null;
|
|
14513
16151
|
return /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
14514
16152
|
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 animate-ping rounded-full bg-green-500 opacity-25" }),
|
|
14515
|
-
/* @__PURE__ */ jsx("div", { className: "relative flex h-24 w-24 items-center justify-center rounded-full bg-green-500/90", children: /* @__PURE__ */ jsx("span", { className: "text-4xl font-bold text-white", children:
|
|
16153
|
+
/* @__PURE__ */ jsx("div", { className: "relative flex h-24 w-24 items-center justify-center rounded-full bg-green-500/90", children: /* @__PURE__ */ jsx("span", { className: "text-4xl font-bold text-white", children: seconds2 }) })
|
|
14516
16154
|
] }) });
|
|
14517
16155
|
}
|
|
14518
16156
|
function StabilityBar({
|
|
@@ -41320,6 +42958,6 @@ function WebsiteInputGroup({
|
|
|
41320
42958
|
}
|
|
41321
42959
|
WebsiteInputGroup.displayName = "WebsiteInputGroup";
|
|
41322
42960
|
|
|
41323
|
-
export { AIChat, AIChatModal, AIChatTrigger, AIReconciliationPanel, AccessDeniedPage, ActionButton2 as ActionButton, ActionButtonsBar, ActiveFilters, AddContactModal, AddServiceCard, AdditionalFields, Address, AddressCard, AddressCompact, AddressDisplay, AddressForm, AddressInline, AppHeader, AppHeaderActions, AppHeaderBrand, AppHeaderDivider, AppHeaderIconButton, AppHeaderSearch, AppHeaderSection, AppHeaderTitle, AppHeaderUserMenu, AuthButtons, AuthDialog, BUSINESS_HOURS_END_OF_DAY, BookAppointmentButton, BookingDialog, BusinessHours, BusinessHoursEditor, CSVColumnMapper, CSVFileUpload, CardSkeleton, CaseContextBar, CaseManagementHeader, CheckrIntegration, ClaimListingButton, ClaimProviderForm, CommandPalette, CommandPaletteProvider, CommandPaletteTrigger, CompactCookieBanner, CompactFilterBar, CompactHeader, CompactHours, CompactProviderHeader, ConnectionStatusBadge, ConnectionStatusBar, ConnectionStatusOverlay, ConsentSwitch, CookieConsentBanner, CopyrightText, CountBadge, CountryDropdown, CreateInvoiceModal, CreateReferralModal, DEFAULT_BUSINESS_HOURS_EDITOR_LABELS, DEFAULT_ERROR_CONFIGS, DEFAULT_LANGUAGES, DEFAULT_RADIUS_OPTIONS, DEFAULT_SERVICE_PRICING_MANAGER_LABELS, DEFAULT_SOCIAL_PROVIDERS, DOTBadge, DashboardWidget, DashboardWidgetActions, DashboardWidgetDataCards, DashboardWidgetInfo, DashboardWidgetTable, DialogOverlay, DisclaimerText, DockablePanel, DocumentDetectionOverlay, DocumentScanner, DropZone, DropzoneOverlay, EditUserRoleModal, EmployeeForm, EmployeeProfileCard, EmployerContactCard, EmployerList, EmployerPricingCard, EmployerServiceModal, EmployerView, ErrorPage, FileManager, FilePreview, FloatingAIChat, FloatingInput, FooterLinkSection, SocialMediaLinks2 as FooterSocialLinks, HRISProviderSelector, HandsFreeChat, HealthSurveillance, HelpSupportPanel, HeroSearchBar, HeyOzwell, HeyOzwellSelector, HeyOzwellToggle, HoursSummary, ImagingOrderEditor, InlineBookingForm, InventoryManager, InviteUserModal, InvoiceList, InvoicePaymentPage, InvoiceView, LabOrderEditor, LanguageSelector, LanguageSelectorInline, LanguageSelectorNative, LegalLinks, LoadingBar, LoadingDots, LoadingOverlay, LoadingPage, LoadingSkeleton, MODEL_MANIFEST, MaintenancePage, MobileBackButton, MobileMenuButton, MobileMenuPanel, ModelInfoList, NavLinks, NewsletterForm, NotFoundPage, NotificationCenter, OfflinePage, OnboardingCompletion, OnboardingStepQuestion, OnboardingWizard, OpenStatusBadge, OrderCard, OrderConfirmation, OrderConfirmationWizard, OrderDetailSidebar, OrderEditor, OrderList, OrderLookupForm, OrderSidebar, OrderSidebarTabs, OzwellChat, OzwellSettingsMenu, PageHeader, PatientHeader, PaymentHistoryTable, PaymentMethodBank, PaymentMethodCard, PaymentMethodList, PendingClaimsTable, PermissionsEditor, PillSelect, PresentingProblems, ProcedureOrderEditor, ProductVersion, ProductVersionBadge, Breadcrumb2 as ProviderBreadcrumb, ProviderCard, ProviderCardGrid, ProviderCardSkeleton, ProviderDetailHeader, ProviderDetailHeaderSkeleton, ProviderLogo2 as ProviderLogo, ProviderOverview, ProviderSearchBar, ProviderSearchFilters, ProviderSelector, ProviderSettings, SocialMediaLinks as ProviderSocialLinks, ProviderUsersTable, QuickBookCard, QuickLinksCard, RELEVANCE_LABELS, RecurringServiceAddCard, RecurringServiceCard, RecurringServiceGrid, RecurringServiceSetupModal, ReferralEditor, RejectionModal, ReportDashboard, ReportDatePicker, ReportLink, ReportTimeRange, ResultsEntryCard, ResultsEntryForm, ResultsEntryModal, SSOConfigForm, ScheduleCalendar, SearchResultsMessage, SelectedServicesBadges, ServerErrorPage, ServiceAccordion, ServiceBadge, ServiceBadgeGroup, ServiceCard, ServiceCategoryBadge, ServiceGeneralSettings, ServiceGrid, ServiceLink, ServiceList, ServiceMultiSelect, ServicePicker, ServicePricingManager, ServiceSelect, ServiceShippingSettings, ServiceTagCloud, ServiceTagCloudBadges, SetupServiceModal, Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarMobileToggle, SidebarNav, SidebarNavGroup, SidebarNavItem, SidebarProvider, SidebarSearch, SidebarToggle, SimpleFooter, SiteFooter, SiteHeader, SiteLogo, StepIndicator, StripeBadge, StripeSecureBadge, SuggestedActions, TableOfContents, TimelineEventList, TimelineProgress, Toast, ToastContainer, ToastProvider, UpdateAvailableOverlay, UserMenu, VerifiedBadge2 as VerifiedBadge, VisitScribe, VoiceManager, VoiceSetup, WEBSITE_TYPES, WebChartReportViewer, WebcamModal, WebsiteInput, WebsiteInputGroup, attributeSegments, centroid, chime, clusterEmbeddings, cosine, countBadgeVariants, countChipVariants, create24HourSchedule, createDefaultSchedule, createWeekdaySchedule, defaultCaseManagementHeaderLabels, defaultHeyOzwellSelectorLabels, defaultOrderTabs, defaultReconciliationIsEqual, formatAddressLines, formatAddressSingleLine, formatCityState, formatCityStateZip, generateId, getGoogleMapsSearchUrl, getGoogleMapsUrl, getWakeWarm, inferSpeakerRoles, isValidUrl, labelClusters, medicationToOrder, mergeTurns, normalizeClosingTime, openRollingRecorder, orderToMedication, parseTimeInput, panelVariants as reconciliationPanelVariants, subscribeWakeWarm, useCamera, useCommandPalette, useConnectionStatus, useCookieConsent, useDiarization, useDocumentDetection, useDropzone, useFileUpload, useHeyOzwell, useOptionalToast, useSidebar, useSpeakerVerify, useToast, useVisitScribe, useVoiceSetup, useWakeWord, warmWakeModels, widgetVariants };
|
|
42961
|
+
export { AIChat, AIChatModal, AIChatTrigger, AIReconciliationPanel, AccessDeniedPage, ActionButton2 as ActionButton, ActionButtonsBar, ActiveFilters, AddContactModal, AddServiceCard, AdditionalFields, Address, AddressCard, AddressCompact, AddressDisplay, AddressForm, AddressInline, AppHeader, AppHeaderActions, AppHeaderBrand, AppHeaderDivider, AppHeaderIconButton, AppHeaderSearch, AppHeaderSection, AppHeaderTitle, AppHeaderUserMenu, AuthButtons, AuthDialog, BUSINESS_HOURS_END_OF_DAY, BookAppointmentButton, BookingDialog, BusinessHours, BusinessHoursEditor, CSVColumnMapper, CSVFileUpload, CardSkeleton, CaseContextBar, CaseManagementHeader, CheckrIntegration, ClaimListingButton, ClaimProviderForm, CommandPalette, CommandPaletteProvider, CommandPaletteTrigger, CompactCookieBanner, CompactFilterBar, CompactHeader, CompactHours, CompactProviderHeader, ConnectionStatusBadge, ConnectionStatusBar, ConnectionStatusOverlay, ConsentSwitch, CookieConsentBanner, CopyrightText, CountBadge, CountryDropdown, CreateInvoiceModal, CreateReferralModal, DEFAULT_BUSINESS_HOURS_EDITOR_LABELS, DEFAULT_ERROR_CONFIGS, DEFAULT_LANGUAGES, DEFAULT_RADIUS_OPTIONS, DEFAULT_SERVICE_PRICING_MANAGER_LABELS, DEFAULT_SOCIAL_PROVIDERS, DEFAULT_TRANSCRIPT_PLAYER_LABELS, DOTBadge, DashboardWidget, DashboardWidgetActions, DashboardWidgetDataCards, DashboardWidgetInfo, DashboardWidgetTable, DialogOverlay, DisclaimerText, DockablePanel, DocumentDetectionOverlay, DocumentScanner, DropZone, DropzoneOverlay, EditUserRoleModal, EmployeeForm, EmployeeProfileCard, EmployerContactCard, EmployerList, EmployerPricingCard, EmployerServiceModal, EmployerView, ErrorPage, FileManager, FilePreview, FloatingAIChat, FloatingInput, FooterLinkSection, SocialMediaLinks2 as FooterSocialLinks, HRISProviderSelector, HandsFreeChat, HealthSurveillance, HelpSupportPanel, HeroSearchBar, HeyOzwell, HeyOzwellSelector, HeyOzwellToggle, HoursSummary, ImagingOrderEditor, InlineBookingForm, InventoryManager, InviteUserModal, InvoiceList, InvoicePaymentPage, InvoiceView, LabOrderEditor, LanguageSelector, LanguageSelectorInline, LanguageSelectorNative, LegalLinks, LoadingBar, LoadingDots, LoadingOverlay, LoadingPage, LoadingSkeleton, MODEL_MANIFEST, MaintenancePage, MobileBackButton, MobileMenuButton, MobileMenuPanel, ModelInfoList, NavLinks, NewsletterForm, NotFoundPage, NotificationCenter, OfflinePage, OnboardingCompletion, OnboardingStepQuestion, OnboardingWizard, OpenStatusBadge, OrderCard, OrderConfirmation, OrderConfirmationWizard, OrderDetailSidebar, OrderEditor, OrderList, OrderLookupForm, OrderSidebar, OrderSidebarTabs, OzwellChat, OzwellSettingsMenu, PageHeader, PatientHeader, PaymentHistoryTable, PaymentMethodBank, PaymentMethodCard, PaymentMethodList, PendingClaimsTable, PermissionsEditor, PillSelect, PresentingProblems, ProcedureOrderEditor, ProductVersion, ProductVersionBadge, Breadcrumb2 as ProviderBreadcrumb, ProviderCard, ProviderCardGrid, ProviderCardSkeleton, ProviderDetailHeader, ProviderDetailHeaderSkeleton, ProviderLogo2 as ProviderLogo, ProviderOverview, ProviderSearchBar, ProviderSearchFilters, ProviderSelector, ProviderSettings, SocialMediaLinks as ProviderSocialLinks, ProviderUsersTable, QuickBookCard, QuickLinksCard, RELEVANCE_LABELS, RecurringServiceAddCard, RecurringServiceCard, RecurringServiceGrid, RecurringServiceSetupModal, ReferralEditor, RejectionModal, ReportDashboard, ReportDatePicker, ReportLink, ReportTimeRange, ResultsEntryCard, ResultsEntryForm, ResultsEntryModal, SSOConfigForm, ScheduleCalendar, SearchResultsMessage, SelectedServicesBadges, ServerErrorPage, ServiceAccordion, ServiceBadge, ServiceBadgeGroup, ServiceCard, ServiceCategoryBadge, ServiceGeneralSettings, ServiceGrid, ServiceLink, ServiceList, ServiceMultiSelect, ServicePicker, ServicePricingManager, ServiceSelect, ServiceShippingSettings, ServiceTagCloud, ServiceTagCloudBadges, SetupServiceModal, Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarMobileToggle, SidebarNav, SidebarNavGroup, SidebarNavItem, SidebarProvider, SidebarSearch, SidebarToggle, SimpleFooter, SiteFooter, SiteHeader, SiteLogo, StepIndicator, StripeBadge, StripeSecureBadge, SuggestedActions, TableOfContents, TimelineEventList, TimelineProgress, Toast, ToastContainer, ToastProvider, TranscriptPlayer, UpdateAvailableOverlay, UserMenu, VerifiedBadge2 as VerifiedBadge, VisitScribe, VoiceManager, VoiceSetup, WEBSITE_TYPES, WebChartReportViewer, WebcamModal, WebsiteInput, WebsiteInputGroup, attributeSegments, centroid, chime, clusterEmbeddings, computePeaks, cosine, countBadgeVariants, countChipVariants, create24HourSchedule, createDefaultSchedule, createWeekdaySchedule, defaultCaseManagementHeaderLabels, defaultHeyOzwellSelectorLabels, defaultOrderTabs, defaultReconciliationIsEqual, formatAddressLines, formatAddressSingleLine, formatCityState, formatCityStateZip, generateId, getGoogleMapsSearchUrl, getGoogleMapsUrl, getWakeWarm, inferSpeakerRoles, isValidUrl, labelClusters, medicationToOrder, mergeTurns, normalizeClosingTime, openRollingRecorder, orderToMedication, parseTimeInput, panelVariants as reconciliationPanelVariants, subscribeWakeWarm, useCamera, useCommandPalette, useConnectionStatus, useCookieConsent, useDiarization, useDocumentDetection, useDropzone, useFileUpload, useHeyOzwell, useOptionalToast, useSidebar, useSpeakerVerify, useToast, useVisitScribe, useVoiceSetup, useWakeWord, warmWakeModels, widgetVariants };
|
|
41324
42962
|
//# sourceMappingURL=index.js.map
|
|
41325
42963
|
//# sourceMappingURL=index.js.map
|