cronli5 0.2.0 → 0.2.1
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 +25 -0
- package/README.md +4 -4
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +123 -104
- package/dist/cronli5.js +123 -104
- package/dist/lang/de.cjs +65 -65
- package/dist/lang/de.js +65 -65
- package/dist/lang/en.cjs +122 -101
- package/dist/lang/en.js +122 -101
- package/dist/lang/es.cjs +71 -72
- package/dist/lang/es.js +71 -72
- package/dist/lang/fi.cjs +71 -66
- package/dist/lang/fi.js +71 -66
- package/dist/lang/zh.cjs +36 -36
- package/dist/lang/zh.js +36 -36
- package/package.json +1 -1
- package/src/core/analyze.ts +14 -13
- package/src/core/ir.ts +8 -8
- package/src/core/shapes.ts +8 -1
- package/src/core/util.ts +86 -3
- package/src/core/validate.ts +1 -1
- package/src/cronli5.ts +3 -3
- package/src/lang/de/index.ts +30 -99
- package/src/lang/en/index.ts +163 -188
- package/src/lang/es/index.ts +36 -120
- package/src/lang/fi/index.ts +33 -104
- package/src/lang/zh/index.ts +23 -48
- package/src/types.ts +2 -2
- package/types/core/analyze.d.ts +2 -2
- package/types/core/ir.d.ts +7 -7
- package/types/core/shapes.d.ts +2 -1
- package/types/core/util.d.ts +17 -2
- package/types/types.d.ts +1 -1
package/dist/lang/de.cjs
CHANGED
|
@@ -85,6 +85,43 @@ function orderWeekdaysForDisplay(segments) {
|
|
|
85
85
|
function toFieldNumber(token, numberMap) {
|
|
86
86
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
87
87
|
}
|
|
88
|
+
function segmentsOf(ir, field) {
|
|
89
|
+
return ir.analyses.segments[field] ?? [];
|
|
90
|
+
}
|
|
91
|
+
function stepSegment(ir, field) {
|
|
92
|
+
return segmentsOf(ir, field)[0];
|
|
93
|
+
}
|
|
94
|
+
function singleValues(segments) {
|
|
95
|
+
const values = [];
|
|
96
|
+
for (const segment of segments) {
|
|
97
|
+
if (segment.kind !== "single") {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
values.push(+segment.value);
|
|
101
|
+
}
|
|
102
|
+
return values;
|
|
103
|
+
}
|
|
104
|
+
function offsetCleanStride(stride) {
|
|
105
|
+
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
106
|
+
}
|
|
107
|
+
function hourListStride(values) {
|
|
108
|
+
if (values.length < 2) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
const interval = values[1] - values[0];
|
|
112
|
+
if (interval < 2) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
for (let i = 2; i < values.length; i += 1) {
|
|
116
|
+
if (values[i] - values[i - 1] !== interval) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (values[0] !== 0 && values.length < 5) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
return { interval, last: values[values.length - 1], start: values[0] };
|
|
124
|
+
}
|
|
88
125
|
|
|
89
126
|
// src/lang/de/dialects.ts
|
|
90
127
|
var months = [
|
|
@@ -145,9 +182,6 @@ function everyN(interval, unit) {
|
|
|
145
182
|
function withAnchor(clause, anchor) {
|
|
146
183
|
return anchor ? clause + " " + anchor : clause;
|
|
147
184
|
}
|
|
148
|
-
function stepSegment(segments) {
|
|
149
|
-
return segments[0];
|
|
150
|
-
}
|
|
151
185
|
function cleanStep(segment, cycle) {
|
|
152
186
|
return (segment.startToken === "*" || +segment.startToken === 0) && cycle % segment.interval === 0;
|
|
153
187
|
}
|
|
@@ -182,16 +216,6 @@ function stepClause(segment, unit, anchor) {
|
|
|
182
216
|
anchor
|
|
183
217
|
});
|
|
184
218
|
}
|
|
185
|
-
function singleValues(segments) {
|
|
186
|
-
const values = [];
|
|
187
|
-
for (const segment of segments) {
|
|
188
|
-
if (segment.kind !== "single") {
|
|
189
|
-
return null;
|
|
190
|
-
}
|
|
191
|
-
values.push(+segment.value);
|
|
192
|
-
}
|
|
193
|
-
return values;
|
|
194
|
-
}
|
|
195
219
|
function strideFromSegments(segments, unit, anchor) {
|
|
196
220
|
const values = singleValues(segments);
|
|
197
221
|
const step = values && arithmeticStep(values);
|
|
@@ -206,9 +230,6 @@ var weekdayNames = [
|
|
|
206
230
|
"freitags",
|
|
207
231
|
"samstags"
|
|
208
232
|
];
|
|
209
|
-
function fieldSegments(ir, field) {
|
|
210
|
-
return ir.analyses.segments[field];
|
|
211
|
-
}
|
|
212
233
|
function flattenSteps(segments) {
|
|
213
234
|
return segments.flatMap(function flat(segment) {
|
|
214
235
|
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
@@ -232,7 +253,7 @@ function weekdayRange(bounds) {
|
|
|
232
253
|
return weekdayName(bounds[0]) + " bis " + weekdayName(bounds[1]);
|
|
233
254
|
}
|
|
234
255
|
function weekdayQualifier(ir) {
|
|
235
|
-
const segments = orderWeekdaysForDisplay(
|
|
256
|
+
const segments = orderWeekdaysForDisplay(segmentsOf(ir, "weekday"));
|
|
236
257
|
if (segments.length === 1 && segments[0].kind === "range") {
|
|
237
258
|
return weekdayRange(segments[0].bounds);
|
|
238
259
|
}
|
|
@@ -302,12 +323,12 @@ function monthRange(bounds, months2) {
|
|
|
302
323
|
return "von " + monthName(bounds[0], months2) + " bis " + monthName(bounds[1], months2);
|
|
303
324
|
}
|
|
304
325
|
function monthNamesList(ir, months2) {
|
|
305
|
-
return joinList(flattenSteps(
|
|
326
|
+
return joinList(flattenSteps(segmentsOf(ir, "month")).map(function name(segment) {
|
|
306
327
|
return segment.kind === "range" ? monthRange(segment.bounds, months2) : monthName(segment.value, months2);
|
|
307
328
|
}));
|
|
308
329
|
}
|
|
309
330
|
function monthClause(ir, months2) {
|
|
310
|
-
const segments = flattenSteps(
|
|
331
|
+
const segments = flattenSteps(segmentsOf(ir, "month"));
|
|
311
332
|
if (segments.length === 1 && segments[0].kind === "range") {
|
|
312
333
|
return monthRange(segments[0].bounds, months2);
|
|
313
334
|
}
|
|
@@ -323,7 +344,7 @@ function dateRange(bounds) {
|
|
|
323
344
|
return "vom " + ordinalDay(bounds[0]) + " bis zum " + ordinalDay(bounds[1]);
|
|
324
345
|
}
|
|
325
346
|
function dateClauseBare(ir) {
|
|
326
|
-
const segments = flattenSteps(
|
|
347
|
+
const segments = flattenSteps(segmentsOf(ir, "date"));
|
|
327
348
|
if (segments.length === 1 && segments[0].kind === "range") {
|
|
328
349
|
return dateRange(segments[0].bounds);
|
|
329
350
|
}
|
|
@@ -341,7 +362,7 @@ function datePhrase(ir, months2) {
|
|
|
341
362
|
if (ir.pattern.month === "*") {
|
|
342
363
|
return clause;
|
|
343
364
|
}
|
|
344
|
-
const monthRanged = flattenSteps(
|
|
365
|
+
const monthRanged = flattenSteps(segmentsOf(ir, "month")).some((segment) => segment.kind === "range");
|
|
345
366
|
return monthRanged ? clause + ", " + monthClause(ir, months2) : clause + " " + monthNamesList(ir, months2);
|
|
346
367
|
}
|
|
347
368
|
function bareTime(time, sep) {
|
|
@@ -362,7 +383,7 @@ function hourWindow(from, to, last, sep) {
|
|
|
362
383
|
return "von " + bareTime({ hour: from, minute: 0 }, sep) + " bis " + bareTime({ hour: to, minute: last }, sep) + " Uhr";
|
|
363
384
|
}
|
|
364
385
|
function fieldValues(ir, field) {
|
|
365
|
-
return flattenSteps(
|
|
386
|
+
return flattenSteps(segmentsOf(ir, field)).map(function value(segment) {
|
|
366
387
|
return segment.kind === "range" ? segment.bounds[0] + " bis " + segment.bounds[1] : String(segment.value);
|
|
367
388
|
});
|
|
368
389
|
}
|
|
@@ -384,7 +405,7 @@ function secondsClause(ir, anchor) {
|
|
|
384
405
|
}
|
|
385
406
|
const segments = ir.analyses.segments.second;
|
|
386
407
|
if (ir.shapes.second === "step") {
|
|
387
|
-
return stepClause(stepSegment(
|
|
408
|
+
return stepClause(stepSegment(ir, "second"), UNITS.second, anchor);
|
|
388
409
|
}
|
|
389
410
|
return strideFromSegments(segments, UNITS.second, anchor) ?? withAnchor(countedPhrase(ir, "second", "Sekunde", "Sekunden"), anchor);
|
|
390
411
|
}
|
|
@@ -395,7 +416,7 @@ function atHours(hours) {
|
|
|
395
416
|
return "um " + joinList(hours.map(String)) + " Uhr";
|
|
396
417
|
}
|
|
397
418
|
function hourFires(ir) {
|
|
398
|
-
return flattenSteps(
|
|
419
|
+
return flattenSteps(segmentsOf(ir, "hour")).map(function fire(segment) {
|
|
399
420
|
return segment.kind === "range" ? +segment.bounds[0] : +segment.value;
|
|
400
421
|
});
|
|
401
422
|
}
|
|
@@ -406,7 +427,7 @@ function partTime(hour, minute, second, sep) {
|
|
|
406
427
|
return minute === 0 ? String(hour) : hour + sep + pad(minute);
|
|
407
428
|
}
|
|
408
429
|
function hourSegmentParts(ir, minute, second, sep) {
|
|
409
|
-
return
|
|
430
|
+
return segmentsOf(ir, "hour").map(function part(segment) {
|
|
410
431
|
if (segment.kind === "range") {
|
|
411
432
|
return "von " + partTime(+segment.bounds[0], minute, second, sep) + " bis " + partTime(+segment.bounds[1], minute, second, sep) + " Uhr";
|
|
412
433
|
}
|
|
@@ -424,7 +445,7 @@ function duringWindows(ir, times, sep) {
|
|
|
424
445
|
return hourWindow(hour, hour, 59, sep);
|
|
425
446
|
});
|
|
426
447
|
}
|
|
427
|
-
return
|
|
448
|
+
return segmentsOf(ir, "hour").flatMap(function part(segment) {
|
|
428
449
|
if (segment.kind === "range") {
|
|
429
450
|
return [hourWindow(+segment.bounds[0], +segment.bounds[1], 59, sep)];
|
|
430
451
|
}
|
|
@@ -457,7 +478,7 @@ function renderSeconds(ir) {
|
|
|
457
478
|
}
|
|
458
479
|
function minutePastClause(ir) {
|
|
459
480
|
return strideFromSegments(
|
|
460
|
-
|
|
481
|
+
segmentsOf(ir, "minute"),
|
|
461
482
|
UNITS.minute,
|
|
462
483
|
"jeder Stunde"
|
|
463
484
|
) ?? countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde";
|
|
@@ -491,7 +512,7 @@ function isEveryOtherMinuteSeconds(ir, plan) {
|
|
|
491
512
|
if (plan.rest.kind !== "minuteFrequency" || ir.shapes.second !== "wildcard" || ir.shapes.hour !== "wildcard") {
|
|
492
513
|
return false;
|
|
493
514
|
}
|
|
494
|
-
const minuteStep = stepSegment(ir
|
|
515
|
+
const minuteStep = stepSegment(ir, "minute");
|
|
495
516
|
return minuteStep.startToken === "*" && minuteStep.interval === 2;
|
|
496
517
|
}
|
|
497
518
|
function renderComposeSeconds(ir, plan, opts) {
|
|
@@ -527,7 +548,7 @@ function renderMinutesAcrossHours(ir, plan, opts) {
|
|
|
527
548
|
if (plan.form === "wildcard") {
|
|
528
549
|
return cadence ? "jede Minute, " + cadence : "jede Minute " + duringHours(ir, plan.times, sep);
|
|
529
550
|
}
|
|
530
|
-
const minuteLead = strideFromSegments(
|
|
551
|
+
const minuteLead = strideFromSegments(segmentsOf(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten");
|
|
531
552
|
if (cadence !== null) {
|
|
532
553
|
return minuteLead + ", " + cadence;
|
|
533
554
|
}
|
|
@@ -537,11 +558,11 @@ function renderMinutesAcrossHours(ir, plan, opts) {
|
|
|
537
558
|
function renderMinuteSpanAcrossHourStep(ir, plan) {
|
|
538
559
|
const cadence = unevenHourCadence(ir);
|
|
539
560
|
if (plan.form === "wildcard") {
|
|
540
|
-
return "jede Minute " + everyNthHour(stepSegment(ir
|
|
561
|
+
return "jede Minute " + everyNthHour(stepSegment(ir, "hour"));
|
|
541
562
|
}
|
|
542
|
-
const segment = stepSegment(ir
|
|
563
|
+
const segment = stepSegment(ir, "hour");
|
|
543
564
|
const hours = cadence ?? (confinedHourStride(segment) ? everyNthHour(segment) : atHours(segment.fires));
|
|
544
|
-
return (strideFromSegments(
|
|
565
|
+
return (strideFromSegments(segmentsOf(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
|
|
545
566
|
}
|
|
546
567
|
function renderCompactClockTimes(ir, plan, opts) {
|
|
547
568
|
const sep = opts.style.sep;
|
|
@@ -550,15 +571,15 @@ function renderCompactClockTimes(ir, plan, opts) {
|
|
|
550
571
|
if (cadence !== null) {
|
|
551
572
|
return cadence;
|
|
552
573
|
}
|
|
553
|
-
const hourly =
|
|
574
|
+
const hourly = segmentsOf(ir, "hour").some((segment) => segment.kind === "range");
|
|
554
575
|
return (hourly ? "st\xFCndlich " : "t\xE4glich ") + joinList(hourSegmentParts(ir, plan.minute, ir.analyses.clockSecond, sep));
|
|
555
576
|
}
|
|
556
|
-
const hours = unevenHourCadence(ir) ?? (
|
|
577
|
+
const hours = unevenHourCadence(ir) ?? (segmentsOf(ir, "hour").some((segment) => segment.kind === "range") ? joinList(hourSegmentParts(ir, 0, 0, sep)) : atHours(hourFires(ir)));
|
|
557
578
|
const lead = ir.analyses.clockSecond ? countedPhrase(ir, "second", "Sekunde", "Sekunden") + ", " : "";
|
|
558
|
-
return lead + (strideFromSegments(
|
|
579
|
+
return lead + (strideFromSegments(segmentsOf(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
|
|
559
580
|
}
|
|
560
581
|
function renderMinuteFrequency(ir, plan, opts) {
|
|
561
|
-
const segment = stepSegment(ir
|
|
582
|
+
const segment = stepSegment(ir, "minute");
|
|
562
583
|
const sep = opts.style.sep;
|
|
563
584
|
const clean = cleanStep(segment, 60);
|
|
564
585
|
if (plan.hours.kind === "window") {
|
|
@@ -582,7 +603,7 @@ function renderMinuteFrequency(ir, plan, opts) {
|
|
|
582
603
|
return cadence ? base + ", " + cadence : base + " " + duringHours(ir, plan.hours.times, sep);
|
|
583
604
|
}
|
|
584
605
|
if (plan.hours.kind === "step") {
|
|
585
|
-
return base + " " + everyNthHour(stepSegment(ir
|
|
606
|
+
return base + " " + everyNthHour(stepSegment(ir, "hour"));
|
|
586
607
|
}
|
|
587
608
|
return base;
|
|
588
609
|
}
|
|
@@ -591,7 +612,7 @@ function hourStepPhrase(ir) {
|
|
|
591
612
|
if (cadence !== null) {
|
|
592
613
|
return cadence;
|
|
593
614
|
}
|
|
594
|
-
const segment = stepSegment(ir
|
|
615
|
+
const segment = stepSegment(ir, "hour");
|
|
595
616
|
if (cleanStep(segment, 24)) {
|
|
596
617
|
return everyN(segment.interval, UNITS.hour);
|
|
597
618
|
}
|
|
@@ -617,29 +638,8 @@ function hourStrideCadence(stride) {
|
|
|
617
638
|
}
|
|
618
639
|
return cadence + " von " + start + " bis " + last + " Uhr";
|
|
619
640
|
}
|
|
620
|
-
function hourListStride(values) {
|
|
621
|
-
if (values.length < 2) {
|
|
622
|
-
return null;
|
|
623
|
-
}
|
|
624
|
-
const interval = values[1] - values[0];
|
|
625
|
-
if (interval < 2) {
|
|
626
|
-
return null;
|
|
627
|
-
}
|
|
628
|
-
for (let i = 2; i < values.length; i += 1) {
|
|
629
|
-
if (values[i] - values[i - 1] !== interval) {
|
|
630
|
-
return null;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
if (values[0] !== 0 && values.length < 5) {
|
|
634
|
-
return null;
|
|
635
|
-
}
|
|
636
|
-
return { interval, last: values[values.length - 1], start: values[0] };
|
|
637
|
-
}
|
|
638
|
-
function offsetCleanStride(stride) {
|
|
639
|
-
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
640
|
-
}
|
|
641
641
|
function hourStride(ir) {
|
|
642
|
-
const segments =
|
|
642
|
+
const segments = segmentsOf(ir, "hour");
|
|
643
643
|
if (!segments) {
|
|
644
644
|
return null;
|
|
645
645
|
}
|
|
@@ -686,8 +686,8 @@ function hourCadence(ir, minute) {
|
|
|
686
686
|
if (ir.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
|
|
687
687
|
return null;
|
|
688
688
|
}
|
|
689
|
-
const segment =
|
|
690
|
-
const confined = minute === 0 && subMinuteSecond(ir) &&
|
|
689
|
+
const segment = segmentsOf(ir, "hour")[0];
|
|
690
|
+
const confined = minute === 0 && subMinuteSecond(ir) && segmentsOf(ir, "hour").length === 1 && segment.kind === "step" && confinedHourStride(segment);
|
|
691
691
|
if (confined) {
|
|
692
692
|
return withAnchor(secondsClause(ir, minuteAnchor(ir)), "f\xFCr eine Minute") + " " + everyNthHour(segment);
|
|
693
693
|
}
|
|
@@ -704,7 +704,7 @@ function hourCadenceApplies(ir) {
|
|
|
704
704
|
return hourCadence(ir, minute) !== null || hourRangeCadence(ir, minute) !== null;
|
|
705
705
|
}
|
|
706
706
|
function hasHourWindow(ir) {
|
|
707
|
-
const segments =
|
|
707
|
+
const segments = segmentsOf(ir, "hour");
|
|
708
708
|
return !!segments && segments.some(function range(segment) {
|
|
709
709
|
return segment.kind === "range";
|
|
710
710
|
});
|
|
@@ -728,7 +728,7 @@ function renderHourRange(ir, plan, opts) {
|
|
|
728
728
|
return "st\xFCndlich " + window;
|
|
729
729
|
}
|
|
730
730
|
return (strideFromSegments(
|
|
731
|
-
|
|
731
|
+
segmentsOf(ir, "minute"),
|
|
732
732
|
UNITS.minute,
|
|
733
733
|
"jeder Stunde"
|
|
734
734
|
) ?? countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde") + ", " + window;
|
|
@@ -799,7 +799,7 @@ function needsDailyFrame(ir) {
|
|
|
799
799
|
if (ir.plan.kind !== "hourStep") {
|
|
800
800
|
return false;
|
|
801
801
|
}
|
|
802
|
-
const segment = stepSegment(ir
|
|
802
|
+
const segment = stepSegment(ir, "hour");
|
|
803
803
|
return !cleanStep(segment, 24) && !openOffsetCleanStride(ir, segment);
|
|
804
804
|
}
|
|
805
805
|
function render(ir, plan, opts) {
|
package/dist/lang/de.js
CHANGED
|
@@ -59,6 +59,43 @@ function orderWeekdaysForDisplay(segments) {
|
|
|
59
59
|
function toFieldNumber(token, numberMap) {
|
|
60
60
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
61
61
|
}
|
|
62
|
+
function segmentsOf(ir, field) {
|
|
63
|
+
return ir.analyses.segments[field] ?? [];
|
|
64
|
+
}
|
|
65
|
+
function stepSegment(ir, field) {
|
|
66
|
+
return segmentsOf(ir, field)[0];
|
|
67
|
+
}
|
|
68
|
+
function singleValues(segments) {
|
|
69
|
+
const values = [];
|
|
70
|
+
for (const segment of segments) {
|
|
71
|
+
if (segment.kind !== "single") {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
values.push(+segment.value);
|
|
75
|
+
}
|
|
76
|
+
return values;
|
|
77
|
+
}
|
|
78
|
+
function offsetCleanStride(stride) {
|
|
79
|
+
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
80
|
+
}
|
|
81
|
+
function hourListStride(values) {
|
|
82
|
+
if (values.length < 2) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const interval = values[1] - values[0];
|
|
86
|
+
if (interval < 2) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
for (let i = 2; i < values.length; i += 1) {
|
|
90
|
+
if (values[i] - values[i - 1] !== interval) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (values[0] !== 0 && values.length < 5) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return { interval, last: values[values.length - 1], start: values[0] };
|
|
98
|
+
}
|
|
62
99
|
|
|
63
100
|
// src/lang/de/dialects.ts
|
|
64
101
|
var months = [
|
|
@@ -119,9 +156,6 @@ function everyN(interval, unit) {
|
|
|
119
156
|
function withAnchor(clause, anchor) {
|
|
120
157
|
return anchor ? clause + " " + anchor : clause;
|
|
121
158
|
}
|
|
122
|
-
function stepSegment(segments) {
|
|
123
|
-
return segments[0];
|
|
124
|
-
}
|
|
125
159
|
function cleanStep(segment, cycle) {
|
|
126
160
|
return (segment.startToken === "*" || +segment.startToken === 0) && cycle % segment.interval === 0;
|
|
127
161
|
}
|
|
@@ -156,16 +190,6 @@ function stepClause(segment, unit, anchor) {
|
|
|
156
190
|
anchor
|
|
157
191
|
});
|
|
158
192
|
}
|
|
159
|
-
function singleValues(segments) {
|
|
160
|
-
const values = [];
|
|
161
|
-
for (const segment of segments) {
|
|
162
|
-
if (segment.kind !== "single") {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
values.push(+segment.value);
|
|
166
|
-
}
|
|
167
|
-
return values;
|
|
168
|
-
}
|
|
169
193
|
function strideFromSegments(segments, unit, anchor) {
|
|
170
194
|
const values = singleValues(segments);
|
|
171
195
|
const step = values && arithmeticStep(values);
|
|
@@ -180,9 +204,6 @@ var weekdayNames = [
|
|
|
180
204
|
"freitags",
|
|
181
205
|
"samstags"
|
|
182
206
|
];
|
|
183
|
-
function fieldSegments(ir, field) {
|
|
184
|
-
return ir.analyses.segments[field];
|
|
185
|
-
}
|
|
186
207
|
function flattenSteps(segments) {
|
|
187
208
|
return segments.flatMap(function flat(segment) {
|
|
188
209
|
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
@@ -206,7 +227,7 @@ function weekdayRange(bounds) {
|
|
|
206
227
|
return weekdayName(bounds[0]) + " bis " + weekdayName(bounds[1]);
|
|
207
228
|
}
|
|
208
229
|
function weekdayQualifier(ir) {
|
|
209
|
-
const segments = orderWeekdaysForDisplay(
|
|
230
|
+
const segments = orderWeekdaysForDisplay(segmentsOf(ir, "weekday"));
|
|
210
231
|
if (segments.length === 1 && segments[0].kind === "range") {
|
|
211
232
|
return weekdayRange(segments[0].bounds);
|
|
212
233
|
}
|
|
@@ -276,12 +297,12 @@ function monthRange(bounds, months2) {
|
|
|
276
297
|
return "von " + monthName(bounds[0], months2) + " bis " + monthName(bounds[1], months2);
|
|
277
298
|
}
|
|
278
299
|
function monthNamesList(ir, months2) {
|
|
279
|
-
return joinList(flattenSteps(
|
|
300
|
+
return joinList(flattenSteps(segmentsOf(ir, "month")).map(function name(segment) {
|
|
280
301
|
return segment.kind === "range" ? monthRange(segment.bounds, months2) : monthName(segment.value, months2);
|
|
281
302
|
}));
|
|
282
303
|
}
|
|
283
304
|
function monthClause(ir, months2) {
|
|
284
|
-
const segments = flattenSteps(
|
|
305
|
+
const segments = flattenSteps(segmentsOf(ir, "month"));
|
|
285
306
|
if (segments.length === 1 && segments[0].kind === "range") {
|
|
286
307
|
return monthRange(segments[0].bounds, months2);
|
|
287
308
|
}
|
|
@@ -297,7 +318,7 @@ function dateRange(bounds) {
|
|
|
297
318
|
return "vom " + ordinalDay(bounds[0]) + " bis zum " + ordinalDay(bounds[1]);
|
|
298
319
|
}
|
|
299
320
|
function dateClauseBare(ir) {
|
|
300
|
-
const segments = flattenSteps(
|
|
321
|
+
const segments = flattenSteps(segmentsOf(ir, "date"));
|
|
301
322
|
if (segments.length === 1 && segments[0].kind === "range") {
|
|
302
323
|
return dateRange(segments[0].bounds);
|
|
303
324
|
}
|
|
@@ -315,7 +336,7 @@ function datePhrase(ir, months2) {
|
|
|
315
336
|
if (ir.pattern.month === "*") {
|
|
316
337
|
return clause;
|
|
317
338
|
}
|
|
318
|
-
const monthRanged = flattenSteps(
|
|
339
|
+
const monthRanged = flattenSteps(segmentsOf(ir, "month")).some((segment) => segment.kind === "range");
|
|
319
340
|
return monthRanged ? clause + ", " + monthClause(ir, months2) : clause + " " + monthNamesList(ir, months2);
|
|
320
341
|
}
|
|
321
342
|
function bareTime(time, sep) {
|
|
@@ -336,7 +357,7 @@ function hourWindow(from, to, last, sep) {
|
|
|
336
357
|
return "von " + bareTime({ hour: from, minute: 0 }, sep) + " bis " + bareTime({ hour: to, minute: last }, sep) + " Uhr";
|
|
337
358
|
}
|
|
338
359
|
function fieldValues(ir, field) {
|
|
339
|
-
return flattenSteps(
|
|
360
|
+
return flattenSteps(segmentsOf(ir, field)).map(function value(segment) {
|
|
340
361
|
return segment.kind === "range" ? segment.bounds[0] + " bis " + segment.bounds[1] : String(segment.value);
|
|
341
362
|
});
|
|
342
363
|
}
|
|
@@ -358,7 +379,7 @@ function secondsClause(ir, anchor) {
|
|
|
358
379
|
}
|
|
359
380
|
const segments = ir.analyses.segments.second;
|
|
360
381
|
if (ir.shapes.second === "step") {
|
|
361
|
-
return stepClause(stepSegment(
|
|
382
|
+
return stepClause(stepSegment(ir, "second"), UNITS.second, anchor);
|
|
362
383
|
}
|
|
363
384
|
return strideFromSegments(segments, UNITS.second, anchor) ?? withAnchor(countedPhrase(ir, "second", "Sekunde", "Sekunden"), anchor);
|
|
364
385
|
}
|
|
@@ -369,7 +390,7 @@ function atHours(hours) {
|
|
|
369
390
|
return "um " + joinList(hours.map(String)) + " Uhr";
|
|
370
391
|
}
|
|
371
392
|
function hourFires(ir) {
|
|
372
|
-
return flattenSteps(
|
|
393
|
+
return flattenSteps(segmentsOf(ir, "hour")).map(function fire(segment) {
|
|
373
394
|
return segment.kind === "range" ? +segment.bounds[0] : +segment.value;
|
|
374
395
|
});
|
|
375
396
|
}
|
|
@@ -380,7 +401,7 @@ function partTime(hour, minute, second, sep) {
|
|
|
380
401
|
return minute === 0 ? String(hour) : hour + sep + pad(minute);
|
|
381
402
|
}
|
|
382
403
|
function hourSegmentParts(ir, minute, second, sep) {
|
|
383
|
-
return
|
|
404
|
+
return segmentsOf(ir, "hour").map(function part(segment) {
|
|
384
405
|
if (segment.kind === "range") {
|
|
385
406
|
return "von " + partTime(+segment.bounds[0], minute, second, sep) + " bis " + partTime(+segment.bounds[1], minute, second, sep) + " Uhr";
|
|
386
407
|
}
|
|
@@ -398,7 +419,7 @@ function duringWindows(ir, times, sep) {
|
|
|
398
419
|
return hourWindow(hour, hour, 59, sep);
|
|
399
420
|
});
|
|
400
421
|
}
|
|
401
|
-
return
|
|
422
|
+
return segmentsOf(ir, "hour").flatMap(function part(segment) {
|
|
402
423
|
if (segment.kind === "range") {
|
|
403
424
|
return [hourWindow(+segment.bounds[0], +segment.bounds[1], 59, sep)];
|
|
404
425
|
}
|
|
@@ -431,7 +452,7 @@ function renderSeconds(ir) {
|
|
|
431
452
|
}
|
|
432
453
|
function minutePastClause(ir) {
|
|
433
454
|
return strideFromSegments(
|
|
434
|
-
|
|
455
|
+
segmentsOf(ir, "minute"),
|
|
435
456
|
UNITS.minute,
|
|
436
457
|
"jeder Stunde"
|
|
437
458
|
) ?? countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde";
|
|
@@ -465,7 +486,7 @@ function isEveryOtherMinuteSeconds(ir, plan) {
|
|
|
465
486
|
if (plan.rest.kind !== "minuteFrequency" || ir.shapes.second !== "wildcard" || ir.shapes.hour !== "wildcard") {
|
|
466
487
|
return false;
|
|
467
488
|
}
|
|
468
|
-
const minuteStep = stepSegment(ir
|
|
489
|
+
const minuteStep = stepSegment(ir, "minute");
|
|
469
490
|
return minuteStep.startToken === "*" && minuteStep.interval === 2;
|
|
470
491
|
}
|
|
471
492
|
function renderComposeSeconds(ir, plan, opts) {
|
|
@@ -501,7 +522,7 @@ function renderMinutesAcrossHours(ir, plan, opts) {
|
|
|
501
522
|
if (plan.form === "wildcard") {
|
|
502
523
|
return cadence ? "jede Minute, " + cadence : "jede Minute " + duringHours(ir, plan.times, sep);
|
|
503
524
|
}
|
|
504
|
-
const minuteLead = strideFromSegments(
|
|
525
|
+
const minuteLead = strideFromSegments(segmentsOf(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten");
|
|
505
526
|
if (cadence !== null) {
|
|
506
527
|
return minuteLead + ", " + cadence;
|
|
507
528
|
}
|
|
@@ -511,11 +532,11 @@ function renderMinutesAcrossHours(ir, plan, opts) {
|
|
|
511
532
|
function renderMinuteSpanAcrossHourStep(ir, plan) {
|
|
512
533
|
const cadence = unevenHourCadence(ir);
|
|
513
534
|
if (plan.form === "wildcard") {
|
|
514
|
-
return "jede Minute " + everyNthHour(stepSegment(ir
|
|
535
|
+
return "jede Minute " + everyNthHour(stepSegment(ir, "hour"));
|
|
515
536
|
}
|
|
516
|
-
const segment = stepSegment(ir
|
|
537
|
+
const segment = stepSegment(ir, "hour");
|
|
517
538
|
const hours = cadence ?? (confinedHourStride(segment) ? everyNthHour(segment) : atHours(segment.fires));
|
|
518
|
-
return (strideFromSegments(
|
|
539
|
+
return (strideFromSegments(segmentsOf(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
|
|
519
540
|
}
|
|
520
541
|
function renderCompactClockTimes(ir, plan, opts) {
|
|
521
542
|
const sep = opts.style.sep;
|
|
@@ -524,15 +545,15 @@ function renderCompactClockTimes(ir, plan, opts) {
|
|
|
524
545
|
if (cadence !== null) {
|
|
525
546
|
return cadence;
|
|
526
547
|
}
|
|
527
|
-
const hourly =
|
|
548
|
+
const hourly = segmentsOf(ir, "hour").some((segment) => segment.kind === "range");
|
|
528
549
|
return (hourly ? "st\xFCndlich " : "t\xE4glich ") + joinList(hourSegmentParts(ir, plan.minute, ir.analyses.clockSecond, sep));
|
|
529
550
|
}
|
|
530
|
-
const hours = unevenHourCadence(ir) ?? (
|
|
551
|
+
const hours = unevenHourCadence(ir) ?? (segmentsOf(ir, "hour").some((segment) => segment.kind === "range") ? joinList(hourSegmentParts(ir, 0, 0, sep)) : atHours(hourFires(ir)));
|
|
531
552
|
const lead = ir.analyses.clockSecond ? countedPhrase(ir, "second", "Sekunde", "Sekunden") + ", " : "";
|
|
532
|
-
return lead + (strideFromSegments(
|
|
553
|
+
return lead + (strideFromSegments(segmentsOf(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
|
|
533
554
|
}
|
|
534
555
|
function renderMinuteFrequency(ir, plan, opts) {
|
|
535
|
-
const segment = stepSegment(ir
|
|
556
|
+
const segment = stepSegment(ir, "minute");
|
|
536
557
|
const sep = opts.style.sep;
|
|
537
558
|
const clean = cleanStep(segment, 60);
|
|
538
559
|
if (plan.hours.kind === "window") {
|
|
@@ -556,7 +577,7 @@ function renderMinuteFrequency(ir, plan, opts) {
|
|
|
556
577
|
return cadence ? base + ", " + cadence : base + " " + duringHours(ir, plan.hours.times, sep);
|
|
557
578
|
}
|
|
558
579
|
if (plan.hours.kind === "step") {
|
|
559
|
-
return base + " " + everyNthHour(stepSegment(ir
|
|
580
|
+
return base + " " + everyNthHour(stepSegment(ir, "hour"));
|
|
560
581
|
}
|
|
561
582
|
return base;
|
|
562
583
|
}
|
|
@@ -565,7 +586,7 @@ function hourStepPhrase(ir) {
|
|
|
565
586
|
if (cadence !== null) {
|
|
566
587
|
return cadence;
|
|
567
588
|
}
|
|
568
|
-
const segment = stepSegment(ir
|
|
589
|
+
const segment = stepSegment(ir, "hour");
|
|
569
590
|
if (cleanStep(segment, 24)) {
|
|
570
591
|
return everyN(segment.interval, UNITS.hour);
|
|
571
592
|
}
|
|
@@ -591,29 +612,8 @@ function hourStrideCadence(stride) {
|
|
|
591
612
|
}
|
|
592
613
|
return cadence + " von " + start + " bis " + last + " Uhr";
|
|
593
614
|
}
|
|
594
|
-
function hourListStride(values) {
|
|
595
|
-
if (values.length < 2) {
|
|
596
|
-
return null;
|
|
597
|
-
}
|
|
598
|
-
const interval = values[1] - values[0];
|
|
599
|
-
if (interval < 2) {
|
|
600
|
-
return null;
|
|
601
|
-
}
|
|
602
|
-
for (let i = 2; i < values.length; i += 1) {
|
|
603
|
-
if (values[i] - values[i - 1] !== interval) {
|
|
604
|
-
return null;
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
if (values[0] !== 0 && values.length < 5) {
|
|
608
|
-
return null;
|
|
609
|
-
}
|
|
610
|
-
return { interval, last: values[values.length - 1], start: values[0] };
|
|
611
|
-
}
|
|
612
|
-
function offsetCleanStride(stride) {
|
|
613
|
-
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
614
|
-
}
|
|
615
615
|
function hourStride(ir) {
|
|
616
|
-
const segments =
|
|
616
|
+
const segments = segmentsOf(ir, "hour");
|
|
617
617
|
if (!segments) {
|
|
618
618
|
return null;
|
|
619
619
|
}
|
|
@@ -660,8 +660,8 @@ function hourCadence(ir, minute) {
|
|
|
660
660
|
if (ir.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
|
|
661
661
|
return null;
|
|
662
662
|
}
|
|
663
|
-
const segment =
|
|
664
|
-
const confined = minute === 0 && subMinuteSecond(ir) &&
|
|
663
|
+
const segment = segmentsOf(ir, "hour")[0];
|
|
664
|
+
const confined = minute === 0 && subMinuteSecond(ir) && segmentsOf(ir, "hour").length === 1 && segment.kind === "step" && confinedHourStride(segment);
|
|
665
665
|
if (confined) {
|
|
666
666
|
return withAnchor(secondsClause(ir, minuteAnchor(ir)), "f\xFCr eine Minute") + " " + everyNthHour(segment);
|
|
667
667
|
}
|
|
@@ -678,7 +678,7 @@ function hourCadenceApplies(ir) {
|
|
|
678
678
|
return hourCadence(ir, minute) !== null || hourRangeCadence(ir, minute) !== null;
|
|
679
679
|
}
|
|
680
680
|
function hasHourWindow(ir) {
|
|
681
|
-
const segments =
|
|
681
|
+
const segments = segmentsOf(ir, "hour");
|
|
682
682
|
return !!segments && segments.some(function range(segment) {
|
|
683
683
|
return segment.kind === "range";
|
|
684
684
|
});
|
|
@@ -702,7 +702,7 @@ function renderHourRange(ir, plan, opts) {
|
|
|
702
702
|
return "st\xFCndlich " + window;
|
|
703
703
|
}
|
|
704
704
|
return (strideFromSegments(
|
|
705
|
-
|
|
705
|
+
segmentsOf(ir, "minute"),
|
|
706
706
|
UNITS.minute,
|
|
707
707
|
"jeder Stunde"
|
|
708
708
|
) ?? countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde") + ", " + window;
|
|
@@ -773,7 +773,7 @@ function needsDailyFrame(ir) {
|
|
|
773
773
|
if (ir.plan.kind !== "hourStep") {
|
|
774
774
|
return false;
|
|
775
775
|
}
|
|
776
|
-
const segment = stepSegment(ir
|
|
776
|
+
const segment = stepSegment(ir, "hour");
|
|
777
777
|
return !cleanStep(segment, 24) && !openOffsetCleanStride(ir, segment);
|
|
778
778
|
}
|
|
779
779
|
function render(ir, plan, opts) {
|