@oyehello/chat 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/transport.ts","../src/client.ts","../src/element.ts","../src/index.ts"],"names":[],"mappings":";AAAO,IAAM,YAAA,GAAN,cAA2B,KAAA,CAAM;AAAA,EACtC,WAAA,CAAY,OAAA,EAA0B,MAAA,EAAyB,IAAA,EAAwB,IAAA,EAAgC;AACrH,IAAA,KAAA,CAAM,OAAO,CAAA;AADuB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAyB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAwB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAErF,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AAAA,EACd;AAAA,EAHsC,MAAA;AAAA,EAAyB,IAAA;AAAA,EAAwB,IAAA;AAIzF;;;ACFA,eAAe,OAAA,CAAQ,KAAe,YAAA,EAA8C;AAClF,EAAA,IAAI,OAA0E,EAAC;AAC/E,EAAA,IAAI;AAAE,IAAA,IAAA,GAAQ,MAAM,IAAI,IAAA,EAAK;AAAA,EAAyE,CAAA,CAAA,MAAQ;AAAA,EAAiB;AAC/H,EAAA,OAAO,IAAI,YAAA,CAAa,IAAA,CAAK,KAAA,IAAS,QAAQ,GAAA,CAAI,MAAM,CAAA,CAAA,EAAI,GAAA,CAAI,MAAA,EAAQ,IAAA,CAAK,IAAA,IAAQ,YAAA,EAAc,KAAK,IAAI,CAAA;AAC9G;AAEA,eAAsB,YAAY,IAAA,EAAmK;AACnM,EAAA,MAAM,IAAA,GAAgC,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ;AAC9D,EAAA,IAAI,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA;AAChC,EAAA,IAAI,IAAA,CAAK,eAAe,IAAA,CAAK,WAAA,CAAY,SAAS,CAAA,EAAG,IAAA,CAAK,cAAc,IAAA,CAAK,WAAA;AAC7E,EAAA,MAAM,MAAM,MAAM,IAAA,CAAK,UAAU,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,cAAA,CAAA,EAAkB;AAAA,IAChE,MAAA,EAAQ,MAAA;AAAA,IAAQ,WAAA,EAAa,MAAA;AAAA,IAC7B,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,eAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA,EAAG;AAAA,IACtF,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,GAC1B,CAAA;AACD,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,MAAM,QAAQ,GAAG,CAAA;AACpC,EAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AACzB;AAEA,eAAsB,YAAY,IAAA,EAAoK;AACpM,EAAA,MAAM,IAAA,GAAgC,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAK;AACxD,EAAA,IAAI,IAAA,CAAK,eAAe,IAAA,CAAK,WAAA,CAAY,SAAS,CAAA,EAAG,IAAA,CAAK,cAAc,IAAA,CAAK,WAAA;AAC7E,EAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,KAAK,OAAO,CAAA,eAAA,EAAkB,IAAA,CAAK,SAAS,CAAA,SAAA,CAAA,EAAa;AAAA,IAC3F,MAAA,EAAQ,MAAA;AAAA,IAAQ,WAAA,EAAa,MAAA;AAAA,IAC7B,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,eAAe,CAAA,OAAA,EAAU,IAAA,CAAK,YAAY,CAAA,CAAA,EAAG;AAAA,IAC5F,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,GAC1B,CAAA;AAGD,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,MAAM,OAAA,CAAQ,GAAA,EAAK,GAAA,CAAI,MAAA,KAAW,GAAA,GAAM,iBAAA,GAAoB,MAAS,CAAA;AAC1F;AAEA,eAAsB,WAAW,IAAA,EAA4G;AAC3I,EAAA,MAAM,IAAA,CAAK,UAAU,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,eAAA,EAAkB,IAAA,CAAK,SAAS,CAAA,IAAA,CAAA,EAAQ;AAAA,IAC1E,MAAA,EAAQ,MAAA;AAAA,IAAQ,WAAA,EAAa,MAAA;AAAA,IAC7B,SAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,YAAY,CAAA,CAAA;AAAG,GACzD,CAAA,CAAE,KAAA,CAAM,MAAM;AAAA,EAAC,CAAC,CAAA;AACnB;AAEA,eAAsB,eAAe,IAAA,EAA0J;AAC7L,EAAA,MAAM,IAAA,CAAK,UAAU,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,eAAA,EAAkB,IAAA,CAAK,SAAS,CAAA,aAAA,CAAA,EAAiB;AAAA,IACnF,MAAA,EAAQ,MAAA;AAAA,IAAQ,WAAA,EAAa,MAAA;AAAA,IAC7B,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,eAAe,CAAA,OAAA,EAAU,IAAA,CAAK,YAAY,CAAA,CAAA,EAAG;AAAA,IAC5F,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,EAAA,EAAI,IAAA,CAAK,EAAA,EAAI,MAAA,EAAQ,IAAA,CAAK,QAAQ;AAAA,GAC/E,CAAA,CAAE,KAAA,CAAM,MAAM;AAAA,EAAC,CAAC,CAAA;AACnB;AAEA,eAAsB,iBAAiB,IAAA,EAAoH;AACzJ,EAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,KAAK,OAAO,CAAA,eAAA,EAAkB,IAAA,CAAK,SAAS,CAAA,cAAA,CAAA,EAAkB;AAAA,IAChG,MAAA,EAAQ,MAAA;AAAA,IAAQ,WAAA,EAAa,MAAA;AAAA,IAC7B,SAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,YAAY,CAAA,CAAA;AAAG,GACzD,CAAA;AAGD,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,MAAM,OAAA,CAAQ,GAAA,EAAK,GAAA,CAAI,MAAA,KAAW,GAAA,GAAM,iBAAA,GAAoB,MAAS,CAAA;AACxF,EAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AACzB;AAEO,SAAS,SAAA,CAAU,OAAA,EAAiB,SAAA,EAAmB,MAAA,EAAwB;AACpF,EAAA,OAAO,GAAG,OAAO,CAAA,eAAA,EAAkB,SAAS,CAAA,eAAA,EAAkB,kBAAA,CAAmB,MAAM,CAAC,CAAA,CAAA;AAC1F;AAIA,eAAsB,kBAAkB,IAAA,EAAsK;AAC5M,EAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,KAAK,OAAO,CAAA,eAAA,EAAkB,IAAA,CAAK,SAAS,CAAA,YAAA,CAAA,EAAgB;AAAA,IAC9F,MAAA,EAAQ,MAAA;AAAA,IAAQ,WAAA,EAAa,MAAA;AAAA,IAC7B,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,eAAe,CAAA,OAAA,EAAU,IAAA,CAAK,YAAY,CAAA,CAAA,EAAG;AAAA,IAC5F,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,WAAA,EAAa,IAAA,CAAK,aAAa;AAAA,GACvD,CAAA;AAGD,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,MAAM,OAAA,CAAQ,GAAA,EAAK,GAAA,CAAI,MAAA,KAAW,GAAA,GAAM,iBAAA,GAAoB,MAAS,CAAA;AACxF,EAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AACzB;AAKA,eAAsB,iBAAiB,IAAA,EAAkI;AACvK,EAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,KAAK,OAAO,CAAA,eAAA,EAAkB,IAAA,CAAK,SAAS,CAAA,eAAA,CAAA,EAAmB;AAAA,IACjG,MAAA,EAAQ,MAAA;AAAA,IAAQ,WAAA,EAAa,MAAA;AAAA,IAC7B,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,eAAe,CAAA,OAAA,EAAU,IAAA,CAAK,YAAY,CAAA,CAAA,EAAG;AAAA,IAC5F,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,UAAA,EAAY,IAAA,CAAK,YAAY;AAAA,GACrD,CAAA;AAGD,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,MAAM,OAAA,CAAQ,GAAA,EAAK,GAAA,CAAI,MAAA,KAAW,GAAA,GAAM,iBAAA,GAAoB,MAAS,CAAA;AACxF,EAAA,OAAA,CAAS,MAAM,GAAA,CAAI,IAAA,EAAK,EAAuB,GAAA;AACjD;AAKA,eAAsB,iBAAA,CAAkB,SAAA,EAAmB,IAAA,EAAY,SAAA,EAAwC;AAC7G,EAAA,MAAM,GAAA,GAAM,MAAM,SAAA,CAAU,SAAA,EAAW,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,IAAA,EAAM,SAAS,EAAE,cAAA,EAAgB,IAAA,CAAK,IAAA,IAAQ,CAAA;AAC5G,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,IAAI,YAAA,CAAa,CAAA,mCAAA,EAAsC,GAAA,CAAI,MAAM,CAAA,CAAA,EAAI,GAAA,CAAI,MAAM,CAAA;AACpG;;;AC9DA,IAAI,GAAA,GAAM,CAAA;AACV,IAAM,MAAM,CAAC,CAAA,KAAc,CAAA,EAAG,CAAC,IAAI,IAAA,CAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,EAAA,CAAK,GAAA,EAAA,EAAO,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA;AAE3E,SAAS,iBAAiB,OAAA,EAAwC;AAIvE,EAAA,MAAM,YAAY,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA,CAAM,KAAK,UAAU,CAAA;AACnE,EAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,WAAA,IAAe,UAAA,CAAW,WAAA;AAE7C,EAAA,MAAM,cAAA,GAAiB,QAAQ,cAAA,IAAkB,CAAA;AAGjD,EAAA,MAAM,kBAAA,GAAqB,QAAQ,kBAAA,IAAsB,GAAA;AACzD,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAkC;AACxD,EAAA,IAAI,KAAA,GAAyB,MAAA;AAC7B,EAAA,MAAM,WAA0B,EAAC;AACjC,EAAA,IAAI,WAAA,GAA6B,IAAA;AACjC,EAAA,IAAI,OAAA,GAAsC,IAAA;AAC1C,EAAA,IAAI,EAAA,GAAyB,IAAA;AAC7B,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAY;AACpC,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAY;AACpC,EAAA,IAAI,YAAA,GAA6B,IAAA;AACjC,EAAA,IAAI,cAAA,GAAuD,IAAA;AAC3D,EAAA,IAAI,iBAAA,GAAoB,CAAA;AACxB,EAAA,IAAI,MAAA,GAAS,KAAA;AACb,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAA6B;AACtD,EAAA,MAAM,iBAAiB,MAAM;AAAE,IAAA,IAAI,cAAA,EAAgB;AAAE,MAAA,YAAA,CAAa,cAAc,CAAA;AAAG,MAAA,cAAA,GAAiB,IAAA;AAAA,IAAM;AAAA,EAAE,CAAA;AAE5G,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAuB;AAAE,IAAA,KAAA,MAAW,CAAA,IAAK,SAAA,EAAW,CAAA,CAAE,CAAC,CAAA;AAAA,EAAG,CAAA;AACxE,EAAA,MAAM,QAAA,GAAW,CAAC,CAAA,KAAuB;AAAE,IAAA,KAAA,GAAQ,CAAA;AAAG,IAAA,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,GAAG,CAAA;AAAA,EAAG,CAAA;AACzF,EAAA,MAAM,YAAA,GAAe,MAAM,IAAA,CAAK,EAAE,IAAA,EAAM,YAAY,QAAA,EAAU,QAAA,CAAS,KAAA,EAAM,EAAG,CAAA;AAEhF,EAAA,MAAM,OAAA,GAAU,CAAC,EAAA,KAAkB;AACjC,IAAA,IAAI,EAAA,CAAG,SAAS,OAAA,EAAS;AACvB,MAAA,IAAI,CAAA,GAAI,cAAc,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,WAAW,CAAA,GAAI,MAAA;AACnE,MAAA,IAAI,CAAC,CAAA,EAAG;AAAE,QAAA,CAAA,GAAI,EAAE,EAAA,EAAI,GAAA,CAAI,GAAG,CAAA,EAAG,MAAM,WAAA,EAAa,IAAA,EAAM,EAAA,EAAI,SAAA,EAAW,IAAA,EAAK;AAAG,QAAA,QAAA,CAAS,KAAK,CAAC,CAAA;AAAG,QAAA,WAAA,GAAc,CAAA,CAAE,EAAA;AAAA,MAAI;AACpH,MAAA,CAAA,CAAE,QAAQ,EAAA,CAAG,IAAA;AAAM,MAAA,YAAA,EAAa;AAAA,IAClC,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,SAAA,EAAW;AAChC,MAAA,IAAI,WAAA,CAAY,GAAA,CAAI,EAAA,CAAG,MAAM,CAAA,EAAG;AAI9B,QAAA,IAAI,WAAA,EAAa;AACf,UAAA,MAAM,MAAM,QAAA,CAAS,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,WAAW,CAAA;AAC1D,UAAA,IAAI,GAAA,KAAQ,EAAA,EAAI,QAAA,CAAS,MAAA,CAAO,KAAK,CAAC,CAAA;AACtC,UAAA,WAAA,GAAc,IAAA;AACd,UAAA,YAAA,EAAa;AAAA,QACf;AACA,QAAA;AAAA,MACF;AACA,MAAA,WAAA,CAAY,GAAA,CAAI,GAAG,MAAM,CAAA;AACzB,MAAA,MAAM,CAAA,GAAI,cAAc,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,WAAW,CAAA,GAAI,MAAA;AACrE,MAAA,IAAI,CAAA,EAAG;AAAE,QAAA,CAAA,CAAE,OAAO,EAAA,CAAG,IAAA;AAAM,QAAA,CAAA,CAAE,SAAA,GAAY,KAAA;AAAO,QAAA,CAAA,CAAE,SAAS,EAAA,CAAG,MAAA;AAAA,MAAQ,CAAA,MAAO;AAAE,QAAA,QAAA,CAAS,KAAK,EAAE,EAAA,EAAI,GAAA,CAAI,GAAG,GAAG,IAAA,EAAM,WAAA,EAAa,IAAA,EAAM,EAAA,CAAG,MAAM,SAAA,EAAW,KAAA,EAAO,MAAA,EAAQ,EAAA,CAAG,QAAQ,CAAA;AAAA,MAAG;AACvL,MAAA,WAAA,GAAc,IAAA;AAAM,MAAA,YAAA,EAAa;AAAA,IACnC,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,WAAA,EAAa;AAIlC,MAAA,MAAM,CAAA,GAAI,SAAS,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,MAAA,KAAW,GAAG,MAAM,CAAA;AACrD,MAAA,IAAI,CAAA,EAAG;AAAE,QAAA,CAAA,CAAE,UAAU,EAAA,CAAG,OAAA;AAAS,QAAA,YAAA,EAAa;AAAA,MAAG;AAAA,IACnD,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,OAAA,EAAS;AAC9B,MAAA,IAAA,CAAK,EAAE,MAAM,OAAA,EAAS,KAAA,EAAO,IAAI,KAAA,CAAM,EAAA,CAAG,OAAO,CAAA,EAAG,CAAA;AAAA,IACtD,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,WAAA,EAAa;AAClC,MAAA,IAAI,WAAA,CAAY,GAAA,CAAI,EAAA,CAAG,MAAM,CAAA,EAAG;AAChC,MAAA,WAAA,CAAY,GAAA,CAAI,GAAG,MAAM,CAAA;AACzB,MAAA,MAAM,OAAA,GAAU,YAAA,CAAa,GAAA,CAAI,EAAA,CAAG,IAAI,CAAA;AACxC,MAAA,KAAA,CAAM,YAAY;AAChB,QAAA,IAAI,CAAC,OAAA,EAAS;AACd,QAAA,MAAM,IAAA,GAAO,EAAE,OAAA,EAAS,OAAA,CAAQ,SAAS,SAAA,EAAW,OAAA,CAAQ,SAAA,EAAW,YAAA,EAAc,OAAA,CAAQ,YAAA,EAAc,MAAA,EAAQ,EAAA,CAAG,QAAQ,SAAA,EAAU;AACxI,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,MAAM,cAAA,CAAe,EAAE,GAAG,IAAA,EAAM,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,CAAA,0BAAA,EAA6B,EAAA,CAAG,IAAI,CAAA,CAAA,EAAI,CAAA;AAC3F,UAAA;AAAA,QACF;AACA,QAAA,IAAI;AACF,UAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,EAAA,CAAG,IAAI,CAAA;AACjC,UAAA,MAAM,eAAe,EAAE,GAAG,MAAM,EAAA,EAAI,IAAA,EAAM,QAAQ,OAAO,GAAA,KAAQ,WAAW,GAAA,GAAM,IAAA,CAAK,UAAU,GAAA,IAAO,EAAE,IAAI,IAAA,EAAM,GAAG,CAAA;AAAA,QACzH,SAAS,GAAA,EAAK;AACZ,UAAA,MAAM,cAAA,CAAe,EAAE,GAAG,IAAA,EAAM,IAAI,KAAA,EAAO,MAAA,EAAS,GAAA,CAAc,OAAA,EAAS,CAAA;AAAA,QAC7E;AAAA,MACF,CAAA,GAAG;AAAA,IACL,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,YAAA,EAAc;AAUnC,MAAA,MAAM,QAAQ,EAAA,CAAG,KAAA;AACjB,MAAA,MAAM,kBAAkB,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,IAAA,CAAK,CAAC,MAAM,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,eAAe,CAAA,CAAE,UAAU,CAAC,CAAC,CAAA;AACzH,MAAA,IAAI,eAAA,EAAiB;AACrB,MAAA,MAAM,MAAA,GAAS,CAAC,GAAG,QAAQ,EAAE,OAAA,EAAQ,CAAE,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,MAAA,IAAU,CAAC,EAAE,WAAW,CAAA;AACtF,MAAA,IAAI,MAAA,SAAe,WAAA,GAAc,KAAA;AAAA,WAC5B,QAAA,CAAS,IAAA,CAAK,EAAE,EAAA,EAAI,IAAI,GAAG,CAAA,EAAG,IAAA,EAAM,MAAA,EAAQ,MAAM,EAAA,EAAI,SAAA,EAAW,KAAA,EAAO,WAAA,EAAa,OAAO,CAAA;AACjG,MAAA,YAAA,EAAa;AAAA,IACf,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,eAAA,EAAiB;AAKtC,MAAA,IAAI,WAAA,CAAY,GAAA,CAAI,EAAA,CAAG,MAAM,CAAA,EAAG;AAChC,MAAA,WAAA,CAAY,GAAA,CAAI,GAAG,MAAM,CAAA;AACzB,MAAA,QAAA,CAAS,IAAA,CAAK,EAAE,EAAA,EAAI,GAAA,CAAI,GAAG,CAAA,EAAG,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,EAAA,CAAG,IAAA,EAAM,SAAA,EAAW,OAAO,CAAA;AAC9E,MAAA,YAAA,EAAa;AAAA,IACf,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,iBAAA,EAAmB,CAG1C,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,OAAA,EAAS;AAG9B,MAAA,IAAI,EAAA,CAAG,UAAU,IAAA,IAAQ,EAAA,CAAG,UAAU,gBAAA,IAAoB,EAAA,CAAG,UAAU,OAAA,EAAS;AAC9E,QAAA,YAAA,GAAe,EAAA,CAAG,KAAA;AAClB,QAAA,IAAA,CAAK,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,cAAc,CAAA;AAAA,MAC/C;AAAA,IACF,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,cAAA,EAAgB;AAErC,MAAA,IAAA,CAAK,EAAE,MAAM,aAAA,EAAe,MAAA,EAAQ,CAAC,CAAC,EAAA,CAAG,QAAQ,CAAA;AAAA,IACnD;AAAA,EAEF,CAAA;AAKA,EAAA,MAAM,aAAa,YAAY;AAC7B,IAAA,IAAI,CAAC,WAAW,MAAA,EAAQ;AACxB,IAAA,EAAA,EAAI,KAAA,EAAM;AACV,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,gBAAA,CAAiB,EAAE,OAAA,EAAS,OAAA,CAAQ,OAAA,EAAS,SAAA,EAAW,QAAQ,SAAA,EAAW,YAAA,EAAc,OAAA,CAAQ,YAAA,EAAc,WAAW,CAAA;AACnJ,IAAA,IAAI,MAAA,EAAQ;AACZ,IAAA,EAAA,GAAK,IAAI,GAAG,SAAA,CAAU,OAAA,CAAQ,SAAS,OAAA,CAAQ,SAAA,EAAW,MAAM,CAAC,CAAA;AACjE,IAAA,EAAA,CAAG,SAAS,MAAM;AAAE,MAAA,iBAAA,GAAoB,CAAA;AAAA,IAAG,CAAA;AAC3C,IAAA,EAAA,CAAG,SAAA,GAAY,CAAC,CAAA,KAAoB;AAAE,MAAA,IAAI;AAAE,QAAA,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,IAAI,CAAc,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAyB;AAAA,IAAE,CAAA;AACzH,IAAA,EAAA,CAAG,UAAU,MAAM;AAAE,MAAA,EAAA,EAAI,KAAA,EAAM;AAAG,MAAA,EAAA,GAAK,IAAA;AAAM,MAAA,iBAAA,EAAkB;AAAA,IAAG,CAAA;AAAA,EACpE,CAAA;AAEA,EAAA,MAAM,oBAAoB,MAAM;AAC9B,IAAA,IAAI,MAAA,EAAQ;AACZ,IAAA,cAAA,EAAe;AACf,IAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,GAAA,EAAQ,GAAA,GAAM,KAAK,iBAAiB,CAAA;AAC3D,IAAA,iBAAA,IAAqB,CAAA;AACrB,IAAA,cAAA,GAAiB,WAAW,MAAM;AAChC,MAAA,UAAA,EAAW,CAAE,KAAA,CAAM,CAAC,GAAA,KAAQ;AAC1B,QAAA,IAAI,GAAA,YAAe,YAAA,IAAiB,GAAA,CAAqB,IAAA,KAAS,iBAAA,EAAmB;AACnF,UAAA,IAAA,EAAK,CAAE,KAAA,CAAM,CAAC,CAAA,KAAM;AAAE,YAAA,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,GAAY,CAAA;AAAG,YAAA,iBAAA,EAAkB;AAAA,UAAG,CAAC,CAAA;AAAA,QAC1F,CAAA,MAAO;AACL,UAAA,iBAAA,EAAkB;AAAA,QACpB;AAAA,MACF,CAAC,CAAA;AAAA,IACH,GAAG,KAAK,CAAA;AAAA,EACV,CAAA;AAEA,EAAA,MAAM,OAAO,YAAY;AACvB,IAAA,OAAA,GAAU,MAAM,YAAY,EAAE,OAAA,EAAS,QAAQ,OAAA,EAAS,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAQ,OAAA,EAAS,OAAA,CAAQ,SAAS,IAAA,EAAM,OAAA,CAAQ,IAAA,EAAM,WAAA,EAAa,KAAA,CAAM,IAAA,CAAK,aAAa,IAAA,EAAM,CAAA,EAAG,SAAA,EAAW,CAAA;AACvL,IAAA,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,OAAA,CAAQ,OAAO,CAAA;AAC5C,IAAA,MAAM,UAAA,EAAW;AAAA,EACnB,CAAA;AAKA,EAAA,MAAM,WAAA,GAAc,OAAO,KAAA,KAAuD;AAChF,IAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,OAAO,IAAA,KAA4C;AAC9E,MAAA,MAAM,EAAE,YAAY,SAAA,EAAU,GAAI,MAAM,iBAAA,CAAkB,EAAE,SAAS,OAAA,CAAQ,OAAA,EAAS,WAAW,OAAA,CAAS,SAAA,EAAW,cAAc,OAAA,CAAS,YAAA,EAAc,aAAa,IAAA,CAAK,IAAA,EAAM,WAAW,CAAA;AAC7L,MAAA,MAAM,iBAAA,CAAkB,SAAA,EAAW,IAAA,EAAM,SAAS,CAAA;AAClD,MAAA,OAAO,EAAE,UAAA,EAAY,WAAA,EAAa,KAAK,IAAA,EAAM,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,IAC/D,CAAC,CAAC,CAAA;AAAA,EACJ,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,MAAM,QAAA,CAAS,KAAA,EAAM;AAAA,IAClC,UAAU,MAAM,KAAA;AAAA,IAChB,GAAG,QAAA,EAAU;AAAE,MAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AAAG,MAAA,OAAO,MAAM,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,IAAG,CAAA;AAAA,IACjF,cAAc,QAAA,EAAU;AAAE,MAAA,KAAA,MAAW,CAAC,IAAA,EAAM,EAAE,CAAA,IAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG,YAAA,CAAa,GAAA,CAAI,IAAA,EAAM,EAAE,CAAA;AAAA,IAAG,CAAA;AAAA,IACzG,MAAM,iBAAiB,UAAA,EAAY;AACjC,MAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,MAAM,sCAAsC,CAAA;AACpE,MAAA,OAAO,gBAAA,CAAiB,EAAE,OAAA,EAAS,OAAA,CAAQ,OAAA,EAAS,SAAA,EAAW,OAAA,CAAQ,SAAA,EAAW,YAAA,EAAc,OAAA,CAAQ,YAAA,EAAc,UAAA,EAAY,WAAW,CAAA;AAAA,IAC/I,CAAA;AAAA,IACA,MAAM,KAAA,GAAQ;AACZ,MAAA,IAAI,UAAU,MAAA,EAAQ;AACtB,MAAA,QAAA,CAAS,SAAS,CAAA;AAClB,MAAA,IAAI;AAAE,QAAA,MAAM,IAAA,EAAK;AAAG,QAAA,QAAA,CAAS,OAAO,CAAA;AAAA,MAAG,SAChC,GAAA,EAAK;AAAE,QAAA,QAAA,CAAS,OAAO,CAAA;AAAG,QAAA,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,KAAc,CAAA;AAAA,MAAG;AAAA,IACjF,CAAA;AAAA,IACA,MAAM,WAAA,CAAY,IAAA,EAAM,KAAA,EAAO;AAC7B,MAAA,IAAI,CAAC,OAAA,EAAS;AAAE,QAAA,IAAA,CAAK,EAAE,MAAM,OAAA,EAAS,KAAA,EAAO,IAAI,KAAA,CAAM,iCAAiC,GAAG,CAAA;AAAG,QAAA;AAAA,MAAQ;AACtG,MAAA,MAAM,QAAA,GAAW,SAAS,EAAC;AAC3B,MAAA,IAAI,QAAA,CAAS,SAAS,cAAA,EAAgB;AACpC,QAAA,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,IAAI,MAAM,CAAA,0BAAA,EAA6B,cAAc,CAAA,YAAA,CAAc,CAAA,EAAG,CAAA;AACnG,QAAA;AAAA,MACF;AACA,MAAA,MAAM,YAAY,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,kBAAkB,CAAA;AAClE,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,SAAA,CAAU,IAAI,CAAA,SAAA,EAAY,kBAAkB,CAAA,MAAA,CAAQ,GAAG,CAAA;AACvH,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,cAA0C,EAAC;AAC/C,MAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,QAAA,IAAI;AACF,UAAA,WAAA,GAAc,MAAM,YAAY,QAAQ,CAAA;AAAA,QAC1C,SAAS,GAAA,EAAK;AACZ,UAAA,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,KAAc,CAAA;AAC3C,UAAA;AAAA,QACF;AAAA,MACF;AACA,MAAA,QAAA,CAAS,KAAK,EAAE,EAAA,EAAI,GAAA,CAAI,GAAG,GAAG,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,SAAA,EAAW,OAAO,WAAA,EAAa,WAAA,CAAY,SAAS,CAAA,GAAI,WAAA,GAAc,QAAW,CAAA;AAAG,MAAA,YAAA,EAAa;AACnJ,MAAA,IAAI;AACF,QAAA,MAAM,WAAA,CAAY,EAAE,OAAA,EAAS,OAAA,CAAQ,SAAS,SAAA,EAAW,OAAA,CAAQ,SAAA,EAAW,YAAA,EAAc,OAAA,CAAQ,YAAA,EAAc,IAAA,EAAM,WAAA,EAAa,WAAW,CAAA;AAAA,MAChJ,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,GAAA,YAAe,YAAA,IAAgB,GAAA,CAAI,IAAA,KAAS,iBAAA,EAAmB;AACjE,UAAA,IAAI;AACF,YAAA,MAAM,IAAA,EAAK;AAGX,YAAA,MAAM,mBAAmB,QAAA,CAAS,MAAA,GAAS,MAAM,WAAA,CAAY,QAAQ,IAAI,EAAC;AAC1E,YAAA,MAAM,WAAA,CAAY,EAAE,OAAA,EAAS,OAAA,CAAQ,SAAS,SAAA,EAAW,OAAA,CAAS,SAAA,EAAW,YAAA,EAAc,QAAS,YAAA,EAAc,IAAA,EAAM,WAAA,EAAa,gBAAA,EAAkB,WAAW,CAAA;AAAA,UACpK,SAAS,QAAA,EAAU;AACjB,YAAA,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,UAAmB,CAAA;AAAA,UAClD;AAAA,QACF,CAAA,MAAO;AAAE,UAAA,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,KAAc,CAAA;AAAA,QAAG;AAAA,MACzD;AAAA,IACF,CAAA;AAAA,IACA,MAAM,GAAA,GAAM;AACV,MAAA,MAAA,GAAS,IAAA;AAAM,MAAA,cAAA,EAAe;AAC9B,MAAA,IAAI,OAAA,EAAS,MAAM,UAAA,CAAW,EAAE,SAAS,OAAA,CAAQ,OAAA,EAAS,SAAA,EAAW,OAAA,CAAQ,SAAA,EAAW,YAAA,EAAc,OAAA,CAAQ,YAAA,EAAc,WAAW,CAAA;AACvI,MAAA,EAAA,EAAI,KAAA,EAAM;AAAG,MAAA,EAAA,GAAK,IAAA;AAAM,MAAA,QAAA,CAAS,OAAO,CAAA;AAAA,IAC1C;AAAA,GACF;AACF;;;AC3QA,IAAM,mBAAA,GAA2D;AAAA,EAC/D,EAAA,EAAI,IAAA;AAAA,EACJ,cAAA,EAAgB,kCAAA;AAAA,EAChB,KAAA,EAAO;AACT,CAAA;AAEA,IAAM,iBAAA,GAAoB,6CAAA;AAC1B,IAAM,iBAAA,GAAoB,2BAAA;AAEnB,IAAM,mBAAA,GAAN,cAAkC,WAAA,CAAY;AAAA,EACnD,OAAO,kBAAA,GAAqB,CAAC,SAAA,EAAW,UAAA,EAAY,YAAY,OAAO,CAAA;AAAA,EAC/D,MAAA,GAA4B,IAAA;AAAA,EAC5B,GAAA,GAA2B,IAAA;AAAA,EAC3B,WAA0B,EAAC;AAAA,EAC3B,KAAA,GAAyB,MAAA;AAAA,EACzB,SAAA,GAA2B,IAAA;AAAA,EAC3B,YAAA,GAA6B,IAAA;AAAA;AAAA;AAAA,EAG7B,WAAA,GAAc,KAAA;AAAA;AAAA;AAAA;AAAA,EAId,SAAA,GAA2B,IAAA;AAAA;AAAA;AAAA,EAG3B,eAAgD,EAAC;AAAA;AAAA,EAEjD,eAAuB,EAAC;AAAA;AAAA;AAAA,EAGxB,iBAAA,uBAAwB,GAAA,EAAoB;AAAA;AAAA;AAAA;AAAA,EAI5C,gBAAA,uBAAuB,GAAA,EAAoB;AAAA,EAEnD,iBAAA,GAAoB;AAClB,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY,IAAA,CAAK,aAAa,EAAE,IAAA,EAAM,QAAQ,CAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,YAAA,CAAa,SAAS,CAAA;AAC1C,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,UAAU,CAAA;AAC5C,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,UAAU,CAAA;AAC5C,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,IAAW,CAAC,OAAA,EAAS;AAAE,MAAA,IAAA,CAAK,YAAY,4DAA4D,CAAA;AAAG,MAAA;AAAA,IAAQ;AAC/H,IAAA,IAAA,CAAK,SAAS,gBAAA,CAAiB,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA;AAC3D,IAAA,IAAI,OAAO,IAAA,CAAK,IAAA,CAAK,YAAY,CAAA,CAAE,SAAS,CAAA,EAAG;AAAE,MAAA,IAAA,CAAK,MAAA,CAAO,aAAA,CAAc,IAAA,CAAK,YAAY,CAAA;AAAG,MAAA,IAAA,CAAK,eAAe,EAAC;AAAA,IAAG;AACvH,IAAA,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,CAAC,CAAA,KAAM;AAC/B,MAAA,IAAI,CAAA,CAAE,IAAA,KAAS,UAAA,EAAY,IAAA,CAAK,WAAW,CAAA,CAAE,QAAA;AAAA,WAAA,IACpC,CAAA,CAAE,SAAS,OAAA,EAAS;AAAE,QAAA,IAAA,CAAK,QAAQ,CAAA,CAAE,KAAA;AAAO,QAAA,IAAI,EAAE,KAAA,KAAU,OAAA,IAAW,EAAE,KAAA,KAAU,SAAA,OAAgB,SAAA,GAAY,IAAA;AAAA,MAAM,WACrH,CAAA,CAAE,IAAA,KAAS,SAAS,IAAA,CAAK,SAAA,GAAY,EAAE,KAAA,CAAM,IAAA;AAAA,WAAA,IAC7C,CAAA,CAAE,IAAA,KAAS,SAAA,EAAW,IAAA,CAAK,eAAe,CAAA,CAAE,KAAA;AAAA,WAAA,IAC5C,CAAA,CAAE,IAAA,KAAS,aAAA,EAAe,IAAA,CAAK,cAAc,CAAA,CAAE,MAAA;AAAA,WAAA,IAC/C,EAAE,IAAA,KAAS,OAAA,EAAS,IAAA,CAAK,SAAA,GAAY,EAAE,KAAA,CAAM,OAAA;AACtD,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,EAAO;AACZ,IAAA,KAAK,IAAA,CAAK,OAAO,KAAA,EAAM;AAAA,EACzB;AAAA,EACA,oBAAA,GAAuB;AACrB,IAAA,IAAA,CAAK,GAAA,IAAM;AAAG,IAAA,KAAK,IAAA,CAAK,QAAQ,GAAA,EAAI;AACpC,IAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,iBAAA,CAAkB,MAAA,EAAO,EAAG;AAAE,MAAA,IAAI,OAAO,GAAA,CAAI,eAAA,KAAoB,UAAA,EAAY,GAAA,CAAI,gBAAgB,GAAG,CAAA;AAAA,IAAG;AAC9H,IAAA,IAAA,CAAK,kBAAkB,KAAA,EAAM;AAAA,EAC/B;AAAA,EAEA,cAAc,QAAA,EAA2C;AACvD,IAAA,IAAI,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,cAAc,QAAQ,CAAA;AAAA,SAC9C,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,YAAA,EAAc,QAAQ,CAAA;AAAA,EAChD;AAAA,EAEQ,IAAA,CAAK,MAAc,KAAA,EAAe;AACxC,IAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAK,EAAG;AAClB,IAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,MAAA,IAAI,CAAA,CAAE,IAAA,CAAK,UAAA,CAAW,QAAQ,KAAK,OAAO,GAAA,CAAI,eAAA,KAAoB,UAAA,IAAc,CAAC,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,EAAG;AACnH,QAAA,IAAA,CAAK,kBAAkB,GAAA,CAAI,CAAA,CAAE,MAAM,GAAA,CAAI,eAAA,CAAgB,CAAC,CAAC,CAAA;AAAA,MAC3D;AAAA,IACF;AACA,IAAA,KAAK,IAAA,CAAK,QAAQ,WAAA,CAAY,IAAA,EAAM,MAAM,MAAA,GAAS,CAAA,GAAI,QAAQ,MAAS,CAAA;AAAA,EAC1E;AAAA,EACQ,YAAY,GAAA,EAAa;AAC/B,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY,IAAA,CAAK,aAAa,EAAE,IAAA,EAAM,QAAQ,CAAA;AACxD,IAAA,IAAA,CAAK,UAAA,CAAY,SAAA,GAAY,CAAA,4DAAA,EAA+D,UAAA,CAAW,GAAG,CAAC,CAAA,MAAA,CAAA;AAAA,EAC7G;AAAA,EACQ,iBAAiB,CAAA,EAAqC;AAC5D,IAAA,IAAI,CAAA,CAAE,WAAA,CAAY,UAAA,CAAW,QAAQ,CAAA,EAAG;AAKtC,MAAA,MAAM,MAAA,GAAA,CAAU,CAAA,CAAE,IAAA,GAAO,IAAA,CAAK,kBAAkB,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,GAAI,MAAA,KAAc,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,EAAE,UAAU,CAAA;AAClH,MAAA,MAAM,OAAA,GAAU,MAAA,GAAS,CAAA,MAAA,EAAS,MAAM,CAAA,CAAA,CAAA,GAAM,EAAA;AAC9C,MAAA,OAAO,CAAA,oCAAA,EAAuC,UAAA,CAAW,CAAA,CAAE,UAAU,CAAC,CAAA,CAAA,EAAI,OAAO,CAAA,MAAA,EAAS,UAAA,CAAW,CAAA,CAAE,IAAA,IAAQ,OAAO,CAAC,CAAA,GAAA,CAAA;AAAA,IACzH;AACA,IAAA,OAAO,mCAA4B,UAAA,CAAW,CAAA,CAAE,IAAA,IAAQ,CAAA,CAAE,WAAW,CAAC,CAAA,MAAA,CAAA;AAAA,EACxE;AAAA,EACQ,aAAa,CAAA,EAA2D;AAC9E,IAAA,OAAO,CAAA,6BAAA,EAAgC,WAAW,CAAA,CAAE,OAAO,CAAC,CAAA,EAAA,EAAK,UAAA,CAAW,CAAA,CAAE,KAAK,CAAC,CAAA,MAAA,CAAA;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAAA,GAA0B;AAChC,IAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAClB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,UAAA,CAAY,gBAAA,CAAmC,4BAA4B,CAAA;AAC7F,IAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,GAAA,KAAQ;AACpB,MAAA,IAAI,GAAA,CAAI,YAAA,CAAa,KAAK,CAAA,EAAG;AAC7B,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,YAAA,CAAa,aAAa,CAAA;AAC1C,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,KAAK,KAAK,MAAA,CAAQ,gBAAA,CAAiB,GAAG,CAAA,CACnC,IAAA,CAAK,CAAC,GAAA,KAAQ;AAAE,QAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,GAAA,EAAK,GAAG,CAAA;AAAG,QAAA,GAAA,CAAI,GAAA,GAAM,GAAA;AAAA,MAAK,CAAC,CAAA,CACrE,KAAA,CAAM,MAAM;AAAA,MAA4E,CAAC,CAAA;AAAA,IAC9F,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,MAAA,GAAS;AACf,IAAA,MAAM,QAAQ,IAAA,CAAK,YAAA,CAAa,OAAO,CAAA,IAAK,KAAK,SAAA,IAAa,MAAA;AAC9D,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM;AACvC,MAAA,MAAM,IAAA,GAAA,CAAQ,CAAA,CAAE,WAAA,IAAe,IAAI,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,gBAAA,CAAiB,CAAC,CAAC,CAAA,CAAE,KAAK,EAAE,CAAA;AAC/E,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,IAAA,KAAS,OAAA,GAAU,wCAAA,GAA2C,EAAA;AAC9E,MAAA,MAAM,MAAA,GAAS,iBAAiB,CAAA,CAAE,IAAI,KAAK,KAAK,CAAA,EAAG,IAAI,CAAA,EAAG,CAAA,CAAE,OAAO,UAAA,CAAW,CAAA,CAAE,IAAI,CAAA,GAAI,EAAE,GAAG,CAAA,CAAE,SAAA,GAAY,WAAM,EAAE,CAAA,MAAA,CAAA;AACnH,MAAA,MAAM,OAAA,GAAU,EAAE,OAAA,IAAW,CAAA,CAAE,QAAQ,MAAA,GAAS,CAAA,GAAI,wBAAwB,CAAA,CAAE,OAAA,CAAQ,IAAI,CAAC,CAAA,KAAM,KAAK,YAAA,CAAa,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAA,MAAA,CAAA,GAAW,EAAA;AAC1I,MAAA,OAAO,MAAA,GAAS,OAAA;AAAA,IAClB,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA;AACV,IAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,IAAA,CAAK,YAAY,CAAA;AACxD,IAAA,MAAM,SAAS,UAAA,GAAa,CAAA,oBAAA,EAAuB,UAAA,CAAW,UAAU,CAAC,CAAA,MAAA,CAAA,GAAW,EAAA;AACpF,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,KAAU,OAAA,IAAW,IAAA,CAAK,SAAA,GAC7C,CAAA,sCAAA,EAAyC,UAAA,CAAW,IAAA,CAAK,SAAS,CAAC,CAAA,MAAA,CAAA,GACnE,EAAA;AACJ,IAAA,MAAM,aAAa,IAAA,CAAK,WAAA,KAAgB,KAAK,YAAA,KAAiB,OAAA,IAAW,KAAK,YAAA,KAAiB,gBAAA,CAAA;AAC/F,IAAA,MAAM,kBAAkB,UAAA,GAAa,CAAA,gCAAA,EAAmC,UAAA,CAAW,iBAAiB,CAAC,CAAA,MAAA,CAAA,GAAW,EAAA;AAChH,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,KAAU,OAAA,GAAU,UAAA,GAAa,EAAA;AAGvD,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,UAAA,CAAY,aAAA,CAAgC,6BAA6B,CAAA;AAChG,IAAA,MAAM,SAAA,GAAY,WAAW,KAAA,IAAS,EAAA;AACtC,IAAA,MAAM,kBAAA,GAAqB,WAAW,cAAA,IAAkB,IAAA;AACxD,IAAA,MAAM,gBAAA,GAAmB,WAAW,YAAA,IAAgB,IAAA;AACpD,IAAA,MAAM,WAAW,CAAC,CAAC,SAAA,IAAa,IAAA,CAAK,WAAY,aAAA,KAAkB,SAAA;AACnE,IAAA,IAAA,CAAK,WAAY,SAAA,GAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAA,EA0BP,UAAA,CAAW,KAAK,CAAC,CAAA;AAAA,QAAA,EACjC,MAAM,GAAG,SAAS;AAAA,0BAAA,EACA,OAAO,GAAG,eAAe,CAAA;AAAA;AAAA,yEAAA,EAEiB,QAAQ,CAAA;AAAA,qCAAA,EACvC,iBAAiB,cAAc,QAAQ,CAAA;AAAA,gCAAA,EAC5C,QAAQ,CAAA;AAAA;AAAA,YAAA,CAAA;AAGtC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,UAAA,CAAY,aAAA,CAAc,MAAM,CAAA;AAClD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,UAAA,CAAY,aAAA,CAAgC,6BAA6B,CAAA;AAC5F,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,UAAA,CAAY,aAAA,CAAgC,oBAAoB,CAAA;AACvF,IAAA,SAAA,CAAU,gBAAA,CAAiB,UAAU,MAAM;AAAE,MAAA,IAAA,CAAK,YAAA,GAAe,UAAU,KAAA,GAAQ,KAAA,CAAM,KAAK,SAAA,CAAU,KAAK,IAAI,EAAC;AAAA,IAAG,CAAC,CAAA;AACtH,IAAA,IAAA,CAAK,gBAAA,CAAiB,QAAA,EAAU,CAAC,CAAA,KAAM;AACrC,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,MAAM,QAAQ,IAAA,CAAK,YAAA;AACnB,MAAA,IAAA,CAAK,eAAe,EAAC;AACrB,MAAA,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,KAAK,CAAA;AAC5B,MAAA,KAAA,CAAM,KAAA,GAAQ,EAAA;AAAA,IAChB,CAAC,CAAA;AACD,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,KAAA,CAAM,KAAA,GAAQ,SAAA;AACd,MAAA,IAAI,uBAAuB,IAAA,IAAQ,gBAAA,KAAqB,MAAM,KAAA,CAAM,iBAAA,CAAkB,oBAAoB,gBAAgB,CAAA;AAAA,IAC5H;AACA,IAAA,IAAI,QAAA,QAAgB,KAAA,EAAM;AAC1B,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,UAAA,CAAY,aAAA,CAAc,OAAO,CAAA;AACnD,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,YAAA;AACtB,IAAA,IAAA,CAAK,uBAAA,EAAwB;AAAA,EAC/B;AACF;AACA,SAAS,WAAW,CAAA,EAAW;AAAE,EAAA,OAAO,EAAE,OAAA,CAAQ,SAAA,EAAW,CAAC,CAAA,KAAA,CAAO,EAAE,GAAA,EAAK,OAAA,EAAS,GAAA,EAAK,MAAA,EAAQ,KAAK,MAAA,EAAQ,GAAA,EAAK,QAAA,EAAS,EAAE,CAAC,CAAG,CAAA;AAAG;;;AC5LtI,IAAI,OAAO,cAAA,KAAmB,WAAA,IAAe,CAAC,cAAA,CAAe,GAAA,CAAI,eAAe,CAAA,EAAG;AACjF,EAAA,cAAA,CAAe,MAAA,CAAO,iBAAiB,mBAAmB,CAAA;AAC5D","file":"index.js","sourcesContent":["export class ChatApiError extends Error {\n constructor(message: string, readonly status: number, readonly code?: string, readonly meta?: Record<string, unknown>) {\n super(message);\n this.name = 'ChatApiError';\n }\n}\n","import { ChatApiError } from './errors';\nimport type { ChatAttachmentDescriptor, OpenSessionResponse, StreamTicket } from './protocol';\n\nasync function asError(res: Response, fallbackCode?: string): Promise<ChatApiError> {\n let body: { error?: string; code?: string; meta?: Record<string, unknown> } = {};\n try { body = (await res.json()) as { error?: string; code?: string; meta?: Record<string, unknown> }; } catch { /* non-json */ }\n return new ChatApiError(body.error ?? `HTTP ${res.status}`, res.status, body.code ?? fallbackCode, body.meta);\n}\n\nexport async function openSession(opts: { baseUrl: string; apiKey: string; agentId: string; user?: { id?: string }; clientTools?: string[]; fetchImpl: typeof fetch }): Promise<OpenSessionResponse> {\n const body: Record<string, unknown> = { agentId: opts.agentId };\n if (opts.user) body.user = opts.user;\n if (opts.clientTools && opts.clientTools.length > 0) body.clientTools = opts.clientTools;\n const res = await opts.fetchImpl(`${opts.baseUrl}/chat/sessions`, {\n method: 'POST', credentials: 'omit',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${opts.apiKey}` },\n body: JSON.stringify(body),\n });\n if (!res.ok) throw await asError(res);\n return (await res.json()) as OpenSessionResponse;\n}\n\nexport async function postMessage(opts: { baseUrl: string; sessionId: string; sessionToken: string; text: string; attachments?: ChatAttachmentDescriptor[]; fetchImpl: typeof fetch }): Promise<void> {\n const body: Record<string, unknown> = { text: opts.text };\n if (opts.attachments && opts.attachments.length > 0) body.attachments = opts.attachments;\n const res = await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/messages`, {\n method: 'POST', credentials: 'omit',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${opts.sessionToken}` },\n body: JSON.stringify(body),\n });\n // A 401 here means the 15-min session token expired (no refresh endpoint) — surface a stable code\n // so the client can transparently re-open a session and retry.\n if (!res.ok) throw await asError(res, res.status === 401 ? 'session_expired' : undefined);\n}\n\nexport async function endSession(opts: { baseUrl: string; sessionId: string; sessionToken: string; fetchImpl: typeof fetch }): Promise<void> {\n await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/end`, {\n method: 'POST', credentials: 'omit',\n headers: { Authorization: `Bearer ${opts.sessionToken}` },\n }).catch(() => {}); // best-effort teardown\n}\n\nexport async function postToolResult(opts: { baseUrl: string; sessionId: string; sessionToken: string; callId: string; ok: boolean; result: unknown; fetchImpl: typeof fetch }): Promise<void> {\n await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/tool-results`, {\n method: 'POST', credentials: 'omit',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${opts.sessionToken}` },\n body: JSON.stringify({ callId: opts.callId, ok: opts.ok, result: opts.result }),\n }).catch(() => {}); // best-effort; a dropped result times out server-side and the model recovers\n}\n\nexport async function mintStreamTicket(opts: { baseUrl: string; sessionId: string; sessionToken: string; fetchImpl: typeof fetch }): Promise<StreamTicket> {\n const res = await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/stream-ticket`, {\n method: 'POST', credentials: 'omit',\n headers: { Authorization: `Bearer ${opts.sessionToken}` },\n });\n // A 401 here means the session token is invalid/expired — surface a stable code so the client\n // can distinguish this from a transient failure (mirrors postMessage's 401 mapping).\n if (!res.ok) throw await asError(res, res.status === 401 ? 'session_expired' : undefined);\n return (await res.json()) as StreamTicket;\n}\n\nexport function streamUrl(baseUrl: string, sessionId: string, ticket: string): string {\n return `${baseUrl}/chat/sessions/${sessionId}/stream?ticket=${encodeURIComponent(ticket)}`;\n}\n\n// POST /chat/sessions/:id/attachments — mints a presigned S3 PUT for a visitor upload. Bearer session\n// token auth, mirrors mintStreamTicket's shape/error-mapping exactly.\nexport async function presignAttachment(opts: { baseUrl: string; sessionId: string; sessionToken: string; contentType: string; fetchImpl: typeof fetch }): Promise<{ storageRef: string; uploadUrl: string }> {\n const res = await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/attachments`, {\n method: 'POST', credentials: 'omit',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${opts.sessionToken}` },\n body: JSON.stringify({ contentType: opts.contentType }),\n });\n // A 401 here means the session token is invalid/expired — surface a stable code so the client\n // can distinguish this from a transient failure (mirrors postMessage's 401 mapping).\n if (!res.ok) throw await asError(res, res.status === 401 ? 'session_expired' : undefined);\n return (await res.json()) as { storageRef: string; uploadUrl: string };\n}\n\n// POST /chat/sessions/:id/attachment-url — mints a presigned S3 GET so an already-uploaded\n// attachment can be read back (e.g. rendering an image thumbnail on reconnect, when no local blob\n// is cached). Bearer session token auth, mirrors presignAttachment's shape/error-mapping exactly.\nexport async function getAttachmentUrl(opts: { baseUrl: string; sessionId: string; sessionToken: string; storageRef: string; fetchImpl: typeof fetch }): Promise<string> {\n const res = await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/attachment-url`, {\n method: 'POST', credentials: 'omit',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${opts.sessionToken}` },\n body: JSON.stringify({ storageRef: opts.storageRef }),\n });\n // A 401 here means the session token is invalid/expired — surface a stable code so the client\n // can distinguish this from a transient failure (mirrors postMessage's 401 mapping).\n if (!res.ok) throw await asError(res, res.status === 401 ? 'session_expired' : undefined);\n return ((await res.json()) as { url: string }).url;\n}\n\n// Uploads a file directly to the presigned S3 URL. The URL is already absolute and fully signed —\n// NO baseUrl prefix, NO Authorization header (would break the signature), just a bare PUT with the\n// file's own content type (Task 4 dropped SSE from the presign so this needs no extra headers).\nexport async function uploadToPresigned(uploadUrl: string, file: File, fetchImpl: typeof fetch): Promise<void> {\n const res = await fetchImpl(uploadUrl, { method: 'PUT', body: file, headers: { 'Content-Type': file.type } });\n if (!res.ok) throw new ChatApiError(`attachment upload failed with HTTP ${res.status}`, res.status);\n}\n","import { openSession, postMessage, endSession, streamUrl, mintStreamTicket, postToolResult, presignAttachment, uploadToPresigned, getAttachmentUrl } from './transport';\nimport { ChatApiError } from './errors';\nimport type { ChatAttachmentDescriptor, ChatClientOptions, ChatEvent, OpenSessionResponse } from './protocol';\n\nexport interface ChatMessage { id: string; role: 'user' | 'assistant' | 'human'; text: string; streaming: boolean; attachments?: ChatAttachmentDescriptor[]; sources?: { id: string; title: string; snippet: string }[]; turnId?: string }\nexport type ChatClientState = 'idle' | 'opening' | 'ready' | 'ended' | 'error';\n// Handoff status of the session, driven by the backend's `state` SSE event (Phase 7). 'ai' = the\n// AI is answering (default/no handoff), 'awaiting_human' = a handoff was requested and no human\n// has taken over yet, 'human' = a human agent is answering.\nexport type HandoffState = 'ai' | 'awaiting_human' | 'human';\nexport type ChatClientEvent =\n | { type: 'state'; state: ChatClientState }\n | { type: 'messages'; messages: ChatMessage[] }\n | { type: 'error'; error: Error }\n | { type: 'agent'; agent: { id: string; name: string } }\n // Handoff status changed (Phase 7) - the widget uses this to show a status line.\n | { type: 'handoff'; state: HandoffState }\n // A human agent is (or stopped) typing in the console during a handoff (Phase 7 followups). The\n // widget uses this to show a transient \"agent is typing…\" affordance - never a message.\n | { type: 'agentTyping'; active: boolean };\nexport type ChatToolHandler = (args: Record<string, unknown>) => unknown | Promise<unknown>;\nexport interface ChatClient {\n start(): Promise<void>;\n sendMessage(text: string, files?: File[]): Promise<void>;\n end(): Promise<void>;\n getMessages(): ChatMessage[];\n getState(): ChatClientState;\n on(listener: (e: ChatClientEvent) => void): () => void;\n // Register browser-side tool handlers the server may call mid-conversation. Register BEFORE\n // start() — the handler names are sent as `clientTools` on session open so the server knows\n // which tools this session can execute.\n registerTools(handlers: Record<string, ChatToolHandler>): void;\n // Resolves a read-back URL for an already-uploaded attachment (e.g. an image thumbnail with no\n // local blob cached — a reconnect, or an `attachment` SSE echo). Requires start() to have been\n // called (a live session).\n getAttachmentUrl(storageRef: string): Promise<string>;\n}\n\nlet seq = 0;\nconst uid = (p: string) => `${p}_${Date.now().toString(36)}_${(seq++).toString(36)}`;\n\nexport function createChatClient(options: ChatClientOptions): ChatClient {\n // Native fetch must be invoked with `this === window`; the transport calls this as\n // `opts.fetchImpl(...)`, so a bare `globalThis.fetch` reference throws \"Illegal invocation\".\n // Bind the default to the global. A caller-supplied fetch is used as-is.\n const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n const ES = options.eventSource ?? globalThis.EventSource;\n // Mirrors the server's CHAT_ATTACHMENT_MAX_PER_MESSAGE default (apps/api/src/config/env.ts).\n const maxAttachments = options.maxAttachments ?? 4;\n // Mirrors the server's CHAT_ATTACHMENT_MAX_BYTES default (apps/api/src/config/env.ts). UX-only\n // fast pre-check - the server is authoritative (message-time HeadObject size enforcement).\n const maxAttachmentBytes = options.maxAttachmentBytes ?? 10_000_000;\n const listeners = new Set<(e: ChatClientEvent) => void>();\n let state: ChatClientState = 'idle';\n const messages: ChatMessage[] = [];\n let streamingId: string | null = null;\n let session: OpenSessionResponse | null = null;\n let es: EventSource | null = null;\n const seenTurnIds = new Set<string>();\n const seenCallIds = new Set<string>();\n let handoffState: HandoffState = 'ai';\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let reconnectAttempts = 0;\n let closed = false;\n const toolHandlers = new Map<string, ChatToolHandler>();\n const clearReconnect = () => { if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; } };\n\n const emit = (e: ChatClientEvent) => { for (const l of listeners) l(e); };\n const setState = (s: ChatClientState) => { state = s; emit({ type: 'state', state: s }); };\n const emitMessages = () => emit({ type: 'messages', messages: messages.slice() });\n\n const onEvent = (ev: ChatEvent) => {\n if (ev.type === 'token') {\n let m = streamingId ? messages.find((x) => x.id === streamingId) : undefined;\n if (!m) { m = { id: uid('m'), role: 'assistant', text: '', streaming: true }; messages.push(m); streamingId = m.id; }\n m.text += ev.text; emitMessages();\n } else if (ev.type === 'message') {\n if (seenTurnIds.has(ev.turnId)) {\n // Replay of an already-finalized turn (EventSource reconnect replays the session's\n // event buffer). Discard it, and drop any partial streaming bubble its replayed\n // tokens built up, without emitting a duplicate assistant message.\n if (streamingId) {\n const idx = messages.findIndex((x) => x.id === streamingId);\n if (idx !== -1) messages.splice(idx, 1);\n streamingId = null;\n emitMessages();\n }\n return;\n }\n seenTurnIds.add(ev.turnId);\n const m = streamingId ? messages.find((x) => x.id === streamingId) : undefined;\n if (m) { m.text = ev.text; m.streaming = false; m.turnId = ev.turnId; } else { messages.push({ id: uid('m'), role: 'assistant', text: ev.text, streaming: false, turnId: ev.turnId }); }\n streamingId = null; emitMessages();\n } else if (ev.type === 'citations') {\n // Arrives AFTER `message` (streamingId already cleared) so the target message is located by\n // the turnId stamped above, not by streamingId. Ignore an unknown turnId (reconnect-safe: a\n // stale/duplicate citations replay for a turn we don't have never crashes or creates a bubble).\n const m = messages.find((x) => x.turnId === ev.turnId);\n if (m) { m.sources = ev.sources; emitMessages(); }\n } else if (ev.type === 'error') {\n emit({ type: 'error', error: new Error(ev.message) });\n } else if (ev.type === 'tool_call') {\n if (seenCallIds.has(ev.callId)) return; // replayed on EventSource reconnect — dispatch once\n seenCallIds.add(ev.callId);\n const handler = toolHandlers.get(ev.name);\n void (async () => {\n if (!session) return;\n const base = { baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, callId: ev.callId, fetchImpl };\n if (!handler) {\n await postToolResult({ ...base, ok: false, result: `no handler registered for ${ev.name}` });\n return;\n }\n try {\n const out = await handler(ev.args);\n await postToolResult({ ...base, ok: true, result: typeof out === 'string' ? out : JSON.stringify(out ?? { ok: true }) });\n } catch (err) {\n await postToolResult({ ...base, ok: false, result: (err as Error).message });\n }\n })();\n } else if (ev.type === 'attachment') {\n // The runtime re-publishes a visitor's message attachments over this event (Phase 5\n // follow-up) so a reconnecting client (buffer replay) or a future second viewer can render\n // them, now that a read-back URL exists (getAttachmentUrl / element.ts's lazy image src).\n // Hardened so it can never double-render on the SENDING client itself, which already rendered\n // these optimistically from its own sendMessage(): if any existing message already carries an\n // attachment with one of these storageRefs, the event is a stale/duplicate echo of something\n // already rendered — ignore it entirely instead of guessing which message to attach to (a\n // \"most recent attachment-less user message\" heuristic misattaches when a second image-first\n // message is sent before the echo of the first one arrives).\n const items = ev.items;\n const alreadyRendered = messages.some((m) => m.attachments?.some((a) => items.some((i) => i.storageRef === a.storageRef)));\n if (alreadyRendered) return;\n const target = [...messages].reverse().find((m) => m.role === 'user' && !m.attachments);\n if (target) target.attachments = items;\n else messages.push({ id: uid('u'), role: 'user', text: '', streaming: false, attachments: items });\n emitMessages();\n } else if (ev.type === 'human_message') {\n // A human agent's reply from the console inbox (Phase 7 handoff) - render as a distinct bubble.\n // Dedup by turnId (shared with the `message` branch's seenTurnIds) - EventSource reconnect\n // replays the session's buffered events, and human_message turnIds (newId('tn')) are distinct\n // from message turnIds, so sharing the Set is safe.\n if (seenTurnIds.has(ev.turnId)) return;\n seenTurnIds.add(ev.turnId);\n messages.push({ id: uid('m'), role: 'human', text: ev.text, streaming: false });\n emitMessages();\n } else if (ev.type === 'visitor_message') {\n // Echo of the visitor's own message, published so the console inbox sees it live. The widget\n // already rendered this optimistically in sendMessage() - ignore the echo entirely.\n } else if (ev.type === 'state') {\n // Handoff status transition (Phase 7): 'ai' | 'awaiting_human' | 'human'. Ignore any other/\n // future state string - forward-compat, no status line for an unrecognized value.\n if (ev.state === 'ai' || ev.state === 'awaiting_human' || ev.state === 'human') {\n handoffState = ev.state;\n emit({ type: 'handoff', state: handoffState });\n }\n } else if (ev.type === 'agent_typing') {\n // Transient signal only - never pushed as a message, never touches dedup/streaming state.\n emit({ type: 'agentTyping', active: !!ev.active });\n }\n // 'done' and any future unknown types are ignored (forward-compat).\n };\n\n // Tickets are single-use and short-lived: a fresh one must be minted for every (re)connect.\n // Native EventSource auto-reconnect would retry the SAME url whose ticket is already consumed\n // (→ 401 forever), so on error we close it ourselves and drive reconnection here instead.\n const openStream = async () => {\n if (!session || closed) return;\n es?.close();\n const { ticket } = await mintStreamTicket({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, fetchImpl });\n if (closed) return;\n es = new ES(streamUrl(options.baseUrl, session.sessionId, ticket));\n es.onopen = () => { reconnectAttempts = 0; };\n es.onmessage = (e: MessageEvent) => { try { onEvent(JSON.parse(e.data) as ChatEvent); } catch { /* ignore malformed */ } };\n es.onerror = () => { es?.close(); es = null; scheduleReconnect(); };\n };\n\n const scheduleReconnect = () => {\n if (closed) return;\n clearReconnect();\n const delay = Math.min(30_000, 500 * 2 ** reconnectAttempts);\n reconnectAttempts += 1;\n reconnectTimer = setTimeout(() => {\n openStream().catch((err) => {\n if (err instanceof ChatApiError && (err as ChatApiError).code === 'session_expired') {\n open().catch((e) => { emit({ type: 'error', error: e as Error }); scheduleReconnect(); });\n } else {\n scheduleReconnect();\n }\n });\n }, delay);\n };\n\n const open = async () => {\n session = await openSession({ baseUrl: options.baseUrl, apiKey: options.apiKey, agentId: options.agentId, user: options.user, clientTools: Array.from(toolHandlers.keys()), fetchImpl });\n emit({ type: 'agent', agent: session.agent });\n await openStream();\n };\n\n // Presign + PUT every file against the CURRENT session. Called from the main sendMessage path and,\n // after a session_expired reopen, from the retry — a storageRef presigned against the old\n // interactionId is rejected cross-session (403 attachment_cross_session) if reused post-reopen.\n const uploadFiles = async (files: File[]): Promise<ChatAttachmentDescriptor[]> => {\n return Promise.all(files.map(async (file): Promise<ChatAttachmentDescriptor> => {\n const { storageRef, uploadUrl } = await presignAttachment({ baseUrl: options.baseUrl, sessionId: session!.sessionId, sessionToken: session!.sessionToken, contentType: file.type, fetchImpl });\n await uploadToPresigned(uploadUrl, file, fetchImpl);\n return { storageRef, contentType: file.type, name: file.name };\n }));\n };\n\n return {\n getMessages: () => messages.slice(),\n getState: () => state,\n on(listener) { listeners.add(listener); return () => listeners.delete(listener); },\n registerTools(handlers) { for (const [name, fn] of Object.entries(handlers)) toolHandlers.set(name, fn); },\n async getAttachmentUrl(storageRef) {\n if (!session) throw new Error('call start() before getAttachmentUrl');\n return getAttachmentUrl({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, storageRef, fetchImpl });\n },\n async start() {\n if (state !== 'idle') return;\n setState('opening');\n try { await open(); setState('ready'); }\n catch (err) { setState('error'); emit({ type: 'error', error: err as Error }); }\n },\n async sendMessage(text, files) {\n if (!session) { emit({ type: 'error', error: new Error('call start() before sendMessage') }); return; }\n const fileList = files ?? [];\n if (fileList.length > maxAttachments) {\n emit({ type: 'error', error: new Error(`too many attachments: max ${maxAttachments} per message`) });\n return;\n }\n const oversized = fileList.find((f) => f.size > maxAttachmentBytes);\n if (oversized) {\n emit({ type: 'error', error: new Error(`attachment too large: ${oversized.name} exceeds ${maxAttachmentBytes} bytes`) });\n return;\n }\n // Upload every file BEFORE posting the message or pushing the optimistic bubble — a failed\n // upload must never leave a broken/partial message in the thread.\n let attachments: ChatAttachmentDescriptor[] = [];\n if (fileList.length > 0) {\n try {\n attachments = await uploadFiles(fileList);\n } catch (err) {\n emit({ type: 'error', error: err as Error });\n return;\n }\n }\n messages.push({ id: uid('u'), role: 'user', text, streaming: false, attachments: attachments.length > 0 ? attachments : undefined }); emitMessages();\n try {\n await postMessage({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, text, attachments, fetchImpl });\n } catch (err) {\n if (err instanceof ChatApiError && err.code === 'session_expired') {\n try {\n await open(); // fresh backend session, same UI thread\n // Re-upload against the NEW session — the old attachments' storageRefs are bound to the\n // stale interactionId and would 403 (attachment_cross_session) if re-posted as-is.\n const freshAttachments = fileList.length ? await uploadFiles(fileList) : [];\n await postMessage({ baseUrl: options.baseUrl, sessionId: session!.sessionId, sessionToken: session!.sessionToken, text, attachments: freshAttachments, fetchImpl });\n } catch (retryErr) {\n emit({ type: 'error', error: retryErr as Error });\n }\n } else { emit({ type: 'error', error: err as Error }); }\n }\n },\n async end() {\n closed = true; clearReconnect();\n if (session) await endSession({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, fetchImpl });\n es?.close(); es = null; setState('ended');\n },\n };\n}\n","import { createChatClient, type ChatClient, type ChatMessage, type ChatClientState, type ChatToolHandler, type HandoffState } from './client';\nimport type { ChatAttachmentDescriptor } from './protocol';\n\nconst HANDOFF_STATUS_TEXT: Record<HandoffState, string | null> = {\n ai: null,\n awaiting_human: 'Connecting you to a person…',\n human: \"You're chatting with a person\",\n};\n\nconst ATTACHMENT_ACCEPT = 'image/*,application/pdf,text/plain,text/csv';\nconst AGENT_TYPING_TEXT = 'The agent is typing…';\n\nexport class OyehelloChatElement extends HTMLElement {\n static observedAttributes = ['api-key', 'agent-id', 'base-url', 'title'];\n private client: ChatClient | null = null;\n private off: (() => void) | null = null;\n private messages: ChatMessage[] = [];\n private state: ChatClientState = 'idle';\n private agentName: string | null = null;\n private handoffState: HandoffState = 'ai';\n // Transient \"agent is typing…\" affordance (Phase 7 followups) - never a message, only rendered\n // while a handoff is active (human/awaiting_human).\n private agentTyping = false;\n // Last connection/runtime error message (client emits an 'error' event on a failed start() or\n // send). Surfaced as a visible banner so a disabled composer always shows WHY, instead of sitting\n // dead. Cleared when the client reaches a healthy state again.\n private lastError: string | null = null;\n // registerTools() may be called before connectedCallback creates the client (e.g. right after\n // document.createElement, before the element is attached). Buffer until the client exists.\n private pendingTools: Record<string, ChatToolHandler> = {};\n // Files picked in the file input, staged until the form submits alongside the text.\n private pendingFiles: File[] = [];\n // Best-effort local thumbnail cache for images THIS widget instance just sent, keyed by filename -\n // an instant blob src, no round-trip needed.\n private imagePreviewCache = new Map<string, string>();\n // Read-back URLs resolved lazily (via client.getAttachmentUrl) for images with no local blob (a\n // reconnect, or an `attachment` SSE echo), keyed by storageRef. Cached across re-renders so the\n // same image isn't re-fetched on every render() call.\n private resolvedUrlCache = new Map<string, string>();\n\n connectedCallback() {\n if (!this.shadowRoot) this.attachShadow({ mode: 'open' });\n const apiKey = this.getAttribute('api-key');\n const agentId = this.getAttribute('agent-id');\n const baseUrl = this.getAttribute('base-url');\n if (!apiKey || !agentId || !baseUrl) { this.renderError('oyehello-chat: api-key, agent-id and base-url are required'); return; }\n this.client = createChatClient({ apiKey, agentId, baseUrl });\n if (Object.keys(this.pendingTools).length > 0) { this.client.registerTools(this.pendingTools); this.pendingTools = {}; }\n this.off = this.client.on((e) => {\n if (e.type === 'messages') this.messages = e.messages;\n else if (e.type === 'state') { this.state = e.state; if (e.state === 'ready' || e.state === 'opening') this.lastError = null; }\n else if (e.type === 'agent') this.agentName = e.agent.name;\n else if (e.type === 'handoff') this.handoffState = e.state;\n else if (e.type === 'agentTyping') this.agentTyping = e.active;\n else if (e.type === 'error') this.lastError = e.error.message;\n this.render();\n });\n this.render();\n void this.client.start();\n }\n disconnectedCallback() {\n this.off?.(); void this.client?.end();\n for (const url of this.imagePreviewCache.values()) { if (typeof URL.revokeObjectURL === 'function') URL.revokeObjectURL(url); }\n this.imagePreviewCache.clear();\n }\n\n registerTools(handlers: Record<string, ChatToolHandler>) {\n if (this.client) this.client.registerTools(handlers);\n else Object.assign(this.pendingTools, handlers);\n }\n\n private send(text: string, files: File[]) {\n if (!text.trim()) return;\n for (const f of files) {\n if (f.type.startsWith('image/') && typeof URL.createObjectURL === 'function' && !this.imagePreviewCache.has(f.name)) {\n this.imagePreviewCache.set(f.name, URL.createObjectURL(f));\n }\n }\n void this.client?.sendMessage(text, files.length > 0 ? files : undefined);\n }\n private renderError(msg: string) {\n if (!this.shadowRoot) this.attachShadow({ mode: 'open' });\n this.shadowRoot!.innerHTML = `<div style=\"color:#b91c1c;font:13px system-ui;padding:12px\">${escapeHtml(msg)}</div>`;\n }\n private renderAttachment(a: ChatAttachmentDescriptor): string {\n if (a.contentType.startsWith('image/')) {\n // Instant src when a local blob (just sent by this widget instance) or a previously-resolved\n // read-back URL is cached. Otherwise render the placeholder with a data-oc-ref marker and no\n // src attribute (an empty src=\"\" would make the browser (re)request the current page) -\n // hydrateAttachmentImages() resolves it lazily right after this markup is attached to the DOM.\n const cached = (a.name ? this.imagePreviewCache.get(a.name) : undefined) ?? this.resolvedUrlCache.get(a.storageRef);\n const srcAttr = cached ? ` src=\"${cached}\"` : '';\n return `<img class=\"att-thumb\" data-oc-ref=\"${escapeHtml(a.storageRef)}\"${srcAttr} alt=\"${escapeHtml(a.name ?? 'image')}\"/>`;\n }\n return `<div class=\"att-chip\">📎 ${escapeHtml(a.name ?? a.contentType)}</div>`;\n }\n private renderSource(s: { id: string; title: string; snippet: string }): string {\n return `<div class=\"src-chip\" title=\"${escapeHtml(s.snippet)}\">${escapeHtml(s.title)}</div>`;\n }\n\n // After render() attaches the markup, resolve a read-back URL (via the client) for every image\n // placeholder that has no src yet - a local blob or a previously-resolved URL already set one, so\n // those are left untouched (no redundant network call).\n private hydrateAttachmentImages() {\n if (!this.client) return;\n const imgs = this.shadowRoot!.querySelectorAll<HTMLImageElement>('img.att-thumb[data-oc-ref]');\n imgs.forEach((img) => {\n if (img.hasAttribute('src')) return;\n const ref = img.getAttribute('data-oc-ref');\n if (!ref) return;\n void this.client!.getAttachmentUrl(ref)\n .then((url) => { this.resolvedUrlCache.set(ref, url); img.src = url; })\n .catch(() => { /* leave unresolved - no thumbnail is an acceptable degrade, not fatal */ });\n });\n }\n\n private render() {\n const title = this.getAttribute('title') ?? this.agentName ?? 'Chat';\n const bubbles = this.messages.map((m) => {\n const atts = (m.attachments ?? []).map((a) => this.renderAttachment(a)).join('');\n const label = m.role === 'human' ? '<div class=\"human-label\">Support</div>' : '';\n const bubble = `<div class=\"b ${m.role}\">${label}${atts}${m.text ? escapeHtml(m.text) : ''}${m.streaming ? '…' : ''}</div>`;\n const sources = m.sources && m.sources.length > 0 ? `<div class=\"src-row\">${m.sources.map((s) => this.renderSource(s)).join('')}</div>` : '';\n return bubble + sources;\n }).join('');\n const statusText = HANDOFF_STATUS_TEXT[this.handoffState];\n const status = statusText ? `<div class=\"status\">${escapeHtml(statusText)}</div>` : '';\n const errBanner = this.state === 'error' && this.lastError\n ? `<div class=\"err\">Couldn't start chat: ${escapeHtml(this.lastError)}</div>`\n : '';\n const showTyping = this.agentTyping && (this.handoffState === 'human' || this.handoffState === 'awaiting_human');\n const typingIndicator = showTyping ? `<div class=\"b assistant typing\">${escapeHtml(AGENT_TYPING_TEXT)}</div>` : '';\n const disabled = this.state !== 'ready' ? 'disabled' : '';\n // Rebuilding innerHTML replaces the input node, which would otherwise drop the user's\n // in-progress text + caret on every streamed token. Capture and restore across the rebuild.\n const prevInput = this.shadowRoot!.querySelector<HTMLInputElement>('input[aria-label=\"message\"]');\n const prevValue = prevInput?.value ?? '';\n const prevSelectionStart = prevInput?.selectionStart ?? null;\n const prevSelectionEnd = prevInput?.selectionEnd ?? null;\n const hadFocus = !!prevInput && this.shadowRoot!.activeElement === prevInput;\n this.shadowRoot!.innerHTML = `\n <style>\n :host{display:block;height:100%;min-height:320px;font-family:system-ui,sans-serif;--oc-accent:#2563eb}\n .wrap{display:flex;flex-direction:column;height:100%;border:1px solid #e5e7eb;border-radius:12px;overflow:hidden}\n .hd{padding:10px 14px;border-bottom:1px solid #e5e7eb;font-weight:600}\n .body{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px}\n .b{max-width:80%;padding:8px 12px;border-radius:12px;white-space:pre-wrap;word-break:break-word}\n .b.user{align-self:flex-end;background:var(--oc-accent);color:#fff}\n .b.assistant{align-self:flex-start;background:#f3f4f6;color:#111}\n .b.human{align-self:flex-start;background:#dbeafe;color:#111}\n .b.typing{font-style:italic;color:#6b7280;opacity:.85}\n .human-label{font-size:11px;font-weight:600;opacity:.7;margin-bottom:2px}\n .status{padding:6px 14px;font-size:12px;color:#6b7280;background:#f9fafb;border-bottom:1px solid #e5e7eb}\n .err{padding:8px 14px;font-size:12px;color:#b91c1c;background:#fef2f2;border-bottom:1px solid #fecaca}\n .att-thumb{display:block;max-width:160px;max-height:160px;border-radius:8px;margin-bottom:6px}\n .att-chip{display:inline-block;font-size:12px;background:rgba(0,0,0,.08);border-radius:6px;padding:2px 8px;margin:0 0 6px}\n .b.user .att-chip{background:rgba(255,255,255,.25)}\n .src-row{align-self:flex-start;display:flex;flex-wrap:wrap;gap:6px;max-width:80%}\n .src-chip{display:inline-block;font-size:11px;background:rgba(0,0,0,.06);color:#374151;border-radius:6px;padding:2px 8px;cursor:default}\n form{display:flex;gap:8px;padding:10px;border-top:1px solid #e5e7eb;align-items:center}\n input[aria-label=\"message\"]{flex:1;padding:8px 10px;border-radius:8px;border:1px solid #d1d5db;font:inherit}\n input[type=\"file\"]{max-width:120px;font-size:12px}\n button{padding:8px 14px;border-radius:8px;border:none;background:var(--oc-accent);color:#fff;font-weight:600;cursor:pointer}\n button:disabled,input:disabled{opacity:.6;cursor:not-allowed}\n </style>\n <div class=\"wrap\">\n <div class=\"hd\">${escapeHtml(title)}</div>\n ${status}${errBanner}\n <div class=\"body\">${bubbles}${typingIndicator}</div>\n <form>\n <input aria-label=\"message\" placeholder=\"Type a message…\" ${disabled}/>\n <input type=\"file\" accept=\"${ATTACHMENT_ACCEPT}\" multiple ${disabled}/>\n <button type=\"submit\" ${disabled}>Send</button>\n </form>\n </div>`;\n const form = this.shadowRoot!.querySelector('form')!;\n const input = this.shadowRoot!.querySelector<HTMLInputElement>('input[aria-label=\"message\"]')!;\n const fileInput = this.shadowRoot!.querySelector<HTMLInputElement>('input[type=\"file\"]')!;\n fileInput.addEventListener('change', () => { this.pendingFiles = fileInput.files ? Array.from(fileInput.files) : []; });\n form.addEventListener('submit', (e) => {\n e.preventDefault();\n const files = this.pendingFiles;\n this.pendingFiles = [];\n this.send(input.value, files);\n input.value = '';\n });\n if (prevValue) {\n input.value = prevValue;\n if (prevSelectionStart !== null && prevSelectionEnd !== null) input.setSelectionRange(prevSelectionStart, prevSelectionEnd);\n }\n if (hadFocus) input.focus();\n const body = this.shadowRoot!.querySelector('.body')!;\n body.scrollTop = body.scrollHeight;\n this.hydrateAttachmentImages();\n }\n}\nfunction escapeHtml(s: string) { return s.replace(/[&<>\"]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;' }[c]!)); }\n","export { ChatApiError } from './errors';\nexport type { ChatEvent, OpenSessionResponse, ChatClientOptions, ChatAttachmentDescriptor } from './protocol';\nexport { createChatClient } from './client';\nexport type { ChatClient, ChatMessage, ChatClientState, ChatClientEvent, ChatToolHandler } from './client';\nexport { OyehelloChatElement } from './element';\n\nimport { OyehelloChatElement } from './element';\n// Side effect: registering the element is why the package is sideEffects:true.\nif (typeof customElements !== 'undefined' && !customElements.get('oyehello-chat')) {\n customElements.define('oyehello-chat', OyehelloChatElement);\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/transport.ts","../src/client.ts","../src/markdown.ts","../src/styles.ts","../src/icons.ts","../src/emoji.ts","../src/element.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export class ChatApiError extends Error {\n constructor(message: string, readonly status: number, readonly code?: string, readonly meta?: Record<string, unknown>) {\n super(message);\n this.name = 'ChatApiError';\n }\n}\n","import { ChatApiError } from './errors';\nimport type { ChatAttachmentDescriptor, OpenSessionResponse, StreamTicket } from './protocol';\n\nasync function asError(res: Response, fallbackCode?: string): Promise<ChatApiError> {\n let body: { error?: string; code?: string; meta?: Record<string, unknown> } = {};\n try { body = (await res.json()) as { error?: string; code?: string; meta?: Record<string, unknown> }; } catch { /* non-json */ }\n return new ChatApiError(body.error ?? `HTTP ${res.status}`, res.status, body.code ?? fallbackCode, body.meta);\n}\n\nexport async function openSession(opts: { baseUrl: string; apiKey: string; agentId: string; user?: { id?: string }; clientTools?: string[]; fetchImpl: typeof fetch }): Promise<OpenSessionResponse> {\n const body: Record<string, unknown> = { agentId: opts.agentId };\n if (opts.user) body.user = opts.user;\n if (opts.clientTools && opts.clientTools.length > 0) body.clientTools = opts.clientTools;\n const res = await opts.fetchImpl(`${opts.baseUrl}/chat/sessions`, {\n method: 'POST', credentials: 'omit',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${opts.apiKey}` },\n body: JSON.stringify(body),\n });\n if (!res.ok) throw await asError(res);\n return (await res.json()) as OpenSessionResponse;\n}\n\nexport async function postMessage(opts: { baseUrl: string; sessionId: string; sessionToken: string; text: string; attachments?: ChatAttachmentDescriptor[]; fetchImpl: typeof fetch }): Promise<void> {\n const body: Record<string, unknown> = { text: opts.text };\n if (opts.attachments && opts.attachments.length > 0) body.attachments = opts.attachments;\n const res = await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/messages`, {\n method: 'POST', credentials: 'omit',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${opts.sessionToken}` },\n body: JSON.stringify(body),\n });\n // A 401 here means the 15-min session token expired (no refresh endpoint) — surface a stable code\n // so the client can transparently re-open a session and retry.\n if (!res.ok) throw await asError(res, res.status === 401 ? 'session_expired' : undefined);\n}\n\nexport async function endSession(opts: { baseUrl: string; sessionId: string; sessionToken: string; fetchImpl: typeof fetch }): Promise<void> {\n await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/end`, {\n method: 'POST', credentials: 'omit',\n headers: { Authorization: `Bearer ${opts.sessionToken}` },\n }).catch(() => {}); // best-effort teardown\n}\n\nexport async function postToolResult(opts: { baseUrl: string; sessionId: string; sessionToken: string; callId: string; ok: boolean; result: unknown; fetchImpl: typeof fetch }): Promise<void> {\n await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/tool-results`, {\n method: 'POST', credentials: 'omit',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${opts.sessionToken}` },\n body: JSON.stringify({ callId: opts.callId, ok: opts.ok, result: opts.result }),\n }).catch(() => {}); // best-effort; a dropped result times out server-side and the model recovers\n}\n\nexport async function mintStreamTicket(opts: { baseUrl: string; sessionId: string; sessionToken: string; fetchImpl: typeof fetch }): Promise<StreamTicket> {\n const res = await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/stream-ticket`, {\n method: 'POST', credentials: 'omit',\n headers: { Authorization: `Bearer ${opts.sessionToken}` },\n });\n // A 401 here means the session token is invalid/expired — surface a stable code so the client\n // can distinguish this from a transient failure (mirrors postMessage's 401 mapping).\n if (!res.ok) throw await asError(res, res.status === 401 ? 'session_expired' : undefined);\n return (await res.json()) as StreamTicket;\n}\n\nexport function streamUrl(baseUrl: string, sessionId: string, ticket: string): string {\n return `${baseUrl}/chat/sessions/${sessionId}/stream?ticket=${encodeURIComponent(ticket)}`;\n}\n\n// POST /chat/sessions/:id/attachments — mints a presigned S3 PUT for a visitor upload. Bearer session\n// token auth, mirrors mintStreamTicket's shape/error-mapping exactly.\nexport async function presignAttachment(opts: { baseUrl: string; sessionId: string; sessionToken: string; contentType: string; fetchImpl: typeof fetch }): Promise<{ storageRef: string; uploadUrl: string }> {\n const res = await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/attachments`, {\n method: 'POST', credentials: 'omit',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${opts.sessionToken}` },\n body: JSON.stringify({ contentType: opts.contentType }),\n });\n // A 401 here means the session token is invalid/expired — surface a stable code so the client\n // can distinguish this from a transient failure (mirrors postMessage's 401 mapping).\n if (!res.ok) throw await asError(res, res.status === 401 ? 'session_expired' : undefined);\n return (await res.json()) as { storageRef: string; uploadUrl: string };\n}\n\n// POST /chat/sessions/:id/attachment-url — mints a presigned S3 GET so an already-uploaded\n// attachment can be read back (e.g. rendering an image thumbnail on reconnect, when no local blob\n// is cached). Bearer session token auth, mirrors presignAttachment's shape/error-mapping exactly.\nexport async function getAttachmentUrl(opts: { baseUrl: string; sessionId: string; sessionToken: string; storageRef: string; fetchImpl: typeof fetch }): Promise<string> {\n const res = await opts.fetchImpl(`${opts.baseUrl}/chat/sessions/${opts.sessionId}/attachment-url`, {\n method: 'POST', credentials: 'omit',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${opts.sessionToken}` },\n body: JSON.stringify({ storageRef: opts.storageRef }),\n });\n // A 401 here means the session token is invalid/expired — surface a stable code so the client\n // can distinguish this from a transient failure (mirrors postMessage's 401 mapping).\n if (!res.ok) throw await asError(res, res.status === 401 ? 'session_expired' : undefined);\n return ((await res.json()) as { url: string }).url;\n}\n\n// Uploads a file directly to the presigned S3 URL. The URL is already absolute and fully signed —\n// NO baseUrl prefix, NO Authorization header (would break the signature), just a bare PUT with the\n// file's own content type (Task 4 dropped SSE from the presign so this needs no extra headers).\nexport async function uploadToPresigned(uploadUrl: string, file: File, fetchImpl: typeof fetch): Promise<void> {\n const res = await fetchImpl(uploadUrl, { method: 'PUT', body: file, headers: { 'Content-Type': file.type } });\n if (!res.ok) throw new ChatApiError(`attachment upload failed with HTTP ${res.status}`, res.status);\n}\n","import { openSession, postMessage, endSession, streamUrl, mintStreamTicket, postToolResult, presignAttachment, uploadToPresigned, getAttachmentUrl } from './transport';\nimport { ChatApiError } from './errors';\nimport type { ChatAttachmentDescriptor, ChatClientOptions, ChatEvent, OpenSessionResponse } from './protocol';\n\nexport interface ChatMessage { id: string; role: 'user' | 'assistant' | 'human'; text: string; streaming: boolean; attachments?: ChatAttachmentDescriptor[]; sources?: { id: string; title: string; snippet: string }[]; turnId?: string }\nexport type ChatClientState = 'idle' | 'opening' | 'ready' | 'ended' | 'error';\n// Handoff status of the session, driven by the backend's `state` SSE event (Phase 7). 'ai' = the\n// AI is answering (default/no handoff), 'awaiting_human' = a handoff was requested and no human\n// has taken over yet, 'human' = a human agent is answering.\nexport type HandoffState = 'ai' | 'awaiting_human' | 'human';\nexport type ChatClientEvent =\n | { type: 'state'; state: ChatClientState }\n | { type: 'messages'; messages: ChatMessage[] }\n | { type: 'error'; error: Error }\n | { type: 'agent'; agent: { id: string; name: string } }\n // Handoff status changed (Phase 7) - the widget uses this to show a status line.\n | { type: 'handoff'; state: HandoffState }\n // A human agent is (or stopped) typing in the console during a handoff (Phase 7 followups). The\n // widget uses this to show a transient \"agent is typing…\" affordance - never a message.\n | { type: 'agentTyping'; active: boolean };\nexport type ChatToolHandler = (args: Record<string, unknown>) => unknown | Promise<unknown>;\nexport interface ChatClient {\n start(): Promise<void>;\n sendMessage(text: string, files?: File[]): Promise<void>;\n end(): Promise<void>;\n getMessages(): ChatMessage[];\n getState(): ChatClientState;\n on(listener: (e: ChatClientEvent) => void): () => void;\n // Register browser-side tool handlers the server may call mid-conversation. Register BEFORE\n // start() — the handler names are sent as `clientTools` on session open so the server knows\n // which tools this session can execute.\n registerTools(handlers: Record<string, ChatToolHandler>): void;\n // Resolves a read-back URL for an already-uploaded attachment (e.g. an image thumbnail with no\n // local blob cached — a reconnect, or an `attachment` SSE echo). Requires start() to have been\n // called (a live session).\n getAttachmentUrl(storageRef: string): Promise<string>;\n}\n\nlet seq = 0;\nconst uid = (p: string) => `${p}_${Date.now().toString(36)}_${(seq++).toString(36)}`;\n\nexport function createChatClient(options: ChatClientOptions): ChatClient {\n // Native fetch must be invoked with `this === window`; the transport calls this as\n // `opts.fetchImpl(...)`, so a bare `globalThis.fetch` reference throws \"Illegal invocation\".\n // Bind the default to the global. A caller-supplied fetch is used as-is.\n const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n const ES = options.eventSource ?? globalThis.EventSource;\n // Mirrors the server's CHAT_ATTACHMENT_MAX_PER_MESSAGE default (apps/api/src/config/env.ts).\n const maxAttachments = options.maxAttachments ?? 4;\n // Mirrors the server's CHAT_ATTACHMENT_MAX_BYTES default (apps/api/src/config/env.ts). UX-only\n // fast pre-check - the server is authoritative (message-time HeadObject size enforcement).\n const maxAttachmentBytes = options.maxAttachmentBytes ?? 10_000_000;\n const listeners = new Set<(e: ChatClientEvent) => void>();\n let state: ChatClientState = 'idle';\n const messages: ChatMessage[] = [];\n let streamingId: string | null = null;\n let session: OpenSessionResponse | null = null;\n let es: EventSource | null = null;\n const seenTurnIds = new Set<string>();\n const seenCallIds = new Set<string>();\n let handoffState: HandoffState = 'ai';\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let reconnectAttempts = 0;\n let closed = false;\n const toolHandlers = new Map<string, ChatToolHandler>();\n const clearReconnect = () => { if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; } };\n\n const emit = (e: ChatClientEvent) => { for (const l of listeners) l(e); };\n const setState = (s: ChatClientState) => { state = s; emit({ type: 'state', state: s }); };\n const emitMessages = () => emit({ type: 'messages', messages: messages.slice() });\n\n const onEvent = (ev: ChatEvent) => {\n if (ev.type === 'token') {\n let m = streamingId ? messages.find((x) => x.id === streamingId) : undefined;\n if (!m) { m = { id: uid('m'), role: 'assistant', text: '', streaming: true }; messages.push(m); streamingId = m.id; }\n m.text += ev.text; emitMessages();\n } else if (ev.type === 'message') {\n if (seenTurnIds.has(ev.turnId)) {\n // Replay of an already-finalized turn (EventSource reconnect replays the session's\n // event buffer). Discard it, and drop any partial streaming bubble its replayed\n // tokens built up, without emitting a duplicate assistant message.\n if (streamingId) {\n const idx = messages.findIndex((x) => x.id === streamingId);\n if (idx !== -1) messages.splice(idx, 1);\n streamingId = null;\n emitMessages();\n }\n return;\n }\n seenTurnIds.add(ev.turnId);\n const m = streamingId ? messages.find((x) => x.id === streamingId) : undefined;\n // Keep the streamed text if the finalize carries none: a streaming turn's `message` event may\n // arrive with an empty `text` (the text was delivered via tokens), and overwriting with '' would\n // blank the just-streamed bubble.\n if (m) { m.text = ev.text || m.text; m.streaming = false; m.turnId = ev.turnId; } else { messages.push({ id: uid('m'), role: 'assistant', text: ev.text, streaming: false, turnId: ev.turnId }); }\n streamingId = null; emitMessages();\n } else if (ev.type === 'citations') {\n // Arrives AFTER `message` (streamingId already cleared) so the target message is located by\n // the turnId stamped above, not by streamingId. Ignore an unknown turnId (reconnect-safe: a\n // stale/duplicate citations replay for a turn we don't have never crashes or creates a bubble).\n const m = messages.find((x) => x.turnId === ev.turnId);\n if (m) { m.sources = ev.sources; emitMessages(); }\n } else if (ev.type === 'error') {\n emit({ type: 'error', error: new Error(ev.message) });\n } else if (ev.type === 'tool_call') {\n if (seenCallIds.has(ev.callId)) return; // replayed on EventSource reconnect — dispatch once\n seenCallIds.add(ev.callId);\n const handler = toolHandlers.get(ev.name);\n void (async () => {\n if (!session) return;\n const base = { baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, callId: ev.callId, fetchImpl };\n if (!handler) {\n await postToolResult({ ...base, ok: false, result: `no handler registered for ${ev.name}` });\n return;\n }\n try {\n const out = await handler(ev.args);\n await postToolResult({ ...base, ok: true, result: typeof out === 'string' ? out : JSON.stringify(out ?? { ok: true }) });\n } catch (err) {\n await postToolResult({ ...base, ok: false, result: (err as Error).message });\n }\n })();\n } else if (ev.type === 'attachment') {\n // The runtime re-publishes a visitor's message attachments over this event (Phase 5\n // follow-up) so a reconnecting client (buffer replay) or a future second viewer can render\n // them, now that a read-back URL exists (getAttachmentUrl / element.ts's lazy image src).\n // Hardened so it can never double-render on the SENDING client itself, which already rendered\n // these optimistically from its own sendMessage(): if any existing message already carries an\n // attachment with one of these storageRefs, the event is a stale/duplicate echo of something\n // already rendered — ignore it entirely instead of guessing which message to attach to (a\n // \"most recent attachment-less user message\" heuristic misattaches when a second image-first\n // message is sent before the echo of the first one arrives).\n const items = ev.items;\n const alreadyRendered = messages.some((m) => m.attachments?.some((a) => items.some((i) => i.storageRef === a.storageRef)));\n if (alreadyRendered) return;\n const target = [...messages].reverse().find((m) => m.role === 'user' && !m.attachments);\n if (target) target.attachments = items;\n else messages.push({ id: uid('u'), role: 'user', text: '', streaming: false, attachments: items });\n emitMessages();\n } else if (ev.type === 'human_message') {\n // A human agent's reply from the console inbox (Phase 7 handoff) - render as a distinct bubble.\n // Dedup by turnId (shared with the `message` branch's seenTurnIds) - EventSource reconnect\n // replays the session's buffered events, and human_message turnIds (newId('tn')) are distinct\n // from message turnIds, so sharing the Set is safe.\n if (seenTurnIds.has(ev.turnId)) return;\n seenTurnIds.add(ev.turnId);\n messages.push({ id: uid('m'), role: 'human', text: ev.text, streaming: false });\n emitMessages();\n } else if (ev.type === 'visitor_message') {\n // Echo of the visitor's own message, published so the console inbox sees it live. The widget\n // already rendered this optimistically in sendMessage() - ignore the echo entirely.\n } else if (ev.type === 'state') {\n // Handoff status transition (Phase 7): 'ai' | 'awaiting_human' | 'human'. Ignore any other/\n // future state string - forward-compat, no status line for an unrecognized value.\n if (ev.state === 'ai' || ev.state === 'awaiting_human' || ev.state === 'human') {\n handoffState = ev.state;\n emit({ type: 'handoff', state: handoffState });\n }\n } else if (ev.type === 'agent_typing') {\n // Transient signal only - never pushed as a message, never touches dedup/streaming state.\n emit({ type: 'agentTyping', active: !!ev.active });\n }\n // 'done' and any future unknown types are ignored (forward-compat).\n };\n\n // Tickets are single-use and short-lived: a fresh one must be minted for every (re)connect.\n // Native EventSource auto-reconnect would retry the SAME url whose ticket is already consumed\n // (→ 401 forever), so on error we close it ourselves and drive reconnection here instead.\n const openStream = async () => {\n if (!session || closed) return;\n es?.close();\n const { ticket } = await mintStreamTicket({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, fetchImpl });\n if (closed) return;\n es = new ES(streamUrl(options.baseUrl, session.sessionId, ticket));\n es.onopen = () => { reconnectAttempts = 0; };\n es.onmessage = (e: MessageEvent) => { try { onEvent(JSON.parse(e.data) as ChatEvent); } catch { /* ignore malformed */ } };\n es.onerror = () => { es?.close(); es = null; scheduleReconnect(); };\n };\n\n const scheduleReconnect = () => {\n if (closed) return;\n clearReconnect();\n const delay = Math.min(30_000, 500 * 2 ** reconnectAttempts);\n reconnectAttempts += 1;\n reconnectTimer = setTimeout(() => {\n openStream().catch((err) => {\n if (err instanceof ChatApiError && (err as ChatApiError).code === 'session_expired') {\n open().catch((e) => { emit({ type: 'error', error: e as Error }); scheduleReconnect(); });\n } else {\n scheduleReconnect();\n }\n });\n }, delay);\n };\n\n const open = async () => {\n session = await openSession({ baseUrl: options.baseUrl, apiKey: options.apiKey, agentId: options.agentId, user: options.user, clientTools: Array.from(toolHandlers.keys()), fetchImpl });\n emit({ type: 'agent', agent: session.agent });\n await openStream();\n };\n\n // Presign + PUT every file against the CURRENT session. Called from the main sendMessage path and,\n // after a session_expired reopen, from the retry — a storageRef presigned against the old\n // interactionId is rejected cross-session (403 attachment_cross_session) if reused post-reopen.\n const uploadFiles = async (files: File[]): Promise<ChatAttachmentDescriptor[]> => {\n return Promise.all(files.map(async (file): Promise<ChatAttachmentDescriptor> => {\n const { storageRef, uploadUrl } = await presignAttachment({ baseUrl: options.baseUrl, sessionId: session!.sessionId, sessionToken: session!.sessionToken, contentType: file.type, fetchImpl });\n await uploadToPresigned(uploadUrl, file, fetchImpl);\n return { storageRef, contentType: file.type, name: file.name };\n }));\n };\n\n return {\n getMessages: () => messages.slice(),\n getState: () => state,\n on(listener) { listeners.add(listener); return () => listeners.delete(listener); },\n registerTools(handlers) { for (const [name, fn] of Object.entries(handlers)) toolHandlers.set(name, fn); },\n async getAttachmentUrl(storageRef) {\n if (!session) throw new Error('call start() before getAttachmentUrl');\n return getAttachmentUrl({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, storageRef, fetchImpl });\n },\n async start() {\n // Ignore only while a connect is in flight or already live; allow a (re)start from idle, error,\n // or ended so a transient failure is recoverable (e.g. the widget's Retry button) without a page\n // reload. Reset closed/backoff so a restart genuinely reconnects.\n if (state === 'opening' || state === 'ready') return;\n closed = false;\n clearReconnect();\n reconnectAttempts = 0;\n setState('opening');\n try { await open(); setState('ready'); }\n catch (err) { setState('error'); emit({ type: 'error', error: err as Error }); }\n },\n async sendMessage(text, files) {\n if (!session) { emit({ type: 'error', error: new Error('call start() before sendMessage') }); return; }\n const fileList = files ?? [];\n if (fileList.length > maxAttachments) {\n emit({ type: 'error', error: new Error(`too many attachments: max ${maxAttachments} per message`) });\n return;\n }\n const oversized = fileList.find((f) => f.size > maxAttachmentBytes);\n if (oversized) {\n emit({ type: 'error', error: new Error(`attachment too large: ${oversized.name} exceeds ${maxAttachmentBytes} bytes`) });\n return;\n }\n // Upload every file BEFORE posting the message or pushing the optimistic bubble — a failed\n // upload must never leave a broken/partial message in the thread.\n let attachments: ChatAttachmentDescriptor[] = [];\n if (fileList.length > 0) {\n try {\n attachments = await uploadFiles(fileList);\n } catch (err) {\n emit({ type: 'error', error: err as Error });\n return;\n }\n }\n messages.push({ id: uid('u'), role: 'user', text, streaming: false, attachments: attachments.length > 0 ? attachments : undefined }); emitMessages();\n try {\n await postMessage({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, text, attachments, fetchImpl });\n } catch (err) {\n if (err instanceof ChatApiError && err.code === 'session_expired') {\n try {\n await open(); // fresh backend session, same UI thread\n // Re-upload against the NEW session — the old attachments' storageRefs are bound to the\n // stale interactionId and would 403 (attachment_cross_session) if re-posted as-is.\n const freshAttachments = fileList.length ? await uploadFiles(fileList) : [];\n await postMessage({ baseUrl: options.baseUrl, sessionId: session!.sessionId, sessionToken: session!.sessionToken, text, attachments: freshAttachments, fetchImpl });\n } catch (retryErr) {\n emit({ type: 'error', error: retryErr as Error });\n }\n } else { emit({ type: 'error', error: err as Error }); }\n }\n },\n async end() {\n closed = true; clearReconnect();\n if (session) await endSession({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, fetchImpl });\n es?.close(); es = null; setState('ended');\n },\n };\n}\n","import { marked } from 'marked';\nimport DOMPurify from 'dompurify';\n\n// GitHub-flavored markdown with single-newline line breaks (chat text rarely uses the two-space\n// hard-break convention). Set once at module load.\nmarked.setOptions({ gfm: true, breaks: true });\n\nlet hookInstalled = false;\nfunction installLinkHook(): void {\n if (hookInstalled) return;\n // Every surviving link opens in a new tab and drops referrer/opener; nofollow since the content is\n // model-generated and visitor-influenced.\n DOMPurify.addHook('afterSanitizeAttributes', (node) => {\n if (node.nodeName === 'A') {\n node.setAttribute('target', '_blank');\n node.setAttribute('rel', 'noopener noreferrer nofollow');\n }\n });\n hookInstalled = true;\n}\n\n// Tags/attributes a chat message may render. Everything else (script, style, iframe, event handlers,\n// inline styles, data-*) is stripped by DOMPurify. javascript:/data: URLs are rejected by the URI\n// regexp, so no link can execute script.\nconst ALLOWED_TAGS = ['p', 'br', 'strong', 'em', 'b', 'i', 'del', 's', 'code', 'pre', 'blockquote',\n 'ul', 'ol', 'li', 'a', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr',\n 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'span'];\nconst ALLOWED_ATTR = ['href', 'target', 'rel', 'class'];\n\n// Render a markdown string to sanitized HTML safe to inject into the widget's shadow DOM. The input\n// is model-generated (and a visitor can influence the conversation), so the output is ALWAYS run\n// through DOMPurify — marked itself passes raw HTML through untouched.\nexport function renderMarkdown(text: string): string {\n installLinkHook();\n const raw = marked.parse(text, { async: false }) as string;\n return DOMPurify.sanitize(raw, {\n ALLOWED_TAGS,\n ALLOWED_ATTR,\n ALLOW_DATA_ATTR: false,\n ALLOWED_URI_REGEXP: /^(?:https?:|mailto:)/i,\n });\n}\n","// Widget CSS, injected once into the shadow root. Ported from the Oyehello Chat Widget design.\n// Every token is namespaced --oc-* so a host page's own custom properties can't bleed across the\n// shadow boundary (custom properties inherit through it). The accent reads the public --oc-accent\n// override (default #096DD9). State is driven by classes on the `.oc` wrapper (open/max/emoji/\n// teaser/away/focus/ready/unread/ring), so the element toggles classes rather than restyling nodes.\nexport const STYLES = `\n :host {\n /* accent (consumer-overridable via --oc-accent) + its derivations */\n --oc-ac: var(--oc-accent, #096DD9);\n --oc-btn-rim: color-mix(in oklab, var(--oc-ac) 70%, black);\n --oc-btn-edge: 0 6px 16px -10px color-mix(in oklab, var(--oc-ac) 55%, transparent);\n --oc-danger: #D92D20;\n --oc-ease: cubic-bezier(0.16,1,0.3,1);\n --oc-bounce: cubic-bezier(0.18,0.89,0.32,1.13);\n --oc-mono: 'Geist Mono', ui-monospace, monospace;\n --oc-r-full: 999px;\n\n /* light palette (base) */\n --oc-bg: #FFFFFF; --oc-bg-sunk: #F6F8FB;\n --oc-fg: #0A0D12; --oc-fg-muted: rgba(10,13,18,0.66); --oc-fg-dim: rgba(10,13,18,0.44);\n --oc-border: rgba(9,13,20,0.10);\n --oc-accent-text: color-mix(in oklab, var(--oc-ac) 88%, black);\n --oc-tint-1: rgba(9,13,20,0.025); --oc-tint-2: rgba(9,13,20,0.04); --oc-tint-3: rgba(9,13,20,0.055);\n --oc-field-bg: #FFFFFF; --oc-field-border: rgba(9,13,20,0.22);\n --oc-glass-border: rgba(9,13,20,0.12);\n\n position: fixed; right: 24px; bottom: 24px; z-index: 2147483000;\n font-family: 'Geist', system-ui, -apple-system, 'Helvetica Neue', sans-serif;\n -webkit-font-smoothing: antialiased;\n }\n @media (prefers-color-scheme: dark) {\n :host(:not([theme=\"light\"])) {\n --oc-bg: #000000; --oc-bg-sunk: #000000;\n --oc-fg: #FFFFFF; --oc-fg-muted: rgba(255,255,255,0.68); --oc-fg-dim: rgba(255,255,255,0.42);\n --oc-border: rgba(255,255,255,0.09);\n --oc-accent-text: color-mix(in oklab, var(--oc-ac) 62%, white);\n --oc-tint-1: rgba(255,255,255,0.03); --oc-tint-2: rgba(255,255,255,0.05); --oc-tint-3: rgba(255,255,255,0.07);\n --oc-field-bg: rgba(255,255,255,0.045); --oc-field-border: rgba(255,255,255,0.20);\n --oc-glass-border: rgba(255,255,255,0.12);\n }\n }\n :host([theme=\"dark\"]) {\n --oc-bg: #000000; --oc-bg-sunk: #000000;\n --oc-fg: #FFFFFF; --oc-fg-muted: rgba(255,255,255,0.68); --oc-fg-dim: rgba(255,255,255,0.42);\n --oc-border: rgba(255,255,255,0.09);\n --oc-accent-text: color-mix(in oklab, var(--oc-ac) 62%, white);\n --oc-tint-1: rgba(255,255,255,0.03); --oc-tint-2: rgba(255,255,255,0.05); --oc-tint-3: rgba(255,255,255,0.07);\n --oc-field-bg: rgba(255,255,255,0.045); --oc-field-border: rgba(255,255,255,0.20);\n --oc-glass-border: rgba(255,255,255,0.12);\n }\n * { box-sizing: border-box; }\n button { font-family: inherit; }\n\n .oc { display: flex; flex-direction: column; align-items: flex-end; gap: 14px; }\n\n /* ── Launcher ─────────────────────────────────────────────────────────────── */\n .launcher {\n position: relative; flex: none; width: 46px; height: 46px; border-radius: var(--oc-r-full);\n border: 1px solid var(--oc-btn-rim); background: var(--oc-ac);\n box-shadow: 0 8px 22px -8px color-mix(in oklab, var(--oc-ac) 70%, transparent), 0 18px 48px -18px rgba(0,0,0,0.6);\n color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer;\n transition: transform .26s var(--oc-bounce), filter .2s var(--oc-ease); align-self: flex-end;\n }\n .launcher:hover { transform: scale(1.06); }\n .launcher:active { transform: scale(0.93); }\n .ring { pointer-events: none; position: absolute; inset: -1px; border-radius: var(--oc-r-full); border: 2px solid var(--oc-ac); opacity: 0; }\n .oc.ring:not(.open) .ring { animation: w-ring 2.4s ease-out 1.1s 3; }\n .ic-chat, .ic-close { position: absolute; display: flex; align-items: center; justify-content: center; transition: all .3s var(--oc-bounce); }\n .ic-chat { width: 28px; height: 28px; opacity: 1; transform: rotate(0) scale(1); }\n .ic-close { opacity: 0; transform: rotate(90deg) scale(0.6); }\n .oc.open .ic-chat { opacity: 0; transform: rotate(-90deg) scale(0.6); }\n .oc.open .ic-close { opacity: 1; transform: rotate(0) scale(1); }\n .badge {\n position: absolute; top: -2px; right: -2px; min-width: 17px; height: 17px; padding: 0 5px;\n border-radius: var(--oc-r-full); border: 2px solid var(--oc-bg-sunk); background: var(--oc-danger);\n color: #fff; font-family: var(--oc-mono); font-size: 10px; font-weight: 700;\n display: flex; align-items: center; justify-content: center; opacity: 0; transform: scale(0.4);\n transition: all .26s var(--oc-bounce);\n }\n .oc.unread:not(.open) .badge { opacity: 1; transform: scale(1); }\n\n /* ── Teaser ───────────────────────────────────────────────────────────────── */\n .teaser {\n position: absolute; right: 0; bottom: 60px; display: none; align-items: center; gap: 11px;\n opacity: 0; transform: translateY(8px) scale(0.94); pointer-events: none;\n transition: opacity .3s var(--oc-ease), transform .38s var(--oc-bounce);\n }\n .oc.has-teaser .teaser { display: flex; }\n .oc.teaser:not(.open) .teaser { opacity: 1; transform: none; pointer-events: auto; }\n .teaser-btn {\n max-width: 250px; display: flex; align-items: center; gap: 10px; padding: 11px 15px;\n border-radius: 16px 16px 5px 16px; border: 1px solid var(--oc-glass-border); background: var(--oc-bg);\n box-shadow: 0 10px 30px -14px rgba(0,0,0,0.5); color: var(--oc-fg); font-size: 13.5px; line-height: 1.45;\n text-align: left; cursor: pointer; transition: transform .2s var(--oc-ease);\n }\n .teaser-btn:hover { transform: translateY(-1px); }\n .teaser-btn .logo { flex: none; width: 24px; height: 24px; border-radius: 6px; overflow: hidden; color: var(--oc-ac); }\n .teaser-x {\n flex: none; width: 22px; height: 22px; border-radius: var(--oc-r-full); border: 1px solid var(--oc-border);\n background: var(--oc-bg); color: var(--oc-fg-dim); display: flex; align-items: center; justify-content: center; cursor: pointer;\n }\n .teaser-x:hover { color: var(--oc-fg); }\n\n /* ── Panel ────────────────────────────────────────────────────────────────── */\n .panel {\n position: relative; width: min(384px, calc(100vw - 40px)); height: min(560px, calc(100vh - 108px));\n display: flex; flex-direction: column; border-radius: 20px; border: 1px solid var(--oc-glass-border);\n background: var(--oc-bg); box-shadow: 0 12px 28px -12px rgba(0,0,0,0.28), 0 40px 90px -30px rgba(0,0,0,0.55);\n overflow: hidden; transform-origin: bottom right;\n opacity: 0; transform: translateY(16px) scale(0.94); pointer-events: none; visibility: hidden;\n transition: opacity .24s var(--oc-ease), transform .34s var(--oc-bounce), visibility .34s, width .3s var(--oc-ease), height .3s var(--oc-ease);\n }\n .oc.open .panel { opacity: 1; transform: none; pointer-events: auto; visibility: visible; }\n .oc.max .panel { width: min(720px, calc(100vw - 40px)); height: calc(100vh - 108px); }\n\n .hd { position: relative; flex: none; display: flex; align-items: center; gap: 12px; padding: 13px 14px 12px; background: var(--oc-ac); color: #fff; overflow: hidden; }\n .hd-grid { pointer-events: none; position: absolute; inset: 0; background-image: linear-gradient(90deg, rgba(255,255,255,0.11) 1px, transparent 1px), linear-gradient(180deg, rgba(255,255,255,0.11) 1px, transparent 1px); background-size: 26px 26px; }\n .hd .logo { position: relative; flex: none; width: 32px; height: 32px; border-radius: 7px; overflow: hidden; color: rgba(255,255,255,0.22); }\n .hd-txt { position: relative; flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }\n .hd-title { font-size: 14.5px; font-weight: 600; letter-spacing: -0.015em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .hd-status { display: flex; align-items: center; gap: 6px; font-size: 11.5px; opacity: 0.9; }\n .hd-status .dot { width: 6px; height: 6px; border-radius: var(--oc-r-full); background: #7BE3A6; flex: none; }\n .hd-status .t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .hd-btn { position: relative; flex: none; width: 28px; height: 28px; border-radius: 8px; border: none; background: rgba(255,255,255,0.16); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background .18s var(--oc-ease); }\n .hd-btn:hover { background: rgba(255,255,255,0.28); }\n .hd-btn .i { position: absolute; display: flex; transition: opacity .2s var(--oc-ease); }\n .i-expand { opacity: 1; } .i-shrink { opacity: 0; }\n .oc.max .i-expand { opacity: 0; } .oc.max .i-shrink { opacity: 1; }\n\n .err { flex: none; display: flex; align-items: center; gap: 8px; padding: 8px 16px; font-size: 12px; color: #fff; background: var(--oc-danger); }\n .err .retry { padding: 3px 10px; font-size: 11px; background: rgba(255,255,255,0.2); color: #fff; border: none; border-radius: 6px; cursor: pointer; }\n\n /* ── Message list ─────────────────────────────────────────────────────────── */\n .body { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 16px; padding: 16px 16px 26px; background: var(--oc-bg); scroll-behavior: smooth; }\n .turn { display: flex; flex-direction: column; gap: 6px; animation: w-in .42s var(--oc-ease) both; }\n .turn.bot { align-items: flex-start; } .turn.user { align-items: flex-end; }\n .b { font-size: 13.5px; line-height: 1.55; text-wrap: pretty; word-break: break-word; }\n .turn.bot .b { max-width: 86%; padding: 13px 15px; border-radius: 20px; background: var(--oc-tint-2); color: var(--oc-fg); }\n .turn.user .b { max-width: 82%; padding: 11px 15px; border-radius: var(--oc-r-full); background: var(--oc-ac); color: #fff; }\n .turn.human .b { max-width: 86%; padding: 13px 15px; border-radius: 20px; background: color-mix(in oklab, var(--oc-ac) 16%, transparent); color: var(--oc-fg); }\n .src { display: inline-flex; align-items: center; gap: 7px; padding: 5px 10px 5px 8px; border-radius: var(--oc-r-full); border: 1px solid var(--oc-border); background: var(--oc-tint-1); max-width: 100%; }\n .src .t { min-width: 0; font-size: 11.5px; color: var(--oc-fg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .byline { display: flex; align-items: center; gap: 6px; padding: 0 4px; font-size: 11.5px; color: var(--oc-fg-dim); }\n .human-label { font-size: 11px; font-weight: 600; opacity: .7; margin-bottom: 2px; }\n\n /* markdown inside a bot bubble */\n .md > :first-child { margin-top: 0; } .md > :last-child { margin-bottom: 0; }\n .md p { margin: 0 0 8px; } .md ul, .md ol { margin: 0 0 8px; padding-left: 20px; } .md li { margin: 2px 0; }\n .md a { color: var(--oc-accent-text); text-decoration: underline; text-underline-offset: 2px; }\n .md code { font-family: var(--oc-mono); font-size: 12.5px; background: var(--oc-tint-3); padding: 1px 5px; border-radius: 5px; }\n .md pre { background: color-mix(in oklab, var(--oc-fg) 10%, transparent); padding: 10px 12px; border-radius: 8px; overflow-x: auto; margin: 0 0 8px; }\n .md pre code { background: none; padding: 0; }\n .md blockquote { margin: 0 0 8px; padding-left: 10px; border-left: 3px solid var(--oc-border); color: var(--oc-fg-muted); }\n .md h1, .md h2, .md h3, .md h4 { margin: 8px 0 6px; font-size: 15px; }\n .md table { border-collapse: collapse; font-size: 13px; margin: 0 0 8px; display: block; overflow-x: auto; }\n .md th, .md td { border: 1px solid var(--oc-border); padding: 4px 8px; }\n .att-thumb { display: block; max-width: 180px; max-height: 180px; border-radius: 8px; margin-bottom: 6px; }\n .att-chip { display: inline-block; font-size: 12px; background: var(--oc-tint-3); border-radius: 6px; padding: 2px 8px; margin: 0 0 6px; }\n .turn.user .att-chip { background: rgba(255,255,255,0.25); }\n\n .typing { align-self: flex-start; display: flex; align-items: center; gap: 5px; padding: 13px 16px; border-radius: 20px; background: var(--oc-tint-2); animation: w-in .3s var(--oc-ease) both; }\n .typing span { width: 6px; height: 6px; border-radius: var(--oc-r-full); background: var(--oc-fg-muted); animation: w-dot 1.2s ease-in-out infinite; }\n .typing span:nth-child(2) { animation-delay: .15s; } .typing span:nth-child(3) { animation-delay: .3s; }\n\n .chips { display: flex; flex-wrap: wrap; gap: 7px; padding-top: 2px; animation: w-in .42s var(--oc-ease) both; animation-delay: .3s; }\n .chip { padding: 8px 13px; border-radius: var(--oc-r-full); border: 1px solid color-mix(in oklab, var(--oc-ac) 34%, transparent); background: color-mix(in oklab, var(--oc-ac) 10%, transparent); color: var(--oc-accent-text); font-size: 12px; font-weight: 500; cursor: pointer; white-space: nowrap; transition: all .18s var(--oc-ease); }\n .chip:hover { background: color-mix(in oklab, var(--oc-ac) 18%, transparent); }\n\n /* ── Jump to latest ───────────────────────────────────────────────────────── */\n .jump-wrap { position: relative; flex: none; height: 0; z-index: 2; display: flex; justify-content: center; }\n .jump { position: absolute; bottom: 8px; width: 34px; height: 34px; border-radius: var(--oc-r-full); border: 1px solid var(--oc-border); background: var(--oc-bg); box-shadow: 0 8px 20px -10px rgba(0,0,0,0.5); color: var(--oc-fg-muted); display: flex; align-items: center; justify-content: center; cursor: pointer; opacity: 0; transform: translateY(6px) scale(0.8); pointer-events: none; transition: all .22s var(--oc-ease); }\n .oc.away .jump { opacity: 1; transform: none; pointer-events: auto; }\n .jump:hover { color: var(--oc-fg); border-color: var(--oc-fg-dim); }\n\n /* ── Composer ─────────────────────────────────────────────────────────────── */\n .composer { flex: none; display: flex; flex-direction: column; gap: 9px; padding: 12px 14px 13px; background: var(--oc-bg); }\n .field { display: flex; flex-direction: column; gap: 11px; padding: 13px 14px 11px; border-radius: 18px; border: 1px solid var(--oc-field-border); background: var(--oc-field-bg); transition: border-color .18s var(--oc-ease); }\n .oc.focus .field { border-color: var(--oc-ac); }\n .input { width: 100%; border: none; background: transparent; color: var(--oc-fg); font-size: 13.5px; line-height: 1.4; outline: none; padding: 0; resize: none; max-height: 108px; font-family: inherit; }\n .input::placeholder { color: var(--oc-fg-dim); }\n .acts { display: flex; align-items: center; gap: 16px; }\n .act { flex: none; display: flex; border: none; background: transparent; padding: 4px; margin: -4px; color: var(--oc-fg-dim); cursor: pointer; transition: color .18s var(--oc-ease); }\n .act:hover { color: var(--oc-fg-muted); }\n .oc.emoji .act.emoji-btn { color: var(--oc-accent-text); }\n .send { flex: none; margin-left: auto; width: 34px; height: 34px; border-radius: var(--oc-r-full); border: 1px solid var(--oc-border); background: var(--oc-tint-3); color: var(--oc-fg-dim); box-shadow: none; display: flex; align-items: center; justify-content: center; cursor: default; transition: all .22s var(--oc-ease); }\n .oc.ready .send { border-color: var(--oc-btn-rim); background: var(--oc-ac); color: #fff; box-shadow: var(--oc-btn-edge); cursor: pointer; }\n .oc.ready .send:hover { filter: brightness(1.1); }\n .send:active { transform: scale(0.92); }\n\n .foot { position: relative; display: none; text-align: center; font-size: 11.5px; line-height: 1.5; color: var(--oc-fg-dim); }\n .oc.has-privacy .foot { display: block; }\n .foot .priv { color: var(--oc-fg-muted); text-decoration: underline; text-underline-offset: 2px; cursor: default; }\n .foot .tip { position: absolute; left: 0; right: 0; bottom: 16px; padding-bottom: 8px; z-index: 7; display: flex; justify-content: flex-end; pointer-events: none; opacity: 0; transition: opacity .18s var(--oc-ease); }\n .oc.max .foot .tip { right: 188px; }\n .foot:hover .tip { opacity: 1; }\n .foot .tip-card { max-width: 100%; width: 262px; padding: 13px 15px; border-radius: 14px; border: 1px solid var(--oc-border); background: var(--oc-bg); box-shadow: 0 8px 22px -12px rgba(0,0,0,0.32); text-align: left; font-size: 11.5px; line-height: 1.55; color: var(--oc-fg-muted); text-wrap: pretty; transform: translateY(6px); transition: transform .24s var(--oc-bounce); }\n .foot:hover .tip-card { transform: none; }\n .foot .tip-card a { color: var(--oc-fg); text-decoration: underline; text-underline-offset: 2px; }\n\n /* ── Emoji picker ─────────────────────────────────────────────────────────── */\n .emoji-scrim { position: absolute; inset: 0; z-index: 3; display: none; }\n .oc.emoji .emoji-scrim { display: block; }\n .emoji-panel { position: absolute; left: 10px; right: 10px; bottom: 96px; z-index: 4; max-height: min(340px, 58%); display: flex; flex-direction: column; border-radius: 18px; border: 1px solid var(--oc-border); background: var(--oc-bg); box-shadow: 0 18px 46px -18px rgba(0,0,0,0.6); overflow: hidden; opacity: 0; transform: translateY(10px) scale(0.96); transform-origin: bottom center; pointer-events: none; visibility: hidden; transition: opacity .18s var(--oc-ease), transform .26s var(--oc-bounce), visibility .26s; }\n .oc.emoji .emoji-panel { opacity: 1; transform: none; pointer-events: auto; visibility: visible; }\n .emoji-search { flex: none; display: flex; align-items: center; gap: 11px; padding: 13px 16px; border-bottom: 1px solid var(--oc-border); color: var(--oc-fg-dim); }\n .emoji-search input { flex: 1 1 auto; min-width: 0; border: none; background: transparent; color: var(--oc-fg); font-size: 14.5px; outline: none; font-family: inherit; }\n .emoji-search input::placeholder { color: var(--oc-fg-dim); }\n .emoji-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; padding: 12px 14px 16px; }\n .emoji-grp { display: flex; flex-direction: column; gap: 6px; }\n .emoji-grp + .emoji-grp { padding-top: 8px; }\n .emoji-grp-name { font-family: var(--oc-mono); font-size: 9.5px; font-weight: 600; letter-spacing: 0.15em; text-transform: uppercase; color: var(--oc-fg-dim); }\n .emoji-grid { display: grid; grid-template-columns: repeat(7, minmax(0,1fr)); gap: 2px; }\n .emoji-grid button { display: flex; align-items: center; justify-content: center; height: 34px; border-radius: 8px; border: none; background: transparent; font-size: 20px; line-height: 1; cursor: pointer; transition: background .14s var(--oc-ease); }\n .emoji-grid button:hover { background: var(--oc-tint-3); }\n .emoji-empty { display: none; flex-direction: column; align-items: center; gap: 5px; padding: 26px 10px; text-align: center; }\n .emoji-empty .h { font-size: 14px; color: var(--oc-fg); } .emoji-empty .s { font-size: 12.5px; color: var(--oc-fg-dim); }\n\n @media (max-width: 480px) {\n :host { right: 0; bottom: 0; }\n .oc { padding: 0 16px 16px; }\n .panel { position: fixed; inset: 0; width: 100vw; height: 100dvh; border-radius: 0; }\n .oc.max .panel { width: 100vw; height: 100dvh; }\n }\n @media (prefers-reduced-motion: reduce) {\n .launcher, .panel, .teaser, .turn, .jump, .emoji-panel { transition: none; animation: none; }\n .ring { animation: none; } .body { scroll-behavior: auto; }\n }\n\n @keyframes w-in { from { opacity: 0; transform: translateY(10px) scale(0.97); } to { opacity: 1; transform: none; } }\n @keyframes w-dot { 0%,60%,100% { transform: translateY(0); opacity: .45; } 30% { transform: translateY(-4px); opacity: 1; } }\n @keyframes w-ring { 0% { transform: scale(1); opacity: .5; } 70%,100% { transform: scale(1.7); opacity: 0; } }\n`;\n","// SVG markup used across the widget, extracted from the design. Kept as strings so the element can\n// inline them into its shadow DOM without a dependency.\n\n// The OyeHello brand mark. `rectFill` colors the rounded-square backdrop; the glyph is always white.\nexport const logoMark = (rectFill: string) =>\n `<svg viewBox=\"0 0 1032 1024\" fill=\"none\" style=\"display:block;width:100%;height:100%\"><rect x=\"4\" width=\"1024\" height=\"1024\" rx=\"150\" fill=\"${rectFill}\"></rect><path d=\"M430.924 831.644C270.203 859.983 138.14 760.606 111.329 608.551C84.5174 456.497 174.627 317.945 335.348 289.605C496.068 261.266 628.131 360.643 654.943 512.698C681.754 664.752 591.644 803.304 430.924 831.644ZM406.613 693.77C488.549 679.323 518.727 615.513 505.252 539.092C491.777 462.671 441.594 413.031 359.658 427.478C277.722 441.926 247.544 505.736 261.02 582.157C274.495 658.578 324.677 708.218 406.613 693.77ZM870.337 558.389L744.281 580.616C727.055 482.923 674.565 369.515 652.06 241.884L841.143 208.543C863.509 335.387 853.111 460.696 870.337 558.389ZM910.583 740.568L768.771 765.573L745.016 630.852L886.828 605.846L910.583 740.568Z\" fill=\"#fff\"></path></svg>`;\n\nconst stroke = (w: number, path: string, size = 24) =>\n `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"${w}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"display:block;flex:none\">${path}</svg>`;\n\nexport const ICON = {\n close: (size = 19) => stroke(2.4, '<path d=\"M18 6 6 18M6 6l12 12\"/>', size),\n minus: stroke(2, '<path d=\"M6 12h12\"/>', 15),\n expand: stroke(2, '<path d=\"M15 4h5v5M20 4l-6.5 6.5M9 20H4v-5M4 20l6.5-6.5\"/>', 15),\n shrink: stroke(2, '<path d=\"M20 9h-5V4M15 9l5.5-5.5M4 15h5v5M9 15l-5.5 5.5\"/>', 15),\n chevronDown: stroke(2.1, '<path d=\"m6 9 6 6 6-6\"/>', 16),\n send: stroke(2.2, '<path d=\"M12 19V5M6 11l6-6 6 6\"/>', 16),\n paperclip: stroke(1.7, '<path d=\"M21 11.5 12.5 20a5.5 5.5 0 0 1-7.8-7.8l8.5-8.5a3.7 3.7 0 0 1 5.2 5.2l-8.5 8.5a1.8 1.8 0 0 1-2.6-2.6l7.9-7.8\"/>', 17),\n emoji: stroke(1.7, '<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M8.5 14.5a4.5 4.5 0 0 0 7 0M9 9.5h.01M15 9.5h.01\"/>', 17),\n mic: stroke(1.7, '<rect x=\"9\" y=\"3\" width=\"6\" height=\"11\" rx=\"3\"/><path d=\"M5 11a7 7 0 0 0 14 0M12 18v3\"/>', 17),\n search: stroke(1.9, '<circle cx=\"11\" cy=\"11\" r=\"7.5\"/><path d=\"m21 21-4.3-4.3\"/>', 17),\n clear: stroke(2.2, '<path d=\"M18 6 6 18M6 6l12 12\"/>', 15),\n // Two-page \"source\" glyph for citation chips.\n book: `<svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"display:block;flex:none;color:var(--oc-accent-text)\"><path d=\"M3 5.5A2.5 2.5 0 0 1 5.5 3H11v18H5.5A2.5 2.5 0 0 1 3 18.5Z\"/><path d=\"M21 5.5A2.5 2.5 0 0 0 18.5 3H13v18h5.5a2.5 2.5 0 0 0 2.5-2.5Z\"/></svg>`,\n teaserDismiss: stroke(2.4, '<path d=\"M18 6 6 18M6 6l12 12\"/>', 12),\n};\n","// Emoji catalogue + search for the composer's picker, ported from the design. Each entry is\n// [character, keyword]; the keyword is what the search box matches against.\nexport interface EmojiGroup { name: string; items: { ch: string; name: string }[] }\n\nconst CATS: { name: string; items: [string, string][] }[] = [\n { name: 'Frequently used', items: [\n ['👍', 'thumbs up'], ['🙏', 'thanks'], ['👋', 'wave'], ['✅', 'done'], ['📞', 'call'], ['😊', 'smile'], ['❤️', 'heart'],\n ] },\n { name: 'Smileys and emotion', items: [\n ['😀', 'grinning'], ['😃', 'smiley'], ['😄', 'grin'], ['😁', 'beaming'], ['😆', 'squinting'], ['😅', 'relief'], ['🤣', 'rolling'],\n ['😂', 'tears of joy'], ['🙂', 'slightly smiling'], ['🙃', 'upside down'], ['😉', 'wink'], ['😇', 'halo'], ['🥰', 'smiling hearts'], ['😍', 'heart eyes'],\n ['😘', 'kiss'], ['😋', 'yum'], ['🤔', 'thinking'], ['🤨', 'raised brow'], ['😐', 'neutral'], ['🙄', 'eye roll'], ['😬', 'grimace'],\n ['😥', 'sad'], ['😢', 'crying'], ['😭', 'sobbing'], ['😠', 'angry'], ['😳', 'flushed'], ['🤩', 'star struck'], ['😴', 'sleeping'],\n ] },\n { name: 'Gestures', items: [\n ['👎', 'thumbs down'], ['👏', 'clap'], ['🙌', 'raised hands'], ['🤝', 'handshake'], ['👌', 'ok hand'], ['✌️', 'victory'], ['💪', 'strong'],\n ['👀', 'eyes'], ['🧠', 'brain'], ['🤟', 'love you'], ['☝️', 'point up'], ['👇', 'point down'], ['🤚', 'raised back'], ['🤞', 'fingers crossed'],\n ] },\n { name: 'Work and travel', items: [\n ['📅', 'calendar'], ['📄', 'document'], ['💰', 'money'], ['📊', 'chart'], ['📦', 'package'], ['🏥', 'hospital'], ['🏦', 'bank'],\n ['🚚', 'truck'], ['✈️', 'plane'], ['📱', 'phone'], ['💻', 'laptop'], ['🔍', 'search'], ['📌', 'pin'], ['🔔', 'bell'],\n ] },\n { name: 'Symbols', items: [\n ['🔥', 'fire'], ['✨', 'sparkles'], ['🎉', 'celebrate'], ['💯', 'hundred'], ['⚠️', 'warning'], ['❌', 'cross'], ['⭐', 'star'],\n ['🚀', 'launch'], ['💚', 'green heart'], ['💙', 'blue heart'], ['🕒', 'clock'], ['💡', 'idea'], ['🔒', 'lock'], ['🎯', 'target'],\n ] },\n];\n\nconst toGroup = (name: string, items: [string, string][]): EmojiGroup => ({\n name,\n items: items.map(([ch, kw]) => ({ ch, name: kw })),\n});\n\n// No query → all categories. With a query → a single group of de-duped keyword matches (mirrors the\n// design's search behaviour), or an empty array when nothing matches (the caller shows an empty state).\nexport function emojiGroups(query: string): EmojiGroup[] {\n const q = query.trim().toLowerCase();\n if (!q) return CATS.map((c) => toGroup(c.name, c.items));\n const hits: [string, string][] = [];\n for (const c of CATS) for (const e of c.items) {\n if (e[1].indexOf(q) >= 0 && !hits.some((h) => h[0] === e[0])) hits.push(e);\n }\n if (!hits.length) return [];\n return [toGroup(`${hits.length} result${hits.length === 1 ? '' : 's'}`, hits)];\n}\n","import { createChatClient, type ChatClient, type ChatClientEvent, type ChatMessage, type ChatClientState, type ChatToolHandler, type HandoffState } from './client';\nimport type { ChatAttachmentDescriptor } from './protocol';\nimport { renderMarkdown } from './markdown';\nimport { STYLES } from './styles';\nimport { ICON, logoMark } from './icons';\nimport { emojiGroups } from './emoji';\n\nconst AGENT_TYPING_TEXT = 'The agent is typing…';\nconst DEFAULT_STATUS = 'Replies in a few seconds';\nconst ATTACHMENT_ACCEPT = 'image/*,application/pdf,text/plain,text/csv';\n// Distance (px) from the bottom past which we treat the reader as scrolled-up (\"away\").\nconst AWAY_THRESHOLD = 60;\n\nconst HANDOFF_STATUS: Record<HandoffState, string | null> = {\n ai: null,\n awaiting_human: 'Connecting you to a person…',\n human: \"You're chatting with a person\",\n};\n\nexport class OyehelloChatElement extends HTMLElement {\n static observedAttributes = ['api-key', 'agent-id', 'base-url', 'title', 'theme'];\n\n // ── live client state ──\n private client: ChatClient | null = null;\n private off: (() => void) | null = null;\n private messages: ChatMessage[] = [];\n private state: ChatClientState = 'idle';\n private agentName: string | null = null;\n private handoffState: HandoffState = 'ai';\n private agentTyping = false;\n private lastError: string | null = null;\n private pendingTools: Record<string, ChatToolHandler> = {};\n private pendingFiles: File[] = [];\n private imagePreviewCache = new Map<string, string>();\n private resolvedUrlCache = new Map<string, string>();\n private mdCache = new Map<string, string>();\n private receivedAt = new Map<string, number>();\n\n // ── widget UI state ──\n private uiOpen = false;\n private started = false;\n private uiMax = false;\n private emojiOpen = false;\n private emojiQuery = '';\n private away = false; // reader scrolled up\n private unseen = 0;\n private focused = false;\n private teaserActive = false;\n private renderedCount = 0;\n private renderedBotFinal = 0;\n private timers: ReturnType<typeof setTimeout>[] = [];\n\n // ── shadow refs ──\n private oc!: HTMLElement;\n private bodyEl!: HTMLElement;\n private textareaEl!: HTMLTextAreaElement;\n private fileEl!: HTMLInputElement;\n private titleEl!: HTMLElement;\n private statusEl!: HTMLElement;\n private errEl!: HTMLElement;\n private emojiListEl!: HTMLElement;\n private emojiSearchEl!: HTMLInputElement;\n\n connectedCallback() {\n if (!this.shadowRoot) this.attachShadow({ mode: 'open' });\n const apiKey = this.getAttribute('api-key');\n const agentId = this.getAttribute('agent-id');\n const baseUrl = this.getAttribute('base-url');\n if (!apiKey || !agentId || !baseUrl) { this.renderError('oyehello-chat: api-key, agent-id and base-url are required'); return; }\n this.client = createChatClient({ apiKey, agentId, baseUrl });\n if (Object.keys(this.pendingTools).length > 0) { this.client.registerTools(this.pendingTools); this.pendingTools = {}; }\n this.off = this.client.on((e) => this.onClientEvent(e));\n this.renderShell();\n this.renderMessages();\n this.updateHeader();\n this.updateStatus();\n this.updateClasses();\n\n let wasOpen = false;\n try { wasOpen = sessionStorage.getItem(this.key('open')) === '1'; } catch { /* blocked */ }\n if (wasOpen) { this.openPanel(); return; }\n\n // Launcher ring (a few pulses to draw the eye), then a teaser nudge if configured + not dismissed.\n this.updateClasses(true);\n this.timers.push(setTimeout(() => { this.oc?.classList.remove('ring'); }, 6000));\n const teaserText = this.getAttribute('teaser');\n let dismissed = false;\n try { dismissed = sessionStorage.getItem(this.key('teaser')) === '0'; } catch { /* ignore */ }\n if (teaserText && !dismissed) {\n this.timers.push(setTimeout(() => { if (!this.uiOpen) { this.teaserActive = true; this.updateClasses(); } }, 1400));\n }\n }\n\n disconnectedCallback() {\n this.off?.(); void this.client?.end();\n for (const t of this.timers) clearTimeout(t);\n for (const url of this.imagePreviewCache.values()) { if (typeof URL.revokeObjectURL === 'function') URL.revokeObjectURL(url); }\n this.imagePreviewCache.clear();\n }\n\n registerTools(handlers: Record<string, ChatToolHandler>) {\n if (this.client) this.client.registerTools(handlers);\n else Object.assign(this.pendingTools, handlers);\n }\n\n private key(k: string) { return `oyehello-chat:${k}:${this.getAttribute('agent-id') ?? ''}`; }\n private get suggestions(): string[] {\n return (this.getAttribute('suggestions') ?? '').split(',').map((s) => s.trim()).filter(Boolean);\n }\n\n // ── Shell (built once) ─────────────────────────────────────────────────────────────────────────\n private renderShell() {\n const root = this.shadowRoot!;\n const hasTeaser = !!this.getAttribute('teaser');\n const hasPrivacy = !!this.getAttribute('privacy-url');\n const teaserText = this.getAttribute('teaser') ?? '';\n root.innerHTML = `\n <style>${STYLES}</style>\n <div class=\"oc${hasTeaser ? ' has-teaser' : ''}${hasPrivacy ? ' has-privacy' : ''}\">\n <div class=\"panel\" role=\"dialog\" aria-label=\"Chat\">\n <div class=\"hd\">\n <span class=\"hd-grid\"></span>\n <span class=\"logo\">${logoMark('currentColor')}</span>\n <span class=\"hd-txt\"><span class=\"hd-title\">Chat</span><span class=\"hd-status\"><span class=\"dot\"></span><span class=\"t\"></span></span></span>\n <button type=\"button\" class=\"hd-btn max\" aria-label=\"Expand\"><span class=\"i i-expand\">${ICON.expand}</span><span class=\"i i-shrink\">${ICON.shrink}</span></button>\n <button type=\"button\" class=\"hd-btn min\" aria-label=\"Minimise\">${ICON.minus}</button>\n </div>\n <div class=\"err\" hidden></div>\n <div class=\"body\"></div>\n <span class=\"emoji-scrim\"></span>\n <div class=\"emoji-panel\">\n <div class=\"emoji-search\">${ICON.search}<input type=\"text\" placeholder=\"Search emoji…\" aria-label=\"Search emoji\" /></div>\n <div class=\"emoji-list\"></div>\n </div>\n <div class=\"jump-wrap\"><button type=\"button\" class=\"jump\" aria-label=\"Jump to latest\">${ICON.chevronDown}</button></div>\n <div class=\"composer\">\n <form class=\"field\">\n <textarea class=\"input\" rows=\"1\" aria-label=\"message\" placeholder=\"Ask a question…\"></textarea>\n <div class=\"acts\">\n <button type=\"button\" class=\"act attach\" aria-label=\"Attach a file\">${ICON.paperclip}</button>\n <input type=\"file\" accept=\"${ATTACHMENT_ACCEPT}\" multiple hidden />\n <button type=\"button\" class=\"act emoji-btn\" aria-label=\"Insert emoji\">${ICON.emoji}</button>\n <button type=\"button\" class=\"act mic\" aria-label=\"Send a voice note\">${ICON.mic}</button>\n <button type=\"submit\" class=\"send\" aria-label=\"Send\">${ICON.send}</button>\n </div>\n </form>\n <div class=\"foot\">\n <span>By chatting with us, you agree to our </span><span class=\"priv\">Privacy Policy</span>\n <span class=\"tip\"><span class=\"tip-card\">By chatting with us, you agree to the monitoring and recording of this chat to deliver our services and processing of your personal data in accordance with our Privacy Policy. <a href=\"${this.escapeAttr(this.getAttribute('privacy-url') ?? '#')}\" target=\"_blank\" rel=\"noopener noreferrer\">See our Privacy Policy</a>.</span></span>\n </div>\n </div>\n </div>\n\n <div class=\"teaser\">\n <button type=\"button\" class=\"teaser-btn\"><span class=\"logo\">${logoMark('currentColor')}</span><span>${escapeHtml(teaserText)}</span></button>\n <button type=\"button\" class=\"teaser-x\" aria-label=\"Dismiss\">${ICON.teaserDismiss}</button>\n </div>\n\n <button type=\"button\" class=\"launcher\" aria-label=\"Open chat\">\n <span class=\"ring\"></span>\n <span class=\"ic-chat\">${logoMark('var(--oc-ac)')}</span>\n <span class=\"ic-close\">${ICON.close(19)}</span>\n <span class=\"badge\"></span>\n </button>\n </div>`;\n\n this.oc = root.querySelector('.oc')!;\n this.bodyEl = root.querySelector('.body')!;\n this.textareaEl = root.querySelector('textarea.input')!;\n this.fileEl = root.querySelector('input[type=\"file\"]')!;\n this.titleEl = root.querySelector('.hd-title')!;\n this.statusEl = root.querySelector('.hd-status .t')!;\n this.errEl = root.querySelector('.err')!;\n this.emojiListEl = root.querySelector('.emoji-list')!;\n this.emojiSearchEl = root.querySelector('.emoji-search input')!;\n\n root.querySelector('.launcher')!.addEventListener('click', () => this.toggle());\n root.querySelector('.hd-btn.min')!.addEventListener('click', () => this.closePanel());\n root.querySelector('.hd-btn.max')!.addEventListener('click', () => { this.uiMax = !this.uiMax; this.updateClasses(); });\n root.querySelector('.teaser-btn')!.addEventListener('click', () => this.openPanel());\n root.querySelector('.teaser-x')!.addEventListener('click', () => this.dismissTeaser());\n root.querySelector('.jump')!.addEventListener('click', () => this.scrollToBottom());\n root.querySelector('.attach')!.addEventListener('click', () => this.fileEl.click());\n this.fileEl.addEventListener('change', () => { this.pendingFiles = this.fileEl.files ? Array.from(this.fileEl.files) : []; });\n root.querySelector('.emoji-btn')!.addEventListener('click', () => this.toggleEmoji());\n root.querySelector('.emoji-scrim')!.addEventListener('click', () => this.closeEmoji());\n this.emojiSearchEl.addEventListener('input', () => { this.emojiQuery = this.emojiSearchEl.value; this.renderEmoji(); });\n this.bodyEl.addEventListener('scroll', () => this.onScroll());\n root.querySelector('form.field')!.addEventListener('submit', (e) => { e.preventDefault(); this.doSend(); });\n this.textareaEl.addEventListener('input', () => { this.autoGrow(); this.updateClasses(); });\n this.textareaEl.addEventListener('focus', () => { this.focused = true; this.updateClasses(); });\n this.textareaEl.addEventListener('blur', () => { this.focused = false; this.updateClasses(); });\n this.textareaEl.addEventListener('keydown', (e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey && !e.isComposing) { e.preventDefault(); this.doSend(); }\n if (e.key === 'Escape') { if (this.emojiOpen) this.closeEmoji(); else this.closePanel(); }\n });\n }\n\n private renderError(msg: string) {\n if (!this.shadowRoot) this.attachShadow({ mode: 'open' });\n // eslint-disable-next-line no-console\n console.error(msg);\n this.shadowRoot!.innerHTML = `<div style=\"position:fixed;right:16px;bottom:16px;color:#b91c1c;font:12px system-ui;background:#fef2f2;border:1px solid #fecaca;padding:8px 12px;border-radius:8px\">${escapeHtml(msg)}</div>`;\n }\n\n // ── State-class sync ──────────────────────────────────────────────────────────────────────────\n private updateClasses(initialRing = false) {\n if (!this.oc) return;\n const c = this.oc.classList;\n c.toggle('open', this.uiOpen);\n c.toggle('max', this.uiMax);\n c.toggle('emoji', this.emojiOpen);\n c.toggle('teaser', this.teaserActive);\n c.toggle('away', this.away);\n c.toggle('focus', this.focused);\n c.toggle('ready', (this.textareaEl?.value.trim().length ?? 0) > 0);\n c.toggle('unread', this.unseen > 0);\n if (initialRing) c.add('ring');\n const badge = this.oc.querySelector('.badge');\n if (badge) badge.textContent = this.unseen > 9 ? '9+' : String(this.unseen);\n const launcher = this.oc.querySelector('.launcher');\n if (launcher) launcher.setAttribute('aria-label', this.uiOpen ? 'Close chat' : 'Open chat');\n }\n\n // ── Open / close ───────────────────────────────────────────────────────────────────────────────\n private toggle() { this.uiOpen ? this.closePanel() : this.openPanel(); }\n private openPanel() {\n this.uiOpen = true; this.teaserActive = false; this.unseen = 0;\n try { sessionStorage.setItem(this.key('open'), '1'); } catch { /* ignore */ }\n if (!this.started && this.client) { this.started = true; void this.client.start(); }\n this.updateClasses();\n this.renderMessages();\n this.scrollToBottom();\n if (!this.textareaEl.disabled) setTimeout(() => this.textareaEl.focus(), 60);\n }\n private closePanel() {\n this.uiOpen = false; this.uiMax = false; this.emojiOpen = false;\n try { sessionStorage.setItem(this.key('open'), '0'); } catch { /* ignore */ }\n this.updateClasses();\n }\n private dismissTeaser() {\n this.teaserActive = false;\n try { sessionStorage.setItem(this.key('teaser'), '0'); } catch { /* ignore */ }\n this.updateClasses();\n }\n\n // ── Client events ─────────────────────────────────────────────────────────────────────────────\n private onClientEvent(e: ChatClientEvent) {\n if (e.type === 'messages') this.messages = e.messages;\n else if (e.type === 'state') { this.state = e.state; if (e.state === 'ready' || e.state === 'opening') this.lastError = null; }\n else if (e.type === 'agent') { this.agentName = e.agent.name; this.updateHeader(); }\n else if (e.type === 'handoff') this.handoffState = e.state;\n else if (e.type === 'agentTyping') this.agentTyping = e.active;\n else if (e.type === 'error') this.lastError = e.error.message;\n this.updateStatus();\n this.renderMessages();\n }\n\n private updateHeader() {\n if (this.titleEl) this.titleEl.textContent = this.getAttribute('title') ?? this.agentName ?? 'Chat';\n }\n\n private updateStatus() {\n if (!this.textareaEl) return;\n const disabled = this.state !== 'ready';\n this.textareaEl.disabled = disabled;\n const handoff = HANDOFF_STATUS[this.handoffState];\n const text = this.state === 'opening' ? 'Connecting…' : handoff ?? (this.getAttribute('status') ?? DEFAULT_STATUS);\n if (this.statusEl) this.statusEl.textContent = text;\n if (this.state === 'error' && this.lastError) {\n this.errEl.hidden = false;\n this.errEl.innerHTML = `<span>Couldn't start chat: ${escapeHtml(this.lastError)}</span><button class=\"retry\" type=\"button\">Retry</button>`;\n this.errEl.querySelector('.retry')!.addEventListener('click', () => { void this.client?.start(); });\n } else { this.errEl.hidden = true; this.errEl.innerHTML = ''; }\n }\n\n // ── Message list + scroll ─────────────────────────────────────────────────────────────────────\n private renderMessages() {\n if (!this.bodyEl) return;\n const body = this.bodyEl;\n const prevTop = body.scrollTop;\n const added = this.messages.length - this.renderedCount;\n const botFinal = this.messages.filter((m) => m.role === 'assistant' && !m.streaming).length;\n const newBotFinal = botFinal > this.renderedBotFinal;\n\n const now = Date.now();\n for (const m of this.messages) if (!this.receivedAt.has(m.id)) this.receivedAt.set(m.id, now);\n\n const lastBot = (() => { for (let i = this.messages.length - 1; i >= 0; i--) if (this.messages[i]?.role === 'assistant') return i; return -1; })();\n let html = this.messages.map((m, i) => this.turnHtml(m, i === lastBot && !this.agentTyping)).join('');\n if (this.agentTyping) html += '<span class=\"typing\"><span></span><span></span><span></span></span>';\n const sugg = this.suggestions;\n if (sugg.length > 0 && !this.agentTyping && this.state === 'ready') {\n html += `<span class=\"chips\">${sugg.map((s, i) => `<button type=\"button\" class=\"chip\" data-chip=\"${i}\">${escapeHtml(s)}</button>`).join('')}</span>`;\n }\n body.innerHTML = html;\n this.hydrateAttachmentImages();\n this.bindChips();\n this.renderedCount = this.messages.length;\n this.renderedBotFinal = botFinal;\n\n if (!this.uiOpen) { if (added > 0) this.unseen += added; this.updateClasses(); return; }\n if (newBotFinal && !this.away) this.parkLastQuestion();\n else if (!this.away) this.scrollToBottom();\n else { body.scrollTop = prevTop; if (added > 0) this.unseen += added; }\n this.updateClasses();\n }\n\n // After a reply lands, float the question that prompted it to the top so the answer reads from its\n // first line rather than its last (the design's behaviour).\n private parkLastQuestion() {\n const users = this.bodyEl.querySelectorAll<HTMLElement>('.turn.user');\n const last = users[users.length - 1];\n if (!last) { this.scrollToBottom(); return; }\n const top = Math.max(0, Math.min(last.offsetTop - 22, this.bodyEl.scrollHeight - this.bodyEl.clientHeight));\n this.bodyEl.scrollTo({ top, behavior: 'smooth' });\n }\n\n private onScroll() {\n const b = this.bodyEl;\n const away = b.scrollHeight - b.scrollTop - b.clientHeight > AWAY_THRESHOLD;\n if (away !== this.away) { this.away = away; if (!away) this.unseen = 0; this.updateClasses(); }\n }\n private scrollToBottom() {\n if (!this.bodyEl) return;\n this.bodyEl.scrollTop = this.bodyEl.scrollHeight;\n this.away = false; this.unseen = 0;\n this.updateClasses();\n }\n\n // ── Composer ──────────────────────────────────────────────────────────────────────────────────\n private autoGrow() {\n const ta = this.textareaEl;\n ta.style.height = 'auto';\n ta.style.height = `${Math.min(ta.scrollHeight, 108)}px`;\n }\n private doSend() {\n const text = this.textareaEl.value;\n if (!text.trim()) return;\n const files = this.pendingFiles; this.pendingFiles = []; this.fileEl.value = '';\n for (const f of files) {\n if (f.type.startsWith('image/') && typeof URL.createObjectURL === 'function' && !this.imagePreviewCache.has(f.name)) {\n this.imagePreviewCache.set(f.name, URL.createObjectURL(f));\n }\n }\n this.away = false; this.emojiOpen = false;\n void this.client?.sendMessage(text, files.length > 0 ? files : undefined);\n this.textareaEl.value = ''; this.textareaEl.style.height = 'auto';\n this.updateClasses();\n }\n private sendChip(text: string) {\n this.away = false; this.emojiOpen = false;\n void this.client?.sendMessage(text);\n this.updateClasses();\n }\n private bindChips() {\n const sugg = this.suggestions;\n this.bodyEl.querySelectorAll<HTMLButtonElement>('.chip[data-chip]').forEach((btn) => {\n const i = Number(btn.getAttribute('data-chip'));\n const text = sugg[i];\n if (text) btn.addEventListener('click', () => this.sendChip(text));\n });\n }\n\n // ── Emoji ─────────────────────────────────────────────────────────────────────────────────────\n private toggleEmoji() { this.emojiOpen = !this.emojiOpen; this.emojiQuery = ''; this.emojiSearchEl.value = ''; this.renderEmoji(); this.updateClasses(); if (this.emojiOpen) setTimeout(() => this.emojiSearchEl.focus(), 60); }\n private closeEmoji() { this.emojiOpen = false; this.emojiQuery = ''; this.updateClasses(); }\n private renderEmoji() {\n const groups = emojiGroups(this.emojiQuery);\n let html = groups.map((g) => `\n <div class=\"emoji-grp\"><span class=\"emoji-grp-name\">${escapeHtml(g.name)}</span>\n <div class=\"emoji-grid\">${g.items.map((e) => `<button type=\"button\" title=\"${this.escapeAttr(e.name)}\" aria-label=\"${this.escapeAttr(e.name)}\" data-ch=\"${this.escapeAttr(e.ch)}\">${e.ch}</button>`).join('')}</div>\n </div>`).join('');\n if (groups.length === 0) html = '<span class=\"emoji-empty\" style=\"display:flex\"><span class=\"h\">No emoji match that</span><span class=\"s\">Try a shorter word, like smile or call.</span></span>';\n this.emojiListEl.innerHTML = html;\n this.emojiListEl.querySelectorAll<HTMLButtonElement>('button[data-ch]').forEach((btn) => {\n btn.addEventListener('click', () => {\n this.textareaEl.value += btn.getAttribute('data-ch') ?? '';\n this.emojiOpen = false;\n this.autoGrow();\n this.updateClasses();\n this.textareaEl.focus();\n });\n });\n }\n\n // ── Bubble rendering ──────────────────────────────────────────────────────────────────────────\n private turnHtml(m: ChatMessage, isLastBot: boolean): string {\n const role = m.role === 'user' ? 'user' : m.role === 'human' ? 'human' : 'bot';\n const atts = (m.attachments ?? []).map((a) => this.renderAttachment(a)).join('');\n let content: string;\n if (m.role === 'assistant') {\n // Only the AI's text renders markdown; cache finalized turns, re-render only the live one.\n let rendered = m.streaming ? undefined : this.mdCache.get(m.id);\n if (rendered === undefined) { rendered = renderMarkdown(m.text || ''); if (!m.streaming) this.mdCache.set(m.id, rendered); }\n content = `<span class=\"b\">${atts}<span class=\"md\">${rendered}</span></span>`;\n } else {\n const label = m.role === 'human' ? '<div class=\"human-label\">Support</div>' : '';\n content = `<span class=\"b\">${label}${atts}${escapeHtml(m.text)}</span>`;\n }\n\n const src = (m.sources && m.sources.length > 0)\n ? `<span class=\"src\">${ICON.book}<span class=\"t\">${escapeHtml('From ' + (m.sources[0]?.title ?? ''))}</span></span>`\n : '';\n const byline = (role === 'bot' && isLastBot)\n ? `<span class=\"byline\">${escapeHtml((this.agentName ?? 'OyeHello') + ' · AI agent · ' + this.relTime(m.id))}</span>`\n : '';\n return `<span class=\"turn ${role}\">${content}${src}${byline}</span>`;\n }\n\n private relTime(id: string): string {\n const t = this.receivedAt.get(id);\n if (!t) return 'just now';\n const mins = Math.floor((Date.now() - t) / 60000);\n return mins <= 0 ? 'just now' : `${mins} min ago`;\n }\n\n private renderAttachment(a: ChatAttachmentDescriptor): string {\n if (a.contentType.startsWith('image/')) {\n const cached = (a.name ? this.imagePreviewCache.get(a.name) : undefined) ?? this.resolvedUrlCache.get(a.storageRef);\n const srcAttr = cached ? ` src=\"${cached}\"` : '';\n return `<img class=\"att-thumb\" data-oc-ref=\"${this.escapeAttr(a.storageRef)}\"${srcAttr} alt=\"${this.escapeAttr(a.name ?? 'image')}\"/>`;\n }\n return `<div class=\"att-chip\">📎 ${escapeHtml(a.name ?? a.contentType)}</div>`;\n }\n\n private hydrateAttachmentImages() {\n if (!this.client) return;\n this.shadowRoot!.querySelectorAll<HTMLImageElement>('img.att-thumb[data-oc-ref]').forEach((img) => {\n if (img.hasAttribute('src')) return;\n const ref = img.getAttribute('data-oc-ref');\n if (!ref) return;\n void this.client!.getAttachmentUrl(ref)\n .then((url) => { this.resolvedUrlCache.set(ref, url); img.src = url; })\n .catch(() => { /* no thumbnail is an acceptable degrade */ });\n });\n }\n\n private escapeAttr(s: string) { return s.replace(/[&<>\"]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;' }[c]!)); }\n}\n\nfunction escapeHtml(s: string) { return s.replace(/[&<>\"]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;' }[c]!)); }\n","export { ChatApiError } from './errors';\nexport type { ChatEvent, OpenSessionResponse, ChatClientOptions, ChatAttachmentDescriptor } from './protocol';\nexport { createChatClient } from './client';\nexport type { ChatClient, ChatMessage, ChatClientState, ChatClientEvent, ChatToolHandler } from './client';\nexport { OyehelloChatElement } from './element';\n\nimport { OyehelloChatElement } from './element';\n// Side effect: registering the element is why the package is sideEffects:true.\nif (typeof customElements !== 'undefined' && !customElements.get('oyehello-chat')) {\n customElements.define('oyehello-chat', OyehelloChatElement);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oyehello/chat",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "Framework-agnostic embeddable chat SDK for oyehello agents. Web component + headless client.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
@@ -28,5 +28,9 @@
28
28
  "build": "tsup",
29
29
  "typecheck": "tsc --noEmit",
30
30
  "prepare": "tsup"
31
+ },
32
+ "dependencies": {
33
+ "dompurify": "^3.4.15",
34
+ "marked": "^18.0.12"
31
35
  }
32
36
  }