@bikdotai/bik-component-library 0.0.838-beta.6 → 0.0.838

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/cjs/components/WhatsAppTextEditor/WhatsAppTextEditor.js +23 -23
  2. package/dist/cjs/components/WhatsAppTextEditor/WhatsAppTextEditor.js.map +1 -1
  3. package/dist/cjs/components/agent-builder/components/AiTextArea.js +1 -1
  4. package/dist/cjs/components/agent-builder/components/AiTextArea.js.map +1 -1
  5. package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js +2 -2
  6. package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
  7. package/dist/cjs/components/bik-chatbot/components/ChatWindow.js +20 -20
  8. package/dist/cjs/components/bik-chatbot/components/ChatWindow.js.map +1 -1
  9. package/dist/cjs/components/input/ChipInput.js +1 -1
  10. package/dist/cjs/components/input/ChipInput.js.map +1 -1
  11. package/dist/cjs/components/input/Input-helper.js +1 -1
  12. package/dist/cjs/components/input/Input-helper.js.map +1 -1
  13. package/dist/cjs/components/input/Input.js +1 -1
  14. package/dist/cjs/components/input/Input.js.map +1 -1
  15. package/dist/cjs/components/plans/SubscriptionPlanSelector.js +5 -5
  16. package/dist/cjs/components/plans/SubscriptionPlanSelector.js.map +1 -1
  17. package/dist/cjs/editor/BikEditor.js +1 -1
  18. package/dist/cjs/editor/BikEditor.js.map +1 -1
  19. package/dist/cjs/editor/BikEditor.utils.js +3 -3
  20. package/dist/cjs/editor/BikEditor.utils.js.map +1 -1
  21. package/dist/cjs/editor/extensions/buildExtensions.js +2 -2
  22. package/dist/cjs/editor/extensions/buildExtensions.js.map +1 -1
  23. package/dist/cjs/icons/Informational/General/HourglassFilled.js +2 -0
  24. package/dist/cjs/icons/Informational/General/HourglassFilled.js.map +1 -0
  25. package/dist/cjs/icons/index.js +1 -1
  26. package/dist/cjs/index.js +1 -1
  27. package/dist/esm/components/WhatsAppTextEditor/WhatsAppTextEditor.js +143 -144
  28. package/dist/esm/components/WhatsAppTextEditor/WhatsAppTextEditor.js.map +1 -1
  29. package/dist/esm/components/agent-builder/components/AiTextArea.js +23 -24
  30. package/dist/esm/components/agent-builder/components/AiTextArea.js.map +1 -1
  31. package/dist/esm/components/agent-builder/components/ToolInstructionsField.js +30 -31
  32. package/dist/esm/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
  33. package/dist/esm/components/bik-chatbot/components/ChatWindow.js +53 -54
  34. package/dist/esm/components/bik-chatbot/components/ChatWindow.js.map +1 -1
  35. package/dist/esm/components/input/ChipInput.js +40 -41
  36. package/dist/esm/components/input/ChipInput.js.map +1 -1
  37. package/dist/esm/components/input/Input-helper.d.ts +0 -7
  38. package/dist/esm/components/input/Input-helper.js +25 -16
  39. package/dist/esm/components/input/Input-helper.js.map +1 -1
  40. package/dist/esm/components/input/Input.js +58 -60
  41. package/dist/esm/components/input/Input.js.map +1 -1
  42. package/dist/esm/components/input/Input.model.d.ts +0 -1
  43. package/dist/esm/components/plans/SubscriptionPlanSelector.js +40 -42
  44. package/dist/esm/components/plans/SubscriptionPlanSelector.js.map +1 -1
  45. package/dist/esm/editor/BikEditor.js +118 -122
  46. package/dist/esm/editor/BikEditor.js.map +1 -1
  47. package/dist/esm/editor/BikEditor.utils.d.ts +1 -1
  48. package/dist/esm/editor/BikEditor.utils.js +140 -141
  49. package/dist/esm/editor/BikEditor.utils.js.map +1 -1
  50. package/dist/esm/editor/extensions/buildExtensions.js +39 -49
  51. package/dist/esm/editor/extensions/buildExtensions.js.map +1 -1
  52. package/dist/esm/helpers/index.d.ts +0 -1
  53. package/dist/esm/icons/Informational/General/HourglassFilled.d.ts +7 -0
  54. package/dist/esm/icons/Informational/General/HourglassFilled.js +33 -0
  55. package/dist/esm/icons/Informational/General/HourglassFilled.js.map +1 -0
  56. package/dist/esm/icons/Informational/General/index.d.ts +1 -0
  57. package/dist/esm/icons/Media/Visual/index.d.ts +0 -2
  58. package/dist/esm/icons/index.d.ts +25 -25
  59. package/dist/esm/icons/index.js +416 -418
  60. package/dist/esm/icons/index.js.map +1 -1
  61. package/dist/esm/index.js +114 -124
  62. package/dist/esm/index.js.map +1 -1
  63. package/package.json +1 -2
  64. package/dist/cjs/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js +0 -2
  65. package/dist/cjs/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js.map +0 -1
  66. package/dist/cjs/helpers/sanitize.js +0 -2
  67. package/dist/cjs/helpers/sanitize.js.map +0 -1
  68. package/dist/cjs/icons/Media/Visual/FormkitNeutral.js +0 -2
  69. package/dist/cjs/icons/Media/Visual/FormkitNeutral.js.map +0 -1
  70. package/dist/cjs/icons/Media/Visual/FormkitSad.js +0 -2
  71. package/dist/cjs/icons/Media/Visual/FormkitSad.js.map +0 -1
  72. package/dist/esm/editor/extensions/htmlTagStrip/HtmlTagStripExtension.d.ts +0 -13
  73. package/dist/esm/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js +0 -64
  74. package/dist/esm/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js.map +0 -1
  75. package/dist/esm/helpers/sanitize.d.ts +0 -32
  76. package/dist/esm/helpers/sanitize.js +0 -204
  77. package/dist/esm/helpers/sanitize.js.map +0 -1
  78. package/dist/esm/icons/Media/Visual/FormkitNeutral.js +0 -58
  79. package/dist/esm/icons/Media/Visual/FormkitNeutral.js.map +0 -1
  80. package/dist/esm/icons/Media/Visual/FormkitSad.js +0 -61
  81. package/dist/esm/icons/Media/Visual/FormkitSad.js.map +0 -1
@@ -1,12 +1,12 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),d=require("react"),h=require("../../assets/icons/check.svg.js"),m=require("../../assets/icons/info.svg.js"),g=require("../../assets/icons/phone.svg.js"),b=require("../../helpers/sanitize.js"),y=require("styled-components"),f=require("./SubscriptionPlan.js"),n=require("../../constants/Theme.js"),i=require("../TypographyStyle.js"),j=require("../modals/styledModal.js"),C=require("../tabs/Tabs.js"),v=require("../button/Button.js"),w=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},s=w(y),O=s.default.div`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),a=require("react"),x=require("../../assets/icons/check.svg.js"),h=require("../../assets/icons/info.svg.js"),g=require("../../assets/icons/phone.svg.js"),m=require("styled-components"),b=require("./SubscriptionPlan.js"),n=require("../../constants/Theme.js"),o=require("../TypographyStyle.js"),y=require("../modals/styledModal.js"),f=require("../tabs/Tabs.js"),j=require("../button/Button.js"),C=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},s=C(m),v=s.default.div`
2
2
  display: flex;
3
3
  column-gap: 22px;
4
4
  align-items: stretch;
5
5
  padding: 24px;
6
- `,P=s.default.div`
6
+ `,w=s.default.div`
7
7
  color: ${n.COLORS.content.negative};
8
8
  padding: 0px 24px;
9
- `,c=s.default.div`
9
+ `,d=s.default.div`
10
10
  padding: 24px 24px 0px 24px;
11
11
  display: flex;
12
12
  align-items: center;
@@ -15,7 +15,7 @@
15
15
  margin-top: 8px;
16
16
  color: ${n.COLORS.content.secondary} !important;
17
17
  }
18
- `,l=s.default.div`
18
+ `,c=s.default.div`
19
19
  padding: 0px 24px 24px 24px;
20
20
  display: flex;
21
21
  align-items: center;
@@ -98,5 +98,5 @@
98
98
  justify-content: flex-start;
99
99
  gap: 8px;
100
100
  }
101
- `,u=[{key:"Monthly",title:"Monthly"},{key:"yearly",title:"Yearly"}],S=e=>{const[p,r]=d.useState(e.discountInputProperties?.defaultValue),x=e.staticWidthMultiplier?e.staticWidthMultiplier:275;return t.jsxs(j.StyledModal,{centralContainerStyles:{width:e.plans.length*x},open:!0,closeOnOutsideClick:!0,onClose:e.onClose,children:[t.jsxs(c,{children:[t.jsxs("div",{children:[t.jsx(i.TitleMedium,{children:e.header||"Select a plan to proceed"}),t.jsx(i.BodyPrimary,{className:"sub--header",children:e.subHeader||""})]}),e.showMonthlyTabs?t.jsx(C.Tabs,{tabs:e.tabProperties&&e.tabProperties.tabs?e.tabProperties.tabs:u,onTabSelected:o=>e.tabProperties?.onTabSelected?e.tabProperties?.onTabSelected(o):"",isSquared:!0}):t.jsx(t.Fragment,{})]}),e.warningDescription&&t.jsx(P,{children:e.warningDescription}),t.jsx(O,{children:e.plans.map(o=>d.createElement(f.SubscriptionPlan,{...o,showMonthly:!0,showMonthlyOptions:e.showMonthlyOptions||!1,showTrialOptions:e.showTrialOptions||!1,onPlanSelect:e.onPlanSelect,key:o.planName}))}),(e.showCouponApplicationCode||e.showBookAdemo)&&t.jsxs(l,{children:[t.jsx("div",{children:e.showCouponApplicationCode&&t.jsxs("div",{className:"coupon-code",children:[t.jsxs("div",{className:"coupon-input",children:[t.jsx(i.BodyPrimary,{style:{color:e.discountInputProperties?.errorMessage?n.COLORS.content.negative:""},children:"Apply coupon code"}),t.jsxs("div",{className:"button--wrapper",children:[t.jsxs("div",{className:e.discountInputProperties?.errorMessage?"error--border dotted--border":"dotted--border",children:[t.jsx("input",{className:"input--class",onChange:o=>{const a=b.stripHtmlTags(o.target.value);r(a),e.discountInputProperties?.onChangeText(a)},value:p,placeholder:"eg:PLAN20",disabled:e.discountInputProperties?.isLoading}),e.discountInputProperties?.successText&&t.jsxs("div",{className:"success--inside--chip",children:[t.jsx(h.default,{height:16,width:16,color:n.COLORS.content.primaryInverse}),t.jsx(i.BodyCaption,{style:{color:n.COLORS.content.primaryInverse},children:"Coupon applied"})]})]}),!e.discountInputProperties?.successText&&t.jsx(v.Button,{buttonText:"Apply",buttonType:"primary",onClick:e?.discountInputProperties?.onCouponApply,isLoading:e.discountInputProperties?.isLoading})]}),e.discountInputProperties?.errorMessage&&t.jsxs("div",{className:"d-flex",style:{gap:8},children:[t.jsx(m.default,{height:16,width:16,color:n.COLORS.content.negative}),t.jsx(i.BodyCaption,{style:{color:n.COLORS.content.negative},children:e.discountInputProperties?.errorMessage??"Enter a valid code"})]}),e.discountInputProperties?.showRemoveCoupon&&t.jsx("div",{className:"demo--input",onClick:()=>{r(""),e.discountInputProperties?.removeCoupon&&e.discountInputProperties?.removeCoupon()},children:"Remove coupon"})]}),e.discountInputProperties?.successText&&t.jsx("div",{className:"coupon--success--chip",children:t.jsx(i.BodyCaption,{style:{color:"#00580E",maxWidth:180},children:e.discountInputProperties?.successText})})]})}),e.showBookAdemo&&t.jsxs("div",{className:"demo--wrapper",children:[t.jsx("div",{className:"demo--phone",children:t.jsx(g.default,{height:16,width:16,color:n.COLORS.background.brand})}),t.jsx(i.BodyPrimary,{className:"demo--input",onClick:()=>e.demoLink?window.open(e.demoLink,"_blank"):e.onClickingBookADemo?e.onClickingBookADemo():"",children:"Book a demo with the team"})]})]})]})};exports.BottomWrapper=l;exports.HeaderWrapper=c;exports.SubscriptionPlanSelector=S;exports.defaultTabs=u;
101
+ `,l=[{key:"Monthly",title:"Monthly"},{key:"yearly",title:"Yearly"}],O=e=>{const[u,r]=a.useState(e.discountInputProperties?.defaultValue),p=e.staticWidthMultiplier?e.staticWidthMultiplier:275;return t.jsxs(y.StyledModal,{centralContainerStyles:{width:e.plans.length*p},open:!0,closeOnOutsideClick:!0,onClose:e.onClose,children:[t.jsxs(d,{children:[t.jsxs("div",{children:[t.jsx(o.TitleMedium,{children:e.header||"Select a plan to proceed"}),t.jsx(o.BodyPrimary,{className:"sub--header",children:e.subHeader||""})]}),e.showMonthlyTabs?t.jsx(f.Tabs,{tabs:e.tabProperties&&e.tabProperties.tabs?e.tabProperties.tabs:l,onTabSelected:i=>e.tabProperties?.onTabSelected?e.tabProperties?.onTabSelected(i):"",isSquared:!0}):t.jsx(t.Fragment,{})]}),e.warningDescription&&t.jsx(w,{children:e.warningDescription}),t.jsx(v,{children:e.plans.map(i=>a.createElement(b.SubscriptionPlan,{...i,showMonthly:!0,showMonthlyOptions:e.showMonthlyOptions||!1,showTrialOptions:e.showTrialOptions||!1,onPlanSelect:e.onPlanSelect,key:i.planName}))}),(e.showCouponApplicationCode||e.showBookAdemo)&&t.jsxs(c,{children:[t.jsx("div",{children:e.showCouponApplicationCode&&t.jsxs("div",{className:"coupon-code",children:[t.jsxs("div",{className:"coupon-input",children:[t.jsx(o.BodyPrimary,{style:{color:e.discountInputProperties?.errorMessage?n.COLORS.content.negative:""},children:"Apply coupon code"}),t.jsxs("div",{className:"button--wrapper",children:[t.jsxs("div",{className:e.discountInputProperties?.errorMessage?"error--border dotted--border":"dotted--border",children:[t.jsx("input",{className:"input--class",onChange:i=>{r(i.target.value),e.discountInputProperties?.onChangeText(i.target.value)},value:u,placeholder:"eg:PLAN20",disabled:e.discountInputProperties?.isLoading}),e.discountInputProperties?.successText&&t.jsxs("div",{className:"success--inside--chip",children:[t.jsx(x.default,{height:16,width:16,color:n.COLORS.content.primaryInverse}),t.jsx(o.BodyCaption,{style:{color:n.COLORS.content.primaryInverse},children:"Coupon applied"})]})]}),!e.discountInputProperties?.successText&&t.jsx(j.Button,{buttonText:"Apply",buttonType:"primary",onClick:e?.discountInputProperties?.onCouponApply,isLoading:e.discountInputProperties?.isLoading})]}),e.discountInputProperties?.errorMessage&&t.jsxs("div",{className:"d-flex",style:{gap:8},children:[t.jsx(h.default,{height:16,width:16,color:n.COLORS.content.negative}),t.jsx(o.BodyCaption,{style:{color:n.COLORS.content.negative},children:e.discountInputProperties?.errorMessage??"Enter a valid code"})]}),e.discountInputProperties?.showRemoveCoupon&&t.jsx("div",{className:"demo--input",onClick:()=>{r(""),e.discountInputProperties?.removeCoupon&&e.discountInputProperties?.removeCoupon()},children:"Remove coupon"})]}),e.discountInputProperties?.successText&&t.jsx("div",{className:"coupon--success--chip",children:t.jsx(o.BodyCaption,{style:{color:"#00580E",maxWidth:180},children:e.discountInputProperties?.successText})})]})}),e.showBookAdemo&&t.jsxs("div",{className:"demo--wrapper",children:[t.jsx("div",{className:"demo--phone",children:t.jsx(g.default,{height:16,width:16,color:n.COLORS.background.brand})}),t.jsx(o.BodyPrimary,{className:"demo--input",onClick:()=>e.demoLink?window.open(e.demoLink,"_blank"):e.onClickingBookADemo?e.onClickingBookADemo():"",children:"Book a demo with the team"})]})]})]})};exports.BottomWrapper=c;exports.HeaderWrapper=d;exports.SubscriptionPlanSelector=O;exports.defaultTabs=l;
102
102
  //# sourceMappingURL=SubscriptionPlanSelector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionPlanSelector.js","sources":["../../../../src/components/plans/SubscriptionPlanSelector.tsx"],"sourcesContent":["import Check from '@src/assets/icons/check.svg';\nimport Info from '@src/assets/icons/info.svg';\nimport PhoneIcon from '@src/assets/icons/phone.svg';\nimport { stripHtmlTags } from '@src/helpers/sanitize';\nimport { FunctionComponent, useState } from 'react';\nimport styled from 'styled-components';\nimport { StyledModal } from '@src/components/modals';\nimport {\n\tSubscriptionPlan,\n\tSubscriptionPlanProps,\n} from '@src/components/plans/SubscriptionPlan';\nimport { COLORS } from '@src/constants/Theme';\nimport { Button } from '../button';\nimport { Tabs } from '../tabs';\nimport { TabViewHeaderProps } from '../tabs/Tabs.model';\nimport { BodyCaption, BodyPrimary, TitleMedium } from '../TypographyStyle';\n\ntype Props = {\n\tplans: SubscriptionPlanProps[];\n\tonPlanSelect: (code: string) => void;\n\tonClose: () => void;\n\tsubHeader?: string;\n\twarningDescription?: string;\n\tshowTrialOptions?: boolean;\n\theader?: string;\n\tshowMonthlyOptions?: boolean;\n\tshowMonthlyTabs?: boolean;\n\tstaticWidthMultiplier?: number;\n\ttabProperties?: TabViewHeaderProps;\n\tshowCouponApplicationCode?: boolean;\n\tdiscountInputProperties?: {\n\t\terrorMessage?: string;\n\t\tsuccessText?: string;\n\t\tdefaultValue?: string;\n\t\tshowRemoveCoupon?: boolean;\n\t\tonChangeText: (text: string) => void;\n\t\tremoveCoupon?: () => void;\n\t\tonCouponApply?: () => void;\n\t\tisLoading?: boolean;\n\t};\n\tshowBookAdemo?: boolean;\n\tdemoLink?: string;\n\tonClickingBookADemo?: () => void;\n};\n\nconst PlanWrapper = styled.div`\n\tdisplay: flex;\n\tcolumn-gap: 22px;\n\talign-items: stretch;\n\tpadding: 24px;\n`;\n\nconst Warning = styled.div`\n\tcolor: ${COLORS.content.negative};\n\tpadding: 0px 24px;\n`;\nexport const HeaderWrapper = styled.div`\n\tpadding: 24px 24px 0px 24px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\t.sub--header {\n\t\tmargin-top: 8px;\n\t\tcolor: ${COLORS.content.secondary} !important;\n\t}\n`;\nexport const BottomWrapper = styled.div`\n\tpadding: 0px 24px 24px 24px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tflex-wrap: wrap;\n\tgap: 8px;\n\t.coupon-code {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: flex-start;\n\t\tgap: 8px;\n\t}\n\t.coupon--success--chip {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tpadding: 4px 8px;\n\t\tborder-radius: 4px;\n\t\tborder: 1px solid #c3e4c4;\n\t\tbackground: #e6f4e7;\n\t}\n\t.coupon-input {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tgap: 8px;\n\t}\n\t.dotted--border {\n\t\tborder: 1px dotted #e0e0e0;\n\t\tpadding: 8px 8px 8px 16px;\n\t\tmin-width: 10%;\n\t\tborder-radius: 4px;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t}\n\t.error--border {\n\t\tborder: 1px dotted ${COLORS.content.negative} !important;\n\t}\n\t.input--class {\n\t\tborder: none;\n\t\t:active,\n\t\t:focus {\n\t\t\tborder: none;\n\t\t\toutline: none;\n\t\t}\n\t}\n\t.success--inside--chip {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tpadding: 4px 8px;\n\t\talign-items: center;\n\t\tgap: 6px;\n\t\tborder-radius: 4px;\n\t\tbackground: ${COLORS.background.positive.vibrant};\n\t}\n\t.demo--wrapper {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tgap: 8px;\n\t}\n\t.demo--input {\n\t\tcolor: ${COLORS.background.brand};\n\t\tborder-bottom: 1px solid ${COLORS.background.brand};\n\t\twidth: fit-content;\n\t\tcursor: pointer;\n\t}\n\t.demo--phone {\n\t\tdisplay: flex;\n\t\tpadding: 8px;\n\t\talign-items: center;\n\t\tgap: 10px;\n\t\tborder-radius: 50%;\n\t\tbackground-color: ${COLORS.background.brandLight};\n\t}\n\t.button--wrapper {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: flex-start;\n\t\tgap: 8px;\n\t}\n`;\n\nexport const defaultTabs = [\n\t{ key: 'Monthly', title: 'Monthly' },\n\t{ key: 'yearly', title: 'Yearly' },\n];\n\n// Selected plan to have chosen plan not selectable\n\nexport const SubscriptionPlanSelector: FunctionComponent<Props> = (props) => {\n\tconst [inputValue, setInputValue] = useState(\n\t\tprops.discountInputProperties?.defaultValue,\n\t);\n\tconst eachCardWidth = props.staticWidthMultiplier\n\t\t? props.staticWidthMultiplier\n\t\t: 275;\n\treturn (\n\t\t<StyledModal\n\t\t\tcentralContainerStyles={{\n\t\t\t\twidth: props.plans.length * eachCardWidth,\n\t\t\t}}\n\t\t\topen={true}\n\t\t\tcloseOnOutsideClick={true}\n\t\t\tonClose={props.onClose}\n\t\t>\n\t\t\t<HeaderWrapper>\n\t\t\t\t<div>\n\t\t\t\t\t<TitleMedium>\n\t\t\t\t\t\t{props.header || 'Select a plan to proceed'}\n\t\t\t\t\t</TitleMedium>\n\t\t\t\t\t<BodyPrimary className=\"sub--header\">\n\t\t\t\t\t\t{props.subHeader || ''}\n\t\t\t\t\t</BodyPrimary>\n\t\t\t\t</div>\n\t\t\t\t{props.showMonthlyTabs ? (\n\t\t\t\t\t<Tabs\n\t\t\t\t\t\ttabs={\n\t\t\t\t\t\t\tprops.tabProperties && props.tabProperties.tabs\n\t\t\t\t\t\t\t\t? props.tabProperties.tabs\n\t\t\t\t\t\t\t\t: defaultTabs\n\t\t\t\t\t\t}\n\t\t\t\t\t\tonTabSelected={(selectedTab) =>\n\t\t\t\t\t\t\tprops.tabProperties?.onTabSelected\n\t\t\t\t\t\t\t\t? props.tabProperties?.onTabSelected(selectedTab)\n\t\t\t\t\t\t\t\t: ''\n\t\t\t\t\t\t}\n\t\t\t\t\t\tisSquared\n\t\t\t\t\t></Tabs>\n\t\t\t\t) : (\n\t\t\t\t\t<></>\n\t\t\t\t)}\n\t\t\t</HeaderWrapper>\n\t\t\t{props.warningDescription && (\n\t\t\t\t<Warning>{props.warningDescription}</Warning>\n\t\t\t)}\n\t\t\t{/*<DurationSelector*/}\n\t\t\t{/*\tisMonthlySelected={monthly}*/}\n\t\t\t{/*\tyearlyDiscount={\"20\"}*/}\n\t\t\t{/*\tonToggle={setIsMonthly}*/}\n\t\t\t{/*/>*/}\n\t\t\t<PlanWrapper>\n\t\t\t\t{props.plans.map((prop) => {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<SubscriptionPlan\n\t\t\t\t\t\t\t{...prop}\n\t\t\t\t\t\t\tshowMonthly={true}\n\t\t\t\t\t\t\tshowMonthlyOptions={props.showMonthlyOptions || false}\n\t\t\t\t\t\t\tshowTrialOptions={props.showTrialOptions || false}\n\t\t\t\t\t\t\tonPlanSelect={props.onPlanSelect}\n\t\t\t\t\t\t\tkey={prop.planName}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</PlanWrapper>\n\t\t\t{(props.showCouponApplicationCode || props.showBookAdemo) && (\n\t\t\t\t<BottomWrapper>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{props.showCouponApplicationCode && (\n\t\t\t\t\t\t\t<div className=\"coupon-code\">\n\t\t\t\t\t\t\t\t<div className=\"coupon-input\">\n\t\t\t\t\t\t\t\t\t<BodyPrimary\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tcolor: props.discountInputProperties?.errorMessage\n\t\t\t\t\t\t\t\t\t\t\t\t? COLORS.content.negative\n\t\t\t\t\t\t\t\t\t\t\t\t: '',\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tApply coupon code\n\t\t\t\t\t\t\t\t\t</BodyPrimary>\n\t\t\t\t\t\t\t\t\t<div className=\"button--wrapper\">\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\t\t\tprops.discountInputProperties?.errorMessage\n\t\t\t\t\t\t\t\t\t\t\t\t\t? 'error--border dotted--border'\n\t\t\t\t\t\t\t\t\t\t\t\t\t: 'dotted--border'\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"input--class\"\n\t\t\t\t\t\t\t\t\t\t\t\tonChange={(text) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tconst sanitized = stripHtmlTags(text.target.value);\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetInputValue(sanitized);\n\t\t\t\t\t\t\t\t\t\t\t\t\tprops.discountInputProperties?.onChangeText(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsanitized,\n\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\tvalue={inputValue}\n\t\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"eg:PLAN20\"\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled={props.discountInputProperties?.isLoading}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t{props.discountInputProperties?.successText && (\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"success--inside--chip\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Check\n\t\t\t\t\t\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.primaryInverse}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<BodyCaption\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tstyle={{ color: COLORS.content.primaryInverse }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tCoupon applied\n\t\t\t\t\t\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{!props.discountInputProperties?.successText && (\n\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\tbuttonText=\"Apply\"\n\t\t\t\t\t\t\t\t\t\t\t\tbuttonType=\"primary\"\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={props?.discountInputProperties?.onCouponApply}\n\t\t\t\t\t\t\t\t\t\t\t\tisLoading={props.discountInputProperties?.isLoading}\n\t\t\t\t\t\t\t\t\t\t\t></Button>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t{props.discountInputProperties?.errorMessage && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"d-flex\" style={{ gap: 8 }}>\n\t\t\t\t\t\t\t\t\t\t\t<Info\n\t\t\t\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.negative}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t<BodyCaption style={{ color: COLORS.content.negative }}>\n\t\t\t\t\t\t\t\t\t\t\t\t{props.discountInputProperties?.errorMessage ??\n\t\t\t\t\t\t\t\t\t\t\t\t\t'Enter a valid code'}\n\t\t\t\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{props.discountInputProperties?.showRemoveCoupon && (\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"demo--input\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tsetInputValue('');\n\t\t\t\t\t\t\t\t\t\t\t\tprops.discountInputProperties?.removeCoupon\n\t\t\t\t\t\t\t\t\t\t\t\t\t? props.discountInputProperties?.removeCoupon()\n\t\t\t\t\t\t\t\t\t\t\t\t\t: '';\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tRemove coupon\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t{props.discountInputProperties?.successText && (\n\t\t\t\t\t\t\t\t\t<div className=\"coupon--success--chip\">\n\t\t\t\t\t\t\t\t\t\t<BodyCaption style={{ color: '#00580E', maxWidth: 180 }}>\n\t\t\t\t\t\t\t\t\t\t\t{props.discountInputProperties?.successText}\n\t\t\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t{props.showBookAdemo && (\n\t\t\t\t\t\t<div className=\"demo--wrapper\">\n\t\t\t\t\t\t\t<div className=\"demo--phone\">\n\t\t\t\t\t\t\t\t<PhoneIcon\n\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\tcolor={COLORS.background.brand}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<BodyPrimary\n\t\t\t\t\t\t\t\tclassName=\"demo--input\"\n\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\tprops.demoLink\n\t\t\t\t\t\t\t\t\t\t? window.open(props.demoLink, '_blank')\n\t\t\t\t\t\t\t\t\t\t: props.onClickingBookADemo\n\t\t\t\t\t\t\t\t\t\t? props.onClickingBookADemo()\n\t\t\t\t\t\t\t\t\t\t: ''\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tBook a demo with the team\n\t\t\t\t\t\t\t</BodyPrimary>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</BottomWrapper>\n\t\t\t)}\n\t\t</StyledModal>\n\t);\n};\n"],"names":["PlanWrapper","styled","Warning","COLORS","HeaderWrapper","BottomWrapper","defaultTabs","SubscriptionPlanSelector","props","inputValue","setInputValue","useState","eachCardWidth","jsxs","StyledModal","jsx","TitleMedium","BodyPrimary","Tabs","selectedTab","Fragment","prop","createElement","SubscriptionPlan","text","sanitized","stripHtmlTags","Check","BodyCaption","Button","Info","PhoneIcon"],"mappings":"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"}
1
+ {"version":3,"file":"SubscriptionPlanSelector.js","sources":["../../../../src/components/plans/SubscriptionPlanSelector.tsx"],"sourcesContent":["import Check from '@src/assets/icons/check.svg';\nimport Info from '@src/assets/icons/info.svg';\nimport PhoneIcon from '@src/assets/icons/phone.svg';\nimport { FunctionComponent, useState } from 'react';\nimport styled from 'styled-components';\nimport { StyledModal } from '@src/components/modals';\nimport {\n\tSubscriptionPlan,\n\tSubscriptionPlanProps,\n} from '@src/components/plans/SubscriptionPlan';\nimport { COLORS } from '@src/constants/Theme';\nimport { Button } from '../button';\nimport { Tabs } from '../tabs';\nimport { TabViewHeaderProps } from '../tabs/Tabs.model';\nimport { BodyCaption, BodyPrimary, TitleMedium } from '../TypographyStyle';\n\ntype Props = {\n\tplans: SubscriptionPlanProps[];\n\tonPlanSelect: (code: string) => void;\n\tonClose: () => void;\n\tsubHeader?: string;\n\twarningDescription?: string;\n\tshowTrialOptions?: boolean;\n\theader?: string;\n\tshowMonthlyOptions?: boolean;\n\tshowMonthlyTabs?: boolean;\n\tstaticWidthMultiplier?: number;\n\ttabProperties?: TabViewHeaderProps;\n\tshowCouponApplicationCode?: boolean;\n\tdiscountInputProperties?: {\n\t\terrorMessage?: string;\n\t\tsuccessText?: string;\n\t\tdefaultValue?: string;\n\t\tshowRemoveCoupon?: boolean;\n\t\tonChangeText: (text: string) => void;\n\t\tremoveCoupon?: () => void;\n\t\tonCouponApply?: () => void;\n\t\tisLoading?: boolean;\n\t};\n\tshowBookAdemo?: boolean;\n\tdemoLink?: string;\n\tonClickingBookADemo?: () => void;\n};\n\nconst PlanWrapper = styled.div`\n\tdisplay: flex;\n\tcolumn-gap: 22px;\n\talign-items: stretch;\n\tpadding: 24px;\n`;\n\nconst Warning = styled.div`\n\tcolor: ${COLORS.content.negative};\n\tpadding: 0px 24px;\n`;\nexport const HeaderWrapper = styled.div`\n\tpadding: 24px 24px 0px 24px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\t.sub--header {\n\t\tmargin-top: 8px;\n\t\tcolor: ${COLORS.content.secondary} !important;\n\t}\n`;\nexport const BottomWrapper = styled.div`\n\tpadding: 0px 24px 24px 24px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tflex-wrap: wrap;\n\tgap: 8px;\n\t.coupon-code {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: flex-start;\n\t\tgap: 8px;\n\t}\n\t.coupon--success--chip {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tpadding: 4px 8px;\n\t\tborder-radius: 4px;\n\t\tborder: 1px solid #c3e4c4;\n\t\tbackground: #e6f4e7;\n\t}\n\t.coupon-input {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tgap: 8px;\n\t}\n\t.dotted--border {\n\t\tborder: 1px dotted #e0e0e0;\n\t\tpadding: 8px 8px 8px 16px;\n\t\tmin-width: 10%;\n\t\tborder-radius: 4px;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t}\n\t.error--border {\n\t\tborder: 1px dotted ${COLORS.content.negative} !important;\n\t}\n\t.input--class {\n\t\tborder: none;\n\t\t:active,\n\t\t:focus {\n\t\t\tborder: none;\n\t\t\toutline: none;\n\t\t}\n\t}\n\t.success--inside--chip {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tpadding: 4px 8px;\n\t\talign-items: center;\n\t\tgap: 6px;\n\t\tborder-radius: 4px;\n\t\tbackground: ${COLORS.background.positive.vibrant};\n\t}\n\t.demo--wrapper {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tgap: 8px;\n\t}\n\t.demo--input {\n\t\tcolor: ${COLORS.background.brand};\n\t\tborder-bottom: 1px solid ${COLORS.background.brand};\n\t\twidth: fit-content;\n\t\tcursor: pointer;\n\t}\n\t.demo--phone {\n\t\tdisplay: flex;\n\t\tpadding: 8px;\n\t\talign-items: center;\n\t\tgap: 10px;\n\t\tborder-radius: 50%;\n\t\tbackground-color: ${COLORS.background.brandLight};\n\t}\n\t.button--wrapper {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: flex-start;\n\t\tgap: 8px;\n\t}\n`;\n\nexport const defaultTabs = [\n\t{ key: 'Monthly', title: 'Monthly' },\n\t{ key: 'yearly', title: 'Yearly' },\n];\n\n// Selected plan to have chosen plan not selectable\n\nexport const SubscriptionPlanSelector: FunctionComponent<Props> = (props) => {\n\tconst [inputValue, setInputValue] = useState(\n\t\tprops.discountInputProperties?.defaultValue,\n\t);\n\tconst eachCardWidth = props.staticWidthMultiplier\n\t\t? props.staticWidthMultiplier\n\t\t: 275;\n\treturn (\n\t\t<StyledModal\n\t\t\tcentralContainerStyles={{\n\t\t\t\twidth: props.plans.length * eachCardWidth,\n\t\t\t}}\n\t\t\topen={true}\n\t\t\tcloseOnOutsideClick={true}\n\t\t\tonClose={props.onClose}\n\t\t>\n\t\t\t<HeaderWrapper>\n\t\t\t\t<div>\n\t\t\t\t\t<TitleMedium>\n\t\t\t\t\t\t{props.header || 'Select a plan to proceed'}\n\t\t\t\t\t</TitleMedium>\n\t\t\t\t\t<BodyPrimary className=\"sub--header\">\n\t\t\t\t\t\t{props.subHeader || ''}\n\t\t\t\t\t</BodyPrimary>\n\t\t\t\t</div>\n\t\t\t\t{props.showMonthlyTabs ? (\n\t\t\t\t\t<Tabs\n\t\t\t\t\t\ttabs={\n\t\t\t\t\t\t\tprops.tabProperties && props.tabProperties.tabs\n\t\t\t\t\t\t\t\t? props.tabProperties.tabs\n\t\t\t\t\t\t\t\t: defaultTabs\n\t\t\t\t\t\t}\n\t\t\t\t\t\tonTabSelected={(selectedTab) =>\n\t\t\t\t\t\t\tprops.tabProperties?.onTabSelected\n\t\t\t\t\t\t\t\t? props.tabProperties?.onTabSelected(selectedTab)\n\t\t\t\t\t\t\t\t: ''\n\t\t\t\t\t\t}\n\t\t\t\t\t\tisSquared\n\t\t\t\t\t></Tabs>\n\t\t\t\t) : (\n\t\t\t\t\t<></>\n\t\t\t\t)}\n\t\t\t</HeaderWrapper>\n\t\t\t{props.warningDescription && (\n\t\t\t\t<Warning>{props.warningDescription}</Warning>\n\t\t\t)}\n\t\t\t{/*<DurationSelector*/}\n\t\t\t{/*\tisMonthlySelected={monthly}*/}\n\t\t\t{/*\tyearlyDiscount={\"20\"}*/}\n\t\t\t{/*\tonToggle={setIsMonthly}*/}\n\t\t\t{/*/>*/}\n\t\t\t<PlanWrapper>\n\t\t\t\t{props.plans.map((prop) => {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<SubscriptionPlan\n\t\t\t\t\t\t\t{...prop}\n\t\t\t\t\t\t\tshowMonthly={true}\n\t\t\t\t\t\t\tshowMonthlyOptions={props.showMonthlyOptions || false}\n\t\t\t\t\t\t\tshowTrialOptions={props.showTrialOptions || false}\n\t\t\t\t\t\t\tonPlanSelect={props.onPlanSelect}\n\t\t\t\t\t\t\tkey={prop.planName}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</PlanWrapper>\n\t\t\t{(props.showCouponApplicationCode || props.showBookAdemo) && (\n\t\t\t\t<BottomWrapper>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{props.showCouponApplicationCode && (\n\t\t\t\t\t\t\t<div className=\"coupon-code\">\n\t\t\t\t\t\t\t\t<div className=\"coupon-input\">\n\t\t\t\t\t\t\t\t\t<BodyPrimary\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tcolor: props.discountInputProperties?.errorMessage\n\t\t\t\t\t\t\t\t\t\t\t\t? COLORS.content.negative\n\t\t\t\t\t\t\t\t\t\t\t\t: '',\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tApply coupon code\n\t\t\t\t\t\t\t\t\t</BodyPrimary>\n\t\t\t\t\t\t\t\t\t<div className=\"button--wrapper\">\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\t\t\tprops.discountInputProperties?.errorMessage\n\t\t\t\t\t\t\t\t\t\t\t\t\t? 'error--border dotted--border'\n\t\t\t\t\t\t\t\t\t\t\t\t\t: 'dotted--border'\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"input--class\"\n\t\t\t\t\t\t\t\t\t\t\t\tonChange={(text) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetInputValue(text.target.value);\n\t\t\t\t\t\t\t\t\t\t\t\t\tprops.discountInputProperties?.onChangeText(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttext.target.value,\n\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\tvalue={inputValue}\n\t\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"eg:PLAN20\"\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled={props.discountInputProperties?.isLoading}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t{props.discountInputProperties?.successText && (\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"success--inside--chip\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Check\n\t\t\t\t\t\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.primaryInverse}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<BodyCaption\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tstyle={{ color: COLORS.content.primaryInverse }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tCoupon applied\n\t\t\t\t\t\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{!props.discountInputProperties?.successText && (\n\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\tbuttonText=\"Apply\"\n\t\t\t\t\t\t\t\t\t\t\t\tbuttonType=\"primary\"\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={props?.discountInputProperties?.onCouponApply}\n\t\t\t\t\t\t\t\t\t\t\t\tisLoading={props.discountInputProperties?.isLoading}\n\t\t\t\t\t\t\t\t\t\t\t></Button>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t{props.discountInputProperties?.errorMessage && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"d-flex\" style={{ gap: 8 }}>\n\t\t\t\t\t\t\t\t\t\t\t<Info\n\t\t\t\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.negative}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t<BodyCaption style={{ color: COLORS.content.negative }}>\n\t\t\t\t\t\t\t\t\t\t\t\t{props.discountInputProperties?.errorMessage ??\n\t\t\t\t\t\t\t\t\t\t\t\t\t'Enter a valid code'}\n\t\t\t\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{props.discountInputProperties?.showRemoveCoupon && (\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"demo--input\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tsetInputValue('');\n\t\t\t\t\t\t\t\t\t\t\t\tprops.discountInputProperties?.removeCoupon\n\t\t\t\t\t\t\t\t\t\t\t\t\t? props.discountInputProperties?.removeCoupon()\n\t\t\t\t\t\t\t\t\t\t\t\t\t: '';\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tRemove coupon\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t{props.discountInputProperties?.successText && (\n\t\t\t\t\t\t\t\t\t<div className=\"coupon--success--chip\">\n\t\t\t\t\t\t\t\t\t\t<BodyCaption style={{ color: '#00580E', maxWidth: 180 }}>\n\t\t\t\t\t\t\t\t\t\t\t{props.discountInputProperties?.successText}\n\t\t\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t{props.showBookAdemo && (\n\t\t\t\t\t\t<div className=\"demo--wrapper\">\n\t\t\t\t\t\t\t<div className=\"demo--phone\">\n\t\t\t\t\t\t\t\t<PhoneIcon\n\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\tcolor={COLORS.background.brand}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<BodyPrimary\n\t\t\t\t\t\t\t\tclassName=\"demo--input\"\n\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\tprops.demoLink\n\t\t\t\t\t\t\t\t\t\t? window.open(props.demoLink, '_blank')\n\t\t\t\t\t\t\t\t\t\t: props.onClickingBookADemo\n\t\t\t\t\t\t\t\t\t\t? props.onClickingBookADemo()\n\t\t\t\t\t\t\t\t\t\t: ''\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tBook a demo with the team\n\t\t\t\t\t\t\t</BodyPrimary>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</BottomWrapper>\n\t\t\t)}\n\t\t</StyledModal>\n\t);\n};\n"],"names":["PlanWrapper","styled","Warning","COLORS","HeaderWrapper","BottomWrapper","defaultTabs","SubscriptionPlanSelector","props","inputValue","setInputValue","useState","eachCardWidth","jsxs","StyledModal","jsx","TitleMedium","BodyPrimary","Tabs","selectedTab","Fragment","prop","createElement","SubscriptionPlan","text","Check","BodyCaption","Button","Info","PhoneIcon"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),he=require("../node_modules/@tiptap/core/dist/index.js"),Q=require("@tiptap/react"),c=require("react"),Z=require("../components/TypographyStyle.js"),G=require("../helpers/sanitize.js"),b=require("./BikEditor.styles.js"),K=require("./BikEditor.types.js"),r=require("./BikEditor.utils.js"),pe=require("./extensions/buildExtensions.js"),Ce=require("./floating/LinkBubbleMenu.js"),ke=require("../icons/BIK AI specific/WandSparkles.js"),Se=require("../icons/Actions/Formatting/Copy.js");function xe(S){return Object.entries(S).map(([x,p])=>`${x.replace(/([A-Z])/g,C=>`-${C.toLowerCase()}`)}:${p}`).join(";")}const ye=(S,x)=>{const{initialContent:p,sections:C,features:k,disabled:Y,maxCharacters:T,characterLimit:ee,shortcuts:te,sendShortcut:ne,mentions:d,slashCommands:h,link:oe,onPaste:se,onReady:R,onChange:E,onSend:y,onFocus:v,onBlur:A,onSelectionChange:j,minHeight:re,maxHeight:ie,style:ce,className:ae,editorClassName:J,editorStyle:I,renderJsonError:M}=S,g=!!k?.jsonMode,L=!!k?.richPaste?G.sanitizeEmailHtml:G.sanitizeBasicHtml,a=c.useCallback(e=>r.normalizeHtml(e,L),[L]),[m,O]=c.useState(null),[le,q]=c.useState(!1),ue=g?r.buildJsonCodeBlockHtml(p??""):C?.length?r.buildSectionedContent(a(p??""),C.map(e=>({...e,content:a(e.content)}))):a(p??""),B=c.useRef([]),F=c.useRef(!1),z=c.useRef(R);z.current=R;const P=c.useRef(E);P.current=E;const H=c.useRef(j);H.current=j;const N=c.useRef(K.DEFAULT_FORMAT_STATE),w=c.useRef(v);w.current=v;const D=c.useRef(A);D.current=A;const U=c.useRef(y);U.current=y;const _=c.useRef(d?.agents??[]);_.current=d?.agents??[];const W=c.useRef(d?.teams??[]);W.current=d?.teams??[];const $=c.useRef(h?.items??[]);$.current=h?.items??[];const n=Q.useEditor({extensions:pe.buildExtensions({features:k,placeholder:S.placeholder,maxCharacters:T,characterLimit:ee,hasSections:(C?.length??0)>0,mentions:{agents:d?_:void 0,teams:d?W:void 0},slashCommands:h?$:void 0,onPaste:se,onSend:y?e=>U.current?.(e):void 0,sendShortcut:ne,shortcuts:te,onMentionSelected:d?.onSelect,onSlashCommandSelected:h?.onSelect,renderMentionItem:d?.renderItem,renderMentionDropdown:d?.renderDropdown,removeMentionTriggerOnDismiss:d?.removeTriggerOnDismiss,renderSlashCommandItem:h?.renderItem,renderSlashCommandDropdown:h?.renderDropdown}),content:ue,editable:!Y,immediatelyRender:!1,editorProps:{attributes:{...J?{class:J}:{},...I?{style:xe(I)}:{}}},onUpdate:({editor:e})=>{if(P.current?.(r.extractContent(e)),g){const t=r.parseJson(r.getCodeBlockText(e));O(t.valid?null:t)}},onTransaction:({editor:e})=>{const t=r.extractActiveFormats(e),o=N.current;(o.bold!==t.bold||o.italic!==t.italic||o.underline!==t.underline||o.strike!==t.strike||o.bulletList!==t.bulletList||o.orderedList!==t.orderedList||o.blockquote!==t.blockquote||o.codeBlock!==t.codeBlock||o.superscript!==t.superscript||o.subscript!==t.subscript||o.textAlign!==t.textAlign||o.fontFamily!==t.fontFamily||o.fontSize!==t.fontSize||o.color!==t.color||o.highlight!==t.highlight||o.link?.href!==t.link?.href)&&(N.current=t,H.current?.(t))},onFocus:()=>w.current?.(),onBlur:()=>D.current?.()});function i(e){n?e(n):B.current.push(e)}c.useEffect(()=>{if(n&&(B.current.length>0&&B.current.splice(0).forEach(t=>t(n)),F.current||(F.current=!0,z.current?.()),g)){const e=r.parseJson(r.getCodeBlockText(n));O(e.valid?null:e)}},[n,g]),c.useImperativeHandle(x,()=>({focus:e=>i(t=>t.commands.focus(e)),blur:()=>i(e=>e.commands.blur()),clearContent:()=>i(e=>e.commands.clearContent(!0)),setContent:e=>{const t=a(e);i(o=>o.commands.setContent(t,{emitUpdate:!0}))},insertContent:e=>{const t=a(e);i(o=>o.commands.insertContent(t))},insertInlineContent:e=>{i(t=>r.insertInlineHtml(t,e))},insertAtStart:e=>{const t=a(e);i(o=>o.commands.insertContentAt(1,t))},insertBlock:e=>{const t=a(e);i(o=>o.commands.insertContentAt(o.state.doc.content.size,t))},appendInline:e=>{const t=a(e);i(o=>o.commands.insertContentAt(o.state.doc.content.size-1,t))},insertAtEnd(e){this.insertBlock(e)},appendContent(e){this.appendInline(e)},getContent:()=>n?r.extractContent(n):{html:"",text:"",isEmpty:!0,characterCount:0},getJSON:()=>n?.getJSON()??null,getMentions:()=>{const e=new Set,t=new Set;return n?(n.state.doc.descendants(o=>{o.type.name==="mentionAgent"&&o.attrs.id!=null?e.add(String(o.attrs.id)):o.type.name==="mentionTeam"&&o.attrs.id!=null&&t.add(String(o.attrs.id))}),{agentIds:Array.from(e),teamIds:Array.from(t)}):{agentIds:[],teamIds:[]}},getCursorPosition:()=>{if(!n)return{from:0,to:0};const{from:e,to:t}=n.state.selection;return{from:e,to:t}},insertAtPosition:(e,t)=>{const o=a(t);i(s=>s.commands.insertContentAt(e,o))},getSelectedText:()=>{if(!n)return"";const{state:e}=n,{from:t,to:o,empty:s}=e.selection;if(!s)return e.doc.textBetween(t,o," ");const u=e.schema.marks.link;if(u){const f=he.getMarkRange(e.doc.resolve(t),u);if(f)return e.doc.textBetween(f.from,f.to," ")}return""},getCharacterCount:()=>({count:n?.storage.characterCount?.characters?.()??n?.getText().length??0,limit:T??null}),getSectionContent:e=>n?r.extractSectionContent(n,e):{html:"",text:"",isEmpty:!0,characterCount:0},setSectionContent:(e,t)=>{const o=a(t);i(s=>r.setSectionContentInEditor(s,e,o))},focusSection:e=>{i(t=>{if(e==="body"){let s=t.state.doc.content.size-1;t.state.doc.descendants((u,f)=>(u.type.name==="sectionDivider"&&s===t.state.doc.content.size-1&&(s=f-1),s===t.state.doc.content.size-1)),s<1&&(s=1),t.chain().focus().setTextSelection(s).run();return}let o=-1;t.state.doc.descendants((s,u)=>{if(o!==-1)return!1;s.type.name==="sectionDivider"&&s.attrs.sectionId===e&&(o=u+s.nodeSize+1)}),o!==-1&&t.chain().focus().setTextSelection(o).run()})},clearSection:e=>{i(t=>r.setSectionContentInEditor(t,e,"<p></p>"))},getBodyContent:()=>n?r.extractBodyContent(n):{html:"",text:"",isEmpty:!0,characterCount:0},setBodyContent:e=>{const t=a(e);i(o=>r.setSectionContentInEditor(o,"body",t))},setBodyAndSections:(e,t)=>{const o=r.buildSectionedContent(a(e),t.map(s=>({id:s.id,content:a(s.content)})));i(s=>s.commands.setContent(o,{emitUpdate:!0}))},appendBodyContent:e=>{const t=a(e);i(o=>{const s=r.findSectionEndPos(o,"body");o.commands.insertContentAt(s-1,t,{parseOptions:{preserveWhitespace:!0}})})},insertAtSectionStart:(e,t)=>{const o=a(t);i(s=>{const u=r.findSectionStartPos(s,e);u!==-1&&s.commands.insertContentAt(u,o,{parseOptions:{preserveWhitespace:!0}})})},insertAtSectionEnd:(e,t)=>{const o=a(t);i(s=>{const u=r.findSectionEndPos(s,e);s.commands.insertContentAt(u,o,{parseOptions:{preserveWhitespace:!0}})})},getActiveFormats:()=>n?r.extractActiveFormats(n):K.DEFAULT_FORMAT_STATE,actions:{toggleBold:()=>n?.chain().focus().toggleBold().run(),toggleItalic:()=>n?.chain().focus().toggleItalic().run(),toggleUnderline:()=>n?.chain().focus().toggleUnderline().run(),toggleStrike:()=>n?.chain().focus().toggleStrike().run(),toggleBulletList:()=>n?.chain().focus().toggleBulletList().run(),toggleOrderedList:()=>n?.chain().focus().toggleOrderedList().run(),toggleBlockquote:()=>n?.chain().focus().toggleBlockquote().run(),toggleCodeBlock:()=>n?.chain().focus().toggleCodeBlock().run(),setTextAlign:e=>n?.chain().focus().setTextAlign(e).run(),setFontFamily:e=>n?.chain().focus().setFontFamily(e).run(),setFontSize:e=>n?.chain().focus().setFontSize(e).run(),setColor:e=>n?.chain().focus().setColor(e).run(),setHighlight:e=>n?.chain().focus().toggleHighlight({color:e}).run(),unsetColor:()=>n?.chain().focus().unsetColor().run(),unsetHighlight:()=>n?.chain().focus().unsetHighlight().run(),setLink:(e,t)=>{n&&(t!==void 0?n.chain().focus().extendMarkRange("link").command(({tr:o,state:s})=>{const{from:u,to:f}=o.selection,V=s.schema.marks.link;if(!V)return!1;const ge=s.schema.text(t,[V.create({href:e})]),fe=s.schema.text(" ");return o.replaceWith(u,f,[ge,fe]),!0}).run():n.chain().focus().extendMarkRange("link").setLink({href:e}).insertContent(" ").run())},updateLink:e=>n?.chain().focus().extendMarkRange("link").setLink({href:e}).run(),removeLink:()=>n?.chain().focus().extendMarkRange("link").unsetLink().run(),insertEmoji:e=>n?.chain().focus().insertContent(e).run(),insertVariable:e=>n?.chain().focus().insertContent(`{{${e}}}`).run(),insertHtml:e=>n?.commands.insertContent(a(e)),undo:()=>n?.chain().focus().undo().run(),redo:()=>n?.chain().focus().redo().run(),canUndo:()=>n?.can().undo()??!1,canRedo:()=>n?.can().redo()??!1,toggleSuperscript:()=>n?.chain().focus().toggleSuperscript().run(),toggleSubscript:()=>n?.chain().focus().toggleSubscript().run(),insertImage:e=>n?.chain().focus().setImage({src:e}).run()},json:k?.jsonMode?{getText:()=>n?r.getCodeBlockText(n):"",setText:e=>i(t=>r.setCodeBlockText(t,e)),parse:()=>r.parseJson(n?r.getCodeBlockText(n):""),isValid:()=>r.parseJson(n?r.getCodeBlockText(n):"").valid,format:(e=2)=>i(t=>{const{valid:o,value:s}=r.parseJson(r.getCodeBlockText(t));!o||s===null||r.setCodeBlockText(t,JSON.stringify(s,null,e))}),minify:()=>i(e=>{const{valid:t,value:o}=r.parseJson(r.getCodeBlockText(e));!t||o===null||r.setCodeBlockText(e,JSON.stringify(o))})}:void 0}),[n]);const de=()=>{if(!n)return;const{valid:e,value:t}=r.parseJson(r.getCodeBlockText(n));!e||t===null||r.setCodeBlockText(n,JSON.stringify(t,null,2))},me=()=>{n&&(navigator.clipboard?.writeText(r.getCodeBlockText(n)),q(!0),setTimeout(()=>q(!1),1500))};return n?l.jsxs(b.BikEditorShell,{minHeight:re,maxHeight:ie,tightParagraphs:!k?.richPaste,jsonMode:g,style:ce,className:ae,children:[g&&l.jsxs(b.BikJsonHeader,{children:[l.jsx("span",{className:"bik-json-header-label",children:"JSON"}),l.jsxs("div",{className:"bik-json-header-actions",children:[l.jsxs("button",{type:"button",onClick:de,disabled:!!m,title:"Format JSON",children:[l.jsx(ke.default,{size:16}),l.jsx(Z.BodyCaption,{children:"Beautify"})]}),l.jsxs("button",{type:"button",onClick:me,title:"Copy JSON",children:[l.jsx(Se.default,{size:16}),le&&l.jsx(Z.BodyCaption,{children:"Copied"})]})]})]}),l.jsx(Q.EditorContent,{editor:n}),l.jsx(Ce.LinkBubbleMenu,{editor:n,renderLinkTooltip:oe?.renderTooltip}),g&&m?M?M(m):l.jsxs(b.BikJsonError,{children:[m.line!=null&&l.jsxs("strong",{children:["Line ",m.line,m.column!=null?`, column ${m.column}`:"",":"," "]}),m.error]}):null]}):null},X=c.forwardRef(ye);X.displayName="BikEditor";exports.BikEditor=X;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),me=require("../node_modules/@tiptap/core/dist/index.js"),$=require("@tiptap/react"),c=require("react"),V=require("../components/TypographyStyle.js"),B=require("./BikEditor.styles.js"),Q=require("./BikEditor.types.js"),s=require("./BikEditor.utils.js"),ge=require("./extensions/buildExtensions.js"),fe=require("./floating/LinkBubbleMenu.js"),he=require("../icons/BIK AI specific/WandSparkles.js"),pe=require("../icons/Actions/Formatting/Copy.js");function Ce(C){return Object.entries(C).map(([S,h])=>`${S.replace(/([A-Z])/g,p=>`-${p.toLowerCase()}`)}:${h}`).join(";")}const ke=(C,S)=>{const{initialContent:h,sections:p,features:k,disabled:G,maxCharacters:T,characterLimit:K,shortcuts:X,sendShortcut:Y,mentions:u,slashCommands:f,link:ee,onPaste:te,onReady:b,onChange:R,onSend:x,onFocus:v,onBlur:E,onSelectionChange:A,minHeight:ne,maxHeight:oe,style:se,className:re,editorClassName:z,editorStyle:H,renderJsonError:j}=C,m=!!k?.jsonMode,[d,J]=c.useState(null),[ie,I]=c.useState(!1),ce=m?s.buildJsonCodeBlockHtml(h??""):p?.length?s.buildSectionedContent(s.normalizeHtml(h??""),p.map(e=>({...e,content:s.normalizeHtml(e.content)}))):s.normalizeHtml(h??""),y=c.useRef([]),M=c.useRef(!1),L=c.useRef(b);L.current=b;const O=c.useRef(R);O.current=R;const F=c.useRef(A);F.current=A;const q=c.useRef(Q.DEFAULT_FORMAT_STATE),N=c.useRef(v);N.current=v;const P=c.useRef(E);P.current=E;const w=c.useRef(x);w.current=x;const D=c.useRef(u?.agents??[]);D.current=u?.agents??[];const U=c.useRef(u?.teams??[]);U.current=u?.teams??[];const _=c.useRef(f?.items??[]);_.current=f?.items??[];const n=$.useEditor({extensions:ge.buildExtensions({features:k,placeholder:C.placeholder,maxCharacters:T,characterLimit:K,hasSections:(p?.length??0)>0,mentions:{agents:u?D:void 0,teams:u?U:void 0},slashCommands:f?_:void 0,onPaste:te,onSend:x?e=>w.current?.(e):void 0,sendShortcut:Y,shortcuts:X,onMentionSelected:u?.onSelect,onSlashCommandSelected:f?.onSelect,renderMentionItem:u?.renderItem,renderMentionDropdown:u?.renderDropdown,removeMentionTriggerOnDismiss:u?.removeTriggerOnDismiss,renderSlashCommandItem:f?.renderItem,renderSlashCommandDropdown:f?.renderDropdown}),content:ce,editable:!G,immediatelyRender:!1,editorProps:{attributes:{...z?{class:z}:{},...H?{style:Ce(H)}:{}}},onUpdate:({editor:e})=>{if(O.current?.(s.extractContent(e)),m){const t=s.parseJson(s.getCodeBlockText(e));J(t.valid?null:t)}},onTransaction:({editor:e})=>{const t=s.extractActiveFormats(e),o=q.current;(o.bold!==t.bold||o.italic!==t.italic||o.underline!==t.underline||o.strike!==t.strike||o.bulletList!==t.bulletList||o.orderedList!==t.orderedList||o.blockquote!==t.blockquote||o.codeBlock!==t.codeBlock||o.superscript!==t.superscript||o.subscript!==t.subscript||o.textAlign!==t.textAlign||o.fontFamily!==t.fontFamily||o.fontSize!==t.fontSize||o.color!==t.color||o.highlight!==t.highlight||o.link?.href!==t.link?.href)&&(q.current=t,F.current?.(t))},onFocus:()=>N.current?.(),onBlur:()=>P.current?.()});function i(e){n?e(n):y.current.push(e)}c.useEffect(()=>{if(n&&(y.current.length>0&&y.current.splice(0).forEach(t=>t(n)),M.current||(M.current=!0,L.current?.()),m)){const e=s.parseJson(s.getCodeBlockText(n));J(e.valid?null:e)}},[n,m]),c.useImperativeHandle(S,()=>({focus:e=>i(t=>t.commands.focus(e)),blur:()=>i(e=>e.commands.blur()),clearContent:()=>i(e=>e.commands.clearContent(!0)),setContent:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.setContent(t,{emitUpdate:!0}))},insertContent:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContent(t))},insertInlineContent:e=>{i(t=>s.insertInlineHtml(t,e))},insertAtStart:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContentAt(1,t))},insertBlock:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContentAt(o.state.doc.content.size,t))},appendInline:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContentAt(o.state.doc.content.size-1,t))},insertAtEnd(e){this.insertBlock(e)},appendContent(e){this.appendInline(e)},getContent:()=>n?s.extractContent(n):{html:"",text:"",isEmpty:!0,characterCount:0},getJSON:()=>n?.getJSON()??null,getMentions:()=>{const e=new Set,t=new Set;return n?(n.state.doc.descendants(o=>{o.type.name==="mentionAgent"&&o.attrs.id!=null?e.add(String(o.attrs.id)):o.type.name==="mentionTeam"&&o.attrs.id!=null&&t.add(String(o.attrs.id))}),{agentIds:Array.from(e),teamIds:Array.from(t)}):{agentIds:[],teamIds:[]}},getCursorPosition:()=>{if(!n)return{from:0,to:0};const{from:e,to:t}=n.state.selection;return{from:e,to:t}},insertAtPosition:(e,t)=>{const o=s.normalizeHtml(t);i(r=>r.commands.insertContentAt(e,o))},getSelectedText:()=>{if(!n)return"";const{state:e}=n,{from:t,to:o,empty:r}=e.selection;if(!r)return e.doc.textBetween(t,o," ");const l=e.schema.marks.link;if(l){const g=me.getMarkRange(e.doc.resolve(t),l);if(g)return e.doc.textBetween(g.from,g.to," ")}return""},getCharacterCount:()=>({count:n?.storage.characterCount?.characters?.()??n?.getText().length??0,limit:T??null}),getSectionContent:e=>n?s.extractSectionContent(n,e):{html:"",text:"",isEmpty:!0,characterCount:0},setSectionContent:(e,t)=>{const o=s.normalizeHtml(t);i(r=>s.setSectionContentInEditor(r,e,o))},focusSection:e=>{i(t=>{if(e==="body"){let r=t.state.doc.content.size-1;t.state.doc.descendants((l,g)=>(l.type.name==="sectionDivider"&&r===t.state.doc.content.size-1&&(r=g-1),r===t.state.doc.content.size-1)),r<1&&(r=1),t.chain().focus().setTextSelection(r).run();return}let o=-1;t.state.doc.descendants((r,l)=>{if(o!==-1)return!1;r.type.name==="sectionDivider"&&r.attrs.sectionId===e&&(o=l+r.nodeSize+1)}),o!==-1&&t.chain().focus().setTextSelection(o).run()})},clearSection:e=>{i(t=>s.setSectionContentInEditor(t,e,"<p></p>"))},getBodyContent:()=>n?s.extractBodyContent(n):{html:"",text:"",isEmpty:!0,characterCount:0},setBodyContent:e=>{const t=s.normalizeHtml(e);i(o=>s.setSectionContentInEditor(o,"body",t))},setBodyAndSections:(e,t)=>{const o=s.buildSectionedContent(s.normalizeHtml(e),t.map(r=>({id:r.id,content:s.normalizeHtml(r.content)})));i(r=>r.commands.setContent(o,{emitUpdate:!0}))},appendBodyContent:e=>{const t=s.normalizeHtml(e);i(o=>{const r=s.findSectionEndPos(o,"body");o.commands.insertContentAt(r-1,t,{parseOptions:{preserveWhitespace:!0}})})},insertAtSectionStart:(e,t)=>{const o=s.normalizeHtml(t);i(r=>{const l=s.findSectionStartPos(r,e);l!==-1&&r.commands.insertContentAt(l,o,{parseOptions:{preserveWhitespace:!0}})})},insertAtSectionEnd:(e,t)=>{const o=s.normalizeHtml(t);i(r=>{const l=s.findSectionEndPos(r,e);r.commands.insertContentAt(l,o,{parseOptions:{preserveWhitespace:!0}})})},getActiveFormats:()=>n?s.extractActiveFormats(n):Q.DEFAULT_FORMAT_STATE,actions:{toggleBold:()=>n?.chain().focus().toggleBold().run(),toggleItalic:()=>n?.chain().focus().toggleItalic().run(),toggleUnderline:()=>n?.chain().focus().toggleUnderline().run(),toggleStrike:()=>n?.chain().focus().toggleStrike().run(),toggleBulletList:()=>n?.chain().focus().toggleBulletList().run(),toggleOrderedList:()=>n?.chain().focus().toggleOrderedList().run(),toggleBlockquote:()=>n?.chain().focus().toggleBlockquote().run(),toggleCodeBlock:()=>n?.chain().focus().toggleCodeBlock().run(),setTextAlign:e=>n?.chain().focus().setTextAlign(e).run(),setFontFamily:e=>n?.chain().focus().setFontFamily(e).run(),setFontSize:e=>n?.chain().focus().setFontSize(e).run(),setColor:e=>n?.chain().focus().setColor(e).run(),setHighlight:e=>n?.chain().focus().toggleHighlight({color:e}).run(),unsetColor:()=>n?.chain().focus().unsetColor().run(),unsetHighlight:()=>n?.chain().focus().unsetHighlight().run(),setLink:(e,t)=>{n&&(t!==void 0?n.chain().focus().extendMarkRange("link").command(({tr:o,state:r})=>{const{from:l,to:g}=o.selection,W=r.schema.marks.link;if(!W)return!1;const ue=r.schema.text(t,[W.create({href:e})]),de=r.schema.text(" ");return o.replaceWith(l,g,[ue,de]),!0}).run():n.chain().focus().extendMarkRange("link").setLink({href:e}).insertContent(" ").run())},updateLink:e=>n?.chain().focus().extendMarkRange("link").setLink({href:e}).run(),removeLink:()=>n?.chain().focus().extendMarkRange("link").unsetLink().run(),insertEmoji:e=>n?.chain().focus().insertContent(e).run(),insertVariable:e=>n?.chain().focus().insertContent(`{{${e}}}`).run(),insertHtml:e=>n?.commands.insertContent(s.normalizeHtml(e)),undo:()=>n?.chain().focus().undo().run(),redo:()=>n?.chain().focus().redo().run(),canUndo:()=>n?.can().undo()??!1,canRedo:()=>n?.can().redo()??!1,toggleSuperscript:()=>n?.chain().focus().toggleSuperscript().run(),toggleSubscript:()=>n?.chain().focus().toggleSubscript().run(),insertImage:e=>n?.chain().focus().setImage({src:e}).run()},json:k?.jsonMode?{getText:()=>n?s.getCodeBlockText(n):"",setText:e=>i(t=>s.setCodeBlockText(t,e)),parse:()=>s.parseJson(n?s.getCodeBlockText(n):""),isValid:()=>s.parseJson(n?s.getCodeBlockText(n):"").valid,format:(e=2)=>i(t=>{const{valid:o,value:r}=s.parseJson(s.getCodeBlockText(t));!o||r===null||s.setCodeBlockText(t,JSON.stringify(r,null,e))}),minify:()=>i(e=>{const{valid:t,value:o}=s.parseJson(s.getCodeBlockText(e));!t||o===null||s.setCodeBlockText(e,JSON.stringify(o))})}:void 0}),[n]);const ae=()=>{if(!n)return;const{valid:e,value:t}=s.parseJson(s.getCodeBlockText(n));!e||t===null||s.setCodeBlockText(n,JSON.stringify(t,null,2))},le=()=>{n&&(navigator.clipboard?.writeText(s.getCodeBlockText(n)),I(!0),setTimeout(()=>I(!1),1500))};return n?a.jsxs(B.BikEditorShell,{minHeight:ne,maxHeight:oe,tightParagraphs:!k?.richPaste,jsonMode:m,style:se,className:re,children:[m&&a.jsxs(B.BikJsonHeader,{children:[a.jsx("span",{className:"bik-json-header-label",children:"JSON"}),a.jsxs("div",{className:"bik-json-header-actions",children:[a.jsxs("button",{type:"button",onClick:ae,disabled:!!d,title:"Format JSON",children:[a.jsx(he.default,{size:16}),a.jsx(V.BodyCaption,{children:"Beautify"})]}),a.jsxs("button",{type:"button",onClick:le,title:"Copy JSON",children:[a.jsx(pe.default,{size:16}),ie&&a.jsx(V.BodyCaption,{children:"Copied"})]})]})]}),a.jsx($.EditorContent,{editor:n}),a.jsx(fe.LinkBubbleMenu,{editor:n,renderLinkTooltip:ee?.renderTooltip}),m&&d?j?j(d):a.jsxs(B.BikJsonError,{children:[d.line!=null&&a.jsxs("strong",{children:["Line ",d.line,d.column!=null?`, column ${d.column}`:"",":"," "]}),d.error]}):null]}):null},Z=c.forwardRef(ke);Z.displayName="BikEditor";exports.BikEditor=Z;
2
2
  //# sourceMappingURL=BikEditor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport { BodyCaption } from '@src/components/TypographyStyle';\nimport { sanitizeBasicHtml, sanitizeEmailHtml } from '../helpers/sanitize';\nimport { Copy, WandSparkles } from '../icons';\nimport {\n\tBikEditorShell,\n\tBikJsonError,\n\tBikJsonHeader,\n} from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n\tJsonParseResult,\n} from './BikEditor.types';\nimport {\n\tbuildJsonCodeBlockHtml,\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tgetCodeBlockText,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tparseJson,\n\tsetCodeBlockText,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tcharacterLimit,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t\trenderJsonError,\n\t} = props;\n\n\tconst isJsonMode = !!features?.jsonMode;\n\tconst isRichPaste = !!features?.richPaste;\n\n\t// Pick the right sanitizer: email channels (richPaste) get the full email\n\t// allowlist; non-email channels get the basic formatting allowlist.\n\tconst sanitizer = isRichPaste ? sanitizeEmailHtml : sanitizeBasicHtml;\n\tconst normalize = useCallback(\n\t\t(html: string) => normalizeHtml(html, sanitizer),\n\t\t[sanitizer],\n\t);\n\n\t// Live JSON parse error, shown inside the editor when jsonMode is on.\n\t// null = valid (or not applicable) → nothing rendered.\n\tconst [jsonError, setJsonError] = useState<JsonParseResult | null>(null);\n\t// Transient \"Copied\" state for the jsonMode copy button.\n\tconst [jsonCopied, setJsonCopied] = useState(false);\n\n\t// JSON body mode: treat initialContent as raw JSON text and wrap it in a code\n\t// block. Skips section/HTML normalisation entirely.\n\tconst initialEditorContent = isJsonMode\n\t\t? buildJsonCodeBlockHtml(initialContent ?? '')\n\t\t: sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalize(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalize(s.content) })),\n\t\t )\n\t\t: normalize(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst prevFormatsRef = useRef<FormatState>(DEFAULT_FORMAT_STATE);\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\tcharacterLimit,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\tremoveMentionTriggerOnDismiss: mentions?.removeTriggerOnDismiss,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t\tif (isJsonMode) {\n\t\t\t\tconst result = parseJson(getCodeBlockText(e));\n\t\t\t\tsetJsonError(result.valid ? null : result);\n\t\t\t}\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tconst next = extractActiveFormats(e);\n\t\t\tconst prev = prevFormatsRef.current;\n\t\t\tconst changed =\n\t\t\t\tprev.bold !== next.bold ||\n\t\t\t\tprev.italic !== next.italic ||\n\t\t\t\tprev.underline !== next.underline ||\n\t\t\t\tprev.strike !== next.strike ||\n\t\t\t\tprev.bulletList !== next.bulletList ||\n\t\t\t\tprev.orderedList !== next.orderedList ||\n\t\t\t\tprev.blockquote !== next.blockquote ||\n\t\t\t\tprev.codeBlock !== next.codeBlock ||\n\t\t\t\tprev.superscript !== next.superscript ||\n\t\t\t\tprev.subscript !== next.subscript ||\n\t\t\t\tprev.textAlign !== next.textAlign ||\n\t\t\t\tprev.fontFamily !== next.fontFamily ||\n\t\t\t\tprev.fontSize !== next.fontSize ||\n\t\t\t\tprev.color !== next.color ||\n\t\t\t\tprev.highlight !== next.highlight ||\n\t\t\t\tprev.link?.href !== next.link?.href;\n\t\t\tif (changed) {\n\t\t\t\tprevFormatsRef.current = next;\n\t\t\t\tonSelectionChangeRef.current?.(next);\n\t\t\t}\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t\t// Surface an error for invalid initialContent immediately on mount.\n\t\tif (isJsonMode) {\n\t\t\tconst result = parseJson(getCodeBlockText(editor));\n\t\t\tsetJsonError(result.valid ? null : result);\n\t\t}\n\t}, [editor, isJsonMode]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalize(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalize(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalize(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalize(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalize(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalize(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalize(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalize(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalize(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalize(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalize(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalize(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1)\n\t\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalize(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) => editor?.commands.insertContent(normalize(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\n\t\t\t// ── JSON body ─────────────────────────────────────────────────────\n\t\t\tjson: features?.jsonMode\n\t\t\t\t? {\n\t\t\t\t\t\tgetText: () => (editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tsetText: (raw) => enqueue((e) => setCodeBlockText(e, raw)),\n\t\t\t\t\t\tparse: () => parseJson(editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tisValid: () =>\n\t\t\t\t\t\t\tparseJson(editor ? getCodeBlockText(editor) : '').valid,\n\t\t\t\t\t\tformat: (indent = 2) =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value, null, indent));\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tminify: () =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value));\n\t\t\t\t\t\t\t}),\n\t\t\t\t }\n\t\t\t\t: undefined,\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\t// ── jsonMode floating actions ────────────────────────────────────────────\n\t// Beautify pretty-prints in place (no-op / disabled while the JSON is broken);\n\t// Copy writes the raw text to the clipboard with transient feedback.\n\tconst handleJsonBeautify = () => {\n\t\tif (!editor) return;\n\t\tconst { valid, value } = parseJson(getCodeBlockText(editor));\n\t\tif (!valid || value === null) return;\n\t\tsetCodeBlockText(editor, JSON.stringify(value, null, 2));\n\t};\n\tconst handleJsonCopy = () => {\n\t\tif (!editor) return;\n\t\tvoid navigator.clipboard?.writeText(getCodeBlockText(editor));\n\t\tsetJsonCopied(true);\n\t\tsetTimeout(() => setJsonCopied(false), 1500);\n\t};\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tjsonMode={isJsonMode}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t{isJsonMode && (\n\t\t\t\t<BikJsonHeader>\n\t\t\t\t\t<span className=\"bik-json-header-label\">JSON</span>\n\t\t\t\t\t<div className=\"bik-json-header-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={handleJsonBeautify}\n\t\t\t\t\t\t\tdisabled={!!jsonError}\n\t\t\t\t\t\t\ttitle=\"Format JSON\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<WandSparkles size={16} />\n\t\t\t\t\t\t\t<BodyCaption>Beautify</BodyCaption>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button type=\"button\" onClick={handleJsonCopy} title=\"Copy JSON\">\n\t\t\t\t\t\t\t<Copy size={16} />\n\t\t\t\t\t\t\t{jsonCopied && <BodyCaption>Copied</BodyCaption>}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</BikJsonHeader>\n\t\t\t)}\n\t\t\t<EditorContent editor={editor} />\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t\t{isJsonMode && jsonError ? (\n\t\t\t\trenderJsonError ? (\n\t\t\t\t\trenderJsonError(jsonError)\n\t\t\t\t) : (\n\t\t\t\t\t<BikJsonError>\n\t\t\t\t\t\t{jsonError.line != null && (\n\t\t\t\t\t\t\t<strong>\n\t\t\t\t\t\t\t\tLine {jsonError.line}\n\t\t\t\t\t\t\t\t{jsonError.column != null ? `, column ${jsonError.column}` : ''}\n\t\t\t\t\t\t\t\t:{' '}\n\t\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{jsonError.error}\n\t\t\t\t\t</BikJsonError>\n\t\t\t\t)\n\t\t\t) : null}\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","k","v","c","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","characterLimit","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","renderJsonError","isJsonMode","sanitizer","sanitizeEmailHtml","sanitizeBasicHtml","normalize","useCallback","html","normalizeHtml","jsonError","setJsonError","useState","jsonCopied","setJsonCopied","initialEditorContent","buildJsonCodeBlockHtml","buildSectionedContent","s","pendingQueue","useRef","hasCalledOnReady","onReadyRef","onChangeRef","onSelectionChangeRef","prevFormatsRef","DEFAULT_FORMAT_STATE","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","teamMentionsRef","slashCommandsRef","editor","useEditor","buildExtensions","snapshot","extractContent","result","parseJson","getCodeBlockText","next","extractActiveFormats","prev","enqueue","op","useEffect","useImperativeHandle","position","e","normalised","insertInlineHtml","agentIds","teamIds","node","from","to","pos","state","empty","linkMarkType","range","getMarkRange","sectionId","extractSectionContent","setSectionContentInEditor","endOfBody","targetPos","extractBodyContent","body","boundaryPos","findSectionEndPos","findSectionStartPos","align","font","size","color","href","text","tr","linkNode","space","emoji","variableName","src","raw","setCodeBlockText","indent","valid","value","handleJsonBeautify","handleJsonCopy","jsxs","BikEditorShell","BikJsonHeader","jsx","WandSparkles","BodyCaption","Copy","EditorContent","LinkBubbleMenu","BikJsonError","BikEditor","forwardRef"],"mappings":"ulBAoDA,SAASA,GAAYC,EAAoC,CACxD,OAAO,OAAO,QAAQA,CAAK,EACzB,IACA,CAAC,CAACC,EAAGC,CAAC,IAAM,GAAGD,EAAE,QAAQ,WAAaE,GAAM,IAAIA,EAAE,YAAA,CAAa,EAAE,CAAC,IAAID,CAAC,EAAA,EAEvE,KAAK,GAAG,CACX,CAEA,MAAME,GAAiB,CACtBC,EACAC,IACI,CACJ,KAAM,CACL,eAAAC,EACA,SAAAC,EACA,SAAAC,EACA,SAAAC,EACA,cAAAC,EACA,eAAAC,GACA,UAAAC,GACA,aAAAC,GACA,SAAAC,EACA,cAAAC,EACA,KAAAC,GACA,QAAAC,GACA,QAAAC,EACA,SAAAC,EACA,OAAAC,EACA,QAAAC,EACA,OAAAC,EACA,kBAAAC,EACA,UAAAC,GACA,UAAAC,GACA,MAAA1B,GACA,UAAA2B,GACA,gBAAAC,EACA,YAAAC,EACA,gBAAAC,CAAA,EACGzB,EAEE0B,EAAa,CAAC,CAACtB,GAAU,SAKzBuB,EAJc,CAAC,CAACvB,GAAU,UAIAwB,EAAAA,kBAAoBC,EAAAA,kBAC9CC,EAAYC,EAAAA,YAChBC,GAAiBC,EAAAA,cAAcD,EAAML,CAAS,EAC/C,CAACA,CAAS,CAAA,EAKL,CAACO,EAAWC,CAAY,EAAIC,EAAAA,SAAiC,IAAI,EAEjE,CAACC,GAAYC,CAAa,EAAIF,EAAAA,SAAS,EAAK,EAI5CG,GAAuBb,EAC1Bc,yBAAuBtC,GAAkB,EAAE,EAC3CC,GAAU,OACVsC,EAAAA,sBACAX,EAAU5B,GAAkB,EAAE,EAC9BC,EAAS,IAAKuC,IAAO,CAAE,GAAGA,EAAG,QAASZ,EAAUY,EAAE,OAAO,GAAI,CAAA,EAE7DZ,EAAU5B,GAAkB,EAAE,EAO3ByC,EAAeC,EAAAA,OAAmC,EAAE,EACpDC,EAAmBD,EAAAA,OAAO,EAAK,EAI/BE,EAAaF,EAAAA,OAAO9B,CAAO,EACjCgC,EAAW,QAAUhC,EACrB,MAAMiC,EAAcH,EAAAA,OAAO7B,CAAQ,EACnCgC,EAAY,QAAUhC,EACtB,MAAMiC,EAAuBJ,EAAAA,OAAOzB,CAAiB,EACrD6B,EAAqB,QAAU7B,EAC/B,MAAM8B,EAAiBL,EAAAA,OAAoBM,sBAAoB,EACzDC,EAAaP,EAAAA,OAAO3B,CAAO,EACjCkC,EAAW,QAAUlC,EACrB,MAAMmC,EAAYR,EAAAA,OAAO1B,CAAM,EAC/BkC,EAAU,QAAUlC,EACpB,MAAMmC,EAAYT,EAAAA,OAAO5B,CAAM,EAC/BqC,EAAU,QAAUrC,EACpB,MAAMsC,EAAmBV,EAAAA,OAAOlC,GAAU,QAAU,CAAA,CAAE,EACtD4C,EAAiB,QAAU5C,GAAU,QAAU,CAAA,EAC/C,MAAM6C,EAAkBX,EAAAA,OAAOlC,GAAU,OAAS,CAAA,CAAE,EACpD6C,EAAgB,QAAU7C,GAAU,OAAS,CAAA,EAC7C,MAAM8C,EAAmBZ,EAAAA,OAAOjC,GAAe,OAAS,CAAA,CAAE,EAC1D6C,EAAiB,QAAU7C,GAAe,OAAS,CAAA,EAEnD,MAAM8C,EAASC,EAAAA,UAAU,CACxB,WAAYC,GAAAA,gBAAgB,CAC3B,SAAAvD,EACA,YAAaJ,EAAM,YACnB,cAAAM,EACA,eAAAC,GACA,aAAcJ,GAAU,QAAU,GAAK,EACvC,SAAU,CACT,OAAQO,EAAW4C,EAAmB,OACtC,MAAO5C,EAAW6C,EAAkB,MAAA,EAErC,cAAe5C,EAAgB6C,EAAmB,OAClD,QAAA3C,GACA,OAAQG,EAAU4C,GAAaP,EAAU,UAAUO,CAAQ,EAAI,OAC/D,aAAAnD,GACA,UAAAD,GACA,kBAAmBE,GAAU,SAC7B,uBAAwBC,GAAe,SACvC,kBAAmBD,GAAU,WAC7B,sBAAuBA,GAAU,eACjC,8BAA+BA,GAAU,uBACzC,uBAAwBC,GAAe,WACvC,2BAA4BA,GAAe,cAAA,CAC3C,EACD,QAAS4B,GACT,SAAU,CAAClC,EACX,kBAAmB,GACnB,YAAa,CACZ,WAAY,CACX,GAAIkB,EAAkB,CAAE,MAAOA,CAAA,EAAoB,CAAA,EACnD,GAAIC,EAAc,CAAE,MAAO9B,GAAY8B,CAAW,CAAA,EAAM,CAAA,CAAC,CAC1D,EAED,SAAU,CAAC,CAAE,OAAQ,KAAQ,CAE5B,GADAuB,EAAY,UAAUc,iBAAe,CAAC,CAAC,EACnCnC,EAAY,CACf,MAAMoC,EAASC,EAAAA,UAAUC,EAAAA,iBAAiB,CAAC,CAAC,EAC5C7B,EAAa2B,EAAO,MAAQ,KAAOA,CAAM,CAC1C,CACD,EACA,cAAe,CAAC,CAAE,OAAQ,KAAQ,CACjC,MAAMG,EAAOC,EAAAA,qBAAqB,CAAC,EAC7BC,EAAOlB,EAAe,SAE3BkB,EAAK,OAASF,EAAK,MACnBE,EAAK,SAAWF,EAAK,QACrBE,EAAK,YAAcF,EAAK,WACxBE,EAAK,SAAWF,EAAK,QACrBE,EAAK,aAAeF,EAAK,YACzBE,EAAK,cAAgBF,EAAK,aAC1BE,EAAK,aAAeF,EAAK,YACzBE,EAAK,YAAcF,EAAK,WACxBE,EAAK,cAAgBF,EAAK,aAC1BE,EAAK,YAAcF,EAAK,WACxBE,EAAK,YAAcF,EAAK,WACxBE,EAAK,aAAeF,EAAK,YACzBE,EAAK,WAAaF,EAAK,UACvBE,EAAK,QAAUF,EAAK,OACpBE,EAAK,YAAcF,EAAK,WACxBE,EAAK,MAAM,OAASF,EAAK,MAAM,QAE/BhB,EAAe,QAAUgB,EACzBjB,EAAqB,UAAUiB,CAAI,EAErC,EACA,QAAS,IAAMd,EAAW,UAAA,EAC1B,OAAQ,IAAMC,EAAU,UAAA,CAAU,CAClC,EAMD,SAASgB,EAAQC,EAA+B,CAC3CZ,EACHY,EAAGZ,CAAM,EAETd,EAAa,QAAQ,KAAK0B,CAAE,CAE9B,CAGAC,EAAAA,UAAU,IAAM,CACf,GAAKb,IACDd,EAAa,QAAQ,OAAS,GACnBA,EAAa,QAAQ,OAAO,CAAC,EACrC,QAAS0B,GAAOA,EAAGZ,CAAM,CAAC,EAE5BZ,EAAiB,UACrBA,EAAiB,QAAU,GAC3BC,EAAW,UAAA,GAGRpB,GAAY,CACf,MAAMoC,EAASC,EAAAA,UAAUC,EAAAA,iBAAiBP,CAAM,CAAC,EACjDtB,EAAa2B,EAAO,MAAQ,KAAOA,CAAM,CAC1C,CACD,EAAG,CAACL,EAAQ/B,CAAU,CAAC,EAEvB6C,EAAAA,oBACCtE,EACA,KAAO,CAEN,MAAQuE,GAAaJ,EAASK,GAAMA,EAAE,SAAS,MAAMD,CAAQ,CAAC,EAC9D,KAAM,IAAMJ,EAAS,GAAM,EAAE,SAAS,MAAM,EAG5C,aAAc,IAAMA,EAAS,GAAM,EAAE,SAAS,aAAa,EAAI,CAAC,EAChE,WAAapC,GAAS,CACrB,MAAM0C,EAAa5C,EAAUE,CAAI,EACjCoC,EAASK,GAAMA,EAAE,SAAS,WAAWC,EAAY,CAAE,WAAY,EAAA,CAAM,CAAC,CACvE,EACA,cAAgB1C,GAAS,CACxB,MAAM0C,EAAa5C,EAAUE,CAAI,EACjCoC,EAASK,GAAMA,EAAE,SAAS,cAAcC,CAAU,CAAC,CACpD,EACA,oBAAsB1C,GAAS,CAC9BoC,EAASK,GAAME,EAAAA,iBAAiBF,EAAGzC,CAAI,CAAC,CACzC,EACA,cAAgBA,GAAS,CACxB,MAAM0C,EAAa5C,EAAUE,CAAI,EACjCoC,EAASK,GAAMA,EAAE,SAAS,gBAAgB,EAAGC,CAAU,CAAC,CACzD,EACA,YAAc1C,GAAS,CACtB,MAAM0C,EAAa5C,EAAUE,CAAI,EACjCoC,EAASK,GACRA,EAAE,SAAS,gBAAgBA,EAAE,MAAM,IAAI,QAAQ,KAAMC,CAAU,CAAA,CAEjE,EACA,aAAe1C,GAAS,CACvB,MAAM0C,EAAa5C,EAAUE,CAAI,EAIjCoC,EAASK,GACRA,EAAE,SAAS,gBAAgBA,EAAE,MAAM,IAAI,QAAQ,KAAO,EAAGC,CAAU,CAAA,CAErE,EAEA,YAAY1C,EAAM,CACjB,KAAK,YAAYA,CAAI,CACtB,EACA,cAAcA,EAAM,CACnB,KAAK,aAAaA,CAAI,CACvB,EACA,WAAY,IACXyB,EACGI,EAAAA,eAAeJ,CAAM,EACrB,CAAE,KAAM,GAAI,KAAM,GAAI,QAAS,GAAM,eAAgB,CAAA,EACzD,QAAS,IAAMA,GAAQ,QAAA,GAAa,KACpC,YAAa,IAAM,CAClB,MAAMmB,MAAe,IACfC,MAAc,IACpB,OAAKpB,GACLA,EAAO,MAAM,IAAI,YAAaqB,GAAS,CAClCA,EAAK,KAAK,OAAS,gBAAkBA,EAAK,MAAM,IAAS,KAC5DF,EAAS,IAAI,OAAOE,EAAK,MAAM,EAAK,CAAC,EAErCA,EAAK,KAAK,OAAS,eACnBA,EAAK,MAAM,IAAS,MAEpBD,EAAQ,IAAI,OAAOC,EAAK,MAAM,EAAK,CAAC,CAEtC,CAAC,EACM,CAAE,SAAU,MAAM,KAAKF,CAAQ,EAAG,QAAS,MAAM,KAAKC,CAAO,CAAA,GAXhD,CAAE,SAAU,CAAA,EAAI,QAAS,EAAC,CAY/C,EAGA,kBAAmB,IAAM,CACxB,GAAI,CAACpB,EAAQ,MAAO,CAAE,KAAM,EAAG,GAAI,CAAA,EACnC,KAAM,CAAE,KAAAsB,EAAM,GAAAC,CAAA,EAAOvB,EAAO,MAAM,UAClC,MAAO,CAAE,KAAAsB,EAAM,GAAAC,CAAA,CAChB,EACA,iBAAkB,CAACC,EAAKjD,IAAS,CAChC,MAAM0C,EAAa5C,EAAUE,CAAI,EACjCoC,EAASK,GAAMA,EAAE,SAAS,gBAAgBQ,EAAKP,CAAU,CAAC,CAC3D,EACA,gBAAiB,IAAM,CACtB,GAAI,CAACjB,EAAQ,MAAO,GACpB,KAAM,CAAE,MAAAyB,GAAUzB,EACZ,CAAE,KAAAsB,EAAM,GAAAC,EAAI,MAAAG,CAAA,EAAUD,EAAM,UAClC,GAAI,CAACC,EACJ,OAAOD,EAAM,IAAI,YAAYH,EAAMC,EAAI,GAAG,EAI3C,MAAMI,EAAeF,EAAM,OAAO,MAAM,KACxC,GAAIE,EAAc,CACjB,MAAMC,EAAQC,GAAAA,aAAaJ,EAAM,IAAI,QAAQH,CAAI,EAAGK,CAAY,EAChE,GAAIC,EACH,OAAOH,EAAM,IAAI,YAAYG,EAAM,KAAMA,EAAM,GAAI,GAAG,CAExD,CACA,MAAO,EACR,EAGA,kBAAmB,KAAO,CACzB,MACC5B,GAAQ,QAAQ,gBAAgB,gBAChCA,GAAQ,UAAU,QAClB,EACD,MAAOnD,GAAiB,IAAA,GAIzB,kBAAoBiF,GACnB9B,EACG+B,EAAAA,sBAAsB/B,EAAQ8B,CAAS,EACvC,CAAE,KAAM,GAAI,KAAM,GAAI,QAAS,GAAM,eAAgB,CAAA,EAEzD,kBAAmB,CAACA,EAAWvD,IAAS,CACvC,MAAM0C,EAAa5C,EAAUE,CAAI,EACjCoC,EAASK,GAAMgB,EAAAA,0BAA0BhB,EAAGc,EAAWb,CAAU,CAAC,CACnE,EAEA,aAAea,GAAc,CAC5BnB,EAASK,GAAM,CACd,GAAIc,IAAc,OAAQ,CACzB,IAAIG,EAAYjB,EAAE,MAAM,IAAI,QAAQ,KAAO,EAC3CA,EAAE,MAAM,IAAI,YAAY,CAACK,EAAMG,KAE7BH,EAAK,KAAK,OAAS,kBACnBY,IAAcjB,EAAE,MAAM,IAAI,QAAQ,KAAO,IAEzCiB,EAAYT,EAAM,GAEZS,IAAcjB,EAAE,MAAM,IAAI,QAAQ,KAAO,EAChD,EACGiB,EAAY,IAAGA,EAAY,GAC/BjB,EAAE,QAAQ,MAAA,EAAQ,iBAAiBiB,CAAS,EAAE,IAAA,EAC9C,MACD,CACA,IAAIC,EAAY,GAChBlB,EAAE,MAAM,IAAI,YAAY,CAACK,EAAMG,IAAQ,CACtC,GAAIU,IAAc,GAAI,MAAO,GAE5Bb,EAAK,KAAK,OAAS,kBACnBA,EAAK,MAAM,YAAiBS,IAI5BI,EAAYV,EAAMH,EAAK,SAAW,EAEpC,CAAC,EACGa,IAAc,IACjBlB,EAAE,QAAQ,MAAA,EAAQ,iBAAiBkB,CAAS,EAAE,IAAA,CAEhD,CAAC,CACF,EAEA,aAAeJ,GAAc,CAC5BnB,EAASK,GAAMgB,EAAAA,0BAA0BhB,EAAGc,EAAW,SAAS,CAAC,CAClE,EAGA,eAAgB,IACf9B,EACGmC,EAAAA,mBAAmBnC,CAAM,EACzB,CAAE,KAAM,GAAI,KAAM,GAAI,QAAS,GAAM,eAAgB,CAAA,EACzD,eAAiBzB,GAAS,CACzB,MAAM0C,EAAa5C,EAAUE,CAAI,EACjCoC,EAASK,GAAMgB,EAAAA,0BAA0BhB,EAAG,OAAQC,CAAU,CAAC,CAChE,EACA,mBAAoB,CAACmB,EAAM1F,IAAa,CACvC,MAAM6B,EAAOS,EAAAA,sBACZX,EAAU+D,CAAI,EACd1F,EAAS,IAAK,IAAO,CACpB,GAAI,EAAE,GACN,QAAS2B,EAAU,EAAE,OAAO,CAAA,EAC3B,CAAA,EAEHsC,EAASK,GAAMA,EAAE,SAAS,WAAWzC,EAAM,CAAE,WAAY,EAAA,CAAM,CAAC,CACjE,EACA,kBAAoBA,GAAS,CAC5B,MAAM0C,EAAa5C,EAAUE,CAAI,EAKjCoC,EAASK,GAAM,CACd,MAAMqB,EAAcC,EAAAA,kBAAkBtB,EAAG,MAAM,EAC/CA,EAAE,SAAS,gBAAgBqB,EAAc,EAAGpB,EAAY,CACvD,aAAc,CAAE,mBAAoB,EAAA,CAAK,CACzC,CACF,CAAC,CACF,EACA,qBAAsB,CAACa,EAAWvD,IAAS,CAC1C,MAAM0C,EAAa5C,EAAUE,CAAI,EACjCoC,EAASK,GAAM,CACd,MAAMQ,EAAMe,EAAAA,oBAAoBvB,EAAGc,CAAS,EACxCN,IAAQ,IACXR,EAAE,SAAS,gBAAgBQ,EAAKP,EAAY,CAC3C,aAAc,CAAE,mBAAoB,EAAA,CAAK,CACzC,CACH,CAAC,CACF,EACA,mBAAoB,CAACa,EAAWvD,IAAS,CACxC,MAAM0C,EAAa5C,EAAUE,CAAI,EACjCoC,EAASK,GAAM,CACd,MAAMQ,EAAMc,EAAAA,kBAAkBtB,EAAGc,CAAS,EAC1Cd,EAAE,SAAS,gBAAgBQ,EAAKP,EAAY,CAC3C,aAAc,CAAE,mBAAoB,EAAA,CAAK,CACzC,CACF,CAAC,CACF,EAEA,iBAAkB,IACjBjB,EAASS,uBAAqBT,CAAM,EAAIP,EAAAA,qBACzC,QAAS,CACR,WAAY,IAAMO,GAAQ,MAAA,EAAQ,QAAQ,WAAA,EAAa,IAAA,EACvD,aAAc,IAAMA,GAAQ,MAAA,EAAQ,QAAQ,aAAA,EAAe,IAAA,EAC3D,gBAAiB,IAAMA,GAAQ,MAAA,EAAQ,QAAQ,gBAAA,EAAkB,IAAA,EACjE,aAAc,IAAMA,GAAQ,MAAA,EAAQ,QAAQ,aAAA,EAAe,IAAA,EAC3D,iBAAkB,IACjBA,GAAQ,MAAA,EAAQ,QAAQ,iBAAA,EAAmB,IAAA,EAC5C,kBAAmB,IAClBA,GAAQ,MAAA,EAAQ,QAAQ,kBAAA,EAAoB,IAAA,EAC7C,iBAAkB,IACjBA,GAAQ,MAAA,EAAQ,QAAQ,iBAAA,EAAmB,IAAA,EAC5C,gBAAiB,IAAMA,GAAQ,MAAA,EAAQ,QAAQ,gBAAA,EAAkB,IAAA,EACjE,aAAewC,GACdxC,GAAQ,MAAA,EAAQ,MAAA,EAAQ,aAAawC,CAAK,EAAE,IAAA,EAC7C,cAAgBC,GACfzC,GAAQ,MAAA,EAAQ,MAAA,EAAQ,cAAcyC,CAAI,EAAE,IAAA,EAC7C,YAAcC,GAAS1C,GAAQ,MAAA,EAAQ,MAAA,EAAQ,YAAY0C,CAAI,EAAE,IAAA,EACjE,SAAWC,GAAU3C,GAAQ,MAAA,EAAQ,MAAA,EAAQ,SAAS2C,CAAK,EAAE,IAAA,EAC7D,aAAeA,GACd3C,GAAQ,MAAA,EAAQ,MAAA,EAAQ,gBAAgB,CAAE,MAAA2C,CAAA,CAAO,EAAE,IAAA,EACpD,WAAY,IAAM3C,GAAQ,MAAA,EAAQ,QAAQ,WAAA,EAAa,IAAA,EACvD,eAAgB,IAAMA,GAAQ,MAAA,EAAQ,QAAQ,eAAA,EAAiB,IAAA,EAC/D,QAAS,CAAC4C,EAAMC,IAAS,CACnB7C,IACD6C,IAAS,OACZ7C,EACE,MAAA,EACA,MAAA,EACA,gBAAgB,MAAM,EACtB,QAAQ,CAAC,CAAE,GAAA8C,EAAI,MAAArB,CAAA,IAAY,CAC3B,KAAM,CAAE,KAAAH,EAAM,GAAAC,CAAA,EAAOuB,EAAG,UAClBnB,EAAeF,EAAM,OAAO,MAAM,KACxC,GAAI,CAACE,EAAc,MAAO,GAC1B,MAAMoB,GAAWtB,EAAM,OAAO,KAAKoB,EAAM,CACxClB,EAAa,OAAO,CAAE,KAAAiB,CAAA,CAAM,CAAA,CAC5B,EACKI,GAAQvB,EAAM,OAAO,KAAK,GAAG,EACnC,OAAAqB,EAAG,YAAYxB,EAAMC,EAAI,CAACwB,GAAUC,EAAK,CAAC,EACnC,EACR,CAAC,EACA,IAAA,EAEFhD,EACE,MAAA,EACA,MAAA,EACA,gBAAgB,MAAM,EACtB,QAAQ,CAAE,KAAA4C,EAAM,EAChB,cAAc,GAAG,EACjB,IAAA,EAEJ,EACA,WAAaA,GACZ5C,GACG,MAAA,EACD,MAAA,EACA,gBAAgB,MAAM,EACtB,QAAQ,CAAE,KAAA4C,CAAA,CAAM,EAChB,IAAA,EACH,WAAY,IACX5C,GAAQ,MAAA,EAAQ,MAAA,EAAQ,gBAAgB,MAAM,EAAE,UAAA,EAAY,IAAA,EAC7D,YAAciD,GACbjD,GAAQ,MAAA,EAAQ,MAAA,EAAQ,cAAciD,CAAK,EAAE,IAAA,EAC9C,eAAiBC,GAChBlD,GAAQ,MAAA,EAAQ,MAAA,EAAQ,cAAc,KAAKkD,CAAY,IAAI,EAAE,IAAA,EAC9D,WAAa3E,GAASyB,GAAQ,SAAS,cAAc3B,EAAUE,CAAI,CAAC,EACpE,KAAM,IAAMyB,GAAQ,MAAA,EAAQ,QAAQ,KAAA,EAAO,IAAA,EAC3C,KAAM,IAAMA,GAAQ,MAAA,EAAQ,QAAQ,KAAA,EAAO,IAAA,EAC3C,QAAS,IAAMA,GAAQ,IAAA,EAAM,QAAU,GACvC,QAAS,IAAMA,GAAQ,IAAA,EAAM,QAAU,GACvC,kBAAmB,IAClBA,GAAQ,MAAA,EAAQ,QAAQ,kBAAA,EAAoB,IAAA,EAC7C,gBAAiB,IAAMA,GAAQ,MAAA,EAAQ,QAAQ,gBAAA,EAAkB,IAAA,EACjE,YAAcmD,GAAQnD,GAAQ,MAAA,EAAQ,MAAA,EAAQ,SAAS,CAAE,IAAAmD,CAAA,CAAK,EAAE,IAAA,CAAI,EAIrE,KAAMxG,GAAU,SACb,CACA,QAAS,IAAOqD,EAASO,mBAAiBP,CAAM,EAAI,GACpD,QAAUoD,GAAQzC,EAASK,GAAMqC,mBAAiBrC,EAAGoC,CAAG,CAAC,EACzD,MAAO,IAAM9C,EAAAA,UAAUN,EAASO,EAAAA,iBAAiBP,CAAM,EAAI,EAAE,EAC7D,QAAS,IACRM,EAAAA,UAAUN,EAASO,EAAAA,iBAAiBP,CAAM,EAAI,EAAE,EAAE,MACnD,OAAQ,CAACsD,EAAS,IACjB3C,EAASK,GAAM,CACd,KAAM,CAAE,MAAAuC,EAAO,MAAAC,CAAA,EAAUlD,EAAAA,UAAUC,EAAAA,iBAAiBS,CAAC,CAAC,EAClD,CAACuC,GAASC,IAAU,MACxBH,EAAAA,iBAAiBrC,EAAG,KAAK,UAAUwC,EAAO,KAAMF,CAAM,CAAC,CACxD,CAAC,EACF,OAAQ,IACP3C,EAAS,GAAM,CACd,KAAM,CAAE,MAAA4C,EAAO,MAAAC,CAAA,EAAUlD,EAAAA,UAAUC,EAAAA,iBAAiB,CAAC,CAAC,EAClD,CAACgD,GAASC,IAAU,MACxBH,EAAAA,iBAAiB,EAAG,KAAK,UAAUG,CAAK,CAAC,CAC1C,CAAC,CAAA,EAEF,MAAA,GAGJ,CAACxD,CAAM,CAAA,EAMR,MAAMyD,GAAqB,IAAM,CAChC,GAAI,CAACzD,EAAQ,OACb,KAAM,CAAE,MAAAuD,EAAO,MAAAC,CAAA,EAAUlD,EAAAA,UAAUC,EAAAA,iBAAiBP,CAAM,CAAC,EACvD,CAACuD,GAASC,IAAU,MACxBH,EAAAA,iBAAiBrD,EAAQ,KAAK,UAAUwD,EAAO,KAAM,CAAC,CAAC,CACxD,EACME,GAAiB,IAAM,CACvB1D,IACA,UAAU,WAAW,UAAUO,EAAAA,iBAAiBP,CAAM,CAAC,EAC5DnB,EAAc,EAAI,EAClB,WAAW,IAAMA,EAAc,EAAK,EAAG,IAAI,EAC5C,EAEA,OAAKmB,EAGJ2D,EAAAA,KAACC,EAAAA,eAAA,CACA,UAAAjG,GACA,UAAAC,GACA,gBAAiB,CAACjB,GAAU,UAC5B,SAAUsB,EACV,MAAA/B,GACA,UAAA2B,GAEC,SAAA,CAAAI,UACC4F,gBAAA,CACA,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,OAAI,EAC5CH,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACd,SAAA,CAAAA,EAAAA,KAAC,SAAA,CACA,KAAK,SACL,QAASF,GACT,SAAU,CAAC,CAAChF,EACZ,MAAM,cAEN,SAAA,CAAAqF,EAAAA,IAACC,GAAAA,QAAA,CAAa,KAAM,EAAA,CAAI,EACxBD,EAAAA,IAACE,EAAAA,aAAY,SAAA,UAAA,CAAQ,CAAA,CAAA,CAAA,SAErB,SAAA,CAAO,KAAK,SAAS,QAASN,GAAgB,MAAM,YACpD,SAAA,CAAAI,EAAAA,IAACG,GAAAA,QAAA,CAAK,KAAM,EAAA,CAAI,EACfrF,IAAckF,EAAAA,IAACE,EAAAA,YAAA,CAAY,SAAA,QAAA,CAAM,CAAA,CAAA,CACnC,CAAA,CAAA,CACD,CAAA,EACD,EAEDF,MAACI,EAAAA,eAAc,OAAAlE,EAAgB,EAC/B8D,EAAAA,IAACK,GAAAA,eAAA,CAAe,OAAAnE,EAAgB,kBAAmB7C,IAAM,cAAe,EACvEc,GAAcQ,EACdT,EACCA,EAAgBS,CAAS,SAExB2F,eAAA,CACC,SAAA,CAAA3F,EAAU,MAAQ,MAClBkF,EAAAA,KAAC,SAAA,CAAO,SAAA,CAAA,QACDlF,EAAU,KACfA,EAAU,QAAU,KAAO,YAAYA,EAAU,MAAM,GAAK,GAAG,IAC9D,GAAA,EACH,EAEAA,EAAU,KAAA,CAAA,CACZ,EAEE,IAAA,CAAA,CAAA,EAhDc,IAmDrB,EAEa4F,EAAYC,EAAAA,WACxBhI,EACD,EACA+H,EAAU,YAAc"}
1
+ {"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport { BodyCaption } from '@src/components/TypographyStyle';\nimport { Copy, WandSparkles } from '../icons';\nimport {\n\tBikEditorShell,\n\tBikJsonError,\n\tBikJsonHeader,\n} from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n\tJsonParseResult,\n} from './BikEditor.types';\nimport {\n\tbuildJsonCodeBlockHtml,\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tgetCodeBlockText,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tparseJson,\n\tsetCodeBlockText,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tcharacterLimit,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t\trenderJsonError,\n\t} = props;\n\n\tconst isJsonMode = !!features?.jsonMode;\n\n\t// Live JSON parse error, shown inside the editor when jsonMode is on.\n\t// null = valid (or not applicable) → nothing rendered.\n\tconst [jsonError, setJsonError] = useState<JsonParseResult | null>(null);\n\t// Transient \"Copied\" state for the jsonMode copy button.\n\tconst [jsonCopied, setJsonCopied] = useState(false);\n\n\t// JSON body mode: treat initialContent as raw JSON text and wrap it in a code\n\t// block. Skips section/HTML normalisation entirely.\n\tconst initialEditorContent = isJsonMode\n\t\t? buildJsonCodeBlockHtml(initialContent ?? '')\n\t\t: sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst prevFormatsRef = useRef<FormatState>(DEFAULT_FORMAT_STATE);\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\tcharacterLimit,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\tremoveMentionTriggerOnDismiss: mentions?.removeTriggerOnDismiss,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t\tif (isJsonMode) {\n\t\t\t\tconst result = parseJson(getCodeBlockText(e));\n\t\t\t\tsetJsonError(result.valid ? null : result);\n\t\t\t}\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tconst next = extractActiveFormats(e);\n\t\t\tconst prev = prevFormatsRef.current;\n\t\t\tconst changed =\n\t\t\t\tprev.bold !== next.bold ||\n\t\t\t\tprev.italic !== next.italic ||\n\t\t\t\tprev.underline !== next.underline ||\n\t\t\t\tprev.strike !== next.strike ||\n\t\t\t\tprev.bulletList !== next.bulletList ||\n\t\t\t\tprev.orderedList !== next.orderedList ||\n\t\t\t\tprev.blockquote !== next.blockquote ||\n\t\t\t\tprev.codeBlock !== next.codeBlock ||\n\t\t\t\tprev.superscript !== next.superscript ||\n\t\t\t\tprev.subscript !== next.subscript ||\n\t\t\t\tprev.textAlign !== next.textAlign ||\n\t\t\t\tprev.fontFamily !== next.fontFamily ||\n\t\t\t\tprev.fontSize !== next.fontSize ||\n\t\t\t\tprev.color !== next.color ||\n\t\t\t\tprev.highlight !== next.highlight ||\n\t\t\t\tprev.link?.href !== next.link?.href;\n\t\t\tif (changed) {\n\t\t\t\tprevFormatsRef.current = next;\n\t\t\t\tonSelectionChangeRef.current?.(next);\n\t\t\t}\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t\t// Surface an error for invalid initialContent immediately on mount.\n\t\tif (isJsonMode) {\n\t\t\tconst result = parseJson(getCodeBlockText(editor));\n\t\t\tsetJsonError(result.valid ? null : result);\n\t\t}\n\t}, [editor, isJsonMode]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1)\n\t\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\n\t\t\t// ── JSON body ─────────────────────────────────────────────────────\n\t\t\tjson: features?.jsonMode\n\t\t\t\t? {\n\t\t\t\t\t\tgetText: () => (editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tsetText: (raw) => enqueue((e) => setCodeBlockText(e, raw)),\n\t\t\t\t\t\tparse: () => parseJson(editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tisValid: () =>\n\t\t\t\t\t\t\tparseJson(editor ? getCodeBlockText(editor) : '').valid,\n\t\t\t\t\t\tformat: (indent = 2) =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value, null, indent));\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tminify: () =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value));\n\t\t\t\t\t\t\t}),\n\t\t\t\t }\n\t\t\t\t: undefined,\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\t// ── jsonMode floating actions ────────────────────────────────────────────\n\t// Beautify pretty-prints in place (no-op / disabled while the JSON is broken);\n\t// Copy writes the raw text to the clipboard with transient feedback.\n\tconst handleJsonBeautify = () => {\n\t\tif (!editor) return;\n\t\tconst { valid, value } = parseJson(getCodeBlockText(editor));\n\t\tif (!valid || value === null) return;\n\t\tsetCodeBlockText(editor, JSON.stringify(value, null, 2));\n\t};\n\tconst handleJsonCopy = () => {\n\t\tif (!editor) return;\n\t\tvoid navigator.clipboard?.writeText(getCodeBlockText(editor));\n\t\tsetJsonCopied(true);\n\t\tsetTimeout(() => setJsonCopied(false), 1500);\n\t};\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tjsonMode={isJsonMode}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t{isJsonMode && (\n\t\t\t\t<BikJsonHeader>\n\t\t\t\t\t<span className=\"bik-json-header-label\">JSON</span>\n\t\t\t\t\t<div className=\"bik-json-header-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={handleJsonBeautify}\n\t\t\t\t\t\t\tdisabled={!!jsonError}\n\t\t\t\t\t\t\ttitle=\"Format JSON\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<WandSparkles size={16} />\n\t\t\t\t\t\t\t<BodyCaption>Beautify</BodyCaption>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button type=\"button\" onClick={handleJsonCopy} title=\"Copy JSON\">\n\t\t\t\t\t\t\t<Copy size={16} />\n\t\t\t\t\t\t\t{jsonCopied && <BodyCaption>Copied</BodyCaption>}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</BikJsonHeader>\n\t\t\t)}\n\t\t\t<EditorContent editor={editor} />\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t\t{isJsonMode && jsonError ? (\n\t\t\t\trenderJsonError ? (\n\t\t\t\t\trenderJsonError(jsonError)\n\t\t\t\t) : (\n\t\t\t\t\t<BikJsonError>\n\t\t\t\t\t\t{jsonError.line != null && (\n\t\t\t\t\t\t\t<strong>\n\t\t\t\t\t\t\t\tLine {jsonError.line}\n\t\t\t\t\t\t\t\t{jsonError.column != null ? `, column ${jsonError.column}` : ''}\n\t\t\t\t\t\t\t\t:{' '}\n\t\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{jsonError.error}\n\t\t\t\t\t</BikJsonError>\n\t\t\t\t)\n\t\t\t) : null}\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","k","v","c","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","characterLimit","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","renderJsonError","isJsonMode","jsonError","setJsonError","useState","jsonCopied","setJsonCopied","initialEditorContent","buildJsonCodeBlockHtml","buildSectionedContent","normalizeHtml","s","pendingQueue","useRef","hasCalledOnReady","onReadyRef","onChangeRef","onSelectionChangeRef","prevFormatsRef","DEFAULT_FORMAT_STATE","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","teamMentionsRef","slashCommandsRef","editor","useEditor","buildExtensions","snapshot","extractContent","result","parseJson","getCodeBlockText","next","extractActiveFormats","prev","enqueue","op","useEffect","useImperativeHandle","position","e","html","normalised","insertInlineHtml","agentIds","teamIds","node","from","to","pos","state","empty","linkMarkType","range","getMarkRange","sectionId","extractSectionContent","setSectionContentInEditor","endOfBody","targetPos","extractBodyContent","body","boundaryPos","findSectionEndPos","findSectionStartPos","align","font","size","color","href","text","tr","linkNode","space","emoji","variableName","src","raw","setCodeBlockText","indent","valid","value","handleJsonBeautify","handleJsonCopy","jsxs","BikEditorShell","BikJsonHeader","jsx","WandSparkles","BodyCaption","Copy","EditorContent","LinkBubbleMenu","BikJsonError","BikEditor","forwardRef"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("../node_modules/prosemirror-model/dist/index.js"),x=require("../helpers/sanitize.js"),S=require("./extensions/plainClipboard/pasteUtils.js");function h(e,n=x.sanitizeEmailHtml){if(!e||typeof document>"u")return e;const i=document.createElement("div");return i.innerHTML=n(e),i.querySelectorAll("span").forEach(t=>{const o=t.getAttribute("data-type");if(t.hasAttribute("style")||t.hasAttribute("data-variable")||o!==null&&o.startsWith("mention"))return;const r=t.parentNode;if(r){for(;t.firstChild;)r.insertBefore(t.firstChild,t);r.removeChild(t)}}),i.querySelectorAll("p").forEach(t=>{t.querySelectorAll("br").length===1&&(t.textContent??"").trim()===""&&(t.innerHTML="")}),i.innerHTML}function u(e){const n=document.createElement("div");n.innerHTML=e;const i=document.createTreeWalker(n,NodeFilter.SHOW_TEXT);let t;for(;t=i.nextNode();)t.nodeValue&&t.nodeValue.includes(" ")&&(t.nodeValue=t.nodeValue.replace(/ {2}/g,"  "));const o=n.querySelectorAll("p");for(const r of Array.from(o)){if(r.childNodes.length===0){r.appendChild(document.createElement("br"));continue}r.lastChild instanceof HTMLBRElement&&r.childNodes.length>1&&r.appendChild(document.createElement("br"))}return n.innerHTML}function A(e,n){const i=h(n),t=document.createElement("div");t.innerHTML=i;const o=a.DOMParser.fromSchema(e.schema).parseSlice(t,{preserveWhitespace:!0});if(o.size===0)return;const{from:r,to:c}=e.state.selection,s=e.state.tr.replaceRange(r,c,o);e.view.dispatch(s)}const d=e=>`<div data-section-divider="${e}" style="display:none;height:0;line-height:0;overflow:hidden;"></div>`;function C(e,n){let i=e;for(const t of n)i+=d(t.id)+t.content;return i}function p(e){return e?g(e).get("body")??e:""}function H(e){if(!e)return"";const n=p(e);return e.substring(n.length)}function g(e){const n=new Map,i=/<div[^>]*data-section-divider="([^"]*)[^>]*>\s*<\/div>/g,t=[];let o;for(;(o=i.exec(e))!==null;)t.push({id:o[1],index:o.index,endIndex:o.index+o[0].length});if(t.length===0)return n.set("body",e),n;n.set("body",e.slice(0,t[0].index));for(let r=0;r<t.length;r++){const c=t[r].endIndex,s=r+1<t.length?t[r+1].index:e.length;n.set(t[r].id,e.slice(c,s))}return n}function v(e,n){const i=f(e,n);if(i===-1)return{html:"",text:"",isEmpty:!0,characterCount:0};const t=m(e,n),o=e.state.doc.slice(i,t),r=document.createElement("div"),c=a.DOMSerializer.fromSchema(e.schema);r.appendChild(c.serializeFragment(o.content));const s=u(r.innerHTML),l=r.textContent??"";return{html:s,text:l,isEmpty:!l.trim(),characterCount:l.length}}function k(e,n){const i=document.createElement("div");return i.innerHTML=n,a.DOMParser.fromSchema(e.schema).parse(i,{preserveWhitespace:!0}).content}function T(e,n,i){const t=f(e,n);if(t===-1){const l=e.state.doc.content.size,y=d(n)+i;e.commands.insertContentAt(l,y,{updateSelection:!1});return}const o=m(e,n),r=k(e,i),{tr:c}=e.state,s=n==="body"?0:t;c.replaceWith(s,o,r),c.setMeta("addToHistory",!1),e.view.dispatch(c)}function E(e){return v(e,"body")}function B(e){return{bold:e.isActive("bold"),italic:e.isActive("italic"),underline:e.isActive("underline"),strike:e.isActive("strike"),bulletList:e.isActive("bulletList"),orderedList:e.isActive("orderedList"),blockquote:e.isActive("blockquote"),codeBlock:e.isActive("codeBlock"),link:(()=>{if(e.isActive("link"))return{href:e.getAttributes("link").href??""};const{$from:n}=e.state.selection;if(n.pos>0){const t=n.doc.resolve(n.pos).marks().find(o=>o.type.name==="link");if(t)return{href:t.attrs.href??""};{const r=n.nodeBefore?.marks.find(c=>c.type.name==="link");if(r)return{href:r.attrs.href??""}}}return null})(),textAlign:e.isActive({textAlign:"center"})?"center":e.isActive({textAlign:"right"})?"right":e.isActive({textAlign:"justify"})?"justify":e.isActive({textAlign:"left"})?"left":null,fontFamily:e.getAttributes("textStyle").fontFamily??null,fontSize:e.getAttributes("textStyle").fontSize??null,color:e.getAttributes("textStyle").color??null,highlight:e.isActive("highlight")?e.getAttributes("highlight").color??"default":null,superscript:e.isActive("superscript"),subscript:e.isActive("subscript")}}function M(e){const n=u(e.getHTML()),i=S.normalizeHardBreaks(e.state.doc.content),t=e.schema.node("doc",null,i),o=t.textBetween(0,t.content.size,`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("../node_modules/prosemirror-model/dist/index.js"),x=require("./extensions/plainClipboard/pasteUtils.js");function h(e){if(!e||typeof document>"u")return e;const t=document.createElement("div");return t.innerHTML=e,t.querySelectorAll("span").forEach(i=>{const n=i.getAttribute("data-type");if(i.hasAttribute("style")||i.hasAttribute("data-variable")||n!==null&&n.startsWith("mention"))return;const r=i.parentNode;if(r){for(;i.firstChild;)r.insertBefore(i.firstChild,i);r.removeChild(i)}}),t.querySelectorAll("p").forEach(i=>{i.querySelectorAll("br").length===1&&(i.textContent??"").trim()===""&&(i.innerHTML="")}),t.innerHTML}function u(e){const t=document.createElement("div");t.innerHTML=e;const i=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);let n;for(;n=i.nextNode();)n.nodeValue&&n.nodeValue.includes(" ")&&(n.nodeValue=n.nodeValue.replace(/ {2}/g,"  "));const r=t.querySelectorAll("p");for(const o of Array.from(r)){if(o.childNodes.length===0){o.appendChild(document.createElement("br"));continue}o.lastChild instanceof HTMLBRElement&&o.childNodes.length>1&&o.appendChild(document.createElement("br"))}return t.innerHTML}function S(e,t){const i=h(t),n=document.createElement("div");n.innerHTML=i;const r=a.DOMParser.fromSchema(e.schema).parseSlice(n,{preserveWhitespace:!0});if(r.size===0)return;const{from:o,to:c}=e.state.selection,s=e.state.tr.replaceRange(o,c,r);e.view.dispatch(s)}const d=e=>`<div data-section-divider="${e}" style="display:none;height:0;line-height:0;overflow:hidden;"></div>`;function A(e,t){let i=e;for(const n of t)i+=d(n.id)+n.content;return i}function p(e){return e?g(e).get("body")??e:""}function C(e){if(!e)return"";const t=p(e);return e.substring(t.length)}function g(e){const t=new Map,i=/<div[^>]*data-section-divider="([^"]*)[^>]*>\s*<\/div>/g,n=[];let r;for(;(r=i.exec(e))!==null;)n.push({id:r[1],index:r.index,endIndex:r.index+r[0].length});if(n.length===0)return t.set("body",e),t;t.set("body",e.slice(0,n[0].index));for(let o=0;o<n.length;o++){const c=n[o].endIndex,s=o+1<n.length?n[o+1].index:e.length;t.set(n[o].id,e.slice(c,s))}return t}function v(e,t){const i=f(e,t);if(i===-1)return{html:"",text:"",isEmpty:!0,characterCount:0};const n=m(e,t),r=e.state.doc.slice(i,n),o=document.createElement("div"),c=a.DOMSerializer.fromSchema(e.schema);o.appendChild(c.serializeFragment(r.content));const s=u(o.innerHTML),l=o.textContent??"";return{html:s,text:l,isEmpty:!l.trim(),characterCount:l.length}}function H(e,t){const i=document.createElement("div");return i.innerHTML=t,a.DOMParser.fromSchema(e.schema).parse(i,{preserveWhitespace:!0}).content}function k(e,t,i){const n=f(e,t);if(n===-1){const l=e.state.doc.content.size,y=d(t)+i;e.commands.insertContentAt(l,y,{updateSelection:!1});return}const r=m(e,t),o=H(e,i),{tr:c}=e.state,s=t==="body"?0:n;c.replaceWith(s,r,o),c.setMeta("addToHistory",!1),e.view.dispatch(c)}function T(e){return v(e,"body")}function E(e){return{bold:e.isActive("bold"),italic:e.isActive("italic"),underline:e.isActive("underline"),strike:e.isActive("strike"),bulletList:e.isActive("bulletList"),orderedList:e.isActive("orderedList"),blockquote:e.isActive("blockquote"),codeBlock:e.isActive("codeBlock"),link:(()=>{if(e.isActive("link"))return{href:e.getAttributes("link").href??""};const{$from:t}=e.state.selection;if(t.pos>0){const n=t.doc.resolve(t.pos).marks().find(r=>r.type.name==="link");if(n)return{href:n.attrs.href??""};{const o=t.nodeBefore?.marks.find(c=>c.type.name==="link");if(o)return{href:o.attrs.href??""}}}return null})(),textAlign:e.isActive({textAlign:"center"})?"center":e.isActive({textAlign:"right"})?"right":e.isActive({textAlign:"justify"})?"justify":e.isActive({textAlign:"left"})?"left":null,fontFamily:e.getAttributes("textStyle").fontFamily??null,fontSize:e.getAttributes("textStyle").fontSize??null,color:e.getAttributes("textStyle").color??null,highlight:e.isActive("highlight")?e.getAttributes("highlight").color??"default":null,superscript:e.isActive("superscript"),subscript:e.isActive("subscript")}}function B(e){const t=u(e.getHTML()),i=x.normalizeHardBreaks(e.state.doc.content),n=e.schema.node("doc",null,i),r=n.textBetween(0,n.content.size,`
2
2
 
3
3
  `,`
4
- `);return{html:n,text:o,isEmpty:e.isEmpty,characterCount:o.length}}function f(e,n){if(n==="body")return 1;let i=-1;return e.state.doc.descendants((t,o)=>{if(i!==-1)return!1;t.type.name==="sectionDivider"&&t.attrs.sectionId===n&&(i=o+t.nodeSize)}),i}function m(e,n){const i=e.state.doc,t=i.content.size;if(n==="body"){let c=-1;return i.descendants((s,l)=>{if(c!==-1)return!1;s.type.name==="sectionDivider"&&(c=l)}),c!==-1?c:t}let o=!1,r=-1;return i.descendants((c,s)=>{if(r!==-1)return!1;if(!o)return c.type.name==="sectionDivider"&&c.attrs.sectionId===n&&(o=!0),!1;c.type.name==="sectionDivider"&&(r=s)}),r!==-1?r:t}function P(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function b(e){return`<pre><code>${P(e??"")}</code></pre>`}function z(e){let n="",i=!1;return e.state.doc.descendants(t=>{if(i)return!1;if(t.type.name==="codeBlock")return n=t.textContent,i=!0,!1}),n}function L(e,n){e.commands.setContent(b(n),{emitUpdate:!0})}function D(e,n){const t=e.slice(0,Math.max(0,n)).split(`
5
- `);return{line:t.length,column:(t[t.length-1]?.length??0)+1}}function N(e,n){const i=e.replace(/\s*in JSON at position[\s\S]*$/i,"").trim()||e,t=e.match(/line (\d+) column (\d+)/i);if(t)return{message:i,line:Number(t[1]),column:Number(t[2])};const o=e.match(/position (\d+)/i);if(o){const{line:r,column:c}=D(n,Number(o[1]));return{message:i,line:r,column:c}}return{message:i,line:null,column:null}}function I(e){if(!e.trim())return{valid:!0,value:null,error:null,line:null,column:null};try{return{valid:!0,value:JSON.parse(e),error:null,line:null,column:null}}catch(n){const{message:i,line:t,column:o}=N(n.message,e);return{valid:!1,value:null,error:i,line:t,column:o}}}exports.SECTION_DIVIDER_HTML=d;exports.buildJsonCodeBlockHtml=b;exports.buildSectionedContent=C;exports.extractActiveFormats=B;exports.extractAllSectionsFromHtml=g;exports.extractBodyContent=E;exports.extractContent=M;exports.extractSectionContent=v;exports.findSectionEndPos=m;exports.findSectionStartPos=f;exports.getBodyHtml=p;exports.getCodeBlockText=z;exports.getSectionsHtml=H;exports.insertInlineHtml=A;exports.normalizeHtml=h;exports.parseJson=I;exports.setCodeBlockText=L;exports.setSectionContentInEditor=T;exports.toPortableHtml=u;
4
+ `);return{html:t,text:r,isEmpty:e.isEmpty,characterCount:r.length}}function f(e,t){if(t==="body")return 1;let i=-1;return e.state.doc.descendants((n,r)=>{if(i!==-1)return!1;n.type.name==="sectionDivider"&&n.attrs.sectionId===t&&(i=r+n.nodeSize)}),i}function m(e,t){const i=e.state.doc,n=i.content.size;if(t==="body"){let c=-1;return i.descendants((s,l)=>{if(c!==-1)return!1;s.type.name==="sectionDivider"&&(c=l)}),c!==-1?c:n}let r=!1,o=-1;return i.descendants((c,s)=>{if(o!==-1)return!1;if(!r)return c.type.name==="sectionDivider"&&c.attrs.sectionId===t&&(r=!0),!1;c.type.name==="sectionDivider"&&(o=s)}),o!==-1?o:n}function M(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function b(e){return`<pre><code>${M(e??"")}</code></pre>`}function P(e){let t="",i=!1;return e.state.doc.descendants(n=>{if(i)return!1;if(n.type.name==="codeBlock")return t=n.textContent,i=!0,!1}),t}function L(e,t){e.commands.setContent(b(t),{emitUpdate:!0})}function z(e,t){const n=e.slice(0,Math.max(0,t)).split(`
5
+ `);return{line:n.length,column:(n[n.length-1]?.length??0)+1}}function D(e,t){const i=e.replace(/\s*in JSON at position[\s\S]*$/i,"").trim()||e,n=e.match(/line (\d+) column (\d+)/i);if(n)return{message:i,line:Number(n[1]),column:Number(n[2])};const r=e.match(/position (\d+)/i);if(r){const{line:o,column:c}=z(t,Number(r[1]));return{message:i,line:o,column:c}}return{message:i,line:null,column:null}}function N(e){if(!e.trim())return{valid:!0,value:null,error:null,line:null,column:null};try{return{valid:!0,value:JSON.parse(e),error:null,line:null,column:null}}catch(t){const{message:i,line:n,column:r}=D(t.message,e);return{valid:!1,value:null,error:i,line:n,column:r}}}exports.SECTION_DIVIDER_HTML=d;exports.buildJsonCodeBlockHtml=b;exports.buildSectionedContent=A;exports.extractActiveFormats=E;exports.extractAllSectionsFromHtml=g;exports.extractBodyContent=T;exports.extractContent=B;exports.extractSectionContent=v;exports.findSectionEndPos=m;exports.findSectionStartPos=f;exports.getBodyHtml=p;exports.getCodeBlockText=P;exports.getSectionsHtml=C;exports.insertInlineHtml=S;exports.normalizeHtml=h;exports.parseJson=N;exports.setCodeBlockText=L;exports.setSectionContentInEditor=k;exports.toPortableHtml=u;
6
6
  //# sourceMappingURL=BikEditor.utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BikEditor.utils.js","sources":["../../../src/editor/BikEditor.utils.ts"],"sourcesContent":["import { Editor } from '@tiptap/core';\nimport { DOMParser, DOMSerializer } from 'prosemirror-model';\nimport { sanitizeEmailHtml } from '../helpers/sanitize';\nimport {\n\tEditorSnapshot,\n\tFormatState,\n\tJsonParseResult,\n} from './BikEditor.types';\nimport { normalizeHardBreaks } from './extensions/plainClipboard/pasteUtils';\n\n// ---------------------------------------------------------------------------\n// HTML normalisation\n// ---------------------------------------------------------------------------\n\n/**\n * Normalise HTML before passing it to TipTap.\n *\n * 1. Unwrap style-less `<span>` wrappers (plain spans, and editor-cursor spans\n * like Quill's `<span class=\"ql-cursor\">`). Spans that carry inline styling\n * (`color` / `font-family` / `font-size` render as styled spans) or that\n * represent a `{{variable}}` token are PRESERVED — otherwise a setContent\n * round-trip would silently drop colour/font formatting that paste keeps.\n * 2. Collapse placeholder paragraphs (`<p><br></p>`) to `<p></p>`. ProseMirror\n * parses `<p></p>` as an empty paragraph and adds its own DOM `<br>` for the\n * cursor — one blank line, correct height. Leaving the source `<br>` would\n * create a `hard_break` child AND the cursor `<br>` → double-height blank line.\n *\n * Uses the DOM (regex cannot selectively pair span tags). `normalizeHtml` runs\n * in the component body for `initialContent`, so it is guarded for SSR: the\n * editor is created lazily on the client (`immediatelyRender: false`), meaning\n * the value is only parsed client-side and passing through on the server is safe.\n */\nexport function normalizeHtml(\n\thtml: string,\n\tsanitizer: (input: string) => string = sanitizeEmailHtml,\n): string {\n\tif (!html || typeof document === 'undefined') return html;\n\n\t// Security boundary: every HTML string entering the editor (initialContent,\n\t// setContent, insertHtml, setBody/SectionContent) passes through here.\n\t// Sanitise BEFORE ProseMirror parses it — the schema drops unknown nodes,\n\t// but does NOT validate attributes it keeps (link href / image src), so we\n\t// strip scripts/handlers/dangerous schemes up front.\n\t// Email channels use sanitizeEmailHtml (tables, images, inline style);\n\t// non-email channels (WhatsApp, IG, private note) use sanitizeBasicHtml\n\t// (formatting allowlist only — no tables/images/style).\n\tconst container = document.createElement('div');\n\tcontainer.innerHTML = sanitizer(html);\n\n\tcontainer.querySelectorAll('span').forEach((span) => {\n\t\t// Keep schema-backed spans: styled spans, variables, and mention chips\n\t\t// (`data-type=\"mention…\"`). Stripping a mention span would drop the\n\t\t// `data-id`/`data-label`/`data-kind` the editor needs to reparse it.\n\t\tconst dataType = span.getAttribute('data-type');\n\t\tif (\n\t\t\tspan.hasAttribute('style') ||\n\t\t\tspan.hasAttribute('data-variable') ||\n\t\t\t(dataType !== null && dataType.startsWith('mention'))\n\t\t)\n\t\t\treturn;\n\t\tconst parent = span.parentNode;\n\t\tif (!parent) return;\n\t\twhile (span.firstChild) parent.insertBefore(span.firstChild, span);\n\t\tparent.removeChild(span);\n\t});\n\n\tcontainer.querySelectorAll('p').forEach((p) => {\n\t\tif (\n\t\t\tp.querySelectorAll('br').length === 1 &&\n\t\t\t(p.textContent ?? '').trim() === ''\n\t\t) {\n\t\t\tp.innerHTML = '';\n\t\t}\n\t});\n\n\treturn container.innerHTML;\n}\n\n/**\n * Make editor HTML portable across email clients and chat renderers.\n *\n * 1. Preserve consecutive spaces by converting every second space in a run\n * to `&nbsp;` (U+00A0). Standard HTML collapses adjacent regular spaces;\n * alternating with `&nbsp;` prevents that — same convention Gmail uses.\n * 2. Double a trailing `<br>` in content paragraphs so the blank line is\n * visible. A single trailing `<br>` before `</p>` is swallowed by most\n * email clients; `<br><br>` renders as a visible blank line (matches\n * Gmail's output).\n * 3. Convert empty `<p></p>` to `<p><br></p>` — email clients collapse\n * zero-height paragraphs without a `<br>`.\n */\nexport function toPortableHtml(html: string): string {\n\tconst div = document.createElement('div');\n\tdiv.innerHTML = html;\n\n\t// TreeWalker visits only text nodes, skipping HTML tags/attributes, so we safely\n\t// replace consecutive spaces with space + \\u00a0 (nbsp) to prevent email clients from collapsing them\n\tconst walker = document.createTreeWalker(div, NodeFilter.SHOW_TEXT);\n\tlet textNode: Text | null;\n\twhile ((textNode = walker.nextNode() as Text | null)) {\n\t\tif (textNode.nodeValue && textNode.nodeValue.includes(' ')) {\n\t\t\ttextNode.nodeValue = textNode.nodeValue.replace(/ {2}/g, '  ');\n\t\t}\n\t}\n\n\tconst blocks = div.querySelectorAll('p');\n\tfor (const p of Array.from(blocks)) {\n\t\tif (p.childNodes.length === 0) {\n\t\t\tp.appendChild(document.createElement('br'));\n\t\t\tcontinue;\n\t\t}\n\t\tconst last = p.lastChild;\n\t\tif (last instanceof HTMLBRElement && p.childNodes.length > 1) {\n\t\t\tp.appendChild(document.createElement('br'));\n\t\t}\n\t}\n\treturn div.innerHTML;\n}\n\n// ---------------------------------------------------------------------------\n// Inline content insertion\n// ---------------------------------------------------------------------------\n\n/**\n * Insert HTML at the current cursor position, merging the first paragraph\n * inline while preserving the block structure of subsequent paragraphs/lists.\n *\n * Uses `parseSlice` which returns an open-ended Slice — the first block merges\n * at the cursor, middle blocks stay intact, and the last block merges with any\n * text that follows the cursor.\n */\nexport function insertInlineHtml(editor: Editor, html: string): void {\n\tconst normalised = normalizeHtml(html);\n\tconst dom = document.createElement('div');\n\tdom.innerHTML = normalised;\n\tconst slice = DOMParser.fromSchema(editor.schema).parseSlice(dom, {\n\t\tpreserveWhitespace: true,\n\t});\n\n\tif (slice.size === 0) return;\n\n\tconst { from, to } = editor.state.selection;\n\tconst tr = editor.state.tr.replaceRange(from, to, slice);\n\teditor.view.dispatch(tr);\n}\n\n// ---------------------------------------------------------------------------\n// Section divider HTML\n// ---------------------------------------------------------------------------\n\nexport const SECTION_DIVIDER_HTML = (id: string) =>\n\t`<div data-section-divider=\"${id}\" style=\"display:none;height:0;line-height:0;overflow:hidden;\"></div>`;\n\n/**\n * Build initial HTML for an editor with one or more named sections below the body.\n * Each section is separated by an invisible divider node.\n *\n * @example\n * buildSectionedContent('<p>Body</p>', [\n * { id: 'signature', content: '<p>Alice</p>' },\n * { id: 'forwarded', content: '<p>--- fwd ---</p>' },\n * ])\n */\nexport function buildSectionedContent(\n\tbody: string,\n\tsections: Array<{ id: string; content: string }>,\n): string {\n\tlet html = body;\n\tfor (const s of sections) {\n\t\thtml += SECTION_DIVIDER_HTML(s.id) + s.content;\n\t}\n\treturn html;\n}\n\n// ---------------------------------------------------------------------------\n// Section extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Parse the editor HTML into a Map of sectionId → raw HTML string.\n * The special key `'body'` always holds the content before the first divider.\n * Map iteration order matches document order.\n */\nexport function extractAllSections(editor: Editor): Map<string, string> {\n\treturn extractAllSectionsFromHtml(editor.getHTML());\n}\n\n/**\n * Extract just the body portion (everything before the first section divider)\n * from an HTML string produced by BikEditor. Safe to call on plain HTML too —\n * returns the full string when no dividers are present.\n */\nexport function getBodyHtml(html: string): string {\n\tif (!html) return '';\n\tconst sections = extractAllSectionsFromHtml(html);\n\treturn sections.get('body') ?? html;\n}\n\n/**\n * Extract everything from the first section divider onward (dividers + their\n * content). Returns an empty string when there are no sections.\n */\nexport function getSectionsHtml(html: string): string {\n\tif (!html) return '';\n\tconst body = getBodyHtml(html);\n\treturn html.substring(body.length);\n}\n\nexport function extractAllSectionsFromHtml(html: string): Map<string, string> {\n\tconst sections = new Map<string, string>();\n\tconst dividerRegex =\n\t\t/<div[^>]*data-section-divider=\"([^\"]*)[^>]*>\\s*<\\/div>/g;\n\tconst dividers: Array<{ id: string; index: number; endIndex: number }> = [];\n\n\tlet match: RegExpExecArray | null;\n\twhile ((match = dividerRegex.exec(html)) !== null) {\n\t\tdividers.push({\n\t\t\tid: match[1],\n\t\t\tindex: match.index,\n\t\t\tendIndex: match.index + match[0].length,\n\t\t});\n\t}\n\n\tif (dividers.length === 0) {\n\t\tsections.set('body', html);\n\t\treturn sections;\n\t}\n\n\tsections.set('body', html.slice(0, dividers[0].index));\n\tfor (let i = 0; i < dividers.length; i++) {\n\t\tconst start = dividers[i].endIndex;\n\t\tconst end = i + 1 < dividers.length ? dividers[i + 1].index : html.length;\n\t\tsections.set(dividers[i].id, html.slice(start, end));\n\t}\n\n\treturn sections;\n}\n\n/** Returns BikEditorContent for a single named section (or 'body'). */\nexport function extractSectionContent(\n\teditor: Editor,\n\tid: string,\n): EditorSnapshot {\n\tconst startPos = findSectionStartPos(editor, id);\n\tif (startPos === -1)\n\t\treturn { html: '', text: '', isEmpty: true, characterCount: 0 };\n\tconst endPos = findSectionEndPos(editor, id);\n\tconst slice = editor.state.doc.slice(startPos, endPos);\n\tconst container = document.createElement('div');\n\tconst serializer = DOMSerializer.fromSchema(editor.schema);\n\tcontainer.appendChild(serializer.serializeFragment(slice.content));\n\tconst html = toPortableHtml(container.innerHTML);\n\tconst text = container.textContent ?? '';\n\treturn { html, text, isEmpty: !text.trim(), characterCount: text.length };\n}\n\n/**\n * Parse an HTML string into ProseMirror nodes using the editor's schema.\n */\nfunction parseHtmlToNodes(editor: Editor, html: string) {\n\tconst container = document.createElement('div');\n\tcontainer.innerHTML = html;\n\treturn DOMParser.fromSchema(editor.schema).parse(container, {\n\t\tpreserveWhitespace: true,\n\t}).content;\n}\n\n/**\n * Replace the content of a single named section without touching others.\n * Uses a ProseMirror transaction to replace only the target range,\n * preserving undo history and other sections' state.\n * If the section doesn't exist yet, it is appended at the end of the document.\n */\nexport function setSectionContentInEditor(\n\teditor: Editor,\n\tid: string,\n\thtml: string,\n): void {\n\tconst startPos = findSectionStartPos(editor, id);\n\tif (startPos === -1) {\n\t\tconst endPos = editor.state.doc.content.size;\n\t\tconst dividerHtml = SECTION_DIVIDER_HTML(id) + html;\n\t\teditor.commands.insertContentAt(endPos, dividerHtml, {\n\t\t\tupdateSelection: false,\n\t\t});\n\t\treturn;\n\t}\n\tconst endPos = findSectionEndPos(editor, id);\n\tconst fragment = parseHtmlToNodes(editor, html);\n\tconst { tr } = editor.state;\n\t// For body, replace from position 0 (before the first paragraph's opening\n\t// boundary) so ProseMirror swaps entire block nodes cleanly. Position 1\n\t// (inside the paragraph) would force ProseMirror to close the open paragraph\n\t// first, creating a ghost empty <p></p>.\n\tconst replaceFrom = id === 'body' ? 0 : startPos;\n\ttr.replaceWith(replaceFrom, endPos, fragment);\n\ttr.setMeta('addToHistory', false);\n\teditor.view.dispatch(tr);\n}\n\n// ---------------------------------------------------------------------------\n// Convenience shorthands (body = first section)\n// ---------------------------------------------------------------------------\n\n/** Extract BikEditorContent for just the body (before the first divider). */\nexport function extractBodyContent(editor: Editor): EditorSnapshot {\n\treturn extractSectionContent(editor, 'body');\n}\n\n// ---------------------------------------------------------------------------\n// Active formats\n// ---------------------------------------------------------------------------\n\nexport function extractActiveFormats(editor: Editor): FormatState {\n\treturn {\n\t\tbold: editor.isActive('bold'),\n\t\titalic: editor.isActive('italic'),\n\t\tunderline: editor.isActive('underline'),\n\t\tstrike: editor.isActive('strike'),\n\t\tbulletList: editor.isActive('bulletList'),\n\t\torderedList: editor.isActive('orderedList'),\n\t\tblockquote: editor.isActive('blockquote'),\n\t\tcodeBlock: editor.isActive('codeBlock'),\n\t\tlink: (() => {\n\t\t\tif (editor.isActive('link')) {\n\t\t\t\treturn { href: editor.getAttributes('link')['href'] ?? '' };\n\t\t\t}\n\t\t\tconst { $from } = editor.state.selection;\n\t\t\tif ($from.pos > 0) {\n\t\t\t\tconst before = $from.doc.resolve($from.pos);\n\t\t\t\tconst linkMark = before.marks().find((m) => m.type.name === 'link');\n\t\t\t\tif (!linkMark) {\n\t\t\t\t\tconst nodeBefore = $from.nodeBefore;\n\t\t\t\t\tconst markOnPrev = nodeBefore?.marks.find(\n\t\t\t\t\t\t(m) => m.type.name === 'link',\n\t\t\t\t\t);\n\t\t\t\t\tif (markOnPrev) {\n\t\t\t\t\t\treturn { href: markOnPrev.attrs['href'] ?? '' };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn { href: linkMark.attrs['href'] ?? '' };\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t})(),\n\t\ttextAlign: editor.isActive({ textAlign: 'center' })\n\t\t\t? 'center'\n\t\t\t: editor.isActive({ textAlign: 'right' })\n\t\t\t? 'right'\n\t\t\t: editor.isActive({ textAlign: 'justify' })\n\t\t\t? 'justify'\n\t\t\t: editor.isActive({ textAlign: 'left' })\n\t\t\t? 'left'\n\t\t\t: null,\n\t\tfontFamily: editor.getAttributes('textStyle')['fontFamily'] ?? null,\n\t\tfontSize: editor.getAttributes('textStyle')['fontSize'] ?? null,\n\t\tcolor: editor.getAttributes('textStyle')['color'] ?? null,\n\t\thighlight: editor.isActive('highlight')\n\t\t\t? editor.getAttributes('highlight')['color'] ?? 'default'\n\t\t\t: null,\n\t\tsuperscript: editor.isActive('superscript'),\n\t\tsubscript: editor.isActive('subscript'),\n\t};\n}\n\nexport function extractContent(editor: Editor): EditorSnapshot {\n\tconst html = toPortableHtml(editor.getHTML());\n\tconst normalized = normalizeHardBreaks(editor.state.doc.content);\n\tconst tempDoc = editor.schema.node('doc', null, normalized);\n\t// Paragraph boundary → blank line (\\n\\n), soft line break (hardBreak) → \\n.\n\t// Matches Gmail's plain-text output for the same content.\n\tconst text = tempDoc.textBetween(0, tempDoc.content.size, '\\n\\n', '\\n');\n\treturn {\n\t\thtml,\n\t\ttext,\n\t\tisEmpty: editor.isEmpty,\n\t\tcharacterCount: text.length,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Section position helpers (used by insertAtSectionStart/End and appendBodyContent)\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the ProseMirror position immediately after a section's opening divider\n * (i.e. the start of the section's own content).\n * For `'body'`, returns 1 (beginning of the document).\n * Returns -1 if the named section's divider is not found.\n */\nexport function findSectionStartPos(editor: Editor, sectionId: string): number {\n\tif (sectionId === 'body') return 1;\n\tlet startPos = -1;\n\teditor.state.doc.descendants((node, pos) => {\n\t\tif (startPos !== -1) return false;\n\t\tif (\n\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t) {\n\t\t\tstartPos = pos + node.nodeSize; // position right after the divider\n\t\t}\n\t});\n\treturn startPos;\n}\n\n/**\n * Returns the ProseMirror position at the end of a named section's content:\n * - For `'body'`: position of the first section divider, or end of document.\n * - For a named section: position of the next divider, or end of document.\n */\nexport function findSectionEndPos(editor: Editor, sectionId: string): number {\n\tconst doc = editor.state.doc;\n\tconst docSize = doc.content.size;\n\n\tif (sectionId === 'body') {\n\t\tlet firstDividerPos = -1;\n\t\tdoc.descendants((node, pos) => {\n\t\t\tif (firstDividerPos !== -1) return false;\n\t\t\tif (node.type.name === 'sectionDivider') {\n\t\t\t\tfirstDividerPos = pos;\n\t\t\t}\n\t\t});\n\t\treturn firstDividerPos !== -1 ? firstDividerPos : docSize;\n\t}\n\n\tlet passedSection = false;\n\tlet nextDividerPos = -1;\n\tdoc.descendants((node, pos) => {\n\t\tif (nextDividerPos !== -1) return false;\n\t\tif (!passedSection) {\n\t\t\tif (\n\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t) {\n\t\t\t\tpassedSection = true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tif (node.type.name === 'sectionDivider') {\n\t\t\tnextDividerPos = pos;\n\t\t}\n\t});\n\treturn nextDividerPos !== -1 ? nextDividerPos : docSize;\n}\n\n// ---------------------------------------------------------------------------\n// JSON body helpers (used when features.jsonMode is on — the whole document is\n// a single code block whose text is raw JSON, Postman-style)\n// ---------------------------------------------------------------------------\n\nfunction escapeHtml(raw: string): string {\n\treturn raw.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\n/**\n * Wrap a raw JSON string in a `<pre><code>` code block so TipTap parses it as a\n * single code-block node (the container for JSON body mode).\n */\nexport function buildJsonCodeBlockHtml(raw: string): string {\n\treturn `<pre><code>${escapeHtml(raw ?? '')}</code></pre>`;\n}\n\n/** Returns the raw text of the first code block in the document (empty if none). */\nexport function getCodeBlockText(editor: Editor): string {\n\tlet text = '';\n\tlet found = false;\n\teditor.state.doc.descendants((node) => {\n\t\tif (found) return false;\n\t\tif (node.type.name === 'codeBlock') {\n\t\t\ttext = node.textContent;\n\t\t\tfound = true;\n\t\t\treturn false;\n\t\t}\n\t\treturn undefined;\n\t});\n\treturn text;\n}\n\n/**\n * Replace the text of the first code block with `raw`, keeping it a code block.\n * Falls back to replacing the whole document when no code block exists yet.\n */\nexport function setCodeBlockText(editor: Editor, raw: string): void {\n\teditor.commands.setContent(buildJsonCodeBlockHtml(raw), { emitUpdate: true });\n}\n\n/** 1-based line/column of a 0-based character offset within `text`. */\nfunction offsetToLineCol(\n\ttext: string,\n\toffset: number,\n): { line: number; column: number } {\n\tconst before = text.slice(0, Math.max(0, offset));\n\tconst lines = before.split('\\n');\n\treturn {\n\t\tline: lines.length,\n\t\tcolumn: (lines[lines.length - 1]?.length ?? 0) + 1,\n\t};\n}\n\n/**\n * Turn a raw `JSON.parse` error into a clean message + location. Engine messages\n * look like `\"Bad control character in string literal in JSON at position 94\n * (line 7 column 9)\"` — we strip the `\"in JSON at position …\"` tail for the\n * message and pull the line/column from it (falling back to computing them from\n * the position offset when the engine omits them).\n */\nfunction describeJsonError(\n\trawMessage: string,\n\ttext: string,\n): { message: string; line: number | null; column: number | null } {\n\tconst message =\n\t\trawMessage.replace(/\\s*in JSON at position[\\s\\S]*$/i, '').trim() ||\n\t\trawMessage;\n\n\tconst lineCol = rawMessage.match(/line (\\d+) column (\\d+)/i);\n\tif (lineCol) {\n\t\treturn {\n\t\t\tmessage,\n\t\t\tline: Number(lineCol[1]),\n\t\t\tcolumn: Number(lineCol[2]),\n\t\t};\n\t}\n\n\tconst posMatch = rawMessage.match(/position (\\d+)/i);\n\tif (posMatch) {\n\t\tconst { line, column } = offsetToLineCol(text, Number(posMatch[1]));\n\t\treturn { message, line, column };\n\t}\n\n\treturn { message, line: null, column: null };\n}\n\n/** Parse a JSON string without throwing. Empty / whitespace-only text is valid. */\nexport function parseJson(text: string): JsonParseResult {\n\tif (!text.trim()) {\n\t\treturn { valid: true, value: null, error: null, line: null, column: null };\n\t}\n\ttry {\n\t\treturn {\n\t\t\tvalid: true,\n\t\t\tvalue: JSON.parse(text),\n\t\t\terror: null,\n\t\t\tline: null,\n\t\t\tcolumn: null,\n\t\t};\n\t} catch (e) {\n\t\tconst { message, line, column } = describeJsonError(\n\t\t\t(e as Error).message,\n\t\t\ttext,\n\t\t);\n\t\treturn { valid: false, value: null, error: message, line, column };\n\t}\n}\n"],"names":["normalizeHtml","html","sanitizer","sanitizeEmailHtml","container","span","dataType","parent","p","toPortableHtml","div","walker","textNode","blocks","insertInlineHtml","editor","normalised","dom","slice","DOMParser","from","to","tr","SECTION_DIVIDER_HTML","id","buildSectionedContent","body","sections","s","getBodyHtml","extractAllSectionsFromHtml","getSectionsHtml","dividerRegex","dividers","match","i","start","end","extractSectionContent","startPos","findSectionStartPos","endPos","findSectionEndPos","serializer","DOMSerializer","text","parseHtmlToNodes","setSectionContentInEditor","dividerHtml","fragment","replaceFrom","extractBodyContent","extractActiveFormats","$from","linkMark","m","markOnPrev","extractContent","normalized","normalizeHardBreaks","tempDoc","sectionId","node","pos","doc","docSize","firstDividerPos","passedSection","nextDividerPos","escapeHtml","raw","buildJsonCodeBlockHtml","getCodeBlockText","found","setCodeBlockText","offsetToLineCol","offset","lines","describeJsonError","rawMessage","message","lineCol","posMatch","line","column","parseJson","e"],"mappings":"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"}
1
+ {"version":3,"file":"BikEditor.utils.js","sources":["../../../src/editor/BikEditor.utils.ts"],"sourcesContent":["import { Editor } from '@tiptap/core';\nimport { DOMParser, DOMSerializer } from 'prosemirror-model';\nimport {\n\tEditorSnapshot,\n\tFormatState,\n\tJsonParseResult,\n} from './BikEditor.types';\nimport { normalizeHardBreaks } from './extensions/plainClipboard/pasteUtils';\n\n// ---------------------------------------------------------------------------\n// HTML normalisation\n// ---------------------------------------------------------------------------\n\n/**\n * Normalise HTML before passing it to TipTap.\n *\n * 1. Unwrap style-less `<span>` wrappers (plain spans, and editor-cursor spans\n * like Quill's `<span class=\"ql-cursor\">`). Spans that carry inline styling\n * (`color` / `font-family` / `font-size` render as styled spans) or that\n * represent a `{{variable}}` token are PRESERVED — otherwise a setContent\n * round-trip would silently drop colour/font formatting that paste keeps.\n * 2. Collapse placeholder paragraphs (`<p><br></p>`) to `<p></p>`. ProseMirror\n * parses `<p></p>` as an empty paragraph and adds its own DOM `<br>` for the\n * cursor — one blank line, correct height. Leaving the source `<br>` would\n * create a `hard_break` child AND the cursor `<br>` → double-height blank line.\n *\n * Uses the DOM (regex cannot selectively pair span tags). `normalizeHtml` runs\n * in the component body for `initialContent`, so it is guarded for SSR: the\n * editor is created lazily on the client (`immediatelyRender: false`), meaning\n * the value is only parsed client-side and passing through on the server is safe.\n */\nexport function normalizeHtml(html: string): string {\n\tif (!html || typeof document === 'undefined') return html;\n\n\tconst container = document.createElement('div');\n\tcontainer.innerHTML = html;\n\n\tcontainer.querySelectorAll('span').forEach((span) => {\n\t\t// Keep schema-backed spans: styled spans, variables, and mention chips\n\t\t// (`data-type=\"mention…\"`). Stripping a mention span would drop the\n\t\t// `data-id`/`data-label`/`data-kind` the editor needs to reparse it.\n\t\tconst dataType = span.getAttribute('data-type');\n\t\tif (\n\t\t\tspan.hasAttribute('style') ||\n\t\t\tspan.hasAttribute('data-variable') ||\n\t\t\t(dataType !== null && dataType.startsWith('mention'))\n\t\t)\n\t\t\treturn;\n\t\tconst parent = span.parentNode;\n\t\tif (!parent) return;\n\t\twhile (span.firstChild) parent.insertBefore(span.firstChild, span);\n\t\tparent.removeChild(span);\n\t});\n\n\tcontainer.querySelectorAll('p').forEach((p) => {\n\t\tif (\n\t\t\tp.querySelectorAll('br').length === 1 &&\n\t\t\t(p.textContent ?? '').trim() === ''\n\t\t) {\n\t\t\tp.innerHTML = '';\n\t\t}\n\t});\n\n\treturn container.innerHTML;\n}\n\n/**\n * Make editor HTML portable across email clients and chat renderers.\n *\n * 1. Preserve consecutive spaces by converting every second space in a run\n * to `&nbsp;` (U+00A0). Standard HTML collapses adjacent regular spaces;\n * alternating with `&nbsp;` prevents that — same convention Gmail uses.\n * 2. Double a trailing `<br>` in content paragraphs so the blank line is\n * visible. A single trailing `<br>` before `</p>` is swallowed by most\n * email clients; `<br><br>` renders as a visible blank line (matches\n * Gmail's output).\n * 3. Convert empty `<p></p>` to `<p><br></p>` — email clients collapse\n * zero-height paragraphs without a `<br>`.\n */\nexport function toPortableHtml(html: string): string {\n\tconst div = document.createElement('div');\n\tdiv.innerHTML = html;\n\n\t// TreeWalker visits only text nodes, skipping HTML tags/attributes, so we safely\n\t// replace consecutive spaces with space + \\u00a0 (nbsp) to prevent email clients from collapsing them\n\tconst walker = document.createTreeWalker(div, NodeFilter.SHOW_TEXT);\n\tlet textNode: Text | null;\n\twhile ((textNode = walker.nextNode() as Text | null)) {\n\t\tif (textNode.nodeValue && textNode.nodeValue.includes(' ')) {\n\t\t\ttextNode.nodeValue = textNode.nodeValue.replace(/ {2}/g, '  ');\n\t\t}\n\t}\n\n\tconst blocks = div.querySelectorAll('p');\n\tfor (const p of Array.from(blocks)) {\n\t\tif (p.childNodes.length === 0) {\n\t\t\tp.appendChild(document.createElement('br'));\n\t\t\tcontinue;\n\t\t}\n\t\tconst last = p.lastChild;\n\t\tif (last instanceof HTMLBRElement && p.childNodes.length > 1) {\n\t\t\tp.appendChild(document.createElement('br'));\n\t\t}\n\t}\n\treturn div.innerHTML;\n}\n\n// ---------------------------------------------------------------------------\n// Inline content insertion\n// ---------------------------------------------------------------------------\n\n/**\n * Insert HTML at the current cursor position, merging the first paragraph\n * inline while preserving the block structure of subsequent paragraphs/lists.\n *\n * Uses `parseSlice` which returns an open-ended Slice — the first block merges\n * at the cursor, middle blocks stay intact, and the last block merges with any\n * text that follows the cursor.\n */\nexport function insertInlineHtml(editor: Editor, html: string): void {\n\tconst normalised = normalizeHtml(html);\n\tconst dom = document.createElement('div');\n\tdom.innerHTML = normalised;\n\tconst slice = DOMParser.fromSchema(editor.schema).parseSlice(dom, {\n\t\tpreserveWhitespace: true,\n\t});\n\n\tif (slice.size === 0) return;\n\n\tconst { from, to } = editor.state.selection;\n\tconst tr = editor.state.tr.replaceRange(from, to, slice);\n\teditor.view.dispatch(tr);\n}\n\n// ---------------------------------------------------------------------------\n// Section divider HTML\n// ---------------------------------------------------------------------------\n\nexport const SECTION_DIVIDER_HTML = (id: string) =>\n\t`<div data-section-divider=\"${id}\" style=\"display:none;height:0;line-height:0;overflow:hidden;\"></div>`;\n\n/**\n * Build initial HTML for an editor with one or more named sections below the body.\n * Each section is separated by an invisible divider node.\n *\n * @example\n * buildSectionedContent('<p>Body</p>', [\n * { id: 'signature', content: '<p>Alice</p>' },\n * { id: 'forwarded', content: '<p>--- fwd ---</p>' },\n * ])\n */\nexport function buildSectionedContent(\n\tbody: string,\n\tsections: Array<{ id: string; content: string }>,\n): string {\n\tlet html = body;\n\tfor (const s of sections) {\n\t\thtml += SECTION_DIVIDER_HTML(s.id) + s.content;\n\t}\n\treturn html;\n}\n\n// ---------------------------------------------------------------------------\n// Section extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Parse the editor HTML into a Map of sectionId → raw HTML string.\n * The special key `'body'` always holds the content before the first divider.\n * Map iteration order matches document order.\n */\nexport function extractAllSections(editor: Editor): Map<string, string> {\n\treturn extractAllSectionsFromHtml(editor.getHTML());\n}\n\n/**\n * Extract just the body portion (everything before the first section divider)\n * from an HTML string produced by BikEditor. Safe to call on plain HTML too —\n * returns the full string when no dividers are present.\n */\nexport function getBodyHtml(html: string): string {\n\tif (!html) return '';\n\tconst sections = extractAllSectionsFromHtml(html);\n\treturn sections.get('body') ?? html;\n}\n\n/**\n * Extract everything from the first section divider onward (dividers + their\n * content). Returns an empty string when there are no sections.\n */\nexport function getSectionsHtml(html: string): string {\n\tif (!html) return '';\n\tconst body = getBodyHtml(html);\n\treturn html.substring(body.length);\n}\n\nexport function extractAllSectionsFromHtml(html: string): Map<string, string> {\n\tconst sections = new Map<string, string>();\n\tconst dividerRegex =\n\t\t/<div[^>]*data-section-divider=\"([^\"]*)[^>]*>\\s*<\\/div>/g;\n\tconst dividers: Array<{ id: string; index: number; endIndex: number }> = [];\n\n\tlet match: RegExpExecArray | null;\n\twhile ((match = dividerRegex.exec(html)) !== null) {\n\t\tdividers.push({\n\t\t\tid: match[1],\n\t\t\tindex: match.index,\n\t\t\tendIndex: match.index + match[0].length,\n\t\t});\n\t}\n\n\tif (dividers.length === 0) {\n\t\tsections.set('body', html);\n\t\treturn sections;\n\t}\n\n\tsections.set('body', html.slice(0, dividers[0].index));\n\tfor (let i = 0; i < dividers.length; i++) {\n\t\tconst start = dividers[i].endIndex;\n\t\tconst end = i + 1 < dividers.length ? dividers[i + 1].index : html.length;\n\t\tsections.set(dividers[i].id, html.slice(start, end));\n\t}\n\n\treturn sections;\n}\n\n/** Returns BikEditorContent for a single named section (or 'body'). */\nexport function extractSectionContent(\n\teditor: Editor,\n\tid: string,\n): EditorSnapshot {\n\tconst startPos = findSectionStartPos(editor, id);\n\tif (startPos === -1)\n\t\treturn { html: '', text: '', isEmpty: true, characterCount: 0 };\n\tconst endPos = findSectionEndPos(editor, id);\n\tconst slice = editor.state.doc.slice(startPos, endPos);\n\tconst container = document.createElement('div');\n\tconst serializer = DOMSerializer.fromSchema(editor.schema);\n\tcontainer.appendChild(serializer.serializeFragment(slice.content));\n\tconst html = toPortableHtml(container.innerHTML);\n\tconst text = container.textContent ?? '';\n\treturn { html, text, isEmpty: !text.trim(), characterCount: text.length };\n}\n\n/**\n * Parse an HTML string into ProseMirror nodes using the editor's schema.\n */\nfunction parseHtmlToNodes(editor: Editor, html: string) {\n\tconst container = document.createElement('div');\n\tcontainer.innerHTML = html;\n\treturn DOMParser.fromSchema(editor.schema).parse(container, {\n\t\tpreserveWhitespace: true,\n\t}).content;\n}\n\n/**\n * Replace the content of a single named section without touching others.\n * Uses a ProseMirror transaction to replace only the target range,\n * preserving undo history and other sections' state.\n * If the section doesn't exist yet, it is appended at the end of the document.\n */\nexport function setSectionContentInEditor(\n\teditor: Editor,\n\tid: string,\n\thtml: string,\n): void {\n\tconst startPos = findSectionStartPos(editor, id);\n\tif (startPos === -1) {\n\t\tconst endPos = editor.state.doc.content.size;\n\t\tconst dividerHtml = SECTION_DIVIDER_HTML(id) + html;\n\t\teditor.commands.insertContentAt(endPos, dividerHtml, {\n\t\t\tupdateSelection: false,\n\t\t});\n\t\treturn;\n\t}\n\tconst endPos = findSectionEndPos(editor, id);\n\tconst fragment = parseHtmlToNodes(editor, html);\n\tconst { tr } = editor.state;\n\t// For body, replace from position 0 (before the first paragraph's opening\n\t// boundary) so ProseMirror swaps entire block nodes cleanly. Position 1\n\t// (inside the paragraph) would force ProseMirror to close the open paragraph\n\t// first, creating a ghost empty <p></p>.\n\tconst replaceFrom = id === 'body' ? 0 : startPos;\n\ttr.replaceWith(replaceFrom, endPos, fragment);\n\ttr.setMeta('addToHistory', false);\n\teditor.view.dispatch(tr);\n}\n\n// ---------------------------------------------------------------------------\n// Convenience shorthands (body = first section)\n// ---------------------------------------------------------------------------\n\n/** Extract BikEditorContent for just the body (before the first divider). */\nexport function extractBodyContent(editor: Editor): EditorSnapshot {\n\treturn extractSectionContent(editor, 'body');\n}\n\n// ---------------------------------------------------------------------------\n// Active formats\n// ---------------------------------------------------------------------------\n\nexport function extractActiveFormats(editor: Editor): FormatState {\n\treturn {\n\t\tbold: editor.isActive('bold'),\n\t\titalic: editor.isActive('italic'),\n\t\tunderline: editor.isActive('underline'),\n\t\tstrike: editor.isActive('strike'),\n\t\tbulletList: editor.isActive('bulletList'),\n\t\torderedList: editor.isActive('orderedList'),\n\t\tblockquote: editor.isActive('blockquote'),\n\t\tcodeBlock: editor.isActive('codeBlock'),\n\t\tlink: (() => {\n\t\t\tif (editor.isActive('link')) {\n\t\t\t\treturn { href: editor.getAttributes('link')['href'] ?? '' };\n\t\t\t}\n\t\t\tconst { $from } = editor.state.selection;\n\t\t\tif ($from.pos > 0) {\n\t\t\t\tconst before = $from.doc.resolve($from.pos);\n\t\t\t\tconst linkMark = before.marks().find((m) => m.type.name === 'link');\n\t\t\t\tif (!linkMark) {\n\t\t\t\t\tconst nodeBefore = $from.nodeBefore;\n\t\t\t\t\tconst markOnPrev = nodeBefore?.marks.find(\n\t\t\t\t\t\t(m) => m.type.name === 'link',\n\t\t\t\t\t);\n\t\t\t\t\tif (markOnPrev) {\n\t\t\t\t\t\treturn { href: markOnPrev.attrs['href'] ?? '' };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn { href: linkMark.attrs['href'] ?? '' };\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t})(),\n\t\ttextAlign: editor.isActive({ textAlign: 'center' })\n\t\t\t? 'center'\n\t\t\t: editor.isActive({ textAlign: 'right' })\n\t\t\t? 'right'\n\t\t\t: editor.isActive({ textAlign: 'justify' })\n\t\t\t? 'justify'\n\t\t\t: editor.isActive({ textAlign: 'left' })\n\t\t\t? 'left'\n\t\t\t: null,\n\t\tfontFamily: editor.getAttributes('textStyle')['fontFamily'] ?? null,\n\t\tfontSize: editor.getAttributes('textStyle')['fontSize'] ?? null,\n\t\tcolor: editor.getAttributes('textStyle')['color'] ?? null,\n\t\thighlight: editor.isActive('highlight')\n\t\t\t? editor.getAttributes('highlight')['color'] ?? 'default'\n\t\t\t: null,\n\t\tsuperscript: editor.isActive('superscript'),\n\t\tsubscript: editor.isActive('subscript'),\n\t};\n}\n\nexport function extractContent(editor: Editor): EditorSnapshot {\n\tconst html = toPortableHtml(editor.getHTML());\n\tconst normalized = normalizeHardBreaks(editor.state.doc.content);\n\tconst tempDoc = editor.schema.node('doc', null, normalized);\n\t// Paragraph boundary → blank line (\\n\\n), soft line break (hardBreak) → \\n.\n\t// Matches Gmail's plain-text output for the same content.\n\tconst text = tempDoc.textBetween(0, tempDoc.content.size, '\\n\\n', '\\n');\n\treturn {\n\t\thtml,\n\t\ttext,\n\t\tisEmpty: editor.isEmpty,\n\t\tcharacterCount: text.length,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Section position helpers (used by insertAtSectionStart/End and appendBodyContent)\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the ProseMirror position immediately after a section's opening divider\n * (i.e. the start of the section's own content).\n * For `'body'`, returns 1 (beginning of the document).\n * Returns -1 if the named section's divider is not found.\n */\nexport function findSectionStartPos(editor: Editor, sectionId: string): number {\n\tif (sectionId === 'body') return 1;\n\tlet startPos = -1;\n\teditor.state.doc.descendants((node, pos) => {\n\t\tif (startPos !== -1) return false;\n\t\tif (\n\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t) {\n\t\t\tstartPos = pos + node.nodeSize; // position right after the divider\n\t\t}\n\t});\n\treturn startPos;\n}\n\n/**\n * Returns the ProseMirror position at the end of a named section's content:\n * - For `'body'`: position of the first section divider, or end of document.\n * - For a named section: position of the next divider, or end of document.\n */\nexport function findSectionEndPos(editor: Editor, sectionId: string): number {\n\tconst doc = editor.state.doc;\n\tconst docSize = doc.content.size;\n\n\tif (sectionId === 'body') {\n\t\tlet firstDividerPos = -1;\n\t\tdoc.descendants((node, pos) => {\n\t\t\tif (firstDividerPos !== -1) return false;\n\t\t\tif (node.type.name === 'sectionDivider') {\n\t\t\t\tfirstDividerPos = pos;\n\t\t\t}\n\t\t});\n\t\treturn firstDividerPos !== -1 ? firstDividerPos : docSize;\n\t}\n\n\tlet passedSection = false;\n\tlet nextDividerPos = -1;\n\tdoc.descendants((node, pos) => {\n\t\tif (nextDividerPos !== -1) return false;\n\t\tif (!passedSection) {\n\t\t\tif (\n\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t) {\n\t\t\t\tpassedSection = true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tif (node.type.name === 'sectionDivider') {\n\t\t\tnextDividerPos = pos;\n\t\t}\n\t});\n\treturn nextDividerPos !== -1 ? nextDividerPos : docSize;\n}\n\n// ---------------------------------------------------------------------------\n// JSON body helpers (used when features.jsonMode is on — the whole document is\n// a single code block whose text is raw JSON, Postman-style)\n// ---------------------------------------------------------------------------\n\nfunction escapeHtml(raw: string): string {\n\treturn raw.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\n/**\n * Wrap a raw JSON string in a `<pre><code>` code block so TipTap parses it as a\n * single code-block node (the container for JSON body mode).\n */\nexport function buildJsonCodeBlockHtml(raw: string): string {\n\treturn `<pre><code>${escapeHtml(raw ?? '')}</code></pre>`;\n}\n\n/** Returns the raw text of the first code block in the document (empty if none). */\nexport function getCodeBlockText(editor: Editor): string {\n\tlet text = '';\n\tlet found = false;\n\teditor.state.doc.descendants((node) => {\n\t\tif (found) return false;\n\t\tif (node.type.name === 'codeBlock') {\n\t\t\ttext = node.textContent;\n\t\t\tfound = true;\n\t\t\treturn false;\n\t\t}\n\t\treturn undefined;\n\t});\n\treturn text;\n}\n\n/**\n * Replace the text of the first code block with `raw`, keeping it a code block.\n * Falls back to replacing the whole document when no code block exists yet.\n */\nexport function setCodeBlockText(editor: Editor, raw: string): void {\n\teditor.commands.setContent(buildJsonCodeBlockHtml(raw), { emitUpdate: true });\n}\n\n/** 1-based line/column of a 0-based character offset within `text`. */\nfunction offsetToLineCol(\n\ttext: string,\n\toffset: number,\n): { line: number; column: number } {\n\tconst before = text.slice(0, Math.max(0, offset));\n\tconst lines = before.split('\\n');\n\treturn {\n\t\tline: lines.length,\n\t\tcolumn: (lines[lines.length - 1]?.length ?? 0) + 1,\n\t};\n}\n\n/**\n * Turn a raw `JSON.parse` error into a clean message + location. Engine messages\n * look like `\"Bad control character in string literal in JSON at position 94\n * (line 7 column 9)\"` — we strip the `\"in JSON at position …\"` tail for the\n * message and pull the line/column from it (falling back to computing them from\n * the position offset when the engine omits them).\n */\nfunction describeJsonError(\n\trawMessage: string,\n\ttext: string,\n): { message: string; line: number | null; column: number | null } {\n\tconst message =\n\t\trawMessage.replace(/\\s*in JSON at position[\\s\\S]*$/i, '').trim() ||\n\t\trawMessage;\n\n\tconst lineCol = rawMessage.match(/line (\\d+) column (\\d+)/i);\n\tif (lineCol) {\n\t\treturn {\n\t\t\tmessage,\n\t\t\tline: Number(lineCol[1]),\n\t\t\tcolumn: Number(lineCol[2]),\n\t\t};\n\t}\n\n\tconst posMatch = rawMessage.match(/position (\\d+)/i);\n\tif (posMatch) {\n\t\tconst { line, column } = offsetToLineCol(text, Number(posMatch[1]));\n\t\treturn { message, line, column };\n\t}\n\n\treturn { message, line: null, column: null };\n}\n\n/** Parse a JSON string without throwing. Empty / whitespace-only text is valid. */\nexport function parseJson(text: string): JsonParseResult {\n\tif (!text.trim()) {\n\t\treturn { valid: true, value: null, error: null, line: null, column: null };\n\t}\n\ttry {\n\t\treturn {\n\t\t\tvalid: true,\n\t\t\tvalue: JSON.parse(text),\n\t\t\terror: null,\n\t\t\tline: null,\n\t\t\tcolumn: null,\n\t\t};\n\t} catch (e) {\n\t\tconst { message, line, column } = describeJsonError(\n\t\t\t(e as Error).message,\n\t\t\ttext,\n\t\t);\n\t\treturn { valid: false, value: null, error: message, line, column };\n\t}\n}\n"],"names":["normalizeHtml","html","container","span","dataType","parent","p","toPortableHtml","div","walker","textNode","blocks","insertInlineHtml","editor","normalised","dom","slice","DOMParser","from","to","tr","SECTION_DIVIDER_HTML","id","buildSectionedContent","body","sections","s","getBodyHtml","extractAllSectionsFromHtml","getSectionsHtml","dividerRegex","dividers","match","i","start","end","extractSectionContent","startPos","findSectionStartPos","endPos","findSectionEndPos","serializer","DOMSerializer","text","parseHtmlToNodes","setSectionContentInEditor","dividerHtml","fragment","replaceFrom","extractBodyContent","extractActiveFormats","$from","linkMark","m","markOnPrev","extractContent","normalized","normalizeHardBreaks","tempDoc","sectionId","node","pos","doc","docSize","firstDividerPos","passedSection","nextDividerPos","escapeHtml","raw","buildJsonCodeBlockHtml","getCodeBlockText","found","setCodeBlockText","offsetToLineCol","offset","lines","describeJsonError","rawMessage","message","lineCol","posMatch","line","column","parseJson","e"],"mappings":"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"}