open-chat-studio-widget 0.6.0 → 0.8.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/README.md +28 -25
- package/dist/cjs/{index-CcvroTR_.js → index-Cf6K60f1.js} +3 -3
- package/dist/cjs/{index-CcvroTR_.js.map → index-Cf6K60f1.js.map} +1 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/open-chat-studio-widget.cjs.entry.js +480 -178
- package/dist/cjs/open-chat-studio-widget.cjs.entry.js.map +1 -1
- package/dist/cjs/open-chat-studio-widget.cjs.js +2 -2
- package/dist/cjs/open-chat-studio-widget.entry.cjs.js.map +1 -1
- package/dist/collection/components/ocs-chat/icons.js +2 -2
- package/dist/collection/components/ocs-chat/icons.js.map +1 -1
- package/dist/collection/components/ocs-chat/ocs-chat.css +29 -34
- package/dist/collection/components/ocs-chat/ocs-chat.js +374 -102
- package/dist/collection/components/ocs-chat/ocs-chat.js.map +1 -1
- package/dist/collection/services/chat-session-service.js +39 -1
- package/dist/collection/services/chat-session-service.js.map +1 -1
- package/dist/collection/services/file-attachment-manager.js +4 -7
- package/dist/collection/services/file-attachment-manager.js.map +1 -1
- package/dist/collection/utils/cookies.js.map +1 -1
- package/dist/collection/utils/markdown.js +43 -17
- package/dist/collection/utils/markdown.js.map +1 -1
- package/dist/collection/utils/translations.js +1 -3
- package/dist/collection/utils/translations.js.map +1 -1
- package/dist/collection/utils/utils.js +2 -2
- package/dist/collection/utils/utils.js.map +1 -1
- package/dist/components/open-chat-studio-widget.js +487 -178
- package/dist/components/open-chat-studio-widget.js.map +1 -1
- package/dist/esm/{index-BKVXO_5E.js → index-DXf2dIht.js} +3 -3
- package/dist/esm/{index-BKVXO_5E.js.map → index-DXf2dIht.js.map} +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/open-chat-studio-widget.entry.js +480 -178
- package/dist/esm/open-chat-studio-widget.entry.js.map +1 -1
- package/dist/esm/open-chat-studio-widget.js +3 -3
- package/dist/open-chat-studio-widget/open-chat-studio-widget.entry.esm.js.map +1 -1
- package/dist/open-chat-studio-widget/open-chat-studio-widget.esm.js +1 -1
- package/dist/open-chat-studio-widget/{p-BKVXO_5E.js → p-DXf2dIht.js} +2 -2
- package/dist/open-chat-studio-widget/{p-BKVXO_5E.js.map → p-DXf2dIht.js.map} +1 -1
- package/dist/open-chat-studio-widget/p-ff47dabf.entry.js +4 -0
- package/dist/open-chat-studio-widget/p-ff47dabf.entry.js.map +1 -0
- package/dist/types/components/ocs-chat/ocs-chat.d.ts +44 -2
- package/dist/types/components.d.ts +33 -4
- package/dist/types/services/chat-session-service.d.ts +7 -0
- package/dist/types/utils/markdown.d.ts +8 -0
- package/package.json +7 -2
- package/dist/open-chat-studio-widget/p-a0d04423.entry.js +0 -4
- package/dist/open-chat-studio-widget/p-a0d04423.entry.js.map +0 -1
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { h, r as registerInstance, E as Env, H as Host, g as getElement } from './index-
|
|
1
|
+
import { h, r as registerInstance, E as Env, H as Host, g as getElement } from './index-DXf2dIht.js';
|
|
2
2
|
|
|
3
3
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4
4
|
const OcsWidgetAvatar = () => {
|
|
5
|
-
return h("svg", { width: "24", height: "24", viewBox: "0 0 500 500", fill: "currentColor", xmlns: "http://www.w3.org/2000/svg" },
|
|
5
|
+
return (h("svg", { width: "24", height: "24", viewBox: "0 0 500 500", fill: "currentColor", xmlns: "http://www.w3.org/2000/svg" },
|
|
6
6
|
h("path", { d: "M80.1777 149.487C73.7354 160.531 68.6208 172.445 65.0576 185.012C43.6097 196.458 29.0128 219.057 29.0127 245.065C29.0127 270.995 43.5207 293.535 64.8613 305.014C68.3612 317.586 73.409 329.512 79.7881 340.575C34.4248 332.436 2.20245e-05 292.771 0 245.065C0.000198788 197.223 34.6221 157.469 80.1777 149.487ZM419.821 149.487C465.377 157.469 500 197.223 500 245.065C500 292.771 465.575 332.436 420.211 340.575C426.59 329.512 431.638 317.586 435.138 305.014C456.479 293.535 470.987 270.995 470.987 245.065C470.987 219.056 456.39 196.458 434.941 185.012C431.378 172.445 426.264 160.532 419.821 149.487ZM259.868 16.4473C304.099 16.4473 341.297 46.5498 352.097 87.3848C340.566 81.9422 328.254 77.8819 315.375 75.4209C303.51 57.3742 283.08 45.46 259.868 45.46H253.289C230.975 45.4601 211.232 56.4698 199.197 73.3535C186.6 74.535 174.442 77.2268 162.906 81.248C175.656 43.5694 211.305 16.4474 253.289 16.4473H259.868Z" }),
|
|
7
7
|
h("path", { d: "M286.185 72.6685C371.571 72.6686 440.789 141.888 440.789 227.274V263.458C440.789 348.844 371.57 418.064 286.185 418.064H213.815C128.43 418.064 59.2111 348.844 59.2109 263.458V227.274C59.211 141.888 128.43 72.6686 213.815 72.6685H286.185ZM213.815 105.263C142.963 105.263 85.5265 162.7 85.5264 233.552V256.579C85.5264 327.431 142.963 384.868 213.815 384.869H286.185C357.037 384.868 414.474 327.431 414.474 256.579V233.552C414.473 162.7 357.037 105.263 286.185 105.263H213.815Z" }),
|
|
8
8
|
h("rect", { x: "289.475", y: "184.808", width: "61.9019", height: "115.73", rx: "30.951" }),
|
|
9
9
|
h("rect", { x: "161.184", y: "184.808", width: "61.9019", height: "115.73", rx: "30.951" }),
|
|
10
|
-
h("path", { d: "M325.658 483.553V414.58V401.316H148.027L325.658 483.553Z" }));
|
|
10
|
+
h("path", { d: "M325.658 483.553V414.58V401.316H148.027L325.658 483.553Z" })));
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
13
|
* Heroicon: x-mark
|
|
14
14
|
*/
|
|
15
15
|
const XMarkIcon = () => {
|
|
16
|
-
return h("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor" },
|
|
17
|
-
h("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M6 18 18 6M6 6l12 12" }));
|
|
16
|
+
return (h("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor" },
|
|
17
|
+
h("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M6 18 18 6M6 6l12 12" })));
|
|
18
18
|
};
|
|
19
19
|
const GripDotsVerticalIcon = () => {
|
|
20
20
|
return (h("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "currentColor", viewBox: "0 0 24 24" },
|
|
@@ -2942,7 +2942,7 @@ marked.Slugger = Slugger;
|
|
|
2942
2942
|
marked.Hooks = Hooks;
|
|
2943
2943
|
marked.parse = marked;
|
|
2944
2944
|
|
|
2945
|
-
/*! @license DOMPurify 3.
|
|
2945
|
+
/*! @license DOMPurify 3.4.0 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.0/LICENSE */
|
|
2946
2946
|
|
|
2947
2947
|
const {
|
|
2948
2948
|
entries,
|
|
@@ -2971,12 +2971,18 @@ if (!seal) {
|
|
|
2971
2971
|
};
|
|
2972
2972
|
}
|
|
2973
2973
|
if (!apply) {
|
|
2974
|
-
apply = function apply(
|
|
2975
|
-
|
|
2974
|
+
apply = function apply(func, thisArg) {
|
|
2975
|
+
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
2976
|
+
args[_key - 2] = arguments[_key];
|
|
2977
|
+
}
|
|
2978
|
+
return func.apply(thisArg, args);
|
|
2976
2979
|
};
|
|
2977
2980
|
}
|
|
2978
2981
|
if (!construct) {
|
|
2979
|
-
construct = function construct(Func
|
|
2982
|
+
construct = function construct(Func) {
|
|
2983
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
2984
|
+
args[_key2 - 1] = arguments[_key2];
|
|
2985
|
+
}
|
|
2980
2986
|
return new Func(...args);
|
|
2981
2987
|
};
|
|
2982
2988
|
}
|
|
@@ -3005,8 +3011,8 @@ function unapply(func) {
|
|
|
3005
3011
|
if (thisArg instanceof RegExp) {
|
|
3006
3012
|
thisArg.lastIndex = 0;
|
|
3007
3013
|
}
|
|
3008
|
-
for (var
|
|
3009
|
-
args[
|
|
3014
|
+
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
|
3015
|
+
args[_key3 - 1] = arguments[_key3];
|
|
3010
3016
|
}
|
|
3011
3017
|
return apply(func, thisArg, args);
|
|
3012
3018
|
};
|
|
@@ -3017,12 +3023,12 @@ function unapply(func) {
|
|
|
3017
3023
|
* @param func - The constructor function to be wrapped and called.
|
|
3018
3024
|
* @returns A new function that constructs an instance of the given constructor function with the provided arguments.
|
|
3019
3025
|
*/
|
|
3020
|
-
function unconstruct(
|
|
3026
|
+
function unconstruct(Func) {
|
|
3021
3027
|
return function () {
|
|
3022
|
-
for (var
|
|
3023
|
-
args[
|
|
3028
|
+
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
3029
|
+
args[_key4] = arguments[_key4];
|
|
3024
3030
|
}
|
|
3025
|
-
return construct(
|
|
3031
|
+
return construct(Func, args);
|
|
3026
3032
|
};
|
|
3027
3033
|
}
|
|
3028
3034
|
/**
|
|
@@ -3121,8 +3127,8 @@ function lookupGetter(object, prop) {
|
|
|
3121
3127
|
return fallbackValue;
|
|
3122
3128
|
}
|
|
3123
3129
|
|
|
3124
|
-
const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
|
|
3125
|
-
const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
|
|
3130
|
+
const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
|
|
3131
|
+
const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
|
|
3126
3132
|
const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
|
|
3127
3133
|
// List of SVG elements that are disallowed by default.
|
|
3128
3134
|
// We still need to know them so that we can do namespace
|
|
@@ -3135,9 +3141,9 @@ const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mgly
|
|
|
3135
3141
|
const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
|
|
3136
3142
|
const text = freeze(['#text']);
|
|
3137
3143
|
|
|
3138
|
-
const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
|
|
3139
|
-
const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
|
|
3140
|
-
const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', '
|
|
3144
|
+
const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
|
|
3145
|
+
const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'mask-type', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
|
|
3146
|
+
const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnalign', 'columnlines', 'columnspacing', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lquote', 'lspace', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
|
|
3141
3147
|
const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
3142
3148
|
|
|
3143
3149
|
// eslint-disable-next-line unicorn/better-regex
|
|
@@ -3234,7 +3240,7 @@ const _createHooksMap = function _createHooksMap() {
|
|
|
3234
3240
|
function createDOMPurify() {
|
|
3235
3241
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
3236
3242
|
const DOMPurify = root => createDOMPurify(root);
|
|
3237
|
-
DOMPurify.version = '3.
|
|
3243
|
+
DOMPurify.version = '3.4.0';
|
|
3238
3244
|
DOMPurify.removed = [];
|
|
3239
3245
|
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
3240
3246
|
// Not running in a browser, provide a factory function
|
|
@@ -3345,6 +3351,21 @@ function createDOMPurify() {
|
|
|
3345
3351
|
let FORBID_TAGS = null;
|
|
3346
3352
|
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
|
|
3347
3353
|
let FORBID_ATTR = null;
|
|
3354
|
+
/* Config object to store ADD_TAGS/ADD_ATTR functions (when used as functions) */
|
|
3355
|
+
const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
|
|
3356
|
+
tagCheck: {
|
|
3357
|
+
writable: true,
|
|
3358
|
+
configurable: false,
|
|
3359
|
+
enumerable: true,
|
|
3360
|
+
value: null
|
|
3361
|
+
},
|
|
3362
|
+
attributeCheck: {
|
|
3363
|
+
writable: true,
|
|
3364
|
+
configurable: false,
|
|
3365
|
+
enumerable: true,
|
|
3366
|
+
value: null
|
|
3367
|
+
}
|
|
3368
|
+
}));
|
|
3348
3369
|
/* Decide if ARIA attributes are okay */
|
|
3349
3370
|
let ALLOW_ARIA_ATTR = true;
|
|
3350
3371
|
/* Decide if custom data attributes are okay */
|
|
@@ -3495,7 +3516,7 @@ function createDOMPurify() {
|
|
|
3495
3516
|
NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
|
|
3496
3517
|
MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;
|
|
3497
3518
|
HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;
|
|
3498
|
-
CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING ||
|
|
3519
|
+
CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || create(null);
|
|
3499
3520
|
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
|
|
3500
3521
|
CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
|
|
3501
3522
|
}
|
|
@@ -3514,7 +3535,7 @@ function createDOMPurify() {
|
|
|
3514
3535
|
/* Parse profile info */
|
|
3515
3536
|
if (USE_PROFILES) {
|
|
3516
3537
|
ALLOWED_TAGS = addToSet({}, text);
|
|
3517
|
-
ALLOWED_ATTR =
|
|
3538
|
+
ALLOWED_ATTR = create(null);
|
|
3518
3539
|
if (USE_PROFILES.html === true) {
|
|
3519
3540
|
addToSet(ALLOWED_TAGS, html$1);
|
|
3520
3541
|
addToSet(ALLOWED_ATTR, html);
|
|
@@ -3535,18 +3556,30 @@ function createDOMPurify() {
|
|
|
3535
3556
|
addToSet(ALLOWED_ATTR, xml);
|
|
3536
3557
|
}
|
|
3537
3558
|
}
|
|
3559
|
+
/* Always reset function-based ADD_TAGS / ADD_ATTR checks to prevent
|
|
3560
|
+
* leaking across calls when switching from function to array config */
|
|
3561
|
+
EXTRA_ELEMENT_HANDLING.tagCheck = null;
|
|
3562
|
+
EXTRA_ELEMENT_HANDLING.attributeCheck = null;
|
|
3538
3563
|
/* Merge configuration parameters */
|
|
3539
3564
|
if (cfg.ADD_TAGS) {
|
|
3540
|
-
if (
|
|
3541
|
-
|
|
3565
|
+
if (typeof cfg.ADD_TAGS === 'function') {
|
|
3566
|
+
EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
|
|
3567
|
+
} else {
|
|
3568
|
+
if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
|
|
3569
|
+
ALLOWED_TAGS = clone(ALLOWED_TAGS);
|
|
3570
|
+
}
|
|
3571
|
+
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
|
|
3542
3572
|
}
|
|
3543
|
-
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
|
|
3544
3573
|
}
|
|
3545
3574
|
if (cfg.ADD_ATTR) {
|
|
3546
|
-
if (
|
|
3547
|
-
|
|
3575
|
+
if (typeof cfg.ADD_ATTR === 'function') {
|
|
3576
|
+
EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
|
|
3577
|
+
} else {
|
|
3578
|
+
if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
|
|
3579
|
+
ALLOWED_ATTR = clone(ALLOWED_ATTR);
|
|
3580
|
+
}
|
|
3581
|
+
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
|
|
3548
3582
|
}
|
|
3549
|
-
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
|
|
3550
3583
|
}
|
|
3551
3584
|
if (cfg.ADD_URI_SAFE_ATTR) {
|
|
3552
3585
|
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
|
|
@@ -3557,6 +3590,12 @@ function createDOMPurify() {
|
|
|
3557
3590
|
}
|
|
3558
3591
|
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
|
|
3559
3592
|
}
|
|
3593
|
+
if (cfg.ADD_FORBID_CONTENTS) {
|
|
3594
|
+
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
3595
|
+
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
3596
|
+
}
|
|
3597
|
+
addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
|
|
3598
|
+
}
|
|
3560
3599
|
/* Add #text in case KEEP_CONTENT is set to true */
|
|
3561
3600
|
if (KEEP_CONTENT) {
|
|
3562
3601
|
ALLOWED_TAGS['#text'] = true;
|
|
@@ -3843,6 +3882,11 @@ function createDOMPurify() {
|
|
|
3843
3882
|
_forceRemove(currentNode);
|
|
3844
3883
|
return true;
|
|
3845
3884
|
}
|
|
3885
|
+
/* Remove risky CSS construction leading to mXSS */
|
|
3886
|
+
if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === 'style' && _isNode(currentNode.firstElementChild)) {
|
|
3887
|
+
_forceRemove(currentNode);
|
|
3888
|
+
return true;
|
|
3889
|
+
}
|
|
3846
3890
|
/* Remove any occurrence of processing instructions */
|
|
3847
3891
|
if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
|
|
3848
3892
|
_forceRemove(currentNode);
|
|
@@ -3854,7 +3898,7 @@ function createDOMPurify() {
|
|
|
3854
3898
|
return true;
|
|
3855
3899
|
}
|
|
3856
3900
|
/* Remove element if anything forbids its presence */
|
|
3857
|
-
if (
|
|
3901
|
+
if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
|
|
3858
3902
|
/* Check if we have a custom element to handle */
|
|
3859
3903
|
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
|
3860
3904
|
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
|
@@ -3918,6 +3962,10 @@ function createDOMPurify() {
|
|
|
3918
3962
|
*/
|
|
3919
3963
|
// eslint-disable-next-line complexity
|
|
3920
3964
|
const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
3965
|
+
/* FORBID_ATTR must always win, even if ADD_ATTR predicate would allow it */
|
|
3966
|
+
if (FORBID_ATTR[lcName]) {
|
|
3967
|
+
return false;
|
|
3968
|
+
}
|
|
3921
3969
|
/* Make sure attribute cannot clobber */
|
|
3922
3970
|
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
3923
3971
|
return false;
|
|
@@ -3926,12 +3974,12 @@ function createDOMPurify() {
|
|
|
3926
3974
|
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
3927
3975
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
3928
3976
|
We don't need to check the value; it's always URI safe. */
|
|
3929
|
-
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
3977
|
+
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
3930
3978
|
if (
|
|
3931
3979
|
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
|
3932
3980
|
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
3933
3981
|
// and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
|
|
3934
|
-
_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) ||
|
|
3982
|
+
_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) ||
|
|
3935
3983
|
// Alternative, second condition checks if it's an `is`-attribute, AND
|
|
3936
3984
|
// the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
3937
3985
|
lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {
|
|
@@ -4010,7 +4058,12 @@ function createDOMPurify() {
|
|
|
4010
4058
|
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
|
4011
4059
|
}
|
|
4012
4060
|
/* Work around a security issue with comments inside attributes */
|
|
4013
|
-
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
|
4061
|
+
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
|
|
4062
|
+
_removeAttribute(name, currentNode);
|
|
4063
|
+
continue;
|
|
4064
|
+
}
|
|
4065
|
+
/* Make sure we cannot easily use animated hrefs, even if animations are allowed */
|
|
4066
|
+
if (lcName === 'attributename' && stringMatch(value, 'href')) {
|
|
4014
4067
|
_removeAttribute(name, currentNode);
|
|
4015
4068
|
continue;
|
|
4016
4069
|
}
|
|
@@ -4084,7 +4137,7 @@ function createDOMPurify() {
|
|
|
4084
4137
|
*
|
|
4085
4138
|
* @param fragment to iterate over recursively
|
|
4086
4139
|
*/
|
|
4087
|
-
const
|
|
4140
|
+
const _sanitizeShadowDOM2 = function _sanitizeShadowDOM(fragment) {
|
|
4088
4141
|
let shadowNode = null;
|
|
4089
4142
|
const shadowIterator = _createNodeIterator(fragment);
|
|
4090
4143
|
/* Execute a hook if present */
|
|
@@ -4098,7 +4151,7 @@ function createDOMPurify() {
|
|
|
4098
4151
|
_sanitizeAttributes(shadowNode);
|
|
4099
4152
|
/* Deep shadow DOM detected */
|
|
4100
4153
|
if (shadowNode.content instanceof DocumentFragment) {
|
|
4101
|
-
|
|
4154
|
+
_sanitizeShadowDOM2(shadowNode.content);
|
|
4102
4155
|
}
|
|
4103
4156
|
}
|
|
4104
4157
|
/* Execute a hook if present */
|
|
@@ -4193,7 +4246,7 @@ function createDOMPurify() {
|
|
|
4193
4246
|
_sanitizeAttributes(currentNode);
|
|
4194
4247
|
/* Shadow DOM detected, sanitize it */
|
|
4195
4248
|
if (currentNode.content instanceof DocumentFragment) {
|
|
4196
|
-
|
|
4249
|
+
_sanitizeShadowDOM2(currentNode.content);
|
|
4197
4250
|
}
|
|
4198
4251
|
}
|
|
4199
4252
|
/* If we sanitized `dirty` in-place, return it. */
|
|
@@ -4202,6 +4255,14 @@ function createDOMPurify() {
|
|
|
4202
4255
|
}
|
|
4203
4256
|
/* Return sanitized string or DOM */
|
|
4204
4257
|
if (RETURN_DOM) {
|
|
4258
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
4259
|
+
body.normalize();
|
|
4260
|
+
let html = body.innerHTML;
|
|
4261
|
+
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
4262
|
+
html = stringReplace(html, expr, ' ');
|
|
4263
|
+
});
|
|
4264
|
+
body.innerHTML = html;
|
|
4265
|
+
}
|
|
4205
4266
|
if (RETURN_DOM_FRAGMENT) {
|
|
4206
4267
|
returnNode = createDocumentFragment.call(body.ownerDocument);
|
|
4207
4268
|
while (body.firstChild) {
|
|
@@ -4295,7 +4356,7 @@ function postProcessMarkdownHTML(html) {
|
|
|
4295
4356
|
tempDiv.innerHTML = html;
|
|
4296
4357
|
// Add target="_blank" and rel="noopener noreferrer" to external links
|
|
4297
4358
|
const links = tempDiv.querySelectorAll('a[href]');
|
|
4298
|
-
links.forEach(
|
|
4359
|
+
links.forEach(link => {
|
|
4299
4360
|
const href = link.getAttribute('href');
|
|
4300
4361
|
if (href && (href.startsWith('http://') || href.startsWith('https://'))) {
|
|
4301
4362
|
link.setAttribute('target', '_blank');
|
|
@@ -4309,28 +4370,54 @@ function postProcessMarkdownHTML(html) {
|
|
|
4309
4370
|
return html;
|
|
4310
4371
|
}
|
|
4311
4372
|
}
|
|
4373
|
+
const SANITIZE_CONFIG = {
|
|
4374
|
+
ALLOWED_TAGS: [
|
|
4375
|
+
'p',
|
|
4376
|
+
'br',
|
|
4377
|
+
'strong',
|
|
4378
|
+
'b',
|
|
4379
|
+
'em',
|
|
4380
|
+
'i',
|
|
4381
|
+
'u',
|
|
4382
|
+
'code',
|
|
4383
|
+
'pre',
|
|
4384
|
+
'ul',
|
|
4385
|
+
'ol',
|
|
4386
|
+
'li',
|
|
4387
|
+
'h1',
|
|
4388
|
+
'h2',
|
|
4389
|
+
'h3',
|
|
4390
|
+
'h4',
|
|
4391
|
+
'h5',
|
|
4392
|
+
'h6',
|
|
4393
|
+
'blockquote',
|
|
4394
|
+
'a',
|
|
4395
|
+
'img',
|
|
4396
|
+
'hr',
|
|
4397
|
+
'table',
|
|
4398
|
+
'thead',
|
|
4399
|
+
'tbody',
|
|
4400
|
+
'tr',
|
|
4401
|
+
'td',
|
|
4402
|
+
'th',
|
|
4403
|
+
'del',
|
|
4404
|
+
'ins',
|
|
4405
|
+
'sub',
|
|
4406
|
+
'sup',
|
|
4407
|
+
],
|
|
4408
|
+
ALLOWED_ATTR: ['href', 'target', 'rel', 'class', 'src', 'alt', 'title', 'width', 'height', 'align', 'colspan', 'rowspan'],
|
|
4409
|
+
ALLOWED_URI_REGEXP: /^(?:(?:https?):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i,
|
|
4410
|
+
ADD_ATTR: ['target'],
|
|
4411
|
+
FORBID_TAGS: ['script', 'style', 'form', 'input', 'button', 'iframe', 'object', 'embed', 'svg', 'math'],
|
|
4412
|
+
FORBID_ATTR: ['onclick', 'onload', 'onerror', 'onmouseover'],
|
|
4413
|
+
};
|
|
4312
4414
|
function renderMarkdownSync(content) {
|
|
4313
4415
|
if (!content || typeof content !== 'string') {
|
|
4314
4416
|
return '';
|
|
4315
4417
|
}
|
|
4316
4418
|
try {
|
|
4317
4419
|
const html = marked.parse(content);
|
|
4318
|
-
const sanitized = purify.sanitize(html,
|
|
4319
|
-
ALLOWED_TAGS: [
|
|
4320
|
-
'p', 'br', 'strong', 'b', 'em', 'i', 'u', 'code', 'pre',
|
|
4321
|
-
'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
|
4322
|
-
'blockquote', 'a', 'img', 'hr', 'table', 'thead', 'tbody',
|
|
4323
|
-
'tr', 'td', 'th', 'del', 'ins', 'sub', 'sup'
|
|
4324
|
-
],
|
|
4325
|
-
ALLOWED_ATTR: [
|
|
4326
|
-
'href', 'target', 'rel', 'class', 'src', 'alt', 'title',
|
|
4327
|
-
'width', 'height', 'align', 'colspan', 'rowspan'
|
|
4328
|
-
],
|
|
4329
|
-
ALLOWED_URI_REGEXP: /^(?:(?:https?):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i,
|
|
4330
|
-
ADD_ATTR: ['target'],
|
|
4331
|
-
FORBID_TAGS: ['script', 'style', 'form', 'input', 'button'],
|
|
4332
|
-
FORBID_ATTR: ['onclick', 'onload', 'onerror', 'onmouseover'],
|
|
4333
|
-
});
|
|
4420
|
+
const sanitized = purify.sanitize(html, SANITIZE_CONFIG);
|
|
4334
4421
|
return postProcessMarkdownHTML(sanitized);
|
|
4335
4422
|
}
|
|
4336
4423
|
catch (error) {
|
|
@@ -4347,13 +4434,13 @@ function renderMarkdownSync(content) {
|
|
|
4347
4434
|
*/
|
|
4348
4435
|
const varToPixels = (value, maxValue, defaultValue) => {
|
|
4349
4436
|
value = value.trim();
|
|
4350
|
-
if (value.includes(
|
|
4437
|
+
if (value.includes('%')) {
|
|
4351
4438
|
const percent = percentToFloat(value);
|
|
4352
4439
|
if (!isNaN(percent)) {
|
|
4353
4440
|
return maxValue * percent;
|
|
4354
4441
|
}
|
|
4355
4442
|
}
|
|
4356
|
-
else if (value.includes(
|
|
4443
|
+
else if (value.includes('px')) {
|
|
4357
4444
|
const pixels = parseFloat(value);
|
|
4358
4445
|
if (!isNaN(pixels)) {
|
|
4359
4446
|
return pixels;
|
|
@@ -4714,9 +4801,7 @@ class TranslationManager {
|
|
|
4714
4801
|
console.error('Failed to load translations:', error);
|
|
4715
4802
|
baseTranslations = defaultTranslations;
|
|
4716
4803
|
}
|
|
4717
|
-
this.translations = customTranslations
|
|
4718
|
-
? mergeTranslations(baseTranslations, customTranslations)
|
|
4719
|
-
: baseTranslations;
|
|
4804
|
+
this.translations = customTranslations ? mergeTranslations(baseTranslations, customTranslations) : baseTranslations;
|
|
4720
4805
|
}
|
|
4721
4806
|
get(key, override) {
|
|
4722
4807
|
var _a;
|
|
@@ -4747,20 +4832,18 @@ class TranslationManager {
|
|
|
4747
4832
|
}
|
|
4748
4833
|
}
|
|
4749
4834
|
|
|
4750
|
-
/*! js-cookie v3.0.
|
|
4751
|
-
/* eslint-disable no-var */
|
|
4835
|
+
/*! js-cookie v3.0.7 | MIT */
|
|
4752
4836
|
function assign (target) {
|
|
4753
4837
|
for (var i = 1; i < arguments.length; i++) {
|
|
4754
4838
|
var source = arguments[i];
|
|
4755
4839
|
for (var key in source) {
|
|
4840
|
+
if (key === '__proto__') continue
|
|
4756
4841
|
target[key] = source[key];
|
|
4757
4842
|
}
|
|
4758
4843
|
}
|
|
4759
4844
|
return target
|
|
4760
4845
|
}
|
|
4761
|
-
/* eslint-enable no-var */
|
|
4762
4846
|
|
|
4763
|
-
/* eslint-disable no-var */
|
|
4764
4847
|
var defaultConverter = {
|
|
4765
4848
|
read: function (value) {
|
|
4766
4849
|
if (value[0] === '"') {
|
|
@@ -4775,12 +4858,9 @@ var defaultConverter = {
|
|
|
4775
4858
|
)
|
|
4776
4859
|
}
|
|
4777
4860
|
};
|
|
4778
|
-
/* eslint-enable no-var */
|
|
4779
4861
|
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
function init (converter, defaultAttributes) {
|
|
4783
|
-
function set (name, value, attributes) {
|
|
4862
|
+
function init(converter, defaultAttributes) {
|
|
4863
|
+
function set(name, value, attributes) {
|
|
4784
4864
|
if (typeof document === 'undefined') {
|
|
4785
4865
|
return
|
|
4786
4866
|
}
|
|
@@ -4824,7 +4904,7 @@ function init (converter, defaultAttributes) {
|
|
|
4824
4904
|
name + '=' + converter.write(value, name) + stringifiedAttributes)
|
|
4825
4905
|
}
|
|
4826
4906
|
|
|
4827
|
-
function get
|
|
4907
|
+
function get(name) {
|
|
4828
4908
|
if (typeof document === 'undefined' || (arguments.length && !name)) {
|
|
4829
4909
|
return
|
|
4830
4910
|
}
|
|
@@ -4839,12 +4919,13 @@ function init (converter, defaultAttributes) {
|
|
|
4839
4919
|
|
|
4840
4920
|
try {
|
|
4841
4921
|
var found = decodeURIComponent(parts[0]);
|
|
4842
|
-
jar[found] = converter.read(value, found);
|
|
4843
|
-
|
|
4922
|
+
if (!(found in jar)) jar[found] = converter.read(value, found);
|
|
4844
4923
|
if (name === found) {
|
|
4845
4924
|
break
|
|
4846
4925
|
}
|
|
4847
|
-
} catch
|
|
4926
|
+
} catch {
|
|
4927
|
+
// Do nothing...
|
|
4928
|
+
}
|
|
4848
4929
|
}
|
|
4849
4930
|
|
|
4850
4931
|
return name ? jar[name] : jar
|
|
@@ -4937,7 +5018,17 @@ class ChatSessionService {
|
|
|
4937
5018
|
headers: this.getCommonHeaders(),
|
|
4938
5019
|
});
|
|
4939
5020
|
if (!response.ok) {
|
|
4940
|
-
|
|
5021
|
+
let errorMessage = `Failed to poll task: ${response.statusText}`;
|
|
5022
|
+
try {
|
|
5023
|
+
const data = (await response.json());
|
|
5024
|
+
if (data === null || data === void 0 ? void 0 : data.error) {
|
|
5025
|
+
errorMessage = data.error;
|
|
5026
|
+
}
|
|
5027
|
+
}
|
|
5028
|
+
catch (_a) {
|
|
5029
|
+
// non-JSON body; keep statusText fallback
|
|
5030
|
+
}
|
|
5031
|
+
throw new Error(errorMessage);
|
|
4941
5032
|
}
|
|
4942
5033
|
return response.json();
|
|
4943
5034
|
}
|
|
@@ -4951,6 +5042,7 @@ class ChatSessionService {
|
|
|
4951
5042
|
}, this.taskPollingIntervalMs);
|
|
4952
5043
|
};
|
|
4953
5044
|
const poll = async () => {
|
|
5045
|
+
var _a;
|
|
4954
5046
|
if (cancelled) {
|
|
4955
5047
|
return;
|
|
4956
5048
|
}
|
|
@@ -4963,6 +5055,9 @@ class ChatSessionService {
|
|
|
4963
5055
|
callbacks.onMessage(data.message);
|
|
4964
5056
|
return;
|
|
4965
5057
|
}
|
|
5058
|
+
if (data.status === 'processing' && ((_a = data.message) === null || _a === void 0 ? void 0 : _a.content) && callbacks.onProgress) {
|
|
5059
|
+
callbacks.onProgress(data.message.content);
|
|
5060
|
+
}
|
|
4966
5061
|
attempts += 1;
|
|
4967
5062
|
if (attempts >= this.taskPollingMaxAttempts) {
|
|
4968
5063
|
if (callbacks.onTimeout) {
|
|
@@ -5001,6 +5096,29 @@ class ChatSessionService {
|
|
|
5001
5096
|
}
|
|
5002
5097
|
return response.json();
|
|
5003
5098
|
}
|
|
5099
|
+
/**
|
|
5100
|
+
* Fetch the complete message history for a session by paging through the
|
|
5101
|
+
* poll endpoint until no more messages remain.
|
|
5102
|
+
*/
|
|
5103
|
+
async fetchAllMessages(sessionId) {
|
|
5104
|
+
var _a;
|
|
5105
|
+
const allMessages = [];
|
|
5106
|
+
let since;
|
|
5107
|
+
let hasMore = true;
|
|
5108
|
+
for (let page = 0; hasMore && page < ChatSessionService.MAX_HISTORY_PAGES; page++) {
|
|
5109
|
+
const data = await this.fetchMessages(sessionId, since);
|
|
5110
|
+
allMessages.push(...data.messages);
|
|
5111
|
+
hasMore = data.has_more && data.messages.length > 0;
|
|
5112
|
+
// The server returns pages in ascending created_at order and `since` is
|
|
5113
|
+
// exclusive (created_at > since), so the last message's timestamp is the
|
|
5114
|
+
// next page cursor.
|
|
5115
|
+
since = (_a = data.messages.at(-1)) === null || _a === void 0 ? void 0 : _a.created_at;
|
|
5116
|
+
}
|
|
5117
|
+
if (hasMore) {
|
|
5118
|
+
console.warn('Chat history truncated after', ChatSessionService.MAX_HISTORY_PAGES, 'pages');
|
|
5119
|
+
}
|
|
5120
|
+
return allMessages;
|
|
5121
|
+
}
|
|
5004
5122
|
startMessagePolling(sessionId, callbacks) {
|
|
5005
5123
|
const poll = async () => {
|
|
5006
5124
|
try {
|
|
@@ -5050,6 +5168,7 @@ class ChatSessionService {
|
|
|
5050
5168
|
return headers;
|
|
5051
5169
|
}
|
|
5052
5170
|
}
|
|
5171
|
+
ChatSessionService.MAX_HISTORY_PAGES = 40;
|
|
5053
5172
|
|
|
5054
5173
|
class FileAttachmentManager {
|
|
5055
5174
|
constructor(config) {
|
|
@@ -5063,8 +5182,8 @@ class FileAttachmentManager {
|
|
|
5063
5182
|
let totalSize = existingFiles.reduce((sum, f) => sum + f.file.size, 0);
|
|
5064
5183
|
for (const file of fileArray) {
|
|
5065
5184
|
const extension = this.getFileExtension(file.name);
|
|
5066
|
-
const contentType = file.type.split(
|
|
5067
|
-
if (contentType !=
|
|
5185
|
+
const contentType = file.type.split('/')[0];
|
|
5186
|
+
if (contentType != 'text' && !this.supportedExtensions.includes(extension)) {
|
|
5068
5187
|
newSelected.push({ file, error: `File type ${extension} not supported` });
|
|
5069
5188
|
continue;
|
|
5070
5189
|
}
|
|
@@ -5099,9 +5218,7 @@ class FileAttachmentManager {
|
|
|
5099
5218
|
return { selectedFiles: existingFiles, uploadedIds: [] };
|
|
5100
5219
|
}
|
|
5101
5220
|
const uploadCandidates = existingFiles.filter(file => !file.error && !file.uploaded);
|
|
5102
|
-
const uploadedIds = existingFiles
|
|
5103
|
-
.filter(file => file.uploaded)
|
|
5104
|
-
.map(file => file.uploaded.id);
|
|
5221
|
+
const uploadedIds = existingFiles.filter(file => file.uploaded).map(file => file.uploaded.id);
|
|
5105
5222
|
if (uploadCandidates.length === 0) {
|
|
5106
5223
|
return { selectedFiles: existingFiles, uploadedIds };
|
|
5107
5224
|
}
|
|
@@ -5120,8 +5237,7 @@ class FileAttachmentManager {
|
|
|
5120
5237
|
});
|
|
5121
5238
|
if (!response.ok) {
|
|
5122
5239
|
const errorData = await this.safeJson(response);
|
|
5123
|
-
const errorMessage = (errorData && typeof errorData === 'object' && 'error' in errorData && errorData.error) ||
|
|
5124
|
-
'Failed to upload files';
|
|
5240
|
+
const errorMessage = (errorData && typeof errorData === 'object' && 'error' in errorData && errorData.error) || 'Failed to upload files';
|
|
5125
5241
|
return {
|
|
5126
5242
|
selectedFiles: this.markPendingFilesWithError(existingFiles, errorMessage),
|
|
5127
5243
|
uploadedIds,
|
|
@@ -5177,7 +5293,7 @@ class FileAttachmentManager {
|
|
|
5177
5293
|
}
|
|
5178
5294
|
}
|
|
5179
5295
|
|
|
5180
|
-
const ocsChatCss = "/*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */@layer properties{@supports ((-webkit-hyphens:none) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,::backdrop,:after,:before{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:host,:root{--font-sans:ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;--color-blue-300:oklch(80.9% .105 251.813);--color-slate-500:oklch(55.4% .046 257.417);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--spacing:.25rem;--breakpoint-lg:64rem;--container-sm:24rem;--font-weight-light:300;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--animate-progress:progress 3s infinite linear;--animate-dots:dots 1s steps(5,end)infinite;--transform-origin-left-right:0% 50%}}@layer base{*,::backdrop,:after,:before{border:0 solid;border-color:var(--color-gray-200,currentcolor);box-sizing:border-box;margin:0;padding:0}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button;background-color:#0000;border:0 solid;border-color:var(--color-gray-200,currentcolor);border-radius:0;box-sizing:border-box;color:inherit;font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;margin:0;margin-inline-end:4px;opacity:1;padding:0}:host,html{-webkit-text-size-adjust:100%;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-size:1em;font-variation-settings:var(--default-mono-font-variation-settings,normal)}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}menu,ol,ul{list-style:none}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}button,input,optgroup,select,textarea{background-color:#0000;border-radius:0;color:inherit;font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;opacity:1}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::-moz-placeholder{opacity:1}::placeholder{opacity:1}@supports (not (-webkit-appearance:-apple-pay-button)) or (contain-intrinsic-size:1px){::-moz-placeholder{color:currentColor}::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::-moz-placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex;padding-block:0}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.static{position:static}.container{width:100%}.flex{display:flex}.hidden{display:none}.w-full{width:100%}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.resize{resize:both}.items-center{align-items:center}.justify-center{justify-content:center}.gap-\\[0\\.5em\\]{gap:.5em}:where(.space-y-\\[0\\.25em\\]>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(.25em*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(.25em*var(--tw-space-y-reverse))}.border{border-style:var(--tw-border-style);border-width:1px}.py-\\[2px\\]{padding-block:2px}.text-\\[0\\.8em\\]{font-size:.8em}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.text-slate-500{color:var(--color-slate-500)}.underline{text-decoration-line:underline}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a)}.ring,.shadow{box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor)}} /*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */@layer properties{}@layer base{}@layer components; /*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */@layer properties{}@layer base{}@layer components{#ocs-chat-window{font-size:var(--chat-window-font-size);z-index:var(--chat-z-index)}.starter-question{border-radius:var(--radius-lg);text-align:left;--tw-duration:.2s;background-color:var(--starter-question-bg-color);border:1px solid var(--starter-question-border-color);color:var(--starter-question-text-color);padding:.75em;transition-duration:.2s}.starter-question:hover{background-color:var(--starter-question-bg-hover-color);border-color:var(--starter-question-border-hover-color)}.chat-btn-text{border-radius:var(--radius-lg);border-style:var(--tw-border-style);transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,);--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;--tw-ease:var(--ease-in-out);align-items:center;background-color:var(--button-background-color,#fff);border-width:0;border:1px solid var(--button-border-color);color:var(--button-text-color,#111827);display:flex;font-size:var(--button-font-size);gap:8px;padding:.5em;transition-duration:.2s;transition-timing-function:var(--ease-in-out);z-index:var(--chat-z-index,50)}.chat-btn-text:hover{border:1px solid var(--button-border-color-hover);color:var(--button-text-color-hover,#1d4ed8)}.chat-btn-text span{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap}.chat-btn-text img{flex-shrink:0;height:var(--button-icon-size);-o-object-fit:contain;object-fit:contain;width:var(--button-icon-size)}.chat-btn-text.round{border-radius:3.40282e+38px}.chat-btn-icon{border-radius:var(--radius-lg);border-style:var(--tw-border-style);transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,);--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;--tw-ease:var(--ease-in-out);background-color:var(--button-background-color,#fff);border-width:0;border:1px solid var(--button-border-color);font-size:var(--button-font-size);padding:.5em;transition-duration:.2s;transition-timing-function:var(--ease-in-out);z-index:var(--chat-z-index,50)}.chat-btn-icon:hover{border:1px solid var(--button-border-color-hover);color:var(--button-text-color-hover,#1d4ed8)}.chat-btn-icon img{height:var(--button-icon-size);-o-object-fit:contain;object-fit:contain;width:var(--button-icon-size)}.chat-btn-icon.round,.round .chat-btn-icon,.round.chat-btn-text{border-radius:3.40282e+38px}.error-message{color:var(--error-text-color);padding:.5em}.chat-window-fullscreen{border-style:var(--tw-border-style);inset:calc(var(--spacing)*0);z-index:9999;--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);height:100%;max-height:100%;transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));width:100%;--tw-duration:.2s;border-radius:0;border-width:0;max-width:var(--chat-window-fullscreen-width);transition-duration:.2s}.chat-window-fullscreen,.chat-window-normal{background-color:var(--chat-window-bg-color);display:flex;flex-direction:column;overflow:hidden;position:fixed}.chat-window-normal{border:1px solid var(--chat-window-border-color);border-radius:var(--radius-lg);height:100vh;max-width:var(--breakpoint-lg);min-height:300px;min-width:300px;width:100vw}.chat-window-normal:not(.chat-window-dragging){--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;transition-duration:.2s}.chat-window-dragging,.chat-window-normal:not(.chat-window-dragging){box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.chat-window-dragging{cursor:grabbing;--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040)}.chat-header{transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.15s;align-items:center;background-color:var(--header-bg-color);border-bottom:1px solid var(--header-border-color);display:flex;font-size:var(--header-font-size);justify-content:space-between;padding:.5em;transition-duration:.15s}.chat-header:active,.chat-header:hover{background-color:var(--header-bg-hover-color)}.header-text{align-items:center;color:var(--header-text-color);display:flex;font-size:var(--header-text-font-size);justify-content:center}.chat-header-draggable{cursor:grab}.chat-header-dragging{cursor:grabbing}.drag-indicator{display:none}.drag-dots{display:flex;gap:2px;margin-left:2px;pointer-events:none}.header-buttons{align-items:center;display:flex;gap:4px}.header-button{border-radius:var(--radius-md);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;color:var(--header-button-text-color);padding:.375em;transition-duration:.2s}.header-button svg{height:var(--header-button-icon-size);width:var(--header-button-icon-size)}.header-button:hover{background-color:var(--header-button-bg-hover-color)}.fullscreen-button{display:none}.chat-content{display:flex;flex-direction:column;flex-grow:1;overflow:hidden}.loading-container{align-items:center;display:flex;flex-grow:1;justify-content:center}.loading-text{color:var(--loading-text-color);margin-left:2px}.messages-container{flex-grow:1;overflow-y:auto;padding:1em}:where(.messages-container>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(var(--spacing)*2*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(var(--spacing)*2*var(--tw-space-y-reverse))}.message-row{display:flex}.message-row-user{justify-content:flex-end}.message-row-assistant{justify-content:flex-start}.message-bubble{border-radius:var(--radius-lg);padding:.5em 1em}.message-bubble-user{background-color:var(--message-user-bg-color);color:var(--message-user-text-color)}.message-bubble-assistant{background-color:var(--message-assistant-bg-color);color:var(--message-assistant-text-color)}.message-bubble-system{background-color:var(--message-system-bg-color);color:var(--message-system-text-color)}.message-timestamp{font-size:var(--chat-window-font-size-sm);margin-top:4px;opacity:.7}.message-attachments{margin-top:8px}:where(.message-attachments>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(var(--spacing)*1*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(var(--spacing)*1*var(--tw-space-y-reverse))}.attachment-link{display:block;text-decoration-line:underline}:where(.welcome-messages>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(var(--spacing)*2*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(var(--spacing)*2*var(--tw-space-y-reverse))}.typing-indicator{height:calc(var(--spacing)*1.5);overflow:hidden;width:100%}.typing-progress{animation:var(--animate-progress);background-color:var(--typing-progress-bg-color);border-radius:var(--radius-lg);height:100%;transform-origin:var(--transform-origin-left-right);width:100%}.typing-text{font-size:var(--chat-window-font-size-sm);justify-content:center;opacity:.7;width:100%}.typing-dots{animation:var(--animate-dots)}:where(.starter-questions>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(var(--spacing)*2*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(var(--spacing)*2*var(--tw-space-y-reverse))}.starter-questions{padding:1em}.starter-question-row{display:flex;justify-content:flex-end}.input-area{background-color:var(--input-bg-color);border-top:1px solid var(--input-border-color);padding:1em 1em 0}.input-container{display:flex;gap:8px}.message-textarea{background-color:var(--input-bg-color);border-color:var(--color-gray-300);border-radius:var(--radius-md);border-style:var(--tw-border-style);border-width:1px;border:1px solid var(--input-border-color);color:var(--input-text-color);flex-grow:1;padding:.5em .75em;resize:none}.message-textarea:focus{outline-color:var(--input-outline-focus-color)}.send-button{border-radius:var(--radius-md);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;padding:.5em 1em;transition-duration:.2s}.send-button-enabled{background-color:var(--send-button-bg-color);color:var(--send-button-text-color)}.send-button-enabled:hover{background-color:var(--send-button-bg-hover-color)}.send-button-disabled{background-color:var(--send-button-bg-disabled-color);color:var(--send-button-text-disabled-color);cursor:not-allowed}.confirmation-overlay{align-items:center;background-color:var(--confirmation-overlay-bg-color);display:flex;inset:calc(var(--spacing)*0);justify-content:center;position:fixed;z-index:9999}.confirmation-dialog{background-color:var(--confirmation-dialog-bg-color);border:1px solid var(--confirmation-dialog-border-color);border-radius:.75em;box-shadow:0 .625em 1.5625em var(--confirmation-dialog-shadow-color);margin-inline:calc(var(--spacing)*4);max-width:var(--container-sm);width:100%}.confirmation-content{padding:1.5em}.confirmation-title{margin-bottom:calc(var(--spacing)*2);--tw-font-weight:var(--font-weight-semibold);color:var(--confirmation-title-color);font-size:var(--confirmation-title-font-size);font-weight:var(--font-weight-semibold)}.confirmation-message{color:var(--confirmation-message-color);font-size:var(--confirmation-message-font-size);margin-bottom:calc(var(--spacing)*4)}.confirmation-buttons{display:flex;gap:.75em;justify-content:flex-end}.confirmation-button{border-radius:var(--radius-md);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;padding:.5em 1em;transition-duration:.2s}.confirmation-button-cancel{background-color:var(--confirmation-button-cancel-bg-color);color:var(--confirmation-button-cancel-text-color)}.confirmation-button-cancel:hover{background-color:var(--confirmation-button-cancel-bg-hover-color)}.confirmation-button-confirm{background-color:var(--confirmation-button-confirm-bg-color);color:var(--confirmation-button-confirm-text-color)}.confirmation-button-confirm:hover{background-color:var(--confirmation-button-confirm-bg-hover-color)}}@layer utilities{:host{--chat-z-index:50;--button-background-color:#fff;--button-background-color-hover:#f3f4f6;--button-text-color:#111827;--button-text-color-hover:#1d4ed8;--button-border-color:#d1d5db;--button-border-color-hover:#6b7280;--button-font-size:1em;--button-icon-size:1.5em;--chat-window-height:60%;--chat-window-width:25%;--chat-window-fullscreen-width:80%;--chat-window-bg-color:#fff;--chat-window-border-color:#d1d5db;--chat-window-shadow-color:#0000001a;--chat-window-font-size:.875em;--chat-window-font-size-sm:.75em;--header-bg-color:transparent;--header-bg-hover-color:#f9fafb;--header-border-color:#f3f4f6;--header-button-text-color:#6b7280;--header-button-bg-hover-color:#f3f4f6;--header-font-size:1em;--header-text-font-size:1em;--header-text-color:#525762;--header-button-icon-size:1.5em;--starter-question-bg-color:transparent;--starter-question-bg-hover-color:#eff6ff;--starter-question-text-color:#3b82f6;--starter-question-border-color:#3b82f6;--starter-question-border-hover-color:#2563eb;--message-user-bg-color:#e4edfb;--message-user-text-color:#1f2937;--message-user-link-color:#155dfc;--message-assistant-bg-color:#eae7e8;--message-assistant-text-color:var(--message-user-text-color);--message-assistant-link-color:var(--message-user-link-color);--message-system-bg-color:#fbe4f8;--message-system-text-color:var(--message-user-text-color);--message-system-link-color:var(--message-user-link-color);--message-timestamp-color:#ffffffb3;--message-timestamp-assistant-color:#4b5563b3;--input-bg-color:transparent;--input-border-color:#d1d5db;--input-text-color:#111827;--input-placeholder-color:#6b7280;--input-outline-focus-color:#3b82f6;--send-button-bg-color:#3b82f6;--send-button-bg-hover-color:#2563eb;--send-button-text-color:#fff;--send-button-bg-disabled-color:#d1d5db;--send-button-text-disabled-color:#6b7280;--loading-text-color:#6b7280;--loading-spinner-track-color:#e5e7eb;--loading-spinner-fill-color:#3b82f6;--loading-spinner-size:1.25em;--typing-progress-bg-color:#ade3ff;--scrollbar-track-color:#f3f4f6;--scrollbar-thumb-color:#d1d5db;--scrollbar-thumb-hover-color:#9ca3af;--error-text-color:#ef4444;--success-text-color:#10b981;--code-bg-user-color:var(--message-user-bg-color);--code-text-user-color:var(--message-user-text-color);--code-border-user-color:var(--message-user-bg-color);--code-bg-assistant-color:var(--message-assistant-bg-color);--code-text-assistant-color:var(--message-assistant-text-color);--code-border-assistant-color:var(--message-assistant-bg-color);--confirmation-overlay-bg-color:#00000080;--confirmation-dialog-bg-color:var(--chat-window-bg-color);--confirmation-dialog-border-color:var(--chat-window-border-color);--confirmation-dialog-shadow-color:var(--chat-window-shadow-color);--confirmation-title-color:#111827;--confirmation-title-font-size:1.125em;--confirmation-message-color:var(--loading-text-color);--confirmation-message-font-size:1em;--confirmation-button-cancel-bg-color:var(--button-background-color-hover);--confirmation-button-cancel-bg-hover-color:#e5e7eb;--confirmation-button-cancel-text-color:var(--header-button-text-color);--confirmation-button-confirm-bg-color:var(--error-text-color);--confirmation-button-confirm-bg-hover-color:var(--error-text-color);--confirmation-button-confirm-text-color:var(--send-button-text-color);--file-attachment-button-bg-color:transparent;--file-attachment-button-bg-hover-color:var(--header-button-bg-hover-color);--file-attachment-button-text-color:var(--header-button-text-color);--file-attachment-button-text-disabled-color:var(--send-button-text-disabled-color);--selected-files-bg-color:var(--chat-window-bg-color);--selected-files-border-color:var(--header-border-color);--selected-file-bg-color:var(--message-system-bg-color);--selected-file-font-size:var(--chat-window-font-size-sm);--selected-file-name-color:var(--message-assistant-text-color);--selected-file-size-color:var(--input-placeholder-color);--selected-file-icon-size:1.25em;--selected-file-remove-icon-color:var(--error-text-color);--selected-file-remove-icon-hover-color:#dc2626;--message-attachment-icon-size:1em;bottom:30px;display:block;position:fixed;right:30px}@supports (color:color-mix(in lab,red,red)){:host{--code-bg-user-color:color-mix(in srgb,var(--message-user-bg-color)80%,#fff 20%);--code-border-user-color:color-mix(in srgb,var(--message-user-bg-color)90%,#000 10%);--code-bg-assistant-color:color-mix(in srgb,var(--message-assistant-bg-color)50%,#fff 50%);--code-border-assistant-color:color-mix(in srgb,var(--message-assistant-bg-color)90%,#000 10%)}}}textarea{max-height:calc(var(--spacing)*32);min-height:calc(var(--spacing)*10);overflow-y:auto;resize:none}.loading-spinner{animation:var(--animate-spin);border-color:var(--loading-spinner-track-color);border-radius:3.40282e+38px;border-style:var(--tw-border-style);border-top-color:var(--loading-spinner-fill-color);border-width:2px;height:var(--loading-spinner-size);width:var(--loading-spinner-size)}.overflow-y-auto::-webkit-scrollbar{height:calc(var(--spacing)*1.5);width:calc(var(--spacing)*1.5)}.overflow-y-auto::-webkit-scrollbar-track{background-color:var(--scrollbar-track-color);border-radius:var(--radius-sm)}.overflow-y-auto::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-color);border-radius:var(--radius-sm)}.overflow-y-auto::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover-color)}.chat-markdown{color:var(--tw-prose-body);font-size:1rem;font-size:.875rem;line-height:1.75;line-height:1.71429;max-width:65ch;--tw-prose-body:oklch(37.3% .034 259.733);--tw-prose-headings:oklch(21% .034 264.665);--tw-prose-lead:oklch(44.6% .03 256.802);--tw-prose-links:oklch(21% .034 264.665);--tw-prose-bold:oklch(21% .034 264.665);--tw-prose-counters:oklch(55.1% .027 264.364);--tw-prose-bullets:oklch(87.2% .01 258.338);--tw-prose-hr:oklch(92.8% .006 264.531);--tw-prose-quotes:oklch(21% .034 264.665);--tw-prose-quote-borders:oklch(92.8% .006 264.531);--tw-prose-captions:oklch(55.1% .027 264.364);--tw-prose-kbd:oklch(21% .034 264.665);--tw-prose-kbd-shadows:NaN NaN NaN;--tw-prose-code:oklch(21% .034 264.665);--tw-prose-pre-code:oklch(92.8% .006 264.531);--tw-prose-pre-bg:oklch(27.8% .033 256.848);--tw-prose-th-borders:oklch(87.2% .01 258.338);--tw-prose-td-borders:oklch(92.8% .006 264.531);--tw-prose-invert-body:oklch(87.2% .01 258.338);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.7% .022 261.325);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.7% .022 261.325);--tw-prose-invert-bullets:oklch(44.6% .03 256.802);--tw-prose-invert-hr:oklch(37.3% .034 259.733);--tw-prose-invert-quotes:oklch(96.7% .003 264.542);--tw-prose-invert-quote-borders:oklch(37.3% .034 259.733);--tw-prose-invert-captions:oklch(70.7% .022 261.325);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:255 255 255;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87.2% .01 258.338);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(44.6% .03 256.802);--tw-prose-invert-td-borders:oklch(37.3% .034 259.733);font-size:1em;max-width:none}.chat-markdown :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;font-size:1.28571em;line-height:1.6;line-height:1.55556;margin-bottom:.888889em;margin-top:.888889em}.chat-markdown :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline;text-decoration-line:none}.chat-markdown :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.chat-markdown :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.chat-markdown :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-bottom:1.25em;margin-top:1.25em;padding-inline-start:1.625em}.chat-markdown :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.chat-markdown :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.chat-markdown :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.chat-markdown :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.chat-markdown :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.chat-markdown :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.chat-markdown :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.chat-markdown :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.chat-markdown :where(ol[type=\"1\"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.chat-markdown :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-bottom:1.25em;margin-top:1.25em;padding-inline-start:1.625em}.chat-markdown :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.chat-markdown :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.chat-markdown :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.14286em}.chat-markdown :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-bottom:2.85714em;margin-top:2.85714em}.chat-markdown :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){border-inline-start-color:var(--tw-prose-quote-borders);border-inline-start-width:.25rem;color:var(--tw-prose-quotes);font-style:italic;font-weight:500;margin-bottom:1.33333em;margin-top:1.33333em;padding-inline-start:1em;padding-inline-start:1.11111em;quotes:\"\u201C\"\"\u201D\"\"\u2018\"\"\u2019\"}.chat-markdown :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.chat-markdown :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.chat-markdown :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-size:2.25em;font-size:2.14286em;font-weight:800;line-height:1.11111;line-height:1.2;margin-bottom:.8em;margin-top:0}.chat-markdown :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.chat-markdown :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-size:1.5em;font-size:1.42857em;font-weight:700;line-height:1.33333;line-height:1.4;margin-bottom:.8em;margin-top:1.6em}.chat-markdown :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.chat-markdown :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-size:1.25em;font-size:1.28571em;font-weight:600;line-height:1.6;line-height:1.55556;margin-bottom:.444444em;margin-top:1.55556em}.chat-markdown :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.chat-markdown :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;line-height:1.5;line-height:1.42857;margin-bottom:.571429em;margin-top:1.42857em}.chat-markdown :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.chat-markdown :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-bottom:2em;margin-top:2em}.chat-markdown :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){border-radius:.3125rem;box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows)/10%),0 3px 0 rgb(var(--tw-prose-kbd-shadows)/10%);color:var(--tw-prose-kbd);font-family:inherit;font-size:.875em;font-size:.857143em;font-weight:500;padding-inline-end:.375em;padding-inline-end:.357143em;padding-bottom:.142857em;padding-inline-start:.375em;padding-top:.142857em;padding-inline-start:.357143em}.chat-markdown :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-size:.857143em;font-weight:600}.chat-markdown :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after,.chat-markdown :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:\"\\`\"}.chat-markdown :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.chat-markdown :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em;font-size:.9em}.chat-markdown :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em;font-size:.888889em}.chat-markdown :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.chat-markdown :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:var(--tw-prose-pre-bg);border-radius:.375rem;border-radius:.25rem;color:var(--tw-prose-pre-code);font-size:.875em;font-size:.857143em;font-weight:400;line-height:1.71429;line-height:1.66667;margin-bottom:1.66667em;margin-top:1.66667em;overflow-x:auto;padding-inline-end:1.14286em;padding-inline-end:1em;padding-bottom:.666667em;padding-inline-start:1.14286em;padding-top:.666667em;padding-inline-start:1em}.chat-markdown :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:#0000;border-radius:0;border-width:0;color:inherit;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit;padding:0}.chat-markdown :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after,.chat-markdown :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.chat-markdown :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;font-size:.857143em;line-height:1.71429;line-height:1.5;margin-bottom:2em;margin-top:2em;table-layout:auto;width:100%}.chat-markdown :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-color:var(--tw-prose-th-borders);border-bottom-width:1px}.chat-markdown :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;padding-inline-end:.571429em;padding-inline-end:1em;padding-bottom:.666667em;padding-inline-start:.571429em;padding-inline-start:1em;vertical-align:bottom}.chat-markdown :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-color:var(--tw-prose-td-borders);border-bottom-width:1px}.chat-markdown :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.chat-markdown :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.chat-markdown :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-color:var(--tw-prose-th-borders);border-top-width:1px}.chat-markdown :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.chat-markdown :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.chat-markdown :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;font-size:.857143em;line-height:1.42857;line-height:1.33333;margin-top:.666667em}.chat-markdown :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:.75em;margin-top:.75em}.chat-markdown :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.chat-markdown :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.chat-markdown :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.chat-markdown :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.chat-markdown :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.chat-markdown :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.chat-markdown :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em;margin-top:1.14286em}.chat-markdown :where(img):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.71429em;margin-top:1.71429em}.chat-markdown :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0;margin-top:0}.chat-markdown :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.71429em;margin-top:1.71429em}.chat-markdown :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em;margin-top:1.14286em;padding-inline-start:1.57143em}.chat-markdown :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:.285714em;margin-top:.285714em}.chat-markdown :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.428571em}.chat-markdown :where(.prose-sm>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:.571429em;margin-top:.571429em}.chat-markdown :where(.prose-sm>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.14286em}.chat-markdown :where(.prose-sm>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em}.chat-markdown :where(.prose-sm>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.14286em}.chat-markdown :where(.prose-sm>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em}.chat-markdown :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:.571429em;margin-top:.571429em}.chat-markdown :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em;margin-top:1.14286em}.chat-markdown :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.285714em;padding-inline-start:1.57143em}.chat-markdown :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.chat-markdown :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.chat-markdown :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.chat-markdown :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:1em;padding-bottom:.666667em;padding-top:.666667em;padding-inline-start:1em}.chat-markdown :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.chat-markdown :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.chat-markdown :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.71429em;margin-top:1.71429em}.chat-markdown :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0;margin-top:0}.chat-markdown :where(.prose-sm>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.chat-markdown :where(.prose-sm>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.chat-markdown>*{margin-bottom:.1em;margin-top:.1em}.message-bubble-assistant .chat-markdown{--tw-prose-body:var(--message-assistant-text-color);--tw-prose-headings:var(--message-assistant-text-color);--tw-prose-lead:var(--message-assistant-text-color);--tw-prose-links:var(--message-assistant-link-color);--tw-prose-bold:var(--message-assistant-text-color);--tw-prose-counters:var(--message-assistant-text-color);--tw-prose-bullets:var(--message-assistant-text-color);--tw-prose-hr:var(--message-assistant-text-color);--tw-prose-quotes:var(--message-assistant-text-color);--tw-prose-quote-borders:var(--message-assistant-text-color);--tw-prose-captions:var(--message-assistant-text-color);--tw-prose-kbd:var(--message-assistant-text-color);--tw-prose-kbd-shadows:var(--message-assistant-text-color);--tw-prose-code:var(--code-text-assistant-color);--tw-prose-pre-code:var(--code-text-assistant-color);--tw-prose-pre-bg:var(--code-bg-assistant-color);--tw-prose-th-borders:var(--message-assistant-text-color);--tw-prose-td-borders:var(--message-assistant-text-color)}.message-bubble-user .chat-markdown{--tw-prose-body:var(--message-user-text-color);--tw-prose-headings:var(--message-user-text-color);--tw-prose-lead:var(--message-user-text-color);--tw-prose-links:var(--message-user-link-color);--tw-prose-bold:var(--message-user-text-color);--tw-prose-counters:var(--message-user-text-color);--tw-prose-bullets:var(--message-user-text-color);--tw-prose-hr:var(--message-user-text-color);--tw-prose-quotes:var(--message-user-text-color);--tw-prose-quote-borders:var(--message-user-text-color);--tw-prose-captions:var(--message-user-text-color);--tw-prose-kbd:var(--message-user-text-color);--tw-prose-kbd-shadows:var(--message-user-text-color);--tw-prose-code:var(--code-text-user-color);--tw-prose-pre-code:var(--code-text-user-color);--tw-prose-pre-bg:var(--code-bg-user-color);--tw-prose-th-borders:var(--message-user-text-color);--tw-prose-td-borders:var(--message-user-text-color)}.message-bubble-system .chat-markdown{--tw-prose-body:var(--message-system-text-color);--tw-prose-headings:var(--message-system-text-color);--tw-prose-lead:var(--message-system-text-color);--tw-prose-links:var(--message-system-link-color);--tw-prose-bold:var(--message-system-text-color);--tw-prose-counters:var(--message-system-text-color);--tw-prose-bullets:var(--message-system-text-color);--tw-prose-hr:var(--message-system-text-color);--tw-prose-quotes:var(--message-system-text-color);--tw-prose-quote-borders:var(--message-system-text-color);--tw-prose-captions:var(--message-system-text-color);--tw-prose-kbd:var(--message-system-text-color);--tw-prose-kbd-shadows:var(--message-system-text-color);--tw-prose-code:var(--message-system-text-color);--tw-prose-pre-code:var(--message-system-text-color);--tw-prose-pre-bg:var(--message-system-text-color);--tw-prose-th-borders:var(--message-system-text-color);--tw-prose-td-borders:var(--message-system-text-color)}.message-bubble-user .chat-markdown pre{border:1px solid var(--code-border-user-color)}.message-bubble-assistant .chat-markdown pre{border:1px solid var(--code-border-assistant-color)}.loading:after{content:\" .\"}.file-attachment-button{border-radius:var(--radius-md);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;background-color:var(--file-attachment-button-bg-color);color:var(--file-attachment-button-text-color);padding:.375em;transition-duration:.2s}.file-attachment-button:disabled{color:var(--file-attachment-button-text-disabled-color);cursor:not-allowed;opacity:.5}.file-attachment-button svg{height:1.5em;width:1.5em}.file-attachment-button:hover:not(:disabled){background-color:var(--file-attachment-button-bg-hover-color)}.selected-files-container{background-color:var(--selected-files-bg-color);border-top:1px solid var(--selected-files-border-color);padding:1em 1em .5em}.selected-file-item{align-items:center;background-color:var(--selected-file-bg-color);border-radius:.375em;color:var(--selected-file-name-color);display:flex;font-size:var(--selected-file-font-size);justify-content:space-between;padding:.25em .5em}.selected-file-icon{align-items:center;display:flex;justify-content:center}.selected-file-icon svg{height:var(--selected-file-icon-size);width:var(--selected-file-icon-size)}.selected-file-size{color:var(--selected-file-size-color)}.selected-file-error{color:var(--error-text-color)}.selected-file-success-icon{align-items:center;color:var(--success-text-color);display:flex;height:var(--selected-file-icon-size);justify-content:center;width:var(--selected-file-icon-size)}.selected-file-remove-button{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;color:var(--selected-file-remove-icon-color);padding:.375em;transition-duration:.2s}.selected-file-remove-button svg{height:var(--selected-file-icon-size);width:var(--selected-file-icon-size)}.selected-file-remove-button:hover{color:var(--selected-file-remove-icon-hover-color)}.message-attachments{font-size:var(--chat-window-font-size-sm);margin-top:.5em}:where(.message-attachments>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(.25em*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(.25em*var(--tw-space-y-reverse))}.message-attachment-icon{align-items:center;display:flex;height:var(--message-attachment-icon-size);justify-content:center;width:var(--message-attachment-icon-size)}.send-button-disabled{background-color:var(--send-button-bg-disabled-color);color:var(--send-button-text-disabled-color);cursor:not-allowed}@property --tw-rotate-x{syntax:\"*\";inherits:false}@property --tw-rotate-y{syntax:\"*\";inherits:false}@property --tw-rotate-z{syntax:\"*\";inherits:false}@property --tw-skew-x{syntax:\"*\";inherits:false}@property --tw-skew-y{syntax:\"*\";inherits:false}@property --tw-space-y-reverse{syntax:\"*\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:\"*\";inherits:false}@property --tw-ease{syntax:\"*\";inherits:false}@property --tw-scale-x{syntax:\"*\";inherits:false;initial-value:1}@property --tw-scale-y{syntax:\"*\";inherits:false;initial-value:1}@property --tw-scale-z{syntax:\"*\";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(1turn)}}@keyframes progress{0%{transform:translate(0)scaleX(0)}10%{transform:translate(0)scaleX(.3)}50%{transform:translate(100%)scaleX(.3)}90%{transform:translate(0)scaleX(.3)}to{transform:translate(0)scaleX(0)}}@keyframes dots{0%,20%{color:#0000;text-shadow:.25em 0 #0000,.5em 0 #0000}40%{color:#000;text-shadow:.25em 0 #0000,.5em 0 #0000}60%{text-shadow:.25em 0 #000,.5em 0 #0000}80%,to{text-shadow:.25em 0 #000,.5em 0 #000}}@media (min-width:40rem){.container{max-width:40rem}.chat-window-normal{height:var(--chat-window-height);width:var(--chat-window-width)}.drag-indicator{display:flex}.fullscreen-button{display:block}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}@media (hover:hover){.chat-btn-icon:hover,.chat-btn-text:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.attachment-link:hover{text-decoration-line:none}.chat-markdown :where(a):not(:where([class~=not-prose],[class~=not-prose] *)):hover{text-decoration-line:underline}}";
|
|
5296
|
+
const ocsChatCss = "/*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */@layer properties{@supports ((-webkit-hyphens:none) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,::backdrop,:after,:before{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:host,:root{--font-sans:ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;--color-blue-300:oklch(80.9% .105 251.813);--color-slate-500:oklch(55.4% .046 257.417);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--spacing:.25rem;--breakpoint-lg:64rem;--container-sm:24rem;--font-weight-light:300;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--animate-progress:progress 3s infinite linear;--animate-dots:dots 1s steps(5,end)infinite;--transform-origin-left-right:0% 50%}}@layer base{*,::backdrop,:after,:before{border:0 solid;border-color:var(--color-gray-200,currentcolor);box-sizing:border-box;margin:0;padding:0}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button;background-color:#0000;border:0 solid;border-color:var(--color-gray-200,currentcolor);border-radius:0;box-sizing:border-box;color:inherit;font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;margin:0;margin-inline-end:4px;opacity:1;padding:0}:host,html{-webkit-text-size-adjust:100%;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-size:1em;font-variation-settings:var(--default-mono-font-variation-settings,normal)}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}menu,ol,ul{list-style:none}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}button,input,optgroup,select,textarea{background-color:#0000;border-radius:0;color:inherit;font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;opacity:1}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::-moz-placeholder{opacity:1}::placeholder{opacity:1}@supports (not (-webkit-appearance:-apple-pay-button)) or (contain-intrinsic-size:1px){::-moz-placeholder{color:currentColor}::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::-moz-placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex;padding-block:0}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.static{position:static}.container{width:100%}.block{display:block}.contents{display:contents}.flex{display:flex}.hidden{display:none}.w-full{width:100%}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.resize{resize:both}.items-center{align-items:center}.justify-center{justify-content:center}.gap-\\[0\\.5em\\]{gap:.5em}:where(.space-y-\\[0\\.25em\\]>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(.25em*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(.25em*var(--tw-space-y-reverse))}.border{border-style:var(--tw-border-style);border-width:1px}.py-\\[2px\\]{padding-block:2px}.text-\\[0\\.8em\\]{font-size:.8em}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.text-slate-500{color:var(--color-slate-500)}.underline{text-decoration-line:underline}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a)}.ring,.shadow{box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor)}} /*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */@layer properties{}@layer base{}@layer components; /*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */@layer properties{}@layer base{}@layer components{#ocs-chat-window{font-size:var(--chat-window-font-size);z-index:var(--chat-z-index)}.starter-question{border-radius:var(--radius-lg);text-align:left;--tw-duration:.2s;background-color:var(--starter-question-bg-color);border:1px solid var(--starter-question-border-color);color:var(--starter-question-text-color);padding:.75em;transition-duration:.2s}.starter-question:hover{background-color:var(--starter-question-bg-hover-color);border-color:var(--starter-question-border-hover-color)}.chat-btn-text{border-radius:var(--radius-lg);border-style:var(--tw-border-style);transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,);--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;--tw-ease:var(--ease-in-out);align-items:center;background-color:var(--button-background-color,#fff);border-width:0;border:1px solid var(--button-border-color);color:var(--button-text-color,#111827);display:flex;font-size:var(--button-font-size);gap:8px;padding:.5em;transition-duration:.2s;transition-timing-function:var(--ease-in-out);z-index:var(--chat-z-index,50)}.chat-btn-text:hover{border:1px solid var(--button-border-color-hover);color:var(--button-text-color-hover,#1d4ed8)}.chat-btn-text span{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap}.chat-btn-text img{flex-shrink:0;height:var(--button-icon-size);-o-object-fit:contain;object-fit:contain;width:var(--button-icon-size)}.chat-btn-text.round{border-radius:3.40282e+38px}.chat-btn-icon{border-radius:var(--radius-lg);border-style:var(--tw-border-style);transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,);--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;--tw-ease:var(--ease-in-out);background-color:var(--button-background-color,#fff);border-width:0;border:1px solid var(--button-border-color);font-size:var(--button-font-size);padding:.5em;transition-duration:.2s;transition-timing-function:var(--ease-in-out);z-index:var(--chat-z-index,50)}.chat-btn-icon:hover{border:1px solid var(--button-border-color-hover);color:var(--button-text-color-hover,#1d4ed8)}.chat-btn-icon img{height:var(--button-icon-size);-o-object-fit:contain;object-fit:contain;width:var(--button-icon-size)}.chat-btn-icon.round,.round .chat-btn-icon,.round.chat-btn-text{border-radius:3.40282e+38px}.error-message{color:var(--error-text-color);padding:.5em}.chat-window-fullscreen{border-style:var(--tw-border-style);inset:calc(var(--spacing)*0);z-index:9999;--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);height:100%;max-height:100%;transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));width:100%;--tw-duration:.2s;border-radius:0;border-width:0;max-width:var(--chat-window-fullscreen-width);transition-duration:.2s}.chat-window-fullscreen,.chat-window-normal{background-color:var(--chat-window-bg-color);display:flex;flex-direction:column;overflow:hidden;position:fixed}.chat-window-normal{border:1px solid var(--chat-window-border-color);border-radius:var(--radius-lg);height:100vh;max-width:var(--breakpoint-lg);min-height:300px;min-width:300px;width:100vw}.chat-window-normal:not(.chat-window-dragging){--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;transition-duration:.2s}.chat-window-dragging,.chat-window-normal:not(.chat-window-dragging){box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.chat-window-dragging{cursor:grabbing;--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040)}.chat-window-kiosk{background-color:var(--chat-window-bg-color);border-radius:0;box-shadow:none;display:flex;flex-direction:column;font-size:var(--chat-window-font-size);height:100%;inset:calc(var(--spacing)*0);overflow:hidden;position:absolute;width:100%;z-index:var(--chat-z-index)}.chat-header{transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.15s;align-items:center;background-color:var(--header-bg-color);border-bottom:1px solid var(--header-border-color);display:flex;font-size:var(--header-font-size);justify-content:space-between;padding:.5em;transition-duration:.15s}.chat-header:active,.chat-header:hover{background-color:var(--header-bg-hover-color)}.header-text{align-items:center;color:var(--header-text-color);display:flex;font-size:var(--header-text-font-size);justify-content:center}.chat-header-draggable{cursor:grab}.chat-header-dragging{cursor:grabbing}.drag-indicator{display:none}.drag-dots{display:flex;gap:2px;margin-left:2px;pointer-events:none}.header-buttons{align-items:center;display:flex;gap:4px}.header-button{border-radius:var(--radius-md);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;color:var(--header-button-text-color);padding:.375em;transition-duration:.2s}.header-button svg{height:var(--header-button-icon-size);width:var(--header-button-icon-size)}.header-button:hover{background-color:var(--header-button-bg-hover-color)}.fullscreen-button{display:none}.chat-content{display:flex;flex-direction:column;flex-grow:1;overflow:hidden}.loading-container{align-items:center;display:flex;flex-grow:1;justify-content:center}.loading-text{color:var(--loading-text-color);margin-left:2px}.messages-container{flex-grow:1;overflow-y:auto;padding:1em}:where(.messages-container>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(var(--spacing)*2*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(var(--spacing)*2*var(--tw-space-y-reverse))}.message-row{display:flex}.message-row-user{justify-content:flex-end}.message-row-assistant{justify-content:flex-start}.message-bubble{border-radius:var(--radius-lg);padding:.5em 1em}.message-bubble-user{background-color:var(--message-user-bg-color);color:var(--message-user-text-color)}.message-bubble-assistant{background-color:var(--message-assistant-bg-color);color:var(--message-assistant-text-color)}.message-bubble-system{background-color:var(--message-system-bg-color);color:var(--message-system-text-color)}.message-timestamp{font-size:var(--chat-window-font-size-sm);margin-top:4px;opacity:.7}.message-attachments{margin-top:8px}:where(.message-attachments>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(var(--spacing)*1*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(var(--spacing)*1*var(--tw-space-y-reverse))}.attachment-link{display:block;text-decoration-line:underline}:where(.welcome-messages>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(var(--spacing)*2*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(var(--spacing)*2*var(--tw-space-y-reverse))}.typing-indicator{height:calc(var(--spacing)*1.5);overflow:hidden;width:100%}.typing-progress{animation:var(--animate-progress);background-color:var(--typing-progress-bg-color);border-radius:var(--radius-lg);height:100%;transform-origin:var(--transform-origin-left-right);width:100%}.typing-text{font-size:var(--chat-window-font-size-sm);justify-content:center;opacity:.7;width:100%}.typing-dots{animation:var(--animate-dots)}:where(.starter-questions>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(var(--spacing)*2*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(var(--spacing)*2*var(--tw-space-y-reverse))}.starter-questions{padding:1em}.starter-question-row{display:flex;justify-content:flex-end}.input-area{background-color:var(--input-bg-color);border-top:1px solid var(--input-border-color);padding:1em 1em 0}.input-container{display:flex;gap:8px}.message-textarea{background-color:var(--input-bg-color);border-color:var(--color-gray-300);border-radius:var(--radius-md);border-style:var(--tw-border-style);border-width:1px;border:1px solid var(--input-border-color);color:var(--input-text-color);flex-grow:1;padding:.5em .75em;resize:none}.message-textarea:focus{outline-color:var(--input-outline-focus-color)}.send-button{border-radius:var(--radius-md);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;padding:.5em 1em;transition-duration:.2s}.send-button-enabled{background-color:var(--send-button-bg-color);color:var(--send-button-text-color)}.send-button-enabled:hover{background-color:var(--send-button-bg-hover-color)}.send-button-disabled{background-color:var(--send-button-bg-disabled-color);color:var(--send-button-text-disabled-color);cursor:not-allowed}.confirmation-overlay{align-items:center;background-color:var(--confirmation-overlay-bg-color);display:flex;inset:calc(var(--spacing)*0);justify-content:center;position:fixed;z-index:9999}.confirmation-dialog{background-color:var(--confirmation-dialog-bg-color);border:1px solid var(--confirmation-dialog-border-color);border-radius:.75em;box-shadow:0 .625em 1.5625em var(--confirmation-dialog-shadow-color);margin-inline:calc(var(--spacing)*4);max-width:var(--container-sm);width:100%}.confirmation-content{padding:1.5em}.confirmation-title{margin-bottom:calc(var(--spacing)*2);--tw-font-weight:var(--font-weight-semibold);color:var(--confirmation-title-color);font-size:var(--confirmation-title-font-size);font-weight:var(--font-weight-semibold)}.confirmation-message{color:var(--confirmation-message-color);font-size:var(--confirmation-message-font-size);margin-bottom:calc(var(--spacing)*4)}.confirmation-buttons{display:flex;gap:.75em;justify-content:flex-end}.confirmation-button{border-radius:var(--radius-md);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;padding:.5em 1em;transition-duration:.2s}.confirmation-button-cancel{background-color:var(--confirmation-button-cancel-bg-color);color:var(--confirmation-button-cancel-text-color)}.confirmation-button-cancel:hover{background-color:var(--confirmation-button-cancel-bg-hover-color)}.confirmation-button-confirm{background-color:var(--confirmation-button-confirm-bg-color);color:var(--confirmation-button-confirm-text-color)}.confirmation-button-confirm:hover{background-color:var(--confirmation-button-confirm-bg-hover-color)}}@layer utilities{:host{--chat-z-index:50;--button-background-color:#fff;--button-background-color-hover:#f3f4f6;--button-text-color:#111827;--button-text-color-hover:#1d4ed8;--button-border-color:#d1d5db;--button-border-color-hover:#6b7280;--button-font-size:1em;--button-icon-size:1.5em;--chat-window-height:60%;--chat-window-width:25%;--chat-window-fullscreen-width:80%;--chat-window-bg-color:#fff;--chat-window-border-color:#d1d5db;--chat-window-shadow-color:#0000001a;--chat-window-font-size:.875em;--chat-window-font-size-sm:.75em;--header-bg-color:transparent;--header-bg-hover-color:#f9fafb;--header-border-color:#f3f4f6;--header-button-text-color:#6b7280;--header-button-bg-hover-color:#f3f4f6;--header-font-size:1em;--header-text-font-size:1em;--header-text-color:#525762;--header-button-icon-size:1.5em;--starter-question-bg-color:transparent;--starter-question-bg-hover-color:#eff6ff;--starter-question-text-color:#3b82f6;--starter-question-border-color:#3b82f6;--starter-question-border-hover-color:#2563eb;--message-user-bg-color:#e4edfb;--message-user-text-color:#1f2937;--message-user-link-color:#155dfc;--message-assistant-bg-color:#eae7e8;--message-assistant-text-color:var(--message-user-text-color);--message-assistant-link-color:var(--message-user-link-color);--message-system-bg-color:#fbe4f8;--message-system-text-color:var(--message-user-text-color);--message-system-link-color:var(--message-user-link-color);--message-timestamp-color:#ffffffb3;--message-timestamp-assistant-color:#4b5563b3;--input-bg-color:transparent;--input-border-color:#d1d5db;--input-text-color:#111827;--input-placeholder-color:#6b7280;--input-outline-focus-color:#3b82f6;--send-button-bg-color:#3b82f6;--send-button-bg-hover-color:#2563eb;--send-button-text-color:#fff;--send-button-bg-disabled-color:#d1d5db;--send-button-text-disabled-color:#6b7280;--loading-text-color:#6b7280;--loading-spinner-track-color:#e5e7eb;--loading-spinner-fill-color:#3b82f6;--loading-spinner-size:1.25em;--typing-progress-bg-color:#ade3ff;--scrollbar-track-color:#f3f4f6;--scrollbar-thumb-color:#d1d5db;--scrollbar-thumb-hover-color:#9ca3af;--error-text-color:#ef4444;--success-text-color:#10b981;--code-bg-user-color:var(--message-user-bg-color);--code-text-user-color:var(--message-user-text-color);--code-border-user-color:var(--message-user-bg-color);--code-bg-assistant-color:var(--message-assistant-bg-color);--code-text-assistant-color:var(--message-assistant-text-color);--code-border-assistant-color:var(--message-assistant-bg-color);--confirmation-overlay-bg-color:#00000080;--confirmation-dialog-bg-color:var(--chat-window-bg-color);--confirmation-dialog-border-color:var(--chat-window-border-color);--confirmation-dialog-shadow-color:var(--chat-window-shadow-color);--confirmation-title-color:#111827;--confirmation-title-font-size:1.125em;--confirmation-message-color:var(--loading-text-color);--confirmation-message-font-size:1em;--confirmation-button-cancel-bg-color:var(--button-background-color-hover);--confirmation-button-cancel-bg-hover-color:#e5e7eb;--confirmation-button-cancel-text-color:var(--header-button-text-color);--confirmation-button-confirm-bg-color:var(--error-text-color);--confirmation-button-confirm-bg-hover-color:var(--error-text-color);--confirmation-button-confirm-text-color:var(--send-button-text-color);--file-attachment-button-bg-color:transparent;--file-attachment-button-bg-hover-color:var(--header-button-bg-hover-color);--file-attachment-button-text-color:var(--header-button-text-color);--file-attachment-button-text-disabled-color:var(--send-button-text-disabled-color);--selected-files-bg-color:var(--chat-window-bg-color);--selected-files-border-color:var(--header-border-color);--selected-file-bg-color:var(--button-background-color-hover);--selected-file-font-size:var(--chat-window-font-size-sm);--selected-file-name-color:var(--message-assistant-text-color);--selected-file-size-color:var(--input-placeholder-color);--selected-file-icon-size:1.25em;--selected-file-remove-icon-color:var(--error-text-color);--selected-file-remove-icon-hover-color:#dc2626;--message-attachment-icon-size:1em;bottom:30px;display:block;position:fixed;right:30px}@supports (color:color-mix(in lab,red,red)){:host{--code-bg-user-color:color-mix(in srgb,var(--message-user-bg-color)80%,#fff 20%);--code-border-user-color:color-mix(in srgb,var(--message-user-bg-color)90%,#000 10%);--code-bg-assistant-color:color-mix(in srgb,var(--message-assistant-bg-color)50%,#fff 50%);--code-border-assistant-color:color-mix(in srgb,var(--message-assistant-bg-color)90%,#000 10%)}}:host([mode=kiosk]){height:100%;inset:0 auto auto 0;position:absolute;width:100%}}textarea{max-height:calc(var(--spacing)*32);min-height:calc(var(--spacing)*10);overflow-y:auto;resize:none}.loading-spinner{animation:var(--animate-spin);border-color:var(--loading-spinner-track-color);border-radius:3.40282e+38px;border-style:var(--tw-border-style);border-top-color:var(--loading-spinner-fill-color);border-width:2px;height:var(--loading-spinner-size);width:var(--loading-spinner-size)}.overflow-y-auto::-webkit-scrollbar{height:calc(var(--spacing)*1.5);width:calc(var(--spacing)*1.5)}.overflow-y-auto::-webkit-scrollbar-track{background-color:var(--scrollbar-track-color);border-radius:var(--radius-sm)}.overflow-y-auto::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-color);border-radius:var(--radius-sm)}.overflow-y-auto::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover-color)}.chat-markdown{color:var(--tw-prose-body);font-size:1rem;font-size:.875rem;line-height:1.75;line-height:1.71429;max-width:65ch;--tw-prose-body:oklch(37.3% .034 259.733);--tw-prose-headings:oklch(21% .034 264.665);--tw-prose-lead:oklch(44.6% .03 256.802);--tw-prose-links:oklch(21% .034 264.665);--tw-prose-bold:oklch(21% .034 264.665);--tw-prose-counters:oklch(55.1% .027 264.364);--tw-prose-bullets:oklch(87.2% .01 258.338);--tw-prose-hr:oklch(92.8% .006 264.531);--tw-prose-quotes:oklch(21% .034 264.665);--tw-prose-quote-borders:oklch(92.8% .006 264.531);--tw-prose-captions:oklch(55.1% .027 264.364);--tw-prose-kbd:oklch(21% .034 264.665);--tw-prose-kbd-shadows:NaN NaN NaN;--tw-prose-code:oklch(21% .034 264.665);--tw-prose-pre-code:oklch(92.8% .006 264.531);--tw-prose-pre-bg:oklch(27.8% .033 256.848);--tw-prose-th-borders:oklch(87.2% .01 258.338);--tw-prose-td-borders:oklch(92.8% .006 264.531);--tw-prose-invert-body:oklch(87.2% .01 258.338);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.7% .022 261.325);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.7% .022 261.325);--tw-prose-invert-bullets:oklch(44.6% .03 256.802);--tw-prose-invert-hr:oklch(37.3% .034 259.733);--tw-prose-invert-quotes:oklch(96.7% .003 264.542);--tw-prose-invert-quote-borders:oklch(37.3% .034 259.733);--tw-prose-invert-captions:oklch(70.7% .022 261.325);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:255 255 255;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87.2% .01 258.338);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(44.6% .03 256.802);--tw-prose-invert-td-borders:oklch(37.3% .034 259.733);font-size:1em;max-width:none}.chat-markdown :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;font-size:1.28571em;line-height:1.6;line-height:1.55556;margin-bottom:.888889em;margin-top:.888889em}.chat-markdown :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline;text-decoration-line:none}.chat-markdown :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.chat-markdown :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.chat-markdown :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-bottom:1.25em;margin-top:1.25em;padding-inline-start:1.625em}.chat-markdown :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.chat-markdown :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.chat-markdown :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.chat-markdown :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.chat-markdown :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.chat-markdown :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.chat-markdown :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.chat-markdown :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.chat-markdown :where(ol[type=\"1\"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.chat-markdown :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-bottom:1.25em;margin-top:1.25em;padding-inline-start:1.625em}.chat-markdown :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.chat-markdown :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.chat-markdown :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.14286em}.chat-markdown :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-bottom:2.85714em;margin-top:2.85714em}.chat-markdown :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){border-inline-start-color:var(--tw-prose-quote-borders);border-inline-start-width:.25rem;color:var(--tw-prose-quotes);font-style:italic;font-weight:500;margin-bottom:1.33333em;margin-top:1.33333em;padding-inline-start:1em;padding-inline-start:1.11111em;quotes:\"\u201C\"\"\u201D\"\"\u2018\"\"\u2019\"}.chat-markdown :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.chat-markdown :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.chat-markdown :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-size:2.25em;font-size:2.14286em;font-weight:800;line-height:1.11111;line-height:1.2;margin-bottom:.8em;margin-top:0}.chat-markdown :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.chat-markdown :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-size:1.5em;font-size:1.42857em;font-weight:700;line-height:1.33333;line-height:1.4;margin-bottom:.8em;margin-top:1.6em}.chat-markdown :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.chat-markdown :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-size:1.25em;font-size:1.28571em;font-weight:600;line-height:1.6;line-height:1.55556;margin-bottom:.444444em;margin-top:1.55556em}.chat-markdown :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.chat-markdown :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;line-height:1.5;line-height:1.42857;margin-bottom:.571429em;margin-top:1.42857em}.chat-markdown :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.chat-markdown :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-bottom:2em;margin-top:2em}.chat-markdown :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){border-radius:.3125rem;box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows)/10%),0 3px 0 rgb(var(--tw-prose-kbd-shadows)/10%);color:var(--tw-prose-kbd);font-family:inherit;font-size:.875em;font-size:.857143em;font-weight:500;padding-inline-end:.375em;padding-inline-end:.357143em;padding-bottom:.142857em;padding-inline-start:.375em;padding-top:.142857em;padding-inline-start:.357143em}.chat-markdown :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-size:.857143em;font-weight:600}.chat-markdown :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after,.chat-markdown :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:\"\\`\"}.chat-markdown :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.chat-markdown :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em;font-size:.9em}.chat-markdown :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em;font-size:.888889em}.chat-markdown :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.chat-markdown :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:var(--tw-prose-pre-bg);border-radius:.375rem;border-radius:.25rem;color:var(--tw-prose-pre-code);font-size:.875em;font-size:.857143em;font-weight:400;line-height:1.71429;line-height:1.66667;margin-bottom:1.66667em;margin-top:1.66667em;overflow-x:auto;padding-inline-end:1.14286em;padding-inline-end:1em;padding-bottom:.666667em;padding-inline-start:1.14286em;padding-top:.666667em;padding-inline-start:1em}.chat-markdown :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:#0000;border-radius:0;border-width:0;color:inherit;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit;padding:0}.chat-markdown :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after,.chat-markdown :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.chat-markdown :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;font-size:.857143em;line-height:1.71429;line-height:1.5;margin-bottom:2em;margin-top:2em;table-layout:auto;width:100%}.chat-markdown :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-color:var(--tw-prose-th-borders);border-bottom-width:1px}.chat-markdown :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;padding-inline-end:.571429em;padding-inline-end:1em;padding-bottom:.666667em;padding-inline-start:.571429em;padding-inline-start:1em;vertical-align:bottom}.chat-markdown :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-color:var(--tw-prose-td-borders);border-bottom-width:1px}.chat-markdown :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.chat-markdown :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.chat-markdown :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-color:var(--tw-prose-th-borders);border-top-width:1px}.chat-markdown :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.chat-markdown :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.chat-markdown :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;font-size:.857143em;line-height:1.42857;line-height:1.33333;margin-top:.666667em}.chat-markdown :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:.75em;margin-top:.75em}.chat-markdown :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.chat-markdown :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.chat-markdown :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.chat-markdown :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.chat-markdown :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.chat-markdown :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.chat-markdown :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em;margin-top:1.14286em}.chat-markdown :where(img):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.71429em;margin-top:1.71429em}.chat-markdown :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0;margin-top:0}.chat-markdown :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.71429em;margin-top:1.71429em}.chat-markdown :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em;margin-top:1.14286em;padding-inline-start:1.57143em}.chat-markdown :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:.285714em;margin-top:.285714em}.chat-markdown :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.428571em}.chat-markdown :where(.prose-sm>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:.571429em;margin-top:.571429em}.chat-markdown :where(.prose-sm>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.14286em}.chat-markdown :where(.prose-sm>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em}.chat-markdown :where(.prose-sm>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.14286em}.chat-markdown :where(.prose-sm>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em}.chat-markdown :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:.571429em;margin-top:.571429em}.chat-markdown :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em;margin-top:1.14286em}.chat-markdown :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.285714em;padding-inline-start:1.57143em}.chat-markdown :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)),.chat-markdown :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.chat-markdown :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.chat-markdown :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.chat-markdown :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:1em;padding-bottom:.666667em;padding-top:.666667em;padding-inline-start:1em}.chat-markdown :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.chat-markdown :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.chat-markdown :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.71429em;margin-top:1.71429em}.chat-markdown :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0;margin-top:0}.chat-markdown :where(.prose-sm>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.chat-markdown :where(.prose-sm>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.chat-markdown>*{margin-bottom:.1em;margin-top:.1em}.message-bubble-assistant .chat-markdown{--tw-prose-body:var(--message-assistant-text-color);--tw-prose-headings:var(--message-assistant-text-color);--tw-prose-lead:var(--message-assistant-text-color);--tw-prose-links:var(--message-assistant-link-color);--tw-prose-bold:var(--message-assistant-text-color);--tw-prose-counters:var(--message-assistant-text-color);--tw-prose-bullets:var(--message-assistant-text-color);--tw-prose-hr:var(--message-assistant-text-color);--tw-prose-quotes:var(--message-assistant-text-color);--tw-prose-quote-borders:var(--message-assistant-text-color);--tw-prose-captions:var(--message-assistant-text-color);--tw-prose-kbd:var(--message-assistant-text-color);--tw-prose-kbd-shadows:var(--message-assistant-text-color);--tw-prose-code:var(--code-text-assistant-color);--tw-prose-pre-code:var(--code-text-assistant-color);--tw-prose-pre-bg:var(--code-bg-assistant-color);--tw-prose-th-borders:var(--message-assistant-text-color);--tw-prose-td-borders:var(--message-assistant-text-color)}.message-bubble-user .chat-markdown{--tw-prose-body:var(--message-user-text-color);--tw-prose-headings:var(--message-user-text-color);--tw-prose-lead:var(--message-user-text-color);--tw-prose-links:var(--message-user-link-color);--tw-prose-bold:var(--message-user-text-color);--tw-prose-counters:var(--message-user-text-color);--tw-prose-bullets:var(--message-user-text-color);--tw-prose-hr:var(--message-user-text-color);--tw-prose-quotes:var(--message-user-text-color);--tw-prose-quote-borders:var(--message-user-text-color);--tw-prose-captions:var(--message-user-text-color);--tw-prose-kbd:var(--message-user-text-color);--tw-prose-kbd-shadows:var(--message-user-text-color);--tw-prose-code:var(--code-text-user-color);--tw-prose-pre-code:var(--code-text-user-color);--tw-prose-pre-bg:var(--code-bg-user-color);--tw-prose-th-borders:var(--message-user-text-color);--tw-prose-td-borders:var(--message-user-text-color)}.message-bubble-system .chat-markdown{--tw-prose-body:var(--message-system-text-color);--tw-prose-headings:var(--message-system-text-color);--tw-prose-lead:var(--message-system-text-color);--tw-prose-links:var(--message-system-link-color);--tw-prose-bold:var(--message-system-text-color);--tw-prose-counters:var(--message-system-text-color);--tw-prose-bullets:var(--message-system-text-color);--tw-prose-hr:var(--message-system-text-color);--tw-prose-quotes:var(--message-system-text-color);--tw-prose-quote-borders:var(--message-system-text-color);--tw-prose-captions:var(--message-system-text-color);--tw-prose-kbd:var(--message-system-text-color);--tw-prose-kbd-shadows:var(--message-system-text-color);--tw-prose-code:var(--message-system-text-color);--tw-prose-pre-code:var(--message-system-text-color);--tw-prose-pre-bg:var(--message-system-text-color);--tw-prose-th-borders:var(--message-system-text-color);--tw-prose-td-borders:var(--message-system-text-color)}.message-bubble-user .chat-markdown pre{border:1px solid var(--code-border-user-color)}.message-bubble-assistant .chat-markdown pre{border:1px solid var(--code-border-assistant-color)}.loading:after{content:\" .\"}.file-attachment-button{border-radius:var(--radius-md);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;background-color:var(--file-attachment-button-bg-color);color:var(--file-attachment-button-text-color);padding:.375em;transition-duration:.2s}.file-attachment-button:disabled{color:var(--file-attachment-button-text-disabled-color);cursor:not-allowed;opacity:.5}.file-attachment-button svg{height:1.5em;width:1.5em}.file-attachment-button:hover:not(:disabled){background-color:var(--file-attachment-button-bg-hover-color)}.selected-files-container{background-color:var(--selected-files-bg-color);border-top:1px solid var(--selected-files-border-color);padding:1em 1em .5em}.selected-file-item{align-items:center;background-color:var(--selected-file-bg-color);border-radius:.375em;color:var(--selected-file-name-color);display:flex;font-size:var(--selected-file-font-size);justify-content:space-between;padding:.25em .5em}.selected-file-icon{align-items:center;display:flex;justify-content:center}.selected-file-icon svg{height:var(--selected-file-icon-size);width:var(--selected-file-icon-size)}.selected-file-size{color:var(--selected-file-size-color)}.selected-file-error{color:var(--error-text-color)}.selected-file-success-icon{align-items:center;color:var(--success-text-color);display:flex;height:var(--selected-file-icon-size);justify-content:center;width:var(--selected-file-icon-size)}.selected-file-remove-button{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);transition-duration:var(--tw-duration,var(--default-transition-duration));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));--tw-duration:.2s;color:var(--selected-file-remove-icon-color);padding:.375em;transition-duration:.2s}.selected-file-remove-button svg{height:var(--selected-file-icon-size);width:var(--selected-file-icon-size)}.selected-file-remove-button:hover{color:var(--selected-file-remove-icon-hover-color)}.message-attachments{font-size:var(--chat-window-font-size-sm);margin-top:.5em}:where(.message-attachments>:not(:last-child)){--tw-space-y-reverse:0;margin-block-end:calc(.25em*(1 - var(--tw-space-y-reverse)));margin-block-start:calc(.25em*var(--tw-space-y-reverse))}.message-attachment-icon{align-items:center;display:flex;height:var(--message-attachment-icon-size);justify-content:center;width:var(--message-attachment-icon-size)}.send-button-disabled{background-color:var(--send-button-bg-disabled-color);color:var(--send-button-text-disabled-color);cursor:not-allowed}@property --tw-rotate-x{syntax:\"*\";inherits:false}@property --tw-rotate-y{syntax:\"*\";inherits:false}@property --tw-rotate-z{syntax:\"*\";inherits:false}@property --tw-skew-x{syntax:\"*\";inherits:false}@property --tw-skew-y{syntax:\"*\";inherits:false}@property --tw-space-y-reverse{syntax:\"*\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:\"*\";inherits:false}@property --tw-ease{syntax:\"*\";inherits:false}@property --tw-scale-x{syntax:\"*\";inherits:false;initial-value:1}@property --tw-scale-y{syntax:\"*\";inherits:false;initial-value:1}@property --tw-scale-z{syntax:\"*\";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(1turn)}}@keyframes progress{0%{transform:translate(0)scaleX(0)}10%{transform:translate(0)scaleX(.3)}50%{transform:translate(100%)scaleX(.3)}90%{transform:translate(0)scaleX(.3)}to{transform:translate(0)scaleX(0)}}@keyframes dots{0%,20%{color:#0000;text-shadow:.25em 0 #0000,.5em 0 #0000}40%{color:#000;text-shadow:.25em 0 #0000,.5em 0 #0000}60%{text-shadow:.25em 0 #000,.5em 0 #0000}80%,to{text-shadow:.25em 0 #000,.5em 0 #000}}@media (min-width:40rem){.container{max-width:40rem}.chat-window-normal{height:var(--chat-window-height);width:var(--chat-window-width)}.drag-indicator{display:flex}.fullscreen-button{display:block}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}@media (hover:hover){.chat-btn-icon:hover,.chat-btn-text:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.attachment-link:hover{text-decoration-line:none}.chat-markdown :where(a):not(:where([class~=not-prose],[class~=not-prose] *)):hover{text-decoration-line:underline}}";
|
|
5181
5297
|
|
|
5182
5298
|
const OcsChat = class {
|
|
5183
5299
|
constructor(hostRef) {
|
|
@@ -5185,11 +5301,23 @@ const OcsChat = class {
|
|
|
5185
5301
|
/**
|
|
5186
5302
|
* The base URL for the API.
|
|
5187
5303
|
*/
|
|
5188
|
-
this.apiBaseUrl =
|
|
5304
|
+
this.apiBaseUrl = 'https://www.openchatstudio.com';
|
|
5189
5305
|
/**
|
|
5190
5306
|
* The shape of the chat button. 'round' makes it circular, 'square' keeps it rectangular.
|
|
5191
5307
|
*/
|
|
5192
5308
|
this.buttonShape = 'square';
|
|
5309
|
+
/**
|
|
5310
|
+
* Whether to show the launcher button. Set to false to hide the button
|
|
5311
|
+
* and open the chat window programmatically via the `visible` property.
|
|
5312
|
+
*/
|
|
5313
|
+
this.showButton = true;
|
|
5314
|
+
/**
|
|
5315
|
+
* The operating mode of the widget.
|
|
5316
|
+
* - 'standard': Default floating window with launcher button.
|
|
5317
|
+
* - 'kiosk': Fills parent container, always visible, no header or launcher button.
|
|
5318
|
+
* The parent element must establish a containing block (e.g. `position: relative`).
|
|
5319
|
+
*/
|
|
5320
|
+
this.mode = 'standard';
|
|
5193
5321
|
/**
|
|
5194
5322
|
* Whether the chat widget is visible on load.
|
|
5195
5323
|
*/
|
|
@@ -5200,6 +5328,7 @@ const OcsChat = class {
|
|
|
5200
5328
|
this.position = 'right';
|
|
5201
5329
|
/**
|
|
5202
5330
|
* Whether to persist session data to local storage to allow resuming previous conversations after page reload.
|
|
5331
|
+
* Ignored when `sessionId` is provided.
|
|
5203
5332
|
*/
|
|
5204
5333
|
this.persistentSession = true;
|
|
5205
5334
|
/**
|
|
@@ -5215,12 +5344,13 @@ const OcsChat = class {
|
|
|
5215
5344
|
* Allow the user to attach files to their messages.
|
|
5216
5345
|
*/
|
|
5217
5346
|
this.allowAttachments = false;
|
|
5218
|
-
this.error =
|
|
5347
|
+
this.error = '';
|
|
5219
5348
|
this.messages = [];
|
|
5220
5349
|
this.isLoading = false;
|
|
5221
5350
|
this.isTyping = false;
|
|
5222
|
-
this.
|
|
5223
|
-
this.
|
|
5351
|
+
this.typingProgressMessage = '';
|
|
5352
|
+
this.messageInput = '';
|
|
5353
|
+
this.currentPollTaskId = '';
|
|
5224
5354
|
this.isDragging = false;
|
|
5225
5355
|
this.dragOffset = { x: 0, y: 0 };
|
|
5226
5356
|
this.windowPosition = { x: 0, y: 0 };
|
|
@@ -5249,6 +5379,7 @@ const OcsChat = class {
|
|
|
5249
5379
|
this.chatWindowWidth = 450;
|
|
5250
5380
|
this.chatWindowFullscreenWidth = 1024;
|
|
5251
5381
|
this.positionInitialized = false;
|
|
5382
|
+
this.sessionEpoch = 0;
|
|
5252
5383
|
this.handleMouseDown = (event) => {
|
|
5253
5384
|
if (!this.isFullscreen && window.innerWidth < OcsChat.MOBILE_BREAKPOINT)
|
|
5254
5385
|
return;
|
|
@@ -5294,6 +5425,8 @@ const OcsChat = class {
|
|
|
5294
5425
|
};
|
|
5295
5426
|
this.handleWindowResize = () => {
|
|
5296
5427
|
var _a, _b;
|
|
5428
|
+
if (this.isKioskMode())
|
|
5429
|
+
return;
|
|
5297
5430
|
this.positionInitialized = false;
|
|
5298
5431
|
this.initializePosition();
|
|
5299
5432
|
// Revalidate button position after resize to keep it within viewport bounds
|
|
@@ -5305,7 +5438,7 @@ const OcsChat = class {
|
|
|
5305
5438
|
const minPadding = 10;
|
|
5306
5439
|
this.buttonPosition = {
|
|
5307
5440
|
x: Math.max(minPadding, Math.min(this.buttonPosition.x, windowWidth - buttonWidth - minPadding)),
|
|
5308
|
-
y: Math.max(minPadding, Math.min(this.buttonPosition.y, windowHeight - buttonHeight - minPadding))
|
|
5441
|
+
y: Math.max(minPadding, Math.min(this.buttonPosition.y, windowHeight - buttonHeight - minPadding)),
|
|
5309
5442
|
};
|
|
5310
5443
|
this.updateHostPosition();
|
|
5311
5444
|
}
|
|
@@ -5323,7 +5456,7 @@ const OcsChat = class {
|
|
|
5323
5456
|
const rect = this.host.getBoundingClientRect();
|
|
5324
5457
|
this.buttonDragOffset = {
|
|
5325
5458
|
x: pointer.clientX - rect.left,
|
|
5326
|
-
y: pointer.clientY - rect.top
|
|
5459
|
+
y: pointer.clientY - rect.top,
|
|
5327
5460
|
};
|
|
5328
5461
|
this.addButtonEventListeners();
|
|
5329
5462
|
};
|
|
@@ -5340,7 +5473,7 @@ const OcsChat = class {
|
|
|
5340
5473
|
const rect = this.host.getBoundingClientRect();
|
|
5341
5474
|
this.buttonDragOffset = {
|
|
5342
5475
|
x: pointer.clientX - rect.left,
|
|
5343
|
-
y: pointer.clientY - rect.top
|
|
5476
|
+
y: pointer.clientY - rect.top,
|
|
5344
5477
|
};
|
|
5345
5478
|
this.addButtonEventListeners();
|
|
5346
5479
|
};
|
|
@@ -5387,12 +5520,19 @@ const OcsChat = class {
|
|
|
5387
5520
|
this.error = 'Chatbot ID is required';
|
|
5388
5521
|
return;
|
|
5389
5522
|
}
|
|
5523
|
+
if (this.isKioskMode()) {
|
|
5524
|
+
this.visible = true;
|
|
5525
|
+
}
|
|
5390
5526
|
await this.initializeTranslations();
|
|
5391
|
-
|
|
5392
|
-
|
|
5527
|
+
if (this.isSessionBound()) {
|
|
5528
|
+
// Bound to an externally-managed session: the host page is the source of truth.
|
|
5529
|
+
this.activeSessionId = this.sessionId;
|
|
5530
|
+
}
|
|
5531
|
+
else if (this.persistentSession && this.isLocalStorageAvailable()) {
|
|
5532
|
+
// Always try to load existing session if localStorage is available
|
|
5393
5533
|
const { sessionId, messages } = this.loadSessionFromStorage();
|
|
5394
5534
|
if (sessionId && messages) {
|
|
5395
|
-
this.
|
|
5535
|
+
this.activeSessionId = sessionId;
|
|
5396
5536
|
this.messages = messages;
|
|
5397
5537
|
}
|
|
5398
5538
|
}
|
|
@@ -5409,15 +5549,29 @@ const OcsChat = class {
|
|
|
5409
5549
|
this.chatWindowWidth = varToPixels(windowWidthVar, window.innerWidth, this.chatWindowWidth);
|
|
5410
5550
|
this.chatWindowFullscreenWidth = varToPixels(fullscreenWidthVar, window.innerWidth, this.chatWindowFullscreenWidth);
|
|
5411
5551
|
// Initialize button position from computed styles
|
|
5412
|
-
this.
|
|
5413
|
-
|
|
5552
|
+
if (this.showButton && !this.isKioskMode()) {
|
|
5553
|
+
this.initializeButtonPosition();
|
|
5554
|
+
}
|
|
5555
|
+
// Defer state changes to avoid triggering them during componentDidLoad
|
|
5414
5556
|
setTimeout(() => {
|
|
5557
|
+
// Restore visible state after dimensions are read so initializePosition
|
|
5558
|
+
// uses the correct CSS-derived chatWindowWidth/chatWindowHeight.
|
|
5559
|
+
if (!this.isKioskMode() && this.showButton && this.persistentSession && this.isLocalStorageAvailable()) {
|
|
5560
|
+
this.restoreVisibleState();
|
|
5561
|
+
}
|
|
5415
5562
|
if (this.visible) {
|
|
5416
|
-
this.
|
|
5563
|
+
if (!this.isKioskMode()) {
|
|
5564
|
+
this.initializePosition();
|
|
5565
|
+
}
|
|
5417
5566
|
}
|
|
5418
5567
|
// Resume polling for existing session (don't auto-start new sessions)
|
|
5419
|
-
if (this.visible && this.
|
|
5420
|
-
this.
|
|
5568
|
+
if (this.visible && this.activeSessionId) {
|
|
5569
|
+
if (this.isSessionBound()) {
|
|
5570
|
+
void this.loadBoundSessionHistory();
|
|
5571
|
+
}
|
|
5572
|
+
else {
|
|
5573
|
+
this.startMessagePolling();
|
|
5574
|
+
}
|
|
5421
5575
|
}
|
|
5422
5576
|
}, 0);
|
|
5423
5577
|
window.addEventListener('resize', this.handleWindowResize);
|
|
@@ -5446,7 +5600,7 @@ const OcsChat = class {
|
|
|
5446
5600
|
created_at: new Date().toISOString(),
|
|
5447
5601
|
role: 'system',
|
|
5448
5602
|
content: `**Error:** ${errorText}\nPlease try again.`,
|
|
5449
|
-
attachments: []
|
|
5603
|
+
attachments: [],
|
|
5450
5604
|
};
|
|
5451
5605
|
this.messages = [...this.messages, errorMessage];
|
|
5452
5606
|
this.saveSessionToStorage();
|
|
@@ -5496,7 +5650,7 @@ const OcsChat = class {
|
|
|
5496
5650
|
return;
|
|
5497
5651
|
}
|
|
5498
5652
|
if (typeof this.pageContext !== 'object' || Array.isArray(this.pageContext)) {
|
|
5499
|
-
console.error(
|
|
5653
|
+
console.error('pageContext is expected to be a plain JavaScript object.');
|
|
5500
5654
|
return;
|
|
5501
5655
|
}
|
|
5502
5656
|
this.internalPageContext = this.pageContext;
|
|
@@ -5524,6 +5678,7 @@ const OcsChat = class {
|
|
|
5524
5678
|
this.currentPollTaskId = '';
|
|
5525
5679
|
}
|
|
5526
5680
|
async startSession() {
|
|
5681
|
+
const epoch = this.sessionEpoch;
|
|
5527
5682
|
try {
|
|
5528
5683
|
this.isLoading = true;
|
|
5529
5684
|
const userId = this.getOrGenerateUserId();
|
|
@@ -5531,34 +5686,65 @@ const OcsChat = class {
|
|
|
5531
5686
|
chatbot_id: this.chatbotId,
|
|
5532
5687
|
session_data: {
|
|
5533
5688
|
source: 'widget',
|
|
5534
|
-
page_url: window.location.href
|
|
5689
|
+
page_url: window.location.href,
|
|
5535
5690
|
},
|
|
5536
|
-
participant_remote_id: userId
|
|
5691
|
+
participant_remote_id: userId,
|
|
5537
5692
|
};
|
|
5538
5693
|
if (this.userName) {
|
|
5539
5694
|
requestBody.participant_name = this.userName;
|
|
5540
5695
|
}
|
|
5696
|
+
if (this.versionNumber != null) {
|
|
5697
|
+
requestBody.version_number = this.versionNumber;
|
|
5698
|
+
}
|
|
5541
5699
|
const data = await this.getChatService().startSession(requestBody);
|
|
5542
|
-
|
|
5700
|
+
if (epoch !== this.sessionEpoch)
|
|
5701
|
+
return;
|
|
5702
|
+
this.activeSessionId = data.session_id;
|
|
5543
5703
|
this.saveSessionToStorage();
|
|
5544
5704
|
this.startMessagePolling();
|
|
5545
5705
|
}
|
|
5546
5706
|
catch (_error) {
|
|
5707
|
+
if (epoch !== this.sessionEpoch)
|
|
5708
|
+
return;
|
|
5547
5709
|
this.handleError('Failed to start chat session');
|
|
5548
5710
|
}
|
|
5549
5711
|
finally {
|
|
5550
5712
|
this.isLoading = false;
|
|
5551
5713
|
}
|
|
5552
5714
|
}
|
|
5715
|
+
/**
|
|
5716
|
+
* Load the full message history for a session provided via the `session-id`
|
|
5717
|
+
* prop, then begin regular polling.
|
|
5718
|
+
*/
|
|
5719
|
+
async loadBoundSessionHistory() {
|
|
5720
|
+
const epoch = this.sessionEpoch;
|
|
5721
|
+
try {
|
|
5722
|
+
const history = await this.getChatService().fetchAllMessages(this.activeSessionId);
|
|
5723
|
+
if (epoch !== this.sessionEpoch)
|
|
5724
|
+
return;
|
|
5725
|
+
// Keep messages added while the history was loading (e.g. an optimistic
|
|
5726
|
+
// user message) by appending any that aren't part of the fetched history.
|
|
5727
|
+
const known = new Set(history.map(m => `${m.created_at}|${m.role}|${m.content}`));
|
|
5728
|
+
const pending = this.messages.filter(m => !known.has(`${m.created_at}|${m.role}|${m.content}`));
|
|
5729
|
+
this.messages = [...history, ...pending];
|
|
5730
|
+
this.scrollToBottom(true);
|
|
5731
|
+
}
|
|
5732
|
+
catch (error) {
|
|
5733
|
+
if (epoch !== this.sessionEpoch)
|
|
5734
|
+
return;
|
|
5735
|
+
console.warn('Failed to load chat history:', error);
|
|
5736
|
+
}
|
|
5737
|
+
this.startMessagePolling();
|
|
5738
|
+
}
|
|
5553
5739
|
async uploadFiles() {
|
|
5554
|
-
if (this.selectedFiles.length === 0 || !this.
|
|
5740
|
+
if (this.selectedFiles.length === 0 || !this.activeSessionId || !this.allowAttachments) {
|
|
5555
5741
|
return [];
|
|
5556
5742
|
}
|
|
5557
5743
|
this.isUploadingFiles = true;
|
|
5558
5744
|
try {
|
|
5559
5745
|
const uploadResult = await this.attachmentManager.uploadPendingFiles(this.selectedFiles, {
|
|
5560
5746
|
apiBaseUrl: this.apiBaseUrl || 'https://www.openchatstudio.com',
|
|
5561
|
-
sessionId: this.
|
|
5747
|
+
sessionId: this.activeSessionId,
|
|
5562
5748
|
participantId: this.getOrGenerateUserId(),
|
|
5563
5749
|
participantName: this.userName,
|
|
5564
5750
|
});
|
|
@@ -5572,15 +5758,16 @@ const OcsChat = class {
|
|
|
5572
5758
|
async sendMessage(message) {
|
|
5573
5759
|
if (!message.trim())
|
|
5574
5760
|
return;
|
|
5761
|
+
const epoch = this.sessionEpoch;
|
|
5575
5762
|
// Start session if we don't have one yet
|
|
5576
|
-
if (!this.
|
|
5763
|
+
if (!this.activeSessionId) {
|
|
5577
5764
|
// Prevent concurrent session initialization
|
|
5578
5765
|
if (this.isLoading) {
|
|
5579
5766
|
return;
|
|
5580
5767
|
}
|
|
5581
5768
|
await this.startSession();
|
|
5582
5769
|
// Check if session started successfully
|
|
5583
|
-
if (!this.
|
|
5770
|
+
if (!this.activeSessionId) {
|
|
5584
5771
|
return; // startSession already handled the error
|
|
5585
5772
|
}
|
|
5586
5773
|
}
|
|
@@ -5605,7 +5792,7 @@ const OcsChat = class {
|
|
|
5605
5792
|
created_at: new Date(now.getTime() - (welcomeMessagesToAdd.length - index) * 1000).toISOString(),
|
|
5606
5793
|
role: 'assistant',
|
|
5607
5794
|
content: welcomeMsg,
|
|
5608
|
-
attachments: []
|
|
5795
|
+
attachments: [],
|
|
5609
5796
|
}));
|
|
5610
5797
|
this.messages = [...this.messages, ...welcomeMessages];
|
|
5611
5798
|
}
|
|
@@ -5614,13 +5801,15 @@ const OcsChat = class {
|
|
|
5614
5801
|
created_at: new Date().toISOString(),
|
|
5615
5802
|
role: 'user',
|
|
5616
5803
|
content: message.trim(),
|
|
5617
|
-
attachments: this.allowAttachments
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5804
|
+
attachments: this.allowAttachments
|
|
5805
|
+
? this.selectedFiles
|
|
5806
|
+
.filter(sf => !sf.error && sf.uploaded)
|
|
5807
|
+
.map(sf => ({
|
|
5808
|
+
name: sf.file.name,
|
|
5809
|
+
content_type: sf.file.type,
|
|
5810
|
+
size: sf.file.size,
|
|
5811
|
+
}))
|
|
5812
|
+
: [],
|
|
5624
5813
|
};
|
|
5625
5814
|
this.messages = [...this.messages, userMessage];
|
|
5626
5815
|
this.saveSessionToStorage();
|
|
@@ -5636,7 +5825,12 @@ const OcsChat = class {
|
|
|
5636
5825
|
if (this.internalPageContext) {
|
|
5637
5826
|
requestBody.context = this.internalPageContext;
|
|
5638
5827
|
}
|
|
5639
|
-
|
|
5828
|
+
if (this.versionNumber != null) {
|
|
5829
|
+
requestBody.version_number = this.versionNumber;
|
|
5830
|
+
}
|
|
5831
|
+
const data = await this.getChatService().sendMessage(this.activeSessionId, requestBody);
|
|
5832
|
+
if (epoch !== this.sessionEpoch)
|
|
5833
|
+
return;
|
|
5640
5834
|
if (data.status === 'error') {
|
|
5641
5835
|
throw new Error(data.error || 'Failed to send message');
|
|
5642
5836
|
}
|
|
@@ -5644,6 +5838,8 @@ const OcsChat = class {
|
|
|
5644
5838
|
this.startTaskPolling(data.task_id);
|
|
5645
5839
|
}
|
|
5646
5840
|
catch (error) {
|
|
5841
|
+
if (epoch !== this.sessionEpoch)
|
|
5842
|
+
return;
|
|
5647
5843
|
const errorText = error instanceof Error ? error.message : 'Failed to send message';
|
|
5648
5844
|
this.handleError(errorText);
|
|
5649
5845
|
}
|
|
@@ -5666,10 +5862,10 @@ const OcsChat = class {
|
|
|
5666
5862
|
const childRect = lastChild.getBoundingClientRect();
|
|
5667
5863
|
const currentScrollTop = this.messageListRef.scrollTop;
|
|
5668
5864
|
const childTopRelativeToParent = childRect.top - parentRect.top;
|
|
5669
|
-
const targetScroll = currentScrollTop + childTopRelativeToParent -
|
|
5865
|
+
const targetScroll = currentScrollTop + childTopRelativeToParent - parentRect.height / 2;
|
|
5670
5866
|
this.messageListRef.scrollTo({
|
|
5671
5867
|
top: targetScroll,
|
|
5672
|
-
behavior: 'smooth'
|
|
5868
|
+
behavior: 'smooth',
|
|
5673
5869
|
});
|
|
5674
5870
|
}
|
|
5675
5871
|
else {
|
|
@@ -5714,10 +5910,10 @@ const OcsChat = class {
|
|
|
5714
5910
|
const k = 1024;
|
|
5715
5911
|
if (bytes < k * k) {
|
|
5716
5912
|
// Less than 1MB, show in KB
|
|
5717
|
-
return Math.round(bytes / k * 100) / 100 + ' KB';
|
|
5913
|
+
return Math.round((bytes / k) * 100) / 100 + ' KB';
|
|
5718
5914
|
}
|
|
5719
5915
|
else {
|
|
5720
|
-
return Math.round(bytes / (k * k) * 100) / 100 + ' MB';
|
|
5916
|
+
return Math.round((bytes / (k * k)) * 100) / 100 + ' MB';
|
|
5721
5917
|
}
|
|
5722
5918
|
}
|
|
5723
5919
|
formatTime(dateString) {
|
|
@@ -5735,23 +5931,40 @@ const OcsChat = class {
|
|
|
5735
5931
|
pageContextHandler() {
|
|
5736
5932
|
this.loadInternalPageContext();
|
|
5737
5933
|
}
|
|
5934
|
+
async chatbotConfigHandler() {
|
|
5935
|
+
await this.clearSession();
|
|
5936
|
+
}
|
|
5738
5937
|
/**
|
|
5739
5938
|
* Watch for changes to the `visible` attribute and update accordingly.
|
|
5740
5939
|
*
|
|
5741
5940
|
* @param visible - The new value for the field.
|
|
5742
5941
|
*/
|
|
5743
5942
|
async visibilityHandler(visible) {
|
|
5943
|
+
// Kiosk mode is always visible
|
|
5944
|
+
if (this.isKioskMode() && !visible) {
|
|
5945
|
+
this.visible = true;
|
|
5946
|
+
return;
|
|
5947
|
+
}
|
|
5948
|
+
this.saveVisibleState(visible);
|
|
5744
5949
|
if (this.isButtonDragging) {
|
|
5745
5950
|
this.isButtonDragging = false;
|
|
5746
5951
|
this.buttonWasDragged = false;
|
|
5747
5952
|
this.removeButtonEventListeners();
|
|
5748
5953
|
}
|
|
5749
5954
|
if (visible) {
|
|
5750
|
-
this.
|
|
5955
|
+
if (!this.isKioskMode()) {
|
|
5956
|
+
this.initializePosition();
|
|
5957
|
+
}
|
|
5751
5958
|
// Resume polling for existing session (don't auto-start new sessions)
|
|
5752
|
-
if (this.
|
|
5959
|
+
if (this.activeSessionId) {
|
|
5753
5960
|
this.scrollToBottom(true);
|
|
5754
|
-
this.
|
|
5961
|
+
if (this.isSessionBound() && this.messages.length === 0) {
|
|
5962
|
+
// A bound widget that was hidden at load has not fetched its history yet.
|
|
5963
|
+
void this.loadBoundSessionHistory();
|
|
5964
|
+
}
|
|
5965
|
+
else {
|
|
5966
|
+
this.startMessagePolling();
|
|
5967
|
+
}
|
|
5755
5968
|
}
|
|
5756
5969
|
}
|
|
5757
5970
|
else {
|
|
@@ -5759,7 +5972,7 @@ const OcsChat = class {
|
|
|
5759
5972
|
}
|
|
5760
5973
|
}
|
|
5761
5974
|
startTaskPolling(taskId) {
|
|
5762
|
-
if (!this.
|
|
5975
|
+
if (!this.activeSessionId)
|
|
5763
5976
|
return;
|
|
5764
5977
|
this.currentPollTaskId = taskId;
|
|
5765
5978
|
this.isTyping = true;
|
|
@@ -5767,50 +5980,56 @@ const OcsChat = class {
|
|
|
5767
5980
|
if (this.taskPollingHandle) {
|
|
5768
5981
|
this.taskPollingHandle.cancel();
|
|
5769
5982
|
}
|
|
5770
|
-
this.taskPollingHandle = this.getChatService().pollTask(this.
|
|
5771
|
-
onMessage:
|
|
5983
|
+
this.taskPollingHandle = this.getChatService().pollTask(this.activeSessionId, taskId, {
|
|
5984
|
+
onMessage: message => {
|
|
5772
5985
|
this.messages = [...this.messages, message];
|
|
5773
5986
|
this.saveSessionToStorage();
|
|
5774
5987
|
this.scrollToBottom();
|
|
5775
5988
|
this.isTyping = false;
|
|
5989
|
+
this.typingProgressMessage = '';
|
|
5776
5990
|
this.currentPollTaskId = '';
|
|
5777
5991
|
this.taskPollingHandle = undefined;
|
|
5778
5992
|
this.startMessagePolling();
|
|
5779
5993
|
this.focusInput();
|
|
5780
5994
|
},
|
|
5995
|
+
onProgress: message => {
|
|
5996
|
+
this.typingProgressMessage = message;
|
|
5997
|
+
},
|
|
5781
5998
|
onTimeout: () => {
|
|
5782
5999
|
const timeoutMessage = {
|
|
5783
6000
|
created_at: new Date().toISOString(),
|
|
5784
6001
|
role: 'system',
|
|
5785
6002
|
content: 'The response is taking longer than expected. The system may be experiencing delays. Please try sending your message again.',
|
|
5786
|
-
attachments: []
|
|
6003
|
+
attachments: [],
|
|
5787
6004
|
};
|
|
5788
6005
|
this.messages = [...this.messages, timeoutMessage];
|
|
5789
6006
|
this.saveSessionToStorage();
|
|
5790
6007
|
this.scrollToBottom();
|
|
5791
6008
|
this.isTyping = false;
|
|
6009
|
+
this.typingProgressMessage = '';
|
|
5792
6010
|
this.currentPollTaskId = '';
|
|
5793
6011
|
this.taskPollingHandle = undefined;
|
|
5794
6012
|
this.startMessagePolling();
|
|
5795
6013
|
this.focusInput();
|
|
5796
6014
|
},
|
|
5797
|
-
onError:
|
|
6015
|
+
onError: error => {
|
|
6016
|
+
this.typingProgressMessage = '';
|
|
5798
6017
|
this.handleError(error.message);
|
|
5799
6018
|
this.taskPollingHandle = undefined;
|
|
5800
6019
|
this.startMessagePolling();
|
|
5801
|
-
}
|
|
6020
|
+
},
|
|
5802
6021
|
});
|
|
5803
6022
|
}
|
|
5804
6023
|
startMessagePolling() {
|
|
5805
|
-
if (!this.
|
|
6024
|
+
if (!this.activeSessionId || this.currentPollTaskId || !this.visible) {
|
|
5806
6025
|
return;
|
|
5807
6026
|
}
|
|
5808
6027
|
if (this.messagePollingHandle) {
|
|
5809
6028
|
return;
|
|
5810
6029
|
}
|
|
5811
|
-
this.messagePollingHandle = this.getChatService().startMessagePolling(this.
|
|
5812
|
-
getSince: () => { var _a; return this.messages.length > 0 ? (_a = this.messages.at(-1)) === null || _a === void 0 ? void 0 : _a.created_at : undefined; },
|
|
5813
|
-
onMessages:
|
|
6030
|
+
this.messagePollingHandle = this.getChatService().startMessagePolling(this.activeSessionId, {
|
|
6031
|
+
getSince: () => { var _a; return (this.messages.length > 0 ? (_a = this.messages.at(-1)) === null || _a === void 0 ? void 0 : _a.created_at : undefined); },
|
|
6032
|
+
onMessages: messages => {
|
|
5814
6033
|
if (messages.length === 0)
|
|
5815
6034
|
return;
|
|
5816
6035
|
this.messages = [...this.messages, ...messages];
|
|
@@ -5820,7 +6039,7 @@ const OcsChat = class {
|
|
|
5820
6039
|
},
|
|
5821
6040
|
onError: () => {
|
|
5822
6041
|
// Silently ignore polling errors to match previous behaviour
|
|
5823
|
-
}
|
|
6042
|
+
},
|
|
5824
6043
|
});
|
|
5825
6044
|
}
|
|
5826
6045
|
stopMessagePolling() {
|
|
@@ -5839,6 +6058,9 @@ const OcsChat = class {
|
|
|
5839
6058
|
this.position = position;
|
|
5840
6059
|
}
|
|
5841
6060
|
getPositionClasses() {
|
|
6061
|
+
if (this.isKioskMode()) {
|
|
6062
|
+
return 'chat-window-kiosk';
|
|
6063
|
+
}
|
|
5842
6064
|
if (this.isFullscreen) {
|
|
5843
6065
|
return 'chat-window-fullscreen';
|
|
5844
6066
|
}
|
|
@@ -5854,6 +6076,9 @@ const OcsChat = class {
|
|
|
5854
6076
|
return { windowWidth, actualChatWidth, centeredX, maxOffset };
|
|
5855
6077
|
}
|
|
5856
6078
|
getPositionStyles() {
|
|
6079
|
+
if (this.isKioskMode()) {
|
|
6080
|
+
return {};
|
|
6081
|
+
}
|
|
5857
6082
|
if (this.isFullscreen) {
|
|
5858
6083
|
const { centeredX } = this.getFullscreenBounds();
|
|
5859
6084
|
const finalX = centeredX + this.fullscreenPosition.x;
|
|
@@ -5885,19 +6110,19 @@ const OcsChat = class {
|
|
|
5885
6110
|
case 'left':
|
|
5886
6111
|
this.windowPosition = {
|
|
5887
6112
|
x: OcsChat.WINDOW_MARGIN,
|
|
5888
|
-
y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN
|
|
6113
|
+
y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN,
|
|
5889
6114
|
};
|
|
5890
6115
|
break;
|
|
5891
6116
|
case 'right':
|
|
5892
6117
|
this.windowPosition = {
|
|
5893
6118
|
x: windowWidth - chatWidth - OcsChat.WINDOW_MARGIN,
|
|
5894
|
-
y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN
|
|
6119
|
+
y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN,
|
|
5895
6120
|
};
|
|
5896
6121
|
break;
|
|
5897
6122
|
case 'center':
|
|
5898
6123
|
this.windowPosition = {
|
|
5899
6124
|
x: (windowWidth - chatWidth) / 2,
|
|
5900
|
-
y: (windowHeight - this.chatWindowHeight) / 2
|
|
6125
|
+
y: (windowHeight - this.chatWindowHeight) / 2,
|
|
5901
6126
|
};
|
|
5902
6127
|
break;
|
|
5903
6128
|
}
|
|
@@ -5920,14 +6145,14 @@ const OcsChat = class {
|
|
|
5920
6145
|
// For fullscreen, track relative to current position
|
|
5921
6146
|
this.dragOffset = {
|
|
5922
6147
|
x: pointer.clientX,
|
|
5923
|
-
y: pointer.clientY
|
|
6148
|
+
y: pointer.clientY,
|
|
5924
6149
|
};
|
|
5925
6150
|
}
|
|
5926
6151
|
else {
|
|
5927
6152
|
const rect = this.chatWindowRef.getBoundingClientRect();
|
|
5928
6153
|
this.dragOffset = {
|
|
5929
6154
|
x: pointer.clientX - rect.left,
|
|
5930
|
-
y: pointer.clientY - rect.top
|
|
6155
|
+
y: pointer.clientY - rect.top,
|
|
5931
6156
|
};
|
|
5932
6157
|
}
|
|
5933
6158
|
}
|
|
@@ -5939,7 +6164,7 @@ const OcsChat = class {
|
|
|
5939
6164
|
const { maxOffset } = this.getFullscreenBounds();
|
|
5940
6165
|
const deltaX = pointer.clientX - this.dragOffset.x;
|
|
5941
6166
|
this.fullscreenPosition = {
|
|
5942
|
-
x: Math.max(-maxOffset, Math.min(maxOffset, deltaX))
|
|
6167
|
+
x: Math.max(-maxOffset, Math.min(maxOffset, deltaX)),
|
|
5943
6168
|
};
|
|
5944
6169
|
}
|
|
5945
6170
|
else {
|
|
@@ -5952,7 +6177,7 @@ const OcsChat = class {
|
|
|
5952
6177
|
const chatHeight = this.chatWindowRef.offsetHeight;
|
|
5953
6178
|
this.windowPosition = {
|
|
5954
6179
|
x: Math.max(0, Math.min(newX, windowWidth - chatWidth)),
|
|
5955
|
-
y: Math.max(0, Math.min(newY, windowHeight - chatHeight))
|
|
6180
|
+
y: Math.max(0, Math.min(newY, windowHeight - chatHeight)),
|
|
5956
6181
|
};
|
|
5957
6182
|
}
|
|
5958
6183
|
}
|
|
@@ -5999,7 +6224,7 @@ const OcsChat = class {
|
|
|
5999
6224
|
const verticalValue = this.buttonVerticalSide === 'top' ? resolvedTop : resolvedBottom;
|
|
6000
6225
|
this.buttonPosition = {
|
|
6001
6226
|
x: horizontalValue,
|
|
6002
|
-
y: verticalValue
|
|
6227
|
+
y: verticalValue,
|
|
6003
6228
|
};
|
|
6004
6229
|
// Apply the position to the host
|
|
6005
6230
|
this.updateHostPosition();
|
|
@@ -6042,12 +6267,8 @@ const OcsChat = class {
|
|
|
6042
6267
|
const maxTop = windowHeight - buttonHeight - minPadding;
|
|
6043
6268
|
const constrainedLeft = Math.max(minLeft, Math.min(candidateLeft, maxLeft));
|
|
6044
6269
|
const constrainedTop = Math.max(minTop, Math.min(candidateTop, maxTop));
|
|
6045
|
-
const newHorizontalValue = this.buttonHorizontalSide === 'left'
|
|
6046
|
-
|
|
6047
|
-
: Math.max(minPadding, windowWidth - (constrainedLeft + buttonWidth));
|
|
6048
|
-
const newVerticalValue = this.buttonVerticalSide === 'top'
|
|
6049
|
-
? constrainedTop
|
|
6050
|
-
: Math.max(minPadding, windowHeight - (constrainedTop + buttonHeight));
|
|
6270
|
+
const newHorizontalValue = this.buttonHorizontalSide === 'left' ? constrainedLeft : Math.max(minPadding, windowWidth - (constrainedLeft + buttonWidth));
|
|
6271
|
+
const newVerticalValue = this.buttonVerticalSide === 'top' ? constrainedTop : Math.max(minPadding, windowHeight - (constrainedTop + buttonHeight));
|
|
6051
6272
|
if (newHorizontalValue !== this.buttonPosition.x || newVerticalValue !== this.buttonPosition.y) {
|
|
6052
6273
|
this.buttonWasDragged = true;
|
|
6053
6274
|
this.buttonPosition = { x: newHorizontalValue, y: newVerticalValue };
|
|
@@ -6110,16 +6331,12 @@ const OcsChat = class {
|
|
|
6110
6331
|
return fallback;
|
|
6111
6332
|
}
|
|
6112
6333
|
getWelcomeMessages() {
|
|
6113
|
-
const translated = this.translationManager.getArray(
|
|
6114
|
-
return translated && translated.length > 0
|
|
6115
|
-
? translated
|
|
6116
|
-
: this.parsedWelcomeMessages;
|
|
6334
|
+
const translated = this.translationManager.getArray('content.welcomeMessages');
|
|
6335
|
+
return translated && translated.length > 0 ? translated : this.parsedWelcomeMessages;
|
|
6117
6336
|
}
|
|
6118
6337
|
getStarterQuestions() {
|
|
6119
|
-
const translated = this.translationManager.getArray(
|
|
6120
|
-
return translated && translated.length > 0
|
|
6121
|
-
? translated
|
|
6122
|
-
: this.parsedStarterQuestions;
|
|
6338
|
+
const translated = this.translationManager.getArray('content.starterQuestions');
|
|
6339
|
+
return translated && translated.length > 0 ? translated : this.parsedStarterQuestions;
|
|
6123
6340
|
}
|
|
6124
6341
|
getButtonClasses() {
|
|
6125
6342
|
const buttonText = this.translationManager.get('branding.buttonText', this.buttonText);
|
|
@@ -6130,6 +6347,9 @@ const OcsChat = class {
|
|
|
6130
6347
|
}
|
|
6131
6348
|
renderButton() {
|
|
6132
6349
|
var _a;
|
|
6350
|
+
if (!this.showButton || this.isKioskMode()) {
|
|
6351
|
+
return null;
|
|
6352
|
+
}
|
|
6133
6353
|
const buttonText = this.translationManager.get('branding.buttonText', this.buttonText);
|
|
6134
6354
|
const hasText = !!(buttonText && buttonText.trim());
|
|
6135
6355
|
const hasCustomIcon = this.iconUrl && this.iconUrl.trim();
|
|
@@ -6139,31 +6359,34 @@ const OcsChat = class {
|
|
|
6139
6359
|
const buttonAriaLabel = finalButtonText ? `${openLabel} - ${finalButtonText}` : openLabel;
|
|
6140
6360
|
// Only show drag cursor if button is draggable
|
|
6141
6361
|
const isDraggable = this.isButtonDraggable();
|
|
6142
|
-
const buttonStyle = isDraggable
|
|
6143
|
-
|
|
6144
|
-
|
|
6362
|
+
const buttonStyle = isDraggable
|
|
6363
|
+
? {
|
|
6364
|
+
cursor: this.isButtonDragging ? 'grabbing' : 'grab',
|
|
6365
|
+
}
|
|
6366
|
+
: {};
|
|
6145
6367
|
if (hasText) {
|
|
6146
|
-
return (h("button", { ref:
|
|
6368
|
+
return (h("button", { ref: el => (this.buttonRef = el), class: buttonClasses, "aria-label": buttonAriaLabel, title: finalButtonText || openLabel, style: buttonStyle, onClick: () => this.handleButtonClick(), onMouseDown: e => this.handleButtonMouseDown(e), onTouchStart: e => this.handleButtonTouchStart(e), "aria-grabbed": this.isButtonDragging, "aria-describedby": isDraggable ? 'chat-button-drag-hint' : undefined }, hasCustomIcon ? h("img", { src: this.iconUrl, alt: "" }) : h(OcsWidgetAvatar, null), h("span", null, finalButtonText), isDraggable && (h("span", { id: "chat-button-drag-hint", style: { display: 'none' } }, "Draggable. Use mouse or touch to reposition."))));
|
|
6147
6369
|
}
|
|
6148
6370
|
else {
|
|
6149
|
-
return (h("button", { ref:
|
|
6371
|
+
return (h("button", { ref: el => (this.buttonRef = el), class: buttonClasses, "aria-label": openLabel, title: openLabel, style: buttonStyle, onClick: () => this.handleButtonClick(), onMouseDown: e => this.handleButtonMouseDown(e), onTouchStart: e => this.handleButtonTouchStart(e), "aria-grabbed": this.isButtonDragging, "aria-describedby": isDraggable ? 'chat-button-drag-hint' : undefined }, hasCustomIcon ? h("img", { src: this.iconUrl, alt: "" }) : h(OcsWidgetAvatar, null), isDraggable && (h("span", { id: "chat-button-drag-hint", style: { display: 'none' } }, "Draggable. Use mouse or touch to reposition."))));
|
|
6150
6372
|
}
|
|
6151
6373
|
}
|
|
6152
6374
|
getStorageKeys() {
|
|
6153
6375
|
return {
|
|
6154
6376
|
sessionId: `ocs-chat-session-${this.chatbotId}`,
|
|
6155
6377
|
messages: `ocs-chat-messages-${this.chatbotId}`,
|
|
6156
|
-
lastActivity: `ocs-chat-activity-${this.chatbotId}
|
|
6378
|
+
lastActivity: `ocs-chat-activity-${this.chatbotId}`,
|
|
6379
|
+
visible: `ocs-chat-visible-${this.chatbotId}`,
|
|
6157
6380
|
};
|
|
6158
6381
|
}
|
|
6159
6382
|
saveSessionToStorage() {
|
|
6160
|
-
if (!this.persistentSession) {
|
|
6383
|
+
if (!this.persistentSession || this.isSessionBound()) {
|
|
6161
6384
|
return;
|
|
6162
6385
|
}
|
|
6163
6386
|
const keys = this.getStorageKeys();
|
|
6164
6387
|
try {
|
|
6165
|
-
if (this.
|
|
6166
|
-
localStorage.setItem(keys.sessionId, this.
|
|
6388
|
+
if (this.activeSessionId) {
|
|
6389
|
+
localStorage.setItem(keys.sessionId, this.activeSessionId);
|
|
6167
6390
|
localStorage.setItem(keys.lastActivity, new Date().toISOString());
|
|
6168
6391
|
}
|
|
6169
6392
|
localStorage.setItem(keys.messages, JSON.stringify(this.messages));
|
|
@@ -6216,30 +6439,73 @@ const OcsChat = class {
|
|
|
6216
6439
|
return this.generatedUserId;
|
|
6217
6440
|
}
|
|
6218
6441
|
const storageKey = `ocs-user-id`;
|
|
6219
|
-
|
|
6442
|
+
let stored = null;
|
|
6443
|
+
try {
|
|
6444
|
+
stored = localStorage.getItem(storageKey);
|
|
6445
|
+
}
|
|
6446
|
+
catch (_a) {
|
|
6447
|
+
// localStorage blocked; fall through to in-memory id generation
|
|
6448
|
+
}
|
|
6220
6449
|
if (stored) {
|
|
6221
6450
|
this.generatedUserId = stored;
|
|
6222
6451
|
return stored;
|
|
6223
6452
|
}
|
|
6224
6453
|
const array = new Uint8Array(9);
|
|
6225
6454
|
window.crypto.getRandomValues(array);
|
|
6226
|
-
const randomString = Array.from(array, byte => byte.toString(36))
|
|
6455
|
+
const randomString = Array.from(array, byte => byte.toString(36))
|
|
6456
|
+
.join('')
|
|
6457
|
+
.substr(0, 9);
|
|
6227
6458
|
const newUserId = `ocs:${Date.now()}_${randomString}`;
|
|
6228
6459
|
this.generatedUserId = newUserId;
|
|
6229
|
-
|
|
6460
|
+
try {
|
|
6461
|
+
localStorage.setItem(storageKey, newUserId);
|
|
6462
|
+
}
|
|
6463
|
+
catch (_b) {
|
|
6464
|
+
// localStorage blocked; the generated id lives in component state for this page
|
|
6465
|
+
}
|
|
6230
6466
|
return newUserId;
|
|
6231
6467
|
}
|
|
6468
|
+
saveVisibleState(visible) {
|
|
6469
|
+
if (!this.persistentSession)
|
|
6470
|
+
return;
|
|
6471
|
+
try {
|
|
6472
|
+
const keys = this.getStorageKeys();
|
|
6473
|
+
localStorage.setItem(keys.visible, visible ? '1' : '0');
|
|
6474
|
+
}
|
|
6475
|
+
catch (_a) {
|
|
6476
|
+
// ignore
|
|
6477
|
+
}
|
|
6478
|
+
}
|
|
6479
|
+
restoreVisibleState() {
|
|
6480
|
+
try {
|
|
6481
|
+
const keys = this.getStorageKeys();
|
|
6482
|
+
const stored = localStorage.getItem(keys.visible);
|
|
6483
|
+
if (stored === '1') {
|
|
6484
|
+
this.visible = true;
|
|
6485
|
+
}
|
|
6486
|
+
}
|
|
6487
|
+
catch (_a) {
|
|
6488
|
+
// ignore
|
|
6489
|
+
}
|
|
6490
|
+
}
|
|
6232
6491
|
clearSessionStorage() {
|
|
6233
6492
|
const keys = this.getStorageKeys();
|
|
6234
6493
|
try {
|
|
6235
6494
|
localStorage.removeItem(keys.sessionId);
|
|
6236
6495
|
localStorage.removeItem(keys.messages);
|
|
6237
6496
|
localStorage.removeItem(keys.lastActivity);
|
|
6497
|
+
localStorage.removeItem(keys.visible);
|
|
6238
6498
|
}
|
|
6239
6499
|
catch (error) {
|
|
6240
6500
|
console.warn('Failed to clear chat session from localStorage:', error);
|
|
6241
6501
|
}
|
|
6242
6502
|
}
|
|
6503
|
+
isKioskMode() {
|
|
6504
|
+
return this.mode === 'kiosk';
|
|
6505
|
+
}
|
|
6506
|
+
isSessionBound() {
|
|
6507
|
+
return !!this.sessionId;
|
|
6508
|
+
}
|
|
6243
6509
|
isLocalStorageAvailable() {
|
|
6244
6510
|
try {
|
|
6245
6511
|
localStorage.setItem(OcsChat.LOCALSTORAGE_TEST_KEY, 'test');
|
|
@@ -6265,8 +6531,11 @@ const OcsChat = class {
|
|
|
6265
6531
|
* will start when the user sends a message.
|
|
6266
6532
|
*/
|
|
6267
6533
|
async clearSession() {
|
|
6534
|
+
this.sessionEpoch += 1;
|
|
6268
6535
|
this.clearSessionStorage();
|
|
6269
|
-
|
|
6536
|
+
// A session provided by the host page (session-id prop) cannot be cleared;
|
|
6537
|
+
// stay bound to it. Unbound widgets start a new session on the next message.
|
|
6538
|
+
this.activeSessionId = this.sessionId;
|
|
6270
6539
|
this.messages = [];
|
|
6271
6540
|
this.isTyping = false;
|
|
6272
6541
|
this.currentPollTaskId = '';
|
|
@@ -6274,6 +6543,11 @@ const OcsChat = class {
|
|
|
6274
6543
|
this.selectedFiles = [];
|
|
6275
6544
|
}
|
|
6276
6545
|
this.cleanup();
|
|
6546
|
+
if (this.isSessionBound()) {
|
|
6547
|
+
// The host-owned session cannot be cleared: reload its history and
|
|
6548
|
+
// resume polling so the widget doesn't end up in a dead state.
|
|
6549
|
+
void this.loadBoundSessionHistory();
|
|
6550
|
+
}
|
|
6277
6551
|
}
|
|
6278
6552
|
toggleFullscreen() {
|
|
6279
6553
|
this.isFullscreen = !this.isFullscreen;
|
|
@@ -6282,25 +6556,21 @@ const OcsChat = class {
|
|
|
6282
6556
|
}
|
|
6283
6557
|
render() {
|
|
6284
6558
|
// Only show error state for critical errors that prevent the widget from functioning
|
|
6285
|
-
if (this.error && !this.
|
|
6559
|
+
if (this.error && !this.activeSessionId) {
|
|
6286
6560
|
return (h(Host, null, h("p", { class: "error-message" }, this.error)));
|
|
6287
6561
|
}
|
|
6288
|
-
return (h(Host, null, this.renderButton(), this.visible && (h("div", { ref:
|
|
6289
|
-
? 'message-bubble-user'
|
|
6290
|
-
: message.role === 'assistant'
|
|
6291
|
-
? 'message-bubble-assistant'
|
|
6292
|
-
: 'message-bubble-system'}` }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownSync(message.content) }), message.attachments && message.attachments.length > 0 && (h("div", { class: "message-attachments" }, message.attachments.map((attachment, attachmentIndex) => (h("div", { key: attachmentIndex, class: "flex items-center gap-[0.5em]" }, h("span", { class: "message-attachment-icon" }, h(PaperClipIcon, null)), h("span", { class: "message-attachment-name" }, attachment.name)))))), h("div", { class: "message-timestamp" }, this.formatTime(message.created_at)))))), this.isTyping && (h("div", null, h("div", { class: "typing-indicator" }, h("div", { class: "typing-progress" })), h("div", { class: "typing-text" }, h("span", null, this.translationManager.get('status.typing', this.typingIndicatorText)), h("span", { class: "typing-dots loading" })))))), this.messages.length === 0 && this.getStarterQuestions().length > 0 && (h("div", { class: "starter-questions" }, this.getStarterQuestions().map((question, index) => (h("div", { key: `starter-${index}`, class: "starter-question-row" }, h("button", { class: "starter-question", onClick: () => this.handleStarterQuestionClick(question) }, question)))))), this.allowAttachments && this.selectedFiles.length > 0 && (h("div", { class: "selected-files-container" }, h("div", { class: "space-y-[0.25em]" }, this.selectedFiles.map((selectedFile, index) => (h("div", { key: index, class: "selected-file-item" }, h("div", { class: "flex items-center gap-[0.5em]" }, h("span", { class: "selected-file-icon" }, h(PaperClipIcon, null)), h("span", null, selectedFile.file.name), h("span", { class: "selected-file-size" }, "(", this.formatFileSize(selectedFile.file.size), ")"), selectedFile.error && (h("span", { class: "selected-file-error" }, selectedFile.error)), selectedFile.uploaded && (h("span", { class: "selected-file-success-icon" }, h(CheckDocumentIcon, null)))), h("button", { onClick: () => this.removeSelectedFile(index), class: "selected-file-remove-button", "aria-label": this.translationManager.get('attach.remove') }, h(XIcon, null)))))))), h("div", { class: "input-area" }, h("div", { class: "input-container" }, h("textarea", { ref: (el) => this.textareaRef = el, class: "message-textarea", rows: 1, placeholder: this.translationManager.get('composer.placeholder'), value: this.messageInput, onInput: (e) => this.handleInputChange(e), onKeyPress: (e) => this.handleKeyPress(e), disabled: this.isTyping || this.isUploadingFiles || this.isLoading }), this.allowAttachments && (h("input", { ref: (el) => {
|
|
6562
|
+
return (h(Host, null, this.renderButton(), this.visible && (h("div", { ref: el => (this.chatWindowRef = el), id: "ocs-chat-window", class: this.getPositionClasses(), style: this.getPositionStyles() }, !this.isKioskMode() && (h("div", { class: `chat-header ${this.isDragging ? 'chat-header-dragging' : 'chat-header-draggable'}`, onMouseDown: this.handleMouseDown, onTouchStart: this.handleTouchStart }, h("div", { class: "drag-indicator" }, h("div", { class: "drag-dots header-button" }, h(GripDotsVerticalIcon, null))), h("div", { class: "header-text" }, this.translationManager.get('branding.headerText', this.headerText)), h("div", { class: "header-buttons" }, this.messages.length > 0 && !this.isSessionBound() && (h("button", { class: "header-button", onClick: () => this.showConfirmationDialog(), title: this.translationManager.get('window.newChat'), "aria-label": this.translationManager.get('window.newChat') }, h(PlusWithCircleIcon, null))), this.allowFullScreen && (h("button", { class: "header-button fullscreen-button", onClick: () => this.toggleFullscreen(), title: this.isFullscreen ? this.translationManager.get('window.exitFullscreen') : this.translationManager.get('window.fullscreen'), "aria-label": this.isFullscreen ? this.translationManager.get('window.exitFullscreen') : this.translationManager.get('window.fullscreen') }, this.isFullscreen ? h(ArrowsPointingInIcon, null) : h(ArrowsPointingOutIcon, null))), h("button", { class: "header-button", onClick: () => (this.visible = false), "aria-label": this.translationManager.get('window.close') }, h(XMarkIcon, null))))), !this.isKioskMode() && this.showNewChatConfirmation && (h("div", { class: "confirmation-overlay" }, h("div", { class: "confirmation-dialog" }, h("div", { class: "confirmation-content" }, h("h3", { class: "confirmation-title" }, this.translationManager.get('modal.newChatTitle')), h("p", { class: "confirmation-message" }, this.translationManager.get('modal.newChatBody', this.newChatConfirmationMessage)), h("div", { class: "confirmation-buttons" }, h("button", { class: "confirmation-button confirmation-button-cancel", onClick: () => this.hideConfirmationDialog() }, this.translationManager.get('modal.cancel')), h("button", { class: "confirmation-button confirmation-button-confirm", onClick: () => this.confirmNewChat() }, this.translationManager.get('modal.confirm'))))))), h("div", { class: "chat-content" }, this.isLoading && !this.activeSessionId && (h("div", { class: "loading-container" }, h("div", { class: "loading-spinner" }), h("span", { class: "loading-text" }, this.translationManager.get('status.starting')))), h("div", { ref: el => (this.messageListRef = el), class: "messages-container" }, this.messages.length === 0 && this.getWelcomeMessages().length > 0 && (h("div", { class: "welcome-messages" }, this.getWelcomeMessages().map((message, index) => (h("div", { key: `welcome-${index}`, class: "message-row message-row-assistant" }, h("div", { class: "message-bubble message-bubble-assistant" }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownSync(message) }))))))), this.messages.map((message, index) => (h("div", { key: index, class: `message-row ${message.role === 'user' ? 'message-row-user' : 'message-row-assistant'}` }, h("div", { class: `message-bubble ${message.role === 'user' ? 'message-bubble-user' : message.role === 'assistant' ? 'message-bubble-assistant' : 'message-bubble-system'}` }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownSync(message.content) }), message.attachments && message.attachments.length > 0 && (h("div", { class: "message-attachments" }, message.attachments.map((attachment, attachmentIndex) => (h("div", { key: attachmentIndex, class: "flex items-center gap-[0.5em]" }, h("span", { class: "message-attachment-icon" }, h(PaperClipIcon, null)), h("span", { class: "message-attachment-name" }, attachment.name)))))), h("div", { class: "message-timestamp" }, this.formatTime(message.created_at)))))), this.isTyping && (h("div", null, h("div", { class: "typing-indicator" }, h("div", { class: "typing-progress" })), h("div", { class: "typing-text" }, h("span", null, this.typingProgressMessage || this.translationManager.get('status.typing', this.typingIndicatorText)), h("span", { class: "typing-dots loading" }))))), this.messages.length === 0 && this.getStarterQuestions().length > 0 && (h("div", { class: "starter-questions" }, this.getStarterQuestions().map((question, index) => (h("div", { key: `starter-${index}`, class: "starter-question-row" }, h("button", { class: "starter-question", onClick: () => this.handleStarterQuestionClick(question) }, question)))))), this.allowAttachments && this.selectedFiles.length > 0 && (h("div", { class: "selected-files-container" }, h("div", { class: "space-y-[0.25em]" }, this.selectedFiles.map((selectedFile, index) => (h("div", { key: index, class: "selected-file-item" }, h("div", { class: "flex items-center gap-[0.5em]" }, h("span", { class: "selected-file-icon" }, h(PaperClipIcon, null)), h("span", null, selectedFile.file.name), h("span", { class: "selected-file-size" }, "(", this.formatFileSize(selectedFile.file.size), ")"), selectedFile.error && h("span", { class: "selected-file-error" }, selectedFile.error), selectedFile.uploaded && (h("span", { class: "selected-file-success-icon" }, h(CheckDocumentIcon, null)))), h("button", { onClick: () => this.removeSelectedFile(index), class: "selected-file-remove-button", "aria-label": this.translationManager.get('attach.remove') }, h(XIcon, null)))))))), h("div", { class: "input-area" }, h("div", { class: "input-container" }, h("textarea", { ref: el => (this.textareaRef = el), class: "message-textarea", rows: 1, placeholder: this.translationManager.get('composer.placeholder'), value: this.messageInput, onInput: e => this.handleInputChange(e), onKeyPress: e => this.handleKeyPress(e), disabled: this.isTyping || this.isUploadingFiles || this.isLoading }), this.allowAttachments && (h("input", { ref: el => {
|
|
6293
6563
|
// Unclear why but after removing all attachments this is being set to `null`.
|
|
6294
6564
|
if (el) {
|
|
6295
6565
|
this.fileInputRef = el;
|
|
6296
6566
|
}
|
|
6297
|
-
}, id: "ocs-file-input", type: "file", multiple: true, accept: OcsChat.SUPPORTED_FILE_EXTENSIONS.join(',') + ',text/*', onChange:
|
|
6298
|
-
? 'send-button-enabled'
|
|
6299
|
-
: 'send-button-disabled'}`, onClick: () => this.sendMessage(this.messageInput), disabled: this.isTyping || this.isUploadingFiles || this.isLoading || !this.messageInput.trim() }, this.isUploadingFiles ? `${this.translationManager.get('status.uploading')}...` : this.translationManager.get('composer.send')))), h("div", { class: "flex items-center justify-center text-[0.8em] font-light w-full text-slate-500 py-[2px]" }, h("p", null, this.translationManager.get('branding.poweredBy'), ' ', " ", h("a", { class: "underline", href: "https://www.dimagi.com", target: "_blank" }, "Dimagi"))))))));
|
|
6567
|
+
}, id: "ocs-file-input", type: "file", multiple: true, accept: OcsChat.SUPPORTED_FILE_EXTENSIONS.join(',') + ',text/*', onChange: e => this.handleFileSelect(e), class: "hidden" })), this.allowAttachments && (h("button", { class: "file-attachment-button", onClick: () => { var _a; return (_a = this.fileInputRef) === null || _a === void 0 ? void 0 : _a.click(); }, disabled: this.isTyping || this.isUploadingFiles || this.isLoading, title: this.translationManager.get('attach.add'), "aria-label": this.translationManager.get('attach.add') }, h(PaperClipIcon, null))), h("button", { class: `send-button ${!this.isTyping && !this.isLoading && !!this.messageInput.trim() ? 'send-button-enabled' : 'send-button-disabled'}`, onClick: () => this.sendMessage(this.messageInput), disabled: this.isTyping || this.isUploadingFiles || this.isLoading || !this.messageInput.trim() }, this.isUploadingFiles ? `${this.translationManager.get('status.uploading')}...` : this.translationManager.get('composer.send')))), h("div", { class: "flex items-center justify-center text-[0.8em] font-light w-full text-slate-500 py-[2px]" }, h("p", null, this.translationManager.get('branding.poweredBy'), ' ', h("a", { class: "underline", href: "https://www.dimagi.com", target: "_blank", rel: "noopener noreferrer" }, "Dimagi"))))))));
|
|
6300
6568
|
}
|
|
6301
6569
|
get host() { return getElement(this); }
|
|
6302
6570
|
static get watchers() { return {
|
|
6303
6571
|
"pageContext": ["pageContextHandler"],
|
|
6572
|
+
"chatbotId": ["chatbotConfigHandler"],
|
|
6573
|
+
"versionNumber": ["chatbotConfigHandler"],
|
|
6304
6574
|
"visible": ["visibilityHandler"]
|
|
6305
6575
|
}; }
|
|
6306
6576
|
};
|
|
@@ -6314,9 +6584,41 @@ OcsChat.WINDOW_MARGIN = 20;
|
|
|
6314
6584
|
OcsChat.LOCALSTORAGE_TEST_KEY = '__ocs_test__';
|
|
6315
6585
|
OcsChat.MAX_FILE_SIZE_MB = 50;
|
|
6316
6586
|
OcsChat.MAX_TOTAL_SIZE_MB = 50;
|
|
6317
|
-
OcsChat.SUPPORTED_FILE_EXTENSIONS = [
|
|
6318
|
-
'.
|
|
6319
|
-
'.
|
|
6587
|
+
OcsChat.SUPPORTED_FILE_EXTENSIONS = [
|
|
6588
|
+
'.txt',
|
|
6589
|
+
'.pdf',
|
|
6590
|
+
'.doc',
|
|
6591
|
+
'.docx',
|
|
6592
|
+
'.xls',
|
|
6593
|
+
'.xlsx',
|
|
6594
|
+
'.csv',
|
|
6595
|
+
'.jpg',
|
|
6596
|
+
'.jpeg',
|
|
6597
|
+
'.png',
|
|
6598
|
+
'.gif',
|
|
6599
|
+
'.bmp',
|
|
6600
|
+
'.webp',
|
|
6601
|
+
'.svg',
|
|
6602
|
+
'.mp4',
|
|
6603
|
+
'.mov',
|
|
6604
|
+
'.avi',
|
|
6605
|
+
'.mp3',
|
|
6606
|
+
'.wav',
|
|
6607
|
+
'.html',
|
|
6608
|
+
'.htm',
|
|
6609
|
+
'.css',
|
|
6610
|
+
'.js',
|
|
6611
|
+
'.xml',
|
|
6612
|
+
'.md',
|
|
6613
|
+
'.ics',
|
|
6614
|
+
'.vcf',
|
|
6615
|
+
'.rtf',
|
|
6616
|
+
'.tsv',
|
|
6617
|
+
'.yaml',
|
|
6618
|
+
'.yml',
|
|
6619
|
+
'.py',
|
|
6620
|
+
'.c',
|
|
6621
|
+
];
|
|
6320
6622
|
OcsChat.style = ocsChatCss;
|
|
6321
6623
|
|
|
6322
6624
|
export { OcsChat as open_chat_studio_widget };
|