ooxml-core 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +21 -43
  2. package/dist/chart/axis-nice.d.ts +97 -0
  3. package/dist/chart/axis-nice.d.ts.map +1 -0
  4. package/dist/chart/histogram-binning.d.ts +40 -0
  5. package/dist/chart/histogram-binning.d.ts.map +1 -0
  6. package/dist/chart/index.cjs +167 -0
  7. package/dist/chart/index.d.ts +2 -0
  8. package/dist/chart/index.d.ts.map +1 -1
  9. package/dist/chart/index.mjs +162 -1
  10. package/dist/index.cjs +167 -0
  11. package/dist/index.mjs +167 -0
  12. package/dist/pptx/automation/index.cjs +1572 -863
  13. package/dist/pptx/automation/index.d.ts +4 -3
  14. package/dist/pptx/automation/index.d.ts.map +1 -1
  15. package/dist/pptx/automation/index.mjs +1572 -863
  16. package/dist/pptx/chunks/color-ref-BM66NGFP.d.ts +42 -0
  17. package/dist/pptx/chunks/color-ref-BM66NGFP.d.ts.map +1 -0
  18. package/dist/pptx/chunks/{index-D0yGoLyw.d.ts → index-CcQTCBnT.d.ts} +63 -479
  19. package/dist/pptx/chunks/index-CcQTCBnT.d.ts.map +1 -0
  20. package/dist/pptx/chunks/{index-BtBj3VG1.d.ts → index-DHoPgFcH.d.ts} +529 -11
  21. package/dist/pptx/chunks/index-DHoPgFcH.d.ts.map +1 -0
  22. package/dist/pptx/chunks/{text-operations-GuisjlbR.d.ts → text-operations-BzdehTeY.d.ts} +50 -51
  23. package/dist/pptx/chunks/text-operations-BzdehTeY.d.ts.map +1 -0
  24. package/dist/pptx/cli/index.cjs +1204 -489
  25. package/dist/pptx/cli/index.d.ts +1 -1
  26. package/dist/pptx/cli/index.mjs +1204 -489
  27. package/dist/pptx/converter/index.cjs +8 -5
  28. package/dist/pptx/converter/index.d.ts +1 -1
  29. package/dist/pptx/converter/index.mjs +8 -5
  30. package/dist/pptx/index.cjs +1699 -989
  31. package/dist/pptx/index.d.ts +5 -4
  32. package/dist/pptx/index.mjs +1698 -990
  33. package/dist/pptx/ui/index.cjs +510 -0
  34. package/dist/pptx/ui/index.d.ts +80 -0
  35. package/dist/pptx/ui/index.d.ts.map +1 -0
  36. package/dist/pptx/ui/index.mjs +499 -0
  37. package/package.json +15 -4
  38. package/dist/pptx/chunks/index-BtBj3VG1.d.ts.map +0 -1
  39. package/dist/pptx/chunks/index-D0yGoLyw.d.ts.map +0 -1
  40. package/dist/pptx/chunks/text-operations-GuisjlbR.d.ts.map +0 -1
package/dist/index.cjs CHANGED
@@ -191,13 +191,19 @@ function linearToSrgb255(linear) {
191
191
  // src/chart/index.ts
192
192
  var chart_exports = {};
193
193
  __export(chart_exports, {
194
+ aggregateByCategory: () => aggregateByCategory,
195
+ axisTargetIntervals: () => axisTargetIntervals,
194
196
  computeBoxStats: () => computeBoxStats,
197
+ computeHistogramBins: () => computeHistogramBins,
195
198
  computeLinearRegression: () => computeLinearRegression,
196
199
  computeRSquared: () => computeRSquared,
197
200
  computeStackedSeriesPlots: () => computeStackedSeriesPlots,
198
201
  fitPolynomial: () => fitPolynomial,
199
202
  groupRowsByCategory: () => groupRowsByCategory,
203
+ niceAxisStep: () => niceAxisStep,
204
+ niceValueAxisBounds: () => niceValueAxisBounds,
200
205
  resolveBlankDisplay: () => resolveBlankDisplay,
206
+ scottBinCount: () => scottBinCount,
201
207
  visibleRuns: () => visibleRuns
202
208
  });
203
209
 
@@ -420,6 +426,167 @@ function computeStackedSeriesPlots(seriesValues, catCount, percent) {
420
426
  });
421
427
  }
422
428
 
429
+ // src/chart/axis-nice.ts
430
+ var NICE_STEPS = [1, 2, 2.5, 5, 10];
431
+ var HEADROOM = 0.05;
432
+ var POINTS_PER_GRIDLINE = 20;
433
+ var MIN_TARGET_INTERVALS = 1;
434
+ var MAX_TARGET_INTERVALS = 10;
435
+ var PX_PER_POINT = 4 / 3;
436
+ var DEFAULT_TARGET_INTERVALS = 4;
437
+ var ZERO_ANCHOR_RATIO = 5 / 6;
438
+ function axisTargetIntervals(plotHeightPx) {
439
+ if (!Number.isFinite(plotHeightPx) || plotHeightPx <= 0) {
440
+ return DEFAULT_TARGET_INTERVALS;
441
+ }
442
+ const plotHeightPt = plotHeightPx / PX_PER_POINT;
443
+ const raw = Math.round(plotHeightPt / POINTS_PER_GRIDLINE);
444
+ return Math.min(MAX_TARGET_INTERVALS, Math.max(MIN_TARGET_INTERVALS, raw));
445
+ }
446
+ function niceAxisStep(value) {
447
+ if (!Number.isFinite(value) || value <= 0) {
448
+ return 1;
449
+ }
450
+ const exponent = Math.floor(Math.log10(value));
451
+ const power = 10 ** exponent;
452
+ const mantissa = value / power;
453
+ const step = NICE_STEPS.find((candidate) => mantissa <= candidate + 1e-12) ?? 10;
454
+ return step * power;
455
+ }
456
+ function snap(value, unit, direction) {
457
+ const scaled = value / unit;
458
+ const rounded = direction === "up" ? Math.ceil(scaled - 1e-9) : Math.floor(scaled + 1e-9);
459
+ return rounded * unit;
460
+ }
461
+ function niceValueAxisBounds(dataMin, dataMax, targetIntervals = DEFAULT_TARGET_INTERVALS, headroom = HEADROOM) {
462
+ if (!Number.isFinite(dataMin) || !Number.isFinite(dataMax)) {
463
+ return { min: 0, max: 1, majorUnit: 0.5 };
464
+ }
465
+ const low = Math.min(dataMin, dataMax);
466
+ const high = Math.max(dataMin, dataMax);
467
+ const intervals = Math.max(1, Math.round(targetIntervals));
468
+ if (low === high) {
469
+ if (low === 0) {
470
+ return { min: 0, max: 1, majorUnit: 1 / intervals };
471
+ }
472
+ const unit2 = niceAxisStep(Math.abs(low) / intervals);
473
+ return low > 0 ? { min: 0, max: snap(low, unit2, "up") || unit2, majorUnit: unit2 } : { min: snap(low, unit2, "down"), max: 0, majorUnit: unit2 };
474
+ }
475
+ const dataSpan = high - low;
476
+ const padding = dataSpan * headroom;
477
+ let paddedMin;
478
+ let paddedMax;
479
+ if (low >= 0) {
480
+ paddedMin = low < high * ZERO_ANCHOR_RATIO ? 0 : low - padding;
481
+ paddedMax = high + padding;
482
+ } else if (high <= 0) {
483
+ paddedMax = high > low * ZERO_ANCHOR_RATIO ? 0 : high + padding;
484
+ paddedMin = low - padding;
485
+ } else {
486
+ paddedMin = low - padding;
487
+ paddedMax = high + padding;
488
+ }
489
+ const unit = niceAxisStep((paddedMax - paddedMin) / intervals);
490
+ const min = paddedMin === 0 ? 0 : snap(paddedMin, unit, "down");
491
+ let max = paddedMax === 0 ? 0 : snap(paddedMax, unit, "up");
492
+ if (max <= min) {
493
+ max = min + unit;
494
+ }
495
+ return { min, max, majorUnit: unit };
496
+ }
497
+
498
+ // src/chart/histogram-binning.ts
499
+ function binLabel(lower, upper, closed, format) {
500
+ return closed === "r" ? `(${format(lower)}, ${format(upper)}]` : `[${format(lower)}, ${format(upper)})`;
501
+ }
502
+ function scottBinCount(values, min, max) {
503
+ if (values.length < 2 || max <= min) {
504
+ return 1;
505
+ }
506
+ const mean = values.reduce((sum, value) => sum + value, 0) / values.length;
507
+ const variance = values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / (values.length - 1);
508
+ const sd = Math.sqrt(variance);
509
+ if (!(sd > 0)) {
510
+ return 1;
511
+ }
512
+ const width = 3.49 * sd * values.length ** (-1 / 3);
513
+ return Math.max(1, Math.ceil((max - min) / width));
514
+ }
515
+ function computeHistogramBins(values, options, format = String) {
516
+ const closed = options.intervalClosed ?? "l";
517
+ const finite2 = values.map((value, sourceIndex) => ({ value, sourceIndex })).filter((item) => Number.isFinite(item.value));
518
+ if (finite2.length === 0) {
519
+ return [];
520
+ }
521
+ const underflow = typeof options.underflow === "number" ? options.underflow : void 0;
522
+ const overflow = typeof options.overflow === "number" ? options.overflow : void 0;
523
+ const under = underflow === void 0 ? [] : finite2.filter(
524
+ (item) => closed === "r" ? item.value <= underflow : item.value < underflow
525
+ );
526
+ const over = overflow === void 0 ? [] : finite2.filter((item) => closed === "l" ? item.value >= overflow : item.value > overflow);
527
+ const regular = finite2.filter((item) => !under.includes(item) && !over.includes(item));
528
+ const result = [];
529
+ if (underflow !== void 0) {
530
+ result.push({
531
+ value: under.length,
532
+ label: `${closed === "r" ? "\u2264" : "<"} ${format(underflow)}`,
533
+ sourceIndices: under.map((item) => item.sourceIndex)
534
+ });
535
+ }
536
+ if (regular.length > 0) {
537
+ const min = Math.min(...regular.map((item) => item.value));
538
+ const max = Math.max(...regular.map((item) => item.value));
539
+ const requestedSize = options.binSize && options.binSize > 0 ? options.binSize : void 0;
540
+ const requestedCount = options.binCount && options.binCount > 0 ? options.binCount : void 0;
541
+ const start = requestedSize ? Math.floor(min / requestedSize) * requestedSize : min;
542
+ const count = requestedSize ? Math.max(
543
+ closed === "l" ? Math.floor((max - start) / requestedSize) + 1 : Math.ceil((max - start) / requestedSize),
544
+ 1
545
+ ) : Math.max(
546
+ requestedCount ?? scottBinCount(
547
+ regular.map((item) => item.value),
548
+ min,
549
+ max
550
+ ),
551
+ 1
552
+ );
553
+ const width = requestedSize ?? Math.max((max - start) / count, 1);
554
+ const bins = Array.from({ length: count }, (_, index) => ({
555
+ value: 0,
556
+ label: binLabel(start + index * width, start + (index + 1) * width, closed, format),
557
+ sourceIndices: []
558
+ }));
559
+ for (const item of regular) {
560
+ const rawIndex = closed === "r" ? Math.ceil((item.value - start) / width) - 1 : Math.floor((item.value - start) / width);
561
+ const index = Math.max(0, Math.min(rawIndex, bins.length - 1));
562
+ const bin = bins[index];
563
+ if (!bin) continue;
564
+ bin.value += 1;
565
+ bin.sourceIndices.push(item.sourceIndex);
566
+ }
567
+ result.push(...bins);
568
+ }
569
+ if (overflow !== void 0) {
570
+ result.push({
571
+ value: over.length,
572
+ label: `${closed === "l" ? "\u2265" : ">"} ${format(overflow)}`,
573
+ sourceIndices: over.map((item) => item.sourceIndex)
574
+ });
575
+ }
576
+ return result;
577
+ }
578
+ function aggregateByCategory(values, rawCategories) {
579
+ const { uniqueCategories, rowIndexesByCategory } = groupRowsByCategory(rawCategories);
580
+ return uniqueCategories.map((label) => {
581
+ const rows = rowIndexesByCategory.get(label) ?? [];
582
+ return {
583
+ value: rows.reduce((sum, row) => sum + (values[row] ?? 0), 0),
584
+ label,
585
+ sourceIndices: rows
586
+ };
587
+ });
588
+ }
589
+
423
590
  // src/text/index.ts
424
591
  var text_exports = {};
425
592
  __export(text_exports, {
package/dist/index.mjs CHANGED
@@ -189,13 +189,19 @@ function linearToSrgb255(linear) {
189
189
  // src/chart/index.ts
190
190
  var chart_exports = {};
191
191
  __export(chart_exports, {
192
+ aggregateByCategory: () => aggregateByCategory,
193
+ axisTargetIntervals: () => axisTargetIntervals,
192
194
  computeBoxStats: () => computeBoxStats,
195
+ computeHistogramBins: () => computeHistogramBins,
193
196
  computeLinearRegression: () => computeLinearRegression,
194
197
  computeRSquared: () => computeRSquared,
195
198
  computeStackedSeriesPlots: () => computeStackedSeriesPlots,
196
199
  fitPolynomial: () => fitPolynomial,
197
200
  groupRowsByCategory: () => groupRowsByCategory,
201
+ niceAxisStep: () => niceAxisStep,
202
+ niceValueAxisBounds: () => niceValueAxisBounds,
198
203
  resolveBlankDisplay: () => resolveBlankDisplay,
204
+ scottBinCount: () => scottBinCount,
199
205
  visibleRuns: () => visibleRuns
200
206
  });
201
207
 
@@ -418,6 +424,167 @@ function computeStackedSeriesPlots(seriesValues, catCount, percent) {
418
424
  });
419
425
  }
420
426
 
427
+ // src/chart/axis-nice.ts
428
+ var NICE_STEPS = [1, 2, 2.5, 5, 10];
429
+ var HEADROOM = 0.05;
430
+ var POINTS_PER_GRIDLINE = 20;
431
+ var MIN_TARGET_INTERVALS = 1;
432
+ var MAX_TARGET_INTERVALS = 10;
433
+ var PX_PER_POINT = 4 / 3;
434
+ var DEFAULT_TARGET_INTERVALS = 4;
435
+ var ZERO_ANCHOR_RATIO = 5 / 6;
436
+ function axisTargetIntervals(plotHeightPx) {
437
+ if (!Number.isFinite(plotHeightPx) || plotHeightPx <= 0) {
438
+ return DEFAULT_TARGET_INTERVALS;
439
+ }
440
+ const plotHeightPt = plotHeightPx / PX_PER_POINT;
441
+ const raw = Math.round(plotHeightPt / POINTS_PER_GRIDLINE);
442
+ return Math.min(MAX_TARGET_INTERVALS, Math.max(MIN_TARGET_INTERVALS, raw));
443
+ }
444
+ function niceAxisStep(value) {
445
+ if (!Number.isFinite(value) || value <= 0) {
446
+ return 1;
447
+ }
448
+ const exponent = Math.floor(Math.log10(value));
449
+ const power = 10 ** exponent;
450
+ const mantissa = value / power;
451
+ const step = NICE_STEPS.find((candidate) => mantissa <= candidate + 1e-12) ?? 10;
452
+ return step * power;
453
+ }
454
+ function snap(value, unit, direction) {
455
+ const scaled = value / unit;
456
+ const rounded = direction === "up" ? Math.ceil(scaled - 1e-9) : Math.floor(scaled + 1e-9);
457
+ return rounded * unit;
458
+ }
459
+ function niceValueAxisBounds(dataMin, dataMax, targetIntervals = DEFAULT_TARGET_INTERVALS, headroom = HEADROOM) {
460
+ if (!Number.isFinite(dataMin) || !Number.isFinite(dataMax)) {
461
+ return { min: 0, max: 1, majorUnit: 0.5 };
462
+ }
463
+ const low = Math.min(dataMin, dataMax);
464
+ const high = Math.max(dataMin, dataMax);
465
+ const intervals = Math.max(1, Math.round(targetIntervals));
466
+ if (low === high) {
467
+ if (low === 0) {
468
+ return { min: 0, max: 1, majorUnit: 1 / intervals };
469
+ }
470
+ const unit2 = niceAxisStep(Math.abs(low) / intervals);
471
+ return low > 0 ? { min: 0, max: snap(low, unit2, "up") || unit2, majorUnit: unit2 } : { min: snap(low, unit2, "down"), max: 0, majorUnit: unit2 };
472
+ }
473
+ const dataSpan = high - low;
474
+ const padding = dataSpan * headroom;
475
+ let paddedMin;
476
+ let paddedMax;
477
+ if (low >= 0) {
478
+ paddedMin = low < high * ZERO_ANCHOR_RATIO ? 0 : low - padding;
479
+ paddedMax = high + padding;
480
+ } else if (high <= 0) {
481
+ paddedMax = high > low * ZERO_ANCHOR_RATIO ? 0 : high + padding;
482
+ paddedMin = low - padding;
483
+ } else {
484
+ paddedMin = low - padding;
485
+ paddedMax = high + padding;
486
+ }
487
+ const unit = niceAxisStep((paddedMax - paddedMin) / intervals);
488
+ const min = paddedMin === 0 ? 0 : snap(paddedMin, unit, "down");
489
+ let max = paddedMax === 0 ? 0 : snap(paddedMax, unit, "up");
490
+ if (max <= min) {
491
+ max = min + unit;
492
+ }
493
+ return { min, max, majorUnit: unit };
494
+ }
495
+
496
+ // src/chart/histogram-binning.ts
497
+ function binLabel(lower, upper, closed, format) {
498
+ return closed === "r" ? `(${format(lower)}, ${format(upper)}]` : `[${format(lower)}, ${format(upper)})`;
499
+ }
500
+ function scottBinCount(values, min, max) {
501
+ if (values.length < 2 || max <= min) {
502
+ return 1;
503
+ }
504
+ const mean = values.reduce((sum, value) => sum + value, 0) / values.length;
505
+ const variance = values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / (values.length - 1);
506
+ const sd = Math.sqrt(variance);
507
+ if (!(sd > 0)) {
508
+ return 1;
509
+ }
510
+ const width = 3.49 * sd * values.length ** (-1 / 3);
511
+ return Math.max(1, Math.ceil((max - min) / width));
512
+ }
513
+ function computeHistogramBins(values, options, format = String) {
514
+ const closed = options.intervalClosed ?? "l";
515
+ const finite2 = values.map((value, sourceIndex) => ({ value, sourceIndex })).filter((item) => Number.isFinite(item.value));
516
+ if (finite2.length === 0) {
517
+ return [];
518
+ }
519
+ const underflow = typeof options.underflow === "number" ? options.underflow : void 0;
520
+ const overflow = typeof options.overflow === "number" ? options.overflow : void 0;
521
+ const under = underflow === void 0 ? [] : finite2.filter(
522
+ (item) => closed === "r" ? item.value <= underflow : item.value < underflow
523
+ );
524
+ const over = overflow === void 0 ? [] : finite2.filter((item) => closed === "l" ? item.value >= overflow : item.value > overflow);
525
+ const regular = finite2.filter((item) => !under.includes(item) && !over.includes(item));
526
+ const result = [];
527
+ if (underflow !== void 0) {
528
+ result.push({
529
+ value: under.length,
530
+ label: `${closed === "r" ? "\u2264" : "<"} ${format(underflow)}`,
531
+ sourceIndices: under.map((item) => item.sourceIndex)
532
+ });
533
+ }
534
+ if (regular.length > 0) {
535
+ const min = Math.min(...regular.map((item) => item.value));
536
+ const max = Math.max(...regular.map((item) => item.value));
537
+ const requestedSize = options.binSize && options.binSize > 0 ? options.binSize : void 0;
538
+ const requestedCount = options.binCount && options.binCount > 0 ? options.binCount : void 0;
539
+ const start = requestedSize ? Math.floor(min / requestedSize) * requestedSize : min;
540
+ const count = requestedSize ? Math.max(
541
+ closed === "l" ? Math.floor((max - start) / requestedSize) + 1 : Math.ceil((max - start) / requestedSize),
542
+ 1
543
+ ) : Math.max(
544
+ requestedCount ?? scottBinCount(
545
+ regular.map((item) => item.value),
546
+ min,
547
+ max
548
+ ),
549
+ 1
550
+ );
551
+ const width = requestedSize ?? Math.max((max - start) / count, 1);
552
+ const bins = Array.from({ length: count }, (_, index) => ({
553
+ value: 0,
554
+ label: binLabel(start + index * width, start + (index + 1) * width, closed, format),
555
+ sourceIndices: []
556
+ }));
557
+ for (const item of regular) {
558
+ const rawIndex = closed === "r" ? Math.ceil((item.value - start) / width) - 1 : Math.floor((item.value - start) / width);
559
+ const index = Math.max(0, Math.min(rawIndex, bins.length - 1));
560
+ const bin = bins[index];
561
+ if (!bin) continue;
562
+ bin.value += 1;
563
+ bin.sourceIndices.push(item.sourceIndex);
564
+ }
565
+ result.push(...bins);
566
+ }
567
+ if (overflow !== void 0) {
568
+ result.push({
569
+ value: over.length,
570
+ label: `${closed === "l" ? "\u2265" : ">"} ${format(overflow)}`,
571
+ sourceIndices: over.map((item) => item.sourceIndex)
572
+ });
573
+ }
574
+ return result;
575
+ }
576
+ function aggregateByCategory(values, rawCategories) {
577
+ const { uniqueCategories, rowIndexesByCategory } = groupRowsByCategory(rawCategories);
578
+ return uniqueCategories.map((label) => {
579
+ const rows = rowIndexesByCategory.get(label) ?? [];
580
+ return {
581
+ value: rows.reduce((sum, row) => sum + (values[row] ?? 0), 0),
582
+ label,
583
+ sourceIndices: rows
584
+ };
585
+ });
586
+ }
587
+
421
588
  // src/text/index.ts
422
589
  var text_exports = {};
423
590
  __export(text_exports, {