chordia-ui 3.4.2 → 3.4.3
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/Timeline.cjs.js +6 -1
- package/dist/Timeline.cjs.js.map +1 -1
- package/dist/Timeline.es.js +597 -129
- package/dist/Timeline.es.js.map +1 -1
- package/dist/UpdatedInteractionRecording.cjs.js +1 -1
- package/dist/UpdatedInteractionRecording.cjs.js.map +1 -1
- package/dist/UpdatedInteractionRecording.es.js +260 -258
- package/dist/UpdatedInteractionRecording.es.js.map +1 -1
- package/dist/components/UpdatedInteractionDetails.cjs.js +2 -2
- package/dist/components/UpdatedInteractionDetails.cjs.js.map +1 -1
- package/dist/components/UpdatedInteractionDetails.es.js +349 -322
- package/dist/components/UpdatedInteractionDetails.es.js.map +1 -1
- package/dist/components/media.cjs.js +1 -1
- package/dist/components/media.cjs.js.map +1 -1
- package/dist/components/media.es.js +8 -9
- package/dist/components/media.es.js.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +52 -53
- package/dist/index.es.js.map +1 -1
- package/dist/pages/interactionDetails.cjs.js +2 -2
- package/dist/pages/interactionDetails.cjs.js.map +1 -1
- package/dist/pages/interactionDetails.es.js +16 -17
- package/dist/pages/interactionDetails.es.js.map +1 -1
- package/package.json +1 -1
- package/src/components/UpdatedInteractionDetails/UpdatedInteractionDetails.jsx +35 -1
- package/src/components/UpdatedInteractionDetails/UpdatedInteractionRecording.jsx +142 -124
- package/src/components/UpdatedInteractionDetails/UpdatedInteractionSignals.jsx +14 -6
- package/dist/TranscriptCard.cjs.js +0 -7
- package/dist/TranscriptCard.cjs.js.map +0 -1
- package/dist/TranscriptCard.es.js +0 -474
- package/dist/TranscriptCard.es.js.map +0 -1
package/dist/Timeline.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Timeline.es.js","sources":["../src/components/media/Timeline.jsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { Play, Pause, RotateCcw, RotateCw } from \"lucide-react\";\n\nexport default function Timeline({\n segments = [],\n durationSeconds = 0,\n actorRows = [],\n currentTimeSeconds = 0,\n onSeek,\n showControls = false,\n hasRecording = false,\n timelinePlaying = false,\n playbackRate = 1,\n speedOptions = [1, 1.25, 1.5, 2],\n onTogglePlay,\n onSeekBack,\n onSeekForward,\n onSetPlaybackRate,\n totalDurationLabel,\n}) {\n const [activeControl, setActiveControl] = useState(null);\n\n useEffect(() => {\n if (!activeControl) return;\n const timer = setTimeout(() => setActiveControl(null), 220);\n return () => clearTimeout(timer);\n }, [activeControl]);\n\n const timelineDuration = Math.max(\n Number(durationSeconds) || 0,\n ...segments.map((segment) => Number(segment.endTime) || 0),\n 1\n );\n const clampedCurrent = Math.max(0, Math.min(Number(currentTimeSeconds) || 0, timelineDuration));\n const playheadPercent = timelineDuration > 0 ? (clampedCurrent / timelineDuration) * 100 : 0;\n const playheadLeft = `calc(${playheadPercent}% + ${(5 * (1 - playheadPercent / 100)).toFixed(4)}rem)`;\n\n const formatTime = (seconds) => {\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins.toString().padStart(2, \"0\")}:${secs.toString().padStart(2, \"0\")}`;\n };\n\n const rows = useMemo(() => {\n if (actorRows.length) {\n return actorRows.map((actor) => ({\n ...actor,\n segments: segments.filter((segment) => segment.actor === actor.key),\n }));\n }\n const actors = Array.from(new Set(segments.map((segment) => segment.actor)));\n const actorColors = new Map(segments.map((segment) => [segment.actor, segment.actorColor]));\n return actors.map((actor) => ({\n key: actor,\n label: actor,\n color: actorColors.get(actor) || \"#6B7C93\",\n segments: segments.filter((segment) => segment.actor === actor),\n }));\n }, [actorRows, segments]);\n\n const timeMarkers = [];\n const interval = 120;\n for (let marker = 0; marker <= timelineDuration; marker += interval) {\n timeMarkers.push(marker);\n }\n if (!timeMarkers.length || timeMarkers[timeMarkers.length - 1] < timelineDuration) {\n timeMarkers.push(timelineDuration);\n }\n\n const handleSeekClick = (event) => {\n if (!onSeek) return;\n const rect = event.currentTarget.getBoundingClientRect();\n if (!rect.width) return;\n const ratio = Math.max(0, Math.min((event.clientX - rect.left) / rect.width, 1));\n onSeek(ratio * timelineDuration);\n };\n\n return (\n <div style={{\n padding: \"10px 0\",\n }}>\n {showControls && (\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", marginBottom: 8 }}>\n <div style={{\n fontSize: \"var(--text-sm, 11px)\",\n fontFamily: \"var(--font-mono, monospace)\",\n color: \"var(--text-muted, rgba(30,33,37,0.56))\",\n fontWeight: 500,\n minWidth: 70,\n }}>\n {formatTime(clampedCurrent)} <span style={{ color: \"var(--text-faint, rgba(30,33,37,0.36))\" }}>/ {formatTime(timelineDuration)}</span>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <button\n type=\"button\"\n onClick={() => { setActiveControl(\"rewind\"); onSeekBack?.(); }}\n disabled={!hasRecording}\n title=\"Rewind 15s\"\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n width: 28, height: 28, borderRadius: \"50%\",\n border: `1px solid ${activeControl === \"rewind\" ? \"var(--rail-discovery, #5E88B0)\" : \"var(--border, rgba(52,58,64,0.12))\"}`,\n background: \"var(--paper, rgba(255,255,255,0.78))\", cursor: \"pointer\", padding: 0,\n }}\n >\n <RotateCcw size={13} stroke=\"var(--rail-discovery, #5E88B0)\" />\n </button>\n\n <button\n type=\"button\"\n onClick={onTogglePlay}\n disabled={!hasRecording}\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n width: 32, height: 32, borderRadius: \"50%\",\n background: \"var(--rail-discovery, #5E88B0)\", color: \"#fff\",\n border: \"none\", cursor: \"pointer\", padding: 0,\n }}\n aria-label={timelinePlaying ? \"Pause recording\" : \"Play recording\"}\n >\n {timelinePlaying ? <Pause size={14} /> : <Play size={14} style={{ marginLeft: 1 }} />}\n </button>\n\n <button\n type=\"button\"\n onClick={() => { setActiveControl(\"forward\"); onSeekForward?.(); }}\n disabled={!hasRecording}\n title=\"Forward 15s\"\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n width: 28, height: 28, borderRadius: \"50%\",\n border: `1px solid ${activeControl === \"forward\" ? \"var(--rail-discovery, #5E88B0)\" : \"var(--border, rgba(52,58,64,0.12))\"}`,\n background: \"var(--paper, rgba(255,255,255,0.78))\", cursor: \"pointer\", padding: 0,\n }}\n >\n <RotateCw size={13} stroke=\"var(--rail-discovery, #5E88B0)\" />\n </button>\n\n <div style={{ display: \"inline-flex\", alignItems: \"center\", gap: 4, borderRadius: 999, border: \"1px solid var(--border, rgba(52,58,64,0.12))\", padding: \"2px 3px\", background: \"var(--paper, rgba(255,255,255,0.78))\", marginLeft: 4 }}>\n {speedOptions.map((speed) => {\n const isActive = playbackRate === speed;\n return (\n <button\n key={speed}\n type=\"button\"\n onClick={() => onSetPlaybackRate?.(speed)}\n disabled={!hasRecording}\n title={`Speed: ${speed}x`}\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n height: 24, minWidth: 38, padding: \"0 6px\", borderRadius: 999,\n border: `1px solid ${isActive ? \"var(--rail-discovery, #5E88B0)\" : \"transparent\"}`,\n background: isActive ? \"var(--rail-discovery, #5E88B0)\" : \"transparent\",\n color: isActive ? \"#fff\" : \"var(--text-muted, rgba(30,33,37,0.56))\",\n fontSize: \"var(--text-xs, 10px)\", fontWeight: 600, cursor: \"pointer\",\n }}\n >\n {speed === 1.5 ? \"1.50x\" : `${speed}x`}\n </button>\n );\n })}\n </div>\n </div>\n </div>\n )}\n\n <div style={{\n background: \"var(--paper, rgba(255,255,255,0.78))\",\n border: \"1px solid var(--border, rgba(52,58,64,0.12))\",\n borderRadius: 10,\n padding: \"12px 16px 10px\",\n }}>\n <div style={{ position: \"relative\" }}>\n {/* Time markers row */}\n <div style={{ display: \"flex\", alignItems: \"center\", marginBottom: 6, height: 16 }}>\n <div style={{ width: \"5rem\", flexShrink: 0 }} />\n <div style={{ position: \"relative\", flex: 1 }}>\n {timeMarkers.map((time) => {\n const percentage = timelineDuration > 0 ? (time / timelineDuration) * 100 : 0;\n return (\n <div\n key={time}\n style={{\n position: \"absolute\",\n fontSize: \"var(--text-xs, 10px)\",\n color: \"var(--text-faint, rgba(30,33,37,0.36))\",\n left: `${percentage}%`,\n transform: \"translateX(-50%)\",\n fontFamily: \"var(--font-mono, monospace)\",\n whiteSpace: \"nowrap\",\n }}\n >\n {formatTime(time)}\n </div>\n );\n })}\n </div>\n </div>\n\n {/* Vertical gridlines */}\n <div\n style={{\n position: \"absolute\",\n pointerEvents: \"none\",\n top: 0,\n bottom: 0,\n left: \"5rem\",\n width: \"calc(100% - 5rem)\",\n zIndex: 20,\n }}\n >\n {timeMarkers.map((time) => {\n const percentage = timelineDuration > 0 ? (time / timelineDuration) * 100 : 0;\n return (\n <div\n key={time}\n style={{\n position: \"absolute\",\n top: 0,\n bottom: 0,\n left: `${percentage}%`,\n borderLeft: \"1px dashed var(--border, rgba(52,58,64,0.12))\",\n transform: \"translateX(-1px)\",\n }}\n />\n );\n })}\n </div>\n\n {/* Swim lanes */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 10, marginTop: 8 }}>\n {rows.map((row) => {\n const isSystem = row.key === \"system\" || row.label === \"System\";\n return (\n <div key={row.key} style={{ display: \"flex\", alignItems: \"center\" }}>\n <div\n style={{\n width: \"5rem\",\n flexShrink: 0,\n fontSize: \"var(--text-sm, 11px)\",\n fontWeight: 600,\n color: \"var(--text-muted, rgba(30,33,37,0.56))\",\n fontFamily: \"var(--font-sans, system-ui, sans-serif)\",\n paddingRight: 8,\n }}\n >\n {row.label}\n </div>\n\n <div\n style={{\n position: \"relative\",\n borderRadius: 4,\n flex: 1,\n height: 18,\n backgroundColor: \"var(--paper-secondary, rgba(244,241,230,0.6))\",\n border: \"1px solid var(--border-subtle, rgba(52,58,64,0.08))\",\n }}\n >\n {row.segments.map((segment, idx) => {\n let leftPercent = timelineDuration > 0 ? (segment.startTime / timelineDuration) * 100 : 0;\n let widthPercent =\n timelineDuration > 0\n ? ((segment.endTime - segment.startTime) / timelineDuration) * 100\n : 0;\n leftPercent = Math.max(0, Math.min(100, leftPercent));\n const rightPercent = leftPercent + widthPercent;\n if (rightPercent > 100) widthPercent = 100 - leftPercent;\n widthPercent = Math.max(0, widthPercent);\n const segmentDuration = segment.endTime - segment.startTime;\n\n if (isSystem && segmentDuration <= 5) {\n return (\n <div\n key={idx}\n style={{\n position: \"absolute\",\n cursor: \"pointer\",\n left: `${leftPercent}%`,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n width: 10,\n height: 10,\n borderRadius: \"50%\",\n backgroundColor: row.color,\n opacity: 0.85,\n }}\n title={`${row.label}: ${formatTime(segment.startTime)}-${formatTime(segment.endTime)}`}\n />\n );\n }\n\n return (\n <div\n key={idx}\n style={{\n position: \"absolute\",\n top: 0,\n bottom: 0,\n left: `${leftPercent}%`,\n width: `${Math.max(widthPercent, 0.7)}%`,\n maxWidth: `${100 - leftPercent}%`,\n backgroundColor: row.color,\n opacity: 0.85,\n borderRadius: 2,\n cursor: \"pointer\",\n transition: \"opacity 0.15s\",\n }}\n title={`${row.label}: ${formatTime(segment.startTime)}-${formatTime(segment.endTime)}`}\n />\n );\n })}\n </div>\n </div>\n );\n })}\n </div>\n\n {/* Playhead */}\n <div\n style={{\n pointerEvents: \"none\",\n position: \"absolute\",\n top: 0,\n bottom: 0,\n width: 2,\n borderRadius: 1,\n backgroundColor: \"var(--rail-discovery, #5E88B0)\",\n opacity: 0.55,\n boxShadow: \"0 0 0 1px rgba(94,136,176,0.10)\",\n left: playheadLeft,\n transform: \"translateX(-50%)\",\n }}\n />\n\n {/* Seek overlay */}\n {onSeek ? (\n <button\n type=\"button\"\n onClick={handleSeekClick}\n style={{\n position: \"absolute\",\n cursor: \"pointer\",\n background: \"transparent\",\n border: \"none\",\n padding: 0,\n margin: 0,\n appearance: \"none\",\n top: 0,\n bottom: 0,\n left: \"5rem\",\n width: \"calc(100% - 5rem)\",\n zIndex: 25,\n }}\n title=\"Click timeline to play from that point\"\n aria-label=\"Click timeline to play from that point\"\n />\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n"],"names":["Timeline","segments","durationSeconds","actorRows","currentTimeSeconds","onSeek","showControls","hasRecording","timelinePlaying","playbackRate","speedOptions","onTogglePlay","onSeekBack","onSeekForward","onSetPlaybackRate","totalDurationLabel","activeControl","setActiveControl","useState","useEffect","timer","timelineDuration","segment","clampedCurrent","playheadPercent","playheadLeft","formatTime","seconds","mins","secs","rows","useMemo","actor","actors","actorColors","timeMarkers","interval","marker","handleSeekClick","event","rect","ratio","jsxs","jsx","RotateCcw","Pause","Play","RotateCw","speed","isActive","time","percentage","row","isSystem","idx","leftPercent","widthPercent","segmentDuration"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Timeline.es.js","sources":["../src/components/media/ConversationTurn.jsx","../src/components/media/TranscriptCard.jsx","../src/components/media/Timeline.jsx"],"sourcesContent":["\"use client\";\n\nimport React, { useEffect } from \"react\";\n\n/**\n * Actor configuration — rail color + subtle card tint per role.\n * Colors reference CSS custom properties from the Chordia design system.\n */\nconst ACTOR_DEFAULTS = {\n customer: {\n label: \"Customer\",\n railColor: \"var(--rail-discovery)\",\n cardBg: \"var(--card-customer)\",\n cardBgHighlight: \"rgba(94, 136, 176, 0.12)\",\n borderColor: \"var(--border-subtle)\",\n },\n agent: {\n label: \"Agent\",\n railColor: \"var(--rail-outcome)\",\n cardBg: \"var(--card-agent)\",\n cardBgHighlight: \"rgba(107, 124, 147, 0.10)\",\n borderColor: \"var(--border-subtle)\",\n },\n assistant: {\n label: \"AI Assistant\",\n railColor: \"var(--rail-purple)\",\n cardBg: \"var(--card-assistant)\",\n cardBgHighlight: \"rgba(155, 122, 168, 0.10)\",\n borderColor: \"var(--border-subtle)\",\n },\n system: {\n label: \"System\",\n railColor: \"var(--text-faint)\",\n cardBg: \"transparent\",\n cardBgHighlight: \"transparent\",\n borderColor: \"transparent\",\n },\n};\n\n/**\n * ConversationTurn Component\n * Displays a single turn in a live conversation stream.\n * Uses the TranscriptCard design language: left actor rail, uppercase label,\n * subtle per-actor card tinting.\n *\n * @param {Object} props\n * @param {string} props.role - \"customer\" | \"agent\" | \"assistant\" | \"system\"\n * @param {string} props.text - Message content\n * @param {string} [props.actorLabel] - Override the default actor label\n * @param {string} [props.actorRailColor] - Override the rail color for this turn\n * @param {string} [props.actionKicker] - NBA action label above message\n * @param {Array} [props.toolBadges] - [{name, success, pending}] tool call results\n * @param {boolean} [props.streaming] - Whether this message is actively streaming\n * @param {string} [props.meta] - Timing info, turn number, etc.\n * @param {string} [props.timeRange] - Time range label (e.g., \"00:03–00:07\")\n * @param {boolean} [props.isHighlighted] - Extra emphasis on this turn\n * @param {string} [props.highlightRailColor] - Color for the right highlight rail (when highlighted)\n * @param {React.ReactNode} [props.children] - Additional content below the message text\n */\nconst KEYFRAMES_ID = \"conversation-turn-keyframes\";\nfunction ensureKeyframes() {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(KEYFRAMES_ID)) return;\n const style = document.createElement(\"style\");\n style.id = KEYFRAMES_ID;\n style.textContent = `\n @keyframes turn-playing-pulse {\n 0%, 100% { opacity: 0.4; }\n 50% { opacity: 0.9; }\n }\n `;\n document.head.appendChild(style);\n}\n\nexport default function ConversationTurn({\n role = \"agent\",\n text,\n actorLabel,\n actorRailColor,\n actionKicker,\n toolBadges,\n streaming = false,\n meta,\n timeRange,\n isHighlighted = false,\n highlightRailColor,\n observations,\n onObservationClick,\n children,\n}) {\n useEffect(() => { ensureKeyframes(); }, []);\n const actor = ACTOR_DEFAULTS[role] || ACTOR_DEFAULTS.agent;\n const label = actorLabel || actor.label;\n const railColor = actorRailColor || actor.railColor;\n const highlighted = isHighlighted || streaming;\n\n // System messages: minimal centered text, no card\n if (role === \"system\") {\n return (\n <div\n style={{\n textAlign: \"center\",\n padding: \"6px 0\",\n flexShrink: 0,\n fontSize: \"var(--text-sm, 11px)\",\n color: \"var(--text-faint, rgba(30,33,37,0.36))\",\n fontWeight: 500,\n letterSpacing: \"0.02em\",\n }}\n >\n {text}\n </div>\n );\n }\n\n return (\n <div\n style={{\n position: \"relative\",\n padding: \"10px 14px 10px 18px\",\n borderRadius: 10,\n overflow: \"hidden\",\n flexShrink: 0,\n background: highlighted ? actor.cardBgHighlight : actor.cardBg,\n border: `1px solid ${streaming ? railColor : actor.borderColor}`,\n boxShadow: streaming\n ? `0 0 8px ${actor.cardBgHighlight}`\n : \"none\",\n transition: \"background 0.2s, border-color 0.2s, box-shadow 0.2s\",\n }}\n >\n {/* Left actor rail */}\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n bottom: 0,\n width: \"var(--rail-width-thin, 4px)\",\n backgroundColor: railColor,\n borderRadius: \"10px 0 0 10px\",\n }}\n />\n\n {/* Header row: actor label left, tool badges right */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n justifyContent: \"space-between\",\n gap: 8,\n marginBottom: 4,\n }}\n >\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 2 }}>\n {/* Action kicker (NBA label) */}\n {actionKicker ? (\n <div\n style={{\n fontSize: \"var(--text-xs-plus, 10.5px)\",\n fontWeight: 650,\n textTransform: \"uppercase\",\n letterSpacing: \"var(--tracking-label, 0.16em)\",\n color: railColor,\n }}\n >\n {actionKicker}\n </div>\n ) : null}\n\n {/* Actor label */}\n <div\n style={{\n fontSize: \"var(--text-xs-plus, 10.5px)\",\n fontWeight: 650,\n textTransform: \"uppercase\",\n letterSpacing: \"var(--tracking-label, 0.16em)\",\n color: \"var(--text-faint, rgba(30,33,37,0.36))\",\n }}\n >\n {label}\n </div>\n </div>\n\n {/* Tool badges — top right pills, uniform neutral with status dot */}\n {toolBadges && toolBadges.length > 0 ? (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4, flexShrink: 0, justifyContent: \"flex-end\" }}>\n {toolBadges.map((t, i) => {\n const isPending = t.pending;\n const isError = !isPending && t.success === false;\n // Dot color only — rail colors for categorization, not judgment\n const dotColor = isPending\n ? \"var(--rail-discovery, #5E88B0)\"\n : isError\n ? \"var(--rail-compliance, #C98A5A)\"\n : \"var(--text-xfaint, rgba(30,33,37,0.28))\";\n\n return (\n <span\n key={i}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 5,\n fontSize: \"var(--text-xs, 10px)\",\n padding: \"2px 8px 2px 6px\",\n borderRadius: 999,\n background: \"var(--paper, rgba(255,255,255,0.78))\",\n border: \"1px solid var(--border-subtle, rgba(52,58,64,0.08))\",\n color: \"var(--text-faint, rgba(30,33,37,0.36))\",\n fontWeight: 500,\n fontFamily: \"var(--font-fira-code, var(--font-mono, monospace))\",\n letterSpacing: \"0.01em\",\n lineHeight: 1.4,\n whiteSpace: \"nowrap\",\n }}\n >\n <span\n style={{\n width: 5,\n height: 5,\n borderRadius: \"50%\",\n backgroundColor: dotColor,\n flexShrink: 0,\n }}\n />\n {t.name}\n </span>\n );\n })}\n </div>\n ) : null}\n </div>\n\n {/* Message text */}\n <div\n style={{\n fontSize: \"var(--text-md, 13px)\",\n lineHeight: \"var(--leading-normal, 1.5)\",\n color: streaming\n ? \"var(--text-strong, rgba(30,33,37,0.92))\"\n : \"var(--text-base, rgba(30,33,37,0.78))\",\n fontWeight: streaming ? 550 : 400,\n }}\n >\n {text}\n {streaming ? (\n <span\n style={{\n display: \"inline-block\",\n width: 6,\n height: 14,\n background: railColor,\n marginLeft: 2,\n borderRadius: 1,\n animation: \"cursorBlink 0.8s ease-in-out infinite\",\n verticalAlign: \"text-bottom\",\n }}\n />\n ) : null}\n </div>\n\n {/* Time range + play button + observation pills — single row */}\n {timeRange || children || (observations && observations.length > 0) ? (\n <div style={{ marginTop: 6, display: \"flex\", alignItems: \"center\", gap: 6 }}>\n {children}\n {timeRange ? (\n <span\n style={{\n fontSize: \"var(--text-sm, 11px)\",\n padding: \"2px 8px\",\n borderRadius: 999,\n border: \"1px solid var(--border, rgba(52,58,64,0.12))\",\n background: \"var(--timestamp-bg, rgba(255,255,255,0.70))\",\n color: \"var(--text-muted, rgba(30,33,37,0.56))\",\n fontFamily: \"var(--font-mono, monospace)\",\n }}\n >\n {timeRange}\n </span>\n ) : null}\n {observations && observations.length > 0 ? (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4, marginLeft: \"auto\" }}>\n {observations.map((obs, i) => (\n <span\n key={i}\n onClick={obs.onClick || (onObservationClick ? () => onObservationClick(obs) : undefined)}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n fontSize: \"var(--text-xs, 10px)\",\n padding: \"2px 8px\",\n borderRadius: 999,\n background: `color-mix(in srgb, ${obs.color || \"var(--state-present)\"} 12%, transparent)`,\n border: `1px solid color-mix(in srgb, ${obs.color || \"var(--state-present)\"} 25%, transparent)`,\n color: obs.color || \"var(--state-present)\",\n fontWeight: 550,\n lineHeight: 1.4,\n whiteSpace: \"nowrap\",\n cursor: obs.onClick || onObservationClick ? \"pointer\" : \"default\",\n transition: \"background 0.15s\",\n }}\n title={obs.reason || obs.label}\n >\n <span style={{\n width: 4, height: 4, borderRadius: \"50%\",\n backgroundColor: obs.color || \"var(--state-present)\",\n flexShrink: 0, opacity: 0.7,\n }} />\n {obs.label}\n </span>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n\n {/* Meta / timestamp */}\n {meta ? (\n <div\n style={{\n marginTop: 6,\n fontSize: \"var(--text-xs-plus, 10.5px)\",\n color: \"var(--text-faint, rgba(30,33,37,0.36))\",\n fontFamily: \"var(--font-mono, monospace)\",\n }}\n >\n {meta}\n </div>\n ) : null}\n\n {/* Right highlight rail (used by TranscriptCard for active/highlighted turns) */}\n {highlighted && highlightRailColor ? (\n <div\n style={{\n position: \"absolute\",\n right: 8,\n top: 8,\n bottom: 8,\n width: 6,\n borderRadius: 4,\n backgroundColor: highlightRailColor,\n opacity: 0.7,\n animation: \"turn-playing-pulse 1.5s ease-in-out infinite\",\n }}\n />\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useState, useRef, useEffect } from \"react\";\nimport { Play, Pause } from \"lucide-react\";\nimport ConversationTurn from \"./ConversationTurn\";\n\n/**\n * Helper function to parse time range string (e.g., \"00:03–00:07\") to seconds\n */\nconst parseTimeRange = (timeRange) => {\n const [start, end] = timeRange.split(\"–\").map((time) => {\n const [minutes, seconds] = time.split(\":\").map(Number);\n return minutes * 60 + seconds;\n });\n return { start, end };\n};\n\n/**\n * Map TranscriptCard actorType values to ConversationTurn role values.\n * ConversationTurn uses: \"customer\" | \"agent\" | \"assistant\" | \"system\"\n * TranscriptCard uses: \"customer\" | \"agent\" | \"third_party\" | \"system\"\n */\nconst mapActorTypeToRole = (actorType) => {\n const map = {\n customer: \"customer\",\n agent: \"agent\",\n third_party: \"agent\",\n system: \"system\",\n assistant: \"assistant\",\n };\n return map[actorType] || \"agent\";\n};\n\n/**\n * TranscriptCard Component\n * Displays a complete transcript with multiple turns, audio playback,\n * highlighting, and per-turn play buttons. Composes ConversationTurn\n * for individual turn rendering.\n *\n * @param {Object} props - Component props\n * @param {Array} props.turns - Array of transcript turn objects\n * @param {string} props.turns[].actor - Display name (e.g., \"Agent\", \"Customer\")\n * @param {string} props.turns[].actorType - \"agent\" | \"customer\" | \"third_party\" | \"system\" | \"assistant\"\n * @param {string} [props.turns[].actorColor] - Override rail color for this turn\n * @param {string} props.turns[].text - Transcript text\n * @param {string} [props.turns[].timeRange] - Time range (e.g., \"00:03–00:07\")\n * @param {boolean} [props.turns[].isHighlighted] - Whether this turn is highlighted\n * @param {string} [props.turns[].highlightColor] - Color for the right highlight rail\n * @param {Array} [props.turns[].toolBadges] - Tool badge data [{name, success, pending}]\n * @param {string} [props.audioUrl] - Audio URL for segment playback\n * @param {number} [props.activeTurnIndex=-1] - Index of the externally active turn\n * @param {boolean} [props.autoScrollActiveTurn=false] - Auto-scroll to active turn\n * @param {boolean} [props.isExternalPlaying=false] - External playback state\n * @param {Function} [props.onTurnPlayPause] - External playback handler (turn, index) => void\n */\nexport default function TranscriptCard({\n turns,\n audioUrl,\n activeTurnIndex = -1,\n autoScrollActiveTurn = false,\n isExternalPlaying = false,\n onTurnPlayPause,\n}) {\n const [playingSegment, setPlayingSegment] = useState(null);\n const [isPlaying, setIsPlaying] = useState(false);\n const audioRef = useRef(null);\n const endTimeListenerRef = useRef(null);\n const turnRefs = useRef([]);\n const containerRef = useRef(null);\n const lastAutoScrolledIndexRef = useRef(-1);\n const useExternalPlaybackControl = typeof onTurnPlayPause === \"function\";\n const hasExternalPlaybackState = isExternalPlaying !== undefined;\n\n // Initialize audio element\n useEffect(() => {\n if (audioUrl) {\n audioRef.current = new Audio(audioUrl);\n audioRef.current.preload = \"auto\";\n return () => {\n if (audioRef.current) {\n audioRef.current.pause();\n audioRef.current = null;\n }\n };\n }\n }, [audioUrl]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (audioRef.current) {\n audioRef.current.pause();\n if (endTimeListenerRef.current) {\n audioRef.current.removeEventListener(\"timeupdate\", endTimeListenerRef.current);\n }\n }\n };\n }, []);\n\n // Auto-scroll to active turn\n useEffect(() => {\n if (!autoScrollActiveTurn || activeTurnIndex < 0) return;\n const container = containerRef.current;\n const activeNode = turnRefs.current[activeTurnIndex];\n if (!activeNode || !container) return;\n\n const containerRect = container.getBoundingClientRect();\n const activeRect = activeNode.getBoundingClientRect();\n const topPadding = 12;\n const isFullyVisible =\n activeRect.top >= containerRect.top + topPadding &&\n activeRect.bottom <= containerRect.bottom - 8;\n const didScrollForThisTurn = lastAutoScrolledIndexRef.current === activeTurnIndex;\n\n if (!didScrollForThisTurn || !isFullyVisible) {\n const activeTopInContainer = activeRect.top - containerRect.top + container.scrollTop;\n container.scrollTop = Math.max(activeTopInContainer - topPadding, 0);\n }\n lastAutoScrolledIndexRef.current = activeTurnIndex;\n }, [activeTurnIndex, autoScrollActiveTurn]);\n\n const handlePlayPause = (timeRange, index) => {\n if (useExternalPlaybackControl) {\n onTurnPlayPause(turns[index], index);\n return;\n }\n\n if (playingSegment === index && isPlaying) {\n // Pause current segment\n if (audioRef.current) {\n audioRef.current.pause();\n if (endTimeListenerRef.current) {\n audioRef.current.removeEventListener(\"timeupdate\", endTimeListenerRef.current);\n endTimeListenerRef.current = null;\n }\n }\n setIsPlaying(false);\n } else {\n // Start/switch segment\n const previousSegment = playingSegment;\n setPlayingSegment(index);\n\n if (audioUrl && audioRef.current) {\n const { start, end } = parseTimeRange(timeRange);\n\n if (previousSegment !== null && previousSegment !== index) {\n audioRef.current.pause();\n if (endTimeListenerRef.current) {\n audioRef.current.removeEventListener(\"timeupdate\", endTimeListenerRef.current);\n endTimeListenerRef.current = null;\n }\n }\n\n const playSegment = () => {\n if (!audioRef.current) return;\n audioRef.current.currentTime = start;\n\n if (end) {\n const checkEndTime = () => {\n if (audioRef.current && audioRef.current.currentTime >= end) {\n audioRef.current.pause();\n setIsPlaying(false);\n setPlayingSegment(null);\n if (endTimeListenerRef.current) {\n audioRef.current.removeEventListener(\"timeupdate\", endTimeListenerRef.current);\n endTimeListenerRef.current = null;\n }\n }\n };\n endTimeListenerRef.current = checkEndTime;\n audioRef.current.addEventListener(\"timeupdate\", checkEndTime);\n }\n\n audioRef.current.play()\n .then(() => setIsPlaying(true))\n .catch((err) => {\n // Ignore AbortError which occurs when play() is interrupted by pause()\n if (err && err.name === \"AbortError\") {\n return;\n }\n setIsPlaying(false);\n setPlayingSegment(null);\n });\n };\n\n if (audioRef.current.readyState >= 2) {\n playSegment();\n } else {\n audioRef.current.addEventListener(\"loadedmetadata\", playSegment, { once: true });\n audioRef.current.load();\n }\n } else {\n setIsPlaying(true);\n }\n }\n };\n\n return (\n <div\n ref={containerRef}\n className=\"custom-thin-scrollbar-library\"\n style={{\n maxHeight: 560,\n overflowY: \"auto\",\n scrollBehavior: \"smooth\",\n border: \"1px solid var(--border, rgba(52,58,64,0.12))\",\n // borderRadius: \"var(--radius-lg, 12px)\",\n borderRadius: \"12px 0px 0px 12px\",\n background: \"var(--paper-elevated, rgba(255,255,255,0.82))\",\n padding: 16,\n }}\n >\n {/* Section label */}\n <div\n style={{\n fontSize: \"var(--text-xs-plus, 10.5px)\",\n fontWeight: 650,\n textTransform: \"uppercase\",\n letterSpacing: \"var(--tracking-label, 0.16em)\",\n color: \"var(--text-faint, rgba(30,33,37,0.36))\",\n marginBottom: 12,\n }}\n >\n Transcript\n </div>\n\n {/* Turns */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n {turns.map((turn, index) => {\n const isTurnPlaying = (useExternalPlaybackControl || hasExternalPlaybackState)\n ? Boolean(isExternalPlaying) && activeTurnIndex === index\n : playingSegment === index && isPlaying;\n const isTurnHighlighted = Boolean(turn.isHighlighted) || isTurnPlaying;\n const role = mapActorTypeToRole(turn.actorType);\n\n return (\n <div\n key={index}\n ref={(el) => { turnRefs.current[index] = el; }}\n >\n <ConversationTurn\n role={role}\n text={turn.text}\n actorLabel={turn.actor}\n actorRailColor={turn.actorColor}\n timeRange={turn.timeRange}\n isHighlighted={isTurnHighlighted}\n highlightRailColor={isTurnPlaying \n ? (turn.highlightColor || (role === 'agent' ? 'var(--rail-outcome)' : 'var(--rail-discovery)'))\n : turn.highlightColor}\n toolBadges={turn.toolBadges}\n observations={turn.observations}\n onObservationClick={turn.onObservationClick}\n >\n {/* Play/pause button — rendered inline left of time range */}\n {turn.timeRange ? (\n <button\n onClick={() => handlePlayPause(turn.timeRange, index)}\n style={{\n width: 24,\n height: 24,\n borderRadius: \"50%\",\n border: \"1px solid var(--border, rgba(52,58,64,0.12))\",\n background: isTurnPlaying\n ? \"var(--rail-discovery, #5E88B0)\"\n : \"var(--paper, rgba(255,255,255,0.78))\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n padding: 0,\n transition: \"all 0.15s\",\n }}\n aria-label={isTurnPlaying ? `Pause segment ${turn.timeRange}` : `Play segment ${turn.timeRange}`}\n >\n {isTurnPlaying ? (\n <Pause\n style={{ width: 12, height: 12, color: \"var(--paper, #fff)\", fill: \"var(--paper, #fff)\" }}\n strokeWidth={0}\n />\n ) : (\n <Play\n style={{ width: 12, height: 12, color: \"var(--text-muted, rgba(30,33,37,0.56))\", fill: \"var(--text-muted, rgba(30,33,37,0.56))\", marginLeft: 1 }}\n strokeWidth={0}\n />\n )}\n </button>\n ) : null}\n </ConversationTurn>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { Play, Pause, RotateCcw, RotateCw } from \"lucide-react\";\n\nexport default function Timeline({\n segments = [],\n durationSeconds = 0,\n actorRows = [],\n currentTimeSeconds = 0,\n onSeek,\n showControls = false,\n hasRecording = false,\n timelinePlaying = false,\n playbackRate = 1,\n speedOptions = [1, 1.25, 1.5, 2],\n onTogglePlay,\n onSeekBack,\n onSeekForward,\n onSetPlaybackRate,\n totalDurationLabel,\n}) {\n const [activeControl, setActiveControl] = useState(null);\n\n useEffect(() => {\n if (!activeControl) return;\n const timer = setTimeout(() => setActiveControl(null), 220);\n return () => clearTimeout(timer);\n }, [activeControl]);\n\n const timelineDuration = Math.max(\n Number(durationSeconds) || 0,\n ...segments.map((segment) => Number(segment.endTime) || 0),\n 1\n );\n const clampedCurrent = Math.max(0, Math.min(Number(currentTimeSeconds) || 0, timelineDuration));\n const playheadPercent = timelineDuration > 0 ? (clampedCurrent / timelineDuration) * 100 : 0;\n const playheadLeft = `calc(${playheadPercent}% + ${(5 * (1 - playheadPercent / 100)).toFixed(4)}rem)`;\n\n const formatTime = (seconds) => {\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins.toString().padStart(2, \"0\")}:${secs.toString().padStart(2, \"0\")}`;\n };\n\n const rows = useMemo(() => {\n if (actorRows.length) {\n return actorRows.map((actor) => ({\n ...actor,\n segments: segments.filter((segment) => segment.actor === actor.key),\n }));\n }\n const actors = Array.from(new Set(segments.map((segment) => segment.actor)));\n const actorColors = new Map(segments.map((segment) => [segment.actor, segment.actorColor]));\n return actors.map((actor) => ({\n key: actor,\n label: actor,\n color: actorColors.get(actor) || \"#6B7C93\",\n segments: segments.filter((segment) => segment.actor === actor),\n }));\n }, [actorRows, segments]);\n\n const timeMarkers = [];\n const interval = 120;\n for (let marker = 0; marker <= timelineDuration; marker += interval) {\n timeMarkers.push(marker);\n }\n if (!timeMarkers.length || timeMarkers[timeMarkers.length - 1] < timelineDuration) {\n timeMarkers.push(timelineDuration);\n }\n\n const handleSeekClick = (event) => {\n if (!onSeek) return;\n const rect = event.currentTarget.getBoundingClientRect();\n if (!rect.width) return;\n const ratio = Math.max(0, Math.min((event.clientX - rect.left) / rect.width, 1));\n onSeek(ratio * timelineDuration);\n };\n\n return (\n <div style={{\n padding: \"10px 0\",\n }}>\n {showControls && (\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", marginBottom: 8 }}>\n <div style={{\n fontSize: \"var(--text-sm, 11px)\",\n fontFamily: \"var(--font-mono, monospace)\",\n color: \"var(--text-muted, rgba(30,33,37,0.56))\",\n fontWeight: 500,\n minWidth: 70,\n }}>\n {formatTime(clampedCurrent)} <span style={{ color: \"var(--text-faint, rgba(30,33,37,0.36))\" }}>/ {formatTime(timelineDuration)}</span>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <button\n type=\"button\"\n onClick={() => { setActiveControl(\"rewind\"); onSeekBack?.(); }}\n disabled={!hasRecording}\n title=\"Rewind 15s\"\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n width: 28, height: 28, borderRadius: \"50%\",\n border: `1px solid ${activeControl === \"rewind\" ? \"var(--rail-discovery, #5E88B0)\" : \"var(--border, rgba(52,58,64,0.12))\"}`,\n background: \"var(--paper, rgba(255,255,255,0.78))\", cursor: \"pointer\", padding: 0,\n }}\n >\n <RotateCcw size={13} stroke=\"var(--rail-discovery, #5E88B0)\" />\n </button>\n\n <button\n type=\"button\"\n onClick={onTogglePlay}\n disabled={!hasRecording}\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n width: 32, height: 32, borderRadius: \"50%\",\n background: \"var(--rail-discovery, #5E88B0)\", color: \"#fff\",\n border: \"none\", cursor: \"pointer\", padding: 0,\n }}\n aria-label={timelinePlaying ? \"Pause recording\" : \"Play recording\"}\n >\n {timelinePlaying ? <Pause size={14} /> : <Play size={14} style={{ marginLeft: 1 }} />}\n </button>\n\n <button\n type=\"button\"\n onClick={() => { setActiveControl(\"forward\"); onSeekForward?.(); }}\n disabled={!hasRecording}\n title=\"Forward 15s\"\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n width: 28, height: 28, borderRadius: \"50%\",\n border: `1px solid ${activeControl === \"forward\" ? \"var(--rail-discovery, #5E88B0)\" : \"var(--border, rgba(52,58,64,0.12))\"}`,\n background: \"var(--paper, rgba(255,255,255,0.78))\", cursor: \"pointer\", padding: 0,\n }}\n >\n <RotateCw size={13} stroke=\"var(--rail-discovery, #5E88B0)\" />\n </button>\n\n <div style={{ display: \"inline-flex\", alignItems: \"center\", gap: 4, borderRadius: 999, border: \"1px solid var(--border, rgba(52,58,64,0.12))\", padding: \"2px 3px\", background: \"var(--paper, rgba(255,255,255,0.78))\", marginLeft: 4 }}>\n {speedOptions.map((speed) => {\n const isActive = playbackRate === speed;\n return (\n <button\n key={speed}\n type=\"button\"\n onClick={() => onSetPlaybackRate?.(speed)}\n disabled={!hasRecording}\n title={`Speed: ${speed}x`}\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n height: 24, minWidth: 38, padding: \"0 6px\", borderRadius: 999,\n border: `1px solid ${isActive ? \"var(--rail-discovery, #5E88B0)\" : \"transparent\"}`,\n background: isActive ? \"var(--rail-discovery, #5E88B0)\" : \"transparent\",\n color: isActive ? \"#fff\" : \"var(--text-muted, rgba(30,33,37,0.56))\",\n fontSize: \"var(--text-xs, 10px)\", fontWeight: 600, cursor: \"pointer\",\n }}\n >\n {speed === 1.5 ? \"1.50x\" : `${speed}x`}\n </button>\n );\n })}\n </div>\n </div>\n </div>\n )}\n\n <div style={{\n background: \"var(--paper, rgba(255,255,255,0.78))\",\n border: \"1px solid var(--border, rgba(52,58,64,0.12))\",\n borderRadius: 10,\n padding: \"12px 16px 10px\",\n }}>\n <div style={{ position: \"relative\" }}>\n {/* Time markers row */}\n <div style={{ display: \"flex\", alignItems: \"center\", marginBottom: 6, height: 16 }}>\n <div style={{ width: \"5rem\", flexShrink: 0 }} />\n <div style={{ position: \"relative\", flex: 1 }}>\n {timeMarkers.map((time) => {\n const percentage = timelineDuration > 0 ? (time / timelineDuration) * 100 : 0;\n return (\n <div\n key={time}\n style={{\n position: \"absolute\",\n fontSize: \"var(--text-xs, 10px)\",\n color: \"var(--text-faint, rgba(30,33,37,0.36))\",\n left: `${percentage}%`,\n transform: \"translateX(-50%)\",\n fontFamily: \"var(--font-mono, monospace)\",\n whiteSpace: \"nowrap\",\n }}\n >\n {formatTime(time)}\n </div>\n );\n })}\n </div>\n </div>\n\n {/* Vertical gridlines */}\n <div\n style={{\n position: \"absolute\",\n pointerEvents: \"none\",\n top: 0,\n bottom: 0,\n left: \"5rem\",\n width: \"calc(100% - 5rem)\",\n zIndex: 20,\n }}\n >\n {timeMarkers.map((time) => {\n const percentage = timelineDuration > 0 ? (time / timelineDuration) * 100 : 0;\n return (\n <div\n key={time}\n style={{\n position: \"absolute\",\n top: 0,\n bottom: 0,\n left: `${percentage}%`,\n borderLeft: \"1px dashed var(--border, rgba(52,58,64,0.12))\",\n transform: \"translateX(-1px)\",\n }}\n />\n );\n })}\n </div>\n\n {/* Swim lanes */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 10, marginTop: 8 }}>\n {rows.map((row) => {\n const isSystem = row.key === \"system\" || row.label === \"System\";\n return (\n <div key={row.key} style={{ display: \"flex\", alignItems: \"center\" }}>\n <div\n style={{\n width: \"5rem\",\n flexShrink: 0,\n fontSize: \"var(--text-sm, 11px)\",\n fontWeight: 600,\n color: \"var(--text-muted, rgba(30,33,37,0.56))\",\n fontFamily: \"var(--font-sans, system-ui, sans-serif)\",\n paddingRight: 8,\n }}\n >\n {row.label}\n </div>\n\n <div\n style={{\n position: \"relative\",\n borderRadius: 4,\n flex: 1,\n height: 18,\n backgroundColor: \"var(--paper-secondary, rgba(244,241,230,0.6))\",\n border: \"1px solid var(--border-subtle, rgba(52,58,64,0.08))\",\n }}\n >\n {row.segments.map((segment, idx) => {\n let leftPercent = timelineDuration > 0 ? (segment.startTime / timelineDuration) * 100 : 0;\n let widthPercent =\n timelineDuration > 0\n ? ((segment.endTime - segment.startTime) / timelineDuration) * 100\n : 0;\n leftPercent = Math.max(0, Math.min(100, leftPercent));\n const rightPercent = leftPercent + widthPercent;\n if (rightPercent > 100) widthPercent = 100 - leftPercent;\n widthPercent = Math.max(0, widthPercent);\n const segmentDuration = segment.endTime - segment.startTime;\n\n if (isSystem && segmentDuration <= 5) {\n return (\n <div\n key={idx}\n style={{\n position: \"absolute\",\n cursor: \"pointer\",\n left: `${leftPercent}%`,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n width: 10,\n height: 10,\n borderRadius: \"50%\",\n backgroundColor: row.color,\n opacity: 0.85,\n }}\n title={`${row.label}: ${formatTime(segment.startTime)}-${formatTime(segment.endTime)}`}\n />\n );\n }\n\n return (\n <div\n key={idx}\n style={{\n position: \"absolute\",\n top: 0,\n bottom: 0,\n left: `${leftPercent}%`,\n width: `${Math.max(widthPercent, 0.7)}%`,\n maxWidth: `${100 - leftPercent}%`,\n backgroundColor: row.color,\n opacity: 0.85,\n borderRadius: 2,\n cursor: \"pointer\",\n transition: \"opacity 0.15s\",\n }}\n title={`${row.label}: ${formatTime(segment.startTime)}-${formatTime(segment.endTime)}`}\n />\n );\n })}\n </div>\n </div>\n );\n })}\n </div>\n\n {/* Playhead */}\n <div\n style={{\n pointerEvents: \"none\",\n position: \"absolute\",\n top: 0,\n bottom: 0,\n width: 2,\n borderRadius: 1,\n backgroundColor: \"var(--rail-discovery, #5E88B0)\",\n opacity: 0.55,\n boxShadow: \"0 0 0 1px rgba(94,136,176,0.10)\",\n left: playheadLeft,\n transform: \"translateX(-50%)\",\n }}\n />\n\n {/* Seek overlay */}\n {onSeek ? (\n <button\n type=\"button\"\n onClick={handleSeekClick}\n style={{\n position: \"absolute\",\n cursor: \"pointer\",\n background: \"transparent\",\n border: \"none\",\n padding: 0,\n margin: 0,\n appearance: \"none\",\n top: 0,\n bottom: 0,\n left: \"5rem\",\n width: \"calc(100% - 5rem)\",\n zIndex: 25,\n }}\n title=\"Click timeline to play from that point\"\n aria-label=\"Click timeline to play from that point\"\n />\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n"],"names":["ACTOR_DEFAULTS","KEYFRAMES_ID","ensureKeyframes","style","ConversationTurn","role","text","actorLabel","actorRailColor","actionKicker","toolBadges","streaming","meta","timeRange","isHighlighted","highlightRailColor","observations","onObservationClick","children","useEffect","actor","label","railColor","highlighted","jsx","jsxs","t","i","isPending","isError","obs","parseTimeRange","start","end","time","minutes","seconds","mapActorTypeToRole","actorType","TranscriptCard","turns","audioUrl","activeTurnIndex","autoScrollActiveTurn","isExternalPlaying","onTurnPlayPause","playingSegment","setPlayingSegment","useState","isPlaying","setIsPlaying","audioRef","useRef","endTimeListenerRef","turnRefs","containerRef","lastAutoScrolledIndexRef","useExternalPlaybackControl","hasExternalPlaybackState","container","activeNode","containerRect","activeRect","topPadding","isFullyVisible","activeTopInContainer","handlePlayPause","index","previousSegment","playSegment","checkEndTime","err","turn","isTurnPlaying","isTurnHighlighted","el","Pause","Play","Timeline","segments","durationSeconds","actorRows","currentTimeSeconds","onSeek","showControls","hasRecording","timelinePlaying","playbackRate","speedOptions","onTogglePlay","onSeekBack","onSeekForward","onSetPlaybackRate","totalDurationLabel","activeControl","setActiveControl","timer","timelineDuration","segment","clampedCurrent","playheadPercent","playheadLeft","formatTime","mins","secs","rows","useMemo","actors","actorColors","timeMarkers","interval","marker","handleSeekClick","event","rect","ratio","RotateCcw","RotateCw","speed","isActive","percentage","row","isSystem","idx","leftPercent","widthPercent","segmentDuration"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const t=require("react/jsx-runtime"),r=require("react"),c=require("lucide-react"),we=require("./Timeline.cjs.js");function te(h){const l=Math.floor(h/60),I=Math.round(h%60);return`${l}:${I.toString().padStart(2,"0")}`}const Re={Agent:[{start:0,end:.08},{start:.18,end:.22},{start:.38,end:.42},{start:.55,end:.58},{start:.68,end:.72},{start:.82,end:.88},{start:.94,end:1}],Customer:[{start:.1,end:.16},{start:.24,end:.36},{start:.44,end:.52},{start:.6,end:.66},{start:.74,end:.8}]},R=[{speaker:"Agent",type:"agent",time:"00:04",text:"Thanks for calling Miles Point S Pensau. This is Steve. How can I help you?"},{speaker:"Customer",type:"customer",time:"00:12",text:"Hi, Steve. This is Sandra with Botai Catering."},{speaker:"Agent",type:"agent",time:"00:18",text:"Hello. How are you?"},{speaker:"Customer",type:"customer",time:"00:20",text:"I'm doing really good. Hey. I brought my vans in last week, and I call it a beeping van, the one that beeps when you back up. Makes the crunchy noise. So I just took it on Saturday after, I think I had the, the Miles. I picked it up on Saturday morning, and I went to an event. So So I don't know if it's the tire or something, but makes it a little crunchy noise. Sometimes when I do the brake, but only if I turn the wheel too."},{speaker:"Agent",type:"agent",time:"00:21",text:"Oh, interesting. Okay. Can you swing by with it one of these days?"}],Ie=[1,1.25,1.5,2];function ne(h){if(!h)return 0;const l=h.split(":").map(Number);return(l[0]||0)*60+(l[1]||0)}const Ce=r.forwardRef(function({audioUrl:l,timelineSegments:I=[],durationSeconds:k=0,currentTimeSeconds:z,timelinePlaying:H,playbackRate:A,onSeek:C,onTogglePlay:P,onSeekBack:$,onSeekForward:B,onSetPlaybackRate:L,audioRef:_,agentName:ie="Agent",customerName:oe="Customer",transcript:g,highlightedTurns:re=new Set,activeTurnIndex:q,activeDemoIndex:se=1,turnObservations:ae={},setExpandedSignals:D,onTurnPlayPause:X},le){var ee;const N=r.useRef(null),d=r.useRef(null),x=r.useRef(null),[Y,f]=r.useState(!1),[T,K]=r.useState(0),[ce,de]=r.useState(0),[ue,he]=r.useState(1),[S,ge]=r.useState(null),[fe,pe]=r.useState(1),[ye,F]=r.useState(!1),[me,V]=r.useState(!1),[Z,E]=r.useState(se),s=!!_,v=!l,a=l&&!s,b=v?ye:s?H??!1:Y,xe=v?S??0:s?z??0:T,G=v?fe:s?A??1:ue,W=v?k||156:s?k:ce||k||0,M=r.useCallback(()=>{const e=()=>{const i=d.current;i&&K(i.currentTime),x.current=requestAnimationFrame(e)};x.current=requestAnimationFrame(e)},[]),p=r.useCallback(()=>{x.current&&(cancelAnimationFrame(x.current),x.current=null)},[]);r.useEffect(()=>()=>p(),[p]),r.useEffect(()=>{if(!a)return;const e=d.current;if(!e)return;const i=()=>de(e.duration||0),n=()=>{f(!1),p()};return e.addEventListener("loadedmetadata",i),e.addEventListener("ended",n),()=>{e.removeEventListener("loadedmetadata",i),e.removeEventListener("ended",n)}},[a,p]);const J=e=>{for(let i=R.length-1;i>=0;i--){const n=ne(R[i].time);if(e>=n)return i}return 0},y=e=>{const n=Math.max(0,Math.min(e,W||156));if(a){const o=d.current;o&&(o.currentTime=n),K(n)}else s&&C&&C(n);ge(n),E(J(n))},ve=()=>{if(a){const e=d.current;if(!e)return;Y?(e.pause(),p(),f(!1)):e.play().then(()=>{f(!0),M()}).catch(()=>{})}else s&&P?P():F(e=>!e)},be=()=>{s&&$?$():y(Math.max(0,(a?T:S??0)-10))},je=()=>{s&&B?B():y(Math.min(W||156,(a?T:S??0)+10))},ke=e=>{if(a){const i=d.current;i&&(i.playbackRate=e),he(e)}else s&&L&&L(e);pe(e),V(!1)};r.useImperativeHandle(le,()=>({seekTo:e=>{if(y(e),a){const n=d.current;n&&n.play().then(()=>{f(!0),M()}).catch(()=>{})}else F(!0);const i=J(e);E(i),setTimeout(()=>{var o;const n=(o=N.current)==null?void 0:o.children;n!=null&&n[i]&&n[i].scrollIntoView({behavior:"smooth",block:"nearest"})},50)}}));const Se=e=>{var i;if(Z===e&&b){if(a){const n=d.current;n&&n.pause(),p(),f(!1)}F(!1)}else{const n=ne((i=R[e])==null?void 0:i.time);if(E(e),y(n),a){const o=d.current;o&&(o.currentTime=n,o.play().then(()=>{f(!0),M()}).catch(()=>{}))}F(!0)}},Fe=(e,i)=>{if(e==null)return;const n=o=>{const u=Math.floor(o/6e4),m=Math.floor(o%6e4/1e3);return`${u.toString().padStart(2,"0")}:${m.toString().padStart(2,"0")}`};return`${n(e)}–${i!=null?n(i):n(e)}`},O=(ee=g==null?void 0:g.messages)!=null&&ee.length?g.messages.map((e,i)=>{var n,o;return{actor:e.actor==="agent"?((n=g.actor_map)==null?void 0:n.agent)||"Agent":((o=g.actor_map)==null?void 0:o.customer)||"Customer",actorType:e.actor==="agent"?"agent":"customer",text:e.text||"",timeRange:Fe(e.start??e.start_ms,e.end??e.end_ms),isHighlighted:re.has(i),highlightColor:b&&q===i?e.actor==="agent"?"var(--rail-outcome)":"var(--rail-discovery)":void 0,observations:(ae[i]||[]).map(u=>({...u,onClick:()=>{D==null||D(m=>new Set([...m,u.signalKey])),setTimeout(()=>{const m=document.getElementById(`signal-${u.signalKey}`);m&&m.scrollIntoView({behavior:"smooth",block:"nearest"})},100)}}))}}):null,Q=v?S??0:xe,w=W||156,j=w>0?Q/w*100:0,U=Math.round(Q);return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:16},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:16,width:"100%"},children:[t.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",width:34,height:34,borderRadius:9999,background:"var(--surface-hover, #F3F7F7)",flexShrink:0},children:t.jsx(c.FileSignal,{size:20,color:"#2E3236",strokeWidth:1.5})}),t.jsx("span",{style:{fontSize:15,fontWeight:500,color:"var(--Grey-Strong, #2E3236)"},children:"Recording"})]}),t.jsxs("div",{style:{display:"flex",padding:24,flexDirection:"column",alignItems:"flex-start",gap:24,borderRadius:8,border:"1px solid var(--Grey-absent, #D9D9D9)",background:"var(--Grey-White, #FFF)"},children:[t.jsxs("div",{style:{width:"100%",display:"flex",flexDirection:"column",gap:16},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:24},children:[t.jsxs("span",{style:{fontSize:14,fontWeight:500,color:"var(--Grey-Strong, #2E3236)",lineHeight:1.2},children:[ie," / ",oe]}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12},children:[t.jsx("span",{style:{fontSize:13,fontWeight:400,color:"var(--Grey-Muted, #808183)",lineHeight:1.2},children:"10"}),t.jsx("button",{onClick:be,style:{background:"none",border:"none",cursor:"pointer",padding:0,display:"flex",alignItems:"center"},children:t.jsx(c.RotateCcw,{size:20,color:"#808183",strokeWidth:1.5})}),t.jsx("button",{onClick:ve,style:{background:"var(--Grey-Strong, #2E3236)",border:"none",cursor:"pointer",width:32,height:32,borderRadius:48,padding:0,display:"flex",alignItems:"center",justifyContent:"center"},children:b?t.jsx(c.Pause,{size:14,color:"#FFF",fill:"#FFF"}):t.jsx(c.Play,{size:14,color:"#FFF",fill:"#FFF",strokeWidth:1.5,style:{marginLeft:2}})}),t.jsx("button",{onClick:je,style:{background:"none",border:"none",cursor:"pointer",padding:0,display:"flex",alignItems:"center"},children:t.jsx(c.RotateCw,{size:20,color:"#808183",strokeWidth:1.5})}),t.jsx("span",{style:{fontSize:13,fontWeight:400,color:"var(--Grey-Muted, #808183)",lineHeight:1.2},children:"10"})]}),t.jsxs("div",{style:{position:"relative"},children:[t.jsxs("button",{onClick:()=>V(e=>!e),style:{background:"var(--Grey-White, #FFF)",border:"1px solid var(--Grey-absent, #D9D9D9)",borderRadius:20,padding:"0 5px 0 10px",height:24,minWidth:56,cursor:"pointer",fontSize:13,fontWeight:400,color:"var(--Grey-Strong, #2E3236)",fontFamily:"var(--font-sans)",lineHeight:1.2,display:"flex",alignItems:"center",justifyContent:"center",gap:4},children:[G,"x",t.jsx(c.ChevronDown,{size:12,color:"#808183"})]}),me&&t.jsx("div",{style:{position:"absolute",top:"100%",right:0,marginTop:4,background:"var(--Grey-White, #FFF)",border:"1px solid var(--Grey-absent, #D9D9D9)",borderRadius:8,boxShadow:"0 4px 12px rgba(0,0,0,0.1)",zIndex:10,overflow:"hidden",minWidth:80},children:Ie.map(e=>t.jsxs("button",{onClick:()=>ke(e),style:{display:"block",width:"100%",padding:"8px 12px",border:"none",background:G===e?"var(--surface-hover, #F3F7F7)":"var(--Grey-White, #FFF)",cursor:"pointer",fontSize:13,fontWeight:G===e?600:400,color:"var(--Grey-Strong, #2E3236)",fontFamily:"var(--font-sans)",textAlign:"left"},children:[e,"x"]},e))})]})]}),l&&s?t.jsxs(t.Fragment,{children:[t.jsx(we.Timeline,{segments:I,durationSeconds:k,currentTimeSeconds:z,onSeek:C,showControls:!1,hasRecording:!0,timelinePlaying:H,playbackRate:A}),t.jsx("audio",{ref:_,preload:"none",style:{display:"none"},children:t.jsx("source",{src:l,type:"audio/mpeg"})})]}):t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[t.jsx("span",{style:{fontSize:13,fontWeight:600,color:j>0?"var(--Green-Primary, #00925F)":"var(--Grey-Strong, #2E3236)",fontFamily:"var(--font-sans)",lineHeight:1.2,minWidth:60},children:te(U)}),t.jsxs("div",{onClick:e=>{const i=e.currentTarget.getBoundingClientRect(),n=e.clientX-i.left,o=Math.max(0,Math.min(1,n/i.width));y(o*w)},style:{flex:1,height:16,position:"relative",display:"flex",alignItems:"center",cursor:"pointer"},children:[t.jsx("div",{style:{position:"absolute",left:0,right:0,height:4,borderRadius:2,background:"var(--rail-surface-2, #E3E1D7)",pointerEvents:"none"}}),t.jsx("div",{style:{position:"absolute",left:0,top:"50%",transform:"translateY(-50%)",width:`${j}%`,height:4,borderRadius:2,background:"var(--Green-Primary, #00925F)",pointerEvents:"none"}}),t.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:{position:"absolute",left:`${j}%`,top:"50%",transform:"translate(-50%, -50%)",pointerEvents:"none"},children:t.jsx("path",{d:"M7.875 1C11.6572 1 14.75 4.1191 14.75 8C14.75 11.8809 11.6572 15 7.875 15C4.09284 15 1 11.8809 1 8C1 4.1191 4.09284 1 7.875 1Z",fill:"#FFF",stroke:"#00925F",strokeWidth:"2"})})]})]}),t.jsxs("div",{style:{position:"relative",paddingBottom:30,cursor:"pointer"},children:[["Agent","Customer"].map((e,i)=>t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,height:20,marginBottom:i===0?4:0},children:[t.jsx("span",{style:{fontSize:13,fontWeight:400,color:"var(--Grey-Muted, #808183)",fontFamily:"var(--font-sans)",lineHeight:1.2,minWidth:60},children:e}),t.jsxs("div",{onClick:n=>{const o=n.currentTarget.getBoundingClientRect(),u=Math.max(0,Math.min(1,(n.clientX-o.left)/o.width));y(u*w)},style:{flex:1,height:6,position:"relative",borderRadius:3,cursor:"pointer"},children:[t.jsx("div",{style:{position:"absolute",left:0,right:0,top:"50%",transform:"translateY(-50%)",height:4,borderRadius:2,background:"var(--rail-surface-2, #E3E1D7)"}}),Re[e].map((n,o)=>t.jsx("div",{style:{position:"absolute",left:`${n.start*100}%`,width:`${(n.end-n.start)*100}%`,top:0,bottom:0,borderRadius:3,background:e==="Agent"?"var(--Grey-Strong, #2E3236)":"var(--Grey-Muted, #808183)"}},o))]})]},e)),t.jsxs("div",{style:{position:"absolute",left:68,right:0,top:0,bottom:0,pointerEvents:"none"},children:[t.jsx("div",{style:{position:"absolute",left:`${j}%`,top:0,height:44,transform:"translateX(-50%)",borderLeft:"1.5px dashed var(--Grey-Muted, #808183)",opacity:.5}}),t.jsx("div",{style:{position:"absolute",left:`${j}%`,bottom:0,transform:"translateX(-50%)",background:"var(--Grey-Strong, #2E3236)",color:"var(--Grey-White, #FFF)",fontSize:14,fontWeight:600,lineHeight:1.2,padding:"4px 6px",borderRadius:4,whiteSpace:"nowrap"},children:te(U)})]})]}),a&&t.jsx("audio",{ref:d,preload:"auto",style:{display:"none"},children:t.jsx("source",{src:l,type:"audio/mpeg"})})]})]}),t.jsxs("div",{style:{width:"100%",display:"flex",flexDirection:"column",gap:16},children:[t.jsx("div",{style:{borderBottom:"1px solid var(--Grey-absent, #D9D9D9)",paddingBottom:16},children:t.jsx("span",{style:{fontSize:14,fontWeight:400,color:"var(--Grey-Strong, #2E3236)",lineHeight:1.2},children:"Transcript"})}),t.jsx("div",{id:"transcript-container",ref:N,style:{display:"flex",flexDirection:"column",maxHeight:600,overflowY:"auto"},children:(O||R.map(e=>({actor:e.speaker,actorType:e.type,text:e.text,timeRange:e.time}))).map((e,i)=>{const n=!!O,o=n?b&&q===i:i===Z&&b,u=(e.actorType||e.type)==="customer";return t.jsxs("div",{style:{display:"flex",padding:16,flexDirection:"column",alignItems:"flex-start",gap:16,alignSelf:"stretch",borderTop:i>0?"1px solid var(--Grey-absent, #D9D9D9)":"none",background:o?"var(--surface-hover, #F3F7F7)":"var(--Grey-White, #FFF)"},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",gap:8},children:[t.jsx("span",{style:{fontSize:14,fontWeight:600,lineHeight:1.2,color:u?"var(--Grey-Strong, #2E3236)":"var(--Grey-Muted, #808183)"},children:e.actor}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[o&&t.jsxs(t.Fragment,{children:[t.jsx(c.AudioLines,{size:12,color:"#2E3236"}),t.jsx(c.AudioLines,{size:12,color:"#2E3236"})]}),t.jsx("span",{style:{fontSize:13,fontWeight:400,lineHeight:1.2,color:"var(--Grey-Muted, #808183)"},children:e.timeRange})]})]}),t.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:8,width:"100%"},children:[t.jsx("button",{onClick:()=>{n&&X?X(e,i):Se(i)},style:{background:"none",border:"none",cursor:"pointer",padding:0,flexShrink:0,display:"flex"},children:o?t.jsx(c.PauseCircle,{size:17,color:"#2E3236",strokeWidth:1.5}):t.jsx(c.PlayCircle,{size:17,color:"#808183",strokeWidth:1})}),t.jsx("p",{style:{fontSize:13,fontWeight:400,color:"var(--Grey-Strong, #2E3236)",lineHeight:1.2,margin:0,flex:1},children:e.text})]})]},i)})})]})]})]})});exports.UpdatedInteractionRecording=Ce;
|
|
1
|
+
"use strict";const t=require("react/jsx-runtime"),s=require("react"),u=require("lucide-react");function A(g){const d=Math.floor(g/60),p=Math.round(g%60);return`${d}:${p.toString().padStart(2,"0")}`}const Re={Agent:[{start:0,end:.08},{start:.18,end:.22},{start:.38,end:.42},{start:.55,end:.58},{start:.68,end:.72},{start:.82,end:.88},{start:.94,end:1}],Customer:[{start:.1,end:.16},{start:.24,end:.36},{start:.44,end:.52},{start:.6,end:.66},{start:.74,end:.8}]},I=[{speaker:"Agent",type:"agent",time:"00:04",text:"Thanks for calling Miles Point S Pensau. This is Steve. How can I help you?"},{speaker:"Customer",type:"customer",time:"00:12",text:"Hi, Steve. This is Sandra with Botai Catering."},{speaker:"Agent",type:"agent",time:"00:18",text:"Hello. How are you?"},{speaker:"Customer",type:"customer",time:"00:20",text:"I'm doing really good. Hey. I brought my vans in last week, and I call it a beeping van, the one that beeps when you back up. Makes the crunchy noise. So I just took it on Saturday after, I think I had the, the Miles. I picked it up on Saturday morning, and I went to an event. So So I don't know if it's the tire or something, but makes it a little crunchy noise. Sometimes when I do the brake, but only if I turn the wheel too."},{speaker:"Agent",type:"agent",time:"00:21",text:"Oh, interesting. Okay. Can you swing by with it one of these days?"}],Ie=[1,1.25,1.5,2];function ne(g){if(!g)return 0;const d=g.split(":").map(Number);return(d[0]||0)*60+(d[1]||0)}const Ce=s.forwardRef(function({audioUrl:d,timelineSegments:p=[],durationSeconds:C=0,currentTimeSeconds:re,timelinePlaying:P,playbackRate:ie,onSeek:$,onTogglePlay:F,onSeekBack:B,onSeekForward:L,onSetPlaybackRate:_,audioRef:q,agentName:D="Agent",customerName:T="Customer",transcript:y,highlightedTurns:oe=new Set,activeTurnIndex:X,activeDemoIndex:se=1,turnObservations:ae={},setExpandedSignals:E,onTurnPlayPause:Y},le){var te;const K=s.useRef(null),h=s.useRef(null),b=s.useRef(null),[V,m]=s.useState(!1),[G,Z]=s.useState(0),[ce,de]=s.useState(0),[ue,he]=s.useState(1),[w,fe]=s.useState(null),[ge,pe]=s.useState(1),[ye,R]=s.useState(!1),[me,J]=s.useState(!1),[N,W]=s.useState(se),a=!!q,j=!d,l=d&&!a,k=j?ye:a?P??!1:V,xe=j?w??0:a?re??0:G,M=j?ge:a?ie??1:ue,z=j?C||156:a?C:ce||C||0,H=s.useCallback(()=>{const e=()=>{const n=h.current;n&&Z(n.currentTime),b.current=requestAnimationFrame(e)};b.current=requestAnimationFrame(e)},[]),x=s.useCallback(()=>{b.current&&(cancelAnimationFrame(b.current),b.current=null)},[]);s.useEffect(()=>()=>x(),[x]),s.useEffect(()=>{if(!l)return;const e=h.current;if(!e)return;const n=()=>de(e.duration||0),r=()=>{m(!1),x()};return e.addEventListener("loadedmetadata",n),e.addEventListener("ended",r),()=>{e.removeEventListener("loadedmetadata",n),e.removeEventListener("ended",r)}},[l,x]);const Q=e=>{for(let n=I.length-1;n>=0;n--){const r=ne(I[n].time);if(e>=r)return n}return 0},v=e=>{const r=Math.max(0,Math.min(e,z||156));if(l){const i=h.current;i&&(i.currentTime=r),Z(r)}else a&&$&&$(r);fe(r),W(Q(r))},ve=()=>{if(l){const e=h.current;if(!e)return;V?(e.pause(),x(),m(!1)):e.play().then(()=>{m(!0),H()}).catch(()=>{})}else a&&F?F():R(e=>!e)},be=()=>{a&&B?B():v(Math.max(0,(l?G:w??0)-10))},je=()=>{a&&L?L():v(Math.min(z||156,(l?G:w??0)+10))},ke=e=>{if(l){const n=h.current;n&&(n.playbackRate=e),he(e)}else a&&_&&_(e);pe(e),J(!1)};s.useImperativeHandle(le,()=>({seekTo:e=>{if(v(e),a)!P&&F&&F();else if(l){const r=h.current;r&&r.play().then(()=>{m(!0),H()}).catch(()=>{})}else R(!0);const n=Q(e);W(n),setTimeout(()=>{var i;const r=(i=K.current)==null?void 0:i.children;r!=null&&r[n]&&r[n].scrollIntoView({behavior:"smooth",block:"nearest"})},50)}}));const Se=e=>{var n;if(N===e&&k){if(l){const r=h.current;r&&r.pause(),x(),m(!1)}R(!1)}else{const r=ne((n=I[e])==null?void 0:n.time);if(W(e),v(r),l){const i=h.current;i&&(i.currentTime=r,i.play().then(()=>{m(!0),H()}).catch(()=>{}))}R(!0)}},Fe=(e,n)=>{if(e==null)return;const r=i=>{const o=Math.floor(i/6e4),c=Math.floor(i%6e4/1e3);return`${o.toString().padStart(2,"0")}:${c.toString().padStart(2,"0")}`};return`${r(e)}–${n!=null?r(n):r(e)}`},O=(te=y==null?void 0:y.messages)!=null&&te.length?y.messages.map((e,n)=>{var r,i;return{actor:e.actor==="agent"?((r=y.actor_map)==null?void 0:r.agent)||"Agent":((i=y.actor_map)==null?void 0:i.customer)||"Customer",actorType:e.actor==="agent"?"agent":"customer",text:e.text||"",timeRange:Fe(e.start??e.start_ms,e.end??e.end_ms),isHighlighted:oe.has(n),highlightColor:k&&X===n?e.actor==="agent"?"var(--rail-outcome)":"var(--rail-discovery)":void 0,observations:(ae[n]||[]).map(o=>({...o,onClick:()=>{E==null||E(c=>new Set([...c,o.signalKey])),setTimeout(()=>{const c=document.getElementById(`signal-${o.signalKey}`);c&&c.scrollIntoView({behavior:"smooth",block:"nearest"})},100)}}))}}):null,U=j?w??0:xe,f=z||156,S=f>0?U/f*100:0,ee=Math.round(U);return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:16},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:16,width:"100%"},children:[t.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",width:34,height:34,borderRadius:9999,background:"var(--surface-hover, #F3F7F7)",flexShrink:0},children:t.jsx(u.FileSignal,{size:20,color:"#2E3236",strokeWidth:1.5})}),t.jsx("span",{style:{fontSize:15,fontWeight:500,color:"var(--Grey-Strong, #2E3236)"},children:"Recording"})]}),t.jsxs("div",{style:{display:"flex",padding:24,flexDirection:"column",alignItems:"flex-start",gap:24,borderRadius:8,border:"1px solid var(--Grey-absent, #D9D9D9)",background:"var(--Grey-White, #FFF)"},children:[t.jsxs("div",{style:{width:"100%",display:"flex",flexDirection:"column",gap:16},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:24},children:[t.jsxs("span",{style:{fontSize:14,fontWeight:500,color:"var(--Grey-Strong, #2E3236)",lineHeight:1.2},children:[D," / ",T]}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12},children:[t.jsx("span",{style:{fontSize:13,fontWeight:400,color:"var(--Grey-Muted, #808183)",lineHeight:1.2},children:"10"}),t.jsx("button",{onClick:be,style:{background:"none",border:"none",cursor:"pointer",padding:0,display:"flex",alignItems:"center"},children:t.jsx(u.RotateCcw,{size:20,color:"#808183",strokeWidth:1.5})}),t.jsx("button",{onClick:ve,style:{background:"var(--Grey-Strong, #2E3236)",border:"none",cursor:"pointer",width:32,height:32,borderRadius:48,padding:0,display:"flex",alignItems:"center",justifyContent:"center"},children:k?t.jsx(u.Pause,{size:14,color:"#FFF",fill:"#FFF"}):t.jsx(u.Play,{size:14,color:"#FFF",fill:"#FFF",strokeWidth:1.5,style:{marginLeft:2}})}),t.jsx("button",{onClick:je,style:{background:"none",border:"none",cursor:"pointer",padding:0,display:"flex",alignItems:"center"},children:t.jsx(u.RotateCw,{size:20,color:"#808183",strokeWidth:1.5})}),t.jsx("span",{style:{fontSize:13,fontWeight:400,color:"var(--Grey-Muted, #808183)",lineHeight:1.2},children:"10"})]}),t.jsxs("div",{style:{position:"relative"},children:[t.jsxs("button",{onClick:()=>J(e=>!e),style:{background:"var(--Grey-White, #FFF)",border:"1px solid var(--Grey-absent, #D9D9D9)",borderRadius:20,padding:"0 5px 0 10px",height:24,minWidth:56,cursor:"pointer",fontSize:13,fontWeight:400,color:"var(--Grey-Strong, #2E3236)",fontFamily:"var(--font-sans)",lineHeight:1.2,display:"flex",alignItems:"center",justifyContent:"center",gap:4},children:[M,"x",t.jsx(u.ChevronDown,{size:12,color:"#808183"})]}),me&&t.jsx("div",{style:{position:"absolute",top:"100%",right:0,marginTop:4,background:"var(--Grey-White, #FFF)",border:"1px solid var(--Grey-absent, #D9D9D9)",borderRadius:8,boxShadow:"0 4px 12px rgba(0,0,0,0.1)",zIndex:10,overflow:"hidden",minWidth:80},children:Ie.map(e=>t.jsxs("button",{onClick:()=>ke(e),style:{display:"block",width:"100%",padding:"8px 12px",border:"none",background:M===e?"var(--surface-hover, #F3F7F7)":"var(--Grey-White, #FFF)",cursor:"pointer",fontSize:13,fontWeight:M===e?600:400,color:"var(--Grey-Strong, #2E3236)",fontFamily:"var(--font-sans)",textAlign:"left"},children:[e,"x"]},e))})]})]}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[t.jsx("span",{style:{fontSize:13,fontWeight:600,color:S>0?"var(--Green-Primary, #00925F)":"var(--Grey-Strong, #2E3236)",fontFamily:"var(--font-sans)",lineHeight:1.2,minWidth:60},children:A(ee)}),t.jsxs("div",{onClick:e=>{const n=e.currentTarget.getBoundingClientRect(),r=e.clientX-n.left,i=Math.max(0,Math.min(1,r/n.width));v(i*f)},style:{flex:1,height:16,position:"relative",display:"flex",alignItems:"center",cursor:"pointer"},children:[t.jsx("div",{style:{position:"absolute",left:0,right:0,height:4,borderRadius:2,background:"var(--rail-surface-2, #E3E1D7)",pointerEvents:"none"}}),t.jsx("div",{style:{position:"absolute",left:0,top:"50%",transform:"translateY(-50%)",width:`${S}%`,height:4,borderRadius:2,background:"var(--Green-Primary, #00925F)",pointerEvents:"none"}}),t.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:{position:"absolute",left:`${S}%`,top:"50%",transform:"translate(-50%, -50%)",pointerEvents:"none"},children:t.jsx("path",{d:"M7.875 1C11.6572 1 14.75 4.1191 14.75 8C14.75 11.8809 11.6572 15 7.875 15C4.09284 15 1 11.8809 1 8C1 4.1191 4.09284 1 7.875 1Z",fill:"#FFF",stroke:"#00925F",strokeWidth:"2"})}),t.jsx("span",{style:{position:"absolute",right:-48,fontSize:13,fontWeight:400,color:"var(--Grey-Muted, #808183)",fontFamily:"var(--font-sans)",lineHeight:1.2,whiteSpace:"nowrap"},children:A(f)})]})]}),t.jsxs("div",{style:{position:"relative",paddingBottom:30,cursor:"pointer"},children:[[D,T].map((e,n)=>{const r=n===0,i=p!=null&&p.length?p.filter(o=>r?o.actor===D:o.actor===T).map(o=>({start:f>0?o.startTime/f:0,end:f>0?o.endTime/f:0})):Re[r?"Agent":"Customer"]||[];return t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,height:20,marginBottom:n===0?4:0},children:[t.jsx("span",{style:{fontSize:13,fontWeight:400,color:"var(--Grey-Muted, #808183)",fontFamily:"var(--font-sans)",lineHeight:1.2,minWidth:60},children:e}),t.jsxs("div",{onClick:o=>{const c=o.currentTarget.getBoundingClientRect(),we=Math.max(0,Math.min(1,(o.clientX-c.left)/c.width));v(we*f)},style:{flex:1,height:6,position:"relative",borderRadius:3,cursor:"pointer"},children:[t.jsx("div",{style:{position:"absolute",left:0,right:0,top:"50%",transform:"translateY(-50%)",height:4,borderRadius:2,background:"var(--rail-surface-2, #E3E1D7)"}}),i.map((o,c)=>t.jsx("div",{style:{position:"absolute",left:`${o.start*100}%`,width:`${(o.end-o.start)*100}%`,top:0,bottom:0,borderRadius:3,background:r?"var(--Grey-Strong, #2E3236)":"var(--Grey-Muted, #808183)"}},c))]})]},e)}),t.jsxs("div",{style:{position:"absolute",left:68,right:0,top:0,bottom:0,pointerEvents:"none"},children:[t.jsx("div",{style:{position:"absolute",left:`${S}%`,top:0,height:44,transform:"translateX(-50%)",borderLeft:"1.5px dashed var(--Grey-Muted, #808183)",opacity:.5}}),t.jsx("div",{style:{position:"absolute",left:`${S}%`,bottom:0,transform:"translateX(-50%)",background:"var(--Grey-Strong, #2E3236)",color:"var(--Grey-White, #FFF)",fontSize:14,fontWeight:600,lineHeight:1.2,padding:"4px 6px",borderRadius:4,whiteSpace:"nowrap"},children:A(ee)})]})]}),l&&t.jsx("audio",{ref:h,preload:"auto",style:{display:"none"},children:t.jsx("source",{src:d,type:"audio/mpeg"})}),a&&d&&t.jsx("audio",{ref:q,preload:"auto",style:{display:"none"},children:t.jsx("source",{src:d,type:"audio/mpeg"})})]})]}),t.jsxs("div",{style:{width:"100%",display:"flex",flexDirection:"column",gap:16},children:[t.jsx("div",{style:{borderBottom:"1px solid var(--Grey-absent, #D9D9D9)",paddingBottom:16},children:t.jsx("span",{style:{fontSize:14,fontWeight:400,color:"var(--Grey-Strong, #2E3236)",lineHeight:1.2},children:"Transcript"})}),t.jsx("div",{id:"transcript-container",ref:K,style:{display:"flex",flexDirection:"column",maxHeight:600,overflowY:"auto"},children:(O||I.map(e=>({actor:e.speaker,actorType:e.type,text:e.text,timeRange:e.time}))).map((e,n)=>{const r=!!O,i=r?k&&X===n:n===N&&k,o=(e.actorType||e.type)==="customer";return t.jsxs("div",{style:{display:"flex",padding:16,flexDirection:"column",alignItems:"flex-start",gap:16,alignSelf:"stretch",borderTop:n>0?"1px solid var(--Grey-absent, #D9D9D9)":"none",background:i?"var(--surface-hover, #F3F7F7)":"var(--Grey-White, #FFF)"},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",gap:8},children:[t.jsx("span",{style:{fontSize:14,fontWeight:600,lineHeight:1.2,color:o?"var(--Grey-Strong, #2E3236)":"var(--Grey-Muted, #808183)"},children:e.actor}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[i&&t.jsxs(t.Fragment,{children:[t.jsx(u.AudioLines,{size:12,color:"#2E3236"}),t.jsx(u.AudioLines,{size:12,color:"#2E3236"})]}),t.jsx("span",{style:{fontSize:13,fontWeight:400,lineHeight:1.2,color:"var(--Grey-Muted, #808183)"},children:e.timeRange})]})]}),t.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:8,width:"100%"},children:[t.jsx("button",{onClick:()=>{r&&Y?Y(e,n):Se(n)},style:{background:"none",border:"none",cursor:"pointer",padding:0,flexShrink:0,display:"flex"},children:i?t.jsx(u.PauseCircle,{size:17,color:"#2E3236",strokeWidth:1.5}):t.jsx(u.PlayCircle,{size:17,color:"#808183",strokeWidth:1})}),t.jsx("p",{style:{fontSize:13,fontWeight:400,color:"var(--Grey-Strong, #2E3236)",lineHeight:1.2,margin:0,flex:1},children:e.text})]})]},n)})})]})]})]})});exports.UpdatedInteractionRecording=Ce;
|
|
2
2
|
//# sourceMappingURL=UpdatedInteractionRecording.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdatedInteractionRecording.cjs.js","sources":["../src/components/UpdatedInteractionDetails/UpdatedInteractionRecording.jsx"],"sourcesContent":["import { useRef, useState, useEffect, useCallback, forwardRef, useImperativeHandle } from 'react';\nimport {\n Play, Pause, RotateCcw, RotateCw,\n ChevronDown,\n AudioLines, PlayCircle, PauseCircle,\n FileSignal,\n} from 'lucide-react';\nimport Timeline from '../media/Timeline.jsx';\n\nfunction fmtTime(seconds) {\n const m = Math.floor(seconds / 60);\n const s = Math.round(seconds % 60);\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\n/* ── Demo data for static preview ── */\nconst DEMO_SEGMENTS = {\n Agent: [\n { start: 0, end: 0.08 },\n { start: 0.18, end: 0.22 },\n { start: 0.38, end: 0.42 },\n { start: 0.55, end: 0.58 },\n { start: 0.68, end: 0.72 },\n { start: 0.82, end: 0.88 },\n { start: 0.94, end: 1 },\n ],\n Customer: [\n { start: 0.1, end: 0.16 },\n { start: 0.24, end: 0.36 },\n { start: 0.44, end: 0.52 },\n { start: 0.6, end: 0.66 },\n { start: 0.74, end: 0.80 },\n ],\n};\n\nconst DEMO_TRANSCRIPT = [\n { speaker: 'Agent', type: 'agent', time: '00:04', text: 'Thanks for calling Miles Point S Pensau. This is Steve. How can I help you?' },\n { speaker: 'Customer', type: 'customer', time: '00:12', text: 'Hi, Steve. This is Sandra with Botai Catering.' },\n { speaker: 'Agent', type: 'agent', time: '00:18', text: 'Hello. How are you?' },\n { speaker: 'Customer', type: 'customer', time: '00:20', text: \"I'm doing really good. Hey. I brought my vans in last week, and I call it a beeping van, the one that beeps when you back up. Makes the crunchy noise. So I just took it on Saturday after, I think I had the, the Miles. I picked it up on Saturday morning, and I went to an event. So So I don't know if it's the tire or something, but makes it a little crunchy noise. Sometimes when I do the brake, but only if I turn the wheel too.\" },\n { speaker: 'Agent', type: 'agent', time: '00:21', text: 'Oh, interesting. Okay. Can you swing by with it one of these days?' },\n];\n\nconst SPEED_OPTIONS = [1, 1.25, 1.5, 2];\n\nfunction parseTimeStr(timeStr) {\n if (!timeStr) return 0;\n const parts = timeStr.split(':').map(Number);\n return (parts[0] || 0) * 60 + (parts[1] || 0);\n}\n\n/* ── Component ── */\nconst UpdatedInteractionRecording = forwardRef(function UpdatedInteractionRecording({\n audioUrl,\n timelineSegments = [],\n durationSeconds = 0,\n // Parent-managed audio props (optional — if not provided, component manages its own audio)\n currentTimeSeconds: externalCurrentTime,\n timelinePlaying: externalPlaying,\n playbackRate: externalRate,\n onSeek: externalOnSeek,\n onTogglePlay: externalOnTogglePlay,\n onSeekBack: externalOnSeekBack,\n onSeekForward: externalOnSeekForward,\n onSetPlaybackRate: externalOnSetPlaybackRate,\n audioRef: externalAudioRef,\n // Speaker names\n agentName = 'Agent',\n customerName = 'Customer',\n // Transcript props\n transcript,\n highlightedTurns = new Set(),\n activeTurnIndex,\n activeDemoIndex = 1,\n turnObservations = {},\n setExpandedSignals,\n onTurnPlayPause,\n}, ref) {\n const scrollRef = useRef(null);\n const internalAudioRef = useRef(null);\n const animFrameRef = useRef(null);\n\n // Internal audio state (used when audioUrl is provided but parent doesn't manage playback)\n const [internalPlaying, setInternalPlaying] = useState(false);\n const [internalCurrentTime, setInternalCurrentTime] = useState(0);\n const [internalDuration, setInternalDuration] = useState(0);\n const [internalRate, setInternalRate] = useState(1);\n\n // Demo state (used when no audioUrl)\n const [demoSeekTime, setDemoSeekTime] = useState(null);\n const [demoRate, setDemoRate] = useState(1);\n const [demoPlaying, setDemoPlaying] = useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = useState(false);\n const [activeDemoIdx, setActiveDemoIdx] = useState(activeDemoIndex);\n\n // Determine control mode\n const parentManaged = !!externalAudioRef;\n const isDemo = !audioUrl;\n const selfManaged = audioUrl && !parentManaged;\n\n // Unified state\n const activePlaying = isDemo ? demoPlaying : (parentManaged ? (externalPlaying ?? false) : internalPlaying);\n const activeCurrentTime = isDemo ? (demoSeekTime ?? 0) : (parentManaged ? (externalCurrentTime ?? 0) : internalCurrentTime);\n const activeRate = isDemo ? demoRate : (parentManaged ? (externalRate ?? 1) : internalRate);\n const activeDuration = isDemo ? (durationSeconds || 156) : (parentManaged ? durationSeconds : (internalDuration || durationSeconds || 0));\n const audioRefToUse = parentManaged ? externalAudioRef : internalAudioRef;\n\n /* ── Internal audio time tracking via requestAnimationFrame ── */\n const startTimeTracking = useCallback(() => {\n const tick = () => {\n const audio = internalAudioRef.current;\n if (audio) setInternalCurrentTime(audio.currentTime);\n animFrameRef.current = requestAnimationFrame(tick);\n };\n animFrameRef.current = requestAnimationFrame(tick);\n }, []);\n\n const stopTimeTracking = useCallback(() => {\n if (animFrameRef.current) {\n cancelAnimationFrame(animFrameRef.current);\n animFrameRef.current = null;\n }\n }, []);\n\n // Cleanup on unmount\n useEffect(() => () => stopTimeTracking(), [stopTimeTracking]);\n\n // Wire up internal audio element events\n useEffect(() => {\n if (!selfManaged) return;\n const audio = internalAudioRef.current;\n if (!audio) return;\n const onLoaded = () => setInternalDuration(audio.duration || 0);\n const onEnded = () => { setInternalPlaying(false); stopTimeTracking(); };\n audio.addEventListener('loadedmetadata', onLoaded);\n audio.addEventListener('ended', onEnded);\n return () => {\n audio.removeEventListener('loadedmetadata', onLoaded);\n audio.removeEventListener('ended', onEnded);\n };\n }, [selfManaged, stopTimeTracking]);\n\n /* Compute which transcript card matches current playback time */\n const computeActiveIdx = (timeSec) => {\n for (let i = DEMO_TRANSCRIPT.length - 1; i >= 0; i--) {\n const turnTime = parseTimeStr(DEMO_TRANSCRIPT[i].time);\n if (timeSec >= turnTime) return i;\n }\n return 0;\n };\n\n /* ── Unified handlers ── */\n const handleSeek = (timeSeconds) => {\n const dur = activeDuration || 156;\n const clamped = Math.max(0, Math.min(timeSeconds, dur));\n\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) audio.currentTime = clamped;\n setInternalCurrentTime(clamped);\n } else if (parentManaged && externalOnSeek) {\n externalOnSeek(clamped);\n }\n\n // Always update demo state for UI\n setDemoSeekTime(clamped);\n setActiveDemoIdx(computeActiveIdx(clamped));\n };\n\n const handleTogglePlay = () => {\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (!audio) return;\n if (internalPlaying) {\n audio.pause();\n stopTimeTracking();\n setInternalPlaying(false);\n } else {\n audio.play().then(() => {\n setInternalPlaying(true);\n startTimeTracking();\n }).catch(() => {});\n }\n } else if (parentManaged && externalOnTogglePlay) {\n externalOnTogglePlay();\n } else {\n // Demo mode\n setDemoPlaying((prev) => !prev);\n }\n };\n\n const handleSeekBack = () => {\n if (parentManaged && externalOnSeekBack) externalOnSeekBack();\n else {\n const cur = selfManaged ? internalCurrentTime : (demoSeekTime ?? 0);\n handleSeek(Math.max(0, cur - 10));\n }\n };\n\n const handleSeekForward = () => {\n if (parentManaged && externalOnSeekForward) externalOnSeekForward();\n else {\n const cur = selfManaged ? internalCurrentTime : (demoSeekTime ?? 0);\n const dur = activeDuration || 156;\n handleSeek(Math.min(dur, cur + 10));\n }\n };\n\n const handleSetRate = (rate) => {\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) audio.playbackRate = rate;\n setInternalRate(rate);\n } else if (parentManaged && externalOnSetPlaybackRate) {\n externalOnSetPlaybackRate(rate);\n }\n setDemoRate(rate);\n setShowSpeedMenu(false);\n };\n\n /* Expose seekTo for parent to call via ref (e.g. from Signals \"Show in transcript\") */\n useImperativeHandle(ref, () => ({\n seekTo: (timeSec) => {\n handleSeek(timeSec);\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) {\n audio.play().then(() => {\n setInternalPlaying(true);\n startTimeTracking();\n }).catch(() => {});\n }\n } else {\n setDemoPlaying(true);\n }\n const idx = computeActiveIdx(timeSec);\n setActiveDemoIdx(idx);\n setTimeout(() => {\n const cards = scrollRef.current?.children;\n if (cards?.[idx]) {\n cards[idx].scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }, 50);\n },\n }));\n\n /* Handle transcript card play/pause */\n const handleDemoTurnPlayPause = (idx) => {\n if (activeDemoIdx === idx && activePlaying) {\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) audio.pause();\n stopTimeTracking();\n setInternalPlaying(false);\n }\n setDemoPlaying(false);\n } else {\n const turnTime = parseTimeStr(DEMO_TRANSCRIPT[idx]?.time);\n setActiveDemoIdx(idx);\n handleSeek(turnTime);\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) {\n audio.currentTime = turnTime;\n audio.play().then(() => {\n setInternalPlaying(true);\n startTimeTracking();\n }).catch(() => {});\n }\n }\n setDemoPlaying(true);\n }\n };\n\n /* transcript turn builder */\n const formatTimeRange = (startMs, endMs) => {\n if (startMs == null) return undefined;\n const fmt = (ms) => {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n };\n return `${fmt(startMs)}\\u2013${endMs != null ? fmt(endMs) : fmt(startMs)}`;\n };\n\n const turns = transcript?.messages?.length\n ? transcript.messages.map((m, i) => ({\n actor: m.actor === 'agent' ? (transcript.actor_map?.agent || 'Agent') : (transcript.actor_map?.customer || 'Customer'),\n actorType: m.actor === 'agent' ? 'agent' : 'customer',\n text: m.text || '',\n timeRange: formatTimeRange(m.start ?? m.start_ms, m.end ?? m.end_ms),\n isHighlighted: highlightedTurns.has(i),\n highlightColor: activePlaying && activeTurnIndex === i\n ? (m.actor === 'agent' ? 'var(--rail-outcome)' : 'var(--rail-discovery)')\n : undefined,\n observations: (turnObservations[i] || []).map((obs) => ({\n ...obs,\n onClick: () => {\n setExpandedSignals?.((prev) => new Set([...prev, obs.signalKey]));\n setTimeout(() => {\n const el = document.getElementById(`signal-${obs.signalKey}`);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 100);\n },\n })),\n }))\n : null;\n\n // Computed display values\n const effectiveTime = isDemo ? (demoSeekTime ?? 0) : activeCurrentTime;\n const effectiveDuration = activeDuration || 156;\n const progress = effectiveDuration > 0 ? (effectiveTime / effectiveDuration) * 100 : 0;\n const displayTime = Math.round(effectiveTime);\n\n return (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 16,\n }}>\n {/* ── \"Recording\" title with icon — outside the card, matches Signals style ── */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 16,\n width: '100%',\n }}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 34,\n height: 34,\n borderRadius: 9999,\n background: 'var(--surface-hover, #F3F7F7)',\n flexShrink: 0,\n }}>\n <FileSignal size={20} color=\"#2E3236\" strokeWidth={1.5} />\n </div>\n <span style={{\n fontSize: 15,\n fontWeight: 500,\n color: 'var(--Grey-Strong, #2E3236)',\n }}>\n Recording\n </span>\n </div>\n\n {/* ── Card with border ── */}\n <div style={{\n display: 'flex',\n padding: 24,\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: 24,\n borderRadius: 8,\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n background: 'var(--Grey-White, #FFF)',\n }}>\n\n {/* ════════════════════════════════════════\n RECORDING CONTROLS\n ════════════════════════════════════════ */}\n <div style={{ width: '100%', display: 'flex', flexDirection: 'column', gap: 16 }}>\n\n {/* ── \"Agent / Customer\" + Controls — horizontal, space-between, center ── */}\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 24 }}>\n <span style={{\n fontSize: 14, fontWeight: 500,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n }}>\n {agentName} / {customerName}\n </span>\n\n {/* Controls — horizontal, gap: 12, center */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>\n {/* Skip back 10s */}\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.2 }}>10</span>\n <button onClick={handleSeekBack} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', alignItems: 'center' }}>\n <RotateCcw size={20} color=\"#808183\" strokeWidth={1.5} />\n </button>\n\n {/* Play / Pause — 32x32 dark circle */}\n <button onClick={handleTogglePlay} style={{\n background: 'var(--Grey-Strong, #2E3236)',\n border: 'none', cursor: 'pointer',\n width: 32, height: 32, borderRadius: 48,\n padding: 0,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n }}>\n {activePlaying\n ? <Pause size={14} color=\"#FFF\" fill=\"#FFF\" />\n : <Play size={14} color=\"#FFF\" fill=\"#FFF\" strokeWidth={1.5} style={{ marginLeft: 2 }} />\n }\n </button>\n\n {/* Skip forward 10s */}\n <button onClick={handleSeekForward} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', alignItems: 'center' }}>\n <RotateCw size={20} color=\"#808183\" strokeWidth={1.5} />\n </button>\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.2 }}>10</span>\n </div>\n\n {/* Speed pill with dropdown */}\n <div style={{ position: 'relative' }}>\n <button\n onClick={() => setShowSpeedMenu((prev) => !prev)}\n style={{\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 20,\n padding: '0 5px 0 10px',\n height: 24,\n minWidth: 56,\n cursor: 'pointer',\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 4,\n }}\n >\n {activeRate}x\n <ChevronDown size={12} color=\"#808183\" />\n </button>\n\n {showSpeedMenu && (\n <div style={{\n position: 'absolute',\n top: '100%',\n right: 0,\n marginTop: 4,\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 8,\n boxShadow: '0 4px 12px rgba(0,0,0,0.1)',\n zIndex: 10,\n overflow: 'hidden',\n minWidth: 80,\n }}>\n {SPEED_OPTIONS.map((speed) => (\n <button\n key={speed}\n onClick={() => handleSetRate(speed)}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n border: 'none',\n background: activeRate === speed ? 'var(--surface-hover, #F3F7F7)' : 'var(--Grey-White, #FFF)',\n cursor: 'pointer',\n fontSize: 13,\n fontWeight: activeRate === speed ? 600 : 400,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n textAlign: 'left',\n }}\n >\n {speed}x\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* ── Row 2: Progress bar ── */}\n {audioUrl && parentManaged ? (\n <>\n <Timeline\n segments={timelineSegments}\n durationSeconds={durationSeconds}\n currentTimeSeconds={externalCurrentTime}\n onSeek={externalOnSeek}\n showControls={false}\n hasRecording\n timelinePlaying={externalPlaying}\n playbackRate={externalRate}\n />\n <audio ref={externalAudioRef} preload=\"none\" style={{ display: 'none' }}>\n <source src={audioUrl} type=\"audio/mpeg\" />\n </audio>\n </>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n {/* Time label + scrubber bar */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{\n fontSize: 13, fontWeight: 600,\n color: progress > 0 ? 'var(--Green-Primary, #00925F)' : 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n minWidth: 60,\n }}>\n {fmtTime(displayTime)}\n </span>\n <div\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const pct = Math.max(0, Math.min(1, clickX / rect.width));\n handleSeek(pct * effectiveDuration);\n }}\n style={{\n flex: 1, height: 16,\n position: 'relative',\n display: 'flex', alignItems: 'center',\n cursor: 'pointer',\n }}\n >\n {/* Background track — Figma: #E3E1D7, stroke w=4 */}\n <div style={{\n position: 'absolute', left: 0, right: 0,\n height: 4, borderRadius: 2,\n background: 'var(--rail-surface-2, #E3E1D7)',\n pointerEvents: 'none',\n }} />\n {/* Played portion — Figma: #00925F, stroke w=4 */}\n <div style={{\n position: 'absolute', left: 0, top: '50%',\n transform: 'translateY(-50%)',\n width: `${progress}%`,\n height: 4, borderRadius: 2,\n background: 'var(--Green-Primary, #00925F)',\n pointerEvents: 'none',\n }} />\n {/* Scrubber handle — Figma ellipse */}\n <svg\n width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{\n position: 'absolute',\n left: `${progress}%`,\n top: '50%',\n transform: 'translate(-50%, -50%)',\n pointerEvents: 'none',\n }}\n >\n <path\n d=\"M7.875 1C11.6572 1 14.75 4.1191 14.75 8C14.75 11.8809 11.6572 15 7.875 15C4.09284 15 1 11.8809 1 8C1 4.1191 4.09284 1 7.875 1Z\"\n fill=\"#FFF\"\n stroke=\"#00925F\"\n strokeWidth=\"2\"\n />\n </svg>\n </div>\n </div>\n\n {/* ── Row 3: Speaker timeline bars + playback indicator ── */}\n <div style={{ position: 'relative', paddingBottom: 30, cursor: 'pointer' }}>\n {['Agent', 'Customer'].map((speaker, rowIdx) => (\n <div key={speaker} style={{\n display: 'flex', alignItems: 'center', gap: 8,\n height: 20,\n marginBottom: rowIdx === 0 ? 4 : 0,\n }}>\n <span style={{\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Muted, #808183)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n minWidth: 60,\n }}>\n {speaker}\n </span>\n <div\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const pct = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n handleSeek(pct * effectiveDuration);\n }}\n style={{\n flex: 1, height: 6,\n position: 'relative', borderRadius: 3,\n cursor: 'pointer',\n }}\n >\n {/* Thin baseline — Figma: #E3E1D7, stroke w=4 */}\n <div style={{\n position: 'absolute', left: 0, right: 0,\n top: '50%', transform: 'translateY(-50%)',\n height: 4, borderRadius: 2,\n background: 'var(--rail-surface-2, #E3E1D7)',\n }} />\n {/* Speech segments */}\n {DEMO_SEGMENTS[speaker].map((seg, i) => (\n <div key={i} style={{\n position: 'absolute',\n left: `${seg.start * 100}%`,\n width: `${(seg.end - seg.start) * 100}%`,\n top: 0, bottom: 0, borderRadius: 3,\n background: speaker === 'Agent'\n ? 'var(--Grey-Strong, #2E3236)'\n : 'var(--Grey-Muted, #808183)',\n }} />\n ))}\n </div>\n </div>\n ))}\n\n {/* ── Playback position: dotted line + time tooltip ── */}\n <div style={{\n position: 'absolute',\n left: 68, /* 60 label + 8 gap */\n right: 0,\n top: 0,\n bottom: 0,\n pointerEvents: 'none',\n }}>\n {/* Dotted vertical line */}\n <div style={{\n position: 'absolute',\n left: `${progress}%`,\n top: 0,\n height: 44, /* spans both rows */\n transform: 'translateX(-50%)',\n borderLeft: '1.5px dashed var(--Grey-Muted, #808183)',\n opacity: 0.5,\n }} />\n\n {/* Time tooltip — Figma: Frame 30, bg=#2E3236, pad 4 6, r=4, 14px/600/#FFF */}\n <div style={{\n position: 'absolute',\n left: `${progress}%`,\n bottom: 0,\n transform: 'translateX(-50%)',\n background: 'var(--Grey-Strong, #2E3236)',\n color: 'var(--Grey-White, #FFF)',\n fontSize: 14, fontWeight: 600,\n lineHeight: 1.2,\n padding: '4px 6px',\n borderRadius: 4,\n whiteSpace: 'nowrap',\n }}>\n {fmtTime(displayTime)}\n </div>\n </div>\n </div>\n\n {/* Hidden audio element for self-managed mode */}\n {selfManaged && (\n <audio ref={internalAudioRef} preload=\"auto\" style={{ display: 'none' }}>\n <source src={audioUrl} type=\"audio/mpeg\" />\n </audio>\n )}\n </div>\n )}\n </div>\n\n {/* ════════════════════════════════════════\n TRANSCRIPT SECTION\n ════════════════════════════════════════ */}\n {/* Figma: Frame 49, vertical, gap: 16 */}\n <div style={{\n width: '100%',\n display: 'flex', flexDirection: 'column', gap: 16,\n }}>\n {/* ── Header: Transcript ── */}\n <div style={{\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n paddingBottom: 16,\n }}>\n <span style={{\n fontSize: 14, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n }}>\n Transcript\n </span>\n </div>\n\n {/* ── Cards — V4 style for both real and demo data ── */}\n <div id=\"transcript-container\" ref={scrollRef} style={{\n display: 'flex', flexDirection: 'column',\n maxHeight: 600, overflowY: 'auto',\n }}>\n {(turns || DEMO_TRANSCRIPT.map((card) => ({\n actor: card.speaker,\n actorType: card.type,\n text: card.text,\n timeRange: card.time,\n }))).map((card, i) => {\n const isRealData = !!turns;\n const isActive = isRealData\n ? (activePlaying && activeTurnIndex === i)\n : (i === activeDemoIdx && activePlaying);\n const isCustomer = (card.actorType || card.type) === 'customer';\n\n return (\n <div key={i} style={{\n display: 'flex',\n padding: 16,\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: 16,\n alignSelf: 'stretch',\n borderTop: i > 0 ? '1px solid var(--Grey-absent, #D9D9D9)' : 'none',\n background: isActive ? 'var(--surface-hover, #F3F7F7)' : 'var(--Grey-White, #FFF)',\n }}>\n {/* Speaker name + time */}\n <div style={{\n display: 'flex', alignItems: 'center',\n justifyContent: 'space-between', width: '100%',\n gap: 8,\n }}>\n <span style={{\n fontSize: 14, fontWeight: 600,\n lineHeight: 1.2,\n color: isCustomer ? 'var(--Grey-Strong, #2E3236)' : 'var(--Grey-Muted, #808183)',\n }}>\n {card.actor}\n </span>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {isActive && (\n <>\n <AudioLines size={12} color=\"#2E3236\" />\n <AudioLines size={12} color=\"#2E3236\" />\n </>\n )}\n <span style={{\n fontSize: 13, fontWeight: 400,\n lineHeight: 1.2,\n color: 'var(--Grey-Muted, #808183)',\n }}>\n {card.timeRange}\n </span>\n </div>\n </div>\n\n {/* Play/Pause icon + text */}\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8, width: '100%' }}>\n <button\n onClick={() => {\n if (isRealData && onTurnPlayPause) {\n onTurnPlayPause(card, i);\n } else {\n handleDemoTurnPlayPause(i);\n }\n }}\n style={{\n background: 'none', border: 'none',\n cursor: 'pointer', padding: 0,\n flexShrink: 0,\n display: 'flex',\n }}\n >\n {isActive ? (\n <PauseCircle size={17} color=\"#2E3236\" strokeWidth={1.5} />\n ) : (\n <PlayCircle size={17} color=\"#808183\" strokeWidth={1} />\n )}\n </button>\n <p style={{\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n margin: 0,\n flex: 1,\n }}>\n {card.text}\n </p>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </div>{/* end card */}\n </div>\n );\n});\n\nexport default UpdatedInteractionRecording;\n"],"names":["fmtTime","seconds","m","s","DEMO_SEGMENTS","DEMO_TRANSCRIPT","SPEED_OPTIONS","parseTimeStr","timeStr","parts","UpdatedInteractionRecording","forwardRef","audioUrl","timelineSegments","durationSeconds","externalCurrentTime","externalPlaying","externalRate","externalOnSeek","externalOnTogglePlay","externalOnSeekBack","externalOnSeekForward","externalOnSetPlaybackRate","externalAudioRef","agentName","customerName","transcript","highlightedTurns","activeTurnIndex","activeDemoIndex","turnObservations","setExpandedSignals","onTurnPlayPause","ref","scrollRef","useRef","internalAudioRef","animFrameRef","internalPlaying","setInternalPlaying","useState","internalCurrentTime","setInternalCurrentTime","internalDuration","setInternalDuration","internalRate","setInternalRate","demoSeekTime","setDemoSeekTime","demoRate","setDemoRate","demoPlaying","setDemoPlaying","showSpeedMenu","setShowSpeedMenu","activeDemoIdx","setActiveDemoIdx","parentManaged","isDemo","selfManaged","activePlaying","activeCurrentTime","activeRate","activeDuration","startTimeTracking","useCallback","tick","audio","stopTimeTracking","useEffect","onLoaded","onEnded","computeActiveIdx","timeSec","turnTime","handleSeek","timeSeconds","clamped","handleTogglePlay","prev","handleSeekBack","handleSeekForward","handleSetRate","rate","useImperativeHandle","idx","cards","_a","handleDemoTurnPlayPause","formatTimeRange","startMs","endMs","fmt","ms","minutes","turns","_b","obs","el","effectiveTime","effectiveDuration","progress","displayTime","jsxs","jsx","FileSignal","RotateCcw","Pause","Play","RotateCw","ChevronDown","speed","Fragment","Timeline","rect","clickX","pct","speaker","rowIdx","e","seg","i","card","isRealData","isActive","isCustomer","AudioLines","PauseCircle","PlayCircle"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UpdatedInteractionRecording.cjs.js","sources":["../src/components/UpdatedInteractionDetails/UpdatedInteractionRecording.jsx"],"sourcesContent":["import { useRef, useState, useEffect, useCallback, forwardRef, useImperativeHandle } from 'react';\nimport {\n Play, Pause, RotateCcw, RotateCw,\n ChevronDown,\n AudioLines, PlayCircle, PauseCircle,\n FileSignal,\n} from 'lucide-react';\n\nfunction fmtTime(seconds) {\n const m = Math.floor(seconds / 60);\n const s = Math.round(seconds % 60);\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\n/* ── Demo data for static preview ── */\nconst DEMO_SEGMENTS = {\n Agent: [\n { start: 0, end: 0.08 },\n { start: 0.18, end: 0.22 },\n { start: 0.38, end: 0.42 },\n { start: 0.55, end: 0.58 },\n { start: 0.68, end: 0.72 },\n { start: 0.82, end: 0.88 },\n { start: 0.94, end: 1 },\n ],\n Customer: [\n { start: 0.1, end: 0.16 },\n { start: 0.24, end: 0.36 },\n { start: 0.44, end: 0.52 },\n { start: 0.6, end: 0.66 },\n { start: 0.74, end: 0.80 },\n ],\n};\n\nconst DEMO_TRANSCRIPT = [\n { speaker: 'Agent', type: 'agent', time: '00:04', text: 'Thanks for calling Miles Point S Pensau. This is Steve. How can I help you?' },\n { speaker: 'Customer', type: 'customer', time: '00:12', text: 'Hi, Steve. This is Sandra with Botai Catering.' },\n { speaker: 'Agent', type: 'agent', time: '00:18', text: 'Hello. How are you?' },\n { speaker: 'Customer', type: 'customer', time: '00:20', text: \"I'm doing really good. Hey. I brought my vans in last week, and I call it a beeping van, the one that beeps when you back up. Makes the crunchy noise. So I just took it on Saturday after, I think I had the, the Miles. I picked it up on Saturday morning, and I went to an event. So So I don't know if it's the tire or something, but makes it a little crunchy noise. Sometimes when I do the brake, but only if I turn the wheel too.\" },\n { speaker: 'Agent', type: 'agent', time: '00:21', text: 'Oh, interesting. Okay. Can you swing by with it one of these days?' },\n];\n\nconst SPEED_OPTIONS = [1, 1.25, 1.5, 2];\n\nfunction parseTimeStr(timeStr) {\n if (!timeStr) return 0;\n const parts = timeStr.split(':').map(Number);\n return (parts[0] || 0) * 60 + (parts[1] || 0);\n}\n\n/* ── Component ── */\nconst UpdatedInteractionRecording = forwardRef(function UpdatedInteractionRecording({\n audioUrl,\n timelineSegments = [],\n durationSeconds = 0,\n // Parent-managed audio props (optional — if not provided, component manages its own audio)\n currentTimeSeconds: externalCurrentTime,\n timelinePlaying: externalPlaying,\n playbackRate: externalRate,\n onSeek: externalOnSeek,\n onTogglePlay: externalOnTogglePlay,\n onSeekBack: externalOnSeekBack,\n onSeekForward: externalOnSeekForward,\n onSetPlaybackRate: externalOnSetPlaybackRate,\n audioRef: externalAudioRef,\n // Speaker names\n agentName = 'Agent',\n customerName = 'Customer',\n // Transcript props\n transcript,\n highlightedTurns = new Set(),\n activeTurnIndex,\n activeDemoIndex = 1,\n turnObservations = {},\n setExpandedSignals,\n onTurnPlayPause,\n}, ref) {\n const scrollRef = useRef(null);\n const internalAudioRef = useRef(null);\n const animFrameRef = useRef(null);\n\n // Internal audio state (used when audioUrl is provided but parent doesn't manage playback)\n const [internalPlaying, setInternalPlaying] = useState(false);\n const [internalCurrentTime, setInternalCurrentTime] = useState(0);\n const [internalDuration, setInternalDuration] = useState(0);\n const [internalRate, setInternalRate] = useState(1);\n\n // Demo state (used when no audioUrl)\n const [demoSeekTime, setDemoSeekTime] = useState(null);\n const [demoRate, setDemoRate] = useState(1);\n const [demoPlaying, setDemoPlaying] = useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = useState(false);\n const [activeDemoIdx, setActiveDemoIdx] = useState(activeDemoIndex);\n\n // Determine control mode\n const parentManaged = !!externalAudioRef;\n const isDemo = !audioUrl;\n const selfManaged = audioUrl && !parentManaged;\n\n // Unified state\n const activePlaying = isDemo ? demoPlaying : (parentManaged ? (externalPlaying ?? false) : internalPlaying);\n const activeCurrentTime = isDemo ? (demoSeekTime ?? 0) : (parentManaged ? (externalCurrentTime ?? 0) : internalCurrentTime);\n const activeRate = isDemo ? demoRate : (parentManaged ? (externalRate ?? 1) : internalRate);\n const activeDuration = isDemo ? (durationSeconds || 156) : (parentManaged ? durationSeconds : (internalDuration || durationSeconds || 0));\n const audioRefToUse = parentManaged ? externalAudioRef : internalAudioRef;\n\n /* ── Internal audio time tracking via requestAnimationFrame ── */\n const startTimeTracking = useCallback(() => {\n const tick = () => {\n const audio = internalAudioRef.current;\n if (audio) setInternalCurrentTime(audio.currentTime);\n animFrameRef.current = requestAnimationFrame(tick);\n };\n animFrameRef.current = requestAnimationFrame(tick);\n }, []);\n\n const stopTimeTracking = useCallback(() => {\n if (animFrameRef.current) {\n cancelAnimationFrame(animFrameRef.current);\n animFrameRef.current = null;\n }\n }, []);\n\n // Cleanup on unmount\n useEffect(() => () => stopTimeTracking(), [stopTimeTracking]);\n\n // Wire up internal audio element events\n useEffect(() => {\n if (!selfManaged) return;\n const audio = internalAudioRef.current;\n if (!audio) return;\n const onLoaded = () => setInternalDuration(audio.duration || 0);\n const onEnded = () => { setInternalPlaying(false); stopTimeTracking(); };\n audio.addEventListener('loadedmetadata', onLoaded);\n audio.addEventListener('ended', onEnded);\n return () => {\n audio.removeEventListener('loadedmetadata', onLoaded);\n audio.removeEventListener('ended', onEnded);\n };\n }, [selfManaged, stopTimeTracking]);\n\n /* Compute which transcript card matches current playback time */\n const computeActiveIdx = (timeSec) => {\n for (let i = DEMO_TRANSCRIPT.length - 1; i >= 0; i--) {\n const turnTime = parseTimeStr(DEMO_TRANSCRIPT[i].time);\n if (timeSec >= turnTime) return i;\n }\n return 0;\n };\n\n /* ── Unified handlers ── */\n const handleSeek = (timeSeconds) => {\n const dur = activeDuration || 156;\n const clamped = Math.max(0, Math.min(timeSeconds, dur));\n\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) audio.currentTime = clamped;\n setInternalCurrentTime(clamped);\n } else if (parentManaged && externalOnSeek) {\n externalOnSeek(clamped);\n }\n\n // Always update demo state for UI\n setDemoSeekTime(clamped);\n setActiveDemoIdx(computeActiveIdx(clamped));\n };\n\n const handleTogglePlay = () => {\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (!audio) return;\n if (internalPlaying) {\n audio.pause();\n stopTimeTracking();\n setInternalPlaying(false);\n } else {\n audio.play().then(() => {\n setInternalPlaying(true);\n startTimeTracking();\n }).catch(() => {});\n }\n } else if (parentManaged && externalOnTogglePlay) {\n externalOnTogglePlay();\n } else {\n // Demo mode\n setDemoPlaying((prev) => !prev);\n }\n };\n\n const handleSeekBack = () => {\n if (parentManaged && externalOnSeekBack) externalOnSeekBack();\n else {\n const cur = selfManaged ? internalCurrentTime : (demoSeekTime ?? 0);\n handleSeek(Math.max(0, cur - 10));\n }\n };\n\n const handleSeekForward = () => {\n if (parentManaged && externalOnSeekForward) externalOnSeekForward();\n else {\n const cur = selfManaged ? internalCurrentTime : (demoSeekTime ?? 0);\n const dur = activeDuration || 156;\n handleSeek(Math.min(dur, cur + 10));\n }\n };\n\n const handleSetRate = (rate) => {\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) audio.playbackRate = rate;\n setInternalRate(rate);\n } else if (parentManaged && externalOnSetPlaybackRate) {\n externalOnSetPlaybackRate(rate);\n }\n setDemoRate(rate);\n setShowSpeedMenu(false);\n };\n\n /* Expose seekTo for parent to call via ref (e.g. from Signals \"Show in transcript\") */\n useImperativeHandle(ref, () => ({\n seekTo: (timeSec) => {\n handleSeek(timeSec);\n if (parentManaged) {\n // Parent manages audio — seek was already called via handleSeek → externalOnSeek\n // Now trigger play if not already playing\n if (!externalPlaying && externalOnTogglePlay) {\n externalOnTogglePlay();\n }\n } else if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) {\n audio.play().then(() => {\n setInternalPlaying(true);\n startTimeTracking();\n }).catch(() => {});\n }\n } else {\n setDemoPlaying(true);\n }\n const idx = computeActiveIdx(timeSec);\n setActiveDemoIdx(idx);\n setTimeout(() => {\n const cards = scrollRef.current?.children;\n if (cards?.[idx]) {\n cards[idx].scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }, 50);\n },\n }));\n\n /* Handle transcript card play/pause */\n const handleDemoTurnPlayPause = (idx) => {\n if (activeDemoIdx === idx && activePlaying) {\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) audio.pause();\n stopTimeTracking();\n setInternalPlaying(false);\n }\n setDemoPlaying(false);\n } else {\n const turnTime = parseTimeStr(DEMO_TRANSCRIPT[idx]?.time);\n setActiveDemoIdx(idx);\n handleSeek(turnTime);\n if (selfManaged) {\n const audio = internalAudioRef.current;\n if (audio) {\n audio.currentTime = turnTime;\n audio.play().then(() => {\n setInternalPlaying(true);\n startTimeTracking();\n }).catch(() => {});\n }\n }\n setDemoPlaying(true);\n }\n };\n\n /* transcript turn builder */\n const formatTimeRange = (startMs, endMs) => {\n if (startMs == null) return undefined;\n const fmt = (ms) => {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n };\n return `${fmt(startMs)}\\u2013${endMs != null ? fmt(endMs) : fmt(startMs)}`;\n };\n\n const turns = transcript?.messages?.length\n ? transcript.messages.map((m, i) => ({\n actor: m.actor === 'agent' ? (transcript.actor_map?.agent || 'Agent') : (transcript.actor_map?.customer || 'Customer'),\n actorType: m.actor === 'agent' ? 'agent' : 'customer',\n text: m.text || '',\n timeRange: formatTimeRange(m.start ?? m.start_ms, m.end ?? m.end_ms),\n isHighlighted: highlightedTurns.has(i),\n highlightColor: activePlaying && activeTurnIndex === i\n ? (m.actor === 'agent' ? 'var(--rail-outcome)' : 'var(--rail-discovery)')\n : undefined,\n observations: (turnObservations[i] || []).map((obs) => ({\n ...obs,\n onClick: () => {\n setExpandedSignals?.((prev) => new Set([...prev, obs.signalKey]));\n setTimeout(() => {\n const el = document.getElementById(`signal-${obs.signalKey}`);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 100);\n },\n })),\n }))\n : null;\n\n // Computed display values\n const effectiveTime = isDemo ? (demoSeekTime ?? 0) : activeCurrentTime;\n const effectiveDuration = activeDuration || 156;\n const progress = effectiveDuration > 0 ? (effectiveTime / effectiveDuration) * 100 : 0;\n const displayTime = Math.round(effectiveTime);\n\n return (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 16,\n }}>\n {/* ── \"Recording\" title with icon — outside the card, matches Signals style ── */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 16,\n width: '100%',\n }}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 34,\n height: 34,\n borderRadius: 9999,\n background: 'var(--surface-hover, #F3F7F7)',\n flexShrink: 0,\n }}>\n <FileSignal size={20} color=\"#2E3236\" strokeWidth={1.5} />\n </div>\n <span style={{\n fontSize: 15,\n fontWeight: 500,\n color: 'var(--Grey-Strong, #2E3236)',\n }}>\n Recording\n </span>\n </div>\n\n {/* ── Card with border ── */}\n <div style={{\n display: 'flex',\n padding: 24,\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: 24,\n borderRadius: 8,\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n background: 'var(--Grey-White, #FFF)',\n }}>\n\n {/* ════════════════════════════════════════\n RECORDING CONTROLS\n ════════════════════════════════════════ */}\n <div style={{ width: '100%', display: 'flex', flexDirection: 'column', gap: 16 }}>\n\n {/* ── \"Agent / Customer\" + Controls — horizontal, space-between, center ── */}\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 24 }}>\n <span style={{\n fontSize: 14, fontWeight: 500,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n }}>\n {agentName} / {customerName}\n </span>\n\n {/* Controls — horizontal, gap: 12, center */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>\n {/* Skip back 10s */}\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.2 }}>10</span>\n <button onClick={handleSeekBack} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', alignItems: 'center' }}>\n <RotateCcw size={20} color=\"#808183\" strokeWidth={1.5} />\n </button>\n\n {/* Play / Pause — 32x32 dark circle */}\n <button onClick={handleTogglePlay} style={{\n background: 'var(--Grey-Strong, #2E3236)',\n border: 'none', cursor: 'pointer',\n width: 32, height: 32, borderRadius: 48,\n padding: 0,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n }}>\n {activePlaying\n ? <Pause size={14} color=\"#FFF\" fill=\"#FFF\" />\n : <Play size={14} color=\"#FFF\" fill=\"#FFF\" strokeWidth={1.5} style={{ marginLeft: 2 }} />\n }\n </button>\n\n {/* Skip forward 10s */}\n <button onClick={handleSeekForward} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', alignItems: 'center' }}>\n <RotateCw size={20} color=\"#808183\" strokeWidth={1.5} />\n </button>\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.2 }}>10</span>\n </div>\n\n {/* Speed pill with dropdown */}\n <div style={{ position: 'relative' }}>\n <button\n onClick={() => setShowSpeedMenu((prev) => !prev)}\n style={{\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 20,\n padding: '0 5px 0 10px',\n height: 24,\n minWidth: 56,\n cursor: 'pointer',\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 4,\n }}\n >\n {activeRate}x\n <ChevronDown size={12} color=\"#808183\" />\n </button>\n\n {showSpeedMenu && (\n <div style={{\n position: 'absolute',\n top: '100%',\n right: 0,\n marginTop: 4,\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 8,\n boxShadow: '0 4px 12px rgba(0,0,0,0.1)',\n zIndex: 10,\n overflow: 'hidden',\n minWidth: 80,\n }}>\n {SPEED_OPTIONS.map((speed) => (\n <button\n key={speed}\n onClick={() => handleSetRate(speed)}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n border: 'none',\n background: activeRate === speed ? 'var(--surface-hover, #F3F7F7)' : 'var(--Grey-White, #FFF)',\n cursor: 'pointer',\n fontSize: 13,\n fontWeight: activeRate === speed ? 600 : 400,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n textAlign: 'left',\n }}\n >\n {speed}x\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* ── Row 2: Progress bar (V4 style for all modes) ── */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n {/* Time label + scrubber bar — same layout as speaker rows: 60px label + 8px gap + flex bar */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{\n fontSize: 13, fontWeight: 600,\n color: progress > 0 ? 'var(--Green-Primary, #00925F)' : 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n minWidth: 60,\n }}>\n {fmtTime(displayTime)}\n </span>\n <div\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const pct = Math.max(0, Math.min(1, clickX / rect.width));\n handleSeek(pct * effectiveDuration);\n }}\n style={{\n flex: 1, height: 16,\n position: 'relative',\n display: 'flex', alignItems: 'center',\n cursor: 'pointer',\n }}\n >\n {/* Background track */}\n <div style={{\n position: 'absolute', left: 0, right: 0,\n height: 4, borderRadius: 2,\n background: 'var(--rail-surface-2, #E3E1D7)',\n pointerEvents: 'none',\n }} />\n {/* Played portion */}\n <div style={{\n position: 'absolute', left: 0, top: '50%',\n transform: 'translateY(-50%)',\n width: `${progress}%`,\n height: 4, borderRadius: 2,\n background: 'var(--Green-Primary, #00925F)',\n pointerEvents: 'none',\n }} />\n {/* Scrubber handle */}\n <svg\n width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{\n position: 'absolute',\n left: `${progress}%`,\n top: '50%',\n transform: 'translate(-50%, -50%)',\n pointerEvents: 'none',\n }}\n >\n <path\n d=\"M7.875 1C11.6572 1 14.75 4.1191 14.75 8C14.75 11.8809 11.6572 15 7.875 15C4.09284 15 1 11.8809 1 8C1 4.1191 4.09284 1 7.875 1Z\"\n fill=\"#FFF\"\n stroke=\"#00925F\"\n strokeWidth=\"2\"\n />\n </svg>\n {/* Duration at end — positioned inside the track so it doesn't affect track width */}\n <span style={{\n position: 'absolute',\n right: -48,\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Muted, #808183)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n whiteSpace: 'nowrap',\n }}>\n {fmtTime(effectiveDuration)}\n </span>\n </div>\n </div>\n\n {/* ── Speaker timeline bars + playback indicator ── */}\n <div style={{ position: 'relative', paddingBottom: 30, cursor: 'pointer' }}>\n {[agentName, customerName].map((speaker, rowIdx) => {\n const isAgent = rowIdx === 0;\n // Build segments from real timelineSegments or fall back to demo\n const speakerSegments = timelineSegments?.length\n ? timelineSegments\n .filter(s => isAgent ? s.actor === agentName : s.actor === customerName)\n .map(s => ({\n start: effectiveDuration > 0 ? s.startTime / effectiveDuration : 0,\n end: effectiveDuration > 0 ? s.endTime / effectiveDuration : 0,\n }))\n : (DEMO_SEGMENTS[isAgent ? 'Agent' : 'Customer'] || []);\n\n return (\n <div key={speaker} style={{\n display: 'flex', alignItems: 'center', gap: 8,\n height: 20,\n marginBottom: rowIdx === 0 ? 4 : 0,\n }}>\n <span style={{\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Muted, #808183)',\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n minWidth: 60,\n }}>\n {speaker}\n </span>\n <div\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const pct = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n handleSeek(pct * effectiveDuration);\n }}\n style={{\n flex: 1, height: 6,\n position: 'relative', borderRadius: 3,\n cursor: 'pointer',\n }}\n >\n {/* Thin baseline */}\n <div style={{\n position: 'absolute', left: 0, right: 0,\n top: '50%', transform: 'translateY(-50%)',\n height: 4, borderRadius: 2,\n background: 'var(--rail-surface-2, #E3E1D7)',\n }} />\n {/* Speech segments */}\n {speakerSegments.map((seg, i) => (\n <div key={i} style={{\n position: 'absolute',\n left: `${seg.start * 100}%`,\n width: `${(seg.end - seg.start) * 100}%`,\n top: 0, bottom: 0, borderRadius: 3,\n background: isAgent\n ? 'var(--Grey-Strong, #2E3236)'\n : 'var(--Grey-Muted, #808183)',\n }} />\n ))}\n </div>\n </div>\n );\n })}\n\n {/* ── Playback position: dotted line + time tooltip ── */}\n <div style={{\n position: 'absolute',\n left: 68, /* 60 label + 8 gap */\n right: 0,\n top: 0,\n bottom: 0,\n pointerEvents: 'none',\n }}>\n {/* Dotted vertical line */}\n <div style={{\n position: 'absolute',\n left: `${progress}%`,\n top: 0,\n height: 44,\n transform: 'translateX(-50%)',\n borderLeft: '1.5px dashed var(--Grey-Muted, #808183)',\n opacity: 0.5,\n }} />\n\n {/* Time tooltip */}\n <div style={{\n position: 'absolute',\n left: `${progress}%`,\n bottom: 0,\n transform: 'translateX(-50%)',\n background: 'var(--Grey-Strong, #2E3236)',\n color: 'var(--Grey-White, #FFF)',\n fontSize: 14, fontWeight: 600,\n lineHeight: 1.2,\n padding: '4px 6px',\n borderRadius: 4,\n whiteSpace: 'nowrap',\n }}>\n {fmtTime(displayTime)}\n </div>\n </div>\n </div>\n\n {/* Hidden audio element — only for self-managed mode */}\n {selfManaged && (\n <audio ref={internalAudioRef} preload=\"auto\" style={{ display: 'none' }}>\n <source src={audioUrl} type=\"audio/mpeg\" />\n </audio>\n )}\n {/* Hidden audio element — for parent-managed mode */}\n {parentManaged && audioUrl && (\n <audio ref={externalAudioRef} preload=\"auto\" style={{ display: 'none' }}>\n <source src={audioUrl} type=\"audio/mpeg\" />\n </audio>\n )}\n </div>\n </div>\n\n {/* ════════════════════════════════════════\n TRANSCRIPT SECTION\n ════════════════════════════════════════ */}\n {/* Figma: Frame 49, vertical, gap: 16 */}\n <div style={{\n width: '100%',\n display: 'flex', flexDirection: 'column', gap: 16,\n }}>\n {/* ── Header: Transcript ── */}\n <div style={{\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n paddingBottom: 16,\n }}>\n <span style={{\n fontSize: 14, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n }}>\n Transcript\n </span>\n </div>\n\n {/* ── Cards — V4 style for both real and demo data ── */}\n <div id=\"transcript-container\" ref={scrollRef} style={{\n display: 'flex', flexDirection: 'column',\n maxHeight: 600, overflowY: 'auto',\n }}>\n {(turns || DEMO_TRANSCRIPT.map((card) => ({\n actor: card.speaker,\n actorType: card.type,\n text: card.text,\n timeRange: card.time,\n }))).map((card, i) => {\n const isRealData = !!turns;\n const isActive = isRealData\n ? (activePlaying && activeTurnIndex === i)\n : (i === activeDemoIdx && activePlaying);\n const isCustomer = (card.actorType || card.type) === 'customer';\n\n return (\n <div key={i} style={{\n display: 'flex',\n padding: 16,\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: 16,\n alignSelf: 'stretch',\n borderTop: i > 0 ? '1px solid var(--Grey-absent, #D9D9D9)' : 'none',\n background: isActive ? 'var(--surface-hover, #F3F7F7)' : 'var(--Grey-White, #FFF)',\n }}>\n {/* Speaker name + time */}\n <div style={{\n display: 'flex', alignItems: 'center',\n justifyContent: 'space-between', width: '100%',\n gap: 8,\n }}>\n <span style={{\n fontSize: 14, fontWeight: 600,\n lineHeight: 1.2,\n color: isCustomer ? 'var(--Grey-Strong, #2E3236)' : 'var(--Grey-Muted, #808183)',\n }}>\n {card.actor}\n </span>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {isActive && (\n <>\n <AudioLines size={12} color=\"#2E3236\" />\n <AudioLines size={12} color=\"#2E3236\" />\n </>\n )}\n <span style={{\n fontSize: 13, fontWeight: 400,\n lineHeight: 1.2,\n color: 'var(--Grey-Muted, #808183)',\n }}>\n {card.timeRange}\n </span>\n </div>\n </div>\n\n {/* Play/Pause icon + text */}\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8, width: '100%' }}>\n <button\n onClick={() => {\n if (isRealData && onTurnPlayPause) {\n onTurnPlayPause(card, i);\n } else {\n handleDemoTurnPlayPause(i);\n }\n }}\n style={{\n background: 'none', border: 'none',\n cursor: 'pointer', padding: 0,\n flexShrink: 0,\n display: 'flex',\n }}\n >\n {isActive ? (\n <PauseCircle size={17} color=\"#2E3236\" strokeWidth={1.5} />\n ) : (\n <PlayCircle size={17} color=\"#808183\" strokeWidth={1} />\n )}\n </button>\n <p style={{\n fontSize: 13, fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n margin: 0,\n flex: 1,\n }}>\n {card.text}\n </p>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </div>{/* end card */}\n </div>\n );\n});\n\nexport default UpdatedInteractionRecording;\n"],"names":["fmtTime","seconds","m","s","DEMO_SEGMENTS","DEMO_TRANSCRIPT","SPEED_OPTIONS","parseTimeStr","timeStr","parts","UpdatedInteractionRecording","forwardRef","audioUrl","timelineSegments","durationSeconds","externalCurrentTime","externalPlaying","externalRate","externalOnSeek","externalOnTogglePlay","externalOnSeekBack","externalOnSeekForward","externalOnSetPlaybackRate","externalAudioRef","agentName","customerName","transcript","highlightedTurns","activeTurnIndex","activeDemoIndex","turnObservations","setExpandedSignals","onTurnPlayPause","ref","scrollRef","useRef","internalAudioRef","animFrameRef","internalPlaying","setInternalPlaying","useState","internalCurrentTime","setInternalCurrentTime","internalDuration","setInternalDuration","internalRate","setInternalRate","demoSeekTime","setDemoSeekTime","demoRate","setDemoRate","demoPlaying","setDemoPlaying","showSpeedMenu","setShowSpeedMenu","activeDemoIdx","setActiveDemoIdx","parentManaged","isDemo","selfManaged","activePlaying","activeCurrentTime","activeRate","activeDuration","startTimeTracking","useCallback","tick","audio","stopTimeTracking","useEffect","onLoaded","onEnded","computeActiveIdx","timeSec","i","turnTime","handleSeek","timeSeconds","clamped","handleTogglePlay","prev","handleSeekBack","handleSeekForward","handleSetRate","rate","useImperativeHandle","idx","cards","_a","handleDemoTurnPlayPause","formatTimeRange","startMs","endMs","fmt","ms","minutes","turns","_b","obs","el","effectiveTime","effectiveDuration","progress","displayTime","jsxs","jsx","FileSignal","RotateCcw","Pause","Play","RotateCw","ChevronDown","speed","rect","clickX","pct","speaker","rowIdx","isAgent","speakerSegments","e","seg","card","isRealData","isActive","isCustomer","Fragment","AudioLines","PauseCircle","PlayCircle"],"mappings":"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"}
|