ggaction 0.0.17 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/README.md +2 -2
- package/knowledge/action-card.schema.json +1 -1
- package/knowledge/action-cards.json +1 -1
- package/knowledge/intent-taxonomy.json +1 -1
- package/knowledge/mcp-resources.json +1 -1
- package/knowledge/task-resolver.js +1 -1
- package/package.json +3 -3
- package/src/BasicChartProgram.js +1 -1
- package/src/accessibility.js +3 -2
- package/src/actions/boxPlots/create.js +14 -4
- package/src/actions/boxPlots/edit.js +39 -33
- package/src/actions/boxPlots/materialize.js +7 -3
- package/src/actions/boxPlots/options.js +37 -11
- package/src/actions/canvas/actions.js +70 -95
- package/src/actions/canvas/fitting.js +16 -1
- package/src/actions/canvas/index.js +3 -0
- package/src/actions/canvas/plotBorder.js +28 -0
- package/src/actions/charts/area.js +2 -2
- package/src/actions/charts/bar.js +34 -7
- package/src/actions/charts/ecdf.js +4 -18
- package/src/actions/charts/endpoints.js +4 -18
- package/src/actions/charts/heatmap.js +4 -4
- package/src/actions/charts/index.js +2 -0
- package/src/actions/charts/interval-regression.js +2 -2
- package/src/actions/charts/line.js +1 -1
- package/src/actions/charts/pie.js +3 -47
- package/src/actions/charts/radial.js +34 -12
- package/src/actions/charts/scatter.js +16 -2
- package/src/actions/charts/shared.js +2 -2
- package/src/actions/charts/text.js +35 -0
- package/src/actions/composition/actions.js +6 -2
- package/src/actions/data/box.js +2 -1
- package/src/actions/data/edit.js +1 -1
- package/src/actions/data/regression.js +2 -1
- package/src/actions/data/shared.js +3 -2
- package/src/actions/data/stack.js +3 -1
- package/src/actions/encodings/appearance.js +37 -29
- package/src/actions/encodings/barWidth.js +36 -11
- package/src/actions/encodings/channels.js +0 -1
- package/src/actions/encodings/color/continuous.js +1 -1
- package/src/actions/encodings/color/index.js +1 -1
- package/src/actions/encodings/color/policy.js +10 -3
- package/src/actions/encodings/density/resolve.js +1 -6
- package/src/actions/encodings/position/policies/arc.js +12 -10
- package/src/actions/encodings/position/policies/area.js +3 -3
- package/src/actions/encodings/position/policies/bar.js +15 -6
- package/src/actions/encodings/position/policies/line.js +17 -6
- package/src/actions/encodings/position/resolve.js +3 -2
- package/src/actions/encodings/ranged.js +17 -0
- package/src/actions/encodings/remove.js +3 -2
- package/src/actions/encodings/seriesLayout.js +1 -0
- package/src/actions/encodings/text.js +6 -3
- package/src/actions/errorBands/create.js +2 -2
- package/src/actions/errorBands/edit.js +2 -1
- package/src/actions/facets/actions.js +158 -240
- package/src/actions/gradientPlots/resolve.js +2 -17
- package/src/actions/guides/applicability.js +1 -1
- package/src/actions/guides/axes/axis.js +16 -4
- package/src/actions/guides/axes/edit.js +4 -4
- package/src/actions/guides/axes/labels.js +120 -46
- package/src/actions/guides/axes/lines.js +6 -5
- package/src/actions/guides/axes/parallel/lifecycle.js +1 -1
- package/src/actions/guides/axes/parallel/policy.js +8 -7
- package/src/actions/guides/axes/remove.js +3 -2
- package/src/actions/guides/axes/tickGroups.js +5 -2
- package/src/actions/guides/axes/ticks.js +6 -3
- package/src/actions/guides/axes/titles.js +71 -26
- package/src/actions/guides/basic.js +2 -0
- package/src/actions/guides/facadeLegend.js +10 -2
- package/src/actions/guides/grids/grid.js +7 -1
- package/src/actions/guides/grids/resolve.js +59 -12
- package/src/actions/guides/legends/blocks.js +3 -1
- package/src/actions/guides/legends/categorical/actions.js +70 -17
- package/src/actions/guides/legends/categorical/components.js +12 -8
- package/src/actions/guides/legends/categorical/index.js +6 -0
- package/src/actions/guides/legends/categorical/layout.js +37 -8
- package/src/actions/guides/legends/categorical/options.js +31 -20
- package/src/actions/guides/legends/categorical/resolve.js +2 -2
- package/src/actions/guides/legends/categorical/symbols.js +18 -12
- package/src/actions/guides/legends/categorical/validation.js +1 -6
- package/src/actions/guides/legends/continuous/colorSymbols.js +1 -0
- package/src/actions/guides/legends/continuous/common.js +1 -447
- package/src/actions/guides/legends/continuous/gradient.js +47 -34
- package/src/actions/guides/legends/continuous/interval.js +4 -4
- package/src/actions/guides/legends/continuous/opacity.js +19 -12
- package/src/actions/guides/legends/edit.js +1 -604
- package/src/actions/guides/legends/focused.js +2 -2
- package/src/actions/guides/legends/group.js +1 -0
- package/src/actions/guides/legends/lane.js +1 -516
- package/src/actions/guides/legends/remove.js +3 -0
- package/src/actions/guides/legends/sampling.js +1 -1
- package/src/actions/guides/legends/size.js +51 -43
- package/src/actions/guides/legends/strokeWidth.js +11 -29
- package/src/actions/guides/legends/target.js +3 -3
- package/src/actions/guides/legends/transition.js +21 -7
- package/src/actions/guides/polar/axes/labels.js +4 -2
- package/src/actions/guides/polar/axes/titles.js +7 -5
- package/src/actions/guides/polar/resolve.js +6 -14
- package/src/actions/index.js +16 -16
- package/src/actions/marks/arc/actions.js +3 -10
- package/src/actions/marks/area/actions.js +8 -5
- package/src/actions/marks/area/materialize.js +8 -9
- package/src/actions/marks/bar/create.js +10 -4
- package/src/actions/marks/bar/edit.js +8 -4
- package/src/actions/marks/bar/materialize.js +9 -6
- package/src/actions/marks/line/actions.js +11 -4
- package/src/actions/marks/line/materialize.js +9 -5
- package/src/actions/marks/point/edit.js +1 -1
- package/src/actions/marks/rect/actions.js +3 -3
- package/src/actions/marks/remove.js +2 -0
- package/src/actions/marks/rule/actions.js +7 -4
- package/src/actions/marks/text/actions.js +17 -5
- package/src/actions/marks/text/layout.js +3 -0
- package/src/actions/primitives/semanticValidation/layer.js +4 -0
- package/src/actions/regression/create.js +1 -1
- package/src/actions/regression/edit.js +3 -3
- package/src/actions/regression/resolve.js +2 -6
- package/src/actions/scales/channels.js +9 -4
- package/src/actions/scales/consumers/families.js +16 -5
- package/src/actions/scales/create.js +8 -3
- package/src/actions/scales/definitions.js +1 -425
- package/src/actions/scales/edit.js +2 -2
- package/src/actions/scales/editPolicy.js +9 -3
- package/src/actions/scales/materialize.js +1 -1
- package/src/actions/scales/preview.js +21 -1
- package/src/actions/scales/quantitativeColor.js +3 -3
- package/src/actions/selection/actions.js +1 -13
- package/src/actions/theme/reconcile.js +81 -27
- package/src/actions/theme/state.js +12 -0
- package/src/actions/titles/actions.js +5 -18
- package/src/actions/titles/resolve.js +41 -19
- package/src/actions/violinPlots/edit.js +3 -20
- package/src/core/compositionState.js +4 -1
- package/src/core/font.js +9 -2
- package/src/core/optionRequirements.js +1 -0
- package/src/core/resourceReferences.js +3 -0
- package/src/core/textMetricProfile.js +3 -2
- package/src/core/textMetrics.js +41 -4
- package/src/core/validation.js +26 -0
- package/src/core/vocabulary.js +4 -0
- package/src/grammar/aggregate.js +4 -18
- package/src/grammar/arcs.js +1 -386
- package/src/grammar/areaPaint.js +10 -0
- package/src/grammar/areaSeries.js +18 -10
- package/src/grammar/bars/geometry.js +30 -3
- package/src/grammar/bars/policy.js +12 -1
- package/src/grammar/bin.js +2 -12
- package/src/grammar/bin2d.js +1 -6
- package/src/grammar/boxPlot.js +56 -9
- package/src/grammar/categoryOrder.js +1 -6
- package/src/grammar/complete.js +15 -19
- package/src/grammar/computed.js +92 -25
- package/src/grammar/curveCommands.js +29 -16
- package/src/grammar/datasetSchema.js +3 -7
- package/src/grammar/displayLabels.js +28 -0
- package/src/grammar/ecdf.js +2 -9
- package/src/grammar/facets/dependencies.js +6 -2
- package/src/grammar/facets/guides.js +5 -0
- package/src/grammar/facets/index.js +2 -5
- package/src/grammar/fold.js +2 -12
- package/src/grammar/gradientProfile.js +1 -6
- package/src/grammar/impute.js +21 -48
- package/src/grammar/interval.js +2 -9
- package/src/grammar/legendGradient.js +18 -0
- package/src/grammar/legendGroups.js +1 -0
- package/src/grammar/legendTitleStyle.js +22 -0
- package/src/grammar/lineSeries.js +32 -17
- package/src/grammar/markLabels.js +5 -2
- package/src/grammar/normalize.js +4 -54
- package/src/grammar/numeric.js +1 -290
- package/src/grammar/parallelCoordinates.js +1 -6
- package/src/grammar/parseTime.js +41 -0
- package/src/grammar/pathCommands.js +11 -4
- package/src/grammar/polar.js +1 -184
- package/src/grammar/positionCompatibility.js +3 -3
- package/src/grammar/regression/derive.js +7 -1
- package/src/grammar/regression/models.js +83 -55
- package/src/grammar/regression/parameters.js +14 -3
- package/src/grammar/roundedRect.js +42 -54
- package/src/grammar/scales/appearance.js +1 -206
- package/src/grammar/scales/color.js +1 -382
- package/src/grammar/scales/colorConsumers.js +5 -2
- package/src/grammar/scales/definition.js +1 -197
- package/src/grammar/scales/discretized.js +1 -195
- package/src/grammar/scales/size.js +1 -456
- package/src/grammar/scales/temporal.js +2 -13
- package/src/grammar/scales/transformed.js +1 -383
- package/src/grammar/scales/types.js +1 -1
- package/src/grammar/scales/validation.js +1 -66
- package/src/grammar/schemas/concreteGraphic.js +11 -0
- package/src/grammar/schemas/graphic.js +3 -0
- package/src/grammar/schemas/semanticPath.js +2 -1
- package/src/grammar/stack.js +2 -10
- package/src/grammar/statisticalReference.js +1 -6
- package/src/grammar/summary.js +3 -26
- package/src/grammar/text.js +19 -0
- package/src/grammar/timeUnit.js +16 -7
- package/src/grammar/transformKeys.js +47 -0
- package/src/grammar/transforms.js +4 -1
- package/src/grammar/valueFormat.js +17 -5
- package/src/grammar/weightedStatistics.js +1 -6
- package/src/grammar/window.js +4 -58
- package/src/inspectionDescriptors.js +1 -1
- package/src/layout/canvas.js +1 -110
- package/src/layout/facets.js +1 -244
- package/src/layout/labels.js +1 -0
- package/src/layout/legend.js +13 -0
- package/src/layout/legendGroup.js +1 -0
- package/src/layout/legendItems.js +59 -15
- package/src/layout/legendLane.js +1 -441
- package/src/layout/legendText.js +1 -0
- package/src/layout/title.js +35 -13
- package/src/materialization/bars/aggregate.js +11 -5
- package/src/materialization/bars/histogram.js +4 -1
- package/src/materialization/bars/ranged.js +19 -6
- package/src/materialization/bars/resolve.js +22 -1
- package/src/materialization/coordinateBounds.js +8 -0
- package/src/materialization/dependencies.js +4 -44
- package/src/materialization/facetGuides/layout.js +1 -0
- package/src/materialization/facetGuides/placement.js +19 -8
- package/src/materialization/facetGuides/preparation.js +15 -7
- package/src/materialization/facetHeaders.js +1 -347
- package/src/materialization/facets.js +1 -185
- package/src/materialization/graphicHierarchy.js +1 -1
- package/src/materialization/guides/layout.js +1 -57
- package/src/materialization/guides/resources.js +1 -123
- package/src/materialization/layout.js +53 -0
- package/src/materialization/legendGroups.js +1 -0
- package/src/materialization/legendText.js +1 -0
- package/src/materialization/legends.js +1 -1
- package/src/materialization/marks/capabilities.js +5 -6
- package/src/materialization/rect.js +1 -1
- package/src/materialization/scaleGuideDependencies.js +1 -1
- package/src/materialization/scales/map.js +3 -0
- package/src/materialization/scales/policies/arc.js +8 -7
- package/src/materialization/scales/policies/bar.js +19 -7
- package/src/materialization/scales/policies/series.js +2 -1
- package/src/materialization/scales/resolve.js +5 -3
- package/src/materialization/selection/items/arc.js +1 -1
- package/src/materialization/selection/items/bar.js +7 -6
- package/src/materialization/selection/items/path.js +7 -6
- package/src/materialization/selection/items/rect.js +2 -2
- package/src/materialization/text.js +13 -4
- package/src/materialization/textLines.js +15 -0
- package/src/persistence/codec.js +37 -6
- package/src/persistence/validation.js +47 -0
- package/src/persistence.js +18 -5
- package/src/renderers/canvas/circle.js +6 -3
- package/src/renderers/canvas/fill.js +7 -1
- package/src/renderers/canvas/index.js +2 -1
- package/src/renderers/canvas/line.js +1 -0
- package/src/renderers/canvas/path.js +1 -1
- package/src/renderers/canvas/rect.js +11 -8
- package/src/renderers/canvas/stroke.js +2 -1
- package/src/renderers/canvas/text.js +5 -3
- package/src/renderers/svg.js +4 -1
- package/src/selectors/layers.js +19 -0
- package/src/theme/defaults.js +8 -2
- package/src/version.js +1 -1
- package/types/basic.d.ts +1 -0
- package/types/index.d.ts +7 -0
- package/types/program.d.ts +347 -85
|
@@ -1,456 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { validateGeneratedItemLimit } from "../../core/validation.js";
|
|
3
|
-
import { interpolateNumber } from "../numeric.js";
|
|
4
|
-
import { validateSizeRange, resolveSizeRange } from "./appearance.js";
|
|
5
|
-
import { mapLinearValues } from "./continuous.js";
|
|
6
|
-
import { mapTransformedValues, resolveTransformedDomain } from "./transformed.js";
|
|
7
|
-
import { validateScaleUnknown } from "./policies.js";
|
|
8
|
-
import { validatePair } from "./validation.js";
|
|
9
|
-
|
|
10
|
-
export const CONTINUOUS_SIZE_SCALE_TYPES = cloneAndFreeze([
|
|
11
|
-
"linear", "log", "sqrt", "pow"
|
|
12
|
-
]);
|
|
13
|
-
export const DISCRETE_SIZE_SCALE_TYPES = cloneAndFreeze([
|
|
14
|
-
"quantize", "quantile", "threshold"
|
|
15
|
-
]);
|
|
16
|
-
export const SIZE_SCALE_TYPES = cloneAndFreeze([
|
|
17
|
-
...CONTINUOUS_SIZE_SCALE_TYPES,
|
|
18
|
-
...DISCRETE_SIZE_SCALE_TYPES
|
|
19
|
-
]);
|
|
20
|
-
|
|
21
|
-
export function isContinuousSizeScaleType(type) {
|
|
22
|
-
return CONTINUOUS_SIZE_SCALE_TYPES.includes(type);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function isDiscreteSizeScaleType(type) {
|
|
26
|
-
return DISCRETE_SIZE_SCALE_TYPES.includes(type);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function isSizeScaleType(type) {
|
|
30
|
-
return SIZE_SCALE_TYPES.includes(type);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function validateSizeScaleType(type) {
|
|
34
|
-
if (!isSizeScaleType(type)) {
|
|
35
|
-
throw new Error(`Scale type "${type}" is not valid for size.`);
|
|
36
|
-
}
|
|
37
|
-
return type;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function finiteArray(value, label, minimumLength = 1) {
|
|
41
|
-
if (
|
|
42
|
-
!Array.isArray(value) ||
|
|
43
|
-
value.length < minimumLength ||
|
|
44
|
-
!value.every(Number.isFinite)
|
|
45
|
-
) {
|
|
46
|
-
throw new TypeError(`${label} must contain finite numbers.`);
|
|
47
|
-
}
|
|
48
|
-
return value;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function strictlyIncreasing(value, label) {
|
|
52
|
-
finiteArray(value, label);
|
|
53
|
-
if (value.some((item, index) => index > 0 && item <= value[index - 1])) {
|
|
54
|
-
throw new RangeError(`${label} must be strictly increasing.`);
|
|
55
|
-
}
|
|
56
|
-
return value;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function validateContinuousDomain(type, domain) {
|
|
60
|
-
const validated = validatePair(domain, "Size scale domain");
|
|
61
|
-
if (type !== "linear" && validated[0] === validated[1]) {
|
|
62
|
-
throw new RangeError(
|
|
63
|
-
`Size ${type} scale domain values must be distinct.`
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
if (type === "log" && validated.some(value => value <= 0)) {
|
|
67
|
-
throw new RangeError("Size log scale domain must be strictly positive.");
|
|
68
|
-
}
|
|
69
|
-
if (["sqrt", "pow"].includes(type) && validated.some(value => value < 0)) {
|
|
70
|
-
throw new RangeError(
|
|
71
|
-
`Size ${type} scale domain must be non-negative.`
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
return validated;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function validateSizeScaleDomain(type, domain) {
|
|
78
|
-
validateSizeScaleType(type);
|
|
79
|
-
if (domain === "auto") {
|
|
80
|
-
if (type === "threshold") {
|
|
81
|
-
throw new Error("Threshold size scale requires an explicit domain.");
|
|
82
|
-
}
|
|
83
|
-
return domain;
|
|
84
|
-
}
|
|
85
|
-
if (isContinuousSizeScaleType(type)) {
|
|
86
|
-
return validateContinuousDomain(type, domain);
|
|
87
|
-
}
|
|
88
|
-
if (type === "quantize") {
|
|
89
|
-
const validated = validatePair(domain, "Quantize size domain");
|
|
90
|
-
if (validated[0] >= validated[1]) {
|
|
91
|
-
throw new RangeError(
|
|
92
|
-
"Quantize size domain must be a strictly increasing pair."
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
return validated;
|
|
96
|
-
}
|
|
97
|
-
if (type === "quantile") {
|
|
98
|
-
return cloneAndFreeze(finiteArray(domain, "Quantile size domain"));
|
|
99
|
-
}
|
|
100
|
-
return cloneAndFreeze(
|
|
101
|
-
strictlyIncreasing(domain, "Threshold size domain")
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function validateDiscreteSizeRange(range) {
|
|
106
|
-
finiteArray(range, "Discrete size range", 2);
|
|
107
|
-
validateGeneratedItemLimit(range.length, "Discrete size range length");
|
|
108
|
-
if (range.some(value => value < 0)) {
|
|
109
|
-
throw new RangeError(
|
|
110
|
-
"Discrete size range must contain non-negative areas."
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
if (range.some((value, index) => index > 0 && value < range[index - 1])) {
|
|
114
|
-
throw new RangeError("Discrete size range must be nondecreasing.");
|
|
115
|
-
}
|
|
116
|
-
return cloneAndFreeze(range);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export function validateSizeScaleRange(type, range) {
|
|
120
|
-
validateSizeScaleType(type);
|
|
121
|
-
if (isContinuousSizeScaleType(type)) return validateSizeRange(range);
|
|
122
|
-
if (range === "auto") {
|
|
123
|
-
throw new Error(`Size ${type} scale requires an explicit range.`);
|
|
124
|
-
}
|
|
125
|
-
return validateDiscreteSizeRange(range);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function sizeTypeFamily(type) {
|
|
129
|
-
return isContinuousSizeScaleType(type) ? "continuous" : type;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function requireBoolean(value, label) {
|
|
133
|
-
if (typeof value !== "boolean") {
|
|
134
|
-
throw new TypeError(`${label} must be a boolean.`);
|
|
135
|
-
}
|
|
136
|
-
return value;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function positiveFinite(value, label) {
|
|
140
|
-
if (!Number.isFinite(value) || value <= 0) {
|
|
141
|
-
throw new RangeError(`${label} must be a positive finite number.`);
|
|
142
|
-
}
|
|
143
|
-
return value;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export function normalizeSizeScaleDefinition({ previous = {}, patch = {} } = {}) {
|
|
147
|
-
const type = validateSizeScaleType(patch.type ?? previous.type ?? "linear");
|
|
148
|
-
const hasPrevious = previous.type !== undefined;
|
|
149
|
-
const typeChanged = hasPrevious && previous.type !== type;
|
|
150
|
-
if (typeChanged && sizeTypeFamily(previous.type) !== sizeTypeFamily(type) &&
|
|
151
|
-
!Object.hasOwn(patch, "domain")) {
|
|
152
|
-
throw new Error(
|
|
153
|
-
"Size scale type-family transition requires an explicit domain."
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
if (typeChanged && isDiscreteSizeScaleType(type) &&
|
|
157
|
-
!Object.hasOwn(patch, "range")) {
|
|
158
|
-
throw new Error(
|
|
159
|
-
`Size ${type} scale transition requires an explicit range.`
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
if (typeChanged && isDiscreteSizeScaleType(previous.type) &&
|
|
163
|
-
isContinuousSizeScaleType(type) && !Object.hasOwn(patch, "range")) {
|
|
164
|
-
throw new Error(
|
|
165
|
-
"Discrete-to-continuous size scale transition requires an explicit range."
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
for (const property of [
|
|
169
|
-
"nice", "zero", "constant", "padding", "paddingInner", "paddingOuter",
|
|
170
|
-
"align", "palette", "interpolate", "midpoint", "radialMapping"
|
|
171
|
-
]) {
|
|
172
|
-
if (Object.hasOwn(patch, property)) {
|
|
173
|
-
throw new Error(`Size scale does not support ${property}.`);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const rawDomain = Object.hasOwn(patch, "domain")
|
|
178
|
-
? patch.domain
|
|
179
|
-
: Object.hasOwn(previous, "domain")
|
|
180
|
-
? previous.domain
|
|
181
|
-
: "auto";
|
|
182
|
-
const rawRange = Object.hasOwn(patch, "range")
|
|
183
|
-
? patch.range
|
|
184
|
-
: Object.hasOwn(previous, "range")
|
|
185
|
-
? previous.range
|
|
186
|
-
: "auto";
|
|
187
|
-
const definition = {
|
|
188
|
-
type,
|
|
189
|
-
domain: validateSizeScaleDomain(type, rawDomain),
|
|
190
|
-
range: validateSizeScaleRange(type, rawRange)
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
const reverse = Object.hasOwn(patch, "reverse")
|
|
194
|
-
? patch.reverse
|
|
195
|
-
: previous.reverse;
|
|
196
|
-
if (reverse !== undefined) {
|
|
197
|
-
definition.reverse = requireBoolean(reverse, "Size scale reverse");
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (isContinuousSizeScaleType(type)) {
|
|
201
|
-
const clamp = Object.hasOwn(patch, "clamp")
|
|
202
|
-
? patch.clamp
|
|
203
|
-
: isContinuousSizeScaleType(previous.type)
|
|
204
|
-
? previous.clamp
|
|
205
|
-
: undefined;
|
|
206
|
-
if (clamp !== undefined) {
|
|
207
|
-
definition.clamp = requireBoolean(clamp, "Size scale clamp");
|
|
208
|
-
}
|
|
209
|
-
} else if (Object.hasOwn(patch, "clamp")) {
|
|
210
|
-
throw new Error(`Size ${type} scale does not support clamp.`);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (type === "log") {
|
|
214
|
-
const base = Object.hasOwn(patch, "base")
|
|
215
|
-
? patch.base
|
|
216
|
-
: !typeChanged && previous.type === "log"
|
|
217
|
-
? previous.base
|
|
218
|
-
: 10;
|
|
219
|
-
definition.base = positiveFinite(base ?? 10, "Size log scale base");
|
|
220
|
-
if (definition.base === 1) {
|
|
221
|
-
throw new RangeError("Size log scale base must not equal 1.");
|
|
222
|
-
}
|
|
223
|
-
} else if (Object.hasOwn(patch, "base")) {
|
|
224
|
-
throw new Error(`Size ${type} scale does not support base.`);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (type === "pow") {
|
|
228
|
-
const exponent = Object.hasOwn(patch, "exponent")
|
|
229
|
-
? patch.exponent
|
|
230
|
-
: !typeChanged && previous.type === "pow"
|
|
231
|
-
? previous.exponent
|
|
232
|
-
: undefined;
|
|
233
|
-
if (exponent === undefined) {
|
|
234
|
-
throw new Error("Size pow scale requires an explicit exponent.");
|
|
235
|
-
}
|
|
236
|
-
definition.exponent = positiveFinite(
|
|
237
|
-
exponent,
|
|
238
|
-
"Size pow scale exponent"
|
|
239
|
-
);
|
|
240
|
-
} else if (Object.hasOwn(patch, "exponent")) {
|
|
241
|
-
throw new Error(`Size ${type} scale does not support exponent.`);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
const unknown = Object.hasOwn(patch, "unknown")
|
|
245
|
-
? patch.unknown
|
|
246
|
-
: previous.unknown;
|
|
247
|
-
if (unknown !== undefined) {
|
|
248
|
-
definition.unknown = validateScaleUnknown("size", unknown);
|
|
249
|
-
}
|
|
250
|
-
return cloneAndFreeze(definition);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
function validateSizeValues(values, type) {
|
|
254
|
-
if (!Array.isArray(values) || !values.every(Number.isFinite)) {
|
|
255
|
-
throw new TypeError("Size scale values must be finite numbers.");
|
|
256
|
-
}
|
|
257
|
-
if (type === "log" && values.some(value => value <= 0)) {
|
|
258
|
-
throw new RangeError("Size log scale values must be strictly positive.");
|
|
259
|
-
}
|
|
260
|
-
if (["sqrt", "pow"].includes(type) && values.some(value => value < 0)) {
|
|
261
|
-
throw new RangeError(`Size ${type} scale values must be non-negative.`);
|
|
262
|
-
}
|
|
263
|
-
return values;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
function numericExtent(values) {
|
|
267
|
-
let minimum = values[0];
|
|
268
|
-
let maximum = values[0];
|
|
269
|
-
for (const value of values.slice(1)) {
|
|
270
|
-
minimum = Math.min(minimum, value);
|
|
271
|
-
maximum = Math.max(maximum, value);
|
|
272
|
-
}
|
|
273
|
-
return [minimum, maximum];
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
function resolveContinuousSizeDomain(definition, values) {
|
|
277
|
-
validateSizeValues(values, definition.type);
|
|
278
|
-
if (definition.domain !== "auto") {
|
|
279
|
-
return validateSizeScaleDomain(definition.type, definition.domain);
|
|
280
|
-
}
|
|
281
|
-
if (values.length === 0) {
|
|
282
|
-
throw new Error("Cannot infer an automatic size scale domain from no values.");
|
|
283
|
-
}
|
|
284
|
-
if (definition.type === "linear") {
|
|
285
|
-
return cloneAndFreeze(numericExtent(values));
|
|
286
|
-
}
|
|
287
|
-
if (["sqrt", "pow"].includes(definition.type) && values.every(value => value === 0)) {
|
|
288
|
-
return cloneAndFreeze([0, 1]);
|
|
289
|
-
}
|
|
290
|
-
const domain = resolveTransformedDomain({
|
|
291
|
-
type: definition.type,
|
|
292
|
-
domain: "auto",
|
|
293
|
-
values,
|
|
294
|
-
...(definition.type === "log" ? { base: definition.base } : {}),
|
|
295
|
-
...(definition.type === "pow" ? { exponent: definition.exponent } : {})
|
|
296
|
-
});
|
|
297
|
-
return validateSizeScaleDomain(definition.type, domain);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
function quantile(sorted, probability) {
|
|
301
|
-
const position = (sorted.length - 1) * probability;
|
|
302
|
-
const lower = Math.floor(position);
|
|
303
|
-
const upper = Math.ceil(position);
|
|
304
|
-
return interpolateNumber(
|
|
305
|
-
sorted[lower],
|
|
306
|
-
sorted[upper],
|
|
307
|
-
position - lower
|
|
308
|
-
);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
export function resolveSizeScale({
|
|
312
|
-
type,
|
|
313
|
-
domain = "auto",
|
|
314
|
-
range = "auto",
|
|
315
|
-
values = [],
|
|
316
|
-
...options
|
|
317
|
-
} = {}) {
|
|
318
|
-
const definition = normalizeSizeScaleDefinition({
|
|
319
|
-
patch: { type, domain, range, ...options }
|
|
320
|
-
});
|
|
321
|
-
validateSizeValues(values, definition.type);
|
|
322
|
-
if (isContinuousSizeScaleType(definition.type)) {
|
|
323
|
-
const resolvedDomain = resolveContinuousSizeDomain(definition, values);
|
|
324
|
-
const resolvedRange = [...resolveSizeRange(definition.range)];
|
|
325
|
-
if (definition.reverse === true) resolvedRange.reverse();
|
|
326
|
-
return cloneAndFreeze({
|
|
327
|
-
type: definition.type,
|
|
328
|
-
domain: resolvedDomain,
|
|
329
|
-
range: resolvedRange,
|
|
330
|
-
...(definition.clamp === undefined ? {} : { clamp: definition.clamp }),
|
|
331
|
-
...(definition.type === "log" ? { base: definition.base } : {}),
|
|
332
|
-
...(definition.type === "pow" ? { exponent: definition.exponent } : {}),
|
|
333
|
-
...(definition.unknown === undefined ? {} : { unknown: definition.unknown })
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const resolvedRange = [...definition.range];
|
|
338
|
-
if (definition.reverse === true) resolvedRange.reverse();
|
|
339
|
-
const sample = [...values].sort((left, right) => left - right);
|
|
340
|
-
let resolvedDomain;
|
|
341
|
-
let thresholds;
|
|
342
|
-
if (definition.type === "quantize") {
|
|
343
|
-
if (definition.domain === "auto") {
|
|
344
|
-
if (sample.length === 0) {
|
|
345
|
-
throw new Error(
|
|
346
|
-
"Cannot infer an automatic quantize size domain from no values."
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
resolvedDomain = numericExtent(sample);
|
|
350
|
-
if (resolvedDomain[0] === resolvedDomain[1]) {
|
|
351
|
-
throw new RangeError(
|
|
352
|
-
"Quantize size scale requires a non-zero domain span."
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
} else {
|
|
356
|
-
resolvedDomain = [...definition.domain];
|
|
357
|
-
}
|
|
358
|
-
thresholds = Array.from(
|
|
359
|
-
{ length: resolvedRange.length - 1 },
|
|
360
|
-
(_, index) => interpolateNumber(
|
|
361
|
-
resolvedDomain[0],
|
|
362
|
-
resolvedDomain[1],
|
|
363
|
-
(index + 1) / resolvedRange.length
|
|
364
|
-
)
|
|
365
|
-
);
|
|
366
|
-
if (thresholds.some((value, index) =>
|
|
367
|
-
value <= (index === 0 ? resolvedDomain[0] : thresholds[index - 1]) ||
|
|
368
|
-
value >= resolvedDomain[1]
|
|
369
|
-
)) {
|
|
370
|
-
throw new RangeError(
|
|
371
|
-
"Quantize size range requests more buckets than its domain can represent."
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
} else if (definition.type === "quantile") {
|
|
375
|
-
const source = definition.domain === "auto"
|
|
376
|
-
? sample
|
|
377
|
-
: [...definition.domain].sort((left, right) => left - right);
|
|
378
|
-
if (source.length === 0) {
|
|
379
|
-
throw new Error(
|
|
380
|
-
"Cannot infer automatic quantile size thresholds from no values."
|
|
381
|
-
);
|
|
382
|
-
}
|
|
383
|
-
resolvedDomain = source;
|
|
384
|
-
thresholds = Array.from(
|
|
385
|
-
{ length: resolvedRange.length - 1 },
|
|
386
|
-
(_, index) => quantile(
|
|
387
|
-
source,
|
|
388
|
-
(index + 1) / resolvedRange.length
|
|
389
|
-
)
|
|
390
|
-
);
|
|
391
|
-
} else {
|
|
392
|
-
resolvedDomain = [...definition.domain];
|
|
393
|
-
thresholds = [...definition.domain];
|
|
394
|
-
if (resolvedRange.length !== thresholds.length + 1) {
|
|
395
|
-
throw new RangeError(
|
|
396
|
-
"Threshold size range must contain exactly one more area than its domain."
|
|
397
|
-
);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
return cloneAndFreeze({
|
|
401
|
-
type: definition.type,
|
|
402
|
-
domain: resolvedDomain,
|
|
403
|
-
thresholds,
|
|
404
|
-
range: resolvedRange,
|
|
405
|
-
...(definition.unknown === undefined ? {} : { unknown: definition.unknown })
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
export function discretizedSizeIndex(value, thresholds) {
|
|
410
|
-
if (!Number.isFinite(value)) {
|
|
411
|
-
throw new TypeError("Discrete size values must be finite numbers.");
|
|
412
|
-
}
|
|
413
|
-
let index = 0;
|
|
414
|
-
while (index < thresholds.length && value >= thresholds[index]) index += 1;
|
|
415
|
-
return index;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
function validateMappedAreas(areas) {
|
|
419
|
-
if (areas.some(area => !Number.isFinite(area) || area < 0)) {
|
|
420
|
-
throw new RangeError(
|
|
421
|
-
"Size scale mapping must produce non-negative finite areas."
|
|
422
|
-
);
|
|
423
|
-
}
|
|
424
|
-
return cloneAndFreeze(areas);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
export function mapSizeValues(values, scale) {
|
|
428
|
-
validateSizeScaleType(scale?.type);
|
|
429
|
-
const hasUnknown = Object.hasOwn(scale, "unknown");
|
|
430
|
-
const finite = values.filter(Number.isFinite);
|
|
431
|
-
validateSizeValues(finite, scale.type);
|
|
432
|
-
if (!hasUnknown && finite.length !== values.length) {
|
|
433
|
-
throw new TypeError("Size scale values must be finite numbers.");
|
|
434
|
-
}
|
|
435
|
-
let mapped;
|
|
436
|
-
if (isDiscreteSizeScaleType(scale.type)) {
|
|
437
|
-
mapped = values.map(value => {
|
|
438
|
-
if (!Number.isFinite(value)) return scale.unknown;
|
|
439
|
-
return scale.range[discretizedSizeIndex(value, scale.thresholds)];
|
|
440
|
-
});
|
|
441
|
-
} else if (scale.type === "linear") {
|
|
442
|
-
mapped = mapLinearValues(values, scale.domain, scale.range, {
|
|
443
|
-
clamp: scale.clamp ?? false,
|
|
444
|
-
...(hasUnknown ? { unknown: scale.unknown } : {})
|
|
445
|
-
});
|
|
446
|
-
} else {
|
|
447
|
-
mapped = mapTransformedValues(values, scale.domain, scale.range, {
|
|
448
|
-
type: scale.type,
|
|
449
|
-
clamp: scale.clamp ?? false,
|
|
450
|
-
...(hasUnknown ? { unknown: scale.unknown } : {}),
|
|
451
|
-
...(scale.type === "log" ? { base: scale.base } : {}),
|
|
452
|
-
...(scale.type === "pow" ? { exponent: scale.exponent } : {})
|
|
453
|
-
});
|
|
454
|
-
}
|
|
455
|
-
return validateMappedAreas(mapped);
|
|
456
|
-
}
|
|
1
|
+
import{cloneAndFreeze as u}from"../../core/immutable.js";import{validateGeneratedItemLimit as g,validatePositiveFinite as R}from"../../core/validation.js";import{interpolateNumber as $,numericExtent as q}from"../numeric.js";import{isNominalValue as A}from"./fields.js";import{resolveOrdinalDomain as C,validateOrdinalDomain as I}from"./ordinal.js";import{mapLinearValues as _}from"./continuous.js";import{mapTransformedValues as j,resolveTransformedDomain as F}from"./transformed.js";import{validateSizeRange as N,DEFAULT_SIZE_RANGE as P,mapOrdinalValues as L}from"./appearance.js";import{validateScaleUnknown as V}from"./policies.js";import{validatePair as U,validateFiniteScaleArray as E}from"./validation.js";import{resolveDiscretizedDomain as Z,validateDiscretizedDomain as Y,discretizedColorIndex as G}from"./discretized.js";const x=u(["linear","log","sqrt","pow"]),O=u(["quantize","quantile","threshold"]),M=u([...x,...O,"ordinal"]);function m(e){return x.includes(e)}function f(e){return O.includes(e)}function ce(e){return e==="ordinal"||f(e)}function B(e){return M.includes(e)}function w(e){if(!B(e))throw new Error(`Scale type "${e}" is not valid for size.`);return e}function v(e,n,t){if(n==="log"&&e.some(o=>o<=0))throw new RangeError(`Size log scale ${t} must be strictly positive.`);if(["sqrt","pow"].includes(n)&&e.some(o=>o<0))throw new RangeError(`Size ${n} scale ${t} must be non-negative.`);return e}function H(e,n){const t=U(n,"Size scale domain");if(e!=="linear"&&t[0]===t[1])throw new RangeError(`Size ${e} scale domain values must be distinct.`);return v(t,e,"domain")}function z(e,n){return w(e),e==="ordinal"?I(n):m(e)?n==="auto"?n:H(e,n):Y(e,n,"size")}function J(e){if(E(e,"Discrete size range",2),g(e.length,"Discrete size range length"),e.some(n=>n<0))throw new RangeError("Discrete size range must contain non-negative areas.");if(e.some((n,t)=>t>0&&n<e[t-1]))throw new RangeError("Discrete size range must be nondecreasing.");return u(e)}function K(e,n){if(w(e),m(e))return N(n);if(e==="ordinal")return n==="auto"?n:(E(n,"Ordinal size range"),g(n.length,"Ordinal size range length"),y(n));if(n==="auto")throw new Error(`Size ${e} scale requires an explicit range.`);return J(n)}function D(e){return m(e)?"continuous":e}function Q({previous:e={},patch:n={}}={}){const t=w(n.type??e.type??"linear"),s=e.type!==void 0&&e.type!==t;if(s&&D(e.type)!==D(t)&&!Object.hasOwn(n,"domain"))throw new Error("Size scale type-family transition requires an explicit domain.");if(s&&f(t)&&!Object.hasOwn(n,"range"))throw new Error(`Size ${t} scale transition requires an explicit range.`);if(s&&f(e.type)&&m(t)&&!Object.hasOwn(n,"range"))throw new Error("Discrete-to-continuous size scale transition requires an explicit range.");for(const i of["nice","zero","constant","padding","paddingInner","paddingOuter","align","palette","interpolate","midpoint","radialMapping"])if(Object.hasOwn(n,i))throw new Error(`Size scale does not support ${i}.`);const r={domain:"auto",range:"auto",...e,...n},a={type:t,domain:z(t,r.domain),range:K(t,r.range)};for(const i of["reverse","clamp"]){if(i==="clamp"&&!m(t)){if(Object.hasOwn(n,i))throw new Error(`Size ${t} scale does not support clamp.`);continue}const p=Object.hasOwn(n,i)?n[i]:i==="clamp"&&!m(e.type)?void 0:e[i];if(p!==void 0){if(typeof p!="boolean")throw new TypeError(`Size scale ${i} must be a boolean.`);a[i]=p}}for(const[i,p,c]of[["base","log",10],["exponent","pow"]]){if(t!==p){if(Object.hasOwn(n,i))throw new Error(`Size ${t} scale does not support ${i}.`);continue}const l=Object.hasOwn(n,i)?n[i]:!s&&e.type===p?e[i]:c;if(i==="exponent"&&l===void 0)throw new Error("Size pow scale requires an explicit exponent.");if(a[i]=R(i==="base"?l??c:l,`Size ${t} scale ${i}`),i==="base"&&a.base===1)throw new RangeError("Size log scale base must not equal 1.")}const d=Object.hasOwn(n,"unknown")?n.unknown:e.unknown;return d!==void 0&&(a.unknown=V("size",d)),u(a)}function k(e,n){if(!Array.isArray(e)||!e.every(Number.isFinite))throw new TypeError("Size scale values must be finite numbers.");return v(e,n,"values")}function W(e,n){if(e.domain!=="auto")return z(e.type,e.domain);if(n.length===0)throw new Error("Cannot infer an automatic size scale domain from no values.");if(e.type==="linear")return u(q(n));if(["sqrt","pow"].includes(e.type)&&n.every(o=>o===0))return u([0,1]);const t=F({type:e.type,domain:"auto",values:n,...e.type==="log"?{base:e.base}:{},...e.type==="pow"?{exponent:e.exponent}:{}});return z(e.type,t)}function fe({type:e,domain:n="auto",range:t="auto",values:o=[],...s}={}){const r=Q({patch:{type:e,domain:n,range:t,...s}}),a=r.type==="ordinal",d=a?o.filter(A):k(o,r.type);if(a&&d.length!==o.length&&r.unknown===void 0)throw new TypeError("Ordinal size values must be nominal values.");if(a||m(r.type)){const l=a?C(r.domain,d):W(r,o);a&&g(l.length,"Ordinal size domain length");const S=r.range==="auto"?P:r.range,h=a&&r.range==="auto"?l.map((ne,T)=>$(S[0],S[1],l.length===1?.5:T/(l.length-1))):[...S];r.reverse===!0&&h.reverse();const b=u({type:r.type,domain:l,range:h,...r.clamp===void 0?{}:{clamp:r.clamp},...r.type==="log"?{base:r.base}:{},...r.type==="pow"?{exponent:r.exponent}:{},...r.unknown===void 0?{}:{unknown:r.unknown}});return a&&ee(o,b),b}const i=[...r.range];r.reverse===!0&&i.reverse();const{domain:p,thresholds:c}=Z({type:r.type,domain:r.domain,values:o,count:i.length,kind:"size"});return u({type:r.type,domain:p,thresholds:c,range:i,...r.unknown===void 0?{}:{unknown:r.unknown}})}function X(e,n){return G(e,n,"Discrete size")}function y(e){if(e.some(n=>!Number.isFinite(n)||n<0))throw new RangeError("Size scale mapping must produce non-negative finite areas.");return u(e)}function ee(e,n){w(n?.type);const t=Object.hasOwn(n,"unknown");if(n.type==="ordinal")return y(L(e,n.domain,n.range,t?{unknown:n.unknown}:{}));const o=e.filter(Number.isFinite);if(k(o,n.type),!t&&o.length!==e.length)throw new TypeError("Size scale values must be finite numbers.");let s;return f(n.type)?s=e.map(r=>Number.isFinite(r)?n.range[X(r,n.thresholds)]:n.unknown):s=(n.type==="linear"?_:j)(e,n.domain,n.range,{type:n.type,clamp:n.clamp??!1,...t?{unknown:n.unknown}:{},...n.type==="log"?{base:n.base}:{},...n.type==="pow"?{exponent:n.exponent}:{}}),y(s)}export{x as CONTINUOUS_SIZE_SCALE_TYPES,O as DISCRETE_SIZE_SCALE_TYPES,M as SIZE_SCALE_TYPES,X as discretizedSizeIndex,m as isContinuousSizeScaleType,f as isDiscreteSizeScaleType,ce as isEnumeratedSizeScaleType,B as isSizeScaleType,ee as mapSizeValues,Q as normalizeSizeScaleDefinition,fe as resolveSizeScale,J as validateDiscreteSizeRange,z as validateSizeScaleDomain,K as validateSizeScaleRange,w as validateSizeScaleType};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cloneAndFreeze } from "../../core/immutable.js";
|
|
2
|
-
import { utcTimestamp, validTimestamp } from "../timeUnit.js";
|
|
2
|
+
import { utcTimestamp, validTimestamp, offsetUtcTimeUnit } from "../timeUnit.js";
|
|
3
3
|
|
|
4
4
|
const TIME_UNITS = [
|
|
5
5
|
{ span: 2 * 365 * 24 * 60 * 60 * 1000, unit: "year" },
|
|
@@ -56,17 +56,6 @@ function floorUtc(timestamp, unit) {
|
|
|
56
56
|
return Math.floor(timestamp / 1000) * 1000;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
function offsetUtc(timestamp, unit) {
|
|
60
|
-
const date = new Date(timestamp);
|
|
61
|
-
if (unit === "year") return utcTimestamp(date.getUTCFullYear() + 1);
|
|
62
|
-
if (unit === "month") {
|
|
63
|
-
return utcTimestamp(date.getUTCFullYear(), date.getUTCMonth() + 1);
|
|
64
|
-
}
|
|
65
|
-
if (unit === "day") return timestamp + 24 * 60 * 60 * 1000;
|
|
66
|
-
if (unit === "hour") return timestamp + 60 * 60 * 1000;
|
|
67
|
-
if (unit === "minute") return timestamp + 60 * 1000;
|
|
68
|
-
return timestamp + 1000;
|
|
69
|
-
}
|
|
70
59
|
|
|
71
60
|
export function niceTimeDomain(domain) {
|
|
72
61
|
const [minimum, maximum] = requireTimeDomain(domain);
|
|
@@ -74,7 +63,7 @@ export function niceTimeDomain(domain) {
|
|
|
74
63
|
const unit = TIME_UNITS.find(item => maximum - minimum >= item.span).unit;
|
|
75
64
|
const start = floorUtc(minimum, unit);
|
|
76
65
|
const endFloor = floorUtc(maximum, unit);
|
|
77
|
-
const end = endFloor === maximum ? maximum :
|
|
66
|
+
const end = endFloor === maximum ? maximum : offsetUtcTimeUnit(endFloor, unit);
|
|
78
67
|
if (![start, end].every(validTimestamp)) {
|
|
79
68
|
throw new RangeError("Nice time domain exceeds the supported date range.");
|
|
80
69
|
}
|