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,22 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-Cf6K60f1.js');
|
|
4
4
|
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
6
6
|
const OcsWidgetAvatar = () => {
|
|
7
|
-
return index.h("svg", { width: "24", height: "24", viewBox: "0 0 500 500", fill: "currentColor", xmlns: "http://www.w3.org/2000/svg" },
|
|
7
|
+
return (index.h("svg", { width: "24", height: "24", viewBox: "0 0 500 500", fill: "currentColor", xmlns: "http://www.w3.org/2000/svg" },
|
|
8
8
|
index.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" }),
|
|
9
9
|
index.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" }),
|
|
10
10
|
index.h("rect", { x: "289.475", y: "184.808", width: "61.9019", height: "115.73", rx: "30.951" }),
|
|
11
11
|
index.h("rect", { x: "161.184", y: "184.808", width: "61.9019", height: "115.73", rx: "30.951" }),
|
|
12
|
-
index.h("path", { d: "M325.658 483.553V414.58V401.316H148.027L325.658 483.553Z" }));
|
|
12
|
+
index.h("path", { d: "M325.658 483.553V414.58V401.316H148.027L325.658 483.553Z" })));
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
15
15
|
* Heroicon: x-mark
|
|
16
16
|
*/
|
|
17
17
|
const XMarkIcon = () => {
|
|
18
|
-
return index.h("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor" },
|
|
19
|
-
index.h("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M6 18 18 6M6 6l12 12" }));
|
|
18
|
+
return (index.h("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor" },
|
|
19
|
+
index.h("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M6 18 18 6M6 6l12 12" })));
|
|
20
20
|
};
|
|
21
21
|
const GripDotsVerticalIcon = () => {
|
|
22
22
|
return (index.h("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "currentColor", viewBox: "0 0 24 24" },
|
|
@@ -2944,7 +2944,7 @@ marked.Slugger = Slugger;
|
|
|
2944
2944
|
marked.Hooks = Hooks;
|
|
2945
2945
|
marked.parse = marked;
|
|
2946
2946
|
|
|
2947
|
-
/*! @license DOMPurify 3.
|
|
2947
|
+
/*! @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 */
|
|
2948
2948
|
|
|
2949
2949
|
const {
|
|
2950
2950
|
entries,
|
|
@@ -2973,12 +2973,18 @@ if (!seal) {
|
|
|
2973
2973
|
};
|
|
2974
2974
|
}
|
|
2975
2975
|
if (!apply) {
|
|
2976
|
-
apply = function apply(
|
|
2977
|
-
|
|
2976
|
+
apply = function apply(func, thisArg) {
|
|
2977
|
+
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
2978
|
+
args[_key - 2] = arguments[_key];
|
|
2979
|
+
}
|
|
2980
|
+
return func.apply(thisArg, args);
|
|
2978
2981
|
};
|
|
2979
2982
|
}
|
|
2980
2983
|
if (!construct) {
|
|
2981
|
-
construct = function construct(Func
|
|
2984
|
+
construct = function construct(Func) {
|
|
2985
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
2986
|
+
args[_key2 - 1] = arguments[_key2];
|
|
2987
|
+
}
|
|
2982
2988
|
return new Func(...args);
|
|
2983
2989
|
};
|
|
2984
2990
|
}
|
|
@@ -3007,8 +3013,8 @@ function unapply(func) {
|
|
|
3007
3013
|
if (thisArg instanceof RegExp) {
|
|
3008
3014
|
thisArg.lastIndex = 0;
|
|
3009
3015
|
}
|
|
3010
|
-
for (var
|
|
3011
|
-
args[
|
|
3016
|
+
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
|
3017
|
+
args[_key3 - 1] = arguments[_key3];
|
|
3012
3018
|
}
|
|
3013
3019
|
return apply(func, thisArg, args);
|
|
3014
3020
|
};
|
|
@@ -3019,12 +3025,12 @@ function unapply(func) {
|
|
|
3019
3025
|
* @param func - The constructor function to be wrapped and called.
|
|
3020
3026
|
* @returns A new function that constructs an instance of the given constructor function with the provided arguments.
|
|
3021
3027
|
*/
|
|
3022
|
-
function unconstruct(
|
|
3028
|
+
function unconstruct(Func) {
|
|
3023
3029
|
return function () {
|
|
3024
|
-
for (var
|
|
3025
|
-
args[
|
|
3030
|
+
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
3031
|
+
args[_key4] = arguments[_key4];
|
|
3026
3032
|
}
|
|
3027
|
-
return construct(
|
|
3033
|
+
return construct(Func, args);
|
|
3028
3034
|
};
|
|
3029
3035
|
}
|
|
3030
3036
|
/**
|
|
@@ -3123,8 +3129,8 @@ function lookupGetter(object, prop) {
|
|
|
3123
3129
|
return fallbackValue;
|
|
3124
3130
|
}
|
|
3125
3131
|
|
|
3126
|
-
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']);
|
|
3127
|
-
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']);
|
|
3132
|
+
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']);
|
|
3133
|
+
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']);
|
|
3128
3134
|
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']);
|
|
3129
3135
|
// List of SVG elements that are disallowed by default.
|
|
3130
3136
|
// We still need to know them so that we can do namespace
|
|
@@ -3137,9 +3143,9 @@ const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mgly
|
|
|
3137
3143
|
const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
|
|
3138
3144
|
const text = freeze(['#text']);
|
|
3139
3145
|
|
|
3140
|
-
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']);
|
|
3141
|
-
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']);
|
|
3142
|
-
const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', '
|
|
3146
|
+
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']);
|
|
3147
|
+
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']);
|
|
3148
|
+
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']);
|
|
3143
3149
|
const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
3144
3150
|
|
|
3145
3151
|
// eslint-disable-next-line unicorn/better-regex
|
|
@@ -3236,7 +3242,7 @@ const _createHooksMap = function _createHooksMap() {
|
|
|
3236
3242
|
function createDOMPurify() {
|
|
3237
3243
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
3238
3244
|
const DOMPurify = root => createDOMPurify(root);
|
|
3239
|
-
DOMPurify.version = '3.
|
|
3245
|
+
DOMPurify.version = '3.4.0';
|
|
3240
3246
|
DOMPurify.removed = [];
|
|
3241
3247
|
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
3242
3248
|
// Not running in a browser, provide a factory function
|
|
@@ -3347,6 +3353,21 @@ function createDOMPurify() {
|
|
|
3347
3353
|
let FORBID_TAGS = null;
|
|
3348
3354
|
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
|
|
3349
3355
|
let FORBID_ATTR = null;
|
|
3356
|
+
/* Config object to store ADD_TAGS/ADD_ATTR functions (when used as functions) */
|
|
3357
|
+
const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
|
|
3358
|
+
tagCheck: {
|
|
3359
|
+
writable: true,
|
|
3360
|
+
configurable: false,
|
|
3361
|
+
enumerable: true,
|
|
3362
|
+
value: null
|
|
3363
|
+
},
|
|
3364
|
+
attributeCheck: {
|
|
3365
|
+
writable: true,
|
|
3366
|
+
configurable: false,
|
|
3367
|
+
enumerable: true,
|
|
3368
|
+
value: null
|
|
3369
|
+
}
|
|
3370
|
+
}));
|
|
3350
3371
|
/* Decide if ARIA attributes are okay */
|
|
3351
3372
|
let ALLOW_ARIA_ATTR = true;
|
|
3352
3373
|
/* Decide if custom data attributes are okay */
|
|
@@ -3497,7 +3518,7 @@ function createDOMPurify() {
|
|
|
3497
3518
|
NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
|
|
3498
3519
|
MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;
|
|
3499
3520
|
HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;
|
|
3500
|
-
CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING ||
|
|
3521
|
+
CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || create(null);
|
|
3501
3522
|
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
|
|
3502
3523
|
CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
|
|
3503
3524
|
}
|
|
@@ -3516,7 +3537,7 @@ function createDOMPurify() {
|
|
|
3516
3537
|
/* Parse profile info */
|
|
3517
3538
|
if (USE_PROFILES) {
|
|
3518
3539
|
ALLOWED_TAGS = addToSet({}, text);
|
|
3519
|
-
ALLOWED_ATTR =
|
|
3540
|
+
ALLOWED_ATTR = create(null);
|
|
3520
3541
|
if (USE_PROFILES.html === true) {
|
|
3521
3542
|
addToSet(ALLOWED_TAGS, html$1);
|
|
3522
3543
|
addToSet(ALLOWED_ATTR, html);
|
|
@@ -3537,18 +3558,30 @@ function createDOMPurify() {
|
|
|
3537
3558
|
addToSet(ALLOWED_ATTR, xml);
|
|
3538
3559
|
}
|
|
3539
3560
|
}
|
|
3561
|
+
/* Always reset function-based ADD_TAGS / ADD_ATTR checks to prevent
|
|
3562
|
+
* leaking across calls when switching from function to array config */
|
|
3563
|
+
EXTRA_ELEMENT_HANDLING.tagCheck = null;
|
|
3564
|
+
EXTRA_ELEMENT_HANDLING.attributeCheck = null;
|
|
3540
3565
|
/* Merge configuration parameters */
|
|
3541
3566
|
if (cfg.ADD_TAGS) {
|
|
3542
|
-
if (
|
|
3543
|
-
|
|
3567
|
+
if (typeof cfg.ADD_TAGS === 'function') {
|
|
3568
|
+
EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
|
|
3569
|
+
} else {
|
|
3570
|
+
if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
|
|
3571
|
+
ALLOWED_TAGS = clone(ALLOWED_TAGS);
|
|
3572
|
+
}
|
|
3573
|
+
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
|
|
3544
3574
|
}
|
|
3545
|
-
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
|
|
3546
3575
|
}
|
|
3547
3576
|
if (cfg.ADD_ATTR) {
|
|
3548
|
-
if (
|
|
3549
|
-
|
|
3577
|
+
if (typeof cfg.ADD_ATTR === 'function') {
|
|
3578
|
+
EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
|
|
3579
|
+
} else {
|
|
3580
|
+
if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
|
|
3581
|
+
ALLOWED_ATTR = clone(ALLOWED_ATTR);
|
|
3582
|
+
}
|
|
3583
|
+
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
|
|
3550
3584
|
}
|
|
3551
|
-
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
|
|
3552
3585
|
}
|
|
3553
3586
|
if (cfg.ADD_URI_SAFE_ATTR) {
|
|
3554
3587
|
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
|
|
@@ -3559,6 +3592,12 @@ function createDOMPurify() {
|
|
|
3559
3592
|
}
|
|
3560
3593
|
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
|
|
3561
3594
|
}
|
|
3595
|
+
if (cfg.ADD_FORBID_CONTENTS) {
|
|
3596
|
+
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
3597
|
+
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
3598
|
+
}
|
|
3599
|
+
addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
|
|
3600
|
+
}
|
|
3562
3601
|
/* Add #text in case KEEP_CONTENT is set to true */
|
|
3563
3602
|
if (KEEP_CONTENT) {
|
|
3564
3603
|
ALLOWED_TAGS['#text'] = true;
|
|
@@ -3845,6 +3884,11 @@ function createDOMPurify() {
|
|
|
3845
3884
|
_forceRemove(currentNode);
|
|
3846
3885
|
return true;
|
|
3847
3886
|
}
|
|
3887
|
+
/* Remove risky CSS construction leading to mXSS */
|
|
3888
|
+
if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === 'style' && _isNode(currentNode.firstElementChild)) {
|
|
3889
|
+
_forceRemove(currentNode);
|
|
3890
|
+
return true;
|
|
3891
|
+
}
|
|
3848
3892
|
/* Remove any occurrence of processing instructions */
|
|
3849
3893
|
if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
|
|
3850
3894
|
_forceRemove(currentNode);
|
|
@@ -3856,7 +3900,7 @@ function createDOMPurify() {
|
|
|
3856
3900
|
return true;
|
|
3857
3901
|
}
|
|
3858
3902
|
/* Remove element if anything forbids its presence */
|
|
3859
|
-
if (
|
|
3903
|
+
if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
|
|
3860
3904
|
/* Check if we have a custom element to handle */
|
|
3861
3905
|
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
|
3862
3906
|
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
|
@@ -3920,6 +3964,10 @@ function createDOMPurify() {
|
|
|
3920
3964
|
*/
|
|
3921
3965
|
// eslint-disable-next-line complexity
|
|
3922
3966
|
const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
3967
|
+
/* FORBID_ATTR must always win, even if ADD_ATTR predicate would allow it */
|
|
3968
|
+
if (FORBID_ATTR[lcName]) {
|
|
3969
|
+
return false;
|
|
3970
|
+
}
|
|
3923
3971
|
/* Make sure attribute cannot clobber */
|
|
3924
3972
|
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
3925
3973
|
return false;
|
|
@@ -3928,12 +3976,12 @@ function createDOMPurify() {
|
|
|
3928
3976
|
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
3929
3977
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
3930
3978
|
We don't need to check the value; it's always URI safe. */
|
|
3931
|
-
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]) {
|
|
3979
|
+
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]) {
|
|
3932
3980
|
if (
|
|
3933
3981
|
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
|
3934
3982
|
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
3935
3983
|
// and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
|
|
3936
|
-
_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)) ||
|
|
3984
|
+
_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)) ||
|
|
3937
3985
|
// Alternative, second condition checks if it's an `is`-attribute, AND
|
|
3938
3986
|
// the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
3939
3987
|
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 {
|
|
@@ -4012,7 +4060,12 @@ function createDOMPurify() {
|
|
|
4012
4060
|
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
|
4013
4061
|
}
|
|
4014
4062
|
/* Work around a security issue with comments inside attributes */
|
|
4015
|
-
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
|
4063
|
+
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
|
|
4064
|
+
_removeAttribute(name, currentNode);
|
|
4065
|
+
continue;
|
|
4066
|
+
}
|
|
4067
|
+
/* Make sure we cannot easily use animated hrefs, even if animations are allowed */
|
|
4068
|
+
if (lcName === 'attributename' && stringMatch(value, 'href')) {
|
|
4016
4069
|
_removeAttribute(name, currentNode);
|
|
4017
4070
|
continue;
|
|
4018
4071
|
}
|
|
@@ -4086,7 +4139,7 @@ function createDOMPurify() {
|
|
|
4086
4139
|
*
|
|
4087
4140
|
* @param fragment to iterate over recursively
|
|
4088
4141
|
*/
|
|
4089
|
-
const
|
|
4142
|
+
const _sanitizeShadowDOM2 = function _sanitizeShadowDOM(fragment) {
|
|
4090
4143
|
let shadowNode = null;
|
|
4091
4144
|
const shadowIterator = _createNodeIterator(fragment);
|
|
4092
4145
|
/* Execute a hook if present */
|
|
@@ -4100,7 +4153,7 @@ function createDOMPurify() {
|
|
|
4100
4153
|
_sanitizeAttributes(shadowNode);
|
|
4101
4154
|
/* Deep shadow DOM detected */
|
|
4102
4155
|
if (shadowNode.content instanceof DocumentFragment) {
|
|
4103
|
-
|
|
4156
|
+
_sanitizeShadowDOM2(shadowNode.content);
|
|
4104
4157
|
}
|
|
4105
4158
|
}
|
|
4106
4159
|
/* Execute a hook if present */
|
|
@@ -4195,7 +4248,7 @@ function createDOMPurify() {
|
|
|
4195
4248
|
_sanitizeAttributes(currentNode);
|
|
4196
4249
|
/* Shadow DOM detected, sanitize it */
|
|
4197
4250
|
if (currentNode.content instanceof DocumentFragment) {
|
|
4198
|
-
|
|
4251
|
+
_sanitizeShadowDOM2(currentNode.content);
|
|
4199
4252
|
}
|
|
4200
4253
|
}
|
|
4201
4254
|
/* If we sanitized `dirty` in-place, return it. */
|
|
@@ -4204,6 +4257,14 @@ function createDOMPurify() {
|
|
|
4204
4257
|
}
|
|
4205
4258
|
/* Return sanitized string or DOM */
|
|
4206
4259
|
if (RETURN_DOM) {
|
|
4260
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
4261
|
+
body.normalize();
|
|
4262
|
+
let html = body.innerHTML;
|
|
4263
|
+
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
4264
|
+
html = stringReplace(html, expr, ' ');
|
|
4265
|
+
});
|
|
4266
|
+
body.innerHTML = html;
|
|
4267
|
+
}
|
|
4207
4268
|
if (RETURN_DOM_FRAGMENT) {
|
|
4208
4269
|
returnNode = createDocumentFragment.call(body.ownerDocument);
|
|
4209
4270
|
while (body.firstChild) {
|
|
@@ -4297,7 +4358,7 @@ function postProcessMarkdownHTML(html) {
|
|
|
4297
4358
|
tempDiv.innerHTML = html;
|
|
4298
4359
|
// Add target="_blank" and rel="noopener noreferrer" to external links
|
|
4299
4360
|
const links = tempDiv.querySelectorAll('a[href]');
|
|
4300
|
-
links.forEach(
|
|
4361
|
+
links.forEach(link => {
|
|
4301
4362
|
const href = link.getAttribute('href');
|
|
4302
4363
|
if (href && (href.startsWith('http://') || href.startsWith('https://'))) {
|
|
4303
4364
|
link.setAttribute('target', '_blank');
|
|
@@ -4311,28 +4372,54 @@ function postProcessMarkdownHTML(html) {
|
|
|
4311
4372
|
return html;
|
|
4312
4373
|
}
|
|
4313
4374
|
}
|
|
4375
|
+
const SANITIZE_CONFIG = {
|
|
4376
|
+
ALLOWED_TAGS: [
|
|
4377
|
+
'p',
|
|
4378
|
+
'br',
|
|
4379
|
+
'strong',
|
|
4380
|
+
'b',
|
|
4381
|
+
'em',
|
|
4382
|
+
'i',
|
|
4383
|
+
'u',
|
|
4384
|
+
'code',
|
|
4385
|
+
'pre',
|
|
4386
|
+
'ul',
|
|
4387
|
+
'ol',
|
|
4388
|
+
'li',
|
|
4389
|
+
'h1',
|
|
4390
|
+
'h2',
|
|
4391
|
+
'h3',
|
|
4392
|
+
'h4',
|
|
4393
|
+
'h5',
|
|
4394
|
+
'h6',
|
|
4395
|
+
'blockquote',
|
|
4396
|
+
'a',
|
|
4397
|
+
'img',
|
|
4398
|
+
'hr',
|
|
4399
|
+
'table',
|
|
4400
|
+
'thead',
|
|
4401
|
+
'tbody',
|
|
4402
|
+
'tr',
|
|
4403
|
+
'td',
|
|
4404
|
+
'th',
|
|
4405
|
+
'del',
|
|
4406
|
+
'ins',
|
|
4407
|
+
'sub',
|
|
4408
|
+
'sup',
|
|
4409
|
+
],
|
|
4410
|
+
ALLOWED_ATTR: ['href', 'target', 'rel', 'class', 'src', 'alt', 'title', 'width', 'height', 'align', 'colspan', 'rowspan'],
|
|
4411
|
+
ALLOWED_URI_REGEXP: /^(?:(?:https?):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i,
|
|
4412
|
+
ADD_ATTR: ['target'],
|
|
4413
|
+
FORBID_TAGS: ['script', 'style', 'form', 'input', 'button', 'iframe', 'object', 'embed', 'svg', 'math'],
|
|
4414
|
+
FORBID_ATTR: ['onclick', 'onload', 'onerror', 'onmouseover'],
|
|
4415
|
+
};
|
|
4314
4416
|
function renderMarkdownSync(content) {
|
|
4315
4417
|
if (!content || typeof content !== 'string') {
|
|
4316
4418
|
return '';
|
|
4317
4419
|
}
|
|
4318
4420
|
try {
|
|
4319
4421
|
const html = marked.parse(content);
|
|
4320
|
-
const sanitized = purify.sanitize(html,
|
|
4321
|
-
ALLOWED_TAGS: [
|
|
4322
|
-
'p', 'br', 'strong', 'b', 'em', 'i', 'u', 'code', 'pre',
|
|
4323
|
-
'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
|
4324
|
-
'blockquote', 'a', 'img', 'hr', 'table', 'thead', 'tbody',
|
|
4325
|
-
'tr', 'td', 'th', 'del', 'ins', 'sub', 'sup'
|
|
4326
|
-
],
|
|
4327
|
-
ALLOWED_ATTR: [
|
|
4328
|
-
'href', 'target', 'rel', 'class', 'src', 'alt', 'title',
|
|
4329
|
-
'width', 'height', 'align', 'colspan', 'rowspan'
|
|
4330
|
-
],
|
|
4331
|
-
ALLOWED_URI_REGEXP: /^(?:(?:https?):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i,
|
|
4332
|
-
ADD_ATTR: ['target'],
|
|
4333
|
-
FORBID_TAGS: ['script', 'style', 'form', 'input', 'button'],
|
|
4334
|
-
FORBID_ATTR: ['onclick', 'onload', 'onerror', 'onmouseover'],
|
|
4335
|
-
});
|
|
4422
|
+
const sanitized = purify.sanitize(html, SANITIZE_CONFIG);
|
|
4336
4423
|
return postProcessMarkdownHTML(sanitized);
|
|
4337
4424
|
}
|
|
4338
4425
|
catch (error) {
|
|
@@ -4349,13 +4436,13 @@ function renderMarkdownSync(content) {
|
|
|
4349
4436
|
*/
|
|
4350
4437
|
const varToPixels = (value, maxValue, defaultValue) => {
|
|
4351
4438
|
value = value.trim();
|
|
4352
|
-
if (value.includes(
|
|
4439
|
+
if (value.includes('%')) {
|
|
4353
4440
|
const percent = percentToFloat(value);
|
|
4354
4441
|
if (!isNaN(percent)) {
|
|
4355
4442
|
return maxValue * percent;
|
|
4356
4443
|
}
|
|
4357
4444
|
}
|
|
4358
|
-
else if (value.includes(
|
|
4445
|
+
else if (value.includes('px')) {
|
|
4359
4446
|
const pixels = parseFloat(value);
|
|
4360
4447
|
if (!isNaN(pixels)) {
|
|
4361
4448
|
return pixels;
|
|
@@ -4716,9 +4803,7 @@ class TranslationManager {
|
|
|
4716
4803
|
console.error('Failed to load translations:', error);
|
|
4717
4804
|
baseTranslations = defaultTranslations;
|
|
4718
4805
|
}
|
|
4719
|
-
this.translations = customTranslations
|
|
4720
|
-
? mergeTranslations(baseTranslations, customTranslations)
|
|
4721
|
-
: baseTranslations;
|
|
4806
|
+
this.translations = customTranslations ? mergeTranslations(baseTranslations, customTranslations) : baseTranslations;
|
|
4722
4807
|
}
|
|
4723
4808
|
get(key, override) {
|
|
4724
4809
|
var _a;
|
|
@@ -4749,20 +4834,18 @@ class TranslationManager {
|
|
|
4749
4834
|
}
|
|
4750
4835
|
}
|
|
4751
4836
|
|
|
4752
|
-
/*! js-cookie v3.0.
|
|
4753
|
-
/* eslint-disable no-var */
|
|
4837
|
+
/*! js-cookie v3.0.7 | MIT */
|
|
4754
4838
|
function assign (target) {
|
|
4755
4839
|
for (var i = 1; i < arguments.length; i++) {
|
|
4756
4840
|
var source = arguments[i];
|
|
4757
4841
|
for (var key in source) {
|
|
4842
|
+
if (key === '__proto__') continue
|
|
4758
4843
|
target[key] = source[key];
|
|
4759
4844
|
}
|
|
4760
4845
|
}
|
|
4761
4846
|
return target
|
|
4762
4847
|
}
|
|
4763
|
-
/* eslint-enable no-var */
|
|
4764
4848
|
|
|
4765
|
-
/* eslint-disable no-var */
|
|
4766
4849
|
var defaultConverter = {
|
|
4767
4850
|
read: function (value) {
|
|
4768
4851
|
if (value[0] === '"') {
|
|
@@ -4777,12 +4860,9 @@ var defaultConverter = {
|
|
|
4777
4860
|
)
|
|
4778
4861
|
}
|
|
4779
4862
|
};
|
|
4780
|
-
/* eslint-enable no-var */
|
|
4781
4863
|
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
function init (converter, defaultAttributes) {
|
|
4785
|
-
function set (name, value, attributes) {
|
|
4864
|
+
function init(converter, defaultAttributes) {
|
|
4865
|
+
function set(name, value, attributes) {
|
|
4786
4866
|
if (typeof document === 'undefined') {
|
|
4787
4867
|
return
|
|
4788
4868
|
}
|
|
@@ -4826,7 +4906,7 @@ function init (converter, defaultAttributes) {
|
|
|
4826
4906
|
name + '=' + converter.write(value, name) + stringifiedAttributes)
|
|
4827
4907
|
}
|
|
4828
4908
|
|
|
4829
|
-
function get
|
|
4909
|
+
function get(name) {
|
|
4830
4910
|
if (typeof document === 'undefined' || (arguments.length && !name)) {
|
|
4831
4911
|
return
|
|
4832
4912
|
}
|
|
@@ -4841,12 +4921,13 @@ function init (converter, defaultAttributes) {
|
|
|
4841
4921
|
|
|
4842
4922
|
try {
|
|
4843
4923
|
var found = decodeURIComponent(parts[0]);
|
|
4844
|
-
jar[found] = converter.read(value, found);
|
|
4845
|
-
|
|
4924
|
+
if (!(found in jar)) jar[found] = converter.read(value, found);
|
|
4846
4925
|
if (name === found) {
|
|
4847
4926
|
break
|
|
4848
4927
|
}
|
|
4849
|
-
} catch
|
|
4928
|
+
} catch {
|
|
4929
|
+
// Do nothing...
|
|
4930
|
+
}
|
|
4850
4931
|
}
|
|
4851
4932
|
|
|
4852
4933
|
return name ? jar[name] : jar
|
|
@@ -4939,7 +5020,17 @@ class ChatSessionService {
|
|
|
4939
5020
|
headers: this.getCommonHeaders(),
|
|
4940
5021
|
});
|
|
4941
5022
|
if (!response.ok) {
|
|
4942
|
-
|
|
5023
|
+
let errorMessage = `Failed to poll task: ${response.statusText}`;
|
|
5024
|
+
try {
|
|
5025
|
+
const data = (await response.json());
|
|
5026
|
+
if (data === null || data === void 0 ? void 0 : data.error) {
|
|
5027
|
+
errorMessage = data.error;
|
|
5028
|
+
}
|
|
5029
|
+
}
|
|
5030
|
+
catch (_a) {
|
|
5031
|
+
// non-JSON body; keep statusText fallback
|
|
5032
|
+
}
|
|
5033
|
+
throw new Error(errorMessage);
|
|
4943
5034
|
}
|
|
4944
5035
|
return response.json();
|
|
4945
5036
|
}
|
|
@@ -4953,6 +5044,7 @@ class ChatSessionService {
|
|
|
4953
5044
|
}, this.taskPollingIntervalMs);
|
|
4954
5045
|
};
|
|
4955
5046
|
const poll = async () => {
|
|
5047
|
+
var _a;
|
|
4956
5048
|
if (cancelled) {
|
|
4957
5049
|
return;
|
|
4958
5050
|
}
|
|
@@ -4965,6 +5057,9 @@ class ChatSessionService {
|
|
|
4965
5057
|
callbacks.onMessage(data.message);
|
|
4966
5058
|
return;
|
|
4967
5059
|
}
|
|
5060
|
+
if (data.status === 'processing' && ((_a = data.message) === null || _a === void 0 ? void 0 : _a.content) && callbacks.onProgress) {
|
|
5061
|
+
callbacks.onProgress(data.message.content);
|
|
5062
|
+
}
|
|
4968
5063
|
attempts += 1;
|
|
4969
5064
|
if (attempts >= this.taskPollingMaxAttempts) {
|
|
4970
5065
|
if (callbacks.onTimeout) {
|
|
@@ -5003,6 +5098,29 @@ class ChatSessionService {
|
|
|
5003
5098
|
}
|
|
5004
5099
|
return response.json();
|
|
5005
5100
|
}
|
|
5101
|
+
/**
|
|
5102
|
+
* Fetch the complete message history for a session by paging through the
|
|
5103
|
+
* poll endpoint until no more messages remain.
|
|
5104
|
+
*/
|
|
5105
|
+
async fetchAllMessages(sessionId) {
|
|
5106
|
+
var _a;
|
|
5107
|
+
const allMessages = [];
|
|
5108
|
+
let since;
|
|
5109
|
+
let hasMore = true;
|
|
5110
|
+
for (let page = 0; hasMore && page < ChatSessionService.MAX_HISTORY_PAGES; page++) {
|
|
5111
|
+
const data = await this.fetchMessages(sessionId, since);
|
|
5112
|
+
allMessages.push(...data.messages);
|
|
5113
|
+
hasMore = data.has_more && data.messages.length > 0;
|
|
5114
|
+
// The server returns pages in ascending created_at order and `since` is
|
|
5115
|
+
// exclusive (created_at > since), so the last message's timestamp is the
|
|
5116
|
+
// next page cursor.
|
|
5117
|
+
since = (_a = data.messages.at(-1)) === null || _a === void 0 ? void 0 : _a.created_at;
|
|
5118
|
+
}
|
|
5119
|
+
if (hasMore) {
|
|
5120
|
+
console.warn('Chat history truncated after', ChatSessionService.MAX_HISTORY_PAGES, 'pages');
|
|
5121
|
+
}
|
|
5122
|
+
return allMessages;
|
|
5123
|
+
}
|
|
5006
5124
|
startMessagePolling(sessionId, callbacks) {
|
|
5007
5125
|
const poll = async () => {
|
|
5008
5126
|
try {
|
|
@@ -5052,6 +5170,7 @@ class ChatSessionService {
|
|
|
5052
5170
|
return headers;
|
|
5053
5171
|
}
|
|
5054
5172
|
}
|
|
5173
|
+
ChatSessionService.MAX_HISTORY_PAGES = 40;
|
|
5055
5174
|
|
|
5056
5175
|
class FileAttachmentManager {
|
|
5057
5176
|
constructor(config) {
|
|
@@ -5065,8 +5184,8 @@ class FileAttachmentManager {
|
|
|
5065
5184
|
let totalSize = existingFiles.reduce((sum, f) => sum + f.file.size, 0);
|
|
5066
5185
|
for (const file of fileArray) {
|
|
5067
5186
|
const extension = this.getFileExtension(file.name);
|
|
5068
|
-
const contentType = file.type.split(
|
|
5069
|
-
if (contentType !=
|
|
5187
|
+
const contentType = file.type.split('/')[0];
|
|
5188
|
+
if (contentType != 'text' && !this.supportedExtensions.includes(extension)) {
|
|
5070
5189
|
newSelected.push({ file, error: `File type ${extension} not supported` });
|
|
5071
5190
|
continue;
|
|
5072
5191
|
}
|
|
@@ -5101,9 +5220,7 @@ class FileAttachmentManager {
|
|
|
5101
5220
|
return { selectedFiles: existingFiles, uploadedIds: [] };
|
|
5102
5221
|
}
|
|
5103
5222
|
const uploadCandidates = existingFiles.filter(file => !file.error && !file.uploaded);
|
|
5104
|
-
const uploadedIds = existingFiles
|
|
5105
|
-
.filter(file => file.uploaded)
|
|
5106
|
-
.map(file => file.uploaded.id);
|
|
5223
|
+
const uploadedIds = existingFiles.filter(file => file.uploaded).map(file => file.uploaded.id);
|
|
5107
5224
|
if (uploadCandidates.length === 0) {
|
|
5108
5225
|
return { selectedFiles: existingFiles, uploadedIds };
|
|
5109
5226
|
}
|
|
@@ -5122,8 +5239,7 @@ class FileAttachmentManager {
|
|
|
5122
5239
|
});
|
|
5123
5240
|
if (!response.ok) {
|
|
5124
5241
|
const errorData = await this.safeJson(response);
|
|
5125
|
-
const errorMessage = (errorData && typeof errorData === 'object' && 'error' in errorData && errorData.error) ||
|
|
5126
|
-
'Failed to upload files';
|
|
5242
|
+
const errorMessage = (errorData && typeof errorData === 'object' && 'error' in errorData && errorData.error) || 'Failed to upload files';
|
|
5127
5243
|
return {
|
|
5128
5244
|
selectedFiles: this.markPendingFilesWithError(existingFiles, errorMessage),
|
|
5129
5245
|
uploadedIds,
|
|
@@ -5179,7 +5295,7 @@ class FileAttachmentManager {
|
|
|
5179
5295
|
}
|
|
5180
5296
|
}
|
|
5181
5297
|
|
|
5182
|
-
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}}";
|
|
5298
|
+
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}}";
|
|
5183
5299
|
|
|
5184
5300
|
const OcsChat = class {
|
|
5185
5301
|
constructor(hostRef) {
|
|
@@ -5187,11 +5303,23 @@ const OcsChat = class {
|
|
|
5187
5303
|
/**
|
|
5188
5304
|
* The base URL for the API.
|
|
5189
5305
|
*/
|
|
5190
|
-
this.apiBaseUrl =
|
|
5306
|
+
this.apiBaseUrl = 'https://www.openchatstudio.com';
|
|
5191
5307
|
/**
|
|
5192
5308
|
* The shape of the chat button. 'round' makes it circular, 'square' keeps it rectangular.
|
|
5193
5309
|
*/
|
|
5194
5310
|
this.buttonShape = 'square';
|
|
5311
|
+
/**
|
|
5312
|
+
* Whether to show the launcher button. Set to false to hide the button
|
|
5313
|
+
* and open the chat window programmatically via the `visible` property.
|
|
5314
|
+
*/
|
|
5315
|
+
this.showButton = true;
|
|
5316
|
+
/**
|
|
5317
|
+
* The operating mode of the widget.
|
|
5318
|
+
* - 'standard': Default floating window with launcher button.
|
|
5319
|
+
* - 'kiosk': Fills parent container, always visible, no header or launcher button.
|
|
5320
|
+
* The parent element must establish a containing block (e.g. `position: relative`).
|
|
5321
|
+
*/
|
|
5322
|
+
this.mode = 'standard';
|
|
5195
5323
|
/**
|
|
5196
5324
|
* Whether the chat widget is visible on load.
|
|
5197
5325
|
*/
|
|
@@ -5202,6 +5330,7 @@ const OcsChat = class {
|
|
|
5202
5330
|
this.position = 'right';
|
|
5203
5331
|
/**
|
|
5204
5332
|
* Whether to persist session data to local storage to allow resuming previous conversations after page reload.
|
|
5333
|
+
* Ignored when `sessionId` is provided.
|
|
5205
5334
|
*/
|
|
5206
5335
|
this.persistentSession = true;
|
|
5207
5336
|
/**
|
|
@@ -5217,12 +5346,13 @@ const OcsChat = class {
|
|
|
5217
5346
|
* Allow the user to attach files to their messages.
|
|
5218
5347
|
*/
|
|
5219
5348
|
this.allowAttachments = false;
|
|
5220
|
-
this.error =
|
|
5349
|
+
this.error = '';
|
|
5221
5350
|
this.messages = [];
|
|
5222
5351
|
this.isLoading = false;
|
|
5223
5352
|
this.isTyping = false;
|
|
5224
|
-
this.
|
|
5225
|
-
this.
|
|
5353
|
+
this.typingProgressMessage = '';
|
|
5354
|
+
this.messageInput = '';
|
|
5355
|
+
this.currentPollTaskId = '';
|
|
5226
5356
|
this.isDragging = false;
|
|
5227
5357
|
this.dragOffset = { x: 0, y: 0 };
|
|
5228
5358
|
this.windowPosition = { x: 0, y: 0 };
|
|
@@ -5251,6 +5381,7 @@ const OcsChat = class {
|
|
|
5251
5381
|
this.chatWindowWidth = 450;
|
|
5252
5382
|
this.chatWindowFullscreenWidth = 1024;
|
|
5253
5383
|
this.positionInitialized = false;
|
|
5384
|
+
this.sessionEpoch = 0;
|
|
5254
5385
|
this.handleMouseDown = (event) => {
|
|
5255
5386
|
if (!this.isFullscreen && window.innerWidth < OcsChat.MOBILE_BREAKPOINT)
|
|
5256
5387
|
return;
|
|
@@ -5296,6 +5427,8 @@ const OcsChat = class {
|
|
|
5296
5427
|
};
|
|
5297
5428
|
this.handleWindowResize = () => {
|
|
5298
5429
|
var _a, _b;
|
|
5430
|
+
if (this.isKioskMode())
|
|
5431
|
+
return;
|
|
5299
5432
|
this.positionInitialized = false;
|
|
5300
5433
|
this.initializePosition();
|
|
5301
5434
|
// Revalidate button position after resize to keep it within viewport bounds
|
|
@@ -5307,7 +5440,7 @@ const OcsChat = class {
|
|
|
5307
5440
|
const minPadding = 10;
|
|
5308
5441
|
this.buttonPosition = {
|
|
5309
5442
|
x: Math.max(minPadding, Math.min(this.buttonPosition.x, windowWidth - buttonWidth - minPadding)),
|
|
5310
|
-
y: Math.max(minPadding, Math.min(this.buttonPosition.y, windowHeight - buttonHeight - minPadding))
|
|
5443
|
+
y: Math.max(minPadding, Math.min(this.buttonPosition.y, windowHeight - buttonHeight - minPadding)),
|
|
5311
5444
|
};
|
|
5312
5445
|
this.updateHostPosition();
|
|
5313
5446
|
}
|
|
@@ -5325,7 +5458,7 @@ const OcsChat = class {
|
|
|
5325
5458
|
const rect = this.host.getBoundingClientRect();
|
|
5326
5459
|
this.buttonDragOffset = {
|
|
5327
5460
|
x: pointer.clientX - rect.left,
|
|
5328
|
-
y: pointer.clientY - rect.top
|
|
5461
|
+
y: pointer.clientY - rect.top,
|
|
5329
5462
|
};
|
|
5330
5463
|
this.addButtonEventListeners();
|
|
5331
5464
|
};
|
|
@@ -5342,7 +5475,7 @@ const OcsChat = class {
|
|
|
5342
5475
|
const rect = this.host.getBoundingClientRect();
|
|
5343
5476
|
this.buttonDragOffset = {
|
|
5344
5477
|
x: pointer.clientX - rect.left,
|
|
5345
|
-
y: pointer.clientY - rect.top
|
|
5478
|
+
y: pointer.clientY - rect.top,
|
|
5346
5479
|
};
|
|
5347
5480
|
this.addButtonEventListeners();
|
|
5348
5481
|
};
|
|
@@ -5389,12 +5522,19 @@ const OcsChat = class {
|
|
|
5389
5522
|
this.error = 'Chatbot ID is required';
|
|
5390
5523
|
return;
|
|
5391
5524
|
}
|
|
5525
|
+
if (this.isKioskMode()) {
|
|
5526
|
+
this.visible = true;
|
|
5527
|
+
}
|
|
5392
5528
|
await this.initializeTranslations();
|
|
5393
|
-
|
|
5394
|
-
|
|
5529
|
+
if (this.isSessionBound()) {
|
|
5530
|
+
// Bound to an externally-managed session: the host page is the source of truth.
|
|
5531
|
+
this.activeSessionId = this.sessionId;
|
|
5532
|
+
}
|
|
5533
|
+
else if (this.persistentSession && this.isLocalStorageAvailable()) {
|
|
5534
|
+
// Always try to load existing session if localStorage is available
|
|
5395
5535
|
const { sessionId, messages } = this.loadSessionFromStorage();
|
|
5396
5536
|
if (sessionId && messages) {
|
|
5397
|
-
this.
|
|
5537
|
+
this.activeSessionId = sessionId;
|
|
5398
5538
|
this.messages = messages;
|
|
5399
5539
|
}
|
|
5400
5540
|
}
|
|
@@ -5411,15 +5551,29 @@ const OcsChat = class {
|
|
|
5411
5551
|
this.chatWindowWidth = varToPixels(windowWidthVar, window.innerWidth, this.chatWindowWidth);
|
|
5412
5552
|
this.chatWindowFullscreenWidth = varToPixels(fullscreenWidthVar, window.innerWidth, this.chatWindowFullscreenWidth);
|
|
5413
5553
|
// Initialize button position from computed styles
|
|
5414
|
-
this.
|
|
5415
|
-
|
|
5554
|
+
if (this.showButton && !this.isKioskMode()) {
|
|
5555
|
+
this.initializeButtonPosition();
|
|
5556
|
+
}
|
|
5557
|
+
// Defer state changes to avoid triggering them during componentDidLoad
|
|
5416
5558
|
setTimeout(() => {
|
|
5559
|
+
// Restore visible state after dimensions are read so initializePosition
|
|
5560
|
+
// uses the correct CSS-derived chatWindowWidth/chatWindowHeight.
|
|
5561
|
+
if (!this.isKioskMode() && this.showButton && this.persistentSession && this.isLocalStorageAvailable()) {
|
|
5562
|
+
this.restoreVisibleState();
|
|
5563
|
+
}
|
|
5417
5564
|
if (this.visible) {
|
|
5418
|
-
this.
|
|
5565
|
+
if (!this.isKioskMode()) {
|
|
5566
|
+
this.initializePosition();
|
|
5567
|
+
}
|
|
5419
5568
|
}
|
|
5420
5569
|
// Resume polling for existing session (don't auto-start new sessions)
|
|
5421
|
-
if (this.visible && this.
|
|
5422
|
-
this.
|
|
5570
|
+
if (this.visible && this.activeSessionId) {
|
|
5571
|
+
if (this.isSessionBound()) {
|
|
5572
|
+
void this.loadBoundSessionHistory();
|
|
5573
|
+
}
|
|
5574
|
+
else {
|
|
5575
|
+
this.startMessagePolling();
|
|
5576
|
+
}
|
|
5423
5577
|
}
|
|
5424
5578
|
}, 0);
|
|
5425
5579
|
window.addEventListener('resize', this.handleWindowResize);
|
|
@@ -5448,7 +5602,7 @@ const OcsChat = class {
|
|
|
5448
5602
|
created_at: new Date().toISOString(),
|
|
5449
5603
|
role: 'system',
|
|
5450
5604
|
content: `**Error:** ${errorText}\nPlease try again.`,
|
|
5451
|
-
attachments: []
|
|
5605
|
+
attachments: [],
|
|
5452
5606
|
};
|
|
5453
5607
|
this.messages = [...this.messages, errorMessage];
|
|
5454
5608
|
this.saveSessionToStorage();
|
|
@@ -5498,7 +5652,7 @@ const OcsChat = class {
|
|
|
5498
5652
|
return;
|
|
5499
5653
|
}
|
|
5500
5654
|
if (typeof this.pageContext !== 'object' || Array.isArray(this.pageContext)) {
|
|
5501
|
-
console.error(
|
|
5655
|
+
console.error('pageContext is expected to be a plain JavaScript object.');
|
|
5502
5656
|
return;
|
|
5503
5657
|
}
|
|
5504
5658
|
this.internalPageContext = this.pageContext;
|
|
@@ -5526,6 +5680,7 @@ const OcsChat = class {
|
|
|
5526
5680
|
this.currentPollTaskId = '';
|
|
5527
5681
|
}
|
|
5528
5682
|
async startSession() {
|
|
5683
|
+
const epoch = this.sessionEpoch;
|
|
5529
5684
|
try {
|
|
5530
5685
|
this.isLoading = true;
|
|
5531
5686
|
const userId = this.getOrGenerateUserId();
|
|
@@ -5533,34 +5688,65 @@ const OcsChat = class {
|
|
|
5533
5688
|
chatbot_id: this.chatbotId,
|
|
5534
5689
|
session_data: {
|
|
5535
5690
|
source: 'widget',
|
|
5536
|
-
page_url: window.location.href
|
|
5691
|
+
page_url: window.location.href,
|
|
5537
5692
|
},
|
|
5538
|
-
participant_remote_id: userId
|
|
5693
|
+
participant_remote_id: userId,
|
|
5539
5694
|
};
|
|
5540
5695
|
if (this.userName) {
|
|
5541
5696
|
requestBody.participant_name = this.userName;
|
|
5542
5697
|
}
|
|
5698
|
+
if (this.versionNumber != null) {
|
|
5699
|
+
requestBody.version_number = this.versionNumber;
|
|
5700
|
+
}
|
|
5543
5701
|
const data = await this.getChatService().startSession(requestBody);
|
|
5544
|
-
|
|
5702
|
+
if (epoch !== this.sessionEpoch)
|
|
5703
|
+
return;
|
|
5704
|
+
this.activeSessionId = data.session_id;
|
|
5545
5705
|
this.saveSessionToStorage();
|
|
5546
5706
|
this.startMessagePolling();
|
|
5547
5707
|
}
|
|
5548
5708
|
catch (_error) {
|
|
5709
|
+
if (epoch !== this.sessionEpoch)
|
|
5710
|
+
return;
|
|
5549
5711
|
this.handleError('Failed to start chat session');
|
|
5550
5712
|
}
|
|
5551
5713
|
finally {
|
|
5552
5714
|
this.isLoading = false;
|
|
5553
5715
|
}
|
|
5554
5716
|
}
|
|
5717
|
+
/**
|
|
5718
|
+
* Load the full message history for a session provided via the `session-id`
|
|
5719
|
+
* prop, then begin regular polling.
|
|
5720
|
+
*/
|
|
5721
|
+
async loadBoundSessionHistory() {
|
|
5722
|
+
const epoch = this.sessionEpoch;
|
|
5723
|
+
try {
|
|
5724
|
+
const history = await this.getChatService().fetchAllMessages(this.activeSessionId);
|
|
5725
|
+
if (epoch !== this.sessionEpoch)
|
|
5726
|
+
return;
|
|
5727
|
+
// Keep messages added while the history was loading (e.g. an optimistic
|
|
5728
|
+
// user message) by appending any that aren't part of the fetched history.
|
|
5729
|
+
const known = new Set(history.map(m => `${m.created_at}|${m.role}|${m.content}`));
|
|
5730
|
+
const pending = this.messages.filter(m => !known.has(`${m.created_at}|${m.role}|${m.content}`));
|
|
5731
|
+
this.messages = [...history, ...pending];
|
|
5732
|
+
this.scrollToBottom(true);
|
|
5733
|
+
}
|
|
5734
|
+
catch (error) {
|
|
5735
|
+
if (epoch !== this.sessionEpoch)
|
|
5736
|
+
return;
|
|
5737
|
+
console.warn('Failed to load chat history:', error);
|
|
5738
|
+
}
|
|
5739
|
+
this.startMessagePolling();
|
|
5740
|
+
}
|
|
5555
5741
|
async uploadFiles() {
|
|
5556
|
-
if (this.selectedFiles.length === 0 || !this.
|
|
5742
|
+
if (this.selectedFiles.length === 0 || !this.activeSessionId || !this.allowAttachments) {
|
|
5557
5743
|
return [];
|
|
5558
5744
|
}
|
|
5559
5745
|
this.isUploadingFiles = true;
|
|
5560
5746
|
try {
|
|
5561
5747
|
const uploadResult = await this.attachmentManager.uploadPendingFiles(this.selectedFiles, {
|
|
5562
5748
|
apiBaseUrl: this.apiBaseUrl || 'https://www.openchatstudio.com',
|
|
5563
|
-
sessionId: this.
|
|
5749
|
+
sessionId: this.activeSessionId,
|
|
5564
5750
|
participantId: this.getOrGenerateUserId(),
|
|
5565
5751
|
participantName: this.userName,
|
|
5566
5752
|
});
|
|
@@ -5574,15 +5760,16 @@ const OcsChat = class {
|
|
|
5574
5760
|
async sendMessage(message) {
|
|
5575
5761
|
if (!message.trim())
|
|
5576
5762
|
return;
|
|
5763
|
+
const epoch = this.sessionEpoch;
|
|
5577
5764
|
// Start session if we don't have one yet
|
|
5578
|
-
if (!this.
|
|
5765
|
+
if (!this.activeSessionId) {
|
|
5579
5766
|
// Prevent concurrent session initialization
|
|
5580
5767
|
if (this.isLoading) {
|
|
5581
5768
|
return;
|
|
5582
5769
|
}
|
|
5583
5770
|
await this.startSession();
|
|
5584
5771
|
// Check if session started successfully
|
|
5585
|
-
if (!this.
|
|
5772
|
+
if (!this.activeSessionId) {
|
|
5586
5773
|
return; // startSession already handled the error
|
|
5587
5774
|
}
|
|
5588
5775
|
}
|
|
@@ -5607,7 +5794,7 @@ const OcsChat = class {
|
|
|
5607
5794
|
created_at: new Date(now.getTime() - (welcomeMessagesToAdd.length - index) * 1000).toISOString(),
|
|
5608
5795
|
role: 'assistant',
|
|
5609
5796
|
content: welcomeMsg,
|
|
5610
|
-
attachments: []
|
|
5797
|
+
attachments: [],
|
|
5611
5798
|
}));
|
|
5612
5799
|
this.messages = [...this.messages, ...welcomeMessages];
|
|
5613
5800
|
}
|
|
@@ -5616,13 +5803,15 @@ const OcsChat = class {
|
|
|
5616
5803
|
created_at: new Date().toISOString(),
|
|
5617
5804
|
role: 'user',
|
|
5618
5805
|
content: message.trim(),
|
|
5619
|
-
attachments: this.allowAttachments
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5806
|
+
attachments: this.allowAttachments
|
|
5807
|
+
? this.selectedFiles
|
|
5808
|
+
.filter(sf => !sf.error && sf.uploaded)
|
|
5809
|
+
.map(sf => ({
|
|
5810
|
+
name: sf.file.name,
|
|
5811
|
+
content_type: sf.file.type,
|
|
5812
|
+
size: sf.file.size,
|
|
5813
|
+
}))
|
|
5814
|
+
: [],
|
|
5626
5815
|
};
|
|
5627
5816
|
this.messages = [...this.messages, userMessage];
|
|
5628
5817
|
this.saveSessionToStorage();
|
|
@@ -5638,7 +5827,12 @@ const OcsChat = class {
|
|
|
5638
5827
|
if (this.internalPageContext) {
|
|
5639
5828
|
requestBody.context = this.internalPageContext;
|
|
5640
5829
|
}
|
|
5641
|
-
|
|
5830
|
+
if (this.versionNumber != null) {
|
|
5831
|
+
requestBody.version_number = this.versionNumber;
|
|
5832
|
+
}
|
|
5833
|
+
const data = await this.getChatService().sendMessage(this.activeSessionId, requestBody);
|
|
5834
|
+
if (epoch !== this.sessionEpoch)
|
|
5835
|
+
return;
|
|
5642
5836
|
if (data.status === 'error') {
|
|
5643
5837
|
throw new Error(data.error || 'Failed to send message');
|
|
5644
5838
|
}
|
|
@@ -5646,6 +5840,8 @@ const OcsChat = class {
|
|
|
5646
5840
|
this.startTaskPolling(data.task_id);
|
|
5647
5841
|
}
|
|
5648
5842
|
catch (error) {
|
|
5843
|
+
if (epoch !== this.sessionEpoch)
|
|
5844
|
+
return;
|
|
5649
5845
|
const errorText = error instanceof Error ? error.message : 'Failed to send message';
|
|
5650
5846
|
this.handleError(errorText);
|
|
5651
5847
|
}
|
|
@@ -5668,10 +5864,10 @@ const OcsChat = class {
|
|
|
5668
5864
|
const childRect = lastChild.getBoundingClientRect();
|
|
5669
5865
|
const currentScrollTop = this.messageListRef.scrollTop;
|
|
5670
5866
|
const childTopRelativeToParent = childRect.top - parentRect.top;
|
|
5671
|
-
const targetScroll = currentScrollTop + childTopRelativeToParent -
|
|
5867
|
+
const targetScroll = currentScrollTop + childTopRelativeToParent - parentRect.height / 2;
|
|
5672
5868
|
this.messageListRef.scrollTo({
|
|
5673
5869
|
top: targetScroll,
|
|
5674
|
-
behavior: 'smooth'
|
|
5870
|
+
behavior: 'smooth',
|
|
5675
5871
|
});
|
|
5676
5872
|
}
|
|
5677
5873
|
else {
|
|
@@ -5716,10 +5912,10 @@ const OcsChat = class {
|
|
|
5716
5912
|
const k = 1024;
|
|
5717
5913
|
if (bytes < k * k) {
|
|
5718
5914
|
// Less than 1MB, show in KB
|
|
5719
|
-
return Math.round(bytes / k * 100) / 100 + ' KB';
|
|
5915
|
+
return Math.round((bytes / k) * 100) / 100 + ' KB';
|
|
5720
5916
|
}
|
|
5721
5917
|
else {
|
|
5722
|
-
return Math.round(bytes / (k * k) * 100) / 100 + ' MB';
|
|
5918
|
+
return Math.round((bytes / (k * k)) * 100) / 100 + ' MB';
|
|
5723
5919
|
}
|
|
5724
5920
|
}
|
|
5725
5921
|
formatTime(dateString) {
|
|
@@ -5737,23 +5933,40 @@ const OcsChat = class {
|
|
|
5737
5933
|
pageContextHandler() {
|
|
5738
5934
|
this.loadInternalPageContext();
|
|
5739
5935
|
}
|
|
5936
|
+
async chatbotConfigHandler() {
|
|
5937
|
+
await this.clearSession();
|
|
5938
|
+
}
|
|
5740
5939
|
/**
|
|
5741
5940
|
* Watch for changes to the `visible` attribute and update accordingly.
|
|
5742
5941
|
*
|
|
5743
5942
|
* @param visible - The new value for the field.
|
|
5744
5943
|
*/
|
|
5745
5944
|
async visibilityHandler(visible) {
|
|
5945
|
+
// Kiosk mode is always visible
|
|
5946
|
+
if (this.isKioskMode() && !visible) {
|
|
5947
|
+
this.visible = true;
|
|
5948
|
+
return;
|
|
5949
|
+
}
|
|
5950
|
+
this.saveVisibleState(visible);
|
|
5746
5951
|
if (this.isButtonDragging) {
|
|
5747
5952
|
this.isButtonDragging = false;
|
|
5748
5953
|
this.buttonWasDragged = false;
|
|
5749
5954
|
this.removeButtonEventListeners();
|
|
5750
5955
|
}
|
|
5751
5956
|
if (visible) {
|
|
5752
|
-
this.
|
|
5957
|
+
if (!this.isKioskMode()) {
|
|
5958
|
+
this.initializePosition();
|
|
5959
|
+
}
|
|
5753
5960
|
// Resume polling for existing session (don't auto-start new sessions)
|
|
5754
|
-
if (this.
|
|
5961
|
+
if (this.activeSessionId) {
|
|
5755
5962
|
this.scrollToBottom(true);
|
|
5756
|
-
this.
|
|
5963
|
+
if (this.isSessionBound() && this.messages.length === 0) {
|
|
5964
|
+
// A bound widget that was hidden at load has not fetched its history yet.
|
|
5965
|
+
void this.loadBoundSessionHistory();
|
|
5966
|
+
}
|
|
5967
|
+
else {
|
|
5968
|
+
this.startMessagePolling();
|
|
5969
|
+
}
|
|
5757
5970
|
}
|
|
5758
5971
|
}
|
|
5759
5972
|
else {
|
|
@@ -5761,7 +5974,7 @@ const OcsChat = class {
|
|
|
5761
5974
|
}
|
|
5762
5975
|
}
|
|
5763
5976
|
startTaskPolling(taskId) {
|
|
5764
|
-
if (!this.
|
|
5977
|
+
if (!this.activeSessionId)
|
|
5765
5978
|
return;
|
|
5766
5979
|
this.currentPollTaskId = taskId;
|
|
5767
5980
|
this.isTyping = true;
|
|
@@ -5769,50 +5982,56 @@ const OcsChat = class {
|
|
|
5769
5982
|
if (this.taskPollingHandle) {
|
|
5770
5983
|
this.taskPollingHandle.cancel();
|
|
5771
5984
|
}
|
|
5772
|
-
this.taskPollingHandle = this.getChatService().pollTask(this.
|
|
5773
|
-
onMessage:
|
|
5985
|
+
this.taskPollingHandle = this.getChatService().pollTask(this.activeSessionId, taskId, {
|
|
5986
|
+
onMessage: message => {
|
|
5774
5987
|
this.messages = [...this.messages, message];
|
|
5775
5988
|
this.saveSessionToStorage();
|
|
5776
5989
|
this.scrollToBottom();
|
|
5777
5990
|
this.isTyping = false;
|
|
5991
|
+
this.typingProgressMessage = '';
|
|
5778
5992
|
this.currentPollTaskId = '';
|
|
5779
5993
|
this.taskPollingHandle = undefined;
|
|
5780
5994
|
this.startMessagePolling();
|
|
5781
5995
|
this.focusInput();
|
|
5782
5996
|
},
|
|
5997
|
+
onProgress: message => {
|
|
5998
|
+
this.typingProgressMessage = message;
|
|
5999
|
+
},
|
|
5783
6000
|
onTimeout: () => {
|
|
5784
6001
|
const timeoutMessage = {
|
|
5785
6002
|
created_at: new Date().toISOString(),
|
|
5786
6003
|
role: 'system',
|
|
5787
6004
|
content: 'The response is taking longer than expected. The system may be experiencing delays. Please try sending your message again.',
|
|
5788
|
-
attachments: []
|
|
6005
|
+
attachments: [],
|
|
5789
6006
|
};
|
|
5790
6007
|
this.messages = [...this.messages, timeoutMessage];
|
|
5791
6008
|
this.saveSessionToStorage();
|
|
5792
6009
|
this.scrollToBottom();
|
|
5793
6010
|
this.isTyping = false;
|
|
6011
|
+
this.typingProgressMessage = '';
|
|
5794
6012
|
this.currentPollTaskId = '';
|
|
5795
6013
|
this.taskPollingHandle = undefined;
|
|
5796
6014
|
this.startMessagePolling();
|
|
5797
6015
|
this.focusInput();
|
|
5798
6016
|
},
|
|
5799
|
-
onError:
|
|
6017
|
+
onError: error => {
|
|
6018
|
+
this.typingProgressMessage = '';
|
|
5800
6019
|
this.handleError(error.message);
|
|
5801
6020
|
this.taskPollingHandle = undefined;
|
|
5802
6021
|
this.startMessagePolling();
|
|
5803
|
-
}
|
|
6022
|
+
},
|
|
5804
6023
|
});
|
|
5805
6024
|
}
|
|
5806
6025
|
startMessagePolling() {
|
|
5807
|
-
if (!this.
|
|
6026
|
+
if (!this.activeSessionId || this.currentPollTaskId || !this.visible) {
|
|
5808
6027
|
return;
|
|
5809
6028
|
}
|
|
5810
6029
|
if (this.messagePollingHandle) {
|
|
5811
6030
|
return;
|
|
5812
6031
|
}
|
|
5813
|
-
this.messagePollingHandle = this.getChatService().startMessagePolling(this.
|
|
5814
|
-
getSince: () => { var _a; return this.messages.length > 0 ? (_a = this.messages.at(-1)) === null || _a === void 0 ? void 0 : _a.created_at : undefined; },
|
|
5815
|
-
onMessages:
|
|
6032
|
+
this.messagePollingHandle = this.getChatService().startMessagePolling(this.activeSessionId, {
|
|
6033
|
+
getSince: () => { var _a; return (this.messages.length > 0 ? (_a = this.messages.at(-1)) === null || _a === void 0 ? void 0 : _a.created_at : undefined); },
|
|
6034
|
+
onMessages: messages => {
|
|
5816
6035
|
if (messages.length === 0)
|
|
5817
6036
|
return;
|
|
5818
6037
|
this.messages = [...this.messages, ...messages];
|
|
@@ -5822,7 +6041,7 @@ const OcsChat = class {
|
|
|
5822
6041
|
},
|
|
5823
6042
|
onError: () => {
|
|
5824
6043
|
// Silently ignore polling errors to match previous behaviour
|
|
5825
|
-
}
|
|
6044
|
+
},
|
|
5826
6045
|
});
|
|
5827
6046
|
}
|
|
5828
6047
|
stopMessagePolling() {
|
|
@@ -5841,6 +6060,9 @@ const OcsChat = class {
|
|
|
5841
6060
|
this.position = position;
|
|
5842
6061
|
}
|
|
5843
6062
|
getPositionClasses() {
|
|
6063
|
+
if (this.isKioskMode()) {
|
|
6064
|
+
return 'chat-window-kiosk';
|
|
6065
|
+
}
|
|
5844
6066
|
if (this.isFullscreen) {
|
|
5845
6067
|
return 'chat-window-fullscreen';
|
|
5846
6068
|
}
|
|
@@ -5856,6 +6078,9 @@ const OcsChat = class {
|
|
|
5856
6078
|
return { windowWidth, actualChatWidth, centeredX, maxOffset };
|
|
5857
6079
|
}
|
|
5858
6080
|
getPositionStyles() {
|
|
6081
|
+
if (this.isKioskMode()) {
|
|
6082
|
+
return {};
|
|
6083
|
+
}
|
|
5859
6084
|
if (this.isFullscreen) {
|
|
5860
6085
|
const { centeredX } = this.getFullscreenBounds();
|
|
5861
6086
|
const finalX = centeredX + this.fullscreenPosition.x;
|
|
@@ -5887,19 +6112,19 @@ const OcsChat = class {
|
|
|
5887
6112
|
case 'left':
|
|
5888
6113
|
this.windowPosition = {
|
|
5889
6114
|
x: OcsChat.WINDOW_MARGIN,
|
|
5890
|
-
y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN
|
|
6115
|
+
y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN,
|
|
5891
6116
|
};
|
|
5892
6117
|
break;
|
|
5893
6118
|
case 'right':
|
|
5894
6119
|
this.windowPosition = {
|
|
5895
6120
|
x: windowWidth - chatWidth - OcsChat.WINDOW_MARGIN,
|
|
5896
|
-
y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN
|
|
6121
|
+
y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN,
|
|
5897
6122
|
};
|
|
5898
6123
|
break;
|
|
5899
6124
|
case 'center':
|
|
5900
6125
|
this.windowPosition = {
|
|
5901
6126
|
x: (windowWidth - chatWidth) / 2,
|
|
5902
|
-
y: (windowHeight - this.chatWindowHeight) / 2
|
|
6127
|
+
y: (windowHeight - this.chatWindowHeight) / 2,
|
|
5903
6128
|
};
|
|
5904
6129
|
break;
|
|
5905
6130
|
}
|
|
@@ -5922,14 +6147,14 @@ const OcsChat = class {
|
|
|
5922
6147
|
// For fullscreen, track relative to current position
|
|
5923
6148
|
this.dragOffset = {
|
|
5924
6149
|
x: pointer.clientX,
|
|
5925
|
-
y: pointer.clientY
|
|
6150
|
+
y: pointer.clientY,
|
|
5926
6151
|
};
|
|
5927
6152
|
}
|
|
5928
6153
|
else {
|
|
5929
6154
|
const rect = this.chatWindowRef.getBoundingClientRect();
|
|
5930
6155
|
this.dragOffset = {
|
|
5931
6156
|
x: pointer.clientX - rect.left,
|
|
5932
|
-
y: pointer.clientY - rect.top
|
|
6157
|
+
y: pointer.clientY - rect.top,
|
|
5933
6158
|
};
|
|
5934
6159
|
}
|
|
5935
6160
|
}
|
|
@@ -5941,7 +6166,7 @@ const OcsChat = class {
|
|
|
5941
6166
|
const { maxOffset } = this.getFullscreenBounds();
|
|
5942
6167
|
const deltaX = pointer.clientX - this.dragOffset.x;
|
|
5943
6168
|
this.fullscreenPosition = {
|
|
5944
|
-
x: Math.max(-maxOffset, Math.min(maxOffset, deltaX))
|
|
6169
|
+
x: Math.max(-maxOffset, Math.min(maxOffset, deltaX)),
|
|
5945
6170
|
};
|
|
5946
6171
|
}
|
|
5947
6172
|
else {
|
|
@@ -5954,7 +6179,7 @@ const OcsChat = class {
|
|
|
5954
6179
|
const chatHeight = this.chatWindowRef.offsetHeight;
|
|
5955
6180
|
this.windowPosition = {
|
|
5956
6181
|
x: Math.max(0, Math.min(newX, windowWidth - chatWidth)),
|
|
5957
|
-
y: Math.max(0, Math.min(newY, windowHeight - chatHeight))
|
|
6182
|
+
y: Math.max(0, Math.min(newY, windowHeight - chatHeight)),
|
|
5958
6183
|
};
|
|
5959
6184
|
}
|
|
5960
6185
|
}
|
|
@@ -6001,7 +6226,7 @@ const OcsChat = class {
|
|
|
6001
6226
|
const verticalValue = this.buttonVerticalSide === 'top' ? resolvedTop : resolvedBottom;
|
|
6002
6227
|
this.buttonPosition = {
|
|
6003
6228
|
x: horizontalValue,
|
|
6004
|
-
y: verticalValue
|
|
6229
|
+
y: verticalValue,
|
|
6005
6230
|
};
|
|
6006
6231
|
// Apply the position to the host
|
|
6007
6232
|
this.updateHostPosition();
|
|
@@ -6044,12 +6269,8 @@ const OcsChat = class {
|
|
|
6044
6269
|
const maxTop = windowHeight - buttonHeight - minPadding;
|
|
6045
6270
|
const constrainedLeft = Math.max(minLeft, Math.min(candidateLeft, maxLeft));
|
|
6046
6271
|
const constrainedTop = Math.max(minTop, Math.min(candidateTop, maxTop));
|
|
6047
|
-
const newHorizontalValue = this.buttonHorizontalSide === 'left'
|
|
6048
|
-
|
|
6049
|
-
: Math.max(minPadding, windowWidth - (constrainedLeft + buttonWidth));
|
|
6050
|
-
const newVerticalValue = this.buttonVerticalSide === 'top'
|
|
6051
|
-
? constrainedTop
|
|
6052
|
-
: Math.max(minPadding, windowHeight - (constrainedTop + buttonHeight));
|
|
6272
|
+
const newHorizontalValue = this.buttonHorizontalSide === 'left' ? constrainedLeft : Math.max(minPadding, windowWidth - (constrainedLeft + buttonWidth));
|
|
6273
|
+
const newVerticalValue = this.buttonVerticalSide === 'top' ? constrainedTop : Math.max(minPadding, windowHeight - (constrainedTop + buttonHeight));
|
|
6053
6274
|
if (newHorizontalValue !== this.buttonPosition.x || newVerticalValue !== this.buttonPosition.y) {
|
|
6054
6275
|
this.buttonWasDragged = true;
|
|
6055
6276
|
this.buttonPosition = { x: newHorizontalValue, y: newVerticalValue };
|
|
@@ -6112,16 +6333,12 @@ const OcsChat = class {
|
|
|
6112
6333
|
return fallback;
|
|
6113
6334
|
}
|
|
6114
6335
|
getWelcomeMessages() {
|
|
6115
|
-
const translated = this.translationManager.getArray(
|
|
6116
|
-
return translated && translated.length > 0
|
|
6117
|
-
? translated
|
|
6118
|
-
: this.parsedWelcomeMessages;
|
|
6336
|
+
const translated = this.translationManager.getArray('content.welcomeMessages');
|
|
6337
|
+
return translated && translated.length > 0 ? translated : this.parsedWelcomeMessages;
|
|
6119
6338
|
}
|
|
6120
6339
|
getStarterQuestions() {
|
|
6121
|
-
const translated = this.translationManager.getArray(
|
|
6122
|
-
return translated && translated.length > 0
|
|
6123
|
-
? translated
|
|
6124
|
-
: this.parsedStarterQuestions;
|
|
6340
|
+
const translated = this.translationManager.getArray('content.starterQuestions');
|
|
6341
|
+
return translated && translated.length > 0 ? translated : this.parsedStarterQuestions;
|
|
6125
6342
|
}
|
|
6126
6343
|
getButtonClasses() {
|
|
6127
6344
|
const buttonText = this.translationManager.get('branding.buttonText', this.buttonText);
|
|
@@ -6132,6 +6349,9 @@ const OcsChat = class {
|
|
|
6132
6349
|
}
|
|
6133
6350
|
renderButton() {
|
|
6134
6351
|
var _a;
|
|
6352
|
+
if (!this.showButton || this.isKioskMode()) {
|
|
6353
|
+
return null;
|
|
6354
|
+
}
|
|
6135
6355
|
const buttonText = this.translationManager.get('branding.buttonText', this.buttonText);
|
|
6136
6356
|
const hasText = !!(buttonText && buttonText.trim());
|
|
6137
6357
|
const hasCustomIcon = this.iconUrl && this.iconUrl.trim();
|
|
@@ -6141,31 +6361,34 @@ const OcsChat = class {
|
|
|
6141
6361
|
const buttonAriaLabel = finalButtonText ? `${openLabel} - ${finalButtonText}` : openLabel;
|
|
6142
6362
|
// Only show drag cursor if button is draggable
|
|
6143
6363
|
const isDraggable = this.isButtonDraggable();
|
|
6144
|
-
const buttonStyle = isDraggable
|
|
6145
|
-
|
|
6146
|
-
|
|
6364
|
+
const buttonStyle = isDraggable
|
|
6365
|
+
? {
|
|
6366
|
+
cursor: this.isButtonDragging ? 'grabbing' : 'grab',
|
|
6367
|
+
}
|
|
6368
|
+
: {};
|
|
6147
6369
|
if (hasText) {
|
|
6148
|
-
return (index.h("button", { ref:
|
|
6370
|
+
return (index.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 ? index.h("img", { src: this.iconUrl, alt: "" }) : index.h(OcsWidgetAvatar, null), index.h("span", null, finalButtonText), isDraggable && (index.h("span", { id: "chat-button-drag-hint", style: { display: 'none' } }, "Draggable. Use mouse or touch to reposition."))));
|
|
6149
6371
|
}
|
|
6150
6372
|
else {
|
|
6151
|
-
return (index.h("button", { ref:
|
|
6373
|
+
return (index.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 ? index.h("img", { src: this.iconUrl, alt: "" }) : index.h(OcsWidgetAvatar, null), isDraggable && (index.h("span", { id: "chat-button-drag-hint", style: { display: 'none' } }, "Draggable. Use mouse or touch to reposition."))));
|
|
6152
6374
|
}
|
|
6153
6375
|
}
|
|
6154
6376
|
getStorageKeys() {
|
|
6155
6377
|
return {
|
|
6156
6378
|
sessionId: `ocs-chat-session-${this.chatbotId}`,
|
|
6157
6379
|
messages: `ocs-chat-messages-${this.chatbotId}`,
|
|
6158
|
-
lastActivity: `ocs-chat-activity-${this.chatbotId}
|
|
6380
|
+
lastActivity: `ocs-chat-activity-${this.chatbotId}`,
|
|
6381
|
+
visible: `ocs-chat-visible-${this.chatbotId}`,
|
|
6159
6382
|
};
|
|
6160
6383
|
}
|
|
6161
6384
|
saveSessionToStorage() {
|
|
6162
|
-
if (!this.persistentSession) {
|
|
6385
|
+
if (!this.persistentSession || this.isSessionBound()) {
|
|
6163
6386
|
return;
|
|
6164
6387
|
}
|
|
6165
6388
|
const keys = this.getStorageKeys();
|
|
6166
6389
|
try {
|
|
6167
|
-
if (this.
|
|
6168
|
-
localStorage.setItem(keys.sessionId, this.
|
|
6390
|
+
if (this.activeSessionId) {
|
|
6391
|
+
localStorage.setItem(keys.sessionId, this.activeSessionId);
|
|
6169
6392
|
localStorage.setItem(keys.lastActivity, new Date().toISOString());
|
|
6170
6393
|
}
|
|
6171
6394
|
localStorage.setItem(keys.messages, JSON.stringify(this.messages));
|
|
@@ -6218,30 +6441,73 @@ const OcsChat = class {
|
|
|
6218
6441
|
return this.generatedUserId;
|
|
6219
6442
|
}
|
|
6220
6443
|
const storageKey = `ocs-user-id`;
|
|
6221
|
-
|
|
6444
|
+
let stored = null;
|
|
6445
|
+
try {
|
|
6446
|
+
stored = localStorage.getItem(storageKey);
|
|
6447
|
+
}
|
|
6448
|
+
catch (_a) {
|
|
6449
|
+
// localStorage blocked; fall through to in-memory id generation
|
|
6450
|
+
}
|
|
6222
6451
|
if (stored) {
|
|
6223
6452
|
this.generatedUserId = stored;
|
|
6224
6453
|
return stored;
|
|
6225
6454
|
}
|
|
6226
6455
|
const array = new Uint8Array(9);
|
|
6227
6456
|
window.crypto.getRandomValues(array);
|
|
6228
|
-
const randomString = Array.from(array, byte => byte.toString(36))
|
|
6457
|
+
const randomString = Array.from(array, byte => byte.toString(36))
|
|
6458
|
+
.join('')
|
|
6459
|
+
.substr(0, 9);
|
|
6229
6460
|
const newUserId = `ocs:${Date.now()}_${randomString}`;
|
|
6230
6461
|
this.generatedUserId = newUserId;
|
|
6231
|
-
|
|
6462
|
+
try {
|
|
6463
|
+
localStorage.setItem(storageKey, newUserId);
|
|
6464
|
+
}
|
|
6465
|
+
catch (_b) {
|
|
6466
|
+
// localStorage blocked; the generated id lives in component state for this page
|
|
6467
|
+
}
|
|
6232
6468
|
return newUserId;
|
|
6233
6469
|
}
|
|
6470
|
+
saveVisibleState(visible) {
|
|
6471
|
+
if (!this.persistentSession)
|
|
6472
|
+
return;
|
|
6473
|
+
try {
|
|
6474
|
+
const keys = this.getStorageKeys();
|
|
6475
|
+
localStorage.setItem(keys.visible, visible ? '1' : '0');
|
|
6476
|
+
}
|
|
6477
|
+
catch (_a) {
|
|
6478
|
+
// ignore
|
|
6479
|
+
}
|
|
6480
|
+
}
|
|
6481
|
+
restoreVisibleState() {
|
|
6482
|
+
try {
|
|
6483
|
+
const keys = this.getStorageKeys();
|
|
6484
|
+
const stored = localStorage.getItem(keys.visible);
|
|
6485
|
+
if (stored === '1') {
|
|
6486
|
+
this.visible = true;
|
|
6487
|
+
}
|
|
6488
|
+
}
|
|
6489
|
+
catch (_a) {
|
|
6490
|
+
// ignore
|
|
6491
|
+
}
|
|
6492
|
+
}
|
|
6234
6493
|
clearSessionStorage() {
|
|
6235
6494
|
const keys = this.getStorageKeys();
|
|
6236
6495
|
try {
|
|
6237
6496
|
localStorage.removeItem(keys.sessionId);
|
|
6238
6497
|
localStorage.removeItem(keys.messages);
|
|
6239
6498
|
localStorage.removeItem(keys.lastActivity);
|
|
6499
|
+
localStorage.removeItem(keys.visible);
|
|
6240
6500
|
}
|
|
6241
6501
|
catch (error) {
|
|
6242
6502
|
console.warn('Failed to clear chat session from localStorage:', error);
|
|
6243
6503
|
}
|
|
6244
6504
|
}
|
|
6505
|
+
isKioskMode() {
|
|
6506
|
+
return this.mode === 'kiosk';
|
|
6507
|
+
}
|
|
6508
|
+
isSessionBound() {
|
|
6509
|
+
return !!this.sessionId;
|
|
6510
|
+
}
|
|
6245
6511
|
isLocalStorageAvailable() {
|
|
6246
6512
|
try {
|
|
6247
6513
|
localStorage.setItem(OcsChat.LOCALSTORAGE_TEST_KEY, 'test');
|
|
@@ -6267,8 +6533,11 @@ const OcsChat = class {
|
|
|
6267
6533
|
* will start when the user sends a message.
|
|
6268
6534
|
*/
|
|
6269
6535
|
async clearSession() {
|
|
6536
|
+
this.sessionEpoch += 1;
|
|
6270
6537
|
this.clearSessionStorage();
|
|
6271
|
-
|
|
6538
|
+
// A session provided by the host page (session-id prop) cannot be cleared;
|
|
6539
|
+
// stay bound to it. Unbound widgets start a new session on the next message.
|
|
6540
|
+
this.activeSessionId = this.sessionId;
|
|
6272
6541
|
this.messages = [];
|
|
6273
6542
|
this.isTyping = false;
|
|
6274
6543
|
this.currentPollTaskId = '';
|
|
@@ -6276,6 +6545,11 @@ const OcsChat = class {
|
|
|
6276
6545
|
this.selectedFiles = [];
|
|
6277
6546
|
}
|
|
6278
6547
|
this.cleanup();
|
|
6548
|
+
if (this.isSessionBound()) {
|
|
6549
|
+
// The host-owned session cannot be cleared: reload its history and
|
|
6550
|
+
// resume polling so the widget doesn't end up in a dead state.
|
|
6551
|
+
void this.loadBoundSessionHistory();
|
|
6552
|
+
}
|
|
6279
6553
|
}
|
|
6280
6554
|
toggleFullscreen() {
|
|
6281
6555
|
this.isFullscreen = !this.isFullscreen;
|
|
@@ -6284,25 +6558,21 @@ const OcsChat = class {
|
|
|
6284
6558
|
}
|
|
6285
6559
|
render() {
|
|
6286
6560
|
// Only show error state for critical errors that prevent the widget from functioning
|
|
6287
|
-
if (this.error && !this.
|
|
6561
|
+
if (this.error && !this.activeSessionId) {
|
|
6288
6562
|
return (index.h(index.Host, null, index.h("p", { class: "error-message" }, this.error)));
|
|
6289
6563
|
}
|
|
6290
|
-
return (index.h(index.Host, null, this.renderButton(), this.visible && (index.h("div", { ref:
|
|
6291
|
-
? 'message-bubble-user'
|
|
6292
|
-
: message.role === 'assistant'
|
|
6293
|
-
? 'message-bubble-assistant'
|
|
6294
|
-
: 'message-bubble-system'}` }, index.h("div", { class: "chat-markdown", innerHTML: renderMarkdownSync(message.content) }), message.attachments && message.attachments.length > 0 && (index.h("div", { class: "message-attachments" }, message.attachments.map((attachment, attachmentIndex) => (index.h("div", { key: attachmentIndex, class: "flex items-center gap-[0.5em]" }, index.h("span", { class: "message-attachment-icon" }, index.h(PaperClipIcon, null)), index.h("span", { class: "message-attachment-name" }, attachment.name)))))), index.h("div", { class: "message-timestamp" }, this.formatTime(message.created_at)))))), this.isTyping && (index.h("div", null, index.h("div", { class: "typing-indicator" }, index.h("div", { class: "typing-progress" })), index.h("div", { class: "typing-text" }, index.h("span", null, this.translationManager.get('status.typing', this.typingIndicatorText)), index.h("span", { class: "typing-dots loading" })))))), this.messages.length === 0 && this.getStarterQuestions().length > 0 && (index.h("div", { class: "starter-questions" }, this.getStarterQuestions().map((question, index$1) => (index.h("div", { key: `starter-${index$1}`, class: "starter-question-row" }, index.h("button", { class: "starter-question", onClick: () => this.handleStarterQuestionClick(question) }, question)))))), this.allowAttachments && this.selectedFiles.length > 0 && (index.h("div", { class: "selected-files-container" }, index.h("div", { class: "space-y-[0.25em]" }, this.selectedFiles.map((selectedFile, index$1) => (index.h("div", { key: index$1, class: "selected-file-item" }, index.h("div", { class: "flex items-center gap-[0.5em]" }, index.h("span", { class: "selected-file-icon" }, index.h(PaperClipIcon, null)), index.h("span", null, selectedFile.file.name), index.h("span", { class: "selected-file-size" }, "(", this.formatFileSize(selectedFile.file.size), ")"), selectedFile.error && (index.h("span", { class: "selected-file-error" }, selectedFile.error)), selectedFile.uploaded && (index.h("span", { class: "selected-file-success-icon" }, index.h(CheckDocumentIcon, null)))), index.h("button", { onClick: () => this.removeSelectedFile(index$1), class: "selected-file-remove-button", "aria-label": this.translationManager.get('attach.remove') }, index.h(XIcon, null)))))))), index.h("div", { class: "input-area" }, index.h("div", { class: "input-container" }, index.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 && (index.h("input", { ref: (el) => {
|
|
6564
|
+
return (index.h(index.Host, null, this.renderButton(), this.visible && (index.h("div", { ref: el => (this.chatWindowRef = el), id: "ocs-chat-window", class: this.getPositionClasses(), style: this.getPositionStyles() }, !this.isKioskMode() && (index.h("div", { class: `chat-header ${this.isDragging ? 'chat-header-dragging' : 'chat-header-draggable'}`, onMouseDown: this.handleMouseDown, onTouchStart: this.handleTouchStart }, index.h("div", { class: "drag-indicator" }, index.h("div", { class: "drag-dots header-button" }, index.h(GripDotsVerticalIcon, null))), index.h("div", { class: "header-text" }, this.translationManager.get('branding.headerText', this.headerText)), index.h("div", { class: "header-buttons" }, this.messages.length > 0 && !this.isSessionBound() && (index.h("button", { class: "header-button", onClick: () => this.showConfirmationDialog(), title: this.translationManager.get('window.newChat'), "aria-label": this.translationManager.get('window.newChat') }, index.h(PlusWithCircleIcon, null))), this.allowFullScreen && (index.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 ? index.h(ArrowsPointingInIcon, null) : index.h(ArrowsPointingOutIcon, null))), index.h("button", { class: "header-button", onClick: () => (this.visible = false), "aria-label": this.translationManager.get('window.close') }, index.h(XMarkIcon, null))))), !this.isKioskMode() && this.showNewChatConfirmation && (index.h("div", { class: "confirmation-overlay" }, index.h("div", { class: "confirmation-dialog" }, index.h("div", { class: "confirmation-content" }, index.h("h3", { class: "confirmation-title" }, this.translationManager.get('modal.newChatTitle')), index.h("p", { class: "confirmation-message" }, this.translationManager.get('modal.newChatBody', this.newChatConfirmationMessage)), index.h("div", { class: "confirmation-buttons" }, index.h("button", { class: "confirmation-button confirmation-button-cancel", onClick: () => this.hideConfirmationDialog() }, this.translationManager.get('modal.cancel')), index.h("button", { class: "confirmation-button confirmation-button-confirm", onClick: () => this.confirmNewChat() }, this.translationManager.get('modal.confirm'))))))), index.h("div", { class: "chat-content" }, this.isLoading && !this.activeSessionId && (index.h("div", { class: "loading-container" }, index.h("div", { class: "loading-spinner" }), index.h("span", { class: "loading-text" }, this.translationManager.get('status.starting')))), index.h("div", { ref: el => (this.messageListRef = el), class: "messages-container" }, this.messages.length === 0 && this.getWelcomeMessages().length > 0 && (index.h("div", { class: "welcome-messages" }, this.getWelcomeMessages().map((message, index$1) => (index.h("div", { key: `welcome-${index$1}`, class: "message-row message-row-assistant" }, index.h("div", { class: "message-bubble message-bubble-assistant" }, index.h("div", { class: "chat-markdown", innerHTML: renderMarkdownSync(message) }))))))), this.messages.map((message, index$1) => (index.h("div", { key: index$1, class: `message-row ${message.role === 'user' ? 'message-row-user' : 'message-row-assistant'}` }, index.h("div", { class: `message-bubble ${message.role === 'user' ? 'message-bubble-user' : message.role === 'assistant' ? 'message-bubble-assistant' : 'message-bubble-system'}` }, index.h("div", { class: "chat-markdown", innerHTML: renderMarkdownSync(message.content) }), message.attachments && message.attachments.length > 0 && (index.h("div", { class: "message-attachments" }, message.attachments.map((attachment, attachmentIndex) => (index.h("div", { key: attachmentIndex, class: "flex items-center gap-[0.5em]" }, index.h("span", { class: "message-attachment-icon" }, index.h(PaperClipIcon, null)), index.h("span", { class: "message-attachment-name" }, attachment.name)))))), index.h("div", { class: "message-timestamp" }, this.formatTime(message.created_at)))))), this.isTyping && (index.h("div", null, index.h("div", { class: "typing-indicator" }, index.h("div", { class: "typing-progress" })), index.h("div", { class: "typing-text" }, index.h("span", null, this.typingProgressMessage || this.translationManager.get('status.typing', this.typingIndicatorText)), index.h("span", { class: "typing-dots loading" }))))), this.messages.length === 0 && this.getStarterQuestions().length > 0 && (index.h("div", { class: "starter-questions" }, this.getStarterQuestions().map((question, index$1) => (index.h("div", { key: `starter-${index$1}`, class: "starter-question-row" }, index.h("button", { class: "starter-question", onClick: () => this.handleStarterQuestionClick(question) }, question)))))), this.allowAttachments && this.selectedFiles.length > 0 && (index.h("div", { class: "selected-files-container" }, index.h("div", { class: "space-y-[0.25em]" }, this.selectedFiles.map((selectedFile, index$1) => (index.h("div", { key: index$1, class: "selected-file-item" }, index.h("div", { class: "flex items-center gap-[0.5em]" }, index.h("span", { class: "selected-file-icon" }, index.h(PaperClipIcon, null)), index.h("span", null, selectedFile.file.name), index.h("span", { class: "selected-file-size" }, "(", this.formatFileSize(selectedFile.file.size), ")"), selectedFile.error && index.h("span", { class: "selected-file-error" }, selectedFile.error), selectedFile.uploaded && (index.h("span", { class: "selected-file-success-icon" }, index.h(CheckDocumentIcon, null)))), index.h("button", { onClick: () => this.removeSelectedFile(index$1), class: "selected-file-remove-button", "aria-label": this.translationManager.get('attach.remove') }, index.h(XIcon, null)))))))), index.h("div", { class: "input-area" }, index.h("div", { class: "input-container" }, index.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 && (index.h("input", { ref: el => {
|
|
6295
6565
|
// Unclear why but after removing all attachments this is being set to `null`.
|
|
6296
6566
|
if (el) {
|
|
6297
6567
|
this.fileInputRef = el;
|
|
6298
6568
|
}
|
|
6299
|
-
}, id: "ocs-file-input", type: "file", multiple: true, accept: OcsChat.SUPPORTED_FILE_EXTENSIONS.join(',') + ',text/*', onChange:
|
|
6300
|
-
? 'send-button-enabled'
|
|
6301
|
-
: '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')))), index.h("div", { class: "flex items-center justify-center text-[0.8em] font-light w-full text-slate-500 py-[2px]" }, index.h("p", null, this.translationManager.get('branding.poweredBy'), ' ', " ", index.h("a", { class: "underline", href: "https://www.dimagi.com", target: "_blank" }, "Dimagi"))))))));
|
|
6569
|
+
}, id: "ocs-file-input", type: "file", multiple: true, accept: OcsChat.SUPPORTED_FILE_EXTENSIONS.join(',') + ',text/*', onChange: e => this.handleFileSelect(e), class: "hidden" })), this.allowAttachments && (index.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') }, index.h(PaperClipIcon, null))), index.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')))), index.h("div", { class: "flex items-center justify-center text-[0.8em] font-light w-full text-slate-500 py-[2px]" }, index.h("p", null, this.translationManager.get('branding.poweredBy'), ' ', index.h("a", { class: "underline", href: "https://www.dimagi.com", target: "_blank", rel: "noopener noreferrer" }, "Dimagi"))))))));
|
|
6302
6570
|
}
|
|
6303
6571
|
get host() { return index.getElement(this); }
|
|
6304
6572
|
static get watchers() { return {
|
|
6305
6573
|
"pageContext": ["pageContextHandler"],
|
|
6574
|
+
"chatbotId": ["chatbotConfigHandler"],
|
|
6575
|
+
"versionNumber": ["chatbotConfigHandler"],
|
|
6306
6576
|
"visible": ["visibilityHandler"]
|
|
6307
6577
|
}; }
|
|
6308
6578
|
};
|
|
@@ -6316,9 +6586,41 @@ OcsChat.WINDOW_MARGIN = 20;
|
|
|
6316
6586
|
OcsChat.LOCALSTORAGE_TEST_KEY = '__ocs_test__';
|
|
6317
6587
|
OcsChat.MAX_FILE_SIZE_MB = 50;
|
|
6318
6588
|
OcsChat.MAX_TOTAL_SIZE_MB = 50;
|
|
6319
|
-
OcsChat.SUPPORTED_FILE_EXTENSIONS = [
|
|
6320
|
-
'.
|
|
6321
|
-
'.
|
|
6589
|
+
OcsChat.SUPPORTED_FILE_EXTENSIONS = [
|
|
6590
|
+
'.txt',
|
|
6591
|
+
'.pdf',
|
|
6592
|
+
'.doc',
|
|
6593
|
+
'.docx',
|
|
6594
|
+
'.xls',
|
|
6595
|
+
'.xlsx',
|
|
6596
|
+
'.csv',
|
|
6597
|
+
'.jpg',
|
|
6598
|
+
'.jpeg',
|
|
6599
|
+
'.png',
|
|
6600
|
+
'.gif',
|
|
6601
|
+
'.bmp',
|
|
6602
|
+
'.webp',
|
|
6603
|
+
'.svg',
|
|
6604
|
+
'.mp4',
|
|
6605
|
+
'.mov',
|
|
6606
|
+
'.avi',
|
|
6607
|
+
'.mp3',
|
|
6608
|
+
'.wav',
|
|
6609
|
+
'.html',
|
|
6610
|
+
'.htm',
|
|
6611
|
+
'.css',
|
|
6612
|
+
'.js',
|
|
6613
|
+
'.xml',
|
|
6614
|
+
'.md',
|
|
6615
|
+
'.ics',
|
|
6616
|
+
'.vcf',
|
|
6617
|
+
'.rtf',
|
|
6618
|
+
'.tsv',
|
|
6619
|
+
'.yaml',
|
|
6620
|
+
'.yml',
|
|
6621
|
+
'.py',
|
|
6622
|
+
'.c',
|
|
6623
|
+
];
|
|
6322
6624
|
OcsChat.style = ocsChatCss;
|
|
6323
6625
|
|
|
6324
6626
|
exports.open_chat_studio_widget = OcsChat;
|