@akropolys/kiku 1.7.7 → 1.7.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +675 -418
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +667 -410
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +285 -0
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -794,7 +794,7 @@ I couldn't find any matching products in the store.`;
|
|
|
794
794
|
}
|
|
795
795
|
|
|
796
796
|
// src/components/KikuButton.tsx
|
|
797
|
-
import { useState as
|
|
797
|
+
import { useState as useState6, useEffect as useEffect4, useRef as useRef6, useCallback as useCallback2 } from "react";
|
|
798
798
|
import { createPortal } from "react-dom";
|
|
799
799
|
import { useKiku as useKiku2 } from "@akropolys/sdk";
|
|
800
800
|
import { useAkropolysContext as useAkropolysContext3 } from "@akropolys/sdk";
|
|
@@ -1107,9 +1107,226 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES", displayConfig }) {
|
|
|
1107
1107
|
);
|
|
1108
1108
|
}
|
|
1109
1109
|
|
|
1110
|
+
// src/components/MarkupEditor.tsx
|
|
1111
|
+
import { useEffect as useEffect3, useRef as useRef5, useState as useState5 } from "react";
|
|
1112
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1113
|
+
var COLORS = ["#111111", "#ff5a5a", "#ffb300", "#22c55e", "#06b6d4", "#d946ef", "#9ca3af"];
|
|
1114
|
+
var MAX_EXPORT_DIM = 1280;
|
|
1115
|
+
function MarkupEditor({ src, onCancel, onSend }) {
|
|
1116
|
+
const [img, setImg] = useState5(null);
|
|
1117
|
+
const [loadError, setLoadError] = useState5(false);
|
|
1118
|
+
const [tool, setTool] = useState5("pen");
|
|
1119
|
+
const [color, setColor] = useState5(COLORS[1]);
|
|
1120
|
+
const [actions, setActions] = useState5([]);
|
|
1121
|
+
const [pendingText, setPendingText] = useState5(null);
|
|
1122
|
+
const [textValue, setTextValue] = useState5("");
|
|
1123
|
+
const [instruction, setInstruction] = useState5("");
|
|
1124
|
+
const [exportError, setExportError] = useState5(false);
|
|
1125
|
+
const canvasRef = useRef5(null);
|
|
1126
|
+
const drawingRef = useRef5(null);
|
|
1127
|
+
const textInputRef = useRef5(null);
|
|
1128
|
+
useEffect3(() => {
|
|
1129
|
+
const el = new Image();
|
|
1130
|
+
el.crossOrigin = "anonymous";
|
|
1131
|
+
el.onload = () => setImg(el);
|
|
1132
|
+
el.onerror = () => setLoadError(true);
|
|
1133
|
+
el.src = src;
|
|
1134
|
+
}, [src]);
|
|
1135
|
+
const dims = (() => {
|
|
1136
|
+
if (!img) return { w: 0, h: 0 };
|
|
1137
|
+
const scale = Math.min(1, MAX_EXPORT_DIM / Math.max(img.naturalWidth, img.naturalHeight));
|
|
1138
|
+
return { w: Math.round(img.naturalWidth * scale), h: Math.round(img.naturalHeight * scale) };
|
|
1139
|
+
})();
|
|
1140
|
+
const markLayer = useRef5(null);
|
|
1141
|
+
const paint = (live) => {
|
|
1142
|
+
const canvas = canvasRef.current;
|
|
1143
|
+
if (!canvas || !img) return;
|
|
1144
|
+
const ctx = canvas.getContext("2d");
|
|
1145
|
+
if (!ctx) return;
|
|
1146
|
+
if (!markLayer.current) markLayer.current = document.createElement("canvas");
|
|
1147
|
+
const layer = markLayer.current;
|
|
1148
|
+
layer.width = canvas.width;
|
|
1149
|
+
layer.height = canvas.height;
|
|
1150
|
+
const lctx = layer.getContext("2d");
|
|
1151
|
+
const all = live ? [...actions, live] : actions;
|
|
1152
|
+
for (const a of all) {
|
|
1153
|
+
if (a.kind === "stroke") {
|
|
1154
|
+
lctx.save();
|
|
1155
|
+
lctx.globalCompositeOperation = a.tool === "eraser" ? "destination-out" : "source-over";
|
|
1156
|
+
lctx.strokeStyle = a.color;
|
|
1157
|
+
lctx.lineWidth = a.tool === "eraser" ? a.size * 3 : a.size;
|
|
1158
|
+
lctx.lineCap = "round";
|
|
1159
|
+
lctx.lineJoin = "round";
|
|
1160
|
+
lctx.beginPath();
|
|
1161
|
+
a.points.forEach((p, i) => i === 0 ? lctx.moveTo(p.x, p.y) : lctx.lineTo(p.x, p.y));
|
|
1162
|
+
if (a.points.length === 1) lctx.lineTo(a.points[0].x + 0.01, a.points[0].y);
|
|
1163
|
+
lctx.stroke();
|
|
1164
|
+
lctx.restore();
|
|
1165
|
+
} else {
|
|
1166
|
+
lctx.save();
|
|
1167
|
+
lctx.fillStyle = a.color;
|
|
1168
|
+
lctx.font = `600 ${a.size}px system-ui, sans-serif`;
|
|
1169
|
+
lctx.fillText(a.value, a.x, a.y);
|
|
1170
|
+
lctx.restore();
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
1174
|
+
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
|
1175
|
+
ctx.drawImage(layer, 0, 0);
|
|
1176
|
+
};
|
|
1177
|
+
useEffect3(() => {
|
|
1178
|
+
paint();
|
|
1179
|
+
}, [img, actions, dims.w, dims.h]);
|
|
1180
|
+
useEffect3(() => {
|
|
1181
|
+
if (pendingText) textInputRef.current?.focus();
|
|
1182
|
+
}, [pendingText]);
|
|
1183
|
+
const toCanvasPoint = (e) => {
|
|
1184
|
+
const canvas = canvasRef.current;
|
|
1185
|
+
const rect = canvas.getBoundingClientRect();
|
|
1186
|
+
return {
|
|
1187
|
+
x: (e.clientX - rect.left) / rect.width * canvas.width,
|
|
1188
|
+
y: (e.clientY - rect.top) / rect.height * canvas.height
|
|
1189
|
+
};
|
|
1190
|
+
};
|
|
1191
|
+
const strokeSize = () => Math.max(4, Math.round(dims.w / 180));
|
|
1192
|
+
const textSize = () => Math.max(18, Math.round(dims.w / 28));
|
|
1193
|
+
const onPointerDown = (e) => {
|
|
1194
|
+
if (!img) return;
|
|
1195
|
+
const p = toCanvasPoint(e);
|
|
1196
|
+
if (tool === "text") {
|
|
1197
|
+
setPendingText({ x: p.x, y: p.y });
|
|
1198
|
+
setTextValue("");
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
1201
|
+
e.target.setPointerCapture(e.pointerId);
|
|
1202
|
+
drawingRef.current = { kind: "stroke", tool, color, size: strokeSize(), points: [p] };
|
|
1203
|
+
paint(drawingRef.current);
|
|
1204
|
+
};
|
|
1205
|
+
const onPointerMove = (e) => {
|
|
1206
|
+
if (!drawingRef.current) return;
|
|
1207
|
+
drawingRef.current.points.push(toCanvasPoint(e));
|
|
1208
|
+
paint(drawingRef.current);
|
|
1209
|
+
};
|
|
1210
|
+
const onPointerUp = () => {
|
|
1211
|
+
if (!drawingRef.current) return;
|
|
1212
|
+
const done = drawingRef.current;
|
|
1213
|
+
drawingRef.current = null;
|
|
1214
|
+
setActions((prev) => [...prev, done]);
|
|
1215
|
+
};
|
|
1216
|
+
const commitText = () => {
|
|
1217
|
+
if (pendingText && textValue.trim()) {
|
|
1218
|
+
setActions((prev) => [...prev, { kind: "text", x: pendingText.x, y: pendingText.y, color, value: textValue.trim(), size: textSize() }]);
|
|
1219
|
+
}
|
|
1220
|
+
setPendingText(null);
|
|
1221
|
+
setTextValue("");
|
|
1222
|
+
};
|
|
1223
|
+
const handleSend = () => {
|
|
1224
|
+
const canvas = canvasRef.current;
|
|
1225
|
+
if (!canvas) return;
|
|
1226
|
+
try {
|
|
1227
|
+
paint();
|
|
1228
|
+
const dataUrl = canvas.toDataURL("image/jpeg", 0.92);
|
|
1229
|
+
onSend(dataUrl, instruction.trim());
|
|
1230
|
+
} catch {
|
|
1231
|
+
setExportError(true);
|
|
1232
|
+
}
|
|
1233
|
+
};
|
|
1234
|
+
const hasMarks = actions.length > 0;
|
|
1235
|
+
return /* @__PURE__ */ jsxs6("div", { className: "hsk-markup", role: "dialog", "aria-label": "Mark up image", children: [
|
|
1236
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-markup-head", children: [
|
|
1237
|
+
/* @__PURE__ */ jsx7("span", { className: "hsk-markup-title", children: "Mark where you want the change" }),
|
|
1238
|
+
/* @__PURE__ */ jsx7("button", { className: "hsk-markup-cancel", onClick: onCancel, children: "Cancel" })
|
|
1239
|
+
] }),
|
|
1240
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-markup-stage", children: loadError ? /* @__PURE__ */ jsx7("div", { className: "hsk-markup-error", children: "This image can't be edited here." }) : !img ? /* @__PURE__ */ jsx7("div", { className: "hsk-markup-loading", children: "Loading image\u2026" }) : /* @__PURE__ */ jsxs6("div", { className: "hsk-markup-canvas-wrap", children: [
|
|
1241
|
+
/* @__PURE__ */ jsx7(
|
|
1242
|
+
"canvas",
|
|
1243
|
+
{
|
|
1244
|
+
ref: canvasRef,
|
|
1245
|
+
width: dims.w,
|
|
1246
|
+
height: dims.h,
|
|
1247
|
+
className: `hsk-markup-canvas hsk-markup-canvas--${tool}`,
|
|
1248
|
+
onPointerDown,
|
|
1249
|
+
onPointerMove,
|
|
1250
|
+
onPointerUp,
|
|
1251
|
+
onPointerLeave: onPointerUp
|
|
1252
|
+
}
|
|
1253
|
+
),
|
|
1254
|
+
pendingText && canvasRef.current && /* @__PURE__ */ jsx7(
|
|
1255
|
+
"input",
|
|
1256
|
+
{
|
|
1257
|
+
ref: textInputRef,
|
|
1258
|
+
className: "hsk-markup-textinput",
|
|
1259
|
+
style: {
|
|
1260
|
+
left: `${pendingText.x / dims.w * 100}%`,
|
|
1261
|
+
top: `${pendingText.y / dims.h * 100}%`,
|
|
1262
|
+
color
|
|
1263
|
+
},
|
|
1264
|
+
value: textValue,
|
|
1265
|
+
placeholder: "Type, then Enter",
|
|
1266
|
+
onChange: (e) => setTextValue(e.target.value),
|
|
1267
|
+
onKeyDown: (e) => {
|
|
1268
|
+
if (e.key === "Enter") commitText();
|
|
1269
|
+
if (e.key === "Escape") {
|
|
1270
|
+
setPendingText(null);
|
|
1271
|
+
setTextValue("");
|
|
1272
|
+
}
|
|
1273
|
+
},
|
|
1274
|
+
onBlur: commitText
|
|
1275
|
+
}
|
|
1276
|
+
)
|
|
1277
|
+
] }) }),
|
|
1278
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-markup-tools", children: [
|
|
1279
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-markup-colors", children: COLORS.map((c) => /* @__PURE__ */ jsx7(
|
|
1280
|
+
"button",
|
|
1281
|
+
{
|
|
1282
|
+
className: `hsk-markup-color${color === c ? " hsk-markup-color--on" : ""}`,
|
|
1283
|
+
style: { background: c },
|
|
1284
|
+
onClick: () => {
|
|
1285
|
+
setColor(c);
|
|
1286
|
+
if (tool === "eraser") setTool("pen");
|
|
1287
|
+
},
|
|
1288
|
+
"aria-label": `Colour ${c}`
|
|
1289
|
+
},
|
|
1290
|
+
c
|
|
1291
|
+
)) }),
|
|
1292
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-markup-actions", children: [
|
|
1293
|
+
/* @__PURE__ */ jsx7("button", { className: `hsk-markup-tool${tool === "pen" ? " hsk-markup-tool--on" : ""}`, onClick: () => setTool("pen"), children: "Sketch" }),
|
|
1294
|
+
/* @__PURE__ */ jsx7("button", { className: `hsk-markup-tool${tool === "text" ? " hsk-markup-tool--on" : ""}`, onClick: () => setTool("text"), children: "Text" }),
|
|
1295
|
+
/* @__PURE__ */ jsx7("button", { className: `hsk-markup-tool${tool === "eraser" ? " hsk-markup-tool--on" : ""}`, onClick: () => setTool("eraser"), children: "Eraser" }),
|
|
1296
|
+
/* @__PURE__ */ jsx7("button", { className: "hsk-markup-tool", onClick: () => setActions((prev) => prev.slice(0, -1)), disabled: !hasMarks, children: "Undo" }),
|
|
1297
|
+
/* @__PURE__ */ jsx7("button", { className: "hsk-markup-tool", onClick: () => setActions([]), disabled: !hasMarks, children: "Clear" })
|
|
1298
|
+
] })
|
|
1299
|
+
] }),
|
|
1300
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-markup-send", children: [
|
|
1301
|
+
/* @__PURE__ */ jsx7(
|
|
1302
|
+
"input",
|
|
1303
|
+
{
|
|
1304
|
+
className: "hsk-markup-instruction",
|
|
1305
|
+
value: instruction,
|
|
1306
|
+
placeholder: "Describe the change \u2014 e.g. add the sofa here",
|
|
1307
|
+
onChange: (e) => setInstruction(e.target.value),
|
|
1308
|
+
onKeyDown: (e) => {
|
|
1309
|
+
if (e.key === "Enter" && (hasMarks || instruction.trim())) handleSend();
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
),
|
|
1313
|
+
/* @__PURE__ */ jsx7(
|
|
1314
|
+
"button",
|
|
1315
|
+
{
|
|
1316
|
+
className: "hsk-markup-go",
|
|
1317
|
+
onClick: handleSend,
|
|
1318
|
+
disabled: !img || !hasMarks && !instruction.trim(),
|
|
1319
|
+
children: "Send"
|
|
1320
|
+
}
|
|
1321
|
+
)
|
|
1322
|
+
] }),
|
|
1323
|
+
exportError && /* @__PURE__ */ jsx7("div", { className: "hsk-markup-error", children: "Couldn't process this image \u2014 try a newer visualization." })
|
|
1324
|
+
] });
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1110
1327
|
// src/components/KikuButton.tsx
|
|
1111
|
-
import { Fragment as Fragment3, jsx as
|
|
1112
|
-
var KikuIcon = ({ className, size = 18 }) => /* @__PURE__ */
|
|
1328
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1329
|
+
var KikuIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsx8(
|
|
1113
1330
|
"svg",
|
|
1114
1331
|
{
|
|
1115
1332
|
className: cn("hsk-brand-mark", className),
|
|
@@ -1118,52 +1335,52 @@ var KikuIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsx7(
|
|
|
1118
1335
|
viewBox: "0 0 100 100",
|
|
1119
1336
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1120
1337
|
"aria-label": "kiku",
|
|
1121
|
-
children: /* @__PURE__ */
|
|
1122
|
-
/* @__PURE__ */
|
|
1123
|
-
/* @__PURE__ */
|
|
1338
|
+
children: /* @__PURE__ */ jsxs7("g", { transform: "translate(22.7 19) scale(0.62)", fill: "currentColor", fillRule: "evenodd", children: [
|
|
1339
|
+
/* @__PURE__ */ jsx8("path", { d: "M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z" }),
|
|
1340
|
+
/* @__PURE__ */ jsx8("circle", { cx: "55", cy: "82", r: "3.4" })
|
|
1124
1341
|
] })
|
|
1125
1342
|
}
|
|
1126
1343
|
);
|
|
1127
1344
|
var SparkleIcon2 = KikuIcon;
|
|
1128
|
-
var ArrowUpIcon2 = () => /* @__PURE__ */
|
|
1129
|
-
/* @__PURE__ */
|
|
1130
|
-
/* @__PURE__ */
|
|
1345
|
+
var ArrowUpIcon2 = () => /* @__PURE__ */ jsxs7("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1346
|
+
/* @__PURE__ */ jsx8("path", { d: "m5 12 7-7 7 7" }),
|
|
1347
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 19V5" })
|
|
1131
1348
|
] });
|
|
1132
|
-
var StopIcon = () => /* @__PURE__ */
|
|
1133
|
-
var ExternalIcon = () => /* @__PURE__ */
|
|
1134
|
-
/* @__PURE__ */
|
|
1135
|
-
/* @__PURE__ */
|
|
1136
|
-
/* @__PURE__ */
|
|
1349
|
+
var StopIcon = () => /* @__PURE__ */ jsx8("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx8("rect", { x: "5", y: "5", width: "14", height: "14", rx: "2" }) });
|
|
1350
|
+
var ExternalIcon = () => /* @__PURE__ */ jsxs7("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1351
|
+
/* @__PURE__ */ jsx8("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
1352
|
+
/* @__PURE__ */ jsx8("polyline", { points: "15 3 21 3 21 9" }),
|
|
1353
|
+
/* @__PURE__ */ jsx8("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
1137
1354
|
] });
|
|
1138
|
-
var ContinueIcon = () => /* @__PURE__ */
|
|
1139
|
-
var CloseIcon = () => /* @__PURE__ */
|
|
1140
|
-
/* @__PURE__ */
|
|
1141
|
-
/* @__PURE__ */
|
|
1355
|
+
var ContinueIcon = () => /* @__PURE__ */ jsx8("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx8("path", { d: "M8 5v14l11-7z" }) });
|
|
1356
|
+
var CloseIcon = () => /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1357
|
+
/* @__PURE__ */ jsx8("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
1358
|
+
/* @__PURE__ */ jsx8("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
1142
1359
|
] });
|
|
1143
|
-
var ChevronRightIcon = () => /* @__PURE__ */
|
|
1144
|
-
var HistoryIcon = () => /* @__PURE__ */
|
|
1145
|
-
/* @__PURE__ */
|
|
1146
|
-
/* @__PURE__ */
|
|
1147
|
-
/* @__PURE__ */
|
|
1360
|
+
var ChevronRightIcon = () => /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "m9 18 6-6-6-6" }) });
|
|
1361
|
+
var HistoryIcon = () => /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1362
|
+
/* @__PURE__ */ jsx8("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
|
|
1363
|
+
/* @__PURE__ */ jsx8("path", { d: "M3 3v5h5" }),
|
|
1364
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 7v5l4 2" })
|
|
1148
1365
|
] });
|
|
1149
|
-
var BookmarkIcon = () => /* @__PURE__ */
|
|
1150
|
-
var TrashIcon = () => /* @__PURE__ */
|
|
1151
|
-
/* @__PURE__ */
|
|
1152
|
-
/* @__PURE__ */
|
|
1366
|
+
var BookmarkIcon = () => /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "M19 21 12 16l-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z" }) });
|
|
1367
|
+
var TrashIcon = () => /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1368
|
+
/* @__PURE__ */ jsx8("path", { d: "M3 6h18" }),
|
|
1369
|
+
/* @__PURE__ */ jsx8("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
|
|
1153
1370
|
] });
|
|
1154
|
-
var PaperclipIcon = () => /* @__PURE__ */
|
|
1155
|
-
var MicIcon2 = () => /* @__PURE__ */
|
|
1156
|
-
/* @__PURE__ */
|
|
1157
|
-
/* @__PURE__ */
|
|
1158
|
-
/* @__PURE__ */
|
|
1371
|
+
var PaperclipIcon = () => /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
|
|
1372
|
+
var MicIcon2 = () => /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1373
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z" }),
|
|
1374
|
+
/* @__PURE__ */ jsx8("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
|
|
1375
|
+
/* @__PURE__ */ jsx8("line", { x1: "12", y1: "19", x2: "12", y2: "22" })
|
|
1159
1376
|
] });
|
|
1160
|
-
var MicOffIcon = () => /* @__PURE__ */
|
|
1161
|
-
/* @__PURE__ */
|
|
1162
|
-
/* @__PURE__ */
|
|
1163
|
-
/* @__PURE__ */
|
|
1164
|
-
/* @__PURE__ */
|
|
1165
|
-
/* @__PURE__ */
|
|
1166
|
-
/* @__PURE__ */
|
|
1377
|
+
var MicOffIcon = () => /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1378
|
+
/* @__PURE__ */ jsx8("line", { x1: "2", y1: "2", x2: "22", y2: "22" }),
|
|
1379
|
+
/* @__PURE__ */ jsx8("path", { d: "M18.89 13.23A7.12 7.12 0 0 0 19 12v-2" }),
|
|
1380
|
+
/* @__PURE__ */ jsx8("path", { d: "M5 10v2a7 7 0 0 0 12 5" }),
|
|
1381
|
+
/* @__PURE__ */ jsx8("path", { d: "M15 9.34V5a3 3 0 0 0-5.68-1.33" }),
|
|
1382
|
+
/* @__PURE__ */ jsx8("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12" }),
|
|
1383
|
+
/* @__PURE__ */ jsx8("line", { x1: "12", y1: "19", x2: "12", y2: "22" })
|
|
1167
1384
|
] });
|
|
1168
1385
|
var DEFAULT_CHIPS = [];
|
|
1169
1386
|
function extractName(raw) {
|
|
@@ -1213,7 +1430,7 @@ function KikuPickerMenu({
|
|
|
1213
1430
|
onDismiss
|
|
1214
1431
|
}) {
|
|
1215
1432
|
const discussed = sources.filter((s) => s.id && referencedIds.includes(s.id));
|
|
1216
|
-
return /* @__PURE__ */
|
|
1433
|
+
return /* @__PURE__ */ jsxs7(
|
|
1217
1434
|
"div",
|
|
1218
1435
|
{
|
|
1219
1436
|
className: "hsk-kiku-picker",
|
|
@@ -1221,7 +1438,7 @@ function KikuPickerMenu({
|
|
|
1221
1438
|
"aria-label": "@kiku commands",
|
|
1222
1439
|
onMouseDown: (e) => e.preventDefault(),
|
|
1223
1440
|
children: [
|
|
1224
|
-
discussed.map((src, i) => /* @__PURE__ */
|
|
1441
|
+
discussed.map((src, i) => /* @__PURE__ */ jsxs7(
|
|
1225
1442
|
"button",
|
|
1226
1443
|
{
|
|
1227
1444
|
className: "hsk-kiku-picker-item",
|
|
@@ -1231,9 +1448,9 @@ function KikuPickerMenu({
|
|
|
1231
1448
|
onDismiss();
|
|
1232
1449
|
},
|
|
1233
1450
|
children: [
|
|
1234
|
-
/* @__PURE__ */
|
|
1235
|
-
/* @__PURE__ */
|
|
1236
|
-
src.price && /* @__PURE__ */
|
|
1451
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon", children: src.image ? /* @__PURE__ */ jsx8("img", { src: src.image, alt: "" }) : /* @__PURE__ */ jsx8(BookmarkIcon, {}) }),
|
|
1452
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-item-name", children: src.name }),
|
|
1453
|
+
src.price && /* @__PURE__ */ jsxs7("span", { className: "hsk-kiku-picker-item-price", children: [
|
|
1237
1454
|
src.currency ?? defaultCurrency,
|
|
1238
1455
|
" ",
|
|
1239
1456
|
parseFloat(String(src.price).replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
@@ -1242,7 +1459,7 @@ function KikuPickerMenu({
|
|
|
1242
1459
|
},
|
|
1243
1460
|
src.id ?? i
|
|
1244
1461
|
)),
|
|
1245
|
-
discussed.length > 1 && /* @__PURE__ */
|
|
1462
|
+
discussed.length > 1 && /* @__PURE__ */ jsxs7(
|
|
1246
1463
|
"button",
|
|
1247
1464
|
{
|
|
1248
1465
|
className: "hsk-kiku-picker-item",
|
|
@@ -1252,8 +1469,8 @@ function KikuPickerMenu({
|
|
|
1252
1469
|
onDismiss();
|
|
1253
1470
|
},
|
|
1254
1471
|
children: [
|
|
1255
|
-
/* @__PURE__ */
|
|
1256
|
-
/* @__PURE__ */
|
|
1472
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon", children: /* @__PURE__ */ jsx8(BookmarkIcon, {}) }),
|
|
1473
|
+
/* @__PURE__ */ jsxs7("span", { className: "hsk-kiku-picker-item-name", children: [
|
|
1257
1474
|
"Capture all (",
|
|
1258
1475
|
discussed.length,
|
|
1259
1476
|
")"
|
|
@@ -1261,7 +1478,7 @@ function KikuPickerMenu({
|
|
|
1261
1478
|
]
|
|
1262
1479
|
}
|
|
1263
1480
|
),
|
|
1264
|
-
discussed.length === 0 && /* @__PURE__ */
|
|
1481
|
+
discussed.length === 0 && /* @__PURE__ */ jsxs7(
|
|
1265
1482
|
"button",
|
|
1266
1483
|
{
|
|
1267
1484
|
className: "hsk-kiku-picker-item",
|
|
@@ -1271,12 +1488,12 @@ function KikuPickerMenu({
|
|
|
1271
1488
|
onDismiss();
|
|
1272
1489
|
},
|
|
1273
1490
|
children: [
|
|
1274
|
-
/* @__PURE__ */
|
|
1275
|
-
/* @__PURE__ */
|
|
1491
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon", children: /* @__PURE__ */ jsx8(BookmarkIcon, {}) }),
|
|
1492
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-item-name", children: "Capture current page" })
|
|
1276
1493
|
]
|
|
1277
1494
|
}
|
|
1278
1495
|
),
|
|
1279
|
-
/* @__PURE__ */
|
|
1496
|
+
/* @__PURE__ */ jsxs7(
|
|
1280
1497
|
"button",
|
|
1281
1498
|
{
|
|
1282
1499
|
className: "hsk-kiku-picker-item",
|
|
@@ -1286,12 +1503,12 @@ function KikuPickerMenu({
|
|
|
1286
1503
|
onDismiss();
|
|
1287
1504
|
},
|
|
1288
1505
|
children: [
|
|
1289
|
-
/* @__PURE__ */
|
|
1290
|
-
/* @__PURE__ */
|
|
1506
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon", children: /* @__PURE__ */ jsx8(HistoryIcon, {}) }),
|
|
1507
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-item-name", children: "What have you saved?" })
|
|
1291
1508
|
]
|
|
1292
1509
|
}
|
|
1293
1510
|
),
|
|
1294
|
-
/* @__PURE__ */
|
|
1511
|
+
/* @__PURE__ */ jsxs7(
|
|
1295
1512
|
"button",
|
|
1296
1513
|
{
|
|
1297
1514
|
className: "hsk-kiku-picker-item",
|
|
@@ -1301,8 +1518,8 @@ function KikuPickerMenu({
|
|
|
1301
1518
|
onDismiss();
|
|
1302
1519
|
},
|
|
1303
1520
|
children: [
|
|
1304
|
-
/* @__PURE__ */
|
|
1305
|
-
/* @__PURE__ */
|
|
1521
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon", children: /* @__PURE__ */ jsx8(TrashIcon, {}) }),
|
|
1522
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-item-name", children: "Delete this" })
|
|
1306
1523
|
]
|
|
1307
1524
|
}
|
|
1308
1525
|
)
|
|
@@ -1311,22 +1528,22 @@ function KikuPickerMenu({
|
|
|
1311
1528
|
);
|
|
1312
1529
|
}
|
|
1313
1530
|
function AtPickerMenu({ onSelect, onDismiss }) {
|
|
1314
|
-
return /* @__PURE__ */
|
|
1531
|
+
return /* @__PURE__ */ jsx8(
|
|
1315
1532
|
"div",
|
|
1316
1533
|
{
|
|
1317
1534
|
className: "hsk-kiku-picker",
|
|
1318
1535
|
role: "menu",
|
|
1319
1536
|
"aria-label": "Extensions",
|
|
1320
1537
|
onMouseDown: (e) => e.preventDefault(),
|
|
1321
|
-
children: /* @__PURE__ */
|
|
1538
|
+
children: /* @__PURE__ */ jsxs7(
|
|
1322
1539
|
"button",
|
|
1323
1540
|
{
|
|
1324
1541
|
className: "hsk-kiku-picker-item",
|
|
1325
1542
|
role: "menuitem",
|
|
1326
1543
|
onClick: () => onSelect("@kiku"),
|
|
1327
1544
|
children: [
|
|
1328
|
-
/* @__PURE__ */
|
|
1329
|
-
/* @__PURE__ */
|
|
1545
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon hsk-kiku-picker-icon--accent", children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
1546
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-item-name", children: "kiku \u2014 capture & remember" })
|
|
1330
1547
|
]
|
|
1331
1548
|
}
|
|
1332
1549
|
)
|
|
@@ -1334,11 +1551,11 @@ function AtPickerMenu({ onSelect, onDismiss }) {
|
|
|
1334
1551
|
);
|
|
1335
1552
|
}
|
|
1336
1553
|
function SourceImg({ src, alt, onImageClick }) {
|
|
1337
|
-
const [failed, setFailed] =
|
|
1554
|
+
const [failed, setFailed] = useState6(false);
|
|
1338
1555
|
if (failed) {
|
|
1339
|
-
return /* @__PURE__ */
|
|
1556
|
+
return /* @__PURE__ */ jsx8("div", { style: { width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center", background: "var(--hsk-chat-source-bg, rgba(0,0,0,.04))", color: "var(--hsk-chat-muted, #888)" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) });
|
|
1340
1557
|
}
|
|
1341
|
-
return /* @__PURE__ */
|
|
1558
|
+
return /* @__PURE__ */ jsx8(
|
|
1342
1559
|
"img",
|
|
1343
1560
|
{
|
|
1344
1561
|
src,
|
|
@@ -1354,15 +1571,15 @@ function SourceImg({ src, alt, onImageClick }) {
|
|
|
1354
1571
|
function SourcesCarousel({ sources, defaultCurrency, onSelectSource, onImageClick, referencedIds = [], compact = false }) {
|
|
1355
1572
|
const client = useAkropolysContext3();
|
|
1356
1573
|
const isProperty = client?.vertical === "property";
|
|
1357
|
-
const railRef =
|
|
1358
|
-
const [showNext, setShowNext] =
|
|
1574
|
+
const railRef = useRef6(null);
|
|
1575
|
+
const [showNext, setShowNext] = useState6(false);
|
|
1359
1576
|
const measure = useCallback2(() => {
|
|
1360
1577
|
const el = railRef.current;
|
|
1361
1578
|
if (!el) return;
|
|
1362
1579
|
const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 8;
|
|
1363
1580
|
setShowNext(el.scrollWidth > el.clientWidth + 4 && !atEnd);
|
|
1364
1581
|
}, []);
|
|
1365
|
-
|
|
1582
|
+
useEffect4(() => {
|
|
1366
1583
|
measure();
|
|
1367
1584
|
const el = railRef.current;
|
|
1368
1585
|
if (!el) return;
|
|
@@ -1379,20 +1596,20 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource, onImageClic
|
|
|
1379
1596
|
};
|
|
1380
1597
|
const display = sources.filter((s) => s.id && referencedIds.includes(s.id));
|
|
1381
1598
|
if (display.length === 0) return null;
|
|
1382
|
-
return /* @__PURE__ */
|
|
1383
|
-
/* @__PURE__ */
|
|
1599
|
+
return /* @__PURE__ */ jsxs7("div", { className: cn("hsk-cb-sources-wrap", compact && "hsk-cb-sources-wrap--compact"), children: [
|
|
1600
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-sources", ref: railRef, children: display.map((src, si) => {
|
|
1384
1601
|
const isReferenced = !!(src.id && referencedIds.includes(src.id));
|
|
1385
|
-
return /* @__PURE__ */
|
|
1602
|
+
return /* @__PURE__ */ jsxs7(
|
|
1386
1603
|
"div",
|
|
1387
1604
|
{
|
|
1388
1605
|
className: cn("hsk-cb-source", isReferenced && "hsk-cb-source--referenced"),
|
|
1389
1606
|
style: { animationDelay: `${si * 50}ms` },
|
|
1390
1607
|
onClick: () => onSelectSource?.(src),
|
|
1391
1608
|
children: [
|
|
1392
|
-
src.image ? /* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1394
|
-
isReferenced && /* @__PURE__ */
|
|
1395
|
-
isProperty && /* @__PURE__ */
|
|
1609
|
+
src.image ? /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-src-imgwrap", style: { position: "relative" }, children: [
|
|
1610
|
+
/* @__PURE__ */ jsx8(SourceImg, { src: src.image, alt: src.name, onImageClick }),
|
|
1611
|
+
isReferenced && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-source-ref-badge", title: "Featured in response", children: /* @__PURE__ */ jsx8(SparkleIcon2, { size: 10 }) }),
|
|
1612
|
+
isProperty && /* @__PURE__ */ jsx8("div", { style: {
|
|
1396
1613
|
position: "absolute",
|
|
1397
1614
|
top: "6px",
|
|
1398
1615
|
right: "6px",
|
|
@@ -1407,14 +1624,14 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource, onImageClic
|
|
|
1407
1624
|
color: "#fbbf24",
|
|
1408
1625
|
// Gold sparkle badge
|
|
1409
1626
|
boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
|
|
1410
|
-
}, children: /* @__PURE__ */
|
|
1411
|
-
] }) : /* @__PURE__ */
|
|
1412
|
-
/* @__PURE__ */
|
|
1413
|
-
isReferenced && /* @__PURE__ */
|
|
1627
|
+
}, children: /* @__PURE__ */ jsx8(SparkleIcon2, { size: 12 }) })
|
|
1628
|
+
] }) : /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-src-imgwrap-empty", style: { position: "relative" }, children: [
|
|
1629
|
+
/* @__PURE__ */ jsx8(SparkleIcon2, {}),
|
|
1630
|
+
isReferenced && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-source-ref-badge", title: "Featured in response", children: /* @__PURE__ */ jsx8(SparkleIcon2, { size: 10 }) })
|
|
1414
1631
|
] }),
|
|
1415
|
-
/* @__PURE__ */
|
|
1416
|
-
/* @__PURE__ */
|
|
1417
|
-
src.price && /* @__PURE__ */
|
|
1632
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-src-info", children: [
|
|
1633
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-src-name", children: src.name }),
|
|
1634
|
+
src.price && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-src-price", children: [
|
|
1418
1635
|
src.currency ?? defaultCurrency,
|
|
1419
1636
|
" ",
|
|
1420
1637
|
parseFloat(String(src.price).replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
@@ -1425,15 +1642,15 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource, onImageClic
|
|
|
1425
1642
|
src.id ?? si
|
|
1426
1643
|
);
|
|
1427
1644
|
}) }),
|
|
1428
|
-
showNext && /* @__PURE__ */
|
|
1429
|
-
/* @__PURE__ */
|
|
1645
|
+
showNext && /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
1646
|
+
/* @__PURE__ */ jsx8(
|
|
1430
1647
|
"div",
|
|
1431
1648
|
{
|
|
1432
1649
|
className: "hsk-cb-sources-fade",
|
|
1433
1650
|
style: { background: "linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))" }
|
|
1434
1651
|
}
|
|
1435
1652
|
),
|
|
1436
|
-
/* @__PURE__ */
|
|
1653
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-sources-next", onClick: scrollNext, "aria-label": "See more", children: /* @__PURE__ */ jsx8(ChevronRightIcon, {}) })
|
|
1437
1654
|
] })
|
|
1438
1655
|
] });
|
|
1439
1656
|
}
|
|
@@ -1510,14 +1727,14 @@ function SmartContextPills({
|
|
|
1510
1727
|
pills.push({ emoji: "\u{1F4A1}", label: "Recommend something", query: "What do you recommend for me?" });
|
|
1511
1728
|
}
|
|
1512
1729
|
if (pills.length === 0) return null;
|
|
1513
|
-
return /* @__PURE__ */
|
|
1730
|
+
return /* @__PURE__ */ jsx8("div", { className: "hsk-action-pills", children: pills.map((pill) => /* @__PURE__ */ jsxs7(
|
|
1514
1731
|
"button",
|
|
1515
1732
|
{
|
|
1516
1733
|
className: "hsk-action-pill",
|
|
1517
1734
|
onClick: () => onSend(pill.query),
|
|
1518
1735
|
disabled: loading,
|
|
1519
1736
|
children: [
|
|
1520
|
-
/* @__PURE__ */
|
|
1737
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-pill-emoji", children: pill.emoji }),
|
|
1521
1738
|
pill.label
|
|
1522
1739
|
]
|
|
1523
1740
|
},
|
|
@@ -1578,10 +1795,10 @@ function parseThinking(text) {
|
|
|
1578
1795
|
};
|
|
1579
1796
|
}
|
|
1580
1797
|
function ThinkingBlock({ text, isComplete, seconds: fixedSeconds }) {
|
|
1581
|
-
const startRef =
|
|
1582
|
-
const [seconds, setSeconds] =
|
|
1583
|
-
const [isOpen, setIsOpen] =
|
|
1584
|
-
|
|
1798
|
+
const startRef = useRef6(Date.now());
|
|
1799
|
+
const [seconds, setSeconds] = useState6(() => isComplete ? null : 0);
|
|
1800
|
+
const [isOpen, setIsOpen] = useState6(!isComplete);
|
|
1801
|
+
useEffect4(() => {
|
|
1585
1802
|
if (isComplete) {
|
|
1586
1803
|
if (seconds !== null) {
|
|
1587
1804
|
setSeconds(Math.max(1, Math.round((Date.now() - startRef.current) / 1e3)));
|
|
@@ -1598,8 +1815,8 @@ function ThinkingBlock({ text, isComplete, seconds: fixedSeconds }) {
|
|
|
1598
1815
|
const finalSeconds = fixedSeconds ?? seconds;
|
|
1599
1816
|
const label = isComplete ? finalSeconds !== null && finalSeconds !== void 0 ? `Thought for ${finalSeconds}s` : "Thought process" : `Thinking${seconds ? ` \xB7 ${seconds}s` : "\u2026"}`;
|
|
1600
1817
|
const expandable = !!text;
|
|
1601
|
-
return /* @__PURE__ */
|
|
1602
|
-
/* @__PURE__ */
|
|
1818
|
+
return /* @__PURE__ */ jsxs7("div", { className: cn("hsk-cb-think", !isComplete && "hsk-cb-think--live"), children: [
|
|
1819
|
+
/* @__PURE__ */ jsxs7(
|
|
1603
1820
|
"button",
|
|
1604
1821
|
{
|
|
1605
1822
|
type: "button",
|
|
@@ -1607,16 +1824,20 @@ function ThinkingBlock({ text, isComplete, seconds: fixedSeconds }) {
|
|
|
1607
1824
|
onClick: expandable ? () => setIsOpen((o) => !o) : void 0,
|
|
1608
1825
|
"aria-expanded": expandable ? isOpen : void 0,
|
|
1609
1826
|
children: [
|
|
1610
|
-
/* @__PURE__ */
|
|
1611
|
-
/* @__PURE__ */
|
|
1612
|
-
/* @__PURE__ */
|
|
1827
|
+
isComplete ? /* @__PURE__ */ jsxs7("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1828
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1829
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 6v6l4 2" })
|
|
1830
|
+
] }) : /* @__PURE__ */ jsxs7("span", { className: "hsk-cb-typing", "aria-hidden": "true", children: [
|
|
1831
|
+
/* @__PURE__ */ jsx8("span", {}),
|
|
1832
|
+
/* @__PURE__ */ jsx8("span", {}),
|
|
1833
|
+
/* @__PURE__ */ jsx8("span", {})
|
|
1613
1834
|
] }),
|
|
1614
|
-
/* @__PURE__ */
|
|
1615
|
-
expandable && /* @__PURE__ */
|
|
1835
|
+
/* @__PURE__ */ jsx8("span", { children: label }),
|
|
1836
|
+
expandable && /* @__PURE__ */ jsx8("span", { className: cn("hsk-cb-think-chevron", isOpen && "hsk-cb-think-chevron--open"), children: "\u25B6" })
|
|
1616
1837
|
]
|
|
1617
1838
|
}
|
|
1618
1839
|
),
|
|
1619
|
-
expandable && isOpen && /* @__PURE__ */
|
|
1840
|
+
expandable && isOpen && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-think-body", children: text })
|
|
1620
1841
|
] });
|
|
1621
1842
|
}
|
|
1622
1843
|
function ChatModal({
|
|
@@ -1637,18 +1858,18 @@ function ChatModal({
|
|
|
1637
1858
|
}) {
|
|
1638
1859
|
const client = useAkropolysContext3();
|
|
1639
1860
|
const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, stop, stopped, interrupted, continueGenerating, reset, referencedIds } = useKiku2();
|
|
1640
|
-
const [input, setInput] =
|
|
1641
|
-
const [shopperName, setShopperNameState] =
|
|
1861
|
+
const [input, setInput] = useState6("");
|
|
1862
|
+
const [shopperName, setShopperNameState] = useState6(() => {
|
|
1642
1863
|
try {
|
|
1643
1864
|
return client.getShopperName?.() ?? "";
|
|
1644
1865
|
} catch {
|
|
1645
1866
|
return "";
|
|
1646
1867
|
}
|
|
1647
1868
|
});
|
|
1648
|
-
const [nameSkipped, setNameSkipped] =
|
|
1869
|
+
const [nameSkipped, setNameSkipped] = useState6(false);
|
|
1649
1870
|
const awaitingName = messages.length === 0 && !shopperName && !nameSkipped;
|
|
1650
|
-
const [attachments, setAttachments] =
|
|
1651
|
-
const imageInputRef =
|
|
1871
|
+
const [attachments, setAttachments] = useState6([]);
|
|
1872
|
+
const imageInputRef = useRef6(null);
|
|
1652
1873
|
const handleImageFiles = (files) => {
|
|
1653
1874
|
if (!files || files.length === 0) return;
|
|
1654
1875
|
Array.from(files).forEach((file) => {
|
|
@@ -1666,9 +1887,9 @@ function ChatModal({
|
|
|
1666
1887
|
const removeAttachment = (idx) => {
|
|
1667
1888
|
setAttachments((prev) => prev.filter((_, i) => i !== idx));
|
|
1668
1889
|
};
|
|
1669
|
-
const [voiceState, setVoiceState] =
|
|
1670
|
-
const recognitionRef =
|
|
1671
|
-
const pendingVoiceRef =
|
|
1890
|
+
const [voiceState, setVoiceState] = useState6("idle");
|
|
1891
|
+
const recognitionRef = useRef6(null);
|
|
1892
|
+
const pendingVoiceRef = useRef6(null);
|
|
1672
1893
|
const hasSpeechAPI = typeof window !== "undefined" && ("SpeechRecognition" in window || "webkitSpeechRecognition" in window);
|
|
1673
1894
|
const startVoice = useCallback2(() => {
|
|
1674
1895
|
if (!hasSpeechAPI || voiceState !== "idle") return;
|
|
@@ -1712,21 +1933,22 @@ function ChatModal({
|
|
|
1712
1933
|
recognitionRef.current?.stop();
|
|
1713
1934
|
setVoiceState("idle");
|
|
1714
1935
|
}, []);
|
|
1715
|
-
|
|
1936
|
+
useEffect4(() => {
|
|
1716
1937
|
return () => recognitionRef.current?.abort();
|
|
1717
1938
|
}, []);
|
|
1718
1939
|
const activeChips = chips;
|
|
1719
1940
|
const activeTitle = title;
|
|
1720
1941
|
const activePlaceholder = awaitingName ? "Type your name\u2026" : placeholder;
|
|
1721
|
-
const [selectedProduct, setSelectedProduct] =
|
|
1722
|
-
const [lightboxSrc, setLightboxSrc] =
|
|
1723
|
-
const
|
|
1724
|
-
const
|
|
1725
|
-
const
|
|
1726
|
-
const [
|
|
1727
|
-
const [
|
|
1728
|
-
const [
|
|
1729
|
-
const [
|
|
1942
|
+
const [selectedProduct, setSelectedProduct] = useState6(null);
|
|
1943
|
+
const [lightboxSrc, setLightboxSrc] = useState6(null);
|
|
1944
|
+
const [markupSrc, setMarkupSrc] = useState6(null);
|
|
1945
|
+
const bottomRef = useRef6(null);
|
|
1946
|
+
const textareaRef = useRef6(null);
|
|
1947
|
+
const [keyInput, setKeyInput] = useState6("");
|
|
1948
|
+
const [keyPhase, setKeyPhase] = useState6("idle");
|
|
1949
|
+
const [mintedKey, setMintedKey] = useState6(null);
|
|
1950
|
+
const [mintedPub, setMintedPub] = useState6(null);
|
|
1951
|
+
const [copied, setCopied] = useState6(null);
|
|
1730
1952
|
const copyValue = (value, which) => {
|
|
1731
1953
|
try {
|
|
1732
1954
|
navigator.clipboard?.writeText(value);
|
|
@@ -1735,17 +1957,17 @@ function ChatModal({
|
|
|
1735
1957
|
setCopied(which);
|
|
1736
1958
|
setTimeout(() => setCopied((c) => c === which ? null : c), 1600);
|
|
1737
1959
|
};
|
|
1738
|
-
const [keyCountdown, setKeyCountdown] =
|
|
1739
|
-
const [minting, setMinting] =
|
|
1740
|
-
const [showKikuPicker, setShowKikuPicker] =
|
|
1741
|
-
const [showAtPicker, setShowAtPicker] =
|
|
1742
|
-
|
|
1960
|
+
const [keyCountdown, setKeyCountdown] = useState6(KIKU_KEY_REVEAL_SECONDS);
|
|
1961
|
+
const [minting, setMinting] = useState6(false);
|
|
1962
|
+
const [showKikuPicker, setShowKikuPicker] = useState6(false);
|
|
1963
|
+
const [showAtPicker, setShowAtPicker] = useState6(false);
|
|
1964
|
+
useEffect4(() => {
|
|
1743
1965
|
if (!lastAction) return;
|
|
1744
1966
|
if (lastAction.type === "request_kiku_key") {
|
|
1745
1967
|
setKeyPhase("prompt_key");
|
|
1746
1968
|
}
|
|
1747
1969
|
}, [lastAction]);
|
|
1748
|
-
|
|
1970
|
+
useEffect4(() => {
|
|
1749
1971
|
if (!mintedKey) return;
|
|
1750
1972
|
setKeyCountdown(KIKU_KEY_REVEAL_SECONDS);
|
|
1751
1973
|
const t = setInterval(() => {
|
|
@@ -1796,9 +2018,9 @@ function ChatModal({
|
|
|
1796
2018
|
setMinting(false);
|
|
1797
2019
|
}
|
|
1798
2020
|
};
|
|
1799
|
-
const msgsContainerRef =
|
|
1800
|
-
const messageRefs =
|
|
1801
|
-
|
|
2021
|
+
const msgsContainerRef = useRef6(null);
|
|
2022
|
+
const messageRefs = useRef6([]);
|
|
2023
|
+
useEffect4(() => {
|
|
1802
2024
|
const container = msgsContainerRef.current;
|
|
1803
2025
|
if (!container) return;
|
|
1804
2026
|
const lastMsg = messages[messages.length - 1];
|
|
@@ -1811,14 +2033,14 @@ function ChatModal({
|
|
|
1811
2033
|
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
1812
2034
|
}
|
|
1813
2035
|
}, [messages, loading, selectedProduct]);
|
|
1814
|
-
|
|
2036
|
+
useEffect4(() => {
|
|
1815
2037
|
const prev = document.body.style.overflow;
|
|
1816
2038
|
document.body.style.overflow = "hidden";
|
|
1817
2039
|
return () => {
|
|
1818
2040
|
document.body.style.overflow = prev;
|
|
1819
2041
|
};
|
|
1820
2042
|
}, []);
|
|
1821
|
-
|
|
2043
|
+
useEffect4(() => {
|
|
1822
2044
|
const h = (e) => {
|
|
1823
2045
|
if (e.key !== "Escape") return;
|
|
1824
2046
|
if (lightboxSrc) {
|
|
@@ -1949,7 +2171,7 @@ function ChatModal({
|
|
|
1949
2171
|
t.style.height = "auto";
|
|
1950
2172
|
t.style.height = `${Math.min(t.scrollHeight, 140)}px`;
|
|
1951
2173
|
};
|
|
1952
|
-
|
|
2174
|
+
useEffect4(() => {
|
|
1953
2175
|
if (voiceState !== "processing") return;
|
|
1954
2176
|
const transcript = pendingVoiceRef.current;
|
|
1955
2177
|
if (!transcript) {
|
|
@@ -1965,7 +2187,7 @@ function ChatModal({
|
|
|
1965
2187
|
}, [voiceState]);
|
|
1966
2188
|
const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur ?? "20px";
|
|
1967
2189
|
const displayMessages = messages;
|
|
1968
|
-
return /* @__PURE__ */
|
|
2190
|
+
return /* @__PURE__ */ jsx8(
|
|
1969
2191
|
"div",
|
|
1970
2192
|
{
|
|
1971
2193
|
className: cn("hsk-cb-overlay", classNames.overlay),
|
|
@@ -1977,7 +2199,7 @@ function ChatModal({
|
|
|
1977
2199
|
...backdropColor ? { background: backdropColor } : {},
|
|
1978
2200
|
...customStyles
|
|
1979
2201
|
},
|
|
1980
|
-
children: /* @__PURE__ */
|
|
2202
|
+
children: /* @__PURE__ */ jsxs7(
|
|
1981
2203
|
"div",
|
|
1982
2204
|
{
|
|
1983
2205
|
className: cn("hsk-cb-panel", classNames.panel),
|
|
@@ -1990,48 +2212,62 @@ function ChatModal({
|
|
|
1990
2212
|
}
|
|
1991
2213
|
},
|
|
1992
2214
|
children: [
|
|
1993
|
-
lightboxSrc && /* @__PURE__ */
|
|
1994
|
-
/* @__PURE__ */
|
|
1995
|
-
/* @__PURE__ */
|
|
2215
|
+
lightboxSrc && /* @__PURE__ */ jsxs7("div", { className: "hsk-lightbox", onClick: () => setLightboxSrc(null), children: [
|
|
2216
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-lightbox-close", onClick: () => setLightboxSrc(null), "aria-label": "Close image", children: /* @__PURE__ */ jsx8(CloseIcon, {}) }),
|
|
2217
|
+
/* @__PURE__ */ jsx8("img", { src: lightboxSrc, alt: "", className: "hsk-lightbox-img", onClick: (e) => e.stopPropagation() })
|
|
1996
2218
|
] }),
|
|
1997
|
-
/* @__PURE__ */
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2219
|
+
markupSrc && /* @__PURE__ */ jsx8("div", { className: "hsk-markup-overlay", children: /* @__PURE__ */ jsx8(
|
|
2220
|
+
MarkupEditor,
|
|
2221
|
+
{
|
|
2222
|
+
src: markupSrc,
|
|
2223
|
+
onCancel: () => setMarkupSrc(null),
|
|
2224
|
+
onSend: (dataUrl, instruction) => {
|
|
2225
|
+
setMarkupSrc(null);
|
|
2226
|
+
handleSend(
|
|
2227
|
+
instruction || "Apply the change indicated by the markings on the image.",
|
|
2228
|
+
[{ type: "image", data: dataUrl, annotated: true }]
|
|
2229
|
+
);
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
) }),
|
|
2233
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-main", children: [
|
|
2234
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-topbar", children: [
|
|
2235
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-topbar-left", children: [
|
|
2236
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-cb-topbar-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
2237
|
+
/* @__PURE__ */ jsx8("div", { children: /* @__PURE__ */ jsx8("div", { className: "hsk-cb-topbar-title", children: activeTitle }) })
|
|
2002
2238
|
] }),
|
|
2003
|
-
/* @__PURE__ */
|
|
2004
|
-
messages.length > 0 && /* @__PURE__ */
|
|
2005
|
-
/* @__PURE__ */
|
|
2239
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-topbar-actions", children: [
|
|
2240
|
+
messages.length > 0 && /* @__PURE__ */ jsx8("button", { className: "hsk-cb-topbar-btn", onClick: handleReset, children: "Clear chat" }),
|
|
2241
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx8(CloseIcon, {}) })
|
|
2006
2242
|
] })
|
|
2007
2243
|
] }),
|
|
2008
|
-
/* @__PURE__ */
|
|
2009
|
-
displayMessages.length === 0 ? /* @__PURE__ */
|
|
2010
|
-
awaitingName ? /* @__PURE__ */
|
|
2011
|
-
/* @__PURE__ */
|
|
2244
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-msgs", ref: msgsContainerRef, children: [
|
|
2245
|
+
displayMessages.length === 0 ? /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-empty", children: [
|
|
2246
|
+
awaitingName ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2247
|
+
/* @__PURE__ */ jsxs7("h2", { className: "hsk-cb-hello", children: [
|
|
2012
2248
|
"Hi, I'm ",
|
|
2013
|
-
/* @__PURE__ */
|
|
2249
|
+
/* @__PURE__ */ jsx8("b", { children: "kiku" }),
|
|
2014
2250
|
"."
|
|
2015
2251
|
] }),
|
|
2016
|
-
/* @__PURE__ */
|
|
2017
|
-
/* @__PURE__ */
|
|
2018
|
-
/* @__PURE__ */
|
|
2019
|
-
] }) : shopperName ? /* @__PURE__ */
|
|
2020
|
-
/* @__PURE__ */
|
|
2252
|
+
/* @__PURE__ */ jsx8("p", { className: "hsk-cb-hello-lead", children: "I can search, visualize, or capture anything for you \u2014 on this site or any other." }),
|
|
2253
|
+
/* @__PURE__ */ jsx8("p", { className: "hsk-cb-hello-ask", children: "What should I call you?" }),
|
|
2254
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-hello-skip", onClick: () => setNameSkipped(true), children: "Skip for now" })
|
|
2255
|
+
] }) : shopperName ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2256
|
+
/* @__PURE__ */ jsxs7("h2", { className: "hsk-cb-hello", children: [
|
|
2021
2257
|
"Hi, ",
|
|
2022
2258
|
shopperName,
|
|
2023
2259
|
"."
|
|
2024
2260
|
] }),
|
|
2025
|
-
/* @__PURE__ */
|
|
2026
|
-
] }) : /* @__PURE__ */
|
|
2027
|
-
/* @__PURE__ */
|
|
2261
|
+
/* @__PURE__ */ jsx8("p", { className: "hsk-cb-hello-lead", children: "What can I find for you today?" })
|
|
2262
|
+
] }) : /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2263
|
+
/* @__PURE__ */ jsxs7("h2", { className: "hsk-cb-hello", children: [
|
|
2028
2264
|
"Hi, I'm ",
|
|
2029
|
-
/* @__PURE__ */
|
|
2265
|
+
/* @__PURE__ */ jsx8("b", { children: "kiku" }),
|
|
2030
2266
|
"."
|
|
2031
2267
|
] }),
|
|
2032
|
-
/* @__PURE__ */
|
|
2268
|
+
/* @__PURE__ */ jsx8("p", { className: "hsk-cb-hello-lead", children: "Ask me to search, visualize, or capture anything \u2014 I look across the whole site in real time." })
|
|
2033
2269
|
] }),
|
|
2034
|
-
!awaitingName && activeChips.length > 0 && /* @__PURE__ */
|
|
2270
|
+
!awaitingName && activeChips.length > 0 && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-chips", children: activeChips.map((chip) => /* @__PURE__ */ jsx8(
|
|
2035
2271
|
"button",
|
|
2036
2272
|
{
|
|
2037
2273
|
className: "hsk-cb-chip",
|
|
@@ -2042,40 +2278,41 @@ function ChatModal({
|
|
|
2042
2278
|
)) })
|
|
2043
2279
|
] }) : displayMessages.map((msg, idx) => {
|
|
2044
2280
|
const isLast = idx === displayMessages.length - 1;
|
|
2281
|
+
const isLastUser = msg.role === "user" && !displayMessages.slice(idx + 1).some((m) => m.role === "user");
|
|
2045
2282
|
const isUser = msg.role === "user";
|
|
2046
2283
|
const compareSources = sources.filter((s) => s.id && referencedIds.includes(s.id));
|
|
2047
2284
|
const showMatrix = isLast && lastIntent === "compare" && compareSources.length >= 2;
|
|
2048
2285
|
const displayContent = !isUser && showMatrix ? stripMarkdownTables(msg.content) : msg.content;
|
|
2049
|
-
return /* @__PURE__ */
|
|
2286
|
+
return /* @__PURE__ */ jsx8("div", { className: "hsk-cb-msg-group", ref: (el) => {
|
|
2050
2287
|
messageRefs.current[idx] = el;
|
|
2051
|
-
}, children: isUser ? /* @__PURE__ */
|
|
2052
|
-
msg.images && msg.images.length > 0 && /* @__PURE__ */
|
|
2053
|
-
msg.content && /* @__PURE__ */
|
|
2054
|
-
/* @__PURE__ */
|
|
2288
|
+
}, children: isUser ? /* @__PURE__ */ jsxs7("div", { className: `hsk-cb-user-msg${isLastUser ? " hsk-sent" : ""}`, children: [
|
|
2289
|
+
msg.images && msg.images.length > 0 && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-user-imgs", children: msg.images.map((img, i) => /* @__PURE__ */ jsx8("img", { src: img, alt: `attachment ${i + 1}`, className: "hsk-cb-user-img-thumb" }, i)) }),
|
|
2290
|
+
msg.content && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-user-bubble", children: /^@kiku\b/i.test(msg.content) ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2291
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-badge", children: "@kiku" }),
|
|
2055
2292
|
msg.content.replace(/^@kiku\s*/i, "")
|
|
2056
2293
|
] }) : msg.content })
|
|
2057
|
-
] }) : /* @__PURE__ */
|
|
2058
|
-
/* @__PURE__ */
|
|
2059
|
-
/* @__PURE__ */
|
|
2294
|
+
] }) : /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-msg", children: [
|
|
2295
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
2296
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-body", children: [
|
|
2060
2297
|
(() => {
|
|
2061
2298
|
const parsed = parseThinking(displayContent);
|
|
2062
2299
|
const thinking = msg.thinking || parsed.thinking;
|
|
2063
2300
|
const content = parsed.content;
|
|
2064
2301
|
const isComplete = msg.thinking ? content.length > 0 || !(isLast && streaming) : parsed.isComplete;
|
|
2065
|
-
return /* @__PURE__ */
|
|
2066
|
-
(thinking || msg.thoughtForSeconds != null) && /* @__PURE__ */
|
|
2067
|
-
content && /* @__PURE__ */
|
|
2302
|
+
return /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2303
|
+
(thinking || msg.thoughtForSeconds != null) && /* @__PURE__ */ jsx8(ThinkingBlock, { text: thinking, isComplete, seconds: msg.thoughtForSeconds }),
|
|
2304
|
+
content && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-text", children: [
|
|
2068
2305
|
renderMarkdown(content, isLast && streaming),
|
|
2069
|
-
isLast && streaming && /* @__PURE__ */
|
|
2306
|
+
isLast && streaming && /* @__PURE__ */ jsx8("span", { style: { display: "inline-block", width: "0.5em", height: "1.05em", marginLeft: "2px", verticalAlign: "text-bottom", background: "currentColor", opacity: 0.55, borderRadius: "1px" } })
|
|
2070
2307
|
] })
|
|
2071
2308
|
] });
|
|
2072
2309
|
})(),
|
|
2073
|
-
msg.visualizing && /* @__PURE__ */
|
|
2074
|
-
/* @__PURE__ */
|
|
2075
|
-
/* @__PURE__ */
|
|
2310
|
+
msg.visualizing && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-viz hsk-cb-viz--loading", children: [
|
|
2311
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-cb-viz-spinner" }),
|
|
2312
|
+
/* @__PURE__ */ jsx8("span", { children: "Visualizing\u2026" })
|
|
2076
2313
|
] }),
|
|
2077
|
-
msg.visualization && /* @__PURE__ */
|
|
2078
|
-
/* @__PURE__ */
|
|
2314
|
+
msg.visualization && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-viz", children: [
|
|
2315
|
+
/* @__PURE__ */ jsx8(
|
|
2079
2316
|
"img",
|
|
2080
2317
|
{
|
|
2081
2318
|
src: msg.visualization,
|
|
@@ -2086,16 +2323,36 @@ function ChatModal({
|
|
|
2086
2323
|
}
|
|
2087
2324
|
}
|
|
2088
2325
|
),
|
|
2089
|
-
/* @__PURE__ */
|
|
2326
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-viz-foot", children: [
|
|
2327
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-viz-disclaimer", children: "AI-generated preview \u2014 colours, size and placement may differ from the real product." }),
|
|
2328
|
+
isLast && !streaming && /* @__PURE__ */ jsx8("button", { className: "hsk-cb-viz-mark", onClick: () => setMarkupSrc(msg.visualization), children: "Mark & edit" })
|
|
2329
|
+
] })
|
|
2090
2330
|
] }),
|
|
2091
|
-
|
|
2331
|
+
!isUser && (msg.knowledgeImages?.length ?? 0) > 0 && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-kimgs", children: msg.knowledgeImages.map((ref) => /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-kimg-group", children: [
|
|
2332
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-kimg-grid", children: ref.images.map((img, i) => /* @__PURE__ */ jsx8(
|
|
2333
|
+
"img",
|
|
2334
|
+
{
|
|
2335
|
+
src: img.url,
|
|
2336
|
+
alt: img.note || ref.title || "Reference image",
|
|
2337
|
+
className: "hsk-cb-kimg",
|
|
2338
|
+
loading: "lazy",
|
|
2339
|
+
onClick: () => setLightboxSrc(img.url),
|
|
2340
|
+
onError: (e) => {
|
|
2341
|
+
e.target.style.display = "none";
|
|
2342
|
+
}
|
|
2343
|
+
},
|
|
2344
|
+
i
|
|
2345
|
+
)) }),
|
|
2346
|
+
(ref.title || ref.images[0]?.note) && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-kimg-caption", children: ref.title || ref.images[0]?.note })
|
|
2347
|
+
] }, ref.entryId)) }),
|
|
2348
|
+
showMatrix && /* @__PURE__ */ jsx8(ComparisonMatrix, { sources: compareSources, defaultCurrency }),
|
|
2092
2349
|
(() => {
|
|
2093
2350
|
const msgReferencedIds = isLast ? referencedIds : msg.referencedIds ?? [];
|
|
2094
2351
|
const msgSources = isLast ? sources : msg.sources ?? [];
|
|
2095
2352
|
const msgIntent = isLast ? lastIntent : msg.intent;
|
|
2096
2353
|
const hiddenIntent = msgIntent === "compare" || msgIntent === "capture" || msgIntent === "capture_all" || msgIntent === "delete" || msgIntent === "view_history";
|
|
2097
2354
|
const showCarousel = msgReferencedIds.length > 0 && !hiddenIntent && (!isLast || lastAction?.type !== "request_kiku_key");
|
|
2098
|
-
return showCarousel && /* @__PURE__ */
|
|
2355
|
+
return showCarousel && /* @__PURE__ */ jsx8(
|
|
2099
2356
|
SourcesCarousel,
|
|
2100
2357
|
{
|
|
2101
2358
|
sources: msgSources,
|
|
@@ -2107,11 +2364,11 @@ function ChatModal({
|
|
|
2107
2364
|
}
|
|
2108
2365
|
);
|
|
2109
2366
|
})(),
|
|
2110
|
-
isLast && !loading && lastAction?.url && /* @__PURE__ */
|
|
2367
|
+
isLast && !loading && lastAction?.url && /* @__PURE__ */ jsx8("div", { className: "hsk-action-pills", children: /* @__PURE__ */ jsxs7("a", { className: "hsk-action-pill", href: lastAction.url, children: [
|
|
2111
2368
|
String(lastAction.type || "continue").replace(/_/g, " "),
|
|
2112
2369
|
" \u2192"
|
|
2113
2370
|
] }) }),
|
|
2114
|
-
isLast && !loading && /* @__PURE__ */
|
|
2371
|
+
isLast && !loading && /* @__PURE__ */ jsx8(
|
|
2115
2372
|
SmartContextPills,
|
|
2116
2373
|
{
|
|
2117
2374
|
intent: lastIntent,
|
|
@@ -2123,16 +2380,16 @@ function ChatModal({
|
|
|
2123
2380
|
] })
|
|
2124
2381
|
] }) }, idx);
|
|
2125
2382
|
}),
|
|
2126
|
-
selectedProduct && loading && /* @__PURE__ */
|
|
2383
|
+
selectedProduct && loading && /* @__PURE__ */ jsxs7(
|
|
2127
2384
|
"div",
|
|
2128
2385
|
{
|
|
2129
2386
|
className: "hsk-cb-selected-product",
|
|
2130
2387
|
onClick: () => selectedProduct.url && window.open(selectedProduct.url, "_blank"),
|
|
2131
2388
|
children: [
|
|
2132
|
-
selectedProduct.image && /* @__PURE__ */
|
|
2133
|
-
/* @__PURE__ */
|
|
2134
|
-
/* @__PURE__ */
|
|
2135
|
-
selectedProduct.price && /* @__PURE__ */
|
|
2389
|
+
selectedProduct.image && /* @__PURE__ */ jsx8("img", { className: "hsk-cb-selected-img", src: selectedProduct.image, alt: selectedProduct.name }),
|
|
2390
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-selected-info", children: [
|
|
2391
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-selected-name", children: selectedProduct.name }),
|
|
2392
|
+
selectedProduct.price && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-selected-price", children: [
|
|
2136
2393
|
selectedProduct.currency ?? defaultCurrency,
|
|
2137
2394
|
" ",
|
|
2138
2395
|
parseFloat(String(selectedProduct.price ?? "").replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
@@ -2141,22 +2398,22 @@ function ChatModal({
|
|
|
2141
2398
|
]
|
|
2142
2399
|
}
|
|
2143
2400
|
),
|
|
2144
|
-
loading && !streaming && /* @__PURE__ */
|
|
2145
|
-
/* @__PURE__ */
|
|
2146
|
-
/* @__PURE__ */
|
|
2147
|
-
/* @__PURE__ */
|
|
2148
|
-
/* @__PURE__ */
|
|
2149
|
-
/* @__PURE__ */
|
|
2150
|
-
/* @__PURE__ */
|
|
2151
|
-
/* @__PURE__ */
|
|
2152
|
-
/* @__PURE__ */
|
|
2153
|
-
/* @__PURE__ */
|
|
2401
|
+
loading && !streaming && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-typing-row", style: { display: "flex", alignItems: "center", gap: "10px" }, children: [
|
|
2402
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-thinking-icon", children: [
|
|
2403
|
+
/* @__PURE__ */ jsx8("svg", { className: "hsk-brand-mark", viewBox: "0 0 100 100", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("path", { d: "M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z", transform: "translate(22.7 19) scale(0.62)", fillRule: "evenodd" }) }),
|
|
2404
|
+
/* @__PURE__ */ jsx8("svg", { className: "hsk-brand-mark hsk-brand-mark--sheen", viewBox: "0 0 100 100", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("path", { d: "M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z", transform: "translate(22.7 19) scale(0.62)", fillRule: "evenodd" }) }),
|
|
2405
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-handle-orbit", children: /* @__PURE__ */ jsxs7("span", { className: "hsk-handle-ring", children: [
|
|
2406
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-handle-ball" }),
|
|
2407
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-handle-ball" }),
|
|
2408
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-handle-ball" }),
|
|
2409
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-handle-ball" }),
|
|
2410
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-handle-ball" })
|
|
2154
2411
|
] }) }),
|
|
2155
|
-
/* @__PURE__ */
|
|
2412
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-handle-rest" })
|
|
2156
2413
|
] }),
|
|
2157
|
-
/* @__PURE__ */
|
|
2414
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-cb-thinking-text", children: "Thinking\u2026" })
|
|
2158
2415
|
] }),
|
|
2159
|
-
lastAction?.type === "open_memory" && lastAction.url && !loading && !streaming && /* @__PURE__ */
|
|
2416
|
+
lastAction?.type === "open_memory" && lastAction.url && !loading && !streaming && /* @__PURE__ */ jsxs7(
|
|
2160
2417
|
"a",
|
|
2161
2418
|
{
|
|
2162
2419
|
className: "hsk-cb-memory-pill",
|
|
@@ -2165,23 +2422,23 @@ function ChatModal({
|
|
|
2165
2422
|
rel: "noopener noreferrer",
|
|
2166
2423
|
children: [
|
|
2167
2424
|
"Open my memory on mimi",
|
|
2168
|
-
/* @__PURE__ */
|
|
2425
|
+
/* @__PURE__ */ jsx8(ExternalIcon, {})
|
|
2169
2426
|
]
|
|
2170
2427
|
}
|
|
2171
2428
|
),
|
|
2172
|
-
(stopped || interrupted) && !loading && !streaming && messages.length > 0 && /* @__PURE__ */
|
|
2173
|
-
/* @__PURE__ */
|
|
2174
|
-
/* @__PURE__ */
|
|
2175
|
-
/* @__PURE__ */
|
|
2429
|
+
(stopped || interrupted) && !loading && !streaming && messages.length > 0 && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-stopped", children: [
|
|
2430
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-cb-stopped-label", children: stopped ? "You stopped this response." : "This response was interrupted." }),
|
|
2431
|
+
/* @__PURE__ */ jsxs7("button", { className: "hsk-cb-continue", onClick: continueGenerating, children: [
|
|
2432
|
+
/* @__PURE__ */ jsx8(ContinueIcon, {}),
|
|
2176
2433
|
messages[messages.length - 1]?.role === "assistant" ? "Continue generating" : "Generate response"
|
|
2177
2434
|
] })
|
|
2178
2435
|
] }),
|
|
2179
|
-
error && /* @__PURE__ */
|
|
2180
|
-
keyPhase === "prompt_key" && /* @__PURE__ */
|
|
2181
|
-
/* @__PURE__ */
|
|
2182
|
-
/* @__PURE__ */
|
|
2183
|
-
/* @__PURE__ */
|
|
2184
|
-
/* @__PURE__ */
|
|
2436
|
+
error && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-error", children: getFriendlyError(error) }),
|
|
2437
|
+
keyPhase === "prompt_key" && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-msg", children: [
|
|
2438
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
2439
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-text", children: /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-phone-form", children: [
|
|
2440
|
+
/* @__PURE__ */ jsx8("label", { className: "hsk-cb-phone-label", children: "Paste your public id \u2014 or create one" }),
|
|
2441
|
+
/* @__PURE__ */ jsx8(
|
|
2185
2442
|
"input",
|
|
2186
2443
|
{
|
|
2187
2444
|
type: "text",
|
|
@@ -2193,49 +2450,49 @@ function ChatModal({
|
|
|
2193
2450
|
autoFocus: true
|
|
2194
2451
|
}
|
|
2195
2452
|
),
|
|
2196
|
-
/* @__PURE__ */
|
|
2197
|
-
/* @__PURE__ */
|
|
2198
|
-
/* @__PURE__ */
|
|
2453
|
+
/* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: 8 }, children: [
|
|
2454
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-phone-submit", onClick: handleUseExistingKey, disabled: !keyInput.trim(), children: "Use my id" }),
|
|
2455
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-phone-submit", onClick: handleCreateKey, disabled: minting, children: minting ? "Creating\u2026" : "I'm new \u2014 create one" })
|
|
2199
2456
|
] })
|
|
2200
2457
|
] }) }) })
|
|
2201
2458
|
] }),
|
|
2202
|
-
mintedKey && /* @__PURE__ */
|
|
2203
|
-
/* @__PURE__ */
|
|
2204
|
-
/* @__PURE__ */
|
|
2205
|
-
/* @__PURE__ */
|
|
2206
|
-
/* @__PURE__ */
|
|
2207
|
-
/* @__PURE__ */
|
|
2208
|
-
/* @__PURE__ */
|
|
2209
|
-
/* @__PURE__ */
|
|
2210
|
-
/* @__PURE__ */
|
|
2459
|
+
mintedKey && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-msg", children: [
|
|
2460
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
2461
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-text", children: /* @__PURE__ */ jsxs7("div", { style: { padding: "12px 14px", border: "1px solid var(--hsk-border, #e5e5e5)", borderRadius: "var(--hsk-border-radius, 0px)", display: "flex", flexDirection: "column", gap: 12 }, children: [
|
|
2462
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
2463
|
+
/* @__PURE__ */ jsx8("div", { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 }, children: "Your secret \u2014 shown only once" }),
|
|
2464
|
+
/* @__PURE__ */ jsx8("code", { style: { display: "block", fontSize: 14, fontWeight: 700, marginBottom: 6, wordBreak: "break-all" }, children: mintedKey }),
|
|
2465
|
+
/* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
2466
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => copyValue(mintedKey, "secret"), children: copied === "secret" ? "Copied" : "Copy secret" }),
|
|
2467
|
+
/* @__PURE__ */ jsx8("span", { style: { fontSize: 11, opacity: 0.7 }, children: "Keep it private \u2014 use it to unlock your memory at mimi.akropolys.cloud. If lost, the memory is lost with it." })
|
|
2211
2468
|
] })
|
|
2212
2469
|
] }),
|
|
2213
|
-
mintedPub && /* @__PURE__ */
|
|
2214
|
-
/* @__PURE__ */
|
|
2215
|
-
/* @__PURE__ */
|
|
2216
|
-
/* @__PURE__ */
|
|
2217
|
-
/* @__PURE__ */
|
|
2218
|
-
/* @__PURE__ */
|
|
2470
|
+
mintedPub && /* @__PURE__ */ jsxs7("div", { children: [
|
|
2471
|
+
/* @__PURE__ */ jsx8("div", { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 }, children: "Your public id" }),
|
|
2472
|
+
/* @__PURE__ */ jsx8("code", { style: { display: "block", fontSize: 13, fontWeight: 600, marginBottom: 6, wordBreak: "break-all", opacity: 0.85 }, children: mintedPub }),
|
|
2473
|
+
/* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
2474
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => copyValue(mintedPub, "pub"), children: copied === "pub" ? "Copied" : "Copy id" }),
|
|
2475
|
+
/* @__PURE__ */ jsx8("span", { style: { fontSize: 11, opacity: 0.7 }, children: "Paste this on any site to keep saving to the same memory." })
|
|
2219
2476
|
] })
|
|
2220
2477
|
] }),
|
|
2221
|
-
/* @__PURE__ */
|
|
2478
|
+
/* @__PURE__ */ jsxs7("div", { style: { fontSize: 11, opacity: 0.6 }, children: [
|
|
2222
2479
|
"Hidden in ",
|
|
2223
2480
|
keyCountdown,
|
|
2224
2481
|
"s."
|
|
2225
2482
|
] })
|
|
2226
2483
|
] }) }) })
|
|
2227
2484
|
] }),
|
|
2228
|
-
/* @__PURE__ */
|
|
2485
|
+
/* @__PURE__ */ jsx8("div", { ref: bottomRef, style: { height: 1 } })
|
|
2229
2486
|
] }),
|
|
2230
|
-
/* @__PURE__ */
|
|
2231
|
-
showAtPicker && /* @__PURE__ */
|
|
2487
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-input-wrap", children: [
|
|
2488
|
+
showAtPicker && /* @__PURE__ */ jsx8(
|
|
2232
2489
|
AtPickerMenu,
|
|
2233
2490
|
{
|
|
2234
2491
|
onSelect: handleSelectExtension,
|
|
2235
2492
|
onDismiss: () => setShowAtPicker(false)
|
|
2236
2493
|
}
|
|
2237
2494
|
),
|
|
2238
|
-
showKikuPicker && /* @__PURE__ */
|
|
2495
|
+
showKikuPicker && /* @__PURE__ */ jsx8(
|
|
2239
2496
|
KikuPickerMenu,
|
|
2240
2497
|
{
|
|
2241
2498
|
sources,
|
|
@@ -2248,9 +2505,9 @@ function ChatModal({
|
|
|
2248
2505
|
onDismiss: () => setShowKikuPicker(false)
|
|
2249
2506
|
}
|
|
2250
2507
|
),
|
|
2251
|
-
attachments.length > 0 && /* @__PURE__ */
|
|
2252
|
-
/* @__PURE__ */
|
|
2253
|
-
/* @__PURE__ */
|
|
2508
|
+
attachments.length > 0 && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-img-strip", children: attachments.map((att, i) => /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-img-thumb-wrap", children: [
|
|
2509
|
+
/* @__PURE__ */ jsx8("img", { src: att.data, alt: `attachment ${i + 1}`, className: "hsk-cb-img-thumb" }),
|
|
2510
|
+
/* @__PURE__ */ jsx8(
|
|
2254
2511
|
"button",
|
|
2255
2512
|
{
|
|
2256
2513
|
className: "hsk-cb-img-thumb-remove",
|
|
@@ -2260,8 +2517,8 @@ function ChatModal({
|
|
|
2260
2517
|
}
|
|
2261
2518
|
)
|
|
2262
2519
|
] }, i)) }),
|
|
2263
|
-
/* @__PURE__ */
|
|
2264
|
-
/* @__PURE__ */
|
|
2520
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-input-box", children: [
|
|
2521
|
+
/* @__PURE__ */ jsx8(
|
|
2265
2522
|
"input",
|
|
2266
2523
|
{
|
|
2267
2524
|
ref: imageInputRef,
|
|
@@ -2272,7 +2529,7 @@ function ChatModal({
|
|
|
2272
2529
|
onChange: (e) => handleImageFiles(e.target.files)
|
|
2273
2530
|
}
|
|
2274
2531
|
),
|
|
2275
|
-
enableVision && /* @__PURE__ */
|
|
2532
|
+
enableVision && /* @__PURE__ */ jsx8(
|
|
2276
2533
|
"button",
|
|
2277
2534
|
{
|
|
2278
2535
|
className: "hsk-cb-attach-btn",
|
|
@@ -2280,10 +2537,10 @@ function ChatModal({
|
|
|
2280
2537
|
disabled: loading,
|
|
2281
2538
|
"aria-label": "Attach image",
|
|
2282
2539
|
title: "Attach image",
|
|
2283
|
-
children: /* @__PURE__ */
|
|
2540
|
+
children: /* @__PURE__ */ jsx8(PaperclipIcon, {})
|
|
2284
2541
|
}
|
|
2285
2542
|
),
|
|
2286
|
-
/* @__PURE__ */
|
|
2543
|
+
/* @__PURE__ */ jsx8(
|
|
2287
2544
|
"textarea",
|
|
2288
2545
|
{
|
|
2289
2546
|
ref: textareaRef,
|
|
@@ -2297,7 +2554,7 @@ function ChatModal({
|
|
|
2297
2554
|
autoFocus: true
|
|
2298
2555
|
}
|
|
2299
2556
|
),
|
|
2300
|
-
hasSpeechAPI && enableVoice && /* @__PURE__ */
|
|
2557
|
+
hasSpeechAPI && enableVoice && /* @__PURE__ */ jsxs7(
|
|
2301
2558
|
"button",
|
|
2302
2559
|
{
|
|
2303
2560
|
className: cn(
|
|
@@ -2310,32 +2567,32 @@ function ChatModal({
|
|
|
2310
2567
|
"aria-label": voiceState === "idle" ? "Start voice input" : "Stop recording",
|
|
2311
2568
|
title: voiceState === "idle" ? "Voice input" : "Stop",
|
|
2312
2569
|
children: [
|
|
2313
|
-
voiceState === "listening" ? /* @__PURE__ */
|
|
2314
|
-
voiceState === "listening" && /* @__PURE__ */
|
|
2570
|
+
voiceState === "listening" ? /* @__PURE__ */ jsx8(MicOffIcon, {}) : /* @__PURE__ */ jsx8(MicIcon2, {}),
|
|
2571
|
+
voiceState === "listening" && /* @__PURE__ */ jsx8("span", { className: "hsk-cb-mic-pulse" })
|
|
2315
2572
|
]
|
|
2316
2573
|
}
|
|
2317
2574
|
),
|
|
2318
|
-
loading || streaming ? /* @__PURE__ */
|
|
2575
|
+
loading || streaming ? /* @__PURE__ */ jsx8(
|
|
2319
2576
|
"button",
|
|
2320
2577
|
{
|
|
2321
2578
|
className: cn("hsk-cb-send", "hsk-cb-send--stop", classNames.sendButton),
|
|
2322
2579
|
onClick: stop,
|
|
2323
2580
|
"aria-label": "Stop generating",
|
|
2324
2581
|
title: "Stop generating",
|
|
2325
|
-
children: /* @__PURE__ */
|
|
2582
|
+
children: /* @__PURE__ */ jsx8(StopIcon, {})
|
|
2326
2583
|
}
|
|
2327
|
-
) : /* @__PURE__ */
|
|
2584
|
+
) : /* @__PURE__ */ jsx8(
|
|
2328
2585
|
"button",
|
|
2329
2586
|
{
|
|
2330
2587
|
className: cn("hsk-cb-send", classNames.sendButton),
|
|
2331
2588
|
onClick: () => handleSend(),
|
|
2332
2589
|
disabled: !input.trim() && attachments.length === 0,
|
|
2333
2590
|
"aria-label": "Send message",
|
|
2334
|
-
children: /* @__PURE__ */
|
|
2591
|
+
children: /* @__PURE__ */ jsx8(ArrowUpIcon2, {})
|
|
2335
2592
|
}
|
|
2336
2593
|
)
|
|
2337
2594
|
] }),
|
|
2338
|
-
/* @__PURE__ */
|
|
2595
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-hint", children: "kiku \xB7 searches the whole catalogue in real time" })
|
|
2339
2596
|
] })
|
|
2340
2597
|
] })
|
|
2341
2598
|
]
|
|
@@ -2361,9 +2618,9 @@ function KikuButton({
|
|
|
2361
2618
|
enableVision = false,
|
|
2362
2619
|
visionCategoryHint
|
|
2363
2620
|
}) {
|
|
2364
|
-
const [open, setOpen] =
|
|
2365
|
-
const [mounted, setMounted] =
|
|
2366
|
-
|
|
2621
|
+
const [open, setOpen] = useState6(false);
|
|
2622
|
+
const [mounted, setMounted] = useState6(false);
|
|
2623
|
+
useEffect4(() => {
|
|
2367
2624
|
setMounted(true);
|
|
2368
2625
|
if (typeof window !== "undefined" && !window.__akropolys_nav_patched) {
|
|
2369
2626
|
window.__akropolys_nav_patched = true;
|
|
@@ -2397,8 +2654,8 @@ function KikuButton({
|
|
|
2397
2654
|
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
2398
2655
|
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
2399
2656
|
} : void 0;
|
|
2400
|
-
return /* @__PURE__ */
|
|
2401
|
-
/* @__PURE__ */
|
|
2657
|
+
return /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2658
|
+
/* @__PURE__ */ jsxs7(
|
|
2402
2659
|
"button",
|
|
2403
2660
|
{
|
|
2404
2661
|
className: cn("hsk-cb-btn", classNames.button, className),
|
|
@@ -2407,13 +2664,13 @@ function KikuButton({
|
|
|
2407
2664
|
"data-hsk-theme": hskThemeAttr,
|
|
2408
2665
|
"aria-label": "Open AI chat",
|
|
2409
2666
|
children: [
|
|
2410
|
-
/* @__PURE__ */
|
|
2667
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-cb-btn-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
2411
2668
|
label !== void 0 ? label : null
|
|
2412
2669
|
]
|
|
2413
2670
|
}
|
|
2414
2671
|
),
|
|
2415
2672
|
open && mounted && createPortal(
|
|
2416
|
-
/* @__PURE__ */
|
|
2673
|
+
/* @__PURE__ */ jsx8(
|
|
2417
2674
|
ChatModal,
|
|
2418
2675
|
{
|
|
2419
2676
|
title,
|
|
@@ -2438,11 +2695,11 @@ function KikuButton({
|
|
|
2438
2695
|
}
|
|
2439
2696
|
|
|
2440
2697
|
// src/components/Sparkle.tsx
|
|
2441
|
-
import { useState as
|
|
2698
|
+
import { useState as useState7, useEffect as useEffect5, useRef as useRef7 } from "react";
|
|
2442
2699
|
import { createPortal as createPortal2 } from "react-dom";
|
|
2443
2700
|
import { useSearch as useSearch2, useKiku as useKiku3, useAkropolysContext as useAkropolysContext4 } from "@akropolys/sdk";
|
|
2444
|
-
import { Fragment as Fragment4, jsx as
|
|
2445
|
-
var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */
|
|
2701
|
+
import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2702
|
+
var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsx9(
|
|
2446
2703
|
"svg",
|
|
2447
2704
|
{
|
|
2448
2705
|
className: cn("hsk-brand-mark", className),
|
|
@@ -2451,19 +2708,19 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsx8(
|
|
|
2451
2708
|
viewBox: "0 0 100 100",
|
|
2452
2709
|
xmlns: "http://www.w3.org/2000/svg",
|
|
2453
2710
|
"aria-label": "kiku",
|
|
2454
|
-
children: /* @__PURE__ */
|
|
2455
|
-
/* @__PURE__ */
|
|
2456
|
-
/* @__PURE__ */
|
|
2711
|
+
children: /* @__PURE__ */ jsxs8("g", { transform: "translate(22.7 19) scale(0.62)", fill: "currentColor", fillRule: "evenodd", children: [
|
|
2712
|
+
/* @__PURE__ */ jsx9("path", { d: "M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z" }),
|
|
2713
|
+
/* @__PURE__ */ jsx9("circle", { cx: "55", cy: "82", r: "3.4" })
|
|
2457
2714
|
] })
|
|
2458
2715
|
}
|
|
2459
2716
|
);
|
|
2460
|
-
var CloseIcon2 = () => /* @__PURE__ */
|
|
2461
|
-
/* @__PURE__ */
|
|
2462
|
-
/* @__PURE__ */
|
|
2717
|
+
var CloseIcon2 = () => /* @__PURE__ */ jsxs8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2718
|
+
/* @__PURE__ */ jsx9("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
2719
|
+
/* @__PURE__ */ jsx9("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
2463
2720
|
] });
|
|
2464
|
-
var ArrowUpIcon3 = () => /* @__PURE__ */
|
|
2465
|
-
/* @__PURE__ */
|
|
2466
|
-
/* @__PURE__ */
|
|
2721
|
+
var ArrowUpIcon3 = () => /* @__PURE__ */ jsxs8("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2722
|
+
/* @__PURE__ */ jsx9("path", { d: "m5 12 7-7 7 7" }),
|
|
2723
|
+
/* @__PURE__ */ jsx9("path", { d: "M12 19V5" })
|
|
2467
2724
|
] });
|
|
2468
2725
|
var getFriendlyError2 = (err) => {
|
|
2469
2726
|
let str = "";
|
|
@@ -2497,17 +2754,17 @@ function SparkleModal({
|
|
|
2497
2754
|
product: initialProduct
|
|
2498
2755
|
}) {
|
|
2499
2756
|
const client = useAkropolysContext4();
|
|
2500
|
-
const [fetchedProduct, setFetchedProduct] =
|
|
2757
|
+
const [fetchedProduct, setFetchedProduct] = useState7(null);
|
|
2501
2758
|
const displayProduct = initialProduct || fetchedProduct;
|
|
2502
2759
|
const { results, loading: searchLoading, search } = useSearch2({ type: "vector" });
|
|
2503
2760
|
const { messages, sources, loading: chatLoading, error: chatError, send } = useKiku3();
|
|
2504
|
-
const [chatInput, setChatInput] =
|
|
2505
|
-
const [isMobile, setIsMobile] =
|
|
2506
|
-
const [showSpecs, setShowSpecs] =
|
|
2507
|
-
const [collapseSimilar, setCollapseSimilar] =
|
|
2508
|
-
const chatBottomRef =
|
|
2509
|
-
const chatTextareaRef =
|
|
2510
|
-
|
|
2761
|
+
const [chatInput, setChatInput] = useState7("");
|
|
2762
|
+
const [isMobile, setIsMobile] = useState7(false);
|
|
2763
|
+
const [showSpecs, setShowSpecs] = useState7(false);
|
|
2764
|
+
const [collapseSimilar, setCollapseSimilar] = useState7(false);
|
|
2765
|
+
const chatBottomRef = useRef7(null);
|
|
2766
|
+
const chatTextareaRef = useRef7(null);
|
|
2767
|
+
useEffect5(() => {
|
|
2511
2768
|
if (!initialProduct && !fetchedProduct) {
|
|
2512
2769
|
client.api.searchVector(productName, 1).then((res) => {
|
|
2513
2770
|
if (res.results && res.results.length > 0) {
|
|
@@ -2517,7 +2774,7 @@ function SparkleModal({
|
|
|
2517
2774
|
}
|
|
2518
2775
|
search(productName, limit);
|
|
2519
2776
|
}, [productName, initialProduct, fetchedProduct, client, limit, search]);
|
|
2520
|
-
|
|
2777
|
+
useEffect5(() => {
|
|
2521
2778
|
const handleResize = () => setIsMobile(window.innerWidth <= 768);
|
|
2522
2779
|
handleResize();
|
|
2523
2780
|
if (typeof window !== "undefined") {
|
|
@@ -2525,17 +2782,17 @@ function SparkleModal({
|
|
|
2525
2782
|
return () => window.removeEventListener("resize", handleResize);
|
|
2526
2783
|
}
|
|
2527
2784
|
}, []);
|
|
2528
|
-
|
|
2785
|
+
useEffect5(() => {
|
|
2529
2786
|
if (results.length > 0) onResult?.(results);
|
|
2530
2787
|
}, [results, onResult]);
|
|
2531
|
-
|
|
2788
|
+
useEffect5(() => {
|
|
2532
2789
|
const h = (e) => {
|
|
2533
2790
|
if (e.key === "Escape") onClose();
|
|
2534
2791
|
};
|
|
2535
2792
|
document.addEventListener("keydown", h);
|
|
2536
2793
|
return () => document.removeEventListener("keydown", h);
|
|
2537
2794
|
}, [onClose]);
|
|
2538
|
-
|
|
2795
|
+
useEffect5(() => {
|
|
2539
2796
|
chatBottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
2540
2797
|
}, [messages, chatLoading]);
|
|
2541
2798
|
const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur ?? "16px";
|
|
@@ -2589,7 +2846,7 @@ Question: ${q}`;
|
|
|
2589
2846
|
}
|
|
2590
2847
|
] : messages;
|
|
2591
2848
|
if (isMobile) {
|
|
2592
|
-
return /* @__PURE__ */
|
|
2849
|
+
return /* @__PURE__ */ jsx9(
|
|
2593
2850
|
"div",
|
|
2594
2851
|
{
|
|
2595
2852
|
className: cn("hsk-sp-backdrop hsk-sp-mobile-view", classNames.backdrop),
|
|
@@ -2600,13 +2857,13 @@ Question: ${q}`;
|
|
|
2600
2857
|
background: bg ?? void 0,
|
|
2601
2858
|
...customStyles
|
|
2602
2859
|
},
|
|
2603
|
-
children: /* @__PURE__ */
|
|
2604
|
-
/* @__PURE__ */
|
|
2605
|
-
/* @__PURE__ */
|
|
2606
|
-
/* @__PURE__ */
|
|
2607
|
-
/* @__PURE__ */
|
|
2608
|
-
/* @__PURE__ */
|
|
2609
|
-
displayProduct && /* @__PURE__ */
|
|
2860
|
+
children: /* @__PURE__ */ jsxs8("div", { className: cn("hsk-sp-card hsk-sp-fullscreen hsk-sp-mobile-card", classNames.card), onClick: (e) => e.stopPropagation(), children: [
|
|
2861
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-header", children: [
|
|
2862
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-header-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
2863
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-header-body", children: [
|
|
2864
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-header-title-row", children: [
|
|
2865
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-header-title", children: displayProduct?.name || productName }),
|
|
2866
|
+
displayProduct && /* @__PURE__ */ jsx9(
|
|
2610
2867
|
"button",
|
|
2611
2868
|
{
|
|
2612
2869
|
type: "button",
|
|
@@ -2616,32 +2873,32 @@ Question: ${q}`;
|
|
|
2616
2873
|
}
|
|
2617
2874
|
)
|
|
2618
2875
|
] }),
|
|
2619
|
-
/* @__PURE__ */
|
|
2876
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-header-sub", children: "kiku" })
|
|
2620
2877
|
] }),
|
|
2621
|
-
/* @__PURE__ */
|
|
2878
|
+
/* @__PURE__ */ jsx9("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx9(CloseIcon2, {}) })
|
|
2622
2879
|
] }),
|
|
2623
|
-
searchLoading && /* @__PURE__ */
|
|
2624
|
-
/* @__PURE__ */
|
|
2625
|
-
/* @__PURE__ */
|
|
2880
|
+
searchLoading && /* @__PURE__ */ jsx9("div", { className: "hsk-sp-bar" }),
|
|
2881
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-chat-container", children: [
|
|
2882
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-msgs", children: [
|
|
2626
2883
|
displayMessages.map((msg, idx) => {
|
|
2627
2884
|
const isUser = msg.role === "user";
|
|
2628
|
-
return /* @__PURE__ */
|
|
2629
|
-
/* @__PURE__ */
|
|
2630
|
-
/* @__PURE__ */
|
|
2631
|
-
/* @__PURE__ */
|
|
2632
|
-
idx === 0 && displayProduct && /* @__PURE__ */
|
|
2633
|
-
/* @__PURE__ */
|
|
2634
|
-
/* @__PURE__ */
|
|
2635
|
-
/* @__PURE__ */
|
|
2636
|
-
/* @__PURE__ */
|
|
2637
|
-
/* @__PURE__ */
|
|
2638
|
-
/* @__PURE__ */
|
|
2885
|
+
return /* @__PURE__ */ jsx9("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ jsx9("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ jsx9("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ jsxs8("div", { className: "hsk-cb-ai-msg", children: [
|
|
2886
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
2887
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-ai-body", children: [
|
|
2888
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }),
|
|
2889
|
+
idx === 0 && displayProduct && /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-attachment-deck", children: [
|
|
2890
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-main-card", children: [
|
|
2891
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-main-card-img", children: displayProduct.images?.[0] ? /* @__PURE__ */ jsx9("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ jsx9("span", { children: "\xF0\u0178\u203A\x8D" }) }),
|
|
2892
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-main-card-info", children: [
|
|
2893
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-main-card-brand", children: displayProduct.brand || displayProduct.category || "Product" }),
|
|
2894
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-main-card-name", children: displayProduct.name }),
|
|
2895
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-main-card-price", children: [
|
|
2639
2896
|
displayProduct.currency ?? "KES",
|
|
2640
2897
|
" ",
|
|
2641
2898
|
parseFloat(displayProduct.price?.replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
2642
2899
|
] })
|
|
2643
2900
|
] }),
|
|
2644
|
-
(displayProduct.specs && Object.keys(displayProduct.specs).length > 0 || displayProduct.description) && /* @__PURE__ */
|
|
2901
|
+
(displayProduct.specs && Object.keys(displayProduct.specs).length > 0 || displayProduct.description) && /* @__PURE__ */ jsx9(
|
|
2645
2902
|
"button",
|
|
2646
2903
|
{
|
|
2647
2904
|
type: "button",
|
|
@@ -2660,21 +2917,21 @@ Question: ${q}`;
|
|
|
2660
2917
|
}
|
|
2661
2918
|
);
|
|
2662
2919
|
if (similarProducts.length === 0) return null;
|
|
2663
|
-
return /* @__PURE__ */
|
|
2664
|
-
/* @__PURE__ */
|
|
2665
|
-
/* @__PURE__ */
|
|
2920
|
+
return /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-similar-carousel-inline", children: [
|
|
2921
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-similar-carousel-title", children: "Similar Products" }),
|
|
2922
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-similar-carousel-list", children: similarProducts.map((r) => {
|
|
2666
2923
|
const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, "") || "0");
|
|
2667
2924
|
const currency = r.entity.currency ?? "KES";
|
|
2668
|
-
return /* @__PURE__ */
|
|
2925
|
+
return /* @__PURE__ */ jsxs8(
|
|
2669
2926
|
"div",
|
|
2670
2927
|
{
|
|
2671
2928
|
className: "hsk-sp-mobile-similar-carousel-item",
|
|
2672
2929
|
onClick: () => handleNav(r),
|
|
2673
2930
|
children: [
|
|
2674
|
-
/* @__PURE__ */
|
|
2675
|
-
/* @__PURE__ */
|
|
2676
|
-
/* @__PURE__ */
|
|
2677
|
-
/* @__PURE__ */
|
|
2931
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-similar-carousel-img", children: r.entity.images?.[0] ? /* @__PURE__ */ jsx9("img", { src: r.entity.images[0], alt: r.entity.name }) : /* @__PURE__ */ jsx9("span", { children: "\xF0\u0178\u203A\x8D" }) }),
|
|
2932
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-similar-carousel-meta", children: [
|
|
2933
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-similar-carousel-name", title: r.entity.name, children: r.entity.name }),
|
|
2934
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-similar-carousel-price", children: [
|
|
2678
2935
|
currency,
|
|
2679
2936
|
" ",
|
|
2680
2937
|
price.toLocaleString()
|
|
@@ -2691,19 +2948,19 @@ Question: ${q}`;
|
|
|
2691
2948
|
] })
|
|
2692
2949
|
] }) }, idx);
|
|
2693
2950
|
}),
|
|
2694
|
-
chatLoading && /* @__PURE__ */
|
|
2695
|
-
/* @__PURE__ */
|
|
2696
|
-
/* @__PURE__ */
|
|
2697
|
-
/* @__PURE__ */
|
|
2698
|
-
/* @__PURE__ */
|
|
2699
|
-
/* @__PURE__ */
|
|
2951
|
+
chatLoading && /* @__PURE__ */ jsxs8("div", { className: "hsk-cb-typing-row", children: [
|
|
2952
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
2953
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-typing", children: [
|
|
2954
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" }),
|
|
2955
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" }),
|
|
2956
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" })
|
|
2700
2957
|
] })
|
|
2701
2958
|
] }),
|
|
2702
|
-
chatError && /* @__PURE__ */
|
|
2703
|
-
/* @__PURE__ */
|
|
2959
|
+
chatError && /* @__PURE__ */ jsx9("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
|
|
2960
|
+
/* @__PURE__ */ jsx9("div", { ref: chatBottomRef, style: { height: 1 } })
|
|
2704
2961
|
] }),
|
|
2705
|
-
/* @__PURE__ */
|
|
2706
|
-
/* @__PURE__ */
|
|
2962
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-input-wrap", children: /* @__PURE__ */ jsxs8("div", { className: "hsk-cb-input-box", children: [
|
|
2963
|
+
/* @__PURE__ */ jsx9(
|
|
2707
2964
|
"textarea",
|
|
2708
2965
|
{
|
|
2709
2966
|
ref: chatTextareaRef,
|
|
@@ -2716,34 +2973,34 @@ Question: ${q}`;
|
|
|
2716
2973
|
disabled: chatLoading
|
|
2717
2974
|
}
|
|
2718
2975
|
),
|
|
2719
|
-
/* @__PURE__ */
|
|
2976
|
+
/* @__PURE__ */ jsx9(
|
|
2720
2977
|
"button",
|
|
2721
2978
|
{
|
|
2722
2979
|
className: "hsk-cb-send",
|
|
2723
2980
|
onClick: () => handleSend(),
|
|
2724
2981
|
disabled: !chatInput.trim() || chatLoading,
|
|
2725
2982
|
"aria-label": "Send message",
|
|
2726
|
-
children: /* @__PURE__ */
|
|
2983
|
+
children: /* @__PURE__ */ jsx9(ArrowUpIcon3, {})
|
|
2727
2984
|
}
|
|
2728
2985
|
)
|
|
2729
2986
|
] }) })
|
|
2730
2987
|
] }),
|
|
2731
|
-
showSpecs && displayProduct && /* @__PURE__ */
|
|
2732
|
-
/* @__PURE__ */
|
|
2733
|
-
/* @__PURE__ */
|
|
2734
|
-
/* @__PURE__ */
|
|
2988
|
+
showSpecs && displayProduct && /* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-specs-overlay", onClick: () => setShowSpecs(false), children: /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-specs-drawer", onClick: (e) => e.stopPropagation(), children: [
|
|
2989
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-specs-header", children: [
|
|
2990
|
+
/* @__PURE__ */ jsx9("h3", { children: "Specifications" }),
|
|
2991
|
+
/* @__PURE__ */ jsx9("button", { type: "button", onClick: () => setShowSpecs(false), children: "Close" })
|
|
2735
2992
|
] }),
|
|
2736
|
-
/* @__PURE__ */
|
|
2737
|
-
/* @__PURE__ */
|
|
2738
|
-
displayProduct.description && /* @__PURE__ */
|
|
2739
|
-
/* @__PURE__ */
|
|
2740
|
-
/* @__PURE__ */
|
|
2993
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-specs-body", children: [
|
|
2994
|
+
/* @__PURE__ */ jsx9("h4", { className: "hsk-sp-mobile-specs-title", children: displayProduct.name }),
|
|
2995
|
+
displayProduct.description && /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-specs-desc", children: [
|
|
2996
|
+
/* @__PURE__ */ jsx9("h5", { children: "Description" }),
|
|
2997
|
+
/* @__PURE__ */ jsx9("p", { children: displayProduct.description })
|
|
2741
2998
|
] }),
|
|
2742
|
-
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */
|
|
2743
|
-
/* @__PURE__ */
|
|
2744
|
-
Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */
|
|
2745
|
-
/* @__PURE__ */
|
|
2746
|
-
/* @__PURE__ */
|
|
2999
|
+
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-specs-list", children: [
|
|
3000
|
+
/* @__PURE__ */ jsx9("h5", { children: "Details" }),
|
|
3001
|
+
Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-spec-row", children: [
|
|
3002
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-mobile-spec-label", children: key }),
|
|
3003
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-mobile-spec-value", children: val })
|
|
2747
3004
|
] }, key))
|
|
2748
3005
|
] })
|
|
2749
3006
|
] })
|
|
@@ -2752,7 +3009,7 @@ Question: ${q}`;
|
|
|
2752
3009
|
}
|
|
2753
3010
|
);
|
|
2754
3011
|
}
|
|
2755
|
-
return /* @__PURE__ */
|
|
3012
|
+
return /* @__PURE__ */ jsx9(
|
|
2756
3013
|
"div",
|
|
2757
3014
|
{
|
|
2758
3015
|
className: cn("hsk-sp-backdrop", classNames.backdrop),
|
|
@@ -2763,65 +3020,65 @@ Question: ${q}`;
|
|
|
2763
3020
|
background: bg ?? void 0,
|
|
2764
3021
|
...customStyles
|
|
2765
3022
|
},
|
|
2766
|
-
children: /* @__PURE__ */
|
|
2767
|
-
/* @__PURE__ */
|
|
2768
|
-
/* @__PURE__ */
|
|
2769
|
-
/* @__PURE__ */
|
|
2770
|
-
/* @__PURE__ */
|
|
2771
|
-
/* @__PURE__ */
|
|
3023
|
+
children: /* @__PURE__ */ jsxs8("div", { className: cn("hsk-sp-card hsk-sp-fullscreen", classNames.card), onClick: (e) => e.stopPropagation(), children: [
|
|
3024
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-header", children: [
|
|
3025
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-header-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
3026
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-header-body", children: [
|
|
3027
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-header-title", children: displayProduct?.name || productName }),
|
|
3028
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-header-sub", children: "Ask questions, compare specs, or check similar products" })
|
|
2772
3029
|
] }),
|
|
2773
|
-
/* @__PURE__ */
|
|
3030
|
+
/* @__PURE__ */ jsx9("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx9(CloseIcon2, {}) })
|
|
2774
3031
|
] }),
|
|
2775
|
-
searchLoading && /* @__PURE__ */
|
|
2776
|
-
/* @__PURE__ */
|
|
2777
|
-
/* @__PURE__ */
|
|
2778
|
-
displayProduct && /* @__PURE__ */
|
|
2779
|
-
/* @__PURE__ */
|
|
2780
|
-
/* @__PURE__ */
|
|
2781
|
-
/* @__PURE__ */
|
|
2782
|
-
displayProduct.brand && /* @__PURE__ */
|
|
2783
|
-
displayProduct.category && /* @__PURE__ */
|
|
2784
|
-
/* @__PURE__ */
|
|
2785
|
-
/* @__PURE__ */
|
|
2786
|
-
/* @__PURE__ */
|
|
2787
|
-
/* @__PURE__ */
|
|
2788
|
-
displayProduct.originalPrice && /* @__PURE__ */
|
|
2789
|
-
displayProduct.discount && /* @__PURE__ */
|
|
3032
|
+
searchLoading && /* @__PURE__ */ jsx9("div", { className: "hsk-sp-bar" }),
|
|
3033
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-body", children: [
|
|
3034
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-details-pane", children: [
|
|
3035
|
+
displayProduct && /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-product-profile-container", children: [
|
|
3036
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-product-profile", children: [
|
|
3037
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-details-imgwrap", children: displayProduct.images?.[0] ? /* @__PURE__ */ jsx9("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ jsx9("span", { className: "hsk-sp-img-placeholder", children: "\xF0\u0178\u203A\x8D" }) }),
|
|
3038
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-details-meta", children: [
|
|
3039
|
+
displayProduct.brand && /* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-brand", children: displayProduct.brand }),
|
|
3040
|
+
displayProduct.category && /* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-cat", children: displayProduct.category }),
|
|
3041
|
+
/* @__PURE__ */ jsx9("h2", { className: "hsk-sp-details-name", children: displayProduct.name }),
|
|
3042
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-item-price-row", children: [
|
|
3043
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-currency", children: displayProduct.currency ?? "KES" }),
|
|
3044
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-price", children: parseFloat(displayProduct.price?.replace(/[^0-9.]/g, "") || "0").toLocaleString() }),
|
|
3045
|
+
displayProduct.originalPrice && /* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-original-price", children: parseFloat(displayProduct.originalPrice.replace(/[^0-9.]/g, "") || "0").toLocaleString() }),
|
|
3046
|
+
displayProduct.discount && /* @__PURE__ */ jsxs8("span", { className: "hsk-sp-item-discount", children: [
|
|
2790
3047
|
"(",
|
|
2791
3048
|
displayProduct.discount,
|
|
2792
3049
|
")"
|
|
2793
3050
|
] })
|
|
2794
3051
|
] }),
|
|
2795
|
-
/* @__PURE__ */
|
|
2796
|
-
displayProduct.rating && /* @__PURE__ */
|
|
3052
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-item-meta-badges", children: [
|
|
3053
|
+
displayProduct.rating && /* @__PURE__ */ jsxs8("span", { className: "hsk-sp-meta-badge hsk-sp-meta-badge-rating", children: [
|
|
2797
3054
|
"\xE2\u02DC\u2026 ",
|
|
2798
3055
|
parseFloat(displayProduct.rating.toString()).toFixed(1),
|
|
2799
3056
|
" ",
|
|
2800
3057
|
displayProduct.reviewCount ? `(${displayProduct.reviewCount})` : ""
|
|
2801
3058
|
] }),
|
|
2802
|
-
displayProduct.availability && /* @__PURE__ */
|
|
2803
|
-
displayProduct.stock && !displayProduct.availability && /* @__PURE__ */
|
|
3059
|
+
displayProduct.availability && /* @__PURE__ */ jsx9("span", { className: `hsk-sp-meta-badge hsk-sp-meta-badge-avail ${displayProduct.availability.toLowerCase().includes("in") ? "in-stock" : "out-stock"}`, children: displayProduct.availability }),
|
|
3060
|
+
displayProduct.stock && !displayProduct.availability && /* @__PURE__ */ jsxs8("span", { className: "hsk-sp-meta-badge hsk-sp-meta-badge-stock", children: [
|
|
2804
3061
|
"Stock: ",
|
|
2805
3062
|
displayProduct.stock
|
|
2806
3063
|
] })
|
|
2807
3064
|
] })
|
|
2808
3065
|
] })
|
|
2809
3066
|
] }),
|
|
2810
|
-
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */
|
|
2811
|
-
/* @__PURE__ */
|
|
3067
|
+
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */ jsx9("div", { className: "hsk-sp-specs-horizontal", children: Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-spec-item-horizontal", children: [
|
|
3068
|
+
/* @__PURE__ */ jsxs8("span", { className: "hsk-sp-spec-label-horizontal", children: [
|
|
2812
3069
|
key,
|
|
2813
3070
|
":"
|
|
2814
3071
|
] }),
|
|
2815
|
-
/* @__PURE__ */
|
|
3072
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-spec-value-horizontal", title: val, children: val })
|
|
2816
3073
|
] }, key)) }),
|
|
2817
|
-
displayProduct.description && /* @__PURE__ */
|
|
2818
|
-
/* @__PURE__ */
|
|
2819
|
-
/* @__PURE__ */
|
|
3074
|
+
displayProduct.description && /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-details-desc", children: [
|
|
3075
|
+
/* @__PURE__ */ jsx9("h4", { children: "Description" }),
|
|
3076
|
+
/* @__PURE__ */ jsx9("p", { children: displayProduct.description })
|
|
2820
3077
|
] })
|
|
2821
3078
|
] }),
|
|
2822
|
-
/* @__PURE__ */
|
|
2823
|
-
/* @__PURE__ */
|
|
2824
|
-
/* @__PURE__ */
|
|
3079
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-similar-section", children: [
|
|
3080
|
+
/* @__PURE__ */ jsx9("h3", { children: "Similar Products" }),
|
|
3081
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-results", children: (() => {
|
|
2825
3082
|
const similarProducts = results.filter(
|
|
2826
3083
|
(r) => {
|
|
2827
3084
|
const isSameName = !!(r.entity.name && displayProduct?.name && r.entity.name.toLowerCase() === displayProduct.name.toLowerCase());
|
|
@@ -2830,29 +3087,29 @@ Question: ${q}`;
|
|
|
2830
3087
|
}
|
|
2831
3088
|
);
|
|
2832
3089
|
if (!searchLoading && similarProducts.length === 0) {
|
|
2833
|
-
return /* @__PURE__ */
|
|
3090
|
+
return /* @__PURE__ */ jsx9("div", { className: "hsk-sp-empty", children: "No similar products found." });
|
|
2834
3091
|
}
|
|
2835
3092
|
return similarProducts.map((r, i) => {
|
|
2836
3093
|
const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, "") || "0");
|
|
2837
3094
|
const currency = r.entity.currency ?? "KES";
|
|
2838
|
-
return /* @__PURE__ */
|
|
3095
|
+
return /* @__PURE__ */ jsxs8(
|
|
2839
3096
|
"div",
|
|
2840
3097
|
{
|
|
2841
3098
|
className: cn("hsk-sp-item", classNames.item),
|
|
2842
3099
|
style: { animationDelay: `${i * 55}ms`, cursor: "pointer" },
|
|
2843
3100
|
onClick: () => handleNav(r),
|
|
2844
3101
|
children: [
|
|
2845
|
-
/* @__PURE__ */
|
|
2846
|
-
/* @__PURE__ */
|
|
2847
|
-
/* @__PURE__ */
|
|
2848
|
-
r.entity.category && /* @__PURE__ */
|
|
2849
|
-
/* @__PURE__ */
|
|
3102
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-img-wrap", children: r.entity.images?.[0] ? /* @__PURE__ */ jsx9("img", { src: r.entity.images[0], alt: r.entity.name }) : /* @__PURE__ */ jsx9("span", { className: "hsk-sp-img-placeholder", children: "\xF0\u0178\u203A\x8D" }) }),
|
|
3103
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-item-body", children: [
|
|
3104
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
3105
|
+
r.entity.category && /* @__PURE__ */ jsx9("div", { className: "hsk-sp-item-cat", children: r.entity.category }),
|
|
3106
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-item-name", title: r.entity.name, children: r.entity.name })
|
|
2850
3107
|
] }),
|
|
2851
|
-
/* @__PURE__ */
|
|
2852
|
-
/* @__PURE__ */
|
|
2853
|
-
/* @__PURE__ */
|
|
3108
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-item-price-row", children: [
|
|
3109
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-currency", children: currency }),
|
|
3110
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-price", children: price.toLocaleString() })
|
|
2854
3111
|
] }),
|
|
2855
|
-
/* @__PURE__ */
|
|
3112
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-actions", children: /* @__PURE__ */ jsx9(
|
|
2856
3113
|
"button",
|
|
2857
3114
|
{
|
|
2858
3115
|
className: "hsk-sp-action hsk-sp-action-primary",
|
|
@@ -2872,29 +3129,29 @@ Question: ${q}`;
|
|
|
2872
3129
|
})() })
|
|
2873
3130
|
] })
|
|
2874
3131
|
] }),
|
|
2875
|
-
/* @__PURE__ */
|
|
2876
|
-
/* @__PURE__ */
|
|
3132
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-chat-pane", children: [
|
|
3133
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-msgs", children: [
|
|
2877
3134
|
displayMessages.map((msg, idx) => {
|
|
2878
3135
|
const isUser = msg.role === "user";
|
|
2879
|
-
return /* @__PURE__ */
|
|
2880
|
-
/* @__PURE__ */
|
|
2881
|
-
/* @__PURE__ */
|
|
3136
|
+
return /* @__PURE__ */ jsx9("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ jsx9("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ jsx9("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ jsxs8("div", { className: "hsk-cb-ai-msg", children: [
|
|
3137
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
3138
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }) })
|
|
2882
3139
|
] }) }, idx);
|
|
2883
3140
|
}),
|
|
2884
|
-
chatLoading && /* @__PURE__ */
|
|
2885
|
-
/* @__PURE__ */
|
|
2886
|
-
/* @__PURE__ */
|
|
2887
|
-
/* @__PURE__ */
|
|
2888
|
-
/* @__PURE__ */
|
|
2889
|
-
/* @__PURE__ */
|
|
3141
|
+
chatLoading && /* @__PURE__ */ jsxs8("div", { className: "hsk-cb-typing-row", children: [
|
|
3142
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
3143
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-typing", children: [
|
|
3144
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" }),
|
|
3145
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" }),
|
|
3146
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" })
|
|
2890
3147
|
] })
|
|
2891
3148
|
] }),
|
|
2892
|
-
chatError && /* @__PURE__ */
|
|
2893
|
-
/* @__PURE__ */
|
|
3149
|
+
chatError && /* @__PURE__ */ jsx9("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
|
|
3150
|
+
/* @__PURE__ */ jsx9("div", { ref: chatBottomRef, style: { height: 1 } })
|
|
2894
3151
|
] }),
|
|
2895
|
-
/* @__PURE__ */
|
|
2896
|
-
/* @__PURE__ */
|
|
2897
|
-
/* @__PURE__ */
|
|
3152
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-input-wrap", children: [
|
|
3153
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-input-box", children: [
|
|
3154
|
+
/* @__PURE__ */ jsx9(
|
|
2898
3155
|
"textarea",
|
|
2899
3156
|
{
|
|
2900
3157
|
ref: chatTextareaRef,
|
|
@@ -2907,22 +3164,22 @@ Question: ${q}`;
|
|
|
2907
3164
|
disabled: chatLoading
|
|
2908
3165
|
}
|
|
2909
3166
|
),
|
|
2910
|
-
/* @__PURE__ */
|
|
3167
|
+
/* @__PURE__ */ jsx9(
|
|
2911
3168
|
"button",
|
|
2912
3169
|
{
|
|
2913
3170
|
className: "hsk-cb-send",
|
|
2914
3171
|
onClick: () => handleSend(),
|
|
2915
3172
|
disabled: !chatInput.trim() || chatLoading,
|
|
2916
3173
|
"aria-label": "Send message",
|
|
2917
|
-
children: /* @__PURE__ */
|
|
3174
|
+
children: /* @__PURE__ */ jsx9(ArrowUpIcon3, {})
|
|
2918
3175
|
}
|
|
2919
3176
|
)
|
|
2920
3177
|
] }),
|
|
2921
|
-
/* @__PURE__ */
|
|
3178
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-hint", children: "Akropolys \xB7 instant product knowledge" })
|
|
2922
3179
|
] })
|
|
2923
3180
|
] })
|
|
2924
3181
|
] }),
|
|
2925
|
-
/* @__PURE__ */
|
|
3182
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-footer", children: /* @__PURE__ */ jsx9("span", { className: "hsk-sp-esc", children: "Esc to close" }) })
|
|
2926
3183
|
] })
|
|
2927
3184
|
}
|
|
2928
3185
|
);
|
|
@@ -2940,9 +3197,9 @@ function Sparkle({
|
|
|
2940
3197
|
product,
|
|
2941
3198
|
children
|
|
2942
3199
|
}) {
|
|
2943
|
-
const [open, setOpen] =
|
|
2944
|
-
const [mounted, setMounted] =
|
|
2945
|
-
|
|
3200
|
+
const [open, setOpen] = useState7(false);
|
|
3201
|
+
const [mounted, setMounted] = useState7(false);
|
|
3202
|
+
useEffect5(() => {
|
|
2946
3203
|
setMounted(true);
|
|
2947
3204
|
}, []);
|
|
2948
3205
|
const customStyles = {
|
|
@@ -2952,8 +3209,8 @@ function Sparkle({
|
|
|
2952
3209
|
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
2953
3210
|
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
2954
3211
|
};
|
|
2955
|
-
return /* @__PURE__ */
|
|
2956
|
-
/* @__PURE__ */
|
|
3212
|
+
return /* @__PURE__ */ jsxs8(Fragment4, { children: [
|
|
3213
|
+
/* @__PURE__ */ jsx9(
|
|
2957
3214
|
"button",
|
|
2958
3215
|
{
|
|
2959
3216
|
className: cn("hsk-sp-btn", classNames.button, className),
|
|
@@ -2961,11 +3218,11 @@ function Sparkle({
|
|
|
2961
3218
|
style: customStyles,
|
|
2962
3219
|
title: "Find similar products",
|
|
2963
3220
|
"aria-label": "Find similar products",
|
|
2964
|
-
children: children || /* @__PURE__ */
|
|
3221
|
+
children: children || /* @__PURE__ */ jsx9(SparkleIcon3, {})
|
|
2965
3222
|
}
|
|
2966
3223
|
),
|
|
2967
3224
|
open && mounted && createPortal2(
|
|
2968
|
-
/* @__PURE__ */
|
|
3225
|
+
/* @__PURE__ */ jsx9(
|
|
2969
3226
|
SparkleModal,
|
|
2970
3227
|
{
|
|
2971
3228
|
productName,
|