@pixelmatters/markup 1.18.4 → 1.18.5
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/README.md +72 -72
- package/dist/widget.js +16 -16
- package/dist/widget.js.map +1 -1
- package/package.json +1 -1
- package/skills/install-markup-widget/SKILL.md +60 -60
package/dist/widget.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widget.js","names":["l","u","t","i","r","o","e","f","c","a","s","h","p","v","y","d","w","_","m","k","C","q","D","A","T","j","z","B","u","i","f","n","i","Base64.fromByteArray","Base64.toByteArray","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","Base64.toByteArray","Base64.fromByteArray","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","r"],"sources":["../../../node_modules/.pnpm/preact@10.29.7/node_modules/preact/dist/preact.module.js","../src/styles.css?inline","../src/runtime/analytics.ts","../src/runtime/error-boundary.tsx","../src/runtime/error-reporter.ts","../src/runtime/theme-store.ts","../../../node_modules/.pnpm/preact@10.29.7/node_modules/preact/hooks/dist/hooks.module.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/index.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/values/base64.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/common/index.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/values/value.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/values/errors.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/logging.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/udf_path_utils.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/local_state.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/request_manager.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/server/functionName.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/server/components/paths.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/server/api.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/optimistic_updates_impl.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/vendor/long.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/remote_query_set.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/protocol.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/web_socket_manager.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/session.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/vendor/jwt-decode/index.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/authentication_manager.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/metrics.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/client.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/pagination.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/paginated_query_client.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/simple_client.js","../src/lib/machine.ts","../src/lib/mentions.ts","../src/lib/use-async-action.ts","../../../node_modules/.pnpm/@medv+finder@4.0.2/node_modules/@medv/finder/finder.js","../src/runtime/anchor.ts","../src/runtime/api.ts","../src/runtime/cookie-probe.ts","../src/runtime/history-observer.ts","../src/runtime/safe-url.ts","../src/runtime/identity-store.ts","../src/runtime/popup-auth.ts","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/util.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/clone-pseudos.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/mimes.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/dataurl.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/clone-node.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/embed-resources.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/embed-images.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/apply-style.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/embed-webfonts.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/index.js","../src/runtime/screenshot.ts","../src/runtime/use-subscription-token.ts","../src/runtime/refresh-token.ts","../src/runtime/use-token-refresh.ts","../src/runtime/utils.ts","../../../node_modules/.pnpm/preact@10.29.7/node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js","../src/runtime/ui/icons.tsx","../src/runtime/ui/identity-menu.tsx","../src/runtime/use-drag.ts","../src/runtime/use-focus-trap.ts","../src/runtime/use-object-url.ts","../src/runtime/ui/author-prompt.tsx","../src/runtime/mention-input.ts","../src/runtime/ui/mentions.tsx","../src/runtime/ui/mention-input.tsx","../src/runtime/ui/composer.tsx","../src/runtime/ui/new-thread-popover.tsx","../src/runtime/ui/notifications-panel.tsx","../src/runtime/use-theme.ts","../src/runtime/ui/overflow-menu.tsx","../src/runtime/ui/panel-popover.tsx","../src/runtime/ui/pin.tsx","../src/runtime/ui/placement-overlay.tsx","../src/runtime/ui/privacy-panel.tsx","../src/runtime/ui/shortcuts-panel.tsx","../src/runtime/ui/thread-popover.tsx","../src/runtime/ui/toolbar.tsx","../src/runtime/ui/app.tsx","../src/runtime/mount.tsx","../src/widget.ts"],"sourcesContent":["var n,l,u,t,i,r,o,e,f,c,a,s,h,p,v,y,d={},w=[],_=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,g=Array.isArray;function m(n,l){for(var u in l)n[u]=l[u];return n}function b(n){n&&n.parentNode&&n.parentNode.removeChild(n)}function k(l,u,t){var i,r,o,e={};for(o in u)\"key\"==o?i=u[o]:\"ref\"==o?r=u[o]:e[o]=u[o];if(arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):t),\"function\"==typeof l&&null!=l.defaultProps)for(o in l.defaultProps)void 0===e[o]&&(e[o]=l.defaultProps[o]);return x(l,e,i,r,null)}function x(n,t,i,r,o){var e={type:n,props:t,key:i,ref:r,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:null==o?++u:o,__i:-1,__u:0};return null==o&&null!=l.vnode&&l.vnode(e),e}function M(){return{current:null}}function S(n){return n.children}function C(n,l){this.props=n,this.context=l}function $(n,l){if(null==l)return n.__?$(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?$(n):null}function I(n){if(n.__P&&n.__d){var u=n.__v,t=u.__e,i=[],r=[],o=m({},u);o.__v=u.__v+1,l.vnode&&l.vnode(o),q(n.__P,o,u,n.__n,n.__P.namespaceURI,32&u.__u?[t]:null,i,null==t?$(u):t,!!(32&u.__u),r),o.__v=u.__v,o.__.__k[o.__i]=o,D(i,o,r),u.__e=u.__=null,o.__e!=t&&P(o)}}function P(n){if(null!=(n=n.__)&&null!=n.__c)return n.__e=n.__c.base=null,n.__k.some(function(l){if(null!=l&&null!=l.__e)return n.__e=n.__c.base=l.__e}),P(n)}function A(n){(!n.__d&&(n.__d=!0)&&i.push(n)&&!H.__r++||r!=l.debounceRendering)&&((r=l.debounceRendering)||o)(H)}function H(){try{for(var n,l=1;i.length;)i.length>l&&i.sort(e),n=i.shift(),l=i.length,I(n)}finally{i.length=H.__r=0}}function L(n,l,u,t,i,r,o,e,f,c,a){var s,h,p,v,y,_,g,m=t&&t.__k||w,b=l.length;for(f=T(u,l,m,f,b),s=0;s<b;s++)null!=(p=u.__k[s])&&(h=-1!=p.__i&&m[p.__i]||d,p.__i=s,_=q(n,p,h,i,r,o,e,f,c,a),v=p.__e,p.ref&&h.ref!=p.ref&&(h.ref&&J(h.ref,null,p),a.push(p.ref,p.__c||v,p)),null==y&&null!=v&&(y=v),(g=!!(4&p.__u))||h.__k===p.__k?(f=j(p,f,n,g),g&&h.__e&&(h.__e=null)):\"function\"==typeof p.type&&void 0!==_?f=_:v&&(f=v.nextSibling),p.__u&=-7);return u.__e=y,f}function T(n,l,u,t,i){var r,o,e,f,c,a=u.length,s=a,h=0;for(n.__k=new Array(i),r=0;r<i;r++)null!=(o=l[r])&&\"boolean\"!=typeof o&&\"function\"!=typeof o?(\"string\"==typeof o||\"number\"==typeof o||\"bigint\"==typeof o||o.constructor==String?o=n.__k[r]=x(null,o,null,null,null):g(o)?o=n.__k[r]=x(S,{children:o},null,null,null):void 0===o.constructor&&o.__b>0?o=n.__k[r]=x(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):n.__k[r]=o,f=r+h,o.__=n,o.__b=n.__b+1,e=null,-1!=(c=o.__i=O(o,u,f,s))&&(s--,(e=u[c])&&(e.__u|=2)),null==e||null==e.__v?(-1==c&&(i>a?h--:i<a&&h++),\"function\"!=typeof o.type&&(o.__u|=4)):c!=f&&(c==f-1?h--:c==f+1?h++:(c>f?h--:h++,o.__u|=4))):n.__k[r]=null;if(s)for(r=0;r<a;r++)null!=(e=u[r])&&0==(2&e.__u)&&(e.__e==t&&(t=$(e)),K(e,e));return t}function j(n,l,u,t){var i,r;if(\"function\"==typeof n.type){for(i=n.__k,r=0;i&&r<i.length;r++)i[r]&&(i[r].__=n,l=j(i[r],l,u,t));return l}n.__e!=l&&(t&&(l&&n.type&&!l.parentNode&&(l=$(n)),u.insertBefore(n.__e,l||null)),l=n.__e);do{l=l&&l.nextSibling}while(null!=l&&8==l.nodeType);return l}function F(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(g(n)?n.some(function(n){F(n,l)}):l.push(n)),l}function O(n,l,u,t){var i,r,o,e=n.key,f=n.type,c=l[u],a=null!=c&&0==(2&c.__u);if(null===c&&null==e||a&&e==c.key&&f==c.type)return u;if(t>(a?1:0))for(i=u-1,r=u+1;i>=0||r<l.length;)if(null!=(c=l[o=i>=0?i--:r++])&&0==(2&c.__u)&&e==c.key&&f==c.type)return o;return-1}function z(n,l,u){\"-\"==l[0]?n.setProperty(l,null==u?\"\":u):n[l]=null==u?\"\":\"number\"!=typeof u||_.test(l)?u:u+\"px\"}function N(n,l,u,t,i){var r,o;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||z(n.style,l,\"\");if(u)for(l in u)t&&u[l]==t[l]||z(n.style,l,u[l])}else if(\"o\"==l[0]&&\"n\"==l[1])r=l!=(l=l.replace(s,\"$1\")),o=l.toLowerCase(),l=o in n||\"onFocusOut\"==l||\"onFocusIn\"==l?o.slice(2):l.slice(2),n.l||(n.l={}),n.l[l+r]=u,u?t?u[a]=t[a]:(u[a]=h,n.addEventListener(l,r?v:p,r)):n.removeEventListener(l,r?v:p,r);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 V(n){return function(u){if(this.l){var t=this.l[u.type+n];if(null==u[c])u[c]=h++;else if(u[c]<t[a])return;return t(l.event?l.event(u):u)}}}function q(n,u,t,i,r,o,e,f,c,a){var s,h,p,v,y,d,_,k,x,M,$,I,P,A,H,T,j=u.type;if(void 0!==u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),o=[f=u.__e=t.__e]),(s=l.__b)&&s(u);n:if(\"function\"==typeof j){h=e.length;try{if(x=u.props,M=j.prototype&&j.prototype.render,$=(s=j.contextType)&&i[s.__c],I=s?$?$.props.value:s.__:i,t.__c?k=(p=u.__c=t.__c).__=p.__E:(M?u.__c=p=new j(x,I):(u.__c=p=new C(x,I),p.constructor=j,p.render=Q),$&&$.sub(p),p.state||(p.state={}),p.__n=i,v=p.__d=!0,p.__h=[],p._sb=[]),M&&null==p.__s&&(p.__s=p.state),M&&null!=j.getDerivedStateFromProps&&(p.__s==p.state&&(p.__s=m({},p.__s)),m(p.__s,j.getDerivedStateFromProps(x,p.__s))),y=p.props,d=p.state,p.__v=u,v)M&&null==j.getDerivedStateFromProps&&null!=p.componentWillMount&&p.componentWillMount(),M&&null!=p.componentDidMount&&p.__h.push(p.componentDidMount);else{if(M&&null==j.getDerivedStateFromProps&&x!==y&&null!=p.componentWillReceiveProps&&p.componentWillReceiveProps(x,I),u.__v==t.__v||!p.__e&&null!=p.shouldComponentUpdate&&!1===p.shouldComponentUpdate(x,p.__s,I)){u.__v!=t.__v&&(p.props=x,p.state=p.__s,p.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.some(function(n){n&&(n.__=u)}),w.push.apply(p.__h,p._sb),p._sb=[],p.__h.length&&e.push(p);break n}null!=p.componentWillUpdate&&p.componentWillUpdate(x,p.__s,I),M&&null!=p.componentDidUpdate&&p.__h.push(function(){p.componentDidUpdate(y,d,_)})}if(p.context=I,p.props=x,p.__P=n,p.__e=!1,P=l.__r,A=0,M)p.state=p.__s,p.__d=!1,P&&P(u),s=p.render(p.props,p.state,p.context),w.push.apply(p.__h,p._sb),p._sb=[];else do{p.__d=!1,P&&P(u),s=p.render(p.props,p.state,p.context),p.state=p.__s}while(p.__d&&++A<25);p.state=p.__s,null!=p.getChildContext&&(i=m(m({},i),p.getChildContext())),M&&!v&&null!=p.getSnapshotBeforeUpdate&&(_=p.getSnapshotBeforeUpdate(y,d)),H=null!=s&&s.type===S&&null==s.key?E(s.props.children):s,f=L(n,g(H)?H:[H],u,t,i,r,o,e,f,c,a),p.base=u.__e,u.__u&=-161,p.__h.length&&e.push(p),k&&(p.__E=p.__=null)}catch(n){if(e.length=h,u.__v=null,c||null!=o){if(n.then){for(u.__u|=c?160:128;f&&8==f.nodeType&&f.nextSibling;)f=f.nextSibling;null!=o&&(o[o.indexOf(f)]=null),u.__e=f}else if(null!=o)for(T=o.length;T--;)b(o[T])}else u.__e=t.__e;null==u.__k&&(u.__k=t.__k||[]),n.then||B(u),l.__e(n,u,t)}}else null==o&&u.__v==t.__v?(u.__k=t.__k,u.__e=t.__e):f=u.__e=G(t.__e,u,t,i,r,o,e,c,a);return(s=l.diffed)&&s(u),128&u.__u?void 0:f}function B(n){n&&(n.__c&&(n.__c.__e=!0),n.__k&&n.__k.some(B))}function D(n,u,t){for(var i=0;i<t.length;i++)J(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 E(n){return\"object\"!=typeof n||null==n||n.__b>0?n:g(n)?n.map(E):void 0!==n.constructor?null:m({},n)}function G(u,t,i,r,o,e,f,c,a){var s,h,p,v,y,w,_,m=i.props||d,k=t.props,x=t.type;if(\"svg\"==x?o=\"http://www.w3.org/2000/svg\":\"math\"==x?o=\"http://www.w3.org/1998/Math/MathML\":o||(o=\"http://www.w3.org/1999/xhtml\"),null!=e)for(s=0;s<e.length;s++)if((y=e[s])&&\"setAttribute\"in y==!!x&&(x?y.localName==x:3==y.nodeType)){u=y,e[s]=null;break}if(null==u){if(null==x)return document.createTextNode(k);u=document.createElementNS(o,x,k.is&&k),c&&(l.__m&&l.__m(t,e),c=!1),e=null}if(null==x)m===k||c&&u.data==k||(u.data=k);else{if(e=\"textarea\"==x&&null!=k.defaultValue?null:e&&n.call(u.childNodes),!c&&null!=e)for(m={},s=0;s<u.attributes.length;s++)m[(y=u.attributes[s]).name]=y.value;for(s in m)y=m[s],\"dangerouslySetInnerHTML\"==s?p=y:\"children\"==s||s in k||\"value\"==s&&\"defaultValue\"in k||\"checked\"==s&&\"defaultChecked\"in k||N(u,s,null,y,o);for(s in k)y=k[s],\"children\"==s?v=y:\"dangerouslySetInnerHTML\"==s?h=y:\"value\"==s?w=y:\"checked\"==s?_=y:c&&\"function\"!=typeof y||m[s]===y||N(u,s,y,m[s],o);if(h)c||p&&(h.__html==p.__html||h.__html==u.innerHTML)||(u.innerHTML=h.__html),t.__k=[];else if(p&&(u.innerHTML=\"\"),L(\"template\"==t.type?u.content:u,g(v)?v:[v],t,i,r,\"foreignObject\"==x?\"http://www.w3.org/1999/xhtml\":o,e,f,e?e[0]:i.__k&&$(i,0),c,a),null!=e)for(s=e.length;s--;)b(e[s]);c&&\"textarea\"!=x||(s=\"value\",\"progress\"==x&&null==w?u.removeAttribute(\"value\"):null!=w&&(w!==u[s]||\"progress\"==x&&!w||\"option\"==x&&w!=m[s])&&N(u,s,w,m[s],o),s=\"checked\",null!=_&&_!=u[s]&&N(u,s,_,m[s],o))}return u}function J(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 K(n,u,t){var i,r;if(l.unmount&&l.unmount(n),(i=n.ref)&&(i.current&&i.current!=n.__e||J(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(n){l.__e(n,u)}i.base=i.__P=i.__n=null}if(i=n.__k)for(r=0;r<i.length;r++)i[r]&&K(i[r],u,t||\"function\"!=typeof n.type);t||b(n.__e),n.__c=n.__=n.__e=void 0}function Q(n,l,u){return this.constructor(n,u)}function R(u,t,i){var r,o,e,f;t==document&&(t=document.documentElement),l.__&&l.__(u,t),o=(r=\"function\"==typeof i)?null:i&&i.__k||t.__k,e=[],f=[],q(t,u=(!r&&i||t).__k=k(S,null,[u]),o||d,d,t.namespaceURI,!r&&i?[i]:o?null:t.firstChild?n.call(t.childNodes):null,e,!r&&i?i:o?o.__e:t.firstChild,r,f),D(e,u,f),u.props.children=null}function U(n,l){R(n,l,U)}function W(l,u,t){var i,r,o,e,f=m({},l.props);for(o in l.type&&l.type.defaultProps&&(e=l.type.defaultProps),u)\"key\"==o?i=u[o]:\"ref\"==o?r=u[o]:f[o]=void 0===u[o]&&null!=e?e[o]:u[o];return arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),x(l.type,f,i||l.key,r||l.ref,null)}function X(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,A(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\"+y++,l.__=n,l.Provider=l.__l=(l.Consumer=function(n,l){return n.children(l)}).contextType=l,l}n=w.slice,l={__e:function(n,l,u,t){for(var i,r,o;l=l.__;)if((i=l.__c)&&!i.__)try{if((r=i.constructor)&&null!=r.getDerivedStateFromError&&(i.setState(r.getDerivedStateFromError(n)),o=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),o=i.__d),o)return i.__E=i}catch(l){n=l}throw n}},u=0,t=function(n){return null!=n&&void 0===n.constructor},C.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!=this.state?this.__s:this.__s=m({},this.state),\"function\"==typeof n&&(n=n(m({},u),this.props)),n&&m(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),A(this))},C.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),A(this))},C.prototype.render=S,i=[],o=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,e=function(n,l){return n.__v.__b-l.__v.__b},H.__r=0,f=Math.random().toString(8),c=\"__d\"+f,a=\"__a\"+f,s=/(PointerCapture)$|Capture$/i,h=0,p=V(!1),v=V(!0),y=0;export{C as Component,S as Fragment,W as cloneElement,X as createContext,k as createElement,M as createRef,k as h,U as hydrate,t as isValidElement,l as options,R as render,F as toChildArray};\n//# sourceMappingURL=preact.module.js.map\n","/*\n * Deliberately not Tailwind: a hand-rolled stylesheet is smaller, ships as a\n * single shadow-DOM <style>, and can't conflict with the host page.\n */\n\n:host {\n --markup-paper: #fdfcfa;\n --markup-surface: #ffffff;\n --markup-surface-2: oklch(0.985 0.002 250);\n --markup-surface-3: oklch(0.95 0.003 250);\n --markup-hover: oklch(0.95 0.003 250);\n --markup-ink: #1a1614;\n --markup-ink-soft: oklch(0.32 0.005 250);\n --markup-muted: #6b6661;\n --markup-border: rgba(26, 22, 20, 0.1);\n --markup-border-strong: rgba(26, 22, 20, 0.18);\n --markup-brand: #e35d2a;\n --markup-brand-hover: #c84d20;\n --markup-accent-soft: oklch(0.95 0.04 60);\n --markup-accent-ink: oklch(0.45 0.14 38);\n --markup-accent-glow: color-mix(in srgb, var(--markup-brand) 28%, transparent);\n --markup-team: #2a4ac8;\n --markup-shadow: 0 1px 2px rgba(26, 22, 20, 0.06), 0 8px 28px rgba(26, 22, 20, 0.12);\n --markup-shadow-toolbar:\n 0 1px 1px rgba(0, 0, 0, 0.04), 0 4px 10px -2px rgba(15, 20, 40, 0.1),\n 0 18px 36px -12px rgba(15, 20, 40, 0.18);\n --markup-shadow-pop:\n 0 1px 1px rgba(0, 0, 0, 0.04), 0 8px 24px -6px rgba(15, 20, 40, 0.12),\n 0 28px 60px -18px rgba(15, 20, 40, 0.22);\n --markup-overlay-tint: rgba(26, 22, 20, 0.04);\n --markup-danger: #dc2626;\n --markup-success: oklch(0.62 0.16 150);\n --markup-radius: 6px;\n --markup-radius-sm: 4px;\n --markup-font:\n 'Geist Variable', 'Geist', ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI',\n system-ui, sans-serif;\n --markup-font-mono:\n 'Geist Mono Variable', 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n\n all: initial;\n font-family: var(--markup-font);\n font-size: 14px;\n line-height: 1.5;\n color: var(--markup-ink);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* `data-theme=\"light\"` wins over the media query, so a host can force light. */\n:host([data-theme='dark']) {\n --markup-paper: #1a1614;\n --markup-surface: oklch(0.16 0.005 250);\n --markup-surface-2: oklch(0.2 0.005 250);\n --markup-surface-3: oklch(0.24 0.005 250);\n --markup-hover: oklch(0.24 0.005 250);\n --markup-ink: #fdfcfa;\n --markup-ink-soft: oklch(0.8 0.005 250);\n --markup-muted: #a8a39e;\n --markup-border: rgba(253, 252, 250, 0.12);\n --markup-border-strong: rgba(253, 252, 250, 0.22);\n --markup-team: #7b99f0;\n --markup-accent-soft: color-mix(in srgb, var(--markup-brand) 22%, transparent);\n --markup-accent-ink: oklch(0.86 0.13 55);\n --markup-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 12px 40px rgba(0, 0, 0, 0.45);\n --markup-shadow-toolbar:\n 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 1px 2px rgba(0, 0, 0, 0.4),\n 0 12px 30px -10px rgba(0, 0, 0, 0.55), 0 28px 60px -20px rgba(0, 0, 0, 0.5);\n --markup-shadow-pop:\n 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 8px 24px -6px rgba(0, 0, 0, 0.45),\n 0 28px 60px -18px rgba(0, 0, 0, 0.55);\n --markup-overlay-tint: rgba(253, 252, 250, 0.05);\n --markup-danger: #f87171;\n}\n\n@media (prefers-color-scheme: dark) {\n :host(:not([data-theme])) {\n --markup-paper: #1a1614;\n --markup-surface: oklch(0.16 0.005 250);\n --markup-surface-2: oklch(0.2 0.005 250);\n --markup-surface-3: oklch(0.24 0.005 250);\n --markup-hover: oklch(0.24 0.005 250);\n --markup-ink: #fdfcfa;\n --markup-ink-soft: oklch(0.8 0.005 250);\n --markup-muted: #a8a39e;\n --markup-border: rgba(253, 252, 250, 0.12);\n --markup-border-strong: rgba(253, 252, 250, 0.22);\n --markup-team: #7b99f0;\n --markup-accent-soft: color-mix(in srgb, var(--markup-brand) 22%, transparent);\n --markup-accent-ink: oklch(0.86 0.13 55);\n --markup-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 12px 40px rgba(0, 0, 0, 0.45);\n --markup-shadow-toolbar:\n 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 1px 2px rgba(0, 0, 0, 0.4),\n 0 12px 30px -10px rgba(0, 0, 0, 0.55), 0 28px 60px -20px rgba(0, 0, 0, 0.5);\n --markup-shadow-pop:\n 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 8px 24px -6px rgba(0, 0, 0, 0.45),\n 0 28px 60px -18px rgba(0, 0, 0, 0.55);\n --markup-overlay-tint: rgba(253, 252, 250, 0.05);\n --markup-danger: #f87171;\n }\n}\n\n.markup-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n\n.markup-shadow-root {\n font-family: var(--markup-font);\n}\n\n.markup-shadow-root *,\n.markup-shadow-root *::before,\n.markup-shadow-root *::after {\n box-sizing: border-box;\n}\n\n/* `:where()` zeroes specificity so these never beat component overrides. */\n:where(.markup-shadow-root button, .markup-shadow-root input, .markup-shadow-root textarea) {\n font: inherit;\n color: inherit;\n}\n\n.markup-eyebrow {\n font-family: var(--markup-font-mono);\n font-size: 10px;\n font-weight: 500;\n letter-spacing: 0.12em;\n text-transform: uppercase;\n color: var(--markup-muted);\n}\n\n/* ────────── Toolbar pill ────────── */\n\n.markup-toolbar {\n position: fixed;\n bottom: 22px;\n z-index: 10;\n display: inline-flex;\n align-items: center;\n height: 44px;\n padding: 4px;\n gap: 2px;\n background: var(--markup-surface);\n border: 1px solid var(--markup-border);\n border-radius: 9999px;\n pointer-events: none;\n box-shadow: var(--markup-shadow-toolbar);\n /* Every position class defines both `left` and `transform`, so CSS can\n * transition between any pair. Going through `auto` breaks the animation. */\n left: 100%;\n transform: translateX(calc(-100% - 22px));\n transition:\n box-shadow 150ms ease,\n left 220ms cubic-bezier(0.2, 0.7, 0.2, 1),\n transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1);\n}\n.markup-toolbar > * {\n pointer-events: auto;\n}\n\n.markup-tb-btn {\n position: relative;\n width: 36px;\n height: 36px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 0;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 9999px;\n color: var(--markup-ink-soft);\n cursor: pointer;\n touch-action: none;\n font-family: var(--markup-font);\n font-size: 13px;\n font-weight: 500;\n transition:\n background 120ms ease,\n color 120ms ease;\n}\n.markup-tb-btn:hover {\n background: var(--markup-hover);\n color: var(--markup-ink);\n}\n.markup-tb-btn:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 2px var(--markup-surface),\n 0 0 0 4px var(--markup-accent-glow);\n}\n.markup-tb-btn[data-on='true'] {\n background: var(--markup-ink);\n color: var(--markup-paper);\n}\n:host([data-theme='dark']) .markup-tb-btn[data-on='true'],\n:host(:not([data-theme])) .markup-tb-btn[data-on='true'] {\n /* Dark mode: pressed/open state uses surface-3 since the ink is now\n * near-white and an inverted swap would lose all contrast. */\n}\n@media (prefers-color-scheme: dark) {\n :host(:not([data-theme])) .markup-tb-btn[data-on='true'] {\n background: var(--markup-surface-3);\n color: var(--markup-ink);\n }\n}\n:host([data-theme='dark']) .markup-tb-btn[data-on='true'] {\n background: var(--markup-surface-3);\n color: var(--markup-ink);\n}\n.markup-tb-btn[data-armed='true'] {\n background: var(--markup-brand);\n color: #fff;\n}\n.markup-tb-btn[data-armed='true']:hover {\n background: var(--markup-brand-hover);\n color: #fff;\n}\n.markup-tb-btn[disabled] {\n color: color-mix(in srgb, var(--markup-muted) 60%, transparent);\n cursor: default;\n}\n.markup-tb-btn[disabled]:hover {\n background: transparent;\n color: color-mix(in srgb, var(--markup-muted) 60%, transparent);\n}\n\n.markup-tb-btn[data-kind='identity'] {\n width: auto;\n padding: 0 4px;\n gap: 6px;\n}\n.markup-tb-avatar {\n width: 28px;\n height: 28px;\n border-radius: 9999px;\n background: var(--markup-surface-3);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n font-weight: 600;\n color: var(--markup-ink);\n overflow: hidden;\n border: 1px solid var(--markup-border);\n flex-shrink: 0;\n}\n.markup-tb-avatar.is-anon {\n color: var(--markup-muted);\n background: var(--markup-surface-2);\n}\n\n.markup-tb-sep {\n width: 1px;\n height: 20px;\n background: var(--markup-border);\n margin: 0 4px;\n flex-shrink: 0;\n}\n\n.markup-tb-badge {\n position: absolute;\n top: 0;\n right: 0;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 9999px;\n background: var(--markup-brand);\n color: #fff;\n font-family: var(--markup-font-mono);\n font-size: 9.5px;\n font-weight: 600;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 0 0 2px var(--markup-surface);\n pointer-events: none;\n}\n\n/* Both properties in every variant, so any pair of positions animates. */\n.markup-toolbar-left {\n left: 0;\n transform: translateX(22px);\n}\n.markup-toolbar-center {\n left: 50%;\n transform: translateX(-50%);\n}\n.markup-toolbar-right {\n left: 100%;\n transform: translateX(calc(-100% - 22px));\n}\n\n/* ────────── Toolbar popovers (overflow / identity / inbox) ──────────\n *\n * Each pops above its anchor button and shares the same surface chrome.\n * `data-pop` distinguishes width and inner padding rules.\n */\n.markup-pop {\n position: absolute;\n bottom: calc(100% + 8px);\n background: var(--markup-surface);\n border: 1px solid var(--markup-border);\n border-radius: 12px;\n box-shadow: var(--markup-shadow-pop);\n font-size: 13px;\n color: var(--markup-ink);\n z-index: 11;\n animation: markup-pop-in 140ms cubic-bezier(0.2, 0.7, 0.2, 1);\n overflow: hidden;\n}\n.markup-pop[data-pop='overflow'] {\n width: 260px;\n padding: 6px;\n}\n.markup-pop[data-pop='identity'] {\n width: 240px;\n padding: 6px;\n}\n.markup-pop[data-pop='inbox'] {\n width: 380px;\n padding: 0;\n}\n.markup-pop.is-anchor-right {\n right: 0;\n}\n.markup-pop.is-anchor-left {\n left: 0;\n}\n.markup-pop.is-anchor-center {\n left: 50%;\n transform: translateX(-50%);\n}\n\n@keyframes markup-pop-in {\n from {\n opacity: 0;\n transform: translateY(6px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.markup-pop.is-anchor-center {\n animation-name: markup-pop-in-center;\n}\n@keyframes markup-pop-in-center {\n from {\n opacity: 0;\n transform: translate(-50%, 6px);\n }\n to {\n opacity: 1;\n transform: translate(-50%, 0);\n }\n}\n\n/* ────────── Overflow menu — appearance, position, behavior, footer ────────── */\n\n.markup-pop-group-label {\n font-family: var(--markup-font-mono);\n font-size: 10px;\n letter-spacing: 0.06em;\n color: var(--markup-muted);\n text-transform: lowercase;\n padding: 8px 10px 4px;\n}\n\n/* Icon-only buttons keep the row inside the 260px popover without crowding\n * the label. Shared by Appearance and Position. */\n.markup-segmented-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 7px 8px;\n border-radius: 6px;\n}\n.markup-segmented-row .lbl {\n flex: 1;\n min-width: 0;\n font-size: 13px;\n color: var(--markup-ink);\n}\n\n.markup-segmented {\n display: inline-flex;\n gap: 2px;\n padding: 2px;\n background: var(--markup-surface-3);\n border-radius: 7px;\n}\n.markup-segmented button {\n background: transparent;\n border: none;\n font: inherit;\n width: 28px;\n height: 24px;\n padding: 0;\n border-radius: 5px;\n color: var(--markup-muted);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition:\n background 100ms ease,\n color 100ms ease;\n}\n.markup-segmented button:hover {\n color: var(--markup-ink);\n}\n.markup-segmented button.is-on {\n background: var(--markup-surface);\n color: var(--markup-ink);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.markup-menu-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 7px 8px;\n border-radius: 6px;\n font-size: 13px;\n cursor: pointer;\n width: 100%;\n background: transparent;\n border: none;\n color: inherit;\n font-family: inherit;\n text-align: left;\n}\n.markup-menu-row:hover {\n background: var(--markup-hover);\n}\n.markup-menu-row:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.markup-menu-row:disabled:hover {\n background: transparent;\n}\n.markup-menu-row .ic {\n width: 16px;\n height: 16px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--markup-muted);\n flex-shrink: 0;\n}\n.markup-menu-row .lbl {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n.markup-menu-row .lbl .sub {\n font-size: 11px;\n color: var(--markup-muted);\n margin-top: 1px;\n}\n.markup-menu-row .right {\n margin-left: auto;\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n color: var(--markup-muted);\n}\n.markup-menu-row.is-danger {\n color: var(--markup-danger);\n}\n.markup-menu-row.is-danger .ic {\n color: var(--markup-danger);\n}\n.markup-menu-row.is-danger:hover {\n background: color-mix(in srgb, var(--markup-danger) 10%, transparent);\n}\n\n.markup-menu-row .switch {\n width: 26px;\n height: 16px;\n background: var(--markup-border-strong);\n border-radius: 9999px;\n position: relative;\n transition: background 120ms ease;\n flex-shrink: 0;\n}\n.markup-menu-row .switch::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: 12px;\n height: 12px;\n background: var(--markup-surface);\n border-radius: 9999px;\n transition: left 120ms ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);\n}\n.markup-menu-row[data-on='true'] .switch {\n background: var(--markup-brand);\n}\n.markup-menu-row[data-on='true'] .switch::after {\n left: 12px;\n}\n\n.markup-menu-divider {\n height: 1px;\n background: var(--markup-border);\n margin: 4px 0;\n}\n\n.markup-brand-line {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n color: var(--markup-muted);\n border-top: 1px solid var(--markup-border);\n margin-top: 6px;\n text-decoration: none;\n}\n.markup-brand-line:hover {\n color: var(--markup-ink);\n}\n.markup-brand-line svg {\n color: var(--markup-brand);\n}\n.markup-brand-line .ver {\n margin-left: auto;\n}\n\n/* ────────── Identity menu ────────── */\n\n.markup-id-who {\n padding: 10px 8px 12px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n border-bottom: 1px solid var(--markup-border);\n margin-bottom: 4px;\n}\n.markup-id-who .nm {\n font-weight: 600;\n font-size: 13.5px;\n color: var(--markup-ink);\n}\n.markup-id-who .em {\n font-family: var(--markup-font-mono);\n font-size: 11px;\n color: var(--markup-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.markup-id-anon {\n padding: 14px 10px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n text-align: left;\n}\n.markup-id-anon .h {\n font-size: 14px;\n font-weight: 600;\n letter-spacing: -0.005em;\n color: var(--markup-ink);\n}\n.markup-id-anon .sub {\n font-size: 12.5px;\n color: var(--markup-muted);\n line-height: 18px;\n}\n.markup-id-anon button:not(.markup-menu-row) {\n width: 100%;\n background: var(--markup-ink);\n color: var(--markup-paper);\n border: none;\n height: 32px;\n border-radius: 7px;\n font: inherit;\n font-weight: 500;\n font-size: 13px;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n.markup-id-anon button:disabled {\n opacity: 0.7;\n cursor: default;\n}\n.markup-id-anon button:not(.markup-menu-row):hover:not(:disabled) {\n background: color-mix(in srgb, var(--markup-ink) 88%, var(--markup-surface));\n}\n\n/* ────────── HUD-hidden toast ──────────\n * Brief instructional message shown once when the HUD is hidden via\n * shortcut or modifier-click. Mirrors the FAB corner so the user's\n * eye lands in the same spot the FAB just vacated; auto-dismisses. */\n\n.markup-hud-hidden-toast {\n position: fixed;\n bottom: 24px;\n z-index: 10;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px;\n border-radius: 999px;\n background: var(--markup-ink);\n color: var(--markup-paper);\n font-size: 12px;\n font-weight: 500;\n letter-spacing: -0.01em;\n box-shadow: var(--markup-shadow);\n pointer-events: none;\n animation:\n markup-hud-hidden-in 220ms ease-out,\n markup-hud-hidden-out 320ms ease-in 4.6s forwards;\n}\n.markup-hud-hidden-toast-right {\n right: 24px;\n}\n.markup-hud-hidden-toast-left {\n left: 24px;\n}\n.markup-hud-hidden-toast-center {\n left: 0;\n right: 0;\n margin-inline: auto;\n width: max-content;\n}\n.markup-kbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--markup-paper) 14%, transparent);\n color: var(--markup-paper);\n font-family: var(--markup-font);\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n}\n/* Retinted for a light surface: the base rule dresses these for the dark HUD\n toast, where `--markup-paper` is the foreground. */\n.markup-kbd.is-inline {\n min-width: 14px;\n height: 14px;\n padding: 0 3px;\n border-radius: 3px;\n background: color-mix(in srgb, var(--markup-ink) 8%, transparent);\n color: var(--markup-muted);\n font-size: 9.5px;\n}\n\n@keyframes markup-hud-hidden-in {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n@keyframes markup-hud-hidden-out {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(4px);\n }\n}\n\n/* ────────── Pins layer ────────── */\n\n.markup-pins-layer {\n position: fixed;\n inset: 0;\n pointer-events: none;\n}\n\n/* The paper-coloured ring is what makes the pin read on any backdrop, and the\n * asymmetric radius gives the disc its comment-bubble tail. Translated so the\n * click point sits at that tail rather than at the centre. */\n.markup-pin {\n position: absolute;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n margin: 0;\n padding: 0;\n border: 2px solid var(--markup-paper);\n background: var(--markup-brand);\n color: #fff;\n border-radius: 999px 999px 999px 4px;\n font-family: var(--markup-font-mono);\n font-size: 11.5px;\n font-weight: 600;\n line-height: 1;\n cursor: pointer;\n pointer-events: auto;\n transform: translate(-50%, -100%);\n box-shadow:\n 0 4px 14px -4px rgba(0, 0, 0, 0.35),\n 0 0 0 1px color-mix(in srgb, var(--markup-brand) 50%, transparent);\n transition:\n background 150ms ease,\n color 150ms ease,\n opacity 150ms ease,\n top 200ms ease,\n left 200ms ease;\n}\n\n/* Deliberately close to the rest paint: an \"I'm clickable\" cue, not a state\n * change. */\n.markup-pin:hover {\n background: color-mix(in oklab, var(--markup-brand) 92%, black);\n}\n:host([data-theme='dark']) .markup-pin:hover {\n background: color-mix(in oklab, var(--markup-brand) 88%, var(--markup-paper));\n}\n@media (prefers-color-scheme: dark) {\n :host(:not([data-theme])) .markup-pin:hover {\n background: color-mix(in oklab, var(--markup-brand) 88%, var(--markup-paper));\n }\n}\n\n/* Same paint as rest: the open pin is re-located by its popover, not by a\n * colour shift. */\n.markup-pin.is-active {\n background: var(--markup-brand);\n color: #fff;\n border-color: var(--markup-paper);\n}\n.markup-pin.is-anchor {\n anchor-name: --markup-active-anchor;\n}\n\n/* Anchor selector didn't resolve, so the pin is at its fraction fallback.\n * Dimmed so a likely-wrong location reads as tentative. */\n.markup-pin.is-unresolved {\n opacity: 0.6;\n}\n\n/* Shown at the click point while the new-thread composer is open. */\n.markup-pin-ghost {\n background: var(--markup-brand);\n color: #fff;\n cursor: default;\n pointer-events: none;\n animation: markup-ghost-pulse 1200ms ease-in-out infinite;\n}\n\n/* Nudged up-right because the asymmetric disc's 4px corner shifts the\n * optical centre away from the geometric one. */\n.markup-pin-num {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n}\n\n/* Unused until an unread-reply count lands server-side. */\n.markup-pin-count {\n position: absolute;\n top: -6px;\n right: -8px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 999px;\n background: var(--markup-ink);\n color: var(--markup-paper);\n font-family: var(--markup-font-mono);\n font-size: 9.5px;\n font-weight: 600;\n line-height: 12px;\n text-align: center;\n border: 2px solid var(--markup-paper);\n pointer-events: none;\n}\n\n@keyframes markup-ghost-pulse {\n 0%,\n 100% {\n box-shadow:\n 0 4px 14px -4px rgba(0, 0, 0, 0.35),\n 0 0 0 0 rgba(227, 93, 42, 0.4);\n }\n 50% {\n box-shadow:\n 0 4px 14px -4px rgba(0, 0, 0, 0.35),\n 0 0 0 10px rgba(227, 93, 42, 0);\n }\n}\n\n/* ────────── Placement overlay ────────── */\n\n.markup-placement-overlay {\n position: fixed;\n inset: 0;\n background: var(--markup-overlay-tint);\n cursor: crosshair;\n pointer-events: auto;\n z-index: 1;\n animation: markup-overlay-in 180ms ease-out;\n}\n.markup-placement-cursor-help {\n position: fixed;\n top: 24px;\n left: 50%;\n /* baseline transform; the keyframes animate from a higher offset */\n transform: translate(-50%, 0);\n padding: 10px 16px;\n background: var(--markup-ink);\n color: var(--markup-paper);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 500;\n letter-spacing: -0.01em;\n box-shadow: var(--markup-shadow);\n pointer-events: none;\n animation: markup-help-in 220ms ease-out 60ms backwards;\n}\n\n@keyframes markup-overlay-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes markup-help-in {\n from {\n opacity: 0;\n transform: translate(-50%, -8px);\n }\n to {\n opacity: 1;\n transform: translate(-50%, 0);\n }\n}\n\n/* ────────── Popover ────────── */\n\n/*\n * `popover=\"auto\"` buys top-layer promotion plus ESC and outside-click\n * dismissal for free, at the cost of overriding the UA defaults below.\n * Position falls back to JS-supplied custom properties where CSS Anchor\n * Positioning isn't supported.\n */\n.markup-popover {\n position: fixed;\n inset: auto;\n margin: 0;\n padding: 0;\n width: 360px;\n max-width: calc(100vw - 24px);\n height: auto;\n /* never grow taller than the viewport — comments list scrolls inside */\n max-height: calc(100dvh - 24px);\n left: var(--markup-pop-x, 0);\n top: var(--markup-pop-y, 0);\n display: flex;\n flex-direction: column;\n gap: 0;\n background: var(--markup-paper);\n color: var(--markup-ink);\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius);\n box-shadow: var(--markup-shadow);\n pointer-events: auto;\n overflow: hidden;\n animation: markup-popover-in 160ms ease-out;\n}\n\n@supports (anchor-name: --x) {\n .markup-popover {\n position-anchor: --markup-active-anchor;\n left: calc(anchor(right) + 8px);\n top: calc(anchor(top) - 9px);\n /* Prefer whichever placement leaves the most block-axis room, so a pin near\n * the bottom flips above rather than clipping. */\n position-try-fallbacks:\n flip-block,\n flip-inline,\n flip-block flip-inline;\n position-try-order: most-block-size;\n }\n /* After a drag, anchor positioning and flip-fallbacks would fight the\n * user-chosen coords. */\n .markup-popover.is-floating {\n left: var(--markup-pop-x, 0);\n top: var(--markup-pop-y, 0);\n position-try-fallbacks: none;\n }\n}\n\n/* Mounted through a HUD-hide so drafts and drag position survive a peek. */\n.markup-popover.is-hud-hidden {\n display: none;\n}\n\n@keyframes markup-popover-in {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n.markup-popover-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-bottom: 1px solid var(--markup-border);\n cursor: grab;\n user-select: none;\n /* Claim touch gestures so a finger drag on the header moves the popover\n * instead of scrolling the page underneath. */\n touch-action: none;\n}\n.markup-popover.is-dragging .markup-popover-header {\n cursor: grabbing;\n}\n.markup-popover-header-actions {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n/* The route segment is what a user scans for, so it stays unmuted. */\n/* Free to ellipsise, unlike the host+path pair it replaced — a clipped\n hostname is worse than no hostname, so that one pushed the header out. */\n.markup-popover-title {\n flex: 1 1 auto;\n min-width: 0;\n font-family: var(--markup-font-mono);\n font-size: 11px;\n line-height: 1;\n letter-spacing: 0.02em;\n color: var(--markup-muted);\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.markup-thread-menu {\n position: relative;\n display: flex;\n}\n.markup-thread-menu-list {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n z-index: 10;\n min-width: 160px;\n padding: 4px;\n background: var(--markup-paper);\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius);\n box-shadow: var(--markup-shadow);\n animation: markup-menu-in 120ms ease-out;\n}\n.markup-thread-menu-item {\n display: block;\n width: 100%;\n padding: 7px 10px;\n border: none;\n border-radius: var(--markup-radius-sm);\n background: transparent;\n color: var(--markup-ink);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition:\n background 100ms ease,\n color 100ms ease;\n}\n.markup-thread-menu-item:hover {\n background: var(--markup-border);\n}\n.markup-thread-menu-item.is-danger {\n color: var(--markup-danger, #dc2626);\n}\n.markup-thread-menu-item.is-danger:hover {\n background: color-mix(in srgb, var(--markup-danger, #dc2626) 10%, transparent);\n}\n.markup-thread-menu-item:disabled {\n opacity: 0.5;\n cursor: default;\n}\n@keyframes markup-menu-in {\n from {\n opacity: 0;\n transform: translateY(-4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.markup-popover-body {\n display: flex;\n flex-direction: column;\n padding: 10px 12px 8px;\n gap: 6px;\n border-top: 1px solid var(--markup-border);\n background: var(--markup-paper);\n}\n/* Adjacency rather than dropping the border: in the composer this rule lands\n on the header's and paints two hairlines, but in a thread it is the only\n thing dividing the last comment from the composer. */\n.markup-popover-header + .markup-popover-body {\n border-top: none;\n}\n/* Redundant with the avatar, but left in the DOM for screen readers. */\n.markup-popover-byline {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n.markup-popover-name {\n color: var(--markup-ink);\n font-weight: 500;\n}\n\n.markup-icon-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n border: none;\n border-radius: var(--markup-radius-sm);\n background: transparent;\n color: var(--markup-muted);\n cursor: pointer;\n transition:\n background 120ms ease,\n color 120ms ease;\n}\n.markup-icon-btn:hover,\n.markup-icon-btn.is-open {\n background: var(--markup-border);\n color: var(--markup-ink);\n}\n\n/* ────────── Comments ────────── */\n\n.markup-comments {\n list-style: none;\n margin: 0;\n padding: 0;\n max-height: 420px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n.markup-comment {\n display: grid;\n grid-template-columns: 26px 1fr;\n column-gap: 10px;\n row-gap: 0;\n align-items: start;\n padding: 12px;\n border-bottom: 1px solid var(--markup-border);\n}\n.markup-comment:last-child {\n border-bottom: none;\n}\n.markup-comment > *:not(.markup-comment-avatar) {\n grid-column: 2;\n}\n\n/* Tones rotate deterministically, so an author always paints the same. */\n.markup-comment-avatar {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n grid-column: 1;\n /* Spans the rows because an auto-sized row grows to its tallest item: a 26px\n circle alone in row 1 would stretch the 20px meta line. */\n grid-row: 1 / span 4;\n /* Half the 26px/20px difference. Without it the circle top-aligns and its\n centre lands 3px low. Safe because the circle sizes no row. */\n margin-top: -3px;\n width: 26px;\n height: 26px;\n border-radius: 999px;\n background: var(--markup-border);\n color: var(--markup-ink);\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n user-select: none;\n overflow: hidden;\n}\n/* Uppercase initials carry no descenders, but the line box still reserves\n descent space, leaving the glyphs 0.88px high in a 26px circle — visible at\n this size. `text-box-trim` centres the letterforms themselves whatever the\n host page's font metrics are; browsers without it fall back to\n `line-height: 1`, which closes most of the same gap.\n\n It has to be its own element: the property trims a block container's line\n boxes, and a bare text node in a flex container is an anonymous item the\n rule cannot reach. */\n.markup-avatar-initials {\n line-height: 1;\n text-box-trim: trim-both;\n text-box-edge: cap alphabetic;\n}\n\n/* `cover` keeps non-square sources from stretching. */\n.markup-avatar-img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n.markup-comment-avatar[data-tone='1'] {\n background: oklch(0.85 0.07 200);\n color: oklch(0.25 0.07 230);\n}\n.markup-comment-avatar[data-tone='2'] {\n background: oklch(0.88 0.07 130);\n color: oklch(0.3 0.1 150);\n}\n.markup-comment-avatar[data-tone='3'] {\n background: oklch(0.9 0.05 50);\n color: oklch(0.35 0.1 40);\n}\n.markup-comment-avatar[data-tone='4'] {\n background: oklch(0.87 0.07 320);\n color: oklch(0.3 0.1 320);\n}\n.markup-comment-avatar[data-tone='5'] {\n background: oklch(0.88 0.06 80);\n color: oklch(0.32 0.09 70);\n}\n.markup-comment-meta {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 4px;\n min-width: 0;\n font-size: 13px;\n}\n.markup-comment-author {\n font-weight: 600;\n color: var(--markup-ink);\n font-size: 13px;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n/* Deliberately uniform. Tinting by \"the author had no host page\" put\n dashboard replies and agent writes in one bucket, so the colour meant\n neither reliably. Human vs. agent is the distinction a reader can act on,\n and the bot badge below carries it. */\n.markup-comment-badge {\n display: inline-flex;\n align-items: center;\n height: 14px;\n padding: 0 5px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--markup-team) 12%, transparent);\n color: var(--markup-team);\n font-family: var(--markup-font-mono);\n font-size: 9px;\n line-height: 1;\n font-weight: 500;\n letter-spacing: 0.12em;\n text-transform: uppercase;\n}\n/* Brand-tinted rather than warning-coloured: an agent reply is expected, it\n just has to be identifiable. Square box because a glyph needs no tracking. */\n.markup-comment-badge.is-agent {\n background: color-mix(in srgb, var(--markup-brand) 14%, transparent);\n color: var(--markup-brand);\n justify-content: center;\n width: 14px;\n padding: 0;\n letter-spacing: normal;\n}\n/* No `margin-left: auto`. Flexbox splits free space equally between every\n auto margin on the line, so a second one parks the timestamp halfway\n between the name and the actions instead of beside either. */\n.markup-comment-time {\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n letter-spacing: 0.04em;\n white-space: nowrap;\n flex-shrink: 0;\n}\n.markup-comment-body {\n margin: 0;\n font-size: 13.5px;\n line-height: 19px;\n color: var(--markup-ink);\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* Inline \" · edited\" suffix on the timestamp, matching the design's\n * compact treatment instead of a separate \"(edited)\" parenthetical. */\n.markup-comment-edited {\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n margin-left: 2px;\n}\n.markup-comment-edited::before {\n content: ' · ';\n}\n\n.markup-thread-actions {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n/* The only auto margin on the meta line, so it absorbs all free space and the\n * actions sit flush right. Do NOT add a second one: free space is divided\n * equally among them, not handed to the first. */\n.markup-comment-meta .markup-reaction-picker-wrap,\n.markup-thread-actions {\n margin-left: auto;\n}\n.markup-comment-meta .markup-reaction-add {\n width: 22px;\n height: 22px;\n margin-top: -4px;\n margin-bottom: -4px;\n}\n.markup-reaction-picker-wrap > .markup-icon-btn,\n.markup-comment-menu > .markup-icon-btn {\n margin-top: -4px;\n margin-bottom: -4px;\n}\n/* `overflow-y: auto` on the list would clip a dropdown that spills out the\n * bottom. Direction is measured on open in thread-popover.tsx. */\n.markup-comment-menu.is-up .markup-thread-menu-list {\n top: auto;\n bottom: calc(100% + 6px);\n animation-name: markup-menu-in-up;\n}\n/* A single-comment popover is too short for a vertical dropdown. */\n.markup-comment-menu.is-side .markup-thread-menu-list {\n top: -4px;\n right: calc(100% + 2px);\n animation-name: markup-menu-in-side;\n}\n@keyframes markup-menu-in-side {\n from {\n opacity: 0;\n transform: translate(4px, 0);\n }\n to {\n opacity: 1;\n transform: translate(0, 0);\n }\n}\n@keyframes markup-menu-in-up {\n from {\n opacity: 0;\n transform: translateY(4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* `position: relative` so the picker popover anchors here rather than\n * leaking out of the scroll container. */\n.markup-comment {\n position: relative;\n}\n.markup-reactions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px;\n margin-top: 6px;\n}\n.markup-reaction-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 7px;\n border: 1px solid var(--markup-border);\n border-radius: 999px;\n background: var(--markup-surface-3);\n color: var(--markup-ink);\n font: inherit;\n font-size: 11.5px;\n line-height: 1.2;\n cursor: pointer;\n transition:\n background 120ms ease,\n border-color 120ms ease;\n}\n.markup-reaction-chip:hover:not(:disabled) {\n background: var(--markup-hover);\n}\n.markup-reaction-chip.is-mine {\n background: var(--markup-accent-soft);\n border-color: color-mix(in srgb, var(--markup-brand) 50%, transparent);\n color: var(--markup-accent-ink);\n}\n.markup-reaction-chip.is-mine:hover:not(:disabled) {\n background: color-mix(in srgb, var(--markup-brand) 18%, transparent);\n}\n.markup-reaction-chip:disabled {\n cursor: default;\n opacity: 0.6;\n}\n.markup-reaction-emoji {\n font-size: 13px;\n line-height: 1;\n}\n.markup-reaction-count {\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n letter-spacing: 0.04em;\n color: var(--markup-muted);\n}\n.markup-reaction-chip.is-mine .markup-reaction-count {\n color: var(--markup-accent-ink);\n}\n\n.markup-reaction-picker-wrap {\n position: relative;\n display: inline-flex;\n flex: 0 0 auto;\n opacity: 0;\n transition: opacity 120ms ease;\n}\n/* The open state stays visible so the cursor can leave the row to reach an\n * emoji without the wrap fading out. */\n.markup-comment:hover .markup-reaction-picker-wrap,\n.markup-comment:focus-within .markup-reaction-picker-wrap,\n.markup-reaction-picker-wrap.is-open {\n opacity: 1;\n}\n.markup-reaction-add {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: var(--markup-muted);\n font: inherit;\n font-size: 13px;\n line-height: 1;\n cursor: pointer;\n transition:\n background 120ms ease,\n color 120ms ease;\n}\n.markup-reaction-add:hover,\n.markup-reaction-add.is-open {\n background: var(--markup-hover);\n color: var(--markup-ink);\n}\n\n.markup-reaction-picker {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n z-index: 1;\n display: flex;\n gap: 2px;\n padding: 4px;\n border: 1px solid var(--markup-border-strong);\n border-radius: 8px;\n background: var(--markup-paper);\n box-shadow:\n 0 1px 2px rgba(26, 22, 20, 0.06),\n 0 8px 28px rgba(26, 22, 20, 0.1);\n animation: markup-menu-in 120ms ease;\n}\n.markup-reaction-picker-wrap.is-up .markup-reaction-picker {\n top: auto;\n bottom: calc(100% + 6px);\n animation-name: markup-menu-in-up;\n}\n/* As with `.markup-comment-menu.is-side`, too short for a vertical picker. */\n.markup-reaction-picker-wrap.is-side .markup-reaction-picker {\n top: -4px;\n right: calc(100% + 2px);\n animation-name: markup-menu-in-side;\n}\n.markup-reaction-picker-item {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 6px;\n background: transparent;\n font-size: 16px;\n line-height: 1;\n cursor: pointer;\n transition: background 120ms ease;\n}\n.markup-reaction-picker-item:hover {\n background: color-mix(in srgb, var(--markup-ink) 8%, transparent);\n}\n.markup-reaction-picker-item.is-mine {\n background: color-mix(in srgb, var(--markup-brand) 14%, transparent);\n}\n\n.markup-comment-edit-form {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n/* The edit field itself is `.markup-comment-edit-input`, styled with the\n * other mention-editor rules further down. */\n.markup-comment-edit-actions {\n display: flex;\n justify-content: flex-end;\n gap: 6px;\n}\n\n/* ────────── Composer ────────── */\n\n.markup-composer {\n position: relative;\n display: flex;\n flex-direction: column;\n}\n\n.markup-composer-input {\n width: 100%;\n min-height: 38px;\n max-height: 120px;\n /* The editing host grows with its content instead of being sized by\n * `rows`, so it needs its own scroller once it hits max-height. */\n overflow-y: auto;\n padding: 2px 0;\n border: none;\n border-radius: 0;\n background: transparent;\n color: var(--markup-ink);\n font-family: var(--markup-font);\n font-size: 13.5px;\n line-height: 19px;\n transition: none;\n}\n.markup-composer-input:focus-visible {\n outline: none;\n box-shadow: none;\n}\n\n.markup-composer-footer-wrap {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 150ms ease;\n}\n.markup-composer.is-filled .markup-composer-footer-wrap {\n grid-template-rows: 1fr;\n}\n\n.markup-composer-footer {\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 0;\n border: none;\n border-radius: 0;\n background: transparent;\n opacity: 0;\n transition: opacity 100ms ease;\n}\n.markup-composer.is-filled .markup-composer-footer {\n opacity: 1;\n transition-delay: 60ms;\n}\n.markup-composer-hint {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n letter-spacing: 0.04em;\n color: var(--markup-muted);\n}\n/* The words after the chips: a little air so \"to send\" reads as a phrase\n about the keys rather than a third chip in the row. */\n.markup-composer-hint-label {\n margin-left: 2px;\n}\n.markup-composer-error {\n color: var(--markup-brand);\n}\n.markup-composer-actions {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* Scoped to the composer so it doesn't bleed into AuthorPrompt buttons. */\n.markup-composer .markup-btn-primary {\n height: 26px;\n padding: 0 10px;\n border-radius: 6px;\n background: var(--markup-ink);\n color: var(--markup-paper);\n}\n.markup-composer .markup-btn-primary:hover:not(:disabled) {\n background: color-mix(in srgb, var(--markup-ink) 88%, var(--markup-paper));\n}\n\n.markup-composer-actions-empty {\n position: absolute;\n bottom: 0;\n right: 0;\n transition: opacity 120ms ease;\n}\n.markup-composer.is-filled .markup-composer-actions-empty {\n opacity: 0;\n pointer-events: none;\n}\n\n/* ────────── Author prompt ────────── */\n\n.markup-author-prompt {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 12px;\n}\n.markup-author-status {\n margin: 0;\n color: var(--markup-muted);\n font-size: 12px;\n}\n.markup-input {\n width: 100%;\n height: 36px;\n padding: 0 10px;\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius-sm);\n background: var(--markup-paper);\n color: var(--markup-ink);\n outline: none;\n font-size: 14px;\n transition:\n border-color 120ms ease,\n box-shadow 120ms ease;\n}\n.markup-input:focus-visible {\n border-color: var(--markup-brand);\n box-shadow: 0 0 0 3px rgba(227, 93, 42, 0.18);\n}\n\n/* ────────── Buttons ────────── */\n\n.markup-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 30px;\n padding: 0 8px;\n border: 1px solid transparent;\n border-radius: var(--markup-radius-sm);\n background: transparent;\n color: var(--markup-ink);\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n letter-spacing: -0.01em;\n white-space: nowrap;\n transition:\n background 120ms ease,\n border-color 120ms ease,\n color 120ms ease,\n opacity 120ms ease;\n}\n.markup-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.markup-btn-primary {\n background: var(--markup-ink);\n color: var(--markup-paper);\n}\n.markup-btn-primary:hover:not(:disabled) {\n background: var(--markup-brand);\n}\n.markup-btn-ghost {\n color: var(--markup-muted);\n}\n.markup-btn-ghost:hover:not(:disabled) {\n background: var(--markup-border);\n color: var(--markup-ink);\n}\n\n/* ────────── Screenshot row ────────── */\n\n/* Dashed pill announcing the auto-attached screenshot. */\n.markup-screenshot-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 0;\n padding: 6px 8px;\n border: 1px dashed var(--markup-border-strong);\n border-radius: 6px;\n font-size: 11.5px;\n color: var(--markup-muted);\n}\n\n.markup-screenshot-status {\n display: flex;\n align-items: center;\n gap: 5px;\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 11px;\n letter-spacing: 0.04em;\n}\n\n/* Capture ran and produced nothing. Deliberately understated — the\n * comment still posts fine, so this is a note, not an error. */\n.markup-screenshot-row.is-failed {\n border-style: dotted;\n opacity: 0.85;\n}\n\n.markup-screenshot-toggle {\n display: flex;\n align-items: center;\n gap: 5px;\n cursor: pointer;\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 11px;\n letter-spacing: 0.04em;\n transition: color 120ms ease;\n}\n.markup-screenshot-toggle:hover {\n color: var(--markup-ink);\n}\n\n.markup-screenshot-checkbox {\n width: 12px;\n height: 12px;\n margin: 0;\n accent-color: var(--markup-brand);\n cursor: pointer;\n}\n\n.markup-screenshot-thumb {\n display: block;\n margin: -5px 0 -5px auto;\n width: auto;\n height: 25px;\n border-radius: 3px;\n border: 1px solid var(--markup-border-strong);\n object-fit: cover;\n flex-shrink: 0;\n}\n\n/* Right end of the shot-strip via `margin-left: auto`. */\n.markup-screenshot-redacted {\n margin-left: auto;\n font-family: var(--markup-font-mono);\n font-size: 10px;\n color: var(--markup-muted);\n}\n\n.markup-screenshot-redacted-chip {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 1px 7px;\n border-radius: 999px;\n border: none;\n background: color-mix(in srgb, var(--markup-success, oklch(0.62 0.16 150)) 16%, transparent);\n color: var(--markup-success, oklch(0.62 0.16 150));\n font-family: var(--markup-font-mono);\n font-size: 10px;\n cursor: pointer;\n}\n.markup-screenshot-redacted-chip:hover {\n filter: brightness(1.05);\n}\n\n.markup-screenshot-redacted-arrow {\n font-style: normal;\n}\n\n.markup-screenshot-redacted-list {\n margin-top: 3px;\n padding-left: 10px;\n}\n\n.markup-screenshot-redacted-selector {\n display: block;\n font-family: var(--markup-font-mono);\n font-size: 9px;\n color: var(--markup-muted);\n}\n\n.markup-screenshot-help {\n margin: 5px 0 0;\n font-family: var(--markup-font-mono);\n font-size: 10px;\n color: var(--markup-muted);\n line-height: 1.5;\n}\n\n.markup-screenshot-help-code {\n font-family: var(--markup-font-mono);\n color: var(--markup-ink);\n}\n\n/* ────────── Screenshot thumbnail inside first comment ────────── */\n\n.markup-comment-screenshot {\n display: block;\n margin-top: 8px;\n padding: 0;\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius-sm);\n background: transparent;\n cursor: pointer;\n overflow: hidden;\n transition:\n border-color 120ms ease,\n opacity 120ms ease;\n}\n.markup-comment-screenshot:hover {\n border-color: var(--markup-brand);\n opacity: 0.9;\n}\n.markup-comment-screenshot img {\n display: block;\n width: 100%;\n height: auto;\n max-height: 120px;\n object-fit: cover;\n object-position: top;\n}\n\n/* ────────── Screenshot lightbox ────────── */\n\n.markup-lightbox {\n position: fixed;\n inset: 0;\n width: 100%;\n height: 100%;\n max-width: 100%;\n max-height: 100%;\n margin: 0;\n padding: 24px;\n border: none;\n background: rgba(26, 22, 20, 0.88);\n}\n\n.markup-lightbox[open] {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.markup-lightbox::backdrop {\n display: none;\n}\n\n.markup-lightbox-img {\n max-width: 100%;\n max-height: 100%;\n border-radius: var(--markup-radius);\n object-fit: contain;\n box-shadow: var(--markup-shadow);\n animation: markup-lightbox-in 160ms ease-out;\n}\n\n.markup-lightbox-close {\n position: absolute;\n top: 16px;\n right: 16px;\n background: rgba(26, 22, 20, 0.6);\n color: #fdfcfa;\n}\n.markup-lightbox-close:hover {\n background: rgba(26, 22, 20, 0.85);\n color: #fdfcfa;\n}\n\n@keyframes markup-lightbox-in {\n from {\n opacity: 0;\n transform: scale(0.96);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n/* ────────── Reduced motion ────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .markup-toolbar,\n .markup-pin,\n .markup-icon-btn,\n .markup-btn,\n .markup-popover,\n .markup-pin-ghost,\n .markup-placement-overlay,\n .markup-placement-cursor-help,\n .markup-lightbox-img {\n transition: none;\n animation: none;\n }\n}\n\n/* ────────── Mentions ────────── */\n\n.markup-mention-chip {\n display: inline-block;\n padding: 0 2px;\n border-radius: 3px;\n background: var(--markup-accent-soft);\n color: var(--markup-accent-ink);\n font-weight: 500;\n}\n\n/* ── Mention editor (contenteditable) ──\n *\n * Shared base for every authoring surface; the composer and the\n * comment-edit form layer their own sizing and chrome on top. Only\n * declares what a contenteditable host needs and a textarea didn't, so\n * nothing here fights those per-surface rules.\n *\n * `position: relative` anchors the placeholder pseudo-element. It has no\n * effect on the picker overlay, which is absolute against\n * `.markup-composer` — a sibling of this element, not a descendant. */\n.markup-mention-input {\n position: relative;\n /* Newlines are stored inside text nodes rather than as <br> elements,\n * so the host needs pre-wrap to break on them. */\n white-space: pre-wrap;\n /* A pasted URL has no break opportunities and would otherwise widen\n * the popover past its own max-width. */\n overflow-wrap: anywhere;\n outline: none;\n cursor: text;\n}\n.markup-mention-input[aria-disabled='true'] {\n opacity: 0.6;\n cursor: default;\n}\n/* Absolutely positioned so the placeholder never occupies layout — as\n * in-flow `::before` content it would push the caret to its right. */\n.markup-mention-input[data-empty]::before {\n content: attr(data-placeholder);\n position: absolute;\n inset: 0 auto auto 0;\n color: var(--markup-muted);\n pointer-events: none;\n}\n/* `contenteditable=\"false\"` already makes the browser delete a chip\n * whole; this only stops one wrapping mid-name at the popover edge. */\n.markup-mention-input .markup-mention-chip {\n white-space: nowrap;\n padding: 0 3px;\n}\n\n/* Boxed variant for the comment-edit form — mirrors the\n * `.markup-textarea` it replaced. */\n.markup-comment-edit-input {\n width: 100%;\n min-height: 58px;\n max-height: 200px;\n overflow-y: auto;\n padding: 8px 10px;\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius-sm);\n background: var(--markup-paper);\n color: var(--markup-ink);\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n}\n.markup-comment-edit-input:focus-visible {\n border-color: var(--markup-brand);\n box-shadow: 0 0 0 3px rgba(227, 93, 42, 0.18);\n}\n/* The placeholder is inset by the box's own padding. */\n.markup-comment-edit-input[data-empty]::before {\n inset: 8px auto auto 10px;\n}\n\n.markup-mention-picker {\n position: absolute;\n /* `.markup-composer`'s top edge is flush with the textarea, so `bottom: 100%`\n * keeps the list adjacent to the input rather than under the hint row. */\n bottom: 100%;\n left: 0;\n right: 0;\n z-index: 10;\n margin: 0 0 4px;\n padding: 4px;\n list-style: none;\n max-height: 180px;\n overflow-y: auto;\n background: var(--markup-paper);\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius-sm);\n box-shadow: var(--markup-shadow);\n}\n\n.markup-mention-picker-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 6px 8px;\n border-radius: var(--markup-radius-sm);\n cursor: pointer;\n color: var(--markup-ink);\n font-size: 13px;\n}\n\n.markup-mention-picker-item.is-active {\n background: color-mix(in srgb, var(--markup-brand) 12%, transparent);\n}\n\n.markup-mention-picker-name {\n font-weight: 500;\n}\n\n.markup-mention-picker-trigger {\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 10px;\n}\n\n/* ────────── Notifications ────────── */\n\n/* The popover already provides chrome and dismissal, so this is only a\n * header plus a scrollable body. */\n.markup-notifications-panel {\n display: flex;\n flex-direction: column;\n max-height: min(60vh, 420px);\n color: var(--markup-ink);\n}\n\n.markup-notifications-panel-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n border-bottom: 1px solid var(--markup-border);\n}\n\n.markup-notifications-panel-header .markup-eyebrow {\n flex: 1;\n}\n\n.markup-notifications-panel-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.markup-notifications-panel-mark-all {\n background: transparent;\n border: none;\n color: var(--markup-muted);\n font-size: 11px;\n cursor: pointer;\n padding: 0;\n}\n\n.markup-notifications-panel-mark-all:hover {\n color: var(--markup-ink);\n}\n\n.markup-notifications-panel-body {\n flex: 1;\n overflow-y: auto;\n}\n\n.markup-notifications-panel-empty,\n.markup-notifications-panel-error {\n padding: 24px 12px;\n text-align: center;\n font-size: 12px;\n color: var(--markup-muted);\n}\n\n.markup-notifications-panel-empty-title {\n color: var(--markup-ink);\n font-weight: 500;\n margin: 0 0 4px;\n}\n\n.markup-notifications-panel-empty-sub {\n margin: 0;\n color: var(--markup-muted);\n line-height: 1.4;\n}\n\n.markup-notifications-panel-error {\n color: var(--markup-danger, #b91c1c);\n}\n\n.markup-notifications-panel-list {\n list-style: none;\n margin: 0;\n padding: 4px;\n}\n\n.markup-notifications-panel-row {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 8px 10px;\n width: 100%;\n background: transparent;\n border: none;\n border-radius: var(--markup-radius-sm);\n text-align: start;\n cursor: pointer;\n font: inherit;\n color: inherit;\n}\n\n.markup-notifications-panel-row:hover {\n background: color-mix(in srgb, var(--markup-brand) 8%, transparent);\n}\n\n.markup-notifications-panel-row.is-unread {\n background: color-mix(in srgb, var(--markup-brand) 5%, transparent);\n}\n\n.markup-notifications-panel-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n}\n\n.markup-notifications-panel-dot {\n width: 6px;\n height: 6px;\n border-radius: 999px;\n background: var(--markup-brand);\n flex-shrink: 0;\n}\n\n.markup-notifications-panel-actor {\n font-weight: 600;\n}\n\n.markup-notifications-panel-sep {\n color: var(--markup-muted);\n}\n\n.markup-notifications-panel-time {\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 10px;\n}\n\n.markup-notifications-panel-thread {\n margin: 0;\n font-size: 12px;\n color: var(--markup-muted);\n}\n\n.markup-notifications-panel-thread-title {\n color: var(--markup-ink);\n}\n\n.markup-notifications-panel-excerpt {\n margin: 0;\n font-size: 12px;\n font-style: italic;\n color: color-mix(in srgb, var(--markup-ink) 80%, transparent);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* ────────── Toolbar-anchored panels (inbox / privacy / shortcuts) ──────────\n * Rendered as siblings of the toolbar pill, anchored to the same corner.\n * The inner `.markup-pop[data-pop=…]` gets the shadow + border; this\n * wrapper just handles positioning + dismissal scoping. `data-panel`\n * carries the width, since the inbox wants room for excerpts while the\n * reading panels read better narrow.\n */\n.markup-panel-pop {\n position: fixed;\n bottom: 76px;\n z-index: 11;\n pointer-events: auto;\n width: 380px;\n max-width: calc(100vw - 24px);\n}\n.markup-panel-pop[data-panel='privacy'] {\n width: 340px;\n}\n.markup-panel-pop[data-panel='shortcuts'] {\n width: 320px;\n}\n.markup-panel-pop-right {\n right: 22px;\n}\n.markup-panel-pop-left {\n left: 22px;\n}\n.markup-panel-pop-center {\n left: 50%;\n transform: translateX(-50%);\n}\n.markup-panel-pop .markup-pop {\n position: static;\n width: 100%;\n animation: markup-pop-in 140ms cubic-bezier(0.2, 0.7, 0.2, 1);\n}\n.markup-panel-pop .markup-notifications-panel {\n max-height: min(60vh, 480px);\n}\n.markup-panel-pop .markup-notifications-panel-header {\n padding: 12px 14px;\n}\n.markup-panel-pop .markup-notifications-panel-header .markup-icon-btn {\n display: none;\n}\n\n/* ────────── Reading panels (privacy & data, keyboard shortcuts) ──────────\n * Both are scrollable prose surfaces rather than menus: a sticky header\n * with the eyebrow + close button, then sections of short lines. The\n * shared `.markup-panel-*` scale keeps them reading as one family.\n */\n.markup-pop[data-pop='privacy'],\n.markup-pop[data-pop='shortcuts'] {\n padding: 0;\n}\n.markup-panel {\n display: flex;\n flex-direction: column;\n max-height: min(70vh, 520px);\n color: var(--markup-ink);\n}\n.markup-panel-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 14px;\n border-bottom: 1px solid var(--markup-border);\n}\n.markup-panel-header .markup-eyebrow {\n flex: 1;\n}\n.markup-panel-body {\n flex: 1;\n overflow-y: auto;\n padding: 4px 14px 14px;\n}\n.markup-panel-section {\n padding: 10px 0;\n border-bottom: 1px solid var(--markup-border);\n}\n.markup-panel-section:last-child {\n border-bottom: none;\n padding-bottom: 2px;\n}\n.markup-panel-section-title {\n margin: 0 0 6px;\n font-family: var(--markup-font-mono);\n font-size: 10px;\n font-weight: 400;\n letter-spacing: 0.06em;\n text-transform: lowercase;\n color: var(--markup-muted);\n}\n.markup-panel-text {\n margin: 0;\n font-size: 12.5px;\n line-height: 1.5;\n color: var(--markup-ink-soft);\n}\n.markup-panel-text strong {\n font-weight: 600;\n color: var(--markup-ink);\n}\n.markup-panel-mono {\n font-family: var(--markup-font-mono);\n font-size: 11.5px;\n color: var(--markup-ink);\n word-break: break-all;\n}\n.markup-panel-list {\n margin: 0;\n padding-left: 16px;\n font-size: 12.5px;\n line-height: 1.5;\n color: var(--markup-ink-soft);\n}\n.markup-panel-list li {\n margin-bottom: 3px;\n}\n.markup-panel-list li::marker {\n color: var(--markup-muted);\n}\n.markup-panel-note {\n margin: 8px 0 0;\n font-size: 11.5px;\n line-height: 1.45;\n color: var(--markup-muted);\n}\n.markup-panel-error {\n margin: 8px 0 0;\n font-size: 11.5px;\n line-height: 1.45;\n color: var(--markup-danger);\n}\n/* Secondary, full-width action — used by the privacy panel's forget-me\n * row. Arming flips it to `is-danger`, matching the identity menu. */\n.markup-panel-action {\n margin-top: 10px;\n width: 100%;\n height: 30px;\n padding: 0 10px;\n border: 1px solid var(--markup-border-strong);\n border-radius: 7px;\n background: transparent;\n color: var(--markup-ink);\n font: inherit;\n font-size: 12.5px;\n cursor: pointer;\n transition:\n background 120ms ease,\n border-color 120ms ease,\n color 120ms ease;\n}\n.markup-panel-action:hover:not(:disabled) {\n background: var(--markup-hover);\n}\n.markup-panel-action:disabled {\n opacity: 0.6;\n cursor: default;\n}\n.markup-panel-action.is-danger {\n border-color: color-mix(in srgb, var(--markup-danger) 45%, transparent);\n color: var(--markup-danger);\n}\n.markup-panel-action.is-danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--markup-danger) 10%, transparent);\n}\n\n/* Caps reuse `.markup-kbd.is-inline`, the light-surface variant. */\n.markup-shortcut-list {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n.markup-shortcut-row {\n display: flex;\n align-items: center;\n gap: 10px;\n min-height: 24px;\n padding: 2px 0;\n}\n.markup-shortcut-label {\n flex: 1;\n min-width: 0;\n font-size: 12.5px;\n line-height: 1.4;\n color: var(--markup-ink-soft);\n}\n.markup-shortcut-keys {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n.markup-shortcut-chord {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n}\n.markup-shortcut-or {\n font-size: 10px;\n color: var(--markup-muted);\n margin-right: 1px;\n}\n","/**\n * Relayed through our own endpoint rather than a third-party SDK on the host\n * page, for the reasons `error-reporter.ts` gives.\n *\n * Nothing identifies the end user: events key on the project, and `sessionId`\n * is per-page-load and never persisted.\n */\n\nconst FLUSH_INTERVAL_MS = 10_000\n/** Matches `MAX_EVENTS_PER_BATCH` server-side, deliberately unshared —\n * widget and deployment version independently. */\nconst MAX_BATCH = 20\nconst MAX_QUEUE = 60\n\n/** Mirrors `WIDGET_EVENTS` server-side, which drops names it doesn't know. */\nexport type WidgetEvent =\n | 'widget_loaded'\n | 'comment_started'\n | 'comment_submitted'\n | 'reply_submitted'\n | 'thread_opened'\n | 'thread_resolved'\n | 'screenshot_captured'\n | 'reaction_added'\n | 'sign_in_started'\n | 'sign_in_completed'\n | 'notifications_opened'\n\ntype EventProperties = Record<string, string | number | boolean>\n\ninterface QueuedEvent {\n name: WidgetEvent\n properties?: EventProperties\n timestamp: number\n}\n\nexport interface AnalyticsConfig {\n apiUrl: string\n apiKey: string\n widgetVersion?: string\n}\n\nlet config: AnalyticsConfig | null = null\nlet queue: QueuedEvent[] = []\nlet flushTimer: ReturnType<typeof setTimeout> | null = null\nlet listenersBound = false\n\n/** Never persisted — that would make it a durable identifier. */\nconst sessionId = generateSessionId()\n\nfunction generateSessionId(): string {\n // Absent on http:// origins in some browsers. Nothing is authorised by\n // this, so the fallback needn't be unguessable.\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n return `s-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`\n}\n\n/** `null` disables and drops the queue — an opt-out that flushed the\n * backlog would not be an opt-out. */\nexport function setAnalyticsConfig(next: AnalyticsConfig | null): void {\n config = next\n if (!next) {\n queue = []\n if (flushTimer) {\n clearTimeout(flushTimer)\n flushTimer = null\n }\n return\n }\n bindUnloadFlush()\n}\n\n/** Never throws, never blocks, no-op when telemetry is off. */\nexport function track(name: WidgetEvent, properties?: EventProperties): void {\n if (!config) return\n // Drop rather than grow; the oldest events describe how the loop started.\n if (queue.length >= MAX_QUEUE) return\n\n queue.push({ name, properties, timestamp: Date.now() })\n\n if (queue.length >= MAX_BATCH) {\n void flush()\n return\n }\n if (!flushTimer) {\n flushTimer = setTimeout(() => {\n flushTimer = null\n void flush()\n }, FLUSH_INTERVAL_MS)\n }\n}\n\n/** `keepalive` so a `pagehide` flush outlives the navigation. */\nasync function flush(): Promise<void> {\n if (!config || queue.length === 0) return\n const batch = queue.splice(0, MAX_BATCH)\n if (flushTimer) {\n clearTimeout(flushTimer)\n flushTimer = null\n }\n\n try {\n await fetch(`${config.apiUrl.replace(/\\/+$/, '')}/widget/events`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-markup-api-key': config.apiKey,\n },\n body: JSON.stringify({\n sessionId,\n widgetVersion: config.widgetVersion,\n events: batch.map((e) => ({\n name: e.name,\n properties: e.properties,\n timestamp: e.timestamp,\n })),\n }),\n keepalive: true,\n })\n } catch {\n // Already spliced off, so this drops the batch. Telemetry that\n // retries is telemetry that can hammer a customer's network.\n }\n\n // Re-armed so a remainder drains on the usual cadence rather than waiting\n // for a `track()` call that may never come. On `pagehide` the timer never\n // fires and the remainder is accepted as lost.\n if (config && queue.length > 0 && !flushTimer) {\n flushTimer = setTimeout(() => {\n flushTimer = null\n void flush()\n }, FLUSH_INTERVAL_MS)\n }\n}\n\n/**\n * `pagehide`, not `beforeunload` — the latter disqualifies the page from\n * the back/forward cache. `visibilitychange` covers mobile tab-switching.\n */\nfunction bindUnloadFlush(): void {\n if (listenersBound || typeof window === 'undefined') return\n listenersBound = true\n\n const send = () => void flush()\n window.addEventListener('pagehide', send)\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') send()\n })\n}\n","/**\n * On a render error the children unmount and the widget disappears, leaving the\n * host page's DOM untouched rather than painting a broken UI over the\n * customer's site.\n *\n * This boundary wraps only our component tree, which is what makes anything it\n * catches definitively widget code however the widget was delivered.\n *\n * Both `getDerivedStateFromError` and `componentDidCatch` are implemented so\n * the render state updates synchronously and the report runs in a later phase.\n */\n\nimport { Component, type ComponentChildren } from 'preact'\n\ninterface WidgetErrorBoundaryProps {\n children: ComponentChildren\n /** No filtering: by construction everything under here is widget code. */\n onError: (err: Error) => void\n}\n\ninterface WidgetErrorBoundaryState {\n hasError: boolean\n}\n\nexport class WidgetErrorBoundary extends Component<\n WidgetErrorBoundaryProps,\n WidgetErrorBoundaryState\n> {\n state: WidgetErrorBoundaryState = { hasError: false }\n\n static getDerivedStateFromError(): WidgetErrorBoundaryState {\n return { hasError: true }\n }\n\n componentDidCatch(error: Error): void {\n // Belt + braces — the reporter swallows network errors itself,\n // but if something inside the reporter throws synchronously we\n // don't want it to re-enter the boundary and loop.\n try {\n this.props.onError(error)\n } catch {\n /* swallow */\n }\n }\n\n render() {\n if (this.state.hasError) {\n // Render nothing on crash. Showing a fallback UI on the\n // customer's site is worse than silently disappearing — they\n // didn't sign up for our error UX on their page.\n return null\n }\n return this.props.children\n }\n}\n","/**\n * Relays to Sentry through `/widget/error` rather than bundling\n * `@sentry/browser`: a third-party ingest in `connect-src` is CSP-blocked on a\n * meaningful fraction of host pages, and the SDK is ~30 KB gzip against <1 KB\n * here on a page we promised one script tag's worth of code.\n *\n * There is **no window-level `error` / `unhandledrejection` listener**, by\n * design. One would either report the customer's own script errors as ours, or\n * fall back to URL-pattern guessing that doesn't generalise across CDN and\n * npm-bundled delivery. Only the Preact error boundary and explicit\n * `reportWidgetError` calls feed this, both of which are certainly widget code.\n *\n * The cost is that unwrapped timer callbacks, raw event listeners and\n * `.catch()`-less promise chains go unreported. Coverage grows by adding\n * explicit calls, not by installing a leaky window backstop.\n */\n\nexport interface ErrorReporterConfig {\n apiUrl: string\n apiKey: string\n /** String shipped with every event so the Sentry inbox can split by version. */\n widgetVersion?: string\n}\n\nconst MIN_REPORT_INTERVAL_MS = 1000\n\ninterface SendReportInput {\n message: string\n name?: string\n stack?: string\n url?: string\n userAgent?: string\n context?: string\n}\n\nfunction buildSender(config: ErrorReporterConfig): (payload: SendReportInput) => void {\n let inflight = false\n let lastSentAt = 0\n\n return (payload) => {\n const now = Date.now()\n if (inflight) return\n if (now - lastSentAt < MIN_REPORT_INTERVAL_MS) return\n inflight = true\n lastSentAt = now\n\n // A fatal error is usually followed by a refresh, and without `keepalive`\n // the pending fetch is cancelled on unload and the event is lost.\n fetch(`${config.apiUrl.replace(/\\/+$/, '')}/widget/error`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-markup-api-key': config.apiKey,\n },\n body: JSON.stringify({\n ...payload,\n widgetVersion: config.widgetVersion,\n }),\n keepalive: true,\n })\n .catch(() => {\n // The error is already on the user's screen; \"failed to report\" on\n // top of it is noise.\n })\n .finally(() => {\n inflight = false\n })\n }\n}\n\nfunction currentLocation(): string | undefined {\n return typeof window !== 'undefined' ? window.location.href : undefined\n}\n\nfunction currentUserAgent(): string | undefined {\n return typeof navigator !== 'undefined' ? navigator.userAgent : undefined\n}\n\n/**\n * Rate-limited to one report per second with in-flight coalescing, so a render\n * loop can't saturate the network. Keyed by `config` reference, so every caller\n * passing the same object shares one window.\n */\nconst senderCache = new WeakMap<ErrorReporterConfig, (payload: SendReportInput) => void>()\n\nexport function reportWidgetError(\n config: ErrorReporterConfig,\n err: unknown,\n extra?: { context?: string },\n): void {\n let send = senderCache.get(config)\n if (!send) {\n send = buildSender(config)\n senderCache.set(config, send)\n }\n const error = err instanceof Error ? err : new Error(String(err))\n send({\n message: error.message,\n name: error.name,\n stack: error.stack,\n url: currentLocation(),\n userAgent: currentUserAgent(),\n context: extra?.context,\n })\n}\n\n/**\n * Ambient so runtime code can report without threading config through every\n * signature. A single slot suffices because the widget is singleton-per-page;\n * multi-mount would make this a `WeakMap<Window, …>`.\n *\n * A no-op when nothing is registered, so an error thrown during teardown\n * doesn't blow up on a destroyed reporter.\n */\nlet activeReporter: ErrorReporterConfig | null = null\n\nexport function setActiveReporter(config: ErrorReporterConfig | null): void {\n activeReporter = config\n}\n\nexport function reportError(err: unknown, extra?: { context?: string }): void {\n if (!activeReporter) return\n reportWidgetError(activeReporter, err, extra)\n}\n","/**\n * `auto` works by *removing* the host's `data-theme` so the shadow CSS falls\n * back to `prefers-color-scheme`; the media-query listener exists only to\n * re-render subscribers showing the resolved value.\n */\n\nconst STORAGE_KEY = 'markup:widget:theme'\n\nexport type ThemeMode = 'light' | 'dark' | 'auto'\ntype Listener = (mode: ThemeMode) => void\n\nlet host: HTMLElement | null = null\nlet mode: ThemeMode = readPersisted() ?? 'auto'\n/**\n * Must stay a live flag, not a load-time snapshot: this module outlives an\n * `init()` → `destroy()` → `init()` cycle, and a stale snapshot would let the\n * host's `theme` prop clobber a choice the user just made.\n */\nlet userPicked = readPersisted() != null\nconst listeners = new Set<Listener>()\n\nfunction readPersisted(): ThemeMode | null {\n try {\n const v = localStorage.getItem(STORAGE_KEY)\n if (v === 'light' || v === 'dark' || v === 'auto') return v\n } catch {\n // localStorage may throw in sandboxed iframes; fall through.\n }\n return null\n}\n\nfunction apply() {\n if (!host) return\n if (mode === 'auto') {\n delete host.dataset.theme\n } else {\n host.dataset.theme = mode\n }\n}\n\n/** `initial` only wins when the user has never picked a theme. */\nexport function bindThemeHost(el: HTMLElement, initial?: ThemeMode) {\n host = el\n if (!userPicked && initial) mode = initial\n apply()\n}\n\nexport function getThemeMode(): ThemeMode {\n return mode\n}\n\n/** For `auto`, reads `prefers-color-scheme` — what the picker displays. */\nexport function resolvedTheme(): 'light' | 'dark' {\n if (mode === 'dark') return 'dark'\n if (mode === 'light') return 'light'\n if (typeof window !== 'undefined' && window.matchMedia) {\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n }\n return 'light'\n}\n\nexport function setThemeMode(next: ThemeMode) {\n if (next === mode) return\n mode = next\n // Before the write: if localStorage is unavailable the choice can't outlive\n // the page, but it must still beat the host config while the page lives.\n userPicked = true\n try {\n localStorage.setItem(STORAGE_KEY, next)\n } catch {\n // Same rationale as readPersisted — non-fatal.\n }\n apply()\n for (const fn of listeners) fn(mode)\n}\n\nexport function subscribeTheme(fn: Listener): () => void {\n listeners.add(fn)\n return () => {\n listeners.delete(fn)\n }\n}\n\n/** Fire `auto`-resolved theme changes when the OS pref flips. */\nexport function watchSystemTheme(): () => void {\n if (typeof window === 'undefined' || !window.matchMedia) return () => {}\n const mq = window.matchMedia('(prefers-color-scheme: dark)')\n const handler = () => {\n if (mode === 'auto') for (const fn of listeners) fn(mode)\n }\n mq.addEventListener?.('change', handler)\n return () => mq.removeEventListener?.('change', handler)\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,p=c.__;function s(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,y(D,n)}function y(n,u,i){var o=s(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=!1,i=o.__c.props!==n;if(o.__c.__H.__.some(function(n){if(n.__N){u=!0;var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),c){var f=c.call(this,n,t,r);return u?f||i:f}return!u||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 h(n,u){var i=s(t++,3);!c.__s&&C(i.__H,u)&&(i.__=n,i.u=u,r.__H.__h.push(i))}function _(n,u){var i=s(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=s(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=s(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=s(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=s(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();){var t=n.__H;if(n.__P&&t)try{t.__h.some(z),t.__h.some(B),t.__h=[]}catch(r){t.__h=[],c.__e(r,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),p&&p(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.__.some(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0})):(i.__h.some(z),i.__h.some(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.__.some(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.some(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.__.some(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,h as useEffect,b as useErrorBoundary,g as useId,F as useImperativeHandle,_ as useLayoutEffect,T as useMemo,y as useReducer,A as useRef,d as useState};\n//# sourceMappingURL=hooks.module.js.map\n","\"use strict\";\nexport const version = \"1.38.0\";\n//# sourceMappingURL=index.js.map\n","\"use strict\";\nvar lookup = [];\nvar revLookup = [];\nvar Arr = Uint8Array;\nvar code = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i];\n revLookup[code.charCodeAt(i)] = i;\n}\nrevLookup[\"-\".charCodeAt(0)] = 62;\nrevLookup[\"_\".charCodeAt(0)] = 63;\nfunction getLens(b64) {\n var len = b64.length;\n if (len % 4 > 0) {\n throw new Error(\"Invalid string. Length must be a multiple of 4\");\n }\n var validLen = b64.indexOf(\"=\");\n if (validLen === -1) validLen = len;\n var placeHoldersLen = validLen === len ? 0 : 4 - validLen % 4;\n return [validLen, placeHoldersLen];\n}\nexport function byteLength(b64) {\n var lens = getLens(b64);\n var validLen = lens[0];\n var placeHoldersLen = lens[1];\n return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;\n}\nfunction _byteLength(_b64, validLen, placeHoldersLen) {\n return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;\n}\nexport function toByteArray(b64) {\n var tmp;\n var lens = getLens(b64);\n var validLen = lens[0];\n var placeHoldersLen = lens[1];\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));\n var curByte = 0;\n var len = placeHoldersLen > 0 ? validLen - 4 : validLen;\n var i;\n for (i = 0; i < len; i += 4) {\n tmp = revLookup[b64.charCodeAt(i)] << 18 | revLookup[b64.charCodeAt(i + 1)] << 12 | revLookup[b64.charCodeAt(i + 2)] << 6 | revLookup[b64.charCodeAt(i + 3)];\n arr[curByte++] = tmp >> 16 & 255;\n arr[curByte++] = tmp >> 8 & 255;\n arr[curByte++] = tmp & 255;\n }\n if (placeHoldersLen === 2) {\n tmp = revLookup[b64.charCodeAt(i)] << 2 | revLookup[b64.charCodeAt(i + 1)] >> 4;\n arr[curByte++] = tmp & 255;\n }\n if (placeHoldersLen === 1) {\n tmp = revLookup[b64.charCodeAt(i)] << 10 | revLookup[b64.charCodeAt(i + 1)] << 4 | revLookup[b64.charCodeAt(i + 2)] >> 2;\n arr[curByte++] = tmp >> 8 & 255;\n arr[curByte++] = tmp & 255;\n }\n return arr;\n}\nfunction tripletToBase64(num) {\n return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63];\n}\nfunction encodeChunk(uint8, start, end) {\n var tmp;\n var output = [];\n for (var i = start; i < end; i += 3) {\n tmp = (uint8[i] << 16 & 16711680) + (uint8[i + 1] << 8 & 65280) + (uint8[i + 2] & 255);\n output.push(tripletToBase64(tmp));\n }\n return output.join(\"\");\n}\nexport function fromByteArray(uint8) {\n var tmp;\n var len = uint8.length;\n var extraBytes = len % 3;\n var parts = [];\n var maxChunkLength = 16383;\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(\n encodeChunk(\n uint8,\n i,\n i + maxChunkLength > len2 ? len2 : i + maxChunkLength\n )\n );\n }\n if (extraBytes === 1) {\n tmp = uint8[len - 1];\n parts.push(lookup[tmp >> 2] + lookup[tmp << 4 & 63] + \"==\");\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1];\n parts.push(\n lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + \"=\"\n );\n }\n return parts.join(\"\");\n}\nexport function fromByteArrayUrlSafeNoPadding(uint8) {\n return fromByteArray(uint8).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n//# sourceMappingURL=base64.js.map\n","\"use strict\";\nexport function parseArgs(args) {\n if (args === void 0) {\n return {};\n }\n if (!isSimpleObject(args)) {\n throw new Error(\n `The arguments to a Convex function must be an object. Received: ${args}`\n );\n }\n return args;\n}\nexport function validateDeploymentUrl(deploymentUrl) {\n if (typeof deploymentUrl === \"undefined\") {\n throw new Error(\n `Client created with undefined deployment address. If you used an environment variable, check that it's set.`\n );\n }\n if (typeof deploymentUrl !== \"string\") {\n throw new Error(\n `Invalid deployment address: found ${deploymentUrl}\".`\n );\n }\n if (!(deploymentUrl.startsWith(\"http:\") || deploymentUrl.startsWith(\"https:\"))) {\n throw new Error(\n `Invalid deployment address: Must start with \"https://\" or \"http://\". Found \"${deploymentUrl}\".`\n );\n }\n try {\n new URL(deploymentUrl);\n } catch {\n throw new Error(\n `Invalid deployment address: \"${deploymentUrl}\" is not a valid URL. If you believe this URL is correct, use the \\`skipConvexDeploymentUrlCheck\\` option to bypass this.`\n );\n }\n if (deploymentUrl.endsWith(\".convex.site\")) {\n throw new Error(\n `Invalid deployment address: \"${deploymentUrl}\" ends with .convex.site, which is used for HTTP Actions. Convex deployment URLs typically end with .convex.cloud? If you believe this URL is correct, use the \\`skipConvexDeploymentUrlCheck\\` option to bypass this.`\n );\n }\n}\nexport function isSimpleObject(value) {\n const isObject = typeof value === \"object\";\n const prototype = Object.getPrototypeOf(value);\n const isSimple = prototype === null || prototype === Object.prototype || // Objects generated from other contexts (e.g. across Node.js `vm` modules) will not satisfy the previous\n // conditions but are still simple objects.\n prototype?.constructor?.name === \"Object\";\n return isObject && isSimple;\n}\n//# sourceMappingURL=index.js.map\n","\"use strict\";\nimport * as Base64 from \"./base64.js\";\nimport { isSimpleObject } from \"../common/index.js\";\nconst LITTLE_ENDIAN = true;\nconst MIN_INT64 = BigInt(\"-9223372036854775808\");\nconst MAX_INT64 = BigInt(\"9223372036854775807\");\nconst ZERO = BigInt(\"0\");\nconst EIGHT = BigInt(\"8\");\nconst TWOFIFTYSIX = BigInt(\"256\");\nfunction isSpecial(n) {\n return Number.isNaN(n) || !Number.isFinite(n) || Object.is(n, -0);\n}\nexport function slowBigIntToBase64(value) {\n if (value < ZERO) {\n value -= MIN_INT64 + MIN_INT64;\n }\n let hex = value.toString(16);\n if (hex.length % 2 === 1) hex = \"0\" + hex;\n const bytes = new Uint8Array(new ArrayBuffer(8));\n let i = 0;\n for (const hexByte of hex.match(/.{2}/g).reverse()) {\n bytes.set([parseInt(hexByte, 16)], i++);\n value >>= EIGHT;\n }\n return Base64.fromByteArray(bytes);\n}\nexport function slowBase64ToBigInt(encoded) {\n const integerBytes = Base64.toByteArray(encoded);\n if (integerBytes.byteLength !== 8) {\n throw new Error(\n `Received ${integerBytes.byteLength} bytes, expected 8 for $integer`\n );\n }\n let value = ZERO;\n let power = ZERO;\n for (const byte of integerBytes) {\n value += BigInt(byte) * TWOFIFTYSIX ** power;\n power++;\n }\n if (value > MAX_INT64) {\n value += MIN_INT64 + MIN_INT64;\n }\n return value;\n}\nexport function modernBigIntToBase64(value) {\n if (value < MIN_INT64 || MAX_INT64 < value) {\n throw new Error(\n `BigInt ${value} does not fit into a 64-bit signed integer.`\n );\n }\n const buffer = new ArrayBuffer(8);\n new DataView(buffer).setBigInt64(0, value, true);\n return Base64.fromByteArray(new Uint8Array(buffer));\n}\nexport function modernBase64ToBigInt(encoded) {\n const integerBytes = Base64.toByteArray(encoded);\n if (integerBytes.byteLength !== 8) {\n throw new Error(\n `Received ${integerBytes.byteLength} bytes, expected 8 for $integer`\n );\n }\n const intBytesView = new DataView(integerBytes.buffer);\n return intBytesView.getBigInt64(0, true);\n}\nexport const bigIntToBase64 = DataView.prototype.setBigInt64 ? modernBigIntToBase64 : slowBigIntToBase64;\nexport const base64ToBigInt = DataView.prototype.getBigInt64 ? modernBase64ToBigInt : slowBase64ToBigInt;\nconst MAX_IDENTIFIER_LEN = 1024;\nfunction validateObjectField(k) {\n if (k.length > MAX_IDENTIFIER_LEN) {\n throw new Error(\n `Field name ${k} exceeds maximum field name length ${MAX_IDENTIFIER_LEN}.`\n );\n }\n if (k.startsWith(\"$\")) {\n throw new Error(`Field name ${k} starts with a '$', which is reserved.`);\n }\n for (let i = 0; i < k.length; i += 1) {\n const charCode = k.charCodeAt(i);\n if (charCode < 32 || charCode >= 127) {\n throw new Error(\n `Field name ${k} has invalid character '${k[i]}': Field names can only contain non-control ASCII characters`\n );\n }\n }\n}\nexport function jsonToConvex(value) {\n if (value === null) {\n return value;\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((value2) => jsonToConvex(value2));\n }\n if (typeof value !== \"object\") {\n throw new Error(`Unexpected type of ${value}`);\n }\n const entries = Object.entries(value);\n if (entries.length === 1) {\n const key = entries[0][0];\n if (key === \"$bytes\") {\n if (typeof value.$bytes !== \"string\") {\n throw new Error(`Malformed $bytes field on ${value}`);\n }\n return Base64.toByteArray(value.$bytes).buffer;\n }\n if (key === \"$integer\") {\n if (typeof value.$integer !== \"string\") {\n throw new Error(`Malformed $integer field on ${value}`);\n }\n return base64ToBigInt(value.$integer);\n }\n if (key === \"$float\") {\n if (typeof value.$float !== \"string\") {\n throw new Error(`Malformed $float field on ${value}`);\n }\n const floatBytes = Base64.toByteArray(value.$float);\n if (floatBytes.byteLength !== 8) {\n throw new Error(\n `Received ${floatBytes.byteLength} bytes, expected 8 for $float`\n );\n }\n const floatBytesView = new DataView(floatBytes.buffer);\n const float = floatBytesView.getFloat64(0, LITTLE_ENDIAN);\n if (!isSpecial(float)) {\n throw new Error(`Float ${float} should be encoded as a number`);\n }\n return float;\n }\n if (key === \"$set\") {\n throw new Error(\n `Received a Set which is no longer supported as a Convex type.`\n );\n }\n if (key === \"$map\") {\n throw new Error(\n `Received a Map which is no longer supported as a Convex type.`\n );\n }\n }\n const out = {};\n for (const [k, v] of Object.entries(value)) {\n validateObjectField(k);\n out[k] = jsonToConvex(v);\n }\n return out;\n}\nconst MAX_VALUE_FOR_ERROR_LEN = 16384;\nexport function stringifyValueForError(value) {\n const str = JSON.stringify(value, (_key, value2) => {\n if (value2 === void 0) {\n return \"undefined\";\n }\n if (typeof value2 === \"bigint\") {\n return `${value2.toString()}n`;\n }\n return value2;\n });\n if (str.length > MAX_VALUE_FOR_ERROR_LEN) {\n const rest = \"[...truncated]\";\n let truncateAt = MAX_VALUE_FOR_ERROR_LEN - rest.length;\n const codePoint = str.codePointAt(truncateAt - 1);\n if (codePoint !== void 0 && codePoint > 65535) {\n truncateAt -= 1;\n }\n return str.substring(0, truncateAt) + rest;\n }\n return str;\n}\nfunction convexToJsonInternal(value, originalValue, context, includeTopLevelUndefined) {\n if (value === void 0) {\n const contextText = context && ` (present at path ${context} in original object ${stringifyValueForError(\n originalValue\n )})`;\n throw new Error(\n `undefined is not a valid Convex value${contextText}. To learn about Convex's supported types, see https://docs.convex.dev/using/types.`\n );\n }\n if (value === null) {\n return value;\n }\n if (typeof value === \"bigint\") {\n if (value < MIN_INT64 || MAX_INT64 < value) {\n throw new Error(\n `BigInt ${value} does not fit into a 64-bit signed integer.`\n );\n }\n return { $integer: bigIntToBase64(value) };\n }\n if (typeof value === \"number\") {\n if (isSpecial(value)) {\n const buffer = new ArrayBuffer(8);\n new DataView(buffer).setFloat64(0, value, LITTLE_ENDIAN);\n return { $float: Base64.fromByteArray(new Uint8Array(buffer)) };\n } else {\n return value;\n }\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (value instanceof ArrayBuffer) {\n return { $bytes: Base64.fromByteArray(new Uint8Array(value)) };\n }\n if (Array.isArray(value)) {\n return value.map(\n (value2, i) => convexToJsonInternal(value2, originalValue, context + `[${i}]`, false)\n );\n }\n if (value instanceof Set) {\n throw new Error(\n errorMessageForUnsupportedType(context, \"Set\", [...value], originalValue)\n );\n }\n if (value instanceof Map) {\n throw new Error(\n errorMessageForUnsupportedType(context, \"Map\", [...value], originalValue)\n );\n }\n if (!isSimpleObject(value)) {\n const theType = value?.constructor?.name;\n const typeName = theType ? `${theType} ` : \"\";\n throw new Error(\n errorMessageForUnsupportedType(context, typeName, value, originalValue)\n );\n }\n const out = {};\n const entries = Object.entries(value);\n entries.sort(([k1, _v1], [k2, _v2]) => k1 === k2 ? 0 : k1 < k2 ? -1 : 1);\n for (const [k, v] of entries) {\n if (v !== void 0) {\n validateObjectField(k);\n out[k] = convexToJsonInternal(v, originalValue, context + `.${k}`, false);\n } else if (includeTopLevelUndefined) {\n validateObjectField(k);\n out[k] = convexOrUndefinedToJsonInternal(\n v,\n originalValue,\n context + `.${k}`\n );\n }\n }\n return out;\n}\nfunction errorMessageForUnsupportedType(context, typeName, value, originalValue) {\n if (context) {\n return `${typeName}${stringifyValueForError(\n value\n )} is not a supported Convex type (present at path ${context} in original object ${stringifyValueForError(\n originalValue\n )}). To learn about Convex's supported types, see https://docs.convex.dev/using/types.`;\n } else {\n return `${typeName}${stringifyValueForError(\n value\n )} is not a supported Convex type.`;\n }\n}\nfunction convexOrUndefinedToJsonInternal(value, originalValue, context) {\n if (value === void 0) {\n return { $undefined: null };\n } else {\n if (originalValue === void 0) {\n throw new Error(\n `Programming error. Current value is ${stringifyValueForError(\n value\n )} but original value is undefined`\n );\n }\n return convexToJsonInternal(value, originalValue, context, false);\n }\n}\nexport function convexToJson(value) {\n return convexToJsonInternal(value, value, \"\", false);\n}\nexport function convexOrUndefinedToJson(value) {\n return convexOrUndefinedToJsonInternal(value, value, \"\");\n}\nexport function patchValueToJson(value) {\n return convexToJsonInternal(value, value, \"\", true);\n}\n//# sourceMappingURL=value.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nvar _a, _b;\nimport { stringifyValueForError } from \"./value.js\";\nconst IDENTIFYING_FIELD = Symbol.for(\"ConvexError\");\nexport class ConvexError extends (_b = Error, _a = IDENTIFYING_FIELD, _b) {\n constructor(data) {\n super(typeof data === \"string\" ? data : stringifyValueForError(data));\n __publicField(this, \"name\", \"ConvexError\");\n __publicField(this, \"data\");\n __publicField(this, _a, true);\n this.data = data;\n }\n}\n//# sourceMappingURL=errors.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nconst INFO_COLOR = \"color:rgb(0, 145, 255)\";\nfunction prefix_for_source(source) {\n switch (source) {\n case \"query\":\n return \"Q\";\n case \"mutation\":\n return \"M\";\n case \"action\":\n return \"A\";\n case \"any\":\n return \"?\";\n }\n}\nexport class DefaultLogger {\n constructor(options) {\n __publicField(this, \"_onLogLineFuncs\");\n __publicField(this, \"_verbose\");\n this._onLogLineFuncs = {};\n this._verbose = options.verbose;\n }\n addLogLineListener(func) {\n let id = Math.random().toString(36).substring(2, 15);\n for (let i = 0; i < 10; i++) {\n if (this._onLogLineFuncs[id] === void 0) {\n break;\n }\n id = Math.random().toString(36).substring(2, 15);\n }\n this._onLogLineFuncs[id] = func;\n return () => {\n delete this._onLogLineFuncs[id];\n };\n }\n logVerbose(...args) {\n if (this._verbose) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"debug\", `${(/* @__PURE__ */ new Date()).toISOString()}`, ...args);\n }\n }\n }\n log(...args) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"info\", ...args);\n }\n }\n warn(...args) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"warn\", ...args);\n }\n }\n error(...args) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"error\", ...args);\n }\n }\n}\nexport function instantiateDefaultLogger(options) {\n const logger = new DefaultLogger(options);\n logger.addLogLineListener((level, ...args) => {\n switch (level) {\n case \"debug\":\n console.debug(...args);\n break;\n case \"info\":\n console.log(...args);\n break;\n case \"warn\":\n console.warn(...args);\n break;\n case \"error\":\n console.error(...args);\n break;\n default: {\n level;\n console.log(...args);\n }\n }\n });\n return logger;\n}\nexport function instantiateNoopLogger(options) {\n return new DefaultLogger(options);\n}\nexport function logForFunction(logger, type, source, udfPath, message) {\n const prefix = prefix_for_source(source);\n if (typeof message === \"object\") {\n message = `ConvexError ${JSON.stringify(message.errorData, null, 2)}`;\n }\n if (type === \"info\") {\n const match = message.match(/^\\[.*?\\] /);\n if (match === null) {\n logger.error(\n `[CONVEX ${prefix}(${udfPath})] Could not parse console.log`\n );\n return;\n }\n const level = message.slice(1, match[0].length - 2);\n const args = message.slice(match[0].length);\n logger.log(`%c[CONVEX ${prefix}(${udfPath})] [${level}]`, INFO_COLOR, args);\n } else {\n logger.error(`[CONVEX ${prefix}(${udfPath})] ${message}`);\n }\n}\nexport function logFatalError(logger, message) {\n const errorMessage = `[CONVEX FATAL ERROR] ${message}`;\n logger.error(errorMessage);\n return new Error(errorMessage);\n}\nexport function createHybridErrorStacktrace(source, udfPath, result) {\n const prefix = prefix_for_source(source);\n return `[CONVEX ${prefix}(${udfPath})] ${result.errorMessage}\n Called by client`;\n}\nexport function forwardData(result, error) {\n error.data = result.errorData;\n return error;\n}\n//# sourceMappingURL=logging.js.map\n","\"use strict\";\nimport { convexToJson } from \"../../values/index.js\";\nexport function canonicalizeUdfPath(udfPath) {\n const pieces = udfPath.split(\":\");\n let moduleName;\n let functionName;\n if (pieces.length === 1) {\n moduleName = pieces[0];\n functionName = \"default\";\n } else {\n moduleName = pieces.slice(0, pieces.length - 1).join(\":\");\n functionName = pieces[pieces.length - 1];\n }\n if (moduleName.endsWith(\".js\")) {\n moduleName = moduleName.slice(0, -3);\n }\n return `${moduleName}:${functionName}`;\n}\nexport function serializePathAndArgs(udfPath, args) {\n return JSON.stringify({\n udfPath: canonicalizeUdfPath(udfPath),\n args: convexToJson(args)\n });\n}\nexport function serializePaginatedPathAndArgs(udfPath, args, options) {\n const { initialNumItems, id } = options;\n const result = JSON.stringify({\n type: \"paginated\",\n udfPath: canonicalizeUdfPath(udfPath),\n args: convexToJson(args),\n options: convexToJson({ initialNumItems, id })\n });\n return result;\n}\nexport function serializedQueryTokenIsPaginated(token) {\n return JSON.parse(token).type === \"paginated\";\n}\n//# sourceMappingURL=udf_path_utils.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { convexToJson } from \"../../values/index.js\";\nimport {\n canonicalizeUdfPath,\n serializePathAndArgs\n} from \"./udf_path_utils.js\";\nexport class LocalSyncState {\n constructor() {\n __publicField(this, \"nextQueryId\");\n __publicField(this, \"querySetVersion\");\n __publicField(this, \"querySet\");\n __publicField(this, \"queryIdToToken\");\n __publicField(this, \"identityVersion\");\n __publicField(this, \"auth\");\n __publicField(this, \"outstandingQueriesOlderThanRestart\");\n __publicField(this, \"outstandingAuthOlderThanRestart\");\n __publicField(this, \"paused\");\n __publicField(this, \"pendingQuerySetModifications\");\n this.nextQueryId = 0;\n this.querySetVersion = 0;\n this.identityVersion = 0;\n this.querySet = /* @__PURE__ */ new Map();\n this.queryIdToToken = /* @__PURE__ */ new Map();\n this.outstandingQueriesOlderThanRestart = /* @__PURE__ */ new Set();\n this.outstandingAuthOlderThanRestart = false;\n this.paused = false;\n this.pendingQuerySetModifications = /* @__PURE__ */ new Map();\n }\n hasSyncedPastLastReconnect() {\n return this.outstandingQueriesOlderThanRestart.size === 0 && !this.outstandingAuthOlderThanRestart;\n }\n markAuthCompletion() {\n this.outstandingAuthOlderThanRestart = false;\n }\n subscribe(udfPath, args, journal, componentPath) {\n const canonicalizedUdfPath = canonicalizeUdfPath(udfPath);\n const queryToken = serializePathAndArgs(canonicalizedUdfPath, args);\n const existingEntry = this.querySet.get(queryToken);\n if (existingEntry !== void 0) {\n existingEntry.numSubscribers += 1;\n return {\n queryToken,\n modification: null,\n unsubscribe: () => this.removeSubscriber(queryToken)\n };\n } else {\n const queryId = this.nextQueryId++;\n const query = {\n id: queryId,\n canonicalizedUdfPath,\n args,\n numSubscribers: 1,\n journal,\n componentPath\n };\n this.querySet.set(queryToken, query);\n this.queryIdToToken.set(queryId, queryToken);\n const baseVersion = this.querySetVersion;\n const newVersion = this.querySetVersion + 1;\n const add = {\n type: \"Add\",\n queryId,\n udfPath: canonicalizedUdfPath,\n args: [convexToJson(args)],\n journal,\n componentPath\n };\n if (this.paused) {\n this.pendingQuerySetModifications.set(queryId, add);\n } else {\n this.querySetVersion = newVersion;\n }\n const modification = {\n type: \"ModifyQuerySet\",\n baseVersion,\n newVersion,\n modifications: [add]\n };\n return {\n queryToken,\n modification,\n unsubscribe: () => this.removeSubscriber(queryToken)\n };\n }\n }\n transition(transition) {\n for (const modification of transition.modifications) {\n switch (modification.type) {\n case \"QueryUpdated\":\n case \"QueryFailed\": {\n this.outstandingQueriesOlderThanRestart.delete(modification.queryId);\n const journal = modification.journal;\n if (journal !== void 0) {\n const queryToken = this.queryIdToToken.get(modification.queryId);\n if (queryToken !== void 0) {\n this.querySet.get(queryToken).journal = journal;\n }\n }\n break;\n }\n case \"QueryRemoved\": {\n this.outstandingQueriesOlderThanRestart.delete(modification.queryId);\n break;\n }\n default: {\n modification;\n throw new Error(`Invalid modification ${modification.type}`);\n }\n }\n }\n }\n queryId(udfPath, args) {\n const canonicalizedUdfPath = canonicalizeUdfPath(udfPath);\n const queryToken = serializePathAndArgs(canonicalizedUdfPath, args);\n const existingEntry = this.querySet.get(queryToken);\n if (existingEntry !== void 0) {\n return existingEntry.id;\n }\n return null;\n }\n isCurrentOrNewerAuthVersion(version) {\n return version >= this.identityVersion;\n }\n getAuth() {\n return this.auth;\n }\n setAuth(value) {\n this.auth = {\n tokenType: \"User\",\n value\n };\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n baseVersion,\n ...this.auth\n };\n }\n setAdminAuth(value, actingAs) {\n const auth = {\n tokenType: \"Admin\",\n value,\n impersonating: actingAs\n };\n this.auth = auth;\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n baseVersion,\n ...auth\n };\n }\n clearAuth() {\n this.auth = void 0;\n this.markAuthCompletion();\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n tokenType: \"None\",\n baseVersion\n };\n }\n hasAuth() {\n return !!this.auth;\n }\n isNewAuth(value) {\n return this.auth?.value !== value;\n }\n queryPath(queryId) {\n const pathAndArgs = this.queryIdToToken.get(queryId);\n if (pathAndArgs) {\n return this.querySet.get(pathAndArgs).canonicalizedUdfPath;\n }\n return null;\n }\n queryArgs(queryId) {\n const pathAndArgs = this.queryIdToToken.get(queryId);\n if (pathAndArgs) {\n return this.querySet.get(pathAndArgs).args;\n }\n return null;\n }\n queryToken(queryId) {\n return this.queryIdToToken.get(queryId) ?? null;\n }\n queryJournal(queryToken) {\n return this.querySet.get(queryToken)?.journal;\n }\n restart() {\n this.unpause();\n this.outstandingQueriesOlderThanRestart.clear();\n const modifications = [];\n for (const localQuery of this.querySet.values()) {\n const add = {\n type: \"Add\",\n queryId: localQuery.id,\n udfPath: localQuery.canonicalizedUdfPath,\n args: [convexToJson(localQuery.args)],\n journal: localQuery.journal,\n componentPath: localQuery.componentPath\n };\n modifications.push(add);\n this.outstandingQueriesOlderThanRestart.add(localQuery.id);\n }\n this.querySetVersion = 1;\n const querySet = {\n type: \"ModifyQuerySet\",\n baseVersion: 0,\n newVersion: 1,\n modifications\n };\n if (!this.auth) {\n this.identityVersion = 0;\n return [querySet, void 0];\n }\n this.outstandingAuthOlderThanRestart = true;\n const authenticate = {\n type: \"Authenticate\",\n baseVersion: 0,\n ...this.auth\n };\n this.identityVersion = 1;\n return [querySet, authenticate];\n }\n pause() {\n this.paused = true;\n }\n resume() {\n const querySet = this.pendingQuerySetModifications.size > 0 ? {\n type: \"ModifyQuerySet\",\n baseVersion: this.querySetVersion,\n newVersion: ++this.querySetVersion,\n modifications: Array.from(\n this.pendingQuerySetModifications.values()\n )\n } : void 0;\n const authenticate = this.auth !== void 0 ? {\n type: \"Authenticate\",\n baseVersion: this.identityVersion++,\n ...this.auth\n } : void 0;\n this.unpause();\n return [querySet, authenticate];\n }\n unpause() {\n this.paused = false;\n this.pendingQuerySetModifications.clear();\n }\n removeSubscriber(queryToken) {\n const localQuery = this.querySet.get(queryToken);\n if (localQuery.numSubscribers > 1) {\n localQuery.numSubscribers -= 1;\n return null;\n } else {\n this.querySet.delete(queryToken);\n this.queryIdToToken.delete(localQuery.id);\n this.outstandingQueriesOlderThanRestart.delete(localQuery.id);\n const baseVersion = this.querySetVersion;\n const newVersion = this.querySetVersion + 1;\n const remove = {\n type: \"Remove\",\n queryId: localQuery.id\n };\n if (this.paused) {\n if (this.pendingQuerySetModifications.has(localQuery.id)) {\n this.pendingQuerySetModifications.delete(localQuery.id);\n } else {\n this.pendingQuerySetModifications.set(localQuery.id, remove);\n }\n } else {\n this.querySetVersion = newVersion;\n }\n return {\n type: \"ModifyQuerySet\",\n baseVersion,\n newVersion,\n modifications: [remove]\n };\n }\n }\n}\n//# sourceMappingURL=local_state.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { jsonToConvex } from \"../../values/index.js\";\nimport { logForFunction } from \"../logging.js\";\nexport class RequestManager {\n constructor(logger, markConnectionStateDirty) {\n this.logger = logger;\n this.markConnectionStateDirty = markConnectionStateDirty;\n __publicField(this, \"inflightRequests\");\n __publicField(this, \"requestsOlderThanRestart\");\n __publicField(this, \"inflightMutationsCount\", 0);\n __publicField(this, \"inflightActionsCount\", 0);\n this.inflightRequests = /* @__PURE__ */ new Map();\n this.requestsOlderThanRestart = /* @__PURE__ */ new Set();\n }\n request(message, sent) {\n const result = new Promise((resolve) => {\n const status = sent ? \"Requested\" : \"NotSent\";\n this.inflightRequests.set(message.requestId, {\n message,\n status: { status, requestedAt: /* @__PURE__ */ new Date(), onResult: resolve }\n });\n if (message.type === \"Mutation\") {\n this.inflightMutationsCount++;\n } else if (message.type === \"Action\") {\n this.inflightActionsCount++;\n }\n });\n this.markConnectionStateDirty();\n return result;\n }\n /**\n * Update the state after receiving a response.\n *\n * @returns A RequestId if the request is complete and its optimistic update\n * can be dropped, null otherwise.\n */\n onResponse(response) {\n const requestInfo = this.inflightRequests.get(response.requestId);\n if (requestInfo === void 0) {\n return null;\n }\n if (requestInfo.status.status === \"Completed\") {\n return null;\n }\n const udfType = requestInfo.message.type === \"Mutation\" ? \"mutation\" : \"action\";\n const udfPath = requestInfo.message.udfPath;\n for (const line of response.logLines) {\n logForFunction(this.logger, \"info\", udfType, udfPath, line);\n }\n const status = requestInfo.status;\n let result;\n let onResolve;\n if (response.success) {\n result = {\n success: true,\n logLines: response.logLines,\n value: jsonToConvex(response.result)\n };\n onResolve = () => status.onResult(result);\n } else {\n const errorMessage = response.result;\n const { errorData } = response;\n logForFunction(this.logger, \"error\", udfType, udfPath, errorMessage);\n result = {\n success: false,\n errorMessage,\n errorData: errorData !== void 0 ? jsonToConvex(errorData) : void 0,\n logLines: response.logLines\n };\n onResolve = () => status.onResult(result);\n }\n if (response.type === \"ActionResponse\" || !response.success) {\n onResolve();\n this.inflightRequests.delete(response.requestId);\n this.requestsOlderThanRestart.delete(response.requestId);\n if (requestInfo.message.type === \"Action\") {\n this.inflightActionsCount--;\n } else if (requestInfo.message.type === \"Mutation\") {\n this.inflightMutationsCount--;\n }\n this.markConnectionStateDirty();\n return { requestId: response.requestId, result };\n }\n requestInfo.status = {\n status: \"Completed\",\n result,\n ts: response.ts,\n onResolve\n };\n return null;\n }\n // Remove and returns completed requests.\n removeCompleted(ts) {\n const completeRequests = /* @__PURE__ */ new Map();\n for (const [requestId, requestInfo] of this.inflightRequests.entries()) {\n const status = requestInfo.status;\n if (status.status === \"Completed\" && status.ts.lessThanOrEqual(ts)) {\n status.onResolve();\n completeRequests.set(requestId, status.result);\n if (requestInfo.message.type === \"Mutation\") {\n this.inflightMutationsCount--;\n } else if (requestInfo.message.type === \"Action\") {\n this.inflightActionsCount--;\n }\n this.inflightRequests.delete(requestId);\n this.requestsOlderThanRestart.delete(requestId);\n }\n }\n if (completeRequests.size > 0) {\n this.markConnectionStateDirty();\n }\n return completeRequests;\n }\n restart() {\n this.requestsOlderThanRestart = new Set(this.inflightRequests.keys());\n const allMessages = [];\n for (const [requestId, value] of this.inflightRequests) {\n if (value.status.status === \"NotSent\") {\n value.status.status = \"Requested\";\n allMessages.push(value.message);\n continue;\n }\n if (value.message.type === \"Mutation\") {\n allMessages.push(value.message);\n } else if (value.message.type === \"Action\") {\n this.inflightRequests.delete(requestId);\n this.requestsOlderThanRestart.delete(requestId);\n this.inflightActionsCount--;\n if (value.status.status === \"Completed\") {\n throw new Error(\"Action should never be in 'Completed' state\");\n }\n value.status.onResult({\n success: false,\n errorMessage: \"Connection lost while action was in flight\",\n logLines: []\n });\n }\n }\n this.markConnectionStateDirty();\n return allMessages;\n }\n resume() {\n const allMessages = [];\n for (const [, value] of this.inflightRequests) {\n if (value.status.status === \"NotSent\") {\n value.status.status = \"Requested\";\n allMessages.push(value.message);\n continue;\n }\n }\n return allMessages;\n }\n /**\n * @returns true if there are any requests that have been requested but have\n * not be completed yet.\n */\n hasIncompleteRequests() {\n for (const requestInfo of this.inflightRequests.values()) {\n if (requestInfo.status.status === \"Requested\") {\n return true;\n }\n }\n return false;\n }\n /**\n * @returns true if there are any inflight requests, including ones that have\n * completed on the server, but have not been applied.\n */\n hasInflightRequests() {\n return this.inflightRequests.size > 0;\n }\n /**\n * @returns true if there are any inflight requests, that have been hanging around\n * since prior to the most recent restart.\n */\n hasSyncedPastLastReconnect() {\n return this.requestsOlderThanRestart.size === 0;\n }\n timeOfOldestInflightRequest() {\n if (this.inflightRequests.size === 0) {\n return null;\n }\n let oldestInflightRequest = Date.now();\n for (const request of this.inflightRequests.values()) {\n if (request.status.status !== \"Completed\") {\n if (request.status.requestedAt.getTime() < oldestInflightRequest) {\n oldestInflightRequest = request.status.requestedAt.getTime();\n }\n }\n }\n return new Date(oldestInflightRequest);\n }\n /**\n * @returns The number of mutations currently in flight.\n */\n inflightMutations() {\n return this.inflightMutationsCount;\n }\n /**\n * @returns The number of actions currently in flight.\n */\n inflightActions() {\n return this.inflightActionsCount;\n }\n}\n//# sourceMappingURL=request_manager.js.map\n","\"use strict\";\nexport const functionName = Symbol.for(\"functionName\");\n//# sourceMappingURL=functionName.js.map\n","\"use strict\";\nimport { functionName } from \"../functionName.js\";\nexport const toReferencePath = Symbol.for(\"toReferencePath\");\nexport function setReferencePath(obj, value) {\n obj[toReferencePath] = value;\n}\nexport function extractReferencePath(reference) {\n return reference[toReferencePath] ?? null;\n}\nexport function isFunctionHandle(s) {\n return s.startsWith(\"function://\");\n}\nexport function getFunctionAddress(functionReference) {\n let functionAddress;\n if (typeof functionReference === \"string\") {\n if (isFunctionHandle(functionReference)) {\n functionAddress = { functionHandle: functionReference };\n } else {\n functionAddress = { name: functionReference };\n }\n } else if (functionReference[functionName]) {\n functionAddress = { name: functionReference[functionName] };\n } else {\n const referencePath = extractReferencePath(functionReference);\n if (!referencePath) {\n throw new Error(`${functionReference} is not a functionReference`);\n }\n functionAddress = { reference: referencePath };\n }\n return functionAddress;\n}\n//# sourceMappingURL=paths.js.map\n","\"use strict\";\nimport { functionName } from \"./functionName.js\";\nimport { getFunctionAddress } from \"./components/paths.js\";\nexport function getFunctionName(functionReference) {\n const address = getFunctionAddress(functionReference);\n if (address.name === void 0) {\n if (address.functionHandle !== void 0) {\n throw new Error(\n `Expected function reference like \"api.file.func\" or \"internal.file.func\", but received function handle ${address.functionHandle}`\n );\n } else if (address.reference !== void 0) {\n throw new Error(\n `Expected function reference in the current component like \"api.file.func\" or \"internal.file.func\", but received reference ${address.reference}`\n );\n }\n throw new Error(\n `Expected function reference like \"api.file.func\" or \"internal.file.func\", but received ${JSON.stringify(address)}`\n );\n }\n if (typeof functionReference === \"string\") return functionReference;\n const name = functionReference[functionName];\n if (!name) {\n throw new Error(`${functionReference} is not a functionReference`);\n }\n return name;\n}\nexport function makeFunctionReference(name) {\n return { [functionName]: name };\n}\nfunction createApi(pathParts = []) {\n const handler = {\n get(_, prop) {\n if (typeof prop === \"string\") {\n const newParts = [...pathParts, prop];\n return createApi(newParts);\n } else if (prop === functionName) {\n if (pathParts.length < 2) {\n const found = [\"api\", ...pathParts].join(\".\");\n throw new Error(\n `API path is expected to be of the form \\`api.moduleName.functionName\\`. Found: \\`${found}\\``\n );\n }\n const path = pathParts.slice(0, -1).join(\"/\");\n const exportName = pathParts[pathParts.length - 1];\n if (exportName === \"default\") {\n return path;\n } else {\n return path + \":\" + exportName;\n }\n } else if (prop === Symbol.toStringTag) {\n return \"FunctionReference\";\n } else {\n return void 0;\n }\n }\n };\n return new Proxy({}, handler);\n}\nexport function filterApi(api) {\n return api;\n}\nexport function justInternal(api) {\n return api;\n}\nexport function justPublic(api) {\n return api;\n}\nexport function justQueries(api) {\n return api;\n}\nexport function justMutations(api) {\n return api;\n}\nexport function justActions(api) {\n return api;\n}\nexport function justPaginatedQueries(api) {\n return api;\n}\nexport function justSchedulable(api) {\n return api;\n}\nexport const anyApi = createApi();\n//# sourceMappingURL=api.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport {\n getFunctionName\n} from \"../../server/api.js\";\nimport { parseArgs } from \"../../common/index.js\";\nimport { createHybridErrorStacktrace, forwardData } from \"../logging.js\";\nimport {\n canonicalizeUdfPath,\n serializePathAndArgs\n} from \"./udf_path_utils.js\";\nimport { ConvexError } from \"../../values/errors.js\";\nclass OptimisticLocalStoreImpl {\n constructor(queryResults) {\n // A references of the query results in OptimisticQueryResults\n __publicField(this, \"queryResults\");\n // All of the queries modified by this class\n __publicField(this, \"modifiedQueries\");\n this.queryResults = queryResults;\n this.modifiedQueries = [];\n }\n getQuery(query, ...args) {\n const queryArgs = parseArgs(args[0]);\n const name = getFunctionName(query);\n const queryResult = this.queryResults.get(\n serializePathAndArgs(name, queryArgs)\n );\n if (queryResult === void 0) {\n return void 0;\n }\n return OptimisticLocalStoreImpl.queryValue(queryResult.result);\n }\n getAllQueries(query) {\n const queriesWithName = [];\n const name = getFunctionName(query);\n for (const queryResult of this.queryResults.values()) {\n if (queryResult.udfPath === canonicalizeUdfPath(name)) {\n queriesWithName.push({\n args: queryResult.args,\n value: OptimisticLocalStoreImpl.queryValue(queryResult.result)\n });\n }\n }\n return queriesWithName;\n }\n setQuery(queryReference, args, value) {\n const queryArgs = parseArgs(args);\n const name = getFunctionName(queryReference);\n const queryToken = serializePathAndArgs(name, queryArgs);\n let result;\n if (value === void 0) {\n result = void 0;\n } else {\n result = {\n success: true,\n value,\n // It's an optimistic update, so there are no function logs to show.\n logLines: []\n };\n }\n const query = {\n udfPath: name,\n args: queryArgs,\n result\n };\n this.queryResults.set(queryToken, query);\n this.modifiedQueries.push(queryToken);\n }\n static queryValue(result) {\n if (result === void 0) {\n return void 0;\n } else if (result.success) {\n return result.value;\n } else {\n return void 0;\n }\n }\n}\nexport class OptimisticQueryResults {\n constructor() {\n __publicField(this, \"queryResults\");\n __publicField(this, \"optimisticUpdates\");\n this.queryResults = /* @__PURE__ */ new Map();\n this.optimisticUpdates = [];\n }\n /**\n * Apply all optimistic updates on top of server query results\n */\n ingestQueryResultsFromServer(serverQueryResults, optimisticUpdatesToDrop) {\n this.optimisticUpdates = this.optimisticUpdates.filter((updateAndId) => {\n return !optimisticUpdatesToDrop.has(updateAndId.mutationId);\n });\n const oldQueryResults = this.queryResults;\n this.queryResults = new Map(serverQueryResults);\n const localStore = new OptimisticLocalStoreImpl(this.queryResults);\n for (const updateAndId of this.optimisticUpdates) {\n updateAndId.update(localStore);\n }\n const changedQueries = [];\n for (const [queryToken, query] of this.queryResults) {\n const oldQuery = oldQueryResults.get(queryToken);\n if (oldQuery === void 0 || oldQuery.result !== query.result) {\n changedQueries.push(queryToken);\n }\n }\n return changedQueries;\n }\n applyOptimisticUpdate(update, mutationId) {\n this.optimisticUpdates.push({\n update,\n mutationId\n });\n const localStore = new OptimisticLocalStoreImpl(this.queryResults);\n update(localStore);\n return localStore.modifiedQueries;\n }\n /**\n * \"Raw\" with respect to errors vs values, but query results still have\n * optimistic updates applied.\n *\n * @internal\n */\n rawQueryResult(queryToken) {\n const query = this.queryResults.get(queryToken);\n if (query === void 0) {\n return void 0;\n }\n return query.result;\n }\n queryResult(queryToken) {\n const query = this.queryResults.get(queryToken);\n if (query === void 0) {\n return void 0;\n }\n const result = query.result;\n if (result === void 0) {\n return void 0;\n } else if (result.success) {\n return result.value;\n } else {\n if (result.errorData !== void 0) {\n throw forwardData(\n result,\n new ConvexError(\n createHybridErrorStacktrace(\"query\", query.udfPath, result)\n )\n );\n }\n throw new Error(\n createHybridErrorStacktrace(\"query\", query.udfPath, result)\n );\n }\n }\n hasQueryResult(queryToken) {\n return this.queryResults.get(queryToken) !== void 0;\n }\n /**\n * @internal\n */\n queryLogs(queryToken) {\n const query = this.queryResults.get(queryToken);\n return query?.result?.logLines;\n }\n}\n//# sourceMappingURL=optimistic_updates_impl.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nexport class Long {\n constructor(low, high) {\n __publicField(this, \"low\");\n __publicField(this, \"high\");\n __publicField(this, \"__isUnsignedLong__\");\n this.low = low | 0;\n this.high = high | 0;\n this.__isUnsignedLong__ = true;\n }\n static isLong(obj) {\n return (obj && obj.__isUnsignedLong__) === true;\n }\n // prettier-ignore\n static fromBytesLE(bytes) {\n return new Long(\n bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24,\n bytes[4] | bytes[5] << 8 | bytes[6] << 16 | bytes[7] << 24\n );\n }\n // prettier-ignore\n toBytesLE() {\n const hi = this.high;\n const lo = this.low;\n return [\n lo & 255,\n lo >>> 8 & 255,\n lo >>> 16 & 255,\n lo >>> 24,\n hi & 255,\n hi >>> 8 & 255,\n hi >>> 16 & 255,\n hi >>> 24\n ];\n }\n static fromNumber(value) {\n if (isNaN(value)) return UZERO;\n if (value < 0) return UZERO;\n if (value >= TWO_PWR_64_DBL) return MAX_UNSIGNED_VALUE;\n return new Long(value % TWO_PWR_32_DBL | 0, value / TWO_PWR_32_DBL | 0);\n }\n toString() {\n return (BigInt(this.high) * BigInt(TWO_PWR_32_DBL) + BigInt(this.low)).toString();\n }\n equals(other) {\n if (!Long.isLong(other)) other = Long.fromValue(other);\n if (this.high >>> 31 === 1 && other.high >>> 31 === 1) return false;\n return this.high === other.high && this.low === other.low;\n }\n notEquals(other) {\n return !this.equals(other);\n }\n comp(other) {\n if (!Long.isLong(other)) other = Long.fromValue(other);\n if (this.equals(other)) return 0;\n return other.high >>> 0 > this.high >>> 0 || other.high === this.high && other.low >>> 0 > this.low >>> 0 ? -1 : 1;\n }\n lessThanOrEqual(other) {\n return this.comp(\n /* validates */\n other\n ) <= 0;\n }\n static fromValue(val) {\n if (typeof val === \"number\") return Long.fromNumber(val);\n return new Long(val.low, val.high);\n }\n}\nconst UZERO = new Long(0, 0);\nconst TWO_PWR_16_DBL = 1 << 16;\nconst TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;\nconst TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;\nconst MAX_UNSIGNED_VALUE = new Long(4294967295 | 0, 4294967295 | 0);\n//# sourceMappingURL=long.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { jsonToConvex } from \"../../values/index.js\";\nimport { Long } from \"../../vendor/long.js\";\nimport { logForFunction } from \"../logging.js\";\nexport class RemoteQuerySet {\n constructor(queryPath, logger) {\n __publicField(this, \"version\");\n __publicField(this, \"remoteQuerySet\");\n __publicField(this, \"queryPath\");\n __publicField(this, \"logger\");\n this.version = { querySet: 0, ts: Long.fromNumber(0), identity: 0 };\n this.remoteQuerySet = /* @__PURE__ */ new Map();\n this.queryPath = queryPath;\n this.logger = logger;\n }\n transition(transition) {\n const start = transition.startVersion;\n if (this.version.querySet !== start.querySet || this.version.ts.notEquals(start.ts) || this.version.identity !== start.identity) {\n throw new Error(\n `Invalid start version: ${start.ts.toString()}:${start.querySet}:${start.identity}, transitioning from ${this.version.ts.toString()}:${this.version.querySet}:${this.version.identity}`\n );\n }\n for (const modification of transition.modifications) {\n switch (modification.type) {\n case \"QueryUpdated\": {\n const queryPath = this.queryPath(modification.queryId);\n if (queryPath) {\n for (const line of modification.logLines) {\n logForFunction(this.logger, \"info\", \"query\", queryPath, line);\n }\n }\n const value = jsonToConvex(modification.value ?? null);\n this.remoteQuerySet.set(modification.queryId, {\n success: true,\n value,\n logLines: modification.logLines\n });\n break;\n }\n case \"QueryFailed\": {\n const queryPath = this.queryPath(modification.queryId);\n if (queryPath) {\n for (const line of modification.logLines) {\n logForFunction(this.logger, \"info\", \"query\", queryPath, line);\n }\n }\n const { errorData } = modification;\n this.remoteQuerySet.set(modification.queryId, {\n success: false,\n errorMessage: modification.errorMessage,\n errorData: errorData !== void 0 ? jsonToConvex(errorData) : void 0,\n logLines: modification.logLines\n });\n break;\n }\n case \"QueryRemoved\": {\n this.remoteQuerySet.delete(modification.queryId);\n break;\n }\n default: {\n modification;\n throw new Error(`Invalid modification ${modification.type}`);\n }\n }\n }\n this.version = transition.endVersion;\n }\n remoteQueryResults() {\n return this.remoteQuerySet;\n }\n timestamp() {\n return this.version.ts;\n }\n}\n//# sourceMappingURL=remote_query_set.js.map\n","\"use strict\";\nimport { Base64 } from \"../../values/index.js\";\nimport { Long } from \"../../vendor/long.js\";\nexport function u64ToLong(encoded) {\n const integerBytes = Base64.toByteArray(encoded);\n return Long.fromBytesLE(Array.from(integerBytes));\n}\nexport function longToU64(raw) {\n const integerBytes = new Uint8Array(raw.toBytesLE());\n return Base64.fromByteArray(integerBytes);\n}\nexport function parseServerMessage(encoded) {\n switch (encoded.type) {\n case \"FatalError\":\n case \"AuthError\":\n case \"ActionResponse\":\n case \"TransitionChunk\":\n case \"Ping\": {\n return { ...encoded };\n }\n case \"MutationResponse\": {\n if (encoded.success) {\n return { ...encoded, ts: u64ToLong(encoded.ts) };\n } else {\n return { ...encoded };\n }\n }\n case \"Transition\": {\n return {\n ...encoded,\n startVersion: {\n ...encoded.startVersion,\n ts: u64ToLong(encoded.startVersion.ts)\n },\n endVersion: {\n ...encoded.endVersion,\n ts: u64ToLong(encoded.endVersion.ts)\n }\n };\n }\n default: {\n encoded;\n }\n }\n return void 0;\n}\nexport function encodeClientMessage(message) {\n switch (message.type) {\n case \"Authenticate\":\n case \"ModifyQuerySet\":\n case \"Mutation\":\n case \"Action\":\n case \"Event\": {\n return { ...message };\n }\n case \"Connect\": {\n if (message.maxObservedTimestamp !== void 0) {\n return {\n ...message,\n maxObservedTimestamp: longToU64(message.maxObservedTimestamp)\n };\n } else {\n return { ...message, maxObservedTimestamp: void 0 };\n }\n }\n default: {\n message;\n }\n }\n return void 0;\n}\n//# sourceMappingURL=protocol.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport {\n encodeClientMessage,\n parseServerMessage\n} from \"./protocol.js\";\nconst CLOSE_NORMAL = 1e3;\nconst CLOSE_GOING_AWAY = 1001;\nconst CLOSE_NO_STATUS = 1005;\nconst CLOSE_NOT_FOUND = 4040;\nlet firstTime;\nfunction monotonicMillis() {\n if (firstTime === void 0) {\n firstTime = Date.now();\n }\n if (typeof performance === \"undefined\" || !performance.now) {\n return Date.now();\n }\n return Math.round(firstTime + performance.now());\n}\nfunction prettyNow() {\n return `t=${Math.round((monotonicMillis() - firstTime) / 100) / 10}s`;\n}\nconst serverDisconnectErrors = {\n // A known error, e.g. during a restart or push\n InternalServerError: { timeout: 1e3 },\n // ErrorMetadata::overloaded() messages that we realy should back off\n SubscriptionsWorkerFullError: { timeout: 3e3 },\n TooManyConcurrentRequests: { timeout: 3e3 },\n CommitterFullError: { timeout: 3e3 },\n AwsTooManyRequestsException: { timeout: 3e3 },\n ExecuteFullError: { timeout: 3e3 },\n SystemTimeoutError: { timeout: 3e3 },\n ExpiredInQueue: { timeout: 3e3 },\n // ErrorMetadata::feature_temporarily_unavailable() that typically indicate a deploy just happened\n VectorIndexesUnavailable: { timeout: 1e3 },\n SearchIndexesUnavailable: { timeout: 1e3 },\n TableSummariesUnavailable: { timeout: 1e3 },\n // More ErrorMetadata::overloaded()\n VectorIndexTooLarge: { timeout: 3e3 },\n SearchIndexTooLarge: { timeout: 3e3 },\n TooManyWritesInTimePeriod: { timeout: 3e3 }\n};\nfunction classifyDisconnectError(s) {\n if (s === void 0) return \"Unknown\";\n for (const prefix of Object.keys(\n serverDisconnectErrors\n )) {\n if (s.startsWith(prefix)) {\n return prefix;\n }\n }\n return \"Unknown\";\n}\nexport class WebSocketManager {\n constructor(uri, callbacks, webSocketConstructor, logger, markConnectionStateDirty, debug) {\n this.markConnectionStateDirty = markConnectionStateDirty;\n this.debug = debug;\n __publicField(this, \"socket\");\n __publicField(this, \"connectionCount\");\n __publicField(this, \"_hasEverConnected\", false);\n __publicField(this, \"lastCloseReason\");\n // State for assembling the split-up Transition currently being received.\n __publicField(this, \"transitionChunkBuffer\", null);\n /** Upon HTTPS/WSS failure, the first jittered backoff duration, in ms. */\n __publicField(this, \"defaultInitialBackoff\");\n /** We backoff exponentially, but we need to cap that--this is the jittered max. */\n __publicField(this, \"maxBackoff\");\n /** How many times have we failed consecutively? */\n __publicField(this, \"retries\");\n /** How long before lack of server response causes us to initiate a reconnect,\n * in ms */\n __publicField(this, \"serverInactivityThreshold\");\n __publicField(this, \"reconnectDueToServerInactivityTimeout\");\n /** Scheduled reconnect state: timeout handle and timing info */\n __publicField(this, \"scheduledReconnect\", null);\n __publicField(this, \"networkOnlineHandler\", null);\n /** Pending event to send after reconnecting due to network recovery */\n __publicField(this, \"pendingNetworkRecoveryInfo\", null);\n __publicField(this, \"uri\");\n __publicField(this, \"onOpen\");\n __publicField(this, \"onResume\");\n __publicField(this, \"onMessage\");\n __publicField(this, \"webSocketConstructor\");\n __publicField(this, \"logger\");\n __publicField(this, \"onServerDisconnectError\");\n this.webSocketConstructor = webSocketConstructor;\n this.socket = { state: \"disconnected\" };\n this.connectionCount = 0;\n this.lastCloseReason = \"InitialConnect\";\n this.defaultInitialBackoff = 1e3;\n this.maxBackoff = 16e3;\n this.retries = 0;\n this.serverInactivityThreshold = 6e4;\n this.reconnectDueToServerInactivityTimeout = null;\n this.uri = uri;\n this.onOpen = callbacks.onOpen;\n this.onResume = callbacks.onResume;\n this.onMessage = callbacks.onMessage;\n this.onServerDisconnectError = callbacks.onServerDisconnectError;\n this.logger = logger;\n this.setupNetworkListener();\n this.connect();\n }\n setSocketState(state) {\n this.socket = state;\n this._logVerbose(\n `socket state changed: ${this.socket.state}, paused: ${\"paused\" in this.socket ? this.socket.paused : void 0}`\n );\n this.markConnectionStateDirty();\n }\n setupNetworkListener() {\n if (typeof window === \"undefined\" || typeof window.addEventListener !== \"function\") {\n return;\n }\n if (this.networkOnlineHandler !== null) {\n return;\n }\n this.networkOnlineHandler = () => {\n this._logVerbose(\"network online event detected\");\n this.tryReconnectImmediately();\n };\n window.addEventListener(\"online\", this.networkOnlineHandler);\n this._logVerbose(\"network online event listener registered\");\n }\n cleanupNetworkListener() {\n if (this.networkOnlineHandler && typeof window !== \"undefined\" && typeof window.removeEventListener === \"function\") {\n window.removeEventListener(\"online\", this.networkOnlineHandler);\n this.networkOnlineHandler = null;\n this._logVerbose(\"network online event listener removed\");\n }\n }\n assembleTransition(chunk) {\n if (chunk.partNumber < 0 || chunk.partNumber >= chunk.totalParts || chunk.totalParts === 0 || this.transitionChunkBuffer && (this.transitionChunkBuffer.totalParts !== chunk.totalParts || this.transitionChunkBuffer.transitionId !== chunk.transitionId)) {\n this.transitionChunkBuffer = null;\n throw new Error(\"Invalid TransitionChunk\");\n }\n if (this.transitionChunkBuffer === null) {\n this.transitionChunkBuffer = {\n chunks: [],\n totalParts: chunk.totalParts,\n transitionId: chunk.transitionId\n };\n }\n if (chunk.partNumber !== this.transitionChunkBuffer.chunks.length) {\n const expectedLength = this.transitionChunkBuffer.chunks.length;\n this.transitionChunkBuffer = null;\n throw new Error(\n `TransitionChunk received out of order: expected part ${expectedLength}, got ${chunk.partNumber}`\n );\n }\n this.transitionChunkBuffer.chunks.push(chunk.chunk);\n if (this.transitionChunkBuffer.chunks.length === chunk.totalParts) {\n const fullJson = this.transitionChunkBuffer.chunks.join(\"\");\n this.transitionChunkBuffer = null;\n const transition = parseServerMessage(JSON.parse(fullJson));\n if (transition.type !== \"Transition\") {\n throw new Error(\n `Expected Transition, got ${transition.type} after assembling chunks`\n );\n }\n return transition;\n }\n return null;\n }\n connect() {\n if (this.socket.state === \"terminated\") {\n return;\n }\n if (this.socket.state !== \"disconnected\" && this.socket.state !== \"stopped\") {\n throw new Error(\n \"Didn't start connection from disconnected state: \" + this.socket.state\n );\n }\n const ws = new this.webSocketConstructor(this.uri);\n this._logVerbose(\"constructed WebSocket\");\n this.setSocketState({\n state: \"connecting\",\n ws,\n paused: \"no\"\n });\n this.resetServerInactivityTimeout();\n ws.onopen = () => {\n this.logger.logVerbose(\"begin ws.onopen\");\n if (this.socket.state !== \"connecting\") {\n throw new Error(\"onopen called with socket not in connecting state\");\n }\n this.setSocketState({\n state: \"ready\",\n ws,\n paused: this.socket.paused === \"yes\" ? \"uninitialized\" : \"no\"\n });\n this.resetServerInactivityTimeout();\n if (this.socket.paused === \"no\") {\n this._hasEverConnected = true;\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n clientTs: monotonicMillis()\n });\n }\n if (this.lastCloseReason !== \"InitialConnect\") {\n if (this.lastCloseReason) {\n this.logger.log(\n \"WebSocket reconnected at\",\n prettyNow(),\n \"after disconnect due to\",\n this.lastCloseReason\n );\n } else {\n this.logger.log(\"WebSocket reconnected at\", prettyNow());\n }\n }\n this.connectionCount += 1;\n this.lastCloseReason = null;\n if (this.pendingNetworkRecoveryInfo !== null) {\n const { timeSavedMs } = this.pendingNetworkRecoveryInfo;\n this.pendingNetworkRecoveryInfo = null;\n this.sendMessage({\n type: \"Event\",\n eventType: \"NetworkRecoveryReconnect\",\n event: { timeSavedMs }\n });\n this.logger.log(\n `Network recovery reconnect saved ~${Math.round(timeSavedMs / 1e3)}s of waiting`\n );\n }\n };\n ws.onerror = (error) => {\n this.transitionChunkBuffer = null;\n const message = error.message;\n if (message) {\n this.logger.log(`WebSocket error message: ${message}`);\n }\n };\n ws.onmessage = (message) => {\n this.resetServerInactivityTimeout();\n const messageLength = message.data.length;\n let serverMessage = parseServerMessage(JSON.parse(message.data));\n this._logVerbose(`received ws message with type ${serverMessage.type}`);\n if (serverMessage.type === \"Ping\") {\n return;\n }\n if (serverMessage.type === \"TransitionChunk\") {\n const transition = this.assembleTransition(serverMessage);\n if (!transition) {\n return;\n }\n serverMessage = transition;\n this._logVerbose(\n `assembled full ws message of type ${serverMessage.type}`\n );\n }\n if (this.transitionChunkBuffer !== null) {\n this.transitionChunkBuffer = null;\n this.logger.log(\n `Received unexpected ${serverMessage.type} while buffering TransitionChunks`\n );\n }\n if (serverMessage.type === \"Transition\") {\n this.reportLargeTransition({\n messageLength,\n transition: serverMessage\n });\n }\n const response = this.onMessage(serverMessage);\n if (response.hasSyncedPastLastReconnect) {\n this.retries = 0;\n this.markConnectionStateDirty();\n }\n };\n ws.onclose = (event) => {\n this._logVerbose(\"begin ws.onclose\");\n this.transitionChunkBuffer = null;\n if (this.lastCloseReason === null) {\n this.lastCloseReason = event.reason || `closed with code ${event.code}`;\n }\n if (event.code !== CLOSE_NORMAL && event.code !== CLOSE_GOING_AWAY && // This commonly gets fired on mobile apps when the app is backgrounded\n event.code !== CLOSE_NO_STATUS && event.code !== CLOSE_NOT_FOUND) {\n let msg = `WebSocket closed with code ${event.code}`;\n if (event.reason) {\n msg += `: ${event.reason}`;\n }\n this.logger.log(msg);\n if (this.onServerDisconnectError && event.reason) {\n this.onServerDisconnectError(msg);\n }\n }\n const reason = classifyDisconnectError(event.reason);\n this.scheduleReconnect(reason);\n return;\n };\n }\n /**\n * @returns The state of the {@link Socket}.\n */\n socketState() {\n return this.socket.state;\n }\n /**\n * @param message - A ClientMessage to send.\n * @returns Whether the message (might have been) sent.\n */\n sendMessage(message) {\n const messageForLog = {\n type: message.type,\n ...message.type === \"Authenticate\" && message.tokenType === \"User\" ? {\n value: `...${message.value.slice(-7)}`\n } : {}\n };\n if (this.socket.state === \"ready\" && this.socket.paused === \"no\") {\n const encodedMessage = encodeClientMessage(message);\n const request = JSON.stringify(encodedMessage);\n let sent = false;\n try {\n this.socket.ws.send(request);\n sent = true;\n } catch (error) {\n this.logger.log(\n `Failed to send message on WebSocket, reconnecting: ${error}`\n );\n this.closeAndReconnect(\"FailedToSendMessage\");\n }\n this._logVerbose(\n `${sent ? \"sent\" : \"failed to send\"} message with type ${message.type}: ${JSON.stringify(\n messageForLog\n )}`\n );\n return true;\n }\n this._logVerbose(\n `message not sent (socket state: ${this.socket.state}, paused: ${\"paused\" in this.socket ? this.socket.paused : void 0}): ${JSON.stringify(\n messageForLog\n )}`\n );\n return false;\n }\n resetServerInactivityTimeout() {\n if (this.socket.state === \"terminated\") {\n return;\n }\n if (this.reconnectDueToServerInactivityTimeout !== null) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n this.reconnectDueToServerInactivityTimeout = null;\n }\n this.reconnectDueToServerInactivityTimeout = setTimeout(() => {\n this.closeAndReconnect(\"InactiveServer\");\n }, this.serverInactivityThreshold);\n }\n scheduleReconnect(reason) {\n if (this.scheduledReconnect) {\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n }\n this.socket = { state: \"disconnected\" };\n const backoff = this.nextBackoff(reason);\n this.markConnectionStateDirty();\n this.logger.log(`Attempting reconnect in ${Math.round(backoff)}ms`);\n const scheduledAt = monotonicMillis();\n const timeoutId = setTimeout(() => {\n if (this.scheduledReconnect?.timeout === timeoutId) {\n this.scheduledReconnect = null;\n this.connect();\n }\n }, backoff);\n this.scheduledReconnect = {\n timeout: timeoutId,\n scheduledAt,\n backoffMs: backoff\n };\n }\n /**\n * Close the WebSocket and schedule a reconnect.\n *\n * This should be used when we hit an error and would like to restart the session.\n */\n closeAndReconnect(closeReason) {\n this._logVerbose(`begin closeAndReconnect with reason ${closeReason}`);\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n return;\n case \"connecting\":\n case \"ready\": {\n this.lastCloseReason = closeReason;\n void this.close();\n this.scheduleReconnect(\"client\");\n return;\n }\n default: {\n this.socket;\n }\n }\n }\n /**\n * Close the WebSocket, being careful to clear the onclose handler to avoid re-entrant\n * calls. Use this instead of directly calling `ws.close()`\n *\n * It is the callers responsibility to update the state after this method is called so that the\n * closed socket is not accessible or used again after this method is called\n */\n close() {\n this.transitionChunkBuffer = null;\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n return Promise.resolve();\n case \"connecting\": {\n const ws = this.socket.ws;\n ws.onmessage = (_message) => {\n this._logVerbose(\"Ignoring message received after close\");\n };\n return new Promise((r) => {\n ws.onclose = () => {\n this._logVerbose(\"Closed after connecting\");\n r();\n };\n ws.onopen = () => {\n this._logVerbose(\"Opened after connecting\");\n ws.close();\n };\n });\n }\n case \"ready\": {\n this._logVerbose(\"ws.close called\");\n const ws = this.socket.ws;\n ws.onmessage = (_message) => {\n this._logVerbose(\"Ignoring message received after close\");\n };\n const result = new Promise((r) => {\n ws.onclose = () => {\n r();\n };\n });\n ws.close();\n return result;\n }\n default: {\n this.socket;\n return Promise.resolve();\n }\n }\n }\n /**\n * Close the WebSocket and do not reconnect.\n * @returns A Promise that resolves when the WebSocket `onClose` callback is called.\n */\n terminate() {\n if (this.reconnectDueToServerInactivityTimeout) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n }\n if (this.scheduledReconnect) {\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n }\n this.cleanupNetworkListener();\n switch (this.socket.state) {\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n case \"connecting\":\n case \"ready\": {\n const result = this.close();\n this.setSocketState({ state: \"terminated\" });\n return result;\n }\n default: {\n this.socket;\n throw new Error(\n `Invalid websocket state: ${this.socket.state}`\n );\n }\n }\n }\n stop() {\n switch (this.socket.state) {\n case \"terminated\":\n return Promise.resolve();\n case \"connecting\":\n case \"stopped\":\n case \"disconnected\":\n case \"ready\": {\n this.cleanupNetworkListener();\n const result = this.close();\n this.socket = { state: \"stopped\" };\n return result;\n }\n default: {\n this.socket;\n return Promise.resolve();\n }\n }\n }\n /**\n * Create a new WebSocket after a previous `stop()`, unless `terminate()` was\n * called before.\n */\n tryRestart() {\n switch (this.socket.state) {\n case \"stopped\":\n break;\n case \"terminated\":\n case \"connecting\":\n case \"ready\":\n case \"disconnected\":\n this.logger.logVerbose(\"Restart called without stopping first\");\n return;\n default: {\n this.socket;\n }\n }\n this.setupNetworkListener();\n this.connect();\n }\n pause() {\n switch (this.socket.state) {\n case \"disconnected\":\n case \"stopped\":\n case \"terminated\":\n return;\n case \"connecting\":\n case \"ready\": {\n this.socket = { ...this.socket, paused: \"yes\" };\n return;\n }\n default: {\n this.socket;\n return;\n }\n }\n }\n /**\n * Try to reconnect immediately, canceling any scheduled reconnect.\n * This is useful when detecting network recovery.\n * Only takes action if we're in disconnected state (waiting to reconnect).\n */\n tryReconnectImmediately() {\n this._logVerbose(\"tryReconnectImmediately called\");\n if (this.socket.state !== \"disconnected\") {\n this._logVerbose(\n `tryReconnectImmediately called but socket state is ${this.socket.state}, no action taken`\n );\n return;\n }\n let timeSavedMs = null;\n if (this.scheduledReconnect) {\n const elapsed = monotonicMillis() - this.scheduledReconnect.scheduledAt;\n timeSavedMs = Math.max(0, this.scheduledReconnect.backoffMs - elapsed);\n this._logVerbose(\n `would have waited ${Math.round(timeSavedMs)}ms more (backoff was ${Math.round(this.scheduledReconnect.backoffMs)}ms, elapsed ${Math.round(elapsed)}ms)`\n );\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n this._logVerbose(\"canceled scheduled reconnect\");\n }\n this.logger.log(\"Network recovery detected, reconnecting immediately\");\n this.pendingNetworkRecoveryInfo = timeSavedMs !== null ? { timeSavedMs } : null;\n this.connect();\n }\n /**\n * Resume the state machine if previously paused.\n */\n resume() {\n switch (this.socket.state) {\n case \"connecting\":\n this.socket = { ...this.socket, paused: \"no\" };\n return;\n case \"ready\":\n if (this.socket.paused === \"uninitialized\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this._hasEverConnected = true;\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n clientTs: monotonicMillis()\n });\n } else if (this.socket.paused === \"yes\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this.onResume();\n }\n return;\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n return;\n default: {\n this.socket;\n }\n }\n this.connect();\n }\n connectionState() {\n return {\n isConnected: this.socket.state === \"ready\",\n hasEverConnected: this._hasEverConnected,\n connectionCount: this.connectionCount,\n connectionRetries: this.retries\n };\n }\n _logVerbose(message) {\n this.logger.logVerbose(message);\n }\n nextBackoff(reason) {\n const initialBackoff = reason === \"client\" ? 100 : reason === \"Unknown\" ? this.defaultInitialBackoff : serverDisconnectErrors[reason].timeout;\n const baseBackoff = initialBackoff * Math.pow(2, this.retries);\n this.retries += 1;\n const actualBackoff = Math.min(baseBackoff, this.maxBackoff);\n const jitter = actualBackoff * (Math.random() - 0.5);\n return actualBackoff + jitter;\n }\n reportLargeTransition({\n transition,\n messageLength\n }) {\n if (transition.clientClockSkew === void 0 || transition.serverTs === void 0) {\n return;\n }\n const transitionTransitTime = monotonicMillis() - // client time now\n // clientClockSkew = (server time + upstream latency) - client time\n // clientClockSkew is \"how many milliseconds behind (slow) is the client clock\"\n // but the latency of the Connect message inflates this, making it appear further behind\n transition.clientClockSkew - transition.serverTs / 1e6;\n const prettyTransitionTime = `${Math.round(transitionTransitTime)}ms`;\n const prettyMessageMB = `${Math.round(messageLength / 1e4) / 100}MB`;\n const bytesPerSecond = messageLength / (transitionTransitTime / 1e3);\n const prettyBytesPerSecond = `${Math.round(bytesPerSecond / 1e4) / 100}MB per second`;\n this._logVerbose(\n `received ${prettyMessageMB} transition in ${prettyTransitionTime} at ${prettyBytesPerSecond}`\n );\n if (messageLength > 2e7) {\n this.logger.log(\n `received query results totaling more that 20MB (${prettyMessageMB}) which will take a long time to download on slower connections`\n );\n } else if (transitionTransitTime > 2e4) {\n this.logger.log(\n `received query results totaling ${prettyMessageMB} which took more than 20s to arrive (${prettyTransitionTime})`\n );\n }\n if (this.debug) {\n this.sendMessage({\n type: \"Event\",\n eventType: \"ClientReceivedTransition\",\n event: { transitionTransitTime, messageLength }\n });\n }\n }\n}\n//# sourceMappingURL=web_socket_manager.js.map\n","\"use strict\";\nexport function newSessionId() {\n return uuidv4();\n}\nfunction uuidv4() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0, v = c === \"x\" ? r : r & 3 | 8;\n return v.toString(16);\n });\n}\n//# sourceMappingURL=session.js.map\n","\"use strict\";\nexport class InvalidTokenError extends Error {\n}\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\nfunction b64DecodeUnicode(str) {\n return decodeURIComponent(\n atob(str).replace(/(.)/g, (_m, p) => {\n let code = p.charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = \"0\" + code;\n }\n return \"%\" + code;\n })\n );\n}\nfunction base64UrlDecode(str) {\n let output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw new Error(\"base64 string is not of the correct length\");\n }\n try {\n return b64DecodeUnicode(output);\n } catch {\n return atob(output);\n }\n}\nexport function jwtDecode(token, options) {\n if (typeof token !== \"string\") {\n throw new InvalidTokenError(\"Invalid token specified: must be a string\");\n }\n options || (options = {});\n const pos = options.header === true ? 0 : 1;\n const part = token.split(\".\")[pos];\n if (typeof part !== \"string\") {\n throw new InvalidTokenError(\n `Invalid token specified: missing part #${pos + 1}`\n );\n }\n let decoded;\n try {\n decoded = base64UrlDecode(part);\n } catch (e) {\n throw new InvalidTokenError(\n `Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`\n );\n }\n try {\n return JSON.parse(decoded);\n } catch (e) {\n throw new InvalidTokenError(\n `Invalid token specified: invalid json for part #${pos + 1} (${e.message})`\n );\n }\n}\n//# sourceMappingURL=index.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { jwtDecode } from \"../../vendor/jwt-decode/index.js\";\nconst MAXIMUM_REFRESH_DELAY = 20 * 24 * 60 * 60 * 1e3;\nconst MAX_TOKEN_CONFIRMATION_ATTEMPTS = 2;\nexport class AuthenticationManager {\n constructor(syncState, callbacks, config) {\n __publicField(this, \"authState\", { state: \"noAuth\" });\n // Used to detect races involving `setConfig` calls\n // while a token is being fetched.\n __publicField(this, \"configVersion\", 0);\n // Shared by the BaseClient so that the auth manager can easily inspect it\n __publicField(this, \"syncState\");\n // Passed down by BaseClient, sends a message to the server\n __publicField(this, \"authenticate\");\n __publicField(this, \"stopSocket\");\n __publicField(this, \"tryRestartSocket\");\n __publicField(this, \"pauseSocket\");\n __publicField(this, \"resumeSocket\");\n // Passed down by BaseClient, sends a message to the server\n __publicField(this, \"clearAuth\");\n __publicField(this, \"logger\");\n __publicField(this, \"refreshTokenLeewaySeconds\");\n // Number of times we have attempted to confirm the latest token. We retry up\n // to `MAX_TOKEN_CONFIRMATION_ATTEMPTS` times.\n __publicField(this, \"tokenConfirmationAttempts\", 0);\n this.syncState = syncState;\n this.authenticate = callbacks.authenticate;\n this.stopSocket = callbacks.stopSocket;\n this.tryRestartSocket = callbacks.tryRestartSocket;\n this.pauseSocket = callbacks.pauseSocket;\n this.resumeSocket = callbacks.resumeSocket;\n this.clearAuth = callbacks.clearAuth;\n this.logger = config.logger;\n this.refreshTokenLeewaySeconds = config.refreshTokenLeewaySeconds;\n }\n async setConfig(fetchToken, onChange) {\n this.resetAuthState();\n this._logVerbose(\"pausing WS for auth token fetch\");\n this.pauseSocket();\n const token = await this.fetchTokenAndGuardAgainstRace(fetchToken, {\n forceRefreshToken: false\n });\n if (token.isFromOutdatedConfig) {\n return;\n }\n if (token.value) {\n this.setAuthState({\n state: \"waitingForServerConfirmationOfCachedToken\",\n config: { fetchToken, onAuthChange: onChange },\n hasRetried: false\n });\n this.authenticate(token.value);\n } else {\n this.setAuthState({\n state: \"initialRefetch\",\n config: { fetchToken, onAuthChange: onChange }\n });\n await this.refetchToken();\n }\n this._logVerbose(\"resuming WS after auth token fetch\");\n this.resumeSocket();\n }\n onTransition(serverMessage) {\n if (!this.syncState.isCurrentOrNewerAuthVersion(\n serverMessage.endVersion.identity\n )) {\n return;\n }\n if (serverMessage.endVersion.identity <= serverMessage.startVersion.identity) {\n return;\n }\n this._logVerbose(\n `auth state is ${this.authState.state} when handling transition`\n );\n this.syncState.markAuthCompletion();\n if (this.authState.state === \"waitingForServerConfirmationOfCachedToken\") {\n this._logVerbose(\"server confirmed auth token is valid\");\n void this.refetchToken();\n this.authState.config.onAuthChange(true);\n return;\n }\n if (this.authState.state === \"waitingForServerConfirmationOfFreshToken\") {\n this._logVerbose(\"server confirmed new auth token is valid\");\n this.scheduleTokenRefetch(this.authState.token);\n this.tokenConfirmationAttempts = 0;\n if (!this.authState.hadAuth) {\n this.authState.config.onAuthChange(true);\n }\n }\n }\n onAuthError(serverMessage) {\n if (serverMessage.authUpdateAttempted === false && (this.authState.state === \"waitingForServerConfirmationOfFreshToken\" || this.authState.state === \"waitingForServerConfirmationOfCachedToken\")) {\n this._logVerbose(\"ignoring non-auth token expired error\");\n return;\n }\n const { baseVersion } = serverMessage;\n if (!this.syncState.isCurrentOrNewerAuthVersion(baseVersion + 1)) {\n this._logVerbose(\"ignoring auth error for previous auth attempt\");\n return;\n }\n void this.tryToReauthenticate(serverMessage);\n return;\n }\n // This is similar to `refetchToken` defined below, in fact we\n // don't represent them as different states, but it is different\n // in that we pause the WebSocket so that mutations\n // don't retry with bad auth.\n async tryToReauthenticate(serverMessage) {\n this._logVerbose(`attempting to reauthenticate: ${serverMessage.error}`);\n if (\n // No way to fetch another token, kaboom\n this.authState.state === \"noAuth\" || // We failed on a fresh token. After a small number of retries, we give up\n // and clear the auth state to avoid infinite retries.\n this.authState.state === \"waitingForServerConfirmationOfFreshToken\" && this.tokenConfirmationAttempts >= MAX_TOKEN_CONFIRMATION_ATTEMPTS\n ) {\n this.logger.error(\n `Failed to authenticate: \"${serverMessage.error}\", check your server auth config`\n );\n if (this.syncState.hasAuth()) {\n this.syncState.clearAuth();\n }\n if (this.authState.state !== \"noAuth\") {\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n return;\n }\n if (this.authState.state === \"waitingForServerConfirmationOfFreshToken\") {\n this.tokenConfirmationAttempts++;\n this._logVerbose(\n `retrying reauthentication, ${MAX_TOKEN_CONFIRMATION_ATTEMPTS - this.tokenConfirmationAttempts} attempts remaining`\n );\n }\n await this.stopSocket();\n const token = await this.fetchTokenAndGuardAgainstRace(\n this.authState.config.fetchToken,\n {\n forceRefreshToken: true\n }\n );\n if (token.isFromOutdatedConfig) {\n return;\n }\n if (token.value && this.syncState.isNewAuth(token.value)) {\n this.authenticate(token.value);\n this.setAuthState({\n state: \"waitingForServerConfirmationOfFreshToken\",\n config: this.authState.config,\n token: token.value,\n hadAuth: this.authState.state === \"notRefetching\" || this.authState.state === \"waitingForScheduledRefetch\"\n });\n } else {\n this._logVerbose(\"reauthentication failed, could not fetch a new token\");\n if (this.syncState.hasAuth()) {\n this.syncState.clearAuth();\n }\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n this.tryRestartSocket();\n }\n // Force refetch the token and schedule another refetch\n // before the token expires - an active client should never\n // need to reauthenticate.\n async refetchToken() {\n if (this.authState.state === \"noAuth\") {\n return;\n }\n this._logVerbose(\"refetching auth token\");\n const token = await this.fetchTokenAndGuardAgainstRace(\n this.authState.config.fetchToken,\n {\n forceRefreshToken: true\n }\n );\n if (token.isFromOutdatedConfig) {\n return;\n }\n if (token.value) {\n if (this.syncState.isNewAuth(token.value)) {\n this.setAuthState({\n state: \"waitingForServerConfirmationOfFreshToken\",\n hadAuth: this.syncState.hasAuth(),\n token: token.value,\n config: this.authState.config\n });\n this.authenticate(token.value);\n } else {\n this.setAuthState({\n state: \"notRefetching\",\n config: this.authState.config\n });\n }\n } else {\n this._logVerbose(\"refetching token failed\");\n if (this.syncState.hasAuth()) {\n this.clearAuth();\n }\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n this._logVerbose(\n \"restarting WS after auth token fetch (if currently stopped)\"\n );\n this.tryRestartSocket();\n }\n scheduleTokenRefetch(token) {\n if (this.authState.state === \"noAuth\") {\n return;\n }\n const decodedToken = this.decodeToken(token);\n if (!decodedToken) {\n this.logger.error(\n \"Auth token is not a valid JWT, cannot refetch the token\"\n );\n return;\n }\n const { iat, exp } = decodedToken;\n if (!iat || !exp) {\n this.logger.error(\n \"Auth token does not have required fields, cannot refetch the token\"\n );\n return;\n }\n const tokenValiditySeconds = exp - iat;\n if (tokenValiditySeconds <= 2) {\n this.logger.error(\n \"Auth token does not live long enough, cannot refetch the token\"\n );\n return;\n }\n let delay = Math.min(\n MAXIMUM_REFRESH_DELAY,\n (tokenValiditySeconds - this.refreshTokenLeewaySeconds) * 1e3\n );\n if (delay <= 0) {\n this.logger.warn(\n `Refetching auth token immediately, configured leeway ${this.refreshTokenLeewaySeconds}s is larger than the token's lifetime ${tokenValiditySeconds}s`\n );\n delay = 0;\n }\n const refetchTokenTimeoutId = setTimeout(() => {\n this._logVerbose(\"running scheduled token refetch\");\n void this.refetchToken();\n }, delay);\n this.setAuthState({\n state: \"waitingForScheduledRefetch\",\n refetchTokenTimeoutId,\n config: this.authState.config\n });\n this._logVerbose(\n `scheduled preemptive auth token refetching in ${delay}ms`\n );\n }\n // Protects against simultaneous calls to `setConfig`\n // while we're fetching a token\n async fetchTokenAndGuardAgainstRace(fetchToken, fetchArgs) {\n const originalConfigVersion = ++this.configVersion;\n this._logVerbose(\n `fetching token with config version ${originalConfigVersion}`\n );\n const token = await fetchToken(fetchArgs);\n if (this.configVersion !== originalConfigVersion) {\n this._logVerbose(\n `stale config version, expected ${originalConfigVersion}, got ${this.configVersion}`\n );\n return { isFromOutdatedConfig: true };\n }\n return { isFromOutdatedConfig: false, value: token };\n }\n stop() {\n this.resetAuthState();\n this.configVersion++;\n this._logVerbose(`config version bumped to ${this.configVersion}`);\n }\n setAndReportAuthFailed(onAuthChange) {\n onAuthChange(false);\n this.resetAuthState();\n }\n resetAuthState() {\n this.setAuthState({ state: \"noAuth\" });\n }\n setAuthState(newAuth) {\n const authStateForLog = newAuth.state === \"waitingForServerConfirmationOfFreshToken\" ? {\n hadAuth: newAuth.hadAuth,\n state: newAuth.state,\n token: `...${newAuth.token.slice(-7)}`\n } : { state: newAuth.state };\n this._logVerbose(\n `setting auth state to ${JSON.stringify(authStateForLog)}`\n );\n switch (newAuth.state) {\n case \"waitingForScheduledRefetch\":\n case \"notRefetching\":\n case \"noAuth\":\n this.tokenConfirmationAttempts = 0;\n break;\n case \"waitingForServerConfirmationOfFreshToken\":\n case \"waitingForServerConfirmationOfCachedToken\":\n case \"initialRefetch\":\n break;\n default: {\n newAuth;\n }\n }\n if (this.authState.state === \"waitingForScheduledRefetch\") {\n clearTimeout(this.authState.refetchTokenTimeoutId);\n }\n this.authState = newAuth;\n }\n decodeToken(token) {\n try {\n return jwtDecode(token);\n } catch (e) {\n this._logVerbose(\n `Error decoding token: ${e instanceof Error ? e.message : \"Unknown error\"}`\n );\n return null;\n }\n }\n _logVerbose(message) {\n this.logger.logVerbose(`${message} [v${this.configVersion}]`);\n }\n}\n//# sourceMappingURL=authentication_manager.js.map\n","\"use strict\";\nconst markNames = [\n \"convexClientConstructed\",\n \"convexWebSocketOpen\",\n \"convexFirstMessageReceived\"\n];\nexport function mark(name, sessionId) {\n const detail = { sessionId };\n if (typeof performance === \"undefined\" || !performance.mark) return;\n performance.mark(name, { detail });\n}\nfunction performanceMarkToJson(mark2) {\n let name = mark2.name.slice(\"convex\".length);\n name = name.charAt(0).toLowerCase() + name.slice(1);\n return {\n name,\n startTime: mark2.startTime\n };\n}\nexport function getMarksReport(sessionId) {\n if (typeof performance === \"undefined\" || !performance.getEntriesByName) {\n return [];\n }\n const allMarks = [];\n for (const name of markNames) {\n const marks = performance.getEntriesByName(name).filter((entry) => entry.entryType === \"mark\").filter((mark2) => mark2.detail.sessionId === sessionId);\n allMarks.push(...marks);\n }\n return allMarks.map(performanceMarkToJson);\n}\n//# sourceMappingURL=metrics.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { version } from \"../../index.js\";\nimport { convexToJson } from \"../../values/index.js\";\nimport {\n createHybridErrorStacktrace,\n forwardData,\n instantiateDefaultLogger,\n instantiateNoopLogger,\n logFatalError\n} from \"../logging.js\";\nimport { LocalSyncState } from \"./local_state.js\";\nimport { RequestManager } from \"./request_manager.js\";\nimport {\n OptimisticQueryResults\n} from \"./optimistic_updates_impl.js\";\nimport { RemoteQuerySet } from \"./remote_query_set.js\";\nimport { serializePathAndArgs } from \"./udf_path_utils.js\";\nimport { WebSocketManager } from \"./web_socket_manager.js\";\nimport { newSessionId } from \"./session.js\";\nimport {\n AuthenticationManager\n} from \"./authentication_manager.js\";\nimport { getMarksReport, mark } from \"./metrics.js\";\nimport { parseArgs, validateDeploymentUrl } from \"../../common/index.js\";\nimport { ConvexError } from \"../../values/errors.js\";\nimport { jwtDecode } from \"../../vendor/jwt-decode/index.js\";\nexport class BaseConvexClient {\n /**\n * @param address - The url of your Convex deployment, often provided\n * by an environment variable. E.g. `https://small-mouse-123.convex.cloud`.\n * @param onTransition - A callback receiving an array of query tokens\n * corresponding to query results that have changed -- additional handlers\n * can be added via `addOnTransitionHandler`.\n * @param options - See {@link BaseConvexClientOptions} for a full description.\n */\n constructor(address, onTransition, options) {\n __publicField(this, \"address\");\n __publicField(this, \"state\");\n __publicField(this, \"requestManager\");\n __publicField(this, \"webSocketManager\");\n __publicField(this, \"authenticationManager\");\n __publicField(this, \"remoteQuerySet\");\n __publicField(this, \"optimisticQueryResults\");\n __publicField(this, \"_transitionHandlerCounter\", 0);\n __publicField(this, \"_nextRequestId\");\n __publicField(this, \"_onTransitionFns\", /* @__PURE__ */ new Map());\n __publicField(this, \"_sessionId\");\n __publicField(this, \"firstMessageReceived\", false);\n __publicField(this, \"debug\");\n __publicField(this, \"logger\");\n __publicField(this, \"maxObservedTimestamp\");\n __publicField(this, \"connectionStateSubscribers\", /* @__PURE__ */ new Map());\n __publicField(this, \"nextConnectionStateSubscriberId\", 0);\n __publicField(this, \"_lastPublishedConnectionState\");\n /**\n * Call this whenever the connection state may have changed in a way that could\n * require publishing it. Schedules a possibly update.\n */\n __publicField(this, \"markConnectionStateDirty\", () => {\n void Promise.resolve().then(() => {\n const curConnectionState = this.connectionState();\n if (JSON.stringify(curConnectionState) !== JSON.stringify(this._lastPublishedConnectionState)) {\n this._lastPublishedConnectionState = curConnectionState;\n for (const cb of this.connectionStateSubscribers.values()) {\n cb(curConnectionState);\n }\n }\n });\n });\n // Instance property so that `mark()` doesn't need to be called as a method.\n __publicField(this, \"mark\", (name) => {\n if (this.debug) {\n mark(name, this.sessionId);\n }\n });\n if (typeof address === \"object\") {\n throw new Error(\n \"Passing a ClientConfig object is no longer supported. Pass the URL of the Convex deployment as a string directly.\"\n );\n }\n if (options?.skipConvexDeploymentUrlCheck !== true) {\n validateDeploymentUrl(address);\n }\n options = { ...options };\n const authRefreshTokenLeewaySeconds = options.authRefreshTokenLeewaySeconds ?? 10;\n let webSocketConstructor = options.webSocketConstructor;\n if (!webSocketConstructor && typeof WebSocket === \"undefined\") {\n throw new Error(\n \"No WebSocket global variable defined! To use Convex in an environment without WebSocket try the HTTP client: https://docs.convex.dev/api/classes/browser.ConvexHttpClient\"\n );\n }\n webSocketConstructor = webSocketConstructor || WebSocket;\n this.debug = options.reportDebugInfoToConvex ?? false;\n this.address = address;\n this.logger = options.logger === false ? instantiateNoopLogger({ verbose: options.verbose ?? false }) : options.logger !== true && options.logger ? options.logger : instantiateDefaultLogger({ verbose: options.verbose ?? false });\n const i = address.search(\"://\");\n if (i === -1) {\n throw new Error(\"Provided address was not an absolute URL.\");\n }\n const origin = address.substring(i + 3);\n const protocol = address.substring(0, i);\n let wsProtocol;\n if (protocol === \"http\") {\n wsProtocol = \"ws\";\n } else if (protocol === \"https\") {\n wsProtocol = \"wss\";\n } else {\n throw new Error(`Unknown parent protocol ${protocol}`);\n }\n const wsUri = `${wsProtocol}://${origin}/api/${version}/sync`;\n this.state = new LocalSyncState();\n this.remoteQuerySet = new RemoteQuerySet(\n (queryId) => this.state.queryPath(queryId),\n this.logger\n );\n this.requestManager = new RequestManager(\n this.logger,\n this.markConnectionStateDirty\n );\n const pauseSocket = () => {\n this.webSocketManager.pause();\n this.state.pause();\n };\n this.authenticationManager = new AuthenticationManager(\n this.state,\n {\n authenticate: (token) => {\n const message = this.state.setAuth(token);\n this.webSocketManager.sendMessage(message);\n return message.baseVersion;\n },\n stopSocket: () => this.webSocketManager.stop(),\n tryRestartSocket: () => this.webSocketManager.tryRestart(),\n pauseSocket,\n resumeSocket: () => this.webSocketManager.resume(),\n clearAuth: () => {\n this.clearAuth();\n }\n },\n {\n logger: this.logger,\n refreshTokenLeewaySeconds: authRefreshTokenLeewaySeconds\n }\n );\n this.optimisticQueryResults = new OptimisticQueryResults();\n this.addOnTransitionHandler((transition) => {\n onTransition(transition.queries.map((q) => q.token));\n });\n this._nextRequestId = 0;\n this._sessionId = newSessionId();\n const { unsavedChangesWarning } = options;\n if (typeof window === \"undefined\" || typeof window.addEventListener === \"undefined\") {\n if (unsavedChangesWarning === true) {\n throw new Error(\n \"unsavedChangesWarning requested, but window.addEventListener not found! Remove {unsavedChangesWarning: true} from Convex client options.\"\n );\n }\n } else if (unsavedChangesWarning !== false) {\n window.addEventListener(\"beforeunload\", (e) => {\n if (this.requestManager.hasIncompleteRequests()) {\n e.preventDefault();\n const confirmationMessage = \"Are you sure you want to leave? Your changes may not be saved.\";\n (e || window.event).returnValue = confirmationMessage;\n return confirmationMessage;\n }\n });\n }\n this.webSocketManager = new WebSocketManager(\n wsUri,\n {\n onOpen: (reconnectMetadata) => {\n this.mark(\"convexWebSocketOpen\");\n this.webSocketManager.sendMessage({\n ...reconnectMetadata,\n type: \"Connect\",\n sessionId: this._sessionId,\n maxObservedTimestamp: this.maxObservedTimestamp\n });\n this.remoteQuerySet = new RemoteQuerySet(\n (queryId) => this.state.queryPath(queryId),\n this.logger\n );\n const [querySetModification, authModification] = this.state.restart();\n if (authModification) {\n this.webSocketManager.sendMessage(authModification);\n }\n this.webSocketManager.sendMessage(querySetModification);\n for (const message of this.requestManager.restart()) {\n this.webSocketManager.sendMessage(message);\n }\n },\n onResume: () => {\n const [querySetModification, authModification] = this.state.resume();\n if (authModification) {\n this.webSocketManager.sendMessage(authModification);\n }\n if (querySetModification) {\n this.webSocketManager.sendMessage(querySetModification);\n }\n for (const message of this.requestManager.resume()) {\n this.webSocketManager.sendMessage(message);\n }\n },\n onMessage: (serverMessage) => {\n if (!this.firstMessageReceived) {\n this.firstMessageReceived = true;\n this.mark(\"convexFirstMessageReceived\");\n this.reportMarks();\n }\n switch (serverMessage.type) {\n case \"Transition\": {\n this.observedTimestamp(serverMessage.endVersion.ts);\n this.authenticationManager.onTransition(serverMessage);\n this.remoteQuerySet.transition(serverMessage);\n this.state.transition(serverMessage);\n const completedRequests = this.requestManager.removeCompleted(\n this.remoteQuerySet.timestamp()\n );\n this.notifyOnQueryResultChanges(completedRequests);\n break;\n }\n case \"MutationResponse\": {\n if (serverMessage.success) {\n this.observedTimestamp(serverMessage.ts);\n }\n const completedMutationInfo = this.requestManager.onResponse(serverMessage);\n if (completedMutationInfo !== null) {\n this.notifyOnQueryResultChanges(\n /* @__PURE__ */ new Map([\n [\n completedMutationInfo.requestId,\n completedMutationInfo.result\n ]\n ])\n );\n }\n break;\n }\n case \"ActionResponse\": {\n this.requestManager.onResponse(serverMessage);\n break;\n }\n case \"AuthError\": {\n this.authenticationManager.onAuthError(serverMessage);\n break;\n }\n case \"FatalError\": {\n const error = logFatalError(this.logger, serverMessage.error);\n void this.webSocketManager.terminate();\n throw error;\n }\n default: {\n serverMessage;\n }\n }\n return {\n hasSyncedPastLastReconnect: this.hasSyncedPastLastReconnect()\n };\n },\n onServerDisconnectError: options.onServerDisconnectError\n },\n webSocketConstructor,\n this.logger,\n this.markConnectionStateDirty,\n this.debug\n );\n this.mark(\"convexClientConstructed\");\n if (options.expectAuth) {\n pauseSocket();\n }\n }\n /**\n * Return true if there is outstanding work from prior to the time of the most recent restart.\n * This indicates that the client has not proven itself to have gotten past the issue that\n * potentially led to the restart. Use this to influence when to reset backoff after a failure.\n */\n hasSyncedPastLastReconnect() {\n const hasSyncedPastLastReconnect = this.requestManager.hasSyncedPastLastReconnect() && this.state.hasSyncedPastLastReconnect();\n return hasSyncedPastLastReconnect;\n }\n observedTimestamp(observedTs) {\n if (this.maxObservedTimestamp === void 0 || this.maxObservedTimestamp.lessThanOrEqual(observedTs)) {\n this.maxObservedTimestamp = observedTs;\n }\n }\n getMaxObservedTimestamp() {\n return this.maxObservedTimestamp;\n }\n /**\n * Compute the current query results based on the remoteQuerySet and the\n * current optimistic updates and call `onTransition` for all the changed\n * queries.\n *\n * @param completedMutations - A set of mutation IDs whose optimistic updates\n * are no longer needed.\n */\n notifyOnQueryResultChanges(completedRequests) {\n const remoteQueryResults = this.remoteQuerySet.remoteQueryResults();\n const queryTokenToValue = /* @__PURE__ */ new Map();\n for (const [queryId, result] of remoteQueryResults) {\n const queryToken = this.state.queryToken(queryId);\n if (queryToken !== null) {\n const query = {\n result,\n udfPath: this.state.queryPath(queryId),\n args: this.state.queryArgs(queryId)\n };\n queryTokenToValue.set(queryToken, query);\n }\n }\n const changedQueryTokens = this.optimisticQueryResults.ingestQueryResultsFromServer(\n queryTokenToValue,\n new Set(completedRequests.keys())\n );\n this.handleTransition({\n queries: changedQueryTokens.map((token) => {\n const optimisticResult = this.optimisticQueryResults.rawQueryResult(token);\n return {\n token,\n modification: {\n kind: \"Updated\",\n result: optimisticResult\n }\n };\n }),\n reflectedMutations: Array.from(completedRequests).map(\n ([requestId, result]) => ({\n requestId,\n result\n })\n ),\n timestamp: this.remoteQuerySet.timestamp()\n });\n }\n handleTransition(transition) {\n for (const fn of this._onTransitionFns.values()) {\n fn(transition);\n }\n }\n /**\n * Add a handler that will be called on a transition.\n *\n * Any external side effects (e.g. setting React state) should be handled here.\n *\n * @param fn\n *\n * @returns\n */\n addOnTransitionHandler(fn) {\n const id = this._transitionHandlerCounter++;\n this._onTransitionFns.set(id, fn);\n return () => this._onTransitionFns.delete(id);\n }\n /**\n * Get the current JWT auth token and decoded claims.\n */\n getCurrentAuthClaims() {\n const authToken = this.state.getAuth();\n let decoded = {};\n if (authToken && authToken.tokenType === \"User\") {\n try {\n decoded = authToken ? jwtDecode(authToken.value) : {};\n } catch {\n decoded = {};\n }\n } else {\n return void 0;\n }\n return { token: authToken.value, decoded };\n }\n /**\n * Set the authentication token to be used for subsequent queries and mutations.\n * `fetchToken` will be called automatically again if a token expires.\n * `fetchToken` should return `null` if the token cannot be retrieved, for example\n * when the user's rights were permanently revoked.\n * @param fetchToken - an async function returning the JWT-encoded OpenID Connect Identity Token\n * @param onChange - a callback that will be called when the authentication status changes\n */\n setAuth(fetchToken, onChange) {\n void this.authenticationManager.setConfig(fetchToken, onChange);\n }\n hasAuth() {\n return this.state.hasAuth();\n }\n /** @internal */\n setAdminAuth(value, fakeUserIdentity) {\n const message = this.state.setAdminAuth(value, fakeUserIdentity);\n this.webSocketManager.sendMessage(message);\n }\n clearAuth() {\n const message = this.state.clearAuth();\n this.webSocketManager.sendMessage(message);\n }\n /**\n * Subscribe to a query function.\n *\n * Whenever this query's result changes, the `onTransition` callback\n * passed into the constructor will be called.\n *\n * @param name - The name of the query.\n * @param args - An arguments object for the query. If this is omitted, the\n * arguments will be `{}`.\n * @param options - A {@link SubscribeOptions} options object for this query.\n \n * @returns An object containing a {@link QueryToken} corresponding to this\n * query and an `unsubscribe` callback.\n */\n subscribe(name, args, options) {\n const argsObject = parseArgs(args);\n const { modification, queryToken, unsubscribe } = this.state.subscribe(\n name,\n argsObject,\n options?.journal,\n options?.componentPath\n );\n if (modification !== null) {\n this.webSocketManager.sendMessage(modification);\n }\n return {\n queryToken,\n unsubscribe: () => {\n const modification2 = unsubscribe();\n if (modification2) {\n this.webSocketManager.sendMessage(modification2);\n }\n }\n };\n }\n /**\n * A query result based only on the current, local state.\n *\n * The only way this will return a value is if we're already subscribed to the\n * query or its value has been set optimistically.\n */\n localQueryResult(udfPath, args) {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(udfPath, argsObject);\n return this.optimisticQueryResults.queryResult(queryToken);\n }\n /**\n * Get query result by query token based on current, local state\n *\n * The only way this will return a value is if we're already subscribed to the\n * query or its value has been set optimistically.\n *\n * @internal\n */\n localQueryResultByToken(queryToken) {\n return this.optimisticQueryResults.queryResult(queryToken);\n }\n /**\n * Whether local query result is available for a token.\n *\n * This method does not throw if the result is an error.\n *\n * @internal\n */\n hasLocalQueryResultByToken(queryToken) {\n return this.optimisticQueryResults.hasQueryResult(queryToken);\n }\n /**\n * @internal\n */\n localQueryLogs(udfPath, args) {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(udfPath, argsObject);\n return this.optimisticQueryResults.queryLogs(queryToken);\n }\n /**\n * Retrieve the current {@link QueryJournal} for this query function.\n *\n * If we have not yet received a result for this query, this will be `undefined`.\n *\n * @param name - The name of the query.\n * @param args - The arguments object for this query.\n * @returns The query's {@link QueryJournal} or `undefined`.\n */\n queryJournal(name, args) {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(name, argsObject);\n return this.state.queryJournal(queryToken);\n }\n /**\n * Get the current {@link ConnectionState} between the client and the Convex\n * backend.\n *\n * @returns The {@link ConnectionState} with the Convex backend.\n */\n connectionState() {\n const wsConnectionState = this.webSocketManager.connectionState();\n return {\n hasInflightRequests: this.requestManager.hasInflightRequests(),\n isWebSocketConnected: wsConnectionState.isConnected,\n hasEverConnected: wsConnectionState.hasEverConnected,\n connectionCount: wsConnectionState.connectionCount,\n connectionRetries: wsConnectionState.connectionRetries,\n timeOfOldestInflightRequest: this.requestManager.timeOfOldestInflightRequest(),\n inflightMutations: this.requestManager.inflightMutations(),\n inflightActions: this.requestManager.inflightActions()\n };\n }\n /**\n * Subscribe to the {@link ConnectionState} between the client and the Convex\n * backend, calling a callback each time it changes.\n *\n * Subscribed callbacks will be called when any part of ConnectionState changes.\n * ConnectionState may grow in future versions (e.g. to provide a array of\n * inflight requests) in which case callbacks would be called more frequently.\n *\n * @returns An unsubscribe function to stop listening.\n */\n subscribeToConnectionState(cb) {\n const id = this.nextConnectionStateSubscriberId++;\n this.connectionStateSubscribers.set(id, cb);\n return () => {\n this.connectionStateSubscribers.delete(id);\n };\n }\n /**\n * Execute a mutation function.\n *\n * @param name - The name of the mutation.\n * @param args - An arguments object for the mutation. If this is omitted,\n * the arguments will be `{}`.\n * @param options - A {@link MutationOptions} options object for this mutation.\n \n * @returns - A promise of the mutation's result.\n */\n async mutation(name, args, options) {\n const result = await this.mutationInternal(name, args, options);\n if (!result.success) {\n if (result.errorData !== void 0) {\n throw forwardData(\n result,\n new ConvexError(\n createHybridErrorStacktrace(\"mutation\", name, result)\n )\n );\n }\n throw new Error(createHybridErrorStacktrace(\"mutation\", name, result));\n }\n return result.value;\n }\n /**\n * @internal\n */\n async mutationInternal(udfPath, args, options, componentPath) {\n const { mutationPromise } = this.enqueueMutation(\n udfPath,\n args,\n options,\n componentPath\n );\n return mutationPromise;\n }\n /**\n * @internal\n */\n enqueueMutation(udfPath, args, options, componentPath) {\n const mutationArgs = parseArgs(args);\n this.tryReportLongDisconnect();\n const requestId = this.nextRequestId;\n this._nextRequestId++;\n if (options !== void 0) {\n const optimisticUpdate = options.optimisticUpdate;\n if (optimisticUpdate !== void 0) {\n const wrappedUpdate = (localQueryStore) => {\n const result = optimisticUpdate(\n localQueryStore,\n mutationArgs\n );\n if (result instanceof Promise) {\n this.logger.warn(\n \"Optimistic update handler returned a Promise. Optimistic updates should be synchronous.\"\n );\n }\n };\n const changedQueryTokens = this.optimisticQueryResults.applyOptimisticUpdate(\n wrappedUpdate,\n requestId\n );\n const changedQueries = changedQueryTokens.map((token) => {\n const localResult = this.localQueryResultByToken(token);\n return {\n token,\n modification: {\n kind: \"Updated\",\n result: localResult === void 0 ? void 0 : {\n success: true,\n value: localResult,\n logLines: []\n }\n }\n };\n });\n this.handleTransition({\n queries: changedQueries,\n reflectedMutations: [],\n timestamp: this.remoteQuerySet.timestamp()\n });\n }\n }\n const message = {\n type: \"Mutation\",\n requestId,\n udfPath,\n componentPath,\n args: [convexToJson(mutationArgs)]\n };\n const mightBeSent = this.webSocketManager.sendMessage(message);\n const mutationPromise = this.requestManager.request(message, mightBeSent);\n return {\n requestId,\n mutationPromise\n };\n }\n /**\n * Execute an action function.\n *\n * @param name - The name of the action.\n * @param args - An arguments object for the action. If this is omitted,\n * the arguments will be `{}`.\n * @returns A promise of the action's result.\n */\n async action(name, args) {\n const result = await this.actionInternal(name, args);\n if (!result.success) {\n if (result.errorData !== void 0) {\n throw forwardData(\n result,\n new ConvexError(createHybridErrorStacktrace(\"action\", name, result))\n );\n }\n throw new Error(createHybridErrorStacktrace(\"action\", name, result));\n }\n return result.value;\n }\n /**\n * @internal\n */\n async actionInternal(udfPath, args, componentPath) {\n const actionArgs = parseArgs(args);\n const requestId = this.nextRequestId;\n this._nextRequestId++;\n this.tryReportLongDisconnect();\n const message = {\n type: \"Action\",\n requestId,\n udfPath,\n componentPath,\n args: [convexToJson(actionArgs)]\n };\n const mightBeSent = this.webSocketManager.sendMessage(message);\n return this.requestManager.request(message, mightBeSent);\n }\n /**\n * Close any network handles associated with this client and stop all subscriptions.\n *\n * Call this method when you're done with an {@link BaseConvexClient} to\n * dispose of its sockets and resources.\n *\n * @returns A `Promise` fulfilled when the connection has been completely closed.\n */\n async close() {\n this.authenticationManager.stop();\n return this.webSocketManager.terminate();\n }\n /**\n * Return the address for this client, useful for creating a new client.\n *\n * Not guaranteed to match the address with which this client was constructed:\n * it may be canonicalized.\n */\n get url() {\n return this.address;\n }\n /**\n * @internal\n */\n get nextRequestId() {\n return this._nextRequestId;\n }\n /**\n * @internal\n */\n get sessionId() {\n return this._sessionId;\n }\n /**\n * Reports performance marks to the server. This should only be called when\n * we have a functional websocket.\n */\n reportMarks() {\n if (this.debug) {\n const report = getMarksReport(this.sessionId);\n this.webSocketManager.sendMessage({\n type: \"Event\",\n eventType: \"ClientConnect\",\n event: report\n });\n }\n }\n tryReportLongDisconnect() {\n if (!this.debug) {\n return;\n }\n const timeOfOldestRequest = this.connectionState().timeOfOldestInflightRequest;\n if (timeOfOldestRequest === null || Date.now() - timeOfOldestRequest.getTime() <= 60 * 1e3) {\n return;\n }\n const endpoint = `${this.address}/api/debug_event`;\n fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`\n },\n body: JSON.stringify({ event: \"LongWebsocketDisconnect\" })\n }).then((response) => {\n if (!response.ok) {\n this.logger.warn(\n \"Analytics request failed with response:\",\n response.body\n );\n }\n }).catch((error) => {\n this.logger.warn(\"Analytics response failed with error:\", error);\n });\n }\n}\n//# sourceMappingURL=client.js.map\n","\"use strict\";\nexport function asPaginationArgs(value) {\n if (typeof value.paginationOpts.numItems !== \"number\") {\n throw new Error(`Not valid paginated query args: ${JSON.stringify(value)}`);\n }\n return value;\n}\nexport function asPaginationResult(value) {\n if (typeof value !== \"object\" || value === null || !Array.isArray(value.page) || typeof value.isDone !== \"boolean\" || typeof value.continueCursor !== \"string\") {\n throw new Error(`Not a valid paginated query result: ${value?.toString()}`);\n }\n return value;\n}\n//# sourceMappingURL=pagination.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport {\n serializePaginatedPathAndArgs,\n canonicalizeUdfPath\n} from \"./udf_path_utils.js\";\nimport {\n asPaginationResult\n} from \"./pagination.js\";\nimport { Long } from \"../../vendor/long.js\";\nexport class PaginatedQueryClient {\n constructor(client, onTransition) {\n this.client = client;\n this.onTransition = onTransition;\n __publicField(this, \"paginatedQuerySet\", /* @__PURE__ */ new Map());\n // hold onto a real Transition so we can construct synthetic ones with that timestamp\n __publicField(this, \"lastTransitionTs\");\n this.lastTransitionTs = Long.fromNumber(0);\n this.client.addOnTransitionHandler(\n (transition) => this.onBaseTransition(transition)\n );\n }\n /**\n * Subscribe to a paginated query.\n *\n * @param name - The name of the paginated query function\n * @param args - Arguments for the query (excluding paginationOpts)\n * @param options - Pagination options including initialNumItems\n * @returns Object with paginatedQueryToken and unsubscribe function\n */\n subscribe(name, args, options) {\n const canonicalizedUdfPath = canonicalizeUdfPath(name);\n const token = serializePaginatedPathAndArgs(\n canonicalizedUdfPath,\n args,\n options\n );\n const unsubscribe = () => this.removePaginatedQuerySubscriber(token);\n const existingEntry = this.paginatedQuerySet.get(token);\n if (existingEntry) {\n existingEntry.numSubscribers += 1;\n return {\n paginatedQueryToken: token,\n unsubscribe\n };\n }\n this.paginatedQuerySet.set(token, {\n token,\n canonicalizedUdfPath,\n args,\n numSubscribers: 1,\n options: { initialNumItems: options.initialNumItems },\n nextPageKey: 0,\n pageKeys: [],\n pageKeyToQuery: /* @__PURE__ */ new Map(),\n ongoingSplits: /* @__PURE__ */ new Map(),\n skip: false,\n id: options.id\n });\n this.addPageToPaginatedQuery(token, null, options.initialNumItems);\n return {\n paginatedQueryToken: token,\n unsubscribe\n };\n }\n /**\n * Get current results for a paginated query based on local state.\n *\n * Throws an error when one of the pages has errored.\n */\n localQueryResult(name, args, options) {\n const canonicalizedUdfPath = canonicalizeUdfPath(name);\n const token = serializePaginatedPathAndArgs(\n canonicalizedUdfPath,\n args,\n options\n );\n return this.localQueryResultByToken(token);\n }\n /**\n * @internal\n */\n localQueryResultByToken(token) {\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n return void 0;\n }\n const activePages = this.activePageQueryTokens(paginatedQuery);\n if (activePages.length === 0) {\n return {\n results: [],\n status: \"LoadingFirstPage\",\n loadMore: (numItems) => {\n return this.loadMoreOfPaginatedQuery(token, numItems);\n }\n };\n }\n let allResults = [];\n let hasUndefined = false;\n let isDone = false;\n for (const pageToken of activePages) {\n const result = this.client.localQueryResultByToken(pageToken);\n if (result === void 0) {\n hasUndefined = true;\n isDone = false;\n continue;\n }\n const paginationResult = asPaginationResult(result);\n allResults = allResults.concat(paginationResult.page);\n isDone = !!paginationResult.isDone;\n }\n let status;\n if (hasUndefined) {\n status = allResults.length === 0 ? \"LoadingFirstPage\" : \"LoadingMore\";\n } else if (isDone) {\n status = \"Exhausted\";\n } else {\n status = \"CanLoadMore\";\n }\n return {\n results: allResults,\n status,\n loadMore: (numItems) => {\n return this.loadMoreOfPaginatedQuery(token, numItems);\n }\n };\n }\n onBaseTransition(transition) {\n const changedBaseTokens = transition.queries.map((q) => q.token);\n const changed = this.queriesContainingTokens(changedBaseTokens);\n let paginatedQueries = [];\n if (changed.length > 0) {\n this.processPaginatedQuerySplits(\n changed,\n (token) => this.client.localQueryResultByToken(token)\n );\n paginatedQueries = changed.map((token) => ({\n token,\n modification: {\n kind: \"Updated\",\n result: this.localQueryResultByToken(token)\n }\n }));\n }\n const extendedTransition = {\n ...transition,\n paginatedQueries\n };\n this.onTransition(extendedTransition);\n }\n /**\n * Load more items for a paginated query.\n *\n * This *always* causes a transition, the status of the query\n * has probably changed from \"CanLoadMore\" to \"LoadingMore\".\n * Data might have changed too: maybe a subscription to this page\n * query already exists (unlikely but possible) or this page query\n * has an optimistic update providing some initial data.\n *\n * @internal\n */\n loadMoreOfPaginatedQuery(token, numItems) {\n this.mustGetPaginatedQuery(token);\n const lastPageToken = this.queryTokenForLastPageOfPaginatedQuery(token);\n const lastPageResult = this.client.localQueryResultByToken(lastPageToken);\n if (!lastPageResult) {\n return false;\n }\n const paginationResult = asPaginationResult(lastPageResult);\n if (paginationResult.isDone) {\n return false;\n }\n this.addPageToPaginatedQuery(\n token,\n paginationResult.continueCursor,\n numItems\n );\n const loadMoreTransition = {\n timestamp: this.lastTransitionTs,\n reflectedMutations: [],\n queries: [],\n paginatedQueries: [\n {\n token,\n modification: {\n kind: \"Updated\",\n result: this.localQueryResultByToken(token)\n }\n }\n ]\n };\n this.onTransition(loadMoreTransition);\n return true;\n }\n /**\n * @internal\n */\n queriesContainingTokens(queryTokens) {\n if (queryTokens.length === 0) {\n return [];\n }\n const changed = [];\n const queryTokenSet = new Set(queryTokens);\n for (const [paginatedToken, paginatedQuery] of this.paginatedQuerySet) {\n for (const pageToken of this.allQueryTokens(paginatedQuery)) {\n if (queryTokenSet.has(pageToken)) {\n changed.push(paginatedToken);\n break;\n }\n }\n }\n return changed;\n }\n /**\n * @internal\n */\n processPaginatedQuerySplits(changed, getResult) {\n for (const paginatedQueryToken of changed) {\n const paginatedQuery = this.mustGetPaginatedQuery(paginatedQueryToken);\n const { ongoingSplits, pageKeyToQuery, pageKeys } = paginatedQuery;\n for (const [pageKey, [splitKey1, splitKey2]] of ongoingSplits) {\n const bothNewPagesLoaded = getResult(pageKeyToQuery.get(splitKey1).queryToken) !== void 0 && getResult(pageKeyToQuery.get(splitKey2).queryToken) !== void 0;\n if (bothNewPagesLoaded) {\n this.completePaginatedQuerySplit(\n paginatedQuery,\n pageKey,\n splitKey1,\n splitKey2\n );\n }\n }\n for (const pageKey of pageKeys) {\n if (ongoingSplits.has(pageKey)) {\n continue;\n }\n const pageToken = pageKeyToQuery.get(pageKey).queryToken;\n const pageResult = getResult(pageToken);\n if (!pageResult) {\n continue;\n }\n const result = asPaginationResult(pageResult);\n const shouldSplit = result.splitCursor && (result.pageStatus === \"SplitRecommended\" || result.pageStatus === \"SplitRequired\" || // This client-driven page splitting condition will change in the future.\n result.page.length > paginatedQuery.options.initialNumItems * 2);\n if (shouldSplit) {\n this.splitPaginatedQueryPage(\n paginatedQuery,\n pageKey,\n result.splitCursor,\n // we just checked\n result.continueCursor\n );\n }\n }\n }\n }\n splitPaginatedQueryPage(paginatedQuery, pageKey, splitCursor, continueCursor) {\n const splitKey1 = paginatedQuery.nextPageKey++;\n const splitKey2 = paginatedQuery.nextPageKey++;\n const paginationOpts = {\n cursor: continueCursor,\n numItems: paginatedQuery.options.initialNumItems,\n id: paginatedQuery.id\n };\n const firstSubscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n {\n ...paginatedQuery.args,\n paginationOpts: {\n ...paginationOpts,\n cursor: null,\n // Start from beginning for first split\n endCursor: splitCursor\n }\n }\n );\n paginatedQuery.pageKeyToQuery.set(splitKey1, firstSubscription);\n const secondSubscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n {\n ...paginatedQuery.args,\n paginationOpts: {\n ...paginationOpts,\n cursor: splitCursor,\n endCursor: continueCursor\n }\n }\n );\n paginatedQuery.pageKeyToQuery.set(splitKey2, secondSubscription);\n paginatedQuery.ongoingSplits.set(pageKey, [splitKey1, splitKey2]);\n }\n /**\n * @internal\n */\n addPageToPaginatedQuery(token, continueCursor, numItems) {\n const paginatedQuery = this.mustGetPaginatedQuery(token);\n const pageKey = paginatedQuery.nextPageKey++;\n const paginationOpts = {\n cursor: continueCursor,\n numItems,\n id: paginatedQuery.id\n };\n const pageArgs = {\n ...paginatedQuery.args,\n paginationOpts\n };\n const subscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n pageArgs\n );\n paginatedQuery.pageKeys.push(pageKey);\n paginatedQuery.pageKeyToQuery.set(pageKey, subscription);\n return subscription;\n }\n removePaginatedQuerySubscriber(token) {\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n return;\n }\n paginatedQuery.numSubscribers -= 1;\n if (paginatedQuery.numSubscribers > 0) {\n return;\n }\n for (const subscription of paginatedQuery.pageKeyToQuery.values()) {\n subscription.unsubscribe();\n }\n this.paginatedQuerySet.delete(token);\n }\n completePaginatedQuerySplit(paginatedQuery, pageKey, splitKey1, splitKey2) {\n const originalQuery = paginatedQuery.pageKeyToQuery.get(pageKey);\n paginatedQuery.pageKeyToQuery.delete(pageKey);\n const pageIndex = paginatedQuery.pageKeys.indexOf(pageKey);\n paginatedQuery.pageKeys.splice(pageIndex, 1, splitKey1, splitKey2);\n paginatedQuery.ongoingSplits.delete(pageKey);\n originalQuery.unsubscribe();\n }\n /** The query tokens for all active pages, in result order */\n activePageQueryTokens(paginatedQuery) {\n return paginatedQuery.pageKeys.map(\n (pageKey) => paginatedQuery.pageKeyToQuery.get(pageKey).queryToken\n );\n }\n allQueryTokens(paginatedQuery) {\n return Array.from(paginatedQuery.pageKeyToQuery.values()).map(\n (sub) => sub.queryToken\n );\n }\n queryTokenForLastPageOfPaginatedQuery(token) {\n const paginatedQuery = this.mustGetPaginatedQuery(token);\n const lastPageKey = paginatedQuery.pageKeys[paginatedQuery.pageKeys.length - 1];\n if (lastPageKey === void 0) {\n throw new Error(`No pages for paginated query ${token}`);\n }\n return paginatedQuery.pageKeyToQuery.get(lastPageKey).queryToken;\n }\n mustGetPaginatedQuery(token) {\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n throw new Error(\"paginated query no longer exists for token \" + token);\n }\n return paginatedQuery;\n }\n}\n//# sourceMappingURL=paginated_query_client.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { validateDeploymentUrl } from \"../common/index.js\";\nimport {\n BaseConvexClient\n} from \"./index.js\";\nimport { getFunctionName } from \"../server/api.js\";\nimport {\n PaginatedQueryClient\n} from \"./sync/paginated_query_client.js\";\nimport { serializedQueryTokenIsPaginated } from \"./sync/udf_path_utils.js\";\nlet defaultWebSocketConstructor;\nexport function setDefaultWebSocketConstructor(ws) {\n defaultWebSocketConstructor = ws;\n}\nexport class ConvexClient {\n /**\n * Construct a client and immediately initiate a WebSocket connection to the passed address.\n *\n * @public\n */\n constructor(address, options = {}) {\n __publicField(this, \"listeners\");\n __publicField(this, \"_client\");\n __publicField(this, \"_paginatedClient\");\n // A synthetic server event to run callbacks the first time\n __publicField(this, \"callNewListenersWithCurrentValuesTimer\");\n __publicField(this, \"_closed\");\n __publicField(this, \"_disabled\");\n if (options.skipConvexDeploymentUrlCheck !== true) {\n validateDeploymentUrl(address);\n }\n const { disabled, ...baseOptions } = options;\n this._closed = false;\n this._disabled = !!disabled;\n if (defaultWebSocketConstructor && !(\"webSocketConstructor\" in baseOptions) && typeof WebSocket === \"undefined\") {\n baseOptions.webSocketConstructor = defaultWebSocketConstructor;\n }\n if (typeof window === \"undefined\" && !(\"unsavedChangesWarning\" in baseOptions)) {\n baseOptions.unsavedChangesWarning = false;\n }\n if (!this.disabled) {\n this._client = new BaseConvexClient(\n address,\n () => {\n },\n // NOP, let the paginated query client do it all\n baseOptions\n );\n this._paginatedClient = new PaginatedQueryClient(\n this._client,\n (transition) => this._transition(transition)\n );\n }\n this.listeners = /* @__PURE__ */ new Set();\n }\n /**\n * Once closed no registered callbacks will fire again.\n */\n get closed() {\n return this._closed;\n }\n get client() {\n if (this._client) return this._client;\n throw new Error(\"ConvexClient is disabled\");\n }\n /**\n * @internal\n */\n get paginatedClient() {\n if (this._paginatedClient) return this._paginatedClient;\n throw new Error(\"ConvexClient is disabled\");\n }\n get disabled() {\n return this._disabled;\n }\n /**\n * Call a callback whenever a new result for a query is received. The callback\n * will run soon after being registered if a result for the query is already\n * in memory.\n *\n * The return value is an {@link Unsubscribe} object which is both a function\n * an an object with properties. Both of the patterns below work with this object:\n *\n *```ts\n * // call the return value as a function\n * const unsubscribe = client.onUpdate(api.messages.list, {}, (messages) => {\n * console.log(messages);\n * });\n * unsubscribe();\n *\n * // unpack the return value into its properties\n * const {\n * getCurrentValue,\n * unsubscribe,\n * } = client.onUpdate(api.messages.list, {}, (messages) => {\n * console.log(messages);\n * });\n *```\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - The arguments to run the query with.\n * @param callback - Function to call when the query result updates.\n * @param onError - Function to call when the query result updates with an error.\n * If not provided, errors will be thrown instead of calling the callback.\n *\n * @return an {@link Unsubscribe} function to stop calling the onUpdate function.\n */\n onUpdate(query, args, callback, onError) {\n if (this.disabled) {\n return this.createDisabledUnsubscribe();\n }\n const { queryToken, unsubscribe } = this.client.subscribe(\n getFunctionName(query),\n args\n );\n const queryInfo = {\n queryToken,\n callback,\n onError,\n unsubscribe,\n hasEverRun: false,\n query,\n args,\n paginationOptions: void 0\n };\n this.listeners.add(queryInfo);\n if (this.queryResultReady(queryToken) && this.callNewListenersWithCurrentValuesTimer === void 0) {\n this.callNewListenersWithCurrentValuesTimer = setTimeout(\n () => this.callNewListenersWithCurrentValues(),\n 0\n );\n }\n const unsubscribeProps = {\n unsubscribe: () => {\n if (this.closed) {\n return;\n }\n this.listeners.delete(queryInfo);\n unsubscribe();\n },\n getCurrentValue: () => this.client.localQueryResultByToken(queryToken),\n getQueryLogs: () => this.client.localQueryLogs(queryToken)\n };\n const ret = unsubscribeProps.unsubscribe;\n Object.assign(ret, unsubscribeProps);\n return ret;\n }\n /**\n * Call a callback whenever a new result for a paginated query is received.\n *\n * This is an experimental preview: the final API may change.\n * In particular, caching behavior, page splitting, and required paginated query options\n * may change.\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - The arguments to run the query with.\n * @param options - Options for the paginated query including initialNumItems and id.\n * @param callback - Function to call when the query result updates.\n * @param onError - Function to call when the query result updates with an error.\n *\n * @return an {@link Unsubscribe} function to stop calling the callback.\n */\n onPaginatedUpdate_experimental(query, args, options, callback, onError) {\n if (this.disabled) {\n return this.createDisabledUnsubscribe();\n }\n const paginationOptions = {\n initialNumItems: options.initialNumItems,\n id: -1\n };\n const { paginatedQueryToken, unsubscribe } = this.paginatedClient.subscribe(\n getFunctionName(query),\n args,\n // Simple client doesn't use IDs, there's no expectation that these queries remain separate.\n paginationOptions\n );\n const queryInfo = {\n queryToken: paginatedQueryToken,\n callback,\n onError,\n unsubscribe,\n hasEverRun: false,\n query,\n args,\n paginationOptions\n };\n this.listeners.add(queryInfo);\n if (!!this.paginatedClient.localQueryResultByToken(paginatedQueryToken) && this.callNewListenersWithCurrentValuesTimer === void 0) {\n this.callNewListenersWithCurrentValuesTimer = setTimeout(\n () => this.callNewListenersWithCurrentValues(),\n 0\n );\n }\n const unsubscribeProps = {\n unsubscribe: () => {\n if (this.closed) {\n return;\n }\n this.listeners.delete(queryInfo);\n unsubscribe();\n },\n getCurrentValue: () => {\n const result = this.paginatedClient.localQueryResult(\n getFunctionName(query),\n args,\n paginationOptions\n );\n return result;\n },\n getQueryLogs: () => []\n // Paginated queries don't aggregate their logs\n };\n const ret = unsubscribeProps.unsubscribe;\n Object.assign(ret, unsubscribeProps);\n return ret;\n }\n // Run all callbacks that have never been run before if they have a query\n // result available now.\n callNewListenersWithCurrentValues() {\n this.callNewListenersWithCurrentValuesTimer = void 0;\n this._transition({ queries: [], paginatedQueries: [] }, true);\n }\n queryResultReady(queryToken) {\n return this.client.hasLocalQueryResultByToken(queryToken);\n }\n createDisabledUnsubscribe() {\n const disabledUnsubscribe = (() => {\n });\n const unsubscribeProps = {\n unsubscribe: disabledUnsubscribe,\n getCurrentValue: () => void 0,\n getQueryLogs: () => void 0\n };\n Object.assign(disabledUnsubscribe, unsubscribeProps);\n return disabledUnsubscribe;\n }\n async close() {\n if (this.disabled) return;\n this.listeners.clear();\n this._closed = true;\n if (this._paginatedClient) {\n this._paginatedClient = void 0;\n }\n return this.client.close();\n }\n /**\n * Get the current JWT auth token and decoded claims.\n */\n getAuth() {\n if (this.disabled) return;\n return this.client.getCurrentAuthClaims();\n }\n /**\n * Set the authentication token to be used for subsequent queries and mutations.\n * `fetchToken` will be called automatically again if a token expires.\n * `fetchToken` should return `null` if the token cannot be retrieved, for example\n * when the user's rights were permanently revoked.\n * @param fetchToken - an async function returning the JWT (typically an OpenID Connect Identity Token)\n * @param onChange - a callback that will be called when the authentication status changes\n */\n setAuth(fetchToken, onChange) {\n if (this.disabled) return;\n this.client.setAuth(\n fetchToken,\n onChange ?? (() => {\n })\n );\n }\n /**\n * @internal\n */\n setAdminAuth(token, identity) {\n if (this.closed) {\n throw new Error(\"ConvexClient has already been closed.\");\n }\n if (this.disabled) return;\n this.client.setAdminAuth(token, identity);\n }\n /**\n * @internal\n */\n _transition({\n queries,\n paginatedQueries\n }, callNewListeners = false) {\n const updatedQueries = [\n ...queries.map((q) => q.token),\n ...paginatedQueries.map((q) => q.token)\n ];\n for (const queryInfo of this.listeners) {\n const { callback, queryToken, onError, hasEverRun } = queryInfo;\n const isPaginatedQuery = serializedQueryTokenIsPaginated(queryToken);\n const hasResultReady = isPaginatedQuery ? !!this.paginatedClient.localQueryResultByToken(queryToken) : this.client.hasLocalQueryResultByToken(queryToken);\n if (updatedQueries.includes(queryToken) || callNewListeners && !hasEverRun && hasResultReady) {\n queryInfo.hasEverRun = true;\n let newValue;\n try {\n if (isPaginatedQuery) {\n newValue = this.paginatedClient.localQueryResultByToken(queryToken);\n } else {\n newValue = this.client.localQueryResultByToken(queryToken);\n }\n } catch (error) {\n if (!(error instanceof Error)) throw error;\n if (onError) {\n onError(\n error,\n \"Second argument to onUpdate onError is reserved for later use\"\n );\n } else {\n void Promise.reject(error);\n }\n continue;\n }\n callback(\n newValue,\n \"Second argument to onUpdate callback is reserved for later use\"\n );\n }\n }\n }\n /**\n * Execute a mutation function.\n *\n * @param mutation - A {@link server.FunctionReference} for the public mutation\n * to run.\n * @param args - An arguments object for the mutation.\n * @param options - A {@link MutationOptions} options object for the mutation.\n * @returns A promise of the mutation's result.\n */\n async mutation(mutation, args, options) {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return await this.client.mutation(getFunctionName(mutation), args, options);\n }\n /**\n * Execute an action function.\n *\n * @param action - A {@link server.FunctionReference} for the public action\n * to run.\n * @param args - An arguments object for the action.\n * @returns A promise of the action's result.\n */\n async action(action, args) {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return await this.client.action(getFunctionName(action), args);\n }\n /**\n * Fetch a query result once.\n *\n * @param query - A {@link server.FunctionReference} for the public query\n * to run.\n * @param args - An arguments object for the query.\n * @returns A promise of the query's result.\n */\n async query(query, args) {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n const value = this.client.localQueryResult(getFunctionName(query), args);\n if (value !== void 0) return Promise.resolve(value);\n return new Promise((resolve, reject) => {\n const { unsubscribe } = this.onUpdate(\n query,\n args,\n (value2) => {\n unsubscribe();\n resolve(value2);\n },\n (e) => {\n unsubscribe();\n reject(e);\n }\n );\n });\n }\n /**\n * Get the current {@link ConnectionState} between the client and the Convex\n * backend.\n *\n * @returns The {@link ConnectionState} with the Convex backend.\n */\n connectionState() {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return this.client.connectionState();\n }\n /**\n * Subscribe to the {@link ConnectionState} between the client and the Convex\n * backend, calling a callback each time it changes.\n *\n * Subscribed callbacks will be called when any part of ConnectionState changes.\n * ConnectionState may grow in future versions (e.g. to provide a array of\n * inflight requests) in which case callbacks would be called more frequently.\n *\n * @returns An unsubscribe function to stop listening.\n */\n subscribeToConnectionState(cb) {\n if (this.disabled) return () => {\n };\n return this.client.subscribeToConnectionState(cb);\n }\n}\n//# sourceMappingURL=simple_client.js.map\n","/**\n * For clusters of correlated `useState` values, where a union makes invalid\n * combinations unrepresentable and side-effects become one effect per\n * `state.kind` rather than orchestration spread across many.\n *\n * Invalid transitions are silent no-ops, not throws.\n */\n\nimport { useCallback, useRef, useState } from 'preact/hooks'\n\n/**\n * Typed so a handler keyed `'idle'`/`'start'` receives the narrowed variants\n * rather than the full unions. `Partial<>` lets a state omit irrelevant events.\n */\nexport type TransitionMap<S extends { kind: string }, E extends { type: string }> = {\n [K in S['kind']]?: Partial<{\n [T in E['type']]: (state: Extract<S, { kind: K }>, event: Extract<E, { type: T }>) => S\n }>\n}\n\nexport type Send<E extends { type: string }> = (event: E) => void\n\n/** Identity helper; only exists so the literal gets full type inference. */\nexport function defineMachine<S extends { kind: string }, E extends { type: string }>(\n transitions: TransitionMap<S, E>,\n): TransitionMap<S, E> {\n return transitions\n}\n\n/**\n * `send` is stable across renders, so it can sit in dependency arrays. The\n * transition table is held in a ref so each call still sees the freshest\n * closure values — callers can inline `defineMachine(...)` in the render body\n * and reference render-scope values without memoizing.\n */\nexport function useMachine<S extends { kind: string }, E extends { type: string }>(\n transitions: TransitionMap<S, E>,\n // `NoInfer` so a narrow literal here doesn't pin `S` to one variant: `S`\n // comes from the transition table, which carries the full union.\n initial: NoInfer<S> | (() => NoInfer<S>),\n): [S, Send<E>] {\n const transitionsRef = useRef(transitions)\n transitionsRef.current = transitions\n\n const [state, setState] = useState<S>(() =>\n typeof initial === 'function' ? (initial as () => S)() : initial,\n )\n\n const send = useCallback<Send<E>>((event) => {\n setState((current) => {\n const forKind = transitionsRef.current[current.kind as S['kind']]\n const handler = forKind?.[event.type as E['type']] as ((s: S, e: E) => S) | undefined\n return handler ? handler(current, event) : current\n })\n }, [])\n\n return [state, send]\n}\n","/**\n * Duplicates `convex/lib/mentions.ts` because a server module and a browser\n * bundle can't import each other. Keep them in lockstep.\n *\n * The `@[Display Name](userId)` marker is a transport detail never shown to a\n * human. Renderers MUST promote one to a chip only when its userId appears in\n * the comment's validated `mentions` array; otherwise it renders `@Name`.\n */\nconst MENTION_MARKER_REGEX = /@\\[([^\\]\\n]+)\\]\\(([^)\\s]+)\\)/g\n\nexport type MentionToken =\n | { type: 'text'; value: string }\n | { type: 'mention'; userId: string; name: string }\n\nexport function parseMentionTokens(body: string): MentionToken[] {\n const tokens: MentionToken[] = []\n let lastIndex = 0\n const re = new RegExp(MENTION_MARKER_REGEX.source, 'g')\n for (let m = re.exec(body); m !== null; m = re.exec(body)) {\n if (m.index > lastIndex) {\n tokens.push({ type: 'text', value: body.slice(lastIndex, m.index) })\n }\n tokens.push({ type: 'mention', name: m[1] ?? '', userId: m[2] ?? '' })\n lastIndex = m.index + m[0].length\n }\n if (lastIndex < body.length) {\n tokens.push({ type: 'text', value: body.slice(lastIndex) })\n }\n return tokens\n}\n\nexport function extractMentionUserIds(body: string): string[] {\n const seen = new Set<string>()\n const out: string[] = []\n const re = new RegExp(MENTION_MARKER_REGEX.source, 'g')\n for (let m = re.exec(body); m !== null; m = re.exec(body)) {\n const id = m[2]\n if (id && !seen.has(id)) {\n seen.add(id)\n out.push(id)\n }\n }\n return out\n}\n\n/** `null` means no `@`-trigger is active. */\nexport type MentionTriggerState = {\n /** Index in the value where the `@` lives. */\n at: number\n /** Caret position when the trigger was last computed. */\n caret: number\n /** The query string after the `@` (may be empty). */\n query: string\n}\n\nexport function detectMentionTrigger(value: string, caret: number): MentionTriggerState | null {\n for (let i = caret - 1; i >= 0; i--) {\n const ch = value[i]\n if (ch === '@') {\n const prev = i === 0 ? undefined : value[i - 1]\n const isBoundary = prev === undefined || /\\s/.test(prev)\n if (!isBoundary) return null\n const query = value.slice(i + 1, caret)\n if (/\\s/.test(query)) return null\n return { at: i, caret, query }\n }\n if (ch === undefined) return null\n if (/[\\s\\]()]/.test(ch)) return null\n }\n return null\n}\n\n/**\n * The display name is sanitised because a `]` or newline would terminate the\n * marker early and leave half of it as literal text.\n *\n * `null` when the userId itself can't be encoded. No real id contains\n * whitespace or `)`; the guard makes a malformed one degrade to \"no mention\"\n * rather than corrupt the body around it.\n */\nexport function mentionMarkerFor(member: { userId: string; name: string }): string | null {\n if (!member.userId || /[)\\s]/.test(member.userId)) return null\n const name = member.name.replace(/[\\]\\r\\n]+/g, ' ').trim()\n if (!name) return null\n return `@[${name}](${member.userId})`\n}\n\n/** For surfaces that can only take a string — titles, `aria-label`s. */\nexport function renderMentionsAsPlainText(body: string): string {\n return body.replace(\n new RegExp(MENTION_MARKER_REGEX.source, 'g'),\n (_m, name: string) => `@${name}`,\n )\n}\n","/**\n * Modeled on TanStack Query's `useMutation`, with the state union making\n * pending+error and error+success unrepresentable. Re-entrant calls while\n * pending are dropped, which subsumes the per-handler `if (busy) return`.\n *\n * **Unlike `useMutation`, the function is passed per call to `run`** rather\n * than bound at setup. One popover surfaces one `pending` + `error` at a time,\n * so binding at the hook would force an instance per handler plus an\n * aggregator; per-call binding keeps the shared instance and still gives each\n * invocation its own callbacks.\n *\n * Deliberately omitted: `retry` (the widget's retry loops own their timing),\n * `mutate` vs `mutateAsync` (not awaiting `run` is already fire-and-forget),\n * and `onMutate` rollback (Convex subscriptions are the authoritative cache,\n * so nothing here optimistic-updates).\n */\n\nimport { useCallback, useRef } from 'preact/hooks'\n\nimport { defineMachine, useMachine } from './machine'\n\nexport type AsyncActionState<T> =\n | { kind: 'idle' }\n | { kind: 'pending' }\n | { kind: 'success'; data: T }\n | { kind: 'error'; message: string }\n\ntype AsyncActionEvent =\n | { type: 'start' }\n | { type: 'success'; data: unknown }\n | { type: 'failure'; message: string }\n | { type: 'reset' }\n\n// `unknown` so one machine instance backs any per-hook `T`. The transitions\n// only shuttle `data` through, never read it, so the cast at the hook\n// boundary is sound.\nconst machine = defineMachine<AsyncActionState<unknown>, AsyncActionEvent>({\n idle: {\n start: () => ({ kind: 'pending' }),\n },\n pending: {\n success: (_, e) => ({ kind: 'success', data: e.data }),\n failure: (_, e) => ({ kind: 'error', message: e.message }),\n },\n success: {\n // Drops the previous data, matching `useMutation`.\n start: () => ({ kind: 'pending' }),\n reset: () => ({ kind: 'idle' }),\n },\n error: {\n start: () => ({ kind: 'pending' }),\n reset: () => ({ kind: 'idle' }),\n },\n})\n\nexport interface RunOptions<T> {\n /** For a parent that must react to failure, e.g. keeping a form open. */\n rethrow?: boolean\n /** Fires after the success transition, with the resolved value. */\n onSuccess?: (data: T) => void\n /** Fires after the failure transition, with the surfaced message. */\n onError?: (message: string) => void\n /** Fires after either branch — equivalent to a `finally`. */\n onSettled?: () => void\n}\n\nexport interface UseAsyncActionResult<T> {\n state: AsyncActionState<T>\n isIdle: boolean\n isPending: boolean\n isSuccess: boolean\n isError: boolean\n /** Resolved value of the most recent successful run, else `undefined`. */\n data: T | undefined\n /** Message from the most recent failure, else `undefined`. */\n error: string | undefined\n /**\n * `undefined` covers two different outcomes: `fn` threw without `rethrow`,\n * or the call was a re-entrant no-op while already pending.\n */\n run: (fn: () => Promise<T>, options?: RunOptions<T>) => Promise<T | undefined>\n /** Force back to `idle`, dropping any data or error message. */\n reset: () => void\n}\n\nexport function useAsyncAction<T = unknown>(): UseAsyncActionResult<T> {\n const [stateAny, send] = useMachine(machine, { kind: 'idle' })\n const state = stateAny as AsyncActionState<T>\n\n // Through a ref, so a re-entrant call in the same render cycle is caught\n // before the machine state reaches the closure.\n const stateRef = useRef(state)\n stateRef.current = state\n\n const run = useCallback(\n async (fn: () => Promise<T>, options?: RunOptions<T>) => {\n if (stateRef.current.kind === 'pending') return undefined\n send({ type: 'start' })\n try {\n const result = await fn()\n send({ type: 'success', data: result })\n options?.onSuccess?.(result)\n options?.onSettled?.()\n return result\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Action failed'\n send({ type: 'failure', message })\n options?.onError?.(message)\n options?.onSettled?.()\n if (options?.rethrow) throw err\n return undefined\n }\n },\n [send],\n )\n\n const reset = useCallback(() => send({ type: 'reset' }), [send])\n\n return {\n state,\n isIdle: state.kind === 'idle',\n isPending: state.kind === 'pending',\n isSuccess: state.kind === 'success',\n isError: state.kind === 'error',\n data: state.kind === 'success' ? state.data : undefined,\n error: state.kind === 'error' ? state.message : undefined,\n run,\n reset,\n }\n}\n","// License: MIT\n// Author: Anton Medvedev <anton@medv.io>\n// Source: https://github.com/antonmedv/finder\nconst acceptedAttrNames = new Set(['role', 'name', 'aria-label', 'rel', 'href']);\n/** Check if attribute name and value are word-like. */\nexport function attr(name, value) {\n let nameIsOk = acceptedAttrNames.has(name);\n nameIsOk ||= name.startsWith('data-') && wordLike(name);\n let valueIsOk = wordLike(value) && value.length < 100;\n valueIsOk ||= value.startsWith('#') && wordLike(value.slice(1));\n return nameIsOk && valueIsOk;\n}\n/** Check if id name is word-like. */\nexport function idName(name) {\n return wordLike(name);\n}\n/** Check if class name is word-like. */\nexport function className(name) {\n return wordLike(name);\n}\n/** Check if tag name is word-like. */\nexport function tagName(name) {\n return true;\n}\n/** Finds unique CSS selectors for the given element. */\nexport function finder(input, options) {\n if (input.nodeType !== Node.ELEMENT_NODE) {\n throw new Error(`Can't generate CSS selector for non-element node type.`);\n }\n if (input.tagName.toLowerCase() === 'html') {\n return 'html';\n }\n const defaults = {\n root: document.body,\n idName: idName,\n className: className,\n tagName: tagName,\n attr: attr,\n timeoutMs: 1000,\n seedMinLength: 3,\n optimizedMinLength: 2,\n maxNumberOfPathChecks: Infinity,\n };\n const startTime = new Date();\n const config = { ...defaults, ...options };\n const rootDocument = findRootDocument(config.root, defaults);\n let foundPath;\n let count = 0;\n for (const candidate of search(input, config, rootDocument)) {\n const elapsedTimeMs = new Date().getTime() - startTime.getTime();\n if (elapsedTimeMs > config.timeoutMs ||\n count >= config.maxNumberOfPathChecks) {\n const fPath = fallback(input, rootDocument);\n if (!fPath) {\n throw new Error(`Timeout: Can't find a unique selector after ${config.timeoutMs}ms`);\n }\n return selector(fPath);\n }\n count++;\n if (unique(candidate, rootDocument)) {\n foundPath = candidate;\n break;\n }\n }\n if (!foundPath) {\n throw new Error(`Selector was not found.`);\n }\n const optimized = [\n ...optimize(foundPath, input, config, rootDocument, startTime),\n ];\n optimized.sort(byPenalty);\n if (optimized.length > 0) {\n return selector(optimized[0]);\n }\n return selector(foundPath);\n}\nfunction* search(input, config, rootDocument) {\n const stack = [];\n let paths = [];\n let current = input;\n let i = 0;\n while (current && current !== rootDocument) {\n const level = tie(current, config);\n for (const node of level) {\n node.level = i;\n }\n stack.push(level);\n current = current.parentElement;\n i++;\n paths.push(...combinations(stack));\n if (i >= config.seedMinLength) {\n paths.sort(byPenalty);\n for (const candidate of paths) {\n yield candidate;\n }\n paths = [];\n }\n }\n paths.sort(byPenalty);\n for (const candidate of paths) {\n yield candidate;\n }\n}\nfunction wordLike(name) {\n if (/^[a-z\\-]{3,}$/i.test(name)) {\n const words = name.split(/-|[A-Z]/);\n for (const word of words) {\n if (word.length <= 2) {\n return false;\n }\n if (/[^aeiou]{4,}/i.test(word)) {\n return false;\n }\n }\n return true;\n }\n return false;\n}\nfunction tie(element, config) {\n const level = [];\n const elementId = element.getAttribute('id');\n if (elementId && config.idName(elementId)) {\n level.push({\n name: '#' + CSS.escape(elementId),\n penalty: 0,\n });\n }\n for (let i = 0; i < element.classList.length; i++) {\n const name = element.classList[i];\n if (config.className(name)) {\n level.push({\n name: '.' + CSS.escape(name),\n penalty: 1,\n });\n }\n }\n for (let i = 0; i < element.attributes.length; i++) {\n const attr = element.attributes[i];\n if (config.attr(attr.name, attr.value)) {\n level.push({\n name: `[${CSS.escape(attr.name)}=\"${CSS.escape(attr.value)}\"]`,\n penalty: 2,\n });\n }\n }\n const tagName = element.tagName.toLowerCase();\n if (config.tagName(tagName)) {\n level.push({\n name: tagName,\n penalty: 5,\n });\n const index = indexOf(element, tagName);\n if (index !== undefined) {\n level.push({\n name: nthOfType(tagName, index),\n penalty: 10,\n });\n }\n }\n const nth = indexOf(element);\n if (nth !== undefined) {\n level.push({\n name: nthChild(tagName, nth),\n penalty: 50,\n });\n }\n return level;\n}\nfunction selector(path) {\n let node = path[0];\n let query = node.name;\n for (let i = 1; i < path.length; i++) {\n const level = path[i].level || 0;\n if (node.level === level - 1) {\n query = `${path[i].name} > ${query}`;\n }\n else {\n query = `${path[i].name} ${query}`;\n }\n node = path[i];\n }\n return query;\n}\nfunction penalty(path) {\n return path.map((node) => node.penalty).reduce((acc, i) => acc + i, 0);\n}\nfunction byPenalty(a, b) {\n return penalty(a) - penalty(b);\n}\nfunction indexOf(input, tagName) {\n const parent = input.parentNode;\n if (!parent) {\n return undefined;\n }\n let child = parent.firstChild;\n if (!child) {\n return undefined;\n }\n let i = 0;\n while (child) {\n if (child.nodeType === Node.ELEMENT_NODE &&\n (tagName === undefined ||\n child.tagName.toLowerCase() === tagName)) {\n i++;\n }\n if (child === input) {\n break;\n }\n child = child.nextSibling;\n }\n return i;\n}\nfunction fallback(input, rootDocument) {\n let i = 0;\n let current = input;\n const path = [];\n while (current && current !== rootDocument) {\n const tagName = current.tagName.toLowerCase();\n const index = indexOf(current, tagName);\n if (index === undefined) {\n return;\n }\n path.push({\n name: nthOfType(tagName, index),\n penalty: NaN,\n level: i,\n });\n current = current.parentElement;\n i++;\n }\n if (unique(path, rootDocument)) {\n return path;\n }\n}\nfunction nthChild(tagName, index) {\n if (tagName === 'html') {\n return 'html';\n }\n return `${tagName}:nth-child(${index})`;\n}\nfunction nthOfType(tagName, index) {\n if (tagName === 'html') {\n return 'html';\n }\n return `${tagName}:nth-of-type(${index})`;\n}\nfunction* combinations(stack, path = []) {\n if (stack.length > 0) {\n for (let node of stack[0]) {\n yield* combinations(stack.slice(1, stack.length), path.concat(node));\n }\n }\n else {\n yield path;\n }\n}\nfunction findRootDocument(rootNode, defaults) {\n if (rootNode.nodeType === Node.DOCUMENT_NODE) {\n return rootNode;\n }\n if (rootNode === defaults.root) {\n return rootNode.ownerDocument;\n }\n return rootNode;\n}\nfunction unique(path, rootDocument) {\n const css = selector(path);\n switch (rootDocument.querySelectorAll(css).length) {\n case 0:\n throw new Error(`Can't select any node with this selector: ${css}`);\n case 1:\n return true;\n default:\n return false;\n }\n}\nfunction* optimize(path, input, config, rootDocument, startTime) {\n if (path.length > 2 && path.length > config.optimizedMinLength) {\n for (let i = 1; i < path.length - 1; i++) {\n const elapsedTimeMs = new Date().getTime() - startTime.getTime();\n if (elapsedTimeMs > config.timeoutMs) {\n return;\n }\n const newPath = [...path];\n newPath.splice(i, 1);\n if (unique(newPath, rootDocument) &&\n rootDocument.querySelector(selector(newPath)) === input) {\n yield newPath;\n yield* optimize(newPath, input, config, rootDocument, startTime);\n }\n }\n }\n}\n","/**\n * Pins store 0..1 fractions of the page's content size plus a viewport\n * snapshot, which re-renders them roughly in place across responsive layouts.\n * The CSS selector captured alongside is what allows an exact re-anchor after\n * a reflow.\n */\n\nimport { finder } from '@medv/finder'\n\nexport type PageCoords = {\n /** Fraction 0..1 of document.documentElement.scrollWidth */\n anchorX: number\n /** Fraction 0..1 of document.documentElement.scrollHeight */\n anchorY: number\n viewportW: number\n viewportY: number\n anchorSelector?: string\n /** Fraction 0..1 of the anchored element's width at click point */\n anchorOffsetX?: number\n /** Fraction 0..1 of the anchored element's height at click point */\n anchorOffsetY?: number\n}\n\nexport type ScreenPoint = {\n /** Pixel position relative to the document (page coords, includes scroll) */\n pageX: number\n pageY: number\n /**\n * `false` means these are fraction-fallback coords, so the caller should\n * render a tentative cue and retry after DOM mutations.\n */\n resolved: boolean\n /** Held so callers can notice via `isConnected` that an anchor was lost. */\n element: Element | null\n}\n\n/** Pass `target` when an overlay is intercepting the click. */\nexport function toPageCoords(event: MouseEvent, target?: Element | null): PageCoords {\n const docEl = document.documentElement\n const docW = Math.max(docEl.scrollWidth, docEl.clientWidth)\n const docH = Math.max(docEl.scrollHeight, docEl.clientHeight)\n\n const pageX = event.clientX + window.scrollX\n const pageY = event.clientY + window.scrollY\n\n const resolvedTarget =\n target !== undefined ? target : event.target instanceof Element ? event.target : null\n const selector = resolvedTarget ? elementSelector(resolvedTarget) : undefined\n\n let anchorOffsetX: number | undefined\n let anchorOffsetY: number | undefined\n if (resolvedTarget) {\n const rect = resolvedTarget.getBoundingClientRect()\n if (rect.width > 0 && rect.height > 0) {\n anchorOffsetX = Math.max(0, Math.min(1, (event.clientX - rect.left) / rect.width))\n anchorOffsetY = Math.max(0, Math.min(1, (event.clientY - rect.top) / rect.height))\n }\n }\n\n return {\n anchorX: docW > 0 ? pageX / docW : 0,\n anchorY: docH > 0 ? pageY / docH : 0,\n viewportW: window.innerWidth,\n viewportY: window.innerHeight,\n anchorSelector: selector,\n anchorOffsetX,\n anchorOffsetY,\n }\n}\n\n/** Falls back to fraction × current document size when the selector misses. */\nexport function resolveCoords(c: {\n anchorX: number\n anchorY: number\n anchorSelector?: string\n anchorOffsetX?: number\n anchorOffsetY?: number\n}): ScreenPoint {\n if (c.anchorSelector) {\n try {\n const el = document.querySelector(c.anchorSelector)\n // A matched-but-unrendered element reports an all-zero rect, and\n // anchoring to it parks the pin in the page's top-left corner as if\n // that were real. Treated as a miss instead.\n const rect = el?.getBoundingClientRect()\n if (el && rect && isRendered(rect)) {\n return {\n pageX: rect.left + window.scrollX + (c.anchorOffsetX ?? 0.5) * rect.width,\n pageY: rect.top + window.scrollY + (c.anchorOffsetY ?? 0.5) * rect.height,\n resolved: true,\n element: el,\n }\n }\n } catch {\n // bad selector — fall through to fraction math\n }\n }\n\n const docEl = document.documentElement\n const docW = Math.max(docEl.scrollWidth, docEl.clientWidth)\n const docH = Math.max(docEl.scrollHeight, docEl.clientHeight)\n return {\n pageX: c.anchorX * docW,\n pageY: c.anchorY * docH,\n resolved: false,\n element: null,\n }\n}\n\n/**\n * Only the degenerate all-zero rect counts as unrendered: a zero-width but\n * positioned element still has a meaningful location.\n */\nfunction isRendered(rect: DOMRect): boolean {\n return rect.width !== 0 || rect.height !== 0 || rect.top !== 0 || rect.left !== 0\n}\n\nfunction elementSelector(el: Element): string | undefined {\n try {\n return finder(el, { timeoutMs: 1000 })\n } catch {\n return undefined\n }\n}\n","/** Raises a typed error on any non-2xx, so the UI has one failure path. */\n\nexport type WidgetThread = {\n _id: string\n url: string\n route: string\n anchorSelector?: string\n anchorX: number\n anchorY: number\n anchorOffsetX?: number\n anchorOffsetY?: number\n viewportW: number\n viewportY: number\n authorName: string\n authorClientId: string\n createdAt: number\n resolvedAt?: number\n screenshotUrl?: string\n comments: Array<{\n _id: string\n body: string\n /**\n * Server-validated: a non-member or a tombstone filters to `[]`. Renderers\n * promote a `@[Name](id)` marker to a chip only when its id is in here.\n */\n mentions: string[]\n authorName: string\n /**\n * Renderers MUST fall back to initials both when this is absent and when\n * the image fails to load: it's a third-party URL a host page's CSP is\n * free to block.\n */\n authorImage?: string\n /** Widget identity that authored this comment (undefined for dashboard replies). */\n authorClientId?: string\n fromDashboard: boolean\n createdAt: number\n editedAt?: number\n /**\n * The comment carries the delegating person's name, so without the badge\n * this renders a visitor no way to tell a machine answered them.\n */\n authoredVia?: 'mcp'\n /** True for soft-deleted comments; `body` is blanked server-side. */\n deleted: boolean\n /**\n * Sorted server-side by the fixed palette order so chips stay stable. An\n * optimistic toggle MUST update `count` and `mine` together. The viewer's\n * own entry is missing from `reactors` — the client re-inserts \"you\".\n */\n reactions: Array<{ emoji: string; count: number; mine: boolean; reactors: string[] }>\n }>\n}\n\nexport type CreateThreadPayload = {\n url: string\n route: string\n anchorSelector?: string\n anchorX: number\n anchorY: number\n anchorOffsetX?: number\n anchorOffsetY?: number\n viewportW: number\n viewportY: number\n userAgent: string\n authorName: string\n authorEmail?: string\n body: string\n /** Optional. Server re-validates each id against `projectMembers`. */\n mentions?: string[]\n screenshotStorageId?: string\n}\n\nexport type AddCommentPayload = {\n body: string\n authorName: string\n authorEmail?: string\n /** Optional. Server re-validates each id against `projectMembers`. */\n mentions?: string[]\n}\n\nexport type EditCommentPayload = {\n body: string\n /** Optional. Server re-validates each id against `projectMembers`. */\n mentions?: string[]\n}\n\nexport type WidgetMember = { userId: string; name: string }\n\n/** Only verified users see these; anonymous visitors get 401. */\nexport type WidgetNotification = {\n _id: string\n type: 'mention'\n createdAt: number\n readAt?: number\n actorName: string\n /**\n * The row is attributed to the delegating person, so this is the only thing\n * distinguishing it from their own reply.\n */\n actorVia?: 'mcp'\n threadId: string\n commentId: string\n /** Navigated to when the thread lives on another route. */\n threadUrl: string\n commentExcerpt: string\n threadTitle: string\n}\n\nexport class WidgetApiError extends Error {\n status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'WidgetApiError'\n this.status = status\n }\n}\n\n/**\n * Distinct from `WidgetApiError` so the UI can tell a slow network from a\n * server error. `status` is `0` because no response arrived, matching fetch's\n * own behaviour for AbortErrors.\n */\nexport class WidgetTimeoutError extends WidgetApiError {\n /** For log/Sentry filtering. */\n category: 'read' | 'write' | 'upload'\n constructor(operation: string, category: 'read' | 'write' | 'upload') {\n super(`${operation} took too long — check your connection`, 0)\n this.name = 'WidgetTimeoutError'\n this.category = category\n }\n}\n\n/**\n * Without these, a blackholing corporate proxy or dead DNS leaves the UI\n * pending forever. Deliberately generous — a phone on degraded 4G should still\n * finish a write — because a too-tight bound generates its own support tickets.\n */\nexport const READ_TIMEOUT_MS = 15_000\nexport const WRITE_TIMEOUT_MS = 30_000\n\n/** Optional per-call overrides. */\nexport interface WidgetApiRequestOptions {\n /** Composed with the per-method timeout, so either source can cancel. */\n signal?: AbortSignal\n}\n\n/**\n * `AbortSignal.any` rather than hand-rolled listeners, because it forwards the\n * specific reason (`TimeoutError` vs `AbortError`) into the rejection, which is\n * what lets `request` tell \"timed out\" from \"caller cancelled\".\n *\n * Exported for the fetches that legitimately sit outside `request()` — the auth\n * handshake and the background token refresh — so they get a deadline without\n * hand-rolling one. The `widget-fetch-timeouts` test keeps that list honest.\n */\nexport function combinedSignal(timeoutMs: number, callerSignal?: AbortSignal): AbortSignal {\n const timeoutSignal = AbortSignal.timeout(timeoutMs)\n return callerSignal ? AbortSignal.any([callerSignal, timeoutSignal]) : timeoutSignal\n}\n\nexport type WidgetApiClient = ReturnType<typeof createApiClient>\n\nexport interface CreateApiClientOpts {\n apiUrl: string\n apiKey: string\n /**\n * Called per request so the client always sees the freshest token without\n * being recreated. Client-side expiry is a shortcut only — the server 401s\n * anything stale that slips through.\n */\n getToken?: () => { token: string; expiresAt: number } | null\n /**\n * Sent as `x-markup-anon-token`. The server trusts the embedded clientId for\n * ownership checks because it verified the signature — this is what replaces\n * trusting a clientId from the request body.\n */\n getAnonToken?: () => string | null\n /**\n * Only for 401s on a request that carried a Bearer. A 401 without one means\n * the api key itself is bad, which is not recoverable by re-minting.\n */\n onUnauthorized?: () => void\n /**\n * `'cookies'` switches the client to `credentials: 'include'` so the browser\n * attaches the HttpOnly access cookie; `getToken` already returns null there.\n */\n getStorageMode?: () => 'cookies' | 'localStorage' | null\n}\n\nexport function createApiClient(opts: CreateApiClientOpts) {\n const baseUrl = opts.apiUrl.replace(/\\/+$/, '')\n\n async function request<T>(\n path: string,\n init: RequestInit,\n reqOpts: {\n timeoutMs: number\n category: 'read' | 'write'\n operation: string\n signal?: AbortSignal\n },\n ): Promise<T> {\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n 'x-markup-api-key': opts.apiKey,\n ...((init.headers ?? {}) as Record<string, string>),\n }\n\n const cached = opts.getToken?.() ?? null\n const sentBearer = cached != null && cached.token.length > 0 && cached.expiresAt > Date.now()\n if (sentBearer && cached) {\n headers['authorization'] = `Bearer ${cached.token}`\n }\n\n const anon = opts.getAnonToken?.() ?? null\n if (anon) {\n headers['x-markup-anon-token'] = anon\n }\n\n // No Authorization header and no anon token in this mode — the HttpOnly\n // cookie the browser attaches is what carries auth.\n const useCookies = opts.getStorageMode?.() === 'cookies'\n const fetchInit: RequestInit = {\n ...init,\n headers,\n signal: combinedSignal(reqOpts.timeoutMs, reqOpts.signal),\n }\n if (useCookies) {\n fetchInit.credentials = 'include'\n }\n\n let res: Response\n try {\n res = await fetch(`${baseUrl}${path}`, fetchInit)\n } catch (err) {\n // A fired deadline arrives as `TimeoutError`, a caller abort as\n // `AbortError`. Only the first becomes a typed error — the second is the\n // caller's own intent and propagates unchanged.\n if (err instanceof DOMException && err.name === 'TimeoutError') {\n throw new WidgetTimeoutError(reqOpts.operation, reqOpts.category)\n }\n throw err\n }\n\n const text = await res.text()\n const data = text ? safeJson(text) : null\n if (!res.ok) {\n // Either a stale Bearer, or a cookie that was revoked or not attached\n // because the partition disappeared.\n if (res.status === 401 && (sentBearer || useCookies)) {\n opts.onUnauthorized?.()\n }\n const message =\n (data && typeof data === 'object' && 'error' in data && typeof data.error === 'string'\n ? data.error\n : null) ?? `Request failed with ${res.status}`\n throw new WidgetApiError(message, res.status)\n }\n return data as T\n }\n\n return {\n mintAnonIdentity(\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ clientId: string; token: string; expiresAt: number }> {\n return request<{ clientId: string; token: string; expiresAt: number }>(\n '/widget/anon-identity',\n { method: 'POST' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'mint-anon-identity',\n signal: reqOpts?.signal,\n },\n )\n },\n getSubscriptionToken(\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ token: string; expiresAt: number }> {\n return request<{ token: string; expiresAt: number }>(\n '/widget/subscription-token',\n { method: 'POST' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'mint-subscription-token',\n signal: reqOpts?.signal,\n },\n )\n },\n getScreenshotUploadUrl(reqOpts?: WidgetApiRequestOptions): Promise<{ uploadUrl: string }> {\n return request<{ uploadUrl: string }>(\n '/widget/screenshots/upload-url',\n { method: 'POST' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'mint-screenshot-upload-url',\n signal: reqOpts?.signal,\n },\n )\n },\n listThreads(\n route: string,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ threads: WidgetThread[] }> {\n return request<{ threads: WidgetThread[] }>(\n `/widget/threads?route=${encodeURIComponent(route)}`,\n { method: 'GET' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'list-threads',\n signal: reqOpts?.signal,\n },\n )\n },\n listMembers(reqOpts?: WidgetApiRequestOptions): Promise<{ members: WidgetMember[] }> {\n return request<{ members: WidgetMember[] }>(\n `/widget/members`,\n { method: 'GET' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'list-members',\n signal: reqOpts?.signal,\n },\n )\n },\n listNotifications(\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ notifications: WidgetNotification[] }> {\n return request<{ notifications: WidgetNotification[] }>(\n `/widget/notifications`,\n { method: 'GET' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'list-notifications',\n signal: reqOpts?.signal,\n },\n )\n },\n markNotificationRead(notificationId: string, reqOpts?: WidgetApiRequestOptions): Promise<void> {\n return request<void>(\n `/widget/notifications/${encodeURIComponent(notificationId)}/read`,\n { method: 'POST' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'mark-notification-read',\n signal: reqOpts?.signal,\n },\n )\n },\n markAllNotificationsRead(reqOpts?: WidgetApiRequestOptions): Promise<void> {\n return request<void>(\n `/widget/notifications/read-all`,\n { method: 'POST' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'mark-all-notifications-read',\n signal: reqOpts?.signal,\n },\n )\n },\n createThread(\n payload: CreateThreadPayload,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ thread: WidgetThread }> {\n return request<{ thread: WidgetThread }>(\n `/widget/threads`,\n { method: 'POST', body: JSON.stringify(payload) },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'create-thread',\n signal: reqOpts?.signal,\n },\n )\n },\n deleteThread(threadId: string, reqOpts?: WidgetApiRequestOptions): Promise<void> {\n return request<void>(\n `/widget/threads/${encodeURIComponent(threadId)}`,\n { method: 'DELETE' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'delete-thread',\n signal: reqOpts?.signal,\n },\n )\n },\n resolveThread(\n threadId: string,\n resolvedBy?: string,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<void> {\n return request<void>(\n `/widget/threads/${encodeURIComponent(threadId)}`,\n { method: 'PATCH', body: JSON.stringify({ resolvedBy }) },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'resolve-thread',\n signal: reqOpts?.signal,\n },\n )\n },\n addComment(\n threadId: string,\n payload: AddCommentPayload,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ thread: WidgetThread }> {\n return request<{ thread: WidgetThread }>(\n `/widget/threads/${encodeURIComponent(threadId)}/comments`,\n { method: 'POST', body: JSON.stringify(payload) },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'add-comment',\n signal: reqOpts?.signal,\n },\n )\n },\n editComment(\n threadId: string,\n commentId: string,\n payload: EditCommentPayload,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ thread: WidgetThread }> {\n return request<{ thread: WidgetThread }>(\n `/widget/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(commentId)}`,\n { method: 'PATCH', body: JSON.stringify(payload) },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'edit-comment',\n signal: reqOpts?.signal,\n },\n )\n },\n deleteComment(\n threadId: string,\n commentId: string,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ thread: WidgetThread }> {\n return request<{ thread: WidgetThread }>(\n `/widget/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(commentId)}`,\n { method: 'DELETE' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'delete-comment',\n signal: reqOpts?.signal,\n },\n )\n },\n toggleReaction(\n commentId: string,\n payload: { emoji: string; authorName?: string },\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ thread: WidgetThread }> {\n return request<{ thread: WidgetThread }>(\n `/widget/comments/${encodeURIComponent(commentId)}/reactions`,\n { method: 'POST', body: JSON.stringify(payload) },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'toggle-reaction',\n signal: reqOpts?.signal,\n },\n )\n },\n /**\n * Authenticated off the `x-markup-anon-token` JWT, so no body is required.\n * Verified Bearers are 403'd — that erasure is a dashboard flow.\n */\n forgetMe(reqOpts?: WidgetApiRequestOptions): Promise<void> {\n return request<void>(\n '/widget/forget-me',\n { method: 'POST' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'forget-me',\n signal: reqOpts?.signal,\n },\n )\n },\n /**\n * Anon callers get 401: nothing ties an anon JWT into the issuance and\n * revocation tables, so their path is the local-only forget-me instead.\n * The counts are diagnostics — the UI transitions on any non-error reply.\n */\n signOut(\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ revoked: number; refreshTokensRevoked: number }> {\n return request<{ revoked: number; refreshTokensRevoked: number }>(\n '/widget/sign-out',\n { method: 'POST' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'sign-out',\n signal: reqOpts?.signal,\n },\n )\n },\n }\n}\n\nfunction safeJson(text: string): unknown {\n try {\n return JSON.parse(text)\n } catch {\n return null\n }\n}\n","/**\n * Decides between cookie-mode auth and the localStorage fallback, by setting a\n * cookie server-side and asking whether it came back.\n *\n * Cached in sessionStorage, deliberately not localStorage: a user can change\n * their third-party cookie policy, and a fresh tab should re-discover that.\n */\n\nimport { combinedSignal, READ_TIMEOUT_MS } from './api'\nimport { reportError } from './error-reporter'\n\nconst SESSION_KEY = 'markup.cookieProbe'\n\nexport async function probePartitionedCookieSupport(\n apiUrl: string,\n apiKey: string,\n): Promise<boolean> {\n // Cached result wins so a refresh inside the same tab is free.\n try {\n const cached = sessionStorage.getItem(SESSION_KEY)\n if (cached === 'supported') return true\n if (cached === 'unsupported') return false\n } catch {\n /* sessionStorage disabled — re-probe every time. Cheap. */\n }\n\n const base = apiUrl.replace(/\\/+$/, '')\n const headers = { 'x-markup-api-key': apiKey }\n\n try {\n const setRes = await fetch(`${base}/widget/auth/probe-set`, {\n method: 'POST',\n credentials: 'include',\n headers,\n signal: combinedSignal(READ_TIMEOUT_MS),\n })\n if (!setRes.ok) {\n // An older deployment without the endpoint, or a rejected origin.\n // Deliberately uncached, so a later deploy is picked up by a fresh tab.\n return false\n }\n const checkRes = await fetch(`${base}/widget/auth/probe-check`, {\n method: 'POST',\n credentials: 'include',\n headers,\n signal: combinedSignal(READ_TIMEOUT_MS),\n })\n if (!checkRes.ok) return false\n const { supported } = (await checkRes.json()) as { supported?: unknown }\n const result = supported === true\n try {\n sessionStorage.setItem(SESSION_KEY, result ? 'supported' : 'unsupported')\n } catch {\n /* sessionStorage disabled — leave uncached. */\n }\n return result\n } catch (err) {\n // Degrades to the localStorage flow. TypeError is network or CORS and is\n // routine; anything else — a throw inside `.json()` — is structural.\n const name = (err as { name?: unknown } | null)?.name\n if (name !== 'TypeError') {\n reportError(err, { context: 'cookie-probe' })\n }\n return false\n }\n}\n","import { reportError } from './error-reporter'\n\ntype Listener = () => void\n\nconst PATCHED_MARKER = '__markup_history_observer__'\nconst LISTENERS_KEY = '__markup_history_listeners__'\n\n/**\n * A throwing listener must not break its siblings and must not propagate: the\n * call stack here belongs to the host page's `history.pushState`, so an\n * escape crashes the customer's navigation code.\n */\nfunction dispatch(listeners: Set<Listener>) {\n listeners.forEach((fn) => {\n try {\n fn()\n } catch (err) {\n reportError(err, { context: 'history-observer-listener' })\n }\n })\n}\n\nconst RESTORE_KEY = '__markup_history_restore__'\n\ntype Patch = { listeners: Set<Listener>; restore: () => void }\n\nfunction install(): Patch {\n const push = history.pushState as typeof history.pushState & {\n [PATCHED_MARKER]?: number\n [LISTENERS_KEY]?: Set<Listener>\n [RESTORE_KEY]?: () => void\n }\n\n // Reusing the set from the wrapper is what survives an HMR re-import.\n if (push[PATCHED_MARKER]) {\n return { listeners: push[LISTENERS_KEY]!, restore: push[RESTORE_KEY]! }\n }\n\n const listeners = new Set<Listener>()\n\n const origPush = history.pushState\n const origReplace = history.replaceState\n\n function wrappedPush(this: History, ...args: Parameters<typeof History.prototype.pushState>) {\n origPush.apply(this, args)\n dispatch(listeners)\n }\n function wrappedReplace(\n this: History,\n ...args: Parameters<typeof History.prototype.replaceState>\n ) {\n origReplace.apply(this, args)\n dispatch(listeners)\n }\n\n const onPopState = () => dispatch(listeners)\n\n const restore = () => {\n // If another script patched on top of us, restoring our captured\n // originals would silently delete their hook — worse than leaving ours.\n if (history.pushState === wrappedPush) history.pushState = origPush\n if (history.replaceState === wrappedReplace) history.replaceState = origReplace\n window.removeEventListener('popstate', onPopState)\n listeners.clear()\n }\n\n Object.defineProperty(wrappedPush, PATCHED_MARKER, { value: 1 })\n Object.defineProperty(wrappedPush, LISTENERS_KEY, { value: listeners })\n Object.defineProperty(wrappedPush, RESTORE_KEY, { value: restore })\n Object.defineProperty(wrappedReplace, PATCHED_MARKER, { value: 1 })\n\n history.pushState = wrappedPush\n history.replaceState = wrappedReplace\n\n window.addEventListener('popstate', onPopState)\n\n return { listeners, restore }\n}\n\n// Null again after an HMR re-import, but `install()` short-circuits and\n// returns the same Set stored on the tagged wrapper.\nlet _patch: Patch | null = null\n\n/**\n * Wrappers install on the first subscribe and unwind when the last subscriber\n * leaves, so `destroy()` hands `window.history` back as it was found rather\n * than leaving the host page permanently patched.\n */\nexport function subscribeToRouteChanges(listener: Listener): () => void {\n if (!_patch) {\n _patch = install()\n }\n const patch = _patch\n patch.listeners.add(listener)\n\n let unsubscribed = false\n return () => {\n // `destroy()` may run twice, and the second must not tear down a patch a\n // later `init()` is relying on.\n if (unsubscribed) return\n unsubscribed = true\n patch.listeners.delete(listener)\n if (patch.listeners.size === 0) {\n patch.restore()\n if (_patch === patch) _patch = null\n }\n }\n}\n","const SAFE_PROTOCOLS = new Set(['http:', 'https:'])\n\n/**\n * Resolve `value` against `base`, returning it only if the result is\n * `http(s)`. Thread URLs come from the `/widget/threads` API, so a\n * `javascript:` value would otherwise execute on navigation.\n *\n * Relative values are fine — they inherit the base's scheme. Parses\n * rather than string-matches: the URL parser strips control characters\n * and lowercases the scheme, so `\"\\tjava\\nscript:…\"` still resolves to\n * `javascript:`.\n */\nexport function resolveSafeUrl(value: string, base: string): URL | null {\n let parsed: URL\n try {\n parsed = new URL(value, base)\n } catch {\n return null\n }\n return SAFE_PROTOCOLS.has(parsed.protocol) ? parsed : null\n}\n","/**\n * Identity lives in the host page's own localStorage, not a cross-origin\n * iframe: modern browsers partition third-party storage per top-level site, so\n * a shared bucket was never actually shared. Sign-in is therefore per host.\n *\n * The runtime state is a discriminated `IdentityState` union; the on-disk\n * shape is a flat record loose enough to accept legacy data from prior\n * widget versions. Translation happens in `loadIdentity` / `saveIdentity`.\n */\n\nimport { resolveSafeUrl } from './safe-url'\n\n/** Anonymous identity, bound to a server-issued JWT for the deployment. */\nexport interface AnonIdentity {\n clientId: string\n /**\n * Binds this `clientId` to the deployment, so ownership checks verify it\n * server-side rather than trusting the request body. Tampering with\n * `clientId` in localStorage invalidates the signature.\n */\n anonToken: string\n name?: string\n email?: string\n}\n\n/** Verified identity, bound to a popup-signed user JWT. */\nexport interface VerifiedIdentity {\n /**\n * Chosen at sign-in from the cookie probe:\n * - `'cookies'`: tokens live in HttpOnly Partitioned cookies and JS never\n * sees them, so `token`/`refreshToken` below are undefined.\n * - `'localStorage'`: tokens are persisted here. `token`/`tokenExpiresAt`\n * are always set; `refreshToken`/`refreshTokenExpiresAt` when the\n * deployment supports refresh and unset on legacy deployments.\n */\n storage: 'cookies' | 'localStorage'\n /** Always `markup_user_<sub>` for the JWT's subject. */\n clientId: string\n /** Undefined under `'cookies'` storage — the cookie carries it instead. */\n token?: string\n /** Epoch milliseconds when the access JWT stops being valid. */\n tokenExpiresAt: number\n /** Undefined under `'cookies'` storage and on legacy deployments. */\n refreshToken?: string\n /** Epoch milliseconds when the refresh token stops being valid. */\n refreshTokenExpiresAt?: number\n name: string\n email?: string\n /** Validated as http(s) on the way in; absent falls back to initials. */\n image?: string\n}\n\n/**\n * Runtime state machine for the widget identity:\n *\n * - `unresolved`: first-load anon mint is pending.\n * - `anon`: anon mint succeeded; `clientId` and `anonToken` are valid.\n * - `verified`: popup sign-in succeeded; `token` is the active Bearer.\n * - `recovering`: a verified session just 401'd. The anon mint is\n * pending again. `preserved` carries the user's display fields so\n * the next mint can roundtrip name/email without re-prompting.\n *\n * `unresolved` and `recovering` look the same to the UI today (both\n * surface as `connecting` on the author prompt) but they're distinct in\n * the type system so a future \"Reconnecting as Alice…\" UX has a slot\n * for it.\n */\nexport type IdentityState =\n | { kind: 'unresolved' }\n | { kind: 'anon'; identity: AnonIdentity }\n | { kind: 'verified'; identity: VerifiedIdentity }\n | { kind: 'recovering'; preserved: { name?: string; email?: string } }\n\n/**\n * Loose because legacy records are accepted: earlier versions wrote a flat\n * record, and a recovering session persisted as `{clientId, name, email}`.\n */\ninterface StoredShape {\n clientId?: string\n name?: string\n email?: string\n image?: string\n isVerified?: boolean\n // Absent on older records, which are treated as 'localStorage'.\n storage?: 'cookies' | 'localStorage'\n token?: string\n tokenExpiresAt?: number\n refreshToken?: string\n refreshTokenExpiresAt?: number\n anonToken?: string\n}\n\nconst KEY = 'markup.identity'\n\nfunction readStored(): StoredShape | null {\n try {\n const raw = localStorage.getItem(KEY)\n return raw ? (JSON.parse(raw) as StoredShape) : null\n } catch {\n return null\n }\n}\n\n/**\n * Re-checked on read even though it was checked on write: localStorage belongs\n * to the host page, any script there can rewrite the record, and this ends up\n * in an `<img src>`. A tampered entry then costs an avatar and nothing more.\n */\nfunction storedImage(stored: StoredShape): string | undefined {\n if (typeof stored.image !== 'string') return undefined\n return resolveSafeUrl(stored.image, location.href)?.href ?? undefined\n}\n\nfunction writeStored(stored: StoredShape | null): void {\n try {\n if (stored == null) {\n localStorage.removeItem(KEY)\n return\n }\n localStorage.setItem(KEY, JSON.stringify(stored))\n } catch {\n /* storage disabled (private mode quota) — identity stays in-memory only */\n }\n}\n\n/**\n * `preserved` comes back separately so a later anon mint can carry display\n * fields forward even when the record held no usable identity.\n */\nexport function loadIdentity(): {\n state: IdentityState\n preserved: { name?: string; email?: string }\n} {\n const stored = readStored()\n const preserved = { name: stored?.name, email: stored?.email }\n if (!stored) return { state: { kind: 'unresolved' }, preserved }\n\n // Legacy records have no `storage` field; cookie mode always writes one.\n const storage = stored.storage ?? 'localStorage'\n\n if (\n storage === 'cookies' &&\n stored.isVerified &&\n typeof stored.clientId === 'string' &&\n typeof stored.tokenExpiresAt === 'number' &&\n typeof stored.refreshTokenExpiresAt === 'number' &&\n typeof stored.name === 'string'\n ) {\n // The record holds only expiries and display fields here. While the\n // refresh token has time left, stay verified — the scheduler swaps in a\n // fresh access token even if the access cookie already expired.\n if (stored.refreshTokenExpiresAt > Date.now()) {\n return {\n state: {\n kind: 'verified',\n identity: {\n storage: 'cookies',\n clientId: stored.clientId,\n tokenExpiresAt: stored.tokenExpiresAt,\n refreshTokenExpiresAt: stored.refreshTokenExpiresAt,\n name: stored.name,\n email: stored.email,\n image: storedImage(stored),\n },\n },\n preserved,\n }\n }\n }\n\n if (\n storage === 'localStorage' &&\n stored.isVerified &&\n typeof stored.clientId === 'string' &&\n typeof stored.token === 'string' &&\n typeof stored.tokenExpiresAt === 'number' &&\n typeof stored.name === 'string'\n ) {\n // A short-TTL access token may be expired by the time the tab\n // reopens; if a refresh token is still valid, surface the verified\n // state anyway and let the refresh scheduler swap in a fresh\n // access token before the next write. This keeps \"signed in\"\n // sticky across tab reloads.\n const accessLive = stored.tokenExpiresAt > Date.now()\n const refreshLive =\n typeof stored.refreshToken === 'string' &&\n typeof stored.refreshTokenExpiresAt === 'number' &&\n stored.refreshTokenExpiresAt > Date.now()\n\n if (accessLive || refreshLive) {\n return {\n state: {\n kind: 'verified',\n identity: {\n storage: 'localStorage',\n clientId: stored.clientId,\n token: stored.token,\n tokenExpiresAt: stored.tokenExpiresAt,\n ...(refreshLive\n ? {\n refreshToken: stored.refreshToken,\n refreshTokenExpiresAt: stored.refreshTokenExpiresAt,\n }\n : {}),\n name: stored.name,\n email: stored.email,\n image: storedImage(stored),\n },\n },\n preserved,\n }\n }\n }\n\n if (typeof stored.clientId === 'string' && typeof stored.anonToken === 'string') {\n return {\n state: {\n kind: 'anon',\n identity: {\n clientId: stored.clientId,\n anonToken: stored.anonToken,\n name: stored.name,\n email: stored.email,\n },\n },\n preserved,\n }\n }\n\n // Has display fields but no signed token. Caller mints to recover.\n return { state: { kind: 'unresolved' }, preserved }\n}\n\n/**\n * Persist the runtime state. The transient states (`unresolved`,\n * `recovering`) drop the signed-identity fields; `recovering` keeps\n * `preserved` so the next mint can carry name/email forward.\n */\nexport function saveIdentity(state: IdentityState): void {\n switch (state.kind) {\n case 'verified':\n writeStored({\n clientId: state.identity.clientId,\n storage: state.identity.storage,\n // In cookie storage the JWT lives in the HttpOnly cookie and\n // is intentionally NOT mirrored into localStorage — that's the\n // whole point. We persist only what JS needs: the expiries\n // (for the refresh scheduler) and the display fields.\n token: state.identity.storage === 'cookies' ? undefined : state.identity.token,\n tokenExpiresAt: state.identity.tokenExpiresAt,\n refreshToken:\n state.identity.storage === 'cookies' ? undefined : state.identity.refreshToken,\n refreshTokenExpiresAt: state.identity.refreshTokenExpiresAt,\n isVerified: true,\n name: state.identity.name,\n email: state.identity.email,\n image: state.identity.image,\n })\n return\n case 'anon':\n writeStored({\n clientId: state.identity.clientId,\n anonToken: state.identity.anonToken,\n name: state.identity.name,\n email: state.identity.email,\n })\n return\n case 'recovering':\n // No identity to persist, just the display fields. clientId is\n // intentionally omitted — the next anon mint replaces it anyway.\n writeStored({\n name: state.preserved.name,\n email: state.preserved.email,\n })\n return\n case 'unresolved':\n writeStored(null)\n return\n }\n}\n\n/**\n * Convenience: the active widget clientId, regardless of identity flavor.\n * Returns `undefined` for `unresolved` / `recovering`.\n */\nexport function clientIdOf(state: IdentityState): string | undefined {\n if (state.kind === 'anon') return state.identity.clientId\n if (state.kind === 'verified') return state.identity.clientId\n return undefined\n}\n\n/**\n * Convenience: the active display name, or null when none is set.\n * Verified identities always have a name; anon may not until the user\n * fills in the author prompt.\n */\nexport function displayNameOf(state: IdentityState): string | null {\n if (state.kind === 'anon') return state.identity.name ?? null\n if (state.kind === 'verified') return state.identity.name\n return null\n}\n\n/**\n * Convenience: read the author display fields for write paths. Returns\n * `null` when the identity has no usable display name (unresolved /\n * recovering, or an anon identity whose user hasn't filled in the\n * prompt yet) — callers should bail in that case since the server\n * requires a name on the post.\n */\nexport function authorFieldsOf(\n state: IdentityState,\n): { name: string; email: string | undefined } | null {\n if (state.kind === 'anon') {\n const name = state.identity.name\n if (!name) return null\n return { name, email: state.identity.email }\n }\n if (state.kind === 'verified') {\n return { name: state.identity.name, email: state.identity.email }\n }\n return null\n}\n","import { combinedSignal, WRITE_TIMEOUT_MS } from './api'\nimport { reportError } from './error-reporter'\n\n/** Shape of the identity the `/widget/auth` popup posts back. */\nexport interface PopupIdentity {\n id: string\n name: string\n email?: string\n /** Profile picture for the toolbar avatar; absent if none is set. */\n image?: string\n}\n\n/**\n * `mode` says where the tokens went. Under `'cookies'` they are in HttpOnly\n * Partitioned cookies and the fields here are null by design — only the\n * expiries flow through, so the widget can still schedule a silent refresh.\n * A popup that sends no `mode` at all is treated as `'localStorage'`.\n */\nexport type PopupMode = 'cookies' | 'localStorage'\n\nexport interface PopupResult {\n mode: PopupMode\n identity: PopupIdentity\n token: string | null\n /** Epoch milliseconds when the JWT stops being valid. */\n tokenExpiresAt: number | null\n refreshToken: string | null\n /** Epoch milliseconds when the refresh token stops being valid. */\n refreshTokenExpiresAt: number | null\n}\n\n/**\n * A popup rather than an iframe because it is first-party to the deployment\n * origin, so the better-auth session cookie is actually sent.\n *\n * The apiKey never appears in the popup URL. The host page exchanges it for a\n * single-use 60-second code, which is what's safe to put in a URL the browser\n * records in history and sends as Referer.\n */\n/* Message types the popup posts back. Mirrored server-side in\n * `convex/http.ts` (the popup HTML is generated there); the two bundles\n * share no package, so the constants are duplicated deliberately. */\nconst POPUP_MSG_RESULT = 'MARKUP_AUTH_RESULT'\nconst POPUP_MSG_RETRY = 'MARKUP_AUTH_RETRY'\nconst POPUP_MSG_EXPIRED = 'MARKUP_AUTH_EXPIRED'\n\n/**\n * Bounds the one shape that could spin: a popup repeatedly reporting a lapsed\n * code because of clock skew or a sweep racing the read.\n *\n * Retry clicks are deliberately NOT counted — those are human-paced, and\n * clicking Retry more than five times before finishing sign-in is ordinary,\n * not something that should strand the visitor.\n */\nconst MAX_AUTOMATIC_REMINTS = 5\n\nexport async function signInWithPopup(args: {\n apiUrl: string\n apiKey: string\n /** Makes the server Set-Cookie the tokens instead of posting them back. */\n useCookies: boolean\n}): Promise<PopupResult> {\n const { apiUrl, apiKey, useCookies } = args\n const sessionOrigin = new URL(apiUrl).origin\n\n // `cookies` is only sent once the probe confirmed the browser honours\n // them, so a degraded path can't accidentally land in cookie mode.\n const capabilities = useCookies ? 'refresh,cookies' : 'refresh'\n\n /**\n * Re-called whenever the popup reports a lapsed code, which is the normal\n * outcome when the visitor has to sign into the dashboard first — that\n * detour routinely outlasts the 60-second TTL.\n */\n async function buildPopupUrl(): Promise<string> {\n const exchangeRes = await fetch(`${apiUrl.replace(/\\/+$/, '')}/widget/popup-exchange`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', 'x-markup-api-key': apiKey },\n body: '{}',\n signal: combinedSignal(WRITE_TIMEOUT_MS),\n })\n if (!exchangeRes.ok) {\n throw new Error(`popup-exchange responded with ${exchangeRes.status}`)\n }\n const { code } = (await exchangeRes.json()) as { code: string }\n const url = new URL('/widget/auth', apiUrl)\n url.searchParams.set('code', code)\n url.searchParams.set('capabilities', capabilities)\n return url.toString()\n }\n\n let popupUrl: string\n try {\n popupUrl = await buildPopupUrl()\n } catch (err) {\n // Structural failures only: bad apiKey, server bug. User-cancel and\n // popup-blocked have their own paths below. TypeError is the pure\n // network case — routine and noisy.\n const name = (err as { name?: unknown } | null)?.name\n if (name !== 'TypeError') {\n reportError(err, { context: 'popup-exchange' })\n }\n return Promise.reject(err instanceof Error ? err : new Error('Failed to start popup exchange'))\n }\n\n const w = 420\n const h = 560\n const left = Math.max(0, window.screenX + (window.outerWidth - w) / 2)\n const top = Math.max(0, window.screenY + (window.outerHeight - h) / 2)\n\n const popup = window.open(\n popupUrl,\n 'markup-auth',\n `width=${w},height=${h},left=${left},top=${top}`,\n )\n if (!popup) {\n return Promise.reject(new Error('Popup blocked — allow popups for this site to sign in'))\n }\n\n // Without this, a popup that never posts back leaves the message listener\n // and close-watch interval running forever, and each retry stacks another\n // pair. Ten minutes rather than five because an unsigned-in visitor has a\n // whole OAuth round trip, password manager and 2FA prompt to get through.\n // Abandonment is caught far sooner by `closeWatch`.\n const TIMEOUT_MS = 10 * 60 * 1000\n\n // The popup posts tokens back in both modes. Cookie mode then re-installs\n // them from the host page's top-level context, because a Set-Cookie on the\n // popup response lands in the *popup's* partition, which the widget can't\n // read.\n const raw = await new Promise<PopupResult>((resolve, reject) => {\n let automaticRemints = 0\n /* Set while a re-mint fetch is in flight. The popup's own page posts\n * `EXPIRED` on load *and* on every Try-again click, so without this\n * a couple of quick clicks would race two navigations. */\n let reminting = false\n\n function cleanup() {\n window.removeEventListener('message', onMessage)\n clearInterval(closeWatch)\n clearTimeout(timeoutId)\n }\n\n /**\n * Hand the popup a fresh code and re-navigate it. Navigating a\n * window we opened is permitted cross-origin, which is what lets\n * the widget — the only party holding the apiKey — drive recovery\n * without the popup ever seeing that key.\n *\n * An arrow const rather than a `function` declaration: hoisted\n * declarations lose the `if (!popup)` narrowing above, so the\n * property accesses below would need non-null assertions.\n */\n const renavigate = (automatic: boolean) => {\n if (reminting) return\n if (automatic) {\n if (automaticRemints >= MAX_AUTOMATIC_REMINTS) {\n cleanup()\n reject(new Error('Sign-in could not be restarted — close the window and try again'))\n return\n }\n automaticRemints += 1\n }\n reminting = true\n buildPopupUrl()\n .then((freshUrl) => {\n if (popup.closed) return\n popup.location.href = freshUrl\n })\n .catch((err) => {\n cleanup()\n reportError(err, { context: 'popup-exchange-remint' })\n reject(err instanceof Error ? err : new Error('Failed to restart sign-in'))\n })\n .finally(() => {\n reminting = false\n })\n }\n\n function onMessage(e: MessageEvent) {\n if (e.origin !== sessionOrigin) return\n // Origin alone would accept a postMessage from any other window on the\n // deployment origin, such as a stale dashboard tab.\n if (e.source !== popup) return\n const d = e.data as {\n type?: string\n mode?: PopupMode\n identity?: PopupIdentity\n token?: string | null\n tokenExpiresAt?: number | null\n refreshToken?: string | null\n refreshTokenExpiresAt?: number | null\n }\n // Both recover the same way; only the automatic one is budgeted.\n if (d?.type === POPUP_MSG_RETRY) {\n renavigate(false)\n return\n }\n if (d?.type === POPUP_MSG_EXPIRED) {\n renavigate(true)\n return\n }\n if (d?.type !== POPUP_MSG_RESULT) return\n cleanup()\n if (d.identity?.id && d.identity?.name) {\n // A popup that sends no `mode` is a legacy one.\n const mode: PopupMode = d.mode === 'cookies' ? 'cookies' : 'localStorage'\n resolve({\n mode,\n identity: d.identity,\n token: typeof d.token === 'string' ? d.token : null,\n tokenExpiresAt: typeof d.tokenExpiresAt === 'number' ? d.tokenExpiresAt : null,\n refreshToken: typeof d.refreshToken === 'string' ? d.refreshToken : null,\n refreshTokenExpiresAt:\n typeof d.refreshTokenExpiresAt === 'number' ? d.refreshTokenExpiresAt : null,\n })\n } else {\n reject(new Error('Sign-in cancelled'))\n }\n }\n const closeWatch = window.setInterval(() => {\n if (popup.closed) {\n cleanup()\n reject(new Error('Sign-in cancelled'))\n }\n }, 500)\n const timeoutId = window.setTimeout(() => {\n cleanup()\n reject(new Error('Sign-in timed out'))\n }, TIMEOUT_MS)\n window.addEventListener('message', onMessage)\n })\n\n // Runs from the host page's top-level context so Set-Cookie lands in the\n // partition the widget reads. The tokens are cleared from the result\n // afterwards, so they never leave this function.\n if (raw.mode === 'cookies' && raw.token && raw.refreshToken) {\n const installRes = await fetch(`${apiUrl.replace(/\\/+$/, '')}/widget/auth/install-cookies`, {\n method: 'POST',\n credentials: 'include',\n headers: { 'content-type': 'application/json', 'x-markup-api-key': apiKey },\n body: JSON.stringify({\n accessToken: raw.token,\n refreshToken: raw.refreshToken,\n }),\n signal: combinedSignal(WRITE_TIMEOUT_MS),\n })\n if (!installRes.ok) {\n // The popup already succeeded, so this is the partition re-install\n // failing specifically — a real bug, not a user-facing outcome.\n const err = new Error(`Failed to install widget cookies (${installRes.status})`)\n reportError(err, { context: 'install-cookies' })\n throw err\n }\n return { ...raw, token: null, refreshToken: null }\n }\n\n return raw\n}\n","export function resolveUrl(url, baseUrl) {\n // url is absolute already\n if (url.match(/^[a-z]+:\\/\\//i)) {\n return url;\n }\n // url is absolute already, without protocol\n if (url.match(/^\\/\\//)) {\n return window.location.protocol + url;\n }\n // dataURI, mailto:, tel:, etc.\n if (url.match(/^[a-z]+:/i)) {\n return url;\n }\n const doc = document.implementation.createHTMLDocument();\n const base = doc.createElement('base');\n const a = doc.createElement('a');\n doc.head.appendChild(base);\n doc.body.appendChild(a);\n if (baseUrl) {\n base.href = baseUrl;\n }\n a.href = url;\n return a.href;\n}\nexport const uuid = (() => {\n // generate uuid for className of pseudo elements.\n // We should not use GUIDs, otherwise pseudo elements sometimes cannot be captured.\n let counter = 0;\n // ref: http://stackoverflow.com/a/6248722/2519373\n const random = () => \n // eslint-disable-next-line no-bitwise\n `0000${((Math.random() * 36 ** 4) << 0).toString(36)}`.slice(-4);\n return () => {\n counter += 1;\n return `u${random()}${counter}`;\n };\n})();\nexport function delay(ms) {\n return (args) => new Promise((resolve) => {\n setTimeout(() => resolve(args), ms);\n });\n}\nexport function toArray(arrayLike) {\n const arr = [];\n for (let i = 0, l = arrayLike.length; i < l; i++) {\n arr.push(arrayLike[i]);\n }\n return arr;\n}\nlet styleProps = null;\nexport function getStyleProperties(options = {}) {\n if (styleProps) {\n return styleProps;\n }\n if (options.includeStyleProperties) {\n styleProps = options.includeStyleProperties;\n return styleProps;\n }\n styleProps = toArray(window.getComputedStyle(document.documentElement));\n return styleProps;\n}\nfunction px(node, styleProperty) {\n const win = node.ownerDocument.defaultView || window;\n const val = win.getComputedStyle(node).getPropertyValue(styleProperty);\n return val ? parseFloat(val.replace('px', '')) : 0;\n}\nfunction getNodeWidth(node) {\n const leftBorder = px(node, 'border-left-width');\n const rightBorder = px(node, 'border-right-width');\n return node.clientWidth + leftBorder + rightBorder;\n}\nfunction getNodeHeight(node) {\n const topBorder = px(node, 'border-top-width');\n const bottomBorder = px(node, 'border-bottom-width');\n return node.clientHeight + topBorder + bottomBorder;\n}\nexport function getImageSize(targetNode, options = {}) {\n const width = options.width || getNodeWidth(targetNode);\n const height = options.height || getNodeHeight(targetNode);\n return { width, height };\n}\nexport function getPixelRatio() {\n let ratio;\n let FINAL_PROCESS;\n try {\n FINAL_PROCESS = process;\n }\n catch (e) {\n // pass\n }\n const val = FINAL_PROCESS && FINAL_PROCESS.env\n ? FINAL_PROCESS.env.devicePixelRatio\n : null;\n if (val) {\n ratio = parseInt(val, 10);\n if (Number.isNaN(ratio)) {\n ratio = 1;\n }\n }\n return ratio || window.devicePixelRatio || 1;\n}\n// @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas#maximum_canvas_size\nconst canvasDimensionLimit = 16384;\nexport function checkCanvasDimensions(canvas) {\n if (canvas.width > canvasDimensionLimit ||\n canvas.height > canvasDimensionLimit) {\n if (canvas.width > canvasDimensionLimit &&\n canvas.height > canvasDimensionLimit) {\n if (canvas.width > canvas.height) {\n canvas.height *= canvasDimensionLimit / canvas.width;\n canvas.width = canvasDimensionLimit;\n }\n else {\n canvas.width *= canvasDimensionLimit / canvas.height;\n canvas.height = canvasDimensionLimit;\n }\n }\n else if (canvas.width > canvasDimensionLimit) {\n canvas.height *= canvasDimensionLimit / canvas.width;\n canvas.width = canvasDimensionLimit;\n }\n else {\n canvas.width *= canvasDimensionLimit / canvas.height;\n canvas.height = canvasDimensionLimit;\n }\n }\n}\nexport function canvasToBlob(canvas, options = {}) {\n if (canvas.toBlob) {\n return new Promise((resolve) => {\n canvas.toBlob(resolve, options.type ? options.type : 'image/png', options.quality ? options.quality : 1);\n });\n }\n return new Promise((resolve) => {\n const binaryString = window.atob(canvas\n .toDataURL(options.type ? options.type : undefined, options.quality ? options.quality : undefined)\n .split(',')[1]);\n const len = binaryString.length;\n const binaryArray = new Uint8Array(len);\n for (let i = 0; i < len; i += 1) {\n binaryArray[i] = binaryString.charCodeAt(i);\n }\n resolve(new Blob([binaryArray], {\n type: options.type ? options.type : 'image/png',\n }));\n });\n}\nexport function createImage(url) {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n img.decode().then(() => {\n requestAnimationFrame(() => resolve(img));\n });\n };\n img.onerror = reject;\n img.crossOrigin = 'anonymous';\n img.decoding = 'async';\n img.src = url;\n });\n}\nexport async function svgToDataURL(svg) {\n return Promise.resolve()\n .then(() => new XMLSerializer().serializeToString(svg))\n .then(encodeURIComponent)\n .then((html) => `data:image/svg+xml;charset=utf-8,${html}`);\n}\nexport async function nodeToDataURL(node, width, height) {\n const xmlns = 'http://www.w3.org/2000/svg';\n const svg = document.createElementNS(xmlns, 'svg');\n const foreignObject = document.createElementNS(xmlns, 'foreignObject');\n svg.setAttribute('width', `${width}`);\n svg.setAttribute('height', `${height}`);\n svg.setAttribute('viewBox', `0 0 ${width} ${height}`);\n foreignObject.setAttribute('width', '100%');\n foreignObject.setAttribute('height', '100%');\n foreignObject.setAttribute('x', '0');\n foreignObject.setAttribute('y', '0');\n foreignObject.setAttribute('externalResourcesRequired', 'true');\n svg.appendChild(foreignObject);\n foreignObject.appendChild(node);\n return svgToDataURL(svg);\n}\nexport const isInstanceOfElement = (node, instance) => {\n if (node instanceof instance)\n return true;\n const nodePrototype = Object.getPrototypeOf(node);\n if (nodePrototype === null)\n return false;\n return (nodePrototype.constructor.name === instance.name ||\n isInstanceOfElement(nodePrototype, instance));\n};\n//# sourceMappingURL=util.js.map","import { uuid, getStyleProperties } from './util';\nfunction formatCSSText(style) {\n const content = style.getPropertyValue('content');\n return `${style.cssText} content: '${content.replace(/'|\"/g, '')}';`;\n}\nfunction formatCSSProperties(style, options) {\n return getStyleProperties(options)\n .map((name) => {\n const value = style.getPropertyValue(name);\n const priority = style.getPropertyPriority(name);\n return `${name}: ${value}${priority ? ' !important' : ''};`;\n })\n .join(' ');\n}\nfunction getPseudoElementStyle(className, pseudo, style, options) {\n const selector = `.${className}:${pseudo}`;\n const cssText = style.cssText\n ? formatCSSText(style)\n : formatCSSProperties(style, options);\n return document.createTextNode(`${selector}{${cssText}}`);\n}\nfunction clonePseudoElement(nativeNode, clonedNode, pseudo, options) {\n const style = window.getComputedStyle(nativeNode, pseudo);\n const content = style.getPropertyValue('content');\n if (content === '' || content === 'none') {\n return;\n }\n const className = uuid();\n try {\n clonedNode.className = `${clonedNode.className} ${className}`;\n }\n catch (err) {\n return;\n }\n const styleElement = document.createElement('style');\n styleElement.appendChild(getPseudoElementStyle(className, pseudo, style, options));\n clonedNode.appendChild(styleElement);\n}\nexport function clonePseudoElements(nativeNode, clonedNode, options) {\n clonePseudoElement(nativeNode, clonedNode, ':before', options);\n clonePseudoElement(nativeNode, clonedNode, ':after', options);\n}\n//# sourceMappingURL=clone-pseudos.js.map","const WOFF = 'application/font-woff';\nconst JPEG = 'image/jpeg';\nconst mimes = {\n woff: WOFF,\n woff2: WOFF,\n ttf: 'application/font-truetype',\n eot: 'application/vnd.ms-fontobject',\n png: 'image/png',\n jpg: JPEG,\n jpeg: JPEG,\n gif: 'image/gif',\n tiff: 'image/tiff',\n svg: 'image/svg+xml',\n webp: 'image/webp',\n};\nfunction getExtension(url) {\n const match = /\\.([^./]*?)$/g.exec(url);\n return match ? match[1] : '';\n}\nexport function getMimeType(url) {\n const extension = getExtension(url).toLowerCase();\n return mimes[extension] || '';\n}\n//# sourceMappingURL=mimes.js.map","function getContentFromDataUrl(dataURL) {\n return dataURL.split(/,/)[1];\n}\nexport function isDataUrl(url) {\n return url.search(/^(data:)/) !== -1;\n}\nexport function makeDataUrl(content, mimeType) {\n return `data:${mimeType};base64,${content}`;\n}\nexport async function fetchAsDataURL(url, init, process) {\n const res = await fetch(url, init);\n if (res.status === 404) {\n throw new Error(`Resource \"${res.url}\" not found`);\n }\n const blob = await res.blob();\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = () => {\n try {\n resolve(process({ res, result: reader.result }));\n }\n catch (error) {\n reject(error);\n }\n };\n reader.readAsDataURL(blob);\n });\n}\nconst cache = {};\nfunction getCacheKey(url, contentType, includeQueryParams) {\n let key = url.replace(/\\?.*/, '');\n if (includeQueryParams) {\n key = url;\n }\n // font resource\n if (/ttf|otf|eot|woff2?/i.test(key)) {\n key = key.replace(/.*\\//, '');\n }\n return contentType ? `[${contentType}]${key}` : key;\n}\nexport async function resourceToDataURL(resourceUrl, contentType, options) {\n const cacheKey = getCacheKey(resourceUrl, contentType, options.includeQueryParams);\n if (cache[cacheKey] != null) {\n return cache[cacheKey];\n }\n // ref: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache\n if (options.cacheBust) {\n // eslint-disable-next-line no-param-reassign\n resourceUrl += (/\\?/.test(resourceUrl) ? '&' : '?') + new Date().getTime();\n }\n let dataURL;\n try {\n const content = await fetchAsDataURL(resourceUrl, options.fetchRequestInit, ({ res, result }) => {\n if (!contentType) {\n // eslint-disable-next-line no-param-reassign\n contentType = res.headers.get('Content-Type') || '';\n }\n return getContentFromDataUrl(result);\n });\n dataURL = makeDataUrl(content, contentType);\n }\n catch (error) {\n dataURL = options.imagePlaceholder || '';\n let msg = `Failed to fetch resource: ${resourceUrl}`;\n if (error) {\n msg = typeof error === 'string' ? error : error.message;\n }\n if (msg) {\n console.warn(msg);\n }\n }\n cache[cacheKey] = dataURL;\n return dataURL;\n}\n//# sourceMappingURL=dataurl.js.map","import { clonePseudoElements } from './clone-pseudos';\nimport { createImage, toArray, isInstanceOfElement, getStyleProperties, } from './util';\nimport { getMimeType } from './mimes';\nimport { resourceToDataURL } from './dataurl';\nasync function cloneCanvasElement(canvas) {\n const dataURL = canvas.toDataURL();\n if (dataURL === 'data:,') {\n return canvas.cloneNode(false);\n }\n return createImage(dataURL);\n}\nasync function cloneVideoElement(video, options) {\n if (video.currentSrc) {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n canvas.width = video.clientWidth;\n canvas.height = video.clientHeight;\n ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(video, 0, 0, canvas.width, canvas.height);\n const dataURL = canvas.toDataURL();\n return createImage(dataURL);\n }\n const poster = video.poster;\n const contentType = getMimeType(poster);\n const dataURL = await resourceToDataURL(poster, contentType, options);\n return createImage(dataURL);\n}\nasync function cloneIFrameElement(iframe, options) {\n var _a;\n try {\n if ((_a = iframe === null || iframe === void 0 ? void 0 : iframe.contentDocument) === null || _a === void 0 ? void 0 : _a.body) {\n return (await cloneNode(iframe.contentDocument.body, options, true));\n }\n }\n catch (_b) {\n // Failed to clone iframe\n }\n return iframe.cloneNode(false);\n}\nasync function cloneSingleNode(node, options) {\n if (isInstanceOfElement(node, HTMLCanvasElement)) {\n return cloneCanvasElement(node);\n }\n if (isInstanceOfElement(node, HTMLVideoElement)) {\n return cloneVideoElement(node, options);\n }\n if (isInstanceOfElement(node, HTMLIFrameElement)) {\n return cloneIFrameElement(node, options);\n }\n return node.cloneNode(isSVGElement(node));\n}\nconst isSlotElement = (node) => node.tagName != null && node.tagName.toUpperCase() === 'SLOT';\nconst isSVGElement = (node) => node.tagName != null && node.tagName.toUpperCase() === 'SVG';\nasync function cloneChildren(nativeNode, clonedNode, options) {\n var _a, _b;\n if (isSVGElement(clonedNode)) {\n return clonedNode;\n }\n let children = [];\n if (isSlotElement(nativeNode) && nativeNode.assignedNodes) {\n children = toArray(nativeNode.assignedNodes());\n }\n else if (isInstanceOfElement(nativeNode, HTMLIFrameElement) &&\n ((_a = nativeNode.contentDocument) === null || _a === void 0 ? void 0 : _a.body)) {\n children = toArray(nativeNode.contentDocument.body.childNodes);\n }\n else {\n children = toArray(((_b = nativeNode.shadowRoot) !== null && _b !== void 0 ? _b : nativeNode).childNodes);\n }\n if (children.length === 0 ||\n isInstanceOfElement(nativeNode, HTMLVideoElement)) {\n return clonedNode;\n }\n await children.reduce((deferred, child) => deferred\n .then(() => cloneNode(child, options))\n .then((clonedChild) => {\n if (clonedChild) {\n clonedNode.appendChild(clonedChild);\n }\n }), Promise.resolve());\n return clonedNode;\n}\nfunction cloneCSSStyle(nativeNode, clonedNode, options) {\n const targetStyle = clonedNode.style;\n if (!targetStyle) {\n return;\n }\n const sourceStyle = window.getComputedStyle(nativeNode);\n if (sourceStyle.cssText) {\n targetStyle.cssText = sourceStyle.cssText;\n targetStyle.transformOrigin = sourceStyle.transformOrigin;\n }\n else {\n getStyleProperties(options).forEach((name) => {\n let value = sourceStyle.getPropertyValue(name);\n if (name === 'font-size' && value.endsWith('px')) {\n const reducedFont = Math.floor(parseFloat(value.substring(0, value.length - 2))) - 0.1;\n value = `${reducedFont}px`;\n }\n if (isInstanceOfElement(nativeNode, HTMLIFrameElement) &&\n name === 'display' &&\n value === 'inline') {\n value = 'block';\n }\n if (name === 'd' && clonedNode.getAttribute('d')) {\n value = `path(${clonedNode.getAttribute('d')})`;\n }\n targetStyle.setProperty(name, value, sourceStyle.getPropertyPriority(name));\n });\n }\n}\nfunction cloneInputValue(nativeNode, clonedNode) {\n if (isInstanceOfElement(nativeNode, HTMLTextAreaElement)) {\n clonedNode.innerHTML = nativeNode.value;\n }\n if (isInstanceOfElement(nativeNode, HTMLInputElement)) {\n clonedNode.setAttribute('value', nativeNode.value);\n }\n}\nfunction cloneSelectValue(nativeNode, clonedNode) {\n if (isInstanceOfElement(nativeNode, HTMLSelectElement)) {\n const clonedSelect = clonedNode;\n const selectedOption = Array.from(clonedSelect.children).find((child) => nativeNode.value === child.getAttribute('value'));\n if (selectedOption) {\n selectedOption.setAttribute('selected', '');\n }\n }\n}\nfunction decorate(nativeNode, clonedNode, options) {\n if (isInstanceOfElement(clonedNode, Element)) {\n cloneCSSStyle(nativeNode, clonedNode, options);\n clonePseudoElements(nativeNode, clonedNode, options);\n cloneInputValue(nativeNode, clonedNode);\n cloneSelectValue(nativeNode, clonedNode);\n }\n return clonedNode;\n}\nasync function ensureSVGSymbols(clone, options) {\n const uses = clone.querySelectorAll ? clone.querySelectorAll('use') : [];\n if (uses.length === 0) {\n return clone;\n }\n const processedDefs = {};\n for (let i = 0; i < uses.length; i++) {\n const use = uses[i];\n const id = use.getAttribute('xlink:href');\n if (id) {\n const exist = clone.querySelector(id);\n const definition = document.querySelector(id);\n if (!exist && definition && !processedDefs[id]) {\n // eslint-disable-next-line no-await-in-loop\n processedDefs[id] = (await cloneNode(definition, options, true));\n }\n }\n }\n const nodes = Object.values(processedDefs);\n if (nodes.length) {\n const ns = 'http://www.w3.org/1999/xhtml';\n const svg = document.createElementNS(ns, 'svg');\n svg.setAttribute('xmlns', ns);\n svg.style.position = 'absolute';\n svg.style.width = '0';\n svg.style.height = '0';\n svg.style.overflow = 'hidden';\n svg.style.display = 'none';\n const defs = document.createElementNS(ns, 'defs');\n svg.appendChild(defs);\n for (let i = 0; i < nodes.length; i++) {\n defs.appendChild(nodes[i]);\n }\n clone.appendChild(svg);\n }\n return clone;\n}\nexport async function cloneNode(node, options, isRoot) {\n if (!isRoot && options.filter && !options.filter(node)) {\n return null;\n }\n return Promise.resolve(node)\n .then((clonedNode) => cloneSingleNode(clonedNode, options))\n .then((clonedNode) => cloneChildren(node, clonedNode, options))\n .then((clonedNode) => decorate(node, clonedNode, options))\n .then((clonedNode) => ensureSVGSymbols(clonedNode, options));\n}\n//# sourceMappingURL=clone-node.js.map","import { resolveUrl } from './util';\nimport { getMimeType } from './mimes';\nimport { isDataUrl, makeDataUrl, resourceToDataURL } from './dataurl';\nconst URL_REGEX = /url\\((['\"]?)([^'\"]+?)\\1\\)/g;\nconst URL_WITH_FORMAT_REGEX = /url\\([^)]+\\)\\s*format\\(([\"']?)([^\"']+)\\1\\)/g;\nconst FONT_SRC_REGEX = /src:\\s*(?:url\\([^)]+\\)\\s*format\\([^)]+\\)[,;]\\s*)+/g;\nfunction toRegex(url) {\n // eslint-disable-next-line no-useless-escape\n const escaped = url.replace(/([.*+?^${}()|\\[\\]\\/\\\\])/g, '\\\\$1');\n return new RegExp(`(url\\\\(['\"]?)(${escaped})(['\"]?\\\\))`, 'g');\n}\nexport function parseURLs(cssText) {\n const urls = [];\n cssText.replace(URL_REGEX, (raw, quotation, url) => {\n urls.push(url);\n return raw;\n });\n return urls.filter((url) => !isDataUrl(url));\n}\nexport async function embed(cssText, resourceURL, baseURL, options, getContentFromUrl) {\n try {\n const resolvedURL = baseURL ? resolveUrl(resourceURL, baseURL) : resourceURL;\n const contentType = getMimeType(resourceURL);\n let dataURL;\n if (getContentFromUrl) {\n const content = await getContentFromUrl(resolvedURL);\n dataURL = makeDataUrl(content, contentType);\n }\n else {\n dataURL = await resourceToDataURL(resolvedURL, contentType, options);\n }\n return cssText.replace(toRegex(resourceURL), `$1${dataURL}$3`);\n }\n catch (error) {\n // pass\n }\n return cssText;\n}\nfunction filterPreferredFontFormat(str, { preferredFontFormat }) {\n return !preferredFontFormat\n ? str\n : str.replace(FONT_SRC_REGEX, (match) => {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const [src, , format] = URL_WITH_FORMAT_REGEX.exec(match) || [];\n if (!format) {\n return '';\n }\n if (format === preferredFontFormat) {\n return `src: ${src};`;\n }\n }\n });\n}\nexport function shouldEmbed(url) {\n return url.search(URL_REGEX) !== -1;\n}\nexport async function embedResources(cssText, baseUrl, options) {\n if (!shouldEmbed(cssText)) {\n return cssText;\n }\n const filteredCSSText = filterPreferredFontFormat(cssText, options);\n const urls = parseURLs(filteredCSSText);\n return urls.reduce((deferred, url) => deferred.then((css) => embed(css, url, baseUrl, options)), Promise.resolve(filteredCSSText));\n}\n//# sourceMappingURL=embed-resources.js.map","import { embedResources } from './embed-resources';\nimport { toArray, isInstanceOfElement } from './util';\nimport { isDataUrl, resourceToDataURL } from './dataurl';\nimport { getMimeType } from './mimes';\nasync function embedProp(propName, node, options) {\n var _a;\n const propValue = (_a = node.style) === null || _a === void 0 ? void 0 : _a.getPropertyValue(propName);\n if (propValue) {\n const cssString = await embedResources(propValue, null, options);\n node.style.setProperty(propName, cssString, node.style.getPropertyPriority(propName));\n return true;\n }\n return false;\n}\nasync function embedBackground(clonedNode, options) {\n ;\n (await embedProp('background', clonedNode, options)) ||\n (await embedProp('background-image', clonedNode, options));\n (await embedProp('mask', clonedNode, options)) ||\n (await embedProp('-webkit-mask', clonedNode, options)) ||\n (await embedProp('mask-image', clonedNode, options)) ||\n (await embedProp('-webkit-mask-image', clonedNode, options));\n}\nasync function embedImageNode(clonedNode, options) {\n const isImageElement = isInstanceOfElement(clonedNode, HTMLImageElement);\n if (!(isImageElement && !isDataUrl(clonedNode.src)) &&\n !(isInstanceOfElement(clonedNode, SVGImageElement) &&\n !isDataUrl(clonedNode.href.baseVal))) {\n return;\n }\n const url = isImageElement ? clonedNode.src : clonedNode.href.baseVal;\n const dataURL = await resourceToDataURL(url, getMimeType(url), options);\n await new Promise((resolve, reject) => {\n clonedNode.onload = resolve;\n clonedNode.onerror = options.onImageErrorHandler\n ? (...attributes) => {\n try {\n resolve(options.onImageErrorHandler(...attributes));\n }\n catch (error) {\n reject(error);\n }\n }\n : reject;\n const image = clonedNode;\n if (image.decode) {\n image.decode = resolve;\n }\n if (image.loading === 'lazy') {\n image.loading = 'eager';\n }\n if (isImageElement) {\n clonedNode.srcset = '';\n clonedNode.src = dataURL;\n }\n else {\n clonedNode.href.baseVal = dataURL;\n }\n });\n}\nasync function embedChildren(clonedNode, options) {\n const children = toArray(clonedNode.childNodes);\n const deferreds = children.map((child) => embedImages(child, options));\n await Promise.all(deferreds).then(() => clonedNode);\n}\nexport async function embedImages(clonedNode, options) {\n if (isInstanceOfElement(clonedNode, Element)) {\n await embedBackground(clonedNode, options);\n await embedImageNode(clonedNode, options);\n await embedChildren(clonedNode, options);\n }\n}\n//# sourceMappingURL=embed-images.js.map","export function applyStyle(node, options) {\n const { style } = node;\n if (options.backgroundColor) {\n style.backgroundColor = options.backgroundColor;\n }\n if (options.width) {\n style.width = `${options.width}px`;\n }\n if (options.height) {\n style.height = `${options.height}px`;\n }\n const manual = options.style;\n if (manual != null) {\n Object.keys(manual).forEach((key) => {\n style[key] = manual[key];\n });\n }\n return node;\n}\n//# sourceMappingURL=apply-style.js.map","import { toArray } from './util';\nimport { fetchAsDataURL } from './dataurl';\nimport { shouldEmbed, embedResources } from './embed-resources';\nconst cssFetchCache = {};\nasync function fetchCSS(url) {\n let cache = cssFetchCache[url];\n if (cache != null) {\n return cache;\n }\n const res = await fetch(url);\n const cssText = await res.text();\n cache = { url, cssText };\n cssFetchCache[url] = cache;\n return cache;\n}\nasync function embedFonts(data, options) {\n let cssText = data.cssText;\n const regexUrl = /url\\([\"']?([^\"')]+)[\"']?\\)/g;\n const fontLocs = cssText.match(/url\\([^)]+\\)/g) || [];\n const loadFonts = fontLocs.map(async (loc) => {\n let url = loc.replace(regexUrl, '$1');\n if (!url.startsWith('https://')) {\n url = new URL(url, data.url).href;\n }\n return fetchAsDataURL(url, options.fetchRequestInit, ({ result }) => {\n cssText = cssText.replace(loc, `url(${result})`);\n return [loc, result];\n });\n });\n return Promise.all(loadFonts).then(() => cssText);\n}\nfunction parseCSS(source) {\n if (source == null) {\n return [];\n }\n const result = [];\n const commentsRegex = /(\\/\\*[\\s\\S]*?\\*\\/)/gi;\n // strip out comments\n let cssText = source.replace(commentsRegex, '');\n // eslint-disable-next-line prefer-regex-literals\n const keyframesRegex = new RegExp('((@.*?keyframes [\\\\s\\\\S]*?){([\\\\s\\\\S]*?}\\\\s*?)})', 'gi');\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const matches = keyframesRegex.exec(cssText);\n if (matches === null) {\n break;\n }\n result.push(matches[0]);\n }\n cssText = cssText.replace(keyframesRegex, '');\n const importRegex = /@import[\\s\\S]*?url\\([^)]*\\)[\\s\\S]*?;/gi;\n // to match css & media queries together\n const combinedCSSRegex = '((\\\\s*?(?:\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)?\\\\s*?@media[\\\\s\\\\S]' +\n '*?){([\\\\s\\\\S]*?)}\\\\s*?})|(([\\\\s\\\\S]*?){([\\\\s\\\\S]*?)})';\n // unified regex\n const unifiedRegex = new RegExp(combinedCSSRegex, 'gi');\n // eslint-disable-next-line no-constant-condition\n while (true) {\n let matches = importRegex.exec(cssText);\n if (matches === null) {\n matches = unifiedRegex.exec(cssText);\n if (matches === null) {\n break;\n }\n else {\n importRegex.lastIndex = unifiedRegex.lastIndex;\n }\n }\n else {\n unifiedRegex.lastIndex = importRegex.lastIndex;\n }\n result.push(matches[0]);\n }\n return result;\n}\nasync function getCSSRules(styleSheets, options) {\n const ret = [];\n const deferreds = [];\n // First loop inlines imports\n styleSheets.forEach((sheet) => {\n if ('cssRules' in sheet) {\n try {\n toArray(sheet.cssRules || []).forEach((item, index) => {\n if (item.type === CSSRule.IMPORT_RULE) {\n let importIndex = index + 1;\n const url = item.href;\n const deferred = fetchCSS(url)\n .then((metadata) => embedFonts(metadata, options))\n .then((cssText) => parseCSS(cssText).forEach((rule) => {\n try {\n sheet.insertRule(rule, rule.startsWith('@import')\n ? (importIndex += 1)\n : sheet.cssRules.length);\n }\n catch (error) {\n console.error('Error inserting rule from remote css', {\n rule,\n error,\n });\n }\n }))\n .catch((e) => {\n console.error('Error loading remote css', e.toString());\n });\n deferreds.push(deferred);\n }\n });\n }\n catch (e) {\n const inline = styleSheets.find((a) => a.href == null) || document.styleSheets[0];\n if (sheet.href != null) {\n deferreds.push(fetchCSS(sheet.href)\n .then((metadata) => embedFonts(metadata, options))\n .then((cssText) => parseCSS(cssText).forEach((rule) => {\n inline.insertRule(rule, inline.cssRules.length);\n }))\n .catch((err) => {\n console.error('Error loading remote stylesheet', err);\n }));\n }\n console.error('Error inlining remote css file', e);\n }\n }\n });\n return Promise.all(deferreds).then(() => {\n // Second loop parses rules\n styleSheets.forEach((sheet) => {\n if ('cssRules' in sheet) {\n try {\n toArray(sheet.cssRules || []).forEach((item) => {\n ret.push(item);\n });\n }\n catch (e) {\n console.error(`Error while reading CSS rules from ${sheet.href}`, e);\n }\n }\n });\n return ret;\n });\n}\nfunction getWebFontRules(cssRules) {\n return cssRules\n .filter((rule) => rule.type === CSSRule.FONT_FACE_RULE)\n .filter((rule) => shouldEmbed(rule.style.getPropertyValue('src')));\n}\nasync function parseWebFontRules(node, options) {\n if (node.ownerDocument == null) {\n throw new Error('Provided element is not within a Document');\n }\n const styleSheets = toArray(node.ownerDocument.styleSheets);\n const cssRules = await getCSSRules(styleSheets, options);\n return getWebFontRules(cssRules);\n}\nfunction normalizeFontFamily(font) {\n return font.trim().replace(/[\"']/g, '');\n}\nfunction getUsedFonts(node) {\n const fonts = new Set();\n function traverse(node) {\n const fontFamily = node.style.fontFamily || getComputedStyle(node).fontFamily;\n fontFamily.split(',').forEach((font) => {\n fonts.add(normalizeFontFamily(font));\n });\n Array.from(node.children).forEach((child) => {\n if (child instanceof HTMLElement) {\n traverse(child);\n }\n });\n }\n traverse(node);\n return fonts;\n}\nexport async function getWebFontCSS(node, options) {\n const rules = await parseWebFontRules(node, options);\n const usedFonts = getUsedFonts(node);\n const cssTexts = await Promise.all(rules\n .filter((rule) => usedFonts.has(normalizeFontFamily(rule.style.fontFamily)))\n .map((rule) => {\n const baseUrl = rule.parentStyleSheet\n ? rule.parentStyleSheet.href\n : null;\n return embedResources(rule.cssText, baseUrl, options);\n }));\n return cssTexts.join('\\n');\n}\nexport async function embedWebFonts(clonedNode, options) {\n const cssText = options.fontEmbedCSS != null\n ? options.fontEmbedCSS\n : options.skipFonts\n ? null\n : await getWebFontCSS(clonedNode, options);\n if (cssText) {\n const styleNode = document.createElement('style');\n const sytleContent = document.createTextNode(cssText);\n styleNode.appendChild(sytleContent);\n if (clonedNode.firstChild) {\n clonedNode.insertBefore(styleNode, clonedNode.firstChild);\n }\n else {\n clonedNode.appendChild(styleNode);\n }\n }\n}\n//# sourceMappingURL=embed-webfonts.js.map","import { cloneNode } from './clone-node';\nimport { embedImages } from './embed-images';\nimport { applyStyle } from './apply-style';\nimport { embedWebFonts, getWebFontCSS } from './embed-webfonts';\nimport { getImageSize, getPixelRatio, createImage, canvasToBlob, nodeToDataURL, checkCanvasDimensions, } from './util';\nexport async function toSvg(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const clonedNode = (await cloneNode(node, options, true));\n await embedWebFonts(clonedNode, options);\n await embedImages(clonedNode, options);\n applyStyle(clonedNode, options);\n const datauri = await nodeToDataURL(clonedNode, width, height);\n return datauri;\n}\nexport async function toCanvas(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const svg = await toSvg(node, options);\n const img = await createImage(svg);\n const canvas = document.createElement('canvas');\n const context = canvas.getContext('2d');\n const ratio = options.pixelRatio || getPixelRatio();\n const canvasWidth = options.canvasWidth || width;\n const canvasHeight = options.canvasHeight || height;\n canvas.width = canvasWidth * ratio;\n canvas.height = canvasHeight * ratio;\n if (!options.skipAutoScale) {\n checkCanvasDimensions(canvas);\n }\n canvas.style.width = `${canvasWidth}`;\n canvas.style.height = `${canvasHeight}`;\n if (options.backgroundColor) {\n context.fillStyle = options.backgroundColor;\n context.fillRect(0, 0, canvas.width, canvas.height);\n }\n context.drawImage(img, 0, 0, canvas.width, canvas.height);\n return canvas;\n}\nexport async function toPixelData(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const canvas = await toCanvas(node, options);\n const ctx = canvas.getContext('2d');\n return ctx.getImageData(0, 0, width, height).data;\n}\nexport async function toPng(node, options = {}) {\n const canvas = await toCanvas(node, options);\n return canvas.toDataURL();\n}\nexport async function toJpeg(node, options = {}) {\n const canvas = await toCanvas(node, options);\n return canvas.toDataURL('image/jpeg', options.quality || 1);\n}\nexport async function toBlob(node, options = {}) {\n const canvas = await toCanvas(node, options);\n const blob = await canvasToBlob(canvas);\n return blob;\n}\nexport async function getFontEmbedCSS(node, options = {}) {\n return getWebFontCSS(node, options);\n}\n//# sourceMappingURL=index.js.map","import { toCanvas } from 'html-to-image'\n\nimport { reportError } from './error-reporter'\n\nconst MAX_SIZE = 2 * 1024 * 1024 // 2 MB\n\n/**\n * html-to-image falls back to `imagePlaceholder || ''` when inlining an image\n * fails, and an empty `src` fires `error` rather than `load` — rejecting the\n * whole capture over one CORS-blocked avatar. A real data URL keeps that path\n * on the happy road: the element loads blank and the rest still captures.\n */\nconst TRANSPARENT_PIXEL =\n 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'\n\n/**\n * Walked in order until one fits `MAX_SIZE`, which mirrors the server's\n * `MAX_SCREENSHOT_BYTES`.\n *\n * Quality drops first because the top of the JPEG range costs no legibility.\n * Below ~0.6 it mangles small text, so the raster shrinks instead — a 1x\n * screenshot of a dense page reads better than a 2x one encoded into mush.\n */\nconst ENCODE_LADDER: ReadonlyArray<{ quality: number; scale: number }> = [\n { quality: 0.85, scale: 1 },\n { quality: 0.6, scale: 1 },\n { quality: 0.6, scale: 0.75 },\n { quality: 0.6, scale: 0.5 },\n]\n\nexport interface ScrubConfig {\n strictScrub?: boolean\n redactSelector?: string\n}\n\nexport interface CaptureResult {\n blob: Blob\n redactedCount: number\n redactedSelectors: string[]\n}\n\nconst MASK_CSS =\n 'background:currentColor!important;color:transparent!important;text-shadow:none!important;-webkit-text-fill-color:transparent!important'\n\nconst SENSITIVE_SELECTOR =\n 'input[type=\"password\"],' +\n 'input[autocomplete~=\"cc-number\"],' +\n 'input[autocomplete~=\"cc-csc\"],' +\n 'input[autocomplete~=\"cc-exp\"],' +\n 'input[autocomplete~=\"cc-name\"],' +\n 'input[autocomplete~=\"cc-type\"],' +\n 'input[autocomplete~=\"current-password\"],' +\n 'input[autocomplete~=\"new-password\"],' +\n 'input[autocomplete~=\"one-time-code\"]'\n\nfunction isWithinSafe(el: Element): boolean {\n let node: Element | null = el.parentElement\n while (node) {\n if (node.hasAttribute('data-markup-safe')) return true\n node = node.parentElement\n }\n return false\n}\n\nfunction buildMaskList(cfg: ScrubConfig): Element[] {\n const seen = new Set<Element>()\n const list: Element[] = []\n\n function add(el: Element) {\n if (!seen.has(el)) {\n seen.add(el)\n list.push(el)\n }\n }\n\n // Always mask regardless of data-markup-safe\n for (const el of document.querySelectorAll('[data-markup-private],[data-markup-redact]')) {\n add(el)\n }\n\n // Auto-detect sensitive fields (exempted by data-markup-safe ancestor)\n for (const el of document.querySelectorAll(SENSITIVE_SELECTOR)) {\n if (!isWithinSafe(el)) add(el)\n }\n\n if (cfg.redactSelector) {\n try {\n for (const el of document.querySelectorAll(cfg.redactSelector)) {\n if (!isWithinSafe(el)) add(el)\n }\n } catch (err) {\n // A customer-configuration bug that would otherwise silently produce\n // un-redacted screenshots.\n reportError(err, { context: 'screenshot-redact-selector' })\n }\n }\n\n if (cfg.strictScrub) {\n for (const el of document.querySelectorAll('input,select,textarea')) {\n if (!isWithinSafe(el)) add(el)\n }\n }\n\n return list\n}\n\nfunction applyMask(el: Element): () => void {\n const prev = el.getAttribute('style')\n el.setAttribute('style', prev ? `${prev};${MASK_CSS}` : MASK_CSS)\n return () => {\n if (prev === null) {\n el.removeAttribute('style')\n } else {\n el.setAttribute('style', prev)\n }\n }\n}\n\nfunction selectorFor(el: Element): string {\n if (el.id) return `#${CSS.escape(el.id)}`\n const tag = el.tagName.toLowerCase()\n const type = el.getAttribute('type')\n const name = el.getAttribute('name')\n if (type && name) return `${tag}[type=\"${type}\"][name=\"${name}\"]`\n if (type) return `${tag}[type=\"${type}\"]`\n if (name) return `${tag}[name=\"${name}\"]`\n return tag\n}\n\n/**\n * Masking mutates the live DOM for the duration of the `toCanvas` call only,\n * then restores it.\n *\n * Every null path reports to Sentry, so a caller can treat null as \"failed\"\n * and say so rather than guessing.\n */\nexport async function captureScreenshot(\n excludeEl?: Element | null,\n pin?: { x: number; y: number },\n scrubConfig?: ScrubConfig,\n): Promise<CaptureResult | null> {\n try {\n const w = window.innerWidth\n const h = window.innerHeight\n const pixelRatio = Math.min(window.devicePixelRatio, 2)\n\n const maskList = scrubConfig ? buildMaskList(scrubConfig) : []\n const redactedSelectors = maskList.map(selectorFor)\n const restores = maskList.map(applyMask)\n\n let canvas!: HTMLCanvasElement\n try {\n canvas = await toCanvas(document.documentElement, {\n width: w,\n height: h,\n cacheBust: true,\n backgroundColor: '#ffffff',\n pixelRatio,\n filter(node: Node): boolean {\n if (excludeEl && (node === excludeEl || excludeEl.contains(node))) return false\n if (node instanceof Element && node.hasAttribute('data-markup-skip')) return false\n return true\n },\n imagePlaceholder: TRANSPARENT_PIXEL,\n // For what the placeholder can't rescue, such as an image that\n // fetched but won't decode. One hole beats no screenshot.\n onImageErrorHandler: () => {},\n style: {\n // Otherwise the scroll offset is baked into the capture.\n transform: `translateY(-${window.scrollY}px)`,\n transformOrigin: 'top left',\n },\n })\n } finally {\n for (const restore of restores) restore()\n }\n\n if (pin) {\n const ctx = canvas.getContext('2d')\n if (ctx) drawPin(ctx, pin.x, pin.y, pixelRatio)\n }\n\n const blob = await encodeWithinLimit(canvas)\n if (!blob) return null\n return { blob, redactedCount: redactedSelectors.length, redactedSelectors }\n } catch (err) {\n // Broken stylesheets, or a SecurityError from a tainted canvas. The user\n // gets \"Screenshot unavailable\"; Sentry gets enough to tell a bug in our\n // codepath from host-page state we can't control.\n reportError(err, { context: 'screenshot-capture' })\n return null\n }\n}\n\nfunction canvasToBlob(canvas: HTMLCanvasElement, quality: number): Promise<Blob | null> {\n return new Promise((resolve) => canvas.toBlob(resolve, 'image/jpeg', quality))\n}\n\n/** Redraws `source` at `scale` so the encoder has fewer pixels to fit. */\nfunction downscale(source: HTMLCanvasElement, scale: number): HTMLCanvasElement | null {\n const canvas = document.createElement('canvas')\n canvas.width = Math.max(1, Math.round(source.width * scale))\n canvas.height = Math.max(1, Math.round(source.height * scale))\n const ctx = canvas.getContext('2d')\n if (!ctx) return null\n ctx.imageSmoothingQuality = 'high'\n ctx.drawImage(source, 0, 0, canvas.width, canvas.height)\n return canvas\n}\n\n/**\n * Reports when every rung fails. Without that, a page reliably blowing the cap\n * is indistinguishable from one with screenshots switched off — on screen and\n * in the Sentry inbox alike.\n */\nasync function encodeWithinLimit(canvas: HTMLCanvasElement): Promise<Blob | null> {\n let smallest: number | null = null\n\n for (const { quality, scale } of ENCODE_LADDER) {\n const target = scale === 1 ? canvas : downscale(canvas, scale)\n if (!target) continue\n const blob = await canvasToBlob(target, quality)\n if (!blob) continue\n if (blob.size <= MAX_SIZE) return blob\n smallest = smallest == null ? blob.size : Math.min(smallest, blob.size)\n }\n\n reportError(\n new Error(\n smallest == null\n ? 'Screenshot encode produced no blob at any quality/scale'\n : `Screenshot still ${smallest} bytes at the end of the encode ladder (cap ${MAX_SIZE})`,\n ),\n { context: 'screenshot-encode' },\n )\n return null\n}\n\n// Mirrors the CSS pin: the pointed bottom-left corner sits at the click point\n// and the body extends upward. x/y are viewport coords.\nfunction drawPin(ctx: CanvasRenderingContext2D, x: number, y: number, pixelRatio: number) {\n const pr = pixelRatio\n const size = 28 * pr\n const half = size / 2\n const px = x * pr\n const py = y * pr\n\n ctx.save()\n\n // Matches `box-shadow: 0 0 0 2px paper`.\n const ring = 2 * pr\n ctx.beginPath()\n // Same order as CSS `border-radius`: TL, TR, BR, BL.\n ctx.roundRect(px - ring, py - size - ring, size + ring * 2, size + ring * 2, [\n 14 * pr + ring,\n 14 * pr + ring,\n 14 * pr + ring,\n 4 * pr + ring,\n ])\n ctx.fillStyle = '#ffffff'\n ctx.fill()\n\n // The 4px pointed corner sits exactly at (px, py).\n ctx.beginPath()\n ctx.roundRect(px, py - size, size, size, [14 * pr, 14 * pr, 14 * pr, 4 * pr])\n ctx.fillStyle = '#1a1614'\n ctx.fill()\n\n // Dot — centered in the pin body\n ctx.beginPath()\n ctx.arc(px + half, py - half, 3 * pr, 0, Math.PI * 2)\n ctx.fillStyle = '#e35d2a'\n ctx.fill()\n\n ctx.restore()\n}\n","/**\n * Re-issued well before its server-side TTL, or an in-flight subscription\n * drops mid-session.\n *\n * The apiKey + Origin gate runs at mint time, so it is the token's value that\n * authorizes the WebSocket — a sniffed apiKey alone can't subscribe from an\n * off-allowlist origin.\n *\n * A two-state machine rather than `string | null`, so \"do we have a usable\n * token\" is a fact callers pattern-match on instead of null-check by\n * convention.\n */\n\nimport { useEffect } from 'preact/hooks'\n\nimport { defineMachine, useMachine } from '../lib/machine'\nimport { reportError } from './error-reporter'\nimport type { WidgetApiClient } from './api'\n\ntype TokenState = { kind: 'idle' } | { kind: 'active'; token: string; expiresAt: number }\n\ntype TokenEvent = { type: 'issued'; token: string; expiresAt: number }\n\nconst tokenMachine = defineMachine<TokenState, TokenEvent>({\n idle: {\n issued: (_, e) => ({ kind: 'active', token: e.token, expiresAt: e.expiresAt }),\n },\n active: {\n // The downstream subscription re-binds because the string changes.\n issued: (_, e) => ({ kind: 'active', token: e.token, expiresAt: e.expiresAt }),\n },\n})\n\n/**\n * Refresh ~30 min before expiry, but never sooner than 60s after the\n * last issuance. The floor avoids a tight retry loop in case the server\n * hands back an already-near-expiry token under clock skew, and gives\n * the WebSocket time to settle on the new credential between handoffs.\n */\nconst REFRESH_LEAD_MS = 30 * 60_000\nconst REFRESH_MIN_INTERVAL_MS = 60_000\nconst RETRY_AFTER_FAILURE_MS = 60_000\n\nexport function useSubscriptionToken(api: WidgetApiClient): string | null {\n const [state, send] = useMachine(tokenMachine, { kind: 'idle' })\n\n useEffect(() => {\n let cancelled = false\n let timer: ReturnType<typeof setTimeout> | null = null\n\n async function refresh() {\n try {\n const issued = await api.getSubscriptionToken()\n if (cancelled) return\n send({ type: 'issued', token: issued.token, expiresAt: issued.expiresAt })\n const refreshAfterMs = Math.max(\n REFRESH_MIN_INTERVAL_MS,\n issued.expiresAt - Date.now() - REFRESH_LEAD_MS,\n )\n timer = setTimeout(refresh, refreshAfterMs)\n } catch (err) {\n if (cancelled) return\n // Deliberately don't surface this to the user — if the apiKey/\n // Origin combo is bad the HTTP write paths will fail loudly\n // anyway, and a transient mint failure shouldn't add noise to\n // a UI that's otherwise still usable. But we DO want Sentry to\n // see it: a silent indefinite retry loop is the worst failure\n // mode for an embedded widget (Widget-H3 in the readiness\n // review). TypeError = network/CORS — skip; everything else\n // is structural and worth reporting.\n const name = (err as { name?: unknown } | null)?.name\n if (name !== 'TypeError') {\n reportError(err, { context: 'subscription-token-refresh' })\n }\n timer = setTimeout(refresh, RETRY_AFTER_FAILURE_MS)\n }\n }\n\n refresh()\n return () => {\n cancelled = true\n if (timer) clearTimeout(timer)\n }\n }, [api, send])\n\n return state.kind === 'active' ? state.token : null\n}\n","/**\n * Under `'localStorage'` the refresh token is posted in the body and the new\n * pair comes back as JSON. Under `'cookies'` the body is empty, the browser\n * attaches the HttpOnly refresh cookie, and the response carries only expiries.\n *\n * Every failure — network, 401, 5xx — surfaces as `null`, because the widget's\n * reaction is the same in each case: drop to `recovering` and re-mint anon.\n */\n\nimport { combinedSignal, WRITE_TIMEOUT_MS } from './api'\nimport { reportError } from './error-reporter'\n\nexport type RefreshedTokens =\n | {\n mode: 'localStorage'\n accessToken: string\n accessTokenExpiresAt: number\n refreshToken: string\n refreshTokenExpiresAt: number\n }\n | {\n mode: 'cookies'\n accessTokenExpiresAt: number\n refreshTokenExpiresAt: number\n }\n\nexport async function refreshWidgetTokens(args: {\n apiUrl: string\n apiKey: string\n mode: 'cookies' | 'localStorage'\n /** Required under `'localStorage'`; ignored under `'cookies'`. */\n refreshToken?: string\n /**\n * Composed with a `WRITE_TIMEOUT_MS` deadline rather than used alone: an\n * unmount controller bounds the fetch against the component's lifetime, not\n * the network, so a blackholing proxy would hang for as long as it's mounted.\n */\n signal?: AbortSignal\n}): Promise<RefreshedTokens | null> {\n try {\n const init: RequestInit = {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-markup-api-key': args.apiKey,\n },\n signal: combinedSignal(WRITE_TIMEOUT_MS, args.signal),\n }\n if (args.mode === 'cookies') {\n init.credentials = 'include'\n // The server reads the cookie when the body has no `refreshToken`.\n init.body = '{}'\n } else {\n if (!args.refreshToken) return null\n init.body = JSON.stringify({ refreshToken: args.refreshToken })\n }\n\n const res = await fetch(`${args.apiUrl.replace(/\\/+$/, '')}/widget/refresh`, init)\n if (!res.ok) return null\n const data = (await res.json()) as {\n mode?: unknown\n accessToken?: unknown\n accessTokenExpiresAt?: unknown\n refreshToken?: unknown\n refreshTokenExpiresAt?: unknown\n }\n\n if (data.mode === 'cookies') {\n if (\n typeof data.accessTokenExpiresAt !== 'number' ||\n typeof data.refreshTokenExpiresAt !== 'number'\n ) {\n return null\n }\n return {\n mode: 'cookies',\n accessTokenExpiresAt: data.accessTokenExpiresAt,\n refreshTokenExpiresAt: data.refreshTokenExpiresAt,\n }\n }\n\n // A server that doesn't emit `mode` is a pre-cookies one.\n if (\n typeof data.accessToken !== 'string' ||\n typeof data.accessTokenExpiresAt !== 'number' ||\n typeof data.refreshToken !== 'string' ||\n typeof data.refreshTokenExpiresAt !== 'number'\n ) {\n return null\n }\n return {\n mode: 'localStorage',\n accessToken: data.accessToken,\n accessTokenExpiresAt: data.accessTokenExpiresAt,\n refreshToken: data.refreshToken,\n refreshTokenExpiresAt: data.refreshTokenExpiresAt,\n }\n } catch (err) {\n // Unmount and offline are routine. Anything else is structural — a bad\n // JSON shape, a throw inside the parser.\n const name = (err as { name?: unknown } | null)?.name\n if (name !== 'AbortError' && name !== 'TypeError') {\n reportError(err, { context: 'refresh-token' })\n }\n return null\n }\n}\n","import { useEffect } from 'preact/hooks'\n\nimport { refreshWidgetTokens } from './refresh-token'\nimport type { IdentityState, VerifiedIdentity } from './identity-store'\n\n/**\n * Fires `~REFRESH_LEAD_MS` before the access token expires. Re-runs on every\n * `tokenExpiresAt` change, so the scheduler self-perpetuates as long as the\n * refresh chain stays alive.\n *\n * A no-op for non-verified states, for localStorage identities with no refresh\n * token (the legacy long-lived flow, which keeps its 401-to-anon fallback), and\n * for an already-expired refresh token — that last one surfaces the re-sign-in\n * CTA immediately rather than waiting for the next 401.\n */\nconst REFRESH_LEAD_MS = 60_000 // refresh 60s before expiry\nconst MIN_DELAY_MS = 500 // floor so we don't busy-loop on near-expired tokens\n\nexport function useTokenRefresh(\n identity: IdentityState,\n apiUrl: string,\n apiKey: string,\n onRefreshed: (next: VerifiedIdentity) => void,\n onFailure: () => void,\n): void {\n const isVerified = identity.kind === 'verified'\n const storage = isVerified ? identity.identity.storage : undefined\n const refreshToken = isVerified ? identity.identity.refreshToken : undefined\n const refreshExp = isVerified ? identity.identity.refreshTokenExpiresAt : undefined\n const accessExp = isVerified ? identity.identity.tokenExpiresAt : undefined\n\n useEffect(() => {\n if (!isVerified || refreshExp == null || accessExp == null) return\n // Cookie mode uses the HttpOnly cookie, so only localStorage needs the\n // raw token — and lacking one there means the legacy flow.\n if (storage === 'localStorage' && refreshToken == null) return\n if (storage !== 'cookies' && storage !== 'localStorage') return\n\n const now = Date.now()\n if (refreshExp <= now) {\n // Nothing to try; surface the re-sign-in path now.\n onFailure()\n return\n }\n\n const delay = Math.max(MIN_DELAY_MS, accessExp - REFRESH_LEAD_MS - now)\n const controller = new AbortController()\n\n const timer = window.setTimeout(async () => {\n const next = await refreshWidgetTokens({\n apiUrl,\n apiKey,\n mode: storage,\n refreshToken,\n signal: controller.signal,\n })\n if (controller.signal.aborted) return\n if (!next) {\n onFailure()\n return\n }\n if (identity.kind !== 'verified') return // changed mid-refresh\n if (next.mode === 'cookies') {\n // The tokens stayed in HttpOnly cookies; only the expiries are\n // visible, and updating them is what re-arms the scheduler.\n onRefreshed({\n ...identity.identity,\n tokenExpiresAt: next.accessTokenExpiresAt,\n refreshTokenExpiresAt: next.refreshTokenExpiresAt,\n })\n } else {\n onRefreshed({\n ...identity.identity,\n token: next.accessToken,\n tokenExpiresAt: next.accessTokenExpiresAt,\n refreshToken: next.refreshToken,\n refreshTokenExpiresAt: next.refreshTokenExpiresAt,\n })\n }\n }, delay)\n\n return () => {\n window.clearTimeout(timer)\n controller.abort()\n }\n // `identity` is read in the closure but deliberately not a dep: the\n // scheduler should re-run on the access window changing, not on every\n // identity event.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isVerified, storage, refreshToken, refreshExp, accessExp, apiUrl, apiKey])\n}\n","type ClassValue = string | boolean | null | undefined\n\nexport function cx(...classes: ClassValue[]) {\n return classes.filter(Boolean).join(' ')\n}\n\n/**\n * Labels for the submit/toggle chord, in the vocabulary of the platform\n * the host page is being read on.\n *\n * The handlers accept Cmd *or* Ctrl, so showing `⌘` unconditionally told\n * every Windows and Linux user to press a key their keyboard doesn't\n * have. Centralised because three call sites had grown their own copy of\n * the same `navigator` sniff.\n */\nexport function platformKeys(): { mod: string; enter: string } {\n const isMac =\n typeof navigator !== 'undefined' &&\n /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent)\n return isMac ? { mod: '⌘', enter: '↵' } : { mod: 'Ctrl', enter: 'Enter' }\n}\n","import{options as r,Fragment as e}from\"preact\";export{Fragment}from\"preact\";var t=/[\"&<]/;function n(r){if(0===r.length||!1===t.test(r))return r;for(var e=0,n=0,o=\"\",f=\"\";n<r.length;n++){switch(r.charCodeAt(n)){case 34:f=\""\";break;case 38:f=\"&\";break;case 60:f=\"<\";break;default:continue}n!==e&&(o+=r.slice(e,n)),o+=f,e=n+1}return n!==e&&(o+=r.slice(e,n)),o}var o=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,f=0,i=Array.isArray;function u(e,t,n,o,i,u){t||(t={});var a,c,p=t;if(\"ref\"in p)for(c in p={},t)\"ref\"==c?a=t[c]:p[c]=t[c];var l={type:e,props:p,key:n,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--f,__i:-1,__u:0,__source:i,__self:u};if(\"function\"==typeof e&&(a=e.defaultProps))for(c in a)void 0===p[c]&&(p[c]=a[c]);return r.vnode&&r.vnode(l),l}function a(r){var t=u(e,{tpl:r,exprs:[].slice.call(arguments,1)});return t.key=t.__v,t}var c={},p=/[A-Z]/g;function l(e,t){if(r.attr){var f=r.attr(e,t);if(\"string\"==typeof f)return f}if(t=function(r){return null!==r&&\"object\"==typeof r&&\"function\"==typeof r.valueOf?r.valueOf():r}(t),\"ref\"===e||\"key\"===e)return\"\";if(\"style\"===e&&\"object\"==typeof t){var i=\"\";for(var u in t){var a=t[u];if(null!=a&&\"\"!==a){var l=\"-\"==u[0]?u:c[u]||(c[u]=u.replace(p,\"-$&\").toLowerCase()),s=\";\";\"number\"!=typeof a||l.startsWith(\"--\")||o.test(l)||(s=\"px;\"),i=i+l+\":\"+a+s}}return e+'=\"'+n(i)+'\"'}return null==t||!1===t||\"function\"==typeof t||\"object\"==typeof t?\"\":!0===t?e:e+'=\"'+n(\"\"+t)+'\"'}function s(r){if(null==r||\"boolean\"==typeof r||\"function\"==typeof r)return null;if(\"object\"==typeof r){if(void 0===r.constructor)return r;if(i(r)){for(var e=0;e<r.length;e++)r[e]=s(r[e]);return r}}return n(\"\"+r)}export{u as jsx,l as jsxAttr,u as jsxDEV,s as jsxEscape,a as jsxTemplate,u as jsxs};\n//# sourceMappingURL=jsxRuntime.module.js.map\n","import type { ComponentChildren } from 'preact'\n\n/* Inline SVG icons — beats pulling in an icon library (~10kB saved). */\n\nexport function IconLogo({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 126 126\" fill=\"currentColor\" aria-hidden>\n <path d=\"M63.4561 0.00557731C70.6277 -0.0175584 76.9025 1.04088 83.5898 3.71066C97.7952 9.43043 109.186 20.5001 115.311 34.5359C119.708 44.8002 120.746 54.7869 119.156 65.8171C116.857 82.7956 105.129 98.8382 90.0566 106.846C83.4394 110.362 74.7336 113.029 67.2051 113.271C62.4204 113.425 61.1274 113.32 56.6807 115.204C50.2035 117.858 43.6874 120.417 37.1348 122.879C34.8442 123.763 32.3203 124.902 29.9404 125.51C29.4023 125.648 28.1978 125.009 27.7598 124.646C26.9046 123.951 27.0582 122.505 27.0264 121.484C26.8123 114.646 27.3302 107.458 26.8604 100.656C25.1578 98.6714 22.4026 96.603 20.3086 94.1989C12.1853 84.8731 7.05334 73.9949 6.18164 61.6101C4.95583 46.292 9.97176 31.1285 20.0908 19.5632C29.989 8.13202 44.0369 1.11921 59.1221 0.0788195C60.2694 -0.0356049 62.2637 0.00944821 63.4561 0.00557731ZM92.2676 55.7497C91.5754 39.5314 77.8207 26.9725 61.6064 27.7536C45.5175 28.5287 33.0758 42.1537 33.7627 58.2468C34.4496 74.3398 48.007 86.8553 64.1035 86.2566C80.3254 85.6533 92.9599 71.968 92.2676 55.7497Z\" />\n </svg>\n )\n}\n\nexport function IconClose({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M6.28 5.22a.75.75 0 0 0-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 1 0 1.06 1.06L10 11.06l3.72 3.72a.75.75 0 1 0 1.06-1.06L11.06 10l3.72-3.72a.75.75 0 0 0-1.06-1.06L10 8.94 6.28 5.22Z\" />\n </svg>\n )\n}\n\nexport function IconChevronDown({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden>\n <path d=\"M5.22 7.22a.75.75 0 0 1 1.06 0L10 10.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 8.28a.75.75 0 0 1 0-1.06Z\" />\n </svg>\n )\n}\n\nexport function IconChevronLeft({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden>\n <path d=\"M12.78 5.22a.75.75 0 0 1 0 1.06L9.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z\" />\n </svg>\n )\n}\n\nexport function IconEllipsis({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M3 10a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0ZM8.5 10a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0ZM15.5 8.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Z\" />\n </svg>\n )\n}\n\nexport function IconCheck({ size = 16 }: { size?: number }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n fill=\"currentColor\"\n viewBox=\"0 0 256 256\"\n >\n <path d=\"M173.66,98.34a8,8,0,0,1,0,11.32l-56,56a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35A8,8,0,0,1,173.66,98.34ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z\"></path>\n </svg>\n )\n}\n\nexport function IconCamera({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden>\n <path\n fill-rule=\"evenodd\"\n d=\"M1 8a2 2 0 0 1 2-2h.93a2 2 0 0 0 1.664-.89l.812-1.22A2 2 0 0 1 8.07 3h3.86a2 2 0 0 1 1.664.89l.812 1.22A2 2 0 0 0 16.07 6H17a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8Zm13.5 3a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0ZM10 14a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n )\n}\n\nexport function IconSend({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M2.87 2.298a.75.75 0 0 0-.812 1.021L3.39 6.624a1 1 0 0 0 .928.626H8.25a.75.75 0 0 1 0 1.5H4.318a1 1 0 0 0-.927.626l-1.333 3.305a.75.75 0 0 0 .811 1.022 24.89 24.89 0 0 0 11.668-5.115.75.75 0 0 0 0-1.175A24.89 24.89 0 0 0 2.869 2.298Z\" />\n </svg>\n )\n}\n\nexport function IconSmile({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 256 256\" fill=\"currentColor\" aria-hidden>\n <path d=\"M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216ZM80,108a12,12,0,1,1,12,12A12,12,0,0,1,80,108Zm96,0a12,12,0,1,1-12-12A12,12,0,0,1,176,108Zm-1.07,48c-10.29,17.79-27.4,28-46.93,28s-36.63-10.2-46.92-28a8,8,0,1,1,13.84-8c7.47,12.91,19.21,20,33.08,20s25.61-7.1,33.07-20a8,8,0,0,1,13.86,8Z\"></path>\n </svg>\n )\n}\n\n/* ──────────── New toolbar/menu icons (24x24 stroke set) ──────────── */\n\nfunction Stroke({ size = 16, children }: { size?: number; children: ComponentChildren }) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width={1.75}\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden\n >\n {children}\n </svg>\n )\n}\n\nexport function IconComment({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M21 11.5a8.4 8.4 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.4 8.4 0 0 1-3.8-.9L3 21l1.9-5.7a8.4 8.4 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.4 8.4 0 0 1 3.8-.9h.5a8.5 8.5 0 0 1 8 8v.5z\" />\n </Stroke>\n )\n}\n\nexport function IconInbox({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M22 12h-6l-2 3h-4l-2-3H2\" />\n <path d=\"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\" />\n </Stroke>\n )\n}\n\nexport function IconEye({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z\" />\n <circle cx=\"12\" cy=\"12\" r=\"2.5\" />\n </Stroke>\n )\n}\n\nexport function IconEyeOff({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M17.94 17.94A10.7 10.7 0 0 1 12 19c-6.5 0-10-7-10-7a18.5 18.5 0 0 1 5.06-5.94\" />\n <path d=\"M9.9 4.24A10.7 10.7 0 0 1 12 4c6.5 0 10 7 10 7a18.5 18.5 0 0 1-2.16 3.19\" />\n <path d=\"m1 1 22 22\" />\n <path d=\"M14.12 14.12a3 3 0 0 1-4.24-4.24\" />\n </Stroke>\n )\n}\n\nexport function IconMenu({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M3 6h18M3 12h18M3 18h18\" />\n </Stroke>\n )\n}\n\nexport function IconSun({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41\" />\n </Stroke>\n )\n}\n\nexport function IconMoon({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3a7 7 0 0 0 9.79 9.79z\" />\n </Stroke>\n )\n}\n\nexport function IconMonitor({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" />\n <path d=\"M8 21h8M12 17v4\" />\n </Stroke>\n )\n}\n\nexport function IconShield({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M12 22s8-3.5 8-10V5l-8-3-8 3v7c0 6.5 8 10 8 10z\" />\n </Stroke>\n )\n}\n\nexport function IconKeyboard({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <rect x=\"2\" y=\"6\" width=\"20\" height=\"12\" rx=\"2\" />\n <path d=\"M6 10h.01M10 10h.01M14 10h.01M18 10h.01M6 14h.01M18 14h.01M10 14h4\" />\n </Stroke>\n )\n}\n\nexport function IconEyeSlash({ size = 16 }: { size?: number }) {\n return IconEyeOff({ size })\n}\n\nexport function IconLogIn({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\" />\n <path d=\"M10 17l5-5-5-5M15 12H3\" />\n </Stroke>\n )\n}\n\nexport function IconLogOut({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <path d=\"M16 17l5-5-5-5M21 12H9\" />\n </Stroke>\n )\n}\n\nexport function IconUser({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <circle cx=\"12\" cy=\"8\" r=\"4\" />\n <path d=\"M4 21a8 8 0 0 1 16 0\" />\n </Stroke>\n )\n}\n\n/**\n * Marks agent-authored comments. Traced from the same Lucide `bot` glyph\n * the dashboard's OAuth authorize screen uses, so the badge on an agent's\n * reply matches the icon shown when its access was granted.\n */\nexport function IconBot({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M12 8V4H8\" />\n <rect x=\"4\" y=\"8\" width=\"16\" height=\"12\" rx=\"2\" />\n <path d=\"M2 14h2\" />\n <path d=\"M20 14h2\" />\n <path d=\"M15 13v2\" />\n <path d=\"M9 13v2\" />\n </Stroke>\n )\n}\n\nexport function IconExternal({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M15 3h6v6\" />\n <path d=\"M10 14 21 3\" />\n <path d=\"M21 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5\" />\n </Stroke>\n )\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\n\nimport { displayNameOf, type IdentityState } from '../identity-store'\nimport { cx } from '../utils'\nimport { IconExternal, IconLogIn, IconLogOut, IconUser } from './icons'\n\ntype ToolbarPosition = 'bottom-right' | 'bottom-left' | 'bottom-center'\n\n/**\n * Identity menu — anchored to the avatar/name button inside the toolbar\n * pill. Two presentation modes:\n *\n * - **Anonymous** (`identity.kind !== 'verified'`): a sign-in CTA card\n * with a primary button and a forget-me secondary action. The\n * popover is intentionally compact and focused — no surface-level\n * \"Notifications\" or \"Account\" entries to crowd the verified case.\n *\n * - **Verified**: name + email card, then Account link (if a\n * dashboardUrl is configured) and Sign out (with arm-then-confirm).\n *\n * Light-dismiss matches the OverflowMenu pattern: document-level\n * capture listener on click + Escape, using `composedPath()` so it\n * detects inside-shadow targets correctly.\n */\nexport function IdentityMenu({\n identity,\n position,\n isSigningIn,\n isSigningOut,\n dashboardUrl,\n onSignIn,\n onSignOut,\n onForgetMe,\n}: {\n identity: IdentityState\n position: ToolbarPosition\n isSigningIn: boolean\n isSigningOut: boolean\n dashboardUrl?: string\n onSignIn: () => void\n onSignOut: () => void\n onForgetMe: () => void\n}) {\n const [open, setOpen] = useState(false)\n const [confirmForget, setConfirmForget] = useState(false)\n const [confirmSignOut, setConfirmSignOut] = useState(false)\n const containerRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n if (!open) return\n function onDocClick(e: MouseEvent) {\n const container = containerRef.current\n if (!container) return\n if (!e.composedPath().includes(container)) setOpen(false)\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') setOpen(false)\n }\n document.addEventListener('click', onDocClick, true)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('click', onDocClick, true)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n useEffect(() => {\n if (!open) {\n setConfirmForget(false)\n setConfirmSignOut(false)\n }\n }, [open])\n\n const name = displayNameOf(identity)\n const initials = nameInitials(name)\n const isVerified = identity.kind === 'verified'\n const image = identity.kind === 'verified' ? identity.identity.image : undefined\n // The picture is third-party-hosted, so a host CSP or a rotated URL can\n // fail it. Track the URL that failed rather than a bare flag, so a later\n // sign-in as someone else gets a fresh chance.\n const [failedImage, setFailedImage] = useState<string | null>(null)\n const showImage = isVerified && image != null && failedImage !== image\n const email = isVerified ? identity.identity.email : null\n\n const anchorClass =\n position === 'bottom-left'\n ? 'is-anchor-left'\n : position === 'bottom-center'\n ? 'is-anchor-center'\n : 'is-anchor-right'\n\n return (\n <div ref={containerRef} style={{ position: 'relative', display: 'inline-flex' }}>\n <button\n type=\"button\"\n class=\"markup-tb-btn markup-id-btn\"\n data-kind=\"identity\"\n data-on={open ? 'true' : undefined}\n data-anon={isVerified ? undefined : 'true'}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-label={isVerified ? `Signed in as ${name ?? 'you'}` : 'Sign in'}\n title={name ?? (isVerified ? 'Account' : 'Sign in')}\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n setOpen((v) => !v)\n }}\n >\n <span class={cx('markup-tb-avatar', !isVerified && 'is-anon')} aria-hidden=\"true\">\n {showImage ? (\n <img\n class=\"markup-avatar-img\"\n src={image}\n alt=\"\"\n decoding=\"async\"\n referrerpolicy=\"no-referrer\"\n onError={() => setFailedImage(image)}\n />\n ) : isVerified && initials ? (\n // Wrapped rather than bare text so `.markup-avatar-initials`\n // has an element to trim — see the rule in styles.css.\n <span class=\"markup-avatar-initials\">{initials}</span>\n ) : (\n <IconUser size={14} />\n )}\n </span>\n {isVerified && name ? <span class=\"markup-sr-only\">{name}</span> : null}\n </button>\n\n {open ? (\n <div class={cx('markup-pop', anchorClass)} data-pop=\"identity\" role=\"menu\">\n {isVerified ? (\n <>\n <div class=\"markup-id-who\">\n <span class=\"nm\">{name ?? 'Account'}</span>\n {email ? <span class=\"em\">{email}</span> : null}\n </div>\n {dashboardUrl ? (\n <a\n role=\"menuitem\"\n class=\"markup-menu-row\"\n href={dashboardUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={() => setOpen(false)}\n >\n <span class=\"ic\">\n <IconExternal size={16} />\n </span>\n <span class=\"lbl\">Account</span>\n </a>\n ) : null}\n <button\n type=\"button\"\n role=\"menuitem\"\n class={cx('markup-menu-row', confirmSignOut && 'is-danger')}\n disabled={isSigningOut}\n onClick={() => {\n if (confirmSignOut) {\n setOpen(false)\n onSignOut()\n } else {\n setConfirmSignOut(true)\n }\n }}\n >\n <span class=\"ic\">\n <IconLogOut size={16} />\n </span>\n <span class=\"lbl\">\n {isSigningOut\n ? 'Signing out…'\n : confirmSignOut\n ? 'Confirm — sign out of this site'\n : 'Sign out'}\n </span>\n </button>\n </>\n ) : (\n <div class=\"markup-id-anon\">\n <div class=\"h\">Sign in to Markup</div>\n <div class=\"sub\">\n Get notified when teammates reply and access your inbox across projects.\n </div>\n <button\n type=\"button\"\n disabled={isSigningIn}\n onClick={() => {\n // Close synchronously so the OAuth popup isn't competing for focus.\n setOpen(false)\n onSignIn()\n }}\n >\n <IconLogIn size={14} />\n <span>{isSigningIn ? 'Signing in…' : 'Sign in'}</span>\n </button>\n <button\n type=\"button\"\n class={cx('markup-menu-row', confirmForget && 'is-danger')}\n onClick={() => {\n if (confirmForget) {\n setOpen(false)\n onForgetMe()\n } else {\n setConfirmForget(true)\n }\n }}\n style={{ marginTop: '2px' }}\n >\n <span class=\"lbl\">\n {confirmForget\n ? 'Confirm — comments stay, name/email cleared'\n : 'Forget me on this site…'}\n </span>\n </button>\n </div>\n )}\n </div>\n ) : null}\n </div>\n )\n}\n\nfunction nameInitials(name: string | null): string | null {\n if (!name) return null\n const parts = name.trim().split(/\\s+/).slice(0, 2)\n const letters = parts.map((p) => p[0]?.toUpperCase() ?? '').join('')\n return letters || null\n}\n","import type { RefObject } from 'preact'\nimport { useCallback, useRef, useState } from 'preact/hooks'\n\n/**\n * `onEnd` fires only on a clean pointerup past the threshold; `onCancel` fires\n * on pointercancel, after bookkeeping is already reset.\n *\n * Deliberately no click-suppression helper: no current caller co-locates a\n * click handler with the drag handle. One that did would have to suppress the\n * synthesized click following a threshold-crossing pointerup itself.\n */\nexport interface UseDragOpts {\n /** Lets the popover headers skip the drag for a pointer on a button. */\n shouldStart?: (e: PointerEvent) => boolean\n /**\n * Only needed when the handle is a sub-region of the thing being dragged, as\n * with a popover header — otherwise `e.currentTarget` is measured.\n */\n targetRef?: RefObject<HTMLElement>\n /** Called once when the pointer first crosses the threshold. */\n onStart?: () => void\n /** Streamed during the drag with viewport-clamped coords. */\n onMove: (coords: { left: number; top: number }) => void\n /** Only past the threshold, and never on pointercancel. */\n onEnd?: (coords: { left: number; top: number }, ev: PointerEvent) => void\n /** Called on pointercancel (no follow-up click expected). */\n onCancel?: () => void\n /** Defaults to 4px. */\n threshold?: number\n /** Margin from the viewport edge when clamping coords. Default 8. */\n margin?: number\n /** So a host page's outside-click handler doesn't read a drag as dismiss. */\n stopPropagation?: boolean\n /**\n * Needed alongside `stopPropagation`: Radix's `DismissableLayer` listens in\n * capture phase, so stopping propagation on bubble is too late. It does bail\n * on `defaultPrevented`, which is what this buys.\n */\n preventDefault?: boolean\n}\n\nexport interface UseDragReturn {\n onPointerDown: (e: PointerEvent) => void\n /** True between threshold-crossed and pointerup/cancel. */\n isDragging: boolean\n}\n\nexport function useDrag(opts: UseDragOpts): UseDragReturn {\n // Keeps `onPointerDown` stable even when callers pass inline callbacks.\n const optsRef = useRef(opts)\n optsRef.current = opts\n\n const [isDragging, setIsDragging] = useState(false)\n\n const onPointerDown = useCallback((e: PointerEvent) => {\n const o = optsRef.current\n if (o.preventDefault) e.preventDefault()\n if (o.stopPropagation) e.stopPropagation()\n if (e.button !== 0) return\n if (o.shouldStart && !o.shouldStart(e)) return\n\n const handle = e.currentTarget as HTMLElement | null\n if (!handle) return\n // The handle receives the events; the target is what gets measured. They\n // differ for a popover header dragging its popover.\n const target = o.targetRef?.current ?? handle\n const rect = target.getBoundingClientRect()\n const startX = e.clientX\n const startY = e.clientY\n const baseLeft = rect.left\n const baseTop = rect.top\n const w = rect.width\n const h = rect.height\n const threshold = o.threshold ?? 4\n const margin = o.margin ?? 8\n const pointerId = e.pointerId\n let started = false\n let lastCoords: { left: number; top: number } | null = null\n\n try {\n handle.setPointerCapture(pointerId)\n } catch {\n /* capture unsupported — fall back to bubbling events */\n }\n\n function teardown() {\n try {\n handle?.releasePointerCapture(pointerId)\n } catch {\n /* ignore */\n }\n handle?.removeEventListener('pointermove', onMove)\n handle?.removeEventListener('pointerup', onPointerUp)\n handle?.removeEventListener('pointercancel', onPointerCancel)\n setIsDragging(false)\n }\n\n function onMove(ev: PointerEvent) {\n if (ev.pointerId !== pointerId) return\n const dx = ev.clientX - startX\n const dy = ev.clientY - startY\n if (!started) {\n if (Math.abs(dx) + Math.abs(dy) < threshold) return\n started = true\n setIsDragging(true)\n optsRef.current.onStart?.()\n }\n const maxLeft = Math.max(margin, window.innerWidth - w - margin)\n const maxTop = Math.max(margin, window.innerHeight - h - margin)\n const coords = {\n left: clamp(baseLeft + dx, margin, maxLeft),\n top: clamp(baseTop + dy, margin, maxTop),\n }\n lastCoords = coords\n optsRef.current.onMove(coords)\n }\n\n function onPointerUp(ev: PointerEvent) {\n if (ev.pointerId !== pointerId) return\n teardown()\n if (started && lastCoords) optsRef.current.onEnd?.(lastCoords, ev)\n }\n\n function onPointerCancel(ev: PointerEvent) {\n if (ev.pointerId !== pointerId) return\n teardown()\n optsRef.current.onCancel?.()\n }\n\n handle.addEventListener('pointermove', onMove)\n handle.addEventListener('pointerup', onPointerUp)\n handle.addEventListener('pointercancel', onPointerCancel)\n }, [])\n\n return { onPointerDown, isDragging }\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value))\n}\n","import type { RefObject } from 'preact'\nimport { useEffect } from 'preact/hooks'\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',')\n\n/**\n * Trap Tab focus inside `ref`. Pressing Tab on the last focusable element\n * wraps to the first; Shift+Tab on the first wraps to the last. The\n * Popover API doesn't trap focus on its own (popovers are non-modal), so\n * we layer this on top.\n *\n * `getRootNode()` is used to read `activeElement` correctly when the\n * popover lives inside a shadow root.\n */\nexport function useFocusTrap(ref: RefObject<HTMLElement>, enabled: boolean): void {\n useEffect(() => {\n if (!enabled) return\n const root = ref.current\n if (!root) return\n\n function onKey(e: KeyboardEvent) {\n if (e.key !== 'Tab') return\n const focusables = Array.from(root!.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR))\n const first = focusables[0]\n const last = focusables[focusables.length - 1]\n if (!first || !last) return\n\n const r = root!.getRootNode()\n const active = r instanceof ShadowRoot ? r.activeElement : document.activeElement\n\n if (e.shiftKey ? active === first : active === last) {\n e.preventDefault()\n ;(e.shiftKey ? last : first).focus()\n }\n }\n\n root.addEventListener('keydown', onKey)\n return () => root.removeEventListener('keydown', onKey)\n }, [ref, enabled])\n}\n","import { useEffect, useState } from 'preact/hooks'\n\n/**\n * Wrap a `Blob` in an object URL for the lifetime of the calling\n * component (or until the blob changes). The previous URL is revoked\n * automatically and the state is reset to `null` when the blob is\n * cleared, so consumers can render an `<img src={url ?? ''}>` without\n * worrying about a dangling revoked URL.\n *\n * The new-thread popover is the only consumer today, but the pattern\n * shows up whenever a transient blob (clipboard paste, drag-drop) needs\n * to be rendered. Keeping this in one place makes adding a second\n * caller free.\n */\nexport function useObjectURL(blob: Blob | null): string | null {\n const [url, setUrl] = useState<string | null>(null)\n\n useEffect(() => {\n if (!blob) {\n setUrl(null)\n return\n }\n const next = URL.createObjectURL(blob)\n setUrl(next)\n return () => URL.revokeObjectURL(next)\n }, [blob])\n\n return url\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\n\n/**\n * One-time identity capture. Shown the first time a user wants to post.\n *\n * Two paths:\n * - Sign in via the dashboard (popup) — verified \"team\" identity.\n * - Type name + email manually — anonymous identity, persisted to host\n * localStorage so this is asked at most once per site.\n *\n * `isConnecting` reflects \"the host hasn't resolved an identity yet\" —\n * either first-load anon mint is still in flight or we're recovering\n * from a 401 by minting a replacement. The guest path needs a signed\n * identity to attach the post to, so the inputs are disabled with a\n * hint until that resolves. The popup sign-in path is independent of\n * the anon mint, so its button stays enabled.\n */\nexport function AuthorPrompt({\n isPending,\n isConnecting = false,\n isSigningIn = false,\n onSubmit,\n onCancel,\n onSignIn,\n}: {\n isPending: boolean\n isConnecting?: boolean\n /** A popup sign-in is in flight — keep the user from launching another. */\n isSigningIn?: boolean\n onSubmit: (name: string, email?: string) => void\n onCancel: () => void\n onSignIn?: () => void\n}) {\n const [name, setName] = useState('')\n const [email, setEmail] = useState('')\n const ref = useRef<HTMLInputElement>(null)\n\n useEffect(() => {\n ref.current?.focus()\n }, [])\n\n function handleSubmit(e?: Event) {\n e?.preventDefault()\n const trimmedName = name.trim()\n if (!trimmedName || isPending || isConnecting) return\n const trimmedEmail = email.trim()\n onSubmit(trimmedName, trimmedEmail || undefined)\n }\n\n const guestDisabled = isPending || isConnecting\n\n return (\n <form class=\"markup-author-prompt\" onSubmit={handleSubmit}>\n {onSignIn ? (\n <>\n <button\n type=\"button\"\n class=\"markup-btn markup-btn-primary\"\n onClick={onSignIn}\n disabled={isPending || isSigningIn}\n >\n {isSigningIn ? 'Signing in…' : 'Sign in with Markup'}\n </button>\n <p class=\"markup-author-divider\">or continue as a guest</p>\n </>\n ) : (\n <p class=\"markup-eyebrow\">who's leaving feedback?</p>\n )}\n <input\n ref={ref}\n class=\"markup-input\"\n type=\"text\"\n name=\"name\"\n placeholder=\"Your name\"\n value={name}\n maxLength={80}\n autoComplete=\"name\"\n onInput={(e) => setName((e.currentTarget as HTMLInputElement).value)}\n disabled={guestDisabled}\n data-1p-ignore\n />\n <input\n class=\"markup-input\"\n type=\"email\"\n name=\"email\"\n placeholder=\"Email (optional)\"\n value={email}\n maxLength={254}\n autoComplete=\"email\"\n onInput={(e) => setEmail((e.currentTarget as HTMLInputElement).value)}\n disabled={guestDisabled}\n data-1p-ignore\n />\n {isConnecting ? (\n <p class=\"markup-author-status\" role=\"status\" aria-live=\"polite\">\n Connecting…\n </p>\n ) : null}\n <div class=\"markup-composer-actions\">\n <button\n type=\"button\"\n class=\"markup-btn markup-btn-ghost\"\n onClick={onCancel}\n disabled={isPending}\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n class=\"markup-btn markup-btn-primary\"\n disabled={!name.trim() || guestDisabled}\n >\n Continue\n </button>\n </div>\n </form>\n )\n}\n","/**\n * A contenteditable host rather than a `<textarea>`: the wire format for a\n * mention is `@[Display Name](userId)`, which a textarea can only show\n * verbatim — brackets, parens and an opaque id mid-sentence. Contenteditable\n * lets each mention render as a chip the browser treats as one atomic unit\n * (`contenteditable=\"false\"`, so Backspace removes the whole thing) while the\n * text around it stays ordinary text.\n *\n * The DOM is the source of truth for the draft. `serializeMentionDom`\n * walks it back to the wire format after every input, which means paste,\n * chip deletion, and multi-line edits all stay in sync without the\n * controller tracking offsets. Nothing here imports Preact — the\n * framework wrapper (`ui/mention-input.tsx`) owns only the picker overlay\n * and prop plumbing.\n *\n * `apps/dashboard/src/lib/mention-input.ts` is the dashboard's copy of\n * this file. They can't import each other (published browser bundle vs.\n * app source), so keep them in lockstep — same reason the mention regex\n * itself is duplicated in three places. See `../lib/mentions.ts`.\n */\n\nimport { detectMentionTrigger, mentionMarkerFor, parseMentionTokens } from '../lib/mentions'\nimport type { MentionTriggerState } from '../lib/mentions'\n\nexport type MentionMember = { userId: string; name: string }\n\n/** Present on chip elements; its value is the userId the chip encodes. */\nexport const MENTION_UID_ATTR = 'data-markup-mention'\n/**\n * The display name exactly as picked. Read in preference to the chip's\n * `textContent` so serialization survives a chip whose visible label the\n * user managed to partially overtype.\n */\nexport const MENTION_NAME_ATTR = 'data-markup-mention-name'\n\n/**\n * Tags an engine may wrap a line in when the user presses Enter (Chrome\n * reaches for `div`, WebKit sometimes `div`/`p`). `plaintext-only` avoids\n * them, but Gecko only shipped that recently, so serialization treats the\n * boundary as a newline rather than flattening two lines together.\n */\nconst BLOCK_TAGS = new Set(['DIV', 'P', 'LI', 'BLOCKQUOTE', 'PRE'])\n\nconst TEXT_NODE = 3\nconst ELEMENT_NODE = 1\n\n/* ────────────────────────── serialize ────────────────────────── */\n\n/** Text nodes verbatim, chips to `@[Name](userId)`, line breaks to `\\n`. */\nexport function serializeMentionDom(root: HTMLElement): string {\n let out = ''\n\n const visit = (parent: Node) => {\n const children = parent.childNodes\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n if (!child) continue\n\n if (child.nodeType === TEXT_NODE) {\n out += (child as Text).data\n continue\n }\n if (child.nodeType !== ELEMENT_NODE) continue\n const el = child as HTMLElement\n\n const uid = el.getAttribute(MENTION_UID_ATTR)\n if (uid) {\n const name = chipName(el)\n out += mentionMarkerFor({ userId: uid, name }) ?? `@${name}`\n continue\n }\n\n if (el.tagName === 'BR') {\n // Engines park a bogus trailing <br> so the final line stays\n // focusable. Scaffolding, not something the author typed.\n const isTrailingScaffold = parent === root && i === children.length - 1\n if (!isTrailingScaffold) out += '\\n'\n continue\n }\n\n if (BLOCK_TAGS.has(el.tagName) && out !== '' && !out.endsWith('\\n')) out += '\\n'\n visit(el)\n }\n }\n\n visit(root)\n return out\n}\n\nfunction chipName(el: HTMLElement): string {\n const authored = el.getAttribute(MENTION_NAME_ATTR)\n if (authored) return authored\n return (el.textContent ?? '').replace(/^@/, '')\n}\n\n/* ────────────────────────── deserialize ────────────────────────── */\n\nexport function createMentionChip(\n doc: Document,\n member: MentionMember,\n chipClass: string,\n): HTMLElement {\n const chip = doc.createElement('span')\n chip.className = chipClass\n // What makes the browser treat the chip as one unit for caret movement\n // and deletion, for free.\n chip.setAttribute('contenteditable', 'false')\n chip.setAttribute(MENTION_UID_ATTR, member.userId)\n chip.setAttribute(MENTION_NAME_ATTR, member.name)\n chip.textContent = `@${member.name}`\n return chip\n}\n\n/**\n * Newlines stay inside text nodes rather than becoming `<br>`, which keeps a\n * line contiguous and so keeps trigger detection on a single text node.\n */\nexport function renderMentionNodes(\n doc: Document,\n body: string,\n chipClass: string,\n): DocumentFragment {\n const frag = doc.createDocumentFragment()\n for (const token of parseMentionTokens(body)) {\n if (token.type === 'text') {\n if (token.value) frag.appendChild(doc.createTextNode(token.value))\n continue\n }\n frag.appendChild(createMentionChip(doc, { userId: token.userId, name: token.name }, chipClass))\n }\n return frag\n}\n\n/* ────────────────────────── selection ────────────────────────── */\n\n/**\n * Behind a shadow root `document.getSelection()` retargets to the host on\n * Chromium and WebKit, so the caret's real text node is only reachable via the\n * non-standard `ShadowRoot.getSelection()`. Gecko has no such method but does\n * pierce shadow boundaries. Root first, document second covers all three, and\n * collapses to the plain document path when there's no\n * shadow root at all (the dashboard).\n */\nfunction selectionFor(root: HTMLElement): Selection | null {\n const owner = root.getRootNode() as { getSelection?: () => Selection | null }\n if (typeof owner.getSelection === 'function') return owner.getSelection()\n return root.ownerDocument.getSelection()\n}\n\ntype Caret = { node: Text; offset: number }\n\n/**\n * Excludes a caret inside a chip: its label isn't editable text, and treating\n * it as real would let the chip's leading `@` reopen the picker on its own name.\n */\nfunction caretIn(root: HTMLElement): Caret | null {\n const sel = selectionFor(root)\n if (!sel || sel.rangeCount === 0 || !sel.isCollapsed) return null\n const node = sel.focusNode\n if (!node || node.nodeType !== TEXT_NODE || !root.contains(node)) return null\n if (chipAncestor(node, root)) return null\n return { node: node as Text, offset: sel.focusOffset }\n}\n\n/** The chip element containing `node`, if any. */\nfunction chipAncestor(node: Node, root: HTMLElement): HTMLElement | null {\n let cur: Node | null = node\n while (cur && cur !== root) {\n if (cur.nodeType === ELEMENT_NODE && (cur as HTMLElement).hasAttribute(MENTION_UID_ATTR)) {\n return cur as HTMLElement\n }\n cur = cur.parentNode\n }\n return null\n}\n\n/**\n * Chips are `contenteditable=\"false\"`, so a caret inside one silently refuses\n * every keystroke — and that is exactly where a click lands when the line ends\n * with a chip, i.e. whenever you edit a comment finishing in a mention. The\n * empty text node gives the caret somewhere legal to sit without changing what\n * the body serializes to, so it can't trip the wrapper's `value` reconciliation.\n */\nfunction nudgeCaretOutOfChip(root: HTMLElement): void {\n const sel = selectionFor(root)\n if (!sel || sel.rangeCount === 0 || !sel.isCollapsed) return\n const node = sel.focusNode\n if (!node || !root.contains(node)) return\n const chip = chipAncestor(node, root)\n if (!chip) return\n\n let after = chip.nextSibling\n if (!after || after.nodeType !== TEXT_NODE) {\n after = root.ownerDocument.createTextNode('')\n chip.parentNode?.insertBefore(after, chip.nextSibling)\n }\n setCaret(root, after, 0)\n}\n\nfunction setCaret(root: HTMLElement, node: Node, offset: number): void {\n const sel = selectionFor(root)\n if (!sel) return\n const range = root.ownerDocument.createRange()\n range.setStart(node, offset)\n range.collapse(true)\n sel.removeAllRanges()\n sel.addRange(range)\n}\n\n/** Offsets are node-local: a chip is an element boundary a trigger can't span. */\ntype ActiveTrigger = MentionTriggerState & { textNode: Text }\n\nfunction triggerAt(caret: Caret): ActiveTrigger | null {\n const state = detectMentionTrigger(caret.node.data, caret.offset)\n return state ? { ...state, textNode: caret.node } : null\n}\n\n/* ────────────────────────── edits ────────────────────────── */\n\nfunction insertChipAtTrigger(\n root: HTMLElement,\n trigger: ActiveTrigger,\n member: MentionMember,\n chipClass: string,\n): boolean {\n if (mentionMarkerFor(member) == null) return false\n const text = trigger.textNode\n if (!root.contains(text)) return false\n const parent = text.parentNode\n if (!parent) return false\n if (trigger.caret > text.data.length) return false\n\n // Split where the query was, so the chip lands exactly there.\n text.deleteData(trigger.at, trigger.caret - trigger.at)\n const after = text.splitText(trigger.at)\n parent.insertBefore(createMentionChip(root.ownerDocument, member, chipClass), after)\n // Normalised to exactly one space, so back-to-back mentions don't pile up\n // separators. The caret lands past it, ready to keep typing.\n if (!after.data.startsWith(' ')) after.insertData(0, ' ')\n setCaret(root, after, 1)\n return true\n}\n\n/**\n * Inserts into the caret's existing text node rather than appending a new one,\n * so pasting into the middle of `@ali|` leaves the trigger intact.\n */\nfunction insertPlainText(root: HTMLElement, text: string): void {\n const sel = selectionFor(root)\n if (!sel || sel.rangeCount === 0) return\n const range = sel.getRangeAt(0)\n if (!root.contains(range.commonAncestorContainer)) return\n range.deleteContents()\n\n const { startContainer, startOffset } = range\n if (startContainer.nodeType === TEXT_NODE) {\n const node = startContainer as Text\n node.insertData(startOffset, text)\n setCaret(root, node, startOffset + text.length)\n return\n }\n const node = root.ownerDocument.createTextNode(text)\n range.insertNode(node)\n setCaret(root, node, node.data.length)\n}\n\n/* ────────────────────────── controller ────────────────────────── */\n\nexport type MentionInputController = {\n /** The draft in wire format, serialized live from the DOM. */\n getValue(): string\n /** Only for changes the editor didn't make. */\n setValue(body: string): void\n /** Focus with the caret parked at the end of the draft. */\n focus(): void\n /** Inserts a chip at the open trigger. No-op when none is open. */\n insertMention(member: MentionMember): void\n /** Recomputes the trigger from the live caret. */\n syncTrigger(): void\n /** Without suppressing it: the next caret sync may legitimately re-open. */\n clearTrigger(): void\n /**\n * Closes the picker and keeps it closed for as long as the caret stays\n * inside *this* `@`. For an explicit dismissal (Escape).\n */\n dismissTrigger(): void\n destroy(): void\n}\n\nexport type MentionInputOptions = {\n /** Class applied to chip elements. */\n chipClass: string\n initialValue?: string\n onChange: (body: string) => void\n onTriggerChange: (trigger: MentionTriggerState | null) => void\n /**\n * Checked before any trigger work so a host with no mentionable\n * members never opens a picker. A callback rather than a boolean\n * because the member list arrives asynchronously.\n */\n mentionsEnabled: () => boolean\n}\n\nexport function attachMentionInput(\n el: HTMLElement,\n opts: MentionInputOptions,\n): MentionInputController {\n const doc = el.ownerDocument\n let trigger: ActiveTrigger | null = null\n /**\n * The `@` the user dismissed with Escape, if any. Without this the\n * picker springs straight back open: Escape clears the trigger, then\n * the very next `keyup` re-detects the same `@` from the unchanged\n * caret. Suppression lasts as long as the caret stays inside that same\n * `@`, so someone typing a literal \"@ me later\" is left alone, while\n * moving away and starting a new mention works normally.\n */\n let dismissed: { node: Text; at: number } | null = null\n let isEmpty = true\n\n function markEmpty(value: string) {\n const next = value.length === 0\n if (next === isEmpty && el.hasAttribute('data-empty') === next) return\n isEmpty = next\n el.toggleAttribute('data-empty', next)\n }\n\n function emit() {\n const next = serializeMentionDom(el)\n markEmpty(next)\n opts.onChange(next)\n }\n\n function publishTrigger(next: ActiveTrigger | null) {\n const prev = trigger\n trigger = next\n // Bail on an unchanged trigger: `syncTrigger` fires on every keyup\n // and pointer-up, and a fresh object each time would re-render the\n // picker (resetting its highlight) on arrow keys that didn't move\n // out of the query.\n const unchanged =\n prev == null\n ? next == null\n : next != null &&\n prev.at === next.at &&\n prev.caret === next.caret &&\n prev.query === next.query &&\n prev.textNode === next.textNode\n if (unchanged) return\n opts.onTriggerChange(next ? { at: next.at, caret: next.caret, query: next.query } : null)\n }\n\n function syncTrigger() {\n if (!opts.mentionsEnabled()) {\n publishTrigger(null)\n return\n }\n const caret = caretIn(el)\n const next = caret ? triggerAt(caret) : null\n if (next && dismissed && next.textNode === dismissed.node && next.at === dismissed.at) {\n publishTrigger(null)\n return\n }\n // The caret left the dismissed `@`, so stop suppressing it.\n dismissed = null\n publishTrigger(next)\n }\n\n function setValue(body: string) {\n el.replaceChildren(renderMentionNodes(doc, body, opts.chipClass))\n markEmpty(serializeMentionDom(el))\n dismissed = null\n publishTrigger(null)\n }\n\n const onInput = () => {\n emit()\n syncTrigger()\n }\n const onCaretMove = () => syncTrigger()\n // Only on pointer-up and focus, not on keyup: arrow keys already step\n // over a chip atomically, and nudging on every keyup would fight anyone\n // navigating leftwards past one.\n const onPointerCaret = () => {\n nudgeCaretOutOfChip(el)\n syncTrigger()\n }\n const onPaste = (e: ClipboardEvent) => {\n // Always take the plain-text flavour. `plaintext-only` hosts do this\n // anyway; the `true` fallback would otherwise accept arbitrary\n // markup, including elements that look like chips.\n const text = e.clipboardData?.getData('text/plain')\n e.preventDefault()\n if (!text) return\n insertPlainText(el, text.replace(/\\r\\n?/g, '\\n'))\n emit()\n syncTrigger()\n }\n const onDrop = (e: DragEvent) => {\n // Dropping a selection from the host page would inject its markup\n // straight into the editing host. Cheaper to refuse than sanitise.\n e.preventDefault()\n }\n\n el.addEventListener('input', onInput)\n el.addEventListener('keyup', onCaretMove)\n el.addEventListener('mouseup', onPointerCaret)\n el.addEventListener('focus', onPointerCaret)\n el.addEventListener('paste', onPaste)\n el.addEventListener('drop', onDrop)\n\n setValue(opts.initialValue ?? '')\n\n return {\n getValue: () => serializeMentionDom(el),\n setValue,\n focus() {\n el.focus()\n // `focus()` alone parks the caret at the start, which reads as\n // broken when the host already holds a draft to edit.\n const last = el.lastChild\n if (!last) return\n if (last.nodeType === TEXT_NODE) setCaret(el, last, (last as Text).data.length)\n else setCaret(el, el, el.childNodes.length)\n },\n insertMention(member) {\n // Prefer the live caret over the stored trigger: the stored one can\n // be a keystroke stale, and its text node may have been replaced\n // by an intervening edit. The stored trigger stays as the fallback\n // for the case where focus has already moved off the host.\n const caret = caretIn(el)\n const target = (caret ? triggerAt(caret) : null) ?? trigger\n if (!target) return\n if (!insertChipAtTrigger(el, target, member, opts.chipClass)) return\n emit()\n dismissed = null\n publishTrigger(null)\n },\n syncTrigger,\n clearTrigger: () => publishTrigger(null),\n dismissTrigger() {\n if (trigger) dismissed = { node: trigger.textNode, at: trigger.at }\n publishTrigger(null)\n },\n destroy() {\n el.removeEventListener('input', onInput)\n el.removeEventListener('keyup', onCaretMove)\n el.removeEventListener('mouseup', onPointerCaret)\n el.removeEventListener('focus', onPointerCaret)\n el.removeEventListener('paste', onPaste)\n el.removeEventListener('drop', onDrop)\n },\n }\n}\n\n/* ────────────────────────── plaintext-only ────────────────────────── */\n\nlet cachedMode: 'plaintext-only' | 'true' | null = null\n\n/**\n * `contenteditable=\"plaintext-only\"` stops an engine turning Enter into\n * block wrappers and ⌘B into `<b>` markup — exactly right for a plain\n * body with atomic chips. Chromium and WebKit ship it; Gecko only got it\n * recently, so fall back to `\"true\"`. Serialization handles either shape,\n * so the fallback is a cosmetic difference, not a correctness one.\n *\n * Probed lazily rather than at module scope so importing this file stays\n * safe where there's no `document` (SSR).\n */\nexport function plaintextEditableMode(): 'plaintext-only' | 'true' {\n if (cachedMode) return cachedMode\n if (typeof document === 'undefined') return 'true'\n const probe = document.createElement('div')\n try {\n probe.contentEditable = 'plaintext-only'\n cachedMode = probe.contentEditable === 'plaintext-only' ? 'plaintext-only' : 'true'\n } catch {\n cachedMode = 'true'\n }\n return cachedMode\n}\n","import type { ComponentChildren } from 'preact'\nimport { useEffect, useMemo, useState } from 'preact/hooks'\n\nimport { parseMentionTokens } from '../../lib/mentions'\nimport type { MentionTriggerState } from '../../lib/mentions'\n\nexport type MentionableMember = { userId: string; name: string }\n\n/**\n * A marker whose id isn't in the validated `mentions` set renders as plain\n * `@Name`, never as the raw marker. The missing chip is the signal that nobody\n * was notified — a hand-crafted id, a member who left, or the common case of a\n * user mentioning themselves, which the server drops on purpose.\n */\nexport function MentionizedBody({\n body,\n mentions,\n trailing,\n}: {\n body: string\n mentions: readonly string[]\n trailing?: ComponentChildren\n}) {\n const valid = useMemo(() => new Set(mentions), [mentions])\n const tokens = useMemo(() => parseMentionTokens(body), [body])\n return (\n <p class=\"markup-comment-body\">\n {tokens.map((t, i) => {\n if (t.type === 'mention' && valid.has(t.userId)) {\n return (\n <span key={i} class=\"markup-mention-chip\">\n @{t.name}\n </span>\n )\n }\n const text = t.type === 'mention' ? `@${t.name}` : t.value\n return <span key={i}>{text}</span>\n })}\n {trailing}\n </p>\n )\n}\n\n/** Headless: the caller owns the textarea and renders the overlay. */\nexport function useMentionPicker(opts: {\n members: readonly MentionableMember[]\n trigger: MentionTriggerState | null\n onSelect: (member: MentionableMember) => void\n onClose: () => void\n}) {\n const { members, trigger, onSelect, onClose } = opts\n const [highlight, setHighlight] = useState(0)\n\n const filtered = useMemo(() => {\n if (!trigger) return []\n const q = trigger.query.toLowerCase()\n return members.filter((m) => m.name.toLowerCase().includes(q)).slice(0, 6)\n }, [trigger, members])\n\n // Keeps the highlight in bounds as the filtered list shrinks.\n useEffect(() => {\n setHighlight((h) => (h >= filtered.length ? 0 : h))\n }, [filtered])\n\n /** `true` means consumed — the caller must skip its own handling. */\n function handleKeyDown(e: KeyboardEvent): boolean {\n if (!trigger || filtered.length === 0) return false\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n setHighlight((h) => (h + 1) % filtered.length)\n return true\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault()\n setHighlight((h) => (h - 1 + filtered.length) % filtered.length)\n return true\n }\n if (e.key === 'Enter' || e.key === 'Tab') {\n e.preventDefault()\n const member = filtered[highlight]\n if (member) onSelect(member)\n return true\n }\n if (e.key === 'Escape') {\n e.preventDefault()\n onClose()\n return true\n }\n return false\n }\n\n return {\n isOpen: trigger != null && filtered.length > 0,\n items: filtered,\n highlight,\n setHighlight,\n handleKeyDown,\n }\n}\n\n/** Positioned by the composer, absolutely, under the textarea container. */\nexport function MentionPickerList({\n items,\n highlight,\n setHighlight,\n onSelect,\n}: {\n items: readonly MentionableMember[]\n highlight: number\n setHighlight: (i: number) => void\n onSelect: (member: MentionableMember) => void\n}) {\n if (items.length === 0) return null\n return (\n <ul class=\"markup-mention-picker\" role=\"listbox\" aria-label=\"Mention member\">\n {items.map((m, i) => (\n <li\n key={m.userId}\n role=\"option\"\n aria-selected={i === highlight}\n class={`markup-mention-picker-item${i === highlight ? ' is-active' : ''}`}\n onMouseDown={(e) => {\n // Not click: the textarea blur would fire first.\n e.preventDefault()\n onSelect(m)\n }}\n onMouseEnter={() => setHighlight(i)}\n >\n <span class=\"markup-mention-picker-name\">{m.name}</span>\n <span class=\"markup-mention-picker-trigger\" aria-hidden=\"true\">\n @\n </span>\n </li>\n ))}\n </ul>\n )\n}\n","import { useLayoutEffect, useRef, useState } from 'preact/hooks'\n\nimport {\n attachMentionInput,\n plaintextEditableMode,\n type MentionInputController,\n} from '../mention-input'\nimport { cx } from '../utils'\nimport { MentionPickerList, useMentionPicker, type MentionableMember } from './mentions'\nimport type { MentionTriggerState } from '../../lib/mentions'\n\n/**\n * Imperative escape hatch for the two things a parent legitimately needs\n * and props can't express on an editor whose DOM is authoritative.\n */\nexport type MentionInputHandle = {\n focus: () => void\n}\n\n/**\n * `value` is controlled, but written back into the DOM only when it differs\n * from what the DOM already serializes to. Keystrokes round-trip identically,\n * so typing never disturbs the caret; the write fires only for values the\n * editor didn't produce, like clearing after submit.\n *\n * A contenteditable host has no `maxLength`, so the over-limit state is the\n * caller's job.\n */\nexport function MentionInput({\n value,\n onChange,\n onKeyDown,\n members,\n label,\n placeholder,\n disabled = false,\n autoFocus = false,\n class: className,\n handle,\n}: {\n value: string\n onChange: (next: string) => void\n /**\n * Runs only for keys the mention picker didn't consume, so a parent\n * can bind Cmd+Enter without stealing Enter from an open picker.\n */\n onKeyDown?: (e: KeyboardEvent) => void\n /** Empty / undefined disables mentions entirely. */\n members?: readonly MentionableMember[]\n label: string\n placeholder?: string\n disabled?: boolean\n autoFocus?: boolean\n class?: string\n handle?: { current: MentionInputHandle | null }\n}) {\n const elRef = useRef<HTMLDivElement>(null)\n const ctrlRef = useRef<MentionInputController | null>(null)\n const [trigger, setTrigger] = useState<MentionTriggerState | null>(null)\n\n // Read through refs so the controller's listeners, which live for the\n // element's whole lifetime, don't force a re-attach every render.\n const onChangeRef = useRef(onChange)\n onChangeRef.current = onChange\n const membersRef = useRef(members)\n membersRef.current = members\n // Reading `value` in the attach effect would make it a dependency and\n // re-create the controller on every keystroke.\n const initialValueRef = useRef(value)\n\n useLayoutEffect(() => {\n const el = elRef.current\n if (!el) return\n const ctrl = attachMentionInput(el, {\n chipClass: 'markup-mention-chip',\n initialValue: initialValueRef.current,\n onChange: (next) => onChangeRef.current(next),\n onTriggerChange: setTrigger,\n mentionsEnabled: () => (membersRef.current?.length ?? 0) > 0,\n })\n ctrlRef.current = ctrl\n return () => {\n ctrl.destroy()\n ctrlRef.current = null\n }\n }, [])\n\n // Cleared on unmount so a parent holding the ref can't call a dead editor.\n useLayoutEffect(() => {\n if (!handle) return\n handle.current = { focus: () => ctrlRef.current?.focus() }\n return () => {\n handle.current = null\n }\n }, [handle])\n\n useLayoutEffect(() => {\n if (autoFocus) ctrlRef.current?.focus()\n }, [autoFocus])\n\n // MUST be a layout effect. `useEffect` runs after paint, so under fast\n // typing it lands several keystrokes late holding a stale `value`, and\n // \"reconciles\" the DOM backwards — dropping characters and resetting the\n // caret. A layout effect commits in the same microtask as its state update.\n useLayoutEffect(() => {\n const ctrl = ctrlRef.current\n if (!ctrl) return\n if (ctrl.getValue() !== value) ctrl.setValue(value)\n }, [value])\n\n const picker = useMentionPicker({\n members: members ?? [],\n trigger,\n onSelect: (member) => ctrlRef.current?.insertMention(member),\n // Escape is deliberate, so it must stick rather than re-open.\n onClose: () => ctrlRef.current?.dismissTrigger(),\n })\n\n return (\n <>\n <div\n ref={elRef}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={label}\n aria-disabled={disabled || undefined}\n class={cx('markup-mention-input', className)}\n /* No children, ever — the controller owns this subtree. Preact\n * only diffs vnode children, so it leaves the DOM alone. */\n contentEditable={disabled ? 'false' : plaintextEditableMode()}\n data-placeholder={placeholder}\n tabIndex={disabled ? -1 : 0}\n onKeyDown={(e) => {\n if (picker.handleKeyDown(e)) return\n onKeyDown?.(e)\n }}\n onBlur={() => {\n // Next tick, so a mousedown on a picker item lands first.\n setTimeout(() => ctrlRef.current?.clearTrigger(), 120)\n }}\n />\n {picker.isOpen ? (\n <MentionPickerList\n items={picker.items}\n highlight={picker.highlight}\n setHighlight={picker.setHighlight}\n onSelect={(member) => ctrlRef.current?.insertMention(member)}\n />\n ) : null}\n </>\n )\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\n\nimport { cx, platformKeys } from '../utils'\nimport { IconSend } from './icons'\nimport { MentionInput, type MentionInputHandle } from './mention-input'\nimport type { MentionableMember } from './mentions'\n\nconst MAX_BODY = 4000\n\n/**\n * Reusable text composer used both for the first comment of a new thread and\n * for replies on an existing thread. Submits on Cmd/Ctrl+Enter; auto-grows;\n * disables submit while the parent's submit promise resolves.\n *\n * When `members` is non-empty, typing `@` opens an autocomplete picker and\n * the selected member becomes a chip. The `@[Name](userId)` wire format\n * lives only in the serialized `body` that `onSubmit` receives — the\n * parent re-extracts mention IDs from it to send alongside the write (the\n * server re-validates).\n */\nexport function Composer({\n label,\n placeholder = 'Leave feedback…',\n submitLabel = 'Post',\n initialFocus = true,\n isPending,\n error,\n onSubmit,\n members,\n}: {\n label: string\n placeholder?: string\n submitLabel?: string\n initialFocus?: boolean\n isPending: boolean\n error?: string\n onSubmit: (body: string) => void\n /** Empty / undefined disables the mention picker entirely. */\n members?: readonly MentionableMember[]\n}) {\n const [value, setValue] = useState('')\n const inputRef = useRef<MentionInputHandle | null>(null)\n const wasPending = useRef(false)\n\n // After a successful submit (isPending true → false with no error) clear the\n // value and re-focus so the user can keep typing replies.\n useEffect(() => {\n if (wasPending.current && !isPending && !error) {\n setValue('')\n inputRef.current?.focus()\n }\n wasPending.current = isPending\n }, [isPending, error])\n\n const remaining = MAX_BODY - value.length\n const isOverLimit = remaining < 0\n\n function handleSubmit(e?: Event) {\n e?.preventDefault()\n const body = value.trim()\n // Mirror the submit button's disabled state. Without the\n // `isOverLimit` check here, Cmd/Ctrl+Enter would fire even though\n // the visible button is greyed — server rejects the body, but UX\n // is inconsistent.\n if (!body || isPending || isOverLimit) return\n onSubmit(body)\n }\n\n // `MentionInput` gives the picker first refusal on every key, so this\n // only ever sees keys it didn't consume — a user pressing Enter to pick\n // a mention can't accidentally submit the comment.\n function onKey(e: KeyboardEvent) {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n handleSubmit(e)\n }\n }\n\n const isFilled = value.length > 0\n const keys = platformKeys()\n\n function submitButton(tabIndex?: number) {\n return (\n <button\n type=\"submit\"\n class=\"markup-btn markup-btn-primary\"\n disabled={isPending || !value.trim() || isOverLimit}\n aria-label={isPending ? 'Sending…' : submitLabel}\n title={isPending ? 'Sending…' : submitLabel}\n tabIndex={tabIndex}\n >\n <IconSend size={14} />\n </button>\n )\n }\n\n return (\n <form class={cx('markup-composer', isFilled && 'is-filled')} onSubmit={handleSubmit}>\n <MentionInput\n class=\"markup-composer-input\"\n label={label}\n placeholder={placeholder}\n value={value}\n onChange={setValue}\n onKeyDown={onKey}\n members={members}\n disabled={isPending}\n autoFocus={initialFocus}\n handle={inputRef}\n />\n {/* Footer always in DOM — height animated via grid-template-rows trick */}\n <div class=\"markup-composer-footer-wrap\">\n <div class=\"markup-composer-footer\">\n <span class=\"markup-composer-hint\">\n {error ? (\n <span class=\"markup-composer-error\">{error}</span>\n ) : isOverLimit ? (\n <span class=\"markup-composer-error\">{Math.abs(remaining)} too long</span>\n ) : (\n /* Chips rather than bare glyphs in the sentence. Measured\n against this mono face, `⌘` floats 1.2px clear of the\n baseline while `↵` is barely half a cap tall and sits on\n it — set inline they read as debris beside the words. A\n chip centres each glyph in its own box, so their metrics\n stop being compared to the text's. Labels follow the\n platform: the handler takes Cmd or Ctrl, and only one of\n those is on the reader's keyboard. */\n <>\n <kbd class=\"markup-kbd is-inline\">{keys.mod}</kbd>\n <kbd class=\"markup-kbd is-inline\">{keys.enter}</kbd>\n <span class=\"markup-composer-hint-label\">to send</span>\n </>\n )}\n </span>\n <div class=\"markup-composer-actions\">{submitButton(isFilled ? undefined : -1)}</div>\n </div>\n </div>\n {/* Floating button shown only when empty */}\n <span class=\"markup-composer-actions-empty\" aria-hidden={isFilled || undefined}>\n {submitButton(isFilled ? -1 : undefined)}\n </span>\n </form>\n )\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\n\nimport { useDrag } from '../use-drag'\nimport { useFocusTrap } from '../use-focus-trap'\nimport { useObjectURL } from '../use-object-url'\nimport { cx } from '../utils'\nimport { AuthorPrompt } from './author-prompt'\nimport { Composer } from './composer'\nimport { IconCamera, IconClose } from './icons'\nimport type { MentionableMember } from './mentions'\n\n/**\n * The \"you just dropped a pin\" popover. Either the author-name capture (if\n * we don't have one yet) or the thread composer. Closing it discards the pin.\n *\n * Uses the native Popover API (`popover=\"auto\"`) — ESC and outside-click\n * dismissal are handled by the browser. Position is anchored to the ghost\n * pin via CSS Anchor Positioning (with a JS-clamp fallback).\n */\nexport function NewThreadPopover({\n pageX,\n pageY,\n authorName,\n isVerified,\n isIdentityResolving,\n isSigningIn,\n isPending,\n error,\n screenshot,\n isScreenshotCapturing,\n screenshotFailed,\n screenshotRedactedCount,\n screenshotRedactedSelectors,\n members = [],\n onAuthor,\n onSignIn,\n onSubmit,\n onClose,\n}: {\n pageX: number\n pageY: number\n authorName: string | null\n isVerified: boolean\n /** Anon mint hasn't completed yet — disable the guest path. */\n isIdentityResolving: boolean\n /** A popup sign-in is already in flight — disable the sign-in button. */\n isSigningIn: boolean\n isPending: boolean\n error: string | undefined\n screenshot: Blob | null\n isScreenshotCapturing: boolean\n /** A capture ran and produced nothing — say so instead of going quiet. */\n screenshotFailed: boolean\n screenshotRedactedCount: number\n screenshotRedactedSelectors: string[]\n /**\n * Mentionable project members for the `@`-autocomplete. Empty\n * disables the picker.\n */\n members?: readonly MentionableMember[]\n onAuthor: (name: string, email?: string) => void\n onSignIn: () => void\n onSubmit: (body: string, includeScreenshot: boolean) => void\n onClose: () => void\n}) {\n const ref = useRef<HTMLDivElement>(null)\n useFocusTrap(ref, true)\n\n const [includeScreenshot, setIncludeScreenshot] = useState(false)\n const [isRedactionExpanded, setIsRedactionExpanded] = useState(false)\n const previewUrl = useObjectURL(screenshot)\n // User-dragged position; `null` means \"use the anchor / fallback coords\".\n // Resets to null on every mount, so reopening snaps back to the pin.\n const [dragPos, setDragPos] = useState<{ left: number; top: number } | null>(null)\n // Drag-to-move from the header. Same shape as ThreadPopover —\n // handle is the header but we measure the popover.\n const { onPointerDown: onHeaderPointerDown, isDragging } = useDrag({\n targetRef: ref,\n shouldStart: (e) => {\n const target = e.target as HTMLElement | null\n return !target?.closest('button, a, input, textarea, select')\n },\n onMove: setDragPos,\n })\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n\n if (typeof el.showPopover === 'function' && !el.matches(':popover-open')) {\n try {\n el.showPopover()\n } catch {\n /* already showing or unsupported */\n }\n }\n\n function onToggle(e: Event) {\n const ev = e as ToggleEvent\n if (ev.newState === 'closed') onClose()\n }\n el.addEventListener('toggle', onToggle)\n return () => el.removeEventListener('toggle', onToggle)\n }, [onClose])\n\n const width = 320\n const margin = 12\n const left = clamp(pageX - window.scrollX + 16, margin, window.innerWidth - width - margin)\n const top = clamp(pageY - window.scrollY - 16, margin, window.innerHeight - 220)\n const pageUrl = typeof window !== 'undefined' ? window.location.href : ''\n\n const hasScreenshot = screenshot != null\n // The failed state is part of the row on purpose. Dropping the row on\n // failure made a broken capture look exactly like a project with\n // screenshots turned off, so nobody reported it as a bug.\n const showScreenshotRow = isScreenshotCapturing || hasScreenshot || screenshotFailed\n\n return (\n <div\n ref={ref}\n class={cx('markup-popover', dragPos && 'is-floating', isDragging && 'is-dragging')}\n popover=\"auto\"\n style={{\n '--markup-pop-x': `${dragPos?.left ?? left}px`,\n '--markup-pop-y': `${dragPos?.top ?? top}px`,\n }}\n role=\"dialog\"\n aria-label=\"New markup\"\n >\n <header class=\"markup-popover-header\" onPointerDown={onHeaderPointerDown}>\n {/* Same reasoning as the thread popover's header: the page is the\n one you are looking at, and a hostname is the one label here\n that cannot be shortened without becoming a lie. Saying \"New\n comment\" also retires the separate \"new\" chip, which existed\n to qualify an address that is no longer shown. Full URL stays\n on hover. */}\n <span class=\"markup-popover-title\" title={pageUrl}>\n New comment\n </span>\n <button type=\"button\" class=\"markup-icon-btn\" aria-label=\"Discard pin\" onClick={onClose}>\n <IconClose size={16} />\n </button>\n </header>\n\n {authorName == null ? (\n <AuthorPrompt\n isPending={isPending}\n isConnecting={isIdentityResolving}\n isSigningIn={isSigningIn}\n onSubmit={onAuthor}\n onCancel={onClose}\n onSignIn={onSignIn}\n />\n ) : (\n <div class=\"markup-popover-body\">\n <p class=\"markup-popover-byline\">\n posting as <span class=\"markup-popover-name\">{authorName}</span>\n {isVerified ? <span class=\"markup-comment-badge\">team</span> : null}\n </p>\n <Composer\n label=\"Feedback\"\n placeholder=\"What's wrong, missing, or worth noting?\"\n submitLabel=\"Post markup\"\n isPending={isPending}\n error={error}\n onSubmit={(body) => onSubmit(body, includeScreenshot && hasScreenshot)}\n members={members}\n />\n {showScreenshotRow ? (\n <div class={cx('markup-screenshot-row', screenshotFailed && 'is-failed')}>\n {isScreenshotCapturing ? (\n <span class=\"markup-screenshot-status\">\n <input type=\"checkbox\" class=\"markup-screenshot-checkbox\" disabled />\n <IconCamera size={12} />\n <span>Capturing…</span>\n </span>\n ) : screenshotFailed ? (\n /* No checkbox — there is nothing to attach. The comment\n still posts; only the screenshot is missing. */\n <span\n class=\"markup-screenshot-status\"\n title=\"This page has something the capture can't read — often a third-party image. Your comment will post without a screenshot.\"\n >\n <IconCamera size={12} />\n <span>Screenshot unavailable</span>\n </span>\n ) : (\n <label class=\"markup-screenshot-toggle\">\n <input\n type=\"checkbox\"\n class=\"markup-screenshot-checkbox\"\n checked={includeScreenshot}\n onChange={(e) => setIncludeScreenshot(e.currentTarget.checked)}\n />\n <IconCamera size={12} />\n <span>Attach screenshot</span>\n {previewUrl && includeScreenshot ? (\n <img\n class=\"markup-screenshot-thumb\"\n src={previewUrl}\n alt=\"Screenshot preview\"\n />\n ) : null}\n </label>\n )}\n {includeScreenshot && hasScreenshot ? (\n <>\n {screenshotRedactedCount > 0 ? (\n <div class=\"markup-screenshot-redacted\">\n <button\n type=\"button\"\n class=\"markup-screenshot-redacted-chip\"\n onClick={() => setIsRedactionExpanded((v) => !v)}\n >\n <em class=\"markup-screenshot-redacted-arrow\">\n {isRedactionExpanded ? '▾' : '▸'}\n </em>\n {screenshotRedactedCount}{' '}\n {screenshotRedactedCount === 1 ? 'field' : 'fields'} redacted\n </button>\n {isRedactionExpanded ? (\n <div class=\"markup-screenshot-redacted-list\">\n {screenshotRedactedSelectors.map((sel) => (\n <code key={sel} class=\"markup-screenshot-redacted-selector\">\n {sel}\n </code>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n <p class=\"markup-screenshot-help\">\n Password and credit-card fields are blacked out automatically. Add{' '}\n <code class=\"markup-screenshot-help-code\">data-markup-private</code> to mask\n anything else.\n </p>\n </>\n ) : null}\n </div>\n ) : null}\n </div>\n )}\n </div>\n )\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value))\n}\n","import { cx } from '../utils'\nimport { IconBot, IconChevronLeft } from './icons'\nimport type { WidgetNotification } from '../api'\n\n/**\n * Verified-user notifications inbox rendered inside a `PanelPopover`\n * (which owns the floating surface chrome anchored to the toolbar's\n * inbox button). This component owns no dismissal logic of\n * its own — the wrapper's outside-click + Escape handlers\n * (`composedPath()`-based so they work across the widget's shadow-root\n * boundary) take the surface down when the user clicks elsewhere.\n *\n * Click a row → mark-read in the same transaction the host runs to\n * open the thread popover for that comment. The dashboard inbox\n * subscribes to the same `readAt` field, so the dashboard's bell\n * decrements in real time once the widget mutation lands.\n *\n * Scoped to the current project on the server — see\n * `convex/widget/notifications.ts#listForProject`. Cross-project\n * notifications live on the dashboard `/notifications` route.\n */\nexport function NotificationsPanel({\n items,\n isLoading,\n error,\n onBack,\n onItemClick,\n onMarkAllRead,\n isMarkingAll,\n}: {\n items: readonly WidgetNotification[]\n isLoading: boolean\n error?: string\n onBack: () => void\n onItemClick: (item: WidgetNotification) => void\n onMarkAllRead: () => void\n isMarkingAll: boolean\n}) {\n const anyUnread = items.some((i) => i.readAt == null)\n\n return (\n <div class=\"markup-notifications-panel\" role=\"dialog\" aria-label=\"Notifications\">\n <header class=\"markup-notifications-panel-header\">\n <button\n type=\"button\"\n class=\"markup-icon-btn\"\n title=\"Back to menu\"\n aria-label=\"Back to menu\"\n onClick={onBack}\n >\n <IconChevronLeft size={16} />\n </button>\n <span class=\"markup-eyebrow\">notifications</span>\n <div class=\"markup-notifications-panel-actions\">\n {anyUnread ? (\n <button\n type=\"button\"\n class=\"markup-notifications-panel-mark-all\"\n disabled={isMarkingAll}\n onClick={onMarkAllRead}\n >\n {isMarkingAll ? 'Marking…' : 'Mark all read'}\n </button>\n ) : null}\n </div>\n </header>\n\n <div class=\"markup-notifications-panel-body\">\n {error ? (\n <p class=\"markup-notifications-panel-error\">{error}</p>\n ) : isLoading ? (\n <p class=\"markup-notifications-panel-empty\">Loading…</p>\n ) : items.length === 0 ? (\n <div class=\"markup-notifications-panel-empty\">\n <p class=\"markup-notifications-panel-empty-title\">You're all caught up.</p>\n <p class=\"markup-notifications-panel-empty-sub\">\n New @mentions on this site land here.\n </p>\n </div>\n ) : (\n <ul class=\"markup-notifications-panel-list\">\n {items.map((item) => (\n <li key={item._id}>\n <button\n type=\"button\"\n class={cx('markup-notifications-panel-row', item.readAt == null && 'is-unread')}\n onClick={() => onItemClick(item)}\n >\n <div class=\"markup-notifications-panel-meta\">\n {item.readAt == null ? (\n <span aria-hidden=\"true\" class=\"markup-notifications-panel-dot\" />\n ) : null}\n <span class=\"markup-notifications-panel-actor\">{item.actorName}</span>\n {/* Same reasoning as the badge in the thread\n popover: the row carries a real person's name,\n so a visitor has to be able to tell that a\n machine wrote the comment that pinged them. */}\n {item.actorVia === 'mcp' ? (\n <span\n class=\"markup-comment-badge is-agent\"\n role=\"img\"\n aria-label=\"Written by an AI agent\"\n title=\"Written by an AI agent on this person's behalf\"\n >\n <IconBot size={11} />\n </span>\n ) : null}\n <span class=\"markup-notifications-panel-sep\">·</span>\n <span class=\"markup-notifications-panel-time\">\n {relativeTime(item.createdAt)}\n </span>\n </div>\n <p class=\"markup-notifications-panel-thread\">\n mentioned you in{' '}\n <span class=\"markup-notifications-panel-thread-title\">{item.threadTitle}</span>\n </p>\n {item.commentExcerpt ? (\n <p class=\"markup-notifications-panel-excerpt\">“{item.commentExcerpt}”</p>\n ) : null}\n </button>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n )\n}\n\nfunction relativeTime(ts: number): string {\n const diff = Date.now() - ts\n const sec = Math.floor(diff / 1000)\n if (sec < 60) return 'just now'\n const min = Math.floor(sec / 60)\n if (min < 60) return `${min}m ago`\n const hr = Math.floor(min / 60)\n if (hr < 24) return `${hr}h ago`\n const day = Math.floor(hr / 24)\n if (day < 30) return `${day}d ago`\n return new Date(ts).toLocaleDateString()\n}\n","import { useEffect, useState } from 'preact/hooks'\n\nimport {\n getThemeMode,\n resolvedTheme,\n setThemeMode,\n subscribeTheme,\n type ThemeMode,\n} from './theme-store'\n\n/**\n * Preact hook that re-renders on theme changes (mode flips OR system\n * preference flips while in `auto`). Returns the user's *mode* plus\n * the *resolved* (light | dark) value, and a setter that writes the\n * store + persists.\n */\nexport function useTheme(): {\n mode: ThemeMode\n resolved: 'light' | 'dark'\n set: (next: ThemeMode) => void\n} {\n const [, forceRender] = useState(0)\n\n useEffect(() => subscribeTheme(() => forceRender((v) => v + 1)), [])\n\n return {\n mode: getThemeMode(),\n resolved: resolvedTheme(),\n set: setThemeMode,\n }\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\n\nimport { useTheme } from '../use-theme'\nimport { cx, platformKeys } from '../utils'\nimport {\n IconKeyboard,\n IconLogo,\n IconMenu,\n IconMonitor,\n IconMoon,\n IconShield,\n IconSun,\n} from './icons'\n\ntype ToolbarPosition = 'bottom-right' | 'bottom-left' | 'bottom-center'\n\n/**\n * The panel rows close this menu before opening, so the panel doesn't appear\n * behind it. `app.tsx` owns the open-panel state because the panels mount as\n * siblings of the toolbar rather than inside this popover.\n *\n * Neither row advertises a key hint, deliberately: a bare `?` would collide\n * with host-page shortcuts we can't see, and the widget has no business\n * claiming a plain key the app underneath may already use.\n */\nexport function OverflowMenu({\n position,\n onSetPosition,\n autoCapture,\n autoCaptureLocked = false,\n onToggleAutoCapture,\n onOpenPrivacy,\n onOpenShortcuts,\n onHideForSession,\n version,\n dashboardUrl,\n}: {\n position: ToolbarPosition\n onSetPosition: (next: ToolbarPosition) => void\n autoCapture: boolean\n /**\n * The user's toggle can't override a host opt-out, so the row says who\n * turned it off rather than offering a control that does nothing.\n */\n autoCaptureLocked?: boolean\n onToggleAutoCapture: () => void\n onOpenPrivacy: () => void\n onOpenShortcuts: () => void\n onHideForSession: () => void\n /** Version string shown in the footer (e.g., \"4.2.0\"). */\n version: string\n /** Optional brand-line link (the dashboard \"marketing\" URL). */\n dashboardUrl?: string\n}) {\n const [open, setOpen] = useState(false)\n const containerRef = useRef<HTMLDivElement>(null)\n const theme = useTheme()\n\n useEffect(() => {\n if (!open) return\n function onDocClick(e: MouseEvent) {\n const container = containerRef.current\n if (!container) return\n if (!e.composedPath().includes(container)) setOpen(false)\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') setOpen(false)\n }\n document.addEventListener('click', onDocClick, true)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('click', onDocClick, true)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n const anchorClass =\n position === 'bottom-left'\n ? 'is-anchor-left'\n : position === 'bottom-center'\n ? 'is-anchor-center'\n : 'is-anchor-right'\n\n const { mod: modKey } = platformKeys()\n\n return (\n <div ref={containerRef} style={{ position: 'relative', display: 'inline-flex' }}>\n <button\n type=\"button\"\n class=\"markup-tb-btn\"\n data-kind=\"overflow\"\n data-on={open ? 'true' : undefined}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-label=\"More options\"\n title=\"More\"\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n setOpen((v) => !v)\n }}\n >\n <IconMenu size={16} />\n </button>\n\n {open ? (\n <div class={cx('markup-pop', anchorClass)} data-pop=\"overflow\" role=\"menu\">\n {/* Appearance — horizontal row: label left, segmented right. */}\n <div class=\"markup-segmented-row\">\n <span class=\"lbl\">Appearance</span>\n <div class=\"markup-segmented\" role=\"radiogroup\" aria-label=\"Appearance\">\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={theme.mode === 'light'}\n aria-label=\"Light\"\n title=\"Light\"\n class={cx(theme.mode === 'light' && 'is-on')}\n onClick={() => theme.set('light')}\n >\n <IconSun size={14} />\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={theme.mode === 'dark'}\n aria-label=\"Dark\"\n title=\"Dark\"\n class={cx(theme.mode === 'dark' && 'is-on')}\n onClick={() => theme.set('dark')}\n >\n <IconMoon size={14} />\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={theme.mode === 'auto'}\n aria-label={`Auto (currently ${theme.resolved})`}\n title={`Auto — currently ${theme.resolved}`}\n class={cx(theme.mode === 'auto' && 'is-on')}\n onClick={() => theme.set('auto')}\n >\n <IconMonitor size={14} />\n </button>\n </div>\n </div>\n\n {/* Position — horizontal row, same shape as Appearance. */}\n <div class=\"markup-segmented-row\">\n <span class=\"lbl\">Position</span>\n <div class=\"markup-segmented\" role=\"radiogroup\" aria-label=\"Position\">\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={position === 'bottom-left'}\n aria-label=\"Bottom left\"\n title=\"Bottom left\"\n class={cx(position === 'bottom-left' && 'is-on')}\n onClick={() => onSetPosition('bottom-left')}\n >\n <CornerIcon side=\"left\" />\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={position === 'bottom-center'}\n aria-label=\"Bottom center\"\n title=\"Bottom center\"\n class={cx(position === 'bottom-center' && 'is-on')}\n onClick={() => onSetPosition('bottom-center')}\n >\n <CornerIcon side=\"center\" />\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={position === 'bottom-right'}\n aria-label=\"Bottom right\"\n title=\"Bottom right\"\n class={cx(position === 'bottom-right' && 'is-on')}\n onClick={() => onSetPosition('bottom-right')}\n >\n <CornerIcon side=\"right\" />\n </button>\n </div>\n </div>\n\n <div class=\"markup-pop-group-label\">behavior</div>\n\n <button\n type=\"button\"\n role=\"menuitemcheckbox\"\n aria-checked={autoCapture}\n class=\"markup-menu-row\"\n data-on={autoCapture ? 'true' : undefined}\n disabled={autoCaptureLocked}\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n onToggleAutoCapture()\n }}\n >\n <span class=\"ic\">\n <CameraIcon />\n </span>\n <span class=\"lbl\">\n <span>Auto-capture screenshots</span>\n <span class=\"sub\">\n {autoCaptureLocked ? 'Turned off by this site' : 'PII fields are scrubbed'}\n </span>\n </span>\n <span class=\"switch\" aria-hidden=\"true\" />\n </button>\n\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"markup-menu-row\"\n onClick={() => {\n setOpen(false)\n onOpenPrivacy()\n }}\n >\n <span class=\"ic\">\n <IconShield size={16} />\n </span>\n <span class=\"lbl\">Privacy & data</span>\n </button>\n\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"markup-menu-row\"\n onClick={() => {\n setOpen(false)\n onOpenShortcuts()\n }}\n >\n <span class=\"ic\">\n <IconKeyboard size={16} />\n </span>\n <span class=\"lbl\">Keyboard shortcuts</span>\n </button>\n\n <div class=\"markup-menu-divider\" />\n\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"markup-menu-row\"\n onClick={() => {\n setOpen(false)\n onHideForSession()\n }}\n >\n <span class=\"ic\">\n <HideIcon />\n </span>\n <span class=\"lbl\">Hide for this session</span>\n <span class=\"right\">{modKey} .</span>\n </button>\n\n <a\n class=\"markup-brand-line\"\n href={dashboardUrl ?? 'https://markup.dev'}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <IconLogo size={12} />\n <span>Powered by Markup</span>\n <span class=\"ver\">v{version}</span>\n </a>\n </div>\n ) : null}\n </div>\n )\n}\n\n/* Small inline pictograms for the Position picker — a rounded square\n * with a dot at the picked corner. Keeps the picker icons unambiguous\n * at 14px without pulling in another icon. */\nfunction CornerIcon({ side }: { side: 'left' | 'center' | 'right' }) {\n const dotX = side === 'left' ? 4 : side === 'right' ? 12 : 8\n return (\n <svg\n width={14}\n height={14}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width={1.5}\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden\n >\n <rect x=\"2\" y=\"2\" width=\"12\" height=\"12\" rx=\"2.5\" />\n <circle cx={dotX} cy={12} r=\"1.4\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n )\n}\n\nfunction CameraIcon() {\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width={1.75}\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden\n >\n <path d=\"M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z\" />\n <circle cx=\"12\" cy=\"13\" r=\"4\" />\n </svg>\n )\n}\n\nfunction HideIcon() {\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width={1.75}\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden\n >\n <path d=\"M17.94 17.94A10.7 10.7 0 0 1 12 19c-6.5 0-10-7-10-7a18.5 18.5 0 0 1 5.06-5.94\" />\n <path d=\"M9.9 4.24A10.7 10.7 0 0 1 12 4c6.5 0 10 7 10 7a18.5 18.5 0 0 1-2.16 3.19\" />\n <path d=\"m1 1 22 22\" />\n <path d=\"M14.12 14.12a3 3 0 0 1-4.24-4.24\" />\n </svg>\n )\n}\n","import type { ComponentChildren } from 'preact'\nimport { useEffect, useRef } from 'preact/hooks'\n\nimport { cx } from '../utils'\n\ntype ToolbarPosition = 'bottom-right' | 'bottom-left' | 'bottom-center'\n\n/** Which auxiliary surface a `PanelPopover` is hosting. */\nexport type PanelKind = 'inbox' | 'privacy' | 'shortcuts'\n\n/**\n * Floating surface anchored to the toolbar's corner, used for the panels\n * that are too tall to live inside a menu: the notifications inbox, the\n * privacy summary, and the shortcut reference. Mounted by `app.tsx`\n * alongside the toolbar rather than inside it, because the toolbar's\n * `overflow: hidden` would clip anything taller than the pill.\n *\n * `kind` drives both the wrapper width (`data-panel`) and the inner\n * surface chrome (`.markup-pop[data-pop]`), so the three panels share\n * one positioning + dismissal implementation and differ only in CSS.\n *\n * Light-dismiss: clicking outside the panel or pressing Escape closes\n * it. Uses `composedPath()` to detect inside-shadow targets, same as\n * the menu components.\n */\nexport function PanelPopover({\n kind,\n label,\n position,\n ignoreToolbarKind,\n onClose,\n children,\n}: {\n kind: PanelKind\n /** Accessible name for the dialog surface. */\n label: string\n position: ToolbarPosition\n /**\n * `data-kind` of the toolbar button that toggles this panel, when it\n * has one. A click on that button must not count as an outside-click:\n * the button's own handler already toggles the panel shut, and if both\n * fired the panel would close and immediately re-open.\n */\n ignoreToolbarKind?: string\n onClose: () => void\n children: ComponentChildren\n}) {\n const containerRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n function onDocClick(e: MouseEvent) {\n const el = containerRef.current\n if (!el) return\n const path = e.composedPath()\n if (path.includes(el)) return\n if (\n ignoreToolbarKind != null &&\n path.some((n) => (n as HTMLElement)?.dataset?.kind === ignoreToolbarKind)\n ) {\n return\n }\n onClose()\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') onClose()\n }\n document.addEventListener('click', onDocClick, true)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('click', onDocClick, true)\n document.removeEventListener('keydown', onKey)\n }\n }, [onClose, ignoreToolbarKind])\n\n const sideClass =\n position === 'bottom-left'\n ? 'markup-panel-pop-left'\n : position === 'bottom-center'\n ? 'markup-panel-pop-center'\n : 'markup-panel-pop-right'\n\n return (\n <div\n ref={containerRef}\n class={cx('markup-panel-pop', sideClass)}\n data-panel={kind}\n role=\"dialog\"\n aria-label={label}\n >\n <div class=\"markup-pop\" data-pop={kind}>\n {children}\n </div>\n </div>\n )\n}\n","import { cx } from '../utils'\n\n/**\n * A single anchored pin marker. Position is set inline because it changes on\n * every render (scroll/resize) and Tailwind's compile-time classes can't\n * express dynamic pixel coords.\n */\nexport function Pin({\n pageX,\n pageY,\n count,\n isActive,\n isUnresolved,\n onClick,\n}: {\n pageX: number\n pageY: number\n count: number\n isActive: boolean\n /**\n * `true` when the pin's anchor selector didn't match a live element\n * and we're showing it at the fraction-based fallback position. Surfaces\n * a dimmed style so the wrong-looking position reads as tentative rather\n * than authoritative. Stays clickable — opening the thread is still useful\n * even if the spatial anchor is off.\n */\n isUnresolved: boolean\n onClick: () => void\n}) {\n // The host element is `position: fixed`, so subtract scroll to get\n // viewport-relative coords for `top` / `left`.\n const top = pageY - window.scrollY\n const left = pageX - window.scrollX\n // `popovertarget` tells the browser this button intentionally interacts\n // with the thread popover, so the pointerdown light-dismiss is suppressed\n // when transitioning from one open thread to another.\n return (\n <button\n type=\"button\"\n class={cx('markup-pin', isActive && 'is-active is-anchor', isUnresolved && 'is-unresolved')}\n style={{ top: `${top}px`, left: `${left}px` }}\n popovertarget=\"markup-thread-popover\"\n popovertargetaction=\"show\"\n onClick={onClick}\n aria-label={`Open feedback thread (${count} comment${count === 1 ? '' : 's'})`}\n title={`Open feedback thread (${count} comment${count === 1 ? '' : 's'})`}\n >\n <span class=\"markup-pin-num\">{count}</span>\n </button>\n )\n}\n\n/**\n * Ghost pin shown at the just-clicked location while the composer for a brand\n * new thread is open. Same visual as a real pin, no click handler. Carries\n * `is-anchor` so the new-thread popover can anchor-position to it.\n */\nexport function GhostPin({ pageX, pageY }: { pageX: number; pageY: number }) {\n const top = pageY - window.scrollY\n const left = pageX - window.scrollX\n return (\n <div\n class=\"markup-pin markup-pin-ghost is-anchor\"\n style={{ top: `${top}px`, left: `${left}px` }}\n >\n <span class=\"markup-pin-num\" aria-hidden>\n +\n </span>\n </div>\n )\n}\n","import { useLayoutEffect } from 'preact/hooks'\n\nimport { toPageCoords, type PageCoords } from '../anchor'\n\n/**\n * Full-viewport overlay that captures the next click and translates it into\n * normalised page coordinates. Mounts only while in placing mode; ESC cancels.\n */\nexport function PlacementOverlay({\n onPlace,\n onCancel,\n}: {\n onPlace: (coords: PageCoords, screenX: number, screenY: number) => void\n onCancel: () => void\n}) {\n /* Layout effect, not a plain one: `useEffect` is deferred to after\n * paint (rAF, with a 100 ms timeout fallback), so on a busy machine\n * the overlay is on screen and taking clicks for a beat before ESC\n * does anything. A user who hits ESC in that window — or an e2e test\n * that acts the moment the overlay appears — gets the key dropped and\n * stays stuck in placement mode. Registering during commit closes the\n * gap: the listener exists before the overlay is ever visible.\n *\n * Safe to bind synchronously here because it's only `keydown`. The\n * menus and panels deliberately keep the deferred effect — they also\n * bind an outside-click listener, and binding that during the very\n * click that opened them would dismiss them immediately. */\n useLayoutEffect(() => {\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') onCancel()\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [onCancel])\n\n function handleClick(e: MouseEvent) {\n e.stopPropagation()\n e.preventDefault()\n // elementsFromPoint returns light-DOM elements top-to-bottom. Our widget\n // host is the only element with a shadowRoot — skip it to get the real\n // page element underneath the overlay.\n const elements = document.elementsFromPoint(e.clientX, e.clientY)\n const pageTarget = elements.find((el) => !el.shadowRoot) ?? null\n const coords = toPageCoords(e, pageTarget)\n onPlace(coords, e.clientX, e.clientY)\n }\n\n // Prevent the click from bubbling up to the document and triggering dismiss of other elements\n // this works for Radix-UI elements like Popover and Menu\n function handlePointerDown(e: PointerEvent) {\n e.preventDefault()\n e.stopPropagation()\n }\n\n return (\n <div\n class=\"markup-placement-overlay\"\n onPointerDown={handlePointerDown}\n onClick={handleClick}\n role=\"presentation\"\n >\n <div class=\"markup-placement-cursor-help\">\n <span>Click anywhere to drop a pin · ESC to cancel</span>\n </div>\n </div>\n )\n}\n","import { useState } from 'preact/hooks'\n\nimport { displayNameOf, type IdentityState } from '../identity-store'\nimport { cx } from '../utils'\nimport { IconClose } from './icons'\n\n/**\n * Every claim here describes runtime behaviour, not policy, and reflects the\n * *current* session, so a visitor can verify it rather than take it on faith.\n * The sources are `identity-store.ts`, `api.ts#createThread`, `screenshot.ts`,\n * `error-reporter.ts` and `POST /widget/forget-me`.\n *\n * Keep the copy honest when any of those change — this is the surface end\n * users are most likely to read closely.\n */\nexport function PrivacyPanel({\n identity,\n apiUrl,\n autoCapture,\n autoCaptureLocked,\n isForgettingMe,\n forgetMeError,\n onForgetMe,\n onClose,\n}: {\n identity: IdentityState\n /** Deployment URL; only its host is shown, as the one network destination. */\n apiUrl: string\n autoCapture: boolean\n /** The host site disabled captures outright — see `OverflowMenu`. */\n autoCaptureLocked: boolean\n isForgettingMe: boolean\n forgetMeError?: string\n onForgetMe: () => void\n onClose: () => void\n}) {\n // Irreversible, on a surface people are reading rather than operating.\n const [confirmForget, setConfirmForget] = useState(false)\n\n const name = displayNameOf(identity)\n const isVerified = identity.kind === 'verified'\n const email = isVerified ? identity.identity.email : undefined\n // The endpoint authenticates with the anon token; a signed-in user's path\n // is Sign out instead.\n const canForget = identity.kind === 'anon'\n\n return (\n <div class=\"markup-panel\">\n <header class=\"markup-panel-header\">\n <span class=\"markup-eyebrow\">privacy & data</span>\n <button\n type=\"button\"\n class=\"markup-icon-btn\"\n title=\"Close\"\n aria-label=\"Close privacy and data\"\n onClick={onClose}\n >\n <IconClose size={14} />\n </button>\n </header>\n\n <div class=\"markup-panel-body\">\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">who you are here</h4>\n {isVerified ? (\n <p class=\"markup-panel-text\">\n Signed in as <strong>{name ?? 'you'}</strong>\n {email ? <span class=\"markup-panel-mono\"> {email}</span> : null}. Comments you post\n carry that name, and your email is visible to this project's team.\n </p>\n ) : name ? (\n <p class=\"markup-panel-text\">\n You post as <strong>{name}</strong> — an anonymous commenter with a random id that\n only means anything on this site.\n </p>\n ) : (\n <p class=\"markup-panel-text\">\n You're anonymous. Markup holds a random id scoped to this site and asks for a name the\n first time you post.\n </p>\n )}\n </section>\n\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">what posting sends</h4>\n <ul class=\"markup-panel-list\">\n <li>What you wrote, under the name (and email, if you gave one) you post with</li>\n <li>This page's URL, your window size, and your browser's user-agent</li>\n <li>A screenshot — only the ones you attach yourself</li>\n </ul>\n </section>\n\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">kept in this browser</h4>\n <ul class=\"markup-panel-list\">\n <li>\n {isVerified\n ? \"Your sign-in token — in this site's storage, or a cookie only this site can send\"\n : \"Your commenter id and the token that proves it, in this site's storage\"}\n </li>\n <li>Your appearance and toolbar-position picks</li>\n </ul>\n <p class=\"markup-panel-note\">\n All of it is scoped to this site, so the same browser on another site is a different\n commenter to us. Nothing here follows you between sites.\n </p>\n </section>\n\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">screenshots</h4>\n <p class=\"markup-panel-text\">\n {autoCaptureLocked\n ? 'This site turned captures off, so none are taken.'\n : autoCapture\n ? 'Captured when you drop a pin. Passwords, card numbers and one-time codes are blacked out before the image exists, and the composer lists what it covered. Nothing uploads unless you post with it attached.'\n : 'Auto-capture is off, so no screenshots are taken. You can turn it back on from the menu.'}\n </p>\n </section>\n\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">where it goes</h4>\n <p class=\"markup-panel-text\">\n Only <span class=\"markup-panel-mono\">{apiHostOf(apiUrl)}</span>. No analytics, no ad\n tech, no third-party requests from the widget. If the widget itself crashes it posts the\n error, this page's URL and your user-agent to that same host — never your identity or\n what you were writing.\n </p>\n </section>\n\n {canForget ? (\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">erase what you left</h4>\n <p class=\"markup-panel-text\">\n Removes every comment and reaction this browser posted on this site, and clears the\n name and email held for you. Replies from other people stay.\n </p>\n <button\n type=\"button\"\n class={cx('markup-panel-action', confirmForget && 'is-danger')}\n disabled={isForgettingMe}\n onClick={() => {\n if (confirmForget) {\n onForgetMe()\n setConfirmForget(false)\n } else {\n setConfirmForget(true)\n }\n }}\n >\n {isForgettingMe\n ? 'Erasing…'\n : confirmForget\n ? 'Confirm — erase and forget me'\n : 'Forget me on this site…'}\n </button>\n {forgetMeError ? <p class=\"markup-panel-error\">{forgetMeError}</p> : null}\n </section>\n ) : null}\n </div>\n </div>\n )\n}\n\n/**\n * Falls back to the raw string: the value comes from the host's own `init()`\n * config, so a malformed one is theirs to see rather than hide.\n */\nfunction apiHostOf(apiUrl: string): string {\n try {\n return new URL(apiUrl).host\n } catch {\n return apiUrl\n }\n}\n","import { platformKeys } from '../utils'\nimport { IconClose } from './icons'\n\n/**\n * Keyboard reference for the widget, opened from the overflow menu's\n * **Keyboard shortcuts** row. Renders inside a `PanelPopover` anchored\n * to the toolbar corner.\n *\n * The rows are the shortcuts the runtime actually implements — every\n * entry below maps to a live handler:\n *\n * - `c` / `mod .` — `app.tsx` window keydown listeners\n * - `Esc` — `placement-overlay.tsx` (cancel) and the menu/panel\n * light-dismiss handlers; the mention picker consumes it first\n * while a composer's `@` list is open (`mentions.tsx`)\n * - `@`, arrows, `Enter`/`Tab` — `mentions.tsx#handleKeyDown`\n * - `mod Enter` — `composer.tsx#onKey`\n *\n * Chord labels come from `platformKeys()` so Windows and Linux readers\n * see `Ctrl`/`Enter` where a Mac reader sees `⌘`/`↵`.\n */\nexport function ShortcutsPanel({ onClose }: { onClose: () => void }) {\n const { mod, enter } = platformKeys()\n\n /* Each shortcut lists one or more chords, joined by \"or\" — the picker\n * accepts Enter *or* Tab, for instance, and both belong on one row. */\n const groups: { title: string; items: { chords: string[][]; label: string }[] }[] = [\n {\n title: 'on the page',\n items: [\n { chords: [['c']], label: 'Start a markup' },\n { chords: [[mod, '.']], label: 'Show or hide Markup' },\n { chords: [['Esc']], label: 'Cancel placement, or close a menu' },\n ],\n },\n {\n title: 'while writing',\n items: [\n { chords: [['@']], label: 'Mention a teammate' },\n { chords: [['↑'], ['↓']], label: 'Move through the member list' },\n { chords: [[enter], ['Tab']], label: 'Pick the highlighted member' },\n { chords: [[mod, enter]], label: 'Post the comment' },\n { chords: [['Esc']], label: 'Dismiss the member list' },\n ],\n },\n ]\n\n return (\n <div class=\"markup-panel\">\n <header class=\"markup-panel-header\">\n <span class=\"markup-eyebrow\">keyboard shortcuts</span>\n <button\n type=\"button\"\n class=\"markup-icon-btn\"\n title=\"Close\"\n aria-label=\"Close keyboard shortcuts\"\n onClick={onClose}\n >\n <IconClose size={14} />\n </button>\n </header>\n\n <div class=\"markup-panel-body\">\n {groups.map((group) => (\n <section key={group.title} class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">{group.title}</h4>\n <ul class=\"markup-shortcut-list\">\n {group.items.map((item) => (\n <li key={item.label} class=\"markup-shortcut-row\">\n <span class=\"markup-shortcut-label\">{item.label}</span>\n <span class=\"markup-shortcut-keys\">\n {item.chords.map((chord, i) => (\n <span key={chord.join('+')} class=\"markup-shortcut-chord\">\n {i > 0 ? <span class=\"markup-shortcut-or\">or</span> : null}\n {chord.map((key) => (\n <kbd key={key} class=\"markup-kbd is-inline\">\n {key}\n </kbd>\n ))}\n </span>\n ))}\n </span>\n </li>\n ))}\n </ul>\n </section>\n ))}\n\n <p class=\"markup-panel-note\">\n {mod}-click the comment button to hide Markup without opening the menu. Drag a popover's\n header to move it off whatever it covers.\n </p>\n </div>\n </div>\n )\n}\n","import { useEffect, useMemo, useRef, useState } from 'preact/hooks'\n\nimport { defineMachine, useMachine } from '../../lib/machine'\nimport { resolveCoords } from '../anchor'\nimport { useDrag } from '../use-drag'\nimport { useFocusTrap } from '../use-focus-trap'\nimport { cx } from '../utils'\nimport { AuthorPrompt } from './author-prompt'\nimport { Composer } from './composer'\nimport { IconBot, IconCheck, IconClose, IconEllipsis, IconSmile } from './icons'\nimport { MentionInput } from './mention-input'\nimport { MentionizedBody, type MentionableMember } from './mentions'\nimport type { WidgetThread } from '../api'\n\n/**\n * Must stay in sync with `convex/lib/reactions.ts`, which validates against the\n * same list and sorts chips by this order so chips and picker line up.\n */\nconst REACTION_PALETTE = ['👍', '❤️', '🎉', '😮', '😄', '❓'] as const\n\n/**\n * A union so the four overlays are mutually exclusive by construction: opening\n * one atomically closes the others. Confirm-delete arming and menu direction\n * live inside their parent overlay, so they reset for free when it closes.\n */\ntype Overlay =\n | { kind: 'none' }\n | { kind: 'thread-menu'; confirmDelete: boolean }\n | {\n kind: 'comment-menu'\n commentId: string\n direction: 'down' | 'up'\n confirmDelete: boolean\n }\n | { kind: 'reaction-picker'; commentId: string; direction: 'down' | 'up' }\n | { kind: 'editing'; commentId: string; draft: string }\n\n/**\n * `toggle-*` opens from `none` and closes from the matching kind. `arm-*-delete`\n * is the first half of confirm-delete; the second half fires the host callback\n * and dispatches `dismiss`. Direction is computed at the call site so these\n * transitions need no DOM access.\n */\ntype OverlayEvent =\n | { type: 'toggle-thread-menu' }\n | { type: 'arm-thread-delete' }\n | { type: 'toggle-comment-menu'; commentId: string; direction: 'down' | 'up' }\n | { type: 'arm-comment-delete' }\n | { type: 'toggle-reaction-picker'; commentId: string; direction: 'down' | 'up' }\n | { type: 'start-edit'; commentId: string; body: string }\n | { type: 'update-draft'; draft: string }\n | { type: 'dismiss' }\n\nconst overlayMachine = defineMachine<Overlay, OverlayEvent>({\n none: {\n 'toggle-thread-menu': () => ({ kind: 'thread-menu', confirmDelete: false }),\n 'toggle-comment-menu': (_, e) => ({\n kind: 'comment-menu',\n commentId: e.commentId,\n direction: e.direction,\n confirmDelete: false,\n }),\n 'toggle-reaction-picker': (_, e) => ({\n kind: 'reaction-picker',\n commentId: e.commentId,\n direction: e.direction,\n }),\n 'start-edit': (_, e) => ({ kind: 'editing', commentId: e.commentId, draft: e.body }),\n },\n 'thread-menu': {\n 'toggle-thread-menu': () => ({ kind: 'none' }),\n 'arm-thread-delete': (s) => ({ ...s, confirmDelete: true }),\n dismiss: () => ({ kind: 'none' }),\n },\n 'comment-menu': {\n // Only the matching comment can re-toggle; the outside-click effect\n // already closes this before a foreign click lands.\n 'toggle-comment-menu': (s, e) => (s.commentId === e.commentId ? { kind: 'none' } : s),\n 'arm-comment-delete': (s) => ({ ...s, confirmDelete: true }),\n // Straight into the edit form: the menu is already open on this comment,\n // so a dismiss step would just be visual churn.\n 'start-edit': (_, e) => ({ kind: 'editing', commentId: e.commentId, draft: e.body }),\n dismiss: () => ({ kind: 'none' }),\n },\n 'reaction-picker': {\n 'toggle-reaction-picker': (s, e) => (s.commentId === e.commentId ? { kind: 'none' } : s),\n dismiss: () => ({ kind: 'none' }),\n },\n editing: {\n // The machine ignores `update-draft` from any other state, so no guard.\n 'update-draft': (s, e) => ({ ...s, draft: e.draft }),\n dismiss: () => ({ kind: 'none' }),\n },\n})\n\n/**\n * `popover=\"auto\"` supplies top-layer rendering, ESC and outside-click\n * dismissal. Position falls back to JS-clamped coords in custom properties\n * where CSS Anchor Positioning isn't supported.\n */\nexport function ThreadPopover({\n thread,\n authorName,\n currentClientId,\n isVerified,\n isIdentityResolving,\n isSigningIn,\n canDelete,\n isPending,\n error,\n isHidden = false,\n members = [],\n onAuthor,\n onSignIn,\n onClose,\n onReply,\n onEditComment,\n onDeleteComment,\n onToggleReaction,\n onResolve,\n onDelete,\n}: {\n thread: WidgetThread\n authorName: string | null\n /**\n * Decides which comments show Edit. Matching `authorClientId` is sufficient\n * because the JWT path uses the same canonical `markup_user_<sub>` form.\n */\n currentClientId: string | null\n isVerified: boolean\n /** Anon mint hasn't completed yet — disable the guest path. */\n isIdentityResolving: boolean\n /** A popup sign-in is already in flight — disable the sign-in button. */\n isSigningIn: boolean\n canDelete: boolean\n isPending: boolean\n error: string | undefined\n /** Kept mounted so a draft, edit or drag position survives a HUD peek. */\n isHidden?: boolean\n /** Empty disables the picker. */\n members?: readonly MentionableMember[]\n onAuthor: (name: string, email?: string) => void\n onSignIn: () => void\n onClose: () => void\n onReply: (body: string) => void\n /** Must reject on failure, or the form closes over an unsaved draft. */\n onEditComment: (commentId: string, body: string) => Promise<void>\n onDeleteComment: (commentId: string) => void\n /** No optimistic update — the host swaps in the server's response. */\n onToggleReaction: (commentId: string, emoji: string) => void\n onResolve: () => void\n onDelete: () => void\n}) {\n const ref = useRef<HTMLDivElement>(null)\n const commentsRef = useRef<HTMLOListElement>(null)\n const dialogRef = useRef<HTMLDialogElement>(null)\n // Written by whichever overlay is active, via a gated inline ref callback,\n // and read by the single outside-click effect below.\n const overlayElRef = useRef<HTMLElement | null>(null)\n const [overlay, sendOverlay] = useMachine(overlayMachine, { kind: 'none' })\n // `null` means anchor/fallback coords. Resets on mount, so reopening a\n // thread snaps the popover back to its pin.\n const [dragPos, setDragPos] = useState<{ left: number; top: number } | null>(null)\n // The handle is the header, but the measured target is the popover — that's\n // what moves. Buttons are excluded so their clicks still work.\n const { onPointerDown: onHeaderPointerDown, isDragging } = useDrag({\n targetRef: ref,\n shouldStart: (e) => {\n const target = e.target as HTMLElement | null\n return !target?.closest('button, a, input, textarea, select')\n },\n onMove: setDragPos,\n })\n useFocusTrap(ref, true)\n\n const isResolved = thread.resolvedAt != null\n // Soft-delete exists for referential integrity, not display. The server's\n // first-comment guard still uses the real earliest comment, so a deleted row\n // preceding everything visible can't be deleted by mistake.\n const visibleComments = useMemo(\n () => thread.comments.filter((c) => !c.deleted),\n [thread.comments],\n )\n\n // One handler for all four overlays, reading whichever element is active.\n // Closing resets confirm-delete arming for free, since that lives inside\n // the overlay's own state.\n useEffect(() => {\n if (overlay.kind === 'none' || overlay.kind === 'editing') return\n function onDown(e: MouseEvent) {\n const el = overlayElRef.current\n if (el && !e.composedPath().includes(el)) {\n sendOverlay({ type: 'dismiss' })\n }\n }\n document.addEventListener('mousedown', onDown)\n return () => document.removeEventListener('mousedown', onDown)\n }, [overlay.kind, sendOverlay])\n\n // Only for a comment that vanished. A failed save leaves the draft intact,\n // because the submit handler cancels on resolve rather than on settle.\n useEffect(() => {\n if (overlay.kind !== 'editing') return\n const c = thread.comments.find((c) => c._id === overlay.commentId)\n if (!c || c.deleted) sendOverlay({ type: 'dismiss' })\n }, [thread.comments, overlay, sendOverlay])\n\n const isFirstOpen = useRef(true)\n useEffect(() => {\n const el = commentsRef.current\n if (!el) return\n if (isFirstOpen.current) {\n isFirstOpen.current = false\n el.scrollTop = el.scrollHeight\n return\n }\n const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight\n if (distanceFromBottom < 80) el.scrollTop = el.scrollHeight\n }, [visibleComments.length])\n\n // Sync state back when the browser closes it — ESC, outside click.\n useEffect(() => {\n const el = ref.current\n if (!el) return\n\n if (typeof el.showPopover === 'function' && !el.matches(':popover-open')) {\n try {\n el.showPopover()\n } catch {\n /* element may already be showing or unsupported */\n }\n }\n\n function onToggle(e: Event) {\n const ev = e as ToggleEvent\n if (ev.newState === 'closed') onClose()\n }\n el.addEventListener('toggle', onToggle)\n return () => el.removeEventListener('toggle', onToggle)\n }, [onClose])\n\n // Fallback coords for browsers without anchor positioning.\n const fallback = useMemo(() => {\n const point = resolveCoords({\n anchorX: thread.anchorX,\n anchorY: thread.anchorY,\n anchorSelector: thread.anchorSelector,\n })\n const width = 320\n const margin = 12\n const left = clamp(\n point.pageX - window.scrollX + 16,\n margin,\n window.innerWidth - width - margin,\n )\n const top = clamp(point.pageY - window.scrollY - 16, margin, window.innerHeight - 200)\n return { left, top }\n }, [thread.anchorX, thread.anchorY, thread.anchorSelector])\n\n return (\n <div\n ref={ref}\n id=\"markup-thread-popover\"\n class={cx(\n 'markup-popover',\n dragPos && 'is-floating',\n isDragging && 'is-dragging',\n isHidden && 'is-hud-hidden',\n )}\n popover=\"auto\"\n style={{\n '--markup-pop-x': `${dragPos?.left ?? fallback.left}px`,\n '--markup-pop-y': `${dragPos?.top ?? fallback.top}px`,\n }}\n role=\"dialog\"\n aria-label=\"Markup thread\"\n aria-hidden={isHidden || undefined}\n >\n <header class=\"markup-popover-header\" onPointerDown={onHeaderPointerDown}>\n {/* Not the URL. The widget only ever shows threads for the page\n you are already on, so the address was telling you something\n you could read in your own address bar — and it was the one\n piece of the header that could not be shortened, since the\n host must render in full to mean anything. The count is what\n the pin you clicked was showing, so the header now confirms\n you opened the right one. Full URL stays on hover for a\n popover dragged away from its pin. */}\n <span class=\"markup-popover-title\" title={thread.url}>\n {visibleComments.length === 1 ? '1 comment' : `${visibleComments.length} comments`}\n </span>\n <div class=\"markup-popover-header-actions\">\n <div\n class=\"markup-thread-menu\"\n ref={(el) => {\n if (overlay.kind === 'thread-menu') overlayElRef.current = el\n }}\n >\n <button\n type=\"button\"\n class={cx('markup-icon-btn', overlay.kind === 'thread-menu' && 'is-open')}\n title=\"More options\"\n onClick={() => sendOverlay({ type: 'toggle-thread-menu' })}\n >\n <IconEllipsis size={16} />\n </button>\n {overlay.kind === 'thread-menu' ? (\n <div class=\"markup-thread-menu-list\">\n <button\n type=\"button\"\n class=\"markup-thread-menu-item\"\n onClick={() => {\n const url = new URL(thread.url)\n url.hash = `markup-thread=${thread._id}`\n navigator.clipboard.writeText(url.toString()).catch(() => {})\n sendOverlay({ type: 'dismiss' })\n }}\n >\n Copy link\n </button>\n {canDelete ? (\n <button\n type=\"button\"\n class={cx('markup-thread-menu-item', overlay.confirmDelete && 'is-danger')}\n disabled={isPending}\n onClick={() => {\n // Two-step: first click arms (confirmDelete: true),\n // second click commits via the host then dismisses.\n if (overlay.kind !== 'thread-menu') return\n if (overlay.confirmDelete) {\n sendOverlay({ type: 'dismiss' })\n onDelete()\n } else {\n sendOverlay({ type: 'arm-thread-delete' })\n }\n }}\n >\n {overlay.confirmDelete ? 'Confirm delete' : 'Delete thread…'}\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n {isVerified ? (\n <button\n type=\"button\"\n class=\"markup-icon-btn\"\n title=\"Mark as resolved\"\n disabled={isPending}\n onClick={onResolve}\n >\n <IconCheck size={16} />\n </button>\n ) : null}\n <button type=\"button\" class=\"markup-icon-btn\" title=\"Close thread\" onClick={onClose}>\n <IconClose size={16} />\n </button>\n </div>\n </header>\n\n <ol ref={commentsRef} class=\"markup-comments\">\n {visibleComments.map((c, i) => {\n const isOwn =\n !c.fromDashboard && currentClientId != null && c.authorClientId === currentClientId\n const isFirst = i === 0\n const canEdit = isOwn && !isResolved && !c.deleted\n const canDelete = isOwn && !isResolved && !c.deleted && !isFirst\n const isEditing = overlay.kind === 'editing' && overlay.commentId === c._id\n const hasMenu = (canEdit || canDelete) && !isEditing && !c.deleted\n const isMenuOpen = overlay.kind === 'comment-menu' && overlay.commentId === c._id\n const isDeletePending = isMenuOpen && overlay.confirmDelete\n const isPickerOpen = overlay.kind === 'reaction-picker' && overlay.commentId === c._id\n const pickerDirection = isPickerOpen ? overlay.direction : 'down'\n const menuDirection = isMenuOpen ? overlay.direction : 'down'\n return (\n <li key={c._id} class=\"markup-comment\">\n <CommentAvatar\n name={c.authorName}\n image={c.authorImage}\n tone={authorTone(c.authorClientId ?? c.authorName)}\n />\n <div class=\"markup-comment-meta\">\n <span class=\"markup-comment-author\">{c.authorName}</span>\n {/* Nothing here marks the author as team. `fromDashboard`\n is only \"the author had no host page\", which lumps\n dashboard replies in with agent writes, so neither the\n badge nor the name tint it used to drive said anything\n a reader could act on. The field itself stays — the\n `isOwn` check above needs it — it just no longer\n decides how the author renders.\n\n Human vs. agent is the distinction that matters to\n someone reading a reply, and this badge carries it:\n the comment has a real person's name on it, so a\n visitor must be able to tell a machine wrote it. */}\n {c.authoredVia === 'mcp' ? (\n <span\n class=\"markup-comment-badge is-agent\"\n role=\"img\"\n aria-label=\"Written by an AI agent\"\n title=\"Written by an AI agent\"\n >\n <IconBot size={11} />\n </span>\n ) : null}\n <time\n class=\"markup-comment-time\"\n datetime={new Date(c.createdAt).toISOString()}\n title={formatTime(c.createdAt)}\n >\n {relativeTime(c.createdAt)}\n </time>\n {c.editedAt != null ? (\n <time\n class=\"markup-comment-edited\"\n datetime={new Date(c.editedAt).toISOString()}\n title={formatTime(c.editedAt)}\n >\n edited\n </time>\n ) : null}\n <div class=\"markup-thread-actions\">\n {!isResolved && !isEditing ? (\n <ReactionAdd\n comment={c}\n pickerOpen={isPickerOpen}\n pickerDirection={pickerDirection}\n pickerSide={visibleComments.length === 1}\n pickerRef={(el) => {\n if (isPickerOpen) overlayElRef.current = el\n }}\n onPickerClick={(e) => {\n if (isPickerOpen) {\n sendOverlay({\n type: 'toggle-reaction-picker',\n commentId: c._id,\n direction: 'down',\n })\n return\n }\n // With a single comment the popover is too short\n // for a vertical picker to fit; we anchor it to\n // the left of the trigger instead (see `.is-side`).\n if (visibleComments.length === 1) {\n sendOverlay({\n type: 'toggle-reaction-picker',\n commentId: c._id,\n direction: 'down',\n })\n return\n }\n // Same flip-above measurement as the comment menu\n // — the picker is taller (one row of 6 chips\n // ~36px), so we account for that explicitly.\n const trigger = e.currentTarget as HTMLElement\n const triggerRect = trigger.getBoundingClientRect()\n const containerRect = commentsRef.current?.getBoundingClientRect()\n const estimatedHeight = 44\n const spaceBelow = containerRect\n ? containerRect.bottom - triggerRect.bottom\n : Number.POSITIVE_INFINITY\n sendOverlay({\n type: 'toggle-reaction-picker',\n commentId: c._id,\n direction: spaceBelow < estimatedHeight ? 'up' : 'down',\n })\n }}\n onPickerSelect={(emoji) => {\n sendOverlay({ type: 'dismiss' })\n onToggleReaction(c._id, emoji)\n }}\n />\n ) : null}\n {hasMenu ? (\n <div\n class={cx(\n 'markup-thread-menu markup-comment-menu',\n isMenuOpen && 'is-open',\n isMenuOpen && menuDirection === 'up' && 'is-up',\n visibleComments.length === 1 && 'is-side',\n )}\n ref={(el: HTMLDivElement | null) => {\n if (isMenuOpen) overlayElRef.current = el\n }}\n >\n <button\n type=\"button\"\n class={cx('markup-icon-btn', isMenuOpen && 'is-open')}\n title=\"More options\"\n onClick={(e) => {\n if (isMenuOpen) {\n sendOverlay({\n type: 'toggle-comment-menu',\n commentId: c._id,\n direction: 'down',\n })\n return\n }\n // With a single comment, the popover is too short\n // for a vertical dropdown to fit, so we open it to\n // the left of the trigger (see `.is-side` in CSS)\n // and skip the up/down measurement entirely.\n if (visibleComments.length === 1) {\n sendOverlay({\n type: 'toggle-comment-menu',\n commentId: c._id,\n direction: 'down',\n })\n return\n }\n // Decide direction before opening so the dropdown\n // never appears clipped at the bottom of the scroll\n // container. Estimate menu height from the visible\n // items (~32px per item + 8px padding).\n const trigger = e.currentTarget as HTMLElement\n const triggerRect = trigger.getBoundingClientRect()\n const containerRect = commentsRef.current?.getBoundingClientRect()\n const itemCount = (canEdit ? 1 : 0) + (canDelete ? 1 : 0)\n const estimatedHeight = itemCount * 32 + 8 + 6\n const spaceBelow = containerRect\n ? containerRect.bottom - triggerRect.bottom\n : Number.POSITIVE_INFINITY\n sendOverlay({\n type: 'toggle-comment-menu',\n commentId: c._id,\n direction: spaceBelow < estimatedHeight ? 'up' : 'down',\n })\n }}\n >\n <IconEllipsis size={16} />\n </button>\n {isMenuOpen ? (\n <div class=\"markup-thread-menu-list\">\n {canEdit ? (\n <button\n type=\"button\"\n class=\"markup-thread-menu-item\"\n onClick={() => {\n sendOverlay({\n type: 'start-edit',\n commentId: c._id,\n body: c.body,\n })\n }}\n >\n Edit\n </button>\n ) : null}\n {canDelete ? (\n <button\n type=\"button\"\n class={cx('markup-thread-menu-item', isDeletePending && 'is-danger')}\n onClick={() => {\n if (overlay.kind !== 'comment-menu') return\n if (overlay.confirmDelete) {\n sendOverlay({ type: 'dismiss' })\n onDeleteComment(c._id)\n } else {\n sendOverlay({ type: 'arm-comment-delete' })\n }\n }}\n >\n {isDeletePending ? 'Confirm delete' : 'Delete…'}\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n </div>\n {isEditing && overlay.kind === 'editing' ? (\n <form\n class=\"markup-comment-edit-form\"\n onSubmit={async (e) => {\n e.preventDefault()\n if (overlay.kind !== 'editing') return\n const next = overlay.draft.trim()\n if (!next || next === c.body) {\n sendOverlay({ type: 'dismiss' })\n return\n }\n try {\n await onEditComment(c._id, next)\n sendOverlay({ type: 'dismiss' })\n } catch {\n /* leave the form open so the user can fix and retry;\n * the host renders the error toast from `error`. */\n }\n }}\n >\n {/* Same editor as the composer, so an existing comment's\n * mentions show as chips while being edited rather than\n * reverting to raw markers — and new ones can be added. */}\n <MentionInput\n class=\"markup-comment-edit-input\"\n label=\"Edit comment\"\n value={overlay.draft}\n onChange={(draft) => sendOverlay({ type: 'update-draft', draft })}\n members={members}\n autoFocus\n disabled={isPending}\n />\n <div class=\"markup-comment-edit-actions\">\n <button\n type=\"button\"\n class=\"markup-btn markup-btn-ghost\"\n onClick={() => sendOverlay({ type: 'dismiss' })}\n disabled={isPending}\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n class=\"markup-btn markup-btn-primary\"\n disabled={isPending || overlay.draft.trim().length === 0}\n >\n Save\n </button>\n </div>\n </form>\n ) : (\n <MentionizedBody body={c.body} mentions={c.mentions} />\n )}\n {i === 0 && thread.screenshotUrl ? (\n <button\n type=\"button\"\n class=\"markup-comment-screenshot\"\n onClick={() => dialogRef.current?.showModal()}\n >\n <img src={thread.screenshotUrl} alt=\"Screenshot\" />\n </button>\n ) : null}\n {!isEditing && c.reactions.length > 0 ? (\n <ReactionChips\n comment={c}\n isResolved={isResolved}\n onToggle={(emoji) => onToggleReaction(c._id, emoji)}\n />\n ) : null}\n </li>\n )\n })}\n </ol>\n\n {thread.screenshotUrl ? (\n <dialog ref={dialogRef} class=\"markup-lightbox\" onClick={() => dialogRef.current?.close()}>\n <button\n type=\"button\"\n class=\"markup-lightbox-close markup-icon-btn\"\n aria-label=\"Close screenshot\"\n onClick={(e) => {\n e.stopPropagation()\n dialogRef.current?.close()\n }}\n >\n <IconClose size={16} />\n </button>\n <img\n class=\"markup-lightbox-img\"\n src={thread.screenshotUrl}\n alt=\"Screenshot\"\n onClick={(e) => e.stopPropagation()}\n />\n </dialog>\n ) : null}\n\n {authorName == null ? (\n <AuthorPrompt\n isPending={isPending}\n isConnecting={isIdentityResolving}\n isSigningIn={isSigningIn}\n onSubmit={onAuthor}\n onCancel={onClose}\n onSignIn={onSignIn}\n />\n ) : (\n <div class=\"markup-popover-body\">\n <p class=\"markup-popover-byline\">\n replying as <span class=\"markup-popover-name\">{authorName}</span>\n {isVerified ? <span class=\"markup-comment-badge\">team</span> : null}\n </p>\n <Composer\n label=\"Reply\"\n placeholder=\"Write a reply…\"\n submitLabel=\"Reply\"\n initialFocus={false}\n isPending={isPending}\n error={error}\n onSubmit={onReply}\n members={members}\n />\n </div>\n )}\n </div>\n )\n}\n\n/**\n * The \"+\" reaction trigger that lives at the right end of the comment\n * body row. Hidden by default and revealed on comment hover (or while\n * the picker is open) so the row stays visually quiet for unreacted\n * comments. Resolved threads omit it entirely.\n */\nfunction ReactionAdd({\n comment,\n pickerOpen,\n pickerDirection,\n pickerSide,\n pickerRef,\n onPickerClick,\n onPickerSelect,\n}: {\n comment: WidgetThread['comments'][number]\n pickerOpen: boolean\n pickerDirection: 'down' | 'up'\n pickerSide: boolean\n pickerRef: (el: HTMLDivElement | null) => void\n onPickerClick: (e: MouseEvent) => void\n onPickerSelect: (emoji: string) => void\n}) {\n return (\n <div\n class={cx(\n 'markup-reaction-picker-wrap',\n pickerOpen && 'is-open',\n pickerOpen && pickerDirection === 'up' && 'is-up',\n pickerSide && 'is-side',\n )}\n ref={pickerRef}\n >\n <button\n type=\"button\"\n class={cx('markup-icon-btn', pickerOpen && 'is-open')}\n title=\"Add reaction\"\n aria-label=\"Add reaction\"\n onClick={onPickerClick}\n >\n <IconSmile size={16} />\n </button>\n {pickerOpen ? (\n <div class=\"markup-reaction-picker\" role=\"menu\">\n {REACTION_PALETTE.map((emoji) => {\n const mine = comment.reactions.find((r) => r.emoji === emoji)?.mine ?? false\n return (\n <button\n key={emoji}\n type=\"button\"\n role=\"menuitem\"\n class={cx('markup-reaction-picker-item', mine && 'is-mine')}\n onClick={() => onPickerSelect(emoji)}\n >\n {emoji}\n </button>\n )\n })}\n </div>\n ) : null}\n </div>\n )\n}\n\n/**\n * Chip strip rendered below the comment body when at least one\n * reaction exists. Resolved threads still render the chips so the\n * history is readable, but each chip is non-interactive.\n */\nfunction ReactionChips({\n comment,\n isResolved,\n onToggle,\n}: {\n comment: WidgetThread['comments'][number]\n isResolved: boolean\n onToggle: (emoji: string) => void\n}) {\n return (\n <div class=\"markup-reactions\">\n {comment.reactions.map((r) => {\n const tooltip = formatReactors(r.reactors, r.mine, r.count, r.emoji)\n return (\n <button\n key={r.emoji}\n type=\"button\"\n class={cx('markup-reaction-chip', r.mine && 'is-mine')}\n disabled={isResolved}\n onClick={() => onToggle(r.emoji)}\n aria-pressed={r.mine}\n aria-label={tooltip}\n title={tooltip}\n >\n <span class=\"markup-reaction-emoji\" aria-hidden>\n {r.emoji}\n </span>\n <span class=\"markup-reaction-count\">{r.count}</span>\n </button>\n )\n })}\n </div>\n )\n}\n\n/**\n * Builds the chip tooltip: \"Alice, Bob and you reacted with 👍\".\n * The server already strips the viewer's own row from `reactors`, so\n * `mine` is the only signal that adds \"you\". `count` may exceed\n * `reactors.length + (mine ? 1 : 0)` when anon reactors didn't supply\n * a name — those collapse into an \"and N other(s)\" clause so the\n * tooltip and the chip count always agree.\n */\nfunction formatReactors(reactors: string[], mine: boolean, count: number, emoji: string): string {\n const parts: string[] = reactors.slice()\n const accountedFor = parts.length + (mine ? 1 : 0)\n const anonExtra = Math.max(0, count - accountedFor)\n if (anonExtra > 0) {\n parts.push(`${anonExtra} other${anonExtra === 1 ? '' : 's'}`)\n }\n if (mine) parts.push('you')\n if (parts.length === 0) return `${count} reacted with ${emoji}`\n const subject =\n parts.length === 1\n ? parts[0]\n : `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`\n return `${subject} reacted with ${emoji}`\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value))\n}\n\n/**\n * Author avatar: the profile picture when the server sent one, initials\n * otherwise.\n *\n * The picture is a third-party URL (whatever the identity provider hosts),\n * loaded inside somebody else's page — so a host CSP, an ad blocker, or a\n * rotated URL can all make it fail, and falling back to initials on `error`\n * is the difference between a name-tinted circle and a broken-image glyph.\n * `no-referrer` keeps the host page's URL out of the request: a customer's\n * internal admin URLs are not the avatar CDN's business.\n *\n * `failed` is keyed off the URL so a re-render with a different author\n * (Preact reuses the node) starts out trusting the new image again.\n */\nfunction CommentAvatar({ name, image, tone }: { name: string; image?: string; tone: number }) {\n const [failedUrl, setFailedUrl] = useState<string | null>(null)\n const showImage = image != null && failedUrl !== image\n return (\n <span class=\"markup-comment-avatar\" data-tone={tone} aria-hidden>\n {showImage ? (\n <img\n class=\"markup-avatar-img\"\n src={image}\n alt=\"\"\n loading=\"lazy\"\n decoding=\"async\"\n referrerpolicy=\"no-referrer\"\n onError={() => setFailedUrl(image)}\n />\n ) : (\n <span class=\"markup-avatar-initials\">{authorInitials(name)}</span>\n )}\n </span>\n )\n}\n\nfunction authorInitials(name: string): string {\n const trimmed = name.trim()\n if (!trimmed) return '??'\n const parts = trimmed.split(/\\s+/).filter(Boolean)\n const first = parts[0] ?? ''\n if (parts.length === 1) return first.slice(0, 2).toUpperCase()\n const last = parts[parts.length - 1] ?? ''\n return ((first[0] ?? '') + (last[0] ?? '')).toUpperCase()\n}\n\n// Stable 1..5 bucket from the seed string so the same author always\n// gets the same avatar color across renders and reloads.\nfunction authorTone(seed: string): number {\n let h = 0\n for (let i = 0; i < seed.length; i++) h = (h * 31 + seed.charCodeAt(i)) | 0\n return (Math.abs(h) % 5) + 1\n}\n\nfunction relativeTime(ts: number): string {\n const diff = Date.now() - ts\n const sec = Math.floor(diff / 1000)\n if (sec < 60) return 'just now'\n const min = Math.floor(sec / 60)\n if (min < 60) return `${min} minute${min === 1 ? '' : 's'} ago`\n const hr = Math.floor(min / 60)\n if (hr < 24) return `${hr} hour${hr === 1 ? '' : 's'} ago`\n const day = Math.floor(hr / 24)\n if (day < 30) return `${day} day${day === 1 ? '' : 's'} ago`\n const isSameYear = new Date(ts).getFullYear() === new Date().getFullYear()\n if (isSameYear) {\n return new Date(ts).toLocaleDateString([], {\n month: 'long',\n day: 'numeric',\n })\n }\n return new Date(ts).toLocaleDateString([], {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n })\n}\n\nfunction formatTime(ts: number): string {\n const date = new Date(ts)\n return date.toLocaleDateString([], {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n })\n}\n","import type { ComponentChildren } from 'preact'\n\nimport { cx } from '../utils'\nimport { IconClose, IconComment, IconEye, IconEyeOff, IconInbox, IconMenu } from './icons'\n\ntype ToolbarPosition = 'bottom-right' | 'bottom-left' | 'bottom-center'\n\n/**\n * In placement mode the comment button flips to Cancel and stays armed, so\n * dismissing doesn't require hitting a different target.\n *\n * The identity and overflow slots are rendered by the host so each owns its\n * own popover positioning; the toolbar only knows where to drop them.\n */\nexport function Toolbar({\n isActive,\n onToggle,\n onHide,\n position = 'bottom-right',\n unreadCount = 0,\n showInbox = false,\n onOpenInbox,\n inboxOpen = false,\n pinsVisible = true,\n onTogglePins,\n identityButton,\n overflowButton,\n}: {\n isActive: boolean\n onToggle: () => void\n /** A discoverable mouse path to the same thing ⌘. does. */\n onHide?: () => void\n position?: ToolbarPosition\n /** Badged on the inbox button when > 0. */\n unreadCount?: number\n /** False for anon visitors, who have no inbox to surface. */\n showInbox?: boolean\n onOpenInbox?: () => void\n /** Drives the \"on\" highlight on the inbox button while its popover is up. */\n inboxOpen?: boolean\n /** The host owns the pin layer; this is only the affordance. */\n pinsVisible?: boolean\n onTogglePins?: () => void\n /** Rendered inside the pill so its popover can anchor to the button. */\n identityButton?: ComponentChildren\n /** Slot for the overflow menu (anchor + popover). */\n overflowButton?: ComponentChildren\n}) {\n const sideClass =\n position === 'bottom-left'\n ? 'markup-toolbar-left'\n : position === 'bottom-center'\n ? 'markup-toolbar-center'\n : 'markup-toolbar-right'\n\n function handleCommentClick(e: MouseEvent) {\n e.preventDefault()\n e.stopPropagation()\n if ((e.metaKey || e.ctrlKey) && onHide) {\n onHide()\n return\n }\n onToggle()\n }\n\n return (\n <div\n class={cx('markup-toolbar', sideClass)}\n role=\"toolbar\"\n aria-label=\"Markup feedback toolbar\"\n >\n <button\n type=\"button\"\n class=\"markup-tb-btn\"\n data-kind=\"comment\"\n data-armed={isActive ? 'true' : undefined}\n title={isActive ? 'Cancel placing markup' : 'Leave a markup'}\n aria-pressed={isActive}\n onClick={handleCommentClick}\n >\n {isActive ? <IconClose size={16} /> : <IconComment size={16} />}\n </button>\n\n {showInbox ? (\n <button\n type=\"button\"\n class=\"markup-tb-btn\"\n data-kind=\"inbox\"\n data-on={inboxOpen ? 'true' : undefined}\n title={unreadCount > 0 ? `Inbox, ${unreadCount} unread` : 'Inbox'}\n aria-pressed={inboxOpen}\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n onOpenInbox?.()\n }}\n >\n <IconInbox size={16} />\n {unreadCount > 0 ? (\n <span class=\"markup-tb-badge\" aria-hidden=\"true\">\n {unreadCount > 9 ? '9+' : unreadCount}\n </span>\n ) : null}\n </button>\n ) : null}\n\n {onTogglePins ? (\n <>\n <div class=\"markup-tb-sep\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n class=\"markup-tb-btn\"\n data-kind=\"pins\"\n aria-label={pinsVisible ? 'Hide pins' : 'Show pins'}\n aria-pressed={!pinsVisible}\n title={pinsVisible ? 'Hide pins' : 'Show pins'}\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n onTogglePins()\n }}\n >\n {pinsVisible ? <IconEye size={16} /> : <IconEyeOff size={16} />}\n </button>\n </>\n ) : null}\n\n {identityButton || overflowButton ? <div class=\"markup-tb-sep\" aria-hidden=\"true\" /> : null}\n\n {identityButton}\n {overflowButton}\n\n {/* Fallback overflow trigger when host doesn't pass an overflow slot. */}\n {!overflowButton ? (\n <button\n type=\"button\"\n class=\"markup-tb-btn\"\n data-kind=\"overflow\"\n aria-label=\"More options\"\n disabled\n >\n <IconMenu size={16} />\n </button>\n ) : null}\n </div>\n )\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks'\nimport { ConvexClient } from 'convex/browser'\nimport { makeFunctionReference } from 'convex/server'\n\nimport { defineMachine, useMachine } from '../../lib/machine'\nimport { extractMentionUserIds } from '../../lib/mentions'\nimport { useAsyncAction } from '../../lib/use-async-action'\nimport { track } from '../analytics'\nimport { resolveCoords, type PageCoords } from '../anchor'\nimport {\n createApiClient,\n type WidgetApiClient,\n type WidgetMember,\n type WidgetNotification,\n type WidgetThread,\n} from '../api'\nimport { probePartitionedCookieSupport } from '../cookie-probe'\nimport { subscribeToRouteChanges } from '../history-observer'\nimport {\n type AnonIdentity,\n type IdentityState,\n type VerifiedIdentity,\n authorFieldsOf,\n clientIdOf,\n displayNameOf,\n loadIdentity,\n saveIdentity,\n} from '../identity-store'\nimport { type PopupResult, signInWithPopup } from '../popup-auth'\nimport { resolveSafeUrl } from '../safe-url'\nimport { captureScreenshot, type ScrubConfig } from '../screenshot'\nimport { useSubscriptionToken } from '../use-subscription-token'\nimport { useTokenRefresh } from '../use-token-refresh'\nimport { cx, platformKeys } from '../utils'\nimport { IdentityMenu } from './identity-menu'\nimport { NewThreadPopover } from './new-thread-popover'\nimport { NotificationsPanel } from './notifications-panel'\nimport { OverflowMenu } from './overflow-menu'\nimport { PanelPopover, type PanelKind } from './panel-popover'\nimport { Pin, GhostPin } from './pin'\nimport { PlacementOverlay } from './placement-overlay'\nimport { PrivacyPanel } from './privacy-panel'\nimport { ShortcutsPanel } from './shortcuts-panel'\nimport { ThreadPopover } from './thread-popover'\nimport { Toolbar } from './toolbar'\n\ntype ToolbarPosition = 'bottom-right' | 'bottom-left' | 'bottom-center'\n\ntype ScreenshotsConfig = {\n enabled?: boolean\n strictScrub?: boolean\n redactSelector?: string\n}\n\nexport type AppProps = {\n apiUrl: string\n apiKey: string\n position?: ToolbarPosition\n screenshots?: ScreenshotsConfig\n /**\n * Linked as \"Account →\" from the identity menu; omitted hides the link.\n * Deliberately unvalidated — host pages opt in to whatever they trust.\n */\n dashboardUrl?: string\n}\n\n/**\n * `null` when the popup didn't return enough to mint a verified state. Cookie\n * mode needs only the expiries — the tokens themselves went to HttpOnly\n * Partitioned cookies that JS deliberately cannot see.\n */\nfunction verifiedFromPopup(result: PopupResult): VerifiedIdentity | null {\n const baseIdentity = {\n clientId: `markup_user_${result.identity.id}`,\n name: result.identity.name,\n email: result.identity.email,\n // Parsed rather than trusted: arrives over postMessage and renders as an\n // `<img src>`. Non-http(s) is dropped and the initials stand in.\n image:\n result.identity.image != null\n ? (resolveSafeUrl(result.identity.image, location.href)?.href ?? undefined)\n : undefined,\n }\n\n if (result.mode === 'cookies') {\n if (result.tokenExpiresAt == null || result.refreshTokenExpiresAt == null) return null\n return {\n storage: 'cookies',\n ...baseIdentity,\n tokenExpiresAt: result.tokenExpiresAt,\n refreshTokenExpiresAt: result.refreshTokenExpiresAt,\n }\n }\n\n if (!result.token || result.tokenExpiresAt == null) return null\n const hasRefresh =\n typeof result.refreshToken === 'string' && typeof result.refreshTokenExpiresAt === 'number'\n return {\n storage: 'localStorage',\n ...baseIdentity,\n token: result.token,\n tokenExpiresAt: result.tokenExpiresAt,\n ...(hasRefresh\n ? {\n refreshToken: result.refreshToken as string,\n refreshTokenExpiresAt: result.refreshTokenExpiresAt as number,\n }\n : {}),\n }\n}\n\ntype Mode =\n | { kind: 'idle' }\n | { kind: 'placing' }\n | {\n kind: 'composing-new'\n coords: PageCoords\n pageX: number\n pageY: number\n screenshot: Blob | null\n isScreenshotCapturing: boolean\n /** Distinct from screenshots being off, which shows no affordance. */\n screenshotFailed: boolean\n screenshotRedactedCount: number\n screenshotRedactedSelectors: string[]\n /**\n * Scopes an async capture to the placement that started it. Without it,\n * an in-flight capture for placement A lands its blob in composer B.\n */\n captureToken: number\n }\n | { kind: 'thread'; threadId: string }\n\n/**\n * Walks shadow roots because the widget renders inside one, so\n * `document.activeElement` reports the host element rather than a focused\n * composer textarea.\n */\nfunction isEditableElementFocused(): boolean {\n let active: Element | null = document.activeElement\n while (active && active.shadowRoot && active.shadowRoot.activeElement) {\n active = active.shadowRoot.activeElement\n }\n if (!active) return false\n const tag = active.tagName\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true\n return (active as HTMLElement).isContentEditable\n}\n\n// Includes `host`, so the same pathname on staging and production is two\n// routes. Without it, threads from one deployment leak into every other.\nfunction currentRoute() {\n return window.location.host + window.location.pathname\n}\n\n/**\n * The menu entry and the keyboard chord feed different events so only the\n * menu-initiated hide surfaces the instructional toast — someone who used the\n * chord already knows it.\n */\ntype HudState = { kind: 'visible' } | { kind: 'hidden-with-toast' } | { kind: 'hidden' }\n\ntype HudEvent = { type: 'hide-with-toast' } | { type: 'toggle' } | { type: 'dismiss-toast' }\n\nconst hudMachine = defineMachine<HudState, HudEvent>({\n visible: {\n 'hide-with-toast': () => ({ kind: 'hidden-with-toast' }),\n toggle: () => ({ kind: 'hidden' }),\n },\n 'hidden-with-toast': {\n toggle: () => ({ kind: 'visible' }),\n 'dismiss-toast': () => ({ kind: 'hidden' }),\n },\n hidden: {\n toggle: () => ({ kind: 'visible' }),\n },\n})\n\n/**\n * Events that don't fit the current state are silent no-ops — notably\n * `anon → unauthorized`, since an anon-token 401 is not on the recovery path.\n *\n * The `verified → recovering` transition is what re-fires the bootstrap mint\n * effect, whose dep array reads `identity.kind`; there is no separate counter.\n */\ntype IdentityEvent =\n | { type: 'mint-success'; identity: AnonIdentity }\n | { type: 'signed-in'; identity: VerifiedIdentity }\n | { type: 'unauthorized' }\n | { type: 'author-set'; name: string; email?: string }\n | { type: 'forget-me' }\n | { type: 'signed-out' }\n\n/**\n * Persisting inside the transitions means every state change writes to storage\n * without a `useEffect([identity])` to remember, and without re-writing on\n * mount what the bootstrap just read. It costs these transitions their purity;\n * every other machine in the widget stays pure.\n */\nfunction persist(next: IdentityState): IdentityState {\n saveIdentity(next)\n return next\n}\n\nconst identityMachine = defineMachine<IdentityState, IdentityEvent>({\n unresolved: {\n 'mint-success': (_, e) => persist({ kind: 'anon', identity: e.identity }),\n 'signed-in': (_, e) => persist({ kind: 'verified', identity: e.identity }),\n },\n anon: {\n 'signed-in': (_, e) => persist({ kind: 'verified', identity: e.identity }),\n 'author-set': (s, e) =>\n persist({\n kind: 'anon',\n identity: { ...s.identity, name: e.name, email: e.email },\n }),\n // Persisting `unresolved` wipes the stored record, and the bootstrap mint\n // loop then fires on the next render with a fresh clientId.\n 'forget-me': () => persist({ kind: 'unresolved' }),\n },\n verified: {\n 'signed-in': (_, e) => persist({ kind: 'verified', identity: e.identity }),\n unauthorized: (s) =>\n persist({\n kind: 'recovering',\n preserved: { name: s.identity.name, email: s.identity.email },\n }),\n // Same shape as `forget-me`: the user gets a fresh anon clientId and can\n // keep commenting as a pseudonym without a reload.\n 'signed-out': () => persist({ kind: 'unresolved' }),\n },\n recovering: {\n 'mint-success': (_, e) => persist({ kind: 'anon', identity: e.identity }),\n 'signed-in': (_, e) => persist({ kind: 'verified', identity: e.identity }),\n },\n})\n\nexport function App({\n apiUrl,\n apiKey,\n position = 'bottom-right',\n screenshots,\n dashboardUrl,\n}: AppProps) {\n const [route, setRoute] = useState(currentRoute)\n const [threads, setThreads] = useState<WidgetThread[]>([])\n const [threadsLoaded, setThreadsLoaded] = useState(false)\n\n // A partial record starts `unresolved` with its name/email in `preserved`,\n // which roundtrips those fields through the very first mint.\n const initialIdentity = useMemo(() => loadIdentity(), [])\n const [identity, sendIdentity] = useMachine(identityMachine, initialIdentity.state)\n\n // `null` while the probe is in flight. The sign-in handler waits for a\n // non-null value, so we never advertise the cookies capability before the\n // browser has confirmed it. Cached per tab in sessionStorage.\n const [cookieSupport, setCookieSupport] = useState<boolean | null>(null)\n useEffect(() => {\n let cancelled = false\n void probePartitionedCookieSupport(apiUrl, apiKey).then((supported) => {\n if (!cancelled) setCookieSupport(supported)\n })\n return () => {\n cancelled = true\n }\n }, [apiUrl, apiKey])\n\n // Effective toolbar corner. Initialized from the prop, but the user\n // can pick a different corner via the overflow menu's Position row;\n // the toast surfaces mirror the same corner.\n const [toolbarPosition, setToolbarPosition] = useState<ToolbarPosition>(position)\n /**\n * UI toggles surfaced in the toolbar pill / overflow menu. These live\n * in component state because they're scoped to the current widget\n * mount — no need to persist across sessions yet.\n *\n * - `pinsVisible` — drives the eye/eye-off button. Local-only;\n * the pin layer reads this and hides everything when false.\n * - `userAutoCapture` — user-toggled override of the screenshots\n * pref. AND-combines with the host-config `screenshots.enabled`\n * (a host that disabled captures wins; a host that allows them\n * defers to the user).\n * - `panel` — which toolbar-anchored panel (inbox / privacy /\n * shortcuts) is open, or `null` for none. One slot rather than a\n * flag per panel: they all render fixed to the same toolbar\n * corner, so two open at once would stack on top of each other.\n */\n const [pinsVisible, setPinsVisible] = useState(true)\n const [userAutoCapture, setUserAutoCapture] = useState(true)\n const [panel, setPanel] = useState<PanelKind | null>(null)\n const closePanel = useCallback(() => setPanel(null), [])\n\n // Read through a ref so the api client sees the freshest token without\n // being recreated whenever identity changes.\n const identityRef = useRef<IdentityState>(identity)\n identityRef.current = identity\n\n // No-op for the legacy long-lived path, where the identity has no refresh\n // token. On failure this falls through to the same verified → recovering\n // path a 401 takes.\n useTokenRefresh(\n identity,\n apiUrl,\n apiKey,\n (next) => sendIdentity({ type: 'signed-in', identity: next }),\n () => sendIdentity({ type: 'unauthorized' }),\n )\n\n const api = useMemo<WidgetApiClient>(\n () =>\n createApiClient({\n apiUrl,\n apiKey,\n getToken: () => {\n const s = identityRef.current\n if (s.kind !== 'verified') return null\n // Cookie mode deliberately has no `token` in JS. Null here skips\n // the Authorization header, and `getStorageMode` below switches the\n // client to `credentials: 'include'` so the cookie attaches instead.\n if (s.identity.token == null) return null\n return { token: s.identity.token, expiresAt: s.identity.tokenExpiresAt }\n },\n getStorageMode: () => {\n const s = identityRef.current\n if (s.kind !== 'verified') return null\n return s.identity.storage\n },\n getAnonToken: () => {\n const s = identityRef.current\n // The verified bearer takes precedence; sending both is redundant.\n if (s.kind !== 'anon') return null\n return s.identity.anonToken\n },\n onUnauthorized: () => {\n // Only `verified` defines this event, so a second 401 from a burst\n // of concurrent requests is a no-op rather than a restarted mint.\n sendIdentity({ type: 'unauthorized' })\n },\n }),\n [apiUrl, apiKey, sendIdentity],\n )\n const [mode, setMode] = useState<Mode>({ kind: 'idle' })\n\n /**\n * Failure degrades to \"no picker, no chips\" rather than blocking the widget.\n * A hand-typed `@[Name](uid)` marker still works, because the server\n * re-validates against `projectMembers` either way.\n */\n const [members, setMembers] = useState<WidgetMember[]>([])\n useEffect(() => {\n let cancelled = false\n api\n .listMembers()\n .then((res) => {\n if (!cancelled) setMembers(res.members)\n })\n .catch(() => {\n /* No picker rather than no widget. */\n })\n return () => {\n cancelled = true\n }\n }, [api])\n\n /**\n * Anonymous identities never see a badge: their subscription token carries\n * no `userId` claim, so the server counts 0.\n */\n const [unreadCount, setUnreadCount] = useState(0)\n const [notifications, setNotifications] = useState<WidgetNotification[]>([])\n const [notificationsLoading, setNotificationsLoading] = useState(false)\n const [notificationsError, setNotificationsError] = useState<string | undefined>(undefined)\n const [markingAllNotificationsRead, setMarkingAllNotificationsRead] = useState(false)\n\n // One-shot per open rather than a live subscription: the badge is enough to\n // motivate opening the inbox. Overlapping opens land last-write-wins, which\n // is fine — both responses are scoped to the same user and project.\n const fetchNotifications = useCallback(() => {\n setNotificationsLoading(true)\n setNotificationsError(undefined)\n api\n .listNotifications()\n .then((res) => {\n setNotifications(res.notifications)\n })\n .catch((err: unknown) => {\n setNotificationsError(err instanceof Error ? err.message : 'Failed to load.')\n })\n .finally(() => {\n setNotificationsLoading(false)\n })\n }, [api])\n\n /**\n * One machine per surface, not one shared: `isPending` grays out the thread\n * popover, so reactions, sign-in, forget-me and sign-out each need their own\n * or a menu-scoped gesture would gray out a half-written reply.\n *\n * Re-entrant `run` calls while pending are dropped, which is what makes\n * spam-clicking safe without per-handler guards.\n */\n const action = useAsyncAction()\n const signInAction = useAsyncAction()\n const reactionAction = useAsyncAction()\n const forgetMeAction = useAsyncAction()\n const signOutAction = useAsyncAction()\n\n // Destructured so these references stay stable across renders and can go in\n // dep arrays — `action.run` would drag the whole fresh-every-render object in.\n const { run: runAction, reset: resetAction } = action\n const { run: runSignIn } = signInAction\n const { run: runReaction, reset: resetReaction } = reactionAction\n const { run: runForgetMe } = forgetMeAction\n const { run: runSignOut } = signOutAction\n const isSigningOut = signOutAction.isPending\n\n const isPending = action.isPending\n // Only one is ever set in practice: the actions are user-initiated and\n // serialized through the UI.\n const error = action.error ?? signInAction.error ?? reactionAction.error\n\n const [hud, sendHud] = useMachine(hudMachine, { kind: 'visible' })\n const isHudHidden = hud.kind !== 'visible'\n\n const [tick, forceTick] = useState(0) // re-render on scroll/resize\n\n // Excluded from screenshots.\n const rootRef = useRef<HTMLDivElement>(null)\n\n const authorName = displayNameOf(identity)\n const isVerified = identity.kind === 'verified'\n // No signed clientId to attach a post to yet, so the author prompt disables\n // the guest path. Sign-in is independent and stays available.\n const isIdentityResolving = identity.kind === 'unresolved' || identity.kind === 'recovering'\n const currentClientId = clientIdOf(identity)\n\n /* — anon-identity mint loop —\n *\n * `identity.kind` is both the trigger and the exit: transitioning to `anon`\n * re-runs this effect, which then bails. Cancellation drops results from a\n * superseded mint, e.g. a sign-in landing while a retry is pending. */\n useEffect(() => {\n if (identity.kind !== 'unresolved' && identity.kind !== 'recovering') return\n // `recovering` carries the preserved fields in the variant itself; on a\n // first mount there is nothing in memory, so fall back to storage.\n const preserved =\n identity.kind === 'recovering' ? identity.preserved : initialIdentity.preserved\n\n let cancelled = false\n let timer: ReturnType<typeof setTimeout> | null = null\n let backoffMs = 1_000\n\n function mint() {\n api\n .mintAnonIdentity()\n .then(({ clientId, token }) => {\n if (cancelled) return\n const minted: AnonIdentity = {\n clientId,\n anonToken: token,\n name: preserved.name,\n email: preserved.email,\n }\n sendIdentity({ type: 'mint-success', identity: minted })\n })\n .catch(() => {\n if (cancelled) return\n const next = Math.min(backoffMs, 30_000)\n timer = setTimeout(mint, next)\n backoffMs = Math.min(backoffMs * 2, 30_000)\n })\n }\n\n mint()\n return () => {\n cancelled = true\n if (timer) clearTimeout(timer)\n }\n }, [api, identity, sendIdentity, initialIdentity])\n\n const subscriptionToken = useSubscriptionToken(api)\n\n /* — Convex client for real-time subscriptions —\n *\n * Held in `useState` rather than a ref so the subscription effect\n * below re-runs when the client is rebuilt (apiUrl change, HMR).\n * With a ref the subscription effect captured a closed client and\n * stayed bound to it until one of its other deps shifted. */\n const [convexClient, setConvexClient] = useState<ConvexClient | null>(null)\n useEffect(() => {\n // HTTP Actions use *.convex.site; the WebSocket client needs *.convex.cloud.\n const wsUrl = apiUrl.replace(/\\.convex\\.site(\\/.*)?$/, '.convex.cloud')\n const client = new ConvexClient(wsUrl)\n setConvexClient(client)\n return () => {\n client.close()\n setConvexClient((current) => (current === client ? null : current))\n }\n }, [apiUrl])\n\n /* — real-time thread subscription via Convex WebSocket — */\n const deepLinkHandled = useRef(false)\n useEffect(() => {\n if (!convexClient || !subscriptionToken) return\n // A resumed subscription means the deployment is reachable again, so a\n // stale \"Failed to post\" would be misleading.\n resetAction()\n resetReaction()\n return convexClient.onUpdate(\n makeFunctionReference<'query'>('widget/queries:subscribeThreadsForRoute'),\n // `viewerClientId` is a hint the server applies no trust to — it only\n // computes the per-reaction `mine` flag. Passing it here also re-fires\n // the subscription when identity changes, so `mine` flips.\n { subscriptionToken, route, viewerClientId: currentClientId },\n (result) => {\n if (result !== undefined) {\n setThreads(result)\n setThreadsLoaded(true)\n }\n },\n )\n }, [convexClient, subscriptionToken, route, currentClientId, resetAction, resetReaction])\n\n /* — real-time unread mention count for verified users —\n *\n * The token's `userId` claim is what tells the server whose inbox to count;\n * anonymous tokens count 0. The explicit reset covers the window between\n * sign-out and the next token mint, where the prior count would linger. */\n useEffect(() => {\n if (identity.kind !== 'verified') {\n setUnreadCount(0)\n return\n }\n if (!convexClient || !subscriptionToken) return\n return convexClient.onUpdate(\n makeFunctionReference<'query'>('widget/queries:subscribeUnreadCountForProject'),\n { subscriptionToken },\n (result) => {\n if (result !== undefined) {\n setUnreadCount(result.count)\n }\n },\n )\n }, [convexClient, subscriptionToken, identity.kind])\n\n /* — auto-open thread from URL fragment (#markup-thread=<id>) —\n *\n * Waits for the first snapshot: `threads` starts `[]`, and acting on that\n * would scrub the hash before the real threads arrive. Marks itself handled\n * either way, so a hash naming a deleted thread doesn't retry every tick. */\n useEffect(() => {\n if (deepLinkHandled.current) return\n if (!threadsLoaded) return\n const match = window.location.hash.match(/^#markup-thread=(.+)$/)\n if (match) {\n const threadId = decodeURIComponent(match[1] ?? '')\n const thread = threads.find((t) => t._id === threadId)\n if (thread) {\n setMode({ kind: 'thread', threadId })\n }\n // Even when unmatched: a stale fragment shouldn't linger in the URL bar.\n history.replaceState(null, '', window.location.pathname + window.location.search)\n }\n deepLinkHandled.current = true\n }, [threads, threadsLoaded])\n\n /* — track route changes (SPA navigation + back/forward) —\n *\n * The pushState/replaceState wrappers are installed once per page by a\n * module-scoped singleton, so init/destroy cycles can't stack them. */\n useEffect(() => subscribeToRouteChanges(() => setRoute(currentRoute())), [])\n\n /* — ⌘/Ctrl + . toggles the whole HUD. Allowed even while an input is\n * focused: the chord produces no text, and peeking at a clean page\n * mid-comment is exactly when it's wanted. */\n useEffect(() => {\n function onKeyDown(e: KeyboardEvent) {\n if (e.key !== '.') return\n if (!(e.metaKey || e.ctrlKey)) return\n if (e.altKey || e.shiftKey) return\n e.preventDefault()\n sendHud({ type: 'toggle' })\n }\n window.addEventListener('keydown', onKeyDown)\n return () => window.removeEventListener('keydown', onKeyDown)\n }, [sendHud])\n\n /* — panels are fixed to the toolbar's corner, so one left mounted after a\n * hide would float next to a toolbar that isn't there. */\n useEffect(() => {\n if (isHudHidden) setPanel(null)\n }, [isHudHidden])\n\n /* — any transition out of `hidden-with-toast` reruns this and the cleanup\n * clears the timer, so no separate reconcile branch is needed. */\n useEffect(() => {\n if (hud.kind !== 'hidden-with-toast') return\n const t = window.setTimeout(() => sendHud({ type: 'dismiss-toast' }), 5000)\n return () => window.clearTimeout(t)\n }, [hud.kind, sendHud])\n\n /* — re-render pins on scroll/resize/layout-shift so they track their anchors — */\n useEffect(() => {\n // Coalesced via rAF: ResizeObserver can fire dozens of times per frame on\n // a busy host page, and each one would otherwise re-render all of App.\n let rafId: number | null = null\n function tick() {\n if (rafId != null) return\n rafId = requestAnimationFrame(() => {\n rafId = null\n forceTick((n) => n + 1)\n })\n }\n window.addEventListener('scroll', tick, { passive: true })\n window.addEventListener('resize', tick)\n // Catches layout shifts that fire neither resize nor scroll — accordions\n // expanding, lazy images loading.\n const ro = new ResizeObserver(tick)\n ro.observe(document.body)\n return () => {\n window.removeEventListener('scroll', tick)\n window.removeEventListener('resize', tick)\n ro.disconnect()\n if (rafId != null) cancelAnimationFrame(rafId)\n }\n }, [])\n\n /* — Mode transitions reset the error machines so a previous failure doesn't\n * carry into the next gesture. Sign-in errors persist on purpose: they\n * belong to the auth surface, not the placing flow. */\n const startPlacing = useCallback(() => {\n resetAction()\n resetReaction()\n track('comment_started')\n setMode({ kind: 'placing' })\n }, [resetAction, resetReaction])\n\n /* — plain `c` starts the comment flow. Only from idle, so it can't yank\n * the user out of an open thread or a half-written composer. */\n useEffect(() => {\n function onKeyDown(e: KeyboardEvent) {\n if (e.key !== 'c') return\n if (e.metaKey || e.ctrlKey || e.altKey || e.shiftKey) return\n if (mode.kind !== 'idle') return\n if (isHudHidden) return\n if (isEditableElementFocused()) return\n e.preventDefault()\n startPlacing()\n }\n window.addEventListener('keydown', onKeyDown)\n return () => window.removeEventListener('keydown', onKeyDown)\n }, [mode.kind, isHudHidden, startPlacing])\n\n const cancel = useCallback(() => {\n setMode({ kind: 'idle' })\n resetAction()\n resetReaction()\n }, [resetAction, resetReaction])\n\n const captureCounterRef = useRef(0)\n const handlePlace = useCallback(\n (coords: PageCoords, screenX: number, screenY: number) => {\n const pageX = screenX + window.scrollX\n const pageY = screenY + window.scrollY\n const captureToken = ++captureCounterRef.current\n\n if (screenshots?.enabled === false || !userAutoCapture) {\n setMode({\n kind: 'composing-new',\n coords,\n pageX,\n pageY,\n screenshot: null,\n isScreenshotCapturing: false,\n screenshotFailed: false,\n screenshotRedactedCount: 0,\n screenshotRedactedSelectors: [],\n captureToken,\n })\n return\n }\n\n setMode({\n kind: 'composing-new',\n coords,\n pageX,\n pageY,\n screenshot: null,\n isScreenshotCapturing: true,\n screenshotFailed: false,\n screenshotRedactedCount: 0,\n screenshotRedactedSelectors: [],\n captureToken,\n })\n\n // Excluded from the capture.\n const shadowHost =\n rootRef.current != null && rootRef.current.getRootNode() instanceof ShadowRoot\n ? (rootRef.current.getRootNode() as ShadowRoot).host\n : null\n\n const scrubConfig: ScrubConfig = {\n strictScrub: screenshots?.strictScrub,\n redactSelector: screenshots?.redactSelector,\n }\n\n captureScreenshot(shadowHost, { x: screenX, y: screenY }, scrubConfig).then((result) => {\n setMode((current) => {\n // Cancelled, or superseded by a fresh placement, since this capture\n // started — otherwise blob A attaches to composer B.\n if (current.kind !== 'composing-new') return current\n if (current.captureToken !== captureToken) return current\n return {\n ...current,\n screenshot: result?.blob ?? null,\n isScreenshotCapturing: false,\n // `captureScreenshot` logs every null path itself.\n screenshotFailed: result == null,\n screenshotRedactedCount: result?.redactedCount ?? 0,\n screenshotRedactedSelectors: result?.redactedSelectors ?? [],\n }\n })\n // `html-to-image` fails silently on assets we never see, so the\n // success rate is only observable here.\n track('screenshot_captured', { ok: result != null })\n })\n },\n [screenshots, userAutoCapture],\n )\n\n const handleAuthor = useCallback(\n (name: string, email?: string) => {\n // Only reachable for an anon identity with no display fields yet; the\n // machine ignores `verified.author-set` regardless.\n sendIdentity({ type: 'author-set', name, email })\n },\n [sendIdentity],\n )\n\n // `useAsyncAction` drops re-entrant `run` calls, so spam-clicking can't\n // stack popups and no explicit guard is needed.\n const isSigningIn = signInAction.isPending\n const signIn = useCallback(async () => {\n track('sign_in_started')\n await runSignIn(async () => {\n // Both `null` (probe in flight) and `false` opt out, so a slow probe\n // can't degrade the session into a half-broken cookie-mode flow.\n const result = await signInWithPopup({\n apiUrl,\n apiKey,\n useCookies: cookieSupport === true,\n })\n const verified = verifiedFromPopup(result)\n if (!verified) {\n // Refuse rather than wedge the user as verified with no token, which\n // is the silent-401 trap.\n throw new Error('Sign-in did not return a verified token')\n }\n sendIdentity({ type: 'signed-in', identity: verified })\n track('sign_in_completed')\n })\n }, [apiUrl, apiKey, cookieSupport, runSignIn, sendIdentity])\n\n const handleSubmitNew = useCallback(\n async (body: string, includeScreenshot: boolean) => {\n if (mode.kind !== 'composing-new') return\n const author = authorFieldsOf(identity)\n if (!author) return\n await runAction(async () => {\n let screenshotStorageId: string | undefined\n\n if (includeScreenshot && mode.screenshot) {\n const { uploadUrl } = await api.getScreenshotUploadUrl()\n // Longer than the 30s write timeout in api.ts: uploads run to 2MB\n // and a degraded uplink can legitimately take this long. Unbounded,\n // a black-holed proxy would leave the composer pending forever.\n let uploadRes: Response\n try {\n uploadRes = await fetch(uploadUrl, {\n method: 'POST',\n headers: { 'Content-Type': mode.screenshot.type || 'image/png' },\n body: mode.screenshot,\n signal: AbortSignal.timeout(60_000),\n })\n } catch (err) {\n if (err instanceof DOMException && err.name === 'TimeoutError') {\n throw new Error('Screenshot upload took too long — check your connection')\n }\n throw err\n }\n // Throwing keeps the composer open to retry. Posting without a\n // screenshot the user explicitly attached is the worse outcome.\n if (!uploadRes.ok) {\n throw new Error(`Screenshot upload failed (${uploadRes.status})`)\n }\n const { storageId } = (await uploadRes.json()) as { storageId: string }\n screenshotStorageId = storageId\n }\n\n const mentions = extractMentionUserIds(body)\n const res = await api.createThread({\n url: window.location.href,\n route,\n anchorSelector: mode.coords.anchorSelector,\n anchorX: mode.coords.anchorX,\n anchorY: mode.coords.anchorY,\n anchorOffsetX: mode.coords.anchorOffsetX,\n anchorOffsetY: mode.coords.anchorOffsetY,\n viewportW: mode.coords.viewportW,\n viewportY: mode.coords.viewportY,\n userAgent: navigator.userAgent,\n authorName: author.name,\n authorEmail: author.email,\n body,\n mentions: mentions.length > 0 ? mentions : undefined,\n screenshotStorageId,\n })\n setThreads((current) => [...current, res.thread])\n track('comment_submitted', {\n hasScreenshot: screenshotStorageId != null,\n hasMentions: mentions.length > 0,\n })\n setMode({ kind: 'thread', threadId: res.thread._id })\n })\n },\n [api, identity, mode, route, runAction],\n )\n\n const handleDelete = useCallback(async () => {\n if (mode.kind !== 'thread') return\n const threadId = mode.threadId\n await runAction(async () => {\n await api.deleteThread(threadId)\n setThreads((current) => current.filter((t) => t._id !== threadId))\n setMode({ kind: 'idle' })\n })\n }, [api, mode, runAction])\n\n const handleResolve = useCallback(async () => {\n if (mode.kind !== 'thread') return\n const threadId = mode.threadId\n await runAction(async () => {\n await api.resolveThread(threadId, currentClientId)\n setThreads((current) => current.filter((t) => t._id !== threadId))\n track('thread_resolved')\n setMode({ kind: 'idle' })\n })\n }, [api, mode, currentClientId, runAction])\n\n const handleNotificationClick = useCallback(\n (item: WidgetNotification) => {\n // Optimistic, so the panel feels immediate.\n if (item.readAt == null) {\n setUnreadCount((n) => Math.max(0, n - 1))\n setNotifications((current) =>\n current.map((n) => (n._id === item._id ? { ...n, readAt: Date.now() } : n)),\n )\n api.markNotificationRead(item._id).catch(() => {\n /* The next poll restores the true count. */\n })\n }\n\n // Off-route hands off to host navigation, and the destination widget's\n // `#markup-thread=` bootstrap picks it up.\n const onCurrentRoute = threads.some((t) => t._id === item.threadId)\n if (onCurrentRoute) {\n setMode({ kind: 'thread', threadId: item.threadId })\n } else {\n // Unsafe or malformed URLs fall through; the dashboard inbox is the\n // working fallback.\n const url = resolveSafeUrl(item.threadUrl, window.location.href)\n if (url) {\n url.hash = `markup-thread=${item.threadId}`\n window.location.href = url.toString()\n }\n }\n },\n [api, threads],\n )\n\n const handleMarkAllNotificationsRead = useCallback(() => {\n setMarkingAllNotificationsRead(true)\n setUnreadCount(0)\n setNotifications((current) =>\n current.map((n) => (n.readAt == null ? { ...n, readAt: Date.now() } : n)),\n )\n api\n .markAllNotificationsRead()\n .catch(() => {\n /* The next poll restores the true state. */\n })\n .finally(() => setMarkingAllNotificationsRead(false))\n }, [api])\n\n const handleReply = useCallback(\n async (body: string) => {\n if (mode.kind !== 'thread') return\n const author = authorFieldsOf(identity)\n if (!author) return\n const threadId = mode.threadId\n await runAction(async () => {\n const mentions = extractMentionUserIds(body)\n const res = await api.addComment(threadId, {\n body,\n authorName: author.name,\n authorEmail: author.email,\n mentions: mentions.length > 0 ? mentions : undefined,\n })\n setThreads((current) => current.map((t) => (t._id === threadId ? res.thread : t)))\n track('reply_submitted', { hasMentions: mentions.length > 0 })\n })\n },\n [api, identity, mode, runAction],\n )\n\n const handleEditComment = useCallback(\n async (commentId: string, body: string) => {\n if (mode.kind !== 'thread') return\n if (identity.kind !== 'anon' && identity.kind !== 'verified') return\n const threadId = mode.threadId\n // `rethrow` keeps the edit form open on failure, so a draft survives.\n await runAction(\n async () => {\n const mentions = extractMentionUserIds(body)\n const res = await api.editComment(threadId, commentId, {\n body,\n mentions: mentions.length > 0 ? mentions : undefined,\n })\n setThreads((current) => current.map((t) => (t._id === threadId ? res.thread : t)))\n },\n { rethrow: true },\n )\n },\n [api, identity, mode, runAction],\n )\n\n const handleDeleteComment = useCallback(\n async (commentId: string) => {\n if (mode.kind !== 'thread') return\n if (identity.kind !== 'anon' && identity.kind !== 'verified') return\n const threadId = mode.threadId\n await runAction(async () => {\n const res = await api.deleteComment(threadId, commentId)\n setThreads((current) => current.map((t) => (t._id === threadId ? res.thread : t)))\n })\n },\n [api, identity, mode, runAction],\n )\n\n /**\n * Swapped from the server's authoritative response rather than toggled\n * locally; a failure leaves the next subscription tick to reconcile.\n */\n const handleToggleReaction = useCallback(\n async (commentId: string, emoji: string) => {\n if (mode.kind !== 'thread') return\n const author = authorFieldsOf(identity)\n if (!author) return\n const threadId = mode.threadId\n await runReaction(async () => {\n const res = await api.toggleReaction(commentId, {\n emoji,\n authorName: author.name,\n })\n setThreads((current) => current.map((t) => (t._id === threadId ? res.thread : t)))\n track('reaction_added')\n })\n },\n [api, identity, mode, runReaction],\n )\n\n /**\n * Closing the popover matters: it would otherwise be anchored to comments\n * that were just soft-deleted. On failure the identity is left intact and\n * the privacy panel renders `forgetMeAction.error` inline.\n */\n const [forgetMeToasted, setForgetMeToasted] = useState(false)\n const handleForgetMe = useCallback(async () => {\n await runForgetMe(async () => {\n await api.forgetMe()\n setMode({ kind: 'idle' })\n // The privacy panel's \"who you are here\" section would describe an\n // identity that no longer exists.\n closePanel()\n sendIdentity({ type: 'forget-me' })\n setForgetMeToasted(true)\n })\n }, [api, closePanel, runForgetMe, sendIdentity])\n\n // Same 5s window as HudHiddenToast.\n useEffect(() => {\n if (!forgetMeToasted) return\n const t = window.setTimeout(() => setForgetMeToasted(false), 5000)\n return () => window.clearTimeout(t)\n }, [forgetMeToasted])\n\n /**\n * Same shape as forget-me. On error the identity stays verified and\n * `signOutAction.error` carries the message.\n */\n const [signedOutToasted, setSignedOutToasted] = useState(false)\n const handleSignOut = useCallback(async () => {\n await runSignOut(async () => {\n await api.signOut()\n setMode({ kind: 'idle' })\n sendIdentity({ type: 'signed-out' })\n setSignedOutToasted(true)\n })\n }, [api, runSignOut, sendIdentity])\n\n useEffect(() => {\n if (!signedOutToasted) return\n const t = window.setTimeout(() => setSignedOutToasted(false), 5000)\n return () => window.clearTimeout(t)\n }, [signedOutToasted])\n\n /* — derived — */\n const activeThread =\n mode.kind === 'thread' ? (threads.find((t) => t._id === mode.threadId) ?? null) : null\n const canDelete =\n isVerified || (currentClientId != null && currentClientId === activeThread?.authorClientId)\n\n /* — resolved pin positions —\n *\n * Memoised so `resolveCoords` doesn't run twice per render: once for the pin\n * markup, once for the unresolved count driving the observer below. `tick` is\n * a dep so any bump recomputes positions and resolved flags together. */\n const pinPositions = useMemo(\n () =>\n threads.map((t) => ({\n thread: t,\n point: resolveCoords({\n anchorX: t.anchorX,\n anchorY: t.anchorY,\n anchorSelector: t.anchorSelector,\n anchorOffsetX: t.anchorOffsetX,\n anchorOffsetY: t.anchorOffsetY,\n }),\n })),\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n [threads, tick],\n )\n /* In a ref rather than effect deps: `pinPositions` is recomputed every\n * scroll frame, and the observer must not be re-attached that often. */\n const anchorWatch = useRef<{ retryable: boolean; elements: Element[] }>({\n retryable: false,\n elements: [],\n })\n useEffect(() => {\n anchorWatch.current = {\n // A selector-less pin lives at the fraction fallback forever, so it\n // must not keep the watcher hot.\n retryable: pinPositions.some((p) => !p.point.resolved && p.thread.anchorSelector != null),\n elements: pinPositions.flatMap((p) => (p.point.element ? [p.point.element] : [])),\n }\n }, [pinPositions])\n const hasAnchoredThreads = threads.some((t) => t.anchorSelector != null)\n\n /* — keep pins in sync as anchor elements appear *and* disappear —\n *\n * The scroll/resize loop tracks pins through layout shifts but not through an\n * anchor that isn't in the DOM at all — common in SPAs that show a skeleton\n * on route change. The observer stays attached after everything anchors,\n * because a pin that *loses* its anchor has to fall back and dim again.\n *\n * Steady-state cost stays near zero: no render unless some pin is still\n * hunting for its selector, or a currently-anchored element just left the\n * document. Purely additive mutations on an anchored page do nothing. */\n useEffect(() => {\n if (!hasAnchoredThreads) return\n let rafId: number | null = null\n function schedule() {\n if (rafId != null) return\n rafId = requestAnimationFrame(() => {\n rafId = null\n forceTick((n) => n + 1)\n })\n }\n const observer = new MutationObserver(() => {\n const { retryable, elements } = anchorWatch.current\n if (!retryable && elements.every((el) => el.isConnected)) return\n schedule()\n })\n observer.observe(document.body, { childList: true, subtree: true })\n return () => {\n observer.disconnect()\n if (rafId != null) cancelAnimationFrame(rafId)\n }\n }, [hasAnchoredThreads])\n\n /* — a teammate-initiated delete or resolve would otherwise leave `mode`\n * pinned to a missing id: the popover gate falls through quietly, so the\n * user sees nothing and `mode` stays wedged until their next action. */\n useEffect(() => {\n if (mode.kind === 'thread' && activeThread == null) {\n cancel()\n }\n }, [mode, activeThread, cancel])\n\n return (\n <div class=\"markup-root\" ref={rootRef}>\n {/* Pins layer — hidden during placement. Thread pins also hide when\n * the HUD is toggled off; the thread popover hides at the same time,\n * so no anchor needs preserving. The ghost pin during composing-new\n * stays regardless, because the composer anchors to it. */}\n {mode.kind !== 'placing' ? (\n <div class=\"markup-pins-layer\">\n {!isHudHidden && pinsVisible\n ? pinPositions.map(({ thread: t, point }) => {\n const isActive = mode.kind === 'thread' && mode.threadId === t._id\n // Hidden from the popover too, so counting them overcounts.\n const visibleCount = t.comments.reduce((n, c) => n + (c.deleted ? 0 : 1), 0)\n return (\n <Pin\n key={t._id}\n pageX={point.pageX}\n pageY={point.pageY}\n count={visibleCount}\n isActive={isActive}\n isUnresolved={!point.resolved}\n onClick={() => {\n track('thread_opened', { commentCount: visibleCount })\n setMode({ kind: 'thread', threadId: t._id })\n }}\n />\n )\n })\n : null}\n {mode.kind === 'composing-new' ? (\n <GhostPin pageX={mode.pageX} pageY={mode.pageY} />\n ) : null}\n </div>\n ) : null}\n\n {/* Placement overlay — captures the click */}\n {mode.kind === 'placing' ? (\n <PlacementOverlay onPlace={handlePlace} onCancel={cancel} />\n ) : null}\n\n {/* Active thread popover. We keep it mounted while the HUD is\n * hidden via CSS rather than unmounted, so a reply draft, edit or\n * drag position survives a Cmd+. peek.\n *\n * Keyed on the thread id: without it Preact reuses the instance and\n * `dragPos`, `editingId`, the per-comment menus and the reaction\n * picker all leak across threads. */}\n {mode.kind === 'thread' && activeThread ? (\n <ThreadPopover\n key={activeThread._id}\n thread={activeThread}\n authorName={authorName}\n currentClientId={currentClientId ?? null}\n isVerified={isVerified}\n isIdentityResolving={isIdentityResolving}\n isSigningIn={isSigningIn}\n canDelete={canDelete}\n isPending={isPending}\n error={error}\n isHidden={isHudHidden}\n members={members}\n onAuthor={handleAuthor}\n onSignIn={signIn}\n onClose={cancel}\n onReply={handleReply}\n onEditComment={handleEditComment}\n onDeleteComment={handleDeleteComment}\n onToggleReaction={handleToggleReaction}\n onDelete={handleDelete}\n onResolve={handleResolve}\n />\n ) : null}\n\n {/* New-thread composer */}\n {mode.kind === 'composing-new' ? (\n <NewThreadPopover\n pageX={mode.pageX}\n pageY={mode.pageY}\n authorName={authorName}\n isVerified={isVerified}\n isIdentityResolving={isIdentityResolving}\n isSigningIn={isSigningIn}\n isPending={isPending}\n error={error}\n screenshot={mode.screenshot}\n isScreenshotCapturing={mode.isScreenshotCapturing}\n screenshotFailed={mode.screenshotFailed}\n screenshotRedactedCount={mode.screenshotRedactedCount}\n screenshotRedactedSelectors={mode.screenshotRedactedSelectors}\n members={members}\n onAuthor={handleAuthor}\n onSignIn={signIn}\n onSubmit={handleSubmitNew}\n onClose={cancel}\n />\n ) : null}\n\n {/* Toolbar pill — hidden along with the pins when the HUD is toggled\n * off. While placing/composing it stays visible regardless, so the\n * user always has a way to cancel. */}\n {!isHudHidden || mode.kind === 'placing' || mode.kind === 'composing-new' ? (\n <Toolbar\n isActive={mode.kind === 'placing'}\n onToggle={() => (mode.kind === 'placing' ? cancel() : startPlacing())}\n onHide={() => sendHud({ type: 'hide-with-toast' })}\n position={toolbarPosition}\n showInbox={isVerified}\n unreadCount={isVerified ? unreadCount : 0}\n inboxOpen={panel === 'inbox'}\n onOpenInbox={() => {\n const next = panel === 'inbox' ? null : 'inbox'\n setPanel(next)\n if (next) {\n track('notifications_opened', { unreadCount })\n fetchNotifications()\n }\n }}\n pinsVisible={pinsVisible}\n onTogglePins={() => setPinsVisible((v) => !v)}\n identityButton={\n <IdentityMenu\n identity={identity}\n position={toolbarPosition}\n isSigningIn={isSigningIn}\n isSigningOut={isSigningOut}\n dashboardUrl={dashboardUrl}\n onSignIn={signIn}\n onSignOut={handleSignOut}\n onForgetMe={handleForgetMe}\n />\n }\n overflowButton={\n <OverflowMenu\n position={toolbarPosition}\n onSetPosition={setToolbarPosition}\n autoCapture={userAutoCapture && screenshots?.enabled !== false}\n autoCaptureLocked={screenshots?.enabled === false}\n onToggleAutoCapture={() => setUserAutoCapture((v) => !v)}\n onOpenPrivacy={() => setPanel('privacy')}\n onOpenShortcuts={() => setPanel('shortcuts')}\n onHideForSession={() => sendHud({ type: 'hide-with-toast' })}\n version={__MARKUP_VERSION__}\n dashboardUrl={dashboardUrl}\n />\n }\n />\n ) : null}\n\n {/* Toolbar-anchored panels. At most one is open at a time (`panel`\n * is a single slot) and all three share `PanelPopover` for\n * positioning plus outside-click / Escape dismissal. */}\n {panel === 'inbox' && isVerified ? (\n <PanelPopover\n kind=\"inbox\"\n label=\"Inbox\"\n position={toolbarPosition}\n ignoreToolbarKind=\"inbox\"\n onClose={closePanel}\n >\n <NotificationsPanel\n items={notifications}\n isLoading={notificationsLoading}\n error={notificationsError}\n isMarkingAll={markingAllNotificationsRead}\n onBack={closePanel}\n onItemClick={(item) => {\n closePanel()\n handleNotificationClick(item)\n }}\n onMarkAllRead={handleMarkAllNotificationsRead}\n />\n </PanelPopover>\n ) : null}\n\n {panel === 'privacy' ? (\n <PanelPopover\n kind=\"privacy\"\n label=\"Privacy and data\"\n position={toolbarPosition}\n onClose={closePanel}\n >\n <PrivacyPanel\n identity={identity}\n apiUrl={apiUrl}\n autoCapture={userAutoCapture && screenshots?.enabled !== false}\n autoCaptureLocked={screenshots?.enabled === false}\n isForgettingMe={forgetMeAction.isPending}\n forgetMeError={forgetMeAction.error}\n onForgetMe={handleForgetMe}\n onClose={closePanel}\n />\n </PanelPopover>\n ) : null}\n\n {panel === 'shortcuts' ? (\n <PanelPopover\n kind=\"shortcuts\"\n label=\"Keyboard shortcuts\"\n position={toolbarPosition}\n onClose={closePanel}\n >\n <ShortcutsPanel onClose={closePanel} />\n </PanelPopover>\n ) : null}\n\n {/* Toast — only shown while the HUD is hidden. Lives outside the\n * HUD-hidden gate so it stays visible after the toolbar\n * disappears. Auto-dismisses via the effect above. */}\n {hud.kind === 'hidden-with-toast' ? <HudHiddenToast position={toolbarPosition} /> : null}\n\n {/* Forget-me confirmation toast. Shows after the server has\n * actually erased the identity (and a fresh anon clientId is\n * being minted in the background). */}\n {forgetMeToasted ? <ForgetMeToast position={toolbarPosition} /> : null}\n\n {/* Sign-out confirmation toast. Same anchor + dismissal pattern\n * as the forget-me toast above; copy reflects that the\n * session ended (not that data was erased). */}\n {signedOutToasted ? <SignedOutToast position={toolbarPosition} /> : null}\n </div>\n )\n}\n\n/** Mirrors the toolbar's corner so the toast doesn't drift across the page. */\nfunction HudHiddenToast({ position }: { position: ToolbarPosition }) {\n const { mod: modKey } = platformKeys()\n return (\n <div\n class={cx(\n 'markup-hud-hidden-toast',\n position === 'bottom-left'\n ? 'markup-hud-hidden-toast-left'\n : position === 'bottom-center'\n ? 'markup-hud-hidden-toast-center'\n : 'markup-hud-hidden-toast-right',\n )}\n role=\"status\"\n aria-live=\"polite\"\n >\n Markup hidden — press <kbd class=\"markup-kbd\">{modKey}</kbd>\n <kbd class=\"markup-kbd\">.</kbd> or refresh to bring it back.\n </div>\n )\n}\n\n/**\n * Copy names \"name and email\" on purpose: the comments stay, since the server\n * soft-deletes only the calling identity's authorship link.\n */\nfunction ForgetMeToast({ position }: { position: ToolbarPosition }) {\n return (\n <div\n class={cx(\n 'markup-hud-hidden-toast',\n position === 'bottom-left'\n ? 'markup-hud-hidden-toast-left'\n : position === 'bottom-center'\n ? 'markup-hud-hidden-toast-center'\n : 'markup-hud-hidden-toast-right',\n )}\n role=\"status\"\n aria-live=\"polite\"\n >\n Forgotten on this site — your name and email were cleared.\n </div>\n )\n}\n\n/** Distinct from the forget-me toast: a session ended, nothing was erased. */\nfunction SignedOutToast({ position }: { position: ToolbarPosition }) {\n return (\n <div\n class={cx(\n 'markup-hud-hidden-toast',\n position === 'bottom-left'\n ? 'markup-hud-hidden-toast-left'\n : position === 'bottom-center'\n ? 'markup-hud-hidden-toast-center'\n : 'markup-hud-hidden-toast-right',\n )}\n role=\"status\"\n aria-live=\"polite\"\n >\n Signed out — commenting anonymously again.\n </div>\n )\n}\n","import { render } from 'preact'\n\nimport styles from '../styles.css?inline'\nimport { setAnalyticsConfig, track } from './analytics'\nimport { WidgetErrorBoundary } from './error-boundary'\nimport { type ErrorReporterConfig, reportError, setActiveReporter } from './error-reporter'\nimport { bindThemeHost, watchSystemTheme } from './theme-store'\nimport { App, type AppProps } from './ui/app'\n\nexport type MountConfig = AppProps & {\n /** `false` sends no product telemetry. See `runtime/analytics.ts`. */\n analytics?: boolean\n /** Once the user picks a theme at runtime, the persisted value wins. */\n theme?: 'light' | 'dark' | 'auto'\n}\n\n/**\n * The host element overlays the whole viewport with `pointer-events: none`, so\n * individual UI bits re-enable it as needed rather than the widget blocking\n * the page underneath.\n */\nexport function mountWidget(host: HTMLElement, config: MountConfig): () => void {\n host.style.position = 'fixed'\n host.style.inset = '0'\n host.style.zIndex = '2147483647'\n host.style.pointerEvents = 'none'\n\n bindThemeHost(host, config.theme ?? 'auto')\n const stopWatch = watchSystemTheme()\n\n const shadow = host.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = styles\n shadow.appendChild(style)\n\n const root = document.createElement('div')\n root.className = 'markup-shadow-root'\n shadow.appendChild(root)\n\n // One object so every report path shares a rate-limit window — the sender\n // cache in error-reporter.ts is keyed by reference.\n const reporterConfig: ErrorReporterConfig = {\n apiUrl: config.apiUrl,\n apiKey: config.apiKey,\n widgetVersion: __MARKUP_VERSION__,\n }\n\n // Before rendering, so an error thrown during the initial render still\n // lands on a configured reporter.\n setActiveReporter(reporterConfig)\n\n setAnalyticsConfig(\n config.analytics === false\n ? null\n : { apiUrl: config.apiUrl, apiKey: config.apiKey, widgetVersion: __MARKUP_VERSION__ },\n )\n track('widget_loaded')\n\n const { theme: _theme, analytics: _analytics, ...appProps } = config\n render(\n <WidgetErrorBoundary onError={(err) => reportError(err, { context: 'render' })}>\n <App {...appProps} />\n </WidgetErrorBoundary>,\n root,\n )\n\n return () => {\n stopWatch()\n setActiveReporter(null)\n // Clears the queue — a torn-down widget shouldn't post after the fact.\n setAnalyticsConfig(null)\n render(null, root)\n }\n}\n","import { mountWidget } from './runtime/mount'\n\nexport type WidgetTheme = 'light' | 'dark' | 'auto'\n\n/**\n * @deprecated The floating action button was replaced by the toolbar\n * pill, which has no variants. Kept so existing type imports keep\n * compiling; it is no longer referenced by anything the widget renders\n * and will be removed in the next major.\n */\nexport type WidgetFab = 'default' | 'icon-only'\n\nexport interface ScreenshotsConfig {\n /** Disable screenshot capture entirely. Default: enabled. */\n enabled?: boolean\n /** Also masks all inputs/selects/textareas in addition to the default sensitive set. Default: false. */\n strictScrub?: boolean\n /** Custom CSS selector — matched elements are always masked. */\n redactSelector?: string\n}\n\nexport interface WidgetConfig {\n /** Convex deployment site URL, e.g. `https://your-deployment.convex.site` */\n apiUrl: string\n /** Raw API key minted from a project's settings page */\n apiKey: string\n /**\n * Initial corner for the toolbar. Defaults to bottom-right. Users can\n * move it afterwards from the toolbar's overflow menu.\n */\n position?: 'bottom-right' | 'bottom-left' | 'bottom-center'\n /**\n * Visual theme.\n * - `'light'` — force light palette\n * - `'dark'` — force dark palette\n * - `'auto'` (default) — follow the host's `prefers-color-scheme`\n */\n theme?: WidgetTheme\n /**\n * @deprecated Ignored. The floating action button was replaced by the\n * toolbar pill, which has no variants, so neither `'default'` nor\n * `'icon-only'` describes anything the widget can render. Accepted\n * (and dropped) so upgrading doesn't break callers that still pass it;\n * remove it from your config. Will be deleted in the next major.\n */\n fab?: WidgetFab\n /** Screenshot capture and PII-scrub options. */\n screenshots?: ScreenshotsConfig\n /**\n * Optional dashboard URL the widget links to from the verified-user\n * identity menu (\"Account →\"). When omitted the menu hides the\n * Account entry. Useful for self-hosters whose dashboard origin\n * isn't statically known to the widget.\n */\n dashboardUrl?: string\n /**\n * Product telemetry — counts of widget interactions, sent to Markup.\n * Default: enabled.\n *\n * What it is not: it adds no third-party script, sets no cookie and\n * writes nothing to storage, and carries no identifier for the person\n * using your site — events are keyed on the *project*, and the\n * session id is generated per page load and discarded with the tab.\n * No comment text, URLs, or names are ever sent.\n *\n * Set `false` if your privacy policy or DPA is easier to write\n * without it.\n */\n analytics?: boolean\n}\n\nlet _unmount: (() => void) | null = null\nlet _host: HTMLElement | null = null\nlet _pendingMount: (() => void) | null = null\n/** Deprecation notices fire once per page, not once per `init()`. */\nlet _warnedFab = false\n\n/**\n * Mounts the feedback widget on the page. Idempotent — calling init again\n * with the same config is a no-op; calling with different config tears down\n * the previous instance first.\n *\n * Returns a `destroy()` function that unmounts the widget and removes the\n * host element. Useful for SPAs that want to dispose on logout.\n */\nexport function init(config: WidgetConfig): () => void {\n if (!config.apiUrl || !config.apiKey) {\n console.warn('[markup] init() requires both apiUrl and apiKey — widget not mounted')\n return () => {}\n }\n // `@deprecated` only reaches TypeScript callers; plain-JS and `data-fab`\n // users need to hear about it before the option disappears.\n if (config.fab != null && !_warnedFab) {\n _warnedFab = true\n console.warn(\n '[markup] the `fab` option is ignored and will be removed in the next major — ' +\n 'the toolbar replaced the floating action button. Remove it from your config.',\n )\n }\n destroy()\n\n const mount = () => {\n _pendingMount = null\n if (!document.body) return\n const host = document.createElement('div')\n host.id = 'markup-widget'\n document.body.appendChild(host)\n _host = host\n _unmount = mountWidget(host, config)\n }\n\n // Called from <head> before <body> parses, `document.body` is still null.\n if (document.readyState === 'loading' || !document.body) {\n const deferred = () => mount()\n _pendingMount = () => document.removeEventListener('DOMContentLoaded', deferred)\n document.addEventListener('DOMContentLoaded', deferred, { once: true })\n } else {\n mount()\n }\n\n return destroy\n}\n\nexport function destroy(): void {\n if (_pendingMount) {\n _pendingMount()\n _pendingMount = null\n }\n if (_unmount) {\n _unmount()\n _unmount = null\n }\n if (_host?.parentNode) _host.parentNode.removeChild(_host)\n _host = null\n}\n\n/* ──────────────────────────────────────────────────────────────────────────\n * Auto-init for <script> tag usage:\n *\n * <script\n * src=\"cdn.example.com/widget.js\"\n * type=\"module\"\n * data-markup-widget=\"true\"\n * data-api-url=\"https://your-deployment.convex.site\"\n * data-api-key=\"markup_...\"\n * data-position=\"bottom-right\"\n * ></script>\n *\n * Skip when there's no document (SSR) or when the script tag carries no\n * data attributes (assumed manual init via `init()`).\n * ────────────────────────────────────────────────────────────────────────── */\n\nif (typeof document !== 'undefined') {\n // `document.currentScript` is null for `type=\"module\"`, which is why\n // `data-markup-widget=\"true\"` is required for auto-init.\n const current =\n (document.currentScript as HTMLScriptElement | null) ??\n (document.querySelector('script[data-markup-widget=\"true\"]') as HTMLScriptElement | null)\n const apiUrl = current?.dataset.apiUrl\n const apiKey = current?.dataset.apiKey\n if (apiUrl && apiKey) {\n const position = current?.dataset.position as WidgetConfig['position'] | undefined\n const theme = current?.dataset.theme as WidgetTheme | undefined\n // Read but ignored, so `data-fab` still triggers the deprecation warning.\n const fab = current?.dataset.fab as WidgetFab | undefined\n const dashboardUrl = current?.dataset.dashboardUrl\n // Exact match only: a typo'd `data-analytics=\"flase\"` must not silently\n // disable it, so an opt-out has to be spelled correctly.\n const analytics = current?.dataset.analytics !== 'false'\n const start = () => init({ apiUrl, apiKey, position, theme, fab, dashboardUrl, analytics })\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', start, { once: true })\n } else {\n start()\n }\n }\n}\n"],"x_google_ignoreList":[0,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,35,43,44,45,46,47,48,49,50,51,52,58],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"widget.js","names":["l","u","t","i","r","o","e","f","c","a","s","h","p","v","y","d","w","_","m","k","C","q","D","A","T","j","z","B","u","i","f","n","i","Base64.fromByteArray","Base64.toByteArray","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","Base64.toByteArray","Base64.fromByteArray","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","__defProp","__defNormalProp","__publicField","r"],"sources":["../../../node_modules/.pnpm/preact@10.29.7/node_modules/preact/dist/preact.module.js","../src/styles.css?inline","../src/runtime/analytics.ts","../src/runtime/error-boundary.tsx","../src/runtime/error-reporter.ts","../src/runtime/theme-store.ts","../../../node_modules/.pnpm/preact@10.29.7/node_modules/preact/hooks/dist/hooks.module.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/index.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/values/base64.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/common/index.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/values/value.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/values/errors.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/logging.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/udf_path_utils.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/local_state.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/request_manager.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/server/functionName.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/server/components/paths.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/server/api.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/optimistic_updates_impl.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/vendor/long.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/remote_query_set.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/protocol.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/web_socket_manager.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/session.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/vendor/jwt-decode/index.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/authentication_manager.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/metrics.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/client.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/pagination.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/sync/paginated_query_client.js","../../../node_modules/.pnpm/convex@1.38.0_react@19.2.8/node_modules/convex/dist/esm/browser/simple_client.js","../src/lib/machine.ts","../src/lib/mentions.ts","../src/lib/use-async-action.ts","../../../node_modules/.pnpm/@medv+finder@4.0.2/node_modules/@medv/finder/finder.js","../src/runtime/anchor.ts","../src/runtime/api.ts","../src/runtime/cookie-probe.ts","../src/runtime/history-observer.ts","../src/runtime/safe-url.ts","../src/runtime/identity-store.ts","../src/runtime/popup-auth.ts","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/util.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/clone-pseudos.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/mimes.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/dataurl.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/clone-node.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/embed-resources.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/embed-images.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/apply-style.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/embed-webfonts.js","../../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/index.js","../src/runtime/screenshot.ts","../src/runtime/use-subscription-token.ts","../src/runtime/refresh-token.ts","../src/runtime/use-token-refresh.ts","../src/runtime/utils.ts","../../../node_modules/.pnpm/preact@10.29.7/node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js","../src/runtime/ui/icons.tsx","../src/runtime/ui/identity-menu.tsx","../src/runtime/use-drag.ts","../src/runtime/use-focus-trap.ts","../src/runtime/use-object-url.ts","../src/runtime/ui/author-prompt.tsx","../src/runtime/mention-input.ts","../src/runtime/ui/mentions.tsx","../src/runtime/ui/mention-input.tsx","../src/runtime/ui/composer.tsx","../src/runtime/ui/new-thread-popover.tsx","../src/runtime/ui/notifications-panel.tsx","../src/runtime/use-theme.ts","../src/runtime/ui/overflow-menu.tsx","../src/runtime/ui/panel-popover.tsx","../src/runtime/ui/pin.tsx","../src/runtime/ui/placement-overlay.tsx","../src/runtime/ui/privacy-panel.tsx","../src/runtime/ui/shortcuts-panel.tsx","../src/runtime/ui/thread-popover.tsx","../src/runtime/ui/toolbar.tsx","../src/runtime/ui/app.tsx","../src/runtime/mount.tsx","../src/widget.ts"],"sourcesContent":["var n,l,u,t,i,r,o,e,f,c,a,s,h,p,v,y,d={},w=[],_=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,g=Array.isArray;function m(n,l){for(var u in l)n[u]=l[u];return n}function b(n){n&&n.parentNode&&n.parentNode.removeChild(n)}function k(l,u,t){var i,r,o,e={};for(o in u)\"key\"==o?i=u[o]:\"ref\"==o?r=u[o]:e[o]=u[o];if(arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):t),\"function\"==typeof l&&null!=l.defaultProps)for(o in l.defaultProps)void 0===e[o]&&(e[o]=l.defaultProps[o]);return x(l,e,i,r,null)}function x(n,t,i,r,o){var e={type:n,props:t,key:i,ref:r,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:null==o?++u:o,__i:-1,__u:0};return null==o&&null!=l.vnode&&l.vnode(e),e}function M(){return{current:null}}function S(n){return n.children}function C(n,l){this.props=n,this.context=l}function $(n,l){if(null==l)return n.__?$(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?$(n):null}function I(n){if(n.__P&&n.__d){var u=n.__v,t=u.__e,i=[],r=[],o=m({},u);o.__v=u.__v+1,l.vnode&&l.vnode(o),q(n.__P,o,u,n.__n,n.__P.namespaceURI,32&u.__u?[t]:null,i,null==t?$(u):t,!!(32&u.__u),r),o.__v=u.__v,o.__.__k[o.__i]=o,D(i,o,r),u.__e=u.__=null,o.__e!=t&&P(o)}}function P(n){if(null!=(n=n.__)&&null!=n.__c)return n.__e=n.__c.base=null,n.__k.some(function(l){if(null!=l&&null!=l.__e)return n.__e=n.__c.base=l.__e}),P(n)}function A(n){(!n.__d&&(n.__d=!0)&&i.push(n)&&!H.__r++||r!=l.debounceRendering)&&((r=l.debounceRendering)||o)(H)}function H(){try{for(var n,l=1;i.length;)i.length>l&&i.sort(e),n=i.shift(),l=i.length,I(n)}finally{i.length=H.__r=0}}function L(n,l,u,t,i,r,o,e,f,c,a){var s,h,p,v,y,_,g,m=t&&t.__k||w,b=l.length;for(f=T(u,l,m,f,b),s=0;s<b;s++)null!=(p=u.__k[s])&&(h=-1!=p.__i&&m[p.__i]||d,p.__i=s,_=q(n,p,h,i,r,o,e,f,c,a),v=p.__e,p.ref&&h.ref!=p.ref&&(h.ref&&J(h.ref,null,p),a.push(p.ref,p.__c||v,p)),null==y&&null!=v&&(y=v),(g=!!(4&p.__u))||h.__k===p.__k?(f=j(p,f,n,g),g&&h.__e&&(h.__e=null)):\"function\"==typeof p.type&&void 0!==_?f=_:v&&(f=v.nextSibling),p.__u&=-7);return u.__e=y,f}function T(n,l,u,t,i){var r,o,e,f,c,a=u.length,s=a,h=0;for(n.__k=new Array(i),r=0;r<i;r++)null!=(o=l[r])&&\"boolean\"!=typeof o&&\"function\"!=typeof o?(\"string\"==typeof o||\"number\"==typeof o||\"bigint\"==typeof o||o.constructor==String?o=n.__k[r]=x(null,o,null,null,null):g(o)?o=n.__k[r]=x(S,{children:o},null,null,null):void 0===o.constructor&&o.__b>0?o=n.__k[r]=x(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):n.__k[r]=o,f=r+h,o.__=n,o.__b=n.__b+1,e=null,-1!=(c=o.__i=O(o,u,f,s))&&(s--,(e=u[c])&&(e.__u|=2)),null==e||null==e.__v?(-1==c&&(i>a?h--:i<a&&h++),\"function\"!=typeof o.type&&(o.__u|=4)):c!=f&&(c==f-1?h--:c==f+1?h++:(c>f?h--:h++,o.__u|=4))):n.__k[r]=null;if(s)for(r=0;r<a;r++)null!=(e=u[r])&&0==(2&e.__u)&&(e.__e==t&&(t=$(e)),K(e,e));return t}function j(n,l,u,t){var i,r;if(\"function\"==typeof n.type){for(i=n.__k,r=0;i&&r<i.length;r++)i[r]&&(i[r].__=n,l=j(i[r],l,u,t));return l}n.__e!=l&&(t&&(l&&n.type&&!l.parentNode&&(l=$(n)),u.insertBefore(n.__e,l||null)),l=n.__e);do{l=l&&l.nextSibling}while(null!=l&&8==l.nodeType);return l}function F(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(g(n)?n.some(function(n){F(n,l)}):l.push(n)),l}function O(n,l,u,t){var i,r,o,e=n.key,f=n.type,c=l[u],a=null!=c&&0==(2&c.__u);if(null===c&&null==e||a&&e==c.key&&f==c.type)return u;if(t>(a?1:0))for(i=u-1,r=u+1;i>=0||r<l.length;)if(null!=(c=l[o=i>=0?i--:r++])&&0==(2&c.__u)&&e==c.key&&f==c.type)return o;return-1}function z(n,l,u){\"-\"==l[0]?n.setProperty(l,null==u?\"\":u):n[l]=null==u?\"\":\"number\"!=typeof u||_.test(l)?u:u+\"px\"}function N(n,l,u,t,i){var r,o;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||z(n.style,l,\"\");if(u)for(l in u)t&&u[l]==t[l]||z(n.style,l,u[l])}else if(\"o\"==l[0]&&\"n\"==l[1])r=l!=(l=l.replace(s,\"$1\")),o=l.toLowerCase(),l=o in n||\"onFocusOut\"==l||\"onFocusIn\"==l?o.slice(2):l.slice(2),n.l||(n.l={}),n.l[l+r]=u,u?t?u[a]=t[a]:(u[a]=h,n.addEventListener(l,r?v:p,r)):n.removeEventListener(l,r?v:p,r);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 V(n){return function(u){if(this.l){var t=this.l[u.type+n];if(null==u[c])u[c]=h++;else if(u[c]<t[a])return;return t(l.event?l.event(u):u)}}}function q(n,u,t,i,r,o,e,f,c,a){var s,h,p,v,y,d,_,k,x,M,$,I,P,A,H,T,j=u.type;if(void 0!==u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),o=[f=u.__e=t.__e]),(s=l.__b)&&s(u);n:if(\"function\"==typeof j){h=e.length;try{if(x=u.props,M=j.prototype&&j.prototype.render,$=(s=j.contextType)&&i[s.__c],I=s?$?$.props.value:s.__:i,t.__c?k=(p=u.__c=t.__c).__=p.__E:(M?u.__c=p=new j(x,I):(u.__c=p=new C(x,I),p.constructor=j,p.render=Q),$&&$.sub(p),p.state||(p.state={}),p.__n=i,v=p.__d=!0,p.__h=[],p._sb=[]),M&&null==p.__s&&(p.__s=p.state),M&&null!=j.getDerivedStateFromProps&&(p.__s==p.state&&(p.__s=m({},p.__s)),m(p.__s,j.getDerivedStateFromProps(x,p.__s))),y=p.props,d=p.state,p.__v=u,v)M&&null==j.getDerivedStateFromProps&&null!=p.componentWillMount&&p.componentWillMount(),M&&null!=p.componentDidMount&&p.__h.push(p.componentDidMount);else{if(M&&null==j.getDerivedStateFromProps&&x!==y&&null!=p.componentWillReceiveProps&&p.componentWillReceiveProps(x,I),u.__v==t.__v||!p.__e&&null!=p.shouldComponentUpdate&&!1===p.shouldComponentUpdate(x,p.__s,I)){u.__v!=t.__v&&(p.props=x,p.state=p.__s,p.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.some(function(n){n&&(n.__=u)}),w.push.apply(p.__h,p._sb),p._sb=[],p.__h.length&&e.push(p);break n}null!=p.componentWillUpdate&&p.componentWillUpdate(x,p.__s,I),M&&null!=p.componentDidUpdate&&p.__h.push(function(){p.componentDidUpdate(y,d,_)})}if(p.context=I,p.props=x,p.__P=n,p.__e=!1,P=l.__r,A=0,M)p.state=p.__s,p.__d=!1,P&&P(u),s=p.render(p.props,p.state,p.context),w.push.apply(p.__h,p._sb),p._sb=[];else do{p.__d=!1,P&&P(u),s=p.render(p.props,p.state,p.context),p.state=p.__s}while(p.__d&&++A<25);p.state=p.__s,null!=p.getChildContext&&(i=m(m({},i),p.getChildContext())),M&&!v&&null!=p.getSnapshotBeforeUpdate&&(_=p.getSnapshotBeforeUpdate(y,d)),H=null!=s&&s.type===S&&null==s.key?E(s.props.children):s,f=L(n,g(H)?H:[H],u,t,i,r,o,e,f,c,a),p.base=u.__e,u.__u&=-161,p.__h.length&&e.push(p),k&&(p.__E=p.__=null)}catch(n){if(e.length=h,u.__v=null,c||null!=o){if(n.then){for(u.__u|=c?160:128;f&&8==f.nodeType&&f.nextSibling;)f=f.nextSibling;null!=o&&(o[o.indexOf(f)]=null),u.__e=f}else if(null!=o)for(T=o.length;T--;)b(o[T])}else u.__e=t.__e;null==u.__k&&(u.__k=t.__k||[]),n.then||B(u),l.__e(n,u,t)}}else null==o&&u.__v==t.__v?(u.__k=t.__k,u.__e=t.__e):f=u.__e=G(t.__e,u,t,i,r,o,e,c,a);return(s=l.diffed)&&s(u),128&u.__u?void 0:f}function B(n){n&&(n.__c&&(n.__c.__e=!0),n.__k&&n.__k.some(B))}function D(n,u,t){for(var i=0;i<t.length;i++)J(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 E(n){return\"object\"!=typeof n||null==n||n.__b>0?n:g(n)?n.map(E):void 0!==n.constructor?null:m({},n)}function G(u,t,i,r,o,e,f,c,a){var s,h,p,v,y,w,_,m=i.props||d,k=t.props,x=t.type;if(\"svg\"==x?o=\"http://www.w3.org/2000/svg\":\"math\"==x?o=\"http://www.w3.org/1998/Math/MathML\":o||(o=\"http://www.w3.org/1999/xhtml\"),null!=e)for(s=0;s<e.length;s++)if((y=e[s])&&\"setAttribute\"in y==!!x&&(x?y.localName==x:3==y.nodeType)){u=y,e[s]=null;break}if(null==u){if(null==x)return document.createTextNode(k);u=document.createElementNS(o,x,k.is&&k),c&&(l.__m&&l.__m(t,e),c=!1),e=null}if(null==x)m===k||c&&u.data==k||(u.data=k);else{if(e=\"textarea\"==x&&null!=k.defaultValue?null:e&&n.call(u.childNodes),!c&&null!=e)for(m={},s=0;s<u.attributes.length;s++)m[(y=u.attributes[s]).name]=y.value;for(s in m)y=m[s],\"dangerouslySetInnerHTML\"==s?p=y:\"children\"==s||s in k||\"value\"==s&&\"defaultValue\"in k||\"checked\"==s&&\"defaultChecked\"in k||N(u,s,null,y,o);for(s in k)y=k[s],\"children\"==s?v=y:\"dangerouslySetInnerHTML\"==s?h=y:\"value\"==s?w=y:\"checked\"==s?_=y:c&&\"function\"!=typeof y||m[s]===y||N(u,s,y,m[s],o);if(h)c||p&&(h.__html==p.__html||h.__html==u.innerHTML)||(u.innerHTML=h.__html),t.__k=[];else if(p&&(u.innerHTML=\"\"),L(\"template\"==t.type?u.content:u,g(v)?v:[v],t,i,r,\"foreignObject\"==x?\"http://www.w3.org/1999/xhtml\":o,e,f,e?e[0]:i.__k&&$(i,0),c,a),null!=e)for(s=e.length;s--;)b(e[s]);c&&\"textarea\"!=x||(s=\"value\",\"progress\"==x&&null==w?u.removeAttribute(\"value\"):null!=w&&(w!==u[s]||\"progress\"==x&&!w||\"option\"==x&&w!=m[s])&&N(u,s,w,m[s],o),s=\"checked\",null!=_&&_!=u[s]&&N(u,s,_,m[s],o))}return u}function J(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 K(n,u,t){var i,r;if(l.unmount&&l.unmount(n),(i=n.ref)&&(i.current&&i.current!=n.__e||J(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(n){l.__e(n,u)}i.base=i.__P=i.__n=null}if(i=n.__k)for(r=0;r<i.length;r++)i[r]&&K(i[r],u,t||\"function\"!=typeof n.type);t||b(n.__e),n.__c=n.__=n.__e=void 0}function Q(n,l,u){return this.constructor(n,u)}function R(u,t,i){var r,o,e,f;t==document&&(t=document.documentElement),l.__&&l.__(u,t),o=(r=\"function\"==typeof i)?null:i&&i.__k||t.__k,e=[],f=[],q(t,u=(!r&&i||t).__k=k(S,null,[u]),o||d,d,t.namespaceURI,!r&&i?[i]:o?null:t.firstChild?n.call(t.childNodes):null,e,!r&&i?i:o?o.__e:t.firstChild,r,f),D(e,u,f),u.props.children=null}function U(n,l){R(n,l,U)}function W(l,u,t){var i,r,o,e,f=m({},l.props);for(o in l.type&&l.type.defaultProps&&(e=l.type.defaultProps),u)\"key\"==o?i=u[o]:\"ref\"==o?r=u[o]:f[o]=void 0===u[o]&&null!=e?e[o]:u[o];return arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),x(l.type,f,i||l.key,r||l.ref,null)}function X(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,A(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\"+y++,l.__=n,l.Provider=l.__l=(l.Consumer=function(n,l){return n.children(l)}).contextType=l,l}n=w.slice,l={__e:function(n,l,u,t){for(var i,r,o;l=l.__;)if((i=l.__c)&&!i.__)try{if((r=i.constructor)&&null!=r.getDerivedStateFromError&&(i.setState(r.getDerivedStateFromError(n)),o=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),o=i.__d),o)return i.__E=i}catch(l){n=l}throw n}},u=0,t=function(n){return null!=n&&void 0===n.constructor},C.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!=this.state?this.__s:this.__s=m({},this.state),\"function\"==typeof n&&(n=n(m({},u),this.props)),n&&m(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),A(this))},C.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),A(this))},C.prototype.render=S,i=[],o=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,e=function(n,l){return n.__v.__b-l.__v.__b},H.__r=0,f=Math.random().toString(8),c=\"__d\"+f,a=\"__a\"+f,s=/(PointerCapture)$|Capture$/i,h=0,p=V(!1),v=V(!0),y=0;export{C as Component,S as Fragment,W as cloneElement,X as createContext,k as createElement,M as createRef,k as h,U as hydrate,t as isValidElement,l as options,R as render,F as toChildArray};\n//# sourceMappingURL=preact.module.js.map\n","/*\n * Deliberately not Tailwind: a hand-rolled stylesheet is smaller, ships as a\n * single shadow-DOM <style>, and can't conflict with the host page.\n */\n\n:host {\n --markup-paper: #fdfcfa;\n --markup-surface: #ffffff;\n --markup-surface-2: oklch(0.985 0.002 250);\n --markup-surface-3: oklch(0.95 0.003 250);\n --markup-hover: oklch(0.95 0.003 250);\n --markup-ink: #1a1614;\n --markup-ink-soft: oklch(0.32 0.005 250);\n --markup-muted: #6b6661;\n --markup-border: rgba(26, 22, 20, 0.1);\n --markup-border-strong: rgba(26, 22, 20, 0.18);\n --markup-brand: #e35d2a;\n --markup-brand-hover: #c84d20;\n --markup-accent-soft: oklch(0.95 0.04 60);\n --markup-accent-ink: oklch(0.45 0.14 38);\n --markup-accent-glow: color-mix(in srgb, var(--markup-brand) 28%, transparent);\n --markup-team: #2a4ac8;\n --markup-shadow: 0 1px 2px rgba(26, 22, 20, 0.06), 0 8px 28px rgba(26, 22, 20, 0.12);\n --markup-shadow-toolbar:\n 0 1px 1px rgba(0, 0, 0, 0.04), 0 4px 10px -2px rgba(15, 20, 40, 0.1),\n 0 18px 36px -12px rgba(15, 20, 40, 0.18);\n --markup-shadow-pop:\n 0 1px 1px rgba(0, 0, 0, 0.04), 0 8px 24px -6px rgba(15, 20, 40, 0.12),\n 0 28px 60px -18px rgba(15, 20, 40, 0.22);\n --markup-overlay-tint: rgba(26, 22, 20, 0.04);\n --markup-danger: #dc2626;\n --markup-success: oklch(0.62 0.16 150);\n --markup-radius: 6px;\n --markup-radius-sm: 4px;\n --markup-font:\n 'Geist Variable', 'Geist', ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI',\n system-ui, sans-serif;\n --markup-font-mono:\n 'Geist Mono Variable', 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n\n all: initial;\n font-family: var(--markup-font);\n font-size: 14px;\n line-height: 1.5;\n color: var(--markup-ink);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* `data-theme=\"light\"` wins over the media query, so a host can force light. */\n:host([data-theme='dark']) {\n --markup-paper: #1a1614;\n --markup-surface: oklch(0.16 0.005 250);\n --markup-surface-2: oklch(0.2 0.005 250);\n --markup-surface-3: oklch(0.24 0.005 250);\n --markup-hover: oklch(0.24 0.005 250);\n --markup-ink: #fdfcfa;\n --markup-ink-soft: oklch(0.8 0.005 250);\n --markup-muted: #a8a39e;\n --markup-border: rgba(253, 252, 250, 0.12);\n --markup-border-strong: rgba(253, 252, 250, 0.22);\n --markup-team: #7b99f0;\n --markup-accent-soft: color-mix(in srgb, var(--markup-brand) 22%, transparent);\n --markup-accent-ink: oklch(0.86 0.13 55);\n --markup-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 12px 40px rgba(0, 0, 0, 0.45);\n --markup-shadow-toolbar:\n 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 1px 2px rgba(0, 0, 0, 0.4),\n 0 12px 30px -10px rgba(0, 0, 0, 0.55), 0 28px 60px -20px rgba(0, 0, 0, 0.5);\n --markup-shadow-pop:\n 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 8px 24px -6px rgba(0, 0, 0, 0.45),\n 0 28px 60px -18px rgba(0, 0, 0, 0.55);\n --markup-overlay-tint: rgba(253, 252, 250, 0.05);\n --markup-danger: #f87171;\n}\n\n@media (prefers-color-scheme: dark) {\n :host(:not([data-theme])) {\n --markup-paper: #1a1614;\n --markup-surface: oklch(0.16 0.005 250);\n --markup-surface-2: oklch(0.2 0.005 250);\n --markup-surface-3: oklch(0.24 0.005 250);\n --markup-hover: oklch(0.24 0.005 250);\n --markup-ink: #fdfcfa;\n --markup-ink-soft: oklch(0.8 0.005 250);\n --markup-muted: #a8a39e;\n --markup-border: rgba(253, 252, 250, 0.12);\n --markup-border-strong: rgba(253, 252, 250, 0.22);\n --markup-team: #7b99f0;\n --markup-accent-soft: color-mix(in srgb, var(--markup-brand) 22%, transparent);\n --markup-accent-ink: oklch(0.86 0.13 55);\n --markup-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 12px 40px rgba(0, 0, 0, 0.45);\n --markup-shadow-toolbar:\n 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 1px 2px rgba(0, 0, 0, 0.4),\n 0 12px 30px -10px rgba(0, 0, 0, 0.55), 0 28px 60px -20px rgba(0, 0, 0, 0.5);\n --markup-shadow-pop:\n 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 8px 24px -6px rgba(0, 0, 0, 0.45),\n 0 28px 60px -18px rgba(0, 0, 0, 0.55);\n --markup-overlay-tint: rgba(253, 252, 250, 0.05);\n --markup-danger: #f87171;\n }\n}\n\n.markup-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n\n.markup-shadow-root {\n font-family: var(--markup-font);\n}\n\n.markup-shadow-root *,\n.markup-shadow-root *::before,\n.markup-shadow-root *::after {\n box-sizing: border-box;\n}\n\n/* `:where()` zeroes specificity so these never beat component overrides. */\n:where(.markup-shadow-root button, .markup-shadow-root input, .markup-shadow-root textarea) {\n font: inherit;\n color: inherit;\n}\n\n.markup-eyebrow {\n font-family: var(--markup-font-mono);\n font-size: 10px;\n font-weight: 500;\n letter-spacing: 0.12em;\n text-transform: uppercase;\n color: var(--markup-muted);\n}\n\n/* ────────── Toolbar pill ────────── */\n\n.markup-toolbar {\n position: fixed;\n bottom: 22px;\n z-index: 10;\n display: inline-flex;\n align-items: center;\n height: 44px;\n padding: 4px;\n gap: 2px;\n background: var(--markup-surface);\n border: 1px solid var(--markup-border);\n border-radius: 9999px;\n pointer-events: none;\n box-shadow: var(--markup-shadow-toolbar);\n /* Every position class defines both `left` and `transform`, so CSS can\n * transition between any pair. Going through `auto` breaks the animation. */\n left: 100%;\n transform: translateX(calc(-100% - 22px));\n transition:\n box-shadow 150ms ease,\n left 220ms cubic-bezier(0.2, 0.7, 0.2, 1),\n transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1);\n}\n.markup-toolbar > * {\n pointer-events: auto;\n}\n\n.markup-tb-btn {\n position: relative;\n width: 36px;\n height: 36px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 0;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 9999px;\n color: var(--markup-ink-soft);\n cursor: pointer;\n touch-action: none;\n font-family: var(--markup-font);\n font-size: 13px;\n font-weight: 500;\n transition:\n background 120ms ease,\n color 120ms ease;\n}\n.markup-tb-btn:hover {\n background: var(--markup-hover);\n color: var(--markup-ink);\n}\n.markup-tb-btn:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 2px var(--markup-surface),\n 0 0 0 4px var(--markup-accent-glow);\n}\n.markup-tb-btn[data-on='true'] {\n background: var(--markup-ink);\n color: var(--markup-paper);\n}\n:host([data-theme='dark']) .markup-tb-btn[data-on='true'],\n:host(:not([data-theme])) .markup-tb-btn[data-on='true'] {\n /* Dark mode: pressed/open state uses surface-3 since the ink is now\n * near-white and an inverted swap would lose all contrast. */\n}\n@media (prefers-color-scheme: dark) {\n :host(:not([data-theme])) .markup-tb-btn[data-on='true'] {\n background: var(--markup-surface-3);\n color: var(--markup-ink);\n }\n}\n:host([data-theme='dark']) .markup-tb-btn[data-on='true'] {\n background: var(--markup-surface-3);\n color: var(--markup-ink);\n}\n.markup-tb-btn[data-armed='true'] {\n background: var(--markup-brand);\n color: #fff;\n}\n.markup-tb-btn[data-armed='true']:hover {\n background: var(--markup-brand-hover);\n color: #fff;\n}\n.markup-tb-btn[disabled] {\n color: color-mix(in srgb, var(--markup-muted) 60%, transparent);\n cursor: default;\n}\n.markup-tb-btn[disabled]:hover {\n background: transparent;\n color: color-mix(in srgb, var(--markup-muted) 60%, transparent);\n}\n\n.markup-tb-btn[data-kind='identity'] {\n width: auto;\n padding: 0 4px;\n gap: 6px;\n}\n.markup-tb-avatar {\n width: 28px;\n height: 28px;\n border-radius: 9999px;\n background: var(--markup-surface-3);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n font-weight: 600;\n color: var(--markup-ink);\n overflow: hidden;\n border: 1px solid var(--markup-border);\n flex-shrink: 0;\n}\n.markup-tb-avatar.is-anon {\n color: var(--markup-muted);\n background: var(--markup-surface-2);\n}\n\n.markup-tb-sep {\n width: 1px;\n height: 20px;\n background: var(--markup-border);\n margin: 0 4px;\n flex-shrink: 0;\n}\n\n.markup-tb-badge {\n position: absolute;\n top: 0;\n right: 0;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 9999px;\n background: var(--markup-brand);\n color: #fff;\n font-family: var(--markup-font-mono);\n font-size: 9.5px;\n font-weight: 600;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 0 0 2px var(--markup-surface);\n pointer-events: none;\n}\n\n/* Both properties in every variant, so any pair of positions animates. */\n.markup-toolbar-left {\n left: 0;\n transform: translateX(22px);\n}\n.markup-toolbar-center {\n left: 50%;\n transform: translateX(-50%);\n}\n.markup-toolbar-right {\n left: 100%;\n transform: translateX(calc(-100% - 22px));\n}\n\n/* ────────── Toolbar popovers (overflow / identity / inbox) ──────────\n *\n * Each pops above its anchor button and shares the same surface chrome.\n * `data-pop` distinguishes width and inner padding rules.\n */\n.markup-pop {\n position: absolute;\n bottom: calc(100% + 8px);\n background: var(--markup-surface);\n border: 1px solid var(--markup-border);\n border-radius: 12px;\n box-shadow: var(--markup-shadow-pop);\n font-size: 13px;\n color: var(--markup-ink);\n z-index: 11;\n animation: markup-pop-in 140ms cubic-bezier(0.2, 0.7, 0.2, 1);\n overflow: hidden;\n}\n.markup-pop[data-pop='overflow'] {\n width: 260px;\n padding: 6px;\n}\n.markup-pop[data-pop='identity'] {\n width: 240px;\n padding: 6px;\n}\n.markup-pop[data-pop='inbox'] {\n width: 380px;\n padding: 0;\n}\n.markup-pop.is-anchor-right {\n right: 0;\n}\n.markup-pop.is-anchor-left {\n left: 0;\n}\n.markup-pop.is-anchor-center {\n left: 50%;\n transform: translateX(-50%);\n}\n\n@keyframes markup-pop-in {\n from {\n opacity: 0;\n transform: translateY(6px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.markup-pop.is-anchor-center {\n animation-name: markup-pop-in-center;\n}\n@keyframes markup-pop-in-center {\n from {\n opacity: 0;\n transform: translate(-50%, 6px);\n }\n to {\n opacity: 1;\n transform: translate(-50%, 0);\n }\n}\n\n/* ────────── Overflow menu — appearance, position, behavior, footer ────────── */\n\n.markup-pop-group-label {\n font-family: var(--markup-font-mono);\n font-size: 10px;\n letter-spacing: 0.06em;\n color: var(--markup-muted);\n text-transform: lowercase;\n padding: 8px 10px 4px;\n}\n\n/* Icon-only buttons keep the row inside the 260px popover without crowding\n * the label. Shared by Appearance and Position. */\n.markup-segmented-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 7px 8px;\n border-radius: 6px;\n}\n.markup-segmented-row .lbl {\n flex: 1;\n min-width: 0;\n font-size: 13px;\n color: var(--markup-ink);\n}\n\n.markup-segmented {\n display: inline-flex;\n gap: 2px;\n padding: 2px;\n background: var(--markup-surface-3);\n border-radius: 7px;\n}\n.markup-segmented button {\n background: transparent;\n border: none;\n font: inherit;\n width: 28px;\n height: 24px;\n padding: 0;\n border-radius: 5px;\n color: var(--markup-muted);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition:\n background 100ms ease,\n color 100ms ease;\n}\n.markup-segmented button:hover {\n color: var(--markup-ink);\n}\n.markup-segmented button.is-on {\n background: var(--markup-surface);\n color: var(--markup-ink);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.markup-menu-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 7px 8px;\n border-radius: 6px;\n font-size: 13px;\n cursor: pointer;\n width: 100%;\n background: transparent;\n border: none;\n color: inherit;\n font-family: inherit;\n text-align: left;\n}\n.markup-menu-row:hover {\n background: var(--markup-hover);\n}\n.markup-menu-row:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.markup-menu-row:disabled:hover {\n background: transparent;\n}\n.markup-menu-row .ic {\n width: 16px;\n height: 16px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--markup-muted);\n flex-shrink: 0;\n}\n.markup-menu-row .lbl {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n.markup-menu-row .lbl .sub {\n font-size: 11px;\n color: var(--markup-muted);\n margin-top: 1px;\n}\n.markup-menu-row .right {\n margin-left: auto;\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n color: var(--markup-muted);\n}\n.markup-menu-row.is-danger {\n color: var(--markup-danger);\n}\n.markup-menu-row.is-danger .ic {\n color: var(--markup-danger);\n}\n.markup-menu-row.is-danger:hover {\n background: color-mix(in srgb, var(--markup-danger) 10%, transparent);\n}\n\n.markup-menu-row .switch {\n width: 26px;\n height: 16px;\n background: var(--markup-border-strong);\n border-radius: 9999px;\n position: relative;\n transition: background 120ms ease;\n flex-shrink: 0;\n}\n.markup-menu-row .switch::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: 12px;\n height: 12px;\n background: var(--markup-surface);\n border-radius: 9999px;\n transition: left 120ms ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);\n}\n.markup-menu-row[data-on='true'] .switch {\n background: var(--markup-brand);\n}\n.markup-menu-row[data-on='true'] .switch::after {\n left: 12px;\n}\n\n.markup-menu-divider {\n height: 1px;\n background: var(--markup-border);\n margin: 4px 0;\n}\n\n.markup-brand-line {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n color: var(--markup-muted);\n border-top: 1px solid var(--markup-border);\n margin-top: 6px;\n text-decoration: none;\n}\n.markup-brand-line:hover {\n color: var(--markup-ink);\n}\n.markup-brand-line svg {\n color: var(--markup-brand);\n}\n.markup-brand-line .ver {\n margin-left: auto;\n}\n\n/* ────────── Identity menu ────────── */\n\n.markup-id-who {\n padding: 10px 8px 12px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n border-bottom: 1px solid var(--markup-border);\n margin-bottom: 4px;\n}\n.markup-id-who .nm {\n font-weight: 600;\n font-size: 13.5px;\n color: var(--markup-ink);\n}\n.markup-id-who .em {\n font-family: var(--markup-font-mono);\n font-size: 11px;\n color: var(--markup-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.markup-id-anon {\n padding: 14px 10px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n text-align: left;\n}\n.markup-id-anon .h {\n font-size: 14px;\n font-weight: 600;\n letter-spacing: -0.005em;\n color: var(--markup-ink);\n}\n.markup-id-anon .sub {\n font-size: 12.5px;\n color: var(--markup-muted);\n line-height: 18px;\n}\n.markup-id-anon button:not(.markup-menu-row) {\n width: 100%;\n background: var(--markup-ink);\n color: var(--markup-paper);\n border: none;\n height: 32px;\n border-radius: 7px;\n font: inherit;\n font-weight: 500;\n font-size: 13px;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n.markup-id-anon button:disabled {\n opacity: 0.7;\n cursor: default;\n}\n.markup-id-anon button:not(.markup-menu-row):hover:not(:disabled) {\n background: color-mix(in srgb, var(--markup-ink) 88%, var(--markup-surface));\n}\n\n/* ────────── HUD-hidden toast ──────────\n * Brief instructional message shown once when the HUD is hidden via\n * shortcut or modifier-click. Mirrors the FAB corner so the user's\n * eye lands in the same spot the FAB just vacated; auto-dismisses. */\n\n.markup-hud-hidden-toast {\n position: fixed;\n bottom: 24px;\n z-index: 10;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px;\n border-radius: 999px;\n background: var(--markup-ink);\n color: var(--markup-paper);\n font-size: 12px;\n font-weight: 500;\n letter-spacing: -0.01em;\n box-shadow: var(--markup-shadow);\n pointer-events: none;\n animation:\n markup-hud-hidden-in 220ms ease-out,\n markup-hud-hidden-out 320ms ease-in 4.6s forwards;\n}\n.markup-hud-hidden-toast-right {\n right: 24px;\n}\n.markup-hud-hidden-toast-left {\n left: 24px;\n}\n.markup-hud-hidden-toast-center {\n left: 0;\n right: 0;\n margin-inline: auto;\n width: max-content;\n}\n.markup-kbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--markup-paper) 14%, transparent);\n color: var(--markup-paper);\n font-family: var(--markup-font);\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n}\n/* Retinted for a light surface: the base rule dresses these for the dark HUD\n toast, where `--markup-paper` is the foreground. */\n.markup-kbd.is-inline {\n min-width: 14px;\n height: 14px;\n padding: 0 3px;\n border-radius: 3px;\n background: color-mix(in srgb, var(--markup-ink) 8%, transparent);\n color: var(--markup-muted);\n font-size: 9.5px;\n}\n\n@keyframes markup-hud-hidden-in {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n@keyframes markup-hud-hidden-out {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(4px);\n }\n}\n\n/* ────────── Pins layer ────────── */\n\n.markup-pins-layer {\n position: fixed;\n inset: 0;\n pointer-events: none;\n}\n\n/* The paper-coloured ring is what makes the pin read on any backdrop, and the\n * asymmetric radius gives the disc its comment-bubble tail. Translated so the\n * click point sits at that tail rather than at the centre. */\n.markup-pin {\n position: absolute;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n margin: 0;\n padding: 0;\n border: 2px solid var(--markup-paper);\n background: var(--markup-brand);\n color: #fff;\n border-radius: 999px 999px 999px 4px;\n font-family: var(--markup-font-mono);\n font-size: 11.5px;\n font-weight: 600;\n line-height: 1;\n cursor: pointer;\n pointer-events: auto;\n transform: translate(-50%, -100%);\n box-shadow:\n 0 4px 14px -4px rgba(0, 0, 0, 0.35),\n 0 0 0 1px color-mix(in srgb, var(--markup-brand) 50%, transparent);\n transition:\n background 150ms ease,\n color 150ms ease,\n opacity 150ms ease,\n top 200ms ease,\n left 200ms ease;\n}\n\n/* Deliberately close to the rest paint: an \"I'm clickable\" cue, not a state\n * change. */\n.markup-pin:hover {\n background: color-mix(in oklab, var(--markup-brand) 92%, black);\n}\n:host([data-theme='dark']) .markup-pin:hover {\n background: color-mix(in oklab, var(--markup-brand) 88%, var(--markup-paper));\n}\n@media (prefers-color-scheme: dark) {\n :host(:not([data-theme])) .markup-pin:hover {\n background: color-mix(in oklab, var(--markup-brand) 88%, var(--markup-paper));\n }\n}\n\n/* Same paint as rest: the open pin is re-located by its popover, not by a\n * colour shift. */\n.markup-pin.is-active {\n background: var(--markup-brand);\n color: #fff;\n border-color: var(--markup-paper);\n}\n.markup-pin.is-anchor {\n anchor-name: --markup-active-anchor;\n}\n\n/* Anchor selector didn't resolve, so the pin is at its fraction fallback.\n * Dimmed so a likely-wrong location reads as tentative. */\n.markup-pin.is-unresolved {\n opacity: 0.6;\n}\n\n/* Shown at the click point while the new-thread composer is open. */\n.markup-pin-ghost {\n background: var(--markup-brand);\n color: #fff;\n cursor: default;\n pointer-events: none;\n animation: markup-ghost-pulse 1200ms ease-in-out infinite;\n}\n\n/* Nudged up-right because the asymmetric disc's 4px corner shifts the\n * optical centre away from the geometric one. */\n.markup-pin-num {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n}\n\n/* Unused until an unread-reply count lands server-side. */\n.markup-pin-count {\n position: absolute;\n top: -6px;\n right: -8px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 999px;\n background: var(--markup-ink);\n color: var(--markup-paper);\n font-family: var(--markup-font-mono);\n font-size: 9.5px;\n font-weight: 600;\n line-height: 12px;\n text-align: center;\n border: 2px solid var(--markup-paper);\n pointer-events: none;\n}\n\n@keyframes markup-ghost-pulse {\n 0%,\n 100% {\n box-shadow:\n 0 4px 14px -4px rgba(0, 0, 0, 0.35),\n 0 0 0 0 rgba(227, 93, 42, 0.4);\n }\n 50% {\n box-shadow:\n 0 4px 14px -4px rgba(0, 0, 0, 0.35),\n 0 0 0 10px rgba(227, 93, 42, 0);\n }\n}\n\n/* ────────── Placement overlay ────────── */\n\n.markup-placement-overlay {\n position: fixed;\n inset: 0;\n background: var(--markup-overlay-tint);\n cursor: crosshair;\n pointer-events: auto;\n z-index: 1;\n animation: markup-overlay-in 180ms ease-out;\n}\n.markup-placement-cursor-help {\n position: fixed;\n top: 24px;\n left: 50%;\n /* baseline transform; the keyframes animate from a higher offset */\n transform: translate(-50%, 0);\n padding: 10px 16px;\n background: var(--markup-ink);\n color: var(--markup-paper);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 500;\n letter-spacing: -0.01em;\n box-shadow: var(--markup-shadow);\n pointer-events: none;\n animation: markup-help-in 220ms ease-out 60ms backwards;\n}\n\n@keyframes markup-overlay-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes markup-help-in {\n from {\n opacity: 0;\n transform: translate(-50%, -8px);\n }\n to {\n opacity: 1;\n transform: translate(-50%, 0);\n }\n}\n\n/* ────────── Popover ────────── */\n\n/*\n * `popover=\"auto\"` buys top-layer promotion plus ESC and outside-click\n * dismissal for free, at the cost of overriding the UA defaults below.\n * Position falls back to JS-supplied custom properties where CSS Anchor\n * Positioning isn't supported.\n */\n.markup-popover {\n position: fixed;\n inset: auto;\n margin: 0;\n padding: 0;\n width: 360px;\n max-width: calc(100vw - 24px);\n height: auto;\n /* never grow taller than the viewport — comments list scrolls inside */\n max-height: calc(100dvh - 24px);\n left: var(--markup-pop-x, 0);\n top: var(--markup-pop-y, 0);\n display: flex;\n flex-direction: column;\n gap: 0;\n background: var(--markup-paper);\n color: var(--markup-ink);\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius);\n box-shadow: var(--markup-shadow);\n pointer-events: auto;\n overflow: hidden;\n animation: markup-popover-in 160ms ease-out;\n}\n\n@supports (anchor-name: --x) {\n .markup-popover {\n position-anchor: --markup-active-anchor;\n left: calc(anchor(right) + 8px);\n top: calc(anchor(top) - 9px);\n /* Prefer whichever placement leaves the most block-axis room, so a pin near\n * the bottom flips above rather than clipping. */\n position-try-fallbacks:\n flip-block,\n flip-inline,\n flip-block flip-inline;\n position-try-order: most-block-size;\n }\n /* After a drag, anchor positioning and flip-fallbacks would fight the\n * user-chosen coords. */\n .markup-popover.is-floating {\n left: var(--markup-pop-x, 0);\n top: var(--markup-pop-y, 0);\n position-try-fallbacks: none;\n }\n}\n\n/* Mounted through a HUD-hide so drafts and drag position survive a peek. */\n.markup-popover.is-hud-hidden {\n display: none;\n}\n\n@keyframes markup-popover-in {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n.markup-popover-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-bottom: 1px solid var(--markup-border);\n cursor: grab;\n user-select: none;\n /* Claim touch gestures so a finger drag on the header moves the popover\n * instead of scrolling the page underneath. */\n touch-action: none;\n}\n.markup-popover.is-dragging .markup-popover-header {\n cursor: grabbing;\n}\n.markup-popover-header-actions {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n/* The route segment is what a user scans for, so it stays unmuted. */\n/* Free to ellipsise, unlike the host+path pair it replaced — a clipped\n hostname is worse than no hostname, so that one pushed the header out. */\n.markup-popover-title {\n flex: 1 1 auto;\n min-width: 0;\n font-family: var(--markup-font-mono);\n font-size: 11px;\n line-height: 1;\n letter-spacing: 0.02em;\n color: var(--markup-muted);\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.markup-thread-menu {\n position: relative;\n display: flex;\n}\n.markup-thread-menu-list {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n z-index: 10;\n min-width: 160px;\n padding: 4px;\n background: var(--markup-paper);\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius);\n box-shadow: var(--markup-shadow);\n animation: markup-menu-in 120ms ease-out;\n}\n.markup-thread-menu-item {\n display: block;\n width: 100%;\n padding: 7px 10px;\n border: none;\n border-radius: var(--markup-radius-sm);\n background: transparent;\n color: var(--markup-ink);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition:\n background 100ms ease,\n color 100ms ease;\n}\n.markup-thread-menu-item:hover {\n background: var(--markup-border);\n}\n.markup-thread-menu-item.is-danger {\n color: var(--markup-danger, #dc2626);\n}\n.markup-thread-menu-item.is-danger:hover {\n background: color-mix(in srgb, var(--markup-danger, #dc2626) 10%, transparent);\n}\n.markup-thread-menu-item:disabled {\n opacity: 0.5;\n cursor: default;\n}\n@keyframes markup-menu-in {\n from {\n opacity: 0;\n transform: translateY(-4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.markup-popover-body {\n display: flex;\n flex-direction: column;\n padding: 10px 12px 8px;\n gap: 6px;\n border-top: 1px solid var(--markup-border);\n background: var(--markup-paper);\n}\n/* Adjacency rather than dropping the border: in the composer this rule lands\n on the header's and paints two hairlines, but in a thread it is the only\n thing dividing the last comment from the composer. */\n.markup-popover-header + .markup-popover-body {\n border-top: none;\n}\n/* Redundant with the avatar, but left in the DOM for screen readers. */\n.markup-popover-byline {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n.markup-popover-name {\n color: var(--markup-ink);\n font-weight: 500;\n}\n\n.markup-icon-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n border: none;\n border-radius: var(--markup-radius-sm);\n background: transparent;\n color: var(--markup-muted);\n cursor: pointer;\n transition:\n background 120ms ease,\n color 120ms ease;\n}\n.markup-icon-btn:hover,\n.markup-icon-btn.is-open {\n background: var(--markup-border);\n color: var(--markup-ink);\n}\n\n/* ────────── Comments ────────── */\n\n.markup-comments {\n list-style: none;\n margin: 0;\n padding: 0;\n max-height: 420px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n.markup-comment {\n display: grid;\n grid-template-columns: 26px 1fr;\n column-gap: 10px;\n row-gap: 0;\n align-items: start;\n padding: 12px;\n border-bottom: 1px solid var(--markup-border);\n}\n.markup-comment:last-child {\n border-bottom: none;\n}\n.markup-comment > *:not(.markup-comment-avatar) {\n grid-column: 2;\n}\n\n/* Tones rotate deterministically, so an author always paints the same. */\n.markup-comment-avatar {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n grid-column: 1;\n /* Spans the rows because an auto-sized row grows to its tallest item: a 26px\n circle alone in row 1 would stretch the 20px meta line. */\n grid-row: 1 / span 4;\n /* Half the 26px/20px difference. Without it the circle top-aligns and its\n centre lands 3px low. Safe because the circle sizes no row. */\n margin-top: -3px;\n width: 26px;\n height: 26px;\n border-radius: 999px;\n background: var(--markup-border);\n color: var(--markup-ink);\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n user-select: none;\n overflow: hidden;\n}\n/* Uppercase initials carry no descenders, but the line box still reserves\n descent space, leaving the glyphs 0.88px high in a 26px circle — visible at\n this size. `text-box-trim` centres the letterforms themselves whatever the\n host page's font metrics are; browsers without it fall back to\n `line-height: 1`, which closes most of the same gap.\n\n It has to be its own element: the property trims a block container's line\n boxes, and a bare text node in a flex container is an anonymous item the\n rule cannot reach. */\n.markup-avatar-initials {\n line-height: 1;\n text-box-trim: trim-both;\n text-box-edge: cap alphabetic;\n}\n\n/* `cover` keeps non-square sources from stretching. */\n.markup-avatar-img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n.markup-comment-avatar[data-tone='1'] {\n background: oklch(0.85 0.07 200);\n color: oklch(0.25 0.07 230);\n}\n.markup-comment-avatar[data-tone='2'] {\n background: oklch(0.88 0.07 130);\n color: oklch(0.3 0.1 150);\n}\n.markup-comment-avatar[data-tone='3'] {\n background: oklch(0.9 0.05 50);\n color: oklch(0.35 0.1 40);\n}\n.markup-comment-avatar[data-tone='4'] {\n background: oklch(0.87 0.07 320);\n color: oklch(0.3 0.1 320);\n}\n.markup-comment-avatar[data-tone='5'] {\n background: oklch(0.88 0.06 80);\n color: oklch(0.32 0.09 70);\n}\n.markup-comment-meta {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 4px;\n min-width: 0;\n font-size: 13px;\n}\n.markup-comment-author {\n font-weight: 600;\n color: var(--markup-ink);\n font-size: 13px;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n/* Deliberately uniform. Tinting by \"the author had no host page\" put\n dashboard replies and agent writes in one bucket, so the colour meant\n neither reliably. Human vs. agent is the distinction a reader can act on,\n and the bot badge below carries it. */\n.markup-comment-badge {\n display: inline-flex;\n align-items: center;\n height: 14px;\n padding: 0 5px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--markup-team) 12%, transparent);\n color: var(--markup-team);\n font-family: var(--markup-font-mono);\n font-size: 9px;\n line-height: 1;\n font-weight: 500;\n letter-spacing: 0.12em;\n text-transform: uppercase;\n}\n/* Brand-tinted rather than warning-coloured: an agent reply is expected, it\n just has to be identifiable. Square box because a glyph needs no tracking. */\n.markup-comment-badge.is-agent {\n background: color-mix(in srgb, var(--markup-brand) 14%, transparent);\n color: var(--markup-brand);\n justify-content: center;\n width: 14px;\n padding: 0;\n letter-spacing: normal;\n}\n/* No `margin-left: auto`. Flexbox splits free space equally between every\n auto margin on the line, so a second one parks the timestamp halfway\n between the name and the actions instead of beside either. */\n.markup-comment-time {\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n letter-spacing: 0.04em;\n white-space: nowrap;\n flex-shrink: 0;\n}\n.markup-comment-body {\n margin: 0;\n font-size: 13.5px;\n line-height: 19px;\n color: var(--markup-ink);\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* Inline \" · edited\" suffix on the timestamp, matching the design's\n * compact treatment instead of a separate \"(edited)\" parenthetical. */\n.markup-comment-edited {\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n margin-left: 2px;\n}\n.markup-comment-edited::before {\n content: ' · ';\n}\n\n.markup-thread-actions {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n/* The only auto margin on the meta line, so it absorbs all free space and the\n * actions sit flush right. Do NOT add a second one: free space is divided\n * equally among them, not handed to the first. */\n.markup-comment-meta .markup-reaction-picker-wrap,\n.markup-thread-actions {\n margin-left: auto;\n}\n.markup-comment-meta .markup-reaction-add {\n width: 22px;\n height: 22px;\n margin-top: -4px;\n margin-bottom: -4px;\n}\n.markup-reaction-picker-wrap > .markup-icon-btn,\n.markup-comment-menu > .markup-icon-btn {\n margin-top: -4px;\n margin-bottom: -4px;\n}\n/* `overflow-y: auto` on the list would clip a dropdown that spills out the\n * bottom. Direction is measured on open in thread-popover.tsx. */\n.markup-comment-menu.is-up .markup-thread-menu-list {\n top: auto;\n bottom: calc(100% + 6px);\n animation-name: markup-menu-in-up;\n}\n/* A single-comment popover is too short for a vertical dropdown. */\n.markup-comment-menu.is-side .markup-thread-menu-list {\n top: -4px;\n right: calc(100% + 2px);\n animation-name: markup-menu-in-side;\n}\n@keyframes markup-menu-in-side {\n from {\n opacity: 0;\n transform: translate(4px, 0);\n }\n to {\n opacity: 1;\n transform: translate(0, 0);\n }\n}\n@keyframes markup-menu-in-up {\n from {\n opacity: 0;\n transform: translateY(4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* `position: relative` so the picker popover anchors here rather than\n * leaking out of the scroll container. */\n.markup-comment {\n position: relative;\n}\n.markup-reactions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px;\n margin-top: 6px;\n}\n.markup-reaction-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 7px;\n border: 1px solid var(--markup-border);\n border-radius: 999px;\n background: var(--markup-surface-3);\n color: var(--markup-ink);\n font: inherit;\n font-size: 11.5px;\n line-height: 1.2;\n cursor: pointer;\n transition:\n background 120ms ease,\n border-color 120ms ease;\n}\n.markup-reaction-chip:hover:not(:disabled) {\n background: var(--markup-hover);\n}\n.markup-reaction-chip.is-mine {\n background: var(--markup-accent-soft);\n border-color: color-mix(in srgb, var(--markup-brand) 50%, transparent);\n color: var(--markup-accent-ink);\n}\n.markup-reaction-chip.is-mine:hover:not(:disabled) {\n background: color-mix(in srgb, var(--markup-brand) 18%, transparent);\n}\n.markup-reaction-chip:disabled {\n cursor: default;\n opacity: 0.6;\n}\n.markup-reaction-emoji {\n font-size: 13px;\n line-height: 1;\n}\n.markup-reaction-count {\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n letter-spacing: 0.04em;\n color: var(--markup-muted);\n}\n.markup-reaction-chip.is-mine .markup-reaction-count {\n color: var(--markup-accent-ink);\n}\n\n.markup-reaction-picker-wrap {\n position: relative;\n display: inline-flex;\n flex: 0 0 auto;\n opacity: 0;\n transition: opacity 120ms ease;\n}\n/* The open state stays visible so the cursor can leave the row to reach an\n * emoji without the wrap fading out. */\n.markup-comment:hover .markup-reaction-picker-wrap,\n.markup-comment:focus-within .markup-reaction-picker-wrap,\n.markup-reaction-picker-wrap.is-open {\n opacity: 1;\n}\n.markup-reaction-add {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: var(--markup-muted);\n font: inherit;\n font-size: 13px;\n line-height: 1;\n cursor: pointer;\n transition:\n background 120ms ease,\n color 120ms ease;\n}\n.markup-reaction-add:hover,\n.markup-reaction-add.is-open {\n background: var(--markup-hover);\n color: var(--markup-ink);\n}\n\n.markup-reaction-picker {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n z-index: 1;\n display: flex;\n gap: 2px;\n padding: 4px;\n border: 1px solid var(--markup-border-strong);\n border-radius: 8px;\n background: var(--markup-paper);\n box-shadow:\n 0 1px 2px rgba(26, 22, 20, 0.06),\n 0 8px 28px rgba(26, 22, 20, 0.1);\n animation: markup-menu-in 120ms ease;\n}\n.markup-reaction-picker-wrap.is-up .markup-reaction-picker {\n top: auto;\n bottom: calc(100% + 6px);\n animation-name: markup-menu-in-up;\n}\n/* As with `.markup-comment-menu.is-side`, too short for a vertical picker. */\n.markup-reaction-picker-wrap.is-side .markup-reaction-picker {\n top: -4px;\n right: calc(100% + 2px);\n animation-name: markup-menu-in-side;\n}\n.markup-reaction-picker-item {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 6px;\n background: transparent;\n font-size: 16px;\n line-height: 1;\n cursor: pointer;\n transition: background 120ms ease;\n}\n.markup-reaction-picker-item:hover {\n background: color-mix(in srgb, var(--markup-ink) 8%, transparent);\n}\n.markup-reaction-picker-item.is-mine {\n background: color-mix(in srgb, var(--markup-brand) 14%, transparent);\n}\n\n.markup-comment-edit-form {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n/* The edit field itself is `.markup-comment-edit-input`, styled with the\n * other mention-editor rules further down. */\n.markup-comment-edit-actions {\n display: flex;\n justify-content: flex-end;\n gap: 6px;\n}\n\n/* ────────── Composer ────────── */\n\n.markup-composer {\n position: relative;\n display: flex;\n flex-direction: column;\n}\n\n.markup-composer-input {\n width: 100%;\n min-height: 38px;\n max-height: 120px;\n /* The editing host grows with its content instead of being sized by\n * `rows`, so it needs its own scroller once it hits max-height. */\n overflow-y: auto;\n padding: 2px 0;\n border: none;\n border-radius: 0;\n background: transparent;\n color: var(--markup-ink);\n font-family: var(--markup-font);\n font-size: 13.5px;\n line-height: 19px;\n transition: none;\n}\n.markup-composer-input:focus-visible {\n outline: none;\n box-shadow: none;\n}\n\n.markup-composer-footer-wrap {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 150ms ease;\n}\n.markup-composer.is-filled .markup-composer-footer-wrap {\n grid-template-rows: 1fr;\n}\n\n.markup-composer-footer {\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 0;\n border: none;\n border-radius: 0;\n background: transparent;\n opacity: 0;\n transition: opacity 100ms ease;\n}\n.markup-composer.is-filled .markup-composer-footer {\n opacity: 1;\n transition-delay: 60ms;\n}\n.markup-composer-hint {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n font-family: var(--markup-font-mono);\n font-size: 10.5px;\n letter-spacing: 0.04em;\n color: var(--markup-muted);\n}\n/* The words after the chips: a little air so \"to send\" reads as a phrase\n about the keys rather than a third chip in the row. */\n.markup-composer-hint-label {\n margin-left: 2px;\n}\n.markup-composer-error {\n color: var(--markup-brand);\n}\n.markup-composer-actions {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* Scoped to the composer so it doesn't bleed into AuthorPrompt buttons. */\n.markup-composer .markup-btn-primary {\n height: 26px;\n padding: 0 10px;\n border-radius: 6px;\n background: var(--markup-ink);\n color: var(--markup-paper);\n}\n.markup-composer .markup-btn-primary:hover:not(:disabled) {\n background: color-mix(in srgb, var(--markup-ink) 88%, var(--markup-paper));\n}\n\n.markup-composer-actions-empty {\n position: absolute;\n bottom: 0;\n right: 0;\n transition: opacity 120ms ease;\n}\n.markup-composer.is-filled .markup-composer-actions-empty {\n opacity: 0;\n pointer-events: none;\n}\n\n/* ────────── Author prompt ────────── */\n\n.markup-author-prompt {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 12px;\n}\n.markup-author-status {\n margin: 0;\n color: var(--markup-muted);\n font-size: 12px;\n}\n.markup-input {\n width: 100%;\n height: 36px;\n padding: 0 10px;\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius-sm);\n background: var(--markup-paper);\n color: var(--markup-ink);\n outline: none;\n font-size: 14px;\n transition:\n border-color 120ms ease,\n box-shadow 120ms ease;\n}\n.markup-input:focus-visible {\n border-color: var(--markup-brand);\n box-shadow: 0 0 0 3px rgba(227, 93, 42, 0.18);\n}\n\n/* ────────── Buttons ────────── */\n\n.markup-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 30px;\n padding: 0 8px;\n border: 1px solid transparent;\n border-radius: var(--markup-radius-sm);\n background: transparent;\n color: var(--markup-ink);\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n letter-spacing: -0.01em;\n white-space: nowrap;\n transition:\n background 120ms ease,\n border-color 120ms ease,\n color 120ms ease,\n opacity 120ms ease;\n}\n.markup-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.markup-btn-primary {\n background: var(--markup-ink);\n color: var(--markup-paper);\n}\n.markup-btn-primary:hover:not(:disabled) {\n background: var(--markup-brand);\n}\n.markup-btn-ghost {\n color: var(--markup-muted);\n}\n.markup-btn-ghost:hover:not(:disabled) {\n background: var(--markup-border);\n color: var(--markup-ink);\n}\n\n/* ────────── Screenshot row ────────── */\n\n/* Dashed pill announcing the auto-attached screenshot. */\n.markup-screenshot-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 0;\n padding: 6px 8px;\n border: 1px dashed var(--markup-border-strong);\n border-radius: 6px;\n font-size: 11.5px;\n color: var(--markup-muted);\n}\n\n.markup-screenshot-status {\n display: flex;\n align-items: center;\n gap: 5px;\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 11px;\n letter-spacing: 0.04em;\n}\n\n/* Capture ran and produced nothing. Deliberately understated — the\n * comment still posts fine, so this is a note, not an error. */\n.markup-screenshot-row.is-failed {\n border-style: dotted;\n opacity: 0.85;\n}\n\n.markup-screenshot-toggle {\n display: flex;\n align-items: center;\n gap: 5px;\n cursor: pointer;\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 11px;\n letter-spacing: 0.04em;\n transition: color 120ms ease;\n}\n.markup-screenshot-toggle:hover {\n color: var(--markup-ink);\n}\n\n.markup-screenshot-checkbox {\n width: 12px;\n height: 12px;\n margin: 0;\n accent-color: var(--markup-brand);\n cursor: pointer;\n}\n\n.markup-screenshot-thumb {\n display: block;\n margin: -5px 0 -5px auto;\n width: auto;\n height: 25px;\n border-radius: 3px;\n border: 1px solid var(--markup-border-strong);\n object-fit: cover;\n flex-shrink: 0;\n}\n\n/* Right end of the shot-strip via `margin-left: auto`. */\n.markup-screenshot-redacted {\n margin-left: auto;\n font-family: var(--markup-font-mono);\n font-size: 10px;\n color: var(--markup-muted);\n}\n\n.markup-screenshot-redacted-chip {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 1px 7px;\n border-radius: 999px;\n border: none;\n background: color-mix(in srgb, var(--markup-success, oklch(0.62 0.16 150)) 16%, transparent);\n color: var(--markup-success, oklch(0.62 0.16 150));\n font-family: var(--markup-font-mono);\n font-size: 10px;\n cursor: pointer;\n}\n.markup-screenshot-redacted-chip:hover {\n filter: brightness(1.05);\n}\n\n.markup-screenshot-redacted-arrow {\n font-style: normal;\n}\n\n.markup-screenshot-redacted-list {\n margin-top: 3px;\n padding-left: 10px;\n}\n\n.markup-screenshot-redacted-selector {\n display: block;\n font-family: var(--markup-font-mono);\n font-size: 9px;\n color: var(--markup-muted);\n}\n\n.markup-screenshot-help {\n margin: 5px 0 0;\n font-family: var(--markup-font-mono);\n font-size: 10px;\n color: var(--markup-muted);\n line-height: 1.5;\n}\n\n.markup-screenshot-help-code {\n font-family: var(--markup-font-mono);\n color: var(--markup-ink);\n}\n\n/* ────────── Screenshot thumbnail inside first comment ────────── */\n\n.markup-comment-screenshot {\n display: block;\n margin-top: 8px;\n padding: 0;\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius-sm);\n background: transparent;\n cursor: pointer;\n overflow: hidden;\n transition:\n border-color 120ms ease,\n opacity 120ms ease;\n}\n.markup-comment-screenshot:hover {\n border-color: var(--markup-brand);\n opacity: 0.9;\n}\n.markup-comment-screenshot img {\n display: block;\n width: 100%;\n height: auto;\n max-height: 120px;\n object-fit: cover;\n object-position: top;\n}\n\n/* ────────── Screenshot lightbox ────────── */\n\n.markup-lightbox {\n position: fixed;\n inset: 0;\n width: 100%;\n height: 100%;\n max-width: 100%;\n max-height: 100%;\n margin: 0;\n padding: 24px;\n border: none;\n background: rgba(26, 22, 20, 0.88);\n}\n\n.markup-lightbox[open] {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.markup-lightbox::backdrop {\n display: none;\n}\n\n.markup-lightbox-img {\n max-width: 100%;\n max-height: 100%;\n border-radius: var(--markup-radius);\n object-fit: contain;\n box-shadow: var(--markup-shadow);\n animation: markup-lightbox-in 160ms ease-out;\n}\n\n.markup-lightbox-close {\n position: absolute;\n top: 16px;\n right: 16px;\n background: rgba(26, 22, 20, 0.6);\n color: #fdfcfa;\n}\n.markup-lightbox-close:hover {\n background: rgba(26, 22, 20, 0.85);\n color: #fdfcfa;\n}\n\n@keyframes markup-lightbox-in {\n from {\n opacity: 0;\n transform: scale(0.96);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n/* ────────── Reduced motion ────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .markup-toolbar,\n .markup-pin,\n .markup-icon-btn,\n .markup-btn,\n .markup-popover,\n .markup-pin-ghost,\n .markup-placement-overlay,\n .markup-placement-cursor-help,\n .markup-lightbox-img {\n transition: none;\n animation: none;\n }\n}\n\n/* ────────── Mentions ────────── */\n\n.markup-mention-chip {\n display: inline-block;\n padding: 0 2px;\n border-radius: 3px;\n background: var(--markup-accent-soft);\n color: var(--markup-accent-ink);\n font-weight: 500;\n}\n\n/* ── Mention editor (contenteditable) ──\n *\n * Shared base for every authoring surface; the composer and the\n * comment-edit form layer their own sizing and chrome on top. Only\n * declares what a contenteditable host needs and a textarea didn't, so\n * nothing here fights those per-surface rules.\n *\n * `position: relative` anchors the placeholder pseudo-element. It has no\n * effect on the picker overlay, which is absolute against\n * `.markup-composer` — a sibling of this element, not a descendant. */\n.markup-mention-input {\n position: relative;\n /* Newlines are stored inside text nodes rather than as <br> elements,\n * so the host needs pre-wrap to break on them. */\n white-space: pre-wrap;\n /* A pasted URL has no break opportunities and would otherwise widen\n * the popover past its own max-width. */\n overflow-wrap: anywhere;\n outline: none;\n cursor: text;\n}\n.markup-mention-input[aria-disabled='true'] {\n opacity: 0.6;\n cursor: default;\n}\n/* Absolutely positioned so the placeholder never occupies layout — as\n * in-flow `::before` content it would push the caret to its right. */\n.markup-mention-input[data-empty]::before {\n content: attr(data-placeholder);\n position: absolute;\n inset: 0 auto auto 0;\n color: var(--markup-muted);\n pointer-events: none;\n}\n/* `contenteditable=\"false\"` already makes the browser delete a chip\n * whole; this only stops one wrapping mid-name at the popover edge. */\n.markup-mention-input .markup-mention-chip {\n white-space: nowrap;\n padding: 0 3px;\n}\n\n/* Boxed variant for the comment-edit form — mirrors the\n * `.markup-textarea` it replaced. */\n.markup-comment-edit-input {\n width: 100%;\n min-height: 58px;\n max-height: 200px;\n overflow-y: auto;\n padding: 8px 10px;\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius-sm);\n background: var(--markup-paper);\n color: var(--markup-ink);\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n}\n.markup-comment-edit-input:focus-visible {\n border-color: var(--markup-brand);\n box-shadow: 0 0 0 3px rgba(227, 93, 42, 0.18);\n}\n/* The placeholder is inset by the box's own padding. */\n.markup-comment-edit-input[data-empty]::before {\n inset: 8px auto auto 10px;\n}\n\n.markup-mention-picker {\n position: absolute;\n /* `.markup-composer`'s top edge is flush with the textarea, so `bottom: 100%`\n * keeps the list adjacent to the input rather than under the hint row. */\n bottom: 100%;\n left: 0;\n right: 0;\n z-index: 10;\n margin: 0 0 4px;\n padding: 4px;\n list-style: none;\n max-height: 180px;\n overflow-y: auto;\n background: var(--markup-paper);\n border: 1px solid var(--markup-border-strong);\n border-radius: var(--markup-radius-sm);\n box-shadow: var(--markup-shadow);\n}\n\n.markup-mention-picker-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 6px 8px;\n border-radius: var(--markup-radius-sm);\n cursor: pointer;\n color: var(--markup-ink);\n font-size: 13px;\n}\n\n.markup-mention-picker-item.is-active {\n background: color-mix(in srgb, var(--markup-brand) 12%, transparent);\n}\n\n.markup-mention-picker-name {\n font-weight: 500;\n}\n\n.markup-mention-picker-trigger {\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 10px;\n}\n\n/* ────────── Notifications ────────── */\n\n/* The popover already provides chrome and dismissal, so this is only a\n * header plus a scrollable body. */\n.markup-notifications-panel {\n display: flex;\n flex-direction: column;\n max-height: min(60vh, 420px);\n color: var(--markup-ink);\n}\n\n.markup-notifications-panel-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n border-bottom: 1px solid var(--markup-border);\n}\n\n.markup-notifications-panel-header .markup-eyebrow {\n flex: 1;\n}\n\n.markup-notifications-panel-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.markup-notifications-panel-mark-all {\n background: transparent;\n border: none;\n color: var(--markup-muted);\n font-size: 11px;\n cursor: pointer;\n padding: 0;\n}\n\n.markup-notifications-panel-mark-all:hover {\n color: var(--markup-ink);\n}\n\n.markup-notifications-panel-body {\n flex: 1;\n overflow-y: auto;\n}\n\n.markup-notifications-panel-empty,\n.markup-notifications-panel-error {\n padding: 24px 12px;\n text-align: center;\n font-size: 12px;\n color: var(--markup-muted);\n}\n\n.markup-notifications-panel-empty-title {\n color: var(--markup-ink);\n font-weight: 500;\n margin: 0 0 4px;\n}\n\n.markup-notifications-panel-empty-sub {\n margin: 0;\n color: var(--markup-muted);\n line-height: 1.4;\n}\n\n.markup-notifications-panel-error {\n color: var(--markup-danger, #b91c1c);\n}\n\n.markup-notifications-panel-list {\n list-style: none;\n margin: 0;\n padding: 4px;\n}\n\n.markup-notifications-panel-row {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 8px 10px;\n width: 100%;\n background: transparent;\n border: none;\n border-radius: var(--markup-radius-sm);\n text-align: start;\n cursor: pointer;\n font: inherit;\n color: inherit;\n}\n\n.markup-notifications-panel-row:hover {\n background: color-mix(in srgb, var(--markup-brand) 8%, transparent);\n}\n\n.markup-notifications-panel-row.is-unread {\n background: color-mix(in srgb, var(--markup-brand) 5%, transparent);\n}\n\n.markup-notifications-panel-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n}\n\n.markup-notifications-panel-dot {\n width: 6px;\n height: 6px;\n border-radius: 999px;\n background: var(--markup-brand);\n flex-shrink: 0;\n}\n\n.markup-notifications-panel-actor {\n font-weight: 600;\n}\n\n.markup-notifications-panel-sep {\n color: var(--markup-muted);\n}\n\n.markup-notifications-panel-time {\n color: var(--markup-muted);\n font-family: var(--markup-font-mono);\n font-size: 10px;\n}\n\n.markup-notifications-panel-thread {\n margin: 0;\n font-size: 12px;\n color: var(--markup-muted);\n}\n\n.markup-notifications-panel-thread-title {\n color: var(--markup-ink);\n}\n\n.markup-notifications-panel-excerpt {\n margin: 0;\n font-size: 12px;\n font-style: italic;\n color: color-mix(in srgb, var(--markup-ink) 80%, transparent);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* ────────── Toolbar-anchored panels (inbox / privacy / shortcuts) ──────────\n * Rendered as siblings of the toolbar pill, anchored to the same corner.\n * The inner `.markup-pop[data-pop=…]` gets the shadow + border; this\n * wrapper just handles positioning + dismissal scoping. `data-panel`\n * carries the width, since the inbox wants room for excerpts while the\n * reading panels read better narrow.\n */\n.markup-panel-pop {\n position: fixed;\n bottom: 76px;\n z-index: 11;\n pointer-events: auto;\n width: 380px;\n max-width: calc(100vw - 24px);\n}\n.markup-panel-pop[data-panel='privacy'] {\n width: 340px;\n}\n.markup-panel-pop[data-panel='shortcuts'] {\n width: 320px;\n}\n.markup-panel-pop-right {\n right: 22px;\n}\n.markup-panel-pop-left {\n left: 22px;\n}\n.markup-panel-pop-center {\n left: 50%;\n transform: translateX(-50%);\n}\n.markup-panel-pop .markup-pop {\n position: static;\n width: 100%;\n animation: markup-pop-in 140ms cubic-bezier(0.2, 0.7, 0.2, 1);\n}\n.markup-panel-pop .markup-notifications-panel {\n max-height: min(60vh, 480px);\n}\n.markup-panel-pop .markup-notifications-panel-header {\n padding: 12px 14px;\n}\n.markup-panel-pop .markup-notifications-panel-header .markup-icon-btn {\n display: none;\n}\n\n/* ────────── Reading panels (privacy & data, keyboard shortcuts) ──────────\n * Both are scrollable prose surfaces rather than menus: a sticky header\n * with the eyebrow + close button, then sections of short lines. The\n * shared `.markup-panel-*` scale keeps them reading as one family.\n */\n.markup-pop[data-pop='privacy'],\n.markup-pop[data-pop='shortcuts'] {\n padding: 0;\n}\n.markup-panel {\n display: flex;\n flex-direction: column;\n max-height: min(70vh, 520px);\n color: var(--markup-ink);\n}\n.markup-panel-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 14px;\n border-bottom: 1px solid var(--markup-border);\n}\n.markup-panel-header .markup-eyebrow {\n flex: 1;\n}\n.markup-panel-body {\n flex: 1;\n overflow-y: auto;\n padding: 4px 14px 14px;\n}\n.markup-panel-section {\n padding: 10px 0;\n border-bottom: 1px solid var(--markup-border);\n}\n.markup-panel-section:last-child {\n border-bottom: none;\n padding-bottom: 2px;\n}\n.markup-panel-section-title {\n margin: 0 0 6px;\n font-family: var(--markup-font-mono);\n font-size: 10px;\n font-weight: 400;\n letter-spacing: 0.06em;\n text-transform: lowercase;\n color: var(--markup-muted);\n}\n.markup-panel-text {\n margin: 0;\n font-size: 12.5px;\n line-height: 1.5;\n color: var(--markup-ink-soft);\n}\n.markup-panel-text strong {\n font-weight: 600;\n color: var(--markup-ink);\n}\n.markup-panel-mono {\n font-family: var(--markup-font-mono);\n font-size: 11.5px;\n color: var(--markup-ink);\n word-break: break-all;\n}\n.markup-panel-list {\n margin: 0;\n padding-left: 16px;\n font-size: 12.5px;\n line-height: 1.5;\n color: var(--markup-ink-soft);\n}\n.markup-panel-list li {\n margin-bottom: 3px;\n}\n.markup-panel-list li::marker {\n color: var(--markup-muted);\n}\n.markup-panel-note {\n margin: 8px 0 0;\n font-size: 11.5px;\n line-height: 1.45;\n color: var(--markup-muted);\n}\n.markup-panel-error {\n margin: 8px 0 0;\n font-size: 11.5px;\n line-height: 1.45;\n color: var(--markup-danger);\n}\n/* Secondary, full-width action — used by the privacy panel's forget-me\n * row. Arming flips it to `is-danger`, matching the identity menu. */\n.markup-panel-action {\n margin-top: 10px;\n width: 100%;\n height: 30px;\n padding: 0 10px;\n border: 1px solid var(--markup-border-strong);\n border-radius: 7px;\n background: transparent;\n color: var(--markup-ink);\n font: inherit;\n font-size: 12.5px;\n cursor: pointer;\n transition:\n background 120ms ease,\n border-color 120ms ease,\n color 120ms ease;\n}\n.markup-panel-action:hover:not(:disabled) {\n background: var(--markup-hover);\n}\n.markup-panel-action:disabled {\n opacity: 0.6;\n cursor: default;\n}\n.markup-panel-action.is-danger {\n border-color: color-mix(in srgb, var(--markup-danger) 45%, transparent);\n color: var(--markup-danger);\n}\n.markup-panel-action.is-danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--markup-danger) 10%, transparent);\n}\n\n/* Caps reuse `.markup-kbd.is-inline`, the light-surface variant. */\n.markup-shortcut-list {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n.markup-shortcut-row {\n display: flex;\n align-items: center;\n gap: 10px;\n min-height: 24px;\n padding: 2px 0;\n}\n.markup-shortcut-label {\n flex: 1;\n min-width: 0;\n font-size: 12.5px;\n line-height: 1.4;\n color: var(--markup-ink-soft);\n}\n.markup-shortcut-keys {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n.markup-shortcut-chord {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n}\n.markup-shortcut-or {\n font-size: 10px;\n color: var(--markup-muted);\n margin-right: 1px;\n}\n","/**\n * Relayed through our own endpoint rather than a third-party SDK on the host\n * page, for the reasons `error-reporter.ts` gives.\n *\n * Nothing identifies the end user: events key on the project, and `sessionId`\n * is per-page-load and never persisted.\n */\n\nconst FLUSH_INTERVAL_MS = 10_000\n/** Matches `MAX_EVENTS_PER_BATCH` server-side, deliberately unshared —\n * widget and deployment version independently. */\nconst MAX_BATCH = 20\nconst MAX_QUEUE = 60\n\n/** Mirrors `WIDGET_EVENTS` server-side, which drops names it doesn't know. */\nexport type WidgetEvent =\n | 'widget_loaded'\n | 'comment_started'\n | 'comment_submitted'\n | 'reply_submitted'\n | 'thread_opened'\n | 'thread_resolved'\n | 'screenshot_captured'\n | 'reaction_added'\n | 'sign_in_started'\n | 'sign_in_completed'\n | 'notifications_opened'\n\ntype EventProperties = Record<string, string | number | boolean>\n\ninterface QueuedEvent {\n name: WidgetEvent\n properties?: EventProperties\n timestamp: number\n}\n\nexport interface AnalyticsConfig {\n apiUrl: string\n apiKey: string\n widgetVersion?: string\n}\n\nlet config: AnalyticsConfig | null = null\nlet queue: QueuedEvent[] = []\nlet flushTimer: ReturnType<typeof setTimeout> | null = null\nlet listenersBound = false\n\n/** Never persisted — that would make it a durable identifier. */\nconst sessionId = generateSessionId()\n\nfunction generateSessionId(): string {\n // Absent on http:// origins in some browsers. Nothing is authorised by\n // this, so the fallback needn't be unguessable.\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n return `s-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`\n}\n\n/** `null` disables and drops the queue — an opt-out that flushed the\n * backlog would not be an opt-out. */\nexport function setAnalyticsConfig(next: AnalyticsConfig | null): void {\n config = next\n if (!next) {\n queue = []\n if (flushTimer) {\n clearTimeout(flushTimer)\n flushTimer = null\n }\n return\n }\n bindUnloadFlush()\n}\n\n/** Never throws, never blocks, no-op when telemetry is off. */\nexport function track(name: WidgetEvent, properties?: EventProperties): void {\n if (!config) return\n // Drop rather than grow; the oldest events describe how the loop started.\n if (queue.length >= MAX_QUEUE) return\n\n queue.push({ name, properties, timestamp: Date.now() })\n\n if (queue.length >= MAX_BATCH) {\n void flush()\n return\n }\n if (!flushTimer) {\n flushTimer = setTimeout(() => {\n flushTimer = null\n void flush()\n }, FLUSH_INTERVAL_MS)\n }\n}\n\n/** `keepalive` so a `pagehide` flush outlives the navigation. */\nasync function flush(): Promise<void> {\n if (!config || queue.length === 0) return\n const batch = queue.splice(0, MAX_BATCH)\n if (flushTimer) {\n clearTimeout(flushTimer)\n flushTimer = null\n }\n\n try {\n await fetch(`${config.apiUrl.replace(/\\/+$/, '')}/widget/events`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-markup-api-key': config.apiKey,\n },\n body: JSON.stringify({\n sessionId,\n widgetVersion: config.widgetVersion,\n events: batch.map((e) => ({\n name: e.name,\n properties: e.properties,\n timestamp: e.timestamp,\n })),\n }),\n keepalive: true,\n })\n } catch {\n // Already spliced off, so this drops the batch. Telemetry that\n // retries is telemetry that can hammer a customer's network.\n }\n\n // Re-armed so a remainder drains on the usual cadence rather than waiting\n // for a `track()` call that may never come. On `pagehide` the timer never\n // fires and the remainder is accepted as lost.\n if (config && queue.length > 0 && !flushTimer) {\n flushTimer = setTimeout(() => {\n flushTimer = null\n void flush()\n }, FLUSH_INTERVAL_MS)\n }\n}\n\n/**\n * `pagehide`, not `beforeunload` — the latter disqualifies the page from\n * the back/forward cache. `visibilitychange` covers mobile tab-switching.\n */\nfunction bindUnloadFlush(): void {\n if (listenersBound || typeof window === 'undefined') return\n listenersBound = true\n\n const send = () => void flush()\n window.addEventListener('pagehide', send)\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') send()\n })\n}\n","/**\n * On a render error the children unmount and the widget disappears, leaving the\n * host page's DOM untouched rather than painting a broken UI over the\n * customer's site.\n *\n * This boundary wraps only our component tree, which is what makes anything it\n * catches definitively widget code however the widget was delivered.\n *\n * Both `getDerivedStateFromError` and `componentDidCatch` are implemented so\n * the render state updates synchronously and the report runs in a later phase.\n */\n\nimport { Component, type ComponentChildren } from 'preact'\n\ninterface WidgetErrorBoundaryProps {\n children: ComponentChildren\n /** No filtering: by construction everything under here is widget code. */\n onError: (err: Error) => void\n}\n\ninterface WidgetErrorBoundaryState {\n hasError: boolean\n}\n\nexport class WidgetErrorBoundary extends Component<\n WidgetErrorBoundaryProps,\n WidgetErrorBoundaryState\n> {\n state: WidgetErrorBoundaryState = { hasError: false }\n\n static getDerivedStateFromError(): WidgetErrorBoundaryState {\n return { hasError: true }\n }\n\n componentDidCatch(error: Error): void {\n // Belt + braces — the reporter swallows network errors itself,\n // but if something inside the reporter throws synchronously we\n // don't want it to re-enter the boundary and loop.\n try {\n this.props.onError(error)\n } catch {\n /* swallow */\n }\n }\n\n render() {\n if (this.state.hasError) {\n // Render nothing on crash. Showing a fallback UI on the\n // customer's site is worse than silently disappearing — they\n // didn't sign up for our error UX on their page.\n return null\n }\n return this.props.children\n }\n}\n","/**\n * Relays to Sentry through `/widget/error` rather than bundling\n * `@sentry/browser`: a third-party ingest in `connect-src` is CSP-blocked on a\n * meaningful fraction of host pages, and the SDK is ~30 KB gzip against <1 KB\n * here on a page we promised one script tag's worth of code.\n *\n * There is **no window-level `error` / `unhandledrejection` listener**, by\n * design. One would either report the customer's own script errors as ours, or\n * fall back to URL-pattern guessing that doesn't generalise across CDN and\n * npm-bundled delivery. Only the Preact error boundary and explicit\n * `reportWidgetError` calls feed this, both of which are certainly widget code.\n *\n * The cost is that unwrapped timer callbacks, raw event listeners and\n * `.catch()`-less promise chains go unreported. Coverage grows by adding\n * explicit calls, not by installing a leaky window backstop.\n */\n\nexport interface ErrorReporterConfig {\n apiUrl: string\n apiKey: string\n /** String shipped with every event so the Sentry inbox can split by version. */\n widgetVersion?: string\n}\n\nconst MIN_REPORT_INTERVAL_MS = 1000\n\ninterface SendReportInput {\n message: string\n name?: string\n stack?: string\n url?: string\n userAgent?: string\n context?: string\n}\n\nfunction buildSender(config: ErrorReporterConfig): (payload: SendReportInput) => void {\n let inflight = false\n let lastSentAt = 0\n\n return (payload) => {\n const now = Date.now()\n if (inflight) return\n if (now - lastSentAt < MIN_REPORT_INTERVAL_MS) return\n inflight = true\n lastSentAt = now\n\n // A fatal error is usually followed by a refresh, and without `keepalive`\n // the pending fetch is cancelled on unload and the event is lost.\n fetch(`${config.apiUrl.replace(/\\/+$/, '')}/widget/error`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-markup-api-key': config.apiKey,\n },\n body: JSON.stringify({\n ...payload,\n widgetVersion: config.widgetVersion,\n }),\n keepalive: true,\n })\n .catch(() => {\n // The error is already on the user's screen; \"failed to report\" on\n // top of it is noise.\n })\n .finally(() => {\n inflight = false\n })\n }\n}\n\nfunction currentLocation(): string | undefined {\n return typeof window !== 'undefined' ? window.location.href : undefined\n}\n\nfunction currentUserAgent(): string | undefined {\n return typeof navigator !== 'undefined' ? navigator.userAgent : undefined\n}\n\n/**\n * Rate-limited to one report per second with in-flight coalescing, so a render\n * loop can't saturate the network. Keyed by `config` reference, so every caller\n * passing the same object shares one window.\n */\nconst senderCache = new WeakMap<ErrorReporterConfig, (payload: SendReportInput) => void>()\n\nexport function reportWidgetError(\n config: ErrorReporterConfig,\n err: unknown,\n extra?: { context?: string },\n): void {\n let send = senderCache.get(config)\n if (!send) {\n send = buildSender(config)\n senderCache.set(config, send)\n }\n const error = err instanceof Error ? err : new Error(String(err))\n send({\n message: error.message,\n name: error.name,\n stack: error.stack,\n url: currentLocation(),\n userAgent: currentUserAgent(),\n context: extra?.context,\n })\n}\n\n/**\n * Ambient so runtime code can report without threading config through every\n * signature. A single slot suffices because the widget is singleton-per-page;\n * multi-mount would make this a `WeakMap<Window, …>`.\n *\n * A no-op when nothing is registered, so an error thrown during teardown\n * doesn't blow up on a destroyed reporter.\n */\nlet activeReporter: ErrorReporterConfig | null = null\n\nexport function setActiveReporter(config: ErrorReporterConfig | null): void {\n activeReporter = config\n}\n\nexport function reportError(err: unknown, extra?: { context?: string }): void {\n if (!activeReporter) return\n reportWidgetError(activeReporter, err, extra)\n}\n","/**\n * `auto` works by *removing* the host's `data-theme` so the shadow CSS falls\n * back to `prefers-color-scheme`; the media-query listener exists only to\n * re-render subscribers showing the resolved value.\n */\n\nconst STORAGE_KEY = 'markup:widget:theme'\n\nexport type ThemeMode = 'light' | 'dark' | 'auto'\ntype Listener = (mode: ThemeMode) => void\n\nlet host: HTMLElement | null = null\nlet mode: ThemeMode = readPersisted() ?? 'auto'\n/**\n * Must stay a live flag, not a load-time snapshot: this module outlives an\n * `init()` → `destroy()` → `init()` cycle, and a stale snapshot would let the\n * host's `theme` prop clobber a choice the user just made.\n */\nlet userPicked = readPersisted() != null\nconst listeners = new Set<Listener>()\n\nfunction readPersisted(): ThemeMode | null {\n try {\n const v = localStorage.getItem(STORAGE_KEY)\n if (v === 'light' || v === 'dark' || v === 'auto') return v\n } catch {\n // localStorage may throw in sandboxed iframes; fall through.\n }\n return null\n}\n\nfunction apply() {\n if (!host) return\n if (mode === 'auto') {\n delete host.dataset.theme\n } else {\n host.dataset.theme = mode\n }\n}\n\n/** `initial` only wins when the user has never picked a theme. */\nexport function bindThemeHost(el: HTMLElement, initial?: ThemeMode) {\n host = el\n if (!userPicked && initial) mode = initial\n apply()\n}\n\nexport function getThemeMode(): ThemeMode {\n return mode\n}\n\n/** For `auto`, reads `prefers-color-scheme` — what the picker displays. */\nexport function resolvedTheme(): 'light' | 'dark' {\n if (mode === 'dark') return 'dark'\n if (mode === 'light') return 'light'\n if (typeof window !== 'undefined' && window.matchMedia) {\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n }\n return 'light'\n}\n\nexport function setThemeMode(next: ThemeMode) {\n if (next === mode) return\n mode = next\n // Before the write: if localStorage is unavailable the choice can't outlive\n // the page, but it must still beat the host config while the page lives.\n userPicked = true\n try {\n localStorage.setItem(STORAGE_KEY, next)\n } catch {\n // Same rationale as readPersisted — non-fatal.\n }\n apply()\n for (const fn of listeners) fn(mode)\n}\n\nexport function subscribeTheme(fn: Listener): () => void {\n listeners.add(fn)\n return () => {\n listeners.delete(fn)\n }\n}\n\n/** Fire `auto`-resolved theme changes when the OS pref flips. */\nexport function watchSystemTheme(): () => void {\n if (typeof window === 'undefined' || !window.matchMedia) return () => {}\n const mq = window.matchMedia('(prefers-color-scheme: dark)')\n const handler = () => {\n if (mode === 'auto') for (const fn of listeners) fn(mode)\n }\n mq.addEventListener?.('change', handler)\n return () => mq.removeEventListener?.('change', handler)\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,p=c.__;function s(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,y(D,n)}function y(n,u,i){var o=s(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=!1,i=o.__c.props!==n;if(o.__c.__H.__.some(function(n){if(n.__N){u=!0;var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),c){var f=c.call(this,n,t,r);return u?f||i:f}return!u||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 h(n,u){var i=s(t++,3);!c.__s&&C(i.__H,u)&&(i.__=n,i.u=u,r.__H.__h.push(i))}function _(n,u){var i=s(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=s(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=s(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=s(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=s(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();){var t=n.__H;if(n.__P&&t)try{t.__h.some(z),t.__h.some(B),t.__h=[]}catch(r){t.__h=[],c.__e(r,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),p&&p(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.__.some(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0})):(i.__h.some(z),i.__h.some(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.__.some(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.some(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.__.some(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,h as useEffect,b as useErrorBoundary,g as useId,F as useImperativeHandle,_ as useLayoutEffect,T as useMemo,y as useReducer,A as useRef,d as useState};\n//# sourceMappingURL=hooks.module.js.map\n","\"use strict\";\nexport const version = \"1.38.0\";\n//# sourceMappingURL=index.js.map\n","\"use strict\";\nvar lookup = [];\nvar revLookup = [];\nvar Arr = Uint8Array;\nvar code = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i];\n revLookup[code.charCodeAt(i)] = i;\n}\nrevLookup[\"-\".charCodeAt(0)] = 62;\nrevLookup[\"_\".charCodeAt(0)] = 63;\nfunction getLens(b64) {\n var len = b64.length;\n if (len % 4 > 0) {\n throw new Error(\"Invalid string. Length must be a multiple of 4\");\n }\n var validLen = b64.indexOf(\"=\");\n if (validLen === -1) validLen = len;\n var placeHoldersLen = validLen === len ? 0 : 4 - validLen % 4;\n return [validLen, placeHoldersLen];\n}\nexport function byteLength(b64) {\n var lens = getLens(b64);\n var validLen = lens[0];\n var placeHoldersLen = lens[1];\n return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;\n}\nfunction _byteLength(_b64, validLen, placeHoldersLen) {\n return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;\n}\nexport function toByteArray(b64) {\n var tmp;\n var lens = getLens(b64);\n var validLen = lens[0];\n var placeHoldersLen = lens[1];\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));\n var curByte = 0;\n var len = placeHoldersLen > 0 ? validLen - 4 : validLen;\n var i;\n for (i = 0; i < len; i += 4) {\n tmp = revLookup[b64.charCodeAt(i)] << 18 | revLookup[b64.charCodeAt(i + 1)] << 12 | revLookup[b64.charCodeAt(i + 2)] << 6 | revLookup[b64.charCodeAt(i + 3)];\n arr[curByte++] = tmp >> 16 & 255;\n arr[curByte++] = tmp >> 8 & 255;\n arr[curByte++] = tmp & 255;\n }\n if (placeHoldersLen === 2) {\n tmp = revLookup[b64.charCodeAt(i)] << 2 | revLookup[b64.charCodeAt(i + 1)] >> 4;\n arr[curByte++] = tmp & 255;\n }\n if (placeHoldersLen === 1) {\n tmp = revLookup[b64.charCodeAt(i)] << 10 | revLookup[b64.charCodeAt(i + 1)] << 4 | revLookup[b64.charCodeAt(i + 2)] >> 2;\n arr[curByte++] = tmp >> 8 & 255;\n arr[curByte++] = tmp & 255;\n }\n return arr;\n}\nfunction tripletToBase64(num) {\n return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63];\n}\nfunction encodeChunk(uint8, start, end) {\n var tmp;\n var output = [];\n for (var i = start; i < end; i += 3) {\n tmp = (uint8[i] << 16 & 16711680) + (uint8[i + 1] << 8 & 65280) + (uint8[i + 2] & 255);\n output.push(tripletToBase64(tmp));\n }\n return output.join(\"\");\n}\nexport function fromByteArray(uint8) {\n var tmp;\n var len = uint8.length;\n var extraBytes = len % 3;\n var parts = [];\n var maxChunkLength = 16383;\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(\n encodeChunk(\n uint8,\n i,\n i + maxChunkLength > len2 ? len2 : i + maxChunkLength\n )\n );\n }\n if (extraBytes === 1) {\n tmp = uint8[len - 1];\n parts.push(lookup[tmp >> 2] + lookup[tmp << 4 & 63] + \"==\");\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1];\n parts.push(\n lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + \"=\"\n );\n }\n return parts.join(\"\");\n}\nexport function fromByteArrayUrlSafeNoPadding(uint8) {\n return fromByteArray(uint8).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n//# sourceMappingURL=base64.js.map\n","\"use strict\";\nexport function parseArgs(args) {\n if (args === void 0) {\n return {};\n }\n if (!isSimpleObject(args)) {\n throw new Error(\n `The arguments to a Convex function must be an object. Received: ${args}`\n );\n }\n return args;\n}\nexport function validateDeploymentUrl(deploymentUrl) {\n if (typeof deploymentUrl === \"undefined\") {\n throw new Error(\n `Client created with undefined deployment address. If you used an environment variable, check that it's set.`\n );\n }\n if (typeof deploymentUrl !== \"string\") {\n throw new Error(\n `Invalid deployment address: found ${deploymentUrl}\".`\n );\n }\n if (!(deploymentUrl.startsWith(\"http:\") || deploymentUrl.startsWith(\"https:\"))) {\n throw new Error(\n `Invalid deployment address: Must start with \"https://\" or \"http://\". Found \"${deploymentUrl}\".`\n );\n }\n try {\n new URL(deploymentUrl);\n } catch {\n throw new Error(\n `Invalid deployment address: \"${deploymentUrl}\" is not a valid URL. If you believe this URL is correct, use the \\`skipConvexDeploymentUrlCheck\\` option to bypass this.`\n );\n }\n if (deploymentUrl.endsWith(\".convex.site\")) {\n throw new Error(\n `Invalid deployment address: \"${deploymentUrl}\" ends with .convex.site, which is used for HTTP Actions. Convex deployment URLs typically end with .convex.cloud? If you believe this URL is correct, use the \\`skipConvexDeploymentUrlCheck\\` option to bypass this.`\n );\n }\n}\nexport function isSimpleObject(value) {\n const isObject = typeof value === \"object\";\n const prototype = Object.getPrototypeOf(value);\n const isSimple = prototype === null || prototype === Object.prototype || // Objects generated from other contexts (e.g. across Node.js `vm` modules) will not satisfy the previous\n // conditions but are still simple objects.\n prototype?.constructor?.name === \"Object\";\n return isObject && isSimple;\n}\n//# sourceMappingURL=index.js.map\n","\"use strict\";\nimport * as Base64 from \"./base64.js\";\nimport { isSimpleObject } from \"../common/index.js\";\nconst LITTLE_ENDIAN = true;\nconst MIN_INT64 = BigInt(\"-9223372036854775808\");\nconst MAX_INT64 = BigInt(\"9223372036854775807\");\nconst ZERO = BigInt(\"0\");\nconst EIGHT = BigInt(\"8\");\nconst TWOFIFTYSIX = BigInt(\"256\");\nfunction isSpecial(n) {\n return Number.isNaN(n) || !Number.isFinite(n) || Object.is(n, -0);\n}\nexport function slowBigIntToBase64(value) {\n if (value < ZERO) {\n value -= MIN_INT64 + MIN_INT64;\n }\n let hex = value.toString(16);\n if (hex.length % 2 === 1) hex = \"0\" + hex;\n const bytes = new Uint8Array(new ArrayBuffer(8));\n let i = 0;\n for (const hexByte of hex.match(/.{2}/g).reverse()) {\n bytes.set([parseInt(hexByte, 16)], i++);\n value >>= EIGHT;\n }\n return Base64.fromByteArray(bytes);\n}\nexport function slowBase64ToBigInt(encoded) {\n const integerBytes = Base64.toByteArray(encoded);\n if (integerBytes.byteLength !== 8) {\n throw new Error(\n `Received ${integerBytes.byteLength} bytes, expected 8 for $integer`\n );\n }\n let value = ZERO;\n let power = ZERO;\n for (const byte of integerBytes) {\n value += BigInt(byte) * TWOFIFTYSIX ** power;\n power++;\n }\n if (value > MAX_INT64) {\n value += MIN_INT64 + MIN_INT64;\n }\n return value;\n}\nexport function modernBigIntToBase64(value) {\n if (value < MIN_INT64 || MAX_INT64 < value) {\n throw new Error(\n `BigInt ${value} does not fit into a 64-bit signed integer.`\n );\n }\n const buffer = new ArrayBuffer(8);\n new DataView(buffer).setBigInt64(0, value, true);\n return Base64.fromByteArray(new Uint8Array(buffer));\n}\nexport function modernBase64ToBigInt(encoded) {\n const integerBytes = Base64.toByteArray(encoded);\n if (integerBytes.byteLength !== 8) {\n throw new Error(\n `Received ${integerBytes.byteLength} bytes, expected 8 for $integer`\n );\n }\n const intBytesView = new DataView(integerBytes.buffer);\n return intBytesView.getBigInt64(0, true);\n}\nexport const bigIntToBase64 = DataView.prototype.setBigInt64 ? modernBigIntToBase64 : slowBigIntToBase64;\nexport const base64ToBigInt = DataView.prototype.getBigInt64 ? modernBase64ToBigInt : slowBase64ToBigInt;\nconst MAX_IDENTIFIER_LEN = 1024;\nfunction validateObjectField(k) {\n if (k.length > MAX_IDENTIFIER_LEN) {\n throw new Error(\n `Field name ${k} exceeds maximum field name length ${MAX_IDENTIFIER_LEN}.`\n );\n }\n if (k.startsWith(\"$\")) {\n throw new Error(`Field name ${k} starts with a '$', which is reserved.`);\n }\n for (let i = 0; i < k.length; i += 1) {\n const charCode = k.charCodeAt(i);\n if (charCode < 32 || charCode >= 127) {\n throw new Error(\n `Field name ${k} has invalid character '${k[i]}': Field names can only contain non-control ASCII characters`\n );\n }\n }\n}\nexport function jsonToConvex(value) {\n if (value === null) {\n return value;\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((value2) => jsonToConvex(value2));\n }\n if (typeof value !== \"object\") {\n throw new Error(`Unexpected type of ${value}`);\n }\n const entries = Object.entries(value);\n if (entries.length === 1) {\n const key = entries[0][0];\n if (key === \"$bytes\") {\n if (typeof value.$bytes !== \"string\") {\n throw new Error(`Malformed $bytes field on ${value}`);\n }\n return Base64.toByteArray(value.$bytes).buffer;\n }\n if (key === \"$integer\") {\n if (typeof value.$integer !== \"string\") {\n throw new Error(`Malformed $integer field on ${value}`);\n }\n return base64ToBigInt(value.$integer);\n }\n if (key === \"$float\") {\n if (typeof value.$float !== \"string\") {\n throw new Error(`Malformed $float field on ${value}`);\n }\n const floatBytes = Base64.toByteArray(value.$float);\n if (floatBytes.byteLength !== 8) {\n throw new Error(\n `Received ${floatBytes.byteLength} bytes, expected 8 for $float`\n );\n }\n const floatBytesView = new DataView(floatBytes.buffer);\n const float = floatBytesView.getFloat64(0, LITTLE_ENDIAN);\n if (!isSpecial(float)) {\n throw new Error(`Float ${float} should be encoded as a number`);\n }\n return float;\n }\n if (key === \"$set\") {\n throw new Error(\n `Received a Set which is no longer supported as a Convex type.`\n );\n }\n if (key === \"$map\") {\n throw new Error(\n `Received a Map which is no longer supported as a Convex type.`\n );\n }\n }\n const out = {};\n for (const [k, v] of Object.entries(value)) {\n validateObjectField(k);\n out[k] = jsonToConvex(v);\n }\n return out;\n}\nconst MAX_VALUE_FOR_ERROR_LEN = 16384;\nexport function stringifyValueForError(value) {\n const str = JSON.stringify(value, (_key, value2) => {\n if (value2 === void 0) {\n return \"undefined\";\n }\n if (typeof value2 === \"bigint\") {\n return `${value2.toString()}n`;\n }\n return value2;\n });\n if (str.length > MAX_VALUE_FOR_ERROR_LEN) {\n const rest = \"[...truncated]\";\n let truncateAt = MAX_VALUE_FOR_ERROR_LEN - rest.length;\n const codePoint = str.codePointAt(truncateAt - 1);\n if (codePoint !== void 0 && codePoint > 65535) {\n truncateAt -= 1;\n }\n return str.substring(0, truncateAt) + rest;\n }\n return str;\n}\nfunction convexToJsonInternal(value, originalValue, context, includeTopLevelUndefined) {\n if (value === void 0) {\n const contextText = context && ` (present at path ${context} in original object ${stringifyValueForError(\n originalValue\n )})`;\n throw new Error(\n `undefined is not a valid Convex value${contextText}. To learn about Convex's supported types, see https://docs.convex.dev/using/types.`\n );\n }\n if (value === null) {\n return value;\n }\n if (typeof value === \"bigint\") {\n if (value < MIN_INT64 || MAX_INT64 < value) {\n throw new Error(\n `BigInt ${value} does not fit into a 64-bit signed integer.`\n );\n }\n return { $integer: bigIntToBase64(value) };\n }\n if (typeof value === \"number\") {\n if (isSpecial(value)) {\n const buffer = new ArrayBuffer(8);\n new DataView(buffer).setFloat64(0, value, LITTLE_ENDIAN);\n return { $float: Base64.fromByteArray(new Uint8Array(buffer)) };\n } else {\n return value;\n }\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (value instanceof ArrayBuffer) {\n return { $bytes: Base64.fromByteArray(new Uint8Array(value)) };\n }\n if (Array.isArray(value)) {\n return value.map(\n (value2, i) => convexToJsonInternal(value2, originalValue, context + `[${i}]`, false)\n );\n }\n if (value instanceof Set) {\n throw new Error(\n errorMessageForUnsupportedType(context, \"Set\", [...value], originalValue)\n );\n }\n if (value instanceof Map) {\n throw new Error(\n errorMessageForUnsupportedType(context, \"Map\", [...value], originalValue)\n );\n }\n if (!isSimpleObject(value)) {\n const theType = value?.constructor?.name;\n const typeName = theType ? `${theType} ` : \"\";\n throw new Error(\n errorMessageForUnsupportedType(context, typeName, value, originalValue)\n );\n }\n const out = {};\n const entries = Object.entries(value);\n entries.sort(([k1, _v1], [k2, _v2]) => k1 === k2 ? 0 : k1 < k2 ? -1 : 1);\n for (const [k, v] of entries) {\n if (v !== void 0) {\n validateObjectField(k);\n out[k] = convexToJsonInternal(v, originalValue, context + `.${k}`, false);\n } else if (includeTopLevelUndefined) {\n validateObjectField(k);\n out[k] = convexOrUndefinedToJsonInternal(\n v,\n originalValue,\n context + `.${k}`\n );\n }\n }\n return out;\n}\nfunction errorMessageForUnsupportedType(context, typeName, value, originalValue) {\n if (context) {\n return `${typeName}${stringifyValueForError(\n value\n )} is not a supported Convex type (present at path ${context} in original object ${stringifyValueForError(\n originalValue\n )}). To learn about Convex's supported types, see https://docs.convex.dev/using/types.`;\n } else {\n return `${typeName}${stringifyValueForError(\n value\n )} is not a supported Convex type.`;\n }\n}\nfunction convexOrUndefinedToJsonInternal(value, originalValue, context) {\n if (value === void 0) {\n return { $undefined: null };\n } else {\n if (originalValue === void 0) {\n throw new Error(\n `Programming error. Current value is ${stringifyValueForError(\n value\n )} but original value is undefined`\n );\n }\n return convexToJsonInternal(value, originalValue, context, false);\n }\n}\nexport function convexToJson(value) {\n return convexToJsonInternal(value, value, \"\", false);\n}\nexport function convexOrUndefinedToJson(value) {\n return convexOrUndefinedToJsonInternal(value, value, \"\");\n}\nexport function patchValueToJson(value) {\n return convexToJsonInternal(value, value, \"\", true);\n}\n//# sourceMappingURL=value.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nvar _a, _b;\nimport { stringifyValueForError } from \"./value.js\";\nconst IDENTIFYING_FIELD = Symbol.for(\"ConvexError\");\nexport class ConvexError extends (_b = Error, _a = IDENTIFYING_FIELD, _b) {\n constructor(data) {\n super(typeof data === \"string\" ? data : stringifyValueForError(data));\n __publicField(this, \"name\", \"ConvexError\");\n __publicField(this, \"data\");\n __publicField(this, _a, true);\n this.data = data;\n }\n}\n//# sourceMappingURL=errors.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nconst INFO_COLOR = \"color:rgb(0, 145, 255)\";\nfunction prefix_for_source(source) {\n switch (source) {\n case \"query\":\n return \"Q\";\n case \"mutation\":\n return \"M\";\n case \"action\":\n return \"A\";\n case \"any\":\n return \"?\";\n }\n}\nexport class DefaultLogger {\n constructor(options) {\n __publicField(this, \"_onLogLineFuncs\");\n __publicField(this, \"_verbose\");\n this._onLogLineFuncs = {};\n this._verbose = options.verbose;\n }\n addLogLineListener(func) {\n let id = Math.random().toString(36).substring(2, 15);\n for (let i = 0; i < 10; i++) {\n if (this._onLogLineFuncs[id] === void 0) {\n break;\n }\n id = Math.random().toString(36).substring(2, 15);\n }\n this._onLogLineFuncs[id] = func;\n return () => {\n delete this._onLogLineFuncs[id];\n };\n }\n logVerbose(...args) {\n if (this._verbose) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"debug\", `${(/* @__PURE__ */ new Date()).toISOString()}`, ...args);\n }\n }\n }\n log(...args) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"info\", ...args);\n }\n }\n warn(...args) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"warn\", ...args);\n }\n }\n error(...args) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"error\", ...args);\n }\n }\n}\nexport function instantiateDefaultLogger(options) {\n const logger = new DefaultLogger(options);\n logger.addLogLineListener((level, ...args) => {\n switch (level) {\n case \"debug\":\n console.debug(...args);\n break;\n case \"info\":\n console.log(...args);\n break;\n case \"warn\":\n console.warn(...args);\n break;\n case \"error\":\n console.error(...args);\n break;\n default: {\n level;\n console.log(...args);\n }\n }\n });\n return logger;\n}\nexport function instantiateNoopLogger(options) {\n return new DefaultLogger(options);\n}\nexport function logForFunction(logger, type, source, udfPath, message) {\n const prefix = prefix_for_source(source);\n if (typeof message === \"object\") {\n message = `ConvexError ${JSON.stringify(message.errorData, null, 2)}`;\n }\n if (type === \"info\") {\n const match = message.match(/^\\[.*?\\] /);\n if (match === null) {\n logger.error(\n `[CONVEX ${prefix}(${udfPath})] Could not parse console.log`\n );\n return;\n }\n const level = message.slice(1, match[0].length - 2);\n const args = message.slice(match[0].length);\n logger.log(`%c[CONVEX ${prefix}(${udfPath})] [${level}]`, INFO_COLOR, args);\n } else {\n logger.error(`[CONVEX ${prefix}(${udfPath})] ${message}`);\n }\n}\nexport function logFatalError(logger, message) {\n const errorMessage = `[CONVEX FATAL ERROR] ${message}`;\n logger.error(errorMessage);\n return new Error(errorMessage);\n}\nexport function createHybridErrorStacktrace(source, udfPath, result) {\n const prefix = prefix_for_source(source);\n return `[CONVEX ${prefix}(${udfPath})] ${result.errorMessage}\n Called by client`;\n}\nexport function forwardData(result, error) {\n error.data = result.errorData;\n return error;\n}\n//# sourceMappingURL=logging.js.map\n","\"use strict\";\nimport { convexToJson } from \"../../values/index.js\";\nexport function canonicalizeUdfPath(udfPath) {\n const pieces = udfPath.split(\":\");\n let moduleName;\n let functionName;\n if (pieces.length === 1) {\n moduleName = pieces[0];\n functionName = \"default\";\n } else {\n moduleName = pieces.slice(0, pieces.length - 1).join(\":\");\n functionName = pieces[pieces.length - 1];\n }\n if (moduleName.endsWith(\".js\")) {\n moduleName = moduleName.slice(0, -3);\n }\n return `${moduleName}:${functionName}`;\n}\nexport function serializePathAndArgs(udfPath, args) {\n return JSON.stringify({\n udfPath: canonicalizeUdfPath(udfPath),\n args: convexToJson(args)\n });\n}\nexport function serializePaginatedPathAndArgs(udfPath, args, options) {\n const { initialNumItems, id } = options;\n const result = JSON.stringify({\n type: \"paginated\",\n udfPath: canonicalizeUdfPath(udfPath),\n args: convexToJson(args),\n options: convexToJson({ initialNumItems, id })\n });\n return result;\n}\nexport function serializedQueryTokenIsPaginated(token) {\n return JSON.parse(token).type === \"paginated\";\n}\n//# sourceMappingURL=udf_path_utils.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { convexToJson } from \"../../values/index.js\";\nimport {\n canonicalizeUdfPath,\n serializePathAndArgs\n} from \"./udf_path_utils.js\";\nexport class LocalSyncState {\n constructor() {\n __publicField(this, \"nextQueryId\");\n __publicField(this, \"querySetVersion\");\n __publicField(this, \"querySet\");\n __publicField(this, \"queryIdToToken\");\n __publicField(this, \"identityVersion\");\n __publicField(this, \"auth\");\n __publicField(this, \"outstandingQueriesOlderThanRestart\");\n __publicField(this, \"outstandingAuthOlderThanRestart\");\n __publicField(this, \"paused\");\n __publicField(this, \"pendingQuerySetModifications\");\n this.nextQueryId = 0;\n this.querySetVersion = 0;\n this.identityVersion = 0;\n this.querySet = /* @__PURE__ */ new Map();\n this.queryIdToToken = /* @__PURE__ */ new Map();\n this.outstandingQueriesOlderThanRestart = /* @__PURE__ */ new Set();\n this.outstandingAuthOlderThanRestart = false;\n this.paused = false;\n this.pendingQuerySetModifications = /* @__PURE__ */ new Map();\n }\n hasSyncedPastLastReconnect() {\n return this.outstandingQueriesOlderThanRestart.size === 0 && !this.outstandingAuthOlderThanRestart;\n }\n markAuthCompletion() {\n this.outstandingAuthOlderThanRestart = false;\n }\n subscribe(udfPath, args, journal, componentPath) {\n const canonicalizedUdfPath = canonicalizeUdfPath(udfPath);\n const queryToken = serializePathAndArgs(canonicalizedUdfPath, args);\n const existingEntry = this.querySet.get(queryToken);\n if (existingEntry !== void 0) {\n existingEntry.numSubscribers += 1;\n return {\n queryToken,\n modification: null,\n unsubscribe: () => this.removeSubscriber(queryToken)\n };\n } else {\n const queryId = this.nextQueryId++;\n const query = {\n id: queryId,\n canonicalizedUdfPath,\n args,\n numSubscribers: 1,\n journal,\n componentPath\n };\n this.querySet.set(queryToken, query);\n this.queryIdToToken.set(queryId, queryToken);\n const baseVersion = this.querySetVersion;\n const newVersion = this.querySetVersion + 1;\n const add = {\n type: \"Add\",\n queryId,\n udfPath: canonicalizedUdfPath,\n args: [convexToJson(args)],\n journal,\n componentPath\n };\n if (this.paused) {\n this.pendingQuerySetModifications.set(queryId, add);\n } else {\n this.querySetVersion = newVersion;\n }\n const modification = {\n type: \"ModifyQuerySet\",\n baseVersion,\n newVersion,\n modifications: [add]\n };\n return {\n queryToken,\n modification,\n unsubscribe: () => this.removeSubscriber(queryToken)\n };\n }\n }\n transition(transition) {\n for (const modification of transition.modifications) {\n switch (modification.type) {\n case \"QueryUpdated\":\n case \"QueryFailed\": {\n this.outstandingQueriesOlderThanRestart.delete(modification.queryId);\n const journal = modification.journal;\n if (journal !== void 0) {\n const queryToken = this.queryIdToToken.get(modification.queryId);\n if (queryToken !== void 0) {\n this.querySet.get(queryToken).journal = journal;\n }\n }\n break;\n }\n case \"QueryRemoved\": {\n this.outstandingQueriesOlderThanRestart.delete(modification.queryId);\n break;\n }\n default: {\n modification;\n throw new Error(`Invalid modification ${modification.type}`);\n }\n }\n }\n }\n queryId(udfPath, args) {\n const canonicalizedUdfPath = canonicalizeUdfPath(udfPath);\n const queryToken = serializePathAndArgs(canonicalizedUdfPath, args);\n const existingEntry = this.querySet.get(queryToken);\n if (existingEntry !== void 0) {\n return existingEntry.id;\n }\n return null;\n }\n isCurrentOrNewerAuthVersion(version) {\n return version >= this.identityVersion;\n }\n getAuth() {\n return this.auth;\n }\n setAuth(value) {\n this.auth = {\n tokenType: \"User\",\n value\n };\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n baseVersion,\n ...this.auth\n };\n }\n setAdminAuth(value, actingAs) {\n const auth = {\n tokenType: \"Admin\",\n value,\n impersonating: actingAs\n };\n this.auth = auth;\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n baseVersion,\n ...auth\n };\n }\n clearAuth() {\n this.auth = void 0;\n this.markAuthCompletion();\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n tokenType: \"None\",\n baseVersion\n };\n }\n hasAuth() {\n return !!this.auth;\n }\n isNewAuth(value) {\n return this.auth?.value !== value;\n }\n queryPath(queryId) {\n const pathAndArgs = this.queryIdToToken.get(queryId);\n if (pathAndArgs) {\n return this.querySet.get(pathAndArgs).canonicalizedUdfPath;\n }\n return null;\n }\n queryArgs(queryId) {\n const pathAndArgs = this.queryIdToToken.get(queryId);\n if (pathAndArgs) {\n return this.querySet.get(pathAndArgs).args;\n }\n return null;\n }\n queryToken(queryId) {\n return this.queryIdToToken.get(queryId) ?? null;\n }\n queryJournal(queryToken) {\n return this.querySet.get(queryToken)?.journal;\n }\n restart() {\n this.unpause();\n this.outstandingQueriesOlderThanRestart.clear();\n const modifications = [];\n for (const localQuery of this.querySet.values()) {\n const add = {\n type: \"Add\",\n queryId: localQuery.id,\n udfPath: localQuery.canonicalizedUdfPath,\n args: [convexToJson(localQuery.args)],\n journal: localQuery.journal,\n componentPath: localQuery.componentPath\n };\n modifications.push(add);\n this.outstandingQueriesOlderThanRestart.add(localQuery.id);\n }\n this.querySetVersion = 1;\n const querySet = {\n type: \"ModifyQuerySet\",\n baseVersion: 0,\n newVersion: 1,\n modifications\n };\n if (!this.auth) {\n this.identityVersion = 0;\n return [querySet, void 0];\n }\n this.outstandingAuthOlderThanRestart = true;\n const authenticate = {\n type: \"Authenticate\",\n baseVersion: 0,\n ...this.auth\n };\n this.identityVersion = 1;\n return [querySet, authenticate];\n }\n pause() {\n this.paused = true;\n }\n resume() {\n const querySet = this.pendingQuerySetModifications.size > 0 ? {\n type: \"ModifyQuerySet\",\n baseVersion: this.querySetVersion,\n newVersion: ++this.querySetVersion,\n modifications: Array.from(\n this.pendingQuerySetModifications.values()\n )\n } : void 0;\n const authenticate = this.auth !== void 0 ? {\n type: \"Authenticate\",\n baseVersion: this.identityVersion++,\n ...this.auth\n } : void 0;\n this.unpause();\n return [querySet, authenticate];\n }\n unpause() {\n this.paused = false;\n this.pendingQuerySetModifications.clear();\n }\n removeSubscriber(queryToken) {\n const localQuery = this.querySet.get(queryToken);\n if (localQuery.numSubscribers > 1) {\n localQuery.numSubscribers -= 1;\n return null;\n } else {\n this.querySet.delete(queryToken);\n this.queryIdToToken.delete(localQuery.id);\n this.outstandingQueriesOlderThanRestart.delete(localQuery.id);\n const baseVersion = this.querySetVersion;\n const newVersion = this.querySetVersion + 1;\n const remove = {\n type: \"Remove\",\n queryId: localQuery.id\n };\n if (this.paused) {\n if (this.pendingQuerySetModifications.has(localQuery.id)) {\n this.pendingQuerySetModifications.delete(localQuery.id);\n } else {\n this.pendingQuerySetModifications.set(localQuery.id, remove);\n }\n } else {\n this.querySetVersion = newVersion;\n }\n return {\n type: \"ModifyQuerySet\",\n baseVersion,\n newVersion,\n modifications: [remove]\n };\n }\n }\n}\n//# sourceMappingURL=local_state.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { jsonToConvex } from \"../../values/index.js\";\nimport { logForFunction } from \"../logging.js\";\nexport class RequestManager {\n constructor(logger, markConnectionStateDirty) {\n this.logger = logger;\n this.markConnectionStateDirty = markConnectionStateDirty;\n __publicField(this, \"inflightRequests\");\n __publicField(this, \"requestsOlderThanRestart\");\n __publicField(this, \"inflightMutationsCount\", 0);\n __publicField(this, \"inflightActionsCount\", 0);\n this.inflightRequests = /* @__PURE__ */ new Map();\n this.requestsOlderThanRestart = /* @__PURE__ */ new Set();\n }\n request(message, sent) {\n const result = new Promise((resolve) => {\n const status = sent ? \"Requested\" : \"NotSent\";\n this.inflightRequests.set(message.requestId, {\n message,\n status: { status, requestedAt: /* @__PURE__ */ new Date(), onResult: resolve }\n });\n if (message.type === \"Mutation\") {\n this.inflightMutationsCount++;\n } else if (message.type === \"Action\") {\n this.inflightActionsCount++;\n }\n });\n this.markConnectionStateDirty();\n return result;\n }\n /**\n * Update the state after receiving a response.\n *\n * @returns A RequestId if the request is complete and its optimistic update\n * can be dropped, null otherwise.\n */\n onResponse(response) {\n const requestInfo = this.inflightRequests.get(response.requestId);\n if (requestInfo === void 0) {\n return null;\n }\n if (requestInfo.status.status === \"Completed\") {\n return null;\n }\n const udfType = requestInfo.message.type === \"Mutation\" ? \"mutation\" : \"action\";\n const udfPath = requestInfo.message.udfPath;\n for (const line of response.logLines) {\n logForFunction(this.logger, \"info\", udfType, udfPath, line);\n }\n const status = requestInfo.status;\n let result;\n let onResolve;\n if (response.success) {\n result = {\n success: true,\n logLines: response.logLines,\n value: jsonToConvex(response.result)\n };\n onResolve = () => status.onResult(result);\n } else {\n const errorMessage = response.result;\n const { errorData } = response;\n logForFunction(this.logger, \"error\", udfType, udfPath, errorMessage);\n result = {\n success: false,\n errorMessage,\n errorData: errorData !== void 0 ? jsonToConvex(errorData) : void 0,\n logLines: response.logLines\n };\n onResolve = () => status.onResult(result);\n }\n if (response.type === \"ActionResponse\" || !response.success) {\n onResolve();\n this.inflightRequests.delete(response.requestId);\n this.requestsOlderThanRestart.delete(response.requestId);\n if (requestInfo.message.type === \"Action\") {\n this.inflightActionsCount--;\n } else if (requestInfo.message.type === \"Mutation\") {\n this.inflightMutationsCount--;\n }\n this.markConnectionStateDirty();\n return { requestId: response.requestId, result };\n }\n requestInfo.status = {\n status: \"Completed\",\n result,\n ts: response.ts,\n onResolve\n };\n return null;\n }\n // Remove and returns completed requests.\n removeCompleted(ts) {\n const completeRequests = /* @__PURE__ */ new Map();\n for (const [requestId, requestInfo] of this.inflightRequests.entries()) {\n const status = requestInfo.status;\n if (status.status === \"Completed\" && status.ts.lessThanOrEqual(ts)) {\n status.onResolve();\n completeRequests.set(requestId, status.result);\n if (requestInfo.message.type === \"Mutation\") {\n this.inflightMutationsCount--;\n } else if (requestInfo.message.type === \"Action\") {\n this.inflightActionsCount--;\n }\n this.inflightRequests.delete(requestId);\n this.requestsOlderThanRestart.delete(requestId);\n }\n }\n if (completeRequests.size > 0) {\n this.markConnectionStateDirty();\n }\n return completeRequests;\n }\n restart() {\n this.requestsOlderThanRestart = new Set(this.inflightRequests.keys());\n const allMessages = [];\n for (const [requestId, value] of this.inflightRequests) {\n if (value.status.status === \"NotSent\") {\n value.status.status = \"Requested\";\n allMessages.push(value.message);\n continue;\n }\n if (value.message.type === \"Mutation\") {\n allMessages.push(value.message);\n } else if (value.message.type === \"Action\") {\n this.inflightRequests.delete(requestId);\n this.requestsOlderThanRestart.delete(requestId);\n this.inflightActionsCount--;\n if (value.status.status === \"Completed\") {\n throw new Error(\"Action should never be in 'Completed' state\");\n }\n value.status.onResult({\n success: false,\n errorMessage: \"Connection lost while action was in flight\",\n logLines: []\n });\n }\n }\n this.markConnectionStateDirty();\n return allMessages;\n }\n resume() {\n const allMessages = [];\n for (const [, value] of this.inflightRequests) {\n if (value.status.status === \"NotSent\") {\n value.status.status = \"Requested\";\n allMessages.push(value.message);\n continue;\n }\n }\n return allMessages;\n }\n /**\n * @returns true if there are any requests that have been requested but have\n * not be completed yet.\n */\n hasIncompleteRequests() {\n for (const requestInfo of this.inflightRequests.values()) {\n if (requestInfo.status.status === \"Requested\") {\n return true;\n }\n }\n return false;\n }\n /**\n * @returns true if there are any inflight requests, including ones that have\n * completed on the server, but have not been applied.\n */\n hasInflightRequests() {\n return this.inflightRequests.size > 0;\n }\n /**\n * @returns true if there are any inflight requests, that have been hanging around\n * since prior to the most recent restart.\n */\n hasSyncedPastLastReconnect() {\n return this.requestsOlderThanRestart.size === 0;\n }\n timeOfOldestInflightRequest() {\n if (this.inflightRequests.size === 0) {\n return null;\n }\n let oldestInflightRequest = Date.now();\n for (const request of this.inflightRequests.values()) {\n if (request.status.status !== \"Completed\") {\n if (request.status.requestedAt.getTime() < oldestInflightRequest) {\n oldestInflightRequest = request.status.requestedAt.getTime();\n }\n }\n }\n return new Date(oldestInflightRequest);\n }\n /**\n * @returns The number of mutations currently in flight.\n */\n inflightMutations() {\n return this.inflightMutationsCount;\n }\n /**\n * @returns The number of actions currently in flight.\n */\n inflightActions() {\n return this.inflightActionsCount;\n }\n}\n//# sourceMappingURL=request_manager.js.map\n","\"use strict\";\nexport const functionName = Symbol.for(\"functionName\");\n//# sourceMappingURL=functionName.js.map\n","\"use strict\";\nimport { functionName } from \"../functionName.js\";\nexport const toReferencePath = Symbol.for(\"toReferencePath\");\nexport function setReferencePath(obj, value) {\n obj[toReferencePath] = value;\n}\nexport function extractReferencePath(reference) {\n return reference[toReferencePath] ?? null;\n}\nexport function isFunctionHandle(s) {\n return s.startsWith(\"function://\");\n}\nexport function getFunctionAddress(functionReference) {\n let functionAddress;\n if (typeof functionReference === \"string\") {\n if (isFunctionHandle(functionReference)) {\n functionAddress = { functionHandle: functionReference };\n } else {\n functionAddress = { name: functionReference };\n }\n } else if (functionReference[functionName]) {\n functionAddress = { name: functionReference[functionName] };\n } else {\n const referencePath = extractReferencePath(functionReference);\n if (!referencePath) {\n throw new Error(`${functionReference} is not a functionReference`);\n }\n functionAddress = { reference: referencePath };\n }\n return functionAddress;\n}\n//# sourceMappingURL=paths.js.map\n","\"use strict\";\nimport { functionName } from \"./functionName.js\";\nimport { getFunctionAddress } from \"./components/paths.js\";\nexport function getFunctionName(functionReference) {\n const address = getFunctionAddress(functionReference);\n if (address.name === void 0) {\n if (address.functionHandle !== void 0) {\n throw new Error(\n `Expected function reference like \"api.file.func\" or \"internal.file.func\", but received function handle ${address.functionHandle}`\n );\n } else if (address.reference !== void 0) {\n throw new Error(\n `Expected function reference in the current component like \"api.file.func\" or \"internal.file.func\", but received reference ${address.reference}`\n );\n }\n throw new Error(\n `Expected function reference like \"api.file.func\" or \"internal.file.func\", but received ${JSON.stringify(address)}`\n );\n }\n if (typeof functionReference === \"string\") return functionReference;\n const name = functionReference[functionName];\n if (!name) {\n throw new Error(`${functionReference} is not a functionReference`);\n }\n return name;\n}\nexport function makeFunctionReference(name) {\n return { [functionName]: name };\n}\nfunction createApi(pathParts = []) {\n const handler = {\n get(_, prop) {\n if (typeof prop === \"string\") {\n const newParts = [...pathParts, prop];\n return createApi(newParts);\n } else if (prop === functionName) {\n if (pathParts.length < 2) {\n const found = [\"api\", ...pathParts].join(\".\");\n throw new Error(\n `API path is expected to be of the form \\`api.moduleName.functionName\\`. Found: \\`${found}\\``\n );\n }\n const path = pathParts.slice(0, -1).join(\"/\");\n const exportName = pathParts[pathParts.length - 1];\n if (exportName === \"default\") {\n return path;\n } else {\n return path + \":\" + exportName;\n }\n } else if (prop === Symbol.toStringTag) {\n return \"FunctionReference\";\n } else {\n return void 0;\n }\n }\n };\n return new Proxy({}, handler);\n}\nexport function filterApi(api) {\n return api;\n}\nexport function justInternal(api) {\n return api;\n}\nexport function justPublic(api) {\n return api;\n}\nexport function justQueries(api) {\n return api;\n}\nexport function justMutations(api) {\n return api;\n}\nexport function justActions(api) {\n return api;\n}\nexport function justPaginatedQueries(api) {\n return api;\n}\nexport function justSchedulable(api) {\n return api;\n}\nexport const anyApi = createApi();\n//# sourceMappingURL=api.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport {\n getFunctionName\n} from \"../../server/api.js\";\nimport { parseArgs } from \"../../common/index.js\";\nimport { createHybridErrorStacktrace, forwardData } from \"../logging.js\";\nimport {\n canonicalizeUdfPath,\n serializePathAndArgs\n} from \"./udf_path_utils.js\";\nimport { ConvexError } from \"../../values/errors.js\";\nclass OptimisticLocalStoreImpl {\n constructor(queryResults) {\n // A references of the query results in OptimisticQueryResults\n __publicField(this, \"queryResults\");\n // All of the queries modified by this class\n __publicField(this, \"modifiedQueries\");\n this.queryResults = queryResults;\n this.modifiedQueries = [];\n }\n getQuery(query, ...args) {\n const queryArgs = parseArgs(args[0]);\n const name = getFunctionName(query);\n const queryResult = this.queryResults.get(\n serializePathAndArgs(name, queryArgs)\n );\n if (queryResult === void 0) {\n return void 0;\n }\n return OptimisticLocalStoreImpl.queryValue(queryResult.result);\n }\n getAllQueries(query) {\n const queriesWithName = [];\n const name = getFunctionName(query);\n for (const queryResult of this.queryResults.values()) {\n if (queryResult.udfPath === canonicalizeUdfPath(name)) {\n queriesWithName.push({\n args: queryResult.args,\n value: OptimisticLocalStoreImpl.queryValue(queryResult.result)\n });\n }\n }\n return queriesWithName;\n }\n setQuery(queryReference, args, value) {\n const queryArgs = parseArgs(args);\n const name = getFunctionName(queryReference);\n const queryToken = serializePathAndArgs(name, queryArgs);\n let result;\n if (value === void 0) {\n result = void 0;\n } else {\n result = {\n success: true,\n value,\n // It's an optimistic update, so there are no function logs to show.\n logLines: []\n };\n }\n const query = {\n udfPath: name,\n args: queryArgs,\n result\n };\n this.queryResults.set(queryToken, query);\n this.modifiedQueries.push(queryToken);\n }\n static queryValue(result) {\n if (result === void 0) {\n return void 0;\n } else if (result.success) {\n return result.value;\n } else {\n return void 0;\n }\n }\n}\nexport class OptimisticQueryResults {\n constructor() {\n __publicField(this, \"queryResults\");\n __publicField(this, \"optimisticUpdates\");\n this.queryResults = /* @__PURE__ */ new Map();\n this.optimisticUpdates = [];\n }\n /**\n * Apply all optimistic updates on top of server query results\n */\n ingestQueryResultsFromServer(serverQueryResults, optimisticUpdatesToDrop) {\n this.optimisticUpdates = this.optimisticUpdates.filter((updateAndId) => {\n return !optimisticUpdatesToDrop.has(updateAndId.mutationId);\n });\n const oldQueryResults = this.queryResults;\n this.queryResults = new Map(serverQueryResults);\n const localStore = new OptimisticLocalStoreImpl(this.queryResults);\n for (const updateAndId of this.optimisticUpdates) {\n updateAndId.update(localStore);\n }\n const changedQueries = [];\n for (const [queryToken, query] of this.queryResults) {\n const oldQuery = oldQueryResults.get(queryToken);\n if (oldQuery === void 0 || oldQuery.result !== query.result) {\n changedQueries.push(queryToken);\n }\n }\n return changedQueries;\n }\n applyOptimisticUpdate(update, mutationId) {\n this.optimisticUpdates.push({\n update,\n mutationId\n });\n const localStore = new OptimisticLocalStoreImpl(this.queryResults);\n update(localStore);\n return localStore.modifiedQueries;\n }\n /**\n * \"Raw\" with respect to errors vs values, but query results still have\n * optimistic updates applied.\n *\n * @internal\n */\n rawQueryResult(queryToken) {\n const query = this.queryResults.get(queryToken);\n if (query === void 0) {\n return void 0;\n }\n return query.result;\n }\n queryResult(queryToken) {\n const query = this.queryResults.get(queryToken);\n if (query === void 0) {\n return void 0;\n }\n const result = query.result;\n if (result === void 0) {\n return void 0;\n } else if (result.success) {\n return result.value;\n } else {\n if (result.errorData !== void 0) {\n throw forwardData(\n result,\n new ConvexError(\n createHybridErrorStacktrace(\"query\", query.udfPath, result)\n )\n );\n }\n throw new Error(\n createHybridErrorStacktrace(\"query\", query.udfPath, result)\n );\n }\n }\n hasQueryResult(queryToken) {\n return this.queryResults.get(queryToken) !== void 0;\n }\n /**\n * @internal\n */\n queryLogs(queryToken) {\n const query = this.queryResults.get(queryToken);\n return query?.result?.logLines;\n }\n}\n//# sourceMappingURL=optimistic_updates_impl.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nexport class Long {\n constructor(low, high) {\n __publicField(this, \"low\");\n __publicField(this, \"high\");\n __publicField(this, \"__isUnsignedLong__\");\n this.low = low | 0;\n this.high = high | 0;\n this.__isUnsignedLong__ = true;\n }\n static isLong(obj) {\n return (obj && obj.__isUnsignedLong__) === true;\n }\n // prettier-ignore\n static fromBytesLE(bytes) {\n return new Long(\n bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24,\n bytes[4] | bytes[5] << 8 | bytes[6] << 16 | bytes[7] << 24\n );\n }\n // prettier-ignore\n toBytesLE() {\n const hi = this.high;\n const lo = this.low;\n return [\n lo & 255,\n lo >>> 8 & 255,\n lo >>> 16 & 255,\n lo >>> 24,\n hi & 255,\n hi >>> 8 & 255,\n hi >>> 16 & 255,\n hi >>> 24\n ];\n }\n static fromNumber(value) {\n if (isNaN(value)) return UZERO;\n if (value < 0) return UZERO;\n if (value >= TWO_PWR_64_DBL) return MAX_UNSIGNED_VALUE;\n return new Long(value % TWO_PWR_32_DBL | 0, value / TWO_PWR_32_DBL | 0);\n }\n toString() {\n return (BigInt(this.high) * BigInt(TWO_PWR_32_DBL) + BigInt(this.low)).toString();\n }\n equals(other) {\n if (!Long.isLong(other)) other = Long.fromValue(other);\n if (this.high >>> 31 === 1 && other.high >>> 31 === 1) return false;\n return this.high === other.high && this.low === other.low;\n }\n notEquals(other) {\n return !this.equals(other);\n }\n comp(other) {\n if (!Long.isLong(other)) other = Long.fromValue(other);\n if (this.equals(other)) return 0;\n return other.high >>> 0 > this.high >>> 0 || other.high === this.high && other.low >>> 0 > this.low >>> 0 ? -1 : 1;\n }\n lessThanOrEqual(other) {\n return this.comp(\n /* validates */\n other\n ) <= 0;\n }\n static fromValue(val) {\n if (typeof val === \"number\") return Long.fromNumber(val);\n return new Long(val.low, val.high);\n }\n}\nconst UZERO = new Long(0, 0);\nconst TWO_PWR_16_DBL = 1 << 16;\nconst TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;\nconst TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;\nconst MAX_UNSIGNED_VALUE = new Long(4294967295 | 0, 4294967295 | 0);\n//# sourceMappingURL=long.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { jsonToConvex } from \"../../values/index.js\";\nimport { Long } from \"../../vendor/long.js\";\nimport { logForFunction } from \"../logging.js\";\nexport class RemoteQuerySet {\n constructor(queryPath, logger) {\n __publicField(this, \"version\");\n __publicField(this, \"remoteQuerySet\");\n __publicField(this, \"queryPath\");\n __publicField(this, \"logger\");\n this.version = { querySet: 0, ts: Long.fromNumber(0), identity: 0 };\n this.remoteQuerySet = /* @__PURE__ */ new Map();\n this.queryPath = queryPath;\n this.logger = logger;\n }\n transition(transition) {\n const start = transition.startVersion;\n if (this.version.querySet !== start.querySet || this.version.ts.notEquals(start.ts) || this.version.identity !== start.identity) {\n throw new Error(\n `Invalid start version: ${start.ts.toString()}:${start.querySet}:${start.identity}, transitioning from ${this.version.ts.toString()}:${this.version.querySet}:${this.version.identity}`\n );\n }\n for (const modification of transition.modifications) {\n switch (modification.type) {\n case \"QueryUpdated\": {\n const queryPath = this.queryPath(modification.queryId);\n if (queryPath) {\n for (const line of modification.logLines) {\n logForFunction(this.logger, \"info\", \"query\", queryPath, line);\n }\n }\n const value = jsonToConvex(modification.value ?? null);\n this.remoteQuerySet.set(modification.queryId, {\n success: true,\n value,\n logLines: modification.logLines\n });\n break;\n }\n case \"QueryFailed\": {\n const queryPath = this.queryPath(modification.queryId);\n if (queryPath) {\n for (const line of modification.logLines) {\n logForFunction(this.logger, \"info\", \"query\", queryPath, line);\n }\n }\n const { errorData } = modification;\n this.remoteQuerySet.set(modification.queryId, {\n success: false,\n errorMessage: modification.errorMessage,\n errorData: errorData !== void 0 ? jsonToConvex(errorData) : void 0,\n logLines: modification.logLines\n });\n break;\n }\n case \"QueryRemoved\": {\n this.remoteQuerySet.delete(modification.queryId);\n break;\n }\n default: {\n modification;\n throw new Error(`Invalid modification ${modification.type}`);\n }\n }\n }\n this.version = transition.endVersion;\n }\n remoteQueryResults() {\n return this.remoteQuerySet;\n }\n timestamp() {\n return this.version.ts;\n }\n}\n//# sourceMappingURL=remote_query_set.js.map\n","\"use strict\";\nimport { Base64 } from \"../../values/index.js\";\nimport { Long } from \"../../vendor/long.js\";\nexport function u64ToLong(encoded) {\n const integerBytes = Base64.toByteArray(encoded);\n return Long.fromBytesLE(Array.from(integerBytes));\n}\nexport function longToU64(raw) {\n const integerBytes = new Uint8Array(raw.toBytesLE());\n return Base64.fromByteArray(integerBytes);\n}\nexport function parseServerMessage(encoded) {\n switch (encoded.type) {\n case \"FatalError\":\n case \"AuthError\":\n case \"ActionResponse\":\n case \"TransitionChunk\":\n case \"Ping\": {\n return { ...encoded };\n }\n case \"MutationResponse\": {\n if (encoded.success) {\n return { ...encoded, ts: u64ToLong(encoded.ts) };\n } else {\n return { ...encoded };\n }\n }\n case \"Transition\": {\n return {\n ...encoded,\n startVersion: {\n ...encoded.startVersion,\n ts: u64ToLong(encoded.startVersion.ts)\n },\n endVersion: {\n ...encoded.endVersion,\n ts: u64ToLong(encoded.endVersion.ts)\n }\n };\n }\n default: {\n encoded;\n }\n }\n return void 0;\n}\nexport function encodeClientMessage(message) {\n switch (message.type) {\n case \"Authenticate\":\n case \"ModifyQuerySet\":\n case \"Mutation\":\n case \"Action\":\n case \"Event\": {\n return { ...message };\n }\n case \"Connect\": {\n if (message.maxObservedTimestamp !== void 0) {\n return {\n ...message,\n maxObservedTimestamp: longToU64(message.maxObservedTimestamp)\n };\n } else {\n return { ...message, maxObservedTimestamp: void 0 };\n }\n }\n default: {\n message;\n }\n }\n return void 0;\n}\n//# sourceMappingURL=protocol.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport {\n encodeClientMessage,\n parseServerMessage\n} from \"./protocol.js\";\nconst CLOSE_NORMAL = 1e3;\nconst CLOSE_GOING_AWAY = 1001;\nconst CLOSE_NO_STATUS = 1005;\nconst CLOSE_NOT_FOUND = 4040;\nlet firstTime;\nfunction monotonicMillis() {\n if (firstTime === void 0) {\n firstTime = Date.now();\n }\n if (typeof performance === \"undefined\" || !performance.now) {\n return Date.now();\n }\n return Math.round(firstTime + performance.now());\n}\nfunction prettyNow() {\n return `t=${Math.round((monotonicMillis() - firstTime) / 100) / 10}s`;\n}\nconst serverDisconnectErrors = {\n // A known error, e.g. during a restart or push\n InternalServerError: { timeout: 1e3 },\n // ErrorMetadata::overloaded() messages that we realy should back off\n SubscriptionsWorkerFullError: { timeout: 3e3 },\n TooManyConcurrentRequests: { timeout: 3e3 },\n CommitterFullError: { timeout: 3e3 },\n AwsTooManyRequestsException: { timeout: 3e3 },\n ExecuteFullError: { timeout: 3e3 },\n SystemTimeoutError: { timeout: 3e3 },\n ExpiredInQueue: { timeout: 3e3 },\n // ErrorMetadata::feature_temporarily_unavailable() that typically indicate a deploy just happened\n VectorIndexesUnavailable: { timeout: 1e3 },\n SearchIndexesUnavailable: { timeout: 1e3 },\n TableSummariesUnavailable: { timeout: 1e3 },\n // More ErrorMetadata::overloaded()\n VectorIndexTooLarge: { timeout: 3e3 },\n SearchIndexTooLarge: { timeout: 3e3 },\n TooManyWritesInTimePeriod: { timeout: 3e3 }\n};\nfunction classifyDisconnectError(s) {\n if (s === void 0) return \"Unknown\";\n for (const prefix of Object.keys(\n serverDisconnectErrors\n )) {\n if (s.startsWith(prefix)) {\n return prefix;\n }\n }\n return \"Unknown\";\n}\nexport class WebSocketManager {\n constructor(uri, callbacks, webSocketConstructor, logger, markConnectionStateDirty, debug) {\n this.markConnectionStateDirty = markConnectionStateDirty;\n this.debug = debug;\n __publicField(this, \"socket\");\n __publicField(this, \"connectionCount\");\n __publicField(this, \"_hasEverConnected\", false);\n __publicField(this, \"lastCloseReason\");\n // State for assembling the split-up Transition currently being received.\n __publicField(this, \"transitionChunkBuffer\", null);\n /** Upon HTTPS/WSS failure, the first jittered backoff duration, in ms. */\n __publicField(this, \"defaultInitialBackoff\");\n /** We backoff exponentially, but we need to cap that--this is the jittered max. */\n __publicField(this, \"maxBackoff\");\n /** How many times have we failed consecutively? */\n __publicField(this, \"retries\");\n /** How long before lack of server response causes us to initiate a reconnect,\n * in ms */\n __publicField(this, \"serverInactivityThreshold\");\n __publicField(this, \"reconnectDueToServerInactivityTimeout\");\n /** Scheduled reconnect state: timeout handle and timing info */\n __publicField(this, \"scheduledReconnect\", null);\n __publicField(this, \"networkOnlineHandler\", null);\n /** Pending event to send after reconnecting due to network recovery */\n __publicField(this, \"pendingNetworkRecoveryInfo\", null);\n __publicField(this, \"uri\");\n __publicField(this, \"onOpen\");\n __publicField(this, \"onResume\");\n __publicField(this, \"onMessage\");\n __publicField(this, \"webSocketConstructor\");\n __publicField(this, \"logger\");\n __publicField(this, \"onServerDisconnectError\");\n this.webSocketConstructor = webSocketConstructor;\n this.socket = { state: \"disconnected\" };\n this.connectionCount = 0;\n this.lastCloseReason = \"InitialConnect\";\n this.defaultInitialBackoff = 1e3;\n this.maxBackoff = 16e3;\n this.retries = 0;\n this.serverInactivityThreshold = 6e4;\n this.reconnectDueToServerInactivityTimeout = null;\n this.uri = uri;\n this.onOpen = callbacks.onOpen;\n this.onResume = callbacks.onResume;\n this.onMessage = callbacks.onMessage;\n this.onServerDisconnectError = callbacks.onServerDisconnectError;\n this.logger = logger;\n this.setupNetworkListener();\n this.connect();\n }\n setSocketState(state) {\n this.socket = state;\n this._logVerbose(\n `socket state changed: ${this.socket.state}, paused: ${\"paused\" in this.socket ? this.socket.paused : void 0}`\n );\n this.markConnectionStateDirty();\n }\n setupNetworkListener() {\n if (typeof window === \"undefined\" || typeof window.addEventListener !== \"function\") {\n return;\n }\n if (this.networkOnlineHandler !== null) {\n return;\n }\n this.networkOnlineHandler = () => {\n this._logVerbose(\"network online event detected\");\n this.tryReconnectImmediately();\n };\n window.addEventListener(\"online\", this.networkOnlineHandler);\n this._logVerbose(\"network online event listener registered\");\n }\n cleanupNetworkListener() {\n if (this.networkOnlineHandler && typeof window !== \"undefined\" && typeof window.removeEventListener === \"function\") {\n window.removeEventListener(\"online\", this.networkOnlineHandler);\n this.networkOnlineHandler = null;\n this._logVerbose(\"network online event listener removed\");\n }\n }\n assembleTransition(chunk) {\n if (chunk.partNumber < 0 || chunk.partNumber >= chunk.totalParts || chunk.totalParts === 0 || this.transitionChunkBuffer && (this.transitionChunkBuffer.totalParts !== chunk.totalParts || this.transitionChunkBuffer.transitionId !== chunk.transitionId)) {\n this.transitionChunkBuffer = null;\n throw new Error(\"Invalid TransitionChunk\");\n }\n if (this.transitionChunkBuffer === null) {\n this.transitionChunkBuffer = {\n chunks: [],\n totalParts: chunk.totalParts,\n transitionId: chunk.transitionId\n };\n }\n if (chunk.partNumber !== this.transitionChunkBuffer.chunks.length) {\n const expectedLength = this.transitionChunkBuffer.chunks.length;\n this.transitionChunkBuffer = null;\n throw new Error(\n `TransitionChunk received out of order: expected part ${expectedLength}, got ${chunk.partNumber}`\n );\n }\n this.transitionChunkBuffer.chunks.push(chunk.chunk);\n if (this.transitionChunkBuffer.chunks.length === chunk.totalParts) {\n const fullJson = this.transitionChunkBuffer.chunks.join(\"\");\n this.transitionChunkBuffer = null;\n const transition = parseServerMessage(JSON.parse(fullJson));\n if (transition.type !== \"Transition\") {\n throw new Error(\n `Expected Transition, got ${transition.type} after assembling chunks`\n );\n }\n return transition;\n }\n return null;\n }\n connect() {\n if (this.socket.state === \"terminated\") {\n return;\n }\n if (this.socket.state !== \"disconnected\" && this.socket.state !== \"stopped\") {\n throw new Error(\n \"Didn't start connection from disconnected state: \" + this.socket.state\n );\n }\n const ws = new this.webSocketConstructor(this.uri);\n this._logVerbose(\"constructed WebSocket\");\n this.setSocketState({\n state: \"connecting\",\n ws,\n paused: \"no\"\n });\n this.resetServerInactivityTimeout();\n ws.onopen = () => {\n this.logger.logVerbose(\"begin ws.onopen\");\n if (this.socket.state !== \"connecting\") {\n throw new Error(\"onopen called with socket not in connecting state\");\n }\n this.setSocketState({\n state: \"ready\",\n ws,\n paused: this.socket.paused === \"yes\" ? \"uninitialized\" : \"no\"\n });\n this.resetServerInactivityTimeout();\n if (this.socket.paused === \"no\") {\n this._hasEverConnected = true;\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n clientTs: monotonicMillis()\n });\n }\n if (this.lastCloseReason !== \"InitialConnect\") {\n if (this.lastCloseReason) {\n this.logger.log(\n \"WebSocket reconnected at\",\n prettyNow(),\n \"after disconnect due to\",\n this.lastCloseReason\n );\n } else {\n this.logger.log(\"WebSocket reconnected at\", prettyNow());\n }\n }\n this.connectionCount += 1;\n this.lastCloseReason = null;\n if (this.pendingNetworkRecoveryInfo !== null) {\n const { timeSavedMs } = this.pendingNetworkRecoveryInfo;\n this.pendingNetworkRecoveryInfo = null;\n this.sendMessage({\n type: \"Event\",\n eventType: \"NetworkRecoveryReconnect\",\n event: { timeSavedMs }\n });\n this.logger.log(\n `Network recovery reconnect saved ~${Math.round(timeSavedMs / 1e3)}s of waiting`\n );\n }\n };\n ws.onerror = (error) => {\n this.transitionChunkBuffer = null;\n const message = error.message;\n if (message) {\n this.logger.log(`WebSocket error message: ${message}`);\n }\n };\n ws.onmessage = (message) => {\n this.resetServerInactivityTimeout();\n const messageLength = message.data.length;\n let serverMessage = parseServerMessage(JSON.parse(message.data));\n this._logVerbose(`received ws message with type ${serverMessage.type}`);\n if (serverMessage.type === \"Ping\") {\n return;\n }\n if (serverMessage.type === \"TransitionChunk\") {\n const transition = this.assembleTransition(serverMessage);\n if (!transition) {\n return;\n }\n serverMessage = transition;\n this._logVerbose(\n `assembled full ws message of type ${serverMessage.type}`\n );\n }\n if (this.transitionChunkBuffer !== null) {\n this.transitionChunkBuffer = null;\n this.logger.log(\n `Received unexpected ${serverMessage.type} while buffering TransitionChunks`\n );\n }\n if (serverMessage.type === \"Transition\") {\n this.reportLargeTransition({\n messageLength,\n transition: serverMessage\n });\n }\n const response = this.onMessage(serverMessage);\n if (response.hasSyncedPastLastReconnect) {\n this.retries = 0;\n this.markConnectionStateDirty();\n }\n };\n ws.onclose = (event) => {\n this._logVerbose(\"begin ws.onclose\");\n this.transitionChunkBuffer = null;\n if (this.lastCloseReason === null) {\n this.lastCloseReason = event.reason || `closed with code ${event.code}`;\n }\n if (event.code !== CLOSE_NORMAL && event.code !== CLOSE_GOING_AWAY && // This commonly gets fired on mobile apps when the app is backgrounded\n event.code !== CLOSE_NO_STATUS && event.code !== CLOSE_NOT_FOUND) {\n let msg = `WebSocket closed with code ${event.code}`;\n if (event.reason) {\n msg += `: ${event.reason}`;\n }\n this.logger.log(msg);\n if (this.onServerDisconnectError && event.reason) {\n this.onServerDisconnectError(msg);\n }\n }\n const reason = classifyDisconnectError(event.reason);\n this.scheduleReconnect(reason);\n return;\n };\n }\n /**\n * @returns The state of the {@link Socket}.\n */\n socketState() {\n return this.socket.state;\n }\n /**\n * @param message - A ClientMessage to send.\n * @returns Whether the message (might have been) sent.\n */\n sendMessage(message) {\n const messageForLog = {\n type: message.type,\n ...message.type === \"Authenticate\" && message.tokenType === \"User\" ? {\n value: `...${message.value.slice(-7)}`\n } : {}\n };\n if (this.socket.state === \"ready\" && this.socket.paused === \"no\") {\n const encodedMessage = encodeClientMessage(message);\n const request = JSON.stringify(encodedMessage);\n let sent = false;\n try {\n this.socket.ws.send(request);\n sent = true;\n } catch (error) {\n this.logger.log(\n `Failed to send message on WebSocket, reconnecting: ${error}`\n );\n this.closeAndReconnect(\"FailedToSendMessage\");\n }\n this._logVerbose(\n `${sent ? \"sent\" : \"failed to send\"} message with type ${message.type}: ${JSON.stringify(\n messageForLog\n )}`\n );\n return true;\n }\n this._logVerbose(\n `message not sent (socket state: ${this.socket.state}, paused: ${\"paused\" in this.socket ? this.socket.paused : void 0}): ${JSON.stringify(\n messageForLog\n )}`\n );\n return false;\n }\n resetServerInactivityTimeout() {\n if (this.socket.state === \"terminated\") {\n return;\n }\n if (this.reconnectDueToServerInactivityTimeout !== null) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n this.reconnectDueToServerInactivityTimeout = null;\n }\n this.reconnectDueToServerInactivityTimeout = setTimeout(() => {\n this.closeAndReconnect(\"InactiveServer\");\n }, this.serverInactivityThreshold);\n }\n scheduleReconnect(reason) {\n if (this.scheduledReconnect) {\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n }\n this.socket = { state: \"disconnected\" };\n const backoff = this.nextBackoff(reason);\n this.markConnectionStateDirty();\n this.logger.log(`Attempting reconnect in ${Math.round(backoff)}ms`);\n const scheduledAt = monotonicMillis();\n const timeoutId = setTimeout(() => {\n if (this.scheduledReconnect?.timeout === timeoutId) {\n this.scheduledReconnect = null;\n this.connect();\n }\n }, backoff);\n this.scheduledReconnect = {\n timeout: timeoutId,\n scheduledAt,\n backoffMs: backoff\n };\n }\n /**\n * Close the WebSocket and schedule a reconnect.\n *\n * This should be used when we hit an error and would like to restart the session.\n */\n closeAndReconnect(closeReason) {\n this._logVerbose(`begin closeAndReconnect with reason ${closeReason}`);\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n return;\n case \"connecting\":\n case \"ready\": {\n this.lastCloseReason = closeReason;\n void this.close();\n this.scheduleReconnect(\"client\");\n return;\n }\n default: {\n this.socket;\n }\n }\n }\n /**\n * Close the WebSocket, being careful to clear the onclose handler to avoid re-entrant\n * calls. Use this instead of directly calling `ws.close()`\n *\n * It is the callers responsibility to update the state after this method is called so that the\n * closed socket is not accessible or used again after this method is called\n */\n close() {\n this.transitionChunkBuffer = null;\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n return Promise.resolve();\n case \"connecting\": {\n const ws = this.socket.ws;\n ws.onmessage = (_message) => {\n this._logVerbose(\"Ignoring message received after close\");\n };\n return new Promise((r) => {\n ws.onclose = () => {\n this._logVerbose(\"Closed after connecting\");\n r();\n };\n ws.onopen = () => {\n this._logVerbose(\"Opened after connecting\");\n ws.close();\n };\n });\n }\n case \"ready\": {\n this._logVerbose(\"ws.close called\");\n const ws = this.socket.ws;\n ws.onmessage = (_message) => {\n this._logVerbose(\"Ignoring message received after close\");\n };\n const result = new Promise((r) => {\n ws.onclose = () => {\n r();\n };\n });\n ws.close();\n return result;\n }\n default: {\n this.socket;\n return Promise.resolve();\n }\n }\n }\n /**\n * Close the WebSocket and do not reconnect.\n * @returns A Promise that resolves when the WebSocket `onClose` callback is called.\n */\n terminate() {\n if (this.reconnectDueToServerInactivityTimeout) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n }\n if (this.scheduledReconnect) {\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n }\n this.cleanupNetworkListener();\n switch (this.socket.state) {\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n case \"connecting\":\n case \"ready\": {\n const result = this.close();\n this.setSocketState({ state: \"terminated\" });\n return result;\n }\n default: {\n this.socket;\n throw new Error(\n `Invalid websocket state: ${this.socket.state}`\n );\n }\n }\n }\n stop() {\n switch (this.socket.state) {\n case \"terminated\":\n return Promise.resolve();\n case \"connecting\":\n case \"stopped\":\n case \"disconnected\":\n case \"ready\": {\n this.cleanupNetworkListener();\n const result = this.close();\n this.socket = { state: \"stopped\" };\n return result;\n }\n default: {\n this.socket;\n return Promise.resolve();\n }\n }\n }\n /**\n * Create a new WebSocket after a previous `stop()`, unless `terminate()` was\n * called before.\n */\n tryRestart() {\n switch (this.socket.state) {\n case \"stopped\":\n break;\n case \"terminated\":\n case \"connecting\":\n case \"ready\":\n case \"disconnected\":\n this.logger.logVerbose(\"Restart called without stopping first\");\n return;\n default: {\n this.socket;\n }\n }\n this.setupNetworkListener();\n this.connect();\n }\n pause() {\n switch (this.socket.state) {\n case \"disconnected\":\n case \"stopped\":\n case \"terminated\":\n return;\n case \"connecting\":\n case \"ready\": {\n this.socket = { ...this.socket, paused: \"yes\" };\n return;\n }\n default: {\n this.socket;\n return;\n }\n }\n }\n /**\n * Try to reconnect immediately, canceling any scheduled reconnect.\n * This is useful when detecting network recovery.\n * Only takes action if we're in disconnected state (waiting to reconnect).\n */\n tryReconnectImmediately() {\n this._logVerbose(\"tryReconnectImmediately called\");\n if (this.socket.state !== \"disconnected\") {\n this._logVerbose(\n `tryReconnectImmediately called but socket state is ${this.socket.state}, no action taken`\n );\n return;\n }\n let timeSavedMs = null;\n if (this.scheduledReconnect) {\n const elapsed = monotonicMillis() - this.scheduledReconnect.scheduledAt;\n timeSavedMs = Math.max(0, this.scheduledReconnect.backoffMs - elapsed);\n this._logVerbose(\n `would have waited ${Math.round(timeSavedMs)}ms more (backoff was ${Math.round(this.scheduledReconnect.backoffMs)}ms, elapsed ${Math.round(elapsed)}ms)`\n );\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n this._logVerbose(\"canceled scheduled reconnect\");\n }\n this.logger.log(\"Network recovery detected, reconnecting immediately\");\n this.pendingNetworkRecoveryInfo = timeSavedMs !== null ? { timeSavedMs } : null;\n this.connect();\n }\n /**\n * Resume the state machine if previously paused.\n */\n resume() {\n switch (this.socket.state) {\n case \"connecting\":\n this.socket = { ...this.socket, paused: \"no\" };\n return;\n case \"ready\":\n if (this.socket.paused === \"uninitialized\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this._hasEverConnected = true;\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n clientTs: monotonicMillis()\n });\n } else if (this.socket.paused === \"yes\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this.onResume();\n }\n return;\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n return;\n default: {\n this.socket;\n }\n }\n this.connect();\n }\n connectionState() {\n return {\n isConnected: this.socket.state === \"ready\",\n hasEverConnected: this._hasEverConnected,\n connectionCount: this.connectionCount,\n connectionRetries: this.retries\n };\n }\n _logVerbose(message) {\n this.logger.logVerbose(message);\n }\n nextBackoff(reason) {\n const initialBackoff = reason === \"client\" ? 100 : reason === \"Unknown\" ? this.defaultInitialBackoff : serverDisconnectErrors[reason].timeout;\n const baseBackoff = initialBackoff * Math.pow(2, this.retries);\n this.retries += 1;\n const actualBackoff = Math.min(baseBackoff, this.maxBackoff);\n const jitter = actualBackoff * (Math.random() - 0.5);\n return actualBackoff + jitter;\n }\n reportLargeTransition({\n transition,\n messageLength\n }) {\n if (transition.clientClockSkew === void 0 || transition.serverTs === void 0) {\n return;\n }\n const transitionTransitTime = monotonicMillis() - // client time now\n // clientClockSkew = (server time + upstream latency) - client time\n // clientClockSkew is \"how many milliseconds behind (slow) is the client clock\"\n // but the latency of the Connect message inflates this, making it appear further behind\n transition.clientClockSkew - transition.serverTs / 1e6;\n const prettyTransitionTime = `${Math.round(transitionTransitTime)}ms`;\n const prettyMessageMB = `${Math.round(messageLength / 1e4) / 100}MB`;\n const bytesPerSecond = messageLength / (transitionTransitTime / 1e3);\n const prettyBytesPerSecond = `${Math.round(bytesPerSecond / 1e4) / 100}MB per second`;\n this._logVerbose(\n `received ${prettyMessageMB} transition in ${prettyTransitionTime} at ${prettyBytesPerSecond}`\n );\n if (messageLength > 2e7) {\n this.logger.log(\n `received query results totaling more that 20MB (${prettyMessageMB}) which will take a long time to download on slower connections`\n );\n } else if (transitionTransitTime > 2e4) {\n this.logger.log(\n `received query results totaling ${prettyMessageMB} which took more than 20s to arrive (${prettyTransitionTime})`\n );\n }\n if (this.debug) {\n this.sendMessage({\n type: \"Event\",\n eventType: \"ClientReceivedTransition\",\n event: { transitionTransitTime, messageLength }\n });\n }\n }\n}\n//# sourceMappingURL=web_socket_manager.js.map\n","\"use strict\";\nexport function newSessionId() {\n return uuidv4();\n}\nfunction uuidv4() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0, v = c === \"x\" ? r : r & 3 | 8;\n return v.toString(16);\n });\n}\n//# sourceMappingURL=session.js.map\n","\"use strict\";\nexport class InvalidTokenError extends Error {\n}\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\nfunction b64DecodeUnicode(str) {\n return decodeURIComponent(\n atob(str).replace(/(.)/g, (_m, p) => {\n let code = p.charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = \"0\" + code;\n }\n return \"%\" + code;\n })\n );\n}\nfunction base64UrlDecode(str) {\n let output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw new Error(\"base64 string is not of the correct length\");\n }\n try {\n return b64DecodeUnicode(output);\n } catch {\n return atob(output);\n }\n}\nexport function jwtDecode(token, options) {\n if (typeof token !== \"string\") {\n throw new InvalidTokenError(\"Invalid token specified: must be a string\");\n }\n options || (options = {});\n const pos = options.header === true ? 0 : 1;\n const part = token.split(\".\")[pos];\n if (typeof part !== \"string\") {\n throw new InvalidTokenError(\n `Invalid token specified: missing part #${pos + 1}`\n );\n }\n let decoded;\n try {\n decoded = base64UrlDecode(part);\n } catch (e) {\n throw new InvalidTokenError(\n `Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`\n );\n }\n try {\n return JSON.parse(decoded);\n } catch (e) {\n throw new InvalidTokenError(\n `Invalid token specified: invalid json for part #${pos + 1} (${e.message})`\n );\n }\n}\n//# sourceMappingURL=index.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { jwtDecode } from \"../../vendor/jwt-decode/index.js\";\nconst MAXIMUM_REFRESH_DELAY = 20 * 24 * 60 * 60 * 1e3;\nconst MAX_TOKEN_CONFIRMATION_ATTEMPTS = 2;\nexport class AuthenticationManager {\n constructor(syncState, callbacks, config) {\n __publicField(this, \"authState\", { state: \"noAuth\" });\n // Used to detect races involving `setConfig` calls\n // while a token is being fetched.\n __publicField(this, \"configVersion\", 0);\n // Shared by the BaseClient so that the auth manager can easily inspect it\n __publicField(this, \"syncState\");\n // Passed down by BaseClient, sends a message to the server\n __publicField(this, \"authenticate\");\n __publicField(this, \"stopSocket\");\n __publicField(this, \"tryRestartSocket\");\n __publicField(this, \"pauseSocket\");\n __publicField(this, \"resumeSocket\");\n // Passed down by BaseClient, sends a message to the server\n __publicField(this, \"clearAuth\");\n __publicField(this, \"logger\");\n __publicField(this, \"refreshTokenLeewaySeconds\");\n // Number of times we have attempted to confirm the latest token. We retry up\n // to `MAX_TOKEN_CONFIRMATION_ATTEMPTS` times.\n __publicField(this, \"tokenConfirmationAttempts\", 0);\n this.syncState = syncState;\n this.authenticate = callbacks.authenticate;\n this.stopSocket = callbacks.stopSocket;\n this.tryRestartSocket = callbacks.tryRestartSocket;\n this.pauseSocket = callbacks.pauseSocket;\n this.resumeSocket = callbacks.resumeSocket;\n this.clearAuth = callbacks.clearAuth;\n this.logger = config.logger;\n this.refreshTokenLeewaySeconds = config.refreshTokenLeewaySeconds;\n }\n async setConfig(fetchToken, onChange) {\n this.resetAuthState();\n this._logVerbose(\"pausing WS for auth token fetch\");\n this.pauseSocket();\n const token = await this.fetchTokenAndGuardAgainstRace(fetchToken, {\n forceRefreshToken: false\n });\n if (token.isFromOutdatedConfig) {\n return;\n }\n if (token.value) {\n this.setAuthState({\n state: \"waitingForServerConfirmationOfCachedToken\",\n config: { fetchToken, onAuthChange: onChange },\n hasRetried: false\n });\n this.authenticate(token.value);\n } else {\n this.setAuthState({\n state: \"initialRefetch\",\n config: { fetchToken, onAuthChange: onChange }\n });\n await this.refetchToken();\n }\n this._logVerbose(\"resuming WS after auth token fetch\");\n this.resumeSocket();\n }\n onTransition(serverMessage) {\n if (!this.syncState.isCurrentOrNewerAuthVersion(\n serverMessage.endVersion.identity\n )) {\n return;\n }\n if (serverMessage.endVersion.identity <= serverMessage.startVersion.identity) {\n return;\n }\n this._logVerbose(\n `auth state is ${this.authState.state} when handling transition`\n );\n this.syncState.markAuthCompletion();\n if (this.authState.state === \"waitingForServerConfirmationOfCachedToken\") {\n this._logVerbose(\"server confirmed auth token is valid\");\n void this.refetchToken();\n this.authState.config.onAuthChange(true);\n return;\n }\n if (this.authState.state === \"waitingForServerConfirmationOfFreshToken\") {\n this._logVerbose(\"server confirmed new auth token is valid\");\n this.scheduleTokenRefetch(this.authState.token);\n this.tokenConfirmationAttempts = 0;\n if (!this.authState.hadAuth) {\n this.authState.config.onAuthChange(true);\n }\n }\n }\n onAuthError(serverMessage) {\n if (serverMessage.authUpdateAttempted === false && (this.authState.state === \"waitingForServerConfirmationOfFreshToken\" || this.authState.state === \"waitingForServerConfirmationOfCachedToken\")) {\n this._logVerbose(\"ignoring non-auth token expired error\");\n return;\n }\n const { baseVersion } = serverMessage;\n if (!this.syncState.isCurrentOrNewerAuthVersion(baseVersion + 1)) {\n this._logVerbose(\"ignoring auth error for previous auth attempt\");\n return;\n }\n void this.tryToReauthenticate(serverMessage);\n return;\n }\n // This is similar to `refetchToken` defined below, in fact we\n // don't represent them as different states, but it is different\n // in that we pause the WebSocket so that mutations\n // don't retry with bad auth.\n async tryToReauthenticate(serverMessage) {\n this._logVerbose(`attempting to reauthenticate: ${serverMessage.error}`);\n if (\n // No way to fetch another token, kaboom\n this.authState.state === \"noAuth\" || // We failed on a fresh token. After a small number of retries, we give up\n // and clear the auth state to avoid infinite retries.\n this.authState.state === \"waitingForServerConfirmationOfFreshToken\" && this.tokenConfirmationAttempts >= MAX_TOKEN_CONFIRMATION_ATTEMPTS\n ) {\n this.logger.error(\n `Failed to authenticate: \"${serverMessage.error}\", check your server auth config`\n );\n if (this.syncState.hasAuth()) {\n this.syncState.clearAuth();\n }\n if (this.authState.state !== \"noAuth\") {\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n return;\n }\n if (this.authState.state === \"waitingForServerConfirmationOfFreshToken\") {\n this.tokenConfirmationAttempts++;\n this._logVerbose(\n `retrying reauthentication, ${MAX_TOKEN_CONFIRMATION_ATTEMPTS - this.tokenConfirmationAttempts} attempts remaining`\n );\n }\n await this.stopSocket();\n const token = await this.fetchTokenAndGuardAgainstRace(\n this.authState.config.fetchToken,\n {\n forceRefreshToken: true\n }\n );\n if (token.isFromOutdatedConfig) {\n return;\n }\n if (token.value && this.syncState.isNewAuth(token.value)) {\n this.authenticate(token.value);\n this.setAuthState({\n state: \"waitingForServerConfirmationOfFreshToken\",\n config: this.authState.config,\n token: token.value,\n hadAuth: this.authState.state === \"notRefetching\" || this.authState.state === \"waitingForScheduledRefetch\"\n });\n } else {\n this._logVerbose(\"reauthentication failed, could not fetch a new token\");\n if (this.syncState.hasAuth()) {\n this.syncState.clearAuth();\n }\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n this.tryRestartSocket();\n }\n // Force refetch the token and schedule another refetch\n // before the token expires - an active client should never\n // need to reauthenticate.\n async refetchToken() {\n if (this.authState.state === \"noAuth\") {\n return;\n }\n this._logVerbose(\"refetching auth token\");\n const token = await this.fetchTokenAndGuardAgainstRace(\n this.authState.config.fetchToken,\n {\n forceRefreshToken: true\n }\n );\n if (token.isFromOutdatedConfig) {\n return;\n }\n if (token.value) {\n if (this.syncState.isNewAuth(token.value)) {\n this.setAuthState({\n state: \"waitingForServerConfirmationOfFreshToken\",\n hadAuth: this.syncState.hasAuth(),\n token: token.value,\n config: this.authState.config\n });\n this.authenticate(token.value);\n } else {\n this.setAuthState({\n state: \"notRefetching\",\n config: this.authState.config\n });\n }\n } else {\n this._logVerbose(\"refetching token failed\");\n if (this.syncState.hasAuth()) {\n this.clearAuth();\n }\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n this._logVerbose(\n \"restarting WS after auth token fetch (if currently stopped)\"\n );\n this.tryRestartSocket();\n }\n scheduleTokenRefetch(token) {\n if (this.authState.state === \"noAuth\") {\n return;\n }\n const decodedToken = this.decodeToken(token);\n if (!decodedToken) {\n this.logger.error(\n \"Auth token is not a valid JWT, cannot refetch the token\"\n );\n return;\n }\n const { iat, exp } = decodedToken;\n if (!iat || !exp) {\n this.logger.error(\n \"Auth token does not have required fields, cannot refetch the token\"\n );\n return;\n }\n const tokenValiditySeconds = exp - iat;\n if (tokenValiditySeconds <= 2) {\n this.logger.error(\n \"Auth token does not live long enough, cannot refetch the token\"\n );\n return;\n }\n let delay = Math.min(\n MAXIMUM_REFRESH_DELAY,\n (tokenValiditySeconds - this.refreshTokenLeewaySeconds) * 1e3\n );\n if (delay <= 0) {\n this.logger.warn(\n `Refetching auth token immediately, configured leeway ${this.refreshTokenLeewaySeconds}s is larger than the token's lifetime ${tokenValiditySeconds}s`\n );\n delay = 0;\n }\n const refetchTokenTimeoutId = setTimeout(() => {\n this._logVerbose(\"running scheduled token refetch\");\n void this.refetchToken();\n }, delay);\n this.setAuthState({\n state: \"waitingForScheduledRefetch\",\n refetchTokenTimeoutId,\n config: this.authState.config\n });\n this._logVerbose(\n `scheduled preemptive auth token refetching in ${delay}ms`\n );\n }\n // Protects against simultaneous calls to `setConfig`\n // while we're fetching a token\n async fetchTokenAndGuardAgainstRace(fetchToken, fetchArgs) {\n const originalConfigVersion = ++this.configVersion;\n this._logVerbose(\n `fetching token with config version ${originalConfigVersion}`\n );\n const token = await fetchToken(fetchArgs);\n if (this.configVersion !== originalConfigVersion) {\n this._logVerbose(\n `stale config version, expected ${originalConfigVersion}, got ${this.configVersion}`\n );\n return { isFromOutdatedConfig: true };\n }\n return { isFromOutdatedConfig: false, value: token };\n }\n stop() {\n this.resetAuthState();\n this.configVersion++;\n this._logVerbose(`config version bumped to ${this.configVersion}`);\n }\n setAndReportAuthFailed(onAuthChange) {\n onAuthChange(false);\n this.resetAuthState();\n }\n resetAuthState() {\n this.setAuthState({ state: \"noAuth\" });\n }\n setAuthState(newAuth) {\n const authStateForLog = newAuth.state === \"waitingForServerConfirmationOfFreshToken\" ? {\n hadAuth: newAuth.hadAuth,\n state: newAuth.state,\n token: `...${newAuth.token.slice(-7)}`\n } : { state: newAuth.state };\n this._logVerbose(\n `setting auth state to ${JSON.stringify(authStateForLog)}`\n );\n switch (newAuth.state) {\n case \"waitingForScheduledRefetch\":\n case \"notRefetching\":\n case \"noAuth\":\n this.tokenConfirmationAttempts = 0;\n break;\n case \"waitingForServerConfirmationOfFreshToken\":\n case \"waitingForServerConfirmationOfCachedToken\":\n case \"initialRefetch\":\n break;\n default: {\n newAuth;\n }\n }\n if (this.authState.state === \"waitingForScheduledRefetch\") {\n clearTimeout(this.authState.refetchTokenTimeoutId);\n }\n this.authState = newAuth;\n }\n decodeToken(token) {\n try {\n return jwtDecode(token);\n } catch (e) {\n this._logVerbose(\n `Error decoding token: ${e instanceof Error ? e.message : \"Unknown error\"}`\n );\n return null;\n }\n }\n _logVerbose(message) {\n this.logger.logVerbose(`${message} [v${this.configVersion}]`);\n }\n}\n//# sourceMappingURL=authentication_manager.js.map\n","\"use strict\";\nconst markNames = [\n \"convexClientConstructed\",\n \"convexWebSocketOpen\",\n \"convexFirstMessageReceived\"\n];\nexport function mark(name, sessionId) {\n const detail = { sessionId };\n if (typeof performance === \"undefined\" || !performance.mark) return;\n performance.mark(name, { detail });\n}\nfunction performanceMarkToJson(mark2) {\n let name = mark2.name.slice(\"convex\".length);\n name = name.charAt(0).toLowerCase() + name.slice(1);\n return {\n name,\n startTime: mark2.startTime\n };\n}\nexport function getMarksReport(sessionId) {\n if (typeof performance === \"undefined\" || !performance.getEntriesByName) {\n return [];\n }\n const allMarks = [];\n for (const name of markNames) {\n const marks = performance.getEntriesByName(name).filter((entry) => entry.entryType === \"mark\").filter((mark2) => mark2.detail.sessionId === sessionId);\n allMarks.push(...marks);\n }\n return allMarks.map(performanceMarkToJson);\n}\n//# sourceMappingURL=metrics.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { version } from \"../../index.js\";\nimport { convexToJson } from \"../../values/index.js\";\nimport {\n createHybridErrorStacktrace,\n forwardData,\n instantiateDefaultLogger,\n instantiateNoopLogger,\n logFatalError\n} from \"../logging.js\";\nimport { LocalSyncState } from \"./local_state.js\";\nimport { RequestManager } from \"./request_manager.js\";\nimport {\n OptimisticQueryResults\n} from \"./optimistic_updates_impl.js\";\nimport { RemoteQuerySet } from \"./remote_query_set.js\";\nimport { serializePathAndArgs } from \"./udf_path_utils.js\";\nimport { WebSocketManager } from \"./web_socket_manager.js\";\nimport { newSessionId } from \"./session.js\";\nimport {\n AuthenticationManager\n} from \"./authentication_manager.js\";\nimport { getMarksReport, mark } from \"./metrics.js\";\nimport { parseArgs, validateDeploymentUrl } from \"../../common/index.js\";\nimport { ConvexError } from \"../../values/errors.js\";\nimport { jwtDecode } from \"../../vendor/jwt-decode/index.js\";\nexport class BaseConvexClient {\n /**\n * @param address - The url of your Convex deployment, often provided\n * by an environment variable. E.g. `https://small-mouse-123.convex.cloud`.\n * @param onTransition - A callback receiving an array of query tokens\n * corresponding to query results that have changed -- additional handlers\n * can be added via `addOnTransitionHandler`.\n * @param options - See {@link BaseConvexClientOptions} for a full description.\n */\n constructor(address, onTransition, options) {\n __publicField(this, \"address\");\n __publicField(this, \"state\");\n __publicField(this, \"requestManager\");\n __publicField(this, \"webSocketManager\");\n __publicField(this, \"authenticationManager\");\n __publicField(this, \"remoteQuerySet\");\n __publicField(this, \"optimisticQueryResults\");\n __publicField(this, \"_transitionHandlerCounter\", 0);\n __publicField(this, \"_nextRequestId\");\n __publicField(this, \"_onTransitionFns\", /* @__PURE__ */ new Map());\n __publicField(this, \"_sessionId\");\n __publicField(this, \"firstMessageReceived\", false);\n __publicField(this, \"debug\");\n __publicField(this, \"logger\");\n __publicField(this, \"maxObservedTimestamp\");\n __publicField(this, \"connectionStateSubscribers\", /* @__PURE__ */ new Map());\n __publicField(this, \"nextConnectionStateSubscriberId\", 0);\n __publicField(this, \"_lastPublishedConnectionState\");\n /**\n * Call this whenever the connection state may have changed in a way that could\n * require publishing it. Schedules a possibly update.\n */\n __publicField(this, \"markConnectionStateDirty\", () => {\n void Promise.resolve().then(() => {\n const curConnectionState = this.connectionState();\n if (JSON.stringify(curConnectionState) !== JSON.stringify(this._lastPublishedConnectionState)) {\n this._lastPublishedConnectionState = curConnectionState;\n for (const cb of this.connectionStateSubscribers.values()) {\n cb(curConnectionState);\n }\n }\n });\n });\n // Instance property so that `mark()` doesn't need to be called as a method.\n __publicField(this, \"mark\", (name) => {\n if (this.debug) {\n mark(name, this.sessionId);\n }\n });\n if (typeof address === \"object\") {\n throw new Error(\n \"Passing a ClientConfig object is no longer supported. Pass the URL of the Convex deployment as a string directly.\"\n );\n }\n if (options?.skipConvexDeploymentUrlCheck !== true) {\n validateDeploymentUrl(address);\n }\n options = { ...options };\n const authRefreshTokenLeewaySeconds = options.authRefreshTokenLeewaySeconds ?? 10;\n let webSocketConstructor = options.webSocketConstructor;\n if (!webSocketConstructor && typeof WebSocket === \"undefined\") {\n throw new Error(\n \"No WebSocket global variable defined! To use Convex in an environment without WebSocket try the HTTP client: https://docs.convex.dev/api/classes/browser.ConvexHttpClient\"\n );\n }\n webSocketConstructor = webSocketConstructor || WebSocket;\n this.debug = options.reportDebugInfoToConvex ?? false;\n this.address = address;\n this.logger = options.logger === false ? instantiateNoopLogger({ verbose: options.verbose ?? false }) : options.logger !== true && options.logger ? options.logger : instantiateDefaultLogger({ verbose: options.verbose ?? false });\n const i = address.search(\"://\");\n if (i === -1) {\n throw new Error(\"Provided address was not an absolute URL.\");\n }\n const origin = address.substring(i + 3);\n const protocol = address.substring(0, i);\n let wsProtocol;\n if (protocol === \"http\") {\n wsProtocol = \"ws\";\n } else if (protocol === \"https\") {\n wsProtocol = \"wss\";\n } else {\n throw new Error(`Unknown parent protocol ${protocol}`);\n }\n const wsUri = `${wsProtocol}://${origin}/api/${version}/sync`;\n this.state = new LocalSyncState();\n this.remoteQuerySet = new RemoteQuerySet(\n (queryId) => this.state.queryPath(queryId),\n this.logger\n );\n this.requestManager = new RequestManager(\n this.logger,\n this.markConnectionStateDirty\n );\n const pauseSocket = () => {\n this.webSocketManager.pause();\n this.state.pause();\n };\n this.authenticationManager = new AuthenticationManager(\n this.state,\n {\n authenticate: (token) => {\n const message = this.state.setAuth(token);\n this.webSocketManager.sendMessage(message);\n return message.baseVersion;\n },\n stopSocket: () => this.webSocketManager.stop(),\n tryRestartSocket: () => this.webSocketManager.tryRestart(),\n pauseSocket,\n resumeSocket: () => this.webSocketManager.resume(),\n clearAuth: () => {\n this.clearAuth();\n }\n },\n {\n logger: this.logger,\n refreshTokenLeewaySeconds: authRefreshTokenLeewaySeconds\n }\n );\n this.optimisticQueryResults = new OptimisticQueryResults();\n this.addOnTransitionHandler((transition) => {\n onTransition(transition.queries.map((q) => q.token));\n });\n this._nextRequestId = 0;\n this._sessionId = newSessionId();\n const { unsavedChangesWarning } = options;\n if (typeof window === \"undefined\" || typeof window.addEventListener === \"undefined\") {\n if (unsavedChangesWarning === true) {\n throw new Error(\n \"unsavedChangesWarning requested, but window.addEventListener not found! Remove {unsavedChangesWarning: true} from Convex client options.\"\n );\n }\n } else if (unsavedChangesWarning !== false) {\n window.addEventListener(\"beforeunload\", (e) => {\n if (this.requestManager.hasIncompleteRequests()) {\n e.preventDefault();\n const confirmationMessage = \"Are you sure you want to leave? Your changes may not be saved.\";\n (e || window.event).returnValue = confirmationMessage;\n return confirmationMessage;\n }\n });\n }\n this.webSocketManager = new WebSocketManager(\n wsUri,\n {\n onOpen: (reconnectMetadata) => {\n this.mark(\"convexWebSocketOpen\");\n this.webSocketManager.sendMessage({\n ...reconnectMetadata,\n type: \"Connect\",\n sessionId: this._sessionId,\n maxObservedTimestamp: this.maxObservedTimestamp\n });\n this.remoteQuerySet = new RemoteQuerySet(\n (queryId) => this.state.queryPath(queryId),\n this.logger\n );\n const [querySetModification, authModification] = this.state.restart();\n if (authModification) {\n this.webSocketManager.sendMessage(authModification);\n }\n this.webSocketManager.sendMessage(querySetModification);\n for (const message of this.requestManager.restart()) {\n this.webSocketManager.sendMessage(message);\n }\n },\n onResume: () => {\n const [querySetModification, authModification] = this.state.resume();\n if (authModification) {\n this.webSocketManager.sendMessage(authModification);\n }\n if (querySetModification) {\n this.webSocketManager.sendMessage(querySetModification);\n }\n for (const message of this.requestManager.resume()) {\n this.webSocketManager.sendMessage(message);\n }\n },\n onMessage: (serverMessage) => {\n if (!this.firstMessageReceived) {\n this.firstMessageReceived = true;\n this.mark(\"convexFirstMessageReceived\");\n this.reportMarks();\n }\n switch (serverMessage.type) {\n case \"Transition\": {\n this.observedTimestamp(serverMessage.endVersion.ts);\n this.authenticationManager.onTransition(serverMessage);\n this.remoteQuerySet.transition(serverMessage);\n this.state.transition(serverMessage);\n const completedRequests = this.requestManager.removeCompleted(\n this.remoteQuerySet.timestamp()\n );\n this.notifyOnQueryResultChanges(completedRequests);\n break;\n }\n case \"MutationResponse\": {\n if (serverMessage.success) {\n this.observedTimestamp(serverMessage.ts);\n }\n const completedMutationInfo = this.requestManager.onResponse(serverMessage);\n if (completedMutationInfo !== null) {\n this.notifyOnQueryResultChanges(\n /* @__PURE__ */ new Map([\n [\n completedMutationInfo.requestId,\n completedMutationInfo.result\n ]\n ])\n );\n }\n break;\n }\n case \"ActionResponse\": {\n this.requestManager.onResponse(serverMessage);\n break;\n }\n case \"AuthError\": {\n this.authenticationManager.onAuthError(serverMessage);\n break;\n }\n case \"FatalError\": {\n const error = logFatalError(this.logger, serverMessage.error);\n void this.webSocketManager.terminate();\n throw error;\n }\n default: {\n serverMessage;\n }\n }\n return {\n hasSyncedPastLastReconnect: this.hasSyncedPastLastReconnect()\n };\n },\n onServerDisconnectError: options.onServerDisconnectError\n },\n webSocketConstructor,\n this.logger,\n this.markConnectionStateDirty,\n this.debug\n );\n this.mark(\"convexClientConstructed\");\n if (options.expectAuth) {\n pauseSocket();\n }\n }\n /**\n * Return true if there is outstanding work from prior to the time of the most recent restart.\n * This indicates that the client has not proven itself to have gotten past the issue that\n * potentially led to the restart. Use this to influence when to reset backoff after a failure.\n */\n hasSyncedPastLastReconnect() {\n const hasSyncedPastLastReconnect = this.requestManager.hasSyncedPastLastReconnect() && this.state.hasSyncedPastLastReconnect();\n return hasSyncedPastLastReconnect;\n }\n observedTimestamp(observedTs) {\n if (this.maxObservedTimestamp === void 0 || this.maxObservedTimestamp.lessThanOrEqual(observedTs)) {\n this.maxObservedTimestamp = observedTs;\n }\n }\n getMaxObservedTimestamp() {\n return this.maxObservedTimestamp;\n }\n /**\n * Compute the current query results based on the remoteQuerySet and the\n * current optimistic updates and call `onTransition` for all the changed\n * queries.\n *\n * @param completedMutations - A set of mutation IDs whose optimistic updates\n * are no longer needed.\n */\n notifyOnQueryResultChanges(completedRequests) {\n const remoteQueryResults = this.remoteQuerySet.remoteQueryResults();\n const queryTokenToValue = /* @__PURE__ */ new Map();\n for (const [queryId, result] of remoteQueryResults) {\n const queryToken = this.state.queryToken(queryId);\n if (queryToken !== null) {\n const query = {\n result,\n udfPath: this.state.queryPath(queryId),\n args: this.state.queryArgs(queryId)\n };\n queryTokenToValue.set(queryToken, query);\n }\n }\n const changedQueryTokens = this.optimisticQueryResults.ingestQueryResultsFromServer(\n queryTokenToValue,\n new Set(completedRequests.keys())\n );\n this.handleTransition({\n queries: changedQueryTokens.map((token) => {\n const optimisticResult = this.optimisticQueryResults.rawQueryResult(token);\n return {\n token,\n modification: {\n kind: \"Updated\",\n result: optimisticResult\n }\n };\n }),\n reflectedMutations: Array.from(completedRequests).map(\n ([requestId, result]) => ({\n requestId,\n result\n })\n ),\n timestamp: this.remoteQuerySet.timestamp()\n });\n }\n handleTransition(transition) {\n for (const fn of this._onTransitionFns.values()) {\n fn(transition);\n }\n }\n /**\n * Add a handler that will be called on a transition.\n *\n * Any external side effects (e.g. setting React state) should be handled here.\n *\n * @param fn\n *\n * @returns\n */\n addOnTransitionHandler(fn) {\n const id = this._transitionHandlerCounter++;\n this._onTransitionFns.set(id, fn);\n return () => this._onTransitionFns.delete(id);\n }\n /**\n * Get the current JWT auth token and decoded claims.\n */\n getCurrentAuthClaims() {\n const authToken = this.state.getAuth();\n let decoded = {};\n if (authToken && authToken.tokenType === \"User\") {\n try {\n decoded = authToken ? jwtDecode(authToken.value) : {};\n } catch {\n decoded = {};\n }\n } else {\n return void 0;\n }\n return { token: authToken.value, decoded };\n }\n /**\n * Set the authentication token to be used for subsequent queries and mutations.\n * `fetchToken` will be called automatically again if a token expires.\n * `fetchToken` should return `null` if the token cannot be retrieved, for example\n * when the user's rights were permanently revoked.\n * @param fetchToken - an async function returning the JWT-encoded OpenID Connect Identity Token\n * @param onChange - a callback that will be called when the authentication status changes\n */\n setAuth(fetchToken, onChange) {\n void this.authenticationManager.setConfig(fetchToken, onChange);\n }\n hasAuth() {\n return this.state.hasAuth();\n }\n /** @internal */\n setAdminAuth(value, fakeUserIdentity) {\n const message = this.state.setAdminAuth(value, fakeUserIdentity);\n this.webSocketManager.sendMessage(message);\n }\n clearAuth() {\n const message = this.state.clearAuth();\n this.webSocketManager.sendMessage(message);\n }\n /**\n * Subscribe to a query function.\n *\n * Whenever this query's result changes, the `onTransition` callback\n * passed into the constructor will be called.\n *\n * @param name - The name of the query.\n * @param args - An arguments object for the query. If this is omitted, the\n * arguments will be `{}`.\n * @param options - A {@link SubscribeOptions} options object for this query.\n \n * @returns An object containing a {@link QueryToken} corresponding to this\n * query and an `unsubscribe` callback.\n */\n subscribe(name, args, options) {\n const argsObject = parseArgs(args);\n const { modification, queryToken, unsubscribe } = this.state.subscribe(\n name,\n argsObject,\n options?.journal,\n options?.componentPath\n );\n if (modification !== null) {\n this.webSocketManager.sendMessage(modification);\n }\n return {\n queryToken,\n unsubscribe: () => {\n const modification2 = unsubscribe();\n if (modification2) {\n this.webSocketManager.sendMessage(modification2);\n }\n }\n };\n }\n /**\n * A query result based only on the current, local state.\n *\n * The only way this will return a value is if we're already subscribed to the\n * query or its value has been set optimistically.\n */\n localQueryResult(udfPath, args) {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(udfPath, argsObject);\n return this.optimisticQueryResults.queryResult(queryToken);\n }\n /**\n * Get query result by query token based on current, local state\n *\n * The only way this will return a value is if we're already subscribed to the\n * query or its value has been set optimistically.\n *\n * @internal\n */\n localQueryResultByToken(queryToken) {\n return this.optimisticQueryResults.queryResult(queryToken);\n }\n /**\n * Whether local query result is available for a token.\n *\n * This method does not throw if the result is an error.\n *\n * @internal\n */\n hasLocalQueryResultByToken(queryToken) {\n return this.optimisticQueryResults.hasQueryResult(queryToken);\n }\n /**\n * @internal\n */\n localQueryLogs(udfPath, args) {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(udfPath, argsObject);\n return this.optimisticQueryResults.queryLogs(queryToken);\n }\n /**\n * Retrieve the current {@link QueryJournal} for this query function.\n *\n * If we have not yet received a result for this query, this will be `undefined`.\n *\n * @param name - The name of the query.\n * @param args - The arguments object for this query.\n * @returns The query's {@link QueryJournal} or `undefined`.\n */\n queryJournal(name, args) {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(name, argsObject);\n return this.state.queryJournal(queryToken);\n }\n /**\n * Get the current {@link ConnectionState} between the client and the Convex\n * backend.\n *\n * @returns The {@link ConnectionState} with the Convex backend.\n */\n connectionState() {\n const wsConnectionState = this.webSocketManager.connectionState();\n return {\n hasInflightRequests: this.requestManager.hasInflightRequests(),\n isWebSocketConnected: wsConnectionState.isConnected,\n hasEverConnected: wsConnectionState.hasEverConnected,\n connectionCount: wsConnectionState.connectionCount,\n connectionRetries: wsConnectionState.connectionRetries,\n timeOfOldestInflightRequest: this.requestManager.timeOfOldestInflightRequest(),\n inflightMutations: this.requestManager.inflightMutations(),\n inflightActions: this.requestManager.inflightActions()\n };\n }\n /**\n * Subscribe to the {@link ConnectionState} between the client and the Convex\n * backend, calling a callback each time it changes.\n *\n * Subscribed callbacks will be called when any part of ConnectionState changes.\n * ConnectionState may grow in future versions (e.g. to provide a array of\n * inflight requests) in which case callbacks would be called more frequently.\n *\n * @returns An unsubscribe function to stop listening.\n */\n subscribeToConnectionState(cb) {\n const id = this.nextConnectionStateSubscriberId++;\n this.connectionStateSubscribers.set(id, cb);\n return () => {\n this.connectionStateSubscribers.delete(id);\n };\n }\n /**\n * Execute a mutation function.\n *\n * @param name - The name of the mutation.\n * @param args - An arguments object for the mutation. If this is omitted,\n * the arguments will be `{}`.\n * @param options - A {@link MutationOptions} options object for this mutation.\n \n * @returns - A promise of the mutation's result.\n */\n async mutation(name, args, options) {\n const result = await this.mutationInternal(name, args, options);\n if (!result.success) {\n if (result.errorData !== void 0) {\n throw forwardData(\n result,\n new ConvexError(\n createHybridErrorStacktrace(\"mutation\", name, result)\n )\n );\n }\n throw new Error(createHybridErrorStacktrace(\"mutation\", name, result));\n }\n return result.value;\n }\n /**\n * @internal\n */\n async mutationInternal(udfPath, args, options, componentPath) {\n const { mutationPromise } = this.enqueueMutation(\n udfPath,\n args,\n options,\n componentPath\n );\n return mutationPromise;\n }\n /**\n * @internal\n */\n enqueueMutation(udfPath, args, options, componentPath) {\n const mutationArgs = parseArgs(args);\n this.tryReportLongDisconnect();\n const requestId = this.nextRequestId;\n this._nextRequestId++;\n if (options !== void 0) {\n const optimisticUpdate = options.optimisticUpdate;\n if (optimisticUpdate !== void 0) {\n const wrappedUpdate = (localQueryStore) => {\n const result = optimisticUpdate(\n localQueryStore,\n mutationArgs\n );\n if (result instanceof Promise) {\n this.logger.warn(\n \"Optimistic update handler returned a Promise. Optimistic updates should be synchronous.\"\n );\n }\n };\n const changedQueryTokens = this.optimisticQueryResults.applyOptimisticUpdate(\n wrappedUpdate,\n requestId\n );\n const changedQueries = changedQueryTokens.map((token) => {\n const localResult = this.localQueryResultByToken(token);\n return {\n token,\n modification: {\n kind: \"Updated\",\n result: localResult === void 0 ? void 0 : {\n success: true,\n value: localResult,\n logLines: []\n }\n }\n };\n });\n this.handleTransition({\n queries: changedQueries,\n reflectedMutations: [],\n timestamp: this.remoteQuerySet.timestamp()\n });\n }\n }\n const message = {\n type: \"Mutation\",\n requestId,\n udfPath,\n componentPath,\n args: [convexToJson(mutationArgs)]\n };\n const mightBeSent = this.webSocketManager.sendMessage(message);\n const mutationPromise = this.requestManager.request(message, mightBeSent);\n return {\n requestId,\n mutationPromise\n };\n }\n /**\n * Execute an action function.\n *\n * @param name - The name of the action.\n * @param args - An arguments object for the action. If this is omitted,\n * the arguments will be `{}`.\n * @returns A promise of the action's result.\n */\n async action(name, args) {\n const result = await this.actionInternal(name, args);\n if (!result.success) {\n if (result.errorData !== void 0) {\n throw forwardData(\n result,\n new ConvexError(createHybridErrorStacktrace(\"action\", name, result))\n );\n }\n throw new Error(createHybridErrorStacktrace(\"action\", name, result));\n }\n return result.value;\n }\n /**\n * @internal\n */\n async actionInternal(udfPath, args, componentPath) {\n const actionArgs = parseArgs(args);\n const requestId = this.nextRequestId;\n this._nextRequestId++;\n this.tryReportLongDisconnect();\n const message = {\n type: \"Action\",\n requestId,\n udfPath,\n componentPath,\n args: [convexToJson(actionArgs)]\n };\n const mightBeSent = this.webSocketManager.sendMessage(message);\n return this.requestManager.request(message, mightBeSent);\n }\n /**\n * Close any network handles associated with this client and stop all subscriptions.\n *\n * Call this method when you're done with an {@link BaseConvexClient} to\n * dispose of its sockets and resources.\n *\n * @returns A `Promise` fulfilled when the connection has been completely closed.\n */\n async close() {\n this.authenticationManager.stop();\n return this.webSocketManager.terminate();\n }\n /**\n * Return the address for this client, useful for creating a new client.\n *\n * Not guaranteed to match the address with which this client was constructed:\n * it may be canonicalized.\n */\n get url() {\n return this.address;\n }\n /**\n * @internal\n */\n get nextRequestId() {\n return this._nextRequestId;\n }\n /**\n * @internal\n */\n get sessionId() {\n return this._sessionId;\n }\n /**\n * Reports performance marks to the server. This should only be called when\n * we have a functional websocket.\n */\n reportMarks() {\n if (this.debug) {\n const report = getMarksReport(this.sessionId);\n this.webSocketManager.sendMessage({\n type: \"Event\",\n eventType: \"ClientConnect\",\n event: report\n });\n }\n }\n tryReportLongDisconnect() {\n if (!this.debug) {\n return;\n }\n const timeOfOldestRequest = this.connectionState().timeOfOldestInflightRequest;\n if (timeOfOldestRequest === null || Date.now() - timeOfOldestRequest.getTime() <= 60 * 1e3) {\n return;\n }\n const endpoint = `${this.address}/api/debug_event`;\n fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`\n },\n body: JSON.stringify({ event: \"LongWebsocketDisconnect\" })\n }).then((response) => {\n if (!response.ok) {\n this.logger.warn(\n \"Analytics request failed with response:\",\n response.body\n );\n }\n }).catch((error) => {\n this.logger.warn(\"Analytics response failed with error:\", error);\n });\n }\n}\n//# sourceMappingURL=client.js.map\n","\"use strict\";\nexport function asPaginationArgs(value) {\n if (typeof value.paginationOpts.numItems !== \"number\") {\n throw new Error(`Not valid paginated query args: ${JSON.stringify(value)}`);\n }\n return value;\n}\nexport function asPaginationResult(value) {\n if (typeof value !== \"object\" || value === null || !Array.isArray(value.page) || typeof value.isDone !== \"boolean\" || typeof value.continueCursor !== \"string\") {\n throw new Error(`Not a valid paginated query result: ${value?.toString()}`);\n }\n return value;\n}\n//# sourceMappingURL=pagination.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport {\n serializePaginatedPathAndArgs,\n canonicalizeUdfPath\n} from \"./udf_path_utils.js\";\nimport {\n asPaginationResult\n} from \"./pagination.js\";\nimport { Long } from \"../../vendor/long.js\";\nexport class PaginatedQueryClient {\n constructor(client, onTransition) {\n this.client = client;\n this.onTransition = onTransition;\n __publicField(this, \"paginatedQuerySet\", /* @__PURE__ */ new Map());\n // hold onto a real Transition so we can construct synthetic ones with that timestamp\n __publicField(this, \"lastTransitionTs\");\n this.lastTransitionTs = Long.fromNumber(0);\n this.client.addOnTransitionHandler(\n (transition) => this.onBaseTransition(transition)\n );\n }\n /**\n * Subscribe to a paginated query.\n *\n * @param name - The name of the paginated query function\n * @param args - Arguments for the query (excluding paginationOpts)\n * @param options - Pagination options including initialNumItems\n * @returns Object with paginatedQueryToken and unsubscribe function\n */\n subscribe(name, args, options) {\n const canonicalizedUdfPath = canonicalizeUdfPath(name);\n const token = serializePaginatedPathAndArgs(\n canonicalizedUdfPath,\n args,\n options\n );\n const unsubscribe = () => this.removePaginatedQuerySubscriber(token);\n const existingEntry = this.paginatedQuerySet.get(token);\n if (existingEntry) {\n existingEntry.numSubscribers += 1;\n return {\n paginatedQueryToken: token,\n unsubscribe\n };\n }\n this.paginatedQuerySet.set(token, {\n token,\n canonicalizedUdfPath,\n args,\n numSubscribers: 1,\n options: { initialNumItems: options.initialNumItems },\n nextPageKey: 0,\n pageKeys: [],\n pageKeyToQuery: /* @__PURE__ */ new Map(),\n ongoingSplits: /* @__PURE__ */ new Map(),\n skip: false,\n id: options.id\n });\n this.addPageToPaginatedQuery(token, null, options.initialNumItems);\n return {\n paginatedQueryToken: token,\n unsubscribe\n };\n }\n /**\n * Get current results for a paginated query based on local state.\n *\n * Throws an error when one of the pages has errored.\n */\n localQueryResult(name, args, options) {\n const canonicalizedUdfPath = canonicalizeUdfPath(name);\n const token = serializePaginatedPathAndArgs(\n canonicalizedUdfPath,\n args,\n options\n );\n return this.localQueryResultByToken(token);\n }\n /**\n * @internal\n */\n localQueryResultByToken(token) {\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n return void 0;\n }\n const activePages = this.activePageQueryTokens(paginatedQuery);\n if (activePages.length === 0) {\n return {\n results: [],\n status: \"LoadingFirstPage\",\n loadMore: (numItems) => {\n return this.loadMoreOfPaginatedQuery(token, numItems);\n }\n };\n }\n let allResults = [];\n let hasUndefined = false;\n let isDone = false;\n for (const pageToken of activePages) {\n const result = this.client.localQueryResultByToken(pageToken);\n if (result === void 0) {\n hasUndefined = true;\n isDone = false;\n continue;\n }\n const paginationResult = asPaginationResult(result);\n allResults = allResults.concat(paginationResult.page);\n isDone = !!paginationResult.isDone;\n }\n let status;\n if (hasUndefined) {\n status = allResults.length === 0 ? \"LoadingFirstPage\" : \"LoadingMore\";\n } else if (isDone) {\n status = \"Exhausted\";\n } else {\n status = \"CanLoadMore\";\n }\n return {\n results: allResults,\n status,\n loadMore: (numItems) => {\n return this.loadMoreOfPaginatedQuery(token, numItems);\n }\n };\n }\n onBaseTransition(transition) {\n const changedBaseTokens = transition.queries.map((q) => q.token);\n const changed = this.queriesContainingTokens(changedBaseTokens);\n let paginatedQueries = [];\n if (changed.length > 0) {\n this.processPaginatedQuerySplits(\n changed,\n (token) => this.client.localQueryResultByToken(token)\n );\n paginatedQueries = changed.map((token) => ({\n token,\n modification: {\n kind: \"Updated\",\n result: this.localQueryResultByToken(token)\n }\n }));\n }\n const extendedTransition = {\n ...transition,\n paginatedQueries\n };\n this.onTransition(extendedTransition);\n }\n /**\n * Load more items for a paginated query.\n *\n * This *always* causes a transition, the status of the query\n * has probably changed from \"CanLoadMore\" to \"LoadingMore\".\n * Data might have changed too: maybe a subscription to this page\n * query already exists (unlikely but possible) or this page query\n * has an optimistic update providing some initial data.\n *\n * @internal\n */\n loadMoreOfPaginatedQuery(token, numItems) {\n this.mustGetPaginatedQuery(token);\n const lastPageToken = this.queryTokenForLastPageOfPaginatedQuery(token);\n const lastPageResult = this.client.localQueryResultByToken(lastPageToken);\n if (!lastPageResult) {\n return false;\n }\n const paginationResult = asPaginationResult(lastPageResult);\n if (paginationResult.isDone) {\n return false;\n }\n this.addPageToPaginatedQuery(\n token,\n paginationResult.continueCursor,\n numItems\n );\n const loadMoreTransition = {\n timestamp: this.lastTransitionTs,\n reflectedMutations: [],\n queries: [],\n paginatedQueries: [\n {\n token,\n modification: {\n kind: \"Updated\",\n result: this.localQueryResultByToken(token)\n }\n }\n ]\n };\n this.onTransition(loadMoreTransition);\n return true;\n }\n /**\n * @internal\n */\n queriesContainingTokens(queryTokens) {\n if (queryTokens.length === 0) {\n return [];\n }\n const changed = [];\n const queryTokenSet = new Set(queryTokens);\n for (const [paginatedToken, paginatedQuery] of this.paginatedQuerySet) {\n for (const pageToken of this.allQueryTokens(paginatedQuery)) {\n if (queryTokenSet.has(pageToken)) {\n changed.push(paginatedToken);\n break;\n }\n }\n }\n return changed;\n }\n /**\n * @internal\n */\n processPaginatedQuerySplits(changed, getResult) {\n for (const paginatedQueryToken of changed) {\n const paginatedQuery = this.mustGetPaginatedQuery(paginatedQueryToken);\n const { ongoingSplits, pageKeyToQuery, pageKeys } = paginatedQuery;\n for (const [pageKey, [splitKey1, splitKey2]] of ongoingSplits) {\n const bothNewPagesLoaded = getResult(pageKeyToQuery.get(splitKey1).queryToken) !== void 0 && getResult(pageKeyToQuery.get(splitKey2).queryToken) !== void 0;\n if (bothNewPagesLoaded) {\n this.completePaginatedQuerySplit(\n paginatedQuery,\n pageKey,\n splitKey1,\n splitKey2\n );\n }\n }\n for (const pageKey of pageKeys) {\n if (ongoingSplits.has(pageKey)) {\n continue;\n }\n const pageToken = pageKeyToQuery.get(pageKey).queryToken;\n const pageResult = getResult(pageToken);\n if (!pageResult) {\n continue;\n }\n const result = asPaginationResult(pageResult);\n const shouldSplit = result.splitCursor && (result.pageStatus === \"SplitRecommended\" || result.pageStatus === \"SplitRequired\" || // This client-driven page splitting condition will change in the future.\n result.page.length > paginatedQuery.options.initialNumItems * 2);\n if (shouldSplit) {\n this.splitPaginatedQueryPage(\n paginatedQuery,\n pageKey,\n result.splitCursor,\n // we just checked\n result.continueCursor\n );\n }\n }\n }\n }\n splitPaginatedQueryPage(paginatedQuery, pageKey, splitCursor, continueCursor) {\n const splitKey1 = paginatedQuery.nextPageKey++;\n const splitKey2 = paginatedQuery.nextPageKey++;\n const paginationOpts = {\n cursor: continueCursor,\n numItems: paginatedQuery.options.initialNumItems,\n id: paginatedQuery.id\n };\n const firstSubscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n {\n ...paginatedQuery.args,\n paginationOpts: {\n ...paginationOpts,\n cursor: null,\n // Start from beginning for first split\n endCursor: splitCursor\n }\n }\n );\n paginatedQuery.pageKeyToQuery.set(splitKey1, firstSubscription);\n const secondSubscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n {\n ...paginatedQuery.args,\n paginationOpts: {\n ...paginationOpts,\n cursor: splitCursor,\n endCursor: continueCursor\n }\n }\n );\n paginatedQuery.pageKeyToQuery.set(splitKey2, secondSubscription);\n paginatedQuery.ongoingSplits.set(pageKey, [splitKey1, splitKey2]);\n }\n /**\n * @internal\n */\n addPageToPaginatedQuery(token, continueCursor, numItems) {\n const paginatedQuery = this.mustGetPaginatedQuery(token);\n const pageKey = paginatedQuery.nextPageKey++;\n const paginationOpts = {\n cursor: continueCursor,\n numItems,\n id: paginatedQuery.id\n };\n const pageArgs = {\n ...paginatedQuery.args,\n paginationOpts\n };\n const subscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n pageArgs\n );\n paginatedQuery.pageKeys.push(pageKey);\n paginatedQuery.pageKeyToQuery.set(pageKey, subscription);\n return subscription;\n }\n removePaginatedQuerySubscriber(token) {\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n return;\n }\n paginatedQuery.numSubscribers -= 1;\n if (paginatedQuery.numSubscribers > 0) {\n return;\n }\n for (const subscription of paginatedQuery.pageKeyToQuery.values()) {\n subscription.unsubscribe();\n }\n this.paginatedQuerySet.delete(token);\n }\n completePaginatedQuerySplit(paginatedQuery, pageKey, splitKey1, splitKey2) {\n const originalQuery = paginatedQuery.pageKeyToQuery.get(pageKey);\n paginatedQuery.pageKeyToQuery.delete(pageKey);\n const pageIndex = paginatedQuery.pageKeys.indexOf(pageKey);\n paginatedQuery.pageKeys.splice(pageIndex, 1, splitKey1, splitKey2);\n paginatedQuery.ongoingSplits.delete(pageKey);\n originalQuery.unsubscribe();\n }\n /** The query tokens for all active pages, in result order */\n activePageQueryTokens(paginatedQuery) {\n return paginatedQuery.pageKeys.map(\n (pageKey) => paginatedQuery.pageKeyToQuery.get(pageKey).queryToken\n );\n }\n allQueryTokens(paginatedQuery) {\n return Array.from(paginatedQuery.pageKeyToQuery.values()).map(\n (sub) => sub.queryToken\n );\n }\n queryTokenForLastPageOfPaginatedQuery(token) {\n const paginatedQuery = this.mustGetPaginatedQuery(token);\n const lastPageKey = paginatedQuery.pageKeys[paginatedQuery.pageKeys.length - 1];\n if (lastPageKey === void 0) {\n throw new Error(`No pages for paginated query ${token}`);\n }\n return paginatedQuery.pageKeyToQuery.get(lastPageKey).queryToken;\n }\n mustGetPaginatedQuery(token) {\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n throw new Error(\"paginated query no longer exists for token \" + token);\n }\n return paginatedQuery;\n }\n}\n//# sourceMappingURL=paginated_query_client.js.map\n","\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nimport { validateDeploymentUrl } from \"../common/index.js\";\nimport {\n BaseConvexClient\n} from \"./index.js\";\nimport { getFunctionName } from \"../server/api.js\";\nimport {\n PaginatedQueryClient\n} from \"./sync/paginated_query_client.js\";\nimport { serializedQueryTokenIsPaginated } from \"./sync/udf_path_utils.js\";\nlet defaultWebSocketConstructor;\nexport function setDefaultWebSocketConstructor(ws) {\n defaultWebSocketConstructor = ws;\n}\nexport class ConvexClient {\n /**\n * Construct a client and immediately initiate a WebSocket connection to the passed address.\n *\n * @public\n */\n constructor(address, options = {}) {\n __publicField(this, \"listeners\");\n __publicField(this, \"_client\");\n __publicField(this, \"_paginatedClient\");\n // A synthetic server event to run callbacks the first time\n __publicField(this, \"callNewListenersWithCurrentValuesTimer\");\n __publicField(this, \"_closed\");\n __publicField(this, \"_disabled\");\n if (options.skipConvexDeploymentUrlCheck !== true) {\n validateDeploymentUrl(address);\n }\n const { disabled, ...baseOptions } = options;\n this._closed = false;\n this._disabled = !!disabled;\n if (defaultWebSocketConstructor && !(\"webSocketConstructor\" in baseOptions) && typeof WebSocket === \"undefined\") {\n baseOptions.webSocketConstructor = defaultWebSocketConstructor;\n }\n if (typeof window === \"undefined\" && !(\"unsavedChangesWarning\" in baseOptions)) {\n baseOptions.unsavedChangesWarning = false;\n }\n if (!this.disabled) {\n this._client = new BaseConvexClient(\n address,\n () => {\n },\n // NOP, let the paginated query client do it all\n baseOptions\n );\n this._paginatedClient = new PaginatedQueryClient(\n this._client,\n (transition) => this._transition(transition)\n );\n }\n this.listeners = /* @__PURE__ */ new Set();\n }\n /**\n * Once closed no registered callbacks will fire again.\n */\n get closed() {\n return this._closed;\n }\n get client() {\n if (this._client) return this._client;\n throw new Error(\"ConvexClient is disabled\");\n }\n /**\n * @internal\n */\n get paginatedClient() {\n if (this._paginatedClient) return this._paginatedClient;\n throw new Error(\"ConvexClient is disabled\");\n }\n get disabled() {\n return this._disabled;\n }\n /**\n * Call a callback whenever a new result for a query is received. The callback\n * will run soon after being registered if a result for the query is already\n * in memory.\n *\n * The return value is an {@link Unsubscribe} object which is both a function\n * an an object with properties. Both of the patterns below work with this object:\n *\n *```ts\n * // call the return value as a function\n * const unsubscribe = client.onUpdate(api.messages.list, {}, (messages) => {\n * console.log(messages);\n * });\n * unsubscribe();\n *\n * // unpack the return value into its properties\n * const {\n * getCurrentValue,\n * unsubscribe,\n * } = client.onUpdate(api.messages.list, {}, (messages) => {\n * console.log(messages);\n * });\n *```\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - The arguments to run the query with.\n * @param callback - Function to call when the query result updates.\n * @param onError - Function to call when the query result updates with an error.\n * If not provided, errors will be thrown instead of calling the callback.\n *\n * @return an {@link Unsubscribe} function to stop calling the onUpdate function.\n */\n onUpdate(query, args, callback, onError) {\n if (this.disabled) {\n return this.createDisabledUnsubscribe();\n }\n const { queryToken, unsubscribe } = this.client.subscribe(\n getFunctionName(query),\n args\n );\n const queryInfo = {\n queryToken,\n callback,\n onError,\n unsubscribe,\n hasEverRun: false,\n query,\n args,\n paginationOptions: void 0\n };\n this.listeners.add(queryInfo);\n if (this.queryResultReady(queryToken) && this.callNewListenersWithCurrentValuesTimer === void 0) {\n this.callNewListenersWithCurrentValuesTimer = setTimeout(\n () => this.callNewListenersWithCurrentValues(),\n 0\n );\n }\n const unsubscribeProps = {\n unsubscribe: () => {\n if (this.closed) {\n return;\n }\n this.listeners.delete(queryInfo);\n unsubscribe();\n },\n getCurrentValue: () => this.client.localQueryResultByToken(queryToken),\n getQueryLogs: () => this.client.localQueryLogs(queryToken)\n };\n const ret = unsubscribeProps.unsubscribe;\n Object.assign(ret, unsubscribeProps);\n return ret;\n }\n /**\n * Call a callback whenever a new result for a paginated query is received.\n *\n * This is an experimental preview: the final API may change.\n * In particular, caching behavior, page splitting, and required paginated query options\n * may change.\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - The arguments to run the query with.\n * @param options - Options for the paginated query including initialNumItems and id.\n * @param callback - Function to call when the query result updates.\n * @param onError - Function to call when the query result updates with an error.\n *\n * @return an {@link Unsubscribe} function to stop calling the callback.\n */\n onPaginatedUpdate_experimental(query, args, options, callback, onError) {\n if (this.disabled) {\n return this.createDisabledUnsubscribe();\n }\n const paginationOptions = {\n initialNumItems: options.initialNumItems,\n id: -1\n };\n const { paginatedQueryToken, unsubscribe } = this.paginatedClient.subscribe(\n getFunctionName(query),\n args,\n // Simple client doesn't use IDs, there's no expectation that these queries remain separate.\n paginationOptions\n );\n const queryInfo = {\n queryToken: paginatedQueryToken,\n callback,\n onError,\n unsubscribe,\n hasEverRun: false,\n query,\n args,\n paginationOptions\n };\n this.listeners.add(queryInfo);\n if (!!this.paginatedClient.localQueryResultByToken(paginatedQueryToken) && this.callNewListenersWithCurrentValuesTimer === void 0) {\n this.callNewListenersWithCurrentValuesTimer = setTimeout(\n () => this.callNewListenersWithCurrentValues(),\n 0\n );\n }\n const unsubscribeProps = {\n unsubscribe: () => {\n if (this.closed) {\n return;\n }\n this.listeners.delete(queryInfo);\n unsubscribe();\n },\n getCurrentValue: () => {\n const result = this.paginatedClient.localQueryResult(\n getFunctionName(query),\n args,\n paginationOptions\n );\n return result;\n },\n getQueryLogs: () => []\n // Paginated queries don't aggregate their logs\n };\n const ret = unsubscribeProps.unsubscribe;\n Object.assign(ret, unsubscribeProps);\n return ret;\n }\n // Run all callbacks that have never been run before if they have a query\n // result available now.\n callNewListenersWithCurrentValues() {\n this.callNewListenersWithCurrentValuesTimer = void 0;\n this._transition({ queries: [], paginatedQueries: [] }, true);\n }\n queryResultReady(queryToken) {\n return this.client.hasLocalQueryResultByToken(queryToken);\n }\n createDisabledUnsubscribe() {\n const disabledUnsubscribe = (() => {\n });\n const unsubscribeProps = {\n unsubscribe: disabledUnsubscribe,\n getCurrentValue: () => void 0,\n getQueryLogs: () => void 0\n };\n Object.assign(disabledUnsubscribe, unsubscribeProps);\n return disabledUnsubscribe;\n }\n async close() {\n if (this.disabled) return;\n this.listeners.clear();\n this._closed = true;\n if (this._paginatedClient) {\n this._paginatedClient = void 0;\n }\n return this.client.close();\n }\n /**\n * Get the current JWT auth token and decoded claims.\n */\n getAuth() {\n if (this.disabled) return;\n return this.client.getCurrentAuthClaims();\n }\n /**\n * Set the authentication token to be used for subsequent queries and mutations.\n * `fetchToken` will be called automatically again if a token expires.\n * `fetchToken` should return `null` if the token cannot be retrieved, for example\n * when the user's rights were permanently revoked.\n * @param fetchToken - an async function returning the JWT (typically an OpenID Connect Identity Token)\n * @param onChange - a callback that will be called when the authentication status changes\n */\n setAuth(fetchToken, onChange) {\n if (this.disabled) return;\n this.client.setAuth(\n fetchToken,\n onChange ?? (() => {\n })\n );\n }\n /**\n * @internal\n */\n setAdminAuth(token, identity) {\n if (this.closed) {\n throw new Error(\"ConvexClient has already been closed.\");\n }\n if (this.disabled) return;\n this.client.setAdminAuth(token, identity);\n }\n /**\n * @internal\n */\n _transition({\n queries,\n paginatedQueries\n }, callNewListeners = false) {\n const updatedQueries = [\n ...queries.map((q) => q.token),\n ...paginatedQueries.map((q) => q.token)\n ];\n for (const queryInfo of this.listeners) {\n const { callback, queryToken, onError, hasEverRun } = queryInfo;\n const isPaginatedQuery = serializedQueryTokenIsPaginated(queryToken);\n const hasResultReady = isPaginatedQuery ? !!this.paginatedClient.localQueryResultByToken(queryToken) : this.client.hasLocalQueryResultByToken(queryToken);\n if (updatedQueries.includes(queryToken) || callNewListeners && !hasEverRun && hasResultReady) {\n queryInfo.hasEverRun = true;\n let newValue;\n try {\n if (isPaginatedQuery) {\n newValue = this.paginatedClient.localQueryResultByToken(queryToken);\n } else {\n newValue = this.client.localQueryResultByToken(queryToken);\n }\n } catch (error) {\n if (!(error instanceof Error)) throw error;\n if (onError) {\n onError(\n error,\n \"Second argument to onUpdate onError is reserved for later use\"\n );\n } else {\n void Promise.reject(error);\n }\n continue;\n }\n callback(\n newValue,\n \"Second argument to onUpdate callback is reserved for later use\"\n );\n }\n }\n }\n /**\n * Execute a mutation function.\n *\n * @param mutation - A {@link server.FunctionReference} for the public mutation\n * to run.\n * @param args - An arguments object for the mutation.\n * @param options - A {@link MutationOptions} options object for the mutation.\n * @returns A promise of the mutation's result.\n */\n async mutation(mutation, args, options) {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return await this.client.mutation(getFunctionName(mutation), args, options);\n }\n /**\n * Execute an action function.\n *\n * @param action - A {@link server.FunctionReference} for the public action\n * to run.\n * @param args - An arguments object for the action.\n * @returns A promise of the action's result.\n */\n async action(action, args) {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return await this.client.action(getFunctionName(action), args);\n }\n /**\n * Fetch a query result once.\n *\n * @param query - A {@link server.FunctionReference} for the public query\n * to run.\n * @param args - An arguments object for the query.\n * @returns A promise of the query's result.\n */\n async query(query, args) {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n const value = this.client.localQueryResult(getFunctionName(query), args);\n if (value !== void 0) return Promise.resolve(value);\n return new Promise((resolve, reject) => {\n const { unsubscribe } = this.onUpdate(\n query,\n args,\n (value2) => {\n unsubscribe();\n resolve(value2);\n },\n (e) => {\n unsubscribe();\n reject(e);\n }\n );\n });\n }\n /**\n * Get the current {@link ConnectionState} between the client and the Convex\n * backend.\n *\n * @returns The {@link ConnectionState} with the Convex backend.\n */\n connectionState() {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return this.client.connectionState();\n }\n /**\n * Subscribe to the {@link ConnectionState} between the client and the Convex\n * backend, calling a callback each time it changes.\n *\n * Subscribed callbacks will be called when any part of ConnectionState changes.\n * ConnectionState may grow in future versions (e.g. to provide a array of\n * inflight requests) in which case callbacks would be called more frequently.\n *\n * @returns An unsubscribe function to stop listening.\n */\n subscribeToConnectionState(cb) {\n if (this.disabled) return () => {\n };\n return this.client.subscribeToConnectionState(cb);\n }\n}\n//# sourceMappingURL=simple_client.js.map\n","/**\n * For clusters of correlated `useState` values, where a union makes invalid\n * combinations unrepresentable and side-effects become one effect per\n * `state.kind` rather than orchestration spread across many.\n *\n * Invalid transitions are silent no-ops, not throws.\n */\n\nimport { useCallback, useRef, useState } from 'preact/hooks'\n\n/**\n * Typed so a handler keyed `'idle'`/`'start'` receives the narrowed variants\n * rather than the full unions. `Partial<>` lets a state omit irrelevant events.\n */\nexport type TransitionMap<S extends { kind: string }, E extends { type: string }> = {\n [K in S['kind']]?: Partial<{\n [T in E['type']]: (state: Extract<S, { kind: K }>, event: Extract<E, { type: T }>) => S\n }>\n}\n\nexport type Send<E extends { type: string }> = (event: E) => void\n\n/** Identity helper; only exists so the literal gets full type inference. */\nexport function defineMachine<S extends { kind: string }, E extends { type: string }>(\n transitions: TransitionMap<S, E>,\n): TransitionMap<S, E> {\n return transitions\n}\n\n/**\n * `send` is stable across renders, so it can sit in dependency arrays. The\n * transition table is held in a ref so each call still sees the freshest\n * closure values — callers can inline `defineMachine(...)` in the render body\n * and reference render-scope values without memoizing.\n */\nexport function useMachine<S extends { kind: string }, E extends { type: string }>(\n transitions: TransitionMap<S, E>,\n // `NoInfer` so a narrow literal here doesn't pin `S` to one variant: `S`\n // comes from the transition table, which carries the full union.\n initial: NoInfer<S> | (() => NoInfer<S>),\n): [S, Send<E>] {\n const transitionsRef = useRef(transitions)\n transitionsRef.current = transitions\n\n const [state, setState] = useState<S>(() =>\n typeof initial === 'function' ? (initial as () => S)() : initial,\n )\n\n const send = useCallback<Send<E>>((event) => {\n setState((current) => {\n const forKind = transitionsRef.current[current.kind as S['kind']]\n const handler = forKind?.[event.type as E['type']] as ((s: S, e: E) => S) | undefined\n return handler ? handler(current, event) : current\n })\n }, [])\n\n return [state, send]\n}\n","/**\n * Duplicates `convex/lib/mentions.ts` because a server module and a browser\n * bundle can't import each other. Keep them in lockstep.\n *\n * The `@[Display Name](userId)` marker is a transport detail never shown to a\n * human. Renderers MUST promote one to a chip only when its userId appears in\n * the comment's validated `mentions` array; otherwise it renders `@Name`.\n */\nconst MENTION_MARKER_REGEX = /@\\[([^\\]\\n]+)\\]\\(([^)\\s]+)\\)/g\n\nexport type MentionToken =\n | { type: 'text'; value: string }\n | { type: 'mention'; userId: string; name: string }\n\nexport function parseMentionTokens(body: string): MentionToken[] {\n const tokens: MentionToken[] = []\n let lastIndex = 0\n const re = new RegExp(MENTION_MARKER_REGEX.source, 'g')\n for (let m = re.exec(body); m !== null; m = re.exec(body)) {\n if (m.index > lastIndex) {\n tokens.push({ type: 'text', value: body.slice(lastIndex, m.index) })\n }\n tokens.push({ type: 'mention', name: m[1] ?? '', userId: m[2] ?? '' })\n lastIndex = m.index + m[0].length\n }\n if (lastIndex < body.length) {\n tokens.push({ type: 'text', value: body.slice(lastIndex) })\n }\n return tokens\n}\n\nexport function extractMentionUserIds(body: string): string[] {\n const seen = new Set<string>()\n const out: string[] = []\n const re = new RegExp(MENTION_MARKER_REGEX.source, 'g')\n for (let m = re.exec(body); m !== null; m = re.exec(body)) {\n const id = m[2]\n if (id && !seen.has(id)) {\n seen.add(id)\n out.push(id)\n }\n }\n return out\n}\n\n/** `null` means no `@`-trigger is active. */\nexport type MentionTriggerState = {\n /** Index in the value where the `@` lives. */\n at: number\n /** Caret position when the trigger was last computed. */\n caret: number\n /** The query string after the `@` (may be empty). */\n query: string\n}\n\nexport function detectMentionTrigger(value: string, caret: number): MentionTriggerState | null {\n for (let i = caret - 1; i >= 0; i--) {\n const ch = value[i]\n if (ch === '@') {\n const prev = i === 0 ? undefined : value[i - 1]\n const isBoundary = prev === undefined || /\\s/.test(prev)\n if (!isBoundary) return null\n const query = value.slice(i + 1, caret)\n if (/\\s/.test(query)) return null\n return { at: i, caret, query }\n }\n if (ch === undefined) return null\n if (/[\\s\\]()]/.test(ch)) return null\n }\n return null\n}\n\n/**\n * The display name is sanitised because a `]` or newline would terminate the\n * marker early and leave half of it as literal text.\n *\n * `null` when the userId itself can't be encoded. No real id contains\n * whitespace or `)`; the guard makes a malformed one degrade to \"no mention\"\n * rather than corrupt the body around it.\n */\nexport function mentionMarkerFor(member: { userId: string; name: string }): string | null {\n if (!member.userId || /[)\\s]/.test(member.userId)) return null\n const name = member.name.replace(/[\\]\\r\\n]+/g, ' ').trim()\n if (!name) return null\n return `@[${name}](${member.userId})`\n}\n\n/** For surfaces that can only take a string — titles, `aria-label`s. */\nexport function renderMentionsAsPlainText(body: string): string {\n return body.replace(\n new RegExp(MENTION_MARKER_REGEX.source, 'g'),\n (_m, name: string) => `@${name}`,\n )\n}\n","/**\n * Modeled on TanStack Query's `useMutation`, with the state union making\n * pending+error and error+success unrepresentable. Re-entrant calls while\n * pending are dropped, which subsumes the per-handler `if (busy) return`.\n *\n * **Unlike `useMutation`, the function is passed per call to `run`** rather\n * than bound at setup. One popover surfaces one `pending` + `error` at a time,\n * so binding at the hook would force an instance per handler plus an\n * aggregator; per-call binding keeps the shared instance and still gives each\n * invocation its own callbacks.\n *\n * Deliberately omitted: `retry` (the widget's retry loops own their timing),\n * `mutate` vs `mutateAsync` (not awaiting `run` is already fire-and-forget),\n * and `onMutate` rollback (Convex subscriptions are the authoritative cache,\n * so nothing here optimistic-updates).\n */\n\nimport { useCallback, useRef } from 'preact/hooks'\n\nimport { defineMachine, useMachine } from './machine'\n\nexport type AsyncActionState<T> =\n | { kind: 'idle' }\n | { kind: 'pending' }\n | { kind: 'success'; data: T }\n | { kind: 'error'; message: string }\n\ntype AsyncActionEvent =\n | { type: 'start' }\n | { type: 'success'; data: unknown }\n | { type: 'failure'; message: string }\n | { type: 'reset' }\n\n// `unknown` so one machine instance backs any per-hook `T`. The transitions\n// only shuttle `data` through, never read it, so the cast at the hook\n// boundary is sound.\nconst machine = defineMachine<AsyncActionState<unknown>, AsyncActionEvent>({\n idle: {\n start: () => ({ kind: 'pending' }),\n },\n pending: {\n success: (_, e) => ({ kind: 'success', data: e.data }),\n failure: (_, e) => ({ kind: 'error', message: e.message }),\n },\n success: {\n // Drops the previous data, matching `useMutation`.\n start: () => ({ kind: 'pending' }),\n reset: () => ({ kind: 'idle' }),\n },\n error: {\n start: () => ({ kind: 'pending' }),\n reset: () => ({ kind: 'idle' }),\n },\n})\n\nexport interface RunOptions<T> {\n /** For a parent that must react to failure, e.g. keeping a form open. */\n rethrow?: boolean\n /** Fires after the success transition, with the resolved value. */\n onSuccess?: (data: T) => void\n /** Fires after the failure transition, with the surfaced message. */\n onError?: (message: string) => void\n /** Fires after either branch — equivalent to a `finally`. */\n onSettled?: () => void\n}\n\nexport interface UseAsyncActionResult<T> {\n state: AsyncActionState<T>\n isIdle: boolean\n isPending: boolean\n isSuccess: boolean\n isError: boolean\n /** Resolved value of the most recent successful run, else `undefined`. */\n data: T | undefined\n /** Message from the most recent failure, else `undefined`. */\n error: string | undefined\n /**\n * `undefined` covers two different outcomes: `fn` threw without `rethrow`,\n * or the call was a re-entrant no-op while already pending.\n */\n run: (fn: () => Promise<T>, options?: RunOptions<T>) => Promise<T | undefined>\n /** Force back to `idle`, dropping any data or error message. */\n reset: () => void\n}\n\nexport function useAsyncAction<T = unknown>(): UseAsyncActionResult<T> {\n const [stateAny, send] = useMachine(machine, { kind: 'idle' })\n const state = stateAny as AsyncActionState<T>\n\n // Through a ref, so a re-entrant call in the same render cycle is caught\n // before the machine state reaches the closure.\n const stateRef = useRef(state)\n stateRef.current = state\n\n const run = useCallback(\n async (fn: () => Promise<T>, options?: RunOptions<T>) => {\n if (stateRef.current.kind === 'pending') return undefined\n send({ type: 'start' })\n try {\n const result = await fn()\n send({ type: 'success', data: result })\n options?.onSuccess?.(result)\n options?.onSettled?.()\n return result\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Action failed'\n send({ type: 'failure', message })\n options?.onError?.(message)\n options?.onSettled?.()\n if (options?.rethrow) throw err\n return undefined\n }\n },\n [send],\n )\n\n const reset = useCallback(() => send({ type: 'reset' }), [send])\n\n return {\n state,\n isIdle: state.kind === 'idle',\n isPending: state.kind === 'pending',\n isSuccess: state.kind === 'success',\n isError: state.kind === 'error',\n data: state.kind === 'success' ? state.data : undefined,\n error: state.kind === 'error' ? state.message : undefined,\n run,\n reset,\n }\n}\n","// License: MIT\n// Author: Anton Medvedev <anton@medv.io>\n// Source: https://github.com/antonmedv/finder\nconst acceptedAttrNames = new Set(['role', 'name', 'aria-label', 'rel', 'href']);\n/** Check if attribute name and value are word-like. */\nexport function attr(name, value) {\n let nameIsOk = acceptedAttrNames.has(name);\n nameIsOk ||= name.startsWith('data-') && wordLike(name);\n let valueIsOk = wordLike(value) && value.length < 100;\n valueIsOk ||= value.startsWith('#') && wordLike(value.slice(1));\n return nameIsOk && valueIsOk;\n}\n/** Check if id name is word-like. */\nexport function idName(name) {\n return wordLike(name);\n}\n/** Check if class name is word-like. */\nexport function className(name) {\n return wordLike(name);\n}\n/** Check if tag name is word-like. */\nexport function tagName(name) {\n return true;\n}\n/** Finds unique CSS selectors for the given element. */\nexport function finder(input, options) {\n if (input.nodeType !== Node.ELEMENT_NODE) {\n throw new Error(`Can't generate CSS selector for non-element node type.`);\n }\n if (input.tagName.toLowerCase() === 'html') {\n return 'html';\n }\n const defaults = {\n root: document.body,\n idName: idName,\n className: className,\n tagName: tagName,\n attr: attr,\n timeoutMs: 1000,\n seedMinLength: 3,\n optimizedMinLength: 2,\n maxNumberOfPathChecks: Infinity,\n };\n const startTime = new Date();\n const config = { ...defaults, ...options };\n const rootDocument = findRootDocument(config.root, defaults);\n let foundPath;\n let count = 0;\n for (const candidate of search(input, config, rootDocument)) {\n const elapsedTimeMs = new Date().getTime() - startTime.getTime();\n if (elapsedTimeMs > config.timeoutMs ||\n count >= config.maxNumberOfPathChecks) {\n const fPath = fallback(input, rootDocument);\n if (!fPath) {\n throw new Error(`Timeout: Can't find a unique selector after ${config.timeoutMs}ms`);\n }\n return selector(fPath);\n }\n count++;\n if (unique(candidate, rootDocument)) {\n foundPath = candidate;\n break;\n }\n }\n if (!foundPath) {\n throw new Error(`Selector was not found.`);\n }\n const optimized = [\n ...optimize(foundPath, input, config, rootDocument, startTime),\n ];\n optimized.sort(byPenalty);\n if (optimized.length > 0) {\n return selector(optimized[0]);\n }\n return selector(foundPath);\n}\nfunction* search(input, config, rootDocument) {\n const stack = [];\n let paths = [];\n let current = input;\n let i = 0;\n while (current && current !== rootDocument) {\n const level = tie(current, config);\n for (const node of level) {\n node.level = i;\n }\n stack.push(level);\n current = current.parentElement;\n i++;\n paths.push(...combinations(stack));\n if (i >= config.seedMinLength) {\n paths.sort(byPenalty);\n for (const candidate of paths) {\n yield candidate;\n }\n paths = [];\n }\n }\n paths.sort(byPenalty);\n for (const candidate of paths) {\n yield candidate;\n }\n}\nfunction wordLike(name) {\n if (/^[a-z\\-]{3,}$/i.test(name)) {\n const words = name.split(/-|[A-Z]/);\n for (const word of words) {\n if (word.length <= 2) {\n return false;\n }\n if (/[^aeiou]{4,}/i.test(word)) {\n return false;\n }\n }\n return true;\n }\n return false;\n}\nfunction tie(element, config) {\n const level = [];\n const elementId = element.getAttribute('id');\n if (elementId && config.idName(elementId)) {\n level.push({\n name: '#' + CSS.escape(elementId),\n penalty: 0,\n });\n }\n for (let i = 0; i < element.classList.length; i++) {\n const name = element.classList[i];\n if (config.className(name)) {\n level.push({\n name: '.' + CSS.escape(name),\n penalty: 1,\n });\n }\n }\n for (let i = 0; i < element.attributes.length; i++) {\n const attr = element.attributes[i];\n if (config.attr(attr.name, attr.value)) {\n level.push({\n name: `[${CSS.escape(attr.name)}=\"${CSS.escape(attr.value)}\"]`,\n penalty: 2,\n });\n }\n }\n const tagName = element.tagName.toLowerCase();\n if (config.tagName(tagName)) {\n level.push({\n name: tagName,\n penalty: 5,\n });\n const index = indexOf(element, tagName);\n if (index !== undefined) {\n level.push({\n name: nthOfType(tagName, index),\n penalty: 10,\n });\n }\n }\n const nth = indexOf(element);\n if (nth !== undefined) {\n level.push({\n name: nthChild(tagName, nth),\n penalty: 50,\n });\n }\n return level;\n}\nfunction selector(path) {\n let node = path[0];\n let query = node.name;\n for (let i = 1; i < path.length; i++) {\n const level = path[i].level || 0;\n if (node.level === level - 1) {\n query = `${path[i].name} > ${query}`;\n }\n else {\n query = `${path[i].name} ${query}`;\n }\n node = path[i];\n }\n return query;\n}\nfunction penalty(path) {\n return path.map((node) => node.penalty).reduce((acc, i) => acc + i, 0);\n}\nfunction byPenalty(a, b) {\n return penalty(a) - penalty(b);\n}\nfunction indexOf(input, tagName) {\n const parent = input.parentNode;\n if (!parent) {\n return undefined;\n }\n let child = parent.firstChild;\n if (!child) {\n return undefined;\n }\n let i = 0;\n while (child) {\n if (child.nodeType === Node.ELEMENT_NODE &&\n (tagName === undefined ||\n child.tagName.toLowerCase() === tagName)) {\n i++;\n }\n if (child === input) {\n break;\n }\n child = child.nextSibling;\n }\n return i;\n}\nfunction fallback(input, rootDocument) {\n let i = 0;\n let current = input;\n const path = [];\n while (current && current !== rootDocument) {\n const tagName = current.tagName.toLowerCase();\n const index = indexOf(current, tagName);\n if (index === undefined) {\n return;\n }\n path.push({\n name: nthOfType(tagName, index),\n penalty: NaN,\n level: i,\n });\n current = current.parentElement;\n i++;\n }\n if (unique(path, rootDocument)) {\n return path;\n }\n}\nfunction nthChild(tagName, index) {\n if (tagName === 'html') {\n return 'html';\n }\n return `${tagName}:nth-child(${index})`;\n}\nfunction nthOfType(tagName, index) {\n if (tagName === 'html') {\n return 'html';\n }\n return `${tagName}:nth-of-type(${index})`;\n}\nfunction* combinations(stack, path = []) {\n if (stack.length > 0) {\n for (let node of stack[0]) {\n yield* combinations(stack.slice(1, stack.length), path.concat(node));\n }\n }\n else {\n yield path;\n }\n}\nfunction findRootDocument(rootNode, defaults) {\n if (rootNode.nodeType === Node.DOCUMENT_NODE) {\n return rootNode;\n }\n if (rootNode === defaults.root) {\n return rootNode.ownerDocument;\n }\n return rootNode;\n}\nfunction unique(path, rootDocument) {\n const css = selector(path);\n switch (rootDocument.querySelectorAll(css).length) {\n case 0:\n throw new Error(`Can't select any node with this selector: ${css}`);\n case 1:\n return true;\n default:\n return false;\n }\n}\nfunction* optimize(path, input, config, rootDocument, startTime) {\n if (path.length > 2 && path.length > config.optimizedMinLength) {\n for (let i = 1; i < path.length - 1; i++) {\n const elapsedTimeMs = new Date().getTime() - startTime.getTime();\n if (elapsedTimeMs > config.timeoutMs) {\n return;\n }\n const newPath = [...path];\n newPath.splice(i, 1);\n if (unique(newPath, rootDocument) &&\n rootDocument.querySelector(selector(newPath)) === input) {\n yield newPath;\n yield* optimize(newPath, input, config, rootDocument, startTime);\n }\n }\n }\n}\n","/**\n * Pins store 0..1 fractions of the page's content size plus a viewport\n * snapshot, which re-renders them roughly in place across responsive layouts.\n * The CSS selector captured alongside is what allows an exact re-anchor after\n * a reflow.\n */\n\nimport { finder } from '@medv/finder'\n\nexport type PageCoords = {\n /** Fraction 0..1 of document.documentElement.scrollWidth */\n anchorX: number\n /** Fraction 0..1 of document.documentElement.scrollHeight */\n anchorY: number\n viewportW: number\n viewportY: number\n anchorSelector?: string\n /** Fraction 0..1 of the anchored element's width at click point */\n anchorOffsetX?: number\n /** Fraction 0..1 of the anchored element's height at click point */\n anchorOffsetY?: number\n}\n\nexport type ScreenPoint = {\n /** Pixel position relative to the document (page coords, includes scroll) */\n pageX: number\n pageY: number\n /**\n * `false` means these are fraction-fallback coords, so the caller should\n * render a tentative cue and retry after DOM mutations.\n */\n resolved: boolean\n /** Held so callers can notice via `isConnected` that an anchor was lost. */\n element: Element | null\n}\n\n/** Pass `target` when an overlay is intercepting the click. */\nexport function toPageCoords(event: MouseEvent, target?: Element | null): PageCoords {\n const docEl = document.documentElement\n const docW = Math.max(docEl.scrollWidth, docEl.clientWidth)\n const docH = Math.max(docEl.scrollHeight, docEl.clientHeight)\n\n const pageX = event.clientX + window.scrollX\n const pageY = event.clientY + window.scrollY\n\n const resolvedTarget =\n target !== undefined ? target : event.target instanceof Element ? event.target : null\n const selector = resolvedTarget ? elementSelector(resolvedTarget) : undefined\n\n let anchorOffsetX: number | undefined\n let anchorOffsetY: number | undefined\n if (resolvedTarget) {\n const rect = resolvedTarget.getBoundingClientRect()\n if (rect.width > 0 && rect.height > 0) {\n anchorOffsetX = Math.max(0, Math.min(1, (event.clientX - rect.left) / rect.width))\n anchorOffsetY = Math.max(0, Math.min(1, (event.clientY - rect.top) / rect.height))\n }\n }\n\n return {\n anchorX: docW > 0 ? pageX / docW : 0,\n anchorY: docH > 0 ? pageY / docH : 0,\n viewportW: window.innerWidth,\n viewportY: window.innerHeight,\n anchorSelector: selector,\n anchorOffsetX,\n anchorOffsetY,\n }\n}\n\n/** Falls back to fraction × current document size when the selector misses. */\nexport function resolveCoords(c: {\n anchorX: number\n anchorY: number\n anchorSelector?: string\n anchorOffsetX?: number\n anchorOffsetY?: number\n}): ScreenPoint {\n if (c.anchorSelector) {\n try {\n const el = document.querySelector(c.anchorSelector)\n // A matched-but-unrendered element reports an all-zero rect, and\n // anchoring to it parks the pin in the page's top-left corner as if\n // that were real. Treated as a miss instead.\n const rect = el?.getBoundingClientRect()\n if (el && rect && isRendered(rect)) {\n return {\n pageX: rect.left + window.scrollX + (c.anchorOffsetX ?? 0.5) * rect.width,\n pageY: rect.top + window.scrollY + (c.anchorOffsetY ?? 0.5) * rect.height,\n resolved: true,\n element: el,\n }\n }\n } catch {\n // bad selector — fall through to fraction math\n }\n }\n\n const docEl = document.documentElement\n const docW = Math.max(docEl.scrollWidth, docEl.clientWidth)\n const docH = Math.max(docEl.scrollHeight, docEl.clientHeight)\n return {\n pageX: c.anchorX * docW,\n pageY: c.anchorY * docH,\n resolved: false,\n element: null,\n }\n}\n\n/**\n * Only the degenerate all-zero rect counts as unrendered: a zero-width but\n * positioned element still has a meaningful location.\n */\nfunction isRendered(rect: DOMRect): boolean {\n return rect.width !== 0 || rect.height !== 0 || rect.top !== 0 || rect.left !== 0\n}\n\nfunction elementSelector(el: Element): string | undefined {\n try {\n return finder(el, { timeoutMs: 1000 })\n } catch {\n return undefined\n }\n}\n","/** Raises a typed error on any non-2xx, so the UI has one failure path. */\n\nexport type WidgetThread = {\n _id: string\n url: string\n route: string\n anchorSelector?: string\n anchorX: number\n anchorY: number\n anchorOffsetX?: number\n anchorOffsetY?: number\n viewportW: number\n viewportY: number\n authorName: string\n authorClientId: string\n createdAt: number\n resolvedAt?: number\n screenshotUrl?: string\n comments: Array<{\n _id: string\n body: string\n /**\n * Server-validated: a non-member or a tombstone filters to `[]`. Renderers\n * promote a `@[Name](id)` marker to a chip only when its id is in here.\n */\n mentions: string[]\n authorName: string\n /**\n * Renderers MUST fall back to initials both when this is absent and when\n * the image fails to load: it's a third-party URL a host page's CSP is\n * free to block.\n */\n authorImage?: string\n /** Widget identity that authored this comment (undefined for dashboard replies). */\n authorClientId?: string\n fromDashboard: boolean\n createdAt: number\n editedAt?: number\n /**\n * The comment carries the delegating person's name, so without the badge\n * this renders a visitor no way to tell a machine answered them.\n */\n authoredVia?: 'mcp'\n /** True for soft-deleted comments; `body` is blanked server-side. */\n deleted: boolean\n /**\n * Sorted server-side by the fixed palette order so chips stay stable. An\n * optimistic toggle MUST update `count` and `mine` together. The viewer's\n * own entry is missing from `reactors` — the client re-inserts \"you\".\n */\n reactions: Array<{ emoji: string; count: number; mine: boolean; reactors: string[] }>\n }>\n}\n\nexport type CreateThreadPayload = {\n url: string\n route: string\n anchorSelector?: string\n anchorX: number\n anchorY: number\n anchorOffsetX?: number\n anchorOffsetY?: number\n viewportW: number\n viewportY: number\n userAgent: string\n authorName: string\n authorEmail?: string\n body: string\n /** Optional. Server re-validates each id against `projectMembers`. */\n mentions?: string[]\n screenshotStorageId?: string\n}\n\nexport type AddCommentPayload = {\n body: string\n authorName: string\n authorEmail?: string\n /** Optional. Server re-validates each id against `projectMembers`. */\n mentions?: string[]\n}\n\nexport type EditCommentPayload = {\n body: string\n /** Optional. Server re-validates each id against `projectMembers`. */\n mentions?: string[]\n}\n\nexport type WidgetMember = { userId: string; name: string }\n\n/** Only verified users see these; anonymous visitors get 401. */\nexport type WidgetNotification = {\n _id: string\n type: 'mention'\n createdAt: number\n readAt?: number\n actorName: string\n /**\n * The row is attributed to the delegating person, so this is the only thing\n * distinguishing it from their own reply.\n */\n actorVia?: 'mcp'\n threadId: string\n commentId: string\n /** Navigated to when the thread lives on another route. */\n threadUrl: string\n commentExcerpt: string\n threadTitle: string\n}\n\nexport class WidgetApiError extends Error {\n status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'WidgetApiError'\n this.status = status\n }\n}\n\n/**\n * Distinct from `WidgetApiError` so the UI can tell a slow network from a\n * server error. `status` is `0` because no response arrived, matching fetch's\n * own behaviour for AbortErrors.\n */\nexport class WidgetTimeoutError extends WidgetApiError {\n /** For log/Sentry filtering. */\n category: 'read' | 'write' | 'upload'\n constructor(operation: string, category: 'read' | 'write' | 'upload') {\n super(`${operation} took too long, so check your connection`, 0)\n this.name = 'WidgetTimeoutError'\n this.category = category\n }\n}\n\n/**\n * Without these, a blackholing corporate proxy or dead DNS leaves the UI\n * pending forever. Deliberately generous — a phone on degraded 4G should still\n * finish a write — because a too-tight bound generates its own support tickets.\n */\nexport const READ_TIMEOUT_MS = 15_000\nexport const WRITE_TIMEOUT_MS = 30_000\n\n/** Optional per-call overrides. */\nexport interface WidgetApiRequestOptions {\n /** Composed with the per-method timeout, so either source can cancel. */\n signal?: AbortSignal\n}\n\n/**\n * `AbortSignal.any` rather than hand-rolled listeners, because it forwards the\n * specific reason (`TimeoutError` vs `AbortError`) into the rejection, which is\n * what lets `request` tell \"timed out\" from \"caller cancelled\".\n *\n * Exported for the fetches that legitimately sit outside `request()` — the auth\n * handshake and the background token refresh — so they get a deadline without\n * hand-rolling one. The `widget-fetch-timeouts` test keeps that list honest.\n */\nexport function combinedSignal(timeoutMs: number, callerSignal?: AbortSignal): AbortSignal {\n const timeoutSignal = AbortSignal.timeout(timeoutMs)\n return callerSignal ? AbortSignal.any([callerSignal, timeoutSignal]) : timeoutSignal\n}\n\nexport type WidgetApiClient = ReturnType<typeof createApiClient>\n\nexport interface CreateApiClientOpts {\n apiUrl: string\n apiKey: string\n /**\n * Called per request so the client always sees the freshest token without\n * being recreated. Client-side expiry is a shortcut only — the server 401s\n * anything stale that slips through.\n */\n getToken?: () => { token: string; expiresAt: number } | null\n /**\n * Sent as `x-markup-anon-token`. The server trusts the embedded clientId for\n * ownership checks because it verified the signature — this is what replaces\n * trusting a clientId from the request body.\n */\n getAnonToken?: () => string | null\n /**\n * Only for 401s on a request that carried a Bearer. A 401 without one means\n * the api key itself is bad, which is not recoverable by re-minting.\n */\n onUnauthorized?: () => void\n /**\n * `'cookies'` switches the client to `credentials: 'include'` so the browser\n * attaches the HttpOnly access cookie; `getToken` already returns null there.\n */\n getStorageMode?: () => 'cookies' | 'localStorage' | null\n}\n\nexport function createApiClient(opts: CreateApiClientOpts) {\n const baseUrl = opts.apiUrl.replace(/\\/+$/, '')\n\n async function request<T>(\n path: string,\n init: RequestInit,\n reqOpts: {\n timeoutMs: number\n category: 'read' | 'write'\n operation: string\n signal?: AbortSignal\n },\n ): Promise<T> {\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n 'x-markup-api-key': opts.apiKey,\n ...((init.headers ?? {}) as Record<string, string>),\n }\n\n const cached = opts.getToken?.() ?? null\n const sentBearer = cached != null && cached.token.length > 0 && cached.expiresAt > Date.now()\n if (sentBearer && cached) {\n headers['authorization'] = `Bearer ${cached.token}`\n }\n\n const anon = opts.getAnonToken?.() ?? null\n if (anon) {\n headers['x-markup-anon-token'] = anon\n }\n\n // No Authorization header and no anon token in this mode — the HttpOnly\n // cookie the browser attaches is what carries auth.\n const useCookies = opts.getStorageMode?.() === 'cookies'\n const fetchInit: RequestInit = {\n ...init,\n headers,\n signal: combinedSignal(reqOpts.timeoutMs, reqOpts.signal),\n }\n if (useCookies) {\n fetchInit.credentials = 'include'\n }\n\n let res: Response\n try {\n res = await fetch(`${baseUrl}${path}`, fetchInit)\n } catch (err) {\n // A fired deadline arrives as `TimeoutError`, a caller abort as\n // `AbortError`. Only the first becomes a typed error — the second is the\n // caller's own intent and propagates unchanged.\n if (err instanceof DOMException && err.name === 'TimeoutError') {\n throw new WidgetTimeoutError(reqOpts.operation, reqOpts.category)\n }\n throw err\n }\n\n const text = await res.text()\n const data = text ? safeJson(text) : null\n if (!res.ok) {\n // Either a stale Bearer, or a cookie that was revoked or not attached\n // because the partition disappeared.\n if (res.status === 401 && (sentBearer || useCookies)) {\n opts.onUnauthorized?.()\n }\n const message =\n (data && typeof data === 'object' && 'error' in data && typeof data.error === 'string'\n ? data.error\n : null) ?? `Request failed with ${res.status}`\n throw new WidgetApiError(message, res.status)\n }\n return data as T\n }\n\n return {\n mintAnonIdentity(\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ clientId: string; token: string; expiresAt: number }> {\n return request<{ clientId: string; token: string; expiresAt: number }>(\n '/widget/anon-identity',\n { method: 'POST' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'mint-anon-identity',\n signal: reqOpts?.signal,\n },\n )\n },\n getSubscriptionToken(\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ token: string; expiresAt: number }> {\n return request<{ token: string; expiresAt: number }>(\n '/widget/subscription-token',\n { method: 'POST' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'mint-subscription-token',\n signal: reqOpts?.signal,\n },\n )\n },\n getScreenshotUploadUrl(reqOpts?: WidgetApiRequestOptions): Promise<{ uploadUrl: string }> {\n return request<{ uploadUrl: string }>(\n '/widget/screenshots/upload-url',\n { method: 'POST' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'mint-screenshot-upload-url',\n signal: reqOpts?.signal,\n },\n )\n },\n listThreads(\n route: string,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ threads: WidgetThread[] }> {\n return request<{ threads: WidgetThread[] }>(\n `/widget/threads?route=${encodeURIComponent(route)}`,\n { method: 'GET' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'list-threads',\n signal: reqOpts?.signal,\n },\n )\n },\n listMembers(reqOpts?: WidgetApiRequestOptions): Promise<{ members: WidgetMember[] }> {\n return request<{ members: WidgetMember[] }>(\n `/widget/members`,\n { method: 'GET' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'list-members',\n signal: reqOpts?.signal,\n },\n )\n },\n listNotifications(\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ notifications: WidgetNotification[] }> {\n return request<{ notifications: WidgetNotification[] }>(\n `/widget/notifications`,\n { method: 'GET' },\n {\n timeoutMs: READ_TIMEOUT_MS,\n category: 'read',\n operation: 'list-notifications',\n signal: reqOpts?.signal,\n },\n )\n },\n markNotificationRead(notificationId: string, reqOpts?: WidgetApiRequestOptions): Promise<void> {\n return request<void>(\n `/widget/notifications/${encodeURIComponent(notificationId)}/read`,\n { method: 'POST' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'mark-notification-read',\n signal: reqOpts?.signal,\n },\n )\n },\n markAllNotificationsRead(reqOpts?: WidgetApiRequestOptions): Promise<void> {\n return request<void>(\n `/widget/notifications/read-all`,\n { method: 'POST' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'mark-all-notifications-read',\n signal: reqOpts?.signal,\n },\n )\n },\n createThread(\n payload: CreateThreadPayload,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ thread: WidgetThread }> {\n return request<{ thread: WidgetThread }>(\n `/widget/threads`,\n { method: 'POST', body: JSON.stringify(payload) },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'create-thread',\n signal: reqOpts?.signal,\n },\n )\n },\n deleteThread(threadId: string, reqOpts?: WidgetApiRequestOptions): Promise<void> {\n return request<void>(\n `/widget/threads/${encodeURIComponent(threadId)}`,\n { method: 'DELETE' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'delete-thread',\n signal: reqOpts?.signal,\n },\n )\n },\n resolveThread(\n threadId: string,\n resolvedBy?: string,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<void> {\n return request<void>(\n `/widget/threads/${encodeURIComponent(threadId)}`,\n { method: 'PATCH', body: JSON.stringify({ resolvedBy }) },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'resolve-thread',\n signal: reqOpts?.signal,\n },\n )\n },\n addComment(\n threadId: string,\n payload: AddCommentPayload,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ thread: WidgetThread }> {\n return request<{ thread: WidgetThread }>(\n `/widget/threads/${encodeURIComponent(threadId)}/comments`,\n { method: 'POST', body: JSON.stringify(payload) },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'add-comment',\n signal: reqOpts?.signal,\n },\n )\n },\n editComment(\n threadId: string,\n commentId: string,\n payload: EditCommentPayload,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ thread: WidgetThread }> {\n return request<{ thread: WidgetThread }>(\n `/widget/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(commentId)}`,\n { method: 'PATCH', body: JSON.stringify(payload) },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'edit-comment',\n signal: reqOpts?.signal,\n },\n )\n },\n deleteComment(\n threadId: string,\n commentId: string,\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ thread: WidgetThread }> {\n return request<{ thread: WidgetThread }>(\n `/widget/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(commentId)}`,\n { method: 'DELETE' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'delete-comment',\n signal: reqOpts?.signal,\n },\n )\n },\n toggleReaction(\n commentId: string,\n payload: { emoji: string; authorName?: string },\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ thread: WidgetThread }> {\n return request<{ thread: WidgetThread }>(\n `/widget/comments/${encodeURIComponent(commentId)}/reactions`,\n { method: 'POST', body: JSON.stringify(payload) },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'toggle-reaction',\n signal: reqOpts?.signal,\n },\n )\n },\n /**\n * Authenticated off the `x-markup-anon-token` JWT, so no body is required.\n * Verified Bearers are 403'd — that erasure is a dashboard flow.\n */\n forgetMe(reqOpts?: WidgetApiRequestOptions): Promise<void> {\n return request<void>(\n '/widget/forget-me',\n { method: 'POST' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'forget-me',\n signal: reqOpts?.signal,\n },\n )\n },\n /**\n * Anon callers get 401: nothing ties an anon JWT into the issuance and\n * revocation tables, so their path is the local-only forget-me instead.\n * The counts are diagnostics — the UI transitions on any non-error reply.\n */\n signOut(\n reqOpts?: WidgetApiRequestOptions,\n ): Promise<{ revoked: number; refreshTokensRevoked: number }> {\n return request<{ revoked: number; refreshTokensRevoked: number }>(\n '/widget/sign-out',\n { method: 'POST' },\n {\n timeoutMs: WRITE_TIMEOUT_MS,\n category: 'write',\n operation: 'sign-out',\n signal: reqOpts?.signal,\n },\n )\n },\n }\n}\n\nfunction safeJson(text: string): unknown {\n try {\n return JSON.parse(text)\n } catch {\n return null\n }\n}\n","/**\n * Decides between cookie-mode auth and the localStorage fallback, by setting a\n * cookie server-side and asking whether it came back.\n *\n * Cached in sessionStorage, deliberately not localStorage: a user can change\n * their third-party cookie policy, and a fresh tab should re-discover that.\n */\n\nimport { combinedSignal, READ_TIMEOUT_MS } from './api'\nimport { reportError } from './error-reporter'\n\nconst SESSION_KEY = 'markup.cookieProbe'\n\nexport async function probePartitionedCookieSupport(\n apiUrl: string,\n apiKey: string,\n): Promise<boolean> {\n // Cached result wins so a refresh inside the same tab is free.\n try {\n const cached = sessionStorage.getItem(SESSION_KEY)\n if (cached === 'supported') return true\n if (cached === 'unsupported') return false\n } catch {\n /* sessionStorage disabled — re-probe every time. Cheap. */\n }\n\n const base = apiUrl.replace(/\\/+$/, '')\n const headers = { 'x-markup-api-key': apiKey }\n\n try {\n const setRes = await fetch(`${base}/widget/auth/probe-set`, {\n method: 'POST',\n credentials: 'include',\n headers,\n signal: combinedSignal(READ_TIMEOUT_MS),\n })\n if (!setRes.ok) {\n // An older deployment without the endpoint, or a rejected origin.\n // Deliberately uncached, so a later deploy is picked up by a fresh tab.\n return false\n }\n const checkRes = await fetch(`${base}/widget/auth/probe-check`, {\n method: 'POST',\n credentials: 'include',\n headers,\n signal: combinedSignal(READ_TIMEOUT_MS),\n })\n if (!checkRes.ok) return false\n const { supported } = (await checkRes.json()) as { supported?: unknown }\n const result = supported === true\n try {\n sessionStorage.setItem(SESSION_KEY, result ? 'supported' : 'unsupported')\n } catch {\n /* sessionStorage disabled — leave uncached. */\n }\n return result\n } catch (err) {\n // Degrades to the localStorage flow. TypeError is network or CORS and is\n // routine; anything else — a throw inside `.json()` — is structural.\n const name = (err as { name?: unknown } | null)?.name\n if (name !== 'TypeError') {\n reportError(err, { context: 'cookie-probe' })\n }\n return false\n }\n}\n","import { reportError } from './error-reporter'\n\ntype Listener = () => void\n\nconst PATCHED_MARKER = '__markup_history_observer__'\nconst LISTENERS_KEY = '__markup_history_listeners__'\n\n/**\n * A throwing listener must not break its siblings and must not propagate: the\n * call stack here belongs to the host page's `history.pushState`, so an\n * escape crashes the customer's navigation code.\n */\nfunction dispatch(listeners: Set<Listener>) {\n listeners.forEach((fn) => {\n try {\n fn()\n } catch (err) {\n reportError(err, { context: 'history-observer-listener' })\n }\n })\n}\n\nconst RESTORE_KEY = '__markup_history_restore__'\n\ntype Patch = { listeners: Set<Listener>; restore: () => void }\n\nfunction install(): Patch {\n const push = history.pushState as typeof history.pushState & {\n [PATCHED_MARKER]?: number\n [LISTENERS_KEY]?: Set<Listener>\n [RESTORE_KEY]?: () => void\n }\n\n // Reusing the set from the wrapper is what survives an HMR re-import.\n if (push[PATCHED_MARKER]) {\n return { listeners: push[LISTENERS_KEY]!, restore: push[RESTORE_KEY]! }\n }\n\n const listeners = new Set<Listener>()\n\n const origPush = history.pushState\n const origReplace = history.replaceState\n\n function wrappedPush(this: History, ...args: Parameters<typeof History.prototype.pushState>) {\n origPush.apply(this, args)\n dispatch(listeners)\n }\n function wrappedReplace(\n this: History,\n ...args: Parameters<typeof History.prototype.replaceState>\n ) {\n origReplace.apply(this, args)\n dispatch(listeners)\n }\n\n const onPopState = () => dispatch(listeners)\n\n const restore = () => {\n // If another script patched on top of us, restoring our captured\n // originals would silently delete their hook — worse than leaving ours.\n if (history.pushState === wrappedPush) history.pushState = origPush\n if (history.replaceState === wrappedReplace) history.replaceState = origReplace\n window.removeEventListener('popstate', onPopState)\n listeners.clear()\n }\n\n Object.defineProperty(wrappedPush, PATCHED_MARKER, { value: 1 })\n Object.defineProperty(wrappedPush, LISTENERS_KEY, { value: listeners })\n Object.defineProperty(wrappedPush, RESTORE_KEY, { value: restore })\n Object.defineProperty(wrappedReplace, PATCHED_MARKER, { value: 1 })\n\n history.pushState = wrappedPush\n history.replaceState = wrappedReplace\n\n window.addEventListener('popstate', onPopState)\n\n return { listeners, restore }\n}\n\n// Null again after an HMR re-import, but `install()` short-circuits and\n// returns the same Set stored on the tagged wrapper.\nlet _patch: Patch | null = null\n\n/**\n * Wrappers install on the first subscribe and unwind when the last subscriber\n * leaves, so `destroy()` hands `window.history` back as it was found rather\n * than leaving the host page permanently patched.\n */\nexport function subscribeToRouteChanges(listener: Listener): () => void {\n if (!_patch) {\n _patch = install()\n }\n const patch = _patch\n patch.listeners.add(listener)\n\n let unsubscribed = false\n return () => {\n // `destroy()` may run twice, and the second must not tear down a patch a\n // later `init()` is relying on.\n if (unsubscribed) return\n unsubscribed = true\n patch.listeners.delete(listener)\n if (patch.listeners.size === 0) {\n patch.restore()\n if (_patch === patch) _patch = null\n }\n }\n}\n","const SAFE_PROTOCOLS = new Set(['http:', 'https:'])\n\n/**\n * Resolve `value` against `base`, returning it only if the result is\n * `http(s)`. Thread URLs come from the `/widget/threads` API, so a\n * `javascript:` value would otherwise execute on navigation.\n *\n * Relative values are fine — they inherit the base's scheme. Parses\n * rather than string-matches: the URL parser strips control characters\n * and lowercases the scheme, so `\"\\tjava\\nscript:…\"` still resolves to\n * `javascript:`.\n */\nexport function resolveSafeUrl(value: string, base: string): URL | null {\n let parsed: URL\n try {\n parsed = new URL(value, base)\n } catch {\n return null\n }\n return SAFE_PROTOCOLS.has(parsed.protocol) ? parsed : null\n}\n","/**\n * Identity lives in the host page's own localStorage, not a cross-origin\n * iframe: modern browsers partition third-party storage per top-level site, so\n * a shared bucket was never actually shared. Sign-in is therefore per host.\n *\n * The runtime state is a discriminated `IdentityState` union; the on-disk\n * shape is a flat record loose enough to accept legacy data from prior\n * widget versions. Translation happens in `loadIdentity` / `saveIdentity`.\n */\n\nimport { resolveSafeUrl } from './safe-url'\n\n/** Anonymous identity, bound to a server-issued JWT for the deployment. */\nexport interface AnonIdentity {\n clientId: string\n /**\n * Binds this `clientId` to the deployment, so ownership checks verify it\n * server-side rather than trusting the request body. Tampering with\n * `clientId` in localStorage invalidates the signature.\n */\n anonToken: string\n name?: string\n email?: string\n}\n\n/** Verified identity, bound to a popup-signed user JWT. */\nexport interface VerifiedIdentity {\n /**\n * Chosen at sign-in from the cookie probe:\n * - `'cookies'`: tokens live in HttpOnly Partitioned cookies and JS never\n * sees them, so `token`/`refreshToken` below are undefined.\n * - `'localStorage'`: tokens are persisted here. `token`/`tokenExpiresAt`\n * are always set; `refreshToken`/`refreshTokenExpiresAt` when the\n * deployment supports refresh and unset on legacy deployments.\n */\n storage: 'cookies' | 'localStorage'\n /** Always `markup_user_<sub>` for the JWT's subject. */\n clientId: string\n /** Undefined under `'cookies'` storage — the cookie carries it instead. */\n token?: string\n /** Epoch milliseconds when the access JWT stops being valid. */\n tokenExpiresAt: number\n /** Undefined under `'cookies'` storage and on legacy deployments. */\n refreshToken?: string\n /** Epoch milliseconds when the refresh token stops being valid. */\n refreshTokenExpiresAt?: number\n name: string\n email?: string\n /** Validated as http(s) on the way in; absent falls back to initials. */\n image?: string\n}\n\n/**\n * Runtime state machine for the widget identity:\n *\n * - `unresolved`: first-load anon mint is pending.\n * - `anon`: anon mint succeeded; `clientId` and `anonToken` are valid.\n * - `verified`: popup sign-in succeeded; `token` is the active Bearer.\n * - `recovering`: a verified session just 401'd. The anon mint is\n * pending again. `preserved` carries the user's display fields so\n * the next mint can roundtrip name/email without re-prompting.\n *\n * `unresolved` and `recovering` look the same to the UI today (both\n * surface as `connecting` on the author prompt) but they're distinct in\n * the type system so a future \"Reconnecting as Alice…\" UX has a slot\n * for it.\n */\nexport type IdentityState =\n | { kind: 'unresolved' }\n | { kind: 'anon'; identity: AnonIdentity }\n | { kind: 'verified'; identity: VerifiedIdentity }\n | { kind: 'recovering'; preserved: { name?: string; email?: string } }\n\n/**\n * Loose because legacy records are accepted: earlier versions wrote a flat\n * record, and a recovering session persisted as `{clientId, name, email}`.\n */\ninterface StoredShape {\n clientId?: string\n name?: string\n email?: string\n image?: string\n isVerified?: boolean\n // Absent on older records, which are treated as 'localStorage'.\n storage?: 'cookies' | 'localStorage'\n token?: string\n tokenExpiresAt?: number\n refreshToken?: string\n refreshTokenExpiresAt?: number\n anonToken?: string\n}\n\nconst KEY = 'markup.identity'\n\nfunction readStored(): StoredShape | null {\n try {\n const raw = localStorage.getItem(KEY)\n return raw ? (JSON.parse(raw) as StoredShape) : null\n } catch {\n return null\n }\n}\n\n/**\n * Re-checked on read even though it was checked on write: localStorage belongs\n * to the host page, any script there can rewrite the record, and this ends up\n * in an `<img src>`. A tampered entry then costs an avatar and nothing more.\n */\nfunction storedImage(stored: StoredShape): string | undefined {\n if (typeof stored.image !== 'string') return undefined\n return resolveSafeUrl(stored.image, location.href)?.href ?? undefined\n}\n\nfunction writeStored(stored: StoredShape | null): void {\n try {\n if (stored == null) {\n localStorage.removeItem(KEY)\n return\n }\n localStorage.setItem(KEY, JSON.stringify(stored))\n } catch {\n /* storage disabled (private mode quota) — identity stays in-memory only */\n }\n}\n\n/**\n * `preserved` comes back separately so a later anon mint can carry display\n * fields forward even when the record held no usable identity.\n */\nexport function loadIdentity(): {\n state: IdentityState\n preserved: { name?: string; email?: string }\n} {\n const stored = readStored()\n const preserved = { name: stored?.name, email: stored?.email }\n if (!stored) return { state: { kind: 'unresolved' }, preserved }\n\n // Legacy records have no `storage` field; cookie mode always writes one.\n const storage = stored.storage ?? 'localStorage'\n\n if (\n storage === 'cookies' &&\n stored.isVerified &&\n typeof stored.clientId === 'string' &&\n typeof stored.tokenExpiresAt === 'number' &&\n typeof stored.refreshTokenExpiresAt === 'number' &&\n typeof stored.name === 'string'\n ) {\n // The record holds only expiries and display fields here. While the\n // refresh token has time left, stay verified — the scheduler swaps in a\n // fresh access token even if the access cookie already expired.\n if (stored.refreshTokenExpiresAt > Date.now()) {\n return {\n state: {\n kind: 'verified',\n identity: {\n storage: 'cookies',\n clientId: stored.clientId,\n tokenExpiresAt: stored.tokenExpiresAt,\n refreshTokenExpiresAt: stored.refreshTokenExpiresAt,\n name: stored.name,\n email: stored.email,\n image: storedImage(stored),\n },\n },\n preserved,\n }\n }\n }\n\n if (\n storage === 'localStorage' &&\n stored.isVerified &&\n typeof stored.clientId === 'string' &&\n typeof stored.token === 'string' &&\n typeof stored.tokenExpiresAt === 'number' &&\n typeof stored.name === 'string'\n ) {\n // A short-TTL access token may be expired by the time the tab\n // reopens; if a refresh token is still valid, surface the verified\n // state anyway and let the refresh scheduler swap in a fresh\n // access token before the next write. This keeps \"signed in\"\n // sticky across tab reloads.\n const accessLive = stored.tokenExpiresAt > Date.now()\n const refreshLive =\n typeof stored.refreshToken === 'string' &&\n typeof stored.refreshTokenExpiresAt === 'number' &&\n stored.refreshTokenExpiresAt > Date.now()\n\n if (accessLive || refreshLive) {\n return {\n state: {\n kind: 'verified',\n identity: {\n storage: 'localStorage',\n clientId: stored.clientId,\n token: stored.token,\n tokenExpiresAt: stored.tokenExpiresAt,\n ...(refreshLive\n ? {\n refreshToken: stored.refreshToken,\n refreshTokenExpiresAt: stored.refreshTokenExpiresAt,\n }\n : {}),\n name: stored.name,\n email: stored.email,\n image: storedImage(stored),\n },\n },\n preserved,\n }\n }\n }\n\n if (typeof stored.clientId === 'string' && typeof stored.anonToken === 'string') {\n return {\n state: {\n kind: 'anon',\n identity: {\n clientId: stored.clientId,\n anonToken: stored.anonToken,\n name: stored.name,\n email: stored.email,\n },\n },\n preserved,\n }\n }\n\n // Has display fields but no signed token. Caller mints to recover.\n return { state: { kind: 'unresolved' }, preserved }\n}\n\n/**\n * Persist the runtime state. The transient states (`unresolved`,\n * `recovering`) drop the signed-identity fields; `recovering` keeps\n * `preserved` so the next mint can carry name/email forward.\n */\nexport function saveIdentity(state: IdentityState): void {\n switch (state.kind) {\n case 'verified':\n writeStored({\n clientId: state.identity.clientId,\n storage: state.identity.storage,\n // In cookie storage the JWT lives in the HttpOnly cookie and\n // is intentionally NOT mirrored into localStorage — that's the\n // whole point. We persist only what JS needs: the expiries\n // (for the refresh scheduler) and the display fields.\n token: state.identity.storage === 'cookies' ? undefined : state.identity.token,\n tokenExpiresAt: state.identity.tokenExpiresAt,\n refreshToken:\n state.identity.storage === 'cookies' ? undefined : state.identity.refreshToken,\n refreshTokenExpiresAt: state.identity.refreshTokenExpiresAt,\n isVerified: true,\n name: state.identity.name,\n email: state.identity.email,\n image: state.identity.image,\n })\n return\n case 'anon':\n writeStored({\n clientId: state.identity.clientId,\n anonToken: state.identity.anonToken,\n name: state.identity.name,\n email: state.identity.email,\n })\n return\n case 'recovering':\n // No identity to persist, just the display fields. clientId is\n // intentionally omitted — the next anon mint replaces it anyway.\n writeStored({\n name: state.preserved.name,\n email: state.preserved.email,\n })\n return\n case 'unresolved':\n writeStored(null)\n return\n }\n}\n\n/**\n * Convenience: the active widget clientId, regardless of identity flavor.\n * Returns `undefined` for `unresolved` / `recovering`.\n */\nexport function clientIdOf(state: IdentityState): string | undefined {\n if (state.kind === 'anon') return state.identity.clientId\n if (state.kind === 'verified') return state.identity.clientId\n return undefined\n}\n\n/**\n * Convenience: the active display name, or null when none is set.\n * Verified identities always have a name; anon may not until the user\n * fills in the author prompt.\n */\nexport function displayNameOf(state: IdentityState): string | null {\n if (state.kind === 'anon') return state.identity.name ?? null\n if (state.kind === 'verified') return state.identity.name\n return null\n}\n\n/**\n * Convenience: read the author display fields for write paths. Returns\n * `null` when the identity has no usable display name (unresolved /\n * recovering, or an anon identity whose user hasn't filled in the\n * prompt yet) — callers should bail in that case since the server\n * requires a name on the post.\n */\nexport function authorFieldsOf(\n state: IdentityState,\n): { name: string; email: string | undefined } | null {\n if (state.kind === 'anon') {\n const name = state.identity.name\n if (!name) return null\n return { name, email: state.identity.email }\n }\n if (state.kind === 'verified') {\n return { name: state.identity.name, email: state.identity.email }\n }\n return null\n}\n","import { combinedSignal, WRITE_TIMEOUT_MS } from './api'\nimport { reportError } from './error-reporter'\n\n/** Shape of the identity the `/widget/auth` popup posts back. */\nexport interface PopupIdentity {\n id: string\n name: string\n email?: string\n /** Profile picture for the toolbar avatar; absent if none is set. */\n image?: string\n}\n\n/**\n * `mode` says where the tokens went. Under `'cookies'` they are in HttpOnly\n * Partitioned cookies and the fields here are null by design — only the\n * expiries flow through, so the widget can still schedule a silent refresh.\n * A popup that sends no `mode` at all is treated as `'localStorage'`.\n */\nexport type PopupMode = 'cookies' | 'localStorage'\n\nexport interface PopupResult {\n mode: PopupMode\n identity: PopupIdentity\n token: string | null\n /** Epoch milliseconds when the JWT stops being valid. */\n tokenExpiresAt: number | null\n refreshToken: string | null\n /** Epoch milliseconds when the refresh token stops being valid. */\n refreshTokenExpiresAt: number | null\n}\n\n/**\n * A popup rather than an iframe because it is first-party to the deployment\n * origin, so the better-auth session cookie is actually sent.\n *\n * The apiKey never appears in the popup URL. The host page exchanges it for a\n * single-use 60-second code, which is what's safe to put in a URL the browser\n * records in history and sends as Referer.\n */\n/* Message types the popup posts back. Mirrored server-side in\n * `convex/http.ts` (the popup HTML is generated there); the two bundles\n * share no package, so the constants are duplicated deliberately. */\nconst POPUP_MSG_RESULT = 'MARKUP_AUTH_RESULT'\nconst POPUP_MSG_RETRY = 'MARKUP_AUTH_RETRY'\nconst POPUP_MSG_EXPIRED = 'MARKUP_AUTH_EXPIRED'\n\n/**\n * Bounds the one shape that could spin: a popup repeatedly reporting a lapsed\n * code because of clock skew or a sweep racing the read.\n *\n * Retry clicks are deliberately NOT counted — those are human-paced, and\n * clicking Retry more than five times before finishing sign-in is ordinary,\n * not something that should strand the visitor.\n */\nconst MAX_AUTOMATIC_REMINTS = 5\n\nexport async function signInWithPopup(args: {\n apiUrl: string\n apiKey: string\n /** Makes the server Set-Cookie the tokens instead of posting them back. */\n useCookies: boolean\n}): Promise<PopupResult> {\n const { apiUrl, apiKey, useCookies } = args\n const sessionOrigin = new URL(apiUrl).origin\n\n // `cookies` is only sent once the probe confirmed the browser honours\n // them, so a degraded path can't accidentally land in cookie mode.\n const capabilities = useCookies ? 'refresh,cookies' : 'refresh'\n\n /**\n * Re-called whenever the popup reports a lapsed code, which is the normal\n * outcome when the visitor has to sign into the dashboard first — that\n * detour routinely outlasts the 60-second TTL.\n */\n async function buildPopupUrl(): Promise<string> {\n const exchangeRes = await fetch(`${apiUrl.replace(/\\/+$/, '')}/widget/popup-exchange`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', 'x-markup-api-key': apiKey },\n body: '{}',\n signal: combinedSignal(WRITE_TIMEOUT_MS),\n })\n if (!exchangeRes.ok) {\n throw new Error(`popup-exchange responded with ${exchangeRes.status}`)\n }\n const { code } = (await exchangeRes.json()) as { code: string }\n const url = new URL('/widget/auth', apiUrl)\n url.searchParams.set('code', code)\n url.searchParams.set('capabilities', capabilities)\n return url.toString()\n }\n\n let popupUrl: string\n try {\n popupUrl = await buildPopupUrl()\n } catch (err) {\n // Structural failures only: bad apiKey, server bug. User-cancel and\n // popup-blocked have their own paths below. TypeError is the pure\n // network case — routine and noisy.\n const name = (err as { name?: unknown } | null)?.name\n if (name !== 'TypeError') {\n reportError(err, { context: 'popup-exchange' })\n }\n return Promise.reject(err instanceof Error ? err : new Error('Failed to start popup exchange'))\n }\n\n const w = 420\n const h = 560\n const left = Math.max(0, window.screenX + (window.outerWidth - w) / 2)\n const top = Math.max(0, window.screenY + (window.outerHeight - h) / 2)\n\n const popup = window.open(\n popupUrl,\n 'markup-auth',\n `width=${w},height=${h},left=${left},top=${top}`,\n )\n if (!popup) {\n return Promise.reject(new Error('Popup blocked. Allow popups for this site to sign in'))\n }\n\n // Without this, a popup that never posts back leaves the message listener\n // and close-watch interval running forever, and each retry stacks another\n // pair. Ten minutes rather than five because an unsigned-in visitor has a\n // whole OAuth round trip, password manager and 2FA prompt to get through.\n // Abandonment is caught far sooner by `closeWatch`.\n const TIMEOUT_MS = 10 * 60 * 1000\n\n // The popup posts tokens back in both modes. Cookie mode then re-installs\n // them from the host page's top-level context, because a Set-Cookie on the\n // popup response lands in the *popup's* partition, which the widget can't\n // read.\n const raw = await new Promise<PopupResult>((resolve, reject) => {\n let automaticRemints = 0\n /* Set while a re-mint fetch is in flight. The popup's own page posts\n * `EXPIRED` on load *and* on every Try-again click, so without this\n * a couple of quick clicks would race two navigations. */\n let reminting = false\n\n function cleanup() {\n window.removeEventListener('message', onMessage)\n clearInterval(closeWatch)\n clearTimeout(timeoutId)\n }\n\n /**\n * Hand the popup a fresh code and re-navigate it. Navigating a\n * window we opened is permitted cross-origin, which is what lets\n * the widget — the only party holding the apiKey — drive recovery\n * without the popup ever seeing that key.\n *\n * An arrow const rather than a `function` declaration: hoisted\n * declarations lose the `if (!popup)` narrowing above, so the\n * property accesses below would need non-null assertions.\n */\n const renavigate = (automatic: boolean) => {\n if (reminting) return\n if (automatic) {\n if (automaticRemints >= MAX_AUTOMATIC_REMINTS) {\n cleanup()\n reject(new Error('Sign-in could not be restarted. Close the window and try again'))\n return\n }\n automaticRemints += 1\n }\n reminting = true\n buildPopupUrl()\n .then((freshUrl) => {\n if (popup.closed) return\n popup.location.href = freshUrl\n })\n .catch((err) => {\n cleanup()\n reportError(err, { context: 'popup-exchange-remint' })\n reject(err instanceof Error ? err : new Error('Failed to restart sign-in'))\n })\n .finally(() => {\n reminting = false\n })\n }\n\n function onMessage(e: MessageEvent) {\n if (e.origin !== sessionOrigin) return\n // Origin alone would accept a postMessage from any other window on the\n // deployment origin, such as a stale dashboard tab.\n if (e.source !== popup) return\n const d = e.data as {\n type?: string\n mode?: PopupMode\n identity?: PopupIdentity\n token?: string | null\n tokenExpiresAt?: number | null\n refreshToken?: string | null\n refreshTokenExpiresAt?: number | null\n }\n // Both recover the same way; only the automatic one is budgeted.\n if (d?.type === POPUP_MSG_RETRY) {\n renavigate(false)\n return\n }\n if (d?.type === POPUP_MSG_EXPIRED) {\n renavigate(true)\n return\n }\n if (d?.type !== POPUP_MSG_RESULT) return\n cleanup()\n if (d.identity?.id && d.identity?.name) {\n // A popup that sends no `mode` is a legacy one.\n const mode: PopupMode = d.mode === 'cookies' ? 'cookies' : 'localStorage'\n resolve({\n mode,\n identity: d.identity,\n token: typeof d.token === 'string' ? d.token : null,\n tokenExpiresAt: typeof d.tokenExpiresAt === 'number' ? d.tokenExpiresAt : null,\n refreshToken: typeof d.refreshToken === 'string' ? d.refreshToken : null,\n refreshTokenExpiresAt:\n typeof d.refreshTokenExpiresAt === 'number' ? d.refreshTokenExpiresAt : null,\n })\n } else {\n reject(new Error('Sign-in cancelled'))\n }\n }\n const closeWatch = window.setInterval(() => {\n if (popup.closed) {\n cleanup()\n reject(new Error('Sign-in cancelled'))\n }\n }, 500)\n const timeoutId = window.setTimeout(() => {\n cleanup()\n reject(new Error('Sign-in timed out'))\n }, TIMEOUT_MS)\n window.addEventListener('message', onMessage)\n })\n\n // Runs from the host page's top-level context so Set-Cookie lands in the\n // partition the widget reads. The tokens are cleared from the result\n // afterwards, so they never leave this function.\n if (raw.mode === 'cookies' && raw.token && raw.refreshToken) {\n const installRes = await fetch(`${apiUrl.replace(/\\/+$/, '')}/widget/auth/install-cookies`, {\n method: 'POST',\n credentials: 'include',\n headers: { 'content-type': 'application/json', 'x-markup-api-key': apiKey },\n body: JSON.stringify({\n accessToken: raw.token,\n refreshToken: raw.refreshToken,\n }),\n signal: combinedSignal(WRITE_TIMEOUT_MS),\n })\n if (!installRes.ok) {\n // The popup already succeeded, so this is the partition re-install\n // failing specifically — a real bug, not a user-facing outcome.\n const err = new Error(`Failed to install widget cookies (${installRes.status})`)\n reportError(err, { context: 'install-cookies' })\n throw err\n }\n return { ...raw, token: null, refreshToken: null }\n }\n\n return raw\n}\n","export function resolveUrl(url, baseUrl) {\n // url is absolute already\n if (url.match(/^[a-z]+:\\/\\//i)) {\n return url;\n }\n // url is absolute already, without protocol\n if (url.match(/^\\/\\//)) {\n return window.location.protocol + url;\n }\n // dataURI, mailto:, tel:, etc.\n if (url.match(/^[a-z]+:/i)) {\n return url;\n }\n const doc = document.implementation.createHTMLDocument();\n const base = doc.createElement('base');\n const a = doc.createElement('a');\n doc.head.appendChild(base);\n doc.body.appendChild(a);\n if (baseUrl) {\n base.href = baseUrl;\n }\n a.href = url;\n return a.href;\n}\nexport const uuid = (() => {\n // generate uuid for className of pseudo elements.\n // We should not use GUIDs, otherwise pseudo elements sometimes cannot be captured.\n let counter = 0;\n // ref: http://stackoverflow.com/a/6248722/2519373\n const random = () => \n // eslint-disable-next-line no-bitwise\n `0000${((Math.random() * 36 ** 4) << 0).toString(36)}`.slice(-4);\n return () => {\n counter += 1;\n return `u${random()}${counter}`;\n };\n})();\nexport function delay(ms) {\n return (args) => new Promise((resolve) => {\n setTimeout(() => resolve(args), ms);\n });\n}\nexport function toArray(arrayLike) {\n const arr = [];\n for (let i = 0, l = arrayLike.length; i < l; i++) {\n arr.push(arrayLike[i]);\n }\n return arr;\n}\nlet styleProps = null;\nexport function getStyleProperties(options = {}) {\n if (styleProps) {\n return styleProps;\n }\n if (options.includeStyleProperties) {\n styleProps = options.includeStyleProperties;\n return styleProps;\n }\n styleProps = toArray(window.getComputedStyle(document.documentElement));\n return styleProps;\n}\nfunction px(node, styleProperty) {\n const win = node.ownerDocument.defaultView || window;\n const val = win.getComputedStyle(node).getPropertyValue(styleProperty);\n return val ? parseFloat(val.replace('px', '')) : 0;\n}\nfunction getNodeWidth(node) {\n const leftBorder = px(node, 'border-left-width');\n const rightBorder = px(node, 'border-right-width');\n return node.clientWidth + leftBorder + rightBorder;\n}\nfunction getNodeHeight(node) {\n const topBorder = px(node, 'border-top-width');\n const bottomBorder = px(node, 'border-bottom-width');\n return node.clientHeight + topBorder + bottomBorder;\n}\nexport function getImageSize(targetNode, options = {}) {\n const width = options.width || getNodeWidth(targetNode);\n const height = options.height || getNodeHeight(targetNode);\n return { width, height };\n}\nexport function getPixelRatio() {\n let ratio;\n let FINAL_PROCESS;\n try {\n FINAL_PROCESS = process;\n }\n catch (e) {\n // pass\n }\n const val = FINAL_PROCESS && FINAL_PROCESS.env\n ? FINAL_PROCESS.env.devicePixelRatio\n : null;\n if (val) {\n ratio = parseInt(val, 10);\n if (Number.isNaN(ratio)) {\n ratio = 1;\n }\n }\n return ratio || window.devicePixelRatio || 1;\n}\n// @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas#maximum_canvas_size\nconst canvasDimensionLimit = 16384;\nexport function checkCanvasDimensions(canvas) {\n if (canvas.width > canvasDimensionLimit ||\n canvas.height > canvasDimensionLimit) {\n if (canvas.width > canvasDimensionLimit &&\n canvas.height > canvasDimensionLimit) {\n if (canvas.width > canvas.height) {\n canvas.height *= canvasDimensionLimit / canvas.width;\n canvas.width = canvasDimensionLimit;\n }\n else {\n canvas.width *= canvasDimensionLimit / canvas.height;\n canvas.height = canvasDimensionLimit;\n }\n }\n else if (canvas.width > canvasDimensionLimit) {\n canvas.height *= canvasDimensionLimit / canvas.width;\n canvas.width = canvasDimensionLimit;\n }\n else {\n canvas.width *= canvasDimensionLimit / canvas.height;\n canvas.height = canvasDimensionLimit;\n }\n }\n}\nexport function canvasToBlob(canvas, options = {}) {\n if (canvas.toBlob) {\n return new Promise((resolve) => {\n canvas.toBlob(resolve, options.type ? options.type : 'image/png', options.quality ? options.quality : 1);\n });\n }\n return new Promise((resolve) => {\n const binaryString = window.atob(canvas\n .toDataURL(options.type ? options.type : undefined, options.quality ? options.quality : undefined)\n .split(',')[1]);\n const len = binaryString.length;\n const binaryArray = new Uint8Array(len);\n for (let i = 0; i < len; i += 1) {\n binaryArray[i] = binaryString.charCodeAt(i);\n }\n resolve(new Blob([binaryArray], {\n type: options.type ? options.type : 'image/png',\n }));\n });\n}\nexport function createImage(url) {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n img.decode().then(() => {\n requestAnimationFrame(() => resolve(img));\n });\n };\n img.onerror = reject;\n img.crossOrigin = 'anonymous';\n img.decoding = 'async';\n img.src = url;\n });\n}\nexport async function svgToDataURL(svg) {\n return Promise.resolve()\n .then(() => new XMLSerializer().serializeToString(svg))\n .then(encodeURIComponent)\n .then((html) => `data:image/svg+xml;charset=utf-8,${html}`);\n}\nexport async function nodeToDataURL(node, width, height) {\n const xmlns = 'http://www.w3.org/2000/svg';\n const svg = document.createElementNS(xmlns, 'svg');\n const foreignObject = document.createElementNS(xmlns, 'foreignObject');\n svg.setAttribute('width', `${width}`);\n svg.setAttribute('height', `${height}`);\n svg.setAttribute('viewBox', `0 0 ${width} ${height}`);\n foreignObject.setAttribute('width', '100%');\n foreignObject.setAttribute('height', '100%');\n foreignObject.setAttribute('x', '0');\n foreignObject.setAttribute('y', '0');\n foreignObject.setAttribute('externalResourcesRequired', 'true');\n svg.appendChild(foreignObject);\n foreignObject.appendChild(node);\n return svgToDataURL(svg);\n}\nexport const isInstanceOfElement = (node, instance) => {\n if (node instanceof instance)\n return true;\n const nodePrototype = Object.getPrototypeOf(node);\n if (nodePrototype === null)\n return false;\n return (nodePrototype.constructor.name === instance.name ||\n isInstanceOfElement(nodePrototype, instance));\n};\n//# sourceMappingURL=util.js.map","import { uuid, getStyleProperties } from './util';\nfunction formatCSSText(style) {\n const content = style.getPropertyValue('content');\n return `${style.cssText} content: '${content.replace(/'|\"/g, '')}';`;\n}\nfunction formatCSSProperties(style, options) {\n return getStyleProperties(options)\n .map((name) => {\n const value = style.getPropertyValue(name);\n const priority = style.getPropertyPriority(name);\n return `${name}: ${value}${priority ? ' !important' : ''};`;\n })\n .join(' ');\n}\nfunction getPseudoElementStyle(className, pseudo, style, options) {\n const selector = `.${className}:${pseudo}`;\n const cssText = style.cssText\n ? formatCSSText(style)\n : formatCSSProperties(style, options);\n return document.createTextNode(`${selector}{${cssText}}`);\n}\nfunction clonePseudoElement(nativeNode, clonedNode, pseudo, options) {\n const style = window.getComputedStyle(nativeNode, pseudo);\n const content = style.getPropertyValue('content');\n if (content === '' || content === 'none') {\n return;\n }\n const className = uuid();\n try {\n clonedNode.className = `${clonedNode.className} ${className}`;\n }\n catch (err) {\n return;\n }\n const styleElement = document.createElement('style');\n styleElement.appendChild(getPseudoElementStyle(className, pseudo, style, options));\n clonedNode.appendChild(styleElement);\n}\nexport function clonePseudoElements(nativeNode, clonedNode, options) {\n clonePseudoElement(nativeNode, clonedNode, ':before', options);\n clonePseudoElement(nativeNode, clonedNode, ':after', options);\n}\n//# sourceMappingURL=clone-pseudos.js.map","const WOFF = 'application/font-woff';\nconst JPEG = 'image/jpeg';\nconst mimes = {\n woff: WOFF,\n woff2: WOFF,\n ttf: 'application/font-truetype',\n eot: 'application/vnd.ms-fontobject',\n png: 'image/png',\n jpg: JPEG,\n jpeg: JPEG,\n gif: 'image/gif',\n tiff: 'image/tiff',\n svg: 'image/svg+xml',\n webp: 'image/webp',\n};\nfunction getExtension(url) {\n const match = /\\.([^./]*?)$/g.exec(url);\n return match ? match[1] : '';\n}\nexport function getMimeType(url) {\n const extension = getExtension(url).toLowerCase();\n return mimes[extension] || '';\n}\n//# sourceMappingURL=mimes.js.map","function getContentFromDataUrl(dataURL) {\n return dataURL.split(/,/)[1];\n}\nexport function isDataUrl(url) {\n return url.search(/^(data:)/) !== -1;\n}\nexport function makeDataUrl(content, mimeType) {\n return `data:${mimeType};base64,${content}`;\n}\nexport async function fetchAsDataURL(url, init, process) {\n const res = await fetch(url, init);\n if (res.status === 404) {\n throw new Error(`Resource \"${res.url}\" not found`);\n }\n const blob = await res.blob();\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = () => {\n try {\n resolve(process({ res, result: reader.result }));\n }\n catch (error) {\n reject(error);\n }\n };\n reader.readAsDataURL(blob);\n });\n}\nconst cache = {};\nfunction getCacheKey(url, contentType, includeQueryParams) {\n let key = url.replace(/\\?.*/, '');\n if (includeQueryParams) {\n key = url;\n }\n // font resource\n if (/ttf|otf|eot|woff2?/i.test(key)) {\n key = key.replace(/.*\\//, '');\n }\n return contentType ? `[${contentType}]${key}` : key;\n}\nexport async function resourceToDataURL(resourceUrl, contentType, options) {\n const cacheKey = getCacheKey(resourceUrl, contentType, options.includeQueryParams);\n if (cache[cacheKey] != null) {\n return cache[cacheKey];\n }\n // ref: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache\n if (options.cacheBust) {\n // eslint-disable-next-line no-param-reassign\n resourceUrl += (/\\?/.test(resourceUrl) ? '&' : '?') + new Date().getTime();\n }\n let dataURL;\n try {\n const content = await fetchAsDataURL(resourceUrl, options.fetchRequestInit, ({ res, result }) => {\n if (!contentType) {\n // eslint-disable-next-line no-param-reassign\n contentType = res.headers.get('Content-Type') || '';\n }\n return getContentFromDataUrl(result);\n });\n dataURL = makeDataUrl(content, contentType);\n }\n catch (error) {\n dataURL = options.imagePlaceholder || '';\n let msg = `Failed to fetch resource: ${resourceUrl}`;\n if (error) {\n msg = typeof error === 'string' ? error : error.message;\n }\n if (msg) {\n console.warn(msg);\n }\n }\n cache[cacheKey] = dataURL;\n return dataURL;\n}\n//# sourceMappingURL=dataurl.js.map","import { clonePseudoElements } from './clone-pseudos';\nimport { createImage, toArray, isInstanceOfElement, getStyleProperties, } from './util';\nimport { getMimeType } from './mimes';\nimport { resourceToDataURL } from './dataurl';\nasync function cloneCanvasElement(canvas) {\n const dataURL = canvas.toDataURL();\n if (dataURL === 'data:,') {\n return canvas.cloneNode(false);\n }\n return createImage(dataURL);\n}\nasync function cloneVideoElement(video, options) {\n if (video.currentSrc) {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n canvas.width = video.clientWidth;\n canvas.height = video.clientHeight;\n ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(video, 0, 0, canvas.width, canvas.height);\n const dataURL = canvas.toDataURL();\n return createImage(dataURL);\n }\n const poster = video.poster;\n const contentType = getMimeType(poster);\n const dataURL = await resourceToDataURL(poster, contentType, options);\n return createImage(dataURL);\n}\nasync function cloneIFrameElement(iframe, options) {\n var _a;\n try {\n if ((_a = iframe === null || iframe === void 0 ? void 0 : iframe.contentDocument) === null || _a === void 0 ? void 0 : _a.body) {\n return (await cloneNode(iframe.contentDocument.body, options, true));\n }\n }\n catch (_b) {\n // Failed to clone iframe\n }\n return iframe.cloneNode(false);\n}\nasync function cloneSingleNode(node, options) {\n if (isInstanceOfElement(node, HTMLCanvasElement)) {\n return cloneCanvasElement(node);\n }\n if (isInstanceOfElement(node, HTMLVideoElement)) {\n return cloneVideoElement(node, options);\n }\n if (isInstanceOfElement(node, HTMLIFrameElement)) {\n return cloneIFrameElement(node, options);\n }\n return node.cloneNode(isSVGElement(node));\n}\nconst isSlotElement = (node) => node.tagName != null && node.tagName.toUpperCase() === 'SLOT';\nconst isSVGElement = (node) => node.tagName != null && node.tagName.toUpperCase() === 'SVG';\nasync function cloneChildren(nativeNode, clonedNode, options) {\n var _a, _b;\n if (isSVGElement(clonedNode)) {\n return clonedNode;\n }\n let children = [];\n if (isSlotElement(nativeNode) && nativeNode.assignedNodes) {\n children = toArray(nativeNode.assignedNodes());\n }\n else if (isInstanceOfElement(nativeNode, HTMLIFrameElement) &&\n ((_a = nativeNode.contentDocument) === null || _a === void 0 ? void 0 : _a.body)) {\n children = toArray(nativeNode.contentDocument.body.childNodes);\n }\n else {\n children = toArray(((_b = nativeNode.shadowRoot) !== null && _b !== void 0 ? _b : nativeNode).childNodes);\n }\n if (children.length === 0 ||\n isInstanceOfElement(nativeNode, HTMLVideoElement)) {\n return clonedNode;\n }\n await children.reduce((deferred, child) => deferred\n .then(() => cloneNode(child, options))\n .then((clonedChild) => {\n if (clonedChild) {\n clonedNode.appendChild(clonedChild);\n }\n }), Promise.resolve());\n return clonedNode;\n}\nfunction cloneCSSStyle(nativeNode, clonedNode, options) {\n const targetStyle = clonedNode.style;\n if (!targetStyle) {\n return;\n }\n const sourceStyle = window.getComputedStyle(nativeNode);\n if (sourceStyle.cssText) {\n targetStyle.cssText = sourceStyle.cssText;\n targetStyle.transformOrigin = sourceStyle.transformOrigin;\n }\n else {\n getStyleProperties(options).forEach((name) => {\n let value = sourceStyle.getPropertyValue(name);\n if (name === 'font-size' && value.endsWith('px')) {\n const reducedFont = Math.floor(parseFloat(value.substring(0, value.length - 2))) - 0.1;\n value = `${reducedFont}px`;\n }\n if (isInstanceOfElement(nativeNode, HTMLIFrameElement) &&\n name === 'display' &&\n value === 'inline') {\n value = 'block';\n }\n if (name === 'd' && clonedNode.getAttribute('d')) {\n value = `path(${clonedNode.getAttribute('d')})`;\n }\n targetStyle.setProperty(name, value, sourceStyle.getPropertyPriority(name));\n });\n }\n}\nfunction cloneInputValue(nativeNode, clonedNode) {\n if (isInstanceOfElement(nativeNode, HTMLTextAreaElement)) {\n clonedNode.innerHTML = nativeNode.value;\n }\n if (isInstanceOfElement(nativeNode, HTMLInputElement)) {\n clonedNode.setAttribute('value', nativeNode.value);\n }\n}\nfunction cloneSelectValue(nativeNode, clonedNode) {\n if (isInstanceOfElement(nativeNode, HTMLSelectElement)) {\n const clonedSelect = clonedNode;\n const selectedOption = Array.from(clonedSelect.children).find((child) => nativeNode.value === child.getAttribute('value'));\n if (selectedOption) {\n selectedOption.setAttribute('selected', '');\n }\n }\n}\nfunction decorate(nativeNode, clonedNode, options) {\n if (isInstanceOfElement(clonedNode, Element)) {\n cloneCSSStyle(nativeNode, clonedNode, options);\n clonePseudoElements(nativeNode, clonedNode, options);\n cloneInputValue(nativeNode, clonedNode);\n cloneSelectValue(nativeNode, clonedNode);\n }\n return clonedNode;\n}\nasync function ensureSVGSymbols(clone, options) {\n const uses = clone.querySelectorAll ? clone.querySelectorAll('use') : [];\n if (uses.length === 0) {\n return clone;\n }\n const processedDefs = {};\n for (let i = 0; i < uses.length; i++) {\n const use = uses[i];\n const id = use.getAttribute('xlink:href');\n if (id) {\n const exist = clone.querySelector(id);\n const definition = document.querySelector(id);\n if (!exist && definition && !processedDefs[id]) {\n // eslint-disable-next-line no-await-in-loop\n processedDefs[id] = (await cloneNode(definition, options, true));\n }\n }\n }\n const nodes = Object.values(processedDefs);\n if (nodes.length) {\n const ns = 'http://www.w3.org/1999/xhtml';\n const svg = document.createElementNS(ns, 'svg');\n svg.setAttribute('xmlns', ns);\n svg.style.position = 'absolute';\n svg.style.width = '0';\n svg.style.height = '0';\n svg.style.overflow = 'hidden';\n svg.style.display = 'none';\n const defs = document.createElementNS(ns, 'defs');\n svg.appendChild(defs);\n for (let i = 0; i < nodes.length; i++) {\n defs.appendChild(nodes[i]);\n }\n clone.appendChild(svg);\n }\n return clone;\n}\nexport async function cloneNode(node, options, isRoot) {\n if (!isRoot && options.filter && !options.filter(node)) {\n return null;\n }\n return Promise.resolve(node)\n .then((clonedNode) => cloneSingleNode(clonedNode, options))\n .then((clonedNode) => cloneChildren(node, clonedNode, options))\n .then((clonedNode) => decorate(node, clonedNode, options))\n .then((clonedNode) => ensureSVGSymbols(clonedNode, options));\n}\n//# sourceMappingURL=clone-node.js.map","import { resolveUrl } from './util';\nimport { getMimeType } from './mimes';\nimport { isDataUrl, makeDataUrl, resourceToDataURL } from './dataurl';\nconst URL_REGEX = /url\\((['\"]?)([^'\"]+?)\\1\\)/g;\nconst URL_WITH_FORMAT_REGEX = /url\\([^)]+\\)\\s*format\\(([\"']?)([^\"']+)\\1\\)/g;\nconst FONT_SRC_REGEX = /src:\\s*(?:url\\([^)]+\\)\\s*format\\([^)]+\\)[,;]\\s*)+/g;\nfunction toRegex(url) {\n // eslint-disable-next-line no-useless-escape\n const escaped = url.replace(/([.*+?^${}()|\\[\\]\\/\\\\])/g, '\\\\$1');\n return new RegExp(`(url\\\\(['\"]?)(${escaped})(['\"]?\\\\))`, 'g');\n}\nexport function parseURLs(cssText) {\n const urls = [];\n cssText.replace(URL_REGEX, (raw, quotation, url) => {\n urls.push(url);\n return raw;\n });\n return urls.filter((url) => !isDataUrl(url));\n}\nexport async function embed(cssText, resourceURL, baseURL, options, getContentFromUrl) {\n try {\n const resolvedURL = baseURL ? resolveUrl(resourceURL, baseURL) : resourceURL;\n const contentType = getMimeType(resourceURL);\n let dataURL;\n if (getContentFromUrl) {\n const content = await getContentFromUrl(resolvedURL);\n dataURL = makeDataUrl(content, contentType);\n }\n else {\n dataURL = await resourceToDataURL(resolvedURL, contentType, options);\n }\n return cssText.replace(toRegex(resourceURL), `$1${dataURL}$3`);\n }\n catch (error) {\n // pass\n }\n return cssText;\n}\nfunction filterPreferredFontFormat(str, { preferredFontFormat }) {\n return !preferredFontFormat\n ? str\n : str.replace(FONT_SRC_REGEX, (match) => {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const [src, , format] = URL_WITH_FORMAT_REGEX.exec(match) || [];\n if (!format) {\n return '';\n }\n if (format === preferredFontFormat) {\n return `src: ${src};`;\n }\n }\n });\n}\nexport function shouldEmbed(url) {\n return url.search(URL_REGEX) !== -1;\n}\nexport async function embedResources(cssText, baseUrl, options) {\n if (!shouldEmbed(cssText)) {\n return cssText;\n }\n const filteredCSSText = filterPreferredFontFormat(cssText, options);\n const urls = parseURLs(filteredCSSText);\n return urls.reduce((deferred, url) => deferred.then((css) => embed(css, url, baseUrl, options)), Promise.resolve(filteredCSSText));\n}\n//# sourceMappingURL=embed-resources.js.map","import { embedResources } from './embed-resources';\nimport { toArray, isInstanceOfElement } from './util';\nimport { isDataUrl, resourceToDataURL } from './dataurl';\nimport { getMimeType } from './mimes';\nasync function embedProp(propName, node, options) {\n var _a;\n const propValue = (_a = node.style) === null || _a === void 0 ? void 0 : _a.getPropertyValue(propName);\n if (propValue) {\n const cssString = await embedResources(propValue, null, options);\n node.style.setProperty(propName, cssString, node.style.getPropertyPriority(propName));\n return true;\n }\n return false;\n}\nasync function embedBackground(clonedNode, options) {\n ;\n (await embedProp('background', clonedNode, options)) ||\n (await embedProp('background-image', clonedNode, options));\n (await embedProp('mask', clonedNode, options)) ||\n (await embedProp('-webkit-mask', clonedNode, options)) ||\n (await embedProp('mask-image', clonedNode, options)) ||\n (await embedProp('-webkit-mask-image', clonedNode, options));\n}\nasync function embedImageNode(clonedNode, options) {\n const isImageElement = isInstanceOfElement(clonedNode, HTMLImageElement);\n if (!(isImageElement && !isDataUrl(clonedNode.src)) &&\n !(isInstanceOfElement(clonedNode, SVGImageElement) &&\n !isDataUrl(clonedNode.href.baseVal))) {\n return;\n }\n const url = isImageElement ? clonedNode.src : clonedNode.href.baseVal;\n const dataURL = await resourceToDataURL(url, getMimeType(url), options);\n await new Promise((resolve, reject) => {\n clonedNode.onload = resolve;\n clonedNode.onerror = options.onImageErrorHandler\n ? (...attributes) => {\n try {\n resolve(options.onImageErrorHandler(...attributes));\n }\n catch (error) {\n reject(error);\n }\n }\n : reject;\n const image = clonedNode;\n if (image.decode) {\n image.decode = resolve;\n }\n if (image.loading === 'lazy') {\n image.loading = 'eager';\n }\n if (isImageElement) {\n clonedNode.srcset = '';\n clonedNode.src = dataURL;\n }\n else {\n clonedNode.href.baseVal = dataURL;\n }\n });\n}\nasync function embedChildren(clonedNode, options) {\n const children = toArray(clonedNode.childNodes);\n const deferreds = children.map((child) => embedImages(child, options));\n await Promise.all(deferreds).then(() => clonedNode);\n}\nexport async function embedImages(clonedNode, options) {\n if (isInstanceOfElement(clonedNode, Element)) {\n await embedBackground(clonedNode, options);\n await embedImageNode(clonedNode, options);\n await embedChildren(clonedNode, options);\n }\n}\n//# sourceMappingURL=embed-images.js.map","export function applyStyle(node, options) {\n const { style } = node;\n if (options.backgroundColor) {\n style.backgroundColor = options.backgroundColor;\n }\n if (options.width) {\n style.width = `${options.width}px`;\n }\n if (options.height) {\n style.height = `${options.height}px`;\n }\n const manual = options.style;\n if (manual != null) {\n Object.keys(manual).forEach((key) => {\n style[key] = manual[key];\n });\n }\n return node;\n}\n//# sourceMappingURL=apply-style.js.map","import { toArray } from './util';\nimport { fetchAsDataURL } from './dataurl';\nimport { shouldEmbed, embedResources } from './embed-resources';\nconst cssFetchCache = {};\nasync function fetchCSS(url) {\n let cache = cssFetchCache[url];\n if (cache != null) {\n return cache;\n }\n const res = await fetch(url);\n const cssText = await res.text();\n cache = { url, cssText };\n cssFetchCache[url] = cache;\n return cache;\n}\nasync function embedFonts(data, options) {\n let cssText = data.cssText;\n const regexUrl = /url\\([\"']?([^\"')]+)[\"']?\\)/g;\n const fontLocs = cssText.match(/url\\([^)]+\\)/g) || [];\n const loadFonts = fontLocs.map(async (loc) => {\n let url = loc.replace(regexUrl, '$1');\n if (!url.startsWith('https://')) {\n url = new URL(url, data.url).href;\n }\n return fetchAsDataURL(url, options.fetchRequestInit, ({ result }) => {\n cssText = cssText.replace(loc, `url(${result})`);\n return [loc, result];\n });\n });\n return Promise.all(loadFonts).then(() => cssText);\n}\nfunction parseCSS(source) {\n if (source == null) {\n return [];\n }\n const result = [];\n const commentsRegex = /(\\/\\*[\\s\\S]*?\\*\\/)/gi;\n // strip out comments\n let cssText = source.replace(commentsRegex, '');\n // eslint-disable-next-line prefer-regex-literals\n const keyframesRegex = new RegExp('((@.*?keyframes [\\\\s\\\\S]*?){([\\\\s\\\\S]*?}\\\\s*?)})', 'gi');\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const matches = keyframesRegex.exec(cssText);\n if (matches === null) {\n break;\n }\n result.push(matches[0]);\n }\n cssText = cssText.replace(keyframesRegex, '');\n const importRegex = /@import[\\s\\S]*?url\\([^)]*\\)[\\s\\S]*?;/gi;\n // to match css & media queries together\n const combinedCSSRegex = '((\\\\s*?(?:\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)?\\\\s*?@media[\\\\s\\\\S]' +\n '*?){([\\\\s\\\\S]*?)}\\\\s*?})|(([\\\\s\\\\S]*?){([\\\\s\\\\S]*?)})';\n // unified regex\n const unifiedRegex = new RegExp(combinedCSSRegex, 'gi');\n // eslint-disable-next-line no-constant-condition\n while (true) {\n let matches = importRegex.exec(cssText);\n if (matches === null) {\n matches = unifiedRegex.exec(cssText);\n if (matches === null) {\n break;\n }\n else {\n importRegex.lastIndex = unifiedRegex.lastIndex;\n }\n }\n else {\n unifiedRegex.lastIndex = importRegex.lastIndex;\n }\n result.push(matches[0]);\n }\n return result;\n}\nasync function getCSSRules(styleSheets, options) {\n const ret = [];\n const deferreds = [];\n // First loop inlines imports\n styleSheets.forEach((sheet) => {\n if ('cssRules' in sheet) {\n try {\n toArray(sheet.cssRules || []).forEach((item, index) => {\n if (item.type === CSSRule.IMPORT_RULE) {\n let importIndex = index + 1;\n const url = item.href;\n const deferred = fetchCSS(url)\n .then((metadata) => embedFonts(metadata, options))\n .then((cssText) => parseCSS(cssText).forEach((rule) => {\n try {\n sheet.insertRule(rule, rule.startsWith('@import')\n ? (importIndex += 1)\n : sheet.cssRules.length);\n }\n catch (error) {\n console.error('Error inserting rule from remote css', {\n rule,\n error,\n });\n }\n }))\n .catch((e) => {\n console.error('Error loading remote css', e.toString());\n });\n deferreds.push(deferred);\n }\n });\n }\n catch (e) {\n const inline = styleSheets.find((a) => a.href == null) || document.styleSheets[0];\n if (sheet.href != null) {\n deferreds.push(fetchCSS(sheet.href)\n .then((metadata) => embedFonts(metadata, options))\n .then((cssText) => parseCSS(cssText).forEach((rule) => {\n inline.insertRule(rule, inline.cssRules.length);\n }))\n .catch((err) => {\n console.error('Error loading remote stylesheet', err);\n }));\n }\n console.error('Error inlining remote css file', e);\n }\n }\n });\n return Promise.all(deferreds).then(() => {\n // Second loop parses rules\n styleSheets.forEach((sheet) => {\n if ('cssRules' in sheet) {\n try {\n toArray(sheet.cssRules || []).forEach((item) => {\n ret.push(item);\n });\n }\n catch (e) {\n console.error(`Error while reading CSS rules from ${sheet.href}`, e);\n }\n }\n });\n return ret;\n });\n}\nfunction getWebFontRules(cssRules) {\n return cssRules\n .filter((rule) => rule.type === CSSRule.FONT_FACE_RULE)\n .filter((rule) => shouldEmbed(rule.style.getPropertyValue('src')));\n}\nasync function parseWebFontRules(node, options) {\n if (node.ownerDocument == null) {\n throw new Error('Provided element is not within a Document');\n }\n const styleSheets = toArray(node.ownerDocument.styleSheets);\n const cssRules = await getCSSRules(styleSheets, options);\n return getWebFontRules(cssRules);\n}\nfunction normalizeFontFamily(font) {\n return font.trim().replace(/[\"']/g, '');\n}\nfunction getUsedFonts(node) {\n const fonts = new Set();\n function traverse(node) {\n const fontFamily = node.style.fontFamily || getComputedStyle(node).fontFamily;\n fontFamily.split(',').forEach((font) => {\n fonts.add(normalizeFontFamily(font));\n });\n Array.from(node.children).forEach((child) => {\n if (child instanceof HTMLElement) {\n traverse(child);\n }\n });\n }\n traverse(node);\n return fonts;\n}\nexport async function getWebFontCSS(node, options) {\n const rules = await parseWebFontRules(node, options);\n const usedFonts = getUsedFonts(node);\n const cssTexts = await Promise.all(rules\n .filter((rule) => usedFonts.has(normalizeFontFamily(rule.style.fontFamily)))\n .map((rule) => {\n const baseUrl = rule.parentStyleSheet\n ? rule.parentStyleSheet.href\n : null;\n return embedResources(rule.cssText, baseUrl, options);\n }));\n return cssTexts.join('\\n');\n}\nexport async function embedWebFonts(clonedNode, options) {\n const cssText = options.fontEmbedCSS != null\n ? options.fontEmbedCSS\n : options.skipFonts\n ? null\n : await getWebFontCSS(clonedNode, options);\n if (cssText) {\n const styleNode = document.createElement('style');\n const sytleContent = document.createTextNode(cssText);\n styleNode.appendChild(sytleContent);\n if (clonedNode.firstChild) {\n clonedNode.insertBefore(styleNode, clonedNode.firstChild);\n }\n else {\n clonedNode.appendChild(styleNode);\n }\n }\n}\n//# sourceMappingURL=embed-webfonts.js.map","import { cloneNode } from './clone-node';\nimport { embedImages } from './embed-images';\nimport { applyStyle } from './apply-style';\nimport { embedWebFonts, getWebFontCSS } from './embed-webfonts';\nimport { getImageSize, getPixelRatio, createImage, canvasToBlob, nodeToDataURL, checkCanvasDimensions, } from './util';\nexport async function toSvg(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const clonedNode = (await cloneNode(node, options, true));\n await embedWebFonts(clonedNode, options);\n await embedImages(clonedNode, options);\n applyStyle(clonedNode, options);\n const datauri = await nodeToDataURL(clonedNode, width, height);\n return datauri;\n}\nexport async function toCanvas(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const svg = await toSvg(node, options);\n const img = await createImage(svg);\n const canvas = document.createElement('canvas');\n const context = canvas.getContext('2d');\n const ratio = options.pixelRatio || getPixelRatio();\n const canvasWidth = options.canvasWidth || width;\n const canvasHeight = options.canvasHeight || height;\n canvas.width = canvasWidth * ratio;\n canvas.height = canvasHeight * ratio;\n if (!options.skipAutoScale) {\n checkCanvasDimensions(canvas);\n }\n canvas.style.width = `${canvasWidth}`;\n canvas.style.height = `${canvasHeight}`;\n if (options.backgroundColor) {\n context.fillStyle = options.backgroundColor;\n context.fillRect(0, 0, canvas.width, canvas.height);\n }\n context.drawImage(img, 0, 0, canvas.width, canvas.height);\n return canvas;\n}\nexport async function toPixelData(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const canvas = await toCanvas(node, options);\n const ctx = canvas.getContext('2d');\n return ctx.getImageData(0, 0, width, height).data;\n}\nexport async function toPng(node, options = {}) {\n const canvas = await toCanvas(node, options);\n return canvas.toDataURL();\n}\nexport async function toJpeg(node, options = {}) {\n const canvas = await toCanvas(node, options);\n return canvas.toDataURL('image/jpeg', options.quality || 1);\n}\nexport async function toBlob(node, options = {}) {\n const canvas = await toCanvas(node, options);\n const blob = await canvasToBlob(canvas);\n return blob;\n}\nexport async function getFontEmbedCSS(node, options = {}) {\n return getWebFontCSS(node, options);\n}\n//# sourceMappingURL=index.js.map","import { toCanvas } from 'html-to-image'\n\nimport { reportError } from './error-reporter'\n\nconst MAX_SIZE = 2 * 1024 * 1024 // 2 MB\n\n/**\n * html-to-image falls back to `imagePlaceholder || ''` when inlining an image\n * fails, and an empty `src` fires `error` rather than `load` — rejecting the\n * whole capture over one CORS-blocked avatar. A real data URL keeps that path\n * on the happy road: the element loads blank and the rest still captures.\n */\nconst TRANSPARENT_PIXEL =\n 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'\n\n/**\n * Walked in order until one fits `MAX_SIZE`, which mirrors the server's\n * `MAX_SCREENSHOT_BYTES`.\n *\n * Quality drops first because the top of the JPEG range costs no legibility.\n * Below ~0.6 it mangles small text, so the raster shrinks instead — a 1x\n * screenshot of a dense page reads better than a 2x one encoded into mush.\n */\nconst ENCODE_LADDER: ReadonlyArray<{ quality: number; scale: number }> = [\n { quality: 0.85, scale: 1 },\n { quality: 0.6, scale: 1 },\n { quality: 0.6, scale: 0.75 },\n { quality: 0.6, scale: 0.5 },\n]\n\nexport interface ScrubConfig {\n strictScrub?: boolean\n redactSelector?: string\n}\n\nexport interface CaptureResult {\n blob: Blob\n redactedCount: number\n redactedSelectors: string[]\n}\n\nconst MASK_CSS =\n 'background:currentColor!important;color:transparent!important;text-shadow:none!important;-webkit-text-fill-color:transparent!important'\n\nconst SENSITIVE_SELECTOR =\n 'input[type=\"password\"],' +\n 'input[autocomplete~=\"cc-number\"],' +\n 'input[autocomplete~=\"cc-csc\"],' +\n 'input[autocomplete~=\"cc-exp\"],' +\n 'input[autocomplete~=\"cc-name\"],' +\n 'input[autocomplete~=\"cc-type\"],' +\n 'input[autocomplete~=\"current-password\"],' +\n 'input[autocomplete~=\"new-password\"],' +\n 'input[autocomplete~=\"one-time-code\"]'\n\nfunction isWithinSafe(el: Element): boolean {\n let node: Element | null = el.parentElement\n while (node) {\n if (node.hasAttribute('data-markup-safe')) return true\n node = node.parentElement\n }\n return false\n}\n\nfunction buildMaskList(cfg: ScrubConfig): Element[] {\n const seen = new Set<Element>()\n const list: Element[] = []\n\n function add(el: Element) {\n if (!seen.has(el)) {\n seen.add(el)\n list.push(el)\n }\n }\n\n // Always mask regardless of data-markup-safe\n for (const el of document.querySelectorAll('[data-markup-private],[data-markup-redact]')) {\n add(el)\n }\n\n // Auto-detect sensitive fields (exempted by data-markup-safe ancestor)\n for (const el of document.querySelectorAll(SENSITIVE_SELECTOR)) {\n if (!isWithinSafe(el)) add(el)\n }\n\n if (cfg.redactSelector) {\n try {\n for (const el of document.querySelectorAll(cfg.redactSelector)) {\n if (!isWithinSafe(el)) add(el)\n }\n } catch (err) {\n // A customer-configuration bug that would otherwise silently produce\n // un-redacted screenshots.\n reportError(err, { context: 'screenshot-redact-selector' })\n }\n }\n\n if (cfg.strictScrub) {\n for (const el of document.querySelectorAll('input,select,textarea')) {\n if (!isWithinSafe(el)) add(el)\n }\n }\n\n return list\n}\n\nfunction applyMask(el: Element): () => void {\n const prev = el.getAttribute('style')\n el.setAttribute('style', prev ? `${prev};${MASK_CSS}` : MASK_CSS)\n return () => {\n if (prev === null) {\n el.removeAttribute('style')\n } else {\n el.setAttribute('style', prev)\n }\n }\n}\n\nfunction selectorFor(el: Element): string {\n if (el.id) return `#${CSS.escape(el.id)}`\n const tag = el.tagName.toLowerCase()\n const type = el.getAttribute('type')\n const name = el.getAttribute('name')\n if (type && name) return `${tag}[type=\"${type}\"][name=\"${name}\"]`\n if (type) return `${tag}[type=\"${type}\"]`\n if (name) return `${tag}[name=\"${name}\"]`\n return tag\n}\n\n/**\n * Masking mutates the live DOM for the duration of the `toCanvas` call only,\n * then restores it.\n *\n * Every null path reports to Sentry, so a caller can treat null as \"failed\"\n * and say so rather than guessing.\n */\nexport async function captureScreenshot(\n excludeEl?: Element | null,\n pin?: { x: number; y: number },\n scrubConfig?: ScrubConfig,\n): Promise<CaptureResult | null> {\n try {\n const w = window.innerWidth\n const h = window.innerHeight\n const pixelRatio = Math.min(window.devicePixelRatio, 2)\n\n const maskList = scrubConfig ? buildMaskList(scrubConfig) : []\n const redactedSelectors = maskList.map(selectorFor)\n const restores = maskList.map(applyMask)\n\n let canvas!: HTMLCanvasElement\n try {\n canvas = await toCanvas(document.documentElement, {\n width: w,\n height: h,\n cacheBust: true,\n backgroundColor: '#ffffff',\n pixelRatio,\n filter(node: Node): boolean {\n if (excludeEl && (node === excludeEl || excludeEl.contains(node))) return false\n if (node instanceof Element && node.hasAttribute('data-markup-skip')) return false\n return true\n },\n imagePlaceholder: TRANSPARENT_PIXEL,\n // For what the placeholder can't rescue, such as an image that\n // fetched but won't decode. One hole beats no screenshot.\n onImageErrorHandler: () => {},\n style: {\n // Otherwise the scroll offset is baked into the capture.\n transform: `translateY(-${window.scrollY}px)`,\n transformOrigin: 'top left',\n },\n })\n } finally {\n for (const restore of restores) restore()\n }\n\n if (pin) {\n const ctx = canvas.getContext('2d')\n if (ctx) drawPin(ctx, pin.x, pin.y, pixelRatio)\n }\n\n const blob = await encodeWithinLimit(canvas)\n if (!blob) return null\n return { blob, redactedCount: redactedSelectors.length, redactedSelectors }\n } catch (err) {\n // Broken stylesheets, or a SecurityError from a tainted canvas. The user\n // gets \"Screenshot unavailable\"; Sentry gets enough to tell a bug in our\n // codepath from host-page state we can't control.\n reportError(err, { context: 'screenshot-capture' })\n return null\n }\n}\n\nfunction canvasToBlob(canvas: HTMLCanvasElement, quality: number): Promise<Blob | null> {\n return new Promise((resolve) => canvas.toBlob(resolve, 'image/jpeg', quality))\n}\n\n/** Redraws `source` at `scale` so the encoder has fewer pixels to fit. */\nfunction downscale(source: HTMLCanvasElement, scale: number): HTMLCanvasElement | null {\n const canvas = document.createElement('canvas')\n canvas.width = Math.max(1, Math.round(source.width * scale))\n canvas.height = Math.max(1, Math.round(source.height * scale))\n const ctx = canvas.getContext('2d')\n if (!ctx) return null\n ctx.imageSmoothingQuality = 'high'\n ctx.drawImage(source, 0, 0, canvas.width, canvas.height)\n return canvas\n}\n\n/**\n * Reports when every rung fails. Without that, a page reliably blowing the cap\n * is indistinguishable from one with screenshots switched off — on screen and\n * in the Sentry inbox alike.\n */\nasync function encodeWithinLimit(canvas: HTMLCanvasElement): Promise<Blob | null> {\n let smallest: number | null = null\n\n for (const { quality, scale } of ENCODE_LADDER) {\n const target = scale === 1 ? canvas : downscale(canvas, scale)\n if (!target) continue\n const blob = await canvasToBlob(target, quality)\n if (!blob) continue\n if (blob.size <= MAX_SIZE) return blob\n smallest = smallest == null ? blob.size : Math.min(smallest, blob.size)\n }\n\n reportError(\n new Error(\n smallest == null\n ? 'Screenshot encode produced no blob at any quality/scale'\n : `Screenshot still ${smallest} bytes at the end of the encode ladder (cap ${MAX_SIZE})`,\n ),\n { context: 'screenshot-encode' },\n )\n return null\n}\n\n// Mirrors the CSS pin: the pointed bottom-left corner sits at the click point\n// and the body extends upward. x/y are viewport coords.\nfunction drawPin(ctx: CanvasRenderingContext2D, x: number, y: number, pixelRatio: number) {\n const pr = pixelRatio\n const size = 28 * pr\n const half = size / 2\n const px = x * pr\n const py = y * pr\n\n ctx.save()\n\n // Matches `box-shadow: 0 0 0 2px paper`.\n const ring = 2 * pr\n ctx.beginPath()\n // Same order as CSS `border-radius`: TL, TR, BR, BL.\n ctx.roundRect(px - ring, py - size - ring, size + ring * 2, size + ring * 2, [\n 14 * pr + ring,\n 14 * pr + ring,\n 14 * pr + ring,\n 4 * pr + ring,\n ])\n ctx.fillStyle = '#ffffff'\n ctx.fill()\n\n // The 4px pointed corner sits exactly at (px, py).\n ctx.beginPath()\n ctx.roundRect(px, py - size, size, size, [14 * pr, 14 * pr, 14 * pr, 4 * pr])\n ctx.fillStyle = '#1a1614'\n ctx.fill()\n\n // Dot — centered in the pin body\n ctx.beginPath()\n ctx.arc(px + half, py - half, 3 * pr, 0, Math.PI * 2)\n ctx.fillStyle = '#e35d2a'\n ctx.fill()\n\n ctx.restore()\n}\n","/**\n * Re-issued well before its server-side TTL, or an in-flight subscription\n * drops mid-session.\n *\n * The apiKey + Origin gate runs at mint time, so it is the token's value that\n * authorizes the WebSocket — a sniffed apiKey alone can't subscribe from an\n * off-allowlist origin.\n *\n * A two-state machine rather than `string | null`, so \"do we have a usable\n * token\" is a fact callers pattern-match on instead of null-check by\n * convention.\n */\n\nimport { useEffect } from 'preact/hooks'\n\nimport { defineMachine, useMachine } from '../lib/machine'\nimport { reportError } from './error-reporter'\nimport type { WidgetApiClient } from './api'\n\ntype TokenState = { kind: 'idle' } | { kind: 'active'; token: string; expiresAt: number }\n\ntype TokenEvent = { type: 'issued'; token: string; expiresAt: number }\n\nconst tokenMachine = defineMachine<TokenState, TokenEvent>({\n idle: {\n issued: (_, e) => ({ kind: 'active', token: e.token, expiresAt: e.expiresAt }),\n },\n active: {\n // The downstream subscription re-binds because the string changes.\n issued: (_, e) => ({ kind: 'active', token: e.token, expiresAt: e.expiresAt }),\n },\n})\n\n/**\n * Refresh ~30 min before expiry, but never sooner than 60s after the\n * last issuance. The floor avoids a tight retry loop in case the server\n * hands back an already-near-expiry token under clock skew, and gives\n * the WebSocket time to settle on the new credential between handoffs.\n */\nconst REFRESH_LEAD_MS = 30 * 60_000\nconst REFRESH_MIN_INTERVAL_MS = 60_000\nconst RETRY_AFTER_FAILURE_MS = 60_000\n\nexport function useSubscriptionToken(api: WidgetApiClient): string | null {\n const [state, send] = useMachine(tokenMachine, { kind: 'idle' })\n\n useEffect(() => {\n let cancelled = false\n let timer: ReturnType<typeof setTimeout> | null = null\n\n async function refresh() {\n try {\n const issued = await api.getSubscriptionToken()\n if (cancelled) return\n send({ type: 'issued', token: issued.token, expiresAt: issued.expiresAt })\n const refreshAfterMs = Math.max(\n REFRESH_MIN_INTERVAL_MS,\n issued.expiresAt - Date.now() - REFRESH_LEAD_MS,\n )\n timer = setTimeout(refresh, refreshAfterMs)\n } catch (err) {\n if (cancelled) return\n // Deliberately don't surface this to the user — if the apiKey/\n // Origin combo is bad the HTTP write paths will fail loudly\n // anyway, and a transient mint failure shouldn't add noise to\n // a UI that's otherwise still usable. But we DO want Sentry to\n // see it: a silent indefinite retry loop is the worst failure\n // mode for an embedded widget (Widget-H3 in the readiness\n // review). TypeError = network/CORS — skip; everything else\n // is structural and worth reporting.\n const name = (err as { name?: unknown } | null)?.name\n if (name !== 'TypeError') {\n reportError(err, { context: 'subscription-token-refresh' })\n }\n timer = setTimeout(refresh, RETRY_AFTER_FAILURE_MS)\n }\n }\n\n refresh()\n return () => {\n cancelled = true\n if (timer) clearTimeout(timer)\n }\n }, [api, send])\n\n return state.kind === 'active' ? state.token : null\n}\n","/**\n * Under `'localStorage'` the refresh token is posted in the body and the new\n * pair comes back as JSON. Under `'cookies'` the body is empty, the browser\n * attaches the HttpOnly refresh cookie, and the response carries only expiries.\n *\n * Every failure — network, 401, 5xx — surfaces as `null`, because the widget's\n * reaction is the same in each case: drop to `recovering` and re-mint anon.\n */\n\nimport { combinedSignal, WRITE_TIMEOUT_MS } from './api'\nimport { reportError } from './error-reporter'\n\nexport type RefreshedTokens =\n | {\n mode: 'localStorage'\n accessToken: string\n accessTokenExpiresAt: number\n refreshToken: string\n refreshTokenExpiresAt: number\n }\n | {\n mode: 'cookies'\n accessTokenExpiresAt: number\n refreshTokenExpiresAt: number\n }\n\nexport async function refreshWidgetTokens(args: {\n apiUrl: string\n apiKey: string\n mode: 'cookies' | 'localStorage'\n /** Required under `'localStorage'`; ignored under `'cookies'`. */\n refreshToken?: string\n /**\n * Composed with a `WRITE_TIMEOUT_MS` deadline rather than used alone: an\n * unmount controller bounds the fetch against the component's lifetime, not\n * the network, so a blackholing proxy would hang for as long as it's mounted.\n */\n signal?: AbortSignal\n}): Promise<RefreshedTokens | null> {\n try {\n const init: RequestInit = {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-markup-api-key': args.apiKey,\n },\n signal: combinedSignal(WRITE_TIMEOUT_MS, args.signal),\n }\n if (args.mode === 'cookies') {\n init.credentials = 'include'\n // The server reads the cookie when the body has no `refreshToken`.\n init.body = '{}'\n } else {\n if (!args.refreshToken) return null\n init.body = JSON.stringify({ refreshToken: args.refreshToken })\n }\n\n const res = await fetch(`${args.apiUrl.replace(/\\/+$/, '')}/widget/refresh`, init)\n if (!res.ok) return null\n const data = (await res.json()) as {\n mode?: unknown\n accessToken?: unknown\n accessTokenExpiresAt?: unknown\n refreshToken?: unknown\n refreshTokenExpiresAt?: unknown\n }\n\n if (data.mode === 'cookies') {\n if (\n typeof data.accessTokenExpiresAt !== 'number' ||\n typeof data.refreshTokenExpiresAt !== 'number'\n ) {\n return null\n }\n return {\n mode: 'cookies',\n accessTokenExpiresAt: data.accessTokenExpiresAt,\n refreshTokenExpiresAt: data.refreshTokenExpiresAt,\n }\n }\n\n // A server that doesn't emit `mode` is a pre-cookies one.\n if (\n typeof data.accessToken !== 'string' ||\n typeof data.accessTokenExpiresAt !== 'number' ||\n typeof data.refreshToken !== 'string' ||\n typeof data.refreshTokenExpiresAt !== 'number'\n ) {\n return null\n }\n return {\n mode: 'localStorage',\n accessToken: data.accessToken,\n accessTokenExpiresAt: data.accessTokenExpiresAt,\n refreshToken: data.refreshToken,\n refreshTokenExpiresAt: data.refreshTokenExpiresAt,\n }\n } catch (err) {\n // Unmount and offline are routine. Anything else is structural — a bad\n // JSON shape, a throw inside the parser.\n const name = (err as { name?: unknown } | null)?.name\n if (name !== 'AbortError' && name !== 'TypeError') {\n reportError(err, { context: 'refresh-token' })\n }\n return null\n }\n}\n","import { useEffect } from 'preact/hooks'\n\nimport { refreshWidgetTokens } from './refresh-token'\nimport type { IdentityState, VerifiedIdentity } from './identity-store'\n\n/**\n * Fires `~REFRESH_LEAD_MS` before the access token expires. Re-runs on every\n * `tokenExpiresAt` change, so the scheduler self-perpetuates as long as the\n * refresh chain stays alive.\n *\n * A no-op for non-verified states, for localStorage identities with no refresh\n * token (the legacy long-lived flow, which keeps its 401-to-anon fallback), and\n * for an already-expired refresh token — that last one surfaces the re-sign-in\n * CTA immediately rather than waiting for the next 401.\n */\nconst REFRESH_LEAD_MS = 60_000 // refresh 60s before expiry\nconst MIN_DELAY_MS = 500 // floor so we don't busy-loop on near-expired tokens\n\nexport function useTokenRefresh(\n identity: IdentityState,\n apiUrl: string,\n apiKey: string,\n onRefreshed: (next: VerifiedIdentity) => void,\n onFailure: () => void,\n): void {\n const isVerified = identity.kind === 'verified'\n const storage = isVerified ? identity.identity.storage : undefined\n const refreshToken = isVerified ? identity.identity.refreshToken : undefined\n const refreshExp = isVerified ? identity.identity.refreshTokenExpiresAt : undefined\n const accessExp = isVerified ? identity.identity.tokenExpiresAt : undefined\n\n useEffect(() => {\n if (!isVerified || refreshExp == null || accessExp == null) return\n // Cookie mode uses the HttpOnly cookie, so only localStorage needs the\n // raw token — and lacking one there means the legacy flow.\n if (storage === 'localStorage' && refreshToken == null) return\n if (storage !== 'cookies' && storage !== 'localStorage') return\n\n const now = Date.now()\n if (refreshExp <= now) {\n // Nothing to try; surface the re-sign-in path now.\n onFailure()\n return\n }\n\n const delay = Math.max(MIN_DELAY_MS, accessExp - REFRESH_LEAD_MS - now)\n const controller = new AbortController()\n\n const timer = window.setTimeout(async () => {\n const next = await refreshWidgetTokens({\n apiUrl,\n apiKey,\n mode: storage,\n refreshToken,\n signal: controller.signal,\n })\n if (controller.signal.aborted) return\n if (!next) {\n onFailure()\n return\n }\n if (identity.kind !== 'verified') return // changed mid-refresh\n if (next.mode === 'cookies') {\n // The tokens stayed in HttpOnly cookies; only the expiries are\n // visible, and updating them is what re-arms the scheduler.\n onRefreshed({\n ...identity.identity,\n tokenExpiresAt: next.accessTokenExpiresAt,\n refreshTokenExpiresAt: next.refreshTokenExpiresAt,\n })\n } else {\n onRefreshed({\n ...identity.identity,\n token: next.accessToken,\n tokenExpiresAt: next.accessTokenExpiresAt,\n refreshToken: next.refreshToken,\n refreshTokenExpiresAt: next.refreshTokenExpiresAt,\n })\n }\n }, delay)\n\n return () => {\n window.clearTimeout(timer)\n controller.abort()\n }\n // `identity` is read in the closure but deliberately not a dep: the\n // scheduler should re-run on the access window changing, not on every\n // identity event.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isVerified, storage, refreshToken, refreshExp, accessExp, apiUrl, apiKey])\n}\n","type ClassValue = string | boolean | null | undefined\n\nexport function cx(...classes: ClassValue[]) {\n return classes.filter(Boolean).join(' ')\n}\n\n/**\n * Labels for the submit/toggle chord, in the vocabulary of the platform\n * the host page is being read on.\n *\n * The handlers accept Cmd *or* Ctrl, so showing `⌘` unconditionally told\n * every Windows and Linux user to press a key their keyboard doesn't\n * have. Centralised because three call sites had grown their own copy of\n * the same `navigator` sniff.\n */\nexport function platformKeys(): { mod: string; enter: string } {\n const isMac =\n typeof navigator !== 'undefined' &&\n /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent)\n return isMac ? { mod: '⌘', enter: '↵' } : { mod: 'Ctrl', enter: 'Enter' }\n}\n","import{options as r,Fragment as e}from\"preact\";export{Fragment}from\"preact\";var t=/[\"&<]/;function n(r){if(0===r.length||!1===t.test(r))return r;for(var e=0,n=0,o=\"\",f=\"\";n<r.length;n++){switch(r.charCodeAt(n)){case 34:f=\""\";break;case 38:f=\"&\";break;case 60:f=\"<\";break;default:continue}n!==e&&(o+=r.slice(e,n)),o+=f,e=n+1}return n!==e&&(o+=r.slice(e,n)),o}var o=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,f=0,i=Array.isArray;function u(e,t,n,o,i,u){t||(t={});var a,c,p=t;if(\"ref\"in p)for(c in p={},t)\"ref\"==c?a=t[c]:p[c]=t[c];var l={type:e,props:p,key:n,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--f,__i:-1,__u:0,__source:i,__self:u};if(\"function\"==typeof e&&(a=e.defaultProps))for(c in a)void 0===p[c]&&(p[c]=a[c]);return r.vnode&&r.vnode(l),l}function a(r){var t=u(e,{tpl:r,exprs:[].slice.call(arguments,1)});return t.key=t.__v,t}var c={},p=/[A-Z]/g;function l(e,t){if(r.attr){var f=r.attr(e,t);if(\"string\"==typeof f)return f}if(t=function(r){return null!==r&&\"object\"==typeof r&&\"function\"==typeof r.valueOf?r.valueOf():r}(t),\"ref\"===e||\"key\"===e)return\"\";if(\"style\"===e&&\"object\"==typeof t){var i=\"\";for(var u in t){var a=t[u];if(null!=a&&\"\"!==a){var l=\"-\"==u[0]?u:c[u]||(c[u]=u.replace(p,\"-$&\").toLowerCase()),s=\";\";\"number\"!=typeof a||l.startsWith(\"--\")||o.test(l)||(s=\"px;\"),i=i+l+\":\"+a+s}}return e+'=\"'+n(i)+'\"'}return null==t||!1===t||\"function\"==typeof t||\"object\"==typeof t?\"\":!0===t?e:e+'=\"'+n(\"\"+t)+'\"'}function s(r){if(null==r||\"boolean\"==typeof r||\"function\"==typeof r)return null;if(\"object\"==typeof r){if(void 0===r.constructor)return r;if(i(r)){for(var e=0;e<r.length;e++)r[e]=s(r[e]);return r}}return n(\"\"+r)}export{u as jsx,l as jsxAttr,u as jsxDEV,s as jsxEscape,a as jsxTemplate,u as jsxs};\n//# sourceMappingURL=jsxRuntime.module.js.map\n","import type { ComponentChildren } from 'preact'\n\n/* Inline SVG icons — beats pulling in an icon library (~10kB saved). */\n\nexport function IconLogo({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 126 126\" fill=\"currentColor\" aria-hidden>\n <path d=\"M63.4561 0.00557731C70.6277 -0.0175584 76.9025 1.04088 83.5898 3.71066C97.7952 9.43043 109.186 20.5001 115.311 34.5359C119.708 44.8002 120.746 54.7869 119.156 65.8171C116.857 82.7956 105.129 98.8382 90.0566 106.846C83.4394 110.362 74.7336 113.029 67.2051 113.271C62.4204 113.425 61.1274 113.32 56.6807 115.204C50.2035 117.858 43.6874 120.417 37.1348 122.879C34.8442 123.763 32.3203 124.902 29.9404 125.51C29.4023 125.648 28.1978 125.009 27.7598 124.646C26.9046 123.951 27.0582 122.505 27.0264 121.484C26.8123 114.646 27.3302 107.458 26.8604 100.656C25.1578 98.6714 22.4026 96.603 20.3086 94.1989C12.1853 84.8731 7.05334 73.9949 6.18164 61.6101C4.95583 46.292 9.97176 31.1285 20.0908 19.5632C29.989 8.13202 44.0369 1.11921 59.1221 0.0788195C60.2694 -0.0356049 62.2637 0.00944821 63.4561 0.00557731ZM92.2676 55.7497C91.5754 39.5314 77.8207 26.9725 61.6064 27.7536C45.5175 28.5287 33.0758 42.1537 33.7627 58.2468C34.4496 74.3398 48.007 86.8553 64.1035 86.2566C80.3254 85.6533 92.9599 71.968 92.2676 55.7497Z\" />\n </svg>\n )\n}\n\nexport function IconClose({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M6.28 5.22a.75.75 0 0 0-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 1 0 1.06 1.06L10 11.06l3.72 3.72a.75.75 0 1 0 1.06-1.06L11.06 10l3.72-3.72a.75.75 0 0 0-1.06-1.06L10 8.94 6.28 5.22Z\" />\n </svg>\n )\n}\n\nexport function IconChevronDown({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden>\n <path d=\"M5.22 7.22a.75.75 0 0 1 1.06 0L10 10.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 8.28a.75.75 0 0 1 0-1.06Z\" />\n </svg>\n )\n}\n\nexport function IconChevronLeft({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden>\n <path d=\"M12.78 5.22a.75.75 0 0 1 0 1.06L9.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z\" />\n </svg>\n )\n}\n\nexport function IconEllipsis({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M3 10a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0ZM8.5 10a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0ZM15.5 8.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Z\" />\n </svg>\n )\n}\n\nexport function IconCheck({ size = 16 }: { size?: number }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n fill=\"currentColor\"\n viewBox=\"0 0 256 256\"\n >\n <path d=\"M173.66,98.34a8,8,0,0,1,0,11.32l-56,56a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35A8,8,0,0,1,173.66,98.34ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z\"></path>\n </svg>\n )\n}\n\nexport function IconCamera({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden>\n <path\n fill-rule=\"evenodd\"\n d=\"M1 8a2 2 0 0 1 2-2h.93a2 2 0 0 0 1.664-.89l.812-1.22A2 2 0 0 1 8.07 3h3.86a2 2 0 0 1 1.664.89l.812 1.22A2 2 0 0 0 16.07 6H17a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8Zm13.5 3a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0ZM10 14a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n )\n}\n\nexport function IconSend({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M2.87 2.298a.75.75 0 0 0-.812 1.021L3.39 6.624a1 1 0 0 0 .928.626H8.25a.75.75 0 0 1 0 1.5H4.318a1 1 0 0 0-.927.626l-1.333 3.305a.75.75 0 0 0 .811 1.022 24.89 24.89 0 0 0 11.668-5.115.75.75 0 0 0 0-1.175A24.89 24.89 0 0 0 2.869 2.298Z\" />\n </svg>\n )\n}\n\nexport function IconSmile({ size = 16 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 256 256\" fill=\"currentColor\" aria-hidden>\n <path d=\"M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216ZM80,108a12,12,0,1,1,12,12A12,12,0,0,1,80,108Zm96,0a12,12,0,1,1-12-12A12,12,0,0,1,176,108Zm-1.07,48c-10.29,17.79-27.4,28-46.93,28s-36.63-10.2-46.92-28a8,8,0,1,1,13.84-8c7.47,12.91,19.21,20,33.08,20s25.61-7.1,33.07-20a8,8,0,0,1,13.86,8Z\"></path>\n </svg>\n )\n}\n\n/* ──────────── New toolbar/menu icons (24x24 stroke set) ──────────── */\n\nfunction Stroke({ size = 16, children }: { size?: number; children: ComponentChildren }) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width={1.75}\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden\n >\n {children}\n </svg>\n )\n}\n\nexport function IconComment({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M21 11.5a8.4 8.4 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.4 8.4 0 0 1-3.8-.9L3 21l1.9-5.7a8.4 8.4 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.4 8.4 0 0 1 3.8-.9h.5a8.5 8.5 0 0 1 8 8v.5z\" />\n </Stroke>\n )\n}\n\nexport function IconInbox({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M22 12h-6l-2 3h-4l-2-3H2\" />\n <path d=\"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\" />\n </Stroke>\n )\n}\n\nexport function IconEye({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z\" />\n <circle cx=\"12\" cy=\"12\" r=\"2.5\" />\n </Stroke>\n )\n}\n\nexport function IconEyeOff({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M17.94 17.94A10.7 10.7 0 0 1 12 19c-6.5 0-10-7-10-7a18.5 18.5 0 0 1 5.06-5.94\" />\n <path d=\"M9.9 4.24A10.7 10.7 0 0 1 12 4c6.5 0 10 7 10 7a18.5 18.5 0 0 1-2.16 3.19\" />\n <path d=\"m1 1 22 22\" />\n <path d=\"M14.12 14.12a3 3 0 0 1-4.24-4.24\" />\n </Stroke>\n )\n}\n\nexport function IconMenu({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M3 6h18M3 12h18M3 18h18\" />\n </Stroke>\n )\n}\n\nexport function IconSun({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41\" />\n </Stroke>\n )\n}\n\nexport function IconMoon({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3a7 7 0 0 0 9.79 9.79z\" />\n </Stroke>\n )\n}\n\nexport function IconMonitor({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" />\n <path d=\"M8 21h8M12 17v4\" />\n </Stroke>\n )\n}\n\nexport function IconShield({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M12 22s8-3.5 8-10V5l-8-3-8 3v7c0 6.5 8 10 8 10z\" />\n </Stroke>\n )\n}\n\nexport function IconKeyboard({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <rect x=\"2\" y=\"6\" width=\"20\" height=\"12\" rx=\"2\" />\n <path d=\"M6 10h.01M10 10h.01M14 10h.01M18 10h.01M6 14h.01M18 14h.01M10 14h4\" />\n </Stroke>\n )\n}\n\nexport function IconEyeSlash({ size = 16 }: { size?: number }) {\n return IconEyeOff({ size })\n}\n\nexport function IconLogIn({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\" />\n <path d=\"M10 17l5-5-5-5M15 12H3\" />\n </Stroke>\n )\n}\n\nexport function IconLogOut({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <path d=\"M16 17l5-5-5-5M21 12H9\" />\n </Stroke>\n )\n}\n\nexport function IconUser({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <circle cx=\"12\" cy=\"8\" r=\"4\" />\n <path d=\"M4 21a8 8 0 0 1 16 0\" />\n </Stroke>\n )\n}\n\n/**\n * Marks agent-authored comments. Traced from the same Lucide `bot` glyph\n * the dashboard's OAuth authorize screen uses, so the badge on an agent's\n * reply matches the icon shown when its access was granted.\n */\nexport function IconBot({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M12 8V4H8\" />\n <rect x=\"4\" y=\"8\" width=\"16\" height=\"12\" rx=\"2\" />\n <path d=\"M2 14h2\" />\n <path d=\"M20 14h2\" />\n <path d=\"M15 13v2\" />\n <path d=\"M9 13v2\" />\n </Stroke>\n )\n}\n\nexport function IconExternal({ size = 16 }: { size?: number }) {\n return (\n <Stroke size={size}>\n <path d=\"M15 3h6v6\" />\n <path d=\"M10 14 21 3\" />\n <path d=\"M21 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5\" />\n </Stroke>\n )\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\n\nimport { displayNameOf, type IdentityState } from '../identity-store'\nimport { cx } from '../utils'\nimport { IconExternal, IconLogIn, IconLogOut, IconUser } from './icons'\n\ntype ToolbarPosition = 'bottom-right' | 'bottom-left' | 'bottom-center'\n\n/**\n * Identity menu — anchored to the avatar/name button inside the toolbar\n * pill. Two presentation modes:\n *\n * - **Anonymous** (`identity.kind !== 'verified'`): a sign-in CTA card\n * with a primary button and a forget-me secondary action. The\n * popover is intentionally compact and focused — no surface-level\n * \"Notifications\" or \"Account\" entries to crowd the verified case.\n *\n * - **Verified**: name + email card, then Account link (if a\n * dashboardUrl is configured) and Sign out (with arm-then-confirm).\n *\n * Light-dismiss matches the OverflowMenu pattern: document-level\n * capture listener on click + Escape, using `composedPath()` so it\n * detects inside-shadow targets correctly.\n */\nexport function IdentityMenu({\n identity,\n position,\n isSigningIn,\n isSigningOut,\n dashboardUrl,\n onSignIn,\n onSignOut,\n onForgetMe,\n}: {\n identity: IdentityState\n position: ToolbarPosition\n isSigningIn: boolean\n isSigningOut: boolean\n dashboardUrl?: string\n onSignIn: () => void\n onSignOut: () => void\n onForgetMe: () => void\n}) {\n const [open, setOpen] = useState(false)\n const [confirmForget, setConfirmForget] = useState(false)\n const [confirmSignOut, setConfirmSignOut] = useState(false)\n const containerRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n if (!open) return\n function onDocClick(e: MouseEvent) {\n const container = containerRef.current\n if (!container) return\n if (!e.composedPath().includes(container)) setOpen(false)\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') setOpen(false)\n }\n document.addEventListener('click', onDocClick, true)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('click', onDocClick, true)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n useEffect(() => {\n if (!open) {\n setConfirmForget(false)\n setConfirmSignOut(false)\n }\n }, [open])\n\n const name = displayNameOf(identity)\n const initials = nameInitials(name)\n const isVerified = identity.kind === 'verified'\n const image = identity.kind === 'verified' ? identity.identity.image : undefined\n // The picture is third-party-hosted, so a host CSP or a rotated URL can\n // fail it. Track the URL that failed rather than a bare flag, so a later\n // sign-in as someone else gets a fresh chance.\n const [failedImage, setFailedImage] = useState<string | null>(null)\n const showImage = isVerified && image != null && failedImage !== image\n const email = isVerified ? identity.identity.email : null\n\n const anchorClass =\n position === 'bottom-left'\n ? 'is-anchor-left'\n : position === 'bottom-center'\n ? 'is-anchor-center'\n : 'is-anchor-right'\n\n return (\n <div ref={containerRef} style={{ position: 'relative', display: 'inline-flex' }}>\n <button\n type=\"button\"\n class=\"markup-tb-btn markup-id-btn\"\n data-kind=\"identity\"\n data-on={open ? 'true' : undefined}\n data-anon={isVerified ? undefined : 'true'}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-label={isVerified ? `Signed in as ${name ?? 'you'}` : 'Sign in'}\n title={name ?? (isVerified ? 'Account' : 'Sign in')}\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n setOpen((v) => !v)\n }}\n >\n <span class={cx('markup-tb-avatar', !isVerified && 'is-anon')} aria-hidden=\"true\">\n {showImage ? (\n <img\n class=\"markup-avatar-img\"\n src={image}\n alt=\"\"\n decoding=\"async\"\n referrerpolicy=\"no-referrer\"\n onError={() => setFailedImage(image)}\n />\n ) : isVerified && initials ? (\n // Wrapped rather than bare text so `.markup-avatar-initials`\n // has an element to trim — see the rule in styles.css.\n <span class=\"markup-avatar-initials\">{initials}</span>\n ) : (\n <IconUser size={14} />\n )}\n </span>\n {isVerified && name ? <span class=\"markup-sr-only\">{name}</span> : null}\n </button>\n\n {open ? (\n <div class={cx('markup-pop', anchorClass)} data-pop=\"identity\" role=\"menu\">\n {isVerified ? (\n <>\n <div class=\"markup-id-who\">\n <span class=\"nm\">{name ?? 'Account'}</span>\n {email ? <span class=\"em\">{email}</span> : null}\n </div>\n {dashboardUrl ? (\n <a\n role=\"menuitem\"\n class=\"markup-menu-row\"\n href={dashboardUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={() => setOpen(false)}\n >\n <span class=\"ic\">\n <IconExternal size={16} />\n </span>\n <span class=\"lbl\">Account</span>\n </a>\n ) : null}\n <button\n type=\"button\"\n role=\"menuitem\"\n class={cx('markup-menu-row', confirmSignOut && 'is-danger')}\n disabled={isSigningOut}\n onClick={() => {\n if (confirmSignOut) {\n setOpen(false)\n onSignOut()\n } else {\n setConfirmSignOut(true)\n }\n }}\n >\n <span class=\"ic\">\n <IconLogOut size={16} />\n </span>\n <span class=\"lbl\">\n {isSigningOut\n ? 'Signing out…'\n : confirmSignOut\n ? 'Confirm: sign out of this site'\n : 'Sign out'}\n </span>\n </button>\n </>\n ) : (\n <div class=\"markup-id-anon\">\n <div class=\"h\">Sign in to Markup</div>\n <div class=\"sub\">\n Get notified when teammates reply and access your inbox across projects.\n </div>\n <button\n type=\"button\"\n disabled={isSigningIn}\n onClick={() => {\n // Close synchronously so the OAuth popup isn't competing for focus.\n setOpen(false)\n onSignIn()\n }}\n >\n <IconLogIn size={14} />\n <span>{isSigningIn ? 'Signing in…' : 'Sign in'}</span>\n </button>\n <button\n type=\"button\"\n class={cx('markup-menu-row', confirmForget && 'is-danger')}\n onClick={() => {\n if (confirmForget) {\n setOpen(false)\n onForgetMe()\n } else {\n setConfirmForget(true)\n }\n }}\n style={{ marginTop: '2px' }}\n >\n <span class=\"lbl\">\n {confirmForget\n ? 'Confirm: comments stay, name and email cleared'\n : 'Forget me on this site…'}\n </span>\n </button>\n </div>\n )}\n </div>\n ) : null}\n </div>\n )\n}\n\nfunction nameInitials(name: string | null): string | null {\n if (!name) return null\n const parts = name.trim().split(/\\s+/).slice(0, 2)\n const letters = parts.map((p) => p[0]?.toUpperCase() ?? '').join('')\n return letters || null\n}\n","import type { RefObject } from 'preact'\nimport { useCallback, useRef, useState } from 'preact/hooks'\n\n/**\n * `onEnd` fires only on a clean pointerup past the threshold; `onCancel` fires\n * on pointercancel, after bookkeeping is already reset.\n *\n * Deliberately no click-suppression helper: no current caller co-locates a\n * click handler with the drag handle. One that did would have to suppress the\n * synthesized click following a threshold-crossing pointerup itself.\n */\nexport interface UseDragOpts {\n /** Lets the popover headers skip the drag for a pointer on a button. */\n shouldStart?: (e: PointerEvent) => boolean\n /**\n * Only needed when the handle is a sub-region of the thing being dragged, as\n * with a popover header — otherwise `e.currentTarget` is measured.\n */\n targetRef?: RefObject<HTMLElement>\n /** Called once when the pointer first crosses the threshold. */\n onStart?: () => void\n /** Streamed during the drag with viewport-clamped coords. */\n onMove: (coords: { left: number; top: number }) => void\n /** Only past the threshold, and never on pointercancel. */\n onEnd?: (coords: { left: number; top: number }, ev: PointerEvent) => void\n /** Called on pointercancel (no follow-up click expected). */\n onCancel?: () => void\n /** Defaults to 4px. */\n threshold?: number\n /** Margin from the viewport edge when clamping coords. Default 8. */\n margin?: number\n /** So a host page's outside-click handler doesn't read a drag as dismiss. */\n stopPropagation?: boolean\n /**\n * Needed alongside `stopPropagation`: Radix's `DismissableLayer` listens in\n * capture phase, so stopping propagation on bubble is too late. It does bail\n * on `defaultPrevented`, which is what this buys.\n */\n preventDefault?: boolean\n}\n\nexport interface UseDragReturn {\n onPointerDown: (e: PointerEvent) => void\n /** True between threshold-crossed and pointerup/cancel. */\n isDragging: boolean\n}\n\nexport function useDrag(opts: UseDragOpts): UseDragReturn {\n // Keeps `onPointerDown` stable even when callers pass inline callbacks.\n const optsRef = useRef(opts)\n optsRef.current = opts\n\n const [isDragging, setIsDragging] = useState(false)\n\n const onPointerDown = useCallback((e: PointerEvent) => {\n const o = optsRef.current\n if (o.preventDefault) e.preventDefault()\n if (o.stopPropagation) e.stopPropagation()\n if (e.button !== 0) return\n if (o.shouldStart && !o.shouldStart(e)) return\n\n const handle = e.currentTarget as HTMLElement | null\n if (!handle) return\n // The handle receives the events; the target is what gets measured. They\n // differ for a popover header dragging its popover.\n const target = o.targetRef?.current ?? handle\n const rect = target.getBoundingClientRect()\n const startX = e.clientX\n const startY = e.clientY\n const baseLeft = rect.left\n const baseTop = rect.top\n const w = rect.width\n const h = rect.height\n const threshold = o.threshold ?? 4\n const margin = o.margin ?? 8\n const pointerId = e.pointerId\n let started = false\n let lastCoords: { left: number; top: number } | null = null\n\n try {\n handle.setPointerCapture(pointerId)\n } catch {\n /* capture unsupported — fall back to bubbling events */\n }\n\n function teardown() {\n try {\n handle?.releasePointerCapture(pointerId)\n } catch {\n /* ignore */\n }\n handle?.removeEventListener('pointermove', onMove)\n handle?.removeEventListener('pointerup', onPointerUp)\n handle?.removeEventListener('pointercancel', onPointerCancel)\n setIsDragging(false)\n }\n\n function onMove(ev: PointerEvent) {\n if (ev.pointerId !== pointerId) return\n const dx = ev.clientX - startX\n const dy = ev.clientY - startY\n if (!started) {\n if (Math.abs(dx) + Math.abs(dy) < threshold) return\n started = true\n setIsDragging(true)\n optsRef.current.onStart?.()\n }\n const maxLeft = Math.max(margin, window.innerWidth - w - margin)\n const maxTop = Math.max(margin, window.innerHeight - h - margin)\n const coords = {\n left: clamp(baseLeft + dx, margin, maxLeft),\n top: clamp(baseTop + dy, margin, maxTop),\n }\n lastCoords = coords\n optsRef.current.onMove(coords)\n }\n\n function onPointerUp(ev: PointerEvent) {\n if (ev.pointerId !== pointerId) return\n teardown()\n if (started && lastCoords) optsRef.current.onEnd?.(lastCoords, ev)\n }\n\n function onPointerCancel(ev: PointerEvent) {\n if (ev.pointerId !== pointerId) return\n teardown()\n optsRef.current.onCancel?.()\n }\n\n handle.addEventListener('pointermove', onMove)\n handle.addEventListener('pointerup', onPointerUp)\n handle.addEventListener('pointercancel', onPointerCancel)\n }, [])\n\n return { onPointerDown, isDragging }\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value))\n}\n","import type { RefObject } from 'preact'\nimport { useEffect } from 'preact/hooks'\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',')\n\n/**\n * Trap Tab focus inside `ref`. Pressing Tab on the last focusable element\n * wraps to the first; Shift+Tab on the first wraps to the last. The\n * Popover API doesn't trap focus on its own (popovers are non-modal), so\n * we layer this on top.\n *\n * `getRootNode()` is used to read `activeElement` correctly when the\n * popover lives inside a shadow root.\n */\nexport function useFocusTrap(ref: RefObject<HTMLElement>, enabled: boolean): void {\n useEffect(() => {\n if (!enabled) return\n const root = ref.current\n if (!root) return\n\n function onKey(e: KeyboardEvent) {\n if (e.key !== 'Tab') return\n const focusables = Array.from(root!.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR))\n const first = focusables[0]\n const last = focusables[focusables.length - 1]\n if (!first || !last) return\n\n const r = root!.getRootNode()\n const active = r instanceof ShadowRoot ? r.activeElement : document.activeElement\n\n if (e.shiftKey ? active === first : active === last) {\n e.preventDefault()\n ;(e.shiftKey ? last : first).focus()\n }\n }\n\n root.addEventListener('keydown', onKey)\n return () => root.removeEventListener('keydown', onKey)\n }, [ref, enabled])\n}\n","import { useEffect, useState } from 'preact/hooks'\n\n/**\n * Wrap a `Blob` in an object URL for the lifetime of the calling\n * component (or until the blob changes). The previous URL is revoked\n * automatically and the state is reset to `null` when the blob is\n * cleared, so consumers can render an `<img src={url ?? ''}>` without\n * worrying about a dangling revoked URL.\n *\n * The new-thread popover is the only consumer today, but the pattern\n * shows up whenever a transient blob (clipboard paste, drag-drop) needs\n * to be rendered. Keeping this in one place makes adding a second\n * caller free.\n */\nexport function useObjectURL(blob: Blob | null): string | null {\n const [url, setUrl] = useState<string | null>(null)\n\n useEffect(() => {\n if (!blob) {\n setUrl(null)\n return\n }\n const next = URL.createObjectURL(blob)\n setUrl(next)\n return () => URL.revokeObjectURL(next)\n }, [blob])\n\n return url\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\n\n/**\n * One-time identity capture. Shown the first time a user wants to post.\n *\n * Two paths:\n * - Sign in via the dashboard (popup) — verified \"team\" identity.\n * - Type name + email manually — anonymous identity, persisted to host\n * localStorage so this is asked at most once per site.\n *\n * `isConnecting` reflects \"the host hasn't resolved an identity yet\" —\n * either first-load anon mint is still in flight or we're recovering\n * from a 401 by minting a replacement. The guest path needs a signed\n * identity to attach the post to, so the inputs are disabled with a\n * hint until that resolves. The popup sign-in path is independent of\n * the anon mint, so its button stays enabled.\n */\nexport function AuthorPrompt({\n isPending,\n isConnecting = false,\n isSigningIn = false,\n onSubmit,\n onCancel,\n onSignIn,\n}: {\n isPending: boolean\n isConnecting?: boolean\n /** A popup sign-in is in flight — keep the user from launching another. */\n isSigningIn?: boolean\n onSubmit: (name: string, email?: string) => void\n onCancel: () => void\n onSignIn?: () => void\n}) {\n const [name, setName] = useState('')\n const [email, setEmail] = useState('')\n const ref = useRef<HTMLInputElement>(null)\n\n useEffect(() => {\n ref.current?.focus()\n }, [])\n\n function handleSubmit(e?: Event) {\n e?.preventDefault()\n const trimmedName = name.trim()\n if (!trimmedName || isPending || isConnecting) return\n const trimmedEmail = email.trim()\n onSubmit(trimmedName, trimmedEmail || undefined)\n }\n\n const guestDisabled = isPending || isConnecting\n\n return (\n <form class=\"markup-author-prompt\" onSubmit={handleSubmit}>\n {onSignIn ? (\n <>\n <button\n type=\"button\"\n class=\"markup-btn markup-btn-primary\"\n onClick={onSignIn}\n disabled={isPending || isSigningIn}\n >\n {isSigningIn ? 'Signing in…' : 'Sign in with Markup'}\n </button>\n <p class=\"markup-author-divider\">or continue as a guest</p>\n </>\n ) : (\n <p class=\"markup-eyebrow\">who's leaving feedback?</p>\n )}\n <input\n ref={ref}\n class=\"markup-input\"\n type=\"text\"\n name=\"name\"\n placeholder=\"Your name\"\n value={name}\n maxLength={80}\n autoComplete=\"name\"\n onInput={(e) => setName((e.currentTarget as HTMLInputElement).value)}\n disabled={guestDisabled}\n data-1p-ignore\n />\n <input\n class=\"markup-input\"\n type=\"email\"\n name=\"email\"\n placeholder=\"Email (optional)\"\n value={email}\n maxLength={254}\n autoComplete=\"email\"\n onInput={(e) => setEmail((e.currentTarget as HTMLInputElement).value)}\n disabled={guestDisabled}\n data-1p-ignore\n />\n {isConnecting ? (\n <p class=\"markup-author-status\" role=\"status\" aria-live=\"polite\">\n Connecting…\n </p>\n ) : null}\n <div class=\"markup-composer-actions\">\n <button\n type=\"button\"\n class=\"markup-btn markup-btn-ghost\"\n onClick={onCancel}\n disabled={isPending}\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n class=\"markup-btn markup-btn-primary\"\n disabled={!name.trim() || guestDisabled}\n >\n Continue\n </button>\n </div>\n </form>\n )\n}\n","/**\n * A contenteditable host rather than a `<textarea>`: the wire format for a\n * mention is `@[Display Name](userId)`, which a textarea can only show\n * verbatim — brackets, parens and an opaque id mid-sentence. Contenteditable\n * lets each mention render as a chip the browser treats as one atomic unit\n * (`contenteditable=\"false\"`, so Backspace removes the whole thing) while the\n * text around it stays ordinary text.\n *\n * The DOM is the source of truth for the draft. `serializeMentionDom`\n * walks it back to the wire format after every input, which means paste,\n * chip deletion, and multi-line edits all stay in sync without the\n * controller tracking offsets. Nothing here imports Preact — the\n * framework wrapper (`ui/mention-input.tsx`) owns only the picker overlay\n * and prop plumbing.\n *\n * `apps/dashboard/src/lib/mention-input.ts` is the dashboard's copy of\n * this file. They can't import each other (published browser bundle vs.\n * app source), so keep them in lockstep — same reason the mention regex\n * itself is duplicated in three places. See `../lib/mentions.ts`.\n */\n\nimport { detectMentionTrigger, mentionMarkerFor, parseMentionTokens } from '../lib/mentions'\nimport type { MentionTriggerState } from '../lib/mentions'\n\nexport type MentionMember = { userId: string; name: string }\n\n/** Present on chip elements; its value is the userId the chip encodes. */\nexport const MENTION_UID_ATTR = 'data-markup-mention'\n/**\n * The display name exactly as picked. Read in preference to the chip's\n * `textContent` so serialization survives a chip whose visible label the\n * user managed to partially overtype.\n */\nexport const MENTION_NAME_ATTR = 'data-markup-mention-name'\n\n/**\n * Tags an engine may wrap a line in when the user presses Enter (Chrome\n * reaches for `div`, WebKit sometimes `div`/`p`). `plaintext-only` avoids\n * them, but Gecko only shipped that recently, so serialization treats the\n * boundary as a newline rather than flattening two lines together.\n */\nconst BLOCK_TAGS = new Set(['DIV', 'P', 'LI', 'BLOCKQUOTE', 'PRE'])\n\nconst TEXT_NODE = 3\nconst ELEMENT_NODE = 1\n\n/* ────────────────────────── serialize ────────────────────────── */\n\n/** Text nodes verbatim, chips to `@[Name](userId)`, line breaks to `\\n`. */\nexport function serializeMentionDom(root: HTMLElement): string {\n let out = ''\n\n const visit = (parent: Node) => {\n const children = parent.childNodes\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n if (!child) continue\n\n if (child.nodeType === TEXT_NODE) {\n out += (child as Text).data\n continue\n }\n if (child.nodeType !== ELEMENT_NODE) continue\n const el = child as HTMLElement\n\n const uid = el.getAttribute(MENTION_UID_ATTR)\n if (uid) {\n const name = chipName(el)\n out += mentionMarkerFor({ userId: uid, name }) ?? `@${name}`\n continue\n }\n\n if (el.tagName === 'BR') {\n // Engines park a bogus trailing <br> so the final line stays\n // focusable. Scaffolding, not something the author typed.\n const isTrailingScaffold = parent === root && i === children.length - 1\n if (!isTrailingScaffold) out += '\\n'\n continue\n }\n\n if (BLOCK_TAGS.has(el.tagName) && out !== '' && !out.endsWith('\\n')) out += '\\n'\n visit(el)\n }\n }\n\n visit(root)\n return out\n}\n\nfunction chipName(el: HTMLElement): string {\n const authored = el.getAttribute(MENTION_NAME_ATTR)\n if (authored) return authored\n return (el.textContent ?? '').replace(/^@/, '')\n}\n\n/* ────────────────────────── deserialize ────────────────────────── */\n\nexport function createMentionChip(\n doc: Document,\n member: MentionMember,\n chipClass: string,\n): HTMLElement {\n const chip = doc.createElement('span')\n chip.className = chipClass\n // What makes the browser treat the chip as one unit for caret movement\n // and deletion, for free.\n chip.setAttribute('contenteditable', 'false')\n chip.setAttribute(MENTION_UID_ATTR, member.userId)\n chip.setAttribute(MENTION_NAME_ATTR, member.name)\n chip.textContent = `@${member.name}`\n return chip\n}\n\n/**\n * Newlines stay inside text nodes rather than becoming `<br>`, which keeps a\n * line contiguous and so keeps trigger detection on a single text node.\n */\nexport function renderMentionNodes(\n doc: Document,\n body: string,\n chipClass: string,\n): DocumentFragment {\n const frag = doc.createDocumentFragment()\n for (const token of parseMentionTokens(body)) {\n if (token.type === 'text') {\n if (token.value) frag.appendChild(doc.createTextNode(token.value))\n continue\n }\n frag.appendChild(createMentionChip(doc, { userId: token.userId, name: token.name }, chipClass))\n }\n return frag\n}\n\n/* ────────────────────────── selection ────────────────────────── */\n\n/**\n * Behind a shadow root `document.getSelection()` retargets to the host on\n * Chromium and WebKit, so the caret's real text node is only reachable via the\n * non-standard `ShadowRoot.getSelection()`. Gecko has no such method but does\n * pierce shadow boundaries. Root first, document second covers all three, and\n * collapses to the plain document path when there's no\n * shadow root at all (the dashboard).\n */\nfunction selectionFor(root: HTMLElement): Selection | null {\n const owner = root.getRootNode() as { getSelection?: () => Selection | null }\n if (typeof owner.getSelection === 'function') return owner.getSelection()\n return root.ownerDocument.getSelection()\n}\n\ntype Caret = { node: Text; offset: number }\n\n/**\n * Excludes a caret inside a chip: its label isn't editable text, and treating\n * it as real would let the chip's leading `@` reopen the picker on its own name.\n */\nfunction caretIn(root: HTMLElement): Caret | null {\n const sel = selectionFor(root)\n if (!sel || sel.rangeCount === 0 || !sel.isCollapsed) return null\n const node = sel.focusNode\n if (!node || node.nodeType !== TEXT_NODE || !root.contains(node)) return null\n if (chipAncestor(node, root)) return null\n return { node: node as Text, offset: sel.focusOffset }\n}\n\n/** The chip element containing `node`, if any. */\nfunction chipAncestor(node: Node, root: HTMLElement): HTMLElement | null {\n let cur: Node | null = node\n while (cur && cur !== root) {\n if (cur.nodeType === ELEMENT_NODE && (cur as HTMLElement).hasAttribute(MENTION_UID_ATTR)) {\n return cur as HTMLElement\n }\n cur = cur.parentNode\n }\n return null\n}\n\n/**\n * Chips are `contenteditable=\"false\"`, so a caret inside one silently refuses\n * every keystroke — and that is exactly where a click lands when the line ends\n * with a chip, i.e. whenever you edit a comment finishing in a mention. The\n * empty text node gives the caret somewhere legal to sit without changing what\n * the body serializes to, so it can't trip the wrapper's `value` reconciliation.\n */\nfunction nudgeCaretOutOfChip(root: HTMLElement): void {\n const sel = selectionFor(root)\n if (!sel || sel.rangeCount === 0 || !sel.isCollapsed) return\n const node = sel.focusNode\n if (!node || !root.contains(node)) return\n const chip = chipAncestor(node, root)\n if (!chip) return\n\n let after = chip.nextSibling\n if (!after || after.nodeType !== TEXT_NODE) {\n after = root.ownerDocument.createTextNode('')\n chip.parentNode?.insertBefore(after, chip.nextSibling)\n }\n setCaret(root, after, 0)\n}\n\nfunction setCaret(root: HTMLElement, node: Node, offset: number): void {\n const sel = selectionFor(root)\n if (!sel) return\n const range = root.ownerDocument.createRange()\n range.setStart(node, offset)\n range.collapse(true)\n sel.removeAllRanges()\n sel.addRange(range)\n}\n\n/** Offsets are node-local: a chip is an element boundary a trigger can't span. */\ntype ActiveTrigger = MentionTriggerState & { textNode: Text }\n\nfunction triggerAt(caret: Caret): ActiveTrigger | null {\n const state = detectMentionTrigger(caret.node.data, caret.offset)\n return state ? { ...state, textNode: caret.node } : null\n}\n\n/* ────────────────────────── edits ────────────────────────── */\n\nfunction insertChipAtTrigger(\n root: HTMLElement,\n trigger: ActiveTrigger,\n member: MentionMember,\n chipClass: string,\n): boolean {\n if (mentionMarkerFor(member) == null) return false\n const text = trigger.textNode\n if (!root.contains(text)) return false\n const parent = text.parentNode\n if (!parent) return false\n if (trigger.caret > text.data.length) return false\n\n // Split where the query was, so the chip lands exactly there.\n text.deleteData(trigger.at, trigger.caret - trigger.at)\n const after = text.splitText(trigger.at)\n parent.insertBefore(createMentionChip(root.ownerDocument, member, chipClass), after)\n // Normalised to exactly one space, so back-to-back mentions don't pile up\n // separators. The caret lands past it, ready to keep typing.\n if (!after.data.startsWith(' ')) after.insertData(0, ' ')\n setCaret(root, after, 1)\n return true\n}\n\n/**\n * Inserts into the caret's existing text node rather than appending a new one,\n * so pasting into the middle of `@ali|` leaves the trigger intact.\n */\nfunction insertPlainText(root: HTMLElement, text: string): void {\n const sel = selectionFor(root)\n if (!sel || sel.rangeCount === 0) return\n const range = sel.getRangeAt(0)\n if (!root.contains(range.commonAncestorContainer)) return\n range.deleteContents()\n\n const { startContainer, startOffset } = range\n if (startContainer.nodeType === TEXT_NODE) {\n const node = startContainer as Text\n node.insertData(startOffset, text)\n setCaret(root, node, startOffset + text.length)\n return\n }\n const node = root.ownerDocument.createTextNode(text)\n range.insertNode(node)\n setCaret(root, node, node.data.length)\n}\n\n/* ────────────────────────── controller ────────────────────────── */\n\nexport type MentionInputController = {\n /** The draft in wire format, serialized live from the DOM. */\n getValue(): string\n /** Only for changes the editor didn't make. */\n setValue(body: string): void\n /** Focus with the caret parked at the end of the draft. */\n focus(): void\n /** Inserts a chip at the open trigger. No-op when none is open. */\n insertMention(member: MentionMember): void\n /** Recomputes the trigger from the live caret. */\n syncTrigger(): void\n /** Without suppressing it: the next caret sync may legitimately re-open. */\n clearTrigger(): void\n /**\n * Closes the picker and keeps it closed for as long as the caret stays\n * inside *this* `@`. For an explicit dismissal (Escape).\n */\n dismissTrigger(): void\n destroy(): void\n}\n\nexport type MentionInputOptions = {\n /** Class applied to chip elements. */\n chipClass: string\n initialValue?: string\n onChange: (body: string) => void\n onTriggerChange: (trigger: MentionTriggerState | null) => void\n /**\n * Checked before any trigger work so a host with no mentionable\n * members never opens a picker. A callback rather than a boolean\n * because the member list arrives asynchronously.\n */\n mentionsEnabled: () => boolean\n}\n\nexport function attachMentionInput(\n el: HTMLElement,\n opts: MentionInputOptions,\n): MentionInputController {\n const doc = el.ownerDocument\n let trigger: ActiveTrigger | null = null\n /**\n * The `@` the user dismissed with Escape, if any. Without this the\n * picker springs straight back open: Escape clears the trigger, then\n * the very next `keyup` re-detects the same `@` from the unchanged\n * caret. Suppression lasts as long as the caret stays inside that same\n * `@`, so someone typing a literal \"@ me later\" is left alone, while\n * moving away and starting a new mention works normally.\n */\n let dismissed: { node: Text; at: number } | null = null\n let isEmpty = true\n\n function markEmpty(value: string) {\n const next = value.length === 0\n if (next === isEmpty && el.hasAttribute('data-empty') === next) return\n isEmpty = next\n el.toggleAttribute('data-empty', next)\n }\n\n function emit() {\n const next = serializeMentionDom(el)\n markEmpty(next)\n opts.onChange(next)\n }\n\n function publishTrigger(next: ActiveTrigger | null) {\n const prev = trigger\n trigger = next\n // Bail on an unchanged trigger: `syncTrigger` fires on every keyup\n // and pointer-up, and a fresh object each time would re-render the\n // picker (resetting its highlight) on arrow keys that didn't move\n // out of the query.\n const unchanged =\n prev == null\n ? next == null\n : next != null &&\n prev.at === next.at &&\n prev.caret === next.caret &&\n prev.query === next.query &&\n prev.textNode === next.textNode\n if (unchanged) return\n opts.onTriggerChange(next ? { at: next.at, caret: next.caret, query: next.query } : null)\n }\n\n function syncTrigger() {\n if (!opts.mentionsEnabled()) {\n publishTrigger(null)\n return\n }\n const caret = caretIn(el)\n const next = caret ? triggerAt(caret) : null\n if (next && dismissed && next.textNode === dismissed.node && next.at === dismissed.at) {\n publishTrigger(null)\n return\n }\n // The caret left the dismissed `@`, so stop suppressing it.\n dismissed = null\n publishTrigger(next)\n }\n\n function setValue(body: string) {\n el.replaceChildren(renderMentionNodes(doc, body, opts.chipClass))\n markEmpty(serializeMentionDom(el))\n dismissed = null\n publishTrigger(null)\n }\n\n const onInput = () => {\n emit()\n syncTrigger()\n }\n const onCaretMove = () => syncTrigger()\n // Only on pointer-up and focus, not on keyup: arrow keys already step\n // over a chip atomically, and nudging on every keyup would fight anyone\n // navigating leftwards past one.\n const onPointerCaret = () => {\n nudgeCaretOutOfChip(el)\n syncTrigger()\n }\n const onPaste = (e: ClipboardEvent) => {\n // Always take the plain-text flavour. `plaintext-only` hosts do this\n // anyway; the `true` fallback would otherwise accept arbitrary\n // markup, including elements that look like chips.\n const text = e.clipboardData?.getData('text/plain')\n e.preventDefault()\n if (!text) return\n insertPlainText(el, text.replace(/\\r\\n?/g, '\\n'))\n emit()\n syncTrigger()\n }\n const onDrop = (e: DragEvent) => {\n // Dropping a selection from the host page would inject its markup\n // straight into the editing host. Cheaper to refuse than sanitise.\n e.preventDefault()\n }\n\n el.addEventListener('input', onInput)\n el.addEventListener('keyup', onCaretMove)\n el.addEventListener('mouseup', onPointerCaret)\n el.addEventListener('focus', onPointerCaret)\n el.addEventListener('paste', onPaste)\n el.addEventListener('drop', onDrop)\n\n setValue(opts.initialValue ?? '')\n\n return {\n getValue: () => serializeMentionDom(el),\n setValue,\n focus() {\n el.focus()\n // `focus()` alone parks the caret at the start, which reads as\n // broken when the host already holds a draft to edit.\n const last = el.lastChild\n if (!last) return\n if (last.nodeType === TEXT_NODE) setCaret(el, last, (last as Text).data.length)\n else setCaret(el, el, el.childNodes.length)\n },\n insertMention(member) {\n // Prefer the live caret over the stored trigger: the stored one can\n // be a keystroke stale, and its text node may have been replaced\n // by an intervening edit. The stored trigger stays as the fallback\n // for the case where focus has already moved off the host.\n const caret = caretIn(el)\n const target = (caret ? triggerAt(caret) : null) ?? trigger\n if (!target) return\n if (!insertChipAtTrigger(el, target, member, opts.chipClass)) return\n emit()\n dismissed = null\n publishTrigger(null)\n },\n syncTrigger,\n clearTrigger: () => publishTrigger(null),\n dismissTrigger() {\n if (trigger) dismissed = { node: trigger.textNode, at: trigger.at }\n publishTrigger(null)\n },\n destroy() {\n el.removeEventListener('input', onInput)\n el.removeEventListener('keyup', onCaretMove)\n el.removeEventListener('mouseup', onPointerCaret)\n el.removeEventListener('focus', onPointerCaret)\n el.removeEventListener('paste', onPaste)\n el.removeEventListener('drop', onDrop)\n },\n }\n}\n\n/* ────────────────────────── plaintext-only ────────────────────────── */\n\nlet cachedMode: 'plaintext-only' | 'true' | null = null\n\n/**\n * `contenteditable=\"plaintext-only\"` stops an engine turning Enter into\n * block wrappers and ⌘B into `<b>` markup — exactly right for a plain\n * body with atomic chips. Chromium and WebKit ship it; Gecko only got it\n * recently, so fall back to `\"true\"`. Serialization handles either shape,\n * so the fallback is a cosmetic difference, not a correctness one.\n *\n * Probed lazily rather than at module scope so importing this file stays\n * safe where there's no `document` (SSR).\n */\nexport function plaintextEditableMode(): 'plaintext-only' | 'true' {\n if (cachedMode) return cachedMode\n if (typeof document === 'undefined') return 'true'\n const probe = document.createElement('div')\n try {\n probe.contentEditable = 'plaintext-only'\n cachedMode = probe.contentEditable === 'plaintext-only' ? 'plaintext-only' : 'true'\n } catch {\n cachedMode = 'true'\n }\n return cachedMode\n}\n","import type { ComponentChildren } from 'preact'\nimport { useEffect, useMemo, useState } from 'preact/hooks'\n\nimport { parseMentionTokens } from '../../lib/mentions'\nimport type { MentionTriggerState } from '../../lib/mentions'\n\nexport type MentionableMember = { userId: string; name: string }\n\n/**\n * A marker whose id isn't in the validated `mentions` set renders as plain\n * `@Name`, never as the raw marker. The missing chip is the signal that nobody\n * was notified — a hand-crafted id, a member who left, or the common case of a\n * user mentioning themselves, which the server drops on purpose.\n */\nexport function MentionizedBody({\n body,\n mentions,\n trailing,\n}: {\n body: string\n mentions: readonly string[]\n trailing?: ComponentChildren\n}) {\n const valid = useMemo(() => new Set(mentions), [mentions])\n const tokens = useMemo(() => parseMentionTokens(body), [body])\n return (\n <p class=\"markup-comment-body\">\n {tokens.map((t, i) => {\n if (t.type === 'mention' && valid.has(t.userId)) {\n return (\n <span key={i} class=\"markup-mention-chip\">\n @{t.name}\n </span>\n )\n }\n const text = t.type === 'mention' ? `@${t.name}` : t.value\n return <span key={i}>{text}</span>\n })}\n {trailing}\n </p>\n )\n}\n\n/** Headless: the caller owns the textarea and renders the overlay. */\nexport function useMentionPicker(opts: {\n members: readonly MentionableMember[]\n trigger: MentionTriggerState | null\n onSelect: (member: MentionableMember) => void\n onClose: () => void\n}) {\n const { members, trigger, onSelect, onClose } = opts\n const [highlight, setHighlight] = useState(0)\n\n const filtered = useMemo(() => {\n if (!trigger) return []\n const q = trigger.query.toLowerCase()\n return members.filter((m) => m.name.toLowerCase().includes(q)).slice(0, 6)\n }, [trigger, members])\n\n // Keeps the highlight in bounds as the filtered list shrinks.\n useEffect(() => {\n setHighlight((h) => (h >= filtered.length ? 0 : h))\n }, [filtered])\n\n /** `true` means consumed — the caller must skip its own handling. */\n function handleKeyDown(e: KeyboardEvent): boolean {\n if (!trigger || filtered.length === 0) return false\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n setHighlight((h) => (h + 1) % filtered.length)\n return true\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault()\n setHighlight((h) => (h - 1 + filtered.length) % filtered.length)\n return true\n }\n if (e.key === 'Enter' || e.key === 'Tab') {\n e.preventDefault()\n const member = filtered[highlight]\n if (member) onSelect(member)\n return true\n }\n if (e.key === 'Escape') {\n e.preventDefault()\n onClose()\n return true\n }\n return false\n }\n\n return {\n isOpen: trigger != null && filtered.length > 0,\n items: filtered,\n highlight,\n setHighlight,\n handleKeyDown,\n }\n}\n\n/** Positioned by the composer, absolutely, under the textarea container. */\nexport function MentionPickerList({\n items,\n highlight,\n setHighlight,\n onSelect,\n}: {\n items: readonly MentionableMember[]\n highlight: number\n setHighlight: (i: number) => void\n onSelect: (member: MentionableMember) => void\n}) {\n if (items.length === 0) return null\n return (\n <ul class=\"markup-mention-picker\" role=\"listbox\" aria-label=\"Mention member\">\n {items.map((m, i) => (\n <li\n key={m.userId}\n role=\"option\"\n aria-selected={i === highlight}\n class={`markup-mention-picker-item${i === highlight ? ' is-active' : ''}`}\n onMouseDown={(e) => {\n // Not click: the textarea blur would fire first.\n e.preventDefault()\n onSelect(m)\n }}\n onMouseEnter={() => setHighlight(i)}\n >\n <span class=\"markup-mention-picker-name\">{m.name}</span>\n <span class=\"markup-mention-picker-trigger\" aria-hidden=\"true\">\n @\n </span>\n </li>\n ))}\n </ul>\n )\n}\n","import { useLayoutEffect, useRef, useState } from 'preact/hooks'\n\nimport {\n attachMentionInput,\n plaintextEditableMode,\n type MentionInputController,\n} from '../mention-input'\nimport { cx } from '../utils'\nimport { MentionPickerList, useMentionPicker, type MentionableMember } from './mentions'\nimport type { MentionTriggerState } from '../../lib/mentions'\n\n/**\n * Imperative escape hatch for the two things a parent legitimately needs\n * and props can't express on an editor whose DOM is authoritative.\n */\nexport type MentionInputHandle = {\n focus: () => void\n}\n\n/**\n * `value` is controlled, but written back into the DOM only when it differs\n * from what the DOM already serializes to. Keystrokes round-trip identically,\n * so typing never disturbs the caret; the write fires only for values the\n * editor didn't produce, like clearing after submit.\n *\n * A contenteditable host has no `maxLength`, so the over-limit state is the\n * caller's job.\n */\nexport function MentionInput({\n value,\n onChange,\n onKeyDown,\n members,\n label,\n placeholder,\n disabled = false,\n autoFocus = false,\n class: className,\n handle,\n}: {\n value: string\n onChange: (next: string) => void\n /**\n * Runs only for keys the mention picker didn't consume, so a parent\n * can bind Cmd+Enter without stealing Enter from an open picker.\n */\n onKeyDown?: (e: KeyboardEvent) => void\n /** Empty / undefined disables mentions entirely. */\n members?: readonly MentionableMember[]\n label: string\n placeholder?: string\n disabled?: boolean\n autoFocus?: boolean\n class?: string\n handle?: { current: MentionInputHandle | null }\n}) {\n const elRef = useRef<HTMLDivElement>(null)\n const ctrlRef = useRef<MentionInputController | null>(null)\n const [trigger, setTrigger] = useState<MentionTriggerState | null>(null)\n\n // Read through refs so the controller's listeners, which live for the\n // element's whole lifetime, don't force a re-attach every render.\n const onChangeRef = useRef(onChange)\n onChangeRef.current = onChange\n const membersRef = useRef(members)\n membersRef.current = members\n // Reading `value` in the attach effect would make it a dependency and\n // re-create the controller on every keystroke.\n const initialValueRef = useRef(value)\n\n useLayoutEffect(() => {\n const el = elRef.current\n if (!el) return\n const ctrl = attachMentionInput(el, {\n chipClass: 'markup-mention-chip',\n initialValue: initialValueRef.current,\n onChange: (next) => onChangeRef.current(next),\n onTriggerChange: setTrigger,\n mentionsEnabled: () => (membersRef.current?.length ?? 0) > 0,\n })\n ctrlRef.current = ctrl\n return () => {\n ctrl.destroy()\n ctrlRef.current = null\n }\n }, [])\n\n // Cleared on unmount so a parent holding the ref can't call a dead editor.\n useLayoutEffect(() => {\n if (!handle) return\n handle.current = { focus: () => ctrlRef.current?.focus() }\n return () => {\n handle.current = null\n }\n }, [handle])\n\n useLayoutEffect(() => {\n if (autoFocus) ctrlRef.current?.focus()\n }, [autoFocus])\n\n // MUST be a layout effect. `useEffect` runs after paint, so under fast\n // typing it lands several keystrokes late holding a stale `value`, and\n // \"reconciles\" the DOM backwards — dropping characters and resetting the\n // caret. A layout effect commits in the same microtask as its state update.\n useLayoutEffect(() => {\n const ctrl = ctrlRef.current\n if (!ctrl) return\n if (ctrl.getValue() !== value) ctrl.setValue(value)\n }, [value])\n\n const picker = useMentionPicker({\n members: members ?? [],\n trigger,\n onSelect: (member) => ctrlRef.current?.insertMention(member),\n // Escape is deliberate, so it must stick rather than re-open.\n onClose: () => ctrlRef.current?.dismissTrigger(),\n })\n\n return (\n <>\n <div\n ref={elRef}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={label}\n aria-disabled={disabled || undefined}\n class={cx('markup-mention-input', className)}\n /* No children, ever — the controller owns this subtree. Preact\n * only diffs vnode children, so it leaves the DOM alone. */\n contentEditable={disabled ? 'false' : plaintextEditableMode()}\n data-placeholder={placeholder}\n tabIndex={disabled ? -1 : 0}\n onKeyDown={(e) => {\n if (picker.handleKeyDown(e)) return\n onKeyDown?.(e)\n }}\n onBlur={() => {\n // Next tick, so a mousedown on a picker item lands first.\n setTimeout(() => ctrlRef.current?.clearTrigger(), 120)\n }}\n />\n {picker.isOpen ? (\n <MentionPickerList\n items={picker.items}\n highlight={picker.highlight}\n setHighlight={picker.setHighlight}\n onSelect={(member) => ctrlRef.current?.insertMention(member)}\n />\n ) : null}\n </>\n )\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\n\nimport { cx, platformKeys } from '../utils'\nimport { IconSend } from './icons'\nimport { MentionInput, type MentionInputHandle } from './mention-input'\nimport type { MentionableMember } from './mentions'\n\nconst MAX_BODY = 4000\n\n/**\n * Reusable text composer used both for the first comment of a new thread and\n * for replies on an existing thread. Submits on Cmd/Ctrl+Enter; auto-grows;\n * disables submit while the parent's submit promise resolves.\n *\n * When `members` is non-empty, typing `@` opens an autocomplete picker and\n * the selected member becomes a chip. The `@[Name](userId)` wire format\n * lives only in the serialized `body` that `onSubmit` receives — the\n * parent re-extracts mention IDs from it to send alongside the write (the\n * server re-validates).\n */\nexport function Composer({\n label,\n placeholder = 'Leave feedback…',\n submitLabel = 'Post',\n initialFocus = true,\n isPending,\n error,\n onSubmit,\n members,\n}: {\n label: string\n placeholder?: string\n submitLabel?: string\n initialFocus?: boolean\n isPending: boolean\n error?: string\n onSubmit: (body: string) => void\n /** Empty / undefined disables the mention picker entirely. */\n members?: readonly MentionableMember[]\n}) {\n const [value, setValue] = useState('')\n const inputRef = useRef<MentionInputHandle | null>(null)\n const wasPending = useRef(false)\n\n // After a successful submit (isPending true → false with no error) clear the\n // value and re-focus so the user can keep typing replies.\n useEffect(() => {\n if (wasPending.current && !isPending && !error) {\n setValue('')\n inputRef.current?.focus()\n }\n wasPending.current = isPending\n }, [isPending, error])\n\n const remaining = MAX_BODY - value.length\n const isOverLimit = remaining < 0\n\n function handleSubmit(e?: Event) {\n e?.preventDefault()\n const body = value.trim()\n // Mirror the submit button's disabled state. Without the\n // `isOverLimit` check here, Cmd/Ctrl+Enter would fire even though\n // the visible button is greyed — server rejects the body, but UX\n // is inconsistent.\n if (!body || isPending || isOverLimit) return\n onSubmit(body)\n }\n\n // `MentionInput` gives the picker first refusal on every key, so this\n // only ever sees keys it didn't consume — a user pressing Enter to pick\n // a mention can't accidentally submit the comment.\n function onKey(e: KeyboardEvent) {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n handleSubmit(e)\n }\n }\n\n const isFilled = value.length > 0\n const keys = platformKeys()\n\n function submitButton(tabIndex?: number) {\n return (\n <button\n type=\"submit\"\n class=\"markup-btn markup-btn-primary\"\n disabled={isPending || !value.trim() || isOverLimit}\n aria-label={isPending ? 'Sending…' : submitLabel}\n title={isPending ? 'Sending…' : submitLabel}\n tabIndex={tabIndex}\n >\n <IconSend size={14} />\n </button>\n )\n }\n\n return (\n <form class={cx('markup-composer', isFilled && 'is-filled')} onSubmit={handleSubmit}>\n <MentionInput\n class=\"markup-composer-input\"\n label={label}\n placeholder={placeholder}\n value={value}\n onChange={setValue}\n onKeyDown={onKey}\n members={members}\n disabled={isPending}\n autoFocus={initialFocus}\n handle={inputRef}\n />\n {/* Footer always in DOM — height animated via grid-template-rows trick */}\n <div class=\"markup-composer-footer-wrap\">\n <div class=\"markup-composer-footer\">\n <span class=\"markup-composer-hint\">\n {error ? (\n <span class=\"markup-composer-error\">{error}</span>\n ) : isOverLimit ? (\n <span class=\"markup-composer-error\">{Math.abs(remaining)} too long</span>\n ) : (\n /* Chips rather than bare glyphs in the sentence. Measured\n against this mono face, `⌘` floats 1.2px clear of the\n baseline while `↵` is barely half a cap tall and sits on\n it — set inline they read as debris beside the words. A\n chip centres each glyph in its own box, so their metrics\n stop being compared to the text's. Labels follow the\n platform: the handler takes Cmd or Ctrl, and only one of\n those is on the reader's keyboard. */\n <>\n <kbd class=\"markup-kbd is-inline\">{keys.mod}</kbd>\n <kbd class=\"markup-kbd is-inline\">{keys.enter}</kbd>\n <span class=\"markup-composer-hint-label\">to send</span>\n </>\n )}\n </span>\n <div class=\"markup-composer-actions\">{submitButton(isFilled ? undefined : -1)}</div>\n </div>\n </div>\n {/* Floating button shown only when empty */}\n <span class=\"markup-composer-actions-empty\" aria-hidden={isFilled || undefined}>\n {submitButton(isFilled ? -1 : undefined)}\n </span>\n </form>\n )\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\n\nimport { useDrag } from '../use-drag'\nimport { useFocusTrap } from '../use-focus-trap'\nimport { useObjectURL } from '../use-object-url'\nimport { cx } from '../utils'\nimport { AuthorPrompt } from './author-prompt'\nimport { Composer } from './composer'\nimport { IconCamera, IconClose } from './icons'\nimport type { MentionableMember } from './mentions'\n\n/**\n * The \"you just dropped a pin\" popover. Either the author-name capture (if\n * we don't have one yet) or the thread composer. Closing it discards the pin.\n *\n * Uses the native Popover API (`popover=\"auto\"`) — ESC and outside-click\n * dismissal are handled by the browser. Position is anchored to the ghost\n * pin via CSS Anchor Positioning (with a JS-clamp fallback).\n */\nexport function NewThreadPopover({\n pageX,\n pageY,\n authorName,\n isVerified,\n isIdentityResolving,\n isSigningIn,\n isPending,\n error,\n screenshot,\n isScreenshotCapturing,\n screenshotFailed,\n screenshotRedactedCount,\n screenshotRedactedSelectors,\n members = [],\n onAuthor,\n onSignIn,\n onSubmit,\n onClose,\n}: {\n pageX: number\n pageY: number\n authorName: string | null\n isVerified: boolean\n /** Anon mint hasn't completed yet — disable the guest path. */\n isIdentityResolving: boolean\n /** A popup sign-in is already in flight — disable the sign-in button. */\n isSigningIn: boolean\n isPending: boolean\n error: string | undefined\n screenshot: Blob | null\n isScreenshotCapturing: boolean\n /** A capture ran and produced nothing — say so instead of going quiet. */\n screenshotFailed: boolean\n screenshotRedactedCount: number\n screenshotRedactedSelectors: string[]\n /**\n * Mentionable project members for the `@`-autocomplete. Empty\n * disables the picker.\n */\n members?: readonly MentionableMember[]\n onAuthor: (name: string, email?: string) => void\n onSignIn: () => void\n onSubmit: (body: string, includeScreenshot: boolean) => void\n onClose: () => void\n}) {\n const ref = useRef<HTMLDivElement>(null)\n useFocusTrap(ref, true)\n\n const [includeScreenshot, setIncludeScreenshot] = useState(false)\n const [isRedactionExpanded, setIsRedactionExpanded] = useState(false)\n const previewUrl = useObjectURL(screenshot)\n // User-dragged position; `null` means \"use the anchor / fallback coords\".\n // Resets to null on every mount, so reopening snaps back to the pin.\n const [dragPos, setDragPos] = useState<{ left: number; top: number } | null>(null)\n // Drag-to-move from the header. Same shape as ThreadPopover —\n // handle is the header but we measure the popover.\n const { onPointerDown: onHeaderPointerDown, isDragging } = useDrag({\n targetRef: ref,\n shouldStart: (e) => {\n const target = e.target as HTMLElement | null\n return !target?.closest('button, a, input, textarea, select')\n },\n onMove: setDragPos,\n })\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n\n if (typeof el.showPopover === 'function' && !el.matches(':popover-open')) {\n try {\n el.showPopover()\n } catch {\n /* already showing or unsupported */\n }\n }\n\n function onToggle(e: Event) {\n const ev = e as ToggleEvent\n if (ev.newState === 'closed') onClose()\n }\n el.addEventListener('toggle', onToggle)\n return () => el.removeEventListener('toggle', onToggle)\n }, [onClose])\n\n const width = 320\n const margin = 12\n const left = clamp(pageX - window.scrollX + 16, margin, window.innerWidth - width - margin)\n const top = clamp(pageY - window.scrollY - 16, margin, window.innerHeight - 220)\n const pageUrl = typeof window !== 'undefined' ? window.location.href : ''\n\n const hasScreenshot = screenshot != null\n // The failed state is part of the row on purpose. Dropping the row on\n // failure made a broken capture look exactly like a project with\n // screenshots turned off, so nobody reported it as a bug.\n const showScreenshotRow = isScreenshotCapturing || hasScreenshot || screenshotFailed\n\n return (\n <div\n ref={ref}\n class={cx('markup-popover', dragPos && 'is-floating', isDragging && 'is-dragging')}\n popover=\"auto\"\n style={{\n '--markup-pop-x': `${dragPos?.left ?? left}px`,\n '--markup-pop-y': `${dragPos?.top ?? top}px`,\n }}\n role=\"dialog\"\n aria-label=\"New markup\"\n >\n <header class=\"markup-popover-header\" onPointerDown={onHeaderPointerDown}>\n {/* Same reasoning as the thread popover's header: the page is the\n one you are looking at, and a hostname is the one label here\n that cannot be shortened without becoming a lie. Saying \"New\n comment\" also retires the separate \"new\" chip, which existed\n to qualify an address that is no longer shown. Full URL stays\n on hover. */}\n <span class=\"markup-popover-title\" title={pageUrl}>\n New comment\n </span>\n <button type=\"button\" class=\"markup-icon-btn\" aria-label=\"Discard pin\" onClick={onClose}>\n <IconClose size={16} />\n </button>\n </header>\n\n {authorName == null ? (\n <AuthorPrompt\n isPending={isPending}\n isConnecting={isIdentityResolving}\n isSigningIn={isSigningIn}\n onSubmit={onAuthor}\n onCancel={onClose}\n onSignIn={onSignIn}\n />\n ) : (\n <div class=\"markup-popover-body\">\n <p class=\"markup-popover-byline\">\n posting as <span class=\"markup-popover-name\">{authorName}</span>\n {isVerified ? <span class=\"markup-comment-badge\">team</span> : null}\n </p>\n <Composer\n label=\"Feedback\"\n placeholder=\"What's wrong, missing, or worth noting?\"\n submitLabel=\"Post markup\"\n isPending={isPending}\n error={error}\n onSubmit={(body) => onSubmit(body, includeScreenshot && hasScreenshot)}\n members={members}\n />\n {showScreenshotRow ? (\n <div class={cx('markup-screenshot-row', screenshotFailed && 'is-failed')}>\n {isScreenshotCapturing ? (\n <span class=\"markup-screenshot-status\">\n <input type=\"checkbox\" class=\"markup-screenshot-checkbox\" disabled />\n <IconCamera size={12} />\n <span>Capturing…</span>\n </span>\n ) : screenshotFailed ? (\n /* No checkbox — there is nothing to attach. The comment\n still posts; only the screenshot is missing. */\n <span\n class=\"markup-screenshot-status\"\n title=\"This page has something the capture can't read, often a third-party image. Your comment will post without a screenshot.\"\n >\n <IconCamera size={12} />\n <span>Screenshot unavailable</span>\n </span>\n ) : (\n <label class=\"markup-screenshot-toggle\">\n <input\n type=\"checkbox\"\n class=\"markup-screenshot-checkbox\"\n checked={includeScreenshot}\n onChange={(e) => setIncludeScreenshot(e.currentTarget.checked)}\n />\n <IconCamera size={12} />\n <span>Attach screenshot</span>\n {previewUrl && includeScreenshot ? (\n <img\n class=\"markup-screenshot-thumb\"\n src={previewUrl}\n alt=\"Screenshot preview\"\n />\n ) : null}\n </label>\n )}\n {includeScreenshot && hasScreenshot ? (\n <>\n {screenshotRedactedCount > 0 ? (\n <div class=\"markup-screenshot-redacted\">\n <button\n type=\"button\"\n class=\"markup-screenshot-redacted-chip\"\n onClick={() => setIsRedactionExpanded((v) => !v)}\n >\n <em class=\"markup-screenshot-redacted-arrow\">\n {isRedactionExpanded ? '▾' : '▸'}\n </em>\n {screenshotRedactedCount}{' '}\n {screenshotRedactedCount === 1 ? 'field' : 'fields'} redacted\n </button>\n {isRedactionExpanded ? (\n <div class=\"markup-screenshot-redacted-list\">\n {screenshotRedactedSelectors.map((sel) => (\n <code key={sel} class=\"markup-screenshot-redacted-selector\">\n {sel}\n </code>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n <p class=\"markup-screenshot-help\">\n Password and credit-card fields are blacked out automatically. Add{' '}\n <code class=\"markup-screenshot-help-code\">data-markup-private</code> to mask\n anything else.\n </p>\n </>\n ) : null}\n </div>\n ) : null}\n </div>\n )}\n </div>\n )\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value))\n}\n","import { cx } from '../utils'\nimport { IconBot, IconChevronLeft } from './icons'\nimport type { WidgetNotification } from '../api'\n\n/**\n * Verified-user notifications inbox rendered inside a `PanelPopover`\n * (which owns the floating surface chrome anchored to the toolbar's\n * inbox button). This component owns no dismissal logic of\n * its own — the wrapper's outside-click + Escape handlers\n * (`composedPath()`-based so they work across the widget's shadow-root\n * boundary) take the surface down when the user clicks elsewhere.\n *\n * Click a row → mark-read in the same transaction the host runs to\n * open the thread popover for that comment. The dashboard inbox\n * subscribes to the same `readAt` field, so the dashboard's bell\n * decrements in real time once the widget mutation lands.\n *\n * Scoped to the current project on the server — see\n * `convex/widget/notifications.ts#listForProject`. Cross-project\n * notifications live on the dashboard `/notifications` route.\n */\nexport function NotificationsPanel({\n items,\n isLoading,\n error,\n onBack,\n onItemClick,\n onMarkAllRead,\n isMarkingAll,\n}: {\n items: readonly WidgetNotification[]\n isLoading: boolean\n error?: string\n onBack: () => void\n onItemClick: (item: WidgetNotification) => void\n onMarkAllRead: () => void\n isMarkingAll: boolean\n}) {\n const anyUnread = items.some((i) => i.readAt == null)\n\n return (\n <div class=\"markup-notifications-panel\" role=\"dialog\" aria-label=\"Notifications\">\n <header class=\"markup-notifications-panel-header\">\n <button\n type=\"button\"\n class=\"markup-icon-btn\"\n title=\"Back to menu\"\n aria-label=\"Back to menu\"\n onClick={onBack}\n >\n <IconChevronLeft size={16} />\n </button>\n <span class=\"markup-eyebrow\">notifications</span>\n <div class=\"markup-notifications-panel-actions\">\n {anyUnread ? (\n <button\n type=\"button\"\n class=\"markup-notifications-panel-mark-all\"\n disabled={isMarkingAll}\n onClick={onMarkAllRead}\n >\n {isMarkingAll ? 'Marking…' : 'Mark all read'}\n </button>\n ) : null}\n </div>\n </header>\n\n <div class=\"markup-notifications-panel-body\">\n {error ? (\n <p class=\"markup-notifications-panel-error\">{error}</p>\n ) : isLoading ? (\n <p class=\"markup-notifications-panel-empty\">Loading…</p>\n ) : items.length === 0 ? (\n <div class=\"markup-notifications-panel-empty\">\n <p class=\"markup-notifications-panel-empty-title\">You're all caught up.</p>\n <p class=\"markup-notifications-panel-empty-sub\">\n New @mentions on this site land here.\n </p>\n </div>\n ) : (\n <ul class=\"markup-notifications-panel-list\">\n {items.map((item) => (\n <li key={item._id}>\n <button\n type=\"button\"\n class={cx('markup-notifications-panel-row', item.readAt == null && 'is-unread')}\n onClick={() => onItemClick(item)}\n >\n <div class=\"markup-notifications-panel-meta\">\n {item.readAt == null ? (\n <span aria-hidden=\"true\" class=\"markup-notifications-panel-dot\" />\n ) : null}\n <span class=\"markup-notifications-panel-actor\">{item.actorName}</span>\n {/* Same reasoning as the badge in the thread\n popover: the row carries a real person's name,\n so a visitor has to be able to tell that a\n machine wrote the comment that pinged them. */}\n {item.actorVia === 'mcp' ? (\n <span\n class=\"markup-comment-badge is-agent\"\n role=\"img\"\n aria-label=\"Written by an AI agent\"\n title=\"Written by an AI agent on this person's behalf\"\n >\n <IconBot size={11} />\n </span>\n ) : null}\n <span class=\"markup-notifications-panel-sep\">·</span>\n <span class=\"markup-notifications-panel-time\">\n {relativeTime(item.createdAt)}\n </span>\n </div>\n <p class=\"markup-notifications-panel-thread\">\n mentioned you in{' '}\n <span class=\"markup-notifications-panel-thread-title\">{item.threadTitle}</span>\n </p>\n {item.commentExcerpt ? (\n <p class=\"markup-notifications-panel-excerpt\">“{item.commentExcerpt}”</p>\n ) : null}\n </button>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n )\n}\n\nfunction relativeTime(ts: number): string {\n const diff = Date.now() - ts\n const sec = Math.floor(diff / 1000)\n if (sec < 60) return 'just now'\n const min = Math.floor(sec / 60)\n if (min < 60) return `${min}m ago`\n const hr = Math.floor(min / 60)\n if (hr < 24) return `${hr}h ago`\n const day = Math.floor(hr / 24)\n if (day < 30) return `${day}d ago`\n return new Date(ts).toLocaleDateString()\n}\n","import { useEffect, useState } from 'preact/hooks'\n\nimport {\n getThemeMode,\n resolvedTheme,\n setThemeMode,\n subscribeTheme,\n type ThemeMode,\n} from './theme-store'\n\n/**\n * Preact hook that re-renders on theme changes (mode flips OR system\n * preference flips while in `auto`). Returns the user's *mode* plus\n * the *resolved* (light | dark) value, and a setter that writes the\n * store + persists.\n */\nexport function useTheme(): {\n mode: ThemeMode\n resolved: 'light' | 'dark'\n set: (next: ThemeMode) => void\n} {\n const [, forceRender] = useState(0)\n\n useEffect(() => subscribeTheme(() => forceRender((v) => v + 1)), [])\n\n return {\n mode: getThemeMode(),\n resolved: resolvedTheme(),\n set: setThemeMode,\n }\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\n\nimport { useTheme } from '../use-theme'\nimport { cx, platformKeys } from '../utils'\nimport {\n IconKeyboard,\n IconLogo,\n IconMenu,\n IconMonitor,\n IconMoon,\n IconShield,\n IconSun,\n} from './icons'\n\ntype ToolbarPosition = 'bottom-right' | 'bottom-left' | 'bottom-center'\n\n/**\n * The panel rows close this menu before opening, so the panel doesn't appear\n * behind it. `app.tsx` owns the open-panel state because the panels mount as\n * siblings of the toolbar rather than inside this popover.\n *\n * Neither row advertises a key hint, deliberately: a bare `?` would collide\n * with host-page shortcuts we can't see, and the widget has no business\n * claiming a plain key the app underneath may already use.\n */\nexport function OverflowMenu({\n position,\n onSetPosition,\n autoCapture,\n autoCaptureLocked = false,\n onToggleAutoCapture,\n onOpenPrivacy,\n onOpenShortcuts,\n onHideForSession,\n version,\n dashboardUrl,\n}: {\n position: ToolbarPosition\n onSetPosition: (next: ToolbarPosition) => void\n autoCapture: boolean\n /**\n * The user's toggle can't override a host opt-out, so the row says who\n * turned it off rather than offering a control that does nothing.\n */\n autoCaptureLocked?: boolean\n onToggleAutoCapture: () => void\n onOpenPrivacy: () => void\n onOpenShortcuts: () => void\n onHideForSession: () => void\n /** Version string shown in the footer (e.g., \"4.2.0\"). */\n version: string\n /** Optional brand-line link (the dashboard \"marketing\" URL). */\n dashboardUrl?: string\n}) {\n const [open, setOpen] = useState(false)\n const containerRef = useRef<HTMLDivElement>(null)\n const theme = useTheme()\n\n useEffect(() => {\n if (!open) return\n function onDocClick(e: MouseEvent) {\n const container = containerRef.current\n if (!container) return\n if (!e.composedPath().includes(container)) setOpen(false)\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') setOpen(false)\n }\n document.addEventListener('click', onDocClick, true)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('click', onDocClick, true)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n const anchorClass =\n position === 'bottom-left'\n ? 'is-anchor-left'\n : position === 'bottom-center'\n ? 'is-anchor-center'\n : 'is-anchor-right'\n\n const { mod: modKey } = platformKeys()\n\n return (\n <div ref={containerRef} style={{ position: 'relative', display: 'inline-flex' }}>\n <button\n type=\"button\"\n class=\"markup-tb-btn\"\n data-kind=\"overflow\"\n data-on={open ? 'true' : undefined}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-label=\"More options\"\n title=\"More\"\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n setOpen((v) => !v)\n }}\n >\n <IconMenu size={16} />\n </button>\n\n {open ? (\n <div class={cx('markup-pop', anchorClass)} data-pop=\"overflow\" role=\"menu\">\n {/* Appearance — horizontal row: label left, segmented right. */}\n <div class=\"markup-segmented-row\">\n <span class=\"lbl\">Appearance</span>\n <div class=\"markup-segmented\" role=\"radiogroup\" aria-label=\"Appearance\">\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={theme.mode === 'light'}\n aria-label=\"Light\"\n title=\"Light\"\n class={cx(theme.mode === 'light' && 'is-on')}\n onClick={() => theme.set('light')}\n >\n <IconSun size={14} />\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={theme.mode === 'dark'}\n aria-label=\"Dark\"\n title=\"Dark\"\n class={cx(theme.mode === 'dark' && 'is-on')}\n onClick={() => theme.set('dark')}\n >\n <IconMoon size={14} />\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={theme.mode === 'auto'}\n aria-label={`Auto (currently ${theme.resolved})`}\n title={`Auto, currently ${theme.resolved}`}\n class={cx(theme.mode === 'auto' && 'is-on')}\n onClick={() => theme.set('auto')}\n >\n <IconMonitor size={14} />\n </button>\n </div>\n </div>\n\n {/* Position — horizontal row, same shape as Appearance. */}\n <div class=\"markup-segmented-row\">\n <span class=\"lbl\">Position</span>\n <div class=\"markup-segmented\" role=\"radiogroup\" aria-label=\"Position\">\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={position === 'bottom-left'}\n aria-label=\"Bottom left\"\n title=\"Bottom left\"\n class={cx(position === 'bottom-left' && 'is-on')}\n onClick={() => onSetPosition('bottom-left')}\n >\n <CornerIcon side=\"left\" />\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={position === 'bottom-center'}\n aria-label=\"Bottom center\"\n title=\"Bottom center\"\n class={cx(position === 'bottom-center' && 'is-on')}\n onClick={() => onSetPosition('bottom-center')}\n >\n <CornerIcon side=\"center\" />\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={position === 'bottom-right'}\n aria-label=\"Bottom right\"\n title=\"Bottom right\"\n class={cx(position === 'bottom-right' && 'is-on')}\n onClick={() => onSetPosition('bottom-right')}\n >\n <CornerIcon side=\"right\" />\n </button>\n </div>\n </div>\n\n <div class=\"markup-pop-group-label\">behavior</div>\n\n <button\n type=\"button\"\n role=\"menuitemcheckbox\"\n aria-checked={autoCapture}\n class=\"markup-menu-row\"\n data-on={autoCapture ? 'true' : undefined}\n disabled={autoCaptureLocked}\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n onToggleAutoCapture()\n }}\n >\n <span class=\"ic\">\n <CameraIcon />\n </span>\n <span class=\"lbl\">\n <span>Auto-capture screenshots</span>\n <span class=\"sub\">\n {autoCaptureLocked ? 'Turned off by this site' : 'PII fields are scrubbed'}\n </span>\n </span>\n <span class=\"switch\" aria-hidden=\"true\" />\n </button>\n\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"markup-menu-row\"\n onClick={() => {\n setOpen(false)\n onOpenPrivacy()\n }}\n >\n <span class=\"ic\">\n <IconShield size={16} />\n </span>\n <span class=\"lbl\">Privacy & data</span>\n </button>\n\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"markup-menu-row\"\n onClick={() => {\n setOpen(false)\n onOpenShortcuts()\n }}\n >\n <span class=\"ic\">\n <IconKeyboard size={16} />\n </span>\n <span class=\"lbl\">Keyboard shortcuts</span>\n </button>\n\n <div class=\"markup-menu-divider\" />\n\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"markup-menu-row\"\n onClick={() => {\n setOpen(false)\n onHideForSession()\n }}\n >\n <span class=\"ic\">\n <HideIcon />\n </span>\n <span class=\"lbl\">Hide for this session</span>\n <span class=\"right\">{modKey} .</span>\n </button>\n\n <a\n class=\"markup-brand-line\"\n href={dashboardUrl ?? 'https://markup.dev'}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <IconLogo size={12} />\n <span>Powered by Markup</span>\n <span class=\"ver\">v{version}</span>\n </a>\n </div>\n ) : null}\n </div>\n )\n}\n\n/* Small inline pictograms for the Position picker — a rounded square\n * with a dot at the picked corner. Keeps the picker icons unambiguous\n * at 14px without pulling in another icon. */\nfunction CornerIcon({ side }: { side: 'left' | 'center' | 'right' }) {\n const dotX = side === 'left' ? 4 : side === 'right' ? 12 : 8\n return (\n <svg\n width={14}\n height={14}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width={1.5}\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden\n >\n <rect x=\"2\" y=\"2\" width=\"12\" height=\"12\" rx=\"2.5\" />\n <circle cx={dotX} cy={12} r=\"1.4\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n )\n}\n\nfunction CameraIcon() {\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width={1.75}\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden\n >\n <path d=\"M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z\" />\n <circle cx=\"12\" cy=\"13\" r=\"4\" />\n </svg>\n )\n}\n\nfunction HideIcon() {\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width={1.75}\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden\n >\n <path d=\"M17.94 17.94A10.7 10.7 0 0 1 12 19c-6.5 0-10-7-10-7a18.5 18.5 0 0 1 5.06-5.94\" />\n <path d=\"M9.9 4.24A10.7 10.7 0 0 1 12 4c6.5 0 10 7 10 7a18.5 18.5 0 0 1-2.16 3.19\" />\n <path d=\"m1 1 22 22\" />\n <path d=\"M14.12 14.12a3 3 0 0 1-4.24-4.24\" />\n </svg>\n )\n}\n","import type { ComponentChildren } from 'preact'\nimport { useEffect, useRef } from 'preact/hooks'\n\nimport { cx } from '../utils'\n\ntype ToolbarPosition = 'bottom-right' | 'bottom-left' | 'bottom-center'\n\n/** Which auxiliary surface a `PanelPopover` is hosting. */\nexport type PanelKind = 'inbox' | 'privacy' | 'shortcuts'\n\n/**\n * Floating surface anchored to the toolbar's corner, used for the panels\n * that are too tall to live inside a menu: the notifications inbox, the\n * privacy summary, and the shortcut reference. Mounted by `app.tsx`\n * alongside the toolbar rather than inside it, because the toolbar's\n * `overflow: hidden` would clip anything taller than the pill.\n *\n * `kind` drives both the wrapper width (`data-panel`) and the inner\n * surface chrome (`.markup-pop[data-pop]`), so the three panels share\n * one positioning + dismissal implementation and differ only in CSS.\n *\n * Light-dismiss: clicking outside the panel or pressing Escape closes\n * it. Uses `composedPath()` to detect inside-shadow targets, same as\n * the menu components.\n */\nexport function PanelPopover({\n kind,\n label,\n position,\n ignoreToolbarKind,\n onClose,\n children,\n}: {\n kind: PanelKind\n /** Accessible name for the dialog surface. */\n label: string\n position: ToolbarPosition\n /**\n * `data-kind` of the toolbar button that toggles this panel, when it\n * has one. A click on that button must not count as an outside-click:\n * the button's own handler already toggles the panel shut, and if both\n * fired the panel would close and immediately re-open.\n */\n ignoreToolbarKind?: string\n onClose: () => void\n children: ComponentChildren\n}) {\n const containerRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n function onDocClick(e: MouseEvent) {\n const el = containerRef.current\n if (!el) return\n const path = e.composedPath()\n if (path.includes(el)) return\n if (\n ignoreToolbarKind != null &&\n path.some((n) => (n as HTMLElement)?.dataset?.kind === ignoreToolbarKind)\n ) {\n return\n }\n onClose()\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') onClose()\n }\n document.addEventListener('click', onDocClick, true)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('click', onDocClick, true)\n document.removeEventListener('keydown', onKey)\n }\n }, [onClose, ignoreToolbarKind])\n\n const sideClass =\n position === 'bottom-left'\n ? 'markup-panel-pop-left'\n : position === 'bottom-center'\n ? 'markup-panel-pop-center'\n : 'markup-panel-pop-right'\n\n return (\n <div\n ref={containerRef}\n class={cx('markup-panel-pop', sideClass)}\n data-panel={kind}\n role=\"dialog\"\n aria-label={label}\n >\n <div class=\"markup-pop\" data-pop={kind}>\n {children}\n </div>\n </div>\n )\n}\n","import { cx } from '../utils'\n\n/**\n * A single anchored pin marker. Position is set inline because it changes on\n * every render (scroll/resize) and Tailwind's compile-time classes can't\n * express dynamic pixel coords.\n */\nexport function Pin({\n pageX,\n pageY,\n count,\n isActive,\n isUnresolved,\n onClick,\n}: {\n pageX: number\n pageY: number\n count: number\n isActive: boolean\n /**\n * `true` when the pin's anchor selector didn't match a live element\n * and we're showing it at the fraction-based fallback position. Surfaces\n * a dimmed style so the wrong-looking position reads as tentative rather\n * than authoritative. Stays clickable — opening the thread is still useful\n * even if the spatial anchor is off.\n */\n isUnresolved: boolean\n onClick: () => void\n}) {\n // The host element is `position: fixed`, so subtract scroll to get\n // viewport-relative coords for `top` / `left`.\n const top = pageY - window.scrollY\n const left = pageX - window.scrollX\n // `popovertarget` tells the browser this button intentionally interacts\n // with the thread popover, so the pointerdown light-dismiss is suppressed\n // when transitioning from one open thread to another.\n return (\n <button\n type=\"button\"\n class={cx('markup-pin', isActive && 'is-active is-anchor', isUnresolved && 'is-unresolved')}\n style={{ top: `${top}px`, left: `${left}px` }}\n popovertarget=\"markup-thread-popover\"\n popovertargetaction=\"show\"\n onClick={onClick}\n aria-label={`Open feedback thread (${count} comment${count === 1 ? '' : 's'})`}\n title={`Open feedback thread (${count} comment${count === 1 ? '' : 's'})`}\n >\n <span class=\"markup-pin-num\">{count}</span>\n </button>\n )\n}\n\n/**\n * Ghost pin shown at the just-clicked location while the composer for a brand\n * new thread is open. Same visual as a real pin, no click handler. Carries\n * `is-anchor` so the new-thread popover can anchor-position to it.\n */\nexport function GhostPin({ pageX, pageY }: { pageX: number; pageY: number }) {\n const top = pageY - window.scrollY\n const left = pageX - window.scrollX\n return (\n <div\n class=\"markup-pin markup-pin-ghost is-anchor\"\n style={{ top: `${top}px`, left: `${left}px` }}\n >\n <span class=\"markup-pin-num\" aria-hidden>\n +\n </span>\n </div>\n )\n}\n","import { useLayoutEffect } from 'preact/hooks'\n\nimport { toPageCoords, type PageCoords } from '../anchor'\n\n/**\n * Full-viewport overlay that captures the next click and translates it into\n * normalised page coordinates. Mounts only while in placing mode; ESC cancels.\n */\nexport function PlacementOverlay({\n onPlace,\n onCancel,\n}: {\n onPlace: (coords: PageCoords, screenX: number, screenY: number) => void\n onCancel: () => void\n}) {\n /* Layout effect, not a plain one: `useEffect` is deferred to after\n * paint (rAF, with a 100 ms timeout fallback), so on a busy machine\n * the overlay is on screen and taking clicks for a beat before ESC\n * does anything. A user who hits ESC in that window — or an e2e test\n * that acts the moment the overlay appears — gets the key dropped and\n * stays stuck in placement mode. Registering during commit closes the\n * gap: the listener exists before the overlay is ever visible.\n *\n * Safe to bind synchronously here because it's only `keydown`. The\n * menus and panels deliberately keep the deferred effect — they also\n * bind an outside-click listener, and binding that during the very\n * click that opened them would dismiss them immediately. */\n useLayoutEffect(() => {\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') onCancel()\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [onCancel])\n\n function handleClick(e: MouseEvent) {\n e.stopPropagation()\n e.preventDefault()\n // elementsFromPoint returns light-DOM elements top-to-bottom. Our widget\n // host is the only element with a shadowRoot — skip it to get the real\n // page element underneath the overlay.\n const elements = document.elementsFromPoint(e.clientX, e.clientY)\n const pageTarget = elements.find((el) => !el.shadowRoot) ?? null\n const coords = toPageCoords(e, pageTarget)\n onPlace(coords, e.clientX, e.clientY)\n }\n\n // Prevent the click from bubbling up to the document and triggering dismiss of other elements\n // this works for Radix-UI elements like Popover and Menu\n function handlePointerDown(e: PointerEvent) {\n e.preventDefault()\n e.stopPropagation()\n }\n\n return (\n <div\n class=\"markup-placement-overlay\"\n onPointerDown={handlePointerDown}\n onClick={handleClick}\n role=\"presentation\"\n >\n <div class=\"markup-placement-cursor-help\">\n <span>Click anywhere to drop a pin · ESC to cancel</span>\n </div>\n </div>\n )\n}\n","import { useState } from 'preact/hooks'\n\nimport { displayNameOf, type IdentityState } from '../identity-store'\nimport { cx } from '../utils'\nimport { IconClose } from './icons'\n\n/**\n * Every claim here describes runtime behaviour, not policy, and reflects the\n * *current* session, so a visitor can verify it rather than take it on faith.\n * The sources are `identity-store.ts`, `api.ts#createThread`, `screenshot.ts`,\n * `error-reporter.ts` and `POST /widget/forget-me`.\n *\n * Keep the copy honest when any of those change — this is the surface end\n * users are most likely to read closely.\n */\nexport function PrivacyPanel({\n identity,\n apiUrl,\n autoCapture,\n autoCaptureLocked,\n isForgettingMe,\n forgetMeError,\n onForgetMe,\n onClose,\n}: {\n identity: IdentityState\n /** Deployment URL; only its host is shown, as the one network destination. */\n apiUrl: string\n autoCapture: boolean\n /** The host site disabled captures outright — see `OverflowMenu`. */\n autoCaptureLocked: boolean\n isForgettingMe: boolean\n forgetMeError?: string\n onForgetMe: () => void\n onClose: () => void\n}) {\n // Irreversible, on a surface people are reading rather than operating.\n const [confirmForget, setConfirmForget] = useState(false)\n\n const name = displayNameOf(identity)\n const isVerified = identity.kind === 'verified'\n const email = isVerified ? identity.identity.email : undefined\n // The endpoint authenticates with the anon token; a signed-in user's path\n // is Sign out instead.\n const canForget = identity.kind === 'anon'\n\n return (\n <div class=\"markup-panel\">\n <header class=\"markup-panel-header\">\n <span class=\"markup-eyebrow\">privacy & data</span>\n <button\n type=\"button\"\n class=\"markup-icon-btn\"\n title=\"Close\"\n aria-label=\"Close privacy and data\"\n onClick={onClose}\n >\n <IconClose size={14} />\n </button>\n </header>\n\n <div class=\"markup-panel-body\">\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">who you are here</h4>\n {isVerified ? (\n <p class=\"markup-panel-text\">\n Signed in as <strong>{name ?? 'you'}</strong>\n {email ? <span class=\"markup-panel-mono\"> {email}</span> : null}. Comments you post\n carry that name, and your email is visible to this project's team.\n </p>\n ) : name ? (\n <p class=\"markup-panel-text\">\n You post as <strong>{name}</strong> — an anonymous commenter with a random id that\n only means anything on this site.\n </p>\n ) : (\n <p class=\"markup-panel-text\">\n You're anonymous. Markup holds a random id scoped to this site and asks for a name the\n first time you post.\n </p>\n )}\n </section>\n\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">what posting sends</h4>\n <ul class=\"markup-panel-list\">\n <li>What you wrote, under the name (and email, if you gave one) you post with</li>\n <li>This page's URL, your window size, and your browser's user-agent</li>\n <li>A screenshot — only the ones you attach yourself</li>\n </ul>\n </section>\n\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">kept in this browser</h4>\n <ul class=\"markup-panel-list\">\n <li>\n {isVerified\n ? \"Your sign-in token, held in this site's storage or in a cookie only this site can send\"\n : \"Your commenter id and the token that proves it, in this site's storage\"}\n </li>\n <li>Your appearance and toolbar-position picks</li>\n </ul>\n <p class=\"markup-panel-note\">\n All of it is scoped to this site, so the same browser on another site is a different\n commenter to us. Nothing here follows you between sites.\n </p>\n </section>\n\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">screenshots</h4>\n <p class=\"markup-panel-text\">\n {autoCaptureLocked\n ? 'This site turned captures off, so none are taken.'\n : autoCapture\n ? 'Captured when you drop a pin. Passwords, card numbers and one-time codes are blacked out before the image exists, and the composer lists what it covered. Nothing uploads unless you post with it attached.'\n : 'Auto-capture is off, so no screenshots are taken. You can turn it back on from the menu.'}\n </p>\n </section>\n\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">where it goes</h4>\n <p class=\"markup-panel-text\">\n Only <span class=\"markup-panel-mono\">{apiHostOf(apiUrl)}</span>. No analytics, no ad\n tech, no third-party requests from the widget. If the widget itself crashes it posts the\n error, this page's URL and your user-agent to that same host, never your identity or\n what you were writing.\n </p>\n </section>\n\n {canForget ? (\n <section class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">erase what you left</h4>\n <p class=\"markup-panel-text\">\n Removes every comment and reaction this browser posted on this site, and clears the\n name and email held for you. Replies from other people stay.\n </p>\n <button\n type=\"button\"\n class={cx('markup-panel-action', confirmForget && 'is-danger')}\n disabled={isForgettingMe}\n onClick={() => {\n if (confirmForget) {\n onForgetMe()\n setConfirmForget(false)\n } else {\n setConfirmForget(true)\n }\n }}\n >\n {isForgettingMe\n ? 'Erasing…'\n : confirmForget\n ? 'Confirm: erase and forget me'\n : 'Forget me on this site…'}\n </button>\n {forgetMeError ? <p class=\"markup-panel-error\">{forgetMeError}</p> : null}\n </section>\n ) : null}\n </div>\n </div>\n )\n}\n\n/**\n * Falls back to the raw string: the value comes from the host's own `init()`\n * config, so a malformed one is theirs to see rather than hide.\n */\nfunction apiHostOf(apiUrl: string): string {\n try {\n return new URL(apiUrl).host\n } catch {\n return apiUrl\n }\n}\n","import { platformKeys } from '../utils'\nimport { IconClose } from './icons'\n\n/**\n * Keyboard reference for the widget, opened from the overflow menu's\n * **Keyboard shortcuts** row. Renders inside a `PanelPopover` anchored\n * to the toolbar corner.\n *\n * The rows are the shortcuts the runtime actually implements — every\n * entry below maps to a live handler:\n *\n * - `c` / `mod .` — `app.tsx` window keydown listeners\n * - `Esc` — `placement-overlay.tsx` (cancel) and the menu/panel\n * light-dismiss handlers; the mention picker consumes it first\n * while a composer's `@` list is open (`mentions.tsx`)\n * - `@`, arrows, `Enter`/`Tab` — `mentions.tsx#handleKeyDown`\n * - `mod Enter` — `composer.tsx#onKey`\n *\n * Chord labels come from `platformKeys()` so Windows and Linux readers\n * see `Ctrl`/`Enter` where a Mac reader sees `⌘`/`↵`.\n */\nexport function ShortcutsPanel({ onClose }: { onClose: () => void }) {\n const { mod, enter } = platformKeys()\n\n /* Each shortcut lists one or more chords, joined by \"or\" — the picker\n * accepts Enter *or* Tab, for instance, and both belong on one row. */\n const groups: { title: string; items: { chords: string[][]; label: string }[] }[] = [\n {\n title: 'on the page',\n items: [\n { chords: [['c']], label: 'Start a markup' },\n { chords: [[mod, '.']], label: 'Show or hide Markup' },\n { chords: [['Esc']], label: 'Cancel placement, or close a menu' },\n ],\n },\n {\n title: 'while writing',\n items: [\n { chords: [['@']], label: 'Mention a teammate' },\n { chords: [['↑'], ['↓']], label: 'Move through the member list' },\n { chords: [[enter], ['Tab']], label: 'Pick the highlighted member' },\n { chords: [[mod, enter]], label: 'Post the comment' },\n { chords: [['Esc']], label: 'Dismiss the member list' },\n ],\n },\n ]\n\n return (\n <div class=\"markup-panel\">\n <header class=\"markup-panel-header\">\n <span class=\"markup-eyebrow\">keyboard shortcuts</span>\n <button\n type=\"button\"\n class=\"markup-icon-btn\"\n title=\"Close\"\n aria-label=\"Close keyboard shortcuts\"\n onClick={onClose}\n >\n <IconClose size={14} />\n </button>\n </header>\n\n <div class=\"markup-panel-body\">\n {groups.map((group) => (\n <section key={group.title} class=\"markup-panel-section\">\n <h4 class=\"markup-panel-section-title\">{group.title}</h4>\n <ul class=\"markup-shortcut-list\">\n {group.items.map((item) => (\n <li key={item.label} class=\"markup-shortcut-row\">\n <span class=\"markup-shortcut-label\">{item.label}</span>\n <span class=\"markup-shortcut-keys\">\n {item.chords.map((chord, i) => (\n <span key={chord.join('+')} class=\"markup-shortcut-chord\">\n {i > 0 ? <span class=\"markup-shortcut-or\">or</span> : null}\n {chord.map((key) => (\n <kbd key={key} class=\"markup-kbd is-inline\">\n {key}\n </kbd>\n ))}\n </span>\n ))}\n </span>\n </li>\n ))}\n </ul>\n </section>\n ))}\n\n <p class=\"markup-panel-note\">\n {mod}-click the comment button to hide Markup without opening the menu. Drag a popover's\n header to move it off whatever it covers.\n </p>\n </div>\n </div>\n )\n}\n","import { useEffect, useMemo, useRef, useState } from 'preact/hooks'\n\nimport { defineMachine, useMachine } from '../../lib/machine'\nimport { resolveCoords } from '../anchor'\nimport { useDrag } from '../use-drag'\nimport { useFocusTrap } from '../use-focus-trap'\nimport { cx } from '../utils'\nimport { AuthorPrompt } from './author-prompt'\nimport { Composer } from './composer'\nimport { IconBot, IconCheck, IconClose, IconEllipsis, IconSmile } from './icons'\nimport { MentionInput } from './mention-input'\nimport { MentionizedBody, type MentionableMember } from './mentions'\nimport type { WidgetThread } from '../api'\n\n/**\n * Must stay in sync with `convex/lib/reactions.ts`, which validates against the\n * same list and sorts chips by this order so chips and picker line up.\n */\nconst REACTION_PALETTE = ['👍', '❤️', '🎉', '😮', '😄', '❓'] as const\n\n/**\n * A union so the four overlays are mutually exclusive by construction: opening\n * one atomically closes the others. Confirm-delete arming and menu direction\n * live inside their parent overlay, so they reset for free when it closes.\n */\ntype Overlay =\n | { kind: 'none' }\n | { kind: 'thread-menu'; confirmDelete: boolean }\n | {\n kind: 'comment-menu'\n commentId: string\n direction: 'down' | 'up'\n confirmDelete: boolean\n }\n | { kind: 'reaction-picker'; commentId: string; direction: 'down' | 'up' }\n | { kind: 'editing'; commentId: string; draft: string }\n\n/**\n * `toggle-*` opens from `none` and closes from the matching kind. `arm-*-delete`\n * is the first half of confirm-delete; the second half fires the host callback\n * and dispatches `dismiss`. Direction is computed at the call site so these\n * transitions need no DOM access.\n */\ntype OverlayEvent =\n | { type: 'toggle-thread-menu' }\n | { type: 'arm-thread-delete' }\n | { type: 'toggle-comment-menu'; commentId: string; direction: 'down' | 'up' }\n | { type: 'arm-comment-delete' }\n | { type: 'toggle-reaction-picker'; commentId: string; direction: 'down' | 'up' }\n | { type: 'start-edit'; commentId: string; body: string }\n | { type: 'update-draft'; draft: string }\n | { type: 'dismiss' }\n\nconst overlayMachine = defineMachine<Overlay, OverlayEvent>({\n none: {\n 'toggle-thread-menu': () => ({ kind: 'thread-menu', confirmDelete: false }),\n 'toggle-comment-menu': (_, e) => ({\n kind: 'comment-menu',\n commentId: e.commentId,\n direction: e.direction,\n confirmDelete: false,\n }),\n 'toggle-reaction-picker': (_, e) => ({\n kind: 'reaction-picker',\n commentId: e.commentId,\n direction: e.direction,\n }),\n 'start-edit': (_, e) => ({ kind: 'editing', commentId: e.commentId, draft: e.body }),\n },\n 'thread-menu': {\n 'toggle-thread-menu': () => ({ kind: 'none' }),\n 'arm-thread-delete': (s) => ({ ...s, confirmDelete: true }),\n dismiss: () => ({ kind: 'none' }),\n },\n 'comment-menu': {\n // Only the matching comment can re-toggle; the outside-click effect\n // already closes this before a foreign click lands.\n 'toggle-comment-menu': (s, e) => (s.commentId === e.commentId ? { kind: 'none' } : s),\n 'arm-comment-delete': (s) => ({ ...s, confirmDelete: true }),\n // Straight into the edit form: the menu is already open on this comment,\n // so a dismiss step would just be visual churn.\n 'start-edit': (_, e) => ({ kind: 'editing', commentId: e.commentId, draft: e.body }),\n dismiss: () => ({ kind: 'none' }),\n },\n 'reaction-picker': {\n 'toggle-reaction-picker': (s, e) => (s.commentId === e.commentId ? { kind: 'none' } : s),\n dismiss: () => ({ kind: 'none' }),\n },\n editing: {\n // The machine ignores `update-draft` from any other state, so no guard.\n 'update-draft': (s, e) => ({ ...s, draft: e.draft }),\n dismiss: () => ({ kind: 'none' }),\n },\n})\n\n/**\n * `popover=\"auto\"` supplies top-layer rendering, ESC and outside-click\n * dismissal. Position falls back to JS-clamped coords in custom properties\n * where CSS Anchor Positioning isn't supported.\n */\nexport function ThreadPopover({\n thread,\n authorName,\n currentClientId,\n isVerified,\n isIdentityResolving,\n isSigningIn,\n canDelete,\n isPending,\n error,\n isHidden = false,\n members = [],\n onAuthor,\n onSignIn,\n onClose,\n onReply,\n onEditComment,\n onDeleteComment,\n onToggleReaction,\n onResolve,\n onDelete,\n}: {\n thread: WidgetThread\n authorName: string | null\n /**\n * Decides which comments show Edit. Matching `authorClientId` is sufficient\n * because the JWT path uses the same canonical `markup_user_<sub>` form.\n */\n currentClientId: string | null\n isVerified: boolean\n /** Anon mint hasn't completed yet — disable the guest path. */\n isIdentityResolving: boolean\n /** A popup sign-in is already in flight — disable the sign-in button. */\n isSigningIn: boolean\n canDelete: boolean\n isPending: boolean\n error: string | undefined\n /** Kept mounted so a draft, edit or drag position survives a HUD peek. */\n isHidden?: boolean\n /** Empty disables the picker. */\n members?: readonly MentionableMember[]\n onAuthor: (name: string, email?: string) => void\n onSignIn: () => void\n onClose: () => void\n onReply: (body: string) => void\n /** Must reject on failure, or the form closes over an unsaved draft. */\n onEditComment: (commentId: string, body: string) => Promise<void>\n onDeleteComment: (commentId: string) => void\n /** No optimistic update — the host swaps in the server's response. */\n onToggleReaction: (commentId: string, emoji: string) => void\n onResolve: () => void\n onDelete: () => void\n}) {\n const ref = useRef<HTMLDivElement>(null)\n const commentsRef = useRef<HTMLOListElement>(null)\n const dialogRef = useRef<HTMLDialogElement>(null)\n // Written by whichever overlay is active, via a gated inline ref callback,\n // and read by the single outside-click effect below.\n const overlayElRef = useRef<HTMLElement | null>(null)\n const [overlay, sendOverlay] = useMachine(overlayMachine, { kind: 'none' })\n // `null` means anchor/fallback coords. Resets on mount, so reopening a\n // thread snaps the popover back to its pin.\n const [dragPos, setDragPos] = useState<{ left: number; top: number } | null>(null)\n // The handle is the header, but the measured target is the popover — that's\n // what moves. Buttons are excluded so their clicks still work.\n const { onPointerDown: onHeaderPointerDown, isDragging } = useDrag({\n targetRef: ref,\n shouldStart: (e) => {\n const target = e.target as HTMLElement | null\n return !target?.closest('button, a, input, textarea, select')\n },\n onMove: setDragPos,\n })\n useFocusTrap(ref, true)\n\n const isResolved = thread.resolvedAt != null\n // Soft-delete exists for referential integrity, not display. The server's\n // first-comment guard still uses the real earliest comment, so a deleted row\n // preceding everything visible can't be deleted by mistake.\n const visibleComments = useMemo(\n () => thread.comments.filter((c) => !c.deleted),\n [thread.comments],\n )\n\n // One handler for all four overlays, reading whichever element is active.\n // Closing resets confirm-delete arming for free, since that lives inside\n // the overlay's own state.\n useEffect(() => {\n if (overlay.kind === 'none' || overlay.kind === 'editing') return\n function onDown(e: MouseEvent) {\n const el = overlayElRef.current\n if (el && !e.composedPath().includes(el)) {\n sendOverlay({ type: 'dismiss' })\n }\n }\n document.addEventListener('mousedown', onDown)\n return () => document.removeEventListener('mousedown', onDown)\n }, [overlay.kind, sendOverlay])\n\n // Only for a comment that vanished. A failed save leaves the draft intact,\n // because the submit handler cancels on resolve rather than on settle.\n useEffect(() => {\n if (overlay.kind !== 'editing') return\n const c = thread.comments.find((c) => c._id === overlay.commentId)\n if (!c || c.deleted) sendOverlay({ type: 'dismiss' })\n }, [thread.comments, overlay, sendOverlay])\n\n const isFirstOpen = useRef(true)\n useEffect(() => {\n const el = commentsRef.current\n if (!el) return\n if (isFirstOpen.current) {\n isFirstOpen.current = false\n el.scrollTop = el.scrollHeight\n return\n }\n const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight\n if (distanceFromBottom < 80) el.scrollTop = el.scrollHeight\n }, [visibleComments.length])\n\n // Sync state back when the browser closes it — ESC, outside click.\n useEffect(() => {\n const el = ref.current\n if (!el) return\n\n if (typeof el.showPopover === 'function' && !el.matches(':popover-open')) {\n try {\n el.showPopover()\n } catch {\n /* element may already be showing or unsupported */\n }\n }\n\n function onToggle(e: Event) {\n const ev = e as ToggleEvent\n if (ev.newState === 'closed') onClose()\n }\n el.addEventListener('toggle', onToggle)\n return () => el.removeEventListener('toggle', onToggle)\n }, [onClose])\n\n // Fallback coords for browsers without anchor positioning.\n const fallback = useMemo(() => {\n const point = resolveCoords({\n anchorX: thread.anchorX,\n anchorY: thread.anchorY,\n anchorSelector: thread.anchorSelector,\n })\n const width = 320\n const margin = 12\n const left = clamp(\n point.pageX - window.scrollX + 16,\n margin,\n window.innerWidth - width - margin,\n )\n const top = clamp(point.pageY - window.scrollY - 16, margin, window.innerHeight - 200)\n return { left, top }\n }, [thread.anchorX, thread.anchorY, thread.anchorSelector])\n\n return (\n <div\n ref={ref}\n id=\"markup-thread-popover\"\n class={cx(\n 'markup-popover',\n dragPos && 'is-floating',\n isDragging && 'is-dragging',\n isHidden && 'is-hud-hidden',\n )}\n popover=\"auto\"\n style={{\n '--markup-pop-x': `${dragPos?.left ?? fallback.left}px`,\n '--markup-pop-y': `${dragPos?.top ?? fallback.top}px`,\n }}\n role=\"dialog\"\n aria-label=\"Markup thread\"\n aria-hidden={isHidden || undefined}\n >\n <header class=\"markup-popover-header\" onPointerDown={onHeaderPointerDown}>\n {/* Not the URL. The widget only ever shows threads for the page\n you are already on, so the address was telling you something\n you could read in your own address bar — and it was the one\n piece of the header that could not be shortened, since the\n host must render in full to mean anything. The count is what\n the pin you clicked was showing, so the header now confirms\n you opened the right one. Full URL stays on hover for a\n popover dragged away from its pin. */}\n <span class=\"markup-popover-title\" title={thread.url}>\n {visibleComments.length === 1 ? '1 comment' : `${visibleComments.length} comments`}\n </span>\n <div class=\"markup-popover-header-actions\">\n <div\n class=\"markup-thread-menu\"\n ref={(el) => {\n if (overlay.kind === 'thread-menu') overlayElRef.current = el\n }}\n >\n <button\n type=\"button\"\n class={cx('markup-icon-btn', overlay.kind === 'thread-menu' && 'is-open')}\n title=\"More options\"\n onClick={() => sendOverlay({ type: 'toggle-thread-menu' })}\n >\n <IconEllipsis size={16} />\n </button>\n {overlay.kind === 'thread-menu' ? (\n <div class=\"markup-thread-menu-list\">\n <button\n type=\"button\"\n class=\"markup-thread-menu-item\"\n onClick={() => {\n const url = new URL(thread.url)\n url.hash = `markup-thread=${thread._id}`\n navigator.clipboard.writeText(url.toString()).catch(() => {})\n sendOverlay({ type: 'dismiss' })\n }}\n >\n Copy link\n </button>\n {canDelete ? (\n <button\n type=\"button\"\n class={cx('markup-thread-menu-item', overlay.confirmDelete && 'is-danger')}\n disabled={isPending}\n onClick={() => {\n // Two-step: first click arms (confirmDelete: true),\n // second click commits via the host then dismisses.\n if (overlay.kind !== 'thread-menu') return\n if (overlay.confirmDelete) {\n sendOverlay({ type: 'dismiss' })\n onDelete()\n } else {\n sendOverlay({ type: 'arm-thread-delete' })\n }\n }}\n >\n {overlay.confirmDelete ? 'Confirm delete' : 'Delete thread…'}\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n {isVerified ? (\n <button\n type=\"button\"\n class=\"markup-icon-btn\"\n title=\"Mark as resolved\"\n disabled={isPending}\n onClick={onResolve}\n >\n <IconCheck size={16} />\n </button>\n ) : null}\n <button type=\"button\" class=\"markup-icon-btn\" title=\"Close thread\" onClick={onClose}>\n <IconClose size={16} />\n </button>\n </div>\n </header>\n\n <ol ref={commentsRef} class=\"markup-comments\">\n {visibleComments.map((c, i) => {\n const isOwn =\n !c.fromDashboard && currentClientId != null && c.authorClientId === currentClientId\n const isFirst = i === 0\n const canEdit = isOwn && !isResolved && !c.deleted\n const canDelete = isOwn && !isResolved && !c.deleted && !isFirst\n const isEditing = overlay.kind === 'editing' && overlay.commentId === c._id\n const hasMenu = (canEdit || canDelete) && !isEditing && !c.deleted\n const isMenuOpen = overlay.kind === 'comment-menu' && overlay.commentId === c._id\n const isDeletePending = isMenuOpen && overlay.confirmDelete\n const isPickerOpen = overlay.kind === 'reaction-picker' && overlay.commentId === c._id\n const pickerDirection = isPickerOpen ? overlay.direction : 'down'\n const menuDirection = isMenuOpen ? overlay.direction : 'down'\n return (\n <li key={c._id} class=\"markup-comment\">\n <CommentAvatar\n name={c.authorName}\n image={c.authorImage}\n tone={authorTone(c.authorClientId ?? c.authorName)}\n />\n <div class=\"markup-comment-meta\">\n <span class=\"markup-comment-author\">{c.authorName}</span>\n {/* Nothing here marks the author as team. `fromDashboard`\n is only \"the author had no host page\", which lumps\n dashboard replies in with agent writes, so neither the\n badge nor the name tint it used to drive said anything\n a reader could act on. The field itself stays — the\n `isOwn` check above needs it — it just no longer\n decides how the author renders.\n\n Human vs. agent is the distinction that matters to\n someone reading a reply, and this badge carries it:\n the comment has a real person's name on it, so a\n visitor must be able to tell a machine wrote it. */}\n {c.authoredVia === 'mcp' ? (\n <span\n class=\"markup-comment-badge is-agent\"\n role=\"img\"\n aria-label=\"Written by an AI agent\"\n title=\"Written by an AI agent\"\n >\n <IconBot size={11} />\n </span>\n ) : null}\n <time\n class=\"markup-comment-time\"\n datetime={new Date(c.createdAt).toISOString()}\n title={formatTime(c.createdAt)}\n >\n {relativeTime(c.createdAt)}\n </time>\n {c.editedAt != null ? (\n <time\n class=\"markup-comment-edited\"\n datetime={new Date(c.editedAt).toISOString()}\n title={formatTime(c.editedAt)}\n >\n edited\n </time>\n ) : null}\n <div class=\"markup-thread-actions\">\n {!isResolved && !isEditing ? (\n <ReactionAdd\n comment={c}\n pickerOpen={isPickerOpen}\n pickerDirection={pickerDirection}\n pickerSide={visibleComments.length === 1}\n pickerRef={(el) => {\n if (isPickerOpen) overlayElRef.current = el\n }}\n onPickerClick={(e) => {\n if (isPickerOpen) {\n sendOverlay({\n type: 'toggle-reaction-picker',\n commentId: c._id,\n direction: 'down',\n })\n return\n }\n // With a single comment the popover is too short\n // for a vertical picker to fit; we anchor it to\n // the left of the trigger instead (see `.is-side`).\n if (visibleComments.length === 1) {\n sendOverlay({\n type: 'toggle-reaction-picker',\n commentId: c._id,\n direction: 'down',\n })\n return\n }\n // Same flip-above measurement as the comment menu\n // — the picker is taller (one row of 6 chips\n // ~36px), so we account for that explicitly.\n const trigger = e.currentTarget as HTMLElement\n const triggerRect = trigger.getBoundingClientRect()\n const containerRect = commentsRef.current?.getBoundingClientRect()\n const estimatedHeight = 44\n const spaceBelow = containerRect\n ? containerRect.bottom - triggerRect.bottom\n : Number.POSITIVE_INFINITY\n sendOverlay({\n type: 'toggle-reaction-picker',\n commentId: c._id,\n direction: spaceBelow < estimatedHeight ? 'up' : 'down',\n })\n }}\n onPickerSelect={(emoji) => {\n sendOverlay({ type: 'dismiss' })\n onToggleReaction(c._id, emoji)\n }}\n />\n ) : null}\n {hasMenu ? (\n <div\n class={cx(\n 'markup-thread-menu markup-comment-menu',\n isMenuOpen && 'is-open',\n isMenuOpen && menuDirection === 'up' && 'is-up',\n visibleComments.length === 1 && 'is-side',\n )}\n ref={(el: HTMLDivElement | null) => {\n if (isMenuOpen) overlayElRef.current = el\n }}\n >\n <button\n type=\"button\"\n class={cx('markup-icon-btn', isMenuOpen && 'is-open')}\n title=\"More options\"\n onClick={(e) => {\n if (isMenuOpen) {\n sendOverlay({\n type: 'toggle-comment-menu',\n commentId: c._id,\n direction: 'down',\n })\n return\n }\n // With a single comment, the popover is too short\n // for a vertical dropdown to fit, so we open it to\n // the left of the trigger (see `.is-side` in CSS)\n // and skip the up/down measurement entirely.\n if (visibleComments.length === 1) {\n sendOverlay({\n type: 'toggle-comment-menu',\n commentId: c._id,\n direction: 'down',\n })\n return\n }\n // Decide direction before opening so the dropdown\n // never appears clipped at the bottom of the scroll\n // container. Estimate menu height from the visible\n // items (~32px per item + 8px padding).\n const trigger = e.currentTarget as HTMLElement\n const triggerRect = trigger.getBoundingClientRect()\n const containerRect = commentsRef.current?.getBoundingClientRect()\n const itemCount = (canEdit ? 1 : 0) + (canDelete ? 1 : 0)\n const estimatedHeight = itemCount * 32 + 8 + 6\n const spaceBelow = containerRect\n ? containerRect.bottom - triggerRect.bottom\n : Number.POSITIVE_INFINITY\n sendOverlay({\n type: 'toggle-comment-menu',\n commentId: c._id,\n direction: spaceBelow < estimatedHeight ? 'up' : 'down',\n })\n }}\n >\n <IconEllipsis size={16} />\n </button>\n {isMenuOpen ? (\n <div class=\"markup-thread-menu-list\">\n {canEdit ? (\n <button\n type=\"button\"\n class=\"markup-thread-menu-item\"\n onClick={() => {\n sendOverlay({\n type: 'start-edit',\n commentId: c._id,\n body: c.body,\n })\n }}\n >\n Edit\n </button>\n ) : null}\n {canDelete ? (\n <button\n type=\"button\"\n class={cx('markup-thread-menu-item', isDeletePending && 'is-danger')}\n onClick={() => {\n if (overlay.kind !== 'comment-menu') return\n if (overlay.confirmDelete) {\n sendOverlay({ type: 'dismiss' })\n onDeleteComment(c._id)\n } else {\n sendOverlay({ type: 'arm-comment-delete' })\n }\n }}\n >\n {isDeletePending ? 'Confirm delete' : 'Delete…'}\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n </div>\n {isEditing && overlay.kind === 'editing' ? (\n <form\n class=\"markup-comment-edit-form\"\n onSubmit={async (e) => {\n e.preventDefault()\n if (overlay.kind !== 'editing') return\n const next = overlay.draft.trim()\n if (!next || next === c.body) {\n sendOverlay({ type: 'dismiss' })\n return\n }\n try {\n await onEditComment(c._id, next)\n sendOverlay({ type: 'dismiss' })\n } catch {\n /* leave the form open so the user can fix and retry;\n * the host renders the error toast from `error`. */\n }\n }}\n >\n {/* Same editor as the composer, so an existing comment's\n * mentions show as chips while being edited rather than\n * reverting to raw markers — and new ones can be added. */}\n <MentionInput\n class=\"markup-comment-edit-input\"\n label=\"Edit comment\"\n value={overlay.draft}\n onChange={(draft) => sendOverlay({ type: 'update-draft', draft })}\n members={members}\n autoFocus\n disabled={isPending}\n />\n <div class=\"markup-comment-edit-actions\">\n <button\n type=\"button\"\n class=\"markup-btn markup-btn-ghost\"\n onClick={() => sendOverlay({ type: 'dismiss' })}\n disabled={isPending}\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n class=\"markup-btn markup-btn-primary\"\n disabled={isPending || overlay.draft.trim().length === 0}\n >\n Save\n </button>\n </div>\n </form>\n ) : (\n <MentionizedBody body={c.body} mentions={c.mentions} />\n )}\n {i === 0 && thread.screenshotUrl ? (\n <button\n type=\"button\"\n class=\"markup-comment-screenshot\"\n onClick={() => dialogRef.current?.showModal()}\n >\n <img src={thread.screenshotUrl} alt=\"Screenshot\" />\n </button>\n ) : null}\n {!isEditing && c.reactions.length > 0 ? (\n <ReactionChips\n comment={c}\n isResolved={isResolved}\n onToggle={(emoji) => onToggleReaction(c._id, emoji)}\n />\n ) : null}\n </li>\n )\n })}\n </ol>\n\n {thread.screenshotUrl ? (\n <dialog ref={dialogRef} class=\"markup-lightbox\" onClick={() => dialogRef.current?.close()}>\n <button\n type=\"button\"\n class=\"markup-lightbox-close markup-icon-btn\"\n aria-label=\"Close screenshot\"\n onClick={(e) => {\n e.stopPropagation()\n dialogRef.current?.close()\n }}\n >\n <IconClose size={16} />\n </button>\n <img\n class=\"markup-lightbox-img\"\n src={thread.screenshotUrl}\n alt=\"Screenshot\"\n onClick={(e) => e.stopPropagation()}\n />\n </dialog>\n ) : null}\n\n {authorName == null ? (\n <AuthorPrompt\n isPending={isPending}\n isConnecting={isIdentityResolving}\n isSigningIn={isSigningIn}\n onSubmit={onAuthor}\n onCancel={onClose}\n onSignIn={onSignIn}\n />\n ) : (\n <div class=\"markup-popover-body\">\n <p class=\"markup-popover-byline\">\n replying as <span class=\"markup-popover-name\">{authorName}</span>\n {isVerified ? <span class=\"markup-comment-badge\">team</span> : null}\n </p>\n <Composer\n label=\"Reply\"\n placeholder=\"Write a reply…\"\n submitLabel=\"Reply\"\n initialFocus={false}\n isPending={isPending}\n error={error}\n onSubmit={onReply}\n members={members}\n />\n </div>\n )}\n </div>\n )\n}\n\n/**\n * The \"+\" reaction trigger that lives at the right end of the comment\n * body row. Hidden by default and revealed on comment hover (or while\n * the picker is open) so the row stays visually quiet for unreacted\n * comments. Resolved threads omit it entirely.\n */\nfunction ReactionAdd({\n comment,\n pickerOpen,\n pickerDirection,\n pickerSide,\n pickerRef,\n onPickerClick,\n onPickerSelect,\n}: {\n comment: WidgetThread['comments'][number]\n pickerOpen: boolean\n pickerDirection: 'down' | 'up'\n pickerSide: boolean\n pickerRef: (el: HTMLDivElement | null) => void\n onPickerClick: (e: MouseEvent) => void\n onPickerSelect: (emoji: string) => void\n}) {\n return (\n <div\n class={cx(\n 'markup-reaction-picker-wrap',\n pickerOpen && 'is-open',\n pickerOpen && pickerDirection === 'up' && 'is-up',\n pickerSide && 'is-side',\n )}\n ref={pickerRef}\n >\n <button\n type=\"button\"\n class={cx('markup-icon-btn', pickerOpen && 'is-open')}\n title=\"Add reaction\"\n aria-label=\"Add reaction\"\n onClick={onPickerClick}\n >\n <IconSmile size={16} />\n </button>\n {pickerOpen ? (\n <div class=\"markup-reaction-picker\" role=\"menu\">\n {REACTION_PALETTE.map((emoji) => {\n const mine = comment.reactions.find((r) => r.emoji === emoji)?.mine ?? false\n return (\n <button\n key={emoji}\n type=\"button\"\n role=\"menuitem\"\n class={cx('markup-reaction-picker-item', mine && 'is-mine')}\n onClick={() => onPickerSelect(emoji)}\n >\n {emoji}\n </button>\n )\n })}\n </div>\n ) : null}\n </div>\n )\n}\n\n/**\n * Chip strip rendered below the comment body when at least one\n * reaction exists. Resolved threads still render the chips so the\n * history is readable, but each chip is non-interactive.\n */\nfunction ReactionChips({\n comment,\n isResolved,\n onToggle,\n}: {\n comment: WidgetThread['comments'][number]\n isResolved: boolean\n onToggle: (emoji: string) => void\n}) {\n return (\n <div class=\"markup-reactions\">\n {comment.reactions.map((r) => {\n const tooltip = formatReactors(r.reactors, r.mine, r.count, r.emoji)\n return (\n <button\n key={r.emoji}\n type=\"button\"\n class={cx('markup-reaction-chip', r.mine && 'is-mine')}\n disabled={isResolved}\n onClick={() => onToggle(r.emoji)}\n aria-pressed={r.mine}\n aria-label={tooltip}\n title={tooltip}\n >\n <span class=\"markup-reaction-emoji\" aria-hidden>\n {r.emoji}\n </span>\n <span class=\"markup-reaction-count\">{r.count}</span>\n </button>\n )\n })}\n </div>\n )\n}\n\n/**\n * Builds the chip tooltip: \"Alice, Bob and you reacted with 👍\".\n * The server already strips the viewer's own row from `reactors`, so\n * `mine` is the only signal that adds \"you\". `count` may exceed\n * `reactors.length + (mine ? 1 : 0)` when anon reactors didn't supply\n * a name — those collapse into an \"and N other(s)\" clause so the\n * tooltip and the chip count always agree.\n */\nfunction formatReactors(reactors: string[], mine: boolean, count: number, emoji: string): string {\n const parts: string[] = reactors.slice()\n const accountedFor = parts.length + (mine ? 1 : 0)\n const anonExtra = Math.max(0, count - accountedFor)\n if (anonExtra > 0) {\n parts.push(`${anonExtra} other${anonExtra === 1 ? '' : 's'}`)\n }\n if (mine) parts.push('you')\n if (parts.length === 0) return `${count} reacted with ${emoji}`\n const subject =\n parts.length === 1\n ? parts[0]\n : `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`\n return `${subject} reacted with ${emoji}`\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value))\n}\n\n/**\n * Author avatar: the profile picture when the server sent one, initials\n * otherwise.\n *\n * The picture is a third-party URL (whatever the identity provider hosts),\n * loaded inside somebody else's page — so a host CSP, an ad blocker, or a\n * rotated URL can all make it fail, and falling back to initials on `error`\n * is the difference between a name-tinted circle and a broken-image glyph.\n * `no-referrer` keeps the host page's URL out of the request: a customer's\n * internal admin URLs are not the avatar CDN's business.\n *\n * `failed` is keyed off the URL so a re-render with a different author\n * (Preact reuses the node) starts out trusting the new image again.\n */\nfunction CommentAvatar({ name, image, tone }: { name: string; image?: string; tone: number }) {\n const [failedUrl, setFailedUrl] = useState<string | null>(null)\n const showImage = image != null && failedUrl !== image\n return (\n <span class=\"markup-comment-avatar\" data-tone={tone} aria-hidden>\n {showImage ? (\n <img\n class=\"markup-avatar-img\"\n src={image}\n alt=\"\"\n loading=\"lazy\"\n decoding=\"async\"\n referrerpolicy=\"no-referrer\"\n onError={() => setFailedUrl(image)}\n />\n ) : (\n <span class=\"markup-avatar-initials\">{authorInitials(name)}</span>\n )}\n </span>\n )\n}\n\nfunction authorInitials(name: string): string {\n const trimmed = name.trim()\n if (!trimmed) return '??'\n const parts = trimmed.split(/\\s+/).filter(Boolean)\n const first = parts[0] ?? ''\n if (parts.length === 1) return first.slice(0, 2).toUpperCase()\n const last = parts[parts.length - 1] ?? ''\n return ((first[0] ?? '') + (last[0] ?? '')).toUpperCase()\n}\n\n// Stable 1..5 bucket from the seed string so the same author always\n// gets the same avatar color across renders and reloads.\nfunction authorTone(seed: string): number {\n let h = 0\n for (let i = 0; i < seed.length; i++) h = (h * 31 + seed.charCodeAt(i)) | 0\n return (Math.abs(h) % 5) + 1\n}\n\nfunction relativeTime(ts: number): string {\n const diff = Date.now() - ts\n const sec = Math.floor(diff / 1000)\n if (sec < 60) return 'just now'\n const min = Math.floor(sec / 60)\n if (min < 60) return `${min} minute${min === 1 ? '' : 's'} ago`\n const hr = Math.floor(min / 60)\n if (hr < 24) return `${hr} hour${hr === 1 ? '' : 's'} ago`\n const day = Math.floor(hr / 24)\n if (day < 30) return `${day} day${day === 1 ? '' : 's'} ago`\n const isSameYear = new Date(ts).getFullYear() === new Date().getFullYear()\n if (isSameYear) {\n return new Date(ts).toLocaleDateString([], {\n month: 'long',\n day: 'numeric',\n })\n }\n return new Date(ts).toLocaleDateString([], {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n })\n}\n\nfunction formatTime(ts: number): string {\n const date = new Date(ts)\n return date.toLocaleDateString([], {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n })\n}\n","import type { ComponentChildren } from 'preact'\n\nimport { cx } from '../utils'\nimport { IconClose, IconComment, IconEye, IconEyeOff, IconInbox, IconMenu } from './icons'\n\ntype ToolbarPosition = 'bottom-right' | 'bottom-left' | 'bottom-center'\n\n/**\n * In placement mode the comment button flips to Cancel and stays armed, so\n * dismissing doesn't require hitting a different target.\n *\n * The identity and overflow slots are rendered by the host so each owns its\n * own popover positioning; the toolbar only knows where to drop them.\n */\nexport function Toolbar({\n isActive,\n onToggle,\n onHide,\n position = 'bottom-right',\n unreadCount = 0,\n showInbox = false,\n onOpenInbox,\n inboxOpen = false,\n pinsVisible = true,\n onTogglePins,\n identityButton,\n overflowButton,\n}: {\n isActive: boolean\n onToggle: () => void\n /** A discoverable mouse path to the same thing ⌘. does. */\n onHide?: () => void\n position?: ToolbarPosition\n /** Badged on the inbox button when > 0. */\n unreadCount?: number\n /** False for anon visitors, who have no inbox to surface. */\n showInbox?: boolean\n onOpenInbox?: () => void\n /** Drives the \"on\" highlight on the inbox button while its popover is up. */\n inboxOpen?: boolean\n /** The host owns the pin layer; this is only the affordance. */\n pinsVisible?: boolean\n onTogglePins?: () => void\n /** Rendered inside the pill so its popover can anchor to the button. */\n identityButton?: ComponentChildren\n /** Slot for the overflow menu (anchor + popover). */\n overflowButton?: ComponentChildren\n}) {\n const sideClass =\n position === 'bottom-left'\n ? 'markup-toolbar-left'\n : position === 'bottom-center'\n ? 'markup-toolbar-center'\n : 'markup-toolbar-right'\n\n function handleCommentClick(e: MouseEvent) {\n e.preventDefault()\n e.stopPropagation()\n if ((e.metaKey || e.ctrlKey) && onHide) {\n onHide()\n return\n }\n onToggle()\n }\n\n return (\n <div\n class={cx('markup-toolbar', sideClass)}\n role=\"toolbar\"\n aria-label=\"Markup feedback toolbar\"\n >\n <button\n type=\"button\"\n class=\"markup-tb-btn\"\n data-kind=\"comment\"\n data-armed={isActive ? 'true' : undefined}\n title={isActive ? 'Cancel placing markup' : 'Leave a markup'}\n aria-pressed={isActive}\n onClick={handleCommentClick}\n >\n {isActive ? <IconClose size={16} /> : <IconComment size={16} />}\n </button>\n\n {showInbox ? (\n <button\n type=\"button\"\n class=\"markup-tb-btn\"\n data-kind=\"inbox\"\n data-on={inboxOpen ? 'true' : undefined}\n title={unreadCount > 0 ? `Inbox, ${unreadCount} unread` : 'Inbox'}\n aria-pressed={inboxOpen}\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n onOpenInbox?.()\n }}\n >\n <IconInbox size={16} />\n {unreadCount > 0 ? (\n <span class=\"markup-tb-badge\" aria-hidden=\"true\">\n {unreadCount > 9 ? '9+' : unreadCount}\n </span>\n ) : null}\n </button>\n ) : null}\n\n {onTogglePins ? (\n <>\n <div class=\"markup-tb-sep\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n class=\"markup-tb-btn\"\n data-kind=\"pins\"\n aria-label={pinsVisible ? 'Hide pins' : 'Show pins'}\n aria-pressed={!pinsVisible}\n title={pinsVisible ? 'Hide pins' : 'Show pins'}\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n onTogglePins()\n }}\n >\n {pinsVisible ? <IconEye size={16} /> : <IconEyeOff size={16} />}\n </button>\n </>\n ) : null}\n\n {identityButton || overflowButton ? <div class=\"markup-tb-sep\" aria-hidden=\"true\" /> : null}\n\n {identityButton}\n {overflowButton}\n\n {/* Fallback overflow trigger when host doesn't pass an overflow slot. */}\n {!overflowButton ? (\n <button\n type=\"button\"\n class=\"markup-tb-btn\"\n data-kind=\"overflow\"\n aria-label=\"More options\"\n disabled\n >\n <IconMenu size={16} />\n </button>\n ) : null}\n </div>\n )\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks'\nimport { ConvexClient } from 'convex/browser'\nimport { makeFunctionReference } from 'convex/server'\n\nimport { defineMachine, useMachine } from '../../lib/machine'\nimport { extractMentionUserIds } from '../../lib/mentions'\nimport { useAsyncAction } from '../../lib/use-async-action'\nimport { track } from '../analytics'\nimport { resolveCoords, type PageCoords } from '../anchor'\nimport {\n createApiClient,\n type WidgetApiClient,\n type WidgetMember,\n type WidgetNotification,\n type WidgetThread,\n} from '../api'\nimport { probePartitionedCookieSupport } from '../cookie-probe'\nimport { subscribeToRouteChanges } from '../history-observer'\nimport {\n type AnonIdentity,\n type IdentityState,\n type VerifiedIdentity,\n authorFieldsOf,\n clientIdOf,\n displayNameOf,\n loadIdentity,\n saveIdentity,\n} from '../identity-store'\nimport { type PopupResult, signInWithPopup } from '../popup-auth'\nimport { resolveSafeUrl } from '../safe-url'\nimport { captureScreenshot, type ScrubConfig } from '../screenshot'\nimport { useSubscriptionToken } from '../use-subscription-token'\nimport { useTokenRefresh } from '../use-token-refresh'\nimport { cx, platformKeys } from '../utils'\nimport { IdentityMenu } from './identity-menu'\nimport { NewThreadPopover } from './new-thread-popover'\nimport { NotificationsPanel } from './notifications-panel'\nimport { OverflowMenu } from './overflow-menu'\nimport { PanelPopover, type PanelKind } from './panel-popover'\nimport { Pin, GhostPin } from './pin'\nimport { PlacementOverlay } from './placement-overlay'\nimport { PrivacyPanel } from './privacy-panel'\nimport { ShortcutsPanel } from './shortcuts-panel'\nimport { ThreadPopover } from './thread-popover'\nimport { Toolbar } from './toolbar'\n\ntype ToolbarPosition = 'bottom-right' | 'bottom-left' | 'bottom-center'\n\ntype ScreenshotsConfig = {\n enabled?: boolean\n strictScrub?: boolean\n redactSelector?: string\n}\n\nexport type AppProps = {\n apiUrl: string\n apiKey: string\n position?: ToolbarPosition\n screenshots?: ScreenshotsConfig\n /**\n * Linked as \"Account →\" from the identity menu; omitted hides the link.\n * Deliberately unvalidated — host pages opt in to whatever they trust.\n */\n dashboardUrl?: string\n}\n\n/**\n * `null` when the popup didn't return enough to mint a verified state. Cookie\n * mode needs only the expiries — the tokens themselves went to HttpOnly\n * Partitioned cookies that JS deliberately cannot see.\n */\nfunction verifiedFromPopup(result: PopupResult): VerifiedIdentity | null {\n const baseIdentity = {\n clientId: `markup_user_${result.identity.id}`,\n name: result.identity.name,\n email: result.identity.email,\n // Parsed rather than trusted: arrives over postMessage and renders as an\n // `<img src>`. Non-http(s) is dropped and the initials stand in.\n image:\n result.identity.image != null\n ? (resolveSafeUrl(result.identity.image, location.href)?.href ?? undefined)\n : undefined,\n }\n\n if (result.mode === 'cookies') {\n if (result.tokenExpiresAt == null || result.refreshTokenExpiresAt == null) return null\n return {\n storage: 'cookies',\n ...baseIdentity,\n tokenExpiresAt: result.tokenExpiresAt,\n refreshTokenExpiresAt: result.refreshTokenExpiresAt,\n }\n }\n\n if (!result.token || result.tokenExpiresAt == null) return null\n const hasRefresh =\n typeof result.refreshToken === 'string' && typeof result.refreshTokenExpiresAt === 'number'\n return {\n storage: 'localStorage',\n ...baseIdentity,\n token: result.token,\n tokenExpiresAt: result.tokenExpiresAt,\n ...(hasRefresh\n ? {\n refreshToken: result.refreshToken as string,\n refreshTokenExpiresAt: result.refreshTokenExpiresAt as number,\n }\n : {}),\n }\n}\n\ntype Mode =\n | { kind: 'idle' }\n | { kind: 'placing' }\n | {\n kind: 'composing-new'\n coords: PageCoords\n pageX: number\n pageY: number\n screenshot: Blob | null\n isScreenshotCapturing: boolean\n /** Distinct from screenshots being off, which shows no affordance. */\n screenshotFailed: boolean\n screenshotRedactedCount: number\n screenshotRedactedSelectors: string[]\n /**\n * Scopes an async capture to the placement that started it. Without it,\n * an in-flight capture for placement A lands its blob in composer B.\n */\n captureToken: number\n }\n | { kind: 'thread'; threadId: string }\n\n/**\n * Walks shadow roots because the widget renders inside one, so\n * `document.activeElement` reports the host element rather than a focused\n * composer textarea.\n */\nfunction isEditableElementFocused(): boolean {\n let active: Element | null = document.activeElement\n while (active && active.shadowRoot && active.shadowRoot.activeElement) {\n active = active.shadowRoot.activeElement\n }\n if (!active) return false\n const tag = active.tagName\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true\n return (active as HTMLElement).isContentEditable\n}\n\n// Includes `host`, so the same pathname on staging and production is two\n// routes. Without it, threads from one deployment leak into every other.\nfunction currentRoute() {\n return window.location.host + window.location.pathname\n}\n\n/**\n * The menu entry and the keyboard chord feed different events so only the\n * menu-initiated hide surfaces the instructional toast — someone who used the\n * chord already knows it.\n */\ntype HudState = { kind: 'visible' } | { kind: 'hidden-with-toast' } | { kind: 'hidden' }\n\ntype HudEvent = { type: 'hide-with-toast' } | { type: 'toggle' } | { type: 'dismiss-toast' }\n\nconst hudMachine = defineMachine<HudState, HudEvent>({\n visible: {\n 'hide-with-toast': () => ({ kind: 'hidden-with-toast' }),\n toggle: () => ({ kind: 'hidden' }),\n },\n 'hidden-with-toast': {\n toggle: () => ({ kind: 'visible' }),\n 'dismiss-toast': () => ({ kind: 'hidden' }),\n },\n hidden: {\n toggle: () => ({ kind: 'visible' }),\n },\n})\n\n/**\n * Events that don't fit the current state are silent no-ops — notably\n * `anon → unauthorized`, since an anon-token 401 is not on the recovery path.\n *\n * The `verified → recovering` transition is what re-fires the bootstrap mint\n * effect, whose dep array reads `identity.kind`; there is no separate counter.\n */\ntype IdentityEvent =\n | { type: 'mint-success'; identity: AnonIdentity }\n | { type: 'signed-in'; identity: VerifiedIdentity }\n | { type: 'unauthorized' }\n | { type: 'author-set'; name: string; email?: string }\n | { type: 'forget-me' }\n | { type: 'signed-out' }\n\n/**\n * Persisting inside the transitions means every state change writes to storage\n * without a `useEffect([identity])` to remember, and without re-writing on\n * mount what the bootstrap just read. It costs these transitions their purity;\n * every other machine in the widget stays pure.\n */\nfunction persist(next: IdentityState): IdentityState {\n saveIdentity(next)\n return next\n}\n\nconst identityMachine = defineMachine<IdentityState, IdentityEvent>({\n unresolved: {\n 'mint-success': (_, e) => persist({ kind: 'anon', identity: e.identity }),\n 'signed-in': (_, e) => persist({ kind: 'verified', identity: e.identity }),\n },\n anon: {\n 'signed-in': (_, e) => persist({ kind: 'verified', identity: e.identity }),\n 'author-set': (s, e) =>\n persist({\n kind: 'anon',\n identity: { ...s.identity, name: e.name, email: e.email },\n }),\n // Persisting `unresolved` wipes the stored record, and the bootstrap mint\n // loop then fires on the next render with a fresh clientId.\n 'forget-me': () => persist({ kind: 'unresolved' }),\n },\n verified: {\n 'signed-in': (_, e) => persist({ kind: 'verified', identity: e.identity }),\n unauthorized: (s) =>\n persist({\n kind: 'recovering',\n preserved: { name: s.identity.name, email: s.identity.email },\n }),\n // Same shape as `forget-me`: the user gets a fresh anon clientId and can\n // keep commenting as a pseudonym without a reload.\n 'signed-out': () => persist({ kind: 'unresolved' }),\n },\n recovering: {\n 'mint-success': (_, e) => persist({ kind: 'anon', identity: e.identity }),\n 'signed-in': (_, e) => persist({ kind: 'verified', identity: e.identity }),\n },\n})\n\nexport function App({\n apiUrl,\n apiKey,\n position = 'bottom-right',\n screenshots,\n dashboardUrl,\n}: AppProps) {\n const [route, setRoute] = useState(currentRoute)\n const [threads, setThreads] = useState<WidgetThread[]>([])\n const [threadsLoaded, setThreadsLoaded] = useState(false)\n\n // A partial record starts `unresolved` with its name/email in `preserved`,\n // which roundtrips those fields through the very first mint.\n const initialIdentity = useMemo(() => loadIdentity(), [])\n const [identity, sendIdentity] = useMachine(identityMachine, initialIdentity.state)\n\n // `null` while the probe is in flight. The sign-in handler waits for a\n // non-null value, so we never advertise the cookies capability before the\n // browser has confirmed it. Cached per tab in sessionStorage.\n const [cookieSupport, setCookieSupport] = useState<boolean | null>(null)\n useEffect(() => {\n let cancelled = false\n void probePartitionedCookieSupport(apiUrl, apiKey).then((supported) => {\n if (!cancelled) setCookieSupport(supported)\n })\n return () => {\n cancelled = true\n }\n }, [apiUrl, apiKey])\n\n // Effective toolbar corner. Initialized from the prop, but the user\n // can pick a different corner via the overflow menu's Position row;\n // the toast surfaces mirror the same corner.\n const [toolbarPosition, setToolbarPosition] = useState<ToolbarPosition>(position)\n /**\n * UI toggles surfaced in the toolbar pill / overflow menu. These live\n * in component state because they're scoped to the current widget\n * mount — no need to persist across sessions yet.\n *\n * - `pinsVisible` — drives the eye/eye-off button. Local-only;\n * the pin layer reads this and hides everything when false.\n * - `userAutoCapture` — user-toggled override of the screenshots\n * pref. AND-combines with the host-config `screenshots.enabled`\n * (a host that disabled captures wins; a host that allows them\n * defers to the user).\n * - `panel` — which toolbar-anchored panel (inbox / privacy /\n * shortcuts) is open, or `null` for none. One slot rather than a\n * flag per panel: they all render fixed to the same toolbar\n * corner, so two open at once would stack on top of each other.\n */\n const [pinsVisible, setPinsVisible] = useState(true)\n const [userAutoCapture, setUserAutoCapture] = useState(true)\n const [panel, setPanel] = useState<PanelKind | null>(null)\n const closePanel = useCallback(() => setPanel(null), [])\n\n // Read through a ref so the api client sees the freshest token without\n // being recreated whenever identity changes.\n const identityRef = useRef<IdentityState>(identity)\n identityRef.current = identity\n\n // No-op for the legacy long-lived path, where the identity has no refresh\n // token. On failure this falls through to the same verified → recovering\n // path a 401 takes.\n useTokenRefresh(\n identity,\n apiUrl,\n apiKey,\n (next) => sendIdentity({ type: 'signed-in', identity: next }),\n () => sendIdentity({ type: 'unauthorized' }),\n )\n\n const api = useMemo<WidgetApiClient>(\n () =>\n createApiClient({\n apiUrl,\n apiKey,\n getToken: () => {\n const s = identityRef.current\n if (s.kind !== 'verified') return null\n // Cookie mode deliberately has no `token` in JS. Null here skips\n // the Authorization header, and `getStorageMode` below switches the\n // client to `credentials: 'include'` so the cookie attaches instead.\n if (s.identity.token == null) return null\n return { token: s.identity.token, expiresAt: s.identity.tokenExpiresAt }\n },\n getStorageMode: () => {\n const s = identityRef.current\n if (s.kind !== 'verified') return null\n return s.identity.storage\n },\n getAnonToken: () => {\n const s = identityRef.current\n // The verified bearer takes precedence; sending both is redundant.\n if (s.kind !== 'anon') return null\n return s.identity.anonToken\n },\n onUnauthorized: () => {\n // Only `verified` defines this event, so a second 401 from a burst\n // of concurrent requests is a no-op rather than a restarted mint.\n sendIdentity({ type: 'unauthorized' })\n },\n }),\n [apiUrl, apiKey, sendIdentity],\n )\n const [mode, setMode] = useState<Mode>({ kind: 'idle' })\n\n /**\n * Failure degrades to \"no picker, no chips\" rather than blocking the widget.\n * A hand-typed `@[Name](uid)` marker still works, because the server\n * re-validates against `projectMembers` either way.\n */\n const [members, setMembers] = useState<WidgetMember[]>([])\n useEffect(() => {\n let cancelled = false\n api\n .listMembers()\n .then((res) => {\n if (!cancelled) setMembers(res.members)\n })\n .catch(() => {\n /* No picker rather than no widget. */\n })\n return () => {\n cancelled = true\n }\n }, [api])\n\n /**\n * Anonymous identities never see a badge: their subscription token carries\n * no `userId` claim, so the server counts 0.\n */\n const [unreadCount, setUnreadCount] = useState(0)\n const [notifications, setNotifications] = useState<WidgetNotification[]>([])\n const [notificationsLoading, setNotificationsLoading] = useState(false)\n const [notificationsError, setNotificationsError] = useState<string | undefined>(undefined)\n const [markingAllNotificationsRead, setMarkingAllNotificationsRead] = useState(false)\n\n // One-shot per open rather than a live subscription: the badge is enough to\n // motivate opening the inbox. Overlapping opens land last-write-wins, which\n // is fine — both responses are scoped to the same user and project.\n const fetchNotifications = useCallback(() => {\n setNotificationsLoading(true)\n setNotificationsError(undefined)\n api\n .listNotifications()\n .then((res) => {\n setNotifications(res.notifications)\n })\n .catch((err: unknown) => {\n setNotificationsError(err instanceof Error ? err.message : 'Failed to load.')\n })\n .finally(() => {\n setNotificationsLoading(false)\n })\n }, [api])\n\n /**\n * One machine per surface, not one shared: `isPending` grays out the thread\n * popover, so reactions, sign-in, forget-me and sign-out each need their own\n * or a menu-scoped gesture would gray out a half-written reply.\n *\n * Re-entrant `run` calls while pending are dropped, which is what makes\n * spam-clicking safe without per-handler guards.\n */\n const action = useAsyncAction()\n const signInAction = useAsyncAction()\n const reactionAction = useAsyncAction()\n const forgetMeAction = useAsyncAction()\n const signOutAction = useAsyncAction()\n\n // Destructured so these references stay stable across renders and can go in\n // dep arrays — `action.run` would drag the whole fresh-every-render object in.\n const { run: runAction, reset: resetAction } = action\n const { run: runSignIn } = signInAction\n const { run: runReaction, reset: resetReaction } = reactionAction\n const { run: runForgetMe } = forgetMeAction\n const { run: runSignOut } = signOutAction\n const isSigningOut = signOutAction.isPending\n\n const isPending = action.isPending\n // Only one is ever set in practice: the actions are user-initiated and\n // serialized through the UI.\n const error = action.error ?? signInAction.error ?? reactionAction.error\n\n const [hud, sendHud] = useMachine(hudMachine, { kind: 'visible' })\n const isHudHidden = hud.kind !== 'visible'\n\n const [tick, forceTick] = useState(0) // re-render on scroll/resize\n\n // Excluded from screenshots.\n const rootRef = useRef<HTMLDivElement>(null)\n\n const authorName = displayNameOf(identity)\n const isVerified = identity.kind === 'verified'\n // No signed clientId to attach a post to yet, so the author prompt disables\n // the guest path. Sign-in is independent and stays available.\n const isIdentityResolving = identity.kind === 'unresolved' || identity.kind === 'recovering'\n const currentClientId = clientIdOf(identity)\n\n /* — anon-identity mint loop —\n *\n * `identity.kind` is both the trigger and the exit: transitioning to `anon`\n * re-runs this effect, which then bails. Cancellation drops results from a\n * superseded mint, e.g. a sign-in landing while a retry is pending. */\n useEffect(() => {\n if (identity.kind !== 'unresolved' && identity.kind !== 'recovering') return\n // `recovering` carries the preserved fields in the variant itself; on a\n // first mount there is nothing in memory, so fall back to storage.\n const preserved =\n identity.kind === 'recovering' ? identity.preserved : initialIdentity.preserved\n\n let cancelled = false\n let timer: ReturnType<typeof setTimeout> | null = null\n let backoffMs = 1_000\n\n function mint() {\n api\n .mintAnonIdentity()\n .then(({ clientId, token }) => {\n if (cancelled) return\n const minted: AnonIdentity = {\n clientId,\n anonToken: token,\n name: preserved.name,\n email: preserved.email,\n }\n sendIdentity({ type: 'mint-success', identity: minted })\n })\n .catch(() => {\n if (cancelled) return\n const next = Math.min(backoffMs, 30_000)\n timer = setTimeout(mint, next)\n backoffMs = Math.min(backoffMs * 2, 30_000)\n })\n }\n\n mint()\n return () => {\n cancelled = true\n if (timer) clearTimeout(timer)\n }\n }, [api, identity, sendIdentity, initialIdentity])\n\n const subscriptionToken = useSubscriptionToken(api)\n\n /* — Convex client for real-time subscriptions —\n *\n * Held in `useState` rather than a ref so the subscription effect\n * below re-runs when the client is rebuilt (apiUrl change, HMR).\n * With a ref the subscription effect captured a closed client and\n * stayed bound to it until one of its other deps shifted. */\n const [convexClient, setConvexClient] = useState<ConvexClient | null>(null)\n useEffect(() => {\n // HTTP Actions use *.convex.site; the WebSocket client needs *.convex.cloud.\n const wsUrl = apiUrl.replace(/\\.convex\\.site(\\/.*)?$/, '.convex.cloud')\n const client = new ConvexClient(wsUrl)\n setConvexClient(client)\n return () => {\n client.close()\n setConvexClient((current) => (current === client ? null : current))\n }\n }, [apiUrl])\n\n /* — real-time thread subscription via Convex WebSocket — */\n const deepLinkHandled = useRef(false)\n useEffect(() => {\n if (!convexClient || !subscriptionToken) return\n // A resumed subscription means the deployment is reachable again, so a\n // stale \"Failed to post\" would be misleading.\n resetAction()\n resetReaction()\n return convexClient.onUpdate(\n makeFunctionReference<'query'>('widget/queries:subscribeThreadsForRoute'),\n // `viewerClientId` is a hint the server applies no trust to — it only\n // computes the per-reaction `mine` flag. Passing it here also re-fires\n // the subscription when identity changes, so `mine` flips.\n { subscriptionToken, route, viewerClientId: currentClientId },\n (result) => {\n if (result !== undefined) {\n setThreads(result)\n setThreadsLoaded(true)\n }\n },\n )\n }, [convexClient, subscriptionToken, route, currentClientId, resetAction, resetReaction])\n\n /* — real-time unread mention count for verified users —\n *\n * The token's `userId` claim is what tells the server whose inbox to count;\n * anonymous tokens count 0. The explicit reset covers the window between\n * sign-out and the next token mint, where the prior count would linger. */\n useEffect(() => {\n if (identity.kind !== 'verified') {\n setUnreadCount(0)\n return\n }\n if (!convexClient || !subscriptionToken) return\n return convexClient.onUpdate(\n makeFunctionReference<'query'>('widget/queries:subscribeUnreadCountForProject'),\n { subscriptionToken },\n (result) => {\n if (result !== undefined) {\n setUnreadCount(result.count)\n }\n },\n )\n }, [convexClient, subscriptionToken, identity.kind])\n\n /* — auto-open thread from URL fragment (#markup-thread=<id>) —\n *\n * Waits for the first snapshot: `threads` starts `[]`, and acting on that\n * would scrub the hash before the real threads arrive. Marks itself handled\n * either way, so a hash naming a deleted thread doesn't retry every tick. */\n useEffect(() => {\n if (deepLinkHandled.current) return\n if (!threadsLoaded) return\n const match = window.location.hash.match(/^#markup-thread=(.+)$/)\n if (match) {\n const threadId = decodeURIComponent(match[1] ?? '')\n const thread = threads.find((t) => t._id === threadId)\n if (thread) {\n setMode({ kind: 'thread', threadId })\n }\n // Even when unmatched: a stale fragment shouldn't linger in the URL bar.\n history.replaceState(null, '', window.location.pathname + window.location.search)\n }\n deepLinkHandled.current = true\n }, [threads, threadsLoaded])\n\n /* — track route changes (SPA navigation + back/forward) —\n *\n * The pushState/replaceState wrappers are installed once per page by a\n * module-scoped singleton, so init/destroy cycles can't stack them. */\n useEffect(() => subscribeToRouteChanges(() => setRoute(currentRoute())), [])\n\n /* — ⌘/Ctrl + . toggles the whole HUD. Allowed even while an input is\n * focused: the chord produces no text, and peeking at a clean page\n * mid-comment is exactly when it's wanted. */\n useEffect(() => {\n function onKeyDown(e: KeyboardEvent) {\n if (e.key !== '.') return\n if (!(e.metaKey || e.ctrlKey)) return\n if (e.altKey || e.shiftKey) return\n e.preventDefault()\n sendHud({ type: 'toggle' })\n }\n window.addEventListener('keydown', onKeyDown)\n return () => window.removeEventListener('keydown', onKeyDown)\n }, [sendHud])\n\n /* — panels are fixed to the toolbar's corner, so one left mounted after a\n * hide would float next to a toolbar that isn't there. */\n useEffect(() => {\n if (isHudHidden) setPanel(null)\n }, [isHudHidden])\n\n /* — any transition out of `hidden-with-toast` reruns this and the cleanup\n * clears the timer, so no separate reconcile branch is needed. */\n useEffect(() => {\n if (hud.kind !== 'hidden-with-toast') return\n const t = window.setTimeout(() => sendHud({ type: 'dismiss-toast' }), 5000)\n return () => window.clearTimeout(t)\n }, [hud.kind, sendHud])\n\n /* — re-render pins on scroll/resize/layout-shift so they track their anchors — */\n useEffect(() => {\n // Coalesced via rAF: ResizeObserver can fire dozens of times per frame on\n // a busy host page, and each one would otherwise re-render all of App.\n let rafId: number | null = null\n function tick() {\n if (rafId != null) return\n rafId = requestAnimationFrame(() => {\n rafId = null\n forceTick((n) => n + 1)\n })\n }\n window.addEventListener('scroll', tick, { passive: true })\n window.addEventListener('resize', tick)\n // Catches layout shifts that fire neither resize nor scroll — accordions\n // expanding, lazy images loading.\n const ro = new ResizeObserver(tick)\n ro.observe(document.body)\n return () => {\n window.removeEventListener('scroll', tick)\n window.removeEventListener('resize', tick)\n ro.disconnect()\n if (rafId != null) cancelAnimationFrame(rafId)\n }\n }, [])\n\n /* — Mode transitions reset the error machines so a previous failure doesn't\n * carry into the next gesture. Sign-in errors persist on purpose: they\n * belong to the auth surface, not the placing flow. */\n const startPlacing = useCallback(() => {\n resetAction()\n resetReaction()\n track('comment_started')\n setMode({ kind: 'placing' })\n }, [resetAction, resetReaction])\n\n /* — plain `c` starts the comment flow. Only from idle, so it can't yank\n * the user out of an open thread or a half-written composer. */\n useEffect(() => {\n function onKeyDown(e: KeyboardEvent) {\n if (e.key !== 'c') return\n if (e.metaKey || e.ctrlKey || e.altKey || e.shiftKey) return\n if (mode.kind !== 'idle') return\n if (isHudHidden) return\n if (isEditableElementFocused()) return\n e.preventDefault()\n startPlacing()\n }\n window.addEventListener('keydown', onKeyDown)\n return () => window.removeEventListener('keydown', onKeyDown)\n }, [mode.kind, isHudHidden, startPlacing])\n\n const cancel = useCallback(() => {\n setMode({ kind: 'idle' })\n resetAction()\n resetReaction()\n }, [resetAction, resetReaction])\n\n const captureCounterRef = useRef(0)\n const handlePlace = useCallback(\n (coords: PageCoords, screenX: number, screenY: number) => {\n const pageX = screenX + window.scrollX\n const pageY = screenY + window.scrollY\n const captureToken = ++captureCounterRef.current\n\n if (screenshots?.enabled === false || !userAutoCapture) {\n setMode({\n kind: 'composing-new',\n coords,\n pageX,\n pageY,\n screenshot: null,\n isScreenshotCapturing: false,\n screenshotFailed: false,\n screenshotRedactedCount: 0,\n screenshotRedactedSelectors: [],\n captureToken,\n })\n return\n }\n\n setMode({\n kind: 'composing-new',\n coords,\n pageX,\n pageY,\n screenshot: null,\n isScreenshotCapturing: true,\n screenshotFailed: false,\n screenshotRedactedCount: 0,\n screenshotRedactedSelectors: [],\n captureToken,\n })\n\n // Excluded from the capture.\n const shadowHost =\n rootRef.current != null && rootRef.current.getRootNode() instanceof ShadowRoot\n ? (rootRef.current.getRootNode() as ShadowRoot).host\n : null\n\n const scrubConfig: ScrubConfig = {\n strictScrub: screenshots?.strictScrub,\n redactSelector: screenshots?.redactSelector,\n }\n\n captureScreenshot(shadowHost, { x: screenX, y: screenY }, scrubConfig).then((result) => {\n setMode((current) => {\n // Cancelled, or superseded by a fresh placement, since this capture\n // started — otherwise blob A attaches to composer B.\n if (current.kind !== 'composing-new') return current\n if (current.captureToken !== captureToken) return current\n return {\n ...current,\n screenshot: result?.blob ?? null,\n isScreenshotCapturing: false,\n // `captureScreenshot` logs every null path itself.\n screenshotFailed: result == null,\n screenshotRedactedCount: result?.redactedCount ?? 0,\n screenshotRedactedSelectors: result?.redactedSelectors ?? [],\n }\n })\n // `html-to-image` fails silently on assets we never see, so the\n // success rate is only observable here.\n track('screenshot_captured', { ok: result != null })\n })\n },\n [screenshots, userAutoCapture],\n )\n\n const handleAuthor = useCallback(\n (name: string, email?: string) => {\n // Only reachable for an anon identity with no display fields yet; the\n // machine ignores `verified.author-set` regardless.\n sendIdentity({ type: 'author-set', name, email })\n },\n [sendIdentity],\n )\n\n // `useAsyncAction` drops re-entrant `run` calls, so spam-clicking can't\n // stack popups and no explicit guard is needed.\n const isSigningIn = signInAction.isPending\n const signIn = useCallback(async () => {\n track('sign_in_started')\n await runSignIn(async () => {\n // Both `null` (probe in flight) and `false` opt out, so a slow probe\n // can't degrade the session into a half-broken cookie-mode flow.\n const result = await signInWithPopup({\n apiUrl,\n apiKey,\n useCookies: cookieSupport === true,\n })\n const verified = verifiedFromPopup(result)\n if (!verified) {\n // Refuse rather than wedge the user as verified with no token, which\n // is the silent-401 trap.\n throw new Error('Sign-in did not return a verified token')\n }\n sendIdentity({ type: 'signed-in', identity: verified })\n track('sign_in_completed')\n })\n }, [apiUrl, apiKey, cookieSupport, runSignIn, sendIdentity])\n\n const handleSubmitNew = useCallback(\n async (body: string, includeScreenshot: boolean) => {\n if (mode.kind !== 'composing-new') return\n const author = authorFieldsOf(identity)\n if (!author) return\n await runAction(async () => {\n let screenshotStorageId: string | undefined\n\n if (includeScreenshot && mode.screenshot) {\n const { uploadUrl } = await api.getScreenshotUploadUrl()\n // Longer than the 30s write timeout in api.ts: uploads run to 2MB\n // and a degraded uplink can legitimately take this long. Unbounded,\n // a black-holed proxy would leave the composer pending forever.\n let uploadRes: Response\n try {\n uploadRes = await fetch(uploadUrl, {\n method: 'POST',\n headers: { 'Content-Type': mode.screenshot.type || 'image/png' },\n body: mode.screenshot,\n signal: AbortSignal.timeout(60_000),\n })\n } catch (err) {\n if (err instanceof DOMException && err.name === 'TimeoutError') {\n throw new Error('Screenshot upload took too long, so check your connection')\n }\n throw err\n }\n // Throwing keeps the composer open to retry. Posting without a\n // screenshot the user explicitly attached is the worse outcome.\n if (!uploadRes.ok) {\n throw new Error(`Screenshot upload failed (${uploadRes.status})`)\n }\n const { storageId } = (await uploadRes.json()) as { storageId: string }\n screenshotStorageId = storageId\n }\n\n const mentions = extractMentionUserIds(body)\n const res = await api.createThread({\n url: window.location.href,\n route,\n anchorSelector: mode.coords.anchorSelector,\n anchorX: mode.coords.anchorX,\n anchorY: mode.coords.anchorY,\n anchorOffsetX: mode.coords.anchorOffsetX,\n anchorOffsetY: mode.coords.anchorOffsetY,\n viewportW: mode.coords.viewportW,\n viewportY: mode.coords.viewportY,\n userAgent: navigator.userAgent,\n authorName: author.name,\n authorEmail: author.email,\n body,\n mentions: mentions.length > 0 ? mentions : undefined,\n screenshotStorageId,\n })\n setThreads((current) => [...current, res.thread])\n track('comment_submitted', {\n hasScreenshot: screenshotStorageId != null,\n hasMentions: mentions.length > 0,\n })\n setMode({ kind: 'thread', threadId: res.thread._id })\n })\n },\n [api, identity, mode, route, runAction],\n )\n\n const handleDelete = useCallback(async () => {\n if (mode.kind !== 'thread') return\n const threadId = mode.threadId\n await runAction(async () => {\n await api.deleteThread(threadId)\n setThreads((current) => current.filter((t) => t._id !== threadId))\n setMode({ kind: 'idle' })\n })\n }, [api, mode, runAction])\n\n const handleResolve = useCallback(async () => {\n if (mode.kind !== 'thread') return\n const threadId = mode.threadId\n await runAction(async () => {\n await api.resolveThread(threadId, currentClientId)\n setThreads((current) => current.filter((t) => t._id !== threadId))\n track('thread_resolved')\n setMode({ kind: 'idle' })\n })\n }, [api, mode, currentClientId, runAction])\n\n const handleNotificationClick = useCallback(\n (item: WidgetNotification) => {\n // Optimistic, so the panel feels immediate.\n if (item.readAt == null) {\n setUnreadCount((n) => Math.max(0, n - 1))\n setNotifications((current) =>\n current.map((n) => (n._id === item._id ? { ...n, readAt: Date.now() } : n)),\n )\n api.markNotificationRead(item._id).catch(() => {\n /* The next poll restores the true count. */\n })\n }\n\n // Off-route hands off to host navigation, and the destination widget's\n // `#markup-thread=` bootstrap picks it up.\n const onCurrentRoute = threads.some((t) => t._id === item.threadId)\n if (onCurrentRoute) {\n setMode({ kind: 'thread', threadId: item.threadId })\n } else {\n // Unsafe or malformed URLs fall through; the dashboard inbox is the\n // working fallback.\n const url = resolveSafeUrl(item.threadUrl, window.location.href)\n if (url) {\n url.hash = `markup-thread=${item.threadId}`\n window.location.href = url.toString()\n }\n }\n },\n [api, threads],\n )\n\n const handleMarkAllNotificationsRead = useCallback(() => {\n setMarkingAllNotificationsRead(true)\n setUnreadCount(0)\n setNotifications((current) =>\n current.map((n) => (n.readAt == null ? { ...n, readAt: Date.now() } : n)),\n )\n api\n .markAllNotificationsRead()\n .catch(() => {\n /* The next poll restores the true state. */\n })\n .finally(() => setMarkingAllNotificationsRead(false))\n }, [api])\n\n const handleReply = useCallback(\n async (body: string) => {\n if (mode.kind !== 'thread') return\n const author = authorFieldsOf(identity)\n if (!author) return\n const threadId = mode.threadId\n await runAction(async () => {\n const mentions = extractMentionUserIds(body)\n const res = await api.addComment(threadId, {\n body,\n authorName: author.name,\n authorEmail: author.email,\n mentions: mentions.length > 0 ? mentions : undefined,\n })\n setThreads((current) => current.map((t) => (t._id === threadId ? res.thread : t)))\n track('reply_submitted', { hasMentions: mentions.length > 0 })\n })\n },\n [api, identity, mode, runAction],\n )\n\n const handleEditComment = useCallback(\n async (commentId: string, body: string) => {\n if (mode.kind !== 'thread') return\n if (identity.kind !== 'anon' && identity.kind !== 'verified') return\n const threadId = mode.threadId\n // `rethrow` keeps the edit form open on failure, so a draft survives.\n await runAction(\n async () => {\n const mentions = extractMentionUserIds(body)\n const res = await api.editComment(threadId, commentId, {\n body,\n mentions: mentions.length > 0 ? mentions : undefined,\n })\n setThreads((current) => current.map((t) => (t._id === threadId ? res.thread : t)))\n },\n { rethrow: true },\n )\n },\n [api, identity, mode, runAction],\n )\n\n const handleDeleteComment = useCallback(\n async (commentId: string) => {\n if (mode.kind !== 'thread') return\n if (identity.kind !== 'anon' && identity.kind !== 'verified') return\n const threadId = mode.threadId\n await runAction(async () => {\n const res = await api.deleteComment(threadId, commentId)\n setThreads((current) => current.map((t) => (t._id === threadId ? res.thread : t)))\n })\n },\n [api, identity, mode, runAction],\n )\n\n /**\n * Swapped from the server's authoritative response rather than toggled\n * locally; a failure leaves the next subscription tick to reconcile.\n */\n const handleToggleReaction = useCallback(\n async (commentId: string, emoji: string) => {\n if (mode.kind !== 'thread') return\n const author = authorFieldsOf(identity)\n if (!author) return\n const threadId = mode.threadId\n await runReaction(async () => {\n const res = await api.toggleReaction(commentId, {\n emoji,\n authorName: author.name,\n })\n setThreads((current) => current.map((t) => (t._id === threadId ? res.thread : t)))\n track('reaction_added')\n })\n },\n [api, identity, mode, runReaction],\n )\n\n /**\n * Closing the popover matters: it would otherwise be anchored to comments\n * that were just soft-deleted. On failure the identity is left intact and\n * the privacy panel renders `forgetMeAction.error` inline.\n */\n const [forgetMeToasted, setForgetMeToasted] = useState(false)\n const handleForgetMe = useCallback(async () => {\n await runForgetMe(async () => {\n await api.forgetMe()\n setMode({ kind: 'idle' })\n // The privacy panel's \"who you are here\" section would describe an\n // identity that no longer exists.\n closePanel()\n sendIdentity({ type: 'forget-me' })\n setForgetMeToasted(true)\n })\n }, [api, closePanel, runForgetMe, sendIdentity])\n\n // Same 5s window as HudHiddenToast.\n useEffect(() => {\n if (!forgetMeToasted) return\n const t = window.setTimeout(() => setForgetMeToasted(false), 5000)\n return () => window.clearTimeout(t)\n }, [forgetMeToasted])\n\n /**\n * Same shape as forget-me. On error the identity stays verified and\n * `signOutAction.error` carries the message.\n */\n const [signedOutToasted, setSignedOutToasted] = useState(false)\n const handleSignOut = useCallback(async () => {\n await runSignOut(async () => {\n await api.signOut()\n setMode({ kind: 'idle' })\n sendIdentity({ type: 'signed-out' })\n setSignedOutToasted(true)\n })\n }, [api, runSignOut, sendIdentity])\n\n useEffect(() => {\n if (!signedOutToasted) return\n const t = window.setTimeout(() => setSignedOutToasted(false), 5000)\n return () => window.clearTimeout(t)\n }, [signedOutToasted])\n\n /* — derived — */\n const activeThread =\n mode.kind === 'thread' ? (threads.find((t) => t._id === mode.threadId) ?? null) : null\n const canDelete =\n isVerified || (currentClientId != null && currentClientId === activeThread?.authorClientId)\n\n /* — resolved pin positions —\n *\n * Memoised so `resolveCoords` doesn't run twice per render: once for the pin\n * markup, once for the unresolved count driving the observer below. `tick` is\n * a dep so any bump recomputes positions and resolved flags together. */\n const pinPositions = useMemo(\n () =>\n threads.map((t) => ({\n thread: t,\n point: resolveCoords({\n anchorX: t.anchorX,\n anchorY: t.anchorY,\n anchorSelector: t.anchorSelector,\n anchorOffsetX: t.anchorOffsetX,\n anchorOffsetY: t.anchorOffsetY,\n }),\n })),\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n [threads, tick],\n )\n /* In a ref rather than effect deps: `pinPositions` is recomputed every\n * scroll frame, and the observer must not be re-attached that often. */\n const anchorWatch = useRef<{ retryable: boolean; elements: Element[] }>({\n retryable: false,\n elements: [],\n })\n useEffect(() => {\n anchorWatch.current = {\n // A selector-less pin lives at the fraction fallback forever, so it\n // must not keep the watcher hot.\n retryable: pinPositions.some((p) => !p.point.resolved && p.thread.anchorSelector != null),\n elements: pinPositions.flatMap((p) => (p.point.element ? [p.point.element] : [])),\n }\n }, [pinPositions])\n const hasAnchoredThreads = threads.some((t) => t.anchorSelector != null)\n\n /* — keep pins in sync as anchor elements appear *and* disappear —\n *\n * The scroll/resize loop tracks pins through layout shifts but not through an\n * anchor that isn't in the DOM at all — common in SPAs that show a skeleton\n * on route change. The observer stays attached after everything anchors,\n * because a pin that *loses* its anchor has to fall back and dim again.\n *\n * Steady-state cost stays near zero: no render unless some pin is still\n * hunting for its selector, or a currently-anchored element just left the\n * document. Purely additive mutations on an anchored page do nothing. */\n useEffect(() => {\n if (!hasAnchoredThreads) return\n let rafId: number | null = null\n function schedule() {\n if (rafId != null) return\n rafId = requestAnimationFrame(() => {\n rafId = null\n forceTick((n) => n + 1)\n })\n }\n const observer = new MutationObserver(() => {\n const { retryable, elements } = anchorWatch.current\n if (!retryable && elements.every((el) => el.isConnected)) return\n schedule()\n })\n observer.observe(document.body, { childList: true, subtree: true })\n return () => {\n observer.disconnect()\n if (rafId != null) cancelAnimationFrame(rafId)\n }\n }, [hasAnchoredThreads])\n\n /* — a teammate-initiated delete or resolve would otherwise leave `mode`\n * pinned to a missing id: the popover gate falls through quietly, so the\n * user sees nothing and `mode` stays wedged until their next action. */\n useEffect(() => {\n if (mode.kind === 'thread' && activeThread == null) {\n cancel()\n }\n }, [mode, activeThread, cancel])\n\n return (\n <div class=\"markup-root\" ref={rootRef}>\n {/* Pins layer — hidden during placement. Thread pins also hide when\n * the HUD is toggled off; the thread popover hides at the same time,\n * so no anchor needs preserving. The ghost pin during composing-new\n * stays regardless, because the composer anchors to it. */}\n {mode.kind !== 'placing' ? (\n <div class=\"markup-pins-layer\">\n {!isHudHidden && pinsVisible\n ? pinPositions.map(({ thread: t, point }) => {\n const isActive = mode.kind === 'thread' && mode.threadId === t._id\n // Hidden from the popover too, so counting them overcounts.\n const visibleCount = t.comments.reduce((n, c) => n + (c.deleted ? 0 : 1), 0)\n return (\n <Pin\n key={t._id}\n pageX={point.pageX}\n pageY={point.pageY}\n count={visibleCount}\n isActive={isActive}\n isUnresolved={!point.resolved}\n onClick={() => {\n track('thread_opened', { commentCount: visibleCount })\n setMode({ kind: 'thread', threadId: t._id })\n }}\n />\n )\n })\n : null}\n {mode.kind === 'composing-new' ? (\n <GhostPin pageX={mode.pageX} pageY={mode.pageY} />\n ) : null}\n </div>\n ) : null}\n\n {/* Placement overlay — captures the click */}\n {mode.kind === 'placing' ? (\n <PlacementOverlay onPlace={handlePlace} onCancel={cancel} />\n ) : null}\n\n {/* Active thread popover. We keep it mounted while the HUD is\n * hidden via CSS rather than unmounted, so a reply draft, edit or\n * drag position survives a Cmd+. peek.\n *\n * Keyed on the thread id: without it Preact reuses the instance and\n * `dragPos`, `editingId`, the per-comment menus and the reaction\n * picker all leak across threads. */}\n {mode.kind === 'thread' && activeThread ? (\n <ThreadPopover\n key={activeThread._id}\n thread={activeThread}\n authorName={authorName}\n currentClientId={currentClientId ?? null}\n isVerified={isVerified}\n isIdentityResolving={isIdentityResolving}\n isSigningIn={isSigningIn}\n canDelete={canDelete}\n isPending={isPending}\n error={error}\n isHidden={isHudHidden}\n members={members}\n onAuthor={handleAuthor}\n onSignIn={signIn}\n onClose={cancel}\n onReply={handleReply}\n onEditComment={handleEditComment}\n onDeleteComment={handleDeleteComment}\n onToggleReaction={handleToggleReaction}\n onDelete={handleDelete}\n onResolve={handleResolve}\n />\n ) : null}\n\n {/* New-thread composer */}\n {mode.kind === 'composing-new' ? (\n <NewThreadPopover\n pageX={mode.pageX}\n pageY={mode.pageY}\n authorName={authorName}\n isVerified={isVerified}\n isIdentityResolving={isIdentityResolving}\n isSigningIn={isSigningIn}\n isPending={isPending}\n error={error}\n screenshot={mode.screenshot}\n isScreenshotCapturing={mode.isScreenshotCapturing}\n screenshotFailed={mode.screenshotFailed}\n screenshotRedactedCount={mode.screenshotRedactedCount}\n screenshotRedactedSelectors={mode.screenshotRedactedSelectors}\n members={members}\n onAuthor={handleAuthor}\n onSignIn={signIn}\n onSubmit={handleSubmitNew}\n onClose={cancel}\n />\n ) : null}\n\n {/* Toolbar pill — hidden along with the pins when the HUD is toggled\n * off. While placing/composing it stays visible regardless, so the\n * user always has a way to cancel. */}\n {!isHudHidden || mode.kind === 'placing' || mode.kind === 'composing-new' ? (\n <Toolbar\n isActive={mode.kind === 'placing'}\n onToggle={() => (mode.kind === 'placing' ? cancel() : startPlacing())}\n onHide={() => sendHud({ type: 'hide-with-toast' })}\n position={toolbarPosition}\n showInbox={isVerified}\n unreadCount={isVerified ? unreadCount : 0}\n inboxOpen={panel === 'inbox'}\n onOpenInbox={() => {\n const next = panel === 'inbox' ? null : 'inbox'\n setPanel(next)\n if (next) {\n track('notifications_opened', { unreadCount })\n fetchNotifications()\n }\n }}\n pinsVisible={pinsVisible}\n onTogglePins={() => setPinsVisible((v) => !v)}\n identityButton={\n <IdentityMenu\n identity={identity}\n position={toolbarPosition}\n isSigningIn={isSigningIn}\n isSigningOut={isSigningOut}\n dashboardUrl={dashboardUrl}\n onSignIn={signIn}\n onSignOut={handleSignOut}\n onForgetMe={handleForgetMe}\n />\n }\n overflowButton={\n <OverflowMenu\n position={toolbarPosition}\n onSetPosition={setToolbarPosition}\n autoCapture={userAutoCapture && screenshots?.enabled !== false}\n autoCaptureLocked={screenshots?.enabled === false}\n onToggleAutoCapture={() => setUserAutoCapture((v) => !v)}\n onOpenPrivacy={() => setPanel('privacy')}\n onOpenShortcuts={() => setPanel('shortcuts')}\n onHideForSession={() => sendHud({ type: 'hide-with-toast' })}\n version={__MARKUP_VERSION__}\n dashboardUrl={dashboardUrl}\n />\n }\n />\n ) : null}\n\n {/* Toolbar-anchored panels. At most one is open at a time (`panel`\n * is a single slot) and all three share `PanelPopover` for\n * positioning plus outside-click / Escape dismissal. */}\n {panel === 'inbox' && isVerified ? (\n <PanelPopover\n kind=\"inbox\"\n label=\"Inbox\"\n position={toolbarPosition}\n ignoreToolbarKind=\"inbox\"\n onClose={closePanel}\n >\n <NotificationsPanel\n items={notifications}\n isLoading={notificationsLoading}\n error={notificationsError}\n isMarkingAll={markingAllNotificationsRead}\n onBack={closePanel}\n onItemClick={(item) => {\n closePanel()\n handleNotificationClick(item)\n }}\n onMarkAllRead={handleMarkAllNotificationsRead}\n />\n </PanelPopover>\n ) : null}\n\n {panel === 'privacy' ? (\n <PanelPopover\n kind=\"privacy\"\n label=\"Privacy and data\"\n position={toolbarPosition}\n onClose={closePanel}\n >\n <PrivacyPanel\n identity={identity}\n apiUrl={apiUrl}\n autoCapture={userAutoCapture && screenshots?.enabled !== false}\n autoCaptureLocked={screenshots?.enabled === false}\n isForgettingMe={forgetMeAction.isPending}\n forgetMeError={forgetMeAction.error}\n onForgetMe={handleForgetMe}\n onClose={closePanel}\n />\n </PanelPopover>\n ) : null}\n\n {panel === 'shortcuts' ? (\n <PanelPopover\n kind=\"shortcuts\"\n label=\"Keyboard shortcuts\"\n position={toolbarPosition}\n onClose={closePanel}\n >\n <ShortcutsPanel onClose={closePanel} />\n </PanelPopover>\n ) : null}\n\n {/* Toast — only shown while the HUD is hidden. Lives outside the\n * HUD-hidden gate so it stays visible after the toolbar\n * disappears. Auto-dismisses via the effect above. */}\n {hud.kind === 'hidden-with-toast' ? <HudHiddenToast position={toolbarPosition} /> : null}\n\n {/* Forget-me confirmation toast. Shows after the server has\n * actually erased the identity (and a fresh anon clientId is\n * being minted in the background). */}\n {forgetMeToasted ? <ForgetMeToast position={toolbarPosition} /> : null}\n\n {/* Sign-out confirmation toast. Same anchor + dismissal pattern\n * as the forget-me toast above; copy reflects that the\n * session ended (not that data was erased). */}\n {signedOutToasted ? <SignedOutToast position={toolbarPosition} /> : null}\n </div>\n )\n}\n\n/** Mirrors the toolbar's corner so the toast doesn't drift across the page. */\nfunction HudHiddenToast({ position }: { position: ToolbarPosition }) {\n const { mod: modKey } = platformKeys()\n return (\n <div\n class={cx(\n 'markup-hud-hidden-toast',\n position === 'bottom-left'\n ? 'markup-hud-hidden-toast-left'\n : position === 'bottom-center'\n ? 'markup-hud-hidden-toast-center'\n : 'markup-hud-hidden-toast-right',\n )}\n role=\"status\"\n aria-live=\"polite\"\n >\n Markup hidden — press <kbd class=\"markup-kbd\">{modKey}</kbd>\n <kbd class=\"markup-kbd\">.</kbd> or refresh to bring it back.\n </div>\n )\n}\n\n/**\n * Copy names \"name and email\" on purpose: the comments stay, since the server\n * soft-deletes only the calling identity's authorship link.\n */\nfunction ForgetMeToast({ position }: { position: ToolbarPosition }) {\n return (\n <div\n class={cx(\n 'markup-hud-hidden-toast',\n position === 'bottom-left'\n ? 'markup-hud-hidden-toast-left'\n : position === 'bottom-center'\n ? 'markup-hud-hidden-toast-center'\n : 'markup-hud-hidden-toast-right',\n )}\n role=\"status\"\n aria-live=\"polite\"\n >\n Forgotten on this site — your name and email were cleared.\n </div>\n )\n}\n\n/** Distinct from the forget-me toast: a session ended, nothing was erased. */\nfunction SignedOutToast({ position }: { position: ToolbarPosition }) {\n return (\n <div\n class={cx(\n 'markup-hud-hidden-toast',\n position === 'bottom-left'\n ? 'markup-hud-hidden-toast-left'\n : position === 'bottom-center'\n ? 'markup-hud-hidden-toast-center'\n : 'markup-hud-hidden-toast-right',\n )}\n role=\"status\"\n aria-live=\"polite\"\n >\n Signed out — commenting anonymously again.\n </div>\n )\n}\n","import { render } from 'preact'\n\nimport styles from '../styles.css?inline'\nimport { setAnalyticsConfig, track } from './analytics'\nimport { WidgetErrorBoundary } from './error-boundary'\nimport { type ErrorReporterConfig, reportError, setActiveReporter } from './error-reporter'\nimport { bindThemeHost, watchSystemTheme } from './theme-store'\nimport { App, type AppProps } from './ui/app'\n\nexport type MountConfig = AppProps & {\n /** `false` sends no product telemetry. See `runtime/analytics.ts`. */\n analytics?: boolean\n /** Once the user picks a theme at runtime, the persisted value wins. */\n theme?: 'light' | 'dark' | 'auto'\n}\n\n/**\n * The host element overlays the whole viewport with `pointer-events: none`, so\n * individual UI bits re-enable it as needed rather than the widget blocking\n * the page underneath.\n */\nexport function mountWidget(host: HTMLElement, config: MountConfig): () => void {\n host.style.position = 'fixed'\n host.style.inset = '0'\n host.style.zIndex = '2147483647'\n host.style.pointerEvents = 'none'\n\n bindThemeHost(host, config.theme ?? 'auto')\n const stopWatch = watchSystemTheme()\n\n const shadow = host.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = styles\n shadow.appendChild(style)\n\n const root = document.createElement('div')\n root.className = 'markup-shadow-root'\n shadow.appendChild(root)\n\n // One object so every report path shares a rate-limit window — the sender\n // cache in error-reporter.ts is keyed by reference.\n const reporterConfig: ErrorReporterConfig = {\n apiUrl: config.apiUrl,\n apiKey: config.apiKey,\n widgetVersion: __MARKUP_VERSION__,\n }\n\n // Before rendering, so an error thrown during the initial render still\n // lands on a configured reporter.\n setActiveReporter(reporterConfig)\n\n setAnalyticsConfig(\n config.analytics === false\n ? null\n : { apiUrl: config.apiUrl, apiKey: config.apiKey, widgetVersion: __MARKUP_VERSION__ },\n )\n track('widget_loaded')\n\n const { theme: _theme, analytics: _analytics, ...appProps } = config\n render(\n <WidgetErrorBoundary onError={(err) => reportError(err, { context: 'render' })}>\n <App {...appProps} />\n </WidgetErrorBoundary>,\n root,\n )\n\n return () => {\n stopWatch()\n setActiveReporter(null)\n // Clears the queue — a torn-down widget shouldn't post after the fact.\n setAnalyticsConfig(null)\n render(null, root)\n }\n}\n","import { mountWidget } from './runtime/mount'\n\nexport type WidgetTheme = 'light' | 'dark' | 'auto'\n\n/**\n * @deprecated The floating action button was replaced by the toolbar\n * pill, which has no variants. Kept so existing type imports keep\n * compiling; it is no longer referenced by anything the widget renders\n * and will be removed in the next major.\n */\nexport type WidgetFab = 'default' | 'icon-only'\n\nexport interface ScreenshotsConfig {\n /** Disable screenshot capture entirely. Default: enabled. */\n enabled?: boolean\n /** Also masks all inputs/selects/textareas in addition to the default sensitive set. Default: false. */\n strictScrub?: boolean\n /** Custom CSS selector — matched elements are always masked. */\n redactSelector?: string\n}\n\nexport interface WidgetConfig {\n /** Convex deployment site URL, e.g. `https://your-deployment.convex.site` */\n apiUrl: string\n /** Raw API key minted from a project's settings page */\n apiKey: string\n /**\n * Initial corner for the toolbar. Defaults to bottom-right. Users can\n * move it afterwards from the toolbar's overflow menu.\n */\n position?: 'bottom-right' | 'bottom-left' | 'bottom-center'\n /**\n * Visual theme.\n * - `'light'` — force light palette\n * - `'dark'` — force dark palette\n * - `'auto'` (default) — follow the host's `prefers-color-scheme`\n */\n theme?: WidgetTheme\n /**\n * @deprecated Ignored. The floating action button was replaced by the\n * toolbar pill, which has no variants, so neither `'default'` nor\n * `'icon-only'` describes anything the widget can render. Accepted\n * (and dropped) so upgrading doesn't break callers that still pass it;\n * remove it from your config. Will be deleted in the next major.\n */\n fab?: WidgetFab\n /** Screenshot capture and PII-scrub options. */\n screenshots?: ScreenshotsConfig\n /**\n * Optional dashboard URL the widget links to from the verified-user\n * identity menu (\"Account →\"). When omitted the menu hides the\n * Account entry. Useful for self-hosters whose dashboard origin\n * isn't statically known to the widget.\n */\n dashboardUrl?: string\n /**\n * Product telemetry — counts of widget interactions, sent to Markup.\n * Default: enabled.\n *\n * What it is not: it adds no third-party script, sets no cookie and\n * writes nothing to storage, and carries no identifier for the person\n * using your site — events are keyed on the *project*, and the\n * session id is generated per page load and discarded with the tab.\n * No comment text, URLs, or names are ever sent.\n *\n * Set `false` if your privacy policy or DPA is easier to write\n * without it.\n */\n analytics?: boolean\n}\n\nlet _unmount: (() => void) | null = null\nlet _host: HTMLElement | null = null\nlet _pendingMount: (() => void) | null = null\n/** Deprecation notices fire once per page, not once per `init()`. */\nlet _warnedFab = false\n\n/**\n * Mounts the feedback widget on the page. Idempotent — calling init again\n * with the same config is a no-op; calling with different config tears down\n * the previous instance first.\n *\n * Returns a `destroy()` function that unmounts the widget and removes the\n * host element. Useful for SPAs that want to dispose on logout.\n */\nexport function init(config: WidgetConfig): () => void {\n if (!config.apiUrl || !config.apiKey) {\n console.warn('[markup] init() requires both apiUrl and apiKey, so the widget was not mounted')\n return () => {}\n }\n // `@deprecated` only reaches TypeScript callers; plain-JS and `data-fab`\n // users need to hear about it before the option disappears.\n if (config.fab != null && !_warnedFab) {\n _warnedFab = true\n console.warn(\n '[markup] the `fab` option is ignored and will be removed in the next major. ' +\n 'The toolbar replaced the floating action button. Remove it from your config.',\n )\n }\n destroy()\n\n const mount = () => {\n _pendingMount = null\n if (!document.body) return\n const host = document.createElement('div')\n host.id = 'markup-widget'\n document.body.appendChild(host)\n _host = host\n _unmount = mountWidget(host, config)\n }\n\n // Called from <head> before <body> parses, `document.body` is still null.\n if (document.readyState === 'loading' || !document.body) {\n const deferred = () => mount()\n _pendingMount = () => document.removeEventListener('DOMContentLoaded', deferred)\n document.addEventListener('DOMContentLoaded', deferred, { once: true })\n } else {\n mount()\n }\n\n return destroy\n}\n\nexport function destroy(): void {\n if (_pendingMount) {\n _pendingMount()\n _pendingMount = null\n }\n if (_unmount) {\n _unmount()\n _unmount = null\n }\n if (_host?.parentNode) _host.parentNode.removeChild(_host)\n _host = null\n}\n\n/* ──────────────────────────────────────────────────────────────────────────\n * Auto-init for <script> tag usage:\n *\n * <script\n * src=\"cdn.example.com/widget.js\"\n * type=\"module\"\n * data-markup-widget=\"true\"\n * data-api-url=\"https://your-deployment.convex.site\"\n * data-api-key=\"markup_...\"\n * data-position=\"bottom-right\"\n * ></script>\n *\n * Skip when there's no document (SSR) or when the script tag carries no\n * data attributes (assumed manual init via `init()`).\n * ────────────────────────────────────────────────────────────────────────── */\n\nif (typeof document !== 'undefined') {\n // `document.currentScript` is null for `type=\"module\"`, which is why\n // `data-markup-widget=\"true\"` is required for auto-init.\n const current =\n (document.currentScript as HTMLScriptElement | null) ??\n (document.querySelector('script[data-markup-widget=\"true\"]') as HTMLScriptElement | null)\n const apiUrl = current?.dataset.apiUrl\n const apiKey = current?.dataset.apiKey\n if (apiUrl && apiKey) {\n const position = current?.dataset.position as WidgetConfig['position'] | undefined\n const theme = current?.dataset.theme as WidgetTheme | undefined\n // Read but ignored, so `data-fab` still triggers the deprecation warning.\n const fab = current?.dataset.fab as WidgetFab | undefined\n const dashboardUrl = current?.dataset.dashboardUrl\n // Exact match only: a typo'd `data-analytics=\"flase\"` must not silently\n // disable it, so an opt-out has to be spelled correctly.\n const analytics = current?.dataset.analytics !== 'false'\n const start = () => init({ apiUrl, apiKey, position, theme, fab, dashboardUrl, analytics })\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', start, { once: true })\n } else {\n start()\n }\n }\n}\n"],"x_google_ignoreList":[0,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,35,43,44,45,46,47,48,49,50,51,52,58],"mappings":";AAAA,IAAI,GAAEA,GAAEC,GAAIE,GAAEC,GAAEC,GAAEC,GAAEC,GAAEC,GAAEC,GAAEC,GAAEC,GAAEC,GAAEC,GAAIE,IAAE,CAAC,GAAEC,IAAE,CAAC,GAAEC,IAAE,qEAAoE,IAAE,MAAM;AAAQ,SAASC,EAAE,GAAE,GAAE;CAAC,KAAI,IAAI,KAAK,GAAE,EAAE,KAAG,EAAE;CAAG,OAAO;AAAC;AAAC,SAAS,EAAE,GAAE;CAAC,KAAG,EAAE,cAAY,EAAE,WAAW,YAAY,CAAC;AAAC;AAAC,SAASC,EAAE,GAAE,GAAE,GAAE;CAAC,IAAI,GAAE,GAAE,GAAE,IAAE,CAAC;CAAE,KAAI,KAAK,GAAE,AAAO,KAAP,QAAS,IAAE,EAAE,KAAU,KAAP,QAAS,IAAE,EAAE,KAAG,EAAE,KAAG,EAAE;CAAG,IAAG,UAAU,SAAO,MAAI,EAAE,WAAS,UAAU,SAAO,IAAE,EAAE,KAAK,WAAU,CAAC,IAAE,IAAe,OAAO,KAAnB,cAA4B,EAAE,gBAAR,MAAqB,KAAI,KAAK,EAAE,cAAa,AAAS,EAAE,OAAX,KAAK,MAAW,EAAE,KAAG,EAAE,aAAa;CAAI,OAAO,EAAE,GAAE,GAAE,GAAE,GAAE,IAAI;AAAC;AAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE;CAAC,IAAI,IAAE;EAAC,MAAK;EAAE,OAAM;EAAE,KAAI;EAAE,KAAI;EAAE,KAAI;EAAK,IAAG;EAAK,KAAI;EAAE,KAAI;EAAK,KAAI;EAAK,aAAY,KAAK;EAAE,KAAU,KAAE,EAAElB;EAAI,KAAI;EAAG,KAAI;CAAC;CAAE,OAAa,KAAN,QAAeD,EAAE,SAAR,QAAeA,EAAE,MAAM,CAAC,GAAE;AAAC;AAAmC,SAAS,EAAE,GAAE;CAAC,OAAO,EAAE;AAAQ;AAAC,SAASoB,EAAE,GAAE,GAAE;CAAC,KAAK,QAAM,GAAE,KAAK,UAAQ;AAAC;AAAC,SAAS,EAAE,GAAE,GAAE;CAAC,IAAS,KAAN,MAAQ,OAAO,EAAE,KAAG,EAAE,EAAE,IAAG,EAAE,MAAI,CAAC,IAAE;CAAK,KAAI,IAAI,GAAE,IAAE,EAAE,IAAI,QAAO,KAAI,KAAU,IAAE,EAAE,IAAI,OAAf,QAA0B,EAAE,OAAR,MAAY,OAAO,EAAE;CAAI,OAAkB,OAAO,EAAE,QAArB,aAA0B,EAAE,CAAC,IAAE;AAAI;AAAC,SAAS,EAAE,GAAE;CAAC,IAAG,EAAE,OAAK,EAAE,KAAI;EAAC,IAAI,IAAE,EAAE,KAAI,IAAE,EAAE,KAAI,IAAE,CAAC,GAAE,IAAE,CAAC,GAAE,IAAEF,EAAE,CAAC,GAAE,CAAC;EAAE,EAAE,MAAI,EAAE,MAAI,GAAElB,EAAE,SAAOA,EAAE,MAAM,CAAC,GAAEqB,GAAE,EAAE,KAAI,GAAE,GAAE,EAAE,KAAI,EAAE,IAAI,cAAa,KAAG,EAAE,MAAI,CAAC,CAAC,IAAE,MAAK,GAAQ,KAAE,EAAE,CAAC,GAAI,CAAC,EAAE,KAAG,EAAE,MAAK,CAAC,GAAE,EAAE,MAAI,EAAE,KAAI,EAAE,GAAG,IAAI,EAAE,OAAK,GAAEC,GAAE,GAAE,GAAE,CAAC,GAAE,EAAE,MAAI,EAAE,KAAG,MAAK,EAAE,OAAK,KAAG,EAAE,CAAC;CAAC;AAAC;AAAC,SAAS,EAAE,GAAE;CAAC,KAAU,IAAE,EAAE,OAAX,QAAsB,EAAE,OAAR,MAAY,OAAO,EAAE,MAAI,EAAE,IAAI,OAAK,MAAK,EAAE,IAAI,KAAK,SAAS,GAAE;EAAC,IAAS,KAAN,QAAe,EAAE,OAAR,MAAY,OAAO,EAAE,MAAI,EAAE,IAAI,OAAK,EAAE;CAAG,CAAC,GAAE,EAAE,CAAC;AAAC;AAAC,SAASC,EAAE,GAAE;CAAC,CAAC,CAAC,EAAE,QAAM,EAAE,MAAI,CAAC,MAAIpB,EAAE,KAAK,CAAC,KAAG,CAAC,EAAE,SAAOC,KAAGJ,EAAE,wBAAsB,IAAEA,EAAE,sBAAoBK,EAAAA,CAAG,CAAC;AAAC;AAAC,SAAS,IAAG;CAAC,IAAG;EAAC,KAAI,IAAI,GAAE,IAAE,GAAEF,EAAE,SAAQ,EAAE,SAAO,KAAGA,EAAE,KAAKG,CAAC,GAAE,IAAEH,EAAE,MAAM,GAAE,IAAEA,EAAE,QAAO,EAAE,CAAC;CAAC,UAAQ;EAAC,EAAE,SAAO,EAAE,MAAI;CAAC;AAAC;AAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;CAAC,IAAI,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,IAAE,KAAG,EAAE,OAAKa,GAAE,IAAE,EAAE;CAAO,KAAI,IAAEQ,EAAE,GAAE,GAAE,GAAE,GAAE,CAAC,GAAE,IAAE,GAAE,IAAE,GAAE,KAAI,CAAO,IAAE,EAAE,IAAI,OAAf,SAAqB,IAAM,EAAE,OAAN,MAAW,EAAE,EAAE,QAAMT,GAAE,EAAE,MAAI,GAAE,IAAEM,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,CAAC,GAAE,IAAE,EAAE,KAAI,EAAE,OAAK,EAAE,OAAK,EAAE,QAAM,EAAE,OAAK,GAAE,EAAE,KAAI,MAAK,CAAC,GAAE,EAAE,KAAK,EAAE,KAAI,EAAE,OAAK,GAAE,CAAC,IAAS,KAAN,QAAe,KAAN,SAAU,IAAE,KAAI,IAAE,CAAC,EAAE,IAAE,EAAE,SAAO,EAAE,QAAM,EAAE,OAAK,IAAEI,EAAE,GAAE,GAAE,GAAE,CAAC,GAAE,KAAG,EAAE,QAAM,EAAE,MAAI,SAAmB,OAAO,EAAE,QAArB,cAAoC,MAAT,KAAK,IAAM,IAAE,IAAE,MAAI,IAAE,EAAE,cAAa,EAAE,OAAK;CAAI,OAAO,EAAE,MAAI,GAAE;AAAC;AAAC,SAASD,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE;CAAC,IAAI,GAAE,GAAE,GAAE,GAAE,GAAE,IAAE,EAAE,QAAO,IAAE,GAAE,IAAE;CAAE,KAAI,EAAE,MAAQ,MAAM,CAAC,GAAE,IAAE,GAAE,IAAE,GAAE,KAAI,CAAO,IAAE,EAAE,OAAX,QAA2B,OAAO,KAAlB,aAAiC,OAAO,KAAnB,cAAgC,OAAO,KAAjB,YAA8B,OAAO,KAAjB,YAA8B,OAAO,KAAjB,YAAoB,EAAE,eAAa,SAAO,IAAE,EAAE,IAAI,KAAG,EAAE,MAAK,GAAE,MAAK,MAAK,IAAI,IAAE,EAAE,CAAC,IAAE,IAAE,EAAE,IAAI,KAAG,EAAE,GAAE,EAAC,UAAS,EAAC,GAAE,MAAK,MAAK,IAAI,IAAW,EAAE,gBAAX,KAAK,KAAmB,EAAE,MAAI,IAAE,IAAE,EAAE,IAAI,KAAG,EAAE,EAAE,MAAK,EAAE,OAAM,EAAE,KAAI,EAAE,MAAI,EAAE,MAAI,MAAK,EAAE,GAAG,IAAE,EAAE,IAAI,KAAG,GAAE,IAAE,IAAE,GAAE,EAAE,KAAG,GAAE,EAAE,MAAI,EAAE,MAAI,GAAE,IAAE,OAAU,IAAE,EAAE,MAAI,EAAE,GAAE,GAAE,GAAE,CAAC,MAAtB,OAA2B,MAAK,IAAE,EAAE,QAAM,EAAE,OAAK,KAAU,KAAN,QAAe,EAAE,OAAR,QAAiB,KAAJ,OAAQ,IAAE,IAAE,MAAI,IAAE,KAAG,MAAiB,OAAO,EAAE,QAArB,eAA4B,EAAE,OAAK,MAAI,KAAG,MAAI,KAAG,IAAE,IAAE,MAAI,KAAG,IAAE,IAAE,OAAK,IAAE,IAAE,MAAI,KAAI,EAAE,OAAK,OAAK,EAAE,IAAI,KAAG;CAAK,IAAG,GAAE,KAAI,IAAE,GAAE,IAAE,GAAE,KAAI,CAAO,IAAE,EAAE,OAAX,QAAgB,EAAI,IAAE,EAAE,SAAO,EAAE,OAAK,MAAI,IAAE,EAAE,CAAC,IAAG,GAAE,GAAE,CAAC;CAAG,OAAO;AAAC;AAAC,SAASC,EAAE,GAAE,GAAE,GAAE,GAAE;CAAC,IAAI,GAAE;CAAE,IAAe,OAAO,EAAE,QAArB,YAA0B;EAAC,KAAI,IAAE,EAAE,KAAI,IAAE,GAAE,KAAG,IAAE,EAAE,QAAO,KAAI,EAAE,OAAK,EAAE,EAAE,CAAC,KAAG,GAAE,IAAEA,EAAE,EAAE,IAAG,GAAE,GAAE,CAAC;EAAG,OAAO;CAAC;CAAC,EAAE,OAAK,MAAI,MAAI,KAAG,EAAE,QAAM,CAAC,EAAE,eAAa,IAAE,EAAE,CAAC,IAAG,EAAE,aAAa,EAAE,KAAI,KAAG,IAAI,IAAG,IAAE,EAAE;CAAK;EAAG,MAAK,EAAE;QAAwB,KAAN,QAAY,EAAE,YAAL;CAAe,OAAO;AAAC;AAA6G,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE;CAAC,IAAI,GAAE,GAAE,GAAE,IAAE,EAAE,KAAI,IAAE,EAAE,MAAK,IAAE,EAAE,IAAG,IAAQ,KAAN,QAAS,EAAI,IAAE,EAAE;CAAK,IAAU,MAAP,QAAgB,KAAN,QAAS,KAAG,KAAG,EAAE,OAAK,KAAG,EAAE,MAAK,OAAO;CAAE,IAAG,IAAG,MAAW;OAAA,IAAE,IAAE,GAAE,IAAE,IAAE,GAAE,KAAG,KAAG,IAAE,EAAE,SAAQ,KAAU,IAAE,EAAE,IAAE,KAAG,IAAE,MAAI,SAAtB,QAA6B,EAAI,IAAE,EAAE,QAAM,KAAG,EAAE,OAAK,KAAG,EAAE,MAAK,OAAO;CAAA;CAAE,OAAM;AAAE;AAAC,SAASC,GAAE,GAAE,GAAE,GAAE;CAAC,AAAK,EAAE,MAAP,MAAU,EAAE,YAAY,GAAQ,KAAE,EAAI,IAAE,EAAE,KAAS,KAAN,OAAQ,KAAa,OAAO,KAAjB,YAAoBT,EAAE,KAAK,CAAC,IAAE,IAAE,IAAE;AAAI;AAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE;CAAC,IAAI,GAAE;CAAE,GAAE,IAAY,KAAT,SAAW,IAAa,OAAO,KAAjB,UAAmB,EAAE,MAAM,UAAQ;MAAM;EAAC,IAAa,OAAO,KAAjB,aAAqB,EAAE,MAAM,UAAQ,IAAE,KAAI,GAAE,KAAI,KAAK,GAAE,KAAG,KAAK,KAAGS,GAAE,EAAE,OAAM,GAAE,EAAE;EAAE,IAAG,GAAE,KAAI,KAAK,GAAE,KAAG,EAAE,MAAI,EAAE,MAAIA,GAAE,EAAE,OAAM,GAAE,EAAE,EAAE;CAAC;MAAM,IAAQ,EAAE,MAAP,OAAgB,EAAE,MAAP,KAAU,IAAE,MAAI,IAAE,EAAE,QAAQhB,GAAE,IAAI,IAAG,IAAE,EAAE,YAAY,GAAE,IAAE,KAAK,KAAiB,KAAd,gBAA8B,KAAb,cAAe,EAAE,MAAM,CAAC,IAAE,EAAE,MAAM,CAAC,GAAE,AAAM,EAAE,MAAE,CAAC,GAAG,EAAE,EAAE,IAAE,KAAG,GAAE,IAAE,IAAE,EAAED,KAAG,EAAEA,MAAI,EAAEA,KAAGE,GAAE,EAAE,iBAAiB,GAAE,IAAEE,IAAED,GAAE,CAAC,KAAG,EAAE,oBAAoB,GAAE,IAAEC,IAAED,GAAE,CAAC;MAAM;EAAC,IAAiC,KAA9B,8BAAgC,IAAE,EAAE,QAAQ,eAAc,GAAG,CAAC,CAAC,QAAQ,UAAS,GAAG;OAAO,IAAY,KAAT,WAAsB,KAAV,YAAqB,KAAR,UAAmB,KAAR,UAAmB,KAAR,UAAuB,KAAZ,cAA2B,KAAZ,cAA0B,KAAX,aAAyB,KAAX,aAAsB,KAAR,UAAsB,KAAX,aAAc,KAAK,GAAE,IAAG;GAAC,EAAE,KAAS,KAAE;GAAK,MAAM;EAAC,QAAS,CAAC;EAAC,AAAY,OAAO,KAAnB,eAA6B,KAAN,QAAS,CAAC,MAAI,KAAQ,EAAE,MAAP,MAAU,EAAE,gBAAgB,CAAC,IAAE,EAAE,aAAa,GAAa,KAAX,aAAiB,KAAH,IAAK,KAAG,CAAC;CAAE;AAAC;AAAC,SAAS,GAAE,GAAE;CAAC,OAAO,SAAS,GAAE;EAAC,IAAG,KAAK,GAAE;GAAC,IAAI,IAAE,KAAK,EAAE,EAAE,OAAK;GAAG,IAAS,EAAEJ,MAAR,MAAW,EAAEA,KAAG;QAAS,IAAG,EAAEA,KAAG,EAAEC,IAAG;GAAO,OAAO,EAAET,EAAE,QAAMA,EAAE,MAAM,CAAC,IAAE,CAAC;EAAC;CAAC;AAAC;AAAC,SAASqB,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;CAAC,IAAI,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,IAAE,IAAE,EAAE;CAAK,IAAY,EAAE,gBAAX,KAAK,GAAkB,OAAO;CAAK,MAAI,EAAE,QAAM,IAAE,CAAC,EAAE,KAAG,EAAE,MAAK,IAAE,CAAC,IAAE,EAAE,MAAI,EAAE,GAAG,KAAI,IAAErB,EAAE,QAAM,EAAE,CAAC;CAAE,GAAE,IAAe,OAAO,KAAnB,YAAqB;EAAC,IAAE,EAAE;EAAO,IAAG;GAAC,IAAG,IAAE,EAAE,OAAM,IAAE,EAAE,aAAW,EAAE,UAAU,QAAO,KAAG,IAAE,EAAE,gBAAc,EAAE,EAAE,MAAK,IAAE,IAAE,IAAE,EAAE,MAAM,QAAM,EAAE,KAAG,GAAE,EAAE,MAAI,IAAE,CAAC,IAAE,EAAE,MAAI,EAAE,IAAA,CAAK,KAAG,EAAE,OAAK,IAAE,EAAE,MAAI,IAAE,IAAI,EAAE,GAAE,CAAC,KAAG,EAAE,MAAI,IAAE,IAAIoB,EAAE,GAAE,CAAC,GAAE,EAAE,cAAY,GAAE,EAAE,SAAO,KAAG,KAAG,EAAE,IAAI,CAAC,GAAE,EAAE,UAAQ,EAAE,QAAM,CAAC,IAAG,EAAE,MAAI,GAAE,IAAE,EAAE,MAAI,CAAC,GAAE,EAAE,MAAI,CAAC,GAAE,EAAE,MAAI,CAAC,IAAG,KAAS,EAAE,OAAR,SAAc,EAAE,MAAI,EAAE,QAAO,KAAS,EAAE,4BAAR,SAAmC,EAAE,OAAK,EAAE,UAAQ,EAAE,MAAIF,EAAE,CAAC,GAAE,EAAE,GAAG,IAAGA,EAAE,EAAE,KAAI,EAAE,yBAAyB,GAAE,EAAE,GAAG,CAAC,IAAG,IAAE,EAAE,OAAM,IAAE,EAAE,OAAM,EAAE,MAAI,GAAE,GAAE,KAAS,EAAE,4BAAR,QAAwC,EAAE,sBAAR,QAA4B,EAAE,mBAAmB,GAAE,KAAS,EAAE,qBAAR,QAA2B,EAAE,IAAI,KAAK,EAAE,iBAAiB;QAAM;IAAC,IAAG,KAAS,EAAE,4BAAR,QAAkC,MAAI,KAAS,EAAE,6BAAR,QAAmC,EAAE,0BAA0B,GAAE,CAAC,GAAE,EAAE,OAAK,EAAE,OAAK,CAAC,EAAE,OAAW,EAAE,yBAAR,QAA+B,CAAC,MAAI,EAAE,sBAAsB,GAAE,EAAE,KAAI,CAAC,GAAE;KAAC,EAAE,OAAK,EAAE,QAAM,EAAE,QAAM,GAAE,EAAE,QAAM,EAAE,KAAI,EAAE,MAAI,CAAC,IAAG,EAAE,MAAI,EAAE,KAAI,EAAE,MAAI,EAAE,KAAI,EAAE,IAAI,KAAK,SAAS,GAAE;MAAC,MAAI,EAAE,KAAG;KAAE,CAAC,GAAEF,EAAE,KAAK,MAAM,EAAE,KAAI,EAAE,GAAG,GAAE,EAAE,MAAI,CAAC,GAAE,EAAE,IAAI,UAAQ,EAAE,KAAK,CAAC;KAAE,MAAM;IAAC;IAAC,AAAM,EAAE,uBAAR,QAA6B,EAAE,oBAAoB,GAAE,EAAE,KAAI,CAAC,GAAE,KAAS,EAAE,sBAAR,QAA4B,EAAE,IAAI,KAAK,WAAU;KAAC,EAAE,mBAAmB,GAAE,GAAE,CAAC;IAAC,CAAC;GAAC;GAAC,IAAG,EAAE,UAAQ,GAAE,EAAE,QAAM,GAAE,EAAE,MAAI,GAAE,EAAE,MAAI,CAAC,GAAE,IAAEhB,EAAE,KAAI,IAAE,GAAE,GAAE,EAAE,QAAM,EAAE,KAAI,EAAE,MAAI,CAAC,GAAE,KAAG,EAAE,CAAC,GAAE,IAAE,EAAE,OAAO,EAAE,OAAM,EAAE,OAAM,EAAE,OAAO,GAAEgB,EAAE,KAAK,MAAM,EAAE,KAAI,EAAE,GAAG,GAAE,EAAE,MAAI,CAAC;QAAO;IAAG,EAAE,MAAI,CAAC,GAAE,KAAG,EAAE,CAAC,GAAE,IAAE,EAAE,OAAO,EAAE,OAAM,EAAE,OAAM,EAAE,OAAO,GAAE,EAAE,QAAM,EAAE;UAAU,EAAE,OAAK,EAAE,IAAE;GAAI,EAAE,QAAM,EAAE,KAAU,EAAE,mBAAR,SAA0B,IAAEE,EAAEA,EAAE,CAAC,GAAE,CAAC,GAAE,EAAE,gBAAgB,CAAC,IAAG,KAAG,CAAC,KAAS,EAAE,2BAAR,SAAkC,IAAE,EAAE,wBAAwB,GAAE,CAAC,IAAG,IAAQ,KAAN,QAAS,EAAE,SAAO,KAAS,EAAE,OAAR,OAAY,GAAE,EAAE,MAAM,QAAQ,IAAE,GAAE,IAAE,GAAE,GAAE,EAAE,CAAC,IAAE,IAAE,CAAC,CAAC,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,CAAC,GAAE,EAAE,OAAK,EAAE,KAAI,EAAE,OAAK,MAAK,EAAE,IAAI,UAAQ,EAAE,KAAK,CAAC,GAAE,MAAI,EAAE,MAAI,EAAE,KAAG;EAAK,SAAO,GAAE;GAAC,IAAG,EAAE,SAAO,GAAE,EAAE,MAAI,MAAK,KAAS,KAAN,MAAY;QAAA,EAAE,MAAK;KAAC,KAAI,EAAE,OAAK,IAAE,MAAI,KAAI,KAAM,EAAE,YAAL,KAAe,EAAE,cAAa,IAAE,EAAE;KAAY,AAAM,KAAN,SAAU,EAAE,EAAE,QAAQ,CAAC,KAAG,OAAM,EAAE,MAAI;IAAC,OAAM,IAAS,KAAN,MAAQ,KAAI,KAAE,EAAE,QAAO,OAAK,EAAE,EAAE,GAAE;GAAA,OAAO,EAAE,MAAI,EAAE;GAAI,EAAgB,QAAI,EAAE,OAAK,CAAC,GAAG,EAAE,QAAMS,GAAE,CAAC,GAAE3B,EAAE,IAAI,GAAE,GAAE,CAAC;EAAC;CAAC,OAAM,AAAM,KAAN,QAAS,EAAE,OAAK,EAAE,OAAK,EAAE,MAAI,EAAE,KAAI,EAAE,MAAI,EAAE,OAAK,IAAE,EAAE,MAAI,GAAE,EAAE,KAAI,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,CAAC;CAAE,QAAO,IAAEA,EAAE,WAAS,EAAE,CAAC,GAAE,MAAI,EAAE,MAAI,KAAK,IAAE;AAAC;AAAC,SAAS2B,GAAE,GAAE;CAAC,MAAI,EAAE,QAAM,EAAE,IAAI,MAAI,CAAC,IAAG,EAAE,OAAK,EAAE,IAAI,KAAKA,EAAC;AAAE;AAAC,SAASL,GAAE,GAAE,GAAE,GAAE;CAAC,KAAI,IAAI,IAAE,GAAE,IAAE,EAAE,QAAO,KAAI,GAAE,EAAE,IAAG,EAAE,EAAE,IAAG,EAAE,EAAE,EAAE;CAAE,EAAE,OAAKtB,EAAE,IAAI,GAAE,CAAC,GAAE,EAAE,KAAK,SAAS,GAAE;EAAC,IAAG;GAAC,IAAE,EAAE,KAAI,EAAE,MAAI,CAAC,GAAE,EAAE,KAAK,SAAS,GAAE;IAAC,EAAE,KAAK,CAAC;GAAC,CAAC;EAAC,SAAO,GAAE;GAAC,EAAE,IAAI,GAAE,EAAE,GAAG;EAAC;CAAC,CAAC;AAAC;AAAC,SAAS,GAAE,GAAE;CAAC,OAAgB,OAAO,KAAjB,aAA0B,KAAG,EAAE,MAAI,IAAE,IAAE,EAAE,CAAC,IAAE,EAAE,IAAI,EAAC,IAAW,EAAE,gBAAX,KAAK,IAAuBkB,EAAE,CAAC,GAAE,CAAC,IAAX;AAAY;AAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;CAAC,IAAI,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,IAAE,EAAE,SAAOH,GAAE,IAAE,EAAE,OAAM,IAAE,EAAE;CAAK,IAAU,KAAP,QAAS,IAAE,+BAAqC,KAAR,SAAU,IAAE,uCAAqC,AAAI,MAAE,gCAAsC,KAAN,MAAY;OAAA,IAAE,GAAE,IAAE,EAAE,QAAO,KAAI,KAAI,IAAE,EAAE,OAAK,kBAAiB,KAAG,CAAC,CAAC,MAAI,IAAE,EAAE,aAAW,IAAK,EAAE,YAAL,IAAe;GAAC,IAAE,GAAE,EAAE,KAAG;GAAK;EAAK;;CAAC,IAAS,KAAN,MAAQ;EAAC,IAAS,KAAN,MAAQ,OAAO,SAAS,eAAe,CAAC;EAAE,IAAE,SAAS,gBAAgB,GAAE,GAAE,EAAE,MAAI,CAAC,GAAE,AAAsB,OAAlBf,EAAE,OAAKA,EAAE,IAAI,GAAE,CAAC,GAAI,CAAC,IAAG,IAAE;CAAI;CAAC,IAAS,KAAN,MAAQ,MAAI,KAAG,KAAG,EAAE,QAAM,MAAI,EAAE,OAAK;MAAO;EAAC,IAAG,IAAc,KAAZ,cAAqB,EAAE,gBAAR,OAAqB,OAAK,KAAG,EAAE,KAAK,EAAE,UAAU,GAAE,CAAC,KAAS,KAAN,MAAQ,KAAI,IAAE,CAAC,GAAE,IAAE,GAAE,IAAE,EAAE,WAAW,QAAO,KAAI,GAAG,IAAE,EAAE,WAAW,GAAA,CAAI,QAAM,EAAE;EAAM,KAAI,KAAK,GAAE,IAAE,EAAE,IAA8B,KAA3B,4BAA6B,IAAE,IAAc,KAAZ,cAAe,KAAK,KAAY,KAAT,WAAY,kBAAiB,KAAc,KAAX,aAAc,oBAAmB,KAAG,EAAE,GAAE,GAAE,MAAK,GAAE,CAAC;EAAE,KAAI,KAAK,GAAE,IAAE,EAAE,IAAe,KAAZ,aAAc,IAAE,IAA6B,KAA3B,4BAA6B,IAAE,IAAW,KAAT,UAAW,IAAE,IAAa,KAAX,YAAa,IAAE,IAAE,KAAe,OAAO,KAAnB,cAAsB,EAAE,OAAK,KAAG,EAAE,GAAE,GAAE,GAAE,EAAE,IAAG,CAAC;EAAE,IAAG,GAAE,KAAG,MAAI,EAAE,UAAQ,EAAE,UAAQ,EAAE,UAAQ,EAAE,eAAa,EAAE,YAAU,EAAE,SAAQ,EAAE,MAAI,CAAC;OAAO,IAAG,MAAI,EAAE,YAAU,KAAI,GAAc,EAAE,QAAd,aAAmB,EAAE,UAAQ,GAAE,EAAE,CAAC,IAAE,IAAE,CAAC,CAAC,GAAE,GAAE,GAAE,GAAmB,KAAjB,kBAAmB,iCAA+B,GAAE,GAAE,GAAE,IAAE,EAAE,KAAG,EAAE,OAAK,EAAE,GAAE,CAAC,GAAE,GAAE,CAAC,GAAQ,KAAN,MAAQ,KAAI,IAAE,EAAE,QAAO,MAAK,EAAE,EAAE,EAAE;EAAE,KAAe,KAAZ,eAAgB,IAAE,SAAoB,KAAZ,cAAqB,KAAN,OAAQ,EAAE,gBAAgB,OAAO,IAAQ,KAAN,SAAU,MAAI,EAAE,MAAgB,KAAZ,cAAe,CAAC,KAAa,KAAV,YAAa,KAAG,EAAE,OAAK,EAAE,GAAE,GAAE,GAAE,EAAE,IAAG,CAAC,GAAE,IAAE,WAAgB,KAAN,QAAS,KAAG,EAAE,MAAI,EAAE,GAAE,GAAE,GAAE,EAAE,IAAG,CAAC;CAAE;CAAC,OAAO;AAAC;AAAC,SAAS,GAAE,GAAE,GAAE,GAAE;CAAC,IAAG;EAAC,IAAe,OAAO,KAAnB,YAAqB;GAAC,IAAI,IAAc,OAAO,EAAE,OAArB;GAAyB,KAAG,EAAE,IAAI,GAAE,KAAS,KAAN,SAAU,EAAE,MAAI,EAAE,CAAC;EAAE,OAAM,EAAE,UAAQ;CAAC,SAAO,GAAE;EAAC,EAAE,IAAI,GAAE,CAAC;CAAC;AAAC;AAAC,SAAS,GAAE,GAAE,GAAE,GAAE;CAAC,IAAI,GAAE;CAAE,IAAGA,EAAE,WAASA,EAAE,QAAQ,CAAC,IAAG,IAAE,EAAE,SAAO,EAAE,WAAS,EAAE,WAAS,EAAE,OAAK,GAAE,GAAE,MAAK,CAAC,KAAU,IAAE,EAAE,QAAX,MAAgB;EAAC,IAAG,EAAE,sBAAqB,IAAG;GAAC,EAAE,qBAAqB;EAAC,SAAO,GAAE;GAAC,EAAE,IAAI,GAAE,CAAC;EAAC;EAAC,EAAE,OAAK,EAAE,MAAI,EAAE,MAAI;CAAI;CAAC,IAAG,IAAE,EAAE,KAAI,KAAI,IAAE,GAAE,IAAE,EAAE,QAAO,KAAI,EAAE,MAAI,GAAE,EAAE,IAAG,GAAE,KAAe,OAAO,EAAE,QAArB,UAAyB;CAAE,KAAG,EAAE,EAAE,GAAG,GAAE,EAAE,MAAI,EAAE,KAAG,EAAE,MAAI,KAAK;AAAC;AAAC,SAAS,GAAE,GAAE,GAAE,GAAE;CAAC,OAAO,KAAK,YAAY,GAAE,CAAC;AAAC;AAAC,SAAS,GAAE,GAAE,GAAE,GAAE;CAAC,IAAI,GAAE,GAAE,GAAE;CAAE,KAAG,aAAW,IAAE,SAAS,kBAAiBA,EAAE,MAAIA,EAAE,GAAG,GAAE,CAAC,GAAE,KAAG,IAAc,OAAO,KAAnB,cAAsB,OAAK,KAAG,EAAE,OAAK,EAAE,KAAI,IAAE,CAAC,GAAE,IAAE,CAAC,GAAEqB,GAAE,GAAE,IAAE,CAAC,CAAC,KAAG,KAAG,EAAA,CAAG,MAAIF,EAAE,GAAE,MAAK,CAAC,CAAC,CAAC,GAAE,KAAGJ,GAAEA,GAAE,EAAE,cAAa,CAAC,KAAG,IAAE,CAAC,CAAC,IAAE,IAAE,OAAK,EAAE,aAAW,EAAE,KAAK,EAAE,UAAU,IAAE,MAAK,GAAE,CAAC,KAAG,IAAE,IAAE,IAAE,EAAE,MAAI,EAAE,YAAW,GAAE,CAAC,GAAEO,GAAE,GAAE,GAAE,CAAC,GAAE,EAAE,MAAM,WAAS;AAAI;AAAy1B,IAAEN,EAAE,OAAM,IAAE,EAAC,KAAI,SAAS,GAAE,GAAE,GAAE,GAAE;CAAC,KAAI,IAAI,GAAE,GAAE,GAAE,IAAE,EAAE,KAAI,KAAI,IAAE,EAAE,QAAM,CAAC,EAAE,IAAG,IAAG;EAAC,KAAI,IAAE,EAAE,gBAAoB,EAAE,4BAAR,SAAmC,EAAE,SAAS,EAAE,yBAAyB,CAAC,CAAC,GAAE,IAAE,EAAE,MAAW,EAAE,qBAAR,SAA4B,EAAE,kBAAkB,GAAE,KAAG,CAAC,CAAC,GAAE,IAAE,EAAE,MAAK,GAAE,OAAO,EAAE,MAAI;CAAC,SAAO,GAAE;EAAC,IAAE;CAAC;CAAC,MAAM;AAAC,EAAC,GAAE,IAAE,GAAwD,EAAE,UAAU,WAAS,SAAS,GAAE,GAAE;CAAC,IAAI,IAAU,KAAK,OAAX,QAAgB,KAAK,OAAK,KAAK,QAAM,KAAK,MAAI,KAAK,MAAIE,EAAE,CAAC,GAAE,KAAK,KAAK;CAAxE,AAAsF,OAAO,KAA7F,eAAiG,IAAE,EAAEA,EAAE,CAAC,GAAE,CAAC,GAAE,KAAK,KAAK,IAAG,KAAGA,EAAE,GAAE,CAAC,GAAQ,KAAN,QAAS,KAAK,QAAM,KAAG,KAAK,IAAI,KAAK,CAAC,GAAEK,EAAE,IAAI;AAAE,GAAE,EAAE,UAAU,cAAY,SAAS,GAAE;CAAC,KAAK,QAAM,KAAK,MAAI,CAAC,GAAE,KAAG,KAAK,IAAI,KAAK,CAAC,GAAEA,EAAE,IAAI;AAAE,GAAE,EAAE,UAAU,SAAO,GAAE,IAAE,CAAC,GAAE,IAAc,OAAO,WAAnB,aAA2B,QAAQ,UAAU,KAAK,KAAK,QAAQ,QAAQ,CAAC,IAAE,YAAW,IAAE,SAAS,GAAE,GAAE;CAAC,OAAO,EAAE,IAAI,MAAI,EAAE,IAAI;AAAG,GAAE,EAAE,MAAI,GAAE,IAAE,KAAK,OAAO,CAAC,CAAC,SAAS,CAAC,GAAE,IAAE,QAAMhB,GAAE,IAAE,QAAMA,GAAE,IAAE,+BAA8B,IAAE,GAAE,IAAE,GAAE,CAAC,CAAC,GAAE,IAAE,GAAE,CAAC,CAAC;;;i7qCEQ7tW,KAAoB,KAGpB,IAAY,IACZ,KAAY,IA8Bd,KAAiC,MACjC,KAAuB,CAAC,GACxB,IAAmD,MACnD,KAAiB,IAGf,KAAY,GAAkB;AAEpC,SAAS,KAA4B;CAMnC,OAHI,OAAO,SAAW,OAAe,OAAO,OAAO,cAAe,aACzD,OAAO,WAAW,IAEpB,KAAK,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,GAAG,EAAE;AAC/E;AAIA,SAAgB,GAAmB,GAAoC;CAErE,IADA,KAAS,GACL,CAAC,GAAM;EAET,AADA,KAAQ,CAAC,GACT,AAEE,OADA,aAAa,CAAU,GACV;EAEf;CACF;CACA,GAAgB;AAClB;AAGA,SAAgB,EAAM,GAAmB,GAAoC;CACtE,UAED,KAAM,UAAU,KAIpB;MAFA,GAAM,KAAK;GAAE;GAAM;GAAY,WAAW,KAAK,IAAI;EAAE,CAAC,GAElD,GAAM,UAAU,GAAW;GAC7B,GAAW;GACX;EACF;EACA,AACE,MAAa,iBAAiB;GAE5B,AADA,IAAa,MACb,GAAW;EACb,GAAG,EAAiB;CALtB;AAOF;AAGA,eAAe,KAAuB;CACpC,IAAI,CAAC,MAAU,GAAM,WAAW,GAAG;CACnC,IAAM,IAAQ,GAAM,OAAO,GAAG,CAAS;CACvC,AAEE,OADA,aAAa,CAAU,GACV;CAGf,IAAI;EACF,MAAM,MAAM,GAAG,GAAO,OAAO,QAAQ,QAAQ,EAAE,EAAE,iBAAiB;GAChE,QAAQ;GACR,SAAS;IACP,gBAAgB;IAChB,oBAAoB,GAAO;GAC7B;GACA,MAAM,KAAK,UAAU;IACnB;IACA,eAAe,GAAO;IACtB,QAAQ,EAAM,KAAK,OAAO;KACxB,MAAM,EAAE;KACR,YAAY,EAAE;KACd,WAAW,EAAE;IACf,EAAE;GACJ,CAAC;GACD,WAAW;EACb,CAAC;CACH,QAAQ,CAGR;CAKA,AAAI,MAAU,GAAM,SAAS,KAAK,CAAC,MACjC,IAAa,iBAAiB;EAE5B,AADA,IAAa,MACb,GAAW;CACb,GAAG,EAAiB;AAExB;AAMA,SAAS,KAAwB;CAC/B,IAAI,MAAkB,OAAO,SAAW,KAAa;CACrD,KAAiB;CAEjB,IAAM,UAAa,KAAK,GAAM;CAE9B,AADA,OAAO,iBAAiB,YAAY,CAAI,GACxC,SAAS,iBAAiB,0BAA0B;EAClD,AAAI,SAAS,oBAAoB,YAAU,EAAK;CAClD,CAAC;AACH;;;AC9HA,IAAa,KAAb,cAAyC,EAGvC;CACA,QAAkC,EAAE,UAAU,GAAM;CAEpD,OAAO,2BAAqD;EAC1D,OAAO,EAAE,UAAU,GAAK;CAC1B;CAEA,kBAAkB,GAAoB;EAIpC,IAAI;GACF,KAAK,MAAM,QAAQ,CAAK;EAC1B,QAAQ,CAER;CACF;CAEA,SAAS;EAOP,OANI,KAAK,MAAM,WAIN,OAEF,KAAK,MAAM;CACpB;AACF,GC9BM,KAAyB;AAW/B,SAAS,GAAY,GAAiE;CACpF,IAAI,IAAW,IACX,IAAa;CAEjB,QAAQ,MAAY;EAClB,IAAM,IAAM,KAAK,IAAI;EACjB,KACA,IAAM,IAAa,OACvB,IAAW,IACX,IAAa,GAIb,MAAM,GAAG,EAAO,OAAO,QAAQ,QAAQ,EAAE,EAAE,gBAAgB;GACzD,QAAQ;GACR,SAAS;IACP,gBAAgB;IAChB,oBAAoB,EAAO;GAC7B;GACA,MAAM,KAAK,UAAU;IACnB,GAAG;IACH,eAAe,EAAO;GACxB,CAAC;GACD,WAAW;EACb,CAAC,CAAC,CACC,YAAY,CAGb,CAAC,CAAC,CACD,cAAc;GACb,IAAW;EACb,CAAC;CACL;AACF;AAEA,SAAS,KAAsC;CAC7C,OAAO,OAAO,SAAW,MAAc,OAAO,SAAS,OAAO,KAAA;AAChE;AAEA,SAAS,KAAuC;CAC9C,OAAO,OAAO,YAAc,MAAc,UAAU,YAAY,KAAA;AAClE;AAOA,IAAM,qBAAc,IAAI,QAAiE;AAEzF,SAAgB,GACd,GACA,GACA,GACM;CACN,IAAI,IAAO,GAAY,IAAI,CAAM;CACjC,AAAK,MACH,IAAO,GAAY,CAAM,GACzB,GAAY,IAAI,GAAQ,CAAI;CAE9B,IAAM,IAAQ,aAAe,QAAQ,IAAU,MAAM,OAAO,CAAG,CAAC;CAChE,EAAK;EACH,SAAS,EAAM;EACf,MAAM,EAAM;EACZ,OAAO,EAAM;EACb,KAAK,GAAgB;EACrB,WAAW,GAAiB;EAC5B,SAAS,GAAO;CAClB,CAAC;AACH;AAUA,IAAI,KAA6C;AAEjD,SAAgB,GAAkB,GAA0C;CAC1E,KAAiB;AACnB;AAEA,SAAgB,EAAY,GAAc,GAAoC;CACvE,MACL,GAAkB,IAAgB,GAAK,CAAK;AAC9C;;;ACrHA,IAAM,KAAc,uBAKhB,KAA2B,MAC3B,IAAkB,GAAc,KAAK,QAMrC,KAAa,GAAc,KAAK,MAC9B,qBAAY,IAAI,IAAc;AAEpC,SAAS,KAAkC;CACzC,IAAI;EACF,IAAM,IAAI,aAAa,QAAQ,EAAW;EAC1C,IAAI,MAAM,WAAW,MAAM,UAAU,MAAM,QAAQ,OAAO;CAC5D,QAAQ,CAER;CACA,OAAO;AACT;AAEA,SAAS,KAAQ;CACV,OACD,MAAS,SACX,OAAO,GAAK,QAAQ,QAEpB,GAAK,QAAQ,QAAQ;AAEzB;AAGA,SAAgB,GAAc,GAAiB,GAAqB;CAGlE,AAFA,KAAO,GACH,CAAC,MAAc,MAAS,IAAO,IACnC,GAAM;AACR;AAEA,SAAgB,KAA0B;CACxC,OAAO;AACT;AAGA,SAAgB,KAAkC;CAMhD,OALI,MAAS,SAAe,SACxB,MAAS,UAAgB,UACzB,OAAO,SAAW,OAAe,OAAO,cACnC,OAAO,WAAW,8BAA8B,CAAC,CAAC,UAAU,SAAS;AAGhF;AAEA,SAAgB,GAAa,GAAiB;CACxC,UAAS,GAIb;EAHA,IAAO,GAGP,KAAa;EACb,IAAI;GACF,aAAa,QAAQ,IAAa,CAAI;EACxC,QAAQ,CAER;EACA,GAAM;EACN,KAAK,IAAM,KAAM,IAAW,EAAG,CAAI;CAPtB;AAQf;AAEA,SAAgB,GAAe,GAA0B;CAEvD,OADA,GAAU,IAAI,CAAE,SACH;EACX,GAAU,OAAO,CAAE;CACrB;AACF;AAGA,SAAgB,KAA+B;CAC7C,IAAI,OAAO,SAAW,OAAe,CAAC,OAAO,YAAY,aAAa,CAAC;CACvE,IAAM,IAAK,OAAO,WAAW,8BAA8B,GACrD,UAAgB;EACpB,IAAI,MAAS,QAAQ,KAAK,IAAM,KAAM,IAAW,EAAG,CAAI;CAC1D;CAEA,OADA,EAAG,mBAAmB,UAAU,CAAO,SAC1B,EAAG,sBAAsB,UAAU,CAAO;AACzD;;;AC5FiC,IAAI,IAAE,GAAEqB,IAAEC,IAAE,KAAE,GAAEC,KAAE,CAAC,GAAE,IAAEC,GAAE,KAAE,EAAE,KAAI,KAAE,EAAE,KAAI,KAAE,EAAE,QAAO,KAAE,EAAE,KAAI,KAAE,EAAE,SAAQ,KAAE,EAAE;AAAG,SAAS,GAAE,GAAE,GAAE;CAAC,EAAE,OAAK,EAAE,IAAI,GAAE,GAAE,MAAG,CAAC,GAAE,KAAE;CAAE,IAAI,IAAE,EAAE,QAAM,EAAE,MAAI;EAAC,IAAG,CAAC;EAAE,KAAI,CAAC;CAAC;CAAG,OAAO,KAAG,EAAE,GAAG,UAAQ,EAAE,GAAG,KAAK,CAAC,CAAC,GAAE,EAAE,GAAG;AAAE;AAAC,SAAS,EAAE,GAAE;CAAC,OAAO,KAAE,GAAE,GAAE,IAAE,CAAC;AAAC;AAAC,SAAS,GAAE,GAAE,GAAE,GAAE;CAAC,IAAI,IAAE,GAAE,MAAI,CAAC;CAAE,IAAG,EAAE,IAAE,GAAE,CAAC,EAAE,QAAM,EAAE,KAAG,CAAC,IAAE,EAAE,CAAC,IAAE,GAAE,KAAK,GAAE,CAAC,GAAE,SAAS,GAAE;EAAC,IAAI,IAAE,EAAE,MAAI,EAAE,IAAI,KAAG,EAAE,GAAG,IAAG,IAAE,EAAE,EAAE,GAAE,CAAC;EAAE,MAAI,MAAI,EAAE,MAAI,CAAC,GAAE,EAAE,GAAG,EAAE,GAAE,EAAE,IAAI,SAAS,CAAC,CAAC;CAAE,CAAC,GAAE,EAAE,MAAI,GAAE,CAAC,EAAE,MAAK;EAAC,IAAI,IAAE,SAAS,GAAE,GAAE,GAAE;GAAC,IAAG,CAAC,EAAE,IAAI,KAAI,OAAM,CAAC;GAAE,IAAI,IAAE,CAAC,GAAE,IAAE,EAAE,IAAI,UAAQ;GAAE,IAAG,EAAE,IAAI,IAAI,GAAG,KAAK,SAAS,GAAE;IAAC,IAAG,EAAE,KAAI;KAAC,IAAE,CAAC;KAAE,IAAI,IAAE,EAAE,GAAG;KAAG,EAAE,KAAG,EAAE,KAAI,EAAE,MAAI,KAAK,GAAE,MAAI,EAAE,GAAG,OAAK,IAAE,CAAC;IAAE;GAAC,CAAC,GAAE,GAAE;IAAC,IAAI,IAAE,EAAE,KAAK,MAAK,GAAE,GAAE,CAAC;IAAE,OAAO,IAAE,KAAG,IAAE;GAAC;GAAC,OAAM,CAAC,KAAG;EAAC;EAAE,EAAE,MAAI,CAAC;EAAE,IAAI,IAAE,EAAE,uBAAsB,IAAE,EAAE;EAAoB,EAAE,sBAAoB,SAAS,GAAE,GAAE,GAAE;GAAC,IAAG,KAAK,KAAI;IAAC,IAAI,IAAE;IAAE,IAAE,KAAK,GAAE,EAAE,GAAE,GAAE,CAAC,GAAE,IAAE;GAAC;GAAC,KAAG,EAAE,KAAK,MAAK,GAAE,GAAE,CAAC;EAAC,GAAE,EAAE,wBAAsB;CAAC;CAAC,OAAO,EAAE,OAAK,EAAE;AAAE;AAAC,SAAS,EAAE,GAAE,GAAE;CAAC,IAAI,IAAE,GAAE,MAAI,CAAC;CAAE,CAAC,EAAE,OAAK,GAAE,EAAE,KAAI,CAAC,MAAI,EAAE,KAAG,GAAE,EAAE,IAAE,GAAE,EAAE,IAAI,IAAI,KAAK,CAAC;AAAE;AAAC,SAAS,GAAE,GAAE,GAAE;CAAC,IAAI,IAAE,GAAE,MAAI,CAAC;CAAE,CAAC,EAAE,OAAK,GAAE,EAAE,KAAI,CAAC,MAAI,EAAE,KAAG,GAAE,EAAE,IAAE,GAAE,EAAE,IAAI,KAAK,CAAC;AAAE;AAAC,SAAS,EAAE,GAAE;CAAC,OAAO,KAAE,GAAE,GAAE,WAAU;EAAC,OAAM,EAAC,SAAQ,EAAC;CAAC,GAAE,CAAC,CAAC;AAAC;AAAsN,SAAS,GAAE,GAAE,GAAE;CAAC,IAAI,IAAE,GAAE,MAAI,CAAC;CAAE,OAAO,GAAE,EAAE,KAAI,CAAC,MAAI,EAAE,KAAG,EAAE,GAAE,EAAE,MAAI,GAAE,EAAE,MAAI,IAAG,EAAE;AAAE;AAAC,SAAS,EAAE,GAAE,GAAE;CAAC,OAAO,KAAE,GAAE,GAAE,WAAU;EAAC,OAAO;CAAC,GAAE,CAAC;AAAC;AAAgf,SAAS,KAAG;CAAC,KAAI,IAAI,GAAE,IAAED,GAAE,MAAM,IAAG;EAAC,IAAI,IAAE,EAAE;EAAI,IAAG,EAAE,OAAK,GAAE,IAAG;GAAC,EAAE,IAAI,KAAK,EAAC,GAAE,EAAE,IAAI,KAAK,EAAC,GAAE,EAAE,MAAI,CAAC;EAAC,SAAO,GAAE;GAAC,EAAE,MAAI,CAAC,GAAE,EAAE,IAAI,GAAE,EAAE,GAAG;EAAC;CAAC;AAAC;AAAC,EAAE,MAAI,SAAS,GAAE;CAAC,IAAE,MAAK,MAAG,GAAE,CAAC;AAAC,GAAE,EAAE,KAAG,SAAS,GAAE,GAAE;CAAC,KAAG,EAAE,OAAK,EAAE,IAAI,QAAM,EAAE,MAAI,EAAE,IAAI,MAAK,MAAG,GAAE,GAAE,CAAC;AAAC,GAAE,EAAE,MAAI,SAAS,GAAE;CAAC,MAAG,GAAE,CAAC,GAAE,KAAE;CAAE,IAAI,KAAG,IAAE,EAAE,IAAA,CAAK;CAAI,MAAIF,OAAI,KAAG,EAAE,MAAI,CAAC,GAAE,EAAE,MAAI,CAAC,GAAE,EAAE,GAAG,KAAK,SAAS,GAAE;EAAC,EAAE,QAAM,EAAE,KAAG,EAAE,MAAK,EAAE,IAAE,EAAE,MAAI,KAAK;CAAC,CAAC,MAAI,EAAE,IAAI,KAAK,EAAC,GAAE,EAAE,IAAI,KAAK,EAAC,GAAE,EAAE,MAAI,CAAC,GAAE,KAAE,KAAI,KAAE;AAAC,GAAE,EAAE,SAAO,SAAS,GAAE;CAAC,MAAG,GAAE,CAAC;CAAE,IAAI,IAAE,EAAE;CAAI,KAAG,EAAE,QAAM,EAAE,IAAI,IAAI,WAAaE,GAAE,KAAK,CAAC,MAAZ,KAAeD,OAAI,EAAE,2BAAyB,KAAE,EAAE,0BAAwB,GAAA,CAAG,EAAC,IAAG,EAAE,IAAI,GAAG,KAAK,SAAS,GAAE;EAAC,AAAgB,EAAE,OAAZ,EAAE,MAAI,EAAE,GAAM,KAAK;CAAE,CAAC,IAAG,KAAE,IAAE;AAAI,GAAE,EAAE,MAAI,SAAS,GAAE,GAAE;CAAC,EAAE,KAAK,SAAS,GAAE;EAAC,IAAG;GAAC,EAAE,IAAI,KAAK,EAAC,GAAE,EAAE,MAAI,EAAE,IAAI,OAAO,SAAS,GAAE;IAAC,OAAM,CAAC,EAAE,MAAI,GAAE,CAAC;GAAC,CAAC;EAAC,SAAO,GAAE;GAAC,EAAE,KAAK,SAAS,GAAE;IAAC,AAAQ,EAAE,QAAI,CAAC;GAAE,CAAC,GAAE,IAAE,CAAC,GAAE,EAAE,IAAI,GAAE,EAAE,GAAG;EAAC;CAAC,CAAC,GAAE,MAAG,GAAE,GAAE,CAAC;AAAC,GAAE,EAAE,UAAQ,SAAS,GAAE;CAAC,MAAG,GAAE,CAAC;CAAE,IAAI,GAAE,IAAE,EAAE;CAAI,KAAG,EAAE,QAAM,EAAE,IAAI,GAAG,KAAK,SAAS,GAAE;EAAC,IAAG;GAAC,GAAE,CAAC;EAAC,SAAO,GAAE;GAAC,IAAE;EAAC;CAAC,CAAC,GAAE,EAAE,MAAI,KAAK,GAAE,KAAG,EAAE,IAAI,GAAE,EAAE,GAAG;AAAE;AAAE,IAAI,KAAc,OAAO,yBAAnB;AAAyC,SAAS,GAAE,GAAE;CAAC,IAAI,GAAE,IAAE,WAAU;EAAC,aAAa,CAAC,GAAE,MAAG,qBAAqB,CAAC,GAAE,WAAW,CAAC;CAAC,GAAE,IAAE,WAAW,GAAE,EAAE;CAAE,OAAI,IAAE,sBAAsB,CAAC;AAAE;AAAC,SAAS,GAAE,GAAE;CAAC,IAAI,IAAE,GAAE,IAAE,EAAE;CAAI,AAAY,OAAO,KAAnB,eAAuB,EAAE,MAAI,KAAK,GAAE,EAAE,IAAG,IAAE;AAAC;AAAC,SAAS,GAAE,GAAE;CAAC,IAAI,IAAE;CAAE,EAAE,MAAI,EAAE,GAAG,GAAE,IAAE;AAAC;AAAC,SAAS,GAAE,GAAE,GAAE;CAAC,OAAM,CAAC,KAAG,EAAE,WAAS,EAAE,UAAQ,EAAE,KAAK,SAAS,GAAE,GAAE;EAAC,OAAO,MAAI,EAAE;CAAE,CAAC;AAAC;AAAC,SAAS,GAAE,GAAE,GAAE;CAAC,OAAkB,OAAO,KAAnB,aAAqB,EAAE,CAAC,IAAE;AAAC;AEKn0G,KAAK,IDJQ,KAAU,UCAnB,KAAS,CAAC,GACV,IAAY,CAAC,GACb,KAAM,YACN,KAAO,oEACFG,KAAI,GAAG,KAAM,GAAK,QAAQA,KAAI,IAAK,EAAEA,IAE5C,AADA,GAAOA,MAAK,GAAKA,KACjB,EAAU,GAAK,WAAWA,EAAC,KAAKA;AAElC,EAAU,MAAqB,IAC/B,EAAU,MAAqB;AAC/B,SAAS,GAAQ,GAAK;CACpB,IAAI,IAAM,EAAI;CACd,IAAI,IAAM,IAAI,GACZ,MAAU,MAAM,gDAAgD;CAElE,IAAI,IAAW,EAAI,QAAQ,GAAG;CAC9B,AAAI,MAAa,OAAI,IAAW;CAChC,IAAI,IAAkB,MAAa,IAAM,IAAI,IAAI,IAAW;CAC5D,OAAO,CAAC,GAAU,CAAe;AACnC;AAOA,SAAS,GAAY,GAAM,GAAU,GAAiB;CACpD,QAAQ,IAAW,KAAmB,IAAI,IAAI;AAChD;AACA,SAAgB,GAAY,GAAK;CAC/B,IAAI,GACA,IAAO,GAAQ,CAAG,GAClB,IAAW,EAAK,IAChB,IAAkB,EAAK,IACvB,IAAM,IAAI,GAAI,GAAY,GAAK,GAAU,CAAe,CAAC,GACzD,IAAU,GACV,IAAM,IAAkB,IAAI,IAAW,IAAI,GAC3C;CACJ,KAAK,IAAI,GAAG,IAAI,GAAK,KAAK,GAIxB,AAHA,IAAM,EAAU,EAAI,WAAW,CAAC,MAAM,KAAK,EAAU,EAAI,WAAW,IAAI,CAAC,MAAM,KAAK,EAAU,EAAI,WAAW,IAAI,CAAC,MAAM,IAAI,EAAU,EAAI,WAAW,IAAI,CAAC,IAC1J,EAAI,OAAa,KAAO,KAAK,KAC7B,EAAI,OAAa,KAAO,IAAI,KAC5B,EAAI,OAAa,IAAM;CAWzB,OATI,MAAoB,MACtB,IAAM,EAAU,EAAI,WAAW,CAAC,MAAM,IAAI,EAAU,EAAI,WAAW,IAAI,CAAC,MAAM,GAC9E,EAAI,OAAa,IAAM,MAErB,MAAoB,MACtB,IAAM,EAAU,EAAI,WAAW,CAAC,MAAM,KAAK,EAAU,EAAI,WAAW,IAAI,CAAC,MAAM,IAAI,EAAU,EAAI,WAAW,IAAI,CAAC,MAAM,GACvH,EAAI,OAAa,KAAO,IAAI,KAC5B,EAAI,OAAa,IAAM,MAElB;AACT;AACA,SAAS,GAAgB,GAAK;CAC5B,OAAO,GAAO,KAAO,KAAK,MAAM,GAAO,KAAO,KAAK,MAAM,GAAO,KAAO,IAAI,MAAM,GAAO,IAAM;AAChG;AACA,SAAS,GAAY,GAAO,GAAO,GAAK;CAGtC,KAAK,IAFD,GACA,IAAS,CAAC,GACL,IAAI,GAAO,IAAI,GAAK,KAAK,GAEhC,AADA,KAAO,EAAM,MAAM,KAAK,aAAa,EAAM,IAAI,MAAM,IAAI,UAAU,EAAM,IAAI,KAAK,MAClF,EAAO,KAAK,GAAgB,CAAG,CAAC;CAElC,OAAO,EAAO,KAAK,EAAE;AACvB;AACA,SAAgB,GAAc,GAAO;CAMnC,KAAK,IALD,GACA,IAAM,EAAM,QACZ,IAAa,IAAM,GACnB,IAAQ,CAAC,GACT,IAAiB,OACZ,IAAI,GAAG,IAAO,IAAM,GAAY,IAAI,GAAM,KAAK,GACtD,EAAM,KACJ,GACE,GACA,GACA,IAAI,IAAiB,IAAO,IAAO,IAAI,CACzC,CACF;CAWF,OATI,MAAe,KACjB,IAAM,EAAM,IAAM,IAClB,EAAM,KAAK,GAAO,KAAO,KAAK,GAAO,KAAO,IAAI,MAAM,IAAI,KACjD,MAAe,MACxB,KAAO,EAAM,IAAM,MAAM,KAAK,EAAM,IAAM,IAC1C,EAAM,KACJ,GAAO,KAAO,MAAM,GAAO,KAAO,IAAI,MAAM,GAAO,KAAO,IAAI,MAAM,GACtE,IAEK,EAAM,KAAK,EAAE;AACtB;;;AC5FA,SAAgB,GAAU,GAAM;CAC9B,IAAI,MAAS,KAAK,GAChB,OAAO,CAAC;CAEV,IAAI,CAAC,GAAe,CAAI,GACtB,MAAU,MACR,mEAAmE,GACrE;CAEF,OAAO;AACT;AACA,SAAgB,GAAsB,GAAe;CACnD,IAAW,MAAkB,QAC3B,MAAU,MACR,6GACF;CAEF,IAAI,OAAO,KAAkB,UAC3B,MAAU,MACR,qCAAqC,EAAc,GACrD;CAEF,IAAI,EAAE,EAAc,WAAW,OAAO,KAAK,EAAc,WAAW,QAAQ,IAC1E,MAAU,MACR,+EAA+E,EAAc,GAC/F;CAEF,IAAI;EACF,IAAI,IAAI,CAAa;CACvB,QAAQ;EACN,MAAU,MACR,gCAAgC,EAAc,0HAChD;CACF;CACA,IAAI,EAAc,SAAS,cAAc,GACvC,MAAU,MACR,gCAAgC,EAAc,uNAChD;AAEJ;AACA,SAAgB,GAAe,GAAO;CACpC,IAAM,IAAW,OAAO,KAAU,UAC5B,IAAY,OAAO,eAAe,CAAK,GACvC,IAAW,MAAc,QAAQ,MAAc,OAAO,aAE5D,GAAW,aAAa,SAAS;CACjC,OAAO,KAAY;AACrB;;;AC7CA,IAAM,KAAgB,IAChB,KAAY,OAAO,sBAAsB,GACzC,KAAY,OAAO,qBAAqB,GACxC,KAAO,OAAO,GAAG,GACjB,KAAQ,OAAO,GAAG,GAClB,KAAc,OAAO,KAAK;AAChC,SAAS,GAAU,GAAG;CACpB,OAAO,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,KAAK,OAAO,GAAG,GAAG,EAAE;AAClE;AACA,SAAgB,GAAmB,GAAO;CACxC,AAAI,IAAQ,OACV,KAAS,KAAY;CAEvB,IAAI,IAAM,EAAM,SAAS,EAAE;CAC3B,AAAI,EAAI,SAAS,KAAM,MAAG,IAAM,MAAM;CACtC,IAAM,IAAQ,IAAI,2BAAW,IAAI,YAAY,CAAC,CAAC,GAC3C,IAAI;CACR,KAAK,IAAM,KAAW,EAAI,MAAM,OAAO,CAAC,CAAC,QAAQ,GAE/C,AADA,EAAM,IAAI,CAAC,SAAS,GAAS,EAAE,CAAC,GAAG,GAAG,GACtC,MAAU;CAEZ,OAAOC,GAAqB,CAAK;AACnC;AACA,SAAgB,GAAmB,GAAS;CAC1C,IAAM,IAAeC,GAAmB,CAAO;CAC/C,IAAI,EAAa,eAAe,GAC9B,MAAU,MACR,YAAY,EAAa,WAAW,gCACtC;CAEF,IAAI,IAAQ,IACR,IAAQ;CACZ,KAAK,IAAM,KAAQ,GAEjB,AADA,KAAS,OAAO,CAAI,IAAI,MAAe,GACvC;CAKF,OAHI,IAAQ,OACV,KAAS,KAAY,KAEhB;AACT;AACA,SAAgB,GAAqB,GAAO;CAC1C,IAAI,IAAQ,MAAa,KAAY,GACnC,MAAU,MACR,UAAU,EAAM,4CAClB;CAEF,IAAM,oBAAS,IAAI,YAAY,CAAC;CAEhC,OADA,IAAI,SAAS,CAAM,CAAC,CAAC,YAAY,GAAG,GAAO,EAAI,GACxCD,GAAqB,IAAI,WAAW,CAAM,CAAC;AACpD;AACA,SAAgB,GAAqB,GAAS;CAC5C,IAAM,IAAeC,GAAmB,CAAO;CAC/C,IAAI,EAAa,eAAe,GAC9B,MAAU,MACR,YAAY,EAAa,WAAW,gCACtC;CAGF,OAAO,IADkB,SAAS,EAAa,MAC7B,CAAC,CAAC,YAAY,GAAG,EAAI;AACzC;AACA,IAAa,KAAiB,SAAS,UAAU,cAAc,KAAuB,IACzE,KAAiB,SAAS,UAAU,cAAc,KAAuB,IAChF,KAAqB;AAC3B,SAAS,GAAoB,GAAG;CAC9B,IAAI,EAAE,SAAS,IACb,MAAU,MACR,cAAc,EAAE,qCAAqC,GAAmB,EAC1E;CAEF,IAAI,EAAE,WAAW,GAAG,GAClB,MAAU,MAAM,cAAc,EAAE,uCAAuC;CAEzE,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK,GAAG;EACpC,IAAM,IAAW,EAAE,WAAW,CAAC;EAC/B,IAAI,IAAW,MAAM,KAAY,KAC/B,MAAU,MACR,cAAc,EAAE,0BAA0B,EAAE,GAAG,6DACjD;CAEJ;AACF;AACA,SAAgB,GAAa,GAAO;CAUlC,IATI,MAAU,QAGV,OAAO,KAAU,aAGjB,OAAO,KAAU,YAGjB,OAAO,KAAU,UACnB,OAAO;CAET,IAAI,MAAM,QAAQ,CAAK,GACrB,OAAO,EAAM,KAAK,MAAW,GAAa,CAAM,CAAC;CAEnD,IAAI,OAAO,KAAU,UACnB,MAAU,MAAM,sBAAsB,GAAO;CAE/C,IAAM,IAAU,OAAO,QAAQ,CAAK;CACpC,IAAI,EAAQ,WAAW,GAAG;EACxB,IAAM,IAAM,EAAQ,EAAE,CAAC;EACvB,IAAI,MAAQ,UAAU;GACpB,IAAI,OAAO,EAAM,UAAW,UAC1B,MAAU,MAAM,6BAA6B,GAAO;GAEtD,OAAOA,GAAmB,EAAM,MAAM,CAAC,CAAC;EAC1C;EACA,IAAI,MAAQ,YAAY;GACtB,IAAI,OAAO,EAAM,YAAa,UAC5B,MAAU,MAAM,+BAA+B,GAAO;GAExD,OAAO,GAAe,EAAM,QAAQ;EACtC;EACA,IAAI,MAAQ,UAAU;GACpB,IAAI,OAAO,EAAM,UAAW,UAC1B,MAAU,MAAM,6BAA6B,GAAO;GAEtD,IAAM,IAAaA,GAAmB,EAAM,MAAM;GAClD,IAAI,EAAW,eAAe,GAC5B,MAAU,MACR,YAAY,EAAW,WAAW,8BACpC;GAGF,IAAM,IAAQ,IADa,SAAS,EAAW,MACpB,CAAC,CAAC,WAAW,GAAG,EAAa;GACxD,IAAI,CAAC,GAAU,CAAK,GAClB,MAAU,MAAM,SAAS,EAAM,+BAA+B;GAEhE,OAAO;EACT;EACA,IAAI,MAAQ,QACV,MAAU,MACR,+DACF;EAEF,IAAI,MAAQ,QACV,MAAU,MACR,+DACF;CAEJ;CACA,IAAM,IAAM,CAAC;CACb,KAAK,IAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,CAAK,GAEvC,AADA,GAAoB,CAAC,GACrB,EAAI,KAAK,GAAa,CAAC;CAEzB,OAAO;AACT;AACA,IAAM,KAA0B;AAChC,SAAgB,GAAuB,GAAO;CAC5C,IAAM,IAAM,KAAK,UAAU,IAAQ,GAAM,MACnC,MAAW,KAAK,IACX,cAEL,OAAO,KAAW,WACb,GAAG,EAAO,SAAS,EAAE,KAEvB,CACR;CACD,IAAI,EAAI,SAAS,IAAyB;EACxC,IACI,IAAa,OACX,IAAY,EAAI,YAAY,IAAa,CAAC;EAIhD,OAHI,MAAc,KAAK,KAAK,IAAY,SACtC,KAEK,EAAI,UAAU,GAAG,CAAU,IAAI;CACxC;CACA,OAAO;AACT;AACA,SAAS,GAAqB,GAAO,GAAe,GAAS,GAA0B;CACrF,IAAI,MAAU,KAAK,GAAG;EACpB,IAAM,IAAc,KAAW,qBAAqB,EAAQ,sBAAsB,GAChF,CACF,EAAE;EACF,MAAU,MACR,wCAAwC,EAAY,oFACtD;CACF;CACA,IAAI,MAAU,MACZ,OAAO;CAET,IAAI,OAAO,KAAU,UAAU;EAC7B,IAAI,IAAQ,MAAa,KAAY,GACnC,MAAU,MACR,UAAU,EAAM,4CAClB;EAEF,OAAO,EAAE,UAAU,GAAe,CAAK,EAAE;CAC3C;CACA,IAAI,OAAO,KAAU,UACnB,IAAI,GAAU,CAAK,GAAG;EACpB,IAAM,oBAAS,IAAI,YAAY,CAAC;EAEhC,OADA,IAAI,SAAS,CAAM,CAAC,CAAC,WAAW,GAAG,GAAO,EAAa,GAChD,EAAE,QAAQD,GAAqB,IAAI,WAAW,CAAM,CAAC,EAAE;CAChE,OACE,OAAO;CAMX,IAHI,OAAO,KAAU,aAGjB,OAAO,KAAU,UACnB,OAAO;CAET,IAAI,aAAiB,aACnB,OAAO,EAAE,QAAQA,GAAqB,IAAI,WAAW,CAAK,CAAC,EAAE;CAE/D,IAAI,MAAM,QAAQ,CAAK,GACrB,OAAO,EAAM,KACV,GAAQ,MAAM,GAAqB,GAAQ,GAAe,IAAU,IAAI,EAAE,IAAI,EAAK,CACtF;CAEF,IAAI,aAAiB,KACnB,MAAU,MACR,GAA+B,GAAS,OAAO,CAAC,GAAG,CAAK,GAAG,CAAa,CAC1E;CAEF,IAAI,aAAiB,KACnB,MAAU,MACR,GAA+B,GAAS,OAAO,CAAC,GAAG,CAAK,GAAG,CAAa,CAC1E;CAEF,IAAI,CAAC,GAAe,CAAK,GAAG;EAC1B,IAAM,IAAU,GAAO,aAAa,MAC9B,IAAW,IAAU,GAAG,EAAQ,KAAK;EAC3C,MAAU,MACR,GAA+B,GAAS,GAAU,GAAO,CAAa,CACxE;CACF;CACA,IAAM,IAAM,CAAC,GACP,IAAU,OAAO,QAAQ,CAAK;CACpC,EAAQ,MAAM,CAAC,GAAI,IAAM,CAAC,GAAI,OAAS,MAAO,IAAK,IAAI,IAAK,IAAK,KAAK,CAAC;CACvE,KAAK,IAAM,CAAC,GAAG,MAAM,GACnB,AAAI,MAAM,KAAK,IAGJ,MACT,GAAoB,CAAC,GACrB,EAAI,KAAK,GACP,GACA,GACA,IAAU,IAAI,GAChB,MARA,GAAoB,CAAC,GACrB,EAAI,KAAK,GAAqB,GAAG,GAAe,IAAU,IAAI,KAAK,EAAK;CAU5E,OAAO;AACT;AACA,SAAS,GAA+B,GAAS,GAAU,GAAO,GAAe;CAQ7E,OAPE,IACK,GAAG,IAAW,GACnB,CACF,EAAE,mDAAmD,EAAQ,sBAAsB,GACjF,CACF,EAAE,wFAEK,GAAG,IAAW,GACnB,CACF,EAAE;AAEN;AACA,SAAS,GAAgC,GAAO,GAAe,GAAS;CACtE,IAAI,MAAU,KAAK,GACjB,OAAO,EAAE,YAAY,KAAK;CAE1B,IAAI,MAAkB,KAAK,GACzB,MAAU,MACR,uCAAuC,GACrC,CACF,EAAE,iCACJ;CAEF,OAAO,GAAqB,GAAO,GAAe,GAAS,EAAK;AAEpE;AACA,SAAgB,GAAa,GAAO;CAClC,OAAO,GAAqB,GAAO,GAAO,IAAI,EAAK;AACrD;;;AC1RA,IAAIE,KAAY,OAAO,gBACnBC,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAMD,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJE,MAAiB,GAAK,GAAK,MAAUD,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GACzG,IAAI,IAEF,KAAoB,OAAO,IAAI,aAAa,GACrC,KAAb,eAAkC,KAAK,OAAO,KAAK,IAAmB,GAAA,CAAI;CACxE,YAAY,GAAM;EAKhB,AAJA,MAAM,OAAO,KAAS,WAAW,IAAO,GAAuB,CAAI,CAAC,GACpE,GAAc,MAAM,QAAQ,aAAa,GACzC,GAAc,MAAM,MAAM,GAC1B,GAAc,MAAM,IAAI,EAAI,GAC5B,KAAK,OAAO;CACd;AACF,GCdIE,KAAY,OAAO,gBACnBC,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAMD,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJE,MAAiB,GAAK,GAAK,MAAUD,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GACvG,KAAa;AACnB,SAAS,GAAkB,GAAQ;CACjC,QAAQ,GAAR;EACE,KAAK,SACH,OAAO;EACT,KAAK,YACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,OACH,OAAO;CACX;AACF;AACA,IAAa,KAAb,MAA2B;CACzB,YAAY,GAAS;EAInB,AAHA,GAAc,MAAM,iBAAiB,GACrC,GAAc,MAAM,UAAU,GAC9B,KAAK,kBAAkB,CAAC,GACxB,KAAK,WAAW,EAAQ;CAC1B;CACA,mBAAmB,GAAM;EACvB,IAAI,IAAK,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,GAAG,EAAE;EACnD,KAAK,IAAI,IAAI,GAAG,IAAI,MACd,KAAK,gBAAgB,OAAQ,KAAK,GADhB,KAItB,IAAK,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,GAAG,EAAE;EAGjD,OADA,KAAK,gBAAgB,KAAM,SACd;GACX,OAAO,KAAK,gBAAgB;EAC9B;CACF;CACA,WAAW,GAAG,GAAM;EAClB,IAAI,KAAK,UACP,KAAK,IAAM,KAAQ,OAAO,OAAO,KAAK,eAAe,GACnD,EAAK,SAAS,oBAAoB,IAAI,KAAK,EAAA,CAAG,YAAY,KAAK,GAAG,CAAI;CAG5E;CACA,IAAI,GAAG,GAAM;EACX,KAAK,IAAM,KAAQ,OAAO,OAAO,KAAK,eAAe,GACnD,EAAK,QAAQ,GAAG,CAAI;CAExB;CACA,KAAK,GAAG,GAAM;EACZ,KAAK,IAAM,KAAQ,OAAO,OAAO,KAAK,eAAe,GACnD,EAAK,QAAQ,GAAG,CAAI;CAExB;CACA,MAAM,GAAG,GAAM;EACb,KAAK,IAAM,KAAQ,OAAO,OAAO,KAAK,eAAe,GACnD,EAAK,SAAS,GAAG,CAAI;CAEzB;AACF;AACA,SAAgB,GAAyB,GAAS;CAChD,IAAM,IAAS,IAAI,GAAc,CAAO;CAqBxC,OApBA,EAAO,oBAAoB,GAAO,GAAG,MAAS;EAC5C,QAAQ,GAAR;GACE,KAAK;IACH,QAAQ,MAAM,GAAG,CAAI;IACrB;GACF,KAAK;IACH,QAAQ,IAAI,GAAG,CAAI;IACnB;GACF,KAAK;IACH,QAAQ,KAAK,GAAG,CAAI;IACpB;GACF,KAAK;IACH,QAAQ,MAAM,GAAG,CAAI;IACrB;GACF,SAEE,QAAQ,IAAI,GAAG,CAAI;EAEvB;CACF,CAAC,GACM;AACT;AACA,SAAgB,GAAsB,GAAS;CAC7C,OAAO,IAAI,GAAc,CAAO;AAClC;AACA,SAAgB,GAAe,GAAQ,GAAM,GAAQ,GAAS,GAAS;CACrE,IAAM,IAAS,GAAkB,CAAM;CAIvC,IAHI,OAAO,KAAY,aACrB,IAAU,eAAe,KAAK,UAAU,EAAQ,WAAW,MAAM,CAAC,MAEhE,MAAS,QAAQ;EACnB,IAAM,IAAQ,EAAQ,MAAM,WAAW;EACvC,IAAI,MAAU,MAAM;GAClB,EAAO,MACL,WAAW,EAAO,GAAG,EAAQ,+BAC/B;GACA;EACF;EACA,IAAM,IAAQ,EAAQ,MAAM,GAAG,EAAM,EAAE,CAAC,SAAS,CAAC,GAC5C,IAAO,EAAQ,MAAM,EAAM,EAAE,CAAC,MAAM;EAC1C,EAAO,IAAI,aAAa,EAAO,GAAG,EAAQ,MAAM,EAAM,IAAI,IAAY,CAAI;CAC5E,OACE,EAAO,MAAM,WAAW,EAAO,GAAG,EAAQ,KAAK,GAAS;AAE5D;AACA,SAAgB,GAAc,GAAQ,GAAS;CAC7C,IAAM,IAAe,wBAAwB;CAE7C,OADA,EAAO,MAAM,CAAY,GACd,MAAM,CAAY;AAC/B;AACA,SAAgB,GAA4B,GAAQ,GAAS,GAAQ;CAEnE,OAAO,WADQ,GAAkB,CACV,EAAE,GAAG,EAAQ,KAAK,EAAO,aAAa;;AAE/D;AACA,SAAgB,GAAY,GAAQ,GAAO;CAEzC,OADA,EAAM,OAAO,EAAO,WACb;AACT;;;ACtHA,SAAgB,GAAoB,GAAS;CAC3C,IAAM,IAAS,EAAQ,MAAM,GAAG,GAC5B,GACA;CAWJ,OAVI,EAAO,WAAW,KACpB,IAAa,EAAO,IACpB,IAAe,cAEf,IAAa,EAAO,MAAM,GAAG,EAAO,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,GACxD,IAAe,EAAO,EAAO,SAAS,KAEpC,EAAW,SAAS,KAAK,MAC3B,IAAa,EAAW,MAAM,GAAG,EAAE,IAE9B,GAAG,EAAW,GAAG;AAC1B;AACA,SAAgB,GAAqB,GAAS,GAAM;CAClD,OAAO,KAAK,UAAU;EACpB,SAAS,GAAoB,CAAO;EACpC,MAAM,GAAa,CAAI;CACzB,CAAC;AACH;AACA,SAAgB,GAA8B,GAAS,GAAM,GAAS;CACpE,IAAM,EAAE,oBAAiB,UAAO;CAOhC,OANe,KAAK,UAAU;EAC5B,MAAM;EACN,SAAS,GAAoB,CAAO;EACpC,MAAM,GAAa,CAAI;EACvB,SAAS,GAAa;GAAE;GAAiB;EAAG,CAAC;CAC/C,CACY;AACd;AACA,SAAgB,GAAgC,GAAO;CACrD,OAAO,KAAK,MAAM,CAAK,CAAC,CAAC,SAAS;AACpC;;;ACnCA,IAAIE,KAAY,OAAO,gBACnBC,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAMD,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJE,MAAiB,GAAK,GAAK,MAAUD,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GAMhG,KAAb,MAA4B;CAC1B,cAAc;EAmBZ,AAlBA,GAAc,MAAM,aAAa,GACjC,GAAc,MAAM,iBAAiB,GACrC,GAAc,MAAM,UAAU,GAC9B,GAAc,MAAM,gBAAgB,GACpC,GAAc,MAAM,iBAAiB,GACrC,GAAc,MAAM,MAAM,GAC1B,GAAc,MAAM,oCAAoC,GACxD,GAAc,MAAM,iCAAiC,GACrD,GAAc,MAAM,QAAQ,GAC5B,GAAc,MAAM,8BAA8B,GAClD,KAAK,cAAc,GACnB,KAAK,kBAAkB,GACvB,KAAK,kBAAkB,GACvB,KAAK,2BAA2B,IAAI,IAAI,GACxC,KAAK,iCAAiC,IAAI,IAAI,GAC9C,KAAK,qDAAqD,IAAI,IAAI,GAClE,KAAK,kCAAkC,IACvC,KAAK,SAAS,IACd,KAAK,+CAA+C,IAAI,IAAI;CAC9D;CACA,6BAA6B;EAC3B,OAAO,KAAK,mCAAmC,SAAS,KAAK,CAAC,KAAK;CACrE;CACA,qBAAqB;EACnB,KAAK,kCAAkC;CACzC;CACA,UAAU,GAAS,GAAM,GAAS,GAAe;EAC/C,IAAM,IAAuB,GAAoB,CAAO,GAClD,IAAa,GAAqB,GAAsB,CAAI,GAC5D,IAAgB,KAAK,SAAS,IAAI,CAAU;EAClD,IAAI,MAAkB,KAAK,GAEzB,OADA,EAAc,kBAAkB,GACzB;GACL;GACA,cAAc;GACd,mBAAmB,KAAK,iBAAiB,CAAU;EACrD;EACK;GACL,IAAM,IAAU,KAAK,eACf,IAAQ;IACZ,IAAI;IACJ;IACA;IACA,gBAAgB;IAChB;IACA;GACF;GAEA,AADA,KAAK,SAAS,IAAI,GAAY,CAAK,GACnC,KAAK,eAAe,IAAI,GAAS,CAAU;GAC3C,IAAM,IAAc,KAAK,iBACnB,IAAa,KAAK,kBAAkB,GACpC,IAAM;IACV,MAAM;IACN;IACA,SAAS;IACT,MAAM,CAAC,GAAa,CAAI,CAAC;IACzB;IACA;GACF;GAYA,OAXI,KAAK,SACP,KAAK,6BAA6B,IAAI,GAAS,CAAG,IAElD,KAAK,kBAAkB,GAQlB;IACL;IACA,cAAA;KAPA,MAAM;KACN;KACA;KACA,eAAe,CAAC,CAAG;IAIR;IACX,mBAAmB,KAAK,iBAAiB,CAAU;GACrD;EACF;CACF;CACA,WAAW,GAAY;EACrB,KAAK,IAAM,KAAgB,EAAW,eACpC,QAAQ,EAAa,MAArB;GACE,KAAK;GACL,KAAK,eAAe;IAClB,KAAK,mCAAmC,OAAO,EAAa,OAAO;IACnE,IAAM,IAAU,EAAa;IAC7B,IAAI,MAAY,KAAK,GAAG;KACtB,IAAM,IAAa,KAAK,eAAe,IAAI,EAAa,OAAO;KAC/D,AAAI,MAAe,KAAK,MACtB,KAAK,SAAS,IAAI,CAAU,CAAC,CAAC,UAAU;IAE5C;IACA;GACF;GACA,KAAK;IACH,KAAK,mCAAmC,OAAO,EAAa,OAAO;IACnE;GAEF,SAEE,MAAU,MAAM,wBAAwB,EAAa,MAAM;EAE/D;CAEJ;CACA,QAAQ,GAAS,GAAM;EAErB,IAAM,IAAa,GADU,GAAoB,CACT,GAAsB,CAAI,GAC5D,IAAgB,KAAK,SAAS,IAAI,CAAU;EAIlD,OAHI,MAAkB,KAAK,IAGpB,OAFE,EAAc;CAGzB;CACA,4BAA4B,GAAS;EACnC,OAAO,KAAW,KAAK;CACzB;CACA,UAAU;EACR,OAAO,KAAK;CACd;CACA,QAAQ,GAAO;EACb,KAAK,OAAO;GACV,WAAW;GACX;EACF;EACA,IAAM,IAAc,KAAK;EAIzB,OAHK,KAAK,WACR,KAAK,kBAAkB,IAAc,IAEhC;GACL,MAAM;GACN;GACA,GAAG,KAAK;EACV;CACF;CACA,aAAa,GAAO,GAAU;EAC5B,IAAM,IAAO;GACX,WAAW;GACX;GACA,eAAe;EACjB;EACA,KAAK,OAAO;EACZ,IAAM,IAAc,KAAK;EAIzB,OAHK,KAAK,WACR,KAAK,kBAAkB,IAAc,IAEhC;GACL,MAAM;GACN;GACA,GAAG;EACL;CACF;CACA,YAAY;EAEV,AADA,KAAK,OAAO,KAAK,GACjB,KAAK,mBAAmB;EACxB,IAAM,IAAc,KAAK;EAIzB,OAHK,KAAK,WACR,KAAK,kBAAkB,IAAc,IAEhC;GACL,MAAM;GACN,WAAW;GACX;EACF;CACF;CACA,UAAU;EACR,OAAO,CAAC,CAAC,KAAK;CAChB;CACA,UAAU,GAAO;EACf,OAAO,KAAK,MAAM,UAAU;CAC9B;CACA,UAAU,GAAS;EACjB,IAAM,IAAc,KAAK,eAAe,IAAI,CAAO;EAInD,OAHI,IACK,KAAK,SAAS,IAAI,CAAW,CAAC,CAAC,uBAEjC;CACT;CACA,UAAU,GAAS;EACjB,IAAM,IAAc,KAAK,eAAe,IAAI,CAAO;EAInD,OAHI,IACK,KAAK,SAAS,IAAI,CAAW,CAAC,CAAC,OAEjC;CACT;CACA,WAAW,GAAS;EAClB,OAAO,KAAK,eAAe,IAAI,CAAO,KAAK;CAC7C;CACA,aAAa,GAAY;EACvB,OAAO,KAAK,SAAS,IAAI,CAAU,CAAC,EAAE;CACxC;CACA,UAAU;EAER,AADA,KAAK,QAAQ,GACb,KAAK,mCAAmC,MAAM;EAC9C,IAAM,IAAgB,CAAC;EACvB,KAAK,IAAM,KAAc,KAAK,SAAS,OAAO,GAAG;GAC/C,IAAM,IAAM;IACV,MAAM;IACN,SAAS,EAAW;IACpB,SAAS,EAAW;IACpB,MAAM,CAAC,GAAa,EAAW,IAAI,CAAC;IACpC,SAAS,EAAW;IACpB,eAAe,EAAW;GAC5B;GAEA,AADA,EAAc,KAAK,CAAG,GACtB,KAAK,mCAAmC,IAAI,EAAW,EAAE;EAC3D;EACA,KAAK,kBAAkB;EACvB,IAAM,IAAW;GACf,MAAM;GACN,aAAa;GACb,YAAY;GACZ;EACF;EACA,IAAI,CAAC,KAAK,MAER,OADA,KAAK,kBAAkB,GAChB,CAAC,GAAU,KAAK,CAAC;EAE1B,KAAK,kCAAkC;EACvC,IAAM,IAAe;GACnB,MAAM;GACN,aAAa;GACb,GAAG,KAAK;EACV;EAEA,OADA,KAAK,kBAAkB,GAChB,CAAC,GAAU,CAAY;CAChC;CACA,QAAQ;EACN,KAAK,SAAS;CAChB;CACA,SAAS;EACP,IAAM,IAAW,KAAK,6BAA6B,OAAO,IAAI;GAC5D,MAAM;GACN,aAAa,KAAK;GAClB,YAAY,EAAE,KAAK;GACnB,eAAe,MAAM,KACnB,KAAK,6BAA6B,OAAO,CAC3C;EACF,IAAI,KAAK,GACH,IAAe,KAAK,SAAS,KAAK,IAIpC,KAAK,IAJmC;GAC1C,MAAM;GACN,aAAa,KAAK;GAClB,GAAG,KAAK;EACV;EAEA,OADA,KAAK,QAAQ,GACN,CAAC,GAAU,CAAY;CAChC;CACA,UAAU;EAER,AADA,KAAK,SAAS,IACd,KAAK,6BAA6B,MAAM;CAC1C;CACA,iBAAiB,GAAY;EAC3B,IAAM,IAAa,KAAK,SAAS,IAAI,CAAU;EAC/C,IAAI,EAAW,iBAAiB,GAE9B,OADA,IAAW,gBACJ;EACF;GAGL,AAFA,KAAK,SAAS,OAAO,CAAU,GAC/B,KAAK,eAAe,OAAO,EAAW,EAAE,GACxC,KAAK,mCAAmC,OAAO,EAAW,EAAE;GAC5D,IAAM,IAAc,KAAK,iBACnB,IAAa,KAAK,kBAAkB,GACpC,IAAS;IACb,MAAM;IACN,SAAS,EAAW;GACtB;GAUA,OATI,KAAK,SACH,KAAK,6BAA6B,IAAI,EAAW,EAAE,IACrD,KAAK,6BAA6B,OAAO,EAAW,EAAE,IAEtD,KAAK,6BAA6B,IAAI,EAAW,IAAI,CAAM,IAG7D,KAAK,kBAAkB,GAElB;IACL,MAAM;IACN;IACA;IACA,eAAe,CAAC,CAAM;GACxB;EACF;CACF;AACF,GCnSIE,KAAY,OAAO,gBACnBC,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAMD,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJE,MAAiB,GAAK,GAAK,MAAUD,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GAGhG,KAAb,MAA4B;CAC1B,YAAY,GAAQ,GAA0B;EAQ5C,AAPA,KAAK,SAAS,GACd,KAAK,2BAA2B,GAChC,GAAc,MAAM,kBAAkB,GACtC,GAAc,MAAM,0BAA0B,GAC9C,GAAc,MAAM,0BAA0B,CAAC,GAC/C,GAAc,MAAM,wBAAwB,CAAC,GAC7C,KAAK,mCAAmC,IAAI,IAAI,GAChD,KAAK,2CAA2C,IAAI,IAAI;CAC1D;CACA,QAAQ,GAAS,GAAM;EACrB,IAAM,IAAS,IAAI,SAAS,MAAY;GACtC,IAAM,IAAS,IAAO,cAAc;GAKpC,AAJA,KAAK,iBAAiB,IAAI,EAAQ,WAAW;IAC3C;IACA,QAAQ;KAAE;KAAQ,6BAA6B,IAAI,KAAK;KAAG,UAAU;IAAQ;GAC/E,CAAC,GACG,EAAQ,SAAS,aACnB,KAAK,2BACI,EAAQ,SAAS,YAC1B,KAAK;EAET,CAAC;EAED,OADA,KAAK,yBAAyB,GACvB;CACT;CAOA,WAAW,GAAU;EACnB,IAAM,IAAc,KAAK,iBAAiB,IAAI,EAAS,SAAS;EAIhE,IAHI,MAAgB,KAAK,KAGrB,EAAY,OAAO,WAAW,aAChC,OAAO;EAET,IAAM,IAAU,EAAY,QAAQ,SAAS,aAAa,aAAa,UACjE,IAAU,EAAY,QAAQ;EACpC,KAAK,IAAM,KAAQ,EAAS,UAC1B,GAAe,KAAK,QAAQ,QAAQ,GAAS,GAAS,CAAI;EAE5D,IAAM,IAAS,EAAY,QACvB,GACA;EACJ,IAAI,EAAS,SAMX,AALA,IAAS;GACP,SAAS;GACT,UAAU,EAAS;GACnB,OAAO,GAAa,EAAS,MAAM;EACrC,GACA,UAAkB,EAAO,SAAS,CAAM;OACnC;GACL,IAAM,IAAe,EAAS,QACxB,EAAE,iBAAc;GAQtB,AAPA,GAAe,KAAK,QAAQ,SAAS,GAAS,GAAS,CAAY,GACnE,IAAS;IACP,SAAS;IACT;IACA,WAAW,MAAc,KAAK,IAA8B,KAAK,IAA/B,GAAa,CAAS;IACxD,UAAU,EAAS;GACrB,GACA,UAAkB,EAAO,SAAS,CAAM;EAC1C;EAmBA,OAlBI,EAAS,SAAS,oBAAoB,CAAC,EAAS,WAClD,EAAU,GACV,KAAK,iBAAiB,OAAO,EAAS,SAAS,GAC/C,KAAK,yBAAyB,OAAO,EAAS,SAAS,GACnD,EAAY,QAAQ,SAAS,WAC/B,KAAK,yBACI,EAAY,QAAQ,SAAS,cACtC,KAAK,0BAEP,KAAK,yBAAyB,GACvB;GAAE,WAAW,EAAS;GAAW;EAAO,MAEjD,EAAY,SAAS;GACnB,QAAQ;GACR;GACA,IAAI,EAAS;GACb;EACF,GACO;CACT;CAEA,gBAAgB,GAAI;EAClB,IAAM,oBAAmC,IAAI,IAAI;EACjD,KAAK,IAAM,CAAC,GAAW,MAAgB,KAAK,iBAAiB,QAAQ,GAAG;GACtE,IAAM,IAAS,EAAY;GAC3B,AAAI,EAAO,WAAW,eAAe,EAAO,GAAG,gBAAgB,CAAE,MAC/D,EAAO,UAAU,GACjB,EAAiB,IAAI,GAAW,EAAO,MAAM,GACzC,EAAY,QAAQ,SAAS,aAC/B,KAAK,2BACI,EAAY,QAAQ,SAAS,YACtC,KAAK,wBAEP,KAAK,iBAAiB,OAAO,CAAS,GACtC,KAAK,yBAAyB,OAAO,CAAS;EAElD;EAIA,OAHI,EAAiB,OAAO,KAC1B,KAAK,yBAAyB,GAEzB;CACT;CACA,UAAU;EACR,KAAK,2BAA2B,IAAI,IAAI,KAAK,iBAAiB,KAAK,CAAC;EACpE,IAAM,IAAc,CAAC;EACrB,KAAK,IAAM,CAAC,GAAW,MAAU,KAAK,kBAAkB;GACtD,IAAI,EAAM,OAAO,WAAW,WAAW;IAErC,AADA,EAAM,OAAO,SAAS,aACtB,EAAY,KAAK,EAAM,OAAO;IAC9B;GACF;GACA,IAAI,EAAM,QAAQ,SAAS,YACzB,EAAY,KAAK,EAAM,OAAO;QACzB,IAAI,EAAM,QAAQ,SAAS,UAAU;IAI1C,IAHA,KAAK,iBAAiB,OAAO,CAAS,GACtC,KAAK,yBAAyB,OAAO,CAAS,GAC9C,KAAK,wBACD,EAAM,OAAO,WAAW,aAC1B,MAAU,MAAM,6CAA6C;IAE/D,EAAM,OAAO,SAAS;KACpB,SAAS;KACT,cAAc;KACd,UAAU,CAAC;IACb,CAAC;GACH;EACF;EAEA,OADA,KAAK,yBAAyB,GACvB;CACT;CACA,SAAS;EACP,IAAM,IAAc,CAAC;EACrB,KAAK,IAAM,GAAG,MAAU,KAAK,kBAC3B,IAAI,EAAM,OAAO,WAAW,WAAW;GAErC,AADA,EAAM,OAAO,SAAS,aACtB,EAAY,KAAK,EAAM,OAAO;GAC9B;EACF;EAEF,OAAO;CACT;CAKA,wBAAwB;EACtB,KAAK,IAAM,KAAe,KAAK,iBAAiB,OAAO,GACrD,IAAI,EAAY,OAAO,WAAW,aAChC,OAAO;EAGX,OAAO;CACT;CAKA,sBAAsB;EACpB,OAAO,KAAK,iBAAiB,OAAO;CACtC;CAKA,6BAA6B;EAC3B,OAAO,KAAK,yBAAyB,SAAS;CAChD;CACA,8BAA8B;EAC5B,IAAI,KAAK,iBAAiB,SAAS,GACjC,OAAO;EAET,IAAI,IAAwB,KAAK,IAAI;EACrC,KAAK,IAAM,KAAW,KAAK,iBAAiB,OAAO,GACjD,AAAI,EAAQ,OAAO,WAAW,eACxB,EAAQ,OAAO,YAAY,QAAQ,IAAI,MACzC,IAAwB,EAAQ,OAAO,YAAY,QAAQ;EAIjE,OAAO,IAAI,KAAK,CAAqB;CACvC;CAIA,oBAAoB;EAClB,OAAO,KAAK;CACd;CAIA,kBAAkB;EAChB,OAAO,KAAK;CACd;AACF,GC9Ma,KAAe,OAAO,IAAI,cAAc,GCCxC,KAAkB,OAAO,IAAI,iBAAiB;AAI3D,SAAgB,GAAqB,GAAW;CAC9C,OAAO,EAAU,OAAoB;AACvC;AACA,SAAgB,GAAiB,GAAG;CAClC,OAAO,EAAE,WAAW,aAAa;AACnC;AACA,SAAgB,GAAmB,GAAmB;CACpD,IAAI;CACJ,IAAI,OAAO,KAAsB,UAC/B,AAGE,IAHE,GAAiB,CAAiB,IAClB,EAAE,gBAAgB,EAAkB,IAEpC,EAAE,MAAM,EAAkB;MAEzC,IAAI,EAAkB,KAC3B,IAAkB,EAAE,MAAM,EAAkB,IAAc;MACrD;EACL,IAAM,IAAgB,GAAqB,CAAiB;EAC5D,IAAI,CAAC,GACH,MAAU,MAAM,GAAG,EAAkB,4BAA4B;EAEnE,IAAkB,EAAE,WAAW,EAAc;CAC/C;CACA,OAAO;AACT;;;AC3BA,SAAgB,GAAgB,GAAmB;CACjD,IAAM,IAAU,GAAmB,CAAiB;CACpD,IAAI,EAAQ,SAAS,KAAK,GAUxB,MATI,EAAQ,mBAAmB,KAAK,IAIzB,EAAQ,cAAc,KAAK,IAK5B,MACR,0FAA0F,KAAK,UAAU,CAAO,GAClH,IANY,MACR,6HAA6H,EAAQ,WACvI,IANU,MACR,0GAA0G,EAAQ,gBACpH;CAUJ,IAAI,OAAO,KAAsB,UAAU,OAAO;CAClD,IAAM,IAAO,EAAkB;CAC/B,IAAI,CAAC,GACH,MAAU,MAAM,GAAG,EAAkB,4BAA4B;CAEnE,OAAO;AACT;AACA,SAAgB,GAAsB,GAAM;CAC1C,OAAO,GAAG,KAAe,EAAK;AAChC;AACA,SAAS,GAAU,IAAY,CAAC,GAAG;CA2BjC,OAAO,IAAI,MAAM,CAAC,GAAG,EAzBnB,IAAI,GAAG,GAAM;EACX,IAAI,OAAO,KAAS,UAElB,OAAO,GAAU,CADC,GAAG,GAAW,CACR,CAAC;EACpB,IAAI,MAAS,IAAc;GAChC,IAAI,EAAU,SAAS,GAAG;IACxB,IAAM,IAAQ,CAAC,OAAO,GAAG,CAAS,CAAC,CAAC,KAAK,GAAG;IAC5C,MAAU,MACR,oFAAoF,EAAM,GAC5F;GACF;GACA,IAAM,IAAO,EAAU,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,GAAG,GACtC,IAAa,EAAU,EAAU,SAAS;GAI9C,OAHE,MAAe,YACV,IAEA,IAAO,MAAM;EAExB;EAAO,IAAI,MAAS,OAAO,aACzB,OAAO;CAIX,EAEyB,CAAC;AAC9B;AAyBsB,GAAU;;;ACjFhC,IAAIE,KAAY,OAAO,gBACnBC,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAMD,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJE,MAAiB,GAAK,GAAK,MAAUD,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GAWvG,KAAN,MAAM,EAAyB;CAC7B,YAAY,GAAc;EAMxB,AAJA,GAAc,MAAM,cAAc,GAElC,GAAc,MAAM,iBAAiB,GACrC,KAAK,eAAe,GACpB,KAAK,kBAAkB,CAAC;CAC1B;CACA,SAAS,GAAO,GAAG,GAAM;EACvB,IAAM,IAAY,GAAU,EAAK,EAAE,GAC7B,IAAO,GAAgB,CAAK,GAC5B,IAAc,KAAK,aAAa,IACpC,GAAqB,GAAM,CAAS,CACtC;EACI,UAAgB,KAAK,GAGzB,OAAO,EAAyB,WAAW,EAAY,MAAM;CAC/D;CACA,cAAc,GAAO;EACnB,IAAM,IAAkB,CAAC,GACnB,IAAO,GAAgB,CAAK;EAClC,KAAK,IAAM,KAAe,KAAK,aAAa,OAAO,GACjD,AAAI,EAAY,YAAY,GAAoB,CAAI,KAClD,EAAgB,KAAK;GACnB,MAAM,EAAY;GAClB,OAAO,EAAyB,WAAW,EAAY,MAAM;EAC/D,CAAC;EAGL,OAAO;CACT;CACA,SAAS,GAAgB,GAAM,GAAO;EACpC,IAAM,IAAY,GAAU,CAAI,GAC1B,IAAO,GAAgB,CAAc,GACrC,IAAa,GAAqB,GAAM,CAAS,GACnD;EACJ,AAGE,IAHE,MAAU,KAAK,IACR,KAAK,IAEL;GACP,SAAS;GACT;GAEA,UAAU,CAAC;EACb;EAEF,IAAM,IAAQ;GACZ,SAAS;GACT,MAAM;GACN;EACF;EAEA,AADA,KAAK,aAAa,IAAI,GAAY,CAAK,GACvC,KAAK,gBAAgB,KAAK,CAAU;CACtC;CACA,OAAO,WAAW,GAAQ;EACpB,UAAW,KAAK,KAET,EAAO,SAChB,OAAO,EAAO;CAIlB;AACF,GACa,KAAb,MAAoC;CAClC,cAAc;EAIZ,AAHA,GAAc,MAAM,cAAc,GAClC,GAAc,MAAM,mBAAmB,GACvC,KAAK,+BAA+B,IAAI,IAAI,GAC5C,KAAK,oBAAoB,CAAC;CAC5B;CAIA,6BAA6B,GAAoB,GAAyB;EACxE,KAAK,oBAAoB,KAAK,kBAAkB,QAAQ,MAC/C,CAAC,EAAwB,IAAI,EAAY,UAAU,CAC3D;EACD,IAAM,IAAkB,KAAK;EAC7B,KAAK,eAAe,IAAI,IAAI,CAAkB;EAC9C,IAAM,IAAa,IAAI,GAAyB,KAAK,YAAY;EACjE,KAAK,IAAM,KAAe,KAAK,mBAC7B,EAAY,OAAO,CAAU;EAE/B,IAAM,IAAiB,CAAC;EACxB,KAAK,IAAM,CAAC,GAAY,MAAU,KAAK,cAAc;GACnD,IAAM,IAAW,EAAgB,IAAI,CAAU;GAC/C,CAAI,MAAa,KAAK,KAAK,EAAS,WAAW,EAAM,WACnD,EAAe,KAAK,CAAU;EAElC;EACA,OAAO;CACT;CACA,sBAAsB,GAAQ,GAAY;EACxC,KAAK,kBAAkB,KAAK;GAC1B;GACA;EACF,CAAC;EACD,IAAM,IAAa,IAAI,GAAyB,KAAK,YAAY;EAEjE,OADA,EAAO,CAAU,GACV,EAAW;CACpB;CAOA,eAAe,GAAY;EACzB,IAAM,IAAQ,KAAK,aAAa,IAAI,CAAU;EAC1C,UAAU,KAAK,GAGnB,OAAO,EAAM;CACf;CACA,YAAY,GAAY;EACtB,IAAM,IAAQ,KAAK,aAAa,IAAI,CAAU;EAC9C,IAAI,MAAU,KAAK,GACjB;EAEF,IAAM,IAAS,EAAM;EACjB,UAAW,KAAK,GAEb;OAAI,EAAO,SAChB,OAAO,EAAO;GAUd,MARI,EAAO,cAAc,KAAK,IAQpB,MACR,GAA4B,SAAS,EAAM,SAAS,CAAM,CAC5D,IATQ,GACJ,GACA,IAAI,GACF,GAA4B,SAAS,EAAM,SAAS,CAAM,CAC5D,CACF;EAKJ;CACF;CACA,eAAe,GAAY;EACzB,OAAO,KAAK,aAAa,IAAI,CAAU,MAAM,KAAK;CACpD;CAIA,UAAU,GAAY;EAEpB,OADc,KAAK,aAAa,IAAI,CACzB,CAAC,EAAE,QAAQ;CACxB;AACF,GCpKIE,KAAY,OAAO,gBACnBC,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAMD,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJE,MAAiB,GAAK,GAAK,MAAUD,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GAChG,KAAb,MAAa,EAAK;CAChB,YAAY,GAAK,GAAM;EAMrB,AALA,GAAc,MAAM,KAAK,GACzB,GAAc,MAAM,MAAM,GAC1B,GAAc,MAAM,oBAAoB,GACxC,KAAK,MAAM,IAAM,GACjB,KAAK,OAAO,IAAO,GACnB,KAAK,qBAAqB;CAC5B;CACA,OAAO,OAAO,GAAK;EACjB,QAAQ,KAAO,EAAI,wBAAwB;CAC7C;CAEA,OAAO,YAAY,GAAO;EACxB,OAAO,IAAI,EACT,EAAM,KAAK,EAAM,MAAM,IAAI,EAAM,MAAM,KAAK,EAAM,MAAM,IACxD,EAAM,KAAK,EAAM,MAAM,IAAI,EAAM,MAAM,KAAK,EAAM,MAAM,EAC1D;CACF;CAEA,YAAY;EACV,IAAM,IAAK,KAAK,MACV,IAAK,KAAK;EAChB,OAAO;GACL,IAAK;GACL,MAAO,IAAI;GACX,MAAO,KAAK;GACZ,MAAO;GACP,IAAK;GACL,MAAO,IAAI;GACX,MAAO,KAAK;GACZ,MAAO;EACT;CACF;CACA,OAAO,WAAW,GAAO;EAIvB,OAHI,MAAM,CAAK,KACX,IAAQ,IAAU,KAClB,KAAS,KAAuB,KAC7B,IAAI,EAAK,IAAQ,KAAiB,GAAG,IAAQ,KAAiB,CAAC;CACxE;CACA,WAAW;EACT,QAAQ,OAAO,KAAK,IAAI,IAAI,OAAO,EAAc,IAAI,OAAO,KAAK,GAAG,EAAA,CAAG,SAAS;CAClF;CACA,OAAO,GAAO;EAGZ,OAFK,EAAK,OAAO,CAAK,MAAG,IAAQ,EAAK,UAAU,CAAK,IACjD,KAAK,SAAS,MAAO,KAAK,EAAM,SAAS,MAAO,IAAU,KACvD,KAAK,SAAS,EAAM,QAAQ,KAAK,QAAQ,EAAM;CACxD;CACA,UAAU,GAAO;EACf,OAAO,CAAC,KAAK,OAAO,CAAK;CAC3B;CACA,KAAK,GAAO;EAGV,OAFK,EAAK,OAAO,CAAK,MAAG,IAAQ,EAAK,UAAU,CAAK,IACjD,KAAK,OAAO,CAAK,IAAU,IACxB,EAAM,SAAS,IAAI,KAAK,SAAS,KAAK,EAAM,SAAS,KAAK,QAAQ,EAAM,QAAQ,IAAI,KAAK,QAAQ,IAAI,KAAK;CACnH;CACA,gBAAgB,GAAO;EACrB,OAAO,KAAK,KAEV,CACF,KAAK;CACP;CACA,OAAO,UAAU,GAAK;EAEpB,OADI,OAAO,KAAQ,WAAiB,EAAK,WAAW,CAAG,IAChD,IAAI,EAAK,EAAI,KAAK,EAAI,IAAI;CACnC;AACF,GACM,KAAQ,IAAI,GAAK,GAAG,CAAC,GACrB,KAAiB,OACjB,KAAiB,KAAiB,IAClC,KAAiB,KAAiB,IAClC,KAAqB,IAAI,GAAK,IAAgB,EAAc,GC1E9DE,KAAY,OAAO,gBACnBC,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAMD,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJE,MAAiB,GAAK,GAAK,MAAUD,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GAIhG,KAAb,MAA4B;CAC1B,YAAY,GAAW,GAAQ;EAQ7B,AAPA,GAAc,MAAM,SAAS,GAC7B,GAAc,MAAM,gBAAgB,GACpC,GAAc,MAAM,WAAW,GAC/B,GAAc,MAAM,QAAQ,GAC5B,KAAK,UAAU;GAAE,UAAU;GAAG,IAAI,GAAK,WAAW,CAAC;GAAG,UAAU;EAAE,GAClE,KAAK,iCAAiC,IAAI,IAAI,GAC9C,KAAK,YAAY,GACjB,KAAK,SAAS;CAChB;CACA,WAAW,GAAY;EACrB,IAAM,IAAQ,EAAW;EACzB,IAAI,KAAK,QAAQ,aAAa,EAAM,YAAY,KAAK,QAAQ,GAAG,UAAU,EAAM,EAAE,KAAK,KAAK,QAAQ,aAAa,EAAM,UACrH,MAAU,MACR,0BAA0B,EAAM,GAAG,SAAS,EAAE,GAAG,EAAM,SAAS,GAAG,EAAM,SAAS,uBAAuB,KAAK,QAAQ,GAAG,SAAS,EAAE,GAAG,KAAK,QAAQ,SAAS,GAAG,KAAK,QAAQ,UAC/K;EAEF,KAAK,IAAM,KAAgB,EAAW,eACpC,QAAQ,EAAa,MAArB;GACE,KAAK,gBAAgB;IACnB,IAAM,IAAY,KAAK,UAAU,EAAa,OAAO;IACrD,IAAI,GACF,KAAK,IAAM,KAAQ,EAAa,UAC9B,GAAe,KAAK,QAAQ,QAAQ,SAAS,GAAW,CAAI;IAGhE,IAAM,IAAQ,GAAa,EAAa,SAAS,IAAI;IACrD,KAAK,eAAe,IAAI,EAAa,SAAS;KAC5C,SAAS;KACT;KACA,UAAU,EAAa;IACzB,CAAC;IACD;GACF;GACA,KAAK,eAAe;IAClB,IAAM,IAAY,KAAK,UAAU,EAAa,OAAO;IACrD,IAAI,GACF,KAAK,IAAM,KAAQ,EAAa,UAC9B,GAAe,KAAK,QAAQ,QAAQ,SAAS,GAAW,CAAI;IAGhE,IAAM,EAAE,iBAAc;IACtB,KAAK,eAAe,IAAI,EAAa,SAAS;KAC5C,SAAS;KACT,cAAc,EAAa;KAC3B,WAAW,MAAc,KAAK,IAA8B,KAAK,IAA/B,GAAa,CAAS;KACxD,UAAU,EAAa;IACzB,CAAC;IACD;GACF;GACA,KAAK;IACH,KAAK,eAAe,OAAO,EAAa,OAAO;IAC/C;GAEF,SAEE,MAAU,MAAM,wBAAwB,EAAa,MAAM;EAE/D;EAEF,KAAK,UAAU,EAAW;CAC5B;CACA,qBAAqB;EACnB,OAAO,KAAK;CACd;CACA,YAAY;EACV,OAAO,KAAK,QAAQ;CACtB;AACF;;;ACzEA,SAAgB,GAAU,GAAS;CACjC,IAAM,IAAeE,GAAmB,CAAO;CAC/C,OAAO,GAAK,YAAY,MAAM,KAAK,CAAY,CAAC;AAClD;AACA,SAAgB,GAAU,GAAK;CAE7B,OAAOC,GAAqB,IADH,WAAW,EAAI,UAAU,CACtB,CAAY;AAC1C;AACA,SAAgB,GAAmB,GAAS;CAC1C,QAAQ,EAAQ,MAAhB;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,QACH,OAAO,EAAE,GAAG,EAAQ;EAEtB,KAAK,oBAID,OAHE,EAAQ,UACH;GAAE,GAAG;GAAS,IAAI,GAAU,EAAQ,EAAE;EAAE,IAExC,EAAE,GAAG,EAAQ;EAGxB,KAAK,cACH,OAAO;GACL,GAAG;GACH,cAAc;IACZ,GAAG,EAAQ;IACX,IAAI,GAAU,EAAQ,aAAa,EAAE;GACvC;GACA,YAAY;IACV,GAAG,EAAQ;IACX,IAAI,GAAU,EAAQ,WAAW,EAAE;GACrC;EACF;CAKJ;AAEF;AACA,SAAgB,GAAoB,GAAS;CAC3C,QAAQ,EAAQ,MAAhB;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO,EAAE,GAAG,EAAQ;EAEtB,KAAK,WAOD,OANE,EAAQ,yBAAyB,KAAK,IAMjC;GAAE,GAAG;GAAS,sBAAsB,KAAK;EAAE,IAL3C;GACL,GAAG;GACH,sBAAsB,GAAU,EAAQ,oBAAoB;EAC9D;CAQN;AAEF;;;ACrEA,IAAIC,KAAY,OAAO,gBACnBC,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAMD,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJE,KAAiB,GAAK,GAAK,MAAUD,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GAKvG,KAAe,KACf,KAAmB,MACnB,KAAkB,MAClB,KAAkB,MACpB;AACJ,SAAS,KAAkB;CAOzB,OANI,OAAc,KAAK,MACrB,KAAY,KAAK,IAAI,IAEnB,OAAO,cAAgB,OAAe,CAAC,YAAY,MAC9C,KAAK,IAAI,IAEX,KAAK,MAAM,KAAY,YAAY,IAAI,CAAC;AACjD;AACA,SAAS,KAAY;CACnB,OAAO,KAAK,KAAK,OAAO,GAAgB,IAAI,MAAa,GAAG,IAAI,GAAG;AACrE;AACA,IAAM,KAAyB;CAE7B,qBAAqB,EAAE,SAAS,IAAI;CAEpC,8BAA8B,EAAE,SAAS,IAAI;CAC7C,2BAA2B,EAAE,SAAS,IAAI;CAC1C,oBAAoB,EAAE,SAAS,IAAI;CACnC,6BAA6B,EAAE,SAAS,IAAI;CAC5C,kBAAkB,EAAE,SAAS,IAAI;CACjC,oBAAoB,EAAE,SAAS,IAAI;CACnC,gBAAgB,EAAE,SAAS,IAAI;CAE/B,0BAA0B,EAAE,SAAS,IAAI;CACzC,0BAA0B,EAAE,SAAS,IAAI;CACzC,2BAA2B,EAAE,SAAS,IAAI;CAE1C,qBAAqB,EAAE,SAAS,IAAI;CACpC,qBAAqB,EAAE,SAAS,IAAI;CACpC,2BAA2B,EAAE,SAAS,IAAI;AAC5C;AACA,SAAS,GAAwB,GAAG;CAClC,IAAI,MAAM,KAAK,GAAG,OAAO;CACzB,KAAK,IAAM,KAAU,OAAO,KAC1B,EACF,GACE,IAAI,EAAE,WAAW,CAAM,GACrB,OAAO;CAGX,OAAO;AACT;AACA,IAAa,KAAb,MAA8B;CAC5B,YAAY,GAAK,GAAW,GAAsB,GAAQ,GAA0B,GAAO;EA+CzF,AA9CA,KAAK,2BAA2B,GAChC,KAAK,QAAQ,GACb,EAAc,MAAM,QAAQ,GAC5B,EAAc,MAAM,iBAAiB,GACrC,EAAc,MAAM,qBAAqB,EAAK,GAC9C,EAAc,MAAM,iBAAiB,GAErC,EAAc,MAAM,yBAAyB,IAAI,GAEjD,EAAc,MAAM,uBAAuB,GAE3C,EAAc,MAAM,YAAY,GAEhC,EAAc,MAAM,SAAS,GAG7B,EAAc,MAAM,2BAA2B,GAC/C,EAAc,MAAM,uCAAuC,GAE3D,EAAc,MAAM,sBAAsB,IAAI,GAC9C,EAAc,MAAM,wBAAwB,IAAI,GAEhD,EAAc,MAAM,8BAA8B,IAAI,GACtD,EAAc,MAAM,KAAK,GACzB,EAAc,MAAM,QAAQ,GAC5B,EAAc,MAAM,UAAU,GAC9B,EAAc,MAAM,WAAW,GAC/B,EAAc,MAAM,sBAAsB,GAC1C,EAAc,MAAM,QAAQ,GAC5B,EAAc,MAAM,yBAAyB,GAC7C,KAAK,uBAAuB,GAC5B,KAAK,SAAS,EAAE,OAAO,eAAe,GACtC,KAAK,kBAAkB,GACvB,KAAK,kBAAkB,kBACvB,KAAK,wBAAwB,KAC7B,KAAK,aAAa,MAClB,KAAK,UAAU,GACf,KAAK,4BAA4B,KACjC,KAAK,wCAAwC,MAC7C,KAAK,MAAM,GACX,KAAK,SAAS,EAAU,QACxB,KAAK,WAAW,EAAU,UAC1B,KAAK,YAAY,EAAU,WAC3B,KAAK,0BAA0B,EAAU,yBACzC,KAAK,SAAS,GACd,KAAK,qBAAqB,GAC1B,KAAK,QAAQ;CACf;CACA,eAAe,GAAO;EAKpB,AAJA,KAAK,SAAS,GACd,KAAK,YACH,yBAAyB,KAAK,OAAO,MAAM,YAAY,YAAY,KAAK,SAAS,KAAK,OAAO,SAAS,KAAK,GAC7G,GACA,KAAK,yBAAyB;CAChC;CACA,uBAAuB;EACjB,OAAO,SAAW,OAAe,OAAO,OAAO,oBAAqB,cAGpE,KAAK,yBAAyB,SAGlC,KAAK,6BAA6B;GAEhC,AADA,KAAK,YAAY,+BAA+B,GAChD,KAAK,wBAAwB;EAC/B,GACA,OAAO,iBAAiB,UAAU,KAAK,oBAAoB,GAC3D,KAAK,YAAY,0CAA0C;CAC7D;CACA,yBAAyB;EACvB,AAAI,KAAK,wBAAwB,OAAO,SAAW,OAAe,OAAO,OAAO,uBAAwB,eACtG,OAAO,oBAAoB,UAAU,KAAK,oBAAoB,GAC9D,KAAK,uBAAuB,MAC5B,KAAK,YAAY,uCAAuC;CAE5D;CACA,mBAAmB,GAAO;EACxB,IAAI,EAAM,aAAa,KAAK,EAAM,cAAc,EAAM,cAAc,EAAM,eAAe,KAAK,KAAK,0BAA0B,KAAK,sBAAsB,eAAe,EAAM,cAAc,KAAK,sBAAsB,iBAAiB,EAAM,eAE3O,MADA,KAAK,wBAAwB,MACnB,MAAM,yBAAyB;EAS3C,IAPI,KAAK,0BAA0B,SACjC,KAAK,wBAAwB;GAC3B,QAAQ,CAAC;GACT,YAAY,EAAM;GAClB,cAAc,EAAM;EACtB,IAEE,EAAM,eAAe,KAAK,sBAAsB,OAAO,QAAQ;GACjE,IAAM,IAAiB,KAAK,sBAAsB,OAAO;GAEzD,MADA,KAAK,wBAAwB,MACnB,MACR,wDAAwD,EAAe,QAAQ,EAAM,YACvF;EACF;EAEA,IADA,KAAK,sBAAsB,OAAO,KAAK,EAAM,KAAK,GAC9C,KAAK,sBAAsB,OAAO,WAAW,EAAM,YAAY;GACjE,IAAM,IAAW,KAAK,sBAAsB,OAAO,KAAK,EAAE;GAC1D,KAAK,wBAAwB;GAC7B,IAAM,IAAa,GAAmB,KAAK,MAAM,CAAQ,CAAC;GAC1D,IAAI,EAAW,SAAS,cACtB,MAAU,MACR,4BAA4B,EAAW,KAAK,yBAC9C;GAEF,OAAO;EACT;EACA,OAAO;CACT;CACA,UAAU;EACR,IAAI,KAAK,OAAO,UAAU,cACxB;EAEF,IAAI,KAAK,OAAO,UAAU,kBAAkB,KAAK,OAAO,UAAU,WAChE,MAAU,MACR,sDAAsD,KAAK,OAAO,KACpE;EAEF,IAAM,IAAK,IAAI,KAAK,qBAAqB,KAAK,GAAG;EAiGjD,AAhGA,KAAK,YAAY,uBAAuB,GACxC,KAAK,eAAe;GAClB,OAAO;GACP;GACA,QAAQ;EACV,CAAC,GACD,KAAK,6BAA6B,GAClC,EAAG,eAAe;GAEhB,IADA,KAAK,OAAO,WAAW,iBAAiB,GACpC,KAAK,OAAO,UAAU,cACxB,MAAU,MAAM,mDAAmD;GA8BrE,IA5BA,KAAK,eAAe;IAClB,OAAO;IACP;IACA,QAAQ,KAAK,OAAO,WAAW,QAAQ,kBAAkB;GAC3D,CAAC,GACD,KAAK,6BAA6B,GAC9B,KAAK,OAAO,WAAW,SACzB,KAAK,oBAAoB,IACzB,KAAK,OAAO;IACV,iBAAiB,KAAK;IACtB,iBAAiB,KAAK;IACtB,UAAU,GAAgB;GAC5B,CAAC,IAEC,KAAK,oBAAoB,qBACvB,KAAK,kBACP,KAAK,OAAO,IACV,4BACA,GAAU,GACV,2BACA,KAAK,eACP,IAEA,KAAK,OAAO,IAAI,4BAA4B,GAAU,CAAC,IAG3D,KAAK,mBAAmB,GACxB,KAAK,kBAAkB,MACnB,KAAK,+BAA+B,MAAM;IAC5C,IAAM,EAAE,mBAAgB,KAAK;IAO7B,AANA,KAAK,6BAA6B,MAClC,KAAK,YAAY;KACf,MAAM;KACN,WAAW;KACX,OAAO,EAAE,eAAY;IACvB,CAAC,GACD,KAAK,OAAO,IACV,qCAAqC,KAAK,MAAM,IAAc,GAAG,EAAE,aACrE;GACF;EACF,GACA,EAAG,WAAW,MAAU;GACtB,KAAK,wBAAwB;GAC7B,IAAM,IAAU,EAAM;GACtB,AAAI,KACF,KAAK,OAAO,IAAI,4BAA4B,GAAS;EAEzD,GACA,EAAG,aAAa,MAAY;GAC1B,KAAK,6BAA6B;GAClC,IAAM,IAAgB,EAAQ,KAAK,QAC/B,IAAgB,GAAmB,KAAK,MAAM,EAAQ,IAAI,CAAC;GAC/D,SAAK,YAAY,iCAAiC,EAAc,MAAM,GAClE,EAAc,SAAS,QAG3B;QAAI,EAAc,SAAS,mBAAmB;KAC5C,IAAM,IAAa,KAAK,mBAAmB,CAAa;KACxD,IAAI,CAAC,GACH;KAGF,AADA,IAAgB,GAChB,KAAK,YACH,qCAAqC,EAAc,MACrD;IACF;IAcA,AAbI,KAAK,0BAA0B,SACjC,KAAK,wBAAwB,MAC7B,KAAK,OAAO,IACV,uBAAuB,EAAc,KAAK,kCAC5C,IAEE,EAAc,SAAS,gBACzB,KAAK,sBAAsB;KACzB;KACA,YAAY;IACd,CAAC,GAEc,KAAK,UAAU,CACrB,CAAC,CAAC,+BACX,KAAK,UAAU,GACf,KAAK,yBAAyB;GAhBhC;EAkBF,GACA,EAAG,WAAW,MAAU;GAMtB,IALA,KAAK,YAAY,kBAAkB,GACnC,KAAK,wBAAwB,MACzB,KAAK,oBAAoB,SAC3B,KAAK,kBAAkB,EAAM,UAAU,oBAAoB,EAAM,SAE/D,EAAM,SAAS,MAAgB,EAAM,SAAS,MAClD,EAAM,SAAS,MAAmB,EAAM,SAAS,IAAiB;IAChE,IAAI,IAAM,8BAA8B,EAAM;IAK9C,AAJI,EAAM,WACR,KAAO,KAAK,EAAM,WAEpB,KAAK,OAAO,IAAI,CAAG,GACf,KAAK,2BAA2B,EAAM,UACxC,KAAK,wBAAwB,CAAG;GAEpC;GACA,IAAM,IAAS,GAAwB,EAAM,MAAM;GACnD,KAAK,kBAAkB,CAAM;EAE/B;CACF;CAIA,cAAc;EACZ,OAAO,KAAK,OAAO;CACrB;CAKA,YAAY,GAAS;EACnB,IAAM,IAAgB;GACpB,MAAM,EAAQ;GACd,GAAG,EAAQ,SAAS,kBAAkB,EAAQ,cAAc,SAAS,EACnE,OAAO,MAAM,EAAQ,MAAM,MAAM,EAAE,IACrC,IAAI,CAAC;EACP;EACA,IAAI,KAAK,OAAO,UAAU,WAAW,KAAK,OAAO,WAAW,MAAM;GAChE,IAAM,IAAiB,GAAoB,CAAO,GAC5C,IAAU,KAAK,UAAU,CAAc,GACzC,IAAO;GACX,IAAI;IAEF,AADA,KAAK,OAAO,GAAG,KAAK,CAAO,GAC3B,IAAO;GACT,SAAS,GAAO;IAId,AAHA,KAAK,OAAO,IACV,sDAAsD,GACxD,GACA,KAAK,kBAAkB,qBAAqB;GAC9C;GAMA,OALA,KAAK,YACH,GAAG,IAAO,SAAS,iBAAiB,qBAAqB,EAAQ,KAAK,IAAI,KAAK,UAC7E,CACF,GACF,GACO;EACT;EAMA,OALA,KAAK,YACH,mCAAmC,KAAK,OAAO,MAAM,YAAY,YAAY,KAAK,SAAS,KAAK,OAAO,SAAS,KAAK,EAAE,KAAK,KAAK,UAC/H,CACF,GACF,GACO;CACT;CACA,+BAA+B;EACzB,KAAK,OAAO,UAAU,iBAGtB,KAAK,0CAA0C,SACjD,aAAa,KAAK,qCAAqC,GACvD,KAAK,wCAAwC,OAE/C,KAAK,wCAAwC,iBAAiB;GAC5D,KAAK,kBAAkB,gBAAgB;EACzC,GAAG,KAAK,yBAAyB;CACnC;CACA,kBAAkB,GAAQ;EAKxB,AAJA,AAEE,KAAK,wBADL,aAAa,KAAK,mBAAmB,OAAO,GAClB,OAE5B,KAAK,SAAS,EAAE,OAAO,eAAe;EACtC,IAAM,IAAU,KAAK,YAAY,CAAM;EAEvC,AADA,KAAK,yBAAyB,GAC9B,KAAK,OAAO,IAAI,2BAA2B,KAAK,MAAM,CAAO,EAAE,GAAG;EAClE,IAAM,IAAc,GAAgB,GAC9B,IAAY,iBAAiB;GACjC,AAAI,KAAK,oBAAoB,YAAY,MACvC,KAAK,qBAAqB,MAC1B,KAAK,QAAQ;EAEjB,GAAG,CAAO;EACV,KAAK,qBAAqB;GACxB,SAAS;GACT;GACA,WAAW;EACb;CACF;CAMA,kBAAkB,GAAa;EAE7B,QADA,KAAK,YAAY,uCAAuC,GAAa,GAC7D,KAAK,OAAO,OAApB;GACE,KAAK;GACL,KAAK;GACL,KAAK,WACH;GACF,KAAK;GACL,KAAK;IAGH,AAFA,KAAK,kBAAkB,GACvB,KAAU,MAAM,GAChB,KAAK,kBAAkB,QAAQ;IAC/B;GAEF,SACE,KAAK;EAET;CACF;CAQA,QAAQ;EAEN,QADA,KAAK,wBAAwB,MACrB,KAAK,OAAO,OAApB;GACE,KAAK;GACL,KAAK;GACL,KAAK,WACH,OAAO,QAAQ,QAAQ;GACzB,KAAK,cAAc;IACjB,IAAM,IAAK,KAAK,OAAO;IAIvB,OAHA,EAAG,aAAa,MAAa;KAC3B,KAAK,YAAY,uCAAuC;IAC1D,GACO,IAAI,SAAS,MAAM;KAKxB,AAJA,EAAG,gBAAgB;MAEjB,AADA,KAAK,YAAY,yBAAyB,GAC1C,EAAE;KACJ,GACA,EAAG,eAAe;MAEhB,AADA,KAAK,YAAY,yBAAyB,GAC1C,EAAG,MAAM;KACX;IACF,CAAC;GACH;GACA,KAAK,SAAS;IACZ,KAAK,YAAY,iBAAiB;IAClC,IAAM,IAAK,KAAK,OAAO;IACvB,EAAG,aAAa,MAAa;KAC3B,KAAK,YAAY,uCAAuC;IAC1D;IACA,IAAM,IAAS,IAAI,SAAS,MAAM;KAChC,EAAG,gBAAgB;MACjB,EAAE;KACJ;IACF,CAAC;IAED,OADA,EAAG,MAAM,GACF;GACT;GACA,SAEE,OADA,KAAK,QACE,QAAQ,QAAQ;EAE3B;CACF;CAKA,YAAY;EASV,QARI,KAAK,yCACP,aAAa,KAAK,qCAAqC,GAEzD,AAEE,KAAK,wBADL,aAAa,KAAK,mBAAmB,OAAO,GAClB,OAE5B,KAAK,uBAAuB,GACpB,KAAK,OAAO,OAApB;GACE,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,SAAS;IACZ,IAAM,IAAS,KAAK,MAAM;IAE1B,OADA,KAAK,eAAe,EAAE,OAAO,aAAa,CAAC,GACpC;GACT;GACA,SAEE,MADA,KAAK,QACK,MACR,4BAA4B,KAAK,OAAO,OAC1C;EAEJ;CACF;CACA,OAAO;EACL,QAAQ,KAAK,OAAO,OAApB;GACE,KAAK,cACH,OAAO,QAAQ,QAAQ;GACzB,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,SAAS;IACZ,KAAK,uBAAuB;IAC5B,IAAM,IAAS,KAAK,MAAM;IAE1B,OADA,KAAK,SAAS,EAAE,OAAO,UAAU,GAC1B;GACT;GACA,SAEE,OADA,KAAK,QACE,QAAQ,QAAQ;EAE3B;CACF;CAKA,aAAa;EACX,QAAQ,KAAK,OAAO,OAApB;GACE,KAAK,WACH;GACF,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;IACH,KAAK,OAAO,WAAW,uCAAuC;IAC9D;GACF,SACE,KAAK;EAET;EAEA,AADA,KAAK,qBAAqB,GAC1B,KAAK,QAAQ;CACf;CACA,QAAQ;EACN,QAAQ,KAAK,OAAO,OAApB;GACE,KAAK;GACL,KAAK;GACL,KAAK,cACH;GACF,KAAK;GACL,KAAK;IACH,KAAK,SAAS;KAAE,GAAG,KAAK;KAAQ,QAAQ;IAAM;IAC9C;GAEF;IACE,KAAK;IACL;EAEJ;CACF;CAMA,0BAA0B;EAExB,IADA,KAAK,YAAY,gCAAgC,GAC7C,KAAK,OAAO,UAAU,gBAAgB;GACxC,KAAK,YACH,sDAAsD,KAAK,OAAO,MAAM,kBAC1E;GACA;EACF;EACA,IAAI,IAAc;EAClB,IAAI,KAAK,oBAAoB;GAC3B,IAAM,IAAU,GAAgB,IAAI,KAAK,mBAAmB;GAO5D,AANA,IAAc,KAAK,IAAI,GAAG,KAAK,mBAAmB,YAAY,CAAO,GACrE,KAAK,YACH,qBAAqB,KAAK,MAAM,CAAW,EAAE,uBAAuB,KAAK,MAAM,KAAK,mBAAmB,SAAS,EAAE,cAAc,KAAK,MAAM,CAAO,EAAE,IACtJ,GACA,aAAa,KAAK,mBAAmB,OAAO,GAC5C,KAAK,qBAAqB,MAC1B,KAAK,YAAY,8BAA8B;EACjD;EAGA,AAFA,KAAK,OAAO,IAAI,qDAAqD,GACrE,KAAK,6BAA6B,MAAgB,OAAyB,OAAlB,EAAE,eAAY,GACvE,KAAK,QAAQ;CACf;CAIA,SAAS;EACP,QAAQ,KAAK,OAAO,OAApB;GACE,KAAK;IACH,KAAK,SAAS;KAAE,GAAG,KAAK;KAAQ,QAAQ;IAAK;IAC7C;GACF,KAAK;IACH,AAAI,KAAK,OAAO,WAAW,mBACzB,KAAK,SAAS;KAAE,GAAG,KAAK;KAAQ,QAAQ;IAAK,GAC7C,KAAK,oBAAoB,IACzB,KAAK,OAAO;KACV,iBAAiB,KAAK;KACtB,iBAAiB,KAAK;KACtB,UAAU,GAAgB;IAC5B,CAAC,KACQ,KAAK,OAAO,WAAW,UAChC,KAAK,SAAS;KAAE,GAAG,KAAK;KAAQ,QAAQ;IAAK,GAC7C,KAAK,SAAS;IAEhB;GACF,KAAK;GACL,KAAK;GACL,KAAK,gBACH;GACF,SACE,KAAK;EAET;EACA,KAAK,QAAQ;CACf;CACA,kBAAkB;EAChB,OAAO;GACL,aAAa,KAAK,OAAO,UAAU;GACnC,kBAAkB,KAAK;GACvB,iBAAiB,KAAK;GACtB,mBAAmB,KAAK;EAC1B;CACF;CACA,YAAY,GAAS;EACnB,KAAK,OAAO,WAAW,CAAO;CAChC;CACA,YAAY,GAAQ;EAElB,IAAM,KADiB,MAAW,WAAW,MAAM,MAAW,YAAY,KAAK,wBAAwB,GAAuB,EAAO,CAAC,WACxF,KAAG,KAAK;EACtD,KAAK,WAAW;EAChB,IAAM,IAAgB,KAAK,IAAI,GAAa,KAAK,UAAU;EAE3D,OAAO,IADQ,KAAiB,KAAK,OAAO,IAAI;CAElD;CACA,sBAAsB,EACpB,eACA,oBACC;EACD,IAAI,EAAW,oBAAoB,KAAK,KAAK,EAAW,aAAa,KAAK,GACxE;EAEF,IAAM,IAAwB,GAAgB,IAI9C,EAAW,kBAAkB,EAAW,WAAW,KAC7C,IAAuB,GAAG,KAAK,MAAM,CAAqB,EAAE,KAC5D,IAAkB,GAAG,KAAK,MAAM,IAAgB,GAAG,IAAI,IAAI,KAC3D,IAAiB,KAAiB,IAAwB,MAC1D,IAAuB,GAAG,KAAK,MAAM,IAAiB,GAAG,IAAI,IAAI;EAavE,AAZA,KAAK,YACH,YAAY,EAAgB,iBAAiB,EAAqB,MAAM,GAC1E,GACI,IAAgB,MAClB,KAAK,OAAO,IACV,mDAAmD,EAAgB,gEACrE,IACS,IAAwB,OACjC,KAAK,OAAO,IACV,mCAAmC,EAAgB,uCAAuC,EAAqB,EACjH,GAEE,KAAK,SACP,KAAK,YAAY;GACf,MAAM;GACN,WAAW;GACX,OAAO;IAAE;IAAuB;GAAc;EAChD,CAAC;CAEL;AACF;;;ACzoBA,SAAgB,KAAe;CAC7B,OAAO,GAAO;AAChB;AACA,SAAS,KAAS;CAChB,OAAO,uCAAuC,QAAQ,UAAU,MAAM;EACpE,IAAM,IAAI,KAAK,OAAO,IAAI,KAAK;EAC/B,QADsC,MAAM,MAAM,IAAI,IAAI,IAAI,EAAA,CACrD,SAAS,EAAE;CACtB,CAAC;AACH;;;ACRA,IAAa,KAAb,cAAuC,MAAM,CAC7C;AACA,GAAkB,UAAU,OAAO;AACnC,SAAS,GAAiB,GAAK;CAC7B,OAAO,mBACL,KAAK,CAAG,CAAC,CAAC,QAAQ,SAAS,GAAI,MAAM;EACnC,IAAI,IAAO,EAAE,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,YAAY;EAIpD,OAHI,EAAK,SAAS,MAChB,IAAO,MAAM,IAER,MAAM;CACf,CAAC,CACH;AACF;AACA,SAAS,GAAgB,GAAK;CAC5B,IAAI,IAAS,EAAI,QAAQ,MAAM,GAAG,CAAC,CAAC,QAAQ,MAAM,GAAG;CACrD,QAAQ,EAAO,SAAS,GAAxB;EACE,KAAK,GACH;EACF,KAAK;GACH,KAAU;GACV;EACF,KAAK;GACH,KAAU;GACV;EACF,SACE,MAAU,MAAM,4CAA4C;CAChE;CACA,IAAI;EACF,OAAO,GAAiB,CAAM;CAChC,QAAQ;EACN,OAAO,KAAK,CAAM;CACpB;AACF;AACA,SAAgB,GAAU,GAAO,GAAS;CACxC,IAAI,OAAO,KAAU,UACnB,MAAM,IAAI,GAAkB,2CAA2C;CAEzE,AAAY,MAAU,CAAC;CACvB,IAAM,IAAM,EAAQ,WAAW,KAAO,IAAI,GACpC,IAAO,EAAM,MAAM,GAAG,CAAC,CAAC;CAC9B,IAAI,OAAO,KAAS,UAClB,MAAM,IAAI,GACR,0CAA0C,IAAM,GAClD;CAEF,IAAI;CACJ,IAAI;EACF,IAAU,GAAgB,CAAI;CAChC,SAAS,GAAG;EACV,MAAM,IAAI,GACR,qDAAqD,IAAM,EAAE,IAAI,EAAE,QAAQ,EAC7E;CACF;CACA,IAAI;EACF,OAAO,KAAK,MAAM,CAAO;CAC3B,SAAS,GAAG;EACV,MAAM,IAAI,GACR,mDAAmD,IAAM,EAAE,IAAI,EAAE,QAAQ,EAC3E;CACF;AACF;;;AC7DA,IAAIE,KAAY,OAAO,gBACnBC,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAMD,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJE,KAAiB,GAAK,GAAK,MAAUD,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GAEvG,KAAwB,QACxB,KAAkC,GAC3B,KAAb,MAAmC;CACjC,YAAY,GAAW,GAAW,GAAQ;EA4BxC,AA3BA,EAAc,MAAM,aAAa,EAAE,OAAO,SAAS,CAAC,GAGpD,EAAc,MAAM,iBAAiB,CAAC,GAEtC,EAAc,MAAM,WAAW,GAE/B,EAAc,MAAM,cAAc,GAClC,EAAc,MAAM,YAAY,GAChC,EAAc,MAAM,kBAAkB,GACtC,EAAc,MAAM,aAAa,GACjC,EAAc,MAAM,cAAc,GAElC,EAAc,MAAM,WAAW,GAC/B,EAAc,MAAM,QAAQ,GAC5B,EAAc,MAAM,2BAA2B,GAG/C,EAAc,MAAM,6BAA6B,CAAC,GAClD,KAAK,YAAY,GACjB,KAAK,eAAe,EAAU,cAC9B,KAAK,aAAa,EAAU,YAC5B,KAAK,mBAAmB,EAAU,kBAClC,KAAK,cAAc,EAAU,aAC7B,KAAK,eAAe,EAAU,cAC9B,KAAK,YAAY,EAAU,WAC3B,KAAK,SAAS,EAAO,QACrB,KAAK,4BAA4B,EAAO;CAC1C;CACA,MAAM,UAAU,GAAY,GAAU;EAGpC,AAFA,KAAK,eAAe,GACpB,KAAK,YAAY,iCAAiC,GAClD,KAAK,YAAY;EACjB,IAAM,IAAQ,MAAM,KAAK,8BAA8B,GAAY,EACjE,mBAAmB,GACrB,CAAC;EACG,EAAM,yBAGN,EAAM,SACR,KAAK,aAAa;GAChB,OAAO;GACP,QAAQ;IAAE;IAAY,cAAc;GAAS;GAC7C,YAAY;EACd,CAAC,GACD,KAAK,aAAa,EAAM,KAAK,MAE7B,KAAK,aAAa;GAChB,OAAO;GACP,QAAQ;IAAE;IAAY,cAAc;GAAS;EAC/C,CAAC,GACD,MAAM,KAAK,aAAa,IAE1B,KAAK,YAAY,oCAAoC,GACrD,KAAK,aAAa;CACpB;CACA,aAAa,GAAe;EACrB,SAAK,UAAU,4BAClB,EAAc,WAAW,QAC3B,KAGI,IAAc,WAAW,YAAY,EAAc,aAAa,WAOpE;OAJA,KAAK,YACH,iBAAiB,KAAK,UAAU,MAAM,0BACxC,GACA,KAAK,UAAU,mBAAmB,GAC9B,KAAK,UAAU,UAAU,6CAA6C;IAGxE,AAFA,KAAK,YAAY,sCAAsC,GACvD,KAAU,aAAa,GACvB,KAAK,UAAU,OAAO,aAAa,EAAI;IACvC;GACF;GACA,AAAI,KAAK,UAAU,UAAU,+CAC3B,KAAK,YAAY,0CAA0C,GAC3D,KAAK,qBAAqB,KAAK,UAAU,KAAK,GAC9C,KAAK,4BAA4B,GAC5B,KAAK,UAAU,WAClB,KAAK,UAAU,OAAO,aAAa,EAAI;EAN3C;CASF;CACA,YAAY,GAAe;EACzB,IAAI,EAAc,wBAAwB,OAAU,KAAK,UAAU,UAAU,8CAA8C,KAAK,UAAU,UAAU,8CAA8C;GAChM,KAAK,YAAY,uCAAuC;GACxD;EACF;EACA,IAAM,EAAE,mBAAgB;EACxB,IAAI,CAAC,KAAK,UAAU,4BAA4B,IAAc,CAAC,GAAG;GAChE,KAAK,YAAY,+CAA+C;GAChE;EACF;EACA,KAAU,oBAAoB,CAAa;CAE7C;CAKA,MAAM,oBAAoB,GAAe;EAEvC,IADA,KAAK,YAAY,iCAAiC,EAAc,OAAO,GAGrE,KAAK,UAAU,UAAU,YAEzB,KAAK,UAAU,UAAU,8CAA8C,KAAK,6BAA6B,IACzG;GAOA,AANA,KAAK,OAAO,MACV,4BAA4B,EAAc,MAAM,iCAClD,GACI,KAAK,UAAU,QAAQ,KACzB,KAAK,UAAU,UAAU,GAEvB,KAAK,UAAU,UAAU,YAC3B,KAAK,uBAAuB,KAAK,UAAU,OAAO,YAAY;GAEhE;EACF;EAOA,AANI,KAAK,UAAU,UAAU,+CAC3B,KAAK,6BACL,KAAK,YACH,8BAA8B,KAAkC,KAAK,0BAA0B,oBACjG,IAEF,MAAM,KAAK,WAAW;EACtB,IAAM,IAAQ,MAAM,KAAK,8BACvB,KAAK,UAAU,OAAO,YACtB,EACE,mBAAmB,GACrB,CACF;EACI,EAAM,yBAGN,EAAM,SAAS,KAAK,UAAU,UAAU,EAAM,KAAK,KACrD,KAAK,aAAa,EAAM,KAAK,GAC7B,KAAK,aAAa;GAChB,OAAO;GACP,QAAQ,KAAK,UAAU;GACvB,OAAO,EAAM;GACb,SAAS,KAAK,UAAU,UAAU,mBAAmB,KAAK,UAAU,UAAU;EAChF,CAAC,MAED,KAAK,YAAY,sDAAsD,GACnE,KAAK,UAAU,QAAQ,KACzB,KAAK,UAAU,UAAU,GAE3B,KAAK,uBAAuB,KAAK,UAAU,OAAO,YAAY,IAEhE,KAAK,iBAAiB;CACxB;CAIA,MAAM,eAAe;EACnB,IAAI,KAAK,UAAU,UAAU,UAC3B;EAEF,KAAK,YAAY,uBAAuB;EACxC,IAAM,IAAQ,MAAM,KAAK,8BACvB,KAAK,UAAU,OAAO,YACtB,EACE,mBAAmB,GACrB,CACF;EACI,EAAM,yBAGN,EAAM,QACJ,KAAK,UAAU,UAAU,EAAM,KAAK,KACtC,KAAK,aAAa;GAChB,OAAO;GACP,SAAS,KAAK,UAAU,QAAQ;GAChC,OAAO,EAAM;GACb,QAAQ,KAAK,UAAU;EACzB,CAAC,GACD,KAAK,aAAa,EAAM,KAAK,KAE7B,KAAK,aAAa;GAChB,OAAO;GACP,QAAQ,KAAK,UAAU;EACzB,CAAC,KAGH,KAAK,YAAY,yBAAyB,GACtC,KAAK,UAAU,QAAQ,KACzB,KAAK,UAAU,GAEjB,KAAK,uBAAuB,KAAK,UAAU,OAAO,YAAY,IAEhE,KAAK,YACH,6DACF,GACA,KAAK,iBAAiB;CACxB;CACA,qBAAqB,GAAO;EAC1B,IAAI,KAAK,UAAU,UAAU,UAC3B;EAEF,IAAM,IAAe,KAAK,YAAY,CAAK;EAC3C,IAAI,CAAC,GAAc;GACjB,KAAK,OAAO,MACV,yDACF;GACA;EACF;EACA,IAAM,EAAE,QAAK,WAAQ;EACrB,IAAI,CAAC,KAAO,CAAC,GAAK;GAChB,KAAK,OAAO,MACV,oEACF;GACA;EACF;EACA,IAAM,IAAuB,IAAM;EACnC,IAAI,KAAwB,GAAG;GAC7B,KAAK,OAAO,MACV,gEACF;GACA;EACF;EACA,IAAI,IAAQ,KAAK,IACf,KACC,IAAuB,KAAK,6BAA6B,GAC5D;EACA,AAAI,KAAS,MACX,KAAK,OAAO,KACV,wDAAwD,KAAK,0BAA0B,wCAAwC,EAAqB,EACtJ,GACA,IAAQ;EAEV,IAAM,IAAwB,iBAAiB;GAE7C,AADA,KAAK,YAAY,iCAAiC,GAClD,KAAU,aAAa;EACzB,GAAG,CAAK;EAMR,AALA,KAAK,aAAa;GAChB,OAAO;GACP;GACA,QAAQ,KAAK,UAAU;EACzB,CAAC,GACD,KAAK,YACH,iDAAiD,EAAM,GACzD;CACF;CAGA,MAAM,8BAA8B,GAAY,GAAW;EACzD,IAAM,IAAwB,EAAE,KAAK;EACrC,KAAK,YACH,sCAAsC,GACxC;EACA,IAAM,IAAQ,MAAM,EAAW,CAAS;EAOxC,OANI,KAAK,kBAAkB,IAMpB;GAAE,sBAAsB;GAAO,OAAO;EAAM,KALjD,KAAK,YACH,kCAAkC,EAAsB,QAAQ,KAAK,eACvE,GACO,EAAE,sBAAsB,GAAK;CAGxC;CACA,OAAO;EAGL,AAFA,KAAK,eAAe,GACpB,KAAK,iBACL,KAAK,YAAY,4BAA4B,KAAK,eAAe;CACnE;CACA,uBAAuB,GAAc;EAEnC,AADA,EAAa,EAAK,GAClB,KAAK,eAAe;CACtB;CACA,iBAAiB;EACf,KAAK,aAAa,EAAE,OAAO,SAAS,CAAC;CACvC;CACA,aAAa,GAAS;EACpB,IAAM,IAAkB,EAAQ,UAAU,6CAA6C;GACrF,SAAS,EAAQ;GACjB,OAAO,EAAQ;GACf,OAAO,MAAM,EAAQ,MAAM,MAAM,EAAE;EACrC,IAAI,EAAE,OAAO,EAAQ,MAAM;EAI3B,QAHA,KAAK,YACH,yBAAyB,KAAK,UAAU,CAAe,GACzD,GACQ,EAAQ,OAAhB;GACE,KAAK;GACL,KAAK;GACL,KAAK,UACH,KAAK,4BAA4B;EASrC;EAIA,AAHI,KAAK,UAAU,UAAU,gCAC3B,aAAa,KAAK,UAAU,qBAAqB,GAEnD,KAAK,YAAY;CACnB;CACA,YAAY,GAAO;EACjB,IAAI;GACF,OAAO,GAAU,CAAK;EACxB,SAAS,GAAG;GAIV,OAHA,KAAK,YACH,yBAAyB,aAAa,QAAQ,EAAE,UAAU,iBAC5D,GACO;EACT;CACF;CACA,YAAY,GAAS;EACnB,KAAK,OAAO,WAAW,GAAG,EAAQ,KAAK,KAAK,cAAc,EAAE;CAC9D;AACF,GClUM,KAAY;CAChB;CACA;CACA;AACF;AACA,SAAgB,GAAK,GAAM,GAAW;CACpC,IAAM,IAAS,EAAE,aAAU;CACvB,OAAO,cAAgB,OAAe,CAAC,YAAY,QACvD,YAAY,KAAK,GAAM,EAAE,UAAO,CAAC;AACnC;AACA,SAAS,GAAsB,GAAO;CACpC,IAAI,IAAO,EAAM,KAAK,MAAM,CAAe;CAE3C,OADA,IAAO,EAAK,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,EAAK,MAAM,CAAC,GAC3C;EACL;EACA,WAAW,EAAM;CACnB;AACF;AACA,SAAgB,GAAe,GAAW;CACxC,IAAI,OAAO,cAAgB,OAAe,CAAC,YAAY,kBACrD,OAAO,CAAC;CAEV,IAAM,IAAW,CAAC;CAClB,KAAK,IAAM,KAAQ,IAAW;EAC5B,IAAM,IAAQ,YAAY,iBAAiB,CAAI,CAAC,CAAC,QAAQ,MAAU,EAAM,cAAc,MAAM,CAAC,CAAC,QAAQ,MAAU,EAAM,OAAO,cAAc,CAAS;EACrJ,EAAS,KAAK,GAAG,CAAK;CACxB;CACA,OAAO,EAAS,IAAI,EAAqB;AAC3C;;;AC5BA,IAAIE,KAAY,OAAO,gBACnBC,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAMD,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJE,KAAiB,GAAK,GAAK,MAAUD,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GA0BhG,KAAb,MAA8B;CAS5B,YAAY,GAAS,GAAc,GAAS;EAwC1C,IAvCA,EAAc,MAAM,SAAS,GAC7B,EAAc,MAAM,OAAO,GAC3B,EAAc,MAAM,gBAAgB,GACpC,EAAc,MAAM,kBAAkB,GACtC,EAAc,MAAM,uBAAuB,GAC3C,EAAc,MAAM,gBAAgB,GACpC,EAAc,MAAM,wBAAwB,GAC5C,EAAc,MAAM,6BAA6B,CAAC,GAClD,EAAc,MAAM,gBAAgB,GACpC,EAAc,MAAM,oCAAoC,IAAI,IAAI,CAAC,GACjE,EAAc,MAAM,YAAY,GAChC,EAAc,MAAM,wBAAwB,EAAK,GACjD,EAAc,MAAM,OAAO,GAC3B,EAAc,MAAM,QAAQ,GAC5B,EAAc,MAAM,sBAAsB,GAC1C,EAAc,MAAM,8CAA8C,IAAI,IAAI,CAAC,GAC3E,EAAc,MAAM,mCAAmC,CAAC,GACxD,EAAc,MAAM,+BAA+B,GAKnD,EAAc,MAAM,kCAAkC;GACpD,QAAa,QAAQ,CAAC,CAAC,WAAW;IAChC,IAAM,IAAqB,KAAK,gBAAgB;IAChD,IAAI,KAAK,UAAU,CAAkB,MAAM,KAAK,UAAU,KAAK,6BAA6B,GAAG;KAC7F,KAAK,gCAAgC;KACrC,KAAK,IAAM,KAAM,KAAK,2BAA2B,OAAO,GACtD,EAAG,CAAkB;IAEzB;GACF,CAAC;EACH,CAAC,GAED,EAAc,MAAM,SAAS,MAAS;GACpC,AAAI,KAAK,SACP,GAAK,GAAM,KAAK,SAAS;EAE7B,CAAC,GACG,OAAO,KAAY,UACrB,MAAU,MACR,mHACF;EAKF,AAHI,GAAS,iCAAiC,MAC5C,GAAsB,CAAO,GAE/B,IAAU,EAAE,GAAG,EAAQ;EACvB,IAAM,IAAgC,EAAQ,iCAAiC,IAC3E,IAAuB,EAAQ;EACnC,IAAI,CAAC,KAAwB,OAAO,YAAc,KAChD,MAAU,MACR,2KACF;EAKF,AAHA,MAA+C,WAC/C,KAAK,QAAQ,EAAQ,2BAA2B,IAChD,KAAK,UAAU,GACf,KAAK,SAAS,EAAQ,WAAW,KAAQ,GAAsB,EAAE,SAAS,EAAQ,WAAW,GAAM,CAAC,IAAI,EAAQ,WAAW,MAAQ,EAAQ,SAAS,EAAQ,SAAS,GAAyB,EAAE,SAAS,EAAQ,WAAW,GAAM,CAAC;EACnO,IAAM,IAAI,EAAQ,OAAO,KAAK;EAC9B,IAAI,MAAM,IACR,MAAU,MAAM,2CAA2C;EAE7D,IAAM,IAAS,EAAQ,UAAU,IAAI,CAAC,GAChC,IAAW,EAAQ,UAAU,GAAG,CAAC,GACnC;EACJ,IAAI,MAAa,QACf,IAAa;OACR,IAAI,MAAa,SACtB,IAAa;OAEb,MAAU,MAAM,2BAA2B,GAAU;EAEvD,IAAM,IAAQ,GAAG,EAAW,KAAK,EAAO,OAAO,GAAQ;EAMvD,AALA,KAAK,QAAQ,IAAI,GAAe,GAChC,KAAK,iBAAiB,IAAI,IACvB,MAAY,KAAK,MAAM,UAAU,CAAO,GACzC,KAAK,MACP,GACA,KAAK,iBAAiB,IAAI,GACxB,KAAK,QACL,KAAK,wBACP;EACA,IAAM,UAAoB;GAExB,AADA,KAAK,iBAAiB,MAAM,GAC5B,KAAK,MAAM,MAAM;EACnB;EA2BA,AA1BA,KAAK,wBAAwB,IAAI,GAC/B,KAAK,OACL;GACE,eAAe,MAAU;IACvB,IAAM,IAAU,KAAK,MAAM,QAAQ,CAAK;IAExC,OADA,KAAK,iBAAiB,YAAY,CAAO,GAClC,EAAQ;GACjB;GACA,kBAAkB,KAAK,iBAAiB,KAAK;GAC7C,wBAAwB,KAAK,iBAAiB,WAAW;GACzD;GACA,oBAAoB,KAAK,iBAAiB,OAAO;GACjD,iBAAiB;IACf,KAAK,UAAU;GACjB;EACF,GACA;GACE,QAAQ,KAAK;GACb,2BAA2B;EAC7B,CACF,GACA,KAAK,yBAAyB,IAAI,GAAuB,GACzD,KAAK,wBAAwB,MAAe;GAC1C,EAAa,EAAW,QAAQ,KAAK,MAAM,EAAE,KAAK,CAAC;EACrD,CAAC,GACD,KAAK,iBAAiB,GACtB,KAAK,aAAa,GAAa;EAC/B,IAAM,EAAE,6BAA0B;EAClC,IAAI,OAAO,SAAW,OAAsB,OAAO,qBAAqB,QAClE;OAAA,MAA0B,IAC5B,MAAU,MACR,0IACF;EAAA,OAEG,AAAI,MAA0B,MACnC,OAAO,iBAAiB,iBAAiB,MAAM;GAC7C,IAAI,KAAK,eAAe,sBAAsB,GAAG;IAC/C,EAAE,eAAe;IACjB,IAAM,IAAsB;IAE5B,OADA,CAAC,KAAK,OAAO,MAAA,CAAO,cAAc,GAC3B;GACT;EACF,CAAC;EAsGH,AApGA,KAAK,mBAAmB,IAAI,GAC1B,GACA;GACE,SAAS,MAAsB;IAQ7B,AAPA,KAAK,KAAK,qBAAqB,GAC/B,KAAK,iBAAiB,YAAY;KAChC,GAAG;KACH,MAAM;KACN,WAAW,KAAK;KAChB,sBAAsB,KAAK;IAC7B,CAAC,GACD,KAAK,iBAAiB,IAAI,IACvB,MAAY,KAAK,MAAM,UAAU,CAAO,GACzC,KAAK,MACP;IACA,IAAM,CAAC,GAAsB,KAAoB,KAAK,MAAM,QAAQ;IAIpE,AAHI,KACF,KAAK,iBAAiB,YAAY,CAAgB,GAEpD,KAAK,iBAAiB,YAAY,CAAoB;IACtD,KAAK,IAAM,KAAW,KAAK,eAAe,QAAQ,GAChD,KAAK,iBAAiB,YAAY,CAAO;GAE7C;GACA,gBAAgB;IACd,IAAM,CAAC,GAAsB,KAAoB,KAAK,MAAM,OAAO;IAInE,AAHI,KACF,KAAK,iBAAiB,YAAY,CAAgB,GAEhD,KACF,KAAK,iBAAiB,YAAY,CAAoB;IAExD,KAAK,IAAM,KAAW,KAAK,eAAe,OAAO,GAC/C,KAAK,iBAAiB,YAAY,CAAO;GAE7C;GACA,YAAY,MAAkB;IAM5B,QALK,KAAK,yBACR,KAAK,uBAAuB,IAC5B,KAAK,KAAK,4BAA4B,GACtC,KAAK,YAAY,IAEX,EAAc,MAAtB;KACE,KAAK,cAAc;MAIjB,AAHA,KAAK,kBAAkB,EAAc,WAAW,EAAE,GAClD,KAAK,sBAAsB,aAAa,CAAa,GACrD,KAAK,eAAe,WAAW,CAAa,GAC5C,KAAK,MAAM,WAAW,CAAa;MACnC,IAAM,IAAoB,KAAK,eAAe,gBAC5C,KAAK,eAAe,UAAU,CAChC;MACA,KAAK,2BAA2B,CAAiB;MACjD;KACF;KACA,KAAK,oBAAoB;MACvB,AAAI,EAAc,WAChB,KAAK,kBAAkB,EAAc,EAAE;MAEzC,IAAM,IAAwB,KAAK,eAAe,WAAW,CAAa;MAC1E,AAAI,MAA0B,QAC5B,KAAK,2CACa,IAAI,IAAI,CACtB,CACE,EAAsB,WACtB,EAAsB,MACxB,CACF,CAAC,CACH;MAEF;KACF;KACA,KAAK;MACH,KAAK,eAAe,WAAW,CAAa;MAC5C;KAEF,KAAK;MACH,KAAK,sBAAsB,YAAY,CAAa;MACpD;KAEF,KAAK,cAAc;MACjB,IAAM,IAAQ,GAAc,KAAK,QAAQ,EAAc,KAAK;MAE5D,MADA,KAAU,iBAAiB,UAAU,GAC/B;KACR;IAIF;IACA,OAAO,EACL,4BAA4B,KAAK,2BAA2B,EAC9D;GACF;GACA,yBAAyB,EAAQ;EACnC,GACA,GACA,KAAK,QACL,KAAK,0BACL,KAAK,KACP,GACA,KAAK,KAAK,yBAAyB,GAC/B,EAAQ,cACV,EAAY;CAEhB;CAMA,6BAA6B;EAE3B,OADmC,KAAK,eAAe,2BAA2B,KAAK,KAAK,MAAM,2BAA2B;CAE/H;CACA,kBAAkB,GAAY;EAC5B,CAAI,KAAK,yBAAyB,KAAK,KAAK,KAAK,qBAAqB,gBAAgB,CAAU,OAC9F,KAAK,uBAAuB;CAEhC;CACA,0BAA0B;EACxB,OAAO,KAAK;CACd;CASA,2BAA2B,GAAmB;EAC5C,IAAM,IAAqB,KAAK,eAAe,mBAAmB,GAC5D,oBAAoC,IAAI,IAAI;EAClD,KAAK,IAAM,CAAC,GAAS,MAAW,GAAoB;GAClD,IAAM,IAAa,KAAK,MAAM,WAAW,CAAO;GAChD,IAAI,MAAe,MAAM;IACvB,IAAM,IAAQ;KACZ;KACA,SAAS,KAAK,MAAM,UAAU,CAAO;KACrC,MAAM,KAAK,MAAM,UAAU,CAAO;IACpC;IACA,EAAkB,IAAI,GAAY,CAAK;GACzC;EACF;EACA,IAAM,IAAqB,KAAK,uBAAuB,6BACrD,GACA,IAAI,IAAI,EAAkB,KAAK,CAAC,CAClC;EACA,KAAK,iBAAiB;GACpB,SAAS,EAAmB,KAAK,OAExB;IACL;IACA,cAAc;KACZ,MAAM;KACN,QALqB,KAAK,uBAAuB,eAAe,CAKzC;IACzB;GACF,EACD;GACD,oBAAoB,MAAM,KAAK,CAAiB,CAAC,CAAC,KAC/C,CAAC,GAAW,QAAa;IACxB;IACA;GACF,EACF;GACA,WAAW,KAAK,eAAe,UAAU;EAC3C,CAAC;CACH;CACA,iBAAiB,GAAY;EAC3B,KAAK,IAAM,KAAM,KAAK,iBAAiB,OAAO,GAC5C,EAAG,CAAU;CAEjB;CAUA,uBAAuB,GAAI;EACzB,IAAM,IAAK,KAAK;EAEhB,OADA,KAAK,iBAAiB,IAAI,GAAI,CAAE,SACnB,KAAK,iBAAiB,OAAO,CAAE;CAC9C;CAIA,uBAAuB;EACrB,IAAM,IAAY,KAAK,MAAM,QAAQ,GACjC,IAAU,CAAC;EACf,IAAI,KAAa,EAAU,cAAc,QACvC,IAAI;GACF,IAAU,IAAY,GAAU,EAAU,KAAK,IAAI,CAAC;EACtD,QAAQ;GACN,IAAU,CAAC;EACb;OAEA;EAEF,OAAO;GAAE,OAAO,EAAU;GAAO;EAAQ;CAC3C;CASA,QAAQ,GAAY,GAAU;EAC5B,KAAU,sBAAsB,UAAU,GAAY,CAAQ;CAChE;CACA,UAAU;EACR,OAAO,KAAK,MAAM,QAAQ;CAC5B;CAEA,aAAa,GAAO,GAAkB;EACpC,IAAM,IAAU,KAAK,MAAM,aAAa,GAAO,CAAgB;EAC/D,KAAK,iBAAiB,YAAY,CAAO;CAC3C;CACA,YAAY;EACV,IAAM,IAAU,KAAK,MAAM,UAAU;EACrC,KAAK,iBAAiB,YAAY,CAAO;CAC3C;CAeA,UAAU,GAAM,GAAM,GAAS;EAC7B,IAAM,IAAa,GAAU,CAAI,GAC3B,EAAE,iBAAc,eAAY,mBAAgB,KAAK,MAAM,UAC3D,GACA,GACA,GAAS,SACT,GAAS,aACX;EAIA,OAHI,MAAiB,QACnB,KAAK,iBAAiB,YAAY,CAAY,GAEzC;GACL;GACA,mBAAmB;IACjB,IAAM,IAAgB,EAAY;IAClC,AAAI,KACF,KAAK,iBAAiB,YAAY,CAAa;GAEnD;EACF;CACF;CAOA,iBAAiB,GAAS,GAAM;EAE9B,IAAM,IAAa,GAAqB,GADrB,GAAU,CACoB,CAAU;EAC3D,OAAO,KAAK,uBAAuB,YAAY,CAAU;CAC3D;CASA,wBAAwB,GAAY;EAClC,OAAO,KAAK,uBAAuB,YAAY,CAAU;CAC3D;CAQA,2BAA2B,GAAY;EACrC,OAAO,KAAK,uBAAuB,eAAe,CAAU;CAC9D;CAIA,eAAe,GAAS,GAAM;EAE5B,IAAM,IAAa,GAAqB,GADrB,GAAU,CACoB,CAAU;EAC3D,OAAO,KAAK,uBAAuB,UAAU,CAAU;CACzD;CAUA,aAAa,GAAM,GAAM;EAEvB,IAAM,IAAa,GAAqB,GADrB,GAAU,CACiB,CAAU;EACxD,OAAO,KAAK,MAAM,aAAa,CAAU;CAC3C;CAOA,kBAAkB;EAChB,IAAM,IAAoB,KAAK,iBAAiB,gBAAgB;EAChE,OAAO;GACL,qBAAqB,KAAK,eAAe,oBAAoB;GAC7D,sBAAsB,EAAkB;GACxC,kBAAkB,EAAkB;GACpC,iBAAiB,EAAkB;GACnC,mBAAmB,EAAkB;GACrC,6BAA6B,KAAK,eAAe,4BAA4B;GAC7E,mBAAmB,KAAK,eAAe,kBAAkB;GACzD,iBAAiB,KAAK,eAAe,gBAAgB;EACvD;CACF;CAWA,2BAA2B,GAAI;EAC7B,IAAM,IAAK,KAAK;EAEhB,OADA,KAAK,2BAA2B,IAAI,GAAI,CAAE,SAC7B;GACX,KAAK,2BAA2B,OAAO,CAAE;EAC3C;CACF;CAWA,MAAM,SAAS,GAAM,GAAM,GAAS;EAClC,IAAM,IAAS,MAAM,KAAK,iBAAiB,GAAM,GAAM,CAAO;EAC9D,IAAI,CAAC,EAAO,SASV,MARI,EAAO,cAAc,KAAK,IAQpB,MAAM,GAA4B,YAAY,GAAM,CAAM,CAAC,IAP7D,GACJ,GACA,IAAI,GACF,GAA4B,YAAY,GAAM,CAAM,CACtD,CACF;EAIJ,OAAO,EAAO;CAChB;CAIA,MAAM,iBAAiB,GAAS,GAAM,GAAS,GAAe;EAC5D,IAAM,EAAE,uBAAoB,KAAK,gBAC/B,GACA,GACA,GACA,CACF;EACA,OAAO;CACT;CAIA,gBAAgB,GAAS,GAAM,GAAS,GAAe;EACrD,IAAM,IAAe,GAAU,CAAI;EACnC,KAAK,wBAAwB;EAC7B,IAAM,IAAY,KAAK;EAEvB,IADA,KAAK,kBACD,MAAY,KAAK,GAAG;GACtB,IAAM,IAAmB,EAAQ;GACjC,IAAI,MAAqB,KAAK,GAAG;IAgB/B,IAAM,IAJqB,KAAK,uBAAuB,uBAXhC,MAAoB;KAKzC,AAJe,EACb,GACA,CAEO,aAAa,WACpB,KAAK,OAAO,KACV,yFACF;IAEJ,GAGE,CAEsC,CAAC,CAAC,KAAK,MAAU;KACvD,IAAM,IAAc,KAAK,wBAAwB,CAAK;KACtD,OAAO;MACL;MACA,cAAc;OACZ,MAAM;OACN,QAAQ,MAAgB,KAAK,IAAI,KAAK,IAAI;QACxC,SAAS;QACT,OAAO;QACP,UAAU,CAAC;OACb;MACF;KACF;IACF,CAAC;IACD,KAAK,iBAAiB;KACpB,SAAS;KACT,oBAAoB,CAAC;KACrB,WAAW,KAAK,eAAe,UAAU;IAC3C,CAAC;GACH;EACF;EACA,IAAM,IAAU;GACd,MAAM;GACN;GACA;GACA;GACA,MAAM,CAAC,GAAa,CAAY,CAAC;EACnC,GACM,IAAc,KAAK,iBAAiB,YAAY,CAAO;EAE7D,OAAO;GACL;GACA,iBAHsB,KAAK,eAAe,QAAQ,GAAS,CAG7C;EAChB;CACF;CASA,MAAM,OAAO,GAAM,GAAM;EACvB,IAAM,IAAS,MAAM,KAAK,eAAe,GAAM,CAAI;EACnD,IAAI,CAAC,EAAO,SAOV,MANI,EAAO,cAAc,KAAK,IAMpB,MAAM,GAA4B,UAAU,GAAM,CAAM,CAAC,IAL3D,GACJ,GACA,IAAI,GAAY,GAA4B,UAAU,GAAM,CAAM,CAAC,CACrE;EAIJ,OAAO,EAAO;CAChB;CAIA,MAAM,eAAe,GAAS,GAAM,GAAe;EACjD,IAAM,IAAa,GAAU,CAAI,GAC3B,IAAY,KAAK;EAEvB,AADA,KAAK,kBACL,KAAK,wBAAwB;EAC7B,IAAM,IAAU;GACd,MAAM;GACN;GACA;GACA;GACA,MAAM,CAAC,GAAa,CAAU,CAAC;EACjC,GACM,IAAc,KAAK,iBAAiB,YAAY,CAAO;EAC7D,OAAO,KAAK,eAAe,QAAQ,GAAS,CAAW;CACzD;CASA,MAAM,QAAQ;EAEZ,OADA,KAAK,sBAAsB,KAAK,GACzB,KAAK,iBAAiB,UAAU;CACzC;CAOA,IAAI,MAAM;EACR,OAAO,KAAK;CACd;CAIA,IAAI,gBAAgB;EAClB,OAAO,KAAK;CACd;CAIA,IAAI,YAAY;EACd,OAAO,KAAK;CACd;CAKA,cAAc;EACZ,IAAI,KAAK,OAAO;GACd,IAAM,IAAS,GAAe,KAAK,SAAS;GAC5C,KAAK,iBAAiB,YAAY;IAChC,MAAM;IACN,WAAW;IACX,OAAO;GACT,CAAC;EACH;CACF;CACA,0BAA0B;EACxB,IAAI,CAAC,KAAK,OACR;EAEF,IAAM,IAAsB,KAAK,gBAAgB,CAAC,CAAC;EACnD,IAAI,MAAwB,QAAQ,KAAK,IAAI,IAAI,EAAoB,QAAQ,KAAK,KAChF;EAEF,IAAM,IAAW,GAAG,KAAK,QAAQ;EACjC,MAAM,GAAU;GACd,QAAQ;GACR,SAAS;IACP,gBAAgB;IAChB,iBAAiB,OAAO;GAC1B;GACA,MAAM,KAAK,UAAU,EAAE,OAAO,0BAA0B,CAAC;EAC3D,CAAC,CAAC,CAAC,MAAM,MAAa;GACpB,AAAK,EAAS,MACZ,KAAK,OAAO,KACV,2CACA,EAAS,IACX;EAEJ,CAAC,CAAC,CAAC,OAAO,MAAU;GAClB,KAAK,OAAO,KAAK,yCAAyC,CAAK;EACjE,CAAC;CACH;AACF;;;ACrtBA,SAAgB,GAAmB,GAAO;CACxC,IAAI,OAAO,KAAU,aAAY,KAAkB,CAAC,MAAM,QAAQ,EAAM,IAAI,KAAK,OAAO,EAAM,UAAW,aAAa,OAAO,EAAM,kBAAmB,UACpJ,MAAU,MAAM,uCAAuC,GAAO,SAAS,GAAG;CAE5E,OAAO;AACT;;;ACXA,IAAIE,KAAY,OAAO,gBACnBC,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAMD,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJE,MAAiB,GAAK,GAAK,MAAUD,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GAShG,KAAb,MAAkC;CAChC,YAAY,GAAQ,GAAc;EAOhC,AANA,KAAK,SAAS,GACd,KAAK,eAAe,GACpB,GAAc,MAAM,qCAAqC,IAAI,IAAI,CAAC,GAElE,GAAc,MAAM,kBAAkB,GACtC,KAAK,mBAAmB,GAAK,WAAW,CAAC,GACzC,KAAK,OAAO,wBACT,MAAe,KAAK,iBAAiB,CAAU,CAClD;CACF;CASA,UAAU,GAAM,GAAM,GAAS;EAC7B,IAAM,IAAuB,GAAoB,CAAI,GAC/C,IAAQ,GACZ,GACA,GACA,CACF,GACM,UAAoB,KAAK,+BAA+B,CAAK,GAC7D,IAAgB,KAAK,kBAAkB,IAAI,CAAK;EAsBtD,OArBI,KACF,EAAc,kBAAkB,GACzB;GACL,qBAAqB;GACrB;EACF,MAEF,KAAK,kBAAkB,IAAI,GAAO;GAChC;GACA;GACA;GACA,gBAAgB;GAChB,SAAS,EAAE,iBAAiB,EAAQ,gBAAgB;GACpD,aAAa;GACb,UAAU,CAAC;GACX,gCAAgC,IAAI,IAAI;GACxC,+BAA+B,IAAI,IAAI;GACvC,MAAM;GACN,IAAI,EAAQ;EACd,CAAC,GACD,KAAK,wBAAwB,GAAO,MAAM,EAAQ,eAAe,GAC1D;GACL,qBAAqB;GACrB;EACF;CACF;CAMA,iBAAiB,GAAM,GAAM,GAAS;EAEpC,IAAM,IAAQ,GADe,GAAoB,CAE/C,GACA,GACA,CACF;EACA,OAAO,KAAK,wBAAwB,CAAK;CAC3C;CAIA,wBAAwB,GAAO;EAC7B,IAAM,IAAiB,KAAK,kBAAkB,IAAI,CAAK;EACvD,IAAI,CAAC,GACH;EAEF,IAAM,IAAc,KAAK,sBAAsB,CAAc;EAC7D,IAAI,EAAY,WAAW,GACzB,OAAO;GACL,SAAS,CAAC;GACV,QAAQ;GACR,WAAW,MACF,KAAK,yBAAyB,GAAO,CAAQ;EAExD;EAEF,IAAI,IAAa,CAAC,GACd,IAAe,IACf,IAAS;EACb,KAAK,IAAM,KAAa,GAAa;GACnC,IAAM,IAAS,KAAK,OAAO,wBAAwB,CAAS;GAC5D,IAAI,MAAW,KAAK,GAAG;IAErB,AADA,IAAe,IACf,IAAS;IACT;GACF;GACA,IAAM,IAAmB,GAAmB,CAAM;GAElD,AADA,IAAa,EAAW,OAAO,EAAiB,IAAI,GACpD,IAAS,CAAC,CAAC,EAAiB;EAC9B;EACA,IAAI;EAQJ,OAPA,AAKE,IALE,IACO,EAAW,WAAW,IAAI,qBAAqB,gBAC/C,IACA,cAEA,eAEJ;GACL,SAAS;GACT;GACA,WAAW,MACF,KAAK,yBAAyB,GAAO,CAAQ;EAExD;CACF;CACA,iBAAiB,GAAY;EAC3B,IAAM,IAAoB,EAAW,QAAQ,KAAK,MAAM,EAAE,KAAK,GACzD,IAAU,KAAK,wBAAwB,CAAiB,GAC1D,IAAmB,CAAC;EACxB,AAAI,EAAQ,SAAS,MACnB,KAAK,4BACH,IACC,MAAU,KAAK,OAAO,wBAAwB,CAAK,CACtD,GACA,IAAmB,EAAQ,KAAK,OAAW;GACzC;GACA,cAAc;IACZ,MAAM;IACN,QAAQ,KAAK,wBAAwB,CAAK;GAC5C;EACF,EAAE;EAEJ,IAAM,IAAqB;GACzB,GAAG;GACH;EACF;EACA,KAAK,aAAa,CAAkB;CACtC;CAYA,yBAAyB,GAAO,GAAU;EACxC,KAAK,sBAAsB,CAAK;EAChC,IAAM,IAAgB,KAAK,sCAAsC,CAAK,GAChE,IAAiB,KAAK,OAAO,wBAAwB,CAAa;EACxE,IAAI,CAAC,GACH,OAAO;EAET,IAAM,IAAmB,GAAmB,CAAc;EAC1D,IAAI,EAAiB,QACnB,OAAO;EAET,KAAK,wBACH,GACA,EAAiB,gBACjB,CACF;EACA,IAAM,IAAqB;GACzB,WAAW,KAAK;GAChB,oBAAoB,CAAC;GACrB,SAAS,CAAC;GACV,kBAAkB,CAChB;IACE;IACA,cAAc;KACZ,MAAM;KACN,QAAQ,KAAK,wBAAwB,CAAK;IAC5C;GACF,CACF;EACF;EAEA,OADA,KAAK,aAAa,CAAkB,GAC7B;CACT;CAIA,wBAAwB,GAAa;EACnC,IAAI,EAAY,WAAW,GACzB,OAAO,CAAC;EAEV,IAAM,IAAU,CAAC,GACX,IAAgB,IAAI,IAAI,CAAW;EACzC,KAAK,IAAM,CAAC,GAAgB,MAAmB,KAAK,mBAClD,KAAK,IAAM,KAAa,KAAK,eAAe,CAAc,GACxD,IAAI,EAAc,IAAI,CAAS,GAAG;GAChC,EAAQ,KAAK,CAAc;GAC3B;EACF;EAGJ,OAAO;CACT;CAIA,4BAA4B,GAAS,GAAW;EAC9C,KAAK,IAAM,KAAuB,GAAS;GACzC,IAAM,IAAiB,KAAK,sBAAsB,CAAmB,GAC/D,EAAE,kBAAe,mBAAgB,gBAAa;GACpD,KAAK,IAAM,CAAC,GAAS,CAAC,GAAW,OAAe,GAE9C,AAD2B,EAAU,EAAe,IAAI,CAAS,CAAC,CAAC,UAAU,MAAM,KAAK,KAAK,EAAU,EAAe,IAAI,CAAS,CAAC,CAAC,UAAU,MAAM,KAAK,KAExJ,KAAK,4BACH,GACA,GACA,GACA,CACF;GAGJ,KAAK,IAAM,KAAW,GAAU;IAC9B,IAAI,EAAc,IAAI,CAAO,GAC3B;IAEF,IAAM,IAAY,EAAe,IAAI,CAAO,CAAC,CAAC,YACxC,IAAa,EAAU,CAAS;IACtC,IAAI,CAAC,GACH;IAEF,IAAM,IAAS,GAAmB,CAAU;IAG5C,AAFoB,EAAO,gBAAgB,EAAO,eAAe,sBAAsB,EAAO,eAAe,mBAC7G,EAAO,KAAK,SAAS,EAAe,QAAQ,kBAAkB,MAE5D,KAAK,wBACH,GACA,GACA,EAAO,aAEP,EAAO,cACT;GAEJ;EACF;CACF;CACA,wBAAwB,GAAgB,GAAS,GAAa,GAAgB;EAC5E,IAAM,IAAY,EAAe,eAC3B,IAAY,EAAe,eAC3B,IAAiB;GACrB,QAAQ;GACR,UAAU,EAAe,QAAQ;GACjC,IAAI,EAAe;EACrB,GACM,IAAoB,KAAK,OAAO,UACpC,EAAe,sBACf;GACE,GAAG,EAAe;GAClB,gBAAgB;IACd,GAAG;IACH,QAAQ;IAER,WAAW;GACb;EACF,CACF;EACA,EAAe,eAAe,IAAI,GAAW,CAAiB;EAC9D,IAAM,IAAqB,KAAK,OAAO,UACrC,EAAe,sBACf;GACE,GAAG,EAAe;GAClB,gBAAgB;IACd,GAAG;IACH,QAAQ;IACR,WAAW;GACb;EACF,CACF;EAEA,AADA,EAAe,eAAe,IAAI,GAAW,CAAkB,GAC/D,EAAe,cAAc,IAAI,GAAS,CAAC,GAAW,CAAS,CAAC;CAClE;CAIA,wBAAwB,GAAO,GAAgB,GAAU;EACvD,IAAM,IAAiB,KAAK,sBAAsB,CAAK,GACjD,IAAU,EAAe,eACzB,IAAiB;GACrB,QAAQ;GACR;GACA,IAAI,EAAe;EACrB,GACM,IAAW;GACf,GAAG,EAAe;GAClB;EACF,GACM,IAAe,KAAK,OAAO,UAC/B,EAAe,sBACf,CACF;EAGA,OAFA,EAAe,SAAS,KAAK,CAAO,GACpC,EAAe,eAAe,IAAI,GAAS,CAAY,GAChD;CACT;CACA,+BAA+B,GAAO;EACpC,IAAM,IAAiB,KAAK,kBAAkB,IAAI,CAAK;EAClD,UAGL,IAAe,gBACX,IAAe,iBAAiB,KAGpC;QAAK,IAAM,KAAgB,EAAe,eAAe,OAAO,GAC9D,EAAa,YAAY;GAE3B,KAAK,kBAAkB,OAAO,CAAK;EAFR;CAG7B;CACA,4BAA4B,GAAgB,GAAS,GAAW,GAAW;EACzE,IAAM,IAAgB,EAAe,eAAe,IAAI,CAAO;EAC/D,EAAe,eAAe,OAAO,CAAO;EAC5C,IAAM,IAAY,EAAe,SAAS,QAAQ,CAAO;EAGzD,AAFA,EAAe,SAAS,OAAO,GAAW,GAAG,GAAW,CAAS,GACjE,EAAe,cAAc,OAAO,CAAO,GAC3C,EAAc,YAAY;CAC5B;CAEA,sBAAsB,GAAgB;EACpC,OAAO,EAAe,SAAS,KAC5B,MAAY,EAAe,eAAe,IAAI,CAAO,CAAC,CAAC,UAC1D;CACF;CACA,eAAe,GAAgB;EAC7B,OAAO,MAAM,KAAK,EAAe,eAAe,OAAO,CAAC,CAAC,CAAC,KACvD,MAAQ,EAAI,UACf;CACF;CACA,sCAAsC,GAAO;EAC3C,IAAM,IAAiB,KAAK,sBAAsB,CAAK,GACjD,IAAc,EAAe,SAAS,EAAe,SAAS,SAAS;EAC7E,IAAI,MAAgB,KAAK,GACvB,MAAU,MAAM,gCAAgC,GAAO;EAEzD,OAAO,EAAe,eAAe,IAAI,CAAW,CAAC,CAAC;CACxD;CACA,sBAAsB,GAAO;EAC3B,IAAM,IAAiB,KAAK,kBAAkB,IAAI,CAAK;EACvD,IAAI,CAAC,GACH,MAAU,MAAM,gDAAgD,CAAK;EAEvE,OAAO;CACT;AACF,GC1WI,KAAY,OAAO,gBACnB,MAAmB,GAAK,GAAK,MAAU,KAAO,IAAM,GAAU,GAAK,GAAK;CAAE,YAAY;CAAM,cAAc;CAAM,UAAU;CAAM;AAAM,CAAC,IAAI,EAAI,KAAO,GACtJ,MAAiB,GAAK,GAAK,MAAU,GAAgB,GAAK,OAAO,KAAQ,WAAsB,IAAX,IAAM,IAAU,CAAK,GAUzG,IAIS,KAAb,MAA0B;CAMxB,YAAY,GAAS,IAAU,CAAC,GAAG;EAQjC,AAPA,GAAc,MAAM,WAAW,GAC/B,GAAc,MAAM,SAAS,GAC7B,GAAc,MAAM,kBAAkB,GAEtC,GAAc,MAAM,wCAAwC,GAC5D,GAAc,MAAM,SAAS,GAC7B,GAAc,MAAM,WAAW,GAC3B,EAAQ,iCAAiC,MAC3C,GAAsB,CAAO;EAE/B,IAAM,EAAE,aAAU,GAAG,MAAgB;EAsBrC,AArBA,KAAK,UAAU,IACf,KAAK,YAAY,CAAC,CAAC,GACf,MAA+B,EAAE,0BAA0B,MAAgB,OAAO,YAAc,QAClG,EAAY,uBAAuB,KAEjC,OAAO,SAAW,OAAe,EAAE,2BAA2B,OAChE,EAAY,wBAAwB,KAEjC,KAAK,aACR,KAAK,UAAU,IAAI,GACjB,SACM,CACN,GAEA,CACF,GACA,KAAK,mBAAmB,IAAI,GAC1B,KAAK,UACJ,MAAe,KAAK,YAAY,CAAU,CAC7C,IAEF,KAAK,4BAA4B,IAAI,IAAI;CAC3C;CAIA,IAAI,SAAS;EACX,OAAO,KAAK;CACd;CACA,IAAI,SAAS;EACX,IAAI,KAAK,SAAS,OAAO,KAAK;EAC9B,MAAU,MAAM,0BAA0B;CAC5C;CAIA,IAAI,kBAAkB;EACpB,IAAI,KAAK,kBAAkB,OAAO,KAAK;EACvC,MAAU,MAAM,0BAA0B;CAC5C;CACA,IAAI,WAAW;EACb,OAAO,KAAK;CACd;CAiCA,SAAS,GAAO,GAAM,GAAU,GAAS;EACvC,IAAI,KAAK,UACP,OAAO,KAAK,0BAA0B;EAExC,IAAM,EAAE,eAAY,mBAAgB,KAAK,OAAO,UAC9C,GAAgB,CAAK,GACrB,CACF,GACM,IAAY;GAChB;GACA;GACA;GACA;GACA,YAAY;GACZ;GACA;GACA,mBAAmB,KAAK;EAC1B;EAEA,AADA,KAAK,UAAU,IAAI,CAAS,GACxB,KAAK,iBAAiB,CAAU,KAAK,KAAK,2CAA2C,KAAK,MAC5F,KAAK,yCAAyC,iBACtC,KAAK,kCAAkC,GAC7C,CACF;EAEF,IAAM,IAAmB;GACvB,mBAAmB;IACb,KAAK,WAGT,KAAK,UAAU,OAAO,CAAS,GAC/B,EAAY;GACd;GACA,uBAAuB,KAAK,OAAO,wBAAwB,CAAU;GACrE,oBAAoB,KAAK,OAAO,eAAe,CAAU;EAC3D,GACM,IAAM,EAAiB;EAE7B,OADA,OAAO,OAAO,GAAK,CAAgB,GAC5B;CACT;CAgBA,+BAA+B,GAAO,GAAM,GAAS,GAAU,GAAS;EACtE,IAAI,KAAK,UACP,OAAO,KAAK,0BAA0B;EAExC,IAAM,IAAoB;GACxB,iBAAiB,EAAQ;GACzB,IAAI;EACN,GACM,EAAE,wBAAqB,mBAAgB,KAAK,gBAAgB,UAChE,GAAgB,CAAK,GACrB,GAEA,CACF,GACM,IAAY;GAChB,YAAY;GACZ;GACA;GACA;GACA,YAAY;GACZ;GACA;GACA;EACF;EAEA,AADA,KAAK,UAAU,IAAI,CAAS,GACtB,KAAK,gBAAgB,wBAAwB,CAAmB,KAAK,KAAK,2CAA2C,KAAK,MAC9H,KAAK,yCAAyC,iBACtC,KAAK,kCAAkC,GAC7C,CACF;EAEF,IAAM,IAAmB;GACvB,mBAAmB;IACb,KAAK,WAGT,KAAK,UAAU,OAAO,CAAS,GAC/B,EAAY;GACd;GACA,uBACiB,KAAK,gBAAgB,iBAClC,GAAgB,CAAK,GACrB,GACA,CAEU;GAEd,oBAAoB,CAAC;EAEvB,GACM,IAAM,EAAiB;EAE7B,OADA,OAAO,OAAO,GAAK,CAAgB,GAC5B;CACT;CAGA,oCAAoC;EAElC,AADA,KAAK,yCAAyC,KAAK,GACnD,KAAK,YAAY;GAAE,SAAS,CAAC;GAAG,kBAAkB,CAAC;EAAE,GAAG,EAAI;CAC9D;CACA,iBAAiB,GAAY;EAC3B,OAAO,KAAK,OAAO,2BAA2B,CAAU;CAC1D;CACA,4BAA4B;EAC1B,IAAM,WAA6B,CACnC;EAOA,OADA,OAAO,OAAO,GAAqB;GAJjC,aAAa;GACb,uBAAuB,KAAK;GAC5B,oBAAoB,KAAK;EAEuB,CAAC,GAC5C;CACT;CACA,MAAM,QAAQ;EACR,UAAK,UAMT,OALA,KAAK,UAAU,MAAM,GACrB,KAAK,UAAU,IACf,AACE,KAAK,qBAAmB,KAAK,GAExB,KAAK,OAAO,MAAM;CAC3B;CAIA,UAAU;EACJ,UAAK,UACT,OAAO,KAAK,OAAO,qBAAqB;CAC1C;CASA,QAAQ,GAAY,GAAU;EACxB,KAAK,YACT,KAAK,OAAO,QACV,GACA,YAAmB,CACnB,EACF;CACF;CAIA,aAAa,GAAO,GAAU;EAC5B,IAAI,KAAK,QACP,MAAU,MAAM,uCAAuC;EAErD,KAAK,YACT,KAAK,OAAO,aAAa,GAAO,CAAQ;CAC1C;CAIA,YAAY,EACV,YACA,uBACC,IAAmB,IAAO;EAC3B,IAAM,IAAiB,CACrB,GAAG,EAAQ,KAAK,MAAM,EAAE,KAAK,GAC7B,GAAG,EAAiB,KAAK,MAAM,EAAE,KAAK,CACxC;EACA,KAAK,IAAM,KAAa,KAAK,WAAW;GACtC,IAAM,EAAE,aAAU,eAAY,YAAS,kBAAe,GAChD,IAAmB,GAAgC,CAAU,GAC7D,IAAiB,IAAmB,CAAC,CAAC,KAAK,gBAAgB,wBAAwB,CAAU,IAAI,KAAK,OAAO,2BAA2B,CAAU;GACxJ,IAAI,EAAe,SAAS,CAAU,KAAK,KAAoB,CAAC,KAAc,GAAgB;IAC5F,EAAU,aAAa;IACvB,IAAI;IACJ,IAAI;KACF,AAGE,IAHE,IACS,KAAK,gBAAgB,wBAAwB,CAAU,IAEvD,KAAK,OAAO,wBAAwB,CAAU;IAE7D,SAAS,GAAO;KACd,IAAI,EAAE,aAAiB,QAAQ,MAAM;KACrC,AAAI,IACF,EACE,GACA,+DACF,IAEA,QAAa,OAAO,CAAK;KAE3B;IACF;IACA,EACE,GACA,gEACF;GACF;EACF;CACF;CAUA,MAAM,SAAS,GAAU,GAAM,GAAS;EACtC,IAAI,KAAK,UAAU,MAAU,MAAM,0BAA0B;EAC7D,OAAO,MAAM,KAAK,OAAO,SAAS,GAAgB,CAAQ,GAAG,GAAM,CAAO;CAC5E;CASA,MAAM,OAAO,GAAQ,GAAM;EACzB,IAAI,KAAK,UAAU,MAAU,MAAM,0BAA0B;EAC7D,OAAO,MAAM,KAAK,OAAO,OAAO,GAAgB,CAAM,GAAG,CAAI;CAC/D;CASA,MAAM,MAAM,GAAO,GAAM;EACvB,IAAI,KAAK,UAAU,MAAU,MAAM,0BAA0B;EAC7D,IAAM,IAAQ,KAAK,OAAO,iBAAiB,GAAgB,CAAK,GAAG,CAAI;EAEvE,OADI,MAAU,KAAK,IACZ,IAAI,SAAS,GAAS,MAAW;GACtC,IAAM,EAAE,mBAAgB,KAAK,SAC3B,GACA,IACC,MAAW;IAEV,AADA,EAAY,GACZ,EAAQ,CAAM;GAChB,IACC,MAAM;IAEL,AADA,EAAY,GACZ,EAAO,CAAC;GACV,CACF;EACF,CAAC,IAd4B,QAAQ,QAAQ,CAAK;CAepD;CAOA,kBAAkB;EAChB,IAAI,KAAK,UAAU,MAAU,MAAM,0BAA0B;EAC7D,OAAO,KAAK,OAAO,gBAAgB;CACrC;CAWA,2BAA2B,GAAI;EAG7B,OAFI,KAAK,iBAAuB,CAChC,IACO,KAAK,OAAO,2BAA2B,CAAE;CAClD;AACF;;;AC1XA,SAAgB,GACd,GACqB;CACrB,OAAO;AACT;AAQA,SAAgB,GACd,GAGA,GACc;CACd,IAAM,IAAiB,EAAO,CAAW;CACzC,EAAe,UAAU;CAEzB,IAAM,CAAC,GAAO,KAAY,QACxB,OAAO,KAAY,aAAc,EAAoB,IAAI,CAC3D;CAUA,OAAO,CAAC,GARK,GAAsB,MAAU;EAC3C,GAAU,MAAY;GAEpB,IAAM,IADU,EAAe,QAAQ,EAAQ,KAC/B,GAAU,EAAM;GAChC,OAAO,IAAU,EAAQ,GAAS,CAAK,IAAI;EAC7C,CAAC;CACH,GAAG,CAAC,CAEW,CAAI;AACrB;;;ACjDA,IAAM,KAAuB;AAM7B,SAAgB,GAAmB,GAA8B;CAC/D,IAAM,IAAyB,CAAC,GAC5B,IAAY,GACV,IAAK,IAAI,OAAO,GAAqB,QAAQ,GAAG;CACtD,KAAK,IAAI,IAAI,EAAG,KAAK,CAAI,GAAG,MAAM,MAAM,IAAI,EAAG,KAAK,CAAI,GAKtD,AAJI,EAAE,QAAQ,KACZ,EAAO,KAAK;EAAE,MAAM;EAAQ,OAAO,EAAK,MAAM,GAAW,EAAE,KAAK;CAAE,CAAC,GAErE,EAAO,KAAK;EAAE,MAAM;EAAW,MAAM,EAAE,MAAM;EAAI,QAAQ,EAAE,MAAM;CAAG,CAAC,GACrE,IAAY,EAAE,QAAQ,EAAE,EAAE,CAAC;CAK7B,OAHI,IAAY,EAAK,UACnB,EAAO,KAAK;EAAE,MAAM;EAAQ,OAAO,EAAK,MAAM,CAAS;CAAE,CAAC,GAErD;AACT;AAEA,SAAgB,GAAsB,GAAwB;CAC5D,IAAM,oBAAO,IAAI,IAAY,GACvB,IAAgB,CAAC,GACjB,IAAK,IAAI,OAAO,GAAqB,QAAQ,GAAG;CACtD,KAAK,IAAI,IAAI,EAAG,KAAK,CAAI,GAAG,MAAM,MAAM,IAAI,EAAG,KAAK,CAAI,GAAG;EACzD,IAAM,IAAK,EAAE;EACb,AAAI,KAAM,CAAC,EAAK,IAAI,CAAE,MACpB,EAAK,IAAI,CAAE,GACX,EAAI,KAAK,CAAE;CAEf;CACA,OAAO;AACT;AAYA,SAAgB,GAAqB,GAAe,GAA2C;CAC7F,KAAK,IAAI,IAAI,IAAQ,GAAG,KAAK,GAAG,KAAK;EACnC,IAAM,IAAK,EAAM;EACjB,IAAI,MAAO,KAAK;GACd,IAAM,IAAO,MAAM,IAAI,KAAA,IAAY,EAAM,IAAI;GAE7C,IAAI,EADe,MAAS,KAAA,KAAa,KAAK,KAAK,CAAI,IACtC,OAAO;GACxB,IAAM,IAAQ,EAAM,MAAM,IAAI,GAAG,CAAK;GAEtC,OADI,KAAK,KAAK,CAAK,IAAU,OACtB;IAAE,IAAI;IAAG;IAAO;GAAM;EAC/B;EAEA,IADI,MAAO,KAAA,KACP,WAAW,KAAK,CAAE,GAAG,OAAO;CAClC;CACA,OAAO;AACT;AAUA,SAAgB,GAAiB,GAAyD;CACxF,IAAI,CAAC,EAAO,UAAU,QAAQ,KAAK,EAAO,MAAM,GAAG,OAAO;CAC1D,IAAM,IAAO,EAAO,KAAK,QAAQ,cAAc,GAAG,CAAC,CAAC,KAAK;CAEzD,OADK,IACE,KAAK,EAAK,IAAI,EAAO,OAAO,KADjB;AAEpB;;;ACjDA,IAAM,KAAU,GAA2D;CACzE,MAAM,EACJ,cAAc,EAAE,MAAM,UAAU,GAClC;CACA,SAAS;EACP,UAAU,GAAG,OAAO;GAAE,MAAM;GAAW,MAAM,EAAE;EAAK;EACpD,UAAU,GAAG,OAAO;GAAE,MAAM;GAAS,SAAS,EAAE;EAAQ;CAC1D;CACA,SAAS;EAEP,cAAc,EAAE,MAAM,UAAU;EAChC,cAAc,EAAE,MAAM,OAAO;CAC/B;CACA,OAAO;EACL,cAAc,EAAE,MAAM,UAAU;EAChC,cAAc,EAAE,MAAM,OAAO;CAC/B;AACF,CAAC;AAgCD,SAAgB,KAAuD;CACrE,IAAM,CAAC,GAAU,KAAQ,GAAW,IAAS,EAAE,MAAM,OAAO,CAAC,GACvD,IAAQ,GAIR,IAAW,EAAO,CAAK;CAC7B,EAAS,UAAU;CAEnB,IAAM,IAAM,EACV,OAAO,GAAsB,MAA4B;EACnD,MAAS,QAAQ,SAAS,WAC9B;KAAK,EAAE,MAAM,QAAQ,CAAC;GACtB,IAAI;IACF,IAAM,IAAS,MAAM,EAAG;IAIxB,OAHA,EAAK;KAAE,MAAM;KAAW,MAAM;IAAO,CAAC,GACtC,GAAS,YAAY,CAAM,GAC3B,GAAS,YAAY,GACd;GACT,SAAS,GAAK;IACZ,IAAM,IAAU,aAAe,QAAQ,EAAI,UAAU;IAIrD,IAHA,EAAK;KAAE,MAAM;KAAW;IAAQ,CAAC,GACjC,GAAS,UAAU,CAAO,GAC1B,GAAS,YAAY,GACjB,GAAS,SAAS,MAAM;IAC5B;GACF;EAdsB;CAexB,GACA,CAAC,CAAI,CACP,GAEM,IAAQ,QAAkB,EAAK,EAAE,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAI,CAAC;CAE/D,OAAO;EACL;EACA,QAAQ,EAAM,SAAS;EACvB,WAAW,EAAM,SAAS;EAC1B,WAAW,EAAM,SAAS;EAC1B,SAAS,EAAM,SAAS;EACxB,MAAM,EAAM,SAAS,YAAY,EAAM,OAAO,KAAA;EAC9C,OAAO,EAAM,SAAS,UAAU,EAAM,UAAU,KAAA;EAChD;EACA;CACF;AACF;;;AC9HA,IAAM,qBAAoB,IAAI,IAAI;CAAC;CAAQ;CAAQ;CAAc;CAAO;AAAM,CAAC;AAE/E,SAAgB,GAAK,GAAM,GAAO;CAC9B,IAAI,IAAW,GAAkB,IAAI,CAAI;CACzC,MAAa,EAAK,WAAW,OAAO,KAAK,GAAS,CAAI;CACtD,IAAI,IAAY,GAAS,CAAK,KAAK,EAAM,SAAS;CAElD,OADA,MAAc,EAAM,WAAW,GAAG,KAAK,GAAS,EAAM,MAAM,CAAC,CAAC,GACvD,KAAY;AACvB;AAEA,SAAgB,GAAO,GAAM;CACzB,OAAO,GAAS,CAAI;AACxB;AAEA,SAAgB,GAAU,GAAM;CAC5B,OAAO,GAAS,CAAI;AACxB;AAEA,SAAgB,GAAQ,GAAM;CAC1B,OAAO;AACX;AAEA,SAAgB,GAAO,GAAO,GAAS;CACnC,IAAI,EAAM,aAAa,KAAK,cACxB,MAAU,MAAM,wDAAwD;CAE5E,IAAI,EAAM,QAAQ,YAAY,MAAM,QAChC,OAAO;CAEX,IAAM,IAAW;EACb,MAAM,SAAS;EACP;EACG;EACF;EACH;EACN,WAAW;EACX,eAAe;EACf,oBAAoB;EACpB,uBAAuB;CAC3B,GACM,oBAAY,IAAI,KAAK,GACrB,IAAS;EAAE,GAAG;EAAU,GAAG;CAAQ,GACnC,IAAe,GAAiB,EAAO,MAAM,CAAQ,GACvD,GACA,IAAQ;CACZ,KAAK,IAAM,KAAa,GAAO,GAAO,GAAQ,CAAY,GAAG;EAEzD,qBADsB,IAAI,KAAK,EAAA,CAAE,QAAQ,IAAI,EAAU,QAAQ,IAC3C,EAAO,aACvB,KAAS,EAAO,uBAAuB;GACvC,IAAM,IAAQ,GAAS,GAAO,CAAY;GAC1C,IAAI,CAAC,GACD,MAAU,MAAM,+CAA+C,EAAO,UAAU,GAAG;GAEvF,OAAO,GAAS,CAAK;EACzB;EAEA,IADA,KACI,GAAO,GAAW,CAAY,GAAG;GACjC,IAAY;GACZ;EACJ;CACJ;CACA,IAAI,CAAC,GACD,MAAU,MAAM,yBAAyB;CAE7C,IAAM,IAAY,CACd,GAAG,GAAS,GAAW,GAAO,GAAQ,GAAc,CAAS,CACjE;CAKA,OAJA,EAAU,KAAK,EAAS,GACpB,EAAU,SAAS,IACZ,GAAS,EAAU,EAAE,IAEzB,GAAS,CAAS;AAC7B;AACA,UAAU,GAAO,GAAO,GAAQ,GAAc;CAC1C,IAAM,IAAQ,CAAC,GACX,IAAQ,CAAC,GACT,IAAU,GACV,IAAI;CACR,OAAO,KAAW,MAAY,IAAc;EACxC,IAAM,IAAQ,GAAI,GAAS,CAAM;EACjC,KAAK,IAAM,KAAQ,GACf,EAAK,QAAQ;EAMjB,IAJA,EAAM,KAAK,CAAK,GAChB,IAAU,EAAQ,eAClB,KACA,EAAM,KAAK,GAAG,GAAa,CAAK,CAAC,GAC7B,KAAK,EAAO,eAAe;GAC3B,EAAM,KAAK,EAAS;GACpB,KAAK,IAAM,KAAa,GACpB,MAAM;GAEV,IAAQ,CAAC;EACb;CACJ;CACA,EAAM,KAAK,EAAS;CACpB,KAAK,IAAM,KAAa,GACpB,MAAM;AAEd;AACA,SAAS,GAAS,GAAM;CACpB,IAAI,iBAAiB,KAAK,CAAI,GAAG;EAC7B,IAAM,IAAQ,EAAK,MAAM,SAAS;EAClC,KAAK,IAAM,KAAQ,GAIf,IAHI,EAAK,UAAU,KAGf,gBAAgB,KAAK,CAAI,GACzB,OAAO;EAGf,OAAO;CACX;CACA,OAAO;AACX;AACA,SAAS,GAAI,GAAS,GAAQ;CAC1B,IAAM,IAAQ,CAAC,GACT,IAAY,EAAQ,aAAa,IAAI;CAC3C,AAAI,KAAa,EAAO,OAAO,CAAS,KACpC,EAAM,KAAK;EACP,MAAM,MAAM,IAAI,OAAO,CAAS;EAChC,SAAS;CACb,CAAC;CAEL,KAAK,IAAI,IAAI,GAAG,IAAI,EAAQ,UAAU,QAAQ,KAAK;EAC/C,IAAM,IAAO,EAAQ,UAAU;EAC/B,AAAI,EAAO,UAAU,CAAI,KACrB,EAAM,KAAK;GACP,MAAM,MAAM,IAAI,OAAO,CAAI;GAC3B,SAAS;EACb,CAAC;CAET;CACA,KAAK,IAAI,IAAI,GAAG,IAAI,EAAQ,WAAW,QAAQ,KAAK;EAChD,IAAM,IAAO,EAAQ,WAAW;EAChC,AAAI,EAAO,KAAK,EAAK,MAAM,EAAK,KAAK,KACjC,EAAM,KAAK;GACP,MAAM,IAAI,IAAI,OAAO,EAAK,IAAI,EAAE,IAAI,IAAI,OAAO,EAAK,KAAK,EAAE;GAC3D,SAAS;EACb,CAAC;CAET;CACA,IAAM,IAAU,EAAQ,QAAQ,YAAY;CAC5C,IAAI,EAAO,QAAQ,CAAO,GAAG;EACzB,EAAM,KAAK;GACP,MAAM;GACN,SAAS;EACb,CAAC;EACD,IAAM,IAAQ,GAAQ,GAAS,CAAO;EACtC,AAAI,MAAU,KAAA,KACV,EAAM,KAAK;GACP,MAAM,GAAU,GAAS,CAAK;GAC9B,SAAS;EACb,CAAC;CAET;CACA,IAAM,IAAM,GAAQ,CAAO;CAO3B,OANI,MAAQ,KAAA,KACR,EAAM,KAAK;EACP,MAAM,GAAS,GAAS,CAAG;EAC3B,SAAS;CACb,CAAC,GAEE;AACX;AACA,SAAS,GAAS,GAAM;CACpB,IAAI,IAAO,EAAK,IACZ,IAAQ,EAAK;CACjB,KAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK;EAClC,IAAM,IAAQ,EAAK,EAAE,CAAC,SAAS;EAO/B,AANA,AAII,IAJA,EAAK,UAAU,IAAQ,IACf,GAAG,EAAK,EAAE,CAAC,KAAK,KAAK,MAGrB,GAAG,EAAK,EAAE,CAAC,KAAK,GAAG,KAE/B,IAAO,EAAK;CAChB;CACA,OAAO;AACX;AACA,SAAS,GAAQ,GAAM;CACnB,OAAO,EAAK,KAAK,MAAS,EAAK,OAAO,CAAC,CAAC,QAAQ,GAAK,MAAM,IAAM,GAAG,CAAC;AACzE;AACA,SAAS,GAAU,GAAG,GAAG;CACrB,OAAO,GAAQ,CAAC,IAAI,GAAQ,CAAC;AACjC;AACA,SAAS,GAAQ,GAAO,GAAS;CAC7B,IAAM,IAAS,EAAM;CACrB,IAAI,CAAC,GACD;CAEJ,IAAI,IAAQ,EAAO;CACnB,IAAI,CAAC,GACD;CAEJ,IAAI,IAAI;CACR,OAAO,MACC,EAAM,aAAa,KAAK,iBACvB,MAAY,KAAA,KACT,EAAM,QAAQ,YAAY,MAAM,MACpC,KAEA,MAAU,KAGd,IAAQ,EAAM;CAElB,OAAO;AACX;AACA,SAAS,GAAS,GAAO,GAAc;CACnC,IAAI,IAAI,GACJ,IAAU,GACR,IAAO,CAAC;CACd,OAAO,KAAW,MAAY,IAAc;EACxC,IAAM,IAAU,EAAQ,QAAQ,YAAY,GACtC,IAAQ,GAAQ,GAAS,CAAO;EACtC,IAAI,MAAU,KAAA,GACV;EAQJ,AANA,EAAK,KAAK;GACN,MAAM,GAAU,GAAS,CAAK;GAC9B,SAAS;GACT,OAAO;EACX,CAAC,GACD,IAAU,EAAQ,eAClB;CACJ;CACA,IAAI,GAAO,GAAM,CAAY,GACzB,OAAO;AAEf;AACA,SAAS,GAAS,GAAS,GAAO;CAI9B,OAHI,MAAY,SACL,SAEJ,GAAG,EAAQ,aAAa,EAAM;AACzC;AACA,SAAS,GAAU,GAAS,GAAO;CAI/B,OAHI,MAAY,SACL,SAEJ,GAAG,EAAQ,eAAe,EAAM;AAC3C;AACA,UAAU,GAAa,GAAO,IAAO,CAAC,GAAG;CACrC,IAAI,EAAM,SAAS,GACf,KAAK,IAAI,KAAQ,EAAM,IACnB,OAAO,GAAa,EAAM,MAAM,GAAG,EAAM,MAAM,GAAG,EAAK,OAAO,CAAI,CAAC;MAIvE,MAAM;AAEd;AACA,SAAS,GAAiB,GAAU,GAAU;CAO1C,OANI,EAAS,aAAa,KAAK,gBACpB,IAEP,MAAa,EAAS,OACf,EAAS,gBAEb;AACX;AACA,SAAS,GAAO,GAAM,GAAc;CAChC,IAAM,IAAM,GAAS,CAAI;CACzB,QAAQ,EAAa,iBAAiB,CAAG,CAAC,CAAC,QAA3C;EACI,KAAK,GACD,MAAU,MAAM,6CAA6C,GAAK;EACtE,KAAK,GACD,OAAO;EACX,SACI,OAAO;CACf;AACJ;AACA,UAAU,GAAS,GAAM,GAAO,GAAQ,GAAc,GAAW;CAC7D,IAAI,EAAK,SAAS,KAAK,EAAK,SAAS,EAAO,oBACxC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAK,SAAS,GAAG,KAAK;EAEtC,qBADsB,IAAI,KAAK,EAAA,CAAE,QAAQ,IAAI,EAAU,QAAQ,IAC3C,EAAO,WACvB;EAEJ,IAAM,IAAU,CAAC,GAAG,CAAI;EAExB,AADA,EAAQ,OAAO,GAAG,CAAC,GACf,GAAO,GAAS,CAAY,KAC5B,EAAa,cAAc,GAAS,CAAO,CAAC,MAAM,MAClD,MAAM,GACN,OAAO,GAAS,GAAS,GAAO,GAAQ,GAAc,CAAS;CAEvE;AAER;;;AC/PA,SAAgB,GAAa,GAAmB,GAAqC;CACnF,IAAM,IAAQ,SAAS,iBACjB,IAAO,KAAK,IAAI,EAAM,aAAa,EAAM,WAAW,GACpD,IAAO,KAAK,IAAI,EAAM,cAAc,EAAM,YAAY,GAEtD,IAAQ,EAAM,UAAU,OAAO,SAC/B,IAAQ,EAAM,UAAU,OAAO,SAE/B,IACJ,MAAW,KAAA,IAAqB,EAAM,kBAAkB,UAAU,EAAM,SAAS,OAA1D,GACnB,IAAW,IAAiB,GAAgB,CAAc,IAAI,KAAA,GAEhE,GACA;CACJ,IAAI,GAAgB;EAClB,IAAM,IAAO,EAAe,sBAAsB;EAClD,AAAI,EAAK,QAAQ,KAAK,EAAK,SAAS,MAClC,IAAgB,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,EAAM,UAAU,EAAK,QAAQ,EAAK,KAAK,CAAC,GACjF,IAAgB,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,EAAM,UAAU,EAAK,OAAO,EAAK,MAAM,CAAC;CAErF;CAEA,OAAO;EACL,SAAS,IAAO,IAAI,IAAQ,IAAO;EACnC,SAAS,IAAO,IAAI,IAAQ,IAAO;EACnC,WAAW,OAAO;EAClB,WAAW,OAAO;EAClB,gBAAgB;EAChB;EACA;CACF;AACF;AAGA,SAAgB,GAAc,GAMd;CACd,IAAI,EAAE,gBACJ,IAAI;EACF,IAAM,IAAK,SAAS,cAAc,EAAE,cAAc,GAI5C,IAAO,GAAI,sBAAsB;EACvC,IAAI,KAAM,KAAQ,GAAW,CAAI,GAC/B,OAAO;GACL,OAAO,EAAK,OAAO,OAAO,WAAW,EAAE,iBAAiB,MAAO,EAAK;GACpE,OAAO,EAAK,MAAM,OAAO,WAAW,EAAE,iBAAiB,MAAO,EAAK;GACnE,UAAU;GACV,SAAS;EACX;CAEJ,QAAQ,CAER;CAGF,IAAM,IAAQ,SAAS,iBACjB,IAAO,KAAK,IAAI,EAAM,aAAa,EAAM,WAAW,GACpD,IAAO,KAAK,IAAI,EAAM,cAAc,EAAM,YAAY;CAC5D,OAAO;EACL,OAAO,EAAE,UAAU;EACnB,OAAO,EAAE,UAAU;EACnB,UAAU;EACV,SAAS;CACX;AACF;AAMA,SAAS,GAAW,GAAwB;CAC1C,OAAO,EAAK,UAAU,KAAK,EAAK,WAAW,KAAK,EAAK,QAAQ,KAAK,EAAK,SAAS;AAClF;AAEA,SAAS,GAAgB,GAAiC;CACxD,IAAI;EACF,OAAO,GAAO,GAAI,EAAE,WAAW,IAAK,CAAC;CACvC,QAAQ;EACN;CACF;AACF;;;ACdA,IAAa,KAAb,cAAoC,MAAM;CACxC;CACA,YAAY,GAAiB,GAAgB;EAG3C,AAFA,MAAM,CAAO,GACb,KAAK,OAAO,kBACZ,KAAK,SAAS;CAChB;AACF,GAOa,KAAb,cAAwC,GAAe;CAErD;CACA,YAAY,GAAmB,GAAuC;EAGpE,AAFA,MAAM,GAAG,EAAU,2CAA2C,CAAC,GAC/D,KAAK,OAAO,sBACZ,KAAK,WAAW;CAClB;AACF,GAOa,KAAkB,MAClB,IAAmB;AAiBhC,SAAgB,GAAe,GAAmB,GAAyC;CACzF,IAAM,IAAgB,YAAY,QAAQ,CAAS;CACnD,OAAO,IAAe,YAAY,IAAI,CAAC,GAAc,CAAa,CAAC,IAAI;AACzE;AA+BA,SAAgB,GAAgB,GAA2B;CACzD,IAAM,IAAU,EAAK,OAAO,QAAQ,QAAQ,EAAE;CAE9C,eAAe,EACb,GACA,GACA,GAMY;EACZ,IAAM,IAAkC;GACtC,gBAAgB;GAChB,oBAAoB,EAAK;GACzB,GAAK,EAAK,WAAW,CAAC;EACxB,GAEM,IAAS,EAAK,WAAW,KAAK,MAC9B,IAAa,KAAU,QAAQ,EAAO,MAAM,SAAS,KAAK,EAAO,YAAY,KAAK,IAAI;EAC5F,AAAI,KAAc,MAChB,EAAQ,gBAAmB,UAAU,EAAO;EAG9C,IAAM,IAAO,EAAK,eAAe,KAAK;EACtC,AAAI,MACF,EAAQ,yBAAyB;EAKnC,IAAM,IAAa,EAAK,iBAAiB,MAAM,WACzC,IAAyB;GAC7B,GAAG;GACH;GACA,QAAQ,GAAe,EAAQ,WAAW,EAAQ,MAAM;EAC1D;EACA,AAAI,MACF,EAAU,cAAc;EAG1B,IAAI;EACJ,IAAI;GACF,IAAM,MAAM,MAAM,GAAG,IAAU,KAAQ,CAAS;EAClD,SAAS,GAAK;GAOZ,MAHI,aAAe,gBAAgB,EAAI,SAAS,iBACxC,IAAI,GAAmB,EAAQ,WAAW,EAAQ,QAAQ,IAE5D;EACR;EAEA,IAAM,IAAO,MAAM,EAAI,KAAK,GACtB,IAAO,IAAO,GAAS,CAAI,IAAI;EACrC,IAAI,CAAC,EAAI,IAUP,MAPI,EAAI,WAAW,QAAQ,KAAc,MACvC,EAAK,iBAAiB,GAMlB,IAAI,IAHP,KAAQ,OAAO,KAAS,YAAY,WAAW,KAAQ,OAAO,EAAK,SAAU,WAC1E,EAAK,QACL,SAAS,uBAAuB,EAAI,UACR,EAAI,MAAM;EAE9C,OAAO;CACT;CAEA,OAAO;EACL,iBACE,GACiE;GACjE,OAAO,EACL,yBACA,EAAE,QAAQ,OAAO,GACjB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,qBACE,GAC+C;GAC/C,OAAO,EACL,8BACA,EAAE,QAAQ,OAAO,GACjB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,uBAAuB,GAAmE;GACxF,OAAO,EACL,kCACA,EAAE,QAAQ,OAAO,GACjB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,YACE,GACA,GACsC;GACtC,OAAO,EACL,yBAAyB,mBAAmB,CAAK,KACjD,EAAE,QAAQ,MAAM,GAChB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,YAAY,GAAyE;GACnF,OAAO,EACL,mBACA,EAAE,QAAQ,MAAM,GAChB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,kBACE,GACkD;GAClD,OAAO,EACL,yBACA,EAAE,QAAQ,MAAM,GAChB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,qBAAqB,GAAwB,GAAkD;GAC7F,OAAO,EACL,yBAAyB,mBAAmB,CAAc,EAAE,QAC5D,EAAE,QAAQ,OAAO,GACjB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,yBAAyB,GAAkD;GACzE,OAAO,EACL,kCACA,EAAE,QAAQ,OAAO,GACjB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,aACE,GACA,GACmC;GACnC,OAAO,EACL,mBACA;IAAE,QAAQ;IAAQ,MAAM,KAAK,UAAU,CAAO;GAAE,GAChD;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,aAAa,GAAkB,GAAkD;GAC/E,OAAO,EACL,mBAAmB,mBAAmB,CAAQ,KAC9C,EAAE,QAAQ,SAAS,GACnB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,cACE,GACA,GACA,GACe;GACf,OAAO,EACL,mBAAmB,mBAAmB,CAAQ,KAC9C;IAAE,QAAQ;IAAS,MAAM,KAAK,UAAU,EAAE,cAAW,CAAC;GAAE,GACxD;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,WACE,GACA,GACA,GACmC;GACnC,OAAO,EACL,mBAAmB,mBAAmB,CAAQ,EAAE,YAChD;IAAE,QAAQ;IAAQ,MAAM,KAAK,UAAU,CAAO;GAAE,GAChD;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,YACE,GACA,GACA,GACA,GACmC;GACnC,OAAO,EACL,mBAAmB,mBAAmB,CAAQ,EAAE,YAAY,mBAAmB,CAAS,KACxF;IAAE,QAAQ;IAAS,MAAM,KAAK,UAAU,CAAO;GAAE,GACjD;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,cACE,GACA,GACA,GACmC;GACnC,OAAO,EACL,mBAAmB,mBAAmB,CAAQ,EAAE,YAAY,mBAAmB,CAAS,KACxF,EAAE,QAAQ,SAAS,GACnB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EACA,eACE,GACA,GACA,GACmC;GACnC,OAAO,EACL,oBAAoB,mBAAmB,CAAS,EAAE,aAClD;IAAE,QAAQ;IAAQ,MAAM,KAAK,UAAU,CAAO;GAAE,GAChD;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EAKA,SAAS,GAAkD;GACzD,OAAO,EACL,qBACA,EAAE,QAAQ,OAAO,GACjB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;EAMA,QACE,GAC4D;GAC5D,OAAO,EACL,oBACA,EAAE,QAAQ,OAAO,GACjB;IACE,WAAW;IACX,UAAU;IACV,WAAW;IACX,QAAQ,GAAS;GACnB,CACF;EACF;CACF;AACF;AAEA,SAAS,GAAS,GAAuB;CACvC,IAAI;EACF,OAAO,KAAK,MAAM,CAAI;CACxB,QAAQ;EACN,OAAO;CACT;AACF;;;AC7fA,IAAM,KAAc;AAEpB,eAAsB,GACpB,GACA,GACkB;CAElB,IAAI;EACF,IAAM,IAAS,eAAe,QAAQ,EAAW;EACjD,IAAI,MAAW,aAAa,OAAO;EACnC,IAAI,MAAW,eAAe,OAAO;CACvC,QAAQ,CAER;CAEA,IAAM,IAAO,EAAO,QAAQ,QAAQ,EAAE,GAChC,IAAU,EAAE,oBAAoB,EAAO;CAE7C,IAAI;EAOF,IAAI,EAAC,MANgB,MAAM,GAAG,EAAK,yBAAyB;GAC1D,QAAQ;GACR,aAAa;GACb;GACA,QAAQ,GAAA,IAA8B;EACxC,CAAC,EAAA,CACW,IAGV,OAAO;EAET,IAAM,IAAW,MAAM,MAAM,GAAG,EAAK,2BAA2B;GAC9D,QAAQ;GACR,aAAa;GACb;GACA,QAAQ,GAAe,EAAe;EACxC,CAAC;EACD,IAAI,CAAC,EAAS,IAAI,OAAO;EACzB,IAAM,EAAE,iBAAe,MAAM,EAAS,KAAK,GACrC,IAAS,MAAc;EAC7B,IAAI;GACF,eAAe,QAAQ,IAAa,IAAS,cAAc,aAAa;EAC1E,QAAQ,CAER;EACA,OAAO;CACT,SAAS,GAAK;EAOZ,OAJc,GAAmC,SACpC,eACX,EAAY,GAAK,EAAE,SAAS,eAAe,CAAC,GAEvC;CACT;AACF;;;AC7DA,IAAM,KAAiB,+BACjB,KAAgB;AAOtB,SAAS,GAAS,GAA0B;CAC1C,EAAU,SAAS,MAAO;EACxB,IAAI;GACF,EAAG;EACL,SAAS,GAAK;GACZ,EAAY,GAAK,EAAE,SAAS,4BAA4B,CAAC;EAC3D;CACF,CAAC;AACH;AAEA,IAAM,KAAc;AAIpB,SAAS,KAAiB;CACxB,IAAM,IAAO,QAAQ;CAOrB,IAAI,EAAK,KACP,OAAO;EAAE,WAAW,EAAK;EAAiB,SAAS,EAAK;CAAc;CAGxE,IAAM,oBAAY,IAAI,IAAc,GAE9B,IAAW,QAAQ,WACnB,IAAc,QAAQ;CAE5B,SAAS,EAA2B,GAAG,GAAsD;EAE3F,AADA,EAAS,MAAM,MAAM,CAAI,GACzB,GAAS,CAAS;CACpB;CACA,SAAS,EAEP,GAAG,GACH;EAEA,AADA,EAAY,MAAM,MAAM,CAAI,GAC5B,GAAS,CAAS;CACpB;CAEA,IAAM,UAAmB,GAAS,CAAS,GAErC,UAAgB;EAMpB,AAHI,QAAQ,cAAc,MAAa,QAAQ,YAAY,IACvD,QAAQ,iBAAiB,MAAgB,QAAQ,eAAe,IACpE,OAAO,oBAAoB,YAAY,CAAU,GACjD,EAAU,MAAM;CAClB;CAYA,OAVA,OAAO,eAAe,GAAa,IAAgB,EAAE,OAAO,EAAE,CAAC,GAC/D,OAAO,eAAe,GAAa,IAAe,EAAE,OAAO,EAAU,CAAC,GACtE,OAAO,eAAe,GAAa,IAAa,EAAE,OAAO,EAAQ,CAAC,GAClE,OAAO,eAAe,GAAgB,IAAgB,EAAE,OAAO,EAAE,CAAC,GAElE,QAAQ,YAAY,GACpB,QAAQ,eAAe,GAEvB,OAAO,iBAAiB,YAAY,CAAU,GAEvC;EAAE;EAAW;CAAQ;AAC9B;AAIA,IAAI,KAAuB;AAO3B,SAAgB,GAAwB,GAAgC;CACtE,AACE,OAAS,GAAQ;CAEnB,IAAM,IAAQ;CACd,EAAM,UAAU,IAAI,CAAQ;CAE5B,IAAI,IAAe;CACnB,aAAa;EAGP,MACJ,IAAe,IACf,EAAM,UAAU,OAAO,CAAQ,GAC3B,EAAM,UAAU,SAAS,MAC3B,EAAM,QAAQ,GACV,OAAW,MAAO,KAAS;CAEnC;AACF;;;AC3GA,IAAM,qBAAiB,IAAI,IAAI,CAAC,SAAS,QAAQ,CAAC;AAYlD,SAAgB,GAAe,GAAe,GAA0B;CACtE,IAAI;CACJ,IAAI;EACF,IAAS,IAAI,IAAI,GAAO,CAAI;CAC9B,QAAQ;EACN,OAAO;CACT;CACA,OAAO,GAAe,IAAI,EAAO,QAAQ,IAAI,IAAS;AACxD;;;ACwEA,IAAM,KAAM;AAEZ,SAAS,KAAiC;CACxC,IAAI;EACF,IAAM,IAAM,aAAa,QAAQ,EAAG;EACpC,OAAO,IAAO,KAAK,MAAM,CAAG,IAAoB;CAClD,QAAQ;EACN,OAAO;CACT;AACF;AAOA,SAAS,GAAY,GAAyC;CACxD,WAAO,EAAO,SAAU,UAC5B,OAAO,GAAe,EAAO,OAAO,SAAS,IAAI,CAAC,EAAE,QAAQ,KAAA;AAC9D;AAEA,SAAS,GAAY,GAAkC;CACrD,IAAI;EACF,IAAI,KAAU,MAAM;GAClB,aAAa,WAAW,EAAG;GAC3B;EACF;EACA,aAAa,QAAQ,IAAK,KAAK,UAAU,CAAM,CAAC;CAClD,QAAQ,CAER;AACF;AAMA,SAAgB,KAGd;CACA,IAAM,IAAS,GAAW,GACpB,IAAY;EAAE,MAAM,GAAQ;EAAM,OAAO,GAAQ;CAAM;CAC7D,IAAI,CAAC,GAAQ,OAAO;EAAE,OAAO,EAAE,MAAM,aAAa;EAAG;CAAU;CAG/D,IAAM,IAAU,EAAO,WAAW;CAElC,IACE,MAAY,aACZ,EAAO,cACP,OAAO,EAAO,YAAa,YAC3B,OAAO,EAAO,kBAAmB,YACjC,OAAO,EAAO,yBAA0B,YACxC,OAAO,EAAO,QAAS,YAKnB,EAAO,wBAAwB,KAAK,IAAI,GAC1C,OAAO;EACL,OAAO;GACL,MAAM;GACN,UAAU;IACR,SAAS;IACT,UAAU,EAAO;IACjB,gBAAgB,EAAO;IACvB,uBAAuB,EAAO;IAC9B,MAAM,EAAO;IACb,OAAO,EAAO;IACd,OAAO,GAAY,CAAM;GAC3B;EACF;EACA;CACF;CAIJ,IACE,MAAY,kBACZ,EAAO,cACP,OAAO,EAAO,YAAa,YAC3B,OAAO,EAAO,SAAU,YACxB,OAAO,EAAO,kBAAmB,YACjC,OAAO,EAAO,QAAS,UACvB;EAMA,IAAM,IAAa,EAAO,iBAAiB,KAAK,IAAI,GAC9C,IACJ,OAAO,EAAO,gBAAiB,YAC/B,OAAO,EAAO,yBAA0B,YACxC,EAAO,wBAAwB,KAAK,IAAI;EAE1C,IAAI,KAAc,GAChB,OAAO;GACL,OAAO;IACL,MAAM;IACN,UAAU;KACR,SAAS;KACT,UAAU,EAAO;KACjB,OAAO,EAAO;KACd,gBAAgB,EAAO;KACvB,GAAI,IACA;MACE,cAAc,EAAO;MACrB,uBAAuB,EAAO;KAChC,IACA,CAAC;KACL,MAAM,EAAO;KACb,OAAO,EAAO;KACd,OAAO,GAAY,CAAM;IAC3B;GACF;GACA;EACF;CAEJ;CAkBA,OAhBI,OAAO,EAAO,YAAa,YAAY,OAAO,EAAO,aAAc,WAC9D;EACL,OAAO;GACL,MAAM;GACN,UAAU;IACR,UAAU,EAAO;IACjB,WAAW,EAAO;IAClB,MAAM,EAAO;IACb,OAAO,EAAO;GAChB;EACF;EACA;CACF,IAIK;EAAE,OAAO,EAAE,MAAM,aAAa;EAAG;CAAU;AACpD;AAOA,SAAgB,GAAa,GAA4B;CACvD,QAAQ,EAAM,MAAd;EACE,KAAK;GACH,GAAY;IACV,UAAU,EAAM,SAAS;IACzB,SAAS,EAAM,SAAS;IAKxB,OAAO,EAAM,SAAS,YAAY,YAAY,KAAA,IAAY,EAAM,SAAS;IACzE,gBAAgB,EAAM,SAAS;IAC/B,cACE,EAAM,SAAS,YAAY,YAAY,KAAA,IAAY,EAAM,SAAS;IACpE,uBAAuB,EAAM,SAAS;IACtC,YAAY;IACZ,MAAM,EAAM,SAAS;IACrB,OAAO,EAAM,SAAS;IACtB,OAAO,EAAM,SAAS;GACxB,CAAC;GACD;EACF,KAAK;GACH,GAAY;IACV,UAAU,EAAM,SAAS;IACzB,WAAW,EAAM,SAAS;IAC1B,MAAM,EAAM,SAAS;IACrB,OAAO,EAAM,SAAS;GACxB,CAAC;GACD;EACF,KAAK;GAGH,GAAY;IACV,MAAM,EAAM,UAAU;IACtB,OAAO,EAAM,UAAU;GACzB,CAAC;GACD;EACF,KAAK;GACH,GAAY,IAAI;GAChB;CACJ;AACF;AAMA,SAAgB,GAAW,GAA0C;CAEnE,IADI,EAAM,SAAS,UACf,EAAM,SAAS,YAAY,OAAO,EAAM,SAAS;AAEvD;AAOA,SAAgB,GAAc,GAAqC;CAGjE,OAFI,EAAM,SAAS,SAAe,EAAM,SAAS,QAAQ,OACrD,EAAM,SAAS,aAAmB,EAAM,SAAS,OAC9C;AACT;AASA,SAAgB,GACd,GACoD;CACpD,IAAI,EAAM,SAAS,QAAQ;EACzB,IAAM,IAAO,EAAM,SAAS;EAE5B,OADK,IACE;GAAE;GAAM,OAAO,EAAM,SAAS;EAAM,IADzB;CAEpB;CAIA,OAHI,EAAM,SAAS,aACV;EAAE,MAAM,EAAM,SAAS;EAAM,OAAO,EAAM,SAAS;CAAM,IAE3D;AACT;;;ACvRA,IAAM,KAAmB,sBACnB,KAAkB,qBAClB,KAAoB,uBAUpB,KAAwB;AAE9B,eAAsB,GAAgB,GAKb;CACvB,IAAM,EAAE,WAAQ,WAAQ,kBAAe,GACjC,IAAgB,IAAI,IAAI,CAAM,CAAC,CAAC,QAIhC,IAAe,IAAa,oBAAoB;CAOtD,eAAe,IAAiC;EAC9C,IAAM,IAAc,MAAM,MAAM,GAAG,EAAO,QAAQ,QAAQ,EAAE,EAAE,yBAAyB;GACrF,QAAQ;GACR,SAAS;IAAE,gBAAgB;IAAoB,oBAAoB;GAAO;GAC1E,MAAM;GACN,QAAQ,GAAe,CAAgB;EACzC,CAAC;EACD,IAAI,CAAC,EAAY,IACf,MAAU,MAAM,iCAAiC,EAAY,QAAQ;EAEvE,IAAM,EAAE,YAAU,MAAM,EAAY,KAAK,GACnC,IAAM,IAAI,IAAI,gBAAgB,CAAM;EAG1C,OAFA,EAAI,aAAa,IAAI,QAAQ,CAAI,GACjC,EAAI,aAAa,IAAI,gBAAgB,CAAY,GAC1C,EAAI,SAAS;CACtB;CAEA,IAAI;CACJ,IAAI;EACF,IAAW,MAAM,EAAc;CACjC,SAAS,GAAK;EAQZ,OAJc,GAAmC,SACpC,eACX,EAAY,GAAK,EAAE,SAAS,iBAAiB,CAAC,GAEzC,QAAQ,OAAO,aAAe,QAAQ,IAAM,gBAAI,MAAM,gCAAgC,CAAC;CAChG;CAEA,IAEM,IAAO,KAAK,IAAI,GAAG,OAAO,WAAW,OAAO,aAAa,OAAK,CAAC,GAC/D,IAAM,KAAK,IAAI,GAAG,OAAO,WAAW,OAAO,cAAc,OAAK,CAAC,GAE/D,IAAQ,OAAO,KACnB,GACA,eACA,6BAA+B,EAAK,OAAO,GAC7C;CACA,IAAI,CAAC,GACH,OAAO,QAAQ,OAAO,gBAAI,MAAM,sDAAsD,CAAC;CAQzF,IAMM,IAAM,MAAM,IAAI,SAAsB,GAAS,MAAW;EAC9D,IAAI,IAAmB,GAInB,IAAY;EAEhB,SAAS,IAAU;GAGjB,AAFA,OAAO,oBAAoB,WAAW,CAAS,GAC/C,cAAc,CAAU,GACxB,aAAa,CAAS;EACxB;EAYA,IAAM,KAAc,MAAuB;GACrC,QACJ;QAAI,GAAW;KACb,IAAI,KAAoB,IAAuB;MAE7C,AADA,EAAQ,GACR,EAAO,gBAAI,MAAM,gEAAgE,CAAC;MAClF;KACF;KACA,KAAoB;IACtB;IAEA,AADA,IAAY,IACZ,EAAc,CAAC,CACZ,MAAM,MAAa;KACd,EAAM,WACV,EAAM,SAAS,OAAO;IACxB,CAAC,CAAC,CACD,OAAO,MAAQ;KAGd,AAFA,EAAQ,GACR,EAAY,GAAK,EAAE,SAAS,wBAAwB,CAAC,GACrD,EAAO,aAAe,QAAQ,IAAM,gBAAI,MAAM,2BAA2B,CAAC;IAC5E,CAAC,CAAC,CACD,cAAc;KACb,IAAY;IACd,CAAC;GAdH;EAeF;EAEA,SAAS,EAAU,GAAiB;GAIlC,IAHI,EAAE,WAAW,KAGb,EAAE,WAAW,GAAO;GACxB,IAAM,IAAI,EAAE;GAUZ,IAAI,GAAG,SAAS,IAAiB;IAC/B,EAAW,EAAK;IAChB;GACF;GACA,IAAI,GAAG,SAAS,IAAmB;IACjC,EAAW,EAAI;IACf;GACF;GACI,GAAG,SAAS,OAChB,EAAQ,GACJ,EAAE,UAAU,MAAM,EAAE,UAAU,OAGhC,EAAQ;IACN,MAFsB,EAAE,SAAS,YAAY,YAAY;IAGzD,UAAU,EAAE;IACZ,OAAO,OAAO,EAAE,SAAU,WAAW,EAAE,QAAQ;IAC/C,gBAAgB,OAAO,EAAE,kBAAmB,WAAW,EAAE,iBAAiB;IAC1E,cAAc,OAAO,EAAE,gBAAiB,WAAW,EAAE,eAAe;IACpE,uBACE,OAAO,EAAE,yBAA0B,WAAW,EAAE,wBAAwB;GAC5E,CAAC,IAED,EAAO,gBAAI,MAAM,mBAAmB,CAAC;EAEzC;EACA,IAAM,IAAa,OAAO,kBAAkB;GAC1C,AAAI,EAAM,WACR,EAAQ,GACR,EAAO,gBAAI,MAAM,mBAAmB,CAAC;EAEzC,GAAG,GAAG,GACA,IAAY,OAAO,iBAAiB;GAExC,AADA,EAAQ,GACR,EAAO,gBAAI,MAAM,mBAAmB,CAAC;EACvC,GAAG,GAAU;EACb,OAAO,iBAAiB,WAAW,CAAS;CAC9C,CAAC;CAKD,IAAI,EAAI,SAAS,aAAa,EAAI,SAAS,EAAI,cAAc;EAC3D,IAAM,IAAa,MAAM,MAAM,GAAG,EAAO,QAAQ,QAAQ,EAAE,EAAE,+BAA+B;GAC1F,QAAQ;GACR,aAAa;GACb,SAAS;IAAE,gBAAgB;IAAoB,oBAAoB;GAAO;GAC1E,MAAM,KAAK,UAAU;IACnB,aAAa,EAAI;IACjB,cAAc,EAAI;GACpB,CAAC;GACD,QAAQ,GAAe,CAAgB;EACzC,CAAC;EACD,IAAI,CAAC,EAAW,IAAI;GAGlB,IAAM,IAAM,gBAAI,MAAM,qCAAqC,EAAW,OAAO,EAAE;GAE/E,MADA,EAAY,GAAK,EAAE,SAAS,kBAAkB,CAAC,GACzC;EACR;EACA,OAAO;GAAE,GAAG;GAAK,OAAO;GAAM,cAAc;EAAK;CACnD;CAEA,OAAO;AACT;;;AClQA,SAAgB,GAAW,GAAK,GAAS;CAErC,IAAI,EAAI,MAAM,eAAe,GACzB,OAAO;CAGX,IAAI,EAAI,MAAM,OAAO,GACjB,OAAO,OAAO,SAAS,WAAW;CAGtC,IAAI,EAAI,MAAM,WAAW,GACrB,OAAO;CAEX,IAAM,IAAM,SAAS,eAAe,mBAAmB,GACjD,IAAO,EAAI,cAAc,MAAM,GAC/B,IAAI,EAAI,cAAc,GAAG;CAO/B,OANA,EAAI,KAAK,YAAY,CAAI,GACzB,EAAI,KAAK,YAAY,CAAC,GAClB,MACA,EAAK,OAAO,IAEhB,EAAE,OAAO,GACF,EAAE;AACb;AACA,IAAa,YAAc;CAGvB,IAAI,IAAU,GAER,UAEN,QAAS,KAAK,OAAO,IAAI,MAAM,KAAM,EAAA,CAAG,SAAS,EAAE,IAAI,MAAM,EAAE;CAC/D,cACI,KAAW,GACJ,IAAI,EAAO,IAAI;AAE9B,EAAA,CAAG;AAMH,SAAgB,GAAQ,GAAW;CAC/B,IAAM,IAAM,CAAC;CACb,KAAK,IAAI,IAAI,GAAG,IAAI,EAAU,QAAQ,IAAI,GAAG,KACzC,EAAI,KAAK,EAAU,EAAE;CAEzB,OAAO;AACX;AACA,IAAI,KAAa;AACjB,SAAgB,GAAmB,IAAU,CAAC,GAAG;CAS7C,OARI,OAGA,EAAQ,0BACR,KAAa,EAAQ,wBACd,OAEX,KAAa,GAAQ,OAAO,iBAAiB,SAAS,eAAe,CAAC,GAC/D;AACX;AACA,SAAS,GAAG,GAAM,GAAe;CAE7B,IAAM,KADM,EAAK,cAAc,eAAe,OAAA,CAC9B,iBAAiB,CAAI,CAAC,CAAC,iBAAiB,CAAa;CACrE,OAAO,IAAM,WAAW,EAAI,QAAQ,MAAM,EAAE,CAAC,IAAI;AACrD;AACA,SAAS,GAAa,GAAM;CACxB,IAAM,IAAa,GAAG,GAAM,mBAAmB,GACzC,IAAc,GAAG,GAAM,oBAAoB;CACjD,OAAO,EAAK,cAAc,IAAa;AAC3C;AACA,SAAS,GAAc,GAAM;CACzB,IAAM,IAAY,GAAG,GAAM,kBAAkB,GACvC,IAAe,GAAG,GAAM,qBAAqB;CACnD,OAAO,EAAK,eAAe,IAAY;AAC3C;AACA,SAAgB,GAAa,GAAY,IAAU,CAAC,GAAG;CAGnD,OAAO;EAAE,OAFK,EAAQ,SAAS,GAAa,CAAU;EAEtC,QADD,EAAQ,UAAU,GAAc,CAAU;CAClC;AAC3B;AACA,SAAgB,KAAgB;CAC5B,IAAI,GACA;CACJ,IAAI;EACA,IAAgB;CACpB,QACU,CAEV;CACA,IAAM,IAAM,KAAiB,EAAc,MACrC,EAAc,IAAI,mBAClB;CAON,OANI,MACA,IAAQ,SAAS,GAAK,EAAE,GACpB,OAAO,MAAM,CAAK,MAClB,IAAQ,KAGT,KAAS,OAAO,oBAAoB;AAC/C;AAEA,IAAM,IAAuB;AAC7B,SAAgB,GAAsB,GAAQ;CAC1C,CAAI,EAAO,QAAQ,KACf,EAAO,SAAS,OACZ,EAAO,QAAQ,KACf,EAAO,SAAS,IACZ,EAAO,QAAQ,EAAO,UACtB,EAAO,UAAU,IAAuB,EAAO,OAC/C,EAAO,QAAQ,MAGf,EAAO,SAAS,IAAuB,EAAO,QAC9C,EAAO,SAAS,KAGf,EAAO,QAAQ,KACpB,EAAO,UAAU,IAAuB,EAAO,OAC/C,EAAO,QAAQ,MAGf,EAAO,SAAS,IAAuB,EAAO,QAC9C,EAAO,SAAS;AAG5B;AAqBA,SAAgB,GAAY,GAAK;CAC7B,OAAO,IAAI,SAAS,GAAS,MAAW;EACpC,IAAM,IAAM,IAAI,MAAM;EAStB,AARA,EAAI,eAAe;GACf,EAAI,OAAO,CAAC,CAAC,WAAW;IACpB,4BAA4B,EAAQ,CAAG,CAAC;GAC5C,CAAC;EACL,GACA,EAAI,UAAU,GACd,EAAI,cAAc,aAClB,EAAI,WAAW,SACf,EAAI,MAAM;CACd,CAAC;AACL;AACA,eAAsB,GAAa,GAAK;CACpC,OAAO,QAAQ,QAAQ,CAAC,CACnB,WAAW,IAAI,cAAc,CAAC,CAAC,kBAAkB,CAAG,CAAC,CAAC,CACtD,KAAK,kBAAkB,CAAC,CACxB,MAAM,MAAS,oCAAoC,GAAM;AAClE;AACA,eAAsB,GAAc,GAAM,GAAO,GAAQ;CACrD,IAAM,IAAQ,8BACR,IAAM,SAAS,gBAAgB,GAAO,KAAK,GAC3C,IAAgB,SAAS,gBAAgB,GAAO,eAAe;CAWrE,OAVA,EAAI,aAAa,SAAS,GAAG,GAAO,GACpC,EAAI,aAAa,UAAU,GAAG,GAAQ,GACtC,EAAI,aAAa,WAAW,OAAO,EAAM,GAAG,GAAQ,GACpD,EAAc,aAAa,SAAS,MAAM,GAC1C,EAAc,aAAa,UAAU,MAAM,GAC3C,EAAc,aAAa,KAAK,GAAG,GACnC,EAAc,aAAa,KAAK,GAAG,GACnC,EAAc,aAAa,6BAA6B,MAAM,GAC9D,EAAI,YAAY,CAAa,GAC7B,EAAc,YAAY,CAAI,GACvB,GAAa,CAAG;AAC3B;AACA,IAAa,KAAuB,GAAM,MAAa;CACnD,IAAI,aAAgB,GAChB,OAAO;CACX,IAAM,IAAgB,OAAO,eAAe,CAAI;CAGhD,OAFI,MAAkB,OACX,KACH,EAAc,YAAY,SAAS,EAAS,QAChD,EAAoB,GAAe,CAAQ;AACnD;;;AC9LA,SAAS,GAAc,GAAO;CAC1B,IAAM,IAAU,EAAM,iBAAiB,SAAS;CAChD,OAAO,GAAG,EAAM,QAAQ,aAAa,EAAQ,QAAQ,QAAQ,EAAE,EAAE;AACrE;AACA,SAAS,GAAoB,GAAO,GAAS;CACzC,OAAO,GAAmB,CAAO,CAAC,CAC7B,KAAK,MAGC,GAAG,EAAK,IAFD,EAAM,iBAAiB,CAEd,IADN,EAAM,oBAAoB,CACT,IAAI,gBAAgB,GAAG,EAC5D,CAAC,CACG,KAAK,GAAG;AACjB;AACA,SAAS,GAAsB,GAAW,GAAQ,GAAO,GAAS;CAC9D,IAAM,IAAW,IAAI,EAAU,GAAG,KAC5B,IAAU,EAAM,UAChB,GAAc,CAAK,IACnB,GAAoB,GAAO,CAAO;CACxC,OAAO,SAAS,eAAe,GAAG,EAAS,GAAG,EAAQ,EAAE;AAC5D;AACA,SAAS,GAAmB,GAAY,GAAY,GAAQ,GAAS;CACjE,IAAM,IAAQ,OAAO,iBAAiB,GAAY,CAAM,GAClD,IAAU,EAAM,iBAAiB,SAAS;CAChD,IAAI,MAAY,MAAM,MAAY,QAC9B;CAEJ,IAAM,IAAY,GAAK;CACvB,IAAI;EACA,EAAW,YAAY,GAAG,EAAW,UAAU,GAAG;CACtD,QACY;EACR;CACJ;CACA,IAAM,IAAe,SAAS,cAAc,OAAO;CAEnD,AADA,EAAa,YAAY,GAAsB,GAAW,GAAQ,GAAO,CAAO,CAAC,GACjF,EAAW,YAAY,CAAY;AACvC;AACA,SAAgB,GAAoB,GAAY,GAAY,GAAS;CAEjE,AADA,GAAmB,GAAY,GAAY,WAAW,CAAO,GAC7D,GAAmB,GAAY,GAAY,UAAU,CAAO;AAChE;;;ACzCA,IAAM,KAAO,yBACP,KAAO,cACP,KAAQ;CACV,MAAM;CACN,OAAO;CACP,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,MAAM;CACN,KAAK;CACL,MAAM;CACN,KAAK;CACL,MAAM;AACV;AACA,SAAS,GAAa,GAAK;CACvB,IAAM,IAAQ,gBAAgB,KAAK,CAAG;CACtC,OAAO,IAAQ,EAAM,KAAK;AAC9B;AACA,SAAgB,GAAY,GAAK;CAE7B,OAAO,GADW,GAAa,CAAG,CAAC,CAAC,YACvB,MAAc;AAC/B;;;ACtBA,SAAS,GAAsB,GAAS;CACpC,OAAO,EAAQ,MAAM,GAAG,CAAC,CAAC;AAC9B;AACA,SAAgB,GAAU,GAAK;CAC3B,OAAO,EAAI,OAAO,UAAU,MAAM;AACtC;AACA,SAAgB,GAAY,GAAS,GAAU;CAC3C,OAAO,QAAQ,EAAS,UAAU;AACtC;AACA,eAAsB,GAAe,GAAK,GAAM,GAAS;CACrD,IAAM,IAAM,MAAM,MAAM,GAAK,CAAI;CACjC,IAAI,EAAI,WAAW,KACf,MAAU,MAAM,aAAa,EAAI,IAAI,YAAY;CAErD,IAAM,IAAO,MAAM,EAAI,KAAK;CAC5B,OAAO,IAAI,SAAS,GAAS,MAAW;EACpC,IAAM,IAAS,IAAI,WAAW;EAU9B,AATA,EAAO,UAAU,GACjB,EAAO,kBAAkB;GACrB,IAAI;IACA,EAAQ,EAAQ;KAAE;KAAK,QAAQ,EAAO;IAAO,CAAC,CAAC;GACnD,SACO,GAAO;IACV,EAAO,CAAK;GAChB;EACJ,GACA,EAAO,cAAc,CAAI;CAC7B,CAAC;AACL;AACA,IAAM,KAAQ,CAAC;AACf,SAAS,GAAY,GAAK,GAAa,GAAoB;CACvD,IAAI,IAAM,EAAI,QAAQ,QAAQ,EAAE;CAQhC,OAPI,MACA,IAAM,IAGN,sBAAsB,KAAK,CAAG,MAC9B,IAAM,EAAI,QAAQ,QAAQ,EAAE,IAEzB,IAAc,IAAI,EAAY,GAAG,MAAQ;AACpD;AACA,eAAsB,GAAkB,GAAa,GAAa,GAAS;CACvE,IAAM,IAAW,GAAY,GAAa,GAAa,EAAQ,kBAAkB;CACjF,IAAI,GAAM,MAAa,MACnB,OAAO,GAAM;CAGjB,AAAI,EAAQ,cAER,MAAgB,KAAK,KAAK,CAAW,IAAI,MAAM,wBAAO,IAAI,KAAK,EAAA,CAAE,QAAQ;CAE7E,IAAI;CACJ,IAAI;EAQA,IAAU,GAAY,MAPA,GAAe,GAAa,EAAQ,mBAAmB,EAAE,QAAK,iBAChF,AAEI,MAAc,EAAI,QAAQ,IAAI,cAAc,KAAK,IAE9C,GAAsB,CAAM,EACtC,GAC8B,CAAW;CAC9C,SACO,GAAO;EACV,IAAU,EAAQ,oBAAoB;EACtC,IAAI,IAAM,6BAA6B;EAIvC,AAHI,MACA,IAAM,OAAO,KAAU,WAAW,IAAQ,EAAM,UAEhD,KACA,QAAQ,KAAK,CAAG;CAExB;CAEA,OADA,GAAM,KAAY,GACX;AACX;;;ACtEA,eAAe,GAAmB,GAAQ;CACtC,IAAM,IAAU,EAAO,UAAU;CAIjC,OAHI,MAAY,WACL,EAAO,UAAU,EAAK,IAE1B,GAAY,CAAO;AAC9B;AACA,eAAe,GAAkB,GAAO,GAAS;CAC7C,IAAI,EAAM,YAAY;EAClB,IAAM,IAAS,SAAS,cAAc,QAAQ,GACxC,IAAM,EAAO,WAAW,IAAI;EAKlC,OAJA,EAAO,QAAQ,EAAM,aACrB,EAAO,SAAS,EAAM,cACtB,GAA8C,UAAU,GAAO,GAAG,GAAG,EAAO,OAAO,EAAO,MAAM,GAEzF,GADS,EAAO,UACJ,CAAO;CAC9B;CACA,IAAM,IAAS,EAAM;CAGrB,OAAO,GAAY,MADG,GAAkB,GADpB,GAAY,CACgB,GAAa,CAAO,CAC1C;AAC9B;AACA,eAAe,GAAmB,GAAQ,GAAS;CAE/C,IAAI;EACA,IAAU,GAAuD,iBAAyD,MACtH,OAAQ,MAAM,GAAU,EAAO,gBAAgB,MAAM,GAAS,EAAI;CAE1E,QACW,CAEX;CACA,OAAO,EAAO,UAAU,EAAK;AACjC;AACA,eAAe,GAAgB,GAAM,GAAS;CAU1C,OATI,EAAoB,GAAM,iBAAiB,IACpC,GAAmB,CAAI,IAE9B,EAAoB,GAAM,gBAAgB,IACnC,GAAkB,GAAM,CAAO,IAEtC,EAAoB,GAAM,iBAAiB,IACpC,GAAmB,GAAM,CAAO,IAEpC,EAAK,UAAU,GAAa,CAAI,CAAC;AAC5C;AACA,IAAM,MAAiB,MAAS,EAAK,WAAW,QAAQ,EAAK,QAAQ,YAAY,MAAM,QACjF,MAAgB,MAAS,EAAK,WAAW,QAAQ,EAAK,QAAQ,YAAY,MAAM;AACtF,eAAe,GAAc,GAAY,GAAY,GAAS;CAE1D,IAAI,GAAa,CAAU,GACvB,OAAO;CAEX,IAAI,IAAW,CAAC;CAsBhB,OArBA,AAQI,IARA,GAAc,CAAU,KAAK,EAAW,gBAC7B,GAAQ,EAAW,cAAc,CAAC,IAExC,EAAoB,GAAY,iBAAiB,KAC/C,EAAW,iBAAyD,OAChE,GAAQ,EAAW,gBAAgB,KAAK,UAAU,IAGlD,IAAe,EAAW,cAA6C,EAAA,CAAY,UAAU,GAExG,EAAS,WAAW,KACpB,EAAoB,GAAY,gBAAgB,KAGpD,MAAM,EAAS,QAAQ,GAAU,MAAU,EACtC,WAAW,GAAU,GAAO,CAAO,CAAC,CAAC,CACrC,MAAM,MAAgB;EACvB,AAAI,KACA,EAAW,YAAY,CAAW;CAE1C,CAAC,GAAG,QAAQ,QAAQ,CAAC,GARV;AAUf;AACA,SAAS,GAAc,GAAY,GAAY,GAAS;CACpD,IAAM,IAAc,EAAW;CAC/B,IAAI,CAAC,GACD;CAEJ,IAAM,IAAc,OAAO,iBAAiB,CAAU;CACtD,AAAI,EAAY,WACZ,EAAY,UAAU,EAAY,SAClC,EAAY,kBAAkB,EAAY,mBAG1C,GAAmB,CAAO,CAAC,CAAC,SAAS,MAAS;EAC1C,IAAI,IAAQ,EAAY,iBAAiB,CAAI;EAa7C,AAZI,MAAS,eAAe,EAAM,SAAS,IAAI,MAE3C,IAAQ,GADY,KAAK,MAAM,WAAW,EAAM,UAAU,GAAG,EAAM,SAAS,CAAC,CAAC,CAAC,IAAI,GAC5D,MAEvB,EAAoB,GAAY,iBAAiB,KACjD,MAAS,aACT,MAAU,aACV,IAAQ,UAER,MAAS,OAAO,EAAW,aAAa,GAAG,MAC3C,IAAQ,QAAQ,EAAW,aAAa,GAAG,EAAE,KAEjD,EAAY,YAAY,GAAM,GAAO,EAAY,oBAAoB,CAAI,CAAC;CAC9E,CAAC;AAET;AACA,SAAS,GAAgB,GAAY,GAAY;CAI7C,AAHI,EAAoB,GAAY,mBAAmB,MACnD,EAAW,YAAY,EAAW,QAElC,EAAoB,GAAY,gBAAgB,KAChD,EAAW,aAAa,SAAS,EAAW,KAAK;AAEzD;AACA,SAAS,GAAiB,GAAY,GAAY;CAC9C,IAAI,EAAoB,GAAY,iBAAiB,GAAG;EACpD,IAAM,IAAe,GACf,IAAiB,MAAM,KAAK,EAAa,QAAQ,CAAC,CAAC,MAAM,MAAU,EAAW,UAAU,EAAM,aAAa,OAAO,CAAC;EACzH,AAAI,KACA,EAAe,aAAa,YAAY,EAAE;CAElD;AACJ;AACA,SAAS,GAAS,GAAY,GAAY,GAAS;CAO/C,OANI,EAAoB,GAAY,OAAO,MACvC,GAAc,GAAY,GAAY,CAAO,GAC7C,GAAoB,GAAY,GAAY,CAAO,GACnD,GAAgB,GAAY,CAAU,GACtC,GAAiB,GAAY,CAAU,IAEpC;AACX;AACA,eAAe,GAAiB,GAAO,GAAS;CAC5C,IAAM,IAAO,EAAM,mBAAmB,EAAM,iBAAiB,KAAK,IAAI,CAAC;CACvE,IAAI,EAAK,WAAW,GAChB,OAAO;CAEX,IAAM,IAAgB,CAAC;CACvB,KAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK;EAElC,IAAM,IADM,EAAK,EACH,CAAC,aAAa,YAAY;EACxC,IAAI,GAAI;GACJ,IAAM,IAAQ,EAAM,cAAc,CAAE,GAC9B,IAAa,SAAS,cAAc,CAAE;GAC5C,AAAI,CAAC,KAAS,KAAc,CAAC,EAAc,OAEvC,EAAc,KAAO,MAAM,GAAU,GAAY,GAAS,EAAI;EAEtE;CACJ;CACA,IAAM,IAAQ,OAAO,OAAO,CAAa;CACzC,IAAI,EAAM,QAAQ;EACd,IAAM,IAAK,gCACL,IAAM,SAAS,gBAAgB,GAAI,KAAK;EAM9C,AALA,EAAI,aAAa,SAAS,CAAE,GAC5B,EAAI,MAAM,WAAW,YACrB,EAAI,MAAM,QAAQ,KAClB,EAAI,MAAM,SAAS,KACnB,EAAI,MAAM,WAAW,UACrB,EAAI,MAAM,UAAU;EACpB,IAAM,IAAO,SAAS,gBAAgB,GAAI,MAAM;EAChD,EAAI,YAAY,CAAI;EACpB,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAC9B,EAAK,YAAY,EAAM,EAAE;EAE7B,EAAM,YAAY,CAAG;CACzB;CACA,OAAO;AACX;AACA,eAAsB,GAAU,GAAM,GAAS,GAAQ;CAInD,OAHI,CAAC,KAAU,EAAQ,UAAU,CAAC,EAAQ,OAAO,CAAI,IAC1C,OAEJ,QAAQ,QAAQ,CAAI,CAAC,CACvB,MAAM,MAAe,GAAgB,GAAY,CAAO,CAAC,CAAC,CAC1D,MAAM,MAAe,GAAc,GAAM,GAAY,CAAO,CAAC,CAAC,CAC9D,MAAM,MAAe,GAAS,GAAM,GAAY,CAAO,CAAC,CAAC,CACzD,MAAM,MAAe,GAAiB,GAAY,CAAO,CAAC;AACnE;;;ACnLA,IAAM,KAAY,8BACZ,KAAwB,+CACxB,KAAiB;AACvB,SAAS,GAAQ,GAAK;CAElB,IAAM,IAAU,EAAI,QAAQ,4BAA4B,MAAM;CAC9D,OAAW,OAAO,iBAAiB,EAAQ,cAAc,GAAG;AAChE;AACA,SAAgB,GAAU,GAAS;CAC/B,IAAM,IAAO,CAAC;CAKd,OAJA,EAAQ,QAAQ,KAAY,GAAK,GAAW,OACxC,EAAK,KAAK,CAAG,GACN,EACV,GACM,EAAK,QAAQ,MAAQ,CAAC,GAAU,CAAG,CAAC;AAC/C;AACA,eAAsB,GAAM,GAAS,GAAa,GAAS,GAAS,GAAmB;CACnF,IAAI;EACA,IAAM,IAAc,IAAU,GAAW,GAAa,CAAO,IAAI,GAC3D,IAAc,GAAY,CAAW,GACvC;EAQJ,OAPA,AAKI,IALA,IAEU,GAAY,MADA,EAAkB,CAAW,GACpB,CAAW,IAGhC,MAAM,GAAkB,GAAa,GAAa,CAAO,GAEhE,EAAQ,QAAQ,GAAQ,CAAW,GAAG,KAAK,EAAQ,GAAG;CACjE,QACc,CAEd;CACA,OAAO;AACX;AACA,SAAS,GAA0B,GAAK,EAAE,0BAAuB;CAC7D,OAAQ,IAEF,EAAI,QAAQ,KAAiB,MAAU;EAErC,SAAa;GACT,IAAM,CAAC,KAAO,KAAU,GAAsB,KAAK,CAAK,KAAK,CAAC;GAC9D,IAAI,CAAC,GACD,OAAO;GAEX,IAAI,MAAW,GACX,OAAO,QAAQ,EAAI;EAE3B;CACJ,CAAC,IAZC;AAaV;AACA,SAAgB,GAAY,GAAK;CAC7B,OAAO,EAAI,OAAO,EAAS,MAAM;AACrC;AACA,eAAsB,GAAe,GAAS,GAAS,GAAS;CAC5D,IAAI,CAAC,GAAY,CAAO,GACpB,OAAO;CAEX,IAAM,IAAkB,GAA0B,GAAS,CAAO;CAElE,OADa,GAAU,CACb,CAAC,CAAC,QAAQ,GAAU,MAAQ,EAAS,MAAM,MAAQ,GAAM,GAAK,GAAK,GAAS,CAAO,CAAC,GAAG,QAAQ,QAAQ,CAAe,CAAC;AACrI;;;AC5DA,eAAe,GAAU,GAAU,GAAM,GAAS;CAE9C,IAAM,IAAkB,EAAK,OAA+C,iBAAiB,CAAQ;CACrG,IAAI,GAAW;EACX,IAAM,IAAY,MAAM,GAAe,GAAW,MAAM,CAAO;EAE/D,OADA,EAAK,MAAM,YAAY,GAAU,GAAW,EAAK,MAAM,oBAAoB,CAAQ,CAAC,GAC7E;CACX;CACA,OAAO;AACX;AACA,eAAe,GAAgB,GAAY,GAAS;CAIhD,AAFA,MAAO,GAAU,cAAc,GAAY,CAAO,KAC7C,MAAM,GAAU,oBAAoB,GAAY,CAAO,GAC5D,MAAO,GAAU,QAAQ,GAAY,CAAO,KACvC,MAAM,GAAU,gBAAgB,GAAY,CAAO,KACnD,MAAM,GAAU,cAAc,GAAY,CAAO,KACjD,MAAM,GAAU,sBAAsB,GAAY,CAAO;AAClE;AACA,eAAe,GAAe,GAAY,GAAS;CAC/C,IAAM,IAAiB,EAAoB,GAAY,gBAAgB;CACvE,IAAI,EAAE,KAAkB,CAAC,GAAU,EAAW,GAAG,MAC7C,EAAE,EAAoB,GAAY,eAAe,KAC7C,CAAC,GAAU,EAAW,KAAK,OAAO,IACtC;CAEJ,IAAM,IAAM,IAAiB,EAAW,MAAM,EAAW,KAAK,SACxD,IAAU,MAAM,GAAkB,GAAK,GAAY,CAAG,GAAG,CAAO;CACtE,MAAM,IAAI,SAAS,GAAS,MAAW;EAEnC,AADA,EAAW,SAAS,GACpB,EAAW,UAAU,EAAQ,uBACtB,GAAG,MAAe;GACjB,IAAI;IACA,EAAQ,EAAQ,oBAAoB,GAAG,CAAU,CAAC;GACtD,SACO,GAAO;IACV,EAAO,CAAK;GAChB;EACJ,IACE;EACN,IAAM,IAAQ;EAOd,AANA,AACI,EAAM,WAAS,GAEf,EAAM,YAAY,WAClB,EAAM,UAAU,UAEhB,KACA,EAAW,SAAS,IACpB,EAAW,MAAM,KAGjB,EAAW,KAAK,UAAU;CAElC,CAAC;AACL;AACA,eAAe,GAAc,GAAY,GAAS;CAE9C,IAAM,IADW,GAAQ,EAAW,UACX,CAAC,CAAC,KAAK,MAAU,GAAY,GAAO,CAAO,CAAC;CACrE,MAAM,QAAQ,IAAI,CAAS,CAAC,CAAC,WAAW,CAAU;AACtD;AACA,eAAsB,GAAY,GAAY,GAAS;CACnD,AAAI,EAAoB,GAAY,OAAO,MACvC,MAAM,GAAgB,GAAY,CAAO,GACzC,MAAM,GAAe,GAAY,CAAO,GACxC,MAAM,GAAc,GAAY,CAAO;AAE/C;;;ACvEA,SAAgB,GAAW,GAAM,GAAS;CACtC,IAAM,EAAE,aAAU;CAOlB,AANI,EAAQ,oBACR,EAAM,kBAAkB,EAAQ,kBAEhC,EAAQ,UACR,EAAM,QAAQ,GAAG,EAAQ,MAAM,MAE/B,EAAQ,WACR,EAAM,SAAS,GAAG,EAAQ,OAAO;CAErC,IAAM,IAAS,EAAQ;CAMvB,OALI,KAAU,QACV,OAAO,KAAK,CAAM,CAAC,CAAC,SAAS,MAAQ;EACjC,EAAM,KAAO,EAAO;CACxB,CAAC,GAEE;AACX;;;ACfA,IAAM,KAAgB,CAAC;AACvB,eAAe,GAAS,GAAK;CACzB,IAAI,IAAQ,GAAc;CAQ1B,OAPI,MAKJ,IAAQ;EAAE;EAAK,SAAA,OADO,MADJ,MAAM,CAAG,EAAA,CACD,KAAK;CACR,GACvB,GAAc,KAAO,GACd;AACX;AACA,eAAe,GAAW,GAAM,GAAS;CACrC,IAAI,IAAU,EAAK,SACb,IAAW,+BAEX,KADW,EAAQ,MAAM,eAAe,KAAK,CAAC,EAAA,CACzB,IAAI,OAAO,MAAQ;EAC1C,IAAI,IAAM,EAAI,QAAQ,GAAU,IAAI;EAIpC,OAHK,EAAI,WAAW,UAAU,MAC1B,IAAM,IAAI,IAAI,GAAK,EAAK,GAAG,CAAC,CAAC,OAE1B,GAAe,GAAK,EAAQ,mBAAmB,EAAE,iBACpD,IAAU,EAAQ,QAAQ,GAAK,OAAO,EAAO,EAAE,GACxC,CAAC,GAAK,CAAM,EACtB;CACL,CAAC;CACD,OAAO,QAAQ,IAAI,CAAS,CAAC,CAAC,WAAW,CAAO;AACpD;AACA,SAAS,GAAS,GAAQ;CACtB,IAAI,KAAU,MACV,OAAO,CAAC;CAEZ,IAAM,IAAS,CAAC,GAGZ,IAAU,EAAO,QAAQ,wBAAe,EAAE,GAExC,IAAiB,gBAAI,OAAO,oDAAoD,IAAI;CAE1F,SAAa;EACT,IAAM,IAAU,EAAe,KAAK,CAAO;EAC3C,IAAI,MAAY,MACZ;EAEJ,EAAO,KAAK,EAAQ,EAAE;CAC1B;CACA,IAAU,EAAQ,QAAQ,GAAgB,EAAE;CAC5C,IAAM,IAAc,0CAKd,IAAe,gBAAI,OAAO,8GAAkB,IAAI;CAEtD,SAAa;EACT,IAAI,IAAU,EAAY,KAAK,CAAO;EACtC,IAAI,MAAY,MAAM;GAElB,IADA,IAAU,EAAa,KAAK,CAAO,GAC/B,MAAY,MACZ;GAGA,EAAY,YAAY,EAAa;EAE7C,OAEI,EAAa,YAAY,EAAY;EAEzC,EAAO,KAAK,EAAQ,EAAE;CAC1B;CACA,OAAO;AACX;AACA,eAAe,GAAY,GAAa,GAAS;CAC7C,IAAM,IAAM,CAAC,GACP,IAAY,CAAC;CA+CnB,OA7CA,EAAY,SAAS,MAAU;EAC3B,IAAI,cAAc,GACd,IAAI;GACA,GAAQ,EAAM,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,GAAM,MAAU;IACnD,IAAI,EAAK,SAAS,QAAQ,aAAa;KACnC,IAAI,IAAc,IAAQ,GACpB,IAAM,EAAK,MACX,IAAW,GAAS,CAAG,CAAC,CACzB,MAAM,MAAa,GAAW,GAAU,CAAO,CAAC,CAAC,CACjD,MAAM,MAAY,GAAS,CAAO,CAAC,CAAC,SAAS,MAAS;MACvD,IAAI;OACA,EAAM,WAAW,GAAM,EAAK,WAAW,SAAS,IACzC,KAAe,IAChB,EAAM,SAAS,MAAM;MAC/B,SACO,GAAO;OACV,QAAQ,MAAM,wCAAwC;QAClD;QACA;OACJ,CAAC;MACL;KACJ,CAAC,CAAC,CAAC,CACE,OAAO,MAAM;MACd,QAAQ,MAAM,4BAA4B,EAAE,SAAS,CAAC;KAC1D,CAAC;KACD,EAAU,KAAK,CAAQ;IAC3B;GACJ,CAAC;EACL,SACO,GAAG;GACN,IAAM,IAAS,EAAY,MAAM,MAAM,EAAE,QAAQ,IAAI,KAAK,SAAS,YAAY;GAW/E,AAVI,EAAM,QAAQ,QACd,EAAU,KAAK,GAAS,EAAM,IAAI,CAAC,CAC9B,MAAM,MAAa,GAAW,GAAU,CAAO,CAAC,CAAC,CACjD,MAAM,MAAY,GAAS,CAAO,CAAC,CAAC,SAAS,MAAS;IACvD,EAAO,WAAW,GAAM,EAAO,SAAS,MAAM;GAClD,CAAC,CAAC,CAAC,CACE,OAAO,MAAQ;IAChB,QAAQ,MAAM,mCAAmC,CAAG;GACxD,CAAC,CAAC,GAEN,QAAQ,MAAM,kCAAkC,CAAC;EACrD;CAER,CAAC,GACM,QAAQ,IAAI,CAAS,CAAC,CAAC,YAE1B,EAAY,SAAS,MAAU;EAC3B,IAAI,cAAc,GACd,IAAI;GACA,GAAQ,EAAM,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,MAAS;IAC5C,EAAI,KAAK,CAAI;GACjB,CAAC;EACL,SACO,GAAG;GACN,QAAQ,MAAM,sCAAsC,EAAM,QAAQ,CAAC;EACvE;CAER,CAAC,GACM,EACV;AACL;AACA,SAAS,GAAgB,GAAU;CAC/B,OAAO,EACF,QAAQ,MAAS,EAAK,SAAS,QAAQ,cAAc,CAAC,CACtD,QAAQ,MAAS,GAAY,EAAK,MAAM,iBAAiB,KAAK,CAAC,CAAC;AACzE;AACA,eAAe,GAAkB,GAAM,GAAS;CAC5C,IAAI,EAAK,iBAAiB,MACtB,MAAU,MAAM,2CAA2C;CAI/D,OAAO,GAAgB,MADA,GADH,GAAQ,EAAK,cAAc,WACF,GAAG,CAAO,CACxB;AACnC;AACA,SAAS,GAAoB,GAAM;CAC/B,OAAO,EAAK,KAAK,CAAC,CAAC,QAAQ,SAAS,EAAE;AAC1C;AACA,SAAS,GAAa,GAAM;CACxB,IAAM,oBAAQ,IAAI,IAAI;CACtB,SAAS,EAAS,GAAM;EAKpB,CAJmB,EAAK,MAAM,cAAc,iBAAiB,CAAI,CAAC,CAAC,WAAA,CACxD,MAAM,GAAG,CAAC,CAAC,SAAS,MAAS;GACpC,EAAM,IAAI,GAAoB,CAAI,CAAC;EACvC,CAAC,GACD,MAAM,KAAK,EAAK,QAAQ,CAAC,CAAC,SAAS,MAAU;GACzC,AAAI,aAAiB,eACjB,EAAS,CAAK;EAEtB,CAAC;CACL;CAEA,OADA,EAAS,CAAI,GACN;AACX;AACA,eAAsB,GAAc,GAAM,GAAS;CAC/C,IAAM,IAAQ,MAAM,GAAkB,GAAM,CAAO,GAC7C,IAAY,GAAa,CAAI;CASnC,QAAO,MARgB,QAAQ,IAAI,EAC9B,QAAQ,MAAS,EAAU,IAAI,GAAoB,EAAK,MAAM,UAAU,CAAC,CAAC,CAAC,CAC3E,KAAK,MAAS;EACf,IAAM,IAAU,EAAK,mBACf,EAAK,iBAAiB,OACtB;EACN,OAAO,GAAe,EAAK,SAAS,GAAS,CAAO;CACxD,CAAC,CAAC,EAAA,CACc,KAAK,IAAI;AAC7B;AACA,eAAsB,GAAc,GAAY,GAAS;CACrD,IAAM,IAAU,EAAQ,gBAAgB,OAElC,EAAQ,YACJ,OACA,MAAM,GAAc,GAAY,CAAO,IAH3C,EAAQ;CAId,IAAI,GAAS;EACT,IAAM,IAAY,SAAS,cAAc,OAAO,GAC1C,IAAe,SAAS,eAAe,CAAO;EAEpD,AADA,EAAU,YAAY,CAAY,GAC9B,EAAW,aACX,EAAW,aAAa,GAAW,EAAW,UAAU,IAGxD,EAAW,YAAY,CAAS;CAExC;AACJ;;;ACtMA,eAAsB,GAAM,GAAM,IAAU,CAAC,GAAG;CAC5C,IAAM,EAAE,UAAO,cAAW,GAAa,GAAM,CAAO,GAC9C,IAAc,MAAM,GAAU,GAAM,GAAS,EAAI;CAKvD,OAJA,MAAM,GAAc,GAAY,CAAO,GACvC,MAAM,GAAY,GAAY,CAAO,GACrC,GAAW,GAAY,CAAO,GAEvB,MADe,GAAc,GAAY,GAAO,CAAM;AAEjE;AACA,eAAsB,GAAS,GAAM,IAAU,CAAC,GAAG;CAC/C,IAAM,EAAE,UAAO,cAAW,GAAa,GAAM,CAAO,GAE9C,IAAM,MAAM,GAAY,MADZ,GAAM,GAAM,CAAO,CACJ,GAC3B,IAAS,SAAS,cAAc,QAAQ,GACxC,IAAU,EAAO,WAAW,IAAI,GAChC,IAAQ,EAAQ,cAAc,GAAc,GAC5C,IAAc,EAAQ,eAAe,GACrC,IAAe,EAAQ,gBAAgB;CAa7C,OAZA,EAAO,QAAQ,IAAc,GAC7B,EAAO,SAAS,IAAe,GAC1B,EAAQ,iBACT,GAAsB,CAAM,GAEhC,EAAO,MAAM,QAAQ,GAAG,KACxB,EAAO,MAAM,SAAS,GAAG,KACrB,EAAQ,oBACR,EAAQ,YAAY,EAAQ,iBAC5B,EAAQ,SAAS,GAAG,GAAG,EAAO,OAAO,EAAO,MAAM,IAEtD,EAAQ,UAAU,GAAK,GAAG,GAAG,EAAO,OAAO,EAAO,MAAM,GACjD;AACX;;;AChCA,IAAM,KAAW,SAQX,KACJ,kFAUI,KAAmE;CACvE;EAAE,SAAS;EAAM,OAAO;CAAE;CAC1B;EAAE,SAAS;EAAK,OAAO;CAAE;CACzB;EAAE,SAAS;EAAK,OAAO;CAAK;CAC5B;EAAE,SAAS;EAAK,OAAO;CAAI;AAC7B,GAaM,KACJ,0IAEI,KACJ;AAUF,SAAS,GAAa,GAAsB;CAC1C,IAAI,IAAuB,EAAG;CAC9B,OAAO,IAAM;EACX,IAAI,EAAK,aAAa,kBAAkB,GAAG,OAAO;EAClD,IAAO,EAAK;CACd;CACA,OAAO;AACT;AAEA,SAAS,GAAc,GAA6B;CAClD,IAAM,oBAAO,IAAI,IAAa,GACxB,IAAkB,CAAC;CAEzB,SAAS,EAAI,GAAa;EACxB,AAAK,EAAK,IAAI,CAAE,MACd,EAAK,IAAI,CAAE,GACX,EAAK,KAAK,CAAE;CAEhB;CAGA,KAAK,IAAM,KAAM,SAAS,iBAAiB,4CAA4C,GACrF,EAAI,CAAE;CAIR,KAAK,IAAM,KAAM,SAAS,iBAAiB,EAAkB,GAC3D,AAAK,GAAa,CAAE,KAAG,EAAI,CAAE;CAG/B,IAAI,EAAI,gBACN,IAAI;EACF,KAAK,IAAM,KAAM,SAAS,iBAAiB,EAAI,cAAc,GAC3D,AAAK,GAAa,CAAE,KAAG,EAAI,CAAE;CAEjC,SAAS,GAAK;EAGZ,EAAY,GAAK,EAAE,SAAS,6BAA6B,CAAC;CAC5D;CAGF,IAAI,EAAI,aACD,KAAA,IAAM,KAAM,SAAS,iBAAiB,uBAAuB,GAChE,AAAK,GAAa,CAAE,KAAG,EAAI,CAAE;CAIjC,OAAO;AACT;AAEA,SAAS,GAAU,GAAyB;CAC1C,IAAM,IAAO,EAAG,aAAa,OAAO;CAEpC,OADA,EAAG,aAAa,SAAS,IAAO,GAAG,EAAK,GAAG,OAAa,EAAQ,SACnD;EACX,AAAI,MAAS,OACX,EAAG,gBAAgB,OAAO,IAE1B,EAAG,aAAa,SAAS,CAAI;CAEjC;AACF;AAEA,SAAS,GAAY,GAAqB;CACxC,IAAI,EAAG,IAAI,OAAO,IAAI,IAAI,OAAO,EAAG,EAAE;CACtC,IAAM,IAAM,EAAG,QAAQ,YAAY,GAC7B,IAAO,EAAG,aAAa,MAAM,GAC7B,IAAO,EAAG,aAAa,MAAM;CAInC,OAHI,KAAQ,IAAa,GAAG,EAAI,SAAS,EAAK,WAAW,EAAK,MAC1D,IAAa,GAAG,EAAI,SAAS,EAAK,MAClC,IAAa,GAAG,EAAI,SAAS,EAAK,MAC/B;AACT;AASA,eAAsB,GACpB,GACA,GACA,GAC+B;CAC/B,IAAI;EACF,IAAM,IAAI,OAAO,YACX,IAAI,OAAO,aACX,IAAa,KAAK,IAAI,OAAO,kBAAkB,CAAC,GAEhD,IAAW,IAAc,GAAc,CAAW,IAAI,CAAC,GACvD,IAAoB,EAAS,IAAI,EAAW,GAC5C,IAAW,EAAS,IAAI,EAAS,GAEnC;EACJ,IAAI;GACF,IAAS,MAAM,GAAS,SAAS,iBAAiB;IAChD,OAAO;IACP,QAAQ;IACR,WAAW;IACX,iBAAiB;IACjB;IACA,OAAO,GAAqB;KAG1B,OADA,EADI,MAAc,MAAS,KAAa,EAAU,SAAS,CAAI,MAC3D,aAAgB,WAAW,EAAK,aAAa,kBAAkB;IAErE;IACA,kBAAkB;IAGlB,2BAA2B,CAAC;IAC5B,OAAO;KAEL,WAAW,eAAe,OAAO,QAAQ;KACzC,iBAAiB;IACnB;GACF,CAAC;EACH,UAAU;GACR,KAAK,IAAM,KAAW,GAAU,EAAQ;EAC1C;EAEA,IAAI,GAAK;GACP,IAAM,IAAM,EAAO,WAAW,IAAI;GAClC,AAAI,KAAK,GAAQ,GAAK,EAAI,GAAG,EAAI,GAAG,CAAU;EAChD;EAEA,IAAM,IAAO,MAAM,GAAkB,CAAM;EAE3C,OADK,IACE;GAAE;GAAM,eAAe,EAAkB;GAAQ;EAAkB,IADxD;CAEpB,SAAS,GAAK;EAKZ,OADA,EAAY,GAAK,EAAE,SAAS,qBAAqB,CAAC,GAC3C;CACT;AACF;AAEA,SAAS,GAAa,GAA2B,GAAuC;CACtF,OAAO,IAAI,SAAS,MAAY,EAAO,OAAO,GAAS,cAAc,CAAO,CAAC;AAC/E;AAGA,SAAS,GAAU,GAA2B,GAAyC;CACrF,IAAM,IAAS,SAAS,cAAc,QAAQ;CAE9C,AADA,EAAO,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,EAAO,QAAQ,CAAK,CAAC,GAC3D,EAAO,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,EAAO,SAAS,CAAK,CAAC;CAC7D,IAAM,IAAM,EAAO,WAAW,IAAI;CAIlC,OAHK,KACL,EAAI,wBAAwB,QAC5B,EAAI,UAAU,GAAQ,GAAG,GAAG,EAAO,OAAO,EAAO,MAAM,GAChD,KAHU;AAInB;AAOA,eAAe,GAAkB,GAAiD;CAChF,IAAI,IAA0B;CAE9B,KAAK,IAAM,EAAE,YAAS,cAAW,IAAe;EAC9C,IAAM,IAAS,MAAU,IAAI,IAAS,GAAU,GAAQ,CAAK;EAC7D,IAAI,CAAC,GAAQ;EACb,IAAM,IAAO,MAAM,GAAa,GAAQ,CAAO;EAC1C,OACL;OAAI,EAAK,QAAQ,IAAU,OAAO;GAClC,IAAW,KAAY,OAAO,EAAK,OAAO,KAAK,IAAI,GAAU,EAAK,IAAI;EADpC;CAEpC;CAUA,OARA,EACE,gBAAI,MACF,KAAY,OACR,4DACA,oBAAoB,EAAS,8CAA8C,GAAS,EAC1F,GACA,EAAE,SAAS,oBAAoB,CACjC,GACO;AACT;AAIA,SAAS,GAAQ,GAA+B,GAAW,GAAW,GAAoB;CACxF,IAAM,IAAK,GACL,IAAO,KAAK,GACZ,IAAO,IAAO,GACd,IAAK,IAAI,GACT,IAAK,IAAI;CAEf,EAAI,KAAK;CAGT,IAAM,IAAO,IAAI;CAwBjB,AAvBA,EAAI,UAAU,GAEd,EAAI,UAAU,IAAK,GAAM,IAAK,IAAO,GAAM,IAAO,IAAO,GAAG,IAAO,IAAO,GAAG;EAC3E,KAAK,IAAK;EACV,KAAK,IAAK;EACV,KAAK,IAAK;EACV,IAAI,IAAK;CACX,CAAC,GACD,EAAI,YAAY,WAChB,EAAI,KAAK,GAGT,EAAI,UAAU,GACd,EAAI,UAAU,GAAI,IAAK,GAAM,GAAM,GAAM;EAAC,KAAK;EAAI,KAAK;EAAI,KAAK;EAAI,IAAI;CAAE,CAAC,GAC5E,EAAI,YAAY,WAChB,EAAI,KAAK,GAGT,EAAI,UAAU,GACd,EAAI,IAAI,IAAK,GAAM,IAAK,GAAM,IAAI,GAAI,GAAG,KAAK,KAAK,CAAC,GACpD,EAAI,YAAY,WAChB,EAAI,KAAK,GAET,EAAI,QAAQ;AACd;;;AC5PA,IAAM,KAAe,GAAsC;CACzD,MAAM,EACJ,SAAS,GAAG,OAAO;EAAE,MAAM;EAAU,OAAO,EAAE;EAAO,WAAW,EAAE;CAAU,GAC9E;CACA,QAAQ,EAEN,SAAS,GAAG,OAAO;EAAE,MAAM;EAAU,OAAO,EAAE;EAAO,WAAW,EAAE;CAAU,GAC9E;AACF,CAAC,GAQK,KAAkB,MAClB,KAA0B,KAC1B,KAAyB;AAE/B,SAAgB,GAAqB,GAAqC;CACxE,IAAM,CAAC,GAAO,KAAQ,GAAW,IAAc,EAAE,MAAM,OAAO,CAAC;CAyC/D,OAvCA,QAAgB;EACd,IAAI,IAAY,IACZ,IAA8C;EAElD,eAAe,IAAU;GACvB,IAAI;IACF,IAAM,IAAS,MAAM,EAAI,qBAAqB;IAC9C,IAAI,GAAW;IACf,EAAK;KAAE,MAAM;KAAU,OAAO,EAAO;KAAO,WAAW,EAAO;IAAU,CAAC;IACzE,IAAM,IAAiB,KAAK,IAC1B,IACA,EAAO,YAAY,KAAK,IAAI,IAAI,EAClC;IACA,IAAQ,WAAW,GAAS,CAAc;GAC5C,SAAS,GAAK;IACZ,IAAI,GAAW;IAaf,AAJc,GAAmC,SACpC,eACX,EAAY,GAAK,EAAE,SAAS,6BAA6B,CAAC,GAE5D,IAAQ,WAAW,GAAS,EAAsB;GACpD;EACF;EAGA,OADA,EAAQ,SACK;GAEX,AADA,IAAY,IACR,KAAO,aAAa,CAAK;EAC/B;CACF,GAAG,CAAC,GAAK,CAAI,CAAC,GAEP,EAAM,SAAS,WAAW,EAAM,QAAQ;AACjD;;;AC5DA,eAAsB,GAAoB,GAYN;CAClC,IAAI;EACF,IAAM,IAAoB;GACxB,QAAQ;GACR,SAAS;IACP,gBAAgB;IAChB,oBAAoB,EAAK;GAC3B;GACA,QAAQ,GAAe,GAAkB,EAAK,MAAM;EACtD;EACA,IAAI,EAAK,SAAS,WAGhB,AAFA,EAAK,cAAc,WAEnB,EAAK,OAAO;OACP;GACL,IAAI,CAAC,EAAK,cAAc,OAAO;GAC/B,EAAK,OAAO,KAAK,UAAU,EAAE,cAAc,EAAK,aAAa,CAAC;EAChE;EAEA,IAAM,IAAM,MAAM,MAAM,GAAG,EAAK,OAAO,QAAQ,QAAQ,EAAE,EAAE,kBAAkB,CAAI;EACjF,IAAI,CAAC,EAAI,IAAI,OAAO;EACpB,IAAM,IAAQ,MAAM,EAAI,KAAK;EA+B7B,OAvBI,EAAK,SAAS,YAEd,OAAO,EAAK,wBAAyB,YACrC,OAAO,EAAK,yBAA0B,WAE/B,OAEF;GACL,MAAM;GACN,sBAAsB,EAAK;GAC3B,uBAAuB,EAAK;EAC9B,IAKA,OAAO,EAAK,eAAgB,YAC5B,OAAO,EAAK,wBAAyB,YACrC,OAAO,EAAK,gBAAiB,YAC7B,OAAO,EAAK,yBAA0B,WAE/B,OAEF;GACL,MAAM;GACN,aAAa,EAAK;GAClB,sBAAsB,EAAK;GAC3B,cAAc,EAAK;GACnB,uBAAuB,EAAK;EAC9B;CACF,SAAS,GAAK;EAGZ,IAAM,IAAQ,GAAmC;EAIjD,OAHI,MAAS,gBAAgB,MAAS,eACpC,EAAY,GAAK,EAAE,SAAS,gBAAgB,CAAC,GAExC;CACT;AACF;;;AC3FA,IAAM,KAAkB,KAClB,KAAe;AAErB,SAAgB,GACd,GACA,GACA,GACA,GACA,GACM;CACN,IAAM,IAAa,EAAS,SAAS,YAC/B,IAAU,IAAa,EAAS,SAAS,UAAU,KAAA,GACnD,IAAe,IAAa,EAAS,SAAS,eAAe,KAAA,GAC7D,IAAa,IAAa,EAAS,SAAS,wBAAwB,KAAA,GACpE,IAAY,IAAa,EAAS,SAAS,iBAAiB,KAAA;CAElE,QAAgB;EAKd,IAJI,CAAC,KAAc,KAAc,QAAQ,KAAa,QAGlD,MAAY,kBAAkB,KAAgB,QAC9C,MAAY,aAAa,MAAY,gBAAgB;EAEzD,IAAM,IAAM,KAAK,IAAI;EACrB,IAAI,KAAc,GAAK;GAErB,EAAU;GACV;EACF;EAEA,IAAM,IAAQ,KAAK,IAAI,IAAc,IAAY,KAAkB,CAAG,GAChE,IAAa,IAAI,gBAAgB,GAEjC,IAAQ,OAAO,WAAW,YAAY;GAC1C,IAAM,IAAO,MAAM,GAAoB;IACrC;IACA;IACA,MAAM;IACN;IACA,QAAQ,EAAW;GACrB,CAAC;GACG,OAAW,OAAO,SACtB;QAAI,CAAC,GAAM;KACT,EAAU;KACV;IACF;IACI,EAAS,SAAS,eAClB,EAAK,SAAS,YAGhB,EAAY;KACV,GAAG,EAAS;KACZ,gBAAgB,EAAK;KACrB,uBAAuB,EAAK;IAC9B,CAAC,IAED,EAAY;KACV,GAAG,EAAS;KACZ,OAAO,EAAK;KACZ,gBAAgB,EAAK;KACrB,cAAc,EAAK;KACnB,uBAAuB,EAAK;IAC9B,CAAC;GAjBH;EAmBF,GAAG,CAAK;EAER,aAAa;GAEX,AADA,OAAO,aAAa,CAAK,GACzB,EAAW,MAAM;EACnB;CAKF,GAAG;EAAC;EAAY;EAAS;EAAc;EAAY;EAAW;EAAQ;CAAM,CAAC;AAC/E;;;ACxFA,SAAgB,EAAG,GAAG,GAAuB;CAC3C,OAAO,EAAQ,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;AACzC;AAWA,SAAgB,KAA+C;CAI7D,OAFE,OAAO,YAAc,OACrB,kBAAkB,KAAK,UAAU,YAAY,UAAU,SAAS,IACnD;EAAE,KAAK;EAAK,OAAO;CAAI,IAAI;EAAE,KAAK;EAAQ,OAAO;CAAQ;AAC1E;;;ACpB4b,IAAA,KAAE;AAAI,MAAM;AAAQ,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;CAAC,AAAI,MAAE,CAAC;CAAG,IAAI,GAAE,GAAE,IAAE;CAAE,IAAG,SAAQ,GAAE,KAAI,KAAK,IAAE,CAAC,GAAE,GAAE,AAAO,KAAP,QAAS,IAAE,EAAE,KAAG,EAAE,KAAG,EAAE;CAAG,IAAI,IAAE;EAAC,MAAK;EAAE,OAAM;EAAE,KAAI;EAAE,KAAI;EAAE,KAAI;EAAK,IAAG;EAAK,KAAI;EAAE,KAAI;EAAK,KAAI;EAAK,aAAY,KAAK;EAAE,KAAI,EAAE;EAAE,KAAI;EAAG,KAAI;EAAE,UAAS;EAAE,QAAO;CAAC;CAAE,IAAe,OAAO,KAAnB,eAAuB,IAAE,EAAE,eAAc,KAAI,KAAK,GAAE,AAAS,EAAE,OAAX,KAAK,MAAW,EAAE,KAAG,EAAE;CAAI,OAAOE,EAAE,SAAOA,EAAE,MAAM,CAAC,GAAE;AAAC;;;ACI3yB,SAAgB,GAAS,EAAE,UAAO,MAAyB;CACzD,OACE,kBAAC,OAAD;EAAK,OAAO;EAAM,QAAQ;EAAM,SAAQ;EAAc,MAAK;EAAe,eAAA;EACxE,UAAA,kBAAC,QAAD,EAAM,GAAE,++BAAg/B,CAAA;CACr/B,CAAA;AAET;AAEA,SAAgB,GAAU,EAAE,UAAO,MAAyB;CAC1D,OACE,kBAAC,OAAD;EAAK,OAAO;EAAM,QAAQ;EAAM,SAAQ;EAAY,MAAK;EACvD,UAAA,kBAAC,QAAD,EAAM,GAAE,qLAAsL,CAAA;CAC3L,CAAA;AAET;AAUA,SAAgB,GAAgB,EAAE,UAAO,MAAyB;CAChE,OACE,kBAAC,OAAD;EAAK,OAAO;EAAM,QAAQ;EAAM,SAAQ;EAAY,MAAK;EAAe,eAAA;EACtE,UAAA,kBAAC,QAAD,EAAM,GAAE,yIAA0I,CAAA;CAC/I,CAAA;AAET;AAEA,SAAgB,GAAa,EAAE,UAAO,MAAyB;CAC7D,OACE,kBAAC,OAAD;EAAK,OAAO;EAAM,QAAQ;EAAM,SAAQ;EAAY,MAAK;EACvD,UAAA,kBAAC,QAAD,EAAM,GAAE,uIAAwI,CAAA;CAC7I,CAAA;AAET;AAEA,SAAgB,GAAU,EAAE,UAAO,MAAyB;CAC1D,OACE,kBAAC,OAAD;EACE,OAAM;EACN,OAAO;EACP,QAAQ;EACR,MAAK;EACL,SAAQ;EAER,UAAA,kBAAC,QAAD,EAAM,GAAE,kPAAwP,CAAA;CAC7P,CAAA;AAET;AAEA,SAAgB,GAAW,EAAE,UAAO,MAAyB;CAC3D,OACE,kBAAC,OAAD;EAAK,OAAO;EAAM,QAAQ;EAAM,SAAQ;EAAY,MAAK;EAAe,eAAA;EACtE,UAAA,kBAAC,QAAD;GACE,aAAU;GACV,GAAE;GACF,aAAU;EACX,CAAA;CACE,CAAA;AAET;AAEA,SAAgB,GAAS,EAAE,UAAO,MAAyB;CACzD,OACE,kBAAC,OAAD;EAAK,OAAO;EAAM,QAAQ;EAAM,SAAQ;EAAY,MAAK;EACvD,UAAA,kBAAC,QAAD,EAAM,GAAE,4OAA6O,CAAA;CAClP,CAAA;AAET;AAEA,SAAgB,GAAU,EAAE,UAAO,MAAyB;CAC1D,OACE,kBAAC,OAAD;EAAK,OAAO;EAAM,QAAQ;EAAM,SAAQ;EAAc,MAAK;EAAe,eAAA;EACxE,UAAA,kBAAC,QAAD,EAAM,GAAE,uVAA6V,CAAA;CAClW,CAAA;AAET;AAIA,SAAS,EAAO,EAAE,UAAO,IAAI,eAA4D;CACvF,OACE,kBAAC,OAAD;EACE,OAAO;EACP,QAAQ;EACR,SAAQ;EACR,MAAK;EACL,QAAO;EACP,gBAAc;EACd,kBAAe;EACf,mBAAgB;EAChB,eAAA;EAEC;CACE,CAAA;AAET;AAEA,SAAgB,GAAY,EAAE,UAAO,MAAyB;CAC5D,OACE,kBAAC,GAAD;EAAc;EACZ,UAAA,kBAAC,QAAD,EAAM,GAAE,iLAAkL,CAAA;CACpL,CAAA;AAEZ;AAEA,SAAgB,GAAU,EAAE,UAAO,MAAyB;CAC1D,OACE,kBAAC,GAAD;EAAc;EAAd,UAAA,CACE,kBAAC,QAAD,EAAM,GAAE,2BAA4B,CAAA,GACpC,kBAAC,QAAD,EAAM,GAAE,6GAA8G,CAAA,CAChH;;AAEZ;AAEA,SAAgB,GAAQ,EAAE,UAAO,MAAyB;CACxD,OACE,kBAAC,GAAD;EAAc;EAAd,UAAA,CACE,kBAAC,QAAD,EAAM,GAAE,mDAAoD,CAAA,GAC5D,kBAAC,UAAD;GAAQ,IAAG;GAAK,IAAG;GAAK,GAAE;EAAO,CAAA,CAC3B;;AAEZ;AAEA,SAAgB,GAAW,EAAE,UAAO,MAAyB;CAC3D,OACE,kBAAC,GAAD;EAAc;EAAd,UAAA;GACE,kBAAC,QAAD,EAAM,GAAE,gFAAiF,CAAA;GACzF,kBAAC,QAAD,EAAM,GAAE,2EAA4E,CAAA;GACpF,kBAAC,QAAD,EAAM,GAAE,aAAc,CAAA;GACtB,kBAAC,QAAD,EAAM,GAAE,mCAAoC,CAAA;EACtC;;AAEZ;AAEA,SAAgB,GAAS,EAAE,UAAO,MAAyB;CACzD,OACE,kBAAC,GAAD;EAAc;EACZ,UAAA,kBAAC,QAAD,EAAM,GAAE,0BAA2B,CAAA;CAC7B,CAAA;AAEZ;AAEA,SAAgB,GAAQ,EAAE,UAAO,MAAyB;CACxD,OACE,kBAAC,GAAD;EAAc;EAAd,UAAA,CACE,kBAAC,UAAD;GAAQ,IAAG;GAAK,IAAG;GAAK,GAAE;EAAK,CAAA,GAC/B,kBAAC,QAAD,EAAM,GAAE,qHAAsH,CAAA,CACxH;;AAEZ;AAEA,SAAgB,GAAS,EAAE,UAAO,MAAyB;CACzD,OACE,kBAAC,GAAD;EAAc;EACZ,UAAA,kBAAC,QAAD,EAAM,GAAE,mDAAoD,CAAA;CACtD,CAAA;AAEZ;AAEA,SAAgB,GAAY,EAAE,UAAO,MAAyB;CAC5D,OACE,kBAAC,GAAD;EAAc;EAAd,UAAA,CACE,kBAAC,QAAD;GAAM,GAAE;GAAI,GAAE;GAAI,OAAM;GAAK,QAAO;GAAK,IAAG;EAAK,CAAA,GACjD,kBAAC,QAAD,EAAM,GAAE,kBAAmB,CAAA,CACrB;;AAEZ;AAEA,SAAgB,GAAW,EAAE,UAAO,MAAyB;CAC3D,OACE,kBAAC,GAAD;EAAc;EACZ,UAAA,kBAAC,QAAD,EAAM,GAAE,kDAAmD,CAAA;CACrD,CAAA;AAEZ;AAEA,SAAgB,GAAa,EAAE,UAAO,MAAyB;CAC7D,OACE,kBAAC,GAAD;EAAc;EAAd,UAAA,CACE,kBAAC,QAAD;GAAM,GAAE;GAAI,GAAE;GAAI,OAAM;GAAK,QAAO;GAAK,IAAG;EAAK,CAAA,GACjD,kBAAC,QAAD,EAAM,GAAE,qEAAsE,CAAA,CACxE;;AAEZ;AAMA,SAAgB,GAAU,EAAE,UAAO,MAAyB;CAC1D,OACE,kBAAC,GAAD;EAAc;EAAd,UAAA,CACE,kBAAC,QAAD,EAAM,GAAE,4CAA6C,CAAA,GACrD,kBAAC,QAAD,EAAM,GAAE,yBAA0B,CAAA,CAC5B;;AAEZ;AAEA,SAAgB,GAAW,EAAE,UAAO,MAAyB;CAC3D,OACE,kBAAC,GAAD;EAAc;EAAd,UAAA,CACE,kBAAC,QAAD,EAAM,GAAE,0CAA2C,CAAA,GACnD,kBAAC,QAAD,EAAM,GAAE,yBAA0B,CAAA,CAC5B;;AAEZ;AAEA,SAAgB,GAAS,EAAE,UAAO,MAAyB;CACzD,OACE,kBAAC,GAAD;EAAc;EAAd,UAAA,CACE,kBAAC,UAAD;GAAQ,IAAG;GAAK,IAAG;GAAI,GAAE;EAAK,CAAA,GAC9B,kBAAC,QAAD,EAAM,GAAE,uBAAwB,CAAA,CAC1B;;AAEZ;AAOA,SAAgB,GAAQ,EAAE,UAAO,MAAyB;CACxD,OACE,kBAAC,GAAD;EAAc;EAAd,UAAA;GACE,kBAAC,QAAD,EAAM,GAAE,YAAa,CAAA;GACrB,kBAAC,QAAD;IAAM,GAAE;IAAI,GAAE;IAAI,OAAM;IAAK,QAAO;IAAK,IAAG;GAAK,CAAA;GACjD,kBAAC,QAAD,EAAM,GAAE,UAAW,CAAA;GACnB,kBAAC,QAAD,EAAM,GAAE,WAAY,CAAA;GACpB,kBAAC,QAAD,EAAM,GAAE,WAAY,CAAA;GACpB,kBAAC,QAAD,EAAM,GAAE,UAAW,CAAA;EACb;;AAEZ;AAEA,SAAgB,GAAa,EAAE,UAAO,MAAyB;CAC7D,OACE,kBAAC,GAAD;EAAc;EAAd,UAAA;GACE,kBAAC,QAAD,EAAM,GAAE,YAAa,CAAA;GACrB,kBAAC,QAAD,EAAM,GAAE,cAAe,CAAA;GACvB,kBAAC,QAAD,EAAM,GAAE,2DAA4D,CAAA;EAC9D;;AAEZ;;;ACnOA,SAAgB,GAAa,EAC3B,aACA,aACA,gBACA,iBACA,iBACA,aACA,cACA,iBAUC;CACD,IAAM,CAAC,GAAM,KAAW,EAAS,EAAK,GAChC,CAAC,GAAe,KAAoB,EAAS,EAAK,GAClD,CAAC,GAAgB,KAAqB,EAAS,EAAK,GACpD,IAAe,EAAuB,IAAI;CAoBhD,AAlBA,QAAgB;EACd,IAAI,CAAC,GAAM;EACX,SAAS,EAAW,GAAe;GACjC,IAAM,IAAY,EAAa;GAC1B,MACA,EAAE,aAAa,CAAC,CAAC,SAAS,CAAS,KAAG,EAAQ,EAAK;EAC1D;EACA,SAAS,EAAM,GAAkB;GAC/B,AAAI,EAAE,QAAQ,YAAU,EAAQ,EAAK;EACvC;EAGA,OAFA,SAAS,iBAAiB,SAAS,GAAY,EAAI,GACnD,SAAS,iBAAiB,WAAW,CAAK,SAC7B;GAEX,AADA,SAAS,oBAAoB,SAAS,GAAY,EAAI,GACtD,SAAS,oBAAoB,WAAW,CAAK;EAC/C;CACF,GAAG,CAAC,CAAI,CAAC,GAET,QAAgB;EACd,AAAK,MACH,EAAiB,EAAK,GACtB,EAAkB,EAAK;CAE3B,GAAG,CAAC,CAAI,CAAC;CAET,IAAM,IAAO,GAAc,CAAQ,GAC7B,IAAW,GAAa,CAAI,GAC5B,IAAa,EAAS,SAAS,YAC/B,IAAQ,EAAS,SAAS,aAAa,EAAS,SAAS,QAAQ,KAAA,GAIjE,CAAC,GAAa,KAAkB,EAAwB,IAAI,GAC5D,IAAY,KAAc,KAAS,QAAQ,MAAgB,GAC3D,IAAQ,IAAa,EAAS,SAAS,QAAQ,MAE/C,IACJ,MAAa,gBACT,mBACA,MAAa,kBACX,qBACA;CAER,OACE,kBAAC,OAAD;EAAK,KAAK;EAAc,OAAO;GAAE,UAAU;GAAY,SAAS;EAAc;EAA9E,UAAA,CACE,kBAAC,UAAD;GACE,MAAK;GACL,OAAM;GACN,aAAU;GACV,WAAS,IAAO,SAAS,KAAA;GACzB,aAAW,IAAa,KAAA,IAAY;GACpC,iBAAc;GACd,iBAAe;GACf,cAAY,IAAa,gBAAgB,KAAQ,UAAU;GAC3D,OAAO,MAAS,IAAa,YAAY;GACzC,UAAU,MAAM;IAGd,AAFA,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAClB,GAAS,MAAM,CAAC,CAAC;GACnB;GAdF,UAAA,CAgBE,kBAAC,QAAD;IAAM,OAAO,EAAG,oBAAoB,CAAC,KAAc,SAAS;IAAG,eAAY;IACxE,UAAA,IACC,kBAAC,OAAD;KACE,OAAM;KACN,KAAK;KACL,KAAI;KACJ,UAAS;KACT,gBAAe;KACf,eAAe,EAAe,CAAK;IACpC,CAAA,IACC,KAAc,IAGhB,kBAAC,QAAD;KAAM,OAAM;KAA0B,UAAA;IAAe,CAAA,IAErD,kBAAC,IAAD,EAAU,MAAM,GAAK,CAAA;GAEnB,CAAA,GACL,KAAc,IAAO,kBAAC,QAAD;IAAM,OAAM;IAAkB,UAAA;GAAW,CAAA,IAAI,IAC7D;EAEP,CAAA,GAAA,IACC,kBAAC,OAAD;GAAK,OAAO,EAAG,cAAc,CAAW;GAAG,YAAS;GAAW,MAAK;GACjE,UAAA,IACC,kBAAA,GAAA,EAAA,UAAA;IACE,kBAAC,OAAD;KAAK,OAAM;KAAX,UAAA,CACE,kBAAC,QAAD;MAAM,OAAM;MAAM,UAAA,KAAQ;KAAgB,CAAA,GACzC,IAAQ,kBAAC,QAAD;MAAM,OAAM;MAAM,UAAA;KAAY,CAAA,IAAI,IACxC;;IACJ,IACC,kBAAC,KAAD;KACE,MAAK;KACL,OAAM;KACN,MAAM;KACN,QAAO;KACP,KAAI;KACJ,eAAe,EAAQ,EAAK;KAN9B,UAAA,CAQE,kBAAC,QAAD;MAAM,OAAM;MACV,UAAA,kBAAC,IAAD,EAAc,MAAM,GAAK,CAAA;KACrB,CAAA,GACN,kBAAC,QAAD;MAAM,OAAM;MAAM,UAAA;KAAa,CAAA,CAC9B;IACD,CAAA,IAAA;IACJ,kBAAC,UAAD;KACE,MAAK;KACL,MAAK;KACL,OAAO,EAAG,mBAAmB,KAAkB,WAAW;KAC1D,UAAU;KACV,eAAe;MACb,AAAI,KACF,EAAQ,EAAK,GACb,EAAU,KAEV,EAAkB,EAAI;KAE1B;KAZF,UAAA,CAcE,kBAAC,QAAD;MAAM,OAAM;MACV,UAAA,kBAAC,IAAD,EAAY,MAAM,GAAK,CAAA;KACnB,CAAA,GACN,kBAAC,QAAD;MAAM,OAAM;MACT,UAAA,IACG,iBACA,IACE,mCACA;KACF,CAAA,CACA;;GACR,EAAA,CAAA,IAEF,kBAAC,OAAD;IAAK,OAAM;IAAX,UAAA;KACE,kBAAC,OAAD;MAAK,OAAM;MAAI,UAAA;KAAsB,CAAA;KACrC,kBAAC,OAAD;MAAK,OAAM;MAAM,UAAA;KAEZ,CAAA;KACL,kBAAC,UAAD;MACE,MAAK;MACL,UAAU;MACV,eAAe;OAGb,AADA,EAAQ,EAAK,GACb,EAAS;MACX;MAPF,UAAA,CASE,kBAAC,IAAD,EAAW,MAAM,GAAK,CAAA,GACtB,kBAAC,QAAD,EAAA,UAAO,IAAc,gBAAgB,UAAgB,CAAA,CAC/C;;KACR,kBAAC,UAAD;MACE,MAAK;MACL,OAAO,EAAG,mBAAmB,KAAiB,WAAW;MACzD,eAAe;OACb,AAAI,KACF,EAAQ,EAAK,GACb,EAAW,KAEX,EAAiB,EAAI;MAEzB;MACA,OAAO,EAAE,WAAW,MAAM;MAE1B,UAAA,kBAAC,QAAD;OAAM,OAAM;OACT,UAAA,IACG,mDACA;MACA,CAAA;KACA,CAAA;IACL;;EAEJ,CAAA,IACH,IACD;;AAET;AAEA,SAAS,GAAa,GAAoC;CAIxD,OAHK,KACS,EAAK,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,GAAG,CAChC,CAAA,CAAM,KAAK,MAAM,EAAE,EAAE,EAAE,YAAY,KAAK,EAAE,CAAC,CAAC,KAAK,EAC1D,KAHW;AAIpB;;;ACtLA,SAAgB,GAAQ,GAAkC;CAExD,IAAM,IAAU,EAAO,CAAI;CAC3B,EAAQ,UAAU;CAElB,IAAM,CAAC,GAAY,KAAiB,EAAS,EAAK;CAkFlD,OAAO;EAAE,eAhFa,GAAa,MAAoB;GACrD,IAAM,IAAI,EAAQ;GAIlB,IAHI,EAAE,kBAAgB,EAAE,eAAe,GACnC,EAAE,mBAAiB,EAAE,gBAAgB,GACrC,EAAE,WAAW,KACb,EAAE,eAAe,CAAC,EAAE,YAAY,CAAC,GAAG;GAExC,IAAM,IAAS,EAAE;GACjB,IAAI,CAAC,GAAQ;GAIb,IAAM,KADS,EAAE,WAAW,WAAW,EAAA,CACnB,sBAAsB,GACpC,IAAS,EAAE,SACX,IAAS,EAAE,SACX,IAAW,EAAK,MAChB,IAAU,EAAK,KACf,IAAI,EAAK,OACT,IAAI,EAAK,QACT,IAAY,EAAE,aAAa,GAC3B,IAAS,EAAE,UAAU,GACrB,IAAY,EAAE,WAChB,IAAU,IACV,IAAmD;GAEvD,IAAI;IACF,EAAO,kBAAkB,CAAS;GACpC,QAAQ,CAER;GAEA,SAAS,IAAW;IAClB,IAAI;KACF,GAAQ,sBAAsB,CAAS;IACzC,QAAQ,CAER;IAIA,AAHA,GAAQ,oBAAoB,eAAe,CAAM,GACjD,GAAQ,oBAAoB,aAAa,CAAW,GACpD,GAAQ,oBAAoB,iBAAiB,CAAe,GAC5D,EAAc,EAAK;GACrB;GAEA,SAAS,EAAO,GAAkB;IAChC,IAAI,EAAG,cAAc,GAAW;IAChC,IAAM,IAAK,EAAG,UAAU,GAClB,IAAK,EAAG,UAAU;IACxB,IAAI,CAAC,GAAS;KACZ,IAAI,KAAK,IAAI,CAAE,IAAI,KAAK,IAAI,CAAE,IAAI,GAAW;KAG7C,AAFA,IAAU,IACV,EAAc,EAAI,GAClB,EAAQ,QAAQ,UAAU;IAC5B;IACA,IAAM,IAAU,KAAK,IAAI,GAAQ,OAAO,aAAa,IAAI,CAAM,GACzD,IAAS,KAAK,IAAI,GAAQ,OAAO,cAAc,IAAI,CAAM,GACzD,IAAS;KACb,MAAM,GAAM,IAAW,GAAI,GAAQ,CAAO;KAC1C,KAAK,GAAM,IAAU,GAAI,GAAQ,CAAM;IACzC;IAEA,AADA,IAAa,GACb,EAAQ,QAAQ,OAAO,CAAM;GAC/B;GAEA,SAAS,EAAY,GAAkB;IACjC,EAAG,cAAc,MACrB,EAAS,GACL,KAAW,KAAY,EAAQ,QAAQ,QAAQ,GAAY,CAAE;GACnE;GAEA,SAAS,EAAgB,GAAkB;IACrC,EAAG,cAAc,MACrB,EAAS,GACT,EAAQ,QAAQ,WAAW;GAC7B;GAIA,AAFA,EAAO,iBAAiB,eAAe,CAAM,GAC7C,EAAO,iBAAiB,aAAa,CAAW,GAChD,EAAO,iBAAiB,iBAAiB,CAAe;EAC1D,GAAG,CAAC,CAEK;EAAe;CAAW;AACrC;AAEA,SAAS,GAAM,GAAe,GAAa,GAAqB;CAC9D,OAAO,KAAK,IAAI,GAAK,KAAK,IAAI,GAAK,CAAK,CAAC;AAC3C;;;ACxIA,IAAM,KAAqB;CACzB;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,GAAG;AAWV,SAAgB,GAAa,GAA6B,GAAwB;CAChF,QAAgB;EACd,IAAI,CAAC,GAAS;EACd,IAAM,IAAO,EAAI;EACjB,IAAI,CAAC,GAAM;EAEX,SAAS,EAAM,GAAkB;GAC/B,IAAI,EAAE,QAAQ,OAAO;GACrB,IAAM,IAAa,MAAM,KAAK,EAAM,iBAA8B,EAAkB,CAAC,GAC/E,IAAQ,EAAW,IACnB,IAAO,EAAW,EAAW,SAAS;GAC5C,IAAI,CAAC,KAAS,CAAC,GAAM;GAErB,IAAM,IAAI,EAAM,YAAY,GACtB,IAAS,aAAa,aAAa,EAAE,gBAAgB,SAAS;GAEpE,CAAI,EAAE,WAAW,MAAW,IAAQ,MAAW,OAC7C,EAAE,eAAe,IACf,EAAE,WAAW,IAAO,EAAA,CAAO,MAAM;EAEvC;EAGA,OADA,EAAK,iBAAiB,WAAW,CAAK,SACzB,EAAK,oBAAoB,WAAW,CAAK;CACxD,GAAG,CAAC,GAAK,CAAO,CAAC;AACnB;;;AChCA,SAAgB,GAAa,GAAkC;CAC7D,IAAM,CAAC,GAAK,KAAU,EAAwB,IAAI;CAYlD,OAVA,QAAgB;EACd,IAAI,CAAC,GAAM;GACT,EAAO,IAAI;GACX;EACF;EACA,IAAM,IAAO,IAAI,gBAAgB,CAAI;EAErC,OADA,EAAO,CAAI,SACE,IAAI,gBAAgB,CAAI;CACvC,GAAG,CAAC,CAAI,CAAC,GAEF;AACT;;;ACXA,SAAgB,GAAa,EAC3B,cACA,kBAAe,IACf,iBAAc,IACd,aACA,aACA,eASC;CACD,IAAM,CAAC,GAAM,KAAW,EAAS,EAAE,GAC7B,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,IAAM,EAAyB,IAAI;CAEzC,QAAgB;EACd,EAAI,SAAS,MAAM;CACrB,GAAG,CAAC,CAAC;CAEL,SAAS,EAAa,GAAW;EAC/B,GAAG,eAAe;EAClB,IAAM,IAAc,EAAK,KAAK;EAC1B,CAAC,KAAe,KAAa,KAEjC,EAAS,GADY,EAAM,KACL,KAAgB,KAAA,CAAS;CACjD;CAEA,IAAM,IAAgB,KAAa;CAEnC,OACE,kBAAC,QAAD;EAAM,OAAM;EAAuB,UAAU;EAA7C,UAAA;GACG,IACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,UAAD;IACE,MAAK;IACL,OAAM;IACN,SAAS;IACT,UAAU,KAAa;IAEtB,UAAA,IAAc,gBAAgB;GACzB,CAAA,GACR,kBAAC,KAAD;IAAG,OAAM;IAAwB,UAAA;GAAyB,CAAA,CAC1D,EAAA,CAAA,IAEF,kBAAC,KAAD;IAAG,OAAM;IAAiB,UAAA;GAA0B,CAAA;GAEtD,kBAAC,SAAD;IACO;IACL,OAAM;IACN,MAAK;IACL,MAAK;IACL,aAAY;IACZ,OAAO;IACP,WAAW;IACX,cAAa;IACb,UAAU,MAAM,EAAS,EAAE,cAAmC,KAAK;IACnE,UAAU;IACV,kBAAA;GACD,CAAA;GACD,kBAAC,SAAD;IACE,OAAM;IACN,MAAK;IACL,MAAK;IACL,aAAY;IACZ,OAAO;IACP,WAAW;IACX,cAAa;IACb,UAAU,MAAM,EAAU,EAAE,cAAmC,KAAK;IACpE,UAAU;IACV,kBAAA;GACD,CAAA;GACA,IACC,kBAAC,KAAD;IAAG,OAAM;IAAuB,MAAK;IAAS,aAAU;IAAS,UAAA;GAE9D,CAAA,IACD;GACJ,kBAAC,OAAD;IAAK,OAAM;IAAX,UAAA,CACE,kBAAC,UAAD;KACE,MAAK;KACL,OAAM;KACN,SAAS;KACT,UAAU;KACX,UAAA;IAEO,CAAA,GACR,kBAAC,UAAD;KACE,MAAK;KACL,OAAM;KACN,UAAU,CAAC,EAAK,KAAK,KAAK;KAC3B,UAAA;IAEO,CAAA,CACL;;EACD;;AAEV;;;AC1FA,IAAa,KAAmB,uBAMnB,KAAoB,4BAQ3B,qBAAa,IAAI,IAAI;CAAC;CAAO;CAAK;CAAM;CAAc;AAAK,CAAC,GAE5D,KAAY,GACZ,KAAe;AAKrB,SAAgB,GAAoB,GAA2B;CAC7D,IAAI,IAAM,IAEJ,KAAS,MAAiB;EAC9B,IAAM,IAAW,EAAO;EACxB,KAAK,IAAI,IAAI,GAAG,IAAI,EAAS,QAAQ,KAAK;GACxC,IAAM,IAAQ,EAAS;GACvB,IAAI,CAAC,GAAO;GAEZ,IAAI,EAAM,aAAa,IAAW;IAChC,KAAQ,EAAe;IACvB;GACF;GACA,IAAI,EAAM,aAAa,IAAc;GACrC,IAAM,IAAK,GAEL,IAAM,EAAG,aAAa,EAAgB;GAC5C,IAAI,GAAK;IACP,IAAM,IAAO,GAAS,CAAE;IACxB,KAAO,GAAiB;KAAE,QAAQ;KAAK;IAAK,CAAC,KAAK,IAAI;IACtD;GACF;GAEA,IAAI,EAAG,YAAY,MAAM;IAIvB,CAD2B,MAAW,KAAQ,MAAM,EAAS,SAAS,OAC7C,KAAO;IAChC;GACF;GAGA,AADI,GAAW,IAAI,EAAG,OAAO,KAAK,MAAQ,MAAM,CAAC,EAAI,SAAS,IAAI,MAAG,KAAO,OAC5E,EAAM,CAAE;EACV;CACF;CAGA,OADA,EAAM,CAAI,GACH;AACT;AAEA,SAAS,GAAS,GAAyB;CAGzC,OAFiB,EAAG,aAAa,EAC7B,MACI,EAAG,eAAe,GAAA,CAAI,QAAQ,MAAM,EAAE;AAChD;AAIA,SAAgB,GACd,GACA,GACA,GACa;CACb,IAAM,IAAO,EAAI,cAAc,MAAM;CAQrC,OAPA,EAAK,YAAY,GAGjB,EAAK,aAAa,mBAAmB,OAAO,GAC5C,EAAK,aAAa,IAAkB,EAAO,MAAM,GACjD,EAAK,aAAa,IAAmB,EAAO,IAAI,GAChD,EAAK,cAAc,IAAI,EAAO,QACvB;AACT;AAMA,SAAgB,GACd,GACA,GACA,GACkB;CAClB,IAAM,IAAO,EAAI,uBAAuB;CACxC,KAAK,IAAM,KAAS,GAAmB,CAAI,GAAG;EAC5C,IAAI,EAAM,SAAS,QAAQ;GACzB,AAAI,EAAM,SAAO,EAAK,YAAY,EAAI,eAAe,EAAM,KAAK,CAAC;GACjE;EACF;EACA,EAAK,YAAY,GAAkB,GAAK;GAAE,QAAQ,EAAM;GAAQ,MAAM,EAAM;EAAK,GAAG,CAAS,CAAC;CAChG;CACA,OAAO;AACT;AAYA,SAAS,GAAa,GAAqC;CACzD,IAAM,IAAQ,EAAK,YAAY;CAE/B,OADI,OAAO,EAAM,gBAAiB,aAAmB,EAAM,aAAa,IACjE,EAAK,cAAc,aAAa;AACzC;AAQA,SAAS,GAAQ,GAAiC;CAChD,IAAM,IAAM,GAAa,CAAI;CAC7B,IAAI,CAAC,KAAO,EAAI,eAAe,KAAK,CAAC,EAAI,aAAa,OAAO;CAC7D,IAAM,IAAO,EAAI;CAGjB,OAFI,CAAC,KAAQ,EAAK,aAAa,MAAa,CAAC,EAAK,SAAS,CAAI,KAC3D,GAAa,GAAM,CAAI,IAAU,OAC9B;EAAQ;EAAc,QAAQ,EAAI;CAAY;AACvD;AAGA,SAAS,GAAa,GAAY,GAAuC;CACvE,IAAI,IAAmB;CACvB,OAAO,KAAO,MAAQ,IAAM;EAC1B,IAAI,EAAI,aAAa,MAAiB,EAAoB,aAAA,qBAA6B,GACrF,OAAO;EAET,IAAM,EAAI;CACZ;CACA,OAAO;AACT;AASA,SAAS,GAAoB,GAAyB;CACpD,IAAM,IAAM,GAAa,CAAI;CAC7B,IAAI,CAAC,KAAO,EAAI,eAAe,KAAK,CAAC,EAAI,aAAa;CACtD,IAAM,IAAO,EAAI;CACjB,IAAI,CAAC,KAAQ,CAAC,EAAK,SAAS,CAAI,GAAG;CACnC,IAAM,IAAO,GAAa,GAAM,CAAI;CACpC,IAAI,CAAC,GAAM;CAEX,IAAI,IAAQ,EAAK;CAKjB,CAJI,CAAC,KAAS,EAAM,aAAa,QAC/B,IAAQ,EAAK,cAAc,eAAe,EAAE,GAC5C,EAAK,YAAY,aAAa,GAAO,EAAK,WAAW,IAEvD,GAAS,GAAM,GAAO,CAAC;AACzB;AAEA,SAAS,GAAS,GAAmB,GAAY,GAAsB;CACrE,IAAM,IAAM,GAAa,CAAI;CAC7B,IAAI,CAAC,GAAK;CACV,IAAM,IAAQ,EAAK,cAAc,YAAY;CAI7C,AAHA,EAAM,SAAS,GAAM,CAAM,GAC3B,EAAM,SAAS,EAAI,GACnB,EAAI,gBAAgB,GACpB,EAAI,SAAS,CAAK;AACpB;AAKA,SAAS,GAAU,GAAoC;CACrD,IAAM,IAAQ,GAAqB,EAAM,KAAK,MAAM,EAAM,MAAM;CAChE,OAAO,IAAQ;EAAE,GAAG;EAAO,UAAU,EAAM;CAAK,IAAI;AACtD;AAIA,SAAS,GACP,GACA,GACA,GACA,GACS;CACT,IAAI,GAAiB,CAAM,KAAK,MAAM,OAAO;CAC7C,IAAM,IAAO,EAAQ;CACrB,IAAI,CAAC,EAAK,SAAS,CAAI,GAAG,OAAO;CACjC,IAAM,IAAS,EAAK;CAEpB,IADI,CAAC,KACD,EAAQ,QAAQ,EAAK,KAAK,QAAQ,OAAO;CAG7C,EAAK,WAAW,EAAQ,IAAI,EAAQ,QAAQ,EAAQ,EAAE;CACtD,IAAM,IAAQ,EAAK,UAAU,EAAQ,EAAE;CAMvC,OALA,EAAO,aAAa,GAAkB,EAAK,eAAe,GAAQ,CAAS,GAAG,CAAK,GAG9E,EAAM,KAAK,WAAW,GAAG,KAAG,EAAM,WAAW,GAAG,GAAG,GACxD,GAAS,GAAM,GAAO,CAAC,GAChB;AACT;AAMA,SAAS,GAAgB,GAAmB,GAAoB;CAC9D,IAAM,IAAM,GAAa,CAAI;CAC7B,IAAI,CAAC,KAAO,EAAI,eAAe,GAAG;CAClC,IAAM,IAAQ,EAAI,WAAW,CAAC;CAC9B,IAAI,CAAC,EAAK,SAAS,EAAM,uBAAuB,GAAG;CACnD,EAAM,eAAe;CAErB,IAAM,EAAE,mBAAgB,mBAAgB;CACxC,IAAI,EAAe,aAAa,IAAW;EACzC,IAAM,IAAO;EAEb,AADA,EAAK,WAAW,GAAa,CAAI,GACjC,GAAS,GAAM,GAAM,IAAc,EAAK,MAAM;EAC9C;CACF;CACA,IAAM,IAAO,EAAK,cAAc,eAAe,CAAI;CAEnD,AADA,EAAM,WAAW,CAAI,GACrB,GAAS,GAAM,GAAM,EAAK,KAAK,MAAM;AACvC;AAuCA,SAAgB,GACd,GACA,GACwB;CACxB,IAAM,IAAM,EAAG,eACX,IAAgC,MAShC,IAA+C,MAC/C,IAAU;CAEd,SAAS,EAAU,GAAe;EAChC,IAAM,IAAO,EAAM,WAAW;EAC1B,OAAS,KAAW,EAAG,aAAa,YAAY,MAAM,OAC1D,IAAU,GACV,EAAG,gBAAgB,cAAc,CAAI;CACvC;CAEA,SAAS,IAAO;EACd,IAAM,IAAO,GAAoB,CAAE;EAEnC,AADA,EAAU,CAAI,GACd,EAAK,SAAS,CAAI;CACpB;CAEA,SAAS,EAAe,GAA4B;EAClD,IAAM,IAAO;EACb,IAAU,GAMR,OAAQ,OACJ,KAAQ,OACR,KAAQ,QACR,EAAK,OAAO,EAAK,MACjB,EAAK,UAAU,EAAK,SACpB,EAAK,UAAU,EAAK,SACpB,EAAK,aAAa,EAAK,aAE7B,EAAK,gBAAgB,IAAO;GAAE,IAAI,EAAK;GAAI,OAAO,EAAK;GAAO,OAAO,EAAK;EAAM,IAAI,IAAI;CAC1F;CAEA,SAAS,IAAc;EACrB,IAAI,CAAC,EAAK,gBAAgB,GAAG;GAC3B,EAAe,IAAI;GACnB;EACF;EACA,IAAM,IAAQ,GAAQ,CAAE,GAClB,IAAO,IAAQ,GAAU,CAAK,IAAI;EACxC,IAAI,KAAQ,KAAa,EAAK,aAAa,EAAU,QAAQ,EAAK,OAAO,EAAU,IAAI;GACrF,EAAe,IAAI;GACnB;EACF;EAGA,AADA,IAAY,MACZ,EAAe,CAAI;CACrB;CAEA,SAAS,EAAS,GAAc;EAI9B,AAHA,EAAG,gBAAgB,GAAmB,GAAK,GAAM,EAAK,SAAS,CAAC,GAChE,EAAU,GAAoB,CAAE,CAAC,GACjC,IAAY,MACZ,EAAe,IAAI;CACrB;CAEA,IAAM,UAAgB;EAEpB,AADA,EAAK,GACL,EAAY;CACd,GACM,UAAoB,EAAY,GAIhC,UAAuB;EAE3B,AADA,GAAoB,CAAE,GACtB,EAAY;CACd,GACM,KAAW,MAAsB;EAIrC,IAAM,IAAO,EAAE,eAAe,QAAQ,YAAY;EAClD,EAAE,eAAe,GACZ,MACL,GAAgB,GAAI,EAAK,QAAQ,UAAU,IAAI,CAAC,GAChD,EAAK,GACL,EAAY;CACd,GACM,KAAU,MAAiB;EAG/B,EAAE,eAAe;CACnB;CAWA,OATA,EAAG,iBAAiB,SAAS,CAAO,GACpC,EAAG,iBAAiB,SAAS,CAAW,GACxC,EAAG,iBAAiB,WAAW,CAAc,GAC7C,EAAG,iBAAiB,SAAS,CAAc,GAC3C,EAAG,iBAAiB,SAAS,CAAO,GACpC,EAAG,iBAAiB,QAAQ,CAAM,GAElC,EAAS,EAAK,gBAAgB,EAAE,GAEzB;EACL,gBAAgB,GAAoB,CAAE;EACtC;EACA,QAAQ;GACN,EAAG,MAAM;GAGT,IAAM,IAAO,EAAG;GACX,MACD,EAAK,aAAa,KAAW,GAAS,GAAI,GAAO,EAAc,KAAK,MAAM,IACzE,GAAS,GAAI,GAAI,EAAG,WAAW,MAAM;EAC5C;EACA,cAAc,GAAQ;GAKpB,IAAM,IAAQ,GAAQ,CAAE,GAClB,KAAU,IAAQ,GAAU,CAAK,IAAI,SAAS;GAC/C,KACA,GAAoB,GAAI,GAAQ,GAAQ,EAAK,SAAS,MAC3D,EAAK,GACL,IAAY,MACZ,EAAe,IAAI;EACrB;EACA;EACA,oBAAoB,EAAe,IAAI;EACvC,iBAAiB;GAEf,AADI,MAAS,IAAY;IAAE,MAAM,EAAQ;IAAU,IAAI,EAAQ;GAAG,IAClE,EAAe,IAAI;EACrB;EACA,UAAU;GAMR,AALA,EAAG,oBAAoB,SAAS,CAAO,GACvC,EAAG,oBAAoB,SAAS,CAAW,GAC3C,EAAG,oBAAoB,WAAW,CAAc,GAChD,EAAG,oBAAoB,SAAS,CAAc,GAC9C,EAAG,oBAAoB,SAAS,CAAO,GACvC,EAAG,oBAAoB,QAAQ,CAAM;EACvC;CACF;AACF;AAIA,IAAI,KAA+C;AAYnD,SAAgB,KAAmD;CACjE,IAAI,IAAY,OAAO;CACvB,IAAI,OAAO,WAAa,KAAa,OAAO;CAC5C,IAAM,IAAQ,SAAS,cAAc,KAAK;CAC1C,IAAI;EAEF,AADA,EAAM,kBAAkB,kBACxB,KAAa,EAAM,oBAAoB,mBAAmB,mBAAmB;CAC/E,QAAQ;EACN,KAAa;CACf;CACA,OAAO;AACT;;;ACldA,SAAgB,GAAgB,EAC9B,SACA,aACA,eAKC;CACD,IAAM,IAAQ,SAAc,IAAI,IAAI,CAAQ,GAAG,CAAC,CAAQ,CAAC;CAEzD,OACE,kBAAC,KAAD;EAAG,OAAM;EAAT,UAAA,CAFa,SAAc,GAAmB,CAAI,GAAG,CAAC,CAAI,CAGvD,CAAA,CAAO,KAAK,GAAG,MACV,EAAE,SAAS,aAAa,EAAM,IAAI,EAAE,MAAM,IAE1C,kBAAC,QAAD;GAAc,OAAM;GAApB,UAAA,CAA0C,KACtC,EAAE,IACA;EAFK,GAAA,CAEL,IAIH,kBAAC,QAAD,EAAA,UADM,EAAE,SAAS,YAAY,IAAI,EAAE,SAAS,EAAE,MACpB,GAAf,CAAe,CAClC,GACA,CACA;;AAEP;AAGA,SAAgB,GAAiB,GAK9B;CACD,IAAM,EAAE,YAAS,YAAS,aAAU,eAAY,GAC1C,CAAC,GAAW,KAAgB,EAAS,CAAC,GAEtC,IAAW,SAAc;EAC7B,IAAI,CAAC,GAAS,OAAO,CAAC;EACtB,IAAM,IAAI,EAAQ,MAAM,YAAY;EACpC,OAAO,EAAQ,QAAQ,MAAM,EAAE,KAAK,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;CAC3E,GAAG,CAAC,GAAS,CAAO,CAAC;CAGrB,QAAgB;EACd,GAAc,MAAO,KAAK,EAAS,SAAS,IAAI,CAAE;CACpD,GAAG,CAAC,CAAQ,CAAC;CAGb,SAAS,EAAc,GAA2B;EAChD,IAAI,CAAC,KAAW,EAAS,WAAW,GAAG,OAAO;EAC9C,IAAI,EAAE,QAAQ,aAGZ,OAFA,EAAE,eAAe,GACjB,GAAc,OAAO,IAAI,KAAK,EAAS,MAAM,GACtC;EAET,IAAI,EAAE,QAAQ,WAGZ,OAFA,EAAE,eAAe,GACjB,GAAc,OAAO,IAAI,IAAI,EAAS,UAAU,EAAS,MAAM,GACxD;EAET,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,OAAO;GACxC,EAAE,eAAe;GACjB,IAAM,IAAS,EAAS;GAExB,OADI,KAAQ,EAAS,CAAM,GACpB;EACT;EAMA,OALI,EAAE,QAAQ,aACZ,EAAE,eAAe,GACjB,EAAQ,GACD;CAGX;CAEA,OAAO;EACL,QAAQ,KAAW,QAAQ,EAAS,SAAS;EAC7C,OAAO;EACP;EACA;EACA;CACF;AACF;AAGA,SAAgB,GAAkB,EAChC,UACA,cACA,iBACA,eAMC;CAED,OADI,EAAM,WAAW,IAAU,OAE7B,kBAAC,MAAD;EAAI,OAAM;EAAwB,MAAK;EAAU,cAAW;EACzD,UAAA,EAAM,KAAK,GAAG,MACb,kBAAC,MAAD;GAEE,MAAK;GACL,iBAAe,MAAM;GACrB,OAAO,6BAA6B,MAAM,IAAY,eAAe;GACrE,cAAc,MAAM;IAGlB,AADA,EAAE,eAAe,GACjB,EAAS,CAAC;GACZ;GACA,oBAAoB,EAAa,CAAC;GAVpC,UAAA,CAYE,kBAAC,QAAD;IAAM,OAAM;IAA8B,UAAA,EAAE;GAAW,CAAA,GACvD,kBAAC,QAAD;IAAM,OAAM;IAAgC,eAAY;IAAO,UAAA;GAEzD,CAAA,CACJ;EAfG,GAAA,EAAE,MAeL,CACL;CACC,CAAA;AAER;;;AC5GA,SAAgB,GAAa,EAC3B,UACA,aACA,cACA,YACA,UACA,gBACA,cAAW,IACX,eAAY,IACZ,OAAO,GACP,aAiBC;CACD,IAAM,IAAQ,EAAuB,IAAI,GACnC,IAAU,EAAsC,IAAI,GACpD,CAAC,GAAS,KAAc,EAAqC,IAAI,GAIjE,IAAc,EAAO,CAAQ;CACnC,EAAY,UAAU;CACtB,IAAM,IAAa,EAAO,CAAO;CACjC,EAAW,UAAU;CAGrB,IAAM,IAAkB,EAAO,CAAK;CAoCpC,AAlCA,SAAsB;EACpB,IAAM,IAAK,EAAM;EACjB,IAAI,CAAC,GAAI;EACT,IAAM,IAAO,GAAmB,GAAI;GAClC,WAAW;GACX,cAAc,EAAgB;GAC9B,WAAW,MAAS,EAAY,QAAQ,CAAI;GAC5C,iBAAiB;GACjB,wBAAwB,EAAW,SAAS,UAAU,KAAK;EAC7D,CAAC;EAED,OADA,EAAQ,UAAU,SACL;GAEX,AADA,EAAK,QAAQ,GACb,EAAQ,UAAU;EACpB;CACF,GAAG,CAAC,CAAC,GAGL,SAAsB;EACf,OAEL,OADA,EAAO,UAAU,EAAE,aAAa,EAAQ,SAAS,MAAM,EAAE,SAC5C;GACX,EAAO,UAAU;EACnB;CACF,GAAG,CAAC,CAAM,CAAC,GAEX,SAAsB;EACpB,AAAI,KAAW,EAAQ,SAAS,MAAM;CACxC,GAAG,CAAC,CAAS,CAAC,GAMd,SAAsB;EACpB,IAAM,IAAO,EAAQ;EAChB,KACD,EAAK,SAAS,MAAM,KAAO,EAAK,SAAS,CAAK;CACpD,GAAG,CAAC,CAAK,CAAC;CAEV,IAAM,IAAS,GAAiB;EAC9B,SAAS,KAAW,CAAC;EACrB;EACA,WAAW,MAAW,EAAQ,SAAS,cAAc,CAAM;EAE3D,eAAe,EAAQ,SAAS,eAAe;CACjD,CAAC;CAED,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;EACE,KAAK;EACL,MAAK;EACL,kBAAe;EACf,cAAY;EACZ,iBAAe,KAAY,KAAA;EAC3B,OAAO,EAAG,wBAAwB,CAAS;EAG3C,iBAAiB,IAAW,UAAU,GAAsB;EAC5D,oBAAkB;EAClB,UAAU,IAAW,KAAK;EAC1B,YAAY,MAAM;GACZ,EAAO,cAAc,CAAC,KAC1B,IAAY,CAAC;EACf;EACA,cAAc;GAEZ,iBAAiB,EAAQ,SAAS,aAAa,GAAG,GAAG;EACvD;CACD,CAAA,GACA,EAAO,SACN,kBAAC,IAAD;EACE,OAAO,EAAO;EACd,WAAW,EAAO;EAClB,cAAc,EAAO;EACrB,WAAW,MAAW,EAAQ,SAAS,cAAc,CAAM;CAC5D,CAAA,IACC,IACJ,EAAA,CAAA;AAEN;;;AChJA,IAAM,KAAW;AAajB,SAAgB,GAAS,EACvB,UACA,iBAAc,mBACd,iBAAc,QACd,kBAAe,IACf,cACA,UACA,aACA,cAWC;CACD,IAAM,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,IAAW,EAAkC,IAAI,GACjD,IAAa,EAAO,EAAK;CAI/B,QAAgB;EAKd,AAJI,EAAW,WAAW,CAAC,KAAa,CAAC,MACvC,EAAS,EAAE,GACX,EAAS,SAAS,MAAM,IAE1B,EAAW,UAAU;CACvB,GAAG,CAAC,GAAW,CAAK,CAAC;CAErB,IAAM,IAAY,KAAW,EAAM,QAC7B,IAAc,IAAY;CAEhC,SAAS,EAAa,GAAW;EAC/B,GAAG,eAAe;EAClB,IAAM,IAAO,EAAM,KAAK;EAKpB,CAAC,KAAQ,KAAa,KAC1B,EAAS,CAAI;CACf;CAKA,SAAS,EAAM,GAAkB;EAC/B,CAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,WACxC,EAAa,CAAC;CAElB;CAEA,IAAM,IAAW,EAAM,SAAS,GAC1B,IAAO,GAAa;CAE1B,SAAS,EAAa,GAAmB;EACvC,OACE,kBAAC,UAAD;GACE,MAAK;GACL,OAAM;GACN,UAAU,KAAa,CAAC,EAAM,KAAK,KAAK;GACxC,cAAY,IAAY,aAAa;GACrC,OAAO,IAAY,aAAa;GACtB;GAEV,UAAA,kBAAC,IAAD,EAAU,MAAM,GAAK,CAAA;EACf,CAAA;CAEZ;CAEA,OACE,kBAAC,QAAD;EAAM,OAAO,EAAG,mBAAmB,KAAY,WAAW;EAAG,UAAU;EAAvE,UAAA;GACE,kBAAC,IAAD;IACE,OAAM;IACC;IACM;IACN;IACP,UAAU;IACV,WAAW;IACF;IACT,UAAU;IACV,WAAW;IACX,QAAQ;GACT,CAAA;GAED,kBAAC,OAAD;IAAK,OAAM;IACT,UAAA,kBAAC,OAAD;KAAK,OAAM;KAAX,UAAA,CACE,kBAAC,QAAD;MAAM,OAAM;MACT,UAAA,IACC,kBAAC,QAAD;OAAM,OAAM;OAAyB,UAAA;MAAY,CAAA,IAC/C,IACF,kBAAC,QAAD;OAAM,OAAM;OAAZ,UAAA,CAAqC,KAAK,IAAI,CAAS,GAAE,WAAe;MAUxE,CAAA,IAAA,kBAAA,GAAA,EAAA,UAAA;OACE,kBAAC,OAAD;QAAK,OAAM;QAAwB,UAAA,EAAK;OAAS,CAAA;OACjD,kBAAC,OAAD;QAAK,OAAM;QAAwB,UAAA,EAAK;OAAW,CAAA;OACnD,kBAAC,QAAD;QAAM,OAAM;QAA6B,UAAA;OAAa,CAAA;MACtD,EAAA,CAAA;KAEA,CAAA,GACN,kBAAC,OAAD;MAAK,OAAM;MAA2B,UAAA,EAAa,IAAW,KAAA,IAAY,EAAE;KAAO,CAAA,CAChF;;GACF,CAAA;GAEL,kBAAC,QAAD;IAAM,OAAM;IAAgC,eAAa,KAAY,KAAA;IAClE,UAAA,EAAa,IAAW,KAAK,KAAA,CAAS;GACnC,CAAA;EACF;;AAEV;;;AC3HA,SAAgB,GAAiB,EAC/B,UACA,UACA,eACA,eACA,wBACA,gBACA,cACA,UACA,eACA,0BACA,qBACA,4BACA,gCACA,aAAU,CAAC,GACX,aACA,aACA,aACA,cA2BC;CACD,IAAM,IAAM,EAAuB,IAAI;CACvC,GAAa,GAAK,EAAI;CAEtB,IAAM,CAAC,GAAmB,KAAwB,EAAS,EAAK,GAC1D,CAAC,GAAqB,KAA0B,EAAS,EAAK,GAC9D,IAAa,GAAa,CAAU,GAGpC,CAAC,GAAS,KAAc,EAA+C,IAAI,GAG3E,EAAE,eAAe,GAAqB,kBAAe,GAAQ;EACjE,WAAW;EACX,cAAc,MAEL,CADQ,EAAE,QACD,QAAQ,oCAAoC;EAE9D,QAAQ;CACV,CAAC;CAED,QAAgB;EACd,IAAM,IAAK,EAAI;EACf,IAAI,CAAC,GAAI;EAET,IAAI,OAAO,EAAG,eAAgB,cAAc,CAAC,EAAG,QAAQ,eAAe,GACrE,IAAI;GACF,EAAG,YAAY;EACjB,QAAQ,CAER;EAGF,SAAS,EAAS,GAAU;GAE1B,AAAI,EAAG,aAAa,YAAU,EAAQ;EACxC;EAEA,OADA,EAAG,iBAAiB,UAAU,CAAQ,SACzB,EAAG,oBAAoB,UAAU,CAAQ;CACxD,GAAG,CAAC,CAAO,CAAC;CAEZ,IAEM,KAAO,GAAM,IAAQ,OAAO,UAAU,IAAI,IAAQ,OAAO,aAAa,MAAQ,EAAM,GACpF,IAAM,GAAM,IAAQ,OAAO,UAAU,IAAI,IAAQ,OAAO,cAAc,GAAG,GACzE,IAAU,OAAO,SAAW,MAAc,OAAO,SAAS,OAAO,IAEjE,IAAgB,KAAc,MAI9B,KAAoB,KAAyB,KAAiB;CAEpE,OACE,kBAAC,OAAD;EACO;EACL,OAAO,EAAG,kBAAkB,KAAW,eAAe,KAAc,aAAa;EACjF,SAAQ;EACR,OAAO;GACL,kBAAkB,GAAG,GAAS,QAAQ,GAAK;GAC3C,kBAAkB,GAAG,GAAS,OAAO,EAAI;EAC3C;EACA,MAAK;EACL,cAAW;EATb,UAAA,CAWE,kBAAC,UAAD;GAAQ,OAAM;GAAwB,eAAe;GAArD,UAAA,CAOE,kBAAC,QAAD;IAAM,OAAM;IAAuB,OAAO;IAAS,UAAA;GAE7C,CAAA,GACN,kBAAC,UAAD;IAAQ,MAAK;IAAS,OAAM;IAAkB,cAAW;IAAc,SAAS;IAC9E,UAAA,kBAAC,IAAD,EAAW,MAAM,GAAK,CAAA;GAChB,CAAA,CACF;EAEP,CAAA,GAAA,KAAc,OACb,kBAAC,IAAD;GACa;GACX,cAAc;GACD;GACb,UAAU;GACV,UAAU;GACA;EACX,CAAA,IAED,kBAAC,OAAD;GAAK,OAAM;GAAX,UAAA;IACE,kBAAC,KAAD;KAAG,OAAM;KAAT,UAAA;MAAiC;MACpB,kBAAC,QAAD;OAAM,OAAM;OAAuB,UAAA;MAAiB,CAAA;MAC9D,IAAa,kBAAC,QAAD;OAAM,OAAM;OAAuB,UAAA;MAAU,CAAA,IAAI;KAC9D;;IACH,kBAAC,IAAD;KACE,OAAM;KACN,aAAY;KACZ,aAAY;KACD;KACJ;KACP,WAAW,MAAS,EAAS,GAAM,KAAqB,CAAa;KAC5D;IACV,CAAA;IACA,KACC,kBAAC,OAAD;KAAK,OAAO,EAAG,yBAAyB,KAAoB,WAAW;KAAvE,UAAA,CACG,IACC,kBAAC,QAAD;MAAM,OAAM;MAAZ,UAAA;OACE,kBAAC,SAAD;QAAO,MAAK;QAAW,OAAM;QAA6B,UAAA;OAAU,CAAA;OACpE,kBAAC,IAAD,EAAY,MAAM,GAAK,CAAA;OACvB,kBAAC,QAAD,EAAA,UAAM,aAAgB,CAAA;MAClB;KACJ,CAAA,IAAA,IAGF,kBAAC,QAAD;MACE,OAAM;MACN,OAAM;MAFR,UAAA,CAIE,kBAAC,IAAD,EAAY,MAAM,GAAK,CAAA,GACvB,kBAAC,QAAD,EAAA,UAAM,yBAA4B,CAAA,CAC9B;KAEN,CAAA,IAAA,kBAAC,SAAD;MAAO,OAAM;MAAb,UAAA;OACE,kBAAC,SAAD;QACE,MAAK;QACL,OAAM;QACN,SAAS;QACT,WAAW,MAAM,EAAqB,EAAE,cAAc,OAAO;OAC9D,CAAA;OACD,kBAAC,IAAD,EAAY,MAAM,GAAK,CAAA;OACvB,kBAAC,QAAD,EAAA,UAAM,oBAAuB,CAAA;OAC5B,KAAc,IACb,kBAAC,OAAD;QACE,OAAM;QACN,KAAK;QACL,KAAI;OACL,CAAA,IACC;MACC;KAER,CAAA,GAAA,KAAqB,IACpB,kBAAA,GAAA,EAAA,UAAA,CACG,IAA0B,IACzB,kBAAC,OAAD;MAAK,OAAM;MAAX,UAAA,CACE,kBAAC,UAAD;OACE,MAAK;OACL,OAAM;OACN,eAAe,GAAwB,MAAM,CAAC,CAAC;OAHjD,UAAA;QAKE,kBAAC,MAAD;SAAI,OAAM;SACP,UAAA,IAAsB,MAAM;QAC3B,CAAA;QACH;QAAyB;QACzB,MAA4B,IAAI,UAAU;QAAS;OAC9C;MACP,CAAA,GAAA,IACC,kBAAC,OAAD;OAAK,OAAM;OACR,UAAA,EAA4B,KAAK,MAChC,kBAAC,QAAD;QAAgB,OAAM;QACnB,UAAA;OACG,GAFK,CAEL,CACP;MACE,CAAA,IACH,IACD;KACH,CAAA,IAAA,MACJ,kBAAC,KAAD;MAAG,OAAM;MAAT,UAAA;OAAkC;OACmC;OACnE,kBAAC,QAAD;QAAM,OAAM;QAA8B,UAAA;OAAyB,CAAA;OAAC;MAEnE;KACH,CAAA,CAAA,EAAA,CAAA,IACA,IACD;IACH,CAAA,IAAA;GACD;EAEJ,CAAA,CAAA;;AAET;AAEA,SAAS,GAAM,GAAe,GAAa,GAAqB;CAC9D,OAAO,KAAK,IAAI,GAAK,KAAK,IAAI,GAAK,CAAK,CAAC;AAC3C;;;ACnOA,SAAgB,GAAmB,EACjC,UACA,cACA,UACA,WACA,gBACA,kBACA,mBASC;CACD,IAAM,IAAY,EAAM,MAAM,MAAM,EAAE,UAAU,IAAI;CAEpD,OACE,kBAAC,OAAD;EAAK,OAAM;EAA6B,MAAK;EAAS,cAAW;EAAjE,UAAA,CACE,kBAAC,UAAD;GAAQ,OAAM;GAAd,UAAA;IACE,kBAAC,UAAD;KACE,MAAK;KACL,OAAM;KACN,OAAM;KACN,cAAW;KACX,SAAS;KAET,UAAA,kBAAC,IAAD,EAAiB,MAAM,GAAK,CAAA;IACtB,CAAA;IACR,kBAAC,QAAD;KAAM,OAAM;KAAiB,UAAA;IAAmB,CAAA;IAChD,kBAAC,OAAD;KAAK,OAAM;KACR,UAAA,IACC,kBAAC,UAAD;MACE,MAAK;MACL,OAAM;MACN,UAAU;MACV,SAAS;MAER,UAAA,IAAe,aAAa;KACvB,CAAA,IACN;IACD,CAAA;GACC;EAER,CAAA,GAAA,kBAAC,OAAD;GAAK,OAAM;GACR,UAAA,IACC,kBAAC,KAAD;IAAG,OAAM;IAAoC,UAAA;GAAS,CAAA,IACpD,IACF,kBAAC,KAAD;IAAG,OAAM;IAAmC,UAAA;GAAW,CAAA,IACrD,EAAM,WAAW,IACnB,kBAAC,OAAD;IAAK,OAAM;IAAX,UAAA,CACE,kBAAC,KAAD;KAAG,OAAM;KAAyC,UAAA;IAAwB,CAAA,GAC1E,kBAAC,KAAD;KAAG,OAAM;KAAuC,UAAA;IAE7C,CAAA,CACA;GAEL,CAAA,IAAA,kBAAC,MAAD;IAAI,OAAM;IACP,UAAA,EAAM,KAAK,MACV,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;KACE,MAAK;KACL,OAAO,EAAG,kCAAkC,EAAK,UAAU,QAAQ,WAAW;KAC9E,eAAe,EAAY,CAAI;KAHjC,UAAA;MAKE,kBAAC,OAAD;OAAK,OAAM;OAAX,UAAA;QACG,EAAK,UAAU,OACd,kBAAC,QAAD;SAAM,eAAY;SAAO,OAAM;QAAkC,CAAA,IAC/D;QACJ,kBAAC,QAAD;SAAM,OAAM;SAAoC,UAAA,EAAK;QAAgB,CAAA;QAKpE,EAAK,aAAa,QACjB,kBAAC,QAAD;SACE,OAAM;SACN,MAAK;SACL,cAAW;SACX,OAAM;SAEN,UAAA,kBAAC,IAAD,EAAS,MAAM,GAAK,CAAA;QAChB,CAAA,IACJ;QACJ,kBAAC,QAAD;SAAM,OAAM;SAAiC,UAAA;QAAO,CAAA;QACpD,kBAAC,QAAD;SAAM,OAAM;SACT,UAAA,GAAa,EAAK,SAAS;QACxB,CAAA;OACH;;MACL,kBAAC,KAAD;OAAG,OAAM;OAAT,UAAA;QAA6C;QAC1B;QACjB,kBAAC,QAAD;SAAM,OAAM;SAA2C,UAAA,EAAK;QAAkB,CAAA;OAC7E;;MACF,EAAK,iBACJ,kBAAC,KAAD;OAAG,OAAM;OAAT,UAAA;QAA8C;QAAE,EAAK;QAAe;OAAI;MACtE,CAAA,IAAA;KACE;IACN,CAAA,EAAA,GAtCK,EAAK,GAsCV,CACL;GACC,CAAA;EAEH,CAAA,CACF;;AAET;AAEA,SAAS,GAAa,GAAoB;CACxC,IAAM,IAAO,KAAK,IAAI,IAAI,GACpB,IAAM,KAAK,MAAM,IAAO,GAAI;CAClC,IAAI,IAAM,IAAI,OAAO;CACrB,IAAM,IAAM,KAAK,MAAM,IAAM,EAAE;CAC/B,IAAI,IAAM,IAAI,OAAO,GAAG,EAAI;CAC5B,IAAM,IAAK,KAAK,MAAM,IAAM,EAAE;CAC9B,IAAI,IAAK,IAAI,OAAO,GAAG,EAAG;CAC1B,IAAM,IAAM,KAAK,MAAM,IAAK,EAAE;CAE9B,OADI,IAAM,KAAW,GAAG,EAAI,SACrB,IAAI,KAAK,CAAE,CAAC,CAAC,mBAAmB;AACzC;;;AC5HA,SAAgB,KAId;CACA,IAAM,GAAG,KAAe,EAAS,CAAC;CAIlC,OAFA,QAAgB,SAAqB,GAAa,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAE5D;EACL,MAAM,GAAa;EACnB,UAAU,GAAc;EACxB,KAAK;CACP;AACF;;;ACLA,SAAgB,GAAa,EAC3B,aACA,kBACA,gBACA,uBAAoB,IACpB,wBACA,kBACA,oBACA,qBACA,YACA,mBAkBC;CACD,IAAM,CAAC,GAAM,KAAW,EAAS,EAAK,GAChC,IAAe,EAAuB,IAAI,GAC1C,IAAQ,GAAS;CAEvB,QAAgB;EACd,IAAI,CAAC,GAAM;EACX,SAAS,EAAW,GAAe;GACjC,IAAM,IAAY,EAAa;GAC1B,MACA,EAAE,aAAa,CAAC,CAAC,SAAS,CAAS,KAAG,EAAQ,EAAK;EAC1D;EACA,SAAS,EAAM,GAAkB;GAC/B,AAAI,EAAE,QAAQ,YAAU,EAAQ,EAAK;EACvC;EAGA,OAFA,SAAS,iBAAiB,SAAS,GAAY,EAAI,GACnD,SAAS,iBAAiB,WAAW,CAAK,SAC7B;GAEX,AADA,SAAS,oBAAoB,SAAS,GAAY,EAAI,GACtD,SAAS,oBAAoB,WAAW,CAAK;EAC/C;CACF,GAAG,CAAC,CAAI,CAAC;CAET,IAAM,IACJ,MAAa,gBACT,mBACA,MAAa,kBACX,qBACA,mBAEF,EAAE,KAAK,MAAW,GAAa;CAErC,OACE,kBAAC,OAAD;EAAK,KAAK;EAAc,OAAO;GAAE,UAAU;GAAY,SAAS;EAAc;EAA9E,UAAA,CACE,kBAAC,UAAD;GACE,MAAK;GACL,OAAM;GACN,aAAU;GACV,WAAS,IAAO,SAAS,KAAA;GACzB,iBAAc;GACd,iBAAe;GACf,cAAW;GACX,OAAM;GACN,UAAU,MAAM;IAGd,AAFA,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAClB,GAAS,MAAM,CAAC,CAAC;GACnB;GAEA,UAAA,kBAAC,IAAD,EAAU,MAAM,GAAK,CAAA;EACf,CAAA,GAEP,IACC,kBAAC,OAAD;GAAK,OAAO,EAAG,cAAc,CAAW;GAAG,YAAS;GAAW,MAAK;GAApE,UAAA;IAEE,kBAAC,OAAD;KAAK,OAAM;KAAX,UAAA,CACE,kBAAC,QAAD;MAAM,OAAM;MAAM,UAAA;KAAgB,CAAA,GAClC,kBAAC,OAAD;MAAK,OAAM;MAAmB,MAAK;MAAa,cAAW;MAA3D,UAAA;OACE,kBAAC,UAAD;QACE,MAAK;QACL,MAAK;QACL,gBAAc,EAAM,SAAS;QAC7B,cAAW;QACX,OAAM;QACN,OAAO,EAAG,EAAM,SAAS,WAAW,OAAO;QAC3C,eAAe,EAAM,IAAI,OAAO;QAEhC,UAAA,kBAAC,IAAD,EAAS,MAAM,GAAK,CAAA;OACd,CAAA;OACR,kBAAC,UAAD;QACE,MAAK;QACL,MAAK;QACL,gBAAc,EAAM,SAAS;QAC7B,cAAW;QACX,OAAM;QACN,OAAO,EAAG,EAAM,SAAS,UAAU,OAAO;QAC1C,eAAe,EAAM,IAAI,MAAM;QAE/B,UAAA,kBAAC,IAAD,EAAU,MAAM,GAAK,CAAA;OACf,CAAA;OACR,kBAAC,UAAD;QACE,MAAK;QACL,MAAK;QACL,gBAAc,EAAM,SAAS;QAC7B,cAAY,mBAAmB,EAAM,SAAS;QAC9C,OAAO,mBAAmB,EAAM;QAChC,OAAO,EAAG,EAAM,SAAS,UAAU,OAAO;QAC1C,eAAe,EAAM,IAAI,MAAM;QAE/B,UAAA,kBAAC,IAAD,EAAa,MAAM,GAAK,CAAA;OAClB,CAAA;MACL;KACF,CAAA,CAAA;;IAGL,kBAAC,OAAD;KAAK,OAAM;KAAX,UAAA,CACE,kBAAC,QAAD;MAAM,OAAM;MAAM,UAAA;KAAc,CAAA,GAChC,kBAAC,OAAD;MAAK,OAAM;MAAmB,MAAK;MAAa,cAAW;MAA3D,UAAA;OACE,kBAAC,UAAD;QACE,MAAK;QACL,MAAK;QACL,gBAAc,MAAa;QAC3B,cAAW;QACX,OAAM;QACN,OAAO,EAAG,MAAa,iBAAiB,OAAO;QAC/C,eAAe,EAAc,aAAa;QAE1C,UAAA,kBAAC,IAAD,EAAY,MAAK,OAAQ,CAAA;OACnB,CAAA;OACR,kBAAC,UAAD;QACE,MAAK;QACL,MAAK;QACL,gBAAc,MAAa;QAC3B,cAAW;QACX,OAAM;QACN,OAAO,EAAG,MAAa,mBAAmB,OAAO;QACjD,eAAe,EAAc,eAAe;QAE5C,UAAA,kBAAC,IAAD,EAAY,MAAK,SAAU,CAAA;OACrB,CAAA;OACR,kBAAC,UAAD;QACE,MAAK;QACL,MAAK;QACL,gBAAc,MAAa;QAC3B,cAAW;QACX,OAAM;QACN,OAAO,EAAG,MAAa,kBAAkB,OAAO;QAChD,eAAe,EAAc,cAAc;QAE3C,UAAA,kBAAC,IAAD,EAAY,MAAK,QAAS,CAAA;OACpB,CAAA;MACL;KACF,CAAA,CAAA;;IAEL,kBAAC,OAAD;KAAK,OAAM;KAAyB,UAAA;IAAa,CAAA;IAEjD,kBAAC,UAAD;KACE,MAAK;KACL,MAAK;KACL,gBAAc;KACd,OAAM;KACN,WAAS,IAAc,SAAS,KAAA;KAChC,UAAU;KACV,UAAU,MAAM;MAGd,AAFA,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAClB,EAAoB;KACtB;KAXF,UAAA;MAaE,kBAAC,QAAD;OAAM,OAAM;OACV,UAAA,kBAAC,IAAD,CAAa,CAAA;MACT,CAAA;MACN,kBAAC,QAAD;OAAM,OAAM;OAAZ,UAAA,CACE,kBAAC,QAAD,EAAA,UAAM,2BAA8B,CAAA,GACpC,kBAAC,QAAD;QAAM,OAAM;QACT,UAAA,IAAoB,4BAA4B;OAC7C,CAAA,CACF;;MACN,kBAAC,QAAD;OAAM,OAAM;OAAS,eAAY;MAAQ,CAAA;KACnC;;IAER,kBAAC,UAAD;KACE,MAAK;KACL,MAAK;KACL,OAAM;KACN,eAAe;MAEb,AADA,EAAQ,EAAK,GACb,EAAc;KAChB;KAPF,UAAA,CASE,kBAAC,QAAD;MAAM,OAAM;MACV,UAAA,kBAAC,IAAD,EAAY,MAAM,GAAK,CAAA;KACnB,CAAA,GACN,kBAAC,QAAD;MAAM,OAAM;MAAM,UAAA;KAAwB,CAAA,CACpC;;IAER,kBAAC,UAAD;KACE,MAAK;KACL,MAAK;KACL,OAAM;KACN,eAAe;MAEb,AADA,EAAQ,EAAK,GACb,EAAgB;KAClB;KAPF,UAAA,CASE,kBAAC,QAAD;MAAM,OAAM;MACV,UAAA,kBAAC,IAAD,EAAc,MAAM,GAAK,CAAA;KACrB,CAAA,GACN,kBAAC,QAAD;MAAM,OAAM;MAAM,UAAA;KAAwB,CAAA,CACpC;;IAER,kBAAC,OAAD,EAAK,OAAM,sBAAuB,CAAA;IAElC,kBAAC,UAAD;KACE,MAAK;KACL,MAAK;KACL,OAAM;KACN,eAAe;MAEb,AADA,EAAQ,EAAK,GACb,EAAiB;KACnB;KAPF,UAAA;MASE,kBAAC,QAAD;OAAM,OAAM;OACV,UAAA,kBAAC,IAAD,CAAW,CAAA;MACP,CAAA;MACN,kBAAC,QAAD;OAAM,OAAM;OAAM,UAAA;MAA2B,CAAA;MAC7C,kBAAC,QAAD;OAAM,OAAM;OAAZ,UAAA,CAAqB,GAAO,IAAQ;;KAC9B;;IAER,kBAAC,KAAD;KACE,OAAM;KACN,MAAM,KAAgB;KACtB,QAAO;KACP,KAAI;KAJN,UAAA;MAME,kBAAC,IAAD,EAAU,MAAM,GAAK,CAAA;MACrB,kBAAC,QAAD,EAAA,UAAM,oBAAuB,CAAA;MAC7B,kBAAC,QAAD;OAAM,OAAM;OAAZ,UAAA,CAAkB,KAAE,CAAc;;KACjC;;GACA;EACH,CAAA,IAAA,IACD;;AAET;AAKA,SAAS,GAAW,EAAE,WAA+C;CAEnE,OACE,kBAAC,OAAD;EACE,OAAO;EACP,QAAQ;EACR,SAAQ;EACR,MAAK;EACL,QAAO;EACP,gBAAc;EACd,kBAAe;EACf,mBAAgB;EAChB,eAAA;EATF,UAAA,CAWE,kBAAC,QAAD;GAAM,GAAE;GAAI,GAAE;GAAI,OAAM;GAAK,QAAO;GAAK,IAAG;EAAO,CAAA,GACnD,kBAAC,UAAD;GAAQ,IAdC,MAAS,SAAS,IAAI,MAAS,UAAU,KAAK;GAcrC,IAAI;GAAI,GAAE;GAAM,MAAK;GAAe,QAAO;EAAQ,CAAA,CAClE;;AAET;AAEA,SAAS,KAAa;CACpB,OACE,kBAAC,OAAD;EACE,OAAO;EACP,QAAQ;EACR,SAAQ;EACR,MAAK;EACL,QAAO;EACP,gBAAc;EACd,kBAAe;EACf,mBAAgB;EAChB,eAAA;EATF,UAAA,CAWE,kBAAC,QAAD,EAAM,GAAE,oFAAqF,CAAA,GAC7F,kBAAC,UAAD;GAAQ,IAAG;GAAK,IAAG;GAAK,GAAE;EAAK,CAAA,CAC5B;;AAET;AAEA,SAAS,KAAW;CAClB,OACE,kBAAC,OAAD;EACE,OAAO;EACP,QAAQ;EACR,SAAQ;EACR,MAAK;EACL,QAAO;EACP,gBAAc;EACd,kBAAe;EACf,mBAAgB;EAChB,eAAA;EATF,UAAA;GAWE,kBAAC,QAAD,EAAM,GAAE,gFAAiF,CAAA;GACzF,kBAAC,QAAD,EAAM,GAAE,2EAA4E,CAAA;GACpF,kBAAC,QAAD,EAAM,GAAE,aAAc,CAAA;GACtB,kBAAC,QAAD,EAAM,GAAE,mCAAoC,CAAA;EACzC;;AAET;;;AC1TA,SAAgB,GAAa,EAC3B,SACA,UACA,aACA,sBACA,YACA,eAeC;CACD,IAAM,IAAe,EAAuB,IAAI;CAkChD,OAhCA,QAAgB;EACd,SAAS,EAAW,GAAe;GACjC,IAAM,IAAK,EAAa;GACxB,IAAI,CAAC,GAAI;GACT,IAAM,IAAO,EAAE,aAAa;GACxB,EAAK,SAAS,CAAE,KAElB,KAAqB,QACrB,EAAK,MAAM,MAAO,GAAmB,SAAS,SAAS,CAAiB,KAI1E,EAAQ;EACV;EACA,SAAS,EAAM,GAAkB;GAC/B,AAAI,EAAE,QAAQ,YAAU,EAAQ;EAClC;EAGA,OAFA,SAAS,iBAAiB,SAAS,GAAY,EAAI,GACnD,SAAS,iBAAiB,WAAW,CAAK,SAC7B;GAEX,AADA,SAAS,oBAAoB,SAAS,GAAY,EAAI,GACtD,SAAS,oBAAoB,WAAW,CAAK;EAC/C;CACF,GAAG,CAAC,GAAS,CAAiB,CAAC,GAU7B,kBAAC,OAAD;EACE,KAAK;EACL,OAAO,EAAG,oBATZ,MAAa,gBACT,0BACA,MAAa,kBACX,4BACA,wBAKmC;EACvC,cAAY;EACZ,MAAK;EACL,cAAY;EAEZ,UAAA,kBAAC,OAAD;GAAK,OAAM;GAAa,YAAU;GAC/B;EACE,CAAA;CACF,CAAA;AAET;;;ACvFA,SAAgB,GAAI,EAClB,UACA,UACA,UACA,aACA,iBACA,cAeC;CAGD,IAAM,IAAM,IAAQ,OAAO,SACrB,IAAO,IAAQ,OAAO;CAI5B,OACE,kBAAC,UAAD;EACE,MAAK;EACL,OAAO,EAAG,cAAc,KAAY,uBAAuB,KAAgB,eAAe;EAC1F,OAAO;GAAE,KAAK,GAAG,EAAI;GAAK,MAAM,GAAG,EAAK;EAAI;EAC5C,eAAc;EACd,qBAAoB;EACX;EACT,cAAY,yBAAyB,EAAM,UAAU,MAAU,IAAI,KAAK,IAAI;EAC5E,OAAO,yBAAyB,EAAM,UAAU,MAAU,IAAI,KAAK,IAAI;EAEvE,UAAA,kBAAC,QAAD;GAAM,OAAM;GAAkB,UAAA;EAAY,CAAA;CACpC,CAAA;AAEZ;AAOA,SAAgB,GAAS,EAAE,UAAO,YAA2C;CAC3E,IAAM,IAAM,IAAQ,OAAO,SACrB,IAAO,IAAQ,OAAO;CAC5B,OACE,kBAAC,OAAD;EACE,OAAM;EACN,OAAO;GAAE,KAAK,GAAG,EAAI;GAAK,MAAM,GAAG,EAAK;EAAI;EAE5C,UAAA,kBAAC,QAAD;GAAM,OAAM;GAAiB,eAAA;GAAY,UAAA;EAEnC,CAAA;CACH,CAAA;AAET;;;AC9DA,SAAgB,GAAiB,EAC/B,YACA,eAIC;CAaD,SAAsB;EACpB,SAAS,EAAM,GAAkB;GAC/B,AAAI,EAAE,QAAQ,YAAU,EAAS;EACnC;EAEA,OADA,OAAO,iBAAiB,WAAW,CAAK,SAC3B,OAAO,oBAAoB,WAAW,CAAK;CAC1D,GAAG,CAAC,CAAQ,CAAC;CAEb,SAAS,EAAY,GAAe;EASlC,AARA,EAAE,gBAAgB,GAClB,EAAE,eAAe,GAOjB,EADe,GAAa,GAFX,SAAS,kBAAkB,EAAE,SAAS,EAAE,OACtC,CAAA,CAAS,MAAM,MAAO,CAAC,EAAG,UAAU,KAAK,IAEpD,GAAQ,EAAE,SAAS,EAAE,OAAO;CACtC;CAIA,SAAS,EAAkB,GAAiB;EAE1C,AADA,EAAE,eAAe,GACjB,EAAE,gBAAgB;CACpB;CAEA,OACE,kBAAC,OAAD;EACE,OAAM;EACN,eAAe;EACf,SAAS;EACT,MAAK;EAEL,UAAA,kBAAC,OAAD;GAAK,OAAM;GACT,UAAA,kBAAC,QAAD,EAAA,UAAM,+CAAkD,CAAA;EACrD,CAAA;CACF,CAAA;AAET;;;ACnDA,SAAgB,GAAa,EAC3B,aACA,WACA,gBACA,sBACA,mBACA,kBACA,eACA,cAYC;CAED,IAAM,CAAC,GAAe,KAAoB,EAAS,EAAK,GAElD,IAAO,GAAc,CAAQ,GAC7B,IAAa,EAAS,SAAS,YAC/B,IAAQ,IAAa,EAAS,SAAS,QAAQ,KAAA,GAG/C,IAAY,EAAS,SAAS;CAEpC,OACE,kBAAC,OAAD;EAAK,OAAM;EAAX,UAAA,CACE,kBAAC,UAAD;GAAQ,OAAM;GAAd,UAAA,CACE,kBAAC,QAAD;IAAM,OAAM;IAAiB,UAAA;GAAwB,CAAA,GACrD,kBAAC,UAAD;IACE,MAAK;IACL,OAAM;IACN,OAAM;IACN,cAAW;IACX,SAAS;IAET,UAAA,kBAAC,IAAD,EAAW,MAAM,GAAK,CAAA;GAChB,CAAA,CACF;EAER,CAAA,GAAA,kBAAC,OAAD;GAAK,OAAM;GAAX,UAAA;IACE,kBAAC,WAAD;KAAS,OAAM;KAAf,UAAA,CACE,kBAAC,MAAD;MAAI,OAAM;MAA6B,UAAA;KAAoB,CAAA,GAC1D,IACC,kBAAC,KAAD;MAAG,OAAM;MAAT,UAAA;OAA6B;OACd,kBAAC,UAAD,EAAA,UAAS,KAAQ,MAAc,CAAA;OAC3C,IAAQ,kBAAC,QAAD;QAAM,OAAM;QAAZ,UAAA,CAAgC,KAAE,CAAY;OAAI,CAAA,IAAA;OAAK;MAE/D;KACD,CAAA,IAAA,IACF,kBAAC,KAAD;MAAG,OAAM;MAAT,UAAA;OAA6B;OACf,kBAAC,UAAD,EAAA,UAAS,EAAa,CAAA;OAAC;MAElC;KAEH,CAAA,IAAA,kBAAC,KAAD;MAAG,OAAM;MAAoB,UAAA;KAG1B,CAAA,CAEE;;IAET,kBAAC,WAAD;KAAS,OAAM;KAAf,UAAA,CACE,kBAAC,MAAD;MAAI,OAAM;MAA6B,UAAA;KAAsB,CAAA,GAC7D,kBAAC,MAAD;MAAI,OAAM;MAAV,UAAA;OACE,kBAAC,MAAD,EAAA,UAAI,4EAA6E,CAAA;OACjF,kBAAC,MAAD,EAAA,UAAI,mEAAoE,CAAA;OACxE,kBAAC,MAAD,EAAA,UAAI,mDAAoD,CAAA;MACtD;KACG,CAAA,CAAA;;IAET,kBAAC,WAAD;KAAS,OAAM;KAAf,UAAA;MACE,kBAAC,MAAD;OAAI,OAAM;OAA6B,UAAA;MAAwB,CAAA;MAC/D,kBAAC,MAAD;OAAI,OAAM;OAAV,UAAA,CACE,kBAAC,MAAD,EAAA,UACG,IACG,2FACA,yEACF,CAAA,GACJ,kBAAC,MAAD,EAAA,UAAI,6CAA8C,CAAA,CAChD;;MACJ,kBAAC,KAAD;OAAG,OAAM;OAAoB,UAAA;MAG1B,CAAA;KACI;;IAET,kBAAC,WAAD;KAAS,OAAM;KAAf,UAAA,CACE,kBAAC,MAAD;MAAI,OAAM;MAA6B,UAAA;KAAe,CAAA,GACtD,kBAAC,KAAD;MAAG,OAAM;MACN,UAAA,IACG,sDACA,IACE,gNACA;KACL,CAAA,CACI;;IAET,kBAAC,WAAD;KAAS,OAAM;KAAf,UAAA,CACE,kBAAC,MAAD;MAAI,OAAM;MAA6B,UAAA;KAAiB,CAAA,GACxD,kBAAC,KAAD;MAAG,OAAM;MAAT,UAAA;OAA6B;OACtB,kBAAC,QAAD;QAAM,OAAM;QAAqB,UAAA,GAAU,CAAM;OAAQ,CAAA;OAAC;MAI9D;KACI,CAAA,CAAA;;IAER,IACC,kBAAC,WAAD;KAAS,OAAM;KAAf,UAAA;MACE,kBAAC,MAAD;OAAI,OAAM;OAA6B,UAAA;MAAuB,CAAA;MAC9D,kBAAC,KAAD;OAAG,OAAM;OAAoB,UAAA;MAG1B,CAAA;MACH,kBAAC,UAAD;OACE,MAAK;OACL,OAAO,EAAG,uBAAuB,KAAiB,WAAW;OAC7D,UAAU;OACV,eAAe;QACb,AAAI,KACF,EAAW,GACX,EAAiB,EAAK,KAEtB,EAAiB,EAAI;OAEzB;OAEC,UAAA,IACG,aACA,IACE,iCACA;MACA,CAAA;MACP,IAAgB,kBAAC,KAAD;OAAG,OAAM;OAAsB,UAAA;MAAiB,CAAA,IAAI;KAC9D;IACP,CAAA,IAAA;GACD;EACF,CAAA,CAAA;;AAET;AAMA,SAAS,GAAU,GAAwB;CACzC,IAAI;EACF,OAAO,IAAI,IAAI,CAAM,CAAC,CAAC;CACzB,QAAQ;EACN,OAAO;CACT;AACF;;;ACxJA,SAAgB,GAAe,EAAE,cAAoC;CACnE,IAAM,EAAE,QAAK,aAAU,GAAa;CAyBpC,OACE,kBAAC,OAAD;EAAK,OAAM;EAAX,UAAA,CACE,kBAAC,UAAD;GAAQ,OAAM;GAAd,UAAA,CACE,kBAAC,QAAD;IAAM,OAAM;IAAiB,UAAA;GAAwB,CAAA,GACrD,kBAAC,UAAD;IACE,MAAK;IACL,OAAM;IACN,OAAM;IACN,cAAW;IACX,SAAS;IAET,UAAA,kBAAC,IAAD,EAAW,MAAM,GAAK,CAAA;GAChB,CAAA,CACF;EAER,CAAA,GAAA,kBAAC,OAAD;GAAK,OAAM;GAAX,UAAA,CACG,CApCL;IACE,OAAO;IACP,OAAO;KACL;MAAE,QAAQ,CAAC,CAAC,GAAG,CAAC;MAAG,OAAO;KAAiB;KAC3C;MAAE,QAAQ,CAAC,CAAC,GAAK,GAAG,CAAC;MAAG,OAAO;KAAsB;KACrD;MAAE,QAAQ,CAAC,CAAC,KAAK,CAAC;MAAG,OAAO;KAAoC;IAClE;GACF,GACA;IACE,OAAO;IACP,OAAO;KACL;MAAE,QAAQ,CAAC,CAAC,GAAG,CAAC;MAAG,OAAO;KAAqB;KAC/C;MAAE,QAAQ,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC;MAAG,OAAO;KAA+B;KAChE;MAAE,QAAQ,CAAC,CAAC,CAAK,GAAG,CAAC,KAAK,CAAC;MAAG,OAAO;KAA8B;KACnE;MAAE,QAAQ,CAAC,CAAC,GAAK,CAAK,CAAC;MAAG,OAAO;KAAmB;KACpD;MAAE,QAAQ,CAAC,CAAC,KAAK,CAAC;MAAG,OAAO;KAA0B;IACxD;GACF,CAmBK,CAAA,CAAO,KAAK,MACX,kBAAC,WAAD;IAA2B,OAAM;IAAjC,UAAA,CACE,kBAAC,MAAD;KAAI,OAAM;KAA8B,UAAA,EAAM;IAAU,CAAA,GACxD,kBAAC,MAAD;KAAI,OAAM;KACP,UAAA,EAAM,MAAM,KAAK,MAChB,kBAAC,MAAD;MAAqB,OAAM;MAA3B,UAAA,CACE,kBAAC,QAAD;OAAM,OAAM;OAAyB,UAAA,EAAK;MAAY,CAAA,GACtD,kBAAC,QAAD;OAAM,OAAM;OACT,UAAA,EAAK,OAAO,KAAK,GAAO,MACvB,kBAAC,QAAD;QAA4B,OAAM;QAAlC,UAAA,CACG,IAAI,IAAI,kBAAC,QAAD;SAAM,OAAM;SAAqB,UAAA;QAAQ,CAAA,IAAI,MACrD,EAAM,KAAK,MACV,kBAAC,OAAD;SAAe,OAAM;SAClB,UAAA;QACE,GAFK,CAEL,CACN,CACG;OAPK,GAAA,EAAM,KAAK,GAAG,CAOnB,CACP;MACG,CAAA,CACJ;KAdK,GAAA,EAAK,KAcV,CACL;IACC,CAAA,CACG;GArBK,GAAA,EAAM,KAqBX,CACV,GAED,kBAAC,KAAD;IAAG,OAAM;IAAT,UAAA,CACG,GAAI,+HAEJ;GACA,CAAA,CAAA;EACF,CAAA,CAAA;;AAET;;;AC7EA,IAAM,KAAmB;CAAC;CAAM;CAAM;CAAM;CAAM;CAAM;AAAG,GAmCrD,KAAiB,GAAqC;CAC1D,MAAM;EACJ,6BAA6B;GAAE,MAAM;GAAe,eAAe;EAAM;EACzE,wBAAwB,GAAG,OAAO;GAChC,MAAM;GACN,WAAW,EAAE;GACb,WAAW,EAAE;GACb,eAAe;EACjB;EACA,2BAA2B,GAAG,OAAO;GACnC,MAAM;GACN,WAAW,EAAE;GACb,WAAW,EAAE;EACf;EACA,eAAe,GAAG,OAAO;GAAE,MAAM;GAAW,WAAW,EAAE;GAAW,OAAO,EAAE;EAAK;CACpF;CACA,eAAe;EACb,6BAA6B,EAAE,MAAM,OAAO;EAC5C,sBAAsB,OAAO;GAAE,GAAG;GAAG,eAAe;EAAK;EACzD,gBAAgB,EAAE,MAAM,OAAO;CACjC;CACA,gBAAgB;EAGd,wBAAwB,GAAG,MAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,OAAO,IAAI;EACnF,uBAAuB,OAAO;GAAE,GAAG;GAAG,eAAe;EAAK;EAG1D,eAAe,GAAG,OAAO;GAAE,MAAM;GAAW,WAAW,EAAE;GAAW,OAAO,EAAE;EAAK;EAClF,gBAAgB,EAAE,MAAM,OAAO;CACjC;CACA,mBAAmB;EACjB,2BAA2B,GAAG,MAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,OAAO,IAAI;EACtF,gBAAgB,EAAE,MAAM,OAAO;CACjC;CACA,SAAS;EAEP,iBAAiB,GAAG,OAAO;GAAE,GAAG;GAAG,OAAO,EAAE;EAAM;EAClD,gBAAgB,EAAE,MAAM,OAAO;CACjC;AACF,CAAC;AAOD,SAAgB,GAAc,EAC5B,WACA,eACA,oBACA,eACA,wBACA,gBACA,cACA,cACA,UACA,cAAW,IACX,aAAU,CAAC,GACX,aACA,aACA,YACA,YACA,kBACA,oBACA,qBACA,cACA,eAgCC;CACD,IAAM,IAAM,EAAuB,IAAI,GACjC,IAAc,EAAyB,IAAI,GAC3C,IAAY,EAA0B,IAAI,GAG1C,IAAe,EAA2B,IAAI,GAC9C,CAAC,GAAS,KAAe,GAAW,IAAgB,EAAE,MAAM,OAAO,CAAC,GAGpE,CAAC,GAAS,KAAc,EAA+C,IAAI,GAG3E,EAAE,eAAe,GAAqB,mBAAe,GAAQ;EACjE,WAAW;EACX,cAAc,MAEL,CADQ,EAAE,QACD,QAAQ,oCAAoC;EAE9D,QAAQ;CACV,CAAC;CACD,GAAa,GAAK,EAAI;CAEtB,IAAM,IAAa,EAAO,cAAc,MAIlC,IAAkB,SAChB,EAAO,SAAS,QAAQ,MAAM,CAAC,EAAE,OAAO,GAC9C,CAAC,EAAO,QAAQ,CAClB;CAmBA,AAdA,QAAgB;EACd,IAAI,EAAQ,SAAS,UAAU,EAAQ,SAAS,WAAW;EAC3D,SAAS,EAAO,GAAe;GAC7B,IAAM,IAAK,EAAa;GACxB,AAAI,KAAM,CAAC,EAAE,aAAa,CAAC,CAAC,SAAS,CAAE,KACrC,EAAY,EAAE,MAAM,UAAU,CAAC;EAEnC;EAEA,OADA,SAAS,iBAAiB,aAAa,CAAM,SAChC,SAAS,oBAAoB,aAAa,CAAM;CAC/D,GAAG,CAAC,EAAQ,MAAM,CAAW,CAAC,GAI9B,QAAgB;EACd,IAAI,EAAQ,SAAS,WAAW;EAChC,IAAM,IAAI,EAAO,SAAS,MAAM,MAAM,EAAE,QAAQ,EAAQ,SAAS;EACjE,CAAI,CAAC,KAAK,EAAE,YAAS,EAAY,EAAE,MAAM,UAAU,CAAC;CACtD,GAAG;EAAC,EAAO;EAAU;EAAS;CAAW,CAAC;CAE1C,IAAM,IAAc,EAAO,EAAI;CAc/B,AAbA,QAAgB;EACd,IAAM,IAAK,EAAY;EAClB,OACL;OAAI,EAAY,SAAS;IAEvB,AADA,EAAY,UAAU,IACtB,EAAG,YAAY,EAAG;IAClB;GACF;GAEA,AAD2B,EAAG,eAAe,EAAG,YAAY,EAAG,eACtC,OAAI,EAAG,YAAY,EAAG;EAF/C;CAGF,GAAG,CAAC,EAAgB,MAAM,CAAC,GAG3B,QAAgB;EACd,IAAM,IAAK,EAAI;EACf,IAAI,CAAC,GAAI;EAET,IAAI,OAAO,EAAG,eAAgB,cAAc,CAAC,EAAG,QAAQ,eAAe,GACrE,IAAI;GACF,EAAG,YAAY;EACjB,QAAQ,CAER;EAGF,SAAS,EAAS,GAAU;GAE1B,AAAI,EAAG,aAAa,YAAU,EAAQ;EACxC;EAEA,OADA,EAAG,iBAAiB,UAAU,CAAQ,SACzB,EAAG,oBAAoB,UAAU,CAAQ;CACxD,GAAG,CAAC,CAAO,CAAC;CAGZ,IAAM,KAAW,SAAc;EAC7B,IAAM,IAAQ,GAAc;GAC1B,SAAS,EAAO;GAChB,SAAS,EAAO;GAChB,gBAAgB,EAAO;EACzB,CAAC;EASD,OAAO;GAAE,MANI,GACX,EAAM,QAAQ,OAAO,UAAU,IAC/B,IACA,OAAO,aAAa,MAAQ,EAGrB;GAAM,KADH,GAAM,EAAM,QAAQ,OAAO,UAAU,IAAI,IAAQ,OAAO,cAAc,GACnE;EAAI;CACrB,GAAG;EAAC,EAAO;EAAS,EAAO;EAAS,EAAO;CAAc,CAAC;CAE1D,OACE,kBAAC,OAAD;EACO;EACL,IAAG;EACH,OAAO,EACL,kBACA,KAAW,eACX,MAAc,eACd,KAAY,eACd;EACA,SAAQ;EACR,OAAO;GACL,kBAAkB,GAAG,GAAS,QAAQ,GAAS,KAAK;GACpD,kBAAkB,GAAG,GAAS,OAAO,GAAS,IAAI;EACpD;EACA,MAAK;EACL,cAAW;EACX,eAAa,KAAY,KAAA;EAhB3B,UAAA;GAkBE,kBAAC,UAAD;IAAQ,OAAM;IAAwB,eAAe;IAArD,UAAA,CASE,kBAAC,QAAD;KAAM,OAAM;KAAuB,OAAO,EAAO;KAC9C,UAAA,EAAgB,WAAW,IAAI,cAAc,GAAG,EAAgB,OAAO;IACpE,CAAA,GACN,kBAAC,OAAD;KAAK,OAAM;KAAX,UAAA;MACE,kBAAC,OAAD;OACE,OAAM;OACN,MAAM,MAAO;QACX,AAAI,EAAQ,SAAS,kBAAe,EAAa,UAAU;OAC7D;OAJF,UAAA,CAME,kBAAC,UAAD;QACE,MAAK;QACL,OAAO,EAAG,mBAAmB,EAAQ,SAAS,iBAAiB,SAAS;QACxE,OAAM;QACN,eAAe,EAAY,EAAE,MAAM,qBAAqB,CAAC;QAEzD,UAAA,kBAAC,IAAD,EAAc,MAAM,GAAK,CAAA;OACnB,CAAA,GACP,EAAQ,SAAS,gBAChB,kBAAC,OAAD;QAAK,OAAM;QAAX,UAAA,CACE,kBAAC,UAAD;SACE,MAAK;SACL,OAAM;SACN,eAAe;UACb,IAAM,IAAM,IAAI,IAAI,EAAO,GAAG;UAG9B,AAFA,EAAI,OAAO,iBAAiB,EAAO,OACnC,UAAU,UAAU,UAAU,EAAI,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,GAC5D,EAAY,EAAE,MAAM,UAAU,CAAC;SACjC;SACD,UAAA;QAEO,CAAA,GACP,IACC,kBAAC,UAAD;SACE,MAAK;SACL,OAAO,EAAG,2BAA2B,EAAQ,iBAAiB,WAAW;SACzE,UAAU;SACV,eAAe;UAGT,EAAQ,SAAS,kBACjB,EAAQ,iBACV,EAAY,EAAE,MAAM,UAAU,CAAC,GAC/B,EAAS,KAET,EAAY,EAAE,MAAM,oBAAoB,CAAC;SAE7C;SAEC,UAAA,EAAQ,gBAAgB,mBAAmB;QACtC,CAAA,IACN,IACD;OACH,CAAA,IAAA,IACD;;MACJ,IACC,kBAAC,UAAD;OACE,MAAK;OACL,OAAM;OACN,OAAM;OACN,UAAU;OACV,SAAS;OAET,UAAA,kBAAC,IAAD,EAAW,MAAM,GAAK,CAAA;MAChB,CAAA,IACN;MACJ,kBAAC,UAAD;OAAQ,MAAK;OAAS,OAAM;OAAkB,OAAM;OAAe,SAAS;OAC1E,UAAA,kBAAC,IAAD,EAAW,MAAM,GAAK,CAAA;MAChB,CAAA;KACL;IACC,CAAA,CAAA;;GAER,kBAAC,MAAD;IAAI,KAAK;IAAa,OAAM;IACzB,UAAA,EAAgB,KAAK,GAAG,MAAM;KAC7B,IAAM,IACJ,CAAC,EAAE,iBAAiB,KAAmB,QAAQ,EAAE,mBAAmB,GAChE,IAAU,MAAM,GAChB,IAAU,KAAS,CAAC,KAAc,CAAC,EAAE,SACrC,IAAY,KAAS,CAAC,KAAc,CAAC,EAAE,WAAW,CAAC,GACnD,IAAY,EAAQ,SAAS,aAAa,EAAQ,cAAc,EAAE,KAClE,KAAW,KAAW,MAAc,CAAC,KAAa,CAAC,EAAE,SACrD,IAAa,EAAQ,SAAS,kBAAkB,EAAQ,cAAc,EAAE,KACxE,IAAkB,KAAc,EAAQ,eACxC,IAAe,EAAQ,SAAS,qBAAqB,EAAQ,cAAc,EAAE,KAC7E,IAAkB,IAAe,EAAQ,YAAY,QACrD,IAAgB,IAAa,EAAQ,YAAY;KACvD,OACE,kBAAC,MAAD;MAAgB,OAAM;MAAtB,UAAA;OACE,kBAAC,IAAD;QACE,MAAM,EAAE;QACR,OAAO,EAAE;QACT,MAAM,GAAW,EAAE,kBAAkB,EAAE,UAAU;OAClD,CAAA;OACD,kBAAC,OAAD;QAAK,OAAM;QAAX,UAAA;SACE,kBAAC,QAAD;UAAM,OAAM;UAAyB,UAAA,EAAE;SAAiB,CAAA;SAavD,EAAE,gBAAgB,QACjB,kBAAC,QAAD;UACE,OAAM;UACN,MAAK;UACL,cAAW;UACX,OAAM;UAEN,UAAA,kBAAC,IAAD,EAAS,MAAM,GAAK,CAAA;SAChB,CAAA,IACJ;SACJ,kBAAC,QAAD;UACE,OAAM;UACN,UAAU,IAAI,KAAK,EAAE,SAAS,CAAC,CAAC,YAAY;UAC5C,OAAO,GAAW,EAAE,SAAS;UAE5B,UAAA,GAAa,EAAE,SAAS;SACrB,CAAA;SACL,EAAE,YAAY,OAQX,OAPF,kBAAC,QAAD;UACE,OAAM;UACN,UAAU,IAAI,KAAK,EAAE,QAAQ,CAAC,CAAC,YAAY;UAC3C,OAAO,GAAW,EAAE,QAAQ;UAC7B,UAAA;SAEK,CAAA;SAER,kBAAC,OAAD;UAAK,OAAM;UAAX,UAAA,CACG,CAAC,KAAc,CAAC,IACf,kBAAC,IAAD;WACE,SAAS;WACT,YAAY;WACK;WACjB,YAAY,EAAgB,WAAW;WACvC,YAAY,MAAO;YACjB,AAAI,MAAc,EAAa,UAAU;WAC3C;WACA,gBAAgB,MAAM;YACpB,IAAI,GAAc;aAChB,EAAY;cACV,MAAM;cACN,WAAW,EAAE;cACb,WAAW;aACb,CAAC;aACD;YACF;YAIA,IAAI,EAAgB,WAAW,GAAG;aAChC,EAAY;cACV,MAAM;cACN,WAAW,EAAE;cACb,WAAW;aACb,CAAC;aACD;YACF;YAKA,IAAM,IADU,EAAE,cACU,sBAAsB,GAC5C,IAAgB,EAAY,SAAS,sBAAsB,GAE3D,IAAa,IACf,EAAc,SAAS,EAAY,SACnC;YACJ,EAAY;aACV,MAAM;aACN,WAAW,EAAE;aACb,WAAW,IAAa,KAAkB,OAAO;YACnD,CAAC;WACH;WACA,iBAAiB,MAAU;YAEzB,AADA,EAAY,EAAE,MAAM,UAAU,CAAC,GAC/B,EAAiB,EAAE,KAAK,CAAK;WAC/B;UACD,CAAA,IACC,MACH,IACC,kBAAC,OAAD;WACE,OAAO,EACL,0CACA,KAAc,WACd,KAAc,MAAkB,QAAQ,SACxC,EAAgB,WAAW,KAAK,SAClC;WACA,MAAM,MAA8B;YAClC,AAAI,MAAY,EAAa,UAAU;WACzC;WATF,UAAA,CAWE,kBAAC,UAAD;YACE,MAAK;YACL,OAAO,EAAG,mBAAmB,KAAc,SAAS;YACpD,OAAM;YACN,UAAU,MAAM;aACd,IAAI,GAAY;cACd,EAAY;eACV,MAAM;eACN,WAAW,EAAE;eACb,WAAW;cACb,CAAC;cACD;aACF;aAKA,IAAI,EAAgB,WAAW,GAAG;cAChC,EAAY;eACV,MAAM;eACN,WAAW,EAAE;eACb,WAAW;cACb,CAAC;cACD;aACF;aAMA,IAAM,IADU,EAAE,cACU,sBAAsB,GAC5C,IAAgB,EAAY,SAAS,sBAAsB,GAE3D,KADa,OAAoB,QACH,KAAK,IAAI,GACvC,IAAa,IACf,EAAc,SAAS,EAAY,SACnC;aACJ,EAAY;cACV,MAAM;cACN,WAAW,EAAE;cACb,WAAW,IAAa,IAAkB,OAAO;aACnD,CAAC;YACH;YAEA,UAAA,kBAAC,IAAD,EAAc,MAAM,GAAK,CAAA;WACnB,CAAA,GACP,IACC,kBAAC,OAAD;YAAK,OAAM;YAAX,UAAA,CACG,IACC,kBAAC,UAAD;aACE,MAAK;aACL,OAAM;aACN,eAAe;cACb,EAAY;eACV,MAAM;eACN,WAAW,EAAE;eACb,MAAM,EAAE;cACV,CAAC;aACH;aACD,UAAA;YAEO,CAAA,IACN,MACH,IACC,kBAAC,UAAD;aACE,MAAK;aACL,OAAO,EAAG,2BAA2B,KAAmB,WAAW;aACnE,eAAe;cACT,EAAQ,SAAS,mBACjB,EAAQ,iBACV,EAAY,EAAE,MAAM,UAAU,CAAC,GAC/B,EAAgB,EAAE,GAAG,KAErB,EAAY,EAAE,MAAM,qBAAqB,CAAC;aAE9C;aAEC,UAAA,IAAkB,mBAAmB;YAChC,CAAA,IACN,IACD;WACH,CAAA,IAAA,IACD;UACH,CAAA,IAAA,IACD;;QACF;;OACJ,KAAa,EAAQ,SAAS,YAC7B,kBAAC,QAAD;QACE,OAAM;QACN,UAAU,OAAO,MAAM;SAErB,IADA,EAAE,eAAe,GACb,EAAQ,SAAS,WAAW;SAChC,IAAM,IAAO,EAAQ,MAAM,KAAK;SAChC,IAAI,CAAC,KAAQ,MAAS,EAAE,MAAM;UAC5B,EAAY,EAAE,MAAM,UAAU,CAAC;UAC/B;SACF;SACA,IAAI;UAEF,AADA,MAAM,EAAc,EAAE,KAAK,CAAI,GAC/B,EAAY,EAAE,MAAM,UAAU,CAAC;SACjC,QAAQ,CAGR;QACF;QAjBF,UAAA,CAsBE,kBAAC,IAAD;SACE,OAAM;SACN,OAAM;SACN,OAAO,EAAQ;SACf,WAAW,MAAU,EAAY;UAAE,MAAM;UAAgB;SAAM,CAAC;SACvD;SACT,WAAA;SACA,UAAU;QACX,CAAA,GACD,kBAAC,OAAD;SAAK,OAAM;SAAX,UAAA,CACE,kBAAC,UAAD;UACE,MAAK;UACL,OAAM;UACN,eAAe,EAAY,EAAE,MAAM,UAAU,CAAC;UAC9C,UAAU;UACX,UAAA;SAEO,CAAA,GACR,kBAAC,UAAD;UACE,MAAK;UACL,OAAM;UACN,UAAU,KAAa,EAAQ,MAAM,KAAK,CAAC,CAAC,WAAW;UACxD,UAAA;SAEO,CAAA,CACL;QACD,CAAA,CAAA;OAEN,CAAA,IAAA,kBAAC,IAAD;QAAiB,MAAM,EAAE;QAAM,UAAU,EAAE;OAAW,CAAA;OAEvD,MAAM,KAAK,EAAO,gBACjB,kBAAC,UAAD;QACE,MAAK;QACL,OAAM;QACN,eAAe,EAAU,SAAS,UAAU;QAE5C,UAAA,kBAAC,OAAD;SAAK,KAAK,EAAO;SAAe,KAAI;QAAc,CAAA;OAC5C,CAAA,IACN;OACH,CAAC,KAAa,EAAE,UAAU,SAAS,IAClC,kBAAC,IAAD;QACE,SAAS;QACG;QACZ,WAAW,MAAU,EAAiB,EAAE,KAAK,CAAK;OACnD,CAAA,IACC;MACF;KAzQK,GAAA,EAAE,GAyQP;IAER,CAAC;GACC,CAAA;GAEH,EAAO,gBACN,kBAAC,UAAD;IAAQ,KAAK;IAAW,OAAM;IAAkB,eAAe,EAAU,SAAS,MAAM;IAAxF,UAAA,CACE,kBAAC,UAAD;KACE,MAAK;KACL,OAAM;KACN,cAAW;KACX,UAAU,MAAM;MAEd,AADA,EAAE,gBAAgB,GAClB,EAAU,SAAS,MAAM;KAC3B;KAEA,UAAA,kBAAC,IAAD,EAAW,MAAM,GAAK,CAAA;IAChB,CAAA,GACR,kBAAC,OAAD;KACE,OAAM;KACN,KAAK,EAAO;KACZ,KAAI;KACJ,UAAU,MAAM,EAAE,gBAAgB;IACnC,CAAA,CACK;GACN,CAAA,IAAA;GAEH,KAAc,OACb,kBAAC,IAAD;IACa;IACX,cAAc;IACD;IACb,UAAU;IACV,UAAU;IACA;GACX,CAAA,IAED,kBAAC,OAAD;IAAK,OAAM;IAAX,UAAA,CACE,kBAAC,KAAD;KAAG,OAAM;KAAT,UAAA;MAAiC;MACnB,kBAAC,QAAD;OAAM,OAAM;OAAuB,UAAA;MAAiB,CAAA;MAC/D,IAAa,kBAAC,QAAD;OAAM,OAAM;OAAuB,UAAA;MAAU,CAAA,IAAI;KAC9D;IACH,CAAA,GAAA,kBAAC,IAAD;KACE,OAAM;KACN,aAAY;KACZ,aAAY;KACZ,cAAc;KACH;KACJ;KACP,UAAU;KACD;IACV,CAAA,CACE;;EAEJ;;AAET;AAQA,SAAS,GAAY,EACnB,YACA,eACA,oBACA,eACA,cACA,kBACA,qBASC;CACD,OACE,kBAAC,OAAD;EACE,OAAO,EACL,+BACA,KAAc,WACd,KAAc,MAAoB,QAAQ,SAC1C,KAAc,SAChB;EACA,KAAK;EAPP,UAAA,CASE,kBAAC,UAAD;GACE,MAAK;GACL,OAAO,EAAG,mBAAmB,KAAc,SAAS;GACpD,OAAM;GACN,cAAW;GACX,SAAS;GAET,UAAA,kBAAC,IAAD,EAAW,MAAM,GAAK,CAAA;EAChB,CAAA,GACP,IACC,kBAAC,OAAD;GAAK,OAAM;GAAyB,MAAK;GACtC,UAAA,GAAiB,KAAK,MAGnB,kBAAC,UAAD;IAEE,MAAK;IACL,MAAK;IACL,OAAO,EAAG,gCAND,EAAQ,UAAU,MAAM,MAAM,EAAE,UAAU,CAAK,CAAC,EAAE,QAAQ,OAMlB,SAAS;IAC1D,eAAe,EAAe,CAAK;IAElC,UAAA;GACK,GAPD,CAOC,CAEX;EACE,CAAA,IACH,IACD;;AAET;AAOA,SAAS,GAAc,EACrB,YACA,eACA,eAKC;CACD,OACE,kBAAC,OAAD;EAAK,OAAM;EACR,UAAA,EAAQ,UAAU,KAAK,MAAM;GAC5B,IAAM,IAAU,GAAe,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK;GACnE,OACE,kBAAC,UAAD;IAEE,MAAK;IACL,OAAO,EAAG,wBAAwB,EAAE,QAAQ,SAAS;IACrD,UAAU;IACV,eAAe,EAAS,EAAE,KAAK;IAC/B,gBAAc,EAAE;IAChB,cAAY;IACZ,OAAO;IART,UAAA,CAUE,kBAAC,QAAD;KAAM,OAAM;KAAwB,eAAA;KACjC,UAAA,EAAE;IACC,CAAA,GACN,kBAAC,QAAD;KAAM,OAAM;KAAyB,UAAA,EAAE;IAAY,CAAA,CAC7C;GAbD,GAAA,EAAE,KAaD;EAEZ,CAAC;CACE,CAAA;AAET;AAUA,SAAS,GAAe,GAAoB,GAAe,GAAe,GAAuB;CAC/F,IAAM,IAAkB,EAAS,MAAM,GACjC,IAAe,EAAM,SAAU,MAC/B,IAAY,KAAK,IAAI,GAAG,IAAQ,CAAY;CAUlD,OATI,IAAY,KACd,EAAM,KAAK,GAAG,EAAU,QAAQ,MAAc,IAAI,KAAK,KAAK,GAE1D,KAAM,EAAM,KAAK,KAAK,GACtB,EAAM,WAAW,IAAU,GAAG,EAAM,gBAAgB,MAKjD,GAHL,EAAM,WAAW,IACb,EAAM,KACN,GAAG,EAAM,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,OAAO,EAAM,EAAM,SAAS,KACjD,gBAAgB;AACpC;AAEA,SAAS,GAAM,GAAe,GAAa,GAAqB;CAC9D,OAAO,KAAK,IAAI,GAAK,KAAK,IAAI,GAAK,CAAK,CAAC;AAC3C;AAgBA,SAAS,GAAc,EAAE,SAAM,UAAO,WAAwD;CAC5F,IAAM,CAAC,GAAW,KAAgB,EAAwB,IAAI;CAE9D,OACE,kBAAC,QAAD;EAAM,OAAM;EAAwB,aAAW;EAAM,eAAA;EAClD,UAHa,KAAS,QAAQ,MAAc,IAI3C,kBAAC,OAAD;GACE,OAAM;GACN,KAAK;GACL,KAAI;GACJ,SAAQ;GACR,UAAS;GACT,gBAAe;GACf,eAAe,EAAa,CAAK;EAClC,CAAA,IAED,kBAAC,QAAD;GAAM,OAAM;GAA0B,UAAA,GAAe,CAAI;EAAQ,CAAA;CAE/D,CAAA;AAEV;AAEA,SAAS,GAAe,GAAsB;CAC5C,IAAM,IAAU,EAAK,KAAK;CAC1B,IAAI,CAAC,GAAS,OAAO;CACrB,IAAM,IAAQ,EAAQ,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO,GAC3C,IAAQ,EAAM,MAAM;CAC1B,IAAI,EAAM,WAAW,GAAG,OAAO,EAAM,MAAM,GAAG,CAAC,CAAC,CAAC,YAAY;CAC7D,IAAM,IAAO,EAAM,EAAM,SAAS,MAAM;CACxC,SAAS,EAAM,MAAM,OAAO,EAAK,MAAM,IAAA,CAAK,YAAY;AAC1D;AAIA,SAAS,GAAW,GAAsB;CACxC,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK,IAAK,IAAI,KAAK,EAAK,WAAW,CAAC,IAAK;CAC1E,OAAQ,KAAK,IAAI,CAAC,IAAI,IAAK;AAC7B;AAEA,SAAS,GAAa,GAAoB;CACxC,IAAM,IAAO,KAAK,IAAI,IAAI,GACpB,IAAM,KAAK,MAAM,IAAO,GAAI;CAClC,IAAI,IAAM,IAAI,OAAO;CACrB,IAAM,IAAM,KAAK,MAAM,IAAM,EAAE;CAC/B,IAAI,IAAM,IAAI,OAAO,GAAG,EAAI,SAAS,MAAQ,IAAI,KAAK,IAAI;CAC1D,IAAM,IAAK,KAAK,MAAM,IAAM,EAAE;CAC9B,IAAI,IAAK,IAAI,OAAO,GAAG,EAAG,OAAO,MAAO,IAAI,KAAK,IAAI;CACrD,IAAM,IAAM,KAAK,MAAM,IAAK,EAAE;CAS9B,OARI,IAAM,KAAW,GAAG,EAAI,MAAM,MAAQ,IAAI,KAAK,IAAI,QACpC,IAAI,KAAK,CAAE,CAAC,CAAC,YAAY,uBAAM,IAAI,KAAK,EAAA,CAAE,YAAY,IAEhE,IAAI,KAAK,CAAE,CAAC,CAAC,mBAAmB,CAAC,GAAG;EACzC,OAAO;EACP,KAAK;CACP,CAAC,IAEI,IAAI,KAAK,CAAE,CAAC,CAAC,mBAAmB,CAAC,GAAG;EACzC,OAAO;EACP,KAAK;EACL,MAAM;CACR,CAAC;AACH;AAEA,SAAS,GAAW,GAAoB;CAEtC,OAAO,IADU,KAAK,CACf,CAAA,CAAK,mBAAmB,CAAC,GAAG;EACjC,OAAO;EACP,KAAK;EACL,MAAM;EACN,MAAM;EACN,QAAQ;CACV,CAAC;AACH;;;ACt4BA,SAAgB,GAAQ,EACtB,aACA,aACA,WACA,cAAW,gBACX,iBAAc,GACd,eAAY,IACZ,gBACA,eAAY,IACZ,iBAAc,IACd,iBACA,mBACA,qBAqBC;CACD,IAAM,IACJ,MAAa,gBACT,wBACA,MAAa,kBACX,0BACA;CAER,SAAS,EAAmB,GAAe;EAGzC,IAFA,EAAE,eAAe,GACjB,EAAE,gBAAgB,IACb,EAAE,WAAW,EAAE,YAAY,GAAQ;GACtC,EAAO;GACP;EACF;EACA,EAAS;CACX;CAEA,OACE,kBAAC,OAAD;EACE,OAAO,EAAG,kBAAkB,CAAS;EACrC,MAAK;EACL,cAAW;EAHb,UAAA;GAKE,kBAAC,UAAD;IACE,MAAK;IACL,OAAM;IACN,aAAU;IACV,cAAY,IAAW,SAAS,KAAA;IAChC,OAAO,IAAW,0BAA0B;IAC5C,gBAAc;IACd,SAAS;IAER,UAAW,EAAX,IAAY,KAA0B,IAA3B,EAAW,MAAM,GAAK,CAA4B;GACxD,CAAA;GAEP,IACC,kBAAC,UAAD;IACE,MAAK;IACL,OAAM;IACN,aAAU;IACV,WAAS,IAAY,SAAS,KAAA;IAC9B,OAAO,IAAc,IAAI,UAAU,EAAY,WAAW;IAC1D,gBAAc;IACd,UAAU,MAAM;KAGd,AAFA,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAClB,IAAc;IAChB;IAXF,UAAA,CAaE,kBAAC,IAAD,EAAW,MAAM,GAAK,CAAA,GACrB,IAAc,IACb,kBAAC,QAAD;KAAM,OAAM;KAAkB,eAAY;KACvC,UAAA,IAAc,IAAI,OAAO;IACtB,CAAA,IACJ,IACE;GACN,CAAA,IAAA;GAEH,IACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;IAAK,OAAM;IAAgB,eAAY;GAAQ,CAAA,GAC/C,kBAAC,UAAD;IACE,MAAK;IACL,OAAM;IACN,aAAU;IACV,cAAY,IAAc,cAAc;IACxC,gBAAc,CAAC;IACf,OAAO,IAAc,cAAc;IACnC,UAAU,MAAM;KAGd,AAFA,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAClB,EAAa;IACf;IAEC,UAAc,EAAd,IAAe,KAAwB,IAAzB,EAAS,MAAM,GAAK,CAA2B;GACxD,CAAA,CACR,EAAA,CAAA,IACA;GAEH,KAAkB,IAAiB,kBAAC,OAAD;IAAK,OAAM;IAAgB,eAAY;GAAQ,CAAA,IAAI;GAEtF;GACA;GAGC,IAUE,OATF,kBAAC,UAAD;IACE,MAAK;IACL,OAAM;IACN,aAAU;IACV,cAAW;IACX,UAAA;IAEA,UAAA,kBAAC,IAAD,EAAU,MAAM,GAAK,CAAA;GACf,CAAA;EAEP;;AAET;;;AC3EA,SAAS,GAAkB,GAA8C;CACvE,IAAM,IAAe;EACnB,UAAU,eAAe,EAAO,SAAS;EACzC,MAAM,EAAO,SAAS;EACtB,OAAO,EAAO,SAAS;EAGvB,OACE,EAAO,SAAS,SAAS,OAErB,KAAA,IADC,GAAe,EAAO,SAAS,OAAO,SAAS,IAAI,CAAC,EAAE,QAAQ,KAAA;CAEvE;CAEA,IAAI,EAAO,SAAS,WAElB,OADI,EAAO,kBAAkB,QAAQ,EAAO,yBAAyB,OAAa,OAC3E;EACL,SAAS;EACT,GAAG;EACH,gBAAgB,EAAO;EACvB,uBAAuB,EAAO;CAChC;CAGF,IAAI,CAAC,EAAO,SAAS,EAAO,kBAAkB,MAAM,OAAO;CAC3D,IAAM,IACJ,OAAO,EAAO,gBAAiB,YAAY,OAAO,EAAO,yBAA0B;CACrF,OAAO;EACL,SAAS;EACT,GAAG;EACH,OAAO,EAAO;EACd,gBAAgB,EAAO;EACvB,GAAI,IACA;GACE,cAAc,EAAO;GACrB,uBAAuB,EAAO;EAChC,IACA,CAAC;CACP;AACF;AA6BA,SAAS,KAAoC;CAC3C,IAAI,IAAyB,SAAS;CACtC,OAAO,KAAU,EAAO,cAAc,EAAO,WAAW,gBACtD,IAAS,EAAO,WAAW;CAE7B,IAAI,CAAC,GAAQ,OAAO;CACpB,IAAM,IAAM,EAAO;CAEnB,OADI,MAAQ,WAAW,MAAQ,cAAc,MAAQ,YAC7C,EAAuB;AACjC;AAIA,SAAS,KAAe;CACtB,OAAO,OAAO,SAAS,OAAO,OAAO,SAAS;AAChD;AAWA,IAAM,KAAa,GAAkC;CACnD,SAAS;EACP,0BAA0B,EAAE,MAAM,oBAAoB;EACtD,eAAe,EAAE,MAAM,SAAS;CAClC;CACA,qBAAqB;EACnB,eAAe,EAAE,MAAM,UAAU;EACjC,wBAAwB,EAAE,MAAM,SAAS;CAC3C;CACA,QAAQ,EACN,eAAe,EAAE,MAAM,UAAU,GACnC;AACF,CAAC;AAuBD,SAAS,GAAQ,GAAoC;CAEnD,OADA,GAAa,CAAI,GACV;AACT;AAEA,IAAM,KAAkB,GAA4C;CAClE,YAAY;EACV,iBAAiB,GAAG,MAAM,GAAQ;GAAE,MAAM;GAAQ,UAAU,EAAE;EAAS,CAAC;EACxE,cAAc,GAAG,MAAM,GAAQ;GAAE,MAAM;GAAY,UAAU,EAAE;EAAS,CAAC;CAC3E;CACA,MAAM;EACJ,cAAc,GAAG,MAAM,GAAQ;GAAE,MAAM;GAAY,UAAU,EAAE;EAAS,CAAC;EACzE,eAAe,GAAG,MAChB,GAAQ;GACN,MAAM;GACN,UAAU;IAAE,GAAG,EAAE;IAAU,MAAM,EAAE;IAAM,OAAO,EAAE;GAAM;EAC1D,CAAC;EAGH,mBAAmB,GAAQ,EAAE,MAAM,aAAa,CAAC;CACnD;CACA,UAAU;EACR,cAAc,GAAG,MAAM,GAAQ;GAAE,MAAM;GAAY,UAAU,EAAE;EAAS,CAAC;EACzE,eAAe,MACb,GAAQ;GACN,MAAM;GACN,WAAW;IAAE,MAAM,EAAE,SAAS;IAAM,OAAO,EAAE,SAAS;GAAM;EAC9D,CAAC;EAGH,oBAAoB,GAAQ,EAAE,MAAM,aAAa,CAAC;CACpD;CACA,YAAY;EACV,iBAAiB,GAAG,MAAM,GAAQ;GAAE,MAAM;GAAQ,UAAU,EAAE;EAAS,CAAC;EACxE,cAAc,GAAG,MAAM,GAAQ;GAAE,MAAM;GAAY,UAAU,EAAE;EAAS,CAAC;CAC3E;AACF,CAAC;AAED,SAAgB,GAAI,EAClB,WACA,WACA,cAAW,gBACX,gBACA,mBACW;CACX,IAAM,CAAC,GAAO,KAAY,EAAS,EAAY,GACzC,CAAC,GAAS,KAAc,EAAyB,CAAC,CAAC,GACnD,CAAC,GAAe,KAAoB,EAAS,EAAK,GAIlD,IAAkB,SAAc,GAAa,GAAG,CAAC,CAAC,GAClD,CAAC,GAAU,KAAgB,GAAW,IAAiB,EAAgB,KAAK,GAK5E,CAAC,GAAe,KAAoB,EAAyB,IAAI;CACvE,QAAgB;EACd,IAAI,IAAY;EAIhB,OAHA,GAAmC,GAAQ,CAAM,CAAC,CAAC,MAAM,MAAc;GACrE,AAAK,KAAW,EAAiB,CAAS;EAC5C,CAAC,SACY;GACX,IAAY;EACd;CACF,GAAG,CAAC,GAAQ,CAAM,CAAC;CAKnB,IAAM,CAAC,GAAiB,KAAsB,EAA0B,CAAQ,GAiB1E,CAAC,GAAa,KAAkB,EAAS,EAAI,GAC7C,CAAC,GAAiB,KAAsB,EAAS,EAAI,GACrD,CAAC,GAAO,KAAY,EAA2B,IAAI,GACnD,IAAa,QAAkB,EAAS,IAAI,GAAG,CAAC,CAAC,GAIjD,IAAc,EAAsB,CAAQ;CAMlD,AALA,EAAY,UAAU,GAKtB,GACE,GACA,GACA,IACC,MAAS,EAAa;EAAE,MAAM;EAAa,UAAU;CAAK,CAAC,SACtD,EAAa,EAAE,MAAM,eAAe,CAAC,CAC7C;CAEA,IAAM,IAAM,SAER,GAAgB;EACd;EACA;EACA,gBAAgB;GACd,IAAM,IAAI,EAAY;GAMtB,OALI,EAAE,SAAS,cAIX,EAAE,SAAS,SAAS,OAAa,OAC9B;IAAE,OAAO,EAAE,SAAS;IAAO,WAAW,EAAE,SAAS;GAAe;EACzE;EACA,sBAAsB;GACpB,IAAM,IAAI,EAAY;GAEtB,OADI,EAAE,SAAS,aACR,EAAE,SAAS,UADgB;EAEpC;EACA,oBAAoB;GAClB,IAAM,IAAI,EAAY;GAGtB,OADI,EAAE,SAAS,SACR,EAAE,SAAS,YADY;EAEhC;EACA,sBAAsB;GAGpB,EAAa,EAAE,MAAM,eAAe,CAAC;EACvC;CACF,CAAC,GACH;EAAC;EAAQ;EAAQ;CAAY,CAC/B,GACM,CAAC,GAAM,KAAW,EAAe,EAAE,MAAM,OAAO,CAAC,GAOjD,CAAC,IAAS,KAAc,EAAyB,CAAC,CAAC;CACzD,QAAgB;EACd,IAAI,IAAY;EAShB,OARA,EACG,YAAY,CAAC,CACb,MAAM,MAAQ;GACb,AAAK,KAAW,EAAW,EAAI,OAAO;EACxC,CAAC,CAAC,CACD,YAAY,CAEb,CAAC,SACU;GACX,IAAY;EACd;CACF,GAAG,CAAC,CAAG,CAAC;CAMR,IAAM,CAAC,GAAa,KAAkB,EAAS,CAAC,GAC1C,CAAC,IAAe,KAAoB,EAA+B,CAAC,CAAC,GACrE,CAAC,IAAsB,MAA2B,EAAS,EAAK,GAChE,CAAC,IAAoB,MAAyB,EAA6B,KAAA,CAAS,GACpF,CAAC,IAA6B,MAAkC,EAAS,EAAK,GAK9E,KAAqB,QAAkB;EAG3C,AAFA,GAAwB,EAAI,GAC5B,GAAsB,KAAA,CAAS,GAC/B,EACG,kBAAkB,CAAC,CACnB,MAAM,MAAQ;GACb,EAAiB,EAAI,aAAa;EACpC,CAAC,CAAC,CACD,OAAO,MAAiB;GACvB,GAAsB,aAAe,QAAQ,EAAI,UAAU,iBAAiB;EAC9E,CAAC,CAAC,CACD,cAAc;GACb,GAAwB,EAAK;EAC/B,CAAC;CACL,GAAG,CAAC,CAAG,CAAC,GAUF,KAAS,GAAe,GACxB,KAAe,GAAe,GAC9B,KAAiB,GAAe,GAChC,KAAiB,GAAe,GAChC,KAAgB,GAAe,GAI/B,EAAE,KAAK,GAAW,OAAO,OAAgB,IACzC,EAAE,KAAK,OAAc,IACrB,EAAE,KAAK,IAAa,OAAO,MAAkB,IAC7C,EAAE,KAAK,OAAgB,IACvB,EAAE,KAAK,OAAe,IACtB,KAAe,GAAc,WAE7B,KAAY,GAAO,WAGnB,KAAQ,GAAO,SAAS,GAAa,SAAS,GAAe,OAE7D,CAAC,IAAK,MAAW,GAAW,IAAY,EAAE,MAAM,UAAU,CAAC,GAC3D,KAAc,GAAI,SAAS,WAE3B,CAAC,IAAM,MAAa,EAAS,CAAC,GAG9B,KAAU,EAAuB,IAAI,GAErC,KAAa,GAAc,CAAQ,GACnC,KAAa,EAAS,SAAS,YAG/B,KAAsB,EAAS,SAAS,gBAAgB,EAAS,SAAS,cAC1E,KAAkB,GAAW,CAAQ;CAO3C,QAAgB;EACd,IAAI,EAAS,SAAS,gBAAgB,EAAS,SAAS,cAAc;EAGtE,IAAM,IACJ,EAAS,SAAS,eAAe,EAAS,YAAY,EAAgB,WAEpE,IAAY,IACZ,IAA8C,MAC9C,IAAY;EAEhB,SAAS,IAAO;GACd,EACG,iBAAiB,CAAC,CAClB,MAAM,EAAE,aAAU,eAAY;IAC7B,IAAI,GAAW;IACf,IAAM,IAAuB;KAC3B;KACA,WAAW;KACX,MAAM,EAAU;KAChB,OAAO,EAAU;IACnB;IACA,EAAa;KAAE,MAAM;KAAgB,UAAU;IAAO,CAAC;GACzD,CAAC,CAAC,CACD,YAAY;IACP,MAEJ,IAAQ,WAAW,GADN,KAAK,IAAI,GAAW,GACR,CAAI,GAC7B,IAAY,KAAK,IAAI,IAAY,GAAG,GAAM;GAC5C,CAAC;EACL;EAGA,OADA,EAAK,SACQ;GAEX,AADA,IAAY,IACR,KAAO,aAAa,CAAK;EAC/B;CACF,GAAG;EAAC;EAAK;EAAU;EAAc;CAAe,CAAC;CAEjD,IAAM,IAAoB,GAAqB,CAAG,GAQ5C,CAAC,IAAc,MAAmB,EAA8B,IAAI;CAC1E,QAAgB;EAGd,IAAM,IAAS,IAAI,GADL,EAAO,QAAQ,0BAA0B,eACvB,CAAK;EAErC,OADA,GAAgB,CAAM,SACT;GAEX,AADA,EAAO,MAAM,GACb,IAAiB,MAAa,MAAY,IAAS,OAAO,CAAQ;EACpE;CACF,GAAG,CAAC,CAAM,CAAC;CAGX,IAAM,IAAkB,EAAO,EAAK;CAqGpC,AApGA,QAAgB;EACV,OAAC,MAAgB,CAAC,IAKtB,OAFA,GAAY,GACZ,EAAc,GACP,GAAa,SAClB,GAA+B,yCAAyC,GAIxE;GAAE;GAAmB;GAAO,gBAAgB;EAAgB,IAC3D,MAAW;GACV,AAAI,MAAW,KAAA,MACb,EAAW,CAAM,GACjB,EAAiB,EAAI;EAEzB,CACF;CACF,GAAG;EAAC;EAAc;EAAmB;EAAO;EAAiB;EAAa;CAAa,CAAC,GAOxF,QAAgB;EACd,IAAI,EAAS,SAAS,YAAY;GAChC,EAAe,CAAC;GAChB;EACF;EACI,OAAC,MAAgB,CAAC,IACtB,OAAO,GAAa,SAClB,GAA+B,+CAA+C,GAC9E,EAAE,qBAAkB,IACnB,MAAW;GACV,AAAI,MAAW,KAAA,KACb,EAAe,EAAO,KAAK;EAE/B,CACF;CACF,GAAG;EAAC;EAAc;EAAmB,EAAS;CAAI,CAAC,GAOnD,QAAgB;EAEd,IADI,EAAgB,WAChB,CAAC,GAAe;EACpB,IAAM,IAAQ,OAAO,SAAS,KAAK,MAAM,uBAAuB;EAChE,IAAI,GAAO;GACT,IAAM,IAAW,mBAAmB,EAAM,MAAM,EAAE;GAMlD,AALe,EAAQ,MAAM,MAAM,EAAE,QAAQ,CACzC,KACF,EAAQ;IAAE,MAAM;IAAU;GAAS,CAAC,GAGtC,QAAQ,aAAa,MAAM,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,MAAM;EAClF;EACA,EAAgB,UAAU;CAC5B,GAAG,CAAC,GAAS,CAAa,CAAC,GAM3B,QAAgB,SAA8B,EAAS,GAAa,CAAC,CAAC,GAAG,CAAC,CAAC,GAK3E,QAAgB;EACd,SAAS,EAAU,GAAkB;GAC/B,EAAE,QAAQ,QACR,EAAE,WAAW,EAAE,aACjB,EAAE,UAAU,EAAE,aAClB,EAAE,eAAe,GACjB,GAAQ,EAAE,MAAM,SAAS,CAAC;EAC5B;EAEA,OADA,OAAO,iBAAiB,WAAW,CAAS,SAC/B,OAAO,oBAAoB,WAAW,CAAS;CAC9D,GAAG,CAAC,EAAO,CAAC,GAIZ,QAAgB;EACd,AAAI,MAAa,EAAS,IAAI;CAChC,GAAG,CAAC,EAAW,CAAC,GAIhB,QAAgB;EACd,IAAI,GAAI,SAAS,qBAAqB;EACtC,IAAM,IAAI,OAAO,iBAAiB,GAAQ,EAAE,MAAM,gBAAgB,CAAC,GAAG,GAAI;EAC1E,aAAa,OAAO,aAAa,CAAC;CACpC,GAAG,CAAC,GAAI,MAAM,EAAO,CAAC,GAGtB,QAAgB;EAGd,IAAI,IAAuB;EAC3B,SAAS,IAAO;GACV,AACJ,MAAQ,4BAA4B;IAElC,AADA,IAAQ,MACR,IAAW,MAAM,IAAI,CAAC;GACxB,CAAC;EACH;EAEA,AADA,OAAO,iBAAiB,UAAU,GAAM,EAAE,SAAS,GAAK,CAAC,GACzD,OAAO,iBAAiB,UAAU,CAAI;EAGtC,IAAM,IAAK,IAAI,eAAe,CAAI;EAElC,OADA,EAAG,QAAQ,SAAS,IAAI,SACX;GAIX,AAHA,OAAO,oBAAoB,UAAU,CAAI,GACzC,OAAO,oBAAoB,UAAU,CAAI,GACzC,EAAG,WAAW,GACV,KAAS,QAAM,qBAAqB,CAAK;EAC/C;CACF,GAAG,CAAC,CAAC;CAKL,IAAM,KAAe,QAAkB;EAIrC,AAHA,GAAY,GACZ,EAAc,GACd,EAAM,iBAAiB,GACvB,EAAQ,EAAE,MAAM,UAAU,CAAC;CAC7B,GAAG,CAAC,IAAa,CAAa,CAAC;CAI/B,QAAgB;EACd,SAAS,EAAU,GAAkB;GAC/B,EAAE,QAAQ,QACV,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,YACxC,EAAK,SAAS,WACd,MACA,GAAyB,MAC7B,EAAE,eAAe,GACjB,GAAa;EACf;EAEA,OADA,OAAO,iBAAiB,WAAW,CAAS,SAC/B,OAAO,oBAAoB,WAAW,CAAS;CAC9D,GAAG;EAAC,EAAK;EAAM;EAAa;CAAY,CAAC;CAEzC,IAAM,KAAS,QAAkB;EAG/B,AAFA,EAAQ,EAAE,MAAM,OAAO,CAAC,GACxB,GAAY,GACZ,EAAc;CAChB,GAAG,CAAC,IAAa,CAAa,CAAC,GAEzB,KAAoB,EAAO,CAAC,GAC5B,KAAc,GACjB,GAAoB,GAAiB,MAAoB;EACxD,IAAM,IAAQ,IAAU,OAAO,SACzB,IAAQ,IAAU,OAAO,SACzB,IAAe,EAAE,GAAkB;EAEzC,IAAI,GAAa,YAAY,MAAS,CAAC,GAAiB;GACtD,EAAQ;IACN,MAAM;IACN;IACA;IACA;IACA,YAAY;IACZ,uBAAuB;IACvB,kBAAkB;IAClB,yBAAyB;IACzB,6BAA6B,CAAC;IAC9B;GACF,CAAC;GACD;EACF;EAEA,EAAQ;GACN,MAAM;GACN;GACA;GACA;GACA,YAAY;GACZ,uBAAuB;GACvB,kBAAkB;GAClB,yBAAyB;GACzB,6BAA6B,CAAC;GAC9B;EACF,CAAC;EAGD,IAAM,IACJ,GAAQ,WAAW,QAAQ,GAAQ,QAAQ,YAAY,aAAa,aAC/D,GAAQ,QAAQ,YAAY,CAAC,CAAgB,OAC9C,MAEA,IAA2B;GAC/B,aAAa,GAAa;GAC1B,gBAAgB,GAAa;EAC/B;EAEA,GAAkB,GAAY;GAAE,GAAG;GAAS,GAAG;EAAQ,GAAG,CAAW,CAAC,CAAC,MAAM,MAAW;GAkBtF,AAjBA,GAAS,MAGH,EAAQ,SAAS,mBACjB,EAAQ,iBAAiB,IAAqB,IAC3C;IACL,GAAG;IACH,YAAY,GAAQ,QAAQ;IAC5B,uBAAuB;IAEvB,kBAAkB,KAAU;IAC5B,yBAAyB,GAAQ,iBAAiB;IAClD,6BAA6B,GAAQ,qBAAqB,CAAC;GAC7D,CACD,GAGD,EAAM,uBAAuB,EAAE,IAAI,KAAU,KAAK,CAAC;EACrD,CAAC;CACH,GACA,CAAC,GAAa,CAAe,CAC/B,GAEM,KAAe,GAClB,GAAc,MAAmB;EAGhC,EAAa;GAAE,MAAM;GAAc;GAAM;EAAM,CAAC;CAClD,GACA,CAAC,CAAY,CACf,GAIM,KAAc,GAAa,WAC3B,KAAS,EAAY,YAAY;EAErC,AADA,EAAM,iBAAiB,GACvB,MAAM,GAAU,YAAY;GAQ1B,IAAM,IAAW,GAAkB,MALd,GAAgB;IACnC;IACA;IACA,YAAY,MAAkB;GAChC,CAAC,CACwC;GACzC,IAAI,CAAC,GAGH,MAAU,MAAM,yCAAyC;GAG3D,AADA,EAAa;IAAE,MAAM;IAAa,UAAU;GAAS,CAAC,GACtD,EAAM,mBAAmB;EAC3B,CAAC;CACH,GAAG;EAAC;EAAQ;EAAQ;EAAe;EAAW;CAAY,CAAC,GAErD,KAAkB,EACtB,OAAO,GAAc,MAA+B;EAClD,IAAI,EAAK,SAAS,iBAAiB;EACnC,IAAM,IAAS,GAAe,CAAQ;EACjC,KACL,MAAM,EAAU,YAAY;GAC1B,IAAI;GAEJ,IAAI,KAAqB,EAAK,YAAY;IACxC,IAAM,EAAE,iBAAc,MAAM,EAAI,uBAAuB,GAInD;IACJ,IAAI;KACF,IAAY,MAAM,MAAM,GAAW;MACjC,QAAQ;MACR,SAAS,EAAE,gBAAgB,EAAK,WAAW,QAAQ,YAAY;MAC/D,MAAM,EAAK;MACX,QAAQ,YAAY,QAAQ,GAAM;KACpC,CAAC;IACH,SAAS,GAAK;KAIZ,MAHI,aAAe,gBAAgB,EAAI,SAAS,iBACpC,MAAM,2DAA2D,IAEvE;IACR;IAGA,IAAI,CAAC,EAAU,IACb,MAAU,MAAM,6BAA6B,EAAU,OAAO,EAAE;IAElE,IAAM,EAAE,iBAAe,MAAM,EAAU,KAAK;IAC5C,IAAsB;GACxB;GAEA,IAAM,IAAW,GAAsB,CAAI,GACrC,IAAM,MAAM,EAAI,aAAa;IACjC,KAAK,OAAO,SAAS;IACrB;IACA,gBAAgB,EAAK,OAAO;IAC5B,SAAS,EAAK,OAAO;IACrB,SAAS,EAAK,OAAO;IACrB,eAAe,EAAK,OAAO;IAC3B,eAAe,EAAK,OAAO;IAC3B,WAAW,EAAK,OAAO;IACvB,WAAW,EAAK,OAAO;IACvB,WAAW,UAAU;IACrB,YAAY,EAAO;IACnB,aAAa,EAAO;IACpB;IACA,UAAU,EAAS,SAAS,IAAI,IAAW,KAAA;IAC3C;GACF,CAAC;GAMD,AALA,GAAY,MAAY,CAAC,GAAG,GAAS,EAAI,MAAM,CAAC,GAChD,EAAM,qBAAqB;IACzB,eAAe,KAAuB;IACtC,aAAa,EAAS,SAAS;GACjC,CAAC,GACD,EAAQ;IAAE,MAAM;IAAU,UAAU,EAAI,OAAO;GAAI,CAAC;EACtD,CAAC;CACH,GACA;EAAC;EAAK;EAAU;EAAM;EAAO;CAAS,CACxC,GAEM,KAAe,EAAY,YAAY;EAC3C,IAAI,EAAK,SAAS,UAAU;EAC5B,IAAM,IAAW,EAAK;EACtB,MAAM,EAAU,YAAY;GAG1B,AAFA,MAAM,EAAI,aAAa,CAAQ,GAC/B,GAAY,MAAY,EAAQ,QAAQ,MAAM,EAAE,QAAQ,CAAQ,CAAC,GACjE,EAAQ,EAAE,MAAM,OAAO,CAAC;EAC1B,CAAC;CACH,GAAG;EAAC;EAAK;EAAM;CAAS,CAAC,GAEnB,KAAgB,EAAY,YAAY;EAC5C,IAAI,EAAK,SAAS,UAAU;EAC5B,IAAM,IAAW,EAAK;EACtB,MAAM,EAAU,YAAY;GAI1B,AAHA,MAAM,EAAI,cAAc,GAAU,EAAe,GACjD,GAAY,MAAY,EAAQ,QAAQ,MAAM,EAAE,QAAQ,CAAQ,CAAC,GACjE,EAAM,iBAAiB,GACvB,EAAQ,EAAE,MAAM,OAAO,CAAC;EAC1B,CAAC;CACH,GAAG;EAAC;EAAK;EAAM;EAAiB;CAAS,CAAC,GAEpC,KAA0B,GAC7B,MAA6B;EAe5B,IAbI,EAAK,WACP,GAAgB,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC,GACxC,GAAkB,MAChB,EAAQ,KAAK,MAAO,EAAE,QAAQ,EAAK,MAAM;GAAE,GAAG;GAAG,QAAQ,KAAK,IAAI;EAAE,IAAI,CAAE,CAC5E,GACA,EAAI,qBAAqB,EAAK,GAAG,CAAC,CAAC,YAAY,CAE/C,CAAC,IAKoB,EAAQ,MAAM,MAAM,EAAE,QAAQ,EAAK,QACtD,GACF,EAAQ;GAAE,MAAM;GAAU,UAAU,EAAK;EAAS,CAAC;OAC9C;GAGL,IAAM,IAAM,GAAe,EAAK,WAAW,OAAO,SAAS,IAAI;GAC/D,AAAI,MACF,EAAI,OAAO,iBAAiB,EAAK,YACjC,OAAO,SAAS,OAAO,EAAI,SAAS;EAExC;CACF,GACA,CAAC,GAAK,CAAO,CACf,GAEM,IAAiC,QAAkB;EAMvD,AALA,GAA+B,EAAI,GACnC,EAAe,CAAC,GAChB,GAAkB,MAChB,EAAQ,KAAK,MAAO,EAAE,UAAU,OAAO;GAAE,GAAG;GAAG,QAAQ,KAAK,IAAI;EAAE,IAAI,CAAE,CAC1E,GACA,EACG,yBAAyB,CAAC,CAC1B,YAAY,CAEb,CAAC,CAAC,CACD,cAAc,GAA+B,EAAK,CAAC;CACxD,GAAG,CAAC,CAAG,CAAC,GAEF,KAAc,EAClB,OAAO,MAAiB;EACtB,IAAI,EAAK,SAAS,UAAU;EAC5B,IAAM,IAAS,GAAe,CAAQ;EACtC,IAAI,CAAC,GAAQ;EACb,IAAM,IAAW,EAAK;EACtB,MAAM,EAAU,YAAY;GAC1B,IAAM,IAAW,GAAsB,CAAI,GACrC,IAAM,MAAM,EAAI,WAAW,GAAU;IACzC;IACA,YAAY,EAAO;IACnB,aAAa,EAAO;IACpB,UAAU,EAAS,SAAS,IAAI,IAAW,KAAA;GAC7C,CAAC;GAED,AADA,GAAY,MAAY,EAAQ,KAAK,MAAO,EAAE,QAAQ,IAAW,EAAI,SAAS,CAAE,CAAC,GACjF,EAAM,mBAAmB,EAAE,aAAa,EAAS,SAAS,EAAE,CAAC;EAC/D,CAAC;CACH,GACA;EAAC;EAAK;EAAU;EAAM;CAAS,CACjC,GAEM,KAAoB,EACxB,OAAO,GAAmB,MAAiB;EAEzC,IADI,EAAK,SAAS,YACd,EAAS,SAAS,UAAU,EAAS,SAAS,YAAY;EAC9D,IAAM,IAAW,EAAK;EAEtB,MAAM,EACJ,YAAY;GACV,IAAM,IAAW,GAAsB,CAAI,GACrC,IAAM,MAAM,EAAI,YAAY,GAAU,GAAW;IACrD;IACA,UAAU,EAAS,SAAS,IAAI,IAAW,KAAA;GAC7C,CAAC;GACD,GAAY,MAAY,EAAQ,KAAK,MAAO,EAAE,QAAQ,IAAW,EAAI,SAAS,CAAE,CAAC;EACnF,GACA,EAAE,SAAS,GAAK,CAClB;CACF,GACA;EAAC;EAAK;EAAU;EAAM;CAAS,CACjC,GAEM,KAAsB,EAC1B,OAAO,MAAsB;EAE3B,IADI,EAAK,SAAS,YACd,EAAS,SAAS,UAAU,EAAS,SAAS,YAAY;EAC9D,IAAM,IAAW,EAAK;EACtB,MAAM,EAAU,YAAY;GAC1B,IAAM,IAAM,MAAM,EAAI,cAAc,GAAU,CAAS;GACvD,GAAY,MAAY,EAAQ,KAAK,MAAO,EAAE,QAAQ,IAAW,EAAI,SAAS,CAAE,CAAC;EACnF,CAAC;CACH,GACA;EAAC;EAAK;EAAU;EAAM;CAAS,CACjC,GAMM,KAAuB,EAC3B,OAAO,GAAmB,MAAkB;EAC1C,IAAI,EAAK,SAAS,UAAU;EAC5B,IAAM,IAAS,GAAe,CAAQ;EACtC,IAAI,CAAC,GAAQ;EACb,IAAM,IAAW,EAAK;EACtB,MAAM,GAAY,YAAY;GAC5B,IAAM,IAAM,MAAM,EAAI,eAAe,GAAW;IAC9C;IACA,YAAY,EAAO;GACrB,CAAC;GAED,AADA,GAAY,MAAY,EAAQ,KAAK,MAAO,EAAE,QAAQ,IAAW,EAAI,SAAS,CAAE,CAAC,GACjF,EAAM,gBAAgB;EACxB,CAAC;CACH,GACA;EAAC;EAAK;EAAU;EAAM;CAAW,CACnC,GAOM,CAAC,GAAiB,MAAsB,EAAS,EAAK,GACtD,KAAiB,EAAY,YAAY;EAC7C,MAAM,GAAY,YAAY;GAO5B,AANA,MAAM,EAAI,SAAS,GACnB,EAAQ,EAAE,MAAM,OAAO,CAAC,GAGxB,EAAW,GACX,EAAa,EAAE,MAAM,YAAY,CAAC,GAClC,GAAmB,EAAI;EACzB,CAAC;CACH,GAAG;EAAC;EAAK;EAAY;EAAa;CAAY,CAAC;CAG/C,QAAgB;EACd,IAAI,CAAC,GAAiB;EACtB,IAAM,IAAI,OAAO,iBAAiB,GAAmB,EAAK,GAAG,GAAI;EACjE,aAAa,OAAO,aAAa,CAAC;CACpC,GAAG,CAAC,CAAe,CAAC;CAMpB,IAAM,CAAC,IAAkB,MAAuB,EAAS,EAAK,GACxD,KAAgB,EAAY,YAAY;EAC5C,MAAM,GAAW,YAAY;GAI3B,AAHA,MAAM,EAAI,QAAQ,GAClB,EAAQ,EAAE,MAAM,OAAO,CAAC,GACxB,EAAa,EAAE,MAAM,aAAa,CAAC,GACnC,GAAoB,EAAI;EAC1B,CAAC;CACH,GAAG;EAAC;EAAK;EAAY;CAAY,CAAC;CAElC,QAAgB;EACd,IAAI,CAAC,IAAkB;EACvB,IAAM,IAAI,OAAO,iBAAiB,GAAoB,EAAK,GAAG,GAAI;EAClE,aAAa,OAAO,aAAa,CAAC;CACpC,GAAG,CAAC,EAAgB,CAAC;CAGrB,IAAM,KACJ,EAAK,SAAS,WAAY,EAAQ,MAAM,MAAM,EAAE,QAAQ,EAAK,QAAQ,KAAK,OAAQ,MAC9E,KACJ,MAAe,MAAmB,QAAQ,OAAoB,IAAc,gBAOxE,KAAe,SAEjB,EAAQ,KAAK,OAAO;EAClB,QAAQ;EACR,OAAO,GAAc;GACnB,SAAS,EAAE;GACX,SAAS,EAAE;GACX,gBAAgB,EAAE;GAClB,eAAe,EAAE;GACjB,eAAe,EAAE;EACnB,CAAC;CACH,EAAE,GAEJ,CAAC,GAAS,EAAI,CAChB,GAGM,KAAc,EAAoD;EACtE,WAAW;EACX,UAAU,CAAC;CACb,CAAC;CACD,QAAgB;EACd,GAAY,UAAU;GAGpB,WAAW,GAAa,MAAM,MAAM,CAAC,EAAE,MAAM,YAAY,EAAE,OAAO,kBAAkB,IAAI;GACxF,UAAU,GAAa,SAAS,MAAO,EAAE,MAAM,UAAU,CAAC,EAAE,MAAM,OAAO,IAAI,CAAC,CAAE;EAClF;CACF,GAAG,CAAC,EAAY,CAAC;CACjB,IAAM,KAAqB,EAAQ,MAAM,MAAM,EAAE,kBAAkB,IAAI;CA2CvE,OA/BA,QAAgB;EACd,IAAI,CAAC,IAAoB;EACzB,IAAI,IAAuB;EAC3B,SAAS,IAAW;GACd,AACJ,MAAQ,4BAA4B;IAElC,AADA,IAAQ,MACR,IAAW,MAAM,IAAI,CAAC;GACxB,CAAC;EACH;EACA,IAAM,IAAW,IAAI,uBAAuB;GAC1C,IAAM,EAAE,cAAW,gBAAa,GAAY;GACxC,CAAC,KAAa,EAAS,OAAO,MAAO,EAAG,WAAW,KACvD,EAAS;EACX,CAAC;EAED,OADA,EAAS,QAAQ,SAAS,MAAM;GAAE,WAAW;GAAM,SAAS;EAAK,CAAC,SACrD;GAEX,AADA,EAAS,WAAW,GAChB,KAAS,QAAM,qBAAqB,CAAK;EAC/C;CACF,GAAG,CAAC,EAAkB,CAAC,GAKvB,QAAgB;EACd,AAAI,EAAK,SAAS,YAAY,MAAgB,QAC5C,GAAO;CAEX,GAAG;EAAC;EAAM;EAAc;CAAM,CAAC,GAG7B,kBAAC,OAAD;EAAK,OAAM;EAAc,KAAK;EAA9B,UAAA;GAKG,EAAK,SAAS,YA2BX,OA1BF,kBAAC,OAAD;IAAK,OAAM;IAAX,UAAA,CACG,CAAC,MAAe,IACb,GAAa,KAAK,EAAE,QAAQ,GAAG,eAAY;KACzC,IAAM,IAAW,EAAK,SAAS,YAAY,EAAK,aAAa,EAAE,KAEzD,IAAe,EAAE,SAAS,QAAQ,GAAG,MAAM,IAAK,IAAE,SAAkB,CAAC;KAC3E,OACE,kBAAC,IAAD;MAEE,OAAO,EAAM;MACb,OAAO,EAAM;MACb,OAAO;MACG;MACV,cAAc,CAAC,EAAM;MACrB,eAAe;OAEb,AADA,EAAM,iBAAiB,EAAE,cAAc,EAAa,CAAC,GACrD,EAAQ;QAAE,MAAM;QAAU,UAAU,EAAE;OAAI,CAAC;MAC7C;KACD,GAVM,EAAE,GAUR;IAEL,CAAC,IACD,MACH,EAAK,SAAS,kBACb,kBAAC,IAAD;KAAU,OAAO,EAAK;KAAO,OAAO,EAAK;IAAQ,CAAA,IAC/C,IACD;GACH,CAAA;GAGH,EAAK,SAAS,YACb,kBAAC,IAAD;IAAkB,SAAS;IAAa,UAAU;GAAS,CAAA,IACzD;GASH,EAAK,SAAS,YAAY,KACzB,kBAAC,IAAD;IAEE,QAAQ;IACI;IACZ,iBAAiB,MAAmB;IACxB;IACS;IACR;IACF;IACA;IACJ;IACP,UAAU;IACD;IACT,UAAU;IACV,UAAU;IACV,SAAS;IACT,SAAS;IACT,eAAe;IACf,iBAAiB;IACjB,kBAAkB;IAClB,UAAU;IACV,WAAW;GACZ,GArBM,GAAa,GAqBnB,IACC;GAGH,EAAK,SAAS,kBACb,kBAAC,IAAD;IACE,OAAO,EAAK;IACZ,OAAO,EAAK;IACA;IACA;IACS;IACR;IACF;IACJ;IACP,YAAY,EAAK;IACjB,uBAAuB,EAAK;IAC5B,kBAAkB,EAAK;IACvB,yBAAyB,EAAK;IAC9B,6BAA6B,EAAK;IACzB;IACT,UAAU;IACV,UAAU;IACV,UAAU;IACV,SAAS;GACV,CAAA,IACC;GAKH,CAAC,MAAe,EAAK,SAAS,aAAa,EAAK,SAAS,kBACxD,kBAAC,IAAD;IACE,UAAU,EAAK,SAAS;IACxB,gBAAiB,EAAK,SAAS,YAAY,GAAO,IAAI,GAAa;IACnE,cAAc,GAAQ,EAAE,MAAM,kBAAkB,CAAC;IACjD,UAAU;IACV,WAAW;IACX,aAAa,KAAa,IAAc;IACxC,WAAW,MAAU;IACrB,mBAAmB;KACjB,IAAM,IAAO,MAAU,UAAU,OAAO;KAExC,AADA,EAAS,CAAI,GACT,MACF,EAAM,wBAAwB,EAAE,eAAY,CAAC,GAC7C,GAAmB;IAEvB;IACa;IACb,oBAAoB,GAAgB,MAAM,CAAC,CAAC;IAC5C,gBACE,kBAAC,IAAD;KACY;KACV,UAAU;KACG;KACC;KACA;KACd,UAAU;KACV,WAAW;KACX,YAAY;IACb,CAAA;IAEH,gBACE,kBAAC,IAAD;KACE,UAAU;KACV,eAAe;KACf,aAAa,KAAmB,GAAa,YAAY;KACzD,mBAAmB,GAAa,YAAY;KAC5C,2BAA2B,GAAoB,MAAM,CAAC,CAAC;KACvD,qBAAqB,EAAS,SAAS;KACvC,uBAAuB,EAAS,WAAW;KAC3C,wBAAwB,GAAQ,EAAE,MAAM,kBAAkB,CAAC;KAC3D,SAAA;KACc;IACf,CAAA;GAEJ,CAAA,IACC;GAKH,MAAU,WAAW,KACpB,kBAAC,IAAD;IACE,MAAK;IACL,OAAM;IACN,UAAU;IACV,mBAAkB;IAClB,SAAS;IAET,UAAA,kBAAC,IAAD;KACE,OAAO;KACP,WAAW;KACX,OAAO;KACP,cAAc;KACd,QAAQ;KACR,cAAc,MAAS;MAErB,AADA,EAAW,GACX,GAAwB,CAAI;KAC9B;KACA,eAAe;IAChB,CAAA;GACW,CAAA,IACZ;GAEH,MAAU,YACT,kBAAC,IAAD;IACE,MAAK;IACL,OAAM;IACN,UAAU;IACV,SAAS;IAET,UAAA,kBAAC,IAAD;KACY;KACF;KACR,aAAa,KAAmB,GAAa,YAAY;KACzD,mBAAmB,GAAa,YAAY;KAC5C,gBAAgB,GAAe;KAC/B,eAAe,GAAe;KAC9B,YAAY;KACZ,SAAS;IACV,CAAA;GACW,CAAA,IACZ;GAEH,MAAU,cACT,kBAAC,IAAD;IACE,MAAK;IACL,OAAM;IACN,UAAU;IACV,SAAS;IAET,UAAA,kBAAC,IAAD,EAAgB,SAAS,EAAa,CAAA;GAC1B,CAAA,IACZ;GAKH,GAAI,SAAS,sBAAsB,kBAAC,IAAD,EAAgB,UAAU,EAAkB,CAAA,IAAI;GAKnF,IAAkB,kBAAC,IAAD,EAAe,UAAU,EAAkB,CAAA,IAAI;GAKjE,KAAmB,kBAAC,IAAD,EAAgB,UAAU,EAAkB,CAAA,IAAI;EACjE;;AAET;AAGA,SAAS,GAAe,EAAE,eAA2C;CACnE,IAAM,EAAE,KAAK,MAAW,GAAa;CACrC,OACE,kBAAC,OAAD;EACE,OAAO,EACL,2BACA,MAAa,gBACT,iCACA,MAAa,kBACX,mCACA,+BACR;EACA,MAAK;EACL,aAAU;EAVZ,UAAA;GAWC;GACuB,kBAAC,OAAD;IAAK,OAAM;IAAc,UAAA;GAAY,CAAA;GAC3D,kBAAC,OAAD;IAAK,OAAM;IAAa,UAAA;GAAM,CAAA;GAAC;EAC5B;;AAET;AAMA,SAAS,GAAc,EAAE,eAA2C;CAClE,OACE,kBAAC,OAAD;EACE,OAAO,EACL,2BACA,MAAa,gBACT,iCACA,MAAa,kBACX,mCACA,+BACR;EACA,MAAK;EACL,aAAU;EACX,UAAA;CAEI,CAAA;AAET;AAGA,SAAS,GAAe,EAAE,eAA2C;CACnE,OACE,kBAAC,OAAD;EACE,OAAO,EACL,2BACA,MAAa,gBACT,iCACA,MAAa,kBACX,mCACA,+BACR;EACA,MAAK;EACL,aAAU;EACX,UAAA;CAEI,CAAA;AAET;;;ACp1CA,SAAgB,GAAY,GAAmB,GAAiC;CAM9E,AALA,EAAK,MAAM,WAAW,SACtB,EAAK,MAAM,QAAQ,KACnB,EAAK,MAAM,SAAS,cACpB,EAAK,MAAM,gBAAgB,QAE3B,GAAc,GAAM,EAAO,SAAS,MAAM;CAC1C,IAAM,IAAY,GAAiB,GAE7B,IAAS,EAAK,aAAa,EAAE,MAAM,OAAO,CAAC,GAE3C,IAAQ,SAAS,cAAc,OAAO;CAE5C,AADA,EAAM,cAAc,IACpB,EAAO,YAAY,CAAK;CAExB,IAAM,IAAO,SAAS,cAAc,KAAK;CAqBzC,AApBA,EAAK,YAAY,sBACjB,EAAO,YAAY,CAAI,GAYvB,GAAkB;EAPhB,QAAQ,EAAO;EACf,QAAQ,EAAO;EACf,eAAA;CAKgB,CAAc,GAEhC,GACE,EAAO,cAAc,KACjB,OACA;EAAE,QAAQ,EAAO;EAAQ,QAAQ,EAAO;EAAQ,eAAA;CAAkC,CACxF,GACA,EAAM,eAAe;CAErB,IAAM,EAAE,OAAO,GAAQ,WAAW,GAAY,GAAG,MAAa;CAQ9D,OAPA,GACE,kBAAC,IAAD;EAAqB,UAAU,MAAQ,EAAY,GAAK,EAAE,SAAS,SAAS,CAAC;EAC3E,UAAA,kBAAC,IAAD,EAAK,GAAI,EAAW,CAAA;CACD,CAAA,GACrB,CACF,SAEa;EAKX,AAJA,EAAU,GACV,GAAkB,IAAI,GAEtB,GAAmB,IAAI,GACvB,GAAO,MAAM,CAAI;CACnB;AACF;;;ACHA,IAAI,KAAgC,MAChC,KAA4B,MAC5B,KAAqC,MAErC,KAAa;AAUjB,SAAgB,GAAK,GAAkC;CACrD,IAAI,CAAC,EAAO,UAAU,CAAC,EAAO,QAE5B,OADA,QAAQ,KAAK,gFAAgF,SAChF,CAAC;CAWhB,AAPI,EAAO,OAAO,QAAQ,CAAC,OACzB,KAAa,IACb,QAAQ,KACN,0JAEF,IAEF,GAAQ;CAER,IAAM,UAAc;EAElB,IADA,KAAgB,MACZ,CAAC,SAAS,MAAM;EACpB,IAAM,IAAO,SAAS,cAAc,KAAK;EAIzC,AAHA,EAAK,KAAK,iBACV,SAAS,KAAK,YAAY,CAAI,GAC9B,KAAQ,GACR,KAAW,GAAY,GAAM,CAAM;CACrC;CAGA,IAAI,SAAS,eAAe,aAAa,CAAC,SAAS,MAAM;EACvD,IAAM,UAAiB,EAAM;EAE7B,AADA,WAAsB,SAAS,oBAAoB,oBAAoB,CAAQ,GAC/E,SAAS,iBAAiB,oBAAoB,GAAU,EAAE,MAAM,GAAK,CAAC;CACxE,OACE,EAAM;CAGR,OAAO;AACT;AAEA,SAAgB,KAAgB;CAU9B,AATA,AAEE,QADA,GAAc,GACE,OAElB,AAEE,QADA,GAAS,GACE,OAET,IAAO,cAAY,GAAM,WAAW,YAAY,EAAK,GACzD,KAAQ;AACV;AAkBA,IAAI,OAAO,WAAa,KAAa;CAGnC,IAAM,IACH,SAAS,iBACT,SAAS,cAAc,qCAAmC,GACvD,IAAS,GAAS,QAAQ,QAC1B,IAAS,GAAS,QAAQ;CAChC,IAAI,KAAU,GAAQ;EACpB,IAAM,IAAW,GAAS,QAAQ,UAC5B,IAAQ,GAAS,QAAQ,OAEzB,IAAM,GAAS,QAAQ,KACvB,IAAe,GAAS,QAAQ,cAGhC,IAAY,GAAS,QAAQ,cAAc,SAC3C,UAAc,GAAK;GAAE;GAAQ;GAAQ;GAAU;GAAO;GAAK;GAAc;EAAU,CAAC;EAC1F,AAAI,SAAS,eAAe,YAC1B,SAAS,iBAAiB,oBAAoB,GAAO,EAAE,MAAM,GAAK,CAAC,IAEnE,EAAM;CAEV;AACF"}
|