supervision 0.1.4 → 0.1.6

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.
Files changed (71) hide show
  1. package/dist/index.d.ts +12 -4
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +864 -127
  4. package/dist/index.js.map +1 -1
  5. package/dist/mask-preparation.worker.js +91 -59
  6. package/dist/mask-preparation.worker.js.map +1 -1
  7. package/dist/media/media-errors.d.ts +32 -0
  8. package/dist/media/media-errors.d.ts.map +1 -0
  9. package/dist/media/media-source-state.d.ts.map +1 -1
  10. package/dist/media/media-stream-media-source.d.ts +31 -0
  11. package/dist/media/media-stream-media-source.d.ts.map +1 -1
  12. package/dist/media/mediabunny-media-source.d.ts.map +1 -1
  13. package/dist/media/presentation-timeline-media-source.d.ts +17 -0
  14. package/dist/media/presentation-timeline-media-source.d.ts.map +1 -0
  15. package/dist/media/static-image-media-source.d.ts.map +1 -1
  16. package/dist/post-processing/default-tracking-worker.d.ts +3 -0
  17. package/dist/post-processing/default-tracking-worker.d.ts.map +1 -0
  18. package/dist/post-processing/detection-post-processing-pipeline.d.ts +7 -0
  19. package/dist/post-processing/detection-post-processing-pipeline.d.ts.map +1 -0
  20. package/dist/post-processing/embedded-tracking-worker.d.ts +2 -0
  21. package/dist/post-processing/embedded-tracking-worker.d.ts.map +1 -0
  22. package/dist/post-processing/tracking-worker-protocol.d.ts +29 -0
  23. package/dist/post-processing/tracking-worker-protocol.d.ts.map +1 -0
  24. package/dist/post-processing/tracking.worker.d.ts +2 -0
  25. package/dist/post-processing/tracking.worker.d.ts.map +1 -0
  26. package/dist/renderers/media-renderer-core.d.ts.map +1 -1
  27. package/dist/renderers/media-renderer-state.d.ts.map +1 -1
  28. package/dist/sessions/media-session-detections.d.ts.map +1 -1
  29. package/dist/sessions/media-session.d.ts +2 -2
  30. package/dist/sessions/media-session.d.ts.map +1 -1
  31. package/dist/tracking.worker.js +1509 -0
  32. package/dist/tracking.worker.js.map +1 -0
  33. package/dist/types/detection-post-processing.d.ts +62 -0
  34. package/dist/types/detection-post-processing.d.ts.map +1 -0
  35. package/dist/types/media-session.d.ts +57 -1
  36. package/dist/types/media-session.d.ts.map +1 -1
  37. package/dist/workers/worker-rpc-client.d.ts +2 -1
  38. package/dist/workers/worker-rpc-client.d.ts.map +1 -1
  39. package/node_modules/supervision-js-core/dist/detections/composite-detection-frame-source.d.ts.map +1 -1
  40. package/node_modules/supervision-js-core/dist/detections/memory-cold-detection-frame-store.d.ts.map +1 -1
  41. package/node_modules/supervision-js-core/dist/detections/projected-detection-frame-source.d.ts +22 -0
  42. package/node_modules/supervision-js-core/dist/detections/projected-detection-frame-source.d.ts.map +1 -0
  43. package/node_modules/supervision-js-core/dist/detections/writable-detection-frame-source.d.ts +2 -7
  44. package/node_modules/supervision-js-core/dist/detections/writable-detection-frame-source.d.ts.map +1 -1
  45. package/node_modules/supervision-js-core/dist/index.d.ts +11 -3
  46. package/node_modules/supervision-js-core/dist/index.d.ts.map +1 -1
  47. package/node_modules/supervision-js-core/dist/index.js +2289 -329
  48. package/node_modules/supervision-js-core/dist/index.js.map +1 -1
  49. package/node_modules/supervision-js-core/dist/post-processing/byte-track-tracker.d.ts +4 -0
  50. package/node_modules/supervision-js-core/dist/post-processing/byte-track-tracker.d.ts.map +1 -0
  51. package/node_modules/supervision-js-core/dist/post-processing/cbiou-tracker.d.ts +4 -0
  52. package/node_modules/supervision-js-core/dist/post-processing/cbiou-tracker.d.ts.map +1 -0
  53. package/node_modules/supervision-js-core/dist/post-processing/oc-sort-tracker.d.ts +4 -0
  54. package/node_modules/supervision-js-core/dist/post-processing/oc-sort-tracker.d.ts.map +1 -0
  55. package/node_modules/supervision-js-core/dist/post-processing/sort-tracker.d.ts +4 -0
  56. package/node_modules/supervision-js-core/dist/post-processing/sort-tracker.d.ts.map +1 -0
  57. package/node_modules/supervision-js-core/dist/post-processing/tracking.d.ts +9 -0
  58. package/node_modules/supervision-js-core/dist/post-processing/tracking.d.ts.map +1 -0
  59. package/node_modules/supervision-js-core/dist/types/detection-timeline.d.ts +113 -3
  60. package/node_modules/supervision-js-core/dist/types/detection-timeline.d.ts.map +1 -1
  61. package/node_modules/supervision-js-core/dist/types/detections.d.ts +33 -3
  62. package/node_modules/supervision-js-core/dist/types/detections.d.ts.map +1 -1
  63. package/node_modules/supervision-js-core/dist/types/media-rendering.d.ts +31 -0
  64. package/node_modules/supervision-js-core/dist/types/media-rendering.d.ts.map +1 -1
  65. package/node_modules/supervision-js-core/dist/types/post-processing.d.ts +148 -0
  66. package/node_modules/supervision-js-core/dist/types/post-processing.d.ts.map +1 -0
  67. package/node_modules/supervision-js-core/dist/utils/detection-frames.d.ts.map +1 -1
  68. package/node_modules/supervision-js-core/dist/utils/detection-projection.d.ts +20 -0
  69. package/node_modules/supervision-js-core/dist/utils/detection-projection.d.ts.map +1 -0
  70. package/node_modules/supervision-js-core/package.json +12 -5
  71. package/package.json +7 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracking.worker.js","sources":["../../core/dist/index.js","../src/post-processing/tracking.worker.ts"],"sourcesContent":["/** COCO-compatible keypoint visibility values. */\nvar KeypointVisibility;\n(function (KeypointVisibility) {\n KeypointVisibility[KeypointVisibility[\"NotLabeled\"] = 0] = \"NotLabeled\";\n KeypointVisibility[KeypointVisibility[\"Occluded\"] = 1] = \"Occluded\";\n KeypointVisibility[KeypointVisibility[\"Visible\"] = 2] = \"Visible\";\n})(KeypointVisibility || (KeypointVisibility = {}));\nvar DetectionMaskEncoding;\n(function (DetectionMaskEncoding) {\n DetectionMaskEncoding[\"CompressedRle\"] = \"compressedRle\";\n})(DetectionMaskEncoding || (DetectionMaskEncoding = {}));\n\nvar DetectionBufferStatus;\n(function (DetectionBufferStatus) {\n DetectionBufferStatus[\"Idle\"] = \"idle\";\n DetectionBufferStatus[\"Loading\"] = \"loading\";\n DetectionBufferStatus[\"Ready\"] = \"ready\";\n DetectionBufferStatus[\"Error\"] = \"error\";\n DetectionBufferStatus[\"Destroyed\"] = \"destroyed\";\n})(DetectionBufferStatus || (DetectionBufferStatus = {}));\n/**\n * How the renderer selects the active detection frame for a media timestamp.\n */\nvar DetectionFrameSelectionMode;\n(function (DetectionFrameSelectionMode) {\n /**\n * Select the frame whose `[mediaTime, endTime)` interval contains the media\n * time. This is the default for interval annotations and timestamped sources.\n */\n DetectionFrameSelectionMode[\"Interval\"] = \"interval\";\n /**\n * Select from a known inference frame grid using `frameIndex`, `frameRate`,\n * and optional `frameIndexOriginTime`. This is useful when inference was run\n * on normalized frames and playback should snap detections to that grid.\n */\n DetectionFrameSelectionMode[\"NearestFrameIndex\"] = \"nearestFrameIndex\";\n})(DetectionFrameSelectionMode || (DetectionFrameSelectionMode = {}));\nvar DetectionFrameRetentionMode;\n(function (DetectionFrameRetentionMode) {\n /**\n * Keep writable detections only in an in-memory store. Useful for ephemeral\n * live streams where old predictions should disappear when evicted.\n */\n DetectionFrameRetentionMode[\"MemoryOnly\"] = \"memoryOnly\";\n /**\n * Persist every written detection frame. Useful for finite media where seek\n * and replay should not require recomputing detections.\n */\n DetectionFrameRetentionMode[\"PersistAll\"] = \"persistAll\";\n /**\n * Persist only the most recent retention window. Useful for long-running\n * streams where replay is bounded to a recent time horizon.\n */\n DetectionFrameRetentionMode[\"PersistWindow\"] = \"persistWindow\";\n})(DetectionFrameRetentionMode || (DetectionFrameRetentionMode = {}));\n\nfunction copySortedDetectionFrames(detectionFrames) {\n validateDetectionFrames(detectionFrames ?? []);\n return (detectionFrames ?? [])\n .map((frame) => ({\n detections: frame.detections.map((detection) => ({\n ...detection,\n attributes: detection.attributes\n ? [...detection.attributes]\n : undefined,\n keypoints: detection.keypoints\n ? {\n edges: detection.keypoints.edges.map((edge) => [edge[0], edge[1]]),\n points: detection.keypoints.points.map((point) => ({ ...point })),\n visibility: detection.keypoints.visibility\n ? [...detection.keypoints.visibility]\n : undefined,\n }\n : undefined,\n mask: detection.mask ? { ...detection.mask } : undefined,\n metadata: detection.metadata\n ? copyDetectionMetadata(detection.metadata)\n : undefined,\n polygon: detection.polygon\n ? {\n points: detection.polygon.points.map((point) => ({ ...point })),\n }\n : undefined,\n polyline: detection.polyline\n ? {\n points: detection.polyline.points.map((point) => ({ ...point })),\n }\n : undefined,\n rect: detection.rect ? { ...detection.rect } : undefined,\n })),\n coordinateSpace: frame.coordinateSpace\n ? { ...frame.coordinateSpace }\n : undefined,\n endTime: frame.endTime,\n frameIndex: frame.frameIndex,\n mediaTime: frame.mediaTime,\n }))\n .sort((left, right) => left.mediaTime - right.mediaTime);\n}\nfunction copyDetectionMetadata(metadata) {\n const clone = globalThis.structuredClone;\n if (clone) {\n return clone(metadata);\n }\n return copyMetadataValue(metadata);\n}\nfunction copyMetadataValue(value) {\n if (Array.isArray(value)) {\n return value.map(copyMetadataValue);\n }\n if (value && typeof value === \"object\") {\n return Object.fromEntries(Object.entries(value).map(([key, child]) => [\n key,\n copyMetadataValue(child),\n ]));\n }\n return value;\n}\nfunction validateDetectionFrames(detectionFrames) {\n for (const [frameOffset, frame] of detectionFrames.entries()) {\n validateNumber(frame.mediaTime, `frames[${frameOffset}].mediaTime`, {\n min: 0,\n });\n if (frame.endTime !== undefined) {\n validateNumber(frame.endTime, `frames[${frameOffset}].endTime`, {\n exclusiveMin: frame.mediaTime,\n });\n }\n if (frame.frameIndex !== undefined) {\n validateNumber(frame.frameIndex, `frames[${frameOffset}].frameIndex`, {\n integer: true,\n min: 0,\n });\n }\n if (frame.coordinateSpace !== undefined) {\n validateNumber(frame.coordinateSpace.width, `frames[${frameOffset}].coordinateSpace.width`, { exclusiveMin: 0 });\n validateNumber(frame.coordinateSpace.height, `frames[${frameOffset}].coordinateSpace.height`, { exclusiveMin: 0 });\n }\n for (const [detectionOffset, detection] of frame.detections.entries()) {\n const detectionPath = `frames[${frameOffset}].detections[${detectionOffset}]`;\n if (detection.confidence !== undefined) {\n validateNumber(detection.confidence, `${detectionPath}.confidence`, {\n max: 1,\n min: 0,\n });\n }\n if (detection.zIndex !== undefined) {\n validateNumber(detection.zIndex, `${detectionPath}.zIndex`);\n }\n if (detection.trackerId !== undefined) {\n validateNumber(detection.trackerId, `${detectionPath}.trackerId`, {\n integer: true,\n min: 0,\n });\n }\n if (detection.sourceId !== undefined &&\n typeof detection.sourceId !== \"string\") {\n throw new Error(`${detectionPath}.sourceId must be a string.`);\n }\n if (detection.sourceDetectionIndex !== undefined) {\n validateNumber(detection.sourceDetectionIndex, `${detectionPath}.sourceDetectionIndex`, {\n integer: true,\n min: 0,\n });\n }\n if (detection.rect) {\n validateNumber(detection.rect.x, `${detectionPath}.rect.x`);\n validateNumber(detection.rect.y, `${detectionPath}.rect.y`);\n validateNumber(detection.rect.width, `${detectionPath}.rect.width`, {\n exclusiveMin: 0,\n });\n validateNumber(detection.rect.height, `${detectionPath}.rect.height`, {\n exclusiveMin: 0,\n });\n }\n validatePoints(detection.polygon?.points, `${detectionPath}.polygon`, 3);\n validatePoints(detection.polyline?.points, `${detectionPath}.polyline`, 2);\n if (detection.keypoints) {\n validatePoints(detection.keypoints.points, `${detectionPath}.keypoints`, 1);\n if (detection.keypoints.visibility !== undefined &&\n detection.keypoints.visibility.length !==\n detection.keypoints.points.length) {\n throw new Error(`${detectionPath}.keypoints.visibility must match points length.`);\n }\n for (const [edgeOffset, edge] of detection.keypoints.edges.entries()) {\n const edgePath = `${detectionPath}.keypoints.edges[${edgeOffset}]`;\n for (const [endpointOffset, endpoint] of edge.entries()) {\n validateNumber(endpoint, `${edgePath}[${endpointOffset}]`, {\n integer: true,\n min: 0,\n });\n if (endpoint >= detection.keypoints.points.length) {\n throw new Error(`${edgePath}[${endpointOffset}] is out of range.`);\n }\n }\n }\n }\n if (detection.mask) {\n validateNumber(detection.mask.width, `${detectionPath}.mask.width`, {\n integer: true,\n exclusiveMin: 0,\n });\n validateNumber(detection.mask.height, `${detectionPath}.mask.height`, {\n integer: true,\n exclusiveMin: 0,\n });\n if (detection.mask.counts.length === 0) {\n throw new Error(`${detectionPath}.mask.counts must not be empty.`);\n }\n }\n }\n }\n}\nfunction validatePoints(points, path, minimumLength) {\n if (!points) {\n return;\n }\n if (points.length < minimumLength) {\n throw new Error(`${path}.points must contain at least ${minimumLength} points.`);\n }\n for (const [pointOffset, point] of points.entries()) {\n validateNumber(point.x, `${path}.points[${pointOffset}].x`);\n validateNumber(point.y, `${path}.points[${pointOffset}].y`);\n }\n}\nfunction validateNumber(value, path, options = {}) {\n if (!Number.isFinite(value)) {\n throw new Error(`${path} must be a finite number.`);\n }\n if (options.integer && !Number.isInteger(value)) {\n throw new Error(`${path} must be an integer.`);\n }\n if (options.min !== undefined && value < options.min) {\n throw new Error(`${path} must be greater than or equal to ${options.min}.`);\n }\n if (options.exclusiveMin !== undefined && value <= options.exclusiveMin) {\n throw new Error(`${path} must be greater than ${options.exclusiveMin}.`);\n }\n if (options.max !== undefined && value > options.max) {\n throw new Error(`${path} must be less than or equal to ${options.max}.`);\n }\n}\nfunction filterDetectionFramesForRange(detectionFrames, startTime, endTime) {\n return detectionFrames.filter((frame) => detectionFrameOverlapsRange(frame, startTime, endTime));\n}\nfunction selectDetectionFrame(detectionFrames, mediaTime, options = {}) {\n if (options.selectionMode === DetectionFrameSelectionMode.NearestFrameIndex) {\n const selection = selectNearestFrameIndexDetectionFrame(detectionFrames, mediaTime, options.frameRate, options.frameIndexOriginTime);\n if (selection.isApplicable) {\n return selection.frame;\n }\n }\n return selectIntervalDetectionFrame(detectionFrames, mediaTime);\n}\nfunction decodeCompressedRleMask(mask) {\n if (mask.encoding !== DetectionMaskEncoding.CompressedRle) {\n throw new Error(`Unsupported detection mask encoding: ${mask.encoding}`);\n }\n const data = new Uint8Array(mask.width * mask.height);\n const counts = decodeCompressedRleCounts(mask.counts);\n let offset = 0;\n for (let index = 0; index < counts.length; index += 1) {\n const runLength = counts[index] ?? 0;\n const isForeground = index % 2 === 1;\n if (isForeground) {\n for (let runOffset = 0; runOffset < runLength; runOffset += 1) {\n const maskOffset = offset + runOffset;\n const x = Math.floor(maskOffset / mask.height);\n const y = maskOffset % mask.height;\n const rowMajorOffset = y * mask.width + x;\n if (rowMajorOffset < data.length) {\n data[rowMajorOffset] = 1;\n }\n }\n }\n offset += runLength;\n }\n return {\n data,\n height: mask.height,\n width: mask.width,\n };\n}\nfunction selectIntervalDetectionFrame(detectionFrames, mediaTime) {\n let selectedFrame;\n let low = 0;\n let high = detectionFrames.length - 1;\n while (low <= high) {\n const middle = Math.floor((low + high) / 2);\n const frame = detectionFrames[middle];\n if (frame.mediaTime <= mediaTime) {\n selectedFrame = frame;\n low = middle + 1;\n }\n else {\n high = middle - 1;\n }\n }\n return selectedFrame && isDetectionFrameActive(selectedFrame, mediaTime)\n ? selectedFrame\n : undefined;\n}\nfunction selectNearestFrameIndexDetectionFrame(detectionFrames, mediaTime, frameRate, frameIndexOriginTime) {\n if (!frameRate || !Number.isFinite(frameRate) || frameRate <= 0) {\n return { frame: undefined, isApplicable: false };\n }\n const firstIndexedFrame = detectionFrames.find((frame) => frame.frameIndex !== undefined);\n if (!firstIndexedFrame || firstIndexedFrame.frameIndex === undefined) {\n return { frame: undefined, isApplicable: false };\n }\n const originTime = frameIndexOriginTime !== undefined\n ? frameIndexOriginTime\n : firstIndexedFrame.mediaTime - firstIndexedFrame.frameIndex / frameRate;\n const targetFrameIndex = Math.round((mediaTime - originTime) * frameRate);\n let nearestFrame;\n let nearestDistance = Number.POSITIVE_INFINITY;\n for (const frame of detectionFrames) {\n if (frame.frameIndex === undefined) {\n continue;\n }\n const distance = Math.abs(frame.frameIndex - targetFrameIndex);\n if (distance < nearestDistance ||\n (distance === nearestDistance &&\n nearestFrame?.frameIndex !== undefined &&\n frame.frameIndex > nearestFrame.frameIndex)) {\n nearestFrame = frame;\n nearestDistance = distance;\n }\n }\n return {\n frame: nearestDistance <= 1 ? nearestFrame : undefined,\n isApplicable: true,\n };\n}\nfunction isDetectionFrameActive(frame, mediaTime) {\n return (frame.mediaTime <= mediaTime &&\n (frame.endTime === undefined || mediaTime < frame.endTime));\n}\nfunction detectionFrameOverlapsRange(frame, startTime, endTime) {\n if (frame.endTime === undefined) {\n return frame.mediaTime >= startTime && frame.mediaTime <= endTime;\n }\n return frame.mediaTime <= endTime && frame.endTime > startTime;\n}\nfunction decodeCompressedRleCounts(counts) {\n const decoded = [];\n let index = 0;\n while (index < counts.length) {\n let value = 0;\n let shift = 0;\n let charCode;\n do {\n charCode = counts.charCodeAt(index) - 48;\n index += 1;\n value |= (charCode & 0x1f) << shift;\n shift += 5;\n } while (charCode & 0x20);\n if (charCode & 0x10) {\n value |= -1 << shift;\n }\n if (decoded.length > 2) {\n value += decoded[decoded.length - 2] ?? 0;\n }\n decoded.push(value);\n }\n return decoded;\n}\nfunction encodeCompressedRleCounts(counts) {\n return counts\n .map((count, index) => {\n let value = index > 2 ? count - counts[index - 2] : count;\n let encoded = \"\";\n let more = true;\n while (more) {\n let charCode = value & 0x1f;\n value >>= 5;\n more = !((value === 0 && (charCode & 0x10) === 0) ||\n (value === -1 && (charCode & 0x10) !== 0));\n if (more) {\n charCode |= 0x20;\n }\n encoded += String.fromCharCode(charCode + 48);\n }\n return encoded;\n })\n .join(\"\");\n}\n\nfunction createArrayDetectionFrameSource(frames) {\n const sortedFrames = copySortedDetectionFrames(frames);\n return {\n async loadFrames(startTime, endTime) {\n return copySortedDetectionFrames(filterDetectionFramesForRange(sortedFrames, startTime, endTime));\n },\n };\n}\n\nconst DEFAULT_BUFFER_AHEAD_SECONDS = 5;\nconst DEFAULT_BUFFER_BEHIND_SECONDS = 0.5;\nconst bufferedFrameSnapshots = new WeakMap();\n/**\n * Returns the timeline-owned hot-buffer snapshot without copying it.\n *\n * This is an internal platform-adapter fast path. Public callers should use\n * `getBufferedFrames()`, which preserves the existing defensive-copy contract.\n */\nfunction getBufferedDetectionTimelineFrameSnapshot(timeline) {\n return (bufferedFrameSnapshots.get(timeline)?.() ?? timeline.getBufferedFrames());\n}\nfunction createBufferedDetectionTimeline(options) {\n const bufferAheadSeconds = options.bufferAheadSeconds ?? DEFAULT_BUFFER_AHEAD_SECONDS;\n const bufferBehindSeconds = options.bufferBehindSeconds ?? DEFAULT_BUFFER_BEHIND_SECONDS;\n const refreshIntervalSeconds = options.refreshIntervalSeconds === undefined\n ? null\n : Math.max(0, options.refreshIntervalSeconds);\n const playbackGate = options.playbackGate;\n let buffer = [];\n let state = createIdleDetectionBufferState();\n let destroyed = false;\n let loadId = 0;\n let bufferedSourceVersion = null;\n let bufferedVersionRange = null;\n let timelineContext = {\n duration: null,\n loop: false,\n };\n let inFlight;\n let incrementalRefresh;\n let pendingPrefetch;\n let prefetchPump;\n const getSourceVersion = (ranges) => {\n if (!ranges) {\n return options.source.getVersion?.() ?? 0;\n }\n return ranges.reduce((version, range) => Math.max(version, options.source.getVersion?.(range) ?? 0), 0);\n };\n const isBufferFresh = () => bufferedVersionRange !== null &&\n bufferedSourceVersion === getSourceVersion(getBufferedSourceRanges());\n const getLoadRange = (mediaTime) => {\n const comparableMediaTime = getComparableMediaTime(mediaTime);\n const startTime = comparableMediaTime - bufferBehindSeconds;\n const endTime = comparableMediaTime + bufferAheadSeconds;\n return createLoadPlan(startTime, endTime);\n };\n const loadWindow = (mediaTime) => {\n const { endTime, sourceRanges, startTime } = getLoadRange(mediaTime);\n const versionRange = { endTime, startTime };\n const sourceVersion = getSourceVersion(sourceRanges);\n if (inFlight &&\n inFlight.sourceVersion === sourceVersion &&\n rangeContains(inFlight.startTime, inFlight.endTime, startTime, endTime)) {\n return inFlight.promise;\n }\n const currentLoadId = loadId + 1;\n loadId = currentLoadId;\n state = {\n ...state,\n errorMessage: null,\n requestedEndTime: endTime,\n requestedStartTime: startTime,\n status: DetectionBufferStatus.Loading,\n };\n const promise = Promise.all(sourceRanges.map((range) => options.source.loadFrames(range.startTime, range.endTime)))\n .then((frameRanges) => {\n if (destroyed || currentLoadId !== loadId) {\n return;\n }\n const committedSourceVersion = getSourceVersion(sourceRanges);\n const loadedBuffer = copySortedDetectionFrames(frameRanges.flat());\n buffer =\n bufferedSourceVersion !== null &&\n bufferedSourceVersion === committedSourceVersion\n ? reuseBufferedFrameSnapshots(buffer, loadedBuffer)\n : loadedBuffer;\n bufferedVersionRange = versionRange;\n bufferedSourceVersion = committedSourceVersion;\n state = {\n bufferEndTime: endTime,\n bufferStartTime: startTime,\n detectionCount: countDetections(buffer),\n errorMessage: null,\n frameCount: buffer.length,\n requestedEndTime: endTime,\n requestedStartTime: startTime,\n status: DetectionBufferStatus.Ready,\n };\n })\n .catch((error) => {\n if (!destroyed && currentLoadId === loadId) {\n state = {\n ...state,\n errorMessage: getErrorMessage(error),\n status: DetectionBufferStatus.Error,\n };\n }\n throw error;\n })\n .finally(() => {\n if (inFlight?.id === currentLoadId) {\n inFlight = undefined;\n }\n });\n inFlight = {\n endTime,\n id: currentLoadId,\n promise,\n sourceVersion,\n startTime,\n };\n return promise;\n };\n const isBuffered = (mediaTime) => {\n const comparableMediaTime = getComparableMediaTime(mediaTime);\n return (isBufferFresh() &&\n state.bufferStartTime !== null &&\n state.bufferEndTime !== null &&\n comparableMediaTime >= state.bufferStartTime &&\n comparableMediaTime <= state.bufferEndTime);\n };\n const isInsideBufferedRange = (mediaTime) => {\n const comparableMediaTime = getComparableMediaTime(mediaTime);\n return (bufferedVersionRange !== null &&\n state.bufferStartTime !== null &&\n state.bufferEndTime !== null &&\n comparableMediaTime >= state.bufferStartTime &&\n comparableMediaTime <= state.bufferEndTime);\n };\n const refreshBuffer = async (mediaTime) => {\n if (isBuffered(mediaTime)) {\n return;\n }\n if (isInsideBufferedRange(mediaTime) &&\n bufferedSourceVersion !== null &&\n options.source.getChangesSince) {\n if (!incrementalRefresh) {\n incrementalRefresh = applyIncrementalChanges().finally(() => {\n incrementalRefresh = undefined;\n });\n }\n await incrementalRefresh;\n if (isBuffered(mediaTime)) {\n return;\n }\n return refreshBuffer(mediaTime);\n }\n await loadWindow(mediaTime);\n };\n const shouldPrefetch = (mediaTime) => {\n if (!isBuffered(mediaTime)) {\n return true;\n }\n if (shouldRefreshRollingWindow(mediaTime)) {\n return true;\n }\n if (state.bufferEndTime === null || bufferAheadSeconds <= 0) {\n return false;\n }\n return (getComparableMediaTime(mediaTime) + bufferAheadSeconds / 2 >=\n state.bufferEndTime);\n };\n const timeline = {\n async prepare(mediaTime, prepareOptions) {\n if (destroyed) {\n return;\n }\n if (shouldWaitForPlaybackGate(prepareOptions)) {\n await waitForPlaybackGate(mediaTime, prepareOptions);\n if (destroyed) {\n return;\n }\n }\n await refreshBuffer(mediaTime);\n },\n prefetch(mediaTime) {\n if (destroyed || !shouldPrefetch(mediaTime)) {\n return;\n }\n pendingPrefetch = { loadId, mediaTime };\n pumpPrefetchQueue();\n },\n selectFrame(mediaTime) {\n if (!isBuffered(mediaTime)) {\n return undefined;\n }\n return selectDetectionFrame(buffer, getSourceMediaTime(mediaTime), options);\n },\n setTimelineContext(context) {\n timelineContext = context;\n bufferedSourceVersion = null;\n bufferedVersionRange = null;\n },\n getBufferedFrames() {\n return copySortedDetectionFrames(buffer);\n },\n getState() {\n return { ...state };\n },\n destroy() {\n if (destroyed) {\n return;\n }\n destroyed = true;\n pendingPrefetch = undefined;\n buffer = [];\n bufferedSourceVersion = null;\n bufferedVersionRange = null;\n state = {\n ...state,\n bufferEndTime: null,\n bufferStartTime: null,\n detectionCount: 0,\n frameCount: 0,\n status: DetectionBufferStatus.Destroyed,\n };\n options.source.destroy?.();\n },\n };\n bufferedFrameSnapshots.set(timeline, () => buffer);\n return timeline;\n function pumpPrefetchQueue() {\n if (destroyed || prefetchPump) {\n return;\n }\n prefetchPump = drainPrefetchQueue().finally(() => {\n prefetchPump = undefined;\n if (!destroyed && pendingPrefetch) {\n pumpPrefetchQueue();\n }\n });\n }\n async function drainPrefetchQueue() {\n while (!destroyed && pendingPrefetch) {\n if (inFlight) {\n await inFlight.promise.catch(() => undefined);\n continue;\n }\n const request = pendingPrefetch;\n pendingPrefetch = undefined;\n if (request.loadId !== loadId) {\n continue;\n }\n const { mediaTime } = request;\n if (!shouldPrefetch(mediaTime)) {\n continue;\n }\n await (shouldRefreshRollingWindow(mediaTime)\n ? loadWindow(mediaTime)\n : refreshBuffer(mediaTime)).catch(() => undefined);\n }\n }\n async function applyIncrementalChanges() {\n if (destroyed ||\n bufferedSourceVersion === null ||\n !options.source.getChangesSince) {\n return;\n }\n const sourceRanges = getBufferedSourceRanges();\n const incrementalLoadId = loadId;\n const incrementalVersionRange = bufferedVersionRange;\n const changes = options.source.getChangesSince(bufferedSourceVersion, sourceRanges);\n if (changes.requiresReload) {\n bufferedSourceVersion = null;\n return;\n }\n if (changes.ranges.length === 0) {\n bufferedSourceVersion = changes.version;\n return;\n }\n const changedRanges = getOverlappingRanges(changes.ranges, sourceRanges);\n if (changedRanges.length === 0) {\n bufferedSourceVersion = changes.version;\n return;\n }\n try {\n const changedFrameRanges = await Promise.all(changedRanges.map((range) => options.source.loadFrames(range.startTime, range.endTime)));\n if (destroyed ||\n loadId !== incrementalLoadId ||\n bufferedVersionRange !== incrementalVersionRange) {\n return;\n }\n buffer = mergeIncrementalFrames(buffer, changedFrameRanges.flat(), changedRanges);\n bufferedSourceVersion = changes.version;\n state = {\n ...state,\n detectionCount: countDetections(buffer),\n errorMessage: null,\n frameCount: buffer.length,\n status: DetectionBufferStatus.Ready,\n };\n }\n catch (error) {\n if (!destroyed) {\n state = {\n ...state,\n errorMessage: getErrorMessage(error),\n status: DetectionBufferStatus.Error,\n };\n }\n throw error;\n }\n }\n function shouldWaitForPlaybackGate(prepareOptions) {\n return (prepareOptions?.gatePlayback === true &&\n playbackGate?.enabled === true &&\n Boolean(options.source.waitForRange));\n }\n async function waitForPlaybackGate(mediaTime, prepareOptions) {\n if (!playbackGate?.enabled || !options.source.waitForRange) {\n return;\n }\n const requiredAheadSeconds = Math.max(0, playbackGate.requiredAheadSeconds ?? 0);\n const comparableMediaTime = getComparableMediaTime(mediaTime);\n const endTime = getRequiredCoverageEndTime({\n duration: isLoopingTimeline() ? null : prepareOptions?.duration,\n firstTimestamp: prepareOptions?.firstTimestamp,\n mediaTime: comparableMediaTime,\n requiredAheadSeconds,\n });\n if (endTime <= comparableMediaTime) {\n return;\n }\n const coveragePlan = createLoadPlan(comparableMediaTime, endTime);\n state = {\n ...state,\n errorMessage: null,\n requestedEndTime: coveragePlan.endTime,\n requestedStartTime: coveragePlan.startTime,\n status: DetectionBufferStatus.Loading,\n };\n try {\n await Promise.all(coveragePlan.sourceRanges.map((range) => options.source.waitForRange?.(range)));\n }\n catch (error) {\n if (!destroyed) {\n state = {\n ...state,\n errorMessage: getErrorMessage(error),\n status: DetectionBufferStatus.Error,\n };\n }\n throw error;\n }\n }\n function shouldRefreshRollingWindow(mediaTime) {\n if (refreshIntervalSeconds === null ||\n refreshIntervalSeconds <= 0 ||\n state.bufferStartTime === null ||\n state.bufferEndTime === null) {\n return false;\n }\n const { endTime, startTime } = getLoadRange(mediaTime);\n return (Math.abs(startTime - state.bufferStartTime) >= refreshIntervalSeconds ||\n Math.abs(endTime - state.bufferEndTime) >= refreshIntervalSeconds);\n }\n function createLoadPlan(requestedStartTime, requestedEndTime) {\n const startTime = Math.min(requestedStartTime, requestedEndTime);\n const endTime = Math.max(startTime, requestedEndTime);\n if (!isLoopingTimeline()) {\n const clampedStartTime = Math.max(0, startTime);\n const clampedEndTime = Math.max(clampedStartTime, endTime);\n return {\n endTime: clampedEndTime,\n sourceRanges: [\n {\n endTime: clampedEndTime,\n startTime: clampedStartTime,\n },\n ],\n startTime: clampedStartTime,\n };\n }\n const duration = timelineContext.duration ?? 0;\n if (endTime - startTime >= duration) {\n return {\n endTime: duration,\n sourceRanges: [{ endTime: duration, startTime: 0 }],\n startTime: 0,\n };\n }\n return {\n endTime,\n sourceRanges: getLoopingSourceRanges(startTime, endTime, duration),\n startTime,\n };\n }\n function getBufferedSourceRanges() {\n if (!bufferedVersionRange) {\n return [];\n }\n return createLoadPlan(bufferedVersionRange.startTime, bufferedVersionRange.endTime).sourceRanges;\n }\n function isLoopingTimeline() {\n return (timelineContext.loop &&\n timelineContext.duration !== null &&\n timelineContext.duration > 0);\n }\n function getComparableMediaTime(mediaTime) {\n if (!isLoopingTimeline() ||\n state.bufferStartTime === null ||\n state.bufferEndTime === null ||\n timelineContext.duration === null) {\n return mediaTime;\n }\n const duration = timelineContext.duration;\n let comparableMediaTime = mediaTime;\n while (comparableMediaTime < state.bufferStartTime) {\n comparableMediaTime += duration;\n }\n while (comparableMediaTime > state.bufferEndTime) {\n comparableMediaTime -= duration;\n }\n return comparableMediaTime;\n }\n function getSourceMediaTime(mediaTime) {\n if (!isLoopingTimeline() || timelineContext.duration === null) {\n return mediaTime;\n }\n if (mediaTime >= 0 && mediaTime <= timelineContext.duration) {\n return mediaTime;\n }\n return modulo(mediaTime, timelineContext.duration);\n }\n}\nfunction createIdleDetectionBufferState() {\n return {\n bufferEndTime: null,\n bufferStartTime: null,\n detectionCount: 0,\n errorMessage: null,\n frameCount: 0,\n requestedEndTime: null,\n requestedStartTime: null,\n status: DetectionBufferStatus.Idle,\n };\n}\nfunction rangeContains(outerStart, outerEnd, innerStart, innerEnd) {\n return outerStart <= innerStart && innerEnd <= outerEnd;\n}\nfunction countDetections(frames) {\n return frames.reduce((total, frame) => total + frame.detections.length, 0);\n}\nfunction getErrorMessage(error) {\n return error instanceof Error\n ? error.message\n : \"Detection buffer load failed.\";\n}\nfunction getRequiredCoverageEndTime(options) {\n const requestedEndTime = options.mediaTime + options.requiredAheadSeconds;\n if (options.duration === null || options.duration === undefined) {\n return requestedEndTime;\n }\n return Math.min(requestedEndTime, (options.firstTimestamp ?? 0) + Math.max(options.duration, 0));\n}\nfunction getLoopingSourceRanges(startTime, endTime, duration) {\n const normalizedStartTime = modulo(startTime, duration);\n const normalizedEndTime = modulo(endTime, duration);\n const startCycle = Math.floor(startTime / duration);\n const endCycle = Math.floor(endTime / duration);\n if (startCycle === endCycle) {\n return [{ endTime: normalizedEndTime, startTime: normalizedStartTime }];\n }\n const ranges = [];\n if (normalizedStartTime < duration) {\n ranges.push({ endTime: duration, startTime: normalizedStartTime });\n }\n if (normalizedEndTime > 0) {\n ranges.push({ endTime: normalizedEndTime, startTime: 0 });\n }\n return ranges;\n}\nfunction modulo(value, modulus) {\n return ((value % modulus) + modulus) % modulus;\n}\nfunction getOverlappingRanges(changedRanges, bufferedRanges) {\n const intersections = [];\n for (const changedRange of changedRanges) {\n for (const bufferedRange of bufferedRanges) {\n const startTime = Math.max(changedRange.startTime, bufferedRange.startTime);\n const endTime = Math.min(changedRange.endTime, bufferedRange.endTime);\n if (startTime <= endTime) {\n intersections.push({ endTime, startTime });\n }\n }\n }\n return intersections;\n}\nfunction mergeIncrementalFrames(currentFrames, changedFrames, changedRanges) {\n const framesByIdentity = new Map();\n for (const frame of currentFrames) {\n if (changedRanges.some((range) => detectionFrameOverlapsRange(frame, range.startTime, range.endTime))) {\n continue;\n }\n framesByIdentity.set(getDetectionFrameIdentity(frame), frame);\n }\n for (const frame of changedFrames) {\n framesByIdentity.set(getDetectionFrameIdentity(frame), frame);\n }\n return Array.from(framesByIdentity.values()).sort(compareDetectionFrames$1);\n}\nfunction reuseBufferedFrameSnapshots(currentFrames, loadedFrames) {\n const currentFramesByIdentity = new Map(currentFrames.map((frame) => [getDetectionFrameIdentity(frame), frame]));\n return loadedFrames.map((frame) => currentFramesByIdentity.get(getDetectionFrameIdentity(frame)) ?? frame);\n}\nfunction getDetectionFrameIdentity(frame) {\n return frame.frameIndex === undefined\n ? `time:${frame.mediaTime}`\n : `index:${frame.frameIndex}`;\n}\nfunction compareDetectionFrames$1(left, right) {\n if (left.mediaTime !== right.mediaTime) {\n return left.mediaTime - right.mediaTime;\n }\n return (left.frameIndex ?? 0) - (right.frameIndex ?? 0);\n}\n\nfunction createColdDetectionFrameSource(options) {\n return {\n loadFrames(startTime, endTime) {\n return options.store.loadFrames({\n datasetId: options.datasetId,\n endTime,\n startTime,\n });\n },\n };\n}\n\n/**\n * Projects one detection frame from its declared source coordinate space into\n * `target`.\n *\n * Rectangles, polygons, polylines, and keypoints are scaled. Masks are left\n * untouched because a `DetectionMask` already carries the mask-pixel\n * dimensions its `counts` are encoded against; scaling them here would apply\n * the ratio twice. Frames without `coordinateSpace`, with a degenerate space,\n * or already in the target space are returned unchanged so mixed producers can\n * share one source.\n */\nfunction projectDetectionFrame(frame, target) {\n const space = frame.coordinateSpace;\n if (!space ||\n !isUsableCoordinateSpace(space) ||\n !isUsableCoordinateSpace(target) ||\n (space.width === target.width && space.height === target.height)) {\n return frame;\n }\n const scaleX = target.width / space.width;\n const scaleY = target.height / space.height;\n return {\n ...frame,\n coordinateSpace: { height: target.height, width: target.width },\n detections: frame.detections.map((detection) => projectDetection(detection, scaleX, scaleY)),\n };\n}\n/**\n * Projects every frame that declares a source coordinate space into `target`.\n *\n * Frames without coordinate metadata pass through by reference.\n */\nfunction projectDetectionFrames(frames, target) {\n let didProject = false;\n const projectedFrames = frames.map((frame) => {\n const projectedFrame = projectDetectionFrame(frame, target);\n didProject ||= projectedFrame !== frame;\n return projectedFrame;\n });\n return didProject ? projectedFrames : frames;\n}\nfunction projectDetection(detection, scaleX, scaleY) {\n return {\n ...detection,\n ...(detection.rect\n ? { rect: scaleRect(detection.rect, scaleX, scaleY) }\n : {}),\n ...(detection.polygon\n ? { polygon: scalePolygon(detection.polygon, scaleX, scaleY) }\n : {}),\n ...(detection.polyline\n ? { polyline: scalePolyline(detection.polyline, scaleX, scaleY) }\n : {}),\n ...(detection.keypoints\n ? { keypoints: scaleKeypoints(detection.keypoints, scaleX, scaleY) }\n : {}),\n };\n}\nfunction scaleRect(rect, scaleX, scaleY) {\n return {\n height: rect.height * scaleY,\n width: rect.width * scaleX,\n x: rect.x * scaleX,\n y: rect.y * scaleY,\n };\n}\nfunction scalePolygon(polygon, scaleX, scaleY) {\n return { points: scalePoints(polygon.points, scaleX, scaleY) };\n}\nfunction scalePolyline(polyline, scaleX, scaleY) {\n return { points: scalePoints(polyline.points, scaleX, scaleY) };\n}\nfunction scaleKeypoints(keypoints, scaleX, scaleY) {\n return {\n ...keypoints,\n points: scalePoints(keypoints.points, scaleX, scaleY),\n };\n}\nfunction scalePoints(points, scaleX, scaleY) {\n return points.map((point) => ({ x: point.x * scaleX, y: point.y * scaleY }));\n}\nfunction isUsableCoordinateSpace(space) {\n return (Number.isFinite(space.width) &&\n Number.isFinite(space.height) &&\n space.width > 0 &&\n space.height > 0);\n}\n\nfunction createCompositeDetectionFrameSource(options) {\n const sources = normalizeCompositeSources(options.sources);\n return {\n async loadFrames(startTime, endTime, loadOptions) {\n const target = loadOptions?.coordinateSpace;\n const loadedSources = await Promise.all(sources.map(async (source) => {\n const frames = copySortedDetectionFrames(await source.source.loadFrames(startTime, endTime, loadOptions));\n return {\n ...source,\n // Composition flattens child detections into one frame, which can\n // only carry one coordinate space. Each child is projected here,\n // while its own `coordinateSpace` is still attached to its own\n // detections, so children inferred at different sizes compose\n // correctly. Masks keep their intrinsic dimensions.\n frames: target ? projectDetectionFrames(frames, target) : frames,\n };\n }));\n if (options.selectionMode === DetectionFrameSelectionMode.NearestFrameIndex) {\n const nearestFrames = composeNearestFrameIndexFrames(loadedSources, startTime, endTime, options, target);\n if (nearestFrames) {\n return nearestFrames;\n }\n }\n return composeIntervalFrames(loadedSources, startTime, endTime, options, target);\n },\n async waitForRange(range) {\n await Promise.all(sources\n .filter((source) => source.requiredForPlayback)\n .map((source) => source.source.waitForRange?.(range)));\n },\n getAvailableRanges() {\n return mergeRanges$1(sources.flatMap((source) => source.source.getAvailableRanges?.() ?? []));\n },\n getVersion(range) {\n return sources.reduce((version, source) => version + (source.source.getVersion?.(range) ?? 0), 0);\n },\n destroy() {\n for (const source of sources) {\n source.source.destroy?.();\n }\n },\n };\n}\nfunction normalizeCompositeSources(entries) {\n const sourceIds = new Set();\n return entries\n .map((entry, declarationIndex) => {\n if (sourceIds.has(entry.id)) {\n throw new Error(`Duplicate detection source id: ${entry.id}.`);\n }\n sourceIds.add(entry.id);\n const inputCount = [\n entry.frames !== undefined,\n entry.source !== undefined,\n ].filter(Boolean).length;\n if (inputCount !== 1) {\n throw new Error(`Detection source ${entry.id} must provide exactly one input: frames or source.`);\n }\n return {\n declarationIndex,\n id: entry.id,\n order: entry.order ?? 0,\n requiredForPlayback: entry.requiredForPlayback !== false,\n source: entry.source ?? createArrayDetectionFrameSource(entry.frames ?? []),\n sync: entry.sync,\n };\n })\n .sort((left, right) => left.order - right.order ||\n left.declarationIndex - right.declarationIndex);\n}\nfunction composeIntervalFrames(sources, startTime, endTime, options, coordinateSpace) {\n const boundaryTimes = new Set([startTime]);\n for (const source of sources) {\n for (const frame of source.frames) {\n if (frame.mediaTime >= startTime && frame.mediaTime < endTime) {\n boundaryTimes.add(frame.mediaTime);\n }\n if (frame.endTime !== undefined &&\n frame.endTime > startTime &&\n frame.endTime < endTime) {\n boundaryTimes.add(frame.endTime);\n }\n }\n }\n const sortedBoundaryTimes = [...boundaryTimes].sort((left, right) => left - right);\n const frames = [];\n for (const [boundaryIndex, mediaTime] of sortedBoundaryTimes.entries()) {\n if (mediaTime < startTime || mediaTime >= endTime) {\n continue;\n }\n const nextBoundaryTime = sortedBoundaryTimes[boundaryIndex + 1] ?? endTime;\n const endTimeForFrame = Math.min(nextBoundaryTime, endTime);\n const frame = composeFrameAtTime(sources, mediaTime, endTimeForFrame, { ...options, selectionMode: DetectionFrameSelectionMode.Interval }, undefined, coordinateSpace);\n if (frame) {\n frames.push(frame);\n }\n }\n return frames;\n}\nfunction composeNearestFrameIndexFrames(sources, startTime, endTime, options, coordinateSpace) {\n const frameRate = options.frameRate;\n if (!frameRate || !Number.isFinite(frameRate) || frameRate <= 0) {\n return null;\n }\n const indexedFrames = sources.flatMap((source) => source.frames.filter((frame) => frame.frameIndex !== undefined));\n const firstIndexedFrame = indexedFrames[0];\n if (!firstIndexedFrame || firstIndexedFrame.frameIndex === undefined) {\n return null;\n }\n const originTime = options.frameIndexOriginTime ??\n firstIndexedFrame.mediaTime - firstIndexedFrame.frameIndex / frameRate;\n const frameIndexes = [\n ...new Set(indexedFrames\n .map((frame) => frame.frameIndex)\n .filter((frameIndex) => frameIndex !== undefined)),\n ].sort((left, right) => left - right);\n const frames = [];\n for (const frameIndex of frameIndexes) {\n const mediaTime = originTime + frameIndex / frameRate;\n if (mediaTime < startTime || mediaTime >= endTime) {\n continue;\n }\n const frame = composeFrameAtTime(sources, mediaTime, Math.min(mediaTime + 1 / frameRate, endTime), {\n ...options,\n selectionMode: DetectionFrameSelectionMode.NearestFrameIndex,\n }, frameIndex, coordinateSpace);\n if (frame) {\n frames.push(frame);\n }\n }\n return frames;\n}\nfunction composeFrameAtTime(sources, mediaTime, endTime, options, frameIndex, coordinateSpace) {\n const detections = [];\n const activeFrameIndexes = [];\n for (const source of sources) {\n const activeFrame = selectDetectionFrame(source.frames, mediaTime, {\n ...options,\n ...source.sync,\n });\n if (!activeFrame) {\n continue;\n }\n if (activeFrame.frameIndex !== undefined) {\n activeFrameIndexes.push(activeFrame.frameIndex);\n }\n activeFrame.detections.forEach((detection, sourceDetectionIndex) => {\n detections.push(copyDetectionWithSource(detection, source.id, sourceDetectionIndex));\n });\n }\n if (detections.length === 0) {\n return undefined;\n }\n return {\n detections,\n endTime,\n frameIndex: frameIndex ?? resolveComposedFrameIndex(activeFrameIndexes) ?? undefined,\n mediaTime,\n // Children were projected before composition, so a composed frame is\n // already in the coordinate space the renderer presents.\n ...(coordinateSpace ? { coordinateSpace } : {}),\n };\n}\nfunction copyDetectionWithSource(detection, sourceId, sourceDetectionIndex) {\n return {\n ...detection,\n mask: detection.mask ? { ...detection.mask } : undefined,\n metadata: detection.metadata ? { ...detection.metadata } : undefined,\n rect: detection.rect ? { ...detection.rect } : undefined,\n sourceDetectionIndex,\n sourceId,\n };\n}\nfunction resolveComposedFrameIndex(frameIndexes) {\n if (frameIndexes.length === 0) {\n return undefined;\n }\n const firstFrameIndex = frameIndexes[0];\n return frameIndexes.every((frameIndex) => frameIndex === firstFrameIndex)\n ? firstFrameIndex\n : undefined;\n}\nfunction mergeRanges$1(ranges) {\n const sortedRanges = [...ranges].sort((left, right) => left.startTime - right.startTime);\n const mergedRanges = [];\n for (const range of sortedRanges) {\n const lastRange = mergedRanges.at(-1);\n if (!lastRange || range.startTime > lastRange.endTime) {\n mergedRanges.push({ ...range });\n continue;\n }\n mergedRanges[mergedRanges.length - 1] = {\n startTime: lastRange.startTime,\n endTime: Math.max(lastRange.endTime, range.endTime),\n };\n }\n return mergedRanges;\n}\n\nvar AnnotationFrameMutationKind;\n(function (AnnotationFrameMutationKind) {\n AnnotationFrameMutationKind[\"Add\"] = \"add\";\n AnnotationFrameMutationKind[\"Remove\"] = \"remove\";\n AnnotationFrameMutationKind[\"Replace\"] = \"replace\";\n AnnotationFrameMutationKind[\"Transact\"] = \"transact\";\n AnnotationFrameMutationKind[\"Update\"] = \"update\";\n})(AnnotationFrameMutationKind || (AnnotationFrameMutationKind = {}));\nfunction createEditableAnnotationFrameSession(initialFrame) {\n let snapshot = createSnapshot(initialFrame);\n let destroyed = false;\n const listeners = new Set();\n assertStableIds(snapshot);\n const commit = (frame, kind, detectionIds) => {\n assertActive();\n const previous = snapshot;\n const current = createSnapshot(frame);\n assertStableIds(current);\n snapshot = current;\n const mutation = Object.freeze({\n current,\n detectionIds: Object.freeze([...detectionIds]),\n kind,\n previous,\n });\n for (const listener of listeners) {\n listener(mutation);\n }\n return current;\n };\n const session = {\n getSnapshot() {\n assertActive();\n return snapshot;\n },\n add(detection, index = snapshot.detections.length) {\n assertActive();\n const id = requireDetectionId(detection);\n if (findDetectionIndex(snapshot, id) !== -1) {\n throw new Error(`Detection id ${String(id)} already exists.`);\n }\n const detections = [...snapshot.detections];\n const insertionIndex = Math.max(0, Math.min(index, detections.length));\n detections.splice(insertionIndex, 0, detection);\n return commit({ ...snapshot, detections }, AnnotationFrameMutationKind.Add, [id]);\n },\n update(id, update) {\n assertActive();\n const detectionIndex = findDetectionIndex(snapshot, id);\n if (detectionIndex === -1) {\n throw new Error(`Detection id ${String(id)} was not found.`);\n }\n const detections = [...snapshot.detections];\n const current = detections[detectionIndex];\n const next = typeof update === \"function\"\n ? update(current)\n : { ...current, ...update };\n if (next.id !== id) {\n throw new Error(\"Detection updates must preserve the stable id.\");\n }\n detections[detectionIndex] = next;\n return commit({ ...snapshot, detections }, AnnotationFrameMutationKind.Update, [id]);\n },\n remove(id) {\n assertActive();\n const detectionIndex = findDetectionIndex(snapshot, id);\n if (detectionIndex === -1) {\n return snapshot;\n }\n const detections = [...snapshot.detections];\n detections.splice(detectionIndex, 1);\n return commit({ ...snapshot, detections }, AnnotationFrameMutationKind.Remove, [id]);\n },\n replace(frame) {\n return commit(frame, AnnotationFrameMutationKind.Replace, frame.detections.map(requireDetectionId));\n },\n transact(mutate, detectionIds = []) {\n assertActive();\n const detections = copySortedDetectionFrames([snapshot])[0]\n .detections;\n mutate(detections);\n return commit({ ...snapshot, detections }, AnnotationFrameMutationKind.Transact, detectionIds);\n },\n subscribe(listener) {\n assertActive();\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n destroy() {\n destroyed = true;\n listeners.clear();\n },\n };\n return session;\n function assertActive() {\n if (destroyed) {\n throw new Error(\"Editable annotation frame session has been destroyed.\");\n }\n }\n}\nfunction findDetectionIndex(frame, id) {\n return frame.detections.findIndex((detection) => detection.id === id);\n}\nfunction requireDetectionId(detection) {\n if (detection.id === undefined) {\n throw new Error(\"Editable annotation detections require a stable id.\");\n }\n return detection.id;\n}\nfunction assertStableIds(frame) {\n const ids = new Set();\n for (const detection of frame.detections) {\n const id = requireDetectionId(detection);\n if (ids.has(id)) {\n throw new Error(`Detection id ${String(id)} is duplicated.`);\n }\n ids.add(id);\n }\n}\nfunction createSnapshot(frame) {\n const snapshot = copySortedDetectionFrames([frame])[0];\n return deepFreeze(snapshot);\n}\nfunction deepFreeze(value) {\n if (value && typeof value === \"object\" && !Object.isFrozen(value)) {\n Object.freeze(value);\n for (const nested of Object.values(value)) {\n deepFreeze(nested);\n }\n }\n return value;\n}\n\nconst DEFAULT_CHUNK_DURATION_SECONDS = 1;\nfunction createMemoryColdDetectionFrameStore() {\n const datasets = new Map();\n let destroyed = false;\n return {\n async putFrames(options) {\n assertActive();\n const dataset = createDataset(resolveChunkDurationSeconds(options));\n upsertFrames(dataset, copySortedDetectionFrames(options.frames));\n datasets.set(options.datasetId, dataset);\n return createWriteSummary(options.datasetId, dataset);\n },\n async appendFrames(options) {\n assertActive();\n const existingDataset = datasets.get(options.datasetId);\n const chunkDurationSeconds = resolveChunkDurationSeconds(options, existingDataset);\n const dataset = existingDataset ?? createDataset(chunkDurationSeconds);\n upsertFrames(dataset, copySortedDetectionFrames(options.frames));\n datasets.set(options.datasetId, dataset);\n return createWriteSummary(options.datasetId, dataset);\n },\n async loadFrames(options) {\n assertActive();\n const dataset = datasets.get(options.datasetId);\n if (!dataset) {\n return [];\n }\n const startTime = Math.max(0, options.startTime);\n const endTime = Math.max(startTime, options.endTime);\n const frameKeys = new Set();\n const startChunkIndex = getChunkIndex(startTime, dataset.chunkDurationSeconds);\n const endChunkIndex = getChunkIndex(endTime, dataset.chunkDurationSeconds);\n for (let chunkIndex = startChunkIndex; chunkIndex <= endChunkIndex; chunkIndex += 1) {\n for (const frameKey of dataset.frameKeysByChunk.get(chunkIndex) ?? []) {\n frameKeys.add(frameKey);\n }\n }\n const frames = Array.from(frameKeys)\n .map((frameKey) => dataset.framesByKey.get(frameKey)?.frame)\n .filter((frame) => frame !== undefined &&\n detectionFrameOverlapsRange(frame, startTime, endTime));\n return copySortedDetectionFrames(frames);\n },\n async pruneFrames(options) {\n assertActive();\n assertRetentionFloor(options.startTime);\n const dataset = datasets.get(options.datasetId);\n if (!dataset) {\n return createWriteSummary(options.datasetId, createDataset(DEFAULT_CHUNK_DURATION_SECONDS));\n }\n pruneDatasetBefore(dataset, options.startTime);\n return createWriteSummary(options.datasetId, dataset);\n },\n async clearDataset(datasetId) {\n assertActive();\n datasets.delete(datasetId);\n },\n destroy() {\n destroyed = true;\n datasets.clear();\n },\n };\n function assertActive() {\n if (destroyed) {\n throw new Error(\"Memory cold detection frame store has been destroyed.\");\n }\n }\n}\nfunction createDataset(chunkDurationSeconds) {\n return {\n chunkDurationSeconds,\n detectionCount: 0,\n endTime: null,\n frameKeysByChunk: new Map(),\n framesByKey: new Map(),\n startTime: null,\n };\n}\nfunction upsertFrames(dataset, frames) {\n let shouldRecalculateBounds = false;\n for (const frame of frames) {\n const frameKey = getDetectionFrameDedupeKey(frame);\n const existingFrame = dataset.framesByKey.get(frameKey);\n if (existingFrame) {\n removeStoredFrame(dataset, frameKey, existingFrame);\n shouldRecalculateBounds ||= replacementCanShrinkBounds(dataset, existingFrame.frame, frame);\n }\n const chunkIndexes = getFrameChunkIndexes(frame, dataset.chunkDurationSeconds);\n dataset.framesByKey.set(frameKey, { chunkIndexes, frame });\n dataset.detectionCount += frame.detections.length;\n dataset.startTime = Math.min(dataset.startTime ?? frame.mediaTime, frame.mediaTime);\n dataset.endTime = Math.max(dataset.endTime ?? getFrameEndTime$1(frame), getFrameEndTime$1(frame));\n for (const chunkIndex of chunkIndexes) {\n const frameKeys = dataset.frameKeysByChunk.get(chunkIndex) ?? new Set();\n frameKeys.add(frameKey);\n dataset.frameKeysByChunk.set(chunkIndex, frameKeys);\n }\n }\n if (shouldRecalculateBounds) {\n recalculateBounds(dataset);\n }\n}\nfunction removeStoredFrame(dataset, frameKey, storedFrame) {\n dataset.framesByKey.delete(frameKey);\n dataset.detectionCount -= storedFrame.frame.detections.length;\n for (const chunkIndex of storedFrame.chunkIndexes) {\n const frameKeys = dataset.frameKeysByChunk.get(chunkIndex);\n frameKeys?.delete(frameKey);\n if (frameKeys?.size === 0) {\n dataset.frameKeysByChunk.delete(chunkIndex);\n }\n }\n}\n/**\n * Drops frames that end before `startTime`.\n *\n * Only chunks at or below the retention boundary are visited, and the new\n * start bound is read from the lowest surviving chunk, so eviction costs work\n * proportional to the evicted range rather than to retained history.\n */\nfunction pruneDatasetBefore(dataset, startTime) {\n const boundaryChunkIndex = getChunkIndex(Math.max(0, startTime), dataset.chunkDurationSeconds);\n let didRemoveFrame = false;\n for (const chunkIndex of Array.from(dataset.frameKeysByChunk.keys())) {\n if (chunkIndex > boundaryChunkIndex) {\n continue;\n }\n for (const frameKey of Array.from(dataset.frameKeysByChunk.get(chunkIndex) ?? [])) {\n const storedFrame = dataset.framesByKey.get(frameKey);\n if (!storedFrame || isFrameRetainedFrom(storedFrame.frame, startTime)) {\n continue;\n }\n removeStoredFrame(dataset, frameKey, storedFrame);\n didRemoveFrame = true;\n }\n }\n if (!didRemoveFrame) {\n return;\n }\n if (dataset.framesByKey.size === 0) {\n dataset.startTime = null;\n dataset.endTime = null;\n return;\n }\n // Every frame is registered in the chunk its `mediaTime` falls in, so the\n // earliest retained frame lives in the lowest remaining chunk. Removing\n // frames can only raise the start bound; `endTime` is unchanged because only\n // frames ending before `startTime` were dropped.\n dataset.startTime = getEarliestChunkStartTime(dataset);\n}\n/**\n * Mirrors `detectionFrameOverlapsRange` so pruning keeps exactly the frames a\n * load from `startTime` would return.\n */\nfunction isFrameRetainedFrom(frame, startTime) {\n return frame.endTime === undefined\n ? frame.mediaTime >= startTime\n : frame.endTime > startTime;\n}\nfunction getEarliestChunkStartTime(dataset) {\n let earliestChunkIndex = null;\n for (const chunkIndex of dataset.frameKeysByChunk.keys()) {\n if (earliestChunkIndex === null || chunkIndex < earliestChunkIndex) {\n earliestChunkIndex = chunkIndex;\n }\n }\n let startTime = null;\n for (const frameKey of dataset.frameKeysByChunk.get(earliestChunkIndex ?? 0) ?? []) {\n const storedFrame = dataset.framesByKey.get(frameKey);\n if (!storedFrame) {\n continue;\n }\n startTime = Math.min(startTime ?? storedFrame.frame.mediaTime, storedFrame.frame.mediaTime);\n }\n return startTime;\n}\nfunction replacementCanShrinkBounds(dataset, previousFrame, nextFrame) {\n return ((dataset.startTime === previousFrame.mediaTime &&\n nextFrame.mediaTime > previousFrame.mediaTime) ||\n (dataset.endTime === getFrameEndTime$1(previousFrame) &&\n getFrameEndTime$1(nextFrame) < getFrameEndTime$1(previousFrame)));\n}\nfunction recalculateBounds(dataset) {\n let startTime = null;\n let endTime = null;\n for (const { frame } of dataset.framesByKey.values()) {\n startTime = Math.min(startTime ?? frame.mediaTime, frame.mediaTime);\n endTime = Math.max(endTime ?? getFrameEndTime$1(frame), getFrameEndTime$1(frame));\n }\n dataset.startTime = startTime;\n dataset.endTime = endTime;\n}\nfunction resolveChunkDurationSeconds(options, existingDataset) {\n const chunkDurationSeconds = options.chunkDurationSeconds ??\n existingDataset?.chunkDurationSeconds ??\n DEFAULT_CHUNK_DURATION_SECONDS;\n if (chunkDurationSeconds <= 0) {\n throw new Error(\"chunkDurationSeconds must be greater than 0.\");\n }\n if (existingDataset &&\n options.chunkDurationSeconds !== undefined &&\n options.chunkDurationSeconds !== existingDataset.chunkDurationSeconds) {\n throw new Error(\"chunkDurationSeconds must match the existing detection dataset.\");\n }\n return chunkDurationSeconds;\n}\nfunction createWriteSummary(datasetId, dataset) {\n return {\n chunkCount: dataset.frameKeysByChunk.size,\n chunkDurationSeconds: dataset.chunkDurationSeconds,\n datasetId,\n detectionCount: dataset.detectionCount,\n endTime: dataset.endTime,\n frameCount: dataset.framesByKey.size,\n startTime: dataset.startTime,\n };\n}\nfunction getFrameChunkIndexes(frame, chunkDurationSeconds) {\n const startIndex = getChunkIndex(frame.mediaTime, chunkDurationSeconds);\n const endIndex = Math.max(startIndex, Math.ceil(getFrameEndTime$1(frame) / chunkDurationSeconds) - 1);\n return Array.from({ length: endIndex - startIndex + 1 }, (_, offset) => startIndex + offset);\n}\nfunction getFrameEndTime$1(frame) {\n return frame.endTime ?? frame.mediaTime;\n}\nfunction getChunkIndex(mediaTime, chunkDurationSeconds) {\n return Math.floor(mediaTime / chunkDurationSeconds);\n}\nfunction getDetectionFrameDedupeKey(frame) {\n return frame.frameIndex === undefined\n ? `time:${frame.mediaTime}`\n : `index:${frame.frameIndex}`;\n}\n/**\n * Rejects a retention floor that could not describe a real media time.\n *\n * Pruning mutates retained history in place, and `NaN` compares false against\n * every retained frame, so an unvalidated floor would silently erase a dataset\n * instead of evicting a bounded range.\n */\nfunction assertRetentionFloor(startTime) {\n if (!Number.isFinite(startTime) || startTime < 0) {\n throw new RangeError(\"pruneFrames requires a finite, non-negative startTime.\");\n }\n}\n\n/**\n * Wraps a detection source so every loaded frame that declares a source\n * coordinate space is projected into the target space.\n *\n * The target is resolved per load because media dimensions are only known once\n * the media has opened, while sources are composed before that. Frames without\n * `coordinateSpace`, and loads made before a target exists, pass through by\n * reference, so a producer already emitting media-pixel geometry pays nothing.\n *\n * The target is also handed to the wrapped source through\n * `DetectionFrameLoadOptions`. A source that flattens child frames, such as a\n * composite source, needs it to project each child while that child's own\n * `coordinateSpace` is still attached; projecting the flattened result again\n * here is then a no-op.\n *\n * Optional source hooks are forwarded only when the wrapped source implements\n * them, so capability detection keeps working through the wrapper.\n */\nfunction createProjectedDetectionFrameSource(source, resolveTarget) {\n const { getAvailableRanges, getChangesSince, getVersion, waitForRange } = source;\n return {\n async loadFrames(startTime, endTime, options) {\n const target = resolveTarget();\n const frames = await source.loadFrames(startTime, endTime, {\n ...options,\n ...(target ? { coordinateSpace: target } : {}),\n });\n return target ? projectDetectionFrames(frames, target) : frames;\n },\n ...(waitForRange\n ? {\n waitForRange: (range) => waitForRange.call(source, range),\n }\n : {}),\n ...(getAvailableRanges\n ? { getAvailableRanges: () => getAvailableRanges.call(source) }\n : {}),\n ...(getVersion\n ? {\n getVersion: (range) => getVersion.call(source, range),\n }\n : {}),\n ...(getChangesSince\n ? {\n getChangesSince: (version, ranges) => getChangesSince.call(source, version, ranges),\n }\n : {}),\n ...(source.destroy ? { destroy: () => source.destroy?.() } : {}),\n };\n}\n\nconst RANGE_EPSILON_SECONDS = 1e-6;\nconst MAX_CHANGED_RANGE_JOURNAL_LENGTH = 512;\nconst DEFAULT_LIVE_HOLD_SECONDS = 60;\nconst NO_COVERAGE_INVALIDATION = { ranges: [] };\nfunction createWritableDetectionFrameSource(options) {\n const liveHoldSeconds = resolveLiveHoldSeconds(options.live?.holdSeconds);\n let summary = null;\n let latestFrame = null;\n let heldLiveFrame = null;\n // Newest live `mediaTime` accepted so far. It survives retention so a late\n // result cannot reopen coverage the source already moved past.\n let liveFrontierTime = null;\n // Newest media time actually covered by producer-declared data. Live frames\n // are written with a synthetic hold end, so the summary end time cannot be\n // used to place the retention window without pushing it into the future.\n let coverageFrontierTime = null;\n let writeQueue = Promise.resolve();\n let version = 0;\n let allRangeVersion = 0;\n let journalFloorVersion = 0;\n let destroyed = false;\n const changedRanges = [];\n const availableRanges = [];\n const waiters = [];\n const writeOptions = (frames) => ({\n chunkDurationSeconds: options.chunkDurationSeconds,\n datasetId: options.datasetId,\n frames,\n });\n const recordRangeWrite = (nextSummary, changedSourceRanges, invalidation, prunedRange) => {\n summary = nextSummary;\n version += 1;\n for (const changedRange of changedSourceRanges) {\n changedRanges.push({ ...changedRange, version });\n recordAvailableRange(changedRange, availableRanges);\n }\n for (const invalidatedRange of invalidation.ranges) {\n // Coverage a write took away is journaled but never made available: a\n // consumer parked there has to redraw, and nothing new can be loaded.\n changedRanges.push({ ...invalidatedRange, version });\n }\n if (prunedRange) {\n // Evicting old history is a change to that range only. Recording it\n // alongside the append keeps a buffered timeline patching two small\n // ranges instead of invalidating and rebuilding everything it retains.\n changedRanges.push({ ...prunedRange, version });\n dropAvailableRangesBefore(prunedRange.endTime, availableRanges);\n }\n compactChangedRangeJournal();\n resolveCoveredWaiters();\n return nextSummary;\n };\n const recordAllRangesWrite = (nextSummary) => {\n summary = nextSummary;\n version += 1;\n allRangeVersion = version;\n journalFloorVersion = version;\n changedRanges.length = 0;\n availableRanges.length = 0;\n if (nextSummary.startTime !== null && nextSummary.endTime !== null) {\n recordAvailableRange({\n endTime: nextSummary.endTime,\n startTime: nextSummary.startTime,\n }, availableRanges);\n }\n resolveCoveredWaiters();\n return nextSummary;\n };\n return {\n datasetId: options.datasetId,\n async appendFrames(frames) {\n assertActive();\n return enqueueWrite(async () => {\n const nextSummary = await options.store.appendFrames(writeOptions(frames));\n assertActive();\n const changedSourceRanges = getDetectionFrameRanges(frames);\n const invalidation = getInvalidatedCoverage(frames, changedSourceRanges);\n recordLatestFrame(frames);\n recordCoverageFrontierFromFrames(frames);\n return retainAndRecord(nextSummary, changedSourceRanges, invalidation);\n });\n },\n async appendLiveFrame(frame) {\n assertActive();\n return enqueueWrite(async () => {\n if (isStaleLiveFrame(frame)) {\n // A result older than the live frontier no longer describes what is\n // on screen. Writing it would reopen coverage the source already\n // closed, so the newest causal frame simply wins.\n return summary ? { ...summary } : createEmptyWriteSummary();\n }\n const framesToWrite = createLiveFrameWrite(frame);\n const nextSummary = await options.store.appendFrames(writeOptions(framesToWrite));\n assertActive();\n const changedSourceRanges = getDetectionFrameRanges(framesToWrite);\n const invalidation = getInvalidatedCoverage(framesToWrite, changedSourceRanges);\n heldLiveFrame = framesToWrite.at(-1) ?? null;\n liveFrontierTime = Math.max(liveFrontierTime ?? frame.mediaTime, frame.mediaTime);\n recordLatestFrame(framesToWrite);\n // The hold end is a placeholder for \"still current\", not covered data.\n recordCoverageFrontier(getFrameEndTime(frame));\n return retainAndRecord(nextSummary, changedSourceRanges, invalidation);\n });\n },\n async finalizeCoverage(endTime) {\n assertActive();\n if (!Number.isFinite(endTime)) {\n throw new RangeError(\"finalizeCoverage requires a finite endTime.\");\n }\n return enqueueWrite(async () => {\n const frameToFinalize = latestFrame;\n if (!frameToFinalize ||\n // A frame that starts at or after the end of media cannot describe a\n // non-empty terminal interval.\n frameToFinalize.mediaTime >= endTime ||\n getFrameEndTime(frameToFinalize) === endTime) {\n return summary ? { ...summary } : null;\n }\n const previousEndTime = getFrameEndTime(frameToFinalize);\n const finalizedFrame = { ...frameToFinalize, endTime };\n const nextSummary = await options.store.appendFrames(writeOptions([finalizedFrame]));\n assertActive();\n const changedSourceRanges = [\n {\n endTime: Math.max(endTime, previousEndTime),\n startTime: frameToFinalize.mediaTime,\n },\n ];\n const invalidation = getInvalidatedCoverage([finalizedFrame], changedSourceRanges);\n latestFrame = finalizedFrame;\n if (heldLiveFrame &&\n haveSameDetectionFrameIdentity(heldLiveFrame, finalizedFrame)) {\n heldLiveFrame = finalizedFrame;\n }\n coverageFrontierTime = endTime;\n const finalSummary = await retainAndRecord(nextSummary, changedSourceRanges, \n // Finalizing usually closes at the end of media, where the tail an\n // open-ended frame gives up is unreachable. The caller may finalize\n // earlier, though, so report it rather than assume.\n invalidation);\n // Closing a held live frame shortens coverage. Reported availability\n // has to shrink with it, or a playback gate would still believe the\n // source covers time past the end of media.\n clipAvailableRangesAfter(endTime);\n return finalSummary;\n });\n },\n async replaceFrames(frames) {\n assertActive();\n return enqueueWrite(async () => {\n const nextSummary = await options.store.putFrames(writeOptions(frames));\n assertActive();\n latestFrame = null;\n heldLiveFrame = null;\n liveFrontierTime = null;\n coverageFrontierTime = null;\n recordLatestFrame(frames);\n recordCoverageFrontierFromFrames(frames);\n const retention = await applyRetention(nextSummary);\n assertActive();\n return recordAllRangesWrite(retention.kind === \"unchanged\" ? nextSummary : retention.summary);\n });\n },\n async clear() {\n assertActive();\n await enqueueWrite(async () => {\n await options.store.clearDataset(options.datasetId);\n assertActive();\n summary = null;\n latestFrame = null;\n heldLiveFrame = null;\n liveFrontierTime = null;\n coverageFrontierTime = null;\n version += 1;\n allRangeVersion = version;\n journalFloorVersion = version;\n changedRanges.length = 0;\n availableRanges.length = 0;\n });\n },\n async loadFrames(startTime, endTime) {\n assertActive();\n const loadedFrames = await options.store.loadFrames({\n datasetId: options.datasetId,\n endTime,\n startTime,\n });\n assertActive();\n return loadedFrames;\n },\n getSummary() {\n return summary ? { ...summary } : null;\n },\n getAvailableRanges() {\n return availableRanges.map((range) => ({ ...range }));\n },\n waitForRange(range) {\n if (destroyed) {\n return Promise.reject(createDestroyedError());\n }\n if (isRangeCovered(range, availableRanges)) {\n return Promise.resolve();\n }\n return new Promise((resolve, reject) => {\n waiters.push({ range, reject, resolve });\n });\n },\n getVersion(range) {\n if (!range) {\n return version;\n }\n return getRangeVersion(range);\n },\n getChangesSince(previousVersion, ranges) {\n const relevantVersion = ranges.reduce((rangeVersion, range) => Math.max(rangeVersion, getRangeVersion(range)), getReloadFloorVersion());\n if (relevantVersion <= previousVersion) {\n return {\n ranges: [],\n requiresReload: false,\n version: relevantVersion,\n };\n }\n if (previousVersion < getReloadFloorVersion()) {\n return {\n ranges: [],\n requiresReload: true,\n version: relevantVersion,\n };\n }\n // Clipped to the requested ranges: a consumer gets back exactly the part\n // of the change it asked about, and an unbounded invalidation stays a\n // bounded, loadable answer.\n const changedSourceRanges = changedRanges\n .filter((changedRange) => changedRange.version > previousVersion)\n .flatMap((changedRange) => ranges\n .filter((range) => rangesOverlap(range, changedRange))\n .map((range) => {\n const startTime = Math.max(range.startTime, changedRange.startTime);\n const endTime = Math.min(range.endTime, changedRange.endTime);\n return {\n // An unbounded ask against an unbounded invalidation would\n // otherwise hand back an infinite range, and a consumer would\n // take it straight to `loadFrames`. Nothing past the coverage\n // the source knows about can be loaded.\n endTime: Number.isFinite(endTime)\n ? endTime\n : Math.max(startTime, getKnownEndTime()),\n startTime,\n };\n }));\n return {\n ranges: mergeRanges(changedSourceRanges),\n requiresReload: false,\n version: relevantVersion,\n };\n },\n destroy() {\n if (destroyed) {\n return;\n }\n destroyed = true;\n for (const waiter of waiters) {\n waiter.reject(new Error(\"Detection frame source has been destroyed.\"));\n }\n waiters.length = 0;\n options.store.destroy?.();\n },\n };\n function assertActive() {\n if (destroyed) {\n throw createDestroyedError();\n }\n }\n /**\n * Oldest version the journal can still describe incrementally. Anything\n * older has to reload, because replacement, clearing, or journal compaction\n * dropped the intervening changes.\n */\n function getReloadFloorVersion() {\n return Math.max(allRangeVersion, journalFloorVersion);\n }\n /**\n * Latest media time the source can actually serve frames for.\n */\n function getKnownEndTime() {\n return Math.max(coverageFrontierTime ?? 0, summary?.endTime ?? 0);\n }\n function getRangeVersion(range) {\n return changedRanges.reduce((rangeVersion, changedRange) => rangesOverlap(range, changedRange)\n ? Math.max(rangeVersion, changedRange.version)\n : rangeVersion, getReloadFloorVersion());\n }\n /**\n * Runs mutating writes one at a time.\n *\n * Every write reads the held live frame, the latest frame, and the coverage\n * frontier before it awaits storage. Without serialization two concurrent\n * live appends would both observe the pre-write state and both stay open,\n * which is exactly the stale overlay live semantics exist to prevent.\n */\n function enqueueWrite(run) {\n const result = writeQueue.then(() => {\n assertActive();\n return run();\n });\n writeQueue = result.then(() => undefined, () => undefined);\n return result;\n }\n function isStaleLiveFrame(frame) {\n if (liveFrontierTime === null || frame.mediaTime > liveFrontierTime) {\n return false;\n }\n // A frame at the frontier that shares the held frame's identity is a\n // revision of the current result, not a late duplicate of an older one.\n return !(heldLiveFrame && haveSameDetectionFrameIdentity(heldLiveFrame, frame));\n }\n function recordCoverageFrontier(endTime) {\n coverageFrontierTime =\n coverageFrontierTime === null\n ? endTime\n : Math.max(coverageFrontierTime, endTime);\n }\n function recordCoverageFrontierFromFrames(frames) {\n for (const frame of frames) {\n recordCoverageFrontier(getFrameEndTime(frame));\n }\n }\n function clipAvailableRangesAfter(endTime) {\n let writeIndex = 0;\n for (const range of availableRanges) {\n if (range.startTime >= endTime) {\n continue;\n }\n availableRanges[writeIndex] = {\n endTime: Math.min(range.endTime, endTime),\n startTime: range.startTime,\n };\n writeIndex += 1;\n }\n availableRanges.length = writeIndex;\n }\n function createEmptyWriteSummary() {\n return {\n chunkCount: 0,\n chunkDurationSeconds: options.chunkDurationSeconds ?? 1,\n datasetId: options.datasetId,\n detectionCount: 0,\n endTime: null,\n frameCount: 0,\n startTime: null,\n };\n }\n /**\n * Applies retention and records the result as an incremental change when the\n * store can prune in place, or as a full rewrite when it cannot.\n */\n async function retainAndRecord(nextSummary, changedSourceRanges, invalidation = NO_COVERAGE_INVALIDATION) {\n const retention = await applyRetention(nextSummary);\n assertActive();\n if (retention.kind === \"rewritten\") {\n return recordAllRangesWrite(retention.summary);\n }\n if (retention.kind === \"unchanged\") {\n if (changedSourceRanges.length === 0 &&\n invalidation.ranges.length === 0) {\n summary = nextSummary;\n return nextSummary;\n }\n return recordRangeWrite(nextSummary, changedSourceRanges, invalidation);\n }\n forgetFramesBefore(retention.prunedRange.endTime);\n return recordRangeWrite(retention.summary, changedSourceRanges, invalidation, retention.prunedRange);\n }\n async function applyRetention(nextSummary) {\n const retention = options.retention;\n if (retention === undefined ||\n !shouldApplyWindowRetention(retention) ||\n nextSummary.endTime === null) {\n return { kind: \"unchanged\" };\n }\n const retentionWindowSeconds = retention.windowSeconds;\n if (retentionWindowSeconds === undefined ||\n !Number.isFinite(retentionWindowSeconds) ||\n retentionWindowSeconds <= 0) {\n throw new Error(\"retention.windowSeconds must be greater than 0.\");\n }\n // Place the window against real producer coverage. A live frame held open\n // for `holdSeconds` reports a summary end far in the future, and anchoring\n // eviction there would evict everything the producer just wrote.\n const retentionStartTime = Math.max(0, Math.min(coverageFrontierTime ?? nextSummary.endTime, nextSummary.endTime) - retentionWindowSeconds);\n if (nextSummary.startTime !== null &&\n nextSummary.startTime + RANGE_EPSILON_SECONDS >= retentionStartTime) {\n return { kind: \"unchanged\" };\n }\n if (options.store.pruneFrames) {\n return {\n kind: \"pruned\",\n prunedRange: {\n endTime: retentionStartTime,\n startTime: nextSummary.startTime ?? 0,\n },\n summary: await options.store.pruneFrames({\n datasetId: options.datasetId,\n startTime: retentionStartTime,\n }),\n };\n }\n // Stores without in-place pruning still get a correct retention window,\n // at the cost of reloading and rewriting everything they keep.\n const retainedFrames = await options.store.loadFrames({\n datasetId: options.datasetId,\n endTime: nextSummary.endTime,\n startTime: retentionStartTime,\n });\n return {\n kind: \"rewritten\",\n summary: await options.store.putFrames(writeOptions(retainedFrames)),\n };\n }\n /**\n * Builds the one or two frames a live append writes: the newest frame held\n * open, plus the previously held frame closed where the newest begins.\n */\n function createLiveFrameWrite(frame) {\n const openFrame = {\n ...frame,\n endTime: Math.max(frame.endTime ?? frame.mediaTime, frame.mediaTime + liveHoldSeconds),\n };\n const heldFrame = heldLiveFrame;\n // Stale results are rejected before this point, so a held frame that is\n // neither the same frame nor already closed always ends strictly later.\n if (!heldFrame ||\n haveSameDetectionFrameIdentity(heldFrame, openFrame) ||\n getFrameEndTime(heldFrame) <= frame.mediaTime) {\n return [openFrame];\n }\n return [{ ...heldFrame, endTime: frame.mediaTime }, openFrame];\n }\n function recordLatestFrame(frames) {\n for (const frame of frames) {\n if (!latestFrame ||\n compareDetectionFrames(frame, latestFrame) > 0 ||\n // A write that shares the tracked frame's identity replaces its stored\n // record. Keeping the superseded contents here would let a later\n // `finalizeCoverage` write them back over the revision.\n haveSameDetectionFrameIdentity(frame, latestFrame)) {\n latestFrame = frame;\n }\n }\n }\n /**\n * Coverage a write takes away from a frame the source already wrote.\n *\n * The journal describes a write by the interval it covers, which is enough\n * while writes only add. Rewriting a frame with a shorter interval, or at a\n * different time, instead stops covering times the new interval never\n * mentions, and a consumer parked in one of them would keep showing a frame\n * the source no longer selects.\n *\n * A frame without an `endTime` was selected with no upper bound, so what it\n * gives up is genuinely unbounded and is journaled that way. The journal\n * stays range-scoped either way: a consumer asking about times the write\n * never touched still hears that nothing changed.\n */\n function getInvalidatedCoverage(frames, coveredRanges) {\n const invalidatedRanges = [];\n for (const frame of frames) {\n for (const trackedFrame of [latestFrame, heldLiveFrame]) {\n if (!trackedFrame ||\n !haveSameDetectionFrameIdentity(trackedFrame, frame)) {\n continue;\n }\n const previousRange = {\n endTime: trackedFrame.endTime ?? Number.POSITIVE_INFINITY,\n startTime: trackedFrame.mediaTime,\n };\n const nextEndTime = frame.endTime ?? Number.POSITIVE_INFINITY;\n if (trackedFrame.mediaTime >= frame.mediaTime &&\n previousRange.endTime <= nextEndTime) {\n continue;\n }\n // A live append closes the held frame and reopens it further out in the\n // same write, so the write's own range already describes the tail. Only\n // coverage nothing else reported is worth a second journal entry.\n if (isRangeCovered(previousRange, coveredRanges)) {\n continue;\n }\n invalidatedRanges.push(previousRange);\n }\n }\n return { ranges: mergeRanges(invalidatedRanges) };\n }\n function forgetFramesBefore(startTime) {\n if (latestFrame && getFrameEndTime(latestFrame) < startTime) {\n latestFrame = null;\n }\n if (heldLiveFrame && getFrameEndTime(heldLiveFrame) < startTime) {\n heldLiveFrame = null;\n }\n }\n function resolveCoveredWaiters() {\n for (let index = waiters.length - 1; index >= 0; index -= 1) {\n const waiter = waiters[index];\n if (!waiter || !isRangeCovered(waiter.range, availableRanges)) {\n continue;\n }\n waiters.splice(index, 1);\n waiter.resolve();\n }\n }\n function compactChangedRangeJournal() {\n const overflow = changedRanges.length - MAX_CHANGED_RANGE_JOURNAL_LENGTH;\n if (overflow <= 0) {\n return;\n }\n const removedRanges = changedRanges.splice(0, overflow);\n journalFloorVersion = Math.max(journalFloorVersion, removedRanges.at(-1)?.version ?? 0);\n }\n}\nfunction createDestroyedError() {\n return new Error(\"Detection frame source has been destroyed.\");\n}\nfunction resolveLiveHoldSeconds(holdSeconds) {\n if (holdSeconds === undefined) {\n return DEFAULT_LIVE_HOLD_SECONDS;\n }\n if (!Number.isFinite(holdSeconds) || holdSeconds <= 0) {\n throw new RangeError(\"live.holdSeconds must be greater than 0.\");\n }\n return holdSeconds;\n}\nfunction getFrameEndTime(frame) {\n return frame.endTime ?? frame.mediaTime;\n}\nfunction haveSameDetectionFrameIdentity(left, right) {\n return left.frameIndex === undefined || right.frameIndex === undefined\n ? left.frameIndex === right.frameIndex && left.mediaTime === right.mediaTime\n : left.frameIndex === right.frameIndex;\n}\nfunction compareDetectionFrames(left, right) {\n if (left.mediaTime !== right.mediaTime) {\n return left.mediaTime - right.mediaTime;\n }\n return (left.frameIndex ?? 0) - (right.frameIndex ?? 0);\n}\nfunction dropAvailableRangesBefore(startTime, availableRanges) {\n let writeIndex = 0;\n for (const range of availableRanges) {\n if (range.endTime <= startTime) {\n continue;\n }\n availableRanges[writeIndex] = {\n endTime: range.endTime,\n startTime: Math.max(range.startTime, startTime),\n };\n writeIndex += 1;\n }\n availableRanges.length = writeIndex;\n}\nfunction shouldApplyWindowRetention(retention) {\n return (retention?.mode === DetectionFrameRetentionMode.PersistWindow ||\n retention?.mode === DetectionFrameRetentionMode.MemoryOnly);\n}\nfunction getDetectionFrameRanges(frames) {\n return mergeRanges(frames.map((frame) => ({\n endTime: frame.endTime ?? frame.mediaTime,\n startTime: frame.mediaTime,\n })));\n}\nfunction rangesOverlap(left, right) {\n return left.startTime <= right.endTime && right.startTime <= left.endTime;\n}\nfunction mergeRanges(ranges) {\n const sortedRanges = ranges\n .map((range) => ({ ...range }))\n .sort((left, right) => left.startTime - right.startTime);\n const mergedRanges = [];\n for (const range of sortedRanges) {\n const previousRange = mergedRanges.at(-1);\n if (previousRange &&\n range.startTime <= previousRange.endTime + RANGE_EPSILON_SECONDS) {\n previousRange.endTime = Math.max(previousRange.endTime, range.endTime);\n continue;\n }\n mergedRanges.push({ ...range });\n }\n return mergedRanges;\n}\nfunction recordAvailableRange(range, availableRanges) {\n if (range.endTime < range.startTime) {\n return;\n }\n availableRanges.push({ ...range });\n availableRanges.sort((left, right) => left.startTime - right.startTime);\n let writeIndex = 0;\n for (const nextRange of availableRanges) {\n const currentRange = availableRanges[writeIndex - 1];\n if (currentRange &&\n nextRange.startTime <= currentRange.endTime + RANGE_EPSILON_SECONDS) {\n currentRange.endTime = Math.max(currentRange.endTime, nextRange.endTime);\n continue;\n }\n availableRanges[writeIndex] = { ...nextRange };\n writeIndex += 1;\n }\n availableRanges.length = writeIndex;\n}\nfunction isRangeCovered(range, availableRanges) {\n return availableRanges.some((availableRange) => availableRange.startTime <= range.startTime + RANGE_EPSILON_SECONDS &&\n availableRange.endTime + RANGE_EPSILON_SECONDS >= range.endTime);\n}\n\n/**\n * Creates one stateful SORT tracker for a single ordered media sequence.\n *\n * Defaults, lifecycle semantics, and observation-only output mirror\n * roboflow/trackers SORT. Motion predictions remain internal to association.\n */\nfunction createSortTracker$1(options = {}) {\n const lostTrackBuffer = normalizeNonNegativeInteger$1(options.lostTrackBuffer ?? 30, \"lostTrackBuffer\");\n const frameRate = options.frameRate ?? 30;\n const trackActivationThreshold = options.trackActivationThreshold ?? 0.25;\n const minimumConsecutiveFrames = normalizePositiveInteger$1(options.minimumConsecutiveFrames ?? 3, \"minimumConsecutiveFrames\");\n const minimumIouThreshold = options.minimumIouThreshold ?? 0.3;\n if (!Number.isFinite(frameRate) || frameRate <= 0) {\n throw new Error(\"frameRate must be a finite positive value.\");\n }\n normalizeUnitInterval$1(trackActivationThreshold, \"trackActivationThreshold\");\n normalizeUnitInterval$1(minimumIouThreshold, \"minimumIouThreshold\");\n const scaledLostTrackBuffer = (frameRate / 30) * lostTrackBuffer;\n if (!Number.isFinite(scaledLostTrackBuffer)) {\n throw new Error(\"Scaled lostTrackBuffer overflows: frameRate / 30 * lostTrackBuffer must be finite.\");\n }\n const maximumFramesWithoutUpdate = lostTrackBuffer === 0 ? 0 : Math.max(1, Math.ceil(scaledLostTrackBuffer));\n let tracks = [];\n let nextTrackerId = 0;\n let previousFrameIndex;\n return {\n reset() {\n tracks = [];\n nextTrackerId = 0;\n previousFrameIndex = undefined;\n },\n update(detections, frameIndex) {\n const frameStep = resolveFrameStep(frameIndex, previousFrameIndex);\n previousFrameIndex = frameIndex ?? previousFrameIndex;\n const predicted = tracks.map((track) => track.predict(frameStep, frameRate));\n const { matches, unmatchedDetections } = associateDetectionsToTracks(detections, predicted, minimumIouThreshold);\n const trackerIds = new Map();\n for (const match of matches) {\n const track = tracks[match.trackIndex];\n const detection = detections[match.detectionIndex];\n track.update(detection);\n if (track.trackerId === undefined &&\n track.successfulUpdates >= minimumConsecutiveFrames) {\n track.trackerId = nextTrackerId;\n nextTrackerId += 1;\n }\n if (track.trackerId !== undefined) {\n trackerIds.set(detection.detectionIndex, track.trackerId);\n }\n }\n for (const detectionIndex of unmatchedDetections) {\n const detection = detections[detectionIndex];\n if ((detection.confidence ?? 1) >= trackActivationThreshold) {\n tracks.push(new KalmanBoxTrack(detection));\n }\n }\n tracks = tracks.filter((track) => track.timeSinceUpdate <= maximumFramesWithoutUpdate &&\n (track.successfulUpdates >= minimumConsecutiveFrames ||\n track.timeSinceUpdate === 0));\n return {\n activeTrackCount: tracks.length,\n assignments: detections.flatMap((detection) => {\n const trackerId = trackerIds.get(detection.detectionIndex);\n return trackerId === undefined\n ? []\n : [{ detectionIndex: detection.detectionIndex, trackerId }];\n }),\n confirmedTrackCount: tracks.filter((track) => track.trackerId !== undefined).length,\n };\n },\n };\n}\nclass KalmanBoxTrack {\n consecutiveUpdates;\n trackerId;\n successfulUpdates = 1;\n timeSinceUpdate = 0;\n state;\n covariance = identity(8);\n constructor(detection, consecutiveUpdates = false) {\n this.consecutiveUpdates = consecutiveUpdates;\n this.state = [...rectToXyxy(detection.rect), 0, 0, 0, 0].map((value) => [\n value,\n ]);\n }\n predict(frameStep, frameRate) {\n if (this.consecutiveUpdates && this.timeSinceUpdate > 0) {\n this.successfulUpdates = 0;\n }\n const transition = identity(8);\n for (let index = 0; index < 4; index += 1) {\n transition[index][index + 4] = frameStep;\n }\n this.state = multiply(transition, this.state);\n this.covariance = add(multiply(multiply(transition, this.covariance), transpose(transition)), createProcessNoise(frameStep, frameRate));\n // Python SORT counts update calls for the fixed-rate lost-track budget.\n this.timeSinceUpdate += 1;\n return stateToRect(this.state);\n }\n update(detection) {\n const measurement = rectToXyxy(detection.rect).map((value) => [value]);\n const observation = [\n [1, 0, 0, 0, 0, 0, 0, 0],\n [0, 1, 0, 0, 0, 0, 0, 0],\n [0, 0, 1, 0, 0, 0, 0, 0],\n [0, 0, 0, 1, 0, 0, 0, 0],\n ];\n const measurementNoise = scale(identity(4), 0.1);\n const innovation = subtract(measurement, multiply(observation, this.state));\n const covarianceObservationTranspose = multiply(this.covariance, transpose(observation));\n const innovationCovariance = add(multiply(observation, covarianceObservationTranspose), measurementNoise);\n const gain = multiply(covarianceObservationTranspose, inverse(innovationCovariance));\n this.state = add(this.state, multiply(gain, innovation));\n const identityMinusGainObservation = subtract(identity(8), multiply(gain, observation));\n // Joseph form matches the Python implementation and is more stable.\n this.covariance = add(multiply(multiply(identityMinusGainObservation, this.covariance), transpose(identityMinusGainObservation)), multiply(multiply(gain, measurementNoise), transpose(gain)));\n this.timeSinceUpdate = 0;\n this.successfulUpdates += 1;\n }\n getStateRect() {\n return stateToRect(this.state);\n }\n}\nfunction associateDetectionsToTracks(detections, predicted, minimumIouThreshold) {\n if (predicted.length === 0 || detections.length === 0) {\n return {\n matches: [],\n unmatchedDetections: detections.map((_, index) => index),\n };\n }\n // Python SORT associates all detections class-agnostically using standard IoU.\n const scores = predicted.map((rect) => detections.map((detection) => intersectionOverUnion(rect, detection.rect)));\n const candidateMatches = maximizeAssignment(scores);\n const matches = [];\n const matchedDetections = new Set();\n for (const [trackIndex, detectionIndex] of candidateMatches) {\n if (scores[trackIndex][detectionIndex] < minimumIouThreshold)\n continue;\n matches.push({ detectionIndex, trackIndex });\n matchedDetections.add(detectionIndex);\n }\n matches.sort((left, right) => left.trackIndex - right.trackIndex);\n return {\n matches,\n unmatchedDetections: detections.flatMap((_, index) => matchedDetections.has(index) ? [] : [index]),\n };\n}\n/** Hungarian assignment for a rectangular score matrix. */\nfunction maximizeAssignment(scores) {\n if (scores.length === 0 || scores[0]?.length === 0) {\n return [];\n }\n const rowCount = scores.length;\n const columnCount = scores[0].length;\n const transposed = rowCount > columnCount;\n const costs = transposed\n ? Array.from({ length: columnCount }, (_, row) => Array.from({ length: rowCount }, (_, column) => 1 - scores[column][row]))\n : scores.map((row) => row.map((score) => 1 - score));\n const rows = costs.length;\n const columns = costs[0].length;\n const u = new Array(rows + 1).fill(0);\n const v = new Array(columns + 1).fill(0);\n const p = new Array(columns + 1).fill(0);\n const way = new Array(columns + 1).fill(0);\n for (let row = 1; row <= rows; row += 1) {\n p[0] = row;\n let column0 = 0;\n const minValue = new Array(columns + 1).fill(Number.POSITIVE_INFINITY);\n const used = new Array(columns + 1).fill(false);\n do {\n used[column0] = true;\n const row0 = p[column0];\n let delta = Number.POSITIVE_INFINITY;\n let column1 = 0;\n for (let column = 1; column <= columns; column += 1) {\n if (used[column])\n continue;\n const current = costs[row0 - 1][column - 1] - u[row0] - v[column];\n if (current < minValue[column]) {\n minValue[column] = current;\n way[column] = column0;\n }\n if (minValue[column] < delta) {\n delta = minValue[column];\n column1 = column;\n }\n }\n for (let column = 0; column <= columns; column += 1) {\n if (used[column]) {\n u[p[column]] += delta;\n v[column] -= delta;\n }\n else {\n minValue[column] -= delta;\n }\n }\n column0 = column1;\n } while (p[column0] !== 0);\n do {\n const column1 = way[column0];\n p[column0] = p[column1];\n column0 = column1;\n } while (column0 !== 0);\n }\n const assignments = [];\n for (let column = 1; column <= columns; column += 1) {\n if (p[column] === 0)\n continue;\n const row = p[column] - 1;\n assignments.push(transposed ? [column - 1, row] : [row, column - 1]);\n }\n return assignments;\n}\nfunction rectToXyxy(rect) {\n return [\n rect.x - rect.width / 2,\n rect.y - rect.height / 2,\n rect.x + rect.width / 2,\n rect.y + rect.height / 2,\n ];\n}\nfunction stateToRect(state) {\n // The Python XYXY estimator intentionally leaves corner velocities\n // unconstrained. Normalize only at the browser Rect boundary so a crossing\n // prediction cannot violate the positive-width/height storage contract.\n const x1 = Math.min(state[0][0], state[2][0]);\n const y1 = Math.min(state[1][0], state[3][0]);\n const x2 = Math.max(state[0][0], state[2][0]);\n const y2 = Math.max(state[1][0], state[3][0]);\n return {\n height: Math.max(Number.EPSILON, y2 - y1),\n width: Math.max(Number.EPSILON, x2 - x1),\n x: (x1 + x2) / 2,\n y: (y1 + y2) / 2,\n };\n}\nfunction createProcessNoise(frameStep, frameRate) {\n if (Math.abs(frameStep - 1) <= 0.004 * frameRate) {\n return scale(identity(8), 0.01);\n }\n const result = Array.from({ length: 8 }, () => new Array(8).fill(0));\n const dt2 = frameStep * frameStep;\n const dt3 = dt2 * frameStep;\n const dt4 = dt2 * dt2;\n for (let index = 0; index < 4; index += 1) {\n const velocityIndex = index + 4;\n result[index][index] = (0.01 * dt4) / 4;\n result[index][velocityIndex] = (0.01 * dt3) / 2;\n result[velocityIndex][index] = (0.01 * dt3) / 2;\n result[velocityIndex][velocityIndex] = 0.01 * dt2;\n }\n return result;\n}\nfunction intersectionOverUnion(left, right) {\n const leftX = left.x - left.width / 2;\n const leftY = left.y - left.height / 2;\n const rightX = right.x - right.width / 2;\n const rightY = right.y - right.height / 2;\n const intersectionWidth = Math.max(0, Math.min(leftX + left.width, rightX + right.width) -\n Math.max(leftX, rightX));\n const intersectionHeight = Math.max(0, Math.min(leftY + left.height, rightY + right.height) -\n Math.max(leftY, rightY));\n const intersection = intersectionWidth * intersectionHeight;\n const union = left.width * left.height + right.width * right.height - intersection;\n return union <= 0 ? 0 : intersection / union;\n}\nfunction resolveFrameStep(current, previous) {\n if (current === undefined || previous === undefined)\n return 1;\n return Math.max(1, current - previous);\n}\nfunction normalizePositiveInteger$1(value, label) {\n if (!Number.isInteger(value) || value < 1) {\n throw new Error(`${label} must be a positive integer.`);\n }\n return value;\n}\nfunction normalizeNonNegativeInteger$1(value, label) {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`${label} must be a non-negative integer.`);\n }\n return value;\n}\nfunction normalizeUnitInterval$1(value, label) {\n if (!Number.isFinite(value) || value < 0 || value > 1) {\n throw new Error(`${label} must be between 0 and 1.`);\n }\n}\nfunction identity(size) {\n return Array.from({ length: size }, (_, row) => Array.from({ length: size }, (_, column) => (row === column ? 1 : 0)));\n}\nfunction scale(matrix, factor) {\n return matrix.map((row) => row.map((value) => value * factor));\n}\nfunction transpose(matrix) {\n return matrix[0].map((_, column) => matrix.map((row) => row[column]));\n}\nfunction add(left, right) {\n return left.map((row, rowIndex) => row.map((value, columnIndex) => value + right[rowIndex][columnIndex]));\n}\nfunction subtract(left, right) {\n return left.map((row, rowIndex) => row.map((value, columnIndex) => value - right[rowIndex][columnIndex]));\n}\nfunction multiply(left, right) {\n return left.map((row) => right[0].map((_, column) => row.reduce((sum, value, index) => sum + value * right[index][column], 0)));\n}\nfunction inverse(matrix) {\n const size = matrix.length;\n const augmented = matrix.map((row, index) => [\n ...row,\n ...identity(size)[index],\n ]);\n for (let column = 0; column < size; column += 1) {\n let pivot = column;\n for (let row = column + 1; row < size; row += 1) {\n if (Math.abs(augmented[row][column]) >\n Math.abs(augmented[pivot][column])) {\n pivot = row;\n }\n }\n if (Math.abs(augmented[pivot][column]) < 1e-12) {\n throw new Error(\"SORT Kalman covariance is singular.\");\n }\n [augmented[column], augmented[pivot]] = [\n augmented[pivot],\n augmented[column],\n ];\n const divisor = augmented[column][column];\n augmented[column] = augmented[column].map((value) => value / divisor);\n for (let row = 0; row < size; row += 1) {\n if (row === column)\n continue;\n const factor = augmented[row][column];\n augmented[row] = augmented[row].map((value, index) => value - factor * augmented[column][index]);\n }\n }\n return augmented.map((row) => row.slice(size));\n}\n\n/**\n * Creates one stateful ByteTrack tracker for a single ordered media sequence.\n *\n * Defaults and two-stage association mirror roboflow/trackers ByteTrack at\n * source commit 60b21c8a48676784085fbee455559f16b75a7c9a.\n * Motion predictions remain internal; only observed detections receive IDs.\n */\nfunction createByteTrackTracker$1(options = {}) {\n const lostTrackBuffer = normalizeNonNegativeInteger$1(options.lostTrackBuffer ?? 30, \"lostTrackBuffer\");\n const frameRate = options.frameRate ?? 30;\n const trackActivationThreshold = options.trackActivationThreshold ?? 0.7;\n const minimumConsecutiveFrames = normalizePositiveInteger$1(options.minimumConsecutiveFrames ?? 2, \"minimumConsecutiveFrames\");\n const minimumIouThreshold = options.minimumIouThreshold ?? 0.1;\n const highConfidenceDetectionThreshold = options.highConfidenceDetectionThreshold ?? 0.6;\n if (!Number.isFinite(frameRate) || frameRate <= 0) {\n throw new Error(\"frameRate must be a finite positive value.\");\n }\n normalizeUnitInterval$1(trackActivationThreshold, \"trackActivationThreshold\");\n normalizeUnitInterval$1(minimumIouThreshold, \"minimumIouThreshold\");\n normalizeUnitInterval$1(highConfidenceDetectionThreshold, \"highConfidenceDetectionThreshold\");\n const scaledLostTrackBuffer = (frameRate / 30) * lostTrackBuffer;\n if (!Number.isFinite(scaledLostTrackBuffer)) {\n throw new Error(\"Scaled lostTrackBuffer overflows: frameRate / 30 * lostTrackBuffer must be finite.\");\n }\n const maximumFramesWithoutUpdate = lostTrackBuffer === 0 ? 0 : Math.max(1, Math.ceil(scaledLostTrackBuffer));\n let tracks = [];\n let nextTrackerId = 0;\n let previousFrameIndex;\n return {\n reset() {\n tracks = [];\n nextTrackerId = 0;\n previousFrameIndex = undefined;\n },\n update(detections, frameIndex) {\n const frameStep = resolveFrameStep(frameIndex, previousFrameIndex);\n previousFrameIndex = frameIndex ?? previousFrameIndex;\n tracks.forEach((track) => track.predict(frameStep, frameRate));\n const highDetectionIndexes = [];\n const lowDetectionIndexes = [];\n detections.forEach((detection, index) => {\n if ((detection.confidence ?? 1) >= highConfidenceDetectionThreshold) {\n highDetectionIndexes.push(index);\n }\n else {\n lowDetectionIndexes.push(index);\n }\n });\n const assignments = new Map();\n const firstStage = associate(tracks, detections, highDetectionIndexes, minimumIouThreshold);\n for (const match of firstStage.matches) {\n updateMatchedTrack(tracks[match.trackIndex], detections[match.detectionIndex], assignments);\n }\n const remainingTracks = firstStage.unmatchedTrackIndexes.map((index) => tracks[index]);\n const secondStage = associate(remainingTracks, detections, lowDetectionIndexes, minimumIouThreshold);\n for (const match of secondStage.matches) {\n updateMatchedTrack(remainingTracks[match.trackIndex], detections[match.detectionIndex], assignments);\n }\n // Only unmatched high-confidence observations can start a track.\n for (const detectionIndex of firstStage.unmatchedDetectionIndexes) {\n const detection = detections[detectionIndex];\n if ((detection.confidence ?? 1) >= trackActivationThreshold) {\n tracks.push(new KalmanBoxTrack(detection, true));\n }\n }\n // Confirmation is sticky once an ID has been allocated. An unmatched\n // unconfirmed track is discarded immediately, as in Python ByteTrack.\n tracks = tracks.filter((track) => track.timeSinceUpdate <= maximumFramesWithoutUpdate &&\n (track.trackerId !== undefined ||\n track.successfulUpdates >= minimumConsecutiveFrames ||\n track.timeSinceUpdate === 0));\n return {\n activeTrackCount: tracks.length,\n assignments: detections.flatMap((detection) => {\n const trackerId = assignments.get(detection.detectionIndex);\n return trackerId === undefined\n ? []\n : [{ detectionIndex: detection.detectionIndex, trackerId }];\n }),\n confirmedTrackCount: tracks.filter((track) => track.trackerId !== undefined).length,\n };\n },\n };\n function updateMatchedTrack(track, detection, assignments) {\n track.update(detection);\n if (track.trackerId === undefined &&\n track.successfulUpdates >= minimumConsecutiveFrames) {\n track.trackerId = nextTrackerId;\n nextTrackerId += 1;\n }\n if (track.trackerId !== undefined) {\n assignments.set(detection.detectionIndex, track.trackerId);\n }\n }\n}\nfunction associate(tracks, detections, detectionIndexes, minimumIouThreshold) {\n if (tracks.length === 0 || detectionIndexes.length === 0) {\n return {\n matches: [],\n unmatchedDetectionIndexes: [...detectionIndexes],\n unmatchedTrackIndexes: tracks.map((_, index) => index),\n };\n }\n const scores = tracks.map((track) => {\n const predictedRect = track.getStateRect();\n return detectionIndexes.map((detectionIndex) => intersectionOverUnion(predictedRect, detections[detectionIndex].rect));\n });\n const matches = [];\n const matchedTracks = new Set();\n const matchedDetections = new Set();\n for (const [trackIndex, localDetectionIndex] of maximizeAssignment(scores)) {\n if (scores[trackIndex][localDetectionIndex] < minimumIouThreshold) {\n continue;\n }\n const detectionIndex = detectionIndexes[localDetectionIndex];\n matches.push({ detectionIndex, trackIndex });\n matchedTracks.add(trackIndex);\n matchedDetections.add(detectionIndex);\n }\n matches.sort((left, right) => left.trackIndex - right.trackIndex);\n return {\n matches,\n unmatchedDetectionIndexes: detectionIndexes.filter((index) => !matchedDetections.has(index)),\n unmatchedTrackIndexes: tracks.flatMap((_, index) => matchedTracks.has(index) ? [] : [index]),\n };\n}\n\nfunction associateTrackingScores(scores, trackCount, detectionCount, minimumScore, acceptanceScores = scores) {\n const matches = [];\n const matchedTracks = new Set();\n const matchedDetections = new Set();\n for (const [trackIndex, detectionIndex] of maximizeAssignment(scores)) {\n if (acceptanceScores[trackIndex][detectionIndex] < minimumScore)\n continue;\n matches.push({ detectionIndex, trackIndex });\n matchedTracks.add(trackIndex);\n matchedDetections.add(detectionIndex);\n }\n matches.sort((left, right) => left.trackIndex - right.trackIndex);\n return {\n matches,\n unmatchedDetectionIndexes: Array.from({ length: detectionCount }, (_, index) => index).filter((index) => !matchedDetections.has(index)),\n unmatchedTrackIndexes: Array.from({ length: trackCount }, (_, index) => index).filter((index) => !matchedTracks.has(index)),\n };\n}\nfunction pairwiseIou(tracks, detections, bufferRatio = 0) {\n return tracks.map((track) => detections.map((detection) => bufferedIntersectionOverUnion(track, detection, bufferRatio)));\n}\nfunction bufferedIntersectionOverUnion(left, right, bufferRatio) {\n const leftWidth = left.width * (1 + 2 * bufferRatio);\n const leftHeight = left.height * (1 + 2 * bufferRatio);\n const rightWidth = right.width * (1 + 2 * bufferRatio);\n const rightHeight = right.height * (1 + 2 * bufferRatio);\n const leftX = left.x - leftWidth / 2;\n const leftY = left.y - leftHeight / 2;\n const rightX = right.x - rightWidth / 2;\n const rightY = right.y - rightHeight / 2;\n const intersectionWidth = Math.max(0, Math.min(leftX + leftWidth, rightX + rightWidth) - Math.max(leftX, rightX));\n const intersectionHeight = Math.max(0, Math.min(leftY + leftHeight, rightY + rightHeight) -\n Math.max(leftY, rightY));\n const intersection = intersectionWidth * intersectionHeight;\n const union = leftWidth * leftHeight + rightWidth * rightHeight - intersection;\n return union <= 0 ? 0 : intersection / union;\n}\n\n/**\n * Kalman state estimator shared by the browser C-BIoU and OC-SORT ports.\n * Its layouts, covariance update, and gap-scaled constant-velocity model\n * mirror roboflow/trackers at 60b21c8.\n */\nclass TrackingKalmanEstimator {\n representation;\n dimension;\n measurementDimension = 4;\n covariance;\n measurementNoise = identity(4);\n processNoise;\n state;\n baselineProcessNoise;\n positionIndexes;\n velocityIndexes;\n constructor(initialRect, representation) {\n this.representation = representation;\n const measurement = rectToMeasurement(initialRect, representation);\n this.dimension = representation === \"xcycsr\" ? 7 : 8;\n this.positionIndexes =\n representation === \"xcycsr\" ? [0, 1, 2] : [0, 1, 2, 3];\n this.velocityIndexes =\n representation === \"xcycsr\" ? [4, 5, 6] : [4, 5, 6, 7];\n this.state = Array.from({ length: this.dimension }, (_, index) => [\n measurement[index] ?? 0,\n ]);\n this.covariance = identity(this.dimension);\n this.processNoise = identity(this.dimension);\n this.baselineProcessNoise = identity(this.dimension);\n }\n predict(frameStep, frameRate) {\n if (this.representation === \"xcycsr\" &&\n this.state[2][0] + frameStep * this.state[6][0] <= 0) {\n this.state[6][0] = 0;\n }\n const transition = identity(this.dimension);\n this.positionIndexes.forEach((positionIndex, index) => {\n transition[positionIndex][this.velocityIndexes[index]] = frameStep;\n });\n this.processNoise = this.createProcessNoise(frameStep, frameRate);\n this.state = multiply(transition, this.state);\n this.covariance = add(multiply(multiply(transition, this.covariance), transpose(transition)), this.processNoise);\n }\n update(rect) {\n this.updateMeasurement(rectToMeasurement(rect, this.representation));\n }\n updateMeasurement(measurement) {\n const observation = Array.from({ length: 4 }, (_, row) => Array.from({ length: this.dimension }, (_, column) => row === column ? 1 : 0));\n const measurementColumn = measurement.map((value) => [value]);\n const innovation = subtract(measurementColumn, multiply(observation, this.state));\n const covarianceObservationTranspose = multiply(this.covariance, transpose(observation));\n const innovationCovariance = add(multiply(observation, covarianceObservationTranspose), this.measurementNoise);\n const gain = multiply(covarianceObservationTranspose, inverse(innovationCovariance));\n this.state = add(this.state, multiply(gain, innovation));\n const identityMinusGainObservation = subtract(identity(this.dimension), multiply(gain, observation));\n this.covariance = add(multiply(multiply(identityMinusGainObservation, this.covariance), transpose(identityMinusGainObservation)), multiply(multiply(gain, this.measurementNoise), transpose(gain)));\n }\n getRect() {\n return measurementToRect(this.state.slice(0, 4).map((row) => row[0]), this.representation);\n }\n setCovariances(options) {\n if (options.covariance)\n this.covariance = clone(options.covariance);\n if (options.measurementNoise) {\n this.measurementNoise = clone(options.measurementNoise);\n }\n if (options.processNoise) {\n this.processNoise = clone(options.processNoise);\n this.baselineProcessNoise = clone(options.processNoise);\n }\n }\n snapshot() {\n return {\n covariance: clone(this.covariance),\n measurementNoise: clone(this.measurementNoise),\n processNoise: clone(this.processNoise),\n state: clone(this.state),\n };\n }\n restore(snapshot) {\n this.covariance = clone(snapshot.covariance);\n this.measurementNoise = clone(snapshot.measurementNoise);\n this.processNoise = clone(snapshot.processNoise);\n this.state = clone(snapshot.state);\n }\n createProcessNoise(frameStep, frameRate) {\n if (Math.abs(frameStep - 1) <= 0.004 * frameRate) {\n return clone(this.baselineProcessNoise);\n }\n const result = Array.from({ length: this.dimension }, () => new Array(this.dimension).fill(0));\n const dt2 = frameStep * frameStep;\n const dt3 = dt2 * frameStep;\n const dt4 = dt2 * dt2;\n const kinematicIndexes = new Set([\n ...this.positionIndexes,\n ...this.velocityIndexes,\n ]);\n this.positionIndexes.forEach((positionIndex, index) => {\n const velocityIndex = this.velocityIndexes[index];\n const accelerationVariance = this.baselineProcessNoise[velocityIndex][velocityIndex];\n result[positionIndex][positionIndex] = (accelerationVariance * dt4) / 4;\n result[positionIndex][velocityIndex] = (accelerationVariance * dt3) / 2;\n result[velocityIndex][positionIndex] = (accelerationVariance * dt3) / 2;\n result[velocityIndex][velocityIndex] = accelerationVariance * dt2;\n });\n for (let index = 0; index < this.dimension; index += 1) {\n if (!kinematicIndexes.has(index)) {\n result[index][index] = this.baselineProcessNoise[index][index];\n }\n }\n return result;\n }\n}\nfunction rectToMeasurement(rect, representation) {\n if (representation === \"xcycwh\") {\n return [rect.x, rect.y, rect.width, rect.height];\n }\n return [\n rect.x,\n rect.y,\n rect.width * rect.height,\n rect.width / (rect.height + 1e-6),\n ];\n}\nfunction measurementToRect(measurement, representation) {\n const [x, y, third, fourth] = measurement;\n if (representation === \"xcycwh\") {\n return {\n height: Math.max(1e-3, fourth),\n width: Math.max(1e-3, third),\n x,\n y,\n };\n }\n const width = Math.sqrt(third * fourth);\n const height = width === 0 ? 0 : third / width;\n return {\n height: Math.max(Number.EPSILON, height),\n width: Math.max(Number.EPSILON, width),\n x,\n y,\n };\n}\nfunction diagonal(values) {\n return values.map((value, row) => values.map((_, column) => (row === column ? value : 0)));\n}\nfunction scaleMatrix(matrix, factor) {\n return scale(matrix, factor);\n}\nfunction clone(matrix) {\n return matrix.map((row) => [...row]);\n}\n\nconst MINIMUM_DETECTION_CONFIDENCE = 0.1;\nclass CBIoUTrack {\n trackerId;\n successfulUpdates = 1;\n timeSinceUpdate = 0;\n estimator;\n constructor(initial) {\n this.estimator = new TrackingKalmanEstimator(initial.rect, \"xcycwh\");\n this.setInitialNoise(initial.rect.width, initial.rect.height);\n }\n predict(frameStep, frameRate) {\n const current = this.estimator.getRect();\n this.estimator.setCovariances({\n processNoise: this.buildProcessNoise(Math.max(current.width, 1e-3), Math.max(current.height, 1e-3)),\n });\n this.estimator.predict(frameStep, frameRate);\n this.clampState();\n this.timeSinceUpdate += 1;\n }\n update(detection) {\n const current = this.estimator.getRect();\n this.estimator.setCovariances({\n measurementNoise: this.buildMeasurementNoise(Math.max(current.width, 1e-3), Math.max(current.height, 1e-3)),\n });\n this.estimator.update(detection.rect);\n this.clampState();\n this.timeSinceUpdate = 0;\n this.successfulUpdates += 1;\n }\n getRect() {\n return this.estimator.getRect();\n }\n setInitialNoise(width, height) {\n const sigmaPosition = 0.05;\n const sigmaVelocity = 0.00625;\n this.estimator.setCovariances({\n covariance: diagonal([\n (2 * sigmaPosition * width) ** 2,\n (2 * sigmaPosition * height) ** 2,\n (2 * sigmaPosition * width) ** 2,\n (2 * sigmaPosition * height) ** 2,\n (10 * sigmaVelocity * width) ** 2,\n (10 * sigmaVelocity * height) ** 2,\n (10 * sigmaVelocity * width) ** 2,\n (10 * sigmaVelocity * height) ** 2,\n ]),\n measurementNoise: this.buildMeasurementNoise(width, height),\n processNoise: this.buildProcessNoise(width, height),\n });\n }\n buildProcessNoise(width, height) {\n const sigmaPosition = 0.05;\n const sigmaVelocity = 0.00625;\n return diagonal([\n (sigmaPosition * width) ** 2,\n (sigmaPosition * height) ** 2,\n (sigmaPosition * width) ** 2,\n (sigmaPosition * height) ** 2,\n (sigmaVelocity * width) ** 2,\n (sigmaVelocity * height) ** 2,\n (sigmaVelocity * width) ** 2,\n (sigmaVelocity * height) ** 2,\n ]);\n }\n buildMeasurementNoise(width, height) {\n const sigmaMeasurement = 0.05;\n return diagonal([\n (sigmaMeasurement * width) ** 2,\n (sigmaMeasurement * height) ** 2,\n (sigmaMeasurement * width) ** 2,\n (sigmaMeasurement * height) ** 2,\n ]);\n }\n clampState() {\n this.estimator.state[2][0] = Math.max(this.estimator.state[2][0], 1e-3);\n this.estimator.state[3][0] = Math.max(this.estimator.state[3][0], 1e-3);\n }\n}\n/** Creates the detection-only C-BIoU implementation from roboflow/trackers. */\nfunction createCBIoUTracker$1(options = {}) {\n const lostTrackBuffer = normalizeNonNegativeInteger$1(options.lostTrackBuffer ?? 30, \"lostTrackBuffer\");\n const frameRate = options.frameRate ?? 30;\n const trackActivationThreshold = options.trackActivationThreshold ?? 0.7;\n const minimumConsecutiveFrames = normalizePositiveInteger$1(options.minimumConsecutiveFrames ?? 2, \"minimumConsecutiveFrames\");\n const minimumIouThresholdFirstAssociation = options.minimumIouThresholdFirstAssociation ?? 0.2;\n const minimumIouThresholdSecondAssociation = options.minimumIouThresholdSecondAssociation ?? 0.5;\n const minimumIouThresholdUnconfirmedAssociation = options.minimumIouThresholdUnconfirmedAssociation ?? 0.3;\n const highConfidenceDetectionThreshold = options.highConfidenceDetectionThreshold ?? 0.6;\n const instantFirstFrameActivation = options.instantFirstFrameActivation ?? true;\n const bufferRatioFirst = options.bufferRatioFirst ?? 0.3;\n const bufferRatioSecond = options.bufferRatioSecond ?? 0.5;\n if (!Number.isFinite(frameRate) || frameRate <= 0) {\n throw new Error(\"frameRate must be a finite positive value.\");\n }\n normalizeUnitInterval$1(trackActivationThreshold, \"trackActivationThreshold\");\n normalizeUnitInterval$1(minimumIouThresholdFirstAssociation, \"minimumIouThresholdFirstAssociation\");\n normalizeUnitInterval$1(minimumIouThresholdSecondAssociation, \"minimumIouThresholdSecondAssociation\");\n normalizeUnitInterval$1(minimumIouThresholdUnconfirmedAssociation, \"minimumIouThresholdUnconfirmedAssociation\");\n normalizeUnitInterval$1(highConfidenceDetectionThreshold, \"highConfidenceDetectionThreshold\");\n if (!Number.isFinite(bufferRatioFirst) || bufferRatioFirst < 0) {\n throw new Error(\"bufferRatioFirst must be a finite non-negative value.\");\n }\n if (!Number.isFinite(bufferRatioSecond) || bufferRatioSecond < 0) {\n throw new Error(\"bufferRatioSecond must be a finite non-negative value.\");\n }\n const scaledLostTrackBuffer = (frameRate / 30) * lostTrackBuffer;\n if (!Number.isFinite(scaledLostTrackBuffer)) {\n throw new Error(\"Scaled lostTrackBuffer overflows: frameRate / 30 * lostTrackBuffer must be finite.\");\n }\n const maximumFramesWithoutUpdate = lostTrackBuffer === 0 ? 0 : Math.max(1, Math.ceil(scaledLostTrackBuffer));\n let tracks = [];\n let nextTrackerId = 0;\n let frameId = 0;\n let previousFrameIndex;\n return {\n reset() {\n tracks = [];\n nextTrackerId = 0;\n frameId = 0;\n previousFrameIndex = undefined;\n },\n update(detections, frameIndex) {\n const frameStep = resolveFrameStep(frameIndex, previousFrameIndex);\n previousFrameIndex = frameIndex ?? previousFrameIndex;\n frameId += 1;\n tracks.forEach((track) => track.predict(frameStep, frameRate));\n const highDetectionIndexes = [];\n const lowDetectionIndexes = [];\n detections.forEach((detection, index) => {\n const confidence = detection.confidence ?? 1;\n if (confidence >= highConfidenceDetectionThreshold) {\n highDetectionIndexes.push(index);\n }\n else if (confidence > MINIMUM_DETECTION_CONFIDENCE) {\n lowDetectionIndexes.push(index);\n }\n });\n const confirmed = [];\n const unconfirmed = [];\n const lost = [];\n for (const track of tracks) {\n if (track.timeSinceUpdate > 1)\n lost.push(track);\n else if (track.trackerId !== undefined ||\n track.successfulUpdates >= minimumConsecutiveFrames) {\n confirmed.push(track);\n }\n else\n unconfirmed.push(track);\n }\n const assignments = new Map();\n const pool = [...confirmed, ...lost];\n const highDetections = highDetectionIndexes.map((index) => detections[index]);\n const firstScores = pairwiseIou(pool.map((track) => track.getRect()), highDetections.map((detection) => detection.rect), bufferRatioFirst).map((row) => row.map((score, index) => score * (highDetections[index].confidence ?? 1)));\n const firstAssociation = associateTrackingScores(firstScores, pool.length, highDetections.length, minimumIouThresholdFirstAssociation);\n for (const match of firstAssociation.matches) {\n updateMatchedTrack(pool[match.trackIndex], highDetections[match.detectionIndex], assignments);\n }\n const remainingTracked = firstAssociation.unmatchedTrackIndexes\n .map((index) => pool[index])\n .filter((track) => track.timeSinceUpdate === 1);\n const lowDetections = lowDetectionIndexes.map((index) => detections[index]);\n const secondScores = pairwiseIou(remainingTracked.map((track) => track.getRect()), lowDetections.map((detection) => detection.rect), bufferRatioSecond);\n const secondAssociation = associateTrackingScores(secondScores, remainingTracked.length, lowDetections.length, minimumIouThresholdSecondAssociation);\n for (const match of secondAssociation.matches) {\n updateMatchedTrack(remainingTracked[match.trackIndex], lowDetections[match.detectionIndex], assignments);\n }\n let unmatchedHighLocal = [...firstAssociation.unmatchedDetectionIndexes];\n let unmatchedUnconfirmed = unconfirmed.map((_, index) => index);\n if (unconfirmed.length > 0 && unmatchedHighLocal.length > 0) {\n const remainingHigh = unmatchedHighLocal.map((index) => highDetections[index]);\n const unconfirmedScores = pairwiseIou(unconfirmed.map((track) => track.getRect()), remainingHigh.map((detection) => detection.rect), bufferRatioFirst).map((row) => row.map((score, index) => score * (remainingHigh[index].confidence ?? 1)));\n const unconfirmedAssociation = associateTrackingScores(unconfirmedScores, unconfirmed.length, remainingHigh.length, minimumIouThresholdUnconfirmedAssociation);\n unmatchedUnconfirmed = unconfirmedAssociation.unmatchedTrackIndexes;\n for (const match of unconfirmedAssociation.matches) {\n updateMatchedTrack(unconfirmed[match.trackIndex], remainingHigh[match.detectionIndex], assignments);\n }\n unmatchedHighLocal =\n unconfirmedAssociation.unmatchedDetectionIndexes.map((index) => unmatchedHighLocal[index]);\n }\n const unmatchedUnconfirmedTracks = new Set(unmatchedUnconfirmed.map((index) => unconfirmed[index]));\n tracks = tracks.filter((track) => !unmatchedUnconfirmedTracks.has(track));\n for (const localIndex of unmatchedHighLocal) {\n const detection = highDetections[localIndex];\n if ((detection.confidence ?? 1) < trackActivationThreshold)\n continue;\n const track = new CBIoUTrack(detection);\n if (frameId === 1 && instantFirstFrameActivation) {\n track.trackerId = nextTrackerId++;\n assignments.set(detection.detectionIndex, track.trackerId);\n }\n tracks.push(track);\n }\n tracks = tracks.filter((track) => track.timeSinceUpdate <= maximumFramesWithoutUpdate &&\n (track.timeSinceUpdate === 0 ||\n track.trackerId !== undefined ||\n track.successfulUpdates >= minimumConsecutiveFrames));\n return createUpdate(detections, assignments, tracks);\n },\n };\n function updateMatchedTrack(track, detection, assignments) {\n track.update(detection);\n if (track.trackerId === undefined &&\n track.successfulUpdates >= minimumConsecutiveFrames) {\n track.trackerId = nextTrackerId++;\n }\n if (track.trackerId !== undefined) {\n assignments.set(detection.detectionIndex, track.trackerId);\n }\n }\n}\nfunction createUpdate(detections, assignments, tracks) {\n const resolvedAssignments = detections.flatMap((detection) => {\n const trackerId = assignments.get(detection.detectionIndex);\n return trackerId === undefined\n ? []\n : [{ detectionIndex: detection.detectionIndex, trackerId }];\n });\n return {\n activeTrackCount: tracks.length,\n assignments: resolvedAssignments,\n confirmedTrackCount: tracks.filter((track) => track.trackerId !== undefined)\n .length,\n };\n}\n\nclass OCSortTrack {\n deltaT;\n age = 0;\n lastObservation;\n trackerId;\n successfulConsecutiveUpdates = 0;\n timeSinceUpdate = 0;\n velocity;\n frozenState;\n observed = true;\n observations = new Map();\n estimator;\n constructor(initial, deltaT) {\n this.deltaT = deltaT;\n this.lastObservation = initial;\n this.estimator = new TrackingKalmanEstimator(initial.rect, \"xcycsr\");\n this.configureNoise();\n }\n predict(frameStep, frameRate) {\n if (this.observed && this.timeSinceUpdate > 0) {\n this.frozenState = this.estimator.snapshot();\n this.observed = false;\n }\n this.estimator.predict(frameStep, frameRate);\n if (this.timeSinceUpdate > 0) {\n this.successfulConsecutiveUpdates = 0;\n }\n this.timeSinceUpdate += 1;\n this.age += 1;\n }\n update(detection, frameStep, frameRate) {\n const previous = this.getPreviousObservation();\n if (previous) {\n this.velocity = computeVelocity(previous, detection);\n }\n if (!this.observed && this.frozenState) {\n this.unfreeze(detection, frameStep, frameRate);\n }\n this.estimator.update(detection.rect);\n this.observed = true;\n this.timeSinceUpdate = 0;\n this.successfulConsecutiveUpdates += 1;\n this.lastObservation = detection;\n this.observations.set(this.age, detection);\n const cutoff = this.age - this.deltaT;\n for (const age of this.observations.keys()) {\n if (age < cutoff)\n this.observations.delete(age);\n }\n }\n getRect() {\n return this.estimator.getRect();\n }\n getPreviousObservation() {\n if (this.observations.size === 0)\n return undefined;\n for (let index = 0; index < this.deltaT; index += 1) {\n const delta = this.deltaT - index;\n const observation = this.observations.get(this.age - delta);\n if (observation)\n return observation;\n }\n const latestAge = Math.max(...this.observations.keys());\n return this.observations.get(latestAge);\n }\n configureNoise() {\n const measurementNoise = identity(4);\n for (let index = 2; index < 4; index += 1) {\n measurementNoise[index][index] *= 10;\n }\n const covariance = scaleMatrix(identity(7), 10);\n for (let index = 4; index < 7; index += 1) {\n covariance[index][index] *= 1000;\n }\n const processNoise = identity(7);\n processNoise[6][6] *= 0.01;\n for (let index = 4; index < 7; index += 1) {\n processNoise[index][index] *= 0.01;\n }\n this.estimator.setCovariances({\n covariance,\n measurementNoise,\n processNoise,\n });\n }\n unfreeze(detection, frameStep, frameRate) {\n if (!this.frozenState || this.timeSinceUpdate === 0)\n return;\n this.estimator.restore(this.frozenState);\n const timeGap = this.timeSinceUpdate;\n const start = rectToMeasurement(this.lastObservation.rect, \"xcycsr\");\n const end = rectToMeasurement(detection.rect, \"xcycsr\");\n const startWidth = Math.sqrt(start[2] * start[3]);\n const startHeight = start[3] === 0 ? 0 : Math.sqrt(start[2] / start[3]);\n const endWidth = Math.sqrt(end[2] * end[3]);\n const endHeight = end[3] === 0 ? 0 : Math.sqrt(end[2] / end[3]);\n for (let index = 0; index < timeGap; index += 1) {\n const progress = (index + 1) / timeGap;\n const x = start[0] + progress * (end[0] - start[0]);\n const y = start[1] + progress * (end[1] - start[1]);\n const width = startWidth + progress * (endWidth - startWidth);\n const height = startHeight + progress * (endHeight - startHeight);\n this.estimator.updateMeasurement([x, y, width * height, width / height]);\n if (index < timeGap - 1) {\n this.estimator.predict(frameStep, frameRate);\n }\n }\n this.frozenState = undefined;\n }\n}\n/** Creates the observation-centric SORT implementation from roboflow/trackers. */\nfunction createOCSortTracker$1(options = {}) {\n const lostTrackBuffer = normalizeNonNegativeInteger$1(options.lostTrackBuffer ?? 30, \"lostTrackBuffer\");\n const frameRate = options.frameRate ?? 30;\n const minimumConsecutiveFrames = normalizePositiveInteger$1(options.minimumConsecutiveFrames ?? 3, \"minimumConsecutiveFrames\");\n const minimumIouThreshold = options.minimumIouThreshold ?? 0.3;\n const directionConsistencyWeight = options.directionConsistencyWeight ?? 0.2;\n const highConfidenceDetectionThreshold = options.highConfidenceDetectionThreshold ?? 0.6;\n const deltaT = normalizePositiveInteger$1(options.deltaT ?? 3, \"deltaT\");\n if (!Number.isFinite(frameRate) || frameRate <= 0) {\n throw new Error(\"frameRate must be a finite positive value.\");\n }\n normalizeUnitInterval$1(minimumIouThreshold, \"minimumIouThreshold\");\n normalizeUnitInterval$1(directionConsistencyWeight, \"directionConsistencyWeight\");\n normalizeUnitInterval$1(highConfidenceDetectionThreshold, \"highConfidenceDetectionThreshold\");\n const scaledLostTrackBuffer = (frameRate / 30) * lostTrackBuffer;\n if (!Number.isFinite(scaledLostTrackBuffer)) {\n throw new Error(\"Scaled lostTrackBuffer overflows: frameRate / 30 * lostTrackBuffer must be finite.\");\n }\n const maximumFramesWithoutUpdate = lostTrackBuffer === 0 ? 0 : Math.max(1, Math.ceil(scaledLostTrackBuffer));\n let tracks = [];\n let frameCount = 0;\n let nextTrackerId = 0;\n let previousFrameIndex;\n return {\n reset() {\n tracks = [];\n frameCount = 0;\n nextTrackerId = 0;\n previousFrameIndex = undefined;\n },\n update(detections, frameIndex) {\n const frameStep = resolveFrameStep(frameIndex, previousFrameIndex);\n previousFrameIndex = frameIndex ?? previousFrameIndex;\n // Match roboflow/trackers: an empty stream before any track exists is\n // not part of OC-SORT's early-sequence activation window.\n if (tracks.length === 0 && detections.length === 0) {\n return {\n activeTrackCount: 0,\n assignments: [],\n confirmedTrackCount: 0,\n };\n }\n tracks.forEach((track) => track.predict(frameStep, frameRate));\n const highDetectionIndexes = detections.flatMap((detection, index) => detection.confidence === undefined ||\n detection.confidence >= highConfidenceDetectionThreshold\n ? [index]\n : []);\n const highDetections = highDetectionIndexes.map((index) => detections[index]);\n const iouScores = pairwiseIou(tracks.map((track) => track.getRect()), highDetections.map((detection) => detection.rect));\n const combinedScores = iouScores.map((row, trackIndex) => row.map((iou, detectionIndex) => {\n if (directionConsistencyWeight === 0)\n return iou;\n return (iou +\n directionConsistencyWeight *\n directionConsistency(tracks[trackIndex], highDetections[detectionIndex]) *\n (highDetections[detectionIndex].confidence ?? 1));\n }));\n const primary = associateTrackingScores(combinedScores, tracks.length, highDetections.length, minimumIouThreshold, iouScores);\n const assignments = new Map();\n for (const match of primary.matches) {\n updateMatchedTrack(tracks[match.trackIndex], highDetections[match.detectionIndex], assignments, frameStep);\n }\n let remainingHigh = [...primary.unmatchedDetectionIndexes];\n if (primary.unmatchedTrackIndexes.length > 0 &&\n remainingHigh.length > 0) {\n const unmatchedTracks = primary.unmatchedTrackIndexes.map((index) => tracks[index]);\n const unmatchedDetections = remainingHigh.map((index) => highDetections[index]);\n const recoveryScores = pairwiseIou(unmatchedTracks.map((track) => track.lastObservation.rect), unmatchedDetections.map((detection) => detection.rect));\n const recovery = associateTrackingScores(recoveryScores, unmatchedTracks.length, unmatchedDetections.length, minimumIouThreshold);\n for (const match of recovery.matches) {\n updateMatchedTrack(unmatchedTracks[match.trackIndex], unmatchedDetections[match.detectionIndex], assignments, frameStep);\n }\n remainingHigh = recovery.unmatchedDetectionIndexes.map((index) => remainingHigh[index]);\n }\n for (const localIndex of remainingHigh) {\n tracks.push(new OCSortTrack(highDetections[localIndex], deltaT));\n }\n tracks = tracks.filter((track) => track.timeSinceUpdate <= maximumFramesWithoutUpdate);\n frameCount += 1;\n const resolvedAssignments = detections.flatMap((detection) => {\n const trackerId = assignments.get(detection.detectionIndex);\n return trackerId === undefined\n ? []\n : [{ detectionIndex: detection.detectionIndex, trackerId }];\n });\n return {\n activeTrackCount: tracks.length,\n assignments: resolvedAssignments,\n confirmedTrackCount: tracks.filter((track) => track.trackerId !== undefined).length,\n };\n },\n };\n function updateMatchedTrack(track, detection, assignments, frameStep) {\n track.update(detection, frameStep, frameRate);\n const earlySequence = frameCount <= minimumConsecutiveFrames;\n const shouldEmit = (earlySequence && track.timeSinceUpdate === 0) ||\n track.successfulConsecutiveUpdates >= minimumConsecutiveFrames;\n if (shouldEmit) {\n if (track.trackerId === undefined) {\n track.trackerId = nextTrackerId++;\n }\n assignments.set(detection.detectionIndex, track.trackerId);\n }\n }\n}\nfunction computeVelocity(previous, current) {\n const deltaX = current.rect.x - previous.rect.x;\n const deltaY = current.rect.y - previous.rect.y;\n const norm = Math.sqrt(deltaX * deltaX + deltaY * deltaY) + 1e-6;\n return { x: deltaX / norm, y: deltaY / norm };\n}\nfunction directionConsistency(track, detection) {\n if (!track.velocity)\n return 0;\n const reference = track.getPreviousObservation() ?? track.lastObservation;\n const deltaX = detection.rect.x - reference.rect.x;\n const deltaY = detection.rect.y - reference.rect.y;\n const norm = Math.sqrt(deltaX * deltaX + deltaY * deltaY) + 1e-6;\n const cosine = Math.max(-1, Math.min(1, track.velocity.x * (deltaX / norm) + track.velocity.y * (deltaY / norm)));\n const angle = Math.acos(cosine);\n return (Math.PI / 2 - Math.abs(angle)) / Math.PI;\n}\n\n/** Public core facade for the internal tracker engine workspace. */\nfunction createSortTracker(options = {}) {\n return createSortTracker$1(options);\n}\n\n/** Public core facade for the internal tracker engine workspace. */\nfunction createByteTrackTracker(options = {}) {\n return createByteTrackTracker$1(options);\n}\n\n/** Public core facade for the internal tracker engine workspace. */\nfunction createCBIoUTracker(options = {}) {\n return createCBIoUTracker$1(options);\n}\n\n/** Public core facade for the internal tracker engine workspace. */\nfunction createOCSortTracker(options = {}) {\n return createOCSortTracker$1(options);\n}\n\n/** Geometry projected into a tracker. The original detection payload is retained. */\nvar TrackingGeometry;\n(function (TrackingGeometry) {\n TrackingGeometry[\"Box\"] = \"box\";\n TrackingGeometry[\"Mask\"] = \"mask\";\n TrackingGeometry[\"Keypoints\"] = \"keypoints\";\n})(TrackingGeometry || (TrackingGeometry = {}));\n\nvar DetectionMaskPayloadFormat;\n(function (DetectionMaskPayloadFormat) {\n DetectionMaskPayloadFormat[\"RawCocoRle\"] = \"rawCocoRle\";\n DetectionMaskPayloadFormat[\"DeflatedBase64\"] = \"deflatedBase64\";\n})(DetectionMaskPayloadFormat || (DetectionMaskPayloadFormat = {}));\nfunction encodeBinaryMask(data, width, height) {\n assertMaskDimensions(data, width, height);\n const runs = [];\n let currentValue = 0;\n let runLength = 0;\n for (let x = 0; x < width; x += 1) {\n for (let y = 0; y < height; y += 1) {\n const value = data[y * width + x] ? 1 : 0;\n if (value === currentValue) {\n runLength += 1;\n }\n else {\n runs.push(runLength);\n currentValue = value;\n runLength = 1;\n }\n }\n }\n runs.push(runLength);\n return {\n counts: encodeCompressedRleCounts(runs),\n encoding: DetectionMaskEncoding.CompressedRle,\n height,\n width,\n };\n}\n/** Encodes a binary mask and derives its bounds in the same raster traversal. */\nfunction encodeBinaryMaskWithBounds(data, width, height) {\n assertMaskDimensions(data, width, height);\n const runs = [];\n let currentValue = 0;\n let runLength = 0;\n let minX = width;\n let minY = height;\n let maxX = -1;\n let maxY = -1;\n for (let x = 0; x < width; x += 1) {\n for (let y = 0; y < height; y += 1) {\n const value = data[y * width + x] ? 1 : 0;\n if (value) {\n minX = Math.min(minX, x);\n minY = Math.min(minY, y);\n maxX = Math.max(maxX, x);\n maxY = Math.max(maxY, y);\n }\n if (value === currentValue) {\n runLength += 1;\n }\n else {\n runs.push(runLength);\n currentValue = value;\n runLength = 1;\n }\n }\n }\n runs.push(runLength);\n return {\n bounds: maxX < 0\n ? null\n : {\n height: maxY - minY + 1,\n width: maxX - minX + 1,\n x: minX + (maxX - minX + 1) / 2,\n y: minY + (maxY - minY + 1) / 2,\n },\n mask: {\n counts: encodeCompressedRleCounts(runs),\n encoding: DetectionMaskEncoding.CompressedRle,\n height,\n width,\n },\n };\n}\nfunction encodeDetectionMaskPayload(mask, codec) {\n return codec ? codec.deflate(mask.counts) : mask.counts;\n}\nfunction decodeDetectionMaskPayload(payload, width, height, options = {}) {\n const format = options.format ??\n (isDeflatedBase64DetectionMaskPayload(payload)\n ? DetectionMaskPayloadFormat.DeflatedBase64\n : DetectionMaskPayloadFormat.RawCocoRle);\n if (format === DetectionMaskPayloadFormat.DeflatedBase64 && !options.codec) {\n throw new Error(\"A detection mask compression codec is required for deflated payloads.\");\n }\n return {\n counts: format === DetectionMaskPayloadFormat.DeflatedBase64\n ? options.codec.inflate(payload)\n : payload,\n encoding: DetectionMaskEncoding.CompressedRle,\n height,\n width,\n };\n}\n/** Matches the annotation editor's legacy transport-format heuristic. */\nfunction isDeflatedBase64DetectionMaskPayload(value) {\n return value.length > 100 && /^[A-Za-z0-9+/]+={0,2}$/.test(value);\n}\nfunction computeMaskBounds(data, width, height) {\n assertMaskDimensions(data, width, height);\n let minX = width;\n let minY = height;\n let maxX = -1;\n let maxY = -1;\n for (let y = 0; y < height; y += 1) {\n for (let x = 0; x < width; x += 1) {\n if (!data[y * width + x]) {\n continue;\n }\n minX = Math.min(minX, x);\n minY = Math.min(minY, y);\n maxX = Math.max(maxX, x);\n maxY = Math.max(maxY, y);\n }\n }\n if (maxX < 0) {\n return null;\n }\n const boundsWidth = maxX - minX + 1;\n const boundsHeight = maxY - minY + 1;\n return {\n height: boundsHeight,\n width: boundsWidth,\n x: minX + boundsWidth / 2,\n y: minY + boundsHeight / 2,\n };\n}\nfunction computeDetectionMaskRect(mask) {\n const decoded = decodeCompressedRleMask(mask);\n const bounds = computeMaskBounds(decoded.data, decoded.width, decoded.height);\n return bounds ?? undefined;\n}\nfunction detectMaskBorders(data, width, height) {\n assertMaskDimensions(data, width, height);\n const borders = new Uint8Array(data.length);\n for (let y = 0; y < height; y += 1) {\n for (let x = 0; x < width; x += 1) {\n const offset = y * width + x;\n if (!data[offset]) {\n continue;\n }\n if (x === 0 ||\n y === 0 ||\n x === width - 1 ||\n y === height - 1 ||\n !data[offset - 1] ||\n !data[offset + 1] ||\n !data[offset - width] ||\n !data[offset + width]) {\n borders[offset] = 1;\n }\n }\n }\n return borders;\n}\nfunction extractMaskContour(data, width, height) {\n assertMaskDimensions(data, width, height);\n const stride = Math.max(1, Math.floor(height / 100));\n const leftEdge = [];\n const rightEdge = [];\n for (let y = 0; y < height; y += stride) {\n let left = -1;\n let right = -1;\n for (let x = 0; x < width; x += 1) {\n if (data[y * width + x]) {\n left = left === -1 ? x : left;\n right = x;\n }\n }\n if (left !== -1) {\n leftEdge.push({ x: left, y });\n rightEdge.push({ x: right, y });\n }\n }\n return leftEdge.length < 2\n ? undefined\n : [...leftEdge, ...rightEdge.reverse()];\n}\nfunction extractMaskRectRuns(data, width, height) {\n assertMaskDimensions(data, width, height);\n const rects = [];\n const openRects = new Map();\n for (let y = 0; y < height; y += 1) {\n const activeSpans = new Set();\n let x = 0;\n while (x < width) {\n while (x < width && !data[y * width + x]) {\n x += 1;\n }\n if (x >= width) {\n break;\n }\n const startX = x;\n while (x < width && data[y * width + x]) {\n x += 1;\n }\n const runWidth = x - startX;\n const key = `${startX}:${runWidth}`;\n const openRect = openRects.get(key);\n activeSpans.add(key);\n if (openRect && openRect.y + openRect.height === y) {\n openRects.set(key, { ...openRect, height: openRect.height + 1 });\n }\n else {\n if (openRect) {\n rects.push(openRect);\n }\n openRects.set(key, { height: 1, width: runWidth, x: startX, y });\n }\n }\n for (const [key, openRect] of openRects) {\n if (!activeSpans.has(key)) {\n rects.push(openRect);\n openRects.delete(key);\n }\n }\n }\n rects.push(...openRects.values());\n return rects.length > 0 ? rects : undefined;\n}\nfunction assertMaskDimensions(data, width, height) {\n if (!Number.isInteger(width) || width <= 0) {\n throw new Error(\"Mask width must be a positive integer.\");\n }\n if (!Number.isInteger(height) || height <= 0) {\n throw new Error(\"Mask height must be a positive integer.\");\n }\n if (data.length !== width * height) {\n throw new Error(\"Mask data length must equal width * height.\");\n }\n}\n\nfunction centerRectToTopLeftRect(rect) {\n return {\n height: rect.height,\n width: rect.width,\n x: rect.x - rect.width / 2,\n y: rect.y - rect.height / 2,\n };\n}\nfunction topLeftRectToCenterRect(rect) {\n return {\n height: rect.height,\n width: rect.width,\n x: rect.x + rect.width / 2,\n y: rect.y + rect.height / 2,\n };\n}\nfunction getPointsRect(points) {\n if (points.length === 0) {\n return undefined;\n }\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (const point of points) {\n minX = Math.min(minX, point.x);\n minY = Math.min(minY, point.y);\n maxX = Math.max(maxX, point.x);\n maxY = Math.max(maxY, point.y);\n }\n return {\n height: maxY - minY,\n width: maxX - minX,\n x: (minX + maxX) / 2,\n y: (minY + maxY) / 2,\n };\n}\nfunction getDetectionRect(detection) {\n return (detection.rect ??\n getPointsRect(detection.polygon?.points ?? []) ??\n getPointsRect(detection.polyline?.points ?? []) ??\n getPointsRect(detection.keypoints?.points ?? []));\n}\nfunction containsPoint(rect, point, padding = 0) {\n const halfWidth = rect.width / 2;\n const halfHeight = rect.height / 2;\n return (point.x >= rect.x - halfWidth - padding &&\n point.x <= rect.x + halfWidth + padding &&\n point.y >= rect.y - halfHeight - padding &&\n point.y <= rect.y + halfHeight + padding);\n}\nfunction pointInPolygon(point, polygon) {\n if (polygon.length < 3) {\n return false;\n }\n let inside = false;\n for (let currentIndex = 0, previousIndex = polygon.length - 1; currentIndex < polygon.length; previousIndex = currentIndex, currentIndex += 1) {\n const current = polygon[currentIndex];\n const previous = polygon[previousIndex];\n const crossesRay = current.y > point.y !== previous.y > point.y &&\n point.x <\n ((previous.x - current.x) * (point.y - current.y)) /\n (previous.y - current.y) +\n current.x;\n if (crossesRay) {\n inside = !inside;\n }\n }\n return inside;\n}\nfunction distanceToSegment(point, start, end) {\n const deltaX = end.x - start.x;\n const deltaY = end.y - start.y;\n const lengthSquared = deltaX * deltaX + deltaY * deltaY;\n if (lengthSquared === 0) {\n return Math.hypot(point.x - start.x, point.y - start.y);\n }\n const projection = Math.max(0, Math.min(1, ((point.x - start.x) * deltaX + (point.y - start.y) * deltaY) /\n lengthSquared));\n const closestX = start.x + projection * deltaX;\n const closestY = start.y + projection * deltaY;\n return Math.hypot(point.x - closestX, point.y - closestY);\n}\nfunction polygonArea(points) {\n if (points.length < 3) {\n return 0;\n }\n let twiceArea = 0;\n for (let index = 0; index < points.length; index += 1) {\n const current = points[index];\n const next = points[(index + 1) % points.length];\n twiceArea += current.x * next.y - next.x * current.y;\n }\n return Math.abs(twiceArea) / 2;\n}\nfunction rectArea(rect) {\n return rect ? Math.max(0, rect.width) * Math.max(0, rect.height) : 0;\n}\n\nconst DEFAULT_LOST_TRACK_BUFFER = 30;\nconst DEFAULT_FRAME_RATE = 30;\nconst DEFAULT_TRACK_ACTIVATION_THRESHOLD = 0.25;\nconst DEFAULT_MINIMUM_CONSECUTIVE_FRAMES = 3;\nconst DEFAULT_MINIMUM_IOU_THRESHOLD = 0.3;\nconst DEFAULT_BYTE_TRACK_ACTIVATION_THRESHOLD = 0.7;\nconst DEFAULT_BYTE_MINIMUM_CONSECUTIVE_FRAMES = 2;\nconst DEFAULT_BYTE_MINIMUM_IOU_THRESHOLD = 0.1;\nconst DEFAULT_HIGH_CONFIDENCE_DETECTION_THRESHOLD = 0.6;\nconst DEFAULT_CBIOU_FIRST_IOU_THRESHOLD = 0.2;\nconst DEFAULT_CBIOU_SECOND_IOU_THRESHOLD = 0.5;\nconst DEFAULT_CBIOU_UNCONFIRMED_IOU_THRESHOLD = 0.3;\nconst DEFAULT_CBIOU_FIRST_BUFFER_RATIO = 0.3;\nconst DEFAULT_CBIOU_SECOND_BUFFER_RATIO = 0.5;\nconst DEFAULT_OCSORT_DIRECTION_CONSISTENCY_WEIGHT = 0.2;\nconst DEFAULT_OCSORT_DELTA_T = 3;\nconst detectionPostProcessors = {\n tracking: ((options = {}) => {\n const isByteTrack = options.algorithm === \"bytetrack\";\n const isCBIoU = options.algorithm === \"cbiou\";\n const isOCSort = options.algorithm === \"ocsort\";\n const lostTrackBuffer = normalizeNonNegativeInteger(options.lostTrackBuffer, DEFAULT_LOST_TRACK_BUFFER, \"lostTrackBuffer\");\n const frameRate = options.frameRate ?? DEFAULT_FRAME_RATE;\n const trackActivationThreshold = options.trackActivationThreshold ??\n (isByteTrack || isCBIoU\n ? DEFAULT_BYTE_TRACK_ACTIVATION_THRESHOLD\n : DEFAULT_TRACK_ACTIVATION_THRESHOLD);\n const minimumConsecutiveFrames = normalizePositiveInteger(options.minimumConsecutiveFrames, isByteTrack || isCBIoU\n ? DEFAULT_BYTE_MINIMUM_CONSECUTIVE_FRAMES\n : DEFAULT_MINIMUM_CONSECUTIVE_FRAMES, \"minimumConsecutiveFrames\");\n const minimumIouThreshold = options.minimumIouThreshold ??\n (isByteTrack\n ? DEFAULT_BYTE_MINIMUM_IOU_THRESHOLD\n : DEFAULT_MINIMUM_IOU_THRESHOLD);\n if (!Number.isFinite(frameRate) || frameRate <= 0) {\n throw new Error(\"frameRate must be a finite positive value.\");\n }\n normalizeUnitInterval(trackActivationThreshold, \"trackActivationThreshold\");\n normalizeUnitInterval(minimumIouThreshold, \"minimumIouThreshold\");\n const base = {\n geometry: options.geometry ?? TrackingGeometry.Box,\n kind: \"tracking\",\n };\n if (isCBIoU) {\n const highConfidenceDetectionThreshold = options.highConfidenceDetectionThreshold ??\n DEFAULT_HIGH_CONFIDENCE_DETECTION_THRESHOLD;\n const minimumIouThresholdFirstAssociation = options.minimumIouThresholdFirstAssociation ??\n DEFAULT_CBIOU_FIRST_IOU_THRESHOLD;\n const minimumIouThresholdSecondAssociation = options.minimumIouThresholdSecondAssociation ??\n DEFAULT_CBIOU_SECOND_IOU_THRESHOLD;\n const minimumIouThresholdUnconfirmedAssociation = options.minimumIouThresholdUnconfirmedAssociation ??\n DEFAULT_CBIOU_UNCONFIRMED_IOU_THRESHOLD;\n const bufferRatioFirst = options.bufferRatioFirst ?? DEFAULT_CBIOU_FIRST_BUFFER_RATIO;\n const bufferRatioSecond = options.bufferRatioSecond ?? DEFAULT_CBIOU_SECOND_BUFFER_RATIO;\n normalizeUnitInterval(highConfidenceDetectionThreshold, \"highConfidenceDetectionThreshold\");\n normalizeUnitInterval(minimumIouThresholdFirstAssociation, \"minimumIouThresholdFirstAssociation\");\n normalizeUnitInterval(minimumIouThresholdSecondAssociation, \"minimumIouThresholdSecondAssociation\");\n normalizeUnitInterval(minimumIouThresholdUnconfirmedAssociation, \"minimumIouThresholdUnconfirmedAssociation\");\n normalizeNonNegativeFinite(bufferRatioFirst, \"bufferRatioFirst\");\n normalizeNonNegativeFinite(bufferRatioSecond, \"bufferRatioSecond\");\n return {\n ...base,\n algorithm: \"cbiou\",\n options: {\n bufferRatioFirst,\n bufferRatioSecond,\n frameRate,\n highConfidenceDetectionThreshold,\n instantFirstFrameActivation: options.instantFirstFrameActivation ?? true,\n lostTrackBuffer,\n minimumConsecutiveFrames,\n minimumIouThresholdFirstAssociation,\n minimumIouThresholdSecondAssociation,\n minimumIouThresholdUnconfirmedAssociation,\n trackActivationThreshold,\n },\n };\n }\n if (isOCSort) {\n const directionConsistencyWeight = options.directionConsistencyWeight ??\n DEFAULT_OCSORT_DIRECTION_CONSISTENCY_WEIGHT;\n const highConfidenceDetectionThreshold = options.highConfidenceDetectionThreshold ??\n DEFAULT_HIGH_CONFIDENCE_DETECTION_THRESHOLD;\n const deltaT = normalizePositiveInteger(options.deltaT, DEFAULT_OCSORT_DELTA_T, \"deltaT\");\n normalizeUnitInterval(directionConsistencyWeight, \"directionConsistencyWeight\");\n normalizeUnitInterval(highConfidenceDetectionThreshold, \"highConfidenceDetectionThreshold\");\n return {\n ...base,\n algorithm: \"ocsort\",\n options: {\n deltaT,\n directionConsistencyWeight,\n frameRate,\n highConfidenceDetectionThreshold,\n lostTrackBuffer,\n minimumConsecutiveFrames,\n minimumIouThreshold,\n },\n };\n }\n if (isByteTrack) {\n const highConfidenceDetectionThreshold = options.highConfidenceDetectionThreshold ??\n DEFAULT_HIGH_CONFIDENCE_DETECTION_THRESHOLD;\n normalizeUnitInterval(highConfidenceDetectionThreshold, \"highConfidenceDetectionThreshold\");\n return {\n ...base,\n algorithm: \"bytetrack\",\n options: {\n frameRate,\n highConfidenceDetectionThreshold,\n lostTrackBuffer,\n minimumConsecutiveFrames,\n minimumIouThreshold,\n trackActivationThreshold,\n },\n };\n }\n return {\n ...base,\n algorithm: \"sort\",\n options: {\n frameRate,\n lostTrackBuffer,\n minimumConsecutiveFrames,\n minimumIouThreshold,\n trackActivationThreshold,\n },\n };\n }),\n};\n/**\n * Creates the lightweight projection sent to a tracker or tracking worker.\n * Masks and keypoint arrays never cross the worker boundary.\n */\nfunction projectDetectionFrameForTracking(frame, geometry) {\n return frame.detections.flatMap((detection, detectionIndex) => {\n const rect = resolveTrackingRect(detection, geometry);\n if (!rect || rect.width <= 0 || rect.height <= 0) {\n return [];\n }\n return [\n {\n ...(detection.confidence === undefined\n ? {}\n : { confidence: detection.confidence }),\n detectionIndex,\n rect,\n },\n ];\n });\n}\nfunction resolveTrackingRect(detection, geometry) {\n switch (geometry) {\n case TrackingGeometry.Box:\n return detection.rect;\n case TrackingGeometry.Mask:\n if (!detection.mask) {\n return undefined;\n }\n // Most segmentation producers already supply the exact mask bounds as a\n // rect. Decode RLE only when that inexpensive projection is absent.\n return detection.rect ?? computeDetectionMaskRect(detection.mask);\n case TrackingGeometry.Keypoints:\n return detection.keypoints\n ? getPointsRect(detection.keypoints.points)\n : undefined;\n }\n}\nfunction normalizePositiveInteger(value, fallback, label) {\n const resolved = value ?? fallback;\n if (!Number.isInteger(resolved) || resolved < 1) {\n throw new Error(`${label} must be a positive integer.`);\n }\n return resolved;\n}\nfunction normalizeNonNegativeInteger(value, fallback, label) {\n const resolved = value ?? fallback;\n if (!Number.isInteger(resolved) || resolved < 0) {\n throw new Error(`${label} must be a non-negative integer.`);\n }\n return resolved;\n}\nfunction normalizeUnitInterval(value, label) {\n if (!Number.isFinite(value) || value < 0 || value > 1) {\n throw new Error(`${label} must be between 0 and 1.`);\n }\n}\nfunction normalizeNonNegativeFinite(value, label) {\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`${label} must be a finite non-negative value.`);\n }\n}\n\nvar DetectionPickTarget;\n(function (DetectionPickTarget) {\n DetectionPickTarget[\"Box\"] = \"box\";\n DetectionPickTarget[\"Edge\"] = \"edge\";\n DetectionPickTarget[\"Keypoint\"] = \"keypoint\";\n DetectionPickTarget[\"Label\"] = \"label\";\n DetectionPickTarget[\"Mask\"] = \"mask\";\n DetectionPickTarget[\"Polygon\"] = \"polygon\";\n DetectionPickTarget[\"Polyline\"] = \"polyline\";\n})(DetectionPickTarget || (DetectionPickTarget = {}));\nvar MediaInteractionMode;\n(function (MediaInteractionMode) {\n MediaInteractionMode[\"Always\"] = \"always\";\n MediaInteractionMode[\"Disabled\"] = \"disabled\";\n MediaInteractionMode[\"PausedOnly\"] = \"pausedOnly\";\n})(MediaInteractionMode || (MediaInteractionMode = {}));\n\nconst decodedMaskCache = new WeakMap();\nfunction pickDetectionAtPoint(frame, point, options = {}) {\n if (!frame) {\n return null;\n }\n const padding = Math.max(0, options.padding ?? 0);\n const polylinePadding = Math.max(0, options.polylinePadding ?? 6);\n const keypointPadding = Math.max(0, options.keypointPadding ?? 10);\n const edgePadding = Math.max(0, options.edgePadding ?? 8);\n const candidates = [];\n for (let detectionIndex = 0; detectionIndex < frame.detections.length; detectionIndex += 1) {\n const detection = frame.detections[detectionIndex];\n if (!detection ||\n (detection.locked && options.includeLocked === false) ||\n options.filter?.(detection, detectionIndex) === false) {\n continue;\n }\n const detectionArea = Math.max(1, rectArea(getDetectionRect(detection)));\n const pushCandidate = (target, area = detectionArea, geometryIndex) => {\n candidates.push({\n area,\n priority: getPickTargetPriority(target),\n result: {\n detection,\n detectionIndex,\n frame,\n geometryIndex,\n mediaTime: frame.mediaTime,\n point,\n target,\n },\n zIndex: detection.zIndex ?? detectionIndex,\n });\n };\n if (detection.rect && containsPoint(detection.rect, point, padding)) {\n pushCandidate(DetectionPickTarget.Box, rectArea(detection.rect));\n }\n if (detection.polygon && pointInPolygon(point, detection.polygon.points)) {\n pushCandidate(DetectionPickTarget.Polygon, Math.max(1, polygonArea(detection.polygon.points)));\n }\n if (detection.polyline) {\n const segmentIndex = findHitSegment(point, detection.polyline.points, polylinePadding);\n if (segmentIndex !== -1) {\n pushCandidate(DetectionPickTarget.Polyline, detectionArea, segmentIndex);\n }\n }\n if (detection.keypoints) {\n const keypointIndex = detection.keypoints.points.findIndex((keypoint, index) => detection.keypoints?.visibility?.[index] !==\n KeypointVisibility.NotLabeled &&\n Math.hypot(point.x - keypoint.x, point.y - keypoint.y) <=\n keypointPadding);\n if (keypointIndex !== -1) {\n pushCandidate(DetectionPickTarget.Keypoint, Math.PI * keypointPadding * keypointPadding, keypointIndex);\n }\n else {\n const edgeIndex = detection.keypoints.edges.findIndex(([fromIndex, toIndex]) => {\n const from = detection.keypoints?.points[fromIndex];\n const to = detection.keypoints?.points[toIndex];\n return Boolean(from &&\n to &&\n detection.keypoints?.visibility?.[fromIndex] !==\n KeypointVisibility.NotLabeled &&\n detection.keypoints?.visibility?.[toIndex] !==\n KeypointVisibility.NotLabeled &&\n distanceToSegment(point, from, to) <= edgePadding);\n });\n if (edgeIndex !== -1) {\n const [fromIndex, toIndex] = detection.keypoints.edges[edgeIndex];\n const from = detection.keypoints.points[fromIndex];\n const to = detection.keypoints.points[toIndex];\n const edgeArea = Math.max(1, Math.hypot(to.x - from.x, to.y - from.y) * edgePadding * 2);\n pushCandidate(DetectionPickTarget.Edge, edgeArea, edgeIndex);\n }\n }\n }\n if (detection.mask && options.includeMasks !== false) {\n const decoded = getDecodedMask(detection.mask);\n const mediaDimensions = options.maskMediaDimensions;\n const x = Math.floor(mediaDimensions && mediaDimensions.width > 0\n ? (point.x / mediaDimensions.width) * decoded.width\n : point.x);\n const y = Math.floor(mediaDimensions && mediaDimensions.height > 0\n ? (point.y / mediaDimensions.height) * decoded.height\n : point.y);\n if (x >= 0 &&\n y >= 0 &&\n x < decoded.width &&\n y < decoded.height &&\n decoded.data[y * decoded.width + x]) {\n pushCandidate(DetectionPickTarget.Mask, getMaskMediaArea(decoded, mediaDimensions));\n }\n }\n }\n candidates.sort((left, right) => {\n const priorityDifference = left.priority - right.priority;\n if (priorityDifference !== 0) {\n return priorityDifference;\n }\n const areaDifference = left.area - right.area;\n if (areaDifference !== 0) {\n return areaDifference;\n }\n const zIndexDifference = right.zIndex - left.zIndex;\n return zIndexDifference === 0\n ? right.result.detectionIndex - left.result.detectionIndex\n : zIndexDifference;\n });\n return candidates[0]?.result ?? null;\n}\nfunction getPickTargetPriority(target) {\n switch (target) {\n case DetectionPickTarget.Keypoint:\n return 0;\n case DetectionPickTarget.Edge:\n case DetectionPickTarget.Polyline:\n return 1;\n default:\n return 2;\n }\n}\nfunction getDecodedMask(mask) {\n const cached = decodedMaskCache.get(mask);\n if (cached)\n return cached;\n const decoded = decodeCompressedRleMask(mask);\n const result = {\n ...decoded,\n pixelArea: countMaskPixels(decoded.data),\n };\n decodedMaskCache.set(mask, result);\n return result;\n}\nfunction getMaskMediaArea(mask, mediaDimensions) {\n if (!mediaDimensions ||\n mediaDimensions.width <= 0 ||\n mediaDimensions.height <= 0) {\n return mask.pixelArea;\n }\n return (mask.pixelArea *\n (mediaDimensions.width / mask.width) *\n (mediaDimensions.height / mask.height));\n}\nfunction createDetectionPickKey(pick) {\n if (!pick) {\n return null;\n }\n const frameKey = [pick.frame.frameIndex ?? \"time\", pick.frame.mediaTime];\n const detectionKey = detectionPickKey(pick);\n return [\n ...frameKey,\n ...detectionKey,\n pick.target,\n pick.geometryIndex ?? \"geometry\",\n ].join(\":\");\n}\n/**\n * Compares the frame-independent membership of two ordered selections.\n *\n * Detection ids retain their runtime type, so numeric `1` and string `\"1\"`\n * remain distinct identities. Anonymous detections keep their frame-local\n * index identity.\n */\nfunction haveSameDetectionPickIdentities(current, next) {\n if (current.length !== next.length) {\n return false;\n }\n return current.every((pick, index) => {\n const nextPick = next[index];\n if (!nextPick) {\n return false;\n }\n const id = pick.detection.id;\n const nextId = nextPick.detection.id;\n return id === undefined || nextId === undefined\n ? id === nextId && pick.detectionIndex === nextPick.detectionIndex\n : typeof id === typeof nextId && id === nextId;\n });\n}\nfunction rebaseDetectionPickToFrame(pick, frame) {\n if (!pick || !frame) {\n return null;\n }\n const detectionIndex = pick.detection.id === undefined ||\n !hasUniqueDetectionId(pick.frame, pick.detection.id)\n ? pick.detectionIndex\n : frame.detections.findIndex((detection) => detection.id === pick.detection.id);\n const detection = frame.detections[detectionIndex];\n if (!detection) {\n return null;\n }\n const rebasedPick = {\n detection,\n detectionIndex,\n frame,\n geometryIndex: pick.geometryIndex,\n mediaTime: frame.mediaTime,\n point: pick.point,\n target: pick.target,\n };\n return createDetectionPickKey(rebasedPick) === createDetectionPickKey(pick)\n ? rebasedPick\n : null;\n}\n/**\n * Carries a pick forward onto a different frame of the same timeline.\n *\n * Same-frame rebases behave exactly like `rebaseDetectionPickToFrame`. Across\n * frames, the pick follows its detection only when the detection id is defined\n * and unique in both frames, so anonymous and duplicate-id detections keep the\n * per-frame lifetime they have today. Returns `null` when the detection has no\n * followable identity or has left the frame.\n */\nfunction followDetectionPickAcrossFrames(pick, frame) {\n const rebasedPick = rebaseDetectionPickToFrame(pick, frame);\n if (rebasedPick || !pick || !frame) {\n return rebasedPick;\n }\n const id = pick.detection.id;\n if (id === undefined ||\n !hasUniqueDetectionId(pick.frame, id) ||\n !hasUniqueDetectionId(frame, id)) {\n return null;\n }\n const detectionIndex = frame.detections.findIndex((detection) => detection.id === id);\n const detection = frame.detections[detectionIndex];\n if (!detection) {\n return null;\n }\n return {\n detection,\n detectionIndex,\n frame,\n geometryIndex: pick.geometryIndex,\n mediaTime: frame.mediaTime,\n point: pick.point,\n target: pick.target,\n };\n}\nfunction detectionPickKey(pick) {\n if (pick.detection.id === undefined) {\n return [\"anonymous\", pick.detectionIndex];\n }\n const idType = typeof pick.detection.id;\n return hasUniqueDetectionId(pick.frame, pick.detection.id)\n ? [\"id\", idType, String(pick.detection.id)]\n : [\n \"duplicate-id\",\n idType,\n String(pick.detection.id),\n \"index\",\n pick.detectionIndex,\n ];\n}\nfunction hasUniqueDetectionId(frame, id) {\n let count = 0;\n for (const detection of frame.detections) {\n if (detection.id !== id)\n continue;\n count += 1;\n if (count > 1)\n return false;\n }\n return count === 1;\n}\nfunction pickDetectionByMaskId(frame, maskId, point) {\n if (!frame || maskId <= 0 || !Number.isInteger(maskId)) {\n return null;\n }\n const detectionIndex = maskId - 1;\n const detection = frame.detections[detectionIndex];\n if (!detection) {\n return null;\n }\n return {\n detection,\n detectionIndex,\n frame,\n mediaTime: frame.mediaTime,\n point,\n target: DetectionPickTarget.Mask,\n };\n}\nfunction findHitSegment(point, points, padding, closed) {\n const segmentCount = points.length - 1;\n for (let index = 0; index < segmentCount; index += 1) {\n const start = points[index];\n const end = points[(index + 1) % points.length];\n if (start && end && distanceToSegment(point, start, end) <= padding) {\n return index;\n }\n }\n return -1;\n}\nfunction countMaskPixels(data) {\n let count = 0;\n for (const value of data) {\n count += value ? 1 : 0;\n }\n return Math.max(1, count);\n}\n\nconst MIN_SCALE = 0.1;\nconst MAX_SCALE = 10;\nconst MAX_WHEEL_DELTA = 50;\nfunction createViewportController(initial = {}) {\n let transform = freeze({\n locked: initial.locked ?? false,\n scale: clampScale(initial.scale ?? 0.8),\n x: initial.x ?? 0,\n y: initial.y ?? 0,\n });\n const listeners = new Set();\n const update = (next) => {\n if (next.scale === transform.scale &&\n next.x === transform.x &&\n next.y === transform.y &&\n next.locked === transform.locked)\n return;\n transform = freeze(next);\n for (const listener of listeners)\n listener(transform);\n };\n const controller = {\n getTransform: () => transform,\n screenToMedia: (point) => screenToMedia(point, transform),\n mediaToScreen: (point) => mediaToScreen(point, transform),\n setTransform(next) {\n if (transform.locked)\n return;\n update({\n ...transform,\n ...(next.scale === undefined ? {} : { scale: clampScale(next.scale) }),\n ...(next.x === undefined ? {} : { x: next.x }),\n ...(next.y === undefined ? {} : { y: next.y }),\n });\n },\n setLocked(locked) {\n update({ ...transform, locked });\n },\n panBy(dx, dy) {\n if (transform.locked)\n return;\n update({ ...transform, x: transform.x + dx, y: transform.y + dy });\n },\n zoomAt(point, factor) {\n if (transform.locked || !Number.isFinite(factor) || factor <= 0)\n return;\n const mediaPoint = screenToMedia(point, transform);\n const scale = clampScale(transform.scale * factor);\n update({\n ...transform,\n scale,\n x: point.x - mediaPoint.x * scale,\n y: point.y - mediaPoint.y * scale,\n });\n },\n zoomFromWheel(point, deltaY) {\n const delta = Math.max(-MAX_WHEEL_DELTA, Math.min(MAX_WHEEL_DELTA, deltaY));\n controller.zoomAt(point, Math.exp(-delta * 0.01));\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n return controller;\n}\nfunction screenToMedia(point, transform) {\n return {\n x: (point.x - transform.x) / transform.scale,\n y: (point.y - transform.y) / transform.scale,\n };\n}\nfunction mediaToScreen(point, transform) {\n return {\n x: point.x * transform.scale + transform.x,\n y: point.y * transform.scale + transform.y,\n };\n}\nfunction clampScale(scale) {\n return Math.max(MIN_SCALE, Math.min(MAX_SCALE, Number.isFinite(scale) ? scale : 1));\n}\nfunction freeze(transform) {\n return Object.freeze(transform);\n}\n\nvar AnnotationGeometryKind;\n(function (AnnotationGeometryKind) {\n AnnotationGeometryKind[\"Box\"] = \"box\";\n AnnotationGeometryKind[\"Polygon\"] = \"polygon\";\n AnnotationGeometryKind[\"Polyline\"] = \"polyline\";\n AnnotationGeometryKind[\"Keypoints\"] = \"keypoints\";\n AnnotationGeometryKind[\"Mask\"] = \"mask\";\n})(AnnotationGeometryKind || (AnnotationGeometryKind = {}));\nvar AnnotationGestureStateKind;\n(function (AnnotationGestureStateKind) {\n AnnotationGestureStateKind[\"Idle\"] = \"idle\";\n AnnotationGestureStateKind[\"Creating\"] = \"creating\";\n AnnotationGestureStateKind[\"Moving\"] = \"moving\";\n AnnotationGestureStateKind[\"Resizing\"] = \"resizing\";\n AnnotationGestureStateKind[\"DragSelecting\"] = \"dragSelecting\";\n})(AnnotationGestureStateKind || (AnnotationGestureStateKind = {}));\nvar AnnotationHandleKind;\n(function (AnnotationHandleKind) {\n AnnotationHandleKind[\"Resize\"] = \"resize\";\n AnnotationHandleKind[\"Vertex\"] = \"vertex\";\n AnnotationHandleKind[\"AddVertex\"] = \"addVertex\";\n AnnotationHandleKind[\"Keypoint\"] = \"keypoint\";\n})(AnnotationHandleKind || (AnnotationHandleKind = {}));\n\nconst HANDLE_RADIUS = 6;\nconst ADD_HANDLE_RADIUS = 3.6;\nconst HANDLE_HIT_SIZE = 16;\nfunction getAnnotationHandles(detection, viewportScale = 1) {\n if (detection.locked || detection.mask)\n return [];\n const radius = HANDLE_RADIUS / viewportScale;\n const hitSize = HANDLE_HIT_SIZE / viewportScale;\n if (detection.polygon)\n return getPathHandles(detection.polygon.points, true, radius, hitSize);\n if (detection.polyline)\n return getPathHandles(detection.polyline.points, false, radius, hitSize);\n if (detection.keypoints) {\n return detection.keypoints.points.map((point, geometryIndex) => ({\n cursor: \"move\",\n geometryIndex,\n hitSize,\n id: `kp-${geometryIndex}`,\n kind: AnnotationHandleKind.Keypoint,\n point,\n radius,\n }));\n }\n if (detection.rect)\n return getBoxHandles(detection.rect, radius, hitSize);\n return [];\n}\nfunction pickAnnotationHandle(handles, point) {\n return [...handles]\n .reverse()\n .find((handle) => Math.abs(point.x - handle.point.x) <= handle.hitSize / 2 &&\n Math.abs(point.y - handle.point.y) <= handle.hitSize / 2);\n}\nfunction applyAnnotationHandleDrag(detection, handle, point) {\n if (detection.rect && handle.kind === AnnotationHandleKind.Resize) {\n return { ...detection, rect: resizeRect(detection.rect, handle.id, point) };\n }\n if (handle.kind === AnnotationHandleKind.AddVertex &&\n handle.edgeIndex !== undefined) {\n const key = detection.polygon ? \"polygon\" : \"polyline\";\n const geometry = detection[key];\n if (!geometry)\n return detection;\n const points = [...geometry.points];\n points.splice(handle.edgeIndex + 1, 0, point);\n return { ...detection, [key]: { points } };\n }\n if (handle.geometryIndex === undefined)\n return detection;\n if (detection.polygon)\n return replacePathPoint(detection, \"polygon\", handle.geometryIndex, point);\n if (detection.polyline)\n return replacePathPoint(detection, \"polyline\", handle.geometryIndex, point);\n if (detection.keypoints) {\n const points = [...detection.keypoints.points];\n points[handle.geometryIndex] = point;\n return { ...detection, keypoints: { ...detection.keypoints, points } };\n }\n return detection;\n}\nfunction deleteAnnotationVertex(detection, vertexIndex) {\n const geometry = detection.polygon ?? detection.polyline;\n const minimum = detection.polygon ? 3 : 2;\n if (!geometry || geometry.points.length <= minimum)\n return null;\n const points = geometry.points.filter((_, index) => index !== vertexIndex);\n return detection.polygon\n ? { ...detection, polygon: { points } }\n : { ...detection, polyline: { points } };\n}\nfunction offsetDetection(detection, dx, dy) {\n const offsetPoint = ({ x, y }) => ({ x: x + dx, y: y + dy });\n return {\n ...detection,\n ...(detection.rect\n ? {\n rect: {\n ...detection.rect,\n x: detection.rect.x + dx,\n y: detection.rect.y + dy,\n },\n }\n : {}),\n ...(detection.polygon\n ? { polygon: { points: detection.polygon.points.map(offsetPoint) } }\n : {}),\n ...(detection.polyline\n ? { polyline: { points: detection.polyline.points.map(offsetPoint) } }\n : {}),\n ...(detection.keypoints\n ? {\n keypoints: {\n ...detection.keypoints,\n points: detection.keypoints.points.map(offsetPoint),\n },\n }\n : {}),\n };\n}\nfunction getBoxHandles(rect, radius, hitSize) {\n const left = rect.x - rect.width / 2;\n const right = rect.x + rect.width / 2;\n const top = rect.y - rect.height / 2;\n const bottom = rect.y + rect.height / 2;\n const definitions = [\n [\"nw\", { x: left, y: top }, \"nwse-resize\"],\n [\"n\", { x: rect.x, y: top }, \"ns-resize\"],\n [\"ne\", { x: right, y: top }, \"nesw-resize\"],\n [\"e\", { x: right, y: rect.y }, \"ew-resize\"],\n [\"se\", { x: right, y: bottom }, \"nwse-resize\"],\n [\"s\", { x: rect.x, y: bottom }, \"ns-resize\"],\n [\"sw\", { x: left, y: bottom }, \"nesw-resize\"],\n [\"w\", { x: left, y: rect.y }, \"ew-resize\"],\n ];\n return definitions.map(([id, point, cursor]) => ({\n cursor,\n hitSize,\n id,\n kind: AnnotationHandleKind.Resize,\n point,\n radius,\n }));\n}\nfunction getPathHandles(points, closed, radius, hitSize) {\n const handles = points.map((point, geometryIndex) => ({\n cursor: \"move\",\n geometryIndex,\n hitSize,\n id: `vertex-${geometryIndex}`,\n kind: AnnotationHandleKind.Vertex,\n point,\n radius,\n }));\n const edgeCount = closed ? points.length : Math.max(0, points.length - 1);\n for (let edgeIndex = 0; edgeIndex < edgeCount; edgeIndex += 1) {\n const from = points[edgeIndex];\n const to = points[(edgeIndex + 1) % points.length];\n handles.push({\n cursor: \"copy\",\n edgeIndex,\n hitSize,\n id: `add-${edgeIndex}`,\n kind: AnnotationHandleKind.AddVertex,\n point: { x: (from.x + to.x) / 2, y: (from.y + to.y) / 2 },\n radius: ADD_HANDLE_RADIUS / (HANDLE_RADIUS / radius),\n });\n }\n return handles;\n}\nfunction resizeRect(rect, handle, point) {\n let left = rect.x - rect.width / 2;\n let right = rect.x + rect.width / 2;\n let top = rect.y - rect.height / 2;\n let bottom = rect.y + rect.height / 2;\n if (handle.includes(\"w\"))\n left = Math.min(point.x, right - 5);\n if (handle.includes(\"e\"))\n right = Math.max(point.x, left + 5);\n if (handle.includes(\"n\"))\n top = Math.min(point.y, bottom - 5);\n if (handle.includes(\"s\"))\n bottom = Math.max(point.y, top + 5);\n return {\n x: (left + right) / 2,\n y: (top + bottom) / 2,\n width: right - left,\n height: bottom - top,\n };\n}\nfunction replacePathPoint(detection, key, index, point) {\n const geometry = detection[key];\n const points = [...geometry.points];\n points[index] = point;\n return { ...detection, [key]: { points } };\n}\n/** Finds the closest path segment, useful for contextual vertex insertion. */\nfunction findClosestAnnotationSegment(points, point, closed) {\n const count = closed ? points.length : points.length - 1;\n let best;\n for (let index = 0; index < count; index += 1) {\n const distance = distanceToSegment(point, points[index], points[(index + 1) % points.length]);\n if (!best || distance < best.distance)\n best = { index, distance };\n }\n return best;\n}\n\nconst MOVE_THRESHOLD = 4;\nconst CLICK_CANCEL_MS = 250;\nconst CLICK_CANCEL_DIAGONAL = 25;\nconst CLOSE_ZONE_SCREEN_PX = 12;\nfunction createAnnotationEditingEngine(options = {}) {\n let tool = null;\n let gesture = null;\n let state = idleState();\n const stateListeners = new Set();\n const fastTranslateListeners = new Set();\n return {\n getState: () => state,\n setCreationTool(nextTool) {\n if (gesture)\n cancel();\n tool = nextTool;\n },\n pointerDown(input, pick = null) {\n if (input.button !== undefined && input.button !== 0)\n return;\n if (tool) {\n beginCreation(input);\n }\n else if (pick && !pick.detection.locked && !pick.detection.mask) {\n beginMove(pick, input);\n }\n },\n pointerMove(input) {\n if (!gesture)\n return;\n switch (gesture.kind) {\n case \"box\":\n gesture = { ...gesture, current: input };\n setPreview(resolveBoxPreview(gesture));\n break;\n case \"move\": {\n const dx = input.point.x - gesture.start.point.x;\n const dy = input.point.y - gesture.start.point.y;\n const moved = gesture.moved || Math.hypot(dx, dy) >= MOVE_THRESHOLD / scale();\n gesture = { ...gesture, current: input, moved };\n if (moved) {\n const preview = offsetDetection(gesture.detection, dx, dy);\n setPreview(preview);\n if (gesture.detection.id !== undefined) {\n options.onFastTranslate?.(gesture.detection.id, dx, dy);\n for (const listener of fastTranslateListeners) {\n listener(gesture.detection.id, dx, dy);\n }\n }\n }\n break;\n }\n case \"resize\":\n gesture = { ...gesture, current: input };\n setPreview(applyAnnotationHandleDrag(gesture.detection, gesture.handle, input.point));\n break;\n case \"path\":\n setPreview(resolvePathPreview([...gesture.points, input.point]));\n break;\n case \"freehand\": {\n const previous = gesture.points.at(-1);\n if (!previous ||\n previous.x !== input.point.x ||\n previous.y !== input.point.y) {\n gesture.points.push(input.point);\n }\n gesture = { ...gesture, current: input };\n setPreview(resolvePathPreview(gesture.points));\n break;\n }\n }\n },\n pointerUp(input) {\n if (!gesture)\n return;\n if (gesture.kind === \"path\")\n return;\n const active = gesture;\n gesture = null;\n release(active.start.pointerId);\n if (active.kind === \"box\") {\n const preview = resolveBoxPreview({ ...active, current: input });\n const duration = input.timestamp - active.start.timestamp;\n const diagonal = Math.hypot(input.point.x - active.start.point.x, input.point.y - active.start.point.y) * scale();\n const rect = preview.rect;\n if (!rect ||\n rect.width < 1 ||\n rect.height < 1 ||\n (duration < CLICK_CANCEL_MS && diagonal <= CLICK_CANCEL_DIAGONAL)) {\n cancel();\n return;\n }\n if (tool?.shouldCommit?.(rect) === false) {\n cancel();\n return;\n }\n commit(preview, null);\n return;\n }\n if (active.kind === \"freehand\") {\n const points = [...active.points, input.point];\n if (points.length < 2 || tool?.shouldCommit?.(points) === false) {\n cancel();\n return;\n }\n commit(tool.createDetection(points), null);\n return;\n }\n if (active.kind === \"move\") {\n if (!active.moved) {\n setState(idleState());\n return;\n }\n const preview = offsetDetection(active.detection, input.point.x - active.start.point.x, input.point.y - active.start.point.y);\n commit(preview, active.detection);\n return;\n }\n const preview = applyAnnotationHandleDrag(active.detection, active.handle, input.point);\n commit(preview, active.detection);\n },\n keyDown(key) {\n if (key === \"Escape\") {\n cancel();\n }\n else if (key === \"Enter\" && gesture?.kind === \"path\") {\n commitPath();\n }\n },\n beginHandleDrag(detection, handle, input) {\n if (detection.locked || detection.mask)\n return;\n capture(input.pointerId);\n gesture = {\n current: input,\n detection,\n handle,\n kind: \"resize\",\n start: input,\n };\n setState({\n activeDetectionId: detection.id ?? null,\n activeHandleId: handle.id,\n kind: AnnotationGestureStateKind.Resizing,\n pointerId: input.pointerId ?? null,\n preview: detection,\n });\n },\n deleteVertex(detection, vertexIndex) {\n const next = deleteAnnotationVertex(detection, vertexIndex);\n if (next)\n commit(next, detection);\n return next;\n },\n cancel,\n hasCreationTool: () => tool !== null,\n subscribe(listener) {\n stateListeners.add(listener);\n return () => stateListeners.delete(listener);\n },\n subscribeFastTranslate(listener) {\n fastTranslateListeners.add(listener);\n return () => fastTranslateListeners.delete(listener);\n },\n };\n function beginCreation(input) {\n if (!tool)\n return;\n const mode = tool.mode ??\n (tool.geometry === AnnotationGeometryKind.Box\n ? \"drag\"\n : tool.geometry === AnnotationGeometryKind.Mask\n ? \"freehand\"\n : \"multiClick\");\n if (mode === \"drag\") {\n capture(input.pointerId);\n gesture = { current: input, kind: \"box\", start: input };\n const preview = resolveBoxPreview(gesture);\n options.onPreview?.(preview);\n setState({\n activeDetectionId: null,\n activeHandleId: null,\n kind: AnnotationGestureStateKind.Creating,\n pointerId: input.pointerId ?? null,\n preview,\n });\n return;\n }\n if (mode === \"freehand\") {\n capture(input.pointerId);\n gesture = {\n current: input,\n kind: \"freehand\",\n points: [input.point],\n start: input,\n };\n setPreview(resolvePathPreview([input.point]));\n return;\n }\n if (tool.geometry !== AnnotationGeometryKind.Polygon &&\n tool.geometry !== AnnotationGeometryKind.Polyline &&\n tool.geometry !== AnnotationGeometryKind.Keypoints)\n return;\n if (gesture?.kind !== \"path\") {\n capture(input.pointerId);\n gesture = {\n kind: \"path\",\n lastTimestamp: input.timestamp,\n pointerId: input.pointerId ?? null,\n points: [input.point],\n };\n setPreview(resolvePathPreview([input.point, input.point]));\n return;\n }\n const minimum = tool.minVertices ??\n (tool.geometry === AnnotationGeometryKind.Polygon ? 3 : 2);\n const closeDistance = Math.hypot(input.point.x - gesture.points[0].x, input.point.y - gesture.points[0].y) * scale();\n const doubleClick = input.detail !== undefined\n ? input.detail >= 2\n : input.timestamp - gesture.lastTimestamp < CLICK_CANCEL_MS;\n if (gesture.points.length >= minimum &&\n ((tool.geometry === AnnotationGeometryKind.Polygon &&\n closeDistance <= CLOSE_ZONE_SCREEN_PX) ||\n doubleClick)) {\n commitPath();\n return;\n }\n gesture.points.push(input.point);\n gesture.lastTimestamp = input.timestamp;\n setPreview(resolvePathPreview([...gesture.points, input.point]));\n }\n function beginMove(pick, input) {\n capture(input.pointerId);\n gesture = {\n current: input,\n detection: pick.detection,\n kind: \"move\",\n moved: false,\n start: input,\n };\n setState({\n activeDetectionId: pick.detection.id ?? null,\n activeHandleId: null,\n kind: AnnotationGestureStateKind.Moving,\n pointerId: input.pointerId ?? null,\n preview: null,\n });\n }\n function resolveBoxPreview(active) {\n const left = Math.min(active.start.point.x, active.current.point.x);\n const right = Math.max(active.start.point.x, active.current.point.x);\n const top = Math.min(active.start.point.y, active.current.point.y);\n const bottom = Math.max(active.start.point.y, active.current.point.y);\n const rect = {\n x: (left + right) / 2,\n y: (top + bottom) / 2,\n width: right - left,\n height: bottom - top,\n };\n return tool.createDetection(rect);\n }\n function resolvePathPreview(points) {\n return tool.createDetection(points);\n }\n function commitPath() {\n if (!tool || gesture?.kind !== \"path\")\n return;\n const minimum = tool.minVertices ??\n (tool.geometry === AnnotationGeometryKind.Polygon ? 3 : 2);\n if (gesture.points.length < minimum) {\n cancel();\n return;\n }\n const preview = tool.createDetection(gesture.points);\n if (tool.shouldCommit?.(gesture.points) === false) {\n cancel();\n return;\n }\n release(gesture.pointerId ?? undefined);\n gesture = null;\n commit(preview, null);\n }\n function commit(detection, previous) {\n options.onCommit?.(detection, previous);\n options.onPreview?.(null);\n setState(idleState());\n }\n function setPreview(preview) {\n options.onPreview?.(preview);\n setState({\n activeDetectionId: state.activeDetectionId,\n activeHandleId: state.activeHandleId,\n kind: state.kind === AnnotationGestureStateKind.Idle\n ? AnnotationGestureStateKind.Creating\n : state.kind,\n pointerId: state.pointerId ??\n (gesture && \"pointerId\" in gesture\n ? (gesture.pointerId ?? null)\n : null),\n preview,\n });\n }\n function cancel() {\n const pointerId = gesture && \"start\" in gesture\n ? gesture.start.pointerId\n : gesture?.kind === \"path\"\n ? (gesture.pointerId ?? undefined)\n : undefined;\n release(pointerId);\n gesture = null;\n options.onPreview?.(null);\n options.onCancel?.();\n setState(idleState());\n }\n function setState(next) {\n state = Object.freeze(next);\n options.onStateChange?.(state);\n for (const listener of stateListeners)\n listener(state);\n }\n function scale() {\n return Math.max(options.viewportScale?.() ?? 1, Number.EPSILON);\n }\n function capture(pointerId) {\n if (pointerId !== undefined)\n options.capturePointer?.(pointerId);\n }\n function release(pointerId) {\n if (pointerId !== undefined)\n options.releasePointer?.(pointerId);\n }\n}\nfunction idleState() {\n return Object.freeze({\n activeDetectionId: null,\n activeHandleId: null,\n kind: AnnotationGestureStateKind.Idle,\n pointerId: null,\n preview: null,\n });\n}\n\nfunction resolveStyleValue(value, detection, context) {\n return typeof value === \"function\"\n ? value(detection, context)\n : value;\n}\n\n/**\n * Resolves the renderer-neutral stroke contract without dropping optional\n * geometry controls as styles move from public configuration to draw\n * instructions.\n *\n * Keep this as the single normalization point for every built-in style. That\n * makes additions to `StrokeStyle` deliberate instead of relying on each style\n * implementation to copy a growing property list correctly.\n */\nfunction resolveStrokeStyle(stroke, defaults) {\n const alignment = stroke?.alignment ?? defaults.alignment;\n const cap = stroke?.cap ?? defaults.cap;\n const dash = stroke?.dash ?? defaults.dash;\n const join = stroke?.join ?? defaults.join;\n const miterLimit = stroke?.miterLimit ?? defaults.miterLimit;\n return {\n alpha: stroke?.alpha ?? defaults.alpha,\n color: stroke?.color ?? defaults.color,\n width: stroke?.width ?? defaults.width,\n ...(alignment === undefined ? {} : { alignment }),\n ...(cap === undefined ? {} : { cap }),\n ...(dash === undefined ? {} : { dash }),\n ...(join === undefined ? {} : { join }),\n ...(miterLimit === undefined ? {} : { miterLimit }),\n };\n}\n\n/** Alignment for strokes applied to closed rendered geometry. */\nvar StrokeAlignment;\n(function (StrokeAlignment) {\n StrokeAlignment[\"Inside\"] = \"inside\";\n StrokeAlignment[\"Center\"] = \"center\";\n StrokeAlignment[\"Outside\"] = \"outside\";\n})(StrokeAlignment || (StrokeAlignment = {}));\n\nvar BoxShape;\n(function (BoxShape) {\n BoxShape[\"Rect\"] = \"rect\";\n BoxShape[\"RoundedRect\"] = \"roundedRect\";\n})(BoxShape || (BoxShape = {}));\n\nconst DEFAULT_BOX_STROKE_ALPHA = 1;\nconst DEFAULT_BOX_STROKE_COLOR = 0x00ff66;\nconst DEFAULT_BOX_STROKE_WIDTH = 2;\n/**\n * Default configurable box style.\n *\n * This is the simplest `supervision-js` equivalent of a box annotator: it\n * converts detections with `rect` geometry into renderer-neutral box draw\n * instructions. Use options such as `shape`, `cornerRadius`, `stroke`, and\n * `fill` for static or per-detection styling.\n */\nclass BaseBoxStyle {\n options;\n constructor(options = {}) {\n this.options = options;\n }\n resolve(detection, context) {\n if (!detection.rect ||\n context.hidden ||\n this.options.shouldRender?.(detection, context) === false) {\n return undefined;\n }\n const shape = this.resolveShape(detection, context);\n const cornerRadius = this.resolveCornerRadius(detection, context, shape);\n const instruction = {\n fill: this.resolveFill(detection, context),\n rect: detection.rect,\n shape,\n stroke: this.resolveStroke(detection, context),\n };\n if (cornerRadius !== undefined) {\n return {\n ...instruction,\n cornerRadius,\n };\n }\n return instruction;\n }\n resolveShape(detection, context) {\n return (resolveStyleValue(this.options.shape, detection, context) ?? BoxShape.Rect);\n }\n resolveCornerRadius(detection, context, shape) {\n if (shape !== BoxShape.RoundedRect) {\n return undefined;\n }\n return resolveStyleValue(this.options.cornerRadius, detection, context);\n }\n resolveStroke(detection, context) {\n const stroke = resolveStyleValue(this.options.stroke, detection, context);\n if (stroke === null) {\n return undefined;\n }\n return resolveStrokeStyle(stroke, {\n alpha: DEFAULT_BOX_STROKE_ALPHA,\n color: DEFAULT_BOX_STROKE_COLOR,\n ...(context.ephemeral ? { dash: [6, 4] } : {}),\n width: DEFAULT_BOX_STROKE_WIDTH,\n });\n }\n resolveFill(detection, context) {\n const fill = resolveStyleValue(this.options.fill, detection, context);\n if (fill === null || fill === undefined) {\n return undefined;\n }\n return {\n alpha: fill.alpha ?? 1,\n color: fill.color ?? DEFAULT_BOX_STROKE_COLOR,\n };\n }\n}\n\nconst DEFAULT_CORNER_LENGTH = 20;\nconst DEFAULT_CORNER_STROKE = {\n alpha: 1,\n cap: \"round\",\n color: 0x00ff66,\n join: \"round\",\n width: 2,\n};\n/**\n * Configurable four-corner decoration derived from a detection rectangle.\n *\n * This is the BoxCornerAnnotator-style facade: it keeps the rectangle semantic\n * and draws only its four open corner segments.\n */\nclass BaseBoxCornerStyle {\n options;\n constructor(options = {}) {\n this.options = options;\n }\n resolve(detection, context) {\n if (!detection.rect ||\n context.hidden ||\n this.options.shouldRender?.(detection, context) === false) {\n return undefined;\n }\n const resolvedLength = resolveStyleValue(this.options.length, detection, context) ??\n DEFAULT_CORNER_LENGTH;\n const viewportScale = context.viewportScale && context.viewportScale > 0\n ? context.viewportScale\n : 1;\n const length = Math.min(Math.max(0, resolvedLength / viewportScale), detection.rect.width / 2, detection.rect.height / 2);\n const stroke = resolveStyleValue(this.options.stroke, detection, context);\n if (length <= 0 || stroke === null)\n return undefined;\n const { height, width, x, y } = detection.rect;\n const left = x - width / 2;\n const right = x + width / 2;\n const top = y - height / 2;\n const bottom = y + height / 2;\n const resolvedStroke = resolveStrokeStyle(stroke, DEFAULT_CORNER_STROKE);\n const openStroke = {\n alpha: resolvedStroke.alpha,\n cap: resolvedStroke.cap,\n color: resolvedStroke.color,\n dash: resolvedStroke.dash,\n join: resolvedStroke.join,\n miterLimit: resolvedStroke.miterLimit,\n width: resolvedStroke.width,\n };\n return {\n segments: [\n [\n { x: left + length, y: top },\n { x: left, y: top },\n { x: left, y: top + length },\n ],\n [\n { x: right - length, y: top },\n { x: right, y: top },\n { x: right, y: top + length },\n ],\n [\n { x: left + length, y: bottom },\n { x: left, y: bottom },\n { x: left, y: bottom - length },\n ],\n [\n { x: right - length, y: bottom },\n { x: right, y: bottom },\n { x: right, y: bottom - length },\n ],\n ],\n stroke: openStroke,\n };\n }\n}\n\nvar FocusTargetMode;\n(function (FocusTargetMode) {\n FocusTargetMode[\"Hovered\"] = \"hovered\";\n FocusTargetMode[\"Selected\"] = \"selected\";\n FocusTargetMode[\"HoveredAndSelected\"] = \"hoveredAndSelected\";\n FocusTargetMode[\"Ambient\"] = \"ambient\";\n})(FocusTargetMode || (FocusTargetMode = {}));\n\nconst DEFAULT_FOCUS_FILL_COLOR = 0x020617;\nconst DEFAULT_FOCUS_FILL_ALPHA = 0.45;\nconst DEFAULT_FOCUS_CORNER_RADIUS = 8;\n/**\n * Default configurable focus style.\n *\n * Focus styles dim the current media frame while leaving the selected or\n * hovered detections visible. Renderers may use prepared mask artifacts for\n * shape-accurate cutouts, falling back to detection rectangles when needed.\n */\nclass BaseFocusStyle {\n options;\n constructor(options = {}) {\n this.options = options;\n }\n resolve(context) {\n if (this.options.shouldRender?.(context) === false) {\n return undefined;\n }\n const targetMode = this.options.targetMode ?? FocusTargetMode.Selected;\n const targets = getFocusTargets(context, targetMode);\n const ambient = targetMode === FocusTargetMode.Ambient &&\n !context.selectedPick &&\n !context.hoveredPick;\n const fill = resolveFocusStyleValue(this.options.fill, context);\n if (targets.length === 0 || fill === null) {\n return undefined;\n }\n return {\n fallback: this.resolveFallback(context),\n fill: {\n alpha: fill?.alpha ?? DEFAULT_FOCUS_FILL_ALPHA,\n color: fill?.color ?? DEFAULT_FOCUS_FILL_COLOR,\n },\n targetMode,\n targets,\n ...(ambient ? { ambient: true } : {}),\n };\n }\n resolveFallback(context) {\n const shape = resolveFocusStyleValue(this.options.shape, context) ??\n BoxShape.RoundedRect;\n const cornerRadius = shape === BoxShape.RoundedRect\n ? (resolveFocusStyleValue(this.options.cornerRadius, context) ??\n DEFAULT_FOCUS_CORNER_RADIUS)\n : undefined;\n if (cornerRadius === undefined) {\n return { shape };\n }\n return {\n cornerRadius,\n shape,\n };\n }\n}\nfunction getFocusTargets(context, targetMode) {\n const targets = [];\n if (targetMode === FocusTargetMode.Ambient) {\n if (context.selectedPick)\n return [context.selectedPick];\n if (context.hoveredPick)\n return [context.hoveredPick];\n return context.frame.detections.map((detection, detectionIndex) => ({\n detection,\n detectionIndex,\n frame: context.frame,\n mediaTime: context.mediaTime,\n point: detection.rect\n ? { x: detection.rect.x, y: detection.rect.y }\n : { x: 0, y: 0 },\n target: detection.mask\n ? DetectionPickTarget.Mask\n : detection.polygon\n ? DetectionPickTarget.Polygon\n : DetectionPickTarget.Box,\n }));\n }\n if ((targetMode === FocusTargetMode.Selected ||\n targetMode === FocusTargetMode.HoveredAndSelected) &&\n context.selectedPick) {\n targets.push(context.selectedPick);\n }\n if ((targetMode === FocusTargetMode.Hovered ||\n targetMode === FocusTargetMode.HoveredAndSelected) &&\n context.hoveredPick) {\n targets.push(context.hoveredPick);\n }\n return dedupeTargetsForFrame(targets, context.frame);\n}\nfunction dedupeTargetsForFrame(targets, frame) {\n const keys = new Set();\n const dedupedTargets = [];\n for (const target of targets) {\n if (target.frame !== frame) {\n continue;\n }\n const key = `${target.detectionIndex}:${target.target}`;\n if (keys.has(key)) {\n continue;\n }\n keys.add(key);\n dedupedTargets.push(target);\n }\n return dedupedTargets;\n}\nfunction resolveFocusStyleValue(value, context) {\n if (typeof value === \"function\") {\n return value(context);\n }\n return value;\n}\n\nvar DetectionInteractionState;\n(function (DetectionInteractionState) {\n DetectionInteractionState[\"Hovered\"] = \"hovered\";\n DetectionInteractionState[\"Selected\"] = \"selected\";\n})(DetectionInteractionState || (DetectionInteractionState = {}));\n\nconst DEFAULT_HOVER_FILL_COLOR = 0x67e8f9;\nconst DEFAULT_HOVER_FILL_ALPHA = 0.1;\nconst DEFAULT_HOVER_STROKE_COLOR = 0x67e8f9;\nconst DEFAULT_HOVER_STROKE_ALPHA = 0.95;\nconst DEFAULT_HOVER_STROKE_WIDTH = 3;\nconst DEFAULT_SELECTED_FILL_COLOR = 0xfde047;\nconst DEFAULT_SELECTED_FILL_ALPHA = 0.18;\nconst DEFAULT_SELECTED_STROKE_COLOR = 0xfde047;\nconst DEFAULT_SELECTED_STROKE_ALPHA = 1;\nconst DEFAULT_SELECTED_STROKE_WIDTH = 4;\n/**\n * Default configurable interaction style.\n *\n * It resolves hover and selected picks into state-specific presentations using\n * the same style contracts as normal boxes, masks, and labels. The older\n * rectangle options are kept as compatibility sugar and resolve to a box style.\n */\nclass BaseInteractionStyle {\n options;\n constructor(options = {}) {\n this.options = options;\n }\n resolve(detection, context) {\n if (this.options.shouldRender?.(detection, context) === false) {\n return undefined;\n }\n const statePresentation = context.state === DetectionInteractionState.Selected\n ? this.options.selected\n : this.options.hovered;\n if (statePresentation !== undefined) {\n return statePresentation ?? undefined;\n }\n const rect = detection.rect;\n if (!rect) {\n return undefined;\n }\n return {\n boxStyle: createResolvedBoxStyle(this.resolveBoxInstruction(detection, context, rect)),\n };\n }\n resolveBoxInstruction(detection, context, rect) {\n const shape = this.resolveShape(detection, context);\n const cornerRadius = this.resolveCornerRadius(detection, context, shape);\n const instruction = {\n fill: this.resolveFill(detection, context),\n rect,\n shape,\n stroke: this.resolveStroke(detection, context),\n };\n if (cornerRadius !== undefined) {\n return {\n ...instruction,\n cornerRadius,\n };\n }\n return instruction;\n }\n resolveShape(detection, context) {\n return (resolveStyleValue(this.options.shape, detection, context) ?? BoxShape.Rect);\n }\n resolveCornerRadius(detection, context, shape) {\n if (shape !== BoxShape.RoundedRect) {\n return undefined;\n }\n return resolveStyleValue(this.options.cornerRadius, detection, context);\n }\n resolveStroke(detection, context) {\n const stroke = resolveStyleValue(this.options.stroke, detection, context);\n if (stroke === null) {\n return undefined;\n }\n const defaults = getStateDefaults(context.state);\n return resolveStrokeStyle(stroke, {\n alpha: defaults.strokeAlpha,\n color: defaults.strokeColor,\n width: defaults.strokeWidth,\n });\n }\n resolveFill(detection, context) {\n const fill = resolveStyleValue(this.options.fill, detection, context);\n if (fill === null) {\n return undefined;\n }\n const defaults = getStateDefaults(context.state);\n return {\n alpha: fill?.alpha ?? defaults.fillAlpha,\n color: fill?.color ?? defaults.fillColor,\n };\n }\n}\nfunction createResolvedBoxStyle(instruction) {\n return {\n resolve() {\n return instruction;\n },\n };\n}\nfunction getStateDefaults(state) {\n if (state === DetectionInteractionState.Selected) {\n return {\n fillAlpha: DEFAULT_SELECTED_FILL_ALPHA,\n fillColor: DEFAULT_SELECTED_FILL_COLOR,\n strokeAlpha: DEFAULT_SELECTED_STROKE_ALPHA,\n strokeColor: DEFAULT_SELECTED_STROKE_COLOR,\n strokeWidth: DEFAULT_SELECTED_STROKE_WIDTH,\n };\n }\n return {\n fillAlpha: DEFAULT_HOVER_FILL_ALPHA,\n fillColor: DEFAULT_HOVER_FILL_COLOR,\n strokeAlpha: DEFAULT_HOVER_STROKE_ALPHA,\n strokeColor: DEFAULT_HOVER_STROKE_COLOR,\n strokeWidth: DEFAULT_HOVER_STROKE_WIDTH,\n };\n}\n\nvar LabelPlacement;\n(function (LabelPlacement) {\n LabelPlacement[\"Top\"] = \"top\";\n LabelPlacement[\"Bottom\"] = \"bottom\";\n LabelPlacement[\"InsideTop\"] = \"insideTop\";\n LabelPlacement[\"InsideBottom\"] = \"insideBottom\";\n LabelPlacement[\"Center\"] = \"center\";\n})(LabelPlacement || (LabelPlacement = {}));\nvar LabelVisibilityMode;\n(function (LabelVisibilityMode) {\n LabelVisibilityMode[\"Always\"] = \"always\";\n LabelVisibilityMode[\"HoveredOnly\"] = \"hoveredOnly\";\n})(LabelVisibilityMode || (LabelVisibilityMode = {}));\n\n/** Returns black or white for readable text over an RGB background. */\nfunction resolveContrastTextColor(color) {\n \"worklet\";\n const red = (color >> 16) & 0xff;\n const green = (color >> 8) & 0xff;\n const blue = color & 0xff;\n const luminance = (red * 299 + green * 587 + blue * 114) / 1000;\n return luminance >= 150 ? 0x111111 : 0xffffff;\n}\nfunction lightenColor(color, amount = 0.14) {\n \"worklet\";\n const mix = (value) => Math.round(value + (255 - value) * amount);\n return ((mix((color >> 16) & 0xff) << 16) |\n (mix((color >> 8) & 0xff) << 8) |\n mix(color & 0xff));\n}\n\n/**\n * Default label style.\n *\n * Resolves labels from `className`, `metadata.label`, or a custom text\n * resolver, optionally including confidence.\n */\nclass BaseLabelStyle {\n includeConfidence;\n offsetY;\n options;\n constructor(options = {}) {\n this.options = options;\n this.includeConfidence = options.includeConfidence ?? false;\n this.offsetY = options.offsetY ?? 0;\n }\n resolve(detection, context) {\n if (!getDetectionRect(detection) ||\n context.hidden ||\n (this.options.visibilityMode === LabelVisibilityMode.HoveredOnly &&\n !context.hovered) ||\n this.options.shouldRender?.(detection, context) === false) {\n return undefined;\n }\n const text = resolveStyleValue(this.options.text, detection, context) ??\n formatDetectionLabel(detection, this.includeConfidence);\n if (!text) {\n return undefined;\n }\n const background = this.resolveBackground(detection, context);\n return {\n background,\n ...this.resolveOffset(detection, context),\n placement: this.resolvePlacement(detection, context),\n rect: getDetectionRect(detection),\n text,\n textStyle: this.resolveTextStyle(detection, context, background),\n };\n }\n resolveBackground(detection, context) {\n const background = resolveStyleValue(this.options.background, detection, context);\n return {\n alpha: background?.alpha ?? 0.72,\n color: context.hovered\n ? lightenColor(background?.color ?? 0x111827)\n : (background?.color ?? 0x111827),\n cornerRadius: background?.cornerRadius ?? 4,\n paddingX: background?.paddingX ?? 6,\n paddingY: background?.paddingY ?? 3,\n ...(background?.topCornersOnly === undefined\n ? {}\n : { topCornersOnly: background.topCornersOnly }),\n };\n }\n resolveTextStyle(detection, context, background) {\n const textStyle = resolveStyleValue(this.options.textStyle, detection, context);\n return {\n alpha: textStyle?.alpha ?? 1,\n color: textStyle?.color ?? resolveContrastTextColor(background.color),\n fontFamily: textStyle?.fontFamily ?? \"Inter, sans-serif\",\n fontSize: textStyle?.fontSize ?? 13,\n fontWeight: textStyle?.fontWeight ?? \"600\",\n };\n }\n resolveOffset(detection, context) {\n const offset = resolveStyleValue(this.options.offset, detection, context);\n if (offset === null) {\n return {};\n }\n return {\n ...(offset?.x === undefined ? {} : { offsetX: offset.x }),\n offsetY: offset?.y ?? this.offsetY,\n };\n }\n resolvePlacement(detection, context) {\n return (resolveStyleValue(this.options.placement, detection, context) ??\n LabelPlacement.Top);\n }\n}\nfunction formatDetectionLabel(detection, includeConfidence) {\n const label = detection.className ??\n (typeof detection.metadata?.label === \"string\"\n ? detection.metadata.label\n : undefined);\n if (!label) {\n return undefined;\n }\n if (!includeConfidence || detection.confidence === undefined) {\n return label;\n }\n return `${label} ${Math.round(detection.confidence * 100)}%`;\n}\n\nvar MaskRenderMode;\n(function (MaskRenderMode) {\n MaskRenderMode[\"FillAndStroke\"] = \"fillAndStroke\";\n MaskRenderMode[\"FillOnly\"] = \"fillOnly\";\n MaskRenderMode[\"StrokeOnly\"] = \"strokeOnly\";\n})(MaskRenderMode || (MaskRenderMode = {}));\n\n/**\n * Default compressed-RLE mask style.\n *\n * Static color/stroke options can reuse prepared mask artifacts by key. Dynamic\n * color or stroke resolvers intentionally do not expose an artifact key, so new\n * style objects rebuild prepared palettes instead of reusing stale ones.\n */\nclass BaseMaskStyle {\n artifactKey;\n opacity;\n options;\n constructor(options = {}) {\n this.options = options;\n this.opacity = clampOpacity(options.opacity ?? options.alpha ?? 0.35);\n this.artifactKey = createArtifactKey(options);\n }\n resolve(detection, context) {\n if (!detection.mask ||\n context.hidden ||\n this.options.shouldRender?.(detection, context) === false) {\n return undefined;\n }\n const color = resolveStyleValue(this.options.color, detection, context) ??\n DEFAULT_MASK_COLOR;\n const mode = resolveStyleValue(this.options.mode, detection, context) ??\n MaskRenderMode.FillAndStroke;\n const stroke = resolveStroke(resolveStyleValue(this.options.stroke, detection, context), color, mode);\n return {\n alpha: mode === MaskRenderMode.StrokeOnly\n ? 0\n : clampOpacity(resolveStyleValue(this.options.fillAlpha, detection, context) ??\n 1),\n color,\n mask: detection.mask,\n stroke: mode === MaskRenderMode.FillOnly ? undefined : stroke,\n };\n }\n}\nconst DEFAULT_MASK_COLOR = 0x00ff66;\nconst DEFAULT_MASK_STROKE_ALPHA = 1;\nconst DEFAULT_MASK_STROKE_WIDTH = 1;\nfunction clampOpacity(opacity) {\n return Number.isFinite(opacity) ? Math.max(0, Math.min(opacity, 1)) : 1;\n}\nfunction serializeStroke(stroke) {\n if (!stroke) {\n return \"none\";\n }\n return `${stroke.color}:${stroke.alpha}:${stroke.width}`;\n}\nfunction normalizeStroke(stroke, fallbackColor) {\n if (!stroke) {\n return undefined;\n }\n return {\n alpha: stroke.alpha ?? DEFAULT_MASK_STROKE_ALPHA,\n color: stroke.color ?? fallbackColor,\n width: stroke.width ?? DEFAULT_MASK_STROKE_WIDTH,\n };\n}\nfunction resolveStroke(stroke, fallbackColor, mode) {\n if (mode === MaskRenderMode.FillOnly) {\n return undefined;\n }\n if (mode === MaskRenderMode.StrokeOnly && stroke === undefined) {\n return normalizeStroke({}, fallbackColor);\n }\n return normalizeStroke(stroke, fallbackColor);\n}\nfunction createArtifactKey(options) {\n if (typeof options.color === \"function\" ||\n typeof options.fillAlpha === \"function\" ||\n typeof options.mode === \"function\" ||\n typeof options.stroke === \"function\") {\n return undefined;\n }\n const color = options.color ?? DEFAULT_MASK_COLOR;\n const fillAlpha = options.fillAlpha ?? 1;\n const mode = options.mode ?? MaskRenderMode.FillAndStroke;\n return `base:${color}:${fillAlpha}:${mode}:${serializeStroke(resolveStroke(options.stroke, color, mode))}`;\n}\n\n/**\n * Discriminator for renderer-neutral shape draw instructions.\n */\nvar ShapeInstructionKind;\n(function (ShapeInstructionKind) {\n ShapeInstructionKind[\"Ellipse\"] = \"ellipse\";\n ShapeInstructionKind[\"Marker\"] = \"marker\";\n ShapeInstructionKind[\"Path\"] = \"path\";\n})(ShapeInstructionKind || (ShapeInstructionKind = {}));\nvar MarkerShape;\n(function (MarkerShape) {\n MarkerShape[\"Circle\"] = \"circle\";\n MarkerShape[\"Cross\"] = \"cross\";\n MarkerShape[\"Square\"] = \"square\";\n MarkerShape[\"Triangle\"] = \"triangle\";\n})(MarkerShape || (MarkerShape = {}));\n/**\n * Coordinate space for marker sizing. Media sizes scale with the viewport;\n * screen sizes stay constant on screen, matching stroke-width semantics.\n */\nvar MarkerSizeSpace;\n(function (MarkerSizeSpace) {\n MarkerSizeSpace[\"Media\"] = \"media\";\n MarkerSizeSpace[\"Screen\"] = \"screen\";\n})(MarkerSizeSpace || (MarkerSizeSpace = {}));\n\nconst DEFAULT_FILL = { alpha: 1, color: 0x00ff66 };\nconst DEFAULT_STROKE = { alpha: 1, color: 0xffffff, width: 1 };\nconst DEFAULT_SIZE = 12;\n/**\n * Configurable marker renderer style anchored to semantic detection geometry.\n *\n * Use `center` for any domain-specific anchor (keypoint, centroid, or custom\n * metadata). Without it, the marker lands at the detection rectangle center.\n */\nclass BaseMarkerStyle {\n options;\n constructor(options = {}) {\n this.options = options;\n }\n resolve(detection, context) {\n if (context.hidden ||\n this.options.shouldRender?.(detection, context) === false) {\n return undefined;\n }\n const center = resolveStyleValue(this.options.center, detection, context) ??\n (detection.rect\n ? { x: detection.rect.x, y: detection.rect.y }\n : undefined);\n const shape = resolveStyleValue(this.options.shape, detection, context) ??\n MarkerShape.Circle;\n const size = resolveStyleValue(this.options.size, detection, context) ?? DEFAULT_SIZE;\n const sizeSpace = resolveStyleValue(this.options.sizeSpace, detection, context) ??\n MarkerSizeSpace.Screen;\n const rotation = resolveStyleValue(this.options.rotation, detection, context);\n const stroke = resolveStyleValue(this.options.stroke, detection, context);\n if (!center || !Number.isFinite(size) || size <= 0) {\n return undefined;\n }\n if (shape === MarkerShape.Cross) {\n if (stroke === null) {\n return undefined;\n }\n const resolvedStroke = resolveStrokeStyle(stroke, DEFAULT_STROKE);\n const openStroke = {\n alpha: resolvedStroke.alpha,\n cap: resolvedStroke.cap,\n color: resolvedStroke.color,\n dash: resolvedStroke.dash,\n join: resolvedStroke.join,\n miterLimit: resolvedStroke.miterLimit,\n width: resolvedStroke.width,\n };\n return {\n center,\n shape,\n size,\n sizeSpace,\n ...(rotation === undefined ? {} : { rotation }),\n stroke: openStroke,\n };\n }\n const fill = resolveStyleValue(this.options.fill, detection, context);\n if (fill === null && stroke === null) {\n return undefined;\n }\n return {\n center,\n shape,\n size,\n sizeSpace,\n ...(rotation === undefined ? {} : { rotation }),\n ...(fill === null\n ? {}\n : {\n fill: {\n alpha: fill?.alpha ?? DEFAULT_FILL.alpha,\n color: fill?.color ?? DEFAULT_FILL.color,\n },\n }),\n ...(stroke === null\n ? {}\n : stroke === undefined\n ? { stroke: DEFAULT_STROKE }\n : { stroke: resolveStrokeStyle(stroke, DEFAULT_STROKE) }),\n };\n }\n}\n\nclass BasePolygonStyle {\n options;\n constructor(options = {}) {\n this.options = options;\n }\n resolve(detection, context) {\n if (!detection.polygon ||\n context.hidden ||\n detection.polygon.points.length < 3 ||\n this.options.shouldRender?.(detection, context) === false) {\n return undefined;\n }\n const fill = resolveStyleValue(this.options.fill, detection, context);\n const stroke = resolveStyleValue(this.options.stroke, detection, context);\n return {\n points: detection.polygon.points,\n ...(fill === null\n ? {}\n : {\n fill: {\n alpha: fill?.alpha ?? 0.16,\n color: fill?.color ?? 0x00ff66,\n },\n }),\n ...(stroke === null\n ? {}\n : {\n stroke: resolveStrokeStyle(stroke, {\n alpha: 1,\n color: 0x00ff66,\n width: 2,\n }),\n }),\n };\n }\n}\n\nclass BasePolylineStyle {\n options;\n constructor(options = {}) {\n this.options = options;\n }\n resolve(detection, context) {\n if (!detection.polyline ||\n context.hidden ||\n detection.polyline.points.length < 2 ||\n this.options.shouldRender?.(detection, context) === false) {\n return undefined;\n }\n const stroke = resolveStyleValue(this.options.stroke, detection, context);\n if (stroke === null) {\n return undefined;\n }\n return {\n points: detection.polyline.points,\n stroke: resolveStrokeStyle(stroke, {\n alpha: 1,\n color: 0x00ff66,\n width: 2,\n }),\n };\n }\n}\n\nvar KeypointMarkerShape;\n(function (KeypointMarkerShape) {\n KeypointMarkerShape[\"Circle\"] = \"circle\";\n KeypointMarkerShape[\"Cross\"] = \"cross\";\n})(KeypointMarkerShape || (KeypointMarkerShape = {}));\n\nclass BaseKeypointStyle {\n options;\n constructor(options = {}) {\n this.options = options;\n }\n resolve(detection, context) {\n const geometry = detection.keypoints;\n if (!geometry ||\n context.hidden ||\n this.options.shouldRender?.(detection, context) === false) {\n return undefined;\n }\n const definition = detection.className\n ? this.options.definitions?.[detection.className]\n : undefined;\n const markerFill = resolveStyleValue(this.options.markerFill, detection, context);\n const markerStroke = resolveStyleValue(this.options.markerStroke, detection, context);\n const edgeStroke = resolveStyleValue(this.options.edgeStroke, detection, context);\n const shadowStroke = resolveStyleValue(this.options.edgeShadowStroke, detection, context);\n const radius = resolveStyleValue(this.options.radius, detection, context) ?? 6;\n const edges = geometry.edges.map(([fromIndex, toIndex], edgeIndex) => ({\n from: geometry.points[fromIndex],\n to: geometry.points[toIndex],\n stroke: resolveStrokeStyle(definition?.edges[edgeIndex]?.color === undefined\n ? edgeStroke\n : { ...edgeStroke, color: definition.edges[edgeIndex].color }, {\n alpha: 1,\n color: 0x00ff66,\n width: 2,\n }),\n ...(shadowStroke === null\n ? {}\n : {\n shadowStroke: resolveStrokeStyle(shadowStroke, {\n alpha: 0.65,\n color: 0x000000,\n width: 4,\n }),\n }),\n }));\n const markers = geometry.points.flatMap((point, index) => {\n const visibility = geometry.visibility?.[index] ?? KeypointVisibility.Visible;\n if (visibility === KeypointVisibility.NotLabeled) {\n return [];\n }\n return [\n {\n fill: {\n alpha: markerFill?.alpha ?? 1,\n color: definition?.vertices[index]?.color ??\n markerFill?.color ??\n 0x00ff66,\n },\n index,\n point,\n radius,\n shape: visibility === KeypointVisibility.Occluded\n ? KeypointMarkerShape.Cross\n : KeypointMarkerShape.Circle,\n stroke: resolveStrokeStyle(markerStroke, {\n alpha: 1,\n color: 0xffffff,\n width: 2,\n }),\n },\n ];\n });\n return { edges, markers };\n }\n}\n\nconst SUPERVISION_ROBOFLOW_COLOR = 0xa351fb;\nconst DEFAULT_DETECTION_COLOR_SEQUENCE = [\n createClassColorStyle(0x38bdf8, 0x164e63, 0xecfeff, 0x7dd3fc),\n createClassColorStyle(0x22c55e, 0x14532d, 0xf0fdf4, 0x86efac),\n createClassColorStyle(0xa78bfa, 0x4c1d95, 0xf5f3ff, 0xc4b5fd),\n createClassColorStyle(0xfacc15, 0x713f12, 0xfffbeb, 0xfde047),\n createClassColorStyle(0xf97316, 0x7c2d12, 0xfff7ed, 0xffa23a),\n createClassColorStyle(0xf472b6, 0x831843, 0xfdf2f8, 0xf9a8d4),\n createClassColorStyle(0x60a5fa, 0x1e3a8a, 0xeff6ff, 0x93c5fd),\n createClassColorStyle(0xfb7185, 0x881337, 0xfff1f2, 0xfda4af),\n createClassColorStyle(0x34d399, 0x064e3b, 0xecfdf5, 0x6ee7b7),\n createClassColorStyle(0xe879f9, 0x701a75, 0xfdf4ff, 0xf0abfc),\n];\nconst DEFAULT_DETECTION_CLASS_STYLES = {\n basketball: DEFAULT_DETECTION_COLOR_SEQUENCE[4],\n bed: DEFAULT_DETECTION_COLOR_SEQUENCE[5],\n bottle: DEFAULT_DETECTION_COLOR_SEQUENCE[4],\n \"cell phone\": DEFAULT_DETECTION_COLOR_SEQUENCE[8],\n cow: DEFAULT_DETECTION_COLOR_SEQUENCE[2],\n cup: DEFAULT_DETECTION_COLOR_SEQUENCE[3],\n horse: DEFAULT_DETECTION_COLOR_SEQUENCE[0],\n keyboard: DEFAULT_DETECTION_COLOR_SEQUENCE[1],\n knife: DEFAULT_DETECTION_COLOR_SEQUENCE[7],\n laptop: DEFAULT_DETECTION_COLOR_SEQUENCE[6],\n person: DEFAULT_DETECTION_COLOR_SEQUENCE[1],\n \"potted plant\": DEFAULT_DETECTION_COLOR_SEQUENCE[8],\n \"sports ball\": DEFAULT_DETECTION_COLOR_SEQUENCE[4],\n tv: DEFAULT_DETECTION_COLOR_SEQUENCE[2],\n \"white team player\": createClassColorStyle(0xf8fafc, 0x334155, 0xffffff, 0xffffff),\n \"yellow team player\": DEFAULT_DETECTION_COLOR_SEQUENCE[3],\n};\n// The \"worklet\" directives below are inert everywhere except React Native:\n// browsers and Node see a no-op string, while React Native's worklets Babel\n// plugin makes these functions callable inside frame worklets, so every\n// platform resolves detection colors through this one implementation.\n// Worklet constraint on ordering: the plugin turns marked declarations into\n// non-hoisted assignments that capture each other at module-init time, so\n// helpers must be defined before the functions that call them.\nfunction normalizeDetectionClassName(className) {\n \"worklet\";\n return (className ?? \"\")\n .trim()\n .toLowerCase()\n .replace(/[_-]/g, \" \")\n .replace(/\\s+/g, \" \");\n}\nfunction hashClassName(className) {\n \"worklet\";\n let hash = 0;\n for (let index = 0; index < className.length; index += 1) {\n hash = (hash * 31 + className.charCodeAt(index)) >>> 0;\n }\n return hash;\n}\nfunction resolveDetectionClassColorStyle(className) {\n \"worklet\";\n const normalizedClassName = normalizeDetectionClassName(className);\n const knownStyle = DEFAULT_DETECTION_CLASS_STYLES[normalizedClassName];\n if (knownStyle) {\n return knownStyle;\n }\n return DEFAULT_DETECTION_COLOR_SEQUENCE[hashClassName(normalizedClassName) % DEFAULT_DETECTION_COLOR_SEQUENCE.length];\n}\nfunction createClassColorStyle(fill, labelBackground, labelText, stroke) {\n return {\n fill,\n labelBackground,\n labelText,\n stroke,\n };\n}\n\nconst DEFAULT_BOX_CORNER_RADIUS = 1;\nconst DEFAULT_ELLIPSE_AXIS_RATIO = 0.35;\nconst DEFAULT_ELLIPSE_START_ANGLE = (-45 * Math.PI) / 180;\nconst DEFAULT_ELLIPSE_END_ANGLE = (235 * Math.PI) / 180;\nconst DEFAULT_OUTLINE_WIDTH = 2;\nconst DEFAULT_FILL_ALPHA = 0.08;\nconst DEFAULT_MASK_FILL_ALPHA = 0.45;\nconst DEFAULT_KEYPOINT_EDGE_WIDTH = 1.5;\nconst DEFAULT_KEYPOINT_SHADOW_WIDTH = 3;\nconst DEFAULT_KEYPOINT_SHADOW_ALPHA = 0.25;\nconst DEFAULT_KEYPOINT_RADIUS = 3.5;\nconst DEFAULT_LABEL_CORNER_RADIUS = 4;\nconst DEFAULT_LABEL_PADDING_X = 6;\nconst DEFAULT_LABEL_PADDING_Y = 3;\nconst DEFAULT_LABEL_FONT_SIZE = 12;\nconst DEFAULT_LABEL_FONT_FAMILY = \"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace\";\n/**\n * Builds the canonical, unselected annotation presentation used by Roboflow's\n * Core annotation editor. It deliberately excludes host-specific interaction,\n * editing, focus, and theme behaviour so consumers can compose those layers.\n */\nfunction createDefaultAnnotationPresentation(options = {}) {\n return {\n boxStyle: createDefaultBoxStyle(options),\n keypointStyle: createDefaultKeypointStyle(options),\n labelStyle: createDefaultLabelStyle(options),\n maskStyle: createDefaultMaskStyle(options),\n polygonStyle: createDefaultPolygonStyle(options),\n polylineStyle: createDefaultPolylineStyle(options),\n };\n}\n/**\n * The canonical default style of one built-in layer.\n *\n * These exist so a renderer kind can build only the style it needs instead of\n * the whole default presentation. Keep them equivalent to the matching field of\n * {@link createDefaultAnnotationPresentation}.\n */\nfunction createDefaultBoxStyle(options = {}) {\n const getClassColor = createClassColorResolver(options);\n return new BaseBoxStyle({\n cornerRadius: DEFAULT_BOX_CORNER_RADIUS,\n fill: (detection) => ({\n alpha: DEFAULT_FILL_ALPHA,\n color: getClassColor(detection),\n }),\n shape: BoxShape.RoundedRect,\n shouldRender: (detection) => !(detection.mask ||\n detection.polygon ||\n detection.polyline ||\n detection.keypoints),\n stroke: (detection) => ({\n alpha: 1,\n color: getClassColor(detection),\n width: DEFAULT_OUTLINE_WIDTH,\n }),\n });\n}\n/** Canonical opt-in BoxCornerAnnotator-style presentation. */\nfunction createDefaultBoxCornerStyle(options = {}) {\n const getClassColor = createClassColorResolver(options);\n return new BaseBoxCornerStyle({\n stroke: (detection) => ({ color: getClassColor(detection) }),\n });\n}\n/**\n * Matches the Python Supervision EllipseAnnotator: an elliptical footprint\n * arc under the detection box, swept from -45deg to 235deg, in the class\n * color.\n */\nfunction createDefaultEllipseStyle(options = {}) {\n const getClassColor = createClassColorResolver(options);\n return {\n resolve(detection, context) {\n if (!detection.rect || context.hidden) {\n return undefined;\n }\n const radiusX = detection.rect.width / 2;\n const radiusY = radiusX * DEFAULT_ELLIPSE_AXIS_RATIO;\n return {\n center: {\n x: detection.rect.x,\n // Bottom-tangent so the arc hugs the detection instead of dipping\n // below its feet.\n y: detection.rect.y + detection.rect.height / 2 - radiusY,\n },\n endAngle: DEFAULT_ELLIPSE_END_ANGLE,\n radiusX,\n radiusY,\n startAngle: DEFAULT_ELLIPSE_START_ANGLE,\n stroke: {\n alpha: 1,\n color: getClassColor(detection),\n width: DEFAULT_OUTLINE_WIDTH,\n },\n };\n },\n };\n}\nfunction createDefaultKeypointStyle(options = {}) {\n const getClassColor = createClassColorResolver(options);\n return new BaseKeypointStyle({\n ...(options.skeletonDefinitions === undefined\n ? {}\n : { definitions: options.skeletonDefinitions }),\n edgeShadowStroke: {\n alpha: DEFAULT_KEYPOINT_SHADOW_ALPHA,\n color: 0x000000,\n width: DEFAULT_KEYPOINT_SHADOW_WIDTH,\n },\n edgeStroke: (detection) => ({\n alpha: 1,\n color: getClassColor(detection),\n width: DEFAULT_KEYPOINT_EDGE_WIDTH,\n }),\n markerFill: (detection) => ({\n alpha: 1,\n color: getClassColor(detection),\n }),\n markerStroke: { alpha: 1, color: 0xffffff, width: 1 },\n radius: DEFAULT_KEYPOINT_RADIUS,\n });\n}\nfunction createDefaultLabelStyle(options = {}) {\n const getClassColor = createClassColorResolver(options);\n return new BaseLabelStyle({\n background: (detection) => ({\n alpha: 1,\n color: getClassColor(detection),\n cornerRadius: DEFAULT_LABEL_CORNER_RADIUS,\n paddingX: DEFAULT_LABEL_PADDING_X,\n paddingY: DEFAULT_LABEL_PADDING_Y,\n topCornersOnly: true,\n }),\n includeConfidence: options.includeConfidence,\n placement: LabelPlacement.Top,\n textStyle: {\n fontFamily: DEFAULT_LABEL_FONT_FAMILY,\n fontSize: DEFAULT_LABEL_FONT_SIZE,\n fontWeight: \"600\",\n },\n });\n}\nfunction createDefaultMaskStyle(options = {}) {\n const getClassColor = createClassColorResolver(options);\n return new BaseMaskStyle({\n color: (detection) => getClassColor(detection),\n fillAlpha: DEFAULT_MASK_FILL_ALPHA,\n mode: MaskRenderMode.FillAndStroke,\n opacity: 1,\n stroke: (detection) => ({\n alpha: 1,\n color: getClassColor(detection),\n width: DEFAULT_OUTLINE_WIDTH,\n }),\n });\n}\n/** Canonical opt-in marker presentation. */\nfunction createDefaultMarkerStyle() {\n return new BaseMarkerStyle();\n}\nconst DEFAULT_MASK_HALO_ALPHA = 0.6;\nconst DEFAULT_MASK_HALO_SPREAD = 12;\n/**\n * Canonical mask halo: a class-colored glow that follows the mask silhouette.\n * Used when the `maskHalo` renderer is listed without an explicit style.\n */\nfunction createDefaultMaskHaloStyle(options = {}) {\n const getClassColor = createClassColorResolver(options);\n return {\n resolve(detection, context) {\n if (!detection.mask || context.hidden) {\n return undefined;\n }\n return {\n alpha: DEFAULT_MASK_HALO_ALPHA,\n color: getClassColor(detection),\n spread: DEFAULT_MASK_HALO_SPREAD,\n };\n },\n };\n}\nfunction createDefaultPolygonStyle(options = {}) {\n const getClassColor = createClassColorResolver(options);\n return new BasePolygonStyle({\n fill: (detection) => ({\n alpha: DEFAULT_FILL_ALPHA,\n color: getClassColor(detection),\n }),\n stroke: (detection) => ({\n alpha: 1,\n color: getClassColor(detection),\n width: DEFAULT_OUTLINE_WIDTH,\n }),\n });\n}\nfunction createDefaultPolylineStyle(options = {}) {\n const getClassColor = createClassColorResolver(options);\n return new BasePolylineStyle({\n stroke: (detection) => ({\n alpha: 1,\n color: getClassColor(detection),\n width: DEFAULT_OUTLINE_WIDTH,\n }),\n });\n}\nfunction createClassColorResolver(options) {\n return (detection) => resolveDefaultClassColor(detection, options.getClassColor);\n}\nfunction resolveDefaultClassColor(detection, getClassColor) {\n const color = getClassColor?.(detection.className);\n return typeof color === \"number\" && Number.isFinite(color)\n ? color\n : resolveDetectionClassColorStyle(detection.className).fill;\n}\n\n/**\n * The built-in annotation renderer vocabulary.\n *\n * These stay plain string literals so `{ kind: \"box\" }` remains assignable to\n * the public descriptor union from JavaScript and TypeScript alike.\n */\nconst annotationRendererKinds = [\n \"box\",\n \"box-corners\",\n \"ellipse\",\n \"keypoints\",\n \"label\",\n \"mask\",\n \"maskHalo\",\n \"marker\",\n \"polygon\",\n \"polyline\",\n \"region\",\n];\n/** Sources currently supported by a region renderer. */\nconst RegionRendererSourceKind = {\n Asset: \"asset\",\n};\n/** Media-space regions currently supported by a region renderer. */\nconst RegionRendererRegionKind = {\n Bounds: \"bounds\",\n KeypointAnchor: \"keypoint-anchor\",\n};\n/** Composition modes currently supported by a region renderer. */\nconst RegionRendererComposeMode = {\n Over: \"over\",\n};\n/**\n * Creates built-in annotation renderer descriptors for\n * `MediaRendererPresentation.renderers`.\n *\n * The currently supported renderers retain their established scene ordering:\n * masks, polygons, vectors, labels. A later renderer kind may add a new\n * composition capability without changing that ordering for existing scenes.\n */\nconst annotationRenderers = {\n box: (options) => createAnnotationRenderer(\"box\", options),\n boxCorners: (options) => createAnnotationRenderer(\"box-corners\", options),\n ellipse: (options) => createAnnotationRenderer(\"ellipse\", options),\n keypoints: (options) => createAnnotationRenderer(\"keypoints\", options),\n label: (options) => createAnnotationRenderer(\"label\", options),\n mask: (options) => createAnnotationRenderer(\"mask\", options),\n maskHalo: (options) => createAnnotationRenderer(\"maskHalo\", options),\n marker: (options) => createAnnotationRenderer(\"marker\", options),\n polygon: (options) => createAnnotationRenderer(\"polygon\", options),\n polyline: (options) => createAnnotationRenderer(\"polyline\", options),\n region: (options) => ({ kind: \"region\", ...options }),\n};\nfunction createAnnotationRenderer(kind, options) {\n // Every built-in renderer keeps its kind as its stable id. TypeScript cannot\n // narrow the descriptor union through the generic kind parameter, so the\n // descriptor shape is asserted here and covered by a focused test.\n return { id: kind, kind, ...options };\n}\n\nconst annotationRendererRegistry = {\n box: {\n cardinality: \"singleton\",\n createCanonicalStyle: createDefaultBoxStyle,\n styleField: \"boxStyle\",\n },\n \"box-corners\": {\n cardinality: \"singleton\",\n createCanonicalStyle: createDefaultBoxCornerStyle,\n styleField: \"boxCornerStyle\",\n },\n ellipse: {\n cardinality: \"singleton\",\n createCanonicalStyle: createDefaultEllipseStyle,\n styleField: \"ellipseStyle\",\n },\n keypoints: {\n cardinality: \"singleton\",\n createCanonicalStyle: createDefaultKeypointStyle,\n styleField: \"keypointStyle\",\n },\n label: {\n cardinality: \"singleton\",\n createCanonicalStyle: createDefaultLabelStyle,\n styleField: \"labelStyle\",\n },\n mask: {\n cardinality: \"singleton\",\n createCanonicalStyle: createDefaultMaskStyle,\n styleField: \"maskStyle\",\n },\n maskHalo: {\n cardinality: \"singleton\",\n createCanonicalStyle: () => createDefaultMaskHaloStyle(),\n styleField: \"maskHaloStyle\",\n },\n marker: {\n cardinality: \"singleton\",\n createCanonicalStyle: createDefaultMarkerStyle,\n styleField: \"markerStyle\",\n },\n polygon: {\n cardinality: \"singleton\",\n createCanonicalStyle: createDefaultPolygonStyle,\n styleField: \"polygonStyle\",\n },\n polyline: {\n cardinality: \"singleton\",\n createCanonicalStyle: createDefaultPolylineStyle,\n styleField: \"polylineStyle\",\n },\n region: { cardinality: \"multiple\" },\n};\nfunction isStyleBackedAnnotationRendererKind(kind) {\n return annotationRendererRegistry[kind].cardinality === \"singleton\";\n}\n/** Presentation fields owned by the given renderer kinds, in the same order. */\nfunction resolveAnnotationRendererStyleFields(kinds) {\n return kinds.flatMap((kind) => {\n const metadata = annotationRendererRegistry[kind];\n return \"styleField\" in metadata ? [metadata.styleField] : [];\n });\n}\n\n/**\n * Resolves built-in renderer descriptors into the existing specialized style\n * fields. The browser backend deliberately keeps ownership of its box, mask,\n * label, polygon, polyline, and keypoint pipelines; this normalizer only\n * supplies those pipelines with their configured style.\n */\nfunction resolveAnnotationRendererPresentation(presentation) {\n const renderers = presentation.renderers;\n if (renderers === undefined) {\n return presentation;\n }\n const resolved = {\n boxStyle: null,\n boxCornerStyle: null,\n ellipseStyle: null,\n keypointStyle: null,\n labelStyle: null,\n maskHaloStyle: null,\n maskStyle: null,\n markerStyle: null,\n polygonStyle: null,\n polylineStyle: null,\n };\n const rendererIds = new Set();\n const rendererKinds = new Set();\n for (const renderer of renderers) {\n if (rendererIds.has(renderer.id)) {\n throw new RangeError(`MediaRendererPresentation.renderers contains duplicate renderer id \"${renderer.id}\".`);\n }\n rendererIds.add(renderer.id);\n if (annotationRendererRegistry[renderer.kind].cardinality === \"singleton\" &&\n rendererKinds.has(renderer.kind)) {\n throw new RangeError(`MediaRendererPresentation.renderers contains duplicate renderer kind \"${renderer.kind}\".`);\n }\n rendererKinds.add(renderer.kind);\n if (isStyleBackedAnnotationRenderer(renderer)) {\n applyRendererStyle(resolved, presentation, renderer);\n }\n }\n return {\n ...presentation,\n ...resolved,\n };\n}\nfunction isStyleBackedAnnotationRenderer(renderer) {\n return isStyleBackedAnnotationRendererKind(renderer.kind);\n}\nfunction applyRendererStyle(resolved, configured, renderer) {\n const { createCanonicalStyle, styleField } = annotationRendererRegistry[renderer.kind];\n const configuredStyle = configured[styleField];\n const style = renderer.style !== undefined\n ? renderer.style\n : configuredStyle !== undefined\n ? configuredStyle\n : createCanonicalStyle();\n // The registry pairs each kind with the presentation field holding the same\n // style contract, but TypeScript cannot correlate that pairing across a\n // lookup on a union, so the write is asserted once here.\n resolved[styleField] = style;\n}\n\nfunction createSourceAwarePresentation(globalPresentation = {}, sources, options = {}) {\n if (!sources.some((source) => source.presentation !== undefined)) {\n return globalPresentation;\n }\n const sourcePresentations = new Map(sources.map((source) => [source.id, source.presentation]));\n const enabledStyleFields = options.enabledRendererKinds === undefined\n ? undefined\n : new Set(resolveAnnotationRendererStyleFields(options.enabledRendererKinds));\n const shouldApplySourceStyle = (style) => hasSourceStyle(sources, style) &&\n (enabledStyleFields === undefined || enabledStyleFields.has(style));\n return {\n ...globalPresentation,\n boxStyle: shouldApplySourceStyle(\"boxStyle\")\n ? new SourceAwareBoxStyle(normalizeGlobalBoxStyle(globalPresentation.boxStyle), sourcePresentations)\n : globalPresentation.boxStyle,\n boxCornerStyle: shouldApplySourceStyle(\"boxCornerStyle\")\n ? new SourceAwareBoxCornerStyle(globalPresentation.boxCornerStyle ?? null, sourcePresentations)\n : globalPresentation.boxCornerStyle,\n ellipseStyle: shouldApplySourceStyle(\"ellipseStyle\")\n ? new SourceAwareEllipseStyle(globalPresentation.ellipseStyle ?? null, sourcePresentations)\n : globalPresentation.ellipseStyle,\n labelStyle: shouldApplySourceStyle(\"labelStyle\")\n ? new SourceAwareLabelStyle(normalizeGlobalLabelStyle(globalPresentation.labelStyle), sourcePresentations)\n : globalPresentation.labelStyle,\n maskStyle: shouldApplySourceStyle(\"maskStyle\")\n ? new SourceAwareMaskStyle(normalizeGlobalMaskStyle(globalPresentation.maskStyle), sourcePresentations)\n : globalPresentation.maskStyle,\n markerStyle: shouldApplySourceStyle(\"markerStyle\")\n ? new SourceAwareMarkerStyle(normalizeGlobalMarkerStyle(globalPresentation.markerStyle), sourcePresentations)\n : globalPresentation.markerStyle,\n maskHaloStyle: shouldApplySourceStyle(\"maskHaloStyle\")\n ? new SourceAwareMaskHaloStyle(normalizeGlobalMaskHaloStyle(globalPresentation.maskHaloStyle), sourcePresentations)\n : globalPresentation.maskHaloStyle,\n polygonStyle: shouldApplySourceStyle(\"polygonStyle\")\n ? new SourceAwarePolygonStyle(normalizeGlobalPolygonStyle(globalPresentation.polygonStyle), sourcePresentations)\n : globalPresentation.polygonStyle,\n polylineStyle: shouldApplySourceStyle(\"polylineStyle\")\n ? new SourceAwarePolylineStyle(normalizeGlobalPolylineStyle(globalPresentation.polylineStyle), sourcePresentations)\n : globalPresentation.polylineStyle,\n keypointStyle: shouldApplySourceStyle(\"keypointStyle\")\n ? new SourceAwareKeypointStyle(normalizeGlobalKeypointStyle(globalPresentation.keypointStyle), sourcePresentations)\n : globalPresentation.keypointStyle,\n };\n}\nclass SourceAwareBoxCornerStyle {\n globalStyle;\n sourcePresentations;\n constructor(globalStyle, sourcePresentations) {\n this.globalStyle = globalStyle;\n this.sourcePresentations = sourcePresentations;\n }\n resolve(detection, context) {\n return resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, \"boxCornerStyle\")?.resolve(detection, context);\n }\n}\nclass SourceAwareBoxStyle {\n globalStyle;\n sourcePresentations;\n constructor(globalStyle, sourcePresentations) {\n this.globalStyle = globalStyle;\n this.sourcePresentations = sourcePresentations;\n }\n resolve(detection, context) {\n const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, \"boxStyle\");\n return style?.resolve(detection, context);\n }\n}\nclass SourceAwareEllipseStyle {\n globalStyle;\n sourcePresentations;\n constructor(globalStyle, sourcePresentations) {\n this.globalStyle = globalStyle;\n this.sourcePresentations = sourcePresentations;\n }\n resolve(detection, context) {\n const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, \"ellipseStyle\");\n return style?.resolve(detection, context);\n }\n}\nclass SourceAwareLabelStyle {\n globalStyle;\n sourcePresentations;\n constructor(globalStyle, sourcePresentations) {\n this.globalStyle = globalStyle;\n this.sourcePresentations = sourcePresentations;\n }\n resolve(detection, context) {\n const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, \"labelStyle\");\n return style?.resolve(detection, context);\n }\n}\nclass SourceAwareMaskStyle {\n globalStyle;\n sourcePresentations;\n artifactKey = undefined;\n opacity;\n constructor(globalStyle, sourcePresentations) {\n this.globalStyle = globalStyle;\n this.sourcePresentations = sourcePresentations;\n this.opacity = globalStyle?.opacity;\n }\n resolve(detection, context) {\n const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, \"maskStyle\");\n return style?.resolve(detection, context);\n }\n}\nclass SourceAwareMaskHaloStyle {\n globalStyle;\n sourcePresentations;\n constructor(globalStyle, sourcePresentations) {\n this.globalStyle = globalStyle;\n this.sourcePresentations = sourcePresentations;\n }\n resolve(detection, context) {\n const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, \"maskHaloStyle\");\n return style?.resolve(detection, context);\n }\n}\nclass SourceAwareMarkerStyle {\n globalStyle;\n sourcePresentations;\n constructor(globalStyle, sourcePresentations) {\n this.globalStyle = globalStyle;\n this.sourcePresentations = sourcePresentations;\n }\n resolve(detection, context) {\n const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, \"markerStyle\");\n return style?.resolve(detection, context);\n }\n}\nclass SourceAwarePolygonStyle {\n globalStyle;\n sourcePresentations;\n constructor(globalStyle, sourcePresentations) {\n this.globalStyle = globalStyle;\n this.sourcePresentations = sourcePresentations;\n }\n resolve(detection, context) {\n const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, \"polygonStyle\");\n return style?.resolve(detection, context);\n }\n}\nclass SourceAwarePolylineStyle {\n globalStyle;\n sourcePresentations;\n constructor(globalStyle, sourcePresentations) {\n this.globalStyle = globalStyle;\n this.sourcePresentations = sourcePresentations;\n }\n resolve(detection, context) {\n const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, \"polylineStyle\");\n return style?.resolve(detection, context);\n }\n}\nclass SourceAwareKeypointStyle {\n globalStyle;\n sourcePresentations;\n constructor(globalStyle, sourcePresentations) {\n this.globalStyle = globalStyle;\n this.sourcePresentations = sourcePresentations;\n }\n resolve(detection, context) {\n const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, \"keypointStyle\");\n return style?.resolve(detection, context);\n }\n}\nfunction hasSourceStyle(sources, key) {\n return sources.some((source) => source.presentation?.[key] !== undefined);\n}\nfunction resolveSourceStyle(detection, globalStyle, sourcePresentations, key) {\n const sourcePresentation = detection.sourceId\n ? sourcePresentations.get(detection.sourceId)\n : undefined;\n const sourceStyle = sourcePresentation?.[key];\n return sourceStyle === undefined ? globalStyle : sourceStyle;\n}\nfunction normalizeGlobalBoxStyle(style) {\n return style === undefined ? new BaseBoxStyle() : style;\n}\nfunction normalizeGlobalLabelStyle(style) {\n return style === undefined ? new BaseLabelStyle() : style;\n}\nfunction normalizeGlobalMaskStyle(style) {\n return style === undefined ? new BaseMaskStyle() : style;\n}\nfunction normalizeGlobalMaskHaloStyle(style) {\n return style === undefined ? createDefaultMaskHaloStyle() : style;\n}\nfunction normalizeGlobalMarkerStyle(style) {\n return style === undefined ? new BaseMarkerStyle() : style;\n}\nfunction normalizeGlobalPolygonStyle(style) {\n return style === undefined ? new BasePolygonStyle() : style;\n}\nfunction normalizeGlobalPolylineStyle(style) {\n return style === undefined ? new BasePolylineStyle() : style;\n}\nfunction normalizeGlobalKeypointStyle(style) {\n return style === undefined ? new BaseKeypointStyle() : style;\n}\n\nfunction rectToPolygon(rect) {\n const halfWidth = rect.width / 2;\n const halfHeight = rect.height / 2;\n return {\n points: [\n { x: rect.x - halfWidth, y: rect.y - halfHeight },\n { x: rect.x + halfWidth, y: rect.y - halfHeight },\n { x: rect.x + halfWidth, y: rect.y + halfHeight },\n { x: rect.x - halfWidth, y: rect.y + halfHeight },\n ],\n };\n}\nfunction polygonToRect(polygon) {\n return getPointsRect(polygon.points);\n}\nfunction rasterizeRectToMask(rect, dimensions) {\n const data = createEmptyMask(dimensions);\n const topLeft = centerRectToTopLeftRect(rect);\n const left = Math.max(0, Math.round(topLeft.x));\n const top = Math.max(0, Math.round(topLeft.y));\n const right = Math.min(dimensions.width - 1, Math.round(rect.x + rect.width / 2));\n const bottom = Math.min(dimensions.height - 1, Math.round(rect.y + rect.height / 2));\n for (let y = top; y <= bottom; y += 1) {\n for (let x = left; x <= right; x += 1) {\n data[y * dimensions.width + x] = 1;\n }\n }\n return data;\n}\nfunction rasterizePolygonToMask(points, dimensions) {\n const data = createEmptyMask(dimensions);\n if (points.length < 3) {\n return data;\n }\n const bounds = centerRectToTopLeftRect(getPointsRect(points));\n const startY = Math.max(0, Math.floor(bounds.y));\n const endY = Math.min(dimensions.height - 1, Math.ceil(bounds.y + bounds.height));\n for (let y = startY; y <= endY; y += 1) {\n const scanY = y + 0.5;\n const intersections = [];\n for (let index = 0; index < points.length; index += 1) {\n const current = points[index];\n const next = points[(index + 1) % points.length];\n if ((current.y <= scanY && next.y > scanY) ||\n (next.y <= scanY && current.y > scanY)) {\n const ratio = (scanY - current.y) / (next.y - current.y);\n intersections.push(current.x + ratio * (next.x - current.x));\n }\n }\n intersections.sort((left, right) => left - right);\n for (let index = 0; index < intersections.length - 1; index += 2) {\n const left = Math.max(0, Math.ceil(intersections[index]));\n const right = Math.min(dimensions.width - 1, Math.floor(intersections[index + 1]));\n for (let x = left; x <= right; x += 1) {\n data[y * dimensions.width + x] = 1;\n }\n }\n }\n return data;\n}\nfunction convertDetectionBoxToPolygon(detection) {\n return detection.rect\n ? replaceGeometry(detection, { polygon: rectToPolygon(detection.rect) })\n : detection;\n}\nfunction convertDetectionPolygonToBox(detection) {\n const rect = detection.polygon ? polygonToRect(detection.polygon) : undefined;\n return rect ? replaceGeometry(detection, { rect }) : detection;\n}\nfunction convertDetectionMaskToBox(detection) {\n const rect = detection.mask\n ? computeDetectionMaskRect(detection.mask)\n : undefined;\n return rect ? replaceGeometry(detection, { rect }) : detection;\n}\nfunction convertDetectionMaskToPolygon(detection) {\n if (!detection.mask) {\n return detection;\n }\n const decoded = decodeCompressedRleMask(detection.mask);\n const contour = extractMaskContour(decoded.data, decoded.width, decoded.height);\n const fallbackRect = computeDetectionMaskRect(detection.mask);\n const polygon = contour && contour.length >= 3\n ? { points: contour }\n : fallbackRect\n ? rectToPolygon(fallbackRect)\n : undefined;\n return polygon ? replaceGeometry(detection, { polygon }) : detection;\n}\nfunction convertDetectionBoxToMask(detection, dimensions) {\n if (!detection.rect) {\n return detection;\n }\n const mask = encodeBinaryMask(rasterizeRectToMask(detection.rect, dimensions), dimensions.width, dimensions.height);\n return replaceGeometry(detection, { mask });\n}\nfunction convertDetectionPolygonToMask(detection, dimensions) {\n if (!detection.polygon) {\n return detection;\n }\n const mask = encodeBinaryMask(rasterizePolygonToMask(detection.polygon.points, dimensions), dimensions.width, dimensions.height);\n return replaceGeometry(detection, { mask });\n}\nfunction mergeDetectionMasks(detections) {\n if (detections.length < 2 || detections.some(({ mask }) => !mask)) {\n return null;\n }\n const first = detections[0];\n if (detections.some((detection) => detection.className !== first.className)) {\n return null;\n }\n const masks = detections.map(({ mask }) => decodeCompressedRleMask(mask));\n const width = masks[0].width;\n const height = masks[0].height;\n if (masks.some((mask) => mask.width !== width || mask.height !== height)) {\n throw new Error(\"Merged detection masks must have matching dimensions.\");\n }\n const data = new Uint8Array(width * height);\n for (const mask of masks) {\n for (let index = 0; index < data.length; index += 1) {\n data[index] ||= mask.data[index] ?? 0;\n }\n }\n return replaceGeometry(first, {\n mask: encodeBinaryMask(data, width, height),\n });\n}\n/**\n * Groups polygon detections by class and returns one union bounding-box\n * detection per class. This intentionally converts the output to rectangles.\n */\nfunction mergeDetectionPolygonsByClass(detections, options = {}) {\n const groups = new Map();\n for (const detection of detections) {\n if (!detection.polygon) {\n continue;\n }\n const group = groups.get(detection.className) ?? [];\n group.push(detection);\n groups.set(detection.className, group);\n }\n return [...groups.entries()].flatMap(([className, group], groupIndex) => {\n const points = group.flatMap((detection) => detection.polygon.points);\n const rect = getPointsRect(points);\n if (!rect) {\n return [];\n }\n const first = group[0];\n const id = options.createId?.(className, groupIndex) ?? first.id;\n return [\n replaceGeometry({\n ...first,\n id,\n }, { rect }),\n ];\n });\n}\nfunction createEmptyMask(dimensions) {\n if (!Number.isInteger(dimensions.width) ||\n dimensions.width <= 0 ||\n !Number.isInteger(dimensions.height) ||\n dimensions.height <= 0) {\n throw new Error(\"Media dimensions must be positive integers.\");\n }\n return new Uint8Array(dimensions.width * dimensions.height);\n}\nfunction replaceGeometry(detection, geometry) {\n return {\n ...detection,\n keypoints: undefined,\n mask: geometry.mask,\n polygon: geometry.polygon,\n polyline: undefined,\n rect: geometry.rect,\n };\n}\n\nfunction canReuseMaskStyleArtifacts(previousMaskStyle, nextMaskStyle) {\n if (previousMaskStyle === nextMaskStyle) {\n return true;\n }\n return (previousMaskStyle?.artifactKey !== undefined &&\n nextMaskStyle?.artifactKey !== undefined &&\n previousMaskStyle.artifactKey === nextMaskStyle.artifactKey);\n}\nfunction resolveMaskStyleOpacity(maskStyle) {\n const opacity = maskStyle?.opacity;\n if (opacity === undefined) {\n return 1;\n }\n return Number.isFinite(opacity) ? Math.max(0, Math.min(opacity, 1)) : 1;\n}\n\nconst MAX_ID_MASK_PALETTE_ENTRIES = 64;\nconst MAX_ID_MASK_STROKE_WIDTH = 16;\nfunction createIdMaskFrame(instructions) {\n if (instructions.length === 0) {\n return undefined;\n }\n const width = Math.max(...instructions.map(({ mask }) => mask.width));\n const height = Math.max(...instructions.map(({ mask }) => mask.height));\n const data = new Uint8Array(new ArrayBuffer(width * height));\n const fillPalette = new Float32Array(new ArrayBuffer(MAX_ID_MASK_PALETTE_ENTRIES * 4 * 4));\n const strokePalette = new Float32Array(new ArrayBuffer(MAX_ID_MASK_PALETTE_ENTRIES * 4 * 4));\n const strokeWidths = new Float32Array(new ArrayBuffer(MAX_ID_MASK_PALETTE_ENTRIES * 4));\n let hasStroke = false;\n let maxStrokeWidth = 0;\n for (const instruction of instructions) {\n const detectionMaskId = instruction.detectionIndex + 1;\n if (detectionMaskId <= 0 ||\n detectionMaskId >= MAX_ID_MASK_PALETTE_ENTRIES) {\n return undefined;\n }\n writePaletteEntry(fillPalette, detectionMaskId, instruction.color, instruction.alpha);\n if (instruction.stroke && instruction.stroke.width > 0) {\n const strokeWidth = Math.min(Math.max(0, instruction.stroke.width), MAX_ID_MASK_STROKE_WIDTH);\n hasStroke = true;\n strokeWidths[detectionMaskId] = strokeWidth;\n maxStrokeWidth = Math.max(maxStrokeWidth, strokeWidth);\n writePaletteEntry(strokePalette, detectionMaskId, instruction.stroke.color, instruction.stroke.alpha);\n }\n const decodedMask = decodeCompressedRleMask(instruction.mask);\n for (let y = 0; y < decodedMask.height; y += 1) {\n for (let x = 0; x < decodedMask.width; x += 1) {\n const maskOffset = y * decodedMask.width + x;\n if (decodedMask.data[maskOffset]) {\n data[y * width + x] = detectionMaskId;\n }\n }\n }\n }\n return {\n data,\n fillPalette,\n hasStroke,\n height,\n maxStrokeWidth,\n strokePalette,\n strokeWidths,\n width,\n };\n}\nfunction writePaletteEntry(palette, id, color, alpha) {\n const offset = id * 4;\n palette[offset] = ((color >> 16) & 0xff) / 255;\n palette[offset + 1] = ((color >> 8) & 0xff) / 255;\n palette[offset + 2] = (color & 0xff) / 255;\n palette[offset + 3] = Math.max(0, Math.min(alpha, 1));\n}\n\nconst DEFAULT_ELLIPSE_SEGMENT_COUNT = 48;\nconst FULL_TURN = Math.PI * 2;\nconst GEOMETRY_EPSILON = 1e-9;\nconst MIN_ELLIPSE_SEGMENT_COUNT = 4;\nconst MAX_ELLIPSE_SEGMENT_COUNT = 512;\n/**\n * Samples an ellipse or elliptical arc into a deterministic polyline so every\n * backend rasterizes the same structural geometry, including dashed strokes.\n *\n * A closed ellipse returns `segmentCount` points without repeating the first\n * point; an open arc returns `segmentCount + 1` points including both\n * endpoints.\n */\nfunction sampleEllipseArc(ellipse, segmentCount = DEFAULT_ELLIPSE_SEGMENT_COUNT) {\n validateEllipseGeometry(ellipse);\n assertIntegerAtLeast(segmentCount, MIN_ELLIPSE_SEGMENT_COUNT, \"segmentCount\");\n const rotation = ellipse.rotation ?? 0;\n const startAngle = ellipse.startAngle ?? 0;\n const endAngle = ellipse.endAngle ?? startAngle + FULL_TURN;\n const range = endAngle - startAngle;\n const closed = ellipse.startAngle === undefined;\n const pointCount = closed ? segmentCount : segmentCount + 1;\n const cosRotation = Math.cos(rotation);\n const sinRotation = Math.sin(rotation);\n const points = [];\n for (let index = 0; index < pointCount; index += 1) {\n const angle = startAngle + (range * index) / segmentCount;\n const localX = Math.cos(angle) * ellipse.radiusX;\n const localY = Math.sin(angle) * ellipse.radiusY;\n points.push({\n x: ellipse.center.x + localX * cosRotation - localY * sinRotation,\n y: ellipse.center.y + localX * sinRotation + localY * cosRotation,\n });\n }\n return { closed, points };\n}\n/**\n * Chooses a bounded segment count from the ellipse's on-screen radius. The\n * result targets sub-pixel chord error without making tiny markers expensive.\n */\nfunction resolveEllipseSegmentCount(ellipse, viewportScale = 1, maxErrorPixels = 0.5) {\n validateEllipseGeometry(ellipse);\n assertPositiveFinite(viewportScale, \"viewportScale\");\n assertPositiveFinite(maxErrorPixels, \"maxErrorPixels\");\n const screenRadius = Math.max(ellipse.radiusX, ellipse.radiusY) * viewportScale;\n assertPositiveFinite(screenRadius, \"screenRadius\");\n const clampedError = Math.min(maxErrorPixels, screenRadius);\n const maxStep = clampedError === screenRadius\n ? Math.PI / 2\n : 2 * Math.acos(1 - clampedError / screenRadius);\n const startAngle = ellipse.startAngle ?? 0;\n const endAngle = ellipse.endAngle ?? startAngle + FULL_TURN;\n const arcLength = Math.abs(endAngle - startAngle);\n const segmentCount = Math.ceil(arcLength / maxStep);\n return Math.min(MAX_ELLIPSE_SEGMENT_COUNT, Math.max(MIN_ELLIPSE_SEGMENT_COUNT, segmentCount));\n}\n/**\n * Resolves a marker instruction into media-space geometry. Screen-space sizes\n * are divided by the viewport scale, matching stroke-width semantics.\n */\nfunction resolveMarkerGeometry(marker, viewportScale = 1) {\n assertFinitePoint(marker.center, \"center\");\n assertPositiveFinite(marker.size, \"size\");\n assertPositiveFinite(viewportScale, \"viewportScale\");\n if (marker.rotation !== undefined) {\n assertFinite(marker.rotation, \"rotation\");\n }\n const size = marker.sizeSpace === MarkerSizeSpace.Screen\n ? marker.size / viewportScale\n : marker.size;\n const radius = size / 2;\n const rotation = marker.rotation ?? 0;\n if (marker.shape === MarkerShape.Circle) {\n return { center: marker.center, kind: \"circle\", radius };\n }\n if (marker.shape === MarkerShape.Cross) {\n return {\n closed: false,\n kind: \"subpaths\",\n subpaths: [\n [\n rotatePoint(marker.center, -radius, -radius, rotation),\n rotatePoint(marker.center, radius, radius, rotation),\n ],\n [\n rotatePoint(marker.center, radius, -radius, rotation),\n rotatePoint(marker.center, -radius, radius, rotation),\n ],\n ],\n };\n }\n if (marker.shape === MarkerShape.Square) {\n return {\n closed: true,\n kind: \"subpaths\",\n subpaths: [\n [\n rotatePoint(marker.center, -radius, -radius, rotation),\n rotatePoint(marker.center, radius, -radius, rotation),\n rotatePoint(marker.center, radius, radius, rotation),\n rotatePoint(marker.center, -radius, radius, rotation),\n ],\n ],\n };\n }\n // Triangle: equilateral, inscribed in the marker circle, pointing toward\n // positive y at rotation 0.\n const baseOffsetY = -radius / 2;\n const baseOffsetX = radius * (Math.sqrt(3) / 2);\n return {\n closed: true,\n kind: \"subpaths\",\n subpaths: [\n [\n rotatePoint(marker.center, 0, radius, rotation),\n rotatePoint(marker.center, baseOffsetX, baseOffsetY, rotation),\n rotatePoint(marker.center, -baseOffsetX, baseOffsetY, rotation),\n ],\n ],\n };\n}\nfunction validateEllipseGeometry(ellipse) {\n assertFinitePoint(ellipse.center, \"center\");\n assertPositiveFinite(ellipse.radiusX, \"radiusX\");\n assertPositiveFinite(ellipse.radiusY, \"radiusY\");\n if (ellipse.rotation !== undefined) {\n assertFinite(ellipse.rotation, \"rotation\");\n }\n const hasStart = ellipse.startAngle !== undefined;\n const hasEnd = ellipse.endAngle !== undefined;\n if (hasStart !== hasEnd) {\n throw new RangeError(\"startAngle and endAngle must be provided together\");\n }\n if (hasStart && hasEnd) {\n assertFinite(ellipse.startAngle, \"startAngle\");\n assertFinite(ellipse.endAngle, \"endAngle\");\n const range = Math.abs(ellipse.endAngle - ellipse.startAngle);\n if (range <= GEOMETRY_EPSILON || range >= FULL_TURN - GEOMETRY_EPSILON) {\n throw new RangeError(\"ellipse arc range must be greater than 0 and less than one full turn\");\n }\n }\n}\nfunction assertFinitePoint(point, name) {\n assertFinite(point.x, `${name}.x`);\n assertFinite(point.y, `${name}.y`);\n}\nfunction assertFinite(value, name) {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${name} must be finite`);\n }\n}\nfunction assertPositiveFinite(value, name) {\n assertFinite(value, name);\n if (value <= 0) {\n throw new RangeError(`${name} must be greater than 0`);\n }\n}\nfunction assertIntegerAtLeast(value, minimum, name) {\n if (!Number.isInteger(value) || value < minimum) {\n throw new RangeError(`${name} must be an integer of at least ${minimum}`);\n }\n}\nfunction rotatePoint(center, offsetX, offsetY, rotation) {\n if (rotation === 0) {\n return { x: center.x + offsetX, y: center.y + offsetY };\n }\n const cosRotation = Math.cos(rotation);\n const sinRotation = Math.sin(rotation);\n return {\n x: center.x + offsetX * cosRotation - offsetY * sinRotation,\n y: center.y + offsetX * sinRotation + offsetY * cosRotation,\n };\n}\n\nfunction includeDefined(values) {\n return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined));\n}\n\nfunction resolveAnnotationStyleState(detection, visibility) {\n const id = detection.id;\n return {\n hidden: visibility?.annotationsHidden === true ||\n (detection.className !== undefined &&\n includes(visibility?.hiddenClasses, detection.className)) ||\n (id !== undefined && includes(visibility?.hiddenDetectionIds, id)),\n loading: id !== undefined && includes(visibility?.loadingDetectionIds, id),\n ephemeral: id !== undefined && includes(visibility?.ephemeralDetectionIds, id),\n isCreating: id !== undefined && visibility?.creatingDetectionId === id,\n };\n}\nfunction includes(values, value) {\n if (!values)\n return false;\n return Array.isArray(values)\n ? values.includes(value)\n : values.has(value);\n}\n\nvar MediaRendererFit;\n(function (MediaRendererFit) {\n /**\n * Preserve media aspect ratio and fit the full frame inside the canvas.\n */\n MediaRendererFit[\"Contain\"] = \"contain\";\n /**\n * Preserve media aspect ratio and fill the canvas, cropping if necessary.\n */\n MediaRendererFit[\"Cover\"] = \"cover\";\n})(MediaRendererFit || (MediaRendererFit = {}));\n/**\n * Playback lifecycle state reported by a platform renderer.\n */\nvar MediaRendererPlaybackState;\n(function (MediaRendererPlaybackState) {\n MediaRendererPlaybackState[\"Loading\"] = \"loading\";\n MediaRendererPlaybackState[\"Ready\"] = \"ready\";\n MediaRendererPlaybackState[\"Playing\"] = \"playing\";\n MediaRendererPlaybackState[\"Buffering\"] = \"buffering\";\n MediaRendererPlaybackState[\"Paused\"] = \"paused\";\n MediaRendererPlaybackState[\"Error\"] = \"error\";\n MediaRendererPlaybackState[\"Destroyed\"] = \"destroyed\";\n})(MediaRendererPlaybackState || (MediaRendererPlaybackState = {}));\n/**\n * Stable classification of a media failure.\n *\n * Applications branch on these kinds instead of parsing decoder, demuxer, or\n * container error text, and still own their localized user-facing copy. New\n * kinds may be added over time, so treat unrecognized values like `Unknown`.\n */\nvar MediaErrorKind;\n(function (MediaErrorKind) {\n /** The media could not be opened or read at all. */\n MediaErrorKind[\"Unreadable\"] = \"unreadable\";\n /** The container or codec is not supported by this platform. */\n MediaErrorKind[\"UnsupportedFormat\"] = \"unsupportedFormat\";\n /** The media opened but carries no usable video track. */\n MediaErrorKind[\"NoVideoTrack\"] = \"noVideoTrack\";\n /** Decoding a sample failed after the source opened. */\n MediaErrorKind[\"Decode\"] = \"decode\";\n /** The media could not be fetched. */\n MediaErrorKind[\"Network\"] = \"network\";\n /** The host environment lacks the APIs this media source requires. */\n MediaErrorKind[\"EnvironmentUnsupported\"] = \"environmentUnsupported\";\n /** The failure could not be classified. */\n MediaErrorKind[\"Unknown\"] = \"unknown\";\n})(MediaErrorKind || (MediaErrorKind = {}));\n/**\n * Lower-level media source readiness.\n */\nvar MediaSourceStatus;\n(function (MediaSourceStatus) {\n MediaSourceStatus[\"Loading\"] = \"loading\";\n MediaSourceStatus[\"Ready\"] = \"ready\";\n MediaSourceStatus[\"Error\"] = \"error\";\n MediaSourceStatus[\"Destroyed\"] = \"destroyed\";\n})(MediaSourceStatus || (MediaSourceStatus = {}));\n\n/**\n * Media-session operating mode.\n *\n * Core owns the names because file-like and stream-like lifecycle choices are\n * platform-neutral. Platform packages decide how these modes tune media,\n * storage, and renderer defaults.\n */\nvar MediaSessionMode;\n(function (MediaSessionMode) {\n /**\n * Finite media. Defaults usually favor seek/replay and persistent detection\n * storage.\n */\n MediaSessionMode[\"File\"] = \"file\";\n /**\n * Live or append-only media. Defaults usually favor rolling windows and\n * bounded retention.\n */\n MediaSessionMode[\"Stream\"] = \"stream\";\n})(MediaSessionMode || (MediaSessionMode = {}));\n/**\n * Aggregate lifecycle state for a media session.\n */\nvar MediaSessionStatus;\n(function (MediaSessionStatus) {\n MediaSessionStatus[\"Buffering\"] = \"buffering\";\n MediaSessionStatus[\"Destroyed\"] = \"destroyed\";\n MediaSessionStatus[\"Error\"] = \"error\";\n MediaSessionStatus[\"Loading\"] = \"loading\";\n MediaSessionStatus[\"Paused\"] = \"paused\";\n MediaSessionStatus[\"Playing\"] = \"playing\";\n MediaSessionStatus[\"Processing\"] = \"processing\";\n MediaSessionStatus[\"Ready\"] = \"ready\";\n})(MediaSessionStatus || (MediaSessionStatus = {}));\n/**\n * Subsystem currently affecting session readiness or presentation.\n */\nvar MediaSessionActivityKind;\n(function (MediaSessionActivityKind) {\n MediaSessionActivityKind[\"DetectionsBuffering\"] = \"detectionsBuffering\";\n MediaSessionActivityKind[\"DetectionsLoading\"] = \"detectionsLoading\";\n MediaSessionActivityKind[\"Error\"] = \"error\";\n MediaSessionActivityKind[\"MediaNormalizing\"] = \"mediaNormalizing\";\n MediaSessionActivityKind[\"MediaOpening\"] = \"mediaOpening\";\n MediaSessionActivityKind[\"PlaybackBuffering\"] = \"playbackBuffering\";\n MediaSessionActivityKind[\"RenderPreparing\"] = \"renderPreparing\";\n})(MediaSessionActivityKind || (MediaSessionActivityKind = {}));\n/**\n * State of one session activity.\n */\nvar MediaSessionActivityStatus;\n(function (MediaSessionActivityStatus) {\n MediaSessionActivityStatus[\"Error\"] = \"error\";\n MediaSessionActivityStatus[\"Running\"] = \"running\";\n MediaSessionActivityStatus[\"Waiting\"] = \"waiting\";\n})(MediaSessionActivityStatus || (MediaSessionActivityStatus = {}));\n\nexport { AnnotationFrameMutationKind, AnnotationGeometryKind, AnnotationGestureStateKind, AnnotationHandleKind, BaseBoxCornerStyle, BaseBoxStyle, BaseFocusStyle, BaseInteractionStyle, BaseKeypointStyle, BaseLabelStyle, BaseMarkerStyle, BaseMaskStyle, BasePolygonStyle, BasePolylineStyle, BoxShape, StrokeAlignment as BoxStrokeAlignment, DEFAULT_DETECTION_CLASS_STYLES, DEFAULT_DETECTION_COLOR_SEQUENCE, DetectionBufferStatus, DetectionFrameRetentionMode, DetectionFrameSelectionMode, DetectionInteractionState, DetectionMaskEncoding, DetectionMaskPayloadFormat, DetectionPickTarget, FocusTargetMode, KeypointMarkerShape, KeypointVisibility, LabelPlacement, LabelVisibilityMode, MAX_ID_MASK_PALETTE_ENTRIES, MAX_ID_MASK_STROKE_WIDTH, MarkerShape, MarkerSizeSpace, MaskRenderMode, MediaErrorKind, MediaInteractionMode, MediaRendererFit, MediaRendererPlaybackState, MediaSessionActivityKind, MediaSessionActivityStatus, MediaSessionMode, MediaSessionStatus, MediaSourceStatus, RegionRendererComposeMode, RegionRendererRegionKind, RegionRendererSourceKind, SUPERVISION_ROBOFLOW_COLOR, ShapeInstructionKind, StrokeAlignment, TrackingGeometry, annotationRendererKinds, annotationRenderers, applyAnnotationHandleDrag, canReuseMaskStyleArtifacts, centerRectToTopLeftRect, computeDetectionMaskRect, computeMaskBounds, containsPoint, convertDetectionBoxToMask, convertDetectionBoxToPolygon, convertDetectionMaskToBox, convertDetectionMaskToPolygon, convertDetectionPolygonToBox, convertDetectionPolygonToMask, copySortedDetectionFrames, createAnnotationEditingEngine, createArrayDetectionFrameSource, createBufferedDetectionTimeline, createByteTrackTracker, createCBIoUTracker, createColdDetectionFrameSource, createCompositeDetectionFrameSource, createDefaultAnnotationPresentation, createDetectionPickKey, createEditableAnnotationFrameSession, createIdMaskFrame, createIdleDetectionBufferState, createMemoryColdDetectionFrameStore, createOCSortTracker, createProjectedDetectionFrameSource, createSortTracker, createSourceAwarePresentation, createViewportController, createWritableDetectionFrameSource, decodeCompressedRleCounts, decodeCompressedRleMask, decodeDetectionMaskPayload, deleteAnnotationVertex, detectMaskBorders, detectionFrameOverlapsRange, detectionPostProcessors, distanceToSegment, encodeBinaryMask, encodeBinaryMaskWithBounds, encodeCompressedRleCounts, encodeDetectionMaskPayload, extractMaskContour, extractMaskRectRuns, filterDetectionFramesForRange, findClosestAnnotationSegment, followDetectionPickAcrossFrames, getAnnotationHandles, getBufferedDetectionTimelineFrameSnapshot, getDetectionRect, getPointsRect, haveSameDetectionPickIdentities, includeDefined, isDeflatedBase64DetectionMaskPayload, lightenColor, mediaToScreen, mergeDetectionMasks, mergeDetectionPolygonsByClass, normalizeDetectionClassName, offsetDetection, pickAnnotationHandle, pickDetectionAtPoint, pickDetectionByMaskId, pointInPolygon, polygonArea, polygonToRect, projectDetectionFrame, projectDetectionFrameForTracking, projectDetectionFrames, rasterizePolygonToMask, rasterizeRectToMask, rebaseDetectionPickToFrame, rectArea, rectToPolygon, resolveAnnotationRendererPresentation, resolveAnnotationStyleState, resolveContrastTextColor, resolveDetectionClassColorStyle, resolveEllipseSegmentCount, resolveMarkerGeometry, resolveMaskStyleOpacity, resolveStyleValue, sampleEllipseArc, screenToMedia, selectDetectionFrame, topLeftRectToCenterRect, validateDetectionFrames };\n//# sourceMappingURL=index.js.map\n",null],"names":[],"mappings":";;;IAAA;IACA,IAAI,kBAAkB;IACtB,CAAC,UAAU,kBAAkB,EAAE;IAC/B,IAAI,kBAAkB,CAAC,kBAAkB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY;IAC3E,IAAI,kBAAkB,CAAC,kBAAkB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU;IACvE,IAAI,kBAAkB,CAAC,kBAAkB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS;IACrE,CAAC,EAAE,kBAAkB,KAAK,kBAAkB,GAAG,EAAE,CAAC,CAAC;IACnD,IAAI,qBAAqB;IACzB,CAAC,UAAU,qBAAqB,EAAE;IAClC,IAAI,qBAAqB,CAAC,eAAe,CAAC,GAAG,eAAe;IAC5D,CAAC,EAAE,qBAAqB,KAAK,qBAAqB,GAAG,EAAE,CAAC,CAAC;;IAEzD,IAAI,qBAAqB;IACzB,CAAC,UAAU,qBAAqB,EAAE;IAClC,IAAI,qBAAqB,CAAC,MAAM,CAAC,GAAG,MAAM;IAC1C,IAAI,qBAAqB,CAAC,SAAS,CAAC,GAAG,SAAS;IAChD,IAAI,qBAAqB,CAAC,OAAO,CAAC,GAAG,OAAO;IAC5C,IAAI,qBAAqB,CAAC,OAAO,CAAC,GAAG,OAAO;IAC5C,IAAI,qBAAqB,CAAC,WAAW,CAAC,GAAG,WAAW;IACpD,CAAC,EAAE,qBAAqB,KAAK,qBAAqB,GAAG,EAAE,CAAC,CAAC;IACzD;IACA;IACA;IACA,IAAI,2BAA2B;IAC/B,CAAC,UAAU,2BAA2B,EAAE;IACxC;IACA;IACA;IACA;IACA,IAAI,2BAA2B,CAAC,UAAU,CAAC,GAAG,UAAU;IACxD;IACA;IACA;IACA;IACA;IACA,IAAI,2BAA2B,CAAC,mBAAmB,CAAC,GAAG,mBAAmB;IAC1E,CAAC,EAAE,2BAA2B,KAAK,2BAA2B,GAAG,EAAE,CAAC,CAAC;IACrE,IAAI,2BAA2B;IAC/B,CAAC,UAAU,2BAA2B,EAAE;IACxC;IACA;IACA;IACA;IACA,IAAI,2BAA2B,CAAC,YAAY,CAAC,GAAG,YAAY;IAC5D;IACA;IACA;IACA;IACA,IAAI,2BAA2B,CAAC,YAAY,CAAC,GAAG,YAAY;IAC5D;IACA;IACA;IACA;IACA,IAAI,2BAA2B,CAAC,eAAe,CAAC,GAAG,eAAe;IAClE,CAAC,EAAE,2BAA2B,KAAK,2BAA2B,GAAG,EAAE,CAAC,CAAC;;IAwoCrE,IAAI,2BAA2B;IAC/B,CAAC,UAAU,2BAA2B,EAAE;IACxC,IAAI,2BAA2B,CAAC,KAAK,CAAC,GAAG,KAAK;IAC9C,IAAI,2BAA2B,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACpD,IAAI,2BAA2B,CAAC,SAAS,CAAC,GAAG,SAAS;IACtD,IAAI,2BAA2B,CAAC,UAAU,CAAC,GAAG,UAAU;IACxD,IAAI,2BAA2B,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACpD,CAAC,EAAE,2BAA2B,KAAK,2BAA2B,GAAG,EAAE,CAAC,CAAC;;IA2gCrE;IACA;IACA;IACA;IACA;IACA;IACA,SAAS,mBAAmB,CAAC,OAAO,GAAG,EAAE,EAAE;IAC3C,IAAI,MAAM,eAAe,GAAG,6BAA6B,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,EAAE,iBAAiB,CAAC;IAC3G,IAAI,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE;IAC7C,IAAI,MAAM,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,IAAI,IAAI;IAC7E,IAAI,MAAM,wBAAwB,GAAG,0BAA0B,CAAC,OAAO,CAAC,wBAAwB,IAAI,CAAC,EAAE,0BAA0B,CAAC;IAClI,IAAI,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,IAAI,GAAG;IAClE,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE;IACvD,QAAQ,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC;IACrE,IAAI;IACJ,IAAI,uBAAuB,CAAC,wBAAwB,EAAE,0BAA0B,CAAC;IACjF,IAAI,uBAAuB,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;IACvE,IAAI,MAAM,qBAAqB,GAAG,CAAC,SAAS,GAAG,EAAE,IAAI,eAAe;IACpE,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE;IACjD,QAAQ,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC;IAC7G,IAAI;IACJ,IAAI,MAAM,0BAA0B,GAAG,eAAe,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAChH,IAAI,IAAI,MAAM,GAAG,EAAE;IACnB,IAAI,IAAI,aAAa,GAAG,CAAC;IACzB,IAAI,IAAI,kBAAkB;IAC1B,IAAI,OAAO;IACX,QAAQ,KAAK,GAAG;IAChB,YAAY,MAAM,GAAG,EAAE;IACvB,YAAY,aAAa,GAAG,CAAC;IAC7B,YAAY,kBAAkB,GAAG,SAAS;IAC1C,QAAQ,CAAC;IACT,QAAQ,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE;IACvC,YAAY,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,CAAC;IAC9E,YAAY,kBAAkB,GAAG,UAAU,IAAI,kBAAkB;IACjE,YAAY,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACxF,YAAY,MAAM,EAAE,OAAO,EAAE,mBAAmB,EAAE,GAAG,2BAA2B,CAAC,UAAU,EAAE,SAAS,EAAE,mBAAmB,CAAC;IAC5H,YAAY,MAAM,UAAU,GAAG,IAAI,GAAG,EAAE;IACxC,YAAY,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE;IACzC,gBAAgB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;IACtD,gBAAgB,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,cAAc,CAAC;IAClE,gBAAgB,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;IACvC,gBAAgB,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;IACjD,oBAAoB,KAAK,CAAC,iBAAiB,IAAI,wBAAwB,EAAE;IACzE,oBAAoB,KAAK,CAAC,SAAS,GAAG,aAAa;IACnD,oBAAoB,aAAa,IAAI,CAAC;IACtC,gBAAgB;IAChB,gBAAgB,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE;IACnD,oBAAoB,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7E,gBAAgB;IAChB,YAAY;IACZ,YAAY,KAAK,MAAM,cAAc,IAAI,mBAAmB,EAAE;IAC9D,gBAAgB,MAAM,SAAS,GAAG,UAAU,CAAC,cAAc,CAAC;IAC5D,gBAAgB,IAAI,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,KAAK,wBAAwB,EAAE;IAC7E,oBAAoB,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC;IAC9D,gBAAgB;IAChB,YAAY;IACZ,YAAY,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,eAAe,IAAI,0BAA0B;IACjG,iBAAiB,KAAK,CAAC,iBAAiB,IAAI,wBAAwB;IACpE,oBAAoB,KAAK,CAAC,eAAe,KAAK,CAAC,CAAC,CAAC;IACjD,YAAY,OAAO;IACnB,gBAAgB,gBAAgB,EAAE,MAAM,CAAC,MAAM;IAC/C,gBAAgB,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK;IAC/D,oBAAoB,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC;IAC9E,oBAAoB,OAAO,SAAS,KAAK;IACzC,0BAA0B;IAC1B,0BAA0B,CAAC,EAAE,cAAc,EAAE,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE,CAAC;IACnF,gBAAgB,CAAC,CAAC;IAClB,gBAAgB,mBAAmB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,MAAM;IACnG,aAAa;IACb,QAAQ,CAAC;IACT,KAAK;IACL;IACA,MAAM,cAAc,CAAC;IACrB,IAAI,kBAAkB;IACtB,IAAI,SAAS;IACb,IAAI,iBAAiB,GAAG,CAAC;IACzB,IAAI,eAAe,GAAG,CAAC;IACvB,IAAI,KAAK;IACT,IAAI,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC;IAC5B,IAAI,WAAW,CAAC,SAAS,EAAE,kBAAkB,GAAG,KAAK,EAAE;IACvD,QAAQ,IAAI,CAAC,kBAAkB,GAAG,kBAAkB;IACpD,QAAQ,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK;IAChF,YAAY,KAAK;IACjB,SAAS,CAAC;IACV,IAAI;IACJ,IAAI,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE;IAClC,QAAQ,IAAI,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,EAAE;IACjE,YAAY,IAAI,CAAC,iBAAiB,GAAG,CAAC;IACtC,QAAQ;IACR,QAAQ,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC;IACtC,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;IACnD,YAAY,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,SAAS;IACpD,QAAQ;IACR,QAAQ,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC;IACrD,QAAQ,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC/I;IACA,QAAQ,IAAI,CAAC,eAAe,IAAI,CAAC;IACjC,QAAQ,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;IACtC,IAAI;IACJ,IAAI,MAAM,CAAC,SAAS,EAAE;IACtB,QAAQ,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9E,QAAQ,MAAM,WAAW,GAAG;IAC5B,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACpC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACpC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACpC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACpC,SAAS;IACT,QAAQ,MAAM,gBAAgB,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;IACxD,QAAQ,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACnF,QAAQ,MAAM,8BAA8B,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;IAChG,QAAQ,MAAM,oBAAoB,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,8BAA8B,CAAC,EAAE,gBAAgB,CAAC;IACjH,QAAQ,MAAM,IAAI,GAAG,QAAQ,CAAC,8BAA8B,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC5F,QAAQ,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAChE,QAAQ,MAAM,4BAA4B,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC/F;IACA,QAAQ,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,4BAA4B,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,4BAA4B,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACtM,QAAQ,IAAI,CAAC,eAAe,GAAG,CAAC;IAChC,QAAQ,IAAI,CAAC,iBAAiB,IAAI,CAAC;IACnC,IAAI;IACJ,IAAI,YAAY,GAAG;IACnB,QAAQ,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;IACtC,IAAI;IACJ;IACA,SAAS,2BAA2B,CAAC,UAAU,EAAE,SAAS,EAAE,mBAAmB,EAAE;IACjF,IAAI,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;IAC3D,QAAQ,OAAO;IACf,YAAY,OAAO,EAAE,EAAE;IACvB,YAAY,mBAAmB,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,KAAK,CAAC;IACpE,SAAS;IACT,IAAI;IACJ;IACA,IAAI,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,qBAAqB,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACtH,IAAI,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,MAAM,CAAC;IACvD,IAAI,MAAM,OAAO,GAAG,EAAE;IACtB,IAAI,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAE;IACvC,IAAI,KAAK,MAAM,CAAC,UAAU,EAAE,cAAc,CAAC,IAAI,gBAAgB,EAAE;IACjE,QAAQ,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,cAAc,CAAC,GAAG,mBAAmB;IACpE,YAAY;IACZ,QAAQ,OAAO,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC;IACpD,QAAQ,iBAAiB,CAAC,GAAG,CAAC,cAAc,CAAC;IAC7C,IAAI;IACJ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IACrE,IAAI,OAAO;IACX,QAAQ,OAAO;IACf,QAAQ,mBAAmB,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1G,KAAK;IACL;IACA;IACA,SAAS,kBAAkB,CAAC,MAAM,EAAE;IACpC,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,EAAE;IACxD,QAAQ,OAAO,EAAE;IACjB,IAAI;IACJ,IAAI,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM;IAClC,IAAI,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM;IACxC,IAAI,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW;IAC7C,IAAI,MAAM,KAAK,GAAG;IAClB,UAAU,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;IAClI,UAAU,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;IAC5D,IAAI,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM;IAC7B,IAAI,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM;IACnC,IAAI,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,IAAI,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5C,IAAI,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5C,IAAI,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9C,IAAI,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE;IAC7C,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG;IAClB,QAAQ,IAAI,OAAO,GAAG,CAAC;IACvB,QAAQ,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAC9E,QAAQ,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IACvD,QAAQ,GAAG;IACX,YAAY,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI;IAChC,YAAY,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC;IACnC,YAAY,IAAI,KAAK,GAAG,MAAM,CAAC,iBAAiB;IAChD,YAAY,IAAI,OAAO,GAAG,CAAC;IAC3B,YAAY,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE;IACjE,gBAAgB,IAAI,IAAI,CAAC,MAAM,CAAC;IAChC,oBAAoB;IACpB,gBAAgB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACjF,gBAAgB,IAAI,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE;IAChD,oBAAoB,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO;IAC9C,oBAAoB,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO;IACzC,gBAAgB;IAChB,gBAAgB,IAAI,QAAQ,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE;IAC9C,oBAAoB,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC5C,oBAAoB,OAAO,GAAG,MAAM;IACpC,gBAAgB;IAChB,YAAY;IACZ,YAAY,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE;IACjE,gBAAgB,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE;IAClC,oBAAoB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK;IACzC,oBAAoB,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK;IACtC,gBAAgB;IAChB,qBAAqB;IACrB,oBAAoB,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK;IAC7C,gBAAgB;IAChB,YAAY;IACZ,YAAY,OAAO,GAAG,OAAO;IAC7B,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACjC,QAAQ,GAAG;IACX,YAAY,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IACxC,YAAY,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;IACnC,YAAY,OAAO,GAAG,OAAO;IAC7B,QAAQ,CAAC,QAAQ,OAAO,KAAK,CAAC;IAC9B,IAAI;IACJ,IAAI,MAAM,WAAW,GAAG,EAAE;IAC1B,IAAI,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE;IACzD,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;IAC3B,YAAY;IACZ,QAAQ,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;IACjC,QAAQ,WAAW,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5E,IAAI;IACJ,IAAI,OAAO,WAAW;IACtB;IACA,SAAS,UAAU,CAAC,IAAI,EAAE;IAC1B,IAAI,OAAO;IACX,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;IAC/B,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;IAChC,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;IAC/B,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;IAChC,KAAK;IACL;IACA,SAAS,WAAW,CAAC,KAAK,EAAE;IAC5B;IACA;IACA;IACA,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,OAAO;IACX,QAAQ,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC;IACjD,QAAQ,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC;IAChD,QAAQ,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC;IACxB,KAAK;IACL;IACA,SAAS,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE;IAClD,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG,SAAS,EAAE;IACtD,QAAQ,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;IACvC,IAAI;IACJ,IAAI,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxE,IAAI,MAAM,GAAG,GAAG,SAAS,GAAG,SAAS;IACrC,IAAI,MAAM,GAAG,GAAG,GAAG,GAAG,SAAS;IAC/B,IAAI,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG;IACzB,IAAI,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;IAC/C,QAAQ,MAAM,aAAa,GAAG,KAAK,GAAG,CAAC;IACvC,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC;IAC/C,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC;IACvD,QAAQ,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC;IACvD,QAAQ,MAAM,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,GAAG,IAAI,GAAG,GAAG;IACzD,IAAI;IACJ,IAAI,OAAO,MAAM;IACjB;IACA,SAAS,qBAAqB,CAAC,IAAI,EAAE,KAAK,EAAE;IAC5C,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;IACzC,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;IAC1C,IAAI,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC;IAC5C,IAAI,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC;IAC7C,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC;IAC5F,QAAQ,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC/F,QAAQ,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,MAAM,YAAY,GAAG,iBAAiB,GAAG,kBAAkB;IAC/D,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,YAAY;IACtF,IAAI,OAAO,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,GAAG,KAAK;IAChD;IACA,SAAS,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE;IAC7C,IAAI,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS;IACvD,QAAQ,OAAO,CAAC;IAChB,IAAI,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1C;IACA,SAAS,0BAA0B,CAAC,KAAK,EAAE,KAAK,EAAE;IAClD,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE;IAC/C,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC/D,IAAI;IACJ,IAAI,OAAO,KAAK;IAChB;IACA,SAAS,6BAA6B,CAAC,KAAK,EAAE,KAAK,EAAE;IACrD,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE;IAC/C,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACnE,IAAI;IACJ,IAAI,OAAO,KAAK;IAChB;IACA,SAAS,uBAAuB,CAAC,KAAK,EAAE,KAAK,EAAE;IAC/C,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE;IAC3D,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC5D,IAAI;IACJ;IACA,SAAS,QAAQ,CAAC,IAAI,EAAE;IACxB,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,MAAM,GAAG,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1H;IACA,SAAS,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE;IAC/B,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,GAAG,MAAM,CAAC,CAAC;IAClE;IACA,SAAS,SAAS,CAAC,MAAM,EAAE;IAC3B,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACzE;IACA,SAAS,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;IAC1B,IAAI,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7G;IACA,SAAS,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE;IAC/B,IAAI,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7G;IACA,SAAS,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE;IAC/B,IAAI,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,KAAK,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACnI;IACA,SAAS,OAAO,CAAC,MAAM,EAAE;IACzB,IAAI,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM;IAC9B,IAAI,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK;IACjD,QAAQ,GAAG,GAAG;IACd,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;IAChC,KAAK,CAAC;IACN,IAAI,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,EAAE;IACrD,QAAQ,IAAI,KAAK,GAAG,MAAM;IAC1B,QAAQ,KAAK,IAAI,GAAG,GAAG,MAAM,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE;IACzD,YAAY,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAChD,gBAAgB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;IACpD,gBAAgB,KAAK,GAAG,GAAG;IAC3B,YAAY;IACZ,QAAQ;IACR,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,EAAE;IACxD,YAAY,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC;IAClE,QAAQ;IACR,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG;IAChD,YAAY,SAAS,CAAC,KAAK,CAAC;IAC5B,YAAY,SAAS,CAAC,MAAM,CAAC;IAC7B,SAAS;IACT,QAAQ,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IACjD,QAAQ,SAAS,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,GAAG,OAAO,CAAC;IAC7E,QAAQ,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE;IAChD,YAAY,IAAI,GAAG,KAAK,MAAM;IAC9B,gBAAgB;IAChB,YAAY,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,YAAY,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;IAC5G,QAAQ;IACR,IAAI;IACJ,IAAI,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClD;;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,SAAS,wBAAwB,CAAC,OAAO,GAAG,EAAE,EAAE;IAChD,IAAI,MAAM,eAAe,GAAG,6BAA6B,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,EAAE,iBAAiB,CAAC;IAC3G,IAAI,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE;IAC7C,IAAI,MAAM,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,IAAI,GAAG;IAC5E,IAAI,MAAM,wBAAwB,GAAG,0BAA0B,CAAC,OAAO,CAAC,wBAAwB,IAAI,CAAC,EAAE,0BAA0B,CAAC;IAClI,IAAI,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,IAAI,GAAG;IAClE,IAAI,MAAM,gCAAgC,GAAG,OAAO,CAAC,gCAAgC,IAAI,GAAG;IAC5F,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE;IACvD,QAAQ,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC;IACrE,IAAI;IACJ,IAAI,uBAAuB,CAAC,wBAAwB,EAAE,0BAA0B,CAAC;IACjF,IAAI,uBAAuB,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;IACvE,IAAI,uBAAuB,CAAC,gCAAgC,EAAE,kCAAkC,CAAC;IACjG,IAAI,MAAM,qBAAqB,GAAG,CAAC,SAAS,GAAG,EAAE,IAAI,eAAe;IACpE,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE;IACjD,QAAQ,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC;IAC7G,IAAI;IACJ,IAAI,MAAM,0BAA0B,GAAG,eAAe,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAChH,IAAI,IAAI,MAAM,GAAG,EAAE;IACnB,IAAI,IAAI,aAAa,GAAG,CAAC;IACzB,IAAI,IAAI,kBAAkB;IAC1B,IAAI,OAAO;IACX,QAAQ,KAAK,GAAG;IAChB,YAAY,MAAM,GAAG,EAAE;IACvB,YAAY,aAAa,GAAG,CAAC;IAC7B,YAAY,kBAAkB,GAAG,SAAS;IAC1C,QAAQ,CAAC;IACT,QAAQ,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE;IACvC,YAAY,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,CAAC;IAC9E,YAAY,kBAAkB,GAAG,UAAU,IAAI,kBAAkB;IACjE,YAAY,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC1E,YAAY,MAAM,oBAAoB,GAAG,EAAE;IAC3C,YAAY,MAAM,mBAAmB,GAAG,EAAE;IAC1C,YAAY,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,KAAK;IACrD,gBAAgB,IAAI,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,KAAK,gCAAgC,EAAE;IACrF,oBAAoB,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC;IACpD,gBAAgB;IAChB,qBAAqB;IACrB,oBAAoB,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;IACnD,gBAAgB;IAChB,YAAY,CAAC,CAAC;IACd,YAAY,MAAM,WAAW,GAAG,IAAI,GAAG,EAAE;IACzC,YAAY,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,oBAAoB,EAAE,mBAAmB,CAAC;IACvG,YAAY,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,OAAO,EAAE;IACpD,gBAAgB,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC;IAC3G,YAAY;IACZ,YAAY,MAAM,eAAe,GAAG,UAAU,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;IAClG,YAAY,MAAM,WAAW,GAAG,SAAS,CAAC,eAAe,EAAE,UAAU,EAAE,mBAAmB,EAAE,mBAAmB,CAAC;IAChH,YAAY,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,EAAE;IACrD,gBAAgB,kBAAkB,CAAC,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC;IACpH,YAAY;IACZ;IACA,YAAY,KAAK,MAAM,cAAc,IAAI,UAAU,CAAC,yBAAyB,EAAE;IAC/E,gBAAgB,MAAM,SAAS,GAAG,UAAU,CAAC,cAAc,CAAC;IAC5D,gBAAgB,IAAI,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,KAAK,wBAAwB,EAAE;IAC7E,oBAAoB,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACpE,gBAAgB;IAChB,YAAY;IACZ;IACA;IACA,YAAY,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,eAAe,IAAI,0BAA0B;IACjG,iBAAiB,KAAK,CAAC,SAAS,KAAK,SAAS;IAC9C,oBAAoB,KAAK,CAAC,iBAAiB,IAAI,wBAAwB;IACvE,oBAAoB,KAAK,CAAC,eAAe,KAAK,CAAC,CAAC,CAAC;IACjD,YAAY,OAAO;IACnB,gBAAgB,gBAAgB,EAAE,MAAM,CAAC,MAAM;IAC/C,gBAAgB,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK;IAC/D,oBAAoB,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC;IAC/E,oBAAoB,OAAO,SAAS,KAAK;IACzC,0BAA0B;IAC1B,0BAA0B,CAAC,EAAE,cAAc,EAAE,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE,CAAC;IACnF,gBAAgB,CAAC,CAAC;IAClB,gBAAgB,mBAAmB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,MAAM;IACnG,aAAa;IACb,QAAQ,CAAC;IACT,KAAK;IACL,IAAI,SAAS,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE;IAC/D,QAAQ,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;IAC/B,QAAQ,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;IACzC,YAAY,KAAK,CAAC,iBAAiB,IAAI,wBAAwB,EAAE;IACjE,YAAY,KAAK,CAAC,SAAS,GAAG,aAAa;IAC3C,YAAY,aAAa,IAAI,CAAC;IAC9B,QAAQ;IACR,QAAQ,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE;IAC3C,YAAY,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC;IACtE,QAAQ;IACR,IAAI;IACJ;IACA,SAAS,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,EAAE;IAC9E,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE;IAC9D,QAAQ,OAAO;IACf,YAAY,OAAO,EAAE,EAAE;IACvB,YAAY,yBAAyB,EAAE,CAAC,GAAG,gBAAgB,CAAC;IAC5D,YAAY,qBAAqB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,KAAK,CAAC;IAClE,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK;IACzC,QAAQ,MAAM,aAAa,GAAG,KAAK,CAAC,YAAY,EAAE;IAClD,QAAQ,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,cAAc,KAAK,qBAAqB,CAAC,aAAa,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9H,IAAI,CAAC,CAAC;IACN,IAAI,MAAM,OAAO,GAAG,EAAE;IACtB,IAAI,MAAM,aAAa,GAAG,IAAI,GAAG,EAAE;IACnC,IAAI,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAE;IACvC,IAAI,KAAK,MAAM,CAAC,UAAU,EAAE,mBAAmB,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE;IAChF,QAAQ,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,EAAE;IAC3E,YAAY;IACZ,QAAQ;IACR,QAAQ,MAAM,cAAc,GAAG,gBAAgB,CAAC,mBAAmB,CAAC;IACpE,QAAQ,OAAO,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC;IACpD,QAAQ,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC;IACrC,QAAQ,iBAAiB,CAAC,GAAG,CAAC,cAAc,CAAC;IAC7C,IAAI;IACJ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IACrE,IAAI,OAAO;IACX,QAAQ,OAAO;IACf,QAAQ,yBAAyB,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpG,QAAQ,qBAAqB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IACpG,KAAK;IACL;;IAEA,SAAS,uBAAuB,CAAC,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,GAAG,MAAM,EAAE;IAC9G,IAAI,MAAM,OAAO,GAAG,EAAE;IACtB,IAAI,MAAM,aAAa,GAAG,IAAI,GAAG,EAAE;IACnC,IAAI,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAE;IACvC,IAAI,KAAK,MAAM,CAAC,UAAU,EAAE,cAAc,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE;IAC3E,QAAQ,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC,cAAc,CAAC,GAAG,YAAY;IACvE,YAAY;IACZ,QAAQ,OAAO,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC;IACpD,QAAQ,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC;IACrC,QAAQ,iBAAiB,CAAC,GAAG,CAAC,cAAc,CAAC;IAC7C,IAAI;IACJ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IACrE,IAAI,OAAO;IACX,QAAQ,OAAO;IACf,QAAQ,yBAAyB,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/I,QAAQ,qBAAqB,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnI,KAAK;IACL;IACA,SAAS,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,GAAG,CAAC,EAAE;IAC1D,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,6BAA6B,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IAC7H;IACA,SAAS,6BAA6B,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE;IACjE,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC;IACxD,IAAI,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC;IAC1D,IAAI,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC;IAC1D,IAAI,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC;IAC5D,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC;IACxC,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,UAAU,GAAG,CAAC;IACzC,IAAI,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,UAAU,GAAG,CAAC;IAC3C,IAAI,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC;IAC5C,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,SAAS,EAAE,MAAM,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACrH,IAAI,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;IAC7F,QAAQ,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,MAAM,YAAY,GAAG,iBAAiB,GAAG,kBAAkB;IAC/D,IAAI,MAAM,KAAK,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY;IAClF,IAAI,OAAO,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,GAAG,KAAK;IAChD;;IAEA;IACA;IACA;IACA;IACA;IACA,MAAM,uBAAuB,CAAC;IAC9B,IAAI,cAAc;IAClB,IAAI,SAAS;IACb,IAAI,oBAAoB,GAAG,CAAC;IAC5B,IAAI,UAAU;IACd,IAAI,gBAAgB,GAAG,QAAQ,CAAC,CAAC,CAAC;IAClC,IAAI,YAAY;IAChB,IAAI,KAAK;IACT,IAAI,oBAAoB;IACxB,IAAI,eAAe;IACnB,IAAI,eAAe;IACnB,IAAI,WAAW,CAAC,WAAW,EAAE,cAAc,EAAE;IAC7C,QAAQ,IAAI,CAAC,cAAc,GAAG,cAAc;IAC5C,QAAQ,MAAM,WAAW,GAAG,iBAAiB,CAAC,WAAW,EAAE,cAAc,CAAC;IAC1E,QAAQ,IAAI,CAAC,SAAS,GAAG,cAAc,KAAK,QAAQ,GAAG,CAAC,GAAG,CAAC;IAC5D,QAAQ,IAAI,CAAC,eAAe;IAC5B,YAAY,cAAc,KAAK,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAClE,QAAQ,IAAI,CAAC,eAAe;IAC5B,YAAY,cAAc,KAAK,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAClE,QAAQ,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK;IAC1E,YAAY,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC;IACnC,SAAS,CAAC;IACV,QAAQ,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;IAClD,QAAQ,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;IACpD,QAAQ,IAAI,CAAC,oBAAoB,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;IAC5D,IAAI;IACJ,IAAI,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE;IAClC,QAAQ,IAAI,IAAI,CAAC,cAAc,KAAK,QAAQ;IAC5C,YAAY,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;IAClE,YAAY,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAChC,QAAQ;IACR,QAAQ,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;IACnD,QAAQ,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,KAAK,KAAK;IAC/D,YAAY,UAAU,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS;IAC9E,QAAQ,CAAC,CAAC;IACV,QAAQ,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC;IACzE,QAAQ,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC;IACrD,QAAQ,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC;IACxH,IAAI;IACJ,IAAI,MAAM,CAAC,IAAI,EAAE;IACjB,QAAQ,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;IAC5E,IAAI;IACJ,IAAI,iBAAiB,CAAC,WAAW,EAAE;IACnC,QAAQ,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAChJ,QAAQ,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC;IACrE,QAAQ,MAAM,UAAU,GAAG,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACzF,QAAQ,MAAM,8BAA8B,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;IAChG,QAAQ,MAAM,oBAAoB,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,8BAA8B,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC;IACtH,QAAQ,MAAM,IAAI,GAAG,QAAQ,CAAC,8BAA8B,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC5F,QAAQ,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAChE,QAAQ,MAAM,4BAA4B,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC5G,QAAQ,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,4BAA4B,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,4BAA4B,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3M,IAAI;IACJ,IAAI,OAAO,GAAG;IACd,QAAQ,OAAO,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC;IAClG,IAAI;IACJ,IAAI,cAAc,CAAC,OAAO,EAAE;IAC5B,QAAQ,IAAI,OAAO,CAAC,UAAU;IAC9B,YAAY,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;IACvD,QAAQ,IAAI,OAAO,CAAC,gBAAgB,EAAE;IACtC,YAAY,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC;IACnE,QAAQ;IACR,QAAQ,IAAI,OAAO,CAAC,YAAY,EAAE;IAClC,YAAY,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;IAC3D,YAAY,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;IACnE,QAAQ;IACR,IAAI;IACJ,IAAI,QAAQ,GAAG;IACf,QAAQ,OAAO;IACf,YAAY,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;IAC9C,YAAY,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC;IAC1D,YAAY,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC;IAClD,YAAY,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;IACpC,SAAS;IACT,IAAI;IACJ,IAAI,OAAO,CAAC,QAAQ,EAAE;IACtB,QAAQ,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;IACpD,QAAQ,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAChE,QAAQ,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC;IACxD,QAAQ,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC1C,IAAI;IACJ,IAAI,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE;IAC7C,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG,SAAS,EAAE;IAC1D,YAAY,OAAO,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC;IACnD,QAAQ;IACR,QAAQ,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtG,QAAQ,MAAM,GAAG,GAAG,SAAS,GAAG,SAAS;IACzC,QAAQ,MAAM,GAAG,GAAG,GAAG,GAAG,SAAS;IACnC,QAAQ,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG;IAC7B,QAAQ,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IACzC,YAAY,GAAG,IAAI,CAAC,eAAe;IACnC,YAAY,GAAG,IAAI,CAAC,eAAe;IACnC,SAAS,CAAC;IACV,QAAQ,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,KAAK,KAAK;IAC/D,YAAY,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;IAC7D,YAAY,MAAM,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC;IAChG,YAAY,MAAM,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,oBAAoB,GAAG,GAAG,IAAI,CAAC;IACnF,YAAY,MAAM,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,oBAAoB,GAAG,GAAG,IAAI,CAAC;IACnF,YAAY,MAAM,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,oBAAoB,GAAG,GAAG,IAAI,CAAC;IACnF,YAAY,MAAM,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,GAAG,oBAAoB,GAAG,GAAG;IAC7E,QAAQ,CAAC,CAAC;IACV,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,IAAI,CAAC,EAAE;IAChE,YAAY,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;IAC9C,gBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;IAC9E,YAAY;IACZ,QAAQ;IACR,QAAQ,OAAO,MAAM;IACrB,IAAI;IACJ;IACA,SAAS,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE;IACjD,IAAI,IAAI,cAAc,KAAK,QAAQ,EAAE;IACrC,QAAQ,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;IACxD,IAAI;IACJ,IAAI,OAAO;IACX,QAAQ,IAAI,CAAC,CAAC;IACd,QAAQ,IAAI,CAAC,CAAC;IACd,QAAQ,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM;IAChC,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACzC,KAAK;IACL;IACA,SAAS,iBAAiB,CAAC,WAAW,EAAE,cAAc,EAAE;IACxD,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,WAAW;IAC7C,IAAI,IAAI,cAAc,KAAK,QAAQ,EAAE;IACrC,QAAQ,OAAO;IACf,YAAY,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC;IAC1C,YAAY,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC;IACxC,YAAY,CAAC;IACb,YAAY,CAAC;IACb,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;IAC3C,IAAI,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,KAAK;IAClD,IAAI,OAAO;IACX,QAAQ,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC;IAChD,QAAQ,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC;IAC9C,QAAQ,CAAC;IACT,QAAQ,CAAC;IACT,KAAK;IACL;IACA,SAAS,QAAQ,CAAC,MAAM,EAAE;IAC1B,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,MAAM,GAAG,KAAK,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9F;IACA,SAAS,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE;IACrC,IAAI,OAAO,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IAChC;IACA,SAAS,KAAK,CAAC,MAAM,EAAE;IACvB,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;IACxC;;IAEA,MAAM,4BAA4B,GAAG,GAAG;IACxC,MAAM,UAAU,CAAC;IACjB,IAAI,SAAS;IACb,IAAI,iBAAiB,GAAG,CAAC;IACzB,IAAI,eAAe,GAAG,CAAC;IACvB,IAAI,SAAS;IACb,IAAI,WAAW,CAAC,OAAO,EAAE;IACzB,QAAQ,IAAI,CAAC,SAAS,GAAG,IAAI,uBAAuB,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;IAC5E,QAAQ,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;IACrE,IAAI;IACJ,IAAI,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE;IAClC,QAAQ,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;IAChD,QAAQ,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;IACtC,YAAY,YAAY,EAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/G,SAAS,CAAC;IACV,QAAQ,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC;IACpD,QAAQ,IAAI,CAAC,UAAU,EAAE;IACzB,QAAQ,IAAI,CAAC,eAAe,IAAI,CAAC;IACjC,IAAI;IACJ,IAAI,MAAM,CAAC,SAAS,EAAE;IACtB,QAAQ,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;IAChD,QAAQ,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;IACtC,YAAY,gBAAgB,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvH,SAAS,CAAC;IACV,QAAQ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7C,QAAQ,IAAI,CAAC,UAAU,EAAE;IACzB,QAAQ,IAAI,CAAC,eAAe,GAAG,CAAC;IAChC,QAAQ,IAAI,CAAC,iBAAiB,IAAI,CAAC;IACnC,IAAI;IACJ,IAAI,OAAO,GAAG;IACd,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;IACvC,IAAI;IACJ,IAAI,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE;IACnC,QAAQ,MAAM,aAAa,GAAG,IAAI;IAClC,QAAQ,MAAM,aAAa,GAAG,OAAO;IACrC,QAAQ,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;IACtC,YAAY,UAAU,EAAE,QAAQ,CAAC;IACjC,gBAAgB,CAAC,CAAC,GAAG,aAAa,GAAG,KAAK,KAAK,CAAC;IAChD,gBAAgB,CAAC,CAAC,GAAG,aAAa,GAAG,MAAM,KAAK,CAAC;IACjD,gBAAgB,CAAC,CAAC,GAAG,aAAa,GAAG,KAAK,KAAK,CAAC;IAChD,gBAAgB,CAAC,CAAC,GAAG,aAAa,GAAG,MAAM,KAAK,CAAC;IACjD,gBAAgB,CAAC,EAAE,GAAG,aAAa,GAAG,KAAK,KAAK,CAAC;IACjD,gBAAgB,CAAC,EAAE,GAAG,aAAa,GAAG,MAAM,KAAK,CAAC;IAClD,gBAAgB,CAAC,EAAE,GAAG,aAAa,GAAG,KAAK,KAAK,CAAC;IACjD,gBAAgB,CAAC,EAAE,GAAG,aAAa,GAAG,MAAM,KAAK,CAAC;IAClD,aAAa,CAAC;IACd,YAAY,gBAAgB,EAAE,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC;IACvE,YAAY,YAAY,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC;IAC/D,SAAS,CAAC;IACV,IAAI;IACJ,IAAI,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;IACrC,QAAQ,MAAM,aAAa,GAAG,IAAI;IAClC,QAAQ,MAAM,aAAa,GAAG,OAAO;IACrC,QAAQ,OAAO,QAAQ,CAAC;IACxB,YAAY,CAAC,aAAa,GAAG,KAAK,KAAK,CAAC;IACxC,YAAY,CAAC,aAAa,GAAG,MAAM,KAAK,CAAC;IACzC,YAAY,CAAC,aAAa,GAAG,KAAK,KAAK,CAAC;IACxC,YAAY,CAAC,aAAa,GAAG,MAAM,KAAK,CAAC;IACzC,YAAY,CAAC,aAAa,GAAG,KAAK,KAAK,CAAC;IACxC,YAAY,CAAC,aAAa,GAAG,MAAM,KAAK,CAAC;IACzC,YAAY,CAAC,aAAa,GAAG,KAAK,KAAK,CAAC;IACxC,YAAY,CAAC,aAAa,GAAG,MAAM,KAAK,CAAC;IACzC,SAAS,CAAC;IACV,IAAI;IACJ,IAAI,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE;IACzC,QAAQ,MAAM,gBAAgB,GAAG,IAAI;IACrC,QAAQ,OAAO,QAAQ,CAAC;IACxB,YAAY,CAAC,gBAAgB,GAAG,KAAK,KAAK,CAAC;IAC3C,YAAY,CAAC,gBAAgB,GAAG,MAAM,KAAK,CAAC;IAC5C,YAAY,CAAC,gBAAgB,GAAG,KAAK,KAAK,CAAC;IAC3C,YAAY,CAAC,gBAAgB,GAAG,MAAM,KAAK,CAAC;IAC5C,SAAS,CAAC;IACV,IAAI;IACJ,IAAI,UAAU,GAAG;IACjB,QAAQ,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;IAC/E,QAAQ,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;IAC/E,IAAI;IACJ;IACA;IACA,SAAS,oBAAoB,CAAC,OAAO,GAAG,EAAE,EAAE;IAC5C,IAAI,MAAM,eAAe,GAAG,6BAA6B,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,EAAE,iBAAiB,CAAC;IAC3G,IAAI,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE;IAC7C,IAAI,MAAM,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,IAAI,GAAG;IAC5E,IAAI,MAAM,wBAAwB,GAAG,0BAA0B,CAAC,OAAO,CAAC,wBAAwB,IAAI,CAAC,EAAE,0BAA0B,CAAC;IAClI,IAAI,MAAM,mCAAmC,GAAG,OAAO,CAAC,mCAAmC,IAAI,GAAG;IAClG,IAAI,MAAM,oCAAoC,GAAG,OAAO,CAAC,oCAAoC,IAAI,GAAG;IACpG,IAAI,MAAM,yCAAyC,GAAG,OAAO,CAAC,yCAAyC,IAAI,GAAG;IAC9G,IAAI,MAAM,gCAAgC,GAAG,OAAO,CAAC,gCAAgC,IAAI,GAAG;IAC5F,IAAI,MAAM,2BAA2B,GAAG,OAAO,CAAC,2BAA2B,IAAI,IAAI;IACnF,IAAI,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,GAAG;IAC5D,IAAI,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,GAAG;IAC9D,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE;IACvD,QAAQ,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC;IACrE,IAAI;IACJ,IAAI,uBAAuB,CAAC,wBAAwB,EAAE,0BAA0B,CAAC;IACjF,IAAI,uBAAuB,CAAC,mCAAmC,EAAE,qCAAqC,CAAC;IACvG,IAAI,uBAAuB,CAAC,oCAAoC,EAAE,sCAAsC,CAAC;IACzG,IAAI,uBAAuB,CAAC,yCAAyC,EAAE,2CAA2C,CAAC;IACnH,IAAI,uBAAuB,CAAC,gCAAgC,EAAE,kCAAkC,CAAC;IACjG,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,GAAG,CAAC,EAAE;IACpE,QAAQ,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC;IAChF,IAAI;IACJ,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,iBAAiB,GAAG,CAAC,EAAE;IACtE,QAAQ,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC;IACjF,IAAI;IACJ,IAAI,MAAM,qBAAqB,GAAG,CAAC,SAAS,GAAG,EAAE,IAAI,eAAe;IACpE,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE;IACjD,QAAQ,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC;IAC7G,IAAI;IACJ,IAAI,MAAM,0BAA0B,GAAG,eAAe,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAChH,IAAI,IAAI,MAAM,GAAG,EAAE;IACnB,IAAI,IAAI,aAAa,GAAG,CAAC;IACzB,IAAI,IAAI,OAAO,GAAG,CAAC;IACnB,IAAI,IAAI,kBAAkB;IAC1B,IAAI,OAAO;IACX,QAAQ,KAAK,GAAG;IAChB,YAAY,MAAM,GAAG,EAAE;IACvB,YAAY,aAAa,GAAG,CAAC;IAC7B,YAAY,OAAO,GAAG,CAAC;IACvB,YAAY,kBAAkB,GAAG,SAAS;IAC1C,QAAQ,CAAC;IACT,QAAQ,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE;IACvC,YAAY,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,CAAC;IAC9E,YAAY,kBAAkB,GAAG,UAAU,IAAI,kBAAkB;IACjE,YAAY,OAAO,IAAI,CAAC;IACxB,YAAY,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC1E,YAAY,MAAM,oBAAoB,GAAG,EAAE;IAC3C,YAAY,MAAM,mBAAmB,GAAG,EAAE;IAC1C,YAAY,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,KAAK;IACrD,gBAAgB,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,IAAI,CAAC;IAC5D,gBAAgB,IAAI,UAAU,IAAI,gCAAgC,EAAE;IACpE,oBAAoB,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC;IACpD,gBAAgB;IAChB,qBAAqB,IAAI,UAAU,GAAG,4BAA4B,EAAE;IACpE,oBAAoB,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;IACnD,gBAAgB;IAChB,YAAY,CAAC,CAAC;IACd,YAAY,MAAM,SAAS,GAAG,EAAE;IAChC,YAAY,MAAM,WAAW,GAAG,EAAE;IAClC,YAAY,MAAM,IAAI,GAAG,EAAE;IAC3B,YAAY,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;IACxC,gBAAgB,IAAI,KAAK,CAAC,eAAe,GAAG,CAAC;IAC7C,oBAAoB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IACpC,qBAAqB,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;IACtD,oBAAoB,KAAK,CAAC,iBAAiB,IAAI,wBAAwB,EAAE;IACzE,oBAAoB,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;IACzC,gBAAgB;IAChB;IACA,oBAAoB,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;IAC3C,YAAY;IACZ,YAAY,MAAM,WAAW,GAAG,IAAI,GAAG,EAAE;IACzC,YAAY,MAAM,IAAI,GAAG,CAAC,GAAG,SAAS,EAAE,GAAG,IAAI,CAAC;IAChD,YAAY,MAAM,cAAc,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC,CAAC;IACzF,YAAY,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/O,YAAY,MAAM,gBAAgB,GAAG,uBAAuB,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,mCAAmC,CAAC;IAClJ,YAAY,KAAK,MAAM,KAAK,IAAI,gBAAgB,CAAC,OAAO,EAAE;IAC1D,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7G,YAAY;IACZ,YAAY,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;IACtD,iBAAiB,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC;IAC3C,iBAAiB,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,eAAe,KAAK,CAAC,CAAC;IAC/D,YAAY,MAAM,aAAa,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC,CAAC;IACvF,YAAY,MAAM,YAAY,GAAG,WAAW,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACnK,YAAY,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,YAAY,EAAE,gBAAgB,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,oCAAoC,CAAC;IAChK,YAAY,KAAK,MAAM,KAAK,IAAI,iBAAiB,CAAC,OAAO,EAAE;IAC3D,gBAAgB,kBAAkB,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC;IACxH,YAAY;IACZ,YAAY,IAAI,kBAAkB,GAAG,CAAC,GAAG,gBAAgB,CAAC,yBAAyB,CAAC;IACpF,YAAY,IAAI,oBAAoB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,KAAK,CAAC;IAC3E,YAAY,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE;IACzE,gBAAgB,MAAM,aAAa,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC,KAAK,CAAC,CAAC;IAC9F,gBAAgB,MAAM,iBAAiB,GAAG,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9P,gBAAgB,MAAM,sBAAsB,GAAG,uBAAuB,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,yCAAyC,CAAC;IAC9K,gBAAgB,oBAAoB,GAAG,sBAAsB,CAAC,qBAAqB;IACnF,gBAAgB,KAAK,MAAM,KAAK,IAAI,sBAAsB,CAAC,OAAO,EAAE;IACpE,oBAAoB,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC;IACvH,gBAAgB;IAChB,gBAAgB,kBAAkB;IAClC,oBAAoB,sBAAsB,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC9G,YAAY;IACZ,YAAY,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/G,YAAY,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,0BAA0B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACrF,YAAY,KAAK,MAAM,UAAU,IAAI,kBAAkB,EAAE;IACzD,gBAAgB,MAAM,SAAS,GAAG,cAAc,CAAC,UAAU,CAAC;IAC5D,gBAAgB,IAAI,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,IAAI,wBAAwB;IAC1E,oBAAoB;IACpB,gBAAgB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC;IACvD,gBAAgB,IAAI,OAAO,KAAK,CAAC,IAAI,2BAA2B,EAAE;IAClE,oBAAoB,KAAK,CAAC,SAAS,GAAG,aAAa,EAAE;IACrD,oBAAoB,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9E,gBAAgB;IAChB,gBAAgB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;IAClC,YAAY;IACZ,YAAY,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,eAAe,IAAI,0BAA0B;IACjG,iBAAiB,KAAK,CAAC,eAAe,KAAK,CAAC;IAC5C,oBAAoB,KAAK,CAAC,SAAS,KAAK,SAAS;IACjD,oBAAoB,KAAK,CAAC,iBAAiB,IAAI,wBAAwB,CAAC,CAAC;IACzE,YAAY,OAAO,YAAY,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,CAAC;IAChE,QAAQ,CAAC;IACT,KAAK;IACL,IAAI,SAAS,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE;IAC/D,QAAQ,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;IAC/B,QAAQ,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;IACzC,YAAY,KAAK,CAAC,iBAAiB,IAAI,wBAAwB,EAAE;IACjE,YAAY,KAAK,CAAC,SAAS,GAAG,aAAa,EAAE;IAC7C,QAAQ;IACR,QAAQ,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE;IAC3C,YAAY,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC;IACtE,QAAQ;IACR,IAAI;IACJ;IACA,SAAS,YAAY,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE;IACvD,IAAI,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK;IAClE,QAAQ,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC;IACnE,QAAQ,OAAO,SAAS,KAAK;IAC7B,cAAc;IACd,cAAc,CAAC,EAAE,cAAc,EAAE,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE,CAAC;IACvE,IAAI,CAAC,CAAC;IACN,IAAI,OAAO;IACX,QAAQ,gBAAgB,EAAE,MAAM,CAAC,MAAM;IACvC,QAAQ,WAAW,EAAE,mBAAmB;IACxC,QAAQ,mBAAmB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,SAAS,KAAK,SAAS;IACnF,aAAa,MAAM;IACnB,KAAK;IACL;;IAEA,MAAM,WAAW,CAAC;IAClB,IAAI,MAAM;IACV,IAAI,GAAG,GAAG,CAAC;IACX,IAAI,eAAe;IACnB,IAAI,SAAS;IACb,IAAI,4BAA4B,GAAG,CAAC;IACpC,IAAI,eAAe,GAAG,CAAC;IACvB,IAAI,QAAQ;IACZ,IAAI,WAAW;IACf,IAAI,QAAQ,GAAG,IAAI;IACnB,IAAI,YAAY,GAAG,IAAI,GAAG,EAAE;IAC5B,IAAI,SAAS;IACb,IAAI,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;IACjC,QAAQ,IAAI,CAAC,MAAM,GAAG,MAAM;IAC5B,QAAQ,IAAI,CAAC,eAAe,GAAG,OAAO;IACtC,QAAQ,IAAI,CAAC,SAAS,GAAG,IAAI,uBAAuB,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;IAC5E,QAAQ,IAAI,CAAC,cAAc,EAAE;IAC7B,IAAI;IACJ,IAAI,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE;IAClC,QAAQ,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,EAAE;IACvD,YAAY,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;IACxD,YAAY,IAAI,CAAC,QAAQ,GAAG,KAAK;IACjC,QAAQ;IACR,QAAQ,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC;IACpD,QAAQ,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,EAAE;IACtC,YAAY,IAAI,CAAC,4BAA4B,GAAG,CAAC;IACjD,QAAQ;IACR,QAAQ,IAAI,CAAC,eAAe,IAAI,CAAC;IACjC,QAAQ,IAAI,CAAC,GAAG,IAAI,CAAC;IACrB,IAAI;IACJ,IAAI,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE;IAC5C,QAAQ,MAAM,QAAQ,GAAG,IAAI,CAAC,sBAAsB,EAAE;IACtD,QAAQ,IAAI,QAAQ,EAAE;IACtB,YAAY,IAAI,CAAC,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC;IAChE,QAAQ;IACR,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE;IAChD,YAAY,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;IAC1D,QAAQ;IACR,QAAQ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7C,QAAQ,IAAI,CAAC,QAAQ,GAAG,IAAI;IAC5B,QAAQ,IAAI,CAAC,eAAe,GAAG,CAAC;IAChC,QAAQ,IAAI,CAAC,4BAA4B,IAAI,CAAC;IAC9C,QAAQ,IAAI,CAAC,eAAe,GAAG,SAAS;IACxC,QAAQ,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC;IAClD,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM;IAC7C,QAAQ,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE;IACpD,YAAY,IAAI,GAAG,GAAG,MAAM;IAC5B,gBAAgB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC;IAC7C,QAAQ;IACR,IAAI;IACJ,IAAI,OAAO,GAAG;IACd,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;IACvC,IAAI;IACJ,IAAI,sBAAsB,GAAG;IAC7B,QAAQ,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC;IACxC,YAAY,OAAO,SAAS;IAC5B,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE;IAC7D,YAAY,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK;IAC7C,YAAY,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC;IACvE,YAAY,IAAI,WAAW;IAC3B,gBAAgB,OAAO,WAAW;IAClC,QAAQ;IACR,QAAQ,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;IAC/D,QAAQ,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC;IAC/C,IAAI;IACJ,IAAI,cAAc,GAAG;IACrB,QAAQ,MAAM,gBAAgB,GAAG,QAAQ,CAAC,CAAC,CAAC;IAC5C,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;IACnD,YAAY,gBAAgB,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE;IAChD,QAAQ;IACR,QAAQ,MAAM,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACvD,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;IACnD,YAAY,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI;IAC5C,QAAQ;IACR,QAAQ,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC;IACxC,QAAQ,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;IAClC,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;IACnD,YAAY,YAAY,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI;IAC9C,QAAQ;IACR,QAAQ,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;IACtC,YAAY,UAAU;IACtB,YAAY,gBAAgB;IAC5B,YAAY,YAAY;IACxB,SAAS,CAAC;IACV,IAAI;IACJ,IAAI,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE;IAC9C,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,KAAK,CAAC;IAC3D,YAAY;IACZ,QAAQ,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC;IAChD,QAAQ,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe;IAC5C,QAAQ,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC;IAC5E,QAAQ,MAAM,GAAG,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC;IAC/D,QAAQ,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzD,QAAQ,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/E,QAAQ,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACnD,QAAQ,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACvE,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE;IACzD,YAAY,MAAM,QAAQ,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,OAAO;IAClD,YAAY,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/D,YAAY,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/D,YAAY,MAAM,KAAK,GAAG,UAAU,GAAG,QAAQ,IAAI,QAAQ,GAAG,UAAU,CAAC;IACzE,YAAY,MAAM,MAAM,GAAG,WAAW,GAAG,QAAQ,IAAI,SAAS,GAAG,WAAW,CAAC;IAC7E,YAAY,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC;IACpF,YAAY,IAAI,KAAK,GAAG,OAAO,GAAG,CAAC,EAAE;IACrC,gBAAgB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC;IAC5D,YAAY;IACZ,QAAQ;IACR,QAAQ,IAAI,CAAC,WAAW,GAAG,SAAS;IACpC,IAAI;IACJ;IACA;IACA,SAAS,qBAAqB,CAAC,OAAO,GAAG,EAAE,EAAE;IAC7C,IAAI,MAAM,eAAe,GAAG,6BAA6B,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,EAAE,iBAAiB,CAAC;IAC3G,IAAI,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE;IAC7C,IAAI,MAAM,wBAAwB,GAAG,0BAA0B,CAAC,OAAO,CAAC,wBAAwB,IAAI,CAAC,EAAE,0BAA0B,CAAC;IAClI,IAAI,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,IAAI,GAAG;IAClE,IAAI,MAAM,0BAA0B,GAAG,OAAO,CAAC,0BAA0B,IAAI,GAAG;IAChF,IAAI,MAAM,gCAAgC,GAAG,OAAO,CAAC,gCAAgC,IAAI,GAAG;IAC5F,IAAI,MAAM,MAAM,GAAG,0BAA0B,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,QAAQ,CAAC;IAC5E,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE;IACvD,QAAQ,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC;IACrE,IAAI;IACJ,IAAI,uBAAuB,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;IACvE,IAAI,uBAAuB,CAAC,0BAA0B,EAAE,4BAA4B,CAAC;IACrF,IAAI,uBAAuB,CAAC,gCAAgC,EAAE,kCAAkC,CAAC;IACjG,IAAI,MAAM,qBAAqB,GAAG,CAAC,SAAS,GAAG,EAAE,IAAI,eAAe;IACpE,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE;IACjD,QAAQ,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC;IAC7G,IAAI;IACJ,IAAI,MAAM,0BAA0B,GAAG,eAAe,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAChH,IAAI,IAAI,MAAM,GAAG,EAAE;IACnB,IAAI,IAAI,UAAU,GAAG,CAAC;IACtB,IAAI,IAAI,aAAa,GAAG,CAAC;IACzB,IAAI,IAAI,kBAAkB;IAC1B,IAAI,OAAO;IACX,QAAQ,KAAK,GAAG;IAChB,YAAY,MAAM,GAAG,EAAE;IACvB,YAAY,UAAU,GAAG,CAAC;IAC1B,YAAY,aAAa,GAAG,CAAC;IAC7B,YAAY,kBAAkB,GAAG,SAAS;IAC1C,QAAQ,CAAC;IACT,QAAQ,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE;IACvC,YAAY,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,CAAC;IAC9E,YAAY,kBAAkB,GAAG,UAAU,IAAI,kBAAkB;IACjE;IACA;IACA,YAAY,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;IAChE,gBAAgB,OAAO;IACvB,oBAAoB,gBAAgB,EAAE,CAAC;IACvC,oBAAoB,WAAW,EAAE,EAAE;IACnC,oBAAoB,mBAAmB,EAAE,CAAC;IAC1C,iBAAiB;IACjB,YAAY;IACZ,YAAY,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC1E,YAAY,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,KAAK,SAAS,CAAC,UAAU,KAAK,SAAS;IACpH,gBAAgB,SAAS,CAAC,UAAU,IAAI;IACxC,kBAAkB,CAAC,KAAK;IACxB,kBAAkB,EAAE,CAAC;IACrB,YAAY,MAAM,cAAc,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC,CAAC;IACzF,YAAY,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;IACpI,YAAY,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,UAAU,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,cAAc,KAAK;IACvG,gBAAgB,IAAI,0BAA0B,KAAK,CAAC;IACpD,oBAAoB,OAAO,GAAG;IAC9B,gBAAgB,QAAQ,GAAG;IAC3B,oBAAoB,0BAA0B;IAC9C,wBAAwB,oBAAoB,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC,cAAc,CAAC,CAAC;IAChG,yBAAyB,cAAc,CAAC,cAAc,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;IACxE,YAAY,CAAC,CAAC,CAAC;IACf,YAAY,MAAM,OAAO,GAAG,uBAAuB,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,mBAAmB,EAAE,SAAS,CAAC;IACzI,YAAY,MAAM,WAAW,GAAG,IAAI,GAAG,EAAE;IACzC,YAAY,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE;IACjD,gBAAgB,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC;IAC1H,YAAY;IACZ,YAAY,IAAI,aAAa,GAAG,CAAC,GAAG,OAAO,CAAC,yBAAyB,CAAC;IACtE,YAAY,IAAI,OAAO,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC;IACxD,gBAAgB,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;IAC1C,gBAAgB,MAAM,eAAe,GAAG,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;IACnG,gBAAgB,MAAM,mBAAmB,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC,KAAK,CAAC,CAAC;IAC/F,gBAAgB,MAAM,cAAc,GAAG,WAAW,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;IACtK,gBAAgB,MAAM,QAAQ,GAAG,uBAAuB,CAAC,cAAc,EAAE,eAAe,CAAC,MAAM,EAAE,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACjJ,gBAAgB,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE;IACtD,oBAAoB,kBAAkB,CAAC,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,mBAAmB,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC;IAC5I,gBAAgB;IAChB,gBAAgB,aAAa,GAAG,QAAQ,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,aAAa,CAAC,KAAK,CAAC,CAAC;IACvG,YAAY;IACZ,YAAY,KAAK,MAAM,UAAU,IAAI,aAAa,EAAE;IACpD,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC;IAChF,YAAY;IACZ,YAAY,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,eAAe,IAAI,0BAA0B,CAAC;IAClG,YAAY,UAAU,IAAI,CAAC;IAC3B,YAAY,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK;IAC1E,gBAAgB,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC;IAC3E,gBAAgB,OAAO,SAAS,KAAK;IACrC,sBAAsB;IACtB,sBAAsB,CAAC,EAAE,cAAc,EAAE,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE,CAAC;IAC/E,YAAY,CAAC,CAAC;IACd,YAAY,OAAO;IACnB,gBAAgB,gBAAgB,EAAE,MAAM,CAAC,MAAM;IAC/C,gBAAgB,WAAW,EAAE,mBAAmB;IAChD,gBAAgB,mBAAmB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,MAAM;IACnG,aAAa;IACb,QAAQ,CAAC;IACT,KAAK;IACL,IAAI,SAAS,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE;IAC1E,QAAQ,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;IACrD,QAAQ,MAAM,aAAa,GAAG,UAAU,IAAI,wBAAwB;IACpE,QAAQ,MAAM,UAAU,GAAG,CAAC,aAAa,IAAI,KAAK,CAAC,eAAe,KAAK,CAAC;IACxE,YAAY,KAAK,CAAC,4BAA4B,IAAI,wBAAwB;IAC1E,QAAQ,IAAI,UAAU,EAAE;IACxB,YAAY,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE;IAC/C,gBAAgB,KAAK,CAAC,SAAS,GAAG,aAAa,EAAE;IACjD,YAAY;IACZ,YAAY,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC;IACtE,QAAQ;IACR,IAAI;IACJ;IACA,SAAS,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE;IAC5C,IAAI,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI;IACpE,IAAI,OAAO,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE;IACjD;IACA,SAAS,oBAAoB,CAAC,KAAK,EAAE,SAAS,EAAE;IAChD,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ;IACvB,QAAQ,OAAO,CAAC;IAChB,IAAI,MAAM,SAAS,GAAG,KAAK,CAAC,sBAAsB,EAAE,IAAI,KAAK,CAAC,eAAe;IAC7E,IAAI,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI;IACpE,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IACrH,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IACnC,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,EAAE;IACpD;;IAEA;IACA,SAAS,iBAAiB,CAAC,OAAO,GAAG,EAAE,EAAE;IACzC,IAAI,OAAO,mBAAmB,CAAC,OAAO,CAAC;IACvC;;IAEA;IACA,SAAS,sBAAsB,CAAC,OAAO,GAAG,EAAE,EAAE;IAC9C,IAAI,OAAO,wBAAwB,CAAC,OAAO,CAAC;IAC5C;;IAEA;IACA,SAAS,kBAAkB,CAAC,OAAO,GAAG,EAAE,EAAE;IAC1C,IAAI,OAAO,oBAAoB,CAAC,OAAO,CAAC;IACxC;;IAEA;IACA,SAAS,mBAAmB,CAAC,OAAO,GAAG,EAAE,EAAE;IAC3C,IAAI,OAAO,qBAAqB,CAAC,OAAO,CAAC;IACzC;;IAEA;IACA,IAAI,gBAAgB;IACpB,CAAC,UAAU,gBAAgB,EAAE;IAC7B,IAAI,gBAAgB,CAAC,KAAK,CAAC,GAAG,KAAK;IACnC,IAAI,gBAAgB,CAAC,MAAM,CAAC,GAAG,MAAM;IACrC,IAAI,gBAAgB,CAAC,WAAW,CAAC,GAAG,WAAW;IAC/C,CAAC,EAAE,gBAAgB,KAAK,gBAAgB,GAAG,EAAE,CAAC,CAAC;;IAE/C,IAAI,0BAA0B;IAC9B,CAAC,UAAU,0BAA0B,EAAE;IACvC,IAAI,0BAA0B,CAAC,YAAY,CAAC,GAAG,YAAY;IAC3D,IAAI,0BAA0B,CAAC,gBAAgB,CAAC,GAAG,gBAAgB;IACnE,CAAC,EAAE,0BAA0B,KAAK,0BAA0B,GAAG,EAAE,CAAC,CAAC;;IA4gBnE,IAAI,mBAAmB;IACvB,CAAC,UAAU,mBAAmB,EAAE;IAChC,IAAI,mBAAmB,CAAC,KAAK,CAAC,GAAG,KAAK;IACtC,IAAI,mBAAmB,CAAC,MAAM,CAAC,GAAG,MAAM;IACxC,IAAI,mBAAmB,CAAC,UAAU,CAAC,GAAG,UAAU;IAChD,IAAI,mBAAmB,CAAC,OAAO,CAAC,GAAG,OAAO;IAC1C,IAAI,mBAAmB,CAAC,MAAM,CAAC,GAAG,MAAM;IACxC,IAAI,mBAAmB,CAAC,SAAS,CAAC,GAAG,SAAS;IAC9C,IAAI,mBAAmB,CAAC,UAAU,CAAC,GAAG,UAAU;IAChD,CAAC,EAAE,mBAAmB,KAAK,mBAAmB,GAAG,EAAE,CAAC,CAAC;IACrD,IAAI,oBAAoB;IACxB,CAAC,UAAU,oBAAoB,EAAE;IACjC,IAAI,oBAAoB,CAAC,QAAQ,CAAC,GAAG,QAAQ;IAC7C,IAAI,oBAAoB,CAAC,UAAU,CAAC,GAAG,UAAU;IACjD,IAAI,oBAAoB,CAAC,YAAY,CAAC,GAAG,YAAY;IACrD,CAAC,EAAE,oBAAoB,KAAK,oBAAoB,GAAG,EAAE,CAAC,CAAC;;IAoYvD,IAAI,sBAAsB;IAC1B,CAAC,UAAU,sBAAsB,EAAE;IACnC,IAAI,sBAAsB,CAAC,KAAK,CAAC,GAAG,KAAK;IACzC,IAAI,sBAAsB,CAAC,SAAS,CAAC,GAAG,SAAS;IACjD,IAAI,sBAAsB,CAAC,UAAU,CAAC,GAAG,UAAU;IACnD,IAAI,sBAAsB,CAAC,WAAW,CAAC,GAAG,WAAW;IACrD,IAAI,sBAAsB,CAAC,MAAM,CAAC,GAAG,MAAM;IAC3C,CAAC,EAAE,sBAAsB,KAAK,sBAAsB,GAAG,EAAE,CAAC,CAAC;IAC3D,IAAI,0BAA0B;IAC9B,CAAC,UAAU,0BAA0B,EAAE;IACvC,IAAI,0BAA0B,CAAC,MAAM,CAAC,GAAG,MAAM;IAC/C,IAAI,0BAA0B,CAAC,UAAU,CAAC,GAAG,UAAU;IACvD,IAAI,0BAA0B,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACnD,IAAI,0BAA0B,CAAC,UAAU,CAAC,GAAG,UAAU;IACvD,IAAI,0BAA0B,CAAC,eAAe,CAAC,GAAG,eAAe;IACjE,CAAC,EAAE,0BAA0B,KAAK,0BAA0B,GAAG,EAAE,CAAC,CAAC;IACnE,IAAI,oBAAoB;IACxB,CAAC,UAAU,oBAAoB,EAAE;IACjC,IAAI,oBAAoB,CAAC,QAAQ,CAAC,GAAG,QAAQ;IAC7C,IAAI,oBAAoB,CAAC,QAAQ,CAAC,GAAG,QAAQ;IAC7C,IAAI,oBAAoB,CAAC,WAAW,CAAC,GAAG,WAAW;IACnD,IAAI,oBAAoB,CAAC,UAAU,CAAC,GAAG,UAAU;IACjD,CAAC,EAAE,oBAAoB,KAAK,oBAAoB,GAAG,EAAE,CAAC,CAAC;;IAmjBvD;IACA,IAAI,eAAe;IACnB,CAAC,UAAU,eAAe,EAAE;IAC5B,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACxC,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACxC,IAAI,eAAe,CAAC,SAAS,CAAC,GAAG,SAAS;IAC1C,CAAC,EAAE,eAAe,KAAK,eAAe,GAAG,EAAE,CAAC,CAAC;;IAE7C,IAAI,QAAQ;IACZ,CAAC,UAAU,QAAQ,EAAE;IACrB,IAAI,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM;IAC7B,IAAI,QAAQ,CAAC,aAAa,CAAC,GAAG,aAAa;IAC3C,CAAC,EAAE,QAAQ,KAAK,QAAQ,GAAG,EAAE,CAAC,CAAC;;IAsJ/B,IAAI,eAAe;IACnB,CAAC,UAAU,eAAe,EAAE;IAC5B,IAAI,eAAe,CAAC,SAAS,CAAC,GAAG,SAAS;IAC1C,IAAI,eAAe,CAAC,UAAU,CAAC,GAAG,UAAU;IAC5C,IAAI,eAAe,CAAC,oBAAoB,CAAC,GAAG,oBAAoB;IAChE,IAAI,eAAe,CAAC,SAAS,CAAC,GAAG,SAAS;IAC1C,CAAC,EAAE,eAAe,KAAK,eAAe,GAAG,EAAE,CAAC,CAAC;;IAkH7C,IAAI,yBAAyB;IAC7B,CAAC,UAAU,yBAAyB,EAAE;IACtC,IAAI,yBAAyB,CAAC,SAAS,CAAC,GAAG,SAAS;IACpD,IAAI,yBAAyB,CAAC,UAAU,CAAC,GAAG,UAAU;IACtD,CAAC,EAAE,yBAAyB,KAAK,yBAAyB,GAAG,EAAE,CAAC,CAAC;;IAsHjE,IAAI,cAAc;IAClB,CAAC,UAAU,cAAc,EAAE;IAC3B,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,KAAK;IACjC,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACvC,IAAI,cAAc,CAAC,WAAW,CAAC,GAAG,WAAW;IAC7C,IAAI,cAAc,CAAC,cAAc,CAAC,GAAG,cAAc;IACnD,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACvC,CAAC,EAAE,cAAc,KAAK,cAAc,GAAG,EAAE,CAAC,CAAC;IAC3C,IAAI,mBAAmB;IACvB,CAAC,UAAU,mBAAmB,EAAE;IAChC,IAAI,mBAAmB,CAAC,QAAQ,CAAC,GAAG,QAAQ;IAC5C,IAAI,mBAAmB,CAAC,aAAa,CAAC,GAAG,aAAa;IACtD,CAAC,EAAE,mBAAmB,KAAK,mBAAmB,GAAG,EAAE,CAAC,CAAC;;IA+GrD,IAAI,cAAc;IAClB,CAAC,UAAU,cAAc,EAAE;IAC3B,IAAI,cAAc,CAAC,eAAe,CAAC,GAAG,eAAe;IACrD,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,UAAU;IAC3C,IAAI,cAAc,CAAC,YAAY,CAAC,GAAG,YAAY;IAC/C,CAAC,EAAE,cAAc,KAAK,cAAc,GAAG,EAAE,CAAC,CAAC;;IAoF3C;IACA;IACA;IACA,IAAI,oBAAoB;IACxB,CAAC,UAAU,oBAAoB,EAAE;IACjC,IAAI,oBAAoB,CAAC,SAAS,CAAC,GAAG,SAAS;IAC/C,IAAI,oBAAoB,CAAC,QAAQ,CAAC,GAAG,QAAQ;IAC7C,IAAI,oBAAoB,CAAC,MAAM,CAAC,GAAG,MAAM;IACzC,CAAC,EAAE,oBAAoB,KAAK,oBAAoB,GAAG,EAAE,CAAC,CAAC;IACvD,IAAI,WAAW;IACf,CAAC,UAAU,WAAW,EAAE;IACxB,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACpC,IAAI,WAAW,CAAC,OAAO,CAAC,GAAG,OAAO;IAClC,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACpC,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,UAAU;IACxC,CAAC,EAAE,WAAW,KAAK,WAAW,GAAG,EAAE,CAAC,CAAC;IACrC;IACA;IACA;IACA;IACA,IAAI,eAAe;IACnB,CAAC,UAAU,eAAe,EAAE;IAC5B,IAAI,eAAe,CAAC,OAAO,CAAC,GAAG,OAAO;IACtC,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACxC,CAAC,EAAE,eAAe,KAAK,eAAe,GAAG,EAAE,CAAC,CAAC;;IAqJ7C,IAAI,mBAAmB;IACvB,CAAC,UAAU,mBAAmB,EAAE;IAChC,IAAI,mBAAmB,CAAC,QAAQ,CAAC,GAAG,QAAQ;IAC5C,IAAI,mBAAmB,CAAC,OAAO,CAAC,GAAG,OAAO;IAC1C,CAAC,EAAE,mBAAmB,KAAK,mBAAmB,GAAG,EAAE,CAAC,CAAC;;IA2qCrD,IAAI,gBAAgB;IACpB,CAAC,UAAU,gBAAgB,EAAE;IAC7B;IACA;IACA;IACA,IAAI,gBAAgB,CAAC,SAAS,CAAC,GAAG,SAAS;IAC3C;IACA;IACA;IACA,IAAI,gBAAgB,CAAC,OAAO,CAAC,GAAG,OAAO;IACvC,CAAC,EAAE,gBAAgB,KAAK,gBAAgB,GAAG,EAAE,CAAC,CAAC;IAC/C;IACA;IACA;IACA,IAAI,0BAA0B;IAC9B,CAAC,UAAU,0BAA0B,EAAE;IACvC,IAAI,0BAA0B,CAAC,SAAS,CAAC,GAAG,SAAS;IACrD,IAAI,0BAA0B,CAAC,OAAO,CAAC,GAAG,OAAO;IACjD,IAAI,0BAA0B,CAAC,SAAS,CAAC,GAAG,SAAS;IACrD,IAAI,0BAA0B,CAAC,WAAW,CAAC,GAAG,WAAW;IACzD,IAAI,0BAA0B,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACnD,IAAI,0BAA0B,CAAC,OAAO,CAAC,GAAG,OAAO;IACjD,IAAI,0BAA0B,CAAC,WAAW,CAAC,GAAG,WAAW;IACzD,CAAC,EAAE,0BAA0B,KAAK,0BAA0B,GAAG,EAAE,CAAC,CAAC;IACnE;IACA;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,cAAc;IAClB,CAAC,UAAU,cAAc,EAAE;IAC3B;IACA,IAAI,cAAc,CAAC,YAAY,CAAC,GAAG,YAAY;IAC/C;IACA,IAAI,cAAc,CAAC,mBAAmB,CAAC,GAAG,mBAAmB;IAC7D;IACA,IAAI,cAAc,CAAC,cAAc,CAAC,GAAG,cAAc;IACnD;IACA,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACvC;IACA,IAAI,cAAc,CAAC,SAAS,CAAC,GAAG,SAAS;IACzC;IACA,IAAI,cAAc,CAAC,wBAAwB,CAAC,GAAG,wBAAwB;IACvE;IACA,IAAI,cAAc,CAAC,SAAS,CAAC,GAAG,SAAS;IACzC,CAAC,EAAE,cAAc,KAAK,cAAc,GAAG,EAAE,CAAC,CAAC;IAC3C;IACA;IACA;IACA,IAAI,iBAAiB;IACrB,CAAC,UAAU,iBAAiB,EAAE;IAC9B,IAAI,iBAAiB,CAAC,SAAS,CAAC,GAAG,SAAS;IAC5C,IAAI,iBAAiB,CAAC,OAAO,CAAC,GAAG,OAAO;IACxC,IAAI,iBAAiB,CAAC,OAAO,CAAC,GAAG,OAAO;IACxC,IAAI,iBAAiB,CAAC,WAAW,CAAC,GAAG,WAAW;IAChD,CAAC,EAAE,iBAAiB,KAAK,iBAAiB,GAAG,EAAE,CAAC,CAAC;;IAEjD;IACA;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,gBAAgB;IACpB,CAAC,UAAU,gBAAgB,EAAE;IAC7B;IACA;IACA;IACA;IACA,IAAI,gBAAgB,CAAC,MAAM,CAAC,GAAG,MAAM;IACrC;IACA;IACA;IACA;IACA,IAAI,gBAAgB,CAAC,QAAQ,CAAC,GAAG,QAAQ;IACzC,CAAC,EAAE,gBAAgB,KAAK,gBAAgB,GAAG,EAAE,CAAC,CAAC;IAC/C;IACA;IACA;IACA,IAAI,kBAAkB;IACtB,CAAC,UAAU,kBAAkB,EAAE;IAC/B,IAAI,kBAAkB,CAAC,WAAW,CAAC,GAAG,WAAW;IACjD,IAAI,kBAAkB,CAAC,WAAW,CAAC,GAAG,WAAW;IACjD,IAAI,kBAAkB,CAAC,OAAO,CAAC,GAAG,OAAO;IACzC,IAAI,kBAAkB,CAAC,SAAS,CAAC,GAAG,SAAS;IAC7C,IAAI,kBAAkB,CAAC,QAAQ,CAAC,GAAG,QAAQ;IAC3C,IAAI,kBAAkB,CAAC,SAAS,CAAC,GAAG,SAAS;IAC7C,IAAI,kBAAkB,CAAC,YAAY,CAAC,GAAG,YAAY;IACnD,IAAI,kBAAkB,CAAC,OAAO,CAAC,GAAG,OAAO;IACzC,CAAC,EAAE,kBAAkB,KAAK,kBAAkB,GAAG,EAAE,CAAC,CAAC;IACnD;IACA;IACA;IACA,IAAI,wBAAwB;IAC5B,CAAC,UAAU,wBAAwB,EAAE;IACrC,IAAI,wBAAwB,CAAC,qBAAqB,CAAC,GAAG,qBAAqB;IAC3E,IAAI,wBAAwB,CAAC,mBAAmB,CAAC,GAAG,mBAAmB;IACvE,IAAI,wBAAwB,CAAC,OAAO,CAAC,GAAG,OAAO;IAC/C,IAAI,wBAAwB,CAAC,kBAAkB,CAAC,GAAG,kBAAkB;IACrE,IAAI,wBAAwB,CAAC,cAAc,CAAC,GAAG,cAAc;IAC7D,IAAI,wBAAwB,CAAC,mBAAmB,CAAC,GAAG,mBAAmB;IACvE,IAAI,wBAAwB,CAAC,iBAAiB,CAAC,GAAG,iBAAiB;IACnE,CAAC,EAAE,wBAAwB,KAAK,wBAAwB,GAAG,EAAE,CAAC,CAAC;IAC/D;IACA;IACA;IACA,IAAI,0BAA0B;IAC9B,CAAC,UAAU,0BAA0B,EAAE;IACvC,IAAI,0BAA0B,CAAC,OAAO,CAAC,GAAG,OAAO;IACjD,IAAI,0BAA0B,CAAC,SAAS,CAAC,GAAG,SAAS;IACrD,IAAI,0BAA0B,CAAC,SAAS,CAAC,GAAG,SAAS;IACrD,CAAC,EAAE,0BAA0B,KAAK,0BAA0B,GAAG,EAAE,CAAC,CAAC;;ICh2NnE,IAAI,OAAoC;IAExC,IAAI,CAAC,gBAAgB,CACnB,SAAS,EACT,CAAC,KAA0C,KAAI;IAC7C,IAAA,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI;IAE1B,IAAA,IAAI;IACF,QAAA,IAAI,QAAgC;IAEpC,QAAA,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE;IAChC,YAAA,QAAQ,OAAO,CAAC,SAAS,CAAC,SAAS;IACjC,gBAAA,KAAK,WAAW;wBACd,OAAO,GAAG,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;wBAC3D;IACF,gBAAA,KAAK,OAAO;wBACV,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;wBACvD;IACF,gBAAA,KAAK,QAAQ;wBACX,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;wBACxD;IACF,gBAAA;wBACE,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;;IAE1D,YAAA,QAAQ,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;YAC9D;IAAO,aAAA,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE;gBACnC,OAAO,EAAE,KAAK,EAAE;IAChB,YAAA,QAAQ,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;YAC9D;iBAAO;gBACL,IAAI,CAAC,OAAO,EAAE;IACZ,gBAAA,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC;gBACvD;IACA,YAAA,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;IACnC,YAAA,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC;IACrE,YAAA,QAAQ,GAAG;IACT,gBAAA,GAAG,MAAM;IACT,gBAAA,UAAU,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS;oBACzC,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,gBAAA,IAAI,EAAE,SAAS;iBAChB;YACH;IAEA,QAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;QAC5B;QAAE,OAAO,KAAK,EAAE;YACd,IAAI,CAAC,WAAW,CAAC;IACf,YAAA,OAAO,EACL,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,yBAAyB;gBACpE,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,YAAA,IAAI,EAAE,OAAO;IACmB,SAAA,CAAC;QACrC;IACF,CAAC,CACF;;;;;;"}