"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from3, except, desc) => { if (from3 && typeof from3 === "object" || typeof from3 === "function") { for (let key of __getOwnPropNames(from3)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from3[key], enumerable: !(desc = __getOwnPropDesc(from3, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __decorateClass = (decorators, target, key, kind) => { var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result; if (kind && result) __defProp(target, key, result); return result; }; // packages/ag-charts-core/src/main.ts var main_exports = {}; __export(main_exports, { AGGREGATION_INDEX_UNSET: () => AGGREGATION_INDEX_UNSET, AGGREGATION_INDEX_X_MAX: () => AGGREGATION_INDEX_X_MAX, AGGREGATION_INDEX_X_MIN: () => AGGREGATION_INDEX_X_MIN, AGGREGATION_INDEX_Y_MAX: () => AGGREGATION_INDEX_Y_MAX, AGGREGATION_INDEX_Y_MIN: () => AGGREGATION_INDEX_Y_MIN, AGGREGATION_MAX_POINTS: () => AGGREGATION_MAX_POINTS, AGGREGATION_MIN_RANGE: () => AGGREGATION_MIN_RANGE, AGGREGATION_SPAN: () => AGGREGATION_SPAN, AGGREGATION_THRESHOLD: () => AGGREGATION_THRESHOLD, AbstractModuleInstance: () => AbstractModuleInstance, ActionOnSet: () => ActionOnSet, AdjacencyListGraph: () => AdjacencyListGraph, AsyncAwaitQueue: () => AsyncAwaitQueue, BASE_FONT_SIZE: () => BASE_FONT_SIZE, BREAK_TRANSFORM_CHAIN: () => BREAK_TRANSFORM_CHAIN, BaseProperties: () => BaseProperties, Border: () => Border, CANVAS_HEIGHT: () => CANVAS_HEIGHT, CANVAS_TO_BUFFER_DEFAULTS: () => CANVAS_TO_BUFFER_DEFAULTS, CANVAS_WIDTH: () => CANVAS_WIDTH, CARTESIAN_AXIS_TYPE: () => CARTESIAN_AXIS_TYPE, CARTESIAN_POSITION: () => CARTESIAN_POSITION, CallbackCache: () => CallbackCache, ChangeDetectableProperties: () => ChangeDetectableProperties, ChartAxisDirection: () => ChartAxisDirection, ChartUpdateType: () => ChartUpdateType, CleanupRegistry: () => CleanupRegistry, Color: () => Color, ConfiguredCanvasMixin: () => ConfiguredCanvasMixin, DEFAULT_ANNOTATION_HANDLE_FILL: () => DEFAULT_ANNOTATION_HANDLE_FILL, DEFAULT_ANNOTATION_STATISTICS_COLOR: () => DEFAULT_ANNOTATION_STATISTICS_COLOR, DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE, DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL: () => DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE, DEFAULT_ANNOTATION_STATISTICS_FILL: () => DEFAULT_ANNOTATION_STATISTICS_FILL, DEFAULT_ANNOTATION_STATISTICS_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_STROKE, DEFAULT_CAPTION_ALIGNMENT: () => DEFAULT_CAPTION_ALIGNMENT, DEFAULT_CAPTION_LAYOUT_STYLE: () => DEFAULT_CAPTION_LAYOUT_STYLE, DEFAULT_FIBONACCI_STROKES: () => DEFAULT_FIBONACCI_STROKES, DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL: () => DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR: () => DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, DEFAULT_POLAR_SERIES_STROKE: () => DEFAULT_POLAR_SERIES_STROKE, DEFAULT_SHADOW_COLOUR: () => DEFAULT_SHADOW_COLOUR, DEFAULT_SPARKLINE_CROSSHAIR_STROKE: () => DEFAULT_SPARKLINE_CROSSHAIR_STROKE, DEFAULT_TEXTBOX_COLOR: () => DEFAULT_TEXTBOX_COLOR, DEFAULT_TEXTBOX_FILL: () => DEFAULT_TEXTBOX_FILL, DEFAULT_TEXTBOX_STROKE: () => DEFAULT_TEXTBOX_STROKE, DEFAULT_TEXT_ANNOTATION_COLOR: () => DEFAULT_TEXT_ANNOTATION_COLOR, DEFAULT_TOOLBAR_POSITION: () => DEFAULT_TOOLBAR_POSITION, DIRECTION_SWAP_AXES: () => DIRECTION_SWAP_AXES, Debug: () => debugLogger_exports, DebugMetrics: () => debugMetrics_exports, DeclaredSceneChangeDetection: () => DeclaredSceneChangeDetection, DeclaredSceneObjectChangeDetection: () => DeclaredSceneObjectChangeDetection, Deprecated: () => Deprecated, DeprecatedAndRenamedTo: () => DeprecatedAndRenamedTo, EllipsisChar: () => EllipsisChar, ErrorType: () => ErrorType, EventEmitter: () => EventEmitter, FILL_GRADIENT_BLANK_DEFAULTS: () => FILL_GRADIENT_BLANK_DEFAULTS, FILL_GRADIENT_CONIC_SERIES_DEFAULTS: () => FILL_GRADIENT_CONIC_SERIES_DEFAULTS, FILL_GRADIENT_LINEAR_DEFAULTS: () => FILL_GRADIENT_LINEAR_DEFAULTS, FILL_GRADIENT_LINEAR_HIERARCHY_DEFAULTS: () => FILL_GRADIENT_LINEAR_HIERARCHY_DEFAULTS, FILL_GRADIENT_LINEAR_KEYED_DEFAULTS: () => FILL_GRADIENT_LINEAR_KEYED_DEFAULTS, FILL_GRADIENT_LINEAR_SINGLE_DEFAULTS: () => FILL_GRADIENT_LINEAR_SINGLE_DEFAULTS, FILL_GRADIENT_RADIAL_DEFAULTS: () => FILL_GRADIENT_RADIAL_DEFAULTS, FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS: () => FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS, FILL_GRADIENT_RADIAL_REVERSED_SERIES_DEFAULTS: () => FILL_GRADIENT_RADIAL_REVERSED_SERIES_DEFAULTS, FILL_GRADIENT_RADIAL_SERIES_DEFAULTS: () => FILL_GRADIENT_RADIAL_SERIES_DEFAULTS, FILL_IMAGE_BLANK_DEFAULTS: () => FILL_IMAGE_BLANK_DEFAULTS, FILL_IMAGE_DEFAULTS: () => FILL_IMAGE_DEFAULTS, FILL_PATTERN_BLANK_DEFAULTS: () => FILL_PATTERN_BLANK_DEFAULTS, FILL_PATTERN_DEFAULTS: () => FILL_PATTERN_DEFAULTS, FILL_PATTERN_HIERARCHY_DEFAULTS: () => FILL_PATTERN_HIERARCHY_DEFAULTS, FILL_PATTERN_KEYED_DEFAULTS: () => FILL_PATTERN_KEYED_DEFAULTS, FILL_PATTERN_SINGLE_DEFAULTS: () => FILL_PATTERN_SINGLE_DEFAULTS, FONT_SIZE: () => FONT_SIZE, FONT_SIZE_RATIO: () => FONT_SIZE_RATIO, IS_DARK_THEME: () => IS_DARK_THEME, InterpolationProperties: () => InterpolationProperties, LABEL_BOXING_DEFAULTS: () => LABEL_BOXING_DEFAULTS, LEGEND_CONTAINER_THEME: () => LEGEND_CONTAINER_THEME, LRUCache: () => LRUCache, LineSplitter: () => LineSplitter, Logger: () => logger_exports, MARKER_SERIES_HIGHLIGHT_STYLE: () => MARKER_SERIES_HIGHLIGHT_STYLE, MULTI_SERIES_HIGHLIGHT_STYLE: () => MULTI_SERIES_HIGHLIGHT_STYLE, MementoCaretaker: () => MementoCaretaker, ModuleRegistry: () => moduleRegistry_exports, ModuleType: () => ModuleType, ObserveChanges: () => ObserveChanges, PALETTE_ALT_DOWN_FILL: () => PALETTE_ALT_DOWN_FILL, PALETTE_ALT_DOWN_STROKE: () => PALETTE_ALT_DOWN_STROKE, PALETTE_ALT_NEUTRAL_FILL: () => PALETTE_ALT_NEUTRAL_FILL, PALETTE_ALT_NEUTRAL_STROKE: () => PALETTE_ALT_NEUTRAL_STROKE, PALETTE_ALT_UP_FILL: () => PALETTE_ALT_UP_FILL, PALETTE_ALT_UP_STROKE: () => PALETTE_ALT_UP_STROKE, PALETTE_DOWN_FILL: () => PALETTE_DOWN_FILL, PALETTE_DOWN_STROKE: () => PALETTE_DOWN_STROKE, PALETTE_NEUTRAL_FILL: () => PALETTE_NEUTRAL_FILL, PALETTE_NEUTRAL_STROKE: () => PALETTE_NEUTRAL_STROKE, PALETTE_UP_FILL: () => PALETTE_UP_FILL, PALETTE_UP_STROKE: () => PALETTE_UP_STROKE, PART_WHOLE_HIGHLIGHT_STYLE: () => PART_WHOLE_HIGHLIGHT_STYLE, POLAR_AXIS_SHAPE: () => POLAR_AXIS_SHAPE, POLAR_AXIS_TYPE: () => POLAR_AXIS_TYPE, PREV_NEXT_KEYS: () => PREV_NEXT_KEYS, Padding: () => Padding, ParallelStateMachine: () => ParallelStateMachine, PolarZIndexMap: () => PolarZIndexMap, PropertiesArray: () => PropertiesArray, Property: () => addFakeTransformToInstanceProperty, ProxyOnWrite: () => ProxyOnWrite, ProxyProperty: () => ProxyProperty, ProxyPropertyOnWrite: () => ProxyPropertyOnWrite, SAFE_FILLS_OPERATION: () => SAFE_FILLS_OPERATION, SAFE_FILL_OPERATION: () => SAFE_FILL_OPERATION, SAFE_RANGE2_OPERATION: () => SAFE_RANGE2_OPERATION, SAFE_STROKE_FILL_OPERATION: () => SAFE_STROKE_FILL_OPERATION, SEGMENTATION_DEFAULTS: () => SEGMENTATION_DEFAULTS, SINGLE_SERIES_HIGHLIGHT_STYLE: () => SINGLE_SERIES_HIGHLIGHT_STYLE, SKIP_JS_BUILTINS: () => SKIP_JS_BUILTINS, ScaleAlignment: () => ScaleAlignment, SceneArrayChangeDetection: () => SceneArrayChangeDetection, SceneChangeDetection: () => SceneChangeDetection, SceneObjectChangeDetection: () => SceneObjectChangeDetection, SceneRefChangeDetection: () => SceneRefChangeDetection, SeriesContentZIndexMap: () => SeriesContentZIndexMap, SeriesZIndexMap: () => SeriesZIndexMap, SimpleCache: () => SimpleCache, SpanJoin: () => SpanJoin, StateMachine: () => StateMachine, StateMachineProperty: () => StateMachineProperty, TRIPLE_EQ: () => TRIPLE_EQ, TextMeasurer: () => TextMeasurer, TickIntervals: () => TickIntervals, TrimCharsRegex: () => TrimCharsRegex, TrimEdgeGuard: () => TrimEdgeGuard, UNIT_MAX: () => UNIT_MAX, UNIT_MIN: () => UNIT_MIN, UnknownError: () => UnknownError, ValidationError: () => ValidationError, Vec2: () => vector_exports, Vec4: () => vector4_exports, Vertex: () => Vertex, WeakCache: () => WeakCache, ZIndexMap: () => ZIndexMap, addEscapeEventListener: () => addEscapeEventListener, addFakeTransformToInstanceProperty: () => addFakeTransformToInstanceProperty, addMouseCloseListener: () => addMouseCloseListener, addObserverToInstanceProperty: () => addObserverToInstanceProperty, addOverrideFocusVisibleEventListener: () => addOverrideFocusVisibleEventListener, addTouchCloseListener: () => addTouchCloseListener, addTransformToInstanceProperty: () => addTransformToInstanceProperty, aggregationBucketForDatum: () => aggregationBucketForDatum, aggregationDatumMatchesIndex: () => aggregationDatumMatchesIndex, aggregationDomain: () => aggregationDomain, aggregationIndexForXRatio: () => aggregationIndexForXRatio, aggregationRangeFittingPoints: () => aggregationRangeFittingPoints, aggregationXRatioForDatumIndex: () => aggregationXRatioForDatumIndex, aggregationXRatioForXValue: () => aggregationXRatioForXValue, and: () => and, angleBetween: () => angleBetween, angularPadding: () => angularPadding, appendEllipsis: () => appendEllipsis, applySkiaPatches: () => applySkiaPatches, arcDistanceSquared: () => arcDistanceSquared, areScalingEqual: () => areScalingEqual, array: () => array, arrayLength: () => arrayLength, arrayOf: () => arrayOf, arrayOfDefs: () => arrayOfDefs, arraysEqual: () => arraysEqual, assignIfNotStrictlyEqual: () => assignIfNotStrictlyEqual, attachDescription: () => attachDescription, attachListener: () => attachListener, autoSizedLabelOptionsDefs: () => autoSizedLabelOptionsDefs, barHighlightOptionsDef: () => barHighlightOptionsDef, bezier2DDistance: () => bezier2DDistance, bezier2DExtrema: () => bezier2DExtrema, boolean: () => boolean, borderOptionsDef: () => borderOptionsDef, boxCollides: () => boxCollides, boxContains: () => boxContains, boxEmpty: () => boxEmpty, boxesEqual: () => boxesEqual, buildDateFormatter: () => buildDateFormatter, cachedTextMeasurer: () => cachedTextMeasurer, calcLineHeight: () => calcLineHeight, calculatePlacement: () => calculatePlacement, callWithContext: () => callWithContext, callback: () => callback, callbackDefs: () => callbackDefs, callbackOf: () => callbackOf, ceilTo: () => ceilTo, checkDatum: () => checkDatum, circularSliceArray: () => circularSliceArray, clamp: () => clamp, clampArray: () => clampArray, clipLines: () => clipLines, clipSpanX: () => clipSpanX, collapseSpanToPoint: () => collapseSpanToPoint, collectAggregationLevels: () => collectAggregationLevels, color: () => color, colorStopsOrderValidator: () => colorStopsOrderValidator, colorUnion: () => colorUnion, commonChartOptionsDefs: () => commonChartOptionsDefs, commonSeriesOptionsDefs: () => commonSeriesOptionsDefs, commonSeriesThemeableOptionsDefs: () => commonSeriesThemeableOptionsDefs, compactAggregationIndices: () => compactAggregationIndices, compareDates: () => compareDates, computeExtremesAggregation: () => computeExtremesAggregation, computeExtremesAggregationPartial: () => computeExtremesAggregationPartial, constant: () => constant, contextMenuItemsArray: () => contextMenuItemsArray, countFractionDigits: () => countFractionDigits, countLines: () => countLines, createAggregationIndices: () => createAggregationIndices, createButton: () => createButton, createCanvasContext: () => createCanvasContext, createCheckbox: () => createCheckbox, createDeprecationWarning: () => createDeprecationWarning, createElement: () => createElement, createElementId: () => createElementId, createIcon: () => createIcon, createId: () => createId, createIdsGenerator: () => createIdsGenerator, createNumberFormatter: () => createNumberFormatter, createSelect: () => createSelect, createSvgElement: () => createSvgElement, createTextArea: () => createTextArea, createTicks: () => createTicks, date: () => date, dateToNumber: () => dateToNumber, dateTruncationForDomain: () => dateTruncationForDomain, datesSortOrder: () => datesSortOrder, debounce: () => debounce, decodeIntervalValue: () => decodeIntervalValue, deepClone: () => deepClone, deepFreeze: () => deepFreeze, defaultEpoch: () => defaultEpoch, defined: () => defined, definedZoomState: () => definedZoomState, diffArrays: () => diffArrays, distribute: () => distribute, downloadUrl: () => downloadUrl, dropFirstWhile: () => dropFirstWhile, dropLastWhile: () => dropLastWhile, durationDay: () => durationDay, durationHour: () => durationHour, durationMinute: () => durationMinute, durationMonth: () => durationMonth, durationSecond: () => durationSecond, durationWeek: () => durationWeek, durationYear: () => durationYear, easeIn: () => easeIn, easeInOut: () => easeInOut, easeInOutQuad: () => easeInOutQuad, easeInQuad: () => easeInQuad, easeOut: () => easeOut, easeOutQuad: () => easeOutQuad, encodedToTimestamp: () => encodedToTimestamp, enterpriseRegistry: () => enterpriseRegistry, entries: () => entries, errorBarOptionsDefs: () => errorBarOptionsDefs, errorBarThemeableOptionsDefs: () => errorBarThemeableOptionsDefs, estimateTickCount: () => estimateTickCount, evaluateBezier: () => evaluateBezier, every: () => every, expandLegendPosition: () => expandLegendPosition, extent: () => extent, extractDecoratedProperties: () => extractDecoratedProperties, extractDomain: () => extractDomain, fillGradientDefaults: () => fillGradientDefaults, fillImageDefaults: () => fillImageDefaults, fillOptionsDef: () => fillOptionsDef, fillPatternDefaults: () => fillPatternDefaults, findMaxIndex: () => findMaxIndex, findMaxValue: () => findMaxValue, findMinIndex: () => findMinIndex, findMinMax: () => findMinMax, findMinValue: () => findMinValue, findRangeExtent: () => findRangeExtent, first: () => first, flush: () => flush, focusCursorAtEnd: () => focusCursorAtEnd, fontFamilyFull: () => fontFamilyFull, fontOptionsDef: () => fontOptionsDef, fontWeight: () => fontWeight, formatNumber: () => formatNumber, formatObjectValidator: () => formatObjectValidator, formatPercent: () => formatPercent, formatValue: () => formatValue, fromPairs: () => fromPairs, generateUUID: () => generateUUID, geoJson: () => geoJson, getAngleRatioRadians: () => getAngleRatioRadians, getAttribute: () => getAttribute, getDOMMatrix: () => getDOMMatrix, getDocument: () => getDocument, getElementBBox: () => getElementBBox, getIconClassNames: () => getIconClassNames, getImage: () => getImage, getLastFocus: () => getLastFocus, getMaxInnerRectSize: () => getMaxInnerRectSize, getMidpointsForIndices: () => getMidpointsForIndices, getMinOuterRectSize: () => getMinOuterRectSize, getOffscreenCanvas: () => getOffscreenCanvas, getPath: () => getPath, getPath2D: () => getPath2D, getResizeObserver: () => getResizeObserver, getSequentialColors: () => getSequentialColors, getTickTimeInterval: () => getTickTimeInterval, getWindow: () => getWindow, googleFont: () => googleFont, gradientColorStops: () => gradientColorStops, gradientStrict: () => gradientStrict, greaterThan: () => greaterThan, groupBy: () => groupBy, guardTextEdges: () => guardTextEdges, hasNoModifiers: () => hasNoModifiers, hasRequiredInPath: () => hasRequiredInPath, highlightOptionsDef: () => highlightOptionsDef, htmlElement: () => htmlElement, inRange: () => inRange, initRovingTabIndex: () => initRovingTabIndex, insertListItemsSorted: () => insertListItemsSorted, instanceOf: () => instanceOf, interpolationOptionsDefs: () => interpolationOptionsDefs, intervalCeil: () => intervalCeil, intervalEpoch: () => intervalEpoch, intervalExtent: () => intervalExtent, intervalFloor: () => intervalFloor, intervalHierarchy: () => intervalHierarchy, intervalMilliseconds: () => intervalMilliseconds, intervalNext: () => intervalNext, intervalPrevious: () => intervalPrevious, intervalRange: () => intervalRange, intervalRangeCount: () => intervalRangeCount, intervalRangeNumeric: () => intervalRangeNumeric, intervalRangeStartIndex: () => intervalRangeStartIndex, intervalStep: () => intervalStep, intervalUnit: () => intervalUnit, inverseEaseOut: () => inverseEaseOut, isArray: () => isArray, isBetweenAngles: () => isBetweenAngles, isBoolean: () => isBoolean, isButtonClickEvent: () => isButtonClickEvent, isColor: () => isColor, isContinuous: () => isContinuous, isDate: () => isDate, isDecoratedObject: () => isDecoratedObject, isDefined: () => isDefined, isDenseInterval: () => isDenseInterval, isDocumentFragment: () => isDocumentFragment, isElement: () => isElement, isEmptyObject: () => isEmptyObject, isEnumKey: () => isEnumKey, isEnumValue: () => isEnumValue, isFiniteNumber: () => isFiniteNumber, isFunction: () => isFunction, isGradientFill: () => isGradientFill, isGradientFillArray: () => isGradientFillArray, isGradientOrPatternFill: () => isGradientOrPatternFill, isHTMLElement: () => isHTMLElement, isHtmlElement: () => isHtmlElement, isImageFill: () => isImageFill, isInputPending: () => isInputPending, isInteger: () => isInteger, isKeyOf: () => isKeyOf, isNegative: () => isNegative, isNode: () => isNode, isNumber: () => isNumber, isNumberEqual: () => isNumberEqual, isNumberObject: () => isNumberObject, isObject: () => isObject, isObjectLike: () => isObjectLike, isObjectWithProperty: () => isObjectWithProperty, isObjectWithStringProperty: () => isObjectWithStringProperty, isPatternFill: () => isPatternFill, isPlainObject: () => isPlainObject, isPointLabelDatum: () => isPointLabelDatum, isProperties: () => isProperties, isRegExp: () => isRegExp, isScaleValid: () => isScaleValid, isSegmentTruncated: () => isSegmentTruncated, isString: () => isString, isStringFillArray: () => isStringFillArray, isStringObject: () => isStringObject, isSymbol: () => isSymbol, isTextTruncated: () => isTextTruncated, isTruncated: () => isTruncated, isUnitTimeCategoryScaling: () => isUnitTimeCategoryScaling, isValidDate: () => isValidDate, isValidNumberFormat: () => isValidNumberFormat, iterate: () => iterate, joinFormatted: () => joinFormatted, jsonApply: () => jsonApply, jsonDiff: () => jsonDiff, jsonPropertyCompare: () => jsonPropertyCompare, jsonWalk: () => jsonWalk, kebabCase: () => kebabCase, labelBoxOptionsDef: () => labelBoxOptionsDef, legendPositionValidator: () => legendPositionValidator, lessThan: () => lessThan, lessThanOrEqual: () => lessThanOrEqual, levenshteinDistance: () => levenshteinDistance, lineDashOptionsDef: () => lineDashOptionsDef, lineDistanceSquared: () => lineDistanceSquared, lineHighlightOptionsDef: () => lineHighlightOptionsDef, lineSegmentOptions: () => lineSegmentOptions, lineSegmentation: () => lineSegmentation, linear: () => linear, linearGaugeSeriesOptionsDef: () => linearGaugeSeriesOptionsDef, linearGaugeSeriesThemeableOptionsDef: () => linearGaugeSeriesThemeableOptionsDef, linearGaugeTargetOptionsDef: () => linearGaugeTargetOptionsDef, linearPoints: () => linearPoints, listDecoratedProperties: () => listDecoratedProperties, lowestGranularityForInterval: () => lowestGranularityForInterval, lowestGranularityUnitForTicks: () => lowestGranularityUnitForTicks, lowestGranularityUnitForValue: () => lowestGranularityUnitForValue, makeAccessibleClickListener: () => makeAccessibleClickListener, mapValues: () => mapValues, markerOptionsDefs: () => markerOptionsDefs, markerStyleOptionsDefs: () => markerStyleOptionsDefs, measureTextSegments: () => measureTextSegments, memo: () => memo, merge: () => merge, mergeArrayDefaults: () => mergeArrayDefaults, mergeDefaults: () => mergeDefaults, modulus: () => modulus, multiSeriesHighlightOptionsDef: () => multiSeriesHighlightOptionsDef, nearestSquared: () => nearestSquared, nearestSquaredInContainer: () => nearestSquaredInContainer, nextPowerOf2: () => nextPowerOf2, niceTicksDomain: () => niceTicksDomain, normalisedExtentWithMetadata: () => normalisedExtentWithMetadata, normalisedTimeExtentWithMetadata: () => normalisedTimeExtentWithMetadata, normalizeAngle180: () => normalizeAngle180, normalizeAngle360: () => normalizeAngle360, normalizeAngle360FromDegrees: () => normalizeAngle360FromDegrees, normalizeAngle360Inclusive: () => normalizeAngle360Inclusive, number: () => number, numberFormatValidator: () => numberFormatValidator, numberMin: () => numberMin, numberRange: () => numberRange, object: () => object, objectsEqual: () => objectsEqual, objectsEqualWith: () => objectsEqualWith, optionsDefs: () => optionsDefs, or: () => or, padding: () => padding, paddingOptions: () => paddingOptions, parseNumberFormat: () => parseNumberFormat, partialAssign: () => partialAssign, pause: () => pause, pick: () => pick, placeLabels: () => placeLabels, positiveNumber: () => positiveNumber, positiveNumberNonZero: () => positiveNumberNonZero, previousPowerOf2: () => previousPowerOf2, radialGaugeSeriesOptionsDef: () => radialGaugeSeriesOptionsDef, radialGaugeSeriesThemeableOptionsDef: () => radialGaugeSeriesThemeableOptionsDef, radialGaugeTargetOptionsDef: () => radialGaugeTargetOptionsDef, range: () => range, rangeValidator: () => rangeValidator, ratio: () => ratio, readIntegratedWrappedValue: () => readIntegratedWrappedValue, record: () => record, required: () => required, rescaleSpan: () => rescaleSpan, rescaleVisibleRange: () => rescaleVisibleRange, resetIds: () => resetIds, rotatePoint: () => rotatePoint, roundTo: () => roundTo, safeCall: () => safeCall, seriesLabelOptionsDefs: () => seriesLabelOptionsDefs, seriesTooltipRangeValidator: () => seriesTooltipRangeValidator, setAttribute: () => setAttribute, setAttributes: () => setAttributes, setDocument: () => setDocument, setElementBBox: () => setElementBBox, setElementStyle: () => setElementStyle, setElementStyles: () => setElementStyles, setPath: () => setPath, setWindow: () => setWindow, shadowOptionsDefs: () => shadowOptionsDefs, shallowClone: () => shallowClone, shapeHighlightOptionsDef: () => shapeHighlightOptionsDef, shapeSegmentOptions: () => shapeSegmentOptions, shapeSegmentation: () => shapeSegmentation, shapeValidator: () => shapeValidator, simpleMemorize: () => simpleMemorize, simpleMemorize2: () => simpleMemorize2, smoothPoints: () => smoothPoints, solveBezier: () => solveBezier, sortAndUniqueDates: () => sortAndUniqueDates, sortBasedOnArray: () => sortBasedOnArray, spanRange: () => spanRange, splitBezier2D: () => splitBezier2D, stepPoints: () => stepPoints, stopPageScrolling: () => stopPageScrolling, strictObjectKeys: () => strictObjectKeys, strictUnion: () => strictUnion, string: () => string, stringLength: () => stringLength, stringifyValue: () => stringifyValue, strokeOptionsDef: () => strokeOptionsDef, textOrSegments: () => textOrSegments, themeOperator: () => themeOperator, throttle: () => throttle, tickFormat: () => tickFormat, tickStep: () => tickStep, toArray: () => toArray, toDegrees: () => toDegrees, toFontString: () => toFontString, toIterable: () => toIterable, toPlainText: () => toPlainText, toRadians: () => toRadians, toTextString: () => toTextString, toolbarButtonOptionsDefs: () => toolbarButtonOptionsDefs, tooltipOptionsDefs: () => tooltipOptionsDefs, tooltipOptionsDefsWithArea: () => tooltipOptionsDefsWithArea, transformIntegratedCategoryValue: () => transformIntegratedCategoryValue, truncateLine: () => truncateLine, typeUnion: () => typeUnion, undocumented: () => undocumented, unguardTextEdges: () => unguardTextEdges, union: () => union, unionSymbol: () => unionSymbol, unique: () => unique, validate: () => validate, withTimeout: () => withTimeout, without: () => without, wrapLines: () => wrapLines, wrapText: () => wrapText, wrapTextOrSegments: () => wrapTextOrSegments, wrapTextSegments: () => wrapTextSegments }); module.exports = __toCommonJS(main_exports); // packages/ag-charts-core/src/modules/moduleDefinition.ts var ModuleType = /* @__PURE__ */ ((ModuleType2) => { ModuleType2["Chart"] = "chart"; ModuleType2["Axis"] = "axis"; ModuleType2["Series"] = "series"; ModuleType2["Plugin"] = "plugin"; ModuleType2["AxisPlugin"] = "axis:plugin"; ModuleType2["SeriesPlugin"] = "series:plugin"; ModuleType2["Preset"] = "preset"; return ModuleType2; })(ModuleType || {}); // packages/ag-charts-core/src/types/scales.ts function extractDomain(value) { return value.domain; } var ScaleAlignment = /* @__PURE__ */ ((ScaleAlignment2) => { ScaleAlignment2[ScaleAlignment2["Leading"] = 0] = "Leading"; ScaleAlignment2[ScaleAlignment2["Trailing"] = 1] = "Trailing"; ScaleAlignment2[ScaleAlignment2["Interpolate"] = 2] = "Interpolate"; return ScaleAlignment2; })(ScaleAlignment || {}); // packages/ag-charts-core/src/structures/eventEmitter.ts var EventEmitter = class { constructor() { this.events = /* @__PURE__ */ new Map(); } /** * Registers an event listener. * @param eventName The event name to listen for. * @param listener The callback to be invoked on the event. * @returns A function to unregister the listener. */ on(eventName, listener) { if (!this.events.has(eventName)) { this.events.set(eventName, /* @__PURE__ */ new Set()); } this.events.get(eventName)?.add(listener); return () => this.off(eventName, listener); } /** * Unregisters an event listener. * @param eventName The event name to stop listening for. * @param listener The callback to be removed. */ off(eventName, listener) { const eventListeners = this.events.get(eventName); if (eventListeners) { eventListeners.delete(listener); if (eventListeners.size === 0) { this.events.delete(eventName); } } } /** * Emits an event to all registered listeners. * @param eventName The name of the event to emit. * @param event The event payload. */ emit(eventName, event) { const listeners = this.events.get(eventName); if (listeners) { for (const callback2 of listeners) { callback2(event); } } } /** * Clears all listeners for a specific event or all events if no event name is provided. * @param eventName (Optional) The name of the event to clear listeners for. If not provided, all listeners for all events are cleared. */ clear(eventName) { if (eventName) { this.events.delete(eventName); } else { this.events.clear(); } } }; // packages/ag-charts-core/src/structures/lruCache.ts var LRUCache = class { constructor(maxCacheSize) { this.maxCacheSize = maxCacheSize; this.store = /* @__PURE__ */ new Map(); if (maxCacheSize <= 0) { throw new Error("LRUCache size must be greater than 0"); } } get(key) { if (!this.store.has(key)) return; const value = this.store.get(key); this.store.delete(key); this.store.set(key, value); return value; } has(key) { return this.store.has(key); } set(key, value) { this.store.set(key, value); if (this.store.size > this.maxCacheSize) { this.store.delete(this.store.keys().next().value); } return value; } clear() { this.store.clear(); } }; // packages/ag-charts-core/src/logging/debugLogger.ts var debugLogger_exports = {}; __export(debugLogger_exports, { Time: () => Time, check: () => check, create: () => create, inDevelopmentMode: () => inDevelopmentMode }); // packages/ag-charts-core/src/utils/data/arrays.ts function toArray(value) { if (value === void 0) { return []; } return Array.isArray(value) ? value : [value]; } function unique(array2) { return Array.from(new Set(array2)); } function groupBy(array2, iteratee) { return array2.reduce((result, item) => { const groupKey = iteratee(item); result[groupKey] ?? (result[groupKey] = []); result[groupKey].push(item); return result; }, {}); } function arraysEqual(a, b) { if (a == null || b == null || a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (Array.isArray(a[i]) && Array.isArray(b[i])) { if (!arraysEqual(a[i], b[i])) { return false; } } else if (a[i] !== b[i]) { return false; } } return true; } function circularSliceArray(data, size, offset = 0) { if (data.length === 0) { return []; } const result = []; for (let i = 0; i < size; i++) { result.push(data.at((i + offset) % data.length)); } return result; } function sortBasedOnArray(baseArray, orderArray) { const orderMap = /* @__PURE__ */ new Map(); for (const [index, item] of orderArray.entries()) { orderMap.set(item, index); } return baseArray.sort((a, b) => { const indexA = orderMap.get(a) ?? Infinity; const indexB = orderMap.get(b) ?? Infinity; return indexA - indexB; }); } function dropFirstWhile(array2, cond) { let i = 0; while (i < array2.length && cond(array2[i])) { i += 1; } const deleteCount = i; if (deleteCount !== 0) array2.splice(0, deleteCount); } function dropLastWhile(array2, cond) { let i = array2.length - 1; while (i >= 0 && cond(array2[i])) { i -= 1; } const deleteCount = array2.length - 1 - i; if (deleteCount !== 0) array2.splice(array2.length - deleteCount, deleteCount); } function distribute(min, max, maxCount) { const values = [min]; const step = Math.round((max - min) / (maxCount - 1)); if (step > 0) { for (let i = min + step; i < max; i += step) { const length2 = values.push(i); if (length2 >= maxCount - 1) break; } } values.push(max); return values; } // packages/ag-charts-core/src/utils/dom/globalsProxy.ts var verifiedGlobals = {}; if (typeof globalThis.window !== "undefined") { verifiedGlobals.window = globalThis.window; } if (typeof document !== "undefined") { verifiedGlobals.document = document; } else if (typeof globalThis.global !== "undefined") { verifiedGlobals.document = globalThis.document; } function getDocument(propertyName) { return propertyName ? verifiedGlobals.document?.[propertyName] : verifiedGlobals.document; } function getWindow(propertyName) { return propertyName ? verifiedGlobals.window?.[propertyName] : verifiedGlobals.window; } function setDocument(document2) { verifiedGlobals.document = document2; } function setWindow(window) { verifiedGlobals.window = window; } function getOffscreenCanvas() { return verifiedGlobals.window?.OffscreenCanvas ?? globalThis.OffscreenCanvas; } function getPath2D() { return verifiedGlobals.window?.Path2D ?? globalThis.Path2D; } function getDOMMatrix() { return verifiedGlobals.window?.DOMMatrix ?? globalThis.DOMMatrix; } function getImage() { return verifiedGlobals.window?.Image ?? globalThis.Image; } function getResizeObserver() { return verifiedGlobals.window?.ResizeObserver ?? globalThis.ResizeObserver; } var ELEMENT_NODE = 1; var DOCUMENT_FRAGMENT_NODE = 11; function isNode(obj) { return obj != null && typeof obj.nodeType === "number"; } function isElement(obj) { return obj != null && obj.nodeType === ELEMENT_NODE; } function isDocumentFragment(obj) { return obj != null && obj.nodeType === DOCUMENT_FRAGMENT_NODE; } function isHTMLElement(obj) { return obj != null && obj.nodeType === ELEMENT_NODE && "style" in obj; } // packages/ag-charts-core/src/logging/logger.ts var logger_exports = {}; __export(logger_exports, { error: () => error, errorOnce: () => errorOnce, log: () => log, logGroup: () => logGroup, reset: () => reset, table: () => table, warn: () => warn, warnOnce: () => warnOnce }); var doOnceCache = /* @__PURE__ */ new Set(); function log(...logContent) { console.log(...logContent); } function warn(message, ...logContent) { console.warn(`AG Charts - ${message}`, ...logContent); } function error(message, ...logContent) { if (typeof message === "object") { console.error(`AG Charts error`, message, ...logContent); } else { console.error(`AG Charts - ${message}`, ...logContent); } } function table(...logContent) { console.table(...logContent); } function guardOnce(messageOrError, prefix, cb) { let message; if (messageOrError instanceof Error) { message = messageOrError.message; } else if (typeof messageOrError === "string") { message = messageOrError; } else if (typeof messageOrError === "object") { message = JSON.stringify(messageOrError); } else { message = String(messageOrError); } const cacheKey = `${prefix}: ${message}`; if (doOnceCache.has(cacheKey)) return; cb(messageOrError); doOnceCache.add(cacheKey); } function warnOnce(messageOrError, ...logContent) { guardOnce(messageOrError, "Logger.warn", (message) => warn(message, ...logContent)); } function errorOnce(messageOrError, ...logContent) { guardOnce(messageOrError, "Logger.error", (message) => error(message, ...logContent)); } function reset() { doOnceCache.clear(); } function logGroup(name, cb) { console.groupCollapsed(name); try { return cb(); } finally { console.groupEnd(); } } // packages/ag-charts-core/src/logging/debugLogger.ts var LongTimePeriodThreshold = 2e3; var timeOfLastLog = Date.now(); function logTimeGap() { const timeSinceLastLog = Date.now() - timeOfLastLog; if (timeSinceLastLog > LongTimePeriodThreshold) { const prettyDuration = (Math.floor(timeSinceLastLog / 100) / 10).toFixed(1); log(`**** ${prettyDuration}s since last log message ****`); } timeOfLastLog = Date.now(); } function create(...debugSelectors) { const resultFn = (...logContent) => { if (check(...debugSelectors)) { if (typeof logContent[0] === "function") { logContent = toArray(logContent[0]()); } logTimeGap(); log(...logContent); } }; return Object.assign(resultFn, { check: () => check(...debugSelectors), group: (name, cb) => { if (check(...debugSelectors)) { return logGroup(name, cb); } return cb(); } }); } function check(...debugSelectors) { if (debugSelectors.length === 0) { debugSelectors.push(true); } const chartDebug = toArray(getWindow("agChartsDebug")); return chartDebug.some((selector) => debugSelectors.includes(selector)); } function inDevelopmentMode(fn) { if (check("dev")) { return fn(); } } function Time(name, opts = {}) { const { logResult = true, logStack = false, logArgs = false, logData } = opts; return function(_target, _propertyKey, descriptor) { const method = descriptor.value; descriptor.value = function(...args) { const start2 = performance.now(); const result = method.apply(this, args); const duration = performance.now() - start2; const logMessage = { duration }; if (logResult) logMessage.result = result; if (logArgs) logMessage.args = args; if (logStack) logMessage.stack = new Error("Stack trace for timing debug").stack; if (logData) logMessage.logData = logData(this); log(name, logMessage); return result; }; }; } // packages/ag-charts-core/src/logging/debugMetrics.ts var debugMetrics_exports = {}; __export(debugMetrics_exports, { flush: () => flush, record: () => record }); var metrics = /* @__PURE__ */ new Map(); function record(key, value) { if (!check("scene:stats:verbose")) return; metrics.set(key, value); } function flush() { const result = Object.fromEntries(metrics); metrics.clear(); return result; } // packages/ag-charts-core/src/modules/enterpriseRegistry.ts var enterpriseRegistry = {}; // packages/ag-charts-core/src/modules/moduleRegistry.ts var moduleRegistry_exports = {}; __export(moduleRegistry_exports, { RegistryMode: () => RegistryMode, getAxisModule: () => getAxisModule, getChartModule: () => getChartModule, getPresetModule: () => getPresetModule, getSeriesModule: () => getSeriesModule, hasModule: () => hasModule, isEnterprise: () => isEnterprise, isIntegrated: () => isIntegrated, isModuleType: () => isModuleType, isUmd: () => isUmd, listModules: () => listModules, listModulesByType: () => listModulesByType, register: () => register, registerModules: () => registerModules, reset: () => reset2, setRegistryMode: () => setRegistryMode }); var RegistryMode = /* @__PURE__ */ ((RegistryMode2) => { RegistryMode2["Enterprise"] = "enterprise"; RegistryMode2["Integrated"] = "integrated"; RegistryMode2["UMD"] = "umd"; return RegistryMode2; })(RegistryMode || {}); var registeredModes = /* @__PURE__ */ new Set(); var registeredModules = /* @__PURE__ */ new Map(); function registerModuleDefinition(def) { registeredModules.set(def.name, def); if (def.dependencies) { for (const dependency of def.dependencies) { register(dependency); } } } function register(def) { const existingDefinition = registeredModules.get(def.name); if (!existingDefinition) { registerModuleDefinition(def); return; } if (existingDefinition.version === def.version) { if (!existingDefinition.enterprise && def.enterprise) { registerModuleDefinition(def); } return; } throw new Error( [ `AG Charts - Module '${def.name}' already registered with different version:`, `${existingDefinition.version} vs ${def.version}`, ``, `Check your package.json for conflicting dependencies - depending on your package manager`, `one of these commands may help:`, `- npm ls ag-charts-community`, `- yarn why ag-charts-community` ].join("\n") ); } function registerModules(definitions) { for (const definition of definitions.flat()) { register(definition); } } function reset2() { registeredModes.clear(); registeredModules.clear(); } function hasModule(moduleName) { return registeredModules.has(moduleName); } function* listModules() { for (const definition of registeredModules.values()) { yield definition; } } function* listModulesByType(moduleType) { for (const definition of registeredModules.values()) { if (isModuleType(moduleType, definition)) { yield definition; } } } function getAxisModule(moduleName) { const definition = registeredModules.get(moduleName); if (isModuleType("axis" /* Axis */, definition)) { return definition; } } function getChartModule(moduleName) { const definition = registeredModules.get(moduleName); if (isModuleType("chart" /* Chart */, definition)) { return definition; } throw new Error( `AG Charts - Unknown chart type; Check options are correctly structured and series types are specified` ); } function getPresetModule(moduleName) { const definition = registeredModules.get(moduleName); if (isModuleType("preset" /* Preset */, definition)) { return definition; } } function getSeriesModule(moduleName) { const definition = registeredModules.get(moduleName); if (isModuleType("series" /* Series */, definition)) { return definition; } } function setRegistryMode(registryFlag) { registeredModes.add(registryFlag); } function isEnterprise() { return registeredModes.has("enterprise" /* Enterprise */); } function isIntegrated() { return registeredModes.has("integrated" /* Integrated */); } function isUmd() { return registeredModes.has("umd" /* UMD */); } function isModuleType(moduleType, definition) { return definition?.type === moduleType; } // packages/ag-charts-core/src/state/cleanupRegistry.ts var CleanupRegistry = class { constructor() { this.callbacks = /* @__PURE__ */ new Set(); } flush() { for (const cb of this.callbacks) { cb(); } this.callbacks.clear(); } merge(registry) { for (const cb of registry.callbacks) { this.callbacks.add(cb); } } register(...callbacks) { for (const cb of callbacks) { if (!cb) continue; this.callbacks.add(cb); } } }; // packages/ag-charts-core/src/modules/moduleInstance.ts var AbstractModuleInstance = class { constructor() { this.cleanup = new CleanupRegistry(); } destroy() { this.cleanup.flush(); } }; // packages/ag-charts-types/src/chart/navigatorOptions.ts var __MINI_CHART_SERIES_OPTIONS = void 0; var __VERIFY_MINI_CHART_SERIES_OPTIONS = void 0; __VERIFY_MINI_CHART_SERIES_OPTIONS = __MINI_CHART_SERIES_OPTIONS; // packages/ag-charts-types/src/chart/themeOptions.ts var __THEME_OVERRIDES = void 0; var __VERIFY_THEME_OVERRIDES = void 0; __VERIFY_THEME_OVERRIDES = __THEME_OVERRIDES; // packages/ag-charts-types/src/presets/gauge/commonOptions.ts var __THEMEABLE_OPTIONS = void 0; var __VERIFY_THEMEABLE_OPTIONS = void 0; __VERIFY_THEMEABLE_OPTIONS = __THEMEABLE_OPTIONS; var __AXIS_LABEL_OPTIONS = void 0; var __VERIFY_AXIS_LABEL_OPTIONS = void 0; __VERIFY_AXIS_LABEL_OPTIONS = __AXIS_LABEL_OPTIONS; // packages/ag-charts-core/src/types/text.ts var EllipsisChar = "\u2026"; var LineSplitter = /\r?\n/g; var TrimEdgeGuard = "\u200B"; var TrimCharsRegex = /[\s.,;:-]{1,5}$/; // packages/ag-charts-core/src/utils/dom/domUtils.ts var style; function parseColor(color2) { if (style == null) { const OptionConstructor = getWindow("Option"); style = new OptionConstructor().style; } style.color = color2; const result = style.color || null; style.color = ""; return result; } // packages/ag-charts-core/src/utils/types/typeGuards.ts function isDefined(val) { return val != null; } function isArray(value) { return Array.isArray(value); } function isBoolean(value) { return typeof value === "boolean"; } function isDate(value) { return value instanceof Date; } function isValidDate(value) { return isDate(value) && !Number.isNaN(Number(value)); } function isRegExp(value) { return value instanceof RegExp; } function isFunction(value) { return typeof value === "function"; } function isObject(value) { return typeof value === "object" && value !== null && !isArray(value); } function isObjectLike(value) { return isArray(value) || isPlainObject(value); } function isPlainObject(value) { return typeof value === "object" && value !== null && value.constructor?.name === "Object"; } function isEmptyObject(value) { if (typeof value !== "object" || value === null) return false; for (const _ in value) { return false; } return true; } function isString(value) { return typeof value === "string"; } function isNumber(value) { return typeof value === "number"; } function isFiniteNumber(value) { return Number.isFinite(value); } function isHtmlElement(value) { return value != null && value.nodeType === 1 && "style" in value; } function isEnumKey(enumObject, enumKey) { return isString(enumKey) && Object.keys(enumObject).includes(enumKey); } function isEnumValue(enumObject, enumValue) { return Object.values(enumObject).includes(enumValue); } function isSymbol(value) { return typeof value === "symbol"; } function isColor(value) { return isString(value) && (value === "none" || parseColor(value) != null); } function isKeyOf(value, container) { return value in container; } // packages/ag-charts-core/src/utils/text/textUtils.ts function toFontString({ fontSize, fontStyle, fontWeight: fontWeight2, fontFamily }) { let fontString = ""; if (fontStyle && fontStyle !== "normal") { fontString += `${fontStyle} `; } if (fontWeight2 && fontWeight2 !== "normal" && fontWeight2 !== 400) { fontString += `${fontWeight2} `; } fontString += `${fontSize}px`; fontString += ` ${fontFamily}`; return fontString; } function calcLineHeight(fontSize, lineHeightRatio = 1.15) { return Math.round(fontSize * lineHeightRatio); } function toTextString(value) { return String(value ?? ""); } function appendEllipsis(text) { return text.replace(TrimCharsRegex, "") + EllipsisChar; } function guardTextEdges(str) { return TrimEdgeGuard + str + TrimEdgeGuard; } function unguardTextEdges(str) { return str.replaceAll(TrimEdgeGuard, ""); } function isTruncated(value) { return isArray(value) ? isSegmentTruncated(value.at(-1)) : isTextTruncated(toTextString(value)); } function isTextTruncated(str) { return str.endsWith(EllipsisChar); } function isSegmentTruncated(segment) { return toTextString(segment?.text).endsWith(EllipsisChar); } // packages/ag-charts-core/src/utils/data/strings.ts function joinFormatted(values, conjunction = "and", format = String, maxItems = Infinity) { if (values.length === 0) { return ""; } else if (values.length === 1) { return format(values[0]); } values = values.map(format); const lastValue = values.pop(); if (values.length >= maxItems) { const remainingCount = values.length - (maxItems - 1); return `${values.slice(0, maxItems - 1).join(", ")}, and ${remainingCount} more ${conjunction} ${lastValue}`; } return `${values.join(", ")} ${conjunction} ${lastValue}`; } function stringifyValue(value, maxLength = Infinity) { if (typeof value === "number") { if (Number.isNaN(value)) { return "NaN"; } else if (value === Infinity) { return "Infinity"; } else if (value === -Infinity) { return "-Infinity"; } } const strValue = JSON.stringify(value) ?? typeof value; if (strValue.length > maxLength) { return `${strValue.slice(0, maxLength)}... (+${strValue.length - maxLength} characters)`; } return strValue; } function countLines(text) { let count = 1; for (let i = 0; i < text.length; i++) { if (text.codePointAt(i) === 10) { count++; } } return count; } function levenshteinDistance(a, b) { if (a === b) return 0; const [shorter, longer] = a.length < b.length ? [a, b] : [b, a]; const m = shorter.length; const n = longer.length; let prevRow = new Array(m + 1).fill(0).map((_, i) => i); let currRow = new Array(m + 1); for (let i = 1; i <= n; i++) { currRow[0] = i; for (let j = 1; j <= m; j++) { const cost = longer[i - 1] === shorter[j - 1] ? 0 : 1; currRow[j] = Math.min( prevRow[j] + 1, // Deletion currRow[j - 1] + 1, // Insertion prevRow[j - 1] + cost // Substitution ); } [prevRow, currRow] = [currRow, prevRow]; } return prevRow[m]; } function kebabCase(a) { return a.replaceAll(KEBAB_CASE_REGEX, (match, offset) => (offset > 0 ? "-" : "") + match.toLowerCase()); } var KEBAB_CASE_REGEX = /[A-Z]+(?![a-z])|[A-Z]/g; function toPlainText(text, fallback = "") { if (text == null) { return fallback; } else if (isArray(text)) { return text.map((segment) => toTextString(segment.text)).join(""); } else if (isString(text)) { return text; } else { return String(text); } } // packages/ag-charts-core/src/utils/functions.ts function debounce(callback2, waitMs = 0, options) { const { leading = false, trailing = true, maxWait = Infinity } = options ?? {}; let timerId; let startTime; if (maxWait < waitMs) { throw new Error("Value of maxWait cannot be lower than waitMs."); } function debounceCallback(...args) { if (leading && !startTime) { startTime = Date.now(); timerId = setTimeout(() => startTime = null, waitMs); callback2(...args); return; } let adjustedWaitMs = waitMs; if (maxWait !== Infinity && startTime) { const elapsedTime = Date.now() - startTime; if (waitMs > maxWait - elapsedTime) { adjustedWaitMs = maxWait - elapsedTime; } } clearTimeout(timerId); startTime ?? (startTime = Date.now()); timerId = setTimeout(() => { startTime = null; if (trailing) { callback2(...args); } }, adjustedWaitMs); } return Object.assign(debounceCallback, { cancel() { clearTimeout(timerId); startTime = null; } }); } function throttle(callback2, waitMs, options) { const { leading = true, trailing = true } = options ?? {}; let timerId; let lastArgs; let shouldWait = false; function timeoutHandler() { if (trailing && lastArgs) { timerId = setTimeout(timeoutHandler, waitMs); callback2(...lastArgs); } else { shouldWait = false; } lastArgs = null; } function throttleCallback(...args) { if (shouldWait) { lastArgs = args; } else { shouldWait = true; timerId = setTimeout(timeoutHandler, waitMs); if (leading) { callback2(...args); } else { lastArgs = args; } } } return Object.assign(throttleCallback, { cancel() { clearTimeout(timerId); shouldWait = false; lastArgs = null; } }); } function safeCall(callback2, args, errorPath = "") { try { return callback2(...args); } catch (error2) { const postfix = errorPath ? ` \`${errorPath}\`` : ""; warnOnce(`Uncaught exception in user callback${postfix}`, error2); } } // packages/ag-charts-core/src/state/validation.ts var descriptionSymbol = Symbol("description"); var requiredSymbol = Symbol("required"); var markedSymbol = Symbol("marked"); var undocumentedSymbol = Symbol("undocumented"); var unionSymbol = Symbol("union"); var similarOptionsMap = [ ["placement", "position"], ["padding", "spacing", "gap"], ["color", "fill", "stroke"], ["whisker", "wick"], ["src", "url"], ["width", "thickness"] ].reduce((map, words) => { for (const word of words) { map.set(word.toLowerCase(), new Set(words.filter((w) => w !== word))); } return map; }, /* @__PURE__ */ new Map()); var ErrorType = /* @__PURE__ */ ((ErrorType2) => { ErrorType2["Invalid"] = "invalid"; ErrorType2["Required"] = "required"; ErrorType2["Unknown"] = "unknown"; return ErrorType2; })(ErrorType || {}); function extendPath(path, key) { if (isFiniteNumber(key)) { return `${path}[${key}]`; } return path ? `${path}.${key}` : key; } var ValidationError = class { constructor(type, description, value, path, key) { this.type = type; this.description = description; this.value = value; this.path = path; this.key = key; } setUnionType(unionType, path) { if (this.path.startsWith(path)) { const suffix = this.path.slice(path.length); this.altPath = `${path}[type=${unionType}]${suffix}`; } } getPrefix() { const { altPath: path = this.path, key } = this; if (!path && !key) return "Value"; return `Option \`${key ? extendPath(path, key) : path}\``; } toString() { const { description = "unknown", type, value } = this; if (type === "required" /* Required */ && value == null) { return `${this.getPrefix()} is required and has not been provided; expecting ${description}, ignoring.`; } return `${this.getPrefix()} cannot be set to \`${stringifyValue(value, 50)}\`; expecting ${description}, ignoring.`; } }; var UnknownError = class extends ValidationError { constructor(suggestions, value, path, key) { super("unknown" /* Unknown */, void 0, value, path, key); this.suggestions = suggestions; this.key = key; } getPrefix() { return `Unknown option \`${extendPath(this.altPath ?? this.path, this.key)}\``; } getPostfix() { const suggestions = joinFormatted(findSuggestions(this.key, this.suggestions), "or", (val) => `\`${val}\``); return suggestions ? `; Did you mean ${suggestions}? Ignoring.` : ", ignoring."; } toString() { return `${this.getPrefix()}${this.getPostfix()}`; } }; function validate(options, optionsDefs2, path = "") { if (!isObject(options)) { return { cleared: null, invalid: [new ValidationError("required" /* Required */, "an object", options, path)] }; } const cleared = {}; const invalid = []; const optionsKeys = new Set(Object.keys(options)); const unusedKeys = []; if (unionSymbol in optionsDefs2) { const validTypes = Object.keys(optionsDefs2); const defaultType = optionsDefs2[unionSymbol]; if (options.type != null && validTypes.includes(options.type) || options.type == null && defaultType != null) { const { type = defaultType, ...rest } = options; const nestedResult = validate(rest, optionsDefs2[type], path); Object.assign(cleared, { type }, nestedResult.cleared); for (const error2 of nestedResult.invalid) { error2.setUnionType(type, path); } invalid.push(...nestedResult.invalid); } else { const keywords = joinFormatted(validTypes, "or", (val) => `'${val}'`); invalid.push( new ValidationError("required" /* Required */, `a keyword such as ${keywords}`, options.type, path, "type") ); } return { cleared, invalid }; } for (const key of Object.keys(optionsDefs2)) { const validatorOrDefs = optionsDefs2[key]; const required3 = validatorOrDefs[requiredSymbol]; const value = options[key]; optionsKeys.delete(key); if (value === void 0) { if (!validatorOrDefs[undocumentedSymbol]) { unusedKeys.push(key); } if (!required3) continue; } const keyPath = extendPath(path, key); if (isFunction(validatorOrDefs)) { const context = { options, path: keyPath }; const validatorResult = validatorOrDefs(value, context); const objectResult = typeof validatorResult === "object"; if (objectResult) { invalid.push(...validatorResult.invalid); if (validatorResult.valid) { cleared[key] = validatorResult.cleared; continue; } else if (hasRequiredInPath(validatorResult.invalid, keyPath)) { continue; } } else if (validatorResult) { cleared[key] = value; continue; } invalid.push( new ValidationError( required3 ? "required" /* Required */ : "invalid" /* Invalid */, validatorOrDefs[descriptionSymbol], value, path, key ) ); } else { const nestedResult = validate(value, validatorOrDefs, keyPath); if (nestedResult.cleared != null) { cleared[key] = nestedResult.cleared; } invalid.push(...nestedResult.invalid); } } for (const key of optionsKeys) { const value = options[key]; if (value === void 0) continue; invalid.push(new UnknownError(unusedKeys, value, path, key)); } return { cleared, invalid }; } function findSuggestions(value, suggestions, maxDistance = 2) { const lowerCaseValue = value.toLowerCase(); const similarValues = similarOptionsMap.get(lowerCaseValue); return suggestions.filter((key) => { const lowerCaseKey = key.toLowerCase(); return similarValues?.has(key) === true || lowerCaseKey.includes(lowerCaseValue) || levenshteinDistance(lowerCaseValue, lowerCaseKey) <= maxDistance; }); } function attachDescription(validatorOrDefs, description) { if (isFunction(validatorOrDefs)) { let clonedValidator2 = function(value, context) { return validatorOrDefs(value, context); }; var clonedValidator = clonedValidator2; clonedValidator2[descriptionSymbol] = description; return clonedValidator2; } else { return { ...validatorOrDefs, [descriptionSymbol]: description }; } } function required(validatorOrDefs) { return Object.assign( isFunction(validatorOrDefs) ? (value, context) => validatorOrDefs(value, context) : optionsDefs(validatorOrDefs), { [requiredSymbol]: true, [descriptionSymbol]: validatorOrDefs[descriptionSymbol] } ); } function undocumented(validatorOrDefs) { return Object.assign( isFunction(validatorOrDefs) ? (value, context) => validatorOrDefs(value, context) : optionsDefs(validatorOrDefs), { [undocumentedSymbol]: true, [descriptionSymbol]: validatorOrDefs[descriptionSymbol] } ); } var optionsDefs = (defs, description = "an object", failAll = false) => attachDescription((value, context) => { const result = validate(value, defs, context.path); const valid = !hasRequiredInPath(result.invalid, context.path); return { valid, cleared: valid || !failAll ? result.cleared : null, invalid: result.invalid }; }, description); var typeUnion = (defs, description, defaultType) => ({ ...defs, [descriptionSymbol]: description, [unionSymbol]: defaultType }); var and = (...validators) => attachDescription( (value, context) => { const invalid = []; for (const validator of validators) { const result = validator(value, context); if (typeof result === "object") { invalid.push(...result.invalid); if (!result.valid) { return { valid: false, cleared: value, invalid }; } value = result.cleared; } else if (!result) { return false; } } return { valid: true, cleared: value, invalid }; }, joinFormatted( validators.filter((v) => !v[undocumentedSymbol]).map((v) => v[descriptionSymbol]).filter(isDefined), "and" ) ); var or = (...validators) => attachDescription( (value, context) => { for (const validator of validators) { const result = validator(value, context); if (typeof result === "object" ? result.valid : result) { return result; } } return false; }, joinFormatted( validators.filter((v) => !v[undocumentedSymbol]).map((v) => v[descriptionSymbol]).filter(isDefined), "or" ) ); var isComparable = (value) => isFiniteNumber(value) || isValidDate(value); var isValidDateValue = (value) => isDate(value) || (isFiniteNumber(value) || isString(value)) && isValidDate(new Date(value)); var array = attachDescription(isArray, "an array"); var boolean = attachDescription(isBoolean, "a boolean"); var callback = attachDescription(isFunction, "a function"); var color = attachDescription(isColor, "a color string"); var date = attachDescription(isValidDateValue, "a date"); var defined = attachDescription(isDefined, "a defined value"); var number = attachDescription(isFiniteNumber, "a number"); var object = attachDescription(isObject, "an object"); var string = attachDescription(isString, "a string"); var htmlElement = attachDescription(isHtmlElement, "an html element"); var arrayLength = (minLength, maxLength = Infinity) => { let message; if (maxLength === Infinity) { message = `an array of at least ${minLength} items`; } else if (minLength === maxLength) { message = `an array of exactly ${minLength} items`; } else if (minLength === 0) { message = `an array of no more than ${maxLength} items`; } else { message = `an array of at least ${minLength} and no more than ${maxLength} items`; } return attachDescription( (value) => isArray(value) && value.length >= minLength && value.length <= maxLength, message ); }; var stringLength = (minLength, maxLength = Infinity) => { let message; if (maxLength === Infinity) { message = `a string of at least ${minLength} characters`; } else if (minLength === maxLength) { message = `an string of exactly ${minLength} characters`; } else if (minLength === 0) { message = `an string of no more than ${maxLength} characters`; } else { message = `an string of at least ${minLength} and no more than ${maxLength} characters`; } return attachDescription( (value) => isString(value) && value.length >= minLength && value.length <= maxLength, message ); }; var numberMin = (min, inclusive = true) => attachDescription( (value) => isFiniteNumber(value) && (value > min || inclusive && value === min), `a number greater than ${inclusive ? "or equal to " : ""}${min}` ); var numberRange = (min, max) => attachDescription( (value) => isFiniteNumber(value) && value >= min && value <= max, `a number between ${min} and ${max} inclusive` ); var positiveNumber = numberMin(0); var positiveNumberNonZero = numberMin(0, false); var ratio = numberRange(0, 1); var lessThan = (otherField) => attachDescription( (value, { options }) => !isComparable(value) || !isComparable(options[otherField]) || value < options[otherField], `the value to be less than \`${otherField}\`` ); var lessThanOrEqual = (otherField) => attachDescription( (value, { options }) => !isComparable(value) || !isComparable(options[otherField]) || value <= options[otherField], `the value to be less than or equal to \`${otherField}\`` ); var greaterThan = (otherField) => attachDescription( (value, { options }) => !isComparable(value) || !isComparable(options[otherField]) || value > options[otherField], `the value to be greater than \`${otherField}\`` ); function union(...allowed) { if (isObject(allowed[0])) { allowed = Object.values(allowed[0]); } const keywords = joinFormatted(allowed, "or", (value) => `'${value}'`); return attachDescription((value) => allowed.includes(value), `a keyword such as ${keywords}`); } function strictUnion() { return union; } var constant = (allowed) => attachDescription((value) => allowed === value, `the value ${JSON.stringify(allowed)}`); var instanceOf = (instanceType, description) => attachDescription((value) => value instanceof instanceType, description ?? `an instance of ${instanceType.name}`); var arrayOf = (validator, description, strict = true) => attachDescription( (value, context) => { if (!isArray(value)) return false; let valid = strict; const cleared = []; const invalid = []; const updateValidity = (result) => { valid = strict ? valid && result : valid || result; }; if (value.length === 0) { return { valid: true, cleared, invalid }; } for (let i = 0; i < value.length; i++) { const options = value[i]; const result = validator(options, { options, path: `${context.path}[${i}]` }); if (typeof result === "object") { updateValidity(result.valid); invalid.push(...result.invalid); if (result.cleared != null) { cleared.push(result.cleared); } } else { updateValidity(result); if (result) { cleared.push(options); } } } return { valid, cleared: valid || !strict ? cleared : null, invalid }; }, description ?? `${validator[descriptionSymbol]} array` ); var arrayOfDefs = (defs, description = "an object array") => attachDescription((value, context) => { if (!isArray(value)) return false; const cleared = []; const invalid = []; for (let i = 0; i < value.length; i++) { const indexPath = `${context.path}[${i}]`; const result = validate(value[i], defs, indexPath); if (!hasRequiredInPath(result.invalid, indexPath)) { cleared.push(result.cleared); } invalid.push(...result.invalid); } return { valid: true, cleared, invalid }; }, description); var callbackOf = (validator, description) => attachDescription((value, context) => { if (!isFunction(value)) return false; if (markedSymbol in value) return true; const validatorDescription = description ?? validator[descriptionSymbol]; const cbWithValidation = Object.assign( (...args) => { const result = safeCall(value, args); if (result == null) return; const validatorResult = validator(result, { options: result, path: "" }); if (typeof validatorResult === "object") { warnCallbackErrors(validatorResult, context, validatorDescription, result); if (validatorResult.valid) { return validatorResult.cleared; } } else if (validatorResult) { return result; } else { warnOnce( `Callback \`${context.path}\` returned an invalid value \`${stringifyValue(result, 50)}\`; expecting ${validatorDescription}, ignoring.` ); } }, { [markedSymbol]: true } ); return { valid: true, cleared: cbWithValidation, invalid: [] }; }, "a function"); var callbackDefs = (defs, description = "an object") => attachDescription((value, context) => { if (!isFunction(value)) return false; if (markedSymbol in value) return true; const validatorDescription = description; const cbWithValidation = Object.assign( (...args) => { const result = safeCall(value, args, context.path); if (result == null) return; const validatorResult = validate(result, defs); warnCallbackErrors(validatorResult, context, validatorDescription, result); return validatorResult.cleared; }, { [markedSymbol]: true } ); return { valid: true, cleared: cbWithValidation, invalid: [] }; }, "a function"); function hasRequiredInPath(errors, rootPath) { return errors.some((error2) => error2.type === "required" /* Required */ && error2.path === rootPath); } function warnCallbackErrors(validatorResult, context, description, result) { if (validatorResult.invalid.length === 0) return; if (isArray(result)) { const expectedDescription = description ?? validatorResult.invalid[0]?.description ?? "a valid value"; return warnOnce( `Callback \`${context.path}\` returned an invalid value \`${stringifyValue(result, 50)}\`; expecting ${expectedDescription}, ignoring.` ); } for (const error2 of validatorResult.invalid) { if (error2 instanceof UnknownError) { return warnOnce( `Callback \`${context.path}\` returned an unknown property \`${extendPath(error2.path, error2.key)}\`${error2.getPostfix()}` ); } const errorValue = stringifyValue(error2.value, 50); warnOnce( error2.key ? `Callback \`${context.path}\` returned an invalid property \`${extendPath(error2.path, error2.key)}\`: \`${errorValue}\`; expecting ${error2.description}, ignoring.` : `Callback \`${context.path}\` returned an invalid value \`${errorValue}\`; expecting ${description ?? error2.description}, ignoring.` ); } } // packages/ag-charts-core/src/utils/data/numbers.ts function clamp(min, value, max) { return Math.min(max, Math.max(min, value)); } function inRange(value, range2, epsilon = 1e-10) { return value >= range2[0] - epsilon && value <= range2[1] + epsilon; } function isNumberEqual(a, b, epsilon = 1e-10) { return a === b || Math.abs(a - b) < epsilon; } function isNegative(value) { return Math.sign(value) === -1 || Object.is(value, -0); } function isInteger(value) { return value % 1 === 0; } function roundTo(value, decimals = 2) { const base = 10 ** decimals; return Math.round(value * base) / base; } function ceilTo(value, decimals = 2) { const base = 10 ** decimals; return Math.ceil(value * base) / base; } function modulus(n, m) { return Math.floor(n % m + (n < 0 ? Math.abs(m) : 0)); } function countFractionDigits(value) { if (Math.floor(value) === value) { return 0; } let valueString = String(value); let exponent = 0; if (value < 1e-6 || value >= 1e21) { let exponentString; [valueString, exponentString] = valueString.split("e"); if (exponentString != null) { exponent = Number(exponentString); } } const decimalPlaces2 = valueString.split(".")[1]?.length ?? 0; return Math.max(decimalPlaces2 - exponent, 0); } // packages/ag-charts-core/src/utils/format/numberFormat.ts var formatRegEx = /^(?:(.)?([<>=^]))?([+\-( ])?([$€£¥₣₹#])?(0)?(\d+)?(,)?(?:\.(\d+))?(~)?([%a-z])?$/i; var surroundedRegEx = /^((?:[^#]|#[^{])*)#{([^}]+)}(.*)$/; function isValidNumberFormat(value) { if (!isString(value)) return false; const match = surroundedRegEx.exec(value); return formatRegEx.test(match ? match[2] : value); } function parseNumberFormat(format) { let prefix; let suffix; const surrounded = surroundedRegEx.exec(format); if (surrounded) { [, prefix, format, suffix] = surrounded; } const match = formatRegEx.exec(format); if (!match) { warnOnce(`The number formatter is invalid: ${format}`); return; } const [, fill, align, sign, symbol, zero, width2, comma, precision, trim, type] = match; return { fill, align, sign, symbol, zero, width: Number.parseInt(width2), comma, precision: Number.parseInt(precision), trim: Boolean(trim), type, prefix, suffix }; } function createNumberFormatter(format) { const options = typeof format === "string" ? parseNumberFormat(format) : format; if (options == null) return; const { fill, align, sign = "-", symbol, zero, width: width2, comma, type, prefix = "", suffix = "", precision } = options; let { trim } = options; const precisionIsNaN = precision == null || Number.isNaN(precision); let formatBody; if (!type) { formatBody = decimalTypes["g"]; trim = true; } else if (type in decimalTypes && type in integerTypes) { formatBody = precisionIsNaN ? integerTypes[type] : decimalTypes[type]; } else if (type in decimalTypes) { formatBody = decimalTypes[type]; } else if (type in integerTypes) { formatBody = integerTypes[type]; } else { throw new Error(`The number formatter type is invalid: ${type}`); } const defaultFormatterPrecision = type ? 6 : 12; let formatterPrecision; if (!precisionIsNaN) { formatterPrecision = precision; } let padAlign = align; let padFill = fill; if (zero) { padFill ?? (padFill = "0"); padAlign ?? (padAlign = "="); } return (n, fractionDigits) => { let effectivePrecision; if (formatterPrecision != null) { effectivePrecision = formatterPrecision; } else if (type === "f" || type === "%") { effectivePrecision = fractionDigits ?? defaultFormatterPrecision; } else if (type) { effectivePrecision = defaultFormatterPrecision; } else { effectivePrecision = fractionDigits ?? defaultFormatterPrecision; } let result = formatBody(n, effectivePrecision); if (trim) { result = removeTrailingZeros(result); } if (comma) { result = insertSeparator(result, comma); } const symbolPrefix = getSymbolPrefix(symbol, type); const symbolPrefixLength = symbolPrefix?.length ?? 0; if (symbolPrefix) { result = `${symbolPrefix}${result}`; } if (type === "s") { result = `${result}${getSIPrefix(n)}`; } if (type === "%" || type === "p") { result = `${result}%`; } const { value: signedResult, prefixLength: signPrefixLength } = addSign(n, result, sign); const totalPrefixLength = signPrefixLength + symbolPrefixLength; let output = signedResult; if (width2 != null && !Number.isNaN(width2)) { output = addPadding(output, width2, padFill ?? " ", padAlign, totalPrefixLength); } output = `${prefix}${output}${suffix}`; return output; }; } var integerTypes = { b: (n) => absFloor(n).toString(2), c: (n) => String.fromCodePoint(n), d: (n) => Math.round(Math.abs(n)).toFixed(0), o: (n) => absFloor(n).toString(8), x: (n) => absFloor(n).toString(16), X: (n) => integerTypes.x(n).toUpperCase(), n: (n) => integerTypes.d(n), "%": (n) => `${absFloor(n * 100).toFixed(0)}` }; var decimalTypes = { e: (n, f) => Math.abs(n).toExponential(f), E: (n, f) => decimalTypes.e(n, f).toUpperCase(), f: (n, f) => Math.abs(n).toFixed(f), F: (n, f) => decimalTypes.f(n, f).toUpperCase(), g: (n, f) => { if (n === 0) { return "0"; } const a = Math.abs(n); const p = Math.floor(Math.log10(a)); if (p >= -4 && p < f) { return a.toFixed(f - 1 - p); } return a.toExponential(f - 1); }, G: (n, f) => decimalTypes.g(n, f).toUpperCase(), n: (n, f) => decimalTypes.g(n, f), p: (n, f) => decimalTypes.r(n * 100, f), r: (n, f) => { if (n === 0) { return "0"; } const a = Math.abs(n); const p = Math.floor(Math.log10(a)); const q = p - (f - 1); if (q <= 0) { return a.toFixed(-q); } const x = 10 ** q; return (Math.round(a / x) * x).toFixed(); }, s: (n, f) => { const p = getSIPrefixPower(n); return decimalTypes.r(n / 10 ** p, f); }, "%": (n, f) => decimalTypes.f(n * 100, f) }; var minSIPrefix = -24; var maxSIPrefix = 24; var siPrefixes = { [minSIPrefix]: "y", [-21]: "z", [-18]: "a", [-15]: "f", [-12]: "p", [-9]: "n", [-6]: "\xB5", [-3]: "m", [0]: "", [3]: "k", [6]: "M", [9]: "G", [12]: "T", [15]: "P", [18]: "E", [21]: "Z", [maxSIPrefix]: "Y" }; var minusSign = "\u2212"; function absFloor(n) { return Math.floor(Math.abs(n)); } function removeTrailingZeros(numString) { if (!numString.endsWith("0") || !numString.includes(".")) return numString; let endIndex = numString.length - 1; while (endIndex > 0) { if (numString[endIndex] == "0") { endIndex -= 1; } else if (numString[endIndex] == ".") { endIndex -= 1; break; } else { break; } } return numString.substring(0, endIndex + 1); } function insertSeparator(numString, separator) { let dotIndex = numString.indexOf("."); if (dotIndex < 0) { dotIndex = numString.length; } const integerChars = numString.substring(0, dotIndex).split(""); const fractionalPart = numString.substring(dotIndex); for (let i = integerChars.length - 3; i > 0; i -= 3) { integerChars.splice(i, 0, separator); } return `${integerChars.join("")}${fractionalPart}`; } function getSIPrefix(n) { return siPrefixes[getSIPrefixPower(n)]; } function getSIPrefixPower(n) { return clamp(minSIPrefix, n ? Math.floor(Math.log10(Math.abs(n)) / 3) * 3 : 0, maxSIPrefix); } function addSign(num, numString, signType = "") { if (signType === "(") { if (num >= 0) { return { value: numString, prefixLength: 0 }; } return { value: `(${numString})`, prefixLength: 1 }; } let signPrefix = ""; if (num < 0) { signPrefix = minusSign; } else if (signType === "+") { signPrefix = "+"; } else if (signType === " ") { signPrefix = " "; } return { value: `${signPrefix}${numString}`, prefixLength: signPrefix.length }; } function addPadding(numString, width2, fill = " ", align = ">", prefixLength = 0) { const padSize = width2 - numString.length; if (padSize <= 0) { return numString; } const padding2 = fill.repeat(padSize); if (align === "=") { const clampedPrefix = Math.min(Math.max(prefixLength, 0), numString.length); const start2 = numString.slice(0, clampedPrefix); const rest = numString.slice(clampedPrefix); return `${start2}${padding2}${rest}`; } if (align === ">" || !align) { return padding2 + numString; } else if (align === "<") { return `${numString}${padding2}`; } else if (align === "^") { const padLeft = Math.ceil(padSize / 2); const padRight = Math.floor(padSize / 2); return `${fill.repeat(padLeft)}${numString}${fill.repeat(padRight)}`; } return padding2 + numString; } function getSymbolPrefix(symbol, type) { if (symbol === "#") { switch (type) { case "b": return "0b"; case "o": return "0o"; case "x": return "0x"; case "X": return "0X"; default: return ""; } } return symbol ?? ""; } // packages/ag-charts-core/src/config/optionsDefaults.ts var themeOperator = (value) => { if (!isObject(value)) return false; const keys = Object.keys(value); return keys.length === 1 && keys[0].startsWith("$"); }; var colorStop = optionsDefs({ color, stop: ratio }, ""); var colorStopsOrderValidator = attachDescription((value) => { let lastStop = -Infinity; for (const item of value) { if (item?.stop != null) { if (item.stop < lastStop) { return false; } lastStop = item.stop; } } return true; }, "colour stops to be defined in ascending order"); var gradientColorStops = and(arrayLength(2), arrayOf(colorStop), colorStopsOrderValidator); var gradientBounds = union("axis", "item", "series"); var gradientStrictDefs = { type: required(constant("gradient")), colorStops: required(gradientColorStops), rotation: number, // @ts-expect-error undocumented option gradient: undocumented(union("linear", "radial", "conic")), bounds: undocumented(gradientBounds), reverse: undocumented(boolean), colorSpace: undocumented(union("rgb", "oklch")) }; var gradientStrict = optionsDefs( gradientStrictDefs, "a gradient object with colour stops" ); var strokeOptionsDef = { stroke: color, strokeWidth: positiveNumber, strokeOpacity: ratio }; var fillGradientDefaults = optionsDefs({ type: required(constant("gradient")), gradient: required(union("linear", "radial", "conic")), bounds: required(gradientBounds), colorStops: required(or(gradientColorStops, and(arrayLength(2), arrayOf(color)))), rotation: required(number), reverse: required(boolean), colorSpace: required(union("rgb", "oklch")) }); var fillPatternDefaults = optionsDefs({ type: required(constant("pattern")), pattern: required( union( "vertical-lines", "horizontal-lines", "forward-slanted-lines", "backward-slanted-lines", "circles", "squares", "triangles", "diamonds", "stars", "hearts", "crosses" ) ), path: stringLength(2), width: required(positiveNumber), height: required(positiveNumber), fill: required(color), fillOpacity: required(ratio), backgroundFill: required(color), backgroundFillOpacity: required(ratio), padding: required(positiveNumber), rotation: required(number), scale: required(positiveNumber), stroke: required(color), strokeWidth: required(positiveNumber), strokeOpacity: required(ratio) }); var fillImageDefaults = optionsDefs({ type: required(constant("image")), url: string, width: positiveNumber, height: positiveNumber, rotation: required(number), backgroundFill: required(color), backgroundFillOpacity: ratio, fit: required(union("stretch", "contain", "cover")), repeat: required(union("repeat", "repeat-x", "repeat-y", "no-repeat")) }); var colorObjectDefs = { // @ts-expect-error undocumented option gradient: { colorStops: gradientColorStops, rotation: number, gradient: undocumented(union("linear", "radial", "conic")), bounds: undocumented(gradientBounds), reverse: undocumented(boolean), colorSpace: undocumented(union("rgb", "oklch")) }, pattern: { pattern: union( "vertical-lines", "horizontal-lines", "forward-slanted-lines", "backward-slanted-lines", "circles", "squares", "triangles", "diamonds", "stars", "hearts", "crosses" ), path: stringLength(2), width: positiveNumber, height: positiveNumber, rotation: number, scale: positiveNumber, fill: color, fillOpacity: ratio, backgroundFill: color, backgroundFillOpacity: ratio, ...strokeOptionsDef, padding: undocumented(positiveNumber) }, image: { url: required(string), backgroundFill: color, backgroundFillOpacity: ratio, width: positiveNumber, height: positiveNumber, fit: union("stretch", "contain", "cover", "none"), repeat: union("repeat", "repeat-x", "repeat-y", "no-repeat"), rotation: number } }; var colorObject = typeUnion(colorObjectDefs, "a color object"); var colorUnion = or(color, optionsDefs(colorObject, "a color object")); var fillOptionsDef = { fill: colorUnion, fillOpacity: ratio }; fillOptionsDef.fillGradientDefaults = undocumented(fillGradientDefaults); fillOptionsDef.fillPatternDefaults = undocumented(fillPatternDefaults); fillOptionsDef.fillImageDefaults = undocumented(fillImageDefaults); var lineDashOptionsDef = { lineDash: arrayOf(positiveNumber), lineDashOffset: number }; var barHighlightOptionsDef = { ...fillOptionsDef, ...strokeOptionsDef, ...lineDashOptionsDef, opacity: ratio, cornerRadius: positiveNumber }; var lineHighlightOptionsDef = { ...strokeOptionsDef, ...lineDashOptionsDef, opacity: ratio }; var shapeHighlightOptionsDef = { ...fillOptionsDef, ...strokeOptionsDef, ...lineDashOptionsDef, opacity: ratio }; function highlightOptionsDef(itemHighlightOptionsDef) { return { enabled: boolean, range: union("tooltip", "node"), highlightedItem: itemHighlightOptionsDef, unhighlightedItem: itemHighlightOptionsDef }; } function multiSeriesHighlightOptionsDef(itemHighlightOptionsDef, seriesHighlightOptionsDef) { return { enabled: boolean, range: union("tooltip", "node"), highlightedItem: itemHighlightOptionsDef, unhighlightedItem: itemHighlightOptionsDef, highlightedSeries: seriesHighlightOptionsDef, unhighlightedSeries: seriesHighlightOptionsDef, bringToFront: boolean }; } var shapeSegmentOptions = { start: defined, stop: defined, ...strokeOptionsDef, ...fillOptionsDef, ...lineDashOptionsDef }; var lineSegmentOptions = { start: defined, stop: defined, ...strokeOptionsDef, ...lineDashOptionsDef }; var shapeSegmentation = optionsDefs( { enabled: boolean, key: required(union("x", "y")), segments: arrayOfDefs(shapeSegmentOptions, "path segments array") }, "a segmentation object", true ); var lineSegmentation = optionsDefs( { enabled: boolean, key: required(union("x", "y")), segments: arrayOfDefs(lineSegmentOptions, "path segments array") }, "a segmentation object", true ); var googleFont = optionsDefs({ googleFont: string }, "google font"); var fontFamilyFull = or(string, themeOperator, googleFont, arrayOf(or(string, googleFont))); var fontWeight = or(positiveNumber, union("normal", "bold", "bolder", "lighter")); var fontOptionsDef = { color, fontFamily: fontFamilyFull, fontSize: positiveNumber, fontStyle: union("normal", "italic", "oblique"), fontWeight }; var paddingOptions = optionsDefs( { top: number, right: number, bottom: number, left: number }, "padding object" ); var padding = or(number, paddingOptions); var borderOptionsDef = { enabled: boolean, stroke: color, strokeWidth: positiveNumber, strokeOpacity: ratio }; var labelBoxOptionsDef = { border: borderOptionsDef, cornerRadius: number, padding, ...fillOptionsDef }; // packages/ag-charts-core/src/config/chartDefaults.ts var legendPlacementLiterals = [ "top", "top-right", "top-left", "bottom", "bottom-right", "bottom-left", "right", "right-top", "right-bottom", "left", "left-top", "left-bottom" ]; var legendPositionOptionsDef = { floating: boolean, placement: union(...legendPlacementLiterals), xOffset: number, yOffset: number }; var legendPositionValidator = attachDescription( (value, context) => { let result; if (typeof value === "string") { const allowedValues = legendPlacementLiterals; if (allowedValues.includes(value)) { result = true; } else { result = { valid: false, invalid: [], cleared: null }; result.invalid.push( new ValidationError( "invalid" /* Invalid */, `a legend placement string: ["${legendPlacementLiterals.join('", "')}"]`, value, context.path ) ); } } else { const { cleared, invalid } = validate(value, legendPositionOptionsDef); result = { valid: invalid.length === 0, cleared, invalid }; } return result; }, `a legend position object or placement string` ); var shapeValidator = or( union("circle", "cross", "diamond", "heart", "plus", "pin", "square", "star", "triangle"), callback ); var textWrapValidator = union("never", "always", "hyphenate", "on-space"); var tooltipPlacementValidator = union( "top", "right", "bottom", "left", "top-right", "bottom-right", "bottom-left", "top-left", "center" ); var rangeValidator = or(positiveNumber, union("exact", "nearest", "area")); var seriesTooltipRangeValidator = or(positiveNumber, union("exact", "nearest")); var textOrSegments = or( string, number, date, arrayOfDefs( { text: required(string), ...fontOptionsDef }, "text segments array" ) ); var chartCaptionOptionsDefs = { enabled: boolean, text: textOrSegments, textAlign: union("left", "center", "right"), wrapping: union("never", "always", "hyphenate", "on-space"), spacing: positiveNumber, maxWidth: positiveNumber, maxHeight: positiveNumber, ...fontOptionsDef }; chartCaptionOptionsDefs.padding = undocumented(positiveNumber); var chartOverlayOptionsDefs = { enabled: boolean, text: textOrSegments, renderer: callbackOf(or(string, htmlElement)) }; var contextMenuItemLiterals = [ "defaults", "download", "zoom-to-cursor", "pan-to-cursor", "reset-zoom", "toggle-series-visibility", "toggle-other-series", "separator" ]; var contextMenuItemObjectDef = { type: union("action", "separator"), showOn: union("always", "series-area", "series-node", "legend-item"), label: required(string), enabled: boolean, action: callback, items: (value, context) => contextMenuItemsArray(value, context) }; contextMenuItemObjectDef.iconUrl = undocumented(string); var contextMenuItemObjectValidator = optionsDefs(contextMenuItemObjectDef); var contextMenuItemValidator = attachDescription( (value, context) => { let result; if (typeof value === "string") { const allowedValues = contextMenuItemLiterals; if (allowedValues.includes(value)) { result = true; } else { result = { valid: false, invalid: [], cleared: null }; result.invalid.push( new ValidationError( "invalid" /* Invalid */, `a context menu item string alias: ["${contextMenuItemLiterals.join('", "')}"]`, value, context.path ) ); } } else { result = contextMenuItemObjectValidator(value, context); } return result; }, `a context menu item object or string alias: [${contextMenuItemLiterals.join(", ")}]` ); var contextMenuItemsArray = arrayOf(contextMenuItemValidator, "a menu items array", false); var toolbarButtonOptionsDefs = { label: string, ariaLabel: string, tooltip: string, icon: union( "align-center", "align-left", "align-right", "arrow-drawing", "arrow-down-drawing", "arrow-up-drawing", "callout-annotation", "candlestick-series", "close", "comment-annotation", "date-range-drawing", "date-price-range-drawing", "delete", "disjoint-channel-drawing", "drag-handle", "fill-color", "line-style-solid", "line-style-dashed", "line-style-dotted", "high-low-series", "hlc-series", "hollow-candlestick-series", "horizontal-line-drawing", "line-color", "line-series", "line-with-markers-series", "locked", "measurer-drawing", "note-annotation", "ohlc-series", "pan-end", "pan-left", "pan-right", "pan-start", "parallel-channel-drawing", "position-bottom", "position-center", "position-top", "price-label-annotation", "price-range-drawing", "reset", "settings", "step-line-series", "text-annotation", "trend-line-drawing", "fibonacci-retracement-drawing", "fibonacci-retracement-trend-based-drawing", "unlocked", "vertical-line-drawing", "zoom-in", "zoom-out" ) }; var formatter = or(string, callbackOf(textOrSegments)); var formatObjectValidator = optionsDefs({ x: formatter, y: formatter, angle: formatter, radius: formatter, size: formatter, color: formatter, label: formatter, secondaryLabel: formatter, sectorLabel: formatter, calloutLabel: formatter, legendItem: formatter }); var numberFormatValidator = attachDescription(isValidNumberFormat, "a valid number format string"); var commonChartOptionsDefs = { width: positiveNumber, height: positiveNumber, minWidth: positiveNumber, minHeight: positiveNumber, suppressFieldDotNotation: boolean, title: chartCaptionOptionsDefs, subtitle: chartCaptionOptionsDefs, footnote: chartCaptionOptionsDefs, padding: { top: positiveNumber, right: positiveNumber, bottom: positiveNumber, left: positiveNumber }, seriesArea: { border: borderOptionsDef, clip: boolean, cornerRadius: number, padding }, legend: { enabled: boolean, position: legendPositionValidator, orientation: union("horizontal", "vertical"), maxWidth: positiveNumber, maxHeight: positiveNumber, spacing: positiveNumber, border: borderOptionsDef, cornerRadius: number, padding, fill: colorUnion, fillOpacity: ratio, preventHidingAll: boolean, reverseOrder: boolean, toggleSeries: boolean, item: { marker: { size: positiveNumber, shape: shapeValidator, padding: positiveNumber, strokeWidth: positiveNumber }, line: { length: positiveNumber, strokeWidth: positiveNumber }, label: { maxLength: positiveNumber, formatter: callback, ...fontOptionsDef }, maxWidth: positiveNumber, paddingX: positiveNumber, paddingY: positiveNumber, showSeriesStroke: boolean }, pagination: { marker: { size: positiveNumber, shape: shapeValidator, padding: positiveNumber }, activeStyle: { ...fillOptionsDef, ...strokeOptionsDef }, inactiveStyle: { ...fillOptionsDef, ...strokeOptionsDef }, highlightStyle: { ...fillOptionsDef, ...strokeOptionsDef }, label: fontOptionsDef }, listeners: { legendItemClick: callback, legendItemDoubleClick: callback } }, gradientLegend: { enabled: boolean, position: legendPositionValidator, spacing: positiveNumber, reverseOrder: boolean, border: borderOptionsDef, cornerRadius: number, padding, fill: colorUnion, fillOpacity: ratio, gradient: { preferredLength: positiveNumber, thickness: positiveNumber }, scale: { label: { ...fontOptionsDef, minSpacing: positiveNumber, format: numberFormatValidator, formatter: callback }, padding: positiveNumber, interval: { step: number, values: array, minSpacing: and(positiveNumber, lessThan("maxSpacing")), maxSpacing: and(positiveNumber, greaterThan("minSpacing")) } } }, listeners: { seriesNodeClick: callback, seriesNodeDoubleClick: callback, seriesVisibilityChange: callback, activeChange: callback, click: callback, doubleClick: callback, annotations: callback, zoom: callback }, loadGoogleFonts: boolean, highlight: { drawingMode: union("overlay", "cutout"), range: union("tooltip", "node") }, overlays: { loading: chartOverlayOptionsDefs, noData: chartOverlayOptionsDefs, noVisibleSeries: chartOverlayOptionsDefs, unsupportedBrowser: chartOverlayOptionsDefs }, tooltip: { enabled: boolean, showArrow: boolean, pagination: boolean, delay: positiveNumber, range: rangeValidator, wrapping: textWrapValidator, mode: union("single", "shared", "compact"), position: { anchorTo: union("pointer", "node", "chart"), placement: or(tooltipPlacementValidator, arrayOf(tooltipPlacementValidator)), xOffset: number, yOffset: number } }, animation: defined, contextMenu: defined, context: () => true, dataSource: { getData: callback }, keyboard: { enabled: boolean, tabIndex: number }, touch: { dragAction: union("none", "drag", "hover") }, ranges: { enabled: boolean, buttons: arrayOfDefs( { ...toolbarButtonOptionsDefs, value: or(number, and(arrayOf(or(number, date)), arrayLength(2, 2)), callback) }, "range button options array" ) }, // modules locale: { localeText: object, getLocaleText: callbackOf(string) }, background: { visible: boolean, fill: color, // enterprise image: { url: required(string), top: number, right: number, bottom: number, left: number, width: positiveNumber, height: positiveNumber, opacity: ratio } }, styleNonce: string, sync: defined, zoom: defined, scrollbar: defined, formatter: or(callbackOf(textOrSegments), formatObjectValidator) }; commonChartOptionsDefs.flashOnUpdate = undocumented(defined); commonChartOptionsDefs.dataSource.requestThrottle = undocumented(positiveNumber); commonChartOptionsDefs.dataSource.updateThrottle = undocumented(positiveNumber); commonChartOptionsDefs.dataSource.updateDuringInteraction = undocumented(boolean); commonChartOptionsDefs.statusBar = undocumented(defined); commonChartOptionsDefs.foreground = undocumented({ visible: boolean, text: string, image: { url: string, top: number, right: number, bottom: number, left: number, width: positiveNumber, height: positiveNumber, opacity: ratio }, ...fillOptionsDef }); commonChartOptionsDefs.overrideDevicePixelRatio = undocumented(number); commonChartOptionsDefs.sync.domainMode = undocumented(union("direction", "position", "key")); commonChartOptionsDefs.displayNullData = undocumented(boolean); var commonSeriesThemeableOptionsDefs = { cursor: string, context: () => true, showInLegend: boolean, nodeClickRange: rangeValidator, listeners: { seriesNodeClick: callback, seriesNodeDoubleClick: callback }, highlight: highlightOptionsDef(shapeHighlightOptionsDef) }; commonSeriesThemeableOptionsDefs.allowNullKeys = undocumented(boolean); var commonSeriesOptionsDefs = { ...commonSeriesThemeableOptionsDefs, id: string, visible: boolean, context: () => true, data: array }; commonSeriesOptionsDefs.seriesGrouping = undocumented(defined); var markerStyleOptionsDefs = { shape: shapeValidator, size: positiveNumber, ...fillOptionsDef, ...strokeOptionsDef, ...lineDashOptionsDef }; var markerOptionsDefs = { enabled: boolean, itemStyler: callbackDefs({ ...fillOptionsDef, ...strokeOptionsDef, ...lineDashOptionsDef, shape: shapeValidator, size: positiveNumber }), ...markerStyleOptionsDefs }; var seriesLabelOptionsDefs = { enabled: boolean, formatter: callbackOf(textOrSegments), format: numberFormatValidator, itemStyler: callbackDefs({ enabled: boolean, ...labelBoxOptionsDef, ...fontOptionsDef }), ...labelBoxOptionsDef, ...fontOptionsDef }; var autoSizedLabelOptionsDefs = { ...seriesLabelOptionsDefs, lineHeight: positiveNumber, minimumFontSize: positiveNumber, wrapping: textWrapValidator, overflowStrategy: union("ellipsis", "hide") }; var errorBarThemeableOptionsDefs = { visible: boolean, cap: { visible: boolean, length: positiveNumber, lengthRatio: ratio, ...strokeOptionsDef, ...lineDashOptionsDef }, ...strokeOptionsDef, ...lineDashOptionsDef }; var errorBarOptionsDefs = { ...errorBarThemeableOptionsDefs, xLowerKey: string, xUpperKey: string, yLowerKey: string, yUpperKey: string, xLowerName: string, xUpperName: string, yLowerName: string, yUpperName: string, itemStyler: callbackDefs({ visible: boolean, ...strokeOptionsDef, ...lineDashOptionsDef, cap: { visible: boolean, length: positiveNumber, lengthRatio: ratio, ...strokeOptionsDef, ...lineDashOptionsDef } }) }; var tooltipOptionsDefs = { enabled: boolean, showArrow: boolean, range: seriesTooltipRangeValidator, renderer: callbackOf( or( string, number, date, optionsDefs( { heading: string, title: string, symbol: { marker: { enabled: boolean, shape: shapeValidator, ...fillOptionsDef, stroke: color, strokeOpacity: ratio, strokeWidth: positiveNumber, ...lineDashOptionsDef }, line: { enabled: boolean, stroke: color, strokeWidth: positiveNumber, strokeOpacity: ratio, ...lineDashOptionsDef } }, data: arrayOfDefs({ label: required(string), value: required(or(string, number, date)) }) }, "tooltip renderer result object" ) ) ), position: { anchorTo: union("node", "pointer", "chart"), placement: or(tooltipPlacementValidator, arrayOf(tooltipPlacementValidator)), xOffset: number, yOffset: number }, interaction: { enabled: boolean } }; var tooltipOptionsDefsWithArea = { ...tooltipOptionsDefs, range: rangeValidator }; var shadowOptionsDefs = { enabled: boolean, xOffset: number, yOffset: number, blur: positiveNumber, color }; var interpolationOptionsDefs = typeUnion( { linear: {}, smooth: { tension: ratio }, step: { position: union("start", "middle", "end") } }, "interpolation line options" ); // packages/ag-charts-core/src/utils/types/decorator.ts var BREAK_TRANSFORM_CHAIN = Symbol("BREAK"); var CONFIG_KEY = "__decorator_config"; var ACCESSORS_KEY = "__decorator_accessors"; function addFakeTransformToInstanceProperty(target, propertyKeyOrSymbol) { initialiseConfig(target, propertyKeyOrSymbol).optional = true; } function initialiseConfig(target, propertyKeyOrSymbol) { if (Object.getOwnPropertyDescriptor(target, CONFIG_KEY) == null) { Object.defineProperty(target, CONFIG_KEY, { value: {} }); } if (Object.getOwnPropertyDescriptor(target, ACCESSORS_KEY) == null) { const parentAccessors = Object.getPrototypeOf(target)?.[ACCESSORS_KEY]; const accessors = parentAccessors?.slice() ?? []; Object.defineProperty(target, ACCESSORS_KEY, { value: accessors }); } const config = target[CONFIG_KEY]; const propertyKey = propertyKeyOrSymbol.toString(); if (config[propertyKey] != null) { return config[propertyKey]; } config[propertyKey] = { setters: [], getters: [], observers: [] }; const descriptor = Object.getOwnPropertyDescriptor(target, propertyKeyOrSymbol); let prevGet = descriptor?.get; let prevSet = descriptor?.set; if (prevGet == null || prevSet == null) { const accessors = target[ACCESSORS_KEY]; let index = accessors.indexOf(propertyKeyOrSymbol); if (index === -1) { index = accessors.push(propertyKeyOrSymbol) - 1; } prevGet ?? (prevGet = function() { let accessorValues = this.__accessors; if (accessorValues == null) { accessorValues = accessors.slice().fill(void 0); Object.defineProperty(this, "__accessors", { value: accessorValues }); } return accessorValues[index]; }); prevSet ?? (prevSet = function(value) { let accessorValues = this.__accessors; if (accessorValues == null) { accessorValues = accessors.slice().fill(void 0); Object.defineProperty(this, "__accessors", { value: accessorValues }); } accessorValues[index] = value; }); } const getter = function() { let value = prevGet.call(this); for (const transformFn of config[propertyKey].getters) { value = transformFn(this, propertyKeyOrSymbol, value); if (value === BREAK_TRANSFORM_CHAIN) { return; } } return value; }; const setter = function(value) { const { setters, observers } = config[propertyKey]; let oldValue; if (setters.some((f) => f.length > 2)) { oldValue = prevGet.call(this); } for (const transformFn of setters) { value = transformFn(this, propertyKeyOrSymbol, value, oldValue); if (value === BREAK_TRANSFORM_CHAIN) { return; } } prevSet.call(this, value); for (const observerFn of observers) { observerFn(this, value, oldValue); } }; Object.defineProperty(target, propertyKeyOrSymbol, { set: setter, get: getter, enumerable: true, configurable: false }); return config[propertyKey]; } function addTransformToInstanceProperty(setTransform, getTransform, configMetadata) { return (target, propertyKeyOrSymbol) => { const config = initialiseConfig(target, propertyKeyOrSymbol); config.setters.push(setTransform); if (getTransform) { config.getters.unshift(getTransform); } if (configMetadata) { Object.assign(config, configMetadata); } }; } function addObserverToInstanceProperty(setObserver) { return (target, propertyKeyOrSymbol) => { initialiseConfig(target, propertyKeyOrSymbol).observers.push(setObserver); }; } function isDecoratedObject(target) { return target !== void 0 && CONFIG_KEY in target; } function listDecoratedProperties(target) { const targets = /* @__PURE__ */ new Set(); while (isDecoratedObject(target)) { targets.add(target?.[CONFIG_KEY]); target = Object.getPrototypeOf(target); } return Array.from(targets).flatMap((configMap) => Object.keys(configMap)); } function extractDecoratedProperties(target) { return listDecoratedProperties(target).reduce((result, key) => { result[String(key)] = target[key] ?? null; return result; }, {}); } // packages/ag-charts-core/src/utils/data/iterators.ts function* iterate(...items) { for (const item of items) { if (item == null) continue; if (item[Symbol.iterator]) { yield* item; } else { yield item; } } } function toIterable(value) { return value != null && typeof value === "object" && Symbol.iterator in value ? value : [value]; } function first(iterable) { for (const value of iterable) { return value; } throw new Error("AG Charts - no first() value found"); } function* entries(obj) { const resultTuple = [void 0, void 0]; for (const key of Object.keys(obj)) { resultTuple[0] = key; resultTuple[1] = obj[key]; yield resultTuple; } } // packages/ag-charts-core/src/utils/data/object.ts function strictObjectKeys(o) { return Object.keys(o); } function objectsEqual(a, b) { if (Array.isArray(a)) { if (!Array.isArray(b)) return false; if (a.length !== b.length) return false; return a.every((av, i) => objectsEqual(av, b[i])); } else if (isPlainObject(a)) { if (!isPlainObject(b)) return false; return objectsEqualWith(a, b, objectsEqual); } return a === b; } function objectsEqualWith(a, b, cmp) { if (Object.is(a, b)) return true; for (const key of Object.keys(b)) { if (!(key in a)) return false; } for (const key of Object.keys(a)) { if (!(key in b)) return false; if (!cmp(a[key], b[key])) return false; } return true; } function mergeDefaults(...sources) { const target = {}; for (const source of sources) { if (!isObject(source)) continue; const keys = isDecoratedObject(source) ? listDecoratedProperties(source) : Object.keys(source); for (const key of keys) { if (isPlainObject(target[key]) && isPlainObject(source[key])) { target[key] = mergeDefaults(target[key], source[key]); } else { target[key] ?? (target[key] = source[key]); } } } return target; } function merge(...sources) { const target = {}; for (const source of sources) { if (!isObject(source)) continue; const keys = isDecoratedObject(source) ? listDecoratedProperties(source) : Object.keys(source); for (const key of keys) { if (isPlainObject(target[key]) && isPlainObject(source[key])) { target[key] = merge(target[key], source[key]); } else if (!(key in target)) { target[key] ?? (target[key] = source[key]); } } } return target; } function mergeArrayDefaults(dataArray, ...itemDefaults) { if (itemDefaults && isArray(dataArray)) { return dataArray.map((item) => mergeDefaults(item, ...itemDefaults)); } return dataArray; } function mapValues(object2, mapper) { const result = {}; for (const [key, value] of entries(object2)) { result[key] = mapper(value, key, object2); } return result; } function without(object2, keys) { const clone2 = { ...object2 }; for (const key of keys) { delete clone2[key]; } return clone2; } function pick(object2, keys) { if (object2 == null) return; const picked = {}; for (const key of keys) { if (Object.hasOwn(object2, key)) { picked[key] = object2[key]; } } return picked; } function every(object2, fn) { if (object2 == null) return true; for (const [key, value] of entries(object2)) { if (!fn(key, value)) return false; } return true; } function fromPairs(pairs) { const object2 = {}; if (pairs == null) return object2; for (const [key, value] of pairs) { object2[key] = value; } return object2; } function getPath(object2, path) { const pathArray = isArray(path) ? path : path.split("."); return pathArray.reduce((value, pathKey) => value[pathKey], object2); } var SKIP_JS_BUILTINS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]); function setPath(object2, path, newValue) { const pathArray = isArray(path) ? path.slice() : path.split("."); const lastKey = pathArray.pop(); if (pathArray.some((p) => SKIP_JS_BUILTINS.has(p))) return; const lastObject = pathArray.reduce((value, pathKey) => value[pathKey], object2); lastObject[lastKey] = newValue; return lastObject[lastKey]; } function partialAssign(keysToCopy, target, source) { if (source === void 0) { return target; } for (const key of keysToCopy) { const value = source[key]; if (value !== void 0) { target[key] = value; } } return target; } function assignIfNotStrictlyEqual(target, source, keys) { const sourceKeys = keys ?? Object.keys(source); for (let i = 0, len = sourceKeys.length; i < len; i++) { const key = sourceKeys[i]; const newValue = source[key]; if (target[key] !== newValue) { target[key] = newValue; } } return target; } function deepFreeze(obj) { if (obj == null || typeof obj !== "object" || !isPlainObject(obj)) { return obj; } Object.freeze(obj); for (const prop of Object.getOwnPropertyNames(obj)) { const value = obj[prop]; if (value !== null && (typeof value === "object" || typeof value === "function") && !Object.isFrozen(value)) { deepFreeze(value); } } return obj; } function isObjectWithProperty(obj, key) { return isPlainObject(obj) && key in obj; } function isObjectWithStringProperty(obj, key) { return isObjectWithProperty(obj, key) && typeof obj[key] === "string"; } // packages/ag-charts-core/src/config/gaugePreset.ts var fillsOptionsDef = { fills: and( arrayLength(2), arrayOf(optionsDefs({ color, stop: number }, "")), colorStopsOrderValidator ), fillMode: union("continuous", "discrete") }; var linearGaugeTargetOptionsDef = { value: required(number), text: string, shape: or( union("circle", "cross", "diamond", "heart", "plus", "pin", "square", "star", "triangle", "line"), callback ), placement: union("before", "after", "middle"), spacing: positiveNumber, size: positiveNumber, rotation: number, ...fillOptionsDef, ...strokeOptionsDef, ...lineDashOptionsDef }; var radialGaugeTargetOptionsDef = { value: required(number), text: string, shape: or( union("circle", "cross", "diamond", "heart", "plus", "pin", "square", "star", "triangle", "line"), callback ), placement: union("inside", "outside", "middle"), spacing: positiveNumber, size: positiveNumber, rotation: number, label: { ...seriesLabelOptionsDefs, spacing: positiveNumber }, ...fillOptionsDef, ...strokeOptionsDef, ...lineDashOptionsDef }; var linearGaugeSeriesThemeableOptionsDef = { ...without(commonSeriesThemeableOptionsDefs, ["listeners"]), direction: union("horizontal", "vertical"), cornerMode: union("container", "item"), cornerRadius: positiveNumber, thickness: positiveNumber, segmentation: { enabled: boolean, spacing: positiveNumber, interval: { values: arrayOf(number), step: number, count: number } }, bar: { enabled: boolean, thickness: positiveNumber, thicknessRatio: ratio, ...fillsOptionsDef, ...fillOptionsDef, ...strokeOptionsDef, ...lineDashOptionsDef }, label: { ...autoSizedLabelOptionsDefs, text: string, spacing: positiveNumber, avoidCollisions: boolean, placement: union( "inside-start", "outside-start", "inside-end", "outside-end", "inside-center", "bar-inside", "bar-inside-end", "bar-outside-end", "bar-end" ) }, tooltip: tooltipOptionsDefs }; var linearGaugeSeriesOptionsDef = { ...without(commonSeriesOptionsDefs, ["listeners"]), ...linearGaugeSeriesThemeableOptionsDef, type: required(constant("linear-gauge")), value: required(number), scale: { min: and(number, lessThan("max")), max: and(number, greaterThan("min")), label: { enabled: boolean, formatter: callback, rotation: number, spacing: positiveNumber, minSpacing: positiveNumber, placement: union("before", "after"), avoidCollisions: boolean, format: numberFormatValidator, ...fontOptionsDef }, interval: { values: arrayOf(number), step: number }, ...fillsOptionsDef, ...fillOptionsDef, ...strokeOptionsDef, ...lineDashOptionsDef }, targets: arrayOfDefs(linearGaugeTargetOptionsDef, "target options array") }; linearGaugeSeriesOptionsDef.margin = undocumented(number); linearGaugeSeriesOptionsDef.defaultColorRange = undocumented(arrayOf(color)); linearGaugeSeriesOptionsDef.defaultTarget = undocumented({ ...linearGaugeTargetOptionsDef, value: number, label: { ...seriesLabelOptionsDefs, spacing: number } }); linearGaugeSeriesOptionsDef.defaultScale = undocumented(linearGaugeSeriesOptionsDef.scale); linearGaugeSeriesOptionsDef.scale.defaultFill = undocumented(color); var radialGaugeSeriesThemeableOptionsDef = { ...without(commonSeriesThemeableOptionsDefs, ["listeners"]), outerRadius: positiveNumber, innerRadius: positiveNumber, outerRadiusRatio: ratio, innerRadiusRatio: ratio, startAngle: number, endAngle: number, spacing: positiveNumber, cornerMode: union("container", "item"), cornerRadius: positiveNumber, scale: { min: and(number, lessThan("max")), max: and(number, greaterThan("min")), label: { enabled: boolean, formatter: callback, rotation: number, spacing: positiveNumber, minSpacing: positiveNumber, avoidCollisions: boolean, format: numberFormatValidator, ...fontOptionsDef }, interval: { values: arrayOf(number), step: number }, ...fillsOptionsDef, ...fillOptionsDef, ...strokeOptionsDef, ...lineDashOptionsDef }, segmentation: { enabled: boolean, spacing: positiveNumber, interval: { values: arrayOf(number), step: number, count: number } }, bar: { enabled: boolean, ...fillsOptionsDef, ...fillOptionsDef, ...strokeOptionsDef, ...lineDashOptionsDef }, needle: { enabled: boolean, spacing: positiveNumber, radiusRatio: ratio, ...fillOptionsDef, ...strokeOptionsDef, ...lineDashOptionsDef }, label: { text: string, spacing: positiveNumber, ...autoSizedLabelOptionsDefs }, secondaryLabel: { text: string, ...autoSizedLabelOptionsDefs }, tooltip: tooltipOptionsDefs }; var radialGaugeSeriesOptionsDef = { ...without(commonSeriesOptionsDefs, ["listeners"]), ...radialGaugeSeriesThemeableOptionsDef, type: required(constant("radial-gauge")), value: required(number), targets: arrayOfDefs(radialGaugeTargetOptionsDef, "target options array") }; radialGaugeSeriesOptionsDef.defaultColorRange = undocumented(arrayOf(color)); radialGaugeSeriesOptionsDef.defaultTarget = undocumented({ ...radialGaugeTargetOptionsDef, value: number, label: { ...seriesLabelOptionsDefs, spacing: number } }); radialGaugeSeriesOptionsDef.scale.defaultFill = undocumented(color); // packages/ag-charts-core/src/types/themeConstants.ts var FONT_SIZE = /* @__PURE__ */ ((FONT_SIZE2) => { FONT_SIZE2[FONT_SIZE2["SMALLEST"] = 8] = "SMALLEST"; FONT_SIZE2[FONT_SIZE2["SMALLER"] = 10] = "SMALLER"; FONT_SIZE2[FONT_SIZE2["SMALL"] = 12] = "SMALL"; FONT_SIZE2[FONT_SIZE2["MEDIUM"] = 13] = "MEDIUM"; FONT_SIZE2[FONT_SIZE2["LARGE"] = 14] = "LARGE"; FONT_SIZE2[FONT_SIZE2["LARGEST"] = 17] = "LARGEST"; return FONT_SIZE2; })(FONT_SIZE || {}); var BASE_FONT_SIZE = 12 /* SMALL */; var FONT_SIZE_RATIO = { SMALLEST: 8 /* SMALLEST */ / BASE_FONT_SIZE, SMALLER: 10 /* SMALLER */ / BASE_FONT_SIZE, SMALL: 12 /* SMALL */ / BASE_FONT_SIZE, MEDIUM: 13 /* MEDIUM */ / BASE_FONT_SIZE, LARGE: 14 /* LARGE */ / BASE_FONT_SIZE, LARGEST: 17 /* LARGEST */ / BASE_FONT_SIZE }; var CARTESIAN_POSITION = /* @__PURE__ */ ((CARTESIAN_POSITION2) => { CARTESIAN_POSITION2["TOP"] = "top"; CARTESIAN_POSITION2["TOP_RIGHT"] = "top-right"; CARTESIAN_POSITION2["TOP_LEFT"] = "top-left"; CARTESIAN_POSITION2["RIGHT"] = "right"; CARTESIAN_POSITION2["RIGHT_TOP"] = "right-top"; CARTESIAN_POSITION2["RIGHT_BOTTOM"] = "right-bottom"; CARTESIAN_POSITION2["BOTTOM"] = "bottom"; CARTESIAN_POSITION2["BOTTOM_RIGHT"] = "bottom-right"; CARTESIAN_POSITION2["BOTTOM_LEFT"] = "bottom-left"; CARTESIAN_POSITION2["LEFT"] = "left"; CARTESIAN_POSITION2["LEFT_TOP"] = "left-top"; CARTESIAN_POSITION2["LEFT_BOTTOM"] = "left-bottom"; return CARTESIAN_POSITION2; })(CARTESIAN_POSITION || {}); var CARTESIAN_AXIS_TYPE = /* @__PURE__ */ ((CARTESIAN_AXIS_TYPE2) => { CARTESIAN_AXIS_TYPE2["CATEGORY"] = "category"; CARTESIAN_AXIS_TYPE2["GROUPED_CATEGORY"] = "grouped-category"; CARTESIAN_AXIS_TYPE2["ORDINAL_TIME"] = "ordinal-time"; CARTESIAN_AXIS_TYPE2["UNIT_TIME"] = "unit-time"; CARTESIAN_AXIS_TYPE2["TIME"] = "time"; CARTESIAN_AXIS_TYPE2["NUMBER"] = "number"; CARTESIAN_AXIS_TYPE2["LOG"] = "log"; return CARTESIAN_AXIS_TYPE2; })(CARTESIAN_AXIS_TYPE || {}); var POLAR_AXIS_TYPE = /* @__PURE__ */ ((POLAR_AXIS_TYPE2) => { POLAR_AXIS_TYPE2["ANGLE_CATEGORY"] = "angle-category"; POLAR_AXIS_TYPE2["ANGLE_NUMBER"] = "angle-number"; POLAR_AXIS_TYPE2["RADIUS_CATEGORY"] = "radius-category"; POLAR_AXIS_TYPE2["RADIUS_NUMBER"] = "radius-number"; return POLAR_AXIS_TYPE2; })(POLAR_AXIS_TYPE || {}); var POLAR_AXIS_SHAPE = /* @__PURE__ */ ((POLAR_AXIS_SHAPE2) => { POLAR_AXIS_SHAPE2["CIRCLE"] = "circle"; POLAR_AXIS_SHAPE2["POLYGON"] = "polygon"; return POLAR_AXIS_SHAPE2; })(POLAR_AXIS_SHAPE || {}); // packages/ag-charts-core/src/utils/format/color.ts var lerp = (x, y, t) => x * (1 - t) + y * t; var srgbToLinear = (value) => { const sign = value < 0 ? -1 : 1; const abs = Math.abs(value); if (abs <= 0.04045) return value / 12.92; return sign * ((abs + 0.055) / 1.055) ** 2.4; }; var srgbFromLinear = (value) => { const sign = value < 0 ? -1 : 1; const abs = Math.abs(value); if (abs > 31308e-7) { return sign * (1.055 * abs ** (1 / 2.4) - 0.055); } return 12.92 * value; }; var _Color = class _Color { /** * Every color component should be in the [0, 1] range. * Some easing functions (such as elastic easing) can overshoot the target value by some amount. * So, when animating colors, if the source or target color components are already near * or at the edge of the allowed [0, 1] range, it is possible for the intermediate color * component value to end up outside of that range mid-animation. For this reason the constructor * performs range checking/constraining. * @param r Red component. * @param g Green component. * @param b Blue component. * @param a Alpha (opacity) component. */ constructor(r, g, b, a = 1) { this.r = clamp(0, r || 0, 1); this.g = clamp(0, g || 0, 1); this.b = clamp(0, b || 0, 1); this.a = clamp(0, a || 0, 1); } /** * A color string can be in one of the following formats to be valid: * - #rgb * - #rrggbb * - rgb(r, g, b) * - rgba(r, g, b, a) * - CSS color name such as 'white', 'orange', 'cyan', etc. */ static validColorString(str) { if (str.includes("#")) { return !!_Color.parseHex(str); } if (str.includes("rgb")) { return !!_Color.stringToRgba(str); } return _Color.nameToHex.has(str.toLowerCase()); } /** * The given string can be in one of the following formats: * - #rgb * - #rrggbb * - rgb(r, g, b) * - rgba(r, g, b, a) * - CSS color name such as 'white', 'orange', 'cyan', etc. * @param str */ static fromString(str) { if (str.includes("#")) { return _Color.fromHexString(str); } const hex = _Color.nameToHex.get(str.toLowerCase()); if (hex) { return _Color.fromHexString(hex); } if (str.includes("rgb")) { return _Color.fromRgbaString(str); } throw new Error(`Invalid color string: '${str}'`); } // See https://drafts.csswg.org/css-color/#hex-notation static parseHex(input) { input = input.replaceAll(" ", "").slice(1); let parts; switch (input.length) { case 6: case 8: parts = []; for (let i = 0; i < input.length; i += 2) { parts.push(Number.parseInt(`${input[i]}${input[i + 1]}`, 16)); } break; case 3: case 4: parts = input.split("").map((p) => Number.parseInt(p, 16)).map((p) => p + p * 16); break; } if (parts?.length >= 3 && parts.every((p) => p >= 0)) { if (parts.length === 3) { parts.push(255); } return parts; } } static fromHexString(str) { const values = _Color.parseHex(str); if (values) { const [r, g, b, a] = values; return new _Color(r / 255, g / 255, b / 255, a / 255); } throw new Error(`Malformed hexadecimal color string: '${str}'`); } static stringToRgba(str) { let po = -1; let pc = -1; for (let i = 0; i < str.length; i++) { const c = str[i]; if (po === -1 && c === "(") { po = i; } else if (c === ")") { pc = i; break; } } if (po === -1 || pc === -1) return; const contents = str.substring(po + 1, pc); const parts = contents.split(","); const rgba = []; for (let i = 0; i < parts.length; i++) { const part = parts[i]; let value = Number.parseFloat(part); if (!Number.isFinite(value)) { return; } if (part.includes("%")) { value = clamp(0, value, 100); value /= 100; } else if (i === 3) { value = clamp(0, value, 1); } else { value = clamp(0, value, 255); value /= 255; } rgba.push(value); } return rgba; } static fromRgbaString(str) { const rgba = _Color.stringToRgba(str); if (rgba) { if (rgba.length === 3) { return new _Color(rgba[0], rgba[1], rgba[2]); } else if (rgba.length === 4) { return new _Color(rgba[0], rgba[1], rgba[2], rgba[3]); } } throw new Error(`Malformed rgb/rgba color string: '${str}'`); } static fromArray(arr) { if (arr.length === 4) { return new _Color(arr[0], arr[1], arr[2], arr[3]); } if (arr.length === 3) { return new _Color(arr[0], arr[1], arr[2]); } throw new Error("The given array should contain 3 or 4 color components (numbers)."); } static fromHSB(h, s, b, alpha = 1) { const rgb = _Color.HSBtoRGB(h, s, b); return new _Color(rgb[0], rgb[1], rgb[2], alpha); } static fromHSL(h, s, l, alpha = 1) { const rgb = _Color.HSLtoRGB(h, s, l); return new _Color(rgb[0], rgb[1], rgb[2], alpha); } static fromOKLCH(l, c, h, alpha = 1) { const rgb = _Color.OKLCHtoRGB(l, c, h); return new _Color(rgb[0], rgb[1], rgb[2], alpha); } static padHex(str) { return str.length === 1 ? "0" + str : str; } toHexString() { let hex = "#" + _Color.padHex(Math.round(this.r * 255).toString(16)) + _Color.padHex(Math.round(this.g * 255).toString(16)) + _Color.padHex(Math.round(this.b * 255).toString(16)); if (this.a < 1) { hex += _Color.padHex(Math.round(this.a * 255).toString(16)); } return hex; } toRgbaString(fractionDigits = 3) { const components = [Math.round(this.r * 255), Math.round(this.g * 255), Math.round(this.b * 255)]; const k = Math.pow(10, fractionDigits); if (this.a !== 1) { components.push(Math.round(this.a * k) / k); return `rgba(${components.join(", ")})`; } return `rgb(${components.join(", ")})`; } toString() { if (this.a === 1) { return this.toHexString(); } return this.toRgbaString(); } toHSB() { return _Color.RGBtoHSB(this.r, this.g, this.b); } static RGBtoOKLCH(r, g, b) { const LSRGB0 = srgbToLinear(r); const LSRGB1 = srgbToLinear(g); const LSRGB2 = srgbToLinear(b); const LMS0 = Math.cbrt(0.4122214708 * LSRGB0 + 0.5363325363 * LSRGB1 + 0.0514459929 * LSRGB2); const LMS1 = Math.cbrt(0.2119034982 * LSRGB0 + 0.6806995451 * LSRGB1 + 0.1073969566 * LSRGB2); const LMS2 = Math.cbrt(0.0883024619 * LSRGB0 + 0.2817188376 * LSRGB1 + 0.6299787005 * LSRGB2); const OKLAB0 = 0.2104542553 * LMS0 + 0.793617785 * LMS1 - 0.0040720468 * LMS2; const OKLAB1 = 1.9779984951 * LMS0 - 2.428592205 * LMS1 + 0.4505937099 * LMS2; const OKLAB2 = 0.0259040371 * LMS0 + 0.7827717662 * LMS1 - 0.808675766 * LMS2; const hue = Math.atan2(OKLAB2, OKLAB1) * 180 / Math.PI; const OKLCH0 = OKLAB0; const OKLCH1 = Math.hypot(OKLAB1, OKLAB2); const OKLCH2 = hue >= 0 ? hue : hue + 360; return [OKLCH0, OKLCH1, OKLCH2]; } static OKLCHtoRGB(l, c, h) { const OKLAB0 = l; const OKLAB1 = c * Math.cos(h * Math.PI / 180); const OKLAB2 = c * Math.sin(h * Math.PI / 180); const LMS0 = (OKLAB0 + 0.3963377774 * OKLAB1 + 0.2158037573 * OKLAB2) ** 3; const LMS1 = (OKLAB0 - 0.1055613458 * OKLAB1 - 0.0638541728 * OKLAB2) ** 3; const LMS2 = (OKLAB0 - 0.0894841775 * OKLAB1 - 1.291485548 * OKLAB2) ** 3; const LSRGB0 = 4.0767416621 * LMS0 - 3.3077115913 * LMS1 + 0.2309699292 * LMS2; const LSRGB1 = -1.2684380046 * LMS0 + 2.6097574011 * LMS1 - 0.3413193965 * LMS2; const LSRGB2 = -0.0041960863 * LMS0 - 0.7034186147 * LMS1 + 1.707614701 * LMS2; const SRGB0 = srgbFromLinear(LSRGB0); const SRGB1 = srgbFromLinear(LSRGB1); const SRGB2 = srgbFromLinear(LSRGB2); return [SRGB0, SRGB1, SRGB2]; } static RGBtoHSL(r, g, b) { const min = Math.min(r, g, b); const max = Math.max(r, g, b); const l = (max + min) / 2; let h; let s; if (max === min) { h = 0; s = 0; } else { const delta = max - min; s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min); if (max === r) { h = (g - b) / delta + (g < b ? 6 : 0); } else if (max === g) { h = (b - r) / delta + 2; } else { h = (r - g) / delta + 4; } h *= 360 / 6; } return [h, s, l]; } static HSLtoRGB(h, s, l) { h = (h % 360 + 360) % 360; if (s === 0) { return [l, l, l]; } const q = l < 0.5 ? l * (1 + s) : l + s - l * s; const p = 2 * l - q; function hueToRgb(t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; } const r = hueToRgb(h / 360 + 1 / 3); const g = hueToRgb(h / 360); const b = hueToRgb(h / 360 - 1 / 3); return [r, g, b]; } /** * Converts the given RGB triple to an array of HSB (HSV) components. */ static RGBtoHSB(r, g, b) { const min = Math.min(r, g, b); const max = Math.max(r, g, b); const S = max === 0 ? 0 : (max - min) / max; let H = 0; if (min !== max) { const delta = max - min; const rc = (max - r) / delta; const gc = (max - g) / delta; const bc = (max - b) / delta; if (r === max) { H = bc - gc; } else if (g === max) { H = 2 + rc - bc; } else { H = 4 + gc - rc; } H /= 6; if (H < 0) { H = H + 1; } } return [H * 360, S, max]; } /** * Converts the given HSB (HSV) triple to an array of RGB components. */ static HSBtoRGB(H, S, B) { H = (H % 360 + 360) % 360 / 360; let r = 0; let g = 0; let b = 0; if (S === 0) { r = g = b = B; } else { const h = (H - Math.floor(H)) * 6; const f = h - Math.floor(h); const p = B * (1 - S); const q = B * (1 - S * f); const t = B * (1 - S * (1 - f)); switch (Math.trunc(h)) { case 0: r = B; g = t; b = p; break; case 1: r = q; g = B; b = p; break; case 2: r = p; g = B; b = t; break; case 3: r = p; g = q; b = B; break; case 4: r = t; g = p; b = B; break; case 5: r = B; g = p; b = q; break; } } return [r, g, b]; } static mix(c0, c1, t) { return new _Color(lerp(c0.r, c1.r, t), lerp(c0.g, c1.g, t), lerp(c0.b, c1.b, t), lerp(c0.a, c1.a, t)); } static lighten(c, t) { const oklch = _Color.RGBtoOKLCH(c.r, c.g, c.b); return _Color.fromOKLCH(clamp(0, oklch[0] + t, 1), oklch[1], oklch[2]); } static darken(c, t) { const oklch = _Color.RGBtoOKLCH(c.r, c.g, c.b); return _Color.fromOKLCH(clamp(0, oklch[0] - t, 1), oklch[1], oklch[2]); } static interpolate(colors, count) { const step = 1 / (colors.length - 1); const oklchColors = colors.map((c) => _Color.RGBtoOKLCH(c.r, c.g, c.b)); return Array.from({ length: count }, (_, i) => { const t = i / (count - 1); const index = colors.length <= 2 ? 0 : Math.min(Math.floor(t * (colors.length - 1)), colors.length - 2); const q = (t - index * step) / step; const c0 = oklchColors[index]; const c1 = oklchColors[index + 1]; return _Color.fromOKLCH(lerp(c0[0], c1[0], q), lerp(c0[1], c1[1], q), lerp(c0[2], c1[2], q)); }); } }; /** * CSS Color Module Level 4: * https://drafts.csswg.org/css-color/#named-colors */ _Color.nameToHex = /* @__PURE__ */ new Map([ ["aliceblue", "#F0F8FF"], ["antiquewhite", "#FAEBD7"], ["aqua", "#00FFFF"], ["aquamarine", "#7FFFD4"], ["azure", "#F0FFFF"], ["beige", "#F5F5DC"], ["bisque", "#FFE4C4"], ["black", "#000000"], ["blanchedalmond", "#FFEBCD"], ["blue", "#0000FF"], ["blueviolet", "#8A2BE2"], ["brown", "#A52A2A"], ["burlywood", "#DEB887"], ["cadetblue", "#5F9EA0"], ["chartreuse", "#7FFF00"], ["chocolate", "#D2691E"], ["coral", "#FF7F50"], ["cornflowerblue", "#6495ED"], ["cornsilk", "#FFF8DC"], ["crimson", "#DC143C"], ["cyan", "#00FFFF"], ["darkblue", "#00008B"], ["darkcyan", "#008B8B"], ["darkgoldenrod", "#B8860B"], ["darkgray", "#A9A9A9"], ["darkgreen", "#006400"], ["darkgrey", "#A9A9A9"], ["darkkhaki", "#BDB76B"], ["darkmagenta", "#8B008B"], ["darkolivegreen", "#556B2F"], ["darkorange", "#FF8C00"], ["darkorchid", "#9932CC"], ["darkred", "#8B0000"], ["darksalmon", "#E9967A"], ["darkseagreen", "#8FBC8F"], ["darkslateblue", "#483D8B"], ["darkslategray", "#2F4F4F"], ["darkslategrey", "#2F4F4F"], ["darkturquoise", "#00CED1"], ["darkviolet", "#9400D3"], ["deeppink", "#FF1493"], ["deepskyblue", "#00BFFF"], ["dimgray", "#696969"], ["dimgrey", "#696969"], ["dodgerblue", "#1E90FF"], ["firebrick", "#B22222"], ["floralwhite", "#FFFAF0"], ["forestgreen", "#228B22"], ["fuchsia", "#FF00FF"], ["gainsboro", "#DCDCDC"], ["ghostwhite", "#F8F8FF"], ["gold", "#FFD700"], ["goldenrod", "#DAA520"], ["gray", "#808080"], ["green", "#008000"], ["greenyellow", "#ADFF2F"], ["grey", "#808080"], ["honeydew", "#F0FFF0"], ["hotpink", "#FF69B4"], ["indianred", "#CD5C5C"], ["indigo", "#4B0082"], ["ivory", "#FFFFF0"], ["khaki", "#F0E68C"], ["lavender", "#E6E6FA"], ["lavenderblush", "#FFF0F5"], ["lawngreen", "#7CFC00"], ["lemonchiffon", "#FFFACD"], ["lightblue", "#ADD8E6"], ["lightcoral", "#F08080"], ["lightcyan", "#E0FFFF"], ["lightgoldenrodyellow", "#FAFAD2"], ["lightgray", "#D3D3D3"], ["lightgreen", "#90EE90"], ["lightgrey", "#D3D3D3"], ["lightpink", "#FFB6C1"], ["lightsalmon", "#FFA07A"], ["lightseagreen", "#20B2AA"], ["lightskyblue", "#87CEFA"], ["lightslategray", "#778899"], ["lightslategrey", "#778899"], ["lightsteelblue", "#B0C4DE"], ["lightyellow", "#FFFFE0"], ["lime", "#00FF00"], ["limegreen", "#32CD32"], ["linen", "#FAF0E6"], ["magenta", "#FF00FF"], ["maroon", "#800000"], ["mediumaquamarine", "#66CDAA"], ["mediumblue", "#0000CD"], ["mediumorchid", "#BA55D3"], ["mediumpurple", "#9370DB"], ["mediumseagreen", "#3CB371"], ["mediumslateblue", "#7B68EE"], ["mediumspringgreen", "#00FA9A"], ["mediumturquoise", "#48D1CC"], ["mediumvioletred", "#C71585"], ["midnightblue", "#191970"], ["mintcream", "#F5FFFA"], ["mistyrose", "#FFE4E1"], ["moccasin", "#FFE4B5"], ["navajowhite", "#FFDEAD"], ["navy", "#000080"], ["oldlace", "#FDF5E6"], ["olive", "#808000"], ["olivedrab", "#6B8E23"], ["orange", "#FFA500"], ["orangered", "#FF4500"], ["orchid", "#DA70D6"], ["palegoldenrod", "#EEE8AA"], ["palegreen", "#98FB98"], ["paleturquoise", "#AFEEEE"], ["palevioletred", "#DB7093"], ["papayawhip", "#FFEFD5"], ["peachpuff", "#FFDAB9"], ["peru", "#CD853F"], ["pink", "#FFC0CB"], ["plum", "#DDA0DD"], ["powderblue", "#B0E0E6"], ["purple", "#800080"], ["rebeccapurple", "#663399"], ["red", "#FF0000"], ["rosybrown", "#BC8F8F"], ["royalblue", "#4169E1"], ["saddlebrown", "#8B4513"], ["salmon", "#FA8072"], ["sandybrown", "#F4A460"], ["seagreen", "#2E8B57"], ["seashell", "#FFF5EE"], ["sienna", "#A0522D"], ["silver", "#C0C0C0"], ["skyblue", "#87CEEB"], ["slateblue", "#6A5ACD"], ["slategray", "#708090"], ["slategrey", "#708090"], ["snow", "#FFFAFA"], ["springgreen", "#00FF7F"], ["steelblue", "#4682B4"], ["tan", "#D2B48C"], ["teal", "#008080"], ["thistle", "#D8BFD8"], ["tomato", "#FF6347"], ["transparent", "#00000000"], ["turquoise", "#40E0D0"], ["violet", "#EE82EE"], ["wheat", "#F5DEB3"], ["white", "#FFFFFF"], ["whitesmoke", "#F5F5F5"], ["yellow", "#FFFF00"], ["yellowgreen", "#9ACD32"] ]); var Color = _Color; // packages/ag-charts-core/src/config/themeUtil.ts var DIRECTION_SWAP_AXES = { x: { position: "bottom" /* BOTTOM */, type: { $if: [ { $eq: [{ $path: ["/series/0/direction", void 0] }, "horizontal"] }, "number" /* NUMBER */, "category" /* CATEGORY */ ] } }, y: { position: "left" /* LEFT */, type: { $if: [ { $eq: [{ $path: ["/series/0/direction", void 0] }, "horizontal"] }, "category" /* CATEGORY */, "number" /* NUMBER */ ] } } }; var SAFE_FILL_OPERATION = { $if: [ { $or: [ { $isGradient: { $palette: "fill" } }, { $isPattern: { $palette: "fill" } }, { $isImage: { $value: "$1" } } ] }, { $palette: "fillFallback" }, { $palette: "fill" } ] }; var SAFE_FILLS_OPERATION = { $if: [ { $or: [ { $isGradient: { $palette: "fill" } }, { $isPattern: { $palette: "fill" } }, { $isImage: { $value: "$1" } } ] }, { $palette: "fillsFallback" }, { $palette: "fills" } ] }; var SAFE_STROKE_FILL_OPERATION = { $if: [ { $isGradient: { $palette: "fill" } }, { $palette: "fillFallback" }, { $if: [ { $isPattern: { $palette: "fill" } }, { $path: ["/stroke", { $palette: "fillFallback" }, { $palette: "fill" }] }, { $palette: "fill" } ] } ] }; var SAFE_RANGE2_OPERATION = { $if: [ { $or: [ { $isGradient: { $palette: "fill" } }, { $isPattern: { $palette: "fill" } }, { $isImage: { $value: "$1" } } ] }, [{ $palette: "fillFallback" }, { $palette: "fillFallback" }], { $palette: "range2" } ] }; var FILL_GRADIENT_BLANK_DEFAULTS = { type: "gradient", gradient: "linear", bounds: "item", colorStops: [{ color: "black" }], rotation: 0, reverse: false, colorSpace: "rgb" }; var FILL_GRADIENT_LINEAR_DEFAULTS = { type: "gradient", gradient: "linear", bounds: "item", colorStops: { $shallow: { $map: [{ color: { $value: "$1" } }, { $palette: "gradient" }] } }, rotation: 0, reverse: false, colorSpace: "rgb" }; var FILL_GRADIENT_LINEAR_HIERARCHY_DEFAULTS = { ...FILL_GRADIENT_LINEAR_DEFAULTS, colorStops: { $shallow: [ { color: { $mix: [{ $path: ["/1", { $palette: "fill" }, { $palette: "hierarchyColors" }] }, "black", 0.15] } }, { color: { $mix: [{ $path: ["/1", { $palette: "fill" }, { $palette: "hierarchyColors" }] }, "white", 0.15] } } ] } }; var FILL_GRADIENT_LINEAR_SINGLE_DEFAULTS = { ...FILL_GRADIENT_LINEAR_DEFAULTS, colorStops: { $map: [{ color: { $value: "$1" } }, { $path: ["/0", void 0, { $palette: "gradients" }] }] } }; var FILL_GRADIENT_LINEAR_KEYED_DEFAULTS = (key) => ({ ...FILL_GRADIENT_LINEAR_DEFAULTS, colorStops: { $shallow: { $if: [ { $or: [ { $isGradient: { $palette: `${key}.fill` } }, { $isPattern: { $palette: `${key}.fill` } }, { $isImage: { $palette: `${key}.fill` } } ] }, { $path: ["/colorStops", void 0, { $palette: `${key}.fill` }] }, [ { color: { $mix: [{ $palette: `${key}.fill` }, "black", 0.15] } }, { color: { $mix: [{ $palette: `${key}.fill` }, "white", 0.15] } } ] ] } } }); var FILL_GRADIENT_RADIAL_DEFAULTS = { type: "gradient", gradient: "radial", bounds: "item", colorStops: { $shallow: { $map: [{ color: { $value: "$1" } }, { $palette: "gradient" }] } }, rotation: 0, reverse: false, colorSpace: "rgb" }; var FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS = { ...FILL_GRADIENT_RADIAL_DEFAULTS, reverse: true }; var FILL_GRADIENT_RADIAL_SERIES_DEFAULTS = { ...FILL_GRADIENT_RADIAL_DEFAULTS, bounds: "series" }; var FILL_GRADIENT_RADIAL_REVERSED_SERIES_DEFAULTS = { ...FILL_GRADIENT_RADIAL_DEFAULTS, bounds: "series", reverse: true }; var FILL_GRADIENT_CONIC_SERIES_DEFAULTS = { type: "gradient", gradient: "conic", bounds: "series", colorStops: { $map: [{ color: { $value: "$1" } }, { $palette: "gradient" }] }, rotation: 0, reverse: false, colorSpace: "rgb" }; var FILL_PATTERN_DEFAULTS = { type: "pattern", pattern: "forward-slanted-lines", width: { $isUserOption: ["./height", { $path: "./height" }, 10] }, height: { $isUserOption: ["./width", { $path: "./width" }, 10] }, padding: 2, fill: { $if: [ { $or: [{ $isGradient: { $palette: "fill" } }, { $isImage: { $palette: "fill" } }] }, { $palette: "fillFallback" }, { $if: [ { $isPattern: { $palette: "fill" } }, { $path: ["/fill", { $palette: "fillFallback" }, { $palette: "fill" }] }, { $palette: "fill" } ] } ] }, fillOpacity: 1, stroke: SAFE_STROKE_FILL_OPERATION, strokeOpacity: 1, strokeWidth: { $switch: [ { $path: "./pattern" }, 0, [["backward-slanted-lines", "forward-slanted-lines", "horizontal-lines", "vertical-lines"], 4] ] }, backgroundFill: "none", backgroundFillOpacity: 1, rotation: 0, scale: 1 }; var FILL_PATTERN_SINGLE_DEFAULTS = { ...FILL_PATTERN_DEFAULTS, stroke: { $if: [ { $isGradient: { $palette: "fill" } }, { $path: ["/0", void 0, { $palette: "fillsFallback" }] }, { $if: [ { $isPattern: { $palette: "fill" } }, { $path: [ "/stroke", { $path: ["/0", void 0, { $palette: "fillsFallback" }] }, { $path: ["/0", void 0, { $palette: "fills" }] } ] }, { $path: ["/0", void 0, { $palette: "fills" }] } ] } ] }, fill: { $if: [ { $or: [{ $isGradient: { $palette: "fill" } }, { $isImage: { $palette: "fill" } }] }, { $path: ["/0", void 0, { $palette: "fillsFallback" }] }, { $if: [ { $isPattern: { $palette: "fill" } }, { $path: [ "/fill", { $path: ["/0", void 0, { $palette: "fillsFallback" }] }, { $path: ["/0", void 0, { $palette: "fills" }] } ] }, { $path: ["/0", void 0, { $palette: "fills" }] } ] } ] } }; var FILL_PATTERN_BLANK_DEFAULTS = { type: "pattern", pattern: "forward-slanted-lines", width: 8, height: 8, padding: 1, fill: "black", fillOpacity: 1, backgroundFill: "white", backgroundFillOpacity: 1, stroke: "black", strokeOpacity: 1, strokeWidth: 1, rotation: 0, scale: 1 }; var FILL_PATTERN_HIERARCHY_DEFAULTS = { ...FILL_PATTERN_DEFAULTS, fill: { $path: ["/1", { $palette: "fill" }, { $palette: "hierarchyColors" }] }, stroke: { $path: ["/1", { $palette: "fill" }, { $palette: "hierarchyColors" }] } }; var FILL_PATTERN_KEYED_DEFAULTS = (key) => ({ ...FILL_PATTERN_DEFAULTS, stroke: { $if: [ { $isGradient: { $palette: `${key}.fill` } }, { $palette: "fillFallback" }, { $if: [ { $isPattern: { $palette: `${key}.fill` } }, { $path: ["/stroke", { $palette: "fillFallback" }, { $palette: `${key}.fill` }] }, { $palette: `${key}.fill` } ] } ] } }); var FILL_IMAGE_DEFAULTS = { type: "image", backgroundFill: { $palette: "fillFallback" }, backgroundFillOpacity: 1, repeat: "no-repeat", fit: "contain", rotation: 0 }; var FILL_IMAGE_BLANK_DEFAULTS = { type: "image", backgroundFill: "black", backgroundFillOpacity: 1, rotation: 0, repeat: "no-repeat", fit: "contain", width: 8, height: 8 }; function getSequentialColors(colors) { return mapValues(colors, (value) => { const color2 = Color.fromString(value); return [Color.darken(color2, 0.15).toString(), value, Color.lighten(color2, 0.15).toString()]; }); } var LABEL_BOXING_DEFAULTS = { padding: 8, cornerRadius: 4, fill: { $if: [ { $and: [ { $eq: [{ $path: "./fill/type" }, "image"] }, { $isUserOption: ["./fill/backgroundFill", false, true] } ] }, { backgroundFill: "transparent" }, void 0 ] }, border: { enabled: { $isUserOption: ["../border", true, false] }, strokeWidth: 1, stroke: { $foregroundOpacity: 0.08 } } }; var MULTI_SERIES_HIGHLIGHT_STYLE = { enabled: true, unhighlightedItem: { opacity: 0.6 }, unhighlightedSeries: { opacity: 0.2 } }; var MARKER_SERIES_HIGHLIGHT_STYLE = { enabled: true, unhighlightedSeries: { opacity: 0.2 } }; var PART_WHOLE_HIGHLIGHT_STYLE = { enabled: true, unhighlightedItem: { opacity: 0.2 }, unhighlightedSeries: { opacity: 0.2 } }; var SINGLE_SERIES_HIGHLIGHT_STYLE = { enabled: true, unhighlightedItem: { opacity: 0.2 } }; var LEGEND_CONTAINER_THEME = { border: { enabled: false, stroke: { $foregroundBackgroundMix: 0.25 }, strokeOpacity: 1, strokeWidth: 1 }, cornerRadius: 4, fillOpacity: 1, padding: { $if: [{ $eq: [{ $path: "./border/enabled" }, true] }, 5, { $isUserOption: ["./fill", 5, 0] }] } }; var SEGMENTATION_DEFAULTS = { enabled: false, key: "x", segments: { $apply: { fill: { $applySwitch: [ { $path: "type" }, { $path: "../../../fill" }, ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS], ["image", FILL_IMAGE_DEFAULTS], ["pattern", FILL_PATTERN_DEFAULTS] ] }, stroke: { $path: "../../../stroke" }, fillOpacity: { $path: "../../../fillOpacity" }, strokeWidth: { $isUserOption: [ "./stroke", { $isUserOption: [ "../../../strokeWidth", { $path: "../../../strokeWidth" }, { $if: [ { $greaterThan: [{ $path: "../../../strokeWidth" }, 0] }, { $path: "../../../strokeWidth" }, 2 ] } ] }, { $path: "../../../strokeWidth" } ] }, strokeOpacity: { $path: "../../../strokeOpacity" }, lineDash: { $path: "../../../lineDash" }, lineDashOffset: { $path: "../../../lineDashOffset" } } } }; // packages/ag-charts-core/src/state/memento.ts var MementoCaretaker = class _MementoCaretaker { constructor(version) { this.version = version.split("-")[0]; } save(...originators) { const packet = { version: this.version }; for (const originator of Object.values(originators)) { packet[originator.mementoOriginatorKey] = this.encode(originator, originator.createMemento()); } return packet; } restore(blob, ...originators) { if (typeof blob !== "object") { warnOnce(`Could not restore data of type [${typeof blob}], expecting an object, ignoring.`); return; } if (blob == null) { warnOnce(`Could not restore data of type [null], expecting an object, ignoring.`); return; } if (!("version" in blob) || typeof blob.version !== "string") { warnOnce(`Could not restore data, missing [version] string in object, ignoring.`); return; } for (const originator of originators) { const memento = this.decode(originator, blob[originator.mementoOriginatorKey]); const messages = []; if (!originator.guardMemento(memento, messages)) { const messagesString = messages.length > 0 ? ` ${messages.join("\n\n")} ` : ""; warnOnce( `Could not restore [${originator.mementoOriginatorKey}] data, value was invalid, ignoring.${messagesString}`, memento ); return; } originator.restoreMemento(this.version, blob.version, memento); } } /** * Encode a memento as a serializable object, encoding any non-serializble types. */ encode(originator, memento) { try { return JSON.parse(JSON.stringify(memento, _MementoCaretaker.encodeTypes)); } catch (error2) { throw new Error(`Failed to encode [${originator.mementoOriginatorKey}] value [${error2}].`, { cause: error2 }); } } /** * Decode an encoded memento, decoding any non-serializable types. */ decode(originator, encoded) { if (encoded == null) return encoded; try { return JSON.parse(JSON.stringify(encoded), _MementoCaretaker.decodeTypes); } catch (error2) { throw new Error(`Failed to decode [${originator.mementoOriginatorKey}] value [${error2}].`, { cause: error2 }); } } static encodeTypes(key, value) { if (isDate(this[key])) { return { __type: "date", value: this[key].toISOString() }; } return value; } static decodeTypes(key, value) { if (isObject(this[key]) && "__type" in this[key] && this[key].__type === "date") { return new Date(this[key].value); } return value; } }; // packages/ag-charts-core/src/types/axisDirection.ts var ChartAxisDirection = /* @__PURE__ */ ((ChartAxisDirection2) => { ChartAxisDirection2["X"] = "x"; ChartAxisDirection2["Y"] = "y"; ChartAxisDirection2["Angle"] = "angle"; ChartAxisDirection2["Radius"] = "radius"; return ChartAxisDirection2; })(ChartAxisDirection || {}); // packages/ag-charts-core/src/types/updateType.ts var ChartUpdateType = /* @__PURE__ */ ((ChartUpdateType2) => { ChartUpdateType2[ChartUpdateType2["FULL"] = 0] = "FULL"; ChartUpdateType2[ChartUpdateType2["UPDATE_DATA"] = 1] = "UPDATE_DATA"; ChartUpdateType2[ChartUpdateType2["PROCESS_DATA"] = 2] = "PROCESS_DATA"; ChartUpdateType2[ChartUpdateType2["PROCESS_DOMAIN"] = 3] = "PROCESS_DOMAIN"; ChartUpdateType2[ChartUpdateType2["PROCESS_RANGE"] = 4] = "PROCESS_RANGE"; ChartUpdateType2[ChartUpdateType2["PERFORM_LAYOUT"] = 5] = "PERFORM_LAYOUT"; ChartUpdateType2[ChartUpdateType2["PRE_SERIES_UPDATE"] = 6] = "PRE_SERIES_UPDATE"; ChartUpdateType2[ChartUpdateType2["SERIES_UPDATE"] = 7] = "SERIES_UPDATE"; ChartUpdateType2[ChartUpdateType2["PRE_SCENE_RENDER"] = 8] = "PRE_SCENE_RENDER"; ChartUpdateType2[ChartUpdateType2["SCENE_RENDER"] = 9] = "SCENE_RENDER"; ChartUpdateType2[ChartUpdateType2["NONE"] = 10] = "NONE"; return ChartUpdateType2; })(ChartUpdateType || {}); // packages/ag-charts-core/src/types/zIndexMap.ts var ZIndexMap = /* @__PURE__ */ ((ZIndexMap2) => { ZIndexMap2[ZIndexMap2["CHART_BACKGROUND"] = 0] = "CHART_BACKGROUND"; ZIndexMap2[ZIndexMap2["AXIS_BAND_HIGHLIGHT"] = 1] = "AXIS_BAND_HIGHLIGHT"; ZIndexMap2[ZIndexMap2["AXIS_GRID"] = 2] = "AXIS_GRID"; ZIndexMap2[ZIndexMap2["AXIS"] = 3] = "AXIS"; ZIndexMap2[ZIndexMap2["SERIES_AREA_CONTAINER"] = 4] = "SERIES_AREA_CONTAINER"; ZIndexMap2[ZIndexMap2["ZOOM_SELECTION"] = 5] = "ZOOM_SELECTION"; ZIndexMap2[ZIndexMap2["SERIES_CROSSLINE_RANGE"] = 6] = "SERIES_CROSSLINE_RANGE"; ZIndexMap2[ZIndexMap2["SERIES_LAYER"] = 7] = "SERIES_LAYER"; ZIndexMap2[ZIndexMap2["AXIS_FOREGROUND"] = 8] = "AXIS_FOREGROUND"; ZIndexMap2[ZIndexMap2["SERIES_CROSSHAIR"] = 9] = "SERIES_CROSSHAIR"; ZIndexMap2[ZIndexMap2["SERIES_CROSSLINE_LINE"] = 10] = "SERIES_CROSSLINE_LINE"; ZIndexMap2[ZIndexMap2["SERIES_ANNOTATION"] = 11] = "SERIES_ANNOTATION"; ZIndexMap2[ZIndexMap2["CHART_ANNOTATION"] = 12] = "CHART_ANNOTATION"; ZIndexMap2[ZIndexMap2["CHART_ANNOTATION_FOCUSED"] = 13] = "CHART_ANNOTATION_FOCUSED"; ZIndexMap2[ZIndexMap2["STATUS_BAR"] = 14] = "STATUS_BAR"; ZIndexMap2[ZIndexMap2["SERIES_LABEL"] = 15] = "SERIES_LABEL"; ZIndexMap2[ZIndexMap2["LEGEND"] = 16] = "LEGEND"; ZIndexMap2[ZIndexMap2["NAVIGATOR"] = 17] = "NAVIGATOR"; ZIndexMap2[ZIndexMap2["FOREGROUND"] = 18] = "FOREGROUND"; return ZIndexMap2; })(ZIndexMap || {}); var SeriesZIndexMap = /* @__PURE__ */ ((SeriesZIndexMap2) => { SeriesZIndexMap2[SeriesZIndexMap2["BACKGROUND"] = 0] = "BACKGROUND"; SeriesZIndexMap2[SeriesZIndexMap2["ANY_CONTENT"] = 1] = "ANY_CONTENT"; return SeriesZIndexMap2; })(SeriesZIndexMap || {}); var SeriesContentZIndexMap = /* @__PURE__ */ ((SeriesContentZIndexMap2) => { SeriesContentZIndexMap2[SeriesContentZIndexMap2["FOREGROUND"] = 0] = "FOREGROUND"; SeriesContentZIndexMap2[SeriesContentZIndexMap2["HIGHLIGHT"] = 1] = "HIGHLIGHT"; SeriesContentZIndexMap2[SeriesContentZIndexMap2["LABEL"] = 2] = "LABEL"; return SeriesContentZIndexMap2; })(SeriesContentZIndexMap || {}); var PolarZIndexMap = /* @__PURE__ */ ((PolarZIndexMap2) => { PolarZIndexMap2[PolarZIndexMap2["BACKGROUND"] = 0] = "BACKGROUND"; PolarZIndexMap2[PolarZIndexMap2["FOREGROUND"] = 1] = "FOREGROUND"; PolarZIndexMap2[PolarZIndexMap2["HIGHLIGHT"] = 2] = "HIGHLIGHT"; PolarZIndexMap2[PolarZIndexMap2["LABEL"] = 3] = "LABEL"; return PolarZIndexMap2; })(PolarZIndexMap || {}); // packages/ag-charts-core/src/chart/legendUtil.ts function expandLegendPosition(position) { const { placement = "bottom", floating = false, xOffset = 0, yOffset = 0 } = typeof position === "string" ? { placement: position, floating: false } : position; return { placement, floating, xOffset, yOffset }; } // packages/ag-charts-core/src/state/properties.ts var BaseProperties = class { handleUnknownProperties(_unknownKeys, _properties) { } set(properties) { const { className = this.constructor.name } = this.constructor; if (properties == null) { this.clear(); return this; } if (typeof properties !== "object") { warn(`unable to set ${className} - expecting a properties object`); return this; } const keys = new Set(Object.keys(properties)); for (const propertyKey of listDecoratedProperties(this)) { if (keys.has(propertyKey)) { const value = properties[propertyKey]; const self = this; if (isProperties(self[propertyKey])) { if (self[propertyKey] instanceof PropertiesArray) { const array2 = self[propertyKey].reset(value); if (array2 == null) { warn(`unable to set [${String(propertyKey)}] - expecting a properties array`); } else { self[propertyKey] = array2; } } else { self[propertyKey].set(value); } } else if (isPlainObject(value)) { self[propertyKey] = merge(value, self[propertyKey] ?? {}); } else { self[propertyKey] = value; } keys.delete(propertyKey); } } this.handleUnknownProperties(keys, properties); for (const unknownKey of keys) { warn(`unable to set [${String(unknownKey)}] in ${className} - property is unknown`); } return this; } clear() { for (const propertyKey of listDecoratedProperties(this)) { const currentValue = this[propertyKey]; if (isProperties(currentValue)) { currentValue.clear(); } else { this[propertyKey] = void 0; } } return this; } toJson() { return listDecoratedProperties(this).reduce((object2, propertyKey) => { const propertyValue = this[propertyKey]; object2[String(propertyKey)] = isProperties(propertyValue) ? propertyValue.toJson() : propertyValue; return object2; }, {}); } }; var PropertiesArray = class _PropertiesArray extends Array { constructor(itemFactory, ...properties) { super(properties.length); const isConstructor = (value2) => Boolean(value2?.prototype?.constructor?.name); const value = isConstructor(itemFactory) ? (params) => new itemFactory().set(params) : itemFactory; Object.defineProperty(this, "itemFactory", { value, enumerable: false, configurable: false }); this.set(properties); } set(properties) { if (isArray(properties)) { this.length = properties.length; for (let i = 0; i < properties.length; i++) { this[i] = this.itemFactory(properties[i]); } } return this; } reset(properties) { if (Array.isArray(properties)) { return new _PropertiesArray(this.itemFactory, ...properties); } } toJson() { return this.map((value) => value?.toJson?.() ?? value); } }; function isProperties(value) { return value instanceof BaseProperties || value instanceof PropertiesArray; } // packages/ag-charts-core/src/chart/interpolationProperties.ts var InterpolationProperties = class extends BaseProperties { constructor() { super(...arguments); this.type = "linear"; this.tension = 1; this.position = "end"; } }; __decorateClass([ addFakeTransformToInstanceProperty ], InterpolationProperties.prototype, "type", 2); __decorateClass([ addFakeTransformToInstanceProperty ], InterpolationProperties.prototype, "tension", 2); __decorateClass([ addFakeTransformToInstanceProperty ], InterpolationProperties.prototype, "position", 2); // packages/ag-charts-core/src/utils/data/numberArray.ts function clampArray(value, array2) { const [min, max] = findMinMax(array2); return clamp(min, value, max); } function findMinMax(array2) { if (array2.length === 0) return []; const result = [Infinity, -Infinity]; for (const val of array2) { if (val < result[0]) result[0] = val; if (val > result[1]) result[1] = val; } return result; } function findRangeExtent(array2) { const [min, max] = findMinMax(array2); return max - min; } function nextPowerOf2(value) { value = Math.trunc(value); if (value <= 0) return 1; if (value === 1) return 2; return 1 << 32 - Math.clz32(value - 1); } function previousPowerOf2(value) { value = Math.trunc(value); if (value <= 0) return 0; if (value === 1) return 1; return 1 << 31 - Math.clz32(value); } // packages/ag-charts-core/src/utils/aggregation.ts var AGGREGATION_INDEX_X_MIN = 0; var AGGREGATION_INDEX_X_MAX = 1; var AGGREGATION_INDEX_Y_MIN = 2; var AGGREGATION_INDEX_Y_MAX = 3; var AGGREGATION_SPAN = 4; var AGGREGATION_THRESHOLD = 1e3; var AGGREGATION_MAX_POINTS = 10; var AGGREGATION_MIN_RANGE = 64; var AGGREGATION_INDEX_UNSET = 4294967295; var SMALLEST_INTERVAL_MIN_RECURSE = 3; var SMALLEST_INTERVAL_RECURSE_LIMIT = 20; var SMALLEST_INTERVAL_MAX_INDEX_ADJUSTMENTS = 100; function estimateSmallestPixelIntervalIter(xValues, d0, d1, startDatumIndex, endDatumIndex, currentSmallestInterval, depth, xNeedsValueOf) { let indexAdjustments = 0; while (indexAdjustments < SMALLEST_INTERVAL_MAX_INDEX_ADJUSTMENTS && xValues[startDatumIndex] == null && startDatumIndex < endDatumIndex) { startDatumIndex += 1; indexAdjustments += 1; } while (indexAdjustments < SMALLEST_INTERVAL_MAX_INDEX_ADJUSTMENTS && xValues[endDatumIndex] == null && endDatumIndex > startDatumIndex) { endDatumIndex -= 1; indexAdjustments += 1; } if (indexAdjustments >= SMALLEST_INTERVAL_MAX_INDEX_ADJUSTMENTS || startDatumIndex >= endDatumIndex) { return currentSmallestInterval; } const ratio2 = Number.isFinite(d0) ? aggregationXRatioForXValue(xValues[endDatumIndex], d0, d1, xNeedsValueOf) - aggregationXRatioForXValue(xValues[startDatumIndex], d0, d1, xNeedsValueOf) : aggregationXRatioForDatumIndex(endDatumIndex, xValues.length) - aggregationXRatioForDatumIndex(startDatumIndex, xValues.length); if (ratio2 === 0 || !Number.isFinite(ratio2)) return currentSmallestInterval; const currentInterval = Math.abs(ratio2) / (endDatumIndex - startDatumIndex); let recurse; if (depth < SMALLEST_INTERVAL_MIN_RECURSE) { recurse = true; } else if (depth > SMALLEST_INTERVAL_RECURSE_LIMIT) { recurse = false; } else { recurse = currentInterval <= currentSmallestInterval; } currentSmallestInterval = Math.min(currentSmallestInterval, currentInterval); if (!recurse) return currentSmallestInterval; const midIndex = Math.floor((startDatumIndex + endDatumIndex) / 2); const leadingInterval = estimateSmallestPixelIntervalIter( xValues, d0, d1, startDatumIndex, midIndex, currentSmallestInterval, depth + 1, xNeedsValueOf ); const trailingInterval = estimateSmallestPixelIntervalIter( xValues, d0, d1, midIndex + 1, endDatumIndex, currentSmallestInterval, depth + 1, xNeedsValueOf ); return Math.min(leadingInterval, trailingInterval, currentSmallestInterval); } function estimateSmallestPixelInterval(xValues, d0, d1, xNeedsValueOf) { return estimateSmallestPixelIntervalIter( xValues, d0, d1, 0, xValues.length - 1, 1 / (xValues.length - 1), 0, xNeedsValueOf ); } function aggregationRangeFittingPoints(xValues, d0, d1, opts) { if (Number.isFinite(d0)) { const smallestKeyInterval = opts?.smallestKeyInterval; const xNeedsValueOf = opts?.xNeedsValueOf ?? true; const smallestPixelInterval = smallestKeyInterval == null ? estimateSmallestPixelInterval(xValues, d0, d1, xNeedsValueOf) : smallestKeyInterval / (d1 - d0); return nextPowerOf2(Math.trunc(1 / smallestPixelInterval)) >> 3; } else { let power = Math.ceil(Math.log2(xValues.length)) - 1; power = Math.min(Math.max(power, 0), 24); return Math.trunc(2 ** power); } } function aggregationDomain(scale, domainInput) { const { domain, sortMetadata } = domainInput; switch (scale) { case "category": return [Number.NaN, Number.NaN]; case "number": case "time": case "ordinal-time": case "unit-time": { if (domain.length === 0) return [Infinity, -Infinity]; if (sortMetadata?.sortOrder === 1) { return [Number(domain[0]), Number(domain.at(-1))]; } if (sortMetadata?.sortOrder === -1) { return [Number(domain.at(-1)), Number(domain[0])]; } let min = Infinity; let max = -Infinity; for (const d of domain) { const value = Number(d); min = Math.min(min, value); max = Math.max(max, value); } return [min, max]; } case "color": case "log": case "mercator": return [0, 0]; } } function aggregationXRatioForDatumIndex(datumIndex, domainCount) { return datumIndex / domainCount; } function aggregationXRatioForXValue(xValue, d0, d1, xNeedsValueOf) { if (xNeedsValueOf) { return (xValue.valueOf() - d0) / (d1 - d0); } return (xValue - d0) / (d1 - d0); } function aggregationIndexForXRatio(xRatio, maxRange) { return Math.trunc(Math.min(Math.floor(xRatio * maxRange), maxRange - 1) * AGGREGATION_SPAN); } function aggregationBucketForDatum(xValues, d0, d1, maxRange, datumIndex, { xNeedsValueOf = true, xValuesLength } = {}) { const xValue = xValues[datumIndex]; if (xValue == null) return -1; const length2 = xValuesLength ?? xValues.length; const xRatio = Number.isFinite(d0) ? aggregationXRatioForXValue(xValue, d0, d1, xNeedsValueOf) : aggregationXRatioForDatumIndex(datumIndex, length2); return aggregationIndexForXRatio(xRatio, maxRange); } function aggregationDatumMatchesIndex(indexData, aggIndex, datumIndex, offsets) { for (const offset of offsets) { if (datumIndex === indexData[aggIndex + offset]) { return true; } } return false; } function createAggregationIndices(xValues, yMaxValues, yMinValues, d0, d1, maxRange, { positive, split = false, xNeedsValueOf = true, yNeedsValueOf = true, // Optional pre-allocated arrays to reuse (must be correct size: maxRange * AGGREGATION_SPAN) reuseIndexData, reuseValueData, reuseNegativeIndexData, reuseNegativeValueData } = {}) { const nan = Number.NaN; const requiredSize = maxRange * AGGREGATION_SPAN; const indexData = reuseIndexData?.length === requiredSize ? reuseIndexData : new Uint32Array(requiredSize); const valueData = reuseValueData?.length === requiredSize ? reuseValueData : new Float64Array(requiredSize); let negativeIndexData; let negativeValueData; if (split) { if (reuseNegativeIndexData?.length === requiredSize) { negativeIndexData = reuseNegativeIndexData; } else { negativeIndexData = new Uint32Array(requiredSize); } if (reuseNegativeValueData?.length === requiredSize) { negativeValueData = reuseNegativeValueData; } else { negativeValueData = new Float64Array(requiredSize); } } const continuous = Number.isFinite(d0) && Number.isFinite(d1); const domainCount = xValues.length; if (continuous) { valueData.fill(nan); indexData.fill(AGGREGATION_INDEX_UNSET); if (split) { negativeValueData.fill(nan); negativeIndexData.fill(AGGREGATION_INDEX_UNSET); } } const scaleFactor = continuous ? maxRange / (d1 - d0) : maxRange * (1 / domainCount); let lastAggIndex = -1; let cachedXMinIndex = -1; let cachedXMinValue = nan; let cachedXMaxIndex = -1; let cachedXMaxValue = nan; let cachedYMinIndex = -1; let cachedYMinValue = nan; let cachedYMaxIndex = -1; let cachedYMaxValue = nan; let negLastAggIndex = -1; let negCachedXMinIndex = -1; let negCachedXMinValue = nan; let negCachedXMaxIndex = -1; let negCachedXMaxValue = nan; let negCachedYMinIndex = -1; let negCachedYMinValue = nan; let negCachedYMaxIndex = -1; let negCachedYMaxValue = nan; const xValuesLength = xValues.length; const yArraysSame = yMaxValues === yMinValues; for (let datumIndex = 0; datumIndex < xValuesLength; datumIndex++) { const xValue = xValues[datumIndex]; if (xValue == null) continue; const yMaxValue = yMaxValues[datumIndex]; const yMinValue = yArraysSame ? yMaxValue : yMinValues[datumIndex]; let yMax; let yMin; if (yNeedsValueOf) { yMax = yMaxValue == null ? nan : yMaxValue.valueOf(); yMin = yMinValue == null ? nan : yMinValue.valueOf(); } else { yMax = yMaxValue ?? nan; yMin = yMinValue ?? nan; } let isPositiveDatum = true; if (split) { isPositiveDatum = yMax >= 0; } else if (positive != null && yMax >= 0 !== positive) { continue; } let scaledX; if (continuous) { if (xNeedsValueOf) { scaledX = (xValue.valueOf() - d0) * scaleFactor; } else { scaledX = (xValue - d0) * scaleFactor; } } else { scaledX = datumIndex * scaleFactor; } const bucketIndex = Math.floor(scaledX); const aggIndex = (bucketIndex < maxRange ? bucketIndex : maxRange - 1) << 2; if (isPositiveDatum) { if (aggIndex !== lastAggIndex) { if (lastAggIndex !== -1) { indexData[lastAggIndex] = cachedXMinIndex; indexData[lastAggIndex + 1] = cachedXMaxIndex; indexData[lastAggIndex + 2] = cachedYMinIndex; indexData[lastAggIndex + 3] = cachedYMaxIndex; valueData[lastAggIndex] = cachedXMinValue; valueData[lastAggIndex + 1] = cachedXMaxValue; valueData[lastAggIndex + 2] = cachedYMinValue; valueData[lastAggIndex + 3] = cachedYMaxValue; } lastAggIndex = aggIndex; cachedXMinIndex = -1; cachedXMinValue = nan; cachedXMaxIndex = -1; cachedXMaxValue = nan; cachedYMinIndex = -1; cachedYMinValue = nan; cachedYMaxIndex = -1; cachedYMaxValue = nan; } const yMinValid = yMin === yMin; const yMaxValid = yMax === yMax; if (cachedXMinIndex === -1) { cachedXMinIndex = datumIndex; cachedXMinValue = scaledX; cachedXMaxIndex = datumIndex; cachedXMaxValue = scaledX; if (yMinValid) { cachedYMinIndex = datumIndex; cachedYMinValue = yMin; } if (yMaxValid) { cachedYMaxIndex = datumIndex; cachedYMaxValue = yMax; } } else { if (scaledX < cachedXMinValue) { cachedXMinIndex = datumIndex; cachedXMinValue = scaledX; } if (scaledX > cachedXMaxValue) { cachedXMaxIndex = datumIndex; cachedXMaxValue = scaledX; } if (yMinValid && yMin < cachedYMinValue) { cachedYMinIndex = datumIndex; cachedYMinValue = yMin; } if (yMaxValid && yMax > cachedYMaxValue) { cachedYMaxIndex = datumIndex; cachedYMaxValue = yMax; } } } else { if (aggIndex !== negLastAggIndex) { if (negLastAggIndex !== -1) { negativeIndexData[negLastAggIndex] = negCachedXMinIndex; negativeIndexData[negLastAggIndex + 1] = negCachedXMaxIndex; negativeIndexData[negLastAggIndex + 2] = negCachedYMinIndex; negativeIndexData[negLastAggIndex + 3] = negCachedYMaxIndex; negativeValueData[negLastAggIndex] = negCachedXMinValue; negativeValueData[negLastAggIndex + 1] = negCachedXMaxValue; negativeValueData[negLastAggIndex + 2] = negCachedYMinValue; negativeValueData[negLastAggIndex + 3] = negCachedYMaxValue; } negLastAggIndex = aggIndex; negCachedXMinIndex = -1; negCachedXMinValue = nan; negCachedXMaxIndex = -1; negCachedXMaxValue = nan; negCachedYMinIndex = -1; negCachedYMinValue = nan; negCachedYMaxIndex = -1; negCachedYMaxValue = nan; } const yMinValid = yMin === yMin; const yMaxValid = yMax === yMax; if (negCachedXMinIndex === -1) { negCachedXMinIndex = datumIndex; negCachedXMinValue = scaledX; negCachedXMaxIndex = datumIndex; negCachedXMaxValue = scaledX; if (yMinValid) { negCachedYMinIndex = datumIndex; negCachedYMinValue = yMin; } if (yMaxValid) { negCachedYMaxIndex = datumIndex; negCachedYMaxValue = yMax; } } else { if (scaledX < negCachedXMinValue) { negCachedXMinIndex = datumIndex; negCachedXMinValue = scaledX; } if (scaledX > negCachedXMaxValue) { negCachedXMaxIndex = datumIndex; negCachedXMaxValue = scaledX; } if (yMinValid && yMin < negCachedYMinValue) { negCachedYMinIndex = datumIndex; negCachedYMinValue = yMin; } if (yMaxValid && yMax > negCachedYMaxValue) { negCachedYMaxIndex = datumIndex; negCachedYMaxValue = yMax; } } } } if (lastAggIndex !== -1) { indexData[lastAggIndex] = cachedXMinIndex; indexData[lastAggIndex + 1] = cachedXMaxIndex; indexData[lastAggIndex + 2] = cachedYMinIndex; indexData[lastAggIndex + 3] = cachedYMaxIndex; valueData[lastAggIndex] = cachedXMinValue; valueData[lastAggIndex + 1] = cachedXMaxValue; valueData[lastAggIndex + 2] = cachedYMinValue; valueData[lastAggIndex + 3] = cachedYMaxValue; } if (split && negLastAggIndex !== -1) { negativeIndexData[negLastAggIndex] = negCachedXMinIndex; negativeIndexData[negLastAggIndex + 1] = negCachedXMaxIndex; negativeIndexData[negLastAggIndex + 2] = negCachedYMinIndex; negativeIndexData[negLastAggIndex + 3] = negCachedYMaxIndex; negativeValueData[negLastAggIndex] = negCachedXMinValue; negativeValueData[negLastAggIndex + 1] = negCachedXMaxValue; negativeValueData[negLastAggIndex + 2] = negCachedYMinValue; negativeValueData[negLastAggIndex + 3] = negCachedYMaxValue; } return { indexData, valueData, negativeIndexData, negativeValueData }; } function compactAggregationIndices(indexData, valueData, maxRange, { inPlace = false, midpointData, reuseIndexData, reuseValueData } = {}) { const nextMaxRange = Math.trunc(maxRange / 2); const requiredSize = nextMaxRange * AGGREGATION_SPAN; let nextIndexData; if (inPlace) { nextIndexData = indexData; } else if (reuseIndexData?.length === requiredSize) { nextIndexData = reuseIndexData; } else { nextIndexData = new Uint32Array(requiredSize); } let nextValueData; if (inPlace) { nextValueData = valueData; } else if (reuseValueData?.length === requiredSize) { nextValueData = reuseValueData; } else { nextValueData = new Float64Array(requiredSize); } const nextMidpointData = midpointData ?? new Uint32Array(nextMaxRange); for (let i = 0; i < nextMaxRange; i += 1) { const aggIndex = Math.trunc(i * AGGREGATION_SPAN); const index0 = Math.trunc(aggIndex * 2); const index1 = Math.trunc(index0 + AGGREGATION_SPAN); const index1Unset = indexData[index1 + AGGREGATION_INDEX_X_MIN] === AGGREGATION_INDEX_UNSET; const xMinAggIndex = index1Unset || valueData[index0 + AGGREGATION_INDEX_X_MIN] < valueData[index1 + AGGREGATION_INDEX_X_MIN] ? index0 : index1; const xMinIndex = indexData[xMinAggIndex + AGGREGATION_INDEX_X_MIN]; nextIndexData[aggIndex + AGGREGATION_INDEX_X_MIN] = xMinIndex; nextValueData[aggIndex + AGGREGATION_INDEX_X_MIN] = valueData[xMinAggIndex + AGGREGATION_INDEX_X_MIN]; const xMaxAggIndex = index1Unset || valueData[index0 + AGGREGATION_INDEX_X_MAX] > valueData[index1 + AGGREGATION_INDEX_X_MAX] ? index0 : index1; const xMaxIndex = indexData[xMaxAggIndex + AGGREGATION_INDEX_X_MAX]; nextIndexData[aggIndex + AGGREGATION_INDEX_X_MAX] = xMaxIndex; nextValueData[aggIndex + AGGREGATION_INDEX_X_MAX] = valueData[xMaxAggIndex + AGGREGATION_INDEX_X_MAX]; nextMidpointData[i] = xMinIndex + xMaxIndex >> 1; const yMinAggIndex = index1Unset || valueData[index0 + AGGREGATION_INDEX_Y_MIN] < valueData[index1 + AGGREGATION_INDEX_Y_MIN] ? index0 : index1; nextIndexData[aggIndex + AGGREGATION_INDEX_Y_MIN] = indexData[yMinAggIndex + AGGREGATION_INDEX_Y_MIN]; nextValueData[aggIndex + AGGREGATION_INDEX_Y_MIN] = valueData[yMinAggIndex + AGGREGATION_INDEX_Y_MIN]; const yMaxAggIndex = index1Unset || valueData[index0 + AGGREGATION_INDEX_Y_MAX] > valueData[index1 + AGGREGATION_INDEX_Y_MAX] ? index0 : index1; nextIndexData[aggIndex + AGGREGATION_INDEX_Y_MAX] = indexData[yMaxAggIndex + AGGREGATION_INDEX_Y_MAX]; nextValueData[aggIndex + AGGREGATION_INDEX_Y_MAX] = valueData[yMaxAggIndex + AGGREGATION_INDEX_Y_MAX]; } return { maxRange: nextMaxRange, indexData: nextIndexData, valueData: nextValueData, midpointData: nextMidpointData }; } function getMidpointsForIndices(maxRange, indexData, reuseMidpointData, xMinOffset = AGGREGATION_INDEX_X_MIN, xMaxOffset = AGGREGATION_INDEX_X_MAX, invalidSentinel = -1) { const midpoints = reuseMidpointData?.length === maxRange ? reuseMidpointData : new Uint32Array(maxRange); for (let i = 0, offset = 0; i < maxRange; i += 1, offset += AGGREGATION_SPAN) { const xMin = indexData[offset + xMinOffset]; const xMax = indexData[offset + xMaxOffset]; midpoints[i] = xMin === invalidSentinel ? invalidSentinel : xMin + xMax >> 1; } return midpoints; } function collectAggregationLevels(state, { collectLevel, shouldContinue, minRange = AGGREGATION_MIN_RANGE, compactInPlace = false }) { let aggregationState = state; let level = collectLevel(aggregationState); const levels = [level]; while (aggregationState.maxRange > minRange && shouldContinue(level, aggregationState)) { const compacted = compactAggregationIndices( aggregationState.indexData, aggregationState.valueData, aggregationState.maxRange, { inPlace: compactInPlace } ); aggregationState = { maxRange: compacted.maxRange, indexData: compacted.indexData, valueData: compacted.valueData, midpointData: compacted.midpointData }; level = collectLevel(aggregationState); levels.push(level); } levels.reverse(); return levels; } function computeExtremesAggregation(domain, xValues, highValues, lowValues, options) { if (xValues.length < AGGREGATION_THRESHOLD) return; const [d0, d1] = domain; const { smallestKeyInterval, xNeedsValueOf, yNeedsValueOf, existingFilters } = options; let maxRange = aggregationRangeFittingPoints(xValues, d0, d1, { smallestKeyInterval, xNeedsValueOf }); const existingFilter = existingFilters?.find((f) => f.maxRange === maxRange); let { indexData, valueData } = createAggregationIndices(xValues, highValues, lowValues, d0, d1, maxRange, { xNeedsValueOf, yNeedsValueOf, reuseIndexData: existingFilter?.indexData, reuseValueData: existingFilter?.valueData }); let midpointIndices = getMidpointsForIndices(maxRange, indexData, existingFilter?.midpointIndices); const filters = [ { maxRange, indexData, valueData, midpointIndices } ]; while (maxRange > AGGREGATION_MIN_RANGE) { const currentMaxRange = maxRange; const nextMaxRange = Math.trunc(currentMaxRange / 2); const nextExistingFilter = existingFilters?.find((f) => f.maxRange === nextMaxRange); const compacted = compactAggregationIndices(indexData, valueData, currentMaxRange, { reuseIndexData: nextExistingFilter?.indexData, reuseValueData: nextExistingFilter?.valueData }); maxRange = compacted.maxRange; indexData = compacted.indexData; valueData = compacted.valueData; midpointIndices = compacted.midpointData ?? getMidpointsForIndices(maxRange, indexData, nextExistingFilter?.midpointIndices); filters.push({ maxRange, indexData, valueData, midpointIndices }); } filters.reverse(); return filters; } function computeExtremesAggregationPartial(domain, xValues, highValues, lowValues, options) { if (xValues.length < AGGREGATION_THRESHOLD) return; const [d0, d1] = domain; const { smallestKeyInterval, targetRange, xNeedsValueOf, yNeedsValueOf, existingFilters } = options; const finestMaxRange = aggregationRangeFittingPoints(xValues, d0, d1, { smallestKeyInterval, xNeedsValueOf }); const targetMaxRange = Math.min(finestMaxRange, nextPowerOf2(Math.max(targetRange, AGGREGATION_MIN_RANGE))); const existingFilter = existingFilters?.find((f) => f.maxRange === targetMaxRange); const { indexData, valueData } = createAggregationIndices(xValues, highValues, lowValues, d0, d1, targetMaxRange, { xNeedsValueOf, yNeedsValueOf, reuseIndexData: existingFilter?.indexData, reuseValueData: existingFilter?.valueData }); const midpointIndices = getMidpointsForIndices(targetMaxRange, indexData, existingFilter?.midpointIndices); const immediateLevel = { maxRange: targetMaxRange, indexData, valueData, midpointIndices }; function computeRemaining() { const allLevels = computeExtremesAggregation([d0, d1], xValues, highValues, lowValues, { smallestKeyInterval, xNeedsValueOf, yNeedsValueOf, existingFilters }); return allLevels?.filter((level) => level.maxRange !== targetMaxRange) ?? []; } return { immediate: [immediateLevel], computeRemaining }; } // packages/ag-charts-core/src/types/themeSymbols.ts var IS_DARK_THEME = Symbol("is-dark-theme"); var DEFAULT_SHADOW_COLOUR = Symbol("default-shadow-colour"); var DEFAULT_CAPTION_LAYOUT_STYLE = Symbol("default-caption-layout-style"); var DEFAULT_CAPTION_ALIGNMENT = Symbol("default-caption-alignment"); var PALETTE_UP_STROKE = Symbol("palette-up-stroke"); var PALETTE_DOWN_STROKE = Symbol("palette-down-stroke"); var PALETTE_UP_FILL = Symbol("palette-up-fill"); var PALETTE_DOWN_FILL = Symbol("palette-down-fill"); var PALETTE_NEUTRAL_STROKE = Symbol("palette-neutral-stroke"); var PALETTE_NEUTRAL_FILL = Symbol("palette-neutral-fill"); var PALETTE_ALT_UP_STROKE = Symbol("palette-alt-up-stroke"); var PALETTE_ALT_DOWN_STROKE = Symbol("palette-alt-down-stroke"); var PALETTE_ALT_UP_FILL = Symbol("palette-alt-up-fill"); var PALETTE_ALT_DOWN_FILL = Symbol("palette-alt-down-fill"); var PALETTE_ALT_NEUTRAL_FILL = Symbol("palette-gray-fill"); var PALETTE_ALT_NEUTRAL_STROKE = Symbol("palette-gray-stroke"); var DEFAULT_POLAR_SERIES_STROKE = Symbol("default-polar-series-stroke"); var DEFAULT_SPARKLINE_CROSSHAIR_STROKE = Symbol("default-sparkline-crosshair-stroke"); var DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR = Symbol( "default-financial-charts-annotation-stroke" ); var DEFAULT_FIBONACCI_STROKES = Symbol("default-hierarchy-strokes"); var DEFAULT_TEXT_ANNOTATION_COLOR = Symbol("default-text-annotation-color"); var DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL = Symbol( "default-financial-charts-annotation-background-fill" ); var DEFAULT_ANNOTATION_HANDLE_FILL = Symbol("default-annotation-handle-fill"); var DEFAULT_ANNOTATION_STATISTICS_FILL = Symbol("default-annotation-statistics-fill"); var DEFAULT_ANNOTATION_STATISTICS_STROKE = Symbol("default-annotation-statistics-stroke"); var DEFAULT_ANNOTATION_STATISTICS_COLOR = Symbol("default-annotation-statistics-color"); var DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE = Symbol( "default-annotation-statistics-divider-stroke" ); var DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL = Symbol( "default-annotation-statistics-fill" ); var DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE = Symbol( "default-annotation-statistics-stroke" ); var DEFAULT_TEXTBOX_FILL = Symbol("default-textbox-fill"); var DEFAULT_TEXTBOX_STROKE = Symbol("default-textbox-stroke"); var DEFAULT_TEXTBOX_COLOR = Symbol("default-textbox-color"); var DEFAULT_TOOLBAR_POSITION = Symbol("default-toolbar-position"); // packages/ag-charts-core/src/state/callbackCache.ts function needsContext(caller, _params) { return "context" in caller; } function maybeSetContext(caller, params) { if (caller != null && needsContext(caller, params)) { if (params != null && typeof params === "object" && params.context === void 0) { params.context = caller.context; return true; } } return false; } function callWithContext(callers, fn, params) { if (Array.isArray(callers)) { for (const caller of callers) { if (maybeSetContext(caller, params)) { break; } } } else { maybeSetContext(callers, params); } return fn(params); } var CallbackCache = class { constructor() { this.cache = /* @__PURE__ */ new WeakMap(); } call(callers, fn, params) { let serialisedParams; let paramCache = this.cache.get(fn); try { serialisedParams = JSON.stringify(params); } catch { return this.invoke(callers, fn, paramCache, void 0, params); } if (paramCache == null) { paramCache = /* @__PURE__ */ new Map(); this.cache.set(fn, paramCache); } if (!paramCache.has(serialisedParams)) { return this.invoke(callers, fn, paramCache, serialisedParams, params); } return paramCache.get(serialisedParams); } invoke(callers, fn, paramCache, serialisedParams, params) { try { const result = callWithContext(callers, fn, params); if (paramCache && serialisedParams != null) { paramCache.set(serialisedParams, result); } return result; } catch (e) { warnOnce(`User callback errored, ignoring`, e); return; } } invalidateCache() { this.cache = /* @__PURE__ */ new WeakMap(); } }; // packages/ag-charts-core/src/utils/dom/domUtil.ts function setElementBBox(element, bbox) { if (!element) return; const { x, y, width: width2, height: height2 } = normalizeBounds(bbox); setPixelValue(element.style, "width", width2); setPixelValue(element.style, "height", height2); setPixelValue(element.style, "left", x); setPixelValue(element.style, "top", y); } function getElementBBox(element) { const styleWidth = Number.parseFloat(element.style.width); const styleHeight = Number.parseFloat(element.style.height); const styleX = Number.parseFloat(element.style.left); const styleY = Number.parseFloat(element.style.top); const width2 = Number.isFinite(styleWidth) ? styleWidth : element.offsetWidth; const height2 = Number.isFinite(styleHeight) ? styleHeight : element.offsetHeight; const x = Number.isFinite(styleX) ? styleX : element.offsetLeft; const y = Number.isFinite(styleY) ? styleY : element.offsetTop; return { x, y, width: width2, height: height2 }; } function focusCursorAtEnd(element) { element.focus({ preventScroll: true }); if (element.lastChild?.textContent == null) return; const range2 = getDocument().createRange(); range2.setStart(element.lastChild, element.lastChild.textContent.length); range2.setEnd(element.lastChild, element.lastChild.textContent.length); const selection = getWindow().getSelection(); selection?.removeAllRanges(); selection?.addRange(range2); } function isInputPending() { const navigator = getWindow("navigator"); if ("scheduling" in navigator) { const scheduling = navigator.scheduling; if ("isInputPending" in scheduling) { return scheduling.isInputPending({ includeContinuous: true }); } } return false; } function getIconClassNames(icon) { return `ag-charts-icon ag-charts-icon-${icon}`; } function normalizeBounds(bbox) { let { x, y, width: width2, height: height2 } = bbox; if ((width2 == null || width2 > 0) && (height2 == null || height2 > 0)) { return bbox; } if (x != null && width2 != null && width2 < 0) { width2 = -width2; x = x - width2; } if (y != null && height2 != null && height2 < 0) { height2 = -height2; y = y - height2; } return { x, y, width: width2, height: height2 }; } function setPixelValue(style2, key, value) { if (value == null) { style2.removeProperty(key); } else { style2.setProperty(key, `${value}px`); } } // packages/ag-charts-core/src/utils/geometry/math/shapeUtils.ts function getMaxInnerRectSize(rotationDeg, containerWidth, containerHeight = Infinity) { const W = containerWidth; const H = containerHeight; const angle2 = rotationDeg % 180 * (Math.PI / 180); const sin = Math.abs(Math.sin(angle2)); const cos = Math.abs(Math.cos(angle2)); if (sin === 0) return { width: W, height: H }; if (cos === 0) return { width: H, height: W }; if (!Number.isFinite(H)) { const r = cos / sin; const width2 = W / (cos + r * sin); return { width: width2, height: r * width2 }; } const denominator = cos * cos - sin * sin; if (denominator === 0) { const side = Math.min(W, H) / Math.SQRT2; return { width: side, height: side }; } return { width: Math.abs((W * cos - H * sin) / denominator), height: Math.abs((H * cos - W * sin) / denominator) }; } function getMinOuterRectSize(rotationDeg, innerWidth, innerHeight = Infinity) { const w = innerWidth; const h = innerHeight; const angle2 = rotationDeg % 180 * (Math.PI / 180); const sin = Math.abs(Math.sin(angle2)); const cos = Math.abs(Math.cos(angle2)); if (sin === 0) return { width: w, height: h }; if (cos === 0) return { width: h, height: w }; return { width: w * cos + h * sin, height: w * sin + h * cos }; } function rotatePoint(x, y, angle2, originX = 0, originY = 0) { const cos = Math.cos(angle2); const sin = Math.sin(angle2); const dx = x - originX; const dy = y - originY; return { x: originX + dx * cos - dy * sin, y: originY + dx * sin + dy * cos }; } // packages/ag-charts-core/src/utils/geometry/angle.ts var twoPi = Math.PI * 2; var halfPi = Math.PI / 2; function normalizeAngle360(radians) { radians %= twoPi; radians += twoPi; radians %= twoPi; return radians; } function normalizeAngle360Inclusive(radians) { radians %= twoPi; radians += twoPi; if (radians !== twoPi) { radians %= twoPi; } return radians; } function normalizeAngle180(radians) { radians %= twoPi; if (radians < -Math.PI) { radians += twoPi; } else if (radians >= Math.PI) { radians -= twoPi; } return radians; } function isBetweenAngles(targetAngle, startAngle, endAngle) { const t = normalizeAngle360(targetAngle); const a0 = normalizeAngle360(startAngle); const a1 = normalizeAngle360(endAngle); if (a0 < a1) { return a0 <= t && t <= a1; } else if (a0 > a1) { return a0 <= t || t <= a1; } else { return startAngle !== endAngle; } } function toRadians(degrees) { return degrees / 180 * Math.PI; } function toDegrees(radians) { return radians / Math.PI * 180; } function angleBetween(angle0, angle1) { angle0 = normalizeAngle360(angle0); angle1 = normalizeAngle360(angle1); return angle1 - angle0 + (angle0 > angle1 ? twoPi : 0); } function getAngleRatioRadians(angle2) { const normalizedAngle = normalizeAngle360(angle2); if (normalizedAngle <= halfPi) { return normalizedAngle / halfPi; } else if (normalizedAngle <= Math.PI) { return (Math.PI - normalizedAngle) / halfPi; } else if (normalizedAngle <= 1.5 * Math.PI) { return (normalizedAngle - Math.PI) / halfPi; } else { return (twoPi - normalizedAngle) / halfPi; } } function angularPadding(hPadding, vPadding, angle2) { const angleRatio = getAngleRatioRadians(angle2); return hPadding * angleRatio + vPadding * Math.abs(1 - angleRatio); } function normalizeAngle360FromDegrees(degrees) { return degrees ? normalizeAngle360(toRadians(degrees)) : 0; } // packages/ag-charts-core/src/utils/async.ts var AsyncAwaitQueue = class { constructor() { this.queue = []; } /** Await another async process to call notify(). */ waitForCompletion(timeout = 50) { const queue = this.queue; function createCompletionPromise(resolve) { function successFn() { clearTimeout(timeoutHandle); resolve(true); } function timeoutFn() { const queueIndex = queue.indexOf(successFn); if (queueIndex < 0) return; queue.splice(queueIndex, 1); resolve(false); } const timeoutHandle = setTimeout(timeoutFn, timeout); queue.push(successFn); } return new Promise(createCompletionPromise); } /** Trigger any await()ing async processes to continue. */ notify() { for (const cb of this.queue.splice(0)) { cb(); } } }; function pause(delayMilliseconds = 0) { function resolveAfterDelay(resolve) { setTimeout(resolve, delayMilliseconds); } return new Promise(resolveAfterDelay); } async function withTimeout(promise, timeoutMs, errorMessage = `Timeout after ${timeoutMs}ms`) { let timer; const timeoutPromise = new Promise((_, reject) => { timer = setTimeout(() => reject(new Error(errorMessage)), timeoutMs); }); try { return await Promise.race([promise, timeoutPromise]); } finally { clearTimeout(timer); } } // packages/ag-charts-core/src/utils/dom/attributeUtil.ts function booleanParser(value) { return value === "true"; } function numberParser(value) { return Number(value); } function stringParser(value) { return value; } var AttributeTypeParsers = { role: stringParser, "aria-checked": booleanParser, "aria-controls": stringParser, "aria-describedby": stringParser, "aria-disabled": booleanParser, "aria-expanded": booleanParser, "aria-haspopup": stringParser, "aria-hidden": booleanParser, "aria-label": stringParser, "aria-labelledby": stringParser, "aria-live": stringParser, "aria-orientation": stringParser, "aria-selected": booleanParser, "data-focus-override": booleanParser, "data-focus-visible-override": booleanParser, "data-preventdefault": booleanParser, class: stringParser, for: stringParser, id: stringParser, tabindex: numberParser, title: stringParser, placeholder: stringParser }; function setAttribute(e, qualifiedName, value) { if (value == null || value === "" || value === "") { e?.removeAttribute(qualifiedName); } else { e?.setAttribute(qualifiedName, value.toString()); } } function setAttributes(e, attrs) { if (attrs == null) return; for (const [key, value] of entries(attrs)) { if (key === "class") continue; setAttribute(e, key, value); } } function getAttribute(e, qualifiedName, defaultValue) { if (!isHTMLElement(e)) return void 0; const value = e.getAttribute(qualifiedName); if (value === null) return defaultValue; return AttributeTypeParsers[qualifiedName]?.(value) ?? void 0; } function setElementStyle(e, property, value) { if (e == null) return; if (value == null) { e.style.removeProperty(property); } else { e.style.setProperty(property, value.toString()); } } function setElementStyles(e, styles) { for (const [key, value] of entries(styles)) { setElementStyle(e, key, value); } } // packages/ag-charts-core/src/state/proxy.ts function ProxyProperty(proxyPath, configMetadata) { const pathArray = Array.isArray(proxyPath) ? proxyPath : proxyPath.split("."); if (pathArray.length === 1) { const [property] = pathArray; return addTransformToInstanceProperty( (target, _, value) => target[property] = value, (target) => target[property], configMetadata ); } return addTransformToInstanceProperty( (target, _, value) => setPath(target, pathArray, value), (target) => getPath(target, pathArray), configMetadata ); } function ProxyOnWrite(proxyProperty) { return addTransformToInstanceProperty((target, _, value) => target[proxyProperty] = value); } function ProxyPropertyOnWrite(childName, childProperty) { return addTransformToInstanceProperty((target, key, value) => target[childName][childProperty ?? key] = value); } function ActionOnSet(opts) { const { newValue: newValueFn, oldValue: oldValueFn, changeValue: changeValueFn } = opts; return addTransformToInstanceProperty((target, _, newValue, oldValue) => { if (newValue !== oldValue) { if (oldValue !== void 0) { oldValueFn?.call(target, oldValue); } if (newValue !== void 0) { newValueFn?.call(target, newValue); } changeValueFn?.call(target, newValue, oldValue); } return newValue; }); } function ObserveChanges(observerFn) { return addObserverToInstanceProperty(observerFn); } // packages/ag-charts-core/src/utils/geometry/border.ts var Border = class extends BaseProperties { constructor(node) { super(); this.node = node; this.enabled = false; this.stroke = "black"; this.strokeOpacity = 1; this.strokeWidth = 1; } }; __decorateClass([ ActionOnSet({ changeValue(newValue) { if (newValue) { this.node.strokeWidth = this.strokeWidth; } else { this.node.strokeWidth = 0; } } }), addFakeTransformToInstanceProperty ], Border.prototype, "enabled", 2); __decorateClass([ ProxyPropertyOnWrite("node", "stroke"), addFakeTransformToInstanceProperty ], Border.prototype, "stroke", 2); __decorateClass([ ProxyPropertyOnWrite("node", "strokeOpacity"), addFakeTransformToInstanceProperty ], Border.prototype, "strokeOpacity", 2); __decorateClass([ ActionOnSet({ changeValue(newValue) { if (this.enabled) { this.node.strokeWidth = newValue; } else { this.node.strokeWidth = 0; } } }), addFakeTransformToInstanceProperty ], Border.prototype, "strokeWidth", 2); // packages/ag-charts-core/src/utils/geometry/boxBounds.ts function boxCollides(b, x, y, w, h) { return x < b.x + b.width && x + w > b.x && y < b.y + b.height && y + h > b.y; } function boxContains(b, x, y, w = 0, h = 0) { return x >= b.x && x + w <= b.x + b.width && y >= b.y && y + h <= b.y + b.height; } function boxEmpty(b) { return b == null || b.height === 0 || b.width === 0 || Number.isNaN(b.height) || Number.isNaN(b.width); } function boxesEqual(a, b) { if (a === b) return true; if (a == null || b == null) return false; return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height; } // packages/ag-charts-core/src/utils/data/binarySearch.ts function findMaxIndex(min, max, iteratee) { if (min > max) return; let found; while (max >= min) { const index = Math.floor((max + min) / 2); const value = iteratee(index); if (value) { found = index; min = index + 1; } else { max = index - 1; } } return found; } function findMinIndex(min, max, iteratee) { if (min > max) return; let found; while (max >= min) { const index = Math.floor((max + min) / 2); const value = iteratee(index); if (value) { found = index; max = index - 1; } else { min = index + 1; } } return found; } function findMaxValue(min, max, iteratee) { if (min > max) return; let found; while (max >= min) { const index = Math.floor((max + min) / 2); const value = iteratee(index); if (value == null) { max = index - 1; } else { found = value; min = index + 1; } } return found; } function findMinValue(min, max, iteratee) { if (min > max) return; let found; while (max >= min) { const index = Math.floor((max + min) / 2); const value = iteratee(index); if (value == null) { min = index + 1; } else { found = value; max = index - 1; } } return found; } // packages/ag-charts-core/src/utils/canvas.ts function createCanvasContext(width2 = 0, height2 = 0) { const OffscreenCanvasCtor = getOffscreenCanvas(); return new OffscreenCanvasCtor(width2, height2).getContext("2d"); } // packages/ag-charts-core/src/utils/configuredCanvasMixin.ts var CANVAS_WIDTH = 800; var CANVAS_HEIGHT = 600; var CANVAS_TO_BUFFER_DEFAULTS = { quality: 1 }; function ConfiguredCanvasMixin(Base) { const ConfiguredCanvasClass = class ConfiguredCanvas extends Base { constructor(...args) { super(...args); this.gpu = false; } toBuffer(format, options) { return super.toBuffer(format, { ...options, msaa: false }); } transferToImageBitmap() { const { width: width2, height: height2 } = this; const bitmap = new ConfiguredCanvasClass(Math.max(1, width2), Math.max(1, height2)); if (width2 > 0 && height2 > 0) { bitmap.getContext("2d").drawCanvas(this, 0, 0, width2, height2); } Object.defineProperty(bitmap, "close", { value: () => { } }); return bitmap; } }; return ConfiguredCanvasClass; } var patchesApplied = false; function applySkiaPatches(CanvasRenderingContext2D, DOMMatrix) { if (patchesApplied) return; patchesApplied = true; const superCreateConicGradient = CanvasRenderingContext2D.prototype.createConicGradient; Object.defineProperty(CanvasRenderingContext2D.prototype, "createConicGradient", { value: function(angle2, x, y) { return superCreateConicGradient.call(this, angle2 + Math.PI / 2, x, y); }, writable: true, configurable: true }); Object.defineProperty(CanvasRenderingContext2D.prototype, "fillText", { value: function(text, x, y) { let path2d = this.outlineText(text); path2d = path2d.transform(new DOMMatrix([1, 0, 0, 1, x, y])); this.fill(path2d); }, writable: true, configurable: true }); } // packages/ag-charts-core/src/state/caching.ts var SimpleCache = class { constructor(getter) { this.getter = getter; } get() { this.result ?? (this.result = this.getter()); return this.result; } clear() { this.result = void 0; } }; var WeakCache = class { constructor(getter) { this.getter = getter; } get() { let result = this.result?.deref(); if (result) return result; result = this.getter(); this.result = new WeakRef(result); return result; } clear() { this.result = void 0; } }; // packages/ag-charts-core/src/utils/time/date.ts function compareDates(a, b) { return a.valueOf() - b.valueOf(); } function deduplicateSortedArray(values) { let v0 = Number.NaN; const out = []; for (const v of values) { const v1 = v.valueOf(); if (v0 !== v1) out.push(v); v0 = v1; } return out; } function sortAndUniqueDates(values) { const sortedValues = values.slice().sort(compareDates); return datesSortOrder(sortedValues) == null ? deduplicateSortedArray(sortedValues) : sortedValues; } function datesSortOrder(d) { if (d.length === 0) return 1; const sign = Number(d.at(-1)) > Number(d[0]) ? 1 : -1; let v0 = -Infinity * sign; for (const v of d) { const v1 = v.valueOf(); if (Math.sign(v1 - v0) !== sign) return; v0 = v1; } return sign; } // packages/ag-charts-core/src/utils/deprecation.ts function createDeprecationWarning() { return (key, message) => { const msg = [`Property [${key}] is deprecated.`, message].filter(Boolean).join(" "); warnOnce(msg); }; } function Deprecated(message, opts) { const warnDeprecated = createDeprecationWarning(); const def = opts?.default; return addTransformToInstanceProperty((_, key, value) => { if (value !== def) { warnDeprecated(key.toString(), message); } return value; }); } function DeprecatedAndRenamedTo(newPropName, mapValue) { const warnDeprecated = createDeprecationWarning(); return addTransformToInstanceProperty( (target, key, value) => { if (value !== target[newPropName]) { warnDeprecated(key.toString(), `Use [${newPropName}] instead.`); setPath(target, newPropName, mapValue ? mapValue(value) : value); } return BREAK_TRANSFORM_CHAIN; }, (target, key) => { warnDeprecated(key.toString(), `Use [${newPropName}] instead.`); return getPath(target, newPropName); } ); } // packages/ag-charts-core/src/utils/data/diff.ts function diffArrays(previous, current) { const size = Math.max(previous.length, current.length); const added = /* @__PURE__ */ new Set(); const removed = /* @__PURE__ */ new Set(); for (let i = 0; i < size; i++) { const prev = previous[i]; const curr = current[i]; if (prev === curr) continue; if (removed.has(curr)) { removed.delete(curr); } else if (curr) { added.add(curr); } if (added.has(prev)) { added.delete(prev); } else if (prev) { removed.add(prev); } } return { changed: added.size > 0 || removed.size > 0, added, removed }; } // packages/ag-charts-core/src/utils/geometry/distance.ts function pointsDistanceSquared(x1, y1, x2, y2) { const dx = x1 - x2; const dy = y1 - y2; return dx * dx + dy * dy; } function lineDistanceSquared(x, y, x1, y1, x2, y2, best) { if (x1 === x2 && y1 === y2) { return Math.min(best, pointsDistanceSquared(x, y, x1, y1)); } const dx = x2 - x1; const dy = y2 - y1; const t = Math.max(0, Math.min(1, ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy))); const ix = x1 + t * dx; const iy = y1 + t * dy; return Math.min(best, pointsDistanceSquared(x, y, ix, iy)); } function arcDistanceSquared(x, y, cx, cy, radius, startAngle, endAngle, counterClockwise, best) { if (counterClockwise) { [endAngle, startAngle] = [startAngle, endAngle]; } const angle2 = Math.atan2(y - cy, x - cx); if (!isBetweenAngles(angle2, startAngle, endAngle)) { const startX = cx + Math.cos(startAngle) * radius; const startY = cy + Math.sin(startAngle) * radius; const endX = cx + Math.cos(startAngle) * radius; const endY = cy + Math.sin(startAngle) * radius; return Math.min(best, pointsDistanceSquared(x, y, startX, startY), pointsDistanceSquared(x, y, endX, endY)); } const distToArc = radius - Math.sqrt(pointsDistanceSquared(x, y, cx, cy)); return Math.min(best, distToArc * distToArc); } // packages/ag-charts-core/src/utils/data/extent.ts function extent(values, sortOrder) { if (values.length === 0) { return null; } if (sortOrder !== void 0) { const first2 = values.at(0); const last = values.at(-1); const v0 = first2 instanceof Date ? first2.getTime() : first2; const v1 = last instanceof Date ? last.getTime() : last; if (typeof v0 === "number" && typeof v1 === "number") { return sortOrder === 1 ? [v0, v1] : [v1, v0]; } } let min = Infinity; let max = -Infinity; for (const n of values) { const v = n instanceof Date ? n.getTime() : n; if (typeof v !== "number") continue; if (v < min) { min = v; } if (v > max) { max = v; } } const result = [min, max]; return result.every(Number.isFinite) ? result : null; } function normalisedExtentWithMetadata(d, min, max, preferredMin, preferredMax, toValue, sortOrder) { let clipped = false; const domainExtentNumbers = extent(d, sortOrder); const domainExtent = domainExtentNumbers && toValue ? [toValue(domainExtentNumbers[0]), toValue(domainExtentNumbers[1])] : domainExtentNumbers; if (domainExtent == null) { let nullExtent; if (min != null && max != null && min <= max) { nullExtent = [min, max]; } else if (preferredMin != null && preferredMax != null && preferredMin <= preferredMax) { nullExtent = [preferredMin, preferredMax]; } return { extent: nullExtent ?? [], clipped: false }; } let [d0, d1] = domainExtent; if (min != null) { clipped || (clipped = min > d0); d0 = min; } else if (preferredMin != null && preferredMin < d0) { d0 = preferredMin; } if (max != null) { clipped || (clipped = max < d1); d1 = max; } else if (preferredMax != null && preferredMax > d1) { d1 = preferredMax; } if (d0 > d1) { return { extent: [], clipped: false }; } return { extent: [d0, d1], clipped }; } function normalisedTimeExtentWithMetadata(input, min, max, preferredMin, preferredMax) { const { extent: e, clipped } = normalisedExtentWithMetadata( input.domain, isNumber(min) ? new Date(min) : min, isNumber(max) ? new Date(max) : max, isNumber(preferredMin) ? new Date(preferredMin) : preferredMin, isNumber(preferredMax) ? new Date(preferredMax) : preferredMax, (x) => new Date(x), input.sortMetadata?.sortOrder ); return { extent: e.map((x) => new Date(x)), clipped }; } // packages/ag-charts-core/src/utils/format/format.util.ts var percentFormatter = new Intl.NumberFormat("en-US", { style: "percent" }); function formatValue(value, maximumFractionDigits = 2) { if (typeof value === "number") { return formatNumber(value, maximumFractionDigits); } return typeof value === "string" ? value : String(value ?? ""); } function formatPercent(value) { return percentFormatter.format(value); } var numberFormatters = (/* @__PURE__ */ new Map()).set( 2, new Intl.NumberFormat("en-US", { maximumFractionDigits: 2, useGrouping: false }) ); function formatNumber(value, maximumFractionDigits) { let formatter2 = numberFormatters.get(maximumFractionDigits); if (!formatter2) { formatter2 = new Intl.NumberFormat("en-US", { maximumFractionDigits, useGrouping: false }); numberFormatters.set(maximumFractionDigits, formatter2); } return formatter2.format(value); } // packages/ag-charts-core/src/utils/geojson.ts function isValidCoordinate(value) { return Array.isArray(value) && value.length >= 2 && value.every(isFiniteNumber); } function isValidCoordinates(value) { return Array.isArray(value) && value.length >= 2 && value.every(isValidCoordinate); } function hasSameStartEndPoint(c) { const start2 = c[0]; const end2 = c.at(-1); if (end2 === void 0) return false; return isNumberEqual(start2[0], end2[0], 1e-3) && isNumberEqual(start2[1], end2[1], 1e-3); } function isValidPolygon(value) { return Array.isArray(value) && value.every(isValidCoordinates) && value.every(hasSameStartEndPoint); } function isValidGeometry(value) { if (value === null) return true; if (!isObject(value) || value.type == null) return false; const { type, coordinates } = value; switch (type) { case "GeometryCollection": return Array.isArray(value.geometries) && value.geometries.every(isValidGeometry); case "MultiPolygon": return Array.isArray(coordinates) && coordinates.every(isValidPolygon); case "Polygon": return isValidPolygon(coordinates); case "MultiLineString": return Array.isArray(coordinates) && coordinates.every(isValidCoordinates); case "LineString": return isValidCoordinates(coordinates); case "MultiPoint": return isValidCoordinates(coordinates); case "Point": return isValidCoordinate(coordinates); default: return false; } } function isValidFeature(value) { return isObject(value) && value.type === "Feature" && isValidGeometry(value.geometry); } function isValidFeatureCollection(value) { return isObject(value) && value.type === "FeatureCollection" && Array.isArray(value.features) && value.features.every(isValidFeature); } var geoJson = attachDescription(isValidFeatureCollection, "a GeoJSON object"); // packages/ag-charts-core/src/structures/graph.ts var AdjacencyListGraph = class { constructor(cachedNeighboursEdge, processedEdge, singleValueEdges) { this._vertexCount = 0; this._edgeCount = 0; this.pendingProcessingEdgesFrom = []; this.pendingProcessingEdgesTo = []; this.cachedNeighboursEdge = cachedNeighboursEdge; this.processedEdge = processedEdge; this.singleValueEdges = singleValueEdges; } clear() { this._vertexCount = 0; this._edgeCount = 0; this.pendingProcessingEdgesFrom = []; this.pendingProcessingEdgesTo = []; this.singleValueEdges?.clear(); } getVertexCount() { return this._vertexCount; } getEdgeCount() { return this._edgeCount; } addVertex(value) { const vertex = new Vertex(value); this._vertexCount++; return vertex; } addEdge(from3, to, edge) { if (edge === this.cachedNeighboursEdge) { from3.updateCachedNeighbours().set(to.value, to); } else if (edge === this.processedEdge) { this.pendingProcessingEdgesFrom.push(from3); this.pendingProcessingEdgesTo.push(to); } const { edges } = from3; const vertices = edges.get(edge); if (!vertices) { edges.set(edge, [to]); this._edgeCount++; } else if (!vertices.includes(to)) { if (this.singleValueEdges?.has(edge)) { edges.set(edge, [to]); } else { vertices.push(to); this._edgeCount++; } } } removeVertex(vertex) { this._vertexCount--; const edges = vertex.edges; if (!edges) return; for (const [, adjacentVertices] of edges) { this._vertexCount -= adjacentVertices.length; } vertex.clear(); } removeEdge(from3, to, edge) { const neighbours = from3.edges.get(edge); if (!neighbours) return; const index = neighbours.indexOf(to); if (index === -1) return; neighbours.splice(index, 1); if (neighbours.length === 0) { from3.edges.delete(edge); } this._edgeCount--; if (edge === this.cachedNeighboursEdge) { from3.readCachedNeighbours()?.delete(to.value); } } removeEdges(from3, edgeValue) { from3.edges.delete(edgeValue); } getVertexValue(vertex) { return vertex.value; } // Iterate all the neighbours of a given vertex. *neighbours(from3) { for (const [, adjacentVertices] of from3.edges) { for (const adjacentVertex of adjacentVertices) { yield adjacentVertex; } } } // Iterate all the neighbours and their edges of a given vertex *neighboursAndEdges(from3) { for (const [edge, adjacentVertices] of from3.edges) { for (const adjacentVertex of adjacentVertices) { yield [adjacentVertex, edge]; } } } // Get the set of neighbours along a given edge. neighboursWithEdgeValue(from3, edgeValue) { return from3.edges.get(edgeValue); } // Find the first neighbour along the given edge. findNeighbour(from3, edgeValue) { return from3.edges.get(edgeValue)?.[0]; } // Find the value of the first neighbour along the given edge. findNeighbourValue(from3, edgeValue) { const neighbour = this.findNeighbour(from3, edgeValue); if (!neighbour) return; return this.getVertexValue(neighbour); } // Find the first neighbour with a given value, optionally along a given edge. findNeighbourWithValue(from3, value, edgeValue) { const neighbours = edgeValue == null ? this.neighbours(from3) : this.neighboursWithEdgeValue(from3, edgeValue); if (!neighbours) return; for (const neighbour of neighbours) { if (this.getVertexValue(neighbour) === value) { return neighbour; } } } // Find a vertex by iterating an array of vertex values along a given edge. findVertexAlongEdge(from3, findValues, edgeValue) { if (edgeValue === this.cachedNeighboursEdge) { let found2; for (const value of findValues) { found2 = (found2 ?? from3).readCachedNeighbours()?.get(value); if (!found2) return; } return found2; } if (findValues.length === 0) return; let found = from3; for (const value of findValues) { const neighbours = found ? this.neighboursWithEdgeValue(found, edgeValue) : void 0; if (!neighbours) return; found = neighbours.find((n) => n.value === value); } return found; } adjacent(from3, to) { for (const [, adjacentVertices] of from3.edges) { if (adjacentVertices.includes(to)) return true; } return false; } }; var Vertex = class { constructor(value) { this.value = value; this.edges = /* @__PURE__ */ new Map(); } readCachedNeighbours() { return this._cachedNeighbours; } updateCachedNeighbours() { this._cachedNeighbours ?? (this._cachedNeighbours = /* @__PURE__ */ new Map()); return this._cachedNeighbours; } clear() { this.edges.clear(); this._cachedNeighbours?.clear(); } }; // packages/ag-charts-core/src/utils/data/json.ts var CLASS_INSTANCE_TYPE = "class-instance"; function jsonDiff(source, target, shallow) { if (isArray(target)) { if (!isArray(source) || source.length !== target.length || target.some((v, i) => jsonDiff(source[i], v, shallow) != null)) { return target; } } else if (isPlainObject(target)) { if (!isPlainObject(source)) { return target; } const result = {}; const allKeys = /* @__PURE__ */ new Set([ ...Object.keys(source), ...Object.keys(target) ]); for (const key of allKeys) { if (source[key] === target[key]) { continue; } else if (shallow?.has(key)) { result[key] = target[key]; } else if (typeof source[key] === typeof target[key]) { const diff = jsonDiff(source[key], target[key], shallow); if (diff !== null) { result[key] = diff; } } else { result[key] = target[key]; } } return Object.keys(result).length ? result : null; } else if (source !== target) { return target; } return null; } function jsonPropertyCompare(source, target) { for (const key of Object.keys(source)) { if (source[key] === target?.[key]) continue; return false; } return true; } function deepClone(source, opts) { if (isArray(source)) { return cloneArray(source, opts); } if (isPlainObject(source)) { return clonePlainObject(source, opts); } if (source instanceof Map) { return new Map(deepClone(Array.from(source))); } return shallowClone(source); } function cloneArray(source, opts) { const result = []; const seen = opts?.seen; for (const item of source) { if (typeof item === "object" && seen?.includes(item)) { warn("cycle detected in array", item); continue; } seen?.push(item); result.push(deepClone(item, opts)); seen?.pop(); } return result; } function clonePlainObject(source, opts) { const target = {}; for (const key of Object.keys(source)) { if (opts?.assign?.has(key)) { target[key] = source[key]; } else if (opts?.shallow?.has(key)) { target[key] = shallowClone(source[key]); } else { target[key] = deepClone(source[key], opts); } } return target; } function shallowClone(source) { if (isArray(source)) { return source.slice(0); } if (isPlainObject(source)) { return { ...source }; } if (isDate(source)) { return new Date(source); } if (isRegExp(source)) { return new RegExp(source.source, source.flags); } return source; } function jsonWalk(json, visit, skip, parallelJson, ctx, acc) { if (isArray(json)) { acc = visit(json, parallelJson, ctx, acc); let index = 0; for (const node of json) { acc = jsonWalk(node, visit, skip, parallelJson?.[index], ctx, acc); index++; } } else if (isPlainObject(json)) { acc = visit(json, parallelJson, ctx, acc); for (const key of Object.keys(json)) { if (skip?.has(key)) { continue; } const value = json[key]; acc = jsonWalk(value, visit, skip, parallelJson?.[key], ctx, acc); } } return acc; } function jsonApply(target, source, params = {}) { const { path, matcherPath = path?.replace(/(\[[0-9+]+])/i, "[]"), skip = [] } = params; if (target == null) { throw new Error(`AG Charts - target is uninitialised: ${path ?? ""}`); } if (source == null) { return target; } if (isProperties(target)) { return target.set(source); } const targetAny = target; const targetType = classify(target); for (const property of Object.keys(source)) { if (SKIP_JS_BUILTINS.has(property)) continue; const propertyMatcherPath = `${matcherPath ? matcherPath + "." : ""}${property}`; if (skip.includes(propertyMatcherPath)) continue; const newValue = source[property]; const propertyPath = `${path ? path + "." : ""}${property}`; const targetClass = targetAny.constructor; const currentValue = targetAny[property]; try { const currentValueType = classify(currentValue); const newValueType = classify(newValue); if (targetType === CLASS_INSTANCE_TYPE && !(property in target || property === "context")) { if (newValue === void 0) continue; warn(`unable to set [${propertyPath}] in ${targetClass?.name} - property is unknown`); continue; } if (currentValueType != null && newValueType != null && newValueType !== currentValueType && (currentValueType !== CLASS_INSTANCE_TYPE || newValueType !== "object")) { warn( `unable to set [${propertyPath}] in ${targetClass?.name} - can't apply type of [${newValueType}], allowed types are: [${currentValueType}]` ); continue; } if (isProperties(currentValue)) { if (newValue === void 0) { currentValue.clear(); } else { currentValue.set(newValue); } } else if (newValueType === "object" && property !== "context") { if (!(property in targetAny)) { warn(`unable to set [${propertyPath}] in ${targetClass?.name} - property is unknown`); continue; } if (currentValue == null) { targetAny[property] = newValue; } else { jsonApply(currentValue, newValue, { ...params, path: propertyPath, matcherPath: propertyMatcherPath }); } } else { targetAny[property] = newValue; } } catch (error2) { warn(`unable to set [${propertyPath}] in [${targetClass?.name}]; nested error is: ${error2.message}`); } } return target; } function classify(value) { if (value == null) { return null; } if (isHtmlElement(value) || isDate(value)) { return "primitive"; } if (isArray(value)) { return "array"; } if (isObject(value)) { return isPlainObject(value) ? "object" : CLASS_INSTANCE_TYPE; } if (isFunction(value)) { return "function"; } return "primitive"; } // packages/ag-charts-core/src/utils/dom/domEvents.ts function attachListener(element, eventName, handler, options) { element.addEventListener(eventName, handler, options); return () => element.removeEventListener(eventName, handler, options); } // packages/ag-charts-core/src/utils/dom/keynavUtil.ts function addEscapeEventListener(elem, onEscape, keyCodes = ["Escape"]) { return attachListener(elem, "keydown", (event) => { if (matchesKey(event, ...keyCodes)) { onEscape(event); } }); } function addMouseCloseListener(menu, hideCallback) { const removeEvent = attachListener(getWindow(), "mousedown", (event) => { if ([0, 2].includes(event.button) && !containsEvent(menu, event)) { hideCallback(); removeEvent(); } }); return removeEvent; } function addTouchCloseListener(menu, hideCallback) { const removeEvent = attachListener(getWindow(), "touchstart", (event) => { const touches = Array.from(event.targetTouches); if (touches.some((touch) => !containsEvent(menu, touch))) { hideCallback(); removeEvent(); } }); return removeEvent; } function containsEvent(container, event) { if (isElement(event.target) && event.target.shadowRoot != null) { return true; } return isNode(event.target) && container.contains(event.target); } function addOverrideFocusVisibleEventListener(menu, buttons, overrideFocusVisible) { const setFocusVisible = (value) => { for (const btn of buttons) { setAttribute(btn, "data-focus-visible-override", value); } }; setFocusVisible(overrideFocusVisible); return attachListener(menu, "keydown", () => setFocusVisible(true), { once: true }); } function hasNoModifiers(event) { return !(event.shiftKey || event.altKey || event.ctrlKey || event.metaKey); } function matchesKey(event, ...keys) { return hasNoModifiers(event) && keys.includes(event.key); } function linkTwoButtons(src, dst, key) { return attachListener(src, "keydown", (event) => { if (matchesKey(event, key)) { dst.focus(); } }); } var PREV_NEXT_KEYS = { horizontal: { nextKey: "ArrowRight", prevKey: "ArrowLeft" }, vertical: { nextKey: "ArrowDown", prevKey: "ArrowUp" } }; function initRovingTabIndex(opts) { const { orientation, buttons, wrapAround = false, onEscape, onFocus, onBlur } = opts; const { nextKey, prevKey } = PREV_NEXT_KEYS[orientation]; const setTabIndices = (event) => { if (event.target && "tabIndex" in event.target) { for (const b of buttons) { b.tabIndex = -1; } event.target.tabIndex = 0; } }; const [c, m] = wrapAround ? [buttons.length, buttons.length] : [0, Infinity]; const cleanup = new CleanupRegistry(); for (let i = 0; i < buttons.length; i++) { const prev = buttons[(c + i - 1) % m]; const curr = buttons[i]; const next = buttons[(c + i + 1) % m]; cleanup.register( attachListener(curr, "focus", setTabIndices), onFocus && attachListener(curr, "focus", onFocus), onBlur && attachListener(curr, "blur", onBlur), onEscape && addEscapeEventListener(curr, onEscape), prev && linkTwoButtons(curr, prev, prevKey), next && linkTwoButtons(curr, next, nextKey), attachListener(curr, "keydown", (event) => { if (matchesKey(event, nextKey, prevKey)) { event.preventDefault(); } }) ); curr.tabIndex = i === 0 ? 0 : -1; } return cleanup; } function makeAccessibleClickListener(element, onclick) { return (event) => { if (element.ariaDisabled === "true") { return event.preventDefault(); } onclick(event); }; } function isButtonClickEvent(event) { if ("button" in event) { return event.button === 0; } return hasNoModifiers(event) && (event.code === "Space" || event.key === "Enter"); } function getLastFocus(sourceEvent) { const target = sourceEvent?.target; if (isElement(target) && "tabindex" in target.attributes) { return target; } return void 0; } function stopPageScrolling(element) { return attachListener(element, "keydown", (event) => { if (event.defaultPrevented) return; const shouldPrevent = getAttribute(event.target, "data-preventdefault", true); if (shouldPrevent && matchesKey(event, "ArrowRight", "ArrowLeft", "ArrowDown", "ArrowUp")) { event.preventDefault(); } }); } // packages/ag-charts-core/src/identity/id.ts var ID_MAP = /* @__PURE__ */ new Map(); var nextElementID = 1; function resetIds() { ID_MAP.clear(); nextElementID = 1; } function createId(instance) { const constructor = instance.constructor; let className = Object.hasOwn(constructor, "className") ? constructor.className : constructor.name; inDevelopmentMode(() => { if (!className) { throw new Error(`The ${String(constructor)} is missing the 'className' property.`); } }); className ?? (className = "Unknown"); const nextId = (ID_MAP.get(className) ?? 0) + 1; ID_MAP.set(className, nextId); return `${className}-${nextId}`; } function createElementId() { return `ag-charts-${nextElementID++}`; } function generateUUID() { return crypto.randomUUID?.() ?? generateUUIDv4(); } function generateUUIDv4() { const uuidArray = new Uint8Array(16); crypto.getRandomValues(uuidArray); uuidArray[6] = uuidArray[6] & 15 | 64; uuidArray[8] = uuidArray[8] & 63 | 128; let uuid = ""; for (let i = 0; i < uuidArray.length; i++) { if (i === 4 || i === 6 || i === 8 || i === 10) { uuid += "-"; } uuid += uuidArray[i].toString(16).padStart(2, "0"); } return uuid; } // packages/ag-charts-core/src/utils/data/linkedList.ts function insertListItemsSorted(list, items, cmp) { let head = list; let current = head; for (const value of items) { if (head == null || cmp(head.value, value) > 0) { head = { value, next: head }; current = head; } else { current = current; while (current.next != null && cmp(current.next.value, value) <= 0) { current = current.next; } current.next = { value, next: current.next }; } } return head; } // packages/ag-charts-core/src/state/memo.ts var memorizedFns = /* @__PURE__ */ new WeakMap(); function memo(params, fnGenerator) { const serialisedParams = JSON.stringify(params, null, 0); if (!memorizedFns.has(fnGenerator)) { memorizedFns.set(fnGenerator, /* @__PURE__ */ new Map()); } if (!memorizedFns.get(fnGenerator)?.has(serialisedParams)) { memorizedFns.get(fnGenerator)?.set(serialisedParams, fnGenerator(params)); } return memorizedFns.get(fnGenerator)?.get(serialisedParams); } var MemoizeNode = class { constructor() { this.weak = /* @__PURE__ */ new WeakMap(); this.strong = /* @__PURE__ */ new Map(); this.set = false; this.value = void 0; } }; function simpleMemorize2(fn, cacheCallback) { let root = new MemoizeNode(); const memoised = (...p) => { let current = root; for (const param of p) { const target = typeof param === "object" || typeof param === "symbol" ? current.weak : current.strong; let next = target.get(param); if (next == null) { next = new MemoizeNode(); target.set(param, next); } current = next; } if (current.set) { cacheCallback?.("hit", fn, p); return current.value; } else { const out = fn(...p); current.set = true; current.value = out; cacheCallback?.("miss", fn, p); return out; } }; memoised.reset = () => { root = new MemoizeNode(); }; return memoised; } function simpleMemorize(fn, cacheCallback) { const primitiveCache = /* @__PURE__ */ new Map(); const paramsToKeys = (...params) => { return params.map((v) => { if (typeof v === "object") return v; if (typeof v === "symbol") return v; if (!primitiveCache.has(v)) { primitiveCache.set(v, { v }); } return primitiveCache.get(v); }); }; const empty = {}; const cache = /* @__PURE__ */ new WeakMap(); return (...p) => { const keys = p.length === 0 ? [empty] : paramsToKeys(...p); let currentCache = cache; for (const key of keys.slice(0, -1)) { if (!currentCache.has(key)) { currentCache.set(key, /* @__PURE__ */ new WeakMap()); } currentCache = currentCache.get(key); } const finalKey = keys.at(-1); let cachedValue = currentCache.get(finalKey); if (cachedValue) { cacheCallback?.("hit", fn, p); } else { cachedValue = fn(...p); currentCache.set(finalKey, cachedValue); cacheCallback?.("miss", fn, p); } return cachedValue; }; } // packages/ag-charts-core/src/utils/data/nearest.ts function nearestSquared(x, y, objects, maxDistanceSquared = Infinity) { const result = { nearest: void 0, distanceSquared: maxDistanceSquared }; for (const obj of objects) { const thisDistance = obj.distanceSquared(x, y); if (thisDistance === 0) { return { nearest: obj, distanceSquared: 0 }; } else if (thisDistance < result.distanceSquared) { result.nearest = obj; result.distanceSquared = thisDistance; } } return result; } function nearestSquaredInContainer(x, y, container, maxDistanceSquared = Infinity) { const { x: tx = x, y: ty = y } = container.transformPoint?.(x, y) ?? {}; const result = { nearest: void 0, distanceSquared: maxDistanceSquared }; for (const child of container.children) { const { nearest, distanceSquared: distanceSquared2 } = child.nearestSquared(tx, ty, result.distanceSquared); if (distanceSquared2 === 0) { return { nearest, distanceSquared: distanceSquared2 }; } else if (distanceSquared2 < result.distanceSquared) { result.nearest = nearest; result.distanceSquared = distanceSquared2; } } return result; } // packages/ag-charts-core/src/utils/geometry/padding.ts var Padding = class extends BaseProperties { constructor(top = 0, right = top, bottom = top, left = right) { super(); this.top = top; this.right = right; this.bottom = bottom; this.left = left; } }; __decorateClass([ addFakeTransformToInstanceProperty ], Padding.prototype, "top", 2); __decorateClass([ addFakeTransformToInstanceProperty ], Padding.prototype, "right", 2); __decorateClass([ addFakeTransformToInstanceProperty ], Padding.prototype, "bottom", 2); __decorateClass([ addFakeTransformToInstanceProperty ], Padding.prototype, "left", 2); // packages/ag-charts-core/src/utils/geometry/placement.ts function calculatePlacement(naturalWidth, naturalHeight, container, bounds) { let { top, right, bottom, left, width: width2, height: height2 } = bounds; if (left != null) { if (width2 != null) { right = container.width - left + width2; } else if (right != null) { width2 = container.width - left - right; } } else if (right != null && width2 != null) { left = container.width - right - width2; } if (top != null) { if (height2 != null) { bottom = container.height - top - height2; } else if (bottom != null) { height2 = container.height - bottom - top; } } else if (bottom != null && height2 != null) { top = container.height - bottom - height2; } if (width2 == null) { if (height2 == null) { height2 = naturalHeight; width2 = naturalWidth; } else { width2 = Math.ceil(naturalWidth * height2 / naturalHeight); } } else { height2 ?? (height2 = Math.ceil(naturalHeight * width2 / naturalWidth)); } if (left == null) { if (right == null) { left = Math.floor((container.width - width2) / 2); } else { left = container.width - right - width2; } } if (top == null) { if (bottom == null) { top = Math.floor((container.height - height2) / 2); } else { top = container.height - height2 - bottom; } } return { x: left, y: top, width: width2, height: height2 }; } // packages/ag-charts-core/src/state/stateMachine.ts var debugColor = "color: green"; var debugQuietColor = "color: grey"; function StateMachineProperty() { return addObserverToInstanceProperty(() => { }); } function applyProperties(parentState, childState) { const childProperties = listDecoratedProperties(childState); if (childProperties.length === 0) return; const properties = extractDecoratedProperties(parentState); for (const property of childProperties) { if (property in properties) { childState[property] = properties[property]; } } } var AbstractStateMachine = class { transitionRoot(event, data) { if (this.parent) { this.parent.transitionRoot(event, data); } else { this.transition(event, data); } } }; var _StateMachine = class _StateMachine extends AbstractStateMachine { constructor(defaultState, states, enterEach) { super(); this.defaultState = defaultState; this.states = states; this.enterEach = enterEach; this.debug = create(true, "animation"); this.state = defaultState; this.debug(`%c${this.constructor.name} | init -> ${defaultState}`, debugColor); } // TODO: handle events which do not require data without requiring `undefined` to be passed as as parameter, while // also still requiring data to be passed to those events which do require it. transition(event, data) { const shouldTransitionSelf = this.transitionChild(event, data); if (!shouldTransitionSelf || this.state === _StateMachine.child || this.state === _StateMachine.parent) { return; } const currentState = this.state; const currentStateConfig = this.states[this.state]; let destination = currentStateConfig[event]; const debugPrefix = `%c${this.constructor.name} | ${this.state} -> ${event} ->`; if (Array.isArray(destination)) { destination = destination.find((transition) => { if (!transition.guard) return true; const valid = transition.guard(data); if (!valid) { this.debug(`${debugPrefix} (guarded)`, transition.target, debugQuietColor); } return valid; }); } else if (typeof destination === "object" && !(destination instanceof _StateMachine) && destination.guard && !destination.guard(data)) { this.debug(`${debugPrefix} (guarded)`, destination.target, debugQuietColor); return; } if (!destination) { this.debug(`${debugPrefix} ${this.state}`, debugQuietColor); return; } const destinationState = this.getDestinationState(destination); const exitFn = destinationState === this.state ? void 0 : currentStateConfig.onExit; this.debug(`${debugPrefix} ${destinationState}`, debugColor); this.state = destinationState; if (typeof destination === "function") { destination(data); } else if (typeof destination === "object" && !(destination instanceof _StateMachine)) { destination.action?.(data); } exitFn?.(); this.enterEach?.(currentState, destinationState); if (destinationState !== currentState && destinationState !== _StateMachine.child && destinationState !== _StateMachine.parent) { this.states[destinationState].onEnter?.(currentState, data); } } transitionAsync(event, data) { setTimeout(() => { this.transition(event, data); }, 0); } is(value) { if (this.state === _StateMachine.child && this.childState) { return this.childState.is(value); } return this.state === value; } resetHierarchy() { this.debug( `%c${this.constructor.name} | ${this.state} -> [resetHierarchy] -> ${this.defaultState}`, "color: green" ); this.state = this.defaultState; } transitionChild(event, data) { if (this.state !== _StateMachine.child || !this.childState) return true; applyProperties(this, this.childState); this.childState.transition(event, data); if (!this.childState.is(_StateMachine.parent)) return true; this.debug(`%c${this.constructor.name} | ${this.state} -> ${event} -> ${this.defaultState}`, debugColor); this.state = this.defaultState; this.states[this.state].onEnter?.(); this.childState.resetHierarchy(); return false; } getDestinationState(destination) { let state = this.state; if (typeof destination === "string") { state = destination; } else if (destination instanceof _StateMachine) { this.childState = destination; this.childState.parent = this; state = _StateMachine.child; } else if (typeof destination === "object") { if (destination.target instanceof _StateMachine) { this.childState = destination.target; this.childState.parent = this; state = _StateMachine.child; } else if (destination.target != null) { state = destination.target; } } return state; } }; _StateMachine.child = "__child"; _StateMachine.parent = "__parent"; var StateMachine = _StateMachine; var ParallelStateMachine = class extends AbstractStateMachine { constructor(...stateMachines) { super(); this.stateMachines = stateMachines; for (const stateMachine of stateMachines) { stateMachine.parent = this; } } transition(event, data) { for (const stateMachine of this.stateMachines) { applyProperties(this, stateMachine); stateMachine.transition(event, data); } } transitionAsync(event, data) { for (const stateMachine of this.stateMachines) { applyProperties(this, stateMachine); stateMachine.transitionAsync(event, data); } } }; // packages/ag-charts-core/src/rendering/textMeasurer.ts var TextMeasurer = class { constructor(ctx, measureTextCached) { this.ctx = ctx; this.measureTextCached = measureTextCached; this.baselineMap = /* @__PURE__ */ new Map(); this.charMap = /* @__PURE__ */ new Map(); this.lineHeightCache = null; } baselineDistance(textBaseline) { if (textBaseline === "alphabetic") return 0; if (this.baselineMap.has(textBaseline)) { return this.baselineMap.get(textBaseline); } this.ctx.textBaseline = textBaseline; const { alphabeticBaseline } = this.ctx.measureText(""); this.baselineMap.set(textBaseline, alphabeticBaseline); this.ctx.textBaseline = "alphabetic"; return alphabeticBaseline; } lineHeight() { this.lineHeightCache ?? (this.lineHeightCache = this.measureText("").height); return this.lineHeightCache; } measureText(text) { const m = this.measureTextCached?.(text) ?? this.ctx.measureText(text); const { width: width2, // Apply fallbacks for environments like `node-canvas` where some metrics may be missing. fontBoundingBoxAscent: ascent = m.emHeightAscent, fontBoundingBoxDescent: descent = m.emHeightDescent } = m; const height2 = ascent + descent; return { width: width2, height: height2, ascent, descent }; } measureLines(text) { const lines = typeof text === "string" ? text.split(LineSplitter) : text; let width2 = 0; let height2 = 0; const lineMetrics = lines.map((line) => { const b = this.measureText(line); if (width2 < b.width) { width2 = b.width; } height2 += b.height; return { text: line, ...b }; }); return { width: width2, height: height2, lineMetrics }; } textWidth(text, estimate) { if (estimate) { let estimatedWidth = 0; for (let i = 0; i < text.length; i++) { estimatedWidth += this.textWidth(text.charAt(i)); } return estimatedWidth; } if (text.length > 1) { return this.ctx.measureText(text).width; } return this.charMap.get(text) ?? this.charWidth(text); } charWidth(char) { const { width: width2 } = this.ctx.measureText(char); this.charMap.set(char, width2); return width2; } }; var instanceMap = new LRUCache(50); function cachedTextMeasurer(font) { if (typeof font === "object") { font = toFontString(font); } let cachedMeasurer = instanceMap.get(font); if (cachedMeasurer) return cachedMeasurer; const cachedTextMetrics = new LRUCache(1e4); const ctx = createCanvasContext(); ctx.font = font; cachedMeasurer = new TextMeasurer(ctx, (text) => { let textMetrics = cachedTextMetrics.get(text); if (textMetrics) return textMetrics; textMetrics = ctx.measureText(text); cachedTextMetrics.set(text, textMetrics); return textMetrics; }); instanceMap.set(font, cachedMeasurer); return cachedMeasurer; } cachedTextMeasurer.clear = () => instanceMap.clear(); function measureTextSegments(textSegments, defaultFont) { let currentLine = { segments: [], width: 0, height: 0, ascent: 0, descent: 0 }; const lineMetrics = [currentLine]; for (const segment of textSegments) { const { text, fontSize = defaultFont.fontSize, fontStyle = defaultFont.fontStyle, fontWeight: fontWeight2 = defaultFont.fontWeight, fontFamily = defaultFont.fontFamily, ...rest } = segment; const font = { fontSize, fontStyle, fontWeight: fontWeight2, fontFamily }; const measurer = cachedTextMeasurer(font); const textLines = toTextString(text).split(LineSplitter); for (let i = 0; i < textLines.length; i++) { const textLine = textLines[i]; const textMetrics = measurer.measureText(textLine); if (i > 0) { currentLine = { segments: [], width: 0, height: 0, ascent: 0, descent: 0 }; lineMetrics.push(currentLine); } if (textLine) { currentLine.width += textMetrics.width; currentLine.ascent = Math.max(currentLine.ascent, textMetrics.ascent); currentLine.descent = Math.max(currentLine.descent, textMetrics.descent); currentLine.height = Math.max(currentLine.height, currentLine.ascent + currentLine.descent); currentLine.segments.push({ ...font, ...rest, text: textLine, textMetrics }); } } } let maxWidth = 0; let totalHeight = 0; for (const line of lineMetrics) { maxWidth = Math.max(maxWidth, line.width); totalHeight += line.height; } return { width: maxWidth, height: totalHeight, lineMetrics }; } // packages/ag-charts-core/src/utils/dom/domElements.ts function createElement(tagName, className, style2) { const element = getDocument().createElement(tagName); if (typeof className === "object") { style2 = className; className = void 0; } if (className) { for (const name of className.split(" ")) { element.classList.add(name); } } if (style2) { Object.assign(element.style, style2); } return element; } function createSvgElement(elementName) { return getDocument().createElementNS("http://www.w3.org/2000/svg", elementName); } // packages/ag-charts-core/src/utils/dom/domDownload.ts function downloadUrl(dataUrl, fileName) { const body = getDocument("body"); const element = createElement("a", { display: "none" }); element.href = dataUrl; element.download = fileName; body.appendChild(element); element.click(); setTimeout(() => element.remove()); } // packages/ag-charts-core/src/utils/text/textWrapper.ts function shouldHideOverflow(clippedResult, options) { return options.overflow === "hide" && clippedResult.some(isTextTruncated); } function wrapTextOrSegments(input, options) { return isArray(input) ? wrapTextSegments(input, options) : wrapLines(toTextString(input), options).join("\n"); } function wrapText(text, options) { return wrapLines(text, options).join("\n"); } function wrapLines(text, options) { return textWrap(text, options); } function truncateLine(text, measurer, maxWidth, ellipsisForce) { const ellipsisWidth = measurer.textWidth(EllipsisChar); let estimatedWidth = 0; let i = 0; for (; i < text.length; i++) { const charWidth = measurer.textWidth(text.charAt(i)); if (estimatedWidth + charWidth > maxWidth) break; estimatedWidth += charWidth; } if (text.length === i && (!ellipsisForce || estimatedWidth + ellipsisWidth <= maxWidth)) { return ellipsisForce ? appendEllipsis(text) : text; } text = text.slice(0, i).trimEnd(); while (text.length && measurer.textWidth(text) + ellipsisWidth > maxWidth) { text = text.slice(0, -1).trimEnd(); } return appendEllipsis(text); } function textWrap(text, options, widthOffset = 0) { const lines = text.split(LineSplitter); const measurer = cachedTextMeasurer(options.font); const result = []; if (options.textWrap === "never") { for (const line of lines) { const truncatedLine = truncateLine(line.trimEnd(), measurer, Math.max(0, options.maxWidth - widthOffset)); if (!truncatedLine) break; result.push(truncatedLine); widthOffset = 0; } return shouldHideOverflow(result, options) ? [] : result; } const wrapHyphenate = options.textWrap === "hyphenate"; const wrapOnSpace = options.textWrap == null || options.textWrap === "on-space"; for (const untrimmedLine of lines) { let line = untrimmedLine.trimEnd(); if (line === "") { result.push(line); continue; } let i = 0; let estimatedWidth = 0; let lastSpaceIndex = 0; if (!result.length) { estimatedWidth = widthOffset; } while (i < line.length) { const char = line.charAt(i); if (char === " ") { lastSpaceIndex = i; } estimatedWidth += measurer.textWidth(char); if (estimatedWidth > options.maxWidth) { if (i === 0) { line = ""; break; } let actualWidth = measurer.textWidth(line.slice(0, i + 1)); if (!result.length) { actualWidth += widthOffset; } if (actualWidth <= options.maxWidth) { estimatedWidth = actualWidth; i++; continue; } if (lastSpaceIndex) { const nextWord = getWordAt(line, lastSpaceIndex + 1); const textWidth = measurer.textWidth(nextWord); if (textWidth <= options.maxWidth) { result.push(line.slice(0, lastSpaceIndex).trimEnd()); line = line.slice(lastSpaceIndex).trimStart(); i = 0; estimatedWidth = 0; lastSpaceIndex = 0; continue; } else if (wrapOnSpace && textWidth > options.maxWidth) { result.push( line.slice(0, lastSpaceIndex).trimEnd(), truncateLine(line.slice(lastSpaceIndex).trimStart(), measurer, options.maxWidth, true) ); } } else if (wrapOnSpace) { const newLine2 = truncateLine(line, measurer, options.maxWidth, true); if (newLine2) { result.push(newLine2); } } if (wrapOnSpace) { line = ""; break; } const postfix = wrapHyphenate ? "-" : ""; let newLine = line.slice(0, i).trim(); while (newLine.length && measurer.textWidth(newLine + postfix) > options.maxWidth) { newLine = newLine.slice(0, -1).trimEnd(); } if (newLine && newLine !== TrimEdgeGuard) { result.push(newLine + postfix); } else { line = ""; break; } line = line.slice(newLine.length).trimStart(); i = -1; estimatedWidth = 0; lastSpaceIndex = 0; } i++; } if (line) { result.push(line); } } avoidOrphans(result, measurer, options); const clippedResult = clipLines(result, measurer, options); return shouldHideOverflow(clippedResult, options) ? [] : clippedResult; } function getWordAt(text, position) { const nextSpaceIndex = text.indexOf(" ", position); return nextSpaceIndex === -1 ? text.slice(position) : text.slice(position, nextSpaceIndex); } function clipLines(lines, measurer, options) { if (!isFiniteNumber(options.maxHeight)) { return lines; } const { height: height2, lineMetrics } = measurer.measureLines(lines); if (height2 <= options.maxHeight) { return lines; } for (let i = 0, cumulativeHeight = 0; i < lineMetrics.length; i++) { cumulativeHeight += lineMetrics[i].height; if (cumulativeHeight > options.maxHeight) { if (options.overflow === "hide" || i === 0) return []; const clippedResults = lines.slice(0, i); const lastLine = clippedResults.pop(); return clippedResults.concat( isTextTruncated(lastLine) ? lastLine : truncateLine(lastLine, measurer, options.maxWidth, true) ); } } return lines; } function avoidOrphans(lines, measurer, options) { if (options.avoidOrphans === false || lines.length < 2) return; const { length: length2 } = lines; const lastLine = lines[length2 - 1]; const beforeLast = lines[length2 - 2]; if (beforeLast.length < lastLine.length) return; const lastSpaceIndex = beforeLast.lastIndexOf(" "); if (lastSpaceIndex === -1 || lastSpaceIndex === beforeLast.indexOf(" ") || lastLine.includes(" ")) return; const lastWord = beforeLast.slice(lastSpaceIndex + 1); if (measurer.textWidth(lastLine + lastWord) <= options.maxWidth) { lines[length2 - 2] = beforeLast.slice(0, lastSpaceIndex); lines[length2 - 1] = lastWord + " " + lastLine; } } function wrapTextSegments(textSegments, options) { const { maxHeight = Infinity } = options; const result = []; let lineWidth = 0; let totalHeight = 0; function truncateLastSegment() { const lastSegment = result.pop(); if (!lastSegment) return; const measurer = cachedTextMeasurer(lastSegment); const truncatedText = truncateLine(lastSegment.text, measurer, options.maxWidth, true); const textMetrics = measurer.measureText(truncatedText); result.push({ ...lastSegment, text: truncatedText, textMetrics }); } for (const { width: width2, height: height2, segments } of measureTextSegments(textSegments, options.font).lineMetrics) { if (totalHeight + height2 > maxHeight) { if (result.length) { truncateLastSegment(); } break; } if (lineWidth + width2 <= options.maxWidth) { lineWidth += width2; totalHeight += height2; result.push(...segments); continue; } for (const segment of segments) { if (lineWidth + segment.textMetrics.width <= options.maxWidth) { lineWidth += segment.textMetrics.width; result.push(segment); continue; } const measurer = cachedTextMeasurer(segment); const guardedText = guardTextEdges(segment.text); const wrapOptions = { ...options, font: segment, maxHeight: maxHeight - totalHeight }; let wrappedLines = textWrap(guardedText, { ...wrapOptions, overflow: "hide" }, lineWidth); if (wrappedLines.length === 0) { if (options.textWrap === "never") { wrappedLines = textWrap(guardedText, wrapOptions, lineWidth); } else { wrappedLines = textWrap(guardedText, wrapOptions); const lastSegment = result.at(-1); if (lastSegment) { lastSegment.text += "\n"; lineWidth = 0; } } } if (wrappedLines.length === 0) { truncateLastSegment(); break; } const truncationIndex = wrappedLines.findIndex(isTextTruncated); if (truncationIndex !== -1) { wrappedLines = wrappedLines.slice(0, truncationIndex + 1); } const lastLine = wrappedLines.at(-1); for (const wrappedLine of wrappedLines) { const cleanLine = unguardTextEdges(wrappedLine); const textMetrics = measurer.measureText(cleanLine); const subSegment = { ...segment, text: cleanLine, textMetrics }; if (wrappedLine === lastLine) { lineWidth += textMetrics.width; } else { subSegment.text += "\n"; lineWidth = 0; } totalHeight += textMetrics.height; result.push(subSegment); } if (truncationIndex !== -1) break; } } return result; } // packages/ag-charts-core/src/utils/data/visibleRange.ts function rescaleVisibleRange(visibleRange, [s0, s1], [d0, d1]) { const dr = d1 - d0; const vr = s1 - s0; const vd0 = s0 + vr * visibleRange[0]; const vd1 = s0 + vr * visibleRange[1]; return [(vd0 - d0) / dr, (vd1 - d0) / dr]; } // packages/ag-charts-core/src/utils/time/time/duration.ts var durationSecond = 1e3; var durationMinute = durationSecond * 60; var durationHour = durationMinute * 60; var durationDay = durationHour * 24; var durationWeek = durationDay * 7; var durationMonth = durationDay * 30; var durationYear = durationDay * 365; // packages/ag-charts-core/src/utils/time/time/encoding.ts var tzOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset() * durationMinute; var unitEncoding = { millisecond: { milliseconds: 1, hierarchy: "day", encode(date2) { return date2.getTime(); }, decode(encoded) { return new Date(encoded); } }, second: { milliseconds: durationSecond, hierarchy: "day", encode(date2, utc) { const offset = utc ? 0 : tzOffset; return Math.floor((date2.getTime() - offset) / durationSecond); }, decode(encoded, utc) { const offset = utc ? 0 : tzOffset; return new Date(offset + encoded * durationSecond); } }, minute: { milliseconds: durationMinute, hierarchy: "day", encode(date2, utc) { const offset = utc ? 0 : tzOffset; return Math.floor((date2.getTime() - offset) / durationMinute); }, decode(encoded, utc) { const offset = utc ? 0 : tzOffset; return new Date(offset + encoded * durationMinute); } }, hour: { milliseconds: durationHour, hierarchy: "day", encode(date2, utc) { const offset = utc ? 0 : tzOffset; return Math.floor((date2.getTime() - offset) / durationHour); }, decode(encoded, utc) { const offset = utc ? 0 : tzOffset; return new Date(offset + encoded * durationHour); } }, day: { milliseconds: durationDay, hierarchy: "month", encode(date2, utc) { const tzOffsetMs2 = utc ? 0 : date2.getTimezoneOffset() * durationMinute; return Math.floor((date2.getTime() - tzOffsetMs2) / durationDay); }, decode(encoded, utc) { let d; if (utc) { d = /* @__PURE__ */ new Date(0); d.setUTCDate(d.getUTCDate() + encoded); d.setUTCHours(0, 0, 0, 0); } else { d = new Date(1970, 0, 1); d.setDate(d.getDate() + encoded); } return d; } }, month: { milliseconds: durationMonth, hierarchy: "year", encode(date2, utc) { if (utc) { return date2.getUTCFullYear() * 12 + date2.getUTCMonth(); } else { return date2.getFullYear() * 12 + date2.getMonth(); } }, decode(encoded, utc) { if (utc) { const year = Math.floor(encoded / 12); const m = encoded - year * 12; return new Date(Date.UTC(year, m, 1)); } else { const y = Math.floor(encoded / 12); const month = encoded - y * 12; return new Date(y, month, 1); } } }, year: { milliseconds: durationYear, hierarchy: void 0, encode(date2, utc) { if (utc) { return date2.getUTCFullYear(); } else { return date2.getFullYear(); } }, decode(encoded, utc) { let d; if (utc) { d = /* @__PURE__ */ new Date(); d.setUTCFullYear(encoded); d.setUTCMonth(0, 1); d.setUTCHours(0, 0, 0, 0); } else { d = new Date(encoded, 0, 1, 0, 0, 0, 0); } return d; } } }; // packages/ag-charts-core/src/utils/time/time/range.ts function timeInterval(interval) { return typeof interval === "string" ? { unit: interval, step: 1, epoch: void 0, utc: false } : { unit: interval.unit, step: interval.step ?? 1, epoch: interval.epoch, utc: interval.utc ?? false }; } function getOffset(unit, step, epoch, utc) { if (epoch == null) return 0; const encoding = unitEncoding[unit]; return Math.floor(encoding.encode(new Date(epoch), utc)) % step; } function encode(d, unit, step, utc, offset) { const encoding = unitEncoding[unit]; return Math.floor((encoding.encode(new Date(d), utc) - offset) / step); } function decode(encoded, unit, step, utc, offset) { const encoding = unitEncoding[unit]; return encoding.decode(encoded * step + offset, utc); } function encodingFloor(date2, unit, step, utc, offset) { const d = new Date(date2); const e = encode(d, unit, step, utc, offset); return decode(e, unit, step, utc, offset); } function encodingCeil(date2, unit, step, utc, offset) { const d = new Date(Number(date2) - 1); const e = encode(d, unit, step, utc, offset); return decode(e + 1, unit, step, utc, offset); } function intervalFloor(interval, date2) { const { unit, step, epoch, utc } = timeInterval(interval); const offset = getOffset(unit, step, epoch, utc); return encodingFloor(date2, unit, step, utc, offset); } function intervalCeil(interval, date2) { const { unit, step, epoch, utc } = timeInterval(interval); const offset = getOffset(unit, step, epoch, utc); return encodingCeil(date2, unit, step, utc, offset); } function intervalPrevious(interval, date2) { const { unit, step, epoch, utc } = timeInterval(interval); const offset = getOffset(unit, step, epoch, utc); return decode( encode(encodingCeil(date2, unit, step, utc, offset), unit, step, utc, offset) - 1, unit, step, utc, offset ); } function intervalNext(interval, date2) { const { unit, step, epoch, utc } = timeInterval(interval); const offset = getOffset(unit, step, epoch, utc); return decode( encode(encodingFloor(date2, unit, step, utc, offset), unit, step, utc, offset) + 1, unit, step, utc, offset ); } function intervalExtent(start2, stop, visibleRange) { if (start2.valueOf() > stop.valueOf()) { [start2, stop] = [stop, start2]; if (visibleRange != null) { visibleRange = [1 - visibleRange[1], 1 - visibleRange[0]]; } } if (visibleRange != null) { const delta = stop.valueOf() - start2.valueOf(); const t0 = start2.valueOf(); start2 = new Date(t0 + visibleRange[0] * delta); stop = new Date(t0 + visibleRange[1] * delta); } return [new Date(start2), new Date(stop)]; } function rangeData(interval, start2, stop, { extend = false, visibleRange = [0, 1], limit, defaultAlignment = "start" } = {}) { const params = timeInterval(interval); const { unit, step, utc } = params; let epoch; if (params.epoch != null) { epoch = params.epoch; } else if (defaultAlignment === "interval") { epoch = void 0; } else if (start2.valueOf() > stop.valueOf()) { epoch = stop; } else { epoch = start2; } const offset = getOffset(params.unit, params.step, epoch, params.utc); let [d0, d1] = intervalExtent(start2, stop, visibleRange); d0 = extend ? encodingFloor(d0, unit, step, utc, offset) : encodingCeil(d0, unit, step, utc, offset); d1 = extend ? encodingCeil(d1, unit, step, utc, offset) : encodingFloor(d1, unit, step, utc, offset); const e0 = encode(d0, unit, step, utc, offset); let e1 = encode(d1, unit, step, utc, offset); if (limit != null && e1 - e0 > limit) { e1 = e0 + limit; } return { range: [e0, e1], unit, step, utc, offset }; } function intervalRangeCount(interval, start2, stop, params) { const { range: [e0, e1] } = rangeData(interval, start2, stop, params); return Math.abs(e1 - e0); } function intervalRange(interval, start2, stop, params) { const { range: [e0, e1], unit, step, utc, offset } = rangeData(interval, start2, stop, params); const values = []; for (let e = e0; e <= e1; e += 1) { const d = decode(e, unit, step, utc, offset); values.push(d); } return values; } function intervalRangeNumeric(interval, start2, stop, params) { const { range: [e0, e1], unit, step, utc, offset } = rangeData(interval, start2, stop, params); const count = Math.max(0, e1 - e0 + 1); const encodedValues = new Array(count); for (let i = 0; i < count; i++) { encodedValues[i] = e0 + i; } return { encodedValues, encodingParams: { unit, step, utc, offset } }; } function decodeIntervalValue(encoded, encodingParams) { return decode(encoded, encodingParams.unit, encodingParams.step, encodingParams.utc, encodingParams.offset); } var tzOffsetMs = (/* @__PURE__ */ new Date()).getTimezoneOffset() * 6e4; var DURATION_SECOND = 1e3; var DURATION_MINUTE = 6e4; var DURATION_HOUR = 36e5; function encodedToTimestamp(encoded, encodingParams) { const { unit, step, utc, offset } = encodingParams; const rawEncoded = encoded * step + offset; switch (unit) { case "millisecond": return rawEncoded; case "second": { const tzOffset2 = utc ? 0 : tzOffsetMs; return tzOffset2 + rawEncoded * DURATION_SECOND; } case "minute": { const tzOffset2 = utc ? 0 : tzOffsetMs; return tzOffset2 + rawEncoded * DURATION_MINUTE; } case "hour": { const tzOffset2 = utc ? 0 : tzOffsetMs; return tzOffset2 + rawEncoded * DURATION_HOUR; } default: { const encoding = unitEncoding[unit]; return encoding.decode(rawEncoded, utc).valueOf(); } } } function intervalRangeStartIndex(interval, start2, stop, { extend, visibleRange, limit, defaultAlignment } = {}) { const { range: [s] } = rangeData(interval, start2, stop, { extend, visibleRange, limit, defaultAlignment }); const { range: [s0] } = rangeData(interval, start2, stop, { extend, limit, defaultAlignment }); return s - s0; } // packages/ag-charts-core/src/utils/time/time/index.ts function intervalUnit(interval) { return typeof interval === "string" ? interval : interval.unit; } function intervalStep(interval) { return typeof interval === "string" ? 1 : interval.step ?? 1; } function intervalEpoch(interval) { return typeof interval === "string" ? void 0 : interval.epoch; } function intervalHierarchy(interval) { return unitEncoding[intervalUnit(interval)].hierarchy; } function intervalMilliseconds(interval) { const step = intervalStep(interval); return step * unitEncoding[intervalUnit(interval)].milliseconds; } // packages/ag-charts-core/src/utils/time/ticks.ts var tInterval = (timeInterval2, step) => ({ duration: intervalMilliseconds(timeInterval2) * step, timeInterval: timeInterval2, step }); var TickIntervals = [ tInterval({ unit: "second" }, 1), tInterval({ unit: "second" }, 5), tInterval({ unit: "second" }, 15), tInterval({ unit: "second" }, 30), tInterval({ unit: "minute" }, 1), tInterval({ unit: "minute" }, 5), tInterval({ unit: "minute" }, 15), tInterval({ unit: "minute" }, 30), tInterval({ unit: "hour" }, 1), tInterval({ unit: "hour" }, 3), tInterval({ unit: "hour" }, 6), tInterval({ unit: "hour" }, 12), tInterval({ unit: "day" }, 1), tInterval({ unit: "day" }, 2), tInterval({ unit: "day", step: 7 }, 1), tInterval({ unit: "day", step: 7 }, 2), tInterval({ unit: "day", step: 7 }, 3), tInterval({ unit: "month" }, 1), tInterval({ unit: "month" }, 2), tInterval({ unit: "month" }, 3), tInterval({ unit: "month" }, 4), tInterval({ unit: "month" }, 6), tInterval({ unit: "year" }, 1) ]; var TickMultipliers = [1, 2, 5, 10]; function isCloseToInteger(n, delta) { return Math.abs(Math.round(n) - n) < delta; } function countTicks(d0, d1, step) { const extent2 = Math.abs(d1 - d0); return extent2 >= step ? Math.abs(d1 - d0) / step + 1 : 1; } function createTicks(start2, stop, count, minCount, maxCount, visibleRange) { if (start2 === stop) return { ticks: [start2], count: 1, firstTickIndex: 0 }; if (count < 2) return { ticks: [start2, stop], count: 2, firstTickIndex: 0 }; const step = tickStep(start2, stop, count, minCount, maxCount); if (!Number.isFinite(step)) return { ticks: [], count: 0, firstTickIndex: void 0 }; let d0 = start2; let d1 = stop; if (!isCloseToInteger(d0 / step, 1e-12)) { d0 = Math.ceil(d0 / step) * step; } if (!isCloseToInteger(d1 / step, 1e-12)) { d1 = Math.floor(d1 / step) * step; } if (visibleRange != null) { visibleRange = rescaleVisibleRange(visibleRange, [start2, stop], [d0, d1]); } const { ticks } = range(d0, d1, step, visibleRange); const firstTick = ticks.at(0); return { ticks, count: countTicks(d0, d1, step), firstTickIndex: firstTick == null ? void 0 : Math.round((firstTick - d0) / step) }; } var minPrimaryTickRatio = Math.floor(2 * durationWeek / durationMonth * 10) / 10; function isPrimaryTickInterval({ timeInterval: timeInterval2, step }) { const milliseconds = intervalMilliseconds(timeInterval2) * step; const hierarchy = intervalHierarchy(timeInterval2); const hierarchyMilliseconds = hierarchy ? intervalMilliseconds(hierarchy) : void 0; return milliseconds <= (hierarchyMilliseconds ?? Infinity) * minPrimaryTickRatio; } function defaultEpoch(timeInterval2, { weekStart }) { if (timeInterval2.unit === "day" && timeInterval2.step === 7) { return weekStart; } } function getTickTimeInterval(start2, stop, count, minCount, maxCount, { weekStart, primaryOnly = false, targetInterval }) { if (count <= 0) return; const target = targetInterval ?? Math.abs(stop - start2) / Math.max(count, 1); const i0 = TickIntervals.findLast((t) => (!primaryOnly || isPrimaryTickInterval(t)) && target > t.duration); const i1 = TickIntervals.find((t) => (!primaryOnly || isPrimaryTickInterval(t)) && target <= t.duration); if (i0 == null) { const step2 = Math.max(tickStep(start2, stop, count, minCount, maxCount), 1); return { unit: "millisecond", step: step2 }; } else if (i1 == null) { const step2 = targetInterval == null ? tickStep(start2 / durationYear, stop / durationYear, count, minCount, maxCount) : 1; return { unit: "year", step: step2 }; } const { timeInterval: timeInterval2, step } = target - i0.duration < i1.duration - target ? i0 : i1; return { unit: timeInterval2.unit, step: intervalStep(timeInterval2) * step, epoch: defaultEpoch(timeInterval2, { weekStart }) }; } function tickStep(start2, end2, count, minCount = 0, maxCount = Infinity) { if (start2 === end2) { return clamp(1, minCount, maxCount); } else if (count < 1) { return Number.NaN; } const extent2 = Math.abs(end2 - start2); const step = 10 ** Math.floor(Math.log10(extent2 / count)); let m = Number.NaN, minDiff = Infinity, isInBounds = false; for (const multiplier of TickMultipliers) { const c = Math.ceil(extent2 / (multiplier * step)); const validBounds = c >= minCount && c <= maxCount; if (isInBounds && !validBounds) continue; const diffCount = Math.abs(c - count); if (minDiff > diffCount || isInBounds !== validBounds) { isInBounds || (isInBounds = validBounds); minDiff = diffCount; m = multiplier; } } return m * step; } function decimalPlaces(decimal) { for (let i = decimal.length - 1; i >= 0; i -= 1) { if (decimal[i] !== "0") { return i + 1; } } return 0; } function tickFormat(ticks, format) { const options = parseNumberFormat(format ?? ",f"); if (options == null) return; if (options.precision == null || Number.isNaN(options.precision)) { if (!options.type || "eEFgGnprs".includes(options.type)) { options.precision = Math.max( ...ticks.map((x) => { if (!Number.isFinite(x)) return 0; const [integer, decimal] = x.toExponential((options.type ? 6 : 12) - 1).split(/[.e]/g); return (integer !== "1" && integer !== "-1" ? 1 : 0) + decimalPlaces(decimal) + 1; }) ); } else if ("f%".includes(options.type)) { options.precision = Math.max( ...ticks.map((x) => { if (!Number.isFinite(x) || x === 0) return 0; const l = Math.floor(Math.log10(Math.abs(x))); const digits = options.type ? 6 : 12; const decimal = x.toExponential(digits - 1).split(/[.e]/g)[1]; const decimalLength = decimalPlaces(decimal); return Math.max(0, decimalLength - l); }) ); } } const formatter2 = createNumberFormatter(options); return (n) => formatter2(Number(n)); } function range(start2, end2, step, visibleRange) { if (!Number.isFinite(step) || step <= 0) { return { ticks: [], count: 0, firstTickIndex: void 0 }; } else if (start2 === end2) { return { ticks: [start2], count: 1, firstTickIndex: 0 }; } const f = 10 ** countFractionDigits(step); const d0 = Math.min(start2, end2); const d1 = Math.max(start2, end2); let vd0; let vd1; if (visibleRange != null && (visibleRange[0] !== 0 || visibleRange[1] !== 1)) { const rangeExtent = end2 - start2; const adjustedStart = start2 + rangeExtent * visibleRange[0]; const adjustedEnd = end2 - rangeExtent * (1 - visibleRange[1]); vd0 = Math.min(adjustedStart, adjustedEnd); vd1 = Math.max(adjustedStart, adjustedEnd); } else { vd0 = d0; vd1 = d1; } vd0 = Math.floor(vd0 * f) / f; vd1 = Math.ceil(vd1 * f) / f; const ticks = []; for (let i = 0; ; i += 1) { const p = Math.round((d0 + step * i) * f) / f; if (p > d1) break; if (p >= vd0 && p <= vd1) { ticks.push(p); } } const firstTick = ticks.at(0); return { ticks, count: countTicks(d0, d1, step), firstTickIndex: firstTick == null ? void 0 : Math.round((firstTick - d0) / step) }; } function isDenseInterval(count, availableRange) { if (count >= availableRange) { warnOnce( `the configured interval results in more than 1 item per pixel, ignoring. Supply a larger interval or omit this configuration` ); return true; } return false; } function niceTicksDomain(start2, end2) { const extent2 = Math.abs(end2 - start2); const step = 10 ** Math.floor(Math.log10(extent2)); let minError = Infinity, ticks = [start2, end2]; for (const multiplier of TickMultipliers) { const m = multiplier * step; const d0 = Math.floor(start2 / m) * m; const d1 = Math.ceil(end2 / m) * m; const error2 = 1 - extent2 / Math.abs(d1 - d0); if (minError > error2) { minError = error2; ticks = [d0, d1]; } } return ticks; } function estimateTickCount(rangeExtent, zoomExtent, minSpacing, maxSpacing, defaultTickCount, defaultMinSpacing) { if (rangeExtent <= 0) { return { minTickCount: 0, maxTickCount: 0, tickCount: 0 }; } defaultMinSpacing = Math.max(defaultMinSpacing, rangeExtent / (defaultTickCount + 1)); minSpacing ?? (minSpacing = defaultMinSpacing); maxSpacing ?? (maxSpacing = rangeExtent); if (minSpacing > maxSpacing) { if (minSpacing === defaultMinSpacing) { minSpacing = maxSpacing; } else { maxSpacing = minSpacing; } } minSpacing = Math.max(minSpacing, 1); const maxTickCount = Math.max(1, Math.floor(rangeExtent / (zoomExtent * minSpacing))); const minTickCount = Math.min(maxTickCount, Math.ceil(rangeExtent / (zoomExtent * maxSpacing))); const tickCount = clamp(minTickCount, Math.floor(defaultTickCount / zoomExtent), maxTickCount); return { minTickCount, maxTickCount, tickCount }; } // packages/ag-charts-core/src/utils/time/timeFormatDefaults.ts function dateToNumber(value) { return value instanceof Date ? value.getTime() : value; } function lowestGranularityForInterval(interval) { if (interval < durationSecond) { return "millisecond"; } else if (interval < durationMinute) { return "second"; } else if (interval < durationHour) { return "minute"; } else if (interval < durationHour * 23) { return "hour"; } else if (interval < 28 * durationDay) { return "day"; } else if (interval < durationYear) { return "month"; } else { return "year"; } } function lowestGranularityUnitForTicks(ticks) { if (ticks.length === 0) { return "millisecond"; } else if (ticks.length === 1) { return lowestGranularityUnitForValue(ticks[0]); } let minInterval = Infinity; for (let i = 1; i < ticks.length; i++) { minInterval = Math.min(minInterval, Math.abs(ticks[i].valueOf() - ticks[i - 1].valueOf())); } return lowestGranularityForInterval(minInterval); } function lowestGranularityUnitForValue(value) { if (intervalFloor("second", value) < value) { return "millisecond"; } else if (intervalFloor("minute", value) < value) { return "second"; } else if (intervalFloor("hour", value) < value) { return "minute"; } else if (intervalFloor("day", value) < value) { return "hour"; } else if (intervalFloor("month", value) < value) { return "day"; } else if (intervalFloor("year", value) < value) { return "month"; } return "year"; } function dateTruncationForDomain(domain) { const [d0, d1] = domain.length === 0 ? [0, 0] : findMinMax([domain[0].valueOf(), domain.at(-1).valueOf()]); const startYear = new Date(d0).getFullYear(); const stopYear = new Date(d1).getFullYear(); if (startYear !== stopYear) return; const startMonth = new Date(d0).getMonth(); const stopMonth = new Date(d1).getMonth(); if (startMonth !== stopMonth) return "year"; const startDate = new Date(d0).getDate(); const stopDate = new Date(d1).getDate(); if (startDate !== stopDate) return "month"; return "day"; } // packages/ag-charts-core/src/identity/idGenerator.ts function createIdsGenerator() { const idsCounter = /* @__PURE__ */ new Map(); return (name) => { const counter = idsCounter.get(name); if (counter) { idsCounter.set(name, counter + 1); return `${name}_${counter}`; } idsCounter.set(name, 1); return name; }; } // packages/ag-charts-core/src/utils/data/value.ts function isStringObject(value) { return value != null && Object.hasOwn(value, "toString") && isString(value.toString()); } function isNumberObject(value) { return value != null && Object.hasOwn(value, "valueOf") && isFiniteNumber(value.valueOf()); } function isContinuous(value) { return isFiniteNumber(value) || isValidDate(value) || isNumberObject(value); } function checkDatum(value, isContinuousScale) { return value != null && (!isContinuousScale || isContinuous(value)); } function transformIntegratedCategoryValue(value) { if (isStringObject(value) && Object.hasOwn(value, "id")) { return value.id; } return value; } function readIntegratedWrappedValue(value) { if (isStringObject(value) && Object.hasOwn(value, "value")) { return value.value; } return value; } // packages/ag-charts-core/src/utils/geometry/vector.ts var vector_exports = {}; __export(vector_exports, { add: () => add, angle: () => angle, apply: () => apply, distance: () => distance, distanceSquared: () => distanceSquared, equal: () => equal, from: () => from, gradient: () => gradient, intercept: () => intercept, intersectAtX: () => intersectAtX, intersectAtY: () => intersectAtY, length: () => length, lengthSquared: () => lengthSquared, multiply: () => multiply, normalized: () => normalized, origin: () => origin, required: () => required2, rotate: () => rotate, round: () => round, sub: () => sub }); function add(a, b) { if (typeof b === "number") { return { x: a.x + b, y: a.y + b }; } return { x: a.x + b.x, y: a.y + b.y }; } function sub(a, b) { if (typeof b === "number") { return { x: a.x - b, y: a.y - b }; } return { x: a.x - b.x, y: a.y - b.y }; } function multiply(a, b) { if (typeof b === "number") { return { x: a.x * b, y: a.y * b }; } return { x: a.x * b.x, y: a.y * b.y }; } function length(a) { return Math.hypot(a.x, a.y); } function lengthSquared(a) { return a.x * a.x + a.y * a.y; } function distance(a, b) { return length(sub(a, b)); } function distanceSquared(a, b) { return lengthSquared(sub(a, b)); } function normalized(a) { const l = length(a); return { x: a.x / l, y: a.y / l }; } function angle(a, b) { if (b == null) return Math.atan2(a.y, a.x); return Math.atan2(a.y, a.x) - Math.atan2(b.y, b.x); } function rotate(a, theta, b = origin()) { const l = length(a); return { x: b.x + l * Math.cos(theta), y: b.y + l * Math.sin(theta) }; } function gradient(a, b, reflection) { const dx = b.x - a.x; const dy = reflection == null ? b.y - a.y : reflection - b.y - (reflection - a.y); return dy / dx; } function intercept(a, gradient2, reflection) { const y = reflection == null ? a.y : reflection - a.y; return y - gradient2 * a.x; } function intersectAtY(gradient2, coefficient, y = 0, reflection) { return { x: gradient2 === Infinity ? Infinity : (y - coefficient) / gradient2, y: reflection == null ? y : reflection - y }; } function intersectAtX(gradient2, coefficient, x = 0, reflection) { const y = gradient2 === Infinity ? Infinity : gradient2 * x + coefficient; return { x, y: reflection == null ? y : reflection - y }; } function round(a, decimals = 2) { return { x: roundTo(a.x, decimals), y: roundTo(a.y, decimals) }; } function equal(a, b) { return a.x === b.x && a.y === b.y; } function from(a, b) { if (typeof a === "number") { return { x: a, y: b }; } if ("currentX" in a) { return { x: a.currentX, y: a.currentY }; } if ("offsetWidth" in a) { return { x: a.offsetWidth, y: a.offsetHeight }; } if ("width" in a) { return [ { x: a.x, y: a.y }, { x: a.x + a.width, y: a.y + a.height } ]; } if ("x1" in a) { return [ { x: a.x1, y: a.y1 }, { x: a.x2, y: a.y2 } ]; } throw new Error(`Values can not be converted into a vector: [${JSON.stringify(a)}] [${b}]`); } function apply(a, b) { a.x = b.x; a.y = b.y; return a; } function required2(a) { return { x: a?.x ?? 0, y: a?.y ?? 0 }; } function origin() { return { x: 0, y: 0 }; } // packages/ag-charts-core/src/utils/geometry/vector4.ts var vector4_exports = {}; __export(vector4_exports, { bottomCenter: () => bottomCenter, center: () => center, clone: () => clone, collides: () => collides, end: () => end, from: () => from2, height: () => height, normalise: () => normalise, origin: () => origin2, round: () => round2, start: () => start, topCenter: () => topCenter, width: () => width }); function start(a) { return { x: a.x1, y: a.y1 }; } function end(a) { return { x: a.x2, y: a.y2 }; } function topCenter(a) { return { x: (a.x1 + a.x2) / 2, y: Math.min(a.y1, a.y2) }; } function center(a) { return { x: (a.x1 + a.x2) / 2, y: (a.y1 + a.y2) / 2 }; } function bottomCenter(a) { return { x: (a.x1 + a.x2) / 2, y: Math.max(a.y1, a.y2) }; } function width(a) { return Math.abs(a.x2 - a.x1); } function height(a) { return Math.abs(a.y2 - a.y1); } function round2(a) { return { x1: Math.round(a.x1), y1: Math.round(a.y1), x2: Math.round(a.x2), y2: Math.round(a.y2) }; } function clone(a) { return { x1: a.x1, y1: a.y1, x2: a.x2, y2: a.y2 }; } function collides(a, b) { const an = normalise(a); const bn = normalise(b); return an.x1 <= bn.x2 && an.x2 >= bn.x1 && an.y1 <= bn.y2 && an.y2 >= bn.y1; } function normalise(a) { return { x1: Math.min(a.x1, a.x2), x2: Math.max(a.x1, a.x2), y1: Math.min(a.y1, a.y2), y2: Math.max(a.y1, a.y2) }; } function from2(a, b, c, d) { if (typeof a === "number") { return { x1: a, y1: b, x2: c, y2: d }; } if ("width" in a) { return normalise({ x1: a.x, y1: a.y, x2: a.x + a.width, y2: a.y + a.height }); } throw new Error(`Values can not be converted into a vector4: [${JSON.stringify(a)}] [${b}] [${c}] [${d}]`); } function origin2() { return { x1: 0, y1: 0, x2: 0, y2: 0 }; } // packages/ag-charts-core/src/utils/geometry/fill.ts function isGradientFill(fill) { return isObject(fill) && fill.type == "gradient"; } function isGradientFillArray(fills) { return isArray(fills) && fills.every(isGradientFill); } function isStringFillArray(fills) { return isArray(fills) && fills.every((fill) => typeof fill === "string"); } function isPatternFill(fill) { return fill !== null && isObject(fill) && fill.type == "pattern"; } function isImageFill(fill) { return fill !== null && isObject(fill) && fill.type == "image"; } function isGradientOrPatternFill(fill) { return isGradientFill(fill) || isPatternFill(fill); } // packages/ag-charts-core/src/utils/geometry/bezier.ts function evaluateBezier(p0, p1, p2, p3, t) { return (1 - t) ** 3 * p0 + 3 * (1 - t) ** 2 * t * p1 + 3 * (1 - t) * t ** 2 * p2 + t ** 3 * p3; } function solveBezier(p0, p1, p2, p3, value) { if (value <= Math.min(p0, p3)) { return p0 < p3 ? 0 : 1; } else if (value >= Math.max(p0, p3)) { return p0 < p3 ? 1 : 0; } let t0 = 0; let t1 = 1; let t = Number.NaN; for (let i = 0; i < 12; i += 1) { t = (t0 + t1) / 2; const curveValue = evaluateBezier(p0, p1, p2, p3, t); if (curveValue < value) { t0 = t; } else { t1 = t; } } return t; } function splitBezier2D(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, t) { const x01 = (1 - t) * p0x + t * p1x; const y01 = (1 - t) * p0y + t * p1y; const x12 = (1 - t) * p1x + t * p2x; const y12 = (1 - t) * p1y + t * p2y; const x23 = (1 - t) * p2x + t * p3x; const y23 = (1 - t) * p2y + t * p3y; const x012 = (1 - t) * x01 + t * x12; const y012 = (1 - t) * y01 + t * y12; const x123 = (1 - t) * x12 + t * x23; const y123 = (1 - t) * y12 + t * y23; const x0123 = (1 - t) * x012 + t * x123; const y0123 = (1 - t) * y012 + t * y123; return [ [ { x: p0x, y: p0y }, { x: x01, y: y01 }, { x: x012, y: y012 }, { x: x0123, y: y0123 } ], [ { x: x0123, y: y0123 }, { x: x123, y: y123 }, { x: x23, y: y23 }, { x: p3x, y: p3y } ] ]; } function calculateDerivativeExtrema(p0, p1, p2, p3) { const a = -p0 + 3 * p1 - 3 * p2 + p3; const b = 2 * (p0 - 2 * p1 + p2); const c = -p0 + p1; if (a === 0) { if (b !== 0) { const t = -c / b; if (t > 0 && t < 1) { return [t]; } } return []; } const discriminant = b * b - 4 * a * c; if (discriminant >= 0) { const sqrtDiscriminant = Math.sqrt(discriminant); const t1 = (-b + sqrtDiscriminant) / (2 * a); const t2 = (-b - sqrtDiscriminant) / (2 * a); return [t1, t2].filter((t) => t > 0 && t < 1); } return []; } function bezier2DExtrema(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y) { const tx = calculateDerivativeExtrema(cp0x, cp1x, cp2x, cp3x); const ty = calculateDerivativeExtrema(cp0y, cp1y, cp2y, cp3y); return [...tx, ...ty]; } function bezierCandidate(points, x, y) { const midX = evaluateBezier(points[0].x, points[1].x, points[2].x, points[3].x, 0.5); const midY = evaluateBezier(points[0].y, points[1].y, points[2].y, points[3].y, 0.5); const distance2 = Math.hypot(midX - x, midY - y); const minDistance = Math.min( Math.hypot(points[0].x - x, points[0].y - y), Math.hypot(points[1].x - x, points[1].y - y), Math.hypot(points[2].x - x, points[2].y - y), Math.hypot(points[3].x - x, points[3].y - y) ); return { points, distance: distance2, minDistance }; } function bezier2DDistance(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y, x, y, precision = 1) { const points0 = [ { x: cp0x, y: cp0y }, { x: cp1x, y: cp1y }, { x: cp2x, y: cp2y }, { x: cp3x, y: cp3y } ]; let queue = { value: bezierCandidate(points0, x, y), next: null }; let bestResult; while (queue != null) { const { points, distance: distance2, minDistance } = queue.value; queue = queue.next; if (bestResult == null || distance2 < bestResult.distance) { bestResult = { distance: distance2, minDistance }; } if (bestResult != null && bestResult.distance - minDistance <= precision) { continue; } const [leftPoints, rightPoints] = splitBezier2D( points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y, points[3].x, points[3].y, 0.5 ); const newCandidates = [bezierCandidate(leftPoints, x, y), bezierCandidate(rightPoints, x, y)].sort( bezierCandidateCmp ); queue = insertListItemsSorted(queue, newCandidates, bezierCandidateCmp); } return bestResult?.distance ?? Infinity; } var bezierCandidateCmp = (a, b) => b.minDistance - a.minDistance; // packages/ag-charts-core/src/utils/geometry/labelPlacement.ts function circleRectOverlap({ point: c, anchor: unitCenter }, x, y, w, h) { if (c.size === 0) { return false; } let cx = c.x; let cy = c.y; if (unitCenter != null) { cx -= (unitCenter.x - 0.5) * c.size; cy -= (unitCenter.y - 0.5) * c.size; } let edgeX = cx; if (cx < x) { edgeX = x; } else if (cx > x + w) { edgeX = x + w; } let edgeY = cy; if (cy < y) { edgeY = y; } else if (cy > y + h) { edgeY = y + h; } const dx = cx - edgeX; const dy = cy - edgeY; const d = Math.hypot(dx, dy); return d <= c.size / 2; } function isPointLabelDatum(x) { return x != null && typeof x.point === "object" && typeof x.label === "object"; } var labelPlacements = { top: { x: 0, y: -1 }, bottom: { x: 0, y: 1 }, left: { x: -1, y: 0 }, right: { x: 1, y: 0 }, "top-left": { x: -1, y: -1 }, "top-right": { x: 1, y: -1 }, "bottom-left": { x: -1, y: 1 }, "bottom-right": { x: 1, y: 1 } }; function placeLabels(data, bounds, padding2 = 5) { const result = /* @__PURE__ */ new Map(); const previousResults = []; const sortedDataClone = new Map( Array.from(data.entries(), ([k, d]) => [k, d.toSorted((a, b) => b.point.size - a.point.size)]) ); const dataValues = [...sortedDataClone.values()].flat(); for (const [seriesId, datums] of sortedDataClone.entries()) { const labels = []; if (!datums[0]?.label) continue; for (let index = 0, ln = datums.length; index < ln; index++) { const d = datums[index]; const { point, label, anchor } = d; const { text, width: width2, height: height2 } = label; const r = point.size / 2; let dx = 0; let dy = 0; if (r > 0 && d.placement != null) { const placement = labelPlacements[d.placement]; dx = (width2 / 2 + r + padding2) * placement.x; dy = (height2 / 2 + r + padding2) * placement.y; } let x = point.x - width2 / 2 + dx; let y = point.y - height2 / 2 + dy; if (anchor) { x -= (anchor.x - 0.5) * point.size; y -= (anchor.y - 0.5) * point.size; } if (boxContains(bounds, x, y, width2, height2) && !dataValues.some((dataDatum) => circleRectOverlap(dataDatum, x, y, width2, height2)) && !previousResults.some((pr) => boxCollides(pr, x, y, width2, height2))) { const resultDatum = { index, text, x, y, width: width2, height: height2, datum: d }; labels.push(resultDatum); previousResults.push(resultDatum); } } result.set(seriesId, labels); } return result; } // packages/ag-charts-core/src/utils/geometry/scaling.ts function isContinuousScaling(scaling) { return scaling.type === "continuous" || scaling.type === "log"; } function isCategoryScaling(scaling) { return scaling.type === "category"; } function isUnitTimeCategoryScaling(scaling) { return "variant" in scaling && scaling.variant === "unit-time"; } function isStandardCategoryScaling(scaling) { return !("variant" in scaling); } function areScalingEqual(a, b) { if (a === void 0 || b === void 0) { return a !== void 0 || b !== void 0; } if (isContinuousScaling(a) && isContinuousScaling(b)) { return a.type === b.type && arraysEqual(a.domain, b.domain) && arraysEqual(a.range, b.range); } if (isCategoryScaling(a) && isCategoryScaling(b)) { if (isUnitTimeCategoryScaling(a) && isUnitTimeCategoryScaling(b)) { return a.firstBandTime === b.firstBandTime && a.lastBandTime === b.lastBandTime && a.bandCount === b.bandCount && a.intervalMs === b.intervalMs && a.inset === b.inset && a.step === b.step; } if (isStandardCategoryScaling(a) && isStandardCategoryScaling(b)) { return a.inset === b.inset && a.step === b.step && arraysEqual(a.domain, b.domain); } return false; } return false; } function isScaleValid(scale) { if (scale == null) return false; if (scale.type === "category") { if (isUnitTimeCategoryScaling(scale)) { return Number.isFinite(scale.firstBandTime) && Number.isFinite(scale.lastBandTime) && Number.isFinite(scale.bandCount) && scale.bandCount > 0; } return scale.domain.every((v) => v != null); } return scale.domain.every((v) => Number.isFinite(v) || v instanceof Date) && scale.range.every((v) => Number.isFinite(v)); } // packages/ag-charts-core/src/utils/geometry/lineInterpolation.ts function spanRange(span) { switch (span.type) { case "linear": case "step": case "multi-line": return [ { x: span.x0, y: span.y0 }, { x: span.x1, y: span.y1 } ]; case "cubic": return [ { x: span.cp0x, y: span.cp0y }, { x: span.cp3x, y: span.cp3y } ]; } } function spanRangeNormalized(span) { const range2 = spanRange(span); if (range2[0].x > range2[1].x) { range2.reverse(); } return range2; } function collapseSpanToPoint(span, point) { const { x, y } = point; switch (span.type) { case "linear": return { type: "linear", moveTo: span.moveTo, x0: x, y0: y, x1: x, y1: y }; case "step": return { type: "step", moveTo: span.moveTo, x0: x, y0: y, x1: x, y1: y, stepX: x }; case "cubic": return { type: "cubic", moveTo: span.moveTo, cp0x: x, cp0y: y, cp1x: x, cp1y: y, cp2x: x, cp2y: y, cp3x: x, cp3y: y }; case "multi-line": return { type: "multi-line", moveTo: span.moveTo, x0: x, y0: y, x1: x, y1: y, midPoints: span.midPoints.map(() => ({ x, y })) }; } } function rescaleSpan(span, nextStart, nextEnd) { const [prevStart, prevEnd] = spanRange(span); const widthScale = prevEnd.x === prevStart.x ? 0 : (nextEnd.x - nextStart.x) / (prevEnd.x - prevStart.x); const heightScale = prevEnd.y === prevStart.y ? 0 : (nextEnd.y - nextStart.y) / (prevEnd.y - prevStart.y); switch (span.type) { case "linear": return { type: "linear", moveTo: span.moveTo, x0: nextStart.x, y0: nextStart.y, x1: nextEnd.x, y1: nextEnd.y }; case "cubic": return { type: "cubic", moveTo: span.moveTo, cp0x: nextStart.x, cp0y: nextStart.y, cp1x: nextEnd.x - (span.cp2x - prevStart.x) * widthScale, cp1y: nextEnd.y - (span.cp2y - prevStart.y) * heightScale, cp2x: nextEnd.x - (span.cp1x - prevStart.x) * widthScale, cp2y: nextEnd.y - (span.cp1y - prevStart.y) * heightScale, cp3x: nextEnd.x, cp3y: nextEnd.y }; case "step": return { type: "step", moveTo: span.moveTo, x0: nextStart.x, y0: nextStart.y, x1: nextEnd.x, y1: nextEnd.y, stepX: nextEnd.x - (span.stepX - prevStart.x) * widthScale }; case "multi-line": return { type: "multi-line", moveTo: span.moveTo, x0: nextStart.x, y0: nextStart.y, x1: nextEnd.x, y1: nextEnd.y, midPoints: span.midPoints.map((midPoint) => ({ x: nextStart.x + (midPoint.x - prevStart.x) * widthScale, y: nextStart.y + (midPoint.y - prevStart.y) * heightScale })) }; } } function clipSpanX(span, x0, x1) { const { moveTo } = span; const [start2, end2] = spanRangeNormalized(span); const { x: spanX0, y: spanY0 } = start2; const { x: spanX1, y: spanY1 } = end2; if (x1 < spanX0) { return rescaleSpan(span, start2, start2); } else if (x0 > spanX1) { return rescaleSpan(span, end2, end2); } switch (span.type) { case "linear": { const m = spanY0 === spanY1 ? void 0 : (spanY1 - spanY0) / (spanX1 - spanX0); const y0 = m == null ? spanY0 : m * (x0 - spanX0) + spanY0; const y1 = m == null ? spanY0 : m * (x1 - spanX0) + spanY0; return { type: "linear", moveTo, x0, y0, x1, y1 }; } case "step": if (x1 <= span.stepX) { const y = span.y0; return { type: "step", moveTo, x0, y0: y, x1, y1: y, stepX: x1 }; } else if (x0 >= span.stepX) { const y = span.y1; return { type: "step", moveTo, x0, y0: y, x1, y1: y, stepX: x0 }; } else { const { y0, y1, stepX } = span; return { type: "step", moveTo, x0, y0, x1, y1, stepX }; } case "cubic": { const t0 = solveBezier(span.cp0x, span.cp1x, span.cp2x, span.cp3x, x0); let [_unused, bezier] = splitBezier2D( span.cp0x, span.cp0y, span.cp1x, span.cp1y, span.cp2x, span.cp2y, span.cp3x, span.cp3y, t0 ); const t1 = solveBezier(bezier[0].x, bezier[1].x, bezier[2].x, bezier[3].x, x1); [bezier, _unused] = splitBezier2D( bezier[0].x, bezier[0].y, bezier[1].x, bezier[1].y, bezier[2].x, bezier[2].y, bezier[3].x, bezier[3].y, t1 ); return { type: "cubic", moveTo, cp0x: bezier[0].x, cp0y: bezier[0].y, cp1x: bezier[1].x, cp1y: bezier[1].y, cp2x: bezier[2].x, cp2y: bezier[2].y, cp3x: bezier[3].x, cp3y: bezier[3].y }; } case "multi-line": { const { midPoints } = span; const midPointStartIndex = midPoints.findLastIndex((midPoint) => midPoint.x <= x0); let midPointEndIndex = midPoints.findIndex((midPoint) => midPoint.x >= x1); if (midPointEndIndex === -1) midPointEndIndex = midPoints.length; const startPoint = midPointStartIndex >= 0 ? midPoints[midPointStartIndex] : void 0; const startX = startPoint?.x ?? spanX0; const startY = startPoint?.y ?? spanY0; const endPoint = midPointEndIndex < midPoints.length ? midPoints[midPointEndIndex] : void 0; const endX = endPoint?.x ?? spanX1; const endY = endPoint?.y ?? spanY1; const m = startY === endY ? void 0 : (endY - startY) / (endX - startX); const y0 = m == null ? startY : m * (startX - spanX0) + startY; const y1 = m == null ? startY : m * (endX - spanX0) + startY; return { type: "multi-line", moveTo, x0, y0, x1, y1, midPoints: midPoints.slice(Math.max(midPointStartIndex, 0), midPointEndIndex) }; } } } var SpanJoin = /* @__PURE__ */ ((SpanJoin2) => { SpanJoin2[SpanJoin2["MoveTo"] = 0] = "MoveTo"; SpanJoin2[SpanJoin2["LineTo"] = 1] = "LineTo"; SpanJoin2[SpanJoin2["Skip"] = 2] = "Skip"; return SpanJoin2; })(SpanJoin || {}); function linearPoints(points) { const spans = []; let i = 0; let x0 = Number.NaN; let y0 = Number.NaN; for (const { x: x1, y: y1 } of points) { if (i > 0) { const moveTo = i === 1; spans.push({ type: "linear", moveTo, x0, y0, x1, y1 }); } i += 1; x0 = x1; y0 = y1; } return spans; } var lineSteps = { start: 0, middle: 0.5, end: 1 }; function stepPoints(points, position) { const spans = []; let i = 0; let x0 = Number.NaN; let y0 = Number.NaN; const p0 = typeof position === "number" ? position : lineSteps[position]; for (const { x: x1, y: y1 } of points) { if (i > 0) { const moveTo = i === 1; const stepX = x0 + (x1 - x0) * p0; spans.push({ type: "step", moveTo, x0, y0, x1, y1, stepX }); } i += 1; x0 = x1; y0 = y1; } return spans; } function smoothPoints(iPoints, tension) { const points = Array.isArray(iPoints) ? iPoints : Array.from(iPoints); if (points.length <= 1) return []; const flatnessRatio = 0.05; const gradients = points.map((c, i) => { const p = i === 0 ? c : points[i - 1]; const n = i === points.length - 1 ? c : points[i + 1]; const isTerminalPoint = i === 0 || i === points.length - 1; if (Math.sign(p.y - c.y) === Math.sign(n.y - c.y)) { return 0; } if (!isTerminalPoint) { const range2 = Math.abs(p.y - n.y); const prevRatio = Math.abs(c.y - p.y) / range2; const nextRatio = Math.abs(c.y - n.y) / range2; if (prevRatio <= flatnessRatio || 1 - prevRatio <= flatnessRatio || nextRatio <= flatnessRatio || 1 - nextRatio <= flatnessRatio) { return 0; } } return (n.y - p.y) / (n.x - p.x); }); if (gradients[1] === 0) { gradients[0] *= 2; } if (gradients.at(-2) === 0) { gradients[gradients.length - 1] *= 2; } const spans = []; for (let i = 1; i < points.length; i += 1) { const prev = points[i - 1]; const prevM = gradients[i - 1]; const cur = points[i]; const curM = gradients[i]; const dx = cur.x - prev.x; const dy = cur.y - prev.y; let dcp1x = dx * tension / 3; let dcp1y = dx * prevM * tension / 3; let dcp2x = dx * tension / 3; let dcp2y = dx * curM * tension / 3; if (curM === 0 && Math.abs(dcp1y) > Math.abs(dy)) { dcp1x *= Math.abs(dy / dcp1y); dcp1y = Math.sign(dcp1y) * Math.abs(dy); } if (prevM === 0 && Math.abs(dcp2y) > Math.abs(dy)) { dcp2x *= Math.abs(dy / dcp2y); dcp2y = Math.sign(dcp2y) * Math.abs(dy); } spans.push({ type: "cubic", moveTo: i === 1, cp0x: prev.x, cp0y: prev.y, cp1x: prev.x + dcp1x, cp1y: prev.y + dcp1y, cp2x: cur.x - dcp2x, cp2y: cur.y - dcp2y, cp3x: cur.x, cp3y: cur.y }); } return spans; } // packages/ag-charts-core/src/utils/zoomUtils.ts var UNIT_MIN = 0; var UNIT_MAX = 1; function definedZoomState(zoom) { return { x: { min: zoom?.x?.min ?? UNIT_MIN, max: zoom?.x?.max ?? UNIT_MAX }, y: { min: zoom?.y?.min ?? UNIT_MIN, max: zoom?.y?.max ?? UNIT_MAX } }; } // packages/ag-charts-core/src/rendering/changeDetectableProperties.ts var ChangeDetectableProperties = class extends BaseProperties { constructor() { super(...arguments); this._dirty = true; } markDirty() { this._dirty = true; } markClean(_opts) { this._dirty = false; } isDirty() { return this._dirty; } onChangeDetection(_property) { this.markDirty(); } }; // packages/ag-charts-core/src/utils/format/timeFormat.ts var CONSTANTS = { periods: ["AM", "PM"], days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] }; function dayOfYear(date2, startOfYear = new Date(date2.getFullYear(), 0, 1)) { const startOffset = date2.getTimezoneOffset() - startOfYear.getTimezoneOffset(); const timeDiff = date2.getTime() - startOfYear.getTime() + startOffset * 6e4; const timeOneDay = 36e5 * 24; return Math.floor(timeDiff / timeOneDay); } function weekOfYear(date2, startDay) { const startOfYear = new Date(date2.getFullYear(), 0, 1); const startOfYearDay = startOfYear.getDay(); const firstWeekStartOffset = (startDay - startOfYearDay + 7) % 7; const startOffset = new Date(date2.getFullYear(), 0, firstWeekStartOffset + 1); if (startOffset <= date2) { return Math.floor(dayOfYear(date2, startOffset) / 7) + 1; } return 0; } var SUNDAY = 0; var MONDAY = 1; var THURSDAY = 4; function isoWeekOfYear(date2, year = date2.getFullYear()) { const firstOfYear = new Date(year, 0, 1); const firstOfYearDay = firstOfYear.getDay(); const firstThursdayOffset = (THURSDAY - firstOfYearDay + 7) % 7; const startOffset = new Date(year, 0, firstThursdayOffset - (THURSDAY - MONDAY) + 1); if (startOffset <= date2) { return Math.floor(dayOfYear(date2, startOffset) / 7) + 1; } return isoWeekOfYear(date2, year - 1); } function timezone(date2) { const offset = date2.getTimezoneOffset(); const unsignedOffset = Math.abs(offset); const sign = offset > 0 ? "-" : "+"; return `${sign}${pad(Math.floor(unsignedOffset / 60), 2, "0")}${pad(Math.floor(unsignedOffset % 60), 2, "0")}`; } var FORMATTERS = { a: (d) => CONSTANTS.shortDays[d.getDay()], A: (d) => CONSTANTS.days[d.getDay()], b: (d) => CONSTANTS.shortMonths[d.getMonth()], B: (d) => CONSTANTS.months[d.getMonth()], c: "%x, %X", d: (d, p) => pad(d.getDate(), 2, p ?? "0"), e: "%_d", f: (d, p) => pad(d.getMilliseconds() * 1e3, 6, p ?? "0"), H: (d, p) => pad(d.getHours(), 2, p ?? "0"), I: (d, p) => { const hours = d.getHours() % 12; return hours === 0 ? "12" : pad(hours, 2, p ?? "0"); }, j: (d, p) => pad(dayOfYear(d) + 1, 3, p ?? "0"), m: (d, p) => pad(d.getMonth() + 1, 2, p ?? "0"), M: (d, p) => pad(d.getMinutes(), 2, p ?? "0"), L: (d, p) => pad(d.getMilliseconds(), 3, p ?? "0"), p: (d) => d.getHours() < 12 ? "AM" : "PM", Q: (d) => String(d.getTime()), s: (d) => String(Math.floor(d.getTime() / 1e3)), S: (d, p) => pad(d.getSeconds(), 2, p ?? "0"), u: (d) => { let day = d.getDay(); if (day < 1) day += 7; return String(day % 7); }, U: (d, p) => pad(weekOfYear(d, SUNDAY), 2, p ?? "0"), V: (d, p) => pad(isoWeekOfYear(d), 2, p ?? "0"), w: (d, p) => pad(d.getDay(), 2, p ?? "0"), W: (d, p) => pad(weekOfYear(d, MONDAY), 2, p ?? "0"), x: "%-m/%-d/%Y", X: "%-I:%M:%S %p", y: (d, p) => pad(d.getFullYear() % 100, 2, p ?? "0"), Y: (d, p) => pad(d.getFullYear(), 4, p ?? "0"), Z: (d) => timezone(d), "%": () => "%" }; var PADS = { _: " ", "0": "0", "-": "" }; function pad(value, size, padChar) { const output = String(Math.floor(value)); if (output.length >= size) { return output; } return `${padChar.repeat(size - output.length)}${output}`; } function buildDateFormatter(formatString) { const formatParts = []; while (formatString.length > 0) { let nextEscapeIdx = formatString.indexOf("%"); if (nextEscapeIdx !== 0) { const literalPart = nextEscapeIdx > 0 ? formatString.substring(0, nextEscapeIdx) : formatString; formatParts.push(literalPart); } if (nextEscapeIdx < 0) break; const maybePadSpecifier = formatString[nextEscapeIdx + 1]; const maybePad = PADS[maybePadSpecifier]; if (maybePad != null) { nextEscapeIdx++; } const maybeFormatterSpecifier = formatString[nextEscapeIdx + 1]; const maybeFormatter = FORMATTERS[maybeFormatterSpecifier]; if (typeof maybeFormatter === "function") { formatParts.push([maybeFormatter, maybePad]); } else if (typeof maybeFormatter === "string") { const formatter2 = buildDateFormatter(maybeFormatter); formatParts.push([formatter2, maybePad]); } else { formatParts.push(`${maybePad ?? ""}${maybeFormatterSpecifier}`); } formatString = formatString.substring(nextEscapeIdx + 2); } return (dateTime) => { const dateTimeAsDate = typeof dateTime === "number" ? new Date(dateTime) : dateTime; return formatParts.map((c) => typeof c === "string" ? c : c[0](dateTimeAsDate, c[1])).join(""); }; } // packages/ag-charts-core/src/rendering/domElements.ts function createButton(options, attrs) { const button = createElement("button", getClassName("ag-charts-input ag-charts-button", attrs)); if (options.label === void 0) { button.append(createIcon(options.icon)); button.ariaLabel = options.altText; } else { button.append(options.label); } button.addEventListener("click", options.onPress); setAttributes(button, attrs); return button; } function createCheckbox(options, attrs) { const checkbox = createElement("input", getClassName("ag-charts-input ag-charts-checkbox", attrs)); checkbox.type = "checkbox"; checkbox.checked = options.checked; checkbox.addEventListener("change", (event) => options.onChange(checkbox.checked, event)); checkbox.addEventListener("keydown", (event) => { if (isButtonClickEvent(event)) { event.preventDefault(); checkbox.click(); } }); setAttributes(checkbox, attrs); return checkbox; } function createSelect(options, attrs) { const select = createElement("select", getClassName("ag-charts-input ag-charts-select", attrs)); select.append( ...options.options.map((option) => { const optionEl = createElement("option"); optionEl.value = option.value; optionEl.textContent = option.label; return optionEl; }) ); setAttribute(select, "data-preventdefault", false); select.value = options.value; select.addEventListener("change", (event) => options.onChange(select.value, event)); setAttributes(select, attrs); return select; } function createTextArea(options, attrs) { const textArea = createElement("textarea", getClassName("ag-charts-input ag-charts-textarea", attrs)); textArea.value = options.value; textArea.addEventListener("input", (event) => options.onChange(textArea.value, event)); setAttributes(textArea, attrs); setAttribute(textArea, "data-preventdefault", false); return textArea; } function createIcon(icon) { const el = createElement("span", `ag-charts-icon ag-charts-icon-${icon}`); setAttribute(el, "aria-hidden", true); return el; } function getClassName(baseClass, attrs) { if (attrs == null) return baseClass; return `${baseClass} ${attrs.class}`; } // packages/ag-charts-core/src/rendering/easing.ts var linear = (n) => n; var easeIn = (n) => 1 - Math.cos(n * Math.PI / 2); var easeOut = (n) => Math.sin(n * Math.PI / 2); var easeInOut = (n) => -(Math.cos(n * Math.PI) - 1) / 2; var easeInQuad = (n) => n * n; var easeOutQuad = (n) => 1 - (1 - n) ** 2; var easeInOutQuad = (n) => n < 0.5 ? 2 * n * n : 1 - (-2 * n + 2) ** 2 / 2; var inverseEaseOut = (x) => 2 * Math.asin(x) / Math.PI; // packages/ag-charts-core/src/rendering/changeDetectable.ts var TRIPLE_EQ = (lhs, rhs) => lhs === rhs; function SceneChangeDetection(opts) { return function(target, key) { const privateKey = `__${key}`; if (target[key]) return; prepareGetSet(target, key, privateKey, opts); }; } function SceneRefChangeDetection(opts) { return SceneChangeDetection(opts); } function SceneObjectChangeDetection(opts) { return SceneChangeDetection(opts); } function SceneArrayChangeDetection(opts) { const baseOpts = opts ?? {}; baseOpts.equals = arraysEqual; return SceneChangeDetection(opts); } function DeclaredSceneChangeDetection(opts) { return function(target, key) { const privateKey = `__${key}`; if (target[key]) return; prepareGetSet(target, key, privateKey, opts); }; } function DeclaredSceneObjectChangeDetection(opts) { return function(target, key) { const privateKey = `__${key}`; if (target[key]) return; prepareGetSet(target, key, privateKey, opts); }; } function prepareGetSet(target, key, privateKey, opts) { const { changeCb, convertor, checkDirtyOnAssignment = false } = opts ?? {}; const requiredOpts = { changeCb, checkDirtyOnAssignment, convertor }; const setter = buildCheckDirtyChain( privateKey, buildChangeCallbackChain( buildConvertorChain(buildSetter(privateKey, requiredOpts), requiredOpts), requiredOpts ), requiredOpts ); function propertyGetter() { return this[privateKey]; } Object.defineProperty(target, key, { set: setter, get: propertyGetter, enumerable: true, configurable: true }); } function buildConvertorChain(setterFn, opts) { const { convertor } = opts; if (convertor) { let convertValueAndSet2 = function(value) { setterFn.call(this, convertValue(value)); }; var convertValueAndSet = convertValueAndSet2; const convertValue = convertor; return convertValueAndSet2; } return setterFn; } var NO_CHANGE = Symbol("no-change"); function buildChangeCallbackChain(setterFn, opts) { const { changeCb } = opts; if (changeCb) { let invokeChangeCallback2 = function(value) { const change = setterFn.call(this, value); if (change !== NO_CHANGE) { changeCallback.call(this, this); } return change; }; var invokeChangeCallback = invokeChangeCallback2; const changeCallback = changeCb; return invokeChangeCallback2; } return setterFn; } function buildCheckDirtyChain(privateKey, setterFn, opts) { const { checkDirtyOnAssignment } = opts; if (checkDirtyOnAssignment) { let checkDirtyOnAssignmentFn2 = function(value) { const change = setterFn.call(this, value); if (value?._dirty === true) { this.markDirty(privateKey); } return change; }; var checkDirtyOnAssignmentFn = checkDirtyOnAssignmentFn2; return checkDirtyOnAssignmentFn2; } return setterFn; } function buildSetter(privateKey, opts) { const { equals = TRIPLE_EQ } = opts; function setWithChangeDetection(value) { const oldValue = this[privateKey]; if (!equals(value, oldValue)) { this[privateKey] = value; this.onChangeDetection(privateKey); return value; } return NO_CHANGE; } return setWithChangeDetection; }