Files
sigpro-grid/node_modules/ag-charts-core/dist/package/main.cjs.js
2026-03-17 08:44:54 +01:00

9583 lines
298 KiB
JavaScript
Executable File

"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 ?? "<root>"}`);
}
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;
}