posthog-js 1.372.1 → 1.372.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/array.full.es5.js +1 -1
- package/dist/array.full.js +1 -1
- package/dist/array.full.no-external.js +1 -1
- package/dist/array.js +1 -1
- package/dist/array.no-external.js +1 -1
- package/dist/conversations.js +1 -1
- package/dist/conversations.js.map +1 -1
- package/dist/customizations.full.js +1 -1
- package/dist/default-extensions.js +1 -1
- package/dist/extension-bundles.js +1 -1
- package/dist/lazy-recorder.js +1 -1
- package/dist/main.js +1 -1
- package/dist/module.full.js +1 -1
- package/dist/module.full.no-external.js +1 -1
- package/dist/module.js +1 -1
- package/dist/module.no-external.js +1 -1
- package/dist/module.slim.js +1 -1
- package/dist/module.slim.no-external.js +1 -1
- package/dist/posthog-recorder.js +1 -1
- package/dist/src/extensions/conversations/external/components/ConversationsWidget.d.ts +0 -2
- package/dist/src/extensions/conversations/external/components/MessagesView.d.ts +1 -2
- package/dist/src/extensions/conversations/external/components/styles.d.ts +1 -1
- package/lib/package.json +1 -1
- package/lib/src/extensions/conversations/external/components/ConversationsWidget.d.ts +0 -2
- package/lib/src/extensions/conversations/external/components/ConversationsWidget.js +3 -12
- package/lib/src/extensions/conversations/external/components/ConversationsWidget.js.map +1 -1
- package/lib/src/extensions/conversations/external/components/MessagesView.d.ts +1 -2
- package/lib/src/extensions/conversations/external/components/MessagesView.js +2 -2
- package/lib/src/extensions/conversations/external/components/MessagesView.js.map +1 -1
- package/lib/src/extensions/conversations/external/components/OpenChatButton.js +0 -2
- package/lib/src/extensions/conversations/external/components/OpenChatButton.js.map +1 -1
- package/lib/src/extensions/conversations/external/components/styles.d.ts +1 -1
- package/lib/src/extensions/conversations/external/components/styles.js +2 -2
- package/lib/src/extensions/conversations/external/components/styles.js.map +1 -1
- package/lib/src/extensions/conversations/external/index.js +3 -1
- package/lib/src/extensions/conversations/external/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversations.js","sources":["../../../node_modules/.pnpm/preact@10.28.2/node_modules/preact/dist/preact.module.js","../../core/dist/utils/type-utils.mjs","../src/constants.ts","../src/utils/globals.ts","../src/utils/logger.ts","../src/uuidv7.ts","../src/extensions/conversations/external/persistence.ts","../src/extensions/conversations/external/components/styles.ts","../src/extensions/conversations/external/components/OpenChatButton.tsx","../src/extensions/conversations/external/components/CloseChatButton.tsx","../src/extensions/conversations/external/components/utils.ts","../src/extensions/conversations/external/components/TicketListItem.tsx","../src/extensions/conversations/external/components/NewConversationButton.tsx","../src/extensions/conversations/external/components/TicketListView.tsx","../src/extensions/conversations/external/components/IdentificationFormView.tsx","../src/extensions/conversations/external/components/RestoreRequestView.tsx","../src/extensions/conversations/external/components/SendMessageButton.tsx","../../../node_modules/.pnpm/preact@10.28.2/node_modules/preact/hooks/dist/hooks.module.js","../src/extensions/conversations/external/components/RichContent.tsx","../src/extensions/conversations/external/components/MessagesView.tsx","../src/extensions/conversations/external/components/ConversationsWidget.tsx","../src/utils/request-utils.ts","../src/utils/index.ts","../src/extensions/conversations/external/url-utils.ts","../src/extensions/conversations/external/index.tsx","../src/entrypoints/conversations.ts"],"sourcesContent":["var n,l,u,t,i,o,r,e,f,c,s,a,h,p={},v=[],y=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,d=Array.isArray;function w(n,l){for(var u in l)n[u]=l[u];return n}function g(n){n&&n.parentNode&&n.parentNode.removeChild(n)}function _(l,u,t){var i,o,r,e={};for(r in u)\"key\"==r?i=u[r]:\"ref\"==r?o=u[r]:e[r]=u[r];if(arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):t),\"function\"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===e[r]&&(e[r]=l.defaultProps[r]);return m(l,e,i,o,null)}function m(n,t,i,o,r){var e={type:n,props:t,key:i,ref:o,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:null==r?++u:r,__i:-1,__u:0};return null==r&&null!=l.vnode&&l.vnode(e),e}function b(){return{current:null}}function k(n){return n.children}function x(n,l){this.props=n,this.context=l}function S(n,l){if(null==l)return n.__?S(n.__,n.__i+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?S(n):null}function C(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return C(n)}}function M(n){(!n.__d&&(n.__d=!0)&&i.push(n)&&!$.__r++||o!=l.debounceRendering)&&((o=l.debounceRendering)||r)($)}function $(){for(var n,u,t,o,r,f,c,s=1;i.length;)i.length>s&&i.sort(e),n=i.shift(),s=i.length,n.__d&&(t=void 0,o=void 0,r=(o=(u=n).__v).__e,f=[],c=[],u.__P&&((t=w({},o)).__v=o.__v+1,l.vnode&&l.vnode(t),O(u.__P,t,o,u.__n,u.__P.namespaceURI,32&o.__u?[r]:null,f,null==r?S(o):r,!!(32&o.__u),c),t.__v=o.__v,t.__.__k[t.__i]=t,N(f,t,c),o.__e=o.__=null,t.__e!=r&&C(t)));$.__r=0}function I(n,l,u,t,i,o,r,e,f,c,s){var a,h,y,d,w,g,_,m=t&&t.__k||v,b=l.length;for(f=P(u,l,m,f,b),a=0;a<b;a++)null!=(y=u.__k[a])&&(h=-1==y.__i?p:m[y.__i]||p,y.__i=a,g=O(n,y,h,i,o,r,e,f,c,s),d=y.__e,y.ref&&h.ref!=y.ref&&(h.ref&&B(h.ref,null,y),s.push(y.ref,y.__c||d,y)),null==w&&null!=d&&(w=d),(_=!!(4&y.__u))||h.__k===y.__k?f=A(y,f,n,_):\"function\"==typeof y.type&&void 0!==g?f=g:d&&(f=d.nextSibling),y.__u&=-7);return u.__e=w,f}function P(n,l,u,t,i){var o,r,e,f,c,s=u.length,a=s,h=0;for(n.__k=new Array(i),o=0;o<i;o++)null!=(r=l[o])&&\"boolean\"!=typeof r&&\"function\"!=typeof r?(\"string\"==typeof r||\"number\"==typeof r||\"bigint\"==typeof r||r.constructor==String?r=n.__k[o]=m(null,r,null,null,null):d(r)?r=n.__k[o]=m(k,{children:r},null,null,null):void 0===r.constructor&&r.__b>0?r=n.__k[o]=m(r.type,r.props,r.key,r.ref?r.ref:null,r.__v):n.__k[o]=r,f=o+h,r.__=n,r.__b=n.__b+1,e=null,-1!=(c=r.__i=L(r,u,f,a))&&(a--,(e=u[c])&&(e.__u|=2)),null==e||null==e.__v?(-1==c&&(i>s?h--:i<s&&h++),\"function\"!=typeof r.type&&(r.__u|=4)):c!=f&&(c==f-1?h--:c==f+1?h++:(c>f?h--:h++,r.__u|=4))):n.__k[o]=null;if(a)for(o=0;o<s;o++)null!=(e=u[o])&&0==(2&e.__u)&&(e.__e==t&&(t=S(e)),D(e,e));return t}function A(n,l,u,t){var i,o;if(\"function\"==typeof n.type){for(i=n.__k,o=0;i&&o<i.length;o++)i[o]&&(i[o].__=n,l=A(i[o],l,u,t));return l}n.__e!=l&&(t&&(l&&n.type&&!l.parentNode&&(l=S(n)),u.insertBefore(n.__e,l||null)),l=n.__e);do{l=l&&l.nextSibling}while(null!=l&&8==l.nodeType);return l}function H(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(d(n)?n.some(function(n){H(n,l)}):l.push(n)),l}function L(n,l,u,t){var i,o,r,e=n.key,f=n.type,c=l[u],s=null!=c&&0==(2&c.__u);if(null===c&&null==e||s&&e==c.key&&f==c.type)return u;if(t>(s?1:0))for(i=u-1,o=u+1;i>=0||o<l.length;)if(null!=(c=l[r=i>=0?i--:o++])&&0==(2&c.__u)&&e==c.key&&f==c.type)return r;return-1}function T(n,l,u){\"-\"==l[0]?n.setProperty(l,null==u?\"\":u):n[l]=null==u?\"\":\"number\"!=typeof u||y.test(l)?u:u+\"px\"}function j(n,l,u,t,i){var o,r;n:if(\"style\"==l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof t&&(n.style.cssText=t=\"\"),t)for(l in t)u&&l in u||T(n.style,l,\"\");if(u)for(l in u)t&&u[l]==t[l]||T(n.style,l,u[l])}else if(\"o\"==l[0]&&\"n\"==l[1])o=l!=(l=l.replace(f,\"$1\")),r=l.toLowerCase(),l=r in n||\"onFocusOut\"==l||\"onFocusIn\"==l?r.slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?t?u.u=t.u:(u.u=c,n.addEventListener(l,o?a:s,o)):n.removeEventListener(l,o?a:s,o);else{if(\"http://www.w3.org/2000/svg\"==i)l=l.replace(/xlink(H|:h)/,\"h\").replace(/sName$/,\"s\");else if(\"width\"!=l&&\"height\"!=l&&\"href\"!=l&&\"list\"!=l&&\"form\"!=l&&\"tabIndex\"!=l&&\"download\"!=l&&\"rowSpan\"!=l&&\"colSpan\"!=l&&\"role\"!=l&&\"popover\"!=l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null==u||!1===u&&\"-\"!=l[4]?n.removeAttribute(l):n.setAttribute(l,\"popover\"==l&&1==u?\"\":u))}}function F(n){return function(u){if(this.l){var t=this.l[u.type+n];if(null==u.t)u.t=c++;else if(u.t<t.u)return;return t(l.event?l.event(u):u)}}}function O(n,u,t,i,o,r,e,f,c,s){var a,h,p,v,y,_,m,b,S,C,M,$,P,A,H,L,T,j=u.type;if(void 0!==u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),r=[f=u.__e=t.__e]),(a=l.__b)&&a(u);n:if(\"function\"==typeof j)try{if(b=u.props,S=\"prototype\"in j&&j.prototype.render,C=(a=j.contextType)&&i[a.__c],M=a?C?C.props.value:a.__:i,t.__c?m=(h=u.__c=t.__c).__=h.__E:(S?u.__c=h=new j(b,M):(u.__c=h=new x(b,M),h.constructor=j,h.render=E),C&&C.sub(h),h.state||(h.state={}),h.__n=i,p=h.__d=!0,h.__h=[],h._sb=[]),S&&null==h.__s&&(h.__s=h.state),S&&null!=j.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=w({},h.__s)),w(h.__s,j.getDerivedStateFromProps(b,h.__s))),v=h.props,y=h.state,h.__v=u,p)S&&null==j.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),S&&null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else{if(S&&null==j.getDerivedStateFromProps&&b!==v&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(b,M),u.__v==t.__v||!h.__e&&null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(b,h.__s,M)){for(u.__v!=t.__v&&(h.props=b,h.state=h.__s,h.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.some(function(n){n&&(n.__=u)}),$=0;$<h._sb.length;$++)h.__h.push(h._sb[$]);h._sb=[],h.__h.length&&e.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(b,h.__s,M),S&&null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(v,y,_)})}if(h.context=M,h.props=b,h.__P=n,h.__e=!1,P=l.__r,A=0,S){for(h.state=h.__s,h.__d=!1,P&&P(u),a=h.render(h.props,h.state,h.context),H=0;H<h._sb.length;H++)h.__h.push(h._sb[H]);h._sb=[]}else do{h.__d=!1,P&&P(u),a=h.render(h.props,h.state,h.context),h.state=h.__s}while(h.__d&&++A<25);h.state=h.__s,null!=h.getChildContext&&(i=w(w({},i),h.getChildContext())),S&&!p&&null!=h.getSnapshotBeforeUpdate&&(_=h.getSnapshotBeforeUpdate(v,y)),L=a,null!=a&&a.type===k&&null==a.key&&(L=V(a.props.children)),f=I(n,d(L)?L:[L],u,t,i,o,r,e,f,c,s),h.base=u.__e,u.__u&=-161,h.__h.length&&e.push(h),m&&(h.__E=h.__=null)}catch(n){if(u.__v=null,c||null!=r)if(n.then){for(u.__u|=c?160:128;f&&8==f.nodeType&&f.nextSibling;)f=f.nextSibling;r[r.indexOf(f)]=null,u.__e=f}else{for(T=r.length;T--;)g(r[T]);z(u)}else u.__e=t.__e,u.__k=t.__k,n.then||z(u);l.__e(n,u,t)}else null==r&&u.__v==t.__v?(u.__k=t.__k,u.__e=t.__e):f=u.__e=q(t.__e,u,t,i,o,r,e,c,s);return(a=l.diffed)&&a(u),128&u.__u?void 0:f}function z(n){n&&n.__c&&(n.__c.__e=!0),n&&n.__k&&n.__k.forEach(z)}function N(n,u,t){for(var i=0;i<t.length;i++)B(t[i],t[++i],t[++i]);l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function V(n){return\"object\"!=typeof n||null==n||n.__b&&n.__b>0?n:d(n)?n.map(V):w({},n)}function q(u,t,i,o,r,e,f,c,s){var a,h,v,y,w,_,m,b=i.props||p,k=t.props,x=t.type;if(\"svg\"==x?r=\"http://www.w3.org/2000/svg\":\"math\"==x?r=\"http://www.w3.org/1998/Math/MathML\":r||(r=\"http://www.w3.org/1999/xhtml\"),null!=e)for(a=0;a<e.length;a++)if((w=e[a])&&\"setAttribute\"in w==!!x&&(x?w.localName==x:3==w.nodeType)){u=w,e[a]=null;break}if(null==u){if(null==x)return document.createTextNode(k);u=document.createElementNS(r,x,k.is&&k),c&&(l.__m&&l.__m(t,e),c=!1),e=null}if(null==x)b===k||c&&u.data==k||(u.data=k);else{if(e=e&&n.call(u.childNodes),!c&&null!=e)for(b={},a=0;a<u.attributes.length;a++)b[(w=u.attributes[a]).name]=w.value;for(a in b)if(w=b[a],\"children\"==a);else if(\"dangerouslySetInnerHTML\"==a)v=w;else if(!(a in k)){if(\"value\"==a&&\"defaultValue\"in k||\"checked\"==a&&\"defaultChecked\"in k)continue;j(u,a,null,w,r)}for(a in k)w=k[a],\"children\"==a?y=w:\"dangerouslySetInnerHTML\"==a?h=w:\"value\"==a?_=w:\"checked\"==a?m=w:c&&\"function\"!=typeof w||b[a]===w||j(u,a,w,b[a],r);if(h)c||v&&(h.__html==v.__html||h.__html==u.innerHTML)||(u.innerHTML=h.__html),t.__k=[];else if(v&&(u.innerHTML=\"\"),I(\"template\"==t.type?u.content:u,d(y)?y:[y],t,i,o,\"foreignObject\"==x?\"http://www.w3.org/1999/xhtml\":r,e,f,e?e[0]:i.__k&&S(i,0),c,s),null!=e)for(a=e.length;a--;)g(e[a]);c||(a=\"value\",\"progress\"==x&&null==_?u.removeAttribute(\"value\"):null!=_&&(_!==u[a]||\"progress\"==x&&!_||\"option\"==x&&_!=b[a])&&j(u,a,_,b[a],r),a=\"checked\",null!=m&&m!=u[a]&&j(u,a,m,b[a],r))}return u}function B(n,u,t){try{if(\"function\"==typeof n){var i=\"function\"==typeof n.__u;i&&n.__u(),i&&null==u||(n.__u=n(u))}else n.current=u}catch(n){l.__e(n,t)}}function D(n,u,t){var i,o;if(l.unmount&&l.unmount(n),(i=n.ref)&&(i.current&&i.current!=n.__e||B(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(n){l.__e(n,u)}i.base=i.__P=null}if(i=n.__k)for(o=0;o<i.length;o++)i[o]&&D(i[o],u,t||\"function\"!=typeof n.type);t||g(n.__e),n.__c=n.__=n.__e=void 0}function E(n,l,u){return this.constructor(n,u)}function G(u,t,i){var o,r,e,f;t==document&&(t=document.documentElement),l.__&&l.__(u,t),r=(o=\"function\"==typeof i)?null:i&&i.__k||t.__k,e=[],f=[],O(t,u=(!o&&i||t).__k=_(k,null,[u]),r||p,p,t.namespaceURI,!o&&i?[i]:r?null:t.firstChild?n.call(t.childNodes):null,e,!o&&i?i:r?r.__e:t.firstChild,o,f),N(e,u,f)}function J(n,l){G(n,l,J)}function K(l,u,t){var i,o,r,e,f=w({},l.props);for(r in l.type&&l.type.defaultProps&&(e=l.type.defaultProps),u)\"key\"==r?i=u[r]:\"ref\"==r?o=u[r]:f[r]=void 0===u[r]&&null!=e?e[r]:u[r];return arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),m(l.type,f,i||l.key,o||l.ref,null)}function Q(n){function l(n){var u,t;return this.getChildContext||(u=new Set,(t={})[l.__c]=this,this.getChildContext=function(){return t},this.componentWillUnmount=function(){u=null},this.shouldComponentUpdate=function(n){this.props.value!=n.value&&u.forEach(function(n){n.__e=!0,M(n)})},this.sub=function(n){u.add(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u&&u.delete(n),l&&l.call(n)}}),n.children}return l.__c=\"__cC\"+h++,l.__=n,l.Provider=l.__l=(l.Consumer=function(n,l){return n.children(l)}).contextType=l,l}n=v.slice,l={__e:function(n,l,u,t){for(var i,o,r;l=l.__;)if((i=l.__c)&&!i.__)try{if((o=i.constructor)&&null!=o.getDerivedStateFromError&&(i.setState(o.getDerivedStateFromError(n)),r=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),r=i.__d),r)return i.__E=i}catch(l){n=l}throw n}},u=0,t=function(n){return null!=n&&void 0===n.constructor},x.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!=this.state?this.__s:this.__s=w({},this.state),\"function\"==typeof n&&(n=n(w({},u),this.props)),n&&w(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),M(this))},x.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),M(this))},x.prototype.render=k,i=[],r=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,e=function(n,l){return n.__v.__b-l.__v.__b},$.__r=0,f=/(PointerCapture)$|Capture$/i,c=0,s=F(!1),a=F(!0),h=0;export{x as Component,k as Fragment,K as cloneElement,Q as createContext,_ as createElement,b as createRef,_ as h,J as hydrate,t as isValidElement,l as options,G as render,H as toChildArray};\n//# sourceMappingURL=preact.module.js.map\n","import { knownUnsafeEditableEvent } from \"../types.mjs\";\nimport { includes } from \"./string-utils.mjs\";\nconst nativeIsArray = Array.isArray;\nconst ObjProto = Object.prototype;\nconst type_utils_hasOwnProperty = ObjProto.hasOwnProperty;\nconst type_utils_toString = ObjProto.toString;\nconst isArray = nativeIsArray || function(obj) {\n return '[object Array]' === type_utils_toString.call(obj);\n};\nconst isFunction = (x)=>'function' == typeof x;\nconst isNativeFunction = (x)=>isFunction(x) && -1 !== x.toString().indexOf('[native code]');\nconst isObject = (x)=>x === Object(x) && !isArray(x);\nconst isEmptyObject = (x)=>{\n if (isObject(x)) {\n for(const key in x)if (type_utils_hasOwnProperty.call(x, key)) return false;\n return true;\n }\n return false;\n};\nconst isUndefined = (x)=>void 0 === x;\nconst isString = (x)=>'[object String]' == type_utils_toString.call(x);\nconst isEmptyString = (x)=>isString(x) && 0 === x.trim().length;\nconst isNull = (x)=>null === x;\nconst isNullish = (x)=>isUndefined(x) || isNull(x);\nconst isNumber = (x)=>'[object Number]' == type_utils_toString.call(x) && x === x;\nconst isPositiveNumber = (value)=>isNumber(value) && value > 0;\nconst isBoolean = (x)=>'[object Boolean]' === type_utils_toString.call(x);\nconst isFormData = (x)=>x instanceof FormData;\nconst isFile = (x)=>x instanceof File;\nconst isPlainError = (x)=>x instanceof Error;\nconst isKnownUnsafeEditableEvent = (x)=>includes(knownUnsafeEditableEvent, x);\nfunction isPrimitive(value) {\n return null === value || 'object' != typeof value;\n}\nfunction isBuiltin(candidate, className) {\n return Object.prototype.toString.call(candidate) === `[object ${className}]`;\n}\nfunction isError(candidate) {\n switch(Object.prototype.toString.call(candidate)){\n case '[object Error]':\n case '[object Exception]':\n case '[object DOMException]':\n case '[object DOMError]':\n case '[object WebAssembly.Exception]':\n return true;\n default:\n return isInstanceOf(candidate, Error);\n }\n}\nfunction isErrorEvent(event) {\n return isBuiltin(event, 'ErrorEvent');\n}\nfunction isEvent(candidate) {\n return 'undefined' != typeof Event && isInstanceOf(candidate, Event);\n}\nfunction isPlainObject(candidate) {\n return isBuiltin(candidate, 'Object');\n}\nfunction isInstanceOf(candidate, base) {\n try {\n return candidate instanceof base;\n } catch {\n return false;\n }\n}\nconst yesLikeValues = [\n true,\n 'true',\n 1,\n '1',\n 'yes'\n];\nconst isYesLike = (val)=>includes(yesLikeValues, val);\nconst noLikeValues = [\n false,\n 'false',\n 0,\n '0',\n 'no'\n];\nconst isNoLike = (val)=>includes(noLikeValues, val);\nexport { type_utils_hasOwnProperty as hasOwnProperty, isArray, isBoolean, isBuiltin, isEmptyObject, isEmptyString, isError, isErrorEvent, isEvent, isFile, isFormData, isFunction, isKnownUnsafeEditableEvent, isNativeFunction, isNoLike, isNull, isNullish, isNumber, isObject, isPlainError, isPlainObject, isPositiveNumber, isPrimitive, isString, isUndefined, isYesLike, noLikeValues, yesLikeValues };\n","/*\n * Constants\n */\n\n/* PROPERTY KEYS */\n\n// This key is deprecated, but we want to check for it to see whether aliasing is allowed.\nexport const PEOPLE_DISTINCT_ID_KEY = '$people_distinct_id'\nexport const DISTINCT_ID = 'distinct_id'\nexport const DEVICE_ID = '$device_id'\nexport const ALIAS_ID_KEY = '__alias'\nexport const CAMPAIGN_IDS_KEY = '__cmpns'\nexport const EVENT_TIMERS_KEY = '__timers'\nexport const AUTOCAPTURE_DISABLED_SERVER_SIDE = '$autocapture_disabled_server_side'\nexport const HEATMAPS_ENABLED_SERVER_SIDE = '$heatmaps_enabled_server_side'\nexport const EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE = '$exception_capture_enabled_server_side'\nexport const ERROR_TRACKING_SUPPRESSION_RULES = '$error_tracking_suppression_rules'\nexport const ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS = '$error_tracking_capture_extension_exceptions'\nexport const WEB_VITALS_ENABLED_SERVER_SIDE = '$web_vitals_enabled_server_side'\nexport const DEAD_CLICKS_ENABLED_SERVER_SIDE = '$dead_clicks_enabled_server_side'\nexport const PRODUCT_TOURS_ENABLED_SERVER_SIDE = '$product_tours_enabled_server_side'\nexport const WEB_VITALS_ALLOWED_METRICS = '$web_vitals_allowed_metrics'\nexport const SESSION_RECORDING_REMOTE_CONFIG = '$session_recording_remote_config'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_ENABLED_SERVER_SIDE = '$session_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const CONSOLE_LOG_RECORDING_ENABLED_SERVER_SIDE = '$console_log_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_NETWORK_PAYLOAD_CAPTURE = '$session_recording_network_payload_capture'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MASKING = '$session_recording_masking'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_CANVAS_RECORDING = '$session_recording_canvas_recording'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SAMPLE_RATE = '$replay_sample_rate'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MINIMUM_DURATION = '$replay_minimum_duration'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SCRIPT_CONFIG = '$replay_script_config'\nexport const SESSION_RECORDING_OVERRIDE_SAMPLING = '$replay_override_sampling'\nexport const SESSION_RECORDING_OVERRIDE_LINKED_FLAG = '$replay_override_linked_flag'\nexport const SESSION_RECORDING_OVERRIDE_URL_TRIGGER = '$replay_override_url_trigger'\nexport const SESSION_RECORDING_OVERRIDE_EVENT_TRIGGER = '$replay_override_event_trigger'\nexport const SESSION_ID = '$sesid'\nexport const SESSION_RECORDING_IS_SAMPLED = '$session_is_sampled'\nexport const SESSION_RECORDING_PAST_MINIMUM_DURATION = '$session_past_minimum_duration'\nexport const SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION = '$session_recording_url_trigger_activated_session'\nexport const SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION = '$session_recording_event_trigger_activated_session'\n// V2 Trigger Groups: Per-group persistence key prefixes (suffix with group ID)\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_EVENT_PREFIX = '$posthog_sr_group_event_trigger_'\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_URL_PREFIX = '$posthog_sr_group_url_trigger_'\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_SAMPLING_PREFIX = '$posthog_sr_group_sampling_'\nexport const SESSION_RECORDING_FIRST_FULL_SNAPSHOT_TIMESTAMP = '$debug_first_full_snapshot_timestamp'\nexport const ENABLED_FEATURE_FLAGS = '$enabled_feature_flags'\nexport const PERSISTENCE_ACTIVE_FEATURE_FLAGS = '$active_feature_flags'\nexport const PERSISTENCE_EARLY_ACCESS_FEATURES = '$early_access_features'\nexport const PERSISTENCE_FEATURE_FLAG_DETAILS = '$feature_flag_details'\nexport const PERSISTENCE_FEATURE_FLAG_PAYLOADS = '$feature_flag_payloads'\nexport const PERSISTENCE_FEATURE_FLAG_REQUEST_ID = '$feature_flag_request_id'\nexport const PERSISTENCE_OVERRIDE_FEATURE_FLAGS = '$override_feature_flags'\nexport const PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS = '$override_feature_flag_payloads'\nexport const STORED_PERSON_PROPERTIES_KEY = '$stored_person_properties'\nexport const STORED_GROUP_PROPERTIES_KEY = '$stored_group_properties'\nexport const SURVEYS = '$surveys'\nexport const SURVEYS_ACTIVATED = '$surveys_activated'\nexport const PRODUCT_TOURS = 'ph_product_tours'\nexport const PRODUCT_TOURS_ACTIVATED = '$product_tours_activated'\nexport const CONVERSATIONS = '$conversations'\nexport const CONVERSATIONS_LEGACY_WIDGET_SESSION_ID = '$conversations_widget_session_id'\nexport const CONVERSATIONS_LEGACY_TICKET_ID = '$conversations_ticket_id'\nexport const CONVERSATIONS_LEGACY_WIDGET_STATE = '$conversations_widget_state'\nexport const CONVERSATIONS_LEGACY_USER_TRAITS = '$conversations_user_traits'\nexport const FLAG_CALL_REPORTED = '$flag_call_reported'\nexport const FLAG_CALL_REPORTED_SESSION_ID = '$flag_call_reported_session_id'\nexport const PERSISTENCE_FEATURE_FLAG_ERRORS = '$feature_flag_errors'\nexport const PERSISTENCE_FEATURE_FLAG_EVALUATED_AT = '$feature_flag_evaluated_at'\nexport const USER_STATE = '$user_state'\nexport const CLIENT_SESSION_PROPS = '$client_session_props'\nexport const CAPTURE_RATE_LIMIT = '$capture_rate_limit'\n\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_CAMPAIGN_PARAMS = '$initial_campaign_params'\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_REFERRER_INFO = '$initial_referrer_info'\nexport const INITIAL_PERSON_INFO = '$initial_person_info'\nexport const ENABLE_PERSON_PROCESSING = '$epp'\nexport const TOOLBAR_ID = '__POSTHOG_TOOLBAR__'\nexport const TOOLBAR_CONTAINER_CLASS = 'toolbar-global-fade-container'\n\n/**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * Sentinel value for distinct id, device id, session id. Signals that the server should generate the value\n * */\nexport const COOKIELESS_SENTINEL_VALUE = '$posthog_cookieless'\nexport const COOKIELESS_MODE_FLAG_PROPERTY = '$cookieless_mode'\n\nexport const WEB_EXPERIMENTS = '$web_experiments'\n\nexport const SDK_DEBUG_EXTENSIONS_INIT_METHOD = '$sdk_debug_extensions_init_method'\nexport const SDK_DEBUG_EXTENSIONS_INIT_TIME_MS = '$sdk_debug_extensions_init_time_ms'\nexport const SDK_DEBUG_RECORDING_SCRIPT_NOT_LOADED = '$sdk_debug_recording_script_not_loaded'\nexport const SDK_DEBUG_REPLAY_EVENT_TRIGGER_STATUS = '$sdk_debug_replay_event_trigger_status'\nexport const SDK_DEBUG_REPLAY_LINKED_FLAG_TRIGGER_STATUS = '$sdk_debug_replay_linked_flag_trigger_status'\nexport const SDK_DEBUG_REPLAY_MATCHED_RECORDING_TRIGGER_GROUPS = '$sdk_debug_replay_matched_recording_trigger_groups'\nexport const SDK_DEBUG_REPLAY_REMOTE_TRIGGER_MATCHING_CONFIG = '$sdk_debug_replay_remote_trigger_matching_config'\nexport const SDK_DEBUG_REPLAY_TRIGGER_GROUPS_COUNT = '$sdk_debug_replay_trigger_groups_count'\nexport const SDK_DEBUG_REPLAY_URL_TRIGGER_STATUS = '$sdk_debug_replay_url_trigger_status'\nexport const SESSION_RECORDING_START_REASON = '$session_recording_start_reason'\n\nexport const SURVEYS_REQUEST_TIMEOUT_MS = 10000\nexport const LOAD_EXT_NOT_FOUND = 'PostHog loadExternalDependency extension not found.'\n\n/* EVENT NAMES - interned to reduce bundle size */\n/* COOKIELESS MODE VALUES */\nexport const COOKIELESS_ON_REJECT = 'on_reject' as const\nexport const COOKIELESS_ALWAYS = 'always' as const\n\n/* USER STATE VALUES */\nexport const USER_STATE_ANONYMOUS = 'anonymous'\nexport const USER_STATE_IDENTIFIED = 'identified'\n\n/* PERSON PROFILE MODES */\nexport const PERSON_PROFILES_IDENTIFIED_ONLY = 'identified_only' as const\n\n/* DOM EVENT NAMES - interned to reduce bundle size */\nexport const DOM_EVENT_VISIBILITYCHANGE = 'visibilitychange'\nexport const DOM_EVENT_BEFOREUNLOAD = 'beforeunload'\n\nexport const EVENT_PAGEVIEW = '$pageview'\nexport const EVENT_PAGELEAVE = '$pageleave'\nexport const EVENT_IDENTIFY = '$identify'\nexport const EVENT_GROUPIDENTIFY = '$groupidentify'\n\n/* Z-INDEX HIERARCHY: tours > surveys > support */\nexport const Z_INDEX_TOURS = 2147483646\nexport const Z_INDEX_SURVEYS = 2147483645\nexport const Z_INDEX_CONVERSATIONS = 2147483644\n","import type { PostHog } from '../posthog-core'\nimport { SessionIdManager } from '../sessionid'\nimport {\n DeadClicksAutoCaptureConfig,\n ExternalIntegrationKind,\n Properties,\n RemoteConfig,\n SiteAppLoader,\n SessionStartReason,\n} from '../types'\nimport type {\n ConversationsRemoteConfig,\n GetMessagesResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n MarkAsReadResponse,\n RestoreFromTokenResponse,\n RequestRestoreLinkResponse,\n SendMessageResponse,\n UserProvidedTraits,\n} from '../posthog-conversations-types'\n// only importing types here, so won't affect the bundle\n// eslint-disable-next-line posthog-js/no-external-replay-imports\nimport type { SessionRecordingStatus, TriggerType } from '../extensions/replay/external/triggerMatching'\nimport { eventWithTime } from '../extensions/replay/types/rrweb-types'\nimport { ErrorTracking } from '@posthog/core'\n\n/*\n * Global helpers to protect access to browser globals in a way that is safer for different targets\n * like DOM, SSR, Web workers etc.\n *\n * NOTE: Typically we want the \"window\" but globalThis works for both the typical browser context as\n * well as other contexts such as the web worker context. Window is still exported for any bits that explicitly require it.\n * If in doubt - export the global you need from this file and use that as an optional value. This way the code path is forced\n * to handle the case where the global is not available.\n */\n\n// eslint-disable-next-line no-restricted-globals\nconst win: (Window & typeof globalThis) | undefined = typeof window !== 'undefined' ? window : undefined\n\nexport type AssignableWindow = Window &\n typeof globalThis & {\n /*\n * Main PostHog instance\n */\n posthog: any\n\n /*\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n */\n __PosthogExtensions__?: PostHogExtensions\n\n /**\n * When loading remote config, we assign it to this global configuration\n * for ease of sharing it with the rest of the SDK\n */\n _POSTHOG_REMOTE_CONFIG?: Record<\n string,\n {\n config: RemoteConfig\n siteApps: SiteAppLoader[]\n }\n >\n\n /**\n * If this is set on the window, our logger will log to the console\n * for ease of debugging. Used for testing purposes only.\n *\n * @see {Config.DEBUG} from config.ts\n */\n POSTHOG_DEBUG: any\n\n // Exposed by the browser\n doNotTrack: any\n\n // See entrypoints/customizations.full.ts\n posthogCustomizations: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/exception-autocapture.ts\n *\n * @deprecated use `__PosthogExtensions__.errorWrappingFunctions` instead\n */\n posthogErrorWrappingFunctions: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrweb` instead\n */\n rrweb: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrwebConsoleRecord` instead\n */\n rrwebConsoleRecord: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.getRecordNetworkPlugin` instead\n */\n getRecordNetworkPlugin: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/web-vitals.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogWebVitalsCallbacks` instead\n */\n postHogWebVitalsCallbacks: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/tracing-headers.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogTracingHeadersPatchFns` instead\n */\n postHogTracingHeadersPatchFns: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/surveys.ts\n *\n * @deprecated use `__PosthogExtensions__.generateSurveys` instead\n */\n extendPostHogWithSurveys: any\n\n /*\n * These are used to handle our toolbar state.\n * @see {Toolbar} from extensions/toolbar.ts\n */\n ph_load_toolbar: any\n ph_load_editor: any\n ph_toolbar_state: any\n } & Record<`__$$ph_site_app_${string}`, any>\n\n/**\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n * changes to this interface can be breaking changes for users of the SDK\n */\n\nexport type ExternalExtensionKind = 'intercom-integration' | 'crisp-chat-integration'\n\nexport type PostHogExtensionKind =\n | 'toolbar'\n | 'exception-autocapture'\n | 'web-vitals'\n | 'web-vitals-with-attribution'\n | 'recorder'\n | 'lazy-recorder'\n | 'tracing-headers'\n | 'surveys'\n | 'logs'\n | 'conversations'\n | 'product-tours'\n | 'dead-clicks-autocapture'\n | 'remote-config'\n | ExternalExtensionKind\n\nexport interface LazyLoadedSessionRecordingInterface {\n start: (startReason?: SessionStartReason) => void\n stop: () => void\n discard: () => void\n sessionId: string\n status: SessionRecordingStatus\n onRRwebEmit: (rawEvent: eventWithTime) => void\n log: (message: string, level: 'log' | 'warn' | 'error') => void\n sdkDebugProperties: Properties\n overrideLinkedFlag: () => void\n overrideSampling: () => void\n overrideTrigger: (triggerType: TriggerType) => void\n isStarted: boolean\n tryAddCustomEvent(tag: string, payload: any): boolean\n}\n\nexport interface LazyLoadedDeadClicksAutocaptureInterface {\n start: (observerTarget: Node) => void\n stop: () => void\n}\n\nexport interface LazyLoadedConversationsInterface {\n // Widget control\n show: () => void\n hide: () => void\n isVisible: () => boolean\n\n // Lifecycle\n reset: () => void\n\n // Identity verification\n setIdentity: () => void\n clearIdentity: () => void\n\n // API methods\n sendMessage: (message: string, userTraits?: UserProvidedTraits, newTicket?: boolean) => Promise<SendMessageResponse>\n getMessages: (ticketId?: string, after?: string) => Promise<GetMessagesResponse>\n markAsRead: (ticketId?: string) => Promise<MarkAsReadResponse>\n getTickets: (options?: GetTicketsOptions) => Promise<GetTicketsResponse>\n requestRestoreLink: (email: string) => Promise<RequestRestoreLinkResponse>\n restoreFromToken: (restoreToken: string) => Promise<RestoreFromTokenResponse>\n restoreFromUrlToken: () => Promise<RestoreFromTokenResponse | null>\n getCurrentTicketId: () => string | null\n getWidgetSessionId: () => string\n}\n\ninterface PostHogExtensions {\n loadExternalDependency?: (\n posthog: PostHog,\n kind: PostHogExtensionKind,\n callback: (error?: string | Event, event?: Event) => void\n ) => void\n\n loadSiteApp?: (posthog: PostHog, appUrl: string, callback: (error?: string | Event, event?: Event) => void) => void\n\n errorWrappingFunctions?: {\n wrapOnError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapUnhandledRejection: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapConsoleError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n }\n rrweb?: { record: any; version: string; wasMaxDepthReached?: () => boolean; resetMaxDepthState?: () => void }\n rrwebPlugins?: { getRecordConsolePlugin: any; getRecordNetworkPlugin?: any }\n generateSurveys?: (posthog: PostHog, isSurveysEnabled: boolean) => any | undefined\n generateProductTours?: (posthog: PostHog, isEnabled: boolean) => any | undefined\n logs?: {\n initializeLogs?: (posthog: PostHog) => any | undefined\n }\n postHogWebVitalsCallbacks?: {\n onLCP: (metric: any) => void\n onCLS: (metric: any) => void\n onFCP: (metric: any) => void\n onINP: (metric: any) => void\n }\n /**\n * @deprecated\n *\n * this was introduced briefly, it is now always a no-op and only kept for backwards compatibility\n */\n loadWebVitalsCallbacks?: (useAttribution?: boolean) => PostHogExtensions['postHogWebVitalsCallbacks']\n tracingHeadersPatchFns?: {\n _patchFetch: (hostnames: string[], distinctId: string, sessionManager?: SessionIdManager) => () => void\n _patchXHR: (hostnames: string[], distinctId: string, sessionManager?: SessionIdManager) => () => void\n }\n initDeadClicksAutocapture?: (\n ph: PostHog,\n config: DeadClicksAutoCaptureConfig\n ) => LazyLoadedDeadClicksAutocaptureInterface\n integrations?: {\n [K in ExternalIntegrationKind]?: { start: (posthog: PostHog) => void; stop: () => void }\n }\n initSessionRecording?: (ph: PostHog) => LazyLoadedSessionRecordingInterface\n initConversations?: (config: ConversationsRemoteConfig, posthog: PostHog) => LazyLoadedConversationsInterface\n}\n\nconst global: typeof globalThis | undefined = typeof globalThis !== 'undefined' ? globalThis : win\n\n// React Native polyfills for posthog-js compatibility\nif (typeof self === 'undefined') {\n ;(global as any).self = global\n}\nif (typeof File === 'undefined') {\n ;(global as any).File = function () {}\n}\n\nexport const navigator = global?.navigator\nexport const document = global?.document\nexport const location = global?.location\nexport const fetch = global?.fetch\nexport const XMLHttpRequest =\n global?.XMLHttpRequest && 'withCredentials' in new global.XMLHttpRequest() ? global.XMLHttpRequest : undefined\nexport const AbortController = global?.AbortController\nexport const CompressionStream = global?.CompressionStream\nexport const userAgent = navigator?.userAgent\nexport const assignableWindow: AssignableWindow = win ?? ({} as any)\n\nexport { win as window }\n","import Config from '../config'\nimport { isUndefined } from '@posthog/core'\nimport { assignableWindow, window } from './globals'\nimport type { Logger } from '@posthog/core'\n\ntype CreateLoggerOptions = {\n debugEnabled?: boolean\n}\n\ntype PosthogJsLogger = Omit<Logger, 'createLogger'> & {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => void\n uninitializedWarning: (methodName: string) => void\n createLogger: (prefix: string, options?: CreateLoggerOptions) => PosthogJsLogger\n}\n\nconst _createLogger = (prefix: string, { debugEnabled }: CreateLoggerOptions = {}): PosthogJsLogger => {\n const logger: PosthogJsLogger = {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => {\n if (\n window &&\n (Config.DEBUG || assignableWindow.POSTHOG_DEBUG || debugEnabled) &&\n !isUndefined(window.console) &&\n window.console\n ) {\n const consoleLog =\n '__rrweb_original__' in window.console[level]\n ? (window.console[level] as any)['__rrweb_original__']\n : window.console[level]\n\n // eslint-disable-next-line no-console\n consoleLog(prefix, ...args)\n }\n },\n\n info: (...args: any[]) => {\n logger._log('log', ...args)\n },\n\n warn: (...args: any[]) => {\n logger._log('warn', ...args)\n },\n\n error: (...args: any[]) => {\n logger._log('error', ...args)\n },\n\n critical: (...args: any[]) => {\n // Critical errors are always logged to the console\n // eslint-disable-next-line no-console\n console.error(prefix, ...args)\n },\n\n uninitializedWarning: (methodName: string) => {\n logger.error(`You must initialize PostHog before calling ${methodName}`)\n },\n\n createLogger: (additionalPrefix: string, options?: CreateLoggerOptions) =>\n _createLogger(`${prefix} ${additionalPrefix}`, options),\n }\n return logger\n}\n\nexport const logger = _createLogger('[PostHog.js]')\n\nexport const createLogger = logger.createLogger\n","/**\n * uuidv7: An experimental implementation of the proposed UUID Version 7\n *\n * @license Apache-2.0\n * @copyright 2021-2023 LiosK\n * @packageDocumentation\n *\n * from https://github.com/LiosK/uuidv7/blob/e501462ea3d23241de13192ceae726956f9b3b7d/src/index.ts\n */\n\n// polyfill for IE11\nimport { window } from './utils/globals'\n\nimport { isNumber, isUndefined } from '@posthog/core'\n\nif (!Math.trunc) {\n Math.trunc = function (v) {\n return v < 0 ? Math.ceil(v) : Math.floor(v)\n }\n}\n\n// polyfill for IE11\nif (!Number.isInteger) {\n Number.isInteger = function (value) {\n return isNumber(value) && isFinite(value) && Math.floor(value) === value\n }\n}\n\n/** Represents a UUID as a 16-byte byte array. */\nexport class UUID {\n /** @param bytes - The 16-byte byte array representation. */\n constructor(readonly bytes: Readonly<Uint8Array>) {\n if (bytes.length !== 16) {\n throw new TypeError('not 128-bit length')\n }\n }\n\n /**\n * Builds a byte array from UUIDv7 field values.\n *\n * @param unixTsMs - A 48-bit `unix_ts_ms` field value.\n * @param randA - A 12-bit `rand_a` field value.\n * @param randBHi - The higher 30 bits of 62-bit `rand_b` field value.\n * @param randBLo - The lower 32 bits of 62-bit `rand_b` field value.\n */\n static fromFieldsV7(unixTsMs: number, randA: number, randBHi: number, randBLo: number): UUID {\n if (\n !Number.isInteger(unixTsMs) ||\n !Number.isInteger(randA) ||\n !Number.isInteger(randBHi) ||\n !Number.isInteger(randBLo) ||\n unixTsMs < 0 ||\n randA < 0 ||\n randBHi < 0 ||\n randBLo < 0 ||\n unixTsMs > 0xffff_ffff_ffff ||\n randA > 0xfff ||\n randBHi > 0x3fff_ffff ||\n randBLo > 0xffff_ffff\n ) {\n throw new RangeError('invalid field value')\n }\n\n const bytes = new Uint8Array(16)\n bytes[0] = unixTsMs / 2 ** 40\n bytes[1] = unixTsMs / 2 ** 32\n bytes[2] = unixTsMs / 2 ** 24\n bytes[3] = unixTsMs / 2 ** 16\n bytes[4] = unixTsMs / 2 ** 8\n bytes[5] = unixTsMs\n bytes[6] = 0x70 | (randA >>> 8)\n bytes[7] = randA\n bytes[8] = 0x80 | (randBHi >>> 24)\n bytes[9] = randBHi >>> 16\n bytes[10] = randBHi >>> 8\n bytes[11] = randBHi\n bytes[12] = randBLo >>> 24\n bytes[13] = randBLo >>> 16\n bytes[14] = randBLo >>> 8\n bytes[15] = randBLo\n return new UUID(bytes)\n }\n\n /** @returns The 8-4-4-4-12 canonical hexadecimal string representation. */\n toString(): string {\n let text = ''\n for (let i = 0; i < this.bytes.length; i++) {\n text = text + (this.bytes[i] >>> 4).toString(16) + (this.bytes[i] & 0xf).toString(16)\n if (i === 3 || i === 5 || i === 7 || i === 9) {\n text += '-'\n }\n }\n\n if (text.length !== 36) {\n // We saw one customer whose bundling code was mangling the UUID generation\n // rather than accept a bad UUID, we throw an error here.\n throw new Error('Invalid UUIDv7 was generated')\n }\n return text\n }\n\n /** Creates an object from `this`. */\n clone(): UUID {\n return new UUID(this.bytes.slice(0))\n }\n\n /** Returns true if `this` is equivalent to `other`. */\n equals(other: UUID): boolean {\n return this.compareTo(other) === 0\n }\n\n /**\n * Returns a negative integer, zero, or positive integer if `this` is less\n * than, equal to, or greater than `other`, respectively.\n */\n compareTo(other: UUID): number {\n for (let i = 0; i < 16; i++) {\n const diff = this.bytes[i] - other.bytes[i]\n if (diff !== 0) {\n return Math.sign(diff)\n }\n }\n return 0\n }\n}\n\n/** Encapsulates the monotonic counter state. */\nclass V7Generator {\n private _timestamp = 0\n private _counter = 0\n private readonly _random = new DefaultRandom()\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or resets the\n * generator upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method resets the generator and returns a new\n * UUID based on the current timestamp.\n */\n generate(): UUID {\n const value = this.generateOrAbort()\n if (!isUndefined(value)) {\n return value\n } else {\n // reset state and resume\n this._timestamp = 0\n const valueAfterReset = this.generateOrAbort()\n if (isUndefined(valueAfterReset)) {\n throw new Error('Could not generate UUID after timestamp reset')\n }\n return valueAfterReset\n }\n }\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or returns\n * `undefined` upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method aborts and returns `undefined`.\n */\n generateOrAbort(): UUID | undefined {\n const MAX_COUNTER = 0x3ff_ffff_ffff\n const ROLLBACK_ALLOWANCE = 10_000 // 10 seconds\n\n const ts = Date.now()\n if (ts > this._timestamp) {\n this._timestamp = ts\n this._resetCounter()\n } else if (ts + ROLLBACK_ALLOWANCE > this._timestamp) {\n // go on with previous timestamp if new one is not much smaller\n this._counter++\n if (this._counter > MAX_COUNTER) {\n // increment timestamp at counter overflow\n this._timestamp++\n this._resetCounter()\n }\n } else {\n // abort if clock went backwards to unbearable extent\n return undefined\n }\n\n return UUID.fromFieldsV7(\n this._timestamp,\n Math.trunc(this._counter / 2 ** 30),\n this._counter & (2 ** 30 - 1),\n this._random.nextUint32()\n )\n }\n\n /** Initializes the counter at a 42-bit random integer. */\n private _resetCounter(): void {\n this._counter = this._random.nextUint32() * 0x400 + (this._random.nextUint32() & 0x3ff)\n }\n}\n\n/** A global flag to force use of cryptographically strong RNG. */\ndeclare const UUIDV7_DENY_WEAK_RNG: boolean\n\n/** Stores `crypto.getRandomValues()` available in the environment. */\nlet getRandomValues: <T extends Uint8Array | Uint32Array>(buffer: T) => T = (buffer) => {\n // fall back on Math.random() unless the flag is set to true\n // TRICKY: don't use the isUndefined method here as can't pass the reference\n if (typeof UUIDV7_DENY_WEAK_RNG !== 'undefined' && UUIDV7_DENY_WEAK_RNG) {\n throw new Error('no cryptographically strong RNG available')\n }\n\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] = Math.trunc(Math.random() * 0x1_0000) * 0x1_0000 + Math.trunc(Math.random() * 0x1_0000)\n }\n return buffer\n}\n\n// detect Web Crypto API\nif (window && !isUndefined(window.crypto) && crypto.getRandomValues) {\n getRandomValues = (buffer) => crypto.getRandomValues(buffer)\n}\n\n/**\n * Wraps `crypto.getRandomValues()` and compatibles to enable buffering; this\n * uses a small buffer by default to avoid unbearable throughput decline in some\n * environments as well as the waste of time and space for unused values.\n */\nclass DefaultRandom {\n private readonly _buffer = new Uint32Array(8)\n private _cursor = Infinity\n nextUint32(): number {\n if (this._cursor >= this._buffer.length) {\n getRandomValues(this._buffer)\n this._cursor = 0\n }\n return this._buffer[this._cursor++]\n }\n}\n\nlet defaultGenerator: V7Generator | undefined\n\n/**\n * Generates a UUIDv7 string.\n *\n * @returns The 8-4-4-4-12 canonical hexadecimal string representation\n * (\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\").\n */\nexport const uuidv7 = (): string => uuidv7obj().toString()\n\n/** Generates a UUIDv7 object. */\nconst uuidv7obj = (): UUID => (defaultGenerator || (defaultGenerator = new V7Generator())).generate()\n\nexport const uuid7ToTimestampMs = (uuid: string): number => {\n // remove hyphens\n const hex = uuid.replace(/-/g, '')\n // ensure that it's a version 7 UUID\n if (hex.length !== 32) {\n throw new Error('Not a valid UUID')\n }\n if (hex[12] !== '7') {\n throw new Error('Not a UUIDv7')\n }\n // the first 6 bytes are the timestamp, which means that we can read only the first 12 hex characters\n return parseInt(hex.substring(0, 12), 16)\n}\n","import {\n CONVERSATIONS_LEGACY_TICKET_ID,\n CONVERSATIONS_LEGACY_USER_TRAITS,\n CONVERSATIONS_LEGACY_WIDGET_SESSION_ID,\n CONVERSATIONS_LEGACY_WIDGET_STATE,\n} from '../../../constants'\nimport { PostHog } from '../../../posthog-core'\nimport { UserProvidedTraits } from '../../../posthog-conversations-types'\nimport { createLogger } from '../../../utils/logger'\nimport { window } from '../../../utils/globals'\nimport { uuidv7 } from '../../../uuidv7'\n\nconst logger = createLogger('[ConversationsPersistence]')\n\ninterface ConversationsStorageData {\n widgetSessionId?: string\n ticketId?: string | null\n widgetState?: 'open' | 'closed'\n userTraits?: UserProvidedTraits | null\n}\n\n/**\n * Dedicated localStorage key scoped to the PostHog project token.\n * Format: `ph_conv_<token>`\n */\nfunction storageKey(posthog: PostHog): string | null {\n const token = posthog.config?.token\n return token ? 'ph_conv_' + token : null\n}\n\n/**\n * ConversationsPersistence manages conversation data in its own dedicated\n * localStorage entry, independent of PostHog's core persistence layer.\n *\n * This avoids a known issue where PostHog's persistence.props can lose data\n * when the cookie+localStorage merge in _parse() fails on large entries.\n *\n * Pattern follows toolbar and surveys extensions which also use dedicated\n * localStorage keys.\n */\nexport class ConversationsPersistence {\n private _cachedWidgetSessionId: string | null = null\n private _storageKey: string | null\n\n constructor(private readonly _posthog: PostHog) {\n this._storageKey = storageKey(_posthog)\n this._migrateFromLegacyPersistence()\n }\n\n /**\n * Get or create the widget session ID (random UUID for access control).\n * This ID is generated once per browser and persists across sessions.\n * It is NOT tied to distinct_id - it stays the same even when user identifies.\n *\n * SECURITY: This is the key for access control. Only the browser that created\n * the widget_session_id can access tickets associated with it.\n */\n getOrCreateWidgetSessionId(): string {\n if (this._cachedWidgetSessionId) {\n return this._cachedWidgetSessionId\n }\n\n let sessionId = this._read()?.widgetSessionId\n\n if (!sessionId) {\n sessionId = uuidv7()\n this._write({ widgetSessionId: sessionId })\n }\n\n this._cachedWidgetSessionId = sessionId\n return sessionId\n }\n\n /**\n * Overwrite the widget session ID (used by restore flow).\n */\n setWidgetSessionId(id: string): void {\n this._cachedWidgetSessionId = id\n const data = this._read() || {}\n this._write({ ...data, widgetSessionId: id })\n }\n\n /**\n * Clear the widget session ID (called on posthog.reset()).\n * This will create a new session and lose access to previous tickets.\n */\n clearWidgetSessionId(): void {\n this._cachedWidgetSessionId = null\n const data = this._read()\n if (data) {\n delete data.widgetSessionId\n this._write(data)\n }\n }\n\n saveTicketId(ticketId: string): void {\n const data = this._read() || {}\n this._write({ ...data, ticketId })\n }\n\n loadTicketId(): string | null {\n return this._read()?.ticketId || null\n }\n\n clearTicketId(): void {\n const data = this._read()\n if (data) {\n delete data.ticketId\n this._write(data)\n }\n }\n\n saveWidgetState(state: 'open' | 'closed'): void {\n const data = this._read() || {}\n this._write({ ...data, widgetState: state })\n }\n\n loadWidgetState(): 'open' | 'closed' | null {\n const state = this._read()?.widgetState\n return state === 'open' || state === 'closed' ? state : null\n }\n\n saveUserTraits(traits: UserProvidedTraits): void {\n const data = this._read() || {}\n this._write({ ...data, userTraits: traits })\n }\n\n loadUserTraits(): UserProvidedTraits | null {\n const traits = this._read()?.userTraits\n return traits && (traits.name || traits.email) ? traits : null\n }\n\n clearUserTraits(): void {\n const data = this._read()\n if (data) {\n delete data.userTraits\n this._write(data)\n }\n }\n\n clearAll(): void {\n this._cachedWidgetSessionId = null\n if (this._storageKey) {\n try {\n window?.localStorage?.removeItem(this._storageKey)\n } catch {\n logger.error('Failed to remove localStorage item')\n }\n }\n }\n\n private _read(): ConversationsStorageData | null {\n if (!this._storageKey) {\n return null\n }\n try {\n const raw = window?.localStorage?.getItem(this._storageKey)\n return raw ? (JSON.parse(raw) as ConversationsStorageData) : null\n } catch {\n return null\n }\n }\n\n private _write(data: ConversationsStorageData): void {\n if (!this._storageKey) {\n return\n }\n try {\n window?.localStorage?.setItem(this._storageKey, JSON.stringify(data))\n } catch (error) {\n logger.error('Failed to write to localStorage', error)\n }\n }\n\n /**\n * One-time migration: copy conversations data from PostHog's main\n * persistence blob into the dedicated localStorage key, then remove\n * the old keys from PostHog persistence so they stop bloating it.\n */\n private _migrateFromLegacyPersistence(): void {\n if (!this._storageKey || this._read()?.widgetSessionId) {\n return\n }\n\n try {\n const persistence = this._posthog.persistence\n if (!persistence || persistence.isDisabled?.()) {\n return\n }\n\n const widgetSessionId = persistence.get_property(CONVERSATIONS_LEGACY_WIDGET_SESSION_ID)\n if (!widgetSessionId) {\n // persistence.props may be empty (the bug) — try raw localStorage\n const legacyFromRaw = this._readLegacyFromRawStorage()\n if (legacyFromRaw) {\n this._write(legacyFromRaw)\n logger.info('Migrated conversations data from raw localStorage')\n }\n return\n }\n\n const data: ConversationsStorageData = { widgetSessionId }\n\n const ticketId = persistence.get_property(CONVERSATIONS_LEGACY_TICKET_ID)\n if (ticketId) {\n data.ticketId = ticketId\n }\n\n const widgetState = persistence.get_property(CONVERSATIONS_LEGACY_WIDGET_STATE)\n if (widgetState === 'open' || widgetState === 'closed') {\n data.widgetState = widgetState\n }\n\n const userTraits = persistence.get_property(CONVERSATIONS_LEGACY_USER_TRAITS) as\n | UserProvidedTraits\n | undefined\n if (userTraits) {\n data.userTraits = userTraits\n }\n\n this._write(data)\n\n persistence.unregister(CONVERSATIONS_LEGACY_WIDGET_SESSION_ID)\n persistence.unregister(CONVERSATIONS_LEGACY_TICKET_ID)\n persistence.unregister(CONVERSATIONS_LEGACY_WIDGET_STATE)\n persistence.unregister(CONVERSATIONS_LEGACY_USER_TRAITS)\n\n logger.info('Migrated conversations data to dedicated storage')\n } catch (error) {\n logger.error('Migration from legacy persistence failed', error)\n }\n }\n\n /**\n * Fallback for migration: read legacy keys directly from raw localStorage\n * when PostHog persistence.props didn't load them (the original bug).\n */\n private _readLegacyFromRawStorage(): ConversationsStorageData | null {\n try {\n const token = this._posthog.config?.token\n if (!token) {\n return null\n }\n const key = (this._posthog.config as any).persistence_name\n ? 'ph_' + (this._posthog.config as any).persistence_name\n : 'ph_' + token + '_posthog'\n\n const raw = window?.localStorage?.getItem(key)\n if (!raw) {\n return null\n }\n\n const parsed = JSON.parse(raw)\n const widgetSessionId = parsed?.[CONVERSATIONS_LEGACY_WIDGET_SESSION_ID]\n if (typeof widgetSessionId !== 'string' || !widgetSessionId) {\n return null\n }\n\n const data: ConversationsStorageData = { widgetSessionId }\n\n const ticketId = parsed?.[CONVERSATIONS_LEGACY_TICKET_ID]\n if (ticketId) {\n data.ticketId = ticketId\n }\n\n const widgetState = parsed?.[CONVERSATIONS_LEGACY_WIDGET_STATE]\n if (widgetState === 'open' || widgetState === 'closed') {\n data.widgetState = widgetState\n }\n\n const userTraits = parsed?.[CONVERSATIONS_LEGACY_USER_TRAITS]\n if (userTraits) {\n data.userTraits = userTraits\n }\n\n return data\n } catch {\n return null\n }\n }\n}\n","// Inline styles following PostHog design system\n\nimport type { WidgetPosition } from '../../../../posthog-conversations-types'\nimport { Z_INDEX_CONVERSATIONS } from '../../../../constants'\n\n/**\n * Calculate contrasting text color (black or white) based on background brightness\n * Uses HSP (Highly Sensitive Purity) brightness formula\n */\nfunction getContrastTextColor(hexColor: string): string {\n const hex = hexColor.replace(/^#/, '')\n const fullHex = hex.length === 3 ? hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] : hex\n\n const r = parseInt(fullHex.slice(0, 2), 16)\n const g = parseInt(fullHex.slice(2, 4), 16)\n const b = parseInt(fullHex.slice(4, 6), 16)\n\n // HSP brightness formula\n const hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b))\n return hsp > 127.5 ? '#020617' : 'white'\n}\n\nexport const getStyles = (primaryColor: string, position: WidgetPosition = 'bottom_right') => {\n const isLeft = position.includes('left')\n const isTop = position.includes('top')\n\n return {\n widget: {\n position: 'fixed' as const,\n ...(isTop ? { top: '20px' } : { bottom: '20px' }),\n ...(isLeft ? { left: '20px' } : { right: '20px' }),\n zIndex: Z_INDEX_CONVERSATIONS,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Inter\", \"Segoe UI\", \"Roboto\", Helvetica, Arial, sans-serif',\n },\n buttonContainer: {\n position: 'relative' as const,\n },\n button: {\n width: '50px',\n height: '50px',\n borderRadius: '50%',\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n border: 'none',\n cursor: 'pointer',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'transform 0.2s ease-out, box-shadow 0.2s ease-out',\n },\n unreadBadge: {\n position: 'absolute' as const,\n ...(isTop ? { bottom: '-4px' } : { top: '-4px' }),\n ...(isLeft ? { left: '-4px' } : { right: '-4px' }),\n minWidth: '20px',\n height: '20px',\n borderRadius: '10px',\n background: '#ef4444',\n color: 'white',\n fontSize: '11px',\n fontWeight: 600,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0 5px',\n boxShadow: '0 2px 4px rgba(0, 0, 0, 0.2)',\n border: '2px solid white',\n boxSizing: 'border-box' as const,\n },\n window: {\n position: 'absolute' as const,\n ...(isTop ? { top: 0 } : { bottom: 0 }),\n ...(isLeft ? { left: 0 } : { right: 0 }),\n background: 'white',\n borderRadius: '10px',\n boxShadow: '0 10px 25px -3px rgba(0,0,0,0.12), 0 4px 12px -2px rgba(0,0,0,0.10)',\n display: 'flex',\n flexDirection: 'column' as const,\n overflow: 'hidden',\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n //border: '1px solid #dcdcdc',\n border: 'none',\n },\n windowOpen: {\n width: '400px',\n maxWidth: 'calc(100vw - 40px)',\n height: '600px',\n maxHeight: 'calc(100vh - 100px)',\n },\n header: {\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n padding: '8px 12px',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexShrink: 0,\n },\n headerTitle: {\n fontWeight: 500,\n fontSize: '14px',\n },\n headerActions: {\n display: 'flex',\n gap: '4px',\n alignItems: 'center',\n },\n headerLinkButton: {\n background: 'transparent',\n border: 'none',\n color: getContrastTextColor(primaryColor),\n cursor: 'pointer',\n padding: '6px 8px',\n fontSize: '12px',\n borderRadius: '4px',\n opacity: 0.9,\n },\n headerButton: {\n background: 'transparent',\n border: 'none',\n color: getContrastTextColor(primaryColor),\n cursor: 'pointer',\n padding: '6px 8px',\n fontSize: '16px',\n lineHeight: 1,\n borderRadius: '4px',\n transition: 'background 0.2s ease-out',\n opacity: 0.9,\n },\n messages: {\n flex: 1,\n overflowY: 'auto' as const,\n padding: '14px',\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '8px',\n background: 'white',\n },\n message: {\n display: 'flex',\n flexDirection: 'column' as const,\n maxWidth: '85%',\n animation: 'fadeIn 0.2s ease-out',\n },\n messageCustomer: {\n alignSelf: 'flex-end',\n alignItems: 'flex-end',\n },\n messageAgent: {\n alignSelf: 'flex-start',\n alignItems: 'flex-start',\n },\n messageAuthor: {\n fontSize: '10px',\n color: '#939393',\n marginBottom: '4px',\n fontWeight: 500,\n },\n messageContent: {\n padding: '8px 12px',\n borderRadius: '8px',\n fontSize: '12px',\n lineHeight: 1.5,\n wordWrap: 'break-word' as const,\n whiteSpace: 'pre-wrap' as const,\n },\n messageContentCustomer: {\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n borderBottomRightRadius: '2px',\n },\n messageContentAgent: {\n background: 'white',\n color: '#020617',\n border: '1.5px solid #dcdcdc',\n borderBottomLeftRadius: '2px',\n },\n messageTime: {\n fontSize: '10px',\n color: '#939393',\n marginTop: '4px',\n opacity: 0.8,\n },\n error: {\n padding: '10px 16px',\n background: '#fee2e2',\n color: '#991b1b',\n fontSize: '13px',\n borderTop: '1px solid #fecaca',\n borderBottom: '1px solid #fecaca',\n textAlign: 'center' as const,\n fontWeight: 500,\n },\n inputContainer: {\n padding: '8px 12px',\n background: 'white',\n borderTop: '1px solid #dcdcdc',\n display: 'flex',\n gap: '8px',\n alignItems: 'center', // Changed from flex-end to center to vertically align input and sendButton\n flexShrink: 0,\n },\n resolvedBanner: {\n paddingTop: '12px',\n background: 'white',\n borderTop: '1px solid #dcdcdc',\n display: 'flex',\n flexDirection: 'column' as const,\n flexShrink: 0,\n },\n resolvedBannerText: {\n padding: '0 20px',\n fontSize: '13px',\n color: '#64748b',\n textAlign: 'center' as const,\n lineHeight: 1.5,\n },\n input: {\n flex: 1,\n maxHeight: '120px',\n fontSize: '14px',\n resize: 'vertical',\n fontFamily: 'inherit',\n lineHeight: 1.5,\n color: '#020617',\n background: 'white',\n border: 'none',\n outline: 'none',\n transition: 'border-color 0.2s ease-out, box-shadow 0.2s ease-out',\n display: 'flex',\n alignItems: 'center',\n fieldSizing: 'content',\n },\n sendButton: {\n width: '33px',\n height: '33px', // Match input minHeight for vertical alignment\n borderRadius: '10px',\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n border: 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'all 0.2s ease-out',\n boxShadow: '0 2px 0 rgba(0, 0, 0, 0.045)',\n fontWeight: 700,\n flexShrink: 0,\n },\n // Identification form styles\n identificationForm: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column' as const,\n padding: '24px',\n background: '#eeeded',\n overflowY: 'auto' as const,\n },\n formTitle: {\n fontSize: '18px',\n fontWeight: 600,\n color: '#020617',\n marginBottom: '8px',\n },\n formDescription: {\n fontSize: '14px',\n color: '#64748b',\n marginBottom: '24px',\n lineHeight: 1.5,\n },\n recoverFooter: {\n padding: '10px 14px',\n borderTop: '1px solid #e5e7eb',\n fontSize: '12px',\n color: '#64748b',\n lineHeight: 1.5,\n flexShrink: 0,\n textAlign: 'center',\n },\n recoverFooterLink: {\n background: 'none',\n border: 'none',\n padding: 0,\n color: '#64748b',\n cursor: 'pointer',\n fontSize: '12px',\n fontFamily: 'inherit',\n textDecoration: 'underline',\n },\n formField: {\n marginBottom: '16px',\n },\n formLabel: {\n display: 'block',\n fontSize: '13px',\n fontWeight: 500,\n color: '#020617',\n marginBottom: '6px',\n },\n formInput: {\n width: '100%',\n padding: '10px 12px',\n border: '1px solid #dcdcdc',\n borderRadius: '6px',\n fontSize: '14px',\n fontFamily: 'inherit',\n color: '#020617',\n background: 'white',\n transition: 'border-color 0.2s ease-out, box-shadow 0.2s ease-out',\n boxSizing: 'border-box' as const,\n },\n formInputError: {\n borderColor: '#ef4444',\n },\n formError: {\n fontSize: '12px',\n color: '#ef4444',\n marginTop: '4px',\n },\n formSubmitButton: {\n width: '100%',\n padding: '12px 16px',\n borderRadius: '6px',\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: 600,\n transition: 'all 0.2s ease-out',\n marginTop: '8px',\n },\n formOptional: {\n fontSize: '12px',\n color: '#939393',\n fontWeight: 400,\n },\n restoreRequestSuccess: {\n marginTop: '12px',\n fontSize: '12px',\n color: '#166534',\n background: '#dcfce7',\n border: '1px solid #86efac',\n borderRadius: '6px',\n padding: '10px 12px',\n lineHeight: 1.4,\n },\n // Ticket list styles\n ticketListContainer: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column' as const,\n background: 'white',\n overflowY: 'auto' as const,\n },\n ticketList: {\n flex: 1,\n overflowY: 'auto' as const,\n },\n ticketItem: {\n padding: '14px 16px',\n borderBottom: '1px solid #f1f1f1',\n cursor: 'pointer',\n transition: 'background 0.15s ease-out',\n background: 'white',\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n },\n ticketItemUnread: {\n background: '#fafafa',\n },\n ticketItemContent: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '6px',\n flex: 1,\n minWidth: 0, // Allow text truncation\n },\n ticketItemArrow: {\n color: '#939393',\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n },\n ticketItemHeader: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n gap: '8px',\n },\n ticketPreview: {\n fontSize: '13px',\n color: '#020617',\n lineHeight: 1.4,\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap' as const,\n },\n ticketPreviewUnread: {\n fontSize: '13px',\n color: '#020617',\n lineHeight: 1.4,\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap' as const,\n fontWeight: 600,\n },\n ticketUnreadBadge: {\n minWidth: '18px',\n height: '18px',\n borderRadius: '9px',\n background: '#ef4444',\n color: 'white',\n fontSize: '10px',\n fontWeight: 600,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0 5px',\n flexShrink: 0,\n },\n ticketMeta: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n },\n ticketTime: {\n fontSize: '11px',\n color: '#939393',\n },\n ticketStatus: {\n fontSize: '10px',\n color: '#64748b',\n background: '#f1f5f9',\n padding: '2px 6px',\n borderRadius: '4px',\n textTransform: 'uppercase' as const,\n letterSpacing: '0.3px',\n },\n newConversationButton: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '12px 16px',\n padding: '10px 16px',\n borderRadius: '8px',\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n fontWeight: 500,\n transition: 'all 0.2s ease-out',\n },\n // Ticket list loading state\n ticketListLoading: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column' as const,\n alignItems: 'center',\n justifyContent: 'center',\n gap: '12px',\n color: '#64748b',\n fontSize: '13px',\n },\n loadingSpinner: {\n width: '24px',\n height: '24px',\n border: '2px solid #e2e8f0',\n borderTop: `2px solid ${primaryColor}`,\n borderRadius: '50%',\n animation: 'spin 0.8s linear infinite',\n },\n // Ticket list empty state\n ticketListEmpty: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column' as const,\n alignItems: 'center',\n justifyContent: 'center',\n padding: '32px 24px',\n textAlign: 'center' as const,\n },\n emptyStateIcon: {\n color: '#cbd5e1',\n marginBottom: '16px',\n },\n emptyStateTitle: {\n fontSize: '16px',\n fontWeight: 600,\n color: '#020617',\n marginBottom: '8px',\n },\n emptyStateDescription: {\n fontSize: '13px',\n color: '#64748b',\n lineHeight: 1.5,\n marginBottom: '20px',\n },\n newConversationButtonLarge: {\n padding: '12px 24px',\n borderRadius: '8px',\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: 600,\n transition: 'all 0.2s ease-out',\n },\n fetchPreviousButton: {\n marginTop: '10px',\n background: 'transparent',\n border: 'none',\n color: primaryColor,\n cursor: 'pointer',\n fontSize: '13px',\n textDecoration: 'underline',\n opacity: 1,\n },\n // Back button for message view header\n backButton: {\n background: 'transparent',\n border: 'none',\n color: getContrastTextColor(primaryColor),\n cursor: 'pointer',\n padding: '6px 0px',\n marginRight: '4px',\n fontSize: '16px',\n lineHeight: 1,\n borderRadius: '4px',\n transition: 'background 0.2s ease-out',\n opacity: 0.9,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n // Header with back button layout\n headerWithBack: {\n display: 'flex',\n alignItems: 'center',\n },\n }\n}\n","import type { WidgetPosition } from '../../../../posthog-conversations-types'\nimport { getStyles } from './styles'\n\ninterface OpenChatButtonProps {\n primaryColor: string\n position?: WidgetPosition\n handleToggleOpen: () => void\n unreadCount?: number\n}\n\nexport const OpenChatButton = ({\n primaryColor,\n position = 'bottom_right',\n handleToggleOpen,\n unreadCount = 0,\n}: OpenChatButtonProps) => {\n const styles = getStyles(primaryColor, position)\n const displayCount = unreadCount > 99 ? '99+' : unreadCount.toString()\n\n return (\n <div style={styles.widget}>\n <div style={styles.buttonContainer}>\n <button\n style={styles.button}\n onClick={handleToggleOpen}\n aria-label={unreadCount > 0 ? `Open chat (${unreadCount} unread)` : 'Open chat'}\n onMouseEnter={(e) => {\n e.currentTarget.style.transform = 'scale(1.05)'\n e.currentTarget.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.2)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.transform = 'scale(1)'\n e.currentTarget.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15)'\n }}\n >\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 2C6.48 2 2 6.48 2 12C2 13.93 2.6 15.71 3.64 17.18L2.5 21.5L7.04 20.42C8.46 21.28 10.17 21.75 12 21.75C17.52 21.75 22 17.27 22 11.75C22 6.23 17.52 2 12 2Z\"\n fill=\"currentColor\"\n />\n </svg>\n </button>\n {unreadCount > 0 && <div style={styles.unreadBadge}>{displayCount}</div>}\n </div>\n </div>\n )\n}\n","import { getStyles } from './styles'\n\ninterface CloseChatButtonProps {\n primaryColor: string\n handleClose: () => void\n}\n\nexport const CloseChatButton = ({ primaryColor, handleClose }: CloseChatButtonProps) => {\n const styles = getStyles(primaryColor)\n return (\n <button\n style={styles.headerButton}\n onClick={handleClose}\n aria-label=\"Close\"\n onMouseEnter={(e) => {\n e.currentTarget.style.background = 'rgba(255, 255, 255, 0.15)'\n e.currentTarget.style.opacity = '1'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = 'transparent'\n e.currentTarget.style.opacity = '0.9'\n }}\n >\n ✕\n </button>\n )\n}\n","/**\n * Format a timestamp to a relative time string\n */\nexport function formatRelativeTime(isoString: string | undefined): string {\n if (!isoString) {\n return ''\n }\n\n const date = new Date(isoString)\n const now = new Date()\n const diffMs = now.getTime() - date.getTime()\n const diffMins = Math.floor(diffMs / 60000)\n const diffHours = Math.floor(diffMins / 60)\n const diffDays = Math.floor(diffHours / 24)\n\n if (diffMins < 1) {\n return 'Just now'\n } else if (diffMins < 60) {\n return `${diffMins}m ago`\n } else if (diffHours < 24) {\n return `${diffHours}h ago`\n } else if (diffDays === 1) {\n return 'Yesterday'\n } else if (diffDays < 7) {\n return `${diffDays}d ago`\n } else {\n return date.toLocaleDateString()\n }\n}\n\n/**\n * Truncate text to a maximum length with ellipsis\n */\nexport function truncateText(text: string | undefined, maxLength: number): string {\n if (!text) {\n return 'No messages yet'\n }\n if (text.length <= maxLength) {\n return text\n }\n return text.substring(0, maxLength - 3) + '...'\n}\n\n/**\n * Strip markdown formatting from text for plain text display\n * Lightweight regex-based approach without external dependencies\n */\nexport function stripMarkdown(text: string | undefined): string {\n if (!text) {\n return ''\n }\n\n return (\n text\n // Remove code blocks first (before other processing)\n .replace(/```[\\s\\S]*?```/g, '')\n // Remove inline code\n .replace(/`([^`]+)`/g, '$1')\n // Remove images\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, '')\n // Convert links to just text\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n // Remove headers\n .replace(/^#{1,6}\\s+/gm, '')\n // Remove blockquotes\n .replace(/^>\\s*/gm, '')\n // Remove horizontal rules (must be before list markers to avoid conflicts)\n .replace(/^[-*_]{3,}\\s*$/gm, '')\n // Remove list markers (must be before bold/italic to avoid conflicts with *)\n .replace(/^[\\s]*[-*+]\\s+/gm, '')\n .replace(/^[\\s]*\\d+\\.\\s+/gm, '')\n // Remove bold/italic (order matters: ** before *)\n .replace(/\\*\\*([^*]+)\\*\\*/g, '$1')\n .replace(/\\*([^*]+)\\*/g, '$1')\n .replace(/__([^_]+)__/g, '$1')\n .replace(/_([^_]+)_/g, '$1')\n // Remove strikethrough\n .replace(/~~([^~]+)~~/g, '$1')\n // Remove HTML tags entirely, then strip any remaining angle brackets for security\n .replace(/<[^>]*>/g, '')\n .replace(/[<>]/g, '')\n // Collapse multiple newlines\n .replace(/\\n{2,}/g, '\\n')\n // Trim whitespace\n .trim()\n )\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, FunctionComponent } from 'preact'\nimport { Ticket, TicketStatus } from '../../../../posthog-conversations-types'\nimport { getStyles } from './styles'\nimport { formatRelativeTime, truncateText, stripMarkdown } from './utils'\n\ninterface TicketListItemProps {\n ticket: Ticket\n styles: ReturnType<typeof getStyles>\n onClick: (ticketId: string) => void\n}\n\n/**\n * Get a human-readable status label\n * Matches the display logic in PostHog main app\n */\nfunction getStatusLabel(status: TicketStatus): string {\n if (status === 'on_hold') {\n return 'On hold'\n }\n // Capitalize first letter: 'new' -> 'New', 'open' -> 'Open', etc.\n return status.charAt(0).toUpperCase() + status.slice(1)\n}\n\n/**\n * A single ticket item in the ticket list\n */\nexport const TicketListItem: FunctionComponent<TicketListItemProps> = ({ ticket, styles, onClick }) => {\n const hasUnread = (ticket.unread_count || 0) > 0\n const statusLabel = getStatusLabel(ticket.status)\n\n const handleClick = () => {\n onClick(ticket.id)\n }\n\n const itemStyle = {\n ...styles.ticketItem,\n ...(hasUnread ? styles.ticketItemUnread : {}),\n }\n\n return (\n <div\n style={itemStyle}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n handleClick()\n }\n }}\n role=\"button\"\n tabIndex={0}\n >\n <div style={styles.ticketItemContent}>\n <div style={styles.ticketItemHeader}>\n <span style={hasUnread ? styles.ticketPreviewUnread : styles.ticketPreview}>\n {truncateText(stripMarkdown(ticket.last_message), 60)}\n </span>\n {hasUnread && <span style={styles.ticketUnreadBadge}>{ticket.unread_count}</span>}\n </div>\n <div style={styles.ticketMeta}>\n <span style={styles.ticketTime}>\n {formatRelativeTime(ticket.last_message_at || ticket.created_at)}\n </span>\n <span style={styles.ticketStatus}>{statusLabel}</span>\n </div>\n </div>\n {/* Right arrow indicator */}\n <div style={styles.ticketItemArrow}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n </div>\n </div>\n )\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, FunctionComponent } from 'preact'\nimport { getStyles } from './styles'\n\ninterface NewConversationButtonProps {\n styles: ReturnType<typeof getStyles>\n onClick: () => void\n}\n\n/**\n * Primary CTA used anywhere the user can start a fresh conversation —\n * the bottom of the ticket list and the resolved-state banner in the message view.\n */\nexport const NewConversationButton: FunctionComponent<NewConversationButtonProps> = ({ styles, onClick }) => (\n <button\n type=\"button\"\n style={styles.newConversationButton}\n onClick={onClick}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '0.9'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n style={{ marginRight: '8px' }}\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n New conversation\n </button>\n)\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, FunctionComponent } from 'preact'\nimport { Ticket } from '../../../../posthog-conversations-types'\nimport { getStyles } from './styles'\nimport { TicketListItem } from './TicketListItem'\nimport { NewConversationButton } from './NewConversationButton'\n\ninterface TicketListViewProps {\n tickets: Ticket[]\n isLoading: boolean\n styles: ReturnType<typeof getStyles>\n onSelectTicket: (ticketId: string) => void\n onNewConversation: () => void\n onOpenRestoreRequest: () => void\n}\n\n/**\n * Loading state component\n */\nconst LoadingState: FunctionComponent<{ styles: ReturnType<typeof getStyles> }> = ({ styles }) => (\n <div style={styles.ticketListLoading}>\n <div style={styles.loadingSpinner} />\n <span>Loading conversations...</span>\n </div>\n)\n\n/**\n * Empty state component when there are no tickets\n */\nconst EmptyState: FunctionComponent<{\n styles: ReturnType<typeof getStyles>\n onNewConversation: () => void\n onOpenRestoreRequest: () => void\n}> = ({ styles, onNewConversation, onOpenRestoreRequest }) => (\n <div style={styles.ticketListEmpty}>\n <div style={styles.emptyStateIcon}>\n <svg width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n </div>\n <div style={styles.emptyStateTitle}>No conversations yet</div>\n <div style={styles.emptyStateDescription}>Start a new conversation to get help from our team.</div>\n <button\n style={styles.newConversationButtonLarge}\n onClick={onNewConversation}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '0.9'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n >\n Start a conversation\n </button>\n <button\n style={styles.fetchPreviousButton}\n onClick={onOpenRestoreRequest}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '0.8'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n >\n Fetch previous conversations\n </button>\n </div>\n)\n\n/**\n * Ticket list view showing all user's tickets\n */\nexport const TicketListView: FunctionComponent<TicketListViewProps> = ({\n tickets,\n isLoading,\n styles,\n onSelectTicket,\n onNewConversation,\n onOpenRestoreRequest,\n}) => {\n // Show loading state\n if (isLoading && tickets.length === 0) {\n return <LoadingState styles={styles} />\n }\n\n // Show empty state when no tickets\n if (tickets.length === 0) {\n return (\n <EmptyState\n styles={styles}\n onNewConversation={onNewConversation}\n onOpenRestoreRequest={onOpenRestoreRequest}\n />\n )\n }\n\n // Show ticket list\n return (\n <div style={styles.ticketListContainer}>\n {/* Ticket list - sorted by most recent activity */}\n <div style={styles.ticketList}>\n {[...tickets]\n .sort((a, b) => {\n const dateA = new Date(a.last_message_at || a.created_at).getTime()\n const dateB = new Date(b.last_message_at || b.created_at).getTime()\n return dateB - dateA // Descending order (newest first)\n })\n .map((ticket) => (\n <TicketListItem\n key={`${ticket.id}-${ticket.last_message_at || ticket.created_at}-${ticket.unread_count}`}\n ticket={ticket}\n styles={styles}\n onClick={onSelectTicket}\n />\n ))}\n </div>\n\n {/* New conversation button at bottom */}\n <NewConversationButton styles={styles} onClick={onNewConversation} />\n </div>\n )\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h } from 'preact'\nimport { ConversationsRemoteConfig } from '../../../../posthog-conversations-types'\nimport { getStyles } from './styles'\n\ninterface IdentificationFormViewProps {\n config: ConversationsRemoteConfig\n styles: ReturnType<typeof getStyles>\n formName: string\n formEmail: string\n formEmailError: string | null\n onNameChange: (e: Event) => void\n onEmailChange: (e: Event) => void\n onSubmit: (e: Event) => void\n}\n\nexport function IdentificationFormView({\n config,\n styles,\n formName,\n formEmail,\n formEmailError,\n onNameChange,\n onEmailChange,\n onSubmit,\n}: IdentificationFormViewProps) {\n const title = config.identificationFormTitle || 'Before we start...'\n const description = config.identificationFormDescription || 'Please provide your details so we can help you better.'\n const showNameField = config.collectName !== false\n\n return (\n <div style={styles.identificationForm}>\n <div style={styles.formTitle}>{title}</div>\n <div style={styles.formDescription}>{description}</div>\n\n <form onSubmit={onSubmit}>\n {showNameField && (\n <div style={styles.formField}>\n <label style={styles.formLabel}>\n Name <span style={styles.formOptional}>(optional)</span>\n </label>\n <input\n type=\"text\"\n style={styles.formInput}\n value={formName}\n onInput={onNameChange}\n placeholder=\"Your name\"\n autoComplete=\"name\"\n />\n </div>\n )}\n\n <div style={styles.formField}>\n <label style={styles.formLabel}>\n Email {!config.requireEmail && <span style={styles.formOptional}>(optional)</span>}\n </label>\n <input\n type=\"email\"\n style={{\n ...styles.formInput,\n ...(formEmailError ? styles.formInputError : {}),\n }}\n value={formEmail}\n onInput={onEmailChange}\n placeholder=\"you@example.com\"\n autoComplete=\"email\"\n />\n {formEmailError && <div style={styles.formError}>{formEmailError}</div>}\n </div>\n\n <button\n type=\"submit\"\n style={styles.formSubmitButton}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '0.9'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n >\n Start Chat\n </button>\n </form>\n </div>\n )\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h } from 'preact'\nimport { getStyles } from './styles'\n\ninterface RestoreRequestViewProps {\n styles: ReturnType<typeof getStyles>\n restoreEmail: string\n restoreEmailError: string | null\n restoreRequestLoading: boolean\n restoreRequestSuccess: boolean\n onEmailChange: (e: Event) => void\n onSubmit: (e: Event) => void\n}\n\nexport function RestoreRequestView({\n styles,\n restoreEmail,\n restoreEmailError,\n restoreRequestLoading,\n restoreRequestSuccess,\n onEmailChange,\n onSubmit,\n}: RestoreRequestViewProps) {\n return (\n <div style={styles.identificationForm}>\n <div style={styles.formTitle}>Restore conversations</div>\n <div style={styles.formDescription}>\n Don't see your previous conversations? Maybe you use another browser or computer. Enter your email and\n we will send a secure restore link if matching conversations exist.\n </div>\n\n <form onSubmit={onSubmit}>\n <div style={styles.formField}>\n <label style={styles.formLabel}>Email</label>\n <input\n type=\"email\"\n style={{\n ...styles.formInput,\n ...(restoreEmailError ? styles.formInputError : {}),\n }}\n value={restoreEmail}\n onInput={onEmailChange}\n placeholder=\"you@example.com\"\n autoComplete=\"email\"\n disabled={restoreRequestLoading}\n />\n {restoreEmailError && <div style={styles.formError}>{restoreEmailError}</div>}\n </div>\n\n <button type=\"submit\" style={styles.formSubmitButton} disabled={restoreRequestLoading}>\n {restoreRequestLoading ? 'Sending...' : 'Send restore link'}\n </button>\n </form>\n\n {restoreRequestSuccess && (\n <div style={styles.restoreRequestSuccess}>\n Check your email for a secure restore link. If an account is found, we sent it.\n </div>\n )}\n </div>\n )\n}\n","import { getStyles } from './styles'\n\ninterface SendMessageButtonProps {\n primaryColor: string\n inputValue: string\n isLoading: boolean\n handleSendMessage: () => void\n}\n\nexport const SendMessageButton = ({\n primaryColor,\n inputValue,\n isLoading,\n handleSendMessage,\n}: SendMessageButtonProps) => {\n const styles = getStyles(primaryColor)\n return (\n <button\n style={{\n ...styles.sendButton,\n opacity: !inputValue.trim() || isLoading ? 0.6 : 1,\n cursor: !inputValue.trim() || isLoading ? 'not-allowed' : 'pointer',\n }}\n onClick={handleSendMessage}\n disabled={!inputValue.trim() || isLoading}\n aria-label=\"Send message\"\n onMouseEnter={(e) => {\n if (!e.currentTarget.disabled) {\n e.currentTarget.style.transform = 'scale(1.02)'\n e.currentTarget.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.1)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.transform = 'scale(1)'\n e.currentTarget.style.boxShadow = '0 2px 0 rgba(0, 0, 0, 0.045)'\n }}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M2 10L18 2L10 18L8 11L2 10Z\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n )\n}\n","import{options as n}from\"preact\";var t,r,u,i,o=0,f=[],c=n,e=c.__b,a=c.__r,v=c.diffed,l=c.__c,m=c.unmount,s=c.__;function p(n,t){c.__h&&c.__h(r,n,o||t),o=0;var u=r.__H||(r.__H={__:[],__h:[]});return n>=u.__.length&&u.__.push({}),u.__[n]}function d(n){return o=1,h(D,n)}function h(n,u,i){var o=p(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):D(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.__f)){var f=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return!!n.__c});if(u.every(function(n){return!n.__N}))return!c||c.call(this,n,t,r);var i=o.__c.props!==n;return u.forEach(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),c&&c.call(this,n,t,r)||i};r.__f=!0;var c=r.shouldComponentUpdate,e=r.componentWillUpdate;r.componentWillUpdate=function(n,t,r){if(this.__e){var u=c;c=void 0,f(n,t,r),c=u}e&&e.call(this,n,t,r)},r.shouldComponentUpdate=f}return o.__N||o.__}function y(n,u){var i=p(t++,3);!c.__s&&C(i.__H,u)&&(i.__=n,i.u=u,r.__H.__h.push(i))}function _(n,u){var i=p(t++,4);!c.__s&&C(i.__H,u)&&(i.__=n,i.u=u,r.__h.push(i))}function A(n){return o=5,T(function(){return{current:n}},[])}function F(n,t,r){o=6,_(function(){if(\"function\"==typeof n){var r=n(t());return function(){n(null),r&&\"function\"==typeof r&&r()}}if(n)return n.current=t(),function(){return n.current=null}},null==r?r:r.concat(n))}function T(n,r){var u=p(t++,7);return C(u.__H,r)&&(u.__=n(),u.__H=r,u.__h=n),u.__}function q(n,t){return o=8,T(function(){return n},t)}function x(n){var u=r.context[n.__c],i=p(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function P(n,t){c.useDebugValue&&c.useDebugValue(t?t(n):n)}function b(n){var u=p(t++,10),i=d();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n,t){u.__&&u.__(n,t),i[1](n)}),[i[0],function(){i[1](void 0)}]}function g(){var n=p(t++,11);if(!n.__){for(var u=r.__v;null!==u&&!u.__m&&null!==u.__;)u=u.__;var i=u.__m||(u.__m=[0,0]);n.__=\"P\"+i[0]+\"-\"+i[1]++}return n.__}function j(){for(var n;n=f.shift();)if(n.__P&&n.__H)try{n.__H.__h.forEach(z),n.__H.__h.forEach(B),n.__H.__h=[]}catch(t){n.__H.__h=[],c.__e(t,n.__v)}}c.__b=function(n){r=null,e&&e(n)},c.__=function(n,t){n&&t.__k&&t.__k.__m&&(n.__m=t.__k.__m),s&&s(n,t)},c.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0})):(i.__h.forEach(z),i.__h.forEach(B),i.__h=[],t=0)),u=r},c.diffed=function(n){v&&v(n);var t=n.__c;t&&t.__H&&(t.__H.__h.length&&(1!==f.push(t)&&i===c.requestAnimationFrame||((i=c.requestAnimationFrame)||w)(j)),t.__H.__.forEach(function(n){n.u&&(n.__H=n.u),n.u=void 0})),u=r=null},c.__c=function(n,t){t.some(function(n){try{n.__h.forEach(z),n.__h=n.__h.filter(function(n){return!n.__||B(n)})}catch(r){t.some(function(n){n.__h&&(n.__h=[])}),t=[],c.__e(r,n.__v)}}),l&&l(n,t)},c.unmount=function(n){m&&m(n);var t,r=n.__c;r&&r.__H&&(r.__H.__.forEach(function(n){try{z(n)}catch(n){t=n}}),r.__H=void 0,t&&c.__e(t,r.__v))};var k=\"function\"==typeof requestAnimationFrame;function w(n){var t,r=function(){clearTimeout(u),k&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,35);k&&(t=requestAnimationFrame(r))}function z(n){var t=r,u=n.__c;\"function\"==typeof u&&(n.__c=void 0,u()),r=t}function B(n){var t=r;n.__c=n.__(),r=t}function C(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function D(n,t){return\"function\"==typeof t?t(n):t}export{q as useCallback,x as useContext,P as useDebugValue,y as useEffect,b as useErrorBoundary,g as useId,F as useImperativeHandle,_ as useLayoutEffect,T as useMemo,h as useReducer,A as useRef,d as useState};\n//# sourceMappingURL=hooks.module.js.map\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, Fragment } from 'preact'\nimport { useMemo } from 'preact/hooks'\nimport { isUndefined, isNumber, isArray } from '@posthog/core'\nimport { TipTapDoc, TipTapNode, TipTapMark } from '../../../../posthog-conversations-types'\n\ninterface RichContentProps {\n /** Rich content in TipTap JSON format (preferred) */\n richContent?: TipTapDoc\n /** Plain text fallback if rich_content is missing or invalid */\n content: string\n /** Whether message is from customer (affects styling) */\n isCustomer: boolean\n /** Primary color for links */\n primaryColor: string\n}\n\n/**\n * Sanitize URL to prevent javascript: and other dangerous protocols.\n * Only allows http:, https:, mailto:, tel:, and relative URLs.\n *\n * Security measures:\n * - Removes ASCII control characters (0x00-0x1F, 0x7F) that could obfuscate protocols\n * - Removes Unicode whitespace and zero-width characters\n * - Collapses whitespace when checking protocols to prevent \"java script:\" bypasses\n * - Blocks javascript:, vbscript:, data:, and file: protocols\n * - Blocks protocol-relative URLs (//example.com)\n */\nfunction sanitizeUrl(url: string): string | undefined {\n if (!url || typeof url !== 'string') {\n return undefined\n }\n\n // Remove ASCII control characters (0x00-0x1F, 0x7F DEL) that could obfuscate protocols\n // Also remove zero-width characters (U+200B-U+200D, U+FEFF) that could be used for obfuscation\n // eslint-disable-next-line no-control-regex\n const cleanedUrl = url.replace(/[\\x00-\\x1f\\x7f\\u200b-\\u200d\\ufeff]/g, '')\n const trimmedUrl = cleanedUrl.trim()\n if (!trimmedUrl) {\n return undefined\n }\n\n // Collapse all whitespace (including Unicode whitespace) when checking protocol\n // This prevents bypasses like \"java script:\" or \"java\\u00A0script:\" (non-breaking space)\n const normalizedForCheck = trimmedUrl.replace(/\\s+/g, '').toLowerCase()\n\n // Block dangerous protocols\n if (\n normalizedForCheck.startsWith('javascript:') ||\n normalizedForCheck.startsWith('vbscript:') ||\n normalizedForCheck.startsWith('data:') ||\n normalizedForCheck.startsWith('file:')\n ) {\n return undefined\n }\n\n // Allow relative URLs (check against trimmed URL, not normalized)\n // Note: We explicitly check for '//' first to block protocol-relative URLs (e.g., //evil.com)\n // which could be used to load content from attacker-controlled domains\n if (trimmedUrl.startsWith('//')) {\n return undefined\n }\n if (\n trimmedUrl.startsWith('/') ||\n trimmedUrl.startsWith('./') ||\n trimmedUrl.startsWith('../') ||\n trimmedUrl.startsWith('#')\n ) {\n return trimmedUrl\n }\n\n // Allow safe absolute URLs\n const lowerUrl = trimmedUrl.toLowerCase()\n if (\n lowerUrl.startsWith('http://') ||\n lowerUrl.startsWith('https://') ||\n lowerUrl.startsWith('mailto:') ||\n lowerUrl.startsWith('tel:')\n ) {\n return trimmedUrl\n }\n\n return undefined\n}\n\n/** Maximum recursion depth to prevent stack overflow */\nconst MAX_DEPTH = 20\n\nfunction getStyles(isCustomer: boolean, primaryColor: string) {\n return {\n code: {\n fontFamily: 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace',\n fontSize: '0.9em',\n padding: '2px 4px',\n borderRadius: '3px',\n background: isCustomer ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.06)',\n },\n codeBlock: {\n fontFamily: 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace',\n fontSize: '0.85em',\n padding: '8px 10px',\n borderRadius: '6px',\n background: isCustomer ? 'rgba(255, 255, 255, 0.15)' : '#f4f4f5',\n overflowX: 'auto' as const,\n whiteSpace: 'pre-wrap' as const,\n wordWrap: 'break-word' as const,\n wordBreak: 'break-word' as const,\n margin: '8px 0',\n display: 'block',\n lineHeight: 1.5,\n border: isCustomer ? 'none' : '1px solid #e4e4e7',\n },\n link: {\n color: isCustomer ? 'white' : primaryColor,\n textDecoration: 'underline',\n },\n image: {\n maxWidth: '100%',\n borderRadius: '4px',\n marginTop: '4px',\n marginBottom: '4px',\n display: 'block',\n },\n }\n}\n\n/**\n * Render a text node with its marks (bold, italic, underline, etc.)\n * Marks are applied by wrapping the content in nested elements.\n */\nfunction renderTextWithMarks(\n text: string,\n marks: TipTapMark[] | undefined,\n styles: ReturnType<typeof getStyles>,\n key: string\n): preact.JSX.Element {\n if (!marks || marks.length === 0) {\n return <span key={key}>{text}</span>\n }\n\n // Build the element by wrapping with marks from inside out\n let element: preact.JSX.Element = <>{text}</>\n\n for (const mark of marks) {\n switch (mark.type) {\n case 'bold':\n element = <strong style={{ fontWeight: 700 }}>{element}</strong>\n break\n case 'italic':\n element = <em style={{ fontStyle: 'italic' }}>{element}</em>\n break\n case 'underline':\n element = <u style={{ textDecoration: 'underline' }}>{element}</u>\n break\n case 'strike':\n element = <s style={{ textDecoration: 'line-through' }}>{element}</s>\n break\n case 'code':\n element = <code style={styles.code}>{element}</code>\n break\n case 'link': {\n const href = mark.attrs?.href\n const safeUrl = typeof href === 'string' ? sanitizeUrl(href) : undefined\n if (safeUrl) {\n element = (\n <a\n href={safeUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n referrerPolicy=\"no-referrer\"\n style={styles.link}\n >\n {element}\n </a>\n )\n }\n break\n }\n // Ignore unknown mark types for safety\n }\n }\n\n return <span key={key}>{element}</span>\n}\n\n/**\n * Recursively render a TipTap node and its children\n */\nfunction renderNode(\n node: TipTapNode | TipTapDoc,\n styles: ReturnType<typeof getStyles>,\n depth: number,\n key: string\n): preact.JSX.Element | null {\n // Safety: prevent infinite recursion\n if (depth > MAX_DEPTH) {\n return null\n }\n\n // Text node with optional marks\n if (node.type === 'text' && !isUndefined(node.text)) {\n return renderTextWithMarks(node.text, node.marks, styles, key)\n }\n\n // Render children recursively\n const children = node.content?.map((child, index) => renderNode(child, styles, depth + 1, `${key}-${index}`)) || []\n\n switch (node.type) {\n case 'doc':\n return <>{children}</>\n\n case 'paragraph':\n return (\n <p key={key} style={{ margin: '0 0 8px 0' }}>\n {children.length > 0 ? children : <br />}\n </p>\n )\n\n case 'hardBreak':\n return <br key={key} />\n\n case 'codeBlock': {\n // Code blocks store text in content[0].text\n const codeText = node.content?.[0]?.text || ''\n return (\n <pre key={key} style={styles.codeBlock}>\n <code>{codeText}</code>\n </pre>\n )\n }\n\n case 'image': {\n const src = node.attrs?.src\n const alt = node.attrs?.alt\n const safeUrl = typeof src === 'string' ? sanitizeUrl(src) : undefined\n if (!safeUrl) {\n return null\n }\n return (\n <img\n key={key}\n src={safeUrl}\n alt={typeof alt === 'string' ? alt : ''}\n style={styles.image}\n onError={(e) => {\n ;(e.target as HTMLImageElement).style.display = 'none'\n }}\n />\n )\n }\n\n case 'bulletList':\n return (\n <ul key={key} style={{ margin: '8px 0', paddingLeft: '24px' }}>\n {children}\n </ul>\n )\n\n case 'orderedList':\n return (\n <ol key={key} style={{ margin: '8px 0', paddingLeft: '24px' }}>\n {children}\n </ol>\n )\n\n case 'listItem':\n return (\n <li key={key} style={{ margin: '4px 0' }}>\n {children}\n </li>\n )\n\n case 'blockquote':\n return (\n <blockquote\n key={key}\n style={{\n margin: '8px 0',\n paddingLeft: '12px',\n borderLeft: '3px solid #e4e4e7',\n color: '#71717a',\n }}\n >\n {children}\n </blockquote>\n )\n\n case 'heading': {\n const rawLevel = node.attrs?.level\n const level = isNumber(rawLevel) ? rawLevel : 1\n const HeadingTag = `h${Math.min(Math.max(level, 1), 6)}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'\n return (\n <HeadingTag key={key} style={{ margin: '12px 0 8px 0' }}>\n {children}\n </HeadingTag>\n )\n }\n\n case 'horizontalRule':\n return <hr key={key} style={{ margin: '12px 0', border: 'none', borderTop: '1px solid #e4e4e7' }} />\n\n default:\n // Unknown node types: render children if any, otherwise ignore\n if (children.length > 0) {\n return <span key={key}>{children}</span>\n }\n return null\n }\n}\n\n/**\n * Validate that the content looks like a valid TipTap document\n */\nfunction isValidTipTapDoc(doc: unknown): doc is TipTapDoc {\n if (!doc || typeof doc !== 'object') {\n return false\n }\n const d = doc as TipTapDoc\n return d.type === 'doc' && (isUndefined(d.content) || isArray(d.content))\n}\n\n/**\n * Render plain text with line breaks preserved\n */\nfunction renderPlainText(text: string): preact.JSX.Element {\n if (!text) {\n return <></>\n }\n const lines = text.split('\\n')\n return (\n <>\n {lines.map((line, index) => (\n <Fragment key={index}>\n {line}\n {index < lines.length - 1 && <br />}\n </Fragment>\n ))}\n </>\n )\n}\n\n/**\n * RichContent component - renders TipTap JSON content with plain text fallback\n *\n * Rendering logic:\n * 1. If richContent is present and valid, render as TipTap tree\n * 2. If richContent is missing or invalid, fall back to plain text content\n * 3. Wrap TipTap rendering in try/catch for safety\n */\nexport function RichContent({ richContent, content, isCustomer, primaryColor }: RichContentProps) {\n const styles = useMemo(() => getStyles(isCustomer, primaryColor), [isCustomer, primaryColor])\n\n // Try to render rich content if available\n if (richContent) {\n try {\n if (isValidTipTapDoc(richContent)) {\n const rendered = renderNode(richContent, styles, 0, 'root')\n if (rendered) {\n return rendered\n }\n }\n } catch {\n // Fall through to plain text on any error\n }\n }\n\n // Fallback: render plain text content\n return renderPlainText(content)\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, Fragment } from 'preact'\nimport { Message } from '../../../../posthog-conversations-types'\nimport { getStyles } from './styles'\nimport { SendMessageButton } from './SendMessageButton'\nimport { RichContent } from './RichContent'\nimport { NewConversationButton } from './NewConversationButton'\nimport { formatRelativeTime } from './utils'\n\ninterface MessagesViewProps {\n styles: ReturnType<typeof getStyles>\n primaryColor: string\n placeholderText: string\n messages: Message[]\n inputValue: string\n isLoading: boolean\n error: string | null\n isResolved: boolean\n onInputChange: (e: Event) => void\n onKeyDown: (e: KeyboardEvent) => void\n onSendMessage: () => void\n onStartNewConversation: () => void\n messagesEndRef: (el: HTMLDivElement | null) => void\n inputRef: (el: HTMLTextAreaElement | null) => void\n}\n\nfunction MessageBubble({\n message,\n styles,\n primaryColor,\n}: {\n message: Message\n styles: ReturnType<typeof getStyles>\n primaryColor: string\n}) {\n const isCustomer = message.author_type === 'customer'\n const messageStyle = {\n ...styles.message,\n ...(isCustomer ? styles.messageCustomer : styles.messageAgent),\n }\n const contentStyle = {\n ...styles.messageContent,\n ...(isCustomer ? styles.messageContentCustomer : styles.messageContentAgent),\n }\n\n return (\n <div key={message.id} style={messageStyle}>\n {!isCustomer && message.author_name && <div style={styles.messageAuthor}>{message.author_name}</div>}\n <div style={contentStyle}>\n <RichContent\n richContent={message.rich_content}\n content={message.content}\n isCustomer={isCustomer}\n primaryColor={primaryColor}\n />\n </div>\n <div style={styles.messageTime}>{formatRelativeTime(message.created_at)}</div>\n </div>\n )\n}\n\nexport function MessagesView({\n styles,\n primaryColor,\n placeholderText,\n messages,\n inputValue,\n isLoading,\n error,\n isResolved,\n onInputChange,\n onKeyDown,\n onSendMessage,\n onStartNewConversation,\n messagesEndRef,\n inputRef,\n}: MessagesViewProps) {\n return (\n <>\n <div style={styles.messages}>\n {messages.map((message) => (\n <MessageBubble key={message.id} message={message} styles={styles} primaryColor={primaryColor} />\n ))}\n <div ref={messagesEndRef} />\n </div>\n\n {error && <div style={styles.error}>{error}</div>}\n\n {isResolved ? (\n <div style={styles.resolvedBanner}>\n <div style={styles.resolvedBannerText}>This conversation was resolved.</div>\n <NewConversationButton styles={styles} onClick={onStartNewConversation} />\n </div>\n ) : (\n <div style={styles.inputContainer}>\n <textarea\n ref={inputRef}\n style={styles.input}\n placeholder={placeholderText}\n value={inputValue}\n onInput={onInputChange}\n onKeyDown={onKeyDown}\n rows={1}\n disabled={isLoading}\n />\n <SendMessageButton\n primaryColor={primaryColor}\n inputValue={inputValue}\n isLoading={isLoading}\n handleSendMessage={onSendMessage}\n />\n </div>\n )}\n </>\n )\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, Component } from 'preact'\nimport {\n ConversationsRemoteConfig,\n Message,\n ConversationsWidgetState,\n RequestRestoreLinkResponse,\n UserProvidedTraits,\n Ticket,\n} from '../../../../posthog-conversations-types'\nimport { createLogger } from '../../../../utils/logger'\nimport { getStyles } from './styles'\nimport { OpenChatButton } from './OpenChatButton'\nimport { CloseChatButton } from './CloseChatButton'\nimport { TicketListView } from './TicketListView'\nimport { IdentificationFormView } from './IdentificationFormView'\nimport { RestoreRequestView } from './RestoreRequestView'\nimport { MessagesView } from './MessagesView'\n\nconst logger = createLogger('[ConversationsWidget]')\n\n/**\n * Type for the current view in the widget\n */\nexport type WidgetView = 'tickets' | 'messages' | 'restore_request' | 'identification'\n\ninterface WidgetProps {\n config: ConversationsRemoteConfig\n initialState?: ConversationsWidgetState\n initialUserTraits?: UserProvidedTraits | null\n isUserIdentified?: boolean\n isIdentityMode?: boolean\n initialView?: WidgetView\n initialTickets?: Ticket[]\n showTicketList?: boolean\n onSendMessage: (message: string) => Promise<void>\n onStateChange?: (state: ConversationsWidgetState) => void\n onIdentify?: (traits: UserProvidedTraits) => void\n onRequestRestoreLink?: (email: string) => Promise<RequestRestoreLinkResponse>\n onSelectTicket?: (ticketId: string) => void\n onNewConversation?: () => void\n onBackToTickets?: () => void\n onViewChange?: (view: WidgetView) => void\n}\n\ninterface WidgetState {\n state: ConversationsWidgetState\n view: WidgetView\n messages: Message[]\n tickets: Ticket[]\n ticketsLoading: boolean\n inputValue: string\n isLoading: boolean\n error: string | null\n formName: string\n formEmail: string\n formEmailError: string | null\n userTraits: UserProvidedTraits | null\n unreadCount: number\n showTicketList: boolean\n isCurrentTicketResolved: boolean\n isIdentityMode: boolean\n restoreEmail: string\n restoreEmailError: string | null\n restoreRequestLoading: boolean\n restoreRequestSuccess: boolean\n}\n\nexport class ConversationsWidget extends Component<WidgetProps, WidgetState> {\n private _messagesEndRef: HTMLDivElement | null = null\n private _inputRef: HTMLTextAreaElement | null = null\n\n constructor(props: WidgetProps) {\n super(props)\n\n const isIdentityMode = props.isIdentityMode || false\n\n // Determine if we need to show the identification form\n const userTraits = props.initialUserTraits || null\n const needsIdentification = this._needsIdentification(\n props.config,\n userTraits,\n props.isUserIdentified,\n isIdentityMode\n )\n\n // If identification is needed, start with that view; otherwise use the provided initial view\n const initialView = needsIdentification ? 'identification' : props.initialView || 'messages'\n\n this.state = {\n state: props.initialState || 'closed',\n view: initialView,\n messages: [],\n tickets: props.initialTickets || [],\n ticketsLoading: false,\n inputValue: '',\n isLoading: false,\n error: null,\n formName: userTraits?.name || '',\n formEmail: userTraits?.email || '',\n formEmailError: null,\n userTraits,\n unreadCount: 0,\n showTicketList: props.showTicketList || false,\n isCurrentTicketResolved: false,\n isIdentityMode,\n restoreEmail: userTraits?.email || '',\n restoreEmailError: null,\n restoreRequestLoading: false,\n restoreRequestSuccess: false,\n }\n }\n\n /**\n * Check if we need to show the identification form\n */\n private _needsIdentification(\n config: ConversationsRemoteConfig,\n traits: UserProvidedTraits | null,\n isUserIdentified?: boolean,\n isIdentityMode?: boolean\n ): boolean {\n // Server-verified identity mode -- identity is already established\n if (isIdentityMode) {\n return false\n }\n\n // If user is already identified via PostHog, no form needed\n // They've called posthog.identify() so we have their identity\n if (isUserIdentified) {\n return false\n }\n\n // If requireEmail is not set, no identification needed\n if (!config.requireEmail) {\n return false\n }\n\n // If we already have an email, no form needed\n if (traits?.email) {\n return false\n }\n\n return true\n }\n\n componentDidMount() {\n // Add greeting message if no messages exist and we're in message view\n if (this.state.view === 'messages' && this.state.messages.length === 0 && this.props.config.greetingText) {\n this._addGreetingMessage()\n }\n }\n\n componentDidUpdate(_prevProps: WidgetProps, prevState: WidgetState) {\n // Scroll to bottom when messages change\n if (this.state.messages.length !== prevState.messages.length) {\n this._scrollToBottom()\n }\n\n // Notify parent of state changes\n if (this.state.state !== prevState.state && this.props.onStateChange) {\n this.props.onStateChange(this.state.state)\n }\n\n // Focus input and scroll to bottom when opening\n if (this.state.state === 'open' && prevState.state !== 'open') {\n this._focusInput()\n this._scrollToBottom()\n }\n }\n\n private _addGreetingMessage() {\n const greetingMessage: Message = {\n id: 'greeting',\n content: this.props.config.greetingText || 'Hi! How can we help?',\n author_type: 'AI',\n author_name: 'Support',\n created_at: new Date().toISOString(),\n is_private: false,\n }\n this.setState({ messages: [greetingMessage] })\n }\n\n private _scrollToBottom() {\n if (this._messagesEndRef) {\n this._messagesEndRef.scrollIntoView({ behavior: 'smooth' })\n }\n }\n\n private _focusInput() {\n if (this._inputRef) {\n this._inputRef.focus()\n }\n }\n\n private _handleToggleOpen = () => {\n this.setState((prevState) => ({\n state: prevState.state === 'open' ? 'closed' : 'open',\n }))\n }\n\n private _handleClose = () => {\n this.setState({ state: 'closed' })\n }\n\n private _handleSelectTicket = (ticketId: string) => {\n if (this.props.onSelectTicket) {\n this.props.onSelectTicket(ticketId)\n }\n }\n\n private _handleNewConversation = () => {\n if (this.props.onNewConversation) {\n this.props.onNewConversation()\n }\n }\n\n private _handleBackToTickets = () => {\n if (this.props.onBackToTickets) {\n this.props.onBackToTickets()\n }\n }\n\n private _handleOpenRestoreRequest = () => {\n this.setState((prevState) => ({\n view: 'restore_request',\n restoreEmail: prevState.restoreEmail || prevState.userTraits?.email || '',\n restoreEmailError: null,\n restoreRequestSuccess: false,\n }))\n if (this.props.onViewChange) {\n this.props.onViewChange('restore_request')\n }\n }\n\n private _handleCloseRestoreRequest = () => {\n const returnView = this.state.showTicketList ? 'tickets' : 'messages'\n this.setState({ view: returnView, restoreEmailError: null, restoreRequestSuccess: false })\n if (this.props.onViewChange) {\n this.props.onViewChange(returnView)\n }\n }\n\n private _handleInputChange = (e: Event) => {\n const target = e.target as HTMLTextAreaElement\n this.setState({ inputValue: target.value })\n }\n\n private _handleKeyPress = (e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n this._handleSendMessage()\n }\n }\n\n // Identification form handlers\n private _handleFormNameChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n this.setState({ formName: target.value })\n }\n\n private _handleFormEmailChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n this.setState({ formEmail: target.value, formEmailError: null })\n }\n\n private _handleRestoreEmailChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n this.setState({\n restoreEmail: target.value,\n restoreEmailError: null,\n restoreRequestSuccess: false,\n })\n }\n\n private _validateEmail(email: string): boolean {\n // Basic email validation\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n return emailRegex.test(email)\n }\n\n private _handleFormSubmit = (e: Event) => {\n e.preventDefault()\n\n const { formEmail, formName } = this.state\n const { config, onIdentify } = this.props\n\n // Validate email if required\n if (config.requireEmail && !formEmail.trim()) {\n this.setState({ formEmailError: 'Email is required' })\n return\n }\n\n if (formEmail.trim() && !this._validateEmail(formEmail.trim())) {\n this.setState({ formEmailError: 'Please enter a valid email address' })\n return\n }\n\n // Create traits object\n const traits: UserProvidedTraits = {}\n if (formName.trim()) {\n traits.name = formName.trim()\n }\n if (formEmail.trim()) {\n traits.email = formEmail.trim()\n }\n\n // Navigate to appropriate view after identification\n const nextView = this.state.showTicketList ? 'tickets' : 'messages'\n\n // Update state and notify parent\n this.setState({\n userTraits: traits,\n view: nextView,\n })\n\n if (onIdentify) {\n onIdentify(traits)\n }\n\n if (this.props.onViewChange) {\n this.props.onViewChange(nextView)\n }\n }\n\n private _handleRestoreRequestSubmit = async (e: Event) => {\n e.preventDefault()\n\n if (!this.props.onRequestRestoreLink) {\n return\n }\n\n const email = this.state.restoreEmail.trim()\n if (!email) {\n this.setState({ restoreEmailError: 'Email is required' })\n return\n }\n\n if (!this._validateEmail(email)) {\n this.setState({ restoreEmailError: 'Please enter a valid email address' })\n return\n }\n\n this.setState({\n restoreRequestLoading: true,\n restoreEmailError: null,\n })\n\n try {\n await this.props.onRequestRestoreLink(email)\n this.setState({\n restoreRequestLoading: false,\n restoreRequestSuccess: true,\n })\n } catch (error) {\n logger.error('Failed to request restore link', error)\n this.setState({\n restoreRequestLoading: false,\n restoreEmailError: error instanceof Error ? error.message : 'Failed to request restore link',\n })\n }\n }\n\n private _handleSendMessage = async () => {\n const { inputValue } = this.state\n const trimmedMessage = inputValue.trim()\n\n if (!trimmedMessage) {\n return\n }\n\n // Add user message to UI immediately\n const userMessage: Message = {\n id: `temp-${Date.now()}`,\n content: trimmedMessage,\n author_type: 'customer',\n author_name: 'You',\n created_at: new Date().toISOString(),\n is_private: false,\n }\n\n this.setState({\n messages: [...this.state.messages, userMessage],\n inputValue: '',\n isLoading: true,\n error: null,\n })\n\n try {\n await this.props.onSendMessage(trimmedMessage)\n // Success - message will be updated via addMessage()\n this.setState({ isLoading: false })\n } catch (error) {\n logger.error('Failed to send message', error)\n this.setState((prevState) => ({\n isLoading: false,\n error: error instanceof Error ? error.message : 'Failed to send message',\n messages: prevState.messages.filter((m) => m.id !== userMessage.id),\n }))\n }\n }\n\n /**\n * Public method to add messages from outside\n */\n addMessages(messages: Message[]) {\n this.setState((prevState) => {\n // Filter out duplicates\n const existingIds = new Set(prevState.messages.map((m) => m.id))\n const newMessages = messages.filter((m) => !existingIds.has(m.id))\n\n if (newMessages.length > 0) {\n return {\n messages: [...prevState.messages, ...newMessages],\n }\n }\n return null\n })\n }\n\n /**\n * Public method to show the widget\n */\n show() {\n this.setState({ state: 'open' })\n }\n\n /**\n * Public method to hide the widget\n */\n hide() {\n this.setState({ state: 'closed' })\n }\n\n /**\n * Get user traits (either provided via form or from props)\n */\n getUserTraits(): UserProvidedTraits | null {\n return this.state.userTraits\n }\n\n /**\n * Called when user identifies via posthog.identify()\n * Navigates away from identification form since we now know who they are\n */\n setUserIdentified(): void {\n if (this.state.view === 'identification') {\n const nextView = this.state.showTicketList ? 'tickets' : 'messages'\n this.setState({ view: nextView })\n if (this.props.onViewChange) {\n this.props.onViewChange(nextView)\n }\n }\n }\n\n /**\n * Set the unread message count (called by manager)\n */\n setUnreadCount(count: number): void {\n this.setState({ unreadCount: count })\n }\n\n /**\n * Update the tickets list (called by manager during polling)\n */\n updateTickets(tickets: Ticket[], showTicketList: boolean): void {\n this.setState({\n tickets,\n ticketsLoading: false,\n showTicketList,\n })\n }\n\n /**\n * Set whether the current ticket (if any) is in the resolved state.\n * Called by the manager whenever the current ticket or tickets list changes.\n */\n setCurrentTicketResolved(resolved: boolean): void {\n this.setState({ isCurrentTicketResolved: resolved })\n }\n\n /**\n * Set the current view (tickets list or messages)\n */\n setView(view: WidgetView): void {\n this.setState({ view })\n if (this.props.onViewChange) {\n this.props.onViewChange(view)\n }\n }\n\n /**\n * Get the current view\n */\n getView(): WidgetView {\n return this.state.view\n }\n\n /**\n * Set tickets loading state\n */\n setTicketsLoading(loading: boolean): void {\n this.setState({ ticketsLoading: loading })\n }\n\n /**\n * Update identity mode state (called by manager on setIdentity/clearIdentity)\n */\n setIdentityMode(isIdentityMode: boolean): void {\n let nextView: WidgetView | undefined\n this.setState(\n (prevState) => {\n const update: Partial<WidgetState> = { isIdentityMode }\n const viewNeedsReset =\n prevState.view === 'identification' ||\n prevState.view === 'restore_request' ||\n prevState.view === 'messages'\n if (viewNeedsReset) {\n nextView = prevState.showTicketList ? 'tickets' : 'messages'\n update.view = nextView\n }\n return update as WidgetState\n },\n () => {\n if (nextView && this.props.onViewChange) {\n this.props.onViewChange(nextView)\n }\n }\n )\n }\n\n /**\n * Clear messages (used when switching tickets or starting new conversation)\n * @param addGreeting - If true, adds the greeting message after clearing\n */\n clearMessages(addGreeting: boolean = false): void {\n this.setState({ messages: [] }, () => {\n if (addGreeting && this.props.config.greetingText) {\n this._addGreetingMessage()\n }\n })\n }\n\n private _renderIdentificationForm(styles: ReturnType<typeof getStyles>) {\n return (\n <IdentificationFormView\n config={this.props.config}\n styles={styles}\n formName={this.state.formName}\n formEmail={this.state.formEmail}\n formEmailError={this.state.formEmailError}\n onNameChange={this._handleFormNameChange}\n onEmailChange={this._handleFormEmailChange}\n onSubmit={this._handleFormSubmit}\n />\n )\n }\n\n private _renderBackButton(styles: ReturnType<typeof getStyles>) {\n const onClick =\n this.state.view === 'restore_request' ? this._handleCloseRestoreRequest : this._handleBackToTickets\n return (\n <button style={styles.backButton} onClick={onClick} aria-label=\"Back to conversations\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polyline points=\"15 18 9 12 15 6\" />\n </svg>\n </button>\n )\n }\n\n private _renderTicketList(styles: ReturnType<typeof getStyles>) {\n const { tickets, ticketsLoading } = this.state\n\n return (\n <TicketListView\n tickets={tickets}\n isLoading={ticketsLoading}\n styles={styles}\n onSelectTicket={this._handleSelectTicket}\n onNewConversation={this._handleNewConversation}\n onOpenRestoreRequest={this._handleOpenRestoreRequest}\n />\n )\n }\n\n private _renderMessages(styles: ReturnType<typeof getStyles>, primaryColor: string, placeholderText: string) {\n return (\n <MessagesView\n styles={styles}\n primaryColor={primaryColor}\n placeholderText={placeholderText}\n messages={this.state.messages}\n inputValue={this.state.inputValue}\n isLoading={this.state.isLoading}\n error={this.state.error}\n isResolved={this.state.isCurrentTicketResolved}\n onInputChange={this._handleInputChange}\n onKeyDown={this._handleKeyPress}\n onSendMessage={this._handleSendMessage}\n onStartNewConversation={this._handleNewConversation}\n messagesEndRef={(el) => {\n this._messagesEndRef = el\n }}\n inputRef={(el) => {\n this._inputRef = el\n }}\n />\n )\n }\n\n private _renderRestoreRequestView(styles: ReturnType<typeof getStyles>) {\n return (\n <RestoreRequestView\n styles={styles}\n restoreEmail={this.state.restoreEmail}\n restoreEmailError={this.state.restoreEmailError}\n restoreRequestLoading={this.state.restoreRequestLoading}\n restoreRequestSuccess={this.state.restoreRequestSuccess}\n onEmailChange={this._handleRestoreEmailChange}\n onSubmit={this._handleRestoreRequestSubmit}\n />\n )\n }\n\n /**\n * Get the title for the current view\n */\n private _getTitle(view: WidgetView): string {\n switch (view) {\n case 'tickets':\n return 'Conversations'\n case 'restore_request':\n return 'Restore conversations'\n case 'identification':\n return 'Support Chat'\n case 'messages':\n return 'Support Chat'\n }\n }\n\n /**\n * Render the content for the current view\n */\n private _renderViewContent(\n styles: ReturnType<typeof getStyles>,\n primaryColor: string,\n placeholderText: string\n ): h.JSX.Element {\n switch (this.state.view) {\n case 'identification':\n return this._renderIdentificationForm(styles)\n case 'restore_request':\n return this._renderRestoreRequestView(styles)\n case 'tickets':\n return this._renderTicketList(styles)\n case 'messages':\n return this._renderMessages(styles, primaryColor, placeholderText)\n }\n }\n\n render() {\n const { config } = this.props\n const { state, view } = this.state\n const primaryColor = config.color || '#5375ff'\n const widgetPosition = config.widgetPosition || 'bottom_right'\n const placeholderText = config.placeholderText || 'Type your message...'\n const styles = getStyles(primaryColor, widgetPosition)\n\n // Button only (closed state)\n if (state === 'closed') {\n return (\n <OpenChatButton\n primaryColor={primaryColor}\n position={widgetPosition}\n handleToggleOpen={this._handleToggleOpen}\n unreadCount={this.state.unreadCount}\n />\n )\n }\n\n // Open state\n const windowStyle = {\n ...styles.window,\n ...styles.windowOpen,\n }\n\n // Show back button in message view when the ticket list is available, or in restore request view\n const showBackButton = (view === 'messages' && this.state.showTicketList) || view === 'restore_request'\n\n // Show recover footer only in tickets and messages views, and not in identity mode\n const showRecoverFooter = !this.state.isIdentityMode && (view === 'tickets' || view === 'messages')\n\n return (\n <div style={styles.widget}>\n <div style={windowStyle}>\n <div style={styles.header}>\n <div style={showBackButton ? styles.headerWithBack : styles.headerTitle}>\n {showBackButton && this._renderBackButton(styles)}\n <span style={styles.headerTitle}>{this._getTitle(view)}</span>\n </div>\n <div style={styles.headerActions}>\n <CloseChatButton primaryColor={primaryColor} handleClose={this._handleClose} />\n </div>\n </div>\n\n {this._renderViewContent(styles, primaryColor, placeholderText)}\n\n {showRecoverFooter && (\n <div style={styles.recoverFooter}>\n Don't see your previous tickets?{' '}\n <button\n type=\"button\"\n style={styles.recoverFooterLink}\n onClick={this._handleOpenRestoreRequest}\n >\n Recover them here\n </button>\n </div>\n )}\n </div>\n </div>\n )\n }\n}\n","import { each } from './'\n\nimport { isArray, isFile, isUndefined } from '@posthog/core'\nimport { logger } from './logger'\nimport { document } from './globals'\n\nconst localDomains = ['localhost', '127.0.0.1']\n\n/**\n * IE11 doesn't support `new URL`\n * so we can create an anchor element and use that to parse the URL\n * there's a lot of overlap between HTMLHyperlinkElementUtils and URL\n * meaning useful properties like `pathname` are available on both\n */\nexport const convertToURL = (url: string): HTMLAnchorElement | null => {\n const location = document?.createElement('a')\n if (isUndefined(location)) {\n return null\n }\n\n location.href = url\n return location\n}\n\nexport const formDataToQuery = function (formdata: Record<string, any> | FormData, arg_separator = '&'): string {\n let use_val: string\n let use_key: string\n const tph_arr: string[] = []\n\n each(formdata, function (val: File | string | undefined, key: string | undefined) {\n // the key might be literally the string undefined for e.g. if {undefined: 'something'}\n if (isUndefined(val) || isUndefined(key) || key === 'undefined') {\n return\n }\n\n use_val = encodeURIComponent(isFile(val) ? val.name : val.toString())\n use_key = encodeURIComponent(key)\n tph_arr[tph_arr.length] = use_key + '=' + use_val\n })\n\n return tph_arr.join(arg_separator)\n}\n\nexport const getQueryParam = function (url: string, param: string): string {\n const withoutHash: string = url.split('#')[0] || ''\n\n // Split only on the first ? to sort problem out for those with multiple ?s\n // and then remove them\n const queryParams: string = withoutHash.split(/\\?(.*)/)[1] || ''\n const cleanedQueryParams = queryParams.replace(/^\\?+/g, '')\n\n const queryParts = cleanedQueryParams.split('&')\n let keyValuePair\n\n for (let i = 0; i < queryParts.length; i++) {\n const parts = queryParts[i].split('=')\n if (parts[0] === param) {\n keyValuePair = parts\n break\n }\n }\n\n if (!isArray(keyValuePair) || keyValuePair.length < 2) {\n return ''\n } else {\n let result = keyValuePair[1]\n try {\n result = decodeURIComponent(result)\n } catch {\n logger.error('Skipping decoding for malformed query param: ' + result)\n }\n return result.replace(/\\+/g, ' ')\n }\n}\n\n// replace any query params in the url with the provided mask value. Tries to keep the URL as instant as possible,\n// including preserving malformed text in most cases\nexport const maskQueryParams = function <T extends string | undefined>(\n url: T,\n maskedParams: string[] | undefined,\n mask: string\n): T extends string ? string : undefined {\n if (!url || !maskedParams || !maskedParams.length) {\n return url as any\n }\n\n const splitHash = url.split('#')\n const withoutHash: string = splitHash[0] || ''\n const hash = splitHash[1]\n\n const splitQuery: string[] = withoutHash.split('?')\n const queryString: string = splitQuery[1]\n const urlWithoutQueryAndHash: string = splitQuery[0]\n const queryParts = (queryString || '').split('&')\n\n // use an array of strings rather than an object to preserve ordering and duplicates\n const paramStrings: string[] = []\n\n for (let i = 0; i < queryParts.length; i++) {\n const keyValuePair = queryParts[i].split('=')\n if (!isArray(keyValuePair)) {\n continue\n } else if (maskedParams.includes(keyValuePair[0])) {\n paramStrings.push(keyValuePair[0] + '=' + mask)\n } else {\n paramStrings.push(queryParts[i])\n }\n }\n\n let result = urlWithoutQueryAndHash\n if (queryString != null) {\n result += '?' + paramStrings.join('&')\n }\n if (hash != null) {\n result += '#' + hash\n }\n\n return result as any\n}\n\nexport const _getHashParam = function (hash: string, param: string): string | null {\n const matches = hash.match(new RegExp(param + '=([^&]*)'))\n return matches ? matches[1] : null\n}\n\nexport const isLocalhost = (): boolean => {\n return localDomains.includes(location.hostname)\n}\n","import { PostHogConfig, Properties } from '../types'\nimport { logger } from './logger'\nimport { isFormData, isNullish, isNumber, isString, hasOwnProperty, isArray } from '@posthog/core'\n\nexport function find<T>(value: T[], predicate: (value: T) => boolean): T | undefined {\n for (let i = 0; i < value.length; i++) {\n if (predicate(value[i])) {\n return value[i]\n }\n }\n return undefined\n}\n\nexport function eachArray<E = any>(obj: E[] | null | undefined, iterator: (value: E, key: number) => void): void {\n if (isArray(obj)) {\n obj.forEach(iterator)\n }\n}\n\nexport function each(obj: any, iterator: (value: any, key: any) => void): void {\n if (isNullish(obj)) {\n return\n }\n if (isArray(obj)) {\n obj.forEach(iterator)\n return\n }\n if (isFormData(obj)) {\n obj.forEach((val: any, key: any) => iterator(val, key))\n return\n }\n for (const key in obj) {\n if (hasOwnProperty.call(obj, key)) {\n iterator(obj[key], key)\n }\n }\n}\n\nexport const extend = function (obj: Record<string, any>, ...args: Record<string, any>[]): Record<string, any> {\n for (const source of args) {\n for (const prop in source) {\n if (source[prop] !== void 0) {\n obj[prop] = source[prop]\n }\n }\n }\n return obj\n}\n\n/**\n * Object.entries() polyfill\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries\n */\nexport function entries<T = any>(obj: Record<string, T>): [string, T][] {\n const ownProps = Object.keys(obj)\n let i = ownProps.length\n const resArray = new Array(i) // preallocate the Array\n\n while (i--) {\n resArray[i] = [ownProps[i], obj[ownProps[i]]]\n }\n return resArray\n}\n\nexport const trySafe = function <T>(fn: () => T): T | undefined {\n try {\n return fn()\n } catch {\n return undefined\n }\n}\n\nexport const safewrap = function <F extends (...args: any[]) => any = (...args: any[]) => any>(f: F): F {\n return function (...args) {\n try {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return f.apply(this, args)\n } catch (e) {\n logger.critical(\n 'Implementation error. Please turn on debug mode and open a ticket on https://app.posthog.com/home#panel=support%3Asupport%3A.'\n )\n logger.critical(e)\n }\n } as F\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const safewrapClass = function (klass: Function, functions: string[]): void {\n for (let i = 0; i < functions.length; i++) {\n klass.prototype[functions[i]] = safewrap(klass.prototype[functions[i]])\n }\n}\n\nexport const stripEmptyProperties = function (p: Properties): Properties {\n const ret: Properties = {}\n each(p, function (v, k) {\n if ((isString(v) && v.length > 0) || isNumber(v)) {\n ret[k] = v\n }\n })\n return ret\n}\n\n/**\n * Deep copies an object.\n * It handles cycles by replacing all references to them with `undefined`\n * Also supports customizing native values\n *\n * @param value\n * @param customizer\n * @returns {{}|undefined|*}\n */\nfunction deepCircularCopy<T extends Record<string, any> = Record<string, any>>(\n value: T,\n customizer?: <K extends keyof T = keyof T>(value: T[K], key?: K) => T[K]\n): T | undefined {\n const COPY_IN_PROGRESS_SET = new Set()\n\n function internalDeepCircularCopy(value: T, key?: string): T | undefined {\n if (value !== Object(value)) return customizer ? customizer(value as any, key) : value // primitive value\n\n if (COPY_IN_PROGRESS_SET.has(value)) return undefined\n COPY_IN_PROGRESS_SET.add(value)\n let result: T\n\n if (isArray(value)) {\n result = [] as any as T\n eachArray(value, (it) => {\n result.push(internalDeepCircularCopy(it))\n })\n } else {\n result = {} as T\n each(value, (val, key) => {\n if (!COPY_IN_PROGRESS_SET.has(val)) {\n ;(result as any)[key] = internalDeepCircularCopy(val, key)\n }\n })\n }\n return result\n }\n return internalDeepCircularCopy(value)\n}\n\nexport function _copyAndTruncateStrings<T extends Record<string, any> = Record<string, any>>(\n object: T,\n maxStringLength: number\n): T {\n return deepCircularCopy(object, (value: any) => {\n if (isString(value)) {\n return (value as string).slice(0, maxStringLength)\n }\n return value\n }) as T\n}\n\n// NOTE: Update PostHogConfig docs if you change this list\n// We will not try to catch all bullets here, but we should make an effort to catch the most common ones\n// You should be highly against adding more to this list, because ultimately customers can configure\n// their `cross_subdomain_cookie` setting to anything they want.\nconst EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE = ['herokuapp.com', 'vercel.app', 'netlify.app']\nexport function isCrossDomainCookie(documentLocation: Location | undefined) {\n const hostname = documentLocation?.hostname\n\n if (!isString(hostname)) {\n return false\n }\n // split and slice isn't a great way to match arbitrary domains,\n // but it's good enough for ensuring we only match herokuapp.com when it is the TLD\n // for the hostname\n const lastTwoParts = hostname.split('.').slice(-2).join('.')\n\n for (const excluded of EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE) {\n if (lastTwoParts === excluded) {\n return false\n }\n }\n\n return true\n}\n\n// Use this instead of element.addEventListener to avoid eslint errors\n// this properly implements the default options for passive event listeners\nexport function addEventListener(\n element: Window | Document | Element | undefined,\n event: string,\n callback: EventListener,\n options?: AddEventListenerOptions\n): void {\n const { capture = false, passive = true } = options ?? {}\n\n // This is the only place where we are allowed to call this function\n // because the whole idea is that we should be calling this instead of the built-in one\n // eslint-disable-next-line posthog-js/no-add-event-listener\n element?.addEventListener(event, callback, { capture, passive })\n}\n\n/**\n * Helper to migrate deprecated config fields to new field names with appropriate warnings\n * @param config - The config object to check\n * @param newField - The new field name to use\n * @param oldField - The deprecated field name to check for\n * @param defaultValue - The default value if neither field is set\n * @param loggerInstance - Optional logger instance for deprecation warnings\n * @returns The value to use (new field takes precedence over old field)\n */\nexport function migrateConfigField<T>(\n config: Record<string, any>,\n newField: string,\n oldField: string,\n defaultValue: T,\n loggerInstance?: { warn: (message: string) => void }\n): T {\n const hasNewField = newField in config && !isNullish(config[newField])\n const hasOldField = oldField in config && !isNullish(config[oldField])\n\n if (hasNewField) {\n return config[newField]\n }\n\n if (hasOldField) {\n if (loggerInstance) {\n loggerInstance.warn(\n `Config field '${oldField}' is deprecated. Please use '${newField}' instead. ` +\n `The old field will be removed in a future major version.`\n )\n }\n return config[oldField]\n }\n\n return defaultValue\n}\n\nconst TOOLBAR_INTERNAL_INSTANCE_NAME = 'ph_toolbar_internal'\n\nexport function isToolbarInstance(config: Pick<PostHogConfig, 'name'>): boolean {\n return config.name === TOOLBAR_INTERNAL_INSTANCE_NAME\n}\n","import { createLogger } from '../../../utils/logger'\nimport { window } from '../../../utils/globals'\n\nconst logger = createLogger('[ConversationsManager]')\n\nexport const RESTORE_QUERY_PARAM = 'ph_conv_restore'\n\n/**\n * Extract hostname from a domain string (handles URLs and plain hostnames)\n */\nfunction extractHostname(domain: string): string | null {\n let hostname = domain.replace(/^https?:\\/\\//, '')\n hostname = hostname.split('/')[0].split('?')[0].split(':')[0]\n return hostname || null\n}\n\n/**\n * Check if the current domain matches the allowed domains list.\n * Returns true if:\n * - domains is empty or not present (no restriction)\n * - current hostname matches any allowed domain\n */\nexport function isCurrentDomainAllowed(domains: string[] | undefined): boolean {\n if (!domains || domains.length === 0) {\n return true\n }\n\n const currentHostname = window?.location?.hostname\n if (!currentHostname) {\n return true\n }\n\n return domains.some((domain) => {\n const allowedHostname = extractHostname(domain)\n if (!allowedHostname) {\n return false\n }\n\n if (allowedHostname.startsWith('*.')) {\n const pattern = allowedHostname.slice(2)\n return currentHostname.endsWith(`.${pattern}`) || currentHostname === pattern\n }\n\n return currentHostname === allowedHostname\n })\n}\n\nexport function getRestoreTokenFromUrl(): string | null {\n if (!window?.location?.search) {\n return null\n }\n\n try {\n // eslint-disable-next-line compat/compat\n const params = new URLSearchParams(window.location.search)\n const token = params.get(RESTORE_QUERY_PARAM)\n return token?.trim() || null\n } catch (error) {\n logger.warn('Failed to parse restore token from URL', error)\n return null\n }\n}\n\nexport function clearRestoreTokenFromUrl(): void {\n if (!window?.location || !window?.history?.replaceState) {\n return\n }\n\n try {\n // eslint-disable-next-line compat/compat\n const url = new URL(window.location.href)\n url.searchParams.delete(RESTORE_QUERY_PARAM)\n const newUrl = `${url.pathname}${url.search}${url.hash}`\n window.history.replaceState(window.history.state, '', newUrl)\n } catch (error) {\n logger.warn('Failed to clear restore token from URL', error)\n }\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { render, h } from 'preact'\nimport { isNumber, isNull } from '@posthog/core'\nimport {\n ConversationsRemoteConfig,\n ConversationsWidgetState,\n UserProvidedTraits,\n SendMessageResponse,\n SendMessagePayload,\n GetMessagesResponse,\n MarkAsReadResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n Ticket,\n RestoreFromTokenPayload,\n RestoreFromTokenResponse,\n RequestRestoreLinkPayload,\n RequestRestoreLinkResponse,\n TicketStatus,\n} from '../../../posthog-conversations-types'\nimport { PostHog } from '../../../posthog-core'\nimport { STORED_PERSON_PROPERTIES_KEY } from '../../../constants'\nimport { ConversationsManager as ConversationsManagerInterface } from '../posthog-conversations'\nimport { ConversationsPersistence } from './persistence'\nimport { ConversationsWidget, WidgetView } from './components/ConversationsWidget'\nimport { createLogger } from '../../../utils/logger'\nimport { document, window } from '../../../utils/globals'\nimport { formDataToQuery } from '../../../utils/request-utils'\nimport { isCurrentDomainAllowed, getRestoreTokenFromUrl, clearRestoreTokenFromUrl } from './url-utils'\n\nconst logger = createLogger('[ConversationsManager]')\n\nconst WIDGET_CONTAINER_ID = 'ph-conversations-widget-container'\nconst POLL_INTERVAL_MS = 5000 // 5 seconds\nconst RESTORE_EXCHANGE_ENDPOINT = '/api/conversations/v1/widget/restore'\nconst RESTORE_REQUEST_ENDPOINT = '/api/conversations/v1/widget/restore/request'\n\n// Singleton guard: only one ConversationsManager per page.\n// The toolbar's internal PostHog instance is excluded from creating a manager\n// (see PostHogConversations.loadIfEnabled), so this always belongs to the main instance.\nlet _activeManager: ConversationsManager | null = null\n\nexport class ConversationsManager implements ConversationsManagerInterface {\n private _config: ConversationsRemoteConfig\n private _persistence: ConversationsPersistence\n private _widgetRef: ConversationsWidget | null = null\n private _containerElement: HTMLDivElement | null = null\n private _currentTicketId: string | null = null\n private _pollIntervalId: number | null = null\n private _lastMessageTimestamp: string | null = null\n private _isPollingMessages: boolean = false\n private _isPollingTickets: boolean = false\n private _unsubscribeIdentifyListener: (() => void) | null = null\n private _unreadCount: number = 0\n // SECURITY: widget_session_id is the key for access control\n // This is a random UUID that only this browser knows\n private _widgetSessionId: string\n private _isWidgetEnabled: boolean\n private _isDomainAllowed: boolean\n private _widgetState: ConversationsWidgetState = 'closed'\n private _isWidgetRendered: boolean = false\n private _hasProcessedRestoreToken: boolean = false\n private _initializeWidgetPromise: Promise<void> | null = null\n // View state management for ticket list vs message view\n private _currentView: WidgetView = 'messages'\n private _tickets: Ticket[] = []\n private _showTicketList: boolean = false\n\n constructor(\n config: ConversationsRemoteConfig,\n private readonly _posthog: PostHog\n ) {\n this._config = config\n this._persistence = new ConversationsPersistence(_posthog)\n\n this._widgetSessionId = this._persistence.getOrCreateWidgetSessionId()\n\n // Determine if widget should be shown based on config and domain\n this._isWidgetEnabled = config.widgetEnabled === true\n this._isDomainAllowed = isCurrentDomainAllowed(config.domains)\n\n this._initialize()\n }\n\n /**\n * Send a message programmatically via the API\n * Creates a new ticket if none exists or if newTicket is true\n *\n * @param message - The message text to send\n * @param userTraits - Optional user identification data (name, email)\n * @param newTicket - If true, forces creation of a new ticket (ignores current ticket)\n * @returns Promise with the response including ticket_id and message_id\n */\n async sendMessage(\n message: string,\n userTraits?: UserProvidedTraits,\n newTicket?: boolean\n ): Promise<SendMessageResponse> {\n // Determine which ticket to use\n // If newTicket is true, force creation of new ticket by sending null\n // Otherwise use current ticket ID (which may be null if no ticket exists yet)\n const ticketId = newTicket ? null : this._currentTicketId\n\n // Track if this is creating a new ticket\n const isNewTicket = !ticketId\n\n const token = this._config.token\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n const personTraits = this._getPersonTraits()\n\n const name = userTraits?.name || personTraits.name || null\n const email = userTraits?.email || personTraits.email || null\n\n const identity = this._identityFields()\n const payload: Partial<SendMessagePayload> = {\n message: message.trim(),\n traits: {\n name,\n email,\n },\n ticket_id: ticketId,\n }\n\n if (identity) {\n payload.identity_distinct_id = identity.identity_distinct_id\n payload.identity_hash = identity.identity_hash\n payload.distinct_id = identity.identity_distinct_id\n } else {\n payload.widget_session_id = this._widgetSessionId\n payload.distinct_id = this._posthog.get_distinct_id()\n }\n\n try {\n // Capture session ID - sent with every message\n const capturedSessionId = this._posthog.get_session_id()\n if (capturedSessionId) {\n payload.session_id = capturedSessionId\n }\n\n // Capture session replay URL with timestamp - sent with every message\n const replayUrl = this._posthog.get_session_replay_url({\n withTimestamp: true,\n timestampLookBack: 30,\n })\n\n // Capture current URL - only for new tickets to record where user started\n const currentUrl = isNewTicket ? window?.location?.href : undefined\n\n if (replayUrl || currentUrl) {\n payload.session_context = {\n session_replay_url: replayUrl || undefined,\n current_url: currentUrl || undefined,\n }\n }\n } catch (error) {\n // Log error but don't fail message sending\n logger.warn('Failed to capture session context', error)\n }\n\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor('api', '/api/conversations/v1/widget/message'),\n method: 'POST',\n data: payload,\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200 && response.statusCode !== 201) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to send message'\n logger.error('Failed to send message', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as SendMessageResponse\n\n // Update current ticket ID if this was a new ticket\n // This happens when: 1) No ticket existed, or 2) User forced new ticket creation\n if (isNewTicket && data.ticket_id) {\n this._currentTicketId = data.ticket_id\n this._persistence.saveTicketId(data.ticket_id)\n logger.info('New ticket created', {\n ticketId: data.ticket_id,\n forced: newTicket === true,\n })\n }\n\n // Track message sent\n this._posthog.capture('$conversations_message_sent', {\n ticketId: data.ticket_id,\n isNewTicket: isNewTicket,\n messageLength: message.length,\n })\n\n // Update last message timestamp\n this._lastMessageTimestamp = data.created_at\n\n resolve(data)\n },\n })\n })\n }\n\n /**\n * Switch to a different ticket if an explicit ticketId is provided\n * This ensures subsequent operations (sendMessage, etc.) use the correct ticket\n */\n private _switchToTicketIfNeeded(ticketId: string | undefined): void {\n if (ticketId && ticketId !== this._currentTicketId) {\n this._currentTicketId = ticketId\n this._persistence.saveTicketId(ticketId)\n // Reset last message timestamp when switching tickets\n this._lastMessageTimestamp = null\n }\n }\n\n /** Fetch messages via the API */\n async getMessages(ticketId?: string, after?: string): Promise<GetMessagesResponse> {\n // Use provided ticketId or fall back to current ticket\n const targetTicketId = ticketId || this._currentTicketId\n\n if (!targetTicketId) {\n throw new Error('No ticket ID provided and no active conversation')\n }\n\n // Switch to this ticket if explicitly provided\n this._switchToTicketIfNeeded(ticketId)\n\n const token = this._config.token\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n const identity = this._identityFields()\n const queryParams: Record<string, string> = {\n limit: '50',\n }\n\n if (identity) {\n queryParams.identity_distinct_id = identity.identity_distinct_id\n queryParams.identity_hash = identity.identity_hash\n } else {\n queryParams.widget_session_id = this._widgetSessionId\n }\n\n if (after) {\n queryParams.after = after\n }\n\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/messages/${targetTicketId}?${formDataToQuery(queryParams)}`\n ),\n method: 'GET',\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to fetch messages'\n logger.error('Failed to fetch messages', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as GetMessagesResponse\n resolve(data)\n },\n })\n })\n }\n\n /** Mark messages as read via the API */\n async markAsRead(ticketId?: string): Promise<MarkAsReadResponse> {\n // Use provided ticketId or fall back to current ticket\n const targetTicketId = ticketId || this._currentTicketId\n\n if (!targetTicketId) {\n throw new Error('No ticket ID provided and no active conversation')\n }\n\n // Switch to this ticket if explicitly provided\n this._switchToTicketIfNeeded(ticketId)\n\n const token = this._config.token\n\n logger.info('Marking messages as read', { ticketId: targetTicketId })\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n const identity = this._identityFields()\n const data = identity\n ? { identity_distinct_id: identity.identity_distinct_id, identity_hash: identity.identity_hash }\n : { widget_session_id: this._widgetSessionId }\n\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/messages/${targetTicketId}/read`\n ),\n method: 'POST',\n data,\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg =\n response.json?.detail || response.json?.message || 'Failed to mark messages as read'\n logger.error('Failed to mark messages as read', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const responseData = response.json as MarkAsReadResponse\n resolve(responseData)\n },\n })\n })\n }\n\n /**\n * Initialize the conversations manager.\n * Always initializes persistence and event listeners for API usage.\n * Only renders the widget if widgetEnabled is true AND domain is allowed.\n */\n private _initialize(): void {\n if (!document || !window) {\n logger.info('Conversations not available: Document or window not available')\n return\n }\n\n // In identity mode, restore is unnecessary and the persisted anonymous\n // ticket belongs to a different principal -- clear it before completing.\n if (this._identityFields()) {\n this._persistence.clearTicketId()\n this._completeInitialization()\n return\n }\n\n const restoreToken = getRestoreTokenFromUrl()\n if (restoreToken && !this._hasProcessedRestoreToken) {\n this._hasProcessedRestoreToken = true\n\n // Clear the token from the URL immediately, then again after a tick and\n // after the restore completes. SPA routers (Next.js, React Router, etc.)\n // maintain their own URL state and can overwrite a single replaceState call.\n clearRestoreTokenFromUrl()\n setTimeout(clearRestoreTokenFromUrl, 0)\n\n this._restoreFromTokenWithRetry(restoreToken)\n .catch((error) => {\n logger.warn('Failed to restore conversations from URL token', error)\n })\n .finally(() => {\n clearRestoreTokenFromUrl()\n this._completeInitialization()\n })\n return\n }\n\n this._completeInitialization()\n }\n\n private _completeInitialization(): void {\n this._hasProcessedRestoreToken = true\n\n // Load any existing ticket ID from localStorage\n this._currentTicketId = this._persistence.loadTicketId()\n logger.info('Loaded ticket ID from storage', { ticketId: this._currentTicketId })\n\n // Track conversations API loaded (separate from widget loaded)\n this._posthog.capture('$conversations_loaded', {\n hasExistingTicket: !!this._currentTicketId,\n widgetEnabled: this._isWidgetEnabled,\n domainAllowed: this._isDomainAllowed,\n })\n\n // Only render widget if both widgetEnabled and domain is allowed\n if (this._isWidgetEnabled && this._isDomainAllowed) {\n this._initializeWidget()\n } else {\n logger.info('Widget not rendered', {\n widgetEnabled: this._isWidgetEnabled,\n domainAllowed: this._isDomainAllowed,\n })\n }\n\n // Listen for identify events to hide identification form when user identifies\n this._setupIdentifyListener()\n }\n\n private async _restoreFromTokenWithRetry(restoreToken: string): Promise<RestoreFromTokenResponse> {\n try {\n return await this._restoreFromToken(restoreToken)\n } catch (error) {\n logger.warn('Restore token exchange failed, retrying once', error)\n return await this._restoreFromToken(restoreToken)\n }\n }\n\n private async _restoreFromToken(restoreToken: string): Promise<RestoreFromTokenResponse> {\n const token = this._config.token\n\n const payload: RestoreFromTokenPayload = {\n restore_token: restoreToken,\n widget_session_id: this._widgetSessionId,\n distinct_id: this._posthog.get_distinct_id(),\n current_url: window?.location?.href,\n }\n\n // eslint-disable-next-line compat/compat\n const data = await new Promise<RestoreFromTokenResponse>((resolve, reject) => {\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor('api', RESTORE_EXCHANGE_ENDPOINT),\n method: 'POST',\n data: payload,\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg =\n response.json?.error ||\n response.json?.detail ||\n response.json?.message ||\n 'Failed to restore conversations'\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n resolve(response.json as RestoreFromTokenResponse)\n },\n })\n })\n\n if (data.status !== 'success') {\n logger.info('Restore token was not accepted', { status: data.status, code: data.code })\n return data\n }\n\n this._lastMessageTimestamp = null\n this._unreadCount = 0\n\n // Apply the canonical widget_session_id from the server if provided\n if (data.widget_session_id) {\n this._widgetSessionId = data.widget_session_id\n this._persistence.setWidgetSessionId(data.widget_session_id)\n }\n\n if (data.migrated_ticket_ids?.length) {\n this._currentTicketId = data.migrated_ticket_ids[0]\n this._persistence.saveTicketId(this._currentTicketId)\n // Poll straight away so messages and ticket list are fresh\n void this._pollMessages()\n void this._pollTickets()\n } else {\n this._currentTicketId = null\n this._persistence.clearTicketId()\n }\n\n return data\n }\n\n /**\n * Initialize and render the widget UI\n * Uses a promise guard to prevent race conditions from concurrent calls\n */\n private _initializeWidget(): Promise<void> {\n if (this._isWidgetRendered) {\n return Promise.resolve()\n }\n if (this._initializeWidgetPromise) {\n return this._initializeWidgetPromise\n }\n this._initializeWidgetPromise = this._doInitializeWidget()\n return this._initializeWidgetPromise\n }\n\n private async _doInitializeWidget(): Promise<void> {\n const savedState = this._persistence.loadWidgetState()\n const initialState: ConversationsWidgetState = savedState === 'open' ? 'open' : 'closed'\n this._widgetState = initialState\n\n // Get initial user traits (from PostHog person properties or saved)\n const initialUserTraits = this._getInitialUserTraits()\n\n // Determine initial view based on ticket count\n const { view: initialView, tickets } = await this._determineInitialView()\n this._currentView = initialView\n\n // Render the widget with initial view\n this._renderWidget(initialState, initialUserTraits, initialView, tickets)\n this._isWidgetRendered = true\n\n this._posthog.capture('$conversations_widget_loaded', {\n hasExistingTicket: !!this._currentTicketId,\n initialState: initialState,\n initialView: initialView,\n ticketCount: tickets.length,\n hasUserTraits: !!initialUserTraits,\n })\n\n // Start polling — the first poll fires immediately and loads messages or tickets\n this._startPolling()\n }\n\n /**\n * Extract name and email from PostHog's stored person properties.\n *\n * Person properties set via posthog.identify() are stored under the\n * $stored_person_properties persistence key, not as top-level props.\n * We check both locations plus the super-properties for completeness.\n */\n private _getPersonTraits(): { name: string | undefined; email: string | undefined } {\n const superProps = this._posthog.persistence?.props || {}\n const storedPersonProps =\n (this._posthog.get_property(STORED_PERSON_PROPERTIES_KEY) as Record<string, any>) || {}\n\n const name =\n storedPersonProps.$name || storedPersonProps.name || superProps.$name || superProps.name || undefined\n const email =\n storedPersonProps.$email || storedPersonProps.email || superProps.$email || superProps.email || undefined\n\n return { name, email }\n }\n\n /**\n * Get initial user traits from PostHog or localStorage\n */\n private _getInitialUserTraits(): UserProvidedTraits | null {\n const { name, email } = this._getPersonTraits()\n\n if (name || email) {\n return {\n name: name || undefined,\n email: email || undefined,\n }\n }\n\n // Otherwise, check localStorage for previously saved traits\n const savedTraits = this._persistence.loadUserTraits()\n if (savedTraits && (savedTraits.name || savedTraits.email)) {\n return savedTraits\n }\n\n return null\n }\n\n /**\n * Handle user identification from the widget form\n */\n private _handleIdentify = (traits: UserProvidedTraits): void => {\n // Save traits to localStorage\n this._persistence.saveUserTraits(traits)\n\n // Track identification\n this._posthog.capture('$conversations_user_identified', {\n hasName: !!traits.name,\n hasEmail: !!traits.email,\n })\n }\n\n private _handleRequestRestoreLink = async (email: string): Promise<RequestRestoreLinkResponse> => {\n const response = await this.requestRestoreLink(email)\n this._posthog.capture('$conversations_restore_link_requested', {\n hasEmail: !!email,\n })\n return response\n }\n\n /**\n * Handle sending a message from the widget\n */\n private _handleSendMessage = async (message: string): Promise<void> => {\n // Get user traits from the widget\n const userTraits = this._widgetRef?.getUserTraits() || undefined\n\n try {\n // Call the public API method (which handles tracking and state updates)\n await this.sendMessage(message, userTraits)\n\n // Poll for response immediately\n setTimeout(() => this._pollMessages(), 1000)\n } catch (error) {\n logger.error('Failed to send message', error)\n throw error\n }\n }\n\n /**\n * Handle widget state changes\n */\n private _handleStateChange = (state: ConversationsWidgetState): void => {\n this._widgetState = state\n logger.info('Widget state changed', { state, view: this._currentView })\n\n this._posthog.capture('$conversations_widget_state_changed', {\n state: state,\n view: this._currentView,\n ticketId: this._currentTicketId,\n })\n\n this._persistence.saveWidgetState(state)\n\n // Mark messages as read when widget opens (only if in message view with a ticket)\n if (state === 'open') {\n if (this._currentView === 'messages' && this._unreadCount > 0 && this._currentTicketId) {\n this._markMessagesAsRead()\n }\n }\n }\n\n /**\n * Mark messages as read\n */\n private async _markMessagesAsRead(): Promise<void> {\n if (!this._currentTicketId) {\n return\n }\n\n try {\n const response = await this.markAsRead(this._currentTicketId)\n this._unreadCount = response.unread_count\n // Update the widget to reflect the new unread count\n this._widgetRef?.setUnreadCount(0)\n logger.info('Messages marked as read', { unreadCount: response.unread_count })\n } catch (error) {\n logger.error('Failed to mark messages as read', error)\n }\n }\n\n /**\n * Load messages for the current ticket\n */\n private async _loadMessages(): Promise<void> {\n if (!this._currentTicketId) {\n return\n }\n\n try {\n const identityBefore = this._posthog.config.identity_distinct_id\n const ticketBefore = this._currentTicketId\n const response = await this.getMessages(this._currentTicketId, this._lastMessageTimestamp || undefined)\n\n // Discard stale response if identity or ticket changed while in-flight\n if (\n this._posthog.config.identity_distinct_id !== identityBefore ||\n this._currentTicketId !== ticketBefore\n ) {\n return\n }\n\n // Update unread count from response\n if (isNumber(response.unread_count)) {\n this._unreadCount = response.unread_count\n this._widgetRef?.setUnreadCount(response.unread_count)\n\n // If widget is open and there are unread messages, mark them as read\n if (response.unread_count > 0 && this._isWidgetOpen()) {\n this._markMessagesAsRead()\n }\n }\n\n // Sync ticket_status so an agent-side resolve flips the UI to locked state even\n // while we're polling messages (ticket polling doesn't run in messages view).\n if (response.ticket_status) {\n this._applyTicketStatusUpdate(this._currentTicketId, response.ticket_status)\n }\n\n if (response.messages.length > 0) {\n this._widgetRef?.addMessages(response.messages)\n // Update last message timestamp\n const lastMessage = response.messages[response.messages.length - 1]\n this._lastMessageTimestamp = lastMessage.created_at\n }\n } catch (error) {\n logger.error('Failed to load messages', error)\n }\n }\n\n private _isWidgetOpen(): boolean {\n return this._widgetState === 'open'\n }\n\n /**\n * Poll for new messages\n */\n private _pollMessages = async (): Promise<void> => {\n if (this._isPollingMessages || !this._currentTicketId) {\n return\n }\n\n this._isPollingMessages = true\n try {\n await this._loadMessages()\n } finally {\n this._isPollingMessages = false\n }\n }\n\n /**\n * Poll for tickets list\n */\n private _pollTickets = async (): Promise<void> => {\n if (this._isPollingTickets) {\n return\n }\n\n this._isPollingTickets = true\n try {\n await this._loadTickets()\n } finally {\n this._isPollingTickets = false\n }\n }\n\n /**\n * Load tickets list from API\n */\n private async _loadTickets(): Promise<void> {\n try {\n const response = await this.getTickets()\n this._tickets = response.results\n this._showTicketList = this._computeShowTicketList(response.results)\n this._widgetRef?.updateTickets(response.results, this._showTicketList)\n\n // Calculate total unread across all tickets\n const totalUnread = response.results.reduce((sum, t) => sum + (t.unread_count || 0), 0)\n this._unreadCount = totalUnread\n this._widgetRef?.setUnreadCount(totalUnread)\n\n this._widgetRef?.setCurrentTicketResolved(this._isCurrentTicketResolved())\n\n logger.info('Tickets loaded', { count: response.results.length, totalUnread })\n } catch (error) {\n logger.error('Failed to load tickets', error)\n }\n }\n\n private _computeShowTicketList(tickets: Ticket[]): boolean {\n if (tickets.length > 1) {\n return true\n }\n if (tickets.length === 1 && tickets[0].status === 'resolved') {\n return true\n }\n return false\n }\n\n private _isCurrentTicketResolved(): boolean {\n if (!this._currentTicketId) {\n return false\n }\n const ticket = this._tickets.find((t) => t.id === this._currentTicketId)\n return ticket?.status === 'resolved'\n }\n\n /**\n * Patch the local _tickets cache with a new status for a given ticket and push\n * any UI-relevant changes (resolved lock + list visibility) to the widget.\n */\n private _applyTicketStatusUpdate(ticketId: string, status: TicketStatus): void {\n const idx = this._tickets.findIndex((t) => t.id === ticketId)\n if (idx === -1) {\n return\n }\n if (this._tickets[idx].status === status) {\n return\n }\n this._tickets = [\n ...this._tickets.slice(0, idx),\n { ...this._tickets[idx], status },\n ...this._tickets.slice(idx + 1),\n ]\n this._showTicketList = this._computeShowTicketList(this._tickets)\n this._widgetRef?.updateTickets(this._tickets, this._showTicketList)\n this._widgetRef?.setCurrentTicketResolved(this._isCurrentTicketResolved())\n }\n\n /**\n * Main poll function that polls based on current view\n */\n private _poll = async (): Promise<void> => {\n if (this._currentView === 'restore_request') {\n return\n }\n\n if (this._currentView === 'messages') {\n await this._pollMessages()\n } else {\n await this._pollTickets()\n }\n }\n\n /**\n * Handle view changes from the widget\n */\n private _handleViewChange = (view: WidgetView): void => {\n logger.info('View changed', { from: this._currentView, to: view })\n this._currentView = view\n }\n\n /**\n * Handle ticket selection from the list\n */\n private _handleSelectTicket = async (ticketId: string): Promise<void> => {\n // Switch to this ticket\n this._switchToTicketIfNeeded(ticketId)\n\n // Clear messages and reset timestamp\n this._lastMessageTimestamp = null\n this._widgetRef?.clearMessages()\n\n // Switch view to messages\n this._currentView = 'messages'\n this._widgetRef?.setView('messages')\n\n // Push resolved state for this ticket so MessagesView locks the input if needed\n this._widgetRef?.setCurrentTicketResolved(this._isCurrentTicketResolved())\n\n // Load messages for the selected ticket\n await this._loadMessages()\n\n // Mark as read if widget is open\n if (this._isWidgetOpen() && this._unreadCount > 0) {\n this._markMessagesAsRead()\n }\n }\n\n /**\n * Handle new conversation request\n */\n private _handleNewConversation = (): void => {\n logger.info('New conversation requested')\n\n // Clear current ticket\n this._currentTicketId = null\n this._persistence.clearTicketId()\n\n // Reset timestamp\n this._lastMessageTimestamp = null\n\n // Switch view to messages\n this._currentView = 'messages'\n this._widgetRef?.setView('messages')\n\n // Fresh ticket is never resolved — unlock the input\n this._widgetRef?.setCurrentTicketResolved(false)\n\n // Clear messages and add greeting\n this._widgetRef?.clearMessages(true)\n }\n\n /**\n * Handle back to tickets request\n */\n private _handleBackToTickets = async (): Promise<void> => {\n logger.info('Back to tickets requested')\n\n // Switch view to tickets\n this._currentView = 'tickets'\n this._widgetRef?.setView('tickets')\n\n // Load tickets\n this._widgetRef?.setTicketsLoading(true)\n await this._loadTickets()\n\n // Track back to tickets\n this._posthog.capture('$conversations_back_to_tickets')\n }\n\n /**\n * Determine initial view based on ticket count\n */\n private async _determineInitialView(): Promise<{ view: WidgetView; tickets: Ticket[] }> {\n try {\n const identityBefore = this._posthog.config.identity_distinct_id\n const response = await this.getTickets()\n\n // If identity changed while the request was in-flight, discard this\n // stale response -- setIdentity/clearIdentity already triggered a\n // fresh _loadTicketsAndReconcileView() with the correct credentials.\n if (this._posthog.config.identity_distinct_id !== identityBefore) {\n return { view: 'messages', tickets: [] }\n }\n\n const view = this._applyTicketsToState(response.results)\n return { view, tickets: response.results }\n } catch (error) {\n logger.error('Failed to determine initial view', error)\n return { view: 'messages', tickets: [] }\n }\n }\n\n /**\n * Apply a fetched ticket list to internal state and return the appropriate view.\n * Shared by _determineInitialView (widget boot) and _loadTicketsAndReconcileView\n * (identity change at runtime).\n */\n private _applyTicketsToState(tickets: Ticket[]): WidgetView {\n this._tickets = tickets\n this._showTicketList = this._computeShowTicketList(tickets)\n\n const totalUnread = tickets.reduce((sum, t) => sum + (t.unread_count || 0), 0)\n this._unreadCount = totalUnread\n\n if (tickets.length >= 2) {\n this._currentTicketId = null\n return 'tickets'\n }\n\n // Single resolved ticket: show list so user can start a new conversation instead of writing to it\n if (tickets.length === 1 && tickets[0].status === 'resolved') {\n this._currentTicketId = null\n this._persistence.clearTicketId()\n return 'tickets'\n }\n\n if (tickets.length === 1) {\n this._currentTicketId = tickets[0].id\n this._persistence.saveTicketId(tickets[0].id)\n }\n\n return 'messages'\n }\n\n /**\n * Start polling based on current view\n */\n private _startPolling(): void {\n if (this._pollIntervalId) {\n return // Already polling\n }\n\n // Poll immediately\n this._poll()\n\n // Set up interval\n this._pollIntervalId = window?.setInterval(() => {\n this._poll()\n }, POLL_INTERVAL_MS) as unknown as number\n\n logger.info('Started polling', { view: this._currentView })\n }\n\n /**\n * Stop polling for new messages\n */\n private _stopPolling(): void {\n if (this._pollIntervalId) {\n window?.clearInterval(this._pollIntervalId)\n this._pollIntervalId = null\n logger.info('Stopped polling for messages')\n }\n }\n\n /**\n * Setup listener for identify events.\n * When user calls posthog.identify(), hide the identification form\n * since we now know who they are.\n */\n private _setupIdentifyListener(): void {\n this._unsubscribeIdentifyListener = this._posthog.on('eventCaptured', (event: any) => {\n if (event.event === '$identify') {\n // User just identified - hide the identification form if it's showing\n this._widgetRef?.setUserIdentified()\n }\n })\n }\n\n /**\n * Show the widget (render it to DOM).\n * The widget respects its saved state (open/closed).\n * Note: Domain restrictions still apply - widget won't render on disallowed domains.\n */\n show(): void {\n // Check domain restrictions - don't render on disallowed domains\n if (!this._isDomainAllowed) {\n logger.warn('Cannot show widget: current domain is not allowed')\n return\n }\n\n // If widget isn't rendered yet, render it now\n if (!this._isWidgetRendered) {\n this._initializeWidget()\n }\n }\n\n /**\n * Hide and remove the widget from the DOM.\n * Conversation data is preserved - call show() to re-render.\n */\n hide(): void {\n // Stop polling when widget is hidden (save resources)\n this._stopPolling()\n\n if (this._containerElement) {\n render(null, this._containerElement)\n this._containerElement.remove()\n this._containerElement = null\n }\n this._widgetRef = null\n this._isWidgetRendered = false\n this._initializeWidgetPromise = null\n\n // Reset timestamp so show() will re-fetch all messages\n this._lastMessageTimestamp = null\n }\n\n /**\n * Check if the widget is currently visible (rendered in DOM)\n */\n isVisible(): boolean {\n return this._isWidgetRendered\n }\n\n /** Get tickets list for the current widget session or verified identity */\n async getTickets(options?: GetTicketsOptions): Promise<GetTicketsResponse> {\n const token = this._config.token\n\n const identity = this._identityFields()\n const queryParams: Record<string, string> = {\n limit: String(options?.limit ?? 20),\n offset: String(options?.offset ?? 0),\n }\n\n if (identity) {\n queryParams.identity_distinct_id = identity.identity_distinct_id\n queryParams.identity_hash = identity.identity_hash\n } else {\n queryParams.widget_session_id = this._widgetSessionId\n }\n\n if (options?.status) {\n queryParams.status = options.status\n }\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/tickets?${formDataToQuery(queryParams)}`\n ),\n method: 'GET',\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to fetch tickets'\n logger.error('Failed to fetch tickets', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as GetTicketsResponse\n resolve(data)\n },\n })\n })\n }\n\n async requestRestoreLink(email: string): Promise<RequestRestoreLinkResponse> {\n if (this._identityFields()) {\n return { ok: true }\n }\n\n const normalizedEmail = email.trim().toLowerCase()\n if (!normalizedEmail) {\n throw new Error('Email is required')\n }\n\n const token = this._config.token\n const payload: RequestRestoreLinkPayload = {\n email: normalizedEmail,\n request_url: window?.location?.href || '',\n }\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor('api', RESTORE_REQUEST_ENDPOINT),\n method: 'POST',\n data: payload,\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg =\n response.json?.error ||\n response.json?.detail ||\n response.json?.message ||\n 'Failed to request restore link'\n reject(new Error(errorMsg))\n return\n }\n\n resolve({ ok: true })\n },\n })\n })\n }\n\n async restoreFromToken(restoreToken: string): Promise<RestoreFromTokenResponse> {\n if (this._identityFields()) {\n return { status: 'success' }\n }\n\n const normalizedToken = restoreToken.trim()\n if (!normalizedToken) {\n throw new Error('Restore token is required')\n }\n try {\n return await this._restoreFromTokenWithRetry(normalizedToken)\n } finally {\n clearRestoreTokenFromUrl()\n }\n }\n\n async restoreFromUrlToken(): Promise<RestoreFromTokenResponse | null> {\n if (this._identityFields()) {\n return null\n }\n\n const restoreToken = getRestoreTokenFromUrl()\n if (!restoreToken) {\n return null\n }\n\n try {\n return await this.restoreFromToken(restoreToken)\n } finally {\n clearRestoreTokenFromUrl()\n }\n }\n\n /**\n * Get the current active ticket ID\n * Returns null if no conversation has been started yet\n */\n getCurrentTicketId(): string | null {\n return this._currentTicketId\n }\n\n /**\n * Get the widget session ID (persistent browser identifier)\n * This ID is used for access control and stays the same across page loads\n */\n getWidgetSessionId(): string {\n return this._widgetSessionId\n }\n\n private _identityFields(): { identity_distinct_id: string; identity_hash: string } | null {\n const id = this._posthog.config.identity_distinct_id\n const hash = this._posthog.config.identity_hash\n if (!id || !hash) {\n return null\n }\n return { identity_distinct_id: id, identity_hash: hash }\n }\n\n setIdentity(): void {\n this._resetConversationState()\n this._widgetRef?.setIdentityMode(true)\n void this._loadTicketsAndReconcileView()\n }\n\n clearIdentity(): void {\n this._resetConversationState()\n this._widgetRef?.setIdentityMode(false)\n void this._loadTicketsAndReconcileView()\n }\n\n private _resetConversationState(): void {\n this._currentTicketId = null\n this._persistence.clearTicketId()\n this._lastMessageTimestamp = null\n this._widgetRef?.clearMessages(true)\n }\n\n private async _loadTicketsAndReconcileView(): Promise<void> {\n try {\n const identityBefore = this._posthog.config.identity_distinct_id\n const response = await this.getTickets()\n\n if (this._posthog.config.identity_distinct_id !== identityBefore) {\n return\n }\n\n const view = this._applyTicketsToState(response.results)\n this._widgetRef?.updateTickets(response.results, this._showTicketList)\n this._widgetRef?.setUnreadCount(this._unreadCount)\n this._widgetRef?.setCurrentTicketResolved(this._isCurrentTicketResolved())\n this._currentView = view\n this._widgetRef?.setView(view)\n\n if (view === 'messages' && this._currentTicketId) {\n void this._loadMessages()\n }\n } catch (error) {\n logger.error('Failed to load tickets after identity change', error)\n }\n }\n\n /**\n * Clean up the widget\n */\n destroy(): void {\n this._stopPolling()\n\n // Unsubscribe from identify events\n if (this._unsubscribeIdentifyListener) {\n this._unsubscribeIdentifyListener()\n this._unsubscribeIdentifyListener = null\n }\n\n if (this._containerElement) {\n render(null, this._containerElement)\n this._containerElement.remove()\n this._containerElement = null\n }\n\n this._widgetRef = null\n\n if (_activeManager === this) {\n _activeManager = null\n }\n logger.info('Widget destroyed')\n }\n\n /**\n * Reset all conversation data and destroy the widget.\n * Called on posthog.reset() to start fresh.\n */\n reset(): void {\n // Clear all persisted conversation data\n this._persistence.clearAll()\n\n // Reset local state\n this._currentTicketId = null\n this._lastMessageTimestamp = null\n this._unreadCount = 0\n\n // Destroy the widget\n this.destroy()\n\n logger.info('Conversations reset')\n }\n\n /**\n * Render the widget to the DOM\n */\n private _renderWidget(\n initialState: ConversationsWidgetState,\n initialUserTraits: UserProvidedTraits | null,\n initialView: WidgetView = 'messages',\n initialTickets: Ticket[] = []\n ): void {\n if (!document) {\n logger.info('Conversations widget not rendered: Document not available')\n return\n }\n\n // Create container if it doesn't exist\n let container = document.getElementById(WIDGET_CONTAINER_ID) as HTMLDivElement\n if (!container) {\n if (!document.body) {\n logger.info('Conversations widget not rendered: Document body not available yet')\n return\n }\n container = document.createElement('div')\n container.id = WIDGET_CONTAINER_ID\n document.body.appendChild(container)\n }\n this._containerElement = container\n\n // Render widget with ref\n render(\n <ConversationsWidget\n ref={(ref: ConversationsWidget | null) => {\n this._widgetRef = ref\n }}\n config={this._config}\n initialState={initialState}\n initialUserTraits={initialUserTraits}\n isUserIdentified={this._posthog._isIdentified()}\n isIdentityMode={!isNull(this._identityFields())}\n initialView={initialView}\n initialTickets={initialTickets}\n showTicketList={this._showTicketList}\n onSendMessage={this._handleSendMessage}\n onStateChange={this._handleStateChange}\n onIdentify={this._handleIdentify}\n onRequestRestoreLink={this._handleRequestRestoreLink}\n onSelectTicket={this._handleSelectTicket}\n onNewConversation={this._handleNewConversation}\n onBackToTickets={this._handleBackToTickets}\n onViewChange={this._handleViewChange}\n />,\n container\n )\n }\n}\n\n/**\n * Initialize the conversations widget.\n * This is the entry point called from the lazy-loaded bundle.\n *\n * Singleton guard: only one ConversationsManager per page. The toolbar's\n * internal PostHog instance is excluded upstream (see loadIfEnabled), so\n * this always belongs to the customer's main instance.\n */\nexport function initConversations(config: ConversationsRemoteConfig, posthog: PostHog): ConversationsManager {\n if (_activeManager) {\n return _activeManager\n }\n\n _activeManager = new ConversationsManager(config, posthog)\n return _activeManager\n}\n","import { initConversations } from '../extensions/conversations/external'\nimport { assignableWindow } from '../utils/globals'\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.initConversations = initConversations\n\nexport default initConversations\n"],"names":["p","v","y","ObjProto","Object","prototype","type_utils_hasOwnProperty","hasOwnProperty","type_utils_toString","toString","isArray","Array","obj","call","isUndefined","x","isNull","isNumber","CONVERSATIONS_LEGACY_WIDGET_SESSION_ID","CONVERSATIONS_LEGACY_TICKET_ID","CONVERSATIONS_LEGACY_WIDGET_STATE","CONVERSATIONS_LEGACY_USER_TRAITS","win","window","undefined","global","globalThis","self","File","document","XMLHttpRequest","assignableWindow","_createLogger","prefix","_temp","debugEnabled","logger","_log","level","POSTHOG_DEBUG","console","consoleLog","_len","arguments","length","args","_key","info","_len2","_key2","warn","_len3","_key3","error","_len4","_key4","critical","_len5","_key5","uninitializedWarning","methodName","createLogger","additionalPrefix","options","Math","trunc","ceil","floor","Number","isInteger","value","isFinite","UUID","constructor","bytes","this","TypeError","fromFieldsV7","unixTsMs","randA","randBHi","randBLo","RangeError","Uint8Array","pow","text","i","Error","clone","slice","equals","other","compareTo","diff","sign","V7Generator","_timestamp","_counter","_random","DefaultRandom","generate","generateOrAbort","valueAfterReset","ts","Date","now","_resetCounter","nextUint32","defaultGenerator","getRandomValues","buffer","UUIDV7_DENY_WEAK_RNG","random","crypto","_buffer","Uint32Array","_cursor","Infinity","ConversationsPersistence","_posthog","_posthog$config","token","_cachedWidgetSessionId","_storageKey","config","_migrateFromLegacyPersistence","getOrCreateWidgetSessionId","_this$_read","sessionId","_read","widgetSessionId","_write","setWidgetSessionId","id","data","_extends","clearWidgetSessionId","saveTicketId","ticketId","loadTicketId","_this$_read2","clearTicketId","saveWidgetState","state","widgetState","loadWidgetState","_this$_read3","saveUserTraits","traits","userTraits","loadUserTraits","_this$_read4","name","email","clearUserTraits","clearAll","_window$localStorage","localStorage","removeItem","_unused","_window$localStorage2","raw","getItem","JSON","parse","_unused2","_window$localStorage3","setItem","stringify","_this$_read5","persistence","isDisabled","get_property","legacyFromRaw","_readLegacyFromRawStorage","unregister","_this$_posthog$config","_window$localStorage4","persistence_name","parsed","_unused3","getContrastTextColor","hexColor","hex","replace","fullHex","r","parseInt","g","b","sqrt","getStyles","primaryColor","position","isLeft","includes","isTop","widget","top","bottom","left","right","zIndex","fontFamily","buttonContainer","button","width","height","borderRadius","background","color","border","cursor","boxShadow","display","alignItems","justifyContent","transition","unreadBadge","minWidth","fontSize","fontWeight","padding","boxSizing","flexDirection","overflow","windowOpen","maxWidth","maxHeight","header","flexShrink","headerTitle","headerActions","gap","headerLinkButton","opacity","headerButton","lineHeight","messages","flex","overflowY","message","animation","messageCustomer","alignSelf","messageAgent","messageAuthor","marginBottom","messageContent","wordWrap","whiteSpace","messageContentCustomer","borderBottomRightRadius","messageContentAgent","borderBottomLeftRadius","messageTime","marginTop","borderTop","borderBottom","textAlign","inputContainer","resolvedBanner","paddingTop","resolvedBannerText","input","resize","outline","fieldSizing","sendButton","identificationForm","formTitle","formDescription","recoverFooter","recoverFooterLink","textDecoration","formField","formLabel","formInput","formInputError","borderColor","formError","formSubmitButton","formOptional","restoreRequestSuccess","ticketListContainer","ticketList","ticketItem","ticketItemUnread","ticketItemContent","ticketItemArrow","ticketItemHeader","ticketPreview","textOverflow","ticketPreviewUnread","ticketUnreadBadge","ticketMeta","ticketTime","ticketStatus","textTransform","letterSpacing","newConversationButton","margin","ticketListLoading","loadingSpinner","ticketListEmpty","emptyStateIcon","emptyStateTitle","emptyStateDescription","newConversationButtonLarge","fetchPreviousButton","backButton","marginRight","headerWithBack","OpenChatButton","_ref","handleToggleOpen","unreadCount","styles","displayCount","_jsx","style","children","_jsxs","onClick","onMouseEnter","e","currentTarget","transform","onMouseLeave","viewBox","fill","xmlns","d","CloseChatButton","handleClose","formatRelativeTime","isoString","date","diffMs","getTime","diffMins","diffHours","diffDays","toLocaleDateString","truncateText","maxLength","substring","TicketListItem","status","ticket","hasUnread","unread_count","statusLabel","charAt","toUpperCase","handleClick","onKeyDown","key","preventDefault","role","tabIndex","last_message","trim","last_message_at","created_at","stroke","strokeWidth","points","NewConversationButton","type","x1","y1","x2","y2","LoadingState","EmptyState","_ref2","onNewConversation","onOpenRestoreRequest","TicketListView","_ref3","tickets","isLoading","onSelectTicket","sort","a","dateA","map","IdentificationFormView","formName","formEmail","formEmailError","onNameChange","onEmailChange","onSubmit","description","identificationFormDescription","showNameField","collectName","identificationFormTitle","onInput","placeholder","autoComplete","requireEmail","RestoreRequestView","restoreEmail","restoreEmailError","restoreRequestLoading","disabled","t","u","SendMessageButton","inputValue","handleSendMessage","strokeLinejoin","o","f","c","n","__b","__r","diffed","l","__c","m","unmount","s","__","__h","__H","push","j","shift","__P","forEach","z","B","__e","__v","__k","__m","__N","requestAnimationFrame","w","some","filter","k","clearTimeout","cancelAnimationFrame","setTimeout","sanitizeUrl","url","trimmedUrl","normalizedForCheck","toLowerCase","startsWith","lowerUrl","MAX_DEPTH","renderNode","node","depth","_node$content","marks","element","_Fragment","mark","fontStyle","code","_mark$attrs","href","attrs","safeUrl","target","rel","referrerPolicy","link","renderTextWithMarks","content","child","index","_node$content2","codeText","codeBlock","_node$attrs","_node$attrs2","src","alt","image","onError","paddingLeft","borderLeft","_node$attrs3","rawLevel","min","max","RichContent","richContent","isCustomer","C","useMemo","overflowX","wordBreak","doc","isValidTipTapDoc","rendered","lines","split","line","Fragment","renderPlainText","MessageBubble","author_type","messageStyle","contentStyle","author_name","rich_content","MessagesView","placeholderText","isResolved","onInputChange","onSendMessage","onStartNewConversation","messagesEndRef","inputRef","ref","rows","ConversationsWidget","Component","props","_this","super","_messagesEndRef","_inputRef","_handleToggleOpen","setState","prevState","_handleClose","_handleSelectTicket","_handleNewConversation","_handleBackToTickets","onBackToTickets","_handleOpenRestoreRequest","_prevState$userTraits","view","onViewChange","_handleCloseRestoreRequest","returnView","showTicketList","_handleInputChange","_handleKeyPress","shiftKey","_handleSendMessage","_handleFormNameChange","_handleFormEmailChange","_handleRestoreEmailChange","_handleFormSubmit","onIdentify","_validateEmail","nextView","_handleRestoreRequestSubmit","_asyncToGenerator","onRequestRestoreLink","_x","apply","trimmedMessage","userMessage","toISOString","is_private","isIdentityMode","initialUserTraits","needsIdentification","_needsIdentification","isUserIdentified","initialState","initialView","initialTickets","ticketsLoading","isCurrentTicketResolved","componentDidMount","greetingText","_addGreetingMessage","componentDidUpdate","_prevProps","_scrollToBottom","onStateChange","_focusInput","greetingMessage","scrollIntoView","behavior","focus","test","addMessages","existingIds","Set","newMessages","has","show","hide","getUserTraits","setUserIdentified","setUnreadCount","count","updateTickets","setCurrentTicketResolved","resolved","setView","getView","setTicketsLoading","loading","setIdentityMode","update","clearMessages","addGreeting","_renderIdentificationForm","_renderBackButton","_renderTicketList","_renderMessages","el","_renderRestoreRequestView","_getTitle","_renderViewContent","render","widgetPosition","windowStyle","showBackButton","showRecoverFooter","formDataToQuery","formdata","arg_separator","use_val","use_key","tph_arr","iterator","isNullish","FormData","isFormData","val","each","encodeURIComponent","isFile","join","RESTORE_QUERY_PARAM","getRestoreTokenFromUrl","_window$location2","location","search","URLSearchParams","get","clearRestoreTokenFromUrl","_window$history","history","replaceState","URL","searchParams","delete","pathname","hash","WIDGET_CONTAINER_ID","_activeManager","ConversationsManager","_widgetRef","_containerElement","_currentTicketId","_pollIntervalId","_lastMessageTimestamp","_isPollingMessages","_isPollingTickets","_unsubscribeIdentifyListener","_unreadCount","_widgetState","_isWidgetRendered","_hasProcessedRestoreToken","_initializeWidgetPromise","_currentView","_tickets","_showTicketList","_handleIdentify","_persistence","capture","hasName","hasEmail","_handleRequestRestoreLink","response","requestRestoreLink","_this$_widgetRef","sendMessage","_pollMessages","_x2","_handleStateChange","_markMessagesAsRead","_loadMessages","_pollTickets","_loadTickets","_poll","_handleViewChange","from","to","_ref6","_this$_widgetRef2","_this$_widgetRef3","_this$_widgetRef4","_switchToTicketIfNeeded","_isCurrentTicketResolved","_isWidgetOpen","_x3","_this$_widgetRef5","_this$_widgetRef6","_this$_widgetRef7","_this$_widgetRef8","_this$_widgetRef9","_config","_widgetSessionId","_isWidgetEnabled","widgetEnabled","_isDomainAllowed","domains","_window$location","currentHostname","hostname","domain","allowedHostname","extractHostname","pattern","endsWith","isCurrentDomainAllowed","_initialize","newTicket","_this2","isNewTicket","Promise","resolve","reject","personTraits","_getPersonTraits","identity","_identityFields","payload","ticket_id","identity_distinct_id","identity_hash","distinct_id","widget_session_id","get_distinct_id","capturedSessionId","get_session_id","session_id","replayUrl","get_session_replay_url","withTimestamp","timestampLookBack","currentUrl","session_context","session_replay_url","current_url","_send_request","requestRouter","endpointFor","method","headers","callback","statusCode","_response$json","_response$json2","errorMsg","json","detail","forced","messageLength","getMessages","after","_this3","targetTicketId","queryParams","limit","_response$json3","_response$json4","markAsRead","_this4","_response$json5","_response$json6","_completeInitialization","restoreToken","_restoreFromTokenWithRetry","catch","finally","hasExistingTicket","domainAllowed","_initializeWidget","_setupIdentifyListener","_this5","_restoreFromToken","_this6","_data$migrated_ticket","restore_token","_response$json7","_response$json8","_response$json9","migrated_ticket_ids","_doInitializeWidget","_this7","_getInitialUserTraits","_determineInitialView","_renderWidget","ticketCount","hasUserTraits","_startPolling","_this$_posthog$persis","superProps","storedPersonProps","$name","$email","savedTraits","_this8","_this8$_widgetRef","_this9","_this9$_widgetRef","_this9$_widgetRef2","identityBefore","ticketBefore","ticket_status","_applyTicketStatusUpdate","_this0","_this0$_widgetRef","_this0$_widgetRef2","_this0$_widgetRef3","getTickets","results","_computeShowTicketList","totalUnread","reduce","sum","find","_this$_widgetRef0","_this$_widgetRef1","idx","findIndex","_this1","_applyTicketsToState","setInterval","_stopPolling","clearInterval","on","event","_this$_widgetRef10","remove","isVisible","_this10","_options$limit","_options$offset","String","offset","_response$json0","_response$json1","_this11","_window$location3","ok","normalizedEmail","request_url","_response$json10","_response$json11","_response$json12","restoreFromToken","_this12","normalizedToken","restoreFromUrlToken","_this13","getCurrentTicketId","getWidgetSessionId","setIdentity","_this$_widgetRef11","_resetConversationState","_loadTicketsAndReconcileView","clearIdentity","_this$_widgetRef12","_this$_widgetRef13","_this14","_this14$_widgetRef","_this14$_widgetRef2","_this14$_widgetRef3","_this14$_widgetRef4","destroy","reset","container","getElementById","body","createElement","appendChild","_isIdentified","__PosthogExtensions__","initConversations","posthog"],"mappings":"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","x_google_ignoreList":[0,17]}
|
|
1
|
+
{"version":3,"file":"conversations.js","sources":["../../../node_modules/.pnpm/preact@10.28.2/node_modules/preact/dist/preact.module.js","../../core/dist/utils/type-utils.mjs","../src/constants.ts","../src/utils/globals.ts","../src/utils/logger.ts","../src/uuidv7.ts","../src/extensions/conversations/external/persistence.ts","../src/extensions/conversations/external/components/styles.ts","../src/extensions/conversations/external/components/OpenChatButton.tsx","../src/extensions/conversations/external/components/CloseChatButton.tsx","../src/extensions/conversations/external/components/utils.ts","../src/extensions/conversations/external/components/TicketListItem.tsx","../src/extensions/conversations/external/components/NewConversationButton.tsx","../src/extensions/conversations/external/components/TicketListView.tsx","../src/extensions/conversations/external/components/IdentificationFormView.tsx","../src/extensions/conversations/external/components/RestoreRequestView.tsx","../src/extensions/conversations/external/components/SendMessageButton.tsx","../../../node_modules/.pnpm/preact@10.28.2/node_modules/preact/hooks/dist/hooks.module.js","../src/extensions/conversations/external/components/RichContent.tsx","../src/extensions/conversations/external/components/MessagesView.tsx","../src/extensions/conversations/external/components/ConversationsWidget.tsx","../src/utils/request-utils.ts","../src/utils/index.ts","../src/extensions/conversations/external/url-utils.ts","../src/extensions/conversations/external/index.tsx","../src/entrypoints/conversations.ts"],"sourcesContent":["var n,l,u,t,i,o,r,e,f,c,s,a,h,p={},v=[],y=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,d=Array.isArray;function w(n,l){for(var u in l)n[u]=l[u];return n}function g(n){n&&n.parentNode&&n.parentNode.removeChild(n)}function _(l,u,t){var i,o,r,e={};for(r in u)\"key\"==r?i=u[r]:\"ref\"==r?o=u[r]:e[r]=u[r];if(arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):t),\"function\"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===e[r]&&(e[r]=l.defaultProps[r]);return m(l,e,i,o,null)}function m(n,t,i,o,r){var e={type:n,props:t,key:i,ref:o,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:null==r?++u:r,__i:-1,__u:0};return null==r&&null!=l.vnode&&l.vnode(e),e}function b(){return{current:null}}function k(n){return n.children}function x(n,l){this.props=n,this.context=l}function S(n,l){if(null==l)return n.__?S(n.__,n.__i+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?S(n):null}function C(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return C(n)}}function M(n){(!n.__d&&(n.__d=!0)&&i.push(n)&&!$.__r++||o!=l.debounceRendering)&&((o=l.debounceRendering)||r)($)}function $(){for(var n,u,t,o,r,f,c,s=1;i.length;)i.length>s&&i.sort(e),n=i.shift(),s=i.length,n.__d&&(t=void 0,o=void 0,r=(o=(u=n).__v).__e,f=[],c=[],u.__P&&((t=w({},o)).__v=o.__v+1,l.vnode&&l.vnode(t),O(u.__P,t,o,u.__n,u.__P.namespaceURI,32&o.__u?[r]:null,f,null==r?S(o):r,!!(32&o.__u),c),t.__v=o.__v,t.__.__k[t.__i]=t,N(f,t,c),o.__e=o.__=null,t.__e!=r&&C(t)));$.__r=0}function I(n,l,u,t,i,o,r,e,f,c,s){var a,h,y,d,w,g,_,m=t&&t.__k||v,b=l.length;for(f=P(u,l,m,f,b),a=0;a<b;a++)null!=(y=u.__k[a])&&(h=-1==y.__i?p:m[y.__i]||p,y.__i=a,g=O(n,y,h,i,o,r,e,f,c,s),d=y.__e,y.ref&&h.ref!=y.ref&&(h.ref&&B(h.ref,null,y),s.push(y.ref,y.__c||d,y)),null==w&&null!=d&&(w=d),(_=!!(4&y.__u))||h.__k===y.__k?f=A(y,f,n,_):\"function\"==typeof y.type&&void 0!==g?f=g:d&&(f=d.nextSibling),y.__u&=-7);return u.__e=w,f}function P(n,l,u,t,i){var o,r,e,f,c,s=u.length,a=s,h=0;for(n.__k=new Array(i),o=0;o<i;o++)null!=(r=l[o])&&\"boolean\"!=typeof r&&\"function\"!=typeof r?(\"string\"==typeof r||\"number\"==typeof r||\"bigint\"==typeof r||r.constructor==String?r=n.__k[o]=m(null,r,null,null,null):d(r)?r=n.__k[o]=m(k,{children:r},null,null,null):void 0===r.constructor&&r.__b>0?r=n.__k[o]=m(r.type,r.props,r.key,r.ref?r.ref:null,r.__v):n.__k[o]=r,f=o+h,r.__=n,r.__b=n.__b+1,e=null,-1!=(c=r.__i=L(r,u,f,a))&&(a--,(e=u[c])&&(e.__u|=2)),null==e||null==e.__v?(-1==c&&(i>s?h--:i<s&&h++),\"function\"!=typeof r.type&&(r.__u|=4)):c!=f&&(c==f-1?h--:c==f+1?h++:(c>f?h--:h++,r.__u|=4))):n.__k[o]=null;if(a)for(o=0;o<s;o++)null!=(e=u[o])&&0==(2&e.__u)&&(e.__e==t&&(t=S(e)),D(e,e));return t}function A(n,l,u,t){var i,o;if(\"function\"==typeof n.type){for(i=n.__k,o=0;i&&o<i.length;o++)i[o]&&(i[o].__=n,l=A(i[o],l,u,t));return l}n.__e!=l&&(t&&(l&&n.type&&!l.parentNode&&(l=S(n)),u.insertBefore(n.__e,l||null)),l=n.__e);do{l=l&&l.nextSibling}while(null!=l&&8==l.nodeType);return l}function H(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(d(n)?n.some(function(n){H(n,l)}):l.push(n)),l}function L(n,l,u,t){var i,o,r,e=n.key,f=n.type,c=l[u],s=null!=c&&0==(2&c.__u);if(null===c&&null==e||s&&e==c.key&&f==c.type)return u;if(t>(s?1:0))for(i=u-1,o=u+1;i>=0||o<l.length;)if(null!=(c=l[r=i>=0?i--:o++])&&0==(2&c.__u)&&e==c.key&&f==c.type)return r;return-1}function T(n,l,u){\"-\"==l[0]?n.setProperty(l,null==u?\"\":u):n[l]=null==u?\"\":\"number\"!=typeof u||y.test(l)?u:u+\"px\"}function j(n,l,u,t,i){var o,r;n:if(\"style\"==l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof t&&(n.style.cssText=t=\"\"),t)for(l in t)u&&l in u||T(n.style,l,\"\");if(u)for(l in u)t&&u[l]==t[l]||T(n.style,l,u[l])}else if(\"o\"==l[0]&&\"n\"==l[1])o=l!=(l=l.replace(f,\"$1\")),r=l.toLowerCase(),l=r in n||\"onFocusOut\"==l||\"onFocusIn\"==l?r.slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?t?u.u=t.u:(u.u=c,n.addEventListener(l,o?a:s,o)):n.removeEventListener(l,o?a:s,o);else{if(\"http://www.w3.org/2000/svg\"==i)l=l.replace(/xlink(H|:h)/,\"h\").replace(/sName$/,\"s\");else if(\"width\"!=l&&\"height\"!=l&&\"href\"!=l&&\"list\"!=l&&\"form\"!=l&&\"tabIndex\"!=l&&\"download\"!=l&&\"rowSpan\"!=l&&\"colSpan\"!=l&&\"role\"!=l&&\"popover\"!=l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null==u||!1===u&&\"-\"!=l[4]?n.removeAttribute(l):n.setAttribute(l,\"popover\"==l&&1==u?\"\":u))}}function F(n){return function(u){if(this.l){var t=this.l[u.type+n];if(null==u.t)u.t=c++;else if(u.t<t.u)return;return t(l.event?l.event(u):u)}}}function O(n,u,t,i,o,r,e,f,c,s){var a,h,p,v,y,_,m,b,S,C,M,$,P,A,H,L,T,j=u.type;if(void 0!==u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),r=[f=u.__e=t.__e]),(a=l.__b)&&a(u);n:if(\"function\"==typeof j)try{if(b=u.props,S=\"prototype\"in j&&j.prototype.render,C=(a=j.contextType)&&i[a.__c],M=a?C?C.props.value:a.__:i,t.__c?m=(h=u.__c=t.__c).__=h.__E:(S?u.__c=h=new j(b,M):(u.__c=h=new x(b,M),h.constructor=j,h.render=E),C&&C.sub(h),h.state||(h.state={}),h.__n=i,p=h.__d=!0,h.__h=[],h._sb=[]),S&&null==h.__s&&(h.__s=h.state),S&&null!=j.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=w({},h.__s)),w(h.__s,j.getDerivedStateFromProps(b,h.__s))),v=h.props,y=h.state,h.__v=u,p)S&&null==j.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),S&&null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else{if(S&&null==j.getDerivedStateFromProps&&b!==v&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(b,M),u.__v==t.__v||!h.__e&&null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(b,h.__s,M)){for(u.__v!=t.__v&&(h.props=b,h.state=h.__s,h.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.some(function(n){n&&(n.__=u)}),$=0;$<h._sb.length;$++)h.__h.push(h._sb[$]);h._sb=[],h.__h.length&&e.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(b,h.__s,M),S&&null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(v,y,_)})}if(h.context=M,h.props=b,h.__P=n,h.__e=!1,P=l.__r,A=0,S){for(h.state=h.__s,h.__d=!1,P&&P(u),a=h.render(h.props,h.state,h.context),H=0;H<h._sb.length;H++)h.__h.push(h._sb[H]);h._sb=[]}else do{h.__d=!1,P&&P(u),a=h.render(h.props,h.state,h.context),h.state=h.__s}while(h.__d&&++A<25);h.state=h.__s,null!=h.getChildContext&&(i=w(w({},i),h.getChildContext())),S&&!p&&null!=h.getSnapshotBeforeUpdate&&(_=h.getSnapshotBeforeUpdate(v,y)),L=a,null!=a&&a.type===k&&null==a.key&&(L=V(a.props.children)),f=I(n,d(L)?L:[L],u,t,i,o,r,e,f,c,s),h.base=u.__e,u.__u&=-161,h.__h.length&&e.push(h),m&&(h.__E=h.__=null)}catch(n){if(u.__v=null,c||null!=r)if(n.then){for(u.__u|=c?160:128;f&&8==f.nodeType&&f.nextSibling;)f=f.nextSibling;r[r.indexOf(f)]=null,u.__e=f}else{for(T=r.length;T--;)g(r[T]);z(u)}else u.__e=t.__e,u.__k=t.__k,n.then||z(u);l.__e(n,u,t)}else null==r&&u.__v==t.__v?(u.__k=t.__k,u.__e=t.__e):f=u.__e=q(t.__e,u,t,i,o,r,e,c,s);return(a=l.diffed)&&a(u),128&u.__u?void 0:f}function z(n){n&&n.__c&&(n.__c.__e=!0),n&&n.__k&&n.__k.forEach(z)}function N(n,u,t){for(var i=0;i<t.length;i++)B(t[i],t[++i],t[++i]);l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function V(n){return\"object\"!=typeof n||null==n||n.__b&&n.__b>0?n:d(n)?n.map(V):w({},n)}function q(u,t,i,o,r,e,f,c,s){var a,h,v,y,w,_,m,b=i.props||p,k=t.props,x=t.type;if(\"svg\"==x?r=\"http://www.w3.org/2000/svg\":\"math\"==x?r=\"http://www.w3.org/1998/Math/MathML\":r||(r=\"http://www.w3.org/1999/xhtml\"),null!=e)for(a=0;a<e.length;a++)if((w=e[a])&&\"setAttribute\"in w==!!x&&(x?w.localName==x:3==w.nodeType)){u=w,e[a]=null;break}if(null==u){if(null==x)return document.createTextNode(k);u=document.createElementNS(r,x,k.is&&k),c&&(l.__m&&l.__m(t,e),c=!1),e=null}if(null==x)b===k||c&&u.data==k||(u.data=k);else{if(e=e&&n.call(u.childNodes),!c&&null!=e)for(b={},a=0;a<u.attributes.length;a++)b[(w=u.attributes[a]).name]=w.value;for(a in b)if(w=b[a],\"children\"==a);else if(\"dangerouslySetInnerHTML\"==a)v=w;else if(!(a in k)){if(\"value\"==a&&\"defaultValue\"in k||\"checked\"==a&&\"defaultChecked\"in k)continue;j(u,a,null,w,r)}for(a in k)w=k[a],\"children\"==a?y=w:\"dangerouslySetInnerHTML\"==a?h=w:\"value\"==a?_=w:\"checked\"==a?m=w:c&&\"function\"!=typeof w||b[a]===w||j(u,a,w,b[a],r);if(h)c||v&&(h.__html==v.__html||h.__html==u.innerHTML)||(u.innerHTML=h.__html),t.__k=[];else if(v&&(u.innerHTML=\"\"),I(\"template\"==t.type?u.content:u,d(y)?y:[y],t,i,o,\"foreignObject\"==x?\"http://www.w3.org/1999/xhtml\":r,e,f,e?e[0]:i.__k&&S(i,0),c,s),null!=e)for(a=e.length;a--;)g(e[a]);c||(a=\"value\",\"progress\"==x&&null==_?u.removeAttribute(\"value\"):null!=_&&(_!==u[a]||\"progress\"==x&&!_||\"option\"==x&&_!=b[a])&&j(u,a,_,b[a],r),a=\"checked\",null!=m&&m!=u[a]&&j(u,a,m,b[a],r))}return u}function B(n,u,t){try{if(\"function\"==typeof n){var i=\"function\"==typeof n.__u;i&&n.__u(),i&&null==u||(n.__u=n(u))}else n.current=u}catch(n){l.__e(n,t)}}function D(n,u,t){var i,o;if(l.unmount&&l.unmount(n),(i=n.ref)&&(i.current&&i.current!=n.__e||B(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(n){l.__e(n,u)}i.base=i.__P=null}if(i=n.__k)for(o=0;o<i.length;o++)i[o]&&D(i[o],u,t||\"function\"!=typeof n.type);t||g(n.__e),n.__c=n.__=n.__e=void 0}function E(n,l,u){return this.constructor(n,u)}function G(u,t,i){var o,r,e,f;t==document&&(t=document.documentElement),l.__&&l.__(u,t),r=(o=\"function\"==typeof i)?null:i&&i.__k||t.__k,e=[],f=[],O(t,u=(!o&&i||t).__k=_(k,null,[u]),r||p,p,t.namespaceURI,!o&&i?[i]:r?null:t.firstChild?n.call(t.childNodes):null,e,!o&&i?i:r?r.__e:t.firstChild,o,f),N(e,u,f)}function J(n,l){G(n,l,J)}function K(l,u,t){var i,o,r,e,f=w({},l.props);for(r in l.type&&l.type.defaultProps&&(e=l.type.defaultProps),u)\"key\"==r?i=u[r]:\"ref\"==r?o=u[r]:f[r]=void 0===u[r]&&null!=e?e[r]:u[r];return arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),m(l.type,f,i||l.key,o||l.ref,null)}function Q(n){function l(n){var u,t;return this.getChildContext||(u=new Set,(t={})[l.__c]=this,this.getChildContext=function(){return t},this.componentWillUnmount=function(){u=null},this.shouldComponentUpdate=function(n){this.props.value!=n.value&&u.forEach(function(n){n.__e=!0,M(n)})},this.sub=function(n){u.add(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u&&u.delete(n),l&&l.call(n)}}),n.children}return l.__c=\"__cC\"+h++,l.__=n,l.Provider=l.__l=(l.Consumer=function(n,l){return n.children(l)}).contextType=l,l}n=v.slice,l={__e:function(n,l,u,t){for(var i,o,r;l=l.__;)if((i=l.__c)&&!i.__)try{if((o=i.constructor)&&null!=o.getDerivedStateFromError&&(i.setState(o.getDerivedStateFromError(n)),r=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),r=i.__d),r)return i.__E=i}catch(l){n=l}throw n}},u=0,t=function(n){return null!=n&&void 0===n.constructor},x.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!=this.state?this.__s:this.__s=w({},this.state),\"function\"==typeof n&&(n=n(w({},u),this.props)),n&&w(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),M(this))},x.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),M(this))},x.prototype.render=k,i=[],r=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,e=function(n,l){return n.__v.__b-l.__v.__b},$.__r=0,f=/(PointerCapture)$|Capture$/i,c=0,s=F(!1),a=F(!0),h=0;export{x as Component,k as Fragment,K as cloneElement,Q as createContext,_ as createElement,b as createRef,_ as h,J as hydrate,t as isValidElement,l as options,G as render,H as toChildArray};\n//# sourceMappingURL=preact.module.js.map\n","import { knownUnsafeEditableEvent } from \"../types.mjs\";\nimport { includes } from \"./string-utils.mjs\";\nconst nativeIsArray = Array.isArray;\nconst ObjProto = Object.prototype;\nconst type_utils_hasOwnProperty = ObjProto.hasOwnProperty;\nconst type_utils_toString = ObjProto.toString;\nconst isArray = nativeIsArray || function(obj) {\n return '[object Array]' === type_utils_toString.call(obj);\n};\nconst isFunction = (x)=>'function' == typeof x;\nconst isNativeFunction = (x)=>isFunction(x) && -1 !== x.toString().indexOf('[native code]');\nconst isObject = (x)=>x === Object(x) && !isArray(x);\nconst isEmptyObject = (x)=>{\n if (isObject(x)) {\n for(const key in x)if (type_utils_hasOwnProperty.call(x, key)) return false;\n return true;\n }\n return false;\n};\nconst isUndefined = (x)=>void 0 === x;\nconst isString = (x)=>'[object String]' == type_utils_toString.call(x);\nconst isEmptyString = (x)=>isString(x) && 0 === x.trim().length;\nconst isNull = (x)=>null === x;\nconst isNullish = (x)=>isUndefined(x) || isNull(x);\nconst isNumber = (x)=>'[object Number]' == type_utils_toString.call(x) && x === x;\nconst isPositiveNumber = (value)=>isNumber(value) && value > 0;\nconst isBoolean = (x)=>'[object Boolean]' === type_utils_toString.call(x);\nconst isFormData = (x)=>x instanceof FormData;\nconst isFile = (x)=>x instanceof File;\nconst isPlainError = (x)=>x instanceof Error;\nconst isKnownUnsafeEditableEvent = (x)=>includes(knownUnsafeEditableEvent, x);\nfunction isPrimitive(value) {\n return null === value || 'object' != typeof value;\n}\nfunction isBuiltin(candidate, className) {\n return Object.prototype.toString.call(candidate) === `[object ${className}]`;\n}\nfunction isError(candidate) {\n switch(Object.prototype.toString.call(candidate)){\n case '[object Error]':\n case '[object Exception]':\n case '[object DOMException]':\n case '[object DOMError]':\n case '[object WebAssembly.Exception]':\n return true;\n default:\n return isInstanceOf(candidate, Error);\n }\n}\nfunction isErrorEvent(event) {\n return isBuiltin(event, 'ErrorEvent');\n}\nfunction isEvent(candidate) {\n return 'undefined' != typeof Event && isInstanceOf(candidate, Event);\n}\nfunction isPlainObject(candidate) {\n return isBuiltin(candidate, 'Object');\n}\nfunction isInstanceOf(candidate, base) {\n try {\n return candidate instanceof base;\n } catch {\n return false;\n }\n}\nconst yesLikeValues = [\n true,\n 'true',\n 1,\n '1',\n 'yes'\n];\nconst isYesLike = (val)=>includes(yesLikeValues, val);\nconst noLikeValues = [\n false,\n 'false',\n 0,\n '0',\n 'no'\n];\nconst isNoLike = (val)=>includes(noLikeValues, val);\nexport { type_utils_hasOwnProperty as hasOwnProperty, isArray, isBoolean, isBuiltin, isEmptyObject, isEmptyString, isError, isErrorEvent, isEvent, isFile, isFormData, isFunction, isKnownUnsafeEditableEvent, isNativeFunction, isNoLike, isNull, isNullish, isNumber, isObject, isPlainError, isPlainObject, isPositiveNumber, isPrimitive, isString, isUndefined, isYesLike, noLikeValues, yesLikeValues };\n","/*\n * Constants\n */\n\n/* PROPERTY KEYS */\n\n// This key is deprecated, but we want to check for it to see whether aliasing is allowed.\nexport const PEOPLE_DISTINCT_ID_KEY = '$people_distinct_id'\nexport const DISTINCT_ID = 'distinct_id'\nexport const DEVICE_ID = '$device_id'\nexport const ALIAS_ID_KEY = '__alias'\nexport const CAMPAIGN_IDS_KEY = '__cmpns'\nexport const EVENT_TIMERS_KEY = '__timers'\nexport const AUTOCAPTURE_DISABLED_SERVER_SIDE = '$autocapture_disabled_server_side'\nexport const HEATMAPS_ENABLED_SERVER_SIDE = '$heatmaps_enabled_server_side'\nexport const EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE = '$exception_capture_enabled_server_side'\nexport const ERROR_TRACKING_SUPPRESSION_RULES = '$error_tracking_suppression_rules'\nexport const ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS = '$error_tracking_capture_extension_exceptions'\nexport const WEB_VITALS_ENABLED_SERVER_SIDE = '$web_vitals_enabled_server_side'\nexport const DEAD_CLICKS_ENABLED_SERVER_SIDE = '$dead_clicks_enabled_server_side'\nexport const PRODUCT_TOURS_ENABLED_SERVER_SIDE = '$product_tours_enabled_server_side'\nexport const WEB_VITALS_ALLOWED_METRICS = '$web_vitals_allowed_metrics'\nexport const SESSION_RECORDING_REMOTE_CONFIG = '$session_recording_remote_config'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_ENABLED_SERVER_SIDE = '$session_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const CONSOLE_LOG_RECORDING_ENABLED_SERVER_SIDE = '$console_log_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_NETWORK_PAYLOAD_CAPTURE = '$session_recording_network_payload_capture'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MASKING = '$session_recording_masking'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_CANVAS_RECORDING = '$session_recording_canvas_recording'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SAMPLE_RATE = '$replay_sample_rate'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MINIMUM_DURATION = '$replay_minimum_duration'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SCRIPT_CONFIG = '$replay_script_config'\nexport const SESSION_RECORDING_OVERRIDE_SAMPLING = '$replay_override_sampling'\nexport const SESSION_RECORDING_OVERRIDE_LINKED_FLAG = '$replay_override_linked_flag'\nexport const SESSION_RECORDING_OVERRIDE_URL_TRIGGER = '$replay_override_url_trigger'\nexport const SESSION_RECORDING_OVERRIDE_EVENT_TRIGGER = '$replay_override_event_trigger'\nexport const SESSION_ID = '$sesid'\nexport const SESSION_RECORDING_IS_SAMPLED = '$session_is_sampled'\nexport const SESSION_RECORDING_PAST_MINIMUM_DURATION = '$session_past_minimum_duration'\nexport const SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION = '$session_recording_url_trigger_activated_session'\nexport const SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION = '$session_recording_event_trigger_activated_session'\n// V2 Trigger Groups: Per-group persistence key prefixes (suffix with group ID)\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_EVENT_PREFIX = '$posthog_sr_group_event_trigger_'\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_URL_PREFIX = '$posthog_sr_group_url_trigger_'\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_SAMPLING_PREFIX = '$posthog_sr_group_sampling_'\nexport const SESSION_RECORDING_FIRST_FULL_SNAPSHOT_TIMESTAMP = '$debug_first_full_snapshot_timestamp'\nexport const ENABLED_FEATURE_FLAGS = '$enabled_feature_flags'\nexport const PERSISTENCE_ACTIVE_FEATURE_FLAGS = '$active_feature_flags'\nexport const PERSISTENCE_EARLY_ACCESS_FEATURES = '$early_access_features'\nexport const PERSISTENCE_FEATURE_FLAG_DETAILS = '$feature_flag_details'\nexport const PERSISTENCE_FEATURE_FLAG_PAYLOADS = '$feature_flag_payloads'\nexport const PERSISTENCE_FEATURE_FLAG_REQUEST_ID = '$feature_flag_request_id'\nexport const PERSISTENCE_OVERRIDE_FEATURE_FLAGS = '$override_feature_flags'\nexport const PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS = '$override_feature_flag_payloads'\nexport const STORED_PERSON_PROPERTIES_KEY = '$stored_person_properties'\nexport const STORED_GROUP_PROPERTIES_KEY = '$stored_group_properties'\nexport const SURVEYS = '$surveys'\nexport const SURVEYS_ACTIVATED = '$surveys_activated'\nexport const PRODUCT_TOURS = 'ph_product_tours'\nexport const PRODUCT_TOURS_ACTIVATED = '$product_tours_activated'\nexport const CONVERSATIONS = '$conversations'\nexport const CONVERSATIONS_LEGACY_WIDGET_SESSION_ID = '$conversations_widget_session_id'\nexport const CONVERSATIONS_LEGACY_TICKET_ID = '$conversations_ticket_id'\nexport const CONVERSATIONS_LEGACY_WIDGET_STATE = '$conversations_widget_state'\nexport const CONVERSATIONS_LEGACY_USER_TRAITS = '$conversations_user_traits'\nexport const FLAG_CALL_REPORTED = '$flag_call_reported'\nexport const FLAG_CALL_REPORTED_SESSION_ID = '$flag_call_reported_session_id'\nexport const PERSISTENCE_FEATURE_FLAG_ERRORS = '$feature_flag_errors'\nexport const PERSISTENCE_FEATURE_FLAG_EVALUATED_AT = '$feature_flag_evaluated_at'\nexport const USER_STATE = '$user_state'\nexport const CLIENT_SESSION_PROPS = '$client_session_props'\nexport const CAPTURE_RATE_LIMIT = '$capture_rate_limit'\n\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_CAMPAIGN_PARAMS = '$initial_campaign_params'\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_REFERRER_INFO = '$initial_referrer_info'\nexport const INITIAL_PERSON_INFO = '$initial_person_info'\nexport const ENABLE_PERSON_PROCESSING = '$epp'\nexport const TOOLBAR_ID = '__POSTHOG_TOOLBAR__'\nexport const TOOLBAR_CONTAINER_CLASS = 'toolbar-global-fade-container'\n\n/**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * Sentinel value for distinct id, device id, session id. Signals that the server should generate the value\n * */\nexport const COOKIELESS_SENTINEL_VALUE = '$posthog_cookieless'\nexport const COOKIELESS_MODE_FLAG_PROPERTY = '$cookieless_mode'\n\nexport const WEB_EXPERIMENTS = '$web_experiments'\n\nexport const SDK_DEBUG_EXTENSIONS_INIT_METHOD = '$sdk_debug_extensions_init_method'\nexport const SDK_DEBUG_EXTENSIONS_INIT_TIME_MS = '$sdk_debug_extensions_init_time_ms'\nexport const SDK_DEBUG_RECORDING_SCRIPT_NOT_LOADED = '$sdk_debug_recording_script_not_loaded'\nexport const SDK_DEBUG_REPLAY_EVENT_TRIGGER_STATUS = '$sdk_debug_replay_event_trigger_status'\nexport const SDK_DEBUG_REPLAY_LINKED_FLAG_TRIGGER_STATUS = '$sdk_debug_replay_linked_flag_trigger_status'\nexport const SDK_DEBUG_REPLAY_MATCHED_RECORDING_TRIGGER_GROUPS = '$sdk_debug_replay_matched_recording_trigger_groups'\nexport const SDK_DEBUG_REPLAY_REMOTE_TRIGGER_MATCHING_CONFIG = '$sdk_debug_replay_remote_trigger_matching_config'\nexport const SDK_DEBUG_REPLAY_TRIGGER_GROUPS_COUNT = '$sdk_debug_replay_trigger_groups_count'\nexport const SDK_DEBUG_REPLAY_URL_TRIGGER_STATUS = '$sdk_debug_replay_url_trigger_status'\nexport const SESSION_RECORDING_START_REASON = '$session_recording_start_reason'\n\nexport const SURVEYS_REQUEST_TIMEOUT_MS = 10000\nexport const LOAD_EXT_NOT_FOUND = 'PostHog loadExternalDependency extension not found.'\n\n/* EVENT NAMES - interned to reduce bundle size */\n/* COOKIELESS MODE VALUES */\nexport const COOKIELESS_ON_REJECT = 'on_reject' as const\nexport const COOKIELESS_ALWAYS = 'always' as const\n\n/* USER STATE VALUES */\nexport const USER_STATE_ANONYMOUS = 'anonymous'\nexport const USER_STATE_IDENTIFIED = 'identified'\n\n/* PERSON PROFILE MODES */\nexport const PERSON_PROFILES_IDENTIFIED_ONLY = 'identified_only' as const\n\n/* DOM EVENT NAMES - interned to reduce bundle size */\nexport const DOM_EVENT_VISIBILITYCHANGE = 'visibilitychange'\nexport const DOM_EVENT_BEFOREUNLOAD = 'beforeunload'\n\nexport const EVENT_PAGEVIEW = '$pageview'\nexport const EVENT_PAGELEAVE = '$pageleave'\nexport const EVENT_IDENTIFY = '$identify'\nexport const EVENT_GROUPIDENTIFY = '$groupidentify'\n\n/* Z-INDEX HIERARCHY: tours > surveys > support */\nexport const Z_INDEX_TOURS = 2147483646\nexport const Z_INDEX_SURVEYS = 2147483645\nexport const Z_INDEX_CONVERSATIONS = 2147483644\n","import type { PostHog } from '../posthog-core'\nimport { SessionIdManager } from '../sessionid'\nimport {\n DeadClicksAutoCaptureConfig,\n ExternalIntegrationKind,\n Properties,\n RemoteConfig,\n SiteAppLoader,\n SessionStartReason,\n} from '../types'\nimport type {\n ConversationsRemoteConfig,\n GetMessagesResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n MarkAsReadResponse,\n RestoreFromTokenResponse,\n RequestRestoreLinkResponse,\n SendMessageResponse,\n UserProvidedTraits,\n} from '../posthog-conversations-types'\n// only importing types here, so won't affect the bundle\n// eslint-disable-next-line posthog-js/no-external-replay-imports\nimport type { SessionRecordingStatus, TriggerType } from '../extensions/replay/external/triggerMatching'\nimport { eventWithTime } from '../extensions/replay/types/rrweb-types'\nimport { ErrorTracking } from '@posthog/core'\n\n/*\n * Global helpers to protect access to browser globals in a way that is safer for different targets\n * like DOM, SSR, Web workers etc.\n *\n * NOTE: Typically we want the \"window\" but globalThis works for both the typical browser context as\n * well as other contexts such as the web worker context. Window is still exported for any bits that explicitly require it.\n * If in doubt - export the global you need from this file and use that as an optional value. This way the code path is forced\n * to handle the case where the global is not available.\n */\n\n// eslint-disable-next-line no-restricted-globals\nconst win: (Window & typeof globalThis) | undefined = typeof window !== 'undefined' ? window : undefined\n\nexport type AssignableWindow = Window &\n typeof globalThis & {\n /*\n * Main PostHog instance\n */\n posthog: any\n\n /*\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n */\n __PosthogExtensions__?: PostHogExtensions\n\n /**\n * When loading remote config, we assign it to this global configuration\n * for ease of sharing it with the rest of the SDK\n */\n _POSTHOG_REMOTE_CONFIG?: Record<\n string,\n {\n config: RemoteConfig\n siteApps: SiteAppLoader[]\n }\n >\n\n /**\n * If this is set on the window, our logger will log to the console\n * for ease of debugging. Used for testing purposes only.\n *\n * @see {Config.DEBUG} from config.ts\n */\n POSTHOG_DEBUG: any\n\n // Exposed by the browser\n doNotTrack: any\n\n // See entrypoints/customizations.full.ts\n posthogCustomizations: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/exception-autocapture.ts\n *\n * @deprecated use `__PosthogExtensions__.errorWrappingFunctions` instead\n */\n posthogErrorWrappingFunctions: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrweb` instead\n */\n rrweb: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrwebConsoleRecord` instead\n */\n rrwebConsoleRecord: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.getRecordNetworkPlugin` instead\n */\n getRecordNetworkPlugin: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/web-vitals.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogWebVitalsCallbacks` instead\n */\n postHogWebVitalsCallbacks: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/tracing-headers.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogTracingHeadersPatchFns` instead\n */\n postHogTracingHeadersPatchFns: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/surveys.ts\n *\n * @deprecated use `__PosthogExtensions__.generateSurveys` instead\n */\n extendPostHogWithSurveys: any\n\n /*\n * These are used to handle our toolbar state.\n * @see {Toolbar} from extensions/toolbar.ts\n */\n ph_load_toolbar: any\n ph_load_editor: any\n ph_toolbar_state: any\n } & Record<`__$$ph_site_app_${string}`, any>\n\n/**\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n * changes to this interface can be breaking changes for users of the SDK\n */\n\nexport type ExternalExtensionKind = 'intercom-integration' | 'crisp-chat-integration'\n\nexport type PostHogExtensionKind =\n | 'toolbar'\n | 'exception-autocapture'\n | 'web-vitals'\n | 'web-vitals-with-attribution'\n | 'recorder'\n | 'lazy-recorder'\n | 'tracing-headers'\n | 'surveys'\n | 'logs'\n | 'conversations'\n | 'product-tours'\n | 'dead-clicks-autocapture'\n | 'remote-config'\n | ExternalExtensionKind\n\nexport interface LazyLoadedSessionRecordingInterface {\n start: (startReason?: SessionStartReason) => void\n stop: () => void\n discard: () => void\n sessionId: string\n status: SessionRecordingStatus\n onRRwebEmit: (rawEvent: eventWithTime) => void\n log: (message: string, level: 'log' | 'warn' | 'error') => void\n sdkDebugProperties: Properties\n overrideLinkedFlag: () => void\n overrideSampling: () => void\n overrideTrigger: (triggerType: TriggerType) => void\n isStarted: boolean\n tryAddCustomEvent(tag: string, payload: any): boolean\n}\n\nexport interface LazyLoadedDeadClicksAutocaptureInterface {\n start: (observerTarget: Node) => void\n stop: () => void\n}\n\nexport interface LazyLoadedConversationsInterface {\n // Widget control\n show: () => void\n hide: () => void\n isVisible: () => boolean\n\n // Lifecycle\n reset: () => void\n\n // Identity verification\n setIdentity: () => void\n clearIdentity: () => void\n\n // API methods\n sendMessage: (message: string, userTraits?: UserProvidedTraits, newTicket?: boolean) => Promise<SendMessageResponse>\n getMessages: (ticketId?: string, after?: string) => Promise<GetMessagesResponse>\n markAsRead: (ticketId?: string) => Promise<MarkAsReadResponse>\n getTickets: (options?: GetTicketsOptions) => Promise<GetTicketsResponse>\n requestRestoreLink: (email: string) => Promise<RequestRestoreLinkResponse>\n restoreFromToken: (restoreToken: string) => Promise<RestoreFromTokenResponse>\n restoreFromUrlToken: () => Promise<RestoreFromTokenResponse | null>\n getCurrentTicketId: () => string | null\n getWidgetSessionId: () => string\n}\n\ninterface PostHogExtensions {\n loadExternalDependency?: (\n posthog: PostHog,\n kind: PostHogExtensionKind,\n callback: (error?: string | Event, event?: Event) => void\n ) => void\n\n loadSiteApp?: (posthog: PostHog, appUrl: string, callback: (error?: string | Event, event?: Event) => void) => void\n\n errorWrappingFunctions?: {\n wrapOnError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapUnhandledRejection: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapConsoleError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n }\n rrweb?: { record: any; version: string; wasMaxDepthReached?: () => boolean; resetMaxDepthState?: () => void }\n rrwebPlugins?: { getRecordConsolePlugin: any; getRecordNetworkPlugin?: any }\n generateSurveys?: (posthog: PostHog, isSurveysEnabled: boolean) => any | undefined\n generateProductTours?: (posthog: PostHog, isEnabled: boolean) => any | undefined\n logs?: {\n initializeLogs?: (posthog: PostHog) => any | undefined\n }\n postHogWebVitalsCallbacks?: {\n onLCP: (metric: any) => void\n onCLS: (metric: any) => void\n onFCP: (metric: any) => void\n onINP: (metric: any) => void\n }\n /**\n * @deprecated\n *\n * this was introduced briefly, it is now always a no-op and only kept for backwards compatibility\n */\n loadWebVitalsCallbacks?: (useAttribution?: boolean) => PostHogExtensions['postHogWebVitalsCallbacks']\n tracingHeadersPatchFns?: {\n _patchFetch: (hostnames: string[], distinctId: string, sessionManager?: SessionIdManager) => () => void\n _patchXHR: (hostnames: string[], distinctId: string, sessionManager?: SessionIdManager) => () => void\n }\n initDeadClicksAutocapture?: (\n ph: PostHog,\n config: DeadClicksAutoCaptureConfig\n ) => LazyLoadedDeadClicksAutocaptureInterface\n integrations?: {\n [K in ExternalIntegrationKind]?: { start: (posthog: PostHog) => void; stop: () => void }\n }\n initSessionRecording?: (ph: PostHog) => LazyLoadedSessionRecordingInterface\n initConversations?: (config: ConversationsRemoteConfig, posthog: PostHog) => LazyLoadedConversationsInterface\n}\n\nconst global: typeof globalThis | undefined = typeof globalThis !== 'undefined' ? globalThis : win\n\n// React Native polyfills for posthog-js compatibility\nif (typeof self === 'undefined') {\n ;(global as any).self = global\n}\nif (typeof File === 'undefined') {\n ;(global as any).File = function () {}\n}\n\nexport const navigator = global?.navigator\nexport const document = global?.document\nexport const location = global?.location\nexport const fetch = global?.fetch\nexport const XMLHttpRequest =\n global?.XMLHttpRequest && 'withCredentials' in new global.XMLHttpRequest() ? global.XMLHttpRequest : undefined\nexport const AbortController = global?.AbortController\nexport const CompressionStream = global?.CompressionStream\nexport const userAgent = navigator?.userAgent\nexport const assignableWindow: AssignableWindow = win ?? ({} as any)\n\nexport { win as window }\n","import Config from '../config'\nimport { isUndefined } from '@posthog/core'\nimport { assignableWindow, window } from './globals'\nimport type { Logger } from '@posthog/core'\n\ntype CreateLoggerOptions = {\n debugEnabled?: boolean\n}\n\ntype PosthogJsLogger = Omit<Logger, 'createLogger'> & {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => void\n uninitializedWarning: (methodName: string) => void\n createLogger: (prefix: string, options?: CreateLoggerOptions) => PosthogJsLogger\n}\n\nconst _createLogger = (prefix: string, { debugEnabled }: CreateLoggerOptions = {}): PosthogJsLogger => {\n const logger: PosthogJsLogger = {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => {\n if (\n window &&\n (Config.DEBUG || assignableWindow.POSTHOG_DEBUG || debugEnabled) &&\n !isUndefined(window.console) &&\n window.console\n ) {\n const consoleLog =\n '__rrweb_original__' in window.console[level]\n ? (window.console[level] as any)['__rrweb_original__']\n : window.console[level]\n\n // eslint-disable-next-line no-console\n consoleLog(prefix, ...args)\n }\n },\n\n info: (...args: any[]) => {\n logger._log('log', ...args)\n },\n\n warn: (...args: any[]) => {\n logger._log('warn', ...args)\n },\n\n error: (...args: any[]) => {\n logger._log('error', ...args)\n },\n\n critical: (...args: any[]) => {\n // Critical errors are always logged to the console\n // eslint-disable-next-line no-console\n console.error(prefix, ...args)\n },\n\n uninitializedWarning: (methodName: string) => {\n logger.error(`You must initialize PostHog before calling ${methodName}`)\n },\n\n createLogger: (additionalPrefix: string, options?: CreateLoggerOptions) =>\n _createLogger(`${prefix} ${additionalPrefix}`, options),\n }\n return logger\n}\n\nexport const logger = _createLogger('[PostHog.js]')\n\nexport const createLogger = logger.createLogger\n","/**\n * uuidv7: An experimental implementation of the proposed UUID Version 7\n *\n * @license Apache-2.0\n * @copyright 2021-2023 LiosK\n * @packageDocumentation\n *\n * from https://github.com/LiosK/uuidv7/blob/e501462ea3d23241de13192ceae726956f9b3b7d/src/index.ts\n */\n\n// polyfill for IE11\nimport { window } from './utils/globals'\n\nimport { isNumber, isUndefined } from '@posthog/core'\n\nif (!Math.trunc) {\n Math.trunc = function (v) {\n return v < 0 ? Math.ceil(v) : Math.floor(v)\n }\n}\n\n// polyfill for IE11\nif (!Number.isInteger) {\n Number.isInteger = function (value) {\n return isNumber(value) && isFinite(value) && Math.floor(value) === value\n }\n}\n\n/** Represents a UUID as a 16-byte byte array. */\nexport class UUID {\n /** @param bytes - The 16-byte byte array representation. */\n constructor(readonly bytes: Readonly<Uint8Array>) {\n if (bytes.length !== 16) {\n throw new TypeError('not 128-bit length')\n }\n }\n\n /**\n * Builds a byte array from UUIDv7 field values.\n *\n * @param unixTsMs - A 48-bit `unix_ts_ms` field value.\n * @param randA - A 12-bit `rand_a` field value.\n * @param randBHi - The higher 30 bits of 62-bit `rand_b` field value.\n * @param randBLo - The lower 32 bits of 62-bit `rand_b` field value.\n */\n static fromFieldsV7(unixTsMs: number, randA: number, randBHi: number, randBLo: number): UUID {\n if (\n !Number.isInteger(unixTsMs) ||\n !Number.isInteger(randA) ||\n !Number.isInteger(randBHi) ||\n !Number.isInteger(randBLo) ||\n unixTsMs < 0 ||\n randA < 0 ||\n randBHi < 0 ||\n randBLo < 0 ||\n unixTsMs > 0xffff_ffff_ffff ||\n randA > 0xfff ||\n randBHi > 0x3fff_ffff ||\n randBLo > 0xffff_ffff\n ) {\n throw new RangeError('invalid field value')\n }\n\n const bytes = new Uint8Array(16)\n bytes[0] = unixTsMs / 2 ** 40\n bytes[1] = unixTsMs / 2 ** 32\n bytes[2] = unixTsMs / 2 ** 24\n bytes[3] = unixTsMs / 2 ** 16\n bytes[4] = unixTsMs / 2 ** 8\n bytes[5] = unixTsMs\n bytes[6] = 0x70 | (randA >>> 8)\n bytes[7] = randA\n bytes[8] = 0x80 | (randBHi >>> 24)\n bytes[9] = randBHi >>> 16\n bytes[10] = randBHi >>> 8\n bytes[11] = randBHi\n bytes[12] = randBLo >>> 24\n bytes[13] = randBLo >>> 16\n bytes[14] = randBLo >>> 8\n bytes[15] = randBLo\n return new UUID(bytes)\n }\n\n /** @returns The 8-4-4-4-12 canonical hexadecimal string representation. */\n toString(): string {\n let text = ''\n for (let i = 0; i < this.bytes.length; i++) {\n text = text + (this.bytes[i] >>> 4).toString(16) + (this.bytes[i] & 0xf).toString(16)\n if (i === 3 || i === 5 || i === 7 || i === 9) {\n text += '-'\n }\n }\n\n if (text.length !== 36) {\n // We saw one customer whose bundling code was mangling the UUID generation\n // rather than accept a bad UUID, we throw an error here.\n throw new Error('Invalid UUIDv7 was generated')\n }\n return text\n }\n\n /** Creates an object from `this`. */\n clone(): UUID {\n return new UUID(this.bytes.slice(0))\n }\n\n /** Returns true if `this` is equivalent to `other`. */\n equals(other: UUID): boolean {\n return this.compareTo(other) === 0\n }\n\n /**\n * Returns a negative integer, zero, or positive integer if `this` is less\n * than, equal to, or greater than `other`, respectively.\n */\n compareTo(other: UUID): number {\n for (let i = 0; i < 16; i++) {\n const diff = this.bytes[i] - other.bytes[i]\n if (diff !== 0) {\n return Math.sign(diff)\n }\n }\n return 0\n }\n}\n\n/** Encapsulates the monotonic counter state. */\nclass V7Generator {\n private _timestamp = 0\n private _counter = 0\n private readonly _random = new DefaultRandom()\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or resets the\n * generator upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method resets the generator and returns a new\n * UUID based on the current timestamp.\n */\n generate(): UUID {\n const value = this.generateOrAbort()\n if (!isUndefined(value)) {\n return value\n } else {\n // reset state and resume\n this._timestamp = 0\n const valueAfterReset = this.generateOrAbort()\n if (isUndefined(valueAfterReset)) {\n throw new Error('Could not generate UUID after timestamp reset')\n }\n return valueAfterReset\n }\n }\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or returns\n * `undefined` upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method aborts and returns `undefined`.\n */\n generateOrAbort(): UUID | undefined {\n const MAX_COUNTER = 0x3ff_ffff_ffff\n const ROLLBACK_ALLOWANCE = 10_000 // 10 seconds\n\n const ts = Date.now()\n if (ts > this._timestamp) {\n this._timestamp = ts\n this._resetCounter()\n } else if (ts + ROLLBACK_ALLOWANCE > this._timestamp) {\n // go on with previous timestamp if new one is not much smaller\n this._counter++\n if (this._counter > MAX_COUNTER) {\n // increment timestamp at counter overflow\n this._timestamp++\n this._resetCounter()\n }\n } else {\n // abort if clock went backwards to unbearable extent\n return undefined\n }\n\n return UUID.fromFieldsV7(\n this._timestamp,\n Math.trunc(this._counter / 2 ** 30),\n this._counter & (2 ** 30 - 1),\n this._random.nextUint32()\n )\n }\n\n /** Initializes the counter at a 42-bit random integer. */\n private _resetCounter(): void {\n this._counter = this._random.nextUint32() * 0x400 + (this._random.nextUint32() & 0x3ff)\n }\n}\n\n/** A global flag to force use of cryptographically strong RNG. */\ndeclare const UUIDV7_DENY_WEAK_RNG: boolean\n\n/** Stores `crypto.getRandomValues()` available in the environment. */\nlet getRandomValues: <T extends Uint8Array | Uint32Array>(buffer: T) => T = (buffer) => {\n // fall back on Math.random() unless the flag is set to true\n // TRICKY: don't use the isUndefined method here as can't pass the reference\n if (typeof UUIDV7_DENY_WEAK_RNG !== 'undefined' && UUIDV7_DENY_WEAK_RNG) {\n throw new Error('no cryptographically strong RNG available')\n }\n\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] = Math.trunc(Math.random() * 0x1_0000) * 0x1_0000 + Math.trunc(Math.random() * 0x1_0000)\n }\n return buffer\n}\n\n// detect Web Crypto API\nif (window && !isUndefined(window.crypto) && crypto.getRandomValues) {\n getRandomValues = (buffer) => crypto.getRandomValues(buffer)\n}\n\n/**\n * Wraps `crypto.getRandomValues()` and compatibles to enable buffering; this\n * uses a small buffer by default to avoid unbearable throughput decline in some\n * environments as well as the waste of time and space for unused values.\n */\nclass DefaultRandom {\n private readonly _buffer = new Uint32Array(8)\n private _cursor = Infinity\n nextUint32(): number {\n if (this._cursor >= this._buffer.length) {\n getRandomValues(this._buffer)\n this._cursor = 0\n }\n return this._buffer[this._cursor++]\n }\n}\n\nlet defaultGenerator: V7Generator | undefined\n\n/**\n * Generates a UUIDv7 string.\n *\n * @returns The 8-4-4-4-12 canonical hexadecimal string representation\n * (\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\").\n */\nexport const uuidv7 = (): string => uuidv7obj().toString()\n\n/** Generates a UUIDv7 object. */\nconst uuidv7obj = (): UUID => (defaultGenerator || (defaultGenerator = new V7Generator())).generate()\n\nexport const uuid7ToTimestampMs = (uuid: string): number => {\n // remove hyphens\n const hex = uuid.replace(/-/g, '')\n // ensure that it's a version 7 UUID\n if (hex.length !== 32) {\n throw new Error('Not a valid UUID')\n }\n if (hex[12] !== '7') {\n throw new Error('Not a UUIDv7')\n }\n // the first 6 bytes are the timestamp, which means that we can read only the first 12 hex characters\n return parseInt(hex.substring(0, 12), 16)\n}\n","import {\n CONVERSATIONS_LEGACY_TICKET_ID,\n CONVERSATIONS_LEGACY_USER_TRAITS,\n CONVERSATIONS_LEGACY_WIDGET_SESSION_ID,\n CONVERSATIONS_LEGACY_WIDGET_STATE,\n} from '../../../constants'\nimport { PostHog } from '../../../posthog-core'\nimport { UserProvidedTraits } from '../../../posthog-conversations-types'\nimport { createLogger } from '../../../utils/logger'\nimport { window } from '../../../utils/globals'\nimport { uuidv7 } from '../../../uuidv7'\n\nconst logger = createLogger('[ConversationsPersistence]')\n\ninterface ConversationsStorageData {\n widgetSessionId?: string\n ticketId?: string | null\n widgetState?: 'open' | 'closed'\n userTraits?: UserProvidedTraits | null\n}\n\n/**\n * Dedicated localStorage key scoped to the PostHog project token.\n * Format: `ph_conv_<token>`\n */\nfunction storageKey(posthog: PostHog): string | null {\n const token = posthog.config?.token\n return token ? 'ph_conv_' + token : null\n}\n\n/**\n * ConversationsPersistence manages conversation data in its own dedicated\n * localStorage entry, independent of PostHog's core persistence layer.\n *\n * This avoids a known issue where PostHog's persistence.props can lose data\n * when the cookie+localStorage merge in _parse() fails on large entries.\n *\n * Pattern follows toolbar and surveys extensions which also use dedicated\n * localStorage keys.\n */\nexport class ConversationsPersistence {\n private _cachedWidgetSessionId: string | null = null\n private _storageKey: string | null\n\n constructor(private readonly _posthog: PostHog) {\n this._storageKey = storageKey(_posthog)\n this._migrateFromLegacyPersistence()\n }\n\n /**\n * Get or create the widget session ID (random UUID for access control).\n * This ID is generated once per browser and persists across sessions.\n * It is NOT tied to distinct_id - it stays the same even when user identifies.\n *\n * SECURITY: This is the key for access control. Only the browser that created\n * the widget_session_id can access tickets associated with it.\n */\n getOrCreateWidgetSessionId(): string {\n if (this._cachedWidgetSessionId) {\n return this._cachedWidgetSessionId\n }\n\n let sessionId = this._read()?.widgetSessionId\n\n if (!sessionId) {\n sessionId = uuidv7()\n this._write({ widgetSessionId: sessionId })\n }\n\n this._cachedWidgetSessionId = sessionId\n return sessionId\n }\n\n /**\n * Overwrite the widget session ID (used by restore flow).\n */\n setWidgetSessionId(id: string): void {\n this._cachedWidgetSessionId = id\n const data = this._read() || {}\n this._write({ ...data, widgetSessionId: id })\n }\n\n /**\n * Clear the widget session ID (called on posthog.reset()).\n * This will create a new session and lose access to previous tickets.\n */\n clearWidgetSessionId(): void {\n this._cachedWidgetSessionId = null\n const data = this._read()\n if (data) {\n delete data.widgetSessionId\n this._write(data)\n }\n }\n\n saveTicketId(ticketId: string): void {\n const data = this._read() || {}\n this._write({ ...data, ticketId })\n }\n\n loadTicketId(): string | null {\n return this._read()?.ticketId || null\n }\n\n clearTicketId(): void {\n const data = this._read()\n if (data) {\n delete data.ticketId\n this._write(data)\n }\n }\n\n saveWidgetState(state: 'open' | 'closed'): void {\n const data = this._read() || {}\n this._write({ ...data, widgetState: state })\n }\n\n loadWidgetState(): 'open' | 'closed' | null {\n const state = this._read()?.widgetState\n return state === 'open' || state === 'closed' ? state : null\n }\n\n saveUserTraits(traits: UserProvidedTraits): void {\n const data = this._read() || {}\n this._write({ ...data, userTraits: traits })\n }\n\n loadUserTraits(): UserProvidedTraits | null {\n const traits = this._read()?.userTraits\n return traits && (traits.name || traits.email) ? traits : null\n }\n\n clearUserTraits(): void {\n const data = this._read()\n if (data) {\n delete data.userTraits\n this._write(data)\n }\n }\n\n clearAll(): void {\n this._cachedWidgetSessionId = null\n if (this._storageKey) {\n try {\n window?.localStorage?.removeItem(this._storageKey)\n } catch {\n logger.error('Failed to remove localStorage item')\n }\n }\n }\n\n private _read(): ConversationsStorageData | null {\n if (!this._storageKey) {\n return null\n }\n try {\n const raw = window?.localStorage?.getItem(this._storageKey)\n return raw ? (JSON.parse(raw) as ConversationsStorageData) : null\n } catch {\n return null\n }\n }\n\n private _write(data: ConversationsStorageData): void {\n if (!this._storageKey) {\n return\n }\n try {\n window?.localStorage?.setItem(this._storageKey, JSON.stringify(data))\n } catch (error) {\n logger.error('Failed to write to localStorage', error)\n }\n }\n\n /**\n * One-time migration: copy conversations data from PostHog's main\n * persistence blob into the dedicated localStorage key, then remove\n * the old keys from PostHog persistence so they stop bloating it.\n */\n private _migrateFromLegacyPersistence(): void {\n if (!this._storageKey || this._read()?.widgetSessionId) {\n return\n }\n\n try {\n const persistence = this._posthog.persistence\n if (!persistence || persistence.isDisabled?.()) {\n return\n }\n\n const widgetSessionId = persistence.get_property(CONVERSATIONS_LEGACY_WIDGET_SESSION_ID)\n if (!widgetSessionId) {\n // persistence.props may be empty (the bug) — try raw localStorage\n const legacyFromRaw = this._readLegacyFromRawStorage()\n if (legacyFromRaw) {\n this._write(legacyFromRaw)\n logger.info('Migrated conversations data from raw localStorage')\n }\n return\n }\n\n const data: ConversationsStorageData = { widgetSessionId }\n\n const ticketId = persistence.get_property(CONVERSATIONS_LEGACY_TICKET_ID)\n if (ticketId) {\n data.ticketId = ticketId\n }\n\n const widgetState = persistence.get_property(CONVERSATIONS_LEGACY_WIDGET_STATE)\n if (widgetState === 'open' || widgetState === 'closed') {\n data.widgetState = widgetState\n }\n\n const userTraits = persistence.get_property(CONVERSATIONS_LEGACY_USER_TRAITS) as\n | UserProvidedTraits\n | undefined\n if (userTraits) {\n data.userTraits = userTraits\n }\n\n this._write(data)\n\n persistence.unregister(CONVERSATIONS_LEGACY_WIDGET_SESSION_ID)\n persistence.unregister(CONVERSATIONS_LEGACY_TICKET_ID)\n persistence.unregister(CONVERSATIONS_LEGACY_WIDGET_STATE)\n persistence.unregister(CONVERSATIONS_LEGACY_USER_TRAITS)\n\n logger.info('Migrated conversations data to dedicated storage')\n } catch (error) {\n logger.error('Migration from legacy persistence failed', error)\n }\n }\n\n /**\n * Fallback for migration: read legacy keys directly from raw localStorage\n * when PostHog persistence.props didn't load them (the original bug).\n */\n private _readLegacyFromRawStorage(): ConversationsStorageData | null {\n try {\n const token = this._posthog.config?.token\n if (!token) {\n return null\n }\n const key = (this._posthog.config as any).persistence_name\n ? 'ph_' + (this._posthog.config as any).persistence_name\n : 'ph_' + token + '_posthog'\n\n const raw = window?.localStorage?.getItem(key)\n if (!raw) {\n return null\n }\n\n const parsed = JSON.parse(raw)\n const widgetSessionId = parsed?.[CONVERSATIONS_LEGACY_WIDGET_SESSION_ID]\n if (typeof widgetSessionId !== 'string' || !widgetSessionId) {\n return null\n }\n\n const data: ConversationsStorageData = { widgetSessionId }\n\n const ticketId = parsed?.[CONVERSATIONS_LEGACY_TICKET_ID]\n if (ticketId) {\n data.ticketId = ticketId\n }\n\n const widgetState = parsed?.[CONVERSATIONS_LEGACY_WIDGET_STATE]\n if (widgetState === 'open' || widgetState === 'closed') {\n data.widgetState = widgetState\n }\n\n const userTraits = parsed?.[CONVERSATIONS_LEGACY_USER_TRAITS]\n if (userTraits) {\n data.userTraits = userTraits\n }\n\n return data\n } catch {\n return null\n }\n }\n}\n","// Inline styles following PostHog design system\n\nimport type { WidgetPosition } from '../../../../posthog-conversations-types'\nimport { Z_INDEX_CONVERSATIONS } from '../../../../constants'\n\n/**\n * Calculate contrasting text color (black or white) based on background brightness\n * Uses HSP (Highly Sensitive Purity) brightness formula\n */\nfunction getContrastTextColor(hexColor: string): string {\n const hex = hexColor.replace(/^#/, '')\n const fullHex = hex.length === 3 ? hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] : hex\n\n const r = parseInt(fullHex.slice(0, 2), 16)\n const g = parseInt(fullHex.slice(2, 4), 16)\n const b = parseInt(fullHex.slice(4, 6), 16)\n\n // HSP brightness formula\n const hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b))\n return hsp > 127.5 ? '#020617' : 'white'\n}\n\nexport const getStyles = (primaryColor: string, position: WidgetPosition = 'bottom_right') => {\n const isLeft = position.includes('left')\n const isTop = position.includes('top')\n\n return {\n widget: {\n position: 'fixed' as const,\n ...(isTop ? { top: '20px' } : { bottom: '20px' }),\n ...(isLeft ? { left: '20px' } : { right: '20px' }),\n zIndex: Z_INDEX_CONVERSATIONS,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Inter\", \"Segoe UI\", \"Roboto\", Helvetica, Arial, sans-serif',\n },\n buttonContainer: {\n position: 'relative' as const,\n },\n button: {\n width: '50px',\n height: '50px',\n borderRadius: '50%',\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n border: 'none',\n cursor: 'pointer',\n filter: 'drop-shadow(rgba(9, 14, 21, 0.54) 0px 1px 6px) drop-shadow(rgba(9, 14, 21, 0.9) 0px 2px 32px)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'transform 0.2s ease-out',\n },\n unreadBadge: {\n position: 'absolute' as const,\n ...(isTop ? { bottom: '-4px' } : { top: '-4px' }),\n ...(isLeft ? { left: '-4px' } : { right: '-4px' }),\n minWidth: '20px',\n height: '20px',\n borderRadius: '10px',\n background: '#ef4444',\n color: 'white',\n fontSize: '11px',\n fontWeight: 600,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0 5px',\n boxShadow: '0 2px 4px rgba(0, 0, 0, 0.2)',\n border: '2px solid white',\n boxSizing: 'border-box' as const,\n },\n window: {\n position: 'absolute' as const,\n ...(isTop ? { top: 0 } : { bottom: 0 }),\n ...(isLeft ? { left: 0 } : { right: 0 }),\n background: 'white',\n borderRadius: '10px',\n boxShadow: '0 10px 25px -3px rgba(0,0,0,0.12), 0 4px 12px -2px rgba(0,0,0,0.10)',\n display: 'flex',\n flexDirection: 'column' as const,\n overflow: 'hidden',\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n //border: '1px solid #dcdcdc',\n border: 'none',\n },\n windowOpen: {\n width: '400px',\n maxWidth: 'calc(100vw - 40px)',\n height: '600px',\n maxHeight: 'calc(100vh - 100px)',\n },\n header: {\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n padding: '8px 12px',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexShrink: 0,\n },\n headerTitle: {\n fontWeight: 500,\n fontSize: '14px',\n },\n headerActions: {\n display: 'flex',\n gap: '4px',\n alignItems: 'center',\n },\n headerLinkButton: {\n background: 'transparent',\n border: 'none',\n color: getContrastTextColor(primaryColor),\n cursor: 'pointer',\n padding: '6px 8px',\n fontSize: '12px',\n borderRadius: '4px',\n opacity: 0.9,\n },\n headerButton: {\n background: 'transparent',\n border: 'none',\n color: getContrastTextColor(primaryColor),\n cursor: 'pointer',\n padding: '6px 8px',\n fontSize: '16px',\n lineHeight: 1,\n borderRadius: '4px',\n transition: 'background 0.2s ease-out',\n opacity: 0.9,\n },\n messages: {\n flex: 1,\n overflowY: 'auto' as const,\n padding: '14px',\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '8px',\n background: 'white',\n },\n message: {\n display: 'flex',\n flexDirection: 'column' as const,\n maxWidth: '85%',\n animation: 'fadeIn 0.2s ease-out',\n },\n messageCustomer: {\n alignSelf: 'flex-end',\n alignItems: 'flex-end',\n },\n messageAgent: {\n alignSelf: 'flex-start',\n alignItems: 'flex-start',\n },\n messageAuthor: {\n fontSize: '10px',\n color: '#939393',\n marginBottom: '4px',\n fontWeight: 500,\n },\n messageContent: {\n padding: '8px 12px',\n borderRadius: '8px',\n fontSize: '12px',\n lineHeight: 1.5,\n wordWrap: 'break-word' as const,\n whiteSpace: 'pre-wrap' as const,\n },\n messageContentCustomer: {\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n borderBottomRightRadius: '2px',\n },\n messageContentAgent: {\n background: 'white',\n color: '#020617',\n border: '1.5px solid #dcdcdc',\n borderBottomLeftRadius: '2px',\n },\n messageTime: {\n fontSize: '10px',\n color: '#939393',\n marginTop: '4px',\n opacity: 0.8,\n },\n error: {\n padding: '10px 16px',\n background: '#fee2e2',\n color: '#991b1b',\n fontSize: '13px',\n borderTop: '1px solid #fecaca',\n borderBottom: '1px solid #fecaca',\n textAlign: 'center' as const,\n fontWeight: 500,\n },\n inputContainer: {\n padding: '8px 12px',\n background: 'white',\n borderTop: '1px solid #dcdcdc',\n display: 'flex',\n gap: '8px',\n alignItems: 'center', // Changed from flex-end to center to vertically align input and sendButton\n flexShrink: 0,\n },\n resolvedBanner: {\n paddingTop: '12px',\n background: 'white',\n borderTop: '1px solid #dcdcdc',\n display: 'flex',\n flexDirection: 'column' as const,\n flexShrink: 0,\n },\n resolvedBannerText: {\n padding: '0 20px',\n fontSize: '13px',\n color: '#64748b',\n textAlign: 'center' as const,\n lineHeight: 1.5,\n },\n input: {\n flex: 1,\n maxHeight: '120px',\n fontSize: '14px',\n resize: 'vertical',\n fontFamily: 'inherit',\n lineHeight: 1.5,\n color: '#020617',\n background: 'white',\n border: 'none',\n outline: 'none',\n transition: 'border-color 0.2s ease-out, box-shadow 0.2s ease-out',\n display: 'flex',\n alignItems: 'center',\n fieldSizing: 'content',\n },\n sendButton: {\n width: '33px',\n height: '33px', // Match input minHeight for vertical alignment\n borderRadius: '10px',\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n border: 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'all 0.2s ease-out',\n boxShadow: '0 2px 0 rgba(0, 0, 0, 0.045)',\n fontWeight: 700,\n flexShrink: 0,\n },\n // Identification form styles\n identificationForm: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column' as const,\n padding: '24px',\n background: '#eeeded',\n overflowY: 'auto' as const,\n },\n formTitle: {\n fontSize: '18px',\n fontWeight: 600,\n color: '#020617',\n marginBottom: '8px',\n },\n formDescription: {\n fontSize: '14px',\n color: '#64748b',\n marginBottom: '24px',\n lineHeight: 1.5,\n },\n recoverFooter: {\n padding: '10px 14px',\n borderTop: '1px solid #e5e7eb',\n fontSize: '12px',\n color: '#64748b',\n lineHeight: 1.5,\n flexShrink: 0,\n textAlign: 'center',\n },\n recoverFooterLink: {\n background: 'none',\n border: 'none',\n padding: 0,\n color: '#64748b',\n cursor: 'pointer',\n fontSize: '12px',\n fontFamily: 'inherit',\n textDecoration: 'underline',\n },\n formField: {\n marginBottom: '16px',\n },\n formLabel: {\n display: 'block',\n fontSize: '13px',\n fontWeight: 500,\n color: '#020617',\n marginBottom: '6px',\n },\n formInput: {\n width: '100%',\n padding: '10px 12px',\n border: '1px solid #dcdcdc',\n borderRadius: '6px',\n fontSize: '14px',\n fontFamily: 'inherit',\n color: '#020617',\n background: 'white',\n transition: 'border-color 0.2s ease-out, box-shadow 0.2s ease-out',\n boxSizing: 'border-box' as const,\n },\n formInputError: {\n borderColor: '#ef4444',\n },\n formError: {\n fontSize: '12px',\n color: '#ef4444',\n marginTop: '4px',\n },\n formSubmitButton: {\n width: '100%',\n padding: '12px 16px',\n borderRadius: '6px',\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: 600,\n transition: 'all 0.2s ease-out',\n marginTop: '8px',\n },\n formOptional: {\n fontSize: '12px',\n color: '#939393',\n fontWeight: 400,\n },\n restoreRequestSuccess: {\n marginTop: '12px',\n fontSize: '12px',\n color: '#166534',\n background: '#dcfce7',\n border: '1px solid #86efac',\n borderRadius: '6px',\n padding: '10px 12px',\n lineHeight: 1.4,\n },\n // Ticket list styles\n ticketListContainer: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column' as const,\n background: 'white',\n overflowY: 'auto' as const,\n },\n ticketList: {\n flex: 1,\n overflowY: 'auto' as const,\n },\n ticketItem: {\n padding: '14px 16px',\n borderBottom: '1px solid #f1f1f1',\n cursor: 'pointer',\n transition: 'background 0.15s ease-out',\n background: 'white',\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n },\n ticketItemUnread: {\n background: '#fafafa',\n },\n ticketItemContent: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '6px',\n flex: 1,\n minWidth: 0, // Allow text truncation\n },\n ticketItemArrow: {\n color: '#939393',\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n },\n ticketItemHeader: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n gap: '8px',\n },\n ticketPreview: {\n fontSize: '13px',\n color: '#020617',\n lineHeight: 1.4,\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap' as const,\n },\n ticketPreviewUnread: {\n fontSize: '13px',\n color: '#020617',\n lineHeight: 1.4,\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap' as const,\n fontWeight: 600,\n },\n ticketUnreadBadge: {\n minWidth: '18px',\n height: '18px',\n borderRadius: '9px',\n background: '#ef4444',\n color: 'white',\n fontSize: '10px',\n fontWeight: 600,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0 5px',\n flexShrink: 0,\n },\n ticketMeta: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n },\n ticketTime: {\n fontSize: '11px',\n color: '#939393',\n },\n ticketStatus: {\n fontSize: '10px',\n color: '#64748b',\n background: '#f1f5f9',\n padding: '2px 6px',\n borderRadius: '4px',\n textTransform: 'uppercase' as const,\n letterSpacing: '0.3px',\n },\n newConversationButton: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '12px 16px',\n padding: '10px 16px',\n borderRadius: '8px',\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n fontWeight: 500,\n transition: 'all 0.2s ease-out',\n },\n // Ticket list loading state\n ticketListLoading: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column' as const,\n alignItems: 'center',\n justifyContent: 'center',\n gap: '12px',\n color: '#64748b',\n fontSize: '13px',\n },\n loadingSpinner: {\n width: '24px',\n height: '24px',\n border: '2px solid #e2e8f0',\n borderTop: `2px solid ${primaryColor}`,\n borderRadius: '50%',\n animation: 'spin 0.8s linear infinite',\n },\n // Ticket list empty state\n ticketListEmpty: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column' as const,\n alignItems: 'center',\n justifyContent: 'center',\n padding: '32px 24px',\n textAlign: 'center' as const,\n },\n emptyStateIcon: {\n color: '#cbd5e1',\n marginBottom: '16px',\n },\n emptyStateTitle: {\n fontSize: '16px',\n fontWeight: 600,\n color: '#020617',\n marginBottom: '8px',\n },\n emptyStateDescription: {\n fontSize: '13px',\n color: '#64748b',\n lineHeight: 1.5,\n marginBottom: '20px',\n },\n newConversationButtonLarge: {\n padding: '12px 24px',\n borderRadius: '8px',\n background: primaryColor,\n color: getContrastTextColor(primaryColor),\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: 600,\n transition: 'all 0.2s ease-out',\n },\n fetchPreviousButton: {\n marginTop: '10px',\n background: 'transparent',\n border: 'none',\n color: primaryColor,\n cursor: 'pointer',\n fontSize: '13px',\n textDecoration: 'underline',\n opacity: 1,\n },\n // Back button for message view header\n backButton: {\n background: 'transparent',\n border: 'none',\n color: getContrastTextColor(primaryColor),\n cursor: 'pointer',\n padding: '6px 0px',\n marginRight: '4px',\n fontSize: '16px',\n lineHeight: 1,\n borderRadius: '4px',\n transition: 'background 0.2s ease-out',\n opacity: 0.9,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n // Header with back button layout\n headerWithBack: {\n display: 'flex',\n alignItems: 'center',\n },\n }\n}\n","import type { WidgetPosition } from '../../../../posthog-conversations-types'\nimport { getStyles } from './styles'\n\ninterface OpenChatButtonProps {\n primaryColor: string\n position?: WidgetPosition\n handleToggleOpen: () => void\n unreadCount?: number\n}\n\nexport const OpenChatButton = ({\n primaryColor,\n position = 'bottom_right',\n handleToggleOpen,\n unreadCount = 0,\n}: OpenChatButtonProps) => {\n const styles = getStyles(primaryColor, position)\n const displayCount = unreadCount > 99 ? '99+' : unreadCount.toString()\n\n return (\n <div style={styles.widget}>\n <div style={styles.buttonContainer}>\n <button\n style={styles.button}\n onClick={handleToggleOpen}\n aria-label={unreadCount > 0 ? `Open chat (${unreadCount} unread)` : 'Open chat'}\n onMouseEnter={(e) => {\n e.currentTarget.style.transform = 'scale(1.05)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.transform = 'scale(1)'\n }}\n >\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 2C6.48 2 2 6.48 2 12C2 13.93 2.6 15.71 3.64 17.18L2.5 21.5L7.04 20.42C8.46 21.28 10.17 21.75 12 21.75C17.52 21.75 22 17.27 22 11.75C22 6.23 17.52 2 12 2Z\"\n fill=\"currentColor\"\n />\n </svg>\n </button>\n {unreadCount > 0 && <div style={styles.unreadBadge}>{displayCount}</div>}\n </div>\n </div>\n )\n}\n","import { getStyles } from './styles'\n\ninterface CloseChatButtonProps {\n primaryColor: string\n handleClose: () => void\n}\n\nexport const CloseChatButton = ({ primaryColor, handleClose }: CloseChatButtonProps) => {\n const styles = getStyles(primaryColor)\n return (\n <button\n style={styles.headerButton}\n onClick={handleClose}\n aria-label=\"Close\"\n onMouseEnter={(e) => {\n e.currentTarget.style.background = 'rgba(255, 255, 255, 0.15)'\n e.currentTarget.style.opacity = '1'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = 'transparent'\n e.currentTarget.style.opacity = '0.9'\n }}\n >\n ✕\n </button>\n )\n}\n","/**\n * Format a timestamp to a relative time string\n */\nexport function formatRelativeTime(isoString: string | undefined): string {\n if (!isoString) {\n return ''\n }\n\n const date = new Date(isoString)\n const now = new Date()\n const diffMs = now.getTime() - date.getTime()\n const diffMins = Math.floor(diffMs / 60000)\n const diffHours = Math.floor(diffMins / 60)\n const diffDays = Math.floor(diffHours / 24)\n\n if (diffMins < 1) {\n return 'Just now'\n } else if (diffMins < 60) {\n return `${diffMins}m ago`\n } else if (diffHours < 24) {\n return `${diffHours}h ago`\n } else if (diffDays === 1) {\n return 'Yesterday'\n } else if (diffDays < 7) {\n return `${diffDays}d ago`\n } else {\n return date.toLocaleDateString()\n }\n}\n\n/**\n * Truncate text to a maximum length with ellipsis\n */\nexport function truncateText(text: string | undefined, maxLength: number): string {\n if (!text) {\n return 'No messages yet'\n }\n if (text.length <= maxLength) {\n return text\n }\n return text.substring(0, maxLength - 3) + '...'\n}\n\n/**\n * Strip markdown formatting from text for plain text display\n * Lightweight regex-based approach without external dependencies\n */\nexport function stripMarkdown(text: string | undefined): string {\n if (!text) {\n return ''\n }\n\n return (\n text\n // Remove code blocks first (before other processing)\n .replace(/```[\\s\\S]*?```/g, '')\n // Remove inline code\n .replace(/`([^`]+)`/g, '$1')\n // Remove images\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, '')\n // Convert links to just text\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n // Remove headers\n .replace(/^#{1,6}\\s+/gm, '')\n // Remove blockquotes\n .replace(/^>\\s*/gm, '')\n // Remove horizontal rules (must be before list markers to avoid conflicts)\n .replace(/^[-*_]{3,}\\s*$/gm, '')\n // Remove list markers (must be before bold/italic to avoid conflicts with *)\n .replace(/^[\\s]*[-*+]\\s+/gm, '')\n .replace(/^[\\s]*\\d+\\.\\s+/gm, '')\n // Remove bold/italic (order matters: ** before *)\n .replace(/\\*\\*([^*]+)\\*\\*/g, '$1')\n .replace(/\\*([^*]+)\\*/g, '$1')\n .replace(/__([^_]+)__/g, '$1')\n .replace(/_([^_]+)_/g, '$1')\n // Remove strikethrough\n .replace(/~~([^~]+)~~/g, '$1')\n // Remove HTML tags entirely, then strip any remaining angle brackets for security\n .replace(/<[^>]*>/g, '')\n .replace(/[<>]/g, '')\n // Collapse multiple newlines\n .replace(/\\n{2,}/g, '\\n')\n // Trim whitespace\n .trim()\n )\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, FunctionComponent } from 'preact'\nimport { Ticket, TicketStatus } from '../../../../posthog-conversations-types'\nimport { getStyles } from './styles'\nimport { formatRelativeTime, truncateText, stripMarkdown } from './utils'\n\ninterface TicketListItemProps {\n ticket: Ticket\n styles: ReturnType<typeof getStyles>\n onClick: (ticketId: string) => void\n}\n\n/**\n * Get a human-readable status label\n * Matches the display logic in PostHog main app\n */\nfunction getStatusLabel(status: TicketStatus): string {\n if (status === 'on_hold') {\n return 'On hold'\n }\n // Capitalize first letter: 'new' -> 'New', 'open' -> 'Open', etc.\n return status.charAt(0).toUpperCase() + status.slice(1)\n}\n\n/**\n * A single ticket item in the ticket list\n */\nexport const TicketListItem: FunctionComponent<TicketListItemProps> = ({ ticket, styles, onClick }) => {\n const hasUnread = (ticket.unread_count || 0) > 0\n const statusLabel = getStatusLabel(ticket.status)\n\n const handleClick = () => {\n onClick(ticket.id)\n }\n\n const itemStyle = {\n ...styles.ticketItem,\n ...(hasUnread ? styles.ticketItemUnread : {}),\n }\n\n return (\n <div\n style={itemStyle}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n handleClick()\n }\n }}\n role=\"button\"\n tabIndex={0}\n >\n <div style={styles.ticketItemContent}>\n <div style={styles.ticketItemHeader}>\n <span style={hasUnread ? styles.ticketPreviewUnread : styles.ticketPreview}>\n {truncateText(stripMarkdown(ticket.last_message), 60)}\n </span>\n {hasUnread && <span style={styles.ticketUnreadBadge}>{ticket.unread_count}</span>}\n </div>\n <div style={styles.ticketMeta}>\n <span style={styles.ticketTime}>\n {formatRelativeTime(ticket.last_message_at || ticket.created_at)}\n </span>\n <span style={styles.ticketStatus}>{statusLabel}</span>\n </div>\n </div>\n {/* Right arrow indicator */}\n <div style={styles.ticketItemArrow}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n </div>\n </div>\n )\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, FunctionComponent } from 'preact'\nimport { getStyles } from './styles'\n\ninterface NewConversationButtonProps {\n styles: ReturnType<typeof getStyles>\n onClick: () => void\n}\n\n/**\n * Primary CTA used anywhere the user can start a fresh conversation —\n * the bottom of the ticket list and the resolved-state banner in the message view.\n */\nexport const NewConversationButton: FunctionComponent<NewConversationButtonProps> = ({ styles, onClick }) => (\n <button\n type=\"button\"\n style={styles.newConversationButton}\n onClick={onClick}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '0.9'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n style={{ marginRight: '8px' }}\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n New conversation\n </button>\n)\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, FunctionComponent } from 'preact'\nimport { Ticket } from '../../../../posthog-conversations-types'\nimport { getStyles } from './styles'\nimport { TicketListItem } from './TicketListItem'\nimport { NewConversationButton } from './NewConversationButton'\n\ninterface TicketListViewProps {\n tickets: Ticket[]\n isLoading: boolean\n styles: ReturnType<typeof getStyles>\n onSelectTicket: (ticketId: string) => void\n onNewConversation: () => void\n onOpenRestoreRequest: () => void\n}\n\n/**\n * Loading state component\n */\nconst LoadingState: FunctionComponent<{ styles: ReturnType<typeof getStyles> }> = ({ styles }) => (\n <div style={styles.ticketListLoading}>\n <div style={styles.loadingSpinner} />\n <span>Loading conversations...</span>\n </div>\n)\n\n/**\n * Empty state component when there are no tickets\n */\nconst EmptyState: FunctionComponent<{\n styles: ReturnType<typeof getStyles>\n onNewConversation: () => void\n onOpenRestoreRequest: () => void\n}> = ({ styles, onNewConversation, onOpenRestoreRequest }) => (\n <div style={styles.ticketListEmpty}>\n <div style={styles.emptyStateIcon}>\n <svg width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n </div>\n <div style={styles.emptyStateTitle}>No conversations yet</div>\n <div style={styles.emptyStateDescription}>Start a new conversation to get help from our team.</div>\n <button\n style={styles.newConversationButtonLarge}\n onClick={onNewConversation}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '0.9'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n >\n Start a conversation\n </button>\n <button\n style={styles.fetchPreviousButton}\n onClick={onOpenRestoreRequest}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '0.8'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n >\n Fetch previous conversations\n </button>\n </div>\n)\n\n/**\n * Ticket list view showing all user's tickets\n */\nexport const TicketListView: FunctionComponent<TicketListViewProps> = ({\n tickets,\n isLoading,\n styles,\n onSelectTicket,\n onNewConversation,\n onOpenRestoreRequest,\n}) => {\n // Show loading state\n if (isLoading && tickets.length === 0) {\n return <LoadingState styles={styles} />\n }\n\n // Show empty state when no tickets\n if (tickets.length === 0) {\n return (\n <EmptyState\n styles={styles}\n onNewConversation={onNewConversation}\n onOpenRestoreRequest={onOpenRestoreRequest}\n />\n )\n }\n\n // Show ticket list\n return (\n <div style={styles.ticketListContainer}>\n {/* Ticket list - sorted by most recent activity */}\n <div style={styles.ticketList}>\n {[...tickets]\n .sort((a, b) => {\n const dateA = new Date(a.last_message_at || a.created_at).getTime()\n const dateB = new Date(b.last_message_at || b.created_at).getTime()\n return dateB - dateA // Descending order (newest first)\n })\n .map((ticket) => (\n <TicketListItem\n key={`${ticket.id}-${ticket.last_message_at || ticket.created_at}-${ticket.unread_count}`}\n ticket={ticket}\n styles={styles}\n onClick={onSelectTicket}\n />\n ))}\n </div>\n\n {/* New conversation button at bottom */}\n <NewConversationButton styles={styles} onClick={onNewConversation} />\n </div>\n )\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h } from 'preact'\nimport { ConversationsRemoteConfig } from '../../../../posthog-conversations-types'\nimport { getStyles } from './styles'\n\ninterface IdentificationFormViewProps {\n config: ConversationsRemoteConfig\n styles: ReturnType<typeof getStyles>\n formName: string\n formEmail: string\n formEmailError: string | null\n onNameChange: (e: Event) => void\n onEmailChange: (e: Event) => void\n onSubmit: (e: Event) => void\n}\n\nexport function IdentificationFormView({\n config,\n styles,\n formName,\n formEmail,\n formEmailError,\n onNameChange,\n onEmailChange,\n onSubmit,\n}: IdentificationFormViewProps) {\n const title = config.identificationFormTitle || 'Before we start...'\n const description = config.identificationFormDescription || 'Please provide your details so we can help you better.'\n const showNameField = config.collectName !== false\n\n return (\n <div style={styles.identificationForm}>\n <div style={styles.formTitle}>{title}</div>\n <div style={styles.formDescription}>{description}</div>\n\n <form onSubmit={onSubmit}>\n {showNameField && (\n <div style={styles.formField}>\n <label style={styles.formLabel}>\n Name <span style={styles.formOptional}>(optional)</span>\n </label>\n <input\n type=\"text\"\n style={styles.formInput}\n value={formName}\n onInput={onNameChange}\n placeholder=\"Your name\"\n autoComplete=\"name\"\n />\n </div>\n )}\n\n <div style={styles.formField}>\n <label style={styles.formLabel}>\n Email {!config.requireEmail && <span style={styles.formOptional}>(optional)</span>}\n </label>\n <input\n type=\"email\"\n style={{\n ...styles.formInput,\n ...(formEmailError ? styles.formInputError : {}),\n }}\n value={formEmail}\n onInput={onEmailChange}\n placeholder=\"you@example.com\"\n autoComplete=\"email\"\n />\n {formEmailError && <div style={styles.formError}>{formEmailError}</div>}\n </div>\n\n <button\n type=\"submit\"\n style={styles.formSubmitButton}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '0.9'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n >\n Start Chat\n </button>\n </form>\n </div>\n )\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h } from 'preact'\nimport { getStyles } from './styles'\n\ninterface RestoreRequestViewProps {\n styles: ReturnType<typeof getStyles>\n restoreEmail: string\n restoreEmailError: string | null\n restoreRequestLoading: boolean\n restoreRequestSuccess: boolean\n onEmailChange: (e: Event) => void\n onSubmit: (e: Event) => void\n}\n\nexport function RestoreRequestView({\n styles,\n restoreEmail,\n restoreEmailError,\n restoreRequestLoading,\n restoreRequestSuccess,\n onEmailChange,\n onSubmit,\n}: RestoreRequestViewProps) {\n return (\n <div style={styles.identificationForm}>\n <div style={styles.formTitle}>Restore conversations</div>\n <div style={styles.formDescription}>\n Don't see your previous conversations? Maybe you use another browser or computer. Enter your email and\n we will send a secure restore link if matching conversations exist.\n </div>\n\n <form onSubmit={onSubmit}>\n <div style={styles.formField}>\n <label style={styles.formLabel}>Email</label>\n <input\n type=\"email\"\n style={{\n ...styles.formInput,\n ...(restoreEmailError ? styles.formInputError : {}),\n }}\n value={restoreEmail}\n onInput={onEmailChange}\n placeholder=\"you@example.com\"\n autoComplete=\"email\"\n disabled={restoreRequestLoading}\n />\n {restoreEmailError && <div style={styles.formError}>{restoreEmailError}</div>}\n </div>\n\n <button type=\"submit\" style={styles.formSubmitButton} disabled={restoreRequestLoading}>\n {restoreRequestLoading ? 'Sending...' : 'Send restore link'}\n </button>\n </form>\n\n {restoreRequestSuccess && (\n <div style={styles.restoreRequestSuccess}>\n Check your email for a secure restore link. If an account is found, we sent it.\n </div>\n )}\n </div>\n )\n}\n","import { getStyles } from './styles'\n\ninterface SendMessageButtonProps {\n primaryColor: string\n inputValue: string\n isLoading: boolean\n handleSendMessage: () => void\n}\n\nexport const SendMessageButton = ({\n primaryColor,\n inputValue,\n isLoading,\n handleSendMessage,\n}: SendMessageButtonProps) => {\n const styles = getStyles(primaryColor)\n return (\n <button\n style={{\n ...styles.sendButton,\n opacity: !inputValue.trim() || isLoading ? 0.6 : 1,\n cursor: !inputValue.trim() || isLoading ? 'not-allowed' : 'pointer',\n }}\n onClick={handleSendMessage}\n disabled={!inputValue.trim() || isLoading}\n aria-label=\"Send message\"\n onMouseEnter={(e) => {\n if (!e.currentTarget.disabled) {\n e.currentTarget.style.transform = 'scale(1.02)'\n e.currentTarget.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.1)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.transform = 'scale(1)'\n e.currentTarget.style.boxShadow = '0 2px 0 rgba(0, 0, 0, 0.045)'\n }}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M2 10L18 2L10 18L8 11L2 10Z\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n )\n}\n","import{options as n}from\"preact\";var t,r,u,i,o=0,f=[],c=n,e=c.__b,a=c.__r,v=c.diffed,l=c.__c,m=c.unmount,s=c.__;function p(n,t){c.__h&&c.__h(r,n,o||t),o=0;var u=r.__H||(r.__H={__:[],__h:[]});return n>=u.__.length&&u.__.push({}),u.__[n]}function d(n){return o=1,h(D,n)}function h(n,u,i){var o=p(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):D(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.__f)){var f=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return!!n.__c});if(u.every(function(n){return!n.__N}))return!c||c.call(this,n,t,r);var i=o.__c.props!==n;return u.forEach(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),c&&c.call(this,n,t,r)||i};r.__f=!0;var c=r.shouldComponentUpdate,e=r.componentWillUpdate;r.componentWillUpdate=function(n,t,r){if(this.__e){var u=c;c=void 0,f(n,t,r),c=u}e&&e.call(this,n,t,r)},r.shouldComponentUpdate=f}return o.__N||o.__}function y(n,u){var i=p(t++,3);!c.__s&&C(i.__H,u)&&(i.__=n,i.u=u,r.__H.__h.push(i))}function _(n,u){var i=p(t++,4);!c.__s&&C(i.__H,u)&&(i.__=n,i.u=u,r.__h.push(i))}function A(n){return o=5,T(function(){return{current:n}},[])}function F(n,t,r){o=6,_(function(){if(\"function\"==typeof n){var r=n(t());return function(){n(null),r&&\"function\"==typeof r&&r()}}if(n)return n.current=t(),function(){return n.current=null}},null==r?r:r.concat(n))}function T(n,r){var u=p(t++,7);return C(u.__H,r)&&(u.__=n(),u.__H=r,u.__h=n),u.__}function q(n,t){return o=8,T(function(){return n},t)}function x(n){var u=r.context[n.__c],i=p(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function P(n,t){c.useDebugValue&&c.useDebugValue(t?t(n):n)}function b(n){var u=p(t++,10),i=d();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n,t){u.__&&u.__(n,t),i[1](n)}),[i[0],function(){i[1](void 0)}]}function g(){var n=p(t++,11);if(!n.__){for(var u=r.__v;null!==u&&!u.__m&&null!==u.__;)u=u.__;var i=u.__m||(u.__m=[0,0]);n.__=\"P\"+i[0]+\"-\"+i[1]++}return n.__}function j(){for(var n;n=f.shift();)if(n.__P&&n.__H)try{n.__H.__h.forEach(z),n.__H.__h.forEach(B),n.__H.__h=[]}catch(t){n.__H.__h=[],c.__e(t,n.__v)}}c.__b=function(n){r=null,e&&e(n)},c.__=function(n,t){n&&t.__k&&t.__k.__m&&(n.__m=t.__k.__m),s&&s(n,t)},c.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0})):(i.__h.forEach(z),i.__h.forEach(B),i.__h=[],t=0)),u=r},c.diffed=function(n){v&&v(n);var t=n.__c;t&&t.__H&&(t.__H.__h.length&&(1!==f.push(t)&&i===c.requestAnimationFrame||((i=c.requestAnimationFrame)||w)(j)),t.__H.__.forEach(function(n){n.u&&(n.__H=n.u),n.u=void 0})),u=r=null},c.__c=function(n,t){t.some(function(n){try{n.__h.forEach(z),n.__h=n.__h.filter(function(n){return!n.__||B(n)})}catch(r){t.some(function(n){n.__h&&(n.__h=[])}),t=[],c.__e(r,n.__v)}}),l&&l(n,t)},c.unmount=function(n){m&&m(n);var t,r=n.__c;r&&r.__H&&(r.__H.__.forEach(function(n){try{z(n)}catch(n){t=n}}),r.__H=void 0,t&&c.__e(t,r.__v))};var k=\"function\"==typeof requestAnimationFrame;function w(n){var t,r=function(){clearTimeout(u),k&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,35);k&&(t=requestAnimationFrame(r))}function z(n){var t=r,u=n.__c;\"function\"==typeof u&&(n.__c=void 0,u()),r=t}function B(n){var t=r;n.__c=n.__(),r=t}function C(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function D(n,t){return\"function\"==typeof t?t(n):t}export{q as useCallback,x as useContext,P as useDebugValue,y as useEffect,b as useErrorBoundary,g as useId,F as useImperativeHandle,_ as useLayoutEffect,T as useMemo,h as useReducer,A as useRef,d as useState};\n//# sourceMappingURL=hooks.module.js.map\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, Fragment } from 'preact'\nimport { useMemo } from 'preact/hooks'\nimport { isUndefined, isNumber, isArray } from '@posthog/core'\nimport { TipTapDoc, TipTapNode, TipTapMark } from '../../../../posthog-conversations-types'\n\ninterface RichContentProps {\n /** Rich content in TipTap JSON format (preferred) */\n richContent?: TipTapDoc\n /** Plain text fallback if rich_content is missing or invalid */\n content: string\n /** Whether message is from customer (affects styling) */\n isCustomer: boolean\n /** Primary color for links */\n primaryColor: string\n}\n\n/**\n * Sanitize URL to prevent javascript: and other dangerous protocols.\n * Only allows http:, https:, mailto:, tel:, and relative URLs.\n *\n * Security measures:\n * - Removes ASCII control characters (0x00-0x1F, 0x7F) that could obfuscate protocols\n * - Removes Unicode whitespace and zero-width characters\n * - Collapses whitespace when checking protocols to prevent \"java script:\" bypasses\n * - Blocks javascript:, vbscript:, data:, and file: protocols\n * - Blocks protocol-relative URLs (//example.com)\n */\nfunction sanitizeUrl(url: string): string | undefined {\n if (!url || typeof url !== 'string') {\n return undefined\n }\n\n // Remove ASCII control characters (0x00-0x1F, 0x7F DEL) that could obfuscate protocols\n // Also remove zero-width characters (U+200B-U+200D, U+FEFF) that could be used for obfuscation\n // eslint-disable-next-line no-control-regex\n const cleanedUrl = url.replace(/[\\x00-\\x1f\\x7f\\u200b-\\u200d\\ufeff]/g, '')\n const trimmedUrl = cleanedUrl.trim()\n if (!trimmedUrl) {\n return undefined\n }\n\n // Collapse all whitespace (including Unicode whitespace) when checking protocol\n // This prevents bypasses like \"java script:\" or \"java\\u00A0script:\" (non-breaking space)\n const normalizedForCheck = trimmedUrl.replace(/\\s+/g, '').toLowerCase()\n\n // Block dangerous protocols\n if (\n normalizedForCheck.startsWith('javascript:') ||\n normalizedForCheck.startsWith('vbscript:') ||\n normalizedForCheck.startsWith('data:') ||\n normalizedForCheck.startsWith('file:')\n ) {\n return undefined\n }\n\n // Allow relative URLs (check against trimmed URL, not normalized)\n // Note: We explicitly check for '//' first to block protocol-relative URLs (e.g., //evil.com)\n // which could be used to load content from attacker-controlled domains\n if (trimmedUrl.startsWith('//')) {\n return undefined\n }\n if (\n trimmedUrl.startsWith('/') ||\n trimmedUrl.startsWith('./') ||\n trimmedUrl.startsWith('../') ||\n trimmedUrl.startsWith('#')\n ) {\n return trimmedUrl\n }\n\n // Allow safe absolute URLs\n const lowerUrl = trimmedUrl.toLowerCase()\n if (\n lowerUrl.startsWith('http://') ||\n lowerUrl.startsWith('https://') ||\n lowerUrl.startsWith('mailto:') ||\n lowerUrl.startsWith('tel:')\n ) {\n return trimmedUrl\n }\n\n return undefined\n}\n\n/** Maximum recursion depth to prevent stack overflow */\nconst MAX_DEPTH = 20\n\nfunction getStyles(isCustomer: boolean, primaryColor: string) {\n return {\n code: {\n fontFamily: 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace',\n fontSize: '0.9em',\n padding: '2px 4px',\n borderRadius: '3px',\n background: isCustomer ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.06)',\n },\n codeBlock: {\n fontFamily: 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace',\n fontSize: '0.85em',\n padding: '8px 10px',\n borderRadius: '6px',\n background: isCustomer ? 'rgba(255, 255, 255, 0.15)' : '#f4f4f5',\n overflowX: 'auto' as const,\n whiteSpace: 'pre-wrap' as const,\n wordWrap: 'break-word' as const,\n wordBreak: 'break-word' as const,\n margin: '8px 0',\n display: 'block',\n lineHeight: 1.5,\n border: isCustomer ? 'none' : '1px solid #e4e4e7',\n },\n link: {\n color: isCustomer ? 'white' : primaryColor,\n textDecoration: 'underline',\n },\n image: {\n maxWidth: '100%',\n borderRadius: '4px',\n marginTop: '4px',\n marginBottom: '4px',\n display: 'block',\n },\n }\n}\n\n/**\n * Render a text node with its marks (bold, italic, underline, etc.)\n * Marks are applied by wrapping the content in nested elements.\n */\nfunction renderTextWithMarks(\n text: string,\n marks: TipTapMark[] | undefined,\n styles: ReturnType<typeof getStyles>,\n key: string\n): preact.JSX.Element {\n if (!marks || marks.length === 0) {\n return <span key={key}>{text}</span>\n }\n\n // Build the element by wrapping with marks from inside out\n let element: preact.JSX.Element = <>{text}</>\n\n for (const mark of marks) {\n switch (mark.type) {\n case 'bold':\n element = <strong style={{ fontWeight: 700 }}>{element}</strong>\n break\n case 'italic':\n element = <em style={{ fontStyle: 'italic' }}>{element}</em>\n break\n case 'underline':\n element = <u style={{ textDecoration: 'underline' }}>{element}</u>\n break\n case 'strike':\n element = <s style={{ textDecoration: 'line-through' }}>{element}</s>\n break\n case 'code':\n element = <code style={styles.code}>{element}</code>\n break\n case 'link': {\n const href = mark.attrs?.href\n const safeUrl = typeof href === 'string' ? sanitizeUrl(href) : undefined\n if (safeUrl) {\n element = (\n <a\n href={safeUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n referrerPolicy=\"no-referrer\"\n style={styles.link}\n >\n {element}\n </a>\n )\n }\n break\n }\n // Ignore unknown mark types for safety\n }\n }\n\n return <span key={key}>{element}</span>\n}\n\n/**\n * Recursively render a TipTap node and its children\n */\nfunction renderNode(\n node: TipTapNode | TipTapDoc,\n styles: ReturnType<typeof getStyles>,\n depth: number,\n key: string\n): preact.JSX.Element | null {\n // Safety: prevent infinite recursion\n if (depth > MAX_DEPTH) {\n return null\n }\n\n // Text node with optional marks\n if (node.type === 'text' && !isUndefined(node.text)) {\n return renderTextWithMarks(node.text, node.marks, styles, key)\n }\n\n // Render children recursively\n const children = node.content?.map((child, index) => renderNode(child, styles, depth + 1, `${key}-${index}`)) || []\n\n switch (node.type) {\n case 'doc':\n return <>{children}</>\n\n case 'paragraph':\n return (\n <p key={key} style={{ margin: '0 0 8px 0' }}>\n {children.length > 0 ? children : <br />}\n </p>\n )\n\n case 'hardBreak':\n return <br key={key} />\n\n case 'codeBlock': {\n // Code blocks store text in content[0].text\n const codeText = node.content?.[0]?.text || ''\n return (\n <pre key={key} style={styles.codeBlock}>\n <code>{codeText}</code>\n </pre>\n )\n }\n\n case 'image': {\n const src = node.attrs?.src\n const alt = node.attrs?.alt\n const safeUrl = typeof src === 'string' ? sanitizeUrl(src) : undefined\n if (!safeUrl) {\n return null\n }\n return (\n <img\n key={key}\n src={safeUrl}\n alt={typeof alt === 'string' ? alt : ''}\n style={styles.image}\n onError={(e) => {\n ;(e.target as HTMLImageElement).style.display = 'none'\n }}\n />\n )\n }\n\n case 'bulletList':\n return (\n <ul key={key} style={{ margin: '8px 0', paddingLeft: '24px' }}>\n {children}\n </ul>\n )\n\n case 'orderedList':\n return (\n <ol key={key} style={{ margin: '8px 0', paddingLeft: '24px' }}>\n {children}\n </ol>\n )\n\n case 'listItem':\n return (\n <li key={key} style={{ margin: '4px 0' }}>\n {children}\n </li>\n )\n\n case 'blockquote':\n return (\n <blockquote\n key={key}\n style={{\n margin: '8px 0',\n paddingLeft: '12px',\n borderLeft: '3px solid #e4e4e7',\n color: '#71717a',\n }}\n >\n {children}\n </blockquote>\n )\n\n case 'heading': {\n const rawLevel = node.attrs?.level\n const level = isNumber(rawLevel) ? rawLevel : 1\n const HeadingTag = `h${Math.min(Math.max(level, 1), 6)}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'\n return (\n <HeadingTag key={key} style={{ margin: '12px 0 8px 0' }}>\n {children}\n </HeadingTag>\n )\n }\n\n case 'horizontalRule':\n return <hr key={key} style={{ margin: '12px 0', border: 'none', borderTop: '1px solid #e4e4e7' }} />\n\n default:\n // Unknown node types: render children if any, otherwise ignore\n if (children.length > 0) {\n return <span key={key}>{children}</span>\n }\n return null\n }\n}\n\n/**\n * Validate that the content looks like a valid TipTap document\n */\nfunction isValidTipTapDoc(doc: unknown): doc is TipTapDoc {\n if (!doc || typeof doc !== 'object') {\n return false\n }\n const d = doc as TipTapDoc\n return d.type === 'doc' && (isUndefined(d.content) || isArray(d.content))\n}\n\n/**\n * Render plain text with line breaks preserved\n */\nfunction renderPlainText(text: string): preact.JSX.Element {\n if (!text) {\n return <></>\n }\n const lines = text.split('\\n')\n return (\n <>\n {lines.map((line, index) => (\n <Fragment key={index}>\n {line}\n {index < lines.length - 1 && <br />}\n </Fragment>\n ))}\n </>\n )\n}\n\n/**\n * RichContent component - renders TipTap JSON content with plain text fallback\n *\n * Rendering logic:\n * 1. If richContent is present and valid, render as TipTap tree\n * 2. If richContent is missing or invalid, fall back to plain text content\n * 3. Wrap TipTap rendering in try/catch for safety\n */\nexport function RichContent({ richContent, content, isCustomer, primaryColor }: RichContentProps) {\n const styles = useMemo(() => getStyles(isCustomer, primaryColor), [isCustomer, primaryColor])\n\n // Try to render rich content if available\n if (richContent) {\n try {\n if (isValidTipTapDoc(richContent)) {\n const rendered = renderNode(richContent, styles, 0, 'root')\n if (rendered) {\n return rendered\n }\n }\n } catch {\n // Fall through to plain text on any error\n }\n }\n\n // Fallback: render plain text content\n return renderPlainText(content)\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, Fragment } from 'preact'\nimport { Message } from '../../../../posthog-conversations-types'\nimport { getStyles } from './styles'\nimport { SendMessageButton } from './SendMessageButton'\nimport { RichContent } from './RichContent'\nimport { NewConversationButton } from './NewConversationButton'\nimport { formatRelativeTime } from './utils'\n\ninterface MessagesViewProps {\n styles: ReturnType<typeof getStyles>\n primaryColor: string\n placeholderText: string\n messages: Message[]\n inputValue: string\n isLoading: boolean\n error: string | null\n isResolved: boolean\n onInputChange: (e: Event) => void\n onKeyDown: (e: KeyboardEvent) => void\n onSendMessage: () => void\n onStartNewConversation: () => void\n messagesEndRef: (el: HTMLDivElement | null) => void\n}\n\nfunction MessageBubble({\n message,\n styles,\n primaryColor,\n}: {\n message: Message\n styles: ReturnType<typeof getStyles>\n primaryColor: string\n}) {\n const isCustomer = message.author_type === 'customer'\n const messageStyle = {\n ...styles.message,\n ...(isCustomer ? styles.messageCustomer : styles.messageAgent),\n }\n const contentStyle = {\n ...styles.messageContent,\n ...(isCustomer ? styles.messageContentCustomer : styles.messageContentAgent),\n }\n\n return (\n <div key={message.id} style={messageStyle}>\n {!isCustomer && message.author_name && <div style={styles.messageAuthor}>{message.author_name}</div>}\n <div style={contentStyle}>\n <RichContent\n richContent={message.rich_content}\n content={message.content}\n isCustomer={isCustomer}\n primaryColor={primaryColor}\n />\n </div>\n <div style={styles.messageTime}>{formatRelativeTime(message.created_at)}</div>\n </div>\n )\n}\n\nexport function MessagesView({\n styles,\n primaryColor,\n placeholderText,\n messages,\n inputValue,\n isLoading,\n error,\n isResolved,\n onInputChange,\n onKeyDown,\n onSendMessage,\n onStartNewConversation,\n messagesEndRef,\n}: MessagesViewProps) {\n return (\n <>\n <div style={styles.messages}>\n {messages.map((message) => (\n <MessageBubble key={message.id} message={message} styles={styles} primaryColor={primaryColor} />\n ))}\n <div ref={messagesEndRef} />\n </div>\n\n {error && <div style={styles.error}>{error}</div>}\n\n {isResolved ? (\n <div style={styles.resolvedBanner}>\n <div style={styles.resolvedBannerText}>This conversation was resolved.</div>\n <NewConversationButton styles={styles} onClick={onStartNewConversation} />\n </div>\n ) : (\n <div style={styles.inputContainer}>\n <textarea\n style={styles.input}\n placeholder={placeholderText}\n value={inputValue}\n onInput={onInputChange}\n onKeyDown={onKeyDown}\n rows={1}\n disabled={isLoading}\n autoFocus\n />\n <SendMessageButton\n primaryColor={primaryColor}\n inputValue={inputValue}\n isLoading={isLoading}\n handleSendMessage={onSendMessage}\n />\n </div>\n )}\n </>\n )\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { h, Component } from 'preact'\nimport {\n ConversationsRemoteConfig,\n Message,\n ConversationsWidgetState,\n RequestRestoreLinkResponse,\n UserProvidedTraits,\n Ticket,\n} from '../../../../posthog-conversations-types'\nimport { createLogger } from '../../../../utils/logger'\nimport { getStyles } from './styles'\nimport { OpenChatButton } from './OpenChatButton'\nimport { CloseChatButton } from './CloseChatButton'\nimport { TicketListView } from './TicketListView'\nimport { IdentificationFormView } from './IdentificationFormView'\nimport { RestoreRequestView } from './RestoreRequestView'\nimport { MessagesView } from './MessagesView'\n\nconst logger = createLogger('[ConversationsWidget]')\n\n/**\n * Type for the current view in the widget\n */\nexport type WidgetView = 'tickets' | 'messages' | 'restore_request' | 'identification'\n\ninterface WidgetProps {\n config: ConversationsRemoteConfig\n initialState?: ConversationsWidgetState\n initialUserTraits?: UserProvidedTraits | null\n isUserIdentified?: boolean\n isIdentityMode?: boolean\n initialView?: WidgetView\n initialTickets?: Ticket[]\n showTicketList?: boolean\n onSendMessage: (message: string) => Promise<void>\n onStateChange?: (state: ConversationsWidgetState) => void\n onIdentify?: (traits: UserProvidedTraits) => void\n onRequestRestoreLink?: (email: string) => Promise<RequestRestoreLinkResponse>\n onSelectTicket?: (ticketId: string) => void\n onNewConversation?: () => void\n onBackToTickets?: () => void\n onViewChange?: (view: WidgetView) => void\n}\n\ninterface WidgetState {\n state: ConversationsWidgetState\n view: WidgetView\n messages: Message[]\n tickets: Ticket[]\n ticketsLoading: boolean\n inputValue: string\n isLoading: boolean\n error: string | null\n formName: string\n formEmail: string\n formEmailError: string | null\n userTraits: UserProvidedTraits | null\n unreadCount: number\n showTicketList: boolean\n isCurrentTicketResolved: boolean\n isIdentityMode: boolean\n restoreEmail: string\n restoreEmailError: string | null\n restoreRequestLoading: boolean\n restoreRequestSuccess: boolean\n}\n\nexport class ConversationsWidget extends Component<WidgetProps, WidgetState> {\n private _messagesEndRef: HTMLDivElement | null = null\n\n constructor(props: WidgetProps) {\n super(props)\n\n const isIdentityMode = props.isIdentityMode || false\n\n // Determine if we need to show the identification form\n const userTraits = props.initialUserTraits || null\n const needsIdentification = this._needsIdentification(\n props.config,\n userTraits,\n props.isUserIdentified,\n isIdentityMode\n )\n\n // If identification is needed, start with that view; otherwise use the provided initial view\n const initialView = needsIdentification ? 'identification' : props.initialView || 'messages'\n\n this.state = {\n state: props.initialState || 'closed',\n view: initialView,\n messages: [],\n tickets: props.initialTickets || [],\n ticketsLoading: false,\n inputValue: '',\n isLoading: false,\n error: null,\n formName: userTraits?.name || '',\n formEmail: userTraits?.email || '',\n formEmailError: null,\n userTraits,\n unreadCount: 0,\n showTicketList: props.showTicketList || false,\n isCurrentTicketResolved: false,\n isIdentityMode,\n restoreEmail: userTraits?.email || '',\n restoreEmailError: null,\n restoreRequestLoading: false,\n restoreRequestSuccess: false,\n }\n }\n\n /**\n * Check if we need to show the identification form\n */\n private _needsIdentification(\n config: ConversationsRemoteConfig,\n traits: UserProvidedTraits | null,\n isUserIdentified?: boolean,\n isIdentityMode?: boolean\n ): boolean {\n // Server-verified identity mode -- identity is already established\n if (isIdentityMode) {\n return false\n }\n\n // If user is already identified via PostHog, no form needed\n // They've called posthog.identify() so we have their identity\n if (isUserIdentified) {\n return false\n }\n\n // If requireEmail is not set, no identification needed\n if (!config.requireEmail) {\n return false\n }\n\n // If we already have an email, no form needed\n if (traits?.email) {\n return false\n }\n\n return true\n }\n\n componentDidMount() {\n // Add greeting message if no messages exist and we're in message view\n if (this.state.view === 'messages' && this.state.messages.length === 0 && this.props.config.greetingText) {\n this._addGreetingMessage()\n }\n }\n\n componentDidUpdate(_prevProps: WidgetProps, prevState: WidgetState) {\n // Scroll to bottom when messages change\n if (this.state.messages.length !== prevState.messages.length) {\n this._scrollToBottom()\n }\n\n // Notify parent of state changes\n if (this.state.state !== prevState.state && this.props.onStateChange) {\n this.props.onStateChange(this.state.state)\n }\n\n // Scroll to bottom when opening\n if (this.state.state === 'open' && prevState.state !== 'open') {\n this._scrollToBottom()\n }\n }\n\n private _addGreetingMessage() {\n const greetingMessage: Message = {\n id: 'greeting',\n content: this.props.config.greetingText || 'Hi! How can we help?',\n author_type: 'AI',\n author_name: 'Support',\n created_at: new Date().toISOString(),\n is_private: false,\n }\n this.setState({ messages: [greetingMessage] })\n }\n\n private _scrollToBottom() {\n if (this._messagesEndRef) {\n this._messagesEndRef.scrollIntoView({ behavior: 'smooth' })\n }\n }\n\n private _handleToggleOpen = () => {\n this.setState((prevState) => ({\n state: prevState.state === 'open' ? 'closed' : 'open',\n }))\n }\n\n private _handleClose = () => {\n this.setState({ state: 'closed' })\n }\n\n private _handleSelectTicket = (ticketId: string) => {\n if (this.props.onSelectTicket) {\n this.props.onSelectTicket(ticketId)\n }\n }\n\n private _handleNewConversation = () => {\n if (this.props.onNewConversation) {\n this.props.onNewConversation()\n }\n }\n\n private _handleBackToTickets = () => {\n if (this.props.onBackToTickets) {\n this.props.onBackToTickets()\n }\n }\n\n private _handleOpenRestoreRequest = () => {\n this.setState((prevState) => ({\n view: 'restore_request',\n restoreEmail: prevState.restoreEmail || prevState.userTraits?.email || '',\n restoreEmailError: null,\n restoreRequestSuccess: false,\n }))\n if (this.props.onViewChange) {\n this.props.onViewChange('restore_request')\n }\n }\n\n private _handleCloseRestoreRequest = () => {\n const returnView = this.state.showTicketList ? 'tickets' : 'messages'\n this.setState({ view: returnView, restoreEmailError: null, restoreRequestSuccess: false })\n if (this.props.onViewChange) {\n this.props.onViewChange(returnView)\n }\n }\n\n private _handleInputChange = (e: Event) => {\n const target = e.target as HTMLTextAreaElement\n this.setState({ inputValue: target.value })\n }\n\n private _handleKeyPress = (e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n this._handleSendMessage()\n }\n }\n\n // Identification form handlers\n private _handleFormNameChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n this.setState({ formName: target.value })\n }\n\n private _handleFormEmailChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n this.setState({ formEmail: target.value, formEmailError: null })\n }\n\n private _handleRestoreEmailChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n this.setState({\n restoreEmail: target.value,\n restoreEmailError: null,\n restoreRequestSuccess: false,\n })\n }\n\n private _validateEmail(email: string): boolean {\n // Basic email validation\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n return emailRegex.test(email)\n }\n\n private _handleFormSubmit = (e: Event) => {\n e.preventDefault()\n\n const { formEmail, formName } = this.state\n const { config, onIdentify } = this.props\n\n // Validate email if required\n if (config.requireEmail && !formEmail.trim()) {\n this.setState({ formEmailError: 'Email is required' })\n return\n }\n\n if (formEmail.trim() && !this._validateEmail(formEmail.trim())) {\n this.setState({ formEmailError: 'Please enter a valid email address' })\n return\n }\n\n // Create traits object\n const traits: UserProvidedTraits = {}\n if (formName.trim()) {\n traits.name = formName.trim()\n }\n if (formEmail.trim()) {\n traits.email = formEmail.trim()\n }\n\n // Navigate to appropriate view after identification\n const nextView = this.state.showTicketList ? 'tickets' : 'messages'\n\n // Update state and notify parent\n this.setState({\n userTraits: traits,\n view: nextView,\n })\n\n if (onIdentify) {\n onIdentify(traits)\n }\n\n if (this.props.onViewChange) {\n this.props.onViewChange(nextView)\n }\n }\n\n private _handleRestoreRequestSubmit = async (e: Event) => {\n e.preventDefault()\n\n if (!this.props.onRequestRestoreLink) {\n return\n }\n\n const email = this.state.restoreEmail.trim()\n if (!email) {\n this.setState({ restoreEmailError: 'Email is required' })\n return\n }\n\n if (!this._validateEmail(email)) {\n this.setState({ restoreEmailError: 'Please enter a valid email address' })\n return\n }\n\n this.setState({\n restoreRequestLoading: true,\n restoreEmailError: null,\n })\n\n try {\n await this.props.onRequestRestoreLink(email)\n this.setState({\n restoreRequestLoading: false,\n restoreRequestSuccess: true,\n })\n } catch (error) {\n logger.error('Failed to request restore link', error)\n this.setState({\n restoreRequestLoading: false,\n restoreEmailError: error instanceof Error ? error.message : 'Failed to request restore link',\n })\n }\n }\n\n private _handleSendMessage = async () => {\n const { inputValue } = this.state\n const trimmedMessage = inputValue.trim()\n\n if (!trimmedMessage) {\n return\n }\n\n // Add user message to UI immediately\n const userMessage: Message = {\n id: `temp-${Date.now()}`,\n content: trimmedMessage,\n author_type: 'customer',\n author_name: 'You',\n created_at: new Date().toISOString(),\n is_private: false,\n }\n\n this.setState({\n messages: [...this.state.messages, userMessage],\n inputValue: '',\n isLoading: true,\n error: null,\n })\n\n try {\n await this.props.onSendMessage(trimmedMessage)\n // Success - message will be updated via addMessage()\n this.setState({ isLoading: false })\n } catch (error) {\n logger.error('Failed to send message', error)\n this.setState((prevState) => ({\n isLoading: false,\n error: error instanceof Error ? error.message : 'Failed to send message',\n messages: prevState.messages.filter((m) => m.id !== userMessage.id),\n }))\n }\n }\n\n /**\n * Public method to add messages from outside\n */\n addMessages(messages: Message[]) {\n this.setState((prevState) => {\n // Filter out duplicates\n const existingIds = new Set(prevState.messages.map((m) => m.id))\n const newMessages = messages.filter((m) => !existingIds.has(m.id))\n\n if (newMessages.length > 0) {\n return {\n messages: [...prevState.messages, ...newMessages],\n }\n }\n return null\n })\n }\n\n /**\n * Public method to show the widget\n */\n show() {\n this.setState({ state: 'open' })\n }\n\n /**\n * Public method to hide the widget\n */\n hide() {\n this.setState({ state: 'closed' })\n }\n\n /**\n * Get user traits (either provided via form or from props)\n */\n getUserTraits(): UserProvidedTraits | null {\n return this.state.userTraits\n }\n\n /**\n * Called when user identifies via posthog.identify()\n * Navigates away from identification form since we now know who they are\n */\n setUserIdentified(): void {\n if (this.state.view === 'identification') {\n const nextView = this.state.showTicketList ? 'tickets' : 'messages'\n this.setState({ view: nextView })\n if (this.props.onViewChange) {\n this.props.onViewChange(nextView)\n }\n }\n }\n\n /**\n * Set the unread message count (called by manager)\n */\n setUnreadCount(count: number): void {\n this.setState({ unreadCount: count })\n }\n\n /**\n * Update the tickets list (called by manager during polling)\n */\n updateTickets(tickets: Ticket[], showTicketList: boolean): void {\n this.setState({\n tickets,\n ticketsLoading: false,\n showTicketList,\n })\n }\n\n /**\n * Set whether the current ticket (if any) is in the resolved state.\n * Called by the manager whenever the current ticket or tickets list changes.\n */\n setCurrentTicketResolved(resolved: boolean): void {\n this.setState({ isCurrentTicketResolved: resolved })\n }\n\n /**\n * Set the current view (tickets list or messages)\n */\n setView(view: WidgetView): void {\n this.setState({ view })\n if (this.props.onViewChange) {\n this.props.onViewChange(view)\n }\n }\n\n /**\n * Get the current view\n */\n getView(): WidgetView {\n return this.state.view\n }\n\n /**\n * Set tickets loading state\n */\n setTicketsLoading(loading: boolean): void {\n this.setState({ ticketsLoading: loading })\n }\n\n /**\n * Update identity mode state (called by manager on setIdentity/clearIdentity)\n */\n setIdentityMode(isIdentityMode: boolean): void {\n let nextView: WidgetView | undefined\n this.setState(\n (prevState) => {\n const update: Partial<WidgetState> = { isIdentityMode }\n const viewNeedsReset =\n prevState.view === 'identification' ||\n prevState.view === 'restore_request' ||\n prevState.view === 'messages'\n if (viewNeedsReset) {\n nextView = prevState.showTicketList ? 'tickets' : 'messages'\n update.view = nextView\n }\n return update as WidgetState\n },\n () => {\n if (nextView && this.props.onViewChange) {\n this.props.onViewChange(nextView)\n }\n }\n )\n }\n\n /**\n * Clear messages (used when switching tickets or starting new conversation)\n * @param addGreeting - If true, adds the greeting message after clearing\n */\n clearMessages(addGreeting: boolean = false): void {\n this.setState({ messages: [] }, () => {\n if (addGreeting && this.props.config.greetingText) {\n this._addGreetingMessage()\n }\n })\n }\n\n private _renderIdentificationForm(styles: ReturnType<typeof getStyles>) {\n return (\n <IdentificationFormView\n config={this.props.config}\n styles={styles}\n formName={this.state.formName}\n formEmail={this.state.formEmail}\n formEmailError={this.state.formEmailError}\n onNameChange={this._handleFormNameChange}\n onEmailChange={this._handleFormEmailChange}\n onSubmit={this._handleFormSubmit}\n />\n )\n }\n\n private _renderBackButton(styles: ReturnType<typeof getStyles>) {\n const onClick =\n this.state.view === 'restore_request' ? this._handleCloseRestoreRequest : this._handleBackToTickets\n return (\n <button style={styles.backButton} onClick={onClick} aria-label=\"Back to conversations\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polyline points=\"15 18 9 12 15 6\" />\n </svg>\n </button>\n )\n }\n\n private _renderTicketList(styles: ReturnType<typeof getStyles>) {\n const { tickets, ticketsLoading } = this.state\n\n return (\n <TicketListView\n tickets={tickets}\n isLoading={ticketsLoading}\n styles={styles}\n onSelectTicket={this._handleSelectTicket}\n onNewConversation={this._handleNewConversation}\n onOpenRestoreRequest={this._handleOpenRestoreRequest}\n />\n )\n }\n\n private _renderMessages(styles: ReturnType<typeof getStyles>, primaryColor: string, placeholderText: string) {\n return (\n <MessagesView\n styles={styles}\n primaryColor={primaryColor}\n placeholderText={placeholderText}\n messages={this.state.messages}\n inputValue={this.state.inputValue}\n isLoading={this.state.isLoading}\n error={this.state.error}\n isResolved={this.state.isCurrentTicketResolved}\n onInputChange={this._handleInputChange}\n onKeyDown={this._handleKeyPress}\n onSendMessage={this._handleSendMessage}\n onStartNewConversation={this._handleNewConversation}\n messagesEndRef={(el) => {\n this._messagesEndRef = el\n }}\n />\n )\n }\n\n private _renderRestoreRequestView(styles: ReturnType<typeof getStyles>) {\n return (\n <RestoreRequestView\n styles={styles}\n restoreEmail={this.state.restoreEmail}\n restoreEmailError={this.state.restoreEmailError}\n restoreRequestLoading={this.state.restoreRequestLoading}\n restoreRequestSuccess={this.state.restoreRequestSuccess}\n onEmailChange={this._handleRestoreEmailChange}\n onSubmit={this._handleRestoreRequestSubmit}\n />\n )\n }\n\n /**\n * Get the title for the current view\n */\n private _getTitle(view: WidgetView): string {\n switch (view) {\n case 'tickets':\n return 'Conversations'\n case 'restore_request':\n return 'Restore conversations'\n case 'identification':\n return 'Support chat'\n case 'messages':\n return 'Support chat'\n }\n }\n\n /**\n * Render the content for the current view\n */\n private _renderViewContent(\n styles: ReturnType<typeof getStyles>,\n primaryColor: string,\n placeholderText: string\n ): h.JSX.Element {\n switch (this.state.view) {\n case 'identification':\n return this._renderIdentificationForm(styles)\n case 'restore_request':\n return this._renderRestoreRequestView(styles)\n case 'tickets':\n return this._renderTicketList(styles)\n case 'messages':\n return this._renderMessages(styles, primaryColor, placeholderText)\n }\n }\n\n render() {\n const { config } = this.props\n const { state, view } = this.state\n const primaryColor = config.color || '#5375ff'\n const widgetPosition = config.widgetPosition || 'bottom_right'\n const placeholderText = config.placeholderText || 'Type your message...'\n const styles = getStyles(primaryColor, widgetPosition)\n\n // Button only (closed state)\n if (state === 'closed') {\n return (\n <OpenChatButton\n primaryColor={primaryColor}\n position={widgetPosition}\n handleToggleOpen={this._handleToggleOpen}\n unreadCount={this.state.unreadCount}\n />\n )\n }\n\n // Open state\n const windowStyle = {\n ...styles.window,\n ...styles.windowOpen,\n }\n\n // Show back button in message view when the ticket list is available, or in restore request view\n const showBackButton = (view === 'messages' && this.state.showTicketList) || view === 'restore_request'\n\n // Show recover footer only in tickets and messages views, and not in identity mode\n const showRecoverFooter = !this.state.isIdentityMode && (view === 'tickets' || view === 'messages')\n\n return (\n <div style={styles.widget}>\n <div style={windowStyle}>\n <div style={styles.header}>\n <div style={showBackButton ? styles.headerWithBack : styles.headerTitle}>\n {showBackButton && this._renderBackButton(styles)}\n <span style={styles.headerTitle}>{this._getTitle(view)}</span>\n </div>\n <div style={styles.headerActions}>\n <CloseChatButton primaryColor={primaryColor} handleClose={this._handleClose} />\n </div>\n </div>\n\n {this._renderViewContent(styles, primaryColor, placeholderText)}\n\n {showRecoverFooter && (\n <div style={styles.recoverFooter}>\n Don't see your previous tickets?{' '}\n <button\n type=\"button\"\n style={styles.recoverFooterLink}\n onClick={this._handleOpenRestoreRequest}\n >\n Recover them here\n </button>\n </div>\n )}\n </div>\n </div>\n )\n }\n}\n","import { each } from './'\n\nimport { isArray, isFile, isUndefined } from '@posthog/core'\nimport { logger } from './logger'\nimport { document } from './globals'\n\nconst localDomains = ['localhost', '127.0.0.1']\n\n/**\n * IE11 doesn't support `new URL`\n * so we can create an anchor element and use that to parse the URL\n * there's a lot of overlap between HTMLHyperlinkElementUtils and URL\n * meaning useful properties like `pathname` are available on both\n */\nexport const convertToURL = (url: string): HTMLAnchorElement | null => {\n const location = document?.createElement('a')\n if (isUndefined(location)) {\n return null\n }\n\n location.href = url\n return location\n}\n\nexport const formDataToQuery = function (formdata: Record<string, any> | FormData, arg_separator = '&'): string {\n let use_val: string\n let use_key: string\n const tph_arr: string[] = []\n\n each(formdata, function (val: File | string | undefined, key: string | undefined) {\n // the key might be literally the string undefined for e.g. if {undefined: 'something'}\n if (isUndefined(val) || isUndefined(key) || key === 'undefined') {\n return\n }\n\n use_val = encodeURIComponent(isFile(val) ? val.name : val.toString())\n use_key = encodeURIComponent(key)\n tph_arr[tph_arr.length] = use_key + '=' + use_val\n })\n\n return tph_arr.join(arg_separator)\n}\n\nexport const getQueryParam = function (url: string, param: string): string {\n const withoutHash: string = url.split('#')[0] || ''\n\n // Split only on the first ? to sort problem out for those with multiple ?s\n // and then remove them\n const queryParams: string = withoutHash.split(/\\?(.*)/)[1] || ''\n const cleanedQueryParams = queryParams.replace(/^\\?+/g, '')\n\n const queryParts = cleanedQueryParams.split('&')\n let keyValuePair\n\n for (let i = 0; i < queryParts.length; i++) {\n const parts = queryParts[i].split('=')\n if (parts[0] === param) {\n keyValuePair = parts\n break\n }\n }\n\n if (!isArray(keyValuePair) || keyValuePair.length < 2) {\n return ''\n } else {\n let result = keyValuePair[1]\n try {\n result = decodeURIComponent(result)\n } catch {\n logger.error('Skipping decoding for malformed query param: ' + result)\n }\n return result.replace(/\\+/g, ' ')\n }\n}\n\n// replace any query params in the url with the provided mask value. Tries to keep the URL as instant as possible,\n// including preserving malformed text in most cases\nexport const maskQueryParams = function <T extends string | undefined>(\n url: T,\n maskedParams: string[] | undefined,\n mask: string\n): T extends string ? string : undefined {\n if (!url || !maskedParams || !maskedParams.length) {\n return url as any\n }\n\n const splitHash = url.split('#')\n const withoutHash: string = splitHash[0] || ''\n const hash = splitHash[1]\n\n const splitQuery: string[] = withoutHash.split('?')\n const queryString: string = splitQuery[1]\n const urlWithoutQueryAndHash: string = splitQuery[0]\n const queryParts = (queryString || '').split('&')\n\n // use an array of strings rather than an object to preserve ordering and duplicates\n const paramStrings: string[] = []\n\n for (let i = 0; i < queryParts.length; i++) {\n const keyValuePair = queryParts[i].split('=')\n if (!isArray(keyValuePair)) {\n continue\n } else if (maskedParams.includes(keyValuePair[0])) {\n paramStrings.push(keyValuePair[0] + '=' + mask)\n } else {\n paramStrings.push(queryParts[i])\n }\n }\n\n let result = urlWithoutQueryAndHash\n if (queryString != null) {\n result += '?' + paramStrings.join('&')\n }\n if (hash != null) {\n result += '#' + hash\n }\n\n return result as any\n}\n\nexport const _getHashParam = function (hash: string, param: string): string | null {\n const matches = hash.match(new RegExp(param + '=([^&]*)'))\n return matches ? matches[1] : null\n}\n\nexport const isLocalhost = (): boolean => {\n return localDomains.includes(location.hostname)\n}\n","import { PostHogConfig, Properties } from '../types'\nimport { logger } from './logger'\nimport { isFormData, isNullish, isNumber, isString, hasOwnProperty, isArray } from '@posthog/core'\n\nexport function find<T>(value: T[], predicate: (value: T) => boolean): T | undefined {\n for (let i = 0; i < value.length; i++) {\n if (predicate(value[i])) {\n return value[i]\n }\n }\n return undefined\n}\n\nexport function eachArray<E = any>(obj: E[] | null | undefined, iterator: (value: E, key: number) => void): void {\n if (isArray(obj)) {\n obj.forEach(iterator)\n }\n}\n\nexport function each(obj: any, iterator: (value: any, key: any) => void): void {\n if (isNullish(obj)) {\n return\n }\n if (isArray(obj)) {\n obj.forEach(iterator)\n return\n }\n if (isFormData(obj)) {\n obj.forEach((val: any, key: any) => iterator(val, key))\n return\n }\n for (const key in obj) {\n if (hasOwnProperty.call(obj, key)) {\n iterator(obj[key], key)\n }\n }\n}\n\nexport const extend = function (obj: Record<string, any>, ...args: Record<string, any>[]): Record<string, any> {\n for (const source of args) {\n for (const prop in source) {\n if (source[prop] !== void 0) {\n obj[prop] = source[prop]\n }\n }\n }\n return obj\n}\n\n/**\n * Object.entries() polyfill\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries\n */\nexport function entries<T = any>(obj: Record<string, T>): [string, T][] {\n const ownProps = Object.keys(obj)\n let i = ownProps.length\n const resArray = new Array(i) // preallocate the Array\n\n while (i--) {\n resArray[i] = [ownProps[i], obj[ownProps[i]]]\n }\n return resArray\n}\n\nexport const trySafe = function <T>(fn: () => T): T | undefined {\n try {\n return fn()\n } catch {\n return undefined\n }\n}\n\nexport const safewrap = function <F extends (...args: any[]) => any = (...args: any[]) => any>(f: F): F {\n return function (...args) {\n try {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return f.apply(this, args)\n } catch (e) {\n logger.critical(\n 'Implementation error. Please turn on debug mode and open a ticket on https://app.posthog.com/home#panel=support%3Asupport%3A.'\n )\n logger.critical(e)\n }\n } as F\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const safewrapClass = function (klass: Function, functions: string[]): void {\n for (let i = 0; i < functions.length; i++) {\n klass.prototype[functions[i]] = safewrap(klass.prototype[functions[i]])\n }\n}\n\nexport const stripEmptyProperties = function (p: Properties): Properties {\n const ret: Properties = {}\n each(p, function (v, k) {\n if ((isString(v) && v.length > 0) || isNumber(v)) {\n ret[k] = v\n }\n })\n return ret\n}\n\n/**\n * Deep copies an object.\n * It handles cycles by replacing all references to them with `undefined`\n * Also supports customizing native values\n *\n * @param value\n * @param customizer\n * @returns {{}|undefined|*}\n */\nfunction deepCircularCopy<T extends Record<string, any> = Record<string, any>>(\n value: T,\n customizer?: <K extends keyof T = keyof T>(value: T[K], key?: K) => T[K]\n): T | undefined {\n const COPY_IN_PROGRESS_SET = new Set()\n\n function internalDeepCircularCopy(value: T, key?: string): T | undefined {\n if (value !== Object(value)) return customizer ? customizer(value as any, key) : value // primitive value\n\n if (COPY_IN_PROGRESS_SET.has(value)) return undefined\n COPY_IN_PROGRESS_SET.add(value)\n let result: T\n\n if (isArray(value)) {\n result = [] as any as T\n eachArray(value, (it) => {\n result.push(internalDeepCircularCopy(it))\n })\n } else {\n result = {} as T\n each(value, (val, key) => {\n if (!COPY_IN_PROGRESS_SET.has(val)) {\n ;(result as any)[key] = internalDeepCircularCopy(val, key)\n }\n })\n }\n return result\n }\n return internalDeepCircularCopy(value)\n}\n\nexport function _copyAndTruncateStrings<T extends Record<string, any> = Record<string, any>>(\n object: T,\n maxStringLength: number\n): T {\n return deepCircularCopy(object, (value: any) => {\n if (isString(value)) {\n return (value as string).slice(0, maxStringLength)\n }\n return value\n }) as T\n}\n\n// NOTE: Update PostHogConfig docs if you change this list\n// We will not try to catch all bullets here, but we should make an effort to catch the most common ones\n// You should be highly against adding more to this list, because ultimately customers can configure\n// their `cross_subdomain_cookie` setting to anything they want.\nconst EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE = ['herokuapp.com', 'vercel.app', 'netlify.app']\nexport function isCrossDomainCookie(documentLocation: Location | undefined) {\n const hostname = documentLocation?.hostname\n\n if (!isString(hostname)) {\n return false\n }\n // split and slice isn't a great way to match arbitrary domains,\n // but it's good enough for ensuring we only match herokuapp.com when it is the TLD\n // for the hostname\n const lastTwoParts = hostname.split('.').slice(-2).join('.')\n\n for (const excluded of EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE) {\n if (lastTwoParts === excluded) {\n return false\n }\n }\n\n return true\n}\n\n// Use this instead of element.addEventListener to avoid eslint errors\n// this properly implements the default options for passive event listeners\nexport function addEventListener(\n element: Window | Document | Element | undefined,\n event: string,\n callback: EventListener,\n options?: AddEventListenerOptions\n): void {\n const { capture = false, passive = true } = options ?? {}\n\n // This is the only place where we are allowed to call this function\n // because the whole idea is that we should be calling this instead of the built-in one\n // eslint-disable-next-line posthog-js/no-add-event-listener\n element?.addEventListener(event, callback, { capture, passive })\n}\n\n/**\n * Helper to migrate deprecated config fields to new field names with appropriate warnings\n * @param config - The config object to check\n * @param newField - The new field name to use\n * @param oldField - The deprecated field name to check for\n * @param defaultValue - The default value if neither field is set\n * @param loggerInstance - Optional logger instance for deprecation warnings\n * @returns The value to use (new field takes precedence over old field)\n */\nexport function migrateConfigField<T>(\n config: Record<string, any>,\n newField: string,\n oldField: string,\n defaultValue: T,\n loggerInstance?: { warn: (message: string) => void }\n): T {\n const hasNewField = newField in config && !isNullish(config[newField])\n const hasOldField = oldField in config && !isNullish(config[oldField])\n\n if (hasNewField) {\n return config[newField]\n }\n\n if (hasOldField) {\n if (loggerInstance) {\n loggerInstance.warn(\n `Config field '${oldField}' is deprecated. Please use '${newField}' instead. ` +\n `The old field will be removed in a future major version.`\n )\n }\n return config[oldField]\n }\n\n return defaultValue\n}\n\nconst TOOLBAR_INTERNAL_INSTANCE_NAME = 'ph_toolbar_internal'\n\nexport function isToolbarInstance(config: Pick<PostHogConfig, 'name'>): boolean {\n return config.name === TOOLBAR_INTERNAL_INSTANCE_NAME\n}\n","import { createLogger } from '../../../utils/logger'\nimport { window } from '../../../utils/globals'\n\nconst logger = createLogger('[ConversationsManager]')\n\nexport const RESTORE_QUERY_PARAM = 'ph_conv_restore'\n\n/**\n * Extract hostname from a domain string (handles URLs and plain hostnames)\n */\nfunction extractHostname(domain: string): string | null {\n let hostname = domain.replace(/^https?:\\/\\//, '')\n hostname = hostname.split('/')[0].split('?')[0].split(':')[0]\n return hostname || null\n}\n\n/**\n * Check if the current domain matches the allowed domains list.\n * Returns true if:\n * - domains is empty or not present (no restriction)\n * - current hostname matches any allowed domain\n */\nexport function isCurrentDomainAllowed(domains: string[] | undefined): boolean {\n if (!domains || domains.length === 0) {\n return true\n }\n\n const currentHostname = window?.location?.hostname\n if (!currentHostname) {\n return true\n }\n\n return domains.some((domain) => {\n const allowedHostname = extractHostname(domain)\n if (!allowedHostname) {\n return false\n }\n\n if (allowedHostname.startsWith('*.')) {\n const pattern = allowedHostname.slice(2)\n return currentHostname.endsWith(`.${pattern}`) || currentHostname === pattern\n }\n\n return currentHostname === allowedHostname\n })\n}\n\nexport function getRestoreTokenFromUrl(): string | null {\n if (!window?.location?.search) {\n return null\n }\n\n try {\n // eslint-disable-next-line compat/compat\n const params = new URLSearchParams(window.location.search)\n const token = params.get(RESTORE_QUERY_PARAM)\n return token?.trim() || null\n } catch (error) {\n logger.warn('Failed to parse restore token from URL', error)\n return null\n }\n}\n\nexport function clearRestoreTokenFromUrl(): void {\n if (!window?.location || !window?.history?.replaceState) {\n return\n }\n\n try {\n // eslint-disable-next-line compat/compat\n const url = new URL(window.location.href)\n url.searchParams.delete(RESTORE_QUERY_PARAM)\n const newUrl = `${url.pathname}${url.search}${url.hash}`\n window.history.replaceState(window.history.state, '', newUrl)\n } catch (error) {\n logger.warn('Failed to clear restore token from URL', error)\n }\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { render, h } from 'preact'\nimport { isNumber, isNull } from '@posthog/core'\nimport {\n ConversationsRemoteConfig,\n ConversationsWidgetState,\n UserProvidedTraits,\n SendMessageResponse,\n SendMessagePayload,\n GetMessagesResponse,\n MarkAsReadResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n Ticket,\n RestoreFromTokenPayload,\n RestoreFromTokenResponse,\n RequestRestoreLinkPayload,\n RequestRestoreLinkResponse,\n TicketStatus,\n} from '../../../posthog-conversations-types'\nimport { PostHog } from '../../../posthog-core'\nimport { STORED_PERSON_PROPERTIES_KEY } from '../../../constants'\nimport { ConversationsManager as ConversationsManagerInterface } from '../posthog-conversations'\nimport { ConversationsPersistence } from './persistence'\nimport { ConversationsWidget, WidgetView } from './components/ConversationsWidget'\nimport { createLogger } from '../../../utils/logger'\nimport { document, window } from '../../../utils/globals'\nimport { formDataToQuery } from '../../../utils/request-utils'\nimport { isCurrentDomainAllowed, getRestoreTokenFromUrl, clearRestoreTokenFromUrl } from './url-utils'\n\nconst logger = createLogger('[ConversationsManager]')\n\nconst WIDGET_CONTAINER_ID = 'ph-conversations-widget-container'\nconst POLL_INTERVAL_MS = 5000 // 5 seconds\nconst RESTORE_EXCHANGE_ENDPOINT = '/api/conversations/v1/widget/restore'\nconst RESTORE_REQUEST_ENDPOINT = '/api/conversations/v1/widget/restore/request'\n\n// Singleton guard: only one ConversationsManager per page.\n// The toolbar's internal PostHog instance is excluded from creating a manager\n// (see PostHogConversations.loadIfEnabled), so this always belongs to the main instance.\nlet _activeManager: ConversationsManager | null = null\n\nexport class ConversationsManager implements ConversationsManagerInterface {\n private _config: ConversationsRemoteConfig\n private _persistence: ConversationsPersistence\n private _widgetRef: ConversationsWidget | null = null\n private _containerElement: HTMLDivElement | null = null\n private _currentTicketId: string | null = null\n private _pollIntervalId: number | null = null\n private _lastMessageTimestamp: string | null = null\n private _isPollingMessages: boolean = false\n private _isPollingTickets: boolean = false\n private _unsubscribeIdentifyListener: (() => void) | null = null\n private _unreadCount: number = 0\n // SECURITY: widget_session_id is the key for access control\n // This is a random UUID that only this browser knows\n private _widgetSessionId: string\n private _isWidgetEnabled: boolean\n private _isDomainAllowed: boolean\n private _widgetState: ConversationsWidgetState = 'closed'\n private _isWidgetRendered: boolean = false\n private _hasProcessedRestoreToken: boolean = false\n private _initializeWidgetPromise: Promise<void> | null = null\n // View state management for ticket list vs message view\n private _currentView: WidgetView = 'messages'\n private _tickets: Ticket[] = []\n private _showTicketList: boolean = false\n\n constructor(\n config: ConversationsRemoteConfig,\n private readonly _posthog: PostHog\n ) {\n this._config = config\n this._persistence = new ConversationsPersistence(_posthog)\n\n this._widgetSessionId = this._persistence.getOrCreateWidgetSessionId()\n\n // Determine if widget should be shown based on config and domain\n this._isWidgetEnabled = config.widgetEnabled === true\n this._isDomainAllowed = isCurrentDomainAllowed(config.domains)\n\n this._initialize()\n }\n\n /**\n * Send a message programmatically via the API\n * Creates a new ticket if none exists or if newTicket is true\n *\n * @param message - The message text to send\n * @param userTraits - Optional user identification data (name, email)\n * @param newTicket - If true, forces creation of a new ticket (ignores current ticket)\n * @returns Promise with the response including ticket_id and message_id\n */\n async sendMessage(\n message: string,\n userTraits?: UserProvidedTraits,\n newTicket?: boolean\n ): Promise<SendMessageResponse> {\n // Determine which ticket to use\n // If newTicket is true, force creation of new ticket by sending null\n // Otherwise use current ticket ID (which may be null if no ticket exists yet)\n const ticketId = newTicket ? null : this._currentTicketId\n\n // Track if this is creating a new ticket\n const isNewTicket = !ticketId\n\n const token = this._config.token\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n const personTraits = this._getPersonTraits()\n\n const name = userTraits?.name || personTraits.name || null\n const email = userTraits?.email || personTraits.email || null\n\n const identity = this._identityFields()\n const payload: Partial<SendMessagePayload> = {\n message: message.trim(),\n traits: {\n name,\n email,\n },\n ticket_id: ticketId,\n }\n\n if (identity) {\n payload.identity_distinct_id = identity.identity_distinct_id\n payload.identity_hash = identity.identity_hash\n payload.distinct_id = identity.identity_distinct_id\n } else {\n payload.widget_session_id = this._widgetSessionId\n payload.distinct_id = this._posthog.get_distinct_id()\n }\n\n try {\n // Capture session ID - sent with every message\n const capturedSessionId = this._posthog.get_session_id()\n if (capturedSessionId) {\n payload.session_id = capturedSessionId\n }\n\n // Capture session replay URL with timestamp - sent with every message\n const replayUrl = this._posthog.get_session_replay_url({\n withTimestamp: true,\n timestampLookBack: 30,\n })\n\n // Capture current URL - only for new tickets to record where user started\n const currentUrl = isNewTicket ? window?.location?.href : undefined\n\n if (replayUrl || currentUrl) {\n payload.session_context = {\n session_replay_url: replayUrl || undefined,\n current_url: currentUrl || undefined,\n }\n }\n } catch (error) {\n // Log error but don't fail message sending\n logger.warn('Failed to capture session context', error)\n }\n\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor('api', '/api/conversations/v1/widget/message'),\n method: 'POST',\n data: payload,\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200 && response.statusCode !== 201) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to send message'\n logger.error('Failed to send message', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as SendMessageResponse\n\n // Update current ticket ID if this was a new ticket\n // This happens when: 1) No ticket existed, or 2) User forced new ticket creation\n if (isNewTicket && data.ticket_id) {\n this._currentTicketId = data.ticket_id\n this._persistence.saveTicketId(data.ticket_id)\n logger.info('New ticket created', {\n ticketId: data.ticket_id,\n forced: newTicket === true,\n })\n }\n\n // Track message sent\n this._posthog.capture('$conversations_message_sent', {\n ticketId: data.ticket_id,\n isNewTicket: isNewTicket,\n messageLength: message.length,\n })\n\n // Update last message timestamp\n this._lastMessageTimestamp = data.created_at\n\n resolve(data)\n },\n })\n })\n }\n\n /**\n * Switch to a different ticket if an explicit ticketId is provided\n * This ensures subsequent operations (sendMessage, etc.) use the correct ticket\n */\n private _switchToTicketIfNeeded(ticketId: string | undefined): void {\n if (ticketId && ticketId !== this._currentTicketId) {\n this._currentTicketId = ticketId\n this._persistence.saveTicketId(ticketId)\n // Reset last message timestamp when switching tickets\n this._lastMessageTimestamp = null\n }\n }\n\n /** Fetch messages via the API */\n async getMessages(ticketId?: string, after?: string): Promise<GetMessagesResponse> {\n // Use provided ticketId or fall back to current ticket\n const targetTicketId = ticketId || this._currentTicketId\n\n if (!targetTicketId) {\n throw new Error('No ticket ID provided and no active conversation')\n }\n\n // Switch to this ticket if explicitly provided\n this._switchToTicketIfNeeded(ticketId)\n\n const token = this._config.token\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n const identity = this._identityFields()\n const queryParams: Record<string, string> = {\n limit: '50',\n }\n\n if (identity) {\n queryParams.identity_distinct_id = identity.identity_distinct_id\n queryParams.identity_hash = identity.identity_hash\n } else {\n queryParams.widget_session_id = this._widgetSessionId\n }\n\n if (after) {\n queryParams.after = after\n }\n\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/messages/${targetTicketId}?${formDataToQuery(queryParams)}`\n ),\n method: 'GET',\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to fetch messages'\n logger.error('Failed to fetch messages', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as GetMessagesResponse\n resolve(data)\n },\n })\n })\n }\n\n /** Mark messages as read via the API */\n async markAsRead(ticketId?: string): Promise<MarkAsReadResponse> {\n // Use provided ticketId or fall back to current ticket\n const targetTicketId = ticketId || this._currentTicketId\n\n if (!targetTicketId) {\n throw new Error('No ticket ID provided and no active conversation')\n }\n\n // Switch to this ticket if explicitly provided\n this._switchToTicketIfNeeded(ticketId)\n\n const token = this._config.token\n\n logger.info('Marking messages as read', { ticketId: targetTicketId })\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n const identity = this._identityFields()\n const data = identity\n ? { identity_distinct_id: identity.identity_distinct_id, identity_hash: identity.identity_hash }\n : { widget_session_id: this._widgetSessionId }\n\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/messages/${targetTicketId}/read`\n ),\n method: 'POST',\n data,\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg =\n response.json?.detail || response.json?.message || 'Failed to mark messages as read'\n logger.error('Failed to mark messages as read', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const responseData = response.json as MarkAsReadResponse\n resolve(responseData)\n },\n })\n })\n }\n\n /**\n * Initialize the conversations manager.\n * Always initializes persistence and event listeners for API usage.\n * Only renders the widget if widgetEnabled is true AND domain is allowed.\n */\n private _initialize(): void {\n if (!document || !window) {\n logger.info('Conversations not available: Document or window not available')\n return\n }\n\n // In identity mode, restore is unnecessary and the persisted anonymous\n // ticket belongs to a different principal -- clear it before completing.\n if (this._identityFields()) {\n this._persistence.clearTicketId()\n this._completeInitialization()\n return\n }\n\n const restoreToken = getRestoreTokenFromUrl()\n if (restoreToken && !this._hasProcessedRestoreToken) {\n this._hasProcessedRestoreToken = true\n\n // Clear the token from the URL immediately, then again after a tick and\n // after the restore completes. SPA routers (Next.js, React Router, etc.)\n // maintain their own URL state and can overwrite a single replaceState call.\n clearRestoreTokenFromUrl()\n setTimeout(clearRestoreTokenFromUrl, 0)\n\n this._restoreFromTokenWithRetry(restoreToken)\n .catch((error) => {\n logger.warn('Failed to restore conversations from URL token', error)\n })\n .finally(() => {\n clearRestoreTokenFromUrl()\n this._completeInitialization()\n })\n return\n }\n\n this._completeInitialization()\n }\n\n private _completeInitialization(): void {\n this._hasProcessedRestoreToken = true\n\n // Load any existing ticket ID from localStorage\n this._currentTicketId = this._persistence.loadTicketId()\n logger.info('Loaded ticket ID from storage', { ticketId: this._currentTicketId })\n\n // Track conversations API loaded (separate from widget loaded)\n this._posthog.capture('$conversations_loaded', {\n hasExistingTicket: !!this._currentTicketId,\n widgetEnabled: this._isWidgetEnabled,\n domainAllowed: this._isDomainAllowed,\n })\n\n // Only render widget if both widgetEnabled and domain is allowed\n if (this._isWidgetEnabled && this._isDomainAllowed) {\n this._initializeWidget()\n } else {\n logger.info('Widget not rendered', {\n widgetEnabled: this._isWidgetEnabled,\n domainAllowed: this._isDomainAllowed,\n })\n }\n\n // Listen for identify events to hide identification form when user identifies\n this._setupIdentifyListener()\n }\n\n private async _restoreFromTokenWithRetry(restoreToken: string): Promise<RestoreFromTokenResponse> {\n try {\n return await this._restoreFromToken(restoreToken)\n } catch (error) {\n logger.warn('Restore token exchange failed, retrying once', error)\n return await this._restoreFromToken(restoreToken)\n }\n }\n\n private async _restoreFromToken(restoreToken: string): Promise<RestoreFromTokenResponse> {\n const token = this._config.token\n\n const payload: RestoreFromTokenPayload = {\n restore_token: restoreToken,\n widget_session_id: this._widgetSessionId,\n distinct_id: this._posthog.get_distinct_id(),\n current_url: window?.location?.href,\n }\n\n // eslint-disable-next-line compat/compat\n const data = await new Promise<RestoreFromTokenResponse>((resolve, reject) => {\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor('api', RESTORE_EXCHANGE_ENDPOINT),\n method: 'POST',\n data: payload,\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg =\n response.json?.error ||\n response.json?.detail ||\n response.json?.message ||\n 'Failed to restore conversations'\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n resolve(response.json as RestoreFromTokenResponse)\n },\n })\n })\n\n if (data.status !== 'success') {\n logger.info('Restore token was not accepted', { status: data.status, code: data.code })\n return data\n }\n\n this._lastMessageTimestamp = null\n this._unreadCount = 0\n\n // Apply the canonical widget_session_id from the server if provided\n if (data.widget_session_id) {\n this._widgetSessionId = data.widget_session_id\n this._persistence.setWidgetSessionId(data.widget_session_id)\n }\n\n if (data.migrated_ticket_ids?.length) {\n this._currentTicketId = data.migrated_ticket_ids[0]\n this._persistence.saveTicketId(this._currentTicketId)\n // Poll straight away so messages and ticket list are fresh\n void this._pollMessages()\n void this._pollTickets()\n } else {\n this._currentTicketId = null\n this._persistence.clearTicketId()\n }\n\n return data\n }\n\n /**\n * Initialize and render the widget UI\n * Uses a promise guard to prevent race conditions from concurrent calls\n */\n private _initializeWidget(): Promise<void> {\n if (this._isWidgetRendered) {\n return Promise.resolve()\n }\n if (this._initializeWidgetPromise) {\n return this._initializeWidgetPromise\n }\n this._initializeWidgetPromise = this._doInitializeWidget()\n return this._initializeWidgetPromise\n }\n\n private async _doInitializeWidget(): Promise<void> {\n const savedState = this._persistence.loadWidgetState()\n const initialState: ConversationsWidgetState = savedState === 'open' ? 'open' : 'closed'\n this._widgetState = initialState\n\n // Get initial user traits (from PostHog person properties or saved)\n const initialUserTraits = this._getInitialUserTraits()\n\n // Determine initial view based on ticket count\n const { view: initialView, tickets } = await this._determineInitialView()\n this._currentView = initialView\n\n // Render the widget with initial view\n this._renderWidget(initialState, initialUserTraits, initialView, tickets)\n this._isWidgetRendered = true\n\n this._posthog.capture('$conversations_widget_loaded', {\n hasExistingTicket: !!this._currentTicketId,\n initialState: initialState,\n initialView: initialView,\n ticketCount: tickets.length,\n hasUserTraits: !!initialUserTraits,\n })\n\n // Start polling — the first poll fires immediately and loads messages or tickets\n this._startPolling()\n }\n\n /**\n * Extract name and email from PostHog's stored person properties.\n *\n * Person properties set via posthog.identify() are stored under the\n * $stored_person_properties persistence key, not as top-level props.\n * We check both locations plus the super-properties for completeness.\n */\n private _getPersonTraits(): { name: string | undefined; email: string | undefined } {\n const superProps = this._posthog.persistence?.props || {}\n const storedPersonProps =\n (this._posthog.get_property(STORED_PERSON_PROPERTIES_KEY) as Record<string, any>) || {}\n\n const name =\n storedPersonProps.$name || storedPersonProps.name || superProps.$name || superProps.name || undefined\n const email =\n storedPersonProps.$email || storedPersonProps.email || superProps.$email || superProps.email || undefined\n\n return { name, email }\n }\n\n /**\n * Get initial user traits from PostHog or localStorage\n */\n private _getInitialUserTraits(): UserProvidedTraits | null {\n const { name, email } = this._getPersonTraits()\n\n if (name || email) {\n return {\n name: name || undefined,\n email: email || undefined,\n }\n }\n\n // Otherwise, check localStorage for previously saved traits\n const savedTraits = this._persistence.loadUserTraits()\n if (savedTraits && (savedTraits.name || savedTraits.email)) {\n return savedTraits\n }\n\n return null\n }\n\n /**\n * Handle user identification from the widget form\n */\n private _handleIdentify = (traits: UserProvidedTraits): void => {\n // Save traits to localStorage\n this._persistence.saveUserTraits(traits)\n\n // Track identification\n this._posthog.capture('$conversations_user_identified', {\n hasName: !!traits.name,\n hasEmail: !!traits.email,\n })\n }\n\n private _handleRequestRestoreLink = async (email: string): Promise<RequestRestoreLinkResponse> => {\n const response = await this.requestRestoreLink(email)\n this._posthog.capture('$conversations_restore_link_requested', {\n hasEmail: !!email,\n })\n return response\n }\n\n /**\n * Handle sending a message from the widget\n */\n private _handleSendMessage = async (message: string): Promise<void> => {\n // Get user traits from the widget\n const userTraits = this._widgetRef?.getUserTraits() || undefined\n\n try {\n // Call the public API method (which handles tracking and state updates)\n await this.sendMessage(message, userTraits)\n\n // Poll for response immediately\n setTimeout(() => this._pollMessages(), 1000)\n } catch (error) {\n logger.error('Failed to send message', error)\n throw error\n }\n }\n\n /**\n * Handle widget state changes\n */\n private _handleStateChange = (state: ConversationsWidgetState): void => {\n this._widgetState = state\n logger.info('Widget state changed', { state, view: this._currentView })\n\n this._posthog.capture('$conversations_widget_state_changed', {\n state: state,\n view: this._currentView,\n ticketId: this._currentTicketId,\n })\n\n this._persistence.saveWidgetState(state)\n\n // Mark messages as read when widget opens (only if in message view with a ticket)\n if (state === 'open') {\n if (this._currentView === 'messages' && this._unreadCount > 0 && this._currentTicketId) {\n this._markMessagesAsRead()\n }\n }\n }\n\n /**\n * Mark messages as read\n */\n private async _markMessagesAsRead(): Promise<void> {\n if (!this._currentTicketId) {\n return\n }\n\n try {\n const response = await this.markAsRead(this._currentTicketId)\n this._unreadCount = response.unread_count\n // Update the widget to reflect the new unread count\n this._widgetRef?.setUnreadCount(0)\n logger.info('Messages marked as read', { unreadCount: response.unread_count })\n } catch (error) {\n logger.error('Failed to mark messages as read', error)\n }\n }\n\n /**\n * Load messages for the current ticket\n */\n private async _loadMessages(): Promise<void> {\n if (!this._currentTicketId) {\n return\n }\n\n try {\n const identityBefore = this._posthog.config.identity_distinct_id\n const ticketBefore = this._currentTicketId\n const response = await this.getMessages(this._currentTicketId, this._lastMessageTimestamp || undefined)\n\n // Discard stale response if identity or ticket changed while in-flight\n if (\n this._posthog.config.identity_distinct_id !== identityBefore ||\n this._currentTicketId !== ticketBefore\n ) {\n return\n }\n\n // Update unread count from response\n if (isNumber(response.unread_count)) {\n this._unreadCount = response.unread_count\n this._widgetRef?.setUnreadCount(response.unread_count)\n\n // If widget is open and there are unread messages, mark them as read\n if (response.unread_count > 0 && this._isWidgetOpen()) {\n this._markMessagesAsRead()\n }\n }\n\n // Sync ticket_status so an agent-side resolve flips the UI to locked state even\n // while we're polling messages (ticket polling doesn't run in messages view).\n // Using ticketBefore (non-null, validated by the stale check above) avoids relying\n // on TS narrowing of the mutable this._currentTicketId field.\n if (response.ticket_status) {\n this._applyTicketStatusUpdate(ticketBefore, response.ticket_status)\n }\n\n if (response.messages.length > 0) {\n this._widgetRef?.addMessages(response.messages)\n // Update last message timestamp\n const lastMessage = response.messages[response.messages.length - 1]\n this._lastMessageTimestamp = lastMessage.created_at\n }\n } catch (error) {\n logger.error('Failed to load messages', error)\n }\n }\n\n private _isWidgetOpen(): boolean {\n return this._widgetState === 'open'\n }\n\n /**\n * Poll for new messages\n */\n private _pollMessages = async (): Promise<void> => {\n if (this._isPollingMessages || !this._currentTicketId) {\n return\n }\n\n this._isPollingMessages = true\n try {\n await this._loadMessages()\n } finally {\n this._isPollingMessages = false\n }\n }\n\n /**\n * Poll for tickets list\n */\n private _pollTickets = async (): Promise<void> => {\n if (this._isPollingTickets) {\n return\n }\n\n this._isPollingTickets = true\n try {\n await this._loadTickets()\n } finally {\n this._isPollingTickets = false\n }\n }\n\n /**\n * Load tickets list from API\n */\n private async _loadTickets(): Promise<void> {\n try {\n const response = await this.getTickets()\n this._tickets = response.results\n this._showTicketList = this._computeShowTicketList(response.results)\n this._widgetRef?.updateTickets(response.results, this._showTicketList)\n\n // Calculate total unread across all tickets\n const totalUnread = response.results.reduce((sum, t) => sum + (t.unread_count || 0), 0)\n this._unreadCount = totalUnread\n this._widgetRef?.setUnreadCount(totalUnread)\n\n this._widgetRef?.setCurrentTicketResolved(this._isCurrentTicketResolved())\n\n logger.info('Tickets loaded', { count: response.results.length, totalUnread })\n } catch (error) {\n logger.error('Failed to load tickets', error)\n }\n }\n\n private _computeShowTicketList(tickets: Ticket[]): boolean {\n if (tickets.length > 1) {\n return true\n }\n if (tickets.length === 1 && tickets[0].status === 'resolved') {\n return true\n }\n return false\n }\n\n private _isCurrentTicketResolved(): boolean {\n if (!this._currentTicketId) {\n return false\n }\n const ticket = this._tickets.find((t) => t.id === this._currentTicketId)\n return ticket?.status === 'resolved'\n }\n\n /**\n * Patch the local _tickets cache with a new status for a given ticket and push\n * any UI-relevant changes (resolved lock + list visibility) to the widget.\n */\n private _applyTicketStatusUpdate(ticketId: string, status: TicketStatus): void {\n const idx = this._tickets.findIndex((t) => t.id === ticketId)\n if (idx === -1) {\n return\n }\n if (this._tickets[idx].status === status) {\n return\n }\n this._tickets = [\n ...this._tickets.slice(0, idx),\n { ...this._tickets[idx], status },\n ...this._tickets.slice(idx + 1),\n ]\n this._showTicketList = this._computeShowTicketList(this._tickets)\n this._widgetRef?.updateTickets(this._tickets, this._showTicketList)\n this._widgetRef?.setCurrentTicketResolved(this._isCurrentTicketResolved())\n }\n\n /**\n * Main poll function that polls based on current view\n */\n private _poll = async (): Promise<void> => {\n if (this._currentView === 'restore_request') {\n return\n }\n\n if (this._currentView === 'messages') {\n await this._pollMessages()\n } else {\n await this._pollTickets()\n }\n }\n\n /**\n * Handle view changes from the widget\n */\n private _handleViewChange = (view: WidgetView): void => {\n logger.info('View changed', { from: this._currentView, to: view })\n this._currentView = view\n }\n\n /**\n * Handle ticket selection from the list\n */\n private _handleSelectTicket = async (ticketId: string): Promise<void> => {\n // Switch to this ticket\n this._switchToTicketIfNeeded(ticketId)\n\n // Clear messages and reset timestamp\n this._lastMessageTimestamp = null\n this._widgetRef?.clearMessages()\n\n // Switch view to messages\n this._currentView = 'messages'\n this._widgetRef?.setView('messages')\n\n // Push resolved state for this ticket so MessagesView locks the input if needed\n this._widgetRef?.setCurrentTicketResolved(this._isCurrentTicketResolved())\n\n // Load messages for the selected ticket\n await this._loadMessages()\n\n // Mark as read if widget is open\n if (this._isWidgetOpen() && this._unreadCount > 0) {\n this._markMessagesAsRead()\n }\n }\n\n /**\n * Handle new conversation request\n */\n private _handleNewConversation = (): void => {\n logger.info('New conversation requested')\n\n // Clear current ticket\n this._currentTicketId = null\n this._persistence.clearTicketId()\n\n // Reset timestamp\n this._lastMessageTimestamp = null\n\n // Switch view to messages\n this._currentView = 'messages'\n this._widgetRef?.setView('messages')\n\n // Fresh ticket is never resolved — unlock the input\n this._widgetRef?.setCurrentTicketResolved(false)\n\n // Clear messages and add greeting\n this._widgetRef?.clearMessages(true)\n }\n\n /**\n * Handle back to tickets request\n */\n private _handleBackToTickets = async (): Promise<void> => {\n logger.info('Back to tickets requested')\n\n // Switch view to tickets\n this._currentView = 'tickets'\n this._widgetRef?.setView('tickets')\n\n // Load tickets\n this._widgetRef?.setTicketsLoading(true)\n await this._loadTickets()\n\n // Track back to tickets\n this._posthog.capture('$conversations_back_to_tickets')\n }\n\n /**\n * Determine initial view based on ticket count\n */\n private async _determineInitialView(): Promise<{ view: WidgetView; tickets: Ticket[] }> {\n try {\n const identityBefore = this._posthog.config.identity_distinct_id\n const response = await this.getTickets()\n\n // If identity changed while the request was in-flight, discard this\n // stale response -- setIdentity/clearIdentity already triggered a\n // fresh _loadTicketsAndReconcileView() with the correct credentials.\n if (this._posthog.config.identity_distinct_id !== identityBefore) {\n return { view: 'messages', tickets: [] }\n }\n\n const view = this._applyTicketsToState(response.results)\n return { view, tickets: response.results }\n } catch (error) {\n logger.error('Failed to determine initial view', error)\n return { view: 'messages', tickets: [] }\n }\n }\n\n /**\n * Apply a fetched ticket list to internal state and return the appropriate view.\n * Shared by _determineInitialView (widget boot) and _loadTicketsAndReconcileView\n * (identity change at runtime).\n */\n private _applyTicketsToState(tickets: Ticket[]): WidgetView {\n this._tickets = tickets\n this._showTicketList = this._computeShowTicketList(tickets)\n\n const totalUnread = tickets.reduce((sum, t) => sum + (t.unread_count || 0), 0)\n this._unreadCount = totalUnread\n\n if (tickets.length >= 2) {\n this._currentTicketId = null\n return 'tickets'\n }\n\n // Single resolved ticket: show list so user can start a new conversation instead of writing to it\n if (tickets.length === 1 && tickets[0].status === 'resolved') {\n this._currentTicketId = null\n this._persistence.clearTicketId()\n return 'tickets'\n }\n\n if (tickets.length === 1) {\n this._currentTicketId = tickets[0].id\n this._persistence.saveTicketId(tickets[0].id)\n }\n\n return 'messages'\n }\n\n /**\n * Start polling based on current view\n */\n private _startPolling(): void {\n if (this._pollIntervalId) {\n return // Already polling\n }\n\n // Poll immediately\n this._poll()\n\n // Set up interval\n this._pollIntervalId = window?.setInterval(() => {\n this._poll()\n }, POLL_INTERVAL_MS) as unknown as number\n\n logger.info('Started polling', { view: this._currentView })\n }\n\n /**\n * Stop polling for new messages\n */\n private _stopPolling(): void {\n if (this._pollIntervalId) {\n window?.clearInterval(this._pollIntervalId)\n this._pollIntervalId = null\n logger.info('Stopped polling for messages')\n }\n }\n\n /**\n * Setup listener for identify events.\n * When user calls posthog.identify(), hide the identification form\n * since we now know who they are.\n */\n private _setupIdentifyListener(): void {\n this._unsubscribeIdentifyListener = this._posthog.on('eventCaptured', (event: any) => {\n if (event.event === '$identify') {\n // User just identified - hide the identification form if it's showing\n this._widgetRef?.setUserIdentified()\n }\n })\n }\n\n /**\n * Show the widget (render it to DOM).\n * The widget respects its saved state (open/closed).\n * Note: Domain restrictions still apply - widget won't render on disallowed domains.\n */\n show(): void {\n // Check domain restrictions - don't render on disallowed domains\n if (!this._isDomainAllowed) {\n logger.warn('Cannot show widget: current domain is not allowed')\n return\n }\n\n // If widget isn't rendered yet, render it now\n if (!this._isWidgetRendered) {\n this._initializeWidget()\n }\n }\n\n /**\n * Hide and remove the widget from the DOM.\n * Conversation data is preserved - call show() to re-render.\n */\n hide(): void {\n // Stop polling when widget is hidden (save resources)\n this._stopPolling()\n\n if (this._containerElement) {\n render(null, this._containerElement)\n this._containerElement.remove()\n this._containerElement = null\n }\n this._widgetRef = null\n this._isWidgetRendered = false\n this._initializeWidgetPromise = null\n\n // Reset timestamp so show() will re-fetch all messages\n this._lastMessageTimestamp = null\n }\n\n /**\n * Check if the widget is currently visible (rendered in DOM)\n */\n isVisible(): boolean {\n return this._isWidgetRendered\n }\n\n /** Get tickets list for the current widget session or verified identity */\n async getTickets(options?: GetTicketsOptions): Promise<GetTicketsResponse> {\n const token = this._config.token\n\n const identity = this._identityFields()\n const queryParams: Record<string, string> = {\n limit: String(options?.limit ?? 20),\n offset: String(options?.offset ?? 0),\n }\n\n if (identity) {\n queryParams.identity_distinct_id = identity.identity_distinct_id\n queryParams.identity_hash = identity.identity_hash\n } else {\n queryParams.widget_session_id = this._widgetSessionId\n }\n\n if (options?.status) {\n queryParams.status = options.status\n }\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor(\n 'api',\n `/api/conversations/v1/widget/tickets?${formDataToQuery(queryParams)}`\n ),\n method: 'GET',\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg = response.json?.detail || response.json?.message || 'Failed to fetch tickets'\n logger.error('Failed to fetch tickets', { status: response.statusCode })\n reject(new Error(errorMsg))\n return\n }\n\n if (!response.json) {\n reject(new Error('Invalid response from server'))\n return\n }\n\n const data = response.json as GetTicketsResponse\n resolve(data)\n },\n })\n })\n }\n\n async requestRestoreLink(email: string): Promise<RequestRestoreLinkResponse> {\n if (this._identityFields()) {\n return { ok: true }\n }\n\n const normalizedEmail = email.trim().toLowerCase()\n if (!normalizedEmail) {\n throw new Error('Email is required')\n }\n\n const token = this._config.token\n const payload: RequestRestoreLinkPayload = {\n email: normalizedEmail,\n request_url: window?.location?.href || '',\n }\n\n // eslint-disable-next-line compat/compat\n return new Promise((resolve, reject) => {\n this._posthog._send_request({\n url: this._posthog.requestRouter.endpointFor('api', RESTORE_REQUEST_ENDPOINT),\n method: 'POST',\n data: payload,\n headers: {\n 'X-Conversations-Token': token,\n },\n callback: (response) => {\n if (response.statusCode === 429) {\n reject(new Error('Too many requests. Please wait before trying again.'))\n return\n }\n\n if (response.statusCode !== 200) {\n const errorMsg =\n response.json?.error ||\n response.json?.detail ||\n response.json?.message ||\n 'Failed to request restore link'\n reject(new Error(errorMsg))\n return\n }\n\n resolve({ ok: true })\n },\n })\n })\n }\n\n async restoreFromToken(restoreToken: string): Promise<RestoreFromTokenResponse> {\n if (this._identityFields()) {\n return { status: 'success' }\n }\n\n const normalizedToken = restoreToken.trim()\n if (!normalizedToken) {\n throw new Error('Restore token is required')\n }\n try {\n return await this._restoreFromTokenWithRetry(normalizedToken)\n } finally {\n clearRestoreTokenFromUrl()\n }\n }\n\n async restoreFromUrlToken(): Promise<RestoreFromTokenResponse | null> {\n if (this._identityFields()) {\n return null\n }\n\n const restoreToken = getRestoreTokenFromUrl()\n if (!restoreToken) {\n return null\n }\n\n try {\n return await this.restoreFromToken(restoreToken)\n } finally {\n clearRestoreTokenFromUrl()\n }\n }\n\n /**\n * Get the current active ticket ID\n * Returns null if no conversation has been started yet\n */\n getCurrentTicketId(): string | null {\n return this._currentTicketId\n }\n\n /**\n * Get the widget session ID (persistent browser identifier)\n * This ID is used for access control and stays the same across page loads\n */\n getWidgetSessionId(): string {\n return this._widgetSessionId\n }\n\n private _identityFields(): { identity_distinct_id: string; identity_hash: string } | null {\n const id = this._posthog.config.identity_distinct_id\n const hash = this._posthog.config.identity_hash\n if (!id || !hash) {\n return null\n }\n return { identity_distinct_id: id, identity_hash: hash }\n }\n\n setIdentity(): void {\n this._resetConversationState()\n this._widgetRef?.setIdentityMode(true)\n void this._loadTicketsAndReconcileView()\n }\n\n clearIdentity(): void {\n this._resetConversationState()\n this._widgetRef?.setIdentityMode(false)\n void this._loadTicketsAndReconcileView()\n }\n\n private _resetConversationState(): void {\n this._currentTicketId = null\n this._persistence.clearTicketId()\n this._lastMessageTimestamp = null\n this._widgetRef?.clearMessages(true)\n }\n\n private async _loadTicketsAndReconcileView(): Promise<void> {\n try {\n const identityBefore = this._posthog.config.identity_distinct_id\n const response = await this.getTickets()\n\n if (this._posthog.config.identity_distinct_id !== identityBefore) {\n return\n }\n\n const view = this._applyTicketsToState(response.results)\n this._widgetRef?.updateTickets(response.results, this._showTicketList)\n this._widgetRef?.setUnreadCount(this._unreadCount)\n this._widgetRef?.setCurrentTicketResolved(this._isCurrentTicketResolved())\n this._currentView = view\n this._widgetRef?.setView(view)\n\n if (view === 'messages' && this._currentTicketId) {\n void this._loadMessages()\n }\n } catch (error) {\n logger.error('Failed to load tickets after identity change', error)\n }\n }\n\n /**\n * Clean up the widget\n */\n destroy(): void {\n this._stopPolling()\n\n // Unsubscribe from identify events\n if (this._unsubscribeIdentifyListener) {\n this._unsubscribeIdentifyListener()\n this._unsubscribeIdentifyListener = null\n }\n\n if (this._containerElement) {\n render(null, this._containerElement)\n this._containerElement.remove()\n this._containerElement = null\n }\n\n this._widgetRef = null\n\n if (_activeManager === this) {\n _activeManager = null\n }\n logger.info('Widget destroyed')\n }\n\n /**\n * Reset all conversation data and destroy the widget.\n * Called on posthog.reset() to start fresh.\n */\n reset(): void {\n // Clear all persisted conversation data\n this._persistence.clearAll()\n\n // Reset local state\n this._currentTicketId = null\n this._lastMessageTimestamp = null\n this._unreadCount = 0\n\n // Destroy the widget\n this.destroy()\n\n logger.info('Conversations reset')\n }\n\n /**\n * Render the widget to the DOM\n */\n private _renderWidget(\n initialState: ConversationsWidgetState,\n initialUserTraits: UserProvidedTraits | null,\n initialView: WidgetView = 'messages',\n initialTickets: Ticket[] = []\n ): void {\n if (!document) {\n logger.info('Conversations widget not rendered: Document not available')\n return\n }\n\n // Create container if it doesn't exist\n let container = document.getElementById(WIDGET_CONTAINER_ID) as HTMLDivElement\n if (!container) {\n if (!document.body) {\n logger.info('Conversations widget not rendered: Document body not available yet')\n return\n }\n container = document.createElement('div')\n container.id = WIDGET_CONTAINER_ID\n document.body.appendChild(container)\n }\n this._containerElement = container\n\n // Render widget with ref\n render(\n <ConversationsWidget\n ref={(ref: ConversationsWidget | null) => {\n this._widgetRef = ref\n }}\n config={this._config}\n initialState={initialState}\n initialUserTraits={initialUserTraits}\n isUserIdentified={this._posthog._isIdentified()}\n isIdentityMode={!isNull(this._identityFields())}\n initialView={initialView}\n initialTickets={initialTickets}\n showTicketList={this._showTicketList}\n onSendMessage={this._handleSendMessage}\n onStateChange={this._handleStateChange}\n onIdentify={this._handleIdentify}\n onRequestRestoreLink={this._handleRequestRestoreLink}\n onSelectTicket={this._handleSelectTicket}\n onNewConversation={this._handleNewConversation}\n onBackToTickets={this._handleBackToTickets}\n onViewChange={this._handleViewChange}\n />,\n container\n )\n }\n}\n\n/**\n * Initialize the conversations widget.\n * This is the entry point called from the lazy-loaded bundle.\n *\n * Singleton guard: only one ConversationsManager per page. The toolbar's\n * internal PostHog instance is excluded upstream (see loadIfEnabled), so\n * this always belongs to the customer's main instance.\n */\nexport function initConversations(config: ConversationsRemoteConfig, posthog: PostHog): ConversationsManager {\n if (_activeManager) {\n return _activeManager\n }\n\n _activeManager = new ConversationsManager(config, posthog)\n return _activeManager\n}\n","import { initConversations } from '../extensions/conversations/external'\nimport { assignableWindow } from '../utils/globals'\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.initConversations = initConversations\n\nexport default initConversations\n"],"names":["p","v","y","ObjProto","Object","prototype","type_utils_hasOwnProperty","hasOwnProperty","type_utils_toString","toString","isArray","Array","obj","call","isUndefined","x","isNull","isNumber","CONVERSATIONS_LEGACY_WIDGET_SESSION_ID","CONVERSATIONS_LEGACY_TICKET_ID","CONVERSATIONS_LEGACY_WIDGET_STATE","CONVERSATIONS_LEGACY_USER_TRAITS","win","window","undefined","global","globalThis","self","File","document","XMLHttpRequest","assignableWindow","_createLogger","prefix","_temp","debugEnabled","logger","_log","level","POSTHOG_DEBUG","console","consoleLog","_len","arguments","length","args","_key","info","_len2","_key2","warn","_len3","_key3","error","_len4","_key4","critical","_len5","_key5","uninitializedWarning","methodName","createLogger","additionalPrefix","options","Math","trunc","ceil","floor","Number","isInteger","value","isFinite","UUID","constructor","bytes","this","TypeError","fromFieldsV7","unixTsMs","randA","randBHi","randBLo","RangeError","Uint8Array","pow","text","i","Error","clone","slice","equals","other","compareTo","diff","sign","V7Generator","_timestamp","_counter","_random","DefaultRandom","generate","generateOrAbort","valueAfterReset","ts","Date","now","_resetCounter","nextUint32","defaultGenerator","getRandomValues","buffer","UUIDV7_DENY_WEAK_RNG","random","crypto","_buffer","Uint32Array","_cursor","Infinity","ConversationsPersistence","_posthog","_posthog$config","token","_cachedWidgetSessionId","_storageKey","config","_migrateFromLegacyPersistence","getOrCreateWidgetSessionId","_this$_read","sessionId","_read","widgetSessionId","_write","setWidgetSessionId","id","data","_extends","clearWidgetSessionId","saveTicketId","ticketId","loadTicketId","_this$_read2","clearTicketId","saveWidgetState","state","widgetState","loadWidgetState","_this$_read3","saveUserTraits","traits","userTraits","loadUserTraits","_this$_read4","name","email","clearUserTraits","clearAll","_window$localStorage","localStorage","removeItem","_unused","_window$localStorage2","raw","getItem","JSON","parse","_unused2","_window$localStorage3","setItem","stringify","_this$_read5","persistence","isDisabled","get_property","legacyFromRaw","_readLegacyFromRawStorage","unregister","_this$_posthog$config","_window$localStorage4","persistence_name","parsed","_unused3","getContrastTextColor","hexColor","hex","replace","fullHex","r","parseInt","g","b","sqrt","getStyles","primaryColor","position","isLeft","includes","isTop","widget","top","bottom","left","right","zIndex","fontFamily","buttonContainer","button","width","height","borderRadius","background","color","border","cursor","filter","display","alignItems","justifyContent","transition","unreadBadge","minWidth","fontSize","fontWeight","padding","boxShadow","boxSizing","flexDirection","overflow","windowOpen","maxWidth","maxHeight","header","flexShrink","headerTitle","headerActions","gap","headerLinkButton","opacity","headerButton","lineHeight","messages","flex","overflowY","message","animation","messageCustomer","alignSelf","messageAgent","messageAuthor","marginBottom","messageContent","wordWrap","whiteSpace","messageContentCustomer","borderBottomRightRadius","messageContentAgent","borderBottomLeftRadius","messageTime","marginTop","borderTop","borderBottom","textAlign","inputContainer","resolvedBanner","paddingTop","resolvedBannerText","input","resize","outline","fieldSizing","sendButton","identificationForm","formTitle","formDescription","recoverFooter","recoverFooterLink","textDecoration","formField","formLabel","formInput","formInputError","borderColor","formError","formSubmitButton","formOptional","restoreRequestSuccess","ticketListContainer","ticketList","ticketItem","ticketItemUnread","ticketItemContent","ticketItemArrow","ticketItemHeader","ticketPreview","textOverflow","ticketPreviewUnread","ticketUnreadBadge","ticketMeta","ticketTime","ticketStatus","textTransform","letterSpacing","newConversationButton","margin","ticketListLoading","loadingSpinner","ticketListEmpty","emptyStateIcon","emptyStateTitle","emptyStateDescription","newConversationButtonLarge","fetchPreviousButton","backButton","marginRight","headerWithBack","OpenChatButton","_ref","handleToggleOpen","unreadCount","styles","displayCount","_jsx","style","children","_jsxs","onClick","onMouseEnter","e","currentTarget","transform","onMouseLeave","viewBox","fill","xmlns","d","CloseChatButton","handleClose","formatRelativeTime","isoString","date","diffMs","getTime","diffMins","diffHours","diffDays","toLocaleDateString","truncateText","maxLength","substring","TicketListItem","status","ticket","hasUnread","unread_count","statusLabel","charAt","toUpperCase","handleClick","onKeyDown","key","preventDefault","role","tabIndex","last_message","trim","last_message_at","created_at","stroke","strokeWidth","points","NewConversationButton","type","x1","y1","x2","y2","LoadingState","EmptyState","_ref2","onNewConversation","onOpenRestoreRequest","TicketListView","_ref3","tickets","isLoading","onSelectTicket","sort","a","dateA","map","IdentificationFormView","formName","formEmail","formEmailError","onNameChange","onEmailChange","onSubmit","description","identificationFormDescription","showNameField","collectName","identificationFormTitle","onInput","placeholder","autoComplete","requireEmail","RestoreRequestView","restoreEmail","restoreEmailError","restoreRequestLoading","disabled","t","u","SendMessageButton","inputValue","handleSendMessage","strokeLinejoin","o","f","c","n","__b","__r","diffed","l","__c","m","unmount","s","__","__h","__H","push","j","shift","__P","forEach","z","B","__e","__v","__k","__m","__N","requestAnimationFrame","w","some","k","clearTimeout","cancelAnimationFrame","setTimeout","sanitizeUrl","url","trimmedUrl","normalizedForCheck","toLowerCase","startsWith","lowerUrl","MAX_DEPTH","renderNode","node","depth","_node$content","marks","element","_Fragment","mark","fontStyle","code","_mark$attrs","href","attrs","safeUrl","target","rel","referrerPolicy","link","renderTextWithMarks","content","child","index","_node$content2","codeText","codeBlock","_node$attrs","_node$attrs2","src","alt","image","onError","paddingLeft","borderLeft","_node$attrs3","rawLevel","min","max","RichContent","richContent","isCustomer","C","useMemo","overflowX","wordBreak","doc","isValidTipTapDoc","rendered","lines","split","line","Fragment","renderPlainText","MessageBubble","author_type","messageStyle","contentStyle","author_name","rich_content","MessagesView","placeholderText","isResolved","onInputChange","onSendMessage","onStartNewConversation","messagesEndRef","ref","rows","autoFocus","ConversationsWidget","Component","props","_this","super","_messagesEndRef","_handleToggleOpen","setState","prevState","_handleClose","_handleSelectTicket","_handleNewConversation","_handleBackToTickets","onBackToTickets","_handleOpenRestoreRequest","_prevState$userTraits","view","onViewChange","_handleCloseRestoreRequest","returnView","showTicketList","_handleInputChange","_handleKeyPress","shiftKey","_handleSendMessage","_handleFormNameChange","_handleFormEmailChange","_handleRestoreEmailChange","_handleFormSubmit","onIdentify","_validateEmail","nextView","_handleRestoreRequestSubmit","_asyncToGenerator","onRequestRestoreLink","_x","apply","trimmedMessage","userMessage","toISOString","is_private","isIdentityMode","initialUserTraits","needsIdentification","_needsIdentification","isUserIdentified","initialState","initialView","initialTickets","ticketsLoading","isCurrentTicketResolved","componentDidMount","greetingText","_addGreetingMessage","componentDidUpdate","_prevProps","_scrollToBottom","onStateChange","greetingMessage","scrollIntoView","behavior","test","addMessages","existingIds","Set","newMessages","has","show","hide","getUserTraits","setUserIdentified","setUnreadCount","count","updateTickets","setCurrentTicketResolved","resolved","setView","getView","setTicketsLoading","loading","setIdentityMode","update","clearMessages","addGreeting","_renderIdentificationForm","_renderBackButton","_renderTicketList","_renderMessages","el","_renderRestoreRequestView","_getTitle","_renderViewContent","render","widgetPosition","windowStyle","showBackButton","showRecoverFooter","formDataToQuery","formdata","arg_separator","use_val","use_key","tph_arr","iterator","isNullish","FormData","isFormData","val","each","encodeURIComponent","isFile","join","RESTORE_QUERY_PARAM","getRestoreTokenFromUrl","_window$location2","location","search","URLSearchParams","get","clearRestoreTokenFromUrl","_window$history","history","replaceState","URL","searchParams","delete","pathname","hash","WIDGET_CONTAINER_ID","_activeManager","ConversationsManager","_widgetRef","_containerElement","_currentTicketId","_pollIntervalId","_lastMessageTimestamp","_isPollingMessages","_isPollingTickets","_unsubscribeIdentifyListener","_unreadCount","_widgetState","_isWidgetRendered","_hasProcessedRestoreToken","_initializeWidgetPromise","_currentView","_tickets","_showTicketList","_handleIdentify","_persistence","capture","hasName","hasEmail","_handleRequestRestoreLink","response","requestRestoreLink","_this$_widgetRef","sendMessage","_pollMessages","_x2","_handleStateChange","_markMessagesAsRead","_loadMessages","_pollTickets","_loadTickets","_poll","_handleViewChange","from","to","_ref6","_this$_widgetRef2","_this$_widgetRef3","_this$_widgetRef4","_switchToTicketIfNeeded","_isCurrentTicketResolved","_isWidgetOpen","_x3","_this$_widgetRef5","_this$_widgetRef6","_this$_widgetRef7","_this$_widgetRef8","_this$_widgetRef9","_config","_widgetSessionId","_isWidgetEnabled","widgetEnabled","_isDomainAllowed","domains","_window$location","currentHostname","hostname","domain","allowedHostname","extractHostname","pattern","endsWith","isCurrentDomainAllowed","_initialize","newTicket","_this2","isNewTicket","Promise","resolve","reject","personTraits","_getPersonTraits","identity","_identityFields","payload","ticket_id","identity_distinct_id","identity_hash","distinct_id","widget_session_id","get_distinct_id","capturedSessionId","get_session_id","session_id","replayUrl","get_session_replay_url","withTimestamp","timestampLookBack","currentUrl","session_context","session_replay_url","current_url","_send_request","requestRouter","endpointFor","method","headers","callback","statusCode","_response$json","_response$json2","errorMsg","json","detail","forced","messageLength","getMessages","after","_this3","targetTicketId","queryParams","limit","_response$json3","_response$json4","markAsRead","_this4","_response$json5","_response$json6","_completeInitialization","restoreToken","_restoreFromTokenWithRetry","catch","finally","hasExistingTicket","domainAllowed","_initializeWidget","_setupIdentifyListener","_this5","_restoreFromToken","_this6","_data$migrated_ticket","restore_token","_response$json7","_response$json8","_response$json9","migrated_ticket_ids","_doInitializeWidget","_this7","_getInitialUserTraits","_determineInitialView","_renderWidget","ticketCount","hasUserTraits","_startPolling","_this$_posthog$persis","superProps","storedPersonProps","$name","$email","savedTraits","_this8","_this8$_widgetRef","_this9","_this9$_widgetRef","_this9$_widgetRef2","identityBefore","ticketBefore","ticket_status","_applyTicketStatusUpdate","_this0","_this0$_widgetRef","_this0$_widgetRef2","_this0$_widgetRef3","getTickets","results","_computeShowTicketList","totalUnread","reduce","sum","find","_this$_widgetRef0","_this$_widgetRef1","idx","findIndex","_this1","_applyTicketsToState","setInterval","_stopPolling","clearInterval","on","event","_this$_widgetRef10","remove","isVisible","_this10","_options$limit","_options$offset","String","offset","_response$json0","_response$json1","_this11","_window$location3","ok","normalizedEmail","request_url","_response$json10","_response$json11","_response$json12","restoreFromToken","_this12","normalizedToken","restoreFromUrlToken","_this13","getCurrentTicketId","getWidgetSessionId","setIdentity","_this$_widgetRef11","_resetConversationState","_loadTicketsAndReconcileView","clearIdentity","_this$_widgetRef12","_this$_widgetRef13","_this14","_this14$_widgetRef","_this14$_widgetRef2","_this14$_widgetRef3","_this14$_widgetRef4","destroy","reset","container","getElementById","body","createElement","appendChild","_isIdentified","__PosthogExtensions__","initConversations","posthog"],"mappings":"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","x_google_ignoreList":[0,17]}
|