@akropolys/kiku 1.7.8 → 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 +660 -425
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +652 -417
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +195 -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,20 +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
|
-
isComplete ? /* @__PURE__ */
|
|
1611
|
-
/* @__PURE__ */
|
|
1612
|
-
/* @__PURE__ */
|
|
1613
|
-
] }) : /* @__PURE__ */
|
|
1614
|
-
/* @__PURE__ */
|
|
1615
|
-
/* @__PURE__ */
|
|
1616
|
-
/* @__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", {})
|
|
1617
1834
|
] }),
|
|
1618
|
-
/* @__PURE__ */
|
|
1619
|
-
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" })
|
|
1620
1837
|
]
|
|
1621
1838
|
}
|
|
1622
1839
|
),
|
|
1623
|
-
expandable && isOpen && /* @__PURE__ */
|
|
1840
|
+
expandable && isOpen && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-think-body", children: text })
|
|
1624
1841
|
] });
|
|
1625
1842
|
}
|
|
1626
1843
|
function ChatModal({
|
|
@@ -1641,18 +1858,18 @@ function ChatModal({
|
|
|
1641
1858
|
}) {
|
|
1642
1859
|
const client = useAkropolysContext3();
|
|
1643
1860
|
const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, stop, stopped, interrupted, continueGenerating, reset, referencedIds } = useKiku2();
|
|
1644
|
-
const [input, setInput] =
|
|
1645
|
-
const [shopperName, setShopperNameState] =
|
|
1861
|
+
const [input, setInput] = useState6("");
|
|
1862
|
+
const [shopperName, setShopperNameState] = useState6(() => {
|
|
1646
1863
|
try {
|
|
1647
1864
|
return client.getShopperName?.() ?? "";
|
|
1648
1865
|
} catch {
|
|
1649
1866
|
return "";
|
|
1650
1867
|
}
|
|
1651
1868
|
});
|
|
1652
|
-
const [nameSkipped, setNameSkipped] =
|
|
1869
|
+
const [nameSkipped, setNameSkipped] = useState6(false);
|
|
1653
1870
|
const awaitingName = messages.length === 0 && !shopperName && !nameSkipped;
|
|
1654
|
-
const [attachments, setAttachments] =
|
|
1655
|
-
const imageInputRef =
|
|
1871
|
+
const [attachments, setAttachments] = useState6([]);
|
|
1872
|
+
const imageInputRef = useRef6(null);
|
|
1656
1873
|
const handleImageFiles = (files) => {
|
|
1657
1874
|
if (!files || files.length === 0) return;
|
|
1658
1875
|
Array.from(files).forEach((file) => {
|
|
@@ -1670,9 +1887,9 @@ function ChatModal({
|
|
|
1670
1887
|
const removeAttachment = (idx) => {
|
|
1671
1888
|
setAttachments((prev) => prev.filter((_, i) => i !== idx));
|
|
1672
1889
|
};
|
|
1673
|
-
const [voiceState, setVoiceState] =
|
|
1674
|
-
const recognitionRef =
|
|
1675
|
-
const pendingVoiceRef =
|
|
1890
|
+
const [voiceState, setVoiceState] = useState6("idle");
|
|
1891
|
+
const recognitionRef = useRef6(null);
|
|
1892
|
+
const pendingVoiceRef = useRef6(null);
|
|
1676
1893
|
const hasSpeechAPI = typeof window !== "undefined" && ("SpeechRecognition" in window || "webkitSpeechRecognition" in window);
|
|
1677
1894
|
const startVoice = useCallback2(() => {
|
|
1678
1895
|
if (!hasSpeechAPI || voiceState !== "idle") return;
|
|
@@ -1716,21 +1933,22 @@ function ChatModal({
|
|
|
1716
1933
|
recognitionRef.current?.stop();
|
|
1717
1934
|
setVoiceState("idle");
|
|
1718
1935
|
}, []);
|
|
1719
|
-
|
|
1936
|
+
useEffect4(() => {
|
|
1720
1937
|
return () => recognitionRef.current?.abort();
|
|
1721
1938
|
}, []);
|
|
1722
1939
|
const activeChips = chips;
|
|
1723
1940
|
const activeTitle = title;
|
|
1724
1941
|
const activePlaceholder = awaitingName ? "Type your name\u2026" : placeholder;
|
|
1725
|
-
const [selectedProduct, setSelectedProduct] =
|
|
1726
|
-
const [lightboxSrc, setLightboxSrc] =
|
|
1727
|
-
const
|
|
1728
|
-
const
|
|
1729
|
-
const
|
|
1730
|
-
const [
|
|
1731
|
-
const [
|
|
1732
|
-
const [
|
|
1733
|
-
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);
|
|
1734
1952
|
const copyValue = (value, which) => {
|
|
1735
1953
|
try {
|
|
1736
1954
|
navigator.clipboard?.writeText(value);
|
|
@@ -1739,17 +1957,17 @@ function ChatModal({
|
|
|
1739
1957
|
setCopied(which);
|
|
1740
1958
|
setTimeout(() => setCopied((c) => c === which ? null : c), 1600);
|
|
1741
1959
|
};
|
|
1742
|
-
const [keyCountdown, setKeyCountdown] =
|
|
1743
|
-
const [minting, setMinting] =
|
|
1744
|
-
const [showKikuPicker, setShowKikuPicker] =
|
|
1745
|
-
const [showAtPicker, setShowAtPicker] =
|
|
1746
|
-
|
|
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(() => {
|
|
1747
1965
|
if (!lastAction) return;
|
|
1748
1966
|
if (lastAction.type === "request_kiku_key") {
|
|
1749
1967
|
setKeyPhase("prompt_key");
|
|
1750
1968
|
}
|
|
1751
1969
|
}, [lastAction]);
|
|
1752
|
-
|
|
1970
|
+
useEffect4(() => {
|
|
1753
1971
|
if (!mintedKey) return;
|
|
1754
1972
|
setKeyCountdown(KIKU_KEY_REVEAL_SECONDS);
|
|
1755
1973
|
const t = setInterval(() => {
|
|
@@ -1800,9 +2018,9 @@ function ChatModal({
|
|
|
1800
2018
|
setMinting(false);
|
|
1801
2019
|
}
|
|
1802
2020
|
};
|
|
1803
|
-
const msgsContainerRef =
|
|
1804
|
-
const messageRefs =
|
|
1805
|
-
|
|
2021
|
+
const msgsContainerRef = useRef6(null);
|
|
2022
|
+
const messageRefs = useRef6([]);
|
|
2023
|
+
useEffect4(() => {
|
|
1806
2024
|
const container = msgsContainerRef.current;
|
|
1807
2025
|
if (!container) return;
|
|
1808
2026
|
const lastMsg = messages[messages.length - 1];
|
|
@@ -1815,14 +2033,14 @@ function ChatModal({
|
|
|
1815
2033
|
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
1816
2034
|
}
|
|
1817
2035
|
}, [messages, loading, selectedProduct]);
|
|
1818
|
-
|
|
2036
|
+
useEffect4(() => {
|
|
1819
2037
|
const prev = document.body.style.overflow;
|
|
1820
2038
|
document.body.style.overflow = "hidden";
|
|
1821
2039
|
return () => {
|
|
1822
2040
|
document.body.style.overflow = prev;
|
|
1823
2041
|
};
|
|
1824
2042
|
}, []);
|
|
1825
|
-
|
|
2043
|
+
useEffect4(() => {
|
|
1826
2044
|
const h = (e) => {
|
|
1827
2045
|
if (e.key !== "Escape") return;
|
|
1828
2046
|
if (lightboxSrc) {
|
|
@@ -1953,7 +2171,7 @@ function ChatModal({
|
|
|
1953
2171
|
t.style.height = "auto";
|
|
1954
2172
|
t.style.height = `${Math.min(t.scrollHeight, 140)}px`;
|
|
1955
2173
|
};
|
|
1956
|
-
|
|
2174
|
+
useEffect4(() => {
|
|
1957
2175
|
if (voiceState !== "processing") return;
|
|
1958
2176
|
const transcript = pendingVoiceRef.current;
|
|
1959
2177
|
if (!transcript) {
|
|
@@ -1969,7 +2187,7 @@ function ChatModal({
|
|
|
1969
2187
|
}, [voiceState]);
|
|
1970
2188
|
const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur ?? "20px";
|
|
1971
2189
|
const displayMessages = messages;
|
|
1972
|
-
return /* @__PURE__ */
|
|
2190
|
+
return /* @__PURE__ */ jsx8(
|
|
1973
2191
|
"div",
|
|
1974
2192
|
{
|
|
1975
2193
|
className: cn("hsk-cb-overlay", classNames.overlay),
|
|
@@ -1981,7 +2199,7 @@ function ChatModal({
|
|
|
1981
2199
|
...backdropColor ? { background: backdropColor } : {},
|
|
1982
2200
|
...customStyles
|
|
1983
2201
|
},
|
|
1984
|
-
children: /* @__PURE__ */
|
|
2202
|
+
children: /* @__PURE__ */ jsxs7(
|
|
1985
2203
|
"div",
|
|
1986
2204
|
{
|
|
1987
2205
|
className: cn("hsk-cb-panel", classNames.panel),
|
|
@@ -1994,48 +2212,62 @@ function ChatModal({
|
|
|
1994
2212
|
}
|
|
1995
2213
|
},
|
|
1996
2214
|
children: [
|
|
1997
|
-
lightboxSrc && /* @__PURE__ */
|
|
1998
|
-
/* @__PURE__ */
|
|
1999
|
-
/* @__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() })
|
|
2000
2218
|
] }),
|
|
2001
|
-
/* @__PURE__ */
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
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 }) })
|
|
2006
2238
|
] }),
|
|
2007
|
-
/* @__PURE__ */
|
|
2008
|
-
messages.length > 0 && /* @__PURE__ */
|
|
2009
|
-
/* @__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, {}) })
|
|
2010
2242
|
] })
|
|
2011
2243
|
] }),
|
|
2012
|
-
/* @__PURE__ */
|
|
2013
|
-
displayMessages.length === 0 ? /* @__PURE__ */
|
|
2014
|
-
awaitingName ? /* @__PURE__ */
|
|
2015
|
-
/* @__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: [
|
|
2016
2248
|
"Hi, I'm ",
|
|
2017
|
-
/* @__PURE__ */
|
|
2249
|
+
/* @__PURE__ */ jsx8("b", { children: "kiku" }),
|
|
2018
2250
|
"."
|
|
2019
2251
|
] }),
|
|
2020
|
-
/* @__PURE__ */
|
|
2021
|
-
/* @__PURE__ */
|
|
2022
|
-
/* @__PURE__ */
|
|
2023
|
-
] }) : shopperName ? /* @__PURE__ */
|
|
2024
|
-
/* @__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: [
|
|
2025
2257
|
"Hi, ",
|
|
2026
2258
|
shopperName,
|
|
2027
2259
|
"."
|
|
2028
2260
|
] }),
|
|
2029
|
-
/* @__PURE__ */
|
|
2030
|
-
] }) : /* @__PURE__ */
|
|
2031
|
-
/* @__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: [
|
|
2032
2264
|
"Hi, I'm ",
|
|
2033
|
-
/* @__PURE__ */
|
|
2265
|
+
/* @__PURE__ */ jsx8("b", { children: "kiku" }),
|
|
2034
2266
|
"."
|
|
2035
2267
|
] }),
|
|
2036
|
-
/* @__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." })
|
|
2037
2269
|
] }),
|
|
2038
|
-
!awaitingName && activeChips.length > 0 && /* @__PURE__ */
|
|
2270
|
+
!awaitingName && activeChips.length > 0 && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-chips", children: activeChips.map((chip) => /* @__PURE__ */ jsx8(
|
|
2039
2271
|
"button",
|
|
2040
2272
|
{
|
|
2041
2273
|
className: "hsk-cb-chip",
|
|
@@ -2051,36 +2283,36 @@ function ChatModal({
|
|
|
2051
2283
|
const compareSources = sources.filter((s) => s.id && referencedIds.includes(s.id));
|
|
2052
2284
|
const showMatrix = isLast && lastIntent === "compare" && compareSources.length >= 2;
|
|
2053
2285
|
const displayContent = !isUser && showMatrix ? stripMarkdownTables(msg.content) : msg.content;
|
|
2054
|
-
return /* @__PURE__ */
|
|
2286
|
+
return /* @__PURE__ */ jsx8("div", { className: "hsk-cb-msg-group", ref: (el) => {
|
|
2055
2287
|
messageRefs.current[idx] = el;
|
|
2056
|
-
}, children: isUser ? /* @__PURE__ */
|
|
2057
|
-
msg.images && msg.images.length > 0 && /* @__PURE__ */
|
|
2058
|
-
msg.content && /* @__PURE__ */
|
|
2059
|
-
/* @__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" }),
|
|
2060
2292
|
msg.content.replace(/^@kiku\s*/i, "")
|
|
2061
2293
|
] }) : msg.content })
|
|
2062
|
-
] }) : /* @__PURE__ */
|
|
2063
|
-
/* @__PURE__ */
|
|
2064
|
-
/* @__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: [
|
|
2065
2297
|
(() => {
|
|
2066
2298
|
const parsed = parseThinking(displayContent);
|
|
2067
2299
|
const thinking = msg.thinking || parsed.thinking;
|
|
2068
2300
|
const content = parsed.content;
|
|
2069
2301
|
const isComplete = msg.thinking ? content.length > 0 || !(isLast && streaming) : parsed.isComplete;
|
|
2070
|
-
return /* @__PURE__ */
|
|
2071
|
-
(thinking || msg.thoughtForSeconds != null) && /* @__PURE__ */
|
|
2072
|
-
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: [
|
|
2073
2305
|
renderMarkdown(content, isLast && streaming),
|
|
2074
|
-
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" } })
|
|
2075
2307
|
] })
|
|
2076
2308
|
] });
|
|
2077
2309
|
})(),
|
|
2078
|
-
msg.visualizing && /* @__PURE__ */
|
|
2079
|
-
/* @__PURE__ */
|
|
2080
|
-
/* @__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" })
|
|
2081
2313
|
] }),
|
|
2082
|
-
msg.visualization && /* @__PURE__ */
|
|
2083
|
-
/* @__PURE__ */
|
|
2314
|
+
msg.visualization && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-viz", children: [
|
|
2315
|
+
/* @__PURE__ */ jsx8(
|
|
2084
2316
|
"img",
|
|
2085
2317
|
{
|
|
2086
2318
|
src: msg.visualization,
|
|
@@ -2091,10 +2323,13 @@ function ChatModal({
|
|
|
2091
2323
|
}
|
|
2092
2324
|
}
|
|
2093
2325
|
),
|
|
2094
|
-
/* @__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
|
+
] })
|
|
2095
2330
|
] }),
|
|
2096
|
-
!isUser && (msg.knowledgeImages?.length ?? 0) > 0 && /* @__PURE__ */
|
|
2097
|
-
/* @__PURE__ */
|
|
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(
|
|
2098
2333
|
"img",
|
|
2099
2334
|
{
|
|
2100
2335
|
src: img.url,
|
|
@@ -2108,16 +2343,16 @@ function ChatModal({
|
|
|
2108
2343
|
},
|
|
2109
2344
|
i
|
|
2110
2345
|
)) }),
|
|
2111
|
-
(ref.title || ref.images[0]?.note) && /* @__PURE__ */
|
|
2346
|
+
(ref.title || ref.images[0]?.note) && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-kimg-caption", children: ref.title || ref.images[0]?.note })
|
|
2112
2347
|
] }, ref.entryId)) }),
|
|
2113
|
-
showMatrix && /* @__PURE__ */
|
|
2348
|
+
showMatrix && /* @__PURE__ */ jsx8(ComparisonMatrix, { sources: compareSources, defaultCurrency }),
|
|
2114
2349
|
(() => {
|
|
2115
2350
|
const msgReferencedIds = isLast ? referencedIds : msg.referencedIds ?? [];
|
|
2116
2351
|
const msgSources = isLast ? sources : msg.sources ?? [];
|
|
2117
2352
|
const msgIntent = isLast ? lastIntent : msg.intent;
|
|
2118
2353
|
const hiddenIntent = msgIntent === "compare" || msgIntent === "capture" || msgIntent === "capture_all" || msgIntent === "delete" || msgIntent === "view_history";
|
|
2119
2354
|
const showCarousel = msgReferencedIds.length > 0 && !hiddenIntent && (!isLast || lastAction?.type !== "request_kiku_key");
|
|
2120
|
-
return showCarousel && /* @__PURE__ */
|
|
2355
|
+
return showCarousel && /* @__PURE__ */ jsx8(
|
|
2121
2356
|
SourcesCarousel,
|
|
2122
2357
|
{
|
|
2123
2358
|
sources: msgSources,
|
|
@@ -2129,11 +2364,11 @@ function ChatModal({
|
|
|
2129
2364
|
}
|
|
2130
2365
|
);
|
|
2131
2366
|
})(),
|
|
2132
|
-
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: [
|
|
2133
2368
|
String(lastAction.type || "continue").replace(/_/g, " "),
|
|
2134
2369
|
" \u2192"
|
|
2135
2370
|
] }) }),
|
|
2136
|
-
isLast && !loading && /* @__PURE__ */
|
|
2371
|
+
isLast && !loading && /* @__PURE__ */ jsx8(
|
|
2137
2372
|
SmartContextPills,
|
|
2138
2373
|
{
|
|
2139
2374
|
intent: lastIntent,
|
|
@@ -2145,16 +2380,16 @@ function ChatModal({
|
|
|
2145
2380
|
] })
|
|
2146
2381
|
] }) }, idx);
|
|
2147
2382
|
}),
|
|
2148
|
-
selectedProduct && loading && /* @__PURE__ */
|
|
2383
|
+
selectedProduct && loading && /* @__PURE__ */ jsxs7(
|
|
2149
2384
|
"div",
|
|
2150
2385
|
{
|
|
2151
2386
|
className: "hsk-cb-selected-product",
|
|
2152
2387
|
onClick: () => selectedProduct.url && window.open(selectedProduct.url, "_blank"),
|
|
2153
2388
|
children: [
|
|
2154
|
-
selectedProduct.image && /* @__PURE__ */
|
|
2155
|
-
/* @__PURE__ */
|
|
2156
|
-
/* @__PURE__ */
|
|
2157
|
-
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: [
|
|
2158
2393
|
selectedProduct.currency ?? defaultCurrency,
|
|
2159
2394
|
" ",
|
|
2160
2395
|
parseFloat(String(selectedProduct.price ?? "").replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
@@ -2163,22 +2398,22 @@ function ChatModal({
|
|
|
2163
2398
|
]
|
|
2164
2399
|
}
|
|
2165
2400
|
),
|
|
2166
|
-
loading && !streaming && /* @__PURE__ */
|
|
2167
|
-
/* @__PURE__ */
|
|
2168
|
-
/* @__PURE__ */
|
|
2169
|
-
/* @__PURE__ */
|
|
2170
|
-
/* @__PURE__ */
|
|
2171
|
-
/* @__PURE__ */
|
|
2172
|
-
/* @__PURE__ */
|
|
2173
|
-
/* @__PURE__ */
|
|
2174
|
-
/* @__PURE__ */
|
|
2175
|
-
/* @__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" })
|
|
2176
2411
|
] }) }),
|
|
2177
|
-
/* @__PURE__ */
|
|
2412
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-handle-rest" })
|
|
2178
2413
|
] }),
|
|
2179
|
-
/* @__PURE__ */
|
|
2414
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-cb-thinking-text", children: "Thinking\u2026" })
|
|
2180
2415
|
] }),
|
|
2181
|
-
lastAction?.type === "open_memory" && lastAction.url && !loading && !streaming && /* @__PURE__ */
|
|
2416
|
+
lastAction?.type === "open_memory" && lastAction.url && !loading && !streaming && /* @__PURE__ */ jsxs7(
|
|
2182
2417
|
"a",
|
|
2183
2418
|
{
|
|
2184
2419
|
className: "hsk-cb-memory-pill",
|
|
@@ -2187,23 +2422,23 @@ function ChatModal({
|
|
|
2187
2422
|
rel: "noopener noreferrer",
|
|
2188
2423
|
children: [
|
|
2189
2424
|
"Open my memory on mimi",
|
|
2190
|
-
/* @__PURE__ */
|
|
2425
|
+
/* @__PURE__ */ jsx8(ExternalIcon, {})
|
|
2191
2426
|
]
|
|
2192
2427
|
}
|
|
2193
2428
|
),
|
|
2194
|
-
(stopped || interrupted) && !loading && !streaming && messages.length > 0 && /* @__PURE__ */
|
|
2195
|
-
/* @__PURE__ */
|
|
2196
|
-
/* @__PURE__ */
|
|
2197
|
-
/* @__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, {}),
|
|
2198
2433
|
messages[messages.length - 1]?.role === "assistant" ? "Continue generating" : "Generate response"
|
|
2199
2434
|
] })
|
|
2200
2435
|
] }),
|
|
2201
|
-
error && /* @__PURE__ */
|
|
2202
|
-
keyPhase === "prompt_key" && /* @__PURE__ */
|
|
2203
|
-
/* @__PURE__ */
|
|
2204
|
-
/* @__PURE__ */
|
|
2205
|
-
/* @__PURE__ */
|
|
2206
|
-
/* @__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(
|
|
2207
2442
|
"input",
|
|
2208
2443
|
{
|
|
2209
2444
|
type: "text",
|
|
@@ -2215,49 +2450,49 @@ function ChatModal({
|
|
|
2215
2450
|
autoFocus: true
|
|
2216
2451
|
}
|
|
2217
2452
|
),
|
|
2218
|
-
/* @__PURE__ */
|
|
2219
|
-
/* @__PURE__ */
|
|
2220
|
-
/* @__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" })
|
|
2221
2456
|
] })
|
|
2222
2457
|
] }) }) })
|
|
2223
2458
|
] }),
|
|
2224
|
-
mintedKey && /* @__PURE__ */
|
|
2225
|
-
/* @__PURE__ */
|
|
2226
|
-
/* @__PURE__ */
|
|
2227
|
-
/* @__PURE__ */
|
|
2228
|
-
/* @__PURE__ */
|
|
2229
|
-
/* @__PURE__ */
|
|
2230
|
-
/* @__PURE__ */
|
|
2231
|
-
/* @__PURE__ */
|
|
2232
|
-
/* @__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." })
|
|
2233
2468
|
] })
|
|
2234
2469
|
] }),
|
|
2235
|
-
mintedPub && /* @__PURE__ */
|
|
2236
|
-
/* @__PURE__ */
|
|
2237
|
-
/* @__PURE__ */
|
|
2238
|
-
/* @__PURE__ */
|
|
2239
|
-
/* @__PURE__ */
|
|
2240
|
-
/* @__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." })
|
|
2241
2476
|
] })
|
|
2242
2477
|
] }),
|
|
2243
|
-
/* @__PURE__ */
|
|
2478
|
+
/* @__PURE__ */ jsxs7("div", { style: { fontSize: 11, opacity: 0.6 }, children: [
|
|
2244
2479
|
"Hidden in ",
|
|
2245
2480
|
keyCountdown,
|
|
2246
2481
|
"s."
|
|
2247
2482
|
] })
|
|
2248
2483
|
] }) }) })
|
|
2249
2484
|
] }),
|
|
2250
|
-
/* @__PURE__ */
|
|
2485
|
+
/* @__PURE__ */ jsx8("div", { ref: bottomRef, style: { height: 1 } })
|
|
2251
2486
|
] }),
|
|
2252
|
-
/* @__PURE__ */
|
|
2253
|
-
showAtPicker && /* @__PURE__ */
|
|
2487
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-input-wrap", children: [
|
|
2488
|
+
showAtPicker && /* @__PURE__ */ jsx8(
|
|
2254
2489
|
AtPickerMenu,
|
|
2255
2490
|
{
|
|
2256
2491
|
onSelect: handleSelectExtension,
|
|
2257
2492
|
onDismiss: () => setShowAtPicker(false)
|
|
2258
2493
|
}
|
|
2259
2494
|
),
|
|
2260
|
-
showKikuPicker && /* @__PURE__ */
|
|
2495
|
+
showKikuPicker && /* @__PURE__ */ jsx8(
|
|
2261
2496
|
KikuPickerMenu,
|
|
2262
2497
|
{
|
|
2263
2498
|
sources,
|
|
@@ -2270,9 +2505,9 @@ function ChatModal({
|
|
|
2270
2505
|
onDismiss: () => setShowKikuPicker(false)
|
|
2271
2506
|
}
|
|
2272
2507
|
),
|
|
2273
|
-
attachments.length > 0 && /* @__PURE__ */
|
|
2274
|
-
/* @__PURE__ */
|
|
2275
|
-
/* @__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(
|
|
2276
2511
|
"button",
|
|
2277
2512
|
{
|
|
2278
2513
|
className: "hsk-cb-img-thumb-remove",
|
|
@@ -2282,8 +2517,8 @@ function ChatModal({
|
|
|
2282
2517
|
}
|
|
2283
2518
|
)
|
|
2284
2519
|
] }, i)) }),
|
|
2285
|
-
/* @__PURE__ */
|
|
2286
|
-
/* @__PURE__ */
|
|
2520
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-input-box", children: [
|
|
2521
|
+
/* @__PURE__ */ jsx8(
|
|
2287
2522
|
"input",
|
|
2288
2523
|
{
|
|
2289
2524
|
ref: imageInputRef,
|
|
@@ -2294,7 +2529,7 @@ function ChatModal({
|
|
|
2294
2529
|
onChange: (e) => handleImageFiles(e.target.files)
|
|
2295
2530
|
}
|
|
2296
2531
|
),
|
|
2297
|
-
enableVision && /* @__PURE__ */
|
|
2532
|
+
enableVision && /* @__PURE__ */ jsx8(
|
|
2298
2533
|
"button",
|
|
2299
2534
|
{
|
|
2300
2535
|
className: "hsk-cb-attach-btn",
|
|
@@ -2302,10 +2537,10 @@ function ChatModal({
|
|
|
2302
2537
|
disabled: loading,
|
|
2303
2538
|
"aria-label": "Attach image",
|
|
2304
2539
|
title: "Attach image",
|
|
2305
|
-
children: /* @__PURE__ */
|
|
2540
|
+
children: /* @__PURE__ */ jsx8(PaperclipIcon, {})
|
|
2306
2541
|
}
|
|
2307
2542
|
),
|
|
2308
|
-
/* @__PURE__ */
|
|
2543
|
+
/* @__PURE__ */ jsx8(
|
|
2309
2544
|
"textarea",
|
|
2310
2545
|
{
|
|
2311
2546
|
ref: textareaRef,
|
|
@@ -2319,7 +2554,7 @@ function ChatModal({
|
|
|
2319
2554
|
autoFocus: true
|
|
2320
2555
|
}
|
|
2321
2556
|
),
|
|
2322
|
-
hasSpeechAPI && enableVoice && /* @__PURE__ */
|
|
2557
|
+
hasSpeechAPI && enableVoice && /* @__PURE__ */ jsxs7(
|
|
2323
2558
|
"button",
|
|
2324
2559
|
{
|
|
2325
2560
|
className: cn(
|
|
@@ -2332,32 +2567,32 @@ function ChatModal({
|
|
|
2332
2567
|
"aria-label": voiceState === "idle" ? "Start voice input" : "Stop recording",
|
|
2333
2568
|
title: voiceState === "idle" ? "Voice input" : "Stop",
|
|
2334
2569
|
children: [
|
|
2335
|
-
voiceState === "listening" ? /* @__PURE__ */
|
|
2336
|
-
voiceState === "listening" && /* @__PURE__ */
|
|
2570
|
+
voiceState === "listening" ? /* @__PURE__ */ jsx8(MicOffIcon, {}) : /* @__PURE__ */ jsx8(MicIcon2, {}),
|
|
2571
|
+
voiceState === "listening" && /* @__PURE__ */ jsx8("span", { className: "hsk-cb-mic-pulse" })
|
|
2337
2572
|
]
|
|
2338
2573
|
}
|
|
2339
2574
|
),
|
|
2340
|
-
loading || streaming ? /* @__PURE__ */
|
|
2575
|
+
loading || streaming ? /* @__PURE__ */ jsx8(
|
|
2341
2576
|
"button",
|
|
2342
2577
|
{
|
|
2343
2578
|
className: cn("hsk-cb-send", "hsk-cb-send--stop", classNames.sendButton),
|
|
2344
2579
|
onClick: stop,
|
|
2345
2580
|
"aria-label": "Stop generating",
|
|
2346
2581
|
title: "Stop generating",
|
|
2347
|
-
children: /* @__PURE__ */
|
|
2582
|
+
children: /* @__PURE__ */ jsx8(StopIcon, {})
|
|
2348
2583
|
}
|
|
2349
|
-
) : /* @__PURE__ */
|
|
2584
|
+
) : /* @__PURE__ */ jsx8(
|
|
2350
2585
|
"button",
|
|
2351
2586
|
{
|
|
2352
2587
|
className: cn("hsk-cb-send", classNames.sendButton),
|
|
2353
2588
|
onClick: () => handleSend(),
|
|
2354
2589
|
disabled: !input.trim() && attachments.length === 0,
|
|
2355
2590
|
"aria-label": "Send message",
|
|
2356
|
-
children: /* @__PURE__ */
|
|
2591
|
+
children: /* @__PURE__ */ jsx8(ArrowUpIcon2, {})
|
|
2357
2592
|
}
|
|
2358
2593
|
)
|
|
2359
2594
|
] }),
|
|
2360
|
-
/* @__PURE__ */
|
|
2595
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-hint", children: "kiku \xB7 searches the whole catalogue in real time" })
|
|
2361
2596
|
] })
|
|
2362
2597
|
] })
|
|
2363
2598
|
]
|
|
@@ -2383,9 +2618,9 @@ function KikuButton({
|
|
|
2383
2618
|
enableVision = false,
|
|
2384
2619
|
visionCategoryHint
|
|
2385
2620
|
}) {
|
|
2386
|
-
const [open, setOpen] =
|
|
2387
|
-
const [mounted, setMounted] =
|
|
2388
|
-
|
|
2621
|
+
const [open, setOpen] = useState6(false);
|
|
2622
|
+
const [mounted, setMounted] = useState6(false);
|
|
2623
|
+
useEffect4(() => {
|
|
2389
2624
|
setMounted(true);
|
|
2390
2625
|
if (typeof window !== "undefined" && !window.__akropolys_nav_patched) {
|
|
2391
2626
|
window.__akropolys_nav_patched = true;
|
|
@@ -2419,8 +2654,8 @@ function KikuButton({
|
|
|
2419
2654
|
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
2420
2655
|
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
2421
2656
|
} : void 0;
|
|
2422
|
-
return /* @__PURE__ */
|
|
2423
|
-
/* @__PURE__ */
|
|
2657
|
+
return /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2658
|
+
/* @__PURE__ */ jsxs7(
|
|
2424
2659
|
"button",
|
|
2425
2660
|
{
|
|
2426
2661
|
className: cn("hsk-cb-btn", classNames.button, className),
|
|
@@ -2429,13 +2664,13 @@ function KikuButton({
|
|
|
2429
2664
|
"data-hsk-theme": hskThemeAttr,
|
|
2430
2665
|
"aria-label": "Open AI chat",
|
|
2431
2666
|
children: [
|
|
2432
|
-
/* @__PURE__ */
|
|
2667
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-cb-btn-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
2433
2668
|
label !== void 0 ? label : null
|
|
2434
2669
|
]
|
|
2435
2670
|
}
|
|
2436
2671
|
),
|
|
2437
2672
|
open && mounted && createPortal(
|
|
2438
|
-
/* @__PURE__ */
|
|
2673
|
+
/* @__PURE__ */ jsx8(
|
|
2439
2674
|
ChatModal,
|
|
2440
2675
|
{
|
|
2441
2676
|
title,
|
|
@@ -2460,11 +2695,11 @@ function KikuButton({
|
|
|
2460
2695
|
}
|
|
2461
2696
|
|
|
2462
2697
|
// src/components/Sparkle.tsx
|
|
2463
|
-
import { useState as
|
|
2698
|
+
import { useState as useState7, useEffect as useEffect5, useRef as useRef7 } from "react";
|
|
2464
2699
|
import { createPortal as createPortal2 } from "react-dom";
|
|
2465
2700
|
import { useSearch as useSearch2, useKiku as useKiku3, useAkropolysContext as useAkropolysContext4 } from "@akropolys/sdk";
|
|
2466
|
-
import { Fragment as Fragment4, jsx as
|
|
2467
|
-
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(
|
|
2468
2703
|
"svg",
|
|
2469
2704
|
{
|
|
2470
2705
|
className: cn("hsk-brand-mark", className),
|
|
@@ -2473,19 +2708,19 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsx8(
|
|
|
2473
2708
|
viewBox: "0 0 100 100",
|
|
2474
2709
|
xmlns: "http://www.w3.org/2000/svg",
|
|
2475
2710
|
"aria-label": "kiku",
|
|
2476
|
-
children: /* @__PURE__ */
|
|
2477
|
-
/* @__PURE__ */
|
|
2478
|
-
/* @__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" })
|
|
2479
2714
|
] })
|
|
2480
2715
|
}
|
|
2481
2716
|
);
|
|
2482
|
-
var CloseIcon2 = () => /* @__PURE__ */
|
|
2483
|
-
/* @__PURE__ */
|
|
2484
|
-
/* @__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" })
|
|
2485
2720
|
] });
|
|
2486
|
-
var ArrowUpIcon3 = () => /* @__PURE__ */
|
|
2487
|
-
/* @__PURE__ */
|
|
2488
|
-
/* @__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" })
|
|
2489
2724
|
] });
|
|
2490
2725
|
var getFriendlyError2 = (err) => {
|
|
2491
2726
|
let str = "";
|
|
@@ -2519,17 +2754,17 @@ function SparkleModal({
|
|
|
2519
2754
|
product: initialProduct
|
|
2520
2755
|
}) {
|
|
2521
2756
|
const client = useAkropolysContext4();
|
|
2522
|
-
const [fetchedProduct, setFetchedProduct] =
|
|
2757
|
+
const [fetchedProduct, setFetchedProduct] = useState7(null);
|
|
2523
2758
|
const displayProduct = initialProduct || fetchedProduct;
|
|
2524
2759
|
const { results, loading: searchLoading, search } = useSearch2({ type: "vector" });
|
|
2525
2760
|
const { messages, sources, loading: chatLoading, error: chatError, send } = useKiku3();
|
|
2526
|
-
const [chatInput, setChatInput] =
|
|
2527
|
-
const [isMobile, setIsMobile] =
|
|
2528
|
-
const [showSpecs, setShowSpecs] =
|
|
2529
|
-
const [collapseSimilar, setCollapseSimilar] =
|
|
2530
|
-
const chatBottomRef =
|
|
2531
|
-
const chatTextareaRef =
|
|
2532
|
-
|
|
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(() => {
|
|
2533
2768
|
if (!initialProduct && !fetchedProduct) {
|
|
2534
2769
|
client.api.searchVector(productName, 1).then((res) => {
|
|
2535
2770
|
if (res.results && res.results.length > 0) {
|
|
@@ -2539,7 +2774,7 @@ function SparkleModal({
|
|
|
2539
2774
|
}
|
|
2540
2775
|
search(productName, limit);
|
|
2541
2776
|
}, [productName, initialProduct, fetchedProduct, client, limit, search]);
|
|
2542
|
-
|
|
2777
|
+
useEffect5(() => {
|
|
2543
2778
|
const handleResize = () => setIsMobile(window.innerWidth <= 768);
|
|
2544
2779
|
handleResize();
|
|
2545
2780
|
if (typeof window !== "undefined") {
|
|
@@ -2547,17 +2782,17 @@ function SparkleModal({
|
|
|
2547
2782
|
return () => window.removeEventListener("resize", handleResize);
|
|
2548
2783
|
}
|
|
2549
2784
|
}, []);
|
|
2550
|
-
|
|
2785
|
+
useEffect5(() => {
|
|
2551
2786
|
if (results.length > 0) onResult?.(results);
|
|
2552
2787
|
}, [results, onResult]);
|
|
2553
|
-
|
|
2788
|
+
useEffect5(() => {
|
|
2554
2789
|
const h = (e) => {
|
|
2555
2790
|
if (e.key === "Escape") onClose();
|
|
2556
2791
|
};
|
|
2557
2792
|
document.addEventListener("keydown", h);
|
|
2558
2793
|
return () => document.removeEventListener("keydown", h);
|
|
2559
2794
|
}, [onClose]);
|
|
2560
|
-
|
|
2795
|
+
useEffect5(() => {
|
|
2561
2796
|
chatBottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
2562
2797
|
}, [messages, chatLoading]);
|
|
2563
2798
|
const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur ?? "16px";
|
|
@@ -2611,7 +2846,7 @@ Question: ${q}`;
|
|
|
2611
2846
|
}
|
|
2612
2847
|
] : messages;
|
|
2613
2848
|
if (isMobile) {
|
|
2614
|
-
return /* @__PURE__ */
|
|
2849
|
+
return /* @__PURE__ */ jsx9(
|
|
2615
2850
|
"div",
|
|
2616
2851
|
{
|
|
2617
2852
|
className: cn("hsk-sp-backdrop hsk-sp-mobile-view", classNames.backdrop),
|
|
@@ -2622,13 +2857,13 @@ Question: ${q}`;
|
|
|
2622
2857
|
background: bg ?? void 0,
|
|
2623
2858
|
...customStyles
|
|
2624
2859
|
},
|
|
2625
|
-
children: /* @__PURE__ */
|
|
2626
|
-
/* @__PURE__ */
|
|
2627
|
-
/* @__PURE__ */
|
|
2628
|
-
/* @__PURE__ */
|
|
2629
|
-
/* @__PURE__ */
|
|
2630
|
-
/* @__PURE__ */
|
|
2631
|
-
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(
|
|
2632
2867
|
"button",
|
|
2633
2868
|
{
|
|
2634
2869
|
type: "button",
|
|
@@ -2638,32 +2873,32 @@ Question: ${q}`;
|
|
|
2638
2873
|
}
|
|
2639
2874
|
)
|
|
2640
2875
|
] }),
|
|
2641
|
-
/* @__PURE__ */
|
|
2876
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-header-sub", children: "kiku" })
|
|
2642
2877
|
] }),
|
|
2643
|
-
/* @__PURE__ */
|
|
2878
|
+
/* @__PURE__ */ jsx9("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx9(CloseIcon2, {}) })
|
|
2644
2879
|
] }),
|
|
2645
|
-
searchLoading && /* @__PURE__ */
|
|
2646
|
-
/* @__PURE__ */
|
|
2647
|
-
/* @__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: [
|
|
2648
2883
|
displayMessages.map((msg, idx) => {
|
|
2649
2884
|
const isUser = msg.role === "user";
|
|
2650
|
-
return /* @__PURE__ */
|
|
2651
|
-
/* @__PURE__ */
|
|
2652
|
-
/* @__PURE__ */
|
|
2653
|
-
/* @__PURE__ */
|
|
2654
|
-
idx === 0 && displayProduct && /* @__PURE__ */
|
|
2655
|
-
/* @__PURE__ */
|
|
2656
|
-
/* @__PURE__ */
|
|
2657
|
-
/* @__PURE__ */
|
|
2658
|
-
/* @__PURE__ */
|
|
2659
|
-
/* @__PURE__ */
|
|
2660
|
-
/* @__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: [
|
|
2661
2896
|
displayProduct.currency ?? "KES",
|
|
2662
2897
|
" ",
|
|
2663
2898
|
parseFloat(displayProduct.price?.replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
2664
2899
|
] })
|
|
2665
2900
|
] }),
|
|
2666
|
-
(displayProduct.specs && Object.keys(displayProduct.specs).length > 0 || displayProduct.description) && /* @__PURE__ */
|
|
2901
|
+
(displayProduct.specs && Object.keys(displayProduct.specs).length > 0 || displayProduct.description) && /* @__PURE__ */ jsx9(
|
|
2667
2902
|
"button",
|
|
2668
2903
|
{
|
|
2669
2904
|
type: "button",
|
|
@@ -2682,21 +2917,21 @@ Question: ${q}`;
|
|
|
2682
2917
|
}
|
|
2683
2918
|
);
|
|
2684
2919
|
if (similarProducts.length === 0) return null;
|
|
2685
|
-
return /* @__PURE__ */
|
|
2686
|
-
/* @__PURE__ */
|
|
2687
|
-
/* @__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) => {
|
|
2688
2923
|
const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, "") || "0");
|
|
2689
2924
|
const currency = r.entity.currency ?? "KES";
|
|
2690
|
-
return /* @__PURE__ */
|
|
2925
|
+
return /* @__PURE__ */ jsxs8(
|
|
2691
2926
|
"div",
|
|
2692
2927
|
{
|
|
2693
2928
|
className: "hsk-sp-mobile-similar-carousel-item",
|
|
2694
2929
|
onClick: () => handleNav(r),
|
|
2695
2930
|
children: [
|
|
2696
|
-
/* @__PURE__ */
|
|
2697
|
-
/* @__PURE__ */
|
|
2698
|
-
/* @__PURE__ */
|
|
2699
|
-
/* @__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: [
|
|
2700
2935
|
currency,
|
|
2701
2936
|
" ",
|
|
2702
2937
|
price.toLocaleString()
|
|
@@ -2713,19 +2948,19 @@ Question: ${q}`;
|
|
|
2713
2948
|
] })
|
|
2714
2949
|
] }) }, idx);
|
|
2715
2950
|
}),
|
|
2716
|
-
chatLoading && /* @__PURE__ */
|
|
2717
|
-
/* @__PURE__ */
|
|
2718
|
-
/* @__PURE__ */
|
|
2719
|
-
/* @__PURE__ */
|
|
2720
|
-
/* @__PURE__ */
|
|
2721
|
-
/* @__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" })
|
|
2722
2957
|
] })
|
|
2723
2958
|
] }),
|
|
2724
|
-
chatError && /* @__PURE__ */
|
|
2725
|
-
/* @__PURE__ */
|
|
2959
|
+
chatError && /* @__PURE__ */ jsx9("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
|
|
2960
|
+
/* @__PURE__ */ jsx9("div", { ref: chatBottomRef, style: { height: 1 } })
|
|
2726
2961
|
] }),
|
|
2727
|
-
/* @__PURE__ */
|
|
2728
|
-
/* @__PURE__ */
|
|
2962
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-input-wrap", children: /* @__PURE__ */ jsxs8("div", { className: "hsk-cb-input-box", children: [
|
|
2963
|
+
/* @__PURE__ */ jsx9(
|
|
2729
2964
|
"textarea",
|
|
2730
2965
|
{
|
|
2731
2966
|
ref: chatTextareaRef,
|
|
@@ -2738,34 +2973,34 @@ Question: ${q}`;
|
|
|
2738
2973
|
disabled: chatLoading
|
|
2739
2974
|
}
|
|
2740
2975
|
),
|
|
2741
|
-
/* @__PURE__ */
|
|
2976
|
+
/* @__PURE__ */ jsx9(
|
|
2742
2977
|
"button",
|
|
2743
2978
|
{
|
|
2744
2979
|
className: "hsk-cb-send",
|
|
2745
2980
|
onClick: () => handleSend(),
|
|
2746
2981
|
disabled: !chatInput.trim() || chatLoading,
|
|
2747
2982
|
"aria-label": "Send message",
|
|
2748
|
-
children: /* @__PURE__ */
|
|
2983
|
+
children: /* @__PURE__ */ jsx9(ArrowUpIcon3, {})
|
|
2749
2984
|
}
|
|
2750
2985
|
)
|
|
2751
2986
|
] }) })
|
|
2752
2987
|
] }),
|
|
2753
|
-
showSpecs && displayProduct && /* @__PURE__ */
|
|
2754
|
-
/* @__PURE__ */
|
|
2755
|
-
/* @__PURE__ */
|
|
2756
|
-
/* @__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" })
|
|
2757
2992
|
] }),
|
|
2758
|
-
/* @__PURE__ */
|
|
2759
|
-
/* @__PURE__ */
|
|
2760
|
-
displayProduct.description && /* @__PURE__ */
|
|
2761
|
-
/* @__PURE__ */
|
|
2762
|
-
/* @__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 })
|
|
2763
2998
|
] }),
|
|
2764
|
-
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */
|
|
2765
|
-
/* @__PURE__ */
|
|
2766
|
-
Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */
|
|
2767
|
-
/* @__PURE__ */
|
|
2768
|
-
/* @__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 })
|
|
2769
3004
|
] }, key))
|
|
2770
3005
|
] })
|
|
2771
3006
|
] })
|
|
@@ -2774,7 +3009,7 @@ Question: ${q}`;
|
|
|
2774
3009
|
}
|
|
2775
3010
|
);
|
|
2776
3011
|
}
|
|
2777
|
-
return /* @__PURE__ */
|
|
3012
|
+
return /* @__PURE__ */ jsx9(
|
|
2778
3013
|
"div",
|
|
2779
3014
|
{
|
|
2780
3015
|
className: cn("hsk-sp-backdrop", classNames.backdrop),
|
|
@@ -2785,65 +3020,65 @@ Question: ${q}`;
|
|
|
2785
3020
|
background: bg ?? void 0,
|
|
2786
3021
|
...customStyles
|
|
2787
3022
|
},
|
|
2788
|
-
children: /* @__PURE__ */
|
|
2789
|
-
/* @__PURE__ */
|
|
2790
|
-
/* @__PURE__ */
|
|
2791
|
-
/* @__PURE__ */
|
|
2792
|
-
/* @__PURE__ */
|
|
2793
|
-
/* @__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" })
|
|
2794
3029
|
] }),
|
|
2795
|
-
/* @__PURE__ */
|
|
3030
|
+
/* @__PURE__ */ jsx9("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx9(CloseIcon2, {}) })
|
|
2796
3031
|
] }),
|
|
2797
|
-
searchLoading && /* @__PURE__ */
|
|
2798
|
-
/* @__PURE__ */
|
|
2799
|
-
/* @__PURE__ */
|
|
2800
|
-
displayProduct && /* @__PURE__ */
|
|
2801
|
-
/* @__PURE__ */
|
|
2802
|
-
/* @__PURE__ */
|
|
2803
|
-
/* @__PURE__ */
|
|
2804
|
-
displayProduct.brand && /* @__PURE__ */
|
|
2805
|
-
displayProduct.category && /* @__PURE__ */
|
|
2806
|
-
/* @__PURE__ */
|
|
2807
|
-
/* @__PURE__ */
|
|
2808
|
-
/* @__PURE__ */
|
|
2809
|
-
/* @__PURE__ */
|
|
2810
|
-
displayProduct.originalPrice && /* @__PURE__ */
|
|
2811
|
-
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: [
|
|
2812
3047
|
"(",
|
|
2813
3048
|
displayProduct.discount,
|
|
2814
3049
|
")"
|
|
2815
3050
|
] })
|
|
2816
3051
|
] }),
|
|
2817
|
-
/* @__PURE__ */
|
|
2818
|
-
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: [
|
|
2819
3054
|
"\xE2\u02DC\u2026 ",
|
|
2820
3055
|
parseFloat(displayProduct.rating.toString()).toFixed(1),
|
|
2821
3056
|
" ",
|
|
2822
3057
|
displayProduct.reviewCount ? `(${displayProduct.reviewCount})` : ""
|
|
2823
3058
|
] }),
|
|
2824
|
-
displayProduct.availability && /* @__PURE__ */
|
|
2825
|
-
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: [
|
|
2826
3061
|
"Stock: ",
|
|
2827
3062
|
displayProduct.stock
|
|
2828
3063
|
] })
|
|
2829
3064
|
] })
|
|
2830
3065
|
] })
|
|
2831
3066
|
] }),
|
|
2832
|
-
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */
|
|
2833
|
-
/* @__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: [
|
|
2834
3069
|
key,
|
|
2835
3070
|
":"
|
|
2836
3071
|
] }),
|
|
2837
|
-
/* @__PURE__ */
|
|
3072
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-spec-value-horizontal", title: val, children: val })
|
|
2838
3073
|
] }, key)) }),
|
|
2839
|
-
displayProduct.description && /* @__PURE__ */
|
|
2840
|
-
/* @__PURE__ */
|
|
2841
|
-
/* @__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 })
|
|
2842
3077
|
] })
|
|
2843
3078
|
] }),
|
|
2844
|
-
/* @__PURE__ */
|
|
2845
|
-
/* @__PURE__ */
|
|
2846
|
-
/* @__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: (() => {
|
|
2847
3082
|
const similarProducts = results.filter(
|
|
2848
3083
|
(r) => {
|
|
2849
3084
|
const isSameName = !!(r.entity.name && displayProduct?.name && r.entity.name.toLowerCase() === displayProduct.name.toLowerCase());
|
|
@@ -2852,29 +3087,29 @@ Question: ${q}`;
|
|
|
2852
3087
|
}
|
|
2853
3088
|
);
|
|
2854
3089
|
if (!searchLoading && similarProducts.length === 0) {
|
|
2855
|
-
return /* @__PURE__ */
|
|
3090
|
+
return /* @__PURE__ */ jsx9("div", { className: "hsk-sp-empty", children: "No similar products found." });
|
|
2856
3091
|
}
|
|
2857
3092
|
return similarProducts.map((r, i) => {
|
|
2858
3093
|
const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, "") || "0");
|
|
2859
3094
|
const currency = r.entity.currency ?? "KES";
|
|
2860
|
-
return /* @__PURE__ */
|
|
3095
|
+
return /* @__PURE__ */ jsxs8(
|
|
2861
3096
|
"div",
|
|
2862
3097
|
{
|
|
2863
3098
|
className: cn("hsk-sp-item", classNames.item),
|
|
2864
3099
|
style: { animationDelay: `${i * 55}ms`, cursor: "pointer" },
|
|
2865
3100
|
onClick: () => handleNav(r),
|
|
2866
3101
|
children: [
|
|
2867
|
-
/* @__PURE__ */
|
|
2868
|
-
/* @__PURE__ */
|
|
2869
|
-
/* @__PURE__ */
|
|
2870
|
-
r.entity.category && /* @__PURE__ */
|
|
2871
|
-
/* @__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 })
|
|
2872
3107
|
] }),
|
|
2873
|
-
/* @__PURE__ */
|
|
2874
|
-
/* @__PURE__ */
|
|
2875
|
-
/* @__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() })
|
|
2876
3111
|
] }),
|
|
2877
|
-
/* @__PURE__ */
|
|
3112
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-actions", children: /* @__PURE__ */ jsx9(
|
|
2878
3113
|
"button",
|
|
2879
3114
|
{
|
|
2880
3115
|
className: "hsk-sp-action hsk-sp-action-primary",
|
|
@@ -2894,29 +3129,29 @@ Question: ${q}`;
|
|
|
2894
3129
|
})() })
|
|
2895
3130
|
] })
|
|
2896
3131
|
] }),
|
|
2897
|
-
/* @__PURE__ */
|
|
2898
|
-
/* @__PURE__ */
|
|
3132
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-chat-pane", children: [
|
|
3133
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-msgs", children: [
|
|
2899
3134
|
displayMessages.map((msg, idx) => {
|
|
2900
3135
|
const isUser = msg.role === "user";
|
|
2901
|
-
return /* @__PURE__ */
|
|
2902
|
-
/* @__PURE__ */
|
|
2903
|
-
/* @__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) }) })
|
|
2904
3139
|
] }) }, idx);
|
|
2905
3140
|
}),
|
|
2906
|
-
chatLoading && /* @__PURE__ */
|
|
2907
|
-
/* @__PURE__ */
|
|
2908
|
-
/* @__PURE__ */
|
|
2909
|
-
/* @__PURE__ */
|
|
2910
|
-
/* @__PURE__ */
|
|
2911
|
-
/* @__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" })
|
|
2912
3147
|
] })
|
|
2913
3148
|
] }),
|
|
2914
|
-
chatError && /* @__PURE__ */
|
|
2915
|
-
/* @__PURE__ */
|
|
3149
|
+
chatError && /* @__PURE__ */ jsx9("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
|
|
3150
|
+
/* @__PURE__ */ jsx9("div", { ref: chatBottomRef, style: { height: 1 } })
|
|
2916
3151
|
] }),
|
|
2917
|
-
/* @__PURE__ */
|
|
2918
|
-
/* @__PURE__ */
|
|
2919
|
-
/* @__PURE__ */
|
|
3152
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-input-wrap", children: [
|
|
3153
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-input-box", children: [
|
|
3154
|
+
/* @__PURE__ */ jsx9(
|
|
2920
3155
|
"textarea",
|
|
2921
3156
|
{
|
|
2922
3157
|
ref: chatTextareaRef,
|
|
@@ -2929,22 +3164,22 @@ Question: ${q}`;
|
|
|
2929
3164
|
disabled: chatLoading
|
|
2930
3165
|
}
|
|
2931
3166
|
),
|
|
2932
|
-
/* @__PURE__ */
|
|
3167
|
+
/* @__PURE__ */ jsx9(
|
|
2933
3168
|
"button",
|
|
2934
3169
|
{
|
|
2935
3170
|
className: "hsk-cb-send",
|
|
2936
3171
|
onClick: () => handleSend(),
|
|
2937
3172
|
disabled: !chatInput.trim() || chatLoading,
|
|
2938
3173
|
"aria-label": "Send message",
|
|
2939
|
-
children: /* @__PURE__ */
|
|
3174
|
+
children: /* @__PURE__ */ jsx9(ArrowUpIcon3, {})
|
|
2940
3175
|
}
|
|
2941
3176
|
)
|
|
2942
3177
|
] }),
|
|
2943
|
-
/* @__PURE__ */
|
|
3178
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-hint", children: "Akropolys \xB7 instant product knowledge" })
|
|
2944
3179
|
] })
|
|
2945
3180
|
] })
|
|
2946
3181
|
] }),
|
|
2947
|
-
/* @__PURE__ */
|
|
3182
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-footer", children: /* @__PURE__ */ jsx9("span", { className: "hsk-sp-esc", children: "Esc to close" }) })
|
|
2948
3183
|
] })
|
|
2949
3184
|
}
|
|
2950
3185
|
);
|
|
@@ -2962,9 +3197,9 @@ function Sparkle({
|
|
|
2962
3197
|
product,
|
|
2963
3198
|
children
|
|
2964
3199
|
}) {
|
|
2965
|
-
const [open, setOpen] =
|
|
2966
|
-
const [mounted, setMounted] =
|
|
2967
|
-
|
|
3200
|
+
const [open, setOpen] = useState7(false);
|
|
3201
|
+
const [mounted, setMounted] = useState7(false);
|
|
3202
|
+
useEffect5(() => {
|
|
2968
3203
|
setMounted(true);
|
|
2969
3204
|
}, []);
|
|
2970
3205
|
const customStyles = {
|
|
@@ -2974,8 +3209,8 @@ function Sparkle({
|
|
|
2974
3209
|
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
2975
3210
|
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
2976
3211
|
};
|
|
2977
|
-
return /* @__PURE__ */
|
|
2978
|
-
/* @__PURE__ */
|
|
3212
|
+
return /* @__PURE__ */ jsxs8(Fragment4, { children: [
|
|
3213
|
+
/* @__PURE__ */ jsx9(
|
|
2979
3214
|
"button",
|
|
2980
3215
|
{
|
|
2981
3216
|
className: cn("hsk-sp-btn", classNames.button, className),
|
|
@@ -2983,11 +3218,11 @@ function Sparkle({
|
|
|
2983
3218
|
style: customStyles,
|
|
2984
3219
|
title: "Find similar products",
|
|
2985
3220
|
"aria-label": "Find similar products",
|
|
2986
|
-
children: children || /* @__PURE__ */
|
|
3221
|
+
children: children || /* @__PURE__ */ jsx9(SparkleIcon3, {})
|
|
2987
3222
|
}
|
|
2988
3223
|
),
|
|
2989
3224
|
open && mounted && createPortal2(
|
|
2990
|
-
/* @__PURE__ */
|
|
3225
|
+
/* @__PURE__ */ jsx9(
|
|
2991
3226
|
SparkleModal,
|
|
2992
3227
|
{
|
|
2993
3228
|
productName,
|