@websolutespa/bom-mixer-llm 0.0.1
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/CHANGELOG.md +7 -0
- package/README.md +11 -0
- package/dist/cjs/index.css +2264 -0
- package/dist/cjs/index.js +3566 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.css +2264 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/llm/components/Background/background.js +76 -0
- package/dist/esm/llm/components/Background/background.js.map +1 -0
- package/dist/esm/llm/components/BusyIndicator/busyindicator.js +23 -0
- package/dist/esm/llm/components/BusyIndicator/busyindicator.js.map +1 -0
- package/dist/esm/llm/components/Canvas/canvas.js +223 -0
- package/dist/esm/llm/components/Canvas/canvas.js.map +1 -0
- package/dist/esm/llm/components/Chunk/chunk.js +65 -0
- package/dist/esm/llm/components/Chunk/chunk.js.map +1 -0
- package/dist/esm/llm/components/Cta/cta.js +33 -0
- package/dist/esm/llm/components/Cta/cta.js.map +1 -0
- package/dist/esm/llm/components/Event/event.js +90 -0
- package/dist/esm/llm/components/Event/event.js.map +1 -0
- package/dist/esm/llm/components/EventGroup/eventgroup.js +61 -0
- package/dist/esm/llm/components/EventGroup/eventgroup.js.map +1 -0
- package/dist/esm/llm/components/FormRecap/FormRecap.js +240 -0
- package/dist/esm/llm/components/FormRecap/FormRecap.js.map +1 -0
- package/dist/esm/llm/components/FormRecapError/FormRecapError.js +13 -0
- package/dist/esm/llm/components/FormRecapError/FormRecapError.js.map +1 -0
- package/dist/esm/llm/components/FormRecapSuccess/FormRecapSuccess.js +13 -0
- package/dist/esm/llm/components/FormRecapSuccess/FormRecapSuccess.js.map +1 -0
- package/dist/esm/llm/components/FormRequest/FormRequest.js +34 -0
- package/dist/esm/llm/components/FormRequest/FormRequest.js.map +1 -0
- package/dist/esm/llm/components/Header/header.js +51 -0
- package/dist/esm/llm/components/Header/header.js.map +1 -0
- package/dist/esm/llm/components/Intro/intro.js +77 -0
- package/dist/esm/llm/components/Intro/intro.js.map +1 -0
- package/dist/esm/llm/components/Main/main.js +118 -0
- package/dist/esm/llm/components/Main/main.js.map +1 -0
- package/dist/esm/llm/components/Poi/poi.js +78 -0
- package/dist/esm/llm/components/Poi/poi.js.map +1 -0
- package/dist/esm/llm/components/PoiGroup/poigroup.js +14 -0
- package/dist/esm/llm/components/PoiGroup/poigroup.js.map +1 -0
- package/dist/esm/llm/components/Prompt/prompt.js +86 -0
- package/dist/esm/llm/components/Prompt/prompt.js.map +1 -0
- package/dist/esm/llm/components/Prompt/suggestions.js +45 -0
- package/dist/esm/llm/components/Prompt/suggestions.js.map +1 -0
- package/dist/esm/llm/components/QuickLinks/quicklinks.js +66 -0
- package/dist/esm/llm/components/QuickLinks/quicklinks.js.map +1 -0
- package/dist/esm/llm/components/Stream/stream.js +43 -0
- package/dist/esm/llm/components/Stream/stream.js.map +1 -0
- package/dist/esm/llm/components/Text/text.js +34 -0
- package/dist/esm/llm/components/Text/text.js.map +1 -0
- package/dist/esm/llm/components/Thread/thread.js +26 -0
- package/dist/esm/llm/components/Thread/thread.js.map +1 -0
- package/dist/esm/llm/components/Trigger/blob.js +122 -0
- package/dist/esm/llm/components/Trigger/blob.js.map +1 -0
- package/dist/esm/llm/components/Trigger/trigger.js +63 -0
- package/dist/esm/llm/components/Trigger/trigger.js.map +1 -0
- package/dist/esm/llm/components/Tripadvisor/tripadvisor.js +94 -0
- package/dist/esm/llm/components/Tripadvisor/tripadvisor.js.map +1 -0
- package/dist/esm/llm/hooks/useAutosizeTextArea.js +13 -0
- package/dist/esm/llm/hooks/useAutosizeTextArea.js.map +1 -0
- package/dist/esm/llm/llm.js +48 -0
- package/dist/esm/llm/llm.js.map +1 -0
- package/dist/esm/llm/utils.js +15 -0
- package/dist/esm/llm/utils.js.map +1 -0
- package/dist/esm/node_modules/tslib/tslib.es6.js +135 -0
- package/dist/esm/node_modules/tslib/tslib.es6.js.map +1 -0
- package/dist/esm/useLlm/emitter.js +32 -0
- package/dist/esm/useLlm/emitter.js.map +1 -0
- package/dist/esm/useLlm/message.service.js +308 -0
- package/dist/esm/useLlm/message.service.js.map +1 -0
- package/dist/esm/useLlm/mock.js +687 -0
- package/dist/esm/useLlm/mock.js.map +1 -0
- package/dist/esm/useLlm/speech.js +306 -0
- package/dist/esm/useLlm/speech.js.map +1 -0
- package/dist/esm/useLlm/useLlm.js +460 -0
- package/dist/esm/useLlm/useLlm.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/llm/components/Background/background.d.ts +34 -0
- package/dist/types/llm/components/Background/background.d.ts.map +1 -0
- package/dist/types/llm/components/BusyIndicator/busyindicator.d.ts +2 -0
- package/dist/types/llm/components/BusyIndicator/busyindicator.d.ts.map +1 -0
- package/dist/types/llm/components/Canvas/canvas.d.ts +12 -0
- package/dist/types/llm/components/Canvas/canvas.d.ts.map +1 -0
- package/dist/types/llm/components/Chunk/chunk.d.ts +9 -0
- package/dist/types/llm/components/Chunk/chunk.d.ts.map +1 -0
- package/dist/types/llm/components/Cta/cta.d.ts +10 -0
- package/dist/types/llm/components/Cta/cta.d.ts.map +1 -0
- package/dist/types/llm/components/Event/event.d.ts +3 -0
- package/dist/types/llm/components/Event/event.d.ts.map +1 -0
- package/dist/types/llm/components/EventGroup/eventgroup.d.ts +3 -0
- package/dist/types/llm/components/EventGroup/eventgroup.d.ts.map +1 -0
- package/dist/types/llm/components/FormRecap/FormRecap.d.ts +10 -0
- package/dist/types/llm/components/FormRecap/FormRecap.d.ts.map +1 -0
- package/dist/types/llm/components/FormRecapError/FormRecapError.d.ts +2 -0
- package/dist/types/llm/components/FormRecapError/FormRecapError.d.ts.map +1 -0
- package/dist/types/llm/components/FormRecapSuccess/FormRecapSuccess.d.ts +2 -0
- package/dist/types/llm/components/FormRecapSuccess/FormRecapSuccess.d.ts.map +1 -0
- package/dist/types/llm/components/FormRequest/FormRequest.d.ts +4 -0
- package/dist/types/llm/components/FormRequest/FormRequest.d.ts.map +1 -0
- package/dist/types/llm/components/Header/header.d.ts +4 -0
- package/dist/types/llm/components/Header/header.d.ts.map +1 -0
- package/dist/types/llm/components/Intro/intro.d.ts +2 -0
- package/dist/types/llm/components/Intro/intro.d.ts.map +1 -0
- package/dist/types/llm/components/Main/main.d.ts +2 -0
- package/dist/types/llm/components/Main/main.d.ts.map +1 -0
- package/dist/types/llm/components/Poi/poi.d.ts +3 -0
- package/dist/types/llm/components/Poi/poi.d.ts.map +1 -0
- package/dist/types/llm/components/PoiGroup/poigroup.d.ts +3 -0
- package/dist/types/llm/components/PoiGroup/poigroup.d.ts.map +1 -0
- package/dist/types/llm/components/Prompt/prompt.d.ts +2 -0
- package/dist/types/llm/components/Prompt/prompt.d.ts.map +1 -0
- package/dist/types/llm/components/Prompt/suggestions.d.ts +2 -0
- package/dist/types/llm/components/Prompt/suggestions.d.ts.map +1 -0
- package/dist/types/llm/components/QuickLinks/quicklinks.d.ts +3 -0
- package/dist/types/llm/components/QuickLinks/quicklinks.d.ts.map +1 -0
- package/dist/types/llm/components/Stream/stream.d.ts +4 -0
- package/dist/types/llm/components/Stream/stream.d.ts.map +1 -0
- package/dist/types/llm/components/Text/text.d.ts +7 -0
- package/dist/types/llm/components/Text/text.d.ts.map +1 -0
- package/dist/types/llm/components/Thread/thread.d.ts +4 -0
- package/dist/types/llm/components/Thread/thread.d.ts.map +1 -0
- package/dist/types/llm/components/Trigger/blob.d.ts +2 -0
- package/dist/types/llm/components/Trigger/blob.d.ts.map +1 -0
- package/dist/types/llm/components/Trigger/trigger.d.ts +2 -0
- package/dist/types/llm/components/Trigger/trigger.d.ts.map +1 -0
- package/dist/types/llm/components/Tripadvisor/tripadvisor.d.ts +4 -0
- package/dist/types/llm/components/Tripadvisor/tripadvisor.d.ts.map +1 -0
- package/dist/types/llm/hooks/useAutosizeTextArea.d.ts +3 -0
- package/dist/types/llm/hooks/useAutosizeTextArea.d.ts.map +1 -0
- package/dist/types/llm/llm.d.ts +5 -0
- package/dist/types/llm/llm.d.ts.map +1 -0
- package/dist/types/llm/utils.d.ts +7 -0
- package/dist/types/llm/utils.d.ts.map +1 -0
- package/dist/types/types.d.ts +163 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/useLlm/cors.d.ts +16 -0
- package/dist/types/useLlm/cors.d.ts.map +1 -0
- package/dist/types/useLlm/emitter.d.ts +8 -0
- package/dist/types/useLlm/emitter.d.ts.map +1 -0
- package/dist/types/useLlm/message.service.d.ts +24 -0
- package/dist/types/useLlm/message.service.d.ts.map +1 -0
- package/dist/types/useLlm/mock.d.ts +5 -0
- package/dist/types/useLlm/mock.d.ts.map +1 -0
- package/dist/types/useLlm/speech.d.ts +57 -0
- package/dist/types/useLlm/speech.d.ts.map +1 -0
- package/dist/types/useLlm/useLlm.d.ts +83 -0
- package/dist/types/useLlm/useLlm.d.ts.map +1 -0
- package/package.json +86 -0
- package/src/__tests/example.test.ts +8 -0
- package/src/index.ts +6 -0
- package/src/llm/components/Background/_style.scss +24 -0
- package/src/llm/components/Background/background.tsx +89 -0
- package/src/llm/components/BusyIndicator/_style.scss +73 -0
- package/src/llm/components/BusyIndicator/busyindicator.tsx +13 -0
- package/src/llm/components/Canvas/_style.scss +10 -0
- package/src/llm/components/Canvas/canvas.tsx +257 -0
- package/src/llm/components/Chunk/chunk.tsx +80 -0
- package/src/llm/components/Cta/_style.scss +72 -0
- package/src/llm/components/Cta/cta.tsx +33 -0
- package/src/llm/components/Event/_style.scss +144 -0
- package/src/llm/components/Event/event.tsx +70 -0
- package/src/llm/components/EventGroup/_style.scss +60 -0
- package/src/llm/components/EventGroup/eventgroup.tsx +59 -0
- package/src/llm/components/FormRecap/FormRecap.tsx +221 -0
- package/src/llm/components/FormRecap/_style.scss +101 -0
- package/src/llm/components/FormRecapError/FormRecapError.tsx +10 -0
- package/src/llm/components/FormRecapError/_style.scss +11 -0
- package/src/llm/components/FormRecapSuccess/FormRecapSuccess.tsx +10 -0
- package/src/llm/components/FormRecapSuccess/_style.scss +11 -0
- package/src/llm/components/FormRequest/FormRequest.tsx +21 -0
- package/src/llm/components/FormRequest/_style.scss +21 -0
- package/src/llm/components/Header/_style.scss +72 -0
- package/src/llm/components/Header/header.tsx +38 -0
- package/src/llm/components/Intro/_style.scss +36 -0
- package/src/llm/components/Intro/intro.tsx +65 -0
- package/src/llm/components/Main/_style.scss +75 -0
- package/src/llm/components/Main/main.tsx +125 -0
- package/src/llm/components/Poi/_style.scss +127 -0
- package/src/llm/components/Poi/poi.tsx +58 -0
- package/src/llm/components/PoiGroup/_style.scss +14 -0
- package/src/llm/components/PoiGroup/poigroup.tsx +15 -0
- package/src/llm/components/Prompt/_style.scss +132 -0
- package/src/llm/components/Prompt/prompt.tsx +73 -0
- package/src/llm/components/Prompt/suggestions.tsx +39 -0
- package/src/llm/components/QuickLinks/_style.scss +61 -0
- package/src/llm/components/QuickLinks/quicklinks.tsx +58 -0
- package/src/llm/components/Stream/stream.tsx +37 -0
- package/src/llm/components/Text/_style.scss +89 -0
- package/src/llm/components/Text/text.tsx +28 -0
- package/src/llm/components/Thread/_style.scss +73 -0
- package/src/llm/components/Thread/thread.tsx +27 -0
- package/src/llm/components/Trigger/_style.scss +104 -0
- package/src/llm/components/Trigger/blob.tsx +42 -0
- package/src/llm/components/Trigger/trigger.tsx +50 -0
- package/src/llm/components/Tripadvisor/_style.scss +113 -0
- package/src/llm/components/Tripadvisor/tripadvisor.tsx +72 -0
- package/src/llm/hooks/useAutosizeTextArea.tsx +15 -0
- package/src/llm/llm.tsx +48 -0
- package/src/llm/scss/_base.scss +20 -0
- package/src/llm/scss/_breakpoints.scss +8 -0
- package/src/llm/scss/_layout.scss +39 -0
- package/src/llm/scss/_mixin.scss +67 -0
- package/src/llm/scss/_reset.scss +104 -0
- package/src/llm/scss/_spacing.scss +17 -0
- package/src/llm/scss/_typography.scss +153 -0
- package/src/llm/scss/_vars.scss +23 -0
- package/src/llm/scss/style.scss +29 -0
- package/src/llm/utils.tsx +12 -0
- package/src/types.ts +215 -0
- package/src/useLlm/cors.ts +124 -0
- package/src/useLlm/emitter.ts +29 -0
- package/src/useLlm/message.service.ts +336 -0
- package/src/useLlm/mock.ts +801 -0
- package/src/useLlm/speech.ts +363 -0
- package/src/useLlm/useLlm.tsx +474 -0
|
@@ -0,0 +1,3566 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var bomCore = require('@websolutespa/bom-core');
|
|
5
|
+
var bomMixerHooks = require('@websolutespa/bom-mixer-hooks');
|
|
6
|
+
var framerMotion = require('framer-motion');
|
|
7
|
+
var react = require('react');
|
|
8
|
+
var zustand = require('zustand');
|
|
9
|
+
var middleware = require('zustand/middleware');
|
|
10
|
+
var reactLenis = require('@studio-freight/react-lenis');
|
|
11
|
+
var bomMixerIcons = require('@websolutespa/bom-mixer-icons');
|
|
12
|
+
var ArrayBuffer = require('nanogl/arraybuffer');
|
|
13
|
+
var Program = require('nanogl/program');
|
|
14
|
+
require('swiper/css');
|
|
15
|
+
var react$1 = require('swiper/react');
|
|
16
|
+
var swiper = require('swiper');
|
|
17
|
+
var marked = require('marked');
|
|
18
|
+
|
|
19
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
|
+
|
|
21
|
+
var ArrayBuffer__default = /*#__PURE__*/_interopDefault(ArrayBuffer);
|
|
22
|
+
var Program__default = /*#__PURE__*/_interopDefault(Program);
|
|
23
|
+
|
|
24
|
+
/******************************************************************************
|
|
25
|
+
Copyright (c) Microsoft Corporation.
|
|
26
|
+
|
|
27
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
28
|
+
purpose with or without fee is hereby granted.
|
|
29
|
+
|
|
30
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
31
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
32
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
33
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
34
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
35
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
36
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
37
|
+
***************************************************************************** */
|
|
38
|
+
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
39
|
+
|
|
40
|
+
function __rest(s, e) {
|
|
41
|
+
var t = {};
|
|
42
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
|
|
43
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
44
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
|
|
45
|
+
}
|
|
46
|
+
return t;
|
|
47
|
+
}
|
|
48
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
49
|
+
function adopt(value) {
|
|
50
|
+
return value instanceof P ? value : new P(function (resolve) {
|
|
51
|
+
resolve(value);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
55
|
+
function fulfilled(value) {
|
|
56
|
+
try {
|
|
57
|
+
step(generator.next(value));
|
|
58
|
+
} catch (e) {
|
|
59
|
+
reject(e);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function rejected(value) {
|
|
63
|
+
try {
|
|
64
|
+
step(generator["throw"](value));
|
|
65
|
+
} catch (e) {
|
|
66
|
+
reject(e);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function step(result) {
|
|
70
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
71
|
+
}
|
|
72
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function __values(o) {
|
|
76
|
+
var s = typeof Symbol === "function" && Symbol.iterator,
|
|
77
|
+
m = s && o[s],
|
|
78
|
+
i = 0;
|
|
79
|
+
if (m) return m.call(o);
|
|
80
|
+
if (o && typeof o.length === "number") return {
|
|
81
|
+
next: function () {
|
|
82
|
+
if (o && i >= o.length) o = void 0;
|
|
83
|
+
return {
|
|
84
|
+
value: o && o[i++],
|
|
85
|
+
done: !o
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
90
|
+
}
|
|
91
|
+
function __await(v) {
|
|
92
|
+
return this instanceof __await ? (this.v = v, this) : new __await(v);
|
|
93
|
+
}
|
|
94
|
+
function __asyncGenerator(thisArg, _arguments, generator) {
|
|
95
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
96
|
+
var g = generator.apply(thisArg, _arguments || []),
|
|
97
|
+
i,
|
|
98
|
+
q = [];
|
|
99
|
+
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () {
|
|
100
|
+
return this;
|
|
101
|
+
}, i;
|
|
102
|
+
function verb(n) {
|
|
103
|
+
if (g[n]) i[n] = function (v) {
|
|
104
|
+
return new Promise(function (a, b) {
|
|
105
|
+
q.push([n, v, a, b]) > 1 || resume(n, v);
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function resume(n, v) {
|
|
110
|
+
try {
|
|
111
|
+
step(g[n](v));
|
|
112
|
+
} catch (e) {
|
|
113
|
+
settle(q[0][3], e);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function step(r) {
|
|
117
|
+
r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
|
|
118
|
+
}
|
|
119
|
+
function fulfill(value) {
|
|
120
|
+
resume("next", value);
|
|
121
|
+
}
|
|
122
|
+
function reject(value) {
|
|
123
|
+
resume("throw", value);
|
|
124
|
+
}
|
|
125
|
+
function settle(f, v) {
|
|
126
|
+
if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function __asyncValues(o) {
|
|
130
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
131
|
+
var m = o[Symbol.asyncIterator],
|
|
132
|
+
i;
|
|
133
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () {
|
|
134
|
+
return this;
|
|
135
|
+
}, i);
|
|
136
|
+
function verb(n) {
|
|
137
|
+
i[n] = o[n] && function (v) {
|
|
138
|
+
return new Promise(function (resolve, reject) {
|
|
139
|
+
v = o[n](v), settle(resolve, reject, v.done, v.value);
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function settle(resolve, reject, d, v) {
|
|
144
|
+
Promise.resolve(v).then(function (v) {
|
|
145
|
+
resolve({
|
|
146
|
+
value: v,
|
|
147
|
+
done: d
|
|
148
|
+
});
|
|
149
|
+
}, reject);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
153
|
+
var e = new Error(message);
|
|
154
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
class MessageService {
|
|
158
|
+
constructor(options) {
|
|
159
|
+
this.decoder_ = new TextDecoder('utf-8');
|
|
160
|
+
this.options = options;
|
|
161
|
+
}
|
|
162
|
+
sendMessage(request, onMessage, onEnd, onChunk) {
|
|
163
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
164
|
+
var _a, e_1, _b, _c;
|
|
165
|
+
this.abort();
|
|
166
|
+
// console.log('MessageServiceService.request', request);
|
|
167
|
+
const aborter = new AbortController();
|
|
168
|
+
const url = this.options.url;
|
|
169
|
+
const decodedChunks = [];
|
|
170
|
+
this.lastMessage_ = {
|
|
171
|
+
aborter,
|
|
172
|
+
decodedChunks,
|
|
173
|
+
onEnd
|
|
174
|
+
};
|
|
175
|
+
let bytes = 0;
|
|
176
|
+
const signal = aborter.signal;
|
|
177
|
+
try {
|
|
178
|
+
const response = yield fetch(url, {
|
|
179
|
+
method: 'POST',
|
|
180
|
+
body: JSON.stringify(request),
|
|
181
|
+
headers: {
|
|
182
|
+
'Content-Type': 'application/json'
|
|
183
|
+
},
|
|
184
|
+
signal
|
|
185
|
+
});
|
|
186
|
+
if (response.body) {
|
|
187
|
+
const reader = response.body.getReader();
|
|
188
|
+
this.lastMessage_.reader = reader;
|
|
189
|
+
try {
|
|
190
|
+
for (var _d = true, _e = __asyncValues(readChunks(reader)), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
|
|
191
|
+
_c = _f.value;
|
|
192
|
+
_d = false;
|
|
193
|
+
const chunk = _c;
|
|
194
|
+
if (!signal.aborted) {
|
|
195
|
+
bytes += chunk.length;
|
|
196
|
+
const chunks = this.bytesToChunks(chunk);
|
|
197
|
+
decodedChunks.push(...chunks);
|
|
198
|
+
const response = chunksToResponse(decodedChunks);
|
|
199
|
+
if (typeof onMessage === 'function') {
|
|
200
|
+
onMessage(response);
|
|
201
|
+
}
|
|
202
|
+
if (typeof onChunk === 'function') {
|
|
203
|
+
onChunk(chunks);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
} catch (e_1_1) {
|
|
208
|
+
e_1 = {
|
|
209
|
+
error: e_1_1
|
|
210
|
+
};
|
|
211
|
+
} finally {
|
|
212
|
+
try {
|
|
213
|
+
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
|
214
|
+
} finally {
|
|
215
|
+
if (e_1) throw e_1.error;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (!signal.aborted) {
|
|
219
|
+
if (typeof onEnd === 'function') {
|
|
220
|
+
const response = chunksToResponse(decodedChunks);
|
|
221
|
+
onEnd(response);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
} catch (error) {
|
|
226
|
+
if (error instanceof TypeError) {
|
|
227
|
+
console.error('TypeError: Browser may not support async iteration', error);
|
|
228
|
+
}
|
|
229
|
+
throw error;
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
abort() {
|
|
234
|
+
const lastMessage = this.lastMessage_;
|
|
235
|
+
if (lastMessage && lastMessage.aborter && !lastMessage.aborter.signal.aborted) {
|
|
236
|
+
try {
|
|
237
|
+
if (lastMessage.reader) {
|
|
238
|
+
lastMessage.reader.cancel().catch(error => {
|
|
239
|
+
console.log('MessageService.abort.reader.error', error);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
lastMessage.aborter.abort();
|
|
243
|
+
} catch (error) {
|
|
244
|
+
console.log('MessageService.abort.error', error);
|
|
245
|
+
}
|
|
246
|
+
if (typeof lastMessage.onEnd === 'function') {
|
|
247
|
+
const response = chunksToResponse(lastMessage.decodedChunks);
|
|
248
|
+
lastMessage.onEnd(response);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
bytesToChunks(byteArray) {
|
|
253
|
+
let decodedChunks = [];
|
|
254
|
+
let decodedText = '';
|
|
255
|
+
try {
|
|
256
|
+
decodedText = this.decoder_.decode(byteArray);
|
|
257
|
+
decodedChunks = textToChunks(decodedText);
|
|
258
|
+
} catch (error) {
|
|
259
|
+
console.log('decodedChunk.error', error, decodedText);
|
|
260
|
+
}
|
|
261
|
+
// console.log(decodedChunks, decodedText);
|
|
262
|
+
return decodedChunks;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function readChunks(reader) {
|
|
266
|
+
return {
|
|
267
|
+
[Symbol.asyncIterator]() {
|
|
268
|
+
return __asyncGenerator(this, arguments, function* _a() {
|
|
269
|
+
let readResult = yield __await(reader.read());
|
|
270
|
+
while (!readResult.done) {
|
|
271
|
+
yield yield __await(readResult.value);
|
|
272
|
+
readResult = yield __await(reader.read());
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
/*
|
|
279
|
+
async function* streamAsyncIterable<T>(stream: ReadableStream<T>) {
|
|
280
|
+
const reader = stream.getReader();
|
|
281
|
+
try {
|
|
282
|
+
while (true) {
|
|
283
|
+
const { done, value } = await reader.read();
|
|
284
|
+
if (done) return;
|
|
285
|
+
yield value;
|
|
286
|
+
}
|
|
287
|
+
} finally {
|
|
288
|
+
reader.releaseLock();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
class Iterator {
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
(Iterator as any).prototype[Symbol.asyncIterator] = async function* () {
|
|
296
|
+
const reader = this.getReader();
|
|
297
|
+
try {
|
|
298
|
+
while (true) {
|
|
299
|
+
const { done, value } = await reader.read();
|
|
300
|
+
if (done) return;
|
|
301
|
+
yield value;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
finally {
|
|
305
|
+
reader.releaseLock();
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
*/
|
|
309
|
+
function chunksToResponse(decodedChunks) {
|
|
310
|
+
const response = {
|
|
311
|
+
chunks: [],
|
|
312
|
+
threadId: ''
|
|
313
|
+
};
|
|
314
|
+
response.chunks = chunksToChunkItems(decodedChunks, response);
|
|
315
|
+
return response;
|
|
316
|
+
}
|
|
317
|
+
function textToChunks(decodedText) {
|
|
318
|
+
let decodedChunks = [];
|
|
319
|
+
try {
|
|
320
|
+
// const replacedText = decodedText.replace(/(^\[)|(,$)|(\]$)/g, '');
|
|
321
|
+
let replacedText = decodedText;
|
|
322
|
+
// replacedText = replacedText.replace(/(^,")/, '",');
|
|
323
|
+
replacedText = replacedText.replace(/(,$)/, '');
|
|
324
|
+
// replacedText = replacedText.replace(/}\s{/g, '},{');
|
|
325
|
+
/*
|
|
326
|
+
replacedText = replacedText.split(',').map(x => {
|
|
327
|
+
return x.replace(/^"([^{]*)"$/m, (m, g) => {
|
|
328
|
+
return '"' + g.replace('"', '\\"') + '"';
|
|
329
|
+
});
|
|
330
|
+
}).join(',');
|
|
331
|
+
*/
|
|
332
|
+
// console.log('textToChunks.replacedText', `[${replacedText}]`);
|
|
333
|
+
const chunks = JSON.parse(`[${replacedText}]`);
|
|
334
|
+
// console.log('chunks', chunks);
|
|
335
|
+
/*
|
|
336
|
+
decodedChunks = chunks.map(chunk => {
|
|
337
|
+
if (typeof chunk === 'string') {
|
|
338
|
+
chunk = chunk.replace(/\r\n/g, '<br>');
|
|
339
|
+
}
|
|
340
|
+
return chunk;
|
|
341
|
+
});
|
|
342
|
+
*/
|
|
343
|
+
decodedChunks = chunks;
|
|
344
|
+
} catch (error) {
|
|
345
|
+
console.log('textToChunks.error', error, decodedText);
|
|
346
|
+
}
|
|
347
|
+
// console.log(decodedChunks, decodedText);
|
|
348
|
+
return decodedChunks;
|
|
349
|
+
}
|
|
350
|
+
function chunksToChunkItems(decodedChunks, response) {
|
|
351
|
+
const chunks = [];
|
|
352
|
+
decodedChunks.forEach(x => {
|
|
353
|
+
const lastMessage = chunks[chunks.length - 1];
|
|
354
|
+
if (bomCore.isObject(x)) {
|
|
355
|
+
switch (x.type) {
|
|
356
|
+
case 'log':
|
|
357
|
+
console.log('LlmMessageService.log', x);
|
|
358
|
+
break;
|
|
359
|
+
case 'error':
|
|
360
|
+
console.error('LlmMessageService.error', x);
|
|
361
|
+
break;
|
|
362
|
+
case 'info':
|
|
363
|
+
case 'end':
|
|
364
|
+
{
|
|
365
|
+
const rest = __rest(x, ["type"]);
|
|
366
|
+
if (response) {
|
|
367
|
+
Object.assign(response, rest);
|
|
368
|
+
}
|
|
369
|
+
// response = { ...response, ...rest };
|
|
370
|
+
}
|
|
371
|
+
break;
|
|
372
|
+
case 'eventItem':
|
|
373
|
+
if (lastMessage && lastMessage.type === 'eventGroup') {
|
|
374
|
+
lastMessage.items.push(x);
|
|
375
|
+
} else {
|
|
376
|
+
chunks.push({
|
|
377
|
+
type: 'eventGroup',
|
|
378
|
+
items: [x]
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
break;
|
|
382
|
+
case 'poiItem':
|
|
383
|
+
if (lastMessage && lastMessage.type === 'poiGroup') {
|
|
384
|
+
lastMessage.items.push(x);
|
|
385
|
+
} else {
|
|
386
|
+
chunks.push({
|
|
387
|
+
type: 'poiGroup',
|
|
388
|
+
items: [x]
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
break;
|
|
392
|
+
case 'tripadvisor':
|
|
393
|
+
case 'tripadvisorItem':
|
|
394
|
+
if (lastMessage && lastMessage.type === 'tripadvisorGroup') {
|
|
395
|
+
lastMessage.items.push(Object.assign(Object.assign({}, x), {
|
|
396
|
+
type: 'tripadvisorItem'
|
|
397
|
+
}));
|
|
398
|
+
} else {
|
|
399
|
+
chunks.push({
|
|
400
|
+
type: 'tripadvisorGroup',
|
|
401
|
+
items: [Object.assign(Object.assign({}, x), {
|
|
402
|
+
type: 'tripadvisorItem'
|
|
403
|
+
})]
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
break;
|
|
407
|
+
default:
|
|
408
|
+
chunks.push(x);
|
|
409
|
+
}
|
|
410
|
+
} else if (typeof x === 'string') {
|
|
411
|
+
// console.warn('chunksToChunkItems typeof string');
|
|
412
|
+
if (lastMessage && lastMessage.type === 'string' && !lastMessage.content.includes('\n')) {
|
|
413
|
+
if (x.includes('\n')) {
|
|
414
|
+
const contents = x.split('\n');
|
|
415
|
+
contents.forEach((content, i) => {
|
|
416
|
+
const lastChar = contents.length > i + 1 ? '\n' : '';
|
|
417
|
+
if (i === 0) {
|
|
418
|
+
lastMessage.content += content + lastChar;
|
|
419
|
+
} else if (content.length > 0) {
|
|
420
|
+
chunks.push({
|
|
421
|
+
type: 'string',
|
|
422
|
+
content: content + lastChar
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
} else {
|
|
427
|
+
lastMessage.content += x;
|
|
428
|
+
}
|
|
429
|
+
} else {
|
|
430
|
+
chunks.push({
|
|
431
|
+
type: 'string',
|
|
432
|
+
content: x
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
return chunks;
|
|
438
|
+
}
|
|
439
|
+
function decodeMessages(messages) {
|
|
440
|
+
return messages.map(x => {
|
|
441
|
+
if (x.role === 'user') {
|
|
442
|
+
return Object.assign(Object.assign({}, x), {
|
|
443
|
+
chunks: [{
|
|
444
|
+
type: 'string',
|
|
445
|
+
content: x.content
|
|
446
|
+
}]
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
return Object.assign(Object.assign({}, x), {
|
|
450
|
+
chunks: chunksToChunkItems(textToChunks(x.content))
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
function shouldAddFormRequest(messages) {
|
|
455
|
+
const hasFormRequest = messages.find(x => x.chunks.find(x => x.type === 'formRequest') !== undefined);
|
|
456
|
+
const importantMessages = messages.filter(x => x.chunks.find(x => ['event', 'eventItem', 'eventGroup', 'poi', 'poiItem', 'poiGroup', 'tripadvisor', 'tripadvisorItem', 'tripadvisorGroup'].includes(x.type)) !== undefined);
|
|
457
|
+
return !hasFormRequest && importantMessages.length > 1;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const APP = {
|
|
461
|
+
it: {
|
|
462
|
+
mode: 'site',
|
|
463
|
+
contents: {
|
|
464
|
+
logo: {
|
|
465
|
+
id: '6560a04654a910c2150ab7a9',
|
|
466
|
+
alt: 'logo Pesaro2024',
|
|
467
|
+
filename: 'logo-pesaro-2025.svg',
|
|
468
|
+
mimeType: 'image/svg+xml',
|
|
469
|
+
filesize: 28279,
|
|
470
|
+
width: 198,
|
|
471
|
+
height: 60,
|
|
472
|
+
sizes: {
|
|
473
|
+
card: {},
|
|
474
|
+
feature: {}
|
|
475
|
+
},
|
|
476
|
+
createdAt: '2023-11-24T13:08:22.746Z',
|
|
477
|
+
updatedAt: '2023-11-24T13:08:22.746Z',
|
|
478
|
+
url: 'https://design.wslabs.it/llm/media/logo-pesaro-2024.svg',
|
|
479
|
+
src: 'https://design.wslabs.it/llm/media/logo-pesaro-2024.svg',
|
|
480
|
+
type: 'image'
|
|
481
|
+
},
|
|
482
|
+
logoMini: {
|
|
483
|
+
id: '6560a04654a910c2150ab7a9',
|
|
484
|
+
alt: 'logo Pesaro2024',
|
|
485
|
+
filename: 'logo-pesaro-2025.svg',
|
|
486
|
+
mimeType: 'image/svg+xml',
|
|
487
|
+
filesize: 28279,
|
|
488
|
+
width: 198,
|
|
489
|
+
height: 60,
|
|
490
|
+
sizes: {
|
|
491
|
+
card: {},
|
|
492
|
+
feature: {}
|
|
493
|
+
},
|
|
494
|
+
createdAt: '2023-11-24T13:08:22.746Z',
|
|
495
|
+
updatedAt: '2023-11-24T13:08:22.746Z',
|
|
496
|
+
url: 'https://design.wslabs.it/llm/media/logo-pesaro-2024-mini.svg',
|
|
497
|
+
src: 'https://design.wslabs.it/llm/media/logo-pesaro-2024-mini.svg',
|
|
498
|
+
type: 'image'
|
|
499
|
+
},
|
|
500
|
+
collapsedWelcomeText: '👋 \\n Ciao, sono il tuo assistente AI',
|
|
501
|
+
collapsedWelcomeTextHover: 'Cliccami e lascia che ti consigli cosa fare e vedere a Pesaro 2024.',
|
|
502
|
+
shortWelcomeText: 'Ciao, sono l\'ambasciatore AI di Pesaro2024.',
|
|
503
|
+
extendedWelcomeText: 'Ciao, sono l\'Ambasciatore AI di Pesaro2024. Più cose mi dirai su ciò che ti piace, più sarò in grado di aiutarti.',
|
|
504
|
+
sampleInputTexts: [{
|
|
505
|
+
sampleInputText: 'Quali sono gli eventi che posso raggiungere a piedi dalla stazione dei treni?',
|
|
506
|
+
id: '656095350d5d91982799c3fd'
|
|
507
|
+
}, {
|
|
508
|
+
sampleInputText: 'Mostra i prossimi eventi di fotografia',
|
|
509
|
+
id: '6560954e0d5d91982799c3fe'
|
|
510
|
+
}, {
|
|
511
|
+
sampleInputText: 'Chi partecipa a Pesaro2024?',
|
|
512
|
+
id: '6560955b0d5d91982799c3ff'
|
|
513
|
+
}],
|
|
514
|
+
layoutBuilder: [{
|
|
515
|
+
icon: {
|
|
516
|
+
id: '6560a05454a910c2150ab7b4',
|
|
517
|
+
alt: 'itinerario',
|
|
518
|
+
filename: 'itinerary-1.svg',
|
|
519
|
+
mimeType: 'image/svg+xml',
|
|
520
|
+
filesize: 1174,
|
|
521
|
+
width: 32,
|
|
522
|
+
height: 33,
|
|
523
|
+
sizes: {
|
|
524
|
+
card: {},
|
|
525
|
+
feature: {}
|
|
526
|
+
},
|
|
527
|
+
createdAt: '2023-11-24T13:08:36.444Z',
|
|
528
|
+
updatedAt: '2023-11-24T13:08:36.444Z',
|
|
529
|
+
url: 'https://design.wslabs.it/llm/media/llm-itinerary.svg',
|
|
530
|
+
src: 'https://design.wslabs.it/llm/media/llm-itinerary.svg',
|
|
531
|
+
type: 'image'
|
|
532
|
+
},
|
|
533
|
+
title: 'Pianifica un itinerario',
|
|
534
|
+
body: 'Chiedi supporto per organizzare il tuo weekend o il tuo soggiorno a Pesaro godendo di tutti gli eventi di Pesaro2024.',
|
|
535
|
+
id: '656095900d5d91982799c400',
|
|
536
|
+
blockType: 'card'
|
|
537
|
+
}, {
|
|
538
|
+
icon: {
|
|
539
|
+
id: '6560a06954a910c2150ab7c9',
|
|
540
|
+
alt: 'pin',
|
|
541
|
+
filename: 'pin-1.svg',
|
|
542
|
+
mimeType: 'image/svg+xml',
|
|
543
|
+
filesize: 1300,
|
|
544
|
+
width: 32,
|
|
545
|
+
height: 32,
|
|
546
|
+
sizes: {
|
|
547
|
+
card: {},
|
|
548
|
+
feature: {}
|
|
549
|
+
},
|
|
550
|
+
createdAt: '2023-11-24T13:08:57.714Z',
|
|
551
|
+
updatedAt: '2023-11-24T13:08:57.714Z',
|
|
552
|
+
url: 'https://design.wslabs.it/llm/media/llm-pin.svg',
|
|
553
|
+
src: 'https://design.wslabs.it/llm/media/llm-pin.svg',
|
|
554
|
+
type: 'image'
|
|
555
|
+
},
|
|
556
|
+
title: 'Esplora Pesaro',
|
|
557
|
+
body: 'Chiedi informazioni sui luoghi di cultura della Città che hanno valso a Pesaro il titolo di Capitale Italiana della Cultura 2024.',
|
|
558
|
+
id: '65609fe4152d35137e46286d',
|
|
559
|
+
blockType: 'card'
|
|
560
|
+
}, {
|
|
561
|
+
icon: {
|
|
562
|
+
id: '6560a07454a910c2150ab7d3',
|
|
563
|
+
alt: 'cerca',
|
|
564
|
+
filename: 'search.svg',
|
|
565
|
+
mimeType: 'image/svg+xml',
|
|
566
|
+
filesize: 680,
|
|
567
|
+
width: 32,
|
|
568
|
+
height: 32,
|
|
569
|
+
sizes: {
|
|
570
|
+
card: {},
|
|
571
|
+
feature: {}
|
|
572
|
+
},
|
|
573
|
+
createdAt: '2023-11-24T13:09:08.678Z',
|
|
574
|
+
updatedAt: '2023-11-24T13:09:08.678Z',
|
|
575
|
+
url: 'https://design.wslabs.it/llm/media/llm-search.svg',
|
|
576
|
+
src: 'https://design.wslabs.it/llm/media/llm-search.svg',
|
|
577
|
+
type: 'image'
|
|
578
|
+
},
|
|
579
|
+
title: 'Scopri il progetto',
|
|
580
|
+
body: 'Chiedi dettagli su come è nato il progetto Pesaro2024, come funziona e quali sono le tante realtà virtuose del territorio coinvolte.',
|
|
581
|
+
id: '65609fe8152d35137e46286e',
|
|
582
|
+
blockType: 'card'
|
|
583
|
+
}]
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
en: {
|
|
587
|
+
mode: 'site',
|
|
588
|
+
contents: {
|
|
589
|
+
logo: {
|
|
590
|
+
id: '6560a04654a910c2150ab7a9',
|
|
591
|
+
alt: 'logo Pesaro2024',
|
|
592
|
+
filename: 'logo-pesaro-2025.svg',
|
|
593
|
+
mimeType: 'image/svg+xml',
|
|
594
|
+
filesize: 28279,
|
|
595
|
+
width: 198,
|
|
596
|
+
height: 60,
|
|
597
|
+
sizes: {
|
|
598
|
+
card: {},
|
|
599
|
+
feature: {}
|
|
600
|
+
},
|
|
601
|
+
createdAt: '2023-11-24T13:08:22.746Z',
|
|
602
|
+
updatedAt: '2023-11-24T13:08:22.746Z',
|
|
603
|
+
url: 'https://design.wslabs.it/llm/media/logo-pesaro-2024.svg',
|
|
604
|
+
src: 'https://design.wslabs.it/llm/media/logo-pesaro-2024.svg',
|
|
605
|
+
type: 'image'
|
|
606
|
+
},
|
|
607
|
+
logoMini: {
|
|
608
|
+
id: '6560a04654a910c2150ab7a9',
|
|
609
|
+
alt: 'logo Pesaro2024',
|
|
610
|
+
filename: 'logo-pesaro-2025.svg',
|
|
611
|
+
mimeType: 'image/svg+xml',
|
|
612
|
+
filesize: 28279,
|
|
613
|
+
width: 198,
|
|
614
|
+
height: 60,
|
|
615
|
+
sizes: {
|
|
616
|
+
card: {},
|
|
617
|
+
feature: {}
|
|
618
|
+
},
|
|
619
|
+
createdAt: '2023-11-24T13:08:22.746Z',
|
|
620
|
+
updatedAt: '2023-11-24T13:08:22.746Z',
|
|
621
|
+
url: 'https://design.wslabs.it/llm/media/logo-pesaro-2024-mini.svg',
|
|
622
|
+
src: 'https://design.wslabs.it/llm/media/logo-pesaro-2024-mini.svg',
|
|
623
|
+
type: 'image'
|
|
624
|
+
},
|
|
625
|
+
collapsedWelcomeText: '👋 \\n Hi, I\'m your AI assistant',
|
|
626
|
+
collapsedWelcomeTextHover: 'Click me and let me advise you on what to do and see in Pesaro 2024.',
|
|
627
|
+
shortWelcomeText: 'Hi, I\'m the AI ambassador of Pesaro2024.',
|
|
628
|
+
extendedWelcomeText: 'Hi, I\'m the AI Ambassador of Pesaro2024. The more you tell me about what you like, the more I will be able to help you.',
|
|
629
|
+
sampleInputTexts: [{
|
|
630
|
+
sampleInputText: 'What events can I walk to from the train station?',
|
|
631
|
+
id: '656095350d5d91982799c3fd'
|
|
632
|
+
}, {
|
|
633
|
+
sampleInputText: 'Shows upcoming photography events',
|
|
634
|
+
id: '6560954e0d5d91982799c3fe'
|
|
635
|
+
}, {
|
|
636
|
+
sampleInputText: 'Who participates in Pesaro2024?',
|
|
637
|
+
id: '6560955b0d5d91982799c3ff'
|
|
638
|
+
}],
|
|
639
|
+
layoutBuilder: [{
|
|
640
|
+
icon: {
|
|
641
|
+
id: '6560a05454a910c2150ab7b4',
|
|
642
|
+
alt: 'itinerario',
|
|
643
|
+
filename: 'itinerary-1.svg',
|
|
644
|
+
mimeType: 'image/svg+xml',
|
|
645
|
+
filesize: 1174,
|
|
646
|
+
width: 32,
|
|
647
|
+
height: 33,
|
|
648
|
+
sizes: {
|
|
649
|
+
card: {},
|
|
650
|
+
feature: {}
|
|
651
|
+
},
|
|
652
|
+
createdAt: '2023-11-24T13:08:36.444Z',
|
|
653
|
+
updatedAt: '2023-11-24T13:08:36.444Z',
|
|
654
|
+
url: 'https://design.wslabs.it/llm/media/llm-itinerary.svg',
|
|
655
|
+
src: 'https://design.wslabs.it/llm/media/llm-itinerary.svg',
|
|
656
|
+
type: 'image'
|
|
657
|
+
},
|
|
658
|
+
title: 'Plan an itinerary',
|
|
659
|
+
body: 'Ask for support to organize your weekend or your stay in Pesaro enjoying all the events of Pesaro2024.',
|
|
660
|
+
id: '656095900d5d91982799c400',
|
|
661
|
+
blockType: 'card'
|
|
662
|
+
}, {
|
|
663
|
+
icon: {
|
|
664
|
+
id: '6560a06954a910c2150ab7c9',
|
|
665
|
+
alt: 'pin',
|
|
666
|
+
filename: 'pin-1.svg',
|
|
667
|
+
mimeType: 'image/svg+xml',
|
|
668
|
+
filesize: 1300,
|
|
669
|
+
width: 32,
|
|
670
|
+
height: 32,
|
|
671
|
+
sizes: {
|
|
672
|
+
card: {},
|
|
673
|
+
feature: {}
|
|
674
|
+
},
|
|
675
|
+
createdAt: '2023-11-24T13:08:57.714Z',
|
|
676
|
+
updatedAt: '2023-11-24T13:08:57.714Z',
|
|
677
|
+
url: 'https://design.wslabs.it/llm/media/llm-pin.svg',
|
|
678
|
+
src: 'https://design.wslabs.it/llm/media/llm-pin.svg',
|
|
679
|
+
type: 'image'
|
|
680
|
+
},
|
|
681
|
+
title: 'Explore Pesaro',
|
|
682
|
+
body: 'Ask for information on the cultural places of the city that earned Pesaro the title of Italian Capital of Culture 2024.',
|
|
683
|
+
id: '65609fe4152d35137e46286d',
|
|
684
|
+
blockType: 'card'
|
|
685
|
+
}, {
|
|
686
|
+
icon: {
|
|
687
|
+
id: '6560a07454a910c2150ab7d3',
|
|
688
|
+
alt: 'cerca',
|
|
689
|
+
filename: 'search.svg',
|
|
690
|
+
mimeType: 'image/svg+xml',
|
|
691
|
+
filesize: 680,
|
|
692
|
+
width: 32,
|
|
693
|
+
height: 32,
|
|
694
|
+
sizes: {
|
|
695
|
+
card: {},
|
|
696
|
+
feature: {}
|
|
697
|
+
},
|
|
698
|
+
createdAt: '2023-11-24T13:09:08.678Z',
|
|
699
|
+
updatedAt: '2023-11-24T13:09:08.678Z',
|
|
700
|
+
url: 'https://design.wslabs.it/llm/media/llm-search.svg',
|
|
701
|
+
src: 'https://design.wslabs.it/llm/media/llm-search.svg',
|
|
702
|
+
type: 'image'
|
|
703
|
+
},
|
|
704
|
+
title: 'Discover the project',
|
|
705
|
+
body: 'Ask for details on how the Pesaro2024 project was born, how it works and which are the many virtuous local realities involved.',
|
|
706
|
+
id: '65609fe8152d35137e46286e',
|
|
707
|
+
blockType: 'card'
|
|
708
|
+
}]
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
const THREAD = {
|
|
713
|
+
it: [{
|
|
714
|
+
chunks: ['Sarò a Pesaro con la mia famiglia a giugno. Siamo tutti appassionati di arte e natura. Cosa ci consigli di fare qui?\n'],
|
|
715
|
+
role: 'user'
|
|
716
|
+
},
|
|
717
|
+
/*
|
|
718
|
+
{
|
|
719
|
+
chunks: [
|
|
720
|
+
'Se è la prima volta che vieni a Pesaro, ti consiglio di non perderti queste tappe!\n',
|
|
721
|
+
{
|
|
722
|
+
type: 'poiItem' as const,
|
|
723
|
+
id: '310',
|
|
724
|
+
title: 'Sfera Grande di A. Pomodoro',
|
|
725
|
+
abstract: 'Scultura sferica bronzea, soprannominata "Il pomodoro", in piscina in un parco sul Mar Adriatico.',
|
|
726
|
+
place: 'Piazzale della Libertà, 61121 Pesaro PU',
|
|
727
|
+
url: 'https://design.wslabs.it/llm',
|
|
728
|
+
image: 'https://design.wslabs.it/llm/media/casa-rossini.jpg',
|
|
729
|
+
time: 'Aperto 24 su 24',
|
|
730
|
+
},
|
|
731
|
+
{
|
|
732
|
+
type: 'poiItem' as const,
|
|
733
|
+
id: 'xxxx',
|
|
734
|
+
title: 'Baia Flaminia',
|
|
735
|
+
abstract: 'Nella spiaggia libera di Baia Flaminia è presente una rara oasi naturalistica urbana, che si trova fra il fiume Foglia e il Parco San Bartolo nel quartiere.',
|
|
736
|
+
place: '61121 Pesaro PU',
|
|
737
|
+
url: 'https://design.wslabs.it/llm',
|
|
738
|
+
image: 'https://design.wslabs.it/llm/media/casa-rossini.jpg',
|
|
739
|
+
time: 'Aperto 24 su 24',
|
|
740
|
+
},
|
|
741
|
+
{
|
|
742
|
+
type: 'poiItem' as const,
|
|
743
|
+
id: '305',
|
|
744
|
+
title: 'Parco Miralfiore',
|
|
745
|
+
abstract: 'Il Parco Urbano Miralfiore si trova proprio nel cuore di Pesaro, a ridosso della stazione ferroviaria alla quale è collegato con un sottopassaggio.',
|
|
746
|
+
place: 'Via Solferino, 61122 Pesaro PU',
|
|
747
|
+
url: 'https://design.wslabs.it/llm',
|
|
748
|
+
image: 'https://design.wslabs.it/llm/media/casa-rossini.jpg',
|
|
749
|
+
time: 'lun-ven 07-23',
|
|
750
|
+
},
|
|
751
|
+
'Vorresti sapere altro?. 🙂\n',
|
|
752
|
+
],
|
|
753
|
+
role: 'assistant',
|
|
754
|
+
},
|
|
755
|
+
{
|
|
756
|
+
chunks: [
|
|
757
|
+
'Sarò a Pesaro con la mia famiglia a giugno. Siamo tutti appassionati di arte e natura. Cosa ci consigli di fare qui?\n',
|
|
758
|
+
],
|
|
759
|
+
role: 'user',
|
|
760
|
+
},
|
|
761
|
+
*/
|
|
762
|
+
{
|
|
763
|
+
chunks: ['Fammi pensare, quanti anni hanno i tuoi figli?\n'],
|
|
764
|
+
role: 'assistant'
|
|
765
|
+
}, {
|
|
766
|
+
chunks: ['17 e 13.'],
|
|
767
|
+
role: 'user'
|
|
768
|
+
}, {
|
|
769
|
+
chunks: ['Ottimo! Niente batte il girovagare tra arte e natura con i propri piccoli! Ho selezionato un sacco di cose da fare, pensate proprio per voi.\n', 'Dai un\'occhiata, approfondisci gli eventi e le attività che ti attirano di più e se ti serve altro mi trovi qui!\n', 'Ecco una lista di eventi e attività selezionate dal sito adatte anche a ragazzi di quella età che si tengono a giugno o in generale:\n', {
|
|
770
|
+
type: 'eventItem',
|
|
771
|
+
id: 'xxxx',
|
|
772
|
+
title: 'Percorri la Bicipolitana di Pesaro con i tuoi bambini',
|
|
773
|
+
abstract: 'Un’esperienza da non perdere se visiterai la città con i bambini, noleggia la tua bici e esplora Pesaro.',
|
|
774
|
+
place: 'Pesaro',
|
|
775
|
+
url: 'https://design.wslabs.it/llm',
|
|
776
|
+
image: 'https://design.wslabs.it/llm/media/bicipolitana.jpg',
|
|
777
|
+
date: '15-16 giugno 2024',
|
|
778
|
+
time: 'ore 20:00'
|
|
779
|
+
}, {
|
|
780
|
+
type: 'eventItem',
|
|
781
|
+
id: '100',
|
|
782
|
+
title: 'Non perderti The Magic Castle di Gradara!',
|
|
783
|
+
abstract: 'The Magic Castle, l’evento per famiglie che ogni estate trasforma magicamente lo splendido borgo di Gradara.',
|
|
784
|
+
place: 'Gradara',
|
|
785
|
+
url: 'https://design.wslabs.it/llm',
|
|
786
|
+
image: 'https://design.wslabs.it/llm/media/gradara.jpg',
|
|
787
|
+
date: '15-16 giugno 2024',
|
|
788
|
+
time: 'ore 20:00'
|
|
789
|
+
}, {
|
|
790
|
+
type: 'eventItem',
|
|
791
|
+
id: 'xxxx',
|
|
792
|
+
title: 'Trekking e panorami mozzafiato al San Bartolo',
|
|
793
|
+
abstract: 'Scendendo lungo la costa Adriatica, si erge il San Bartolo, un meraviglioso parco naturale affacciato sul mare.',
|
|
794
|
+
place: 'Parco San Bartolo',
|
|
795
|
+
url: 'https://design.wslabs.it/llm',
|
|
796
|
+
image: 'https://design.wslabs.it/llm/media/san-bartolo.jpg',
|
|
797
|
+
date: '15-16 giugno 2024',
|
|
798
|
+
time: 'ore 20:00'
|
|
799
|
+
}, 'Per qualunque altra cosa sono qui. 🙂\n'],
|
|
800
|
+
role: 'assistant'
|
|
801
|
+
}, {
|
|
802
|
+
chunks: ['E se piove?\n'],
|
|
803
|
+
role: 'user'
|
|
804
|
+
}, {
|
|
805
|
+
chunks: ['D\'estate piove meno, ma quando succede è proprio una scocciatura. Speriamo di evitarla, ma nel caso non ti lascio di certo scoperto!\n', 'Ti ho preparato una lista di cose da fare al chiuso.\n', 'Ecco una lista di eventi e attività selezionate dal sito adatte a ragazzi di quella età che si tengono a giugno o in generale ma al chiuso:\n', {
|
|
806
|
+
type: 'eventItem',
|
|
807
|
+
id: '310',
|
|
808
|
+
title: 'Esplora la casa del grande compositore Rossini',
|
|
809
|
+
abstract: 'Rossini è stato un grande compositore italiano della prima metà del XIX secolo, vieni ad esplorare la sua casa natale.',
|
|
810
|
+
place: 'Casa Rossini',
|
|
811
|
+
url: 'https://design.wslabs.it/llm',
|
|
812
|
+
image: 'https://design.wslabs.it/llm/media/casa-rossini.jpg',
|
|
813
|
+
date: '15-16 giugno 2024',
|
|
814
|
+
time: 'ore 20:00'
|
|
815
|
+
}, {
|
|
816
|
+
type: 'eventItem',
|
|
817
|
+
id: '305',
|
|
818
|
+
title: 'Vivi un’esperienza sonora incredibile alla Sonosfera©',
|
|
819
|
+
abstract: 'Questo Teatro per l’ascolto profondo di ecosistemi e musica è un’esperienza unica al mondo.',
|
|
820
|
+
place: 'Sonosfera',
|
|
821
|
+
url: 'https://design.wslabs.it/llm',
|
|
822
|
+
image: 'https://design.wslabs.it/llm/media/sonosfera.jpg',
|
|
823
|
+
date: '15-16 giugno 2024',
|
|
824
|
+
time: 'ore 20:00'
|
|
825
|
+
}, {
|
|
826
|
+
type: 'eventItem',
|
|
827
|
+
id: 'xxxx',
|
|
828
|
+
title: 'Sperimenta con la scienza al Museo del Balì',
|
|
829
|
+
abstract: 'Il museo del Balì rispecchia la filosofia “hands-on”, Vietato NON toccare! Divertiti con le sue installazioni interattive.',
|
|
830
|
+
place: 'Museo del Balì',
|
|
831
|
+
url: 'https://design.wslabs.it/llm',
|
|
832
|
+
image: 'https://design.wslabs.it/llm/media/museo-del-bali.jpg',
|
|
833
|
+
date: '15-16 giugno 2024',
|
|
834
|
+
time: 'ore 20:00'
|
|
835
|
+
}, 'Vorresti sapere altro?. 🙂\n'],
|
|
836
|
+
role: 'assistant'
|
|
837
|
+
}, {
|
|
838
|
+
chunks: ['Ci sono eventi o iniziative specifiche per i bambini alla Casa Rossini durante il mese di giugno?\n'],
|
|
839
|
+
role: 'user'
|
|
840
|
+
}, {
|
|
841
|
+
chunks: ['Certo! A giugno ci sono alcune iniziative che possono essere interessanti e divertenti per i tuoi ragazzi, ho pensato di proporti queste:\n', {
|
|
842
|
+
type: 'event',
|
|
843
|
+
id: '234',
|
|
844
|
+
title: 'Rossini Virtual Experience: esplora casa Rossini in AR',
|
|
845
|
+
abstract: 'Lasciati guidare dallo stesso Gioacchino nella sua casa e scopri la sua storia attraverso giocosi aneddoti in AR.',
|
|
846
|
+
place: 'Pesaro',
|
|
847
|
+
url: 'https://design.wslabs.it/llm',
|
|
848
|
+
image: 'https://design.wslabs.it/llm/media/rossini.jpg',
|
|
849
|
+
date: '15-16 giugno 2024',
|
|
850
|
+
time: 'ore 20:00'
|
|
851
|
+
}],
|
|
852
|
+
role: 'assistant'
|
|
853
|
+
}, {
|
|
854
|
+
chunks: ['Puoi anche consigliarmi dove mangiare del buon cibo tipico, specialmente pesce, a un prezzo ragionevole?\n'],
|
|
855
|
+
role: 'user'
|
|
856
|
+
}, {
|
|
857
|
+
chunks: ['Bene! Mangiando piatti locali assaporerei la vera cultura pesarese!\n', 'ho pensato per te alcuni ristoranti che fanno pesce in modo tipico, sono adatti alle famiglie con ragazzi e non sono troppo costosi, vediamo se fanno per te:\n', {
|
|
858
|
+
type: 'tripadvisor',
|
|
859
|
+
id: 'xxxx',
|
|
860
|
+
title: 'L\'Angolo di Mario',
|
|
861
|
+
rating: 4.8,
|
|
862
|
+
reviews: 2276,
|
|
863
|
+
priceRange: '€€-€€€',
|
|
864
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
865
|
+
address: 'Via Nazario Sauro, 61100 Pesaro PU',
|
|
866
|
+
url: 'https://design.wslabs.it/llm',
|
|
867
|
+
book: 'https://design.wslabs.it/llm',
|
|
868
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-01.jpg'
|
|
869
|
+
}, {
|
|
870
|
+
type: 'tripadvisor',
|
|
871
|
+
id: 'xxxx',
|
|
872
|
+
title: 'L\'Amo Osteria di Mare',
|
|
873
|
+
rating: 4.2,
|
|
874
|
+
reviews: 287,
|
|
875
|
+
priceRange: '€€-€€€',
|
|
876
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
877
|
+
address: 'Via Venturini 4/6, 61121 Pesaro PU',
|
|
878
|
+
url: 'https://design.wslabs.it/llm',
|
|
879
|
+
book: 'https://design.wslabs.it/llm',
|
|
880
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-02.jpg'
|
|
881
|
+
}, {
|
|
882
|
+
type: 'tripadvisor',
|
|
883
|
+
id: 'xxxx',
|
|
884
|
+
title: 'Osteria Marconi',
|
|
885
|
+
rating: 3.5,
|
|
886
|
+
reviews: 175,
|
|
887
|
+
priceRange: '€€-€€€',
|
|
888
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
889
|
+
address: 'Viale Guglielmo Marconi 55, 61121 Pesaro PU',
|
|
890
|
+
url: 'https://design.wslabs.it/llm',
|
|
891
|
+
book: 'https://design.wslabs.it/llm',
|
|
892
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-03.jpg'
|
|
893
|
+
}, {
|
|
894
|
+
type: 'tripadvisor',
|
|
895
|
+
id: 'xxxx',
|
|
896
|
+
title: 'Ristorante Marino',
|
|
897
|
+
rating: 4.5,
|
|
898
|
+
reviews: 25,
|
|
899
|
+
priceRange: '€€-€€€',
|
|
900
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
901
|
+
address: 'Str. Panoramica Adriatica, 61121 Pesaro PU',
|
|
902
|
+
url: 'https://design.wslabs.it/llm',
|
|
903
|
+
book: 'https://design.wslabs.it/llm',
|
|
904
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-04.jpg'
|
|
905
|
+
}, {
|
|
906
|
+
type: 'tripadvisor',
|
|
907
|
+
id: 'xxxx',
|
|
908
|
+
title: 'Ristorante Pizzeria Giro di Boa',
|
|
909
|
+
rating: 4.5,
|
|
910
|
+
reviews: 474,
|
|
911
|
+
priceRange: '€€-€€€',
|
|
912
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
913
|
+
address: 'Viale Trieste, 277, 61121 Pesaro PU',
|
|
914
|
+
url: 'https://design.wslabs.it/llm',
|
|
915
|
+
book: 'https://design.wslabs.it/llm',
|
|
916
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-05.jpg'
|
|
917
|
+
}, {
|
|
918
|
+
type: 'tripadvisor',
|
|
919
|
+
id: 'xxxx',
|
|
920
|
+
title: 'Taverna del Pescatore',
|
|
921
|
+
rating: 4.5,
|
|
922
|
+
reviews: 811,
|
|
923
|
+
priceRange: '€€-€€€',
|
|
924
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
925
|
+
address: 'Borgata Casteldimezzo, 23, 61121 Pesaro PU',
|
|
926
|
+
url: 'https://design.wslabs.it/llm',
|
|
927
|
+
book: 'https://design.wslabs.it/llm',
|
|
928
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-06.jpg'
|
|
929
|
+
}],
|
|
930
|
+
role: 'assistant'
|
|
931
|
+
}, {
|
|
932
|
+
chunks: ['Sì\n'],
|
|
933
|
+
role: 'user'
|
|
934
|
+
}],
|
|
935
|
+
en: [{
|
|
936
|
+
chunks: ['I will be in Pesaro with my family in June. We are all passionate about art and nature. What do you recommend we do here?\n'],
|
|
937
|
+
role: 'user'
|
|
938
|
+
}, {
|
|
939
|
+
chunks: ['Let me think, how old are your kids?\n'],
|
|
940
|
+
role: 'assistant'
|
|
941
|
+
}, {
|
|
942
|
+
chunks: ['17 and 13.'],
|
|
943
|
+
role: 'user'
|
|
944
|
+
}, {
|
|
945
|
+
chunks: ['Optimal! Nothing beats wandering around art and nature with your little ones! I have selected a lot of things to do designed just for you.\n', 'Take a look, learn more about the events and activities that attract you most and if you need anything else, you can find me here!\n', 'Here is a list of events and activities selected by the site also suitable for children of that age that take place in June or in general:\n', {
|
|
946
|
+
type: 'eventItem',
|
|
947
|
+
id: 'xxxx',
|
|
948
|
+
title: 'Ride along the Bicipolitana of Pesaro with your children',
|
|
949
|
+
abstract: 'An experience not to be missed if you visit the city with children, rent your bike and explore Pesaro.',
|
|
950
|
+
place: 'Pesaro',
|
|
951
|
+
url: 'https://design.wslabs.it/llm',
|
|
952
|
+
image: 'https://design.wslabs.it/llm/media/bicipolitana.jpg',
|
|
953
|
+
date: '15-16 june 2024',
|
|
954
|
+
time: '8:00 pm'
|
|
955
|
+
}, {
|
|
956
|
+
type: 'eventItem',
|
|
957
|
+
id: '100',
|
|
958
|
+
title: 'Don\'t miss The Magic Castle of Gradara!',
|
|
959
|
+
abstract: 'The Magic Castle, the family event that magically transforms the splendid village of Gradara every summer.',
|
|
960
|
+
place: 'Gradara',
|
|
961
|
+
url: 'https://design.wslabs.it/llm',
|
|
962
|
+
image: 'https://design.wslabs.it/llm/media/gradara.jpg',
|
|
963
|
+
date: '15-16 june 2024',
|
|
964
|
+
time: '8:00 pm'
|
|
965
|
+
}, {
|
|
966
|
+
type: 'eventItem',
|
|
967
|
+
id: 'xxxx',
|
|
968
|
+
title: 'Trekking and breathtaking views at San Bartolo',
|
|
969
|
+
abstract: 'Going down the Adriatic coast, stands San Bartolo, a wonderful natural park overlooking the sea.',
|
|
970
|
+
place: 'Parco San Bartolo',
|
|
971
|
+
url: 'https://design.wslabs.it/llm',
|
|
972
|
+
image: 'https://design.wslabs.it/llm/media/san-bartolo.jpg',
|
|
973
|
+
date: '15-16 june 2024',
|
|
974
|
+
time: '8:00 pm'
|
|
975
|
+
}, 'For anything else I\'m here. 🙂\n'],
|
|
976
|
+
role: 'assistant'
|
|
977
|
+
}, {
|
|
978
|
+
chunks: ['What if it rains?\n'],
|
|
979
|
+
role: 'user'
|
|
980
|
+
}, {
|
|
981
|
+
chunks: ['In the summer it rains less, but when it happens it\'s a real nuisance. We hope to avoid it, but if we do, I certainly won\'t leave you exposed!\n', 'I\'ve prepared a list of things for you to do indoors.\n', 'Here is a list of events and activities selected by the site suitable for children of that age that take place in June or in general but indoors:\n', {
|
|
982
|
+
type: 'eventItem',
|
|
983
|
+
id: '310',
|
|
984
|
+
title: 'Explore the home of the great composer Rossini',
|
|
985
|
+
abstract: 'Rossini was a great Italian composer of the first half of the 19th century, come and explore his birthplace.',
|
|
986
|
+
place: 'Rossini House',
|
|
987
|
+
url: 'https://design.wslabs.it/llm',
|
|
988
|
+
image: 'https://design.wslabs.it/llm/media/casa-rossini.jpg',
|
|
989
|
+
date: '15-16 jun 2024',
|
|
990
|
+
time: '8:00 pm'
|
|
991
|
+
}, {
|
|
992
|
+
type: 'eventItem',
|
|
993
|
+
id: '305',
|
|
994
|
+
title: 'Live an incredible sound experience at Sonosfera©',
|
|
995
|
+
abstract: 'This Theater for deep listening to ecosystems and music is a unique experience in the world.',
|
|
996
|
+
place: 'Sonosfera',
|
|
997
|
+
url: 'https://design.wslabs.it/llm',
|
|
998
|
+
image: 'https://design.wslabs.it/llm/media/sonosfera.jpg',
|
|
999
|
+
date: '15-16 june 2024',
|
|
1000
|
+
time: '8:00 pm'
|
|
1001
|
+
}, {
|
|
1002
|
+
type: 'eventItem',
|
|
1003
|
+
id: 'xxxx',
|
|
1004
|
+
title: 'Experiment with science at the Balì Museum',
|
|
1005
|
+
abstract: 'The Balì museum reflects the "hands-on" philosophy, DO NOT touch! Have fun with its interactive installations.',
|
|
1006
|
+
place: 'Balì Museum',
|
|
1007
|
+
url: 'https://design.wslabs.it/llm',
|
|
1008
|
+
image: 'https://design.wslabs.it/llm/media/museo-del-bali.jpg',
|
|
1009
|
+
date: '15-16 june 2024',
|
|
1010
|
+
time: '8:00 pm'
|
|
1011
|
+
}, 'Would you like to know more?. 🙂\n'],
|
|
1012
|
+
role: 'assistant'
|
|
1013
|
+
}, {
|
|
1014
|
+
chunks: ['Are there specific events or initiatives for children at Casa Rossini during the month of June?\n'],
|
|
1015
|
+
role: 'user'
|
|
1016
|
+
}, {
|
|
1017
|
+
chunks: ['Certain! In June there are some initiatives that can be interesting and fun for your kids, I thought I\'d offer you these:\n', {
|
|
1018
|
+
type: 'event',
|
|
1019
|
+
id: '234',
|
|
1020
|
+
title: 'Rossini Virtual Experience: explore Rossini\'s home in AR',
|
|
1021
|
+
abstract: 'Let Gioacchino himself guide you through his home and discover his story through playful anecdotes in AR.',
|
|
1022
|
+
place: 'Pesaro',
|
|
1023
|
+
url: 'https://design.wslabs.it/llm',
|
|
1024
|
+
image: 'https://design.wslabs.it/llm/media/rossini.jpg',
|
|
1025
|
+
date: '15-16 june 2024',
|
|
1026
|
+
time: '8:00 pm'
|
|
1027
|
+
}],
|
|
1028
|
+
role: 'assistant'
|
|
1029
|
+
}, {
|
|
1030
|
+
chunks: ['Can you also advise me where to eat good typical food, especially fish, at a reasonable price?\n'],
|
|
1031
|
+
role: 'user'
|
|
1032
|
+
}, {
|
|
1033
|
+
chunks: ['Well! By eating local dishes I would savor the true culture of Pesaro!\n', 'I have thought of some restaurants for you that do fish in a typical way, are suitable for families with children and are not too expensive, let\'s see if they are for you:\n', {
|
|
1034
|
+
type: 'tripadvisor',
|
|
1035
|
+
id: 'xxxx',
|
|
1036
|
+
title: 'L\'Angolo di Mario',
|
|
1037
|
+
rating: 4.8,
|
|
1038
|
+
reviews: 2276,
|
|
1039
|
+
priceRange: '€€-€€€',
|
|
1040
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
1041
|
+
address: 'Via Nazario Sauro, 61100 Pesaro PU',
|
|
1042
|
+
url: 'https://design.wslabs.it/llm',
|
|
1043
|
+
book: 'https://design.wslabs.it/llm',
|
|
1044
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-01.jpg'
|
|
1045
|
+
}, {
|
|
1046
|
+
type: 'tripadvisor',
|
|
1047
|
+
id: 'xxxx',
|
|
1048
|
+
title: 'L\'Amo Osteria di Mare',
|
|
1049
|
+
rating: 4.2,
|
|
1050
|
+
reviews: 287,
|
|
1051
|
+
priceRange: '€€-€€€',
|
|
1052
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
1053
|
+
address: 'Via Venturini 4/6, 61121 Pesaro PU',
|
|
1054
|
+
url: 'https://design.wslabs.it/llm',
|
|
1055
|
+
book: 'https://design.wslabs.it/llm',
|
|
1056
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-02.jpg'
|
|
1057
|
+
}, {
|
|
1058
|
+
type: 'tripadvisor',
|
|
1059
|
+
id: 'xxxx',
|
|
1060
|
+
title: 'Osteria Marconi',
|
|
1061
|
+
rating: 3.5,
|
|
1062
|
+
reviews: 175,
|
|
1063
|
+
priceRange: '€€-€€€',
|
|
1064
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
1065
|
+
address: 'Viale Guglielmo Marconi 55, 61121 Pesaro PU',
|
|
1066
|
+
url: 'https://design.wslabs.it/llm',
|
|
1067
|
+
book: 'https://design.wslabs.it/llm',
|
|
1068
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-03.jpg'
|
|
1069
|
+
}, {
|
|
1070
|
+
type: 'tripadvisor',
|
|
1071
|
+
id: 'xxxx',
|
|
1072
|
+
title: 'Ristorante Marino',
|
|
1073
|
+
rating: 4.5,
|
|
1074
|
+
reviews: 25,
|
|
1075
|
+
priceRange: '€€-€€€',
|
|
1076
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
1077
|
+
address: 'Str. Panoramica Adriatica, 61121 Pesaro PU',
|
|
1078
|
+
url: 'https://design.wslabs.it/llm',
|
|
1079
|
+
book: 'https://design.wslabs.it/llm',
|
|
1080
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-04.jpg'
|
|
1081
|
+
}, {
|
|
1082
|
+
type: 'tripadvisor',
|
|
1083
|
+
id: 'xxxx',
|
|
1084
|
+
title: 'Ristorante Pizzeria Giro di Boa',
|
|
1085
|
+
rating: 4.5,
|
|
1086
|
+
reviews: 474,
|
|
1087
|
+
priceRange: '€€-€€€',
|
|
1088
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
1089
|
+
address: 'Viale Trieste, 277, 61121 Pesaro PU',
|
|
1090
|
+
url: 'https://design.wslabs.it/llm',
|
|
1091
|
+
book: 'https://design.wslabs.it/llm',
|
|
1092
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-05.jpg'
|
|
1093
|
+
}, {
|
|
1094
|
+
type: 'tripadvisor',
|
|
1095
|
+
id: 'xxxx',
|
|
1096
|
+
title: 'Taverna del Pescatore',
|
|
1097
|
+
rating: 4.5,
|
|
1098
|
+
reviews: 811,
|
|
1099
|
+
priceRange: '€€-€€€',
|
|
1100
|
+
cuisine: 'Italiana, Pesce, Mediterranea',
|
|
1101
|
+
address: 'Borgata Casteldimezzo, 23, 61121 Pesaro PU',
|
|
1102
|
+
url: 'https://design.wslabs.it/llm',
|
|
1103
|
+
book: 'https://design.wslabs.it/llm',
|
|
1104
|
+
image: 'https://design.wslabs.it/llm/media/tripadvisor-06.jpg'
|
|
1105
|
+
}],
|
|
1106
|
+
role: 'assistant'
|
|
1107
|
+
}]
|
|
1108
|
+
};
|
|
1109
|
+
function getMockApp(locale, threadId) {
|
|
1110
|
+
const app = APP[locale];
|
|
1111
|
+
if (threadId) {
|
|
1112
|
+
const thread = THREAD[locale].slice(0, 4);
|
|
1113
|
+
app.thread = {
|
|
1114
|
+
messages: thread.map(x => ({
|
|
1115
|
+
role: x.role,
|
|
1116
|
+
content: x.chunks.map(x => typeof x === 'string' ? x : JSON.stringify(x)).join('\r\n')
|
|
1117
|
+
})),
|
|
1118
|
+
threadId
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
return app;
|
|
1122
|
+
}
|
|
1123
|
+
function getMockChunks(index, locale) {
|
|
1124
|
+
const chunks = [];
|
|
1125
|
+
const message = THREAD[locale][index];
|
|
1126
|
+
if (message && message.role === 'assistant') {
|
|
1127
|
+
message.chunks.forEach(chunk => {
|
|
1128
|
+
if (typeof chunk === 'string') {
|
|
1129
|
+
chunks.push(...chunk.split(' ').map((x, i, a) => `${x}${i < a.length - 1 ? ' ' : ''}`));
|
|
1130
|
+
} else {
|
|
1131
|
+
chunks.push(chunk);
|
|
1132
|
+
}
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
return chunks;
|
|
1136
|
+
}
|
|
1137
|
+
function getMockPrompt(index, locale) {
|
|
1138
|
+
const message = THREAD[locale][index];
|
|
1139
|
+
if (message && message.role === 'user') {
|
|
1140
|
+
return message.chunks[0];
|
|
1141
|
+
}
|
|
1142
|
+
return undefined;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
class Emitter {
|
|
1146
|
+
constructor() {
|
|
1147
|
+
this.events = new Map();
|
|
1148
|
+
}
|
|
1149
|
+
on(event, callback) {
|
|
1150
|
+
const callbacks = this.events.get(event) || [];
|
|
1151
|
+
callbacks.push(callback);
|
|
1152
|
+
if (!this.events.has(event)) {
|
|
1153
|
+
this.events.set(event, callbacks);
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
off(event, callback) {
|
|
1157
|
+
if (this.events.has(event)) {
|
|
1158
|
+
const callbacks = this.events.get(event).filter(c => c !== callback);
|
|
1159
|
+
this.events.set(event, callbacks);
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
emit(event) {
|
|
1163
|
+
for (var _len = arguments.length, data = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
1164
|
+
data[_key - 1] = arguments[_key];
|
|
1165
|
+
}
|
|
1166
|
+
if (this.events.has(event)) {
|
|
1167
|
+
this.events.get(event).forEach(callback => {
|
|
1168
|
+
callback(...data);
|
|
1169
|
+
// setTimeout(() => callback(...data), 0);
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
class Speech extends Emitter {
|
|
1176
|
+
set lang(lang) {
|
|
1177
|
+
if (lang !== this.lang_) {
|
|
1178
|
+
this.lang_ = lang;
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
get lang() {
|
|
1182
|
+
return this.lang_;
|
|
1183
|
+
}
|
|
1184
|
+
get pitch() {
|
|
1185
|
+
return 1;
|
|
1186
|
+
}
|
|
1187
|
+
get rate() {
|
|
1188
|
+
return 1;
|
|
1189
|
+
}
|
|
1190
|
+
get volume() {
|
|
1191
|
+
return 1;
|
|
1192
|
+
}
|
|
1193
|
+
constructor(lang, enabled) {
|
|
1194
|
+
if (lang === void 0) {
|
|
1195
|
+
lang = 'it';
|
|
1196
|
+
}
|
|
1197
|
+
if (enabled === void 0) {
|
|
1198
|
+
enabled = false;
|
|
1199
|
+
}
|
|
1200
|
+
super();
|
|
1201
|
+
this.lang_ = '';
|
|
1202
|
+
this.chunks_ = [];
|
|
1203
|
+
this.lang = lang;
|
|
1204
|
+
this.enabled = enabled;
|
|
1205
|
+
if (!this.hasSupport) {
|
|
1206
|
+
this.unsupported();
|
|
1207
|
+
}
|
|
1208
|
+
/* else {
|
|
1209
|
+
const synthesis = this.synthesis as SpeechSynthesis;
|
|
1210
|
+
if (synthesis.onvoiceschanged !== undefined) {
|
|
1211
|
+
synthesis.onvoiceschanged = (event) => {
|
|
1212
|
+
this.log('onvoiceschanged', event);
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
*/
|
|
1217
|
+
}
|
|
1218
|
+
log() {
|
|
1219
|
+
for (var _len = arguments.length, rest = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1220
|
+
rest[_key] = arguments[_key];
|
|
1221
|
+
}
|
|
1222
|
+
console.log('Speech', ...rest);
|
|
1223
|
+
}
|
|
1224
|
+
speak(text) {
|
|
1225
|
+
// console.log('Speech.speak', text, this.enabled, this.hasSupport);
|
|
1226
|
+
if (!text || !this.enabled) {
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1229
|
+
if (!this.hasSupport) {
|
|
1230
|
+
return this.unsupported();
|
|
1231
|
+
}
|
|
1232
|
+
const synthesis = this.synthesis;
|
|
1233
|
+
if (synthesis.speaking) {
|
|
1234
|
+
// console.warn('speak already speaking');
|
|
1235
|
+
this.chunks_.push(text);
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
const utterance = new SpeechSynthesisUtterance(text);
|
|
1239
|
+
utterance.onend = event => {
|
|
1240
|
+
// console.warn('speak onend');
|
|
1241
|
+
if (this.chunks_.length > 0) {
|
|
1242
|
+
const text = this.chunks_.shift();
|
|
1243
|
+
if (text) {
|
|
1244
|
+
this.speak(text);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
utterance.onerror = event => {
|
|
1249
|
+
console.warn('speak onerror', event);
|
|
1250
|
+
};
|
|
1251
|
+
/*
|
|
1252
|
+
utterance.onboundary = (event) => {
|
|
1253
|
+
console.warn('speak onboundary', event);
|
|
1254
|
+
};
|
|
1255
|
+
utterance.onmark = (event) => {
|
|
1256
|
+
console.warn('speak onmark', event);
|
|
1257
|
+
};
|
|
1258
|
+
utterance.onpause = (event) => {
|
|
1259
|
+
console.warn('speak onpause', event);
|
|
1260
|
+
};
|
|
1261
|
+
utterance.onresume = (event) => {
|
|
1262
|
+
console.warn('speak onresume', event);
|
|
1263
|
+
};
|
|
1264
|
+
*/
|
|
1265
|
+
const voice = this.voice;
|
|
1266
|
+
if (voice) {
|
|
1267
|
+
const pitch = this.pitch;
|
|
1268
|
+
const rate = this.rate;
|
|
1269
|
+
const volume = this.volume;
|
|
1270
|
+
utterance.voice = voice;
|
|
1271
|
+
utterance.pitch = pitch;
|
|
1272
|
+
utterance.rate = rate;
|
|
1273
|
+
utterance.volume = volume;
|
|
1274
|
+
// console.log('Speech.speak', `chars(${text.length})`, voice.name, voice.lang, pitch, rate, volume);
|
|
1275
|
+
synthesis.speak(utterance);
|
|
1276
|
+
} else {
|
|
1277
|
+
console.warn('speak', 'no available voice found');
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
setEnabled(enabled) {
|
|
1281
|
+
this.enabled = enabled;
|
|
1282
|
+
if (!enabled) {
|
|
1283
|
+
const synthesis = this.synthesis;
|
|
1284
|
+
if (synthesis.speaking) {
|
|
1285
|
+
synthesis.cancel();
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
recognizeStart() {
|
|
1290
|
+
if (!this.hasSupport) {
|
|
1291
|
+
return this.unsupported();
|
|
1292
|
+
}
|
|
1293
|
+
const recognizer = this.recognizer;
|
|
1294
|
+
recognizer.lang = this.lang; // "en-US";
|
|
1295
|
+
recognizer.start();
|
|
1296
|
+
}
|
|
1297
|
+
recognizeStop() {
|
|
1298
|
+
if (!this.hasSupport) {
|
|
1299
|
+
return this.unsupported();
|
|
1300
|
+
}
|
|
1301
|
+
const recognizer = this.recognizer;
|
|
1302
|
+
recognizer.stop();
|
|
1303
|
+
}
|
|
1304
|
+
onResult(event) {
|
|
1305
|
+
const results = event.results;
|
|
1306
|
+
const result = results[event.resultIndex];
|
|
1307
|
+
const alternatives = Array.from(result);
|
|
1308
|
+
const alternative = alternatives.reduce((p, c) => {
|
|
1309
|
+
return p ? c.confidence > p.confidence ? c : p : c;
|
|
1310
|
+
}, undefined);
|
|
1311
|
+
const transcript = alternative ? alternative.transcript : '';
|
|
1312
|
+
this.emit('result', transcript);
|
|
1313
|
+
}
|
|
1314
|
+
unsupported() {
|
|
1315
|
+
if (bomCore.isBrowser) {
|
|
1316
|
+
this.log('Speech Synthesis not supported on this device');
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
get synthesis() {
|
|
1320
|
+
return window.speechSynthesis || window.webkitSpeechSynthesis;
|
|
1321
|
+
}
|
|
1322
|
+
get recognition() {
|
|
1323
|
+
return window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
1324
|
+
}
|
|
1325
|
+
get grammarList() {
|
|
1326
|
+
return window.SpeechGrammarList || window.webkitSpeechGrammarList;
|
|
1327
|
+
}
|
|
1328
|
+
getReader(wordCount) {
|
|
1329
|
+
if (wordCount === void 0) {
|
|
1330
|
+
wordCount = 6;
|
|
1331
|
+
}
|
|
1332
|
+
const reader = this.reader_ || new SpeechReader(this, wordCount);
|
|
1333
|
+
this.reader_ = reader;
|
|
1334
|
+
return reader;
|
|
1335
|
+
}
|
|
1336
|
+
get recognizer() {
|
|
1337
|
+
if (this.recognizer_) {
|
|
1338
|
+
return this.recognizer_;
|
|
1339
|
+
} else {
|
|
1340
|
+
const recognizer = new this.recognition();
|
|
1341
|
+
/*
|
|
1342
|
+
const grammar =
|
|
1343
|
+
"#JSGF V1.0; grammar colors; public <color> = aqua | azure | beige | bisque | black | blue | brown | chocolate | coral | crimson | cyan | fuchsia | ghostwhite | gold | goldenrod | gray | green | indigo | ivory | khaki | lavender | lime | linen | magenta | maroon | moccasin | navy | olive | orange | orchid | peru | pink | plum | purple | red | salmon | sienna | silver | snow | tan | teal | thistle | tomato | turquoise | violet | white | yellow ;";
|
|
1344
|
+
const grammarList = new this.grammarList();
|
|
1345
|
+
grammarList.addFromString(grammar, 1);
|
|
1346
|
+
recognizer.grammars = grammarList;
|
|
1347
|
+
*/
|
|
1348
|
+
recognizer.lang = this.lang; // "en-US";
|
|
1349
|
+
recognizer.continuous = true;
|
|
1350
|
+
recognizer.interimResults = false;
|
|
1351
|
+
recognizer.maxAlternatives = 1;
|
|
1352
|
+
recognizer.addEventListener('result', event => {
|
|
1353
|
+
// console.log(event);
|
|
1354
|
+
this.onResult(event);
|
|
1355
|
+
});
|
|
1356
|
+
/*
|
|
1357
|
+
recognizer.addEventListener("audioend", (event) => {
|
|
1358
|
+
this.log('recognizer', "audioend", event);
|
|
1359
|
+
});
|
|
1360
|
+
recognizer.addEventListener("speechend", (event) => {
|
|
1361
|
+
this.log('recognizer', "speechend", event);
|
|
1362
|
+
});
|
|
1363
|
+
*/
|
|
1364
|
+
/*
|
|
1365
|
+
audiostart
|
|
1366
|
+
Fired when the user agent has started to capture audio. Also available via the onaudiostart property.
|
|
1367
|
+
audioend
|
|
1368
|
+
Fired when the user agent has finished capturing audio. Also available via the onaudioend property.
|
|
1369
|
+
end
|
|
1370
|
+
Fired when the speech recognition service has disconnected. Also available via the onend property.
|
|
1371
|
+
error
|
|
1372
|
+
Fired when a speech recognition error occurs. Also available via the onerror property.
|
|
1373
|
+
nomatch
|
|
1374
|
+
Fired when the speech recognition service returns a final result with no significant recognition. This may involve some degree of recognition, which doesn't meet or exceed the confidence threshold. Also available via the onnomatch property.
|
|
1375
|
+
result
|
|
1376
|
+
Fired when the speech recognition service returns a result — a word or phrase has been positively recognized and this has been communicated back to the app. Also available via the onresult property.
|
|
1377
|
+
soundstart
|
|
1378
|
+
Fired when any sound — recognizable speech or not — has been detected. Also available via the onsoundstart property.
|
|
1379
|
+
soundend
|
|
1380
|
+
Fired when any sound — recognizable speech or not — has stopped being detected. Also available via the onsoundend property.
|
|
1381
|
+
speechstart
|
|
1382
|
+
Fired when sound that is recognized by the speech recognition service as speech has been detected. Also available via the onspeechstart property.
|
|
1383
|
+
speechend
|
|
1384
|
+
Fired when speech recognized by the speech recognition service has stopped being detected. Also available via the onspeechend property.
|
|
1385
|
+
start
|
|
1386
|
+
Fired when the speech recognition service has begun listening to incoming audio with intent to recognize grammars associated with the current SpeechRecognition. Also available via the onstart property.
|
|
1387
|
+
*/
|
|
1388
|
+
this.recognizer_ = recognizer;
|
|
1389
|
+
return recognizer;
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
get recognitionEvent() {
|
|
1393
|
+
return window.SpeechRecognitionEvent || window.webkitSpeechRecognitionEvent;
|
|
1394
|
+
}
|
|
1395
|
+
get hasSupport() {
|
|
1396
|
+
return bomCore.isBrowser && this.synthesis != null;
|
|
1397
|
+
}
|
|
1398
|
+
get voices() {
|
|
1399
|
+
if (!this.hasSupport) {
|
|
1400
|
+
return [];
|
|
1401
|
+
} else {
|
|
1402
|
+
const synthesis = this.synthesis;
|
|
1403
|
+
const voices = synthesis.getVoices().sort((a, b) => {
|
|
1404
|
+
const aname = a.name.toUpperCase();
|
|
1405
|
+
const bname = b.name.toUpperCase();
|
|
1406
|
+
if (aname < bname) {
|
|
1407
|
+
return -1;
|
|
1408
|
+
} else if (aname == bname) {
|
|
1409
|
+
return 0;
|
|
1410
|
+
} else {
|
|
1411
|
+
return +1;
|
|
1412
|
+
}
|
|
1413
|
+
});
|
|
1414
|
+
return voices;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
get voice() {
|
|
1418
|
+
const voices = this.voices;
|
|
1419
|
+
let voice = voices.find(x => x.lang.toLowerCase().indexOf(this.lang) === 0 && x.name.toLowerCase().indexOf('natural') === -1);
|
|
1420
|
+
if (!voice && voices.length > 0) {
|
|
1421
|
+
voice = voices.find(x => x.lang.toLowerCase().indexOf('en') === 0 && x.name.toLowerCase().indexOf('natural') === -1);
|
|
1422
|
+
}
|
|
1423
|
+
return voice;
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
class SpeechReader {
|
|
1427
|
+
constructor(speech, wordCount) {
|
|
1428
|
+
this.chunks = [];
|
|
1429
|
+
this.speech = speech;
|
|
1430
|
+
}
|
|
1431
|
+
add(chunk) {
|
|
1432
|
+
if (!this.speech.enabled) {
|
|
1433
|
+
return;
|
|
1434
|
+
}
|
|
1435
|
+
chunk = stripEmojis(chunk);
|
|
1436
|
+
chunk = chunk.replace(/[#*\-=_>]|(\[.+?\]\(.+?\))|(\d\.)/g, '');
|
|
1437
|
+
// console.log('SpeechReader.add', `{${chunk}}`, chunk.match(/[,|:|.|?|!](\s*)$/));
|
|
1438
|
+
const chunks = this.chunks;
|
|
1439
|
+
const splittedChunks = chunk.split(/[,|:|.|?|!]/);
|
|
1440
|
+
if (splittedChunks.length > 1) {
|
|
1441
|
+
const first = splittedChunks.shift();
|
|
1442
|
+
if (first) {
|
|
1443
|
+
chunks.push(first);
|
|
1444
|
+
this.speak();
|
|
1445
|
+
}
|
|
1446
|
+
splittedChunks.forEach(x => this.add(x));
|
|
1447
|
+
} else {
|
|
1448
|
+
chunks.push(...splittedChunks);
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
end() {
|
|
1452
|
+
const chunks = this.chunks;
|
|
1453
|
+
if (chunks.length > 0) {
|
|
1454
|
+
this.speak();
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
speak() {
|
|
1458
|
+
const speech = this.speech;
|
|
1459
|
+
const chunks = this.chunks;
|
|
1460
|
+
// const text = chunks.join(' ').replace(/\s\s/g, ' ');
|
|
1461
|
+
let text = chunks.join('');
|
|
1462
|
+
// text = text.replace('\n', '');
|
|
1463
|
+
text = text.replace(/(\s+)/g, ' ');
|
|
1464
|
+
// text = text.replace(/\s$/g, '');
|
|
1465
|
+
if (text) {
|
|
1466
|
+
// console.log('SpeechReader.speak', [text]);
|
|
1467
|
+
this.chunks = [];
|
|
1468
|
+
speech.speak(text);
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
function stripEmojis(text) {
|
|
1473
|
+
return text.replace(/(\s?)([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g, '');
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
const createLlmStore = _ref => {
|
|
1477
|
+
let {
|
|
1478
|
+
appKey,
|
|
1479
|
+
apiKey,
|
|
1480
|
+
threadId,
|
|
1481
|
+
opened,
|
|
1482
|
+
decorateUrl,
|
|
1483
|
+
endpoint,
|
|
1484
|
+
test,
|
|
1485
|
+
storage,
|
|
1486
|
+
label
|
|
1487
|
+
} = _ref;
|
|
1488
|
+
const props = {
|
|
1489
|
+
hydrated: false,
|
|
1490
|
+
messages: [],
|
|
1491
|
+
prompt: '',
|
|
1492
|
+
locale: 'en',
|
|
1493
|
+
streaming: false,
|
|
1494
|
+
opened: opened != null ? opened : threadId != null ? true : false,
|
|
1495
|
+
hidden: false,
|
|
1496
|
+
fixed: false,
|
|
1497
|
+
idle: true,
|
|
1498
|
+
direction: 0,
|
|
1499
|
+
speakEnabled: false
|
|
1500
|
+
};
|
|
1501
|
+
let messageService = undefined;
|
|
1502
|
+
const speech = new Speech();
|
|
1503
|
+
let lenis_ = undefined;
|
|
1504
|
+
let autoScroll = true;
|
|
1505
|
+
const scrollToBottom = () => {
|
|
1506
|
+
if (lenis_ && autoScroll) {
|
|
1507
|
+
lenis_.scrollTo('bottom', {
|
|
1508
|
+
immediate: true
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1511
|
+
};
|
|
1512
|
+
function getApi(options) {
|
|
1513
|
+
const origin = endpoint || (bomCore.isBrowser ? window.location.origin : process.env.STORE_URL);
|
|
1514
|
+
const baseUrl = `${origin}/api/llm`;
|
|
1515
|
+
return {
|
|
1516
|
+
get: pathname => __awaiter(this, void 0, void 0, function* () {
|
|
1517
|
+
const url = `${baseUrl}${pathname}${pathname.indexOf('?') !== -1 ? '&' : '?'}locale=${options.locale}`;
|
|
1518
|
+
try {
|
|
1519
|
+
const response = yield fetch(url, {
|
|
1520
|
+
method: 'GET',
|
|
1521
|
+
headers: {
|
|
1522
|
+
'Content-Type': 'application/json'
|
|
1523
|
+
}
|
|
1524
|
+
});
|
|
1525
|
+
if (response.ok) {
|
|
1526
|
+
const data = yield response.json();
|
|
1527
|
+
return data;
|
|
1528
|
+
} else {
|
|
1529
|
+
console.error('useLlm.api.get', url, response);
|
|
1530
|
+
return undefined;
|
|
1531
|
+
}
|
|
1532
|
+
} catch (error) {
|
|
1533
|
+
console.error('useLlm.api.get', url, error);
|
|
1534
|
+
return undefined;
|
|
1535
|
+
}
|
|
1536
|
+
}),
|
|
1537
|
+
post: (pathname, payload) => __awaiter(this, void 0, void 0, function* () {
|
|
1538
|
+
const url = `${baseUrl}${pathname}${pathname.indexOf('?') !== -1 ? '&' : '?'}locale=${options.locale}`;
|
|
1539
|
+
try {
|
|
1540
|
+
const response = yield fetch(url, {
|
|
1541
|
+
method: 'POST',
|
|
1542
|
+
body: JSON.stringify(Object.assign(Object.assign({}, options), payload)),
|
|
1543
|
+
headers: {
|
|
1544
|
+
'Content-Type': 'application/json'
|
|
1545
|
+
}
|
|
1546
|
+
});
|
|
1547
|
+
if (response.ok) {
|
|
1548
|
+
const data = yield response.json();
|
|
1549
|
+
return data;
|
|
1550
|
+
} else {
|
|
1551
|
+
console.error('useLlm.api.post', response, url);
|
|
1552
|
+
return undefined;
|
|
1553
|
+
}
|
|
1554
|
+
} catch (error) {
|
|
1555
|
+
console.error('useLlm.api.post', error, url);
|
|
1556
|
+
return undefined;
|
|
1557
|
+
}
|
|
1558
|
+
})
|
|
1559
|
+
};
|
|
1560
|
+
}
|
|
1561
|
+
const useStore = zustand.createStore()(middleware.persist((set, get) => Object.assign(Object.assign({}, props), {
|
|
1562
|
+
actions: {
|
|
1563
|
+
getApi: () => {
|
|
1564
|
+
const state = get();
|
|
1565
|
+
const {
|
|
1566
|
+
locale,
|
|
1567
|
+
threadId
|
|
1568
|
+
} = state;
|
|
1569
|
+
return getApi({
|
|
1570
|
+
locale,
|
|
1571
|
+
appKey,
|
|
1572
|
+
apiKey,
|
|
1573
|
+
threadId
|
|
1574
|
+
});
|
|
1575
|
+
},
|
|
1576
|
+
init: locale => __awaiter(void 0, void 0, void 0, function* () {
|
|
1577
|
+
const fetchApp = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1578
|
+
const api = getApi({
|
|
1579
|
+
locale,
|
|
1580
|
+
appKey,
|
|
1581
|
+
apiKey,
|
|
1582
|
+
threadId
|
|
1583
|
+
});
|
|
1584
|
+
const app = yield api.post('/info');
|
|
1585
|
+
return app;
|
|
1586
|
+
});
|
|
1587
|
+
const app = yield fetchApp();
|
|
1588
|
+
if (!app) {
|
|
1589
|
+
return;
|
|
1590
|
+
}
|
|
1591
|
+
const state = get();
|
|
1592
|
+
speech.lang = locale;
|
|
1593
|
+
speech.enabled = state.speakEnabled;
|
|
1594
|
+
speech.on('result', transcript => {
|
|
1595
|
+
state.actions.setPrompt(transcript);
|
|
1596
|
+
});
|
|
1597
|
+
const decodeThread = thread => {
|
|
1598
|
+
return thread ? {
|
|
1599
|
+
messages: decodeMessages(thread.messages),
|
|
1600
|
+
threadId: thread.threadId
|
|
1601
|
+
} : undefined;
|
|
1602
|
+
};
|
|
1603
|
+
const thread = decodeThread(app.thread);
|
|
1604
|
+
// console.log('thread', thread);
|
|
1605
|
+
set(() => Object.assign({
|
|
1606
|
+
app,
|
|
1607
|
+
locale
|
|
1608
|
+
}, thread));
|
|
1609
|
+
// handle idle times
|
|
1610
|
+
const setIdleTimeout = () => {
|
|
1611
|
+
return setTimeout(() => {
|
|
1612
|
+
set(() => ({
|
|
1613
|
+
idle: true
|
|
1614
|
+
}));
|
|
1615
|
+
}, 6000);
|
|
1616
|
+
};
|
|
1617
|
+
const handleIdleTimes = () => {
|
|
1618
|
+
let to = setIdleTimeout();
|
|
1619
|
+
let lastScrollTop = 0;
|
|
1620
|
+
window.addEventListener('scroll', () => {
|
|
1621
|
+
const st = window.scrollY || document.documentElement.scrollTop;
|
|
1622
|
+
let direction = 0;
|
|
1623
|
+
if (st > lastScrollTop) {
|
|
1624
|
+
direction = 1;
|
|
1625
|
+
} else if (st < lastScrollTop) {
|
|
1626
|
+
direction = -1;
|
|
1627
|
+
}
|
|
1628
|
+
lastScrollTop = st <= 0 ? 0 : st;
|
|
1629
|
+
if (direction === 1) {
|
|
1630
|
+
if (to) {
|
|
1631
|
+
clearTimeout(to);
|
|
1632
|
+
}
|
|
1633
|
+
set(() => ({
|
|
1634
|
+
idle: false
|
|
1635
|
+
}));
|
|
1636
|
+
to = setIdleTimeout();
|
|
1637
|
+
}
|
|
1638
|
+
});
|
|
1639
|
+
};
|
|
1640
|
+
setTimeout(() => {
|
|
1641
|
+
set(() => ({
|
|
1642
|
+
idle: false
|
|
1643
|
+
}));
|
|
1644
|
+
handleIdleTimes();
|
|
1645
|
+
}, 2000);
|
|
1646
|
+
}),
|
|
1647
|
+
send: (prompt, onChunk, onEnd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1648
|
+
if (test) {
|
|
1649
|
+
const {
|
|
1650
|
+
locale
|
|
1651
|
+
} = get();
|
|
1652
|
+
prompt = getMockPrompt(get().messages.length, locale) || prompt;
|
|
1653
|
+
}
|
|
1654
|
+
const userMessage = {
|
|
1655
|
+
chunks: [{
|
|
1656
|
+
type: 'string',
|
|
1657
|
+
content: prompt
|
|
1658
|
+
}],
|
|
1659
|
+
content: prompt,
|
|
1660
|
+
role: 'user'
|
|
1661
|
+
};
|
|
1662
|
+
set(state => ({
|
|
1663
|
+
messages: [...state.messages, userMessage],
|
|
1664
|
+
chunks: [],
|
|
1665
|
+
prompt: '',
|
|
1666
|
+
streaming: true
|
|
1667
|
+
}));
|
|
1668
|
+
autoScroll = true;
|
|
1669
|
+
scrollToBottom();
|
|
1670
|
+
const state = get();
|
|
1671
|
+
const origin = endpoint || window.location.origin;
|
|
1672
|
+
const url = `${origin}/api/llm/message?locale=${state.locale}`;
|
|
1673
|
+
messageService = new MessageService({
|
|
1674
|
+
url
|
|
1675
|
+
});
|
|
1676
|
+
const {
|
|
1677
|
+
messages,
|
|
1678
|
+
threadId
|
|
1679
|
+
} = state;
|
|
1680
|
+
const request = {
|
|
1681
|
+
apiKey,
|
|
1682
|
+
appKey,
|
|
1683
|
+
messages: messages.filter(x => {
|
|
1684
|
+
const chunks = x.chunks.filter(x => !['info', 'end', 'formRequest', 'formRecap', 'formRecapSuccess', 'formRecapError'].includes(x.type));
|
|
1685
|
+
return chunks.length > 0;
|
|
1686
|
+
}).map(x => ({
|
|
1687
|
+
role: x.role,
|
|
1688
|
+
content: x.content
|
|
1689
|
+
})),
|
|
1690
|
+
threadId
|
|
1691
|
+
};
|
|
1692
|
+
const speechReader = speech.getReader();
|
|
1693
|
+
yield messageService.sendMessage(request,
|
|
1694
|
+
// onMessage
|
|
1695
|
+
response => {
|
|
1696
|
+
// console.log('messageService.sendMessage.onMessage', response.chunks);
|
|
1697
|
+
set(state => ({
|
|
1698
|
+
chunks: response.chunks
|
|
1699
|
+
}));
|
|
1700
|
+
if (typeof onChunk === 'function') {
|
|
1701
|
+
onChunk(response);
|
|
1702
|
+
}
|
|
1703
|
+
scrollToBottom();
|
|
1704
|
+
},
|
|
1705
|
+
// onEnd
|
|
1706
|
+
response => {
|
|
1707
|
+
// console.log('messageService.sendMessage.onEnd', response.chunks);
|
|
1708
|
+
const chunks = [...response.chunks];
|
|
1709
|
+
const assistantMessage = {
|
|
1710
|
+
chunks,
|
|
1711
|
+
content: '',
|
|
1712
|
+
role: 'assistant'
|
|
1713
|
+
};
|
|
1714
|
+
const messages = [...state.messages, assistantMessage];
|
|
1715
|
+
if (shouldAddFormRequest(messages)) {
|
|
1716
|
+
chunks.push({
|
|
1717
|
+
type: 'formRequest'
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
// filtering history
|
|
1721
|
+
const validChunks = chunks.filter(x => !['info', 'end', 'formRequest', 'formRecap', 'formRecapSuccess', 'formRecapError'].includes(x.type));
|
|
1722
|
+
const parsedChunks = [];
|
|
1723
|
+
validChunks.reduce((p, c) => {
|
|
1724
|
+
const firstChunk = p.length > 1 && p[p.length - 2];
|
|
1725
|
+
const secondChunk = p.length > 1 && p[p.length - 1];
|
|
1726
|
+
if (firstChunk && secondChunk && c.type === 'string' && firstChunk.type === 'string' && secondChunk.type === 'string') {
|
|
1727
|
+
secondChunk.content += c.content;
|
|
1728
|
+
} else {
|
|
1729
|
+
p.push(Object.assign({}, c));
|
|
1730
|
+
}
|
|
1731
|
+
return p;
|
|
1732
|
+
}, parsedChunks);
|
|
1733
|
+
assistantMessage.content = parsedChunks.map(x => JSON.stringify(x)).join(',') + ',';
|
|
1734
|
+
set(state => ({
|
|
1735
|
+
chunks: undefined,
|
|
1736
|
+
messages,
|
|
1737
|
+
threadId: response.threadId,
|
|
1738
|
+
streaming: false
|
|
1739
|
+
}));
|
|
1740
|
+
speechReader.end();
|
|
1741
|
+
if (typeof onEnd === 'function') {
|
|
1742
|
+
onEnd(response);
|
|
1743
|
+
}
|
|
1744
|
+
scrollToBottom();
|
|
1745
|
+
},
|
|
1746
|
+
// onChunk
|
|
1747
|
+
chunks => {
|
|
1748
|
+
// console.log('onChunk', chunks);
|
|
1749
|
+
chunks.forEach(chunk => {
|
|
1750
|
+
if (typeof chunk === 'string') {
|
|
1751
|
+
speechReader.add(chunk);
|
|
1752
|
+
} else if (chunk.type === 'string') {
|
|
1753
|
+
speechReader.add(chunk.content);
|
|
1754
|
+
}
|
|
1755
|
+
});
|
|
1756
|
+
});
|
|
1757
|
+
}),
|
|
1758
|
+
abort: () => {
|
|
1759
|
+
if (messageService) {
|
|
1760
|
+
messageService.abort();
|
|
1761
|
+
messageService = undefined;
|
|
1762
|
+
}
|
|
1763
|
+
},
|
|
1764
|
+
setPrompt: prompt => set(state => ({
|
|
1765
|
+
prompt
|
|
1766
|
+
})),
|
|
1767
|
+
toggleSpeak: () => {
|
|
1768
|
+
set(state => {
|
|
1769
|
+
const speakEnabled = !state.speakEnabled;
|
|
1770
|
+
speech.setEnabled(speakEnabled);
|
|
1771
|
+
return {
|
|
1772
|
+
speakEnabled
|
|
1773
|
+
};
|
|
1774
|
+
});
|
|
1775
|
+
},
|
|
1776
|
+
recognizeStart: () => {
|
|
1777
|
+
get();
|
|
1778
|
+
speech.recognizeStart();
|
|
1779
|
+
},
|
|
1780
|
+
recognizeStop: () => {
|
|
1781
|
+
get();
|
|
1782
|
+
speech.recognizeStop();
|
|
1783
|
+
},
|
|
1784
|
+
formRequest: choice => {
|
|
1785
|
+
const choiceMessage = choice ? label('llm.formRequestYes') : label('llm.formRequestNo');
|
|
1786
|
+
const userMessage = {
|
|
1787
|
+
chunks: [{
|
|
1788
|
+
type: 'string',
|
|
1789
|
+
content: choiceMessage
|
|
1790
|
+
}],
|
|
1791
|
+
content: choiceMessage,
|
|
1792
|
+
role: 'user'
|
|
1793
|
+
};
|
|
1794
|
+
const messages = [userMessage];
|
|
1795
|
+
if (choice) {
|
|
1796
|
+
const assistantMessage = {
|
|
1797
|
+
chunks: [{
|
|
1798
|
+
type: 'formRecap'
|
|
1799
|
+
}],
|
|
1800
|
+
content: '',
|
|
1801
|
+
role: 'assistant'
|
|
1802
|
+
};
|
|
1803
|
+
messages.push(assistantMessage);
|
|
1804
|
+
}
|
|
1805
|
+
set(state => ({
|
|
1806
|
+
messages: [...state.messages, ...messages]
|
|
1807
|
+
}));
|
|
1808
|
+
},
|
|
1809
|
+
formRecap: error => {
|
|
1810
|
+
if (error) {
|
|
1811
|
+
console.warn('useLlm.formRecap', error);
|
|
1812
|
+
}
|
|
1813
|
+
const messages = [];
|
|
1814
|
+
const assistantMessage = {
|
|
1815
|
+
chunks: [{
|
|
1816
|
+
type: error ? 'formRecapError' : 'formRecapSuccess'
|
|
1817
|
+
}],
|
|
1818
|
+
content: '',
|
|
1819
|
+
role: 'assistant'
|
|
1820
|
+
};
|
|
1821
|
+
messages.push(assistantMessage);
|
|
1822
|
+
set(state => ({
|
|
1823
|
+
messages: [...state.messages, ...messages]
|
|
1824
|
+
}));
|
|
1825
|
+
},
|
|
1826
|
+
decorateUrl: (item, defaultUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1827
|
+
let url;
|
|
1828
|
+
if (typeof decorateUrl === 'function') {
|
|
1829
|
+
url = yield decorateUrl(item);
|
|
1830
|
+
}
|
|
1831
|
+
return url || defaultUrl || '#';
|
|
1832
|
+
}),
|
|
1833
|
+
open: () => set(state => ({
|
|
1834
|
+
opened: !state.opened
|
|
1835
|
+
})),
|
|
1836
|
+
clear: () => set(state => ({
|
|
1837
|
+
messages: []
|
|
1838
|
+
})),
|
|
1839
|
+
setLenis: lenis => {
|
|
1840
|
+
if (lenis_ !== lenis) {
|
|
1841
|
+
lenis_ = lenis;
|
|
1842
|
+
if (lenis) {
|
|
1843
|
+
lenis.on('scroll', event => {
|
|
1844
|
+
const {
|
|
1845
|
+
direction,
|
|
1846
|
+
targetScroll,
|
|
1847
|
+
limit
|
|
1848
|
+
} = event;
|
|
1849
|
+
if (limit === targetScroll) {
|
|
1850
|
+
autoScroll = true;
|
|
1851
|
+
} else if (direction == -1 && Math.abs(limit - targetScroll) > 100) {
|
|
1852
|
+
autoScroll = false;
|
|
1853
|
+
}
|
|
1854
|
+
const scrolled = targetScroll > 100;
|
|
1855
|
+
const fixed = direction == -1 && scrolled && !autoScroll;
|
|
1856
|
+
const hidden = autoScroll || direction == 1 && scrolled;
|
|
1857
|
+
const state = get();
|
|
1858
|
+
if (state.hidden !== hidden || state.fixed !== fixed || state.direction !== direction) {
|
|
1859
|
+
set(state => ({
|
|
1860
|
+
hidden,
|
|
1861
|
+
fixed,
|
|
1862
|
+
direction
|
|
1863
|
+
}));
|
|
1864
|
+
}
|
|
1865
|
+
});
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
}), {
|
|
1871
|
+
name: 'llm',
|
|
1872
|
+
storage: middleware.createJSONStorage(() => storage || localStorage),
|
|
1873
|
+
onRehydrateStorage: () => () => {
|
|
1874
|
+
useStore.setState({
|
|
1875
|
+
hydrated: true
|
|
1876
|
+
});
|
|
1877
|
+
},
|
|
1878
|
+
merge: (persistedState, currentState) => {
|
|
1879
|
+
if (persistedState.app) {
|
|
1880
|
+
currentState.app = Object.assign({}, persistedState.app);
|
|
1881
|
+
}
|
|
1882
|
+
currentState.speakEnabled = persistedState.speakEnabled || false;
|
|
1883
|
+
speech.enabled = currentState.speakEnabled;
|
|
1884
|
+
/*
|
|
1885
|
+
if (persistedState.messages) {
|
|
1886
|
+
currentState.messages = [...persistedState.messages];
|
|
1887
|
+
}
|
|
1888
|
+
*/
|
|
1889
|
+
currentState.hydrated = true;
|
|
1890
|
+
return currentState;
|
|
1891
|
+
},
|
|
1892
|
+
partialize: state => Object.fromEntries(Object.entries(state).filter(_ref2 => {
|
|
1893
|
+
let [key] = _ref2;
|
|
1894
|
+
return ['app', 'locale', 'speakEnabled'].includes(key);
|
|
1895
|
+
}))
|
|
1896
|
+
}));
|
|
1897
|
+
return useStore;
|
|
1898
|
+
};
|
|
1899
|
+
const LlmContext = /*#__PURE__*/react.createContext(null);
|
|
1900
|
+
function LlmProvider(_a) {
|
|
1901
|
+
var {
|
|
1902
|
+
children
|
|
1903
|
+
} = _a,
|
|
1904
|
+
props = __rest(_a, ["children"]);
|
|
1905
|
+
const label = bomMixerHooks.useLabel();
|
|
1906
|
+
const storeRef = react.useRef();
|
|
1907
|
+
if (!storeRef.current) {
|
|
1908
|
+
storeRef.current = createLlmStore(Object.assign(Object.assign({}, props), {
|
|
1909
|
+
label
|
|
1910
|
+
}));
|
|
1911
|
+
}
|
|
1912
|
+
return storeRef.current && jsxRuntime.jsx(LlmContext.Provider, {
|
|
1913
|
+
value: storeRef.current,
|
|
1914
|
+
children: children
|
|
1915
|
+
});
|
|
1916
|
+
}
|
|
1917
|
+
function useLlm(selector) {
|
|
1918
|
+
const store = react.useContext(LlmContext);
|
|
1919
|
+
if (!store) throw new Error('Missing LlmContext.Provider in the tree');
|
|
1920
|
+
return zustand.useStore(store, selector);
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
const vertex = `attribute vec2 aPosition;
|
|
1924
|
+
attribute vec2 aTexCoord;
|
|
1925
|
+
varying vec2 vUv;
|
|
1926
|
+
|
|
1927
|
+
void main(void){
|
|
1928
|
+
gl_Position = vec4(aPosition, 0.0, 1.0);
|
|
1929
|
+
vUv = aTexCoord;
|
|
1930
|
+
}
|
|
1931
|
+
`;
|
|
1932
|
+
const fragment = `
|
|
1933
|
+
#ifdef GL_ES
|
|
1934
|
+
precision mediump float;
|
|
1935
|
+
#endif
|
|
1936
|
+
|
|
1937
|
+
varying vec2 vUv;
|
|
1938
|
+
|
|
1939
|
+
uniform int uColor1;
|
|
1940
|
+
uniform int uColor2;
|
|
1941
|
+
uniform int uColor3;
|
|
1942
|
+
uniform int uColor4;
|
|
1943
|
+
uniform float uBlobSize;
|
|
1944
|
+
uniform float uCellSize;
|
|
1945
|
+
uniform float uNoiseSize;
|
|
1946
|
+
uniform float uOpacity;
|
|
1947
|
+
uniform float uTime;
|
|
1948
|
+
|
|
1949
|
+
vec2 random2(vec2 st) {
|
|
1950
|
+
st = vec2(dot(st, vec2(127.1, 311.7)), dot(st, vec2(269.5, 183.3)));
|
|
1951
|
+
return - 1.0 + 2.0 * fract(sin(st) * 43758.5453123);
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
float noise(vec2 st) {
|
|
1955
|
+
vec2 i = floor(st);
|
|
1956
|
+
vec2 f = fract(st);
|
|
1957
|
+
vec2 u = f * f * (3.0 - 2.0 * f);
|
|
1958
|
+
return mix(mix(dot(random2(i + vec2(0.0, 0.0)), f - vec2(0.0, 0.0)),
|
|
1959
|
+
dot(random2(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0)), u.x),
|
|
1960
|
+
mix(dot(random2(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0)),
|
|
1961
|
+
dot(random2(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0)), u.x), u.y) * 0.5 + 0.5;
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
float gaussFunction(vec2 st, vec2 p, float r) {
|
|
1965
|
+
return exp(-dot(st - p, st - p) / 2.0 / r / r);
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
vec3 hash32(vec2 p) {
|
|
1969
|
+
vec3 p3 = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973));
|
|
1970
|
+
p3 += dot(p3, p3.yxz + 33.33);
|
|
1971
|
+
return fract((p3.xxy + p3.yzz) * p3.zyx);
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
vec3 blob(vec2 p) {
|
|
1975
|
+
vec2 i = floor(p / uCellSize);
|
|
1976
|
+
vec3 c = vec3(0.0);
|
|
1977
|
+
for(int x = -1; x <= 1; x ++ )
|
|
1978
|
+
for(int y = -1; y <= 1; y ++ ) {
|
|
1979
|
+
vec2 v = i + vec2(x, y);
|
|
1980
|
+
vec3 h = hash32(v);
|
|
1981
|
+
float g = gaussFunction(p / uCellSize, v + h.xy, uBlobSize);
|
|
1982
|
+
float n = smoothstep(0.0, 1.0, noise(uNoiseSize * p / uCellSize / uBlobSize));
|
|
1983
|
+
c += uOpacity * g * n;
|
|
1984
|
+
}
|
|
1985
|
+
return c;
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
float random(vec2 st) {
|
|
1989
|
+
return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
vec3 intToColor(int color) {
|
|
1993
|
+
float r = float(color / 256 / 256);
|
|
1994
|
+
float g = float(color / 256 - int(r * 256.0));
|
|
1995
|
+
float b = float(color - int(r * 256.0 * 256.0) - int(g * 256.0));
|
|
1996
|
+
return vec3(r / 255.0, g / 255.0, b / 255.0);
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
void main(void) {
|
|
2000
|
+
vec2 st = vUv;
|
|
2001
|
+
|
|
2002
|
+
vec2 p1 = st + vec2(cos(uTime * 0.1), sin(uTime * 0.1));
|
|
2003
|
+
vec3 b1 = blob(p1);
|
|
2004
|
+
|
|
2005
|
+
vec2 p2 = st + 3.43 + vec2(sin(uTime * 0.2), cos(uTime * 0.2));
|
|
2006
|
+
vec3 b2 = blob(p2);
|
|
2007
|
+
|
|
2008
|
+
vec2 p3 = st + 5.43 + vec2(cos(uTime * 0.2), cos(uTime * 0.2));
|
|
2009
|
+
vec3 b3 = blob(p3);
|
|
2010
|
+
|
|
2011
|
+
vec3 mask = (1.0 - b1 - b2 - b3);
|
|
2012
|
+
|
|
2013
|
+
vec3 c1 = intToColor(uColor1);
|
|
2014
|
+
vec3 c2 = intToColor(uColor2);
|
|
2015
|
+
vec3 c3 = intToColor(uColor3);
|
|
2016
|
+
vec3 c4 = intToColor(uColor4);
|
|
2017
|
+
|
|
2018
|
+
vec3 color = mask * c1;
|
|
2019
|
+
|
|
2020
|
+
color += b1 * c2;
|
|
2021
|
+
|
|
2022
|
+
color += b2 * c3;
|
|
2023
|
+
|
|
2024
|
+
color += b3 * c4;
|
|
2025
|
+
|
|
2026
|
+
vec2 n = random2(st) * 0.05;
|
|
2027
|
+
color += n.x - n.y;
|
|
2028
|
+
|
|
2029
|
+
gl_FragColor = vec4(color, 1.0);
|
|
2030
|
+
}
|
|
2031
|
+
`;
|
|
2032
|
+
const shader = {
|
|
2033
|
+
vertex,
|
|
2034
|
+
fragment
|
|
2035
|
+
};
|
|
2036
|
+
const initWebGl = (canvas, _ref) => {
|
|
2037
|
+
let {
|
|
2038
|
+
color1 = '#003c8c',
|
|
2039
|
+
color2 = '#73c3ff',
|
|
2040
|
+
color3 = '#96dca0',
|
|
2041
|
+
color4 = '#dcdc3c',
|
|
2042
|
+
blobSize = 0.3,
|
|
2043
|
+
cellSize = 0.6,
|
|
2044
|
+
noiseSize = 0.3,
|
|
2045
|
+
opacity = 0.5
|
|
2046
|
+
} = _ref;
|
|
2047
|
+
const gl = canvas.getContext('webgl');
|
|
2048
|
+
if (!gl) {
|
|
2049
|
+
throw 'cannot initialize gl';
|
|
2050
|
+
}
|
|
2051
|
+
const pixelRatio = window.devicePixelRatio;
|
|
2052
|
+
const size = {
|
|
2053
|
+
width: 1,
|
|
2054
|
+
height: 1
|
|
2055
|
+
};
|
|
2056
|
+
const shouldRenderSingleFrame = isApple();
|
|
2057
|
+
let canRender = true;
|
|
2058
|
+
let isDirty = true;
|
|
2059
|
+
let rafID = null;
|
|
2060
|
+
const onResize = _ref2 => {
|
|
2061
|
+
let [entry] = _ref2;
|
|
2062
|
+
const canvasWidth = entry.contentRect.width;
|
|
2063
|
+
const canvasHeight = entry.contentRect.height;
|
|
2064
|
+
canvas.width = Math.round(canvasWidth * pixelRatio);
|
|
2065
|
+
canvas.height = Math.round(canvasHeight * pixelRatio);
|
|
2066
|
+
size.width = gl.drawingBufferWidth;
|
|
2067
|
+
size.height = gl.drawingBufferHeight;
|
|
2068
|
+
isDirty = true;
|
|
2069
|
+
};
|
|
2070
|
+
const resizeObserver = new ResizeObserver(onResize);
|
|
2071
|
+
resizeObserver.observe(canvas);
|
|
2072
|
+
const quadData = new Float32Array([-1, 3, 0, 2, -1, -1, 0, 0, 3, -1, 2, 0]);
|
|
2073
|
+
const quad = new ArrayBuffer__default.default(gl, quadData);
|
|
2074
|
+
quad.attrib('aPosition', 2, gl.FLOAT);
|
|
2075
|
+
quad.attrib('aTexCoord', 2, gl.FLOAT);
|
|
2076
|
+
const program = new Program__default.default(gl, shader.vertex, shader.fragment);
|
|
2077
|
+
const render = function (time) {
|
|
2078
|
+
if (time === void 0) {
|
|
2079
|
+
time = 0;
|
|
2080
|
+
}
|
|
2081
|
+
if (!canRender) {
|
|
2082
|
+
return;
|
|
2083
|
+
}
|
|
2084
|
+
if (!isDirty) {
|
|
2085
|
+
rafID = window.requestAnimationFrame(render);
|
|
2086
|
+
return;
|
|
2087
|
+
}
|
|
2088
|
+
gl.viewport(0, 0, size.width, size.height);
|
|
2089
|
+
gl.clearColor(0, 0, 0, 0);
|
|
2090
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
2091
|
+
program.use();
|
|
2092
|
+
if (time === 0) {
|
|
2093
|
+
program.uColor1(parseInt(color1.replace('#', ''), 16));
|
|
2094
|
+
program.uColor2(parseInt(color2.replace('#', ''), 16));
|
|
2095
|
+
program.uColor3(parseInt(color3.replace('#', ''), 16));
|
|
2096
|
+
program.uColor4(parseInt(color4.replace('#', ''), 16));
|
|
2097
|
+
program.uBlobSize(blobSize);
|
|
2098
|
+
program.uCellSize(cellSize);
|
|
2099
|
+
program.uNoiseSize(noiseSize);
|
|
2100
|
+
program.uOpacity(opacity);
|
|
2101
|
+
}
|
|
2102
|
+
program.uTime(time * 0.001);
|
|
2103
|
+
quad.attribPointer(program);
|
|
2104
|
+
quad.drawTriangles();
|
|
2105
|
+
isDirty = !shouldRenderSingleFrame;
|
|
2106
|
+
rafID = window.requestAnimationFrame(render);
|
|
2107
|
+
};
|
|
2108
|
+
setTimeout(render, 0);
|
|
2109
|
+
const dispose = () => {
|
|
2110
|
+
canRender = false;
|
|
2111
|
+
if (rafID) {
|
|
2112
|
+
window.cancelAnimationFrame(rafID);
|
|
2113
|
+
}
|
|
2114
|
+
resizeObserver.disconnect();
|
|
2115
|
+
program.dispose();
|
|
2116
|
+
};
|
|
2117
|
+
return dispose;
|
|
2118
|
+
};
|
|
2119
|
+
function Canvas() {
|
|
2120
|
+
const ref = react.useRef(null);
|
|
2121
|
+
react.useEffect(() => {
|
|
2122
|
+
if (bomCore.isBrowser && ref.current) {
|
|
2123
|
+
const dispose = initWebGl(ref.current, {});
|
|
2124
|
+
return () => dispose();
|
|
2125
|
+
} else {
|
|
2126
|
+
return undefined;
|
|
2127
|
+
}
|
|
2128
|
+
}, []);
|
|
2129
|
+
return jsxRuntime.jsx("canvas", {
|
|
2130
|
+
className: "llm__canvas",
|
|
2131
|
+
ref: ref
|
|
2132
|
+
});
|
|
2133
|
+
}
|
|
2134
|
+
function isApple() {
|
|
2135
|
+
return ['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(navigator.platform) || navigator.platform.indexOf('Mac') === 0 || navigator.userAgent.includes('Mac');
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
const Header = props => {
|
|
2139
|
+
var _a;
|
|
2140
|
+
const app = useLlm(state => state.app);
|
|
2141
|
+
const {
|
|
2142
|
+
open
|
|
2143
|
+
} = useLlm(state => state.actions);
|
|
2144
|
+
const hidden = useLlm(state => state.hidden);
|
|
2145
|
+
const fixed = useLlm(state => state.fixed);
|
|
2146
|
+
const label = bomMixerHooks.useLabel();
|
|
2147
|
+
const logo = app === null || app === void 0 ? void 0 : app.contents.logo;
|
|
2148
|
+
const logoMini = (_a = app === null || app === void 0 ? void 0 : app.contents) === null || _a === void 0 ? void 0 : _a.logoMini;
|
|
2149
|
+
const classes = bomCore.getClassNames('llm__header', {
|
|
2150
|
+
hidden,
|
|
2151
|
+
fixed
|
|
2152
|
+
});
|
|
2153
|
+
return jsxRuntime.jsx("div", {
|
|
2154
|
+
className: classes,
|
|
2155
|
+
children: jsxRuntime.jsxs("div", {
|
|
2156
|
+
className: "llm__header-wrapper",
|
|
2157
|
+
children: [jsxRuntime.jsxs("div", {
|
|
2158
|
+
className: "llm__header-logo",
|
|
2159
|
+
children: [logo && jsxRuntime.jsx("div", {
|
|
2160
|
+
className: "llm__header-logo-full",
|
|
2161
|
+
children: jsxRuntime.jsx("img", {
|
|
2162
|
+
src: logo.src || logo.url,
|
|
2163
|
+
alt: logo.alt
|
|
2164
|
+
})
|
|
2165
|
+
}), logoMini && jsxRuntime.jsx("div", {
|
|
2166
|
+
className: "llm__header-logo-mini",
|
|
2167
|
+
children: jsxRuntime.jsx("img", {
|
|
2168
|
+
src: logoMini.src || logoMini.url,
|
|
2169
|
+
alt: logoMini.alt
|
|
2170
|
+
})
|
|
2171
|
+
})]
|
|
2172
|
+
}), jsxRuntime.jsxs("button", {
|
|
2173
|
+
className: "llm__header-back -llm-t-cta-3",
|
|
2174
|
+
onClick: () => open(),
|
|
2175
|
+
children: [label('llm.back'), jsxRuntime.jsx(bomMixerIcons.IconLlmArrowCornerRightUp, {})]
|
|
2176
|
+
})]
|
|
2177
|
+
})
|
|
2178
|
+
});
|
|
2179
|
+
};
|
|
2180
|
+
|
|
2181
|
+
const Nl2Br = props => {
|
|
2182
|
+
var _a;
|
|
2183
|
+
const lines = (_a = props.text) === null || _a === void 0 ? void 0 : _a.split('\\n').map(function (line, n) {
|
|
2184
|
+
return n == 0 ? [line] : [jsxRuntime.jsx("br", {}, n), line];
|
|
2185
|
+
});
|
|
2186
|
+
return jsxRuntime.jsx("span", {
|
|
2187
|
+
children: lines
|
|
2188
|
+
});
|
|
2189
|
+
};
|
|
2190
|
+
const clamp = (min, max) => Math.min(Math.max(min + (window.innerWidth - 375) / (1920 - 375) * (max - min), min), max);
|
|
2191
|
+
|
|
2192
|
+
const QuickLinks = () => {
|
|
2193
|
+
const {
|
|
2194
|
+
width
|
|
2195
|
+
} = bomMixerHooks.useWindowSize();
|
|
2196
|
+
const {
|
|
2197
|
+
send
|
|
2198
|
+
} = useLlm(state => state.actions);
|
|
2199
|
+
const app = useLlm(state => state.app);
|
|
2200
|
+
const swiperProps = {
|
|
2201
|
+
spaceBetween: clamp(8, 16),
|
|
2202
|
+
slidesOffsetAfter: clamp(20, 110),
|
|
2203
|
+
slidesOffsetBefore: clamp(20, 110),
|
|
2204
|
+
slidesPerView: clamp(1.2, 2.2)
|
|
2205
|
+
};
|
|
2206
|
+
const onClick = item => __awaiter(void 0, void 0, void 0, function* () {
|
|
2207
|
+
yield send(item.message || item.title, response => {
|
|
2208
|
+
// console.log('QuickLinks.onChunk', response.chunks);
|
|
2209
|
+
}, response => {
|
|
2210
|
+
// console.log('QuickLinks.onEnd', response);
|
|
2211
|
+
});
|
|
2212
|
+
});
|
|
2213
|
+
const getCard = (item, j) => {
|
|
2214
|
+
return jsxRuntime.jsxs("div", {
|
|
2215
|
+
className: "llm__links-card",
|
|
2216
|
+
onClick: () => onClick(item),
|
|
2217
|
+
children: [jsxRuntime.jsxs("div", {
|
|
2218
|
+
className: "llm__links-title -llm-t-label-1",
|
|
2219
|
+
children: [item.icon && jsxRuntime.jsx("i", {
|
|
2220
|
+
children: jsxRuntime.jsx("img", {
|
|
2221
|
+
src: item.icon.src || item.icon.url,
|
|
2222
|
+
alt: item.icon.alt
|
|
2223
|
+
})
|
|
2224
|
+
}), item.title]
|
|
2225
|
+
}), jsxRuntime.jsx("div", {
|
|
2226
|
+
className: "llm__links-body -llm-t-body-3",
|
|
2227
|
+
children: item.body
|
|
2228
|
+
})]
|
|
2229
|
+
}, j);
|
|
2230
|
+
};
|
|
2231
|
+
const getCards = () => {
|
|
2232
|
+
if (width < 768) {
|
|
2233
|
+
return jsxRuntime.jsx(react$1.Swiper, Object.assign({}, swiperProps, {
|
|
2234
|
+
children: app === null || app === void 0 ? void 0 : app.contents.layoutBuilder.map((item, j) => jsxRuntime.jsx(react$1.SwiperSlide, {
|
|
2235
|
+
children: getCard(item, j)
|
|
2236
|
+
}, j))
|
|
2237
|
+
}));
|
|
2238
|
+
} else {
|
|
2239
|
+
return app === null || app === void 0 ? void 0 : app.contents.layoutBuilder.map(getCard);
|
|
2240
|
+
}
|
|
2241
|
+
};
|
|
2242
|
+
return jsxRuntime.jsx("div", {
|
|
2243
|
+
className: "llm__links",
|
|
2244
|
+
children: getCards()
|
|
2245
|
+
});
|
|
2246
|
+
};
|
|
2247
|
+
|
|
2248
|
+
const Blob = () => {
|
|
2249
|
+
return jsxRuntime.jsxs("div", {
|
|
2250
|
+
className: "llm__trigger-blob",
|
|
2251
|
+
children: [jsxRuntime.jsxs("svg", {
|
|
2252
|
+
version: "1.1",
|
|
2253
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2254
|
+
viewBox: "0 0 500 500",
|
|
2255
|
+
width: "100%",
|
|
2256
|
+
id: "blobSvg",
|
|
2257
|
+
filter: "blur(8px)",
|
|
2258
|
+
transform: "rotate(0)",
|
|
2259
|
+
children: [jsxRuntime.jsx("defs", {
|
|
2260
|
+
children: jsxRuntime.jsxs("linearGradient", {
|
|
2261
|
+
id: "gradient3",
|
|
2262
|
+
x1: "0%",
|
|
2263
|
+
y1: "0%",
|
|
2264
|
+
x2: "0%",
|
|
2265
|
+
y2: "100%",
|
|
2266
|
+
children: [jsxRuntime.jsx("stop", {
|
|
2267
|
+
offset: "0%",
|
|
2268
|
+
style: {
|
|
2269
|
+
stopColor: '#dcdc3c'
|
|
2270
|
+
}
|
|
2271
|
+
}), jsxRuntime.jsx("stop", {
|
|
2272
|
+
offset: "100%",
|
|
2273
|
+
style: {
|
|
2274
|
+
stopColor: '#d0c911'
|
|
2275
|
+
}
|
|
2276
|
+
})]
|
|
2277
|
+
})
|
|
2278
|
+
}), jsxRuntime.jsx("path", {
|
|
2279
|
+
id: "blob",
|
|
2280
|
+
fill: "url(#gradient3)",
|
|
2281
|
+
children: jsxRuntime.jsx("animate", {
|
|
2282
|
+
attributeName: "d",
|
|
2283
|
+
dur: "10s",
|
|
2284
|
+
repeatCount: "indefinite",
|
|
2285
|
+
values: "M453.70516,317.0107Q433.36186,384.02139,362.52423,381.146Q291.6866,378.27061,242.8433,399.93801Q194,421.60541,117.08118,412.14317Q40.16237,402.68093,64.29201,326.34046Q88.42165,250,109.0107,206.32693Q129.59975,162.65387,148.64317,78.76495Q167.6866,-5.12397,241.8433,20.74072Q316,46.60541,350.8433,99.17023Q385.6866,151.73505,429.86753,200.86753Q474.04846,250,453.70516,317.0107Z;M403.5,294Q372,338,343,393Q314,448,254,435.5Q194,423,138,397.5Q82,372,88,311Q94,250,86,187.5Q78,125,134,95.5Q190,66,253,57Q316,48,362,91.5Q408,135,421.5,192.5Q435,250,403.5,294Z;M424.84079,321.86371Q447.86386,393.72743,384.56836,431.15935Q321.27286,468.59128,248.86371,472.84107Q176.45457,477.09086,148.84107,410.1135Q121.22757,343.13614,67.95457,296.56807Q14.68157,250,76.45485,209.5685Q138.22813,169.13699,166.2505,123.59142Q194.27286,78.04585,249.70464,79.81828Q305.13643,81.59072,362.47721,103.93179Q419.818,126.27286,410.81786,188.13643Q401.81772,250,424.84079,321.86371Z;M439.43806,316.51312Q432.44085,383.02623,370.39398,407.14258Q308.3471,431.25893,240.13979,459.78516Q171.93248,488.31139,132.30301,426.26451Q92.67355,364.21763,63.21484,307.10882Q33.75613,250,44.06194,178.90151Q54.36774,107.80301,118.67355,75.31613Q182.97935,42.82924,240.60882,72.66602Q298.23828,102.50279,368.10882,107.87054Q437.97935,113.23828,442.20731,181.61914Q446.43527,250,439.43806,316.51312Z;M423.38828,307.00416Q406.39243,364.00831,353.55217,384.57202Q300.71191,405.13573,242.06787,430.50416Q183.42382,455.87258,116.5554,425.63666Q49.68697,395.40075,58.87581,322.70037Q68.06464,250,86.66067,197.31625Q105.2567,144.63251,148.86843,108.53648Q192.48015,72.44045,252.10019,66.13989Q311.72022,59.83933,378.54063,84.21929Q445.36105,108.59925,442.87258,179.29963Q440.38412,250,423.38828,307.00416Z;M453.70516,317.0107Q433.36186,384.02139,362.52423,381.146Q291.6866,378.27061,242.8433,399.93801Q194,421.60541,117.08118,412.14317Q40.16237,402.68093,64.29201,326.34046Q88.42165,250,109.0107,206.32693Q129.59975,162.65387,148.64317,78.76495Q167.6866,-5.12397,241.8433,20.74072Q316,46.60541,350.8433,99.17023Q385.6866,151.73505,429.86753,200.86753Q474.04846,250,453.70516,317.0107Z"
|
|
2286
|
+
})
|
|
2287
|
+
})]
|
|
2288
|
+
}), jsxRuntime.jsxs("svg", {
|
|
2289
|
+
version: "1.1",
|
|
2290
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2291
|
+
viewBox: "0 0 500 500",
|
|
2292
|
+
width: "100%",
|
|
2293
|
+
id: "blobSvg",
|
|
2294
|
+
filter: "blur(8px)",
|
|
2295
|
+
transform: "rotate(0)",
|
|
2296
|
+
children: [jsxRuntime.jsx("defs", {
|
|
2297
|
+
children: jsxRuntime.jsxs("linearGradient", {
|
|
2298
|
+
id: "gradient2",
|
|
2299
|
+
x1: "0%",
|
|
2300
|
+
y1: "0%",
|
|
2301
|
+
x2: "0%",
|
|
2302
|
+
y2: "100%",
|
|
2303
|
+
children: [jsxRuntime.jsx("stop", {
|
|
2304
|
+
offset: "0%",
|
|
2305
|
+
style: {
|
|
2306
|
+
stopColor: '#003c8c'
|
|
2307
|
+
}
|
|
2308
|
+
}), jsxRuntime.jsx("stop", {
|
|
2309
|
+
offset: "100%",
|
|
2310
|
+
style: {
|
|
2311
|
+
stopColor: '#054ead'
|
|
2312
|
+
}
|
|
2313
|
+
})]
|
|
2314
|
+
})
|
|
2315
|
+
}), jsxRuntime.jsx("path", {
|
|
2316
|
+
id: "blob",
|
|
2317
|
+
fill: "url(#gradient2)",
|
|
2318
|
+
children: jsxRuntime.jsx("animate", {
|
|
2319
|
+
attributeName: "d",
|
|
2320
|
+
dur: "20s",
|
|
2321
|
+
repeatCount: "indefinite",
|
|
2322
|
+
values: "M385.47259,309.13613Q368.27225,368.27225,309.13613,425.14983Q250,482.02741,183.02911,432.9846Q116.05821,383.94179,100.85787,316.97089Q85.65753,250,111.11302,193.28426Q136.56852,136.56852,193.28426,70.4846Q250,4.40068,303.89298,73.30736Q357.78596,142.21404,380.22944,196.10702Q402.67293,250,385.47259,309.13613Z;M449.66467,329.57458Q409.14917,409.14917,329.57458,407.97733Q250,406.80549,191.3735,387.02924Q132.74701,367.25299,77.06026,308.6265Q21.3735,250,49.05191,163.36516Q76.73032,76.73032,163.36516,85.537Q250,94.34367,322.00775,100.16408Q394.01551,105.98449,442.09784,177.99225Q490.18018,250,449.66467,329.57458Z;M418.08664,320.33435Q390.6687,390.6687,320.33435,427.91946Q250,465.17023,188.27506,419.31005Q126.55013,373.44987,106.38448,311.72494Q86.21883,250,84.09726,165.98785Q81.9757,81.9757,165.98785,53.98938Q250,26.00305,311.1687,76.83282Q372.3374,127.6626,408.92099,188.8313Q445.50458,250,418.08664,320.33435Z;M409.06419,322.5266Q395.0532,395.0532,322.5266,445.11739Q250,495.18159,163.51944,459.07135Q77.03888,422.96112,82.39949,336.48056Q87.7601,250,115.64271,196.76266Q143.52532,143.52532,196.76266,76.83657Q250,10.14783,323.24578,56.82813Q396.49156,103.50844,409.78338,176.75422Q423.07519,250,409.06419,322.5266Z;M408.24461,332.63257Q415.26513,415.26513,332.63257,434.71568Q250,454.16622,179.33614,422.74697Q108.67228,391.32772,65.87585,320.66386Q23.07942,250,63.27221,176.73251Q103.46501,103.46501,176.73251,63.02288Q250,22.58075,311.86507,74.4253Q373.73015,126.26985,387.47712,188.13493Q401.22409,250,408.24461,332.63257Z;M423.42552,332.41134Q414.82268,414.82268,332.41134,424.30554Q250,433.78841,170.96572,420.92848Q91.93144,408.06856,46.07152,329.03428Q0.21159,250,66.88003,191.77423Q133.54846,133.54846,191.77423,102.82861Q250,72.10876,305.00592,106.04846Q360.01185,139.98815,396.0201,194.99408Q432.02836,250,423.42552,332.41134Z;M405.0078,325.44624Q400.89248,400.89248,325.44624,434.97549Q250,469.0585,165.42535,444.1039Q80.8507,419.1493,84.75627,334.57465Q88.66184,250,94.44262,175.1117Q100.2234,100.2234,175.1117,82.29749Q250,64.37159,306.73538,100.45042Q363.47075,136.52925,386.29693,193.26462Q409.12312,250,405.0078,325.44624Z;M395.5,320Q390,390,320,400Q250,410,172,408Q94,406,59,328Q24,250,70.5,183.5Q117,117,183.5,108Q250,99,335,89.5Q420,80,410.5,165Q401,250,395.5,320Z;M385.47259,309.13613Q368.27225,368.27225,309.13613,425.14983Q250,482.02741,183.02911,432.9846Q116.05821,383.94179,100.85787,316.97089Q85.65753,250,111.11302,193.28426Q136.56852,136.56852,193.28426,70.4846Q250,4.40068,303.89298,73.30736Q357.78596,142.21404,380.22944,196.10702Q402.67293,250,385.47259,309.13613Z"
|
|
2323
|
+
})
|
|
2324
|
+
})]
|
|
2325
|
+
}), jsxRuntime.jsxs("svg", {
|
|
2326
|
+
version: "1.1",
|
|
2327
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2328
|
+
viewBox: "0 0 500 500",
|
|
2329
|
+
width: "100%",
|
|
2330
|
+
id: "blobSvg",
|
|
2331
|
+
filter: "blur(8px)",
|
|
2332
|
+
transform: "rotate(0)",
|
|
2333
|
+
children: [jsxRuntime.jsx("defs", {
|
|
2334
|
+
children: jsxRuntime.jsxs("linearGradient", {
|
|
2335
|
+
id: "gradient1",
|
|
2336
|
+
x1: "0%",
|
|
2337
|
+
y1: "0%",
|
|
2338
|
+
x2: "0%",
|
|
2339
|
+
y2: "100%",
|
|
2340
|
+
children: [jsxRuntime.jsx("stop", {
|
|
2341
|
+
offset: "0%",
|
|
2342
|
+
style: {
|
|
2343
|
+
stopColor: '#96dca0'
|
|
2344
|
+
}
|
|
2345
|
+
}), jsxRuntime.jsx("stop", {
|
|
2346
|
+
offset: "100%",
|
|
2347
|
+
style: {
|
|
2348
|
+
stopColor: '#0ba224'
|
|
2349
|
+
}
|
|
2350
|
+
})]
|
|
2351
|
+
})
|
|
2352
|
+
}), jsxRuntime.jsx("path", {
|
|
2353
|
+
id: "blob",
|
|
2354
|
+
fill: "url(#gradient1)",
|
|
2355
|
+
children: jsxRuntime.jsx("animate", {
|
|
2356
|
+
attributeName: "d",
|
|
2357
|
+
dur: "10s",
|
|
2358
|
+
repeatCount: "indefinite",
|
|
2359
|
+
values: "M403.5,294Q372,338,343,393Q314,448,254,435.5Q194,423,138,397.5Q82,372,88,311Q94,250,86,187.5Q78,125,134,95.5Q190,66,253,57Q316,48,362,91.5Q408,135,421.5,192.5Q435,250,403.5,294Z;M469.34657,320.38487Q443.8468,390.76973,373.53877,402.1156Q303.23073,413.46147,238.88463,448.30757Q174.53853,483.15367,122.76833,431.6929Q70.99814,380.23213,76.84563,315.11607Q82.69313,250,78.9227,186.3071Q75.15227,122.6142,131.92223,91.73003Q188.6922,60.84587,253.2305,51.539Q317.7688,42.23213,359.5759,90.92433Q401.383,139.61653,448.11467,194.80827Q494.84633,250,469.34657,320.38487Z;M453.70516,317.0107Q433.36186,384.02139,362.52423,381.146Q291.6866,378.27061,242.8433,399.93801Q194,421.60541,117.08118,412.14317Q40.16237,402.68093,64.29201,326.34046Q88.42165,250,109.0107,206.32693Q129.59975,162.65387,148.64317,78.76495Q167.6866,-5.12397,241.8433,20.74072Q316,46.60541,350.8433,99.17023Q385.6866,151.73505,429.86753,200.86753Q474.04846,250,453.70516,317.0107Z;M460.19079,314.81752Q429.48296,379.63503,366.74655,397.33779Q304.01014,415.04055,238.62673,450.6401Q173.24331,486.23965,141.80231,418.853Q110.3613,351.46635,87.51337,300.73317Q64.66545,250,86.56406,198.80231Q108.46268,147.60462,149.75669,107.39355Q191.05069,67.18248,258.9189,40.41566Q326.7871,13.64883,381.21107,64.45621Q435.63503,115.26359,463.26683,182.63179Q490.89862,250,460.19079,314.81752Z;M402.82336,294.74662Q372.52122,339.49324,339.45366,380.77461Q306.3861,422.05598,251.70463,416.9165Q197.02317,411.77702,159.66506,377.28619Q122.30695,342.79537,72.75579,296.39768Q23.20463,250,37.88851,178.24662Q52.57238,106.49324,117.0304,72.97924Q181.48842,39.46525,238.53957,73.79537Q295.59073,108.12549,332.49083,135.50917Q369.39092,162.89286,401.2582,206.44643Q433.12549,250,402.82336,294.74662Z;M428.88107,298.41731Q382.87896,346.83463,343.6411,381.94757Q304.40324,417.06052,249.73188,417.66327Q195.06052,418.26602,121.90324,407.33463Q48.74595,396.40324,42.90922,323.20162Q37.07249,250,50.04223,182.03624Q63.01197,114.07249,129.2076,98.49191Q195.40324,82.91133,251.0746,78.83673Q306.74595,74.76214,356.50598,105.64321Q406.26602,136.52427,440.5746,193.26214Q474.88318,250,428.88107,298.41731Z;M437.48517,301.93698Q392.82947,353.87396,357.50371,413.21131Q322.17795,472.54867,247.51112,479.51159Q172.8443,486.47452,129.54819,427.64458Q86.25209,368.81464,81.57785,309.40732Q76.90361,250,83.86283,191.93327Q90.82205,133.86654,141.98146,104.152Q193.14087,74.43745,247.01483,83.88926Q300.88878,93.34106,355.51112,113.62234Q410.13346,133.90361,446.13717,191.95181Q482.14087,250,437.48517,301.93698Z;M439.43806,316.51312Q432.44085,383.02623,370.39398,407.14258Q308.3471,431.25893,240.13979,459.78516Q171.93248,488.31139,132.30301,426.26451Q92.67355,364.21763,63.21484,307.10882Q33.75613,250,44.06194,178.90151Q54.36774,107.80301,118.67355,75.31613Q182.97935,42.82924,240.60882,72.66602Q298.23828,102.50279,368.10882,107.87054Q437.97935,113.23828,442.20731,181.61914Q446.43527,250,439.43806,316.51312Z;M403.5,294Q372,338,343,393Q314,448,254,435.5Q194,423,138,397.5Q82,372,88,311Q94,250,86,187.5Q78,125,134,95.5Q190,66,253,57Q316,48,362,91.5Q408,135,421.5,192.5Q435,250,403.5,294Z"
|
|
2360
|
+
})
|
|
2361
|
+
})]
|
|
2362
|
+
})]
|
|
2363
|
+
});
|
|
2364
|
+
};
|
|
2365
|
+
|
|
2366
|
+
const Intro = () => {
|
|
2367
|
+
const app = useLlm(state => state.app);
|
|
2368
|
+
const motionItem = {
|
|
2369
|
+
hidden: {
|
|
2370
|
+
y: '40px'
|
|
2371
|
+
},
|
|
2372
|
+
show: {
|
|
2373
|
+
y: 0,
|
|
2374
|
+
transition: {
|
|
2375
|
+
type: 'tween',
|
|
2376
|
+
duration: 1
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
};
|
|
2380
|
+
const motionBlob = {
|
|
2381
|
+
top: {
|
|
2382
|
+
y: '-15%'
|
|
2383
|
+
},
|
|
2384
|
+
bottom: {
|
|
2385
|
+
y: '0%',
|
|
2386
|
+
transition: {
|
|
2387
|
+
repeat: Infinity,
|
|
2388
|
+
repeatType: 'mirror',
|
|
2389
|
+
duration: 2,
|
|
2390
|
+
ease: 'easeInOut'
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
};
|
|
2394
|
+
const stagger = {
|
|
2395
|
+
hidden: {},
|
|
2396
|
+
show: {
|
|
2397
|
+
transition: {
|
|
2398
|
+
staggerChildren: .3
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
};
|
|
2402
|
+
return jsxRuntime.jsx("div", {
|
|
2403
|
+
className: "llm__intro",
|
|
2404
|
+
children: jsxRuntime.jsx("div", {
|
|
2405
|
+
className: "llm-container",
|
|
2406
|
+
children: jsxRuntime.jsxs(framerMotion.motion.div, {
|
|
2407
|
+
variants: stagger,
|
|
2408
|
+
className: "llm__intro-wrapper llm-row",
|
|
2409
|
+
children: [jsxRuntime.jsxs(framerMotion.motion.div, {
|
|
2410
|
+
variants: motionItem,
|
|
2411
|
+
className: "llm__intro-text llm-span-md-6",
|
|
2412
|
+
children: [jsxRuntime.jsx("div", {
|
|
2413
|
+
className: "llm__intro-blob",
|
|
2414
|
+
children: jsxRuntime.jsx(framerMotion.motion.div, {
|
|
2415
|
+
variants: motionBlob,
|
|
2416
|
+
initial: "top",
|
|
2417
|
+
animate: "bottom",
|
|
2418
|
+
children: jsxRuntime.jsx(Blob, {})
|
|
2419
|
+
})
|
|
2420
|
+
}), jsxRuntime.jsx(framerMotion.motion.div, {
|
|
2421
|
+
variants: motionItem,
|
|
2422
|
+
className: "llm__intro-title -llm-t-display-3",
|
|
2423
|
+
children: app === null || app === void 0 ? void 0 : app.contents.extendedWelcomeText
|
|
2424
|
+
})]
|
|
2425
|
+
}), jsxRuntime.jsx(framerMotion.motion.div, {
|
|
2426
|
+
variants: motionItem,
|
|
2427
|
+
className: "llm__intro-links llm-span-md-6 llm-span-lg-5",
|
|
2428
|
+
children: jsxRuntime.jsx(QuickLinks, {})
|
|
2429
|
+
})]
|
|
2430
|
+
})
|
|
2431
|
+
})
|
|
2432
|
+
});
|
|
2433
|
+
};
|
|
2434
|
+
|
|
2435
|
+
const useAutosizeTextArea = (textAreaRef, value) => {
|
|
2436
|
+
react.useEffect(() => {
|
|
2437
|
+
if (textAreaRef) {
|
|
2438
|
+
textAreaRef.style.height = '0px';
|
|
2439
|
+
textAreaRef.style.height = textAreaRef.scrollHeight + 1 + 'px';
|
|
2440
|
+
}
|
|
2441
|
+
}, [textAreaRef, value]);
|
|
2442
|
+
};
|
|
2443
|
+
|
|
2444
|
+
const Suggestions = () => {
|
|
2445
|
+
bomMixerHooks.useWindowSize();
|
|
2446
|
+
const app = useLlm(state => state.app);
|
|
2447
|
+
const {
|
|
2448
|
+
send
|
|
2449
|
+
} = useLlm(state => state.actions);
|
|
2450
|
+
const swiperProps = {
|
|
2451
|
+
modules: [swiper.FreeMode],
|
|
2452
|
+
spaceBetween: 8,
|
|
2453
|
+
freeMode: true,
|
|
2454
|
+
slidesPerView: 'auto',
|
|
2455
|
+
slidesOffsetAfter: clamp(20, 110),
|
|
2456
|
+
slidesOffsetBefore: clamp(20, 110)
|
|
2457
|
+
};
|
|
2458
|
+
const onClick = item => __awaiter(void 0, void 0, void 0, function* () {
|
|
2459
|
+
yield send(item.sampleInputText, response => {
|
|
2460
|
+
// console.log('Suggestions.onChunk', response.chunks);
|
|
2461
|
+
}, response => {
|
|
2462
|
+
// console.log('Suggestions.onEnd', response);
|
|
2463
|
+
});
|
|
2464
|
+
});
|
|
2465
|
+
return jsxRuntime.jsx("div", {
|
|
2466
|
+
className: "llm__suggestions",
|
|
2467
|
+
children: jsxRuntime.jsx(react$1.Swiper, Object.assign({}, swiperProps, {
|
|
2468
|
+
onInit: swiper => swiper.update(),
|
|
2469
|
+
children: app === null || app === void 0 ? void 0 : app.contents.sampleInputTexts.map((s, j) => jsxRuntime.jsx(react$1.SwiperSlide, {
|
|
2470
|
+
children: jsxRuntime.jsx("div", {
|
|
2471
|
+
onClick: () => onClick(s),
|
|
2472
|
+
children: s.sampleInputText
|
|
2473
|
+
})
|
|
2474
|
+
}, j))
|
|
2475
|
+
}))
|
|
2476
|
+
});
|
|
2477
|
+
};
|
|
2478
|
+
|
|
2479
|
+
const Prompt = () => {
|
|
2480
|
+
const textArea = react.useRef(null);
|
|
2481
|
+
const prompt = useLlm(state => state.prompt);
|
|
2482
|
+
const messages = useLlm(state => state.messages);
|
|
2483
|
+
const streaming = useLlm(state => state.streaming);
|
|
2484
|
+
const {
|
|
2485
|
+
send,
|
|
2486
|
+
setPrompt,
|
|
2487
|
+
recognizeStart,
|
|
2488
|
+
recognizeStop,
|
|
2489
|
+
abort
|
|
2490
|
+
} = useLlm(state => state.actions);
|
|
2491
|
+
useAutosizeTextArea(textArea.current, prompt);
|
|
2492
|
+
const onChange = event => {
|
|
2493
|
+
var _a;
|
|
2494
|
+
const prompt = (_a = event.target) === null || _a === void 0 ? void 0 : _a.value;
|
|
2495
|
+
setPrompt(prompt);
|
|
2496
|
+
};
|
|
2497
|
+
const onSubmit = event => __awaiter(void 0, void 0, void 0, function* () {
|
|
2498
|
+
event && event.preventDefault();
|
|
2499
|
+
if (!prompt) {
|
|
2500
|
+
return;
|
|
2501
|
+
}
|
|
2502
|
+
yield send(prompt, response => {
|
|
2503
|
+
// console.log('Prompt.onChunk', response.chunks);
|
|
2504
|
+
}, response => {
|
|
2505
|
+
// console.log('Prompt.onEnd', response);
|
|
2506
|
+
});
|
|
2507
|
+
});
|
|
2508
|
+
const onKeyDown = event => {
|
|
2509
|
+
if (event.code == 'Enter' && !event.shiftKey) {
|
|
2510
|
+
onSubmit(event);
|
|
2511
|
+
}
|
|
2512
|
+
};
|
|
2513
|
+
return jsxRuntime.jsx("div", {
|
|
2514
|
+
className: "llm__prompt",
|
|
2515
|
+
children: jsxRuntime.jsxs("div", {
|
|
2516
|
+
className: "llm-container",
|
|
2517
|
+
children: [messages.length === 0 && jsxRuntime.jsx("div", {
|
|
2518
|
+
className: "llm__prompt-suggestions",
|
|
2519
|
+
children: jsxRuntime.jsx(Suggestions, {})
|
|
2520
|
+
}), jsxRuntime.jsxs("form", {
|
|
2521
|
+
className: "llm__prompt-form",
|
|
2522
|
+
onSubmit: onSubmit,
|
|
2523
|
+
children: [jsxRuntime.jsxs("div", {
|
|
2524
|
+
className: "llm__prompt-input",
|
|
2525
|
+
children: [jsxRuntime.jsx("textarea", {
|
|
2526
|
+
className: "llm__prompt-textarea",
|
|
2527
|
+
name: "prompt",
|
|
2528
|
+
onKeyDown: onKeyDown,
|
|
2529
|
+
onChange: onChange,
|
|
2530
|
+
ref: textArea,
|
|
2531
|
+
rows: 1,
|
|
2532
|
+
value: prompt
|
|
2533
|
+
}), false ]
|
|
2534
|
+
}), streaming ? jsxRuntime.jsxs("button", {
|
|
2535
|
+
className: "llm__prompt-stop",
|
|
2536
|
+
type: "button",
|
|
2537
|
+
onClick: abort,
|
|
2538
|
+
children: [jsxRuntime.jsx(Blob, {}), jsxRuntime.jsx("i", {
|
|
2539
|
+
children: jsxRuntime.jsx(bomMixerIcons.IconLlmStop, {})
|
|
2540
|
+
})]
|
|
2541
|
+
}) : jsxRuntime.jsxs("button", {
|
|
2542
|
+
className: "llm__prompt-submit",
|
|
2543
|
+
type: "submit",
|
|
2544
|
+
disabled: !prompt,
|
|
2545
|
+
children: [jsxRuntime.jsx(Blob, {}), jsxRuntime.jsx("i", {
|
|
2546
|
+
children: jsxRuntime.jsx(bomMixerIcons.IconLlmSend, {})
|
|
2547
|
+
})]
|
|
2548
|
+
})]
|
|
2549
|
+
})]
|
|
2550
|
+
})
|
|
2551
|
+
});
|
|
2552
|
+
};
|
|
2553
|
+
|
|
2554
|
+
const defaultProps = {
|
|
2555
|
+
blur: '10px',
|
|
2556
|
+
blob1: {
|
|
2557
|
+
duration: '4s',
|
|
2558
|
+
color: 'var(--llm-color-ui-2)',
|
|
2559
|
+
transform: 'translate(400 -100) scale(2 2)'
|
|
2560
|
+
},
|
|
2561
|
+
blob2: {
|
|
2562
|
+
duration: '6s',
|
|
2563
|
+
color: 'var(--llm-color-ui-3)',
|
|
2564
|
+
transform: 'translate(-600 0) scale(2 2)'
|
|
2565
|
+
},
|
|
2566
|
+
blob3: {
|
|
2567
|
+
duration: '8s',
|
|
2568
|
+
color: 'var(--llm-color-ui-4)',
|
|
2569
|
+
transform: 'translate(-200 -600) scale(2 2)'
|
|
2570
|
+
}
|
|
2571
|
+
};
|
|
2572
|
+
const Background = props => {
|
|
2573
|
+
const blob1 = Object.assign({}, defaultProps.blob1, props.blob1);
|
|
2574
|
+
const blob2 = Object.assign({}, defaultProps.blob2, props.blob2);
|
|
2575
|
+
const blob3 = Object.assign({}, defaultProps.blob3, props.blob3);
|
|
2576
|
+
return jsxRuntime.jsxs("div", {
|
|
2577
|
+
className: "llm__background",
|
|
2578
|
+
children: [jsxRuntime.jsx("span", {
|
|
2579
|
+
className: "llm__background-noise",
|
|
2580
|
+
style: {
|
|
2581
|
+
backgroundImage: 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAGuGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjItMDYtMjZUMjM6NTA6NTIrMDM6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIyLTA2LTI2VDIzOjU2OjM4KzAzOjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIyLTA2LTI2VDIzOjU2OjM4KzAzOjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjBkYTdiMWEyLWZhMzAtNDc3ZC05MTkzLTE1N2NlYjlhNjlhYiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOWMwMjFlNy03Y2UyLTQyMjUtOTBjMi1kNWViMjhhZTdjZWQiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoxOWMwMjFlNy03Y2UyLTQyMjUtOTBjMi1kNWViMjhhZTdjZWQiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjE5YzAyMWU3LTdjZTItNDIyNS05MGMyLWQ1ZWIyOGFlN2NlZCIgc3RFdnQ6d2hlbj0iMjAyMi0wNi0yNlQyMzo1MDo1MiswMzowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjAgKE1hY2ludG9zaCkiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmZkMmZmNzcxLTU0YjQtNDMxZi1iMmE0LThhNjRjOTEyNTllNyIgc3RFdnQ6d2hlbj0iMjAyMi0wNi0yNlQyMzo1NjoyNiswMzowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjAgKE1hY2ludG9zaCkiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjBkYTdiMWEyLWZhMzAtNDc3ZC05MTkzLTE1N2NlYjlhNjlhYiIgc3RFdnQ6d2hlbj0iMjAyMi0wNi0yNlQyMzo1NjozOCswMzowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjAgKE1hY2ludG9zaCkiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+3K8pSwAA1CBJREFUeJxk/ddz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)'
|
|
2582
|
+
}
|
|
2583
|
+
}), jsxRuntime.jsx("div", {
|
|
2584
|
+
className: "llm__background-shade",
|
|
2585
|
+
children: jsxRuntime.jsxs("svg", {
|
|
2586
|
+
filter: `blur(${props.blur})`,
|
|
2587
|
+
version: "1.1",
|
|
2588
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2589
|
+
width: "100%",
|
|
2590
|
+
height: "100%",
|
|
2591
|
+
viewBox: "0 0 500 500",
|
|
2592
|
+
children: [jsxRuntime.jsx("path", {
|
|
2593
|
+
fill: blob1.color,
|
|
2594
|
+
transform: blob1.transform,
|
|
2595
|
+
children: jsxRuntime.jsx("animate", {
|
|
2596
|
+
attributeName: "d",
|
|
2597
|
+
dur: blob1.duration,
|
|
2598
|
+
repeatCount: "indefinite",
|
|
2599
|
+
values: "M405.0078,325.44624Q400.89248,400.89248,325.44624,434.97549Q250,469.0585,165.42535,444.1039Q80.8507,419.1493,84.75627,334.57465Q88.66184,250,94.44262,175.1117Q100.2234,100.2234,175.1117,82.29749Q250,64.37159,306.73538,100.45042Q363.47075,136.52925,386.29693,193.26462Q409.12312,250,405.0078,325.44624Z;M385.47259,309.13613Q368.27225,368.27225,309.13613,425.14983Q250,482.02741,183.02911,432.9846Q116.05821,383.94179,100.85787,316.97089Q85.65753,250,111.11302,193.28426Q136.56852,136.56852,193.28426,70.4846Q250,4.40068,303.89298,73.30736Q357.78596,142.21404,380.22944,196.10702Q402.67293,250,385.47259,309.13613Z;M446.86448,329.36764Q408.73529,408.73529,329.36764,419.76576Q250,430.79624,166.60504,423.79308Q83.21008,416.78992,69.36975,333.39496Q55.52942,250,96.13341,193.3687Q136.7374,136.7374,193.3687,119.10083Q250,101.46426,313.50105,112.23108Q377.00211,122.99789,430.99789,186.49895Q484.99368,250,446.86448,329.36764Z;M449.05134,329.9003Q409.80059,409.80059,329.9003,451.15995Q250,492.5193,162.89881,458.36084Q75.79762,424.20238,65.04837,337.10119Q54.29911,250,85.74629,183.59673Q117.19347,117.19347,183.59673,88.1905Q250,59.18753,328.8549,75.73886Q407.7098,92.2902,448.00594,171.1451Q488.30208,250,449.05134,329.9003Z;M405.0078,325.44624Q400.89248,400.89248,325.44624,434.97549Q250,469.0585,165.42535,444.1039Q80.8507,419.1493,84.75627,334.57465Q88.66184,250,94.44262,175.1117Q100.2234,100.2234,175.1117,82.29749Q250,64.37159,306.73538,100.45042Q363.47075,136.52925,386.29693,193.26462Q409.12312,250,405.0078,325.44624Z"
|
|
2600
|
+
})
|
|
2601
|
+
}), jsxRuntime.jsx("path", {
|
|
2602
|
+
fill: blob2.color,
|
|
2603
|
+
transform: blob2.transform,
|
|
2604
|
+
children: jsxRuntime.jsx("animate", {
|
|
2605
|
+
attributeName: "d",
|
|
2606
|
+
dur: blob2.duration,
|
|
2607
|
+
repeatCount: "indefinite",
|
|
2608
|
+
values: "M385.47259,309.13613Q368.27225,368.27225,309.13613,425.14983Q250,482.02741,183.02911,432.9846Q116.05821,383.94179,100.85787,316.97089Q85.65753,250,111.11302,193.28426Q136.56852,136.56852,193.28426,70.4846Q250,4.40068,303.89298,73.30736Q357.78596,142.21404,380.22944,196.10702Q402.67293,250,385.47259,309.13613Z;M409.06419,322.5266Q395.0532,395.0532,322.5266,445.11739Q250,495.18159,163.51944,459.07135Q77.03888,422.96112,82.39949,336.48056Q87.7601,250,115.64271,196.76266Q143.52532,143.52532,196.76266,76.83657Q250,10.14783,323.24578,56.82813Q396.49156,103.50844,409.78338,176.75422Q423.07519,250,409.06419,322.5266Z;M423.42552,332.41134Q414.82268,414.82268,332.41134,424.30554Q250,433.78841,170.96572,420.92848Q91.93144,408.06856,46.07152,329.03428Q0.21159,250,66.88003,191.77423Q133.54846,133.54846,191.77423,102.82861Q250,72.10876,305.00592,106.04846Q360.01185,139.98815,396.0201,194.99408Q432.02836,250,423.42552,332.41134Z;M408.24461,332.63257Q415.26513,415.26513,332.63257,434.71568Q250,454.16622,179.33614,422.74697Q108.67228,391.32772,65.87585,320.66386Q23.07942,250,63.27221,176.73251Q103.46501,103.46501,176.73251,63.02288Q250,22.58075,311.86507,74.4253Q373.73015,126.26985,387.47712,188.13493Q401.22409,250,408.24461,332.63257Z;M385.47259,309.13613Q368.27225,368.27225,309.13613,425.14983Q250,482.02741,183.02911,432.9846Q116.05821,383.94179,100.85787,316.97089Q85.65753,250,111.11302,193.28426Q136.56852,136.56852,193.28426,70.4846Q250,4.40068,303.89298,73.30736Q357.78596,142.21404,380.22944,196.10702Q402.67293,250,385.47259,309.13613Z"
|
|
2609
|
+
})
|
|
2610
|
+
}), jsxRuntime.jsx("path", {
|
|
2611
|
+
fill: blob3.color,
|
|
2612
|
+
transform: blob3.transform,
|
|
2613
|
+
children: jsxRuntime.jsx("animate", {
|
|
2614
|
+
attributeName: "d",
|
|
2615
|
+
dur: blob3.duration,
|
|
2616
|
+
repeatCount: "indefinite",
|
|
2617
|
+
values: "M385.47259,309.13613Q368.27225,368.27225,309.13613,425.14983Q250,482.02741,183.02911,432.9846Q116.05821,383.94179,100.85787,316.97089Q85.65753,250,111.11302,193.28426Q136.56852,136.56852,193.28426,70.4846Q250,4.40068,303.89298,73.30736Q357.78596,142.21404,380.22944,196.10702Q402.67293,250,385.47259,309.13613Z;M409.06419,322.5266Q395.0532,395.0532,322.5266,445.11739Q250,495.18159,163.51944,459.07135Q77.03888,422.96112,82.39949,336.48056Q87.7601,250,115.64271,196.76266Q143.52532,143.52532,196.76266,76.83657Q250,10.14783,323.24578,56.82813Q396.49156,103.50844,409.78338,176.75422Q423.07519,250,409.06419,322.5266Z;M423.42552,332.41134Q414.82268,414.82268,332.41134,424.30554Q250,433.78841,170.96572,420.92848Q91.93144,408.06856,46.07152,329.03428Q0.21159,250,66.88003,191.77423Q133.54846,133.54846,191.77423,102.82861Q250,72.10876,305.00592,106.04846Q360.01185,139.98815,396.0201,194.99408Q432.02836,250,423.42552,332.41134Z;M408.24461,332.63257Q415.26513,415.26513,332.63257,434.71568Q250,454.16622,179.33614,422.74697Q108.67228,391.32772,65.87585,320.66386Q23.07942,250,63.27221,176.73251Q103.46501,103.46501,176.73251,63.02288Q250,22.58075,311.86507,74.4253Q373.73015,126.26985,387.47712,188.13493Q401.22409,250,408.24461,332.63257Z;M385.47259,309.13613Q368.27225,368.27225,309.13613,425.14983Q250,482.02741,183.02911,432.9846Q116.05821,383.94179,100.85787,316.97089Q85.65753,250,111.11302,193.28426Q136.56852,136.56852,193.28426,70.4846Q250,4.40068,303.89298,73.30736Q357.78596,142.21404,380.22944,196.10702Q402.67293,250,385.47259,309.13613Z"
|
|
2618
|
+
})
|
|
2619
|
+
})]
|
|
2620
|
+
})
|
|
2621
|
+
})]
|
|
2622
|
+
});
|
|
2623
|
+
};
|
|
2624
|
+
Background.defaultProps = defaultProps;
|
|
2625
|
+
|
|
2626
|
+
const Cta = props => {
|
|
2627
|
+
const onClick = () => {
|
|
2628
|
+
if (typeof props.onClick === 'function') {
|
|
2629
|
+
props.onClick();
|
|
2630
|
+
}
|
|
2631
|
+
};
|
|
2632
|
+
const bg = props.type == 'button' || props.type == 'submit' ? jsxRuntime.jsx(Background, {}) : '';
|
|
2633
|
+
const icon = props.type == 'text' ? jsxRuntime.jsx(bomMixerIcons.IconLlmArrowRight, {}) : '';
|
|
2634
|
+
const classNames = bomCore.getClassNames('llm__cta', `llm__cta--${props.type}`);
|
|
2635
|
+
return props.url ? jsxRuntime.jsxs("a", {
|
|
2636
|
+
className: classNames,
|
|
2637
|
+
href: props.url,
|
|
2638
|
+
target: props.target,
|
|
2639
|
+
children: [bg, jsxRuntime.jsx("span", {
|
|
2640
|
+
children: props.label
|
|
2641
|
+
}), icon]
|
|
2642
|
+
}) : jsxRuntime.jsxs("button", {
|
|
2643
|
+
className: classNames,
|
|
2644
|
+
onClick: () => onClick(),
|
|
2645
|
+
type: props.type == 'button' || props.type == 'submit' ? props.type : undefined,
|
|
2646
|
+
children: [bg, jsxRuntime.jsx("span", {
|
|
2647
|
+
children: props.label
|
|
2648
|
+
}), icon]
|
|
2649
|
+
});
|
|
2650
|
+
};
|
|
2651
|
+
|
|
2652
|
+
const Event = props => {
|
|
2653
|
+
const label = bomMixerHooks.useLabel();
|
|
2654
|
+
const {
|
|
2655
|
+
send,
|
|
2656
|
+
decorateUrl
|
|
2657
|
+
} = useLlm(state => state.actions);
|
|
2658
|
+
const onTellMeMore = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
2659
|
+
const prompt = `${label('llm.tellMeMoreAbout')} ${props.title}`;
|
|
2660
|
+
yield send(prompt, response => {
|
|
2661
|
+
// console.log('Prompt.onChunk', response.chunks);
|
|
2662
|
+
}, response => {
|
|
2663
|
+
// console.log('Prompt.onEnd', response);
|
|
2664
|
+
});
|
|
2665
|
+
});
|
|
2666
|
+
const onGoToWebsite = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
2667
|
+
if (bomCore.isBrowser) {
|
|
2668
|
+
const url = yield decorateUrl(props, props.url);
|
|
2669
|
+
window.open(url, '_blank');
|
|
2670
|
+
}
|
|
2671
|
+
});
|
|
2672
|
+
const classNames = bomCore.getClassNames('llm__event', {
|
|
2673
|
+
[`llm__event--${props.type}`]: !!props.type
|
|
2674
|
+
});
|
|
2675
|
+
return jsxRuntime.jsx("div", {
|
|
2676
|
+
className: classNames,
|
|
2677
|
+
children: jsxRuntime.jsxs("div", {
|
|
2678
|
+
className: "llm__event-inner",
|
|
2679
|
+
children: [jsxRuntime.jsxs("div", {
|
|
2680
|
+
className: "llm__event-content",
|
|
2681
|
+
children: [props.type == 'event' && jsxRuntime.jsx("div", {
|
|
2682
|
+
className: "llm__event-pretitle",
|
|
2683
|
+
children: label('llm.eventPretitle')
|
|
2684
|
+
}), props.title && jsxRuntime.jsx("div", {
|
|
2685
|
+
className: "llm__event-title",
|
|
2686
|
+
dangerouslySetInnerHTML: {
|
|
2687
|
+
__html: props.title
|
|
2688
|
+
}
|
|
2689
|
+
}), props.abstract && jsxRuntime.jsx("div", {
|
|
2690
|
+
className: "llm__event-body",
|
|
2691
|
+
dangerouslySetInnerHTML: {
|
|
2692
|
+
__html: props.abstract
|
|
2693
|
+
}
|
|
2694
|
+
}), props.place && jsxRuntime.jsxs("div", {
|
|
2695
|
+
className: "llm__event-location",
|
|
2696
|
+
children: [jsxRuntime.jsx(bomMixerIcons.IconLlmPin, {}), " ", props.place]
|
|
2697
|
+
}), jsxRuntime.jsxs("div", {
|
|
2698
|
+
className: "llm__event-ctas",
|
|
2699
|
+
children: [jsxRuntime.jsx(Cta, {
|
|
2700
|
+
type: "button",
|
|
2701
|
+
label: label('llm.tellMeMore'),
|
|
2702
|
+
onClick: onTellMeMore
|
|
2703
|
+
}), jsxRuntime.jsx(Cta, {
|
|
2704
|
+
type: "text",
|
|
2705
|
+
label: label('llm.goToWebsite'),
|
|
2706
|
+
onClick: onGoToWebsite
|
|
2707
|
+
})]
|
|
2708
|
+
})]
|
|
2709
|
+
}), props.image && jsxRuntime.jsxs("div", {
|
|
2710
|
+
className: "llm__event-media",
|
|
2711
|
+
children: [jsxRuntime.jsx("div", {
|
|
2712
|
+
className: "llm__event-asset",
|
|
2713
|
+
children: jsxRuntime.jsx("img", {
|
|
2714
|
+
src: props.image,
|
|
2715
|
+
alt: props.title
|
|
2716
|
+
})
|
|
2717
|
+
}), (props.time || props.date) && jsxRuntime.jsxs("div", {
|
|
2718
|
+
className: "llm__event-tags",
|
|
2719
|
+
children: [props.date && jsxRuntime.jsx("div", {
|
|
2720
|
+
className: "llm__event-tag llm__event-date",
|
|
2721
|
+
children: props.date
|
|
2722
|
+
}), props.time && jsxRuntime.jsx("div", {
|
|
2723
|
+
className: "llm__event-tag llm__event-time",
|
|
2724
|
+
children: props.time
|
|
2725
|
+
})]
|
|
2726
|
+
})]
|
|
2727
|
+
})]
|
|
2728
|
+
})
|
|
2729
|
+
});
|
|
2730
|
+
};
|
|
2731
|
+
|
|
2732
|
+
const EventGroup = props => {
|
|
2733
|
+
bomMixerHooks.useWindowSize();
|
|
2734
|
+
const classNames = bomCore.getClassNames('llm__events');
|
|
2735
|
+
const navigationPrevRef = react.useRef(null);
|
|
2736
|
+
const navigationNextRef = react.useRef(null);
|
|
2737
|
+
const swiperProps = {
|
|
2738
|
+
modules: [swiper.Navigation],
|
|
2739
|
+
spaceBetween: clamp(16, 24),
|
|
2740
|
+
slidesPerView: 1.1,
|
|
2741
|
+
watchOverflow: true,
|
|
2742
|
+
navigation: {
|
|
2743
|
+
prevEl: navigationPrevRef.current,
|
|
2744
|
+
nextEl: navigationNextRef.current
|
|
2745
|
+
},
|
|
2746
|
+
breakpoints: {
|
|
2747
|
+
630: {
|
|
2748
|
+
slidesPerView: 1.5
|
|
2749
|
+
},
|
|
2750
|
+
768: {
|
|
2751
|
+
slidesPerView: 2
|
|
2752
|
+
},
|
|
2753
|
+
1024: {
|
|
2754
|
+
slidesPerView: 2.5
|
|
2755
|
+
},
|
|
2756
|
+
1280: {
|
|
2757
|
+
slidesPerView: 3
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
};
|
|
2761
|
+
return jsxRuntime.jsx("div", {
|
|
2762
|
+
className: classNames,
|
|
2763
|
+
children: jsxRuntime.jsxs(react$1.Swiper, Object.assign({}, swiperProps, {
|
|
2764
|
+
children: [jsxRuntime.jsxs("div", {
|
|
2765
|
+
className: "llm__events-nav",
|
|
2766
|
+
children: [jsxRuntime.jsx("button", {
|
|
2767
|
+
ref: navigationPrevRef,
|
|
2768
|
+
children: jsxRuntime.jsx(bomMixerIcons.IconLlmArrowLeft, {})
|
|
2769
|
+
}), jsxRuntime.jsx("button", {
|
|
2770
|
+
ref: navigationNextRef,
|
|
2771
|
+
children: jsxRuntime.jsx(bomMixerIcons.IconLlmArrowRight, {})
|
|
2772
|
+
})]
|
|
2773
|
+
}), props.items.map((item, i) => jsxRuntime.jsx(react$1.SwiperSlide, {
|
|
2774
|
+
className: "llm__events-slide",
|
|
2775
|
+
children: jsxRuntime.jsx(Event, Object.assign({}, item))
|
|
2776
|
+
}, i))]
|
|
2777
|
+
}))
|
|
2778
|
+
});
|
|
2779
|
+
};
|
|
2780
|
+
|
|
2781
|
+
const FormRecap = () => {
|
|
2782
|
+
const label = bomMixerHooks.useLabel();
|
|
2783
|
+
const app = useLlm(state => state.app);
|
|
2784
|
+
const threadId = useLlm(state => state.threadId);
|
|
2785
|
+
const {
|
|
2786
|
+
formRecap,
|
|
2787
|
+
getApi
|
|
2788
|
+
} = useLlm(state => state.actions);
|
|
2789
|
+
const onSubmit = event => __awaiter(void 0, void 0, void 0, function* () {
|
|
2790
|
+
event.preventDefault();
|
|
2791
|
+
try {
|
|
2792
|
+
const formData = new FormData(event.target);
|
|
2793
|
+
const data = {};
|
|
2794
|
+
for (const [key, value] of formData) {
|
|
2795
|
+
data[key] = value;
|
|
2796
|
+
}
|
|
2797
|
+
data.threadId = threadId;
|
|
2798
|
+
const payload = Object.assign(Object.assign({}, data), {
|
|
2799
|
+
html: getEmailHtml(data, app)
|
|
2800
|
+
});
|
|
2801
|
+
const api = getApi();
|
|
2802
|
+
const response = yield api.post('/summary', payload);
|
|
2803
|
+
if (response) {
|
|
2804
|
+
console.warn('FormRecap.onSubmit.success', response, payload);
|
|
2805
|
+
formRecap();
|
|
2806
|
+
} else {
|
|
2807
|
+
console.warn('FormRecap.onSubmit.error');
|
|
2808
|
+
formRecap({
|
|
2809
|
+
message: 'unknown error'
|
|
2810
|
+
});
|
|
2811
|
+
}
|
|
2812
|
+
} catch (error) {
|
|
2813
|
+
console.warn('FormRecap.onSubmit.error', error);
|
|
2814
|
+
formRecap(error);
|
|
2815
|
+
}
|
|
2816
|
+
});
|
|
2817
|
+
return jsxRuntime.jsx("div", {
|
|
2818
|
+
className: "llm__subscribe",
|
|
2819
|
+
children: jsxRuntime.jsx("div", {
|
|
2820
|
+
className: "llm__subscribe-wrapper",
|
|
2821
|
+
children: jsxRuntime.jsxs("form", {
|
|
2822
|
+
className: "llm__subscribe-form",
|
|
2823
|
+
onSubmit: onSubmit,
|
|
2824
|
+
children: [jsxRuntime.jsx("div", {
|
|
2825
|
+
className: "llm__subscribe-title",
|
|
2826
|
+
children: label('llm.formRecapTitle')
|
|
2827
|
+
}), jsxRuntime.jsxs("div", {
|
|
2828
|
+
className: "llm__subscribe-fields",
|
|
2829
|
+
children: [jsxRuntime.jsx("div", {
|
|
2830
|
+
className: "llm__subscribe-field",
|
|
2831
|
+
children: jsxRuntime.jsx("input", {
|
|
2832
|
+
type: "text",
|
|
2833
|
+
name: "fullName",
|
|
2834
|
+
id: "subscribe-fullName",
|
|
2835
|
+
placeholder: label('llm.formRecapFullName')
|
|
2836
|
+
})
|
|
2837
|
+
}), jsxRuntime.jsx("div", {
|
|
2838
|
+
className: "llm__subscribe-field",
|
|
2839
|
+
children: jsxRuntime.jsx("input", {
|
|
2840
|
+
type: "email",
|
|
2841
|
+
name: "email",
|
|
2842
|
+
id: "subscribe-email",
|
|
2843
|
+
placeholder: label('llm.formRecapEmail')
|
|
2844
|
+
})
|
|
2845
|
+
}), jsxRuntime.jsxs("div", {
|
|
2846
|
+
className: "llm__subscribe-field -privacy",
|
|
2847
|
+
children: [jsxRuntime.jsx("input", {
|
|
2848
|
+
type: "checkbox",
|
|
2849
|
+
name: "privacy",
|
|
2850
|
+
id: "subscribe-privacy"
|
|
2851
|
+
}), jsxRuntime.jsx("label", {
|
|
2852
|
+
htmlFor: "subscribe-privacy",
|
|
2853
|
+
children: label('llm.formRecapPrivacy')
|
|
2854
|
+
})]
|
|
2855
|
+
}), jsxRuntime.jsx("div", {
|
|
2856
|
+
className: "llm__subscribe-cta",
|
|
2857
|
+
children: jsxRuntime.jsx(Cta, {
|
|
2858
|
+
type: "submit",
|
|
2859
|
+
label: label('llm.formRecapSend')
|
|
2860
|
+
})
|
|
2861
|
+
})]
|
|
2862
|
+
})]
|
|
2863
|
+
})
|
|
2864
|
+
})
|
|
2865
|
+
});
|
|
2866
|
+
};
|
|
2867
|
+
function getEmailHtml(data, app) {
|
|
2868
|
+
var _a;
|
|
2869
|
+
const firstName = data.fullName ? data.fullName.split(' ')[0] : '';
|
|
2870
|
+
const name = ((_a = app === null || app === void 0 ? void 0 : app.contents) === null || _a === void 0 ? void 0 : _a.shortWelcomeText) || 'PlatformAI';
|
|
2871
|
+
const title = `Ciao ${firstName}`;
|
|
2872
|
+
const paragraphs = `<p>${['Ecco il tuo promemoria,', 'per qualunque altra cosa sai dove potermi trovare, sarò sempre lieto di parlare con te. 👋'].join('</p><p>')}</p>`;
|
|
2873
|
+
const colorAccent = '#00aeff';
|
|
2874
|
+
const threadUrl = window.location.href + `${window.location.search ? '&' : '?'}llmThreadId=${data.threadId}`;
|
|
2875
|
+
return `
|
|
2876
|
+
<!doctype html>
|
|
2877
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
|
2878
|
+
|
|
2879
|
+
<head>
|
|
2880
|
+
<title> ${title} </title>
|
|
2881
|
+
<!--[if !mso]><!-->
|
|
2882
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
2883
|
+
<!--<![endif]-->
|
|
2884
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
2885
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
2886
|
+
<style type="text/css">
|
|
2887
|
+
#outlook a {
|
|
2888
|
+
padding: 0;
|
|
2889
|
+
}
|
|
2890
|
+
|
|
2891
|
+
body {
|
|
2892
|
+
margin: 0;
|
|
2893
|
+
padding: 0;
|
|
2894
|
+
-webkit-text-size-adjust: 100%;
|
|
2895
|
+
-ms-text-size-adjust: 100%;
|
|
2896
|
+
}
|
|
2897
|
+
|
|
2898
|
+
table,
|
|
2899
|
+
td {
|
|
2900
|
+
border-collapse: collapse;
|
|
2901
|
+
mso-table-lspace: 0pt;
|
|
2902
|
+
mso-table-rspace: 0pt;
|
|
2903
|
+
}
|
|
2904
|
+
|
|
2905
|
+
img {
|
|
2906
|
+
border: 0;
|
|
2907
|
+
height: auto;
|
|
2908
|
+
line-height: 100%;
|
|
2909
|
+
outline: none;
|
|
2910
|
+
text-decoration: none;
|
|
2911
|
+
-ms-interpolation-mode: bicubic;
|
|
2912
|
+
}
|
|
2913
|
+
|
|
2914
|
+
p {
|
|
2915
|
+
display: block;
|
|
2916
|
+
margin: 13px 0;
|
|
2917
|
+
}
|
|
2918
|
+
</style>
|
|
2919
|
+
<!--[if mso]>
|
|
2920
|
+
<noscript>
|
|
2921
|
+
<xml>
|
|
2922
|
+
<o:OfficeDocumentSettings>
|
|
2923
|
+
<o:AllowPNG/>
|
|
2924
|
+
<o:PixelsPerInch>96</o:PixelsPerInch>
|
|
2925
|
+
</o:OfficeDocumentSettings>
|
|
2926
|
+
</xml>
|
|
2927
|
+
</noscript>
|
|
2928
|
+
<![endif]-->
|
|
2929
|
+
<!--[if lte mso 11]>
|
|
2930
|
+
<style type="text/css">
|
|
2931
|
+
.mj-outlook-group-fix { width:100% !important; }
|
|
2932
|
+
</style>
|
|
2933
|
+
<![endif]-->
|
|
2934
|
+
<!--[if !mso]><!-->
|
|
2935
|
+
<link href="https://fonts.googleapis.com/css?family=Inter:400,600" rel="stylesheet" type="text/css">
|
|
2936
|
+
<style type="text/css">
|
|
2937
|
+
@import url(https://fonts.googleapis.com/css?family=Inter:400,600);
|
|
2938
|
+
</style>
|
|
2939
|
+
<!--<![endif]-->
|
|
2940
|
+
<style type="text/css">
|
|
2941
|
+
@media only screen and (min-width:480px) {
|
|
2942
|
+
.mj-column-per-100 {
|
|
2943
|
+
width: 100% !important;
|
|
2944
|
+
max-width: 100%;
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
</style>
|
|
2948
|
+
<style media="screen and (min-width:480px)">
|
|
2949
|
+
.moz-text-html .mj-column-per-100 {
|
|
2950
|
+
width: 100% !important;
|
|
2951
|
+
max-width: 100%;
|
|
2952
|
+
}
|
|
2953
|
+
</style>
|
|
2954
|
+
<style type="text/css">
|
|
2955
|
+
</style>
|
|
2956
|
+
</head>
|
|
2957
|
+
|
|
2958
|
+
<body style="word-spacing:normal;">
|
|
2959
|
+
<div style="">
|
|
2960
|
+
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
|
2961
|
+
<div style="margin:0px auto;max-width:600px;">
|
|
2962
|
+
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
|
2963
|
+
<tbody>
|
|
2964
|
+
<tr>
|
|
2965
|
+
<td style="direction:ltr;font-size:0px;padding:0px;padding-top:20px;text-align:center;">
|
|
2966
|
+
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]-->
|
|
2967
|
+
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
|
2968
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
|
|
2969
|
+
<tbody>
|
|
2970
|
+
<tr>
|
|
2971
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
|
2972
|
+
<div style="font-family:Inter;font-size:20px;font-weight:600;line-height:24px;text-align:left;color:#3b3b3b;">${name}</div>
|
|
2973
|
+
</td>
|
|
2974
|
+
</tr>
|
|
2975
|
+
<tr>
|
|
2976
|
+
<td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
|
2977
|
+
<p style="border-top:solid 3px #EFEFF2;font-size:1px;margin:0px auto;width:100%;">
|
|
2978
|
+
</p>
|
|
2979
|
+
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 3px #EFEFF2;font-size:1px;margin:0px auto;width:550px;" role="presentation" width="550px" ><tr><td style="height:0;line-height:0;">
|
|
2980
|
+
</td></tr></table><![endif]-->
|
|
2981
|
+
</td>
|
|
2982
|
+
</tr>
|
|
2983
|
+
<tr>
|
|
2984
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
|
2985
|
+
<div style="font-family:Inter;font-size:28px;font-weight:600;line-height:24px;text-align:left;color:#3b3b3b;">${title}</div>
|
|
2986
|
+
</td>
|
|
2987
|
+
</tr>
|
|
2988
|
+
<tr>
|
|
2989
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
|
2990
|
+
<div style="font-family:Inter, Helvetica, sans-serif;font-size:16px;font-weight:400;line-height:24px;text-align:left;color:#555555;">${paragraphs} <h3 style="font-weight: 600; margin-top: 20px; margin-bottom: 0">
|
|
2991
|
+
<a href="${threadUrl}" style="color: ${colorAccent}; text-decoration: underline">link</a>
|
|
2992
|
+
</h3>
|
|
2993
|
+
</div>
|
|
2994
|
+
</td>
|
|
2995
|
+
</tr>
|
|
2996
|
+
</tbody>
|
|
2997
|
+
</table>
|
|
2998
|
+
</div>
|
|
2999
|
+
<!--[if mso | IE]></td></tr></table><![endif]-->
|
|
3000
|
+
</td>
|
|
3001
|
+
</tr>
|
|
3002
|
+
</tbody>
|
|
3003
|
+
</table>
|
|
3004
|
+
</div>
|
|
3005
|
+
<!--[if mso | IE]></td></tr></table><![endif]-->
|
|
3006
|
+
</div>
|
|
3007
|
+
</body>
|
|
3008
|
+
|
|
3009
|
+
</html>
|
|
3010
|
+
`;
|
|
3011
|
+
}
|
|
3012
|
+
|
|
3013
|
+
const Text = props => {
|
|
3014
|
+
const label = bomMixerHooks.useLabel();
|
|
3015
|
+
const html = react.useMemo(() => {
|
|
3016
|
+
return marked.marked.parse(props.body);
|
|
3017
|
+
}, [props.body]);
|
|
3018
|
+
const disclaimer = props.disclaimer ? label('llm.disclaimer') : '';
|
|
3019
|
+
return jsxRuntime.jsxs("div", {
|
|
3020
|
+
className: "llm__text",
|
|
3021
|
+
children: [jsxRuntime.jsx("div", {
|
|
3022
|
+
className: "llm__text-body",
|
|
3023
|
+
dangerouslySetInnerHTML: {
|
|
3024
|
+
__html: html
|
|
3025
|
+
}
|
|
3026
|
+
}), disclaimer && jsxRuntime.jsxs("small", {
|
|
3027
|
+
className: "llm__text-disclaimer",
|
|
3028
|
+
children: [jsxRuntime.jsx("i", {
|
|
3029
|
+
children: jsxRuntime.jsx(bomMixerIcons.IconLlmInfoCircle, {})
|
|
3030
|
+
}), jsxRuntime.jsx("div", {
|
|
3031
|
+
dangerouslySetInnerHTML: {
|
|
3032
|
+
__html: disclaimer
|
|
3033
|
+
}
|
|
3034
|
+
})]
|
|
3035
|
+
})]
|
|
3036
|
+
});
|
|
3037
|
+
};
|
|
3038
|
+
|
|
3039
|
+
const FormRecapError = () => {
|
|
3040
|
+
const label = bomMixerHooks.useLabel();
|
|
3041
|
+
return jsxRuntime.jsx(Text, {
|
|
3042
|
+
body: label('llm.formRecapError')
|
|
3043
|
+
});
|
|
3044
|
+
};
|
|
3045
|
+
|
|
3046
|
+
const FormRecapSuccess = () => {
|
|
3047
|
+
const label = bomMixerHooks.useLabel();
|
|
3048
|
+
return jsxRuntime.jsx(Text, {
|
|
3049
|
+
body: label('llm.formRecapSuccess')
|
|
3050
|
+
});
|
|
3051
|
+
};
|
|
3052
|
+
|
|
3053
|
+
const FormRequest = _ref => {
|
|
3054
|
+
let {
|
|
3055
|
+
last
|
|
3056
|
+
} = _ref;
|
|
3057
|
+
const label = bomMixerHooks.useLabel();
|
|
3058
|
+
const {
|
|
3059
|
+
formRequest
|
|
3060
|
+
} = useLlm(state => state.actions);
|
|
3061
|
+
return jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
3062
|
+
children: [jsxRuntime.jsx(Text, {
|
|
3063
|
+
body: label('llm.formRequestTitle')
|
|
3064
|
+
}), last && jsxRuntime.jsxs("div", {
|
|
3065
|
+
className: "llm__ctas",
|
|
3066
|
+
children: [jsxRuntime.jsx(Cta, {
|
|
3067
|
+
type: "simple",
|
|
3068
|
+
label: label('llm.formRequestYes'),
|
|
3069
|
+
onClick: () => formRequest(true)
|
|
3070
|
+
}), jsxRuntime.jsx(Cta, {
|
|
3071
|
+
type: "simple",
|
|
3072
|
+
label: label('llm.formRequestNo'),
|
|
3073
|
+
onClick: () => formRequest(false)
|
|
3074
|
+
})]
|
|
3075
|
+
})]
|
|
3076
|
+
});
|
|
3077
|
+
};
|
|
3078
|
+
|
|
3079
|
+
const Poi = props => {
|
|
3080
|
+
const label = bomMixerHooks.useLabel();
|
|
3081
|
+
const {
|
|
3082
|
+
send,
|
|
3083
|
+
decorateUrl
|
|
3084
|
+
} = useLlm(state => state.actions);
|
|
3085
|
+
const onTellMeMore = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
3086
|
+
const prompt = `${label('llm.tellMeMoreAbout')} ${props.title}`;
|
|
3087
|
+
yield send(prompt, response => {
|
|
3088
|
+
// console.log('Prompt.onChunk', response.chunks);
|
|
3089
|
+
}, response => {
|
|
3090
|
+
// console.log('Prompt.onEnd', response);
|
|
3091
|
+
});
|
|
3092
|
+
});
|
|
3093
|
+
const onGoToWebsite = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
3094
|
+
if (bomCore.isBrowser) {
|
|
3095
|
+
const url = yield decorateUrl(props, props.url);
|
|
3096
|
+
window.open(url, '_blank');
|
|
3097
|
+
}
|
|
3098
|
+
});
|
|
3099
|
+
const classNames = bomCore.getClassNames('llm__poi', {
|
|
3100
|
+
[`llm__poi--${props.type}`]: !!props.type
|
|
3101
|
+
});
|
|
3102
|
+
return jsxRuntime.jsxs("div", {
|
|
3103
|
+
className: classNames,
|
|
3104
|
+
children: [props.image && jsxRuntime.jsx("div", {
|
|
3105
|
+
className: "llm__poi-media",
|
|
3106
|
+
children: jsxRuntime.jsx("img", {
|
|
3107
|
+
src: props.image,
|
|
3108
|
+
alt: props.title
|
|
3109
|
+
})
|
|
3110
|
+
}), jsxRuntime.jsxs("div", {
|
|
3111
|
+
className: "llm__poi-content",
|
|
3112
|
+
children: [props.title && jsxRuntime.jsx("div", {
|
|
3113
|
+
className: "llm__poi-title",
|
|
3114
|
+
dangerouslySetInnerHTML: {
|
|
3115
|
+
__html: props.title
|
|
3116
|
+
}
|
|
3117
|
+
}), props.abstract && jsxRuntime.jsx("div", {
|
|
3118
|
+
className: "llm__poi-body",
|
|
3119
|
+
dangerouslySetInnerHTML: {
|
|
3120
|
+
__html: props.abstract
|
|
3121
|
+
}
|
|
3122
|
+
}), (props.time || props.place) && jsxRuntime.jsxs("div", {
|
|
3123
|
+
className: "llm__poi-tags",
|
|
3124
|
+
children: [props.time && jsxRuntime.jsxs("div", {
|
|
3125
|
+
className: "llm__poi-tag llm__poi-time",
|
|
3126
|
+
children: [jsxRuntime.jsx(bomMixerIcons.IconLlmTimetable, {}), props.time]
|
|
3127
|
+
}), props.place && jsxRuntime.jsxs("div", {
|
|
3128
|
+
className: "llm__poi-tag llm__poi-location",
|
|
3129
|
+
children: [jsxRuntime.jsx(bomMixerIcons.IconLlmPin, {}), props.place]
|
|
3130
|
+
})]
|
|
3131
|
+
}), jsxRuntime.jsxs("div", {
|
|
3132
|
+
className: "llm__poi-ctas",
|
|
3133
|
+
children: [jsxRuntime.jsx(Cta, {
|
|
3134
|
+
type: "button",
|
|
3135
|
+
label: label('llm.tellMeMore'),
|
|
3136
|
+
onClick: onTellMeMore
|
|
3137
|
+
}), jsxRuntime.jsx(Cta, {
|
|
3138
|
+
type: "text",
|
|
3139
|
+
label: label('llm.goToWebsite'),
|
|
3140
|
+
onClick: onGoToWebsite
|
|
3141
|
+
})]
|
|
3142
|
+
})]
|
|
3143
|
+
})]
|
|
3144
|
+
});
|
|
3145
|
+
};
|
|
3146
|
+
|
|
3147
|
+
const PoiGroup = props => {
|
|
3148
|
+
const classNames = bomCore.getClassNames('llm__pois');
|
|
3149
|
+
return jsxRuntime.jsx("div", {
|
|
3150
|
+
className: classNames,
|
|
3151
|
+
children: props.items.map((item, i) => jsxRuntime.jsx(Poi, Object.assign({}, item), i))
|
|
3152
|
+
});
|
|
3153
|
+
};
|
|
3154
|
+
|
|
3155
|
+
const TripAdvisor = props => {
|
|
3156
|
+
const label = bomMixerHooks.useLabel();
|
|
3157
|
+
const {
|
|
3158
|
+
decorateUrl
|
|
3159
|
+
} = useLlm(state => state.actions);
|
|
3160
|
+
const onGoToWebsite = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
3161
|
+
if (bomCore.isBrowser) {
|
|
3162
|
+
const url = yield decorateUrl(props, props.url);
|
|
3163
|
+
window.open(url, '_blank');
|
|
3164
|
+
}
|
|
3165
|
+
});
|
|
3166
|
+
return jsxRuntime.jsx("div", {
|
|
3167
|
+
className: "llm__tripadv",
|
|
3168
|
+
children: jsxRuntime.jsxs("div", {
|
|
3169
|
+
className: "llm__tripadv-inner",
|
|
3170
|
+
children: [props.image && jsxRuntime.jsx("div", {
|
|
3171
|
+
className: "llm__tripadv-media",
|
|
3172
|
+
children: jsxRuntime.jsx("img", {
|
|
3173
|
+
src: props.image,
|
|
3174
|
+
alt: props.title
|
|
3175
|
+
})
|
|
3176
|
+
}), jsxRuntime.jsxs("div", {
|
|
3177
|
+
className: "llm__tripadv-content",
|
|
3178
|
+
children: [props.title && jsxRuntime.jsx("div", {
|
|
3179
|
+
className: "llm__tripadv-title",
|
|
3180
|
+
children: props.title
|
|
3181
|
+
}), props.rating && jsxRuntime.jsxs("div", {
|
|
3182
|
+
className: "llm__tripadv-rating",
|
|
3183
|
+
children: [jsxRuntime.jsx("span", {
|
|
3184
|
+
className: "llm__tripadv-dots",
|
|
3185
|
+
children: jsxRuntime.jsx("span", {
|
|
3186
|
+
style: {
|
|
3187
|
+
width: `${props.rating / 5 * 100}%`
|
|
3188
|
+
}
|
|
3189
|
+
})
|
|
3190
|
+
}), props.reviews && jsxRuntime.jsxs("span", {
|
|
3191
|
+
children: [props.reviews, " ", label('llm.reviews')]
|
|
3192
|
+
})]
|
|
3193
|
+
}), jsxRuntime.jsx("div", {
|
|
3194
|
+
className: "llm__tripadv-info",
|
|
3195
|
+
children: jsxRuntime.jsxs("span", {
|
|
3196
|
+
className: "llm__tripadv-cuisine",
|
|
3197
|
+
children: [`${props.priceRange}, `, props.cuisine]
|
|
3198
|
+
})
|
|
3199
|
+
}), props.address && jsxRuntime.jsxs("div", {
|
|
3200
|
+
className: "llm__tripadv-location",
|
|
3201
|
+
children: [jsxRuntime.jsx(bomMixerIcons.IconLlmPin, {}), " ", props.address]
|
|
3202
|
+
}), jsxRuntime.jsxs("div", {
|
|
3203
|
+
className: "llm__tripadv-ctas",
|
|
3204
|
+
children: [props.book && jsxRuntime.jsx(Cta, {
|
|
3205
|
+
type: "button",
|
|
3206
|
+
url: props.book,
|
|
3207
|
+
target: "_blank",
|
|
3208
|
+
label: label('llm.bookNow')
|
|
3209
|
+
}), jsxRuntime.jsx(Cta, {
|
|
3210
|
+
type: "text",
|
|
3211
|
+
label: label('llm.goToWebsite'),
|
|
3212
|
+
onClick: onGoToWebsite
|
|
3213
|
+
})]
|
|
3214
|
+
}), jsxRuntime.jsx("div", {
|
|
3215
|
+
className: "llm__tripadv-icon",
|
|
3216
|
+
children: jsxRuntime.jsxs("svg", {
|
|
3217
|
+
role: "img",
|
|
3218
|
+
viewBox: "0 0 24 24",
|
|
3219
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3220
|
+
children: [jsxRuntime.jsx("title", {
|
|
3221
|
+
children: "Tripadvisor"
|
|
3222
|
+
}), jsxRuntime.jsx("path", {
|
|
3223
|
+
d: "M12.006 4.295c-2.67 0-5.338.784-7.645 2.353H0l1.963 2.135a5.997 5.997 0 0 0 4.04 10.43 5.976 5.976 0 0 0 4.075-1.6L12 19.705l1.922-2.09a5.972 5.972 0 0 0 4.072 1.598 6 6 0 0 0 6-5.998 5.982 5.982 0 0 0-1.957-4.432L24 6.648h-4.35a13.573 13.573 0 0 0-7.644-2.353zM12 6.255c1.531 0 3.063.303 4.504.903C13.943 8.138 12 10.43 12 13.1c0-2.671-1.942-4.962-4.504-5.942A11.72 11.72 0 0 1 12 6.256zM6.002 9.157a4.059 4.059 0 1 1 0 8.118 4.059 4.059 0 0 1 0-8.118zm11.992.002a4.057 4.057 0 1 1 .003 8.115 4.057 4.057 0 0 1-.003-8.115zm-11.992 1.93a2.128 2.128 0 0 0 0 4.256 2.128 2.128 0 0 0 0-4.256zm11.992 0a2.128 2.128 0 0 0 0 4.256 2.128 2.128 0 0 0 0-4.256z"
|
|
3224
|
+
})]
|
|
3225
|
+
})
|
|
3226
|
+
})]
|
|
3227
|
+
})]
|
|
3228
|
+
})
|
|
3229
|
+
});
|
|
3230
|
+
};
|
|
3231
|
+
const TripAdvisorGroup = props => {
|
|
3232
|
+
const classNames = bomCore.getClassNames('llm__tripadvisor-group');
|
|
3233
|
+
return jsxRuntime.jsx("div", {
|
|
3234
|
+
className: classNames,
|
|
3235
|
+
children: props.items.map((item, i) => jsxRuntime.jsx(TripAdvisor, Object.assign({}, item), i))
|
|
3236
|
+
});
|
|
3237
|
+
};
|
|
3238
|
+
|
|
3239
|
+
const Chunk = _ref => {
|
|
3240
|
+
let {
|
|
3241
|
+
item,
|
|
3242
|
+
index,
|
|
3243
|
+
total
|
|
3244
|
+
} = _ref;
|
|
3245
|
+
switch (item.type) {
|
|
3246
|
+
case 'string':
|
|
3247
|
+
{
|
|
3248
|
+
return item.content.length > 0 && jsxRuntime.jsx(Text, {
|
|
3249
|
+
body: item.content,
|
|
3250
|
+
disclaimer: index === 0
|
|
3251
|
+
});
|
|
3252
|
+
}
|
|
3253
|
+
case 'event':
|
|
3254
|
+
case 'eventItem':
|
|
3255
|
+
{
|
|
3256
|
+
return jsxRuntime.jsx(Event, Object.assign({}, item));
|
|
3257
|
+
}
|
|
3258
|
+
case 'eventGroup':
|
|
3259
|
+
return jsxRuntime.jsx(EventGroup, Object.assign({}, item));
|
|
3260
|
+
case 'poi':
|
|
3261
|
+
case 'poiItem':
|
|
3262
|
+
{
|
|
3263
|
+
return jsxRuntime.jsx(Poi, Object.assign({}, item));
|
|
3264
|
+
}
|
|
3265
|
+
case 'poiGroup':
|
|
3266
|
+
return jsxRuntime.jsx(PoiGroup, Object.assign({}, item));
|
|
3267
|
+
case 'tripadvisorGroup':
|
|
3268
|
+
return jsxRuntime.jsx(TripAdvisorGroup, Object.assign({}, item));
|
|
3269
|
+
case 'formRequest':
|
|
3270
|
+
return jsxRuntime.jsx(FormRequest, {
|
|
3271
|
+
last: index === total - 1
|
|
3272
|
+
});
|
|
3273
|
+
case 'formRecap':
|
|
3274
|
+
return jsxRuntime.jsx(FormRecap, {});
|
|
3275
|
+
case 'formRecapSuccess':
|
|
3276
|
+
return jsxRuntime.jsx(FormRecapSuccess, {});
|
|
3277
|
+
case 'formRecapError':
|
|
3278
|
+
return jsxRuntime.jsx(FormRecapError, {});
|
|
3279
|
+
case 'image':
|
|
3280
|
+
return jsxRuntime.jsx("img", {
|
|
3281
|
+
src: item.src
|
|
3282
|
+
});
|
|
3283
|
+
default:
|
|
3284
|
+
return jsxRuntime.jsx("code", {
|
|
3285
|
+
children: JSON.stringify(item)
|
|
3286
|
+
});
|
|
3287
|
+
}
|
|
3288
|
+
};
|
|
3289
|
+
|
|
3290
|
+
const BusyIndicator = () => {
|
|
3291
|
+
return jsxRuntime.jsx(framerMotion.motion.div, {
|
|
3292
|
+
className: "llm__busyIndicator",
|
|
3293
|
+
initial: {
|
|
3294
|
+
opacity: 0,
|
|
3295
|
+
y: 10
|
|
3296
|
+
},
|
|
3297
|
+
animate: {
|
|
3298
|
+
opacity: 1,
|
|
3299
|
+
y: 0
|
|
3300
|
+
},
|
|
3301
|
+
transition: {
|
|
3302
|
+
duration: 1
|
|
3303
|
+
},
|
|
3304
|
+
children: jsxRuntime.jsx("span", {})
|
|
3305
|
+
});
|
|
3306
|
+
};
|
|
3307
|
+
|
|
3308
|
+
const Stream = props => {
|
|
3309
|
+
const messages = useLlm(state => state.messages);
|
|
3310
|
+
const chunks = useLlm(state => state.chunks);
|
|
3311
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
3312
|
+
children: chunks && jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
3313
|
+
children: jsxRuntime.jsx("div", {
|
|
3314
|
+
className: "llm__message llm__message--assistant llm-row",
|
|
3315
|
+
children: jsxRuntime.jsxs(framerMotion.AnimatePresence, {
|
|
3316
|
+
children: [chunks.map((chunk, c) => jsxRuntime.jsx("div", {
|
|
3317
|
+
className: `llm__inner llm__inner--${chunk.type}`,
|
|
3318
|
+
children: jsxRuntime.jsx(framerMotion.motion.div, {
|
|
3319
|
+
initial: {
|
|
3320
|
+
opacity: 0,
|
|
3321
|
+
y: 10
|
|
3322
|
+
},
|
|
3323
|
+
animate: {
|
|
3324
|
+
opacity: 1,
|
|
3325
|
+
y: 0
|
|
3326
|
+
},
|
|
3327
|
+
transition: {
|
|
3328
|
+
duration: 1
|
|
3329
|
+
},
|
|
3330
|
+
children: jsxRuntime.jsx(Chunk, {
|
|
3331
|
+
item: chunk,
|
|
3332
|
+
index: messages.length,
|
|
3333
|
+
total: messages.length + 1
|
|
3334
|
+
})
|
|
3335
|
+
})
|
|
3336
|
+
}, c)), jsxRuntime.jsx(BusyIndicator, {})]
|
|
3337
|
+
})
|
|
3338
|
+
})
|
|
3339
|
+
})
|
|
3340
|
+
});
|
|
3341
|
+
};
|
|
3342
|
+
|
|
3343
|
+
const Thread = () => {
|
|
3344
|
+
const messages = useLlm(state => state.messages);
|
|
3345
|
+
return jsxRuntime.jsxs("div", {
|
|
3346
|
+
className: "llm__thread llm-container",
|
|
3347
|
+
children: [messages.map((message, m) => jsxRuntime.jsx("div", {
|
|
3348
|
+
className: bomCore.getClassNames('llm__message', `llm__message--${message.role}`, 'llm-row'),
|
|
3349
|
+
children: message.chunks.map((chunk, c) => jsxRuntime.jsx("div", {
|
|
3350
|
+
className: `llm__inner llm__inner--${chunk.type}`,
|
|
3351
|
+
children: jsxRuntime.jsx(Chunk, {
|
|
3352
|
+
item: chunk,
|
|
3353
|
+
index: m,
|
|
3354
|
+
total: messages.length
|
|
3355
|
+
})
|
|
3356
|
+
}, c))
|
|
3357
|
+
}, m)), jsxRuntime.jsx(Stream, {})]
|
|
3358
|
+
});
|
|
3359
|
+
};
|
|
3360
|
+
|
|
3361
|
+
const Main = () => {
|
|
3362
|
+
var _a;
|
|
3363
|
+
const lenisRef = react.useRef(null);
|
|
3364
|
+
const {
|
|
3365
|
+
messages,
|
|
3366
|
+
speakEnabled
|
|
3367
|
+
} = useLlm(state => state);
|
|
3368
|
+
const {
|
|
3369
|
+
setLenis,
|
|
3370
|
+
toggleSpeak
|
|
3371
|
+
} = useLlm(state => state.actions);
|
|
3372
|
+
const classNames = bomCore.getClassNames('llm__main');
|
|
3373
|
+
setLenis((_a = lenisRef.current) === null || _a === void 0 ? void 0 : _a.lenis);
|
|
3374
|
+
const reveal = {
|
|
3375
|
+
hidden: {
|
|
3376
|
+
opacity: 0,
|
|
3377
|
+
scale: .98
|
|
3378
|
+
},
|
|
3379
|
+
show: {
|
|
3380
|
+
opacity: 1,
|
|
3381
|
+
scale: 1,
|
|
3382
|
+
transition: {
|
|
3383
|
+
duration: .3
|
|
3384
|
+
}
|
|
3385
|
+
},
|
|
3386
|
+
exit: {
|
|
3387
|
+
opacity: 0,
|
|
3388
|
+
transition: {
|
|
3389
|
+
duration: .3,
|
|
3390
|
+
delay: .3
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
};
|
|
3394
|
+
const intro = {
|
|
3395
|
+
hidden: {
|
|
3396
|
+
opacity: 0
|
|
3397
|
+
},
|
|
3398
|
+
show: {
|
|
3399
|
+
opacity: 1,
|
|
3400
|
+
transition: {
|
|
3401
|
+
delay: .6,
|
|
3402
|
+
duration: .5
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
};
|
|
3406
|
+
const slideIn = direction => ({
|
|
3407
|
+
hidden: {
|
|
3408
|
+
y: `${100 * direction}%`
|
|
3409
|
+
},
|
|
3410
|
+
show: {
|
|
3411
|
+
y: 0,
|
|
3412
|
+
transition: {
|
|
3413
|
+
type: 'tween',
|
|
3414
|
+
delay: 1.2,
|
|
3415
|
+
duration: .6
|
|
3416
|
+
}
|
|
3417
|
+
},
|
|
3418
|
+
exit: {
|
|
3419
|
+
y: `${100 * direction}%`,
|
|
3420
|
+
transition: {
|
|
3421
|
+
type: 'tween',
|
|
3422
|
+
duration: .3
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
});
|
|
3426
|
+
return jsxRuntime.jsxs(framerMotion.motion.div, {
|
|
3427
|
+
variants: reveal,
|
|
3428
|
+
initial: "hidden",
|
|
3429
|
+
animate: "show",
|
|
3430
|
+
exit: "exit",
|
|
3431
|
+
className: classNames,
|
|
3432
|
+
children: [jsxRuntime.jsx("button", {
|
|
3433
|
+
className: "llm__toggle-speak",
|
|
3434
|
+
onClick: toggleSpeak,
|
|
3435
|
+
children: speakEnabled ? jsxRuntime.jsx(bomMixerIcons.IconLlmSpeakDisabled, {}) : jsxRuntime.jsx(bomMixerIcons.IconLlmSpeakEnabled, {})
|
|
3436
|
+
}), jsxRuntime.jsx(Canvas, {}), jsxRuntime.jsx(framerMotion.motion.div, {
|
|
3437
|
+
className: "llm__top",
|
|
3438
|
+
variants: slideIn(-1),
|
|
3439
|
+
initial: "hidden",
|
|
3440
|
+
animate: "show",
|
|
3441
|
+
exit: "exit",
|
|
3442
|
+
children: jsxRuntime.jsx(Header, {})
|
|
3443
|
+
}), jsxRuntime.jsx(reactLenis.ReactLenis, {
|
|
3444
|
+
ref: lenisRef,
|
|
3445
|
+
className: "llm__scroller",
|
|
3446
|
+
children: jsxRuntime.jsxs(framerMotion.motion.div, {
|
|
3447
|
+
variants: intro,
|
|
3448
|
+
initial: "hidden",
|
|
3449
|
+
animate: "show",
|
|
3450
|
+
className: "llm__content",
|
|
3451
|
+
children: [jsxRuntime.jsx(Intro, {}), messages && messages.length > 0 && jsxRuntime.jsx(Thread, {})]
|
|
3452
|
+
})
|
|
3453
|
+
}), jsxRuntime.jsx(framerMotion.motion.div, {
|
|
3454
|
+
className: "llm__bottom",
|
|
3455
|
+
variants: slideIn(1),
|
|
3456
|
+
initial: "hidden",
|
|
3457
|
+
animate: "show",
|
|
3458
|
+
exit: "exit",
|
|
3459
|
+
children: jsxRuntime.jsx(Prompt, {})
|
|
3460
|
+
})]
|
|
3461
|
+
}, "main-container");
|
|
3462
|
+
};
|
|
3463
|
+
|
|
3464
|
+
const Trigger = () => {
|
|
3465
|
+
const {
|
|
3466
|
+
open
|
|
3467
|
+
} = useLlm(state => state.actions);
|
|
3468
|
+
const app = useLlm(state => state.app);
|
|
3469
|
+
const label = bomMixerHooks.useLabel();
|
|
3470
|
+
return jsxRuntime.jsxs(framerMotion.motion.div, {
|
|
3471
|
+
initial: {
|
|
3472
|
+
y: '200%',
|
|
3473
|
+
opacity: 0
|
|
3474
|
+
},
|
|
3475
|
+
animate: {
|
|
3476
|
+
y: 0,
|
|
3477
|
+
opacity: 1
|
|
3478
|
+
},
|
|
3479
|
+
exit: {
|
|
3480
|
+
y: '200%',
|
|
3481
|
+
opacity: 0
|
|
3482
|
+
},
|
|
3483
|
+
transition: {
|
|
3484
|
+
duration: .4
|
|
3485
|
+
},
|
|
3486
|
+
className: "llm__trigger",
|
|
3487
|
+
onClick: () => open(),
|
|
3488
|
+
children: [jsxRuntime.jsxs("button", {
|
|
3489
|
+
className: bomCore.getClassNames('llm__trigger-btn', {
|
|
3490
|
+
'llm__trigger-btn--hover': app === null || app === void 0 ? void 0 : app.contents.collapsedWelcomeTextHover
|
|
3491
|
+
}),
|
|
3492
|
+
children: [jsxRuntime.jsx(Blob, {}), jsxRuntime.jsx("span", {
|
|
3493
|
+
children: label('llm.button')
|
|
3494
|
+
})]
|
|
3495
|
+
}), jsxRuntime.jsxs("div", {
|
|
3496
|
+
className: "llm__trigger-welcome -llm-t-body-2",
|
|
3497
|
+
children: [jsxRuntime.jsxs(framerMotion.motion.div, {
|
|
3498
|
+
exit: {
|
|
3499
|
+
opacity: 0
|
|
3500
|
+
},
|
|
3501
|
+
children: [jsxRuntime.jsx(Background, {}), jsxRuntime.jsx(Nl2Br, {
|
|
3502
|
+
text: app === null || app === void 0 ? void 0 : app.contents.collapsedWelcomeText
|
|
3503
|
+
})]
|
|
3504
|
+
}), (app === null || app === void 0 ? void 0 : app.contents.collapsedWelcomeTextHover) && jsxRuntime.jsxs(framerMotion.motion.div, {
|
|
3505
|
+
exit: {
|
|
3506
|
+
opacity: 0
|
|
3507
|
+
},
|
|
3508
|
+
children: [jsxRuntime.jsx(Background, {}), jsxRuntime.jsx(Nl2Br, {
|
|
3509
|
+
text: app === null || app === void 0 ? void 0 : app.contents.collapsedWelcomeTextHover
|
|
3510
|
+
})]
|
|
3511
|
+
})]
|
|
3512
|
+
})]
|
|
3513
|
+
});
|
|
3514
|
+
};
|
|
3515
|
+
|
|
3516
|
+
const LlmComponent = props => {
|
|
3517
|
+
const {
|
|
3518
|
+
locale
|
|
3519
|
+
} = bomMixerHooks.useLayout();
|
|
3520
|
+
const {
|
|
3521
|
+
init
|
|
3522
|
+
} = useLlm(state => state.actions);
|
|
3523
|
+
const app = useLlm(state => state.app);
|
|
3524
|
+
const idle = useLlm(state => state.idle);
|
|
3525
|
+
const opened = useLlm(state => state.opened);
|
|
3526
|
+
react.useEffect(() => {
|
|
3527
|
+
init(locale);
|
|
3528
|
+
}, [init, locale]);
|
|
3529
|
+
react.useEffect(() => {
|
|
3530
|
+
document.documentElement.style.overflow = opened ? 'hidden' : 'auto';
|
|
3531
|
+
}, [opened]);
|
|
3532
|
+
const mounted = bomMixerHooks.useMounted();
|
|
3533
|
+
const classNames = bomCore.getClassNames('llm', {
|
|
3534
|
+
'-open': opened
|
|
3535
|
+
});
|
|
3536
|
+
if (mounted) {
|
|
3537
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
3538
|
+
children: app && jsxRuntime.jsx("div", Object.assign({
|
|
3539
|
+
className: classNames
|
|
3540
|
+
}, props, {
|
|
3541
|
+
children: jsxRuntime.jsxs(framerMotion.AnimatePresence, {
|
|
3542
|
+
mode: "wait",
|
|
3543
|
+
initial: false,
|
|
3544
|
+
children: [!opened && !idle && jsxRuntime.jsx(Trigger, {}), opened && jsxRuntime.jsx(Main, {})]
|
|
3545
|
+
})
|
|
3546
|
+
}))
|
|
3547
|
+
});
|
|
3548
|
+
} else {
|
|
3549
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
3550
|
+
}
|
|
3551
|
+
};
|
|
3552
|
+
|
|
3553
|
+
exports.LlmComponent = LlmComponent;
|
|
3554
|
+
exports.LlmContext = LlmContext;
|
|
3555
|
+
exports.LlmProvider = LlmProvider;
|
|
3556
|
+
exports.MessageService = MessageService;
|
|
3557
|
+
exports.chunksToChunkItems = chunksToChunkItems;
|
|
3558
|
+
exports.chunksToResponse = chunksToResponse;
|
|
3559
|
+
exports.decodeMessages = decodeMessages;
|
|
3560
|
+
exports.getMockApp = getMockApp;
|
|
3561
|
+
exports.getMockChunks = getMockChunks;
|
|
3562
|
+
exports.getMockPrompt = getMockPrompt;
|
|
3563
|
+
exports.shouldAddFormRequest = shouldAddFormRequest;
|
|
3564
|
+
exports.textToChunks = textToChunks;
|
|
3565
|
+
exports.useLlm = useLlm;
|
|
3566
|
+
//# sourceMappingURL=index.js.map
|