@waveform-playlist/annotations 5.1.0 → 5.2.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -308,11 +308,11 @@ var Label = import_styled_components2.default.span`
|
|
|
308
308
|
var ResizeHandle = import_styled_components2.default.div`
|
|
309
309
|
position: absolute;
|
|
310
310
|
top: 0;
|
|
311
|
-
${(props) => props.$position === "left" ? "left:
|
|
312
|
-
width:
|
|
311
|
+
${(props) => props.$position === "left" ? "left: 0" : "right: 0"};
|
|
312
|
+
width: 8px;
|
|
313
313
|
height: 100%;
|
|
314
314
|
cursor: ew-resize;
|
|
315
|
-
z-index: 120;
|
|
315
|
+
z-index: 120;
|
|
316
316
|
background: ${(props) => props.$isDragging ? props.theme?.annotationResizeHandleColor || "rgba(0, 0, 0, 0.2)" : "transparent"};
|
|
317
317
|
border-radius: 4px;
|
|
318
318
|
touch-action: none; /* Important for @dnd-kit on touch devices */
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/parsers/aeneas.ts","../src/components/Annotation.tsx","../src/components/AnnotationBox.tsx","../src/components/AnnotationBoxesWrapper.tsx","../src/components/AnnotationsTrack.tsx","../src/components/AnnotationText.tsx","../src/components/ContinuousPlayCheckbox.tsx","../src/components/LinkEndpointsCheckbox.tsx","../src/components/EditableCheckbox.tsx","../src/components/DownloadAnnotationsButton.tsx","../src/hooks/useAnnotationControls.ts"],"sourcesContent":["// Types\nexport type {\n Annotation as AnnotationType,\n AnnotationFormat,\n AnnotationListOptions,\n AnnotationEventMap\n} from './types';\n\n// Parsers\nexport { parseAeneas, serializeAeneas } from './parsers/aeneas';\nexport type { AeneasFragment } from './parsers/aeneas';\n\n// Components\nexport { Annotation } from './components/Annotation';\nexport type { AnnotationProps, AnnotationData, AnnotationAction, AnnotationActionOptions } from './components/Annotation';\n\nexport { AnnotationBox } from './components/AnnotationBox';\nexport type { AnnotationBoxComponentProps } from './components/AnnotationBox';\n\nexport { AnnotationBoxesWrapper } from './components/AnnotationBoxesWrapper';\nexport type { AnnotationBoxesWrapperProps } from './components/AnnotationBoxesWrapper';\n\nexport { AnnotationsTrack } from './components/AnnotationsTrack';\nexport type { AnnotationsTrackProps } from './components/AnnotationsTrack';\n\nexport { AnnotationText } from './components/AnnotationText';\nexport type { AnnotationTextProps, RenderAnnotationItemProps } from './components/AnnotationText';\n\nexport { ContinuousPlayCheckbox } from './components/ContinuousPlayCheckbox';\nexport type { ContinuousPlayCheckboxProps } from './components/ContinuousPlayCheckbox';\n\nexport { LinkEndpointsCheckbox } from './components/LinkEndpointsCheckbox';\nexport type { LinkEndpointsCheckboxProps } from './components/LinkEndpointsCheckbox';\n\nexport { EditableCheckbox } from './components/EditableCheckbox';\nexport type { EditableCheckboxProps } from './components/EditableCheckbox';\n\nexport { DownloadAnnotationsButton } from './components/DownloadAnnotationsButton';\nexport type { DownloadAnnotationsButtonProps } from './components/DownloadAnnotationsButton';\n\n// Hooks\nexport { useAnnotationControls } from './hooks/useAnnotationControls';\nexport type {\n UseAnnotationControlsOptions,\n UseAnnotationControlsReturn,\n AnnotationUpdateParams,\n} from './hooks/useAnnotationControls';\n","import { Annotation } from '../types';\n\nexport interface AeneasFragment {\n begin: string;\n end: string;\n id: string;\n language: string;\n lines: string[];\n}\n\nexport function parseAeneas(data: AeneasFragment): Annotation {\n return {\n id: data.id,\n start: parseFloat(data.begin),\n end: parseFloat(data.end),\n lines: data.lines,\n lang: data.language,\n };\n}\n\nexport function serializeAeneas(annotation: Annotation): AeneasFragment {\n return {\n id: annotation.id,\n begin: annotation.start.toFixed(3),\n end: annotation.end.toFixed(3),\n lines: annotation.lines,\n language: annotation.lang || 'en',\n };\n}\n","import React, { FunctionComponent, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface AnnotationOverlayProps {\n readonly $left: number;\n readonly $width: number;\n readonly $color: string;\n}\n\nconst AnnotationOverlay = styled.div.attrs<AnnotationOverlayProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<AnnotationOverlayProps>`\n position: absolute;\n top: 0;\n background: ${(props) => props.$color};\n height: 100%;\n z-index: 10;\n pointer-events: auto;\n opacity: 0.3;\n border: 2px solid ${(props) => props.$color};\n border-radius: 4px;\n cursor: pointer;\n\n &:hover {\n opacity: 0.5;\n border-color: ${(props) => props.$color};\n }\n`;\n\nconst AnnotationText = styled.div`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: none;\n white-space: pre-wrap;\n word-break: break-word;\n`;\n\nconst EditableText = styled.textarea`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.9);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: auto;\n border: 1px solid #fff;\n resize: none;\n font-family: inherit;\n\n &:focus {\n outline: none;\n border-color: #4CAF50;\n }\n`;\n\nconst ControlsBar = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n gap: 4px;\n padding: 4px;\n justify-content: flex-start;\n align-items: center;\n`;\n\nconst ControlButton = styled.button`\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.5);\n color: white;\n padding: 4px 8px;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n border-color: white;\n }\n\n &:active {\n background: rgba(255, 255, 255, 0.3);\n }\n`;\n\n/**\n * Configuration options passed to annotation action handlers\n */\nexport interface AnnotationActionOptions {\n /** Whether annotation endpoints are linked (moving one endpoint moves the other) */\n linkEndpoints?: boolean;\n /** Whether to continue playing after an annotation ends */\n continuousPlay?: boolean;\n /** Additional custom properties */\n [key: string]: unknown;\n}\n\nexport interface AnnotationAction {\n class?: string;\n text?: string;\n title: string;\n action: (annotation: AnnotationData, index: number, annotations: AnnotationData[], opts: AnnotationActionOptions) => void;\n}\n\nexport interface AnnotationData {\n id: string;\n start: number;\n end: number;\n lines: string[];\n language?: string;\n}\n\nexport interface AnnotationProps {\n annotation: AnnotationData;\n index: number;\n allAnnotations: AnnotationData[];\n startPosition: number; // Start position in pixels\n endPosition: number; // End position in pixels\n color?: string;\n editable?: boolean;\n controls?: AnnotationAction[];\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n annotationListConfig?: AnnotationActionOptions;\n onClick?: (annotation: AnnotationData) => void;\n}\n\nexport const Annotation: FunctionComponent<AnnotationProps> = ({\n annotation,\n index,\n allAnnotations,\n startPosition,\n endPosition,\n color = '#ff9800',\n editable = false,\n controls = [],\n onAnnotationUpdate,\n annotationListConfig,\n onClick,\n}) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editedText, setEditedText] = useState(annotation.lines.join('\\n'));\n const width = Math.max(0, endPosition - startPosition);\n\n if (width <= 0) {\n return null;\n }\n\n const handleClick = () => {\n if (onClick) {\n onClick(annotation);\n }\n };\n\n const handleDoubleClick = () => {\n if (editable) {\n setIsEditing(true);\n }\n };\n\n const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setEditedText(e.target.value);\n };\n\n const handleTextBlur = () => {\n setIsEditing(false);\n const newLines = editedText.split('\\n');\n if (newLines.join('\\n') !== annotation.lines.join('\\n')) {\n const updatedAnnotations = [...allAnnotations];\n updatedAnnotations[index] = { ...annotation, lines: newLines };\n if (onAnnotationUpdate) {\n onAnnotationUpdate(updatedAnnotations);\n }\n }\n };\n\n const handleControlClick = (control: AnnotationAction) => {\n const annotationsCopy = [...allAnnotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n if (onAnnotationUpdate) {\n onAnnotationUpdate(annotationsCopy);\n }\n };\n\n const getIconClass = (classString: string) => {\n // Convert \"fas.fa-minus\" to \"fas fa-minus\"\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <AnnotationOverlay\n $left={startPosition}\n $width={width}\n $color={color}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n >\n {controls.length > 0 && (\n <ControlsBar>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={(e) => {\n e.stopPropagation();\n handleControlClick(control);\n }}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </ControlsBar>\n )}\n {isEditing ? (\n <EditableText\n value={editedText}\n onChange={handleTextChange}\n onBlur={handleTextBlur}\n autoFocus\n onClick={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n />\n ) : (\n <AnnotationText>\n {annotation.lines.join('\\n')}\n </AnnotationText>\n )}\n </AnnotationOverlay>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { useDraggable } from '@dnd-kit/core';\nimport type { DraggableAttributes } from '@dnd-kit/core';\nimport type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';\n\ninterface WrapperProps {\n readonly $left: number;\n readonly $width: number;\n}\n\n// Wrapper positions the annotation and contains both Box and ResizeHandles as siblings\nconst Wrapper = styled.div.attrs<WrapperProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<WrapperProps>`\n position: absolute;\n top: 0;\n height: 100%;\n pointer-events: none; /* Let events pass through to children */\n`;\n\ninterface BoxProps {\n readonly $color: string;\n readonly $isActive?: boolean;\n}\n\nconst Box = styled.div<BoxProps>`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 100%;\n background: ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBackground || 'rgba(255, 200, 100, 0.95)')\n : (props.theme?.annotationBoxBackground || 'rgba(255, 255, 255, 0.85)')};\n border: ${(props) => props.$isActive ? '3px' : '2px'} solid ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBorder || '#ff9800')\n : props.$color};\n border-radius: 4px;\n cursor: pointer;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: ${(props) => props.$isActive\n ? '0 2px 8px rgba(255, 152, 0, 0.4), inset 0 0 0 1px rgba(255, 152, 0, 0.2)'\n : '0 1px 3px rgba(0, 0, 0, 0.1)'};\n\n &:hover {\n background: ${(props) => props.theme?.annotationBoxHoverBackground || 'rgba(255, 255, 255, 0.98)'};\n border-color: ${(props) => props.theme?.annotationBoxActiveBorder || '#ff9800'};\n border-width: 3px;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);\n }\n`;\n\nconst Label = styled.span`\n font-size: 12px;\n font-weight: 600;\n color: ${(props) => props.theme?.annotationLabelColor || '#2a2a2a'};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0 6px;\n letter-spacing: 0.3px;\n user-select: none;\n`;\n\ninterface ResizeHandleStyledProps {\n $position: 'left' | 'right';\n $isDragging?: boolean;\n}\n\n// ResizeHandles are now siblings of Box, positioned relative to Wrapper\n// Reduced from 30px/-15px to 16px/-8px to minimize overlap between adjacent annotations\nconst ResizeHandle = styled.div<ResizeHandleStyledProps>`\n position: absolute;\n top: 0;\n ${(props) => props.$position === 'left' ? 'left: -8px' : 'right: -8px'};\n width: 16px;\n height: 100%;\n cursor: ew-resize;\n z-index: 120; /* Above ClickOverlay (z-index: 100) and AnnotationBoxesWrapper (z-index: 110) */\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.2)')\n : 'transparent'};\n border-radius: 4px;\n touch-action: none; /* Important for @dnd-kit on touch devices */\n pointer-events: auto;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 4px;\n height: 60%;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.8)')\n : (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.4)')};\n border-radius: 2px;\n opacity: ${(props) => props.$isDragging ? 1 : 0.6};\n transition: opacity 0.2s, background 0.2s;\n }\n\n &:hover {\n background: ${(props) => props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.1)'};\n }\n\n &:hover::before {\n opacity: 1;\n background: ${(props) => props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.7)'};\n }\n`;\n\nexport interface DragHandleProps {\n attributes: DraggableAttributes;\n listeners: SyntheticListenerMap | undefined;\n setActivatorNodeRef: (element: HTMLElement | null) => void;\n isDragging: boolean;\n}\n\nexport interface AnnotationBoxComponentProps {\n annotationId: string;\n annotationIndex: number;\n startPosition: number;\n endPosition: number;\n label?: string;\n color?: string;\n isActive?: boolean;\n onClick?: () => void;\n editable?: boolean; // Whether to show drag handles\n}\n\nexport const AnnotationBox: FunctionComponent<AnnotationBoxComponentProps> = ({\n annotationId,\n annotationIndex,\n startPosition,\n endPosition,\n label,\n color = '#ff9800',\n isActive = false,\n onClick,\n editable = true,\n}) => {\n const width = Math.max(0, endPosition - startPosition);\n\n // Left (start) boundary draggable\n const leftBoundaryId = `annotation-boundary-start-${annotationIndex}`;\n const {\n attributes: leftAttributes,\n listeners: leftListeners,\n setActivatorNodeRef: setLeftActivatorRef,\n isDragging: isLeftDragging,\n } = useDraggable({\n id: leftBoundaryId,\n data: { annotationId, annotationIndex, edge: 'start' as const },\n disabled: !editable,\n });\n\n // Right (end) boundary draggable\n const rightBoundaryId = `annotation-boundary-end-${annotationIndex}`;\n const {\n attributes: rightAttributes,\n listeners: rightListeners,\n setActivatorNodeRef: setRightActivatorRef,\n isDragging: isRightDragging,\n } = useDraggable({\n id: rightBoundaryId,\n data: { annotationId, annotationIndex, edge: 'end' as const },\n disabled: !editable,\n });\n\n if (width <= 0) {\n return null;\n }\n\n // Wrap @dnd-kit pointer handlers to also stop propagation\n // This prevents the ClickOverlay from capturing the event\n const createPointerDownHandler = (dndKitHandler?: (e: React.PointerEvent) => void) => {\n return (e: React.PointerEvent) => {\n e.stopPropagation();\n dndKitHandler?.(e);\n };\n };\n\n const handleHandleClick = (e: React.MouseEvent) => {\n // Prevent clicks on resize handles from bubbling to annotation box\n e.stopPropagation();\n };\n\n return (\n <Wrapper $left={startPosition} $width={width}>\n <Box\n $color={color}\n $isActive={isActive}\n onClick={onClick}\n >\n {label && <Label>{label}</Label>}\n </Box>\n {editable && (\n <ResizeHandle\n ref={setLeftActivatorRef}\n $position=\"left\"\n $isDragging={isLeftDragging}\n onClick={handleHandleClick}\n {...leftListeners}\n onPointerDown={createPointerDownHandler(leftListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...leftAttributes}\n />\n )}\n {editable && (\n <ResizeHandle\n ref={setRightActivatorRef}\n $position=\"right\"\n $isDragging={isRightDragging}\n onClick={handleHandleClick}\n {...rightListeners}\n onPointerDown={createPointerDownHandler(rightListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...rightAttributes}\n />\n )}\n </Wrapper>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n z-index: 110;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n`;\n\nconst BoxesContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationBoxesWrapperProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationBoxesWrapper: FunctionComponent<AnnotationBoxesWrapperProps> = ({\n children,\n className,\n height = 30,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0} />\n <BoxesContainer $offset={offset}>\n {children}\n </BoxesContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n font-weight: bold;\n`;\n\nconst AnnotationsContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationsTrackProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationsTrack: FunctionComponent<AnnotationsTrackProps> = ({\n children,\n className,\n height = 100,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0}>\n Annotations\n </ControlsPlaceholder>\n <AnnotationsContainer $offset={offset}>\n {children}\n </AnnotationsContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent, useRef, useEffect } from 'react';\nimport styled from 'styled-components';\nimport type { AnnotationData, AnnotationAction, AnnotationActionOptions } from './Annotation';\n\ninterface ContainerProps {\n $height?: number;\n}\n\nconst Container = styled.div<ContainerProps>`\n background: ${(props) => props.theme?.backgroundColor || '#fff'};\n ${(props) => props.$height ? `height: ${props.$height}px;` : 'max-height: 200px;'}\n overflow-y: auto;\n padding: 8px;\n`;\n\nconst AnnotationItem = styled.div<{ $isActive?: boolean }>`\n padding: 12px;\n margin-bottom: 6px;\n border-left: 4px solid ${(props) => (props.$isActive ? '#ff9800' : 'transparent')};\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.15)' : 'transparent')};\n border-radius: 4px;\n transition: all 0.2s;\n cursor: pointer;\n box-shadow: ${(props) => (props.$isActive ? '0 2px 8px rgba(255, 152, 0, 0.25), inset 0 0 0 1px rgba(255, 152, 0, 0.3)' : 'none')};\n\n &:hover {\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.2)' : props.theme?.annotationTextItemHoverBackground || 'rgba(0, 0, 0, 0.05)')};\n border-left-color: ${(props) => (props.$isActive ? '#ff9800' : props.theme?.borderColor || '#ddd')};\n }\n\n &:focus-visible {\n outline: 2px solid #ff9800;\n outline-offset: 2px;\n }\n`;\n\nconst AnnotationHeader = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n`;\n\nconst AnnotationInfo = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n`;\n\nconst AnnotationIdLabel = styled.span<{ $isEditable?: boolean }>`\n font-size: 11px;\n font-weight: 600;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n background: transparent;\n padding: 2px 6px;\n border-radius: 3px;\n min-width: 20px;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\nconst TimeRange = styled.span`\n font-size: 12px;\n font-weight: 500;\n color: ${(props) => props.theme?.textColorMuted || '#555'};\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n letter-spacing: 0.5px;\n`;\n\nconst AnnotationControls = styled.div`\n display: flex;\n gap: 6px;\n`;\n\nconst ControlButton = styled.button`\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n color: ${(props) => props.theme?.textColor || '#333'};\n padding: 4px 8px;\n font-size: 14px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n\n &:hover {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n transform: scale(1.05);\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst AnnotationTextContent = styled.div<{ $isEditable?: boolean }>`\n font-size: 14px;\n line-height: 1.6;\n color: ${(props) => props.theme?.textColor || '#2a2a2a'};\n white-space: pre-wrap;\n word-break: break-word;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n padding: ${(props) => (props.$isEditable ? '6px' : '0')};\n border-radius: 3px;\n min-height: 20px;\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\n/**\n * Props passed to the renderAnnotationItem function for custom rendering\n */\nexport interface RenderAnnotationItemProps {\n annotation: AnnotationData;\n index: number;\n isActive: boolean;\n onClick: () => void;\n formatTime: (seconds: number) => string;\n}\n\nexport interface AnnotationTextProps {\n annotations: AnnotationData[];\n activeAnnotationId?: string;\n shouldScrollToActive?: boolean;\n /** Where to position the active annotation when scrolling: 'center', 'start', 'end', or 'nearest'. Defaults to 'center'. */\n scrollActivePosition?: ScrollLogicalPosition;\n /** Which scrollable containers to scroll: 'nearest' (only the annotation list) or 'all' (including viewport). Defaults to 'nearest'. */\n scrollActiveContainer?: 'nearest' | 'all';\n editable?: boolean;\n controls?: AnnotationAction[];\n annotationListConfig?: AnnotationActionOptions;\n height?: number;\n onAnnotationClick?: (annotation: AnnotationData) => void;\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n /**\n * Custom render function for annotation items.\n * When provided, completely replaces the default annotation item rendering.\n * Use this to customize the appearance of each annotation in the list.\n */\n renderAnnotationItem?: (props: RenderAnnotationItemProps) => React.ReactNode;\n}\n\nconst AnnotationTextComponent: FunctionComponent<AnnotationTextProps> = ({\n annotations,\n activeAnnotationId,\n shouldScrollToActive = false,\n scrollActivePosition = 'center',\n scrollActiveContainer = 'nearest',\n editable = false,\n controls = [],\n annotationListConfig,\n height,\n onAnnotationClick,\n onAnnotationUpdate,\n renderAnnotationItem,\n}) => {\n const activeAnnotationRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const prevActiveIdRef = useRef<string | undefined>(undefined);\n\n // Track component renders and scroll position\n useEffect(() => {\n // Render tracking removed\n });\n\n // Track scroll changes\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n // Scroll tracking removed\n };\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, []);\n\n // Auto-scroll to active annotation when it changes\n useEffect(() => {\n // Only scroll if parent says we should (prevents scrolling on remount after pause)\n if (activeAnnotationId && activeAnnotationRef.current && shouldScrollToActive) {\n activeAnnotationRef.current.scrollIntoView({\n behavior: 'smooth',\n block: scrollActivePosition,\n container: scrollActiveContainer,\n } as ScrollIntoViewOptions);\n }\n\n prevActiveIdRef.current = activeAnnotationId;\n }, [activeAnnotationId, shouldScrollToActive, scrollActivePosition, scrollActiveContainer]);\n\n const formatTime = (seconds: number): string => {\n if (isNaN(seconds) || !isFinite(seconds)) {\n return '0:00.000';\n }\n const mins = Math.floor(seconds / 60);\n const secs = (seconds % 60).toFixed(3);\n return `${mins}:${secs.padStart(6, '0')}`;\n };\n\n const handleTextEdit = (index: number, newText: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n lines: newText.split('\\n'),\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleIdEdit = (index: number, newId: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const trimmedId = newId.trim();\n if (!trimmedId) return; // Don't allow empty IDs\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n id: trimmedId,\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleControlClick = (control: AnnotationAction, annotation: AnnotationData, index: number) => {\n if (!onAnnotationUpdate) return;\n\n const annotationsCopy = [...annotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n onAnnotationUpdate(annotationsCopy);\n };\n\n const getIconClass = (classString: string) => {\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <Container ref={containerRef} $height={height}>\n {annotations.map((annotation, index) => {\n const isActive = annotation.id === activeAnnotationId;\n const handleClick = () => onAnnotationClick?.(annotation);\n\n // Use custom render function if provided\n if (renderAnnotationItem) {\n return (\n <div\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n >\n {renderAnnotationItem({\n annotation,\n index,\n isActive,\n onClick: handleClick,\n formatTime,\n })}\n </div>\n );\n }\n\n // Default rendering\n return (\n <AnnotationItem\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n $isActive={isActive}\n onClick={handleClick}\n >\n <AnnotationHeader>\n <AnnotationInfo>\n <AnnotationIdLabel\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleIdEdit(index, e.currentTarget.textContent || '')}\n >\n {annotation.id}\n </AnnotationIdLabel>\n <TimeRange>\n {formatTime(annotation.start)} - {formatTime(annotation.end)}\n </TimeRange>\n </AnnotationInfo>\n {controls.length > 0 && (\n <AnnotationControls onClick={(e) => e.stopPropagation()}>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={() => handleControlClick(control, annotation, index)}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </AnnotationControls>\n )}\n </AnnotationHeader>\n <AnnotationTextContent\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleTextEdit(index, e.currentTarget.textContent || '')}\n >\n {annotation.lines.join('\\n')}\n </AnnotationTextContent>\n </AnnotationItem>\n );\n })}\n </Container>\n );\n};\n\n// Memoize to prevent unnecessary remounting when parent re-renders\nexport const AnnotationText = React.memo(AnnotationTextComponent);\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface ContinuousPlayCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling continuous play of annotations.\n * When enabled, playback continues from one annotation to the next without stopping.\n */\nexport const ContinuousPlayCheckbox: React.FC<ContinuousPlayCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"continuous-play\"\n className=\"continuous-play\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"continuous-play\">Continuous Play</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface LinkEndpointsCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling linked endpoints between annotations.\n * When enabled, the end time of one annotation is automatically linked to the start time of the next.\n */\nexport const LinkEndpointsCheckbox: React.FC<LinkEndpointsCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"link-endpoints\"\n className=\"link-endpoints\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"link-endpoints\">Link Endpoints</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface EditableCheckboxProps {\n checked: boolean;\n onChange: (enabled: boolean) => void;\n className?: string;\n}\n\nexport const EditableCheckbox: React.FC<EditableCheckboxProps> = ({\n checked,\n onChange,\n className,\n}) => {\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"editable-annotations\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n />\n <BaseCheckboxLabel htmlFor=\"editable-annotations\">Editable Annotations</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport styled from 'styled-components';\nimport { serializeAeneas } from '../parsers/aeneas';\nimport type { Annotation } from '../types';\n\nconst StyledButton = styled.button`\n padding: 0.5rem 1rem;\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n color: ${(props) => props.theme?.textColor || '#333'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n border-radius: ${(props) => props.theme?.borderRadius || '4px'};\n cursor: pointer;\n font-family: ${(props) => props.theme?.fontFamily || 'inherit'};\n font-size: ${(props) => props.theme?.fontSize || '14px'};\n font-weight: 500;\n transition: all 0.15s ease;\n\n &:hover:not(:disabled) {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 2px ${(props) => props.theme?.inputFocusBorder || '#007bff'}44;\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n`;\n\nexport interface DownloadAnnotationsButtonProps {\n annotations: Annotation[];\n filename?: string;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport const DownloadAnnotationsButton: React.FC<DownloadAnnotationsButtonProps> = ({\n annotations,\n filename = 'annotations.json',\n disabled = false,\n className,\n children = 'Download JSON',\n}) => {\n const handleDownload = () => {\n if (annotations.length === 0) {\n return;\n }\n\n // Serialize annotations to Aeneas JSON format\n const jsonData = annotations.map(annotation => serializeAeneas(annotation));\n const jsonString = JSON.stringify(jsonData, null, 2);\n\n // Create a blob and download link\n const blob = new Blob([jsonString], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n\n // Trigger download\n document.body.appendChild(link);\n link.click();\n\n // Cleanup\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n };\n\n return (\n <StyledButton\n onClick={handleDownload}\n disabled={disabled || annotations.length === 0}\n className={className}\n title={annotations.length === 0 ? 'No annotations to download' : 'Download the annotations as JSON'}\n >\n {children}\n </StyledButton>\n );\n};\n","import { useState, useCallback } from 'react';\nimport type { Annotation, AnnotationListOptions } from '../types';\n\nconst LINK_THRESHOLD = 0.01; // Consider edges \"linked\" if within 10ms\n\nexport interface UseAnnotationControlsOptions {\n initialContinuousPlay?: boolean;\n initialLinkEndpoints?: boolean;\n}\n\nexport interface AnnotationUpdateParams {\n annotationIndex: number;\n newTime: number;\n isDraggingStart: boolean;\n annotations: Annotation[];\n duration: number;\n linkEndpoints: boolean;\n}\n\nexport interface UseAnnotationControlsReturn {\n continuousPlay: boolean;\n linkEndpoints: boolean;\n setContinuousPlay: (value: boolean) => void;\n setLinkEndpoints: (value: boolean) => void;\n updateAnnotationBoundaries: (params: AnnotationUpdateParams) => Annotation[];\n}\n\n/**\n * Hook for managing annotation control state and boundary logic.\n * Handles continuous play mode and linked endpoints behavior.\n */\nexport const useAnnotationControls = (\n options: UseAnnotationControlsOptions = {}\n): UseAnnotationControlsReturn => {\n const {\n initialContinuousPlay = false,\n initialLinkEndpoints = true,\n } = options;\n\n const [continuousPlay, setContinuousPlay] = useState(initialContinuousPlay);\n const [linkEndpoints, setLinkEndpoints] = useState(initialLinkEndpoints);\n\n /**\n * Updates annotation boundaries based on drag operations.\n * Handles linked endpoints and collision detection.\n * Note: linkEndpoints is passed as a parameter to ensure it uses the current value from context.\n */\n const updateAnnotationBoundaries = useCallback(\n ({\n annotationIndex,\n newTime,\n isDraggingStart,\n annotations,\n duration,\n linkEndpoints: shouldLinkEndpoints,\n }: AnnotationUpdateParams): Annotation[] => {\n const updatedAnnotations = [...annotations];\n const annotation = annotations[annotationIndex];\n\n if (isDraggingStart) {\n // Dragging start edge\n const constrainedStart = Math.min(annotation.end - 0.1, Math.max(0, newTime));\n const delta = constrainedStart - annotation.start;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n start: constrainedStart,\n };\n\n if (shouldLinkEndpoints && annotationIndex > 0) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const prevAnnotation = updatedAnnotations[annotationIndex - 1];\n\n if (Math.abs(prevAnnotation.end - annotation.start) < LINK_THRESHOLD) {\n // Already linked: move previous annotation's end together with this start\n updatedAnnotations[annotationIndex - 1] = {\n ...prevAnnotation,\n end: Math.max(prevAnnotation.start + 0.1, prevAnnotation.end + delta),\n };\n } else if (constrainedStart <= prevAnnotation.end) {\n // Dragged past previous annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n start: prevAnnotation.end,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex > 0 && constrainedStart < updatedAnnotations[annotationIndex - 1].end) {\n // Collision detection: push previous annotation's end back\n updatedAnnotations[annotationIndex - 1] = {\n ...updatedAnnotations[annotationIndex - 1],\n end: constrainedStart,\n };\n }\n } else {\n // Dragging end edge\n const constrainedEnd = Math.max(annotation.start + 0.1, Math.min(newTime, duration));\n const delta = constrainedEnd - annotation.end;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n end: constrainedEnd,\n };\n\n if (shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n if (Math.abs(nextAnnotation.start - annotation.end) < LINK_THRESHOLD) {\n // Already linked: move next annotation's start together with this end\n const newStart = nextAnnotation.start + delta;\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: Math.min(nextAnnotation.end - 0.1, newStart),\n };\n\n // Cascade linked endpoints\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (Math.abs(next.start - current.end) < LINK_THRESHOLD) {\n const nextDelta = current.end - annotations[currentIndex].end;\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: Math.min(next.end - 0.1, next.start + nextDelta),\n };\n currentIndex++;\n } else {\n break; // No more linked endpoints\n }\n }\n } else if (constrainedEnd >= nextAnnotation.start) {\n // Dragged past next annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n end: nextAnnotation.start,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1 && constrainedEnd > updatedAnnotations[annotationIndex + 1].start) {\n // Collision detection: push next annotation's start forward\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: constrainedEnd,\n };\n\n // Cascade collisions\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (current.end > next.start) {\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: current.end,\n };\n currentIndex++;\n } else {\n break; // No more collisions\n }\n }\n }\n }\n\n return updatedAnnotations;\n },\n []\n );\n\n return {\n continuousPlay,\n linkEndpoints,\n setContinuousPlay,\n setLinkEndpoints,\n updateAnnotationBoundaries,\n };\n};\n"],"mappings":"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","names":["AnnotationText","styled","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_ui_components","import_jsx_runtime","Container","styled","ControlsPlaceholder","import_react","import_styled_components","import_jsx_runtime","Container","styled","ControlButton","AnnotationText","React","import_ui_components","import_jsx_runtime","import_ui_components","import_jsx_runtime","import_ui_components","import_jsx_runtime","import_styled_components","import_jsx_runtime","styled","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/parsers/aeneas.ts","../src/components/Annotation.tsx","../src/components/AnnotationBox.tsx","../src/components/AnnotationBoxesWrapper.tsx","../src/components/AnnotationsTrack.tsx","../src/components/AnnotationText.tsx","../src/components/ContinuousPlayCheckbox.tsx","../src/components/LinkEndpointsCheckbox.tsx","../src/components/EditableCheckbox.tsx","../src/components/DownloadAnnotationsButton.tsx","../src/hooks/useAnnotationControls.ts"],"sourcesContent":["// Types\nexport type {\n Annotation as AnnotationType,\n AnnotationFormat,\n AnnotationListOptions,\n AnnotationEventMap\n} from './types';\n\n// Parsers\nexport { parseAeneas, serializeAeneas } from './parsers/aeneas';\nexport type { AeneasFragment } from './parsers/aeneas';\n\n// Components\nexport { Annotation } from './components/Annotation';\nexport type { AnnotationProps, AnnotationData, AnnotationAction, AnnotationActionOptions } from './components/Annotation';\n\nexport { AnnotationBox } from './components/AnnotationBox';\nexport type { AnnotationBoxComponentProps } from './components/AnnotationBox';\n\nexport { AnnotationBoxesWrapper } from './components/AnnotationBoxesWrapper';\nexport type { AnnotationBoxesWrapperProps } from './components/AnnotationBoxesWrapper';\n\nexport { AnnotationsTrack } from './components/AnnotationsTrack';\nexport type { AnnotationsTrackProps } from './components/AnnotationsTrack';\n\nexport { AnnotationText } from './components/AnnotationText';\nexport type { AnnotationTextProps, RenderAnnotationItemProps } from './components/AnnotationText';\n\nexport { ContinuousPlayCheckbox } from './components/ContinuousPlayCheckbox';\nexport type { ContinuousPlayCheckboxProps } from './components/ContinuousPlayCheckbox';\n\nexport { LinkEndpointsCheckbox } from './components/LinkEndpointsCheckbox';\nexport type { LinkEndpointsCheckboxProps } from './components/LinkEndpointsCheckbox';\n\nexport { EditableCheckbox } from './components/EditableCheckbox';\nexport type { EditableCheckboxProps } from './components/EditableCheckbox';\n\nexport { DownloadAnnotationsButton } from './components/DownloadAnnotationsButton';\nexport type { DownloadAnnotationsButtonProps } from './components/DownloadAnnotationsButton';\n\n// Hooks\nexport { useAnnotationControls } from './hooks/useAnnotationControls';\nexport type {\n UseAnnotationControlsOptions,\n UseAnnotationControlsReturn,\n AnnotationUpdateParams,\n} from './hooks/useAnnotationControls';\n","import { Annotation } from '../types';\n\nexport interface AeneasFragment {\n begin: string;\n end: string;\n id: string;\n language: string;\n lines: string[];\n}\n\nexport function parseAeneas(data: AeneasFragment): Annotation {\n return {\n id: data.id,\n start: parseFloat(data.begin),\n end: parseFloat(data.end),\n lines: data.lines,\n lang: data.language,\n };\n}\n\nexport function serializeAeneas(annotation: Annotation): AeneasFragment {\n return {\n id: annotation.id,\n begin: annotation.start.toFixed(3),\n end: annotation.end.toFixed(3),\n lines: annotation.lines,\n language: annotation.lang || 'en',\n };\n}\n","import React, { FunctionComponent, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface AnnotationOverlayProps {\n readonly $left: number;\n readonly $width: number;\n readonly $color: string;\n}\n\nconst AnnotationOverlay = styled.div.attrs<AnnotationOverlayProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<AnnotationOverlayProps>`\n position: absolute;\n top: 0;\n background: ${(props) => props.$color};\n height: 100%;\n z-index: 10;\n pointer-events: auto;\n opacity: 0.3;\n border: 2px solid ${(props) => props.$color};\n border-radius: 4px;\n cursor: pointer;\n\n &:hover {\n opacity: 0.5;\n border-color: ${(props) => props.$color};\n }\n`;\n\nconst AnnotationText = styled.div`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: none;\n white-space: pre-wrap;\n word-break: break-word;\n`;\n\nconst EditableText = styled.textarea`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.9);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: auto;\n border: 1px solid #fff;\n resize: none;\n font-family: inherit;\n\n &:focus {\n outline: none;\n border-color: #4CAF50;\n }\n`;\n\nconst ControlsBar = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n gap: 4px;\n padding: 4px;\n justify-content: flex-start;\n align-items: center;\n`;\n\nconst ControlButton = styled.button`\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.5);\n color: white;\n padding: 4px 8px;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n border-color: white;\n }\n\n &:active {\n background: rgba(255, 255, 255, 0.3);\n }\n`;\n\n/**\n * Configuration options passed to annotation action handlers\n */\nexport interface AnnotationActionOptions {\n /** Whether annotation endpoints are linked (moving one endpoint moves the other) */\n linkEndpoints?: boolean;\n /** Whether to continue playing after an annotation ends */\n continuousPlay?: boolean;\n /** Additional custom properties */\n [key: string]: unknown;\n}\n\nexport interface AnnotationAction {\n class?: string;\n text?: string;\n title: string;\n action: (annotation: AnnotationData, index: number, annotations: AnnotationData[], opts: AnnotationActionOptions) => void;\n}\n\nexport interface AnnotationData {\n id: string;\n start: number;\n end: number;\n lines: string[];\n language?: string;\n}\n\nexport interface AnnotationProps {\n annotation: AnnotationData;\n index: number;\n allAnnotations: AnnotationData[];\n startPosition: number; // Start position in pixels\n endPosition: number; // End position in pixels\n color?: string;\n editable?: boolean;\n controls?: AnnotationAction[];\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n annotationListConfig?: AnnotationActionOptions;\n onClick?: (annotation: AnnotationData) => void;\n}\n\nexport const Annotation: FunctionComponent<AnnotationProps> = ({\n annotation,\n index,\n allAnnotations,\n startPosition,\n endPosition,\n color = '#ff9800',\n editable = false,\n controls = [],\n onAnnotationUpdate,\n annotationListConfig,\n onClick,\n}) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editedText, setEditedText] = useState(annotation.lines.join('\\n'));\n const width = Math.max(0, endPosition - startPosition);\n\n if (width <= 0) {\n return null;\n }\n\n const handleClick = () => {\n if (onClick) {\n onClick(annotation);\n }\n };\n\n const handleDoubleClick = () => {\n if (editable) {\n setIsEditing(true);\n }\n };\n\n const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setEditedText(e.target.value);\n };\n\n const handleTextBlur = () => {\n setIsEditing(false);\n const newLines = editedText.split('\\n');\n if (newLines.join('\\n') !== annotation.lines.join('\\n')) {\n const updatedAnnotations = [...allAnnotations];\n updatedAnnotations[index] = { ...annotation, lines: newLines };\n if (onAnnotationUpdate) {\n onAnnotationUpdate(updatedAnnotations);\n }\n }\n };\n\n const handleControlClick = (control: AnnotationAction) => {\n const annotationsCopy = [...allAnnotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n if (onAnnotationUpdate) {\n onAnnotationUpdate(annotationsCopy);\n }\n };\n\n const getIconClass = (classString: string) => {\n // Convert \"fas.fa-minus\" to \"fas fa-minus\"\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <AnnotationOverlay\n $left={startPosition}\n $width={width}\n $color={color}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n >\n {controls.length > 0 && (\n <ControlsBar>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={(e) => {\n e.stopPropagation();\n handleControlClick(control);\n }}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </ControlsBar>\n )}\n {isEditing ? (\n <EditableText\n value={editedText}\n onChange={handleTextChange}\n onBlur={handleTextBlur}\n autoFocus\n onClick={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n />\n ) : (\n <AnnotationText>\n {annotation.lines.join('\\n')}\n </AnnotationText>\n )}\n </AnnotationOverlay>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { useDraggable } from '@dnd-kit/core';\nimport type { DraggableAttributes } from '@dnd-kit/core';\nimport type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';\n\ninterface WrapperProps {\n readonly $left: number;\n readonly $width: number;\n}\n\n// Wrapper positions the annotation and contains both Box and ResizeHandles as siblings\nconst Wrapper = styled.div.attrs<WrapperProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<WrapperProps>`\n position: absolute;\n top: 0;\n height: 100%;\n pointer-events: none; /* Let events pass through to children */\n`;\n\ninterface BoxProps {\n readonly $color: string;\n readonly $isActive?: boolean;\n}\n\nconst Box = styled.div<BoxProps>`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 100%;\n background: ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBackground || 'rgba(255, 200, 100, 0.95)')\n : (props.theme?.annotationBoxBackground || 'rgba(255, 255, 255, 0.85)')};\n border: ${(props) => props.$isActive ? '3px' : '2px'} solid ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBorder || '#ff9800')\n : props.$color};\n border-radius: 4px;\n cursor: pointer;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: ${(props) => props.$isActive\n ? '0 2px 8px rgba(255, 152, 0, 0.4), inset 0 0 0 1px rgba(255, 152, 0, 0.2)'\n : '0 1px 3px rgba(0, 0, 0, 0.1)'};\n\n &:hover {\n background: ${(props) => props.theme?.annotationBoxHoverBackground || 'rgba(255, 255, 255, 0.98)'};\n border-color: ${(props) => props.theme?.annotationBoxActiveBorder || '#ff9800'};\n border-width: 3px;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);\n }\n`;\n\nconst Label = styled.span`\n font-size: 12px;\n font-weight: 600;\n color: ${(props) => props.theme?.annotationLabelColor || '#2a2a2a'};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0 6px;\n letter-spacing: 0.3px;\n user-select: none;\n`;\n\ninterface ResizeHandleStyledProps {\n $position: 'left' | 'right';\n $isDragging?: boolean;\n}\n\n// ResizeHandles sit inside their annotation's bounds so adjacent annotations'\n// handles never overlap — each handle is independently grabbable.\nconst ResizeHandle = styled.div<ResizeHandleStyledProps>`\n position: absolute;\n top: 0;\n ${(props) => props.$position === 'left' ? 'left: 0' : 'right: 0'};\n width: 8px;\n height: 100%;\n cursor: ew-resize;\n z-index: 120;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.2)')\n : 'transparent'};\n border-radius: 4px;\n touch-action: none; /* Important for @dnd-kit on touch devices */\n pointer-events: auto;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 4px;\n height: 60%;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.8)')\n : (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.4)')};\n border-radius: 2px;\n opacity: ${(props) => props.$isDragging ? 1 : 0.6};\n transition: opacity 0.2s, background 0.2s;\n }\n\n &:hover {\n background: ${(props) => props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.1)'};\n }\n\n &:hover::before {\n opacity: 1;\n background: ${(props) => props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.7)'};\n }\n`;\n\nexport interface DragHandleProps {\n attributes: DraggableAttributes;\n listeners: SyntheticListenerMap | undefined;\n setActivatorNodeRef: (element: HTMLElement | null) => void;\n isDragging: boolean;\n}\n\nexport interface AnnotationBoxComponentProps {\n annotationId: string;\n annotationIndex: number;\n startPosition: number;\n endPosition: number;\n label?: string;\n color?: string;\n isActive?: boolean;\n onClick?: () => void;\n editable?: boolean; // Whether to show drag handles\n}\n\nexport const AnnotationBox: FunctionComponent<AnnotationBoxComponentProps> = ({\n annotationId,\n annotationIndex,\n startPosition,\n endPosition,\n label,\n color = '#ff9800',\n isActive = false,\n onClick,\n editable = true,\n}) => {\n const width = Math.max(0, endPosition - startPosition);\n\n // Left (start) boundary draggable\n const leftBoundaryId = `annotation-boundary-start-${annotationIndex}`;\n const {\n attributes: leftAttributes,\n listeners: leftListeners,\n setActivatorNodeRef: setLeftActivatorRef,\n isDragging: isLeftDragging,\n } = useDraggable({\n id: leftBoundaryId,\n data: { annotationId, annotationIndex, edge: 'start' as const },\n disabled: !editable,\n });\n\n // Right (end) boundary draggable\n const rightBoundaryId = `annotation-boundary-end-${annotationIndex}`;\n const {\n attributes: rightAttributes,\n listeners: rightListeners,\n setActivatorNodeRef: setRightActivatorRef,\n isDragging: isRightDragging,\n } = useDraggable({\n id: rightBoundaryId,\n data: { annotationId, annotationIndex, edge: 'end' as const },\n disabled: !editable,\n });\n\n if (width <= 0) {\n return null;\n }\n\n // Wrap @dnd-kit pointer handlers to also stop propagation\n // This prevents the ClickOverlay from capturing the event\n const createPointerDownHandler = (dndKitHandler?: (e: React.PointerEvent) => void) => {\n return (e: React.PointerEvent) => {\n e.stopPropagation();\n dndKitHandler?.(e);\n };\n };\n\n const handleHandleClick = (e: React.MouseEvent) => {\n // Prevent clicks on resize handles from bubbling to annotation box\n e.stopPropagation();\n };\n\n return (\n <Wrapper $left={startPosition} $width={width}>\n <Box\n $color={color}\n $isActive={isActive}\n onClick={onClick}\n >\n {label && <Label>{label}</Label>}\n </Box>\n {editable && (\n <ResizeHandle\n ref={setLeftActivatorRef}\n $position=\"left\"\n $isDragging={isLeftDragging}\n onClick={handleHandleClick}\n {...leftListeners}\n onPointerDown={createPointerDownHandler(leftListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...leftAttributes}\n />\n )}\n {editable && (\n <ResizeHandle\n ref={setRightActivatorRef}\n $position=\"right\"\n $isDragging={isRightDragging}\n onClick={handleHandleClick}\n {...rightListeners}\n onPointerDown={createPointerDownHandler(rightListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...rightAttributes}\n />\n )}\n </Wrapper>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n z-index: 110;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n`;\n\nconst BoxesContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationBoxesWrapperProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationBoxesWrapper: FunctionComponent<AnnotationBoxesWrapperProps> = ({\n children,\n className,\n height = 30,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0} />\n <BoxesContainer $offset={offset}>\n {children}\n </BoxesContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n font-weight: bold;\n`;\n\nconst AnnotationsContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationsTrackProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationsTrack: FunctionComponent<AnnotationsTrackProps> = ({\n children,\n className,\n height = 100,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0}>\n Annotations\n </ControlsPlaceholder>\n <AnnotationsContainer $offset={offset}>\n {children}\n </AnnotationsContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent, useRef, useEffect } from 'react';\nimport styled from 'styled-components';\nimport type { AnnotationData, AnnotationAction, AnnotationActionOptions } from './Annotation';\n\ninterface ContainerProps {\n $height?: number;\n}\n\nconst Container = styled.div<ContainerProps>`\n background: ${(props) => props.theme?.backgroundColor || '#fff'};\n ${(props) => props.$height ? `height: ${props.$height}px;` : 'max-height: 200px;'}\n overflow-y: auto;\n padding: 8px;\n`;\n\nconst AnnotationItem = styled.div<{ $isActive?: boolean }>`\n padding: 12px;\n margin-bottom: 6px;\n border-left: 4px solid ${(props) => (props.$isActive ? '#ff9800' : 'transparent')};\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.15)' : 'transparent')};\n border-radius: 4px;\n transition: all 0.2s;\n cursor: pointer;\n box-shadow: ${(props) => (props.$isActive ? '0 2px 8px rgba(255, 152, 0, 0.25), inset 0 0 0 1px rgba(255, 152, 0, 0.3)' : 'none')};\n\n &:hover {\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.2)' : props.theme?.annotationTextItemHoverBackground || 'rgba(0, 0, 0, 0.05)')};\n border-left-color: ${(props) => (props.$isActive ? '#ff9800' : props.theme?.borderColor || '#ddd')};\n }\n\n &:focus-visible {\n outline: 2px solid #ff9800;\n outline-offset: 2px;\n }\n`;\n\nconst AnnotationHeader = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n`;\n\nconst AnnotationInfo = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n`;\n\nconst AnnotationIdLabel = styled.span<{ $isEditable?: boolean }>`\n font-size: 11px;\n font-weight: 600;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n background: transparent;\n padding: 2px 6px;\n border-radius: 3px;\n min-width: 20px;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\nconst TimeRange = styled.span`\n font-size: 12px;\n font-weight: 500;\n color: ${(props) => props.theme?.textColorMuted || '#555'};\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n letter-spacing: 0.5px;\n`;\n\nconst AnnotationControls = styled.div`\n display: flex;\n gap: 6px;\n`;\n\nconst ControlButton = styled.button`\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n color: ${(props) => props.theme?.textColor || '#333'};\n padding: 4px 8px;\n font-size: 14px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n\n &:hover {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n transform: scale(1.05);\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst AnnotationTextContent = styled.div<{ $isEditable?: boolean }>`\n font-size: 14px;\n line-height: 1.6;\n color: ${(props) => props.theme?.textColor || '#2a2a2a'};\n white-space: pre-wrap;\n word-break: break-word;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n padding: ${(props) => (props.$isEditable ? '6px' : '0')};\n border-radius: 3px;\n min-height: 20px;\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\n/**\n * Props passed to the renderAnnotationItem function for custom rendering\n */\nexport interface RenderAnnotationItemProps {\n annotation: AnnotationData;\n index: number;\n isActive: boolean;\n onClick: () => void;\n formatTime: (seconds: number) => string;\n}\n\nexport interface AnnotationTextProps {\n annotations: AnnotationData[];\n activeAnnotationId?: string;\n shouldScrollToActive?: boolean;\n /** Where to position the active annotation when scrolling: 'center', 'start', 'end', or 'nearest'. Defaults to 'center'. */\n scrollActivePosition?: ScrollLogicalPosition;\n /** Which scrollable containers to scroll: 'nearest' (only the annotation list) or 'all' (including viewport). Defaults to 'nearest'. */\n scrollActiveContainer?: 'nearest' | 'all';\n editable?: boolean;\n controls?: AnnotationAction[];\n annotationListConfig?: AnnotationActionOptions;\n height?: number;\n onAnnotationClick?: (annotation: AnnotationData) => void;\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n /**\n * Custom render function for annotation items.\n * When provided, completely replaces the default annotation item rendering.\n * Use this to customize the appearance of each annotation in the list.\n */\n renderAnnotationItem?: (props: RenderAnnotationItemProps) => React.ReactNode;\n}\n\nconst AnnotationTextComponent: FunctionComponent<AnnotationTextProps> = ({\n annotations,\n activeAnnotationId,\n shouldScrollToActive = false,\n scrollActivePosition = 'center',\n scrollActiveContainer = 'nearest',\n editable = false,\n controls = [],\n annotationListConfig,\n height,\n onAnnotationClick,\n onAnnotationUpdate,\n renderAnnotationItem,\n}) => {\n const activeAnnotationRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const prevActiveIdRef = useRef<string | undefined>(undefined);\n\n // Track component renders and scroll position\n useEffect(() => {\n // Render tracking removed\n });\n\n // Track scroll changes\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n // Scroll tracking removed\n };\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, []);\n\n // Auto-scroll to active annotation when it changes\n useEffect(() => {\n // Only scroll if parent says we should (prevents scrolling on remount after pause)\n if (activeAnnotationId && activeAnnotationRef.current && shouldScrollToActive) {\n activeAnnotationRef.current.scrollIntoView({\n behavior: 'smooth',\n block: scrollActivePosition,\n container: scrollActiveContainer,\n } as ScrollIntoViewOptions);\n }\n\n prevActiveIdRef.current = activeAnnotationId;\n }, [activeAnnotationId, shouldScrollToActive, scrollActivePosition, scrollActiveContainer]);\n\n const formatTime = (seconds: number): string => {\n if (isNaN(seconds) || !isFinite(seconds)) {\n return '0:00.000';\n }\n const mins = Math.floor(seconds / 60);\n const secs = (seconds % 60).toFixed(3);\n return `${mins}:${secs.padStart(6, '0')}`;\n };\n\n const handleTextEdit = (index: number, newText: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n lines: newText.split('\\n'),\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleIdEdit = (index: number, newId: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const trimmedId = newId.trim();\n if (!trimmedId) return; // Don't allow empty IDs\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n id: trimmedId,\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleControlClick = (control: AnnotationAction, annotation: AnnotationData, index: number) => {\n if (!onAnnotationUpdate) return;\n\n const annotationsCopy = [...annotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n onAnnotationUpdate(annotationsCopy);\n };\n\n const getIconClass = (classString: string) => {\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <Container ref={containerRef} $height={height}>\n {annotations.map((annotation, index) => {\n const isActive = annotation.id === activeAnnotationId;\n const handleClick = () => onAnnotationClick?.(annotation);\n\n // Use custom render function if provided\n if (renderAnnotationItem) {\n return (\n <div\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n >\n {renderAnnotationItem({\n annotation,\n index,\n isActive,\n onClick: handleClick,\n formatTime,\n })}\n </div>\n );\n }\n\n // Default rendering\n return (\n <AnnotationItem\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n $isActive={isActive}\n onClick={handleClick}\n >\n <AnnotationHeader>\n <AnnotationInfo>\n <AnnotationIdLabel\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleIdEdit(index, e.currentTarget.textContent || '')}\n >\n {annotation.id}\n </AnnotationIdLabel>\n <TimeRange>\n {formatTime(annotation.start)} - {formatTime(annotation.end)}\n </TimeRange>\n </AnnotationInfo>\n {controls.length > 0 && (\n <AnnotationControls onClick={(e) => e.stopPropagation()}>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={() => handleControlClick(control, annotation, index)}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </AnnotationControls>\n )}\n </AnnotationHeader>\n <AnnotationTextContent\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleTextEdit(index, e.currentTarget.textContent || '')}\n >\n {annotation.lines.join('\\n')}\n </AnnotationTextContent>\n </AnnotationItem>\n );\n })}\n </Container>\n );\n};\n\n// Memoize to prevent unnecessary remounting when parent re-renders\nexport const AnnotationText = React.memo(AnnotationTextComponent);\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface ContinuousPlayCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling continuous play of annotations.\n * When enabled, playback continues from one annotation to the next without stopping.\n */\nexport const ContinuousPlayCheckbox: React.FC<ContinuousPlayCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"continuous-play\"\n className=\"continuous-play\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"continuous-play\">Continuous Play</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface LinkEndpointsCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling linked endpoints between annotations.\n * When enabled, the end time of one annotation is automatically linked to the start time of the next.\n */\nexport const LinkEndpointsCheckbox: React.FC<LinkEndpointsCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"link-endpoints\"\n className=\"link-endpoints\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"link-endpoints\">Link Endpoints</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface EditableCheckboxProps {\n checked: boolean;\n onChange: (enabled: boolean) => void;\n className?: string;\n}\n\nexport const EditableCheckbox: React.FC<EditableCheckboxProps> = ({\n checked,\n onChange,\n className,\n}) => {\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"editable-annotations\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n />\n <BaseCheckboxLabel htmlFor=\"editable-annotations\">Editable Annotations</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport styled from 'styled-components';\nimport { serializeAeneas } from '../parsers/aeneas';\nimport type { Annotation } from '../types';\n\nconst StyledButton = styled.button`\n padding: 0.5rem 1rem;\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n color: ${(props) => props.theme?.textColor || '#333'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n border-radius: ${(props) => props.theme?.borderRadius || '4px'};\n cursor: pointer;\n font-family: ${(props) => props.theme?.fontFamily || 'inherit'};\n font-size: ${(props) => props.theme?.fontSize || '14px'};\n font-weight: 500;\n transition: all 0.15s ease;\n\n &:hover:not(:disabled) {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 2px ${(props) => props.theme?.inputFocusBorder || '#007bff'}44;\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n`;\n\nexport interface DownloadAnnotationsButtonProps {\n annotations: Annotation[];\n filename?: string;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport const DownloadAnnotationsButton: React.FC<DownloadAnnotationsButtonProps> = ({\n annotations,\n filename = 'annotations.json',\n disabled = false,\n className,\n children = 'Download JSON',\n}) => {\n const handleDownload = () => {\n if (annotations.length === 0) {\n return;\n }\n\n // Serialize annotations to Aeneas JSON format\n const jsonData = annotations.map(annotation => serializeAeneas(annotation));\n const jsonString = JSON.stringify(jsonData, null, 2);\n\n // Create a blob and download link\n const blob = new Blob([jsonString], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n\n // Trigger download\n document.body.appendChild(link);\n link.click();\n\n // Cleanup\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n };\n\n return (\n <StyledButton\n onClick={handleDownload}\n disabled={disabled || annotations.length === 0}\n className={className}\n title={annotations.length === 0 ? 'No annotations to download' : 'Download the annotations as JSON'}\n >\n {children}\n </StyledButton>\n );\n};\n","import { useState, useCallback } from 'react';\nimport type { Annotation, AnnotationListOptions } from '../types';\n\nconst LINK_THRESHOLD = 0.01; // Consider edges \"linked\" if within 10ms\n\nexport interface UseAnnotationControlsOptions {\n initialContinuousPlay?: boolean;\n initialLinkEndpoints?: boolean;\n}\n\nexport interface AnnotationUpdateParams {\n annotationIndex: number;\n newTime: number;\n isDraggingStart: boolean;\n annotations: Annotation[];\n duration: number;\n linkEndpoints: boolean;\n}\n\nexport interface UseAnnotationControlsReturn {\n continuousPlay: boolean;\n linkEndpoints: boolean;\n setContinuousPlay: (value: boolean) => void;\n setLinkEndpoints: (value: boolean) => void;\n updateAnnotationBoundaries: (params: AnnotationUpdateParams) => Annotation[];\n}\n\n/**\n * Hook for managing annotation control state and boundary logic.\n * Handles continuous play mode and linked endpoints behavior.\n */\nexport const useAnnotationControls = (\n options: UseAnnotationControlsOptions = {}\n): UseAnnotationControlsReturn => {\n const {\n initialContinuousPlay = false,\n initialLinkEndpoints = true,\n } = options;\n\n const [continuousPlay, setContinuousPlay] = useState(initialContinuousPlay);\n const [linkEndpoints, setLinkEndpoints] = useState(initialLinkEndpoints);\n\n /**\n * Updates annotation boundaries based on drag operations.\n * Handles linked endpoints and collision detection.\n * Note: linkEndpoints is passed as a parameter to ensure it uses the current value from context.\n */\n const updateAnnotationBoundaries = useCallback(\n ({\n annotationIndex,\n newTime,\n isDraggingStart,\n annotations,\n duration,\n linkEndpoints: shouldLinkEndpoints,\n }: AnnotationUpdateParams): Annotation[] => {\n const updatedAnnotations = [...annotations];\n const annotation = annotations[annotationIndex];\n\n if (isDraggingStart) {\n // Dragging start edge\n const constrainedStart = Math.min(annotation.end - 0.1, Math.max(0, newTime));\n const delta = constrainedStart - annotation.start;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n start: constrainedStart,\n };\n\n if (shouldLinkEndpoints && annotationIndex > 0) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const prevAnnotation = updatedAnnotations[annotationIndex - 1];\n\n if (Math.abs(prevAnnotation.end - annotation.start) < LINK_THRESHOLD) {\n // Already linked: move previous annotation's end together with this start\n updatedAnnotations[annotationIndex - 1] = {\n ...prevAnnotation,\n end: Math.max(prevAnnotation.start + 0.1, prevAnnotation.end + delta),\n };\n } else if (constrainedStart <= prevAnnotation.end) {\n // Dragged past previous annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n start: prevAnnotation.end,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex > 0 && constrainedStart < updatedAnnotations[annotationIndex - 1].end) {\n // Collision detection: push previous annotation's end back\n updatedAnnotations[annotationIndex - 1] = {\n ...updatedAnnotations[annotationIndex - 1],\n end: constrainedStart,\n };\n }\n } else {\n // Dragging end edge\n const constrainedEnd = Math.max(annotation.start + 0.1, Math.min(newTime, duration));\n const delta = constrainedEnd - annotation.end;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n end: constrainedEnd,\n };\n\n if (shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n if (Math.abs(nextAnnotation.start - annotation.end) < LINK_THRESHOLD) {\n // Already linked: move next annotation's start together with this end\n const newStart = nextAnnotation.start + delta;\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: Math.min(nextAnnotation.end - 0.1, newStart),\n };\n\n // Cascade linked endpoints\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (Math.abs(next.start - current.end) < LINK_THRESHOLD) {\n const nextDelta = current.end - annotations[currentIndex].end;\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: Math.min(next.end - 0.1, next.start + nextDelta),\n };\n currentIndex++;\n } else {\n break; // No more linked endpoints\n }\n }\n } else if (constrainedEnd >= nextAnnotation.start) {\n // Dragged past next annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n end: nextAnnotation.start,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1 && constrainedEnd > updatedAnnotations[annotationIndex + 1].start) {\n // Collision detection: push next annotation's start forward\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: constrainedEnd,\n };\n\n // Cascade collisions\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (current.end > next.start) {\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: current.end,\n };\n currentIndex++;\n } else {\n break; // No more collisions\n }\n }\n }\n }\n\n return updatedAnnotations;\n },\n []\n );\n\n return {\n continuousPlay,\n linkEndpoints,\n setContinuousPlay,\n setLinkEndpoints,\n updateAnnotationBoundaries,\n };\n};\n"],"mappings":"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","names":["AnnotationText","styled","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_ui_components","import_jsx_runtime","Container","styled","ControlsPlaceholder","import_react","import_styled_components","import_jsx_runtime","Container","styled","ControlButton","AnnotationText","React","import_ui_components","import_jsx_runtime","import_ui_components","import_jsx_runtime","import_ui_components","import_jsx_runtime","import_styled_components","import_jsx_runtime","styled","import_react"]}
|
package/dist/index.mjs
CHANGED
|
@@ -261,11 +261,11 @@ var Label = styled2.span`
|
|
|
261
261
|
var ResizeHandle = styled2.div`
|
|
262
262
|
position: absolute;
|
|
263
263
|
top: 0;
|
|
264
|
-
${(props) => props.$position === "left" ? "left:
|
|
265
|
-
width:
|
|
264
|
+
${(props) => props.$position === "left" ? "left: 0" : "right: 0"};
|
|
265
|
+
width: 8px;
|
|
266
266
|
height: 100%;
|
|
267
267
|
cursor: ew-resize;
|
|
268
|
-
z-index: 120;
|
|
268
|
+
z-index: 120;
|
|
269
269
|
background: ${(props) => props.$isDragging ? props.theme?.annotationResizeHandleColor || "rgba(0, 0, 0, 0.2)" : "transparent"};
|
|
270
270
|
border-radius: 4px;
|
|
271
271
|
touch-action: none; /* Important for @dnd-kit on touch devices */
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parsers/aeneas.ts","../src/components/Annotation.tsx","../src/components/AnnotationBox.tsx","../src/components/AnnotationBoxesWrapper.tsx","../src/components/AnnotationsTrack.tsx","../src/components/AnnotationText.tsx","../src/components/ContinuousPlayCheckbox.tsx","../src/components/LinkEndpointsCheckbox.tsx","../src/components/EditableCheckbox.tsx","../src/components/DownloadAnnotationsButton.tsx","../src/hooks/useAnnotationControls.ts"],"sourcesContent":["import { Annotation } from '../types';\n\nexport interface AeneasFragment {\n begin: string;\n end: string;\n id: string;\n language: string;\n lines: string[];\n}\n\nexport function parseAeneas(data: AeneasFragment): Annotation {\n return {\n id: data.id,\n start: parseFloat(data.begin),\n end: parseFloat(data.end),\n lines: data.lines,\n lang: data.language,\n };\n}\n\nexport function serializeAeneas(annotation: Annotation): AeneasFragment {\n return {\n id: annotation.id,\n begin: annotation.start.toFixed(3),\n end: annotation.end.toFixed(3),\n lines: annotation.lines,\n language: annotation.lang || 'en',\n };\n}\n","import React, { FunctionComponent, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface AnnotationOverlayProps {\n readonly $left: number;\n readonly $width: number;\n readonly $color: string;\n}\n\nconst AnnotationOverlay = styled.div.attrs<AnnotationOverlayProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<AnnotationOverlayProps>`\n position: absolute;\n top: 0;\n background: ${(props) => props.$color};\n height: 100%;\n z-index: 10;\n pointer-events: auto;\n opacity: 0.3;\n border: 2px solid ${(props) => props.$color};\n border-radius: 4px;\n cursor: pointer;\n\n &:hover {\n opacity: 0.5;\n border-color: ${(props) => props.$color};\n }\n`;\n\nconst AnnotationText = styled.div`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: none;\n white-space: pre-wrap;\n word-break: break-word;\n`;\n\nconst EditableText = styled.textarea`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.9);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: auto;\n border: 1px solid #fff;\n resize: none;\n font-family: inherit;\n\n &:focus {\n outline: none;\n border-color: #4CAF50;\n }\n`;\n\nconst ControlsBar = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n gap: 4px;\n padding: 4px;\n justify-content: flex-start;\n align-items: center;\n`;\n\nconst ControlButton = styled.button`\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.5);\n color: white;\n padding: 4px 8px;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n border-color: white;\n }\n\n &:active {\n background: rgba(255, 255, 255, 0.3);\n }\n`;\n\n/**\n * Configuration options passed to annotation action handlers\n */\nexport interface AnnotationActionOptions {\n /** Whether annotation endpoints are linked (moving one endpoint moves the other) */\n linkEndpoints?: boolean;\n /** Whether to continue playing after an annotation ends */\n continuousPlay?: boolean;\n /** Additional custom properties */\n [key: string]: unknown;\n}\n\nexport interface AnnotationAction {\n class?: string;\n text?: string;\n title: string;\n action: (annotation: AnnotationData, index: number, annotations: AnnotationData[], opts: AnnotationActionOptions) => void;\n}\n\nexport interface AnnotationData {\n id: string;\n start: number;\n end: number;\n lines: string[];\n language?: string;\n}\n\nexport interface AnnotationProps {\n annotation: AnnotationData;\n index: number;\n allAnnotations: AnnotationData[];\n startPosition: number; // Start position in pixels\n endPosition: number; // End position in pixels\n color?: string;\n editable?: boolean;\n controls?: AnnotationAction[];\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n annotationListConfig?: AnnotationActionOptions;\n onClick?: (annotation: AnnotationData) => void;\n}\n\nexport const Annotation: FunctionComponent<AnnotationProps> = ({\n annotation,\n index,\n allAnnotations,\n startPosition,\n endPosition,\n color = '#ff9800',\n editable = false,\n controls = [],\n onAnnotationUpdate,\n annotationListConfig,\n onClick,\n}) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editedText, setEditedText] = useState(annotation.lines.join('\\n'));\n const width = Math.max(0, endPosition - startPosition);\n\n if (width <= 0) {\n return null;\n }\n\n const handleClick = () => {\n if (onClick) {\n onClick(annotation);\n }\n };\n\n const handleDoubleClick = () => {\n if (editable) {\n setIsEditing(true);\n }\n };\n\n const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setEditedText(e.target.value);\n };\n\n const handleTextBlur = () => {\n setIsEditing(false);\n const newLines = editedText.split('\\n');\n if (newLines.join('\\n') !== annotation.lines.join('\\n')) {\n const updatedAnnotations = [...allAnnotations];\n updatedAnnotations[index] = { ...annotation, lines: newLines };\n if (onAnnotationUpdate) {\n onAnnotationUpdate(updatedAnnotations);\n }\n }\n };\n\n const handleControlClick = (control: AnnotationAction) => {\n const annotationsCopy = [...allAnnotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n if (onAnnotationUpdate) {\n onAnnotationUpdate(annotationsCopy);\n }\n };\n\n const getIconClass = (classString: string) => {\n // Convert \"fas.fa-minus\" to \"fas fa-minus\"\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <AnnotationOverlay\n $left={startPosition}\n $width={width}\n $color={color}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n >\n {controls.length > 0 && (\n <ControlsBar>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={(e) => {\n e.stopPropagation();\n handleControlClick(control);\n }}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </ControlsBar>\n )}\n {isEditing ? (\n <EditableText\n value={editedText}\n onChange={handleTextChange}\n onBlur={handleTextBlur}\n autoFocus\n onClick={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n />\n ) : (\n <AnnotationText>\n {annotation.lines.join('\\n')}\n </AnnotationText>\n )}\n </AnnotationOverlay>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { useDraggable } from '@dnd-kit/core';\nimport type { DraggableAttributes } from '@dnd-kit/core';\nimport type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';\n\ninterface WrapperProps {\n readonly $left: number;\n readonly $width: number;\n}\n\n// Wrapper positions the annotation and contains both Box and ResizeHandles as siblings\nconst Wrapper = styled.div.attrs<WrapperProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<WrapperProps>`\n position: absolute;\n top: 0;\n height: 100%;\n pointer-events: none; /* Let events pass through to children */\n`;\n\ninterface BoxProps {\n readonly $color: string;\n readonly $isActive?: boolean;\n}\n\nconst Box = styled.div<BoxProps>`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 100%;\n background: ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBackground || 'rgba(255, 200, 100, 0.95)')\n : (props.theme?.annotationBoxBackground || 'rgba(255, 255, 255, 0.85)')};\n border: ${(props) => props.$isActive ? '3px' : '2px'} solid ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBorder || '#ff9800')\n : props.$color};\n border-radius: 4px;\n cursor: pointer;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: ${(props) => props.$isActive\n ? '0 2px 8px rgba(255, 152, 0, 0.4), inset 0 0 0 1px rgba(255, 152, 0, 0.2)'\n : '0 1px 3px rgba(0, 0, 0, 0.1)'};\n\n &:hover {\n background: ${(props) => props.theme?.annotationBoxHoverBackground || 'rgba(255, 255, 255, 0.98)'};\n border-color: ${(props) => props.theme?.annotationBoxActiveBorder || '#ff9800'};\n border-width: 3px;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);\n }\n`;\n\nconst Label = styled.span`\n font-size: 12px;\n font-weight: 600;\n color: ${(props) => props.theme?.annotationLabelColor || '#2a2a2a'};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0 6px;\n letter-spacing: 0.3px;\n user-select: none;\n`;\n\ninterface ResizeHandleStyledProps {\n $position: 'left' | 'right';\n $isDragging?: boolean;\n}\n\n// ResizeHandles are now siblings of Box, positioned relative to Wrapper\n// Reduced from 30px/-15px to 16px/-8px to minimize overlap between adjacent annotations\nconst ResizeHandle = styled.div<ResizeHandleStyledProps>`\n position: absolute;\n top: 0;\n ${(props) => props.$position === 'left' ? 'left: -8px' : 'right: -8px'};\n width: 16px;\n height: 100%;\n cursor: ew-resize;\n z-index: 120; /* Above ClickOverlay (z-index: 100) and AnnotationBoxesWrapper (z-index: 110) */\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.2)')\n : 'transparent'};\n border-radius: 4px;\n touch-action: none; /* Important for @dnd-kit on touch devices */\n pointer-events: auto;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 4px;\n height: 60%;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.8)')\n : (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.4)')};\n border-radius: 2px;\n opacity: ${(props) => props.$isDragging ? 1 : 0.6};\n transition: opacity 0.2s, background 0.2s;\n }\n\n &:hover {\n background: ${(props) => props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.1)'};\n }\n\n &:hover::before {\n opacity: 1;\n background: ${(props) => props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.7)'};\n }\n`;\n\nexport interface DragHandleProps {\n attributes: DraggableAttributes;\n listeners: SyntheticListenerMap | undefined;\n setActivatorNodeRef: (element: HTMLElement | null) => void;\n isDragging: boolean;\n}\n\nexport interface AnnotationBoxComponentProps {\n annotationId: string;\n annotationIndex: number;\n startPosition: number;\n endPosition: number;\n label?: string;\n color?: string;\n isActive?: boolean;\n onClick?: () => void;\n editable?: boolean; // Whether to show drag handles\n}\n\nexport const AnnotationBox: FunctionComponent<AnnotationBoxComponentProps> = ({\n annotationId,\n annotationIndex,\n startPosition,\n endPosition,\n label,\n color = '#ff9800',\n isActive = false,\n onClick,\n editable = true,\n}) => {\n const width = Math.max(0, endPosition - startPosition);\n\n // Left (start) boundary draggable\n const leftBoundaryId = `annotation-boundary-start-${annotationIndex}`;\n const {\n attributes: leftAttributes,\n listeners: leftListeners,\n setActivatorNodeRef: setLeftActivatorRef,\n isDragging: isLeftDragging,\n } = useDraggable({\n id: leftBoundaryId,\n data: { annotationId, annotationIndex, edge: 'start' as const },\n disabled: !editable,\n });\n\n // Right (end) boundary draggable\n const rightBoundaryId = `annotation-boundary-end-${annotationIndex}`;\n const {\n attributes: rightAttributes,\n listeners: rightListeners,\n setActivatorNodeRef: setRightActivatorRef,\n isDragging: isRightDragging,\n } = useDraggable({\n id: rightBoundaryId,\n data: { annotationId, annotationIndex, edge: 'end' as const },\n disabled: !editable,\n });\n\n if (width <= 0) {\n return null;\n }\n\n // Wrap @dnd-kit pointer handlers to also stop propagation\n // This prevents the ClickOverlay from capturing the event\n const createPointerDownHandler = (dndKitHandler?: (e: React.PointerEvent) => void) => {\n return (e: React.PointerEvent) => {\n e.stopPropagation();\n dndKitHandler?.(e);\n };\n };\n\n const handleHandleClick = (e: React.MouseEvent) => {\n // Prevent clicks on resize handles from bubbling to annotation box\n e.stopPropagation();\n };\n\n return (\n <Wrapper $left={startPosition} $width={width}>\n <Box\n $color={color}\n $isActive={isActive}\n onClick={onClick}\n >\n {label && <Label>{label}</Label>}\n </Box>\n {editable && (\n <ResizeHandle\n ref={setLeftActivatorRef}\n $position=\"left\"\n $isDragging={isLeftDragging}\n onClick={handleHandleClick}\n {...leftListeners}\n onPointerDown={createPointerDownHandler(leftListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...leftAttributes}\n />\n )}\n {editable && (\n <ResizeHandle\n ref={setRightActivatorRef}\n $position=\"right\"\n $isDragging={isRightDragging}\n onClick={handleHandleClick}\n {...rightListeners}\n onPointerDown={createPointerDownHandler(rightListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...rightAttributes}\n />\n )}\n </Wrapper>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n z-index: 110;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n`;\n\nconst BoxesContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationBoxesWrapperProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationBoxesWrapper: FunctionComponent<AnnotationBoxesWrapperProps> = ({\n children,\n className,\n height = 30,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0} />\n <BoxesContainer $offset={offset}>\n {children}\n </BoxesContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n font-weight: bold;\n`;\n\nconst AnnotationsContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationsTrackProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationsTrack: FunctionComponent<AnnotationsTrackProps> = ({\n children,\n className,\n height = 100,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0}>\n Annotations\n </ControlsPlaceholder>\n <AnnotationsContainer $offset={offset}>\n {children}\n </AnnotationsContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent, useRef, useEffect } from 'react';\nimport styled from 'styled-components';\nimport type { AnnotationData, AnnotationAction, AnnotationActionOptions } from './Annotation';\n\ninterface ContainerProps {\n $height?: number;\n}\n\nconst Container = styled.div<ContainerProps>`\n background: ${(props) => props.theme?.backgroundColor || '#fff'};\n ${(props) => props.$height ? `height: ${props.$height}px;` : 'max-height: 200px;'}\n overflow-y: auto;\n padding: 8px;\n`;\n\nconst AnnotationItem = styled.div<{ $isActive?: boolean }>`\n padding: 12px;\n margin-bottom: 6px;\n border-left: 4px solid ${(props) => (props.$isActive ? '#ff9800' : 'transparent')};\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.15)' : 'transparent')};\n border-radius: 4px;\n transition: all 0.2s;\n cursor: pointer;\n box-shadow: ${(props) => (props.$isActive ? '0 2px 8px rgba(255, 152, 0, 0.25), inset 0 0 0 1px rgba(255, 152, 0, 0.3)' : 'none')};\n\n &:hover {\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.2)' : props.theme?.annotationTextItemHoverBackground || 'rgba(0, 0, 0, 0.05)')};\n border-left-color: ${(props) => (props.$isActive ? '#ff9800' : props.theme?.borderColor || '#ddd')};\n }\n\n &:focus-visible {\n outline: 2px solid #ff9800;\n outline-offset: 2px;\n }\n`;\n\nconst AnnotationHeader = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n`;\n\nconst AnnotationInfo = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n`;\n\nconst AnnotationIdLabel = styled.span<{ $isEditable?: boolean }>`\n font-size: 11px;\n font-weight: 600;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n background: transparent;\n padding: 2px 6px;\n border-radius: 3px;\n min-width: 20px;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\nconst TimeRange = styled.span`\n font-size: 12px;\n font-weight: 500;\n color: ${(props) => props.theme?.textColorMuted || '#555'};\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n letter-spacing: 0.5px;\n`;\n\nconst AnnotationControls = styled.div`\n display: flex;\n gap: 6px;\n`;\n\nconst ControlButton = styled.button`\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n color: ${(props) => props.theme?.textColor || '#333'};\n padding: 4px 8px;\n font-size: 14px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n\n &:hover {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n transform: scale(1.05);\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst AnnotationTextContent = styled.div<{ $isEditable?: boolean }>`\n font-size: 14px;\n line-height: 1.6;\n color: ${(props) => props.theme?.textColor || '#2a2a2a'};\n white-space: pre-wrap;\n word-break: break-word;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n padding: ${(props) => (props.$isEditable ? '6px' : '0')};\n border-radius: 3px;\n min-height: 20px;\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\n/**\n * Props passed to the renderAnnotationItem function for custom rendering\n */\nexport interface RenderAnnotationItemProps {\n annotation: AnnotationData;\n index: number;\n isActive: boolean;\n onClick: () => void;\n formatTime: (seconds: number) => string;\n}\n\nexport interface AnnotationTextProps {\n annotations: AnnotationData[];\n activeAnnotationId?: string;\n shouldScrollToActive?: boolean;\n /** Where to position the active annotation when scrolling: 'center', 'start', 'end', or 'nearest'. Defaults to 'center'. */\n scrollActivePosition?: ScrollLogicalPosition;\n /** Which scrollable containers to scroll: 'nearest' (only the annotation list) or 'all' (including viewport). Defaults to 'nearest'. */\n scrollActiveContainer?: 'nearest' | 'all';\n editable?: boolean;\n controls?: AnnotationAction[];\n annotationListConfig?: AnnotationActionOptions;\n height?: number;\n onAnnotationClick?: (annotation: AnnotationData) => void;\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n /**\n * Custom render function for annotation items.\n * When provided, completely replaces the default annotation item rendering.\n * Use this to customize the appearance of each annotation in the list.\n */\n renderAnnotationItem?: (props: RenderAnnotationItemProps) => React.ReactNode;\n}\n\nconst AnnotationTextComponent: FunctionComponent<AnnotationTextProps> = ({\n annotations,\n activeAnnotationId,\n shouldScrollToActive = false,\n scrollActivePosition = 'center',\n scrollActiveContainer = 'nearest',\n editable = false,\n controls = [],\n annotationListConfig,\n height,\n onAnnotationClick,\n onAnnotationUpdate,\n renderAnnotationItem,\n}) => {\n const activeAnnotationRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const prevActiveIdRef = useRef<string | undefined>(undefined);\n\n // Track component renders and scroll position\n useEffect(() => {\n // Render tracking removed\n });\n\n // Track scroll changes\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n // Scroll tracking removed\n };\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, []);\n\n // Auto-scroll to active annotation when it changes\n useEffect(() => {\n // Only scroll if parent says we should (prevents scrolling on remount after pause)\n if (activeAnnotationId && activeAnnotationRef.current && shouldScrollToActive) {\n activeAnnotationRef.current.scrollIntoView({\n behavior: 'smooth',\n block: scrollActivePosition,\n container: scrollActiveContainer,\n } as ScrollIntoViewOptions);\n }\n\n prevActiveIdRef.current = activeAnnotationId;\n }, [activeAnnotationId, shouldScrollToActive, scrollActivePosition, scrollActiveContainer]);\n\n const formatTime = (seconds: number): string => {\n if (isNaN(seconds) || !isFinite(seconds)) {\n return '0:00.000';\n }\n const mins = Math.floor(seconds / 60);\n const secs = (seconds % 60).toFixed(3);\n return `${mins}:${secs.padStart(6, '0')}`;\n };\n\n const handleTextEdit = (index: number, newText: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n lines: newText.split('\\n'),\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleIdEdit = (index: number, newId: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const trimmedId = newId.trim();\n if (!trimmedId) return; // Don't allow empty IDs\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n id: trimmedId,\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleControlClick = (control: AnnotationAction, annotation: AnnotationData, index: number) => {\n if (!onAnnotationUpdate) return;\n\n const annotationsCopy = [...annotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n onAnnotationUpdate(annotationsCopy);\n };\n\n const getIconClass = (classString: string) => {\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <Container ref={containerRef} $height={height}>\n {annotations.map((annotation, index) => {\n const isActive = annotation.id === activeAnnotationId;\n const handleClick = () => onAnnotationClick?.(annotation);\n\n // Use custom render function if provided\n if (renderAnnotationItem) {\n return (\n <div\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n >\n {renderAnnotationItem({\n annotation,\n index,\n isActive,\n onClick: handleClick,\n formatTime,\n })}\n </div>\n );\n }\n\n // Default rendering\n return (\n <AnnotationItem\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n $isActive={isActive}\n onClick={handleClick}\n >\n <AnnotationHeader>\n <AnnotationInfo>\n <AnnotationIdLabel\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleIdEdit(index, e.currentTarget.textContent || '')}\n >\n {annotation.id}\n </AnnotationIdLabel>\n <TimeRange>\n {formatTime(annotation.start)} - {formatTime(annotation.end)}\n </TimeRange>\n </AnnotationInfo>\n {controls.length > 0 && (\n <AnnotationControls onClick={(e) => e.stopPropagation()}>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={() => handleControlClick(control, annotation, index)}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </AnnotationControls>\n )}\n </AnnotationHeader>\n <AnnotationTextContent\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleTextEdit(index, e.currentTarget.textContent || '')}\n >\n {annotation.lines.join('\\n')}\n </AnnotationTextContent>\n </AnnotationItem>\n );\n })}\n </Container>\n );\n};\n\n// Memoize to prevent unnecessary remounting when parent re-renders\nexport const AnnotationText = React.memo(AnnotationTextComponent);\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface ContinuousPlayCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling continuous play of annotations.\n * When enabled, playback continues from one annotation to the next without stopping.\n */\nexport const ContinuousPlayCheckbox: React.FC<ContinuousPlayCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"continuous-play\"\n className=\"continuous-play\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"continuous-play\">Continuous Play</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface LinkEndpointsCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling linked endpoints between annotations.\n * When enabled, the end time of one annotation is automatically linked to the start time of the next.\n */\nexport const LinkEndpointsCheckbox: React.FC<LinkEndpointsCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"link-endpoints\"\n className=\"link-endpoints\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"link-endpoints\">Link Endpoints</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface EditableCheckboxProps {\n checked: boolean;\n onChange: (enabled: boolean) => void;\n className?: string;\n}\n\nexport const EditableCheckbox: React.FC<EditableCheckboxProps> = ({\n checked,\n onChange,\n className,\n}) => {\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"editable-annotations\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n />\n <BaseCheckboxLabel htmlFor=\"editable-annotations\">Editable Annotations</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport styled from 'styled-components';\nimport { serializeAeneas } from '../parsers/aeneas';\nimport type { Annotation } from '../types';\n\nconst StyledButton = styled.button`\n padding: 0.5rem 1rem;\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n color: ${(props) => props.theme?.textColor || '#333'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n border-radius: ${(props) => props.theme?.borderRadius || '4px'};\n cursor: pointer;\n font-family: ${(props) => props.theme?.fontFamily || 'inherit'};\n font-size: ${(props) => props.theme?.fontSize || '14px'};\n font-weight: 500;\n transition: all 0.15s ease;\n\n &:hover:not(:disabled) {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 2px ${(props) => props.theme?.inputFocusBorder || '#007bff'}44;\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n`;\n\nexport interface DownloadAnnotationsButtonProps {\n annotations: Annotation[];\n filename?: string;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport const DownloadAnnotationsButton: React.FC<DownloadAnnotationsButtonProps> = ({\n annotations,\n filename = 'annotations.json',\n disabled = false,\n className,\n children = 'Download JSON',\n}) => {\n const handleDownload = () => {\n if (annotations.length === 0) {\n return;\n }\n\n // Serialize annotations to Aeneas JSON format\n const jsonData = annotations.map(annotation => serializeAeneas(annotation));\n const jsonString = JSON.stringify(jsonData, null, 2);\n\n // Create a blob and download link\n const blob = new Blob([jsonString], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n\n // Trigger download\n document.body.appendChild(link);\n link.click();\n\n // Cleanup\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n };\n\n return (\n <StyledButton\n onClick={handleDownload}\n disabled={disabled || annotations.length === 0}\n className={className}\n title={annotations.length === 0 ? 'No annotations to download' : 'Download the annotations as JSON'}\n >\n {children}\n </StyledButton>\n );\n};\n","import { useState, useCallback } from 'react';\nimport type { Annotation, AnnotationListOptions } from '../types';\n\nconst LINK_THRESHOLD = 0.01; // Consider edges \"linked\" if within 10ms\n\nexport interface UseAnnotationControlsOptions {\n initialContinuousPlay?: boolean;\n initialLinkEndpoints?: boolean;\n}\n\nexport interface AnnotationUpdateParams {\n annotationIndex: number;\n newTime: number;\n isDraggingStart: boolean;\n annotations: Annotation[];\n duration: number;\n linkEndpoints: boolean;\n}\n\nexport interface UseAnnotationControlsReturn {\n continuousPlay: boolean;\n linkEndpoints: boolean;\n setContinuousPlay: (value: boolean) => void;\n setLinkEndpoints: (value: boolean) => void;\n updateAnnotationBoundaries: (params: AnnotationUpdateParams) => Annotation[];\n}\n\n/**\n * Hook for managing annotation control state and boundary logic.\n * Handles continuous play mode and linked endpoints behavior.\n */\nexport const useAnnotationControls = (\n options: UseAnnotationControlsOptions = {}\n): UseAnnotationControlsReturn => {\n const {\n initialContinuousPlay = false,\n initialLinkEndpoints = true,\n } = options;\n\n const [continuousPlay, setContinuousPlay] = useState(initialContinuousPlay);\n const [linkEndpoints, setLinkEndpoints] = useState(initialLinkEndpoints);\n\n /**\n * Updates annotation boundaries based on drag operations.\n * Handles linked endpoints and collision detection.\n * Note: linkEndpoints is passed as a parameter to ensure it uses the current value from context.\n */\n const updateAnnotationBoundaries = useCallback(\n ({\n annotationIndex,\n newTime,\n isDraggingStart,\n annotations,\n duration,\n linkEndpoints: shouldLinkEndpoints,\n }: AnnotationUpdateParams): Annotation[] => {\n const updatedAnnotations = [...annotations];\n const annotation = annotations[annotationIndex];\n\n if (isDraggingStart) {\n // Dragging start edge\n const constrainedStart = Math.min(annotation.end - 0.1, Math.max(0, newTime));\n const delta = constrainedStart - annotation.start;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n start: constrainedStart,\n };\n\n if (shouldLinkEndpoints && annotationIndex > 0) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const prevAnnotation = updatedAnnotations[annotationIndex - 1];\n\n if (Math.abs(prevAnnotation.end - annotation.start) < LINK_THRESHOLD) {\n // Already linked: move previous annotation's end together with this start\n updatedAnnotations[annotationIndex - 1] = {\n ...prevAnnotation,\n end: Math.max(prevAnnotation.start + 0.1, prevAnnotation.end + delta),\n };\n } else if (constrainedStart <= prevAnnotation.end) {\n // Dragged past previous annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n start: prevAnnotation.end,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex > 0 && constrainedStart < updatedAnnotations[annotationIndex - 1].end) {\n // Collision detection: push previous annotation's end back\n updatedAnnotations[annotationIndex - 1] = {\n ...updatedAnnotations[annotationIndex - 1],\n end: constrainedStart,\n };\n }\n } else {\n // Dragging end edge\n const constrainedEnd = Math.max(annotation.start + 0.1, Math.min(newTime, duration));\n const delta = constrainedEnd - annotation.end;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n end: constrainedEnd,\n };\n\n if (shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n if (Math.abs(nextAnnotation.start - annotation.end) < LINK_THRESHOLD) {\n // Already linked: move next annotation's start together with this end\n const newStart = nextAnnotation.start + delta;\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: Math.min(nextAnnotation.end - 0.1, newStart),\n };\n\n // Cascade linked endpoints\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (Math.abs(next.start - current.end) < LINK_THRESHOLD) {\n const nextDelta = current.end - annotations[currentIndex].end;\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: Math.min(next.end - 0.1, next.start + nextDelta),\n };\n currentIndex++;\n } else {\n break; // No more linked endpoints\n }\n }\n } else if (constrainedEnd >= nextAnnotation.start) {\n // Dragged past next annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n end: nextAnnotation.start,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1 && constrainedEnd > updatedAnnotations[annotationIndex + 1].start) {\n // Collision detection: push next annotation's start forward\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: constrainedEnd,\n };\n\n // Cascade collisions\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (current.end > next.start) {\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: current.end,\n };\n currentIndex++;\n } else {\n break; // No more collisions\n }\n }\n }\n }\n\n return updatedAnnotations;\n },\n []\n );\n\n return {\n continuousPlay,\n linkEndpoints,\n setContinuousPlay,\n setLinkEndpoints,\n updateAnnotationBoundaries,\n };\n};\n"],"mappings":"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","names":["styled","jsx","jsxs","styled","jsx","jsxs","styled","usePlaylistInfo","jsx","jsxs","Container","ControlsPlaceholder","React","styled","jsx","jsxs","Container","ControlButton","AnnotationText","jsx","jsxs","BaseCheckboxWrapper","BaseCheckbox","BaseCheckboxLabel","jsx","jsxs","BaseCheckboxWrapper","BaseCheckbox","BaseCheckboxLabel","jsx","jsxs","styled","jsx","styled","useState"]}
|
|
1
|
+
{"version":3,"sources":["../src/parsers/aeneas.ts","../src/components/Annotation.tsx","../src/components/AnnotationBox.tsx","../src/components/AnnotationBoxesWrapper.tsx","../src/components/AnnotationsTrack.tsx","../src/components/AnnotationText.tsx","../src/components/ContinuousPlayCheckbox.tsx","../src/components/LinkEndpointsCheckbox.tsx","../src/components/EditableCheckbox.tsx","../src/components/DownloadAnnotationsButton.tsx","../src/hooks/useAnnotationControls.ts"],"sourcesContent":["import { Annotation } from '../types';\n\nexport interface AeneasFragment {\n begin: string;\n end: string;\n id: string;\n language: string;\n lines: string[];\n}\n\nexport function parseAeneas(data: AeneasFragment): Annotation {\n return {\n id: data.id,\n start: parseFloat(data.begin),\n end: parseFloat(data.end),\n lines: data.lines,\n lang: data.language,\n };\n}\n\nexport function serializeAeneas(annotation: Annotation): AeneasFragment {\n return {\n id: annotation.id,\n begin: annotation.start.toFixed(3),\n end: annotation.end.toFixed(3),\n lines: annotation.lines,\n language: annotation.lang || 'en',\n };\n}\n","import React, { FunctionComponent, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface AnnotationOverlayProps {\n readonly $left: number;\n readonly $width: number;\n readonly $color: string;\n}\n\nconst AnnotationOverlay = styled.div.attrs<AnnotationOverlayProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<AnnotationOverlayProps>`\n position: absolute;\n top: 0;\n background: ${(props) => props.$color};\n height: 100%;\n z-index: 10;\n pointer-events: auto;\n opacity: 0.3;\n border: 2px solid ${(props) => props.$color};\n border-radius: 4px;\n cursor: pointer;\n\n &:hover {\n opacity: 0.5;\n border-color: ${(props) => props.$color};\n }\n`;\n\nconst AnnotationText = styled.div`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: none;\n white-space: pre-wrap;\n word-break: break-word;\n`;\n\nconst EditableText = styled.textarea`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.9);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: auto;\n border: 1px solid #fff;\n resize: none;\n font-family: inherit;\n\n &:focus {\n outline: none;\n border-color: #4CAF50;\n }\n`;\n\nconst ControlsBar = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n gap: 4px;\n padding: 4px;\n justify-content: flex-start;\n align-items: center;\n`;\n\nconst ControlButton = styled.button`\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.5);\n color: white;\n padding: 4px 8px;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n border-color: white;\n }\n\n &:active {\n background: rgba(255, 255, 255, 0.3);\n }\n`;\n\n/**\n * Configuration options passed to annotation action handlers\n */\nexport interface AnnotationActionOptions {\n /** Whether annotation endpoints are linked (moving one endpoint moves the other) */\n linkEndpoints?: boolean;\n /** Whether to continue playing after an annotation ends */\n continuousPlay?: boolean;\n /** Additional custom properties */\n [key: string]: unknown;\n}\n\nexport interface AnnotationAction {\n class?: string;\n text?: string;\n title: string;\n action: (annotation: AnnotationData, index: number, annotations: AnnotationData[], opts: AnnotationActionOptions) => void;\n}\n\nexport interface AnnotationData {\n id: string;\n start: number;\n end: number;\n lines: string[];\n language?: string;\n}\n\nexport interface AnnotationProps {\n annotation: AnnotationData;\n index: number;\n allAnnotations: AnnotationData[];\n startPosition: number; // Start position in pixels\n endPosition: number; // End position in pixels\n color?: string;\n editable?: boolean;\n controls?: AnnotationAction[];\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n annotationListConfig?: AnnotationActionOptions;\n onClick?: (annotation: AnnotationData) => void;\n}\n\nexport const Annotation: FunctionComponent<AnnotationProps> = ({\n annotation,\n index,\n allAnnotations,\n startPosition,\n endPosition,\n color = '#ff9800',\n editable = false,\n controls = [],\n onAnnotationUpdate,\n annotationListConfig,\n onClick,\n}) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editedText, setEditedText] = useState(annotation.lines.join('\\n'));\n const width = Math.max(0, endPosition - startPosition);\n\n if (width <= 0) {\n return null;\n }\n\n const handleClick = () => {\n if (onClick) {\n onClick(annotation);\n }\n };\n\n const handleDoubleClick = () => {\n if (editable) {\n setIsEditing(true);\n }\n };\n\n const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setEditedText(e.target.value);\n };\n\n const handleTextBlur = () => {\n setIsEditing(false);\n const newLines = editedText.split('\\n');\n if (newLines.join('\\n') !== annotation.lines.join('\\n')) {\n const updatedAnnotations = [...allAnnotations];\n updatedAnnotations[index] = { ...annotation, lines: newLines };\n if (onAnnotationUpdate) {\n onAnnotationUpdate(updatedAnnotations);\n }\n }\n };\n\n const handleControlClick = (control: AnnotationAction) => {\n const annotationsCopy = [...allAnnotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n if (onAnnotationUpdate) {\n onAnnotationUpdate(annotationsCopy);\n }\n };\n\n const getIconClass = (classString: string) => {\n // Convert \"fas.fa-minus\" to \"fas fa-minus\"\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <AnnotationOverlay\n $left={startPosition}\n $width={width}\n $color={color}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n >\n {controls.length > 0 && (\n <ControlsBar>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={(e) => {\n e.stopPropagation();\n handleControlClick(control);\n }}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </ControlsBar>\n )}\n {isEditing ? (\n <EditableText\n value={editedText}\n onChange={handleTextChange}\n onBlur={handleTextBlur}\n autoFocus\n onClick={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n />\n ) : (\n <AnnotationText>\n {annotation.lines.join('\\n')}\n </AnnotationText>\n )}\n </AnnotationOverlay>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { useDraggable } from '@dnd-kit/core';\nimport type { DraggableAttributes } from '@dnd-kit/core';\nimport type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';\n\ninterface WrapperProps {\n readonly $left: number;\n readonly $width: number;\n}\n\n// Wrapper positions the annotation and contains both Box and ResizeHandles as siblings\nconst Wrapper = styled.div.attrs<WrapperProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<WrapperProps>`\n position: absolute;\n top: 0;\n height: 100%;\n pointer-events: none; /* Let events pass through to children */\n`;\n\ninterface BoxProps {\n readonly $color: string;\n readonly $isActive?: boolean;\n}\n\nconst Box = styled.div<BoxProps>`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 100%;\n background: ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBackground || 'rgba(255, 200, 100, 0.95)')\n : (props.theme?.annotationBoxBackground || 'rgba(255, 255, 255, 0.85)')};\n border: ${(props) => props.$isActive ? '3px' : '2px'} solid ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBorder || '#ff9800')\n : props.$color};\n border-radius: 4px;\n cursor: pointer;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: ${(props) => props.$isActive\n ? '0 2px 8px rgba(255, 152, 0, 0.4), inset 0 0 0 1px rgba(255, 152, 0, 0.2)'\n : '0 1px 3px rgba(0, 0, 0, 0.1)'};\n\n &:hover {\n background: ${(props) => props.theme?.annotationBoxHoverBackground || 'rgba(255, 255, 255, 0.98)'};\n border-color: ${(props) => props.theme?.annotationBoxActiveBorder || '#ff9800'};\n border-width: 3px;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);\n }\n`;\n\nconst Label = styled.span`\n font-size: 12px;\n font-weight: 600;\n color: ${(props) => props.theme?.annotationLabelColor || '#2a2a2a'};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0 6px;\n letter-spacing: 0.3px;\n user-select: none;\n`;\n\ninterface ResizeHandleStyledProps {\n $position: 'left' | 'right';\n $isDragging?: boolean;\n}\n\n// ResizeHandles sit inside their annotation's bounds so adjacent annotations'\n// handles never overlap — each handle is independently grabbable.\nconst ResizeHandle = styled.div<ResizeHandleStyledProps>`\n position: absolute;\n top: 0;\n ${(props) => props.$position === 'left' ? 'left: 0' : 'right: 0'};\n width: 8px;\n height: 100%;\n cursor: ew-resize;\n z-index: 120;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.2)')\n : 'transparent'};\n border-radius: 4px;\n touch-action: none; /* Important for @dnd-kit on touch devices */\n pointer-events: auto;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 4px;\n height: 60%;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.8)')\n : (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.4)')};\n border-radius: 2px;\n opacity: ${(props) => props.$isDragging ? 1 : 0.6};\n transition: opacity 0.2s, background 0.2s;\n }\n\n &:hover {\n background: ${(props) => props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.1)'};\n }\n\n &:hover::before {\n opacity: 1;\n background: ${(props) => props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.7)'};\n }\n`;\n\nexport interface DragHandleProps {\n attributes: DraggableAttributes;\n listeners: SyntheticListenerMap | undefined;\n setActivatorNodeRef: (element: HTMLElement | null) => void;\n isDragging: boolean;\n}\n\nexport interface AnnotationBoxComponentProps {\n annotationId: string;\n annotationIndex: number;\n startPosition: number;\n endPosition: number;\n label?: string;\n color?: string;\n isActive?: boolean;\n onClick?: () => void;\n editable?: boolean; // Whether to show drag handles\n}\n\nexport const AnnotationBox: FunctionComponent<AnnotationBoxComponentProps> = ({\n annotationId,\n annotationIndex,\n startPosition,\n endPosition,\n label,\n color = '#ff9800',\n isActive = false,\n onClick,\n editable = true,\n}) => {\n const width = Math.max(0, endPosition - startPosition);\n\n // Left (start) boundary draggable\n const leftBoundaryId = `annotation-boundary-start-${annotationIndex}`;\n const {\n attributes: leftAttributes,\n listeners: leftListeners,\n setActivatorNodeRef: setLeftActivatorRef,\n isDragging: isLeftDragging,\n } = useDraggable({\n id: leftBoundaryId,\n data: { annotationId, annotationIndex, edge: 'start' as const },\n disabled: !editable,\n });\n\n // Right (end) boundary draggable\n const rightBoundaryId = `annotation-boundary-end-${annotationIndex}`;\n const {\n attributes: rightAttributes,\n listeners: rightListeners,\n setActivatorNodeRef: setRightActivatorRef,\n isDragging: isRightDragging,\n } = useDraggable({\n id: rightBoundaryId,\n data: { annotationId, annotationIndex, edge: 'end' as const },\n disabled: !editable,\n });\n\n if (width <= 0) {\n return null;\n }\n\n // Wrap @dnd-kit pointer handlers to also stop propagation\n // This prevents the ClickOverlay from capturing the event\n const createPointerDownHandler = (dndKitHandler?: (e: React.PointerEvent) => void) => {\n return (e: React.PointerEvent) => {\n e.stopPropagation();\n dndKitHandler?.(e);\n };\n };\n\n const handleHandleClick = (e: React.MouseEvent) => {\n // Prevent clicks on resize handles from bubbling to annotation box\n e.stopPropagation();\n };\n\n return (\n <Wrapper $left={startPosition} $width={width}>\n <Box\n $color={color}\n $isActive={isActive}\n onClick={onClick}\n >\n {label && <Label>{label}</Label>}\n </Box>\n {editable && (\n <ResizeHandle\n ref={setLeftActivatorRef}\n $position=\"left\"\n $isDragging={isLeftDragging}\n onClick={handleHandleClick}\n {...leftListeners}\n onPointerDown={createPointerDownHandler(leftListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...leftAttributes}\n />\n )}\n {editable && (\n <ResizeHandle\n ref={setRightActivatorRef}\n $position=\"right\"\n $isDragging={isRightDragging}\n onClick={handleHandleClick}\n {...rightListeners}\n onPointerDown={createPointerDownHandler(rightListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...rightAttributes}\n />\n )}\n </Wrapper>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n z-index: 110;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n`;\n\nconst BoxesContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationBoxesWrapperProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationBoxesWrapper: FunctionComponent<AnnotationBoxesWrapperProps> = ({\n children,\n className,\n height = 30,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0} />\n <BoxesContainer $offset={offset}>\n {children}\n </BoxesContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n font-weight: bold;\n`;\n\nconst AnnotationsContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationsTrackProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationsTrack: FunctionComponent<AnnotationsTrackProps> = ({\n children,\n className,\n height = 100,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0}>\n Annotations\n </ControlsPlaceholder>\n <AnnotationsContainer $offset={offset}>\n {children}\n </AnnotationsContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent, useRef, useEffect } from 'react';\nimport styled from 'styled-components';\nimport type { AnnotationData, AnnotationAction, AnnotationActionOptions } from './Annotation';\n\ninterface ContainerProps {\n $height?: number;\n}\n\nconst Container = styled.div<ContainerProps>`\n background: ${(props) => props.theme?.backgroundColor || '#fff'};\n ${(props) => props.$height ? `height: ${props.$height}px;` : 'max-height: 200px;'}\n overflow-y: auto;\n padding: 8px;\n`;\n\nconst AnnotationItem = styled.div<{ $isActive?: boolean }>`\n padding: 12px;\n margin-bottom: 6px;\n border-left: 4px solid ${(props) => (props.$isActive ? '#ff9800' : 'transparent')};\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.15)' : 'transparent')};\n border-radius: 4px;\n transition: all 0.2s;\n cursor: pointer;\n box-shadow: ${(props) => (props.$isActive ? '0 2px 8px rgba(255, 152, 0, 0.25), inset 0 0 0 1px rgba(255, 152, 0, 0.3)' : 'none')};\n\n &:hover {\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.2)' : props.theme?.annotationTextItemHoverBackground || 'rgba(0, 0, 0, 0.05)')};\n border-left-color: ${(props) => (props.$isActive ? '#ff9800' : props.theme?.borderColor || '#ddd')};\n }\n\n &:focus-visible {\n outline: 2px solid #ff9800;\n outline-offset: 2px;\n }\n`;\n\nconst AnnotationHeader = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n`;\n\nconst AnnotationInfo = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n`;\n\nconst AnnotationIdLabel = styled.span<{ $isEditable?: boolean }>`\n font-size: 11px;\n font-weight: 600;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n background: transparent;\n padding: 2px 6px;\n border-radius: 3px;\n min-width: 20px;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\nconst TimeRange = styled.span`\n font-size: 12px;\n font-weight: 500;\n color: ${(props) => props.theme?.textColorMuted || '#555'};\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n letter-spacing: 0.5px;\n`;\n\nconst AnnotationControls = styled.div`\n display: flex;\n gap: 6px;\n`;\n\nconst ControlButton = styled.button`\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n color: ${(props) => props.theme?.textColor || '#333'};\n padding: 4px 8px;\n font-size: 14px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n\n &:hover {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n transform: scale(1.05);\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst AnnotationTextContent = styled.div<{ $isEditable?: boolean }>`\n font-size: 14px;\n line-height: 1.6;\n color: ${(props) => props.theme?.textColor || '#2a2a2a'};\n white-space: pre-wrap;\n word-break: break-word;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n padding: ${(props) => (props.$isEditable ? '6px' : '0')};\n border-radius: 3px;\n min-height: 20px;\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\n/**\n * Props passed to the renderAnnotationItem function for custom rendering\n */\nexport interface RenderAnnotationItemProps {\n annotation: AnnotationData;\n index: number;\n isActive: boolean;\n onClick: () => void;\n formatTime: (seconds: number) => string;\n}\n\nexport interface AnnotationTextProps {\n annotations: AnnotationData[];\n activeAnnotationId?: string;\n shouldScrollToActive?: boolean;\n /** Where to position the active annotation when scrolling: 'center', 'start', 'end', or 'nearest'. Defaults to 'center'. */\n scrollActivePosition?: ScrollLogicalPosition;\n /** Which scrollable containers to scroll: 'nearest' (only the annotation list) or 'all' (including viewport). Defaults to 'nearest'. */\n scrollActiveContainer?: 'nearest' | 'all';\n editable?: boolean;\n controls?: AnnotationAction[];\n annotationListConfig?: AnnotationActionOptions;\n height?: number;\n onAnnotationClick?: (annotation: AnnotationData) => void;\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n /**\n * Custom render function for annotation items.\n * When provided, completely replaces the default annotation item rendering.\n * Use this to customize the appearance of each annotation in the list.\n */\n renderAnnotationItem?: (props: RenderAnnotationItemProps) => React.ReactNode;\n}\n\nconst AnnotationTextComponent: FunctionComponent<AnnotationTextProps> = ({\n annotations,\n activeAnnotationId,\n shouldScrollToActive = false,\n scrollActivePosition = 'center',\n scrollActiveContainer = 'nearest',\n editable = false,\n controls = [],\n annotationListConfig,\n height,\n onAnnotationClick,\n onAnnotationUpdate,\n renderAnnotationItem,\n}) => {\n const activeAnnotationRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const prevActiveIdRef = useRef<string | undefined>(undefined);\n\n // Track component renders and scroll position\n useEffect(() => {\n // Render tracking removed\n });\n\n // Track scroll changes\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n // Scroll tracking removed\n };\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, []);\n\n // Auto-scroll to active annotation when it changes\n useEffect(() => {\n // Only scroll if parent says we should (prevents scrolling on remount after pause)\n if (activeAnnotationId && activeAnnotationRef.current && shouldScrollToActive) {\n activeAnnotationRef.current.scrollIntoView({\n behavior: 'smooth',\n block: scrollActivePosition,\n container: scrollActiveContainer,\n } as ScrollIntoViewOptions);\n }\n\n prevActiveIdRef.current = activeAnnotationId;\n }, [activeAnnotationId, shouldScrollToActive, scrollActivePosition, scrollActiveContainer]);\n\n const formatTime = (seconds: number): string => {\n if (isNaN(seconds) || !isFinite(seconds)) {\n return '0:00.000';\n }\n const mins = Math.floor(seconds / 60);\n const secs = (seconds % 60).toFixed(3);\n return `${mins}:${secs.padStart(6, '0')}`;\n };\n\n const handleTextEdit = (index: number, newText: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n lines: newText.split('\\n'),\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleIdEdit = (index: number, newId: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const trimmedId = newId.trim();\n if (!trimmedId) return; // Don't allow empty IDs\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n id: trimmedId,\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleControlClick = (control: AnnotationAction, annotation: AnnotationData, index: number) => {\n if (!onAnnotationUpdate) return;\n\n const annotationsCopy = [...annotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n onAnnotationUpdate(annotationsCopy);\n };\n\n const getIconClass = (classString: string) => {\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <Container ref={containerRef} $height={height}>\n {annotations.map((annotation, index) => {\n const isActive = annotation.id === activeAnnotationId;\n const handleClick = () => onAnnotationClick?.(annotation);\n\n // Use custom render function if provided\n if (renderAnnotationItem) {\n return (\n <div\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n >\n {renderAnnotationItem({\n annotation,\n index,\n isActive,\n onClick: handleClick,\n formatTime,\n })}\n </div>\n );\n }\n\n // Default rendering\n return (\n <AnnotationItem\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n $isActive={isActive}\n onClick={handleClick}\n >\n <AnnotationHeader>\n <AnnotationInfo>\n <AnnotationIdLabel\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleIdEdit(index, e.currentTarget.textContent || '')}\n >\n {annotation.id}\n </AnnotationIdLabel>\n <TimeRange>\n {formatTime(annotation.start)} - {formatTime(annotation.end)}\n </TimeRange>\n </AnnotationInfo>\n {controls.length > 0 && (\n <AnnotationControls onClick={(e) => e.stopPropagation()}>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={() => handleControlClick(control, annotation, index)}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </AnnotationControls>\n )}\n </AnnotationHeader>\n <AnnotationTextContent\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleTextEdit(index, e.currentTarget.textContent || '')}\n >\n {annotation.lines.join('\\n')}\n </AnnotationTextContent>\n </AnnotationItem>\n );\n })}\n </Container>\n );\n};\n\n// Memoize to prevent unnecessary remounting when parent re-renders\nexport const AnnotationText = React.memo(AnnotationTextComponent);\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface ContinuousPlayCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling continuous play of annotations.\n * When enabled, playback continues from one annotation to the next without stopping.\n */\nexport const ContinuousPlayCheckbox: React.FC<ContinuousPlayCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"continuous-play\"\n className=\"continuous-play\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"continuous-play\">Continuous Play</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface LinkEndpointsCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling linked endpoints between annotations.\n * When enabled, the end time of one annotation is automatically linked to the start time of the next.\n */\nexport const LinkEndpointsCheckbox: React.FC<LinkEndpointsCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"link-endpoints\"\n className=\"link-endpoints\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"link-endpoints\">Link Endpoints</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface EditableCheckboxProps {\n checked: boolean;\n onChange: (enabled: boolean) => void;\n className?: string;\n}\n\nexport const EditableCheckbox: React.FC<EditableCheckboxProps> = ({\n checked,\n onChange,\n className,\n}) => {\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"editable-annotations\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n />\n <BaseCheckboxLabel htmlFor=\"editable-annotations\">Editable Annotations</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport styled from 'styled-components';\nimport { serializeAeneas } from '../parsers/aeneas';\nimport type { Annotation } from '../types';\n\nconst StyledButton = styled.button`\n padding: 0.5rem 1rem;\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n color: ${(props) => props.theme?.textColor || '#333'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n border-radius: ${(props) => props.theme?.borderRadius || '4px'};\n cursor: pointer;\n font-family: ${(props) => props.theme?.fontFamily || 'inherit'};\n font-size: ${(props) => props.theme?.fontSize || '14px'};\n font-weight: 500;\n transition: all 0.15s ease;\n\n &:hover:not(:disabled) {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 2px ${(props) => props.theme?.inputFocusBorder || '#007bff'}44;\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n`;\n\nexport interface DownloadAnnotationsButtonProps {\n annotations: Annotation[];\n filename?: string;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport const DownloadAnnotationsButton: React.FC<DownloadAnnotationsButtonProps> = ({\n annotations,\n filename = 'annotations.json',\n disabled = false,\n className,\n children = 'Download JSON',\n}) => {\n const handleDownload = () => {\n if (annotations.length === 0) {\n return;\n }\n\n // Serialize annotations to Aeneas JSON format\n const jsonData = annotations.map(annotation => serializeAeneas(annotation));\n const jsonString = JSON.stringify(jsonData, null, 2);\n\n // Create a blob and download link\n const blob = new Blob([jsonString], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n\n // Trigger download\n document.body.appendChild(link);\n link.click();\n\n // Cleanup\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n };\n\n return (\n <StyledButton\n onClick={handleDownload}\n disabled={disabled || annotations.length === 0}\n className={className}\n title={annotations.length === 0 ? 'No annotations to download' : 'Download the annotations as JSON'}\n >\n {children}\n </StyledButton>\n );\n};\n","import { useState, useCallback } from 'react';\nimport type { Annotation, AnnotationListOptions } from '../types';\n\nconst LINK_THRESHOLD = 0.01; // Consider edges \"linked\" if within 10ms\n\nexport interface UseAnnotationControlsOptions {\n initialContinuousPlay?: boolean;\n initialLinkEndpoints?: boolean;\n}\n\nexport interface AnnotationUpdateParams {\n annotationIndex: number;\n newTime: number;\n isDraggingStart: boolean;\n annotations: Annotation[];\n duration: number;\n linkEndpoints: boolean;\n}\n\nexport interface UseAnnotationControlsReturn {\n continuousPlay: boolean;\n linkEndpoints: boolean;\n setContinuousPlay: (value: boolean) => void;\n setLinkEndpoints: (value: boolean) => void;\n updateAnnotationBoundaries: (params: AnnotationUpdateParams) => Annotation[];\n}\n\n/**\n * Hook for managing annotation control state and boundary logic.\n * Handles continuous play mode and linked endpoints behavior.\n */\nexport const useAnnotationControls = (\n options: UseAnnotationControlsOptions = {}\n): UseAnnotationControlsReturn => {\n const {\n initialContinuousPlay = false,\n initialLinkEndpoints = true,\n } = options;\n\n const [continuousPlay, setContinuousPlay] = useState(initialContinuousPlay);\n const [linkEndpoints, setLinkEndpoints] = useState(initialLinkEndpoints);\n\n /**\n * Updates annotation boundaries based on drag operations.\n * Handles linked endpoints and collision detection.\n * Note: linkEndpoints is passed as a parameter to ensure it uses the current value from context.\n */\n const updateAnnotationBoundaries = useCallback(\n ({\n annotationIndex,\n newTime,\n isDraggingStart,\n annotations,\n duration,\n linkEndpoints: shouldLinkEndpoints,\n }: AnnotationUpdateParams): Annotation[] => {\n const updatedAnnotations = [...annotations];\n const annotation = annotations[annotationIndex];\n\n if (isDraggingStart) {\n // Dragging start edge\n const constrainedStart = Math.min(annotation.end - 0.1, Math.max(0, newTime));\n const delta = constrainedStart - annotation.start;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n start: constrainedStart,\n };\n\n if (shouldLinkEndpoints && annotationIndex > 0) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const prevAnnotation = updatedAnnotations[annotationIndex - 1];\n\n if (Math.abs(prevAnnotation.end - annotation.start) < LINK_THRESHOLD) {\n // Already linked: move previous annotation's end together with this start\n updatedAnnotations[annotationIndex - 1] = {\n ...prevAnnotation,\n end: Math.max(prevAnnotation.start + 0.1, prevAnnotation.end + delta),\n };\n } else if (constrainedStart <= prevAnnotation.end) {\n // Dragged past previous annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n start: prevAnnotation.end,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex > 0 && constrainedStart < updatedAnnotations[annotationIndex - 1].end) {\n // Collision detection: push previous annotation's end back\n updatedAnnotations[annotationIndex - 1] = {\n ...updatedAnnotations[annotationIndex - 1],\n end: constrainedStart,\n };\n }\n } else {\n // Dragging end edge\n const constrainedEnd = Math.max(annotation.start + 0.1, Math.min(newTime, duration));\n const delta = constrainedEnd - annotation.end;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n end: constrainedEnd,\n };\n\n if (shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n if (Math.abs(nextAnnotation.start - annotation.end) < LINK_THRESHOLD) {\n // Already linked: move next annotation's start together with this end\n const newStart = nextAnnotation.start + delta;\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: Math.min(nextAnnotation.end - 0.1, newStart),\n };\n\n // Cascade linked endpoints\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (Math.abs(next.start - current.end) < LINK_THRESHOLD) {\n const nextDelta = current.end - annotations[currentIndex].end;\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: Math.min(next.end - 0.1, next.start + nextDelta),\n };\n currentIndex++;\n } else {\n break; // No more linked endpoints\n }\n }\n } else if (constrainedEnd >= nextAnnotation.start) {\n // Dragged past next annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n end: nextAnnotation.start,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1 && constrainedEnd > updatedAnnotations[annotationIndex + 1].start) {\n // Collision detection: push next annotation's start forward\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: constrainedEnd,\n };\n\n // Cascade collisions\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (current.end > next.start) {\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: current.end,\n };\n currentIndex++;\n } else {\n break; // No more collisions\n }\n }\n }\n }\n\n return updatedAnnotations;\n },\n []\n );\n\n return {\n continuousPlay,\n linkEndpoints,\n setContinuousPlay,\n setLinkEndpoints,\n updateAnnotationBoundaries,\n };\n};\n"],"mappings":";AAUO,SAAS,YAAY,MAAkC;AAC5D,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,OAAO,WAAW,KAAK,KAAK;AAAA,IAC5B,KAAK,WAAW,KAAK,GAAG;AAAA,IACxB,OAAO,KAAK;AAAA,IACZ,MAAM,KAAK;AAAA,EACb;AACF;AAEO,SAAS,gBAAgB,YAAwC;AACtE,SAAO;AAAA,IACL,IAAI,WAAW;AAAA,IACf,OAAO,WAAW,MAAM,QAAQ,CAAC;AAAA,IACjC,KAAK,WAAW,IAAI,QAAQ,CAAC;AAAA,IAC7B,OAAO,WAAW;AAAA,IAClB,UAAU,WAAW,QAAQ;AAAA,EAC/B;AACF;;;AC5BA,SAAmC,gBAAgB;AACnD,OAAO,YAAY;AAoNf,SAkByC,KAlBzC;AA5MJ,IAAM,oBAAoB,OAAO,IAAI,MAA8B,CAAC,WAAW;AAAA,EAC7E,OAAO;AAAA,IACL,MAAM,GAAG,MAAM,KAAK;AAAA,IACpB,OAAO,GAAG,MAAM,MAAM;AAAA,EACxB;AACF,EAAE;AAAA;AAAA;AAAA,gBAGc,CAAC,UAAU,MAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,sBAKjB,CAAC,UAAU,MAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAMzB,CAAC,UAAU,MAAM,MAAM;AAAA;AAAA;AAI3C,IAAM,iBAAiB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkB9B,IAAM,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsB5B,IAAM,cAAc,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAa3B,IAAM,gBAAgB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiEtB,IAAM,aAAiD,CAAC;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,WAAW,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,WAAW,MAAM,KAAK,IAAI,CAAC;AACxE,QAAM,QAAQ,KAAK,IAAI,GAAG,cAAc,aAAa;AAErD,MAAI,SAAS,GAAG;AACd,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,MAAM;AACxB,QAAI,SAAS;AACX,cAAQ,UAAU;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,oBAAoB,MAAM;AAC9B,QAAI,UAAU;AACZ,mBAAa,IAAI;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,mBAAmB,CAAC,MAA8C;AACtE,kBAAc,EAAE,OAAO,KAAK;AAAA,EAC9B;AAEA,QAAM,iBAAiB,MAAM;AAC3B,iBAAa,KAAK;AAClB,UAAM,WAAW,WAAW,MAAM,IAAI;AACtC,QAAI,SAAS,KAAK,IAAI,MAAM,WAAW,MAAM,KAAK,IAAI,GAAG;AACvD,YAAM,qBAAqB,CAAC,GAAG,cAAc;AAC7C,yBAAmB,KAAK,IAAI,EAAE,GAAG,YAAY,OAAO,SAAS;AAC7D,UAAI,oBAAoB;AACtB,2BAAmB,kBAAkB;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,qBAAqB,CAAC,YAA8B;AACxD,UAAM,kBAAkB,CAAC,GAAG,cAAc;AAC1C,YAAQ,OAAO,gBAAgB,KAAK,GAAG,OAAO,iBAAiB,wBAAwB,CAAC,CAAC;AACzF,QAAI,oBAAoB;AACtB,yBAAmB,eAAe;AAAA,IACpC;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,gBAAwB;AAE5C,WAAO,YAAY,QAAQ,OAAO,GAAG;AAAA,EACvC;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,eAAe;AAAA,MAEd;AAAA,iBAAS,SAAS,KACjB,oBAAC,eACE,mBAAS,IAAI,CAAC,SAAS,QACtB;AAAA,UAAC;AAAA;AAAA,YAEC,OAAO,QAAQ;AAAA,YACf,SAAS,CAAC,MAAM;AACd,gBAAE,gBAAgB;AAClB,iCAAmB,OAAO;AAAA,YAC5B;AAAA,YAEC,kBAAQ,OAAO,QAAQ,OAAO,oBAAC,OAAE,WAAW,aAAa,QAAQ,SAAS,EAAE,GAAG;AAAA;AAAA,UAP3E;AAAA,QAQP,CACD,GACH;AAAA,QAED,YACC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU;AAAA,YACV,QAAQ;AAAA,YACR,WAAS;AAAA,YACT,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,YAClC,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA;AAAA,QAC1C,IAEA,oBAAC,kBACE,qBAAW,MAAM,KAAK,IAAI,GAC7B;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;AC3PA,OAAOA,aAAY;AACnB,SAAS,oBAAoB;AAoMzB,SAMc,OAAAC,MANd,QAAAC,aAAA;AA1LJ,IAAM,UAAUF,QAAO,IAAI,MAAoB,CAAC,WAAW;AAAA,EACzD,OAAO;AAAA,IACL,MAAM,GAAG,MAAM,KAAK;AAAA,IACpB,OAAO,GAAG,MAAM,MAAM;AAAA,EACxB;AACF,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAYF,IAAM,MAAMA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAMH,CAAC,UAAU,MAAM,YAC1B,MAAM,OAAO,iCAAiC,8BAC9C,MAAM,OAAO,2BAA2B,2BAA4B;AAAA,YAC/D,CAAC,UAAU,MAAM,YAAY,QAAQ,KAAK,UAAU,CAAC,UAAU,MAAM,YAC1E,MAAM,OAAO,6BAA6B,YAC3C,MAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBASF,CAAC,UAAU,MAAM,YAC3B,6EACA,8BAA8B;AAAA;AAAA;AAAA,kBAGlB,CAAC,UAAU,MAAM,OAAO,gCAAgC,2BAA2B;AAAA,oBACjF,CAAC,UAAU,MAAM,OAAO,6BAA6B,SAAS;AAAA;AAAA;AAAA;AAAA;AAMlF,IAAM,QAAQA,QAAO;AAAA;AAAA;AAAA,WAGV,CAAC,UAAU,MAAM,OAAO,wBAAwB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBpE,IAAM,eAAeA,QAAO;AAAA;AAAA;AAAA,IAGxB,CAAC,UAAU,MAAM,cAAc,SAAS,YAAY,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,gBAKlD,CAAC,UAAU,MAAM,cAC1B,MAAM,OAAO,+BAA+B,uBAC7C,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAaD,CAAC,UAAU,MAAM,cAC1B,MAAM,OAAO,qCAAqC,uBAClD,MAAM,OAAO,+BAA+B,oBAAqB;AAAA;AAAA,eAE3D,CAAC,UAAU,MAAM,cAAc,IAAI,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKnC,CAAC,UAAU,MAAM,OAAO,+BAA+B,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,kBAK3E,CAAC,UAAU,MAAM,OAAO,qCAAqC,oBAAoB;AAAA;AAAA;AAuB5F,IAAM,gBAAgE,CAAC;AAAA,EAC5E;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,WAAW;AAAA,EACX;AAAA,EACA,WAAW;AACb,MAAM;AACJ,QAAM,QAAQ,KAAK,IAAI,GAAG,cAAc,aAAa;AAGrD,QAAM,iBAAiB,6BAA6B,eAAe;AACnE,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,qBAAqB;AAAA,IACrB,YAAY;AAAA,EACd,IAAI,aAAa;AAAA,IACf,IAAI;AAAA,IACJ,MAAM,EAAE,cAAc,iBAAiB,MAAM,QAAiB;AAAA,IAC9D,UAAU,CAAC;AAAA,EACb,CAAC;AAGD,QAAM,kBAAkB,2BAA2B,eAAe;AAClE,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,qBAAqB;AAAA,IACrB,YAAY;AAAA,EACd,IAAI,aAAa;AAAA,IACf,IAAI;AAAA,IACJ,MAAM,EAAE,cAAc,iBAAiB,MAAM,MAAe;AAAA,IAC5D,UAAU,CAAC;AAAA,EACb,CAAC;AAED,MAAI,SAAS,GAAG;AACd,WAAO;AAAA,EACT;AAIA,QAAM,2BAA2B,CAAC,kBAAoD;AACpF,WAAO,CAAC,MAA0B;AAChC,QAAE,gBAAgB;AAClB,sBAAgB,CAAC;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,oBAAoB,CAAC,MAAwB;AAEjD,MAAE,gBAAgB;AAAA,EACpB;AAEA,SACE,gBAAAE,MAAC,WAAQ,OAAO,eAAe,QAAQ,OACrC;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,WAAW;AAAA,QACX;AAAA,QAEC,mBAAS,gBAAAA,KAAC,SAAO,iBAAM;AAAA;AAAA,IAC1B;AAAA,IACC,YACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAU;AAAA,QACV,aAAa;AAAA,QACb,SAAS;AAAA,QACR,GAAG;AAAA,QACJ,eAAe,yBAAyB,eAAe,aAA8D;AAAA,QACpH,GAAG;AAAA;AAAA,IACN;AAAA,IAED,YACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAU;AAAA,QACV,aAAa;AAAA,QACb,SAAS;AAAA,QACR,GAAG;AAAA,QACJ,eAAe,yBAAyB,gBAAgB,aAA8D;AAAA,QACrH,GAAG;AAAA;AAAA,IACN;AAAA,KAEJ;AAEJ;;;ACrOA,OAAOE,aAAY;AACnB,SAAS,uBAAuB;AAwD5B,SAME,OAAAC,MANF,QAAAC,aAAA;AAhDJ,IAAM,YAAYF,QAAO,IAAI,MAAsB,CAAC,WAAW;AAAA,EAC7D,OAAO;AAAA,IACL,QAAQ,GAAG,MAAM,OAAO;AAAA,EAC1B;AACF,EAAE;AAAA;AAAA;AAAA,IAGE,CAAC,UAAU,MAAM,WAAW,UAAa,UAAU,MAAM,MAAM,KAAK;AAAA;AAAA;AAAA;AAKxE,IAAM,sBAAsBA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,WAKxB,CAAC,UAAU,MAAM,aAAa;AAAA;AAAA;AAAA;AAKzC,IAAM,iBAAiBA,QAAO;AAAA;AAAA;AAAA,kBAGZ,CAAC,UAAU,MAAM,WAAW,CAAC;AAAA;AAWxC,IAAM,yBAAyE,CAAC;AAAA,EACrF;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,SAAS;AAAA,EACT;AACF,MAAM;AACJ,QAAM;AAAA,IACJ,UAAU,EAAE,MAAM,OAAO,aAAa;AAAA,EACxC,IAAI,gBAAgB;AAEpB,SACE,gBAAAE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAS;AAAA,MACT,eAAe,OAAO,eAAe;AAAA,MACrC,QAAQ;AAAA,MAER;AAAA,wBAAAD,KAAC,uBAAoB,eAAe,OAAO,eAAe,GAAG;AAAA,QAC7D,gBAAAA,KAAC,kBAAe,SAAS,QACtB,UACH;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACrEA,OAAOE,aAAY;AACnB,SAAS,mBAAAC,wBAAuB;AA6D5B,SAME,OAAAC,MANF,QAAAC,aAAA;AArDJ,IAAMC,aAAYJ,QAAO,IAAI,MAAsB,CAAC,WAAW;AAAA,EAC7D,OAAO;AAAA,IACL,QAAQ,GAAG,MAAM,OAAO;AAAA,EAC1B;AACF,EAAE;AAAA;AAAA;AAAA,IAGE,CAAC,UAAU,MAAM,WAAW,UAAa,UAAU,MAAM,MAAM,KAAK;AAAA;AAAA;AAIxE,IAAMK,uBAAsBL,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,WAKxB,CAAC,UAAU,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAO9B,CAAC,UAAU,MAAM,OAAO,kBAAkB,MAAM;AAAA;AAAA;AAI3D,IAAM,uBAAuBA,QAAO;AAAA;AAAA;AAAA,kBAGlB,CAAC,UAAU,MAAM,WAAW,CAAC;AAAA;AAWxC,IAAM,mBAA6D,CAAC;AAAA,EACzE;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,SAAS;AAAA,EACT;AACF,MAAM;AACJ,QAAM;AAAA,IACJ,UAAU,EAAE,MAAM,OAAO,aAAa;AAAA,EACxC,IAAIC,iBAAgB;AAEpB,SACE,gBAAAE;AAAA,IAACC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,SAAS;AAAA,MACT,eAAe,OAAO,eAAe;AAAA,MACrC,QAAQ;AAAA,MAER;AAAA,wBAAAF,KAACG,sBAAA,EAAoB,eAAe,OAAO,eAAe,GAAG,yBAE7D;AAAA,QACA,gBAAAH,KAAC,wBAAqB,SAAS,QAC5B,UACH;AAAA;AAAA;AAAA,EACF;AAEJ;;;AC7EA,OAAOI,UAA4B,QAAQ,iBAAiB;AAC5D,OAAOC,aAAY;AA6PP,gBAAAC,MAiCE,QAAAC,aAjCF;AAtPZ,IAAMC,aAAYH,QAAO;AAAA,gBACT,CAAC,UAAU,MAAM,OAAO,mBAAmB,MAAM;AAAA,IAC7D,CAAC,UAAU,MAAM,UAAU,WAAW,MAAM,OAAO,QAAQ,oBAAoB;AAAA;AAAA;AAAA;AAKnF,IAAM,iBAAiBA,QAAO;AAAA;AAAA;AAAA,2BAGH,CAAC,UAAW,MAAM,YAAY,YAAY,aAAc;AAAA,gBACnE,CAAC,UAAW,MAAM,YAAY,4BAA4B,aAAc;AAAA;AAAA;AAAA;AAAA,gBAIxE,CAAC,UAAW,MAAM,YAAY,8EAA8E,MAAO;AAAA;AAAA;AAAA,kBAGjH,CAAC,UAAW,MAAM,YAAY,2BAA2B,MAAM,OAAO,qCAAqC,qBAAsB;AAAA,yBAC1H,CAAC,UAAW,MAAM,YAAY,YAAY,MAAM,OAAO,eAAe,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAStG,IAAM,mBAAmBA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAOhC,IAAM,iBAAiBA,QAAO;AAAA;AAAA;AAAA;AAAA;AAM9B,IAAM,oBAAoBA,QAAO;AAAA;AAAA;AAAA,WAGtB,CAAC,UAAU,MAAM,OAAO,kBAAkB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,aAK9C,CAAC,UAAW,MAAM,cAAc,cAAc,MAAM,OAAO,eAAe,MAAM,KAAK,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQzG,IAAM,YAAYA,QAAO;AAAA;AAAA;AAAA,WAGd,CAAC,UAAU,MAAM,OAAO,kBAAkB,MAAM;AAAA;AAAA;AAAA;AAK3D,IAAM,qBAAqBA,QAAO;AAAA;AAAA;AAAA;AAKlC,IAAMI,iBAAgBJ,QAAO;AAAA,gBACb,CAAC,UAAU,MAAM,OAAO,gBAAgB,SAAS;AAAA,sBAC3C,CAAC,UAAU,MAAM,OAAO,eAAe,MAAM;AAAA,WACxD,CAAC,UAAU,MAAM,OAAO,aAAa,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAQpC,CAAC,UAAU,MAAM,OAAO,mBAAmB,SAAS;AAAA,oBAClD,CAAC,UAAU,MAAM,OAAO,kBAAkB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASpE,IAAM,wBAAwBA,QAAO;AAAA;AAAA;AAAA,WAG1B,CAAC,UAAU,MAAM,OAAO,aAAa,SAAS;AAAA;AAAA;AAAA,aAG5C,CAAC,UAAW,MAAM,cAAc,cAAc,MAAM,OAAO,eAAe,MAAM,KAAK,MAAO;AAAA,aAC5F,CAAC,UAAW,MAAM,cAAc,QAAQ,GAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2CzD,IAAM,0BAAkE,CAAC;AAAA,EACvE;AAAA,EACA;AAAA,EACA,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,WAAW;AAAA,EACX,WAAW,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,sBAAsB,OAAuB,IAAI;AACvD,QAAM,eAAe,OAAuB,IAAI;AAChD,QAAM,kBAAkB,OAA2B,MAAS;AAG5D,YAAU,MAAM;AAAA,EAEhB,CAAC;AAGD,YAAU,MAAM;AACd,UAAM,YAAY,aAAa;AAC/B,QAAI,CAAC,UAAW;AAEhB,UAAM,eAAe,MAAM;AAAA,IAE3B;AAEA,cAAU,iBAAiB,UAAU,YAAY;AACjD,WAAO,MAAM,UAAU,oBAAoB,UAAU,YAAY;AAAA,EACnE,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AAEd,QAAI,sBAAsB,oBAAoB,WAAW,sBAAsB;AAC7E,0BAAoB,QAAQ,eAAe;AAAA,QACzC,UAAU;AAAA,QACV,OAAO;AAAA,QACP,WAAW;AAAA,MACb,CAA0B;AAAA,IAC5B;AAEA,oBAAgB,UAAU;AAAA,EAC5B,GAAG,CAAC,oBAAoB,sBAAsB,sBAAsB,qBAAqB,CAAC;AAE1F,QAAM,aAAa,CAAC,YAA4B;AAC9C,QAAI,MAAM,OAAO,KAAK,CAAC,SAAS,OAAO,GAAG;AACxC,aAAO;AAAA,IACT;AACA,UAAM,OAAO,KAAK,MAAM,UAAU,EAAE;AACpC,UAAM,QAAQ,UAAU,IAAI,QAAQ,CAAC;AACrC,WAAO,GAAG,IAAI,IAAI,KAAK,SAAS,GAAG,GAAG,CAAC;AAAA,EACzC;AAEA,QAAM,iBAAiB,CAAC,OAAe,YAAoB;AACzD,QAAI,CAAC,YAAY,CAAC,mBAAoB;AAEtC,UAAM,qBAAqB,CAAC,GAAG,WAAW;AAC1C,uBAAmB,KAAK,IAAI;AAAA,MAC1B,GAAG,mBAAmB,KAAK;AAAA,MAC3B,OAAO,QAAQ,MAAM,IAAI;AAAA,IAC3B;AACA,uBAAmB,kBAAkB;AAAA,EACvC;AAEA,QAAM,eAAe,CAAC,OAAe,UAAkB;AACrD,QAAI,CAAC,YAAY,CAAC,mBAAoB;AAEtC,UAAM,YAAY,MAAM,KAAK;AAC7B,QAAI,CAAC,UAAW;AAEhB,UAAM,qBAAqB,CAAC,GAAG,WAAW;AAC1C,uBAAmB,KAAK,IAAI;AAAA,MAC1B,GAAG,mBAAmB,KAAK;AAAA,MAC3B,IAAI;AAAA,IACN;AACA,uBAAmB,kBAAkB;AAAA,EACvC;AAEA,QAAM,qBAAqB,CAAC,SAA2B,YAA4B,UAAkB;AACnG,QAAI,CAAC,mBAAoB;AAEzB,UAAM,kBAAkB,CAAC,GAAG,WAAW;AACvC,YAAQ,OAAO,gBAAgB,KAAK,GAAG,OAAO,iBAAiB,wBAAwB,CAAC,CAAC;AACzF,uBAAmB,eAAe;AAAA,EACpC;AAEA,QAAM,eAAe,CAAC,gBAAwB;AAC5C,WAAO,YAAY,QAAQ,OAAO,GAAG;AAAA,EACvC;AAEA,SACE,gBAAAC,KAACE,YAAA,EAAU,KAAK,cAAc,SAAS,QACpC,sBAAY,IAAI,CAAC,YAAY,UAAU;AACtC,UAAM,WAAW,WAAW,OAAO;AACnC,UAAM,cAAc,MAAM,oBAAoB,UAAU;AAGxD,QAAI,sBAAsB;AACxB,aACE,gBAAAF;AAAA,QAAC;AAAA;AAAA,UAEC,KAAK,WAAW,sBAAsB;AAAA,UAErC,+BAAqB;AAAA,YACpB;AAAA,YACA;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT;AAAA,UACF,CAAC;AAAA;AAAA,QATI,WAAW;AAAA,MAUlB;AAAA,IAEJ;AAGA,WACA,gBAAAC;AAAA,MAAC;AAAA;AAAA,QAEC,KAAK,WAAW,sBAAsB;AAAA,QACtC,WAAW;AAAA,QACX,SAAS;AAAA,QAET;AAAA,0BAAAA,MAAC,oBACC;AAAA,4BAAAA,MAAC,kBACC;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,aAAa;AAAA,kBACb,iBAAiB;AAAA,kBACjB,gCAA8B;AAAA,kBAC9B,QAAQ,CAAC,MAAM,aAAa,OAAO,EAAE,cAAc,eAAe,EAAE;AAAA,kBAEnE,qBAAW;AAAA;AAAA,cACd;AAAA,cACA,gBAAAC,MAAC,aACE;AAAA,2BAAW,WAAW,KAAK;AAAA,gBAAE;AAAA,gBAAI,WAAW,WAAW,GAAG;AAAA,iBAC7D;AAAA,eACF;AAAA,YACC,SAAS,SAAS,KACjB,gBAAAD,KAAC,sBAAmB,SAAS,CAAC,MAAM,EAAE,gBAAgB,GACnD,mBAAS,IAAI,CAAC,SAAS,QACtB,gBAAAA;AAAA,cAACG;AAAA,cAAA;AAAA,gBAEC,OAAO,QAAQ;AAAA,gBACf,SAAS,MAAM,mBAAmB,SAAS,YAAY,KAAK;AAAA,gBAE3D,kBAAQ,OAAO,QAAQ,OAAO,gBAAAH,KAAC,OAAE,WAAW,aAAa,QAAQ,SAAS,EAAE,GAAG;AAAA;AAAA,cAJ3E;AAAA,YAKP,CACD,GACH;AAAA,aAEJ;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,aAAa;AAAA,cACb,iBAAiB;AAAA,cACjB,gCAA8B;AAAA,cAC9B,QAAQ,CAAC,MAAM,eAAe,OAAO,EAAE,cAAc,eAAe,EAAE;AAAA,cAErE,qBAAW,MAAM,KAAK,IAAI;AAAA;AAAA,UAC7B;AAAA;AAAA;AAAA,MAxCK,WAAW;AAAA,IAyClB;AAAA,EAEF,CAAC,GACH;AAEJ;AAGO,IAAMI,kBAAiBN,OAAM,KAAK,uBAAuB;;;AChUhE,SAAS,qBAAqB,cAAc,yBAAyB;AAwBjE,SACE,OAAAO,MADF,QAAAC,aAAA;AAXG,IAAM,yBAAgE,CAAC;AAAA,EAC5E;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AACF,MAAM;AACJ,QAAM,eAAe,CAAC,MAA2C;AAC/D,aAAS,EAAE,OAAO,OAAO;AAAA,EAC3B;AAEA,SACE,gBAAAA,MAAC,uBAAoB,WACnB;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,IAAG;AAAA,QACH,WAAU;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV;AAAA;AAAA,IACF;AAAA,IACA,gBAAAA,KAAC,qBAAkB,SAAQ,mBAAkB,6BAAe;AAAA,KAC9D;AAEJ;;;ACpCA,SAAS,uBAAAE,sBAAqB,gBAAAC,eAAc,qBAAAC,0BAAyB;AAwBjE,SACE,OAAAC,MADF,QAAAC,aAAA;AAXG,IAAM,wBAA8D,CAAC;AAAA,EAC1E;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AACF,MAAM;AACJ,QAAM,eAAe,CAAC,MAA2C;AAC/D,aAAS,EAAE,OAAO,OAAO;AAAA,EAC3B;AAEA,SACE,gBAAAA,MAACJ,sBAAA,EAAoB,WACnB;AAAA,oBAAAG;AAAA,MAACF;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,IAAG;AAAA,QACH,WAAU;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV;AAAA;AAAA,IACF;AAAA,IACA,gBAAAE,KAACD,oBAAA,EAAkB,SAAQ,kBAAiB,4BAAc;AAAA,KAC5D;AAEJ;;;ACpCA,SAAS,uBAAAG,sBAAqB,gBAAAC,eAAc,qBAAAC,0BAAyB;AAcjE,SACE,OAAAC,MADF,QAAAC,aAAA;AANG,IAAM,mBAAoD,CAAC;AAAA,EAChE;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,SACE,gBAAAA,MAACJ,sBAAA,EAAoB,WACnB;AAAA,oBAAAG;AAAA,MAACF;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,IAAG;AAAA,QACH;AAAA,QACA,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,OAAO;AAAA;AAAA,IAC5C;AAAA,IACA,gBAAAE,KAACD,oBAAA,EAAkB,SAAQ,wBAAuB,kCAAoB;AAAA,KACxE;AAEJ;;;ACxBA,OAAOG,aAAY;AAyEf,gBAAAC,YAAA;AArEJ,IAAM,eAAeC,QAAO;AAAA;AAAA,gBAEZ,CAAC,UAAU,MAAM,OAAO,gBAAgB,SAAS;AAAA,WACtD,CAAC,UAAU,MAAM,OAAO,aAAa,MAAM;AAAA,sBAChC,CAAC,UAAU,MAAM,OAAO,eAAe,MAAM;AAAA,mBAChD,CAAC,UAAU,MAAM,OAAO,gBAAgB,KAAK;AAAA;AAAA,iBAE/C,CAAC,UAAU,MAAM,OAAO,cAAc,SAAS;AAAA,eACjD,CAAC,UAAU,MAAM,OAAO,YAAY,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKvC,CAAC,UAAU,MAAM,OAAO,mBAAmB,SAAS;AAAA,oBAClD,CAAC,UAAU,MAAM,OAAO,kBAAkB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,4BAKxC,CAAC,UAAU,MAAM,OAAO,oBAAoB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiB1E,IAAM,4BAAsE,CAAC;AAAA,EAClF;AAAA,EACA,WAAW;AAAA,EACX,WAAW;AAAA,EACX;AAAA,EACA,WAAW;AACb,MAAM;AACJ,QAAM,iBAAiB,MAAM;AAC3B,QAAI,YAAY,WAAW,GAAG;AAC5B;AAAA,IACF;AAGA,UAAM,WAAW,YAAY,IAAI,gBAAc,gBAAgB,UAAU,CAAC;AAC1E,UAAM,aAAa,KAAK,UAAU,UAAU,MAAM,CAAC;AAGnD,UAAM,OAAO,IAAI,KAAK,CAAC,UAAU,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAChE,UAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,UAAM,OAAO,SAAS,cAAc,GAAG;AACvC,SAAK,OAAO;AACZ,SAAK,WAAW;AAGhB,aAAS,KAAK,YAAY,IAAI;AAC9B,SAAK,MAAM;AAGX,aAAS,KAAK,YAAY,IAAI;AAC9B,QAAI,gBAAgB,GAAG;AAAA,EACzB;AAEA,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,UAAU,YAAY,YAAY,WAAW;AAAA,MAC7C;AAAA,MACA,OAAO,YAAY,WAAW,IAAI,+BAA+B;AAAA,MAEhE;AAAA;AAAA,EACH;AAEJ;;;ACnFA,SAAS,YAAAE,WAAU,mBAAmB;AAGtC,IAAM,iBAAiB;AA4BhB,IAAM,wBAAwB,CACnC,UAAwC,CAAC,MACT;AAChC,QAAM;AAAA,IACJ,wBAAwB;AAAA,IACxB,uBAAuB;AAAA,EACzB,IAAI;AAEJ,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAS,qBAAqB;AAC1E,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,oBAAoB;AAOvE,QAAM,6BAA6B;AAAA,IACjC,CAAC;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe;AAAA,IACjB,MAA4C;AAC1C,YAAM,qBAAqB,CAAC,GAAG,WAAW;AAC1C,YAAM,aAAa,YAAY,eAAe;AAE9C,UAAI,iBAAiB;AAEnB,cAAM,mBAAmB,KAAK,IAAI,WAAW,MAAM,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC;AAC5E,cAAM,QAAQ,mBAAmB,WAAW;AAE5C,2BAAmB,eAAe,IAAI;AAAA,UACpC,GAAG;AAAA,UACH,OAAO;AAAA,QACT;AAEA,YAAI,uBAAuB,kBAAkB,GAAG;AAE9C,gBAAM,iBAAiB,mBAAmB,kBAAkB,CAAC;AAE7D,cAAI,KAAK,IAAI,eAAe,MAAM,WAAW,KAAK,IAAI,gBAAgB;AAEpE,+BAAmB,kBAAkB,CAAC,IAAI;AAAA,cACxC,GAAG;AAAA,cACH,KAAK,KAAK,IAAI,eAAe,QAAQ,KAAK,eAAe,MAAM,KAAK;AAAA,YACtE;AAAA,UACF,WAAW,oBAAoB,eAAe,KAAK;AAEjD,+BAAmB,eAAe,IAAI;AAAA,cACpC,GAAG,mBAAmB,eAAe;AAAA,cACrC,OAAO,eAAe;AAAA,YACxB;AAAA,UACF;AAAA,QACF,WAAW,CAAC,uBAAuB,kBAAkB,KAAK,mBAAmB,mBAAmB,kBAAkB,CAAC,EAAE,KAAK;AAExH,6BAAmB,kBAAkB,CAAC,IAAI;AAAA,YACxC,GAAG,mBAAmB,kBAAkB,CAAC;AAAA,YACzC,KAAK;AAAA,UACP;AAAA,QACF;AAAA,MACF,OAAO;AAEL,cAAM,iBAAiB,KAAK,IAAI,WAAW,QAAQ,KAAK,KAAK,IAAI,SAAS,QAAQ,CAAC;AACnF,cAAM,QAAQ,iBAAiB,WAAW;AAE1C,2BAAmB,eAAe,IAAI;AAAA,UACpC,GAAG;AAAA,UACH,KAAK;AAAA,QACP;AAEA,YAAI,uBAAuB,kBAAkB,mBAAmB,SAAS,GAAG;AAE1E,gBAAM,iBAAiB,mBAAmB,kBAAkB,CAAC;AAE7D,cAAI,KAAK,IAAI,eAAe,QAAQ,WAAW,GAAG,IAAI,gBAAgB;AAEpE,kBAAM,WAAW,eAAe,QAAQ;AACxC,+BAAmB,kBAAkB,CAAC,IAAI;AAAA,cACxC,GAAG;AAAA,cACH,OAAO,KAAK,IAAI,eAAe,MAAM,KAAK,QAAQ;AAAA,YACpD;AAGA,gBAAI,eAAe,kBAAkB;AACrC,mBAAO,eAAe,mBAAmB,SAAS,GAAG;AACnD,oBAAM,UAAU,mBAAmB,YAAY;AAC/C,oBAAM,OAAO,mBAAmB,eAAe,CAAC;AAEhD,kBAAI,KAAK,IAAI,KAAK,QAAQ,QAAQ,GAAG,IAAI,gBAAgB;AACvD,sBAAM,YAAY,QAAQ,MAAM,YAAY,YAAY,EAAE;AAC1D,mCAAmB,eAAe,CAAC,IAAI;AAAA,kBACrC,GAAG;AAAA,kBACH,OAAO,KAAK,IAAI,KAAK,MAAM,KAAK,KAAK,QAAQ,SAAS;AAAA,gBACxD;AACA;AAAA,cACF,OAAO;AACL;AAAA,cACF;AAAA,YACF;AAAA,UACF,WAAW,kBAAkB,eAAe,OAAO;AAEjD,+BAAmB,eAAe,IAAI;AAAA,cACpC,GAAG,mBAAmB,eAAe;AAAA,cACrC,KAAK,eAAe;AAAA,YACtB;AAAA,UACF;AAAA,QACF,WAAW,CAAC,uBAAuB,kBAAkB,mBAAmB,SAAS,KAAK,iBAAiB,mBAAmB,kBAAkB,CAAC,EAAE,OAAO;AAEpJ,gBAAM,iBAAiB,mBAAmB,kBAAkB,CAAC;AAE7D,6BAAmB,kBAAkB,CAAC,IAAI;AAAA,YACxC,GAAG;AAAA,YACH,OAAO;AAAA,UACT;AAGA,cAAI,eAAe,kBAAkB;AACrC,iBAAO,eAAe,mBAAmB,SAAS,GAAG;AACnD,kBAAM,UAAU,mBAAmB,YAAY;AAC/C,kBAAM,OAAO,mBAAmB,eAAe,CAAC;AAEhD,gBAAI,QAAQ,MAAM,KAAK,OAAO;AAC5B,iCAAmB,eAAe,CAAC,IAAI;AAAA,gBACrC,GAAG;AAAA,gBACH,OAAO,QAAQ;AAAA,cACjB;AACA;AAAA,YACF,OAAO;AACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":["styled","jsx","jsxs","styled","jsx","jsxs","styled","usePlaylistInfo","jsx","jsxs","Container","ControlsPlaceholder","React","styled","jsx","jsxs","Container","ControlButton","AnnotationText","jsx","jsxs","BaseCheckboxWrapper","BaseCheckbox","BaseCheckboxLabel","jsx","jsxs","BaseCheckboxWrapper","BaseCheckbox","BaseCheckboxLabel","jsx","jsxs","styled","jsx","styled","useState"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@waveform-playlist/annotations",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0-next.1",
|
|
4
4
|
"description": "Annotation support for waveform-playlist",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"typescript": "^5.3.3"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@waveform-playlist/
|
|
45
|
-
"@waveform-playlist/
|
|
44
|
+
"@waveform-playlist/core": "5.2.0-next.1",
|
|
45
|
+
"@waveform-playlist/ui-components": "5.2.0-next.1"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"@dnd-kit/core": "^6.0.0",
|